Possum - YanYi C.#22
Conversation
anselrognlie
left a comment
There was a problem hiding this comment.
Looks good! Please review my comments, and let me know if you have any questions. Nice job!
| correct_letter_guess_statuses = build_letter_status_dict(snowman_word) | ||
| wrong_guesses_list = [] |
There was a problem hiding this comment.
👍 These are the two pieces of data we need to make use of our other helper functions for tracking correct and incorrect guesses. Tracking the letter status involves using a dictionary with a particular structure, which our build_letter_status_dict helper is able to calculate from the random word.
| correct_letter_guess_statuses = build_letter_status_dict(snowman_word) | ||
| wrong_guesses_list = [] | ||
|
|
||
| while len(wrong_guesses_list) < SNOWMAN_MAX_WRONG_GUESSES: |
There was a problem hiding this comment.
👍 We can use a single condition on our loop by performing checks for additional conditions that could end the game (such as guessing the word) within the loop itself.
| wrong_guesses_list = [] | ||
|
|
||
| while len(wrong_guesses_list) < SNOWMAN_MAX_WRONG_GUESSES: | ||
| user_input = get_letter_from_user(correct_letter_guess_statuses, wrong_guesses_list) |
There was a problem hiding this comment.
Since we don't display the word status until after the guess, the player doesn't get to see the length of the word before guessing. This wasn't a requirement, but it would be nice to have from a gameplay perspective.
|
|
||
| while len(wrong_guesses_list) < SNOWMAN_MAX_WRONG_GUESSES: | ||
| user_input = get_letter_from_user(correct_letter_guess_statuses, wrong_guesses_list) | ||
| # Use the new variable snowman_word instead of the constant variable SNOWMAN_WORD here: |
There was a problem hiding this comment.
It looks like you actually used correct_letter_guess_statuses rather than snowman_word. Make sure that any comments in your code match the actual code, as mismatched comments can be confusing.
| user_input = get_letter_from_user(correct_letter_guess_statuses, wrong_guesses_list) | ||
| # Use the new variable snowman_word instead of the constant variable SNOWMAN_WORD here: | ||
| # this is hint 4 in 'Using the Letter Status Dictionary' | ||
| if user_input in correct_letter_guess_statuses: |
There was a problem hiding this comment.
👍 Nice decision to check whether the letter was in the word by using the status dict rather than the word itself. Checking for the presence of a value in a dict is more efficient than checking in a str, even when both use the in operator. It won't matter much in this small program, but it's helpful to start thinking about these differences and biasing our choices towards efficiency!
| wrong_guesses_list.append(user_input) | ||
|
|
||
| # this print_snowman is from the helper function below at line 123 | ||
| print_snowman_graphic(len(wrong_guesses_list)) |
There was a problem hiding this comment.
👍 Nice decision to get the count of wrong guesses directly from the length of the wrong guesses list when needed. If we had used a separate variable to track the count, it would be possible for the values to become out of sync, leading to player confusion. Though unlikely in a program this short, in longer programs it can be more difficult to be sure that related values are always updated together. Forgetting to update both in one place can lead to them drifting.
In some languages, getting the length of certain data types is a relatively slow operation. Python is fast for most built-in containers (and strings), so it's fine to call len() as many times as we need to. But we do need to understand the costs of operations in the languages we are working in. In a language where getting the length of a container might be costly (or even impossible), it might be worthwhile (or necessary) to track the count in a separate variable.
|
|
||
| # this print_snowman is from the helper function below at line 123 | ||
| print_snowman_graphic(len(wrong_guesses_list)) | ||
| print(f"Wrong guesses:{wrong_guesses_list}") |
There was a problem hiding this comment.
Python is able to print out a list of strings, which lets us show the wrong guesses to the player. However, we might consider writing our own function to customize the string we build (try looking into the join method of the string type) since the default output is somewhat "programmer-y." A typical player doesn't need to see the surrounding [] nor the '' around each character.
| if is_word_guessed(snowman_word, correct_letter_guess_statuses): | ||
| print("Congratulations, you win!") | ||
| return |
There was a problem hiding this comment.
👍 Because we are explicitly handling the win case and leaving the function, we know that the loop will only terminate when the number of wrong guesses has been exceeded, meaning the player has lost. Any code we place after the loop would only be run in the case that the player has lost. This would allow us to place the lose logic following the loop without using the while/else structure.
| else: | ||
| # print("Sorry, you lose! The word was {snowman_word}") | ||
| print(f"Sorry, you lose! The word was {snowman_word}") |
There was a problem hiding this comment.
Loops with else are very specific to Python. As a result, they don't get used that often, and it usually takes programmers more effort to understand logic that depends on them. You're free to use them, but it can be helpful to think about how we could express this same logic (exiting the loop with victory skips this logic, while exiting by losing runs this logic) without the use of while/else.
Sincw your win logic returned, the function will exit on victory without reaching any code that follows the loop. So if we moved this code to the area after the loop (without the else) then we would know that logic only runs when the game is lost.
Many style guides recommend avoiding while/else or for/else other than simple cases of searching through data. Here, it's being used for general logic, which makes it a little more difficult to understand.
No description provided.