From 6d5d75a88bc783e83c4c7b2c255820a619587f5d Mon Sep 17 00:00:00 2001 From: waldek Date: Tue, 26 Apr 2022 22:41:09 +0200 Subject: [PATCH] adds the hangman multi level spoilers --- learning_python3.md | 717 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 656 insertions(+), 61 deletions(-) diff --git a/learning_python3.md b/learning_python3.md index 4255e6e..f5a6f5c 100644 --- a/learning_python3.md +++ b/learning_python3.md @@ -351,11 +351,11 @@ Let's convert the quote below to logical statements. ```python3 age = 35 if age < 27: - print("you are still very young, enjoy it!") + print("you are still very young, enjoy it!") elif age > 27: - print("watch out for those hips oldie...") + print("watch out for those hips oldie...") else: - print("you are at a dangerous crossroad in life!") + print("you are at a dangerous crossroad in life!") ``` ⛑ **Do not fight the automatic indentation in your IDE! Pycharm is intelligent enough to know when to indent so if it does not indent by itself, you probably made a syntax error.** @@ -372,17 +372,17 @@ name = input("What is you name?") age = input("What is you age?") if age.isdigit(): - age = int(age) + age = int(age) else: - print("{} is not a valid age".format(age)) - exit(1) + print("{} is not a valid age".format(age)) + exit(1) if age < 27: - print("My god {}, you are still very young, enjoy it!".format(name)) + print("My god {}, you are still very young, enjoy it!".format(name)) elif age > 27: - print("Wow {}! Watch out for those hips oldie...".format(name)) + print("Wow {}! Watch out for those hips oldie...".format(name)) else: - print("{}, you are at a dangerous crossroad in life!".format(name.capitalize())) + print("{}, you are at a dangerous crossroad in life!".format(name.capitalize())) ``` An object of the type `str` has multiple **methods** that can be applied on itself. @@ -599,8 +599,8 @@ Here is a basic abstraction with a correct syntax. ```python3 def first_function(): - print("I'm a function") - print("Hear me roar!") + print("I'm a function") + print("Hear me roar!") ``` ⛑ **Do not fight the indentation, it's part of the syntax of python!** @@ -612,8 +612,8 @@ This is done as follows. ```python3 def first_function(): - print("I'm a function") - print("Hear me roar!") + print("I'm a function") + print("Hear me roar!") first_function() ``` @@ -636,10 +636,10 @@ Below we create **one** function to bake the cake, and call it **three** times t ```python3 def bake_chocolate_cake(): - print("mix the base ingredients") - print("add the chocolate flavour") - print("put in the oven") - print("enjoy!") + print("mix the base ingredients") + print("add the chocolate flavour") + print("put in the oven") + print("enjoy!") bake_chocolate_cake() bake_chocolate_cake() @@ -651,16 +651,16 @@ Easy, we'll just write a second function for that purpose. ```python3 def bake_chocolate_cake(): - print("mix the base ingredients") - print("add the chocolate flavour") - print("put in the oven") - print("enjoy!") + print("mix the base ingredients") + print("add the chocolate flavour") + print("put in the oven") + print("enjoy!") def bake_vanilla_cake(): - print("mix the base ingredients") - print("add the vanilla flavour") - print("put in the oven") - print("enjoy!") + print("mix the base ingredients") + print("add the vanilla flavour") + print("put in the oven") + print("enjoy!") bake_chocolate_cake() bake_chocolate_cake() @@ -678,10 +678,10 @@ This can be done with arguments. ```python3 def bake_cake(flavor): - print("mix the base ingredients") - print("add the {} flavor".format(flavor)) - print("put in the oven") - print("enjoy!") + print("mix the base ingredients") + print("add the {} flavor".format(flavor)) + print("put in the oven") + print("enjoy!") bake_cake("chocolate") bake_cake("vanilla") @@ -733,8 +733,8 @@ This will give an `UnboundLocalError: local variable 'name' referenced before as name = "Wouter" def function_scope(): - print("inside the function", name) - name = "Alice" + print("inside the function", name) + name = "Alice" function_scope() @@ -748,9 +748,9 @@ This is done as follows with the `global` keyword. name = "Wouter" def function_scope(): - global name + global name print("inside the function", name) - name = "Alice" + name = "Alice" function_scope() @@ -810,10 +810,10 @@ As an extra challenge you could return a [multi line string](https://www.askpyth ```python3 def pretty_print(msg, decorator="#"): - line_len = len(msg) + (len(decorator) * 2) + 2 - print(decorator * line_len) - print("{} {} {}".format(decorator, msg, decorator)) - print(decorator * line_len) + line_len = len(msg) + (len(decorator) * 2) + 2 + print(decorator * line_len) + print("{} {} {}".format(decorator, msg, decorator)) + print(decorator * line_len) pretty_print("Wouter") pretty_print("Python rules!") @@ -941,11 +941,11 @@ This opens up a **second tab** in your editor window with a `datetime.py` file i In this file your cursor should have jumped to the following code. ```python3 - @classmethod - def now(cls, tz=None): - "Construct a datetime from time.time() and optional time zone info." - t = _time.time() - return cls.fromtimestamp(t, tz) + @classmethod + def now(cls, tz=None): + "Construct a datetime from time.time() and optional time zone info." + t = _time.time() + return cls.fromtimestamp(t, tz) ``` What does this look like? @@ -968,10 +968,10 @@ I have code along these lines. ```python3 def pretty_print(msg, decorator="#"): - line_len = len(msg) + (len(decorator) * 2) + 2 - print(decorator * line_len) - print("{} {} {}".format(decorator, msg, decorator)) - print(decorator * line_len) + line_len = len(msg) + (len(decorator) * 2) + 2 + print(decorator * line_len) + print("{} {} {}".format(decorator, msg, decorator)) + print(decorator * line_len) pretty_print("Wouter") @@ -1178,9 +1178,9 @@ counter = 0 print("before the loop, counter: {}".format(counter)) while counter <= 10: - print("inside the loop, counter: {}".format(counter)) - counter += 1 - time.sleep(1) + print("inside the loop, counter: {}".format(counter)) + counter += 1 + time.sleep(1) print("after the loop, counter: {}".format(counter)) ``` @@ -1203,9 +1203,9 @@ counter = 0 print("before the loop, counter: {}".format(counter)) while True: - print("inside the loop, counter: {}".format(counter)) - counter += 1 - time.sleep(1) + print("inside the loop, counter: {}".format(counter)) + counter += 1 + time.sleep(1) print("after the loop, counter: {}".format(counter)) ``` @@ -1222,12 +1222,12 @@ counter = 0 print("before the loop, counter: {}".format(counter)) while True: - print("inside the loop, counter: {}".format(counter)) - counter += 1 - if counter >= 10: - print("I'll break now!") - break - time.sleep(1) + print("inside the loop, counter: {}".format(counter)) + counter += 1 + if counter >= 10: + print("I'll break now!") + break + time.sleep(1) print("after the loop, counter: {}".format(counter)) ``` @@ -1529,8 +1529,8 @@ friends = ["max", "mike", "alice", "steve", "rosa", "hans"] print("The door opens and in walk my {} friends!".format(len(friends))) for friend in friends: - print("Hello {}!".format(friend.capitalize())) - time.sleep(1) + print("Hello {}!".format(friend.capitalize())) + time.sleep(1) print("{} closes the door behind him...".format(friend.capitalize())) ``` @@ -2471,7 +2471,7 @@ Throughout the day 4 buses will pass by and each bus has 30 seats on it. * How many people are left at each stop at the end of the day? * How many buses would the bus line need in order to get everybody to the terminal? - * What if at each stop 10% of the people on the bus get off? + * What if at each stop 10% of the people on the bus get off? | bus stop | people waiting | |-------------------|----------------| @@ -3137,6 +3137,601 @@ When looking at the game above we can break down the game logic as follows. 7. A winning banner is shown 8. The player is asked to play a new game or not. +### A non object orientated solution + +You can try to create the hangman game in multiple stages. +Below you can find multi level hints towards a solution. + +
+Spoiler warning +
+First hint + +```python +import random + + +def get_random_word(): + pass + +def ask_for_letter(): + pass + +def is_letter_in_word(): + pass + +def show_hidden_word(): + pass + +def show_end_game(status): + pass + +def game(): + pass + +def ask_new_game(): + pass + +def main(): + pass + + +if __name__ == "__main__": + main() + +``` + +
+ +
+Second hint + +```python +import random + + +def get_random_word(): + pass + +def ask_for_letter(): + pass + +def is_letter_in_word(letter, word): + pass + +def show_hidden_word(word, letters_found): + pass + +def show_end_game(status): + pass + +def game(): + pass + +def ask_new_game(): + pass + +def main(): + while True: + status = game() + show_end_game(status) + status = ask_new_game() + if not status: + break + print("bye bye!") + + +if __name__ == "__main__": + main() + +``` + +
+ +
+Possible solution + +```python +import random + + +def get_random_word(): + words = ["hello", "world", "apple", "banana", "hippopotamus"] + return random.choice(words) + + +def ask_for_letter(): + while True: + letter = input("your letter please: ") + if len(letter) != 1: + print("only one letter! no cheating!") + continue + if not letter.isalpha(): + print("letters please, no numbers nor spaces...") + continue + else: + break + return letter.lower() + + +def is_letter_in_word(letter, word): + if letter in word: + return True + return False + + +def show_hidden_word(word, letters_found): + hidden = "" + for letter in word: + if letter in letters_found: + hidden += letter + else: + hidden += "*" + print("word to find: {}".format(hidden)) + if "*" in hidden: + return False + return True + + +def show_end_game(status): + if status: + print("good job!") + else: + print("better luck next time...") + + +def game(): + word_to_guess = get_random_word() + letters_found = [] + difficulty = len(word_to_guess) * 3 + while len(letters_found) <= difficulty: + left = difficulty - len(letters_found) + print("you have {} tries left".format(left)) + status = show_hidden_word(word_to_guess, letters_found) + if status: + return True + letter = ask_for_letter() + letters_found.append(letter) + return False + + +def ask_new_game(): + while True: + result = input("do you want to play a new game?").lower() + if result.startswith("y"): + status = True + break + elif result.startswith("n"): + status = False + break + else: + print("please answer y(es) or n(o)") + return status + + +def main(): + while True: + status = game() + show_end_game(status) + status = ask_new_game() + if not status: + break + print("bye bye!") + + +if __name__ == "__main__": + main() + +``` + +
+ +
+ +### An object orientated solution + +You can try to create the hangman game in multiple stages. +Below you can find multi level hints towards a solution. + +
+Spoiler warning + +
+First hint + +```python +import random + + +class Word(object): + def __init__(self): + pass + + def __iter__(self): + pass + + def __len__(self): + pass + + def is_letter_in_word(self): + pass + + +class Game(object): + def __init__(self): + pass + + def play_turn(self): + pass + + def get_hidden_word(self): + pass + + def is_word_found(self): + pass + + +class Controller(object): + def __init__(self): + pass + + def set_view(self): + pass + + def submit_letter(self): + pass + + def request_hidden_word(self): + pass + + def request_new_game(self): + pass + + +class CommandLineInterface(object): + def __init__(self): + pass + + def ask_for_letter(self): + pass + + def ask_for_bool(self): + pass + + def show_message(self): + pass + + def run(self): + pass + + +if __name__ == "__main__": + pass + +``` + + +
+ + +
+Second hint + +```python +import random + + +class Word(object): + def __init__(self): + pass + + def __iter__(self): + pass + + def __len__(self): + pass + + def is_letter_in_word(self, letter): + pass + + +class Game(object): + def __init__(self): + pass + + def play_turn(self, letter): + pass + + def get_hidden_word(self): + pass + + def is_word_found(self): + pass + + +class Controller(object): + def __init__(self, model): + pass + + def set_view(self, view): + pass + + def submit_letter(self, letter): + pass + + def request_hidden_word(self): + pass + + def request_new_game(self): + pass + + +class CommandLineInterface(object): + def __init__(self, controller): + pass + + def ask_for_letter(self): + pass + + def ask_for_bool(self, msg): + pass + + def show_message(self, msg): + pass + + def run(self): + pass + + +if __name__ == "__main__": + model = Game() + controller = Controller(model) + view = CommandLineInterface(controller) + controller.set_view(view) + view.run() + +``` + +
+ +
+Third hint + +```python +import random + + +class Word(object): + def __init__(self): + pass + + def __iter__(self): + pass + + def __len__(self): + pass + + def is_letter_in_word(self, letter): + pass + + +class Game(object): + def __init__(self): + pass + + def play_turn(self, letter): + pass + + def get_hidden_word(self): + pass + + def is_word_found(self): + pass + + +class Controller(object): + def __init__(self, model): + pass + + def set_view(self, view): + pass + + def submit_letter(self, letter): + pass + + def request_hidden_word(self): + pass + + def request_new_game(self): + pass + + +class CommandLineInterface(object): + def __init__(self, controller): + pass + + def ask_for_letter(self): + pass + + def ask_for_bool(self, msg): + pass + + def show_message(self, msg): + pass + + def run(self): + while True: + self.controller.request_hidden_word() + letter = self.ask_for_letter() + status = self.controller.submit_letter(letter) + if status: + status = self.ask_for_bool("do you want to play a new game?") + if status: + self.controller.request_new_game() + else: + break + self.show_message("bye bye!") + + +if __name__ == "__main__": + model = Game() + controller = Controller(model) + view = CommandLineInterface(controller) + controller.set_view(view) + view.run() + +``` + +
+ +
+Possible solution + +```python +import random + + +DB = ["hello", "world", "apple", "banana", "hippopotamus"] + + +class Word(object): + def __init__(self): + self.data = list(random.choice(DB)) + + def __iter__(self): + for element in self.data: + yield element + + def __len__(self): + return len(self.data) + + def is_letter_in_word(self, letter): + if letter in self.data: + return True + else: + return False + + +class Game(object): + def __init__(self): + self.word = Word() + self.tries = len(self.word) * 3 + self.letters_found = [] + + def play_turn(self, letter): + if self.tries == 0: + return False + self.letters_found.append(letter) + if self.word.is_letter_in_word(letter): + if self.is_word_found(): + return True + self.tries -= 1 + return None + + def get_hidden_word(self): + hidden = "" + for letter in self.word: + if letter in self.letters_found: + hidden += letter + else: + hidden += "*" + return hidden + + def is_word_found(self): + word = self.get_hidden_word() + if "*" in word: + return False + else: + return True + + +class Controller(object): + def __init__(self, model): + if isinstance(model, Game): + self.model = model + + def set_view(self, view): + if isinstance(view, CommandLineInterface): + self.view = view + + def submit_letter(self, letter): + status = self.model.play_turn(letter) + if status: + self.view.show_message("congragulations! you found it!") + return True + elif status == False: + self.view.show_message("better luck next time...") + return True + else: + self.view.show_message("you have {} tries left".format(self.model.tries)) + + def request_hidden_word(self): + self.view.show_message(self.model.get_hidden_word()) + + def request_new_game(self): + self.model = Game() + + +class CommandLineInterface(object): + def __init__(self, controller): + self.controller = controller + + def ask_for_letter(self): + while True: + letter = input("your letter please: ") + if len(letter) != 1: + print("only one letter! no cheating!") + continue + if not letter.isalpha(): + print("letters only please, no numbers nor spaces...") + continue + else: + break + return letter.lower() + + def ask_for_bool(self, msg): + while True: + result = input(msg).lower() + if result.startswith("y"): + status = True + break + elif result.startswith("n"): + status = False + break + else: + print("please answer y(es) or n(o)") + return status + + def show_message(self, msg): + print(msg) + + def run(self): + while True: + self.controller.request_hidden_word() + letter = self.ask_for_letter() + status = self.controller.submit_letter(letter) + if status: + status = self.ask_for_bool("do you want to play a new game?") + if status: + self.controller.request_new_game() + else: + break + self.show_message("bye bye!") + + +if __name__ == "__main__": + model = Game() + controller = Controller(model) + view = CommandLineInterface(controller) + controller.set_view(view) + view.run() +``` + +
+ +
+ + ## Trivial pursuit multiple choice game We can fetch questions for an online [api](https://opentdb.com/api_config.php) to make a game.