AI Study Planner Generator

import pandas as pd

from datetime import datetime, timedelta

import math


# ============================================================

# STEP 1: Input Syllabus Topics

# ============================================================


def get_syllabus():

    print("\n" + "="*55)

    print("AI STUDY PLANNER GENERATOR")

    print("="*55)

    print("\nEnter your syllabus topics.")

    print("Format: topic name, difficulty (1=Easy, 2=Medium, 3=Hard)")

    print("Type 'done' when finished.\n")


    topics = []

    while True:

        entry = input("Topic (name, difficulty): ").strip()

        if entry.lower() == "done":

            break

        parts = entry.split(",")

        if len(parts) != 2:

            print("  Please enter: topic name, difficulty (1/2/3)")

            continue

        name = parts[0].strip()

        try:

            difficulty = int(parts[1].strip())

            if difficulty not in [1, 2, 3]:

                raise ValueError

        except ValueError:

            print("  Difficulty must be 1, 2, or 3")

            continue

        topics.append({"topic": name, "difficulty": difficulty})


    return topics



# ============================================================

# STEP 2: Get Deadline

# ============================================================


def get_deadline():

    while True:

        date_str = input("\nEnter exam/deadline date (DD-MM-YYYY): ").strip()

        try:

            deadline = datetime.strptime(date_str, "%d-%m-%Y")

            if deadline.date() <= datetime.today().date():

                print("  Deadline must be a future date!")

                continue

            return deadline

        except ValueError:

            print("  Invalid date format. Use DD-MM-YYYY")



# ============================================================

# STEP 3: Get Daily Study Hours

# ============================================================


def get_study_hours():

    while True:

        try:

            hours = float(input("How many hours can you study per day? "))

            if hours <= 0 or hours > 16:

                print("  Please enter a realistic value (0 - 16 hours)")

                continue

            return hours

        except ValueError:

            print("  Enter a valid number")



# ============================================================

# STEP 4: Calculate Time Allocation Per Topic

# ============================================================


def allocate_hours(topics, total_available_hours):

    """

    Allocate hours proportionally based on difficulty.

    Easy = 1x, Medium = 2x, Hard = 3x weight

    """

    total_weight = sum(t["difficulty"] for t in topics)


    for topic in topics:

        share = topic["difficulty"] / total_weight

        allocated = round(share * total_available_hours, 1)

        topic["allocated_hours"] = max(allocated, 0.5)  # minimum 30 min per topic


    return topics



# ============================================================

# STEP 5: Generate Day-by-Day Schedule

# ============================================================


def generate_schedule(topics, start_date, deadline, daily_hours):

    schedule = []

    current_date = start_date

    topic_queue = topics.copy()


    # Buffer: keep last day free for revision

    available_days = (deadline.date() - start_date.date()).days

    if available_days < 1:

        print("\n⚠ Not enough days! Please revise your deadline.")

        return pd.DataFrame()


    study_days = available_days - 1  # last day = revision


    # Recalculate total available hours

    total_hours = study_days * daily_hours


    topic_queue = allocate_hours(topic_queue, total_hours)


    for topic in topic_queue:

        hours_remaining = topic["allocated_hours"]

        sessions = []


        while hours_remaining > 0:

            if current_date.date() >= deadline.date():

                break

            session_hours = min(hours_remaining, daily_hours)

            sessions.append({

                "Date": current_date.strftime("%d-%m-%Y (%A)"),

                "Topic": topic["topic"],

                "Difficulty": ["", "Easy 🟢", "Medium 🟡", "Hard 🔴"][topic["difficulty"]],

                "Study Hours": session_hours,

                "Status": "⬜ Pending"

            })

            hours_remaining -= session_hours

            hours_remaining = round(hours_remaining, 1)

            current_date += timedelta(days=1)


        schedule.extend(sessions)


    # Add Revision Day

    if current_date.date() <= deadline.date():

        schedule.append({

            "Date": deadline.strftime("%d-%m-%Y (%A)"),

            "Topic": "FULL REVISION",

            "Difficulty": "All Topics",

            "Study Hours": daily_hours,

            "Status": "Pending"

        })


    return pd.DataFrame(schedule)



# ============================================================

# STEP 6: Display & Export

# ============================================================


def display_plan(df, topics, deadline, daily_hours):

    print("\n" + "="*55)

    print(" YOUR OPTIMIZED STUDY PLAN")

    print("="*55)


    print(f"\nExam Date   : {deadline.strftime('%d-%m-%Y')}")

    print(f"Daily Hours  : {daily_hours} hrs/day")

    print(f" Total Topics: {len(topics)}")

    print(f" Total Days  : {len(df['Date'].unique())}\n")


    pd.set_option("display.max_rows", None)

    pd.set_option("display.max_colwidth", 35)

    pd.set_option("display.width", 100)

    print(df.to_string(index=False))


    # Summary Table

    print("\n" + "="*55)

    print("  TOPIC SUMMARY")

    print("="*55)

    summary = pd.DataFrame(topics)[["topic", "difficulty", "allocated_hours"]]

    summary.columns = ["Topic", "Difficulty (1-3)", "Hours Allocated"]

    print(summary.to_string(index=False))


    # Save to CSV

    save = input("\n Save study plan to CSV? (y/n): ").strip().lower()

    if save == "y":

        filename = f"study_plan_{deadline.strftime('%d%m%Y')}.csv"

        df.to_csv(filename, index=False)

        print(f" Saved as: {filename}")



# ============================================================

# STEP 7: Smart Suggestions

# ============================================================


def give_tips(topics, available_days):

    hard_topics = [t["topic"] for t in topics if t["difficulty"] == 3]

    print("\n" + "="*55)

    print("   SMART STUDY TIPS")

    print("="*55)


    if hard_topics:

        print(f"\n⚠  Hard topics detected: {', '.join(hard_topics)}")

        print("   → Schedule these in the MORNING when focus is highest.")


    if available_days < len(topics):

        print(f"\n⚠  You have {available_days} days for {len(topics)} topics.")

        print("   → Consider grouping related topics together.")


    print("\n General Tips:")

    print("   • Use Pomodoro: 25 min study + 5 min break")

    print("   • Review notes at the end of each session")

    print("   • Mark completed topics in your saved CSV")

    print("   • Keep last day for full revision only\n")



# ============================================================

# MAIN

# ============================================================


if __name__ == "__main__":

    # Get inputs

    topics = get_syllabus()


    if not topics:

        print("\n No topics entered. Exiting.")

        exit()


    deadline = get_deadline()

    daily_hours = get_study_hours()


    start_date = datetime.today().replace(hour=0, minute=0, second=0, microsecond=0) + timedelta(days=1)

    available_days = (deadline.date() - start_date.date()).days


    if available_days < 1:

        print("\n Not enough time before deadline!")

        exit()


    # Generate plan

    df = generate_schedule(topics, start_date, deadline, daily_hours)


    if df.empty:

        print("\n Could not generate plan. Check your inputs.")

        exit()


    # Display results

    display_plan(df, topics, deadline, daily_hours)

    give_tips(topics, available_days)


    print("="*55)

    print("  Good luck with your studies! You've got this.")

    print("="*55 + "\n") 

No comments: