


'''simple docstring'''

from collections import deque
class   __lowerCAmelCase						:





      '''simple docstring'''






      def __init__(self    :    Optional[Any]   ,						UpperCamelCase    :    List[str]   ,						UpperCamelCase    :    Optional[Any]   ,						UpperCamelCase    :    Optional[Any] ):

             '''simple docstring'''







             lowercase__      			= process_name  # process name
             lowercase__      			= arrival_time  # arrival time of the process
             # completion time of finished process or last interrupted time
             lowercase__      			= arrival_time
             lowercase__      			= burst_time  # remaining burst time
             lowercase__      			= 0  # total time of the process wait in ready queue
             lowercase__      			= 0  # time from arrival time to completion time






class   __lowerCAmelCase						:





      '''simple docstring'''






      def __init__(self    :    List[str]   ,						UpperCamelCase    :    Any   ,						UpperCamelCase    :    Optional[Any]   ,						UpperCamelCase    :    Dict   ,						UpperCamelCase    :    Tuple   ,						):

             '''simple docstring'''







             lowercase__      			= number_of_queues
             # time slice of queues that round robin algorithm applied
             lowercase__      			= time_slices
             # unfinished process is in this ready_queue
             lowercase__      			= queue
             # current time
             lowercase__      			= current_time
             # finished process is in this sequence queue
             lowercase__      			= deque()



      def       UpperCamelCase__		(self    :    Optional[int] ):

             '''simple docstring'''







             lowercase__      			= []
             for i in range(len(self.finish_queue ) ):
                    sequence.append(self.finish_queue[i].process_name )
             return sequence



      def       UpperCamelCase__		(self    :    List[Any]   ,						UpperCamelCase    :    Dict ):

             '''simple docstring'''







             lowercase__      			= []
             for i in range(len(UpperCamelCase ) ):
                    waiting_times.append(queue[i].waiting_time )
             return waiting_times



      def       UpperCamelCase__		(self    :    Dict   ,						UpperCamelCase    :    str ):

             '''simple docstring'''







             lowercase__      			= []
             for i in range(len(UpperCamelCase ) ):
                    turnaround_times.append(queue[i].turnaround_time )
             return turnaround_times



      def       UpperCamelCase__		(self    :    Dict   ,						UpperCamelCase    :    Dict ):

             '''simple docstring'''







             lowercase__      			= []
             for i in range(len(UpperCamelCase ) ):
                    completion_times.append(queue[i].stop_time )
             return completion_times



      def       UpperCamelCase__		(self    :    Optional[int]   ,						UpperCamelCase    :    Optional[int] ):

             '''simple docstring'''







             return [q.burst_time for q in queue]



      def       UpperCamelCase__		(self    :    List[str]   ,						UpperCamelCase    :    List[Any] ):

             '''simple docstring'''







             process.waiting_time += self.current_time - process.stop_time
             return process.waiting_time



      def       UpperCamelCase__		(self    :    Dict   ,						UpperCamelCase    :    Union[str, Any] ):

             '''simple docstring'''







             lowercase__      			= deque()  # sequence deque of finished process
             while len(UpperCamelCase ) != 0:
                    lowercase__      			= ready_queue.popleft()  # current process

                    # if process's arrival time is later than current time, update current time
                    if self.current_time < cp.arrival_time:
                           self.current_time += cp.arrival_time

                    # update waiting time of current process
                    self.update_waiting_time(UpperCamelCase )
                    # update current time
                    self.current_time += cp.burst_time
                    # finish the process and set the process's burst-time 0
                    lowercase__      			= 0
                    # set the process's turnaround time because it is finished
                    lowercase__      			= self.current_time - cp.arrival_time
                    # set the completion time
                    lowercase__      			= self.current_time
                    # add the process to queue that has finished queue
                    finished.append(UpperCamelCase )

             self.finish_queue.extend(UpperCamelCase )  # add finished process to finish queue
             # FCFS will finish all remaining processes
             return finished



      def       UpperCamelCase__		(self    :    Union[str, Any]   ,						UpperCamelCase    :    Dict   ,						UpperCamelCase    :    Tuple ):

             '''simple docstring'''







             lowercase__      			= deque()  # sequence deque of terminated process
             # just for 1 cycle and unfinished processes will go back to queue
             for _ in range(len(UpperCamelCase ) ):
                    lowercase__      			= ready_queue.popleft()  # current process

                    # if process's arrival time is later than current time, update current time
                    if self.current_time < cp.arrival_time:
                           self.current_time += cp.arrival_time

                    # update waiting time of unfinished processes
                    self.update_waiting_time(UpperCamelCase )
                    # if the burst time of process is bigger than time-slice
                    if cp.burst_time > time_slice:
                           # use CPU for only time-slice
                           self.current_time += time_slice
                           # update remaining burst time
                           cp.burst_time -= time_slice
                           # update end point time
                           lowercase__      			= self.current_time
                           # locate the process behind the queue because it is not finished
                           ready_queue.append(UpperCamelCase )
                    else:
                           # use CPU for remaining burst time
                           self.current_time += cp.burst_time
                           # set burst time 0 because the process is finished
                           lowercase__      			= 0
                           # set the finish time
                           lowercase__      			= self.current_time
                           # update the process' turnaround time because it is finished
                           lowercase__      			= self.current_time - cp.arrival_time
                           # add the process to queue that has finished queue
                           finished.append(UpperCamelCase )

             self.finish_queue.extend(UpperCamelCase )  # add finished process to finish queue
             # return finished processes queue and remaining processes queue
             return finished, ready_queue






      def       UpperCamelCase__		(self    :    List[str] ):

             '''simple docstring'''







             for i in range(self.number_of_queues - 1 ):
                    lowercase__      			= self.round_robin(
                        self.ready_queue   ,						self.time_slices[i] )
             #  the last queue has first_come_first_served algorithm
             self.first_come_first_served(self.ready_queue )

             return self.finish_queue


if __name__ == "__main__":
 import doctest

 lowerCamelCase							:   Union[str, Any]  						=	Process('P1', 0, 53)
 lowerCamelCase							:   Tuple  						=	Process('P2', 0, 17)
 lowerCamelCase							:   Optional[Any]  						=	Process('P3', 0, 68)
 lowerCamelCase							:   int  						=	Process('P4', 0, 24)
 lowerCamelCase							:   Tuple  						=	3
 lowerCamelCase							:   Dict  						=	[17, 25]
 lowerCamelCase							:   Any  						=	deque([Pa, Pa, Pa, Pa])

 if len(time_slices) != number_of_queues - 1:
  raise SystemExit(0)

 doctest.testmod(extraglobs={'queue': deque([Pa, Pa, Pa, Pa])})

 lowerCamelCase							:   Optional[int]  						=	Process('P1', 0, 53)
 lowerCamelCase							:   Optional[Any]  						=	Process('P2', 0, 17)
 lowerCamelCase							:   Union[str, Any]  						=	Process('P3', 0, 68)
 lowerCamelCase							:   List[Any]  						=	Process('P4', 0, 24)
 lowerCamelCase							:   Optional[Any]  						=	3
 lowerCamelCase							:   Union[str, Any]  						=	[17, 25]
 lowerCamelCase							:   Optional[int]  						=	deque([Pa, Pa, Pa, Pa])
 lowerCamelCase							:   str  						=	MLFQ(number_of_queues, time_slices, queue, 0)
 lowerCamelCase							:   Optional[Any]  						=	mlfq.multi_level_feedback_queue()

 # print total waiting times of processes(P1, P2, P3, P4)
 print(
     f"""waiting time:\
        \t\t\t{MLFQ.calculate_waiting_time(mlfq, [Pa, Pa, Pa, Pa])}"""
 )
 # print completion times of processes(P1, P2, P3, P4)
 print(
     f"""completion time:\
        \t\t{MLFQ.calculate_completion_time(mlfq, [Pa, Pa, Pa, Pa])}"""
 )
 # print total turnaround times of processes(P1, P2, P3, P4)
 print(
     f"""turnaround time:\
        \t\t{MLFQ.calculate_turnaround_time(mlfq, [Pa, Pa, Pa, Pa])}"""
 )
 # print sequence of finished processes
 print(
     f"""sequence of finished processes:\
        {mlfq.calculate_sequence_of_finish_queue()}"""
 )






'''simple docstring'''




import os







def 		lowerCAmelCase_				(   ):




    '''simple docstring'''



    A       :   List[Any]					=						os.path.join(os.path.dirname(snake_case__						)		,				'''num.txt'''						)
    with open(snake_case__						) as file_hand:
        return str(sum(int(snake_case__						) for line in file_hand						)						)[:10]


if __name__ == "__main__":
      print(solution())




