Trying to create bagel game in python - python

I am getting this error. Please help me explain the cause and the meaning of the error
Traceback (most recent call last):
File "E:\Python\bagels.py", line 61, in <module>
while len(guess) != NUMDIGITS or not isOnlyDigits(guess):
TypeError: object of type 'builtin_function_or_method' has no len()
I am doing lessons from invent with python and stuck on this lesson
https://inventwithpython.com/chapter11.html
here is my code
import random
def getSecretNum(numDigits):
numbers = list(range(10))
random.shuffle(numbers)
secretNum = ''
for i in range(numDigits):
secretNum += str(numbers[i])
return secretNum
def getClues(guess, secretNum):
if guess == secretNum:
return 'You got it!'
clue = []
for i in range(len(guess)):
if guess[i] == secretNum[i]:
clue.append('fermi')
elif guess[i] in secretNum:
clue.append('Pico')
if len(clue) == 0:
return 'Bagels'
clue.sort()
return ' '.join(clue)
def isOnlyDigits(num):
if num == '':
return False
for i in num:
if i not in '0 1 2 3 4 5 6 7 8 9'.split():
return False
return True
def playAgain():
print('Do you want to play again?(yes or no)')
return input().lower().startswith('y')
NUMDIGITS = 3
MAXGUESS = 10
print('I am thinking of a %s-digit number. Try to guess what it is.' %(NUMDIGITS))
print('here are some clues:')
print('When I say: That means:')
print(' Pico One digit is correct but in the wrong position.')
print(' Fermi One digit is correct and in right position.')
print(' Bagels No digit is correct.')
while True:
secretNum = getSecretNum(NUMDIGITS)
print('I have thought of a number. You have %s guesses to guess it' %(MAXGUESS))
numGuesses = 1
while numGuesses <= MAXGUESS:
guess = ''
while len(guess) != NUMDIGITS or not isOnlyDigits(guess):
print('Guess #%s: ' % (numGuesses))
guess = input
clue = getClues(guess, secretNum)
print(clue)
numGuesses ++ 1
if guess == secretNum:
break
if numGuesses > MAXGUESS:
print('You ran out of guesses. The answer was %s. ' %(secretNum))
if not playAgain():
break

In the while loop you overwrite guess with the builtin function input.
You need to call the input function (please notice the extra pair of parentheses).
while len(guess) != NUMDIGITS or not isOnlyDigits(guess):
print('Guess #%s: ' % (numGuesses))
guess = input()

The problem is here:
guess = input
clue = getClues(guess, secretNum)
guess is now a reference to input, which is a python built-in function (like the error said).
You might want to do
guess = int(input("please enter guess"))

Related

What is the best way to make a guessing loop in python?

Basically I'm trying to make a guessing game. There are 3 questions and you have 3 guesses for every question. The problem is I'm bad at coding, this is only my first time.
print("Guessing Game")
player_name = input("Hi! What's your name? ")
number_of_guesses1 = 0
number_of_guesses2 = 0
number_of_guesses3 = 0
guess1 = input("What is the most popular car company in America? ")
while number_of_guesses1 < 3:
number_of_guesses1 += 1
if guess1 == ("Ford"):
break
if guess1 == ("Ford"):
print('You guessed the answer in ' + str(number_of_guesses1) + ' tries!')
else:
guess2 = input("Try again:")
if guess2 == ("Ford"):
print('You guessed the answer in ' + str(number_of_guesses1) + ' tries!')
else:
guess3 = input("Try again:")
if guess3 == ("Ford"):
print('You guessed the answer in ' + str(number_of_guesses1) + ' tries!')
else:
print('You did not guess the answer, The answer was Ford')
guess1b = input("What color do you get when you mix red and brown?")
while number_of_guesses2 < 3:
number_of_guesses2 += 1
if guess1 == ("Maroon"):
break
if guess1b == ("Maroon"):
print('You guessed the answer in ' + str(number_of_guesses1) + ' tries!')
else:
guess2b = input("Try again:")
if guess2b == ("Maroon"):
print('You guessed the answer in ' + str(number_of_guesses1) + ' tries!')
else:
guess3b = input("Try again:")
if guess3b == ("Maroon"):
print('You guessed the answer in ' + str(number_of_guesses1) + ' tries!')
else:
print('You did not guess the answer, The answer was Maroon')
This code kind of works, but only if you get the answer wrong 2 times in a row for every question lol. I also haven't thought of a way to implement a score keeper yet (at the end I want it to say how many points you got out of 3.) The code also is obviously not done. Basically, my questions are: How come when I get the answer wrong once and then get it right on the second try it says that it took 3 tries? And if you get the answer right on the first or second try how can I make it so it ignores the remaining tries you have left? This is the error code for example if I get it right on the second try:
Traceback (most recent call last):
File "main.py", line 20, in <module>
if guess3 == ("Ford"):
NameError: name 'guess3' is not defined
By utilizing the data structures within Python and a couple of functions, you can simplify your code considerably as shown below:
from collections import namedtuple
# Create a tuyple containing the Question, number of allowed tries and the answer
Question = namedtuple("Question", ["quest", 'maxTries', 'ans'])
def askQuestion(quest: str, mxTry: int, ans: str) -> int:
""" Ask the question, process answer, keep track of tries, return score"""
score = mxTry
while score > 0:
resp = input(quest)
if resp.lower() == ans:
print('Yes, you got it')
break
else:
score -= 1
print(f'Sorry {resp} is incorrect, try again')
if score == 0:
print("Too Bad, you didn't get the correct answer.")
print(f"The correct answer is {ans}")
return score
def playGame():
# Create a list of questions defiend using the Question structure defined above
question_list =[Question('What is the most popular car company in America? ' , 3, 'ford'),
Question("What color do you get when you mix red and brown?", 3, 'maroon')]
plyr_score = 0
for q in question_list:
plyr_score += askQuestion(q.quest, q.maxTries, q.ans)
print(f'Your final score is {plyr_score}')
The above approach allows you to extend the question repertoire as well as provide a different number of max tries by question.
simply execute playGame() to run the game
Don't use a different variable to keep track of each guess, instead just use one variable, and continually update it using input(). Then you can check it over and over again, without writing a whole mess of if-else statements. For keeping track of the number correct, you can use a variable, and increment it every time a correct answer is entered.
print("Guessing Game")
player_name = input("Hi! What's your name? ")
score = 0
answer1 = "Ford"
answer2 = "Maroon"
guess = input("What is the most popular car company in America? ")
number_of_guesses = 1
while guess != answer1 and number_of_guesses < 3:
guess = input("Try again: ")
number_of_guesses += 1
if guess == answer1:
print('You guessed the answer in ' + str(number_of_guesses) + ' tries!')
score += 1
else:
print('You did not guess the answer, The answer was Ford')
guess = input("What color do you get when you mix red and brown? ")
number_of_guesses = 1
while guess != answer2 and number_of_guesses < 3:
guess = input("Try again: ")
number_of_guesses += 1
if guess == answer2:
print('You guessed the answer in ' + str(number_of_guesses) + ' tries!')
score += 1
else:
print('You did not guess the answer, The answer was Maroon')
print('You got ' + str(score) + ' out of 2 questions.')

Why does my output execute multiple print functions?

I'm working on a guessing game where the user inputs a number until they get it correct. I'm trying to understand why my output creates multiple print functions if I don't guess in the first try. But if I guess the answer correctly on first try, it prints correctly.
ans = 5
def function(guess, ans):
if ans != guess:
if ans < guess:
print("Guess lower")
return False
elif ans > guess:
print("Guess higher")
return False
elif ans == guess:
print("Correct!")
def init():
print("Guess a number between 1 and 10: ")
guess = int(input())
main(guess)
def main(guess):
while function(guess, ans) == False:
init()
function(guess, ans)
break
init()
Outputs:
Correct guess on first attempt:
Guess a number between 1 and 10:
5
Correct!
Correct guess on third attempt:
Guess a number between 1 and 10:
4
Guess higher
Guess a number between 1 and 10:
6
Guess lower
5
Correct!
Guess lower
Guess higher
It is because of this:
The answer is incorrect. So you go to init()
The init() again passes the argument to main() function. So, it has become a sort of recursion where the function is executed again.
Here is what your code is doing.
main()
|__init()
| |
| main()
| |
| function()
|
function()
That is why you are getting that output.
Also, this hierarchy increases 1 level with each incorrect answer.
Instead, here is what you can do:
ans = 5
guess=0
def function(guess, ans):
if ans != guess:
if ans < guess:
print("Guess lower")
return False
elif ans > guess:
print("Guess higher")
return False
elif ans == guess:
print("Correct!")
return True
def init(guess):
while True:
print("Guess a number between 1 and 10: ")
guess = int(input())
if function(guess, ans):
break
init(guess)
The answer to your question is that when your input isn't correct the first time, your code is entering into a recursive call because of the main(guess) line that you've put in the init() function which later is returning those extra lines of output that you don't want to see. (For n incorrect tries, you'll be seeing n such extra lines after your code prints out Correct! depending on whether your previous inputs were higher or lower.)
First, there is no need of ans != guess, you can simply make a conditional with if-elif-else condition like:
def function(guess, ans):
if ans < guess:
print("Guess lower")
return False
elif ans > guess:
print("Guess higher")
return False
else: # This will automatically be ans = guess case
print("Correct!")
return True # You weren't returning any value here and I suppose you wanted to exploit this
You'll need to remove the main(guess) line from your init() function to avoid recursive-call and add a line to return guess i.e. user input so that you can pass it on to the main() function.
def init():
print("Guess a number between 1 and 10: ")
guess = int(input())
return guess
Now, you need to modify your main function like-
def main():
while True:
guess = init()
if function(guess, ans):
break
You can call the main function as shown below and it'll work-
main()
PS- There are many ways to fix your code into the one which does what you wish to do and this is just one of those ways.
All explanations were given by #Sujay.
This is an alternative with local variable.
ans = 5
def guess_my_number(guess, ans): # <- choose a meaning function name
if ans != guess:
if ans < guess:
print("Guess lower")
return False
elif ans > guess:
print("Guess higher")
return False
elif ans == guess:
print("Correct!")
return True # <- It's important to return True
def main():
# If user guessed the answer, this variable is set to True
good_answer = False
# So while the user has not found, continue to ask him a number
while good_answer != True:
print("Guess a number between 1 and 10: ")
guess = int(input())
good_answer = guess_my_number(guess, ans)
main()
Just remove function(guess, ans) in the main() function. you are already using while loop and returning bool values from function()
In the function function () return true when value is satisfied

How do I fix the ValueError?

I used the Python for Kids book to learn the basics of Python 2.7.14, and there's this Python written game in it. It is a number guessing game, but in line 40 of the code, the ValueError keeps popping up. How do I fix this?
Line 40: if comnum == int(players_guess):
Whole code:
# New constants
QUIT = -1
quit_text = 'q'
quit_message = 'Thanks for playing'
comfirm_quit_message = 'Are you sure you want to quit (Y/N)?'
# New comfirm_quit funtion
def comfirm_quit():
"""Ask user to comfirm that they want to quit
default to yes
Return True (yes, quit) or False (no, don't quit) """
spam = raw_input(comfirm_quit_message)
if spam == 'n':
return False
else:
return True
def do_guess_round():
"""Choose a random number, ask the user for a guess
check wether the guess is true
and repeat until the user is correct"""
comnum = random.randint(1, 100)
numofguess = 0
while True:
players_guess = raw_input('Input your choice:')
# new if clause to test against quit
if players_guess == quit_text:
if comfirm_quit():
QUIT
else:
continue # that is, do next round of loop
numofguess = numofguess + 1
if comnum == int(players_guess):
print('Correct!')
elif comnum > int(players_guess):
print('Too low')
else:
print('Too high')
totalrounds = 0
totalguesses = 0
while True:
totalrounds = totalrounds + 1
print('Starting round number: ' + str(total_rounds))
print('Let the guessing begin!!!')
thisround = do_guess_round()
# new if condition (and clode block) to test against quit
if thisround == 0:
totalrounds = totalrounds - 1
avg = str(totalguesses / float(totalrounds))
if totalrounds == 0:
statsmsg = 'You completed no rounds. ' +\
'Please try again later.'
else:
statsmsg = 'You played ' + str(totalrounds) +\
' rounds, with an averave of ' +\
str(avg)
break
totalguesses = totalguesses + thisround
avg = str(totalguesses / float(totalrounds))
print("You took " + str(thisround) + " guesses")
print("Your guessing average = " + str(avg))
print("")
# Added exit messages
print(statsmsg)
(I have changed the name of the variables in the code, so the variables won't be the same from the book.)
Error Message: Traceback (most recent call last):
File "C:\Users\26benk\Desktop\Programming\PY 2\Programs\Number_guess_game.py", line 40, in <module>
if comnum == int(players_guess):
ValueError: invalid literal for int() with base 10: '0.1'
Please remove the type conversion in the line like this if comnum == int(players_guess): to if comnum == players_guess: and add these lines next to the raw input,
players_guess = raw_input(prompt)
try:
players_guess = int(players_guess)
except ValueError:
players_guess = str(players_guess)
This will definitely solve the case.
That's because you dont have a break statement to pull you out of the loop where you are checking whether the user guesses the number correctly or not.
In this loop,
while True:
players_guess = raw_input(prompt)
# new if clause to test against quit
if players_guess == quit_text:
if comfirm_quit():
QUIT
else:
continue # that is, do next round of loop
numofguess = numofguess+1
if comnum == int(players_guess):
print('Correct!')
elif comnum > int(players_guess):
print('Too low')
else:
print('Too high')
even if the user guesses correctly, he is asked for a raw_input because the loop is still active. If you hit enter, you will get the ValueError because you are trying the int function on an empty string. To avoid that, change your loop to
while True:
players_guess = raw_input(prompt)
# new if clause to test against quit
if players_guess == quit_text:
if comfirm_quit():
QUIT
else:
continue # that is, do next round of loop
numofguess = numofguess+1
if comnum == int(players_guess):
print('Correct!')
break
elif comnum > int(players_guess):
print('Too low')
else:
print('Too high')
There are other problems with this code as well. The first while loop has to be a function of the do_guess_round function

higher or lower game unexpected EOF while parsing

need help with a higher or lower game I think the problem has something to do with the loop. I have been told been told to add an except but I have no idea where to add it
print('Welcome to higher or lower game')
input('press enter to start.\n')
import random
Max = 10
Min = 0
num = random.randint(1, 10)
print('your starting number is a ' + str(num))
while 'well done.\n' :
guess = input('higher (h) or lower (l).\n')
new_num = random.randint(1, 10)
print('your new number is a ' + str (new_num))
try :
if new_num > num and guess == 'h':
print('well done.\n')
elif new_num < num and guess == 'l':
print('well done.\n')
break
if num and guess == 'l' and new_num > num and guess:
print('game over')
elif num and guess == 'h' and new_num < num and guess:
print('game over')
else:
print('game over you got a score of ' + str(score))
You do not have an except clause in the try statement. That clause is required unless you have a finally clause.
You really shouldn't have a try statement there. You could take it out and just go with some if and elif statements.
Example:
import random
number = random.randint(1,10)
lives = 3
Success = False
while lives > 0:
guess = int(input("What is your guess between 1 and 10? \r\n"))
if guess > number:
print("Too high! Go lower. \r\n")
lives -= 1
elif guess < number:
print("Too low! Go higher. \r\n")
lives -= 1
elif guess == number:
print("Congratulations, you win!")
global Success = True
break
if Success != True:
print("Sorry. Try again! The number was ", number, ".")
As far as I understand, try statements are mainly used for error handling.

User input Exit to break while loop

I'm doing an assignment for the computer to generate a random number and have the user input their guess. The problem is I'm supposed to give the user an option to input 'Exit' and it will break the While loop. What am I doing wrong? I'm running it and it says there's something wrong with the line guess = int(input("Guess a number from 1 to 9: "))
import random
num = random.randint(1,10)
tries = 1
guess = 0
guess = int(input("Guess a number from 1 to 9: "))
while guess != num:
if guess == num:
tries = tries + 1
break
elif guess == str('Exit'):
break
elif guess > num:
guess = int(input("Too high! Guess again: "))
tries = tries + 1
continue
else:
guess = int(input("Too low! Guess again: "))
tries = tries + 1
continue
print("Exactly right!")
print("You guessed " + str(tries) + " times.")
The easiest solution is probably to create a function that gets the displayed message as an input and returns the user input after testing that it fulfils your criteria:
def guess_input(input_message):
flag = False
#endless loop until we are satisfied with the input
while True:
#asking for user input
guess = input(input_message)
#testing, if input was x or exit no matter if upper or lower case
if guess.lower() == "x" or guess.lower() == "exit":
#return string "x" as a sign that the user wants to quit
return "x"
#try to convert the input into a number
try:
guess = int(guess)
#it was a number, but not between 1 and 9
if guess > 9 or guess < 1:
#flag showing an illegal input
flag = True
else:
#yes input as expected a number, break out of while loop
break
except:
#input is not an integer number
flag = True
#not the input, we would like to see
if flag:
#give feedback
print("Sorry, I didn't get that.")
#and change the message displayed during the input routine
input_message = "I can only accept numbers from 1 to 9 (or X for eXit): "
continue
#give back the guessed number
return guess
You can call this from within your main program like
#the first guess
guess = guess_input("Guess a number from 1 to 9: ")
or
#giving feedback from previous input and asking for the next guess
guess = guess_input("Too high! Guess again (or X to eXit): ")
You are trying the parse the string 'Exit' to an integer.
You can add a try/except around the casting line and handle invalid input.
import random
num = random.randint(1,9)
tries = 1
guess = 0
guess = input("Guess a number from 1 to 9: ")
try:
guess = int(guess) // try to cast the guess to a int
while guess != num:
if guess == num:
tries = tries + 1
break
elif guess > num:
guess = int(input("Too high! Guess again: "))
tries = tries + 1
continue
else:
guess = int(input("Too low! Guess again: "))
tries = tries + 1
continue
print("Exactly right!")
print("You guessed " + str(tries) + " times.")
except ValueError:
if guess == str('Exit'):
print("Good bye")
else:
print("Invalid input")

Categories

Resources