Daily Habit Forecasting Using Time-Series

import pandas as pd

import matplotlib.pyplot as plt

from statsmodels.tsa.holtwinters import ExponentialSmoothing


# --------------------------------------------------

# Load & Prepare Data

# --------------------------------------------------

def load_habit_data(csv_path, habit_name):

    df = pd.read_csv(csv_path)

    df["date"] = pd.to_datetime(df["date"])


    habit_df = df[df["habit"] == habit_name]

    habit_df = habit_df.sort_values("date")


    habit_df.set_index("date", inplace=True)

    ts = habit_df["completed"]


    return ts


# --------------------------------------------------

# Forecast Habit Completion

# --------------------------------------------------

def forecast_habit(ts, days=7):

    model = ExponentialSmoothing(

        ts,

        trend="add",

        seasonal=None,

        initialization_method="estimated"

    )


    fitted_model = model.fit()

    forecast = fitted_model.forecast(days)


    return fitted_model, forecast


# --------------------------------------------------

# Risk Analysis

# --------------------------------------------------

def habit_risk_score(forecast):

    avg_completion = forecast.mean()


    if avg_completion < 0.4:

        return "🚨 High Risk (likely to break)"

    elif avg_completion < 0.7:

        return "⚠️ Medium Risk"

    else:

        return "✅ Low Risk (stable habit)"


# --------------------------------------------------

# Visualization

# --------------------------------------------------

def plot_forecast(ts, forecast, habit_name):

    plt.figure(figsize=(10, 5))


    plt.plot(ts.index, ts.values, label="Past Completion", marker="o")

    plt.plot(forecast.index, forecast.values, label="Forecast", linestyle="--", marker="x")


    plt.ylim(-0.1, 1.1)

    plt.ylabel("Habit Completed (1=yes, 0=no)")

    plt.title(f"Habit Forecast: {habit_name}")

    plt.legend()

    plt.grid(True)


    plt.show()


# --------------------------------------------------

# MAIN

# --------------------------------------------------

if __name__ == "__main__":

    csv_file = input("Enter CSV file path: ").strip()

    habit = input("Enter habit name (case-sensitive): ").strip()


    ts = load_habit_data(csv_file, habit)


    model, forecast = forecast_habit(ts, days=7)


    risk = habit_risk_score(forecast)


    print("\nšŸ“Š HABIT FORECAST REPORT")

    print("------------------------")

    print(f"Habit: {habit}")

    print(f"Next 7-day average completion: {forecast.mean():.2f}")

    print(f"Risk Level: {risk}")


    plot_forecast(ts, forecast, habit)


Local Password Strength Analyzer

import tkinter as tk

from tkinter import ttk

import math

import re


# ---------------------------

# Heuristics & helpers

# ---------------------------


COMMON_PASSWORDS = {

    "password", "123456", "123456789", "qwerty", "abc123",

    "letmein", "welcome", "admin", "iloveyou", "monkey"

}


SEQUENCES = [

    "abcdefghijklmnopqrstuvwxyz",

    "ABCDEFGHIJKLMNOPQRSTUVWXYZ",

    "0123456789",

    "qwertyuiop", "asdfghjkl", "zxcvbnm"

]


def shannon_entropy(password: str) -> float:

    """Approximate entropy based on character sets used."""

    pool = 0

    if re.search(r"[a-z]", password): pool += 26

    if re.search(r"[A-Z]", password): pool += 26

    if re.search(r"\d", password):    pool += 10

    if re.search(r"[^\w\s]", password): pool += 32  # symbols

    if pool == 0:

        return 0.0

    return len(password) * math.log2(pool)


def has_repeats(password: str) -> bool:

    return bool(re.search(r"(.)\1{2,}", password))  # aaa, 111


def has_sequence(password: str) -> bool:

    p = password

    for seq in SEQUENCES:

        for i in range(len(seq) - 3):

            if seq[i:i+4] in p:

                return True

    return False


def keyboard_walk(password: str) -> bool:

    walks = ["qwerty", "asdf", "zxcv", "poiuy", "lkjhg", "mnbv"]

    p = password.lower()

    return any(w in p for w in walks)


def analyze_password(password: str):

    issues = []

    score = 0


    # Length

    if len(password) < 8:

        issues.append("Too short (minimum 8 characters).")

    else:

        score += min(20, (len(password) - 7) * 3)


    # Character classes

    classes = 0

    classes += bool(re.search(r"[a-z]", password))

    classes += bool(re.search(r"[A-Z]", password))

    classes += bool(re.search(r"\d", password))

    classes += bool(re.search(r"[^\w\s]", password))

    score += classes * 10


    if classes < 3:

        issues.append("Use at least 3 character types (upper/lower/digits/symbols).")


    # Entropy

    ent = shannon_entropy(password)

    score += min(30, int(ent / 3))  # cap contribution


    if ent < 40:

        issues.append("Low entropy. Add length and variety.")


    # Patterns

    if password.lower() in COMMON_PASSWORDS:

        issues.append("Common password detected.")

        score -= 30


    if has_repeats(password):

        issues.append("Repeated characters detected (e.g., 'aaa').")

        score -= 10


    if has_sequence(password):

        issues.append("Sequential pattern detected (e.g., 'abcd', '1234').")

        score -= 10


    if keyboard_walk(password):

        issues.append("Keyboard pattern detected (e.g., 'qwerty').")

        score -= 10


    score = max(0, min(100, score))


    if score >= 80:

        verdict = "Strong"

    elif score >= 60:

        verdict = "Good"

    elif score >= 40:

        verdict = "Weak"

    else:

        verdict = "Very Weak"


    return {

        "score": score,

        "verdict": verdict,

        "entropy": round(ent, 1),

        "issues": issues

    }


# ---------------------------

# GUI

# ---------------------------


class App(tk.Tk):

    def __init__(self):

        super().__init__()

        self.title("Local Password Strength Analyzer")

        self.geometry("520x420")

        self.resizable(False, False)


        ttk.Label(self, text="Enter Password:", font=("Arial", 12)).pack(pady=10)

        self.pw = ttk.Entry(self, show="*", width=40)

        self.pw.pack()


        self.show_var = tk.BooleanVar(value=False)

        ttk.Checkbutton(self, text="Show password", variable=self.show_var,

                        command=self.toggle_show).pack(pady=5)


        ttk.Button(self, text="Analyze", command=self.run).pack(pady=10)


        self.score_lbl = ttk.Label(self, text="Score: —", font=("Arial", 12, "bold"))

        self.score_lbl.pack()


        self.ent_lbl = ttk.Label(self, text="Entropy: — bits")

        self.ent_lbl.pack(pady=5)


        self.verdict_lbl = ttk.Label(self, text="Verdict: —", font=("Arial", 12))

        self.verdict_lbl.pack(pady=5)


        ttk.Label(self, text="Feedback:", font=("Arial", 11, "bold")).pack(pady=8)

        self.feedback = tk.Text(self, height=8, width=60, wrap="word")

        self.feedback.pack(padx=10)


    def toggle_show(self):

        self.pw.config(show="" if self.show_var.get() else "*")


    def run(self):

        pwd = self.pw.get()

        res = analyze_password(pwd)


        self.score_lbl.config(text=f"Score: {res['score']}/100")

        self.ent_lbl.config(text=f"Entropy: {res['entropy']} bits")

        self.verdict_lbl.config(text=f"Verdict: {res['verdict']}")


        self.feedback.delete("1.0", "end")

        if res["issues"]:

            for i in res["issues"]:

                self.feedback.insert("end", f"• {i}\n")

        else:

            self.feedback.insert("end", "No issues found. Great password!")


if __name__ == "__main__":

    App().mainloop()