'''

SJF: Shortest Job First

The task is to find the Average Waiting Time and Average Turnaround Time of the given processes with their Burst Time using SJF Scheduling Algorithm.

SJF is a scheduling policy that selects the waiting process with the smallest execution time to execute next.

SJF is a Non Pre-emptive Algorithm, hence the process which has the least Burst Time will be served first and the next process will be served only after the previous process is executed completely.

SJF has the advantage of having a minimum average waiting time among all scheduling algorithms.

Start Time: Time at which the execution of the process starts

Completion Time: Time at which the process completes its execution

Turnaround Time: Completion Time - Arrival Time

Waiting Time: Turnaround Time - Burst Time

I have made use of 2 queues in the code:

Ready Queue: It stores all the processes which have already arrived.

Normal Queue: It stores all the processes which have not arrived yet.

'''

class SJF:

def processData(self, no_of_processes):

process_data = []

for i in range(no_of_processes):

temporary = []

process_id = int(input("Enter Process ID: "))

arrival_time = int(input(f"Enter Arrival Time for Process {process_id}: "))

burst_time = int(input(f"Enter Burst Time for Process {process_id}: "))

temporary.extend([process_id, arrival_time, burst_time, 0])

'''

'0' is the state of the process. 0 means not executed and 1 means execution complete

'''

process_data.append(temporary)

SJF.schedulingProcess(self, process_data)

def schedulingProcess(self, process_data):

start_time = []

exit_time = []

s_time = 0

process_data.sort(key=lambda x: x[1])

'''

Sort processes according to the Arrival Time

'''

for i in range(len(process_data)):

ready_queue = []

temp = []

normal_queue = []

for j in range(len(process_data)):

if (process_data[j][1] <= s_time) and (process_data[j][3] == 0):

temp.extend([process_data[j][0], process_data[j][1], process_data[j][2]])

ready_queue.append(temp)

temp = []

elif process_data[j][3] == 0:

temp.extend([process_data[j][0], process_data[j][1], process_data[j][2]])

normal_queue.append(temp)

temp = []

if len(ready_queue) != 0:

ready_queue.sort(key=lambda x: x[2])

'''

Sort the processes according to the Burst Time

'''

start_time.append(s_time)

s_time = s_time + ready_queue[0][2]

e_time = s_time

exit_time.append(e_time)

for k in range(len(process_data)):

if process_data[k][0] == ready_queue[0][0]:

break

process_data[k][3] = 1

process_data[k].append(e_time)

elif len(ready_queue) == 0:

if s_time < normal_queue[0][1]:

s_time = normal_queue[0][1]

start_time.append(s_time)

s_time = s_time + normal_queue[0][2]

e_time = s_time

exit_time.append(e_time)

for k in range(len(process_data)):

if process_data[k][0] == normal_queue[0][0]:

break

process_data[k][3] = 1

process_data[k].append(e_time)

t_time = SJF.calculateTurnaroundTime(self, process_data)

w_time = SJF.calculateWaitingTime(self, process_data)

SJF.printData(self, process_data, t_time, w_time)

def calculateTurnaroundTime(self, process_data):

total_turnaround_time = 0

for i in range(len(process_data)):

turnaround_time = process_data[i][4] - process_data[i][1]

'''

turnaround_time = completion_time - arrival_time

'''

total_turnaround_time = total_turnaround_time + turnaround_time

process_data[i].append(turnaround_time)

average_turnaround_time = total_turnaround_time / len(process_data)

'''

average_turnaround_time = total_turnaround_time / no_of_processes

'''

return average_turnaround_time

def calculateWaitingTime(self, process_data):

total_waiting_time = 0

for i in range(len(process_data)):

waiting_time = process_data[i][5] - process_data[i][2]

'''

waiting_time = turnaround_time - burst_time

'''

total_waiting_time = total_waiting_time + waiting_time

process_data[i].append(waiting_time)

average_waiting_time = total_waiting_time / len(process_data)

'''

average_waiting_time = total_waiting_time / no_of_processes

'''

return average_waiting_time

def printData(self, process_data, average_turnaround_time, average_waiting_time):

process_data.sort(key=lambda x: x[0])

'''

Sort processes according to the Process ID

'''

print("Process_ID Arrival_Time Burst_Time Completed Completion_Time Turnaround_Time Waiting_Time")

for i in range(len(process_data)):

for j in range(len(process_data[i])):

print(process_data[i][j], end=" ")

print()

print(f'Average Turnaround Time: {average_turnaround_time}')

print(f'Average Waiting Time: {average_waiting_time}')

if __name__ == "__main__":

no_of_processes = int(input("Enter number of processes: "))

sjf = SJF()

sjf.processData(no_of_processes)

Output:

## Comments