refactor: move some classes and functions to separate files
This commit is contained in:
21
task6/entities.py
Normal file
21
task6/entities.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Request:
|
||||||
|
request_time: int
|
||||||
|
plane: Plane
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ProcessedRequest(Request):
|
||||||
|
start_process_time: int
|
||||||
|
process_time: int
|
||||||
|
type_: Literal["landing", "launching"]
|
||||||
|
|
||||||
|
class Plane:
|
||||||
|
__id_increment = 0
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.id = self.__id_increment
|
||||||
|
Plane.__id_increment += 1
|
||||||
121
task6/main.py
121
task6/main.py
@@ -1,122 +1,13 @@
|
|||||||
from collections import deque
|
from stats import Stats, finalize_waiting_stats, show_stats
|
||||||
from dataclasses import dataclass, field
|
from entities import Plane, ProcessedRequest, Request
|
||||||
from numpy import random, average
|
from queues import EnforcingQueue, PermissiveQueue, Queue
|
||||||
from typing import Callable, Final, Iterable, Literal, Optional, Self, override
|
|
||||||
from abc import ABC, abstractmethod
|
from numpy import random
|
||||||
|
from typing import Final, Iterable, Optional
|
||||||
|
|
||||||
from numpy.typing import NDArray
|
from numpy.typing import NDArray
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Request:
|
|
||||||
request_time: int
|
|
||||||
plane: Plane
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class ProcessedRequest(Request):
|
|
||||||
start_process_time: int
|
|
||||||
process_time: int
|
|
||||||
type_: Literal["landing", "launching"]
|
|
||||||
|
|
||||||
class Queue[T](ABC):
|
|
||||||
def __init__(self, size: int) -> None:
|
|
||||||
self.size = size
|
|
||||||
self.queue: deque[T] = deque()
|
|
||||||
|
|
||||||
def __len__(self) -> int:
|
|
||||||
return len(self.queue)
|
|
||||||
|
|
||||||
def __bool__(self) -> bool:
|
|
||||||
return bool(self.queue)
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def add(self, item: T) -> None: pass
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def pop(self) -> T: pass
|
|
||||||
|
|
||||||
class PermissiveQueue[T](Queue):
|
|
||||||
def __init__(self, size: int, overload_function: Optional[Callable[[Self], None]] = None) -> None:
|
|
||||||
super().__init__(size)
|
|
||||||
self._on_overload = overload_function
|
|
||||||
|
|
||||||
@override
|
|
||||||
def add(self, item: T) -> None:
|
|
||||||
self.queue.append(item)
|
|
||||||
if self._on_overload and len(self.queue) > self.size:
|
|
||||||
self._on_overload(self)
|
|
||||||
|
|
||||||
@override
|
|
||||||
def pop(self) -> T:
|
|
||||||
return self.queue.popleft()
|
|
||||||
|
|
||||||
class EnforcingQueue[T](Queue):
|
|
||||||
def __init__(self, size: int) -> None:
|
|
||||||
super().__init__(size)
|
|
||||||
|
|
||||||
@override
|
|
||||||
def add(self, item: T) -> None:
|
|
||||||
if len(self.queue) >= self.size:
|
|
||||||
raise IndexError
|
|
||||||
self.queue.append(item)
|
|
||||||
|
|
||||||
@override
|
|
||||||
def pop(self) -> T:
|
|
||||||
return self.queue.popleft()
|
|
||||||
|
|
||||||
class Plane:
|
|
||||||
__id_increment = 0
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
|
||||||
self.id = self.__id_increment
|
|
||||||
Plane.__id_increment += 1
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Stats:
|
|
||||||
total_plane_requests = 0
|
|
||||||
|
|
||||||
in_requests = 0
|
|
||||||
out_requests = 0
|
|
||||||
|
|
||||||
accepted_in_requests = 0
|
|
||||||
accepted_out_requests = 0
|
|
||||||
|
|
||||||
rejected_in_requests = 0
|
|
||||||
rejected_out_requests = 0
|
|
||||||
|
|
||||||
landings_count = 0
|
|
||||||
launches_count = 0
|
|
||||||
|
|
||||||
in_queued = 0
|
|
||||||
out_queued = 0
|
|
||||||
|
|
||||||
sleep_minutes = 0
|
|
||||||
|
|
||||||
in_waiting_time: list[float] = field(default_factory=list)
|
|
||||||
out_waiting_time: list[float] = field(default_factory=list)
|
|
||||||
|
|
||||||
def show_stats(stats: Stats) -> None:
|
|
||||||
string = f"""============
|
|
||||||
Total requests: {stats.total_plane_requests}
|
|
||||||
In requests: {stats.in_requests}
|
|
||||||
Out requests: {stats.out_requests}
|
|
||||||
Accepted in requests: {stats.accepted_in_requests}
|
|
||||||
Accepted out requests: {stats.accepted_out_requests}
|
|
||||||
Rejected in/out: {stats.rejected_in_requests}/{stats.rejected_out_requests}
|
|
||||||
Landings: {stats.landings_count}
|
|
||||||
Launches: {stats.launches_count}
|
|
||||||
Left in queues (in/out): {stats.in_queued}/{stats.out_queued}
|
|
||||||
Sleep: {stats.sleep_minutes}
|
|
||||||
Average waiting time (in/out): {average(stats.in_waiting_time)}/{average(stats.out_waiting_time)}
|
|
||||||
"""
|
|
||||||
print(string)
|
|
||||||
|
|
||||||
def finalize_waiting_stats(stats: Stats, in_queue: Queue[Request], out_queue: Queue[Request], current_time: int) -> None:
|
|
||||||
for item in in_queue.queue:
|
|
||||||
stats.in_waiting_time.append(current_time - item.request_time)
|
|
||||||
for item in out_queue.queue:
|
|
||||||
stats.out_waiting_time.append(current_time - item.request_time)
|
|
||||||
|
|
||||||
def warn_about_outcoming_queue_overload(queue: Queue) -> None:
|
def warn_about_outcoming_queue_overload(queue: Queue) -> None:
|
||||||
print(f"Outcoming queue is overloaded: {len(queue)} planes/{queue.size} planes")
|
print(f"Outcoming queue is overloaded: {len(queue)} planes/{queue.size} planes")
|
||||||
|
|
||||||
|
|||||||
50
task6/queues.py
Normal file
50
task6/queues.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
from abc import ABC, abstractmethod
|
||||||
|
from collections import deque
|
||||||
|
from typing import Callable, Optional, Self, override
|
||||||
|
|
||||||
|
|
||||||
|
class Queue[T](ABC):
|
||||||
|
def __init__(self, size: int) -> None:
|
||||||
|
self.size = size
|
||||||
|
self.queue: deque[T] = deque()
|
||||||
|
|
||||||
|
def __len__(self) -> int:
|
||||||
|
return len(self.queue)
|
||||||
|
|
||||||
|
def __bool__(self) -> bool:
|
||||||
|
return bool(self.queue)
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def add(self, item: T) -> None: pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def pop(self) -> T: pass
|
||||||
|
|
||||||
|
class PermissiveQueue[T](Queue):
|
||||||
|
def __init__(self, size: int, overload_function: Optional[Callable[[Self], None]] = None) -> None:
|
||||||
|
super().__init__(size)
|
||||||
|
self._on_overload = overload_function
|
||||||
|
|
||||||
|
@override
|
||||||
|
def add(self, item: T) -> None:
|
||||||
|
self.queue.append(item)
|
||||||
|
if self._on_overload and len(self.queue) > self.size:
|
||||||
|
self._on_overload(self)
|
||||||
|
|
||||||
|
@override
|
||||||
|
def pop(self) -> T:
|
||||||
|
return self.queue.popleft()
|
||||||
|
|
||||||
|
class EnforcingQueue[T](Queue):
|
||||||
|
def __init__(self, size: int) -> None:
|
||||||
|
super().__init__(size)
|
||||||
|
|
||||||
|
@override
|
||||||
|
def add(self, item: T) -> None:
|
||||||
|
if len(self.queue) >= self.size:
|
||||||
|
raise IndexError
|
||||||
|
self.queue.append(item)
|
||||||
|
|
||||||
|
@override
|
||||||
|
def pop(self) -> T:
|
||||||
|
return self.queue.popleft()
|
||||||
53
task6/stats.py
Normal file
53
task6/stats.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
|
from numpy import average
|
||||||
|
|
||||||
|
from entities import Request
|
||||||
|
from queues import Queue
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Stats:
|
||||||
|
total_plane_requests = 0
|
||||||
|
|
||||||
|
in_requests = 0
|
||||||
|
out_requests = 0
|
||||||
|
|
||||||
|
accepted_in_requests = 0
|
||||||
|
accepted_out_requests = 0
|
||||||
|
|
||||||
|
rejected_in_requests = 0
|
||||||
|
rejected_out_requests = 0
|
||||||
|
|
||||||
|
landings_count = 0
|
||||||
|
launches_count = 0
|
||||||
|
|
||||||
|
in_queued = 0
|
||||||
|
out_queued = 0
|
||||||
|
|
||||||
|
sleep_minutes = 0
|
||||||
|
|
||||||
|
in_waiting_time: list[float] = field(default_factory=list)
|
||||||
|
out_waiting_time: list[float] = field(default_factory=list)
|
||||||
|
|
||||||
|
def show_stats(stats: Stats) -> None:
|
||||||
|
string = f"""============
|
||||||
|
Total requests: {stats.total_plane_requests}
|
||||||
|
In requests: {stats.in_requests}
|
||||||
|
Out requests: {stats.out_requests}
|
||||||
|
Accepted in requests: {stats.accepted_in_requests}
|
||||||
|
Accepted out requests: {stats.accepted_out_requests}
|
||||||
|
Rejected in/out: {stats.rejected_in_requests}/{stats.rejected_out_requests}
|
||||||
|
Landings: {stats.landings_count}
|
||||||
|
Launches: {stats.launches_count}
|
||||||
|
Left in queues (in/out): {stats.in_queued}/{stats.out_queued}
|
||||||
|
Sleep: {stats.sleep_minutes}
|
||||||
|
Average waiting time (in/out): {average(stats.in_waiting_time)}/{average(stats.out_waiting_time)}
|
||||||
|
"""
|
||||||
|
print(string)
|
||||||
|
|
||||||
|
def finalize_waiting_stats(stats: Stats, in_queue: Queue[Request], out_queue: Queue[Request], current_time: int) -> None:
|
||||||
|
for item in in_queue.queue:
|
||||||
|
stats.in_waiting_time.append(current_time - item.request_time)
|
||||||
|
for item in out_queue.queue:
|
||||||
|
stats.out_waiting_time.append(current_time - item.request_time)
|
||||||
Reference in New Issue
Block a user