Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Python OOP Retake Exam - 23 August 2021 - Astronauts
- # https://judge.softuni.org/Contests/Practice/Index/3093#1
- =============================================================================================
- # file name: astronaut.py
- from abc import ABC, abstractmethod
- class Astronaut(ABC):
- def __init__(self, name: str, oxygen: int):
- self.name = name
- self.oxygen = oxygen
- self.backpack = []
- @property
- def name(self):
- return self.__name
- @name.setter
- def name(self, value):
- if value.strip() == '':
- raise ValueError("Astronaut name cannot be empty string or whitespace!")
- self.__name = value
- def increase_oxygen(self, amount: int):
- self.oxygen += amount
- @abstractmethod
- def breathe(self):
- ...
- def __str__(self):
- if not self.backpack:
- self.backpack = ['none']
- return f'Name: {self.name}\nOxygen: {self.oxygen}\nBackpack items: {", ".join(self.backpack)}\n'
- =============================================================================================
- # file name: biologist.py
- from project.astronaut.astronaut import Astronaut
- class Biologist(Astronaut):
- INITIAL_UNITS_OXYGEN = 70
- def __init__(self, name: str):
- super().__init__(name, self.INITIAL_UNITS_OXYGEN)
- def breathe(self):
- self.oxygen -= 5
- =============================================================================================
- # file name: geodesist.py
- from project.astronaut.astronaut import Astronaut
- class Geodesist(Astronaut):
- INITIAL_UNITS_OXYGEN = 50
- def __init__(self, name: str):
- super().__init__(name, self.INITIAL_UNITS_OXYGEN)
- def breathe(self):
- self.oxygen -= 10
- =============================================================================================
- # file name: meteorologist.py
- from project.astronaut.astronaut import Astronaut
- class Meteorologist(Astronaut):
- INITIAL_UNITS_OXYGEN = 90
- def __init__(self, name: str):
- super().__init__(name, self.INITIAL_UNITS_OXYGEN)
- def breathe(self):
- self.oxygen -= 15
- =============================================================================================
- # file name: astronaut_repository.py
- from project.astronaut.astronaut import Astronaut
- class AstronautRepository:
- def __init__(self):
- self.astronauts = [] # OJBs of Astronauts !
- def add(self, astronaut: Astronaut):
- if astronaut not in self.astronauts:
- self.astronauts.append(astronaut)
- def remove(self, astronaut: Astronaut):
- if astronaut in self.astronauts:
- self.astronauts.remove(astronaut)
- def find_by_name(self, name: str):
- for astro_obj in self.astronauts:
- if astro_obj.name == name:
- return astro_obj
- =============================================================================================
- # file name: validator.py
- from project.astronaut.biologist import Biologist
- from project.astronaut.geodesist import Geodesist
- from project.astronaut.meteorologist import Meteorologist
- from project.planet.planet import Planet
- class Validator:
- @staticmethod
- def create_astro_by_type_and_name(type_, name_):
- astronauts_types_mapper = {
- 'Meteorologist': Meteorologist, 'Geodesist': Geodesist, 'Biologist': Biologist, }
- if type_ not in astronauts_types_mapper.keys():
- raise Exception('Astronaut type is not valid!')
- astro_obj = astronauts_types_mapper[type_](name_)
- return astro_obj
- @staticmethod
- def create_planet_by_name_items(planet_name_, items_):
- new_planet = Planet(planet_name_)
- new_planet.items.extend(items_.split(', '))
- return new_planet
- =============================================================================================
- # file name: planet.py
- class Planet:
- def __init__(self, name: str):
- self.name = name
- self.items = []
- @property
- def name(self):
- return self.__name
- @name.setter
- def name(self, value):
- if value.strip() == '':
- raise ValueError("Planet name cannot be empty string or whitespace!")
- self.__name = value
- def __repr__(self):
- return f'Planet name: {self.name}, items = {self.items}'
- =============================================================================================
- # file name: planet_repository.py
- from project.planet.planet import Planet
- class PlanetRepository:
- def __init__(self):
- self.planets = []
- def add(self, planet: Planet):
- if planet not in self.planets:
- self.planets.append(planet)
- def remove(self, planet: Planet):
- if planet in self.planets:
- self.planets.remove(planet)
- def find_by_name(self, name: str):
- for planet_obj in self.planets:
- if planet_obj.name == name:
- return planet_obj
- =============================================================================================
- # file name: space_station.py
- from project.astronaut.astronaut_repository import AstronautRepository
- from project.helper.validator import Validator
- from project.planet.planet_repository import PlanetRepository
- class SpaceStation:
- def __init__(self):
- self.planet_repository = PlanetRepository()
- self.astronaut_repository = AstronautRepository()
- self.mission_completed = 0
- self.mission_failed = 0
- def add_astronaut(self, astronaut_type: str, name: str):
- new_astronaut = Validator.create_astro_by_type_and_name(astronaut_type, name)
- for astro_obj in self.astronaut_repository.astronauts:
- if astro_obj.name == name:
- return f"{name} is already added."
- self.astronaut_repository.astronauts.append(new_astronaut)
- return f'Successfully added {new_astronaut.__class__.__name__}: {new_astronaut.name}.'
- def add_planet(self, name: str, items: str):
- new_planet = Validator.create_planet_by_name_items(name, items)
- for planet_obj in self.planet_repository.planets:
- if planet_obj.name == name:
- return f"{planet_obj.name} is already added."
- self.planet_repository.planets.append(new_planet)
- return f'Successfully added Planet: {new_planet.name}.'
- def retire_astronaut(self, name: str):
- current_astronaut = self.astronaut_repository.find_by_name(name)
- if current_astronaut:
- self.astronaut_repository.remove(current_astronaut)
- return f'Astronaut {current_astronaut.name} was retired!'
- raise Exception(f"Astronaut {name} doesn't exist!")
- def recharge_oxygen(self):
- AMOUNT = 10
- for astro_obj in self.astronaut_repository.astronauts:
- astro_obj.increase_oxygen(AMOUNT)
- def send_on_mission(self, planet_name: str):
- if planet_name not in [planet.name for planet in self.planet_repository.planets]:
- raise Exception("Invalid planet name!")
- planet = self.planet_repository.find_by_name(planet_name)
- astros_need_5 = [a for a in self.astronaut_repository.astronauts if a.oxygen > 30]
- sorted_astros = sorted(astros_need_5, key=lambda x: -x.oxygen)
- if not astros_need_5:
- self.mission_failed += 1
- raise Exception("You need at least one astronaut to explore the planet!")
- counter_astros = 1
- for astro in sorted_astros[:5]:
- while 'none' in astro.backpack:
- astro.backpack.remove('none')
- while True:
- if astro.oxygen <= 0 or not planet.items:
- break
- astro.backpack.append(planet.items.pop())
- astro.breathe()
- if astro.oxygen <= 0:
- counter_astros += 1
- astro.oxygen = 0
- if planet.items:
- self.mission_failed += 1
- return 'Mission is not completed.'
- self.mission_completed += 1
- return f'Planet: {planet.name} was explored. {counter_astros} astronauts participated in collecting items.'
- def report(self):
- result = f"{self.mission_completed} successful missions!\n"
- result += f'{self.mission_failed} missions were not completed!\n'
- result += "Astronauts' info:\n"
- for astro in self.astronaut_repository.astronauts:
- result += str(astro)
- return result.strip()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement