11"""
2- Shortest job remaining first
3- Please note arrival time and burst
4- Please use spaces to separate times entered.
2+ Shortest Job Remaining First (Preemptive SJF)
3+ ---------------------------------------------
4+ Please note arrival time and burst time.
5+ Use spaces to separate times entered.
56"""
67
78from __future__ import annotations
8-
99import pandas as pd
10+ import matplotlib .pyplot as plt
1011
1112
1213def calculate_waitingtime (
1314 arrival_time : list [int ], burst_time : list [int ], no_of_processes : int
14- ) -> list [int ]:
15+ ) -> tuple [ list [int ], list [ tuple [ int , int , int ]] ]:
1516 """
16- Calculate the waiting time of each processes
17- Return: List of waiting times.
18- >>> calculate_waitingtime([1,2,3,4],[3,3,5,1],4)
19- [0, 3, 5, 0]
20- >>> calculate_waitingtime([1,2,3],[2,5,1],3)
21- [0, 2, 0]
22- >>> calculate_waitingtime([2,3],[5,1],2)
23- [1, 0]
17+ Calculate the waiting time for each process and record execution timeline for Gantt Chart.
18+ Returns: (waiting_time, timeline)
19+ timeline -> list of tuples: (start_time, end_time, process_id)
2420 """
25- remaining_time = [ 0 ] * no_of_processes
21+ remaining_time = burst_time . copy ()
2622 waiting_time = [0 ] * no_of_processes
27- # Copy the burst time into remaining_time[]
28- for i in range (no_of_processes ):
29- remaining_time [i ] = burst_time [i ]
30-
3123 complete = 0
3224 increment_time = 0
33- minm = 999999999
25+ minm = float ( "inf" )
3426 short = 0
3527 check = False
3628
37- # Process until all processes are completed
29+ timeline = [] # To store execution sequence for Gantt chart
30+ last_process = - 1
31+
3832 while complete != no_of_processes :
3933 for j in range (no_of_processes ):
4034 if (
@@ -49,43 +43,41 @@ def calculate_waitingtime(
4943 if not check :
5044 increment_time += 1
5145 continue
52- remaining_time [short ] -= 1
5346
47+ # Record when process switches (for Gantt chart)
48+ if short != last_process :
49+ if timeline and timeline [- 1 ][2 ] == last_process :
50+ timeline [- 1 ] = (timeline [- 1 ][0 ], increment_time , last_process )
51+ if short != - 1 :
52+ timeline .append ((increment_time , None , short ))
53+ last_process = short
54+
55+ remaining_time [short ] -= 1
5456 minm = remaining_time [short ]
5557 if minm == 0 :
56- minm = 999999999
58+ minm = float ( "inf" )
5759
5860 if remaining_time [short ] == 0 :
5961 complete += 1
6062 check = False
61-
62- # Find finish time of current process
6363 finish_time = increment_time + 1
64-
65- # Calculate waiting time
6664 finar = finish_time - arrival_time [short ]
6765 waiting_time [short ] = finar - burst_time [short ]
68-
6966 waiting_time [short ] = max (waiting_time [short ], 0 )
7067
71- # Increment time
7268 increment_time += 1
73- return waiting_time
69+
70+ # Close last ongoing process in timeline
71+ if timeline and timeline [- 1 ][1 ] is None :
72+ timeline [- 1 ] = (timeline [- 1 ][0 ], increment_time , last_process )
73+
74+ return waiting_time , timeline
7475
7576
7677def calculate_turnaroundtime (
7778 burst_time : list [int ], no_of_processes : int , waiting_time : list [int ]
7879) -> list [int ]:
79- """
80- Calculate the turn around time of each Processes
81- Return: list of turn around times.
82- >>> calculate_turnaroundtime([3,3,5,1], 4, [0,3,5,0])
83- [3, 6, 10, 1]
84- >>> calculate_turnaroundtime([3,3], 2, [0,3])
85- [3, 6]
86- >>> calculate_turnaroundtime([8,10,1], 3, [1,0,3])
87- [9, 10, 4]
88- """
80+ """Calculate the turn around time for each process."""
8981 turn_around_time = [0 ] * no_of_processes
9082 for i in range (no_of_processes ):
9183 turn_around_time [i ] = burst_time [i ] + waiting_time [i ]
@@ -94,60 +86,64 @@ def calculate_turnaroundtime(
9486
9587def calculate_average_times (
9688 waiting_time : list [int ], turn_around_time : list [int ], no_of_processes : int
97- ) -> None :
98- """
99- This function calculates the average of the waiting & turnaround times
100- Prints: Average Waiting time & Average Turn Around Time
101- >>> calculate_average_times([0,3,5,0],[3,6,10,1],4)
102- Average waiting time = 2.00000
103- Average turn around time = 5.0
104- >>> calculate_average_times([2,3],[3,6],2)
105- Average waiting time = 2.50000
106- Average turn around time = 4.5
107- >>> calculate_average_times([10,4,3],[2,7,6],3)
108- Average waiting time = 5.66667
109- Average turn around time = 5.0
110- """
111- total_waiting_time = 0
112- total_turn_around_time = 0
113- for i in range (no_of_processes ):
114- total_waiting_time = total_waiting_time + waiting_time [i ]
115- total_turn_around_time = total_turn_around_time + turn_around_time [i ]
116- print (f"Average waiting time = { total_waiting_time / no_of_processes :.5f} " )
117- print ("Average turn around time =" , total_turn_around_time / no_of_processes )
89+ ) -> tuple [float , float ]:
90+ """Calculate and return average waiting and turnaround times."""
91+ avg_wait = sum (waiting_time ) / no_of_processes
92+ avg_turn = sum (turn_around_time ) / no_of_processes
93+ print (f"Average waiting time = { avg_wait :.5f} " )
94+ print (f"Average turn around time = { avg_turn :.5f} " )
95+ return avg_wait , avg_turn
96+
97+
98+ def plot_gantt_chart (timeline : list [tuple [int , int , int ]], processes : list [int ]) -> None :
99+ """Plot a Gantt chart for process execution."""
100+ fig , ax = plt .subplots (figsize = (10 , 2 ))
101+ colors = plt .cm .tab10 .colors # Nice color set
102+ for start , end , pid in timeline :
103+ ax .barh (
104+ 0 ,
105+ end - start ,
106+ left = start ,
107+ color = colors [pid % len (colors )],
108+ edgecolor = "black" ,
109+ label = f"P{ processes [pid ]} " ,
110+ )
111+ ax .text ((start + end ) / 2 , 0 , f"P{ processes [pid ]} " , ha = "center" , va = "center" , color = "white" , fontsize = 9 )
112+
113+ ax .set_xlabel ("Time" )
114+ ax .set_yticks ([])
115+ ax .set_title ("Gantt Chart - Shortest Job Remaining First (SJF Preemptive)" )
116+ handles , labels = plt .gca ().get_legend_handles_labels ()
117+ by_label = dict (zip (labels , handles ))
118+ ax .legend (by_label .values (), by_label .keys (), bbox_to_anchor = (1.05 , 1 ), loc = "upper left" )
119+ plt .tight_layout ()
120+ plt .show ()
118121
119122
120123if __name__ == "__main__" :
121- print ("Enter how many process you want to analyze" )
122- no_of_processes = int (input ())
124+ print ("Enter how many processes you want to analyze:" )
125+ no_of_processes = int (input ().strip ())
126+
123127 burst_time = [0 ] * no_of_processes
124128 arrival_time = [0 ] * no_of_processes
125129 processes = list (range (1 , no_of_processes + 1 ))
126130
127131 for i in range (no_of_processes ):
128- print ("Enter the arrival time and burst time for process:--" + str ( i + 1 ) )
132+ print (f "Enter the arrival time and burst time for process { i + 1 } :" )
129133 arrival_time [i ], burst_time [i ] = map (int , input ().split ())
130134
131- waiting_time = calculate_waitingtime (arrival_time , burst_time , no_of_processes )
132-
133- bt = burst_time
134- n = no_of_processes
135- wt = waiting_time
136- turn_around_time = calculate_turnaroundtime (bt , n , wt )
137-
135+ waiting_time , timeline = calculate_waitingtime (arrival_time , burst_time , no_of_processes )
136+ turn_around_time = calculate_turnaroundtime (burst_time , no_of_processes , waiting_time )
138137 calculate_average_times (waiting_time , turn_around_time , no_of_processes )
139138
140- fcfs = pd .DataFrame (
141- list (zip (processes , burst_time , arrival_time , waiting_time , turn_around_time )),
142- columns = [
143- "Process" ,
144- "BurstTime" ,
145- "ArrivalTime" ,
146- "WaitingTime" ,
147- "TurnAroundTime" ,
148- ],
139+ # Display results table
140+ df = pd .DataFrame (
141+ list (zip (processes , arrival_time , burst_time , waiting_time , turn_around_time )),
142+ columns = ["Process" , "ArrivalTime" , "BurstTime" , "WaitingTime" , "TurnAroundTime" ],
149143 )
144+ pd .set_option ("display.max_rows" , df .shape [0 ] + 1 )
145+ print ("\n --- Process Table ---" )
146+ print (df )
150147
151- # Printing the dataFrame
152- pd .set_option ("display.max_rows" , fcfs .shape [0 ] + 1 )
153- print (fcfs )
148+ # Plot Gantt chart
149+ plot_gantt_chart (timeline , processes )
0 commit comments