├── .idea └── .gitignore ├── 01. First Steps in OOP ├── 01. First Steps in OOP - Exercise │ ├── 01_shop.py │ ├── 02_hero.py │ ├── 03_employee.py │ ├── 04_cup.py │ ├── 05_flower.py │ ├── 06_steam_user.py │ ├── 07_programmer.py │ ├── 08_ pokemon_battle.py │ ├── __init__.py │ └── project │ │ ├── __init__.py │ │ ├── pokemon.py │ │ └── trainer.py └── 01. First Steps in OOP - Lab │ ├── 01_rhombus_of_stars.py │ ├── 02_scope_mess.py │ ├── 03_class_book.py │ ├── 04_car.py │ ├── 05_music.py │ └── __init__.py ├── 02. Classes and Objects ├── 02. Classes and Objects - Exercise │ ├── 1_vet.py │ ├── 2_time.py │ ├── 3_account.py │ ├── 4_pizza_delivery.py │ ├── __init__.py │ ├── project_guild │ │ ├── __ini__.py │ │ ├── guild.py │ │ └── player.py │ ├── project_library │ │ ├── __init__.py │ │ ├── library.py │ │ ├── registration.py │ │ └── user.py │ ├── project_spoopify │ │ ├── __init__.py │ │ ├── album.py │ │ ├── band.py │ │ └── song.py │ ├── project_to_do │ │ ├── __init__.py │ │ ├── section.py │ │ └── task.py │ ├── test_guild_system.py │ ├── test_library.py │ ├── test_spoopify.py │ └── test_to_do.py └── 02. Classes and Objects - Lab │ ├── 1_vehicle.py │ ├── 2_point.py │ ├── 3_circle.py │ ├── 4_glass.py │ ├── 5_smartphone.py │ └── __init__.py ├── 03. Inheritance ├── 03. Inheritance - Exercise │ ├── project │ │ ├── car.py │ │ ├── cross_motorcycle.py │ │ ├── family_car.py │ │ ├── motorcycle.py │ │ ├── race_motorcycle.py │ │ ├── sport_car.py │ │ └── vehicle.py │ ├── project_person │ │ ├── child.py │ │ └── person.py │ ├── project_players_and_monsters │ │ ├── blade_knight.py │ │ ├── dark_knight.py │ │ ├── dark_wizard.py │ │ ├── elf.py │ │ ├── hero.py │ │ ├── knight.py │ │ ├── muse_elf.py │ │ ├── soul_master.py │ │ └── wizard.py │ ├── project_shop │ │ ├── __init__.py │ │ ├── drink.py │ │ ├── food.py │ │ ├── product.py │ │ └── product_repository.py │ └── project_zoo │ │ ├── animal.py │ │ ├── bear.py │ │ ├── gorilla.py │ │ ├── lizard.py │ │ ├── mammal.py │ │ ├── reptile.py │ │ └── snake.py └── 03. Inheritance - Lab │ ├── 6_stack_of_strings.py │ ├── project_food │ ├── food.py │ └── fruit.py │ ├── project_hierarchical_inheritance │ ├── animal.py │ ├── cat.py │ └── dog.py │ ├── project_multilevel_inheritance │ ├── car.py │ ├── sports_car.py │ └── vehicle.py │ ├── project_multiple_inheritance │ ├── employee.py │ ├── person.py │ └── teacher.py │ ├── project_single_inheritance │ ├── animal.py │ └── dog.py │ └── test.py ├── 04. Encapsulation ├── 04. Encapsulation - Exercise │ ├── project_football_team_generator │ │ ├── player.py │ │ └── team.py │ ├── project_pizza_maker │ │ ├── __init__.py │ │ ├── dough.py │ │ ├── pizza.py │ │ ├── project.zip │ │ ├── topping.py │ │ └── validation │ │ │ └── validation.py │ ├── project_restaurant │ │ ├── __init__.py │ │ ├── beverage │ │ │ ├── __init__.py │ │ │ ├── beverage.py │ │ │ ├── coffee.py │ │ │ ├── cold_beverage.py │ │ │ ├── hot_beverage.py │ │ │ └── tea.py │ │ ├── food │ │ │ ├── __init__.py │ │ │ ├── cake.py │ │ │ ├── dessert.py │ │ │ ├── food.py │ │ │ ├── main_dish.py │ │ │ ├── salmon.py │ │ │ ├── soup.py │ │ │ └── starter.py │ │ └── product.py │ └── project_wild_cat_zoo │ │ ├── __init__.py │ │ ├── animal.py │ │ ├── caretaker.py │ │ ├── cheetah.py │ │ ├── keeper.py │ │ ├── lion.py │ │ ├── tiger.py │ │ ├── vet.py │ │ ├── worker.py │ │ └── zoo.py └── 04. Encapsulation - Lab │ ├── 1_person.py │ ├── 2_mammal.py │ ├── 3_profile.py │ ├── 4_email_validator.py │ └── 5_account.py ├── 05. Static and Class Methods ├── 05. Static and Class Methods - Exercise │ ├── 1_photo_album.py │ ├── project_2_movie_world │ │ ├── __init__.py │ │ ├── customer.py │ │ ├── dvd.py │ │ └── movie_world.py │ ├── project_3_document_management │ │ ├── __init__.py │ │ ├── category.py │ │ ├── document.py │ │ ├── storage.py │ │ └── topic.py │ └── project_4_gym │ │ ├── __init__.py │ │ ├── customer.py │ │ ├── equipment.py │ │ ├── exercise_plan.py │ │ ├── gym.py │ │ ├── subscription.py │ │ └── trainer.py └── 05. Static and Class Methods - Lab │ ├── 1_calculator.py │ ├── 2_shop.py │ ├── 3_integer.py │ └── project_4_hotel_rooms │ ├── __init__.py │ ├── hotel.py │ └── room.py ├── 06. Polymorphism and Abstraction ├── 06. Polymorphism and Abstraction - Exercise │ ├── 1_vehicles.py │ ├── 2_groups.py │ ├── 3_account.py │ ├── project_4_wild_farm │ │ ├── __init__.py │ │ ├── animals │ │ │ ├── __init__.py │ │ │ ├── animal.py │ │ │ ├── birds.py │ │ │ └── mammals.py │ │ └── food.py │ ├── project_5_animals │ │ ├── __init__.py │ │ ├── animal.py │ │ ├── cat.py │ │ ├── dog.py │ │ ├── kitten.py │ │ └── tomcat.py │ └── project_6_formula_1_manager │ │ ├── __init__.py │ │ ├── f1_season_app.py │ │ ├── formula_teams │ │ ├── __init__.py │ │ ├── formula_team.py │ │ ├── mercedes_team.py │ │ └── red_bull_team.py │ │ └── ver 2.0 │ │ ├── __init__.py │ │ ├── f1_season_app.py │ │ ├── formula_teams │ │ ├── __init__.py │ │ ├── formula_team.py │ │ ├── mercedes_team.py │ │ └── red_bull_team.py │ │ └── validation │ │ ├── __init__.py │ │ └── validation.py └── 06. Polymorphism and Abstraction - Lab │ ├── 2_image_area.py │ ├── 3_playing.py │ └── 4_shapes.py ├── 07. SOLID ├── 07. SOLID - Exercise │ ├── 1_workers.py │ ├── 2_workers_updated.py │ ├── 3_prisoner.py │ ├── 4_shapes.py │ └── 5_emails.py └── 07. SOLID - Lab │ ├── 1_books.py │ ├── 2_animals.py │ ├── 3_ducks.py │ ├── 4_entertainment_system.py │ └── 5_print_books.py ├── 08. Iterators and Generators ├── 08. Iterators and Generators - Exercise │ ├── 1_take_skip.py │ ├── 2_dictionary_iterator.py │ ├── 3_countdown_ierator.py │ ├── 4_sequence_repeat.py │ ├── 5_take_halves.py │ ├── 6_fibonacci_generator.py │ ├── 7_reader.py │ ├── 8_prime_nmbers.py │ └── 9_possible_permutations.py └── 08. Iterators and Generators - Lab │ ├── 1_custom_range.py │ ├── 2_reverse_iter.py │ ├── 3_vowels.py │ ├── 4_squares.py │ ├── 5_generator_range.py │ └── 6_reverse_string.py ├── 09. Decorators ├── 09. Decorators - Exercise │ ├── 1_logged.py │ ├── 2_even_parameters.py │ ├── 3_bold_italic_underline.py │ ├── 4_type_check.py │ ├── 5_cache.py │ └── 6_html_tags.py └── 09. Decorators - Lab │ ├── 1_number_increment.py │ ├── 2_vowel_filter.py │ ├── 3_even_numbers.py │ └── 4_multiply.py ├── 10. Testing ├── 10. Testing - Exercise │ ├── 01_mammal.py │ ├── 02_vehicle.py │ ├── 03_hero.py │ └── 04_student.py └── 10. Testing - Lab │ ├── 1_test_worker.py │ ├── 2_test_cat.py │ ├── 3_test_list.py │ └── 4_test_car_manager.py └── README.md /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Exercise/01_shop.py: -------------------------------------------------------------------------------- 1 | class Shop: 2 | def __init__(self, name, items): 3 | self.name = name 4 | self.items = items 5 | 6 | def get_items_count(self): 7 | return len(self.items) 8 | 9 | -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Exercise/02_hero.py: -------------------------------------------------------------------------------- 1 | class Hero: 2 | def __init__(self, name, health): 3 | self.name = name 4 | self.health = int(health) 5 | 6 | def defend(self, damage): 7 | self.health -= damage 8 | if self.health <= 0: 9 | self.health = 0 10 | return f"{self.name} was defeated" 11 | 12 | def heal(self, amount): 13 | self.health += amount 14 | -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Exercise/03_employee.py: -------------------------------------------------------------------------------- 1 | class Employee: 2 | def __init__(self, id, first_name, last_name, salary): 3 | self.id = int(id) 4 | self.first_name = first_name 5 | self.last_name = last_name 6 | self.salary = int(salary) 7 | 8 | def get_full_name(self): 9 | return f"{self.first_name} {self.last_name}" 10 | 11 | def get_annual_salary(self): 12 | return self.salary * 12 13 | 14 | def raise_salary(self, amount): 15 | self.salary += int(amount) 16 | return self.salary 17 | -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Exercise/04_cup.py: -------------------------------------------------------------------------------- 1 | class Cup: 2 | def __init__(self, size, quantity): 3 | self.size = int(size) 4 | self.quantity = int(quantity) 5 | 6 | def fill(self, milliliters): 7 | if self.quantity + milliliters <= self.size: 8 | self.quantity += milliliters 9 | 10 | def status(self): 11 | return self.size - self.quantity -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Exercise/05_flower.py: -------------------------------------------------------------------------------- 1 | class Flower: 2 | def __init__(self, name,water_requirements): 3 | self.name = name 4 | self.water_requirements = int(water_requirements) 5 | self.is_happy = False 6 | 7 | def water(self, quantity): 8 | if quantity >= self.water_requirements: 9 | self.is_happy = True 10 | 11 | def status(self): 12 | if self.is_happy: 13 | return f"{self.name} is happy" 14 | return f"{self.name} is not happy" 15 | -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Exercise/06_steam_user.py: -------------------------------------------------------------------------------- 1 | class SteamUser: 2 | def __init__(self, username, games): 3 | self.username = username 4 | self.games = games 5 | self.played_hours = 0 6 | 7 | def play(self, game, hours): 8 | if game in self.games: 9 | self.played_hours += hours 10 | return f"{self.username} is playing {game}" 11 | return f"{game} is not in library" 12 | 13 | def buy_game(self, game): 14 | if game not in self.games: 15 | self.games.append(game) 16 | return f"{self.username} bought {game}" 17 | return f"{game} is already in your library" 18 | 19 | def status(self): 20 | return f"{self.username} has {len(self.games)} games. Total play time: {self.played_hours}" 21 | 22 | -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Exercise/07_programmer.py: -------------------------------------------------------------------------------- 1 | class Programmer: 2 | def __init__(self, name, language, skills): 3 | self.name = name 4 | self.language = language 5 | self.skills = int(skills) 6 | 7 | def watch_course(self, course_name, language, skills_earned): 8 | if language == self.language: 9 | self.skills += skills_earned 10 | return f"{self.name} watched {course_name}" 11 | return f"{self.name} does not know {language}" 12 | 13 | def change_language(self, new_language, skills_needed): 14 | if all([skills_needed <= self.skills, new_language != self.language]): 15 | old_language = self.language 16 | self.language = new_language 17 | return f"{self.name} switched from {old_language} to {new_language}" 18 | if all([skills_needed <= self.skills, new_language == self.language]): 19 | return f"{self.name} already knows {new_language}" 20 | if skills_needed > self.skills: 21 | return f"{self.name} needs {abs(self.skills - skills_needed)} more skills" 22 | -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Exercise/08_ pokemon_battle.py: -------------------------------------------------------------------------------- 1 | from project.pokemon import Pokemon 2 | from project.trainer import Trainer 3 | 4 | import unittest 5 | 6 | 7 | class PokemonTest(unittest.TestCase): 8 | def setUp(self): 9 | self.trainer = Trainer("Ash") 10 | self.pokemon = Pokemon("Pikachu", 90) 11 | self.second_pokemon = Pokemon("Charizard", 110) 12 | 13 | def test_pokemon_init(self): 14 | message = self.pokemon.pokemon_details() 15 | expected = "Pikachu with health 90" 16 | self.assertEqual(message, expected) 17 | 18 | def test_adding_pokemon(self): 19 | message = self.trainer.add_pokemon(self.pokemon) 20 | expected = "Caught Pikachu with health 90" 21 | self.assertEqual(message, expected) 22 | 23 | def test_adding_second_pokemon(self): 24 | message = self.trainer.add_pokemon(self.second_pokemon) 25 | expected = "Caught Charizard with health 110" 26 | self.assertEqual(message, expected) 27 | 28 | def test_adding_already_added_pokemon(self): 29 | self.trainer.add_pokemon(self.second_pokemon) 30 | message = self.trainer.add_pokemon(self.second_pokemon) 31 | expected = "This pokemon is already caught" 32 | self.assertEqual(message, expected) 33 | 34 | def test_releasing_pokemon(self): 35 | self.trainer.add_pokemon(self.pokemon) 36 | message = self.trainer.release_pokemon("Pikachu") 37 | expected = "You have released Pikachu" 38 | self.assertEqual(message, expected) 39 | 40 | def test_releasing_pokemon_that_is_not_caught(self): 41 | message = self.trainer.release_pokemon("Pikachu") 42 | expected = "Pokemon is not caught" 43 | self.assertEqual(message, expected) 44 | 45 | def test_trainer_data(self): 46 | self.trainer.add_pokemon(self.pokemon) 47 | self.trainer.add_pokemon(self.second_pokemon) 48 | self.trainer.release_pokemon("Pikachu") 49 | message = self.trainer.trainer_data() 50 | message = message.strip('\n') 51 | expected = "Pokemon Trainer Ash\nPokemon count 1\n- Charizard with health 110" 52 | self.assertEqual(message, expected) 53 | 54 | 55 | if __name__ == '__main__': 56 | unittest.main() -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Exercise/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/01. First Steps in OOP/01. First Steps in OOP - Exercise/__init__.py -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Exercise/project/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/01. First Steps in OOP/01. First Steps in OOP - Exercise/project/__init__.py -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Exercise/project/pokemon.py: -------------------------------------------------------------------------------- 1 | class Pokemon: 2 | def __init__(self, name, health): 3 | self.name = name 4 | self.health = int(health) 5 | 6 | def pokemon_details(self): 7 | return f"{self.name} with health {self.health}" 8 | 9 | -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Exercise/project/trainer.py: -------------------------------------------------------------------------------- 1 | from project.pokemon import Pokemon 2 | 3 | 4 | class Trainer: 5 | def __init__(self, name=None): 6 | self.name = name 7 | self.pokemons = [] 8 | 9 | def add_pokemon(self, pokemon): 10 | if pokemon.name not in [x.name for x in self.pokemons]: 11 | self.pokemons.append(pokemon) 12 | return f"Caught {pokemon.pokemon_details()}" 13 | return "This pokemon is already caught" 14 | 15 | def release_pokemon(self, pokemon_name): 16 | for pos, name in enumerate(self.pokemons): 17 | if pokemon_name == name.name: 18 | del self.pokemons[pos] 19 | return f"You have released {pokemon_name}" 20 | return "Pokemon is not caught" 21 | 22 | def trainer_data(self): 23 | text = f"Pokemon Trainer {self.name}\nPokemon count {len(self.pokemons)}\n" 24 | for info in self.pokemons: 25 | text += f"- {info.pokemon_details()}\n" 26 | 27 | return text 28 | 29 | -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Lab/01_rhombus_of_stars.py: -------------------------------------------------------------------------------- 1 | number_of_rhombus = int(input()) 2 | 3 | 4 | class Rhombus: 5 | def __init__(self, stars): 6 | self.stars = stars 7 | self.draw = [] 8 | 9 | def make_rhombus(self): 10 | for row in range(1, self.stars + 1): 11 | if row == 1: 12 | self.draw.append((self.stars - row) * " " + row * "*") 13 | else: 14 | self.draw.append((self.stars - row) * " " + row * "* ") 15 | for rows in range(0, self.stars - 1): 16 | if rows == 0: 17 | self.draw.append((self.stars - (row - 1)) * " " + (self.stars - 1) * "* ") 18 | else: 19 | self.draw.append((rows + 1) * " " + (self.stars - rows - 1) * "* ") 20 | 21 | def __repr__(self): 22 | return '\n'.join(self.draw) 23 | 24 | 25 | r = Rhombus(number_of_rhombus) 26 | r.make_rhombus() 27 | print(r) 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | # 38 | # 39 | # 40 | # number_of_rhombus = int(input()) 41 | # 42 | # 43 | # class Rhombus: 44 | # def __init__(self, stars): 45 | # self.stars = stars 46 | # 47 | # def show_result(self): 48 | # for row in range(1, self.stars + 1): 49 | # if row == 1: 50 | # print((self.stars - row) * " " + row * "*") 51 | # else: 52 | # print((self.stars - row) * " " + row * "* ") 53 | # for rows in range(0, self.stars - 1): 54 | # if rows == 0: 55 | # print((self.stars - (row - 1)) * " " + (self.stars - 1) * "* ") 56 | # else: 57 | # print((rows + 1) * " " + (self.stars - rows - 1) * "* ") 58 | # 59 | # 60 | # r = Rhombus(number_of_rhombus) 61 | # r.show_result() 62 | -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Lab/02_scope_mess.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) -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Lab/03_class_book.py: -------------------------------------------------------------------------------- 1 | class Book: 2 | def __init__(self, name, author, pages): 3 | self.name = name 4 | self.author = author 5 | self.pages = int(pages) -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Lab/04_car.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 | -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Lab/05_music.py: -------------------------------------------------------------------------------- 1 | class Music: 2 | def __init__(self, title, artist, lyrics): 3 | self.title = title 4 | self.artist = artist 5 | self.lyrics = lyrics 6 | 7 | def print_info(self): 8 | return f'This is "{self.title}" from "{self.artist}"' 9 | 10 | def play(self): 11 | return self.lyrics 12 | -------------------------------------------------------------------------------- /01. First Steps in OOP/01. First Steps in OOP - Lab/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/01. First Steps in OOP/01. First Steps in OOP - Lab/__init__.py -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/1_vet.py: -------------------------------------------------------------------------------- 1 | class Vet: 2 | animals = [] 3 | space = 5 4 | 5 | def __init__(self, name): 6 | self.name = name 7 | self.animals = [] 8 | 9 | def register_animal(self, animal_name): 10 | if Vet.space > 0: 11 | Vet.space -= 1 12 | Vet.animals.append(animal_name) 13 | self.animals.append(animal_name) 14 | return f"{animal_name} registered in the clinic" 15 | return "Not enough space" 16 | 17 | def unregister_animal(self, animal_name): 18 | if animal_name in self.animals and animal_name in Vet.animals: 19 | self.animals.remove(animal_name) 20 | Vet.animals.remove(animal_name) 21 | Vet.space += 1 22 | return f"{animal_name} unregistered successfully" 23 | return f"{animal_name} not in the clinic" 24 | 25 | def info(self): 26 | return f"{self.name} has {len(self.animals)} animals. {Vet.space} space left in clinic" 27 | 28 | 29 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/2_time.py: -------------------------------------------------------------------------------- 1 | class Time: 2 | max_hours = 23 3 | max_minutes = 59 4 | max_seconds = 59 5 | 6 | def __init__(self, hours, minutes, seconds): 7 | self.hours = int(hours) 8 | self.minutes = int(minutes) 9 | self.seconds = int(seconds) 10 | 11 | def set_time(self, hours, minutes, seconds): 12 | self.hours = int(hours) 13 | self.minutes = int(minutes) 14 | self.seconds = int(seconds) 15 | 16 | def get_time(self): 17 | return f"{self.hours:02}:{self.minutes:02}:{self.seconds:02}" 18 | 19 | def next_second(self): 20 | self.seconds += 1 21 | if self.seconds > Time.max_seconds: 22 | self.seconds = 0 23 | self.minutes += 1 24 | if self.minutes > Time.max_minutes: 25 | self.minutes = 0 26 | self.hours += 1 27 | if self.hours > Time.max_hours: 28 | self.hours = 0 29 | return self.get_time() 30 | 31 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/3_account.py: -------------------------------------------------------------------------------- 1 | class Account: 2 | def __init__(self, id, name, balance=0): 3 | self.id = id 4 | self.name = name 5 | self.balance = balance 6 | 7 | def credit(self, amount): 8 | self.balance += amount 9 | return self.balance 10 | 11 | def debit(self, amount): 12 | if amount <= self.balance: 13 | self.balance -= amount 14 | return self.balance 15 | return "Amount exceeded balance" 16 | 17 | def info(self): 18 | return f"User {self.name} with account {self.id} has {self.balance} balance" 19 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/4_pizza_delivery.py: -------------------------------------------------------------------------------- 1 | class PizzaDelivery: 2 | def __init__(self, name, price, ingredients): 3 | self.name = name 4 | self.price = float(price) 5 | self.ingredients = ingredients 6 | self.ordered = False 7 | 8 | def add_extra(self, ingredient: str, quantity: int, price_per_quantity: float): 9 | if not self.ordered: 10 | self.ingredients[ingredient] = self.ingredients.get(ingredient, 0) + quantity 11 | self.price += price_per_quantity * quantity 12 | return f"Pizza {self.name} already prepared, and we can't make any changes!" 13 | 14 | def remove_ingredient(self, ingredient: str, quantity: int, price_per_quantity: float): 15 | if not self.ordered: 16 | if ingredient not in self.ingredients: 17 | return f"Wrong ingredient selected! We do not use {ingredient} in {self.name}!" 18 | if self.ingredients[ingredient] < quantity: 19 | return f"Please check again the desired quantity of {ingredient}!" 20 | self.ingredients[ingredient] -= quantity 21 | self.price -= price_per_quantity * quantity 22 | return f"Pizza {self.name} already prepared, and we can't make any changes!" 23 | 24 | def make_order(self): 25 | if not self.ordered: 26 | self.ordered = True 27 | text = [f"{key}: {value}" for key, value in self.ingredients.items()] 28 | return f"You've ordered pizza {self.name} prepared with {', '.join(text)} " \ 29 | f"and the price will be {int(self.price)}lv." 30 | return f"Pizza {self.name} already prepared, and we can't make any changes!" -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/02. Classes and Objects/02. Classes and Objects - Exercise/__init__.py -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/project_guild/__ini__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/02. Classes and Objects/02. Classes and Objects - Exercise/project_guild/__ini__.py -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/project_guild/guild.py: -------------------------------------------------------------------------------- 1 | from project.player import Player 2 | 3 | 4 | class Guild: 5 | def __init__(self, name): 6 | self.name = name 7 | self.players = [] 8 | 9 | def assign_player(self, player: Player): 10 | if player.guild == self.name: 11 | return f"Player {player.name} is already in the guild." 12 | 13 | if player.guild == "Unaffiliated": 14 | self.players.append(player) 15 | player.guild = self.name 16 | return f"Welcome player {player.name} to the guild {self.name}" 17 | 18 | return f"Player {player.name} is in another guild." 19 | 20 | def kick_player(self, player_name: str): 21 | if all(x.name != player_name for x in self.players): 22 | return f"Player {player_name} is not in the guild." 23 | 24 | for player in self.players: 25 | if player.name == player_name: 26 | player.guild = "Unaffiliated" 27 | self.players.remove(player) 28 | return f"Player {player_name} has been removed from the guild." 29 | 30 | def guild_info(self): 31 | output = [f"Guild: {self.name}"] 32 | for player in self.players: 33 | output.append(player.player_info()) 34 | return "\n".join(output) 35 | 36 | 37 | 38 | # player = Player("George", 50, 100) 39 | # print(player.add_skill("Shield Break", 20)) 40 | # print(player.player_info()) 41 | # guild = Guild("UGT") 42 | # print(guild.assign_player(player)) 43 | # print(guild.guild_info()) -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/project_guild/player.py: -------------------------------------------------------------------------------- 1 | class Player: 2 | 3 | def __init__(self, name: str, hp: int, mp: int): 4 | self.name = name 5 | self.hp = int(hp) 6 | self.mp = int(mp) 7 | self.skills = {} 8 | self.guild = "Unaffiliated" 9 | 10 | def add_skill(self, skill_name, mana_cost): 11 | if skill_name not in self.skills: 12 | self.skills[skill_name] = int(mana_cost) 13 | return f"Skill {skill_name} added to the collection of the player {self.name}" 14 | return "Skill already added" 15 | 16 | def player_info(self): 17 | output = [f"Name: {self.name}", f"Guild: {self.guild}", f"HP: {self.hp}", f"MP: {self.mp}"] 18 | for skill_name, mana_cost in self.skills.items(): 19 | output.append(f"==={skill_name} - {mana_cost}") 20 | return "\n".join(output) 21 | 22 | 23 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/project_library/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/02. Classes and Objects/02. Classes and Objects - Exercise/project_library/__init__.py -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/project_library/library.py: -------------------------------------------------------------------------------- 1 | from project.user import User 2 | 3 | 4 | class Library: 5 | user_records = [] 6 | books_available = {} 7 | rented_books = {} 8 | 9 | def get_book(self, author: str, book_name: str, days_to_return: int, user): 10 | if author in Library.books_available: 11 | if book_name in Library.books_available[author]: 12 | Library.books_available[author].pop(Library.books_available[author].index(book_name)) 13 | if user.username not in Library.rented_books: 14 | Library.rented_books[user.username] = {} 15 | Library.rented_books[user.username][book_name] = days_to_return 16 | user.books.append(book_name) 17 | return f"{book_name} successfully rented for the next {days_to_return} days!" 18 | for name in Library.rented_books: 19 | for book, days_return in Library.rented_books[name].items(): 20 | if book == book_name: 21 | return f'The book "{book_name}" is already rented and will be available in {days_return} days!' 22 | 23 | def return_book(self, author: str, book_name: str, user): 24 | if book_name in user.books: 25 | user.books.pop(user.books.index(book_name)) 26 | Library.books_available[author].append(book_name) 27 | del Library.rented_books[user.username][book_name] 28 | return f"{user.username} doesn't have this book in his/her records!" 29 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/project_library/registration.py: -------------------------------------------------------------------------------- 1 | from project.user import User 2 | from project.library import Library 3 | 4 | 5 | class Registration: 6 | def add_user(self, user: User, library: Library): 7 | for show in library.user_records: 8 | if show.user_id == user.user_id: 9 | return f"User with id = {user.user_id} already registered in the library!" 10 | library.user_records.append(user) 11 | 12 | def remove_user(self, user: User, library: Library): 13 | find_user = False 14 | for pos, show in enumerate(library.user_records): 15 | if user.user_id == show.user_id: 16 | del library.user_records[pos] 17 | find_user = True 18 | break 19 | if not find_user: 20 | return "We could not find such user to remove!" 21 | 22 | def change_username(self, user_id: int, new_username: str, library: Library): 23 | for pos, show in enumerate(library.user_records): 24 | if show.user_id == user_id: 25 | if show.username != new_username: 26 | if show.username in library.rented_books: 27 | library.rented_books[new_username] = library.rented_books.pop(show.username) 28 | show.username = new_username 29 | return f"Username successfully changed to: {new_username} for user id: {user_id}" 30 | return f"Please check again the provided username - it should be different than the username used so far!" 31 | return f"There is no user with id = {user_id}!" 32 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/project_library/user.py: -------------------------------------------------------------------------------- 1 | class User: 2 | 3 | def __init__(self, user_id, username): 4 | self.user_id = user_id 5 | self.username = username 6 | self.books = [] 7 | 8 | def info(self): 9 | return f"{', '.join(sorted(self.books))}" 10 | 11 | def __str__(self): 12 | return f"{self.user_id}, {self.username}, {self.books}" 13 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/project_spoopify/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/02. Classes and Objects/02. Classes and Objects - Exercise/project_spoopify/__init__.py -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/project_spoopify/album.py: -------------------------------------------------------------------------------- 1 | from project.song import Song 2 | 3 | 4 | class Album: 5 | def __init__(self, name, *songs): 6 | self.name = name 7 | self.published = False 8 | self.songs = [x for x in songs] 9 | 10 | def add_song(self, song: Song): 11 | if song.single: 12 | return f"Cannot add {song.name}. It's a single" 13 | if self.published: 14 | return "Cannot add songs. Album is published." 15 | if song.name in [x.name for x in self.songs]: 16 | return "Song is already in the album." 17 | 18 | self.songs.append(song) 19 | return f"Song {song.name} has been added to the album {self.name}." 20 | 21 | def remove_song(self, song_name: str): 22 | if song_name not in [x.name for x in self.songs]: 23 | return "Song is not in the album." 24 | if self.published: 25 | return "Cannot remove songs. Album is published." 26 | for show in self.songs: 27 | if show.name == song_name: 28 | del show 29 | return f"Removed song {song_name} from album {self.name}." 30 | 31 | def publish(self): 32 | if self.published: 33 | return f"Album {self.name} is already published." 34 | self.published = True 35 | return f"Album {self.name} has been published." 36 | 37 | def details(self): 38 | text = f"Album {self.name}\n" 39 | for song in self.songs: 40 | text += f"== {song}\n" 41 | return text 42 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/project_spoopify/band.py: -------------------------------------------------------------------------------- 1 | from project.album import Album 2 | 3 | 4 | class Band: 5 | def __init__(self, name): 6 | self.name = name 7 | self.albums = [] 8 | 9 | def add_album(self, album: Album): 10 | if album.name in [x.name for x in self.albums]: 11 | return f"Band {self.name} already has {album.name} in their library." 12 | self.albums.append(album) 13 | return f"Band {self.name} has added their newest album {album.name}." 14 | 15 | def remove_album(self, album_name: str): 16 | for show in self.albums: 17 | if show.name in [x.name for x in self.albums] and show.published: 18 | return "Album has been published. It cannot be removed." 19 | if album_name in [x.name for x in self.albums]: 20 | return f"Album {album_name} has been removed." 21 | elif album_name not in [x.name for x in self.albums]: 22 | return f"Album {album_name} is not found." 23 | 24 | def details(self): 25 | text = f"Band {self.name}\n" 26 | for x in self.albums: 27 | text += x.details() 28 | return text 29 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/project_spoopify/song.py: -------------------------------------------------------------------------------- 1 | class Song: 2 | def __init__(self, name, length, single): 3 | self.name = name 4 | self.length = float(length) 5 | self.single = single 6 | 7 | def get_info(self): 8 | return f"{self.name} - {self.length}" 9 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/project_to_do/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/02. Classes and Objects/02. Classes and Objects - Exercise/project_to_do/__init__.py -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/project_to_do/section.py: -------------------------------------------------------------------------------- 1 | from project.task import Task 2 | 3 | 4 | class Section: 5 | tasks = [] 6 | 7 | def __init__(self, name): 8 | self.name = name 9 | 10 | def add_task(self, new_task): 11 | for show in Section.tasks: 12 | if new_task.name in show.name: 13 | return f"Task is already in the section {self.name}" 14 | Section.tasks.append(new_task) 15 | return f"Task {new_task.details()} is added to the section" 16 | 17 | def complete_task(self, task_name: str): 18 | for name_t in Section.tasks: 19 | if task_name == name_t.name: 20 | name_t.completed = True 21 | return f"Completed task {task_name}" 22 | return f"Could not find task with the name {task_name}" 23 | 24 | def clean_section(self): 25 | count = 0 26 | for pos, tasks in enumerate(Section.tasks): 27 | if tasks.completed: 28 | count += 1 29 | del Section.tasks[pos] 30 | return f"Cleared {count} tasks." 31 | 32 | def view_section(self): 33 | text = f"Section {self.name}:\n" 34 | for show in Section.tasks: 35 | text += f"{show.details()}\n" 36 | return text 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/project_to_do/task.py: -------------------------------------------------------------------------------- 1 | class Task: 2 | def __init__(self, name, due_date): 3 | self.name = name 4 | self.due_date = due_date 5 | self.comments = [] 6 | self.completed = False 7 | 8 | def change_name(self, new_name: str): 9 | if self.name == new_name: 10 | return "Name cannot be the same." 11 | self.name = new_name 12 | return self.name 13 | 14 | def change_due_date(self, new_date: str): 15 | if self.due_date == new_date: 16 | return "Name cannot be the same." 17 | self.due_date = new_date 18 | return self.due_date 19 | 20 | def add_comment(self, comment: str): 21 | self.comments.append(comment) 22 | 23 | def edit_comment(self, comment_number: int, new_comment: str): 24 | if comment_number >= len(self.comments): 25 | return "Cannot find comment." 26 | self.comments[comment_number] = new_comment 27 | return ", ".join(self.comments) 28 | 29 | def details(self): 30 | return f"Name: {self.name} - Due Date: {self.due_date}" -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/test_guild_system.py: -------------------------------------------------------------------------------- 1 | from project_guild.player import Player 2 | from project_guild.guild import Guild 3 | 4 | import unittest 5 | 6 | 7 | class PlayerTest(unittest.TestCase): 8 | 9 | def test_player_init(self): 10 | player = Player("Pesho", 90, 90) 11 | result = player.player_info().strip() 12 | expected = "Name: Pesho\nGuild: Unaffiliated\nHP: 90\nMP: 90" 13 | self.assertEqual(result, expected) 14 | 15 | def test_adding_skill_should_work(self): 16 | player = Player("Pesho", 90, 90) 17 | message = player.add_skill("A", 3) 18 | expected = "Skill A added to the collection of the player Pesho" 19 | self.assertEqual(message, expected) 20 | 21 | # def test_adding_existing_skill_should_not_work(self): 22 | # player = Player("Pesho", 90, 90) 23 | # player.add_skill("A", 3) 24 | # message = player.add_skill("A", 3) 25 | # expected = "Skill already added" 26 | # self.assertEqual(message, expected) 27 | 28 | def test_info(self): 29 | player = Player("Pesho", 90, 90) 30 | player.add_skill("A", 3) 31 | message = player.player_info().strip() 32 | expected = "Name: Pesho\nGuild: Unaffiliated\nHP: 90\nMP: 90\n===A - 3" 33 | self.assertEqual(message, expected) 34 | 35 | def test_guild_init(self): 36 | guild = Guild("GGXrd") 37 | message = guild.guild_info().strip() 38 | expeted = "Guild: GGXrd" 39 | self.assertEqual(message, expeted) 40 | 41 | def test_assign_working(self): 42 | guild = Guild("GGXrd") 43 | player = Player("Pesho", 90, 90) 44 | message = guild.assign_player(player) 45 | expected = "Welcome player Pesho to the guild GGXrd" 46 | self.assertEqual(message, expected) 47 | 48 | def test_assigning_player_in_the_same_guild(self): 49 | guild = Guild("GGXrd") 50 | player = Player("Pesho", 90, 90) 51 | guild.assign_player(player) 52 | message = guild.assign_player(player) 53 | expected = "Player Pesho is already in the guild." 54 | self.assertEqual(message, expected) 55 | 56 | 57 | if __name__ == '__main__': 58 | unittest.main() 59 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/test_library.py: -------------------------------------------------------------------------------- 1 | from project_library.library import Library 2 | from project_library.user import User 3 | from project_library.registration import Registration 4 | import unittest 5 | 6 | 7 | class TestsUser(unittest.TestCase): 8 | def setUp(self): 9 | self.user = User(12, 'Valentina') 10 | self.library = Library() 11 | self.register = Registration() 12 | 13 | # LIBRARY CLASS TESTS 14 | def test_get_book_method_with_book_available_in_the_library_should_add_it_in_the_books_list(self): 15 | self.library.books_available.update({'J.K.Rowling': ['Harry Potter and the Philosopher\'s Stone', 16 | 'Harry Potter and the Philosopher\'s Stone', 17 | 'Harry Potter and the Deathly Hallows', 18 | 'Harry Potter and the Order of the Phoenix']}) 19 | result = self.library.get_book('J.K.Rowling', 'Harry Potter and the Deathly Hallows', 17, self.user) 20 | self.assertEqual(result, 'Harry Potter and the Deathly Hallows successfully rented for the next 17 days!') 21 | self.assertEqual(self.user.books, ["Harry Potter and the Deathly Hallows"]) 22 | self.assertEqual(self.library.rented_books, {'Valentina': {'Harry Potter and the Deathly Hallows': 17}}) 23 | self.assertEqual(self.library.books_available, {'J.K.Rowling': ['Harry Potter and the Philosopher\'s Stone', 24 | 'Harry Potter and the Philosopher\'s Stone', 25 | 'Harry Potter and the Order of the Phoenix']}) 26 | 27 | def test_get_book_method_with_book_already_rented_should_return_a_message(self): 28 | self.library.books_available.update({'J.K.Rowling': ['Harry Potter and the Philosopher\'s Stone', 29 | 'Harry Potter and the Philosopher\'s Stone', 30 | 'Harry Potter and the Deathly Hallows', 31 | 'Harry Potter and the Order of the Phoenix']}) 32 | self.library.get_book('J.K.Rowling', 'Harry Potter and the Deathly Hallows', 17, self.user) 33 | second_user = User(13, 'Peter') 34 | result = self.library.get_book('J.K.Rowling', 'Harry Potter and the Deathly Hallows', 17, self.user) 35 | self.assertEqual(result, 36 | 'The book "Harry Potter and the Deathly Hallows" is already rented and will be available in 17 days!') 37 | self.assertEqual(self.user.books, ["Harry Potter and the Deathly Hallows"]) 38 | self.assertEqual(second_user.books, []) 39 | self.assertEqual(self.library.rented_books, {'Valentina': {'Harry Potter and the Deathly Hallows': 17}}) 40 | self.assertEqual(self.library.books_available, {'J.K.Rowling': ['Harry Potter and the Philosopher\'s Stone', 41 | 'Harry Potter and the Philosopher\'s Stone', 42 | 'Harry Potter and the Order of the Phoenix']}) 43 | 44 | 45 | if __name__ == "__main__": 46 | unittest.main() -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/test_spoopify.py: -------------------------------------------------------------------------------- 1 | from project_spoopify.song import Song 2 | from project_spoopify.album import Album 3 | from project_spoopify.band import Band 4 | 5 | import unittest 6 | 7 | 8 | class SongTest(unittest.TestCase): 9 | def test_song_init(self): 10 | song = Song("A", 3.15, False) 11 | message = song.get_info() 12 | expected = "A - 3.15" 13 | self.assertEqual(message, expected) 14 | 15 | def test_album_init(self): 16 | album = Album("The Sound of Perseverance") 17 | message = album.details().strip() 18 | expected = "Album The Sound of Perseverance" 19 | self.assertEqual(message, expected) 20 | 21 | def test_add_song_working(self): 22 | album = Album("The Sound of Perseverance") 23 | song = Song("Scavenger of Human Sorrow", 6.56, False) 24 | message = album.add_song(song) 25 | expected = "Song Scavenger of Human Sorrow has been added to the album The Sound of Perseverance." 26 | self.assertEqual(message, expected) 27 | 28 | def test_add_song_already_added(self): 29 | album = Album("The Sound of Perseverance") 30 | song = Song("Scavenger of Human Sorrow", 6.56, False) 31 | album.add_song(song) 32 | message = album.add_song(song) 33 | expected = "Song is already in the album." 34 | self.assertEqual(message, expected) 35 | 36 | def test_add_song_single(self): 37 | album = Album("The Sound of Perseverance") 38 | song = Song("Scavenger of Human Sorrow", 6.56, True) 39 | message = album.add_song(song) 40 | expected = "Cannot add Scavenger of Human Sorrow. It's a single" 41 | self.assertEqual(message, expected) 42 | 43 | def test_add_song_published_album(self): 44 | album = Album("The Sound of Perseverance") 45 | song = Song("Scavenger of Human Sorrow", 6.56, False) 46 | album.publish() 47 | message = album.add_song(song) 48 | expected = "Cannot add songs. Album is published." 49 | self.assertEqual(message, expected) 50 | 51 | def test_remove_song_working(self): 52 | album = Album("The Sound of Perseverance") 53 | song = Song("Scavenger of Human Sorrow", 6.56, False) 54 | album.add_song(song) 55 | message = album.remove_song("Scavenger of Human Sorrow") 56 | expected = "Removed song Scavenger of Human Sorrow from album The Sound of Perseverance." 57 | self.assertEqual(message, expected) 58 | 59 | def test_remove_song_not_in_album(self): 60 | album = Album("The Sound of Perseverance") 61 | song = Song("Scavenger of Human Sorrow", 6.56, False) 62 | message = album.remove_song("Scavenger of Human Sorrow") 63 | expected = "Song is not in the album." 64 | self.assertEqual(message, expected) 65 | 66 | def test_remove_song_album_published(self): 67 | album = Album("The Sound of Perseverance") 68 | song = Song("Scavenger of Human Sorrow", 6.56, False) 69 | album.add_song(song) 70 | album.publish() 71 | message = album.remove_song("Scavenger of Human Sorrow") 72 | expected = "Cannot remove songs. Album is published." 73 | self.assertEqual(message, expected) 74 | 75 | def test_publish(self): 76 | album = Album("The Sound of Perseverance") 77 | message = album.publish() 78 | expected = album.published 79 | self.assertTrue(expected) 80 | 81 | def test_publish_message(self): 82 | album = Album("The Sound of Perseverance") 83 | message = album.publish() 84 | expected = "Album The Sound of Perseverance has been published." 85 | self.assertEqual(message, expected) 86 | 87 | def test_details(self): 88 | album = Album("The Sound of Perseverance") 89 | song = Song("Scavenger of Human Sorrow", 6.56, False) 90 | album.add_song(song) 91 | message = album.details().strip() 92 | expected = "Album The Sound of Perseverance\n== Scavenger of Human Sorrow - 6.56" 93 | 94 | 95 | def test_init(self): 96 | band = Band("Death") 97 | message = f"{band.name} - {len(band.albums)}" 98 | expected = "Death - 0" 99 | self.assertEqual(message, expected) 100 | 101 | def test_add_album_working(self): 102 | band = Band("Death") 103 | album = Album("The Sound of Perseverance") 104 | message = band.add_album(album) 105 | expected = "Band Death has added their newest album The Sound of Perseverance." 106 | self.assertEqual(message, expected) 107 | 108 | def test_add_album_already_added(self): 109 | band = Band("Death") 110 | album = Album("The Sound of Perseverance") 111 | band.add_album(album) 112 | message = band.add_album(album) 113 | expected = "Band Death already has The Sound of Perseverance in their library." 114 | self.assertEqual(message, expected) 115 | 116 | def test_remove_album_working(self): 117 | band = Band("Death") 118 | album = Album("The Sound of Perseverance") 119 | band.add_album(album) 120 | message = band.remove_album("The Sound of Perseverance") 121 | expected = "Album The Sound of Perseverance has been removed." 122 | self.assertEqual(message, expected) 123 | 124 | def test_remove_album_not_found(self): 125 | band = Band("Death") 126 | album = Album("The Sound of Perseverance") 127 | message = band.remove_album("The Sound of Perseverance") 128 | expected = "Album The Sound of Perseverance is not found." 129 | self.assertEqual(message, expected) 130 | 131 | def test_remove_album_published(self): 132 | band = Band("Death") 133 | album = Album("The Sound of Perseverance") 134 | album.publish() 135 | band.add_album(album) 136 | message = band.remove_album("The Sound of Perseverance") 137 | expected = "Album has been published. It cannot be removed." 138 | self.assertEqual(message, expected) 139 | 140 | def test_details(self): 141 | band = Band("Death") 142 | message = band.details().strip() 143 | expected = "Band Death" 144 | self.assertEqual(message, expected) 145 | 146 | 147 | if __name__ == '__main__': 148 | unittest.main() -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Exercise/test_to_do.py: -------------------------------------------------------------------------------- 1 | from project_to_do.task import Task 2 | from project_to_do.section import Section 3 | 4 | import unittest 5 | 6 | 7 | class Test(unittest.TestCase): 8 | 9 | def test_task_init(self): 10 | task = Task("Tst", "27.04.2020") 11 | message = f"{task.name} - {task.due_date}" 12 | expected = "Tst - 27.04.2020" 13 | self.assertEqual(message, expected) 14 | 15 | def test_change_name_working(self): 16 | task = Task("Tst", "27.04.2020") 17 | task.change_name("New name") 18 | message = task.name 19 | expected = "New name" 20 | self.assertEqual(message, expected) 21 | 22 | def test_change_name_same_name(self): 23 | task = Task("Tst", "27.04.2020") 24 | message = task.change_name("Tst") 25 | expected = "Name cannot be the same." 26 | self.assertEqual(message, expected) 27 | 28 | def test_change_due_date_working(self): 29 | task = Task("Tst", "27.04.2020") 30 | task.change_due_date("21.05.2020") 31 | message = task.due_date 32 | expected = "21.05.2020" 33 | self.assertEqual(message, expected) 34 | 35 | def test_edit_comment_working(self): 36 | task = Task("Tst", "27.04.2020") 37 | task.add_comment("pay the bills") 38 | message = task.edit_comment(0, "finish my homework") 39 | expected = "finish my homework" 40 | self.assertEqual(message, expected) 41 | 42 | def test_edit_comment_not_found(self): 43 | task = Task("Tst", "27.04.2020") 44 | task.add_comment("pay the bills") 45 | message = task.edit_comment(1, "finish my homework") 46 | expected = "Cannot find comment." 47 | self.assertEqual(message, expected) 48 | 49 | def test_section_init(self): 50 | section = Section("New section") 51 | message = f"{section.name} - {len(section.tasks)}" 52 | expected = "New section - 0" 53 | self.assertEqual(message, expected) 54 | 55 | def test_add_task(self): 56 | section = Section("New section") 57 | task = Task("Tst", "27.04.2020") 58 | message = section.add_task(task) 59 | expected = "Task Name: Tst - Due Date: 27.04.2020 is added to the section" 60 | self.assertEqual(message, expected) 61 | 62 | def test_add_task_already_added(self): 63 | section = Section("New section") 64 | task = Task("Tst", "27.04.2020") 65 | section.add_task(task) 66 | message = section.add_task(task) 67 | expected = "Task is already in the section New section" 68 | self.assertEqual(message, expected) 69 | 70 | def test_complete_task(self): 71 | section = Section("New section") 72 | task = Task("Tst", "27.04.2020") 73 | section.add_task(task) 74 | section.complete_task("Tst") 75 | message = task.completed 76 | self.assertTrue(message) 77 | 78 | def test_complete_task_message(self): 79 | section = Section("New section") 80 | task = Task("Tst", "27.04.2020") 81 | section.add_task(task) 82 | message = section.complete_task("Tst") 83 | expected = "Completed task Tst" 84 | self.assertEqual(message, expected) 85 | 86 | def test_complete_not_found(self): 87 | section = Section("New section") 88 | message = section.complete_task("Tst") 89 | expected = "Could not find task with the name Tst" 90 | self.assertEqual(message, expected) 91 | 92 | def test_clean_section(self): 93 | section = Section("New section") 94 | task = Task("Tst", "27.04.2020") 95 | section.add_task(task) 96 | section.complete_task("Tst") 97 | message = section.clean_section() 98 | expected = "Cleared 1 tasks." 99 | self.assertEqual(message, expected) 100 | 101 | def test_view_section(self): 102 | section = Section("New section") 103 | message = section.view_section().strip() 104 | expected = "Section New section:" 105 | self.assertEqual(message, expected) 106 | 107 | 108 | if __name__ == '__main__': 109 | unittest.main() -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Lab/1_vehicle.py: -------------------------------------------------------------------------------- 1 | class Vehicle: 2 | def __init__(self, mileage, max_speed= 150): 3 | self.max_speed = int(max_speed) 4 | self.mileage = mileage 5 | self.gadgets = [] 6 | 7 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Lab/2_point.py: -------------------------------------------------------------------------------- 1 | class Point: 2 | def __init__(self, x, y): 3 | self.x = int(x) 4 | self.y = int(y) 5 | 6 | def set_x(self, new_x): 7 | self.x = int(new_x) 8 | 9 | def set_y(self, new_y): 10 | self.y = int(new_y) 11 | 12 | def __str__(self): 13 | return f"The point has coordinates ({self.x},{self.y})" 14 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Lab/3_circle.py: -------------------------------------------------------------------------------- 1 | class Circle: 2 | pi = 3.14 3 | 4 | def __init__(self, radius): 5 | self.radius = float(radius) 6 | 7 | def set_radius(self, new_radius): 8 | self.radius = float(new_radius) 9 | 10 | def get_area(self): 11 | return Circle.pi * self.radius ** 2 12 | 13 | def get_circumference(self): 14 | return 2 * Circle.pi * self.radius 15 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Lab/4_glass.py: -------------------------------------------------------------------------------- 1 | class Glass: 2 | content = 0 3 | capacity = 250 4 | 5 | def fill(self, ml): 6 | if self.content + ml <= self.capacity: 7 | self.content += ml 8 | return f"Glass filled with {ml} ml" 9 | return f"Cannot add {ml} ml" 10 | 11 | def empty(self): 12 | self.content = 0 13 | return "Glass is now empty" 14 | 15 | def info(self): 16 | return f"{self.capacity - self.content} ml left" -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Lab/5_smartphone.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 = True 9 | 10 | def install(self,app, app_memory): 11 | if self.is_on and self.memory >= app_memory: 12 | self.memory -= app_memory 13 | self.apps.append(app) 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 | return f"Not enough memory to install {app}" 18 | 19 | def status(self): 20 | return f"Total apps: {len(self.apps)}. Memory left: {self.memory}" 21 | 22 | -------------------------------------------------------------------------------- /02. Classes and Objects/02. Classes and Objects - Lab/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/02. Classes and Objects/02. Classes and Objects - Lab/__init__.py -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project/car.py: -------------------------------------------------------------------------------- 1 | from project.vehicle import Vehicle 2 | 3 | 4 | class Car(Vehicle): 5 | DEFAULT_FUEL_CONSUMPTION = 3 6 | 7 | def drive(self, kilometers): 8 | if kilometers * Car.DEFAULT_FUEL_CONSUMPTION <= self.fuel: 9 | self.fuel -= kilometers * Car.DEFAULT_FUEL_CONSUMPTION 10 | -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project/cross_motorcycle.py: -------------------------------------------------------------------------------- 1 | from project.motorcycle import Motorcycle 2 | 3 | 4 | class CrossMotorcycle(Motorcycle): 5 | 6 | def drive(self, kilometers): 7 | if kilometers * Motorcycle.DEFAULT_FUEL_CONSUMPTION <= self.fuel: 8 | self.fuel -= kilometers * Motorcycle.DEFAULT_FUEL_CONSUMPTION -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project/family_car.py: -------------------------------------------------------------------------------- 1 | from project.car import Car 2 | 3 | 4 | class FamilyCar(Car): 5 | 6 | def drive(self, kilometers): 7 | if kilometers * FamilyCar.DEFAULT_FUEL_CONSUMPTION <= self.fuel: 8 | self.fuel -= kilometers * FamilyCar.DEFAULT_FUEL_CONSUMPTION -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project/motorcycle.py: -------------------------------------------------------------------------------- 1 | from project.vehicle import Vehicle 2 | 3 | class Motorcycle(Vehicle): 4 | def drive(self, kilometers): 5 | if kilometers * Motorcycle.DEFAULT_FUEL_CONSUMPTION <= self.fuel: 6 | self.fuel -= kilometers * Motorcycle.DEFAULT_FUEL_CONSUMPTION 7 | -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project/race_motorcycle.py: -------------------------------------------------------------------------------- 1 | from project.motorcycle import Motorcycle 2 | 3 | class RaceMotorcycle(Motorcycle): 4 | DEFAULT_FUEL_CONSUMPTION = 8 5 | 6 | def drive(self, kilometers): 7 | if kilometers * RaceMotorcycle.DEFAULT_FUEL_CONSUMPTION <= self.fuel: 8 | self.fuel -= kilometers * RaceMotorcycle.DEFAULT_FUEL_CONSUMPTION -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project/sport_car.py: -------------------------------------------------------------------------------- 1 | from project.car import Car 2 | 3 | 4 | class SportCar(Car): 5 | DEFAULT_FUEL_CONSUMPTION = 10 6 | 7 | def drive(self, kilometers): 8 | if kilometers * SportCar.DEFAULT_FUEL_CONSUMPTION <= self.fuel: 9 | self.fuel -= kilometers * SportCar.DEFAULT_FUEL_CONSUMPTION -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project/vehicle.py: -------------------------------------------------------------------------------- 1 | class Vehicle: 2 | DEFAULT_FUEL_CONSUMPTION = 1.25 3 | 4 | def __init__(self, fuel, horse_power): 5 | self.fuel = float(fuel) 6 | self.horse_power = int(horse_power) 7 | self.fuel_consumption = self.DEFAULT_FUEL_CONSUMPTION 8 | 9 | def drive(self, kilometers): 10 | if kilometers * Vehicle.DEFAULT_FUEL_CONSUMPTION <= self.fuel: 11 | self.fuel -= kilometers * Vehicle.DEFAULT_FUEL_CONSUMPTION -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_person/child.py: -------------------------------------------------------------------------------- 1 | from project.person import Person 2 | 3 | class Child(Person): 4 | pass -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_person/person.py: -------------------------------------------------------------------------------- 1 | class Person: 2 | def __init__(self, name, age): 3 | self.name = name 4 | self.age = age -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_players_and_monsters/blade_knight.py: -------------------------------------------------------------------------------- 1 | from project.dark_knight import DarkKnight 2 | 3 | class BladeKnight(DarkKnight): 4 | def __str__(self): 5 | return f"{self.username} of type {BladeKnight.__name__} has level {self.level}" -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_players_and_monsters/dark_knight.py: -------------------------------------------------------------------------------- 1 | from project.knight import Knight 2 | 3 | class DarkKnight(Knight): 4 | def __str__(self): 5 | return f"{self.username} of type {DarkKnight.__name__} has level {self.level}" -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_players_and_monsters/dark_wizard.py: -------------------------------------------------------------------------------- 1 | from project.wizard import Wizard 2 | 3 | class DarkWizard(Wizard): 4 | def __str__(self): 5 | return f"{self.username} of type {DarkWizard.__name__} has level {self.level}" -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_players_and_monsters/elf.py: -------------------------------------------------------------------------------- 1 | from project.hero import Hero 2 | 3 | class Elf(Hero): 4 | def __str__(self): 5 | return f"{self.username} of type {Elf.__name__} has level {self.level}" -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_players_and_monsters/hero.py: -------------------------------------------------------------------------------- 1 | class Hero: 2 | def __init__(self, username, level): 3 | self.username = str(username) 4 | self.level = int(level) 5 | 6 | def __str__(self): 7 | return f"{self.username} of type {Hero.__name__} has level {self.level}" 8 | -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_players_and_monsters/knight.py: -------------------------------------------------------------------------------- 1 | from project.hero import Hero 2 | 3 | class Knight(Hero): 4 | def __str__(self): 5 | return f"{self.username} of type {Knight.__name__} has level {self.level}" -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_players_and_monsters/muse_elf.py: -------------------------------------------------------------------------------- 1 | from project.elf import Elf 2 | 3 | class MuseElf(Elf): 4 | def __str__(self): 5 | return f"{self.username} of type {MuseElf.__name__} has level {self.level}" -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_players_and_monsters/soul_master.py: -------------------------------------------------------------------------------- 1 | from project.dark_wizard import DarkWizard 2 | 3 | class SoulMaster(DarkWizard): 4 | def __str__(self): 5 | return f"{self.username} of type {SoulMaster.__name__} has level {self.level}" -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_players_and_monsters/wizard.py: -------------------------------------------------------------------------------- 1 | from project.hero import Hero 2 | 3 | class Wizard(Hero): 4 | def __str__(self): 5 | return f"{self.username} of type {Wizard.__name__} has level {self.level}" -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_shop/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/03. Inheritance/03. Inheritance - Exercise/project_shop/__init__.py -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_shop/drink.py: -------------------------------------------------------------------------------- 1 | from project.product import Product 2 | 3 | 4 | class Drink(Product): 5 | 6 | def __init__(self, name): 7 | self.name = name 8 | self.quantity = 10 9 | -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_shop/food.py: -------------------------------------------------------------------------------- 1 | from project.product import Product 2 | 3 | 4 | class Food(Product): 5 | 6 | def __init__(self, name): 7 | self.name = name 8 | self.quantity = 15 9 | -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_shop/product.py: -------------------------------------------------------------------------------- 1 | class Product: 2 | def __init__(self, name: str, quantity: int): 3 | self.name = str(name) 4 | self.quantity = int(quantity) 5 | 6 | def decrease(self, quantity: int): 7 | if self.quantity - quantity >= 0: 8 | self.quantity -= quantity 9 | 10 | def increase(self, quantity: int): 11 | self.quantity += quantity 12 | 13 | def __repr__(self): 14 | return self.name 15 | -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_shop/product_repository.py: -------------------------------------------------------------------------------- 1 | from project.product import Product 2 | 3 | 4 | class ProductRepository: 5 | products = [] 6 | 7 | def add(self, product: Product): 8 | self.products.append(product) 9 | 10 | def find(self, product: Product): 11 | for x in self.products: 12 | if x.__class__.__name__ == product.__class__.__name__: 13 | return x 14 | 15 | def remove(self, product_name): 16 | for pos, x in enumerate(self.products): 17 | if x.name == product_name: 18 | del self.products[pos] 19 | 20 | def __repr__(self): 21 | show = "" 22 | for x in self.products: 23 | if x.name not in show: 24 | show += f"{x.name}: {x.quantity}\n" 25 | return show.rstrip() 26 | -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_zoo/animal.py: -------------------------------------------------------------------------------- 1 | class Animal: 2 | def __init__(self, name): 3 | self.name = name -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_zoo/bear.py: -------------------------------------------------------------------------------- 1 | from project.mammal import Mammal 2 | 3 | class Bear(Mammal): 4 | pass -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_zoo/gorilla.py: -------------------------------------------------------------------------------- 1 | from project.mammal import Mammal 2 | 3 | class Gorilla(Mammal): 4 | pass -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_zoo/lizard.py: -------------------------------------------------------------------------------- 1 | from project.reptile import Reptile 2 | 3 | class Lizard(Reptile): 4 | pass -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_zoo/mammal.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | class Mammal(Animal): 4 | pass -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_zoo/reptile.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | class Reptile(Animal): 4 | pass -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Exercise/project_zoo/snake.py: -------------------------------------------------------------------------------- 1 | from project.reptile import Reptile 2 | 3 | class Snake(Reptile): 4 | pass -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Lab/6_stack_of_strings.py: -------------------------------------------------------------------------------- 1 | 2 | class Stack: 3 | data = [] 4 | 5 | def push(self, element): 6 | if isinstance(element, str): 7 | Stack.data.append(element) 8 | 9 | def pop(self): 10 | return Stack.data.pop() 11 | 12 | def top(self): 13 | return Stack.data[-1] 14 | 15 | def is_empty(self): 16 | if Stack.data: 17 | return False 18 | return True 19 | 20 | def __str__(self): 21 | return f"[{', '.join(Stack.data[::-1])}]" 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Lab/project_food/food.py: -------------------------------------------------------------------------------- 1 | class Food: 2 | def __init__(self, expiration_date): 3 | self.expiration_date = str(expiration_date) -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Lab/project_food/fruit.py: -------------------------------------------------------------------------------- 1 | from project.food import Food 2 | 3 | 4 | class Fruit(Food): 5 | def __init__(self, name, expiration_date): 6 | self.name = str(name) 7 | self.expiration_date = str(expiration_date) 8 | -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Lab/project_hierarchical_inheritance/animal.py: -------------------------------------------------------------------------------- 1 | class Animal: 2 | def eat(self): 3 | return "eating..." -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Lab/project_hierarchical_inheritance/cat.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | class Cat(Animal): 4 | def meow(self): 5 | return "meowing..." -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Lab/project_hierarchical_inheritance/dog.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | class Dog(Animal): 4 | def bark(self): 5 | return "barking..." -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Lab/project_multilevel_inheritance/car.py: -------------------------------------------------------------------------------- 1 | from project.vehicle import Vehicle 2 | 3 | class Car(Vehicle): 4 | def drive(self): 5 | return "driving..." -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Lab/project_multilevel_inheritance/sports_car.py: -------------------------------------------------------------------------------- 1 | from project.car import Car 2 | 3 | class SportsCar(Car): 4 | def race(self): 5 | return "racing..." -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Lab/project_multilevel_inheritance/vehicle.py: -------------------------------------------------------------------------------- 1 | class Vehicle: 2 | def move(self): 3 | return "moving..." -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Lab/project_multiple_inheritance/employee.py: -------------------------------------------------------------------------------- 1 | class Employee: 2 | 3 | def get_fired(self): 4 | return "fired..." -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Lab/project_multiple_inheritance/person.py: -------------------------------------------------------------------------------- 1 | class Person: 2 | 3 | def sleep(self): 4 | return "sleeping..." -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Lab/project_multiple_inheritance/teacher.py: -------------------------------------------------------------------------------- 1 | from project.person import Person 2 | from project.employee import Employee 3 | 4 | 5 | class Teacher(Person, Employee): 6 | 7 | def teach(self): 8 | return "teaching..." 9 | -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Lab/project_single_inheritance/animal.py: -------------------------------------------------------------------------------- 1 | class Animal: 2 | 3 | def eat(self): 4 | return "eating..." -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Lab/project_single_inheritance/dog.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | class Dog(Animal): 4 | 5 | def bark(self): 6 | return "barking..." 7 | -------------------------------------------------------------------------------- /03. Inheritance/03. Inheritance - Lab/test.py: -------------------------------------------------------------------------------- 1 | # zero test 2 | from project.person import Person 3 | from project.child import Child 4 | import unittest 5 | 6 | class Tests(unittest.TestCase): 7 | def test(self): 8 | person = Person("Peter", 25) 9 | child = Child("Peter Junior", 5) 10 | self.assertEqual(person.name, "Peter") 11 | self.assertEqual(person.age, 25) 12 | self.assertEqual(child.__class__.__bases__[0].__name__, "Person") 13 | 14 | if __name__ == "__main__": 15 | unittest.main() -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_football_team_generator/player.py: -------------------------------------------------------------------------------- 1 | class Player: 2 | def __init__(self, name, sprint, dribble, passing, shooting): 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 | @__name.setter 14 | def __name(self, value): 15 | self.name = value 16 | 17 | def __repr__(self): 18 | return f"Player: {self.__name}\n" \ 19 | f"Sprint: {self.__sprint}\n" \ 20 | f"Dribble: {self.__dribble}\n" \ 21 | f"Passing: {self.__passing}\n" \ 22 | f"Shooting: {self.__shooting}" 23 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_football_team_generator/team.py: -------------------------------------------------------------------------------- 1 | from project.player import Player 2 | 3 | 4 | class Team: 5 | 6 | def __init__(self, name, rating): 7 | self.__name = name 8 | self.__rating = rating 9 | self.__players = [] 10 | 11 | def add_player(self, player: Player): 12 | if any(x.name == player.name for x in self.__players): 13 | return f"Player {player.name} has already joined" 14 | self.__players.append(player) 15 | return f"Player {player.name} joined team {self.__name}" 16 | 17 | def remove_player(self, player_name: str): 18 | if all(x.name != player_name for x in self.__players): 19 | return f"Player {player_name} not found" 20 | for x in self.__players: 21 | if x.name == player_name: 22 | self.__players.remove(x) 23 | return x 24 | 25 | 26 | 27 | 28 | # p = Player("Pall", 1, 3, 5, 7) 29 | # 30 | # print("Player name:", p.name) 31 | # print("Points sprint:", p._Player__sprint) 32 | # print("Points dribble:", p._Player__dribble) 33 | # print("Points passing:", p._Player__passing) 34 | # print("Points shooting:", p._Player__shooting) 35 | # 36 | # print("\ncalling the __str__ method") 37 | # print(p) 38 | # 39 | # print("\nAbout the team") 40 | # t = Team("Best", 10) 41 | # print("Team name:", t._Team__name) 42 | # print("Teams points:", t._Team__rating) 43 | # print("Teams players:", len(t._Team__players)) 44 | # print(t.add_player(p)) 45 | # print(t.add_player(p)) 46 | # print("Teams players:", len(t._Team__players)) 47 | # print(t.remove_player("Pall")) 48 | # print(t.remove_player("Pall")) 49 | 50 | 51 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_pizza_maker/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/04. Encapsulation/04. Encapsulation - Exercise/project_pizza_maker/__init__.py -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_pizza_maker/dough.py: -------------------------------------------------------------------------------- 1 | from project.validation.validation import Validation 2 | 3 | 4 | class Dough: 5 | def __init__(self, flour_type: str, baking_technique: str, weight: float): 6 | self.flour_type = flour_type 7 | self.baking_technique = baking_technique 8 | self.weight = weight 9 | 10 | @property 11 | def flour_type(self): 12 | return self.__flour_type 13 | 14 | @flour_type.setter 15 | def flour_type(self, value): 16 | Validation.empty_string(value, "The flour type cannot be an empty string") 17 | self.__flour_type = value 18 | 19 | @property 20 | def baking_technique(self): 21 | return self.__baking_technique 22 | 23 | @baking_technique.setter 24 | def baking_technique(self, value): 25 | Validation.empty_string(value, "The baking technique cannot be an empty string") 26 | self.__baking_technique = value 27 | 28 | @property 29 | def weight(self): 30 | return self.__weight 31 | 32 | @weight.setter 33 | def weight(self, value): 34 | Validation.number_less_than_to(value, 0, "The weight cannot be less or equal to zero") 35 | self.__weight = value 36 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_pizza_maker/pizza.py: -------------------------------------------------------------------------------- 1 | from project.dough import Dough 2 | from project.topping import Topping 3 | from project.validation.validation import Validation 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 | Validation.empty_string(value, "The name cannot be an empty string") 20 | self.__name = value 21 | 22 | @property 23 | def dough(self): 24 | return self.__dough 25 | 26 | @dough.setter 27 | def dough(self, value): 28 | Validation.check_if_its_none(value, "You should add dough to the pizza") 29 | self.__dough = value 30 | 31 | @property 32 | def max_number_of_toppings(self): 33 | return self.__max_number_of_toppings 34 | 35 | @max_number_of_toppings.setter 36 | def max_number_of_toppings(self, value): 37 | Validation.number_less_than_to(value, 0, "The maximum number of toppings cannot be less or equal to zero") 38 | self.__max_number_of_toppings = value 39 | 40 | 41 | 42 | def add_topping(self, topping: Topping): 43 | Validation.number_less_than_to(self.max_number_of_toppings, len(self.toppings), "Not enough space for another topping") 44 | self.toppings[topping.topping_type] = self.toppings.get(topping.topping_type, 0) + topping.weight 45 | 46 | def calculate_total_weight(self): 47 | return self.dough.weight + sum(self.toppings.values()) -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_pizza_maker/project.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/04. Encapsulation/04. Encapsulation - Exercise/project_pizza_maker/project.zip -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_pizza_maker/topping.py: -------------------------------------------------------------------------------- 1 | from project.validation.validation import Validation 2 | 3 | 4 | class Topping: 5 | def __init__(self, topping_type: str, weight: float): 6 | self.topping_type = topping_type 7 | self.weight = weight 8 | 9 | @property 10 | def topping_type(self): 11 | return self.__topping_type 12 | 13 | @topping_type.setter 14 | def topping_type(self, value): 15 | Validation.empty_string(value, "The topping type cannot be an empty string") 16 | self.__topping_type = value 17 | 18 | @property 19 | def weight(self): 20 | return self.__weight 21 | 22 | @weight.setter 23 | def weight(self, value): 24 | Validation.number_less_than_to(value, 0, "The weight cannot be less or equal to zero") 25 | self.__weight = value 26 | 27 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_pizza_maker/validation/validation.py: -------------------------------------------------------------------------------- 1 | class Validation: 2 | 3 | @staticmethod 4 | def empty_string(string_: str, message: str): 5 | if len(string_) == 0: 6 | raise ValueError(message) 7 | 8 | @staticmethod 9 | def number_less_than_to(number: float, number_to_check: float, message: str): 10 | if number <= number_to_check: 11 | raise ValueError(message) 12 | 13 | @staticmethod 14 | def check_if_its_none(object_to_check: object, message: str): 15 | if object_to_check is None: 16 | raise ValueError(message) -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/__init__.py -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/beverage/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/beverage/__init__.py -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/beverage/beverage.py: -------------------------------------------------------------------------------- 1 | from project.product import Product 2 | 3 | 4 | class Beverage(Product): 5 | def __init__(self, name, price, milliliters): 6 | super().__init__(name, price) 7 | 8 | self.__milliliters = milliliters 9 | 10 | @property 11 | def milliliters(self): 12 | return self.__milliliters 13 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/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, caffeine): 9 | super().__init__(name, Coffee.PRICE, Coffee.MILLILITERS) 10 | 11 | self.__caffeine = caffeine 12 | 13 | @property 14 | def caffeine(self): 15 | return self.__caffeine 16 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/beverage/cold_beverage.py: -------------------------------------------------------------------------------- 1 | from project.beverage.beverage import Beverage 2 | 3 | 4 | class ColdBeverage(Beverage): 5 | def __init__(self, name, price, milliliters): 6 | super().__init__(name, price, milliliters) -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/beverage/hot_beverage.py: -------------------------------------------------------------------------------- 1 | from project.beverage.beverage import Beverage 2 | 3 | 4 | class HotBeverage(Beverage): 5 | def __init__(self, name, price, milliliters): 6 | super().__init__(name, price, milliliters) -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/beverage/tea.py: -------------------------------------------------------------------------------- 1 | from project.beverage.hot_beverage import HotBeverage 2 | 3 | 4 | class Tea(HotBeverage): 5 | def __init__(self, name, price, milliliters): 6 | super().__init__(name, price, milliliters) 7 | 8 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/food/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/food/__init__.py -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/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): 10 | super().__init__(name, Cake.PRICE, Cake.GRAMS, Cake.CALORIES) -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/food/dessert.py: -------------------------------------------------------------------------------- 1 | from project.food.food import Food 2 | 3 | 4 | class Dessert(Food): 5 | def __init__(self, name, price, grams, calories): 6 | super().__init__(name, price, grams) 7 | 8 | self.__calories = calories 9 | 10 | @property 11 | def calories(self): 12 | return self.__calories 13 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/food/food.py: -------------------------------------------------------------------------------- 1 | from project.product import Product 2 | 3 | 4 | class Food(Product): 5 | def __init__(self, name, price, grams): 6 | super().__init__(name, price) 7 | 8 | self.__grams = grams 9 | 10 | @property 11 | def grams(self): 12 | return self.__grams 13 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/food/main_dish.py: -------------------------------------------------------------------------------- 1 | from project.food.food import Food 2 | 3 | 4 | class MainDish(Food): 5 | def __init__(self, name, price, grams): 6 | super().__init__(name, price, grams) -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/food/salmon.py: -------------------------------------------------------------------------------- 1 | from project.food.main_dish import MainDish 2 | 3 | class Salmon(MainDish): 4 | GRAMS = 22 5 | 6 | def __init__(self, name, price): 7 | super().__init__(name, price, Salmon.GRAMS) -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/food/soup.py: -------------------------------------------------------------------------------- 1 | from project.food.starter import Starter 2 | 3 | 4 | class Soup(Starter): 5 | def __init__(self, name, price, grams): 6 | super().__init__(name, price, grams) 7 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/food/starter.py: -------------------------------------------------------------------------------- 1 | from project.food.food import Food 2 | 3 | 4 | class Starter(Food): 5 | def __init__(self, name, price, grams): 6 | super().__init__(name, price, grams) -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_restaurant/product.py: -------------------------------------------------------------------------------- 1 | class Product: 2 | def __init__(self, name, price): 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 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_wild_cat_zoo/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/04. Encapsulation/04. Encapsulation - Exercise/project_wild_cat_zoo/__init__.py -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_wild_cat_zoo/animal.py: -------------------------------------------------------------------------------- 1 | class Animal: 2 | def __init__(self, name : str, gender : str, age: int, money_for_care=0): 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): 9 | return f"Name: {self.name}, Age: {self.age}, Gender: {self.gender}" 10 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_wild_cat_zoo/caretaker.py: -------------------------------------------------------------------------------- 1 | from project.worker import Worker 2 | 3 | class Caretaker(Worker): 4 | pass -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_wild_cat_zoo/cheetah.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | class Cheetah(Animal): 4 | def __init__(self, name: str, gender: str, age: int, money_for_care=0): 5 | super().__init__(name, gender, age, money_for_care) 6 | self.money_for_care = 60 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_wild_cat_zoo/keeper.py: -------------------------------------------------------------------------------- 1 | from project.worker import Worker 2 | 3 | class Keeper(Worker): 4 | pass -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_wild_cat_zoo/lion.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | 4 | class Lion(Animal): 5 | def __init__(self, name: str, gender: str, age: int, money_for_care=0): 6 | super().__init__(name, gender, age, money_for_care) 7 | self.money_for_care = 50 8 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_wild_cat_zoo/tiger.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | class Tiger(Animal): 4 | def __init__(self, name: str, gender: str, age: int, money_for_care=0): 5 | super().__init__(name, gender, age, money_for_care) 6 | self.money_for_care = 45 7 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_wild_cat_zoo/vet.py: -------------------------------------------------------------------------------- 1 | from project.worker import Worker 2 | 3 | class Vet(Worker): 4 | pass -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_wild_cat_zoo/worker.py: -------------------------------------------------------------------------------- 1 | class Worker: 2 | def __init__(self, name: str, age: int, salary: int): 3 | self.name = name 4 | self.age = int(age) 5 | self.salary = int(salary) 6 | 7 | def __repr__(self): 8 | return f"Name: {self.name}, Age: {self.age}, Salary: {self.salary}" 9 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Exercise/project_wild_cat_zoo/zoo.py: -------------------------------------------------------------------------------- 1 | class Zoo: 2 | 3 | def __init__(self, name : str, budget: int, animal_capacity: int, workers_capacity: int): 4 | self.name = name 5 | self.__budget = budget 6 | self.__animal_capacity = animal_capacity 7 | self.__workers_capacity = workers_capacity 8 | self.animals = [] 9 | self.workers = [] 10 | 11 | def add_animal(self, animal, price): 12 | price = int(price) 13 | if self.__animal_capacity > len(self.animals) and price > self.__budget: 14 | return "Not enough budget" 15 | 16 | if price <= self.__budget and self.__animal_capacity > len(self.animals): 17 | self.animals.append(animal) 18 | self.__budget -= price 19 | return f"{animal.name} the {animal.__class__.__name__} added to the zoo" 20 | 21 | return "Not enough space for animal" 22 | 23 | def hire_worker(self, worker): 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): 30 | for pos, x in enumerate(self.workers): 31 | if x.name == worker_name: 32 | del self.workers[pos] 33 | return f"{worker_name} fired successfully" 34 | return f"There is no {worker_name} in the zoo" 35 | 36 | def pay_workers(self): 37 | workers_salary = sum(x.salary for x in self.workers) 38 | if workers_salary <= self.__budget: 39 | self.__budget -= workers_salary 40 | return f"You payed your workers. They are happy. Budget left: {self.__budget}" 41 | 42 | return "You have no budget to pay your workers. They are unhappy" 43 | 44 | def tend_animals(self): 45 | tended_animals = sum(x.money_for_care for x in self.animals) 46 | if tended_animals <= self.__budget: 47 | self.__budget -= tended_animals 48 | return f"You tended all the animals. They are happy. Budget left: {self.__budget}" 49 | return "You have no budget to tend the animals. They are unhappy." 50 | 51 | def profit(self, amount): 52 | self.__budget += int(amount) 53 | 54 | def animals_status(self): 55 | info = {"Cheetah": [], "Tiger": [], "Lion": []} 56 | [info[x.__class__.__name__].append(str(x)) for x in self.animals] 57 | output = [f"You have {len(info['Cheetah']) + len(info['Tiger']) + len(info['Lion'])} animals", 58 | f"----- {len(info['Lion'])} Lions:", *info['Lion'], 59 | f"----- {len(info['Tiger'])} Tigers:", *info['Tiger'], 60 | f"----- {len(info['Cheetah'])} Cheetahs:", *info['Cheetah']] 61 | return "\n".join(output) 62 | 63 | def workers_status(self): 64 | info = {"Keeper": [], "Vet": [], "Caretaker": []} 65 | [info[x.__class__.__name__].append(str(x)) for x in self.workers] 66 | output = [f"You have {len(info['Keeper']) + len(info['Vet']) + len(info['Caretaker'])} workers", 67 | f"----- {len(info['Keeper'])} Keepers:", *info['Keeper'], 68 | f"----- {len(info['Caretaker'])} Caretakers:", *info['Caretaker'], 69 | f"----- {len(info['Vet'])} Vets:", *info['Vet']] 70 | return "\n".join(output) 71 | 72 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Lab/1_person.py: -------------------------------------------------------------------------------- 1 | class Person: 2 | def __init__(self, name, age): 3 | self.__name = name 4 | self.__age = age 5 | 6 | def get_name(self): 7 | return self.__name 8 | 9 | def get_age(self): 10 | return self.__age 11 | 12 | 13 | # class Person: 14 | # def __init__(self, name, age): 15 | # self.__name = name 16 | # self.__age = age 17 | # 18 | # @property 19 | # def name(self): 20 | # return self.__name 21 | # 22 | # @name.setter 23 | # def name(self, value): 24 | # self.__name = value 25 | # 26 | # @property 27 | # def age(self): 28 | # return self.__age 29 | # 30 | # @age.setter 31 | # def age(self, value): 32 | # self.__age = value 33 | 34 | 35 | # class Person: 36 | # def __init__(self, name, age): 37 | # self.name = name 38 | # self.age = age 39 | # 40 | # @property 41 | # def name(self): 42 | # return self.__name 43 | # 44 | # @name.setter 45 | # def name(self, value): 46 | # if not value or not isinstance(value, str): 47 | # raise ValueError("Name must be a non-empty string") 48 | # self.__name = value 49 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Lab/2_mammal.py: -------------------------------------------------------------------------------- 1 | class Mammal: 2 | def __init__(self, name, type, sound): 3 | self.__kingdom = "animals" 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 self.__kingdom 13 | 14 | def info(self): 15 | return f"{self.name} is of type {self.type}" 16 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Lab/3_profile.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 5 <= len(value) <= 15: 13 | self.__username = value 14 | else: 15 | raise ValueError("The username must be between 5 and 15 characters.") 16 | 17 | @property 18 | def password(self): 19 | return self.__password 20 | 21 | @password.setter 22 | def password(self, value): 23 | if len(value) >= 8 and sum(1 for x in value if x.isdigit()) >= 1 and \ 24 | sum(1 for x in value if x.isupper()): 25 | self.__password = value 26 | else: 27 | raise ValueError("The password must be 8 or more characters " 28 | "with at least 1 digit and 1 uppercase letter.") 29 | 30 | def __str__(self): 31 | return f'You have a profile with username: "{self.__username}" and ' \ 32 | f'password: {"*" * len(self.__password)}' 33 | 34 | 35 | 36 | # correct_profile = Profile("Username", "Passw0rd") 37 | # print(correct_profile) 38 | 39 | profile_with_invalid_username = Profile('Too_long_username', 'Any') 40 | -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Lab/4_email_validator.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 | email = email.split("@") 18 | mail, domain = email[1].split(".") 19 | name = email[0] 20 | return self.__is_name_valid(name) and self.__is_mail_valid(mail) and self.__is_domain_valid(domain) 21 | 22 | 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")) -------------------------------------------------------------------------------- /04. Encapsulation/04. Encapsulation - Lab/5_account.py: -------------------------------------------------------------------------------- 1 | class Account: 2 | 3 | def __init__(self, id, balance, pin): 4 | self.id = id 5 | self.balance = balance 6 | self.pin = pin 7 | 8 | @property 9 | def id(self): 10 | return self.__id 11 | 12 | @id.setter 13 | def id(self, value): 14 | self.__id = value 15 | 16 | @property 17 | def pin(self): 18 | return self.__pin 19 | 20 | @pin.setter 21 | def pin(self, value): 22 | self.__pin = value 23 | 24 | def get_id(self, pin): 25 | if pin == self.__pin: 26 | return self.__id 27 | return "Wrong pin" 28 | 29 | def change_pin(self, old_pin, new_pin): 30 | if old_pin == self.__pin: 31 | self.__pin = new_pin 32 | return "Pin changed" 33 | return "Wrong pin" 34 | 35 | 36 | 37 | account = Account(8827312, 100, 3421) 38 | print(account.get_id(1111)) 39 | print(account.get_id(3421)) 40 | print(account.balance) 41 | print(account.change_pin(2212, 4321)) 42 | print(account.change_pin(3421, 1234)) 43 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/1_photo_album.py: -------------------------------------------------------------------------------- 1 | from math import ceil 2 | 3 | 4 | class PhotoAlbum: 5 | 6 | def __init__(self, pages): 7 | self.pages = pages 8 | self.photos = [[] for _ in range(pages)] 9 | 10 | @classmethod 11 | def from_photos_count(cls, photos_count: int): 12 | return cls(ceil(photos_count / 4)) 13 | 14 | def add_photo(self, label: str): 15 | for row in range(len(self.photos)): 16 | if len(self.photos[row]) < 4: 17 | self.photos[row].append(label) 18 | return f"{label} photo added successfully on page {row + 1} slot {len(self.photos[row])}" 19 | return "No more free slots" 20 | 21 | def display(self): 22 | output = ["-----------",] 23 | for row in range(len(self.photos)): 24 | how_long = len(self.photos[row]) 25 | if how_long > 0: 26 | pics = "[] " * how_long 27 | else: 28 | pics = "" 29 | output.append(pics.rstrip()) 30 | output.append("-----------") 31 | return "\n".join(output) 32 | 33 | 34 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_2_movie_world/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/05. Static and Class Methods/05. Static and Class Methods - Exercise/project_2_movie_world/__init__.py -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_2_movie_world/customer.py: -------------------------------------------------------------------------------- 1 | class Customer: 2 | 3 | def __init__(self, name, age, id): 4 | self.id = id 5 | self.age = age 6 | self.name = name 7 | self.rented_dvds = [] 8 | 9 | def __repr__(self): 10 | return f"{self.id}: {self.name} of age {self.age} " \ 11 | f"has {len(self.rented_dvds)} rented DVD's ({', '.join(x.name for x in self.rented_dvds)})" 12 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_2_movie_world/dvd.py: -------------------------------------------------------------------------------- 1 | month = {'01': 'January', 2 | '02': 'February', 3 | '03': 'March', 4 | '04': 'April', 5 | '05': 'May', 6 | '06': 'June', 7 | '07': 'July', 8 | '08': 'August', 9 | '09': 'September', 10 | '10': 'October', 11 | '11': 'November', 12 | '12': 'December'} 13 | status = {True: "rented", False: "not rented"} 14 | 15 | 16 | class DVD: 17 | 18 | def __init__(self, name, id, creation_year, creation_month, age_restriction): 19 | self.creation_month = creation_month 20 | self.creation_year = creation_year 21 | self.age_restriction = age_restriction 22 | self.id = id 23 | self.name = name 24 | self.is_rented = False 25 | 26 | @classmethod 27 | def from_date(cls, id: int, name: str, date: str, age_restriction: int): 28 | mount_creation, year_creation = date.split(".")[1:] 29 | return cls(name, id, int(year_creation), month[mount_creation], age_restriction) 30 | 31 | def __repr__(self): 32 | return f"{self.id}: {self.name} ({self.creation_month} {self.creation_year}) " \ 33 | f"has age restriction {self.age_restriction}. Status: {status[self.is_rented]}" 34 | 35 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_2_movie_world/movie_world.py: -------------------------------------------------------------------------------- 1 | from project.customer import Customer 2 | from project.dvd import DVD 3 | 4 | 5 | class MovieWorld: 6 | def __init__(self, name): 7 | self.name = name 8 | self.customers = [] 9 | self.dvds = [] 10 | 11 | @staticmethod 12 | def dvd_capacity(): 13 | return 15 14 | 15 | @staticmethod 16 | def customer_capacity(): 17 | return 10 18 | 19 | def __get_customer(self, id): 20 | return [customer for customer in self.customers if id == customer.id][0] 21 | 22 | def __get_dvd(self, id): 23 | return [x for x in self.dvds if x.id == id][0] 24 | 25 | def add_customer(self, customer: Customer): 26 | if len(self.customers) < MovieWorld.customer_capacity(): 27 | self.customers.append(customer) 28 | 29 | def add_dvd(self, dvd: DVD): 30 | if len(self.dvds) < MovieWorld.dvd_capacity(): 31 | self.dvds.append(dvd) 32 | 33 | def rent_dvd(self, customer_id: int, dvd_id: int): 34 | find_dvd = self.__get_dvd(dvd_id) 35 | find_customer = self.__get_customer(customer_id) 36 | 37 | if find_dvd in find_customer.rented_dvds: 38 | return f"{find_customer.name} has already rented {find_dvd.name}" 39 | 40 | if find_dvd.is_rented: 41 | return "DVD is already rented" 42 | 43 | if find_customer.age < find_dvd.age_restriction: 44 | return f"{find_customer.name} should be at least {find_dvd.age_restriction} to rent this movie" 45 | 46 | find_customer.rented_dvds.append(find_dvd) 47 | find_dvd.is_rented = True 48 | return f"{find_customer.name} has successfully rented {find_dvd.name}" 49 | 50 | def return_dvd(self, customer_id, dvd_id): 51 | find_dvd = self.__get_dvd(dvd_id) 52 | find_customer = self.__get_customer(customer_id) 53 | 54 | if find_dvd in find_customer.rented_dvds: 55 | find_customer.rented_dvds.remove(find_dvd) 56 | find_dvd.is_rented = False 57 | return f"{find_customer.name} has successfully returned {find_dvd.name}" 58 | 59 | return f"{find_customer.name} does not have that DVD" 60 | 61 | def __repr__(self): 62 | output = "" 63 | for x in self.customers: 64 | output += f"{str(x)}\n" 65 | for x in self.dvds: 66 | output += f"{str(x)}\n" 67 | return output.rstrip() 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_3_document_management/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/05. Static and Class Methods/05. Static and Class Methods - Exercise/project_3_document_management/__init__.py -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_3_document_management/category.py: -------------------------------------------------------------------------------- 1 | class Category: 2 | 3 | def __init__(self, id, name): 4 | self.name = name 5 | self.id = id 6 | 7 | def edit(self, new_name: str): 8 | self.name = new_name 9 | 10 | def __repr__(self): 11 | return f"Category {self.id}: {self.name}" 12 | 13 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_3_document_management/document.py: -------------------------------------------------------------------------------- 1 | from project.category import Category 2 | from project.topic import Topic 3 | 4 | 5 | class Document: 6 | 7 | def __init__(self, id, category_id, topic_id, file_name): 8 | self.file_name = file_name 9 | self.topic_id = topic_id 10 | self.category_id = category_id 11 | self.id = id 12 | self.tags = [] 13 | 14 | @classmethod 15 | def from_instances(cls, id: int, category: Category, topic: Topic, file_name: str): 16 | return cls(id, category.id, topic.id, file_name) 17 | 18 | def add_tag(self, tag_content: str): 19 | if tag_content not in self.tags: 20 | self.tags.append(tag_content) 21 | 22 | def remove_tag(self, tag_content:str): 23 | if tag_content in self.tags: 24 | self.tags.remove(tag_content) 25 | 26 | def edit(self, file_name:str): 27 | self.file_name = file_name 28 | 29 | def __repr__(self): 30 | return f"Document {self.id}: {self.file_name}; category {self.category_id}, " \ 31 | f"topic {self.topic_id}, tags: {', '.join(self.tags)}" 32 | 33 | 34 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_3_document_management/storage.py: -------------------------------------------------------------------------------- 1 | from project.category import Category 2 | from project.topic import Topic 3 | from project.document import Document 4 | 5 | 6 | class Storage: 7 | 8 | def __init__(self): 9 | self.categories = [] 10 | self.topics = [] 11 | self.documents = [] 12 | 13 | def add_category(self, category: Category): 14 | if category not in self.categories: 15 | self.categories.append(category) 16 | 17 | def add_topic(self, topic: Topic): 18 | if topic not in self.topics: 19 | self.topics.append(topic) 20 | 21 | def add_document(self, document:Document): 22 | if document not in self.documents: 23 | self.documents.append(document) 24 | 25 | def edit_category(self, category_id: int, new_name:str): 26 | for x in self.categories: 27 | if category_id == x.id: 28 | x.name = new_name 29 | break 30 | 31 | def edit_topic(self, topic_id: int, new_topic: str, new_storage_folder: str): 32 | for x in self.topics: 33 | if x.id == topic_id: 34 | x.storage_folder = new_storage_folder 35 | x.topic = new_topic 36 | break 37 | 38 | def edit_document(self, document_id: int, new_file_name: str): 39 | for x in self.documents: 40 | if x.id == document_id: 41 | x.file_name = new_file_name 42 | 43 | def delete_category(self, category_id): 44 | for x in self.categories: 45 | if x.id == category_id: 46 | self.categories.remove(x) 47 | break 48 | 49 | def delete_topic(self, topic_id): 50 | for x in self.topics: 51 | if x.id == topic_id: 52 | self.topics.remove(x) 53 | break 54 | 55 | def delete_document(self, document_id): 56 | for x in self.documents: 57 | if x.id == document_id: 58 | self.documents.remove(x) 59 | break 60 | 61 | def get_document(self, document_id): 62 | for x in self.documents: 63 | if x.id == document_id: 64 | return f"{str(x)}" 65 | 66 | def __repr__(self): 67 | return "\n".join(str(x) for x in self.documents) 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_3_document_management/topic.py: -------------------------------------------------------------------------------- 1 | class Topic: 2 | def __init__(self, id, topic, storage_folder): 3 | self.storage_folder = storage_folder 4 | self.topic = topic 5 | self.id = id 6 | 7 | def edit(self, new_topic: str, new_storage_folder: str): 8 | self.topic = new_topic 9 | self.storage_folder = new_storage_folder 10 | 11 | def __repr__(self): 12 | return f"Topic {self.id}: {self.topic} in {self.storage_folder}" 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_4_gym/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/05. Static and Class Methods/05. Static and Class Methods - Exercise/project_4_gym/__init__.py -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_4_gym/customer.py: -------------------------------------------------------------------------------- 1 | class Customer: 2 | id = 1 3 | 4 | def __init__(self, name: str, address: str, email: str): 5 | self.address = address 6 | self.email = email 7 | self.name = name 8 | self.id = self.get_next_id() 9 | 10 | @staticmethod 11 | def get_next_id(): 12 | result = Customer.id 13 | Customer.id += 1 14 | return result 15 | 16 | def __repr__(self): 17 | return f"Customer <{self.id}> {self.name}; Address: {self.address}; Email: {self.email}" 18 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_4_gym/equipment.py: -------------------------------------------------------------------------------- 1 | class Equipment: 2 | id = 1 3 | 4 | def __init__(self, name: str): 5 | self.name = name 6 | self.id = Equipment.get_next_id() 7 | 8 | @staticmethod 9 | def get_next_id(): 10 | result = Equipment.id 11 | Equipment.id += 1 12 | return result 13 | 14 | def __repr__(self): 15 | return f"Equipment <{self.id}> {self.name}" 16 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_4_gym/exercise_plan.py: -------------------------------------------------------------------------------- 1 | class ExercisePlan: 2 | id = 1 3 | 4 | def __init__(self, trainer_id: int, equipment_id: int, duration: int): 5 | self.duration = duration 6 | self.equipment_id = equipment_id 7 | self.trainer_id = trainer_id 8 | self.id = ExercisePlan.get_next_id() 9 | 10 | @staticmethod 11 | def get_next_id(): 12 | result = ExercisePlan.id 13 | ExercisePlan.id += 1 14 | return result 15 | 16 | @classmethod 17 | def from_hours(cls, trainer_id: int, equipment_id: int, hours: int): 18 | duration = hours * 60 19 | return cls(trainer_id, equipment_id, duration) 20 | 21 | def __repr__(self): 22 | return f"Plan <{self.id}> with duration {self.duration} minutes" 23 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_4_gym/gym.py: -------------------------------------------------------------------------------- 1 | from project.customer import Customer 2 | from project.equipment import Equipment 3 | from project.exercise_plan import ExercisePlan 4 | from project.subscription import Subscription 5 | from project.trainer import Trainer 6 | 7 | 8 | class Gym: 9 | 10 | def __init__(self): 11 | self.customers = [] 12 | self.trainers = [] 13 | self.equipment = [] 14 | self.plans = [] 15 | self.subscriptions = [] 16 | 17 | @staticmethod 18 | def __add_data(collection, item): 19 | if item not in collection: 20 | collection.append(item) 21 | 22 | def add_customer(self, customer: Customer): 23 | Gym.__add_data(self.customers, customer) 24 | 25 | def add_trainer(self, trainer: Trainer): 26 | Gym.__add_data(self.trainers, trainer) 27 | 28 | def add_equipment(self, equipment: Equipment): 29 | Gym.__add_data(self.equipment, equipment) 30 | 31 | def add_plan(self, plan: ExercisePlan): 32 | Gym.__add_data(self.plans, plan) 33 | 34 | def add_subscription(self, subscription: Subscription): 35 | Gym.__add_data(self.subscriptions, subscription) 36 | 37 | def subscription_info(self, subscription_id: int): 38 | 39 | # output = [] 40 | # for info in (self.subscriptions,self.customers, self.trainers, self.equipment, self.plans): 41 | # for x in info: 42 | # if x.id == subscription_id: 43 | # output.append(str(x)) 44 | 45 | # output = [[str(x) for x in self.subscriptions if x.id == subscription_id][0], 46 | # [str(x) for x in self.customers if x.id == subscription_id][0], 47 | # [str(x) for x in self.trainers if x.id == subscription_id][0], 48 | # [str(x) for x in self.equipment if x.id == subscription_id][0], 49 | # [str(x) for x in self.plans if x.id == subscription_id][0]] 50 | 51 | return "\n".join( 52 | str(x) for info in (self.subscriptions, self.customers, self.trainers, self.equipment, self.plans) 53 | for x in info if x.id == subscription_id) 54 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_4_gym/subscription.py: -------------------------------------------------------------------------------- 1 | class Subscription: 2 | id = 1 3 | 4 | def __init__(self, date:str, customer_id: int, trainer_id: int, exercise_id: int): 5 | self.exercise_id = exercise_id 6 | self.trainer_id = trainer_id 7 | self.customer_id = customer_id 8 | self.date = date 9 | self.id = Subscription.get_next_id() 10 | 11 | @staticmethod 12 | def get_next_id(): 13 | result = Subscription.id 14 | Subscription.id += 1 15 | return result 16 | 17 | def __repr__(self): 18 | return f"Subscription <{self.id}> on {self.date}" 19 | 20 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Exercise/project_4_gym/trainer.py: -------------------------------------------------------------------------------- 1 | class Trainer: 2 | id = 1 3 | 4 | def __init__(self, name: str): 5 | self.name = name 6 | self.id = Trainer.get_next_id() 7 | 8 | @staticmethod 9 | def get_next_id(): 10 | result = Trainer.id 11 | Trainer.id += 1 12 | return result 13 | 14 | def __repr__(self): 15 | return f"Trainer <{self.id}> {self.name}" 16 | 17 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Lab/1_calculator.py: -------------------------------------------------------------------------------- 1 | class Calculator: 2 | 3 | @staticmethod 4 | def add(*args): 5 | return sum(args) 6 | 7 | @staticmethod 8 | def multiply(*args): 9 | output = 1 10 | for x in args: 11 | output *= x 12 | return output 13 | 14 | @staticmethod 15 | def divide(*args): 16 | output = args[0] 17 | for x in args[1:]: 18 | output /= x 19 | return output 20 | 21 | @staticmethod 22 | def subtract(*args): 23 | output = args[0] 24 | for x in args[1:]: 25 | output -= x 26 | return output 27 | 28 | 29 | 30 | # from functools import reduce 31 | # 32 | # 33 | # class Calculator: 34 | # 35 | # @staticmethod 36 | # def add(*args): 37 | # return reduce(lambda x, y: x + y, args) 38 | # 39 | # @staticmethod 40 | # def multiply(*args): 41 | # return reduce(lambda x, y: x * y, args) 42 | # 43 | # @staticmethod 44 | # def divide(*args): 45 | # return reduce(lambda x, y: x / y, args) 46 | # 47 | # @staticmethod 48 | # def subtract(*args): 49 | # return reduce(lambda x, y: x - y, args) -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Lab/2_shop.py: -------------------------------------------------------------------------------- 1 | class Shop: 2 | 3 | def __init__(self, name, type, capacity): 4 | self.capacity = capacity 5 | self.type = type 6 | self.name = name 7 | self.items = {} 8 | 9 | @staticmethod 10 | def small_shop(name: str, type: str): 11 | return Shop(name, type, 10) 12 | 13 | def add_item(self, item_name:str): 14 | if self.capacity > sum(self.items.values()): 15 | self.items[item_name] = self.items.get(item_name, 0) + 1 16 | return f"{item_name} added to the shop" 17 | return "Not enough capacity in the shop" 18 | 19 | def remove_item(self, item_name:str, amount:int): 20 | if item_name not in self.items or self.items[item_name] - amount < 0: 21 | return f"Cannot remove {amount} {item_name}" 22 | 23 | self.items[item_name] -= amount 24 | if self.items[item_name] <= 0: 25 | del self.items[item_name] 26 | return f"{amount} {item_name} removed from the shop" 27 | 28 | def __repr__(self): 29 | return f"{self.name} of type {self.type} with capacity {self.capacity}" 30 | 31 | 32 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Lab/3_integer.py: -------------------------------------------------------------------------------- 1 | class Integer: 2 | def __init__(self, value): 3 | self.value = value 4 | 5 | @staticmethod 6 | def from_float(float_value): 7 | if not isinstance(float_value, float): 8 | return "value is not a float" 9 | return Integer(int(float_value)) 10 | 11 | @staticmethod 12 | def from_roman(value): 13 | def value_(r): 14 | if r == 'I': 15 | return 1 16 | if r == 'V': 17 | return 5 18 | if r == 'X': 19 | return 10 20 | if r == 'L': 21 | return 50 22 | if r == 'C': 23 | return 100 24 | if r == 'D': 25 | return 500 26 | if r == 'M': 27 | return 1000 28 | return -1 29 | 30 | def romanToDecimal(str): 31 | res = 0 32 | i = 0 33 | 34 | while i < len(str): 35 | 36 | s1 = value_(str[i]) 37 | 38 | if i + 1 < len(str): 39 | s2 = value_(str[i + 1]) 40 | if s1 >= s2: 41 | res = res + s1 42 | i = i + 1 43 | else: 44 | res = res + s2 - s1 45 | i = i + 2 46 | else: 47 | res = res + s1 48 | i = i + 1 49 | 50 | return Integer(int(res)) 51 | 52 | return romanToDecimal(value) 53 | 54 | @staticmethod 55 | def from_string(value): 56 | if str(value).isdigit(): 57 | return Integer(int(value)) 58 | else: 59 | return "wrong type" 60 | 61 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Lab/project_4_hotel_rooms/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/05. Static and Class Methods/05. Static and Class Methods - Lab/project_4_hotel_rooms/__init__.py -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Lab/project_4_hotel_rooms/hotel.py: -------------------------------------------------------------------------------- 1 | from project.room import Room 2 | 3 | 4 | class Hotel: 5 | 6 | def __init__(self, name): 7 | self.name = name 8 | self.rooms = [] 9 | self.guests = 0 10 | 11 | @staticmethod 12 | def from_stars(stars_count: int): 13 | return Hotel(f"{stars_count} stars Hotel") 14 | 15 | def add_room(self, room: Room): 16 | self.rooms.append(room) 17 | 18 | def take_room(self, room_number, people): 19 | [room.take_room(people) for room in self.rooms if room.number == room_number] 20 | 21 | def free_room(self, room_number): 22 | [room.free_room() for room in self.rooms if room.number == room_number] 23 | 24 | def status(self): 25 | self.guests = 0 26 | free_rooms, taken_rooms = [], [] 27 | for x in self.rooms: 28 | if x.is_taken: 29 | taken_rooms.append(str(x.number)) 30 | self.guests += x.guests 31 | else: 32 | free_rooms.append(str(x.number)) 33 | output = [f"Hotel {self.name} has {self.guests} total guests", 34 | f"Free rooms: {', '.join(free_rooms)}", 35 | f"Taken rooms: {', '.join(taken_rooms)}"] 36 | 37 | return "\n".join(output) 38 | 39 | -------------------------------------------------------------------------------- /05. Static and Class Methods/05. Static and Class Methods - Lab/project_4_hotel_rooms/room.py: -------------------------------------------------------------------------------- 1 | 2 | class Room: 3 | def __init__(self, number, capacity): 4 | self.capacity = capacity 5 | self.number = number 6 | self.guests = 0 7 | self.is_taken = False 8 | 9 | def take_room(self, people): 10 | if not self.is_taken and self.capacity >= people: 11 | self.is_taken = True 12 | self.guests = people 13 | else: 14 | return f"Room number {self.number} cannot be taken" 15 | 16 | def free_room(self): 17 | if self.is_taken: 18 | self.guests = 0 19 | self.is_taken = False 20 | else: 21 | return f"Room number {self.number} is not taken" 22 | 23 | 24 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/1_vehicles.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class Vehicle(ABC): 5 | 6 | @abstractmethod 7 | def drive(self, distance): 8 | pass 9 | 10 | @abstractmethod 11 | def refuel(self, fuel): 12 | pass 13 | 14 | 15 | class Car(Vehicle): 16 | def __init__(self, fuel_quantity, fuel_consumption): 17 | self.fuel_consumption = fuel_consumption 18 | self.fuel_quantity = fuel_quantity 19 | self.__air_conditioners_consumptions = 0.9 20 | 21 | def drive(self, distance): 22 | consumption = distance * (self.fuel_consumption + self.__air_conditioners_consumptions) 23 | if consumption <= self.fuel_quantity: 24 | self.fuel_quantity -= consumption 25 | 26 | def refuel(self, fuel): 27 | self.fuel_quantity += fuel 28 | 29 | 30 | class Truck(Vehicle): 31 | def __init__(self, fuel_quantity, fuel_consumption): 32 | self.fuel_consumption = fuel_consumption 33 | self.fuel_quantity = fuel_quantity 34 | self.__air_conditioners_consumptions = 1.6 35 | self.__fuel_tank_leak = 0.95 36 | 37 | def drive(self, distance): 38 | consumption = distance * (self.fuel_consumption + self.__air_conditioners_consumptions) 39 | if consumption <= self.fuel_quantity: 40 | self.fuel_quantity -= consumption 41 | 42 | def refuel(self, fuel): 43 | self.fuel_quantity += fuel * self.__fuel_tank_leak 44 | 45 | 46 | car = Car(20, 5) 47 | car.drive(3) 48 | print(car.fuel_quantity) 49 | car.refuel(10) 50 | print(car.fuel_quantity) 51 | 52 | 53 | truck = Truck(100, 15) 54 | truck.drive(5) 55 | print(truck.fuel_quantity) 56 | truck.refuel(50) 57 | print(truck.fuel_quantity) -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/2_groups.py: -------------------------------------------------------------------------------- 1 | class Person: 2 | def __init__(self, name: str, surname: str): 3 | self.surname = surname 4 | self.name = name 5 | 6 | def __add__(self, obj): 7 | return Person(self.name, obj.surname) 8 | 9 | def __repr__(self): 10 | return f"{self.name} {self.surname}" 11 | 12 | 13 | class Group: 14 | def __init__(self, name:str, people: list): 15 | self.people = people 16 | self.name = name 17 | 18 | def __len__(self): 19 | return len(self.people) 20 | 21 | def __add__(self, obj): 22 | return Group(f"{self.name} {obj.name}", self.people + obj.people) 23 | 24 | def __getitem__(self, index): 25 | return f"Person {index}: {str(self.people[index])}" 26 | 27 | def __repr__(self): 28 | return f"Group {self.name} with members {', '.join(str(x) for x in self.people)}" 29 | 30 | 31 | aaa = [1,2,3,4] 32 | 33 | for x in aaa: 34 | 35 | 36 | 37 | 38 | p0 = Person('Aliko', 'Dangote') 39 | p1 = Person('Bill', 'Gates') 40 | 41 | p3 = p0 + p1 42 | print(p3.name) 43 | print(p3.surname) 44 | p2 = Person('Warren', 'Buffet') 45 | p3 = Person('Elon', 'Musk') 46 | p4 = p2 + p3 47 | 48 | 49 | 50 | first_group = Group('__VIP__', [p0, p1, p2]) 51 | second_group = Group('Special', [p3, p4]) 52 | third_group = first_group + second_group 53 | 54 | # print(len(first_group)) 55 | # print(second_group) 56 | # print(third_group[0]) 57 | 58 | # for person in third_group: 59 | # print(person) 60 | 61 | 62 | for person in first_group: 63 | print(person) -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/3_account.py: -------------------------------------------------------------------------------- 1 | class Account: 2 | 3 | def __init__(self, owner: str, amount: int = 0): 4 | self.owner = owner 5 | self.amount = amount 6 | self._transactions = [] 7 | 8 | def handle_transaction(self, transaction_amount): 9 | if self.balance + transaction_amount < 0: 10 | raise ValueError("sorry cannot go in debt!") 11 | 12 | self._transactions.append(transaction_amount) 13 | return f"New balance: {self.balance}" 14 | 15 | def add_transaction(self, amount): 16 | if not isinstance(amount, int): 17 | raise ValueError("please use int for amount") 18 | self.handle_transaction(amount) 19 | 20 | @property 21 | def balance(self): 22 | return self.amount + sum(self._transactions) 23 | 24 | def __str__(self): 25 | return f"Account of {self.owner} with starting amount: {self.amount}" 26 | 27 | def __repr__(self): 28 | return f"Account({self.owner}, {self.amount})" 29 | 30 | def __len__(self): 31 | return len(self._transactions) 32 | 33 | def __getitem__(self, index): 34 | return self._transactions[index] 35 | 36 | def __reversed__(self): 37 | return self._transactions[::-1] 38 | 39 | def __lt__(self, obj): 40 | return self.balance < obj.balance 41 | 42 | def __le__(self, obj): 43 | return self.balance <= obj.balance 44 | 45 | def __eq__(self, obj): 46 | return self.balance == obj.balance 47 | 48 | def __ne__(self, obj): 49 | return self.balance != obj.balance 50 | 51 | def __gt__(self, obj): 52 | return self.balance > obj.balance 53 | 54 | def __ge__(self, obj): 55 | return self.balance >= obj.balance 56 | 57 | def __add__(self, obj): 58 | concatenate_two_accounts = Account(f"{self.owner}&{obj.owner}", self.amount + obj.amount) 59 | concatenate_two_accounts._transactions = self._transactions + obj._transactions 60 | return concatenate_two_accounts 61 | 62 | 63 | acc = Account('bob', 10) 64 | acc2 = Account('john') 65 | print(acc) 66 | print(repr(acc)) 67 | acc.add_transaction(20) 68 | acc.add_transaction(-20) 69 | acc.add_transaction(30) 70 | print(acc.balance) 71 | print(len(acc)) 72 | for transaction in acc: 73 | print(transaction) 74 | print(acc[1]) 75 | print(list(reversed(acc))) 76 | acc2.add_transaction(10) 77 | acc2.add_transaction(60) 78 | print(acc > acc2) 79 | print(acc >= acc2) 80 | print(acc < acc2) 81 | print(acc <= acc2) 82 | print(acc == acc2) 83 | print(acc != acc2) 84 | acc3 = acc + acc2 85 | print(acc3) 86 | print(acc3._transactions) 87 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_4_wild_farm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_4_wild_farm/__init__.py -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_4_wild_farm/animals/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_4_wild_farm/animals/__init__.py -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_4_wild_farm/animals/animal.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | from project.food import Food 3 | 4 | 5 | class Animal(ABC): 6 | data_dic = { 7 | "Hen": {"food": ["Vegetable", "Fruit", "Meat", "Seed"], "weight increase": 0.35}, 8 | "Owl": {"food": ["Meat"], "weight increase": 0.25}, 9 | "Mouse": {"food": ["Vegetable", "Fruit"], "weight increase": 0.10}, 10 | "Cat": {"food": ["Vegetable", "Meat"], "weight increase": 0.30}, 11 | "Dog": {"food": ["Meat"], "weight increase": 0.40}, 12 | "Tiger": {"food": ["Meat"], "weight increase": 1.00} 13 | } 14 | 15 | def __init__(self, name: str, weight: float): 16 | self.name = name 17 | self.weight = weight 18 | self.food_eaten = 0 19 | 20 | @abstractmethod 21 | def make_sound(self): 22 | pass 23 | 24 | def feed(self, food: Food): 25 | animal_type = self.__class__.__name__ 26 | food_type = food.__class__.__name__ 27 | if food_type not in Animal.data_dic[animal_type]["food"]: 28 | return f"{animal_type} does not eat {food_type}!" 29 | self.weight += food.quantity * Animal.data_dic[animal_type]["weight increase"] 30 | self.food_eaten += food.quantity 31 | 32 | 33 | class Bird(Animal, ABC): 34 | def __init__(self, name, weight: float, wing_size: float): 35 | super().__init__(name, weight) 36 | self.wing_size = wing_size 37 | 38 | def __repr__(self): 39 | return f"{self.__class__.__name__} [{self.name}, {self.wing_size}, {self.weight}, {self.food_eaten}]" 40 | 41 | 42 | class Mammal(Animal, ABC): 43 | def __init__(self, name, weight: float, living_region: str): 44 | super().__init__(name, weight) 45 | self.living_region = living_region 46 | 47 | def __repr__(self): 48 | return f"{self.__class__.__name__} [{self.name}, {self.weight}, {self.living_region}, {self.food_eaten}]" 49 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_4_wild_farm/animals/birds.py: -------------------------------------------------------------------------------- 1 | from project.animals.animal import Bird 2 | 3 | 4 | class Owl(Bird): 5 | 6 | def __init__(self, name, weight: float, wing_size: float): 7 | super().__init__(name, weight, wing_size) 8 | 9 | def make_sound(self): 10 | return "Hoot Hoot" 11 | 12 | 13 | class Hen(Bird): 14 | def __init__(self, name, weight: float, wing_size: float): 15 | super().__init__(name, weight, wing_size) 16 | 17 | def make_sound(self): 18 | return "Cluck" 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_4_wild_farm/animals/mammals.py: -------------------------------------------------------------------------------- 1 | from project.animals.animal import Mammal 2 | 3 | 4 | class Mouse(Mammal): 5 | def __init__(self, name, weight: float, living_region: str): 6 | super().__init__(name, weight, living_region) 7 | 8 | def make_sound(self): 9 | return "Squeak" 10 | 11 | 12 | class Dog(Mammal): 13 | def __init__(self, name, weight: float, living_region: str): 14 | super().__init__(name, weight, living_region) 15 | 16 | def make_sound(self): 17 | return "Woof!" 18 | 19 | 20 | class Cat(Mammal): 21 | def __init__(self, name, weight: float, living_region: str): 22 | super().__init__(name, weight, living_region) 23 | 24 | def make_sound(self): 25 | return "Meow" 26 | 27 | 28 | class Tiger(Mammal): 29 | def __init__(self, name, weight: float, living_region: str): 30 | super().__init__(name, weight, living_region) 31 | 32 | def make_sound(self): 33 | return "ROAR!!!" 34 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_4_wild_farm/food.py: -------------------------------------------------------------------------------- 1 | from abc import ABC 2 | 3 | 4 | class Food(ABC): 5 | def __init__(self, quantity: int): 6 | self.quantity = quantity 7 | 8 | 9 | class Vegetable(Food): 10 | def __init__(self, quantity: int): 11 | super().__init__(quantity) 12 | 13 | 14 | class Fruit(Food): 15 | def __init__(self, quantity: int): 16 | super().__init__(quantity) 17 | 18 | 19 | class Meat(Food): 20 | def __init__(self, quantity: int): 21 | super().__init__(quantity) 22 | 23 | 24 | class Seed(Food): 25 | def __init__(self, quantity: int): 26 | super().__init__(quantity) 27 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_5_animals/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_5_animals/__init__.py -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_5_animals/animal.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class Animal(ABC): 5 | def __init__(self, name: str, age: int, gender: str): 6 | self.age = age 7 | self.name = name 8 | self.gender = gender 9 | 10 | @abstractmethod 11 | def make_sound(self): 12 | pass 13 | 14 | @abstractmethod 15 | def __repr__(self): 16 | pass -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_5_animals/cat.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | 4 | class Cat(Animal): 5 | def __init__(self, name: str, age: int, gender: str): 6 | super().__init__(name, age, gender) 7 | 8 | def make_sound(self): 9 | return "Meow meow!" 10 | 11 | def __repr__(self): 12 | return f"This is {self.name}. {self.name} is a {self.age} year old {self.gender} {self.__class__.__name__}" 13 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_5_animals/dog.py: -------------------------------------------------------------------------------- 1 | from project.animal import Animal 2 | 3 | 4 | class Dog(Animal): 5 | def __init__(self, name: str, age: int, gender: str): 6 | super().__init__(name, age, gender) 7 | 8 | def make_sound(self): 9 | return "Woof!" 10 | 11 | def __repr__(self): 12 | return f"This is {self.name}. {self.name} is a {self.age} year old {self.gender} {self.__class__.__name__}" -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_5_animals/kitten.py: -------------------------------------------------------------------------------- 1 | from project.cat import Cat 2 | 3 | 4 | class Kitten(Cat): 5 | def __init__(self, name: str, age: int, gender: str = "Female"): 6 | super().__init__(name, age, gender) 7 | self.gender = gender 8 | 9 | def make_sound(self): 10 | return "Meow" 11 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_5_animals/tomcat.py: -------------------------------------------------------------------------------- 1 | from project.cat import Cat 2 | 3 | 4 | class Tomcat(Cat): 5 | def __init__(self, name: str, age: int, gender: str ="Male"): 6 | super().__init__(name, age, gender) 7 | self.gender = gender 8 | 9 | def make_sound(self): 10 | return "Hiss" 11 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/__init__.py -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/f1_season_app.py: -------------------------------------------------------------------------------- 1 | from project.formula_teams.mercedes_team import MercedesTeam 2 | from project.formula_teams.red_bull_team import RedBullTeam 3 | 4 | 5 | class F1SeasonApp: 6 | 7 | def __init__(self): 8 | self.red_bull_team = None 9 | self.mercedes_team = None 10 | 11 | def register_team_for_season(self, team_name: str, budget: int): 12 | if "Red Bull" != team_name != "Mercedes": 13 | raise ValueError("Invalid team name!") 14 | 15 | if "Red Bull" == team_name: 16 | self.red_bull_team = RedBullTeam(budget) 17 | 18 | elif "Mercedes" == team_name: 19 | self.mercedes_team = MercedesTeam(budget) 20 | 21 | return f"{team_name} has joined the new F1 season." 22 | 23 | def new_race_results(self, race_name: str, red_bull_pos: int, mercedes_pos: int): 24 | if self.mercedes_team is None or self.red_bull_team is None: 25 | raise Exception("Not all teams have registered for the season.") 26 | 27 | output = f"Red Bull: {self.red_bull_team.calculate_revenue_after_race(red_bull_pos)}. " 28 | output += f"Mercedes: {self.mercedes_team.calculate_revenue_after_race(mercedes_pos)}. " 29 | team_display = "Red Bull" 30 | if mercedes_pos < red_bull_pos: 31 | team_display = "Mercedes" 32 | 33 | output += f"{team_display} is ahead at the {race_name} race." 34 | return output 35 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/formula_teams/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/formula_teams/__init__.py -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/formula_teams/formula_team.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class FormulaTeam(ABC): 5 | 6 | @abstractmethod 7 | def __init__(self, budget: int): 8 | self.budget = budget 9 | 10 | @property 11 | def budget(self): 12 | return self.__budget 13 | 14 | @budget.setter 15 | def budget(self, value): 16 | if value < 1_000_000: 17 | raise ValueError("F1 is an expensive sport, find more sponsors!") 18 | self.__budget = value 19 | 20 | def calculate_revenue_after_race(self, race_pos: int): 21 | revenue = self.sponsors.get(race_pos, 0) - self.expenses 22 | self.budget += revenue 23 | return f"The revenue after the race is {revenue}$. Current budget {self.budget}$" 24 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/formula_teams/mercedes_team.py: -------------------------------------------------------------------------------- 1 | from project.formula_teams.formula_team import FormulaTeam 2 | 3 | 4 | class MercedesTeam(FormulaTeam): 5 | 6 | def __init__(self, budget: int): 7 | self.budget = budget 8 | self.sponsors = { 9 | 1: 1_100_000, 10 | 2: 600_000, 11 | 3: 600_000, 12 | 4: 100_000, 13 | 5: 100_000, 14 | 6: 50_000, 15 | 7: 50_000, 16 | } 17 | self.expenses = 200_000 18 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/formula_teams/red_bull_team.py: -------------------------------------------------------------------------------- 1 | from project.formula_teams.formula_team import FormulaTeam 2 | 3 | 4 | class RedBullTeam(FormulaTeam): 5 | 6 | def __init__(self, budget: int): 7 | self.budget = budget 8 | self.sponsors = { 9 | 1: 1_520_000, 10 | 2: 820_000, 11 | 3: 20_000, 12 | 4: 20_000, 13 | 5: 20_000, 14 | 6: 20_000, 15 | 7: 20_000, 16 | 8: 20_000, 17 | 9: 10_000, 18 | 10: 10_000 19 | } 20 | self.expenses = 250_000 21 | 22 | 23 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/ver 2.0/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/ver 2.0/__init__.py -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/ver 2.0/f1_season_app.py: -------------------------------------------------------------------------------- 1 | from project.formula_teams.formula_team import FormulaTeam 2 | from project.formula_teams.mercedes_team import MercedesTeam 3 | from project.formula_teams.red_bull_team import RedBullTeam 4 | from project.validation.validation import Validation 5 | 6 | 7 | class F1SeasonApp: 8 | 9 | def __init__(self): 10 | self.red_bull_team = None 11 | self.mercedes_team = None 12 | 13 | @property 14 | def teams(self): 15 | return [self.red_bull_team, self.mercedes_team] 16 | 17 | def register_team_for_season(self, team_name: str, budget: int): 18 | Validation.item_duplicate(team_name, FormulaTeam.teams, "Invalid team name!") 19 | 20 | if team_name == "Red Bull": 21 | self.red_bull_team = RedBullTeam(budget) 22 | elif team_name == "Mercedes": 23 | self.mercedes_team = MercedesTeam(budget) 24 | 25 | return f"{team_name} has joined the new F1 season." 26 | 27 | def new_race_results(self, race_name: str, red_bull_pos: int, mercedes_pos: int): 28 | Validation.team_registered(self.teams, "Not all teams have registered for the season.") 29 | 30 | winner = self.red_bull_team.name if red_bull_pos < mercedes_pos else self.mercedes_team.name 31 | output = [] 32 | 33 | for pos, team in zip([red_bull_pos, mercedes_pos], self.teams): 34 | output.append(f"{team.name}: {team.calculate_revenue_after_race(pos)}. ") 35 | output.append(f"{winner} is ahead at the {race_name} race.") 36 | 37 | return "".join(output) 38 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/ver 2.0/formula_teams/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/ver 2.0/formula_teams/__init__.py -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/ver 2.0/formula_teams/formula_team.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | from project.validation.validation import Validation 4 | 5 | 6 | class FormulaTeam(ABC): 7 | teams = { 8 | "Red Bull": { 9 | 1: 1_520_000, 10 | 2: 820_000, 11 | 3: 20_000, 12 | 4: 20_000, 13 | 5: 20_000, 14 | 6: 20_000, 15 | 7: 20_000, 16 | 8: 20_000, 17 | 9: 10_000, 18 | 10: 10_000, 19 | }, 20 | "Mercedes": { 21 | 1: 1_100_000, 22 | 2: 600_000, 23 | 3: 600_000, 24 | 4: 100_000, 25 | 5: 100_000, 26 | 6: 50_000, 27 | 7: 50_000, 28 | } 29 | } 30 | 31 | def __init__(self, budget: int) -> object: 32 | self.budget = budget 33 | 34 | @property 35 | def budget(self) -> int: 36 | return self.__budget 37 | 38 | @budget.setter 39 | def budget(self, value): 40 | Validation.less_than(value, 1_000_000, "F1 is an expensive sport, find more sponsors!") 41 | self.__budget = value 42 | 43 | @abstractmethod 44 | def calculate_revenue_after_race(self, race_pos: int): 45 | pass 46 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/ver 2.0/formula_teams/mercedes_team.py: -------------------------------------------------------------------------------- 1 | from project.formula_teams.formula_team import FormulaTeam 2 | 3 | 4 | class MercedesTeam(FormulaTeam): 5 | 6 | def __init__(self, budget: int) -> object: 7 | super().__init__(budget) 8 | 9 | @property 10 | def expenses(self): 11 | return 200_000 12 | 13 | @property 14 | def name(self): 15 | return "Mercedes" 16 | 17 | def calculate_revenue_after_race(self, race_pos: int): 18 | revenue = self.teams[self.name].get(race_pos, 0) - self.expenses 19 | self.budget += revenue 20 | 21 | return f"The revenue after the race is {revenue}$. Current budget {self.budget}$" 22 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/ver 2.0/formula_teams/red_bull_team.py: -------------------------------------------------------------------------------- 1 | from project.formula_teams.formula_team import FormulaTeam 2 | 3 | 4 | class RedBullTeam(FormulaTeam): 5 | 6 | def __init__(self, budget: int) -> object: 7 | super().__init__(budget) 8 | 9 | @property 10 | def expenses(self): 11 | return 250_000 12 | 13 | @property 14 | def name(self): 15 | return "Red Bull" 16 | 17 | def calculate_revenue_after_race(self, race_pos: int): 18 | revenue = self.teams[self.name].get(race_pos, 0) - self.expenses 19 | self.budget += revenue 20 | 21 | return f"The revenue after the race is {revenue}$. Current budget {self.budget}$" 22 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/ver 2.0/validation/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/ver 2.0/validation/__init__.py -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Exercise/project_6_formula_1_manager/ver 2.0/validation/validation.py: -------------------------------------------------------------------------------- 1 | class Validation: 2 | 3 | @staticmethod 4 | def less_than(num: int, target_num: int, message: str): 5 | if num < target_num: 6 | raise ValueError(message) 7 | 8 | @staticmethod 9 | def item_duplicate(item: str, collection: dict, message: str): 10 | if item not in collection: 11 | raise ValueError(message) 12 | 13 | @staticmethod 14 | def team_registered(teams: dict, message: str): 15 | if any(t is None for t in teams): 16 | raise Exception(message) 17 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Lab/2_image_area.py: -------------------------------------------------------------------------------- 1 | class ImageArea: 2 | 3 | def __init__(self, width, height): 4 | self.height = height 5 | self.width = width 6 | 7 | def get_area(self): 8 | return self.height * self.width 9 | 10 | def __lt__(self, obj): 11 | return self.get_area() < obj.get_area() 12 | 13 | def __le__(self, obj): 14 | return self.get_area() <= obj.get_area() 15 | 16 | def __eq__(self, obj): 17 | return self.get_area() == obj.get_area() 18 | 19 | def __ne__(self, obj): 20 | return self.get_area() != obj.get_area() 21 | 22 | def __gt__(self, obj): 23 | return self.get_area() > obj.get_area() 24 | 25 | def __ge__(self, obj): 26 | return self.get_area() >= obj.get_area() 27 | 28 | # check https://docs.python.org/3/reference/datamodel.html 29 | # for for info -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Lab/3_playing.py: -------------------------------------------------------------------------------- 1 | def start_playing(obj): 2 | return obj.play() 3 | 4 | -------------------------------------------------------------------------------- /06. Polymorphism and Abstraction/06. Polymorphism and Abstraction - Lab/4_shapes.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | from math import pi 3 | 4 | 5 | class Shape(ABC): 6 | 7 | @abstractmethod 8 | def calculate_area(self): 9 | pass 10 | 11 | @abstractmethod 12 | def calculate_perimeter(self): 13 | pass 14 | 15 | 16 | class Circle(Shape): 17 | def __init__(self, radius): 18 | self.__radius = radius 19 | 20 | def calculate_area(self): 21 | return pi * self.__radius ** 2 22 | 23 | def calculate_perimeter(self): 24 | return self.__radius * pi * 2 25 | 26 | 27 | class Rectangle(Shape): 28 | def __init__(self, height, width): 29 | self.__width = width 30 | self.__height = height 31 | 32 | def calculate_area(self): 33 | return self.__width * self.__height 34 | 35 | def calculate_perimeter(self): 36 | return (self.__width + self.__height)*2 37 | 38 | -------------------------------------------------------------------------------- /07. SOLID/07. SOLID - Exercise/1_workers.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class BaseWorker(ABC): 5 | @abstractmethod 6 | def work(self): 7 | ... 8 | 9 | 10 | class Worker(BaseWorker): 11 | def work(self): 12 | print("I'm working!!") 13 | 14 | 15 | class SuperWorker(BaseWorker): 16 | def work(self): 17 | print("I work very hard!!!") 18 | 19 | 20 | class LazyWorker(BaseWorker): 21 | def work(self): 22 | print("Uf, I dont want to work...") 23 | 24 | 25 | class Manager: 26 | def __init__(self): 27 | self.worker = None 28 | 29 | def set_worker(self, worker): 30 | if not isinstance(worker, BaseWorker): 31 | raise AssertionError(f'`worker` must be of type {BaseWorker}') 32 | 33 | self.worker = worker 34 | 35 | def manage(self): 36 | if self.worker is not None: 37 | self.worker.work() 38 | 39 | 40 | worker = Worker() 41 | manager = Manager() 42 | 43 | manager.set_worker(worker) 44 | manager.manage() 45 | 46 | super_worker = SuperWorker() 47 | lazy_worker = LazyWorker() 48 | try: 49 | manager.set_worker(super_worker) 50 | manager.manage() 51 | 52 | manager.set_worker(lazy_worker) 53 | manager.manage() 54 | except AssertionError: 55 | print("manager fails to support super_worker....") -------------------------------------------------------------------------------- /07. SOLID/07. SOLID - Exercise/2_workers_updated.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | import time 3 | 4 | 5 | class Workable(ABC): 6 | @abstractmethod 7 | def work(self): 8 | ... 9 | 10 | 11 | class Eatable(ABC): 12 | @abstractmethod 13 | def eat(self): 14 | ... 15 | 16 | 17 | class Worker(Workable, Eatable): 18 | 19 | def work(self): 20 | print("I'm normal worker. I'm working.") 21 | 22 | def eat(self): 23 | print("Lunch break....(5 secs)") 24 | time.sleep(5) 25 | 26 | 27 | class SuperWorker(Workable, Eatable): 28 | 29 | def work(self): 30 | print("I'm super worker. I work very hard!") 31 | 32 | def eat(self): 33 | print("Lunch break....(3 secs)") 34 | time.sleep(3) 35 | 36 | 37 | class Robot(Workable): 38 | def work(self): 39 | print("I'm a robot. I'm working....") 40 | 41 | 42 | class BaseManager(ABC): 43 | def __init__(self): 44 | self.worker = None 45 | 46 | @abstractmethod 47 | def set_worker(self, worker): 48 | pass 49 | 50 | 51 | class WorkManager(BaseManager): 52 | def set_worker(self, worker): 53 | assert isinstance(worker, Workable), f"`worker` must be of type {Workable}" 54 | 55 | self.worker = worker 56 | 57 | def manage(self): 58 | self.worker.work() 59 | 60 | 61 | class BreakManager(BaseManager): 62 | def set_worker(self, worker): 63 | assert isinstance(worker, Eatable), f"`worker` must be of type {Eatable}" 64 | 65 | self.worker = worker 66 | 67 | def lunch_break(self): 68 | self.worker.eat() 69 | 70 | 71 | work_manager = WorkManager() 72 | break_manager = BreakManager() 73 | 74 | worker = Worker() 75 | work_manager.set_worker(worker) 76 | break_manager.set_worker(worker) 77 | work_manager.manage() 78 | break_manager.lunch_break() 79 | 80 | super_worker = SuperWorker() 81 | work_manager.set_worker(super_worker) 82 | break_manager.set_worker(super_worker) 83 | work_manager.manage() 84 | break_manager.lunch_break() 85 | 86 | robot = Robot() 87 | work_manager.set_worker(robot) 88 | work_manager.manage() 89 | 90 | break_manager.set_worker(robot) -------------------------------------------------------------------------------- /07. SOLID/07. SOLID - Exercise/3_prisoner.py: -------------------------------------------------------------------------------- 1 | class Person: 2 | def __init__(self, position): 3 | self.position = position 4 | 5 | 6 | class FreePerson(Person): 7 | def __init__(self, position): 8 | super().__init__(position) 9 | 10 | def walk_north(self, dist): 11 | self.position[1] += dist 12 | 13 | def walk_east(self, dist): 14 | self.position[0] += dist 15 | 16 | 17 | class Prisoner(Person): 18 | PRISON_LOCATION = [3, 3] 19 | 20 | def __init__(self): 21 | super().__init__(self.PRISON_LOCATION[::]) 22 | self.is_free = False 23 | 24 | 25 | prisoner = Prisoner() 26 | print("The prisoner trying to walk to north by 10 and east by -3.") 27 | 28 | try: 29 | prisoner.walk_north(10) 30 | prisoner.walk_east(-3) 31 | except: 32 | pass 33 | 34 | print(f"The location of the prison: {prisoner.PRISON_LOCATION}") 35 | print(f"The current position of the prisoner: {prisoner.position}") -------------------------------------------------------------------------------- /07. SOLID/07. SOLID - Exercise/4_shapes.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class Shape(ABC): 5 | @abstractmethod 6 | def calc_area(self): 7 | pass 8 | 9 | 10 | class Rectangle(Shape): 11 | def __init__(self, width, height): 12 | self.width = width 13 | self.height = height 14 | 15 | def calc_area(self): 16 | return self.width * self.height 17 | 18 | 19 | class Square(Shape): 20 | def __init__(self, side): 21 | self.side = side 22 | 23 | def calc_area(self): 24 | return self.side * self.side 25 | 26 | 27 | class AreaCalculator: 28 | def __init__(self, shapes): 29 | assert isinstance(shapes, list), "`shapes` should be of type `list`." 30 | self.shapes = shapes 31 | 32 | @property 33 | def total_area(self): 34 | return sum(shape.calc_area() for shape in self.shapes) 35 | 36 | 37 | shapes = [Rectangle(2, 3), Rectangle(1, 6), Square(3)] 38 | calculator = AreaCalculator(shapes) 39 | print("The total area is: ", calculator.total_area) 40 | -------------------------------------------------------------------------------- /07. SOLID/07. SOLID - Exercise/5_emails.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class IContent(ABC): 5 | def __init__(self, text): 6 | self.text = text 7 | 8 | @abstractmethod 9 | def format(self): 10 | ... 11 | 12 | 13 | class MyContent(IContent): 14 | def format(self): 15 | return f"{self.text}" 16 | 17 | 18 | class EncryptedContent(IContent): 19 | def format(self): 20 | result = "" 21 | for letter in self.text: 22 | result += chr(ord(letter) + 5) 23 | return result 24 | 25 | 26 | class MaskedContent(IContent): 27 | def format(self): 28 | return '*' * len(self.text) 29 | 30 | 31 | class IEmail(ABC): 32 | @abstractmethod 33 | def set_sender(self, sender): 34 | ... 35 | 36 | @abstractmethod 37 | def set_receiver(self, receiver): 38 | ... 39 | 40 | @abstractmethod 41 | def set_content(self, content): 42 | ... 43 | 44 | 45 | class Email(IEmail): 46 | def __init__(self, protocol): 47 | self.protocol = protocol 48 | self.__sender = None 49 | self.__receiver = None 50 | self.__content = None 51 | 52 | def set_sender(self, sender): 53 | self.__sender = sender 54 | 55 | def set_receiver(self, receiver): 56 | self.__receiver = receiver 57 | 58 | def set_content(self, content): 59 | self.__content = content 60 | 61 | def __repr__(self): 62 | template = "Sender: I`m {sender}\nReceiver: I`m {receiver}\nContent:\n{content}" 63 | 64 | return template.format(sender=self.__sender, receiver=self.__receiver, content=self.__content.format()) 65 | 66 | 67 | email = Email('IM') 68 | 69 | email.set_sender('qmal') 70 | 71 | email.set_receiver('james') 72 | 73 | content = MyContent('Hello, there!') 74 | 75 | email.set_content(content) 76 | 77 | print(email) -------------------------------------------------------------------------------- /07. SOLID/07. SOLID - Lab/1_books.py: -------------------------------------------------------------------------------- 1 | class Book: 2 | def __init__(self, title, author, pages): 3 | self.title = title 4 | self.author = author 5 | self.page = pages 6 | 7 | 8 | class Library: 9 | def __init__(self, location): 10 | self.location = location 11 | self.books = [] 12 | 13 | def find_book(self, title): 14 | for book in self.books: 15 | if book.title == title: 16 | return book 17 | 18 | return "No such book" 19 | 20 | def add_book(self, book): 21 | self.books.append(book) 22 | 23 | 24 | class Person: 25 | def __init__(self, name): 26 | self.name = name 27 | 28 | 29 | class Reader(Person): 30 | def __init__(self, name, current_book): 31 | super().__init__(name) 32 | self.current_book = current_book 33 | self.current_page = None 34 | 35 | def turn_page(self): 36 | if self.current_page: 37 | self.current_page += 1 38 | return 39 | self.current_page = 1 -------------------------------------------------------------------------------- /07. SOLID/07. SOLID - Lab/2_animals.py: -------------------------------------------------------------------------------- 1 | from abc import ABC, abstractmethod 2 | 3 | 4 | class Animal(ABC): 5 | def __init__(self): 6 | ... 7 | 8 | @abstractmethod 9 | def make_sound(self): 10 | ... 11 | 12 | 13 | class Cat(Animal): 14 | 15 | def make_sound(self): 16 | return "Meow" 17 | 18 | 19 | class Dog(Animal): 20 | 21 | def make_sound(self): 22 | return "Woof-woof" 23 | 24 | 25 | animals = [Cat(), Dog()] 26 | for animal in animals: 27 | print(animal.make_sound()) -------------------------------------------------------------------------------- /07. SOLID/07. SOLID - Lab/3_ducks.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ip681/python-oop/de5d9b392a8e0851c6580f5bd81a7fe9dcc6d59a/07. SOLID/07. SOLID - Lab/3_ducks.py -------------------------------------------------------------------------------- /07. SOLID/07. SOLID - Lab/4_entertainment_system.py: -------------------------------------------------------------------------------- 1 | class POWERConnector: 2 | def connect_device_to_power_outlet(self, device): 3 | ... 4 | 5 | 6 | class HDMIConnector: 7 | def connect_to_device_via_hdmi_cable(self, device): 8 | ... 9 | 10 | 11 | class RCAConnector: 12 | def connect_to_device_via_rca_cable(self, device): 13 | ... 14 | 15 | 16 | class ETHERNETConnector: 17 | def connect_to_device_via_ethernet_cable(self, device): 18 | ... 19 | 20 | 21 | class Television(RCAConnector, HDMIConnector, POWERConnector): 22 | def connect_to_dvd(self, dvd_player): 23 | self.connect_to_device_via_rca_cable(dvd_player) 24 | 25 | def connect_to_game_console(self, game_console): 26 | self.connect_to_device_via_hdmi_cable(game_console) 27 | 28 | def plug_in_power(self): 29 | self.connect_device_to_power_outlet(self) 30 | 31 | 32 | class dvd_player(HDMIConnector, POWERConnector): 33 | def connect_to_tv(self, television): 34 | self.connect_to_device_via_hdmi_cable(television) 35 | 36 | def plug_in_power(self): 37 | self.connect_device_to_power_outlet(self) 38 | 39 | 40 | class GameConsole(HDMIConnector, ETHERNETConnector, POWERConnector): 41 | def connect_to_tv(self, television): 42 | self.connect_to_device_via_hdmi_cable(television) 43 | 44 | def connect_to_router(self, router): 45 | self.connect_to_device_via_ethernet_cable(router) 46 | 47 | def plug_in_power(self): 48 | self.connect_device_to_power_outlet(self) 49 | 50 | 51 | class Router(ETHERNETConnector, POWERConnector): 52 | def connect_to_tv(self, television): 53 | self.connect_to_device_via_ethernet_cable(television) 54 | 55 | def connect_to_game_console(self, game_console): 56 | self.connect_to_device_via_ethernet_cable(game_console) 57 | 58 | def plug_in_power(self): 59 | self.connect_device_to_power_outlet(self) 60 | -------------------------------------------------------------------------------- /07. SOLID/07. SOLID - Lab/5_print_books.py: -------------------------------------------------------------------------------- 1 | class Book: 2 | def __init__(self, content): 3 | self.content = content 4 | 5 | 6 | class Formatter: 7 | def format(self, book): 8 | return book.content 9 | 10 | 11 | class Printer: 12 | def get_book(self, book, formatter): 13 | return formatter.format(book) 14 | 15 | 16 | b = Book("book") 17 | f = Formatter() 18 | p = Printer() 19 | 20 | print(p.get_book(b, f)) 21 | -------------------------------------------------------------------------------- /08. Iterators and Generators/08. Iterators and Generators - Exercise/1_take_skip.py: -------------------------------------------------------------------------------- 1 | class take_skip: 2 | def __init__(self,step,count): 3 | self.step = step 4 | self.count = count 5 | self.number=0 6 | self.counter=0 7 | def __iter__(self): 8 | return self 9 | 10 | def __next__(self): 11 | while self.counter=1: 13 | self.number+=self.step 14 | self.counter+=1 15 | return self.number 16 | else: 17 | self.counter += 1 18 | return self.number 19 | 20 | raise StopIteration -------------------------------------------------------------------------------- /08. Iterators and Generators/08. Iterators and Generators - Exercise/2_dictionary_iterator.py: -------------------------------------------------------------------------------- 1 | class dictionary_iter: 2 | 3 | def __init__(self, dict_: dict): 4 | self.items = list(dict_.items()) 5 | self.iters = len(dict_) 6 | self.start = 0 7 | 8 | def __iter__(self): 9 | return self 10 | 11 | def __next__(self): 12 | if self.start >= self.iters: 13 | raise StopIteration() 14 | output = self.items[self.start] 15 | self.start += 1 16 | return output 17 | 18 | -------------------------------------------------------------------------------- /08. Iterators and Generators/08. Iterators and Generators - Exercise/3_countdown_ierator.py: -------------------------------------------------------------------------------- 1 | class countdown_iterator: 2 | def __init__(self, counter): 3 | self.counter = counter 4 | 5 | def __iter__(self): 6 | return self 7 | 8 | def __next__(self): 9 | if self.counter == -1: 10 | raise StopIteration() 11 | 12 | output = self.counter 13 | self.counter -= 1 14 | return output 15 | 16 | -------------------------------------------------------------------------------- /08. Iterators and Generators/08. Iterators and Generators - Exercise/4_sequence_repeat.py: -------------------------------------------------------------------------------- 1 | class sequence_repeat: 2 | def __init__(self, sting_to_repeat: str, times_to_repeat: int): 3 | self.sting_to_repeat = sting_to_repeat 4 | self.times_to_repeat = times_to_repeat 5 | self.iterations = 0 6 | 7 | def __iter__(self): 8 | return self 9 | 10 | def __next__(self): 11 | if self.iterations == self.times_to_repeat: 12 | raise StopIteration() 13 | index = self.sting_to_repeat[self.iterations % len(self.sting_to_repeat)] 14 | self.iterations += 1 15 | return index 16 | -------------------------------------------------------------------------------- /08. Iterators and Generators/08. Iterators and Generators - Exercise/5_take_halves.py: -------------------------------------------------------------------------------- 1 | def solution(): 2 | def integers(): 3 | num = 1 4 | while True: 5 | yield num 6 | num += 1 7 | 8 | def halves(): 9 | for x in integers(): 10 | yield x / 2 11 | 12 | def take(n, num): 13 | return [next(num) for _ in range(n)] 14 | 15 | return take, halves, integers 16 | 17 | -------------------------------------------------------------------------------- /08. Iterators and Generators/08. Iterators and Generators - Exercise/6_fibonacci_generator.py: -------------------------------------------------------------------------------- 1 | def fibonacci(): 2 | last_num = 0 3 | current_num = 1 4 | 5 | yield last_num 6 | yield current_num 7 | 8 | while True: 9 | next_num = last_num + current_num 10 | yield next_num 11 | last_num, current_num = current_num, next_num 12 | 13 | 14 | -------------------------------------------------------------------------------- /08. Iterators and Generators/08. Iterators and Generators - Exercise/7_reader.py: -------------------------------------------------------------------------------- 1 | def read_next(*args): 2 | for item in args: 3 | for x in item: 4 | yield x 5 | 6 | 7 | for item in read_next('string', (2,), {'d': 1, 'i': 2, 'c': 3, 't': 4}): 8 | print(item, end='') -------------------------------------------------------------------------------- /08. Iterators and Generators/08. Iterators and Generators - Exercise/8_prime_nmbers.py: -------------------------------------------------------------------------------- 1 | def prime_checker(n): 2 | if n <= 1: 3 | return False 4 | for i in range(2, n): 5 | if n % i == 0: 6 | return False 7 | return True 8 | 9 | 10 | def get_primes(numbers): 11 | for num in numbers: 12 | if prime_checker(num): 13 | yield num 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /08. Iterators and Generators/08. Iterators and Generators - Exercise/9_possible_permutations.py: -------------------------------------------------------------------------------- 1 | from itertools import permutations 2 | 3 | 4 | def possible_permutations(numbers): 5 | output = permutations(numbers) 6 | 7 | for permutation in output: 8 | yield list(permutation) 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /08. Iterators and Generators/08. Iterators and Generators - Lab/1_custom_range.py: -------------------------------------------------------------------------------- 1 | class custom_range: 2 | def __init__(self, start, end, step=None): 3 | self.start = start 4 | self.end = end 5 | self.step = step 6 | self.counter = 0 7 | self.incrementator = 1 8 | 9 | if step and step < 0: 10 | self.start, self.end = self.end, self.start 11 | self.incrementator = -1 12 | 13 | def __iter__(self): 14 | return self 15 | 16 | def __next__(self): 17 | if self.incrementator < 0: 18 | if self.start >= self.end: 19 | temp = self.start 20 | self.start += self.incrementator 21 | return temp 22 | else: 23 | if self.start <= self.end: 24 | temp = self.start 25 | self.start += self.incrementator 26 | return temp 27 | raise StopIteration() -------------------------------------------------------------------------------- /08. Iterators and Generators/08. Iterators and Generators - Lab/2_reverse_iter.py: -------------------------------------------------------------------------------- 1 | class reverse_iter: 2 | def __init__(self, list_of_numbers: list): 3 | self.list_of_numbers = list_of_numbers 4 | self.index = len(list_of_numbers) - 1 5 | 6 | def __iter__(self): 7 | return self 8 | 9 | def __next__(self): 10 | if self.index >= 0: 11 | output = self.list_of_numbers[self.index] 12 | self.index -= 1 13 | return output 14 | else: 15 | raise StopIteration() 16 | 17 | 18 | 19 | 20 | # class reverse_iter: 21 | # def __init__(self, list_of_numbers: list): 22 | # self.list_of_numbers = list_of_numbers[::-1] 23 | # 24 | # def __iter__(self): 25 | # return self 26 | # 27 | # def __next__(self): 28 | # try: 29 | # return self.list_of_numbers.pop() 30 | # except IndexError: 31 | # raise StopIteration() 32 | -------------------------------------------------------------------------------- /08. Iterators and Generators/08. Iterators and Generators - Lab/3_vowels.py: -------------------------------------------------------------------------------- 1 | class vowels: 2 | def __init__(self, string: str): 3 | self.string = string 4 | self.start_index = 0 5 | self.end_index = len(string) 6 | self.vowels = ('a', 'e', 'i', 'o', 'u') 7 | 8 | def __iter__(self): 9 | return self 10 | 11 | def __next__(self): 12 | while self.start_index < self.end_index: 13 | output = self.string[self.start_index] 14 | self.start_index += 1 15 | 16 | if output.lower() in self.vowels: 17 | return output 18 | else: 19 | raise StopIteration() 20 | 21 | 22 | 23 | 24 | 25 | # 26 | # class vowels: 27 | # def __init__(self, string: str): 28 | # self.string = string 29 | # self.vowels = ('a', 'e', 'i', 'o', 'u') 30 | # 31 | # def __iter__(self): 32 | # return self 33 | # 34 | # def __next__(self): 35 | # while True: 36 | # try: 37 | # letter, self.string = self.string[0], self.string[1:] 38 | # if letter.lower() in self.vowels: 39 | # return letter 40 | # except IndexError: 41 | # raise StopIteration() 42 | # 43 | # 44 | # 45 | # 46 | # 47 | -------------------------------------------------------------------------------- /08. Iterators and Generators/08. Iterators and Generators - Lab/4_squares.py: -------------------------------------------------------------------------------- 1 | def squares(param): 2 | num = 1 3 | 4 | while num <= param: 5 | yield num * num 6 | num += 1 7 | 8 | 9 | -------------------------------------------------------------------------------- /08. Iterators and Generators/08. Iterators and Generators - Lab/5_generator_range.py: -------------------------------------------------------------------------------- 1 | def genrange(start_num, end_num): 2 | while start_num <= end_num: 3 | yield start_num 4 | start_num += 1 5 | 6 | 7 | -------------------------------------------------------------------------------- /08. Iterators and Generators/08. Iterators and Generators - Lab/6_reverse_string.py: -------------------------------------------------------------------------------- 1 | def reverse_text(param): 2 | while param: 3 | yield param[-1] 4 | param = param[:-1] 5 | 6 | -------------------------------------------------------------------------------- /09. Decorators/09. Decorators - Exercise/1_logged.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | 3 | 4 | def logged(func): 5 | @wraps(func) 6 | def wrapper(*args, **kwargs): 7 | return f"you called {func.__name__}{args}\nit returned {func(*args, **kwargs)}" 8 | 9 | return wrapper 10 | 11 | 12 | @logged 13 | def func(*args): 14 | return 3 + len(args) 15 | 16 | 17 | print(func(4, 4, 4)) 18 | 19 | 20 | @logged 21 | def sum_func(a, b): 22 | return a + b 23 | 24 | 25 | print(sum_func(1, 4)) 26 | -------------------------------------------------------------------------------- /09. Decorators/09. Decorators - Exercise/2_even_parameters.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | 3 | 4 | def even_parameters(func): 5 | def is_even_number(n): 6 | return n % 2 == 0 7 | 8 | @wraps(func) 9 | def wrapper(*args, **kwargs): 10 | for el in args: 11 | if isinstance(el, str) or not is_even_number(el): 12 | return "Please use only even numbers!" 13 | return func(*args) 14 | 15 | return wrapper 16 | 17 | 18 | @even_parameters 19 | def add(a, b): 20 | return a + b 21 | 22 | 23 | print(add(2, 4)) 24 | print(add("Peter", 1)) 25 | 26 | 27 | @even_parameters 28 | def multiply(*nums): 29 | result = 1 30 | for num in nums: 31 | result *= num 32 | return result 33 | 34 | 35 | print(multiply(2, 4, 6, 8)) 36 | print(multiply(2, 4, 9, 8)) 37 | -------------------------------------------------------------------------------- /09. Decorators/09. Decorators - Exercise/3_bold_italic_underline.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | 3 | 4 | def make_bold(func): 5 | @wraps(func) 6 | def wrapper(*args, **kwargs): 7 | return f"{func(*args, **kwargs)}" 8 | 9 | return wrapper 10 | 11 | 12 | def make_italic(func): 13 | @wraps(func) 14 | def wrapper(*args, **kwargs): 15 | return f"{func(*args, **kwargs)}" 16 | 17 | return wrapper 18 | 19 | 20 | def make_underline(func): 21 | @wraps(func) 22 | def wrapper(*args, **kwargs): 23 | return f"{func(*args, **kwargs)}" 24 | 25 | return wrapper 26 | 27 | 28 | @make_bold 29 | @make_italic 30 | @make_underline 31 | def greet(name): 32 | return f"Hello, {name}" 33 | 34 | 35 | print(greet("Peter")) 36 | -------------------------------------------------------------------------------- /09. Decorators/09. Decorators - Exercise/4_type_check.py: -------------------------------------------------------------------------------- 1 | def type_check(type): 2 | def decorator(func): 3 | def wrapper(*args): 4 | if not isinstance(*args, type): 5 | return "Bad Type" 6 | return func(*args) 7 | 8 | return wrapper 9 | 10 | return decorator 11 | 12 | 13 | @type_check(int) 14 | def times2(num): 15 | return num * 2 16 | 17 | 18 | print(times2(2)) 19 | print(times2('Not A Number')) 20 | 21 | 22 | @type_check(str) 23 | def first_letter(word): 24 | return word[0] 25 | 26 | 27 | print(first_letter('Hello World')) 28 | print(first_letter(['Not', 'A', 'String'])) 29 | -------------------------------------------------------------------------------- /09. Decorators/09. Decorators - Exercise/5_cache.py: -------------------------------------------------------------------------------- 1 | def cache(func): 2 | def wrapper(n): 3 | cache_key = n 4 | if cache_key not in wrapper.log: 5 | wrapper.log[cache_key] = func(n) 6 | return wrapper.log[cache_key] 7 | 8 | wrapper.log = {} 9 | return wrapper 10 | 11 | 12 | @cache 13 | def fibonacci(n): 14 | if n < 2: 15 | return n 16 | else: 17 | return fibonacci(n - 1) + fibonacci(n - 2) 18 | 19 | 20 | fibonacci(3) 21 | print(fibonacci.log) 22 | -------------------------------------------------------------------------------- /09. Decorators/09. Decorators - Exercise/6_html_tags.py: -------------------------------------------------------------------------------- 1 | def tags(tag): 2 | def decorator(func): 3 | def wrapper(*args, **kwargs): 4 | result = f"<{tag}>{func(*args, *kwargs)}" 5 | return result 6 | 7 | return wrapper 8 | 9 | return decorator 10 | 11 | 12 | @tags('g') 13 | def join_strings(*args): 14 | return "".join(args) 15 | 16 | 17 | print(join_strings("Hello", " you!")) 18 | -------------------------------------------------------------------------------- /09. Decorators/09. Decorators - Lab/1_number_increment.py: -------------------------------------------------------------------------------- 1 | def number_increment(numbers): 2 | def increase(): 3 | return [n + 1 for n in numbers] 4 | 5 | return increase() 6 | 7 | 8 | print(number_increment([1, 2, 3])) 9 | -------------------------------------------------------------------------------- /09. Decorators/09. Decorators - Lab/2_vowel_filter.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | 3 | 4 | def vowel_filter(func): 5 | VOWELS = ["a", "A", "e", "E", "i", "I", "o", "O", "u", "U", "y", "Y"] 6 | 7 | @wraps(func) 8 | def wrapper(*args, **kwargs): 9 | result = func(*args, **kwargs) 10 | return [char for char in result if char in VOWELS] 11 | 12 | return wrapper 13 | 14 | 15 | @vowel_filter 16 | def get_letters(text): 17 | return text 18 | 19 | 20 | print(get_letters(["a", "b", "c", "d", "e"])) 21 | print(get_letters("GoGo")) 22 | -------------------------------------------------------------------------------- /09. Decorators/09. Decorators - Lab/3_even_numbers.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | 3 | 4 | def even_numbers(func): 5 | @wraps(func) 6 | def wrapper(*args, **kwargs): 7 | nums = func(*args, **kwargs) 8 | return [num for num in nums if num % 2 == 0] 9 | 10 | return wrapper 11 | 12 | 13 | @even_numbers 14 | def get_numbers(numbers): 15 | return numbers 16 | 17 | 18 | print(get_numbers([1, 2, 3, 4, 5, 8])) 19 | -------------------------------------------------------------------------------- /09. Decorators/09. Decorators - Lab/4_multiply.py: -------------------------------------------------------------------------------- 1 | from functools import wraps 2 | 3 | 4 | def multiply(times): 5 | def decorator(func): 6 | @wraps(func) 7 | def wrapper(*args, **kwargs): 8 | result = func(*args, **kwargs) * times 9 | return result 10 | 11 | return wrapper 12 | 13 | return decorator 14 | 15 | 16 | @multiply(5) 17 | def add_ten(number): 18 | return number + 10 19 | 20 | 21 | print(add_ten(6)) 22 | -------------------------------------------------------------------------------- /10. Testing/10. Testing - Exercise/01_mammal.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | from project.mammal import Mammal 3 | 4 | 5 | class TestGunitSquad(TestCase): 6 | 7 | def setUp(self) -> None: 8 | self.mammal = Mammal("Dino", "BIG", "BRRRRRRrrr") 9 | 10 | def test_successful_init(self): 11 | self.assertEqual("Dino", self.mammal.name) 12 | self.assertEqual("BIG", self.mammal.type) 13 | self.assertEqual("BRRRRRRrrr", self.mammal.sound) 14 | self.assertEqual("animals", self.mammal._Mammal__kingdom) 15 | 16 | def test_successful_make_sound_str(self): 17 | result = self.mammal.make_sound() 18 | self.assertEqual("Dino makes BRRRRRRrrr", result) 19 | 20 | def test_successful_get_kingdom_str(self): 21 | result = self.mammal.get_kingdom() 22 | self.assertEqual("animals", result) 23 | 24 | def test_successful_info_str(self): 25 | result = self.mammal.info() 26 | self.assertEqual("Dino is of type BIG", result) 27 | 28 | if __name__ == "__main__": 29 | main() 30 | -------------------------------------------------------------------------------- /10. Testing/10. Testing - Exercise/02_vehicle.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | from project.vehicle import Vehicle 3 | 4 | 5 | class TestGunitSquad(TestCase): 6 | 7 | def setUp(self) -> None: 8 | self.vehicle = Vehicle(56, 51) 9 | 10 | def test_successful_initialization(self): 11 | self.assertEqual(56, self.vehicle.fuel) 12 | self.assertEqual(56, self.vehicle.capacity) 13 | self.assertEqual(51, self.vehicle.horse_power) 14 | self.assertEqual(1.25, self.vehicle.fuel_consumption) 15 | self.assertEqual(1.25, self.vehicle.DEFAULT_FUEL_CONSUMPTION) 16 | 17 | def test_unsuccessful_drive_raise_exception(self): 18 | kilometers = 1000 19 | with self.assertRaises(Exception) as ex: 20 | self.vehicle.drive(kilometers) 21 | 22 | self.assertTrue(kilometers * 1.25 > self.vehicle.fuel) 23 | self.assertEqual("Not enough fuel", str(ex.exception)) 24 | 25 | def test_successful_drive(self): 26 | kilometers = 10 27 | self.vehicle.drive(kilometers) 28 | self.assertTrue(kilometers * 1.25 <= self.vehicle.fuel) 29 | self.assertEqual(43.5, self.vehicle.fuel) 30 | 31 | def test_unsuccessful_refuel_raise_exception(self): 32 | fuel = 1000 33 | with self.assertRaises(Exception) as ex: 34 | self.vehicle.refuel(fuel) 35 | 36 | self.assertTrue(fuel + self.vehicle.fuel > self.vehicle.capacity) 37 | self.assertEqual("Too much fuel", str(ex.exception)) 38 | 39 | def test_successful_refuel(self): 40 | self.vehicle.capacity = 66 41 | fuel = 10 42 | self.assertTrue(fuel + self.vehicle.fuel <= self.vehicle.capacity) 43 | self.vehicle.refuel(fuel) 44 | self.assertEqual(66, self.vehicle.fuel) 45 | 46 | def test___str__(self): 47 | result = str(self.vehicle) 48 | self.assertEqual("The vehicle has 51 horse power " 49 | "with 56 fuel left and " 50 | "1.25 fuel consumption", result) 51 | 52 | 53 | if __name__ == "__main__": 54 | main() 55 | -------------------------------------------------------------------------------- /10. Testing/10. Testing - Exercise/03_hero.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | from project.hero import Hero 3 | 4 | 5 | class TestGunitSquad(TestCase): 6 | 7 | def setUp(self) -> None: 8 | self.hero = Hero("RetroMan", 1, 20, 10) 9 | 10 | def test_successful_initialization(self): 11 | self.assertEqual("RetroMan", self.hero.username) 12 | self.assertEqual(1, self.hero.level) 13 | self.assertEqual(20, self.hero.health) 14 | self.assertEqual(10, self.hero.damage) 15 | 16 | def test_unsuccessful_battle_raise_exception_self_battle(self): 17 | with self.assertRaises(Exception) as ex: 18 | copy_ = Hero("RetroMan", 1, 20, 10) 19 | self.hero.battle(copy_) 20 | 21 | self.assertEqual("You cannot fight yourself", str(ex.exception)) 22 | 23 | def test_unsuccessful_battle_raise_value_error_hero_zero_or_negative_health(self): 24 | enemy_hero = Hero("ScrapMan", 1, 20, 10) 25 | self.hero.health = 0 26 | with self.assertRaises(ValueError) as ve: 27 | self.hero.battle(enemy_hero) 28 | 29 | self.assertEqual("Your health is lower than or equal to 0. You need to rest", str(ve.exception)) 30 | 31 | def test_unsuccessful_battle_raise_value_error_enemy_zero_or_negative_health(self): 32 | enemy_hero = Hero("ScrapMan", 1, -1, 10) 33 | with self.assertRaises(ValueError) as ve: 34 | self.hero.battle(enemy_hero) 35 | 36 | self.assertEqual("You cannot fight ScrapMan. He needs to rest", str(ve.exception)) 37 | 38 | def test_successful_battle_draw(self): 39 | self.hero.damage = 20 40 | enemy_hero = Hero("ScrapMan", 1, 20, 20) 41 | result = self.hero.battle(enemy_hero) 42 | 43 | self.assertEqual("Draw", result) 44 | self.assertEqual(0, self.hero.health) 45 | self.assertEqual(0, enemy_hero.health) 46 | 47 | def test_successful_battle_hero_win(self): 48 | enemy_hero = Hero("ScrapMan", 1, 20, 2) 49 | self.hero.damage = 20 50 | result = self.hero.battle(enemy_hero) 51 | self.assertEqual("You win", result) 52 | self.assertEqual(23, self.hero.health) 53 | self.assertEqual(0, enemy_hero.health) 54 | 55 | def test_successful_battle_hero_lose(self): 56 | enemy_hero = Hero("ScrapMan", 1, 20, 25) 57 | result = self.hero.battle(enemy_hero) 58 | self.assertEqual("You lose", result) 59 | self.assertEqual(-5, self.hero.health) 60 | self.assertEqual(15, enemy_hero.health) 61 | 62 | def test__str__(self): 63 | self.assertEqual("Hero RetroMan: 1 lvl\n" 64 | "Health: 20\n" 65 | "Damage: 10\n", str(self.hero)) 66 | 67 | 68 | 69 | if __name__ == "__main__": 70 | main() 71 | -------------------------------------------------------------------------------- /10. Testing/10. Testing - Exercise/04_student.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | 3 | from project.student import Student 4 | 5 | 6 | class TestGunitSquad(TestCase): 7 | 8 | def setUp(self) -> None: 9 | self.student = Student("Not Joro") 10 | self.student_with_courses = Student("Joro", {"Python": ["too weak"]}) 11 | 12 | def test_successful_initialization(self): 13 | self.assertEqual("Not Joro", self.student.name) 14 | self.assertEqual({}, self.student.courses) 15 | self.assertEqual("Joro", self.student_with_courses.name) 16 | self.assertEqual({"Python": ["too weak"]}, self.student_with_courses.courses) 17 | 18 | def test_successful_enroll_course_exist_added_only_notes(self): 19 | result = self.student_with_courses.enroll("Python", ["can't argue with that"]) 20 | 21 | self.assertEqual("Course already added. Notes have been updated.", result) 22 | self.assertEqual(["too weak", "can't argue with that"], self.student_with_courses.courses["Python"]) 23 | 24 | def test_successful_enroll_course_and_notes_not_existing_with_Y(self): 25 | result = self.student.enroll("JS", ["too much {}"], "Y") 26 | 27 | self.assertEqual("Course and course notes have been added.", result) 28 | self.assertEqual({"JS": ["too much {}"]}, self.student.courses) 29 | 30 | def test_successful_enroll_course_and_notes_not_existing_with_empty_string(self): 31 | result = self.student.enroll("JS", ["too much {}"]) 32 | 33 | self.assertEqual("Course and course notes have been added.", result) 34 | self.assertEqual({"JS": ["too much {}"]}, self.student.courses) 35 | 36 | def test_successful_enroll_course(self): 37 | result = self.student.enroll("JS", ["too much {}"], "N") 38 | 39 | self.assertEqual("Course has been added.", result) 40 | self.assertEqual([], self.student.courses["JS"]) 41 | 42 | def test_unsuccessful_add_notes_raise_exception(self): 43 | with self.assertRaises(Exception) as ex: 44 | self.student.add_notes("C--", ["too good, to be true"]) 45 | 46 | self.assertEqual("Cannot add notes. Course not found.", str(ex.exception)) 47 | 48 | def test_successful_add_notes_to_existing_course_in_list(self): 49 | result = self.student_with_courses.add_notes("Python", "learn to test") 50 | 51 | self.assertEqual("Notes have been updated", result) 52 | self.assertTrue("learn to test" in self.student_with_courses.courses["Python"]) 53 | 54 | def test_unsuccessful_leave_course_raise_exception_course_not_found(self): 55 | with self.assertRaises(Exception) as ex: 56 | self.student.leave_course("Python") 57 | 58 | self.assertEqual("Cannot remove course. Course not found.", str(ex.exception)) 59 | 60 | def test_successful_leave_course_pop_from_list(self): 61 | self.student_with_courses.courses = {"Python": ["too weak"], "R": ["Damn its fast"]} 62 | result = self.student_with_courses.leave_course("Python") 63 | 64 | self.assertEqual("Course has been removed", result) 65 | self.assertEqual({"R": ["Damn its fast"]}, self.student_with_courses.courses) 66 | 67 | 68 | if __name__ == "__main__": 69 | main() 70 | -------------------------------------------------------------------------------- /10. Testing/10. Testing - Lab/1_test_worker.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | 3 | 4 | # from 1_christmas_pastry_shop.worker import Worker 5 | 6 | 7 | class TestGunitSquad(TestCase): 8 | 9 | def setUp(self) -> None: 10 | self.worker = Worker("Test", 100, 100) 11 | 12 | def test_successful_initialization(self): 13 | self.assertEqual("Test", self.worker.name) 14 | self.assertEqual(100, self.worker.salary) 15 | self.assertEqual(100, self.worker.energy) 16 | self.assertEqual(0, self.worker.money) 17 | 18 | def test_successful_work(self): 19 | self.worker.work() 20 | self.assertEqual(100, self.worker.money) 21 | self.assertEqual(99, self.worker.energy) 22 | 23 | def test_unsuccessful_work_not_enough_energy_exception(self): 24 | self.worker.energy = 0 25 | 26 | with self.assertRaises(Exception) as ex: 27 | self.worker.work() 28 | 29 | self.assertEqual("Not enough energy.", str(ex.exception)) 30 | 31 | def test_rest_adding_one_energy(self): 32 | self.worker.rest() 33 | 34 | self.assertEqual(101, self.worker.energy) 35 | 36 | def test_get_info_string_return(self): 37 | result = self.worker.get_info() 38 | 39 | self.assertEqual(f'Test has saved 0 money.', result) 40 | 41 | 42 | if __name__ == "__main__": 43 | main() 44 | -------------------------------------------------------------------------------- /10. Testing/10. Testing - Lab/2_test_cat.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | # from 1_christmas_pastry_shop.cat import Cat 3 | 4 | 5 | class TestGunitSquad(TestCase): 6 | 7 | def setUp(self) -> None: 8 | self.cat = Cat("Test") 9 | 10 | def test_successful_initial(self): 11 | self.assertEqual("Test", self.cat.name) 12 | self.assertEqual(False, self.cat.fed) 13 | self.assertEqual(False, self.cat.sleepy) 14 | self.assertEqual(0, self.cat.size) 15 | 16 | def test_unsuccessful_eat_raise_exception(self): 17 | self.cat.fed = True 18 | 19 | with self.assertRaises(Exception) as ex: 20 | self.cat.eat() 21 | 22 | self.assertEqual('Already fed.', str(ex.exception)) 23 | 24 | def test_successful_eat(self): 25 | self.cat.eat() 26 | 27 | self.assertEqual(True, self.cat.fed) 28 | self.assertEqual(True, self.cat.sleepy) 29 | self.assertEqual(1, self.cat.size) 30 | 31 | def test_unsuccessful_sleep_raise_exception(self): 32 | with self.assertRaises(Exception) as ex: 33 | self.cat.sleep() 34 | 35 | self.assertEqual('Cannot sleep while hungry', str(ex.exception)) 36 | 37 | def test_successful_sleep(self): 38 | self.cat.fed = True 39 | self.cat.sleepy = True 40 | self.cat.sleep() 41 | self.assertEqual(False, self.cat.sleepy) 42 | 43 | 44 | if __name__ == "__main__": 45 | main() 46 | -------------------------------------------------------------------------------- /10. Testing/10. Testing - Lab/3_test_list.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | 3 | # from 1_christmas_pastry_shop.list import IntegerList 4 | 5 | 6 | class TestGunitSquad(TestCase): 7 | 8 | def setUp(self) -> None: 9 | self.list = IntegerList(1, 2, 3, "top", 2.2, False, ()) 10 | 11 | def test_successful_initial(self): 12 | self.assertEqual([1, 2, 3], self.list._IntegerList__data) 13 | 14 | def test_successful_get_data(self): 15 | self.assertEqual([1, 2, 3], self.list.get_data()) 16 | 17 | def test_unsuccessful_add_raise_value_error(self): 18 | with self.assertRaises(ValueError) as ve: 19 | self.list.add("TOP THAT") 20 | 21 | self.assertEqual("Element is not Integer", str(ve.exception)) 22 | 23 | def test_successful_add_to_list(self): 24 | self.list.add(66) 25 | self.assertEqual([1, 2, 3, 66], self.list.get_data()) 26 | # self.assertEqual([1,2,3,66], self.list._IntegerList__data) 27 | 28 | def test_unsuccessful_remove_index_raise_index_error(self): 29 | with self.assertRaises(IndexError) as ie: 30 | self.list.remove_index(10) 31 | 32 | self.assertEqual("Index is out of range", str(ie.exception)) 33 | 34 | def test_successful_remove_index_from_list(self): 35 | result = self.list.remove_index(0) 36 | self.assertEqual(1, result) 37 | self.assertEqual([2, 3], self.list._IntegerList__data) 38 | 39 | def test_unsuccessful_get_raise_index_error(self): 40 | with self.assertRaises(IndexError) as ie: 41 | self.list.get(10) 42 | 43 | self.assertEqual("Index is out of range", str(ie.exception)) 44 | 45 | def test_successful_get_item_from_list_by_index(self): 46 | result = self.list.get(0) 47 | 48 | self.assertEqual(1, result) 49 | self.assertEqual(1, self.list._IntegerList__data[0]) 50 | 51 | def test_unsuccessful_insert_raise_index_error(self): 52 | with self.assertRaises(IndexError) as ie: 53 | self.list.insert(3, 4) 54 | 55 | self.assertEqual("Index is out of range", str(ie.exception)) 56 | 57 | def test_unsuccessful_insert_with_wrong_element_raise_value_error(self): 58 | with self.assertRaises(ValueError) as ve: 59 | self.list.insert(0, "1") 60 | 61 | self.assertEqual("Element is not Integer", str(ve.exception)) 62 | 63 | def test_successful_insert_element_in_list(self): 64 | self.list.insert(0, 10) 65 | 66 | self.assertEqual([10, 1, 2, 3], self.list._IntegerList__data) 67 | 68 | def test_successful_get_biggest_element_in_list(self): 69 | result = self.list.get_biggest() 70 | self.assertEqual(3, result) 71 | 72 | def test_successful_get_index_element_in_list(self): 73 | result = self.list.get_index(3) 74 | self.assertEqual(2, result) 75 | 76 | 77 | if __name__ == "__main__": 78 | main() 79 | -------------------------------------------------------------------------------- /10. Testing/10. Testing - Lab/4_test_car_manager.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase, main 2 | 3 | # from 1_christmas_pastry_shop.car import Car 4 | 5 | 6 | class TestGunitSquad(TestCase): 7 | 8 | def setUp(self) -> None: 9 | self.car = Car("KR", "CHEVY", 5, 51) 10 | 11 | def test_successful_initialization(self): 12 | self.assertEqual("KR", self.car.make) 13 | self.assertEqual("CHEVY", self.car.model) 14 | self.assertEqual(5, self.car.fuel_consumption) 15 | self.assertEqual(51, self.car.fuel_capacity) 16 | self.assertEqual(0, self.car.fuel_amount) 17 | 18 | def test_unsuccessful_make_attribute_raise_exception(self): 19 | with self.assertRaises(Exception) as ex: 20 | self.car.make = "" 21 | 22 | self.assertEqual("Make cannot be null or empty!", str(ex.exception)) 23 | 24 | def test_unsuccessful_model_attribute_raise_exception(self): 25 | with self.assertRaises(Exception) as ex: 26 | self.car.model = "" 27 | 28 | self.assertEqual("Model cannot be null or empty!", str(ex.exception)) 29 | 30 | def test_unsuccessful_fuel_consumption_attribute_raise_exception(self): 31 | with self.assertRaises(Exception) as ex: 32 | self.car.fuel_consumption = 0 33 | 34 | self.assertEqual("Fuel consumption cannot be zero or negative!", str(ex.exception)) 35 | 36 | def test_unsuccessful_fuel_capacity_attribute_raise_exception(self): 37 | with self.assertRaises(Exception) as ex: 38 | self.car.fuel_capacity = 0 39 | 40 | self.assertEqual("Fuel capacity cannot be zero or negative!", str(ex.exception)) 41 | 42 | def test_unsuccessful_fuel_amount_attribute_raise_exception(self): 43 | with self.assertRaises(Exception) as ex: 44 | self.car.fuel_amount = -1 45 | 46 | self.assertEqual("Fuel amount cannot be negative!", str(ex.exception)) 47 | 48 | def test_unsuccessful_refuel_raise_exception(self): 49 | with self.assertRaises(Exception) as ex: 50 | self.car.refuel(0) 51 | 52 | self.assertEqual("Fuel amount cannot be zero or negative!", str(ex.exception)) 53 | 54 | def test_successful_refuel(self): 55 | self.car.refuel(10) 56 | self.assertEqual(10, self.car.fuel_amount) 57 | 58 | def test_successful_refuel_with_over_the_limit(self): 59 | amount = 1000 60 | self.car.refuel(amount) 61 | self.assertTrue(amount > self.car.fuel_capacity) 62 | self.assertEqual(51, self.car.fuel_capacity) 63 | 64 | def test_unsuccessful_drive_raise_exception(self): 65 | distance = 1000 66 | with self.assertRaises(Exception) as ex: 67 | self.car.drive(distance) 68 | 69 | self.assertTrue(distance > self.car.fuel_amount) 70 | self.assertEqual("You don't have enough fuel to drive!", str(ex.exception)) 71 | 72 | def test_successful_drive(self): 73 | self.car.fuel_amount = 51 74 | self.car.drive(100) 75 | self.assertEqual(46, self.car.fuel_amount) 76 | 77 | 78 | if __name__ == "__main__": 79 | main() 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # python-oop --------------------------------------------------------------------------------