├── a.py ├── asd └── __init__.py ├── solid ├── __init__.py ├── di │ ├── __init__.py │ ├── di_broken.py │ └── di.py ├── isp │ ├── __init__.py │ ├── interface_broken.py │ └── interface.py ├── ocp │ ├── __init__.py │ ├── animal_broken.py │ └── animal.py ├── srp │ ├── __init__.py │ ├── main.py │ ├── books_broken.py │ └── book.py └── liskov │ ├── __init__.py │ ├── liskov.py │ └── liskov_broken.py ├── decorators ├── __init__.py ├── ex_1.py ├── ex_3.py ├── ex_4.py ├── ex_2.py ├── class_as_decorator.py ├── order_of_execution.py └── class_as_decorator_logger.py ├── exam_prep_1 ├── __init__.py ├── ex_3.py ├── ex_1.py └── ex_2.py ├── exam_prep_2 ├── __init__.py ├── ex_3.py ├── ex_1.py ├── ex_3_pets_hotel.py ├── ex_2_delivery_boy.py └── ex_2.py ├── inheritance ├── __init__.py ├── food │ ├── __init__.py │ └── project │ │ ├── __init__.py │ │ ├── main.py │ │ ├── food.py │ │ └── fruit.py ├── single_inheritance │ ├── __init__.py │ ├── project │ │ ├── animal.py │ │ ├── main.py │ │ ├── dog.py │ │ └── __init__.py │ └── project.zip ├── hierarchical_inheritance │ ├── __init__.py │ ├── project │ │ ├── __init__.py │ │ ├── animal.py │ │ ├── cat.py │ │ ├── dog.py │ │ └── main.py │ └── project.zip ├── multilevel_inheritance │ ├── __init__.py │ ├── project │ │ ├── __init__.py │ │ ├── vehicle.py │ │ ├── sports_car.py │ │ ├── car.py │ │ └── main.py │ └── project.zip ├── multiple_inheritance │ ├── __init__.py │ ├── project │ │ ├── __init__.py │ │ ├── person.py │ │ ├── employee.py │ │ ├── main.py │ │ └── teacher.py │ └── project.zip └── stack_of_strings.py ├── My directory ├── __init__.py └── example.txt ├── design_patterns ├── __init__.py ├── ex_1 │ ├── __init__.py │ ├── factories │ │ ├── __init__.py │ │ ├── abstract_furntiture_factory.py │ │ ├── modern_factory.py │ │ └── victorian_factory.py │ ├── furnitures │ │ ├── __init__.py │ │ ├── chair.py │ │ ├── sofa.py │ │ └── table.py │ └── main.py ├── fascade_example.py ├── singleton_example.py ├── decorator_pattern.py └── command_pattern.py ├── encapsulation_ex ├── __init__.py ├── pizza │ ├── __init__.py │ ├── project │ │ ├── __init__.py │ │ ├── topping.py │ │ ├── dough.py │ │ ├── main.py │ │ └── pizza.py │ └── project.zip ├── restaurant │ ├── __init__.py │ ├── project │ │ ├── __init__.py │ │ ├── food │ │ │ ├── __init__.py │ │ │ ├── starter.py │ │ │ ├── main_dish.py │ │ │ ├── soup.py │ │ │ ├── salmon.py │ │ │ ├── cake.py │ │ │ ├── food.py │ │ │ └── dessert.py │ │ ├── beverage │ │ │ ├── __init__.py │ │ │ ├── tea.py │ │ │ ├── hot_beverage.py │ │ │ ├── cold_beverage.py │ │ │ ├── beverage.py │ │ │ └── coffee.py │ │ ├── product.py │ │ └── main.py │ └── project.zip ├── wild_cat_zoo │ ├── __init__.py │ ├── project │ │ ├── __init__.py │ │ ├── vet.py │ │ ├── caretaker.py │ │ ├── keeper.py │ │ ├── lion.py │ │ ├── tiger.py │ │ ├── cheetah.py │ │ ├── worker.py │ │ ├── animal.py │ │ ├── main.py │ │ └── zoo.py │ └── project.zip └── football_team_generator │ ├── __init__.py │ ├── project │ ├── __init__.py │ ├── player.py │ ├── main.py │ └── team.py │ └── project.zip ├── error_handling ├── __init__.py ├── ex_2.py ├── ex_3.py └── ex_1.py ├── file_handling ├── __init__.py ├── resources │ ├── words.txt │ ├── numbers.txt │ ├── text.txt │ └── input.txt ├── my_first_file.txt ├── text.txt ├── ex_3.py ├── ex_2.py ├── ex_4.py ├── ex_1.py └── ex_5.py ├── modules_example ├── __init__.py ├── example_1 │ ├── __init__.py │ ├── first.py │ ├── third.py │ └── second.py ├── fibonacci │ ├── __init__.py │ ├── core.py │ └── main.py ├── triangle │ ├── __init__.py │ ├── main.py │ └── core.py ├── math_operations │ ├── __init__.py │ ├── helpers.py │ ├── actions.py │ ├── main.py │ └── core.py ├── ex_2.py └── ex_1.py ├── tuples_and_sets ├── __init__.py ├── ex_3.py ├── ex_5.py ├── ex_1.py ├── ex_4.py └── ex_2.py ├── classes_and_objects ├── __init__.py ├── ex_3.py ├── ex_1.py ├── ex_2.py ├── ex_4.py └── ex_5.py ├── first_steps_in_oop ├── __init__.py ├── ex_3.py ├── ex_2.py ├── ex_5.py ├── ex_1.py └── ex_4.py ├── functions_advanced ├── __init__.py ├── ex_2.py ├── ex_5.py ├── ex_1.py ├── ex_6.py ├── ex_4.py └── ex_3.py ├── stacks_and_queues ├── __init__.py ├── ex_1.py ├── ex_5.py ├── ex_2.py ├── ex_3.py └── ex_4.py ├── workshop_create_4 ├── __init__.py └── game.py ├── workshop_custom_list ├── __init__.py ├── test │ ├── __init__.py │ └── test_custom_list.py ├── custom_exceptions.py └── custom_list.py ├── exam_prep_divers_amd_tests ├── __init__.py ├── project │ ├── __init__.py │ ├── divers │ │ ├── __init__.py │ │ ├── free_diver.py │ │ ├── scuba_diver.py │ │ └── base_diver.py │ ├── fish │ │ ├── __init__.py │ │ ├── deep_sea_fish.py │ │ ├── predatory_fish.py │ │ └── base_fish.py │ ├── main.py │ └── nautical_catch_challenge_app.py └── exam_part_tests │ ├── __init__.py │ └── project │ ├── __init__.py │ ├── test │ ├── __init__.py │ └── test.py │ └── railway_station.py ├── multidimentional_lists ├── __init__.py ├── ex_5.py ├── ex_3.py ├── ex_4.py ├── ex_6.py ├── ex_2.py ├── ex_1.py └── ex_7.py ├── workshop__custom_dictionary ├── __init__.py ├── test │ ├── __init__.py │ └── test_custom_hashable.py └── custom_hashtable.py ├── my_example.txt ├── requirements.txt ├── my_math.py ├── my_planning.py ├── my_folder └── nested_folder │ └── text.txt ├── example_softuni.xlsx ├── main.py ├── iterators_and_generators ├── ex_4.py ├── ex_6.py ├── ex_5.py ├── ex_2.py ├── ex_1.py ├── __init__.py └── ex_3.py ├── encapsulation ├── __init__.py ├── ex_1.py ├── ex_2.py ├── ex_5.py ├── ex_4.py └── ex_3.py ├── polymorphism_and_abstraction ├── __init__.py ├── ex_3.py ├── ex_2.py ├── ex_4.py └── ex_1.py └── .gitignore /a.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /asd/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /solid/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /decorators/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exam_prep_1/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exam_prep_2/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inheritance/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /solid/di/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /solid/isp/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /solid/ocp/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /solid/srp/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /My directory/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /My directory/example.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /design_patterns/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /encapsulation_ex/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /error_handling/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /file_handling/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inheritance/food/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /modules_example/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /solid/liskov/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tuples_and_sets/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /classes_and_objects/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /design_patterns/ex_1/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /first_steps_in_oop/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /functions_advanced/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /stacks_and_queues/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /workshop_create_4/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /workshop_custom_list/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /encapsulation_ex/pizza/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inheritance/food/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /modules_example/example_1/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /modules_example/fibonacci/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /modules_example/triangle/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /multidimentional_lists/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /workshop_custom_list/test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /design_patterns/ex_1/factories/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /design_patterns/ex_1/furnitures/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /encapsulation_ex/pizza/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /encapsulation_ex/wild_cat_zoo/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inheritance/single_inheritance/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /modules_example/math_operations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /workshop__custom_dictionary/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /file_handling/resources/words.txt: -------------------------------------------------------------------------------- 1 | quick is fault -------------------------------------------------------------------------------- /inheritance/hierarchical_inheritance/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inheritance/multilevel_inheritance/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inheritance/multiple_inheritance/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /workshop__custom_dictionary/test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /encapsulation_ex/football_team_generator/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/food/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /encapsulation_ex/wild_cat_zoo/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/project/divers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/project/fish/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inheritance/multiple_inheritance/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/beverage/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/exam_part_tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inheritance/hierarchical_inheritance/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inheritance/multilevel_inheritance/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /my_example.txt: -------------------------------------------------------------------------------- 1 | Hello! 2 | My name is test!new lineabcabc -------------------------------------------------------------------------------- /encapsulation_ex/football_team_generator/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/exam_part_tests/project/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /file_handling/my_first_file.txt: -------------------------------------------------------------------------------- 1 | I just created my first file! -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pandas==2.2.0 2 | pyfiglet==1.0.2 3 | 4 | -------------------------------------------------------------------------------- /solid/srp/main.py: -------------------------------------------------------------------------------- 1 | from solid.srp.book import Library 2 | 3 | -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/exam_part_tests/project/test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /file_handling/resources/numbers.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 6 | -------------------------------------------------------------------------------- /my_math.py: -------------------------------------------------------------------------------- 1 | def estimate(): 2 | return "Estimating from math..." -------------------------------------------------------------------------------- /file_handling/resources/text.txt: -------------------------------------------------------------------------------- 1 | is - 3 2 | quick - 2 3 | fault - 1 4 | -------------------------------------------------------------------------------- /my_planning.py: -------------------------------------------------------------------------------- 1 | def estimate(): 2 | return "looking at my calendar..." -------------------------------------------------------------------------------- /my_folder/nested_folder/text.txt: -------------------------------------------------------------------------------- 1 | Hello 2 | My name is Test 3 | This is a new line content -------------------------------------------------------------------------------- /workshop_custom_list/custom_exceptions.py: -------------------------------------------------------------------------------- 1 | class EmptyListException(Exception): 2 | pass -------------------------------------------------------------------------------- /example_softuni.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InesIvanova/advanced2024Jan/HEAD/example_softuni.xlsx -------------------------------------------------------------------------------- /file_handling/text.txt: -------------------------------------------------------------------------------- 1 | This is some random line 2 | This is the second line 3 | And this is the third one 4 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | class A: 2 | @staticmethod 3 | def hi(): 4 | return "Hi" 5 | 6 | 7 | print(A.hi()) 8 | -------------------------------------------------------------------------------- /design_patterns/ex_1/furnitures/chair.py: -------------------------------------------------------------------------------- 1 | class Chair: 2 | def __init__(self, _type): 3 | self.type = _type -------------------------------------------------------------------------------- /design_patterns/ex_1/furnitures/sofa.py: -------------------------------------------------------------------------------- 1 | class Sofa: 2 | def __init__(self, _type): 3 | self.type = _type -------------------------------------------------------------------------------- /design_patterns/ex_1/furnitures/table.py: -------------------------------------------------------------------------------- 1 | class Table: 2 | def __init__(self, _type): 3 | self.type = _type -------------------------------------------------------------------------------- /file_handling/ex_3.py: -------------------------------------------------------------------------------- 1 | with open("my_first_file.txt", "a") as file: 2 | file.write("I just created my first file!") -------------------------------------------------------------------------------- /inheritance/single_inheritance/project/animal.py: -------------------------------------------------------------------------------- 1 | class Animal: 2 | def eat(self): 3 | return f"eating..." -------------------------------------------------------------------------------- /encapsulation_ex/wild_cat_zoo/project/vet.py: -------------------------------------------------------------------------------- 1 | from project.worker import Worker 2 | 3 | 4 | class Vet(Worker): 5 | pass -------------------------------------------------------------------------------- /inheritance/hierarchical_inheritance/project/animal.py: -------------------------------------------------------------------------------- 1 | class Animal: 2 | def eat(self): 3 | return "eating..." -------------------------------------------------------------------------------- /inheritance/multilevel_inheritance/project/vehicle.py: -------------------------------------------------------------------------------- 1 | class Vehicle: 2 | def move(self): 3 | return "moving..." -------------------------------------------------------------------------------- /inheritance/multiple_inheritance/project/person.py: -------------------------------------------------------------------------------- 1 | class Person: 2 | def sleep(self): 3 | return "sleeping..." -------------------------------------------------------------------------------- /modules_example/ex_2.py: -------------------------------------------------------------------------------- 1 | from pyfiglet import figlet_format 2 | 3 | text = input() 4 | 5 | print(figlet_format(text)) 6 | 7 | -------------------------------------------------------------------------------- /encapsulation_ex/pizza/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InesIvanova/advanced2024Jan/HEAD/encapsulation_ex/pizza/project.zip -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/food/starter.py: -------------------------------------------------------------------------------- 1 | from project.food.food import Food 2 | 3 | 4 | class Starter(Food): 5 | pass -------------------------------------------------------------------------------- /inheritance/food/project/main.py: -------------------------------------------------------------------------------- 1 | from project.fruit import Fruit 2 | 3 | fruit = Fruit("banana", "2024-03-01") 4 | print(fruit.name) -------------------------------------------------------------------------------- /inheritance/multiple_inheritance/project/employee.py: -------------------------------------------------------------------------------- 1 | class Employee: 2 | def get_fired(self): 3 | return "fired..." 4 | -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/food/main_dish.py: -------------------------------------------------------------------------------- 1 | from project.food.food import Food 2 | 3 | 4 | class MainDish(Food): 5 | pass -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/food/soup.py: -------------------------------------------------------------------------------- 1 | from project.food.starter import Starter 2 | 3 | 4 | class Soup(Starter): 5 | pass -------------------------------------------------------------------------------- /encapsulation_ex/wild_cat_zoo/project/caretaker.py: -------------------------------------------------------------------------------- 1 | from project.worker import Worker 2 | 3 | 4 | class Caretaker(Worker): 5 | pass -------------------------------------------------------------------------------- /encapsulation_ex/wild_cat_zoo/project/keeper.py: -------------------------------------------------------------------------------- 1 | from project.worker import Worker 2 | 3 | 4 | class Keeper(Worker): 5 | pass 6 | -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InesIvanova/advanced2024Jan/HEAD/encapsulation_ex/restaurant/project.zip -------------------------------------------------------------------------------- /inheritance/food/project/food.py: -------------------------------------------------------------------------------- 1 | class Food: 2 | def __init__(self, expiration_date): 3 | self.expiration_date = expiration_date -------------------------------------------------------------------------------- /inheritance/single_inheritance/project/main.py: -------------------------------------------------------------------------------- 1 | from project.dog import Dog 2 | 3 | dog = Dog() 4 | 5 | print(dog.bark()) 6 | print(dog.eat()) -------------------------------------------------------------------------------- /encapsulation_ex/wild_cat_zoo/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InesIvanova/advanced2024Jan/HEAD/encapsulation_ex/wild_cat_zoo/project.zip -------------------------------------------------------------------------------- /inheritance/single_inheritance/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InesIvanova/advanced2024Jan/HEAD/inheritance/single_inheritance/project.zip -------------------------------------------------------------------------------- /inheritance/multiple_inheritance/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InesIvanova/advanced2024Jan/HEAD/inheritance/multiple_inheritance/project.zip -------------------------------------------------------------------------------- /modules_example/triangle/main.py: -------------------------------------------------------------------------------- 1 | from modules_example.triangle.core import print_triangle 2 | 3 | 4 | n = int(input()) 5 | 6 | 7 | print_triangle(n) -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/beverage/tea.py: -------------------------------------------------------------------------------- 1 | from project.beverage.hot_beverage import HotBeverage 2 | 3 | 4 | class Tea(HotBeverage): 5 | pass -------------------------------------------------------------------------------- /inheritance/multilevel_inheritance/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InesIvanova/advanced2024Jan/HEAD/inheritance/multilevel_inheritance/project.zip -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/beverage/hot_beverage.py: -------------------------------------------------------------------------------- 1 | from project.beverage.beverage import Beverage 2 | 3 | 4 | class HotBeverage(Beverage): 5 | pass -------------------------------------------------------------------------------- /functions_advanced/ex_2.py: -------------------------------------------------------------------------------- 1 | def get_info(*args): 2 | return f"This is {name} from {town} and he is {age} years old" 3 | 4 | 5 | print(get_info(3.6, "string")) -------------------------------------------------------------------------------- /inheritance/hierarchical_inheritance/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InesIvanova/advanced2024Jan/HEAD/inheritance/hierarchical_inheritance/project.zip -------------------------------------------------------------------------------- /inheritance/hierarchical_inheritance/project/cat.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | class Cat(Animal): 3 | def meow(self): 4 | return "meowing..." -------------------------------------------------------------------------------- /encapsulation_ex/football_team_generator/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InesIvanova/advanced2024Jan/HEAD/encapsulation_ex/football_team_generator/project.zip -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/beverage/cold_beverage.py: -------------------------------------------------------------------------------- 1 | from project.beverage.beverage import Beverage 2 | 3 | 4 | class ColdBeverage(Beverage): 5 | pass -------------------------------------------------------------------------------- /file_handling/resources/input.txt: -------------------------------------------------------------------------------- 1 | -I was quick to judge him, but it wasn't his fault. 2 | -Is this some kind of joke?! Is it? 3 | -Quick, hide here…It is safer. 4 | -------------------------------------------------------------------------------- /inheritance/multilevel_inheritance/project/sports_car.py: -------------------------------------------------------------------------------- 1 | from project.car import Car 2 | class SportsCar(Car): 3 | def race(self): 4 | return "racing..." -------------------------------------------------------------------------------- /inheritance/single_inheritance/project/dog.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | 4 | class Dog(Animal): 5 | def bark(self): 6 | return "barking..." -------------------------------------------------------------------------------- /inheritance/hierarchical_inheritance/project/dog.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | 4 | class Dog(Animal): 5 | def bark(self): 6 | return "barking..." -------------------------------------------------------------------------------- /inheritance/multilevel_inheritance/project/car.py: -------------------------------------------------------------------------------- 1 | from project.vehicle import Vehicle 2 | 3 | class Car(Vehicle): 4 | def drive(self): 5 | return "driving..." -------------------------------------------------------------------------------- /inheritance/multiple_inheritance/project/main.py: -------------------------------------------------------------------------------- 1 | from project.teacher import Teacher 2 | 3 | t = Teacher() 4 | 5 | print(t.sleep()) 6 | print(t.get_fired()) 7 | print(t.teach()) -------------------------------------------------------------------------------- /inheritance/multilevel_inheritance/project/main.py: -------------------------------------------------------------------------------- 1 | from project.sports_car import SportsCar 2 | 3 | sc = SportsCar() 4 | print(sc.race()) 5 | print(sc.drive()) 6 | print(sc.move()) -------------------------------------------------------------------------------- /error_handling/ex_2.py: -------------------------------------------------------------------------------- 1 | text = input() 2 | 3 | try: 4 | times = int(input()) 5 | print(text*times) 6 | except ValueError: 7 | print("Variable times must be an integer") 8 | 9 | -------------------------------------------------------------------------------- /decorators/ex_1.py: -------------------------------------------------------------------------------- 1 | def number_increment(numbers): 2 | def increase(): 3 | return [el+1 for el in numbers] 4 | 5 | return increase() 6 | 7 | 8 | print(number_increment([1, 2, 3])) -------------------------------------------------------------------------------- /tuples_and_sets/ex_3.py: -------------------------------------------------------------------------------- 1 | n = int(input()) 2 | 3 | names = set() 4 | 5 | for _ in range(n): 6 | name = input() 7 | names.add(name) 8 | 9 | for name in names: 10 | print(name) -------------------------------------------------------------------------------- /error_handling/ex_3.py: -------------------------------------------------------------------------------- 1 | class ValueCannotBeNegative(Exception): 2 | pass 3 | 4 | 5 | for _ in range(5): 6 | number = int(input()) 7 | 8 | if number < 0: 9 | raise ValueCannotBeNegative -------------------------------------------------------------------------------- /functions_advanced/ex_5.py: -------------------------------------------------------------------------------- 1 | def recursive_power(number, power): 2 | if power == 1: 3 | return number 4 | return number * recursive_power(number, power-1) 5 | 6 | print(recursive_power(2, 3)) -------------------------------------------------------------------------------- /iterators_and_generators/ex_4.py: -------------------------------------------------------------------------------- 1 | def squares(n): 2 | current = 1 3 | while current <= n: 4 | yield current ** 2 5 | current += 1 6 | 7 | 8 | for el in squares(5): 9 | print(el) -------------------------------------------------------------------------------- /modules_example/example_1/first.py: -------------------------------------------------------------------------------- 1 | def print_hello(): 2 | print("Hello") 3 | 4 | def a(): 5 | print("a") 6 | 7 | 8 | def b(): 9 | print("b") 10 | 11 | 12 | print('from first file') -------------------------------------------------------------------------------- /inheritance/food/project/fruit.py: -------------------------------------------------------------------------------- 1 | from project.food import Food 2 | 3 | 4 | class Fruit(Food): 5 | def __init__(self, name, expiration_date): 6 | self.name = name 7 | super().__init__( expiration_date) 8 | -------------------------------------------------------------------------------- /encapsulation_ex/wild_cat_zoo/project/lion.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | 4 | class Lion(Animal): 5 | def __init__(self, name: str, gender: str, age: int) -> None: 6 | super().__init__(name, gender, age, 50) -------------------------------------------------------------------------------- /encapsulation_ex/wild_cat_zoo/project/tiger.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | 4 | class Tiger(Animal): 5 | def __init__(self, name: str, gender: str, age: int) -> None: 6 | super().__init__(name, gender, age, 45) -------------------------------------------------------------------------------- /modules_example/ex_1.py: -------------------------------------------------------------------------------- 1 | from math import log 2 | 3 | 4 | number = int(input()) 5 | 6 | try: 7 | base = int(input()) 8 | print(f"{log(number, base):.2f}") 9 | except ValueError: 10 | print(f"{log(number):.2f}") 11 | -------------------------------------------------------------------------------- /encapsulation_ex/wild_cat_zoo/project/cheetah.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | 4 | class Cheetah(Animal): 5 | def __init__(self, name: str, gender: str, age: int) -> None: 6 | super().__init__(name, gender, age, 60) -------------------------------------------------------------------------------- /encapsulation/__init__.py: -------------------------------------------------------------------------------- 1 | class A: 2 | def say(self): 3 | return "A" 4 | 5 | class B(A): 6 | def say(self): 7 | return f"{super().say()} B" 8 | 9 | b = B() 10 | print(b.__class__.__base__.say(b)) 11 | 12 | 13 | -------------------------------------------------------------------------------- /modules_example/example_1/third.py: -------------------------------------------------------------------------------- 1 | from random import shuffle as rand_shuffle 2 | import os 3 | import sys 4 | 5 | def shuffle(a): 6 | print("Hiii") 7 | 8 | fruits = ["apple", "banana", "cherry"] 9 | 10 | print(choice(fruits)) 11 | -------------------------------------------------------------------------------- /inheritance/hierarchical_inheritance/project/main.py: -------------------------------------------------------------------------------- 1 | from project.cat import Cat 2 | from project.dog import Dog 3 | 4 | d = Dog() 5 | c = Cat() 6 | 7 | print(d.eat()) 8 | print(c.eat()) 9 | print(d.bark()) 10 | print(c.meow()) 11 | print(d.meow()) -------------------------------------------------------------------------------- /modules_example/example_1/second.py: -------------------------------------------------------------------------------- 1 | from modules_example.example_1.first import print_hello, a 2 | 3 | 4 | def custom_function(): 5 | print("custom") 6 | 7 | 8 | 9 | print_hello() 10 | custom_function() 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/food/salmon.py: -------------------------------------------------------------------------------- 1 | from project.food.main_dish import MainDish 2 | 3 | 4 | class Salmon(MainDish): 5 | GRAMS = 22 6 | 7 | def __init__(self, name: str, price: float): 8 | super().__init__(name, price, Salmon.GRAMS) -------------------------------------------------------------------------------- /functions_advanced/ex_1.py: -------------------------------------------------------------------------------- 1 | def multiply(*args): 2 | result = 1 3 | for el in args: 4 | result *= el 5 | return result 6 | 7 | 8 | print(multiply(1, 4, 5)) 9 | print(multiply(4, 5, 6, 1, 3)) 10 | print(multiply(2, 0, 1000, 5000)) 11 | -------------------------------------------------------------------------------- /modules_example/math_operations/helpers.py: -------------------------------------------------------------------------------- 1 | from modules_example.math_operations.core import add, subtract, divide, multiply, power 2 | 3 | sign_mapper = { 4 | "+": add, 5 | "-": subtract, 6 | "/": divide, 7 | "*": multiply, 8 | "^": power 9 | } -------------------------------------------------------------------------------- /iterators_and_generators/ex_6.py: -------------------------------------------------------------------------------- 1 | def reverse_text(string: str): 2 | current_index = len(string) -1 3 | while current_index >= 0: 4 | yield string[current_index] 5 | current_index -= 1 6 | 7 | 8 | for char in reverse_text("step"): 9 | print(char, end='') 10 | -------------------------------------------------------------------------------- /functions_advanced/ex_6.py: -------------------------------------------------------------------------------- 1 | from functools import reduce 2 | 3 | def operate(operator, *args): 4 | if 0 in args and operator == "-": 5 | return 6 | return reduce(lambda x,y: eval(f"{x}{operator}{y}"), args) 7 | 8 | 9 | print(operate("+", 1, 2, 3)) 10 | print(operate("*", 3, 4)) -------------------------------------------------------------------------------- /solid/srp/books_broken.py: -------------------------------------------------------------------------------- 1 | class Book: 2 | def __init__(self, title, author, location): 3 | self.title = title 4 | self.author = author 5 | self.location = location 6 | self.page = 0 7 | 8 | def turn_page(self, page): 9 | self.page = page 10 | 11 | -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/food/cake.py: -------------------------------------------------------------------------------- 1 | from project.food.dessert import Dessert 2 | 3 | 4 | class Cake(Dessert): 5 | GRAMS = 250 6 | CALORIES = 1000 7 | PRICE = 5 8 | 9 | def __init__(self, name: str): 10 | super().__init__(name, Cake.PRICE, Cake.GRAMS, Cake.CALORIES) -------------------------------------------------------------------------------- /file_handling/ex_2.py: -------------------------------------------------------------------------------- 1 | import os.path 2 | 3 | path = os.path.join("resources", "numbers.txt") 4 | 5 | file = open(path) 6 | 7 | total_amount = 0 8 | lines = file.readlines() 9 | file.close() 10 | 11 | 12 | for line in lines: 13 | total_amount += int(line.strip()) 14 | 15 | print(total_amount) -------------------------------------------------------------------------------- /modules_example/math_operations/actions.py: -------------------------------------------------------------------------------- 1 | from modules_example.math_operations.helpers import sign_mapper 2 | 3 | 4 | def execute_expression(exp): 5 | num1_text, sign, num2_text = exp.split() 6 | num1 = float(num1_text) 7 | num2 = float(num2_text) 8 | 9 | return sign_mapper[sign](num1, num2) -------------------------------------------------------------------------------- /multidimentional_lists/ex_5.py: -------------------------------------------------------------------------------- 1 | row = int(input()) 2 | 3 | matrix = [] 4 | 5 | for _ in range(row): 6 | matrix.append([int(el) for el in input().split()]) 7 | 8 | 9 | diagonal_sum = 0 10 | for row_index in range(row): 11 | diagonal_sum += matrix[row_index][row_index] 12 | print(diagonal_sum) -------------------------------------------------------------------------------- /stacks_and_queues/ex_1.py: -------------------------------------------------------------------------------- 1 | text = list(input()) 2 | 3 | 4 | def some_func(a,b): 5 | return None 6 | 7 | while text: 8 | print(text.pop(), end="") 9 | 10 | 11 | a = [10, 5, 3, 100] 12 | 13 | n_ro_remove = 3 14 | 15 | for _ in range(n_ro_remove): 16 | a.pop() 17 | 18 | print(a) 19 | 20 | -------------------------------------------------------------------------------- /error_handling/ex_1.py: -------------------------------------------------------------------------------- 1 | numbers_list = [int(el) for el in input().split(", ")] 2 | result = 1 3 | 4 | for i in range(len(numbers_list)): 5 | number = numbers_list[i] 6 | if number <= 5: 7 | result *= number 8 | elif 5 < number <= 10: 9 | result /= number 10 | 11 | print(result) 12 | -------------------------------------------------------------------------------- /inheritance/multiple_inheritance/project/teacher.py: -------------------------------------------------------------------------------- 1 | from project.person import Person 2 | from project.employee import Employee 3 | 4 | 5 | class Teacher(Person, Employee): 6 | def teach(self): 7 | return "teaching..." 8 | 9 | def some_method(self): 10 | return f"{Person.sleep(self)} + something else" 11 | -------------------------------------------------------------------------------- /stacks_and_queues/ex_5.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | names = deque(input().split()) 4 | n_toss = int(input()) - 1 5 | 6 | while len(names) > 1: 7 | names.rotate(-n_toss) 8 | removed_kid = names.popleft() 9 | print(f"Removed {removed_kid}") 10 | 11 | print(f"Last is {names.popleft()}") 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /decorators/ex_3.py: -------------------------------------------------------------------------------- 1 | def even_numbers(function): 2 | def wrapper(*args, **kwargs): 3 | result = [el for el in args if el % 2 ==0] 4 | return function(result) 5 | return wrapper 6 | 7 | 8 | @even_numbers 9 | def get_numbers(numbers): 10 | return numbers 11 | 12 | 13 | print(get_numbers([1, 2, 3, 4, 5])) 14 | -------------------------------------------------------------------------------- /encapsulation_ex/wild_cat_zoo/project/worker.py: -------------------------------------------------------------------------------- 1 | class Worker: 2 | def __init__(self, name: str, age: int, salary: int) -> None: 3 | self.name = name 4 | self.age = age 5 | self.salary = salary 6 | 7 | def __repr__(self) -> str: 8 | return f"Name: {self.name}, Age: {self.age}, Salary: {self.salary}" 9 | -------------------------------------------------------------------------------- /file_handling/ex_4.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | path = os.path.join("resources", "just_created.txt") 4 | 5 | try: 6 | os.remove(path) 7 | except FileNotFoundError: 8 | print("File is already deleted") 9 | 10 | 11 | if os.path.exists(path): 12 | os.remove(path) 13 | else: 14 | print("File is already deleted") 15 | 16 | 17 | -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/food/food.py: -------------------------------------------------------------------------------- 1 | from project.product import Product 2 | 3 | 4 | class Food(Product): 5 | def __init__(self, name: str, price: float, grams: float): 6 | super().__init__(name, price) 7 | self.__grams = grams 8 | 9 | @property 10 | def grams(self): 11 | return self.__grams -------------------------------------------------------------------------------- /first_steps_in_oop/ex_3.py: -------------------------------------------------------------------------------- 1 | def some_func(): 2 | x = 5 3 | 4 | 5 | class Book: 6 | def __init__(self, name, author, pages): 7 | self.name = name 8 | self.author = author 9 | self.pages = pages 10 | 11 | 12 | 13 | book = Book("My Book", "Me", 200) 14 | book2 = Book("Test", "Me", 400) 15 | a = 5 16 | 17 | -------------------------------------------------------------------------------- /iterators_and_generators/ex_5.py: -------------------------------------------------------------------------------- 1 | def nums_recursion(n): 2 | if n <= 0: 3 | return 1 4 | return nums_recursion(n - 1) 5 | 6 | print(nums_recursion(5)) 7 | 8 | 9 | 10 | def genrange(start, end): 11 | while start <= end: 12 | yield start 13 | start += 1 14 | 15 | 16 | print(list(genrange(1, 10))) 17 | -------------------------------------------------------------------------------- /modules_example/math_operations/main.py: -------------------------------------------------------------------------------- 1 | from math import floor 2 | 3 | from modules_example.math_operations.actions import execute_expression 4 | 5 | 6 | def truncate(f, n): 7 | return floor(f * 10 ** n) / 10 ** n 8 | 9 | 10 | expression = input() 11 | 12 | result = execute_expression(expression) 13 | print(f"{truncate(result, 2)}") -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/product.py: -------------------------------------------------------------------------------- 1 | class Product: 2 | def __init__(self, name: str, price: float) -> None: 3 | self.__name = name 4 | self.__price = price 5 | 6 | @property 7 | def name(self): 8 | return self.__name 9 | 10 | @property 11 | def price(self): 12 | return self.__price 13 | -------------------------------------------------------------------------------- /tuples_and_sets/ex_5.py: -------------------------------------------------------------------------------- 1 | n = int(input()) 2 | 3 | codes = set() 4 | 5 | for _ in range(n): 6 | code = input() 7 | codes.add(code) 8 | 9 | 10 | code = input() 11 | while code != "END": 12 | if code in codes: 13 | codes.remove(code) 14 | code = input() 15 | 16 | print(len(codes)) 17 | for code in sorted(codes): 18 | print(code) -------------------------------------------------------------------------------- /design_patterns/ex_1/factories/abstract_furntiture_factory.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class AbstractFactory(ABC): 5 | @abstractmethod 6 | def create_sofa(self): 7 | pass 8 | 9 | @abstractmethod 10 | def create_chair(self): 11 | pass 12 | 13 | @abstractmethod 14 | def create_table(self): 15 | pass -------------------------------------------------------------------------------- /file_handling/ex_1.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | ABSOLUTE_DIR_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") 5 | file_name = "text.txt" 6 | path = os.path.join("..", "..", "nested_folder", file_name) 7 | 8 | 9 | try: 10 | file = open("text.txt", "r") 11 | print("File found") 12 | except FileNotFoundError: 13 | print("File is not found") -------------------------------------------------------------------------------- /modules_example/math_operations/core.py: -------------------------------------------------------------------------------- 1 | def add(num1, num2): 2 | return num1 + num2 3 | 4 | 5 | def subtract(num1, num2): 6 | return num1 - num2 7 | 8 | 9 | def divide(num1, num2): 10 | return num1 / num2 11 | 12 | 13 | def multiply(num1, num2): 14 | return num1 * num2 15 | 16 | 17 | def power(num1, num2): 18 | return num1 ** num2 19 | 20 | -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/food/dessert.py: -------------------------------------------------------------------------------- 1 | from project.food.food import Food 2 | 3 | 4 | class Dessert(Food): 5 | def __init__(self, name: str, price: float, grams: float, calories: float): 6 | super().__init__(name, price, grams) 7 | self.__calories = calories 8 | 9 | @property 10 | def calories(self): 11 | return self.__calories -------------------------------------------------------------------------------- /multidimentional_lists/ex_3.py: -------------------------------------------------------------------------------- 1 | row = int(input()) 2 | 3 | flatten = [] 4 | for i in range(row): 5 | row_data = [int(el) for el in input().split(", ")] 6 | flatten.extend(row_data) 7 | print(flatten) 8 | 9 | 10 | # flatten = [] 11 | # for row in matrix: 12 | # for el in row: 13 | # flatten.append(el) 14 | # 15 | # flatten = [el for row in matrix for el in row] 16 | -------------------------------------------------------------------------------- /stacks_and_queues/ex_2.py: -------------------------------------------------------------------------------- 1 | expression = input() 2 | paren_indexes = [] 3 | 4 | for index in range(0, len(expression)): 5 | if expression[index] == "(": 6 | paren_indexes.append(index) 7 | elif expression[index] == ")": 8 | start_index = paren_indexes.pop() 9 | end_index = index + 1 10 | print(expression[start_index:end_index]) 11 | 12 | 13 | -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/beverage/beverage.py: -------------------------------------------------------------------------------- 1 | from project.product import Product 2 | 3 | 4 | class Beverage(Product): 5 | def __init__(self, name: str, price: float, milliliters: float) -> None: 6 | super().__init__(name, price) 7 | self.__milliliters = milliliters 8 | 9 | @property 10 | def milliliters(self): 11 | return self.__milliliters 12 | -------------------------------------------------------------------------------- /decorators/ex_4.py: -------------------------------------------------------------------------------- 1 | def multiply(a, *nums): 2 | def decorator(ref_func): 3 | def wrapper(*args, **kwargs): 4 | result = ref_func(*args, **kwargs) 5 | return [result*el for el in nums] 6 | return wrapper 7 | return decorator 8 | 9 | @multiply(1, 2,3) 10 | def sum_nums(num_1, num_2, ): 11 | return num_1 + num_2 12 | 13 | print(sum_nums(1,num_2 =2)) -------------------------------------------------------------------------------- /encapsulation_ex/wild_cat_zoo/project/animal.py: -------------------------------------------------------------------------------- 1 | class Animal: 2 | def __init__(self, name: str, gender: str, age: int, money_for_care: int) -> None: 3 | self.name = name 4 | self.gender = gender 5 | self.age = age 6 | self.money_for_care = money_for_care 7 | 8 | def __repr__(self) -> str: 9 | return f"Name: {self.name}, Age: {self.age}, Gender: {self.gender}" -------------------------------------------------------------------------------- /solid/di/di_broken.py: -------------------------------------------------------------------------------- 1 | class Book: 2 | def __init__(self, content: str): 3 | self.content = content 4 | 5 | 6 | class Formatter: 7 | def format(self, book: Book) -> str: 8 | return book.content 9 | 10 | 11 | class Printer: 12 | def get_book(self, book: Book): 13 | formatter = Formatter() 14 | formatted_book = formatter.format(book) 15 | return formatted_book -------------------------------------------------------------------------------- /modules_example/fibonacci/core.py: -------------------------------------------------------------------------------- 1 | def create_sequence(n): 2 | seq = [0, 1] 3 | 4 | for _ in range(n - 2): 5 | next_num = seq[-1] + seq[-2] 6 | seq.append(next_num) 7 | 8 | return seq 9 | 10 | 11 | def locate_number(number, seq): 12 | try: 13 | return seq.index(number) 14 | except ValueError: 15 | return f"The number {number} is not in the sequence" 16 | 17 | -------------------------------------------------------------------------------- /decorators/ex_2.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | 3 | 4 | def vowel_filter(function): 5 | def wrapper(*args, **kwargs): 6 | result = function(*args, **kwargs) 7 | return [el for el in result if el.lower() in 'aeyoui'] 8 | return wrapper 9 | 10 | @vowel_filter 11 | def get_letters(): 12 | """some docs here""" 13 | return ["a", "b", "c", "d", "e"] 14 | 15 | print(get_letters()) 16 | -------------------------------------------------------------------------------- /multidimentional_lists/ex_4.py: -------------------------------------------------------------------------------- 1 | row, col = [int(el) for el in input().split(", ")] 2 | 3 | matrix = [] 4 | print(matrix) 5 | for _ in range(row): 6 | row_nums = [int(el) for el in input().split()] 7 | matrix.append(row_nums) 8 | 9 | 10 | for col_index in range(col): 11 | col_total = 0 12 | for row_index in range(row): 13 | col_total += matrix[row_index][col_index] 14 | print(col_total) 15 | -------------------------------------------------------------------------------- /tuples_and_sets/ex_1.py: -------------------------------------------------------------------------------- 1 | def print_nums(nums): 2 | print(nums) 3 | 4 | a = [1,2,3] 5 | print_nums(tuple(a)) 6 | 7 | 8 | 9 | numbers = tuple([float(el) for el in input().split()]) 10 | 11 | 12 | same_values = {} 13 | 14 | for num in numbers: 15 | if num not in same_values: 16 | same_values[num] = numbers.count(num) 17 | 18 | for number, occ in same_values.items(): 19 | print(f"{number} - {occ} times") -------------------------------------------------------------------------------- /functions_advanced/ex_4.py: -------------------------------------------------------------------------------- 1 | def rectangle(length, width): 2 | if not isinstance(length, int) or not isinstance(width, int): 3 | return "Enter valid values!" 4 | 5 | def area(): 6 | return length * width 7 | 8 | def perimeter(): 9 | return 2*(length + width) 10 | 11 | return f"Rectangle area: {area()}\nRectangle perimeter: {perimeter()}" 12 | 13 | print(rectangle(2, 10)) 14 | print(rectangle('2', 10)) -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/beverage/coffee.py: -------------------------------------------------------------------------------- 1 | from project.beverage.hot_beverage import HotBeverage 2 | 3 | 4 | class Coffee(HotBeverage): 5 | MILLILITERS = 50 6 | PRICE = 3.50 7 | 8 | def __init__(self, name: str, caffeine: float): 9 | super().__init__(name, Coffee.PRICE, Coffee.MILLILITERS) 10 | self.__caffeine = caffeine 11 | 12 | @property 13 | def caffeine(self): 14 | return self.__caffeine -------------------------------------------------------------------------------- /first_steps_in_oop/ex_2.py: -------------------------------------------------------------------------------- 1 | x = "global" 2 | 3 | 4 | def outer(): 5 | x = "local" 6 | 7 | def inner(): 8 | nonlocal x 9 | x = "nonlocal" 10 | print("inner:", x) 11 | 12 | def change_global(): 13 | global x 14 | x = "global: changed!" 15 | 16 | print("outer:", x) 17 | inner() 18 | print("outer:", x) 19 | change_global() 20 | 21 | 22 | print(x) 23 | outer() 24 | print(x) 25 | -------------------------------------------------------------------------------- /first_steps_in_oop/ex_5.py: -------------------------------------------------------------------------------- 1 | class Engine: 2 | def __init__(self): 3 | pass 4 | 5 | 6 | class Car: 7 | def __init__(self, engine): 8 | self.engine = engine 9 | 10 | 11 | class Music(object): 12 | def __init__(self, length: int, name: str): 13 | self.length = length 14 | 15 | 16 | song = Music(30) 17 | song.asd = "Test" 18 | 19 | song2 = Music(30) 20 | 21 | print(song.asd) 22 | print(song2.asd) 23 | 24 | 25 | -------------------------------------------------------------------------------- /modules_example/triangle/core.py: -------------------------------------------------------------------------------- 1 | def print_triangle(n): 2 | print_top(n) 3 | print_bottom(n) 4 | 5 | 6 | def print_top(n): 7 | for row in range(1, n + 1): 8 | for num in range(1, row + 1): 9 | print(num, end=" ") 10 | print() 11 | 12 | 13 | def print_bottom(n): 14 | for row in range(n-1, -1, -1): 15 | for num in range(1, row+1): 16 | print(num, end=" ") 17 | print() 18 | 19 | -------------------------------------------------------------------------------- /design_patterns/ex_1/main.py: -------------------------------------------------------------------------------- 1 | from design_patterns.ex_1.factories.modern_factory import ModernFactory 2 | from design_patterns.ex_1.factories.victorian_factory import VictorianFactory 3 | 4 | factory = VictorianFactory() 5 | 6 | print(factory.create_sofa()) 7 | print(factory.create_table()) 8 | print(factory.create_sofa()) 9 | print(factory.create_chair()) 10 | 11 | 12 | modern_factory = ModernFactory() 13 | print(modern_factory.create_table()) 14 | 15 | -------------------------------------------------------------------------------- /tuples_and_sets/ex_4.py: -------------------------------------------------------------------------------- 1 | n = int(input()) 2 | 3 | cars = set() 4 | 5 | for _ in range(n): 6 | data = input().split(", ") 7 | direction, car_number = data 8 | 9 | if direction == "IN": 10 | cars.add(car_number) 11 | elif direction == "OUT": 12 | if car_number in cars: 13 | cars.remove(car_number) 14 | 15 | if cars: 16 | for car in cars: 17 | print(car) 18 | else: 19 | print("Parking Lot is Empty") -------------------------------------------------------------------------------- /multidimentional_lists/ex_6.py: -------------------------------------------------------------------------------- 1 | n = int(input()) 2 | 3 | matrix = [] 4 | 5 | for _ in range(n): 6 | matrix.append(list(input())) 7 | 8 | searched_element = input() 9 | 10 | for row_index in range(n): 11 | for col_index in range(len(matrix[row_index])): 12 | if matrix[row_index][col_index] == searched_element: 13 | print(f"({row_index}, {col_index})") 14 | exit() 15 | 16 | print(f"{searched_element} does not occur in the matrix") 17 | 18 | -------------------------------------------------------------------------------- /encapsulation/ex_1.py: -------------------------------------------------------------------------------- 1 | class Person: 2 | def __init__(self, name, age): 3 | self._name = name 4 | self.__age = age 5 | 6 | def get_age(self): 7 | return self.__age 8 | 9 | 10 | def get_name(self): 11 | return self._name 12 | 13 | 14 | class Student(Person): 15 | def say_something(self): 16 | return f"{self._name}" 17 | 18 | 19 | person = Person("George", 32) 20 | s = Student("George", 32) 21 | print(hasattr(s, "_name")) 22 | -------------------------------------------------------------------------------- /stacks_and_queues/ex_3.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | import time 3 | name = input() 4 | 5 | customers = deque() 6 | 7 | start_time = time.time() 8 | 9 | 10 | while name != "End": 11 | if name == "Paid": 12 | while customers: 13 | print(customers.popleft()) 14 | else: 15 | customers.append(name) 16 | name = input() 17 | 18 | 19 | print(f"{len(customers)} people remaining.") 20 | 21 | print("--- %s seconds ---" % (time.time() - start_time)) 22 | -------------------------------------------------------------------------------- /polymorphism_and_abstraction/__init__.py: -------------------------------------------------------------------------------- 1 | class Pizza: 2 | def __init__(self, ingredients): 3 | self.ingredients = ingredients 4 | 5 | @classmethod 6 | def create_pepperoni(cls): 7 | return cls(["pepperoni", "tomato", "cheese"]) 8 | 9 | @classmethod 10 | def create_margarita(cls): 11 | return cls(["cheese2", "tomato", "cheese"]) 12 | 13 | 14 | pizza = Pizza(['1', '2', '3']) 15 | margarita = Pizza.create_margarita() 16 | print(margarita) 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /design_patterns/fascade_example.py: -------------------------------------------------------------------------------- 1 | class PaymentManager: 2 | def pay(self): 3 | self.create_payment_account() 4 | self.check_funds() 5 | self.create_tranaction() 6 | self.release_funds() 7 | 8 | def create_payment_account(self): 9 | pass 10 | 11 | def create_tranaction(self): 12 | pass 13 | 14 | 15 | def check_funds(self): 16 | pass 17 | 18 | def release_funds(self): 19 | pass 20 | 21 | 22 | pm = PaymentManager() 23 | print(pm.pay()) -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/project/fish/deep_sea_fish.py: -------------------------------------------------------------------------------- 1 | from project.fish.base_fish import BaseFish 2 | 3 | 4 | class DeepSeaFish(BaseFish): 5 | TIME_TO_CATCH = 180 6 | 7 | def __init__(self, name: str, points: float): 8 | super().__init__(name, points, DeepSeaFish.TIME_TO_CATCH) 9 | 10 | def fish_details(self): 11 | return (f"{self.__class__.__name__}: {self.name} " 12 | f"[Points: {self.points}, " 13 | f"Time to Catch: {self.time_to_catch} seconds]") 14 | -------------------------------------------------------------------------------- /classes_and_objects/ex_3.py: -------------------------------------------------------------------------------- 1 | class Circle: 2 | pi = 3.14 3 | def __init__(self, radius): 4 | self.radius = radius 5 | 6 | def set_radius(self, new_radius): 7 | self.radius = new_radius 8 | 9 | def get_area(self): 10 | return Circle.pi * self.radius * self.radius 11 | 12 | def get_circumference(self): 13 | return 2 * Circle.pi * self.radius 14 | 15 | 16 | circle = Circle(10) 17 | circle.set_radius(12) 18 | print(circle.get_area()) 19 | print(circle.get_circumference()) 20 | -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/project/fish/predatory_fish.py: -------------------------------------------------------------------------------- 1 | from project.fish.base_fish import BaseFish 2 | 3 | 4 | class PredatoryFish(BaseFish): 5 | TIME_TO_CATCH = 90 6 | 7 | def __init__(self, name: str, points: float): 8 | super().__init__(name, points, PredatoryFish.TIME_TO_CATCH) 9 | 10 | def fish_details(self): 11 | return (f"{self.__class__.__name__}: {self.name} " 12 | f"[Points: {self.points}, " 13 | f"Time to Catch: {self.time_to_catch} seconds]") 14 | -------------------------------------------------------------------------------- /classes_and_objects/ex_1.py: -------------------------------------------------------------------------------- 1 | def sum_nums(a, b=0): 2 | return a + b 3 | 4 | 5 | print(sum_nums(5)) 6 | 7 | 8 | class Vehicle: 9 | def __init__(self, mileage, max_speed=150): 10 | self.mileage = mileage 11 | self.max_speed = max_speed 12 | self.gadgets = [] 13 | 14 | 15 | 16 | mileage = int(input()) 17 | 18 | car = Vehicle(mileage, 150) 19 | 20 | 21 | print(car.max_speed) 22 | print(car.mileage) 23 | print(car.gadgets) 24 | car.gadgets.append('Hudly Wireless') 25 | print(car.gadgets) 26 | 27 | -------------------------------------------------------------------------------- /first_steps_in_oop/ex_1.py: -------------------------------------------------------------------------------- 1 | n = int(input()) 2 | 3 | 4 | def print_row(size, row): 5 | print(f"{' '*(size - row)}{'* ' * row}") 6 | 7 | 8 | def print_upper_rhombus_part(size): 9 | for row in range(1, size + 1): 10 | print_row(size, row) 11 | 12 | 13 | def print_bottom_rhombus_part(size): 14 | for row in range(size-1, 0, -1): 15 | print_row(size, row) 16 | 17 | 18 | def print_rhombus(size): 19 | print_upper_rhombus_part(size) 20 | print_bottom_rhombus_part(size) 21 | 22 | 23 | print_rhombus(n) -------------------------------------------------------------------------------- /classes_and_objects/ex_2.py: -------------------------------------------------------------------------------- 1 | class Point: 2 | def __init__(self, x, y): 3 | self.x = x 4 | self.y = y 5 | 6 | def set_x(self, new_x): 7 | self.x = new_x 8 | 9 | def set_y(self, new_y): 10 | self.y = new_y 11 | 12 | # def __str__(self): 13 | # return f"The point has coordinates ({self.x},{self.y})" 14 | 15 | def __repr__(self): 16 | return "from repr" 17 | 18 | 19 | 20 | p = Point(2, 4) 21 | print(p) 22 | print(repr(p)) 23 | # p.set_x(3) 24 | # p.set_y(5) 25 | # print(p) 26 | -------------------------------------------------------------------------------- /tuples_and_sets/ex_2.py: -------------------------------------------------------------------------------- 1 | n = int(input()) 2 | 3 | student_grades = {} 4 | 5 | for _ in range(n): 6 | name, grade_as_str = tuple(input().split()) 7 | grade = float(grade_as_str) 8 | 9 | if name not in student_grades: 10 | student_grades[name] = [] 11 | student_grades[name].append(grade) 12 | 13 | for name, grades in student_grades.items(): 14 | avg_grade = sum(grades) / len(grades) 15 | formatted_grades = f"{' '.join([f'{g:.2f}' for g in grades])}" 16 | print(f"{name} ->", *formatted_grades, f"(avg: {avg_grade:.2f})") -------------------------------------------------------------------------------- /decorators/class_as_decorator.py: -------------------------------------------------------------------------------- 1 | class Fibonacci: 2 | def __init__(self): 3 | self.cache = {} 4 | 5 | def __call__(self, n): 6 | if n not in self.cache: 7 | if n == 0: 8 | self.cache[0] = 0 9 | elif n == 1: 10 | self.cache[1] = 1 11 | else: 12 | self.cache[n] = self.cache[n-1] + self.cache[n-2] 13 | return self.cache[n] 14 | 15 | 16 | fib = Fibonacci() 17 | 18 | for i in range(11): 19 | print(fib(i)) 20 | 21 | print(fib.cache) 22 | 23 | -------------------------------------------------------------------------------- /polymorphism_and_abstraction/ex_3.py: -------------------------------------------------------------------------------- 1 | def start_playing(obj): 2 | return obj.play() 3 | 4 | 5 | 6 | class MixinPlay: 7 | def play(self): 8 | return f"from mixin playing" 9 | 10 | 11 | 12 | class Guitar: 13 | # pass 14 | def play(self): 15 | return "Playing the guitar" 16 | 17 | 18 | class Children: 19 | # pass 20 | def play(self): 21 | return "Children are playing" 22 | 23 | children = Children() 24 | print(start_playing(children)) 25 | 26 | 27 | guitar = Guitar() 28 | print(start_playing(guitar)) 29 | -------------------------------------------------------------------------------- /design_patterns/ex_1/factories/modern_factory.py: -------------------------------------------------------------------------------- 1 | from design_patterns.ex_1.factories.abstract_furntiture_factory import AbstractFactory 2 | from design_patterns.ex_1.furnitures.chair import Chair 3 | from design_patterns.ex_1.furnitures.sofa import Sofa 4 | from design_patterns.ex_1.furnitures.table import Table 5 | 6 | 7 | class ModernFactory(AbstractFactory): 8 | def create_sofa(self): 9 | return Sofa("Modern") 10 | 11 | def create_chair(self): 12 | return Chair("Modern") 13 | 14 | def create_table(self): 15 | return Table("Modern") 16 | -------------------------------------------------------------------------------- /modules_example/fibonacci/main.py: -------------------------------------------------------------------------------- 1 | from modules_example.fibonacci.core import create_sequence, locate_number 2 | 3 | command = input() 4 | sequence = [] 5 | 6 | while command != "Stop": 7 | if "Create" in command: 8 | _, _ ,number = command.split() 9 | number = int(number) 10 | sequence = create_sequence(number) 11 | print(*sequence) 12 | else: 13 | _, number = command.split() 14 | number = int(number) 15 | result = locate_number(number, sequence) 16 | print(result) 17 | 18 | command = input() 19 | 20 | 21 | -------------------------------------------------------------------------------- /encapsulation/ex_2.py: -------------------------------------------------------------------------------- 1 | class Mammal: 2 | __kingdom = "animals" 3 | def __init__(self, name, type, sound): 4 | self.name = name 5 | self.type = type 6 | self.sound = sound 7 | 8 | def make_sound(self): 9 | return f"{self.name} makes {self.sound}" 10 | 11 | def get_kingdom(self): 12 | return Mammal.__kingdom 13 | 14 | def info(self): 15 | return f"{self.name} is of type {self.type}" 16 | 17 | 18 | 19 | mammal = Mammal("Dog", "Domestic", "Bark") 20 | print(mammal._Mammal__kingdom) 21 | print(Mammal._Mammal__kingdom) 22 | -------------------------------------------------------------------------------- /multidimentional_lists/ex_2.py: -------------------------------------------------------------------------------- 1 | # row_count = int(input()) 2 | # 3 | # matrix = [] 4 | # 5 | # for i in range(row_count): 6 | # data = [int(el) for el in input().split(", ") if int(el) % 2 == 0] 7 | # matrix.append(data) 8 | # 9 | # print(matrix) 10 | # even_matrix = [] 11 | # 12 | # for row in matrix: 13 | # sub_list = [] 14 | # for el in row: 15 | # if el % 2 == 0: 16 | # sub_list.append(el) 17 | # even_matrix.append(sub_list) 18 | 19 | a = [] 20 | for el in a: 21 | pass 22 | el 23 | 24 | if not a: 25 | print("No elements") 26 | 27 | 28 | -------------------------------------------------------------------------------- /design_patterns/ex_1/factories/victorian_factory.py: -------------------------------------------------------------------------------- 1 | from design_patterns.ex_1.factories.abstract_furntiture_factory import AbstractFactory 2 | from design_patterns.ex_1.furnitures.chair import Chair 3 | from design_patterns.ex_1.furnitures.sofa import Sofa 4 | from design_patterns.ex_1.furnitures.table import Table 5 | 6 | 7 | class VictorianFactory(AbstractFactory): 8 | def create_sofa(self): 9 | return Sofa("Victorian") 10 | 11 | def create_chair(self): 12 | return Chair("Victorian") 13 | 14 | def create_table(self): 15 | return Table("Victorian") 16 | -------------------------------------------------------------------------------- /iterators_and_generators/ex_2.py: -------------------------------------------------------------------------------- 1 | class reverse_iter: 2 | def __init__(self, iter_obj): 3 | self.iter_obj = iter_obj 4 | self.end_index = len(self.iter_obj) 5 | self.start_index = 0 6 | 7 | def __iter__(self): 8 | return self.iter_obj 9 | 10 | def __next__(self): 11 | if self.end_index > self.start_index: 12 | self.end_index -= 1 13 | return self.iter_obj[self.end_index] 14 | raise StopIteration 15 | 16 | 17 | reversed_list = reverse_iter([1, 2, 3, 4]) 18 | for item in reversed_list: 19 | print(item) 20 | -------------------------------------------------------------------------------- /functions_advanced/ex_3.py: -------------------------------------------------------------------------------- 1 | def sorting_cheeses(**kwargs): 2 | result = "" 3 | sorted_result = sorted( 4 | kwargs.items(), 5 | key=lambda kvp: (-len(kvp[1]), kvp[0]), 6 | ) 7 | for cheese_name, quantities in sorted_result: 8 | result += cheese_name + "\n" 9 | for quantity in sorted(quantities, reverse=True): 10 | result += f"{quantity}\n" 11 | return result 12 | 13 | 14 | print( 15 | sorting_cheeses( 16 | Parmesan=[102, 120], 17 | Camembert=[100, 100, 105, 500, 430], 18 | Mozzarella=[50, 125], 19 | ) 20 | ) 21 | -------------------------------------------------------------------------------- /iterators_and_generators/ex_1.py: -------------------------------------------------------------------------------- 1 | class custom_range: 2 | def __init__(self, start, end): 3 | self.start = start 4 | self.end = end 5 | self.current = self.start - 1 6 | 7 | # def __iter__(self): 8 | # return self 9 | # 10 | # def __next__(self): 11 | # self.current += 1 12 | # if self.current <= self.end: 13 | # return self.current 14 | # # self.current = self.start - 1 15 | # raise StopIteration 16 | 17 | def iterate(self): 18 | ... 19 | cr = custom_range(1, 5) 20 | 21 | for obj in cr: 22 | print(obj) 23 | 24 | -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/project/divers/free_diver.py: -------------------------------------------------------------------------------- 1 | from project.divers.base_diver import BaseDiver 2 | 3 | 4 | class FreeDiver(BaseDiver): 5 | INITIAL_OXYGEN = 120 6 | 7 | def __init__(self, name: str): 8 | super().__init__(name, FreeDiver.INITIAL_OXYGEN) 9 | 10 | def miss(self, time_to_catch: int): 11 | reduce_amount = round(time_to_catch*0.6) 12 | 13 | if (self.oxygen_level - reduce_amount) < 0: 14 | self.oxygen_level = 0 15 | else: 16 | self.oxygen_level -= reduce_amount 17 | 18 | def renew_oxy(self): 19 | self.oxygen_level = self.INITIAL_OXYGEN -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/project/divers/scuba_diver.py: -------------------------------------------------------------------------------- 1 | from project.divers.base_diver import BaseDiver 2 | 3 | 4 | class ScubaDiver(BaseDiver): 5 | INITIAL_OXYGEN = 540 6 | 7 | def __init__(self, name: str): 8 | super().__init__(name, ScubaDiver.INITIAL_OXYGEN) 9 | 10 | def miss(self, time_to_catch: int): 11 | reduce_amount = round(time_to_catch*0.3) 12 | 13 | if (self.oxygen_level - reduce_amount) < 0: 14 | self.oxygen_level = 0 15 | else: 16 | self.oxygen_level -= reduce_amount 17 | 18 | def renew_oxy(self): 19 | self.oxygen_level = self.INITIAL_OXYGEN -------------------------------------------------------------------------------- /inheritance/single_inheritance/project/__init__.py: -------------------------------------------------------------------------------- 1 | class Parent: 2 | def say_hi(self): 3 | return "from parent class" 4 | 5 | class FirstChild(Parent): 6 | # pass 7 | def say_hi(self): 8 | return "from FirstChild class" 9 | 10 | class SecondChild(Parent): 11 | SOME_SOME = "a" 12 | def say_hi(self): 13 | return "from SecondChild class" 14 | 15 | class GrandChild(SecondChild, FirstChild): 16 | SOME_SOME = "b" 17 | 18 | def say_hi(self): 19 | return FirstChild.say_hi(self) 20 | 21 | 22 | g = GrandChild() 23 | print(g.SOME_SOME) 24 | print(g.say_hi()) 25 | print(GrandChild.mro()) 26 | -------------------------------------------------------------------------------- /multidimentional_lists/ex_1.py: -------------------------------------------------------------------------------- 1 | row, col = [int(el) for el in input().split(", ")] 2 | 3 | total_amount = 0 4 | matrix = [] 5 | for i in range(row): 6 | row_data = [int(el) for el in input().split(", ")] 7 | total_amount += sum(row_data) 8 | matrix.append(row_data) 9 | 10 | matrix = [] 11 | for i in range(row): 12 | data = input().split(", ") 13 | sub_list = [] 14 | for j in range(col): 15 | current_element = int(data[j]) 16 | total_amount += current_element 17 | sub_list.append(current_element) 18 | matrix.append(sub_list) 19 | 20 | print(total_amount) 21 | print(matrix) 22 | 23 | a = [] 24 | 25 | -------------------------------------------------------------------------------- /decorators/order_of_execution.py: -------------------------------------------------------------------------------- 1 | 2 | def upper(func): 3 | def wrapper(*args, **kwargs): 4 | result = func(*args, **kwargs) 5 | return result.upper() 6 | return wrapper 7 | 8 | 9 | def bold(func): 10 | def wrapper(*args, **kwargs): 11 | result = func(*args, **kwargs) 12 | return f"{result}" 13 | return wrapper 14 | 15 | 16 | 17 | # They are executed from bottom to top - 18 | # first it makes the result from the function uppercase, then applies the bold tag 19 | # HELLO 20 | 21 | @bold 22 | @upper 23 | def base_func(): 24 | """some docs""" 25 | return "Hello" 26 | 27 | 28 | print(base_func()) -------------------------------------------------------------------------------- /polymorphism_and_abstraction/ex_2.py: -------------------------------------------------------------------------------- 1 | class ImageArea: 2 | def __init__(self, width, height): 3 | self.width = width 4 | self.height = height 5 | 6 | def get_area(self): 7 | return self.width * self.height 8 | 9 | def __lt__(self, other): 10 | return self.get_area() < other.get_area() 11 | 12 | def __le__(self, other): 13 | return self.get_area() <= other.get_area() 14 | 15 | # def __eq__(self, other): 16 | # return self.get_area() == other.get_area() 17 | 18 | 19 | 20 | a1 = ImageArea(7, 10) 21 | a2 = ImageArea(7, 10) 22 | a3 = ImageArea(8, 9) 23 | 24 | print(id(a1)) 25 | print(id(a2)) 26 | print(a1 != a2) 27 | -------------------------------------------------------------------------------- /solid/di/di.py: -------------------------------------------------------------------------------- 1 | class Book: 2 | def __init__(self, content: str): 3 | self.content = content 4 | 5 | 6 | class Formatter: 7 | def format(self, book: Book) -> str: 8 | return book.content 9 | 10 | 11 | class PaperFormatter: 12 | def format(self, book): 13 | return book.content[:4] 14 | 15 | 16 | class Printer: 17 | def get_book(self, book: Book, formatter): 18 | formatted_book = formatter.format(book) 19 | return formatted_book 20 | 21 | 22 | base_formatter = Formatter() 23 | book = Book("Some content") 24 | paper_formatter = PaperFormatter() 25 | 26 | 27 | p = Printer() 28 | 29 | print(p.get_book(book, paper_formatter)) -------------------------------------------------------------------------------- /design_patterns/singleton_example.py: -------------------------------------------------------------------------------- 1 | def singleton(cls): 2 | instance = [None] 3 | def wrapper(*args, **kwargs): 4 | if instance[0] is None: 5 | instance[0] = cls(*args, **kwargs) 6 | return instance[0] 7 | 8 | return wrapper 9 | 10 | 11 | 12 | class Person: 13 | def __init__(self): 14 | self.name = "Test" 15 | 16 | # def __new__(cls): 17 | # if not hasattr(cls, 'instance'): 18 | # cls.instance = super(Person, cls).__new__(cls) 19 | # return cls.instance 20 | 21 | 22 | class PersonFactory: 23 | def get_person(self): 24 | return Person() 25 | 26 | 27 | 28 | p = PersonFactory().get_person() 29 | print(p) -------------------------------------------------------------------------------- /encapsulation_ex/restaurant/project/main.py: -------------------------------------------------------------------------------- 1 | from project.beverage.beverage import Beverage 2 | from project.food.soup import Soup 3 | from project.product import Product 4 | 5 | product = Product("coffee", 2.5) 6 | print(product.__class__.__name__) 7 | print(product.name) 8 | print(product.price) 9 | beverage = Beverage("coffee", 2.5, 50) 10 | print(beverage.__class__.__name__) 11 | print(beverage.__class__.__bases__[0].__name__) 12 | print(beverage.name) 13 | print(beverage.price) 14 | print(beverage.milliliters) 15 | soup = Soup("fish soup", 9.90, 230) 16 | print(soup.__class__.__name__) 17 | print(soup.__class__.__bases__[0].__name__) 18 | print(soup.name) 19 | print(soup.price) 20 | print(soup.grams) 21 | -------------------------------------------------------------------------------- /solid/ocp/animal_broken.py: -------------------------------------------------------------------------------- 1 | class Animal: 2 | def __init__(self, species): 3 | self.species = species 4 | 5 | def get_species(self): 6 | return self.species 7 | 8 | 9 | def animal_sound(animals: list): 10 | for animal in animals: 11 | if animal.species == 'cat': 12 | print('meow') 13 | elif animal.species == 'dog': 14 | print('woof-woof') 15 | 16 | 17 | 18 | animals = [Animal('cat'), Animal('dog')] 19 | animal_sound(animals) 20 | 21 | ## добавете ново животно и рефакторирайте кода да работи без да се налага да се правят промени по него 22 | ## при добавяне на нови животни 23 | # animals = [Animal('cat'), Animal('dog'), Animal('chicken')] 24 | -------------------------------------------------------------------------------- /first_steps_in_oop/ex_4.py: -------------------------------------------------------------------------------- 1 | class Car: 2 | def __init__(self, name, model, engine): 3 | self.name = name 4 | self.model = model 5 | self.engine = engine 6 | 7 | def get_info(self): 8 | return f"This is {self.name} {self.model} with engine {self.engine}" 9 | 10 | def change_name(self, new_name): 11 | if new_name.strip() == "": 12 | raise ValueError("Name can not be empty") 13 | self.name = new_name 14 | 15 | def __str__(self): 16 | return f"This is a car with name {self.name}" 17 | 18 | def __repr__(self): 19 | return f"This is a car with name {self.name}" 20 | 21 | 22 | 23 | car = Car("Test", "test", "1.6") 24 | print(car) 25 | -------------------------------------------------------------------------------- /decorators/class_as_decorator_logger.py: -------------------------------------------------------------------------------- 1 | class func_logger: 2 | 3 | _logfile = 'out.log' 4 | 5 | def __init__(self, func): 6 | self.func = func 7 | 8 | def __call__(self, *args): 9 | log_string = self.func.__name__ + " was called" 10 | with open(self._logfile, 'a') as opened_file: 11 | opened_file.write(log_string + '\n') 12 | return self.func(*args) 13 | 14 | 15 | @func_logger 16 | def say_hi(name): 17 | print(f"Hi, {name}") 18 | 19 | @func_logger 20 | def say_bye(name): 21 | print(f"Bye, {name}") 22 | 23 | 24 | @func_logger 25 | def say_test(name): 26 | print(f"This is a test, {name}") 27 | 28 | say_hi("Peter") 29 | say_bye("Peter") 30 | say_test("Ines") 31 | -------------------------------------------------------------------------------- /encapsulation/ex_5.py: -------------------------------------------------------------------------------- 1 | class Account: 2 | def __init__(self, id, balance, pin): 3 | self.__id = id 4 | self.balance = balance 5 | self.__pin = pin 6 | 7 | def get_id(self, pin): 8 | if pin == self.__pin: 9 | return self.__id 10 | return "Wrong pin" 11 | 12 | def change_pin(self, old_pin, new_pin): 13 | if old_pin == self.__pin: 14 | self.__pin = new_pin 15 | return "Pin changed" 16 | return "Wrong pin" 17 | 18 | 19 | account = Account(8827312, 100, 3421) 20 | print(account.get_id(1111)) 21 | print(account.get_id(3421)) 22 | print(account.balance) 23 | print(account.change_pin(2212, 4321)) 24 | print(account.change_pin(3421, 1234)) 25 | -------------------------------------------------------------------------------- /solid/ocp/animal.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class Animal(ABC): 5 | @abstractmethod 6 | def make_sound(self): 7 | pass 8 | 9 | def get_species(self): 10 | return self.__class__.__name__.lower() 11 | 12 | 13 | class Cat(Animal): 14 | def make_sound(self): 15 | return "meow" 16 | 17 | 18 | class Dog(Animal): 19 | def make_sound(self): 20 | return "bark bark" 21 | 22 | 23 | class Pig(Animal): 24 | def make_sound(self): 25 | return "pig sound" 26 | 27 | 28 | def animal_sound(animals: list[Animal]): 29 | for animal in animals: 30 | print(animal.make_sound()) 31 | 32 | animals = [Cat(), Dog(), Pig()] 33 | 34 | animal_sound(animals) 35 | -------------------------------------------------------------------------------- /encapsulation_ex/football_team_generator/project/player.py: -------------------------------------------------------------------------------- 1 | class Player: 2 | def __init__(self, name: str, sprint: int, dribble: int, passing: int, shooting: int): 3 | self.__name = name 4 | self.__sprint = sprint 5 | self.__dribble = dribble 6 | self.__passing = passing 7 | self.__shooting = shooting 8 | 9 | @property 10 | def name(self): 11 | return self.__name 12 | 13 | def __str__(self): 14 | return (f"Player: {self.__name}\n" 15 | f"Sprint: {self.__sprint}\n" 16 | f"Dribble: {self.__dribble}\n" 17 | f"Passing: {self.__passing}\n" 18 | f"Shooting: {self.__shooting}") 19 | 20 | p = Player("Hello",3,4,5,6) 21 | 22 | print(p.name) -------------------------------------------------------------------------------- /stacks_and_queues/ex_4.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | water = int(input()) 4 | 5 | name = input() 6 | people = deque() 7 | 8 | while name != "Start": 9 | people.append(name) 10 | name = input() 11 | 12 | command = input() 13 | 14 | while command != "End": 15 | data = command.split() 16 | if len(data) == 1: 17 | liters_requested = int(data[0]) 18 | person = people.popleft() 19 | 20 | if water >= liters_requested: 21 | print(f"{person} got water") 22 | water -= liters_requested 23 | else: 24 | print(f"{person} must wait") 25 | elif len(data) == 2: 26 | _, liters_to_add = data 27 | water += int(liters_to_add) 28 | 29 | command = input() 30 | 31 | print(f"{water} liters left") -------------------------------------------------------------------------------- /encapsulation_ex/football_team_generator/project/main.py: -------------------------------------------------------------------------------- 1 | from project.player import Player 2 | from project.team import Team 3 | 4 | 5 | p = Player("Pall", 1, 3, 5, 7) 6 | 7 | print("Player name:", p.name) 8 | print("Points sprint:", p._Player__sprint) 9 | print("Points dribble:", p._Player__dribble) 10 | print("Points passing:", p._Player__passing) 11 | print("Points shooting:", p._Player__shooting) 12 | 13 | print("\ncalling the __str__ method") 14 | print(p) 15 | 16 | print("\nAbout the team") 17 | t = Team("Best", 10) 18 | print("Team name:", t._Team__name) 19 | print("Teams points:", t._Team__rating) 20 | print("Teams players:", len(t._Team__players)) 21 | print(t.add_player(p)) 22 | print(t.add_player(p)) 23 | print("Teams players:", len(t._Team__players)) 24 | print(t.remove_player("Pall")) 25 | print(t.remove_player("Pall")) 26 | -------------------------------------------------------------------------------- /iterators_and_generators/__init__.py: -------------------------------------------------------------------------------- 1 | # def my_gen(n): 2 | # current = 1 3 | # while current <= n: 4 | # yield current 5 | # current += 1 6 | # 7 | # 8 | # 9 | # def my_gen2(): 10 | # n = 1 11 | # print('This is printed first') 12 | # return n 13 | # 14 | # n += 1 15 | # print('This is printed second') 16 | # return n 17 | # 18 | # n += 1 19 | # print('This is printed at last') 20 | # return n 21 | # 22 | # 23 | # a = my_gen(3) 24 | # 25 | # for el in a: 26 | # print(el) 27 | 28 | 29 | def square_even(n): 30 | current = 1 31 | while current <= n: 32 | if current %2 ==0: 33 | yield current * 5 34 | current+=1 35 | 36 | # result = (i * 5 for i in range(1, 5) if i%2==0) 37 | result = square_even(5) 38 | for el in result: 39 | print(el) 40 | -------------------------------------------------------------------------------- /iterators_and_generators/ex_3.py: -------------------------------------------------------------------------------- 1 | class vowels: 2 | def __init__(self, string): 3 | self.string = string 4 | self.vowels_list = ['a', 'e', 'i', 'u', 'y', 'o'] 5 | self.index = -1 6 | self.vowels_values = [c for c in self.string if c.lower() in self.vowels_list] 7 | 8 | def __iter__(self): 9 | return self 10 | 11 | def __next__(self): 12 | self.index += 1 13 | if self.index < len(self.vowels_values): 14 | return self.vowels_values[self.index] 15 | raise StopIteration 16 | 17 | 18 | # test iter 19 | import unittest 20 | 21 | class VowelsTests(unittest.TestCase): 22 | def test_iter(self): 23 | my_string = vowels('Iteratori') 24 | self.assertEqual(my_string .__iter__().__class__.__name__, "vowels") 25 | 26 | if __name__ == '__main__': 27 | unittest.main() -------------------------------------------------------------------------------- /exam_prep_1/ex_3.py: -------------------------------------------------------------------------------- 1 | def gather_credits(number_of_credits_needed, *course_info): 2 | courses_enrolled = {} 3 | 4 | for course_name, credits in course_info: 5 | if sum(courses_enrolled.values()) >= number_of_credits_needed: 6 | break 7 | 8 | if course_name not in courses_enrolled: 9 | courses_enrolled[course_name] = credits 10 | 11 | if sum(courses_enrolled.values()) >= number_of_credits_needed: 12 | return (f"Enrollment finished! Maximum credits: {sum(courses_enrolled.values())}.\n" 13 | f"Courses: {', '.join(sorted(courses_enrolled))}") 14 | return (f"You need to enroll in more courses! " 15 | f"You have to gather {number_of_credits_needed - sum(courses_enrolled.values())} credits more.") 16 | 17 | 18 | print(gather_credits( 19 | 80, 20 | ("Basics", 27), 21 | )) 22 | 23 | 24 | -------------------------------------------------------------------------------- /exam_prep_2/ex_3.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | def sort_players(kvp): 5 | return -len(kvp[1]), kvp[0] 6 | 7 | 8 | def team_lineup(*args): 9 | country_players = defaultdict(lambda: []) 10 | for player_name, country in args: 11 | country_players[country].append(player_name) 12 | 13 | result = "" 14 | 15 | sorted_players = sorted(country_players.items(), key=sort_players) 16 | for country, players in sorted_players: 17 | result += f"{country}:\n" 18 | for player_name in players: 19 | result += f" -{player_name}\n" 20 | return result[:-1] 21 | 22 | 23 | 24 | 25 | print(team_lineup( 26 | ("Harry Kane", "England"), 27 | ("Manuel Neuer", "Germany"), 28 | ("Raheem Sterling", "England"), 29 | ("Toni Kroos", "Germany"), 30 | ("Cristiano Ronaldo", "Portugal"), 31 | ("Thomas Muller", "Germany") 32 | ) 33 | ) 34 | -------------------------------------------------------------------------------- /file_handling/ex_5.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | 4 | words_path = os.path.join("resources", "words.txt") 5 | text_path = os.path.join("resources", "input.txt") 6 | output_file_path = os.path.join("resources", "text.txt") 7 | 8 | with open(words_path) as file: 9 | searched_words_as_text = file.read() 10 | searched_words = [word.lower() for word in searched_words_as_text.split()] 11 | 12 | with open(text_path) as file: 13 | content = file.read().lower() 14 | 15 | 16 | words_count = {} 17 | 18 | for searched_word in searched_words: 19 | pattern = re.compile(rf"\b{searched_word}\b") 20 | results = re.findall(pattern, content) 21 | words_count[searched_word] = len(results) 22 | 23 | sorted_words_count = sorted(words_count.items(), key=lambda kvp: -kvp[1]) 24 | 25 | with open(output_file_path, "a") as file: 26 | for word, count in sorted_words_count: 27 | file.write(f"{word} - {count}\n") -------------------------------------------------------------------------------- /multidimentional_lists/ex_7.py: -------------------------------------------------------------------------------- 1 | row, col = [int(el) for el in input().split(", ")] 2 | 3 | 4 | matrix = [] 5 | 6 | for _ in range(row): 7 | matrix.append([int(el) for el in input().split(", ")]) 8 | 9 | 10 | max_sum = float('-inf') 11 | sub_matrix = [] 12 | 13 | for row_index in range(row-1): 14 | for col_index in range(col-1): 15 | current_element = matrix[row_index][col_index] 16 | next_element = matrix[row_index][col_index+1] 17 | element_under = matrix[row_index+1][col_index] 18 | element_diagonal = matrix[row_index+1][col_index+1] 19 | 20 | total_sum = current_element + next_element + element_under + element_diagonal 21 | 22 | if max_sum < total_sum: 23 | max_sum = total_sum 24 | sub_matrix = [[current_element, next_element], [element_under, element_diagonal]] 25 | 26 | print(*sub_matrix[0]) 27 | print(*sub_matrix[1]) 28 | print(max_sum) -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/project/fish/base_fish.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class BaseFish(ABC): 5 | def __init__(self, name: str, points: float, time_to_catch: int): 6 | self.name = name 7 | self.points = points 8 | self.time_to_catch = time_to_catch 9 | 10 | @property 11 | def name(self): 12 | return self.__name 13 | 14 | @name.setter 15 | def name(self, value): 16 | if value.strip() == "": 17 | raise ValueError("Fish name should be determined!") 18 | self.__name = value 19 | 20 | @property 21 | def points(self): 22 | return self.__points 23 | 24 | @points.setter 25 | def points(self, value): 26 | if value < 1 or value > 10: 27 | raise ValueError("Points should be a value ranging from 1 to 10!") 28 | self.__points = value 29 | 30 | @abstractmethod 31 | def fish_details(self): 32 | pass 33 | 34 | 35 | -------------------------------------------------------------------------------- /classes_and_objects/ex_4.py: -------------------------------------------------------------------------------- 1 | class Glass: 2 | """ 3 | This class produces glasses 4 | """ 5 | capacity = 250 6 | 7 | def __init__(self): 8 | """ 9 | This is the init to create instances of this class 10 | """ 11 | self.content = 0 12 | 13 | def fill(self, ml): 14 | """ 15 | If there is enough capacity we fill the glass 16 | :param ml: fload 17 | :return: string - the output of the action 18 | """ 19 | if Glass.capacity >= (self.content + ml): 20 | self.content += ml 21 | return f"Glass filled with {ml} ml" 22 | return f"Cannot add {ml} ml" 23 | 24 | def empty(self): 25 | self.content = 0 26 | return "Glass is now empty" 27 | 28 | def info(self): 29 | diff = Glass.capacity - self.content 30 | return f"{diff} ml left" 31 | 32 | 33 | 34 | print(Glass.__doc__) 35 | print(Glass.fill.__doc__) 36 | glass = Glass() 37 | print(Glass.__dict__) 38 | print(glass.__dict__) 39 | -------------------------------------------------------------------------------- /classes_and_objects/ex_5.py: -------------------------------------------------------------------------------- 1 | class Smartphone: 2 | def __init__(self, memory): 3 | self.memory = memory 4 | self.apps = [] 5 | self.is_on = False 6 | 7 | def power(self): 8 | self.is_on = not self.is_on 9 | 10 | def install(self, app, app_memory): 11 | if self.memory >= app_memory and self.is_on: 12 | self.apps.append(app) 13 | self.memory -= app_memory 14 | return f"Installing {app}" 15 | elif self.memory >= app_memory and not self.is_on: 16 | return f"Turn on your phone to install {app}" 17 | 18 | return f"Not enough memory to install {app}" 19 | 20 | def status(self): 21 | return f"Total apps: {len(self.apps)}. Memory left: {self.memory}" 22 | 23 | 24 | smartphone = Smartphone(100) 25 | print(smartphone.install("Facebook", 60)) 26 | smartphone.power() 27 | print(smartphone.install("Facebook", 60)) 28 | print(smartphone.install("Messenger", 20)) 29 | print(smartphone.install("Instagram", 40)) 30 | print(smartphone.status()) 31 | 32 | -------------------------------------------------------------------------------- /exam_prep_1/ex_1.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | worms = [int(el) for el in input().split()] 4 | holes = deque([int(el) for el in input().split()]) 5 | 6 | all_worms_count = len(worms) 7 | countMatches = 0 8 | 9 | while worms and holes: 10 | current_worm = worms[-1] 11 | current_hole = holes.popleft() 12 | 13 | if current_worm == current_hole: 14 | worms.pop() 15 | countMatches += 1 16 | else: 17 | worms[-1] -= 3 18 | if worms[-1] <= 0: 19 | worms.pop() 20 | 21 | if countMatches: 22 | print(f"Matches: {countMatches}") 23 | else: 24 | print(f"There are no matches.") 25 | 26 | if not worms and countMatches == all_worms_count: 27 | print(f"Every worm found a suitable hole!") 28 | elif not worms and countMatches < all_worms_count: 29 | print("Worms left: none") 30 | else: 31 | print(f"Worms left: {', '.join([str(el) for el in worms])}") 32 | 33 | if not holes: 34 | print(f"Holes left: none") 35 | else: 36 | print(f"Holes left: {', '.join([str(el) for el in holes])}") 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /encapsulation_ex/pizza/project/topping.py: -------------------------------------------------------------------------------- 1 | class Topping: 2 | def __init__(self, topping_type: str, weight: float): 3 | self.topping_type = topping_type 4 | self.weight = weight 5 | # self.asd = 6 6 | 7 | @property 8 | def topping_type(self): 9 | return self.__topping_type 10 | 11 | @topping_type.setter 12 | def topping_type(self, value: str): 13 | if value == "": 14 | raise ValueError("The topping type cannot be an empty string") 15 | self.__topping_type = value 16 | 17 | @property 18 | def weight(self): 19 | return self.__weight 20 | 21 | @weight.setter 22 | def weight(self, value: float): 23 | if value <= 0: 24 | raise ValueError("The weight cannot be less or equal to zero") 25 | self.__weight = value 26 | 27 | 28 | # @property 29 | # def asd(self): 30 | # return self.__asd 31 | # 32 | # @asd.setter 33 | # def asd(self, value): 34 | # if value == "": 35 | # raise ValueError 36 | # self.__asd = value 37 | 38 | 39 | -------------------------------------------------------------------------------- /design_patterns/decorator_pattern.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class DataSource(ABC): 5 | @abstractmethod 6 | def writeData(self, data): 7 | pass 8 | 9 | @abstractmethod 10 | def readData(self) -> str: 11 | pass 12 | 13 | 14 | class FileDataSource(DataSource): 15 | def __init__(self, filename): 16 | self._file = filename 17 | 18 | def writeData(self, data): 19 | # write data to file. 20 | with open(self._file, "a") as f: 21 | f.write(data) 22 | 23 | def readData(self) -> str: 24 | # read data from file. 25 | with open(self._file, "r") as f: 26 | return f.read() 27 | 28 | 29 | class EncryptionDecorator(DataSource): 30 | def writeData(self, data): 31 | # encrypt the data 32 | # pass encrypted data to wrapper 33 | return ''.join([str(ord(c) for c in data)]) 34 | 35 | def readData(self) -> str: 36 | # get encrypted data 37 | # decrypt it 38 | # return it 39 | data = "" 40 | return ''.join([str(chr(c) for c in data)]) 41 | 42 | -------------------------------------------------------------------------------- /encapsulation/ex_4.py: -------------------------------------------------------------------------------- 1 | class EmailValidator: 2 | def __init__(self, min_length, mails, domains): 3 | self.min_length = min_length 4 | self.mails = mails 5 | self.domains = domains 6 | 7 | def __is_name_valid(self, name): 8 | return len(name) >= self.min_length 9 | 10 | def __is_mail_valid(self, mail): 11 | return mail in self.mails 12 | 13 | def __is_domain_valid(self, domain): 14 | return domain in self.domains 15 | 16 | def validate(self, email): 17 | username, data = email.split("@") 18 | provider, domain = data.split(".") 19 | 20 | return (self.__is_name_valid(username) and 21 | self.__is_mail_valid(provider) and 22 | self.__is_domain_valid(domain)) 23 | 24 | 25 | mails = ["gmail", "softuni"] 26 | domains = ["com", "bg"] 27 | email_validator = EmailValidator(6, mails, domains) 28 | print(email_validator.validate("pe77er@gmail.com")) 29 | print(email_validator.validate("georgios@gmail.net")) 30 | print(email_validator.validate("stamatito@abv.net")) 31 | print(email_validator.validate("abv@softuni.bg")) 32 | -------------------------------------------------------------------------------- /polymorphism_and_abstraction/ex_4.py: -------------------------------------------------------------------------------- 1 | from math import pi 2 | from abc import ABC, abstractmethod 3 | 4 | 5 | class Shape(ABC): 6 | @abstractmethod 7 | def calculate_area(self): 8 | pass 9 | 10 | @abstractmethod 11 | def calculate_perimeter(self): 12 | pass 13 | 14 | def print_self(self): 15 | print(f"Hi I am printing {self.__class__.__name__}") 16 | 17 | 18 | class Circle(Shape): 19 | def __init__(self, radius): 20 | self.__radius = radius 21 | 22 | def calculate_area(self): 23 | return pi * self.__radius ** 2 24 | 25 | def calculate_perimeter(self): 26 | return 2 * pi * self.__radius 27 | 28 | 29 | class Rectangle(Shape): 30 | def __init__(self, height, width): 31 | self.__height = height 32 | self.__width = width 33 | 34 | def calculate_area(self): 35 | return self.__width * self.__height 36 | 37 | def calculate_perimeter(self): 38 | return 2 * (self.__width + self.__height) 39 | 40 | 41 | 42 | circle = Circle(5) 43 | circle.print_self() 44 | 45 | 46 | rectangle = Rectangle(10, 20) 47 | print(rectangle.calculate_area()) 48 | print(rectangle.calculate_perimeter()) 49 | 50 | -------------------------------------------------------------------------------- /encapsulation_ex/pizza/project/dough.py: -------------------------------------------------------------------------------- 1 | class Dough: 2 | def __init__(self, flour_type: str, baking_technique: str, weight: float): 3 | self.flour_type = flour_type 4 | self.baking_technique = baking_technique 5 | self.weight = weight 6 | 7 | @property 8 | def flour_type(self): 9 | return self.__flour_type 10 | 11 | @flour_type.setter 12 | def flour_type(self, value): 13 | if value == "": 14 | raise ValueError("The flour type cannot be an empty string") 15 | self.__flour_type = value 16 | 17 | @property 18 | def baking_technique(self): 19 | return self.__baking_technique 20 | 21 | @baking_technique.setter 22 | def baking_technique(self, value): 23 | if value == "": 24 | raise ValueError("The baking technique cannot be an empty string") 25 | self.__baking_technique = value 26 | 27 | 28 | @property 29 | def weight(self): 30 | return self.__weight 31 | 32 | @weight.setter 33 | def weight(self, value): 34 | if value <= 0: 35 | raise ValueError("The weight cannot be less or equal to zero") 36 | self.__weight = value 37 | -------------------------------------------------------------------------------- /solid/liskov/liskov.py: -------------------------------------------------------------------------------- 1 | from abc import abstractmethod, ABC 2 | 3 | 4 | class DebuggingTool(ABC): 5 | @abstractmethod 6 | def make_sound(self): 7 | pass 8 | 9 | class Duck(ABC): 10 | @staticmethod 11 | @abstractmethod 12 | def quack(): 13 | pass 14 | 15 | @staticmethod 16 | @abstractmethod 17 | def walk(): 18 | pass 19 | 20 | @staticmethod 21 | @abstractmethod 22 | def fly(): 23 | pass 24 | 25 | 26 | class RubberDuck(DebuggingTool): 27 | @staticmethod 28 | def quack(): 29 | return "Squeek" 30 | 31 | 32 | 33 | class RobotDuck(Duck): 34 | HEIGHT = 50 35 | 36 | def __init__(self): 37 | self.height = 0 38 | 39 | @staticmethod 40 | def quack(): 41 | return 'Robotic quacking' 42 | 43 | @staticmethod 44 | def walk(): 45 | return 'Robotic walking' 46 | 47 | def fly(self): 48 | """can only fly to specific height but 49 | when it reaches it starts landing automatically""" 50 | if self.height == RobotDuck.HEIGHT: 51 | self.land() 52 | else: 53 | self.height += 1 54 | 55 | def land(self): 56 | self.height = 0 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /encapsulation_ex/pizza/project/main.py: -------------------------------------------------------------------------------- 1 | from project.dough import Dough 2 | from project.pizza import Pizza 3 | from project.topping import Topping 4 | 5 | 6 | tomato_topping = Topping("Tomato", 60) 7 | print(tomato_topping.topping_type) 8 | print(tomato_topping.weight) 9 | 10 | mushrooms_topping = Topping("Mushroom", 75) 11 | print(mushrooms_topping.topping_type) 12 | print(mushrooms_topping.weight) 13 | 14 | mozzarella_topping = Topping("Mozzarella", 80) 15 | print(mozzarella_topping.topping_type) 16 | print(mozzarella_topping.weight) 17 | 18 | cheddar_topping = Topping("Cheddar", 150) 19 | 20 | pepperoni_topping = Topping("Pepperoni", 120) 21 | 22 | white_flour_dough = Dough("White Flour", "Mixing", 200) 23 | print(white_flour_dough.flour_type) 24 | print(white_flour_dough.weight) 25 | print(white_flour_dough.baking_technique) 26 | 27 | whole_wheat_dough = Dough("Whole Wheat Flour", "Mixing", 200) 28 | print(whole_wheat_dough.weight) 29 | print(whole_wheat_dough.flour_type) 30 | print(whole_wheat_dough.baking_technique) 31 | 32 | p = Pizza("Margherita", "", 2) 33 | 34 | p.add_topping(tomato_topping) 35 | print(p.calculate_total_weight()) 36 | 37 | p.add_topping(mozzarella_topping) 38 | print(p.calculate_total_weight()) 39 | 40 | p.add_topping(mozzarella_topping) 41 | -------------------------------------------------------------------------------- /exam_prep_2/ex_1.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | initial_fuel = [int(el) for el in input().split()] 4 | additional_consumption_index = deque([int(el) for el in input().split()]) 5 | amount_of_fuel_needed = deque([int(el) for el in input().split()]) 6 | 7 | altitude_count = 0 8 | max_altitude_count = len(initial_fuel) 9 | 10 | while initial_fuel and additional_consumption_index and amount_of_fuel_needed: 11 | fuel = initial_fuel.pop() 12 | index = additional_consumption_index.popleft() 13 | needed = amount_of_fuel_needed.popleft() 14 | 15 | if (fuel - index) >= needed: 16 | altitude_count += 1 17 | print(f"John has reached: Altitude {altitude_count}") 18 | else: 19 | print(f"John did not reach: Altitude {altitude_count+1}") 20 | break 21 | 22 | 23 | if max_altitude_count > altitude_count and altitude_count: 24 | print(f"John failed to reach the top.") 25 | print(f"Reached altitudes: {', '.join([f'Altitude {num}' for num in range(1, altitude_count+1)])}") 26 | elif max_altitude_count > altitude_count and not altitude_count: 27 | print(f"John failed to reach the top.") 28 | print(f"John didn't reach any altitude.") 29 | 30 | if max_altitude_count == altitude_count: 31 | print(f"John has reached all the altitudes and managed to reach the top!") 32 | -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/exam_part_tests/project/railway_station.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | 4 | class RailwayStation: 5 | def __init__(self, name: str): 6 | self.name = name 7 | self.arrival_trains = deque() 8 | self.departure_trains = deque() 9 | 10 | @property 11 | def name(self): 12 | return self.__name 13 | 14 | @name.setter 15 | def name(self, value): 16 | if len(value) <= 3: 17 | raise ValueError("Name should be more than 3 symbols!") 18 | self.__name = value 19 | 20 | def new_arrival_on_board(self, train_info: str): 21 | self.arrival_trains.append(train_info) 22 | 23 | def train_has_arrived(self, train_info: str): 24 | if self.arrival_trains and self.arrival_trains[0] != train_info: 25 | return f"There are other trains to arrive before {train_info}." 26 | 27 | self.departure_trains.append(self.arrival_trains.popleft()) 28 | return f"{train_info} is on the platform and will leave in 5 minutes." 29 | 30 | def train_has_left(self, train_info: str): 31 | if self.departure_trains and self.departure_trains[0] == train_info: 32 | self.departure_trains.popleft() 33 | return True 34 | return False 35 | -------------------------------------------------------------------------------- /encapsulation_ex/football_team_generator/project/team.py: -------------------------------------------------------------------------------- 1 | from typing import Union 2 | 3 | from project.player import Player 4 | 5 | 6 | class Team: 7 | def __init__(self, name: str, rating: int): 8 | self.__name = name 9 | self.__rating = rating 10 | self.__players: list[Player] = [] 11 | self._test = 5 12 | 13 | def add_player(self, player: Player) -> str: 14 | if player in self.__players: 15 | return f"Player {player.name} has already joined" 16 | self.__players.append(player) 17 | return f"Player {player.name} joined team {self.__name}" 18 | 19 | def remove_player(self, player_name: str) -> Union[Player, str]: 20 | try: 21 | player = [p for p in self.__players if p.name == player_name][0] 22 | self.__players.remove(player) 23 | return player 24 | except IndexError: 25 | return f"Player {player_name} not found" 26 | 27 | @property 28 | def all_players_count(self): 29 | return len(self.__players) 30 | 31 | 32 | # @property 33 | # def name(self): 34 | # return self.__name 35 | # 36 | # @name.setter 37 | # def name(self, value): 38 | # if value == "": 39 | # raise ValueError() 40 | # self.__name = value 41 | 42 | 43 | -------------------------------------------------------------------------------- /inheritance/stack_of_strings.py: -------------------------------------------------------------------------------- 1 | class Stack: 2 | def __init__(self): 3 | self.data = [] 4 | 5 | def push(self, el): 6 | self.data.append(el) 7 | 8 | def pop(self): 9 | return self.data.pop() 10 | 11 | def top(self): 12 | return self.data[-1] 13 | 14 | def is_empty(self): 15 | return not self.data 16 | 17 | def __str__(self): 18 | reversed_data = reversed(self.data) 19 | result = ", ".join(reversed_data) 20 | return f"[{result}]" 21 | 22 | 23 | # test zero 24 | import unittest 25 | 26 | a = [1,2,3] 27 | class StackTests(unittest.TestCase): 28 | def test_zero(self): 29 | stack = Stack() 30 | stack.push("apple") 31 | stack.push("carrot") 32 | self.assertEqual(str(stack), '[carrot, apple]') 33 | self.assertEqual(stack.pop(), 'carrot') 34 | self.assertEqual(stack.top(), 'apple') 35 | stack.push("cucumber") 36 | self.assertEqual(str(stack), '[cucumber, apple]') 37 | self.assertEqual(stack.is_empty(), False) 38 | 39 | 40 | if __name__ == '__main__': 41 | unittest.main() 42 | 43 | s = Stack() 44 | print(s.is_empty()) 45 | s.push("5") 46 | s.push("6") 47 | print(s.top()) 48 | s.push("7") 49 | print(s.top()) 50 | 51 | print(s.is_empty()) 52 | print(s) 53 | s.pop() 54 | print(s) 55 | -------------------------------------------------------------------------------- /encapsulation_ex/wild_cat_zoo/project/main.py: -------------------------------------------------------------------------------- 1 | from project.caretaker import Caretaker 2 | from project.cheetah import Cheetah 3 | from project.keeper import Keeper 4 | from project.lion import Lion 5 | from project.tiger import Tiger 6 | from project.vet import Vet 7 | from project.zoo import Zoo 8 | 9 | 10 | zoo = Zoo("Zootopia", 3000, 5, 8) 11 | 12 | # Animals creation 13 | animals = [Cheetah("Cheeto", "Male", 2), Cheetah("Cheetia", "Female", 1), Lion("Simba", "Male", 4), Tiger("Zuba", "Male", 3), Tiger("Tigeria", "Female", 1), Lion("Nala", "Female", 4)] 14 | 15 | # Animal prices 16 | prices = [200, 190, 204, 156, 211, 140] 17 | 18 | # Workers creation 19 | workers = [Keeper("John", 26, 100), Keeper("Adam", 29, 80), Keeper("Anna", 31, 95), Caretaker("Bill", 21, 68), Caretaker("Marie", 32, 105), Caretaker("Stacy", 35, 140), Vet("Peter", 40, 300), Vet("Kasey", 37, 280), Vet("Sam", 29, 220)] 20 | 21 | # Adding all animals 22 | for i in range(len(animals)): 23 | animal = animals[i] 24 | price = prices[i] 25 | print(zoo.add_animal(animal, price)) 26 | 27 | # Adding all workers 28 | for worker in workers: 29 | print(zoo.hire_worker(worker)) 30 | 31 | # Tending animals 32 | print(zoo.tend_animals()) 33 | 34 | # Paying keepers 35 | print(zoo.pay_workers()) 36 | 37 | # Fireing worker 38 | print(zoo.fire_worker("Adam")) 39 | 40 | # Printing statuses 41 | print(zoo.animals_status()) 42 | print(zoo.workers_status()) 43 | -------------------------------------------------------------------------------- /solid/liskov/liskov_broken.py: -------------------------------------------------------------------------------- 1 | from abc import abstractmethod, ABC 2 | 3 | 4 | class Duck(ABC): 5 | @staticmethod 6 | @abstractmethod 7 | def quack(): 8 | pass 9 | 10 | @staticmethod 11 | @abstractmethod 12 | def walk(): 13 | pass 14 | 15 | @staticmethod 16 | @abstractmethod 17 | def fly(): 18 | pass 19 | 20 | 21 | class RubberDuck(Duck): 22 | @staticmethod 23 | def quack(): 24 | return "Squeek" 25 | 26 | @staticmethod 27 | def walk(): 28 | """Rubber duck can walk only if you move it""" 29 | raise Exception('I cannot walk by myself') 30 | 31 | @staticmethod 32 | def fly(): 33 | """Rubber duck can fly only if you throw it""" 34 | raise Exception('I cannot fly by myself') 35 | 36 | 37 | class RobotDuck(Duck): 38 | HEIGHT = 50 39 | 40 | def __init__(self): 41 | self.height = 0 42 | 43 | @staticmethod 44 | def quack(): 45 | return 'Robotic quacking' 46 | 47 | @staticmethod 48 | def walk(): 49 | return 'Robotic walking' 50 | 51 | def fly(self): 52 | """can only fly to specific height but 53 | when it reaches it starts landing automatically""" 54 | if self.height == RobotDuck.HEIGHT: 55 | self.land() 56 | else: 57 | self.height += 1 58 | 59 | def land(self): 60 | self.height = 0 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /polymorphism_and_abstraction/ex_1.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class Robot(ABC): 5 | 6 | def __init__(self, name): 7 | self.name = name 8 | 9 | @property 10 | def name(self): 11 | return self.__name 12 | 13 | @name.setter 14 | def name(self, value): 15 | if value == '': 16 | raise ValueError("Robot can not be created without a name") 17 | self.__name = value 18 | 19 | @staticmethod 20 | @abstractmethod 21 | def sensors_amount(): 22 | pass 23 | 24 | 25 | 26 | 27 | class MedicalRobot(Robot): 28 | @staticmethod 29 | def sensors_amount(): 30 | return 6 31 | 32 | r = Robot("f") 33 | print(r) 34 | m = MedicalRobot("T") 35 | print(m) 36 | class ChefRobot(Robot): 37 | @staticmethod 38 | def sensors_amount(): 39 | return 4 40 | 41 | 42 | class WarRobot(Robot): 43 | @staticmethod 44 | def sensors_amount(): 45 | return 12 46 | 47 | 48 | class AIRobot(Robot): 49 | @staticmethod 50 | def sensors_amount(): 51 | return 12 52 | 53 | 54 | class NewAgeRobot(Robot): 55 | @staticmethod 56 | def sensors_amount(): 57 | return 32 58 | 59 | 60 | def number_of_robot_sensors(robot): 61 | print(robot.sensors_amount()) 62 | 63 | 64 | # basic_robot = Robot('Robo') 65 | # da_vinci = MedicalRobot('Da Vinci') 66 | # moley = ChefRobot('Moley') 67 | # griffin = WarRobot('Griffin') 68 | # new_age = NewAgeRobot("Test") 69 | # 70 | # number_of_robot_sensors(basic_robot) 71 | # number_of_robot_sensors(da_vinci) 72 | # number_of_robot_sensors(moley) 73 | # number_of_robot_sensors(griffin) 74 | # number_of_robot_sensors(new_age) 75 | -------------------------------------------------------------------------------- /solid/isp/interface_broken.py: -------------------------------------------------------------------------------- 1 | class EntertainmentDevice: 2 | def connect_to_device_via_hdmi_cable(self, device): pass 3 | def connect_to_device_via_rca_cable(self, device): pass 4 | def connect_to_device_via_ethernet_cable(self, device): pass 5 | def connect_device_to_power_outlet(self, device): pass 6 | 7 | 8 | class Television(EntertainmentDevice): 9 | def connect_to_dvd(self, dvd_player): 10 | self.connect_to_device_via_rca_cable(dvd_player) 11 | 12 | def connect_to_game_console(self, game_console): 13 | self.connect_to_device_via_hdmi_cable(game_console) 14 | 15 | def plug_in_power(self): 16 | self.connect_device_to_power_outlet(self) 17 | 18 | 19 | class DVDPlayer(EntertainmentDevice): 20 | def connect_to_tv(self, television): 21 | self.connect_to_device_via_hdmi_cable(television) 22 | 23 | def plug_in_power(self): 24 | self.connect_device_to_power_outlet(self) 25 | 26 | 27 | class GameConsole(EntertainmentDevice): 28 | def connect_to_tv(self, television): 29 | self.connect_to_device_via_hdmi_cable(television) 30 | 31 | def connect_to_router(self, router): 32 | self.connect_to_device_via_ethernet_cable(router) 33 | 34 | def plug_in_power(self): 35 | self.connect_device_to_power_outlet(self) 36 | 37 | 38 | class Router(EntertainmentDevice): 39 | def connect_to_tv(self, television): 40 | self.connect_to_device_via_ethernet_cable(television) 41 | 42 | def connect_to_game_console(self, game_console): 43 | self.connect_to_device_via_ethernet_cable(game_console) 44 | 45 | def plug_in_power(self): 46 | self.connect_device_to_power_outlet(self) 47 | -------------------------------------------------------------------------------- /exam_prep_2/ex_3_pets_hotel.py: -------------------------------------------------------------------------------- 1 | def accommodate_new_pets(hotel_capacity, max_allowed_weight, *pets): 2 | accommodated_pets = {} 3 | are_all_accommodated = True 4 | 5 | for pet_name, pet_weight in pets: 6 | if not hotel_capacity: 7 | are_all_accommodated = False 8 | break 9 | if pet_weight <= max_allowed_weight: 10 | if pet_name not in accommodated_pets: 11 | accommodated_pets[pet_name] = 0 12 | accommodated_pets[pet_name] += 1 13 | hotel_capacity -= 1 14 | 15 | result = "" 16 | if are_all_accommodated: 17 | result += f"All pets are accommodated! Available capacity: {hotel_capacity}.\n" 18 | else: 19 | result += f"You did not manage to accommodate all pets!\n" 20 | 21 | result += "Accommodated pets:\n" 22 | 23 | if accommodated_pets: 24 | sorted_pets = sorted(accommodated_pets.items(), key=lambda kvp: kvp[0]) 25 | for pet_name, pet_weight in sorted_pets: 26 | result += f"{pet_name}: {pet_weight}\n" 27 | return result[:-1] 28 | 29 | 30 | 31 | 32 | from unittest import TestCase, main 33 | 34 | 35 | class Test(TestCase): 36 | def test_accommodate_pets(self): 37 | result = accommodate_new_pets( 38 | 1, 39 | 5.0, 40 | ("dog", 17.0), 41 | ("cat", 15.8), 42 | ("dog", 22.7), 43 | ("dog", 15.01), 44 | 45 | ) 46 | 47 | self.assertEqual( 48 | result.strip(), 49 | """All pets are accommodated! Available capacity: 1. 50 | Accommodated pets:""") 51 | 52 | 53 | if __name__ == '__main__': 54 | main() 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /encapsulation/ex_3.py: -------------------------------------------------------------------------------- 1 | class Profile: 2 | def __init__(self, username, password): 3 | self.username = username 4 | self.password = password 5 | 6 | @property 7 | def username(self): 8 | return self.__username 9 | 10 | @username.setter 11 | def username(self, value): 12 | if len(value) < 5 or len(value) > 15: 13 | raise ValueError("The username must be between 5 and 15 characters.") 14 | self.__username = value 15 | 16 | 17 | @property 18 | def password(self): 19 | return self.__password 20 | 21 | @password.setter 22 | def password(self, value): 23 | is_length_valid = len(value) >= 8 24 | is_upper_case_presented = len([c for c in value if c.isupper()]) > 0 25 | is_digit_presented = len([c for c in value if c.isdigit()]) > 0 26 | 27 | is_valid = is_length_valid and is_upper_case_presented and is_digit_presented 28 | 29 | if not is_valid: 30 | raise ValueError("The password must be 8 or more characters with at least 1 digit and 1 uppercase letter.") 31 | self.__password = value 32 | 33 | def __str__(self): 34 | return (f'You have a profile with username: ' 35 | f'"{self.__username}" and password: {"*" * len(self.__password)}') 36 | 37 | 38 | class ExtendProfile(Profile): 39 | def __init__(self, username, password, age): 40 | super().__init__(username, password) 41 | self.age = age 42 | 43 | @property 44 | def age(self): 45 | return 46 | 47 | @age.setter 48 | def age(self, value): 49 | pass 50 | 51 | correct_profile = ExtendProfile("Username", "1", 12) 52 | print(correct_profile) 53 | -------------------------------------------------------------------------------- /solid/isp/interface.py: -------------------------------------------------------------------------------- 1 | class EntertainmentDevice: 2 | def connect_device_to_power_outlet(self, device): pass 3 | 4 | 5 | 6 | class ConnectRCA: 7 | def rca_connect(self, obj): 8 | pass 9 | 10 | 11 | class ConnectHDMI: 12 | def hdmi_connect(self, obj): 13 | pass 14 | 15 | 16 | class ConnectEthernet: 17 | def ethernet_connect(self, obj): 18 | pass 19 | 20 | class Television(EntertainmentDevice, ConnectRCA, ConnectHDMI): 21 | def connect_to_dvd(self, dvd_player): 22 | super().rca_connect(dvd_player) 23 | 24 | def connect_to_game_console(self, game_console): 25 | super().hdmi_connect(game_console) 26 | 27 | def plug_in_power(self): 28 | self.connect_device_to_power_outlet(self) 29 | 30 | 31 | class DVDPlayer(EntertainmentDevice, ConnectHDMI): 32 | def connect_to_tv(self, television): 33 | super().hdmi_connect(television) 34 | 35 | def plug_in_power(self): 36 | self.connect_device_to_power_outlet(self) 37 | 38 | 39 | class GameConsole(EntertainmentDevice, ConnectHDMI, ConnectEthernet): 40 | def connect_to_tv(self, television): 41 | super().hdmi_connect(television) 42 | 43 | def connect_to_router(self, router): 44 | super().ethernet_connect(router) 45 | 46 | def plug_in_power(self): 47 | self.connect_device_to_power_outlet(self) 48 | 49 | 50 | class Router(EntertainmentDevice, ConnectEthernet): 51 | def connect_to_tv(self, television): 52 | super().ethernet_connect(television) 53 | 54 | def connect_to_game_console(self, game_console): 55 | super().ethernet_connect(game_console) 56 | 57 | def plug_in_power(self): 58 | self.connect_device_to_power_outlet(self) 59 | -------------------------------------------------------------------------------- /design_patterns/command_pattern.py: -------------------------------------------------------------------------------- 1 | # check size 2 | # check headers (column names, missing?) 3 | # check data in column Age (all rows should be with values) 4 | 5 | 6 | from abc import ABC, abstractmethod 7 | class Invoker: 8 | def __init__(self): 9 | self._commands = [] 10 | 11 | def store_command(self, command): 12 | self._commands.append(command) 13 | 14 | def execute_commands(self): 15 | for command in self._commands: 16 | command.execute() 17 | 18 | 19 | class Command(ABC): 20 | def __init__(self, receiver): 21 | self._receiver = receiver 22 | 23 | @abstractmethod 24 | def execute(self): 25 | pass 26 | 27 | 28 | class CheckSizeCommand(Command): 29 | def execute(self): 30 | if len(self._receiver) < 3: 31 | raise ValueError("File is below certain size") 32 | 33 | 34 | class HeaderCheckerFile(Command): 35 | def execute(self): 36 | if self._receiver.columns != ["name", "age"]: 37 | raise ValueError("Headers are invalid") 38 | 39 | 40 | class AgeColumnCheckerFile(Command): 41 | def execute(self): 42 | if len(self._receiver['age']) != len([el for el in self._receiver['age'] if el is not None]): 43 | raise ValueError("Headers are invalid") 44 | 45 | 46 | class Receiver: 47 | def action(self): 48 | pass 49 | 50 | 51 | 52 | def main(): 53 | receiver = Receiver() 54 | concrete_command = HeaderCheckerFile(receiver) 55 | cc2 = CheckSizeCommand(receiver) 56 | cc3 = AgeColumnCheckerFile(receiver) 57 | invoker = Invoker() 58 | invoker.store_command(concrete_command) 59 | invoker.store_command(cc2) 60 | invoker.store_command(cc3) 61 | 62 | invoker.execute_commands() 63 | 64 | if __name__ == "__main__": 65 | main() 66 | 67 | -------------------------------------------------------------------------------- /exam_prep_2/ex_2_delivery_boy.py: -------------------------------------------------------------------------------- 1 | def is_in_scope(row_index, col_index, row_count, col_count): 2 | return 0 <= row_index < row_count and 0 <= col_index < col_count 3 | 4 | 5 | direction_mapper = { 6 | "up": (-1, 0), 7 | "down": (1, 0), 8 | "left": (0, -1), 9 | "right": (0, 1), 10 | } 11 | 12 | 13 | n, m = [int(el) for el in input().split()] 14 | 15 | matrix = [] 16 | initial_position = None 17 | 18 | for row_index in range(n): 19 | data = list(input()) 20 | 21 | if "B" in data: 22 | col_index = data.index("B") 23 | initial_position = (row_index, col_index) 24 | matrix.append(data) 25 | 26 | 27 | current_position = initial_position 28 | 29 | while True: 30 | direction = input() 31 | 32 | current_row_index, current_col_index = current_position 33 | row_movement, col_movement = direction_mapper[direction] 34 | desired_row = current_row_index + row_movement 35 | desired_col = current_col_index + col_movement 36 | 37 | if not is_in_scope(desired_row, desired_col, n, m): 38 | matrix[initial_position[0]][initial_position[1]] = " " 39 | print(f"The delivery is late. Order is canceled.") 40 | break 41 | 42 | symbol = matrix[desired_row][desired_col] 43 | 44 | if symbol == "*": 45 | continue 46 | 47 | current_position = [desired_row, desired_col] 48 | 49 | if symbol == "P": 50 | print(f"Pizza is collected. 10 minutes for delivery.") 51 | matrix[desired_row][desired_col] = "R" 52 | 53 | elif symbol == "A": 54 | matrix[desired_row][desired_col] = "P" 55 | print(f"Pizza is delivered on time! Next order...") 56 | break 57 | 58 | elif symbol == "-": 59 | matrix[desired_row][desired_col] = "." 60 | 61 | 62 | for row in matrix: 63 | print(''.join(row)) -------------------------------------------------------------------------------- /encapsulation_ex/pizza/project/pizza.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | 3 | from project.topping import Topping 4 | 5 | 6 | class Pizza: 7 | def __init__(self, name: str, dough: Dough, max_number_of_toppings: int): 8 | self.name = name 9 | self.dough = dough 10 | self.max_number_of_toppings = max_number_of_toppings 11 | self.toppings = {} 12 | 13 | @property 14 | def name(self): 15 | return self.__name 16 | 17 | @name.setter 18 | def name(self, value): 19 | if value == "": 20 | raise ValueError("The name cannot be an empty string") 21 | self.__name = value 22 | 23 | @property 24 | def dough(self): 25 | return self.__dough 26 | 27 | @dough.setter 28 | def dough(self, value): 29 | if value is None: 30 | raise ValueError("You should add dough to the pizza") 31 | self.__dough = value 32 | 33 | @property 34 | def max_number_of_toppings(self): 35 | return self.__max_number_of_toppings 36 | 37 | @max_number_of_toppings.setter 38 | def max_number_of_toppings(self, value) -> None: 39 | if value <= 0: 40 | raise ValueError("The maximum number of toppings cannot be less or equal to zero") 41 | self.__max_number_of_toppings = value 42 | 43 | def add_topping(self, topping: Topping): 44 | if len(self.toppings) >= self.max_number_of_toppings: 45 | raise ValueError("Not enough space for another topping") 46 | 47 | if topping.topping_type in self.toppings: 48 | self.toppings[topping.topping_type] += topping.weight 49 | else: 50 | self.toppings[topping.topping_type] = topping.weight 51 | 52 | 53 | def calculate_total_weight(self): 54 | toppings_weight = sum(self.toppings.values()) 55 | pizza_wight = self.dough.weight + toppings_weight 56 | return pizza_wight -------------------------------------------------------------------------------- /exam_prep_2/ex_2.py: -------------------------------------------------------------------------------- 1 | def is_in_boundaries(row_index, col_index, n): 2 | return 0 <= row_index < n and 0 <= col_index < n 3 | 4 | 5 | def print_board(board): 6 | for row in board: 7 | print(''.join(row)) 8 | 9 | 10 | direction_mapper = { 11 | "up": (-1, 0), 12 | "down": (1, 0), 13 | "left": (0, -1), 14 | "right": (0, 1), 15 | } 16 | 17 | n = int(input()) 18 | 19 | board = [] 20 | player_position = None 21 | 22 | for row_index in range(n): 23 | data = list(input()) 24 | 25 | if "G" in data: 26 | col_index = data.index("G") 27 | player_position = [row_index, col_index] 28 | board.append(data) 29 | 30 | 31 | direction = input() 32 | money = 100 33 | 34 | while direction != "end": 35 | current_row_index, current_col_index = player_position 36 | row_movement, col_movement = direction_mapper[direction] 37 | desired_row_index = current_row_index + row_movement 38 | desired_col_index = current_col_index + col_movement 39 | 40 | if not is_in_boundaries(desired_row_index, desired_col_index, n): 41 | print("Game over! You lost everything!") 42 | exit() 43 | 44 | symbol = board[desired_row_index][desired_col_index] 45 | board[desired_row_index][desired_col_index] = "G" 46 | board[current_row_index][current_col_index] = "-" 47 | player_position = [desired_row_index, desired_col_index] 48 | 49 | if symbol == "W": 50 | money += 100 51 | elif symbol == "P": 52 | money -= 200 53 | if money <= 0: 54 | money = 0 55 | print(f"Game over! You lost everything!") 56 | exit() 57 | elif symbol == "J": 58 | money += 100000 59 | print(f"You win the Jackpot!") 60 | print(f"End of the game. Total amount: {money}$") 61 | print_board(board) 62 | exit() 63 | 64 | direction = input() 65 | 66 | print(f"End of the game. Total amount: {money}$") 67 | print_board(board) 68 | -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/project/divers/base_diver.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | from typing import List 3 | 4 | from project.fish.base_fish import BaseFish 5 | 6 | 7 | class BaseDiver(ABC): 8 | def __init__(self, name: str, oxygen_level: float): 9 | self.name = name 10 | self.oxygen_level = oxygen_level 11 | self.catch: List[BaseFish] = [] 12 | self.__competition_points = 0.0 13 | self.has_health_issue = False 14 | 15 | @property 16 | def competition_points(self) -> float: 17 | return round(self.__competition_points, 1) 18 | 19 | @property 20 | def name(self): 21 | return self.__name 22 | 23 | @name.setter 24 | def name(self, value): 25 | if value.strip() == "": 26 | raise ValueError("Diver name cannot be null or empty!") 27 | self.__name = value 28 | 29 | @property 30 | def oxygen_level(self): 31 | return self.__oxygen_level 32 | 33 | @oxygen_level.setter 34 | def oxygen_level(self, value): 35 | if value < 0: 36 | raise ValueError("Cannot create diver with negative oxygen level!") 37 | self.__oxygen_level = value 38 | 39 | @abstractmethod 40 | def miss(self, time_to_catch: int): 41 | pass 42 | 43 | @abstractmethod 44 | def renew_oxy(self): 45 | pass 46 | 47 | def hit(self, fish: BaseFish): 48 | 49 | if self.oxygen_level < fish.time_to_catch: 50 | self.oxygen_level = 0 51 | else: 52 | self.catch.append(fish) 53 | self.__competition_points += fish.points 54 | self.oxygen_level -= fish.time_to_catch 55 | 56 | def update_health_status(self): 57 | self.has_health_issue = not self.has_health_issue 58 | 59 | def __str__(self): 60 | return (f"{self.__class__.__name__}: " 61 | f"[Name: {self.name}, " 62 | f"Oxygen level left: {self.oxygen_level}, " 63 | f"Fish caught: {len(self.catch)}, " 64 | f"Points earned: {self.competition_points}]") -------------------------------------------------------------------------------- /solid/srp/book.py: -------------------------------------------------------------------------------- 1 | class Book: 2 | def __init__(self, title, author): 3 | self.title = title 4 | self.author = author 5 | self.page = 0 6 | 7 | def turn_page(self, page): 8 | self.page = page 9 | 10 | def __repr__(self): 11 | return f"Title {self.title} by {self.author}" 12 | 13 | 14 | class Library: 15 | def __init__(self, books): 16 | self.books: list[Book] = books 17 | 18 | def add_book(self, book: Book): 19 | self.books.append(book) 20 | 21 | def remove_book(self, title): 22 | to_remove = [b for b in self.books if b.title == title] 23 | 24 | if not to_remove: 25 | raise ValueError("No such title") 26 | 27 | if len(to_remove) > 1: 28 | raise ValueError("Too many books were found") 29 | 30 | self.books.remove(to_remove[0]) 31 | 32 | def get_books_by_author(self, author): 33 | return [b for b in self.books if b.author == author] 34 | 35 | def get_books_by_title(self, title): 36 | books = [b for b in self.books if b.title == title] 37 | 38 | if not books: 39 | raise ValueError("No such title") 40 | 41 | return books 42 | 43 | def get_book_by_title(self, title): 44 | try: 45 | next(filter(lambda x: x.title == title, self.books)) 46 | except StopIteration: 47 | return "No such record" 48 | try: 49 | filter(lambda x: x.title == title, self.books) 50 | [b for b in self.books if b.title == title][0] 51 | except IndexError: 52 | return None 53 | 54 | 55 | 56 | # book = Book("1", "a") 57 | # book2 = Book("2", "a") 58 | # book3 = Book("3", "b") 59 | # 60 | # lib = Library([book, book2, book3]) 61 | # 62 | # print(lib.get_books_by_title("1")) 63 | # print(lib.get_books_by_author("a")) 64 | # book4 = Book("4", "c") 65 | # 66 | # lib.add_book(book4) 67 | # 68 | # print(lib.get_books_by_title("4")) 69 | # 70 | # print(lib.get_books_by_author("5")) 71 | # print(lib.get_books_by_title("non")) 72 | 73 | if __name__ == "__main__": 74 | book = Book("1", "a") 75 | book2 = Book("2", "a") 76 | book3 = Book("3", "b") 77 | 78 | lib = Library([book, book2, book3]) 79 | 80 | print(lib.get_book_by_title("1")) 81 | -------------------------------------------------------------------------------- /.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 | .env_tests 107 | .env_prod 108 | .venv 109 | env/ 110 | venv/ 111 | ENV/ 112 | env.bak/ 113 | venv.bak/ 114 | 115 | # Spyder project settings 116 | .spyderproject 117 | .spyproject 118 | 119 | # Rope project settings 120 | .ropeproject 121 | 122 | # mkdocs documentation 123 | /site 124 | 125 | # mypy 126 | .mypy_cache/ 127 | .dmypy.json 128 | dmypy.json 129 | 130 | # Pyre type checker 131 | .pyre/ 132 | 133 | .idea/ 134 | .DS_Store 135 | 136 | logs.json 137 | 138 | temp_test_filesfiles/* 139 | google-creds.json 140 | 141 | .serverless/ 142 | nmible-fffc8-8baba03007f9.json 143 | some.py -------------------------------------------------------------------------------- /exam_prep_1/ex_2.py: -------------------------------------------------------------------------------- 1 | def get_next_position(position, direction_mapper, direction, matrix): 2 | current_row_index, current_col_index = position 3 | row_movement, col_movement = direction_mapper[direction] 4 | desired_row_index = current_row_index + row_movement 5 | desired_col_index = current_col_index + col_movement 6 | 7 | # if 0 <= desired_row_index < len(matrix) and 0 <= desired_col_index < len(matrix): 8 | # return desired_row_index, desired_col_index 9 | 10 | desired_row_index = (desired_row_index + len(matrix)) % len(matrix) 11 | desired_col_index = (desired_col_index + len(matrix)) % len(matrix) 12 | 13 | # if desired_row_index < 0: 14 | # desired_row_index = len(matrix) - 1 15 | # elif desired_row_index >= len(matrix): 16 | # desired_row_index = 0 17 | # 18 | # if desired_col_index < 0: 19 | # desired_col_index = len(matrix) - 1 20 | # elif desired_col_index >= len(matrix): 21 | # desired_col_index = 0 22 | 23 | return desired_row_index, desired_col_index 24 | 25 | 26 | n = int(input()) 27 | 28 | direction_mapper = { 29 | "up": (-1, 0), 30 | "down": (1, 0), 31 | "right": (0, 1), 32 | "left": (0, -1), 33 | } 34 | 35 | matrix = [] 36 | position = None 37 | 38 | for row_index in range(n): 39 | data = list(input()) 40 | 41 | if "S" in data: 42 | current_col = data.index("S") 43 | position = [row_index, current_col] 44 | matrix.append(data) 45 | 46 | 47 | command = input() 48 | collected_fish = 0 49 | 50 | while command != "collect the nets": 51 | current_row_index, current_col_index = position 52 | next_row_index, next_col_index = get_next_position(position, direction_mapper, command, matrix) 53 | 54 | symbol = matrix[next_row_index][next_col_index] 55 | matrix[next_row_index][next_col_index] = "S" 56 | matrix[current_row_index][current_col_index] = "-" 57 | position = [next_row_index, next_col_index] 58 | 59 | if symbol.isdigit(): 60 | collected_fish += int(symbol) 61 | elif symbol == "W": 62 | print(f"You fell into a whirlpool! " 63 | f"The ship sank and you lost the fish you caught. " 64 | f"Last coordinates of the ship: [{position[0]},{position[1]}]") 65 | exit() 66 | 67 | command = input() 68 | 69 | 70 | if collected_fish >= 20: 71 | print(f"Success! You managed to reach the quota!") 72 | else: 73 | print(f"You didn't catch enough fish and didn't reach the quota! " 74 | f"You need {20 - collected_fish} tons of fish more.") 75 | 76 | if collected_fish > 0: 77 | print(f"Amount of fish caught: {collected_fish} tons.") 78 | 79 | for row in matrix: 80 | print(f"{''.join(row)}") 81 | -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/project/main.py: -------------------------------------------------------------------------------- 1 | # !! Do not forget to change the root if you want to run it from this repo 2 | 3 | 4 | from project.nautical_catch_challenge_app import NauticalCatchChallengeApp 5 | 6 | nautical_catch_challenge = NauticalCatchChallengeApp() 7 | 8 | # Dive into competition 9 | print(nautical_catch_challenge.dive_into_competition("ScubaDiver", "MaxineHarper")) 10 | print(nautical_catch_challenge.dive_into_competition("FreeDiver", "JamalCarter")) 11 | print(nautical_catch_challenge.dive_into_competition("SkyDiver", "FionaBennett")) 12 | print(nautical_catch_challenge.dive_into_competition("FreeDiver", "OscarWallace")) 13 | print(nautical_catch_challenge.dive_into_competition("ScubaDiver", "LilaMoreno")) 14 | print(nautical_catch_challenge.dive_into_competition("FreeDiver", "LilaMoreno")) 15 | 16 | # Swim into competition 17 | print(nautical_catch_challenge.swim_into_competition("ReefFish", "AzureDamselfish", 8.7)) 18 | print(nautical_catch_challenge.swim_into_competition("DeepSeaFish", "BluestripeSnapper", 6.3)) 19 | print(nautical_catch_challenge.swim_into_competition("PredatoryFish", "YellowtailSurgeonfish", 5.0)) 20 | print(nautical_catch_challenge.swim_into_competition("PredatoryFish", "Barracuda", 9.2)) 21 | print(nautical_catch_challenge.swim_into_competition("PredatoryFish", "Coryphaena", 9.7)) 22 | print(nautical_catch_challenge.swim_into_competition("PredatoryFish", "Bluefish", 4.4)) 23 | print(nautical_catch_challenge.swim_into_competition("DeepSeaFish", "SwordFish", 10.0)) 24 | print(nautical_catch_challenge.swim_into_competition("DeepSeaFish", "Mahi-Mahi", 9.1)) 25 | print(nautical_catch_challenge.swim_into_competition("DeepSeaFish", "Tuna", 8.5)) 26 | print(nautical_catch_challenge.swim_into_competition("AquariumFish", "SilverArowana", 3.3)) 27 | print(nautical_catch_challenge.swim_into_competition("DeepSeaFish", "Barracuda", 8.6)) 28 | 29 | # Conduct fishing competitions 30 | print(nautical_catch_challenge.chase_fish("FionaBennett", "AzureDamselfish", False)) 31 | print(nautical_catch_challenge.chase_fish("JamalCarter", "SilverArowana", True)) 32 | print(nautical_catch_challenge.chase_fish("MaxineHarper", "YellowtailSurgeonfish", False)) 33 | print(nautical_catch_challenge.chase_fish("MaxineHarper", "Mahi-Mahi", False)) 34 | print(nautical_catch_challenge.chase_fish("MaxineHarper", "Tuna", False)) 35 | print(nautical_catch_challenge.chase_fish("MaxineHarper", "Coryphaena", True)) 36 | print(nautical_catch_challenge.chase_fish("MaxineHarper", "BluestripeSnapper", True)) 37 | print(nautical_catch_challenge.chase_fish("OscarWallace", "Barracuda", False)) 38 | print(nautical_catch_challenge.chase_fish("OscarWallace", "YellowtailSurgeonfish", False)) 39 | print(nautical_catch_challenge.chase_fish("OscarWallace", "Tuna", True)) 40 | print(nautical_catch_challenge.chase_fish("JamalCarter", "Barracuda", True)) 41 | print(nautical_catch_challenge.chase_fish("JamalCarter", "YellowtailSurgeonfish", True)) 42 | print(nautical_catch_challenge.chase_fish("LilaMoreno", "Tuna", False)) 43 | print(nautical_catch_challenge.chase_fish("LilaMoreno", "Mahi-Mahi", False)) 44 | print(nautical_catch_challenge.chase_fish("LilaMoreno", "SwordFish", True)) 45 | 46 | # Check health recovery 47 | print(nautical_catch_challenge.health_recovery()) 48 | 49 | # Conduct fishing competitions 50 | print(nautical_catch_challenge.chase_fish("LilaMoreno", "Tuna", False)) 51 | print(nautical_catch_challenge.chase_fish("LilaMoreno", "Mahi-Mahi", False)) 52 | print(nautical_catch_challenge.chase_fish("LilaMoreno", "SwordFish", True)) 53 | 54 | # View catch reports 55 | print(nautical_catch_challenge.diver_catch_report("LilaMoreno")) 56 | 57 | # View competition statistics 58 | print(nautical_catch_challenge.competition_statistics()) 59 | -------------------------------------------------------------------------------- /workshop_create_4/game.py: -------------------------------------------------------------------------------- 1 | class FullColumnError(Exception): 2 | pass 3 | 4 | 5 | class InvalidColumnChoice(Exception): 6 | pass 7 | 8 | 9 | ROWS = 6 10 | COLS = 7 11 | MAXIMUM_CONNECTIONS = 4 12 | 13 | 14 | DIRECTION_MAPPER = { 15 | "left": (0, -1), 16 | "up": (-1, 0), 17 | "main_diagonal": (-1, -1), 18 | "other_diagonal": (-1, 1), 19 | } 20 | 21 | 22 | def travel_direction(coordinates, current_row, current_col, element, sign, board): 23 | count = 0 24 | row_direction, col_direction = coordinates 25 | 26 | for i in range(1, MAXIMUM_CONNECTIONS): 27 | next_element_row_index = eval(f"{current_row} {sign} {row_direction} * {i}") 28 | next_element_col_index = eval(f"{current_col} {sign} {col_direction} * {i}") 29 | 30 | try: 31 | if board[next_element_row_index][next_element_col_index] == element: 32 | count += 1 33 | else: 34 | return count 35 | except IndexError: 36 | return count 37 | return count 38 | 39 | 40 | # def travel_opposite_direction(coordinates, current_row, current_col, element, board): 41 | # count = 0 42 | # row_direction, col_direction = coordinates 43 | # 44 | # for i in range(1, MAXIMUM_CONNECTIONS): 45 | # next_element_row_index = current_row - row_direction * i 46 | # next_element_col_index = current_col - col_direction * i 47 | # 48 | # try: 49 | # if board[next_element_row_index][next_element_col_index] == element: 50 | # count += 1 51 | # else: 52 | # return count 53 | # except IndexError: 54 | # return count 55 | 56 | 57 | def is_winner(current_row_index, current_col_index, board): 58 | for direction, coords in DIRECTION_MAPPER.items(): 59 | searched_element = board[current_row_index][current_col_index] 60 | travel_direction_count = travel_direction(coords, current_row_index, current_col_index, searched_element, "+", board) 61 | travel_opposite_direction_count = travel_direction(coords, current_row_index, current_col_index, searched_element, "-", board) 62 | 63 | if travel_direction_count + travel_opposite_direction_count + 1 >= MAXIMUM_CONNECTIONS: 64 | return True 65 | else: 66 | return False 67 | 68 | def print_board(board): 69 | for row in board: 70 | print(row) 71 | 72 | 73 | def validate_column_choice(col): 74 | if 1 <= col <= COLS: 75 | return True 76 | raise InvalidColumnChoice 77 | 78 | 79 | def get_first_available_row(col_index, board): 80 | for row_index in range(ROWS-1, -1, -1): 81 | if board[row_index][col_index] == 0: 82 | return row_index 83 | else: 84 | raise FullColumnError 85 | 86 | 87 | def is_board_full(turns): 88 | return ROWS*COLS <= turns 89 | 90 | 91 | board = [] 92 | 93 | for _ in range(ROWS): 94 | board.append([0 for _ in range(COLS)]) 95 | 96 | turns = 1 97 | 98 | while True: 99 | player = 2 if turns % 2 == 0 else 1 100 | 101 | try: 102 | column = int(input(f"Player {player}, please choose a column: ")) 103 | validate_column_choice(column) 104 | column_index = int(column) - 1 105 | row = get_first_available_row(column_index, board) 106 | board[row][column_index] = player 107 | turns += 1 108 | if is_winner(row, column_index, board): 109 | break 110 | if is_board_full(turns): 111 | print("Board is full, nobody wins") 112 | exit(0) 113 | except FullColumnError as ex: 114 | print(f"This column is full, please select another one") 115 | continue 116 | except (InvalidColumnChoice, ValueError): 117 | print(f"This column is invalid, please select a number between 1 and {COLS}") 118 | continue 119 | 120 | print_board(board) 121 | 122 | 123 | print_board(board) 124 | print(f"WINNER is player {player}") 125 | -------------------------------------------------------------------------------- /workshop__custom_dictionary/custom_hashtable.py: -------------------------------------------------------------------------------- 1 | from copy import deepcopy 2 | 3 | 4 | class HashTable: 5 | def __init__(self): 6 | self.__keys = [None, None, None, None] 7 | self.__values = [None, None, None, None] 8 | self.__length = 4 9 | 10 | @property 11 | def count(self): 12 | return len([el for el in self.__keys if el is not None]) 13 | 14 | def __len__(self): 15 | return self.__length 16 | 17 | def __getitem__(self, item): 18 | try: 19 | index = self.__keys.index(item) 20 | return self.__values[index] 21 | except ValueError: 22 | raise KeyError("Key does not exist") 23 | 24 | def __setitem__(self, key, value): 25 | try: 26 | existing_value_index = self.__keys.index(key) 27 | self.__values[existing_value_index] = value 28 | except ValueError: 29 | if self.count == self.__length: 30 | # Resize the lists, so that we have space for the new value 31 | self.__resize() 32 | 33 | index = self.__find_index(self.hash(key)) 34 | self.__keys[index] = key 35 | self.__values[index] = value 36 | 37 | def __find_index(self, index): 38 | if index == self.__length: 39 | index = 0 40 | if self.__keys[index] is None: 41 | return index 42 | return self.__find_index(index + 1) 43 | 44 | def hash(self, key: str) -> int: 45 | return sum([ord(el) for el in key]) % self.__length 46 | 47 | def __resize(self): 48 | self.__keys = self.__keys + [None] * self.__length 49 | self.__values = self.__values + [None] * self.__length 50 | self.__length *= 2 51 | 52 | def get(self, key, return_default_value=None): 53 | try: 54 | index = self.__keys.index(key) 55 | return self.__values[index] 56 | except ValueError: 57 | return return_default_value 58 | 59 | def sort(self): 60 | copy_keys = [el for el in self.__keys if el is not None] 61 | copy_values = [el for el in self.__values if el is not None] 62 | 63 | result = list(zip(copy_keys, copy_values)) 64 | sorted_result = sorted(result, key=lambda t: t[0]) 65 | table = HashTable() 66 | table._HashTable__keys = [t[0] for t in sorted_result] 67 | table._HashTable__values = [t[1] for t in sorted_result] 68 | table._HashTable__length = self.__length 69 | diff = self.__length - self.count 70 | table._HashTable__keys = table._HashTable__keys + [None] * diff 71 | table._HashTable__values = table._HashTable__values + [None] * diff 72 | 73 | return table 74 | 75 | def sort_by_values_ascending(self): 76 | # TODO at home 77 | pass 78 | 79 | def sort_by_keys_descending(self): 80 | # TODO at home 81 | pass 82 | 83 | def sort_by_values_descending(self): 84 | # TODO at home 85 | pass 86 | 87 | 88 | def add(self, key, value): 89 | self.__setitem__(key, value) 90 | 91 | def __str__(self): 92 | result = [ 93 | f"{self.__keys[index]}: {self.__values[index]}" 94 | for index in range(self.__length) 95 | if self.__keys[index] is not None 96 | ] 97 | return "{ " + ", ".join(result) + " }" 98 | 99 | 100 | 101 | 102 | 103 | 104 | table = HashTable() 105 | 106 | table["name"] = "Peter" 107 | table["age"] = 25 108 | table["id"] = 1 109 | table["city"] = "Plovdiv" 110 | table["street"] = "Markovo Tepe" 111 | table["name"] = "Test" 112 | 113 | print(table) 114 | sorted_table = table.sort() 115 | 116 | print(type(table)) 117 | print(type(sorted_table)) 118 | # print(table.get("name")) 119 | # print(table.get("asd", "Me")) 120 | # table.add("number", "8") 121 | 122 | 123 | # TODO implement .sort() for sorting 124 | 125 | 126 | 127 | 128 | print(table["age"]) 129 | # print(table["asd"]) 130 | 131 | print(len(table)) 132 | print(table.count) 133 | sorted_table.add("new_key", 8) 134 | print(sorted_table) 135 | 136 | -------------------------------------------------------------------------------- /workshop_custom_list/custom_list.py: -------------------------------------------------------------------------------- 1 | from collections.abc import Iterable 2 | 3 | from workshop_custom_list.custom_exceptions import EmptyListException 4 | 5 | 6 | class CustomList: 7 | def __init__(self): 8 | self.__values = [] 9 | 10 | def __check_index(self, index): 11 | if not isinstance(index, int): 12 | raise TypeError("Index must be of type integer") 13 | if index < 0: 14 | raise ValueError("Integer must be 0 or positive") 15 | if index >= len(self.__values): 16 | raise ValueError("Index is out of range") 17 | 18 | def append(self, value): 19 | self.__values.append(value) 20 | return self.__values 21 | 22 | def remove(self, index): 23 | self.__check_index(index) 24 | return self.__values.pop(index) 25 | 26 | def get(self, index): 27 | self.__check_index(index) 28 | return self.__values[index] 29 | 30 | def extend(self, iterable): 31 | if not isinstance(iterable, Iterable): 32 | raise ValueError("Value is not an iterable") 33 | 34 | self.__values.extend(iterable) 35 | return self.__values 36 | 37 | def insert(self, index, value): 38 | self.__check_index(index) 39 | self.__values.insert(index, value) 40 | return self.__values 41 | 42 | def pop(self): 43 | if not self.__values: 44 | raise EmptyListException("Can not pop from an empty list") 45 | return self.__values.pop() 46 | 47 | def clear(self): 48 | self.__values.clear() 49 | 50 | def index(self, value): 51 | if value not in self.__values: 52 | raise ValueError("Value is not in the list") 53 | return self.__values.index(value) 54 | 55 | def count(self, value): 56 | return self.__values.count(value) 57 | 58 | def reverse(self): 59 | return self.__values[::-1] 60 | 61 | def copy(self): 62 | return self.__values[:] 63 | 64 | def size(self): 65 | return len(self.__values) 66 | 67 | def add_first(self, value): 68 | self.__values.insert(0, value) 69 | 70 | def dictionize(self): 71 | data = {} 72 | for index in range(0, len(self.__values), 2): 73 | key = self.__values[index] 74 | 75 | try: 76 | value = self.__values[index+1] 77 | except IndexError: 78 | value = " " 79 | 80 | data[key] = value 81 | return data 82 | 83 | def move(self, n): 84 | 85 | if not isinstance(n, int) or n < 0: 86 | raise ValueError("Value is not a valid int") 87 | 88 | self.__values = self.__values[n:] + self.__values[:n] 89 | return self.__values 90 | 91 | def sum(self): 92 | total = 0 93 | 94 | for el in self.__values: 95 | if isinstance(el, Iterable): 96 | total += len(el) 97 | else: 98 | total += el 99 | 100 | return total 101 | 102 | 103 | def overbound(self): 104 | max_value = float('-inf') 105 | max_value_index = None 106 | 107 | for index in range(0, len(self.__values)): 108 | current_element = self.__values[index] 109 | 110 | if isinstance(current_element, Iterable): 111 | current_element = len(current_element) 112 | 113 | if max_value < current_element: 114 | max_value = current_element 115 | max_value_index = index 116 | 117 | return max_value_index 118 | 119 | def underbound(self): 120 | min_value = float('inf') 121 | min_value_index = None 122 | 123 | for index in range(0, len(self.__values)): 124 | current_element = self.__values[index] 125 | 126 | if isinstance(current_element, Iterable): 127 | current_element = len(current_element) 128 | 129 | if min_value > current_element: 130 | min_value = current_element 131 | min_value_index = index 132 | 133 | return min_value_index 134 | 135 | 136 | -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/exam_part_tests/project/test/test.py: -------------------------------------------------------------------------------- 1 | # !! Do not forget to change the root if you want to run it from this repo 2 | 3 | from collections import deque 4 | from unittest import TestCase, main 5 | 6 | from project.railway_station import RailwayStation 7 | 8 | 9 | class TestRailwayStation(TestCase): 10 | def setUp(self): 11 | self.s = RailwayStation("Sofia") 12 | 13 | def test_initialised_correctly(self): 14 | s = RailwayStation("Sofia") 15 | self.assertEqual(s.name, "Sofia") 16 | self.assertEqual(s.arrival_trains, deque()) 17 | self.assertEqual(s.departure_trains, deque()) 18 | 19 | def test_less_name_chars_raises(self): 20 | with self.assertRaises(ValueError) as ex: 21 | s = RailwayStation("So") 22 | self.assertEqual(str(ex.exception), "Name should be more than 3 symbols!") 23 | 24 | with self.assertRaises(ValueError) as ex: 25 | s = RailwayStation("Sof") 26 | self.assertEqual(str(ex.exception), "Name should be more than 3 symbols!") 27 | 28 | def test_new_arrival_on_board(self): 29 | self.assertEqual(len(self.s.arrival_trains), 0) 30 | self.assertEqual(self.s.arrival_trains, deque()) 31 | 32 | self.s.new_arrival_on_board("Some info") 33 | 34 | self.assertEqual(len(self.s.arrival_trains), 1) 35 | self.assertEqual(self.s.arrival_trains, deque(["Some info"])) 36 | 37 | self.s.new_arrival_on_board("Some info 2") 38 | self.assertEqual(len(self.s.arrival_trains), 2) 39 | self.assertEqual(self.s.arrival_trains, deque(["Some info", "Some info 2"])) 40 | 41 | def test_train_has_arrived_other_trains(self): 42 | self.s.new_arrival_on_board("Some info") 43 | 44 | self.assertEqual(len(self.s.arrival_trains), 1) 45 | self.assertEqual(len(self.s.departure_trains), 0) 46 | 47 | train_info = "Some info2" 48 | result = self.s.train_has_arrived(train_info) 49 | expected_message = f"There are other trains to arrive before {train_info}." 50 | self.assertEqual(result, expected_message) 51 | 52 | self.assertEqual(len(self.s.arrival_trains), 1) 53 | self.assertEqual(len(self.s.departure_trains), 0) 54 | 55 | def test_train_has_arrived_go_to_departure(self): 56 | self.s.new_arrival_on_board("Some info") 57 | 58 | self.assertEqual(len(self.s.arrival_trains), 1) 59 | self.assertEqual(len(self.s.departure_trains), 0) 60 | 61 | train_info = "Some info" 62 | result = self.s.train_has_arrived(train_info) 63 | expected_message = f"{train_info} is on the platform and will leave in 5 minutes." 64 | self.assertEqual(result, expected_message) 65 | 66 | self.assertEqual(len(self.s.arrival_trains), 0) 67 | self.assertEqual(len(self.s.departure_trains), 1) 68 | 69 | def test_train_has_left_no_departure_trains(self): 70 | self.s.new_arrival_on_board("Some info") 71 | 72 | self.assertEqual(len(self.s.arrival_trains), 1) 73 | self.assertEqual(len(self.s.departure_trains), 0) 74 | 75 | result = self.s.train_has_left("Some info") 76 | self.assertFalse(result) 77 | 78 | def test_train_has_left_same_info(self): 79 | self.s.new_arrival_on_board("Some info") 80 | self.s.train_has_arrived("Some info") 81 | 82 | self.assertEqual(len(self.s.departure_trains), 1) 83 | self.assertEqual(len(self.s.arrival_trains), 0) 84 | 85 | result = self.s.train_has_left("Some info") 86 | 87 | self.assertTrue(result) 88 | self.assertEqual(len(self.s.departure_trains), 0) 89 | self.assertEqual(len(self.s.arrival_trains), 0) 90 | 91 | self.assertEqual(self.s.departure_trains, deque()) 92 | 93 | def test_train_has_left_different_info(self): 94 | self.s.new_arrival_on_board("Some info") 95 | self.s.train_has_arrived("Some info") 96 | 97 | self.assertEqual(len(self.s.departure_trains), 1) 98 | self.assertEqual(len(self.s.arrival_trains), 0) 99 | 100 | result = self.s.train_has_left("Different info") 101 | 102 | self.assertFalse(result) 103 | self.assertEqual(len(self.s.departure_trains), 1) 104 | self.assertEqual(len(self.s.arrival_trains), 0) 105 | 106 | 107 | if __name__ == "__main__": 108 | main() -------------------------------------------------------------------------------- /exam_prep_divers_amd_tests/project/nautical_catch_challenge_app.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | from project.divers.base_diver import BaseDiver 4 | from project.divers.free_diver import FreeDiver 5 | from project.divers.scuba_diver import ScubaDiver 6 | from project.fish.base_fish import BaseFish 7 | from project.fish.deep_sea_fish import DeepSeaFish 8 | from project.fish.predatory_fish import PredatoryFish 9 | 10 | 11 | class NauticalCatchChallengeApp: 12 | divers_mapper = {"FreeDiver": FreeDiver, "ScubaDiver": ScubaDiver} 13 | fish_mapper = {"PredatoryFish": PredatoryFish, "DeepSeaFish": DeepSeaFish} 14 | 15 | def __init__(self): 16 | self.divers: List[BaseDiver] = [] 17 | self.fish_list: List[BaseFish] = [] 18 | 19 | def dive_into_competition(self, diver_type: str, diver_name: str): 20 | if diver_type not in self.divers_mapper: 21 | return f"{diver_type} is not allowed in our competition." 22 | 23 | try: 24 | diver = [d for d in self.divers if d.name == diver_name][0] 25 | return f"{diver.name} is already a participant." 26 | except IndexError: 27 | new_diver = self.divers_mapper[diver_type](diver_name) 28 | self.divers.append(new_diver) 29 | return f"{diver_name} is successfully registered for the competition as a {diver_type}." 30 | 31 | def swim_into_competition(self, fish_type: str, fish_name: str, points: float): 32 | if fish_type not in self.fish_mapper: 33 | return f"{fish_type} is forbidden for chasing in our competition." 34 | 35 | try: 36 | fish = [f for f in self.fish_list if f.name == fish_name][0] 37 | return f"{fish.name} is already permitted." 38 | except IndexError: 39 | new_fish = self.fish_mapper[fish_type](fish_name, points) 40 | self.fish_list.append(new_fish) 41 | return f"{fish_name} is allowed for chasing as a {fish_type}." 42 | 43 | def chase_fish(self, diver_name: str, fish_name: str, is_lucky: bool): 44 | try: 45 | diver = [d for d in self.divers if d.name == diver_name][0] 46 | except IndexError: 47 | return f"{diver_name} is not registered for the competition." 48 | 49 | try: 50 | fish = [f for f in self.fish_list if f.name == fish_name][0] 51 | except IndexError: 52 | return f"The {fish_name} is not allowed to be caught in this competition." 53 | 54 | if diver.has_health_issue: 55 | return f"{diver_name} will not be allowed to dive, due to health issues." 56 | 57 | if diver.oxygen_level < fish.time_to_catch: 58 | diver.miss(fish.time_to_catch) 59 | message = f"{diver_name} missed a good {fish_name}." 60 | elif diver.oxygen_level == fish.time_to_catch: 61 | if is_lucky: 62 | diver.hit(fish) 63 | message = f"{diver.name} hits a {fish.points}pt. {fish.name}." 64 | else: 65 | diver.miss(fish.time_to_catch) 66 | message = f"{diver_name} missed a good {fish_name}." 67 | else: 68 | diver.hit(fish) 69 | message = f"{diver_name} hits a {fish.points}pt. {fish_name}." 70 | 71 | if diver.oxygen_level == 0: 72 | diver.update_health_status() 73 | return message 74 | 75 | def health_recovery(self): 76 | divers_with_health_issues = [d for d in self.divers if d.has_health_issue] 77 | 78 | for diver in divers_with_health_issues: 79 | diver.has_health_issue = False 80 | diver.renew_oxy() 81 | 82 | return f"Divers recovered: {len(divers_with_health_issues)}" 83 | 84 | def diver_catch_report(self, diver_name: str): 85 | diver = [d for d in self.divers if d.name == diver_name][0] 86 | 87 | result = f"**{diver_name} Catch Report**\n" 88 | 89 | fish_details = "\n".join([fish.fish_details() for fish in diver.catch]) 90 | result += fish_details 91 | return result 92 | 93 | def competition_statistics(self): 94 | healthy_divers = [d for d in self.divers if not d.has_health_issue] 95 | 96 | sorted_divers = sorted( 97 | healthy_divers, key=lambda d: (-d.competition_points, -len(d.catch), d.name) 98 | ) 99 | 100 | result = f"**Nautical Catch Challenge Statistics**\n" 101 | result += '\n'.join(str(d) for d in sorted_divers) 102 | return result -------------------------------------------------------------------------------- /encapsulation_ex/wild_cat_zoo/project/zoo.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | from project.worker import Worker 3 | 4 | 5 | class Zoo: 6 | def __init__(self, name: str, budget: int, animal_capacity: int, workers_capacity: int) -> None: 7 | self.name = name 8 | self.__budget = budget 9 | self.__animal_capacity = animal_capacity 10 | self.__workers_capacity = workers_capacity 11 | self.animals: list[Animal] = [] 12 | self.workers: list[Worker] = [] 13 | 14 | def add_animal(self, animal: Animal, price: int) -> str: 15 | if self.__budget >= price and self.__animal_capacity > len(self.animals): 16 | self.animals.append(animal) 17 | self.__budget -= price 18 | return f"{animal.name} the {animal.__class__.__name__} added to the zoo" 19 | elif self.__animal_capacity > len(self.animals) and self.__budget < price: 20 | return f"Not enough budget" 21 | return "Not enough space for animal" 22 | 23 | def hire_worker(self, worker: Worker) -> str: 24 | if self.__workers_capacity > len(self.workers): 25 | self.workers.append(worker) 26 | return f"{worker.name} the {worker.__class__.__name__} hired successfully" 27 | return "Not enough space for worker" 28 | 29 | def fire_worker(self, worker_name: str) -> str: 30 | try: 31 | worker = [w for w in self.workers if w.name == worker_name][0] 32 | self.workers.remove(worker) 33 | return f"{worker_name} fired successfully" 34 | except IndexError: 35 | return f"There is no {worker_name} in the zoo" 36 | 37 | def pay_workers(self) -> str: 38 | money_to_pay = sum([w.salary for w in self.workers]) 39 | 40 | if money_to_pay <= self.__budget: 41 | self.__budget -= money_to_pay 42 | return f"You payed your workers. They are happy. Budget left: {self.__budget}" 43 | return "You have no budget to pay your workers. They are unhappy" 44 | 45 | def tend_animals(self) -> str: 46 | money_to_feed_animals = sum([a.money_for_care for a in self.animals]) 47 | 48 | if money_to_feed_animals <= self.__budget: 49 | self.__budget -= money_to_feed_animals 50 | return f"You tended all the animals. They are happy. Budget left: {self.__budget}" 51 | return "You have no budget to tend the animals. They are unhappy." 52 | 53 | def profit(self, amount: int) -> None: 54 | self.__budget += amount 55 | 56 | def animals_status(self) -> str: 57 | result = f"You have {len(self.animals)} animals\n" 58 | lions = [a for a in self.animals if a.__class__.__name__ == "Lion"] 59 | amount_of_lions = len(lions) 60 | result += f"----- {amount_of_lions} Lions:\n" 61 | for lion in lions: 62 | result += f"{lion}\n" 63 | 64 | tigers = [t for t in self.animals if t.__class__.__name__ == "Tiger"] 65 | amount_of_tigers = len(tigers) 66 | result += f"----- {amount_of_tigers} Tigers:\n" 67 | for tiger in tigers: 68 | result += f"{tiger}\n" 69 | 70 | cheetahs = [c for c in self.animals if c.__class__.__name__ == "Cheetah"] 71 | amount_of_cheetahs = len(cheetahs) 72 | result += f"----- {amount_of_cheetahs} Cheetahs:\n" 73 | for cheetah in cheetahs: 74 | result += f"{cheetah}\n" 75 | 76 | return result[:-1] 77 | 78 | def workers_status(self) -> str: 79 | result = f"You have {len(self.workers)} workers\n" 80 | 81 | 82 | sub_result = "" 83 | len_keeper = 0 84 | len_caretaker = 0 85 | for w in self.workers: 86 | if w.__class__.__name__ == "Keeper": 87 | len_caretaker += 1 88 | sub_result += f"{w}\n" 89 | 90 | 91 | keepers = [w for w in self.workers if w.__class__.__name__ == "Keeper"] 92 | caretakers = [w for w in self.workers if w.__class__.__name__ == "Caretaker"] 93 | vets = [w for w in self.workers if w.__class__.__name__ == "Vet"] 94 | 95 | result += f"----- {len(keepers)} Keepers:\n" 96 | for k in keepers: 97 | result += f"{k}\n" 98 | 99 | result += f"----- {len(caretakers)} Caretakers:\n" 100 | for c in caretakers: 101 | result += f"{c}\n" 102 | 103 | result += f"----- {len(vets)} Vets:\n" 104 | for v in vets: 105 | result += f"{v}\n" 106 | 107 | return result[:-1] 108 | 109 | -------------------------------------------------------------------------------- /workshop__custom_dictionary/test/test_custom_hashable.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | 3 | from workshop__custom_dictionary.custom_hashtable import HashTable 4 | 5 | 6 | class TestHashTable(TestCase): 7 | def setUp(self): 8 | self.h = HashTable() 9 | 10 | def test_init(self): 11 | self.assertEqual(self.h._HashTable__keys, [None, None, None, None]) 12 | self.assertEqual(self.h._HashTable__values, [None, None, None, None]) 13 | self.assertEqual(self.h._HashTable__length, 4) 14 | 15 | def test_count(self): 16 | result = self.h.count 17 | self.assertEqual(result, 0) 18 | 19 | # TODO test when there is element which is not None 20 | 21 | def test_length(self): 22 | self.assertEqual(len(self.h), 4) 23 | self.assertEqual(len(self.h), self.h._HashTable__length) 24 | 25 | # Test with resizing 26 | self.h["name"] = "Peter" 27 | self.h["age"] = 25 28 | self.h["id"] = 1 29 | self.h["city"] = "Plovdiv" 30 | self.h["street"] = "Markovo Tepe" 31 | 32 | self.assertEqual(len(self.h), 8) 33 | self.assertEqual(len(self.h), self.h._HashTable__length) 34 | 35 | def test_get_item(self): 36 | self.h["name"] = "Peter" 37 | 38 | self.assertEqual(self.h["name"], "Peter") 39 | 40 | def test_get_item_key_not_presented_raises(self): 41 | with self.assertRaises(KeyError) as err: 42 | self.h["no-such-key"] 43 | self.assertEqual(err.exception.args[0], "Key does not exist") 44 | 45 | def test_set_item(self): 46 | self.assertEqual(self.h._HashTable__keys, [None, None, None, None]) 47 | self.assertEqual(self.h._HashTable__values, [None, None, None, None]) 48 | self.assertEqual(self.h._HashTable__length, 4) 49 | 50 | self.h["name"] = "test" 51 | 52 | self.assertEqual(self.h._HashTable__keys, [None, "name", None, None]) 53 | self.assertEqual(self.h._HashTable__values, [None, "test", None, None]) 54 | self.assertEqual(self.h._HashTable__length, 4) 55 | 56 | def test_same_key_is_replaced_with_latest_value(self): 57 | self.assertEqual(self.h._HashTable__keys, [None, None, None, None]) 58 | self.assertEqual(self.h._HashTable__values, [None, None, None, None]) 59 | self.assertEqual(self.h._HashTable__length, 4) 60 | 61 | self.h["name"] = "test" 62 | 63 | self.assertEqual(self.h._HashTable__keys, [None, "name", None, None]) 64 | self.assertEqual(self.h._HashTable__values, [None, "test", None, None]) 65 | self.assertEqual(self.h._HashTable__length, 4) 66 | 67 | self.h["name"] = "test2" 68 | 69 | self.assertEqual(self.h._HashTable__keys, [None, "name", None, None]) 70 | self.assertEqual(self.h._HashTable__values, [None, "test2", None, None]) 71 | self.assertEqual(self.h._HashTable__length, 4) 72 | 73 | def test_more_values_then_current_length_resizes_attributes(self): 74 | self.assertEqual(self.h._HashTable__keys, [None, None, None, None]) 75 | self.assertEqual(self.h._HashTable__values, [None, None, None, None]) 76 | self.assertEqual(self.h._HashTable__length, 4) 77 | 78 | self.h["name"] = "test" 79 | self.h["age"] = 25 80 | self.h["street"] = "new street" 81 | self.h["number"] = 8 82 | 83 | self.assertEqual(self.h._HashTable__keys, ["number", "name", "age", "street"]) 84 | self.assertEqual(self.h._HashTable__values, [8, "test", 25, "new street"]) 85 | self.assertEqual(self.h._HashTable__length, 4) 86 | 87 | self.h['new_value'] = "hi" 88 | self.assertEqual(self.h._HashTable__keys, ["number", "name", "age", "street", None, None, "new_value", None]) 89 | self.assertEqual(self.h._HashTable__values, [8, "test", 25, "new street", None, None, "hi", None]) 90 | self.assertEqual(self.h._HashTable__length, 8) 91 | 92 | def test_hash(self): 93 | result = self.h.hash("name") 94 | 95 | self.assertEqual(result, 1) 96 | 97 | def test_get_existing_value(self): 98 | self.h["name"] = "test" 99 | result = self.h.get("name") 100 | self.assertEqual(result, "test") 101 | 102 | def test_get_non_existing_value_with_no_default_argument(self): 103 | self.assertNotIn("name", self.h._HashTable__keys) 104 | 105 | result = self.h.get("name") 106 | 107 | self.assertIsNone(result) 108 | 109 | def test_get_non_existing_value_with_default_argument(self): 110 | self.assertNotIn("name", self.h._HashTable__keys) 111 | 112 | result = self.h.get("name", "default") 113 | self.assertEqual(result, "default") 114 | 115 | def test_sort(self): 116 | self.h["name"] = "test" 117 | self.h["age"] = 25 118 | 119 | self.assertEqual(self.h._HashTable__keys, [None, "name", "age", None]) 120 | self.assertEqual(self.h._HashTable__values, [None, "test", 25, None]) 121 | self.assertEqual(self.h._HashTable__length, 4) 122 | 123 | result = self.h.sort() 124 | 125 | self.assertEqual(self.h._HashTable__keys, [None, "name", "age", None]) 126 | self.assertEqual(self.h._HashTable__values, [None, "test", 25, None]) 127 | self.assertEqual(self.h._HashTable__length, 4) 128 | 129 | self.assertEqual(result._HashTable__keys, ["age", "name", None, None]) 130 | self.assertEqual(result._HashTable__values, [25, "test", None, None]) 131 | self.assertEqual(result._HashTable__length, 4) 132 | 133 | 134 | def test_add(self): 135 | self.h["name"] = "test" 136 | self.h["age"] = 25 137 | 138 | self.assertEqual(self.h._HashTable__keys, [None, "name", "age", None]) 139 | self.assertEqual(self.h._HashTable__values, [None, "test", 25, None]) 140 | self.assertEqual(self.h._HashTable__length, 4) 141 | 142 | self.h.add("new_key", 6) 143 | 144 | self.assertEqual(self.h._HashTable__keys, [None, "name", "age", "new_key"]) 145 | self.assertEqual(self.h._HashTable__values, [None, "test", 25, 6]) 146 | self.assertEqual(self.h._HashTable__length, 4) 147 | 148 | def test_string_representation(self): 149 | self.h["name"] = "test" 150 | self.h["age"] = 25 151 | 152 | result = str(self.h) 153 | 154 | self.assertEqual("{ name: test, age: 25 }", result) 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | if __name__ == "__main__": 167 | main() -------------------------------------------------------------------------------- /workshop_custom_list/test/test_custom_list.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | 3 | from workshop_custom_list.custom_exceptions import EmptyListException 4 | from workshop_custom_list.custom_list import CustomList 5 | 6 | 7 | class TestCustomList(TestCase): 8 | def setUp(self): 9 | self.l = CustomList() 10 | 11 | def test_initializer(self): 12 | self.assertEqual(self.l._CustomList__values, []) 13 | 14 | def test_add(self): 15 | self.assertEqual(self.l._CustomList__values, []) 16 | 17 | self.l.append(5) 18 | 19 | self.assertEqual(self.l._CustomList__values, [5]) 20 | 21 | def test_add_multiple_existing_elements_add_element_at_the_end(self): 22 | self.l._CustomList__values = [1, 2, 3] 23 | self.assertEqual(self.l._CustomList__values, [1, 2, 3]) 24 | self.assertEqual(len(self.l._CustomList__values), 3) 25 | 26 | 27 | self.l.append(5) 28 | 29 | self.assertEqual(self.l._CustomList__values, [1, 2, 3, 5]) 30 | last_element = self.l._CustomList__values[-1] 31 | 32 | self.assertEqual(last_element, 5) 33 | self.assertEqual(len(self.l._CustomList__values), 4) 34 | 35 | def test_add_returns_the_same_list(self): 36 | self.l._CustomList__values = [1, 2, 3] 37 | 38 | result = self.l.append(5) 39 | 40 | self.assertIs(result, self.l._CustomList__values) 41 | 42 | def test_type_of_index_is_not_integer_raises(self): 43 | invalid_args = [2.5, "asd", [1,23], {"1": 1}] 44 | 45 | for invalid_arg in invalid_args: 46 | with self.assertRaises(TypeError) as ex: 47 | self.l.remove(invalid_arg) 48 | self.assertEqual(str(ex.exception), f"Index must be of type integer") 49 | 50 | def test_check_index_argument_is_not_positive_or_zero_integer_raises(self): 51 | invalid_value = -1 52 | 53 | with self.assertRaises(ValueError) as ex: 54 | self.l.remove(invalid_value) 55 | self.assertEqual(str(ex.exception), "Integer must be 0 or positive") 56 | 57 | def test_index_is_not_in_array_boundary_raises(self): 58 | self.l._CustomList__values = [1, 2, 3] 59 | self.assertEqual(len(self.l._CustomList__values), 3) 60 | 61 | index_out_of_range = [3, 4] 62 | 63 | for index in index_out_of_range: 64 | with self.assertRaises(ValueError) as ex: 65 | self.l.remove(index) 66 | self.assertEqual(str(ex.exception), "Index is out of range") 67 | 68 | def test_remove_value_on_given_index(self): 69 | """ 70 | Test remove value on index 71 | Test if multiple same values, removed is only one (on the index) 72 | Check the return result is the correct value 73 | """ 74 | 75 | self.l._CustomList__values = [1, 2, 3, 1] 76 | self.assertEqual(self.l._CustomList__values, [1, 2, 3, 1]) 77 | self.assertEqual(len(self.l._CustomList__values), 4) 78 | 79 | result = self.l.remove(0) 80 | 81 | self.assertEqual(self.l._CustomList__values, [2, 3, 1]) 82 | self.assertEqual(len(self.l._CustomList__values), 3) 83 | 84 | self.assertEqual(result, 1) 85 | 86 | def test_get_type_of_index_is_not_integer_raises(self): 87 | invalid_args = [2.5, "asd", [1,23], {"1": 1}] 88 | 89 | for invalid_arg in invalid_args: 90 | with self.assertRaises(TypeError) as ex: 91 | self.l.get(invalid_arg) 92 | self.assertEqual(str(ex.exception.args[0]), f"Index must be of type integer") 93 | 94 | def test_get_check_index_argument_is_not_positive_or_zero_integer_raises(self): 95 | invalid_value = -1 96 | 97 | with self.assertRaises(ValueError) as ex: 98 | self.l.get(invalid_value) 99 | self.assertEqual(str(ex.exception), "Integer must be 0 or positive") 100 | 101 | def test_get_index_is_not_in_array_boundary_raises(self): 102 | self.l._CustomList__values = [1, 2, 3] 103 | self.assertEqual(len(self.l._CustomList__values), 3) 104 | 105 | index_out_of_range = [3, 4] 106 | 107 | for index in index_out_of_range: 108 | with self.assertRaises(ValueError) as ex: 109 | self.l.get(index) 110 | self.assertEqual(str(ex.exception), "Index is out of range") 111 | 112 | def test_get_valid_index_returns_the_element(self): 113 | self.l._CustomList__values = [1, 2, 3, 1] 114 | 115 | result = self.l.get(0) 116 | self.assertEqual(result, 1) 117 | 118 | def test_args_is_not_iterable_raises_value_error(self): 119 | self.l._CustomList__values = [1, 2, 3] 120 | self.assertEqual(self.l._CustomList__values, [1, 2, 3]) 121 | 122 | invalid_values = [1, 2.4] 123 | 124 | for invalid in invalid_values: 125 | with self.assertRaises(ValueError) as ex: 126 | self.l.extend(invalid) 127 | self.assertEqual(str(ex.exception), "Value is not an iterable") 128 | 129 | self.assertEqual(self.l._CustomList__values, [1, 2, 3]) 130 | 131 | def test_extend_extends_list_with_values_by_unpacking_them(self): 132 | self.l._CustomList__values = [1, 2, 3] 133 | self.assertEqual(self.l._CustomList__values, [1, 2, 3]) 134 | 135 | result = self.l.extend([3, 4]) 136 | 137 | self.assertEqual(self.l._CustomList__values, [1, 2, 3, 3, 4]) 138 | 139 | self.assertIs(result, self.l._CustomList__values) 140 | 141 | def test_insert_type_of_index_is_not_integer_raises(self): 142 | invalid_args = [2.5, "asd", [1, 23], {"1": 1}] 143 | 144 | for invalid_arg in invalid_args: 145 | with self.assertRaises(TypeError) as ex: 146 | self.l.insert(invalid_arg, 5) 147 | self.assertEqual(str(ex.exception.args[0]), f"Index must be of type integer") 148 | 149 | def test_insert_check_index_argument_is_not_positive_or_zero_integer_raises(self): 150 | invalid_value = -1 151 | 152 | with self.assertRaises(ValueError) as ex: 153 | self.l.insert(invalid_value, 5) 154 | self.assertEqual(str(ex.exception), "Integer must be 0 or positive") 155 | 156 | def test_insert_index_is_not_in_array_boundary_raises(self): 157 | self.l._CustomList__values = [1, 2, 3] 158 | self.assertEqual(len(self.l._CustomList__values), 3) 159 | 160 | index_out_of_range = [3, 4] 161 | 162 | for index in index_out_of_range: 163 | with self.assertRaises(ValueError) as ex: 164 | self.l.insert(index, 5) 165 | self.assertEqual(str(ex.exception), "Index is out of range") 166 | 167 | def test_insert_adds_value_on_correct_index(self): 168 | # inserts on index 0 169 | # inserts in the middle 170 | 171 | self.l._CustomList__values = [1, 2, 3] 172 | self.assertEqual(self.l._CustomList__values, [1, 2, 3]) 173 | 174 | result = self.l.insert(0, 5) 175 | self.assertEqual(self.l._CustomList__values, [5, 1, 2, 3]) 176 | self.assertIs(result, self.l._CustomList__values) 177 | 178 | result = self.l.insert(2, 100) 179 | self.assertEqual(self.l._CustomList__values, [5, 1, 100, 2, 3]) 180 | self.assertIs(result, self.l._CustomList__values) 181 | 182 | # pop with multiple elements removes only the last one 183 | 184 | def test_pop_empty_list_raises(self): 185 | self.assertEqual(self.l._CustomList__values, []) 186 | 187 | with self.assertRaises(EmptyListException) as ex: 188 | self.l.pop() 189 | self.assertEqual(str(ex.exception), "Can not pop from an empty list") 190 | 191 | def test_pop_last_element_leaves_list_empty(self): 192 | self.l._CustomList__values = [100] 193 | self.assertEqual(self.l._CustomList__values, [100]) 194 | 195 | result = self.l.pop() 196 | 197 | self.assertEqual(self.l._CustomList__values, []) 198 | self.assertEqual(result, 100) 199 | 200 | def test_pop_only_last_element(self): 201 | self.l._CustomList__values = [100, 1, 2, 100] 202 | self.assertEqual(self.l._CustomList__values, [100, 1, 2, 100]) 203 | 204 | self.l.pop() 205 | 206 | self.assertEqual(self.l._CustomList__values, [100, 1, 2]) 207 | 208 | def test_clear_empty_list(self): 209 | self.assertEqual(self.l._CustomList__values, []) 210 | 211 | self.l.clear() 212 | 213 | self.assertEqual(self.l._CustomList__values, []) 214 | 215 | def test_clear_delete_all_elements(self): 216 | self.l._CustomList__values = [100, 1, 2, 100] 217 | self.assertEqual(self.l._CustomList__values, [100, 1, 2, 100]) 218 | 219 | result = self.l.clear() 220 | self.assertIsNone(result) 221 | 222 | self.assertEqual(self.l._CustomList__values, []) 223 | 224 | def test_index_value_does_exist(self): 225 | self.l._CustomList__values = [100, 1, 2, 100] 226 | self.assertEqual(self.l._CustomList__values, [100, 1, 2, 100]) 227 | 228 | with self.assertRaises(ValueError) as ex: 229 | self.l.index(3) 230 | self.assertEqual(str(ex.exception), "Value is not in the list") 231 | 232 | def test_index_returns_first_occurrence_of_the_value(self): 233 | self.l._CustomList__values = [100, 1, 2, 100] 234 | self.assertEqual(self.l._CustomList__values, [100, 1, 2, 100]) 235 | 236 | result = self.l.index(100) 237 | 238 | self.assertEqual(result, 0) 239 | self.assertEqual(self.l._CustomList__values, [100, 1, 2, 100]) 240 | 241 | def test_count_value_is_not_in_the_list_returns_0(self): 242 | self.l._CustomList__values = [100, 1, 2, 100] 243 | self.assertEqual(self.l._CustomList__values, [100, 1, 2, 100]) 244 | 245 | result = self.l.count(3) 246 | 247 | self.assertEqual(result, 0) 248 | self.assertEqual(self.l._CustomList__values, [100, 1, 2, 100]) 249 | 250 | def test_count_value_returns_count(self): 251 | self.l._CustomList__values = [100, 1, 2, 100] 252 | self.assertEqual(self.l._CustomList__values, [100, 1, 2, 100]) 253 | 254 | result = self.l.count(100) 255 | 256 | self.assertEqual(result, 2) 257 | self.assertEqual(self.l._CustomList__values, [100, 1, 2, 100]) 258 | 259 | def test_reverse_empty_list(self): 260 | self.assertEqual(self.l._CustomList__values, []) 261 | 262 | result = self.l.reverse() 263 | 264 | self.assertEqual(self.l._CustomList__values, []) 265 | self.assertIsNot(self.l._CustomList__values, result) 266 | 267 | 268 | 269 | def test_reverse_returns_new_list_with_reversed_value_order(self): 270 | self.l._CustomList__values = [1, 2, 100] 271 | self.assertEqual(self.l._CustomList__values, [1, 2, 100]) 272 | 273 | result = self.l.reverse() 274 | 275 | self.assertEqual(self.l._CustomList__values, [1, 2, 100]) 276 | self.assertEqual(result, [100, 2, 1]) 277 | self.assertIsNot(result, self.l._CustomList__values) 278 | 279 | def test_copy_empty_list(self): 280 | self.assertEqual(self.l._CustomList__values, []) 281 | 282 | result = self.l.copy() 283 | 284 | self.assertEqual(self.l._CustomList__values, []) 285 | self.assertIsNot(self.l._CustomList__values, result) 286 | 287 | def test_copy_returns_same_values_new_list(self): 288 | self.l._CustomList__values = [1, 2, 100] 289 | self.assertEqual(self.l._CustomList__values, [1, 2, 100]) 290 | 291 | result = self.l.copy() 292 | 293 | self.assertEqual(self.l._CustomList__values, [1, 2, 100]) 294 | self.assertEqual(result, [1, 2, 100]) 295 | self.assertIsNot(result, self.l._CustomList__values) 296 | 297 | def test_size_empty_list_returns_0(self): 298 | self.assertEqual(self.l._CustomList__values, []) 299 | self.assertEqual(len(self.l._CustomList__values), 0) 300 | 301 | result = self.l.size() 302 | 303 | self.assertEqual(self.l._CustomList__values, []) 304 | self.assertEqual(result, 0) 305 | 306 | def test_size_returns_lentgh_of_the_list(self): 307 | self.l._CustomList__values = [1, 2, 100] 308 | self.assertEqual(self.l._CustomList__values, [1, 2, 100]) 309 | self.assertEqual(len(self.l._CustomList__values), 3) 310 | 311 | 312 | result = self.l.size() 313 | 314 | self.assertEqual(self.l._CustomList__values, [1, 2, 100]) 315 | self.assertEqual(result, 3) 316 | 317 | def test_add_first_empty_list_ends_up_with_one_element(self): 318 | self.assertEqual(self.l._CustomList__values, []) 319 | self.assertEqual(len(self.l._CustomList__values), 0) 320 | 321 | result = self.l.add_first(5) 322 | 323 | self.assertIsNone(result) 324 | 325 | self.assertEqual(self.l._CustomList__values, [5]) 326 | self.assertEqual(len(self.l._CustomList__values), 1) 327 | 328 | def test_add_first_elements_in_list_ends_up_with_the_element_at_index_0(self): 329 | self.l._CustomList__values = [1, 2, 100] 330 | self.assertEqual(self.l._CustomList__values, [1, 2, 100]) 331 | self.assertEqual(len(self.l._CustomList__values), 3) 332 | 333 | result = self.l.add_first(100) 334 | 335 | self.assertEqual(self.l._CustomList__values, [100, 1, 2, 100]) 336 | self.assertEqual(len(self.l._CustomList__values), 4) 337 | 338 | self.assertIsNone(result) 339 | 340 | def test_dictionize_empty_list_empty_dict(self): 341 | self.assertEqual(self.l._CustomList__values, []) 342 | 343 | result = self.l.dictionize() 344 | 345 | self.assertDictEqual(result, {}) 346 | def test_dictionize_odd_count_appends_space_as_value(self): 347 | self.l._CustomList__values = [1, 2, 100] 348 | self.assertEqual(self.l._CustomList__values, [1, 2, 100]) 349 | self.assertEqual(len(self.l._CustomList__values), 3) 350 | 351 | result = self.l.dictionize() 352 | 353 | self.assertDictEqual(result, {1: 2, 100: ' '}) 354 | self.assertEqual(self.l._CustomList__values, [1, 2, 100]) 355 | self.assertEqual(len(self.l._CustomList__values), 3) 356 | 357 | def test_dictionize_even_count(self): 358 | self.l._CustomList__values = [1, 2, 100, 5] 359 | self.assertEqual(self.l._CustomList__values, [1, 2, 100, 5]) 360 | self.assertEqual(len(self.l._CustomList__values), 4) 361 | 362 | result = self.l.dictionize() 363 | 364 | self.assertDictEqual(result, {1: 2, 100: 5}) 365 | self.assertEqual(self.l._CustomList__values, [1, 2, 100, 5]) 366 | self.assertEqual(len(self.l._CustomList__values), 4) 367 | 368 | def test_move_empty_list(self): 369 | self.assertEqual(self.l._CustomList__values, []) 370 | 371 | result = self.l.move(2) 372 | 373 | self.assertEqual(self.l._CustomList__values, []) 374 | self.assertIs(result, self.l._CustomList__values) 375 | 376 | def test_move(self): 377 | self.l._CustomList__values = [1, 2, 100, 5] 378 | self.assertEqual(self.l._CustomList__values, [1, 2, 100, 5]) 379 | 380 | result = self.l.move(2) 381 | 382 | self.assertEqual(self.l._CustomList__values, [100, 5, 1, 2]) 383 | self.assertIs(result, self.l._CustomList__values) 384 | 385 | def test_move_0_does_not_change_list(self): 386 | self.l._CustomList__values = [1, 2, 100, 5] 387 | self.assertEqual(self.l._CustomList__values, [1, 2, 100, 5]) 388 | 389 | result = self.l.move(0) 390 | 391 | self.assertEqual(self.l._CustomList__values, [1, 2, 100, 5]) 392 | self.assertIs(result, self.l._CustomList__values) 393 | 394 | def test_move_with_length_of_the_list_does_not_change_list(self): 395 | self.l._CustomList__values = [1, 2, 100, 5] 396 | self.assertEqual(self.l._CustomList__values, [1, 2, 100, 5]) 397 | 398 | result = self.l.move(len(self.l._CustomList__values)) 399 | 400 | self.assertEqual(self.l._CustomList__values, [1, 2, 100, 5]) 401 | self.assertIs(result, self.l._CustomList__values) 402 | 403 | def test_move_with_length_plus_one_of_the_list_does_not_change_list(self): 404 | self.l._CustomList__values = [1, 2, 100, 5] 405 | self.assertEqual(self.l._CustomList__values, [1, 2, 100, 5]) 406 | 407 | result = self.l.move(len(self.l._CustomList__values)+1) 408 | 409 | self.assertEqual(self.l._CustomList__values, [1, 2, 100, 5]) 410 | self.assertIs(result, self.l._CustomList__values) 411 | 412 | def test_move_invalid_int_or_negative_raises(self): 413 | self.assertEqual(self.l._CustomList__values, []) 414 | 415 | invalid_args = [2.3, "123", (1,3,3)] 416 | 417 | for arg in invalid_args: 418 | with self.assertRaises(ValueError) as ex: 419 | self.l.move(arg) 420 | self.assertEqual(str(ex.exception), "Value is not a valid int") 421 | 422 | with self.assertRaises(ValueError) as ex: 423 | self.l.move(-1) 424 | self.assertEqual(str(ex.exception), "Value is not a valid int") 425 | 426 | def test_sum_empty_list_returns_0(self): 427 | self.assertEqual(self.l._CustomList__values, []) 428 | 429 | result = self.l.sum() 430 | 431 | self.assertEqual(result, 0) 432 | self.assertEqual(self.l._CustomList__values, []) 433 | 434 | def test_sum_only_numeric(self): 435 | self.l._CustomList__values = [1, 2, 100, 5] 436 | self.assertEqual(self.l._CustomList__values, [1, 2, 100, 5]) 437 | 438 | result = self.l.sum() 439 | 440 | self.assertEqual(self.l._CustomList__values, [1, 2, 100, 5]) 441 | self.assertIs(result, 108) 442 | 443 | def test_sum_non_numeric_returns_lens_amount(self): 444 | self.l._CustomList__values = [1, 2, 100, 5, "asd", (1, 2), [1, 2, 3], {"1": 3}] 445 | self.assertEqual(self.l._CustomList__values, [1, 2, 100, 5, "asd", (1, 2), [1, 2, 3], {"1": 3}]) 446 | 447 | result = self.l.sum() 448 | 449 | self.assertEqual(self.l._CustomList__values, [1, 2, 100, 5, "asd", (1, 2), [1, 2, 3], {"1": 3}]) 450 | self.assertIs(result, 117) 451 | 452 | def test_overbound_empty_list(self): 453 | self.assertEqual(self.l._CustomList__values, []) 454 | 455 | result = self.l.overbound() 456 | 457 | self.assertIsNone(result) 458 | self.assertEqual(self.l._CustomList__values, []) 459 | 460 | 461 | def test_overbound_only_numeric(self): 462 | self.l._CustomList__values = [100, 2, 100, 5] 463 | self.assertEqual(self.l._CustomList__values, [100, 2, 100, 5]) 464 | 465 | result = self.l.overbound() 466 | 467 | self.assertEqual(self.l._CustomList__values, [100, 2, 100, 5]) 468 | self.assertEqual(result, 0) 469 | 470 | def test_overbound_numeric_and_iterables(self): 471 | self.l._CustomList__values = [1, 2, "asd", (1, 2), [1, 2, 3], {"1": 3}] 472 | self.assertEqual(self.l._CustomList__values, [1, 2, "asd", (1, 2), [1, 2, 3], {"1": 3}]) 473 | 474 | result = self.l.overbound() 475 | 476 | self.assertEqual(self.l._CustomList__values, [1, 2, "asd", (1, 2), [1, 2, 3], {"1": 3}]) 477 | self.assertEqual(result, 2) 478 | 479 | def test_underbound_empty_list(self): 480 | self.assertEqual(self.l._CustomList__values, []) 481 | 482 | result = self.l.underbound() 483 | 484 | self.assertIsNone(result) 485 | self.assertEqual(self.l._CustomList__values, []) 486 | 487 | def test_underbound_only_numeric(self): 488 | self.l._CustomList__values = [2, 100, 2, 5] 489 | self.assertEqual(self.l._CustomList__values, [2, 100, 2, 5]) 490 | 491 | result = self.l.underbound() 492 | 493 | self.assertEqual(self.l._CustomList__values, [2, 100, 2, 5]) 494 | self.assertEqual(result, 0) 495 | 496 | def test_underbound_numeric_and_iterables(self): 497 | self.l._CustomList__values = [5, 6, "asd", (1, 2), [1, 2, 3], {"1": 3}] 498 | self.assertEqual(self.l._CustomList__values, [5, 6, "asd", (1, 2), [1, 2, 3], {"1": 3}]) 499 | 500 | result = self.l.underbound() 501 | 502 | self.assertEqual(self.l._CustomList__values, [5, 6, "asd", (1, 2), [1, 2, 3], {"1": 3}]) 503 | self.assertEqual(result, 5) 504 | 505 | 506 | if __name__ == "__main__": 507 | main() --------------------------------------------------------------------------------