Advertisement
GeorgiLukanov87

Python OOP Exam - 11 December 2021 - Christmas Races

Nov 12th, 2022 (edited)
259
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.81 KB | None | 0 0
  1. # Python OOP Exam - 11 December 2021 - Christmas Races
  2.  
  3. # https://judge.softuni.org/Contests/Practice/Index/3305#1
  4. =============================================================================================
  5.  
  6. # file name: car.py
  7.  
  8. from abc import ABC, abstractmethod
  9.  
  10.  
  11. class Car(ABC):
  12.     MAX_SPEED_LIMIT = 0
  13.     MIN_SPEED_LIMIT = 0
  14.  
  15.     @abstractmethod
  16.     def __init__(self, model: str, speed_limit: int):
  17.         self.model = model
  18.         self.speed_limit = speed_limit
  19.         self.is_taken = False
  20.  
  21.     @property
  22.     def model(self):
  23.         return self.__model
  24.  
  25.     @model.setter
  26.     def model(self, value):
  27.         if len(value) < 4:
  28.             raise ValueError(f"Model {value} is less than 4 symbols!")
  29.         self.__model = value
  30.  
  31.     @property
  32.     def speed_limit(self):
  33.         return self.__speed_limit
  34.  
  35.     @speed_limit.setter
  36.     def speed_limit(self, value):
  37.         if not self.MIN_SPEED_LIMIT <= value <= self.MAX_SPEED_LIMIT:
  38.             raise ValueError(f"Invalid speed limit! "
  39.                              f"Must be between {self.MIN_SPEED_LIMIT} and {self.MAX_SPEED_LIMIT}!")
  40.         self.__speed_limit = value
  41.  
  42.  
  43.  
  44.  
  45. =============================================================================================
  46. # file name: muscle_car.py
  47.  
  48. from project.car.car import Car
  49.  
  50.  
  51. class MuscleCar(Car):
  52.     MIN_SPEED_LIMIT = 250
  53.     MAX_SPEED_LIMIT = 450
  54.  
  55.     def __init__(self, model: str, speed_limit: int):
  56.         super().__init__(model, speed_limit)
  57.  
  58. =============================================================================================
  59. # file name: sports_car.py
  60.  
  61. from project.car.car import Car
  62.  
  63.  
  64. class SportsCar(Car):
  65.     MIN_SPEED_LIMIT = 400
  66.     MAX_SPEED_LIMIT = 600
  67.  
  68.     def __init__(self, model: str, speed_limit: int):
  69.         super().__init__(model, speed_limit)
  70.  
  71. =============================================================================================
  72. # file name: driver.py
  73.  
  74. class Driver:
  75.     def __init__(self, name: str):
  76.         self.name = name
  77.         self.car = None
  78.         self.number_of_wins = 0
  79.  
  80.     @property
  81.     def name(self):
  82.         return self.__name
  83.  
  84.     @name.setter
  85.     def name(self, value):
  86.         if value.strip() == '':
  87.             raise ValueError("Name should contain at least one character!")
  88.         self.__name = value
  89.  
  90. =============================================================================================
  91. # file name: race.py
  92.  
  93. class Race:
  94.     def __init__(self, name: str):
  95.         self.name = name
  96.         self.drivers = []
  97.  
  98.     @property
  99.     def name(self):
  100.         return self.__name
  101.  
  102.     @name.setter
  103.     def name(self, value):
  104.         if value == "":
  105.             raise ValueError("Name cannot be an empty string!")
  106.         self.__name = value
  107.  
  108.  
  109. =============================================================================================
  110. # file name: controller.py
  111.  
  112. from project.car.muscle_car import MuscleCar
  113. from project.car.sports_car import SportsCar
  114. from project.driver import Driver
  115. from project.race import Race
  116.  
  117.  
  118. class Controller:
  119.     def __init__(self):
  120.         self.cars = []
  121.         self.drivers = []
  122.         self.races = []
  123.         self.car_type_mapper = {
  124.             'MuscleCar': MuscleCar,
  125.             'SportsCar': SportsCar,
  126.         }
  127.  
  128.     def create_car(self, car_type: str, model: str, speed_limit: int):
  129.         if car_type not in ['MuscleCar', 'SportsCar']:
  130.             return
  131.         if model in [car.model for car in self.cars]:
  132.             raise Exception(f"Car {model} is already created!")
  133.         new_car = self.car_type_mapper[car_type](model, speed_limit)
  134.         self.cars.append(new_car)
  135.         return f"{car_type} {model} is created."
  136.  
  137.     def create_driver(self, driver_name: str):
  138.         if driver_name in [d.name for d in self.drivers]:
  139.             raise Exception(f"Driver {driver_name} is already created!")
  140.         new_driver = Driver(driver_name)
  141.         self.drivers.append(new_driver)
  142.         return f"Driver {driver_name} is created."
  143.  
  144.     def create_race(self, race_name: str):
  145.         if race_name in [r.name for r in self.races]:
  146.             raise Exception(f"Race {race_name} is already created!")
  147.         new_race = Race(race_name)
  148.         self.races.append(new_race)
  149.         return f'Race {race_name} is created.'
  150.  
  151.     def add_car_to_driver(self, driver_name: str, car_type: str):
  152.         driver = self.__find_driver_by_name(driver_name)
  153.         last_car = self.__find_car_by_type(car_type)
  154.  
  155.         if driver.car:
  156.             old_model = driver.car.model
  157.             new_model = last_car.model
  158.  
  159.             driver.car.is_taken = False
  160.             driver.car = last_car
  161.             last_car.is_taken = True
  162.             return f'Driver {driver_name} changed his car from {old_model} to {new_model}.'
  163.  
  164.         driver.car = last_car
  165.         last_car.is_taken = True
  166.         return f'Driver {driver_name} chose the car {last_car.model}.'
  167.  
  168.     def __find_car_by_type(self, car_type_):
  169.         searching_last_car = [car for car in self.cars if type(car).__name__ == car_type_ and not car.is_taken]
  170.         if not searching_last_car:
  171.             raise Exception(f"Car {car_type_} could not be found!")
  172.         return searching_last_car[-1]
  173.  
  174.     def __find_driver_by_name(self, driver_name_):
  175.         for driver_obj in self.drivers:
  176.             if driver_obj.name == driver_name_:
  177.                 return driver_obj
  178.         raise Exception(f"Driver {driver_name_} could not be found!")
  179.  
  180.     def add_driver_to_race(self, race_name: str, driver_name: str):
  181.         race = self.__find_race_by_name(race_name)
  182.         driver = self.__find_driver_by_name(driver_name)
  183.  
  184.         if not driver.car:
  185.             raise Exception(f"Driver {driver_name} could not participate in the race!")
  186.         if driver in race.drivers:
  187.             return f'Driver {driver_name} is already added in {race_name} race.'
  188.  
  189.         race.drivers.append(driver)
  190.         return f'Driver {driver_name} added in {race_name} race.'
  191.  
  192.     def __find_race_by_name(self, race_name_):
  193.         for race_obj in self.races:
  194.             if race_obj.name == race_name_:
  195.                 return race_obj
  196.         raise Exception(f"Race {race_name_} could not be found!")
  197.  
  198.     def start_race(self, race_name: str):
  199.         race = self.__find_race_by_name(race_name)
  200.         if len(race.drivers) < 3:
  201.             raise Exception(f'Race {race_name} cannot start with less than 3 participants!')
  202.  
  203.         final_result = []
  204.         top_3_winners = sorted(race.drivers, key=lambda x: -x.car.speed_limit)
  205.         for driver_obj in top_3_winners[:3]:
  206.             driver_obj.number_of_wins += 1
  207.             final_result.append(
  208.                 f'Driver {driver_obj.name} wins the {race_name} race with a speed of {driver_obj.car.speed_limit}.')
  209.  
  210.         return '\n'.join(final_result)
  211.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement