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.