Advertisement
GeorgiLukanov87

Python OOP Retake Exam - 23 August 2021 - Astronauts

Nov 12th, 2022 (edited)
265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.58 KB | None | 0 0
  1. # Python OOP Retake Exam - 23 August 2021 - Astronauts
  2.  
  3. # https://judge.softuni.org/Contests/Practice/Index/3093#1
  4. =============================================================================================
  5. # file name: astronaut.py
  6.  
  7. from abc import ABC, abstractmethod
  8.  
  9.  
  10. class Astronaut(ABC):
  11.     def __init__(self, name: str, oxygen: int):
  12.         self.name = name
  13.         self.oxygen = oxygen
  14.         self.backpack = []
  15.  
  16.     @property
  17.     def name(self):
  18.         return self.__name
  19.  
  20.     @name.setter
  21.     def name(self, value):
  22.         if value.strip() == '':
  23.             raise ValueError("Astronaut name cannot be empty string or whitespace!")
  24.         self.__name = value
  25.  
  26.     def increase_oxygen(self, amount: int):
  27.         self.oxygen += amount
  28.  
  29.     @abstractmethod
  30.     def breathe(self):
  31.         ...
  32.  
  33.     def __str__(self):
  34.         if not self.backpack:
  35.             self.backpack = ['none']
  36.  
  37.         return f'Name: {self.name}\nOxygen: {self.oxygen}\nBackpack items: {", ".join(self.backpack)}\n'
  38.  
  39. =============================================================================================
  40. # file name: biologist.py
  41.  
  42. from project.astronaut.astronaut import Astronaut
  43.  
  44.  
  45. class Biologist(Astronaut):
  46.     INITIAL_UNITS_OXYGEN = 70
  47.  
  48.     def __init__(self, name: str):
  49.         super().__init__(name, self.INITIAL_UNITS_OXYGEN)
  50.  
  51.     def breathe(self):
  52.         self.oxygen -= 5
  53.  
  54. =============================================================================================
  55. # file name: geodesist.py
  56.  
  57. from project.astronaut.astronaut import Astronaut
  58.  
  59.  
  60. class Geodesist(Astronaut):
  61.     INITIAL_UNITS_OXYGEN = 50
  62.  
  63.     def __init__(self, name: str):
  64.         super().__init__(name, self.INITIAL_UNITS_OXYGEN)
  65.  
  66.     def breathe(self):
  67.         self.oxygen -= 10
  68.  
  69. =============================================================================================
  70. # file name: meteorologist.py
  71.  
  72. from project.astronaut.astronaut import Astronaut
  73.  
  74.  
  75. class Meteorologist(Astronaut):
  76.     INITIAL_UNITS_OXYGEN = 90
  77.  
  78.     def __init__(self, name: str):
  79.         super().__init__(name, self.INITIAL_UNITS_OXYGEN)
  80.  
  81.     def breathe(self):
  82.         self.oxygen -= 15
  83.  
  84. =============================================================================================
  85. # file name: astronaut_repository.py
  86.  
  87. from project.astronaut.astronaut import Astronaut
  88.  
  89.  
  90. class AstronautRepository:
  91.     def __init__(self):
  92.         self.astronauts = []  # OJBs of Astronauts !
  93.  
  94.     def add(self, astronaut: Astronaut):
  95.         if astronaut not in self.astronauts:
  96.             self.astronauts.append(astronaut)
  97.  
  98.     def remove(self, astronaut: Astronaut):
  99.         if astronaut in self.astronauts:
  100.             self.astronauts.remove(astronaut)
  101.  
  102.     def find_by_name(self, name: str):
  103.         for astro_obj in self.astronauts:
  104.             if astro_obj.name == name:
  105.                 return astro_obj
  106.  
  107. =============================================================================================
  108. # file name: validator.py
  109.  
  110. from project.astronaut.biologist import Biologist
  111. from project.astronaut.geodesist import Geodesist
  112. from project.astronaut.meteorologist import Meteorologist
  113. from project.planet.planet import Planet
  114.  
  115.  
  116. class Validator:
  117.     @staticmethod
  118.     def create_astro_by_type_and_name(type_, name_):
  119.         astronauts_types_mapper = {
  120.             'Meteorologist': Meteorologist, 'Geodesist': Geodesist, 'Biologist': Biologist, }
  121.  
  122.         if type_ not in astronauts_types_mapper.keys():
  123.             raise Exception('Astronaut type is not valid!')
  124.  
  125.         astro_obj = astronauts_types_mapper[type_](name_)
  126.         return astro_obj
  127.  
  128.     @staticmethod
  129.     def create_planet_by_name_items(planet_name_, items_):
  130.         new_planet = Planet(planet_name_)
  131.         new_planet.items.extend(items_.split(', '))
  132.         return new_planet
  133.  
  134.  
  135. =============================================================================================
  136. # file name: planet.py
  137.  
  138. class Planet:
  139.     def __init__(self, name: str):
  140.         self.name = name
  141.         self.items = []
  142.  
  143.     @property
  144.     def name(self):
  145.         return self.__name
  146.  
  147.     @name.setter
  148.     def name(self, value):
  149.         if value.strip() == '':
  150.             raise ValueError("Planet name cannot be empty string or whitespace!")
  151.         self.__name = value
  152.  
  153.     def __repr__(self):
  154.         return f'Planet name: {self.name}, items = {self.items}'
  155.  
  156.  
  157. =============================================================================================
  158. # file name: planet_repository.py
  159.  
  160. from project.planet.planet import Planet
  161.  
  162.  
  163. class PlanetRepository:
  164.     def __init__(self):
  165.         self.planets = []
  166.  
  167.     def add(self, planet: Planet):
  168.         if planet not in self.planets:
  169.             self.planets.append(planet)
  170.  
  171.     def remove(self, planet: Planet):
  172.         if planet in self.planets:
  173.             self.planets.remove(planet)
  174.  
  175.     def find_by_name(self, name: str):
  176.         for planet_obj in self.planets:
  177.             if planet_obj.name == name:
  178.                 return planet_obj
  179.  
  180.  
  181. =============================================================================================
  182. # file name: space_station.py
  183.  
  184. from project.astronaut.astronaut_repository import AstronautRepository
  185. from project.helper.validator import Validator
  186.  
  187. from project.planet.planet_repository import PlanetRepository
  188.  
  189.  
  190. class SpaceStation:
  191.     def __init__(self):
  192.         self.planet_repository = PlanetRepository()
  193.         self.astronaut_repository = AstronautRepository()
  194.         self.mission_completed = 0
  195.         self.mission_failed = 0
  196.  
  197.     def add_astronaut(self, astronaut_type: str, name: str):
  198.         new_astronaut = Validator.create_astro_by_type_and_name(astronaut_type, name)
  199.  
  200.         for astro_obj in self.astronaut_repository.astronauts:
  201.             if astro_obj.name == name:
  202.                 return f"{name} is already added."
  203.         self.astronaut_repository.astronauts.append(new_astronaut)
  204.         return f'Successfully added {new_astronaut.__class__.__name__}: {new_astronaut.name}.'
  205.  
  206.     def add_planet(self, name: str, items: str):
  207.         new_planet = Validator.create_planet_by_name_items(name, items)
  208.  
  209.         for planet_obj in self.planet_repository.planets:
  210.             if planet_obj.name == name:
  211.                 return f"{planet_obj.name} is already added."
  212.         self.planet_repository.planets.append(new_planet)
  213.         return f'Successfully added Planet: {new_planet.name}.'
  214.  
  215.     def retire_astronaut(self, name: str):
  216.         current_astronaut = self.astronaut_repository.find_by_name(name)
  217.  
  218.         if current_astronaut:
  219.             self.astronaut_repository.remove(current_astronaut)
  220.             return f'Astronaut {current_astronaut.name} was retired!'
  221.         raise Exception(f"Astronaut {name} doesn't exist!")
  222.  
  223.     def recharge_oxygen(self):
  224.         AMOUNT = 10
  225.         for astro_obj in self.astronaut_repository.astronauts:
  226.             astro_obj.increase_oxygen(AMOUNT)
  227.  
  228.     def send_on_mission(self, planet_name: str):
  229.         if planet_name not in [planet.name for planet in self.planet_repository.planets]:
  230.             raise Exception("Invalid planet name!")
  231.  
  232.         planet = self.planet_repository.find_by_name(planet_name)
  233.         astros_need_5 = [a for a in self.astronaut_repository.astronauts if a.oxygen > 30]
  234.         sorted_astros = sorted(astros_need_5, key=lambda x: -x.oxygen)
  235.  
  236.         if not astros_need_5:
  237.             self.mission_failed += 1
  238.             raise Exception("You need at least one astronaut to explore the planet!")
  239.  
  240.         counter_astros = 1
  241.         for astro in sorted_astros[:5]:
  242.             while 'none' in astro.backpack:
  243.                 astro.backpack.remove('none')
  244.             while True:
  245.                 if astro.oxygen <= 0 or not planet.items:
  246.                     break
  247.                 astro.backpack.append(planet.items.pop())
  248.                 astro.breathe()
  249.                 if astro.oxygen <= 0:
  250.                     counter_astros += 1
  251.                     astro.oxygen = 0
  252.  
  253.         if planet.items:
  254.             self.mission_failed += 1
  255.             return 'Mission is not completed.'
  256.  
  257.         self.mission_completed += 1
  258.         return f'Planet: {planet.name} was explored. {counter_astros} astronauts participated in collecting items.'
  259.  
  260.     def report(self):
  261.         result = f"{self.mission_completed} successful missions!\n"
  262.         result += f'{self.mission_failed} missions were not completed!\n'
  263.         result += "Astronauts' info:\n"
  264.  
  265.         for astro in self.astronaut_repository.astronauts:
  266.             result += str(astro)
  267.  
  268.         return result.strip()
  269.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement