Advertisement
GeorgiLukanov87

Python OOP Exam - 10 April 2021 - Aquariums

Nov 14th, 2022 (edited)
272
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.59 KB | None | 0 0
  1. # Python OOP Exam - 10 April 2021 - Aquariums
  2.  
  3. # https://judge.softuni.org/Contests/Practice/Index/2934#1
  4. =============================================================================================
  5. # file name: base_aquarium.py
  6.  
  7. from abc import ABC, abstractmethod
  8.  
  9.  
  10. class BaseAquarium(ABC):
  11.     def __init__(self, name: str, capacity: int):
  12.         self.name = name
  13.         self.capacity = capacity
  14.  
  15.         self.decorations = []  # decorations (objects).
  16.         self.fish = []  # all the fish (objects).
  17.  
  18.     # All passed names would be UNIQUE !!!
  19.     # and it will not be necessary to check if a given name already exists.
  20.     @property
  21.     def name(self):
  22.         return self.__name
  23.  
  24.     @name.setter
  25.     def name(self, value):
  26.         if value == "":
  27.             raise ValueError("Aquarium name cannot be an empty string.")
  28.         self.__name = value
  29.  
  30.     @abstractmethod
  31.     def calculate_comfort(self):
  32.         ...
  33.  
  34.     @abstractmethod
  35.     def add_fish(self, fish):  # add Fish OBJECT!
  36.         ...
  37.  
  38.     @abstractmethod
  39.     def remove_fish(self, fish):  # remove Fish OBJECT!
  40.         ...
  41.  
  42.     @abstractmethod
  43.     def add_decoration(self, decoration):  # remove Decoration OBJECT!
  44.         ...
  45.  
  46.     @abstractmethod
  47.     def feed(self):  # feed all fish in the aquarium
  48.         ...
  49.  
  50.     def __str__(self):
  51.         ...
  52.  
  53.  
  54.  
  55. =============================================================================================
  56. # file name: freshwater_aquarium.py
  57.  
  58. from project.aquarium.base_aquarium import BaseAquarium
  59.  
  60.  
  61. class FreshwaterAquarium(BaseAquarium):
  62.     INITIAL_CAPACITY = 50
  63.  
  64.     def __init__(self, name: str):
  65.         super().__init__(name, self.INITIAL_CAPACITY)
  66.         self.name = name
  67.         self.capacity = self.INITIAL_CAPACITY
  68.  
  69.     def calculate_comfort(self):
  70.         return sum([d.comfort for d in self.decorations])
  71.  
  72.     def add_fish(self, fish):
  73.         if self.capacity == 0:
  74.             return f"Not enough capacity."
  75.         if type(fish).__name__ == 'FreshwaterFish':
  76.             self.fish.append(fish)
  77.             self.capacity -= 1
  78.             return f"Successfully added {type(fish).__name__} to {self.name}."
  79.         else:
  80.             return 'Water not suitable.'
  81.  
  82.     def remove_fish(self, fish):
  83.         if fish in self.fish:
  84.             self.fish.remove(fish)
  85.  
  86.     def add_decoration(self, decoration):
  87.         if decoration not in self.decorations:
  88.             self.decorations.append(decoration)
  89.  
  90.     def feed(self):
  91.         for fish_obj in self.fish:
  92.             fish_obj.eat()
  93.  
  94.     def __str__(self):
  95.         fish_names = [f.name for f in self.fish]
  96.         if not fish_names:
  97.             fish_names = ['none']
  98.         result = f"{self.name}:\n"
  99.         result += f"Fish: {' '.join(fish_names)}\n"
  100.         result += f"Decorations: {len(self.decorations)}\n"
  101.         result += f"Comfort: {self.calculate_comfort()}"
  102.         return result
  103.  
  104. =============================================================================================
  105. # file name: saltwater_aquarium.py
  106.  
  107. from project.aquarium.base_aquarium import BaseAquarium
  108.  
  109.  
  110. class SaltwaterAquarium(BaseAquarium):
  111.     INITIAL_CAPACITY = 25
  112.  
  113.     def __init__(self, name: str):
  114.         super().__init__(name, self.INITIAL_CAPACITY)
  115.         self.name = name
  116.         self.capacity = self.INITIAL_CAPACITY
  117.  
  118.     def calculate_comfort(self):
  119.         return sum([d.comfort for d in self.decorations])
  120.  
  121.     def add_fish(self, fish):
  122.         if self.capacity == 0:
  123.             return f"Not enough capacity."
  124.         if type(fish).__name__ == 'SaltwaterFish':
  125.             self.fish.append(fish)
  126.             self.capacity -= 1
  127.             return f"Successfully added {type(fish).__name__} to {self.name}."
  128.         else:
  129.             return 'Water not suitable.'
  130.  
  131.     def remove_fish(self, fish):
  132.         if fish in self.fish:
  133.             self.fish.remove(fish)
  134.  
  135.     def add_decoration(self, decoration):
  136.         self.decorations.append(decoration)
  137.  
  138.     def feed(self):
  139.         for fish_obj in self.fish:
  140.             fish_obj.eat()
  141.  
  142.     def __str__(self):
  143.         fish_names = [f.name for f in self.fish]
  144.         if not fish_names:
  145.             fish_names = ['none']
  146.         result = f"{self.name}:\n"
  147.         result += f"Fish: {' '.join(fish_names)}\n"
  148.         result += f"Decorations: {len(self.decorations)}\n"
  149.         result += f"Comfort: {self.calculate_comfort()}"
  150.         return result
  151.  
  152. =============================================================================================
  153. # file name: base_decoration.py
  154.  
  155. from abc import ABC, abstractmethod
  156.  
  157.  
  158. class BaseDecoration(ABC):
  159.     @abstractmethod
  160.     def __init__(self, comfort: int, price: float):
  161.         self.comfort = comfort
  162.         self.price = price
  163.  
  164. =============================================================================================
  165. # file name: ornament.py
  166.  
  167. from project.decoration.base_decoration import BaseDecoration
  168.  
  169.  
  170. class Ornament(BaseDecoration):
  171.     COMFORT = 1
  172.     PRICE = 5
  173.  
  174.     def __init__(self):
  175.         super().__init__(self.COMFORT, self.PRICE)
  176.         self.comfort = self.COMFORT
  177.         self.price = self.PRICE
  178.  
  179. =============================================================================================
  180. # file name: plant.py
  181.  
  182. from project.decoration.base_decoration import BaseDecoration
  183.  
  184.  
  185. class Plant(BaseDecoration):
  186.     COMFORT = 5
  187.     PRICE = 10
  188.  
  189.     def __init__(self):
  190.         super().__init__(self.COMFORT, self.PRICE)
  191.         self.comfort = self.COMFORT
  192.         self.price = self.PRICE
  193.  
  194. =============================================================================================
  195. # file name: decoration_repository.py
  196.  
  197. class DecorationRepository:
  198.     def __init__(self):
  199.         self.decorations = []  # contain all decorations (objects).
  200.  
  201.     def add(self, decoration):  # Add Obj!
  202.         self.decorations.append(decoration)
  203.  
  204.     def remove(self, decoration):  # Remove Obj!
  205.         if decoration in self.decorations:
  206.             self.decorations.remove(decoration)
  207.             return True
  208.         return False
  209.  
  210.     def find_by_type(self, decoration_type: str):
  211.         decorations_founds = [d for d in self.decorations if type(d).__name__ == decoration_type]
  212.         if decorations_founds:
  213.             first_decoration_found = decorations_founds[0]
  214.             return first_decoration_found
  215.         return 'None'
  216.  
  217. =============================================================================================
  218. # file name: base_fish.py
  219.  
  220. from abc import ABC, abstractmethod
  221.  
  222.  
  223. class BaseFish(ABC):
  224.     def __init__(self, name: str, species: str, size: int, price: float):
  225.         self.name = name
  226.         self.species = species
  227.         self.size = size
  228.         self.price = price
  229.  
  230.     @property
  231.     def name(self):
  232.         return self.__name
  233.  
  234.     @name.setter
  235.     def name(self, value):
  236.         if value == '':
  237.             raise ValueError("Fish name cannot be an empty string.")
  238.         self.__name = value
  239.  
  240.     @property
  241.     def species(self):
  242.         return self.__species
  243.  
  244.     @species.setter
  245.     def species(self, value):
  246.         if value == '':
  247.             raise ValueError("Fish species cannot be an empty string.")
  248.         self.__species = value
  249.  
  250.     @property
  251.     def price(self):
  252.         return self.__price
  253.  
  254.     @price.setter
  255.     def price(self, value):
  256.         if value <= 0:
  257.             raise ValueError("Price cannot be equal to or below zero.")
  258.         self.__price = value
  259.  
  260.     @abstractmethod
  261.     def eat(self):
  262.         self.size += 5
  263.  
  264. =============================================================================================
  265. # file name: freshwater_fish
  266.  
  267. from project.fish.base_fish import BaseFish
  268.  
  269.  
  270. class FreshwaterFish(BaseFish):
  271.     # The FreshwaterFish could only live in FreshwaterAquarium!
  272.     INITIAL_SIZE = 3
  273.  
  274.     def __init__(self, name: str, species: str, price: float):
  275.         super().__init__(name, species, self.INITIAL_SIZE, price)
  276.         self.name = name
  277.         self.size = self.INITIAL_SIZE
  278.         self.price = price
  279.  
  280.     def eat(self):
  281.         self.size += 3
  282.  
  283. =============================================================================================
  284. # file name: saltwater_fish
  285.  
  286. from project.fish.base_fish import BaseFish
  287.  
  288.  
  289. class SaltwaterFish(BaseFish):
  290.     # The SaltwaterFish could only live in SaltwaterAquarium!
  291.     INITIAL_SIZE = 5
  292.  
  293.     def __init__(self, name: str, species: str, price: float):
  294.         super().__init__(name, species, self.INITIAL_SIZE, price)
  295.         self.name = name
  296.         self.species = species
  297.         self.size = self.INITIAL_SIZE
  298.         self.price = price
  299.  
  300.     def eat(self):
  301.         self.size += 2
  302.  
  303. =============================================================================================
  304. # file name: controller.py
  305.  
  306. from project.aquarium.freshwater_aquarium import FreshwaterAquarium
  307. from project.aquarium.saltwater_aquarium import SaltwaterAquarium
  308. from project.decoration.decoration_repository import DecorationRepository
  309. from project.decoration.ornament import Ornament
  310. from project.decoration.plant import Plant
  311. from project.fish.freshwater_fish import FreshwaterFish
  312. from project.fish.saltwater_fish import SaltwaterFish
  313.  
  314.  
  315. class Controller:
  316.     def __init__(self):
  317.         self.decorations_repository = self.add_repo()
  318.         self.aquariums = []  # all aquariums (objects).
  319.  
  320.     @staticmethod
  321.     def add_repo():
  322.         repo_obj = DecorationRepository()
  323.         return repo_obj
  324.  
  325.     def add_aquarium(self, aquarium_type: str, aquarium_name: str):
  326.         aquarium_mapper = {"FreshwaterAquarium": FreshwaterAquarium, "SaltwaterAquarium": SaltwaterAquarium}
  327.         if aquarium_type not in aquarium_mapper:
  328.             return 'Invalid aquarium type.'
  329.         else:
  330.             new_aquarium = aquarium_mapper[aquarium_type](aquarium_name)
  331.             self.aquariums.append(new_aquarium)
  332.             return f"Successfully added {aquarium_type}."
  333.  
  334.     def add_decoration(self, decoration_type: str):
  335.         if decoration_type == 'Ornament':
  336.             decoration_to_add = Ornament()
  337.         elif decoration_type == 'Plant':
  338.             decoration_to_add = Plant()
  339.         else:
  340.             return "Invalid decoration type."
  341.  
  342.         self.decorations_repository.add(decoration_to_add)
  343.         return f"Successfully added {decoration_type}."
  344.  
  345.     def find_aquarium_by_name(self, aquarium_name_):
  346.         for aquarium_obj in self.aquariums:
  347.             if aquarium_obj.name == aquarium_name_:
  348.                 return aquarium_obj
  349.  
  350.     def insert_decoration(self, aquarium_name: str, decoration_type: str):
  351.         decoration = self.decorations_repository.find_by_type(decoration_type)
  352.         aquarium = self.find_aquarium_by_name(aquarium_name)
  353.         if decoration == 'None':
  354.             return f"There isn't a decoration of type {decoration_type}."
  355.         else:
  356.             aquarium.add_decoration(decoration)
  357.             self.decorations_repository.remove(decoration)
  358.             return f"Successfully added {decoration_type} to {aquarium_name}."
  359.  
  360.     @staticmethod
  361.     def create_fish_by_type(fish_type_, fish_name_, fish_species_, price_):
  362.         if fish_type_ == 'FreshwaterFish':
  363.             return FreshwaterFish(fish_name_, fish_species_, price_)
  364.         elif fish_type_ == 'SaltwaterFish':
  365.             return SaltwaterFish(fish_name_, fish_species_, price_)
  366.         else:
  367.             return None
  368.  
  369.     def add_fish(self, aquarium_name: str, fish_type: str, fish_name: str, fish_species: str, price: float):
  370.         new_fish = self.create_fish_by_type(fish_type, fish_name, fish_species, price)
  371.         if not new_fish:
  372.             return f"There isn't a fish of type {fish_type}."
  373.         aquarium = self.find_aquarium_by_name(aquarium_name)
  374.         return aquarium.add_fish(new_fish)
  375.  
  376.     def feed_fish(self, aquarium_name: str):
  377.         aquarium = self.find_aquarium_by_name(aquarium_name)
  378.         for fish in aquarium.fish:
  379.             fish.eat()
  380.         return f"Fish fed: {len(aquarium.fish)}"
  381.  
  382.     def calculate_value(self, aquarium_name: str):
  383.         aquarium = self.find_aquarium_by_name(aquarium_name)
  384.         total_value = self.calculate_value_of_all_decorations_and_fish(aquarium)
  385.         return f"The value of Aquarium {aquarium_name} is {total_value:.2f}."
  386.  
  387.     @staticmethod
  388.     def calculate_value_of_all_decorations_and_fish(aquarium_obj):
  389.         sum_fish = sum([f.price for f in aquarium_obj.fish])
  390.         sum_decorations = sum([d.price for d in aquarium_obj.decorations])
  391.         return sum_fish + sum_decorations
  392.  
  393.     def report(self):
  394.         return '\n'.join([str(a) for a in self.aquariums])
  395.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement