User Input only at the end of while loop - while-loop

I want to make the "continue playing" user input to only appear when all the tries are exhausted in the guessing game.
from random import random, randint
import random
#Guessing Game
attempts = 5
print("===GUESS THE NUMBER===")
print(f"GAME OBJECTIVE: Guess the computer's number in {attempts} tries")
running = True
computerNum = random.randint(1,15)
while running == True:
guess = int(input("Guess the number:\n>"))
print("\n")
if guess > computerNum:
print("Lower...")
attempts -= 1
print(f"[You have {attempts} tries left]")
if guess < computerNum:
print("Higher...")
attempts -= 1
print(f"[You have {attempts} tries left]")
if attempts == 0:
print("GAME OVER!!!")
print(f"The computer's number is {computerNum}")
break
if guess == computerNum:
print("You have guessed the number!!!")
print("YOU WIN!!!")
break
print("\n")
playAgain = input("Do you want to continue playing(Y/N):\n")
if playAgain in ("N","n"):
break
The problem with this code now is just that each time you guess the number, it keeps asking if you want to continue playing.
Also, I want the console to print "Not a number" each time anything apart from a number is input.
if guess != int():
print("Enter a number")
This is my rough idea so far but I keep getting error messages
I am a beginner by the way

You can handle user input that is not a number as shown in https://www.geeksforgeeks.org/python-int-function/.
You should not use break when the user wins or loses.
If you use it, the user is not able to play the game again.
To prevent the program from asking every time whether the user wants to play again, you have to check again for remaining tries if attempts == 0 or guess == computerNum.
from random import random
import random
# Guessing Game
attempts = 5
print("===GUESS THE NUMBER===")
print(f"GAME OBJECTIVE: Guess the computer's number in {attempts} tries")
running = True
computerNum = random.randint(1, 15)
while running == True:
try:
guess = int(input("Guess the number:\n>"))
except ValueError as e:
print("Enter a number")
continue
print("\n")
if guess > computerNum:
print("Lower...")
attempts -= 1
print(f"[You have {attempts} tries left]")
if guess < computerNum:
print("Higher...")
attempts -= 1
print(f"[You have {attempts} tries left]")
if attempts == 0:
print("GAME OVER!!!")
print(f"The computer's number is {computerNum}")
if guess == computerNum:
print("You have guessed the number!!!")
print("YOU WIN!!!")
if attempts == 0 or guess == computerNum:
print("\n")
playAgain = input("Do you want to continue playing(Y/N):\n")
if playAgain in ("N", "n"):
break
else:
computerNum = random.randint(1, 15)
attempts = 5

Like Tacconinja007 said, you could use a try, except statement to make sure the guess is always a number. And if you want to check if the guess is an integer you could do:
if type(guess) == int:
And if you want to make it so the program asks the user if they want to play again once they run out of attempts you could try the following code:
from random import random, randint
import random
# Guessing Game
attempts = 5
print("===GUESS THE NUMBER===")
print(f"GAME OBJECTIVE: Guess the computer's number in {attempts} tries")
running = True
computerNum = random.randint(1, 15)
while running:
try:
guess = int(input("Guess the number:\n>"))
print("\n")
except ValueError:
print("Enter a number")
continue
if guess > computerNum:
print("Lower...")
attempts -= 1
print(f"[You have {attempts} tries left]")
elif guess < computerNum:
print("Higher...")
attempts -= 1
print(f"[You have {attempts} tries left]")
if attempts == 0:
print("GAME OVER!!!")
print(f"The computer's number is {computerNum}")
replay = input("Do you want to play again? (Y/N): ")
if replay in ("N", "n"):
break
else:
attempts = 5
computerNum = random.randint(1, 15)
if guess == computerNum:
print("You have guessed the number!!!")
print("YOU WIN!!!")
break
print("\n")

Related

break parameter not ending loop until second input

def county_quiz():
correct = 0
incorrect = 0
print ("End quiz by pressing 0")
while len(seat)>0:
pick = random.choice(list(seat))
correct_answer=seat.get(pick)
print("What is the County seat of",pick,"?")
answer = input(("Your answer: "))
if answer == "0":
incorrect -=1
break
else:
continue
if answer.lower()==correct_answer.lower():
print("That's correct !")
correct+=1
else:
print("That's incorrect.")
print("The correct answer is",correct_answer)
incorrect+=1
print(f"You answered correctly {correct} times")
print(f"You had {incorrect} incorrect answers")
return (correct, incorrect)
This function has a while loop that should be broken after the user inputs "0", but the loop isn't broken until the second time the user inputs "0". I'm not sure why, and don't know how to resolve this.

Psychopy not getting all the answers

I'm using psychopy to build a cognitive task.
I have 5 circles on the screen and the participant needs to pressed on the good circle.
My code :
if mouse.isPressedIn(cercle_1):
continueRoutine = False
# save data if you like:
thisExp.addData('correct', 1)
thisExp.addData('RT', t)
elif mouse.isPressedIn(cercle_2):
# save data if you like:
thisExp.addData('correct', 0)
thisExp.addData('RT', t)
continueRoutine = True
elif mouse.isPressedIn(cercle_3):
# save data if you like:
thisExp.addData('correct', 0)
thisExp.addData('RT', t)
continueRoutine = True
elif mouse.isPressedIn(cercle_4):
# save data if you like:
thisExp.addData('correct', 0)
thisExp.addData('RT', t)
continueRoutine = True
elif mouse.isPressedIn(cercle_5):
# save data if you like:
thisExp.addData('correct', 0)
thisExp.addData('RT', t)
continueRoutine = True
The problem is that my datafile only contains the response time (RT) and the info of the circle_1. I would have no idea if the participant tried other circle before pressing on circle_1.
Question : How can I have in my csv file infos about all the times a participant pressed the mouse bouton.Maybe before pressing cercle_1, he pressed the cercle_3. Right now, I only have how long it took to get the correct answer.
It sounds like you want to record a sequence of events in the trial. This can be hard to find an appropriate data structure for, but in your case, I can think of two solutions.
Record the number of wrong responses
Have a column (e.g. n_wrong) and count the number of non-circle_1 responses. In Begin routine add
n_wrong = 0
Then in each frame add:
if mouse.isPressedIn(cercle_1):
thisExp.addData('correct', 1)
thisExp.addData('RT', t)
continueRoutine = False
elif mouse.isPressedIn(cercle_2) or mouse.isPressedIn(cercle_3) or mouse.isPressedIn(cercle_4) or mouse.isPressedIn(cercle_5):
thisExp.addData('correct', 0)
thisExp.addData('RT', t)
n_wrong += 1 # One more error recorded!
# Now wait until the mouse release to prevent recording 60 wrong clicks per second!
while any(mouse.getPressed()):
pass
Then under end routine add:
thisExp.addData('n_wrong', n_wrong)
Record which circles were pressed
The other is to have a column for each circle and shift those from "unpressed" to "pressed" when they are clicked. Then the column cercle1 would correspond to what you currently call the correct column. So under begin routine:
# Mark all non-target cirlces as unpressed
thisExp.addData('cercle1', 0)
thisExp.addData('cercle2', 0)
thisExp.addData('cercle3', 0)
thisExp.addData('cercle4', 0)
thisExp.addData('cercle5', 0)
Then under each frame I would do this:
if mouse.isPressedIn(cercle_1):
thisExp.addData('cercle1', 1)
continueRoutine = False
if mouse.isPressedIn(cercle_2):
thisExp.addData('cercle2', 1)
if mouse.isPressedIn(cercle_3):
thisExp.addData('cercle3', 1)
if mouse.isPressedIn(cercle_4):
thisExp.addData('cercle4', 1)
if mouse.isPressedIn(cercle_5):
thisExp.addData('cercle5', 1)
The latter approach could be extended with reaction times by adding columns called cercle1_rt etc. but then you'd also need to do the while any(mouse.getPressed()): pass trick to record the onset and not just the release.

variable from text box won't assign

I am creating some code for a school project, and for a module I use later on, I need to know what the intensity to end on(end_intensity) is. When the code is run, the end_intensity still comes out as unassigned, this means that the
if client_intensity == "High":
line is never being run.Can someone please explain why it won't assign .
correct = False
end_intensity = "Unassigned"
while correct != True:
id_search = input("please enter the Client ID of the client you wish to record results for:")
# open file, with will automatically close it for you
with open("text_documents/clientIntensity.txt") as f:
user_found = False
# loop over every line
for line in f:
client,intensity = line.split(",")
if id_search == client:
correct = True
user_found = True
intensity = str (intensity)
client_intensity = intensity
#assigns which one is the end intensity
if intensity == 'High':
end_intensity = 'Moderate'
elif intensity == 'Moderate':
end_intensity = 'High'
if user_found == False:
print("I'm sorry no results we're found for that ID, please try again\n")
print(end_intensity)
The text document is in this format:
NeQua,High
ImKol,Moderate
YoTri,Moderate
(I apologize for the numbers for the text document formatting,stack overflow would only let me show it like that)
Any help would be appreciated,Thanks
Ieuan

Python twisted, reactor.callLater() not defering

The following code snippet is from a python poker server. The program works except when trying to delay the start of a tourney when a reactor.callLater is used.
The variable "wait" gets its integer from an xml file which has a setting of "60". However the delay is never implemented and the tourney always starts immediately. I am not very familiar with python or twisted just trying to hack this into working for me. One thing however from my perspective is it seems that it shouldn't work given that I can't see how or where the variable "old_state" gets its value in order for the code to properly determine the states of the server. But perhaps I am mistaken.
I hope that someone familiar with python and twisted can see what the problem might be and be willing to enlighten me on this issue.
elif old_state == TOURNAMENT_STATE_REGISTERING and new_state == TOURNAMENT_STATE_RUNNING:
self.databaseEvent(event = PacketPokerMonitorEvent.TOURNEY_START, param1 = tourney.serial)
reactor.callLater(0.01, self.tourneyBroadcastStart, tourney.serial)
# Only obey extra_wait_tourney_start if we had been registering and are now running,
# since we only want this behavior before the first deal.
wait = int(self.delays.get('extra_wait_tourney_start', 0))
if wait > 0:
reactor.callLater(wait, self.tourneyDeal, tourney)
else:
self.tourneyDeal(tourney)
For reference I have placed the larger portion of the code that is relative to the problem.
def spawnTourneyInCore(self, tourney_map, tourney_serial, schedule_serial, currency_serial, prize_currency):
tourney_map['start_time'] = int(tourney_map['start_time'])
if tourney_map['sit_n_go'] == 'y':
tourney_map['register_time'] = int(seconds()) - 1
else:
tourney_map['register_time'] = int(tourney_map.get('register_time', 0))
tourney = PokerTournament(dirs = self.dirs, **tourney_map)
tourney.serial = tourney_serial
tourney.verbose = self.verbose
tourney.schedule_serial = schedule_serial
tourney.currency_serial = currency_serial
tourney.prize_currency = prize_currency
tourney.bailor_serial = tourney_map['bailor_serial']
tourney.player_timeout = int(tourney_map['player_timeout'])
tourney.via_satellite = int(tourney_map['via_satellite'])
tourney.satellite_of = int(tourney_map['satellite_of'])
tourney.satellite_of, reason = self.tourneySatelliteLookup(tourney)
tourney.satellite_player_count = int(tourney_map['satellite_player_count'])
tourney.satellite_registrations = []
tourney.callback_new_state = self.tourneyNewState
tourney.callback_create_game = self.tourneyCreateTable
tourney.callback_game_filled = self.tourneyGameFilled
tourney.callback_destroy_game = self.tourneyDestroyGame
tourney.callback_move_player = self.tourneyMovePlayer
tourney.callback_remove_player = self.tourneyRemovePlayer
tourney.callback_cancel = self.tourneyCancel
if not self.schedule2tourneys.has_key(schedule_serial):
self.schedule2tourneys[schedule_serial] = []
self.schedule2tourneys[schedule_serial].append(tourney)
self.tourneys[tourney.serial] = tourney
return tourney
def deleteTourney(self, tourney):
if self.verbose > 2:
self.message("deleteTourney: %d" % tourney.serial)
self.schedule2tourneys[tourney.schedule_serial].remove(tourney)
if len(self.schedule2tourneys[tourney.schedule_serial]) <= 0:
del self.schedule2tourneys[tourney.schedule_serial]
del self.tourneys[tourney.serial]
def tourneyResumeAndDeal(self, tourney):
self.tourneyBreakResume(tourney)
self.tourneyDeal(tourney)
def tourneyNewState(self, tourney, old_state, new_state):
cursor = self.db.cursor()
updates = [ "state = '" + new_state + "'" ]
if old_state != TOURNAMENT_STATE_BREAK and new_state == TOURNAMENT_STATE_RUNNING:
updates.append("start_time = %d" % tourney.start_time)
sql = "update tourneys set " + ", ".join(updates) + " where serial = " + str(tourney.serial)
if self.verbose > 2:
self.message("tourneyNewState: " + sql)
cursor.execute(sql)
if cursor.rowcount != 1:
self.error("modified %d rows (expected 1): %s " % ( cursor.rowcount, sql ))
cursor.close()
if new_state == TOURNAMENT_STATE_BREAK:
# When we are entering BREAK state for the first time, which
# should only occur here in the state change operation, we
# send the PacketPokerTableTourneyBreakBegin. Note that this
# code is here and not in tourneyBreakCheck() because that
# function is called over and over again, until the break
# finishes. Note that tourneyBreakCheck() also sends a
# PacketPokerGameMessage() with the time remaining, too.
secsLeft = tourney.remainingBreakSeconds()
if secsLeft == None:
# eek, should I really be digging down into tourney's
# member variables in this next assignment?
secsLeft = tourney.breaks_duration
resumeTime = seconds() + secsLeft
for gameId in map(lambda game: game.id, tourney.games):
table = self.getTable(gameId)
table.broadcast(PacketPokerTableTourneyBreakBegin(game_id = gameId, resume_time = resumeTime))
self.tourneyBreakCheck(tourney)
elif old_state == TOURNAMENT_STATE_BREAK and new_state == TOURNAMENT_STATE_RUNNING:
wait = int(self.delays.get('extra_wait_tourney_break', 0))
if wait > 0:
reactor.callLater(wait, self.tourneyResumeAndDeal, tourney)
else:
self.tourneyResumeAndDeal(tourney)
elif old_state == TOURNAMENT_STATE_REGISTERING and new_state == TOURNAMENT_STATE_RUNNING:
self.databaseEvent(event = PacketPokerMonitorEvent.TOURNEY_START, param1 = tourney.serial)
reactor.callLater(0.01, self.tourneyBroadcastStart, tourney.serial)
# Only obey extra_wait_tourney_start if we had been registering and are now running,
# since we only want this behavior before the first deal.
wait = int(self.delays.get('extra_wait_tourney_start', 0))
if wait > 0:
reactor.callLater(wait, self.tourneyDeal, tourney)
else:
self.tourneyDeal(tourney)
elif new_state == TOURNAMENT_STATE_RUNNING:
self.tourneyDeal(tourney)
elif new_state == TOURNAMENT_STATE_BREAK_WAIT:
self.tourneyBreakWait(tourney)
I have discovered that this code has several imported files that were in another directory that I did not examine. I also made a false assumption of the purpose of this code block. I expected the function to be arbitrary and delay each tourney by n seconds but in practice it implements the delay only when a player forgets about the game and does not show up for it. These facts were made clear once I examined the proper files. Lesson learned. Look at all the imports!

Learning Python 3.3 - TypeError: 'int' object is not callable

I was trying to solve Challenge 2 at the end of the classes chapter (Chapter 8) in "Python Programming for the Absolute Beginner" which is stated as:
Write a program that simulates a television by creating it as an object. The user should be able to enter a channel number and raise or lower the volume. Make sure that the channel number and the volume level stay within valid ranges.
I keep getting: TypeError: 'int' object is not callable, which at this stage just isn't very helpful.
I'm a beginner but I've seen something really similar working (see at the bottom right below my code) and nearly went as far as nearly copying that code. Could somebody maybe explain what's wrong with this and how I can get it to work?
Here's the complete error:
Traceback (most recent call last):
File "Untitled 3.py", line 59, in <module>
main()
File "Untitled 3.py", line 50, in main
tv.channel(newchannel = int(input("What channel would you like to set the TV to?")))
TypeError: 'int' object is not callable
My code is below,
Thanks
class Television(object):
"""a TV"""
def __init__(self, channel = 0, volume = 0):
self.channel = channel
self.volume = volume
def channel(self, newchannel = 0):
if newchannel <= 0 or newchannel >9:
print("No negative numbers or numbers higher than 9. Start again from the menu")
else:
self.channel = newchannel
print("You set the TV on channel", self.channel)
def volume(self, newvolume = 0):
if newvolume <= 0 or newvolume >9:
print("No negative numbers or numbers higher than 9. Start again from the menu")
else:
self.volume = newvolume
print("You set the TV on volume", self.volume)
def watch(self):
print("You are watching channel", self.channel, "at volume", self.volume)
def main():
tv = Television()
choice = None
while choice != "0":
print \
("""
TV
0 - Quit
1 - Watch the TV
2 - Change channel
3 - Set the volume
""")
choice = input("Choice: ")
print()
# exit
if choice == "0":
print("Good-bye.")
elif choice == "1":
tv.watching()
elif choice == "2":
tv.channel(newchannel = int(input("What channel would you like to set the TV to?")))
elif choice == "3":
tv.volume(newvolume = int(input("What channel would you like to set the TV to?")))
# some unknown choice
else:
print("\nSorry, but", choice, "isn't a valid choice.")
main()
("\n\nPress the enter key to exit.")
Why does the following work instead? To me, it looks pretty similar to what I've done.
class Critter(object):
"""A virtual pet"""
def __init__(self, hunger = 0, boredom = 0):
self.hunger = hunger
self.boredom = boredom
def eat(self, food = 4):
print("Brruppp. Thank you.")
self.hunger += food
if self.hunger < 0:
self.hunger = 0
crit = Critter()
print(crit.hunger)
crit.eat(food = int(input("how much do you want to feed him?")))
print(crit.hunger)
The problem is you are defining a method with the same name as a property. That is, you're saying Television.channel is an int, but later you are binding a method to that name.