├── 10_Unit_Testing_Exercise ├── main.py ├── hero │ ├── test │ │ ├── __init__.py │ │ └── test_hero.py │ ├── project │ │ ├── __init__.py │ │ └── hero.py │ └── test.zip ├── mammal │ ├── test │ │ ├── __init__.py │ │ └── test_mammal.py │ ├── project │ │ ├── __init__.py │ │ └── mammal.py │ └── test.zip ├── student │ ├── project │ │ ├── __init__.py │ │ └── student.py │ ├── test │ │ ├── __init__.py │ │ └── test_student.py │ └── test.zip ├── vehicle │ ├── project │ │ ├── __init__.py │ │ └── vehicle.py │ ├── test │ │ ├── __init__.py │ │ └── test_vehicle.py │ └── test.zip └── .idea │ ├── vcs.xml │ ├── .gitignore │ ├── inspectionProfiles │ ├── profiles_settings.xml │ └── Project_Default.xml │ ├── modules.xml │ ├── misc.xml │ └── 10_Unit_Testing_Exercise.iml ├── 03_Inheritance ├── OLD_TASK │ ├── __init__.py │ └── Guild_System │ │ ├── __init__.py │ │ ├── project │ │ ├── __init__.py │ │ ├── player.py │ │ └── guild.py │ │ └── project.zip ├── 02_Zoo │ ├── project │ │ ├── __init__.py │ │ ├── bear.py │ │ ├── gorilla.py │ │ ├── mammal.py │ │ ├── reptile.py │ │ ├── snake.py │ │ ├── animal.py │ │ └── lizard.py │ └── project.zip ├── 05_Shop │ ├── project │ │ ├── __init__.py │ │ ├── food.py │ │ ├── drink.py │ │ ├── product.py │ │ └── product_repository.py │ └── project.zip ├── 01_Person │ ├── project │ │ ├── __init__.py │ │ ├── person.py │ │ └── child.py │ └── project.zip ├── 04_Need_For_Speed │ ├── project │ │ ├── __init__.py │ │ ├── family_car.py │ │ ├── motorcycle.py │ │ ├── car.py │ │ ├── sport_car.py │ │ ├── cross_motorcycle.py │ │ ├── race_motorcycle.py │ │ └── vehicle.py │ └── project.zip ├── 03_Players_And_Monsters │ ├── project │ │ ├── __init__.py │ │ ├── elf.py │ │ ├── knight.py │ │ ├── muse_elf.py │ │ ├── wizard.py │ │ ├── dark_knight.py │ │ ├── dark_wizard.py │ │ ├── blade_knight.py │ │ ├── soul_master.py │ │ └── hero.py │ └── project.zip └── .idea │ ├── vcs.xml │ ├── .gitignore │ ├── inspectionProfiles │ ├── profiles_settings.xml │ └── Project_Default.xml │ ├── modules.xml │ ├── misc.xml │ └── 03_Inheritance.iml ├── 11_Exam_Preparation ├── task3 │ ├── __init__.py │ ├── test │ │ └── __init__.py │ ├── test.zip │ └── climbing_robot.py ├── project │ ├── climbers │ │ ├── __init__.py │ │ ├── arctic_climber.py │ │ ├── summit_climber.py │ │ └── base_climber.py │ ├── peaks │ │ ├── __init__.py │ │ ├── arctic_peak.py │ │ ├── summit_peak.py │ │ └── base_peak.py │ └── summit_quest_manager_app.py ├── project.zip └── .idea │ ├── vcs.xml │ ├── .gitignore │ ├── inspectionProfiles │ ├── profiles_settings.xml │ └── Project_Default.xml │ ├── modules.xml │ ├── misc.xml │ └── 11_Exam_Preparation.iml ├── 02_Classes_And_Objects ├── 05_Task │ ├── project │ │ ├── __init__.py │ │ ├── task.py │ │ └── section.py │ └── project.zip ├── 08_Library │ ├── project │ │ ├── __init__.py │ │ ├── user.py │ │ ├── registration.py │ │ └── library.py │ └── project.zip ├── 07_Spoopify │ ├── project │ │ ├── __init__.py │ │ ├── song.py │ │ ├── band.py │ │ └── album.py │ └── project.zip ├── .idea │ ├── vcs.xml │ ├── .gitignore │ ├── inspectionProfiles │ │ ├── profiles_settings.xml │ │ └── Project_Default.xml │ ├── modules.xml │ ├── misc.xml │ └── 02_Classes_And_Objects.iml ├── main.py ├── 03_Account.py ├── 02_Time.py ├── 01_Vet.py └── 04_Pizza_Delivery.py ├── 05_Static_And_Class_Methods_Lab ├── 04_HotelRoom │ ├── project │ │ ├── __init__.py │ │ ├── test.py │ │ ├── room.py │ │ └── hotel.py │ └── project.zip ├── .idea │ ├── vcs.xml │ ├── .gitignore │ ├── inspectionProfiles │ │ ├── profiles_settings.xml │ │ └── Project_Default.xml │ ├── modules.xml │ ├── misc.xml │ └── 05_Static_And_Class_Methods_Lab.iml ├── custom_reduce.py ├── 01_Calculator.py ├── main.py ├── 03_Integer.py └── 02_Shop.py ├── 05_Static_And_Class_Methods_Exercise ├── 02_Movie_World │ ├── project │ │ ├── __init__.py │ │ ├── customer.py │ │ ├── dvd.py │ │ └── movie_world.py │ └── project.zip ├── 04_Gym │ ├── project.zip │ └── project │ │ ├── next_id_mixin.py │ │ ├── trainer.py │ │ ├── equipment.py │ │ ├── customer.py │ │ ├── subscription.py │ │ ├── exercise_plan.py │ │ ├── test.py │ │ └── gym.py ├── 03_Document │ ├── project.zip │ └── project │ │ ├── category.py │ │ ├── topic.py │ │ ├── document.py │ │ └── storage.py ├── .idea │ ├── vcs.xml │ ├── .gitignore │ ├── inspectionProfiles │ │ ├── profiles_settings.xml │ │ └── Project_Default.xml │ ├── modules.xml │ ├── misc.xml │ └── 05_Static_And_Class_Methods_Exercise.iml └── 01_Photo_Album.py ├── .DS_Store ├── 01_First_Steps_In_OOP ├── .DS_Store ├── project.zip ├── main.py ├── .idea │ ├── vcs.xml │ ├── .gitignore │ ├── inspectionProfiles │ │ ├── profiles_settings.xml │ │ └── Project_Default.xml │ ├── modules.xml │ ├── misc.xml │ └── 01_First_Steps_In_OOP.iml ├── Enum_classes.py ├── project │ ├── pokemon.py │ └── trainer.py ├── 01_Shop.py ├── 04_Cup.py ├── 02_Hero.py ├── 03_Employee.py ├── 05_Flower.py ├── 06_SteamUser.py └── 07_Programmer.py ├── 09_Decorators_Exercise ├── files │ ├── log.txt │ └── result.txt ├── project.zip ├── main.py ├── .idea │ ├── vcs.xml │ ├── .gitignore │ ├── inspectionProfiles │ │ ├── profiles_settings.xml │ │ └── Project_Default.xml │ ├── modules.xml │ ├── misc.xml │ └── 09_Decorators_Exercise.iml ├── project │ ├── test.py │ ├── computer_types │ │ ├── laptop.py │ │ ├── desktop_computer.py │ │ └── computer.py │ └── computer_store_app.py ├── 06_HTML_Tags.py ├── 04_Type_Check.py ├── 05_Cache.py ├── 02_Even_Numbers.py ├── 03_Bold_Italic_Underline.py ├── 01_Logged.py ├── 08_Execution_Time.py └── 07_Store_Results.py ├── 06_Polymorphism_And_Abstraction ├── 05_Animals │ ├── project.zip │ └── project │ │ ├── dog.py │ │ ├── cat.py │ │ ├── kitten.py │ │ ├── tomcat.py │ │ └── animal.py ├── 04_Wild_Farm │ ├── project.zip │ └── project │ │ ├── test.py │ │ ├── food.py │ │ └── animals │ │ ├── birds.py │ │ ├── mammals.py │ │ └── animal.py ├── 06_Formula_1_Team │ ├── project.zip │ └── project │ │ ├── test.py │ │ ├── formula_teams │ │ ├── red_bull_team.py │ │ ├── mercedes_team.py │ │ └── formula_team.py │ │ └── f1_season_app.py ├── .idea │ ├── vcs.xml │ ├── .gitignore │ ├── inspectionProfiles │ │ ├── profiles_settings.xml │ │ └── Project_Default.xml │ ├── modules.xml │ ├── misc.xml │ └── 06_Polymorphism_And_Abstraction.iml ├── 02_Groups.py ├── 01_Vehicle_Extra_Not_For_Judge.py ├── 01_Vehicle.py └── 03_Account.py ├── 10_Unit_Testing ├── .idea │ ├── vcs.xml │ ├── .gitignore │ ├── inspectionProfiles │ │ ├── profiles_settings.xml │ │ └── Project_Default.xml │ ├── modules.xml │ ├── misc.xml │ └── 10_Unit_Testing.iml ├── main.py ├── Second_Test_Cat │ ├── cat.py │ └── test_cat.py ├── First_Test_Worker │ ├── worker.py │ └── test_worker.py ├── Third_List │ ├── extended_list.py │ └── test_integer_list.py └── Car_Manager │ ├── car_manager.py │ └── test_car_manager.py ├── 07_SOLID_Exercise ├── .idea │ ├── vcs.xml │ ├── .gitignore │ ├── inspectionProfiles │ │ ├── profiles_settings.xml │ │ └── Project_Default.xml │ ├── modules.xml │ ├── misc.xml │ └── 07_SOLID_Exercise.iml ├── main.py ├── before │ ├── shapes.py │ ├── workers.py │ ├── prisoner.py │ ├── workers_updated.py │ └── emails.py └── after │ ├── prisoner.py │ ├── workers.py │ ├── shapes.py │ ├── workers_updated.py │ └── emails.py ├── 08_Iterators_And_Generators_Exercise ├── .idea │ ├── vcs.xml │ ├── .gitignore │ ├── inspectionProfiles │ │ ├── profiles_settings.xml │ │ └── Project_Default.xml │ ├── modules.xml │ ├── misc.xml │ └── 08_Iterators_And_Generators_Exercise.iml ├── 09_permutations.py ├── 06_fibonacci_generator.py ├── 07_reader.py ├── 08_Prime_Numbers_Generator.py ├── 05_take_halves.py ├── 03_Countdown_Iterator.py ├── 01_Take_Skip.py ├── 04_Sequence_Repeat.py ├── main.py ├── custom_list.py └── 02_Dictionary_iterator.py └── .gitignore /10_Unit_Testing_Exercise/main.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /03_Inheritance/OLD_TASK/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /11_Exam_Preparation/task3/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /03_Inheritance/02_Zoo/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /03_Inheritance/05_Shop/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /11_Exam_Preparation/task3/test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /03_Inheritance/01_Person/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /03_Inheritance/OLD_TASK/Guild_System/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/hero/test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/mammal/test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /11_Exam_Preparation/project/climbers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /11_Exam_Preparation/project/peaks/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/05_Task/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/08_Library/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /03_Inheritance/04_Need_For_Speed/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/hero/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/mammal/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/student/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/student/test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/vehicle/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/vehicle/test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/07_Spoopify/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /03_Inheritance/03_Players_And_Monsters/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /03_Inheritance/OLD_TASK/Guild_System/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/04_HotelRoom/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/02_Movie_World/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/.DS_Store -------------------------------------------------------------------------------- /03_Inheritance/02_Zoo/project/bear.py: -------------------------------------------------------------------------------- 1 | from project.mammal import Mammal 2 | 3 | 4 | class Bear(Mammal): 5 | pass 6 | -------------------------------------------------------------------------------- /03_Inheritance/02_Zoo/project/gorilla.py: -------------------------------------------------------------------------------- 1 | from project.mammal import Mammal 2 | 3 | 4 | class Gorilla(Mammal): 5 | pass -------------------------------------------------------------------------------- /03_Inheritance/02_Zoo/project/mammal.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | 4 | class Mammal(Animal): 5 | pass 6 | -------------------------------------------------------------------------------- /03_Inheritance/02_Zoo/project/reptile.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | 4 | class Reptile(Animal): 5 | pass 6 | -------------------------------------------------------------------------------- /03_Inheritance/02_Zoo/project/snake.py: -------------------------------------------------------------------------------- 1 | from project.reptile import Reptile 2 | 3 | 4 | class Snake(Reptile): 5 | pass 6 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/01_First_Steps_In_OOP/.DS_Store -------------------------------------------------------------------------------- /03_Inheritance/02_Zoo/project/animal.py: -------------------------------------------------------------------------------- 1 | class Animal: 2 | 3 | def __init__(self, name: str): 4 | self.name = name 5 | -------------------------------------------------------------------------------- /03_Inheritance/02_Zoo/project/lizard.py: -------------------------------------------------------------------------------- 1 | from project.reptile import Reptile 2 | 3 | 4 | class Lizard(Reptile): 5 | pass 6 | -------------------------------------------------------------------------------- /03_Inheritance/03_Players_And_Monsters/project/elf.py: -------------------------------------------------------------------------------- 1 | from project.hero import Hero 2 | 3 | 4 | class Elf(Hero): 5 | pass 6 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/files/log.txt: -------------------------------------------------------------------------------- 1 | Function sum_numbers was called. Result: 12 2 | Function sum_numbers was called. Result: 14 3 | -------------------------------------------------------------------------------- /11_Exam_Preparation/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/11_Exam_Preparation/project.zip -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/01_First_Steps_In_OOP/project.zip -------------------------------------------------------------------------------- /03_Inheritance/02_Zoo/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/03_Inheritance/02_Zoo/project.zip -------------------------------------------------------------------------------- /03_Inheritance/03_Players_And_Monsters/project/knight.py: -------------------------------------------------------------------------------- 1 | from project.hero import Hero 2 | 3 | 4 | class Knight(Hero): 5 | pass 6 | -------------------------------------------------------------------------------- /03_Inheritance/03_Players_And_Monsters/project/muse_elf.py: -------------------------------------------------------------------------------- 1 | from project.elf import Elf 2 | 3 | 4 | class MuseElf(Elf): 5 | pass 6 | -------------------------------------------------------------------------------- /03_Inheritance/03_Players_And_Monsters/project/wizard.py: -------------------------------------------------------------------------------- 1 | from project.hero import Hero 2 | 3 | 4 | class Wizard(Hero): 5 | pass 6 | -------------------------------------------------------------------------------- /03_Inheritance/04_Need_For_Speed/project/family_car.py: -------------------------------------------------------------------------------- 1 | from project.car import Car 2 | 3 | 4 | class FamilyCar(Car): 5 | pass 6 | -------------------------------------------------------------------------------- /03_Inheritance/05_Shop/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/03_Inheritance/05_Shop/project.zip -------------------------------------------------------------------------------- /09_Decorators_Exercise/files/result.txt: -------------------------------------------------------------------------------- 1 | Function sum_numbers was called. Result: 14 2 | Function sum_numbers was called. Result: 15 3 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/09_Decorators_Exercise/project.zip -------------------------------------------------------------------------------- /11_Exam_Preparation/task3/test.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/11_Exam_Preparation/task3/test.zip -------------------------------------------------------------------------------- /03_Inheritance/01_Person/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/03_Inheritance/01_Person/project.zip -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/main.py: -------------------------------------------------------------------------------- 1 | nums = [1, 3, 5, 7, 9] 2 | filtered_nums = filter(lambda n: n % 2 == 0, nums) 3 | print(next(filtered_nums)) 4 | 5 | -------------------------------------------------------------------------------- /03_Inheritance/04_Need_For_Speed/project/motorcycle.py: -------------------------------------------------------------------------------- 1 | from project.vehicle import Vehicle 2 | 3 | 4 | class Motorcycle(Vehicle): 5 | pass 6 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/hero/test.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/10_Unit_Testing_Exercise/hero/test.zip -------------------------------------------------------------------------------- /03_Inheritance/03_Players_And_Monsters/project/dark_knight.py: -------------------------------------------------------------------------------- 1 | from project.knight import Knight 2 | 3 | 4 | class DarkKnight(Knight): 5 | pass 6 | -------------------------------------------------------------------------------- /03_Inheritance/03_Players_And_Monsters/project/dark_wizard.py: -------------------------------------------------------------------------------- 1 | from project.wizard import Wizard 2 | 3 | 4 | class DarkWizard(Wizard): 5 | pass 6 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/mammal/test.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/10_Unit_Testing_Exercise/mammal/test.zip -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/student/test.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/10_Unit_Testing_Exercise/student/test.zip -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/vehicle/test.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/10_Unit_Testing_Exercise/vehicle/test.zip -------------------------------------------------------------------------------- /02_Classes_And_Objects/05_Task/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/02_Classes_And_Objects/05_Task/project.zip -------------------------------------------------------------------------------- /03_Inheritance/04_Need_For_Speed/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/03_Inheritance/04_Need_For_Speed/project.zip -------------------------------------------------------------------------------- /03_Inheritance/04_Need_For_Speed/project/car.py: -------------------------------------------------------------------------------- 1 | from project.vehicle import Vehicle 2 | 3 | 4 | class Car(Vehicle): 5 | DEFAULT_FUEL_CONSUMPTION = 3 6 | -------------------------------------------------------------------------------- /03_Inheritance/04_Need_For_Speed/project/sport_car.py: -------------------------------------------------------------------------------- 1 | from project.car import Car 2 | 3 | 4 | class SportCar(Car): 5 | DEFAULT_FUEL_CONSUMPTION = 10 6 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/07_Spoopify/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/02_Classes_And_Objects/07_Spoopify/project.zip -------------------------------------------------------------------------------- /02_Classes_And_Objects/08_Library/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/02_Classes_And_Objects/08_Library/project.zip -------------------------------------------------------------------------------- /03_Inheritance/03_Players_And_Monsters/project/blade_knight.py: -------------------------------------------------------------------------------- 1 | from project.dark_knight import DarkKnight 2 | 3 | 4 | class BladeKnight(DarkKnight): 5 | pass 6 | -------------------------------------------------------------------------------- /03_Inheritance/03_Players_And_Monsters/project/soul_master.py: -------------------------------------------------------------------------------- 1 | from project.dark_wizard import DarkWizard 2 | 3 | 4 | class SoulMaster(DarkWizard): 5 | pass 6 | -------------------------------------------------------------------------------- /03_Inheritance/04_Need_For_Speed/project/cross_motorcycle.py: -------------------------------------------------------------------------------- 1 | from project.motorcycle import Motorcycle 2 | 3 | 4 | class CrossMotorcycle(Motorcycle): 5 | pass 6 | -------------------------------------------------------------------------------- /03_Inheritance/OLD_TASK/Guild_System/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/03_Inheritance/OLD_TASK/Guild_System/project.zip -------------------------------------------------------------------------------- /03_Inheritance/01_Person/project/person.py: -------------------------------------------------------------------------------- 1 | class Person: 2 | 3 | def __init__(self, name: str, age: int): 4 | self.name = name 5 | self.age = age 6 | -------------------------------------------------------------------------------- /03_Inheritance/03_Players_And_Monsters/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/03_Inheritance/03_Players_And_Monsters/project.zip -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/05_Animals/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/06_Polymorphism_And_Abstraction/05_Animals/project.zip -------------------------------------------------------------------------------- /09_Decorators_Exercise/main.py: -------------------------------------------------------------------------------- 1 | class MyClass: 2 | 3 | 4 | def __call__(self): 5 | print(2) 6 | 7 | 8 | a = MyClass() 9 | 10 | a.__call__() 11 | 12 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/04_Gym/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/05_Static_And_Class_Methods_Exercise/04_Gym/project.zip -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/04_HotelRoom/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/05_Static_And_Class_Methods_Lab/04_HotelRoom/project.zip -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/04_Wild_Farm/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/06_Polymorphism_And_Abstraction/04_Wild_Farm/project.zip -------------------------------------------------------------------------------- /03_Inheritance/04_Need_For_Speed/project/race_motorcycle.py: -------------------------------------------------------------------------------- 1 | from project.motorcycle import Motorcycle 2 | 3 | 4 | class RaceMotorcycle(Motorcycle): 5 | DEFAULT_FUEL_CONSUMPTION = 8 6 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/03_Document/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/05_Static_And_Class_Methods_Exercise/03_Document/project.zip -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/06_Formula_1_Team/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/06_Polymorphism_And_Abstraction/06_Formula_1_Team/project.zip -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/02_Movie_World/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DiyanKalaydzhiev23/Python-OOP-2024/HEAD/05_Static_And_Class_Methods_Exercise/02_Movie_World/project.zip -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/05_Animals/project/dog.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | 4 | class Dog(Animal): 5 | 6 | @staticmethod 7 | def make_sound() -> str: 8 | return "Woof!" 9 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/05_Animals/project/cat.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | 4 | class Cat(Animal): 5 | 6 | @staticmethod 7 | def make_sound() -> str: 8 | return "Meow meow!" 9 | -------------------------------------------------------------------------------- /03_Inheritance/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /10_Unit_Testing/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/Enum_classes.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | 4 | class Color(Enum, object): 5 | RED = 1 6 | GREEN = 2 7 | BLUE = 3 8 | 9 | 10 | color = Color.RED 11 | print(color.name, color.value) 12 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /11_Exam_Preparation/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /03_Inheritance/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /10_Unit_Testing/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /03_Inheritance/05_Shop/project/food.py: -------------------------------------------------------------------------------- 1 | from project.product import Product 2 | 3 | 4 | class Food(Product): 5 | DEFAULT_QUANTITY = 15 6 | 7 | def __init__(self, name: str): 8 | super().__init__(name, self.DEFAULT_QUANTITY) 9 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /11_Exam_Preparation/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /03_Inheritance/05_Shop/project/drink.py: -------------------------------------------------------------------------------- 1 | from project.product import Product 2 | 3 | 4 | class Drink(Product): 5 | DEFAULT_QUANTITY: int = 10 6 | 7 | def __init__(self, name: str): 8 | super().__init__(name, self.DEFAULT_QUANTITY) 9 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /03_Inheritance/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /10_Unit_Testing/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /11_Exam_Preparation/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/project/pokemon.py: -------------------------------------------------------------------------------- 1 | class Pokemon: 2 | def __init__(self, name: str, health: int): 3 | self.name = name 4 | self.health = health 5 | 6 | def pokemon_details(self) -> str: 7 | return f"{self.name} with health {self.health}" 8 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/09_permutations.py: -------------------------------------------------------------------------------- 1 | from itertools import permutations 2 | 3 | 4 | def possible_permutations(elements: list): 5 | for el in permutations(elements): 6 | yield list(el) 7 | 8 | 9 | [print(n) for n in possible_permutations([1, 2, 3])] -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/06_fibonacci_generator.py: -------------------------------------------------------------------------------- 1 | def fibonacci(): 2 | n1, n2 = 0, 1 3 | 4 | while True: 5 | yield n1 6 | n1, n2 = n2, n1 + n2 7 | 8 | generator = fibonacci() 9 | 10 | for _ in range(50): 11 | print(next(generator)) 12 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/project/test.py: -------------------------------------------------------------------------------- 1 | from project.computer_store_app import ComputerStoreApp 2 | 3 | computer_store = ComputerStoreApp() 4 | print(computer_store.build_computer("Laptop", "Apple", "Macbook", "Apple M1 Pro", 64)) 5 | print(computer_store.sell_computer(10000, "Apple M1 Pro", 32)) 6 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/04_Gym/project/next_id_mixin.py: -------------------------------------------------------------------------------- 1 | class NextIdMixin: 2 | id = -1 # not needed, only to avoid warnings 3 | 4 | @classmethod 5 | def get_next_id(cls): 6 | return cls.id 7 | 8 | @classmethod 9 | def increment_id(cls): 10 | cls.id += 1 -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/01_Shop.py: -------------------------------------------------------------------------------- 1 | class Shop: 2 | def __init__(self, name, items): 3 | self.name = name 4 | self.items = items 5 | 6 | def get_items_count(self): 7 | return len(self.items) 8 | 9 | 10 | billa = Shop("Billa", ["apple", "bread"]) 11 | print(billa.get_items_count()) -------------------------------------------------------------------------------- /03_Inheritance/01_Person/project/child.py: -------------------------------------------------------------------------------- 1 | from project.person import Person 2 | 3 | 4 | class Child(Person): 5 | pass 6 | 7 | 8 | person = Person("Peter", 25) 9 | child = Child("Peter Junior", 5) 10 | 11 | print(person.name) 12 | print(person.age) 13 | 14 | print(child.__class__.__bases__[0].__name__) 15 | -------------------------------------------------------------------------------- /03_Inheritance/03_Players_And_Monsters/project/hero.py: -------------------------------------------------------------------------------- 1 | class Hero: 2 | 3 | def __init__(self, username: str, level: int): 4 | self.username = username 5 | self.level = level 6 | 7 | def __str__(self): 8 | return f"{self.username} of type {self.__class__.__name__} has level {self.level}" 9 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/05_Animals/project/kitten.py: -------------------------------------------------------------------------------- 1 | from project.cat import Cat 2 | 3 | 4 | class Kitten(Cat): 5 | 6 | def __init__(self, name: str, age: int): 7 | super().__init__(name, age, "Female") 8 | 9 | @staticmethod 10 | def make_sound() -> str: 11 | return "Meow" 12 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/05_Animals/project/tomcat.py: -------------------------------------------------------------------------------- 1 | from project.cat import Cat 2 | 3 | 4 | class Tomcat(Cat): 5 | 6 | def __init__(self, name: str, age: int): 7 | super().__init__(name, age, "Male") 8 | 9 | @staticmethod 10 | def make_sound() -> str: 11 | return "Hiss" 12 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/07_Spoopify/project/song.py: -------------------------------------------------------------------------------- 1 | class Song: 2 | 3 | def __init__(self, name: str, length: float, single: bool): 4 | self.name = name 5 | self.length = length 6 | self.single = single 7 | 8 | def get_info(self) -> str: 9 | return f"{self.name} - {self.length}" 10 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/04_Wild_Farm/project/test.py: -------------------------------------------------------------------------------- 1 | from project.animals.birds import Owl 2 | from project.food import Meat, Vegetable 3 | 4 | owl = Owl("Pip", 10, 10) 5 | print(owl) 6 | meat = Meat(4) 7 | print(owl.make_sound()) 8 | owl.feed(meat) 9 | veg = Vegetable(1) 10 | print(owl.feed(veg)) 11 | print(owl) 12 | -------------------------------------------------------------------------------- /03_Inheritance/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /10_Unit_Testing/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /11_Exam_Preparation/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/07_reader.py: -------------------------------------------------------------------------------- 1 | def read_next(*args): 2 | for seq in args: 3 | # Option 1 4 | # for el in seq: 5 | # yield el 6 | 7 | # Option 2 8 | yield from seq 9 | 10 | 11 | for item in read_next("string", (2,), {"d": 1, "i": 2, "c": 3, "t": 4}): 12 | print(item, end='') 13 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /03_Inheritance/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /10_Unit_Testing/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/03_Document/project/category.py: -------------------------------------------------------------------------------- 1 | class Category: 2 | 3 | def __init__(self, _id: int, name: str): 4 | self.id = _id 5 | self.name = name 6 | 7 | def edit(self, new_name: str) -> None: 8 | self.name = new_name 9 | 10 | def __repr__(self): 11 | return f"Category {self.id}: {self.name}" 12 | -------------------------------------------------------------------------------- /11_Exam_Preparation/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/04_Wild_Farm/project/food.py: -------------------------------------------------------------------------------- 1 | from abc import ABC 2 | 3 | 4 | class Food(ABC): 5 | def __init__(self, quantity: int): 6 | self.quantity = quantity 7 | 8 | 9 | class Fruit(Food): 10 | pass 11 | 12 | 13 | class Vegetable(Food): 14 | pass 15 | 16 | 17 | class Meat(Food): 18 | pass 19 | 20 | 21 | class Seed(Food): 22 | pass 23 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/06_Formula_1_Team/project/test.py: -------------------------------------------------------------------------------- 1 | from project.f1_season_app import F1SeasonApp 2 | 3 | f1_season = F1SeasonApp() 4 | 5 | print(f1_season.register_team_for_season("Red Bull", 2000000)) 6 | print(f1_season.register_team_for_season("Mercedes", 2500000)) 7 | print(f1_season.new_race_results("Nurburgring", 1, 7)) 8 | print(f1_season.new_race_results("Silverstone", 10, 1)) 9 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/06_HTML_Tags.py: -------------------------------------------------------------------------------- 1 | def tags(tag: str): 2 | def decorator(func): 3 | def wrapper(*args, **kwargs): 4 | return f"<{tag}>{func(*args, **kwargs)}" 5 | 6 | return wrapper 7 | 8 | return decorator 9 | 10 | 11 | @tags('body') 12 | @tags('div') 13 | @tags('p') 14 | def say_hi(): 15 | return "Hello" 16 | 17 | 18 | print(say_hi()) 19 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/04_Gym/project/trainer.py: -------------------------------------------------------------------------------- 1 | from project.next_id_mixin import NextIdMixin 2 | 3 | 4 | class Trainer(NextIdMixin): 5 | id = 1 6 | 7 | def __init__(self, name: str): 8 | self.name = name 9 | self.id = self.get_next_id() 10 | self.increment_id() 11 | 12 | def __repr__(self): 13 | return f"Trainer <{self.id}> {self.name}" 14 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/04_Gym/project/equipment.py: -------------------------------------------------------------------------------- 1 | from project.next_id_mixin import NextIdMixin 2 | 3 | 4 | class Equipment(NextIdMixin): 5 | id = 1 6 | 7 | def __init__(self, name: str): 8 | self.name = name 9 | self.id = self.get_next_id() 10 | self.increment_id() 11 | 12 | def __repr__(self): 13 | return f"Equipment <{self.id}> {self.name}" 14 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /10_Unit_Testing/.idea/10_Unit_Testing.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/main.py: -------------------------------------------------------------------------------- 1 | class Car: 2 | TIRES = 4 3 | 4 | def __init__(self, hp: int): 5 | self.hp = hp 6 | 7 | def __str__(self): 8 | return f"This is car with {self.hp} hp" 9 | 10 | def __repr__(self): 11 | return f"This is car with {self.hp} hp" 12 | 13 | 14 | nissan = Car(255) 15 | toyota = Car(320) 16 | 17 | Car.TIRES = 5 18 | 19 | print(nissan.TIRES) 20 | print(toyota.TIRES) -------------------------------------------------------------------------------- /07_SOLID_Exercise/.idea/07_SOLID_Exercise.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /11_Exam_Preparation/.idea/11_Exam_Preparation.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/.idea/09_Decorators_Exercise.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/.idea/08_Iterators_And_Generators_Exercise.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/08_Prime_Numbers_Generator.py: -------------------------------------------------------------------------------- 1 | from math import isqrt 2 | 3 | 4 | def get_primes(numbers: list): 5 | for number in numbers: 6 | if number <= 1: 7 | continue 8 | 9 | for divisor in range(2, isqrt(number) + 1): 10 | if number % divisor == 0: 11 | break 12 | else: 13 | yield number 14 | 15 | 16 | print(list(get_primes([2, 4, 3, 5, 6, 9, 1, 0]))) 17 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/08_Library/project/user.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class User: 5 | 6 | def __init__(self, user_id: int, username: str): 7 | self.user_id = user_id 8 | self.username = username 9 | self.books: List[str] = [] 10 | 11 | def info(self) -> str: 12 | return ", ".join(sorted(self.books)) or "[]" 13 | 14 | def __str__(self): 15 | return f"{self.user_id}, {self.username}, {self.info()}" 16 | -------------------------------------------------------------------------------- /03_Inheritance/05_Shop/project/product.py: -------------------------------------------------------------------------------- 1 | class Product: 2 | 3 | def __init__(self, name: str, quantity: int): 4 | self.name = name 5 | self.quantity = quantity 6 | 7 | def increase(self, quantity: int) -> None: 8 | self.quantity += quantity 9 | 10 | def decrease(self, quantity: int) -> None: 11 | if quantity <= self.quantity: 12 | self.quantity -= quantity 13 | 14 | def __repr__(self): 15 | return self.name 16 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/04_Type_Check.py: -------------------------------------------------------------------------------- 1 | def type_check(expected_type): 2 | def decorator(func): 3 | def wrapper(*args): 4 | for arg in args: 5 | if not isinstance(arg, expected_type): 6 | return "Bad Type" 7 | 8 | return func(*args) 9 | 10 | return wrapper 11 | 12 | return decorator 13 | 14 | 15 | @type_check(int) 16 | def sum_numbers(a, b): 17 | return a + b 18 | 19 | print(sum_numbers(5, 6.5)) -------------------------------------------------------------------------------- /03_Inheritance/04_Need_For_Speed/project/vehicle.py: -------------------------------------------------------------------------------- 1 | class Vehicle: 2 | DEFAULT_FUEL_CONSUMPTION = 1.25 3 | 4 | def __init__(self, fuel: float, horse_power: int): 5 | self.fuel = fuel 6 | self.horse_power = horse_power 7 | self.fuel_consumption = self.DEFAULT_FUEL_CONSUMPTION 8 | 9 | def drive(self, kilometers: int) -> None: 10 | if self.fuel >= kilometers * self.fuel_consumption: 11 | self.fuel -= kilometers * self.fuel_consumption 12 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/04_HotelRoom/project/test.py: -------------------------------------------------------------------------------- 1 | from project.hotel import Hotel 2 | from project.room import Room 3 | 4 | hotel = Hotel.from_stars(5) 5 | 6 | first_room = Room(1, 3) 7 | second_room = Room(2, 2) 8 | third_room = Room(3, 1) 9 | 10 | hotel.add_room(first_room) 11 | hotel.add_room(second_room) 12 | hotel.add_room(third_room) 13 | 14 | hotel.take_room(1, 4) 15 | hotel.take_room(1, 2) 16 | hotel.take_room(3, 1) 17 | hotel.take_room(3, 1) 18 | 19 | print(hotel.status()) 20 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/05_Cache.py: -------------------------------------------------------------------------------- 1 | def cache(func): 2 | def wrapper(num): 3 | if not wrapper.log.get(num): # 0(1) 4 | wrapper.log[num] = func(num) 5 | 6 | return wrapper.log[num] 7 | 8 | wrapper.log = {} 9 | 10 | return wrapper 11 | 12 | 13 | @cache 14 | def fibonacci(n): 15 | if n < 2: 16 | return n 17 | else: 18 | return fibonacci(n - 1) + fibonacci(n - 2) 19 | 20 | 21 | fibonacci(3) 22 | fibonacci(3) 23 | print(fibonacci.log) 24 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/mammal/project/mammal.py: -------------------------------------------------------------------------------- 1 | class Mammal: 2 | def __init__(self, name, mammal_type, sound): 3 | self.name = name 4 | self.type = mammal_type 5 | self.sound = sound 6 | self.__kingdom = "animals" 7 | 8 | def make_sound(self): 9 | return f"{self.name} makes {self.sound}" 10 | 11 | def get_kingdom(self): 12 | return self.__kingdom 13 | 14 | def info(self): 15 | return f"{self.name} is of type {self.type}" 16 | -------------------------------------------------------------------------------- /03_Inheritance/.idea/03_Inheritance.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/05_take_halves.py: -------------------------------------------------------------------------------- 1 | def solution(): 2 | 3 | def integers(): 4 | num: int = 1 5 | 6 | while True: 7 | yield num 8 | num += 1 9 | 10 | def halves(): 11 | for num in integers(): 12 | yield num / 2 13 | 14 | def take(n, seq): 15 | return [next(seq) for _ in range(n)] 16 | 17 | return take, halves, integers 18 | 19 | take = solution()[0] 20 | halves = solution()[1] 21 | generator = halves() 22 | -------------------------------------------------------------------------------- /11_Exam_Preparation/project/peaks/arctic_peak.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from project.peaks.base_peak import BasePeak 3 | 4 | 5 | class ArcticPeak(BasePeak): 6 | 7 | def get_recommended_gear(self) -> List[str]: 8 | return ["Ice axe", "Crampons", "Insulated clothing", "Helmet"] 9 | 10 | def calculate_difficulty_level(self) -> str: 11 | if self.elevation > 3000: 12 | return "Extreme" 13 | elif 2000 <= self.elevation <= 3000: 14 | return "Advanced" 15 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/04_Cup.py: -------------------------------------------------------------------------------- 1 | class Cup: 2 | def __init__(self, size: int, quantity: int): 3 | self.size = size 4 | self.quantity = quantity 5 | 6 | def fill(self, quantity: int) -> None: 7 | if self.quantity + quantity <= self.size: 8 | self.quantity += quantity 9 | 10 | def status(self) -> int: 11 | return self.size - self.quantity 12 | 13 | 14 | cup = Cup(100, 50) 15 | print(cup.status()) 16 | cup.fill(40) 17 | cup.fill(20) 18 | print(cup.status()) 19 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/custom_reduce.py: -------------------------------------------------------------------------------- 1 | import inspect 2 | 3 | 4 | def custom_reduce(func, iterable): 5 | args_count = len(inspect.getfullargspec(func).args) 6 | 7 | accumulator = iterable[0] 8 | 9 | for i in range(1, len(iterable), args_count - 1): 10 | args_to_pass = iterable[i:i+args_count - 1] # 3 11 | accumulator = func(accumulator, *args_to_pass) 12 | 13 | print(accumulator) # original return 14 | 15 | 16 | custom_reduce(lambda x, y, z: x * y * z, [2, 3, 4]) 17 | -------------------------------------------------------------------------------- /11_Exam_Preparation/project/peaks/summit_peak.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from project.peaks.base_peak import BasePeak 3 | 4 | 5 | class SummitPeak(BasePeak): 6 | 7 | def get_recommended_gear(self) -> List[str]: 8 | return ["Climbing helmet", "Harness", "Climbing shoes", "Ropes"] 9 | 10 | def calculate_difficulty_level(self) -> str: 11 | if self.elevation > 2500: 12 | return "Extreme" 13 | elif 1500 <= self.elevation <= 2500: 14 | return "Advanced" 15 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/.idea/01_First_Steps_In_OOP.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/.idea/02_Classes_And_Objects.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/.idea/10_Unit_Testing_Exercise.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/03_Document/project/topic.py: -------------------------------------------------------------------------------- 1 | class Topic: 2 | 3 | def __init__(self, _id: int, topic: str, storage_folder: str): 4 | self.id = _id 5 | self.topic = topic 6 | self.storage_folder = storage_folder 7 | 8 | def edit(self, new_topic: str, new_storage_folder: str) -> None: 9 | self.topic = new_topic 10 | self.storage_folder = new_storage_folder 11 | 12 | def __repr__(self): 13 | return f"Topic {self.id}: {self.topic} in {self.storage_folder}" 14 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/03_Countdown_Iterator.py: -------------------------------------------------------------------------------- 1 | class countdown_iterator: 2 | 3 | def __init__(self, count: int): 4 | self.count = count + 1 5 | 6 | def __iter__(self): 7 | return self 8 | 9 | def __next__(self): 10 | if self.count <= 0: 11 | raise StopIteration 12 | 13 | self.count -= 1 14 | 15 | return self.count 16 | 17 | 18 | iterator = countdown_iterator(10) 19 | 20 | for el in iterator: 21 | print(el) 22 | 23 | for el in iterator: 24 | print(el) -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/04_Gym/project/customer.py: -------------------------------------------------------------------------------- 1 | from project.next_id_mixin import NextIdMixin 2 | 3 | 4 | class Customer(NextIdMixin): 5 | id = 1 6 | 7 | def __init__(self, name: str, address: str, email: str): 8 | self.name = name 9 | self.address = address 10 | self.email = email 11 | self.id = self.get_next_id() 12 | self.increment_id() 13 | 14 | def __repr__(self): 15 | return f"Customer <{self.id}> {self.name}; Address: {self.address}; Email: {self.email}" 16 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/.idea/05_Static_And_Class_Methods_Lab.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/05_Animals/project/animal.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class Animal(ABC): 5 | 6 | def __init__(self, name: str, age: int, gender: str): 7 | self.name = name 8 | self.age = age 9 | self.gender = gender 10 | 11 | @staticmethod 12 | @abstractmethod 13 | def make_sound() -> str: 14 | ... 15 | 16 | def __repr__(self): 17 | return f"This is {self.name}. {self.name} is a {self.age} year old {self.gender} {self.__class__.__name__}" 18 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/main.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | class Car(ABC): 4 | pass 5 | 6 | class Fuel(ABC): 7 | 8 | @abstractmethod 9 | def refuel(self): 10 | ... 11 | 12 | class Charge(ABC): 13 | 14 | @abstractmethod 15 | def charge(self): 16 | ... 17 | 18 | class CarWithCombustionEngine(Car, Fuel): 19 | 20 | def refuel(self): 21 | print("Fueling with A95") 22 | 23 | 24 | class ElectricCar(Car, Charge): 25 | 26 | def charge(self): 27 | print("Charging as your iphone") -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/.idea/05_Static_And_Class_Methods_Exercise.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/.idea/06_Polymorphism_And_Abstraction.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/01_Calculator.py: -------------------------------------------------------------------------------- 1 | from functools import reduce 2 | 3 | 4 | class Calculator: 5 | 6 | @staticmethod 7 | def add(*nums) -> int: 8 | return sum(nums) 9 | 10 | @staticmethod 11 | def multiply(*nums) -> int: 12 | return reduce(lambda x, y: x * y, nums) 13 | 14 | @staticmethod 15 | def subtract(*nums) -> int: 16 | return reduce(lambda x, y: x - y, nums) 17 | 18 | @staticmethod 19 | def divide(*nums) -> float: 20 | return reduce(lambda x, y: x / y, nums) 21 | 22 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/02_Hero.py: -------------------------------------------------------------------------------- 1 | class Hero: 2 | def __init__(self, name, health): 3 | self.name = name 4 | self.health = health 5 | 6 | def defend(self, damage): 7 | self.health -= damage 8 | 9 | if self.health <= 0: 10 | self.health = 0 11 | return f"{self.name} was defeated" 12 | 13 | def heal(self, amount): 14 | self.health += amount 15 | 16 | 17 | hero = Hero("Peter", 100) 18 | print(hero.defend(50)) 19 | hero.heal(50) 20 | print(hero.defend(99)) 21 | print(hero.defend(1)) 22 | -------------------------------------------------------------------------------- /10_Unit_Testing/main.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | 3 | 4 | class MyCar: 5 | 6 | def __init__(self, model: str, hp: int): 7 | self.model = model 8 | self.hp = hp 9 | 10 | 11 | # Test suite 12 | class TestMyCar(TestCase): 13 | 14 | def test_correct_init(self): 15 | model, hp = "BMW", 100 # Arrange 16 | 17 | my_car = MyCar(model, hp) # Act 18 | 19 | self.assertEqual(my_car.model, model) 20 | self.assertEqual(my_car.hp, hp) 21 | 22 | 23 | if __name__ == "__main__": 24 | main() 25 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/02_Movie_World/project/customer.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from project.dvd import DVD 3 | 4 | 5 | class Customer: 6 | 7 | def __init__(self, name: str, age: int, _id: int): 8 | self.name = name 9 | self.age = age 10 | self.id = _id 11 | self.rented_dvds: List[DVD] = [] 12 | 13 | def __repr__(self): 14 | return (f"{self.id}: {self.name} of age {self.age} has {len(self.rented_dvds)} " 15 | f"rented DVD's ({', '.join(d.name for d in self.rented_dvds)})") 16 | -------------------------------------------------------------------------------- /10_Unit_Testing/Second_Test_Cat/cat.py: -------------------------------------------------------------------------------- 1 | class Cat: 2 | 3 | def __init__(self, name): 4 | self.name = name 5 | self.fed = False 6 | self.sleepy = False 7 | self.size = 0 8 | 9 | def eat(self): 10 | if self.fed: 11 | raise Exception('Already fed.') 12 | 13 | self.fed = True 14 | self.sleepy = True 15 | self.size += 1 16 | 17 | def sleep(self): 18 | if not self.fed: 19 | raise Exception('Cannot sleep while hungry') 20 | 21 | self.sleepy = False 22 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/project/computer_types/laptop.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | from project.computer_types.computer import Computer 3 | 4 | 5 | class Laptop(Computer): 6 | 7 | @property 8 | def type(self) -> str: 9 | return "laptop" 10 | 11 | @property 12 | def available_processors(self) -> Dict[str, int]: 13 | return { 14 | "AMD Ryzen 9 5950X": 900, 15 | "Intel Core i9-11900H": 1050, 16 | "Apple M1 Pro": 1200, 17 | } 18 | 19 | @property 20 | def max_ram(self) -> int: 21 | return 64 22 | -------------------------------------------------------------------------------- /10_Unit_Testing/First_Test_Worker/worker.py: -------------------------------------------------------------------------------- 1 | class Worker: 2 | 3 | def __init__(self, name, salary, energy): 4 | self.name = name 5 | self.salary = salary 6 | self.energy = energy 7 | self.money = 0 8 | 9 | def work(self): 10 | if self.energy <= 0: 11 | raise Exception('Not enough energy.') 12 | 13 | self.money += self.salary 14 | self.energy -= 1 15 | 16 | def rest(self): 17 | self.energy += 1 18 | 19 | def get_info(self): 20 | return f'{self.name} has saved {self.money} money.' 21 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/01_Take_Skip.py: -------------------------------------------------------------------------------- 1 | class take_skip: 2 | def __init__(self, step: int, count: int): 3 | self.step = step # 2 4 | self.count = count # 6 5 | self.iterations = -1 6 | 7 | def __iter__(self): 8 | return self 9 | 10 | def __next__(self): 11 | if self.iterations == self.count - 1: 12 | raise StopIteration 13 | 14 | self.iterations += 1 15 | 16 | return self.iterations * self.step 17 | 18 | 19 | numbers = take_skip(2, 6) 20 | for number in numbers: 21 | print(number) 22 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/02_Even_Numbers.py: -------------------------------------------------------------------------------- 1 | def even_parameters(func): 2 | def wrapper(*args): 3 | for arg in args: 4 | if isinstance(arg, int): 5 | if arg % 2 == 0: 6 | continue 7 | 8 | return "Please use only even numbers!" 9 | 10 | return func(*args) 11 | 12 | return wrapper 13 | 14 | 15 | @even_parameters 16 | def sum_numbers(a, b, c): 17 | return a + b + c 18 | 19 | 20 | print(sum_numbers(4, 6, 8)) 21 | print(sum_numbers(4, 6, 7)) # Please use only even numbers! 22 | print(sum_numbers(4, 6, 5)) 23 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/04_Gym/project/subscription.py: -------------------------------------------------------------------------------- 1 | from project.next_id_mixin import NextIdMixin 2 | 3 | 4 | class Subscription(NextIdMixin): 5 | id = 1 6 | 7 | def __init__(self, date: str, customer_id: int, trainer_id: int, exercise_id: int): 8 | self.date = date 9 | self.customer_id = customer_id 10 | self.trainer_id = trainer_id 11 | self.exercise_id = exercise_id 12 | self.id = self.get_next_id() 13 | self.increment_id() 14 | 15 | def __repr__(self): 16 | return f"Subscription <{self.id}> on {self.date}" 17 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/project/computer_types/desktop_computer.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | from project.computer_types.computer import Computer 3 | 4 | 5 | class DesktopComputer(Computer): 6 | 7 | @property 8 | def type(self) -> str: 9 | return "desktop computer" 10 | 11 | @property 12 | def available_processors(self) -> Dict[str, int]: 13 | return { 14 | "AMD Ryzen 7 5700G": 500, 15 | "Intel Core i5-12600K": 600, 16 | "Apple M1 Max": 1800, 17 | } 18 | 19 | @property 20 | def max_ram(self) -> int: 21 | return 128 22 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/04_Sequence_Repeat.py: -------------------------------------------------------------------------------- 1 | class sequence_repeat: 2 | 3 | def __init__(self, sequence: str, number: int): 4 | self.sequence = sequence 5 | self.number = number 6 | self.idx = -1 7 | 8 | def __iter__(self): 9 | return self 10 | 11 | def __next__(self): 12 | if self.idx == self.number - 1: 13 | raise StopIteration 14 | 15 | self.idx += 1 16 | 17 | return self.sequence[self.idx % len(self.sequence)] 18 | 19 | 20 | result = sequence_repeat('abc', 5) 21 | for item in result: 22 | print(item, end ='') 23 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/06_Formula_1_Team/project/formula_teams/red_bull_team.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | from project.formula_teams.formula_team import FormulaTeam 3 | 4 | 5 | class RedBullTeam(FormulaTeam): 6 | 7 | @property 8 | def sponsors(self): 9 | return { 10 | "Oracle": { 11 | 1: 1_500_000, 12 | 2: 800_000, 13 | }, 14 | "Honda": { 15 | 8: 20_000, 16 | 10: 10_000, 17 | } 18 | } 19 | 20 | @property 21 | def expenses_for_one_race(self) -> int: 22 | return 250_000 23 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/06_Formula_1_Team/project/formula_teams/mercedes_team.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | from project.formula_teams.formula_team import FormulaTeam 3 | 4 | 5 | class MercedesTeam(FormulaTeam): 6 | 7 | @property 8 | def sponsors(self): 9 | return { 10 | "Petronas": { 11 | 1: 1_000_000, 12 | 3: 500_000, 13 | }, 14 | "TeamViewer": { 15 | 5: 100_000, 16 | 7: 50_000, 17 | } 18 | } 19 | 20 | @property 21 | def expenses_for_one_race(self) -> int: 22 | return 200_000 23 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/03_Bold_Italic_Underline.py: -------------------------------------------------------------------------------- 1 | def make_bold(func): 2 | def wrapper(*args, **kwargs): 3 | return f"{func(*args, **kwargs)}" 4 | 5 | return wrapper 6 | 7 | 8 | def make_italic(func): 9 | def wrapper(*args, **kwargs): 10 | return f"{func(*args, **kwargs)}" 11 | 12 | return wrapper 13 | 14 | 15 | def make_underline(func): 16 | def wrapper(*args, **kwargs): 17 | return f"{func(*args, **kwargs)}" 18 | 19 | return wrapper 20 | 21 | 22 | @make_italic 23 | @make_underline 24 | @make_bold 25 | def greet(name): 26 | return f"Hello, {name}" 27 | 28 | 29 | print(greet("Peter")) 30 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/03_Account.py: -------------------------------------------------------------------------------- 1 | class Account: 2 | 3 | def __init__(self, _id: int, name: str, balance: int = 0): 4 | self.id = _id 5 | self.name = name 6 | self.balance = balance 7 | 8 | def credit(self, amount: int) -> int: 9 | self.balance += amount 10 | return self.balance 11 | 12 | def debit(self, amount: int) -> str or int: 13 | if self.balance < amount: 14 | return "Amount exceeded balance" 15 | 16 | self.balance -= amount 17 | 18 | return self.balance 19 | 20 | def info(self) -> str: 21 | return f"User {self.name} with account {self.id} has {self.balance} balance" 22 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/01_Logged.py: -------------------------------------------------------------------------------- 1 | 2 | def logged(func): 3 | def wrapper(*args, **kwargs): 4 | return f"you called {func.__name__}{args}\n" \ 5 | f"it returned {func(*args, **kwargs)}" 6 | 7 | return wrapper 8 | 9 | # Bonus 10 | # def logged(func): 11 | # def wrapper(*args, **kwargs): 12 | # return (f"you called {func.__name__}({', '.join(str(a) for a in args)}, " 13 | # f"{', '.join(f'{k}={v}' for k, v in kwargs.items())})\n" 14 | # f"it returned {func(*args, **kwargs)}") 15 | # 16 | # return wrapper 17 | 18 | @logged 19 | def sum_numbers(a, b): 20 | return a + b 21 | 22 | 23 | print(sum_numbers(5, 4)) -------------------------------------------------------------------------------- /07_SOLID_Exercise/before/shapes.py: -------------------------------------------------------------------------------- 1 | class Rectangle: 2 | 3 | def __init__(self, width, height): 4 | self.width = width 5 | self.height = height 6 | 7 | class AreaCalculator: 8 | 9 | def __init__(self, shapes): 10 | 11 | assert isinstance(shapes, list), "`shapes` should be of type `list`." 12 | self.shapes = shapes 13 | 14 | @property 15 | def total_area(self): 16 | total = 0 17 | for shape in self.shapes: 18 | total += shape.width * shape.height 19 | 20 | return total 21 | 22 | 23 | shapes = [Rectangle(2, 3), Rectangle(1, 6)] 24 | calculator = AreaCalculator(shapes) 25 | print("The total area is: ", calculator.total_area) 26 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/04_Gym/project/exercise_plan.py: -------------------------------------------------------------------------------- 1 | from project.next_id_mixin import NextIdMixin 2 | 3 | 4 | class ExercisePlan(NextIdMixin): 5 | id = 1 6 | 7 | def __init__(self, trainer_id: int, equipment_id: int, duration: int): 8 | self.trainer_id = trainer_id 9 | self.equipment_id = equipment_id 10 | self.duration = duration 11 | self.id = self.get_next_id() 12 | self.increment_id() 13 | 14 | @classmethod 15 | def from_hours(cls, trainer_id: int, equipment_id: int, hours: int): 16 | return cls(trainer_id, equipment_id, hours * 60) 17 | 18 | def __repr__(self): 19 | return f"Plan <{self.id}> with duration {self.duration} minutes" 20 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/04_HotelRoom/project/room.py: -------------------------------------------------------------------------------- 1 | class Room: 2 | 3 | def __init__(self, number: int, capacity: int): 4 | self.number = number 5 | self.capacity = capacity 6 | self.guests: int = 0 7 | self.is_taken: bool = False 8 | 9 | def take_room(self, people: int) -> str or None: 10 | if people > self.capacity or self.is_taken: 11 | return f"Room number {self.number} cannot be taken" 12 | 13 | self.is_taken = True 14 | self.guests = people 15 | 16 | def free_room(self) -> str or None: 17 | if not self.is_taken: 18 | return f"Room number {self.number} is not taken" 19 | 20 | self.is_taken = False 21 | self.guests = 0 22 | -------------------------------------------------------------------------------- /11_Exam_Preparation/project/climbers/arctic_climber.py: -------------------------------------------------------------------------------- 1 | from project.climbers.base_climber import BaseClimber 2 | from project.peaks.base_peak import BasePeak 3 | 4 | 5 | class ArcticClimber(BaseClimber): 6 | MIN_STRENGTH_NEEDED: float = 100 7 | INITIAL_STRENGTH_NEEDED: float = 200 8 | 9 | def __init__(self, name: str): 10 | super().__init__(name, ArcticClimber.INITIAL_STRENGTH_NEEDED) 11 | 12 | def can_climb(self) -> bool: 13 | return self.strength >= ArcticClimber.MIN_STRENGTH_NEEDED 14 | 15 | def climb(self, peak: BasePeak) -> None: 16 | if peak.difficulty_level == "Extreme": 17 | self.strength -= 20 * 2 18 | else: 19 | self.strength -= 20 * 1.5 20 | 21 | self.conquered_peaks.append(peak.name) 22 | -------------------------------------------------------------------------------- /11_Exam_Preparation/project/climbers/summit_climber.py: -------------------------------------------------------------------------------- 1 | from project.climbers.base_climber import BaseClimber 2 | from project.peaks.base_peak import BasePeak 3 | 4 | 5 | class SummitClimber(BaseClimber): 6 | MIN_STRENGTH_NEEDED: float = 75 7 | INITIAL_STRENGTH_NEEDED: float = 150 8 | 9 | def __init__(self, name: str): 10 | super().__init__(name, SummitClimber.INITIAL_STRENGTH_NEEDED) 11 | 12 | def can_climb(self) -> bool: 13 | return self.strength >= SummitClimber.MIN_STRENGTH_NEEDED 14 | 15 | def climb(self, peak: BasePeak) -> None: 16 | if peak.difficulty_level == "Advanced": 17 | self.strength -= 30 * 1.3 18 | else: 19 | self.strength -= 30 * 2.5 20 | 21 | self.conquered_peaks.append(peak.name) 22 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/03_Employee.py: -------------------------------------------------------------------------------- 1 | class Employee: 2 | MONTHS = 12 3 | 4 | def __init__(self, _id: int, first_name: str, last_name: str, salary: float): 5 | self.id = _id 6 | self.first_name = first_name 7 | self.last_name = last_name 8 | self.salary = salary 9 | 10 | def get_full_name(self) -> str: 11 | return self.first_name + " " + self.last_name 12 | 13 | def get_annual_salary(self) -> float: 14 | return self.salary * Employee.MONTHS 15 | 16 | def raise_salary(self, amount: float) -> float: 17 | self.salary += amount 18 | return self.salary 19 | 20 | 21 | employee = Employee(744423129, "John", "Smith", 1000) 22 | print(employee.get_full_name()) 23 | print(employee.raise_salary(500)) 24 | print(employee.get_annual_salary()) 25 | 26 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/05_Flower.py: -------------------------------------------------------------------------------- 1 | class Flower: 2 | 3 | def __init__(self, name: str, water_requirements: int): 4 | self.name = name 5 | self.water_requirements = water_requirements 6 | self.is_happy = False 7 | 8 | def water(self, quantity: int) -> None: 9 | if quantity >= self.water_requirements: 10 | self.is_happy = True 11 | 12 | def status(self) -> str: 13 | return f"{self.name} is {'' if self.is_happy else 'not '}happy" 14 | # if self.is_happy: 15 | # return f"{self.name} is happy" 16 | # 17 | # return f"{self.name} is not happy" 18 | 19 | 20 | flower = Flower("Lilly", 100) 21 | flower.water(100) 22 | print(flower.status()) 23 | 24 | tulip = Flower("John", 50) 25 | tulip.water(200) 26 | print(tulip.status()) 27 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/04_Wild_Farm/project/animals/birds.py: -------------------------------------------------------------------------------- 1 | from typing import List, Type 2 | 3 | from project.animals.animal import Bird 4 | from project.food import Food, Meat, Vegetable, Fruit, Seed 5 | 6 | 7 | class Owl(Bird): 8 | 9 | @property 10 | def food_that_eats(self): 11 | return [Meat] 12 | 13 | @property 14 | def gained_weight(self) -> float: 15 | return 0.25 16 | 17 | @staticmethod 18 | def make_sound() -> str: 19 | return "Hoot Hoot" 20 | 21 | 22 | class Hen(Bird): 23 | 24 | @property 25 | def food_that_eats(self): 26 | return [Meat, Fruit, Vegetable, Seed] 27 | 28 | @property 29 | def gained_weight(self) -> float: 30 | return 0.35 31 | 32 | @staticmethod 33 | def make_sound() -> str: 34 | return "Cluck" 35 | 36 | -------------------------------------------------------------------------------- /03_Inheritance/05_Shop/project/product_repository.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from project.food import Food 3 | from project.drink import Drink 4 | 5 | 6 | class ProductRepository: 7 | 8 | def __init__(self): 9 | self.products: List[Food, Drink] = [] 10 | 11 | def add(self, product: Food or Drink) -> None: 12 | self.products.append(product) 13 | 14 | def find(self, product_name: str) -> Food or Drink: 15 | for product in self.products: 16 | if product.name == product_name: 17 | return product 18 | 19 | def remove(self, product_name: str) -> None: 20 | product = self.find(product_name) 21 | 22 | if product: 23 | self.products.remove(product) 24 | 25 | def __repr__(self): 26 | return "\n".join(f"{p.name}: {p.quantity}" for p in self.products) 27 | -------------------------------------------------------------------------------- /03_Inheritance/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /10_Unit_Testing/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/before/workers.py: -------------------------------------------------------------------------------- 1 | class Worker: 2 | 3 | def work(self): 4 | print("I'm working!!") 5 | 6 | 7 | class SuperWorker: 8 | 9 | def work(self): 10 | print("I work very hard!!!") 11 | 12 | 13 | class Manager: 14 | 15 | def __init__(self): 16 | self.worker = None 17 | 18 | def set_worker(self, worker): 19 | assert isinstance(worker, Worker), '`worker` must be of type {}'.format(Worker) 20 | 21 | self.worker = worker 22 | 23 | def manage(self): 24 | if self.worker is not None: 25 | self.worker.work() 26 | 27 | 28 | worker = Worker() 29 | manager = Manager() 30 | manager.set_worker(worker) 31 | manager.manage() 32 | 33 | super_worker = SuperWorker() 34 | try: 35 | manager.set_worker(super_worker) 36 | except AssertionError: 37 | print("manager fails to support super_worker....") 38 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 17 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/04_Gym/project/test.py: -------------------------------------------------------------------------------- 1 | from project.customer import Customer 2 | from project.equipment import Equipment 3 | from project.exercise_plan import ExercisePlan 4 | from project.gym import Gym 5 | from project.subscription import Subscription 6 | from project.trainer import Trainer 7 | 8 | 9 | customer = Customer("John", "Maple Street", "john.smith@gmail.com") 10 | customer1 = Customer("Pesho", "Maple Street", "john.smith@gmail.com") 11 | equipment = Equipment("Treadmill") 12 | trainer = Trainer("Peter") 13 | subscription = Subscription("14.05.2020", 1, 1, 1) 14 | plan = ExercisePlan(1, 1, 20) 15 | 16 | gym = Gym() 17 | 18 | gym.add_customer(customer) 19 | gym.add_equipment(equipment) 20 | gym.add_trainer(trainer) 21 | gym.add_plan(plan) 22 | gym.add_subscription(subscription) 23 | 24 | print(Customer.get_next_id()) 25 | 26 | print(gym.subscription_info(1)) 27 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/before/prisoner.py: -------------------------------------------------------------------------------- 1 | import copy 2 | 3 | class Person: 4 | 5 | def __init__(self, position): 6 | self.position = position 7 | 8 | def walk_north(self, dist): 9 | self.position[1] += dist 10 | 11 | def walk_east(self, dist): 12 | self.position[0] += dist 13 | 14 | 15 | class Prisoner(Person): 16 | PRISON_LOCATION = [3, 3] 17 | 18 | def __init__(self): 19 | super(Prisoner, self).__init__(copy.copy(self.PRISON_LOCATION)) 20 | self.is_free = False 21 | 22 | 23 | 24 | prisoner = Prisoner() 25 | print("The prisoner trying to walk to north by 10 and east by -3.") 26 | 27 | try: 28 | prisoner.walk_north(10) 29 | prisoner.walk_east(-3) 30 | except: 31 | pass 32 | 33 | print(f"The location of the prison: {prisoner.PRISON_LOCATION}") 34 | print(f"The current position of the prisoner: {prisoner.position}") 35 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/after/prisoner.py: -------------------------------------------------------------------------------- 1 | import copy 2 | 3 | 4 | class Person: 5 | 6 | def __init__(self, position): 7 | self.position = position # [row, col] 8 | 9 | 10 | class FreePerson(Person): 11 | def walk_north(self, dist): 12 | self.position[1] += dist 13 | 14 | def walk_east(self, dist): 15 | self.position[0] += dist 16 | 17 | 18 | class Prisoner(Person): 19 | PRISON_LOCATION = [3, 3] 20 | 21 | def __init__(self): 22 | super().__init__(copy.copy(self.PRISON_LOCATION)) 23 | self.is_free = False 24 | 25 | 26 | prisoner = Prisoner() 27 | print("The prisoner trying to walk to north by 10 and east by -3.") 28 | 29 | try: 30 | prisoner.walk_north(10) 31 | prisoner.walk_east(-3) 32 | except: 33 | pass 34 | 35 | print(f"The location of the prison: {prisoner.PRISON_LOCATION}") 36 | print(f"The current position of the prisoner: {prisoner.position}") 37 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/main.py: -------------------------------------------------------------------------------- 1 | class TupleIterator: 2 | def __next__(self): 3 | pass 4 | 5 | 6 | class MyList: 7 | 8 | def __init__(self, my_list: list): 9 | self.my_list = my_list 10 | self.index = -1 11 | 12 | def __iter__(self): 13 | return self 14 | 15 | def __next__(self): 16 | if self.index == len(self.my_list) - 1: 17 | raise StopIteration 18 | 19 | self.index += 1 20 | 21 | return self.my_list[self.index] 22 | 23 | 24 | # for loop in python 25 | 26 | iterator = MyList([1, 2, 3]).__iter__() 27 | 28 | while True: 29 | try: 30 | print(next(iterator)) 31 | except StopIteration: 32 | break 33 | 34 | 35 | def numbers_multiplied_by_two(numbers: list): 36 | for number in numbers: 37 | yield number * 2 38 | 39 | 40 | a = (number * 2 for number in [1, 2, 3]) 41 | print(next(a)) 42 | print(next(a)) -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/main.py: -------------------------------------------------------------------------------- 1 | class Person: 2 | min_age = 0 3 | max_age = 150 4 | 5 | def __init__(self, name, age): 6 | self.name = name 7 | self.age = age 8 | 9 | @classmethod 10 | def __validate_age(cls, value): 11 | raise ValueError(f'{value} must be between ' 12 | f'{cls.min_age} and {cls.max_age}') 13 | 14 | @property 15 | def age(self): 16 | return self.__age 17 | 18 | @age.setter 19 | def age(self, value): 20 | self.__validate_age(value) 21 | self.__age = value 22 | 23 | 24 | class Employee(Person): 25 | min_age = 16 26 | 27 | # __validate_age() takes the class attribute min_age of class Employee 28 | 29 | def __init__(self, name, age, salary): 30 | super().__init__(name, age) # when checking the age of the Employee 31 | self.salary = salary 32 | 33 | 34 | e = Employee('ifew', 23, 314) -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/custom_list.py: -------------------------------------------------------------------------------- 1 | class MyListIterator: 2 | def __init__(self, initial_elements: list): 3 | self.__initial_elements = initial_elements 4 | self.__index = 0 5 | 6 | def __next__(self): 7 | if self.__index >= len(self.__initial_elements): 8 | raise StopIteration 9 | 10 | value = self.__initial_elements[self.__index] 11 | self.__index += 1 12 | 13 | return value 14 | 15 | 16 | class MyList: 17 | 18 | def __init__(self, initial_elements=None): 19 | # could be a setter 20 | if not initial_elements: 21 | self.initial_elements = [] 22 | else: 23 | self.initial_elements = initial_elements 24 | 25 | def __iter__(self): 26 | return MyListIterator(self.initial_elements) 27 | 28 | 29 | my_list = MyList([1, 2, 3]) 30 | 31 | for el in my_list: 32 | print(el) 33 | 34 | for el in my_list: 35 | print(el) -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/02_Groups.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Person: 5 | 6 | def __init__(self, name: str, surname: str): 7 | self.name = name 8 | self.surname = surname 9 | 10 | def __repr__(self): 11 | return f"{self.name} {self.surname}" 12 | 13 | def __add__(self, other): 14 | return Person(self.name, other.surname) 15 | 16 | 17 | class Group: 18 | 19 | def __init__(self, name: str, people: List[Person]): 20 | self.name = name 21 | self.people = people 22 | 23 | def __len__(self): 24 | return len(self.people) 25 | 26 | def __add__(self, other): 27 | return Group(f"{self.name} {other.name}", self.people + other.people) 28 | 29 | def __repr__(self): 30 | return f"Group {self.name} with members {', '.join(str(p) for p in self.people)}" 31 | 32 | def __getitem__(self, idx: int): 33 | return f"Person {idx}: {str(self.people[idx])}" 34 | -------------------------------------------------------------------------------- /08_Iterators_And_Generators_Exercise/02_Dictionary_iterator.py: -------------------------------------------------------------------------------- 1 | class dictionary_iter: 2 | 3 | def __init__(self, dictionary: dict): # {1: "1", 2: "2"} 4 | self.items = list(dictionary.items()) # dictionary.items() => dict_items([(1, "1"), (2, "2")]) 5 | self.index: int = -1 6 | 7 | def __iter__(self): 8 | return self 9 | 10 | def __next__(self): 11 | if self.index >= len(self.items) - 1: 12 | raise StopIteration 13 | 14 | self.index += 1 15 | 16 | return self.items[self.index] # [(1, "1"), (2, "2")][0] => (1, "1") 17 | 18 | 19 | # not passing in judge but still correct 20 | class dictionary_iterator: 21 | def __init__(self, dictionary: dict): # {1: "1", 2: "2"} 22 | self.items = dictionary.items() # dictionary.items() => dict_items([(1, "1"), (2, "2")]) 23 | 24 | def __iter__(self): 25 | return iter(self.items) 26 | 27 | 28 | result = dictionary_iterator({1: "1", 2: "2"}) 29 | for x in result: 30 | print(x) 31 | -------------------------------------------------------------------------------- /03_Inheritance/OLD_TASK/Guild_System/project/player.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | 3 | 4 | class Player: 5 | DEFAULT_GUILD = "Unaffiliated" 6 | 7 | def __init__(self, name: str, hp: int, mp: int): 8 | self.name = name 9 | self.hp = hp 10 | self.mp = mp 11 | self.skills: Dict[str: int] = {} # {"flame": 120} 12 | self.guild: str = self.DEFAULT_GUILD 13 | 14 | def add_skill(self, skill_name: str, mana_cost: int) -> str: 15 | if self.skills.get(skill_name): 16 | return "Skill already added" 17 | 18 | self.skills[skill_name] = mana_cost 19 | 20 | return f"Skill {skill_name} added to the collection of the player {self.name}" 21 | 22 | def player_info(self) -> str: 23 | skills_string = "\n".join(f"==={name} - {mp}" for name, mp in self.skills.items()) 24 | return f"Name: {self.name}\n" \ 25 | f"Guild: {self.guild}\n" \ 26 | f"HP: {self.hp}\n" \ 27 | f"MP: {self.mp}\n" \ 28 | f"{skills_string}" 29 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/03_Integer.py: -------------------------------------------------------------------------------- 1 | class Integer: 2 | ROMAN = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000} 3 | 4 | def __init__(self, value: int): 5 | self.value = value 6 | 7 | @classmethod 8 | def from_float(cls, value: float): 9 | if not isinstance(value, float): 10 | return "value is not a float" 11 | 12 | return cls(int(value)) 13 | 14 | @classmethod 15 | def from_roman(cls, value: str): 16 | int_sum = 0 17 | 18 | for i in range(len(value)): 19 | if i != 0 and cls.ROMAN[value[i]] > cls.ROMAN[value[i - 1]]: 20 | int_sum += cls.ROMAN[value[i]] - 2 * cls.ROMAN[value[i - 1]] 21 | else: 22 | int_sum += cls.ROMAN[value[i]] 23 | 24 | return cls(int_sum) 25 | 26 | @classmethod 27 | def from_string(cls, value: str): 28 | if not isinstance(value, str): 29 | return "wrong type" 30 | 31 | return cls(int(value)) 32 | 33 | 34 | integer = Integer.from_roman("IV") 35 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/02_Movie_World/project/dvd.py: -------------------------------------------------------------------------------- 1 | import calendar 2 | 3 | 4 | class DVD: 5 | 6 | def __init__(self, name: str, _id: int, creation_year: int, creation_month: str, age_restriction: int): 7 | self.name = name 8 | self.id = _id 9 | self.creation_year = creation_year 10 | self.creation_month = creation_month 11 | self.age_restriction = age_restriction 12 | self.is_rented: bool = False 13 | 14 | @classmethod 15 | def from_date(cls, _id: int, name: str, date: str, age_restriction: int): 16 | day, month, year = [int(x) for x in date.split('.')] # 23.12.2003 17 | month_name = calendar.month_name[month] # 12 => December 18 | 19 | return cls(name, _id, year, month_name, age_restriction) 20 | 21 | def __repr__(self): 22 | return (f"{self.id}: {self.name} ({self.creation_month} {self.creation_year}) " 23 | f"has age restriction {self.age_restriction}. " 24 | f"Status: {'rented' if self.is_rented else 'not rented'}") 25 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/mammal/test/test_mammal.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | from project.mammal import Mammal 3 | 4 | 5 | class TestMammal(TestCase): 6 | 7 | def setUp(self): 8 | self.mammal = Mammal( 9 | "some name", 10 | "some type", 11 | "some sound", 12 | ) 13 | 14 | def test_correct_init_(self): 15 | self.assertEqual("some name", self.mammal.name) 16 | self.assertEqual("some type", self.mammal.type) 17 | self.assertEqual("some sound", self.mammal.sound) 18 | self.assertEqual("animals", self.mammal._Mammal__kingdom) 19 | 20 | def test_get_sound_returns_correct_string(self): 21 | self.assertEqual(f"some name makes some sound", self.mammal.make_sound()) 22 | 23 | def test_get_kingdom_returns_correct_string(self): 24 | self.assertEqual("animals", self.mammal.get_kingdom()) 25 | 26 | def test_get_info_returns_correct_string(self): 27 | self.assertEqual(f"some name is of type some type", self.mammal.info()) 28 | 29 | 30 | if __name__ == "__main__": 31 | main() 32 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/vehicle/project/vehicle.py: -------------------------------------------------------------------------------- 1 | from typing import ClassVar 2 | 3 | 4 | class Vehicle: 5 | DEFAULT_FUEL_CONSUMPTION: ClassVar[float] = 1.25 6 | fuel_consumption: float 7 | fuel: float 8 | capacity: float 9 | horse_power: float 10 | 11 | def __init__(self, fuel: float, horse_power: float): 12 | self.fuel = fuel 13 | self.capacity = self.fuel 14 | self.horse_power = horse_power 15 | self.fuel_consumption = self.DEFAULT_FUEL_CONSUMPTION 16 | 17 | def drive(self, kilometers): 18 | fuel_needed = self.fuel_consumption * kilometers 19 | 20 | if self.fuel < fuel_needed: 21 | raise Exception("Not enough fuel") 22 | 23 | self.fuel -= fuel_needed 24 | 25 | def refuel(self, fuel): 26 | if self.fuel + fuel > self.capacity: 27 | raise Exception("Too much fuel") 28 | 29 | self.fuel += fuel 30 | 31 | def __str__(self): 32 | return f"The vehicle has {self.horse_power} " \ 33 | f"horse power with {self.fuel} fuel left and {self.fuel_consumption} fuel consumption" 34 | -------------------------------------------------------------------------------- /11_Exam_Preparation/project/peaks/base_peak.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | from typing import List 3 | 4 | 5 | class BasePeak(ABC): 6 | 7 | def __init__(self, name: str, elevation: int): 8 | self.name = name 9 | self.elevation = elevation 10 | self.difficulty_level = self.calculate_difficulty_level() 11 | 12 | @property 13 | def name(self): 14 | return self.__name 15 | 16 | @name.setter 17 | def name(self, value): 18 | if len(value) < 2: 19 | raise ValueError("Peak name cannot be less than 2 symbols!") 20 | 21 | self.__name = value 22 | 23 | @property 24 | def elevation(self): 25 | return self.__elevation 26 | 27 | @elevation.setter 28 | def elevation(self, value): 29 | if value < 1500: 30 | raise ValueError("Peak elevation cannot be below 1500m.") 31 | 32 | self.__elevation = value 33 | 34 | @abstractmethod 35 | def get_recommended_gear(self) -> List[str]: 36 | pass 37 | 38 | @abstractmethod 39 | def calculate_difficulty_level(self) -> str: 40 | pass 41 | -------------------------------------------------------------------------------- /11_Exam_Preparation/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 24 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/03_Document/project/document.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | from project.category import Category 4 | from project.topic import Topic 5 | 6 | 7 | class Document: 8 | 9 | def __init__(self, _id: int, category_id: int, topic_id: int, file_name: str): 10 | self.id = _id 11 | self.category_id = category_id 12 | self.topic_id = topic_id 13 | self.file_name = file_name 14 | self.tags: List[str] = [] 15 | 16 | @classmethod 17 | def from_instances(cls, _id: int, category: Category, topic: Topic, file_name: str): 18 | return cls(_id, category.id, topic.id, file_name) 19 | 20 | def add_tag(self, tag: str) -> None: 21 | if tag not in self.tags: 22 | self.tags.append(tag) 23 | 24 | def remove_tag(self, tag: str) -> None: 25 | if tag in self.tags: 26 | self.tags.remove(tag) 27 | 28 | def edit(self, new_file_name: str) -> None: 29 | self.file_name = new_file_name 30 | 31 | def __repr__(self): 32 | return (f"Document {self.id}: {self.file_name}; " 33 | f"category {self.category_id}, topic {self.topic_id}, " 34 | f"tags: {', '.join(self.tags)}") 35 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/after/workers.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class BaseWorker(ABC): 5 | 6 | @staticmethod 7 | @abstractmethod 8 | def work() -> None: 9 | ... 10 | 11 | 12 | class Worker(BaseWorker): 13 | 14 | def work(self): 15 | print("I'm working!!") 16 | 17 | 18 | class SuperWorker(BaseWorker): 19 | 20 | def work(self): 21 | print("I work very hard!!!") 22 | 23 | 24 | class UltimateWorker(BaseWorker): 25 | 26 | def work(self): 27 | print("I work very very veryyyy hard!!!") 28 | 29 | 30 | class Manager: 31 | 32 | def __init__(self): 33 | self.worker = None 34 | 35 | def set_worker(self, worker): 36 | assert isinstance(worker, BaseWorker), f'`worker` must be of type {Worker}' 37 | 38 | self.worker = worker 39 | 40 | def manage(self): 41 | if self.worker is not None: 42 | self.worker.work() 43 | 44 | 45 | worker = Worker() 46 | manager = Manager() 47 | manager.set_worker(worker) 48 | manager.manage() 49 | 50 | super_worker = SuperWorker() 51 | try: 52 | manager.set_worker(super_worker) 53 | manager.manage() 54 | except AssertionError: 55 | print("manager fails to support super_worker....") 56 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/07_Spoopify/project/band.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from project.album import Album 3 | from project.song import Song 4 | 5 | 6 | class Band: 7 | 8 | def __init__(self, name: str): 9 | self.name = name 10 | self.albums: List[Album] = [] 11 | 12 | def add_album(self, album: Album) -> str: 13 | if album in self.albums: 14 | return f"Band {self.name} already has {album.name} in their library." 15 | 16 | self.albums.append(album) 17 | 18 | return f"Band {self.name} has added their newest album {album.name}." 19 | 20 | def remove_album(self, album_name: str) -> str: 21 | try: 22 | album = next(filter(lambda a: a.name == album_name, self.albums)) 23 | except StopIteration: 24 | return f"Album {album_name} is not found." 25 | 26 | if album.published: 27 | return "Album has been published. It cannot be removed." 28 | 29 | self.albums.remove(album) 30 | 31 | return f"Album {album_name} has been removed." 32 | 33 | def details(self) -> str: 34 | albums_details = "\n".join(a.details() for a in self.albums) 35 | return f"Band {self.name}\n" \ 36 | f"{albums_details}" 37 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/02_Time.py: -------------------------------------------------------------------------------- 1 | class Time: 2 | max_hours: int = 23 # UpperCase but lower case for judge 3 | max_minutes: int = 59 4 | max_seconds: int = 59 5 | 6 | def __init__(self, hours: int, minutes: int, seconds: int): 7 | self.hours = hours 8 | self.minutes = minutes 9 | self.seconds = seconds 10 | 11 | def set_time(self, hours: int, minutes: int, seconds: int) -> None: 12 | self.hours = hours 13 | self.minutes = minutes 14 | self.seconds = seconds 15 | 16 | def get_time(self) -> str: 17 | return f"{self.hours:02d}:{self.minutes:02d}:{self.seconds:02d}" 18 | 19 | def next_second(self) -> str: 20 | self.seconds += 1 21 | 22 | self.update_valid_time() 23 | 24 | return self.get_time() 25 | 26 | def update_valid_time(self) -> None: 27 | if self.seconds > Time.max_seconds: 28 | self.seconds = 0 29 | self.minutes += 1 30 | 31 | if self.minutes > Time.max_minutes: 32 | self.minutes = 0 33 | self.hours += 1 34 | 35 | if self.hours > Time.max_hours: 36 | self.hours = 0 37 | 38 | 39 | time = Time(23, 59, 59) 40 | print(time.next_second()) 41 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/06_SteamUser.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class SteamUser: 5 | def __init__(self, username: str, games: List[str]): 6 | self.username = username 7 | self.games = games 8 | self.played_hours: int = 0 9 | 10 | def play(self, game_name: str, hours: int) -> str: 11 | if game_name not in self.games: 12 | return f"{game_name} is not in library" 13 | 14 | self.played_hours += hours 15 | 16 | return f"{self.username} is playing {game_name}" 17 | 18 | def buy_game(self, game_name: str) -> str: 19 | if game_name in self.games: 20 | return f"{game_name} is already in your library" 21 | 22 | self.games.append(game_name) 23 | 24 | return f"{self.username} bought {game_name}" 25 | 26 | def status(self) -> str: 27 | return f"{self.username} has {len(self.games)} games. Total play time: {self.played_hours}" 28 | 29 | 30 | user = SteamUser("Peter", ["Rainbow Six Siege", "CS:GO", "Fortnite"]) 31 | print(user.play("Fortnite", 3)) 32 | print(user.play("Oxygen Not Included", 5)) 33 | print(user.buy_game("CS:GO")) 34 | print(user.buy_game("Oxygen Not Included")) 35 | print(user.play("Oxygen Not Included", 6)) 36 | print(user.status()) 37 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/05_Task/project/task.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Task: 5 | 6 | def __init__(self, name: str, due_date: str): 7 | self.name = name 8 | self.due_date = due_date 9 | self.comments: List[str] = [] 10 | self.completed = False 11 | 12 | def change_name(self, new_name: str) -> str: 13 | if self.name == new_name: 14 | return "Name cannot be the same." 15 | 16 | self.name = new_name 17 | 18 | return self.name 19 | 20 | def change_due_date(self, new_due_date: str) -> str: 21 | if self.due_date == new_due_date: 22 | return "Date cannot be the same." 23 | 24 | self.due_date = new_due_date 25 | 26 | return self.due_date 27 | 28 | def add_comment(self, comment: str) -> None: 29 | self.comments.append(comment) 30 | 31 | def edit_comment(self, comment_idx: int, new_comment: str) -> str: 32 | if not 0 <= comment_idx < len(self.comments): 33 | return "Cannot find comment." 34 | 35 | self.comments[comment_idx] = new_comment 36 | 37 | return ", ".join(self.comments) 38 | 39 | def details(self) -> str: 40 | return f"Name: {self.name} - Due Date: {self.due_date}" 41 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/01_Vehicle_Extra_Not_For_Judge.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class Vehicle(ABC): # Abstract Base Class 5 | def __init__(self, fuel_quantity: float, fuel_consumption: float): 6 | self.fuel_quantity = fuel_quantity 7 | self.fuel_consumption = fuel_consumption 8 | 9 | @property 10 | @abstractmethod 11 | def conditioner_on(self) -> float: 12 | ... 13 | 14 | def drive(self, distance: float) -> None: 15 | consumption = (self.conditioner_on + self.fuel_consumption) * distance 16 | 17 | if self.fuel_quantity >= consumption: 18 | self.fuel_quantity -= consumption 19 | 20 | @abstractmethod 21 | def refuel(self, fuel: float) -> None: 22 | pass 23 | 24 | 25 | class Car(Vehicle): 26 | 27 | @property 28 | def conditioner_on(self) -> float: 29 | return 0.9 30 | 31 | def refuel(self, fuel: float) -> None: 32 | self.fuel_quantity += fuel 33 | 34 | 35 | class Truck(Vehicle): 36 | TANK_PERCENTAGE_FILL: float = 0.95 37 | 38 | @property 39 | def conditioner_on(self) -> float: 40 | return 1.6 41 | 42 | def refuel(self, fuel: float) -> None: 43 | self.fuel_quantity += fuel * self.TANK_PERCENTAGE_FILL 44 | -------------------------------------------------------------------------------- /03_Inheritance/OLD_TASK/Guild_System/project/guild.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from project.player import Player 3 | 4 | 5 | class Guild: 6 | 7 | def __init__(self, name: str): 8 | self.name = name 9 | self.players: List[Player] = [] 10 | 11 | def assign_player(self, player: Player) -> str: 12 | if self.name == player.guild: 13 | return f"Player {player.name} is already in the guild." 14 | 15 | if player.guild != player.DEFAULT_GUILD: 16 | return f"Player {player.name} is in another guild." 17 | 18 | player.guild = self.name 19 | self.players.append(player) 20 | 21 | return f"Welcome player {player.name} to the guild {self.name}" 22 | 23 | def kick_player(self, player_name: str) -> str: 24 | try: 25 | player = next(filter(lambda p: p.name == player_name, self.players)) 26 | except StopIteration: 27 | return f"Player {player_name} is not in the guild." 28 | 29 | player.guild = player.DEFAULT_GUILD 30 | self.players.remove(player) 31 | 32 | return f"Player {player_name} has been removed from the guild." 33 | 34 | def guild_info(self) -> str: 35 | players_info = '\n'.join(p.player_info() for p in self.players) 36 | return f"Guild: {self.name}\n" \ 37 | f"{players_info}" 38 | 39 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/student/project/student.py: -------------------------------------------------------------------------------- 1 | class Student: 2 | def __init__(self, name: str, courses=None): 3 | if courses is None: 4 | courses = {} 5 | 6 | self.name = name 7 | self.courses = courses # {course_name: [notes]} 8 | 9 | def enroll(self, course_name: str, notes: list, add_course_notes: str = ""): 10 | if course_name in self.courses.keys(): 11 | [self.courses[course_name].append(x) for x in notes] 12 | return "Course already added. Notes have been updated." 13 | 14 | if add_course_notes == "Y" or add_course_notes == "": 15 | self.courses[course_name] = notes 16 | return "Course and course notes have been added." 17 | 18 | self.courses[course_name] = [] 19 | return "Course has been added." 20 | 21 | def add_notes(self, course_name, notes): 22 | if course_name in self.courses.keys(): 23 | self.courses[course_name].append(notes) 24 | return "Notes have been updated" 25 | 26 | raise Exception("Cannot add notes. Course not found.") 27 | 28 | def leave_course(self, course_name): 29 | if course_name in self.courses.keys(): 30 | self.courses.pop(course_name) 31 | return "Course has been removed" 32 | 33 | raise Exception("Cannot remove course. Course not found.") 34 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/04_Wild_Farm/project/animals/mammals.py: -------------------------------------------------------------------------------- 1 | from project.animals.animal import Mammal 2 | from project.food import Meat, Fruit, Vegetable, Seed 3 | 4 | 5 | class Mouse(Mammal): 6 | 7 | @property 8 | def food_that_eats(self): 9 | return [Fruit, Vegetable] 10 | 11 | @property 12 | def gained_weight(self) -> float: 13 | return 0.10 14 | 15 | @staticmethod 16 | def make_sound() -> str: 17 | return "Squeak" 18 | 19 | 20 | class Dog(Mammal): 21 | 22 | @property 23 | def food_that_eats(self): 24 | return [Meat] 25 | 26 | @property 27 | def gained_weight(self) -> float: 28 | return 0.40 29 | 30 | @staticmethod 31 | def make_sound() -> str: 32 | return "Woof!" 33 | 34 | 35 | class Cat(Mammal): 36 | 37 | @property 38 | def food_that_eats(self): 39 | return [Meat, Vegetable] 40 | 41 | @property 42 | def gained_weight(self) -> float: 43 | return 0.30 44 | 45 | @staticmethod 46 | def make_sound() -> str: 47 | return "Meow" 48 | 49 | 50 | class Tiger(Mammal): 51 | 52 | @property 53 | def food_that_eats(self): 54 | return [Meat] 55 | 56 | @property 57 | def gained_weight(self) -> float: 58 | return 1.00 59 | 60 | @staticmethod 61 | def make_sound() -> str: 62 | return "ROAR!!!" 63 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/01_Vehicle.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class Vehicle(ABC): # Abstract Base Class 5 | 6 | def __init__(self, fuel_quantity: float, fuel_consumption: float): 7 | self.fuel_quantity = fuel_quantity 8 | self.fuel_consumption = fuel_consumption 9 | 10 | @abstractmethod 11 | def drive(self, distance: float) -> None: 12 | ... 13 | 14 | @abstractmethod 15 | def refuel(self, fuel: float) -> None: 16 | pass 17 | 18 | 19 | class Car(Vehicle): 20 | CONDITIONER_ON: float = 0.9 21 | 22 | def drive(self, distance: float) -> None: 23 | consumption = (self.CONDITIONER_ON + self.fuel_consumption) * distance 24 | 25 | if self.fuel_quantity >= consumption: 26 | self.fuel_quantity -= consumption 27 | 28 | def refuel(self, fuel: float) -> None: 29 | self.fuel_quantity += fuel 30 | 31 | 32 | class Truck(Vehicle): 33 | CONDITIONER_ON: float = 1.6 34 | TANK_PERCENTAGE_FILL: float = 0.95 35 | 36 | def drive(self, distance: float) -> None: 37 | consumption = (self.CONDITIONER_ON + self.fuel_consumption) * distance 38 | 39 | if self.fuel_quantity >= consumption: 40 | self.fuel_quantity -= consumption 41 | 42 | def refuel(self, fuel: float) -> None: 43 | self.fuel_quantity += fuel * self.TANK_PERCENTAGE_FILL 44 | 45 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/08_Execution_Time.py: -------------------------------------------------------------------------------- 1 | from time import time 2 | 3 | # with stop 4 | # def exec_time(func): 5 | # def wrapper(*args, **kwargs): 6 | # start = time() # gets the current time 7 | # func(*args, start_time=start, threshold=2, **kwargs) 8 | # end = time() # gets the current time 9 | # 10 | # return end - start 11 | # 12 | # return wrapper 13 | # 14 | # 15 | # @exec_time 16 | # def loop(start, end, start_time, threshold): 17 | # total = 0 18 | # 19 | # for x in range(start, end): 20 | # if time() - start_time > threshold: 21 | # print("function terminated") 22 | # return 23 | # 24 | # total += x 25 | # 26 | # return total 27 | 28 | 29 | def exec_time(func): 30 | def wrapper(*args, **kwargs): 31 | start = time() # gets the current time 32 | func(*args, **kwargs) 33 | end = time() # gets the current time 34 | 35 | return end - start 36 | 37 | return wrapper 38 | 39 | 40 | @exec_time 41 | def loop(start, end): 42 | total = 0 43 | 44 | for x in range(start, end): 45 | total += x 46 | 47 | return total 48 | 49 | 50 | @exec_time 51 | def concatenate(strings): 52 | result = "" 53 | 54 | for string in strings: 55 | result += string 56 | 57 | return result 58 | 59 | 60 | print(concatenate(["a" for i in range(100_000_000)])) 61 | 62 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/06_Formula_1_Team/project/formula_teams/formula_team.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | from typing import Dict 3 | 4 | 5 | class FormulaTeam(ABC): 6 | MIN_BUDGET: int = 1_000_000 7 | 8 | def __init__(self, budget: int): 9 | self.budget = budget 10 | 11 | @property 12 | @abstractmethod 13 | def sponsors(self): 14 | ... 15 | 16 | @property 17 | @abstractmethod 18 | def expenses_for_one_race(self) -> int: 19 | ... 20 | 21 | @property 22 | def budget(self): 23 | return self.__budget 24 | 25 | @budget.setter 26 | def budget(self, value): 27 | if value < FormulaTeam.MIN_BUDGET: 28 | raise ValueError("F1 is an expensive sport, find more sponsors!") 29 | 30 | self.__budget = value 31 | 32 | def calculate_revenue_after_race(self, race_pos: int): 33 | revenue: int = 0 34 | 35 | for sponsor in self.sponsors.values(): # [{1: 1_500_000, 2: 800_000}, {8: 20_000, 10: 10_000}] 36 | for pos in sponsor: # {1: 1_500_000, 2: 800_000} - should be sorted 37 | if race_pos <= pos: 38 | revenue += sponsor[pos] 39 | break 40 | 41 | revenue -= self.expenses_for_one_race 42 | self.budget += revenue 43 | 44 | return f"The revenue after the race is {revenue}$. Current budget {self.budget}$" 45 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/07_Programmer.py: -------------------------------------------------------------------------------- 1 | class Programmer: 2 | def __init__(self, name: str, language: str, skills: int): 3 | self.name = name 4 | self.language = language 5 | self.skills = skills 6 | 7 | def watch_course(self, course_name: str, language: str, skills_earned: int) -> str: 8 | if self.language != language: 9 | return f"{self.name} does not know {language}" 10 | 11 | self.skills += skills_earned 12 | 13 | return f"{self.name} watched {course_name}" 14 | 15 | def change_language(self, new_language: str, skills_needed: int) -> str: 16 | if self.skills >= skills_needed: 17 | if self.language != new_language: 18 | previous_language = self.language 19 | self.language = new_language 20 | 21 | return f"{self.name} switched from {previous_language} to {new_language}" 22 | 23 | return f"{self.name} already knows {self.language}" 24 | 25 | return f"{self.name} needs {skills_needed - self.skills} more skills" 26 | 27 | programmer = Programmer("John", "Java", 50) 28 | print(programmer.watch_course("Python Masterclass", "Python", 84)) 29 | print(programmer.change_language("Java", 30)) 30 | print(programmer.change_language("Python", 100)) 31 | print(programmer.watch_course("Java: zero to hero", "Java", 50)) 32 | print(programmer.change_language("Python", 100)) 33 | print(programmer.watch_course("Python Masterclass", "Python", 84)) 34 | -------------------------------------------------------------------------------- /10_Unit_Testing/Third_List/extended_list.py: -------------------------------------------------------------------------------- 1 | class IntegerList: 2 | def __init__(self, *args): 3 | self.__data = [] 4 | for x in args: 5 | if type(x) == int: 6 | self.__data.append(x) 7 | 8 | def get_data(self): 9 | return self.__data 10 | 11 | def add(self, element): 12 | if not type(element) == int: 13 | raise ValueError("Element is not Integer") 14 | 15 | self.get_data().append(element) 16 | 17 | return self.get_data() 18 | 19 | def remove_index(self, index): 20 | if index >= len(self.get_data()): 21 | raise IndexError("Index is out of range") 22 | 23 | a = self.get_data()[index] 24 | del self.get_data()[index] 25 | 26 | return a 27 | 28 | def get(self, index): 29 | if index >= len(self.get_data()): 30 | raise IndexError("Index is out of range") 31 | 32 | return self.get_data()[index] 33 | 34 | def insert(self, index, el): 35 | if index >= len(self.get_data()): 36 | raise IndexError("Index is out of range") 37 | elif not type(el) == int: 38 | raise ValueError("Element is not Integer") 39 | 40 | self.get_data().insert(index, el) 41 | 42 | def get_biggest(self): 43 | a = sorted(self.get_data(), reverse=True) 44 | return a[0] 45 | 46 | def get_index(self, el): 47 | return self.get_data().index(el) -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/04_HotelRoom/project/hotel.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from project.room import Room 3 | 4 | 5 | class Hotel: 6 | 7 | def __init__(self, name: str): 8 | self.name = name 9 | self.guests: int = 0 10 | self.rooms: List[Room] = [] 11 | 12 | @classmethod 13 | def from_stars(cls, stars_count: int): 14 | return cls(f"{stars_count} stars Hotel") 15 | 16 | def add_room(self, room: Room) -> None: 17 | self.rooms.append(room) 18 | 19 | def take_room(self, room_number: int, people: int) -> None: 20 | try: 21 | room = next(filter(lambda r: r.number == room_number, self.rooms)) 22 | except StopIteration: 23 | return 24 | 25 | result = room.take_room(people) 26 | 27 | if not result: 28 | self.guests += people 29 | 30 | def free_room(self, room_number) -> None: 31 | try: 32 | room = next(filter(lambda r: r.number == room_number, self.rooms)) 33 | except StopIteration: 34 | return 35 | 36 | people = room.guests 37 | result = room.free_room() 38 | 39 | if not result: 40 | self.guests -= people 41 | 42 | def status(self) -> str: 43 | return f"Hotel {self.name} has {self.guests} total guests\n" \ 44 | f"Free rooms: {', '.join(str(r.number) for r in self.rooms if not r.is_taken)}\n" \ 45 | f"Taken rooms: {', '.join(str(r.number) for r in self.rooms if r.is_taken)}" 46 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/08_Library/project/registration.py: -------------------------------------------------------------------------------- 1 | from project.library import Library 2 | from project.user import User 3 | 4 | 5 | class Registration: 6 | 7 | def add_user(self, user: User, library: Library) -> str or None: 8 | if user in library.user_records: 9 | return f"User with id = {user.user_id} already registered in the library!" 10 | 11 | library.user_records.append(user) 12 | 13 | def remove_user(self, user: User, library: Library) -> str or None: 14 | if user not in library.user_records: 15 | return "We could not find such user to remove!" 16 | 17 | try: 18 | del library.rented_books[user.username] 19 | except KeyError: 20 | pass 21 | 22 | library.user_records.remove(user) 23 | 24 | def change_username(self, user_id: int, new_username: str, library: Library) -> str: 25 | try: 26 | user = next(filter(lambda u: u.user_id == user_id, library.user_records)) 27 | except StopIteration: 28 | return f"There is no user with id = {user_id}!" 29 | 30 | if user.username == new_username: 31 | return "Please check again the provided username - it should be different than the username used so far!" 32 | 33 | try: 34 | library.rented_books[new_username] = library.rented_books.pop(user.username) 35 | except KeyError: 36 | pass 37 | 38 | user.username = new_username 39 | 40 | return f"Username successfully changed to: {new_username} for user id: {user_id}" 41 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/07_Store_Results.py: -------------------------------------------------------------------------------- 1 | def store_results(func): # that's our decorator 2 | _FILE_NAME = "files/log.txt" 3 | 4 | def wrapper(*args, **kwargs): 5 | with open(_FILE_NAME, "a") as log_file: 6 | log_file.write( 7 | f"Function {func.__name__} was called. Result: {func(*args, **kwargs)}\n" 8 | ) 9 | 10 | return wrapper 11 | 12 | 13 | class store_result: 14 | _FILE_NAME = "files/log.txt" 15 | 16 | def __init__(self, func): # that's our decorator 17 | self.func = func 18 | 19 | def __call__(self, *args, **kwargs): # the same as wrapper 20 | with open(self._FILE_NAME, "a") as log_file: 21 | log_file.write( 22 | f"Function {self.func.__name__} was called. Result: {self.func(*args, **kwargs)}\n" 23 | ) 24 | 25 | 26 | # with param not defined by task 27 | class store_result_in_file_name(): 28 | _DIR = "files" 29 | 30 | def __init__(self, file_name: str): # here goes the param 31 | self.file_name = file_name 32 | 33 | def __call__(self, func): # this is out decorator 34 | def wrapper(*args, **kwargs): 35 | with open(f"{self._DIR}/{self.file_name}", "a") as log_file: 36 | log_file.write( 37 | f"Function {func.__name__} was called. Result: {func(*args, **kwargs)}\n" 38 | ) 39 | 40 | return wrapper 41 | 42 | 43 | @store_result_in_file_name("result.txt") 44 | def sum_numbers(a: int, b: int): 45 | return a + b 46 | 47 | 48 | sum_numbers(6, 9) 49 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/01_Vet.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Vet: 5 | animals: List[str] = [] 6 | space: int = 5 # SPACE: int = 5 7 | 8 | def __init__(self, vet_name: str): 9 | self.name = vet_name 10 | self.animals: List[str] = [] 11 | 12 | def register_animal(self, animal_name: str) -> str: 13 | if len(Vet.animals) == Vet.space: 14 | return "Not enough space" 15 | 16 | self.animals.append(animal_name) 17 | Vet.animals.append(animal_name) 18 | 19 | return f"{animal_name} registered in the clinic" 20 | 21 | def unregister_animal(self, animal_name: str) -> str: 22 | if animal_name not in self.animals: 23 | return f"{animal_name} not in the clinic" 24 | 25 | self.animals.remove(animal_name) 26 | Vet.animals.remove(animal_name) 27 | 28 | return f"{animal_name} unregistered successfully" 29 | 30 | def info(self) -> str: 31 | return f"{self.name} has {len(self.animals)} animals. {Vet.space - len(Vet.animals)} space left in clinic" 32 | 33 | 34 | peter = Vet("Peter") 35 | george = Vet("George") 36 | print(peter.register_animal("Tom")) 37 | print(peter.register_animal("Toma")) 38 | print(george.register_animal("Cory")) 39 | print(peter.register_animal("Fishy")) 40 | print(peter.register_animal("Bobby")) 41 | print(george.register_animal("Kay")) 42 | print(george.unregister_animal("Cory")) 43 | print(peter.register_animal("Silky")) 44 | print(peter.unregister_animal("Molly")) 45 | print(peter.unregister_animal("Tom")) 46 | print(peter.info()) 47 | print(george.info()) 48 | -------------------------------------------------------------------------------- /10_Unit_Testing/Second_Test_Cat/test_cat.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | from Second_Test_Cat.cat import Cat 3 | 4 | 5 | class TestCat(TestCase): 6 | 7 | def setUp(self): 8 | self.cat = Cat("Pancho") 9 | 10 | def test_correct_init(self): 11 | self.assertEqual("Pancho", self.cat.name) 12 | self.assertFalse(self.cat.fed) 13 | self.assertFalse(self.cat.sleepy) 14 | self.assertEqual(0, self.cat.size) 15 | 16 | def test_feed_cat_makes_cat_sleepy_and_not_hungry_expect_size_increase_by_1(self): 17 | expected_size = self.cat.size + 1 18 | 19 | self.cat.eat() 20 | 21 | self.assertTrue(self.cat.fed) 22 | self.assertTrue(self.cat.sleepy) 23 | self.assertEqual(expected_size, self.cat.size) 24 | 25 | def test_feed_cat_when_cat_is_already_fed_raise_exception(self): 26 | self.cat.fed = True 27 | 28 | with self.assertRaises(Exception) as ex: 29 | self.cat.eat() 30 | 31 | self.assertEqual('Already fed.', str(ex.exception)) 32 | 33 | def test_sleepy_cat_sleeps_and_its_not_sleepy_after_that(self): 34 | self.cat.sleepy = True 35 | self.cat.fed = True 36 | 37 | self.cat.sleep() 38 | 39 | self.assertFalse(self.cat.sleepy) 40 | 41 | def test_make_hungry_cat_sleep_raises_exception(self): 42 | self.cat.fed = False 43 | 44 | with self.assertRaises(Exception) as ex: 45 | self.cat.sleep() 46 | 47 | self.assertEqual('Cannot sleep while hungry', str(ex.exception)) 48 | 49 | 50 | if __name__ == "__main__": 51 | main() 52 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/hero/project/hero.py: -------------------------------------------------------------------------------- 1 | class Hero: 2 | username: str 3 | health: float 4 | damage: float 5 | level: int 6 | 7 | def __init__(self, username: str, level: int, health: float, damage: float): 8 | self.username = username 9 | self.level = level 10 | self.health = health 11 | self.damage = damage 12 | 13 | def battle(self, enemy_hero): 14 | if enemy_hero.username == self.username: 15 | raise Exception("You cannot fight yourself") 16 | 17 | if self.health <= 0: 18 | raise ValueError("Your health is lower than or equal to 0. You need to rest") 19 | 20 | if enemy_hero.health <= 0: 21 | raise ValueError(f"You cannot fight {enemy_hero.username}. He needs to rest") 22 | 23 | player_damage = self.damage * self.level 24 | enemy_hero_damage = enemy_hero.damage * enemy_hero.level 25 | 26 | self.health -= enemy_hero_damage 27 | enemy_hero.health -= player_damage 28 | 29 | if self.health <= 0 and enemy_hero.health <= 0: 30 | return "Draw" 31 | 32 | if enemy_hero.health <= 0: 33 | self.level += 1 34 | self.health += 5 35 | self.damage += 5 36 | return "You win" 37 | 38 | enemy_hero.level += 1 39 | enemy_hero.health += 5 40 | enemy_hero.damage += 5 41 | return "You lose" 42 | 43 | def __str__(self): 44 | return f"Hero {self.username}: {self.level} lvl\n" \ 45 | f"Health: {self.health}\n" \ 46 | f"Damage: {self.damage}\n" 47 | -------------------------------------------------------------------------------- /11_Exam_Preparation/project/climbers/base_climber.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | from project.peaks.base_peak import BasePeak 3 | from typing import List 4 | 5 | 6 | class BaseClimber(ABC): 7 | STRENGTH_INCREASE: int = 15 8 | 9 | def __init__(self, name: str, strength: float): 10 | self.name = name 11 | self.strength = strength 12 | self.conquered_peaks: List[str] = [] 13 | self.is_prepared = True 14 | 15 | @property 16 | def name(self): 17 | return self.__name 18 | 19 | @name.setter 20 | def name(self, value): 21 | if not value.strip(): 22 | raise ValueError("Climber name cannot be null or empty!") 23 | 24 | self.__name = value 25 | 26 | @property 27 | def strength(self): 28 | return self.__strength 29 | 30 | @strength.setter 31 | def strength(self, value): 32 | if value <= 0: 33 | raise ValueError("A climber cannot have negative strength or strength equal to 0!") 34 | 35 | self.__strength = value 36 | 37 | @abstractmethod 38 | def can_climb(self) -> bool: 39 | pass 40 | 41 | @abstractmethod 42 | def climb(self, peak: BasePeak) -> None: 43 | pass 44 | 45 | def rest(self) -> None: 46 | self.strength += BaseClimber.STRENGTH_INCREASE 47 | 48 | def __str__(self): 49 | return (f"{self.__class__.__name__}: " 50 | f"/// Climber name: {self.name} * " 51 | f"Left strength: {float(self.strength)} * " 52 | f"Conquered peaks: {', '.join(sorted(self.conquered_peaks))} ///") 53 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/01_Photo_Album.py: -------------------------------------------------------------------------------- 1 | from math import ceil 2 | from typing import List 3 | 4 | 5 | class PhotoAlbum: 6 | PHOTOS_PER_PAGE: int = 4 7 | DASHES_COUNT: int = 11 8 | SYMBOL_FOR_LINE: str = '-' 9 | 10 | def __init__(self, pages: int): 11 | self.pages = pages 12 | self.photos: List[List[str]] = [[] for _ in range(self.pages)] 13 | 14 | @classmethod 15 | def from_photos_count(cls, photos_count: int): 16 | return cls(ceil(photos_count / cls.PHOTOS_PER_PAGE)) 17 | 18 | def add_photo(self, label: str) -> str: 19 | for page in range(self.pages): 20 | if len(self.photos[page]) < self.PHOTOS_PER_PAGE: 21 | slot = len(self.photos[page]) + 1 22 | self.photos[page].append(label) 23 | 24 | return f"{label} photo added successfully on page {page + 1} slot {slot}" 25 | 26 | return "No more free slots" 27 | 28 | def display(self) -> str: 29 | result = [ 30 | self.DASHES_COUNT * self.SYMBOL_FOR_LINE, 31 | ] 32 | 33 | for page in self.photos: 34 | result.append(("[] " * len(page)).rstrip()) 35 | result.append(self.DASHES_COUNT * self.SYMBOL_FOR_LINE) 36 | 37 | return "\n".join(result) 38 | 39 | 40 | album = PhotoAlbum(2) 41 | 42 | print(album.add_photo("baby")) 43 | print(album.add_photo("first grade")) 44 | print(album.add_photo("eight grade")) 45 | print(album.add_photo("party with friends")) 46 | print(album.photos) 47 | print(album.add_photo("prom")) 48 | print(album.add_photo("wedding")) 49 | 50 | print(album.display()) 51 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/after/shapes.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class Shape(ABC): 5 | 6 | @abstractmethod 7 | def calculate_area(self): 8 | ... 9 | 10 | 11 | class Rectangle(Shape): 12 | 13 | def __init__(self, width, height): 14 | self.width = width 15 | self.height = height 16 | 17 | def calculate_area(self): 18 | return self.width * self.height 19 | 20 | 21 | class Triangle(Shape): 22 | 23 | def __init__(self, base: int, height: int): 24 | self.base = base 25 | self.height = height 26 | 27 | def calculate_area(self): 28 | return self.base * self.height / 2 29 | 30 | 31 | class Square(Shape): 32 | 33 | def __init__(self, side: int): 34 | self.side = side 35 | 36 | def calculate_area(self): 37 | return self.side * self.side 38 | 39 | 40 | class AreaCalculator: 41 | 42 | def __init__(self, shapes: list): 43 | self.shapes = shapes 44 | 45 | @property 46 | def shapes(self): 47 | return self.__shapes 48 | 49 | @shapes.setter 50 | def shapes(self, value): 51 | if not isinstance(value, list): 52 | raise AssertionError("Must be a list!") 53 | 54 | self.__shapes = value 55 | 56 | @property 57 | def total_area(self): 58 | total = 0 59 | 60 | for shape in self.shapes: 61 | total += shape.calculate_area() 62 | 63 | return total 64 | 65 | 66 | shapes = [Rectangle(2, 3), Rectangle(1, 6), Triangle(1, 12), Square(3)] 67 | calculator = AreaCalculator(shapes) 68 | print("The total area is:", calculator.total_area) 69 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/before/workers_updated.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | import time 3 | 4 | class AbstractWorker: 5 | __metaclass__ = ABCMeta 6 | 7 | @abstractmethod 8 | def work(self): 9 | pass 10 | 11 | @abstractmethod 12 | def eat(self): 13 | pass 14 | 15 | class Worker(AbstractWorker): 16 | 17 | def work(self): 18 | print("I'm normal worker. I'm working.") 19 | 20 | def eat(self): 21 | print("Lunch break....(5 secs)") 22 | time.sleep(5) 23 | 24 | class SuperWorker(AbstractWorker): 25 | 26 | def work(self): 27 | print("I'm super worker. I work very hard!") 28 | 29 | def eat(self): 30 | print("Lunch break....(3 secs)") 31 | time.sleep(3) 32 | 33 | 34 | class Manager: 35 | 36 | def __init__(self): 37 | self.worker = None 38 | 39 | def set_worker(self, worker): 40 | assert isinstance(worker, AbstractWorker), "`worker` must be of type {}".format(AbstractWorker) 41 | 42 | self.worker = worker 43 | 44 | def manage(self): 45 | self.worker.work() 46 | 47 | def lunch_break(self): 48 | self.worker.eat() 49 | 50 | class Robot(AbstractWorker): 51 | 52 | def work(self): 53 | print("I'm a robot. I'm working....") 54 | 55 | def eat(self): 56 | print("I don't need to eat....") 57 | 58 | 59 | manager = Manager() 60 | manager.set_worker(Worker()) 61 | manager.manage() 62 | manager.lunch_break() 63 | 64 | manager.set_worker(SuperWorker()) 65 | manager.manage() 66 | manager.lunch_break() 67 | 68 | manager.set_worker(Robot()) 69 | manager.manage() 70 | manager.lunch_break() 71 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/project/computer_store_app.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from project.computer_types.computer import Computer 3 | from project.computer_types.desktop_computer import DesktopComputer 4 | from project.computer_types.laptop import Laptop 5 | 6 | 7 | class ComputerStoreApp: 8 | VALID_COMPUTERS = { 9 | "Desktop Computer": DesktopComputer, 10 | "Laptop": Laptop, 11 | } 12 | 13 | def __init__(self): 14 | self.warehouse: List[Computer] = [] 15 | self.profits: int = 0 16 | 17 | def build_computer(self, type_computer: str, manufacturer: str, model: str, processor: str, ram: int) -> str: 18 | try: 19 | computer = self.VALID_COMPUTERS[type_computer](manufacturer, model) 20 | except KeyError: 21 | raise ValueError(f"{type_computer} is not a valid type computer!") 22 | 23 | configuration: str = computer.configure_computer(processor, ram) 24 | 25 | self.warehouse.append(computer) 26 | 27 | return configuration 28 | 29 | def sell_computer(self, client_budget: int, wanted_processor: str, wanted_ram: int) -> str: 30 | for computer in self.warehouse: 31 | if computer.price <= client_budget \ 32 | and \ 33 | wanted_processor == computer.processor \ 34 | and \ 35 | computer.ram >= wanted_ram: 36 | self.profits += client_budget - computer.price 37 | self.warehouse.remove(computer) 38 | 39 | return f"{computer} sold for {client_budget}$." 40 | 41 | raise Exception("Sorry, we don't have a computer for you.") 42 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/after/workers_updated.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class Workable(ABC): 5 | 6 | @abstractmethod 7 | def work(self): 8 | ... 9 | 10 | 11 | class Eatable(ABC): 12 | 13 | @abstractmethod 14 | def eat(self): 15 | ... 16 | 17 | 18 | class Worker(Workable, Eatable): 19 | 20 | def work(self): 21 | print("I'm normal worker. I'm working.") 22 | 23 | def eat(self): 24 | print("Lunch break....(5 secs)") 25 | 26 | 27 | class SuperWorker(Workable, Eatable): 28 | 29 | def work(self): 30 | print("I'm super worker. I work very hard!") 31 | 32 | def eat(self): 33 | print("Lunch break....(3 secs)") 34 | 35 | 36 | class Robot(Workable): 37 | 38 | def work(self): 39 | print("I'm a robot. I'm working....") 40 | 41 | 42 | class LazyPerson(Eatable): 43 | 44 | def eat(self): 45 | print("I only eat!") 46 | 47 | 48 | class BaseManager(ABC): 49 | 50 | def __init__(self): 51 | self.worker = None 52 | 53 | @abstractmethod 54 | def set_worker(self, worker): 55 | ... 56 | 57 | 58 | class WorkManager(BaseManager): 59 | 60 | def set_worker(self, worker): 61 | assert isinstance(worker, Workable), f"`worker` must be of type {Workable}" 62 | 63 | self.worker = worker 64 | 65 | def manage(self): 66 | self.worker.work() 67 | 68 | 69 | class BreakManager(BaseManager): 70 | def set_worker(self, worker): 71 | assert isinstance(worker, Eatable), f"`worker` must be of type {Eatable}" 72 | 73 | self.worker = worker 74 | 75 | def manage(self): 76 | self.worker.eat() 77 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/06_Formula_1_Team/project/f1_season_app.py: -------------------------------------------------------------------------------- 1 | from project.formula_teams.mercedes_team import MercedesTeam 2 | from project.formula_teams.red_bull_team import RedBullTeam 3 | 4 | 5 | class F1SeasonApp: 6 | 7 | def __init__(self): 8 | self.red_bull_team = None 9 | self.mercedes_team = None 10 | 11 | def register_team_for_season(self, team_name: str, budget: int) -> str: 12 | if team_name == "Red Bull": 13 | self.red_bull_team = RedBullTeam(budget) 14 | elif team_name == "Mercedes": 15 | self.mercedes_team = MercedesTeam(budget) 16 | else: 17 | raise ValueError("Invalid team name!") 18 | 19 | return f"{team_name} has joined the new F1 season." 20 | 21 | def new_race_results(self, race_name: str, red_bull_pos: int, mercedes_pos: int) -> str: 22 | if not self.red_bull_team or not self.mercedes_team: 23 | raise Exception("Not all teams have registered for the season.") 24 | 25 | return self.get_race_results(race_name, red_bull_pos, mercedes_pos) 26 | 27 | def get_race_results(self, race_name: str, red_bull_pos: int, mercedes_pos: int) -> str: 28 | ahead_team: str = "Red Bull" if red_bull_pos < mercedes_pos else "Mercedes" 29 | 30 | red_bull_revenue: str = self.red_bull_team.calculate_revenue_after_race(red_bull_pos) 31 | mercedes_revenue: str = self.mercedes_team.calculate_revenue_after_race(mercedes_pos) 32 | 33 | return ( 34 | f"Red Bull: {red_bull_revenue}. " 35 | f"Mercedes: {mercedes_revenue}. " 36 | f"{ahead_team} is ahead at the {race_name} race." 37 | ) 38 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/before/emails.py: -------------------------------------------------------------------------------- 1 | from abc import ABCMeta, abstractmethod 2 | 3 | 4 | class IEmail(object): 5 | __metaclass__ = ABCMeta 6 | 7 | @abstractmethod 8 | def set_sender(self, sender): 9 | pass 10 | 11 | @abstractmethod 12 | def set_receiver(self, receiver): 13 | pass 14 | 15 | @abstractmethod 16 | def set_content(self, content): 17 | pass 18 | 19 | class Email(IEmail): 20 | 21 | def __init__(self, protocol, content_type): 22 | self.protocol = protocol 23 | self.content_type = content_type 24 | self.__sender = None 25 | self.__receiver = None 26 | self.__content = None 27 | 28 | def set_sender(self, sender): 29 | if self.protocol == 'IM': 30 | self.__sender = ''.join(["I'm ", sender]) 31 | else: 32 | self.__sender = sender 33 | 34 | def set_receiver(self, receiver): 35 | if self.protocol == 'IM': 36 | self.__receiver = ''.join(["I'm ", receiver]) 37 | else: 38 | self.__receiver = receiver 39 | 40 | def set_content(self, content): 41 | if self.content_type == 'MyML': 42 | self.__content = '\n'.join(['', content, '']) 43 | else: 44 | self.__content = content 45 | 46 | def __repr__(self): 47 | 48 | template = "Sender: {sender}\nReceiver: {receiver}\nContent:\n{content}" 49 | 50 | return template.format(sender = self.__sender, receiver = self.__receiver, content = self.__content) 51 | 52 | 53 | email = Email('IM', 'MyML') 54 | email.set_sender('qmal') 55 | email.set_receiver('james') 56 | email.set_content('Hello, there!') 57 | print(email) 58 | 59 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/07_Spoopify/project/album.py: -------------------------------------------------------------------------------- 1 | from typing import Tuple 2 | from project.song import Song 3 | 4 | 5 | class Album: 6 | 7 | def __init__(self, name: str, *songs: Tuple[Song]): # (0x..13784387, 0x.37843724) 8 | self.name = name 9 | self.songs = [*songs] # [0x..13784387, 0x.37843724] 10 | self.published: bool = False 11 | 12 | def add_song(self, song: Song) -> str: 13 | if song.single: 14 | return f"Cannot add {song.name}. It's a single" 15 | if self.published: 16 | return "Cannot add songs. Album is published." 17 | if song in self.songs: 18 | return "Song is already in the album." 19 | 20 | self.songs.append(song) 21 | 22 | return f"Song {song.name} has been added to the album {self.name}." 23 | 24 | def remove_song(self, song_name: str) -> str: 25 | try: 26 | song = next(filter(lambda s: s.name == song_name, self.songs)) 27 | except StopIteration: 28 | return "Song is not in the album." 29 | 30 | if self.published: 31 | return "Cannot remove songs. Album is published." 32 | 33 | self.songs.remove(song) 34 | 35 | return f"Removed song {song_name} from album {self.name}." 36 | 37 | def publish(self) -> str: 38 | if self.published: 39 | return f"Album {self.name} is already published." 40 | 41 | self.published = True 42 | 43 | return f"Album {self.name} has been published." 44 | 45 | def details(self) -> str: 46 | songs_details = "\n".join(f"== {s.get_info()}" for s in self.songs) 47 | return f"Album {self.name}\n" \ 48 | f"{songs_details}" 49 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/04_Wild_Farm/project/animals/animal.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | from typing import List, Type 3 | 4 | from project.food import Food, Meat, Vegetable, Fruit, Seed 5 | 6 | 7 | class Animal(ABC): 8 | 9 | def __init__(self, name: str, weight: float): 10 | self.name = name 11 | self.weight = weight 12 | self.food_eaten = 0 13 | 14 | @property 15 | @abstractmethod 16 | def food_that_eats(self): 17 | ... 18 | 19 | @property 20 | @abstractmethod 21 | def gained_weight(self) -> float: 22 | ... 23 | 24 | @staticmethod 25 | @abstractmethod 26 | def make_sound() -> str: 27 | ... 28 | 29 | def feed(self, food: Food) -> str or None: 30 | if type(food) not in self.food_that_eats: 31 | return f"{self.__class__.__name__} does not eat {food.__class__.__name__}!" 32 | 33 | self.weight += self.gained_weight * food.quantity 34 | self.food_eaten += food.quantity 35 | 36 | 37 | class Bird(Animal, ABC): 38 | 39 | def __init__(self, name: str, weight: float, wing_size: float): 40 | super().__init__(name, weight) 41 | self.wing_size = wing_size 42 | 43 | def __repr__(self): 44 | return f"{self.__class__.__name__} [{self.name}, {self.wing_size}, {self.weight}, {self.food_eaten}]" 45 | 46 | 47 | class Mammal(Animal, ABC): 48 | 49 | def __init__(self, name: str, weight: float, living_region: str): 50 | super().__init__(name, weight) 51 | self.living_region = living_region 52 | 53 | def __repr__(self): 54 | return f"{self.__class__.__name__} [{self.name}, {self.weight}, {self.living_region}, {self.food_eaten}]" 55 | -------------------------------------------------------------------------------- /11_Exam_Preparation/task3/climbing_robot.py: -------------------------------------------------------------------------------- 1 | class ClimbingRobot: 2 | ALLOWED_CATEGORIES = ['Mountain', 'Alpine', 'Indoor', 'Bouldering'] 3 | 4 | def __init__(self, category: str, part_type: str, capacity: int, memory: int): 5 | self.category = category 6 | self.part_type = part_type 7 | self.capacity = capacity 8 | self.memory = memory 9 | self.installed_software = [] 10 | 11 | @property 12 | def category(self): 13 | return self.__category 14 | 15 | @category.setter 16 | def category(self, value): 17 | if value not in self.ALLOWED_CATEGORIES: 18 | raise ValueError(f"Category should be one of {self.ALLOWED_CATEGORIES}") 19 | self.__category = value 20 | 21 | def get_used_capacity(self): 22 | return sum(s['capacity_consumption'] for s in self.installed_software) 23 | 24 | def get_available_capacity(self): 25 | return self.capacity - self.get_used_capacity() 26 | 27 | def get_used_memory(self): 28 | return sum(s['memory_consumption'] for s in self.installed_software) 29 | 30 | def get_available_memory(self): 31 | return self.memory - self.get_used_memory() 32 | 33 | def install_software(self, software: {str, int}): 34 | if self.get_available_capacity() >= software['capacity_consumption'] and \ 35 | self.get_available_memory() >= software['memory_consumption']: 36 | self.installed_software.append(software) 37 | return f"Software '{software['name']}' successfully installed on {self.category} part." 38 | else: 39 | return f"Software '{software['name']}' cannot be installed on {self.category} part." 40 | -------------------------------------------------------------------------------- /10_Unit_Testing/First_Test_Worker/test_worker.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | from First_Test_Worker.worker import Worker 3 | 4 | 5 | class TestWorker(TestCase): 6 | 7 | def setUp(self): # runs before each test case 8 | self.worker = Worker( 9 | "TestGuy", 10 | 25_000, 11 | 100 12 | ) 13 | 14 | def test_correct_init(self): 15 | self.assertEqual("TestGuy", self.worker.name) 16 | self.assertEqual(25_000, self.worker.salary) 17 | self.assertEqual(100, self.worker.energy) 18 | self.assertEqual(0, self.worker.money) 19 | 20 | def test_work_when_worker_has_energy_expect_money_increase_and_energy_decrease(self): 21 | expected_money = self.worker.salary * 2 22 | expected_energy = self.worker.energy - 2 23 | 24 | self.worker.work() 25 | self.worker.work() 26 | 27 | self.assertEqual(expected_money, self.worker.money) 28 | self.assertEqual(expected_energy, self.worker.energy) 29 | 30 | def test_work_when_worker_does_not_have_energy_raise_exception(self): 31 | self.worker.energy = 0 # Arrange 32 | 33 | with self.assertRaises(Exception) as ex: 34 | self.worker.work() # Act 35 | 36 | self.assertEqual('Not enough energy.', str(ex.exception)) # Assert 37 | 38 | def test_rest_increases_energy_with_one(self): 39 | expected_energy = self.worker.energy + 1 40 | 41 | self.worker.rest() 42 | 43 | self.assertEqual(expected_energy, self.worker.energy) 44 | 45 | def test_get_info_returns_correct_string(self): 46 | self.assertEqual(f'TestGuy has saved 0 money.', self.worker.get_info()) 47 | 48 | 49 | if __name__ == "__main__": 50 | main() 51 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/08_Library/project/library.py: -------------------------------------------------------------------------------- 1 | from typing import List, Dict 2 | 3 | from project.user import User 4 | 5 | 6 | class Library: 7 | 8 | def __init__(self): 9 | self.user_records: List[User] = [] # [User(1, "Pesho"), User(2, "Ivan"), ...] 10 | self.books_available: Dict[str: List[str]] = {} # {"Svetlin Nakov": ["Python Basics", "JS basics"]...} 11 | self.rented_books: Dict[str: Dict[str: int]] = {} # {"Pesho": {"Python Baiscs": 30, "JS basics": 10}, ...} 12 | 13 | def get_book(self, author: str, book_name: str, days_to_return: int, user: User) -> str: 14 | if book_name in self.books_available[author]: 15 | self.books_available[author].remove(book_name) 16 | user.books.append(book_name) 17 | 18 | if user.username in self.rented_books: 19 | self.rented_books[user.username][book_name] = days_to_return 20 | else: 21 | self.rented_books[user.username] = {book_name: days_to_return} 22 | 23 | return f"{book_name} successfully rented for the next {days_to_return} days!" 24 | 25 | for data in self.rented_books.values(): # data is a dictionary => {"Python Baiscs": 30, "JS basics": 10} 26 | if book_name in data: 27 | return f'The book "{book_name}" is already rented and will be available in {data[book_name]} days!' 28 | 29 | def return_book(self, author: str, book_name: str, user: User) -> str: 30 | if book_name not in self.rented_books[user.username]: 31 | return f"{user.username} doesn't have this book in his/her records!" 32 | 33 | del self.rented_books[user.username][book_name] 34 | user.books.remove(book_name) 35 | self.books_available[author].append(book_name) 36 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Lab/02_Shop.py: -------------------------------------------------------------------------------- 1 | from typing import Dict 2 | 3 | 4 | class Shop: 5 | 6 | def __init__(self, name: str, type_shop: str, capacity: int): 7 | self.name = name 8 | self.type = type_shop 9 | self.capacity = capacity 10 | self.items: Dict[str: int] = {} # {bananas: 10} 11 | 12 | @classmethod 13 | def small_shop(cls, name: str, type_shop: str): # from __future__ import annotations -> Shop 14 | return cls(name, type_shop, 10) 15 | 16 | def add_item(self, item_name: str) -> str: 17 | if sum(self.items.values()) >= self.capacity: 18 | return "Not enough capacity in the shop" 19 | 20 | self.items[item_name] = self.items.get(item_name, 0) + 1 21 | 22 | return f"{item_name} added to the shop" 23 | 24 | def remove_item(self, item_name: str, amount: int) -> str: 25 | product_quantity = self.items.get(item_name) 26 | 27 | if not product_quantity or amount > product_quantity: 28 | return f"Cannot remove {amount} {item_name}" 29 | 30 | self.items[item_name] -= amount 31 | 32 | if self.items[item_name] == 0: 33 | del self.items[item_name] 34 | 35 | return f"{amount} {item_name} removed from the shop" 36 | 37 | def __repr__(self): 38 | return f"{self.name} of type {self.type} with capacity {self.capacity}" 39 | 40 | 41 | fresh_shop = Shop("Fresh Shop", "Fruit and Veg", 50) 42 | small_shop = Shop.small_shop("Fashion Boutique", "Clothes") 43 | print(fresh_shop) 44 | print(small_shop) 45 | 46 | print(fresh_shop.add_item("Bananas")) 47 | print(fresh_shop.remove_item("Tomatoes", 2)) 48 | 49 | print(small_shop.add_item("Jeans")) 50 | print(small_shop.add_item("Jeans")) 51 | print(small_shop.remove_item("Jeans", 2)) 52 | print(small_shop.items) 53 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/05_Task/project/section.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from project.task import Task 3 | 4 | 5 | class Section: 6 | 7 | def __init__(self, name: str): 8 | self.name = name 9 | self.tasks: List[Task] = [] 10 | 11 | def add_task(self, task: Task) -> str: 12 | if task in self.tasks: 13 | return f"Task is already in the section {self.name}" 14 | 15 | self.tasks.append(task) 16 | 17 | return f"Task {task.details()} is added to the section" 18 | 19 | def complete_task(self, task_name: str) -> str: 20 | try: 21 | task = next(filter(lambda t: t.name == task_name, self.tasks)) 22 | except StopIteration: 23 | return f"Could not find task with the name {task_name}" 24 | 25 | task.completed = True 26 | 27 | return f"Completed task {task_name}" 28 | 29 | def clean_section(self) -> str: 30 | count_tasks = 0 31 | 32 | for task in self.tasks: 33 | if task.completed: 34 | count_tasks += 1 35 | self.tasks.remove(task) 36 | 37 | return f"Cleared {count_tasks} tasks." 38 | 39 | def view_section(self) -> str: 40 | tasks_with_details = "\n".join(t.details() for t in self.tasks) 41 | return f"Section {self.name}:\n" \ 42 | f"{tasks_with_details}" 43 | 44 | 45 | task = Task("Make bed", "27/05/2020") 46 | print(task.change_name("Go to University")) 47 | print(task.change_due_date("28.05.2020")) 48 | task.add_comment("Don't forget laptop") 49 | print(task.edit_comment(0, "Don't forget laptop and notebook")) 50 | print(task.details()) 51 | section = Section("Daily tasks") 52 | print(section.add_task(task)) 53 | second_task = Task("Make bed", "27/05/2020") 54 | section.add_task(second_task) 55 | print(section.clean_section()) 56 | print(section.view_section()) 57 | -------------------------------------------------------------------------------- /06_Polymorphism_And_Abstraction/03_Account.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Account: 5 | 6 | def __init__(self, owner: str, amount: int = 0): 7 | self.owner = owner 8 | self.amount = amount 9 | self._transactions: List[int] = [] 10 | 11 | @property 12 | def balance(self) -> int: 13 | return sum(self._transactions) + self.amount 14 | 15 | def handle_transaction(self, transaction_amount: int) -> str: 16 | if self.balance + transaction_amount < 0: 17 | raise ValueError("sorry cannot go in debt!") 18 | 19 | self._transactions.append(transaction_amount) 20 | 21 | return f"New balance: {self.balance}" 22 | 23 | def add_transaction(self, amount: int) -> str: 24 | if not isinstance(amount, int): 25 | raise ValueError("please use int for amount") 26 | 27 | return self.handle_transaction(amount) 28 | 29 | def __str__(self): 30 | return f"Account of {self.owner} with starting amount: {self.amount}" 31 | 32 | def __repr__(self): 33 | return f"Account({self.owner}, {self.amount})" 34 | 35 | def __len__(self): 36 | return len(self._transactions) 37 | 38 | def __getitem__(self, idx: int): 39 | return self._transactions[idx] 40 | 41 | def __reversed__(self): 42 | return reversed(self._transactions) 43 | 44 | def __gt__(self, other): # > 45 | return self.balance > other.balance 46 | 47 | def __ge__(self, other): # >= 48 | return self.balance >= other.balance 49 | 50 | def __eq__(self, other): # == 51 | return self.balance == other.balance 52 | 53 | def __add__(self, other): 54 | new_account = Account(f"{self.owner}&{other.owner}", self.amount + other.amount) 55 | new_account._transactions = self._transactions + other._transactions 56 | 57 | return new_account 58 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/vehicle/test/test_vehicle.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | from project.vehicle import Vehicle 3 | 4 | 5 | class TestVehicle(TestCase): 6 | 7 | def setUp(self): 8 | self.vehicle = Vehicle( 9 | 100, 10 | 100, 11 | ) 12 | 13 | def test_default_fuel_consumption_is_correct_value(self): 14 | self.assertEqual(1.25, Vehicle.DEFAULT_FUEL_CONSUMPTION) 15 | 16 | def test_correct_init(self): 17 | self.assertEqual(100, self.vehicle.fuel) 18 | self.assertEqual(100, self.vehicle.capacity) 19 | self.assertEqual(100, self.vehicle.horse_power) 20 | self.assertEqual(self.vehicle.DEFAULT_FUEL_CONSUMPTION, self.vehicle.fuel_consumption) 21 | 22 | def test_drive_without_fuel_raises_exception(self): 23 | self.vehicle.fuel = 0 24 | 25 | with self.assertRaises(Exception) as ex: 26 | self.vehicle.drive(100) 27 | 28 | self.assertEqual("Not enough fuel", str(ex.exception)) 29 | 30 | def test_drive_with_enough_fuel_decreases_fuel(self): 31 | self.vehicle.drive(10) 32 | self.assertEqual(87.5, self.vehicle.fuel) 33 | 34 | def test_refuel_above_capacity_raises_exception(self): 35 | with self.assertRaises(Exception) as ex: 36 | self.vehicle.refuel(1000) 37 | 38 | self.assertEqual("Too much fuel", str(ex.exception)) 39 | 40 | def test_refuel_correct_amount(self): 41 | self.vehicle.fuel = 0 42 | 43 | self.vehicle.refuel(50) 44 | 45 | self.assertEqual(50, self.vehicle.fuel) 46 | 47 | def test_correct__str__method(self): 48 | expected_result = f"The vehicle has 100 " \ 49 | f"horse power with 100 fuel left and 1.25 fuel consumption" 50 | 51 | self.assertEqual(expected_result, str(self.vehicle)) 52 | 53 | 54 | if __name__ == "__main__": 55 | main() 56 | -------------------------------------------------------------------------------- /07_SOLID_Exercise/after/emails.py: -------------------------------------------------------------------------------- 1 | from abc import abstractmethod, ABC 2 | 3 | 4 | class IContent(ABC): 5 | 6 | def __init__(self, text: str): 7 | self.text = text 8 | 9 | @abstractmethod 10 | def format(self): 11 | ... 12 | 13 | 14 | class MyMl(IContent): 15 | 16 | def format(self): 17 | return '\n'.join(['', self.text, '']) 18 | 19 | 20 | class HTML(IContent): 21 | 22 | def format(self): 23 | return '\n'.join(['', self.text, '']) 24 | 25 | 26 | class IEmail(ABC): 27 | 28 | @abstractmethod 29 | def set_sender(self, sender): 30 | pass 31 | 32 | @abstractmethod 33 | def set_receiver(self, receiver): 34 | pass 35 | 36 | @abstractmethod 37 | def set_content(self, content): 38 | pass 39 | 40 | 41 | class Email(IEmail): 42 | 43 | def __init__(self, protocol): 44 | self.protocol = protocol 45 | self.__sender = None 46 | self.__receiver = None 47 | self.__content = None 48 | 49 | def set_sender(self, sender): 50 | # TODO: fix sender 51 | if self.protocol == 'IM': 52 | self.__sender = ''.join(["I'm ", sender]) 53 | else: 54 | self.__sender = sender 55 | 56 | def set_receiver(self, receiver): 57 | # TODO: fix receiver 58 | if self.protocol == 'IM': 59 | self.__receiver = ''.join(["I'm ", receiver]) 60 | else: 61 | self.__receiver = receiver 62 | 63 | def set_content(self, content: IContent): 64 | self.__content = content.format() 65 | 66 | def __repr__(self): 67 | 68 | template = "Sender: {sender}\nReceiver: {receiver}\nContent:\n{content}" 69 | 70 | return template.format(sender = self.__sender, receiver = self.__receiver, content = self.__content) 71 | 72 | 73 | email = Email('IM') 74 | email.set_sender('qmal') 75 | email.set_receiver('james') 76 | content = HTML('Hello, there!') 77 | email.set_content(content) 78 | print(email) 79 | 80 | 81 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/04_Gym/project/gym.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from project.customer import Customer 3 | from project.equipment import Equipment 4 | from project.trainer import Trainer 5 | from project.subscription import Subscription 6 | from project.exercise_plan import ExercisePlan 7 | 8 | 9 | class Gym: 10 | 11 | def __init__(self): 12 | self.customers: List[Customer] = [] 13 | self.equipment: List[Equipment] = [] 14 | self.plans: List[ExercisePlan] = [] 15 | self.subscriptions: List[Subscription] = [] 16 | self.trainers: List[Trainer] = [] 17 | 18 | def add_customer(self, customer: Customer) -> None: 19 | if customer not in self.customers: 20 | self.customers.append(customer) 21 | 22 | def add_equipment(self, equipment: Equipment) -> None: 23 | if equipment not in self.equipment: 24 | self.equipment.append(equipment) 25 | 26 | def add_plan(self, plan: ExercisePlan) -> None: 27 | if plan not in self.plans: 28 | self.plans.append(plan) 29 | 30 | def add_subscription(self, subscription: Subscription) -> None: 31 | if subscription not in self.subscriptions: 32 | self.subscriptions.append(subscription) 33 | 34 | def add_trainer(self, trainer: Trainer) -> None: 35 | if trainer not in self.trainers: 36 | self.trainers.append(trainer) 37 | 38 | def subscription_info(self, subscription_id: int) -> str: 39 | subscription = next(filter(lambda s: s.id == subscription_id, self.subscriptions)) 40 | customer = next(filter(lambda c: c.id == subscription.customer_id, self.customers)) 41 | trainer = next(filter(lambda t: t.id == subscription.trainer_id, self.trainers)) 42 | plan = next(filter(lambda p: p.id == subscription.exercise_id, self.plans)) 43 | equipment = next(filter(lambda e: e.id == plan.equipment_id, self.equipment)) 44 | 45 | return f"{str(subscription)}\n{str(customer)}\n{str(trainer)}\n{str(equipment)}\n{str(plan)}" 46 | -------------------------------------------------------------------------------- /01_First_Steps_In_OOP/project/trainer.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from project.pokemon import Pokemon 3 | 4 | 5 | class Trainer: 6 | def __init__(self, name: str): 7 | self.name = name 8 | self.pokemons: List[Pokemon] = [] 9 | 10 | def add_pokemon(self, pokemon: Pokemon) -> str: 11 | if pokemon in self.pokemons: 12 | return "This pokemon is already caught" 13 | 14 | self.pokemons.append(pokemon) 15 | 16 | return f"Caught {pokemon.pokemon_details()}" 17 | 18 | def release_pokemon(self, pokemon_name: str) -> str: 19 | # Option 1 -> fast but long 20 | # pokemon = None 21 | # 22 | # for p in self.pokemons: 23 | # if p.name == pokemon_name: 24 | # pokemon = p 25 | # break 26 | 27 | # Option 2 -> slow, but short 28 | # try: 29 | # pokemon = [p for p in self.pokemons if p.name == pokemon_name][0] 30 | # except IndexError: 31 | # return "Pokemon is not caught" 32 | 33 | # Option 3 -> fast and short 34 | try: 35 | pokemon = next(filter(lambda p: p.name == pokemon_name, self.pokemons)) 36 | except StopIteration: 37 | return "Pokemon is not caught" 38 | 39 | self.pokemons.remove(pokemon) 40 | 41 | return f"You have released {pokemon_name}" 42 | 43 | def trainer_data(self) -> str: 44 | pokemons_data = '\n'.join(f"- {p.pokemon_details()}" for p in self.pokemons) 45 | 46 | return f"Pokemon Trainer {self.name}\n" \ 47 | f"Pokemon count {len(self.pokemons)}\n" \ 48 | f"{pokemons_data}" 49 | 50 | 51 | pokemon = Pokemon("Pikachu", 90) 52 | print(pokemon.pokemon_details()) 53 | trainer = Trainer("Ash") 54 | print(trainer.add_pokemon(pokemon)) 55 | second_pokemon = Pokemon("Charizard", 110) 56 | print(trainer.add_pokemon(second_pokemon)) 57 | print(trainer.add_pokemon(second_pokemon)) 58 | print(trainer.release_pokemon("Pikachu")) 59 | print(trainer.release_pokemon("Pikachu")) 60 | print(trainer.trainer_data()) 61 | -------------------------------------------------------------------------------- /02_Classes_And_Objects/04_Pizza_Delivery.py: -------------------------------------------------------------------------------- 1 | class PizzaDelivery: 2 | 3 | def __init__(self, name: str, price: float, ingredients: dict): 4 | self.name = name 5 | self.price = price 6 | self.ingredients = ingredients # {cheese: 3, peperoni: 2, olives: 3...} 7 | self.ordered = False 8 | 9 | def get_ordered_message(self): 10 | return f"Pizza {self.name} already prepared, and we can't make any changes!" 11 | 12 | def add_extra(self, ingredient: str, quantity: int, price_per_ingredient: float) -> str or None: 13 | if self.ordered: 14 | return self.get_ordered_message() 15 | 16 | self.ingredients[ingredient] = self.ingredients.get(ingredient, 0) + quantity 17 | self.price += quantity * price_per_ingredient 18 | 19 | def remove_ingredient(self, ingredient: str, quantity: int, price_per_ingredient: float) -> str or None: 20 | if self.ordered: 21 | return self.get_ordered_message() 22 | 23 | ingredient_quantity = self.ingredients.get(ingredient) 24 | 25 | if not ingredient_quantity: 26 | return f"Wrong ingredient selected! We do not use {ingredient} in {self.name}!" 27 | 28 | if ingredient_quantity < quantity: 29 | return f"Please check again the desired quantity of {ingredient}!" 30 | 31 | self.ingredients[ingredient] -= quantity 32 | self.price -= price_per_ingredient * quantity 33 | 34 | def make_order(self) -> str: 35 | self.ordered = True 36 | ingredients = ', '.join(f"{k}: {v}" for k, v in self.ingredients.items()) 37 | return f"You've ordered pizza {self.name} prepared with {ingredients} and the price will be {self.price}lv." 38 | 39 | 40 | margarita = PizzaDelivery('Margarita', 11, {'cheese': 2, 'tomatoes': 1}) 41 | margarita.add_extra('mozzarella', 1, 0.5) 42 | margarita.add_extra('cheese', 1, 1) 43 | margarita.remove_ingredient('cheese', 1, 1) 44 | print(margarita.remove_ingredient('bacon', 1, 2.5)) 45 | print(margarita.remove_ingredient('tomatoes', 2, 0.5)) 46 | margarita.remove_ingredient('cheese', 2, 1) 47 | print(margarita.make_order()) 48 | print(margarita.add_extra('cheese', 1, 1)) 49 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/02_Movie_World/project/movie_world.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from project.customer import Customer 3 | from project.dvd import DVD 4 | 5 | 6 | class MovieWorld: 7 | 8 | def __init__(self, name: str): 9 | self.name = name 10 | self.customers: List[Customer] = [] 11 | self.dvds: List[DVD] = [] 12 | 13 | @staticmethod 14 | def dvd_capacity() -> int: 15 | return 15 16 | 17 | @staticmethod 18 | def customer_capacity() -> int: 19 | return 10 20 | 21 | def add_customer(self, customer: Customer) -> None: 22 | if len(self.customers) < self.customer_capacity(): 23 | self.customers.append(customer) 24 | 25 | def add_dvd(self, dvd: DVD) -> None: 26 | if len(self.dvds) < self.dvd_capacity(): 27 | self.dvds.append(dvd) 28 | 29 | def rent_dvd(self, customer_id: int, dvd_id: int) -> str: 30 | customer = next(filter(lambda c: c.id == customer_id, self.customers)) 31 | dvd = next(filter(lambda d: d.id == dvd_id, self.dvds)) 32 | 33 | if dvd in customer.rented_dvds: 34 | return f"{customer.name} has already rented {dvd.name}" 35 | if dvd.is_rented: 36 | return f"DVD is already rented" 37 | if customer.age < dvd.age_restriction: 38 | return f"{customer.name} should be at least {dvd.age_restriction} to rent this movie" 39 | 40 | customer.rented_dvds.append(dvd) 41 | dvd.is_rented = True 42 | 43 | return f"{customer.name} has successfully rented {dvd.name}" 44 | 45 | def return_dvd(self, customer_id: int, dvd_id: int) -> str: 46 | customer = next(filter(lambda c: c.id == customer_id, self.customers)) 47 | dvd = next(filter(lambda d: d.id == dvd_id, self.dvds)) 48 | 49 | if dvd not in customer.rented_dvds: 50 | return f"{customer.name} does not have that DVD" 51 | 52 | customer.rented_dvds.remove(dvd) 53 | dvd.is_rented = False 54 | 55 | return f"{customer.name} has successfully returned {dvd.name}" 56 | 57 | def __repr__(self): 58 | return "\n".join([ 59 | *[str(c) for c in self.customers], 60 | *[str(d) for d in self.dvds], 61 | ]) 62 | -------------------------------------------------------------------------------- /05_Static_And_Class_Methods_Exercise/03_Document/project/storage.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from project.category import Category 3 | from project.document import Document 4 | from project.topic import Topic 5 | 6 | 7 | class Storage: 8 | 9 | def __init__(self): 10 | self.categories: List[Category] = [] # [Category("Food"), ] 11 | self.documents: List[Document] = [] 12 | self.topics: List[Topic] = [] 13 | 14 | def add_category(self, category: Category) -> None: 15 | if category not in self.categories: 16 | self.categories.append(category) 17 | 18 | def add_document(self, document: Document) -> None: 19 | if document not in self.documents: 20 | self.documents.append(document) 21 | 22 | def add_topic(self, topic: Topic) -> None: 23 | if topic not in self.topics: 24 | self.topics.append(topic) 25 | 26 | def edit_category(self, category_id: int, new_name: str) -> None: 27 | category = next(filter(lambda c: c.id == category_id, self.categories)) 28 | category.edit(new_name) 29 | 30 | def edit_document(self, document_id: int, new_file_name: str) -> None: 31 | document = next(filter(lambda d: d.id == document_id, self.documents)) 32 | document.edit(new_file_name) 33 | 34 | def edit_topic(self, topic_id: int, new_topic: str, new_storage_folder: str) -> None: 35 | topic = next(filter(lambda t: t.id == topic_id, self.topics)) 36 | topic.edit(new_topic, new_storage_folder) 37 | 38 | def delete_category(self, category_id: int) -> None: 39 | category = next(filter(lambda c: c.id == category_id, self.categories)) 40 | self.categories.remove(category) 41 | 42 | def delete_topic(self, topic_id: int) -> None: 43 | topic = next(filter(lambda t: t.id == topic_id, self.topics)) 44 | self.topics.remove(topic) 45 | 46 | def delete_document(self, document_id: int) -> None: 47 | document = next(filter(lambda d: d.id == document_id, self.documents)) 48 | self.documents.remove(document) 49 | 50 | def get_document(self, document_id: int): 51 | return next(filter(lambda d: d.id == document_id, self.documents)) 52 | 53 | def __repr__(self): 54 | return "\n".join(str(d) for d in self.documents) 55 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /09_Decorators_Exercise/project/computer_types/computer.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | from typing import Dict 3 | from math import log2 4 | 5 | 6 | class Computer(ABC): 7 | ONE_BLOCK_OF_RAM_PRICE: int = 100 8 | 9 | def __init__(self, manufacturer: str, model: str): 10 | self.manufacturer = manufacturer 11 | self.model = model 12 | self.processor = None 13 | self.ram = None 14 | self.price = 0 15 | 16 | @property 17 | @abstractmethod 18 | def type(self) -> str: 19 | ... 20 | 21 | @property 22 | @abstractmethod 23 | def available_processors(self) -> Dict[str, int]: 24 | ... 25 | 26 | @property 27 | @abstractmethod 28 | def max_ram(self) -> int: 29 | ... 30 | 31 | @property 32 | def manufacturer(self): 33 | return self.__manufacturer 34 | 35 | @manufacturer.setter 36 | def manufacturer(self, value): 37 | if not value.strip(): 38 | raise ValueError("Manufacturer name cannot be empty.") 39 | 40 | self.__manufacturer = value 41 | 42 | @property 43 | def model(self): 44 | return self.__model 45 | 46 | @model.setter 47 | def model(self, value): 48 | if not value.strip(): 49 | raise ValueError("Model name cannot be empty.") 50 | 51 | self.__model = value 52 | 53 | @staticmethod 54 | def power_of_two(ram: int): 55 | result = log2(ram) # log of ram with base 2 = 2^x = ram; result is x 56 | return result.is_integer() 57 | 58 | def configure_computer(self, processor: str, ram: int) -> str: 59 | if processor not in self.available_processors: 60 | raise ValueError(f"{processor} is not compatible with {self.type} {self.manufacturer} {self.model}!") 61 | 62 | if ram > self.max_ram or not self.power_of_two(ram): 63 | raise ValueError(f"{ram}GB RAM is not compatible with {self.type} {self.manufacturer} {self.model}!") 64 | 65 | self.set_parts(processor, ram) 66 | 67 | return f"Created {self.__repr__()} for {self.price}$." 68 | 69 | def set_parts(self, processor: str, ram: int) -> None: 70 | self.processor = processor 71 | self.ram = ram 72 | self.price += self.available_processors[processor] # processor AMD Ryzen 7 => 500$ 73 | self.price += int(log2(ram)) * self.ONE_BLOCK_OF_RAM_PRICE 74 | 75 | def __repr__(self): 76 | return f"{self.manufacturer} {self.model} with {self.processor} and {self.ram}GB RAM" 77 | -------------------------------------------------------------------------------- /10_Unit_Testing/Car_Manager/car_manager.py: -------------------------------------------------------------------------------- 1 | class Car: 2 | def __init__(self, make, model, fuel_consumption, fuel_capacity): 3 | self.make = make 4 | self.model = model 5 | self.fuel_consumption = fuel_consumption 6 | self.fuel_capacity = fuel_capacity 7 | self.fuel_amount = 0 8 | 9 | @property 10 | def make(self): 11 | return self.__make 12 | 13 | @make.setter 14 | def make(self, new_value): 15 | if not new_value: 16 | raise Exception("Make cannot be null or empty!") 17 | 18 | self.__make = new_value 19 | 20 | @property 21 | def model(self): 22 | return self.__model 23 | 24 | @model.setter 25 | def model(self, new_value): 26 | if not new_value: 27 | raise Exception("Model cannot be null or empty!") 28 | 29 | self.__model = new_value 30 | 31 | @property 32 | def fuel_consumption(self): 33 | return self.__fuel_consumption 34 | 35 | @fuel_consumption.setter 36 | def fuel_consumption(self, new_value): 37 | if new_value <= 0: 38 | raise Exception("Fuel consumption cannot be zero or negative!") 39 | self.__fuel_consumption = new_value 40 | 41 | @property 42 | def fuel_capacity(self): 43 | return self.__fuel_capacity 44 | 45 | @fuel_capacity.setter 46 | def fuel_capacity(self, new_value): 47 | if new_value <= 0: 48 | raise Exception("Fuel capacity cannot be zero or negative!") 49 | self.__fuel_capacity = new_value 50 | 51 | @property 52 | def fuel_amount(self): 53 | return self.__fuel_amount 54 | 55 | @fuel_amount.setter 56 | def fuel_amount(self, new_value): 57 | if new_value < 0: 58 | raise Exception("Fuel amount cannot be negative!") 59 | 60 | self.__fuel_amount = new_value 61 | 62 | def refuel(self, fuel): 63 | if fuel <= 0: 64 | raise Exception("Fuel amount cannot be zero or negative!") 65 | 66 | self.__fuel_amount += fuel 67 | 68 | if self.__fuel_amount > self.__fuel_capacity: 69 | self.__fuel_amount = self.__fuel_capacity 70 | 71 | def drive(self, distance): 72 | needed = (distance / 100) * self.__fuel_consumption 73 | 74 | if needed > self.__fuel_amount: 75 | raise Exception("You don't have enough fuel to drive!") 76 | 77 | self.__fuel_amount -= needed 78 | -------------------------------------------------------------------------------- /10_Unit_Testing/Car_Manager/test_car_manager.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | # from Car_Manager.car_manager import Car 3 | 4 | 5 | class TestCar(TestCase): 6 | 7 | def setUp(self): 8 | self.car = Car("Nissan", "GT-R", 15, 75) 9 | 10 | def test_correct_init(self): 11 | self.assertEqual("Nissan", self.car.make) 12 | self.assertEqual("GT-R", self.car.model) 13 | self.assertEqual(15, self.car.fuel_consumption) 14 | self.assertEqual(75, self.car.fuel_capacity) 15 | self.assertEqual(0, self.car.fuel_amount) 16 | 17 | def test_make_with_empty_string_raise_exception(self): 18 | with self.assertRaises(Exception) as ex: 19 | self.car.make = "" 20 | 21 | self.assertEqual("Make cannot be null or empty!", str(ex.exception)) 22 | 23 | def test_model_with_empty_string_raise_exception(self): 24 | with self.assertRaises(Exception) as ex: 25 | self.car.model = "" 26 | 27 | self.assertEqual("Model cannot be null or empty!", str(ex.exception)) 28 | 29 | def test_fuel_consumption_with_zero_raise_exception(self): 30 | with self.assertRaises(Exception) as ex: 31 | self.car.fuel_consumption = 0 32 | 33 | self.assertEqual("Fuel consumption cannot be zero or negative!", str(ex.exception)) 34 | 35 | def test_fuel_capacity_with_zero_raise_exception(self): 36 | with self.assertRaises(Exception) as ex: 37 | self.car.fuel_capacity = 0 38 | 39 | self.assertEqual("Fuel capacity cannot be zero or negative!", str(ex.exception)) 40 | 41 | def test_fuel_amount_with_zero_raise_exception(self): 42 | with self.assertRaises(Exception) as ex: 43 | self.car.fuel_amount = -1 44 | 45 | self.assertEqual("Fuel amount cannot be negative!", str(ex.exception)) 46 | 47 | def test_refuel_zero_fuel_raises_exception(self): 48 | with self.assertRaises(Exception) as ex: 49 | self.car.refuel(0) 50 | 51 | self.assertEqual("Fuel amount cannot be zero or negative!", str(ex.exception)) 52 | 53 | def test_refuel_more_than_capacity_fills_to_capacity(self): 54 | self.car.fuel_capacity = 75 55 | self.car.refuel(80) 56 | self.assertEqual(75, self.car.fuel_amount) 57 | 58 | def test_drive_car_without_fuel_raises_exception(self): 59 | with self.assertRaises(Exception) as ex: 60 | self.car.drive(100) 61 | 62 | self.assertEqual("You don't have enough fuel to drive!", str(ex.exception)) 63 | 64 | def test_drive_car_with_fuel_decreases_fuel(self): 65 | self.car.refuel(1000) 66 | self.car.drive(10) 67 | self.assertEqual(73.5, self.car.fuel_amount) 68 | 69 | 70 | if __name__ == "__main__": 71 | main() 72 | -------------------------------------------------------------------------------- /10_Unit_Testing/Third_List/test_integer_list.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | from Third_List.extended_list import IntegerList 3 | 4 | 5 | class TestIntegerList(TestCase): 6 | 7 | def setUp(self): 8 | self.i_list = IntegerList(5.5, 1, 2, 3, "hello") 9 | 10 | def test_correct_init_ignores_non_int_values(self): 11 | self.assertEqual([1, 2, 3], self.i_list.get_data()) 12 | 13 | def test_add_non_integer_value_to_the_list_raises_value_error(self): 14 | with self.assertRaises(ValueError) as ve: 15 | self.i_list.add(5.5) 16 | 17 | self.assertEqual("Element is not Integer", str(ve.exception)) 18 | 19 | def test_add_integer_adds_the_integer_to_the_list(self): 20 | expected_list = self.i_list.get_data() + [4] 21 | 22 | self.i_list.add(4) 23 | 24 | self.assertEqual(expected_list, self.i_list.get_data()) 25 | 26 | def test_remove_index_with_out_of_range_index_raise_index_error(self): 27 | with self.assertRaises(IndexError) as ie: 28 | self.i_list.remove_index(1000) 29 | 30 | self.assertEqual("Index is out of range", str(ie.exception)) 31 | 32 | def test_remove_index_with_valid_index(self): 33 | self.i_list.remove_index(1) 34 | 35 | self.assertEqual([1, 3], self.i_list.get_data()) 36 | 37 | def test_get_with_out_of_range_index(self): 38 | with self.assertRaises(IndexError) as ie: 39 | self.i_list.get(1000) 40 | 41 | self.assertEqual("Index is out of range", str(ie.exception)) 42 | 43 | def test_get_with_valid_index_returns_value_on_index(self): 44 | result = self.i_list.get(1) 45 | self.assertEqual(2, result) 46 | 47 | def test_insert_on_invalid_index_raises_index_error(self): 48 | with self.assertRaises(IndexError) as ie: 49 | self.i_list.insert(1000, 5) 50 | 51 | self.assertEqual("Index is out of range", str(ie.exception)) 52 | 53 | def test_insert_on_valid_index_with_non_integer_type_raise_value_error(self): 54 | with self.assertRaises(ValueError) as ve: 55 | self.i_list.insert(1, 6.7) 56 | 57 | self.assertEqual("Element is not Integer", str(ve.exception)) 58 | 59 | def test_insert_integer_on_valid_index(self): 60 | expected_list = self.i_list.get_data().copy() 61 | 62 | expected_list.insert(1, 5) 63 | self.i_list.insert(1, 5) 64 | 65 | self.assertEqual(expected_list, self.i_list.get_data()) 66 | 67 | def test_get_biggest_number(self): 68 | result = self.i_list.get_biggest() 69 | self.assertEqual(3, result) 70 | 71 | def test_get_index(self): 72 | result = self.i_list.get_index(2) 73 | self.assertEqual(1, result) 74 | 75 | 76 | if __name__ == "__main__": 77 | main() 78 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/hero/test/test_hero.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | from project.hero import Hero 3 | 4 | 5 | class TestHero(TestCase): 6 | 7 | def setUp(self): 8 | self.hero = Hero("Hero", 1, 100, 100) 9 | self.enemy = Hero("Enemy", 1, 50, 50) 10 | 11 | def test_correct__init__(self): 12 | self.assertEqual("Hero", self.hero.username) 13 | self.assertEqual(1, self.hero.level) 14 | self.assertEqual(100, self.hero.damage) 15 | self.assertEqual(100, self.hero.health) 16 | 17 | def test_battle_hero_with_himself_raises_exception(self): 18 | with self.assertRaises(Exception) as ex: 19 | self.hero.battle(self.hero) 20 | 21 | self.assertEqual("You cannot fight yourself", str(ex.exception)) 22 | 23 | def test_battle_hero_with_zero_health_raises_value_error(self): 24 | self.hero.health = 0 # Arrange 25 | expected_string = "Your health is lower than or equal to 0. You need to rest" 26 | 27 | with self.assertRaises(ValueError) as ve: 28 | self.hero.battle(self.enemy) # Act 29 | 30 | self.assertEqual(expected_string, str(ve.exception)) # Assert 31 | 32 | def test_battle_enemy_with_zero_health_raises_value_error(self): 33 | self.enemy.health = 0 # Arrange 34 | expected_string = f"You cannot fight {self.enemy.username}. He needs to rest" 35 | 36 | with self.assertRaises(ValueError) as ve: 37 | self.hero.battle(self.enemy) # Act 38 | 39 | self.assertEqual(expected_string, str(ve.exception)) # Assert 40 | 41 | def test_fight_with_result_draw_returns_draw_and_decreases_health_on_both_players(self): 42 | self.hero.health = 50 43 | 44 | result = self.hero.battle(self.enemy) 45 | 46 | self.assertEqual("Draw", result) 47 | self.assertEqual(-50, self.enemy.health) 48 | self.assertEqual(0, self.hero.health) 49 | 50 | def test_fight_enemy_and_win_expect_stats_increase(self): 51 | expected_level = self.hero.level + 1 52 | expected_damage = self.hero.damage + 5 53 | expected_health = self.hero.health - self.enemy.damage + 5 54 | 55 | result = self.hero.battle(self.enemy) 56 | 57 | self.assertEqual("You win", result) 58 | self.assertEqual(expected_level, self.hero.level) 59 | self.assertEqual(expected_health, self.hero.health) 60 | self.assertEqual(expected_damage, self.hero.damage) 61 | 62 | def test_fight_enemy_and_lose_expect_enemy_stats_increase(self): 63 | self.hero, self.enemy = self.enemy, self.hero 64 | 65 | expected_level = self.enemy.level + 1 66 | expected_damage = self.enemy.damage + 5 67 | expected_health = self.enemy.health - self.hero.damage + 5 68 | 69 | result = self.hero.battle(self.enemy) 70 | 71 | self.assertEqual("You lose", result) 72 | self.assertEqual(expected_level, self.enemy.level) 73 | self.assertEqual(expected_health, self.enemy.health) 74 | self.assertEqual(expected_damage, self.enemy.damage) 75 | 76 | def test_correct__str__(self): 77 | expected_result = f"Hero {self.hero.username}: {self.hero.level} lvl\n" \ 78 | f"Health: {self.hero.health}\n" \ 79 | f"Damage: {self.hero.damage}\n" 80 | 81 | self.assertEqual(expected_result, str(self.hero)) 82 | 83 | 84 | if __name__ == "__main__": 85 | main() 86 | -------------------------------------------------------------------------------- /11_Exam_Preparation/project/summit_quest_manager_app.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from project.peaks.base_peak import BasePeak 3 | from project.climbers.base_climber import BaseClimber 4 | from project.climbers.arctic_climber import ArcticClimber 5 | from project.climbers.summit_climber import SummitClimber 6 | from project.peaks.summit_peak import SummitPeak 7 | from project.peaks.arctic_peak import ArcticPeak 8 | 9 | 10 | class SummitQuestManagerApp: 11 | VALID_CLIMBER_TYPES = { 12 | "ArcticClimber": ArcticClimber, 13 | "SummitClimber": SummitClimber, 14 | } 15 | 16 | VALID_PEAKS_TYPES = { 17 | "ArcticPeak": ArcticPeak, 18 | "SummitPeak": SummitPeak, 19 | } 20 | 21 | def __init__(self): 22 | self.peaks: List[BasePeak] = [] 23 | self.climbers: List[BaseClimber] = [] 24 | 25 | def register_climber(self, climber_type: str, climber_name: str) -> str: 26 | try: 27 | climber = self.VALID_CLIMBER_TYPES[climber_type](climber_name) 28 | except KeyError: 29 | return f"{climber_type} doesn't exist in our register." 30 | 31 | try: 32 | next(filter(lambda c: c.name == climber_name, self.climbers)) 33 | return f"{climber_name} has been already registered." 34 | except StopIteration: 35 | self.climbers.append(climber) 36 | return f"{climber_name} is successfully registered as a {climber_type}." 37 | 38 | def peak_wish_list(self, peak_type: str, peak_name: str, peak_elevation: int) -> str: 39 | try: 40 | peak = self.VALID_PEAKS_TYPES[peak_type](peak_name, peak_elevation) 41 | except KeyError: 42 | return f"{peak_type} is an unknown type of peak." 43 | 44 | self.peaks.append(peak) 45 | 46 | return f"{peak_name} is successfully added to the wish list as a {peak_type}." 47 | 48 | def check_gear(self, climber_name: str, peak_name: str, gear: List[str]) -> str: 49 | climber = next(filter(lambda c: c.name == climber_name, self.climbers)) 50 | peak = next(filter(lambda p: p.name == peak_name, self.peaks)) 51 | 52 | if gear == peak.get_recommended_gear(): 53 | return f"{climber_name} is prepared to climb {peak_name}." 54 | 55 | climber.is_prepared = False 56 | 57 | return (f"{climber_name} is not prepared to climb {peak_name}. " 58 | f"Missing gear: " 59 | f"{', '.join(g for g in sorted(peak.get_recommended_gear()) if g not in gear)}.") 60 | 61 | def perform_climbing(self, climber_name: str, peak_name: str) -> str: 62 | try: 63 | climber = next(filter(lambda c: c.name == climber_name, self.climbers)) 64 | except StopIteration: 65 | return f"Climber {climber_name} is not registered yet." 66 | 67 | try: 68 | peak = next(filter(lambda p: p.name == peak_name, self.peaks)) 69 | except StopIteration: 70 | return f"Peak {peak_name} is not part of the wish list." 71 | 72 | if not climber.is_prepared: 73 | return f"{climber_name} will need to be better prepared next time." 74 | 75 | if not climber.can_climb(): 76 | climber.rest() 77 | return f"{climber_name} needs more strength to climb {peak_name} and is therefore taking some rest." 78 | 79 | climber.climb(peak) 80 | 81 | return f"{climber_name} conquered {peak_name} whose difficulty level is {peak.difficulty_level}." 82 | 83 | def get_statistics(self) -> str: 84 | climbers_that_can_climb = filter(lambda c: len(c.conquered_peaks) > 0, self.climbers) 85 | climbers = sorted(climbers_that_can_climb, key=lambda c: (-len(c.conquered_peaks), c.name)) 86 | 87 | total_peaks_climbed = len({p for c in climbers for p in c.conquered_peaks}) 88 | 89 | return f"Total climbed peaks: {total_peaks_climbed}\n" + \ 90 | "**Climber's statistics:**\n" + \ 91 | "\n".join(str(c) for c in climbers) 92 | -------------------------------------------------------------------------------- /10_Unit_Testing_Exercise/student/test/test_student.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | from project.student import Student 3 | 4 | 5 | class TestStudent(TestCase): 6 | 7 | def setUp(self): 8 | self.student = Student("Test1") 9 | self.student_with_courses = Student("Test2", {"math": ["x + y = z"]}) 10 | 11 | def test_correct__init__(self): 12 | self.assertEqual("Test1", self.student.name) 13 | self.assertEqual("Test2", self.student_with_courses.name) 14 | 15 | self.assertEqual({}, self.student.courses) 16 | self.assertEqual({"math": ["x + y = z"]}, self.student_with_courses.courses) 17 | 18 | def test_enroll_in_the_same_course_appends_new_notes(self): 19 | result = self.student_with_courses.enroll( 20 | "math", 21 | ["1 + 2 = 3", "3 + 4 = 7"] 22 | ) 23 | 24 | self.assertEqual( 25 | "Course already added. Notes have been updated.", 26 | result 27 | ) 28 | 29 | self.assertEqual( 30 | ["x + y = z", "1 + 2 = 3", "3 + 4 = 7"], 31 | self.student_with_courses.courses["math"] 32 | ) 33 | 34 | def test_enroll_in_new_course_without_third_param_adds_notes_to_the_course(self): 35 | result = self.student.enroll( 36 | "math", 37 | ["x + y = z"] 38 | ) 39 | 40 | self.assertEqual( 41 | "Course and course notes have been added.", 42 | result 43 | ) 44 | 45 | self.assertEqual( 46 | {"math": ["x + y = z"]}th, 47 | self.student.courses 48 | ) 49 | 50 | def test_enroll_in_new_course_with_third_param_Y_adds_notes_to_the_course(self): 51 | result = self.student.enroll( 52 | "math", 53 | ["x + y = z"], 54 | "Y" 55 | ) 56 | 57 | self.assertEqual( 58 | "Course and course notes have been added.", 59 | result 60 | ) 61 | 62 | self.assertEqual( 63 | {"math": ["x + y = z"]}, 64 | self.student.courses 65 | ) 66 | 67 | def test_enroll_in_new_course_with_third_NO_param_does_not_add_the_notes_to_the_course(self): 68 | result = self.student.enroll( 69 | "math", 70 | ["x + y = z"], 71 | "n" 72 | ) 73 | 74 | self.assertEqual( 75 | "Course has been added.", 76 | result 77 | ) 78 | 79 | self.assertEqual( 80 | {"math": []}, 81 | self.student.courses 82 | ) 83 | 84 | def test_add_notes_to_existing_course_expect_success(self): 85 | result = self.student_with_courses.add_notes("math", "1 + 2 = 3") 86 | 87 | self.assertEqual( 88 | "Notes have been updated", 89 | result 90 | ) 91 | self.assertEqual( 92 | ["x + y = z", "1 + 2 = 3"], 93 | self.student_with_courses.courses["math"] 94 | ) 95 | 96 | def test_add_note_to_a_non_existing_course_raises_exception(self): 97 | with self.assertRaises(Exception) as ex: 98 | self.student.add_notes("math", "some note") 99 | 100 | self.assertEqual( 101 | "Cannot add notes. Course not found.", 102 | str(ex.exception) 103 | ) 104 | 105 | def test_leave_existing_course_expect_success(self): 106 | result = self.student_with_courses.leave_course("math") 107 | 108 | self.assertEqual( 109 | {}, 110 | self.student_with_courses.courses 111 | ) 112 | self.assertEqual( 113 | "Course has been removed", 114 | result 115 | ) 116 | 117 | def test_leave_non_existing_course_raises_exception(self): 118 | with self.assertRaises(Exception) as ex: 119 | self.student.leave_course("math") 120 | 121 | self.assertEqual("Cannot remove course. Course not found.", str(ex.exception)) 122 | 123 | 124 | if __name__ == "__main__": 125 | main() 126 | --------------------------------------------------------------------------------