I am making a game which requires the user to enter a number. They get four tries, and if they get the number wrong, they get a hint.
How can I try to give only one hint for each of the four tries the user has to get the number right? For example, after the user gets the first try wrong, I would like the program to display the even_or_odd hint.
from random import randrange
new_number = randrange(1, 101)
class Hints:
def __init__(self, new_number):
self.new_number = new_number
def even_or_odd(self):
if self.new_number % 2 == 0:
print('Hint. The number is even.')
else:
print('Hint. The number is odd.')
def multiple3to5(self):
for x in range(3, 6):
n = self.new_number % x
if n == 0:
print(f'Hint. The number is a multiple of {x}', end = ' ' )
def multiple6to10(self):
for x in range(6, 11):
n = self.new_number % x
if n == 0:
print(f'Hint. The number is a multiple of x {x}', end = ' ')
print('Guess a number beteen 1 and 100.')
hint = Hints(new_number)
for x in range(1, 5):
is_answer_given = False
while not is_answer_given:
try:
user_input = int(input(f'Attempt {x}: '))
is_answer_given = True
except ValueError:
print('Please enter a numerical value.')
if user_input == new_number and x == 1: #hint after first attempt
print('You win!')
break
else:
print('Incorrect!')
hint.even_or_odd()
if user_input == new_number and x == 2: #hint after second attempt
print('You win!')
break
else:
print('Incorrect!')
hint.multiple3to5()
if user_input == new_number and x == 3: #hint after third attempt
print('You win!')
break
else:
print('Incorrect!')
hint.multiple6to10()
if x == 4:
print('You are out of attempts!')
print(f'The number was {new_number}')
break
You should make one if statement that checks for the correct answer. In the else statement you can use if - elif statements to check for the attempt number.
if user_input == new_number:
print('You win!')
break
else:
print('Incorrect!')
if x == 1:
hint.even_or_odd()
elif x == 2:
hint.multiple3to5()
elif x == 3:
hint.multiple6to10()
else:
print('You are out of attempts!')
print(f'The number was {new_number}')
The reason you see multiple hints on attempt is that for multiple if statements their condition is not true, so their 'else' block is run
Here is a neat trick:
from random import randrange
new_number = randrange(1, 101)
class Hints:
def __init__(self, new_number):
self.new_number = new_number
self.choices = {
1: self.even_or_odd,
2: self.multiple3to5,
3: self.multiple6to10
}
def run(self,key):
action = self.choices.get(key)
action()
def even_or_odd(self):
if self.new_number % 2 == 0:
print('Hint. The number is even.')
else:
print('Hint. The number is odd.')
def multiple3to5(self):
for x in range(3, 6):
n = self.new_number % x
if n == 0:
print(f'Hint. The number is a multiple of {x}', end = ' ' )
else:
print("Well, Not a multple of 3 or 5")
def multiple6to10(self):
for x in range(6, 11):
n = self.new_number % x
if n == 0:
print(f'Hint. The number is a multiple of x {x}', end = ' ')
else:
print("Well, Not a multple of 6 or 10")
print('Guess a number beteen 1 and 100.')
hint = Hints(new_number)
print(new_number)
i = 3
win = False
while i >= 1 :
is_answer_given = False
while not is_answer_given:
try:
user_input = int(input(f'Attempt {i}: '))
is_answer_given = True
except ValueError:
print('Please enter a numerical value.')
if user_input == new_number:
print('You win!, Number is: {new_number}')
win = True
break
hint.run(i)
i -= 1
if not win:
print("You lost!")
print(f"Number is {new_number}")
Related
here is the code, it's a car parking system:
import time
parking_slots = []
start = []
for i in range(6):
start.append(0)
for i in range(6):
parking_slots.append(False)
while True:
print("1.view empty\n2.add\n3.remove\n4.save\n5.load\n6.exit")
choice = int(input())
if choice == 1:
print("Empty slots are: ")
for slot in range(6):
if parking_slots[slot] == 0:
print(slot, end=" - ")
print("")
if choice == 2:
index = int(input("Enter the index of the slot: "))
if start[index] == 0:
start[index] = int(time.time())
parking_slots[index] = True
else:
print("this slot is already token, please choose another one")
if choice == 3:
index = int(input("Enter the index of the slot: "))
print("Your bill is", int(time.time()) - start[index])
parking_slots[index] = False
start[index] = 0
if choice == 4:
open("cps.txt", "w").write("")
for i in start:
open("cps.txt", "a").write(str(i) + "\n")
if choice == 5:
file = open("cps.txt", "r").readlines()
start = [float(x.strip("\n")) for x in file]
for x in range(6):
if start[x] == 0:
parking_slots = False
else:
parking_slots = True
if choice == 6:
break
the error is when I enter choice 1, it tells me bool object is not subscriptable
When choice == 5 you do
for x in range(6):
if start[x] == 0:
parking_slots = False
else:
parking_slots = True
which replaces the list that was contained in parking_slots with a plain boolean, which gives you that error when you later try to index it. Probably here you meant
for x in range(6):
if start[x] == 0:
parking_slots[x] = False
else:
parking_slots[x] = True
def get_user_choice():
global user_choice
''' 3users give their numbers to be validated'''
for i in range(1, 4):
choices = []
** choices = input("User {}, please enter 5 numbers separated by ',' :".format(i))
nums = choices.split(',')
while True:
if len(nums) != 5:
print(" Wrong choice,You have to enter 5 numbers separated by ','")
break
for nr in nums:
if nr.isdigit():
if int(nr) < 1 or int(nr) > 25:
print(" Wrong! Enter 5 Numbers between 1 and 25")
continue
else:
print(nr + " is not a number, try again")
continue
# How can i go back to ** from here????
This code corrects the logic for requesting numbers and returns the numbers selected.
def get_user_choice():
''' 3users give their numbers to be validated'''
#global user_choice--didn't understand why you needed a global user_choice so commented out for now
user_choices = []
for i in range(1, 4):
while True:
choices = input("User {}, please enter 5 numbers separated by ',' :".format(i))
nums = choices.split(',')
if len(nums) != 5:
print(" Wrong choice,You have to enter 5 numbers separated by ','")
else:
for nr in nums:
if nr.isdigit():
if int(nr) < 1 or int(nr) > 25:
print(" Wrong! Enter 5 Numbers between 1 and 25")
break
else:
print(nr + " is not a number, try again")
break
else:
user_choices.append(nums)
break
return user_choices
# Get user choices
choices = get_user_choice()
A cleaner version of the Above Code
def get_user_choice():
''' 3users give their numbers to be validated'''
invalid_numbers = lambda numbers: list(filter(lambda y: not y.isdigit(), numbers))
invalid_range = lambda numbers: list(filter(lambda y: not (1 <= int(y) <= 25), numbers))
user_choices = []
for i in range(1, 4):
while True:
choices = input("User {}, please enter 5 numbers separated by ',' :".format(i))
nums = choices.split(',')
if len(nums) != 5:
print(" Wrong choice, You have to enter 5 numbers separated by ','")
continue
p = invalid_numbers(nums)
if p:
print(*p,' are not numbers. Enter 5 numbers separaterd by "," ')
continue
p = invalid_range(nums)
if p:
print(*p, ' are out of range. Enter 5 numbers between 1 and 25')
continue
## uncomment if you wanted the number rather than strings
# nums = list(map(int, nums))
user_choices.append(nums)
break
return user_choices
choices = get_user_choice()
I have a python function and would like to retrieve a value from outside the function. How can achieve that without to use global variable. I had an idea, if functions in python are objects then this could be a right solution?
def check_difficulty():
if (difficulty == 1):
check_difficulty.tries = 10
elif (difficulty == 2):
check_difficulty.tries = 5
elif (difficulty == 3):
check_difficulty.tries = 3
try:
difficulty = int(input("Choose your difficulty: "))
check_difficulty()
except ValueError:
difficulty = int(input("Type a valid number: "))
check_difficulty()
while check_difficulty.tries > 0:
I am new to python so excuse me...
def check_difficulty(difficulty):
if (difficulty == 1):
return 10
elif (difficulty == 2):
return 5
elif (difficulty == 3):
return 3
tries = 0
while tries > 0:
difficulty = int(input("Choose your difficulty: "))
tries = check_difficulty(difficulty)
tries = tries - 1
if you use a while loop and put everything inside in a structured way, a function will not be needed.
You can change this to a class to get your tries:
class MyClass:
def __init__(self):
self.tries = 0
def check_difficulty(self, difficulty):
if (difficulty == 1):
self.tries = 10
elif (difficulty == 2):
self.tries = 5
elif (difficulty == 3):
self.tries = 3
ch = MyClass()
try:
difficulty = int(input("Choose your difficulty: "))
ch.check_difficulty(difficulty)
except ValueError:
difficulty = int(input("Type a valid number: "))
ch.check_difficulty(difficulty)
ch.tries
# 5
If you want the question answered within the construct of your current code simply put your try, except before the function. You can call a function anywhere in the code it doesn't ave to be after the function is created . So something like this:
try:
difficulty = int(input("Choose your difficulty: "))
check_difficulty()
except ValueError:
difficulty = int(input("Type a valid number: "))
check_difficulty()
def check_difficulty():
if (difficulty == 1):
check_difficulty.tries = 10
elif (difficulty == 2):
check_difficulty.tries = 5
elif (difficulty == 3):
check_difficulty.tries = 3
while check_difficulty.tries > 0:
however, I would have to agree with the other answers and just kind of put everything together within the same loop and you won't have to worry about this. I created a guessing game recently that actually had something similar to this. Here is the difficulty portion of that code:
def guessing_game():
again = ''
# Define guesses/lives
while True:
try:
guesses_left = int(input('How many guess would you like(up to 4)?: '))
if 1 > guesses_left or guesses_left > 4:
print('You must choose between 1 and 4 for your guess amount. Try again.')
continue
break
except:
print('You must enter a valid number between 1 and 4. Try again.')
# Define difficulty based on guesses_left
difficulty = ''
if guesses_left == 1:
difficulty = 'Hard Mode'
elif guesses_left == 2:
difficulty = 'Medium Mode'
elif guesses_left == 3:
difficulty = 'Easy Mode'
elif guesses_left == 4:
difficulty = 'Super Easy Mode'
print('You are playing on ' + difficulty + ' with ' + str(guesses_left) + ' guesses.')
#code continues under this line to finish#
I'm trying to finish writing this function that contains five different options and uses a While loop to allow the user to enter in their choice with the entry '5' exiting the loop. Below is the code I have so far, I'm having trouble completing the menu part within the def_main function. I keep getting an error after else:
break
Any input would be appreciated. Thank you for reading.
def main():
menuOption = 0
while 1 == 1:
print("1. Expanded Sum\n2. Reverse Expanded Sum\n3. Reverse Integer\n4. Product Table\n5. Exit\n")
menuOption = int(input("Enter correct menu option: "))
while menuOption<1 or menuOption>5:
print("Incorrect menu option!!")
menuOption = int(input("Enter correct menu option: "))
if menuOption == 5:
return
while 1 == 1:
num = int(input("Enter positive Integer: "))
if num <= 0:
print("You have entered negative integer or zero.")
continue
else:
break
if menuOption == 1:
printSum(num, int(False))
elif menuOption == 2:
printSum(num, int(True))
elif menuOption == 3:
print(str(reverseInt(num)))
elif menuOption == 4:
printProductTable(num)
if __name__ == "__main__": main()
def printSum(n, reverse):
s = sum(range(n+1))
if reverse:
print('+'.join(str(i) for i in range(1, n+1)) + ' = ' + str(s))
else:
print('+'.join(str(i) for i in range(n, 0, -1)) + ' = ' + str(s))
def reverse_int(n):
Reverse = 0
while(n > 0):
Reminder = n %10
Reverse = (Reverse *10) + Reminder
n = n //10
print(Reverse)
def printProductTable(n):
for row in range(1,n+1):
print(*("{:3}".format(row*col) for col in range(1, n+1)))
What is the error you are getting at the break?
It looks like your spacing might be off in the continue, I assume your else goes to the if at the top of the statement, but your continue does not match with it.
Rather than doing while 1==1 you can write while True. And also you have already checked while menuOption<1 or menuOption>5. So if your menuOption is a negative number it already falls into this condition as, say, -2 < 1.
And also seems like your code is not formatted. Means, continue is just above the else. It will generate the error. Re-formate your code. Give proper indentation.
I am doing past coursework for practice, but I'm not sure what to do.
The task: create a game where the user has to guess a random 4 digit number(no repeated digits).
The problem: my code kind of works - like when you input a number with no repeating digits, it's fine, but when you enter, for example, 1223 I get the error:
TypeError: unsupported operand type(s) for divmod(): 'NoneType' and 'Int'
I have looked online and cannot find an answer. Any help would be greatly appreciated.
Thank you
Code below
import random
from collections import Counter
def rng():
num = []
i = 0
while i <=3:
rng = random.randrange(1,9)
if num.count(rng) == 0:
num.append(rng)
i+=1
return num
def menu():
userGuesses = 1
num = rng()#sort out a new num every time
print(num)
x = True
while x == True:
userExit = input("Would you like to exit(yes or no)")
if userExit == "yes":
print("Exiting...")
exit()
elif userExit == "no":
x = False
over = game(num)
while over !=True:
over = game(num)
userGuesses+=1
print("Congratulations you got it right, and it only took you ", userGuesses, " guesses!")
menu()
else:
print("Invalid entry")
def userInput():
userNum = int(input("Please enter a four digit number(no repeated digits)"))
if(userNum > 1000 or userNum < 9999):
print("...")
c = Counter(str(userNum))
if any(value > 1 for value in c.values()):
print ("Your number has repeating digits, please change it.")
else:
x = False
return userNum
else:
print("Invalid entry")
def convertToArray(userNum):
userArray = []
while userNum != 0:
userNum, x = divmod(userNum, 10)
userArray.append(int(x))
userArray.reverse()
print(userArray)
return userArray
def check(userArray, num):
i = 0
bulls = 0
cows = 0
while i<=3:
if num[i] == userArray[i]:
bulls +=1
elif int(userArray[i] in num):
cows +=1
i+=1
print("Bulls:")
print(bulls)
print("Cows:")
print(cows)
if bulls == 4:
return True
else:
return False
def game(num):
userNum = userInput()
userArray = convertToArray(userNum)
if check(userArray, num) == True:
return True
else:
return False
#Main-----------------------------------------------------------------
print("""Hello and welcome to the game \"Cows and Bulls\":
*In this game you enter a 4 digit number
*We compare it to a random number
*If you get the right number in the right 'place' then you get one bull
*If you get the right number in the wrong 'place then you get one cow'
*The game is over when you get 4 bulls, or all the numbers in the right place""")
menu()
Yes - your function doesn't actually return anything because of the print statements, hence an implicit None is returned - but there's another solution you can use.
Take advantage of the fact that userInput will return None if the input isn't valid. Have a condition just before userArray = convertToArray(userNum) to check if userNum is None:
def game(num):
userNum = userInput()
if userNum is None:
# Bad input was given
return False
userArray = convertToArray(userNum)
if check(userArray, num) == True:
return True
else:
return False
def userInput():
userNum = int(input("Please enter a four digit number(no repeated digits)"))
if(userNum > 1000 or userNum < 9999):
print("...")
c = Counter(str(userNum))
if any(value > 1 for value in c.values()):
print ("Your number has repeating digits, please change it.")
else:
x = False
return userNum
else:
print("Invalid entry")
when userNum is repeated, you return nothing. you should return something and pass it to convertToArray