Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python Coding Error
#1
import random


POTATOPICS = ['''

     +------+
     |      |
            |
            |
            |
            |
            |
===============''', '''

     +------+
     |      |
   _____    |
  /     \   |
 |       |  |
  \_____/   |
            |
===============''', '''

     +------+
     |      |
   _____    |
  /     \   |
 |    O  |  |
  \_____/   |
            |
===============''', '''

     +------+
     |      |
   _____    |
  /     \   |
 | O  O  |  |
  \_____/   |
            |
===============''', '''

     +------+
     |      |
   _____    |
  /     \   |
(( O  O  |  |
  \_____/   |
            |
===============''', '''

     +------+
     |      |
   _____    |
  /     \   |
(( O  O  )) |
  \_____/   |
            |
===============''', '''

     +------+
     |      |
   _____    |
  /     \   |
(( 0  0  )) |
  \__o__/   |
            |
===============
         ''']
words={
   'Colors':'red orange yellow green blue indigo violet white black brown'.split(),
   'Shapes':'square triangle rectangle circle ellipse rhombus trapezoid chevron pentagon hexagon septagon octagon'.split(),
   'Fruits':'apple orange lemon lime pear watermelon grape grapefruit cherry banana cantaloupe mango strawberry tomato'.split(),
   'Animals':'bat bear beaver cat cougar crab deer dog donkey duck eagle fish frog goat leech lion lizard monkey moose mouse otter owl panda python rabbit rat shark sheep skunk squid tiger turkey turtle weasel whale wolf wombat zebra'.split()
}

def getRandomWord(wordDict):
   # This function returns a random string from the passed dictionary of lists of strings, and the key also.
   # First, randomly select a key from the dictionary:
   wordKey = random.choice(list(wordDict.keys()))
   # Second, randomly select a word from the key's list in the dictionary:
   wordIndex = random.randint(0, len(wordDict[wordKey]) - 1)
   return [wordDict[wordKey][wordIndex], wordKey]

def displayBoard(POTATOPICS, missedLetters, correctLetters, secretWord):
   print(POTATOPICS[len(missedLetters)])
   print()

   print('Missed letters:', end=' ')
   for letter in missedLetters:
       #prints letters with dividers at the start and end; also makes letter appear in uppercase
       print('{ '+letter.upper(), end=' }')
   print()

   blanks = '_' * len(secretWord)

   for i in range(len(secretWord)): # replace blanks with correctly guessed letters
       if secretWord[i] in correctLetters:
           blanks = blanks[:i] + secretWord[i] + blanks[i+1:]

   for letter in blanks: # show the secret word with spaces in between each letter
       #makes letter appear uppercase
       print(letter.upper(), end=' ')
   print()

def getGuess(alreadyGuessed):
   # Returns the letter the player entered. This function makes sure the player entered a single letter, and not something else.
   while True:
       print('Guess a letter.')
       guess = input()
       guess = guess.lower()
       if len(guess) != 1:
           print('Please enter a single letter.')
       elif guess in alreadyGuessed:
           print('You have already guessed that letter. Choose again.')
       elif guess not in 'abcdefghijklmnopqrstuvwxyz':
           print('Please enter a LETTER.')
       else:
           return guess

def playAgain():
   # This function returns True if the player wants to play again, otherwise it returns False.
   print('Do you want to play again? (yes or no)')
   return input().lower().startswith('y')

print('P O T A T O M A N')
missedLetters = ''
correctLetters = ''
secretWord = getRandomWord(words)
gameIsDone = False

while True:
   displayBoard(POTATOPICS, missedLetters, correctLetters, secretWord)

   # Let the player type in a letter.
   guess = getGuess(missedLetters + correctLetters)

   if guess in secretWord:
       correctLetters = correctLetters + guess

       # Check if the player has won
       foundAllLetters = True
       for i in range(len(secretWord)):
           if secretWord[i] not in correctLetters:
               foundAllLetters = False
               break
       if foundAllLetters:
           print('Yes! The secret word is "' + secretWord + '"! You have won!')
           gameIsDone = True
   else:
       missedLetters = missedLetters + guess

       # Check if player has guessed too many times and lost
       if len(missedLetters) == len(POTATOPICS) - 1:
           displayBoard(POTATOPICS, missedLetters, correctLetters, secretWord)
           print('You have run out of guesses!\nAfter ' + str(len(missedLetters)) + ' missed guesses and ' + str(len(correctLetters)) + ' correct guesses, the word was "' + secretWord + '"')
           gameIsDone = True

   # Ask the player if they want to play again (but only if the game is done).
   if gameIsDone:
       if playAgain():
           missedLetters = ''
           correctLetters = ''
           gameIsDone = False
           secretWord = getRandomWord(words)
       else:
           break
I have been getting a two letter word every time that I try to run this program, and it doesn't have a vowel in it. When I run out of guesses, it gives me an error message. Try running the code for more information. Any information is helpful!

Thanks!
-MGallo
Reply
#2
Please post the error code, in it's entirety, between the error code tags.
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
Reply
#3
getRandomWord returns a list of the word and the category for the word. That list is what you are assigning to secretWord. That's why it always thinks the word is two letters long (the length of the list is two), and that's why you get the error (secretWord is a list, which doesn't convert to string implicitly for string addition).

If you change lines 129 and 164 to this:

secretWord, wordCategory = getRandomWord(words)
it fixes the problem. This is called 'unpacking', or 'tuple assignment', where you assign a sequence on the right to a set of variables on the left.

You can also use random.choice for both selections in getRandomWord:

def getRandomWord(wordDict):
   # This function returns a random string from the passed dictionary of lists of strings, and the key also.
   # First, randomly select a key from the dictionary:
   wordKey = random.choice(list(wordDict.keys()))
   # Second, randomly select a word from the key's list in the dictionary:
   word = random.choice(wordDict[wordKey])
   return [word, wordKey]
You might also want to check out string formatting: https://docs.python.org/3/library/string...ing-syntax. It's more versatile than adding strings.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#4
(Jul-20-2017, 12:40 PM)ichabod801 Wrote: getRandomWord returns a list of the word and the category for the word. That list is what you are assigning to secretWord. That's why it always thinks the word is two letters long (the length of the list is two), and that's why you get the error (secretWord is a list, which doesn't convert to string implicitly for string addition).

If you change lines 129 and 164 to this:

secretWord, wordCategory = getRandomWord(words)
it fixes the problem. This is called 'unpacking', or 'tuple assignment', where you assign a sequence on the right to a set of variables on the left.

You can also use random.choice for both selections in getRandomWord:

def getRandomWord(wordDict):
   # This function returns a random string from the passed dictionary of lists of strings, and the key also.
   # First, randomly select a key from the dictionary:
   wordKey = random.choice(list(wordDict.keys()))
   # Second, randomly select a word from the key's list in the dictionary:
   word = random.choice(wordDict[wordKey])
   return [word, wordKey]
You might also want to check out string formatting: https://docs.python.org/3/library/string...ing-syntax. It's more versatile than adding strings.

Thanks, that worked! However, the first time I play the program it grabs a random word how it's supposed to, but the second it still gives me the 2 letter blanks that I described above and an error message:

Traceback (most recent call last):
Error:
 File "/Documents/Untitled.py", line 155, in <module>    print('You have run out of guesses!\nAfter ' + str(len(missedLetters)) + ' missed guesses and ' + str(len(correctLetters)) + ' correct guesses, the word was "' + secretWord + '"') TypeError: must be str, not list
After playing around with it a bit more, I found out that the program was still grabbing the category and word, it just wasn't implementing them into the hangman display.

NEVERMIND! fixed the problem! I was forgetting to redeclare the randomWord and randomCategory when the player decides that they want to play again! Thank you everybody!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Coding error? Mugwash 4 3,095 Apr-06-2018, 06:57 PM
Last Post: Mugwash
  New to coding. An error occurs with no definition westernwhiskey 4 2,935 Mar-15-2018, 12:37 PM
Last Post: westernwhiskey

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020