├── .gitignore ├── README.md ├── src ├── day_1 │ ├── README.md │ └── username_generator.py ├── day_10 │ ├── README.md │ ├── calculator.py │ ├── logo.py │ └── main.py ├── day_11 │ ├── README.md │ ├── blackjack.py │ └── logo.py ├── day_12 │ ├── README.md │ ├── logo.py │ └── number_guess.py ├── day_13 │ ├── README.md │ ├── fizzbuzz.py │ └── logo.py ├── day_14 │ ├── README.md │ ├── game_data.py │ ├── higher_lower.py │ └── logo.py ├── day_15 │ ├── README.md │ ├── coffee.py │ └── main.py ├── day_16 │ ├── README.md │ ├── main.py │ ├── tic_tac_toe.py │ └── user_interface.py ├── day_17 │ ├── README.md │ ├── main.py │ ├── question.py │ └── quiz.py ├── day_18 │ ├── README.md │ ├── art.py │ └── images │ │ └── dots.jpg ├── day_19 │ ├── README.md │ ├── images │ │ └── race.gif │ ├── main.py │ └── player.py ├── day_2 │ ├── README.md │ └── tip_calculator.py ├── day_20 │ ├── README.md │ ├── food.py │ ├── main.py │ └── snake.py ├── day_21 │ ├── README.md │ ├── ball.py │ ├── main.py │ ├── paddle.py │ └── score.py ├── day_22 │ ├── README.md │ ├── car.py │ ├── display.py │ ├── frog.py │ ├── images │ │ ├── bg0.png │ │ ├── bg1.png │ │ ├── bg2.png │ │ ├── cars │ │ │ ├── blue_car.gif │ │ │ ├── green_car.gif │ │ │ ├── red_car.gif │ │ │ └── yellow_car.gif │ │ ├── frog.gif │ │ ├── frog3.gif │ │ └── frog4.gif │ └── main.py ├── day_23 │ ├── README.md │ ├── data │ │ ├── 50_states.csv │ │ └── blank_states_img.gif │ └── main.py ├── day_24 │ ├── README.md │ ├── data │ │ └── nato_phonetic_alphabet.csv │ └── main.py ├── day_25 │ ├── README.md │ └── main.py ├── day_26 │ ├── README.md │ ├── images │ │ └── pomodoro.png │ ├── main.py │ ├── pomodoro.py │ └── pomodoro_settings.py ├── day_27 │ ├── README.md │ ├── data │ │ └── passwords.txt │ ├── file_handler.py │ ├── images │ │ └── pass.png │ ├── main.py │ ├── password_generator.py │ └── password_manager.py ├── day_28 │ ├── README.md │ ├── data │ │ └── french_words.csv │ ├── flash_card.py │ ├── images │ │ ├── back_flash_card.png │ │ ├── flash_card.png │ │ ├── right.png │ │ └── wrong.png │ └── main.py ├── day_29 │ ├── README.md │ └── main.py ├── day_3 │ ├── README.md │ └── treasure_island.py ├── day_30 │ ├── README.md │ ├── main.py │ └── movies.txt ├── day_31 │ ├── README.md │ └── main.py ├── day_4 │ ├── README.md │ └── rock_paper_scissors.py ├── day_5 │ ├── README.md │ ├── password_generator.py │ └── user_interface.py ├── day_6 │ ├── README.md │ ├── dice.py │ ├── main.py │ └── user_interface.py ├── day_7 │ ├── README.md │ ├── hangman.py │ ├── players-scores │ ├── requirements.txt │ └── words.txt ├── day_8 │ ├── README.md │ ├── caesar_cipher.py │ └── logo.py └── day_9 │ ├── README.md │ ├── auction.py │ ├── auction_program.py │ └── logo.py └── utility.py /.gitignore: -------------------------------------------------------------------------------- 1 | test.py 2 | .vscode 3 | 4 | 5 | # Byte-compiled / optimized / DLL files 6 | __pycache__/ 7 | *.py[cod] 8 | *$py.class 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | wheels/ 27 | pip-wheel-metadata/ 28 | share/python-wheels/ 29 | *.egg-info/ 30 | .installed.cfg 31 | *.egg 32 | MANIFEST 33 | 34 | # PyInstaller 35 | # Usually these files are written by a python script from a template 36 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 37 | *.manifest 38 | *.spec 39 | 40 | # Installer logs 41 | pip-log.txt 42 | pip-delete-this-directory.txt 43 | 44 | # Unit test / coverage reports 45 | htmlcov/ 46 | .tox/ 47 | .nox/ 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *.cover 54 | *.py,cover 55 | .hypothesis/ 56 | .pytest_cache/ 57 | 58 | # Translations 59 | *.mo 60 | *.pot 61 | 62 | # Django stuff: 63 | *.log 64 | local_settings.py 65 | db.sqlite3 66 | db.sqlite3-journal 67 | 68 | # Flask stuff: 69 | instance/ 70 | .webassets-cache 71 | 72 | # Scrapy stuff: 73 | .scrapy 74 | 75 | # Sphinx documentation 76 | docs/_build/ 77 | 78 | # PyBuilder 79 | target/ 80 | 81 | # Jupyter Notebook 82 | .ipynb_checkpoints 83 | 84 | # IPython 85 | profile_default/ 86 | ipython_config.py 87 | 88 | # pyenv 89 | .python-version 90 | 91 | # pipenv 92 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 93 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 94 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 95 | # install all needed dependencies. 96 | #Pipfile.lock 97 | 98 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 99 | __pypackages__/ 100 | 101 | # Celery stuff 102 | celerybeat-schedule 103 | celerybeat.pid 104 | 105 | # SageMath parsed files 106 | *.sage.py 107 | 108 | # Environments 109 | .env 110 | .venv 111 | env/ 112 | venv/ 113 | ENV/ 114 | env.bak/ 115 | venv.bak/ 116 | 117 | # Spyder project settings 118 | .spyderproject 119 | .spyproject 120 | 121 | # Rope project settings 122 | .ropeproject 123 | 124 | # mkdocs documentation 125 | /site 126 | 127 | # mypy 128 | .mypy_cache/ 129 | .dmypy.json 130 | dmypy.json 131 | 132 | # Pyre type checker 133 | .pyre/ 134 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 31 Days Of Code 2 | 3 | I took on a challenge to build 31 mini-projects using Python. These projects included a variety of applications and features, such as a hangman game, a tic-tac-toe game, a quiz program, and a flash cards app. 4 | 5 | # Overview: 6 | 7 | | Day | Project | Demo | Code | 8 | | --- | ---------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | 9 | | 1 | Username Generator | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_1#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_1/username_generator.py) | 10 | | 2 | Tip Calculator | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_2#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_2/tip_calculator.py) | | 11 | | 3 | Treasure Island | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_3#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_3/treasure_island.py) | | 12 | | 4 | Rock Paper Scissors | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_4#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_4/rock_paper_scissors.py) | | 13 | | 5 | Password Generator | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_5#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_5/password_generator.py) | | 14 | | 6 | Dice Rolling Simulator | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_6#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_6/user_interface.py) | | 15 | | **7** | **Hangman Game** | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_7#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_7/hangman.py) | | 16 | | 8 | Caesar Cipher | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_8#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_8/caesar_cipher.py) | | 17 | | 9 | Auction Program | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_9#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_9/auction_program.py) | | 18 | | 10 | Calculator | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_10#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_10/main.py) | | 19 | | **11** | **BlackJack** | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_11#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_11/blackjack.py) | | 20 | | 12 | Number Guessing Game | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_12#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_12/number_guess.py) | | 21 | | 13 | FizzBuzz | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_13#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_13/fizzbuzz.py) | | 22 | | 14 | Higher Lower Game | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_14#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_14/higher_lower.py) | | 23 | | **15** |**Coffee Machine** | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_15#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_15/main.py) | | 24 | | **16** |**Tic Tac Toe** | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_16#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_16/main.py) | | 25 | | **17** |**Quiz Program** | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_17#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_17/main.py) | | 26 | | 18 | Dot Painting | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_18#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_18/art.py) | | 27 | | **19** | **Turtle Race Game** | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_19#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_19/main.py) | | 28 | | **20** | **Snake Game** | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_20#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_20/main.py) | | 29 | | **21** | **Pong Game** | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_21#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_21/main.py) | | 30 | | **22** | **Crossy Road Game** | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_22#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_22/main.py) | | 31 | | 23 | US Map Quiz | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_23#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_23/main.py) | | 32 | | 24 |NATO Phonetic Alphabet | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_24#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_24/main.py) | | 33 | | 25 |Miles to Km Converter | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_25#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_25/main.py) | | 34 | | **26** |**Pomodoro Timer App** | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_26#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_26/pomodoro.py) | | 35 | | **27** |**Password Manager App** | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_27#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_27/password_manager.py) | | 36 | | **28** |**FlashCards App** | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_28#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_28/flash_card.py) | | 37 | | 29 |Weather Forecast via SMS | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_29#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_29/main.py) | | 38 | | 30 |Best Movies To Watch App | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_30#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_30/main.py) | | 39 | | 31 |WallPaper Bot | [demo](https://github.com/dylanbuchi/100-days-of-code/tree/main/src/day_31#demo) | [code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_31/main.py) | | 40 | 41 | -------------------------------------------------------------------------------- /src/day_1/README.md: -------------------------------------------------------------------------------- 1 | # Username Generator 2 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_1/username_generator.py) 3 | ## Demo: 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/day_1/username_generator.py: -------------------------------------------------------------------------------- 1 | # Username Generator 2 | 3 | 4 | def print_welcome(name: str): 5 | print(f"Welcome to {name}.") 6 | 7 | 8 | def get_username() -> str: 9 | user_color = ask_user_favorite('color') 10 | user_food = ask_user_favorite('food') 11 | username = create_username_from(user_color, user_food) 12 | 13 | return username 14 | 15 | 16 | def ask_user_favorite(item: str) -> str: 17 | return input(f"What's your favorite {item}?\n") 18 | 19 | 20 | def create_username_from(*args: str): 21 | if not args: 22 | raise ValueError("Cant create an empty username") 23 | 24 | username_parts = [] 25 | username_number = 0 26 | 27 | for arg in args: 28 | username_parts.append(title_string_and_replace_spaces(arg, '-')) 29 | username_number += len(arg) 30 | 31 | username_number *= len(args) 32 | 33 | username_parts.append(str(username_number)) 34 | username = format_username(username_parts) 35 | 36 | return username 37 | 38 | 39 | def title_string_and_replace_spaces(string: str, replacement: str): 40 | result = string.replace(" ", replacement) 41 | return result.title() 42 | 43 | 44 | def format_username(username_parts): 45 | username = f"{'-'.join(username_parts[:-1])}{username_parts[-1]}" 46 | return username 47 | 48 | 49 | def main(): 50 | print_welcome("to the username generator") 51 | username = get_username() 52 | 53 | print(f"Your new username is {username}") 54 | 55 | 56 | if __name__ == "__main__": 57 | main() -------------------------------------------------------------------------------- /src/day_10/README.md: -------------------------------------------------------------------------------- 1 | # Calculator 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_10/main.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_10/calculator.py: -------------------------------------------------------------------------------- 1 | # Calculator 2 | import sys 3 | 4 | 5 | class Calculator: 6 | def __init__(self): 7 | self.operations = { 8 | '+': self.add, 9 | '-': self.substract, 10 | '*': self.multiply, 11 | '/': self.divide, 12 | } 13 | 14 | def get_operations(self): 15 | return self.operations 16 | 17 | def add(self, n1, n2): 18 | return n1 + n2 19 | 20 | def substract(self, n1, n2): 21 | return n1 - n2 22 | 23 | def multiply(self, n1, n2): 24 | return n1 * n2 25 | 26 | def divide(self, n1, n2): 27 | try: 28 | return n1 / n2 29 | except ZeroDivisionError as err: 30 | print("Error, Can't divide by zero") 31 | sys.exit() 32 | -------------------------------------------------------------------------------- /src/day_10/logo.py: -------------------------------------------------------------------------------- 1 | LOGO = """ _____________________ 2 | | _________________ | 3 | | | JO 0. | | 4 | | |_________________| | 5 | | ___ ___ ___ ___ | 6 | | | 7 | 8 | 9 | | + | | 7 | | |___|___|___| |___| | 8 | | | 4 | 5 | 6 | | - | | 9 | | |___|___|___| |___| | 10 | | | 1 | 2 | 3 | | x | | 11 | | |___|___|___| |___| | 12 | | | . | 0 | = | | / | | 13 | | |___|___|___| |___| | 14 | |_____________________|""" -------------------------------------------------------------------------------- /src/day_10/main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | sys.path.append(os.getcwd()) 5 | 6 | from calculator import Calculator 7 | from logo import LOGO 8 | 9 | 10 | def print_operations(): 11 | print(""" 12 | + 13 | - 14 | * 15 | / 16 | """) 17 | 18 | 19 | def get_user_operation(operations): 20 | print_operations() 21 | try: 22 | operator = input("Pick an operation: ").lower().strip() 23 | assert operator in operations.keys() 24 | except AssertionError: 25 | print("Select a valid operation") 26 | return get_user_operation(operations) 27 | else: 28 | return operator 29 | 30 | 31 | def get_user_number(string): 32 | try: 33 | number = float(input(f"\nPick the {string} number: ")) 34 | 35 | except ValueError: 36 | print("Error, only numbers allowed") 37 | return get_user_number(string) 38 | 39 | else: 40 | return int(number) if (str(number)[-1] == '0') else number 41 | 42 | 43 | def get_user_inputs(operations): 44 | 45 | number_1 = get_user_number('first') 46 | operation = get_user_operation(operations) 47 | number_2 = get_user_number('second') 48 | 49 | return number_1, number_2, operation 50 | 51 | 52 | def print_result(n1, n2, operator, result): 53 | print(f"{n1} {operator} {n2} = {result}") 54 | 55 | 56 | def calculate_user_numbers(n1, n2, operator, operations): 57 | calculate = operations[operator] 58 | result = calculate(n1, n2) 59 | return result 60 | 61 | 62 | def user_interface(): 63 | calculator = Calculator() 64 | operations = calculator.get_operations() 65 | number_1, number_2, operator = get_user_inputs(operations) 66 | 67 | result = calculate_user_numbers(number_1, number_2, operator, operations) 68 | print_result(number_1, number_2, operator, result) 69 | current_num = result 70 | 71 | choice = '' 72 | 73 | while choice == '': 74 | 75 | choice = input( 76 | f"Press enter to keep calculating with the number {current_num}\n") 77 | if not choice: 78 | operation = get_user_operation(operations) 79 | next_num = get_user_number('next') 80 | result = calculate_user_numbers(current_num, next_num, operation, 81 | operations) 82 | print_result(current_num, next_num, operation, result) 83 | current_num = result 84 | 85 | run_again("\nPress enter to use the calculator again\n", main) 86 | 87 | 88 | def run_again(string, func): 89 | choice = input(string).lower().strip() 90 | if not choice: 91 | func() 92 | 93 | 94 | def main(): 95 | print(LOGO) 96 | try: 97 | user_interface() 98 | except KeyboardInterrupt: 99 | sys.exit() 100 | 101 | 102 | if __name__ == "__main__": 103 | main() -------------------------------------------------------------------------------- /src/day_11/README.md: -------------------------------------------------------------------------------- 1 | # BlackJack 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_11/blackjack.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_11/blackjack.py: -------------------------------------------------------------------------------- 1 | # Blackjack 2 | import sys 3 | import os 4 | import random 5 | from colorama import init, Fore 6 | from time import sleep 7 | 8 | from logo import LOGO 9 | 10 | 11 | def create_standard_deck(): 12 | """Create a deck of cards with 8 packs""" 13 | deck = [] 14 | for _ in range(8): 15 | cards = {i: i for (i) in range(2, 11)} 16 | cards.update({'J': 10, 'Q': 10, 'K': 10, 'A': [11, 1]}) 17 | deck.append(cards) 18 | return deck 19 | 20 | 21 | def refill_deck(deck): 22 | if not deck: 23 | temp = create_standard_deck() 24 | deck.extend(temp) 25 | 26 | 27 | def get_a_card(card_names, card_values, cards_count): 28 | """get a random card with it's value and remove it from deck""" 29 | index = random.randrange(0, len(card_names)) 30 | card_name, card_value = card_names[index], card_values[index] 31 | 32 | cards_count[card_name] += 1 33 | 34 | if cards_count[card_name] == 4: 35 | card_names.pop(index) 36 | card_values.pop(index) 37 | 38 | return card_name, card_value 39 | 40 | 41 | def clear_console(): 42 | os.system('cls' if os.name == 'nt' else 'clear') 43 | 44 | 45 | def get_value_for_Ace_card(player_name, player_card, card_values, total=0): 46 | """return 1 or 11 if card is As""" 47 | if (player_card != 'A'): 48 | return 49 | 50 | if player_name == 'You': 51 | try: 52 | 53 | choice = int( 54 | input("Your card is an Ace Do you want 1 or 11?:\n ").lower(). 55 | strip()) 56 | assert choice == 1 or choice == 11 57 | 58 | except (ValueError, AssertionError): 59 | print("Error, pick 1 or 11!") 60 | return get_value_for_Ace_card(player_name, player_card, 61 | card_values) 62 | 63 | else: 64 | clear_console() 65 | return choice 66 | else: 67 | bot_choice = 11 if total < 17 else 1 68 | return bot_choice 69 | 70 | 71 | def print_result(player_name, current_hand, total): 72 | total_color = Fore.RED if total > 21 else Fore.YELLOW 73 | 74 | print("*" * 80, end="\n") 75 | print(f"{Fore.GREEN} {player_name.upper()}:\n") 76 | 77 | print(f"Cards: {Fore.YELLOW + ', '.join(current_hand)}\n") 78 | print(f"Total: {total_color + str(total)}\n") 79 | 80 | 81 | def draw_card(player_name, 82 | card_names, 83 | card_values, 84 | current_hand, 85 | total, 86 | cards_count, 87 | balance=0): 88 | """A player draws a card, prints their hand and return the total points""" 89 | card, card_value = get_a_card(card_names, card_values, cards_count) 90 | if card != 'A': 91 | total += card_value 92 | else: 93 | if player_name != 'The dealer': 94 | if (total): 95 | print_result(player_name, current_hand, total) 96 | 97 | total += get_value_for_Ace_card(player_name, card, card_value, total) 98 | # if player_name == 'The dealer': 99 | # print_result(player_name, current_hand, total) 100 | 101 | # print("*" * 80, end="\n") 102 | # print(f"{player_name.upper()}:\n") 103 | 104 | current_hand.append(f"[{str(card)}]") 105 | 106 | # print_result(player_name, current_hand, total) 107 | 108 | return total 109 | 110 | 111 | def print_player_balance(balance): 112 | print(f"you have ${Fore.GREEN + str(balance)}") 113 | 114 | 115 | def rules(player_total, dealer_total, player_stop_draw): 116 | win = None 117 | if (player_total == 21): 118 | win = True 119 | elif (dealer_total == 21): 120 | win = False 121 | elif dealer_total >= 22: 122 | win = True 123 | elif player_total >= 22: 124 | win = False 125 | 126 | if player_stop_draw: 127 | if (player_total >= dealer_total and player_total < 21): 128 | win = True 129 | elif (dealer_total > player_total and dealer_total < 21): 130 | win = False 131 | return win 132 | 133 | 134 | def place_bet(max): 135 | 136 | try: 137 | bet = int(input("Place your bet\n:$")) 138 | assert bet > 0 and bet <= max 139 | except (AssertionError, ValueError): 140 | print("Place a correct bet amount") 141 | return place_bet(max) 142 | else: 143 | clear_console() 144 | return bet 145 | 146 | 147 | def dealer_plays(dealer_name, card_names, card_values, dealer_hand, 148 | dealer_total, player_total, cards_count): 149 | 150 | while True: 151 | if dealer_total >= 17 and player_total <= 17: 152 | return dealer_total 153 | else: 154 | if dealer_total > 21: 155 | break 156 | dealer_total = draw_card(dealer_name, card_names, card_values, 157 | dealer_hand, dealer_total, cards_count) 158 | 159 | print_result(dealer_name, dealer_hand, dealer_total) 160 | sleep(1.2) 161 | clear_console() 162 | return dealer_total 163 | 164 | 165 | def hit_or_stand(): 166 | try: 167 | answer = int(input(" Hit (1) or Stand (2)\n:").lower().strip()) 168 | assert 1 <= answer <= 2 169 | except (AssertionError, ValueError): 170 | print(f"Enter 1 to Hit or 2 to Stand") 171 | return hit_or_stand() 172 | return answer 173 | 174 | 175 | def get_cards(): 176 | cards = {i: i for (i) in range(1, 11)} 177 | cards.update({'J': 10, 'Q': 10, 'K': 10, 'A': [11, 1]}) 178 | return cards 179 | 180 | 181 | def play_black_jack(decks): 182 | 183 | # variables 184 | game_ended = False 185 | only_dealer_plays = False 186 | player_stop_draw = False 187 | new_game = True 188 | 189 | player_name = 'You' 190 | balance = 100 191 | dealer_name = 'The dealer' 192 | 193 | player_hand = [] 194 | dealer_hand = [] 195 | cards_count = get_cards() 196 | for k, v in cards_count.items(): 197 | cards_count[k] = 0 198 | 199 | player_total = dealer_total = bet = 0 200 | 201 | while (len(decks)): 202 | current_deck = decks.pop() 203 | 204 | card_names = list(current_deck.keys()) 205 | card_values = list(current_deck.values()) 206 | 207 | # while current deck has cards 208 | while (len(card_names) and len(card_values)): 209 | if (balance <= 0): 210 | print("You have $0, deposit more to play again!") 211 | sys.exit() 212 | 213 | if new_game: 214 | new_game = False 215 | print_player_balance(balance) 216 | bet = place_bet(balance) 217 | dealer_total = draw_card(dealer_name, card_names, card_values, 218 | dealer_hand, dealer_total, 219 | cards_count) 220 | 221 | if only_dealer_plays: 222 | 223 | dealer_total = dealer_plays(dealer_name, card_names, 224 | card_values, dealer_hand, 225 | dealer_total, player_total, 226 | cards_count) 227 | else: 228 | 229 | print_result(dealer_name, dealer_hand, dealer_total) 230 | player_total = draw_card(player_name, card_names, card_values, 231 | player_hand, player_total, 232 | cards_count, balance) 233 | 234 | print_result(player_name, player_hand, player_total) 235 | 236 | has_winner = rules(player_total, dealer_total, player_stop_draw) 237 | 238 | if (has_winner == None): 239 | answer = '' 240 | 241 | if (not only_dealer_plays): 242 | answer = hit_or_stand() 243 | 244 | if answer == 1: 245 | clear_console() 246 | continue 247 | else: 248 | clear_console() 249 | player_stop_draw = True 250 | only_dealer_plays = True 251 | continue 252 | 253 | elif (has_winner): 254 | clear_console() 255 | 256 | balance += bet * 2 257 | 258 | print_result(dealer_name, dealer_hand, dealer_total) 259 | print_result(player_name, player_hand, player_total) 260 | if player_total == 21: 261 | print(f"{Fore.CYAN} BLACKJACK ", end='') 262 | print(f"You Win! {Fore.GREEN}+${bet * 2}") 263 | game_ended = True 264 | break 265 | elif (has_winner == False): 266 | clear_console() 267 | 268 | game_ended = True 269 | balance -= bet 270 | print_result(dealer_name, dealer_hand, dealer_total) 271 | print_result(player_name, player_hand, player_total) 272 | if (dealer_total == 21): 273 | print(f"{Fore.CYAN} BLACKJACK ", end='') 274 | print(f"Dealer wins! {Fore.RED} -${bet}\n") 275 | break 276 | 277 | # clear the current deck adn count when cards are empty 278 | if (not len(card_names) and not len(card_values)): 279 | current_deck.clear() 280 | cards_count.clear() 281 | 282 | # check if it's the end game 283 | if (game_ended): 284 | player_total, dealer_total = reset_points() 285 | reset_player_hand(player_hand) 286 | reset_player_hand(dealer_hand) 287 | 288 | ans = input("play again ? (y/n)\n:") 289 | 290 | if (ans == 'y'): 291 | game_ended = False 292 | only_dealer_plays = False 293 | player_stop_draw = False 294 | new_game = True 295 | clear_console() 296 | continue 297 | else: 298 | return 299 | # refill if no more cards in the decks 300 | if (not decks): 301 | refill_deck(decks) 302 | play_black_jack() 303 | 304 | 305 | def reset_player_hand(player_hand): 306 | player_hand.clear() 307 | 308 | 309 | def reset_points(): 310 | return 0, 0 311 | 312 | 313 | def user_interface(): 314 | decks = create_standard_deck() 315 | play_black_jack(decks) 316 | 317 | 318 | def main(): 319 | init(autoreset=True) 320 | print(LOGO) 321 | 322 | try: 323 | user_interface() 324 | except KeyboardInterrupt: 325 | sys.exit() 326 | 327 | 328 | if __name__ == "__main__": 329 | main() -------------------------------------------------------------------------------- /src/day_11/logo.py: -------------------------------------------------------------------------------- 1 | LOGO = """ 2 | 88 88 88 88 88 3 | 88 88 88 "" 88 4 | 88 88 88 88 5 | 88,dPPYba, 88 ,adPPYYba, ,adPPYba, 88 ,d8 88 ,adPPYYba, ,adPPYba, 88 ,d8 6 | 88P' "8a 88 "" `Y8 a8" "" 88 ,a8" 88 "" `Y8 a8" "" 88 ,a8" 7 | 88 d8 88 ,adPPPPP88 8b 8888[ 88 ,adPPPPP88 8b 8888[ 8 | 88b, ,a8" 88 88, ,88 "8a, ,aa 88`"Yba, 88 88, ,88 "8a, ,aa 88`"Yba, 9 | 8Y"Ybbd8"' 88 `"8bbdP"Y8 `"Ybbd8"' 88 `Y8a 88 `"8bbdP"Y8 `"Ybbd8"' 88 `Y8a 10 | ,88 11 | 888P" 12 | """ -------------------------------------------------------------------------------- /src/day_12/README.md: -------------------------------------------------------------------------------- 1 | # Number Guessing Game 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_12/number_guess.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_12/logo.py: -------------------------------------------------------------------------------- 1 | LOGO = """ 2 | .__ __. __ __ .___ ___. .______ _______ .______ 3 | | \ | | | | | | | \/ | | _ \ | ____|| _ \ 4 | | \| | | | | | | \ / | | |_) | | |__ | |_) | 5 | | . ` | | | | | | |\/| | | _ < | __| | / 6 | | |\ | | `--' | | | | | | |_) | | |____ | |\ \- 7 | |__| \__| \______/ |__| |__| |______/ |_______|| _| `.__ 8 | 9 | """ -------------------------------------------------------------------------------- /src/day_12/number_guess.py: -------------------------------------------------------------------------------- 1 | # Number Guessing Game 2 | import sys 3 | import random 4 | 5 | sys.path.append('src/day_9') 6 | 7 | from logo import LOGO 8 | from auction_program import clear_console 9 | from colorama import init, Fore 10 | 11 | 12 | def handle_exception(func, error_message): 13 | try: 14 | return func() 15 | except (AssertionError, ValueError): 16 | clear_console() 17 | print(Fore.RED + error_message) 18 | return handle_exception(func, error_message) 19 | 20 | 21 | def get_player_guess(): 22 | player_guess = int(input("Make a guess: ").strip()) 23 | assert 1 <= player_guess <= 100 24 | return player_guess 25 | 26 | 27 | def choose_difficulty(): 28 | 29 | print( 30 | f"Choose a mode: {Fore.BLUE} (1) Easy - {Fore.LIGHTGREEN_EX} (2) Hard - {Fore.RED} (3) Expert: " 31 | ) 32 | choice = int(input().strip()) 33 | mode = "Easy" if choice == 1 else "Hard" if choice == 2 else "Expert" 34 | print(f"{mode} mode activated! Good luck!\n") 35 | 36 | assert choice == 1 or choice == 2 or choice == 3 37 | return choice 38 | 39 | 40 | def computer_picks_random_number(start, end): 41 | return random.randint(start, end) 42 | 43 | 44 | def welcome(): 45 | print("Welcome to the Number Guessing Game\n") 46 | 47 | 48 | def get_player_attempts_by_difficulty(mode): 49 | # key: user difficulty choice choice, value: total attempts 50 | modes = {1: 10, 2: 5, 3: 3} 51 | return modes[mode] 52 | 53 | 54 | def print_user_attempts(player_attempts): 55 | color = Fore.RED if player_attempts <= 3 else Fore.YELLOW 56 | word = 'attempts' if player_attempts > 1 else 'attempt' 57 | print( 58 | color + 59 | f"You have {str(player_attempts)} {word} remaining to guess the number\n" 60 | ) 61 | 62 | 63 | def play_again(): 64 | choice = input("Press enter to play again!").strip() 65 | play_number_guessing_game() if not choice else sys.exit() 66 | 67 | 68 | def play_number_guessing_game(): 69 | start, end, count = 1, 100, 0 70 | 71 | welcome() 72 | target = computer_picks_random_number(start, end) 73 | mode = handle_exception(choose_difficulty, "Please enter a valid mode") 74 | player_attempts = get_player_attempts_by_difficulty(mode) 75 | print(f"I'm thinking of a number from {start} to {end}\n") 76 | 77 | while True: 78 | if player_attempts == 0: 79 | print( 80 | f"No more attempts left, the number was {Fore.BLUE + str(target)}" 81 | ) 82 | break 83 | player_guess = handle_exception( 84 | get_player_guess, f"Please enter a valid number ({start} - {end})") 85 | 86 | if target > player_guess: 87 | print(Fore.GREEN + "Too Low") 88 | elif target < player_guess: 89 | print(Fore.YELLOW + "Too High") 90 | else: 91 | print(f"Correct! The number was {target}") 92 | break 93 | 94 | count += 1 95 | player_attempts -= 1 96 | print_user_attempts(player_attempts) 97 | 98 | play_again() 99 | 100 | 101 | def main(): 102 | init(autoreset=True) 103 | print(Fore.RED + LOGO) 104 | try: 105 | play_number_guessing_game() 106 | except KeyboardInterrupt: 107 | sys.exit() 108 | 109 | 110 | if __name__ == "__main__": 111 | main() 112 | -------------------------------------------------------------------------------- /src/day_13/README.md: -------------------------------------------------------------------------------- 1 | # FizzBuzz 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_13/fizzbuzz.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_13/fizzbuzz.py: -------------------------------------------------------------------------------- 1 | # Fizz Buzz 2 | import sys 3 | import pyttsx3 4 | 5 | from colorama import init, Fore 6 | from logo import LOGO 7 | 8 | 9 | def play_fizz_buzz(limit): 10 | fizzBuzz = 'FizzBuzz' 11 | fizz = 'Fizz' 12 | buzz = 'Buzz' 13 | 14 | engine = pyttsx3.init() 15 | 16 | for i in range(1, limit + 1): 17 | end_line = ', ' if i < limit else '.\n' 18 | if i % 15 == 0: 19 | print(Fore.CYAN + fizzBuzz, end=end_line) 20 | engine.say(fizzBuzz) 21 | elif i % 5 == 0: 22 | print(Fore.YELLOW + buzz, end=end_line) 23 | engine.say(buzz) 24 | elif i % 3 == 0: 25 | print(Fore.GREEN + fizz, end=end_line) 26 | engine.say(fizz) 27 | else: 28 | print(i, end=end_line) 29 | engine.say(i) 30 | engine.runAndWait() 31 | 32 | 33 | def main(): 34 | init(autoreset=True) 35 | print(Fore.RED + LOGO) 36 | try: 37 | play_fizz_buzz(15) 38 | except KeyboardInterrupt: 39 | sys.exit() 40 | 41 | 42 | if __name__ == "__main__": 43 | main() 44 | -------------------------------------------------------------------------------- /src/day_13/logo.py: -------------------------------------------------------------------------------- 1 | LOGO = """ 2 | _____ ____ _____ _____ ____ __ __ _____ _____ 3 | | || || || || \ | | || || | 4 | | __| | | |__/ ||__/ || o )| | ||__/ ||__/ | 5 | | |_ | | | __|| __|| || | || __|| __| 6 | | _] | | | / || / || O || : || / || / | 7 | | | | | | || || || || || | 8 | |__| |____||_____||_____||_____| \__,_||_____||_____| 9 | """ -------------------------------------------------------------------------------- /src/day_14/README.md: -------------------------------------------------------------------------------- 1 | # Higher Lower Game 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_14/higher_lower.py) 4 | 5 | ## Demo: 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/day_14/game_data.py: -------------------------------------------------------------------------------- 1 | GAME_DATA = [{ 2 | 'name': 'Instagram', 3 | 'follower_count': 346, 4 | 'description': 'Social media platform', 5 | 'country': 'United States' 6 | }, { 7 | 'name': 'Cristiano Ronaldo', 8 | 'follower_count': 215, 9 | 'description': 'Footballer', 10 | 'country': 'Portugal' 11 | }, { 12 | 'name': 'Ariana Grande', 13 | 'follower_count': 183, 14 | 'description': 'Musician and actress', 15 | 'country': 'United States' 16 | }, { 17 | 'name': 'Dwayne Johnson', 18 | 'follower_count': 181, 19 | 'description': 'Actor and professional wrestler', 20 | 'country': 'United States' 21 | }, { 22 | 'name': 'Selena Gomez', 23 | 'follower_count': 174, 24 | 'description': 'Musician and actress', 25 | 'country': 'United States' 26 | }, { 27 | 'name': 'Kylie Jenner', 28 | 'follower_count': 172, 29 | 'description': 30 | 'Reality TV personality and businesswoman and Self-Made Billionaire', 31 | 'country': 'United States' 32 | }, { 33 | 'name': 'Kim Kardashian', 34 | 'follower_count': 167, 35 | 'description': 'Reality TV personality and businesswoman', 36 | 'country': 'United States' 37 | }, { 38 | 'name': 'Lionel Messi', 39 | 'follower_count': 149, 40 | 'description': 'Footballer', 41 | 'country': 'Argentina' 42 | }, { 43 | 'name': 'Beyoncé', 44 | 'follower_count': 145, 45 | 'description': 'Musician', 46 | 'country': 'United States' 47 | }, { 48 | 'name': 'Neymar', 49 | 'follower_count': 138, 50 | 'description': 'Footballer', 51 | 'country': 'Brasil' 52 | }, { 53 | 'name': 'National Geographic', 54 | 'follower_count': 135, 55 | 'description': 'Magazine', 56 | 'country': 'United States' 57 | }, { 58 | 'name': 'Justin Bieber', 59 | 'follower_count': 133, 60 | 'description': 'Musician', 61 | 'country': 'Canada' 62 | }, { 63 | 'name': 'Taylor Swift', 64 | 'follower_count': 131, 65 | 'description': 'Musician', 66 | 'country': 'United States' 67 | }, { 68 | 'name': 'Kendall Jenner', 69 | 'follower_count': 127, 70 | 'description': 'Reality TV personality and Model', 71 | 'country': 'United States' 72 | }, { 73 | 'name': 'Jennifer Lopez', 74 | 'follower_count': 119, 75 | 'description': 'Musician and actress', 76 | 'country': 'United States' 77 | }, { 78 | 'name': 'Nicki Minaj', 79 | 'follower_count': 113, 80 | 'description': 'Musician', 81 | 'country': 'Trinidad and Tobago' 82 | }, { 83 | 'name': 'Nike', 84 | 'follower_count': 109, 85 | 'description': 'Sportswear multinational', 86 | 'country': 'United States' 87 | }, { 88 | 'name': 'Khloé Kardashian', 89 | 'follower_count': 108, 90 | 'description': 'Reality TV personality and businesswoman', 91 | 'country': 'United States' 92 | }, { 93 | 'name': 'Miley Cyrus', 94 | 'follower_count': 107, 95 | 'description': 'Musician and actress', 96 | 'country': 'United States' 97 | }, { 98 | 'name': 'Katy Perry', 99 | 'follower_count': 94, 100 | 'description': 'Musician', 101 | 'country': 'United States' 102 | }, { 103 | 'name': 'Kourtney Kardashian', 104 | 'follower_count': 90, 105 | 'description': 'Reality TV personality', 106 | 'country': 'United States' 107 | }, { 108 | 'name': 'Kevin Hart', 109 | 'follower_count': 89, 110 | 'description': 'Comedian and actor', 111 | 'country': 'United States' 112 | }, { 113 | 'name': 'Ellen DeGeneres', 114 | 'follower_count': 87, 115 | 'description': 'Comedian', 116 | 'country': 'United States' 117 | }, { 118 | 'name': 'Real Madrid CF', 119 | 'follower_count': 86, 120 | 'description': 'Football club', 121 | 'country': 'Spain' 122 | }, { 123 | 'name': 'FC Barcelona', 124 | 'follower_count': 85, 125 | 'description': 'Football club', 126 | 'country': 'Spain' 127 | }, { 128 | 'name': 'Rihanna', 129 | 'follower_count': 81, 130 | 'description': 'Musician and businesswoman', 131 | 'country': 'Barbados' 132 | }, { 133 | 'name': 'Demi Lovato', 134 | 'follower_count': 80, 135 | 'description': 'Musician and actress', 136 | 'country': 'United States' 137 | }, { 138 | 'name': "Victoria's Secret", 139 | 'follower_count': 69, 140 | 'description': 'Lingerie brand', 141 | 'country': 'United States' 142 | }, { 143 | 'name': 'Zendaya', 144 | 'follower_count': 68, 145 | 'description': 'Actress and musician', 146 | 'country': 'United States' 147 | }, { 148 | 'name': 'Shakira', 149 | 'follower_count': 66, 150 | 'description': 'Musician', 151 | 'country': 'Colombia' 152 | }, { 153 | 'name': 'Drake', 154 | 'follower_count': 65, 155 | 'description': 'Musician', 156 | 'country': 'Canada' 157 | }, { 158 | 'name': 'Chris Brown', 159 | 'follower_count': 64, 160 | 'description': 'Musician', 161 | 'country': 'United States' 162 | }, { 163 | 'name': 'LeBron James', 164 | 'follower_count': 63, 165 | 'description': 'Basketball player', 166 | 'country': 'United States' 167 | }, { 168 | 'name': 'Vin Diesel', 169 | 'follower_count': 62, 170 | 'description': 'Actor', 171 | 'country': 'United States' 172 | }, { 173 | 'name': 'Cardi B', 174 | 'follower_count': 67, 175 | 'description': 'Musician', 176 | 'country': 'United States' 177 | }, { 178 | 'name': 'David Beckham', 179 | 'follower_count': 82, 180 | 'description': 'Footballer', 181 | 'country': 'United Kingdom' 182 | }, { 183 | 'name': 'Billie Eilish', 184 | 'follower_count': 61, 185 | 'description': 'Musician', 186 | 'country': 'United States' 187 | }, { 188 | 'name': 'Justin Timberlake', 189 | 'follower_count': 59, 190 | 'description': 'Musician and actor', 191 | 'country': 'United States' 192 | }, { 193 | 'name': 'UEFA Champions League', 194 | 'follower_count': 58, 195 | 'description': 'Club football competition', 196 | 'country': 'Europe' 197 | }, { 198 | 'name': 'NASA', 199 | 'follower_count': 56, 200 | 'description': 'Space agency', 201 | 'country': 'United States' 202 | }, { 203 | 'name': 'Emma Watson', 204 | 'follower_count': 56, 205 | 'description': 'Actress', 206 | 'country': 'United Kingdom' 207 | }, { 208 | 'name': 'Shawn Mendes', 209 | 'follower_count': 57, 210 | 'description': 'Musician', 211 | 'country': 'Canada' 212 | }, { 213 | 'name': 'Virat Kohli', 214 | 'follower_count': 55, 215 | 'description': 'Cricketer', 216 | 'country': 'India' 217 | }, { 218 | 'name': 'Gigi Hadid', 219 | 'follower_count': 54, 220 | 'description': 'Model', 221 | 'country': 'United States' 222 | }, { 223 | 'name': 'Priyanka Chopra Jonas', 224 | 'follower_count': 53, 225 | 'description': 'Actress and musician', 226 | 'country': 'India' 227 | }, { 228 | 'name': '9GAG', 229 | 'follower_count': 52, 230 | 'description': 'Social media platform', 231 | 'country': 'China' 232 | }, { 233 | 'name': 'Ronaldinho', 234 | 'follower_count': 51, 235 | 'description': 'Footballer', 236 | 'country': 'Brasil' 237 | }, { 238 | 'name': 'Maluma', 239 | 'follower_count': 50, 240 | 'description': 'Musician', 241 | 'country': 'Colombia' 242 | }, { 243 | 'name': 'Camila Cabello', 244 | 'follower_count': 49, 245 | 'description': 'Musician', 246 | 'country': 'Cuba' 247 | }, { 248 | 'name': 'NBA', 249 | 'follower_count': 47, 250 | 'description': 'Club Basketball Competition', 251 | 'country': 'United States' 252 | }] 253 | -------------------------------------------------------------------------------- /src/day_14/higher_lower.py: -------------------------------------------------------------------------------- 1 | # Higher Lower Game 2 | import sys 3 | import random 4 | import os 5 | 6 | from colorama import init, Fore 7 | from typing_extensions import IntVar 8 | from logo import LOGO, VS_LOGO 9 | from game_data import GAME_DATA 10 | 11 | 12 | def clear_console(): 13 | os.system('cls' if os.name == 'nt' else 'clear') 14 | 15 | 16 | def get_user_answer(string): 17 | try: 18 | answer = input(string).upper().strip()[:1] 19 | assert answer in 'AB' and answer 20 | 21 | except (AssertionError): 22 | print(Fore.RED + 'Please enter a valid answer') 23 | return get_user_answer(string) 24 | 25 | else: 26 | return answer 27 | 28 | 29 | def get_random_choices(data): 30 | compared_data = random.choice(data) 31 | against_data = random.choice(data) 32 | 33 | # to not compare the same data 34 | while compared_data == against_data: 35 | compared_data = random.choice(data) 36 | against_data = random.choice(data) 37 | 38 | return compared_data, against_data 39 | 40 | 41 | def get_game_data(): 42 | return GAME_DATA.copy() 43 | 44 | 45 | def play_again(): 46 | choice = input("Press enter to play again") 47 | return main() if not choice else sys.exit() 48 | 49 | 50 | def get_highest_followers_count(data_1, data_2): 51 | return max(data_1, data_2) 52 | 53 | 54 | def play_higher_lower(): 55 | score = 0 56 | player_is_right = True 57 | starting = True 58 | compared_data = against_data = '' 59 | game_data = get_game_data() 60 | 61 | while player_is_right: 62 | if (starting): 63 | compared_data, against_data = get_random_choices(game_data) 64 | else: 65 | while compared_data == against_data: 66 | against_data = random.choice(game_data) 67 | 68 | compared_info = get_data_info(compared_data) 69 | against_info = get_data_info(against_data) 70 | 71 | compared_followers = compared_info.pop() 72 | against_followers = against_info.pop() 73 | 74 | results = {'A': compared_followers, 'B': against_followers} 75 | 76 | print_data_info(compared_info, 'Compare A: ') 77 | print(VS_LOGO) 78 | print_data_info(against_info, 'Compare B: ') 79 | 80 | user_answer = get_user_answer( 81 | f"\nWho has more followers? Type 'A ' or 'B': ") 82 | 83 | correct_answer = get_highest_followers_count(compared_followers, 84 | against_followers) 85 | user_result = results[user_answer] 86 | 87 | if (user_result) == correct_answer: 88 | clear_console() 89 | print() 90 | score += user_result 91 | compared_data = against_data 92 | starting = False 93 | print(Fore.CYAN + "Correct!") 94 | print(f"\nScore: {score}\n") 95 | 96 | else: 97 | clear_console() 98 | print(Fore.RED + f"Wrong Answer!") 99 | print(f"Score: {str(score)}") 100 | play_again() 101 | break 102 | 103 | 104 | def get_data_info(data): 105 | name = data['name'] 106 | description = data['description'] 107 | country = data['country'] 108 | follower_count = data['follower_count'] 109 | 110 | return [name, description, country, follower_count] 111 | 112 | 113 | def print_data_info(data, string): 114 | name, description, country = data 115 | an_or_a = 'an' if description[0][0] in 'AEIOU' else 'a' 116 | color_string = Fore.RED if 'A' in string else Fore.CYAN 117 | print( 118 | f"{color_string + string} {Fore.YELLOW + name}, {an_or_a} {description}, from {country}." 119 | ) 120 | 121 | 122 | def main(): 123 | init(autoreset=True) 124 | print(Fore.MAGENTA + LOGO) 125 | try: 126 | play_higher_lower() 127 | except KeyboardInterrupt: 128 | sys.exit() 129 | 130 | 131 | if __name__ == "__main__": 132 | print(os.getcwd()) 133 | main() 134 | -------------------------------------------------------------------------------- /src/day_14/logo.py: -------------------------------------------------------------------------------- 1 | LOGO = """ 2 | __ ___ __ 3 | / / / (_)___ _/ /_ ___ _____ 4 | / /_/ / / __ `/ __ \/ _ \/ ___/ 5 | / __ / / /_/ / / / / __/ / 6 | /_/ ///_/\__, /_/ /_/\___/_/ 7 | / / /____/_ _____ _____ 8 | / / / __ \ | /| / / _ \/ ___/ 9 | / /___/ /_/ / |/ |/ / __/ / 10 | /_____/\____/|__/|__/\___/_/ 11 | """ 12 | 13 | VS_LOGO = """ 14 | _ __ 15 | | | / /____ 16 | | | / / ___/ 17 | | |/ (__ ) 18 | |___/____(_) 19 | """ -------------------------------------------------------------------------------- /src/day_15/README.md: -------------------------------------------------------------------------------- 1 | # Coffee Machine 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_15/main.py) 4 | 5 | ## Demo: 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/day_15/coffee.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | from colorama import init, Fore 4 | 5 | 6 | class CoffeeIngredients: 7 | def __init__(self, water: int, milk: int, coffee_beans: int): 8 | self._water = water 9 | self._milk = milk 10 | self._coffee_beans = coffee_beans 11 | 12 | @property 13 | def water(self): 14 | return self._water 15 | 16 | @water.setter 17 | def water(self, new_value): 18 | if (new_value <= 0): 19 | self._water = 0 20 | else: 21 | self._water = new_value 22 | 23 | @property 24 | def milk(self): 25 | return self._milk 26 | 27 | @milk.setter 28 | def milk(self, new_value): 29 | if (new_value <= 0): 30 | self._milk = 0 31 | else: 32 | self._milk = new_value 33 | 34 | @property 35 | def coffee_beans(self): 36 | return self._coffee_beans 37 | 38 | @coffee_beans.setter 39 | def coffee_beans(self, new_value): 40 | if (new_value <= 0): 41 | self._coffee_beans = 0 42 | else: 43 | self._coffee_beans = new_value 44 | 45 | def __repr__(self): 46 | return f"""{Fore.BLUE}Water: {self.water:>12}ml 47 | {Fore.WHITE}Milk: {self.milk:>13}ml 48 | {Fore.LIGHTYELLOW_EX}Coffee beans: {self.coffee_beans:>5}g 49 | """ 50 | 51 | 52 | class Coffee: 53 | def __init__(self, ingredients: CoffeeIngredients, price: float): 54 | self.ingredients = ingredients 55 | self.price = price 56 | 57 | def __repr__(self): 58 | return f"{self.ingredients}{Fore.GREEN}Money: {'$'+ str(self.price):>9}" 59 | 60 | def get_water(self): 61 | return self.ingredients.water 62 | 63 | def get_milk(self): 64 | return self.ingredients.milk 65 | 66 | def get_coffee_beans(self): 67 | return self.ingredients.coffee_beans 68 | 69 | 70 | class Latte(Coffee): 71 | def __init__(self, water, milk, coffee_beans, price): 72 | super().__init__(CoffeeIngredients(water, milk, coffee_beans), price) 73 | self.name = 'Latte' 74 | 75 | def __repr__(self): 76 | return f"Latte:\n\n{Coffee.__repr__(self)}" 77 | 78 | 79 | class Cappuccino(Coffee): 80 | def __init__(self, water, milk, coffee_beans, price): 81 | super().__init__(CoffeeIngredients(water, milk, coffee_beans), price) 82 | self.name = 'Cappuccino' 83 | 84 | def __repr__(self): 85 | return f"Cappuccino:\n\n{Coffee.__repr__(self)}" 86 | 87 | 88 | class Espresso(Coffee): 89 | def __init__(self, water, milk, coffee_beans, price): 90 | super().__init__(CoffeeIngredients(water, milk, coffee_beans), price) 91 | self.name = 'Espresso' 92 | 93 | def __repr__(self): 94 | return f"Espresso:\n\n{Coffee.__repr__(self)}" 95 | 96 | 97 | class CoffeeMachine: 98 | def __init__(self, ingredients: CoffeeIngredients, coffees: list, 99 | total_money: float): 100 | self.ingredients = ingredients 101 | self._total_money = total_money 102 | self.coffees = coffees 103 | 104 | def get_logo(self): 105 | return """ ) ( 106 | ( ) ) 107 | ) ( ( 108 | _______)_ 109 | .-'---------| 110 | ( C|/\/\/\/\/| 111 | '-./\/\/\/\/| 112 | '_________' 113 | '-------' 114 | """ 115 | 116 | def shut_down_coffee_machine(self): 117 | print("The coffee machine is shutting down..") 118 | sys.exit() 119 | 120 | def ask_user_to_pay_coffee(self, coffee_name, price): 121 | try: 122 | user_money = float( 123 | input( 124 | f"{coffee_name} costs ${price:.2f}, please insert the money here: $" 125 | )) 126 | assert user_money >= price 127 | 128 | if (user_money > self.total_money): 129 | print( 130 | Fore.RED + 131 | f"Sorry! I only have ${self.total_money}, please enter a correct amount" 132 | ) 133 | return self.ask_user_to_pay_coffee(coffee_name, price) 134 | except (ValueError, AssertionError): 135 | print(Fore.RED + "Error, please enter a correct amount") 136 | return self.ask_user_to_pay_coffee(coffee_name, price) 137 | 138 | else: 139 | return user_money 140 | 141 | def prepare_coffee(self, coffee_name: str): 142 | for coffee in self.coffees: 143 | if coffee.name == coffee_name: 144 | can_make_coffee = self.check_enough_ingredients_to_make_a_coffee( 145 | coffee) 146 | 147 | if can_make_coffee: 148 | user_money = self.ask_user_to_pay_coffee( 149 | coffee.name, coffee.price) 150 | 151 | user_has_money = self.check_user_has_enough_money( 152 | user_money, 153 | coffee.price, 154 | ) 155 | machine_has_money = self.check_machine_has_enough_money( 156 | user_money) 157 | 158 | if (user_has_money and machine_has_money): 159 | self.make_coffee(coffee, coffee_name) 160 | return self.give_user_change(user_money, coffee) 161 | 162 | else: 163 | return False 164 | 165 | def pause_coffee_machine(self, seconds): 166 | print('...') 167 | time.sleep(seconds) 168 | 169 | def check_machine_has_enough_money(self, user_money): 170 | return self.total_money >= user_money 171 | 172 | def check_user_has_enough_money(self, user_money: float, 173 | coffee_price: float): 174 | return user_money >= coffee_price 175 | 176 | def give_user_change(self, user_money: float, coffee: Coffee): 177 | coffee_price = coffee.price 178 | change = user_money - coffee_price 179 | self.total_money += coffee_price 180 | return change 181 | 182 | def make_coffee(self, coffee: Coffee, coffee_name: str): 183 | print(f"Preparing your {coffee_name}!") 184 | self.pause_coffee_machine(1.5) 185 | print(f"\nHere is your {coffee.name} ☕. Enjoy!") 186 | 187 | coffee_water = coffee.get_water() 188 | coffee_milk = coffee.get_milk() 189 | coffee_beans = coffee.get_coffee_beans() 190 | 191 | self.ingredients.water = self.ingredients.water - coffee_water 192 | self.ingredients.milk = self.ingredients.milk - coffee_milk 193 | self.ingredients.coffee_beans = self.ingredients._coffee_beans - coffee_beans 194 | 195 | def check_enough_ingredients_to_make_a_coffee(self, coffee: Coffee): 196 | total_water = self.ingredients.water 197 | total_milk = self.ingredients.milk 198 | total_coffee_beans = self.ingredients.coffee_beans 199 | 200 | if (total_water < coffee.get_water() or total_water <= 1): 201 | print(Fore.RED + f"Not enough water to make a {coffee.name}") 202 | return False 203 | elif (total_milk < coffee.get_milk() or total_milk <= 1): 204 | print(Fore.RED + f"Not enough milk to make a {coffee.name}") 205 | return False 206 | elif total_coffee_beans < coffee.get_coffee_beans( 207 | ) or total_coffee_beans <= 1: 208 | print(Fore.RED + 209 | f"Not enough coffee beans to make a {coffee.name}") 210 | return False 211 | else: 212 | return True 213 | 214 | def print_report(self): 215 | print("Coffee Machine: \n") 216 | print( 217 | f"{self.ingredients}{Fore.GREEN}Money: {'$'+ str(self.total_money):>12}" 218 | ) 219 | 220 | @property 221 | def total_money(self): 222 | return self._total_money 223 | 224 | @total_money.setter 225 | def total_money(self, new_value): 226 | self._total_money = new_value 227 | -------------------------------------------------------------------------------- /src/day_15/main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import time 4 | from colorama import init, Fore 5 | 6 | from coffee import CoffeeIngredients, CoffeeMachine, Latte, Cappuccino, Espresso 7 | 8 | 9 | def clear_console(): 10 | os.system('cls' if os.name == 'nt' else 'clear') 11 | 12 | 13 | def ask_user_coffee_machine_commands(string, error_msg): 14 | commands = ['1', '2', '3', 'off', 'report'] 15 | 16 | try: 17 | choice = input(string).strip().lower() 18 | assert choice in commands 19 | except (AssertionError, ValueError): 20 | clear_console() 21 | print(Fore.RED + error_msg) 22 | return ask_user_coffee_machine_commands(string, error_msg) 23 | else: 24 | return choice 25 | 26 | 27 | def get_default_coffees(): 28 | coffees = [ 29 | Latte(water=200, milk=150, coffee_beans=24, price=2.5), 30 | Cappuccino(water=250, milk=100, coffee_beans=24, price=3.0), 31 | Espresso(water=50, milk=0, coffee_beans=18, price=1.5), 32 | ] 33 | return coffees 34 | 35 | 36 | def get_default_coffee_ingredients(): 37 | return CoffeeIngredients(water=500, milk=500, coffee_beans=500) 38 | 39 | 40 | def print_coffee_machine_report(coffee_machine): 41 | coffee_machine.print_report() 42 | 43 | 44 | def get_coffee(coffee_machine, coffee_name): 45 | for coffee in coffee_machine.coffees: 46 | if coffee.name == coffee_name: 47 | coffee_machine.check_enough_ingredients_to_make_a_coffee(coffee) 48 | 49 | 50 | def make_user_coffee(coffee_machine: CoffeeMachine, user_choice): 51 | choices_coffees = {'1': 'Latte', '2': 'Espresso', '3': 'Cappuccino'} 52 | change = coffee_machine.prepare_coffee(choices_coffees[user_choice]) 53 | 54 | time.sleep(1.2) 55 | if change: 56 | print(f"\nHere is your change: ${change:.2f}!\n") 57 | 58 | elif change == False: 59 | coffee_name = choices_coffees[user_choice] 60 | if not coffee_machine.ingredients.water: 61 | print(Fore.RED + f"No more water to make a coffee!") 62 | elif not coffee_machine.ingredients.milk: 63 | print(Fore.RED + f"No more milk to make a coffee!") 64 | elif not coffee_machine.ingredients._coffee_beans: 65 | print(Fore.RED + f"No more coffee beans to make a coffee!") 66 | 67 | coffee_machine.print_report() 68 | print("\nSomeone will come to refill the machine, come back later!") 69 | coffee_machine.shut_down_coffee_machine() 70 | else: 71 | return False 72 | 73 | 74 | def ask_user_another_coffee(coffee_machine): 75 | try: 76 | 77 | choice = input( 78 | "Do you want to buy another coffee ? (y/n)").strip().lower()[:1] 79 | assert choice in 'yn' 80 | except AssertionError: 81 | print(Fore.RED + "PLease enter 'y' for yes or 'n' for no\n") 82 | return ask_user_another_coffee(coffee_machine) 83 | else: 84 | return choice 85 | 86 | 87 | def user_interface(coffee_machine): 88 | 89 | clear_console() 90 | 91 | print(Fore.YELLOW + coffee_machine.get_logo()) 92 | 93 | while True: 94 | special_commands = { 95 | 'off': coffee_machine.shut_down_coffee_machine, 96 | 'report': coffee_machine.print_report 97 | } 98 | 99 | choice = ask_user_coffee_machine_commands( 100 | "Choose a coffee to buy: (1) Latte - (2) Espresso - (3) Cappuccino: ", 101 | "Please enter a valid command") 102 | clear_console() 103 | 104 | if choice not in special_commands: 105 | make_user_coffee(coffee_machine, choice) 106 | another_coffee = ask_user_another_coffee(coffee_machine) 107 | if another_coffee == 'y': 108 | clear_console() 109 | user_interface(coffee_machine) 110 | else: 111 | print('Ok bye') 112 | sys.exit() 113 | else: 114 | special_function = special_commands[choice] 115 | special_function() 116 | 117 | 118 | def main(): 119 | coffee_machine = CoffeeMachine( 120 | ingredients=get_default_coffee_ingredients(), 121 | total_money=12, 122 | coffees=get_default_coffees()) 123 | 124 | init(autoreset=True) 125 | try: 126 | user_interface(coffee_machine) 127 | except KeyboardInterrupt: 128 | sys.exit() 129 | 130 | 131 | if __name__ == "__main__": 132 | main() -------------------------------------------------------------------------------- /src/day_16/README.md: -------------------------------------------------------------------------------- 1 | # Tic Tac Toe 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_16/main.py) 4 | 5 | ## Demo: 6 | 7 | -------------------------------------------------------------------------------- /src/day_16/main.py: -------------------------------------------------------------------------------- 1 | import random 2 | import os 3 | import sys 4 | 5 | from functools import partial 6 | from colorama import Fore, init 7 | 8 | from tic_tac_toe import TicTacToe 9 | from user_interface import UserInterface 10 | 11 | 12 | def clear_console(): 13 | os.system('cls' if os.name == 'nt' else 'clear') 14 | 15 | 16 | def get_player_pos(player, ui): 17 | error_message = ui.create_error_message('Please enter a correct position!') 18 | return ui.handle_exception(partial(ui.ask_player_a_position, player), 19 | error_message) 20 | 21 | 22 | def get_player_symbol(player, ui): 23 | clear_console() 24 | error_message = ui.create_error_message( 25 | 'Please enter a correct symbol! Numbers are not allowed') 26 | return ui.handle_exception(partial(ui.ask_player_to_choose_symbol, player), 27 | error_message) 28 | 29 | 30 | def get_player_name(ui): 31 | clear_console() 32 | error_message = ui.create_error_message( 33 | 'Please enter a correct symbol! Numbers are not allowed') 34 | return ui.handle_exception(ui.ask_player_name, error_message) 35 | 36 | 37 | def player_plays(player, player_symbol, game_board, userinterface, rounds): 38 | clear_console() 39 | print(f"Round {rounds}:\n") 40 | game_board.print_board() 41 | print(f"\n{player}, It's your turn: \n") 42 | p1_pos = get_player_pos(player, userinterface) 43 | 44 | while game_board.check_position_is_taken(p1_pos): 45 | clear_console() 46 | print(Fore.RED + "This position is already taken") 47 | game_board.print_board() 48 | p1_pos = get_player_pos(player, userinterface) 49 | 50 | game_board.put_player_symbol(player_symbol, p1_pos) 51 | 52 | 53 | def get_winner(game_board, scores): 54 | if (game_board.check_winner()): 55 | winner = game_board.get_winner_name_by_symbol() 56 | scores[winner] += 1 57 | print(f"\n{winner} wins!") 58 | return 59 | 60 | 61 | def play_game(p1_name, p2_name, userinterface, scores, rounds): 62 | clear_console() 63 | 64 | players_symbols = userinterface.players_symbols 65 | 66 | has_won = False 67 | game_board = TicTacToe(players_symbols) 68 | 69 | players = [p1_name, p2_name] 70 | index = random.randint(0, 1) 71 | 72 | first_player = players.pop(index) 73 | other_player = players.pop() 74 | 75 | p1_symbol = players_symbols[first_player] 76 | p2_symbol = players_symbols[other_player] 77 | 78 | while True: 79 | player_plays(first_player, p1_symbol, game_board, userinterface, 80 | rounds) 81 | has_won = game_board.check_winner() 82 | 83 | if has_won: 84 | clear_console() 85 | game_board.print_board() 86 | get_winner(game_board, scores) 87 | break 88 | 89 | if (game_board.is_board_full()): 90 | clear_console() 91 | game_board.print_board() 92 | print("\nIt's a draw!") 93 | break 94 | 95 | player_plays(other_player, p2_symbol, game_board, userinterface, 96 | rounds) 97 | has_won = game_board.check_winner() 98 | 99 | if has_won: 100 | clear_console() 101 | game_board.print_board() 102 | get_winner(game_board, scores) 103 | break 104 | 105 | if (game_board.is_board_full()): 106 | print("\nIt's a draw!") 107 | break 108 | 109 | clear_console() 110 | print_scores(scores) 111 | rounds += 1 112 | play_again(p1_name, p2_name, userinterface, scores, rounds) 113 | 114 | 115 | def play_again(p1_name, p2_name, userinterface, scores, rounds): 116 | choice = input("\nPress enter to play again!").strip() 117 | if not choice: 118 | play_game(p1_name, p2_name, userinterface, scores, rounds) 119 | else: 120 | sys.exit() 121 | 122 | 123 | def print_scores(scores): 124 | for k, v in scores.items(): 125 | print(f"\n{k}, score: {Fore.BLUE} {v}") 126 | 127 | 128 | def user_interface(): 129 | user_interface = UserInterface() 130 | 131 | p1_name = get_player_name(user_interface) 132 | p2_name = get_player_name(user_interface) 133 | 134 | p1_symbol = get_player_symbol(p1_name, user_interface) 135 | p2_symbol = get_player_symbol(p2_name, user_interface) 136 | 137 | user_interface.print_symbol(p1_name, p1_symbol) 138 | user_interface.print_symbol(p2_name, p2_symbol) 139 | 140 | scores = {p1_name: 0, p2_name: 0} 141 | rounds = 1 142 | play_game(p1_name, p2_name, user_interface, scores, rounds) 143 | 144 | 145 | def main(): 146 | try: 147 | user_interface() 148 | except KeyboardInterrupt: 149 | pass 150 | 151 | 152 | if __name__ == "__main__": 153 | init(autoreset=True) 154 | main() 155 | -------------------------------------------------------------------------------- /src/day_16/tic_tac_toe.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from colorama import Fore, init 3 | 4 | 5 | class TicTacToe: 6 | def __init__(self, player_symbols): 7 | self.board = self.create_board() 8 | self.player_symbols = player_symbols 9 | self.symbols_counts = {k: 0 for k in self.player_symbols.values()} 10 | self.symbol_winner = 'None' 11 | self.board_positions = { 12 | 1: [0, 0], 13 | 2: [0, 1], 14 | 3: [0, 2], 15 | 4: [1, 0], 16 | 5: [1, 1], 17 | 6: [1, 2], 18 | 7: [2, 0], 19 | 8: [2, 1], 20 | 9: [2, 2] 21 | } 22 | 23 | self.winning_positions = [ 24 | # rows 25 | [[0, 0], [0, 1], [0, 2]], 26 | [[1, 0], [1, 1], [1, 2]], 27 | [[2, 0], [2, 1], [2, 2]], 28 | # cols 29 | [[0, 0], [1, 0], [2, 0]], 30 | [[0, 1], [1, 1], [2, 1]], 31 | [[0, 2], [1, 2], [2, 2]], 32 | # diagonals 33 | [[0, 0], [1, 1], [2, 2]], 34 | [[2, 0], [1, 1], [0, 2]], 35 | ] 36 | 37 | def create_board(self): 38 | return [[' ', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' ']] 39 | 40 | def get_board(self, board): 41 | return (Fore.YELLOW + 42 | "\n---------\n".join([" | ".join(i) for i in board])) 43 | 44 | def check_position_is_taken(self, pos): 45 | row, col = self.board_positions[pos] 46 | return not self.board[row][col] == ' ' 47 | 48 | def put_player_symbol(self, player_symbol, pos): 49 | row, col = self.board_positions[pos] 50 | self.board[row][col] = player_symbol 51 | 52 | def is_board_full(self): 53 | for row, col in self.board_positions.values(): 54 | board_item = self.board[row][col] 55 | if (board_item.isspace()): 56 | return False 57 | return True 58 | 59 | def print_board(self): 60 | print(self.get_board(self.board)) 61 | 62 | def get_winner_name_by_symbol(self): 63 | symbols_players = {k: v for (v, k) in self.player_symbols.items()} 64 | if self.symbol_winner in symbols_players: 65 | winner = symbols_players[self.symbol_winner] 66 | return winner 67 | 68 | def check_winner(self): 69 | p1_list = [] 70 | p2_list = [] 71 | 72 | p1_symbol, p2_symbol = self.player_symbols.values() 73 | 74 | for winning_position in self.winning_positions: 75 | for pos in winning_position: 76 | row, col = pos 77 | item = self.board[row][col] 78 | if item == p1_symbol: 79 | p1_list.append(1) 80 | elif item == p2_symbol: 81 | p2_list.append(1) 82 | 83 | if len(p1_list) == 3: 84 | self.symbol_winner = p1_symbol 85 | return True 86 | 87 | if len(p2_list) == 3: 88 | self.symbol_winner = p2_symbol 89 | return True 90 | 91 | p1_list.clear() 92 | p2_list.clear() 93 | 94 | return False 95 | -------------------------------------------------------------------------------- /src/day_16/user_interface.py: -------------------------------------------------------------------------------- 1 | from colorama import Fore, init 2 | from tic_tac_toe import TicTacToe 3 | import random 4 | 5 | 6 | class UserInterface: 7 | def __init__(self): 8 | self.players_symbols = {} 9 | self.player_count = 1 10 | 11 | def ask_player_name(self): 12 | player_name = input(f"Player {self.player_count}: ").strip().title() 13 | assert len(player_name) 14 | 15 | if player_name in self.players_symbols: 16 | print(Fore.RED + 17 | "This name is already taken! Please choose another one") 18 | return self.ask_player_name() 19 | 20 | self.players_symbols[player_name] = '' 21 | self.player_count += 1 22 | return player_name 23 | 24 | def check_player_names(self, player): 25 | return player in self.players_symbols 26 | 27 | def create_error_message(self, error_message): 28 | return Fore.RED + error_message 29 | 30 | def handle_exception(self, function, error_message): 31 | try: 32 | return function() 33 | except (AssertionError, ValueError): 34 | print(error_message) 35 | return self.handle_exception(function, error_message) 36 | 37 | def ask_player_to_choose_symbol(self, player): 38 | symbol = '' 39 | if player == 'Bot': 40 | symbol = random.choice(['o', 'x']).upper() 41 | else: 42 | symbol = input( 43 | f"\n{player}, Choose a symbol for the game: ").upper().strip() 44 | assert not symbol.isdigit() and len(symbol) == 1 45 | if (self.check_symbols(symbol)): 46 | print(Fore.RED + 47 | "This symbol is taken, please choose another one\n") 48 | return self.ask_player_to_choose_symbol(player) 49 | else: 50 | self.players_symbols[player] = symbol 51 | return symbol 52 | 53 | def ask_player_a_position(self, player): 54 | if player == 'Bot': 55 | return random.randint(1, 9) 56 | else: 57 | pos = input(f"Choose a position: ").strip() 58 | assert 1 <= int(pos) <= 9 59 | return int(pos) 60 | 61 | def print_symbol(self, player, symbol): 62 | print(f"{player} plays with {symbol}\n") 63 | 64 | def check_symbols(self, symbol): 65 | return symbol in self.players_symbols.values() 66 | -------------------------------------------------------------------------------- /src/day_17/README.md: -------------------------------------------------------------------------------- 1 | # Quiz Program 2 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_17/main.py) 3 | 4 | ## Demo: 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/day_17/main.py: -------------------------------------------------------------------------------- 1 | # Quiz 2 | import os 3 | import sys 4 | import requests 5 | 6 | from colorama import Fore, init 7 | 8 | from question import Question 9 | from quiz import Quiz 10 | 11 | 12 | def get_questions_data_from(url): 13 | response = requests.get(url) 14 | return response.json()['results'] 15 | 16 | 17 | def clear_console(): 18 | os.system('cls' if os.name == 'nt' else 'clear') 19 | 20 | 21 | def get_questions_from(questions_dict): 22 | question_objects = [] 23 | 24 | for q in questions_dict: 25 | question = remove_unreadable_parts(q['question']) 26 | correct_answer = remove_unreadable_parts(q['correct_answer']) 27 | incorrect_answers = remove_unreadable_parts(q['incorrect_answers']) 28 | 29 | question_objects.append( 30 | Question(question, correct_answer, incorrect_answers)) 31 | return question_objects 32 | 33 | 34 | def run_quiz(quiz: Quiz): 35 | clear_console() 36 | print(quiz) 37 | 38 | while True: 39 | question_object = quiz.get_user_a_question() 40 | correct_answer = question_object.correct_answer 41 | # question = question_object.question 42 | incorrect_answers = question_object.incorrect_answers 43 | quiz.display_list_of_possible_answers(incorrect_answers, 44 | correct_answer) 45 | user_answer = quiz.ask_user_an_answer("Answer: ") 46 | result = quiz.get_result_from_user_answer(user_answer, correct_answer) 47 | 48 | string_false_answer = f"{Fore.RED}False!\n{Fore.WHITE}The correct answer is:{Fore.GREEN} {correct_answer}\n" 49 | string_correct_answer = f"{Fore.GREEN}Correct!\n" 50 | 51 | if result: 52 | clear_console() 53 | print("*" * 55) 54 | print(string_correct_answer) 55 | quiz.player_score += 1 56 | 57 | else: 58 | clear_console() 59 | print(string_false_answer) 60 | quiz.player_lives -= 1 61 | print("*" * 55) 62 | 63 | if quiz.check_user_has_done_every_question(): 64 | clear_console() 65 | print( 66 | f"{Fore.BLUE} Congratulations! You finished the whole Quiz without losing!!" 67 | ) 68 | quiz.print_player_score() 69 | break 70 | 71 | if not quiz.player_lives: 72 | quiz.print_player_score() 73 | print( 74 | f"{Fore.RED}No more lives left...{Fore.RESET} Do you want to try again? (y/n)" 75 | ) 76 | play_again() 77 | quiz.print_player_score() 78 | 79 | 80 | def play_again(): 81 | choice = input().strip().lower() 82 | return main() if choice == 'y' else sys.exit() 83 | 84 | 85 | def remove_unreadable_parts(string): 86 | if '&' in string and ';' in string: 87 | start = string.index('&') 88 | end = string.index(';') 89 | word = string[start:end + 1] 90 | result = string.replace(word, '') 91 | return result 92 | else: 93 | return string 94 | 95 | 96 | def remove_unreadable_parts_from_list(question_objects): 97 | for q in question_objects: 98 | for string in q.incorrect_answers: 99 | index = q.incorrect_answers.index(string) 100 | q.incorrect_answers[index] = remove_unreadable_parts(string) 101 | 102 | 103 | def main(): 104 | init(autoreset=True) 105 | # file_path = os.path.join(os.getcwd(), 'src', 'day_17', 'data.txt') 106 | quiz_data = get_questions_data_from( 107 | "https://opentdb.com/api.php?amount=48&category=18") 108 | 109 | question_objects = get_questions_from(quiz_data) 110 | remove_unreadable_parts_from_list(question_objects) 111 | 112 | quiz = Quiz(question_objects) 113 | run_quiz(quiz) 114 | 115 | 116 | if __name__ == "__main__": 117 | main() -------------------------------------------------------------------------------- /src/day_17/question.py: -------------------------------------------------------------------------------- 1 | class Question: 2 | def __init__(self, question: str, correct_answer: str, 3 | incorrect_answers: list): 4 | self._question = question 5 | self._correct_answer = correct_answer 6 | self._incorrect_answers = incorrect_answers 7 | 8 | def __repr__(self): 9 | return f"\nQuestion: {str(self._question)}\nAnswer: {str(self._correct_answer)}\nIncorrect Answers{self._incorrect_answers}" 10 | 11 | @property 12 | def question(self): 13 | return str(self._question) 14 | 15 | @property 16 | def correct_answer(self): 17 | return str(self._correct_answer) 18 | 19 | @property 20 | def incorrect_answers(self): 21 | return self._incorrect_answers 22 | -------------------------------------------------------------------------------- /src/day_17/quiz.py: -------------------------------------------------------------------------------- 1 | import random 2 | from colorama import Fore, init 3 | 4 | 5 | class Quiz: 6 | def __init__(self, question_objects: list): 7 | self.question_objects = question_objects 8 | self.track_questions = [] 9 | self.question_counter = 0 10 | self.player_score = 0 11 | self.random_string_colors = [ 12 | Fore.BLUE, Fore.GREEN, Fore.MAGENTA, Fore.WHITE, Fore.YELLOW 13 | ] 14 | self.numbers_answers = {} 15 | self.player_lives = 3 16 | 17 | init(autoreset=True) 18 | 19 | def display_list_of_possible_answers(self, incorrect_answers, 20 | correct_answer): 21 | possible_answers = incorrect_answers.copy() 22 | possible_answers.append(correct_answer) 23 | 24 | random.shuffle(possible_answers) 25 | 26 | for index, answer in enumerate(possible_answers): 27 | index += 1 28 | print(f"\n{Fore.WHITE}{str(index)} - {Fore.YELLOW}{answer}") 29 | self.numbers_answers[index] = answer 30 | print() 31 | 32 | def __repr__(self): 33 | return """ 34 | 88 35 | "" 36 | 37 | ,adPPYb,d8 88 88 88 888888888 38 | a8" `Y88 88 88 88 a8P" 39 | 8b 88 88 88 88 ,d8P' 40 | "8a ,d88 "8a, ,a88 88 ,d8" 41 | `"YbbdP'88 `"YbbdP'Y8 88 888888888 42 | 88 43 | 88 """ 44 | 45 | def get_random_question(self): 46 | question = None 47 | while question is None or question in self.track_questions: 48 | if (self.check_user_has_done_every_question()): 49 | break 50 | question = random.choice(self.question_objects) 51 | 52 | self.track_questions.append(question) 53 | return question 54 | 55 | def check_user_has_done_every_question(self): 56 | return len(self.track_questions) == len(self.question_objects) 57 | 58 | def get_random_color_for_string(self): 59 | return random.choice(self.random_string_colors) 60 | 61 | def get_user_a_question(self): 62 | self.question_counter += 1 63 | color = self.get_random_color_for_string() 64 | question_object = self.get_random_question() 65 | question = question_object.question 66 | print(f"\n{color}Question {self.question_counter}:") 67 | print(f"\n{question}\n") 68 | return question_object 69 | 70 | def get_number_key_from_correct_answer(self, correct_answer): 71 | for number, answer in self.numbers_answers.items(): 72 | if answer == correct_answer: 73 | return number 74 | 75 | def get_result_from_user_answer(self, user_answer, correct_answer): 76 | answer_number = self.get_number_key_from_correct_answer(correct_answer) 77 | return True if answer_number == user_answer else False 78 | 79 | def ask_user_an_answer(self, message): 80 | try: 81 | answer = int(input(message).strip()) 82 | 83 | assert answer in self.numbers_answers 84 | except (AssertionError, ValueError): 85 | print(Fore.RED + "Please choose a correct number") 86 | return self.ask_user_an_answer(message) 87 | else: 88 | return answer 89 | 90 | def print_player_score(self): 91 | print(f"Score: {self.player_score}/{self.question_counter}") -------------------------------------------------------------------------------- /src/day_18/README.md: -------------------------------------------------------------------------------- 1 | # Dot Painting 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_18/art.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_18/art.py: -------------------------------------------------------------------------------- 1 | import random 2 | import colorgram 3 | 4 | from turtle import Turtle, Screen 5 | 6 | 7 | def create_pen(shape, color, speed): 8 | pen = Turtle() 9 | pen.shape(shape) 10 | pen.color(color) 11 | pen.speed(speed) 12 | 13 | return pen 14 | 15 | 16 | def get_colors_from_image(image_path, n_colors): 17 | colors_list = [] 18 | 19 | for color_object in colorgram.extract(image_path, n_colors): 20 | r, g, b = color_object.rgb 21 | colors_list.append((r, g, b)) 22 | return colors_list 23 | 24 | 25 | def get_random_unique_color(colors): 26 | color = random.choice(colors) 27 | return color 28 | 29 | 30 | def draw_art(pen): 31 | image_path = 'src/day_18/images/dots.jpg' 32 | n_colors = 35 33 | colors = get_colors_from_image(image_path, n_colors) 34 | n = 10 35 | x = -280 36 | y = -200 37 | 38 | move_pen(pen, x, y) 39 | 40 | while n: 41 | for _ in range(10): 42 | color = get_random_unique_color(colors) 43 | print(color) 44 | pen.color(color) 45 | 46 | move_forward(pen, 50) 47 | pen.dot(20) 48 | y += 50 49 | move_pen(pen, x, y) 50 | n -= 1 51 | 52 | 53 | def move_forward(pen, distance): 54 | pen.penup() 55 | pen.forward(distance) 56 | pen.pendown() 57 | 58 | 59 | def move_pen(pen, x, y): 60 | pen.penup() 61 | pen.goto(x, y) 62 | pen.pendown() 63 | 64 | 65 | def main(): 66 | app = Screen() 67 | app.colormode(255) 68 | 69 | pen = create_pen('classic', 'black', 'fast') 70 | pen.hideturtle() 71 | 72 | draw_art(pen) 73 | 74 | app.mainloop() 75 | 76 | 77 | if __name__ == "__main__": 78 | main() -------------------------------------------------------------------------------- /src/day_18/images/dots.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_18/images/dots.jpg -------------------------------------------------------------------------------- /src/day_19/README.md: -------------------------------------------------------------------------------- 1 | # Turtle Race Game 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_19/main.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_19/images/race.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_19/images/race.gif -------------------------------------------------------------------------------- /src/day_19/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import random 3 | import sys 4 | import time 5 | 6 | from turtle import Turtle, Screen 7 | from player import Player 8 | 9 | 10 | def get_player_bet_amount(player, app): 11 | player.set_player_bet( 12 | int( 13 | app.numinput(title="Place your bet!", 14 | prompt="Bet amount", 15 | minval=1, 16 | maxval=player.balance))) 17 | 18 | 19 | def get_player_turtle_color(player, app, colors): 20 | colors = get_colors() 21 | turtle_colors = ', '.join([i for i in colors]) 22 | 23 | try: 24 | color = (app.textinput( 25 | title="Choose a turtle", 26 | prompt=f"Which turtle will win the race !?\n{turtle_colors}") 27 | ).lower().strip() 28 | assert color in colors 29 | player.set_player_turtle_color(color) 30 | except AssertionError: 31 | get_player_turtle_color(player, app, colors) 32 | 33 | 34 | def move_turtles(turtles, max_distance): 35 | for turtle in turtles: 36 | move_turtle_randomly(turtle, max_distance) 37 | if turtle_has_passed_finish_line(turtle): 38 | return turtle 39 | return False 40 | 41 | 42 | def move_turtle_randomly(turtle, max_distance): 43 | n = random.randint(0, max_distance) 44 | turtle.forward(n) 45 | 46 | 47 | def place_turtle_to_pos(turtle, x, y): 48 | turtle.penup() 49 | turtle.goto(x, y) 50 | 51 | 52 | def get_turtles(colors): 53 | turtles = [] 54 | for color in colors: 55 | turtle = Turtle(shape='turtle') 56 | turtle.color(color) 57 | turtle.turtlesize(2) 58 | turtles.append(turtle) 59 | return turtles 60 | 61 | 62 | def get_colors(): 63 | return [ 64 | 'red', 65 | 'blue', 66 | 'yellow', 67 | 'green', 68 | 'orange', 69 | 'white', 70 | ] 71 | 72 | 73 | def setup_app(app): 74 | app.listen() 75 | app.title("Turtle Race") 76 | app.setup(width=600, height=600) 77 | app.bgpic("src/day_19/images/race.gif") 78 | app.bgcolor('black') 79 | 80 | 81 | def move_turtles_to_starting_positions(turtles): 82 | x = -230 83 | y = -200 84 | 85 | for turtle in turtles: 86 | place_turtle_to_pos(turtle, x, y) 87 | y += 80 88 | 89 | 90 | def check_user_won_bet(winner_color, player): 91 | if winner_color == player.turtle_color: 92 | player.player_wins() 93 | return True 94 | return False 95 | 96 | 97 | def play_again(app, player): 98 | app.reset() 99 | app.bgpic("src/day_19/images/race.gif") 100 | response = app.textinput( 101 | title="Play", prompt=f"Do you want to play again?").lower().strip() 102 | if response == 'yes': 103 | race(app, player) 104 | else: 105 | say_bye(app) 106 | 107 | 108 | def turtle_has_passed_finish_line(turtle): 109 | return turtle.xcor() >= 190 110 | 111 | 112 | def race(app, player): 113 | current_balance_coordinates = (130, 260) 114 | winner_coordinates = (-230, 200) 115 | 116 | balance_pen = set_pen('white', current_balance_coordinates) 117 | winner_pen = set_pen('white', winner_coordinates) 118 | 119 | display_user_balance(balance_pen, player) 120 | 121 | colors = get_colors() 122 | turtles = get_turtles(colors) 123 | 124 | get_player_turtle_color(player, app, colors) 125 | get_player_bet_amount(player, app) 126 | 127 | move_turtles_to_starting_positions(turtles) 128 | 129 | while True: 130 | winner = move_turtles(turtles, max_distance=20) 131 | if winner: 132 | balance_pen.clear() 133 | display_winner(winner_pen, winner) 134 | winner_color = winner.pencolor() 135 | check_user_won_bet(winner_color, player) 136 | display_user_balance(balance_pen, player) 137 | time.sleep(3) 138 | break 139 | 140 | if player.balance_is_zero(): 141 | say_bye(app) 142 | else: 143 | play_again(app, player) 144 | 145 | 146 | def display_user_balance(pen, player): 147 | pen.write(f"Balance: ${player.balance}", font=("Arial", 10, "normal")) 148 | 149 | 150 | def say_bye(app): 151 | app.reset() 152 | pen = set_pen('white') 153 | pen.write('Bye bye', font=('Arial', 20, 'normal')) 154 | time.sleep(3) 155 | sys.exit() 156 | 157 | 158 | def set_pen(color, coordinates=(-230, 200)): 159 | x, y = coordinates 160 | pen = Turtle() 161 | pen.pendown 162 | pen.goto(x, y) 163 | pen.pendown 164 | pen.hideturtle() 165 | pen.color(color) 166 | return pen 167 | 168 | 169 | def get_winner_message(color): 170 | return f"{color.title()} turtle wins the race!" 171 | 172 | 173 | def display_winner(pen, winner, coordinates=(-230, 220)): 174 | color = winner.pencolor() 175 | pen = set_pen('white', coordinates) 176 | pen.write(get_winner_message(color), font=('Arial', 12, 'normal')) 177 | 178 | 179 | def main(): 180 | try: 181 | player = Player(balance=100) 182 | app = Screen() 183 | setup_app(app) 184 | race(app, player) 185 | app.mainloop() 186 | except: 187 | sys.exit() 188 | 189 | 190 | if __name__ == "__main__": 191 | main() -------------------------------------------------------------------------------- /src/day_19/player.py: -------------------------------------------------------------------------------- 1 | class Player: 2 | def __init__(self, balance): 3 | self.balance = balance 4 | self.turtle_color = None 5 | self.current_bet = 0 6 | 7 | def set_player_bet(self, bet_amount): 8 | self.current_bet = bet_amount 9 | self.balance -= bet_amount 10 | self.balance_is_zero() 11 | 12 | def balance_is_zero(self): 13 | if self.balance <= 0: 14 | self.balance = 0 15 | return True 16 | return False 17 | 18 | def set_player_turtle_color(self, color): 19 | self.turtle_color = color 20 | 21 | def player_wins(self): 22 | self.balance += self.current_bet * 2 23 | -------------------------------------------------------------------------------- /src/day_2/README.md: -------------------------------------------------------------------------------- 1 | # Tip Calculator 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_2/tip_calculator.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_2/tip_calculator.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | # Tip Calculator 4 | 5 | 6 | def run_tip_calculator(): 7 | print("Welcome to the tip calculator.") 8 | 9 | total_bill = float(input("What was the total bill?\n$")) 10 | check_bill(total_bill) 11 | 12 | percentage_tip = check_percentage( 13 | int(input("Choose a percentage tip you would like to give:\n"))) 14 | 15 | total_people = check_people( 16 | int(input("How many people to split the bill?\n"))) 17 | 18 | total_to_pay = calculate_tip(total_bill, percentage_tip, total_people) 19 | 20 | print(f"You have to pay ", end='') if total_people == 1 else print( 21 | f"Each person should pay ", end='') 22 | 23 | print(f"${total_to_pay:.2f}") 24 | 25 | 26 | def calculate_tip(total_bill, percentage_tip, total_people): 27 | percentage = percentage_tip / 100 * total_bill 28 | total = (total_bill + percentage) / total_people 29 | return total 30 | 31 | 32 | def check_bill(total): 33 | if total <= 0: 34 | print("It's on the house!") 35 | sys.exit() 36 | 37 | 38 | def check_people(total): 39 | return 1 if total <= 0 else total 40 | 41 | 42 | def check_percentage(total): 43 | return 0 if total <= 0 else total 44 | 45 | 46 | def main(): 47 | run_tip_calculator() 48 | 49 | 50 | if __name__ == "__main__": 51 | main() -------------------------------------------------------------------------------- /src/day_20/README.md: -------------------------------------------------------------------------------- 1 | # Snake Game 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_20/main.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_20/food.py: -------------------------------------------------------------------------------- 1 | import random 2 | from turtle import Turtle 3 | 4 | 5 | class Food(Turtle): 6 | def __init__(self): 7 | super().__init__() 8 | self.shape('square') 9 | self.color('red') 10 | self.penup() 11 | self.pensize(1) 12 | self.speed(0) 13 | self.got_to_random_pos() 14 | 15 | def got_to_random_pos(self): 16 | x, y = self.get_random_pos() 17 | self.goto(x, y) 18 | 19 | def get_random_pos(self): 20 | x = random.randint(-550, 550) 21 | y = random.randint(-350, 350) 22 | return x, y 23 | -------------------------------------------------------------------------------- /src/day_20/main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | 4 | from turtle import Turtle, Screen 5 | from snake import Snake 6 | from food import Food 7 | 8 | # Constants variables 9 | SCORE_X_Y_COORDINATES = (0, 270) 10 | GAME_OVER_X_Y_COORDINATES = (0, 100) 11 | 12 | FONT_PEN_SETTINGS = ('ROBOTO', 30, 'normal') 13 | FONT_SCORE_PEN_SETTINGS = ('ROBOTO', 15, 'normal') 14 | 15 | 16 | def play_again(app, snake): 17 | pen = create_pen(GAME_OVER_X_Y_COORDINATES) 18 | choice = app.textinput("Play again", 19 | "Do you want to play again?").lower().strip() 20 | 21 | snake.score = 0 22 | 23 | return main() if choice == 'yes' else pen.write( 24 | 'BYE!', align='center', 25 | font=FONT_PEN_SETTINGS), time.sleep(2), app.bye() 26 | 27 | 28 | def setup_app(app): 29 | app.setup(width=1200, height=800) 30 | app.bgcolor('#07470B') 31 | app.title('Snake Game') 32 | 33 | 34 | def play_game(app, snake: Snake): 35 | apple = Food() 36 | pen_score = create_pen(SCORE_X_Y_COORDINATES) 37 | pen_game_over = create_pen(GAME_OVER_X_Y_COORDINATES) 38 | 39 | while True: 40 | app.update() 41 | if snake.check_player_passed_game_boundaries((580, 380)): 42 | display_user_score(pen_score, snake) 43 | display_game_over(pen_game_over) 44 | time.sleep(1) 45 | pen_game_over.clear() 46 | play_again(app, snake) 47 | break 48 | display_user_score(pen_score, snake) 49 | 50 | pen_score.clear() 51 | speed_time = snake.speed 52 | snake.move(snake.get_player_key(app)) 53 | time.sleep(speed_time) 54 | if (snake.eat(apple)): 55 | apple.got_to_random_pos() 56 | 57 | 58 | def ask_user_to_pick_snake_color_for(body_part, app): 59 | colors = [ 60 | 'red', 61 | 'blue', 62 | 'green', 63 | 'white', 64 | 'pink', 65 | 'orange', 66 | 'purple', 67 | 'black', 68 | ] 69 | colors_text = ' - '.join(colors) 70 | try: 71 | color = app.textinput( 72 | title="Choose a color", 73 | prompt= 74 | f"Pick a color for the {body_part} of the snake\n{colors_text}" 75 | ).lower().strip() 76 | 77 | assert color in colors or color == '' 78 | except AssertionError: 79 | return ask_user_to_pick_snake_color_for(body_part, app) 80 | else: 81 | return color 82 | 83 | 84 | def create_pen(coords): 85 | x, y = coords 86 | pen = Turtle() 87 | pen.penup() 88 | pen.goto(x, y) 89 | pen.color('white') 90 | pen.hideturtle() 91 | return pen 92 | 93 | 94 | def display_user_score(pen, snake): 95 | pen.write(f"Score: {snake.score}", 96 | align="center", 97 | font=FONT_SCORE_PEN_SETTINGS) 98 | 99 | 100 | def display_game_over(pen): 101 | pen.write(f"GAME OVER", align="center", font=FONT_PEN_SETTINGS) 102 | 103 | 104 | def change_snake_colors(app, snake): 105 | body_color = ask_user_to_pick_snake_color_for('body', app) 106 | if body_color: snake.change_snake_body_color(body_color) 107 | 108 | head_color = ask_user_to_pick_snake_color_for('head', app) 109 | if head_color: snake.change_snake_head_color(head_color) 110 | 111 | 112 | def main(): 113 | app = Screen() 114 | app.reset() 115 | app.clear() 116 | 117 | setup_app(app) 118 | app.tracer(0) 119 | snake = Snake() 120 | 121 | change_snake_colors(app, snake) 122 | 123 | app.listen() 124 | play_game(app, snake) 125 | app.mainloop() 126 | 127 | 128 | if __name__ == "__main__": 129 | try: 130 | main() 131 | except: 132 | sys.exit() 133 | -------------------------------------------------------------------------------- /src/day_20/snake.py: -------------------------------------------------------------------------------- 1 | from tkinter.constants import LEFT 2 | from turtle import Turtle, down 3 | from functools import partial 4 | 5 | # Constant Variables 6 | DOWN_VAL = 270 7 | UP_VAL = 90 8 | LEFT_VAL = 180 9 | RIGHT_VAL = 0 10 | 11 | KEYS = 'wasd' 12 | PADDING = 23 13 | # ----------------------------------------------------------------------------------- 14 | 15 | 16 | class Snake: 17 | def __init__( 18 | self, 19 | body_color='lime green', 20 | head_color='green yellow', 21 | shape='square', 22 | size=20, 23 | body_length=3, 24 | ): 25 | self.snake_body = [] 26 | self.speed = 0.12 27 | self._create_snake_body(body_color, head_color, shape, size, 28 | body_length) 29 | self._place_snake_to_starting_position() 30 | self.snake_head = self.snake_body[0] 31 | self.count_eaten = 0 32 | self.score = 0 33 | self.play_again = False 34 | 35 | def change_snake_head_color(self, color='green yellow'): 36 | self.snake_head.color(color) 37 | 38 | def change_snake_body_color(self, color='lime green'): 39 | for body in self.snake_body[1:]: 40 | body.color(color) 41 | 42 | def _create_snake_body(self, color, head_color, shape, size, body_length): 43 | for i in range(body_length): 44 | turtle = self._create_body_part(shape, head_color, size, color, i) 45 | self.snake_body.append(turtle) 46 | 47 | def _create_body_part(self, shape, head_color, size, color, index=-1): 48 | turtle = Turtle(shape=shape) 49 | turtle.color(head_color) if index == 0 else turtle.color(color) 50 | turtle.pensize(size) 51 | turtle.speed(0) 52 | turtle.penup() 53 | return turtle 54 | 55 | def _place_snake_to_starting_position(self, coords=(0, 0)): 56 | x, y = coords 57 | for body in self.snake_body: 58 | body.goto(x, y) 59 | x -= PADDING 60 | 61 | def eat(self, food: Turtle): 62 | if self.snake_head.distance(food) <= 25: 63 | self.count_eaten += 1 64 | self.grow() 65 | self.score += 1 66 | print('Yummy!') 67 | return True 68 | return False 69 | 70 | def grow(self): 71 | body_part = self.snake_body[-1].clone() 72 | body_part2 = self.snake_body[-1].clone() 73 | self.snake_body.extend([body_part, body_part2]) 74 | 75 | if self.count_eaten % 2 == 0: 76 | self.speed -= 0.02 77 | if self.speed <= 0.02: 78 | self.speed = 0.02 79 | 80 | def move(self, command, degree=0): 81 | for i in range(len(self.snake_body) - 1, 0, -1): 82 | pos = 0 83 | if (i >= 0): 84 | pos = self.snake_body[i - 1].pos() 85 | x, y = pos 86 | self.snake_body[i].goto(x, y) 87 | commands = { 88 | 'w': self.snake_head.setheading, # up 89 | 'a': self.snake_head.setheading, # left 90 | 's': self.snake_head.setheading, # down 91 | 'd': self.snake_head.setheading, # right 92 | } 93 | if (command in commands): 94 | move_function = commands[command] 95 | if command == 'w': 96 | if self.snake_head.heading() != DOWN_VAL: 97 | move_function(degree) 98 | elif command == 'a': 99 | 100 | if self.snake_head.heading() != RIGHT_VAL: 101 | move_function(degree) 102 | elif command == 's': 103 | if self.snake_head.heading() != UP_VAL: 104 | move_function(degree) 105 | elif command == 'd': 106 | if self.snake_head.heading() != LEFT_VAL: 107 | move_function(degree) 108 | 109 | self.snake_head.forward(PADDING) 110 | 111 | def get_player_key(self, app): 112 | W, A, S, D = KEYS 113 | 114 | app.onkey(partial(self.move, W, UP_VAL), W) 115 | app.onkey(partial(self.move, A, LEFT_VAL), A) 116 | app.onkey(partial(self.move, S, DOWN_VAL), S) 117 | app.onkey(partial(self.move, D, RIGHT_VAL), D) 118 | 119 | def check_player_passed_game_boundaries(self, coords): 120 | x, y = coords 121 | if self.snake_head.xcor() >= x or self.snake_head.xcor( 122 | ) <= -x or self.snake_head.ycor() >= y or self.snake_head.ycor() <= -y: 123 | return True 124 | for body in self.snake_body[1:]: 125 | if self.snake_head.distance(body) <= 20: 126 | return True 127 | -------------------------------------------------------------------------------- /src/day_21/README.md: -------------------------------------------------------------------------------- 1 | # Pong Game 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_21/main.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_21/ball.py: -------------------------------------------------------------------------------- 1 | import random 2 | from turtle import Turtle 3 | 4 | 5 | class Ball(Turtle): 6 | def __init__(self): 7 | super().__init__() 8 | self.color('white') 9 | self.shape('circle') 10 | self.penup() 11 | self.x = 10 12 | self.y = 10 13 | self.speed = 0.04 14 | 15 | def move_ball(self): 16 | x, y = self.pos() 17 | x += self.x 18 | y += self.y 19 | self.goto(x, y) 20 | 21 | def bounce_of_wall(self, walls): 22 | up_wall, down_wall = walls 23 | if (self.ycor() >= up_wall + 30 or self.ycor() <= down_wall - 30): 24 | self.bounce_Y() 25 | 26 | def bounce_Y(self): 27 | self.y *= -1 28 | 29 | def bounce_X(self): 30 | self.x *= -1 31 | self.speed -= 0.005 32 | if self.speed <= 0.01: 33 | self.speed = 0.01 34 | 35 | def ball_scored(self, score, limits): 36 | right_limit, left_limit = limits 37 | if (self.xcor() >= right_limit + 30): 38 | self.reset_ball() 39 | return 'right' 40 | if (self.xcor() <= left_limit - 30): 41 | self.reset_ball() 42 | return 'left' 43 | 44 | def bounce_paddle(self, paddles): 45 | left_paddle, bot_paddle = paddles 46 | 47 | if self.distance(left_paddle) < 40 and self.xcor() < -340: 48 | self.bounce_X() 49 | elif self.distance(bot_paddle) < 40 and self.xcor() > 340: 50 | self.bounce_X() 51 | 52 | def is_ball_out_of_bounds(self, limits): 53 | right, left = limits 54 | if self.xcor() >= right or self.xcor() <= left: 55 | self.reset_ball() 56 | return True 57 | return False 58 | 59 | def reset_ball(self): 60 | self.goto(0, 0) 61 | self.speed = 0.04 62 | self.bounce_X() 63 | -------------------------------------------------------------------------------- /src/day_21/main.py: -------------------------------------------------------------------------------- 1 | import time 2 | import sys 3 | 4 | from turtle import Turtle, Screen 5 | from tkinter import TclError 6 | 7 | from ball import Ball 8 | from score import Score 9 | from paddle import Paddle 10 | 11 | LIMITS_Y = (250, -250) 12 | LIMITS_X = (400, -400) 13 | 14 | 15 | def create_screen(): 16 | game_screen = Screen() 17 | game_screen.setup(width=800, height=600) 18 | game_screen.bgcolor('black') 19 | game_screen.tracer(0) 20 | game_screen.listen() 21 | game_screen.title('Pong Game') 22 | 23 | return game_screen 24 | 25 | 26 | def move_bot(paddle): 27 | paddle.bot_move() 28 | 29 | 30 | def display_score(score): 31 | return score 32 | 33 | 34 | def check_winner(result, score): 35 | if result == 'right': 36 | score.left_score += 1 37 | elif result == 'left': 38 | score.right_score += 1 39 | score.update_score() 40 | 41 | 42 | def ball_moves(ball, left_paddle, bot_paddle, score): 43 | ball.move_ball() 44 | ball.bounce_of_wall(LIMITS_Y) 45 | ball.bounce_paddle((left_paddle, bot_paddle)) 46 | result = ball.ball_scored(score, LIMITS_X) 47 | check_winner(result, score) 48 | 49 | 50 | def play_pong_game(game_screen): 51 | left_paddle = Paddle() 52 | bot_paddle = Paddle() 53 | ball = Ball() 54 | score = Score() 55 | 56 | bot_paddle.place_paddle_to((350, 0)) 57 | left_paddle.place_paddle_to((-350, 0)) 58 | 59 | while True: 60 | score 61 | left_paddle.move_up_down(game_screen, LIMITS_Y) 62 | bot_paddle.bot_move(ball, LIMITS_Y) 63 | 64 | ball_moves(ball, left_paddle, bot_paddle, score) 65 | 66 | time.sleep(ball.speed) 67 | game_screen.update() 68 | 69 | 70 | def main(): 71 | game_screen = create_screen() 72 | play_pong_game(game_screen) 73 | game_screen.mainloop() 74 | 75 | 76 | if __name__ == "__main__": 77 | try: 78 | main() 79 | except TclError: 80 | sys.exit() 81 | -------------------------------------------------------------------------------- /src/day_21/paddle.py: -------------------------------------------------------------------------------- 1 | from turtle import Turtle 2 | from functools import partial 3 | import random 4 | import time 5 | 6 | # constant variables 7 | KEYS = ('Up', 'Down') 8 | 9 | 10 | class Paddle(Turtle): 11 | def __init__(self): 12 | super().__init__() 13 | self.color('white') 14 | self.shape('square') 15 | self.shapesize(4, 0.2, 15) 16 | self.penup() 17 | 18 | def place_paddle_to(self, coords: tuple): 19 | x, y = coords 20 | self.goto(x, y) 21 | 22 | def bot_move(self, ball, limits_Y): 23 | n = random.randint(0, 20) 24 | ball_x, ball_y = ball.pos() 25 | x, y = self.pos() 26 | up_limit, down_limit = limits_Y 27 | 28 | if y >= ball_y: 29 | y -= n 30 | else: 31 | y += n 32 | self.goto(x, y) 33 | 34 | def move_up_down(self, game_screen, limits_Y): 35 | UP, DOWN = KEYS 36 | for key in KEYS: 37 | game_screen.onkey(partial(self._move, key, limits_Y), key) 38 | 39 | def _move(self, key, limits_Y): 40 | x, y = self.pos() 41 | up_limit, down_limit = limits_Y 42 | UP, DOWN = KEYS 43 | 44 | if key == UP: 45 | if y >= up_limit - 20: 46 | y -= 100 47 | self.goto(x, y) 48 | self.goto(x, y + 48) 49 | else: 50 | if y <= down_limit + 25: 51 | y += 100 52 | self.goto(x, y) 53 | self.goto(x, y - 48) 54 | -------------------------------------------------------------------------------- /src/day_21/score.py: -------------------------------------------------------------------------------- 1 | from turtle import Turtle 2 | 3 | 4 | class Score(Turtle): 5 | def __init__(self, color='white'): 6 | super().__init__() 7 | self.color(color) 8 | self.penup() 9 | self.hideturtle() 10 | self.left_score = 0 11 | self.right_score = 0 12 | self.update_score() 13 | 14 | def update_score(self): 15 | self.clear() 16 | self.goto(-100, 200) 17 | self.write_score(self.left_score) 18 | self.goto(100, 200) 19 | self.write_score(self.right_score) 20 | 21 | def write_score(self, score): 22 | self.write(score, align='center', font=('Roboto', 20, 'normal')) 23 | -------------------------------------------------------------------------------- /src/day_22/README.md: -------------------------------------------------------------------------------- 1 | # Crossy Road Game 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_22/main.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_22/car.py: -------------------------------------------------------------------------------- 1 | from turtle import Turtle 2 | 3 | 4 | class Car(Turtle): 5 | def __init__(self, shape, x, y): 6 | super().__init__() 7 | self.shape(shape) 8 | self.penup() 9 | self.goto(x, y) 10 | self.speed = 4 11 | 12 | def run_over_frog(self, frog: Turtle): 13 | if self.distance(frog) < 48: 14 | return True 15 | return False 16 | -------------------------------------------------------------------------------- /src/day_22/display.py: -------------------------------------------------------------------------------- 1 | from turtle import Turtle 2 | 3 | 4 | class Display(Turtle): 5 | def __init__(self, color, x, y): 6 | super().__init__() 7 | self.color(color) 8 | self.penup() 9 | self.hideturtle() 10 | self.goto(x, y) 11 | 12 | def display_score(self, level): 13 | self.clear() 14 | self.write(f'Level: {level}', font=('Consolas', 15, 'normal')) 15 | 16 | def display_game_over(self): 17 | self.clear() 18 | self.write(f'Game Over', 19 | align='center', 20 | font=('Consolas', 20, 'normal')) 21 | -------------------------------------------------------------------------------- /src/day_22/frog.py: -------------------------------------------------------------------------------- 1 | from turtle import Turtle 2 | from functools import partial 3 | 4 | 5 | class Frog(Turtle): 6 | def __init__(self, shape): 7 | super().__init__() 8 | self.shape(shape) 9 | self.penup() 10 | self.go_to_starting_position() 11 | self.lvl = 1 12 | 13 | def reset_lvl(self): 14 | self.lvl = 1 15 | 16 | def go_to_starting_position(self): 17 | self.goto(0, -350) 18 | 19 | def _move(self): 20 | y = self.ycor() + 20 21 | self.goto(0, y) 22 | 23 | def move(self, screen): 24 | """move the frog on up arrow key press""" 25 | screen.onkey(self._move, 'Up') 26 | 27 | def frog_passed_lvl(self, limit): 28 | if self.ycor() >= limit: 29 | self.go_to_starting_position() 30 | self.lvl += 1 31 | return True 32 | return False 33 | -------------------------------------------------------------------------------- /src/day_22/images/bg0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_22/images/bg0.png -------------------------------------------------------------------------------- /src/day_22/images/bg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_22/images/bg1.png -------------------------------------------------------------------------------- /src/day_22/images/bg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_22/images/bg2.png -------------------------------------------------------------------------------- /src/day_22/images/cars/blue_car.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_22/images/cars/blue_car.gif -------------------------------------------------------------------------------- /src/day_22/images/cars/green_car.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_22/images/cars/green_car.gif -------------------------------------------------------------------------------- /src/day_22/images/cars/red_car.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_22/images/cars/red_car.gif -------------------------------------------------------------------------------- /src/day_22/images/cars/yellow_car.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_22/images/cars/yellow_car.gif -------------------------------------------------------------------------------- /src/day_22/images/frog.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_22/images/frog.gif -------------------------------------------------------------------------------- /src/day_22/images/frog3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_22/images/frog3.gif -------------------------------------------------------------------------------- /src/day_22/images/frog4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_22/images/frog4.gif -------------------------------------------------------------------------------- /src/day_22/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | import time 3 | import random 4 | from turtle import Screen 5 | 6 | from car import Car 7 | from frog import Frog 8 | from display import Display 9 | 10 | # constants 11 | IMAGES_PATH = os.path.join(os.getcwd(), 'src', 'day_22', 'images') 12 | BACKGROUND = f"{IMAGES_PATH}/bg2.png" 13 | CARS_IMAGE_PATH = f"{IMAGES_PATH}/cars/" 14 | FROG_IMAGE = f"{IMAGES_PATH}/frog3.gif" 15 | 16 | LIMIT_UP = 300 17 | 18 | # ----------------------------------------------------- 19 | 20 | 21 | def get_cars_images_path(): 22 | """return a list of the paths of every car image""" 23 | onlyfiles = [ 24 | f"{CARS_IMAGE_PATH}{car_file}" 25 | for car_file in os.listdir(CARS_IMAGE_PATH) 26 | if os.path.isfile(os.path.join(CARS_IMAGE_PATH, car_file)) 27 | ] 28 | return onlyfiles 29 | 30 | 31 | def create_screen(title='Crossy Road Game', 32 | width=600, 33 | height=600, 34 | color='white', 35 | bg_image=BACKGROUND): 36 | screen = Screen() 37 | screen.tracer(0) 38 | screen.bgcolor(color) 39 | screen.bgpic(bg_image) 40 | screen.listen() 41 | screen.setup() 42 | screen.title(title) 43 | 44 | return screen 45 | 46 | 47 | def set_screen_car_shapes(screen): 48 | """set the screen to add custom car images""" 49 | cars = get_cars_images_path() 50 | for car in cars: 51 | screen.addshape(car) 52 | 53 | 54 | def teleport(car): 55 | """teleport the car when it goes out of bounds""" 56 | if car.xcor() >= 600: 57 | y = car.ycor() 58 | x = car.xcor() 59 | car.goto(-x, y) 60 | 61 | 62 | def change_car_positions(cars): 63 | range_x_slots = [i for i in range(-280, 300, 80)] 64 | range_y_slots = [i for i in range(-280, 300, 120)] 65 | 66 | for car in cars: 67 | x = random.choice(range_x_slots) 68 | y = random.choice(range_y_slots) 69 | if range_y_slots: 70 | range_x_slots.remove(x) 71 | 72 | car.speed += 2 73 | car.goto(x, y) 74 | 75 | 76 | def play_game(screen): 77 | frog = Frog(FROG_IMAGE) 78 | 79 | cars = create_cars() 80 | cars_2 = create_cars() 81 | cars.extend(cars_2) 82 | 83 | score = Display(color='white', x=-450, y=350) 84 | game_over = Display('white', 0, 0) 85 | 86 | while True: 87 | score.display_score(frog.lvl) 88 | 89 | for car in cars: 90 | car.forward(car.speed) 91 | frog.move(screen) 92 | teleport(car) 93 | 94 | if (frog.frog_passed_lvl(LIMIT_UP)): 95 | random_car = random.choice(cars) 96 | random_car.speed += 1 97 | 98 | change_car_positions(cars) 99 | if car.run_over_frog(frog): 100 | game_over.display_game_over() 101 | return 102 | 103 | screen.update() 104 | time.sleep(0.01) 105 | 106 | 107 | def create_cars(): 108 | car_paths = get_cars_images_path() 109 | cars = [] 110 | 111 | range_x_slots = [i for i in range(-280, 280, 120)] 112 | range_y_slots = [i for i in range(-280, 300, 120)] 113 | 114 | for cp in car_paths: 115 | x = random.choice(range_x_slots) 116 | y = random.choice(range_y_slots) 117 | 118 | if range_y_slots: 119 | range_x_slots.remove(x) 120 | 121 | new_car = Car(cp, x, y) 122 | 123 | cars.append(new_car) 124 | 125 | return cars 126 | 127 | 128 | def main(): 129 | screen = create_screen() 130 | set_screen_car_shapes(screen) 131 | screen.addshape(FROG_IMAGE) 132 | play_game(screen) 133 | screen.mainloop() 134 | 135 | 136 | if __name__ == "__main__": 137 | main() -------------------------------------------------------------------------------- /src/day_23/README.md: -------------------------------------------------------------------------------- 1 | # US map Quiz 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_23/main.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_23/data/50_states.csv: -------------------------------------------------------------------------------- 1 | state,x,y 2 | Alabama,139,-77 3 | Alaska,-204,-170 4 | Arizona,-203,-40 5 | Arkansas,57,-53 6 | California,-297,13 7 | Colorado,-112,20 8 | Connecticut,297,96 9 | Delaware,275,42 10 | Florida,220,-145 11 | Georgia,182,-75 12 | Hawaii,-317,-143 13 | Idaho,-216,122 14 | Illinois,95,37 15 | Indiana,133,39 16 | Iowa,38,65 17 | Kansas,-17,5 18 | Kentucky,149,1 19 | Louisiana,59,-114 20 | Maine,319,164 21 | Maryland,288,27 22 | Massachusetts,312,112 23 | Michigan,148,101 24 | Minnesota,23,135 25 | Mississippi,94,-78 26 | Missouri,49,6 27 | Montana,-141,150 28 | Nebraska,-61,66 29 | Nevada,-257,56 30 | New Hampshire,302,127 31 | New Jersey,282,65 32 | New Mexico,-128,-43 33 | New York,236,104 34 | North Carolina,239,-22 35 | North Dakota,-44,158 36 | Ohio,176,52 37 | Oklahoma,-8,-41 38 | Oregon,-278,138 39 | Pennsylvania,238,72 40 | Rhode Island,318,94 41 | South Carolina,218,-51 42 | South Dakota,-44,109 43 | Tennessee,131,-34 44 | Texas,-38,-106 45 | Utah,-189,34 46 | Vermont,282,154 47 | Virginia,234,12 48 | Washington,-257,193 49 | West Virginia,200,20 50 | Wisconsin,83,113 51 | Wyoming,-134,90 -------------------------------------------------------------------------------- /src/day_23/data/blank_states_img.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_23/data/blank_states_img.gif -------------------------------------------------------------------------------- /src/day_23/main.py: -------------------------------------------------------------------------------- 1 | import pandas 2 | import os 3 | import time 4 | 5 | from functools import partial 6 | from turtle import Turtle, Screen 7 | 8 | IMAGE_PATH = os.path.abspath('./src/day_23/data/blank_states_img.gif') 9 | DATA_PATH = os.path.abspath('./src/day_23/data/50_states.csv') 10 | 11 | 12 | def display_score(pen, score): 13 | pen.goto(-200, 210) 14 | pen.write(f"Score: {score}/50", font=('Arial', 12, 'normal')) 15 | 16 | 17 | def display_lives(pen, lives): 18 | pen.goto(80, 220) 19 | pen.write(f"Lives left: {lives} ", font=('Arial', 8, 'normal')) 20 | 21 | 22 | def get_states_data(): 23 | return pandas.read_csv(DATA_PATH) 24 | 25 | 26 | def create_screen(): 27 | screen = Screen() 28 | screen.bgpic(IMAGE_PATH) 29 | screen.setup(width=700, height=500) 30 | screen.title("US States Quiz") 31 | screen.listen() 32 | return screen 33 | 34 | 35 | def get_state_name_coordinate_dict(states_data): 36 | state_name_coordinates = {} 37 | 38 | states_names = states_data['state'].tolist() 39 | states_x = states_data['x'].tolist() 40 | states_y = states_data['y'].tolist() 41 | 42 | for i in range(len(states_names)): 43 | state_name_coordinates[states_names[i]] = (states_x[i], states_y[i]) 44 | 45 | return state_name_coordinates 46 | 47 | 48 | def get_state_names(states_data): 49 | states_names = states_data['state'].tolist() 50 | return states_names 51 | 52 | 53 | def create_pen(): 54 | pen = Turtle() 55 | pen.penup() 56 | pen.hideturtle() 57 | pen.speed(0) 58 | return pen 59 | 60 | 61 | def play_US_state_quiz(screen): 62 | score = 0 63 | lives = 3 64 | 65 | pen = create_pen() 66 | pen_score = create_pen() 67 | pen_game_over = create_pen() 68 | pen_lives = create_pen() 69 | 70 | states_data = get_states_data() 71 | states_names = get_state_names(states_data) 72 | state_name_coordinates = get_state_name_coordinate_dict(states_data) 73 | 74 | while states_names and lives: 75 | pen_lives.clear() 76 | display_lives(pen_lives, lives) 77 | 78 | user_state_name = ask_user_to_guess_state(screen) 79 | 80 | if check_user_response(user_state_name, states_names): 81 | screen.onclick(partial(write_to_map, pen, user_state_name)) 82 | x, y = state_name_coordinates[user_state_name] 83 | write_to_map(pen, user_state_name, x, y) 84 | states_names.remove(user_state_name) 85 | score += 1 86 | else: 87 | lives -= 1 88 | 89 | pen_score.clear() 90 | 91 | display_score(pen_score, score) 92 | 93 | if not lives: 94 | pen_lives.clear() 95 | display_lives(pen_lives, lives) 96 | 97 | pen_score.clear() 98 | display_game_over(pen_game_over) 99 | display_score(pen_score, score) 100 | time.sleep(2) 101 | pen_game_over.clear() 102 | display_remaining_states(pen, states_names, state_name_coordinates) 103 | 104 | 105 | def display_remaining_states(pen, states_names, state_name_coordinate): 106 | for name in states_names: 107 | x, y = state_name_coordinate[name] 108 | write_to_map(pen, name, x, y) 109 | 110 | 111 | def display_game_over(pen): 112 | pen.goto(0, 0) 113 | pen.write('Game Over', align='center', font=("Arial", 20, 'normal')) 114 | 115 | 116 | def check_user_response(user_state, states): 117 | return user_state in states 118 | 119 | 120 | def main(): 121 | screen = create_screen() 122 | play_US_state_quiz(screen) 123 | screen.mainloop() 124 | 125 | 126 | def ask_user_to_guess_state(screen): 127 | user_choice = screen.textinput(title="", 128 | prompt="Enter state name:").title().strip() 129 | return user_choice 130 | 131 | 132 | def write_to_map(pen, user_state_name, x, y): 133 | pen.goto(x, y) 134 | pen.write(user_state_name, font=('Arial', 5, 'normal')) 135 | 136 | 137 | if __name__ == "__main__": 138 | main() -------------------------------------------------------------------------------- /src/day_24/README.md: -------------------------------------------------------------------------------- 1 | # NATO phonetic alphabet 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_24/main.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_24/data/nato_phonetic_alphabet.csv: -------------------------------------------------------------------------------- 1 | letter,code 2 | A,Alfa 3 | B,Bravo 4 | C,Charlie 5 | D,Delta 6 | E,Echo 7 | F,Foxtrot 8 | G,Golf 9 | H,Hotel 10 | I,India 11 | J,Juliet 12 | K,Kilo 13 | L,Lima 14 | M,Mike 15 | N,November 16 | O,Oscar 17 | P,Papa 18 | Q,Quebec 19 | R,Romeo 20 | S,Sierra 21 | T,Tango 22 | U,Uniform 23 | V,Victor 24 | W,Whiskey 25 | X,X-ray 26 | Y,Yankee 27 | Z,Zulu 28 | , -------------------------------------------------------------------------------- /src/day_24/main.py: -------------------------------------------------------------------------------- 1 | import pandas 2 | import os 3 | import random 4 | import sys 5 | import re 6 | 7 | from functools import partial 8 | from tkinter import TclError 9 | from colorama import Fore, init 10 | from turtle import Turtle, Screen 11 | 12 | FILE_PATH = os.path.abspath( 13 | os.path.join(os.getcwd(), 'src/day_24/data/nato_phonetic_alphabet.csv')) 14 | 15 | 16 | def get_phonetic_alphabet_data_dict_dict_from(file_path): 17 | return pandas.read_csv(file_path, index_col=0, squeeze=True).to_dict() 18 | 19 | 20 | def get_phonetic_alphabet_list(screen): 21 | user_word = get_user_input(screen) 22 | phonetic_alphabet_data_dict = get_phonetic_alphabet_data_dict_dict_from( 23 | FILE_PATH) 24 | words = create_phonetic_alphabet_words_list_from( 25 | user_word, phonetic_alphabet_data_dict) 26 | return words 27 | 28 | 29 | def main(): 30 | try: 31 | init(autoreset=True) 32 | screen = create_screen() 33 | pen = create_pen() 34 | 35 | phonetic_alphabet_list = get_phonetic_alphabet_list(screen) 36 | display_phonetic_alphabet(pen, phonetic_alphabet_list) 37 | 38 | screen.listen() 39 | screen.onclick(partial(run_again, pen)) 40 | screen.mainloop() 41 | 42 | except (TclError): 43 | sys.exit() 44 | 45 | 46 | def run_again(pen, x, y): 47 | pen.goto(x, y) 48 | pen.clear() 49 | main() 50 | 51 | 52 | def write_to_screen(word, directions, pen, pen_color, font_specs): 53 | x, y = directions 54 | font, size, style = font_specs 55 | pen.goto(x, y) 56 | pen.color(pen_color) 57 | pen.write(f"{word}", font=(font, size, style)) 58 | 59 | 60 | def display_phonetic_alphabet(pen, phonetic_alphabet_list): 61 | y = 150 62 | x = -380 63 | white_color = 255, 255, 255 64 | 65 | for word in phonetic_alphabet_list: 66 | 67 | if check_word_passed_y_screen_limit(y) or word == ' ': 68 | x, y = change_directions(x, y) 69 | 70 | colors = get_random_rgb_colors() 71 | first_letter = word[0] 72 | 73 | write_to_screen(word=first_letter, 74 | directions=(x, y), 75 | pen=pen, 76 | pen_color=white_color, 77 | font_specs=('Consolas', 21, 'bold')) 78 | 79 | temp_x = x + 30 80 | 81 | write_to_screen(word=word[1:], 82 | directions=(temp_x, y), 83 | pen=pen, 84 | pen_color=colors, 85 | font_specs=('Consolas', 20, 'italic')) 86 | 87 | y -= 50 88 | 89 | 90 | def check_word_passed_y_screen_limit(y): 91 | return y < -300 92 | 93 | 94 | def change_directions(x, y): 95 | """change (x, y) coordinates""" 96 | x += 200 97 | y = 200 98 | return x, y 99 | 100 | 101 | def create_pen(): 102 | """Create a Turtle object to write on the screen""" 103 | pen = Turtle() 104 | pen.penup() 105 | pen.hideturtle() 106 | pen.speed(0) 107 | return pen 108 | 109 | 110 | def clear_pen(pen): 111 | pen.clear() 112 | 113 | 114 | def create_screen(): 115 | screen = Screen() 116 | screen.setup(width=900, height=600) 117 | screen.title("NATO Phonetic Alphabet") 118 | screen.bgcolor('black') 119 | screen.colormode(255) 120 | return screen 121 | 122 | 123 | def get_random_rgb_colors(): 124 | rgb = [] 125 | for _ in range(3): 126 | color = random.randint(50, 250) 127 | rgb.append(color) 128 | return tuple(rgb) 129 | 130 | 131 | def get_user_input(screen): 132 | user_word = None 133 | try: 134 | user_word = screen.textinput(title="", 135 | prompt="Enter a word").upper().strip() 136 | assert re.match(r'^[a-z A-Z]+$', user_word) is not None 137 | 138 | except (AssertionError, AttributeError): 139 | if user_word is None: 140 | # when the user clicks the Cancel button it will exit without error 141 | sys.exit() 142 | 143 | print(f"{Fore.RED}Only letters allowed!\n") 144 | return get_user_input(screen) 145 | else: 146 | return user_word 147 | 148 | 149 | def create_phonetic_alphabet_words_list_from(user_input, data_dict): 150 | words = [data_dict[i] for i in list(user_input)] 151 | return words 152 | 153 | 154 | if __name__ == "__main__": 155 | main() 156 | -------------------------------------------------------------------------------- /src/day_25/README.md: -------------------------------------------------------------------------------- 1 | # Miles to Km Converter 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_25/main.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_25/main.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | 3 | MILES_TO_KM_VALUE = 1.60934 4 | 5 | 6 | def create_screen(title): 7 | screen = tk.Tk() 8 | screen.title(title) 9 | screen.minsize(width=400, height=200) 10 | screen.config(padx=100, pady=20) 11 | return screen 12 | 13 | 14 | def convert_miles_to_km(miles): 15 | return miles * MILES_TO_KM_VALUE 16 | 17 | 18 | def clear_text_area(text_area): 19 | """clears input text area """ 20 | text_area.delete(0, tk.END) 21 | 22 | 23 | def click_calculate_button(result_label, text_area): 24 | try: 25 | miles = float(text_area.get()) 26 | except Exception: 27 | text_area.delete(0, tk.END) 28 | return 29 | else: 30 | result = convert_miles_to_km(miles) 31 | result_label['text'] = f"{result:.2f}" 32 | 33 | 34 | def main(): 35 | screen = create_screen('Mile to Km') 36 | 37 | # text area 38 | text_area = tk.Entry(width=6) 39 | text_area.focus() 40 | text_area.grid(row=0, column=2, padx=20) 41 | 42 | # bind the enter key to the calculate button 43 | text_area.bind( 44 | "", 45 | lambda event: click_calculate_button(result_label, text_area)) 46 | 47 | # bind the backspace key to the calculate button 48 | text_area.bind("", lambda event: clear_text_area(text_area)) 49 | 50 | # miles label 51 | miles_label = tk.Label(text="Mile") 52 | miles_label.grid(row=0, column=3) 53 | 54 | # converter result label 55 | result_label = tk.Label(text='0') 56 | result_label.grid(row=1, column=2) 57 | 58 | # calculate button 59 | calculate_button = tk.Button( 60 | text="Calculate", 61 | command=lambda: click_calculate_button(result_label, text_area)) 62 | calculate_button.grid(row=2, column=2) 63 | 64 | # km label 65 | km_label = tk.Label(text='Km') 66 | km_label.grid(row=1, column=3) 67 | 68 | screen.mainloop() 69 | 70 | 71 | if __name__ == "__main__": 72 | main() 73 | -------------------------------------------------------------------------------- /src/day_26/README.md: -------------------------------------------------------------------------------- 1 | # Pomodoro Timer App 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_26/pomodoro.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_26/images/pomodoro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_26/images/pomodoro.png -------------------------------------------------------------------------------- /src/day_26/main.py: -------------------------------------------------------------------------------- 1 | from pomodoro import PomodoroTimerApp 2 | 3 | 4 | def main(): 5 | pomodoro_app = PomodoroTimerApp() 6 | pomodoro_app.mainloop() 7 | 8 | 9 | if __name__ == "__main__": 10 | main() 11 | -------------------------------------------------------------------------------- /src/day_26/pomodoro.py: -------------------------------------------------------------------------------- 1 | import pyttsx3 as text_to_speech 2 | 3 | from tkinter import Button, Canvas, Label, Tk, PhotoImage 4 | from tkinter.constants import LEFT, TOP 5 | 6 | from pomodoro_settings import PomodoroAppSettings 7 | 8 | 9 | class PomodoroTimerApp(Tk): 10 | def __init__(self): 11 | super().__init__() 12 | self.repetition_number = 0 13 | self.clicked_started_button_count = 0 14 | self.timer_count = None 15 | self.settings = PomodoroAppSettings() 16 | self.tomato_image = PhotoImage(file=self.settings.TOMATO_IMAGE_PATH) 17 | self.work_break_label = Label(text='', 18 | fg=self.settings.GREEN, 19 | bg=self.settings.LIGHT_RED, 20 | font=self.settings.WORK_BREAK_LABEL) 21 | self.work_break_label.pack(side=TOP, pady=0) 22 | 23 | self.canvas = Canvas(width=600, height=600) 24 | self.setup_text_to_speech() 25 | self.setup_pomodoro_screen() 26 | self.setup_canvas_screen() 27 | self.timer_label = self.add_timer_label_for_canvas( 28 | 300, 330, text='25:00', fill='#FFF', font=self.settings.TIMER_FONT) 29 | self.setup_buttons() 30 | 31 | def setup_text_to_speech(self): 32 | self.engine = text_to_speech.init() 33 | voices = self.engine.getProperty('voices') 34 | self.engine.setProperty('voice', voices[1].id) 35 | 36 | def click_start_button(self): 37 | # break out if user clicks the start button multiples times 38 | if self.clicked_started_button_count == 1: 39 | return 40 | self.clicked_started_button_count += 1 41 | 42 | self.start_timer() 43 | 44 | def setup_buttons(self): 45 | self.add_start_button() 46 | self.add_reset_button() 47 | 48 | def add_start_button(self): 49 | button = Button(self, 50 | text="Start", 51 | borderwidth=0, 52 | activeforeground=self.settings.LIGHT_RED, 53 | background='white', 54 | font=self.settings.START_BUTTON_FONT, 55 | command=self.click_start_button) 56 | button.pack(side=LEFT, padx=100) 57 | 58 | def add_reset_button(self): 59 | button = Button(self, 60 | text="Reset", 61 | borderwidth=0, 62 | activeforeground=self.settings.LIGHT_RED, 63 | background='white', 64 | font=self.settings.START_BUTTON_FONT, 65 | command=self.reset_timer) 66 | button.pack(side=TOP) 67 | 68 | def setup_pomodoro_screen(self): 69 | width = self.winfo_screenwidth() 70 | add_spaces = (" " * (int(width) // 50)) 71 | 72 | self.title(f"{add_spaces}Big Pomodoro Timer") 73 | self.config(padx=100, pady=50, background='#F6CFCF') 74 | self.resizable(width=False, height=False) 75 | 76 | def reset_timer(self): 77 | if self.timer_count: 78 | self.after_cancel(self.timer_count) 79 | 80 | self.canvas.itemconfigure(self.timer_label, text="25:00") 81 | self.work_break_label.config(text="") 82 | 83 | self.repetition_number = 0 84 | self.clicked_started_button_count = 0 85 | self.timer_count = None 86 | 87 | def start_timer(self): 88 | self.repetition_number += 1 89 | rep_num = self.repetition_number 90 | 91 | # long break of 25 min 92 | if rep_num % 8 == 0: 93 | text = "It's time for a big break!" 94 | self.work_break_label.config(text="It's time for a big break!", 95 | fg=self.settings.RED) 96 | self.count_down(self.settings.LONG_BREAK_MINUTES) 97 | text_to_speech.speak(text) 98 | 99 | # short break 5 min 100 | elif rep_num % 2 == 0: 101 | text = "It's time for a break!" 102 | self.work_break_label.config(text=text, fg=self.settings.RED) 103 | self.count_down(self.settings.SHORT_BREAK_MINUTES) 104 | text_to_speech.speak(text) 105 | else: 106 | # work time 107 | text = "It's time to work!" 108 | text_to_speech.speak(text) 109 | self.work_break_label.config(text=text, fg=self.settings.GREEN) 110 | self.count_down(self.settings.WORK_MINUTES) 111 | 112 | def count_down(self, count): 113 | if count == -1: 114 | self.start_timer() 115 | else: 116 | minutes = count // 60 117 | seconds = count % 60 118 | 119 | if count < 10: 120 | seconds = f"0{seconds}" 121 | elif int(seconds) < 10: 122 | seconds = f"0{seconds}" 123 | 124 | timer = f"{minutes}:{seconds}" 125 | 126 | self.canvas.itemconfigure(self.timer_label, text=timer) 127 | self.timer_count = self.after(1000, self.count_down, count - 1) 128 | 129 | def setup_canvas_screen(self): 130 | self.canvas.config(background=self.settings.LIGHT_RED, 131 | highlightthickness=0) 132 | self.pack_items_to_canvas() 133 | 134 | def pack_items_to_canvas(self): 135 | self.add_tomato_image_to_canvas() 136 | self.canvas.pack() 137 | 138 | def add_timer_label_for_canvas(self, x, y, text, fill, font): 139 | return self.canvas.create_text(x, y, text=text, fill=fill, font=font) 140 | 141 | def kill_app(self): 142 | self.destroy() 143 | 144 | def add_tomato_image_to_canvas(self): 145 | self.canvas.create_image(300, 300, image=self.tomato_image) 146 | -------------------------------------------------------------------------------- /src/day_26/pomodoro_settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | class PomodoroAppSettings(): 5 | # files 6 | TOMATO_IMAGE_PATH = os.path.join(os.getcwd(), 7 | 'src/day_26/images/pomodoro.png') 8 | # colors 9 | LIGHT_RED = "#F6CFCF" 10 | RED = "#e7305b" 11 | GREEN = "#00a130" 12 | YELLOW = "#f7f5dd" 13 | 14 | # fonts 15 | FONT_NAME = "Ubuntu Mono" 16 | 17 | TIMER_FONT = (FONT_NAME, 35, 'bold') 18 | START_BUTTON_FONT = (FONT_NAME, 15, 'normal') 19 | WORK_BREAK_LABEL = (FONT_NAME, 20, 'bold') 20 | 21 | # timers 22 | WORK_MINUTES = 25 * 60 23 | SHORT_BREAK_MINUTES = 5 * 60 24 | LONG_BREAK_MINUTES = 20 * 60 25 | -------------------------------------------------------------------------------- /src/day_27/README.md: -------------------------------------------------------------------------------- 1 | # Password Manager App 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_27/password_manager.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_27/data/passwords.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_27/data/passwords.txt -------------------------------------------------------------------------------- /src/day_27/file_handler.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | 4 | PASSWORDS_DATA_FILE_PATH = os.path.join(os.getcwd(), 5 | 'src/day_27/data/passwords.txt') 6 | 7 | 8 | class PasswordsDataFileHandler: 9 | def __init__(self): 10 | pass 11 | 12 | def save_passwords_data_to_file(self, passwords_data): 13 | """save passwords_data to the passwords file in a JSON format""" 14 | data_to_write = None 15 | website, email, password = passwords_data 16 | new_passwords_data = {website: {"email": email, "password": password}} 17 | 18 | updated_passwords_data = self.update_passwords_data_file( 19 | new_passwords_data) 20 | 21 | if updated_passwords_data: 22 | data_to_write = updated_passwords_data 23 | else: 24 | data_to_write = new_passwords_data 25 | 26 | with open(PASSWORDS_DATA_FILE_PATH, 'w') as password_data_file: 27 | json.dump(data_to_write, password_data_file, indent=4) 28 | 29 | def update_passwords_data_file(self, new_passwords_data): 30 | try: 31 | with open(PASSWORDS_DATA_FILE_PATH) as password_data_file: 32 | password_data = json.load(password_data_file) 33 | password_data.update(new_passwords_data) 34 | except: 35 | return False 36 | else: 37 | return password_data 38 | -------------------------------------------------------------------------------- /src/day_27/images/pass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_27/images/pass.png -------------------------------------------------------------------------------- /src/day_27/main.py: -------------------------------------------------------------------------------- 1 | from password_manager import PasswordManager 2 | 3 | 4 | def main(): 5 | PasswordManager() 6 | 7 | 8 | if __name__ == "__main__": 9 | main() 10 | -------------------------------------------------------------------------------- /src/day_27/password_generator.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | class PasswordGenerator: 5 | def __init__(self): 6 | 7 | self.lower_letters_list = [chr(i) for i in range(97, 123)] 8 | self.letters_list = [i.upper() for i in self.lower_letters_list 9 | ] + self.lower_letters_list 10 | 11 | self.numbers_list = [i for i in range(10)] 12 | self.symbols_list = [ 13 | '!', 14 | '#', 15 | '$', 16 | '%', 17 | '&', 18 | '(', 19 | ')', 20 | '*', 21 | '+', 22 | '.', 23 | '-', 24 | '=', 25 | ] 26 | 27 | def append_random_character_to_password_from(self, lst, random_number, 28 | password_list): 29 | for _ in range(random_number): 30 | password_list.append(str(random.choice(lst))) 31 | 32 | def generate_password(self): 33 | password_list = [] 34 | 35 | letters_count = random.randint(8, 10) 36 | symbols_count = random.randint(2, 4) 37 | numbers_count = random.randint(2, 4) 38 | 39 | self.append_random_character_to_password_from(self.letters_list, 40 | letters_count, 41 | password_list) 42 | self.append_random_character_to_password_from(self.symbols_list, 43 | symbols_count, 44 | password_list) 45 | self.append_random_character_to_password_from(self.numbers_list, 46 | numbers_count, 47 | password_list) 48 | 49 | random.shuffle(password_list) 50 | 51 | return ''.join(password_list) 52 | -------------------------------------------------------------------------------- /src/day_27/password_manager.py: -------------------------------------------------------------------------------- 1 | import os 2 | import tkinter as tk 3 | import tkinter.messagebox as messagebox 4 | 5 | from tkinter import PhotoImage, Tk, Canvas 6 | from PIL import Image, ImageTk 7 | from password_generator import PasswordGenerator 8 | from file_handler import PasswordsDataFileHandler 9 | 10 | PASSWORD_IMAGE_PATH = os.path.join(os.getcwd(), 'src/day_27/images/pass.png') 11 | PASSWORDS_DATA_FILE_PATH = os.path.join(os.getcwd(), 12 | 'src/day_27/data/passwords.txt') 13 | 14 | 15 | class PasswordManager(Tk): 16 | def __init__(self): 17 | super().__init__() 18 | self.canvas = Canvas(width=200, height=150) 19 | self.password_generator = PasswordGenerator() 20 | self.file_handler = PasswordsDataFileHandler() 21 | self.website = None 22 | self.email = None 23 | self.password = None 24 | self.password_entry = None 25 | self.entries = [] 26 | self.passwords_data = [] 27 | self.config_app() 28 | self.mainloop() 29 | 30 | def generate_password(self): 31 | self.password_entry.delete(0, tk.END) 32 | password = self.password_generator.generate_password() 33 | self.password_entry.insert(0, string=password) 34 | return password 35 | 36 | def ask_user_to_save_current_data(self): 37 | try: 38 | website, email, password = self.passwords_data 39 | assert website and email and password 40 | except (AssertionError): 41 | messagebox.showerror(title="Error", 42 | message='Some fields are empty!') 43 | return 44 | else: 45 | is_ok = messagebox.askokcancel( 46 | title="Save", 47 | message= 48 | f"Website: {website}\nEmail: {email}\nPassword: {password}\n\nDo you want to save?" 49 | ) 50 | return is_ok 51 | 52 | def delete_entry_inputs(self): 53 | for entry in self.entries: 54 | entry.delete(0, tk.END) 55 | 56 | def click_submit_button(self): 57 | self.append_data_to_passwords_data() 58 | if self.ask_user_to_save_current_data(): 59 | self.append_passwords_data_to_file() 60 | self.delete_entry_inputs() 61 | 62 | self.passwords_data.clear() 63 | 64 | def append_passwords_data_to_file(self): 65 | self.file_handler.save_data_to_file(self.passwords_data) 66 | 67 | def append_data_to_passwords_data(self): 68 | for entry in self.entries: 69 | data = entry.get() 70 | self.passwords_data.append(data) 71 | 72 | def config_app(self): 73 | self.set_screen() 74 | self.add_password_image() 75 | self.add_labels() 76 | self.add_text_areas() 77 | self.add_buttons() 78 | 79 | def add_labels(self): 80 | website_label = tk.Label(text='Website:', bg='white') 81 | website_label.grid(row=1, column=0) 82 | 83 | email_label = tk.Label(text='Email:', bg='white') 84 | email_label.grid(row=2, column=0, padx=0) 85 | 86 | password_label = tk.Label(text='Password:', bg='white') 87 | password_label.grid(row=3, column=0) 88 | 89 | def add_text_areas(self): 90 | website_entry = tk.Entry() 91 | website_entry.focus() 92 | website_entry.insert(0, 'https://www.google.com/') 93 | website_entry.grid(row=1, column=1) 94 | 95 | email_entry = tk.Entry() 96 | email_entry.insert(0, 'test@gmail.com') 97 | email_entry.grid(row=2, column=1) 98 | 99 | self.password_entry = tk.Entry() 100 | self.password_entry.grid(row=3, column=1) 101 | 102 | self.entries.extend([website_entry, email_entry, self.password_entry]) 103 | 104 | def add_buttons(self): 105 | submit_button = tk.Button(text="Submit", 106 | borderwidth=1, 107 | command=self.click_submit_button) 108 | submit_button.grid(row=4, column=1, pady=20) 109 | 110 | generate_password = tk.Button(text="Generate Password", 111 | borderwidth=1, 112 | command=self.generate_password) 113 | generate_password.grid(row=4, column=0, pady=20) 114 | 115 | def add_password_image(self): 116 | image = Image.open(PASSWORD_IMAGE_PATH) 117 | image = image.resize((150, 150), Image.ANTIALIAS) 118 | self.password_image = ImageTk.PhotoImage(image) 119 | self.canvas.create_image(100, 80, image=self.password_image) 120 | self.canvas.config(bg='white', borderwidth=0, highlightthickness=0) 121 | self.canvas.grid(row=0, column=1, pady=20) 122 | 123 | def set_screen(self): 124 | self.title(f"Password Manager") 125 | self.config(padx=20, pady=20, background='#FFF') 126 | self.geometry('500x400') 127 | self.resizable(width=False, height=False) 128 | 129 | 130 | def main(): 131 | pm = PasswordManager() 132 | 133 | 134 | if __name__ == "__main__": 135 | main() -------------------------------------------------------------------------------- /src/day_28/README.md: -------------------------------------------------------------------------------- 1 | # FlashCards App 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_28/flash_card.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_28/data/french_words.csv: -------------------------------------------------------------------------------- 1 | French,English 2 | partir,leave 3 | histoire,history 4 | chercher,search 5 | seulement,only 6 | police,police 7 | pensée,thought 8 | aide,help 9 | demande,request 10 | genre,kind 11 | mois,month 12 | frère,brother 13 | laisser,let 14 | car,because 15 | mettre,to put 16 | aucun,no 17 | laisse,leash 18 | eux,them 19 | ville,city 20 | chaque,each 21 | parlé,speak 22 | arrivé,come 23 | devrait,should 24 | bébé,baby 25 | longtemps,long time 26 | heures,hours 27 | vont,will 28 | pendant,while 29 | revoir,meet again 30 | aucune,any 31 | place,square 32 | parler,speak 33 | compris,understood 34 | savais,knew 35 | étaient,were 36 | attention,Warning 37 | voici,here is 38 | pourrais,could 39 | affaire,case 40 | donner,give 41 | type,type 42 | leurs,their 43 | donné,given 44 | train,train 45 | corps,body 46 | endroit,place 47 | yeux,eyes 48 | façon,way 49 | écoute,listen 50 | dont,whose 51 | trouver,find 52 | premier,first 53 | perdu,lost 54 | main,hand 55 | première,first 56 | côté,side 57 | pouvoir,power 58 | vieux,old 59 | sois,be 60 | tiens,here 61 | matin,morning 62 | tellement,so much 63 | enfant,child 64 | point,point 65 | venu,came 66 | suite,after 67 | pardon,sorry 68 | venez,come 69 | devant,in front of 70 | vers,towards 71 | minutes,minutes 72 | demandé,request 73 | chambre,bedroom 74 | mis,placed 75 | belle,beautiful 76 | droit,law 77 | aimerais,would like to 78 | aujourd'hui,today 79 | mari,husband 80 | cause,cause 81 | enfin,finally 82 | espère,hope 83 | eau,water 84 | attendez,Wait 85 | parti,left 86 | nouvelle,new 87 | boulot,job 88 | arrêter,Stop 89 | dirait,would say 90 | terre,Earth 91 | compte,account 92 | donne,given 93 | loin,far 94 | fin,end 95 | croire,believe 96 | chérie,sweetheart 97 | gros,large 98 | plutôt,rather 99 | aura,will have 100 | filles,girls 101 | jouer,to play 102 | bureau,office -------------------------------------------------------------------------------- /src/day_28/flash_card.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import pandas 4 | import random 5 | import tkinter as tk 6 | 7 | CSV_FRENCH_WORDS_FILE_PATH = os.path.join(os.getcwd(), 8 | "src/day_28/data/french_words.csv") 9 | IMAGES_PATH = os.path.join(os.getcwd(), "src/day_28/images/") 10 | 11 | FLASHCARD_IMAGE_PATH = f"{IMAGES_PATH}flash_card.png" 12 | BACK_FLASHCARD_IMAGE_PATH = f"{IMAGES_PATH}back_flash_card.png" 13 | 14 | WRONG_IMAGE_PATH = f"{IMAGES_PATH}wrong.png" 15 | RIGHT_IMAGE_PATH = f"{IMAGES_PATH}right.png" 16 | 17 | BG_COLOR = '#a4dea0' 18 | FONT_NAME = 'MonoLisa-Medium' 19 | FONT_NAME_ITALIC = 'MonoLisa-MediumItalic' 20 | 21 | 22 | class Flashcard(tk.Tk): 23 | def __init__(self): 24 | super().__init__() 25 | # fields 26 | self.french_word = None 27 | self.english_word = None 28 | self.card_title = None 29 | self.card_word = None 30 | 31 | self.change_card_canvas_image = None 32 | 33 | self.french_english_words_dict = pandas.read_csv( 34 | CSV_FRENCH_WORDS_FILE_PATH).to_dict(orient='records') 35 | self.right_or_wrong_button_is_clicked = False 36 | self.clicked_on_canvas_image = False 37 | self.canvas = tk.Canvas(width=700, height=500) 38 | # images 39 | self.flash_card_image = tk.PhotoImage(file=f"{FLASHCARD_IMAGE_PATH}") 40 | self.back_flash_card_image = tk.PhotoImage( 41 | file=f"{BACK_FLASHCARD_IMAGE_PATH}") 42 | self.wrong_card_image = tk.PhotoImage(file=f"{WRONG_IMAGE_PATH}") 43 | self.right_card_image = tk.PhotoImage(file=f"{RIGHT_IMAGE_PATH}") 44 | # methods 45 | self.config_app_screen() 46 | self.add_flash_card_image_to_canvas() 47 | self.add_words_to_canvas() 48 | self.add_right_and_wrong_buttons() 49 | self.mainloop() 50 | 51 | def get_random_flashcard(self) -> dict: 52 | """get a random list of dicts: {French: word, English: word} and return it""" 53 | try: 54 | return random.choice(self.french_english_words_dict) 55 | except IndexError: 56 | sys.exit() 57 | 58 | def remove_known_card_from_french_english_words_dict(self): 59 | temp = self.french_english_words_dict[:] 60 | index = next((index for (index, dic) in enumerate(temp) 61 | if dic["French"] == self.french_word.lower()), None) 62 | if temp: 63 | temp.pop(index) 64 | else: 65 | sys.exit() 66 | self.french_english_words_dict = temp 67 | 68 | def click_right_button(self): 69 | self.right_or_wrong_button_is_clicked = True 70 | self.store_card_words() 71 | self.remove_from_known_card_from_french_english_words_dict() 72 | self.add_flashcard_to_canvas() 73 | 74 | def click_wrong_button(self): 75 | self.right_or_wrong_button_is_clicked = True 76 | self.store_card_words() 77 | self.add_flashcard_to_canvas() 78 | 79 | def click_on_canvas_image(self, event): 80 | self.clicked_on_canvas_image = True 81 | self.add_flashcard_to_canvas() 82 | 83 | def store_card_words(self): 84 | flash_card = self.get_random_flashcard() 85 | french_card_word = flash_card['French'].title() 86 | english_card_word = flash_card['English'].title() 87 | self.french_word = french_card_word 88 | self.english_word = english_card_word 89 | 90 | def add_flashcard_to_canvas(self): 91 | if self.right_or_wrong_button_is_clicked: 92 | self.canvas.itemconfig(self.card_title, 93 | text='French', 94 | fill='black') 95 | self.canvas.itemconfig(self.card_word, 96 | text=self.french_word, 97 | fill='black') 98 | 99 | self.config_canvas_french_card() 100 | self.right_or_wrong_button_is_clicked = False 101 | 102 | elif self.clicked_on_canvas_image: 103 | self.canvas.itemconfig(self.card_title, 104 | text='English', 105 | fill='white') 106 | self.canvas.itemconfig(self.card_word, 107 | text=self.english_word, 108 | fill='white') 109 | self.config_canvas_english_card() 110 | self.clicked_on_canvas_image = False 111 | 112 | def config_canvas_french_card(self): 113 | self.canvas.itemconfigure(self.change_card_canvas_image, 114 | image=self.flash_card_image) 115 | 116 | def config_canvas_english_card(self): 117 | self.canvas.itemconfigure(self.change_card_canvas_image, 118 | image=self.back_flash_card_image) 119 | 120 | def config_app_screen(self): 121 | space = ' ' * 25 122 | self.title(f"Flashcards { space} French - English ") 123 | self.config(padx=50, pady=70, background=BG_COLOR) 124 | self.geometry('800x800') 125 | self.resizable(width=False, height=False) 126 | 127 | def add_flash_card_image_to_canvas(self): 128 | self.change_card_canvas_image = self.canvas.create_image( 129 | 350, 250, image=self.flash_card_image) 130 | self.canvas.bind("", self.click_on_canvas_image) 131 | self.canvas.config(bg=BG_COLOR, highlightthickness=0) 132 | self.canvas.pack() 133 | 134 | def add_words_to_canvas(self): 135 | # Title 136 | cards = self.get_random_flashcard() 137 | 138 | french_word = cards["French"] 139 | english_word = cards["English"] 140 | 141 | self.french_word = french_word 142 | self.english_word = english_word 143 | 144 | self.card_title = self.canvas.create_text(350, 145 | 165, 146 | text="French", 147 | font=(FONT_NAME_ITALIC, 18)) 148 | # Word 149 | self.card_word = self.canvas.create_text(350, 150 | 295, 151 | text=french_word, 152 | font=(FONT_NAME, 30, 'bold')) 153 | 154 | def add_right_and_wrong_buttons(self): 155 | # Right button 156 | right_button = tk.Button(image=self.right_card_image, 157 | highlightthickness=0, 158 | command=self.click_right_button) 159 | right_button.pack(side=tk.RIGHT, padx=100, pady=(50, 0)) 160 | 161 | # Wrong button 162 | wrong_button = tk.Button(image=self.wrong_card_image, 163 | highlightthickness=0, 164 | command=self.click_wrong_button) 165 | wrong_button.pack(side=tk.LEFT, padx=100, pady=(50, 0)) 166 | -------------------------------------------------------------------------------- /src/day_28/images/back_flash_card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_28/images/back_flash_card.png -------------------------------------------------------------------------------- /src/day_28/images/flash_card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_28/images/flash_card.png -------------------------------------------------------------------------------- /src/day_28/images/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_28/images/right.png -------------------------------------------------------------------------------- /src/day_28/images/wrong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_28/images/wrong.png -------------------------------------------------------------------------------- /src/day_28/main.py: -------------------------------------------------------------------------------- 1 | from flash_card import Flashcard 2 | 3 | 4 | def main(): 5 | Flashcard() 6 | 7 | 8 | if __name__ == "__main__": 9 | main() 10 | -------------------------------------------------------------------------------- /src/day_29/README.md: -------------------------------------------------------------------------------- 1 | # Weather Forecast via SMS 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_29/main.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_29/main.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import os 3 | 4 | from twilio.rest import Client 5 | # loads .env secret variables 6 | from dotenv import load_dotenv 7 | load_dotenv() 8 | 9 | WEATHER_API_KEY = os.environ['WEATHER_API_KEY'] 10 | 11 | # city location longitude and latitude 12 | LON = -43.9378 13 | LAT = -19.9208 14 | 15 | # weather API url 16 | URL = f"https://api.openweathermap.org/data/2.5/onecall?lat={LAT}&lon={LON}&appid={WEATHER_API_KEY}" 17 | 18 | 19 | def send_message_with_twilio(weather_msg): 20 | account_sid = os.environ['TWILIO_ACCOUNT_SID'] 21 | auth_token = os.environ['TWILIO_AUTH_TOKEN'] 22 | sender_number = os.environ['SENDER_PHONE_NUMBER'] 23 | receiver_number = os.environ['RECEIVER_PHONE_NUMBER'] 24 | 25 | client = Client(account_sid, auth_token) 26 | message = client.messages.create(body=f'{weather_msg}', 27 | from_=sender_number, 28 | to=receiver_number) 29 | 30 | 31 | def get_12_hours_weather_ids_data(): 32 | """get only the 12 hours of weather data of the day""" 33 | 34 | response = requests.get(URL) 35 | weather_data = response.json() 36 | weather_data_12_hours = weather_data["hourly"][:12] 37 | weather_ids = [i['weather'][0]['id'] for i in weather_data_12_hours] 38 | return weather_ids 39 | 40 | 41 | def get_weather_string_message_from(id_num, weather_status): 42 | 43 | if id_num == 801: 44 | weather_status['is_clear'] = True 45 | return "Today will be a clear day! ☀︎" 46 | 47 | elif 800 <= id_num <= 804: 48 | weather_status['is_cloudy'] = True 49 | return "Today will be a cloudy day! ☁️" 50 | 51 | elif 600 <= id_num <= 622: 52 | weather_status['is_snow'] = True 53 | return "It's going to snow today! ❄️" 54 | 55 | elif 500 <= id_num <= 531: 56 | weather_status['is_rain'] = True 57 | return "It's going to rain today! ☔" 58 | 59 | elif 300 <= id_num <= 321: 60 | weather_status['is_drizzle'] = True 61 | return 'Today will be a drizzle day! 💧' 62 | 63 | elif 200 <= id_num <= 232: 64 | weather_status['is_thunderstorm'] = True 65 | return 'Today we will have a thunderstorm! ⛈' 66 | 67 | 68 | def main(): 69 | weather_status = { 70 | 'is_clear': False, 71 | 'is_cloudy': False, 72 | 'is_snow': False, 73 | 'is_rain': False, 74 | 'is_drizzle': False, 75 | 'is_thunderstorm': False 76 | } 77 | 78 | weather_string_msg = None 79 | 80 | for weather_id in get_12_hours_weather_ids_data(): 81 | weather_string_msg = get_weather_string_message_from( 82 | weather_id, weather_status) 83 | if True in weather_status.values(): 84 | break 85 | 86 | send_message_with_twilio(weather_string_msg) 87 | 88 | 89 | if __name__ == "__main__": 90 | main() 91 | -------------------------------------------------------------------------------- /src/day_3/README.md: -------------------------------------------------------------------------------- 1 | # Treasure Island 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_3/treasure_island.py) 4 | 5 | ## Demo: 6 | 7 | ![Screenshot (296)](https://user-images.githubusercontent.com/52018183/103614532-91896c80-4f07-11eb-8517-5490eb9510e6.png) 8 | -------------------------------------------------------------------------------- /src/day_3/treasure_island.py: -------------------------------------------------------------------------------- 1 | # Treasure Island 2 | 3 | 4 | def start(): 5 | 6 | print("\nWelcome to this mysterious Treasure Island.") 7 | print("\nYour mission is to find the hidden treasure.") 8 | 9 | user_choice = get_user_choice( 10 | '\nYou\'re at a cross road. Where do you want to go? - Type "left" or "right"' 11 | ) 12 | 13 | if user_choice == 'left': 14 | go_left() 15 | elif user_choice == 'right': 16 | go_right() 17 | else: 18 | wrong_choice() 19 | 20 | 21 | def get_user_choice(question): 22 | choice = input(question).lower().strip() 23 | return choice 24 | 25 | 26 | def wait(): 27 | # end game 28 | print( 29 | "\nYou arrive at the island and see a house with 3 doors. One red, one blue, and the last one is purple" 30 | ) 31 | user_choice = get_user_choice( 32 | '\nWhich color do you choose? - Type "red", "green" or "purple"') 33 | 34 | if user_choice == 'red': 35 | print( 36 | "\nThere is a red button in the middle of the room, you press it. The door shuts and locks you inside, a fire starts and you're trapped..." 37 | ) 38 | print_game_over() 39 | elif user_choice == 'green': 40 | print("\nYou found the hidden treasure!") 41 | print(get_treasure()) 42 | 43 | elif user_choice == 'purple': 44 | print( 45 | '\nYou open the door, and a sudden explosion occurs inside the room...' 46 | ) 47 | print_game_over() 48 | else: 49 | wrong_choice() 50 | 51 | 52 | def go_left(): 53 | # go to lake 54 | user_choice = get_user_choice( 55 | '\nYou come to the lake and there\'s an island in the middle do you swim or wait for a boat? - Type "swim" or "wait"' 56 | ) 57 | if user_choice == 'swim': 58 | swim() 59 | elif user_choice == 'wait': 60 | wait() 61 | else: 62 | wrong_choice() 63 | 64 | 65 | def swim(): 66 | # game over 67 | print( 68 | "\nA white shark comes near and bites you in the stomach, you manage to reach the island but you pass out and die." 69 | ) 70 | 71 | 72 | def wrong_choice(): 73 | # game over 74 | print("\nYou don't feel so good and die...") 75 | print_game_over() 76 | 77 | 78 | def print_game_over(): 79 | print("\nGame Over.") 80 | 81 | 82 | def go_right(): 83 | # dies 84 | print( 85 | "\nThere's a giant hole in front of you, you slip... and fall to death" 86 | ) 87 | print_game_over() 88 | 89 | 90 | def get_treasure(): 91 | return """ 92 | ****************B**************I**********I************I*********I*****G************* 93 | _.--. 94 | _.-'_:-'|| 95 | _.-'_.-::::'|| 96 | _.-:'_.-::::::' || 97 | .'`-.-:::::::' || 98 | /.'`;|:::::::' ||_ 99 | || ||::::::' _.;._'-._ 100 | || ||:::::' _.-!oo @.!-._'-. 101 | \'. ||:::::.-!()oo @!()@.-'_.| 102 | '.'-;|:.-'.&$@.& ()$%-'o.'\\U|| 103 | `>'-.!@%()@'@_%-'_.-o _.|'|| 104 | ||-._'-.@.-'_.-' _.-o |'|| 105 | ||=[ '-._.-\\U/.-' o |'|| 106 | || '-.]=|| |'| o |'|| 107 | || || |'| _| '; 108 | || || |'| _.-'_.-' 109 | |'-._ || |'|_.-'_.-' 110 | '-._'-.|| |' `_.-' 111 | '-.||_/.-' 112 | 113 | ****************B**************I**********I************I*********I*****G************* 114 | """ 115 | 116 | 117 | def main(): 118 | start() 119 | 120 | 121 | if __name__ == "__main__": 122 | main() -------------------------------------------------------------------------------- /src/day_30/README.md: -------------------------------------------------------------------------------- 1 | # Best Movies To Watch App 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_30/main.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_30/main.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | import urllib.request 3 | import clipboard 4 | import requests 5 | import random 6 | import re 7 | import io 8 | import sys 9 | 10 | from urllib.error import HTTPError 11 | from bs4 import BeautifulSoup 12 | from PIL import Image, ImageTk 13 | from tkinter import messagebox 14 | 15 | MOVIE_FILE_PATH = 'src/day_30/movies.txt' 16 | 17 | 18 | def paste_movie_title_to_clipboard(movie_title): 19 | messagebox.showinfo(message="The movie title was copied to the clipboard!") 20 | clipboard.copy(movie_title) 21 | 22 | 23 | def ask_user_to_watch_or_skip(movies_and_images, image_label, movie_label): 24 | is_yes = messagebox.askyesno(message='Do you want to watch this movie?') 25 | if not is_yes: 26 | configure_image_and_movie_labels(movies_and_images, image_label, 27 | movie_label) 28 | return ask_user_to_watch_or_skip(movies_and_images, image_label, 29 | movie_label) 30 | else: 31 | return is_yes 32 | 33 | 34 | def configure_image_and_movie_labels(movies_and_images, image_label, 35 | movie_label): 36 | movie, image_url = get_random_movie_and_image(movies_and_images) 37 | image = get_formated_image(image_url) 38 | image_label.configure(image=image) 39 | image_label.image = image 40 | movie_label.configure(text=movie) 41 | 42 | 43 | def remove_unicode_characters_from(string): 44 | string_encode = string.encode("ascii", "ignore") 45 | string_decode = string_encode.decode() 46 | return string_decode 47 | 48 | 49 | def get_url_images(soup): 50 | images = soup.find_all('img') 51 | image_list = [] 52 | prev = '' 53 | 54 | for image in images: 55 | image_src = (image['src']) 56 | if image_src and image_src.endswith('jpg'): 57 | if len(image_src) <= 52: 58 | # skip if the current image is equal to the previous one 59 | if image_list: 60 | prev = image_list[-1] 61 | if prev == image_src: 62 | continue 63 | 64 | image_list.append(image_src) 65 | 66 | return image_list[0:100] 67 | 68 | 69 | def get_movies(soup): 70 | movies = [] 71 | movies_data = soup.find_all(name='a') 72 | 73 | for movie in movies_data: 74 | movie = movie.getText().strip() 75 | matches = re.match(r'[0-9]+', movie) 76 | if (matches): 77 | movie = remove_unicode_characters_from(movie) 78 | # format the string 79 | point_index = movie.index('.') 80 | movie = f"{movie[0:point_index]}. {movie[point_index+1:]}" 81 | movies.append(movie) 82 | return movies 83 | 84 | 85 | def get_soup_data(): 86 | url = "https://www.timeout.com/newyork/movies/best-movies-of-all-time" 87 | try: 88 | response = requests.get(url) 89 | response.raise_for_status() 90 | html_text = response.text 91 | except HTTPError: 92 | sys.exit() 93 | 94 | soup = BeautifulSoup(html_text, 'html.parser') 95 | return soup 96 | 97 | 98 | def zip_movies_and_images(): 99 | soup = get_soup_data() 100 | images = get_url_images(soup) 101 | movies = get_movies(soup) 102 | 103 | movies_and_images = zip(movies, images) 104 | return movies_and_images 105 | 106 | 107 | def get_app_screen(): 108 | screen = tk.Tk() 109 | screen.title('Best Movies of all time') 110 | screen.geometry('800x600') 111 | return screen 112 | 113 | 114 | def get_formated_image(image_url): 115 | image_url_data = urllib.request.urlopen(image_url) 116 | raw_data = image_url_data.read() 117 | 118 | pilImage = Image.open(io.BytesIO(raw_data)) 119 | pilImage = pilImage.resize((800, 600), Image.ANTIALIAS) 120 | 121 | image = ImageTk.PhotoImage(pilImage) 122 | return image 123 | 124 | 125 | def save_movies_to_file(movies_and_images, filename): 126 | with open(filename, 'w') as movie_file: 127 | for movie, _ in movies_and_images: 128 | movie_file.write(f"{movie}\n") 129 | 130 | 131 | def load_movies_from_file(filename): 132 | with open(filename) as movie_file: 133 | return movie_file.read().splitlines() 134 | 135 | 136 | def get_random_movie_and_image(movies_and_images): 137 | return random.choice(movies_and_images) 138 | 139 | 140 | def main(): 141 | screen = get_app_screen() 142 | movies_and_images = list(zip_movies_and_images()) 143 | save_movies_to_file(movies_and_images, MOVIE_FILE_PATH) 144 | 145 | movie, image_url = get_random_movie_and_image(movies_and_images) 146 | 147 | image = get_formated_image(image_url) 148 | 149 | movie_label = tk.Label(text=movie) 150 | movie_label.pack() 151 | 152 | image_label = tk.Label(image=image) 153 | image_label.pack() 154 | 155 | result = ask_user_to_watch_or_skip(movies_and_images, image_label, 156 | movie_label) 157 | if result: 158 | paste_movie_title_to_clipboard(movie) 159 | screen.after(3000, sys.exit) 160 | 161 | screen.mainloop() 162 | 163 | 164 | if __name__ == "__main__": 165 | main() -------------------------------------------------------------------------------- /src/day_30/movies.txt: -------------------------------------------------------------------------------- 1 | 1. 2001: A Space Odyssey (1968) 2 | 2. The Godfather (1972) 3 | 3. Citizen Kane (1941) 4 | 4. Jeanne Dielman, 23, Quai du Commerce, 1080 Bruxelles (1975) 5 | 5. Raiders of the Lost Ark (1981) 6 | 6. La Dolce Vita (1960) 7 | 7. Seven Samurai (1954) 8 | 8. In the Mood for Love (2000) 9 | 9. There Will Be Blood (2007) 10 | 10. Singin in the Rain (1952) 11 | 11. Goodfellas (1990) 12 | 12. North by Northwest (1959) 13 | 13. Mulholland Drive (2001) 14 | 14. Bicycle Thieves (1948) 15 | 15. The Dark Knight (2008) 16 | 16. City Lights (1931) 17 | 17. Grand Illusion (1937) 18 | 18. His Girl Friday (1940) 19 | 19. The Red Shoes (1948) 20 | 20. Vertigo (1958) 21 | 21. Beau Travail (1999) 22 | 22. The Searchers (1956) 23 | 23. Persona (1966) 24 | 24. Do the Right Thing (1989) 25 | 25. Rashomon (1950) 26 | 26. The Rules of the Game (1939) 27 | 27. Jaws (1975) 28 | 28. Double Indemnity (1944) 29 | 29. The 400 Blows (1959) 30 | 30. Star Wars (1977) 31 | 31. The Passion of Joan of Arc (1928) 32 | 32. Once Upon a Time in the West (1968) 33 | 33. Alien (1979) 34 | 34. Tokyo Story (1951) 35 | 35. Pulp Fiction (1994) 36 | 36. The Truman Show (1998) 37 | 37. Lawrence of Arabia (1962) 38 | 38. Psycho (1960) 39 | 39. Sansho the Bailiff (1954) 40 | 40. Andrei Rublev (1966) 41 | 41. The Umbrellas of Cherbourg (1964) 42 | 42. Chinatown (1974) 43 | 43. The Seventh Seal (1957) 44 | 44. Lost in Translation (2003) 45 | 45. Taxi Driver (1976) 46 | 46. Spirited Away (2001) 47 | 47. Night of the Living Dead (1968) 48 | 48. Battleship Potemkin (1925) 49 | 49. Modern Times (1936) 50 | 50. Breathless (1960) 51 | 51. Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb (1964) 52 | 52. M (1931) 53 | 53. Blade Runner 54 | 54. The Bitter Tears of Petra von Kant (1972) 55 | 55. Rome, Open City (1945) 56 | 56. Nosferatu (1922) 57 | 57. Airplane! (1980) 58 | 58. Under the Skin (2013) 59 | 59. Mad Max: Fury Road (2015) 60 | 60. Apocalypse Now (1979) 61 | 61. Brokeback Mountain (2005) 62 | 62. Duck Soup (1933) 63 | 63. The Blair Witch Project (1999) 64 | 64. All the Presidents Men (1976) 65 | 65. The Apu trilogy (1955, 1956, 1959) 66 | 66. The General (1926) 67 | 67. Eternal Sunshine of the Spotless Mind (2004) 68 | 68. The Texas Chain Saw Massacre (1974) 69 | 69. Come and See (1985) 70 | 70. Heat (1995) 71 | 71. The Shining (1980) 72 | 72. Toy Story (1995) 73 | 73. Killer of Sheep (1977) 74 | 74. A Woman Under the Influence (1974) 75 | 75. Annie Hall (1977) 76 | 76. Some Like It Hot (1959) 77 | 77. Metropolis (1927) 78 | 78. The Maltese Falcon (1941) 79 | 79. This Is Spinal Tap (1984) 80 | 80. It Happened One Night (1934) 81 | 81. Die Hard (1988) 82 | 82. The Conformist (1970) 83 | 83. The Thing (1982) 84 | 84. Daughters of the Dust (1991) 85 | 85. Barry Lyndon (1975) 86 | 86. Raging Bull (1980) 87 | 87. Seven (1995) 88 | 88. Aguirre, the Wrath of God (1972) 89 | 89. The Battle of Algiers (1966) 90 | 90. Women on the Verge of a Nervous Breakdown (1988) 91 | 91. Boyhood (2014) 92 | 92. The Discreet Charm of the Bourgeoisie (1972) 93 | 93. Paths of Glory (1957) 94 | 94. Secrets & Lies (1996) 95 | 95. Sweet Smell of Success (1957) 96 | 96. The Cabinet of Dr. Caligari (1920) 97 | 97. Nashville (1975) 98 | 98. Dont Look Now (1973) 99 | 99. Bonnie and Clyde (1967) 100 | 100. Get Out (2017) 101 | -------------------------------------------------------------------------------- /src/day_31/README.md: -------------------------------------------------------------------------------- 1 | # Wallpaper Bot 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_31/main.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_31/main.py: -------------------------------------------------------------------------------- 1 | import pyautogui 2 | 3 | from selenium import webdriver 4 | from selenium.webdriver import ActionChains 5 | from selenium.webdriver.chrome.service import Service 6 | from selenium.webdriver.common.by import By 7 | 8 | from webdriver_manager.firefox import GeckoDriverManager 9 | from time import sleep 10 | 11 | 12 | WALLPAPERS_URL = "https://dailydevbytes.com/channel/wallpapers" 13 | 14 | 15 | class Keys: 16 | DOWN = "down" 17 | ENTER = "enter" 18 | 19 | 20 | def get_web_driver_for(url): 21 | driver = webdriver.Firefox(service=Service(GeckoDriverManager().install())) 22 | driver.get(url) 23 | return driver 24 | 25 | 26 | def press_key(key, press_count=1): 27 | for _ in range(press_count): 28 | pyautogui.press(key) 29 | 30 | 31 | 32 | def set_wallpaper(driver): 33 | first_image = driver.find_element(By.TAG_NAME, "img") 34 | 35 | action_chains = ActionChains(driver) 36 | action_chains.context_click(first_image).perform() 37 | 38 | press_key(Keys.DOWN, 13) 39 | press_key(Keys.ENTER) 40 | 41 | sleep(2.5) 42 | 43 | press_key(Keys.DOWN, 6) 44 | press_key(Keys.ENTER) 45 | 46 | 47 | def main(): 48 | driver = get_web_driver_for(WALLPAPERS_URL) 49 | set_wallpaper(driver) 50 | 51 | driver.quit() 52 | 53 | 54 | if __name__ == "__main__": 55 | main() 56 | 57 | -------------------------------------------------------------------------------- /src/day_4/README.md: -------------------------------------------------------------------------------- 1 | # Rock Paper Scissors 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_4/rock_paper_scissors.py) 4 | 5 | ## Demo: 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/day_4/rock_paper_scissors.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | import sys 4 | 5 | 6 | def get_game_images(): 7 | rock = ''' 8 | _______ 9 | ---' ____) 10 | (_____) 11 | (_____) 12 | (____) 13 | ---.__(___) 14 | ''' 15 | paper = ''' 16 | _______ 17 | ---' ____)____ 18 | ______) 19 | _______) 20 | _______) 21 | ---.__________) 22 | ''' 23 | 24 | scissors = ''' 25 | _______ 26 | ---' ____)____ 27 | ______) 28 | __________) 29 | (____) 30 | ---.__(___) 31 | ''' 32 | return (rock, paper, scissors) 33 | 34 | 35 | def get_index_from(user_choice): 36 | indexes = {'r': 0, 'p': 1, 's': 2} 37 | return indexes.get(user_choice.lower().strip()[:1], 0) 38 | 39 | 40 | def play_again(points): 41 | main(points) if (choice := 42 | input("Press enter to play again or else to exit") 43 | == '') else sys.exit() 44 | 45 | 46 | def print_game_images(player, computer): 47 | print(f"You chose:") 48 | print(get_game_images()[player]) 49 | time.sleep(1) 50 | 51 | print("Computer chose:") 52 | print(get_game_images()[computer]) 53 | time.sleep(1) 54 | 55 | 56 | def get_game_result(player, computer, points): 57 | 58 | win_combs = { 59 | 0: 2, 60 | 1: 0, 61 | 2: 1, 62 | } 63 | 64 | print_game_images(player, computer) 65 | 66 | if (win_combs[player] == computer): 67 | 68 | points['You'] += 1 69 | 70 | return 'You win!' 71 | 72 | elif (win_combs[computer] == player): 73 | points['Computer'] += 1 74 | 75 | return 'You lose' 76 | 77 | else: 78 | return 'It\'s a Draw!' 79 | 80 | 81 | def print_points(points): 82 | print("TOTAL POINTS:", '\n') 83 | 84 | for player, score in points.items(): 85 | print(f"{player}: {score}\n") 86 | 87 | 88 | def main(points): 89 | 90 | rules = ('Rock', 'Paper', 'Scissors') 91 | 92 | computer_choice = rules.index(random.choice(rules)) 93 | 94 | try: 95 | player_choice = int( 96 | input("Choose Rock (1), Paper (2), or Scissors (3):\n").lower(). 97 | strip()[:1]) - 1 98 | 99 | except (ValueError, IndexError): 100 | player_choice = random.randint(0, 2) 101 | 102 | result = get_game_result(player_choice, computer_choice, points) 103 | 104 | print(result, '\n') 105 | print_points(points) 106 | play_again(points) 107 | 108 | 109 | if __name__ == "__main__": 110 | points = {'You': 0, 'Computer': 0} 111 | 112 | try: 113 | main(points) 114 | 115 | except KeyboardInterrupt: 116 | print('Exit Program') 117 | sys.exit() 118 | -------------------------------------------------------------------------------- /src/day_5/README.md: -------------------------------------------------------------------------------- 1 | # Password Generator 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_5/password_generator.py) 4 | 5 | ## Demo: 6 | 7 | 9 | -------------------------------------------------------------------------------- /src/day_5/password_generator.py: -------------------------------------------------------------------------------- 1 | import random 2 | import string 3 | 4 | 5 | class PasswordGenerator: 6 | def __init__( 7 | self, 8 | letters_amount: int, 9 | symbols_amount: int, 10 | numbers_amount: int, 11 | ): 12 | self.letters_amount = letters_amount 13 | self.symbols_amount = symbols_amount 14 | self.numbers_amount = numbers_amount 15 | 16 | self.letters = list(string.ascii_letters) 17 | self.symbols = list(string.punctuation) 18 | self.numbers = [i for i in range(10)] 19 | 20 | self.password = [] 21 | 22 | def generate_password(self): 23 | self._append_to_password_from(self.letters, self.letters_amount) 24 | self._append_to_password_from(self.symbols, self.symbols_amount) 25 | self._append_to_password_from(self.numbers, self.numbers_amount) 26 | 27 | random.shuffle(self.password) 28 | return ''.join(self.password) 29 | 30 | def _append_to_password_from(self, lst: list, amount: int): 31 | for _ in range(amount): 32 | ch = random.choice(lst) 33 | self.password.append(str(ch)) 34 | -------------------------------------------------------------------------------- /src/day_5/user_interface.py: -------------------------------------------------------------------------------- 1 | from password_generator import PasswordGenerator 2 | 3 | 4 | class UserInterface(): 5 | def __init__(self): 6 | self.nb_letters = self.nb_symbols = self.nb_numbers = None 7 | 8 | def print_welcome(self): 9 | print("Welcome to BIGSECURE Password Generator!!") 10 | 11 | def ask_user_password_details(self): 12 | while True: 13 | try: 14 | self.nb_letters = int( 15 | input( 16 | "How many letters would you like in your password?\n")) 17 | assert self.nb_letters > 0 18 | 19 | self.nb_symbols = int( 20 | input(f"How many symbols would you like?\n")) 21 | assert self.nb_symbols > 0 22 | 23 | self.nb_numbers = int( 24 | input(f"How many numbers would you like?\n")) 25 | assert self.nb_numbers > 0 26 | 27 | except (ValueError, AssertionError): 28 | print("Please enter a valid number") 29 | continue 30 | else: 31 | break 32 | 33 | def generate_password(self): 34 | password = PasswordGenerator(self.nb_letters, self.nb_symbols, 35 | self.nb_numbers).generate_password() 36 | return password 37 | 38 | def run(self): 39 | self.print_welcome() 40 | self.ask_user_password_details() 41 | 42 | print("Here is your new password: ") 43 | print(self.generate_password()) 44 | 45 | 46 | def main(): 47 | ui = UserInterface() 48 | ui.run() 49 | 50 | 51 | if __name__ == "__main__": 52 | main() -------------------------------------------------------------------------------- /src/day_6/README.md: -------------------------------------------------------------------------------- 1 | # Dice Rolling Simulator 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_6/dice_rolling.py) 4 | 5 | ## Demo: 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/day_6/dice.py: -------------------------------------------------------------------------------- 1 | import random 2 | import time 3 | 4 | from collections import Counter 5 | 6 | 7 | class Dice: 8 | def __init__(self, rolling_time=0): 9 | self.rolling_time = rolling_time 10 | self.stats = Counter() 11 | 12 | def print_dice(self, dice_value): 13 | number = 'o ' 14 | string = '-----\n|' + number[dice_value < 1] + ' ' + number[ 15 | dice_value < 3] + '|\n|' + number[dice_value < 5] 16 | print(string + number[dice_value & 1] + string[::-1]) 17 | 18 | def roll_dices(self, dices_number): 19 | dices = dices_number 20 | self.rolling_a_dice(dices) 21 | 22 | def rolling_a_dice(self, dices): 23 | for dice in range(1, dices + 1): 24 | dice_value = random.randrange(6) 25 | self.stats[dice_value + 1] += 1 26 | 27 | print(f"Rolling dice number #{dice}...:\n") 28 | time.sleep(self.rolling_time) 29 | self.print_dice(dice_value) 30 | 31 | def get_dice_stats(self): 32 | return self.stats -------------------------------------------------------------------------------- /src/day_6/main.py: -------------------------------------------------------------------------------- 1 | from user_interface import UserInterface 2 | 3 | 4 | def main(): 5 | UserInterface().run_app() 6 | 7 | 8 | if __name__ == "__main__": 9 | main() -------------------------------------------------------------------------------- /src/day_6/user_interface.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from dice import Dice 4 | 5 | 6 | class UserInterface(): 7 | def run_app(self): 8 | try: 9 | dice = Dice(rolling_time=1) 10 | dices_to_roll = self.ask_user_how_many_dices() 11 | dice_stats = dice.get_dice_stats() 12 | 13 | dice.roll_dices(dices_to_roll) 14 | self.print_stats(dice_stats) 15 | self.play_again() 16 | 17 | except (KeyboardInterrupt): 18 | print('Exit Program') 19 | sys.exit() 20 | 21 | def ask_user_how_many_dices(self): 22 | try: 23 | dices_to_roll = int( 24 | input("How many dices would you like to roll?\n")) 25 | except ValueError: 26 | # recursive calls until the user enters a correct input 27 | print('Please enter a valid number') 28 | self.ask_user_how_many_dices() 29 | else: 30 | return dices_to_roll 31 | 32 | def print_stats(self, results): 33 | sorted_dices = list(sorted(results.items())) 34 | print(" STATS ".center(20, '*')) 35 | 36 | for dice, total in sorted_dices: 37 | print(f"Dice {dice}:\ntotal: {total}\n") 38 | 39 | if len(results) > 3: 40 | lucky_numbers = self.get_lucky_numbers(results) 41 | numbers = self.make_word_plural('number', lucky_numbers) 42 | print(f"Your lucky {numbers} {str(lucky_numbers)}\n") 43 | 44 | def get_lucky_numbers(self, results): 45 | max_val = max(results.values()) 46 | lucky_numbers = [] 47 | 48 | # grab the keys from the max values 49 | for dice, total in results.items(): 50 | if max_val == total: 51 | lucky_numbers.append(str(dice)) 52 | 53 | return ' and '.join(lucky_numbers) if len( 54 | lucky_numbers) == 2 else ', '.join(lucky_numbers) 55 | 56 | def make_word_plural(self, word, condition): 57 | # make a word plural if condition is more than 1 58 | return f"{word}s are" if len(condition) > 1 else f"{word} is" 59 | 60 | def play_again(self): 61 | user_choice = input("Press enter to roll the dice again!") 62 | if user_choice != '': 63 | sys.exit() 64 | else: 65 | self.run_app() 66 | 67 | 68 | if __name__ == "__main__": 69 | ui = UserInterface() 70 | ui.run_app() -------------------------------------------------------------------------------- /src/day_7/README.md: -------------------------------------------------------------------------------- 1 | # Hangman Game 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_7/hangman.py) 4 | 5 | ## Demo: 6 | ![](https://user-images.githubusercontent.com/52018183/104050222-0fc66700-51c5-11eb-8691-e222b7ad0ad6.gif) 7 | -------------------------------------------------------------------------------- /src/day_7/hangman.py: -------------------------------------------------------------------------------- 1 | import random 2 | import pickle 3 | import sys 4 | import os 5 | 6 | from colorama import init, Fore 7 | 8 | 9 | def hangman_pic(): 10 | return [ 11 | ''' 12 | +---+ 13 | | | 14 | | 15 | | 16 | | 17 | | 18 | =========''', ''' 19 | +---+ 20 | | | 21 | O | 22 | | 23 | | 24 | | 25 | =========''', ''' 26 | +---+ 27 | | | 28 | O | 29 | | | 30 | | 31 | | 32 | =========''', ''' 33 | +---+ 34 | | | 35 | O | 36 | /| | 37 | | 38 | | 39 | =========''', ''' 40 | +---+ 41 | | | 42 | O | 43 | /|\\ | 44 | | 45 | | 46 | =========''', ''' 47 | +---+ 48 | | | 49 | O | 50 | /|\\ | 51 | / | 52 | | 53 | =========''', ''' 54 | +---+ 55 | | | 56 | O | 57 | /|\\ | 58 | / \\ | 59 | | 60 | =========''' 61 | ] 62 | 63 | 64 | def get_file_path(*paths): 65 | return os.path.join(os.getcwd(), ''.join(list(paths))) 66 | 67 | 68 | def save_player_score_to(file_name, player_name, score): 69 | scores = get_players_scores_from(file_name) 70 | 71 | with open(get_file_path(file_name), 'wb') as scores_file: 72 | scores[player_name] = score 73 | pickle.dump(scores, scores_file) 74 | 75 | 76 | def create_scores_file(file_name): 77 | if not os.path.isfile(file_name): 78 | with open(get_file_path(file_name), 'wb') as scores_file: 79 | pickle.dump({}, scores_file) 80 | 81 | 82 | def get_players_scores_from(file_name): 83 | with open(get_file_path(file_name), 'rb') as scores_file: 84 | try: 85 | data = pickle.load(scores_file) 86 | except EOFError as error: 87 | return {} 88 | return data 89 | 90 | 91 | def get_words_list(): 92 | with open(os.path.join(os.getcwd(), 'words.txt')) as words_file: 93 | words = words_file.read().strip().split() 94 | return words 95 | 96 | 97 | def get_string_word(word): 98 | return ''.join(word).upper() 99 | 100 | 101 | # def check_keyboardInterrupt(callback): 102 | # # check if the player exits the terminal with (control + C) or other if true he can exit without error 103 | # try: 104 | # return callback() 105 | # except KeyboardInterrupt as error: 106 | # print("Exit program") 107 | # sys.exit() 108 | 109 | 110 | def remove_player(name, players_scores, file_name): 111 | del players_scores[name] 112 | with open(get_file_path(file_name), 'wb') as scores_file: 113 | pickle.dump(players_scores, scores_file) 114 | 115 | 116 | def remove_last_player(players_scores, file_name): 117 | players_scores.popitem() 118 | with open(get_file_path(file_name), 'wb') as scores_file: 119 | pickle.dump(players_scores, scores_file) 120 | 121 | 122 | def ask_player_letter(): 123 | letter = input("Enter a letter:\n").strip().upper()[:1] 124 | return letter 125 | 126 | 127 | def make_word_plural_or_singular(condition, word): 128 | plural_word = word 129 | 130 | if word.endswith('s'): 131 | plural_word = word + 'es' 132 | else: 133 | plural_word = word + 's' 134 | 135 | word = plural_word if condition > 1 else word 136 | return word 137 | 138 | 139 | def print_guesses_left(player_guesses): 140 | guess_color = Fore.YELLOW if int(player_guesses) > 3 else Fore.RED 141 | print( 142 | f'You have {guess_color + str(player_guesses)} {make_word_plural_or_singular(player_guesses, "guess")} left!' 143 | ) 144 | 145 | 146 | def play_again(file_name, player_name): 147 | 148 | choice = input(f"{player_name}, type 'y' to play again or 'n' to exit" 149 | ).lower().strip() 150 | 151 | if choice == 'y': 152 | play_game(file_name, player_name) 153 | 154 | 155 | def get_player_name(): 156 | return input("Enter your name to save your score:\n").title().strip() 157 | 158 | 159 | def print_leaderboard(scores): 160 | 161 | if (scores): 162 | names_scores_sorted = sorted(scores.items(), 163 | key=lambda x: x[1], 164 | reverse=True) 165 | placement = 1 166 | 167 | print(Fore.YELLOW + "LEADERBOARD".center(40, '*')) 168 | print() 169 | print(Fore.YELLOW + "TOP 3 PLAYERS".center(40, '*'), "\n") 170 | 171 | for name, score in names_scores_sorted: 172 | 173 | score_color = Fore.CYAN if score > 0 else Fore.RED 174 | placement_color = Fore.YELLOW if placement <= 3 else Fore.WHITE 175 | name_color = Fore.GREEN if placement <= 3 else Fore.WHITE 176 | 177 | if placement == 4: 178 | print(Fore.YELLOW + "******".center(40, '*')) 179 | 180 | print( 181 | f"# {placement_color + str(placement)}: {name_color+ name} - {score_color + str(score)} {Fore.WHITE + make_word_plural_or_singular(score, 'point')}" 182 | ) 183 | 184 | placement += 1 185 | 186 | print(Fore.YELLOW + "******".center(40, '*')) 187 | 188 | 189 | def play_game(file_name, player_name): 190 | players_scores = get_players_scores_from(file_name) 191 | print_leaderboard(players_scores) 192 | 193 | hangman_pic_index = 0 194 | wrong_letters = [] 195 | score = 0 196 | 197 | if players_scores and player_name in players_scores: 198 | score = players_scores[player_name] 199 | 200 | words_list = get_words_list() 201 | correct_word = random.choice(words_list).upper() 202 | 203 | player_guesses = 6 204 | word_to_guess_list = ['_' for _ in range(len(correct_word))] 205 | 206 | print(f'The secret word has {len(correct_word)} letters\n') 207 | 208 | while player_guesses: 209 | 210 | player_letter = ask_player_letter() 211 | 212 | if player_letter and player_letter in correct_word: 213 | indexes = [ 214 | i for i, letter in enumerate(correct_word) 215 | if letter == player_letter 216 | ] 217 | for i in indexes: 218 | word_to_guess_list[i] = player_letter 219 | else: 220 | wrong_letters.append((player_letter)) 221 | wrong_letters = list(set(wrong_letters)) 222 | player_guesses -= 1 223 | hangman_pic_index += 1 224 | 225 | word_to_guess_string = get_string_word(word_to_guess_list) 226 | 227 | for ch in word_to_guess_string: 228 | word_color = Fore.WHITE if ch == '_' else Fore.CYAN 229 | print(f" {word_color + ch} ".center(1), end='') 230 | print("\n") 231 | print(hangman_pic()[hangman_pic_index], '\n') 232 | print_guesses_left(player_guesses) 233 | 234 | print(f"Wrong letters: {Fore.RED + ' '.join(wrong_letters)}\n") 235 | 236 | if (word_to_guess_string == correct_word): 237 | print(f'You win! The word is {Fore.CYAN + correct_word}\n') 238 | break 239 | 240 | if (not player_guesses): 241 | print( 242 | f'Sorry! You lost! No more guesses left! The word was {Fore.CYAN + correct_word}\n' 243 | ) 244 | 245 | score += player_guesses 246 | 247 | save_player_score_to(file_name, player_name, score) 248 | 249 | play_again(file_name, player_name) 250 | 251 | 252 | def main(): 253 | os.chdir(os.getcwd() + "/src/day_7") 254 | 255 | try: 256 | file_name = 'players-scores' 257 | create_scores_file(file_name) 258 | 259 | player_name = get_player_name() 260 | play_game(file_name, player_name) 261 | 262 | except KeyboardInterrupt: 263 | print("Exit Program") 264 | sys.exit() 265 | 266 | 267 | if __name__ == "__main__": 268 | # for the color to reset at each print 269 | 270 | init(autoreset=True) 271 | main() -------------------------------------------------------------------------------- /src/day_7/players-scores: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dylanbuchi/31-days-of-code/216585d2402129da42bc17babce4ae444fc40dff/src/day_7/players-scores -------------------------------------------------------------------------------- /src/day_7/requirements.txt: -------------------------------------------------------------------------------- 1 | colorama==0.4.4 -------------------------------------------------------------------------------- /src/day_7/words.txt: -------------------------------------------------------------------------------- 1 | able 2 | about 3 | account 4 | acid 5 | across 6 | act 7 | addition 8 | adjustment 9 | advertisement 10 | after 11 | again 12 | against 13 | agreement 14 | air 15 | all 16 | almost 17 | among 18 | amount 19 | amusement 20 | and 21 | angle 22 | angry 23 | animal 24 | answer 25 | ant 26 | any 27 | apparatus 28 | apple 29 | approval 30 | arch 31 | argument 32 | arm 33 | army 34 | art 35 | as 36 | at 37 | attack 38 | attempt 39 | attention 40 | attraction 41 | authority 42 | automatic 43 | awake 44 | baby 45 | back 46 | bad 47 | bag 48 | balance 49 | ball 50 | band 51 | base 52 | basin 53 | basket 54 | bath 55 | be 56 | beautiful 57 | because 58 | bed 59 | bee 60 | before 61 | behaviour 62 | belief 63 | bell 64 | bent 65 | berry 66 | between 67 | bird 68 | birth 69 | bit 70 | bite 71 | bitter 72 | black 73 | blade 74 | blood 75 | blow 76 | blue 77 | board 78 | boat 79 | body 80 | boiling 81 | bone 82 | book 83 | boot 84 | bottle 85 | box 86 | boy 87 | brain 88 | brake 89 | branch 90 | brass 91 | bread 92 | breath 93 | brick 94 | bridge 95 | bright 96 | broken 97 | brother 98 | brown 99 | brush 100 | bucket 101 | building 102 | bulb 103 | burn 104 | burst 105 | business 106 | biiiiiig 107 | but 108 | butter 109 | button 110 | by 111 | cake 112 | camera 113 | canvas 114 | card 115 | care 116 | carriage 117 | cart 118 | cat 119 | cause 120 | certain 121 | chain 122 | chalk 123 | chance 124 | change 125 | cheap 126 | cheese 127 | chemical 128 | chest 129 | chief 130 | chin 131 | church 132 | circle 133 | clean 134 | clear 135 | clock 136 | cloth 137 | cloud 138 | coal 139 | coat 140 | cold 141 | collar 142 | colour 143 | comb 144 | come 145 | comfort 146 | committee 147 | common 148 | company 149 | comparison 150 | competition 151 | complete 152 | complex 153 | condition 154 | connection 155 | conscious 156 | control 157 | cook 158 | copper 159 | copy 160 | cord 161 | cork 162 | cotton 163 | cough 164 | country 165 | cover 166 | cow 167 | crack 168 | credit 169 | crime 170 | cruel 171 | crush 172 | cry 173 | cup 174 | cup 175 | current 176 | curtain 177 | curve 178 | cushion 179 | damage 180 | danger 181 | dark 182 | daughter 183 | day 184 | dead 185 | dear 186 | death 187 | debt 188 | decision 189 | deep 190 | degree 191 | delicate 192 | dependent 193 | design 194 | desire 195 | destruction 196 | detail 197 | development 198 | different 199 | digestion 200 | direction 201 | dirty 202 | discovery 203 | discussion 204 | disease 205 | disgust 206 | distance 207 | distribution 208 | division 209 | do 210 | dog 211 | door 212 | doubt 213 | down 214 | drain 215 | drawer 216 | dress 217 | drink 218 | driving 219 | drop 220 | dry 221 | dust 222 | ear 223 | early 224 | earth 225 | east 226 | edge 227 | education 228 | effect 229 | egg 230 | elastic 231 | electric 232 | end 233 | engine 234 | enough 235 | equal 236 | error 237 | even 238 | event 239 | ever 240 | every 241 | example 242 | exchange 243 | existence 244 | expansion 245 | experience 246 | expert 247 | eye 248 | face 249 | fact 250 | fall 251 | false 252 | family 253 | far 254 | farm 255 | fat 256 | father 257 | fear 258 | feather 259 | feeble 260 | feeling 261 | female 262 | fertile 263 | fiction 264 | field 265 | fight 266 | finger 267 | fire 268 | first 269 | fish 270 | fixed 271 | flag 272 | flame 273 | flat 274 | flight 275 | floor 276 | flower 277 | fly 278 | fold 279 | food 280 | foolish 281 | foot 282 | for 283 | force 284 | fork 285 | form 286 | forward 287 | fowl 288 | frame 289 | free 290 | frequent 291 | friend 292 | from 293 | front 294 | fruit 295 | full 296 | future 297 | garden 298 | general 299 | get 300 | girl 301 | give 302 | glass 303 | glove 304 | go 305 | goat 306 | gold 307 | good 308 | government 309 | grain 310 | grass 311 | great 312 | green 313 | grey 314 | grip 315 | group 316 | growth 317 | guide 318 | gun 319 | hair 320 | hammer 321 | hand 322 | hanging 323 | happy 324 | harbour 325 | hard 326 | harmony 327 | hat 328 | hate 329 | have 330 | he 331 | head 332 | healthy 333 | hear 334 | hearing 335 | heart 336 | heat 337 | help 338 | high 339 | history 340 | hole 341 | hollow 342 | hook 343 | hope 344 | horn 345 | horse 346 | hospital 347 | hour 348 | house 349 | how 350 | humour 351 | I 352 | ice 353 | idea 354 | if 355 | ill 356 | important 357 | impulse 358 | in 359 | increase 360 | industry 361 | ink 362 | insect 363 | instrument 364 | insurance 365 | interest 366 | invention 367 | iron 368 | island 369 | jelly 370 | jewel 371 | join 372 | journey 373 | judge 374 | jump 375 | keep 376 | kettle 377 | key 378 | kick 379 | kind 380 | kiss 381 | knee 382 | knife 383 | knot 384 | knowledge 385 | land 386 | language 387 | last 388 | late 389 | laugh 390 | law 391 | lead 392 | leaf 393 | learning 394 | leather 395 | left 396 | leg 397 | let 398 | letter 399 | level 400 | library 401 | lift 402 | light 403 | like 404 | limit 405 | line 406 | linen 407 | lip 408 | liquid 409 | list 410 | little 411 | living 412 | lock 413 | long 414 | look 415 | loose 416 | loss 417 | loud 418 | love 419 | low 420 | machine 421 | make 422 | male 423 | man 424 | manager 425 | map 426 | mark 427 | market 428 | married 429 | mass 430 | match 431 | material 432 | may 433 | meal 434 | measure 435 | meat 436 | medical 437 | meeting 438 | memory 439 | metal 440 | middle 441 | military 442 | milk 443 | mind 444 | mine 445 | minute 446 | mist 447 | mixed 448 | money 449 | monkey 450 | month 451 | moon 452 | morning 453 | mother 454 | motion 455 | mountain 456 | mouth 457 | move 458 | much 459 | muscle 460 | music 461 | nail 462 | name 463 | narrow 464 | nation 465 | natural 466 | near 467 | necessary 468 | neck 469 | need 470 | needle 471 | nerve 472 | net 473 | new 474 | news 475 | night 476 | no 477 | noise 478 | normal 479 | north 480 | nose 481 | not 482 | note 483 | now 484 | number 485 | nut 486 | observation 487 | of 488 | off 489 | offer 490 | office 491 | oil 492 | old 493 | on 494 | only 495 | open 496 | operation 497 | opinion 498 | opposite 499 | or 500 | orange 501 | order 502 | organization 503 | ornament 504 | other 505 | out 506 | oven 507 | over 508 | owner 509 | page 510 | pain 511 | paint 512 | paper 513 | parallel 514 | parcel 515 | part 516 | past 517 | paste 518 | payment 519 | peace 520 | pen 521 | pencil 522 | person 523 | physical 524 | picture 525 | pig 526 | pin 527 | pipe 528 | place 529 | plane 530 | plant 531 | plate 532 | play 533 | please 534 | pleasure 535 | plough 536 | pocket 537 | point 538 | poison 539 | polish 540 | political 541 | poor 542 | porter 543 | position 544 | possible 545 | pot 546 | potato 547 | powder 548 | power 549 | present 550 | price 551 | print 552 | prison 553 | private 554 | probable 555 | process 556 | produce 557 | profit 558 | property 559 | prose 560 | protest 561 | public 562 | pull 563 | pump 564 | punishment 565 | purpose 566 | push 567 | put 568 | quality 569 | question 570 | quick 571 | quiet 572 | quite 573 | rail 574 | rain 575 | range 576 | rat 577 | rate 578 | ray 579 | reaction 580 | reading 581 | ready 582 | reason 583 | receipt 584 | record 585 | red 586 | regret 587 | regular 588 | relation 589 | religion 590 | representative 591 | request 592 | respect 593 | responsible 594 | rest 595 | reward 596 | rhythm 597 | rice 598 | right 599 | ring 600 | river 601 | road 602 | rod 603 | roll 604 | roof 605 | room 606 | root 607 | rough 608 | round 609 | rub 610 | rule 611 | run 612 | sad 613 | safe 614 | sail 615 | salt 616 | same 617 | sand 618 | say 619 | scale 620 | school 621 | science 622 | scissors 623 | screw 624 | sea 625 | seat 626 | second 627 | secret 628 | secretary 629 | see 630 | seed 631 | seem 632 | selection 633 | self 634 | send 635 | sense 636 | separate 637 | serious 638 | servant 639 | sex 640 | shade 641 | shake 642 | shame 643 | sharp 644 | sheep 645 | shelf 646 | ship 647 | shirt 648 | shock 649 | shoe 650 | short 651 | shut 652 | side 653 | sign 654 | silk 655 | silver 656 | simple 657 | sister 658 | size 659 | skin 660 | 661 | skirt 662 | sky 663 | sleep 664 | slip 665 | slope 666 | slow 667 | small 668 | smash 669 | smell 670 | smile 671 | smoke 672 | smooth 673 | snake 674 | sneeze 675 | snow 676 | so 677 | soap 678 | society 679 | sock 680 | soft 681 | solid 682 | some 683 | 684 | son 685 | song 686 | sort 687 | sound 688 | soup 689 | south 690 | space 691 | spade 692 | special 693 | sponge 694 | spoon 695 | spring 696 | square 697 | stage 698 | stamp 699 | star 700 | start 701 | statement 702 | station 703 | steam 704 | steel 705 | stem 706 | step 707 | stick 708 | sticky 709 | stiff 710 | still 711 | stitch 712 | stocking 713 | stomach 714 | stone 715 | stop 716 | store 717 | story 718 | straight 719 | strange 720 | street 721 | stretch 722 | strong 723 | structure 724 | substance 725 | such 726 | sudden 727 | sugar 728 | suggestion 729 | summer 730 | sun 731 | support 732 | surprise 733 | sweet 734 | swim 735 | system 736 | table 737 | tail 738 | take 739 | talk 740 | tall 741 | taste 742 | tax 743 | teaching 744 | tendency 745 | test 746 | than 747 | that 748 | the 749 | then 750 | theory 751 | there 752 | thick 753 | thin 754 | thing 755 | this 756 | thought 757 | thread 758 | throat 759 | through 760 | through 761 | thumb 762 | thunder 763 | ticket 764 | tight 765 | till 766 | time 767 | tin 768 | tired 769 | to 770 | toe 771 | together 772 | tomorrow 773 | tongue 774 | tooth 775 | top 776 | touch 777 | town 778 | trade 779 | train 780 | transport 781 | tray 782 | tree 783 | trick 784 | trouble 785 | trousers 786 | true 787 | turn 788 | twist 789 | umbrella 790 | under 791 | unit 792 | up 793 | use 794 | value 795 | verse 796 | very 797 | vessel 798 | view 799 | violent 800 | voice 801 | waiting 802 | walk 803 | wall 804 | war 805 | warm 806 | wash 807 | waste 808 | watch 809 | water 810 | wave 811 | wax 812 | way 813 | weather 814 | week 815 | weight 816 | well 817 | west 818 | wet 819 | wheel 820 | when 821 | where 822 | while 823 | whip 824 | whistle 825 | white 826 | who 827 | why 828 | wide 829 | will 830 | wind 831 | window 832 | wine 833 | wing 834 | winter 835 | wire 836 | wise 837 | with 838 | woman 839 | wood 840 | wool 841 | word 842 | work 843 | worm 844 | wound 845 | writing 846 | wrong 847 | year 848 | yellow 849 | yes 850 | yesterday 851 | you 852 | young 853 | Bernhard 854 | Breytenbach 855 | Android -------------------------------------------------------------------------------- /src/day_8/README.md: -------------------------------------------------------------------------------- 1 | # Caesar Cipher 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_8/caesar_cipher.py) 4 | 5 | ## Demo: 6 | 7 | ![](https://user-images.githubusercontent.com/52018183/104049880-77c87d80-51c4-11eb-9d34-43ded937e8ac.gif) 8 | -------------------------------------------------------------------------------- /src/day_8/caesar_cipher.py: -------------------------------------------------------------------------------- 1 | # Caesar Cipher 2 | import sys 3 | import os 4 | 5 | # add this to import the logo and run the file here 6 | sys.path.append(os.getcwd()) 7 | 8 | from src.day_8.logo import LOGO 9 | 10 | # Global constant variable 11 | ALPHABET = [chr(i) for i in range(97, 123)] 12 | 13 | 14 | def run_again(): 15 | choice = input("Press enter to run again") 16 | if not choice: 17 | main() 18 | 19 | 20 | def ask_user_encryption_details(): 21 | text = space = ' ' 22 | shift = 5 23 | 24 | while True: 25 | try: 26 | text = input("Type your message:\n").lower() 27 | assert text.isalpha() or space in text 28 | shift = int(input("Type the shift number:\n")) 29 | 30 | except (ValueError, AssertionError): 31 | print("Error, please try again with valid inputs") 32 | continue 33 | else: 34 | return text, shift 35 | 36 | 37 | def choose_codec_mode(mode, text: str, shift): 38 | parts = [] 39 | 40 | for ch in text: 41 | if not ch.isalpha(): 42 | parts.append(ch) 43 | 44 | else: 45 | index = (ALPHABET.index(ch)) 46 | index = index + shift if mode == 'encode' else index - shift 47 | parts.append(ALPHABET[index % 26]) 48 | 49 | return ''.join(parts) 50 | 51 | 52 | def run_caesar_cipher(text, shift, mode): 53 | return choose_codec_mode(mode, text, shift) 54 | 55 | 56 | def user_interface(): 57 | mode = input("Type 'encode' to encrypt or type 'decode' to decrypt:\n" 58 | ).lower().strip() 59 | text, shift = ask_user_encryption_details() 60 | result = run_caesar_cipher(text, shift, mode) 61 | 62 | print(f"The {mode}d message is: {result}") 63 | 64 | 65 | def main(): 66 | print(LOGO) 67 | try: 68 | user_interface() 69 | run_again() 70 | 71 | except KeyboardInterrupt: 72 | sys.exit() 73 | 74 | 75 | if __name__ == "__main__": 76 | main() -------------------------------------------------------------------------------- /src/day_8/logo.py: -------------------------------------------------------------------------------- 1 | LOGO = """ 2 | ,adPPYba, ,adPPYYba, ,adPPYba, ,adPPYba, ,adPPYYba, 8b,dPPYba, 3 | a8" "" "" `Y8 a8P_____88 I8[ "" "" `Y8 88P' "Y8 4 | 8b ,adPPPPP88 8PP""" """" `"Y8ba, ,adPPPPP88 88 5 | "8a, ,aa 88, ,88 "8b, ,aa aa ]8I 88, ,88 88 6 | `"Ybbd8"' `"8bbdP"Y8 `"Ybbd8"' `"YbbdP"' `"8bbdP"Y8 88 7 | 88 88 8 | "" 88 9 | 88 10 | ,adPPYba, 88 8b,dPPYba, 88,dPPYba, ,adPPYba, 8b,dPPYba, 11 | a8" "" 88 88P' "8a 88P' "8a a8P_____88 88P' "Y8 12 | 8b 88 88 d8 88 88 8PP""" """" 88 13 | "8a, ,aa 88 88b, ,a8" 88 88 "8b, ,aa 88 14 | `"Ybbd8"' 88 88`YbbdP"' 88 88 `"Ybbd8"' 88 15 | 88 16 | 88 17 | """ -------------------------------------------------------------------------------- /src/day_9/README.md: -------------------------------------------------------------------------------- 1 | # Auction Program 2 | 3 | ## [Code](https://github.com/dylanbuchi/100-days-of-code/blob/main/src/day_9/auction_program.py) 4 | 5 | ## Demo: 6 | 7 | ![bid](https://user-images.githubusercontent.com/52018183/104095985-a30ca480-5278-11eb-9422-6ee2bb9da6fa.gif) 8 | 9 | -------------------------------------------------------------------------------- /src/day_9/auction.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | from colorama import Fore, init 4 | 5 | 6 | class Auction: 7 | def __init__(self) -> None: 8 | init(autoreset=True) 9 | self.name_with_bid_amount_map = {} 10 | 11 | def check_user_name(self, name): 12 | return name in self.name_with_bid_amount_map 13 | 14 | def get_welcome_message(self, message="Welcome to my auction program"): 15 | return message 16 | 17 | def print_error_message(self, message): 18 | print(Fore.RED + message) 19 | 20 | def get_user_name(self): 21 | try: 22 | name = input("What's your name?\n").title().strip() 23 | if self.check_user_name(name): 24 | self.print_error_message( 25 | "This name is already in our database. Please choose an username" 26 | ) 27 | return self.get_user_name() 28 | 29 | assert re.match(r"^[a-z A-Z]+$", name) is not None 30 | 31 | except AssertionError: 32 | self.print_error_message("Please enter a valid name") 33 | return self.get_user_name() 34 | 35 | else: 36 | return name 37 | 38 | def get_user_bid_amount(self): 39 | try: 40 | bid = int(input("What's your bid?\n$").strip()) 41 | assert bid > 0 42 | 43 | except (ValueError, AssertionError): 44 | # recursive calls until user enters a valid input 45 | self.print_error_message('Please enter a valid amount') 46 | return self.get_user_bid_amount() 47 | 48 | else: 49 | return bid 50 | 51 | def ask_user_more_biders(self): 52 | try: 53 | answer = input( 54 | "Are there any other bidders? (y/n)\n").lower().strip()[:1] 55 | assert answer == 'y' or answer == 'n' 56 | 57 | except AssertionError: 58 | self.print_error_message("Please enter 'yes' or 'no' (y/n)") 59 | return self.ask_user_more_biders() 60 | else: 61 | return answer 62 | 63 | def get_winner(self, name_bid_amount): 64 | max_amount = max(name_bid_amount.values()) 65 | 66 | for name, amount in name_bid_amount.items(): 67 | if max_amount == amount: 68 | return name, amount 69 | 70 | def print_current_bidders(self): 71 | print("\nCurrent bidders:\n") 72 | 73 | if self.name_with_bid_amount_map: 74 | for name, amount in sorted(self.name_with_bid_amount_map.items(), 75 | key=lambda x: x[1], 76 | reverse=True): 77 | print(f"{name:5}: ${amount:,}") 78 | print() 79 | -------------------------------------------------------------------------------- /src/day_9/auction_program.py: -------------------------------------------------------------------------------- 1 | # Auction_Program 2 | import os 3 | import sys 4 | sys.path.extend([os.path.join(os.getcwd(), 'src'), os.path.join(os.getcwd())]) 5 | 6 | import random 7 | 8 | from day_9.auction import Auction 9 | from day_9.logo import LOGO 10 | 11 | from utility import clear_console 12 | 13 | 14 | def get_random_bid(start=1, end=2000): 15 | return random.randint(start, end) 16 | 17 | 18 | def get_random_name_and_remove_it_from(names): 19 | name = random.choice(names) 20 | names.remove(name) 21 | return name 22 | 23 | 24 | def create_default_bidders(): 25 | names = ["John", "Harry", "Joe", "Tony", "Emma", "Mia"] 26 | 27 | bidders_list = [{ 28 | get_random_name_and_remove_it_from(names): get_random_bid() 29 | for i in range(6) 30 | }] 31 | 32 | return bidders_list 33 | 34 | 35 | def get_default_bidders(): 36 | temp = {} 37 | for b in create_default_bidders(): 38 | temp.update(b) 39 | return temp 40 | 41 | 42 | def user_interface(): 43 | auction = Auction() 44 | print(auction.get_welcome_message()) 45 | 46 | auction.name_with_bid_amount_map = get_default_bidders() 47 | name_bid_amount = auction.name_with_bid_amount_map 48 | 49 | while True: 50 | auction.print_current_bidders() 51 | 52 | user_name = auction.get_user_name() 53 | user_bid = auction.get_user_bid_amount() 54 | 55 | name_bid_amount[user_name] = user_bid 56 | answer = auction.ask_user_more_biders() 57 | 58 | if answer == 'n': 59 | break 60 | 61 | clear_console() 62 | 63 | winner, winner_bid = auction.get_winner(name_bid_amount) 64 | print(f"The winner is {winner} with a bid of ${winner_bid:,}") 65 | 66 | 67 | def main(): 68 | print(LOGO) 69 | 70 | try: 71 | user_interface() 72 | 73 | except KeyboardInterrupt: 74 | print("Exit") 75 | 76 | 77 | if __name__ == "__main__": 78 | main() -------------------------------------------------------------------------------- /src/day_9/logo.py: -------------------------------------------------------------------------------- 1 | LOGO = ''' 2 | ___________ 3 | \ / 4 | )_______( 5 | |"""""""|_.-._,.---------.,_.-._ 6 | | | | | | | ''-. 7 | | |_| |_ _| |_..-' 8 | |_______| '-' `'---------'` '-' 9 | )"""""""( 10 | /_________\\ 11 | .-------------. 12 | /_______________\\ 13 | ''' -------------------------------------------------------------------------------- /utility.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def clear_console(): 5 | os.system('cls' if os.name == 'nt' else 'clear') --------------------------------------------------------------------------------