Global variable is not defined - Python and PyGame - python

i try to create a Flappy Bird clone. When i try to define some Global variables visual studio said me that this variables aren't defined in global scope.
Some could help me??
I tried to move the variables in the global scope and it works, but i don't understand why this solution doesn 't work.
This is my code
Thanks in advance
import pygame
import random
pygame.init()
background = pygame.image.load('img/background.png')
base = pygame.image.load('img/base.png')
bird = pygame.image.load('img/bird.png')
gameover = pygame.image.load('img/gameover.png')
pipe_down = pygame.image.load('img/pipe.png')
pipe_up = pygame.transform.flip(pipe_down, False, True)
windowX = 288
winwowY = 512
frame_rate = 50
display_surface = pygame.display.set_mode((windowX, winwowY))
FPS = frame_rate
pygame.display.set_caption('Flappy Bird')
def drawObject():
display_surface.blit(background, (0, 0))
display_surface.blit(bird, (birdX, birdY))
def update():
pygame.display.update()
pygame.time.Clock().tick(FPS)
# Here is where define my global vars
def initializes():
global birdX, birdY, birdSpeedY
birdX = 60
birdY = 150
birdSpeedY = 0
initializes()
while True:
birdSpeedY += 1
birdY += birdSpeedY
drawObject()
update()

The message is telling you exactly what the issue is. The global variables aren't defined in global scope.
That means that for these variables that you are telling it you want to use from the global namespace global birdX, birdY, birdSpeedY, it expects to find a definition of those in that uppermost namespace. The global keyword does NOT create them in the global namespace just because you use it. They must exist there independent of that.
For them to be defined in the global scope there needs to be an assignment to them in the global namespace, not inside a function or a class. That cannot be something a += either since that is a reference and an assignment and so it assumes that the definition must be elsewhere (or it would be being referenced before a value was assigned).
So somewhere in the global namespace you need an assignment. If you want to handle the initialization in a function (as you are doing) it must still be defined/assigned outside that function, but it can be any value, like None. So you could add this near the top of you program:
birdX = None
birdY = None
birdSpeedY = None
Then still use your initializes() as you are.
Or in your case you would probably just take the stuff inside initializes() and put it at the top /global level.

Related

Are there cases where global keyword is necessary in python?

I want to know if there are some cases where declaring global keyword is necessary in python.
Yes, there are some cases where global is neccessary.
Have a look at this code, which will work fine:
i = 42 # this is a global var
def f():
print(i)
But what if you would like to edit i (which is a global variable).
If you do this, you get an error:
i = 42 # this is a global var
def f():
i += 1 # this will not work
print(i)
We can only access i. If python compiles the function to bytecode it detects an assignment to a variable and it assumes it is a local variable. But this is not the case here (it is a global variable). Therefore if we also want to modify the global var i we must use the global keyword.
i = 42 # this is a global var
def f():
global i
i += 1 # this will change the global var without error
print(i)
When you have shared resources and want to make changes in global one.
a = 0
def add_five():
global a
a += 5
def remove_two():
global a
a -= 2
add_five() # a = 5
add_five() # a = 10
add_five() # a = 15
remove_two() # a = 13

Why is this variable not defined if it is a global variable?

I create a list and try to append it to another list, but even though it is a global list it still is not defined.
I had the same issue trying to apppend a string to another list, and that had the same error so I tried to make the string a list.
sees if the player hits
def hit_or_stand():
global hit **<-- notice hit is a global variable**
if hitStand == ("hit"):
player_hand()
card = deck()
hit = []
hit.append(card)
now I need to append hit to pHand (player's hand)
def player_hand():
global pHand
deck()
pHand = []
pHand.append(card)
deck()
pHand.append(card)
pHand.append(hit) **<--- "NameError: name 'hit' is not defined"**
pHand = (" and ").join(pHand)
return (pHand)
hit_or_stand()
player_hand()
global hit
This does not declare a variable which is global. It does not create a variable which does not exist. It simply says "if you see this name in this scope, assume it's global". To "declare" a global variable, you need to give it a value.
# At the top-level
hit = "Whatever"
# Or in a function
global hit
hit = "Whatever"
The only time you need a global declaration is if you want to assign to a global variable inside a function, as the name could be interpreted as local otherwise. For more on globals, see this question.
There is a misunderstanding of the global operation in OP's post. The global inside a function tells python to use that global variable name within that scope. It doesn't make a variable into a global variable by itself.
# this is already a global variable because it's on the top level
g = ''
# in this function, the global variable g is used
def example1():
global g
g = 'this is a global variable'
# in this function, a local variable g is used within the function scope
def example2():
g = 'this is a local variable'
# confirm the logic
example1()
print( g ) # prints "this is a global variable"
example2()
print( g ) # still prints "this is a global variable"

Python alter external variable from within function

When I run this it works, but it says
"name 'select_place' is assigned to before global declaration"
When I get rid of the second global, no comment appears, but as select_place is no longer global it is not readable (if selected) in my last line of code.
I'm really new to python, ideally I'd like a way of not using the global command but after searching i still can't find anything that helps.
My code:
def attempt(x):
if location =='a':
global select_place
select_place = 0
if location =='b'
global select_place
select_place = 1
place = ([a,b,c,d])
This is the start of some turtle graphics
def Draw_piece_a(Top_right):
goto(place[select_place])
You need to declare the variable first, additionally the function code can be made clearer:
select_place = False
def attempt(x):
global select_place
if location == 'a':
select_place = 0
elif location == 'b':
select_place = 1
Also, there is no return value for attempt(), is this what you want?

Using global variables as variable parameter on function on python

Im trying to do a function (Inside another function wich is a Toplevel() window on tkinter) That takes different args from different objects and move them acording to the args. Using global variables.
The thing is that for every object, I need different global variables and I dont know how to put the necessary globals for every single object.
Im trying to move images created with canvas.create_image() and I had already done that, but with an specific case.
Let me see if I can explain better:
from tkinter import *
import os
import Threading
def CargarImagen(nombre):
ruta = os.path.join('Imagenes',nombre)
imagen = PhotoImage(file=ruta)
return imagen
Space= Tk()
Space.title("Invaders! Give Some Space!")
Space.geometry ("540x540")
Space.resizable (width=NO, height=NO)
CanvSpace= Canvas(Space, width=540, height= 540)
CanvSpace.config(cursor="dotbox")
CanvSpace.pack()
ImagenFondoInicio= CargarImagen('Pantalla Inicio.gif')
FondoCanvSpace= Label(CanvSpace,image=ImagenFondoInicio)
FondoCanvSpace.pack()
DxInvader0=1 #direction x #These are the globals I need to switch on every case
DyInvader0=0 #directtion y
DxInvader1=1
DyInvader1=0
def VentanaPlayy():
Space.withdraw()
VentanaPlay= Toplevel()
VentanaPlay.title("Kill'em all!'")
VentanaPlay.resizable(width=NO, height=NO)
VentanaPlay.geometry("540x540")
def MoverInvader(numInvader, Global1, Global2, Invader): #This is where I want to put the globals as variables
global Global1, Global2 #So this would work
x,y= CanvPlay.coords(Invader)
if Global1+x<=Listaif1[numInvader]:
Global1+=-0.5
Global1= -Global1
y+=20
elif Global1+x>=Listaif2[numInvader]:
Global1+=0.5
Global1= -Global1
y+=20
print("Maximo Limite a la Derecha", CanvPlay.coords(Invader))
elif y>= 500:
print("Game Over")
CanvPlay.coords(Invader, x+Global1, y+Global2)
VentanaPlay.after(50,MoverInvader(numInvader, Global1, Global2, Invader))
def ThreadMoverInvader(numeromover):
b=Thread(target=numeromover, args=())
b.start()
CanvPlay= Canvas(VentanaPlay, width=540, height=540, bg="white")
CanvPlay.config(cursor="dotbox")
CanvPlay.place(x=-1,y=-1)
ImagenNave= CargarImagen("Ship.gif")
Nave= CanvPlay.create_image(260, 520, image=ImagenNave)
ImagenHowTo= CargarImagen("HowTo.gif")
HowTo= CanvPlay.create_image(260, 250, image=ImagenHowTo)
ImagenNave0= CargarImagen("InvaderJuego.gif")
Nave0= CanvPlay.create_image(21, 300, image=ImagenNave0)
CanvPlay.after(0, ThreadMoverInvader(MoverInvader(0, DxInvader0, DyInvader0, Nave0))) #I call the function here
ImagenNave1= CargarImagen("InvaderJuego.gif")
Nave1= CanvPlay.create_image(51, 300, image=ImagenNave1)
CanvPlay.after(0, ThreadMoverInvader(MoverInvader(1, DxInvader1, DyInvader1, Nave1))) #And here with their own globals and variables
Listaif1=[20, 50] #these are the lists I'm using for every if on the function I need
Listaif2=[490, 520]
VentanaPlay.mainloop()
Space.mainloop()
So is there any way to do this?
basically what I need to do is this:
A=1
B=2
def getglobals(global1):
global global1
and call it like :
getglobals(A)
getglobals(B)
Thank You!!
EDIT: I define VentanaPlayy() Because I use that function as a command on a button.
And btw, escuse my poor english skills... As you may notice in the code... My main languaje is spanish :)
Regards from Costa Rica :D
EDIT2: Forgot to put the error message:
def MoverInvader(numInvader, Global1, Global2, Invader):
SyntaxError: name 'Global1' is parameter and global

Global variables declared within function are still considered local

I am trying to write the program battleship. I have two gameboard matrices: one for player, one for computer. These are defined outside of main because I want them to be global variables because several functions manipulate/read them. I am using Python 2.6.1.
#create player game board (10x10 matrix filled with zeros)
playerBoard = [[0]*10 for i in range(10)]
#create computer game board (10x10 matrix filled with zeros)
computerBoard = [[0]*10 for i in range(10)]
Then I define the main function.
#define main function
def main():
global playerBoard
global computerBoard
#keepGoing is true
keepGoing = True
#while keepGoing is true
while keepGoing:
#call main menu function. Set to response.
response = mainMenu()
#if response is 1
if response == "1":
#begin new game
#call clearBoards function
clearBoards()
#call resetCounters function
resetCounters()
#call placeShips function (player)
playerBoard = placeShips(playerBoard, "player")
#call placeShips function (computer)
computerBoard = placeShips(computerBoard, "computer")
#call guessCycler function
guessCycler()
#if response is 2
if response == "2":
#keepGoing is false
keepGoing = False
Despite my declaration of global playerboard and global computerBoard within main PyScripter still says those are local variables. I don't understand this. How can I make sure they are global?
Documents I have already looked at:
Using global variables in a function other than the one that created them
Changing global variables within a function
http://www.python-course.eu/global_vs_local_variables.php
I definitely think you should reconsider if you need them to be global - You don't .-)
The cheap way, is do declare your stuff and the pass them on as parameters to the function
def MyFunc(board1):
print board1
board1 = "Very weak horse"
MyFunc(board1)
The real way to do it is to create a class and then access them using self
class MySuperClass():
def __init__(self):
self.horse = "No way up"
def myRealCoolFunc(self):
print self.horse
uhhh = MySuperClass()
uhhh.myRealCoolFunc()

Categories