Global variable referenced before assignment? - python

I'm brand new to Python and I'm trying to create a very simple code where every time the user presses enter, they earn five points, followed by the line printing how many points they currently have. The code looks like this:
pointsEarned = 0
alien_0 = {"points":5}
new_points = alien_0["points"]
def kill():
input("Press enter to kill an alien!")
pointsEarned = pointsEarned + 5
killed()
def killed():
print("You just earned " + str(new_points) + " points!")
print("Current points: " + str(pointsEarned))
kill()
kill()
However, when I run this code, it gives me this error:
UnboundLocalError: local variable 'pointsEarned' referenced before assignment
I don't understand this, as I defined pointsEarned outside of either function beforehand. How do I fix this?

pointsEarned = 0
alien_0 = {"points":5}
new_points = alien_0["points"]
def kill():
global pointsEarned
input("Press enter to kill an alien!")
pointsEarned += 5
killed()
def killed():
print("You just earned " + str(new_points) + " points!")
print("Current points: " + str(pointsEarned))
kill()
kill()

Related

How can I take another variable from a def function and add it to another def function to get a new sum?

def room1(phone_charge):
phone_charge = 5
import random
randNum = random.randint(1,5)
print("An outlet! You quickly plug in your phone, but the wiring in the house is faulty and soon shorts out.\n")
positve = str(phone_charge + randNum)
print("Your phone is now " + positve + " % charged\n")
return(positve)
I need to add positive to another function
def room5(phone_charge):
import random
randomNUM = random.randint(1,30)
positve2= str(phone_charge + randomNUM)
print("Your phone is now " + positve2 + " % charged\n")
return(positve2)
I need to add postive to the room5 variable postive2
I tried returning variables and putting them in the next function but then my code that was written behind where I entered the returning variable it was no longer highlighted
Since the two functions return their values, you can add them together after calling.
p1 = room1(phone_charge)
p5 = room5(phone_charge)
print(f"Total is {p1 + p5}")
Since the two functions have the same functionality use one function with an extra parameter.
import random
def room(phone_charge, rand_range):
randNum = random.randint(1,rand_range)
print("An outlet! You quickly plug in your phone, but the wiring in the house is faulty and soon shorts out.\n")
positve = str(phone_charge + randNum)
print("Your phone is now " + positve + " % charged\n")
return positve
room1 = room(5, 5)
room5 = room(10, 30)
total = room1 + room5

Python Loop Unable to interrupt

I'm making a curency converter, time converter and weather app for an year 12 computer sciences project. Im unable to interrupt the loop that is being used for the main menu/location selector.
Can anyone help?
The code is below.
##This program is intended to help travellers with date and currency conversions ##
##Changelog----->##
##V1 - Include code for Forex Converter, code modified from - https://www.w3schools.in/python/examples/real-time-currency-converter##
##V2 - Implement GUI##
##V2.1 - Implement Multiple Screens GUI##
##V3 - Remove all GUI aspects##
##V3.1 - Create initial loop##
##Import Modules##
from forex_python.converter import CurrencyRates
import time
import datetime
import python_weather
import asyncio
##Opening info##
##V3.1##
global enter
enter = 'GO'
while enter == 'GO':
print("========================================================================================================================================================================================")
print("")
print("Welcome to the Traveller Assisstant. This program is able to help you with currency conversions, date and time conversions and viewing weather details of your destination.")
print("")
print("========================================================================================================================================================================================")
time.sleep(2.5)
ori = str(input("Please enter your current country: "))
dest = str(input("Please enter your destination country: "))
time.sleep(5)
check = str(input("Are you sure you are in " + ori + ", and would like to go to " + dest + "? ")).upper
if check == 'YES':
enter = 'STOP'
elif check == 'NO':
print("Returning to Location Selector")
enter = 'GO'
##V1##
##Change Currency##
#cr = CurrencyRates()
#output = cr.convert(entry1, entry2, entry3)
#final = round(output, 2)
#print("THE FINAL AMOUNT IS:", final, c2)
A simple typo, that's all that was wrong.
In this line of code:
check = str(input("Are you sure you are in " + ori + ", and would like to go to " + dest + "? ")).upper
You are attempting to use the method
.upper()
But your fatal flaw is that you forgot the parentheses.
I changed this:
check = str(input("Are you sure you are in " + ori + ", and would like to go to " + dest + "? ")).upper
To this:
check = str(input("Are you sure you are in " + ori + ", and would like to go to " + dest + "? ")).upper()
And the code worked perfectly for me
EXPLANATION
In the original code, check could never be equal to 'YES' or 'NO', because of the typo;
.upper was never recognized as a strings' function and returned with this value:
<built-in method upper of str object at 0x105fec130>
.upper() on the other IS in fact a valid function for a string and returned with this value when it was supplied with the input of 'yes':
YES
If you need to exit from the loop when a condition is met you can achieve that easily by using break. So when your condition is met:
either add bellow enter = "STOP" the statement break or just replace enter = "STOP" for break
if check == 'YES':
enter = "STOP"
break
or
if check == 'YES':
break
both should work, I guess you could go with the first answer if you need to keep the state of the variable enter otherwise you could just use the second.
The problem with your original code is that you are missing a parenthesis on the declaration of the upper method in this line:
check = str(input("Are you sure you are in " + ori + ", and would like to go to " + dest + "? ")).upper
instead it should be:
check = str(input("Are you sure you are in " + ori + ", and would like to go to " + dest + "? ")).upper()
if you don't add the parenthesis to upper() it means you are declaring the object method itself not triggering instead what the method actually does. (In this case making the string uppercase)

How do I use user input, obtained through a function, to alter global variables?

I have a global variable that needs to be altered by user input generated by a function.
I'm trying to make a Zork style text game and want the character name, input by the user during a character creation function, to alter a global variable.
I've been able to create a class to store character information and been able to display most of the information in the class on a mock command prompt I have appear when input options are available to the user.
I use a global variable to define the character's name until the character creation stage. I use the 'global' keyword in the creation() function to alter the 'name' variable with user input.
When the prompt is ready to be used it still only displays the name as 00 instead of the input generated during the creation() function
I am exceedingly novice. Any advice, tips or direction would be cherished.
import time
name = "00" ##this is what we want to change
##
def Intro():
print("\n\n\nWelcome to the game.")
time.sleep(1)
print("This is an attempt to make an interactive text based game.")
##
def Creation():
Character_name = input("\nWhat will your Character's name be: ")
time.sleep(1)
print("\nWelcome to the game " + Character_name + " \n" )
time.sleep(1.5)
Character_class = input("In one word, name " + Character_name + "'s profession: ")
t00n = Character_name + " the " + Character_class
global name ##here I am using the global keyword
name = t00n
time.sleep(1)
print("\n" + t00n + "\n")
time.sleep(2)
next_func = input("When ready type 'next' to begin.\n>>>:")
if next_func == "next":
segway()
else:
Jump()
##
def Jump():
Jump_Prompt = input("Just 'Jump' on in\n>>>: ")
if Jump_Prompt == "Jump":
segway1()
else:
Jump()
##
def segway():
print("A room with options to choose from")
prompt()
class Character:
def __init__(self, name, HP, full_HP, AtS, AR):
self.name = name ##should = t00n now?
self.hp = HP
self.full_HP = full_HP
self.AtS = AtS
self.AR = AR
def stat_bar(self):
return '{} {} {} {} {} {}'.format("[Name:]", self.name, "[HP:]", self.hp, "[Max HP:]", self.full_HP)
Player1 = Character(name, 100, 100, 1, 0)
##
def prompt():
_pr = input("<<< " + Character.stat_bar(Player1) + " >>> \n")
return _pr
#Begin
Intro()
Creation()
segway()
##The prompt() function still displays the name as 00 even tho the creation() function is using the 'global' keyword to change the 'name' variable to the user input.
You need to use the global keyword in your prompt, and update Player1.name with that global name
def prompt():
#Take name from global scope
global name
#Assign it to Player1 name
Player1.name = name
_pr = input("<<< " + Character.stat_bar(Player1) + " >>> \n")
return _pr
Then your prompt will work as intended, for example
Welcome to the game.
This is an attempt to make an interactive text based game.
What will your Character's name be: Joe
Welcome to the game Joe
In one word, name Joe's profession: Don
Joe the Don
When ready type 'next' to begin.
>>>:next
A room with options to choose from
<<< [Name:] Joe the Don [HP:] 100 [Max HP:] 100 >>>
Ahhh, took a little bit, but I think I found the problem.
You initialize Player 1 using the name variable before calling Creation(), where you change the global name variable, so Player1 is created with the original name “00.”
Move the line:
Player1 = Character(name, 100, 100, 1, 0)
Put it after Creation() at the bottom but before segway()
Python more or less executes any unindented code (code that isn’t in a function, class, etc.) from top to bottom.
So, moving from top to bottom in your program, it sets name to “00”, then creates Player1 with the original name, then calls Intro(), Creation() (which changes the name to t00n), and finally segway().

Local variable 'first' referenced before assignment [duplicate]

This question already has answers here:
Using global variables in a function
(25 answers)
Closed 7 years ago.
I get a Local variable 'first' referenced before assignment error when I run my code.
def start():
global a
a = [" "," "," "," "," "," "," "," "," "]
global first
first = randrange(2)
def reverse():
if first == 1:
first = 0
else:
first = 1
if first == 1:
turn = "X"
else:
turn = "O"
That is just a part of my code where the error occurs. However when I paste the code into IDLE it works no problem so I don't know why this is happening.
Anyways, my full code (unfinished Tic Tac Toe):
from os import name
from os import system
from random import randrange
from time import sleep
def cls():
system(['clear','cls'][name == 'nt'])
def start():
global a
a = [" "," "," "," "," "," "," "," "," "]
global first
first = randrange(2)
def reverse():
if first == 1:
first = 0
else:
first = 1
if first == 1:
turn = "X"
else:
turn = "O"
while True:
reverse()
cls()
printBoard()
print ""
print "Its %s's turn." % (turn)
print ""
move = raw_input("Enter your move (1-9): ")
if move.isdigit() == True:
move = int(move)
if move in range(9):
move = move - 1
if a[move] == " ":
a[move] = turn
else:
print "Incorrect move: Place taken"
reverse()
sleep(2)
else:
print "Incorrect move: Number out of range"
sleep(2)
else:
print "Incorrect move: Move not a number"
sleep(2)
def printBoard():
cls()
print a[0],"|",a[1],"|",a[2]
print "---------"
print a[3],"|",a[4],"|",a[5]
print "---------"
print a[6],"|",a[7],"|",a[8]
start()
Python scans a function body for any assignments, and if they aren't explicitly declared global, then it creates a local scope variable for that name. Because you assign to first in your reverse() function, and you haven't explicitly declared first to be global within that function's scope, python creates a local variable named first that hides the global one.
It doesn't matter that the assignment comes after the comparison; python implicitly declares all local variables at the beginning of the function.
To fix this you can declare first to be global within the reverse() function, but as others have said, globals should be avoided when possible.

Python 3.1.1 - Assign random values to a function

I need a way to assign random values to a function, call the function and print the value to the screen.
When I run the code as it is, the enemy's attack and user's defense does not get recalculated. What can I do to have Python recalculate these variables every time the function is called?
import random
enemyName = "Crimson Dragon"
def dragonAtk():
return random.randint(5,10)
def userDef():
return random.randrange(8)
userHp = 100
userName = input("What is your name? ")
enemyAttackname = "Fire Blast"
def enemyAttacks():
global battleDmg
global userHp
global enemyAtk
global userDef
enemyAtk = dragonAtk()
userDef = userDef()
print (">>> " + enemyName + " attacks " + userName + " with " + enemyAttackname + "!")
if enemyAtk < userDef:
print (">>> " + userName + " successfully defended the enemy's attack!")
elif enemyAtk == userDef:
print (">>> " + userName + " successfully parried the enemy's attack!")
else:
battleDmg = enemyAtk - userDef
userHp -= battleDmg
print (">>> " + userName + " takes " + str(battleDmg) + " DMG! "\
+ userName + " has " + str(userHp) + " HP remaining!")
enemyAttacks()
input()
enemyAttacks()
input()
This is my result
What is your name? Murk
>>> Crimson Dragon attacks Murk with Fire Blast!
>>> Murk takes 6 DMG! Murk has 94 HP remaining!
Traceback (most recent call last):
File "C:\Users\Junior\Desktop\python projects\test", line 37, in <module>
enemyAttacks()
File "C:\Users\Junior\Desktop\python projects\test", line 22, in enemyAttacks
userDef = userDef()
TypeError: 'int' object is not callable
>>>
So, I see it ran once through enemyAttacks(), but the second time gave me an error. Not sure what to make of it. Any thoughts?
Here:
userDef = userDef()
You have overridden your function. Thus, when you call the function again, you are trying to call the function, but you have an integer instead (hence the error).
Rename your variable to another name so you don't override your function.

Categories