Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Python OOP Exam - 11 December 2021 - Christmas Races
- # https://judge.softuni.org/Contests/Practice/Index/3305#1
- =============================================================================================
- # file name: car.py
- from abc import ABC, abstractmethod
- class Car(ABC):
- MAX_SPEED_LIMIT = 0
- MIN_SPEED_LIMIT = 0
- @abstractmethod
- def __init__(self, model: str, speed_limit: int):
- self.model = model
- self.speed_limit = speed_limit
- self.is_taken = False
- @property
- def model(self):
- return self.__model
- @model.setter
- def model(self, value):
- if len(value) < 4:
- raise ValueError(f"Model {value} is less than 4 symbols!")
- self.__model = value
- @property
- def speed_limit(self):
- return self.__speed_limit
- @speed_limit.setter
- def speed_limit(self, value):
- if not self.MIN_SPEED_LIMIT <= value <= self.MAX_SPEED_LIMIT:
- raise ValueError(f"Invalid speed limit! "
- f"Must be between {self.MIN_SPEED_LIMIT} and {self.MAX_SPEED_LIMIT}!")
- self.__speed_limit = value
- =============================================================================================
- # file name: muscle_car.py
- from project.car.car import Car
- class MuscleCar(Car):
- MIN_SPEED_LIMIT = 250
- MAX_SPEED_LIMIT = 450
- def __init__(self, model: str, speed_limit: int):
- super().__init__(model, speed_limit)
- =============================================================================================
- # file name: sports_car.py
- from project.car.car import Car
- class SportsCar(Car):
- MIN_SPEED_LIMIT = 400
- MAX_SPEED_LIMIT = 600
- def __init__(self, model: str, speed_limit: int):
- super().__init__(model, speed_limit)
- =============================================================================================
- # file name: driver.py
- class Driver:
- def __init__(self, name: str):
- self.name = name
- self.car = None
- self.number_of_wins = 0
- @property
- def name(self):
- return self.__name
- @name.setter
- def name(self, value):
- if value.strip() == '':
- raise ValueError("Name should contain at least one character!")
- self.__name = value
- =============================================================================================
- # file name: race.py
- class Race:
- def __init__(self, name: str):
- self.name = name
- self.drivers = []
- @property
- def name(self):
- return self.__name
- @name.setter
- def name(self, value):
- if value == "":
- raise ValueError("Name cannot be an empty string!")
- self.__name = value
- =============================================================================================
- # file name: controller.py
- from project.car.muscle_car import MuscleCar
- from project.car.sports_car import SportsCar
- from project.driver import Driver
- from project.race import Race
- class Controller:
- def __init__(self):
- self.cars = []
- self.drivers = []
- self.races = []
- self.car_type_mapper = {
- 'MuscleCar': MuscleCar,
- 'SportsCar': SportsCar,
- }
- def create_car(self, car_type: str, model: str, speed_limit: int):
- if car_type not in ['MuscleCar', 'SportsCar']:
- return
- if model in [car.model for car in self.cars]:
- raise Exception(f"Car {model} is already created!")
- new_car = self.car_type_mapper[car_type](model, speed_limit)
- self.cars.append(new_car)
- return f"{car_type} {model} is created."
- def create_driver(self, driver_name: str):
- if driver_name in [d.name for d in self.drivers]:
- raise Exception(f"Driver {driver_name} is already created!")
- new_driver = Driver(driver_name)
- self.drivers.append(new_driver)
- return f"Driver {driver_name} is created."
- def create_race(self, race_name: str):
- if race_name in [r.name for r in self.races]:
- raise Exception(f"Race {race_name} is already created!")
- new_race = Race(race_name)
- self.races.append(new_race)
- return f'Race {race_name} is created.'
- def add_car_to_driver(self, driver_name: str, car_type: str):
- driver = self.__find_driver_by_name(driver_name)
- last_car = self.__find_car_by_type(car_type)
- if driver.car:
- old_model = driver.car.model
- new_model = last_car.model
- driver.car.is_taken = False
- driver.car = last_car
- last_car.is_taken = True
- return f'Driver {driver_name} changed his car from {old_model} to {new_model}.'
- driver.car = last_car
- last_car.is_taken = True
- return f'Driver {driver_name} chose the car {last_car.model}.'
- def __find_car_by_type(self, car_type_):
- searching_last_car = [car for car in self.cars if type(car).__name__ == car_type_ and not car.is_taken]
- if not searching_last_car:
- raise Exception(f"Car {car_type_} could not be found!")
- return searching_last_car[-1]
- def __find_driver_by_name(self, driver_name_):
- for driver_obj in self.drivers:
- if driver_obj.name == driver_name_:
- return driver_obj
- raise Exception(f"Driver {driver_name_} could not be found!")
- def add_driver_to_race(self, race_name: str, driver_name: str):
- race = self.__find_race_by_name(race_name)
- driver = self.__find_driver_by_name(driver_name)
- if not driver.car:
- raise Exception(f"Driver {driver_name} could not participate in the race!")
- if driver in race.drivers:
- return f'Driver {driver_name} is already added in {race_name} race.'
- race.drivers.append(driver)
- return f'Driver {driver_name} added in {race_name} race.'
- def __find_race_by_name(self, race_name_):
- for race_obj in self.races:
- if race_obj.name == race_name_:
- return race_obj
- raise Exception(f"Race {race_name_} could not be found!")
- def start_race(self, race_name: str):
- race = self.__find_race_by_name(race_name)
- if len(race.drivers) < 3:
- raise Exception(f'Race {race_name} cannot start with less than 3 participants!')
- final_result = []
- top_3_winners = sorted(race.drivers, key=lambda x: -x.car.speed_limit)
- for driver_obj in top_3_winners[:3]:
- driver_obj.number_of_wins += 1
- final_result.append(
- f'Driver {driver_obj.name} wins the {race_name} race with a speed of {driver_obj.car.speed_limit}.')
- return '\n'.join(final_result)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement