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") 

Network Packet Visualizer

 from scapy.all import sniff

import matplotlib.pyplot as plt


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

# Packet Counters

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


protocol_counts = {

    "TCP": 0,

    "UDP": 0,

    "ICMP": 0,

    "Other": 0

}



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

# Packet Handler

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


def process_packet(packet):


    if packet.haslayer("TCP"):

        protocol_counts["TCP"] += 1


    elif packet.haslayer("UDP"):

        protocol_counts["UDP"] += 1


    elif packet.haslayer("ICMP"):

        protocol_counts["ICMP"] += 1


    else:

        protocol_counts["Other"] += 1



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

# Capture Packets

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


def capture_packets(packet_limit=200):


    print("Capturing packets...")


    sniff(prn=process_packet, count=packet_limit)


    print("Capture complete.")



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

# Visualization

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


def visualize():


    labels = list(protocol_counts.keys())

    values = list(protocol_counts.values())


    plt.figure(figsize=(6,6))


    plt.pie(

        values,

        labels=labels,

        autopct='%1.1f%%',

        startangle=140

    )


    plt.title("Network Protocol Distribution")

    plt.show()



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

# MAIN

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


if __name__ == "__main__":


    capture_packets(300)


    print("\nProtocol counts:")


    for proto, count in protocol_counts.items():

        print(f"{proto}: {count}")


    visualize()

Matrix Calculator with Step-by-Step Linear Algebra

import numpy as np

import sympy as sp


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

# Input Matrix

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


def input_matrix():

    rows = int(input("Enter number of rows: "))

    cols = int(input("Enter number of columns: "))


    matrix = []


    print("Enter matrix values row by row:")


    for i in range(rows):

        row = list(map(float, input().split()))

        matrix.append(row)


    return np.array(matrix)



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

# Determinant

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


def calculate_determinant(matrix):

    sym_matrix = sp.Matrix(matrix)


    print("\nMatrix:")

    sp.pprint(sym_matrix)


    det = sym_matrix.det()


    print("\nDeterminant calculation:")

    print(det)


    return det



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

# Matrix Inverse

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


def calculate_inverse(matrix):

    sym_matrix = sp.Matrix(matrix)


    print("\nMatrix:")

    sp.pprint(sym_matrix)


    try:

        inverse = sym_matrix.inv()


        print("\nInverse Matrix:")

        sp.pprint(inverse)


        return inverse


    except:

        print("Matrix is not invertible.")

        return None



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

# Eigenvalues

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


def calculate_eigenvalues(matrix):

    sym_matrix = sp.Matrix(matrix)


    print("\nMatrix:")

    sp.pprint(sym_matrix)


    eigenvals = sym_matrix.eigenvals()


    print("\nEigenvalues:")


    for val, mult in eigenvals.items():

        print(f"{val} (multiplicity {mult})")


    return eigenvals



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

# MAIN

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


if __name__ == "__main__":


    matrix = input_matrix()


    print("\nChoose operation:")

    print("1. Determinant")

    print("2. Inverse")

    print("3. Eigenvalues")


    choice = input("Enter choice: ")


    if choice == "1":

        calculate_determinant(matrix)


    elif choice == "2":

        calculate_inverse(matrix)


    elif choice == "3":

        calculate_eigenvalues(matrix)


    else:

        print("Invalid option")

Algorithm Performance Visualizer

import random

import time

import matplotlib.pyplot as plt


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

# Sorting Algorithms

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


def bubble_sort(arr):

    arr = arr.copy()

    n = len(arr)

    for i in range(n):

        for j in range(0, n - i - 1):

            if arr[j] > arr[j + 1]:

                arr[j], arr[j + 1] = arr[j + 1], arr[j]

    return arr



def insertion_sort(arr):

    arr = arr.copy()

    for i in range(1, len(arr)):

        key = arr[i]

        j = i - 1

        while j >= 0 and key < arr[j]:

            arr[j + 1] = arr[j]

            j -= 1

        arr[j + 1] = key

    return arr



def merge_sort(arr):

    if len(arr) <= 1:

        return arr


    mid = len(arr) // 2

    left = merge_sort(arr[:mid])

    right = merge_sort(arr[mid:])


    return merge(left, right)



def merge(left, right):

    result = []

    i = j = 0


    while i < len(left) and j < len(right):

        if left[i] < right[j]:

            result.append(left[i])

            i += 1

        else:

            result.append(right[j])

            j += 1


    result.extend(left[i:])

    result.extend(right[j:])

    return result



def quick_sort(arr):

    if len(arr) <= 1:

        return arr

    pivot = arr[len(arr) // 2]

    left = [x for x in arr if x < pivot]

    middle = [x for x in arr if x == pivot]

    right = [x for x in arr if x > pivot]

    return quick_sort(left) + middle + quick_sort(right)



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

# Benchmark Function

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


def measure_time(func, arr):

    start = time.time()

    func(arr)

    end = time.time()

    return end - start



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

# Main Visualization

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


if __name__ == "__main__":

    sizes = [100, 500, 1000, 2000]

    results = {

        "Bubble Sort": [],

        "Insertion Sort": [],

        "Merge Sort": [],

        "Quick Sort": []

    }


    for size in sizes:

        print(f"Testing size: {size}")

        data = [random.randint(1, 10000) for _ in range(size)]


        results["Bubble Sort"].append(measure_time(bubble_sort, data))

        results["Insertion Sort"].append(measure_time(insertion_sort, data))

        results["Merge Sort"].append(measure_time(merge_sort, data))

        results["Quick Sort"].append(measure_time(quick_sort, data))


    # Plot Results

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


    for algo, times in results.items():

        plt.plot(sizes, times, marker='o', label=algo)


    plt.xlabel("Input Size")

    plt.ylabel("Execution Time (seconds)")

    plt.title("Sorting Algorithm Performance Comparison")

    plt.legend()

    plt.grid(True)

    plt.show()

Local File Integrity Monitor

import os

import hashlib

import json

from watchdog.observers import Observer

from watchdog.events import FileSystemEventHandler

import time


HASH_DB = "file_hashes.json"



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

# Hash Function

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

def calculate_hash(file_path):

    sha256 = hashlib.sha256()


    try:

        with open(file_path, "rb") as f:

            while chunk := f.read(4096):

                sha256.update(chunk)

        return sha256.hexdigest()

    except:

        return None



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

# Load & Save Hash Database

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

def load_hash_db():

    if os.path.exists(HASH_DB):

        with open(HASH_DB, "r") as f:

            return json.load(f)

    return {}



def save_hash_db(db):

    with open(HASH_DB, "w") as f:

        json.dump(db, f, indent=4)



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

# Initial Scan

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

def initial_scan(folder_path):

    db = {}


    print(" Performing initial scan...\n")


    for root, dirs, files in os.walk(folder_path):

        for file in files:

            path = os.path.join(root, file)

            file_hash = calculate_hash(path)

            if file_hash:

                db[path] = file_hash


    save_hash_db(db)

    print(" Initial scan complete.")

    return db



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

# Event Handler

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

class IntegrityHandler(FileSystemEventHandler):

    def __init__(self, folder_path):

        self.folder_path = folder_path

        self.hash_db = load_hash_db()


        if not self.hash_db:

            self.hash_db = initial_scan(folder_path)


    def on_modified(self, event):

        if event.is_directory:

            return


        file_path = event.src_path

        new_hash = calculate_hash(file_path)


        if file_path in self.hash_db:

            if self.hash_db[file_path] != new_hash:

                print(f"⚠ ALERT: File modified → {file_path}")

                self.hash_db[file_path] = new_hash

                save_hash_db(self.hash_db)


        else:

            print(f" New file detected → {file_path}")

            self.hash_db[file_path] = new_hash

            save_hash_db(self.hash_db)


    def on_deleted(self, event):

        if event.src_path in self.hash_db:

            print(f" File deleted → {event.src_path}")

            del self.hash_db[event.src_path]

            save_hash_db(self.hash_db)



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

# MAIN

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

if __name__ == "__main__":

    folder = input("Enter folder path to monitor: ").strip()


    if not os.path.isdir(folder):

        print(" Invalid folder path.")

        exit()


    print("\n Monitoring started... (Press Ctrl+C to stop)\n")


    event_handler = IntegrityHandler(folder)

    observer = Observer()

    observer.schedule(event_handler, folder, recursive=True)

    observer.start()


    try:

        while True:

            time.sleep(1)

    except KeyboardInterrupt:

        observer.stop()


    observer.join()