Python won't return number variable back - python-2.7

The integer variables aren't working, they don't come back even though I used global on them, I even tried return and it didn't work. After numerous tries of trying to bug test and solve the problem I found the source of the problem but I don't know how to fix it. Because this code is very long (714) I won't put up the whole thing. Instead I'll put up what is required.
def plrcheck():
global pwr
global typ
if prsna in [sf1, sf2, sf3, sa1, sa2, sa3, sw1, sw2, sw3, se1, se2, se3]:
pwr = 5
elif prsna in [sf4, sf5, sa4, sa5, se4, se5, sw4, sw5]:
pwr = 8
elif prsna in [sf6, sa6, sw6, se6]:
pwr = 11
if prsna in [sf1, sf2, sf3, sf4, sf5, sf6]:
typ = 'Fire'
elif prsna in [sw1, sw2, sw3, sw4, sw5, sw6]:
typ = 'Water'
elif prsna in [sa1, sa2, sa3, sa4, sa5, sa6]:
typ = 'Air'
elif prsna in [se1, se2, se3, se4, se5, se6]:
typ = 'Earth'
pygame.display.flip()
def oppcheck():
global optyp
global oppwr
if opp in [sf1, sf2, sf3, sa1, sa2, sa3, sw1, sw2, sw3, se1, se2, se3]:
oppwr = 5
elif opp in [sf4, sf5, sa4, sa5, se4, se5, sw4, sw5]:
oppwr = 8
elif opp in [sf6, sa6, sw6, se6]:
oppwr = 11
if opp in [sf1, sf2, sf3, sf4, sf5, sf6]:
optyp = 'Fire'
elif opp in [sw1, sw2, sw3, sw4, sw5, sw6]:
optyp = 'Water'
elif opp in [sa1, sa2, sa3, sa4, sa5, sa6]:
optyp = 'Air'
elif opp in [se1, se2, se3, se4, se5, se6]:
optyp = 'Earth'
pygame.display.flip()
def atkchk(x):
plrcheck()
oppcheck()
if x == 'opponent':
if optyp == 'Air':
if typ == 'Earth':
oppwr += 2
elif optyp == 'Water':
if typ == 'Fire':
oppwr += 2
elif optyp == 'Fire':
if typ == 'Air':
oppwr += 2
elif optyp == 'Earth':
if typ == 'Water':
oppwr += 2
elif x == 'player':
if typ == 'Air':
if optyp == 'Earth':
pwr += 2
elif typ == 'Water':
if optyp == 'Fire':
pwr += 2
elif typ == 'Fire':
if optyp == 'Air':
pwr += 2
elif typ == 'Earth':
if optyp == 'Water':
pwr += 2
while pwr - oppwr < 0:
discard = int(math.fabs(pwr-oppwr)/2)+1
#Selection Process of Discarding for Player
while pwr - oppwr > -1:
discard = int(math.fabs(pwr-oppwr)/2)+1
#Selection process of discarding for opponent
win()
def game():
while matchLoop:
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_x:
plrcheck()
oppcheck()
atkchk('player')
The problem appears at for [atkchk(x)], it forgets the [pwr and oppwr] variable even though outside that it's still working. By the way this shouldn't require pygame knowledge just simple python knowledge should be enough. I have assigned all the other variables but that's not part of the problem (it was working completely fine until I added in [atkchk(x)]), and I've narrowed it down to what I said before. So is there anyway you know of to solve this?

Add a global reference to these variables at the top of the function like
def atkchk(x):
global pwr
global oppwr
Python will allow you to work with locally scoped variables with the same name as global variables. This can get a bit confusing. If you don't tell the function that you intend to work with the already defined globally scoped pwr and oppwr any assignment to these names will create a locally scoped variable of the same name, effectively hiding the global variables from your function.
Check out the answers to this post: Use of Global Keyword in Python
The second and third answers talk about the problem it appears you are running into.

Related

How to fix "list index out of range" error?

I keep getting "list index out of range" error. I have been trying to Google a solution, but I can't find anything that fits my problem.
I tried to use other random things like random.shuffle() and randint().
import random
svart = [18,28,38,58,68,78,88,47,46,45,44,43,42,41,37,26,15,57,66,75,84]
vit = [11,21,31,51,61,71,81,42,43,44,45,46,47,48,32,23,14,52,63,74,85]
def schack(svart,vit):
hit = 0
miss = 0
for i in range(10000):
random.choice(svart)
random.choice(vit)
if svart == vit:
i = i + 1
elif svart[18] == vit[11]:
hit += 1
elif svart[28] == vit[21]:
hit += 1
elif svart[38] == vit[31]:
hit += 1
elif svart[58] == vit[51]:
hit += 1
elif svart[68] == vit[61]:
hit += 1
elif svart[78] == vit[71]:
hit += 1
elif svart[88] == vit[81]:
hit += 1
elif svart[7,46,45,44,43,42,41] == vit[42,43,44,45,46,47,48]:
hit += 1
elif svart[37] == vit[31,47,32]:
hit += 1
elif svart[26] == vit[21,23,46]:
hit += 1
elif svart[15] == vit[11,45,14]:
hit += 1
elif svart[57] == vit[51,52,47]:
hit += 1
elif svart[66] == vit[46,61,63]:
hit += 1
elif svart[75] == vit[71,45,74]:
hit += 1
elif svart[84] == vit[81,44,85]:
hit += 1
elif svart[38,37,42] == vit[32]:
hit += 1
elif svart[28,43,26] == vit[23]:
hit += 1
elif svart[18,15,44] == vit[14]:
hit += 1
elif svart[58,42,57] == vit[52]:
hit += 1
elif svart[68,43,66] == vit[63]:
hit += 1
elif svart[78,44,75] == vit[74]:
hit += 1
elif svart[84,88,45] == vit[85]:
hit += 1
else:
miss += 1
print hit
print miss
schack(svart,vit)
This is a so-called chess simulator, that will take a value and compare the numbers from both lists. If the numbers "threaten each other", a point will be added. If both values are the same, it will not register the hit or miss and add an extra loop turn.
I don't know if I am comparing the values to each other incorrectly or what I am doing wrong.
Any help would be highly appreciated.
The following gives the 29th element of the list "svart":
svart[28]
But the list has only 21 elements. So you are accessing an element out of the possible range. That is why you get an "list index out of range" error.

Python: list comparison vs integer comparison which is more efficient?

I am currently implementing the LTE physical layer in Python (ver 2.7.7).
For the qpsk, 16qam and 64qam modulation I would like to know which is more efficient to use between an integer comparison and a list comparison:
Integer comparison: bit_pair as an integer value before comparison
# QPSK - TS 36.211 V12.2.0, section 7.1.2, Table 7.1.2-1
def mp_qpsk(self):
r = []
for i in range(self.nbits/2):
bit_pair = (self.sbits[i*2] << 1) | self.sbits[i*2+1]
if bit_pair == 0:
r.append(complex(1/math.sqrt(2),1/math.sqrt(2)))
elif bit_pair == 1:
r.append(complex(1/math.sqrt(2),-1/math.sqrt(2)))
elif bit_pair == 2:
r.append(complex(-1/math.sqrt(2),1/math.sqrt(2)))
elif bit_pair == 3:
r.append(complex(-1/math.sqrt(2),-1/math.sqrt(2)))
return r
List comparison: bit_pair as a list before comparison
# QPSK - TS 36.211 V12.2.0, section 7.1.2, Table 7.1.2-1
def mp_qpsk(self):
r = []
for i in range(self.nbits/2):
bit_pair = self.sbits[i*2:i*2+2]
if bit_pair == [0,0]:
r.append(complex(1/math.sqrt(2),1/math.sqrt(2)))
elif bit_pair == [0,1]:
r.append(complex(1/math.sqrt(2),-1/math.sqrt(2)))
elif bit_pair == [1,0]:
r.append(complex(-1/math.sqrt(2),1/math.sqrt(2)))
elif bit_pair == [1,1]:
r.append(complex(-1/math.sqrt(2),-1/math.sqrt(2)))
return r
Thanks

Making program do two things at the same time and command crashes game

I am trying to make a alternate way to create "gravity" with python 2.7. I need the game to move the x position of the ball 25 pixels to the right AND the y position of the ball 25 pixels up. So here a piece of my current program:
def jump(self):
false = 0
global false
while self.rect.top < 750 and false == 0:
self.rect.top += 50
self.rect.left += 50
while self.rect.top <= 750:
false = 1
self.rect.top -= 50
self.rect.left += 50
First, how do I make the program do the lines 5 and 6/ 9 and 10 at the same time? My next question will need this source code:
import pygame, sys
import time
pygame.init()
screen = pygame.display.set_mode([1500,750])
background = pygame.Surface(screen.get_size())
background.fill([255, 255, 255])
class Attacker(pygame.sprite.Sprite):
def __init__(self, image_file, location):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(image_file)
self.rect = self.image.get_rect()
self.rect.left, self.rect.top = location
def jump(self):
false = 0
global false
while self.rect.top < 750 and false == 0:
self.rect.top += 50
self.rect.left += 50
while self.rect.top <= 750:
false = 1
self.rect.top -= 50
self.rect.left += 50
my_ball = Attacker('wackyball.bmp', [300, 300])
running = True
while running:
screen.fill([255, 255, 255])
screen.blit(my_ball.image, my_ball.rect)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
my_ball.rect.top = my_ball.rect.top - 200
elif event.key == pygame.K_DOWN:
my_ball.rect.top = my_ball.rect.top + 125
elif event.key == pygame.K_RIGHT:
my_ball.rect.left += 175
elif event.key == pygame.K_LEFT:
my_ball.rect.left -= 125
elif event.key == pygame.K_SPACE:
my_ball.jump()
screen.blit(background, (0, 0))
screen.blit(my_ball.image, my_ball.rect)
pygame.display.flip()
pygame.quit()
When ever I press the spacebar so my guy will "jump" (do the jump function), my game crashes. Why does this happen?
Your game is crashing because it's getting inside the while loop and not returning.(inside the second while loop)
If you want to simulate gravity, you need to move the char a little bit every frame, the way you are doing you will move it all the way up, then all the way down in a single frame, meaning it won't appear to move.
Here's some ideas that might help you.
import pygame, sys
import time
pygame.init()
screen = pygame.display.set_mode([1500,750])
background = pygame.Surface(screen.get_size())
background.fill([255, 255, 255])
class Attacker(pygame.sprite.Sprite):
def __init__(self, image_file, location):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load(image_file)
self.rect = self.image.get_rect()
self.x_pos, self.y_pos = location
self.rect.x, self.rect.y = location
self.jumping = False
self.falling = False
self.direction = 1
def jump(self):
if self.y_pos > CEILING:
self.x_pos += 1*self.direction
self.y_pos -= 5
else:
self.jumping = False
self.falling = True
self.update_pos()
def fall(self):
if self.y_pos < FLOOR:
self.x_pos += 1*self.direction
self.y_pos += 5
else:
self.falling = False
self.update_pos()
def update_pos(self):
self.rect.x = self.x_pos
self.rect.y = self.y_pos
FLOOR = 700
CEILING = 300
my_ball = Attacker('wackyball.bmp',[300, FLOOR])
running = True
while running:
if my_ball.jumping:
my_ball.jump()
if my_ball.falling:
my_ball.fall()
screen.blit(my_ball.image, my_ball.rect)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
my_ball.y_pos -= 5
elif event.key == pygame.K_DOWN:
my_ball.y_pos += 5
elif event.key == pygame.K_RIGHT:
my_ball.direction = 1
my_ball.x_pos += 5
elif event.key == pygame.K_LEFT:
my_ball.direction = -1
my_ball.x_pos -= 5
elif event.key == pygame.K_SPACE:
if not my_ball.falling:
my_ball.jumping = True
my_ball.update_pos()
screen.blit(background, (0, 0))
screen.blit(my_ball.image, my_ball.rect)
pygame.display.flip()
pygame.quit()

raw_input() invalid syntax

I want to input a string of five numbers with spaces between them and use raw_input() for it. However the second item(the portion that's between the first and second spaces) is claimed to be a syntax error. Code below:
#class for final output - used as an ad hoc static string
class StatString:
outstring = ""
#function to check if Boom or Trach or both
def BoomTrach(num,B,T):
Boom = False
Trach = False
temp = num
while temp != 0:
if num % B == 0:
Boom == True
break
if (temp % 10) % B == 0:
Boom = True
break
temp = (temp - temp % 10) / 10
temp = num
while temp != 0:
if num % T == 0:
Trach = True
break
if (temp % 10) % T == 0:
Trach = True
break
temp = (temp - temp % 10) / 10
if Boom and Trach:
herestring.outstring = herestring.outstring + "Boom-Trach"
elif Boom:
herestring.outstring = herestring.outstring + "Boom"
elif Trach:
herestring.outstring = herestring.outstring + "Trach"
else:
herestring.outstring = herestring.outstring + str(num)
#start of "main" portion
def main():
inS = raw_input() <<<--- Input here
arr = inS.split(' ')
X = int(arr[0])
Y = int(arr[1])
CountFrom = int(arr[2])
jump = int(arr[3])
CountUntil = int(arr[4])
#variable for error check
error = False
#checking for errors
if X < 1 or X > 9 or Y < 1 or Y > 9:
print "X and Y must be between 1 and 9"
error = True
if jump == 0:
print "jump cannot be 0"
error = True
elif (CountUntil - CountFrom) % jump != 0:
print "cannot jump from %d to %d",CountFrom,CountUntil
error = True
if error:
exit()
if CountFrom < 0 and CountUntil < 0 and jump > 0:
jump = jump * (-1)
herestring = StatString()
while CountFrom != CountUntil:
BoomTrach(CountFrom,X,Y)
CountFrom = CountFrom + jump
if(CountFrom != CountUntil):
herestring.outstring = herestring.outstring + ","
print herestring.outstring
error message: (the second 1 was marked as the source of the error)
>>> 1 1 1 1 1
SyntaxError: invalid syntax
>>>
I know what happened. You just run this module, and you thought that you start running it from the main function (like in C for example).
There is no problem with the raw_input line (the first line of the input). The problem is that your module does not try to read anything! You just typed "1 1 1 1 1" which is of course syntax error...
Append to your code this line to run the main function:
main()
You can also write the code of the main function not in some function, to get the same effect.

How to consolidate if / elif statements in Python

I looked around and did some research, but for some reason I still couldn't get it to work as planned. Basically, as a beginner, I wrote a Mastermind code game- same rules and all. Here's the code:
import random
trial = 0
def geuss():
geuss = raw_input("What is your geuss? ")
global g1
global g2
global g3
global g4
a = geuss[:-3]
b = geuss[1:-2]
c = geuss[2:-1]
d = geuss[3:]
if a == peg1:
g1 = 'R'
elif a == peg2:
g1 = 'W'
elif a == peg3:
g1 = 'W'
elif a == peg4:
g1 = 'W'
else:
g1 = 'X'
if b == peg2:
g2 = 'R'
elif b == peg1:
g2 = 'W'
elif b == peg3:
g2 = 'W'
elif b == peg4:
g2 = 'W'
else:
g2 = 'X'
if c == peg3:
g3 = 'R'
elif c == peg1:
g3 = 'W'
elif c == peg2:
g3 = 'W'
elif c == peg4:
g3 = 'W'
else:
g3 = 'X'
if d == peg4:
g4 = 'R'
elif d == peg1:
g4 = 'W'
elif d == peg2:
g4 = 'W'
elif d == peg3:
g4 = 'W'
else:
g4 = 'X'
print g1, g2, g3, g4
global trial
trial = trial + 1
return trial
colour = ['B', 'G', 'Y', 'P', 'R']
peg1 = random.choice(colour)
peg2 = random.choice(colour)
peg3 = random.choice(colour)
peg4 = random.choice(colour)
g1 = 0
g2 = 0
g3 = 0
g4 = 0
print ""
while g1 != 'R' or g2 != 'R' or g3 != 'R' or g4 != 'R':
geuss()
print "Congratulations! It took you %d tries to crack the code!" % trial
print ""
print "The code was %s%s%s%s." % (peg1, peg2, peg3, peg4)
As you can see the if and elif statements in the function 'geuss()' are needlessly wrong- but when I tried putting them together the script would always put a W.
if a == peg1:
g1 = 'R'
elif a == peg2 or peg 3 or peg4:
g1 = 'W'
else:
g1 = 'X'
Even when I put "QWER" in as an input, I would get an X. Is there some way I can consolidate them while still getting the correct response?
Also, off topic, if there are any other suggestions you can give me on the script as I am a beginner, that would be much appreciated! Thank you!
When you use or or and, you need to specify which operation you are using. Here is what you wrote...
if a == peg1:
g1 = 'R'
elif a == peg2 or peg 3 or peg4:
g1 = 'W'
else:
g1 = 'X'
The elif in that asks if a is equal to peg2, and then if peg3 or peg4 exists. You need to change it so a == peg3/4 also. Like this...
elif a == peg2 or a == peg3 or a == peg4:
In regards to your if/elif question a typical Python idiom to use a dictionary for a switch statement.
// http://stackoverflow.com/questions/374239/why-doesnt-python-have-a-switch-statement
{'option1': function1,
'option2': function2,
'option3': function3,
'option4': function4,
}.get(value, defaultfunction)()
However, in this case I believe you are taking the wrong approach. "Thinking" in Python is a little different than other languages and takes awhile to get used to doing things "the Python way". You seem to understand lists, and string slices which is good. You can leverage that a bit more to simplify your Mastermind program as shown below.
import random
trial = 0
colour = ['B', 'G', 'Y', 'P', 'R']
pegs = [random.choice(colour), random.choice(colour), random.choice(colour), random.choice(colour)]
guess_pegs = ['?', '?', '?', '?']
def main():
print "Generating a code"
print pegs
guess()
print "Congratulations! It took you %d tries to crack the code!\n" % trial
print "The code was: " + ', '.join(pegs)
def guess():
global trial
global pegs
global guess_pegs
entry_list = ['?', '?', '?', '?']
while pegs != guess_pegs :
entry_list = raw_input("What is your guess? ").split(' ')
trial = trial + 1
if len(pegs) == len(entry_list) :
for i in range(0,4) :
if(entry_list[i] == pegs[i]) :
guess_pegs[i] = entry_list[i]
print guess_pegs
guess()
# Kick things off
main()
An experienced python programmer would write:-
elif a == peg2 or a == peg3 or a == peg4:
as:-
elif a in (peg2, peg3, peg4):