How do you minus one from an INT in a function?
This is what I'm trying:
try:
lives
except NameError:
lives = 6
else:
lives = lives-1
print("\nWrong!\nYou have " +str(lives)+ " lives remaining\n")
But it doesn't work.
The lives are always at 6 :(
Any ideas?
UPDATE:
def main():
used = []
print(blanks)
choice = input("\nEnter a letter:")
lives -= 1
print("\nWrong!\nYou have " +str(lives)+ " lives remaining\n")
used.append(choice)
main()
The real reason you are seeing 6 is because the NameError is thrown, and therefore your else clause is never actually executed
NameError: name 'lives' is not defined
If lives wasn't defined before, than try: lives will always get you to the except section.
if you define lives before this code (by assigning it something) or inside the try section, you'll get to see the -1 in action.
try:
lives = 1
except NameError:
lives = 6
else:
lives = lives-1
print lives
will output 0
as well as:
lives = 1
try:
lives
except NameError:
lives = 6
else:
lives = lives-1
print lives
EDIT:
For your comment, here is some sample code that does something like what you are probably trying to achieve, that is a game of guess the letter. Hopefully this will help you.
def main():
# The setup
right_answer = "a"
lives = 6
# The game
while lives > 0:
choice = raw_input("Enter a letter:")
if choice == right_answer:
print "yay, you win!"
break
else:
lives -= 1
print "nay, try again, you have", lives, "lives left"
else:
print "you lose"
# This will call our function and run the game
if __name__ == "__main__":
main()
** written fro python 2.7, for python 3 the prints will need parentheses.
All I needed to go was define the variable outside the function and then put:
global lives in the function.
Job done.
Related
I'm making a dart score keeper but it just keeps going round and round. I just need some help as to why this is.
The code:
import time
import sys
from sys import argv
script, name1, name2 = argv
def dartscore():
print "Play from 501 or 301?"
threeorfive = int(raw_input())
if (threeorfive == 501):
def playerone():
startnum1 = threeorfive
while (startnum1 > 0):
print "Ready ", name1,"?"
print "Please enter your score."
minusnum1 = int(raw_input())
startnum1 = startnum1 - minusnum1
playertwo()
if (startnum1 == 0):
print "Well done! You win!"
elif (startnum1 < 0):
print "Sorry but you have entered a wrong score"
playertwo()
def playertwo():
startnum2 = threeorfive
print "Ready ", name2,"?"
print "Please enter your score."
minusnum2 = int(raw_input())
startnum2 = startnum2 - minusnum2
if (startnum2 == 0):
print "Well done! You win!"
print "Unlucky ", name1,". Well played though."
sys.exit()
if (startnum2 < 0):
print "Sorry but you have entered an incorrect score. Please try again"
startnum2 += minusnum2
playerone()
playerone()
dartscore()
Now the two functions playerone() and playertwo() are different because I was trying something with the playerone() function to see if that solved my problem.
Well you have a while(startnum1 > 0):. It seems like startnum1is always bigger then 0. The only way to exit your loop is player 2 has a startnum2 on 0.
Your problem is:
threeorfive = 501
Throughout the entire game, and you begin each of your functions with
startnum = threeorfive
Which means the game 'resets' after both player takes a turn.
A possible fix would be to add global variables:
cumulative1 = 0
cumulative2 = 0
then update cumulative in each iteration:
cumulative1 += minusnum1
cumulative2 += minusnum2
and change your while loop to:
while(threeorfive - cumulative1 > 0)
while(threeorfive - cumulative2 > 0)
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Im new(-ish) to python and I made a game today which after I finished I realised I'd made a big mistake :
inside the functions I had to access and edit variables which where also accessed and changed in other functions and maybe in the future outside the functions. And I don't know how to do that.
I've researched for a long time and found very few things that might solve the problem, I've tried a few, but they haven't worked and I don't understand how to use others.
Could you please try to help me with the problem and if you spot others please tell me, as Im not too good at debugging :(
Here is the code below, its quite big (I've put the variables I need to access and change in bold):
from random import randint
print ("Ghost Game v2.0")
print ("select difficulty")
score = 0
alive = True
difficulty = 0
doors = 0
ghost_door = 0
action = 0
ghost_power = 0
#define the function 'ask_difficulty'
def ask_difficulty() :
difficulty = input ("Hard, Normal, Easy")
set_difficulty()
# define the function 'set_difficulty' which sets the difficulty.
def set_difficulty() :
if difficulty == 'Hard' or 'Normal' or 'Easy' :
if difficulty == 'Hard' :
doors = 2
elif difficulty == 'Normal' :
doors = 3
elif difficulty == 'Easy' :
doors = 5
else:
print ("Invalid input, please type Hard, Normal, or Easy")
ask_difficulty()
# define the function 'ghost_door_choose' which sets the ghost door and the chosen door
def ghost_door_choose(x):
ghost_door = randint (1, x)
print (doors + " doors ahead...")
print ("A ghost behind one.")
print ("Which do you open?")
if doors == 2 :
door = int("Door number 1, or door number 2...")
if 1 or 2 in door :
ghost_or_no()
else :
print ("Invalid input")
ghost_door_choose(difficulty)
elif doors == 3 :
door = int("Door number 1, door number 2, or door number 3")
if 1 or 2 or 3 in door :
ghost_or_no()
else:
print ("Invalid input")
ghost_door_choose(difficulty)
elif doors == 5 :
print("Door number 1, door number 2, door number 3, door number 4, or door number 5.")
if 1 or 2 or 3 or 4 or 5 in door :
ghost_or_no()
else:
print ("Invalid input")
ghost_door_choose(difficulty)
# define the function 'ghost_or_no'
def ghost_or_no() :
if door == ghost_door:
print ("GHOST!!")
print ("Initiating battle...")
battle()
else:
print ("No ghost, you\'ve been lucky, but will luck remain with you...")
score = score + 1
ghost_door_choose(difficulty)
# define the function 'battle' which is the battle program
def battle() :
ghost_power = randint (1, 4) # 1 = Speed, 2 = Strength, 3 = The ghost is not friendly, 4 = The ghost is friendly
print ("You have 3 options")
print ("You can flee, but beware, the ghost may be fast (flee),")
print ("You can battle it, but beware, the ghost might be strong (fight),")
print ("Or you can aproach the ghost and be friendly, but beware, the ghost may not be friendly (aproach)...")
action = input ("What do you choose?")
if flee in action :
action = 1
elif fight in action :
action = 2
elif aproach in action :
action = 3
else :
print ("Invalid input")
battle()
if ghost_power == action :
if action == 1:
print ("Oh no, the ghost\'s power was speed!")
print ("DEFEAT")
print ("You\'r score is " + score)
alive = False
elif action == 2:
print ("Oh no, the ghost\'s power was strength!")
print ("DEFEAT")
print ("You\'r score is " + score)
alive = False
elif action == 3:
print ("Oh no, the ghost wasn\'t friendly ")
alive = False
elif ghost_power == 4 and action == 3 :
print ("Congratulations, The ghost was friendly!")
score = score + 1
ghost_door_choose(difficulty)
elif ghost_power != action and ghost_power != 4 :
if action == 1:
print ("Congratulations, the ghost wasn\'t fast!")
score = score + 1
ghost_door_choose(difficulty)
elif action == 2:
print ("Congratulations, you defeated the ghost!")
score = score +1
ghost_door_choose(difficulty)
elif ghost_power != action and ghost_power == 4 :
if action == 1:
print ("You ran away from a friendly ghost!")
print ("Because you ran away for no reason, your score is now 0")
score = 0
ghost_door_choose(difficulty)
elif action == 1:
print ("You killed a friendly ghost!")
print ("Your score is now 0 because you killed the friendly ghost")
score = 0
ghost_door_choose(difficulty)
#actual game loop
ask_difficulty()
while alive :
ghost_door_choose(doors)
Consider:
x=0
z=22
def func(x,y):
y=22
z+=1
print x,y,z
func('x','y')
When you call func you will get UnboundLocalError: local variable 'z' referenced before assignment
To fix the error in our function, do:
x=0
z=22
def func(x,y):
global z
y=22
z+=1
print x,y,z
The global keyword allows a local reference to a global defined variable to be changed.
Notice too that the local version of x is printed, not the global version. This is what you would expect. The ambiguity is if there is no local version of a value. Python treats globally defined values as read only unless you use the global keyword.
As stated in comments, a class to hold these variables would be better.
Those variables at the top of your script are global and to set them in functions, you have to declare them global in the function. As a smaller example,
score = 0
alive = True
def add_score(value):
"""Add value to score"""
global score
score += value
def kill_kill_kill():
global alive
alive = False
The next step is to create classes, which can get complicated. For instance, if you want to track score by user but a user can have multiple characters which each have their own aliveness, you would start to build classes to represent those things.
The global keyword may be what you are looking for.
For example in the following code.
some_variable = 10
def some_function():
global some_variable
some_variable = 20
This would result in some_variable (in the global scope) referring to the value of 20. Where as it would remain at 10 (in the global scope) without the use of the global keyword.
More on global and local variables here.
A function has its own variable scope - this is true for many languages. This means that once the function finishes executing, the variables cease to exist (and Python's garbage collection will clean them up).
The old-school (and generally frowned upon, not necessarily fairly) way of doing this is to use Global Variables. These are variables you declared outside the scope of the function, usually at the beginning of your source, and can be used throughout your program's various functions and classes.
There are good reasons people don't use global variables much, from performance issues through to getting them confused with locally scoped variables, but they are a quick and easy way to keep information and access it throughout your program.
To use a global, you need to declare within the function that you are using that variable, like this:
MyGlobal="This is a global variable"
def MyFunction():
global MyGlobal
MyGlobal += " and my function has changed it"
if __name__=="__main__":
print MyGlobal
MyFunction()
print MyGlobal
Having said this, the usual way to pass information to and from functions is to use arguments and return values - this is a better design methodology, and the one usually taught. This is more a design method than a change to your code; you write your program with keeping global variables down to an absolute minimum.
To take the above example, this would change our code to the following:
def MyFunction(MyArg):
MyArg+=" and my function has given me a new version of it"
return MyArg
if __name__=="__main__":
MyVariable="This is a variable"
print MyVariable
MyVariable = MyFunction(MyVariable)
print MyVariable
Note that this is much more flexible - I can use it as I have above, to change the value of MyVariable, but I could also use the same function to return the new value to a different variable, keeping the original intact.
I hope this helps, sorry if I was a tad verbose.
I am trying to limit the amount of tries a person has when attempting to guess the random number. I get this error code when I run the program and can't figure out what to do next.
Traceback (most recent call last):
File "C:/Python27/coding/Guess.py", line 34, in <module>
main()
File "C:/Python27/coding/Guess.py", line 24, in main
trys(userGuess)
File "C:/Python27/coding/Guess.py", line 29, in trys
trysLeft -= 1
UnboundLocalError: local variable 'trysLeft' referenced before assignment
The code:
import random
def main():
print "Guess a number between 1 and 100."
randomNumber = random.randint(1,100)
found = False
trysLeft = 5
while not found:
userGuess = input("Your guess: ")
if userGuess == randomNumber:
print "You got it!"
found = True
elif userGuess > randomNumber:
trys()
print "Guess lower!"
else:
trys()
print "Guess higher!"
def trys():
trysLeft -= 1
print "You have %d trys left." %trysLeft
if __name__ == "__main__":
main()
You have 3 options to fix this:
Put trysLeft in a global (not a good idea)
Add function trys() to your class and reference it as self.trysLeft
Pass the variable into the trys() function.
You need to pass trysLeft to the function for it to see it ...
def trys(trysLeft):
trysLeft -= 1
print "You have %d trys left." %trysLeft
return trysLeft
and then when you call trys ...
trysLeft = trys(trysLeft)
The problem is that you're assigning trysLeft in the function, so it assumes it has local (rather than global) scope. But you actually want to assign the global variable, so you need to declare that trysLeft has global scope. Change your trys() function to the following:
def trys():
global trysLeft
trysLeft -= 1
print "You have %d trys left." %trysLeft
For more information, see the FAQ
FWIW, the correct way to solve this would be to pass a variable to your function rather than use globals, but that's outside the scope of your question.
def trys(self):
self.trysLeft-=1
Should do it!
Self is referring to the instance of the class that you are currently in.
Similar to this in java and Me in vba.
I'm having some issues with this code. There is a lot of other code to go with it but none that will interfere or have any affect on the issue I'm having. So basically, when I run the code and we get to the for loop at the bottom, it prints nothing because apparently the variable 'walls' = 0, even though I've already given it a valid input. If anyone could help it would be much appreciated.
global walls
global wallLengths
walls = 0
wall = 0
wallLengths = 0
def clientDetails():
#global walls
print("Welcome to the InHouse Solutions Room Painting Price Calculator")
print("STEP 1 - CLIENT DETAILS")
print("Please enter your full name")
userName = input(">>>")
print("Please enter your post code")
postCode = input(">>>")
print("Please enter you first address line here:")
addressLineOne = input(">>>")
print("Please enter your second address line here (OPTIONAL)")
addressLineTwo = input(">>>")
print("Thank you for your information")
print (userName)
print (addressLineOne + ", " + addressLineTwo + ", " + postCode)
print (" ")
def ValidationOne():
print ("Is this information correct? Pleast enter Yes or No")
clientDetailsCorrect = input(">>>")
if clientDetailsCorrect == "no" or clientDetailsCorrect == "No":
clientDetails()
elif clientDetailsCorrect == "Yes" or clientDetailsCorrect == "yes":
roomDimensions()
else:
("Invalid response, please try again")
ValidationOne()
ValidationOne()
def roomDimensions():
global walls
print ("STEP 2 - ROOM DIMENSIONS")
def ValidationTwo():
global walls
print ("How many walls does your room have?")
walls = int(input(">>>"))
if walls > 10 or walls < 3:
print("Invalid, please enter a number between 3 and 10")
ValidationTwo()
elif walls == " " or walls == "":
print("Invalid")
ValidationTwo()
def ValidationThree():
global walls
print ("How tall is the room in meters?")
roomHeight = float(input(">>>"))
if roomHeight < 2.4 or roomHeight > 6:
print ("Invalid, please enter a value between 2.4 and 6")
ValidationThree()
def IndividualWalls():
global wallLengths
global walls
for i in range(1,walls):
print("Please enter the width of wall" , i)
wallLengths[i] = float(input(">>>"))
ValidationTwo()
ValidationThree()
IndividualWalls()
clientDetails()
there is no need to use 'global' keyword when declaring a global at the top of the script:
>>> walls = 0
>>> def increase_walls():
... global walls
... walls += 1
... print walls
...
>>> increase_walls()
1
I can't comment to your question because I don't have over 50 reputation so I will ask here
Can you tell me what the function roomDimensions does?
I tried to run it and you have some deep recursion problem (you can't call recursion function without any if - it will run forever) BUT the first thing that I notice is that you don’t initialize the walls variable so it will not be global variable it will be non-local variable. and you don't call any inner function ( ValidationTwo, ValidationThree,IndividualWalls)
so you main problems are: (handle them in this order)
walls initialize
you didn't call any inner function
deep recursion
here is my example for the use of the three of above:
global_var = 12
def outer():
global global_var
print("*"*10)
print('hello im outer function')
print("*"*10)
def inner1():
global global_var
print('hello im inner1 function')
if global_var < 10:
return 'end for inner1'
print ('global_var is: ' + str(global_var))
global_var -= 1
return inner1()
def inner2():
global global_var
print('hello im inner2 function')
if global_var >= 10:
return 'end for inner1'
print ('global_var is: ' + str(global_var))
global_var += 1
return inner2()
if global_var >= 10:
return inner1()
else:
return inner2()
if __name__ == '__main__':
print outer()
Ok so im working on a basic dice game, But when it gets to the while loop it doesnt print the message inside, The message is just a placeholder.
dicenumber = None
numberchoice = None
ready = None
test = "Lol"
class playerClass():
points = 0
class enemyClass():
point = 0
def rolldice():
dicenumber = dicenumber.randint(1,9)
def start():
print("Hello welcome to the dice game.")
print("The goal of the game is to guess what number the dice will land on.")
print("The option are 1 to 6 and the game is won by getting 3 points.")
print()
print("Are you ready to play?")
print("1 - Yes")
print("2 - No")
ready = int(input())
start()
while ready == 1:
print("hello")
Use global inside your start function. Also, as you were trying to put while ready==1, it will be in infinite loop!
dicenumber = None
numberchoice = None
ready = None
test = "Lol"
class playerClass():
points = 0
class enemyClass():
point = 0
def rolldice():
dicenumber = dicenumber.randint(1,9)
def start():
global ready
print("Hello welcome to the dice game.")
print("The goal of the game is to guess what number the dice will land on.")
print("The option are 1 to 6 and the game is won by getting 3 points.")
print()
print("Are you ready to play?")
print("1 - Yes")
print("2 - No")
ready = int(input())
start()
while ready == 1:
print("hello")
When you access ready inside the start() method, you are accessing it as a local variable. Python assumes that all variables you use are local, not global. Put global ready in the start() method before you set the ready variable. This will tell python to access ready as a global variable.
There is a scoping issue. ready variable defined in a global scope is not updated inside the start() function.
Simple demo of what is happening:
>>> ready = None
>>> def start():
... ready = 1
...
>>> start()
>>> print ready
None
Better return ready variable from the start():
def start():
print("Hello welcome to the dice game.")
print("The goal of the game is to guess what number the dice will land on.")
print("The option are 1 to 6 and the game is won by getting 3 points.")
print()
print("Are you ready to play?")
print("1 - Yes")
print("2 - No")
return int(input())
ready = start()
You can also make it global as #S.M. Al Mamun suggested, but i would not recommend it. Global variables are needed for sharing data, state between functions. In this case there is no need for it - your start() function defines a value for the ready variable. It is a single one place where ready is defined - no need to make it global. start() is an entry point and it would be a good idea to return a "state" (ready variable) from it.
See also:
Short Description of the Scoping Rules?
ready is defined in the global scope, but you are setting it in the local scope of the start function. Also, your rolldice function returns a number from 1 to 9 instead of 1 to 6.
from random import randint
class Player:
def __init__(self, name):
self.name = name
self.points = 0
self.won = False
def add_point(self):
self.points += 1
self.won = True
print('''
Hello welcome to the dice game.
The goal of the game is to guess what number the dice will land on.
The options are 1 to 6 and the game is won by getting 3 points.
Are you ready to play?
0 - No
1 - Yes'''
ready = int(input())
if ready:
players = []
number_of_players = int(input('How many players? '))
for i in range(number_of_players):
name = input('What is the name of player {}?'.format(i+1))
players.append(Player(name))
winners = []
while ready:
random_number = randint(1, 6)
for player in players:
guess = int(input('What is your guess, {}?'.format(player.name)))
if guess == random_number:
player.add_point()
if player.won:
winners.append(player.name)
if winners:
print('Winners: {}'.format(', '.join(winners)))
break
You are accessing a variable(ready) which was defined originally as a global variable, then you are accessing it in your start function without mentioning in your code('start' function) that is a global variable and finally in your while loop you are again trying to access a variable which you assume it has a value assigned to it.
The other thing is you while loop. when you set ready==1, you need to some where break from your loop if you don't want it to be infinite loop.