Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 36 additions & 15 deletions game.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,46 @@ def snowman(snowman_word):
"""Complete the snowman function
replace "pass" below with your own code
It should print 'Congratulations, you win!'
If the player wins and,
If the player wins and,
'Sorry, you lose! The word was {snowman_word}' if the player loses
"""
pass
correct_letter_guess_statuses = build_letter_status_dict(snowman_word)
wrong_guesses_list = []

while len(wrong_guesses_list) < SNOWMAN_MAX_WRONG_GUESSES and not is_word_guessed(snowman_word, correct_letter_guess_statuses) :
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this particular program, we have two potential finish conditions: 1. We find the word, 2. We use up all our guesses. One is a win condition and one is a lose condition.

There are a couple different ways we could handle these two conditions:

  1. Place both in a compound conditional within the while loop.
  2. Use one as the while loop conditional and nest the other conditional within the while loop.

You have opted for the former, which Is good, but it does increase a bit of the work that needs to be done outside the loop. This happens for the following reasons:

If we check both for each iteration, our loop ends if either the win or lose condition is met. This means that we are going to have to make an additional and unnecessary check after the loop to see which condition was met. If we somehow resolved one win condition inside the loop, we would remove the need for extra checks after the while loop has complete.

If we meet one of the conditions inside the loop, we can exit the function early with an explicit return. This resolves one of our conditions that we no longer have to worry about later on.

Overall your approach works, but it does add a little bit of extra code!


user_input = get_letter_from_user(correct_letter_guess_statuses, wrong_guesses_list)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When it comes to writing Python code, one of the guides you'll see us reference is the PEP 8 Style Guide. This is a guide for best practices when it comes to styling our code. One of the most common things we see is to try and keep individual lines of code under 79 characters. This line currently goes past that limit! It won't cause the code to break or anything, but it is a good thing to keep in mind in terms of readability and best practices!

I currently see two possible fixes here:

  1. Shorter and more concise variable names:

    • While there is no hard and fast rule on how long variable names should be, we could first try shortening the variable names we use here (correct_letter_guess_statuses and wrong_guesses_list) as they are on the longer side. That being said, these names match the parameters for the function you use to call them, which is good practice, so we'll need a different approach (but shorter variable names can help with this in other circumstances).
  2. Restyle the Function Call:

    • This is a great trick to have up your sleeve when making a function call that either includes multiple parameters or starts to approach that 79 character line limit! We can drop the parameters to the next line(s) to look something like the following:
    Suggested change
    user_input = get_letter_from_user(correct_letter_guess_statuses, wrong_guesses_list)
    user_input = get_letter_from_user(
    correct_letter_guess_statuses,
    wrong_guesses_list
    )
    • This is known as Implicit Line Continuation in Python. Whenever we have information nested inside parentheses, brackets or curly braces, we can drop the nested information to new lines without any specific notation!


if user_input in snowman_word :
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we receive a letter from the user, we want to check to see if it exists within the word or not. Given the way this program is set up, we end up with two different collections that hold all the letters of the word, a string (snowman_word) and a dictionary (correct_letter_guess_statuses).

While we could check either one for the letter we've received, searching within a dictionary is ever so slightly more efficient than searching through a string (We'll talk more about why in Unit 1)! With that in mind, we could make the following small tweak to increase the efficiency of our solution:

Suggested change
if user_input in snowman_word :
if user_input in correct_letter_guess_statuses:

print("You guessed a letter that's in the word!")
correct_letter_guess_statuses[user_input] = True
print(generate_word_progress_string(snowman_word, correct_letter_guess_statuses))

else :
print(f"The letter {user_input} is not in the word!")
wrong_guesses_list.append(user_input)
print_snowman_graphic(len(wrong_guesses_list)-1)

if is_word_guessed(snowman_word, correct_letter_guess_statuses) :
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we moved this conditional from where it currently is to inside the loop, we could handle one of the ending conditions inside the loop and remove it from the while conditionals. We could then exit the function early with an explicit return statement! That allows us only deal with the lose condition outside of the loop. In fact, we would know that the user has lost if the loop ends, so we could just include the print statement on line 43 outside the loop!

print("Congratulations, you win!")
else :
print(f"Sorry, you lose! The word was {snowman_word}")



def print_snowman_graphic(wrong_guesses_count):
"""This function prints out the appropriate snowman image
"""This function prints out the appropriate snowman image
depending on the number of wrong guesses the player has made.
"""

for i in range(SNOWMAN_MAX_WRONG_GUESSES - wrong_guesses_count, SNOWMAN_MAX_WRONG_GUESSES):
print(SNOWMAN_GRAPHIC[i])


def get_letter_from_user(correct_letter_guess_statuses, wrong_guesses_list):
"""This function takes the snowman_word_dict and the list of characters
"""This function takes the snowman_word_dict and the list of characters
that have been guessed incorrectly (wrong_guesses_list) as input.
It asks for input from the user of a single character until
It asks for input from the user of a single character until
a valid character is provided and then returns this character.
"""

Expand All @@ -48,33 +69,33 @@ def get_letter_from_user(correct_letter_guess_statuses, wrong_guesses_list):
print("You must input a letter!")
elif len(user_input_string) > 1:
print("You can only input one letter at a time!")
elif (user_input_string in correct_letter_guess_statuses
and correct_letter_guess_statuses[user_input_string]):
elif (user_input_string in correct_letter_guess_statuses
and correct_letter_guess_statuses[user_input_string]):
print("You already guessed that letter and it's in the word!")
elif user_input_string in wrong_guesses_list:
print("You already guessed that letter and it's not in the word!")
else:
valid_input = True

return user_input_string


def build_letter_status_dict(snowman_word):
"""This function takes snowman_word as input and returns
a dictionary with a key-value pair for each letter in
"""This function takes snowman_word as input and returns
a dictionary with a key-value pair for each letter in
snowman_word where the key is the letter and the value is `False`.
"""

letter_status_dict = {}
for letter in snowman_word:
letter_status_dict[letter] = False
return letter_status_dict


def print_word_progress_string(snowman_word, correct_letter_guess_statuses):
"""
This function takes the snowman_word and snowman_word_dict as input.
It calls another function to generate a string representation of the
It calls another function to generate a string representation of the
user's progress towards guessing snowman_word and prints this string.
"""

Expand All @@ -85,8 +106,8 @@ def print_word_progress_string(snowman_word, correct_letter_guess_statuses):
def generate_word_progress_string(snowman_word, correct_letter_guess_statuses):
"""
This function takes the snowman_word and snowman_word_dict as input.
It creates and returns an output string that shows the correct letter
guess placements as well as the placements for the letters yet to be
It creates and returns an output string that shows the correct letter
guess placements as well as the placements for the letters yet to be
guessed.
"""

Expand Down