From a4f2a00ea6f65ee00432ce38766a7eb4a72224a7 Mon Sep 17 00:00:00 2001 From: shashwat-126 Date: Tue, 4 Nov 2025 23:25:56 +0530 Subject: [PATCH 1/3] Added README and CPU Scheduling Interface --- scheduling/CPU SCH INTERFACE.md | 118 ++++++++++ scheduling/cpu_scheduling_interface.py | 310 +++++++++++++++++++++++++ 2 files changed, 428 insertions(+) create mode 100644 scheduling/CPU SCH INTERFACE.md create mode 100644 scheduling/cpu_scheduling_interface.py diff --git a/scheduling/CPU SCH INTERFACE.md b/scheduling/CPU SCH INTERFACE.md new file mode 100644 index 000000000000..af3109e99a7a --- /dev/null +++ b/scheduling/CPU SCH INTERFACE.md @@ -0,0 +1,118 @@ +
+ +# ๐Ÿ–ฅ๏ธ CPU Scheduling Visualizer (Python + Tkinter) + +
+ +A **GUI-based CPU Scheduling Algorithm Visualizer** built using **Python**, **Tkinter**, and **Matplotlib**. +It allows users to add custom processes and simulate various scheduling algorithms with **real-time Gantt chart animation**, **ready queue visualization**, and **performance statistics**. + +--- + +## ๐Ÿš€ Features + +โœ… Interactive **Tkinter GUI** +โœ… Supports multiple **CPU scheduling algorithms** +โœ… Real-time **Gantt chart animation** using Matplotlib +โœ… Displays **Ready Queue** (for Round Robin & Preemptive algorithms) +โœ… Shows **average waiting time**, **turnaround time**, and **response time** +โœ… Add or delete processes dynamically +โœ… Clean and responsive design + +--- + +## โš™๏ธ Supported Algorithms + +| Type | Algorithm | Preemptive | Non-Preemptive | +|------|-------------------------------------------|-------------|----------------| +| ๐Ÿ”น | **First Come First Serve (FCFS)** | โŒ | โœ… | +| ๐Ÿ”น | **Shortest Job First (SJF)** | โœ… | โœ… | +| ๐Ÿ”น | **Priority Scheduling** | โœ… | โœ… | +| ๐Ÿ”น | **Round Robin (RR)** | โœ… | โŒ | + +--- + +## ๐Ÿงฎ Example Input + +| PID | Arrival | Burst | Priority | +|-----|----------|--------|-----------| +| P1 | 0 | 5 | 2 | +| P2 | 1 | 3 | 1 | +| P3 | 2 | 8 | 3 | + +--- + +## ๐Ÿ“Š Output Example + +### โžค Gantt Chart (Animated) +Displays process execution in timeline order, showing process IDs along the time axis. + +### โžค Results Table +| PID | Arrival | Burst | Completion | TAT | WT | RT | +|-----|----------|--------|-------------|------|------|------| +| P1 | 0 | 5 | 5 | 5 | 0 | 0 | +| P2 | 1 | 3 | 8 | 7 | 4 | 4 | +| P3 | 2 | 8 | 16 | 14 | 6 | 6 | + +**AVG WT = 3.33 | AVG TAT = 8.67 | AVG RT = 3.33** + +--- + +## ๐Ÿง  Working + +1. Enter process details (`PID`, `Arrival`, `Burst`, `Priority`) +2. Choose your desired **Scheduling Algorithm** +3. (Optional) Enter Quantum value (for Round Robin) +4. Click **Run** +5. Watch the **live animation** of process execution +6. View detailed results with averages + +--- + +## ๐Ÿ› ๏ธ Tech Stack + +- **Python 3.8+** +- **Tkinter** โ†’ GUI Framework +- **Matplotlib** โ†’ Animation and Gantt Chart +- **Threading** โ†’ Live simulation without freezing GUI + +--- + +## ๐Ÿ“ฆ Installation & Setup + +### 1๏ธโƒฃ Clone this repository +```bash +git clone https://github.com/yourusername/Python +cd Python +cd scheduling +``` + +### 2๏ธโƒฃ Install dependencies +```bash +pip install matplotlib +``` + +### 3๏ธโƒฃ Run the application +```bash +python cpu_scheduling_interface.py +``` + +or + +```bash +python3 cpu_scheduling_interface.py +``` + +## ๐ŸŽฅ Demo (Preview) + + + +#### ๐Ÿ‘จโ€๐Ÿ’ป Author +Shashwat + +โญ If you find this helpful, donโ€™t forget to star the repository! +
+ +Made with โค๏ธ using Python & Tkinter + +
diff --git a/scheduling/cpu_scheduling_interface.py b/scheduling/cpu_scheduling_interface.py new file mode 100644 index 000000000000..6eaaa2650171 --- /dev/null +++ b/scheduling/cpu_scheduling_interface.py @@ -0,0 +1,310 @@ +import tkinter as tk +from tkinter import ttk, messagebox +import matplotlib.pyplot as plt +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg +import threading, time, copy + +# ===================== Scheduler Engine ===================== # +class SchedulerEngine: + def __init__(self, processes, algorithm, quantum=2): + self.original = copy.deepcopy(processes) + self.processes = [p.copy() for p in processes] + self.algorithm = algorithm + self.quantum = quantum + for p in self.processes: + p["remaining"] = p["burst"] + self.timeline = [] # [(time, pid)] + self.stats = [] + + def simulate(self): + algo = self.algorithm.lower() + if algo == "fcfs": + yield from self._simulate_fcfs() + elif algo == "sjf (non-preemptive)": + yield from self._simulate_sjf_np() + elif algo == "sjf (preemptive)": + yield from self._simulate_sjf_p() + elif algo == "priority (non-preemptive)": + yield from self._simulate_priority_np() + elif algo == "priority (preemptive)": + yield from self._simulate_priority_p() + elif algo == "round robin": + yield from self._simulate_rr() + self._calculate_stats() + + #first come first serve + def _simulate_fcfs(self): + t = 0 + processes = sorted(self.processes, key=lambda p: p["arrival"]) + for p in processes: + if t < p["arrival"]: + t = p["arrival"] + for _ in range(p["burst"]): + self.timeline.append((t, p["pid"])) + yield (t, p["pid"], []) + t += 1 + p["completion"] = t + + #shortest job first non preemptive + def _simulate_sjf_np(self): + t = 0 + processes = sorted(self.processes, key=lambda p: p["arrival"]) + done = 0 + while done < len(processes): + ready = [p for p in processes if p["arrival"] <= t and "completion" not in p] + if not ready: + t += 1 + yield (t, None, []) + continue + p = min(ready, key=lambda x: x["burst"]) + for _ in range(p["burst"]): + self.timeline.append((t, p["pid"])) + yield (t, p["pid"], []) + t += 1 + p["completion"] = t + done += 1 + + # shortest job first preemptive + def _simulate_sjf_p(self): + t = 0 + processes = sorted(self.processes, key=lambda p: p["arrival"]) + done = 0 + while done < len(processes): + ready = [p for p in processes if p["arrival"] <= t and p["remaining"] > 0] + if not ready: + t += 1 + yield (t, None, []) + continue + p = min(ready, key=lambda x: x["remaining"]) + self.timeline.append((t, p["pid"])) + yield (t, p["pid"], []) + p["remaining"] -= 1 + if p["remaining"] == 0: + p["completion"] = t + 1 + done += 1 + t += 1 + + # priority non preemptive + def _simulate_priority_np(self): + t = 0 + done = 0 + while done < len(self.processes): + ready = [p for p in self.processes if p["arrival"] <= t and "completion" not in p] + if not ready: + t += 1 + yield (t, None, []) + continue + p = min(ready, key=lambda x: x["priority"]) + for _ in range(p["burst"]): + self.timeline.append((t, p["pid"])) + yield (t, p["pid"], []) + t += 1 + p["completion"] = t + done += 1 + + # priority preemptive + def _simulate_priority_p(self): + t = 0 + done = 0 + while done < len(self.processes): + ready = [p for p in self.processes if p["arrival"] <= t and p["remaining"] > 0] + if not ready: + t += 1 + yield (t, None, []) + continue + p = min(ready, key=lambda x: x["priority"]) + self.timeline.append((t, p["pid"])) + yield (t, p["pid"], []) + p["remaining"] -= 1 + if p["remaining"] == 0: + p["completion"] = t + 1 + done += 1 + t += 1 + + # round robin + def _simulate_rr(self): + t = 0 + q = [] + processes = sorted(self.processes, key=lambda p: p["arrival"]) + i = 0 + done = 0 + while done < len(processes): + while i < len(processes) and processes[i]["arrival"] <= t: + q.append(processes[i]) + i += 1 + if not q: + t += 1 + yield (t, None, []) + continue + p = q.pop(0) + burst = min(self.quantum, p["remaining"]) + for _ in range(burst): + self.timeline.append((t, p["pid"])) + yield (t, p["pid"], [x["pid"] for x in q]) + t += 1 + p["remaining"] -= 1 + while i < len(processes) and processes[i]["arrival"] <= t: + q.append(processes[i]) + i += 1 + if p["remaining"] > 0: + q.append(p) + else: + p["completion"] = t + done += 1 + + + def _calculate_stats(self): + for p in self.processes: + pid = p["pid"] + arrival = p["arrival"] + burst = p["burst"] + completion = p["completion"] + first_exec = next((t for t, pid2 in self.timeline if pid2 == pid), arrival) + tat = completion - arrival + wt = tat - burst + rt = first_exec - arrival + self.stats.append((pid, arrival, burst, completion, tat, wt, rt)) + +# Interface +class CPUSchedulerGUI: + def __init__(self, root): + self.root = root + self.root.title("CPU Scheduling Visualizer") + self.root.geometry("1000x700") + + self.processes = [] + self.setup_ui() + + def setup_ui(self): + top_frame = ttk.Frame(self.root) + top_frame.pack(pady=10) + + self.tree = ttk.Treeview(top_frame, columns=("pid", "arrival", "burst", "priority"), show="headings") + for col in self.tree["columns"]: + self.tree.heading(col, text=col.capitalize()) + self.tree.pack(side="left") + + form = ttk.Frame(top_frame) + form.pack(side="left", padx=10) + ttk.Label(form, text="PID").grid(row=0, column=0) + ttk.Label(form, text="Arrival").grid(row=1, column=0) + ttk.Label(form, text="Burst").grid(row=2, column=0) + ttk.Label(form, text="Priority").grid(row=3, column=0) + self.pid_e = ttk.Entry(form) + self.arrival_e = ttk.Entry(form) + self.burst_e = ttk.Entry(form) + self.priority_e = ttk.Entry(form) + self.pid_e.grid(row=0, column=1) + self.arrival_e.grid(row=1, column=1) + self.burst_e.grid(row=2, column=1) + self.priority_e.grid(row=3, column=1) + ttk.Button(form, text="Add", command=self.add_process).grid(row=4, column=0, pady=5) + ttk.Button(form, text="Delete", command=self.delete_process).grid(row=4, column=1) + + algo_frame = ttk.Frame(self.root) + algo_frame.pack(pady=10) + ttk.Label(algo_frame, text="Algorithm:").pack(side="left") + self.algo_cb = ttk.Combobox(algo_frame, values=[ + "FCFS", "SJF (Non-Preemptive)", "SJF (Preemptive)", + "Priority (Non-Preemptive)", "Priority (Preemptive)", "Round Robin" + ]) + self.algo_cb.current(0) + self.algo_cb.pack(side="left", padx=5) + ttk.Label(algo_frame, text="Quantum:").pack(side="left") + self.quantum_e = ttk.Entry(algo_frame, width=5) + self.quantum_e.insert(0, "2") + self.quantum_e.pack(side="left") + ttk.Button(algo_frame, text="Run", command=self.run_scheduling).pack(side="left", padx=10) + + self.ready_label = ttk.Label(self.root, text="Ready Queue:") + self.ready_list = tk.Listbox(self.root, height=3) + self.ready_label.pack_forget() + self.ready_list.pack_forget() + + self.figure, self.ax = plt.subplots(figsize=(8, 3)) + self.canvas = FigureCanvasTkAgg(self.figure, master=self.root) + self.canvas.get_tk_widget().pack() + + self.result_box = ttk.Treeview(self.root, + columns=("pid", "arrival", "burst", "completion", "tat", "wt", "rt"), + show="headings", height=6) + for col in self.result_box["columns"]: + self.result_box.heading(col, text=col.upper()) + self.result_box.pack(pady=10) + + self.avg_label = ttk.Label(self.root, text="", font=("Arial", 11, "bold")) + self.avg_label.pack() + + def add_process(self): + try: + pid = self.pid_e.get() + arrival = int(self.arrival_e.get()) + burst = int(self.burst_e.get()) + priority = int(self.priority_e.get() or 0) + self.processes.append({"pid": pid, "arrival": arrival, "burst": burst, "priority": priority}) + self.tree.insert("", "end", values=(pid, arrival, burst, priority)) + except ValueError: + messagebox.showerror("Error", "Invalid input") + + def delete_process(self): + sel = self.tree.selection() + if sel: + pid = self.tree.item(sel[0])["values"][0] + self.processes = [p for p in self.processes if p["pid"] != pid] + self.tree.delete(sel[0]) + + def run_scheduling(self): + algo = self.algo_cb.get() + quantum = int(self.quantum_e.get() or 2) + if algo.lower() == "round robin": + self.ready_label.pack() + self.ready_list.pack() + else: + self.ready_label.pack_forget() + self.ready_list.pack_forget() + + self.engine = SchedulerEngine(self.processes, algo, quantum) + threading.Thread(target=self.animate).start() + + def animate(self): + self.ax.clear() + x, colors, current_pid = 0, {}, None + for step in self.engine.simulate(): + t, pid, rq = step + if pid: + if pid != current_pid: + self.ax.axvline(x, color="black", linewidth=0.8) + current_pid = pid + colors.setdefault(pid, plt.cm.tab20(len(colors) % 20)) + self.ax.barh(0, 1, left=x, color=colors[pid]) + self.ax.text(x + 0.5, 0, pid, ha="center", va="center", color="white", fontsize=9) + x += 1 + self.ax.set_xticks(range(0, x + 1)) + self.ax.set_yticks([]) + self.ax.set_xlabel("Time") + self.canvas.draw() + if rq: + self.ready_list.delete(0, tk.END) + for pid_r in rq: + self.ready_list.insert(tk.END, pid_r) + time.sleep(0.3) + self.show_results() + + def show_results(self): + for item in self.result_box.get_children(): + self.result_box.delete(item) + total_wt = total_tat = total_rt = 0 + for row in self.engine.stats: + self.result_box.insert("", "end", values=row) + total_wt += row[5] + total_tat += row[4] + total_rt += row[6] + n = len(self.engine.stats) + self.avg_label.config(text=f"AVG WT = {total_wt/n:.2f} | AVG TAT = {total_tat/n:.2f} | AVG RT = {total_rt/n:.2f}") + +# main call +if __name__ == "__main__": + root = tk.Tk() + CPUSchedulerGUI(root) + root.mainloop() + From 15f913a513c867be438612832dd2da3000dc8b5a Mon Sep 17 00:00:00 2001 From: shashwat-126 Date: Tue, 4 Nov 2025 23:56:39 +0530 Subject: [PATCH 2/3] Added README and CPU Scheduling Interface --- scheduling/cpu_scheduling_interface.py | 153 +++++++++++++----- ...INTERFACE.md => cpuschedulinginterface.md} | 0 2 files changed, 111 insertions(+), 42 deletions(-) rename scheduling/{CPU SCH INTERFACE.md => cpuschedulinginterface.md} (100%) diff --git a/scheduling/cpu_scheduling_interface.py b/scheduling/cpu_scheduling_interface.py index 6eaaa2650171..b0824f56dc5c 100644 --- a/scheduling/cpu_scheduling_interface.py +++ b/scheduling/cpu_scheduling_interface.py @@ -1,20 +1,24 @@ +import copy +import threading +import time import tkinter as tk -from tkinter import ttk, messagebox +from tkinter import messagebox, ttk + import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg -import threading, time, copy + # ===================== Scheduler Engine ===================== # class SchedulerEngine: - def __init__(self, processes, algorithm, quantum=2): + def __init__(self, processes, algorithm, quantum: int = 2): self.original = copy.deepcopy(processes) self.processes = [p.copy() for p in processes] self.algorithm = algorithm self.quantum = quantum for p in self.processes: p["remaining"] = p["burst"] - self.timeline = [] # [(time, pid)] - self.stats = [] + self.timeline: list[tuple[int, str]] = [] # [(time, pid)] + self.stats: list[tuple] = [] def simulate(self): algo = self.algorithm.lower() @@ -32,26 +36,30 @@ def simulate(self): yield from self._simulate_rr() self._calculate_stats() - #first come first serve + # first come first serve def _simulate_fcfs(self): t = 0 processes = sorted(self.processes, key=lambda p: p["arrival"]) for p in processes: - if t < p["arrival"]: - t = p["arrival"] + t = max(t, p["arrival"]) for _ in range(p["burst"]): self.timeline.append((t, p["pid"])) yield (t, p["pid"], []) t += 1 p["completion"] = t - - #shortest job first non preemptive + + # shortest job first non preemptive def _simulate_sjf_np(self): t = 0 processes = sorted(self.processes, key=lambda p: p["arrival"]) done = 0 while done < len(processes): - ready = [p for p in processes if p["arrival"] <= t and "completion" not in p] + ready = [ + p + for p in processes + if p["arrival"] <= t and "completion" not in p + ] + if not ready: t += 1 yield (t, None, []) @@ -63,14 +71,18 @@ def _simulate_sjf_np(self): t += 1 p["completion"] = t done += 1 - + # shortest job first preemptive def _simulate_sjf_p(self): t = 0 processes = sorted(self.processes, key=lambda p: p["arrival"]) done = 0 while done < len(processes): - ready = [p for p in processes if p["arrival"] <= t and p["remaining"] > 0] + ready = [ + p + for p in processes + if p["arrival"] <= t and p["remaining"] > 0 + ] if not ready: t += 1 yield (t, None, []) @@ -83,13 +95,18 @@ def _simulate_sjf_p(self): p["completion"] = t + 1 done += 1 t += 1 - - # priority non preemptive + + # priority non preemptive def _simulate_priority_np(self): t = 0 done = 0 while done < len(self.processes): - ready = [p for p in self.processes if p["arrival"] <= t and "completion" not in p] + ready = [ + p + for p in self.processes + if p["arrival"] <= t and "completion" not in p + ] + if not ready: t += 1 yield (t, None, []) @@ -102,12 +119,17 @@ def _simulate_priority_np(self): p["completion"] = t done += 1 - # priority preemptive + # priority preemptive def _simulate_priority_p(self): t = 0 done = 0 while done < len(self.processes): - ready = [p for p in self.processes if p["arrival"] <= t and p["remaining"] > 0] + ready = [ + p + for p in self.processes + if p["arrival"] <= t and p["remaining"] > 0 + ] + if not ready: t += 1 yield (t, None, []) @@ -124,7 +146,7 @@ def _simulate_priority_p(self): # round robin def _simulate_rr(self): t = 0 - q = [] + q: list[dict] = [] processes = sorted(self.processes, key=lambda p: p["arrival"]) i = 0 done = 0 @@ -152,34 +174,41 @@ def _simulate_rr(self): p["completion"] = t done += 1 - def _calculate_stats(self): for p in self.processes: pid = p["pid"] arrival = p["arrival"] burst = p["burst"] completion = p["completion"] - first_exec = next((t for t, pid2 in self.timeline if pid2 == pid), arrival) + first_exec = next( + (t for t, pid2 in self.timeline if pid2 == pid), arrival + ) tat = completion - arrival wt = tat - burst rt = first_exec - arrival self.stats.append((pid, arrival, burst, completion, tat, wt, rt)) -# Interface + +# Interface class CPUSchedulerGUI: def __init__(self, root): self.root = root self.root.title("CPU Scheduling Visualizer") self.root.geometry("1000x700") - self.processes = [] + self.processes: list[dict] = [] self.setup_ui() def setup_ui(self): top_frame = ttk.Frame(self.root) top_frame.pack(pady=10) - self.tree = ttk.Treeview(top_frame, columns=("pid", "arrival", "burst", "priority"), show="headings") + self.tree = ttk.Treeview( + top_frame, + columns=("pid", "arrival", "burst", "priority"), + show="headings", + ) + for col in self.tree["columns"]: self.tree.heading(col, text=col.capitalize()) self.tree.pack(side="left") @@ -198,23 +227,37 @@ def setup_ui(self): self.arrival_e.grid(row=1, column=1) self.burst_e.grid(row=2, column=1) self.priority_e.grid(row=3, column=1) - ttk.Button(form, text="Add", command=self.add_process).grid(row=4, column=0, pady=5) - ttk.Button(form, text="Delete", command=self.delete_process).grid(row=4, column=1) + ttk.Button(form, text="Add", command=self.add_process).grid( + row=4, column=0, pady=5 + ) + + ttk.Button(form, text="Delete", command=self.delete_process).grid( + row=4, column=1 + ) algo_frame = ttk.Frame(self.root) algo_frame.pack(pady=10) ttk.Label(algo_frame, text="Algorithm:").pack(side="left") - self.algo_cb = ttk.Combobox(algo_frame, values=[ - "FCFS", "SJF (Non-Preemptive)", "SJF (Preemptive)", - "Priority (Non-Preemptive)", "Priority (Preemptive)", "Round Robin" - ]) + self.algo_cb = ttk.Combobox( + algo_frame, + values=[ + "FCFS", + "SJF (Non-Preemptive)", + "SJF (Preemptive)", + "Priority (Non-Preemptive)", + "Priority (Preemptive)", + "Round Robin", + ], + ) self.algo_cb.current(0) self.algo_cb.pack(side="left", padx=5) ttk.Label(algo_frame, text="Quantum:").pack(side="left") self.quantum_e = ttk.Entry(algo_frame, width=5) self.quantum_e.insert(0, "2") self.quantum_e.pack(side="left") - ttk.Button(algo_frame, text="Run", command=self.run_scheduling).pack(side="left", padx=10) + ttk.Button(algo_frame, text="Run", command=self.run_scheduling).pack( + side="left", padx=10 + ) self.ready_label = ttk.Label(self.root, text="Ready Queue:") self.ready_list = tk.Listbox(self.root, height=3) @@ -225,9 +268,13 @@ def setup_ui(self): self.canvas = FigureCanvasTkAgg(self.figure, master=self.root) self.canvas.get_tk_widget().pack() - self.result_box = ttk.Treeview(self.root, - columns=("pid", "arrival", "burst", "completion", "tat", "wt", "rt"), - show="headings", height=6) + self.result_box = ttk.Treeview( + self.root, + columns=("pid", "arrival", "burst", "completion", "tat", "wt", "rt"), + show="headings", + height=6, + ) + for col in self.result_box["columns"]: self.result_box.heading(col, text=col.upper()) self.result_box.pack(pady=10) @@ -241,7 +288,14 @@ def add_process(self): arrival = int(self.arrival_e.get()) burst = int(self.burst_e.get()) priority = int(self.priority_e.get() or 0) - self.processes.append({"pid": pid, "arrival": arrival, "burst": burst, "priority": priority}) + self.processes.append( + { + "pid": pid, + "arrival": arrival, + "burst": burst, + "priority": priority, + } + ) self.tree.insert("", "end", values=(pid, arrival, burst, priority)) except ValueError: messagebox.showerror("Error", "Invalid input") @@ -264,22 +318,31 @@ def run_scheduling(self): self.ready_list.pack_forget() self.engine = SchedulerEngine(self.processes, algo, quantum) - threading.Thread(target=self.animate).start() + threading.Thread(target=self.animate, daemon=True).start() def animate(self): self.ax.clear() x, colors, current_pid = 0, {}, None for step in self.engine.simulate(): - t, pid, rq = step + _, pid, rq = step if pid: if pid != current_pid: self.ax.axvline(x, color="black", linewidth=0.8) current_pid = pid colors.setdefault(pid, plt.cm.tab20(len(colors) % 20)) self.ax.barh(0, 1, left=x, color=colors[pid]) - self.ax.text(x + 0.5, 0, pid, ha="center", va="center", color="white", fontsize=9) + self.ax.text( + x + 0.5, + 0, + pid, + ha="center", + va="center", + color="white", + fontsize=9, + ) + x += 1 - self.ax.set_xticks(range(0, x + 1)) + self.ax.set_xticks(range(x + 1)) self.ax.set_yticks([]) self.ax.set_xlabel("Time") self.canvas.draw() @@ -299,12 +362,18 @@ def show_results(self): total_wt += row[5] total_tat += row[4] total_rt += row[6] - n = len(self.engine.stats) - self.avg_label.config(text=f"AVG WT = {total_wt/n:.2f} | AVG TAT = {total_tat/n:.2f} | AVG RT = {total_rt/n:.2f}") + n = len(self.engine.stats) or 1 + self.avg_label.config( + text=( + f"AVG WT = {total_wt/n:.2f} | " + f"AVG TAT = {total_tat/n:.2f} | " + f"AVG RT = {total_rt/n:.2f}" + ) + ) + # main call if __name__ == "__main__": root = tk.Tk() CPUSchedulerGUI(root) root.mainloop() - diff --git a/scheduling/CPU SCH INTERFACE.md b/scheduling/cpuschedulinginterface.md similarity index 100% rename from scheduling/CPU SCH INTERFACE.md rename to scheduling/cpuschedulinginterface.md From cbff732322b7711d1e9da72024ff39472e0e43c6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 5 Nov 2025 13:51:02 +0000 Subject: [PATCH 3/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- scheduling/cpu_scheduling_interface.py | 31 ++++++++------------------ scheduling/cpuschedulinginterface.md | 26 ++++++++++----------- 2 files changed, 22 insertions(+), 35 deletions(-) diff --git a/scheduling/cpu_scheduling_interface.py b/scheduling/cpu_scheduling_interface.py index b0824f56dc5c..fb51194125f7 100644 --- a/scheduling/cpu_scheduling_interface.py +++ b/scheduling/cpu_scheduling_interface.py @@ -55,9 +55,7 @@ def _simulate_sjf_np(self): done = 0 while done < len(processes): ready = [ - p - for p in processes - if p["arrival"] <= t and "completion" not in p + p for p in processes if p["arrival"] <= t and "completion" not in p ] if not ready: @@ -78,11 +76,7 @@ def _simulate_sjf_p(self): processes = sorted(self.processes, key=lambda p: p["arrival"]) done = 0 while done < len(processes): - ready = [ - p - for p in processes - if p["arrival"] <= t and p["remaining"] > 0 - ] + ready = [p for p in processes if p["arrival"] <= t and p["remaining"] > 0] if not ready: t += 1 yield (t, None, []) @@ -102,9 +96,7 @@ def _simulate_priority_np(self): done = 0 while done < len(self.processes): ready = [ - p - for p in self.processes - if p["arrival"] <= t and "completion" not in p + p for p in self.processes if p["arrival"] <= t and "completion" not in p ] if not ready: @@ -125,9 +117,7 @@ def _simulate_priority_p(self): done = 0 while done < len(self.processes): ready = [ - p - for p in self.processes - if p["arrival"] <= t and p["remaining"] > 0 + p for p in self.processes if p["arrival"] <= t and p["remaining"] > 0 ] if not ready: @@ -180,9 +170,7 @@ def _calculate_stats(self): arrival = p["arrival"] burst = p["burst"] completion = p["completion"] - first_exec = next( - (t for t, pid2 in self.timeline if pid2 == pid), arrival - ) + first_exec = next((t for t, pid2 in self.timeline if pid2 == pid), arrival) tat = completion - arrival wt = tat - burst rt = first_exec - arrival @@ -301,8 +289,7 @@ def add_process(self): messagebox.showerror("Error", "Invalid input") def delete_process(self): - sel = self.tree.selection() - if sel: + if sel := self.tree.selection(): pid = self.tree.item(sel[0])["values"][0] self.processes = [p for p in self.processes if p["pid"] != pid] self.tree.delete(sel[0]) @@ -365,9 +352,9 @@ def show_results(self): n = len(self.engine.stats) or 1 self.avg_label.config( text=( - f"AVG WT = {total_wt/n:.2f} | " - f"AVG TAT = {total_tat/n:.2f} | " - f"AVG RT = {total_rt/n:.2f}" + f"AVG WT = {total_wt / n:.2f} | " + f"AVG TAT = {total_tat / n:.2f} | " + f"AVG RT = {total_rt / n:.2f}" ) ) diff --git a/scheduling/cpuschedulinginterface.md b/scheduling/cpuschedulinginterface.md index af3109e99a7a..5ab91f56c9c3 100644 --- a/scheduling/cpuschedulinginterface.md +++ b/scheduling/cpuschedulinginterface.md @@ -4,20 +4,20 @@ -A **GUI-based CPU Scheduling Algorithm Visualizer** built using **Python**, **Tkinter**, and **Matplotlib**. +A **GUI-based CPU Scheduling Algorithm Visualizer** built using **Python**, **Tkinter**, and **Matplotlib**. It allows users to add custom processes and simulate various scheduling algorithms with **real-time Gantt chart animation**, **ready queue visualization**, and **performance statistics**. --- ## ๐Ÿš€ Features -โœ… Interactive **Tkinter GUI** -โœ… Supports multiple **CPU scheduling algorithms** -โœ… Real-time **Gantt chart animation** using Matplotlib -โœ… Displays **Ready Queue** (for Round Robin & Preemptive algorithms) -โœ… Shows **average waiting time**, **turnaround time**, and **response time** -โœ… Add or delete processes dynamically -โœ… Clean and responsive design +โœ… Interactive **Tkinter GUI** +โœ… Supports multiple **CPU scheduling algorithms** +โœ… Real-time **Gantt chart animation** using Matplotlib +โœ… Displays **Ready Queue** (for Round Robin & Preemptive algorithms) +โœ… Shows **average waiting time**, **turnaround time**, and **response time** +โœ… Add or delete processes dynamically +โœ… Clean and responsive design --- @@ -60,7 +60,7 @@ Displays process execution in timeline order, showing process IDs along the time ## ๐Ÿง  Working -1. Enter process details (`PID`, `Arrival`, `Burst`, `Priority`) +1. Enter process details (`PID`, `Arrival`, `Burst`, `Priority`) 2. Choose your desired **Scheduling Algorithm** 3. (Optional) Enter Quantum value (for Round Robin) 4. Click **Run** @@ -72,9 +72,9 @@ Displays process execution in timeline order, showing process IDs along the time ## ๐Ÿ› ๏ธ Tech Stack - **Python 3.8+** -- **Tkinter** โ†’ GUI Framework -- **Matplotlib** โ†’ Animation and Gantt Chart -- **Threading** โ†’ Live simulation without freezing GUI +- **Tkinter** โ†’ GUI Framework +- **Matplotlib** โ†’ Animation and Gantt Chart +- **Threading** โ†’ Live simulation without freezing GUI --- @@ -115,4 +115,4 @@ Shashwat Made with โค๏ธ using Python & Tkinter - +