Bulk File Renamer

import os

import re

import shutil

from pathlib import Path

from datetime import datetime

 

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

# UTILITY: List Files in Folder

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

 

def list_files(folder, extension_filter=None):

    files = []

    for f in sorted(Path(folder).iterdir()):

        if f.is_file():

            if extension_filter:

                if f.suffix.lower() == extension_filter.lower():

                    files.append(f)

            else:

                files.append(f)

    return files

 

 

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

# MODE 1: Add Prefix / Suffix

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

 

def rename_prefix_suffix(files, prefix="", suffix=""):

    renamed = []

    for f in files:

        stem = f.stem        # filename without extension

        ext  = f.suffix      # .jpg, .txt etc.

        new_name = f"{prefix}{stem}{suffix}{ext}"

        new_path = f.parent / new_name

        renamed.append((f, new_path))

    return renamed

 

 

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

# MODE 2: Sequential Numbering

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

 

def rename_sequential(files, base_name="file", start=1, padding=3):

    renamed = []

    for i, f in enumerate(files, start=start):

        ext = f.suffix

        number = str(i).zfill(padding)

        new_name = f"{base_name}_{number}{ext}"

        new_path = f.parent / new_name

        renamed.append((f, new_path))

    return renamed

 

 

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

# MODE 3: Find & Replace in Filename

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

 

def rename_find_replace(files, find_text, replace_text):

    renamed = []

    for f in files:

        new_name = f.name.replace(find_text, replace_text)

        new_path = f.parent / new_name

        renamed.append((f, new_path))

    return renamed

 

 

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

# MODE 4: Regex-Based Rename

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

 

def rename_regex(files, pattern, replacement):

    renamed = []

    for f in files:

        try:

            new_name = re.sub(pattern, replacement, f.name)

            new_path = f.parent / new_name

            renamed.append((f, new_path))

        except re.error as e:

            print(f"  ⚠ Regex error for {f.name}: {e}")

    return renamed

 

 

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

# MODE 5: Add Date Stamp

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

 

def rename_add_date(files, position="prefix"):

    today = datetime.today().strftime("%Y%m%d")

    renamed = []

    for f in files:

        stem = f.stem

        ext  = f.suffix

        if position == "prefix":

            new_name = f"{today}_{stem}{ext}"

        else:

            new_name = f"{stem}_{today}{ext}"

        new_path = f.parent / new_name

        renamed.append((f, new_path))

    return renamed

 

 

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

# PREVIEW & CONFIRM

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

 

def preview_changes(renamed):

    print("\n" + "-"*60)

    print(f"{'ORIGINAL':<30} {'NEW NAME':<30}")

    print("-"*60)

    for old, new in renamed:

        print(f"{old.name:<30} {new.name:<30}")

    print("-"*60)

 

 

def apply_rename(renamed, dry_run=False):

    success = 0

    skipped = 0

    for old, new in renamed:

        if old == new:

            skipped += 1

            continue

        if new.exists():

            print(f"  ⚠ Skipped (already exists): {new.name}")

            skipped += 1

            continue

        if not dry_run:

            old.rename(new)

        success += 1

 

    if dry_run:

        print(f"\n Dry Run Complete: {success} files would be renamed, {skipped} skipped.")

    else:

        print(f"\n Done! {success} files renamed, {skipped} skipped.")

 

 

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

# BACKUP (Optional)

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

 

def backup_folder(folder):

    backup_path = str(folder) + "_backup_" + datetime.today().strftime("%Y%m%d_%H%M%S")

    shutil.copytree(folder, backup_path)

    print(f" Backup created: {backup_path}")

 

 

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

# MAIN MENU

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

 

def main():

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

    print("          BULK FILE RENAMER")

    print("="*55)

 

    # --- Folder Path ---

    folder = input("\nEnter folder path: ").strip()

    if not os.path.isdir(folder):

        print(" Invalid folder path!")

        return

 

    # --- Optional Extension Filter ---

    ext_filter = input("Filter by extension? (e.g. .jpg) or press Enter for all: ").strip()

    if not ext_filter:

        ext_filter = None

 

    files = list_files(folder, ext_filter)

    if not files:

        print(" No files found!")

        return

 

    print(f"\n Found {len(files)} file(s) in '{folder}'")

 

    # --- Optional Backup ---

    backup = input("\nCreate backup before renaming? (y/n): ").strip().lower()

    if backup == "y":

        backup_folder(folder)

 

    # --- Choose Mode ---

    print("\nChoose Rename Mode:")

    print("  1. Add Prefix / Suffix")

    print("  2. Sequential Numbering")

    print("  3. Find & Replace")

    print("  4. Regex Pattern")

    print("  5. Add Date Stamp")

 

    choice = input("\nEnter choice (1-5): ").strip()

 

    renamed = []

 

    if choice == "1":

        prefix = input("Enter prefix (or leave blank): ").strip()

        suffix = input("Enter suffix (or leave blank): ").strip()

        renamed = rename_prefix_suffix(files, prefix, suffix)

 

    elif choice == "2":

        base = input("Enter base name (e.g. photo): ").strip()

        start = int(input("Start number (default 1): ").strip() or 1)

        padding = int(input("Number padding digits (default 3): ").strip() or 3)

        renamed = rename_sequential(files, base, start, padding)

 

    elif choice == "3":

        find = input("Find text: ").strip()

        replace = input("Replace with: ").strip()

        renamed = rename_find_replace(files, find, replace)

 

    elif choice == "4":

        print("  Example pattern: (\\d+)  → matches numbers")

        pattern = input("Regex pattern: ").strip()

        replacement = input("Replacement: ").strip()

        renamed = rename_regex(files, pattern, replacement)

 

    elif choice == "5":

        pos = input("Add date as prefix or suffix? (prefix/suffix): ").strip().lower()

        if pos not in ["prefix", "suffix"]:

            pos = "prefix"

        renamed = rename_add_date(files, pos)

 

    else:

        print(" Invalid choice.")

        return

 

    if not renamed:

        print(" No files to rename.")

        return

 

    # --- Preview ---

    preview_changes(renamed)

 

    # --- Dry Run or Apply ---

    mode = input("\nChoose action:\n  1. Apply rename\n  2. Dry run (preview only)\nChoice: ").strip()

 

    if mode == "1":

        apply_rename(renamed, dry_run=False)

    else:

        apply_rename(renamed, dry_run=True)

 

 

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

# RUN

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

 

if __name__ == "__main__":

    main()

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