unpacking tuples based on if statements - python

I'm creating a nested dictionary with values from a tuple that is based on if statement. The variables in the code(estabilidad_atm, Q_puntos_muestreo and puntos de muestreo) are defined in the global scope. When I run the function I got and error saying: name a is not defined. I'm not sure why it isn't working... I've thought of applying namedtuple but I'm not sure which is the best way to proceed. Thanks!
variables_coeficientes_por_punto = {}
for punto in puntos_de_muestreo:
x = punto[0]
if estabilidad_atm == 'A' and x <= 1:
a,c,d,f = (213,440.8,1.941,9.27)
elif estabilidad_atm == 'A' and x > 1:
a,c,d,f = (213,459.7,2.094,-9.6)
elif estabilidad_atm == 'B' and x <= 1:
a,c,d,f = (156,106.6,1.149,3.3)
elif estabilidad_atm == 'B' and x > 1:
a,c,d,f = (156,108.2,1.098,2)
elif estabilidad_atm == 'C' and x <= 1:
a,c,d,f = (104,61,0.911,0)
elif estabilidad_atm == 'C' and x > 1:
a,c,d,f = (104,61,0.911,0)
elif estabilidad_atm == 'D' and x <= 1:
a,c,d,f = (68,33.2,0.725,-1.7)
elif estabilidad_atm == 'D' and x > 1:
a,c,d,f = (68,44.5,0.516,-13)
elif estabilidad_atm == 'E' and x <= 1:
a,c,d,f = (50.5,22.8,0.678,-1.3)
elif estabilidad_atm == 'E' and x > 1:
a,c,d,f = (50.5,55.4,0.305,-34)
elif estabilidad_atm == 'F' and x <= 1:
a,c,d,f = (34,14.35,0.740,-0.35)
elif estabilidad_atm == 'F' and x > 1:
a,c,d,f = (34,62.6,0.180,-48.6)
for i in range(Q_puntos_muestreo):
variables_coeficientes_por_punto['punto '+ str(i+1)] = {}
variables_coeficientes_por_punto['punto ' + str(i+1)]['a'] = a
variables_coeficientes_por_punto['punto ' + str(i+1)]['c'] = c
variables_coeficientes_por_punto['punto ' + str(i+1)]['d'] = d
variables_coeficientes_por_punto['punto ' + str(i+1)]['f'] = f

Many large if statements like this can be replaced with a dict. For example,
tuples = {
'A': lambda x: (213,440.8,1.941,9.27) if x < 1 else (213,459.7,2.094,-9.6),
'B': lambda x: (156,106.6,1.149,3.3) if x <= 1 else (156,108.2,1.098,2),
...
}
variables_coeficientes_por_punto = {}
for punto in puntos_de_muestreo:
x = punto[0]
try:
a, c, d, f = tuples[estabilidad_atm](x)
except KeyError:
raise
for i in range(1, Q_puntos_muestreo + 1):
variables_coeficientes_por_punto['punto '+ str(i)] = dict(a=a, c=c, d=d, f=f)
This will raise a KeyError if estabilidad_atm is not a valid key, at which point you can optionally catch and do something sensible, rather than simply let your program exit.

Related

If a certain letter is included in a string then its coordinate will increase or decrease

The program should ask what its first coordinates are. Then movement is asked and its answer should be with
r,R,l,L,u,U,d,D.
Coordinate are input with a comma (x,y), and then again if 'u','d','l','r' are input then the x or y axis will increase or decrease.
'u' and 'd' for the y-axis; 'r' and 'l' for the x-axis.
def program_for_grid(x,y,where):
if where == 'r' or where == 'R':
# move x upp +
for r in range(len(where)):
r == 'r' or r == 'R'
x + 1
elif where == 'l' or where == 'L':
# move x down -
for l in range(len(where)):
l == 'l' or l == 'L'
x - 1
elif where == 'u' or where == 'U':
# move y up +
for u in range(len(where)):
u == 'u' or u == 'U'
y + 1
elif where == 'd' or where == 'D':
# move y down -
for d in range(len(where)):
d == 'd' or d == 'D'
y - 1
x_axis,y_axis = input('Initial position: ').split(',')
int_x_axix = int(x_axis)
int_y_axix = int(x_axis)
movement = input('Movement: ')
grid = program_for_grid(int_x_axix,int_y_axix,movement)
print(grid)
Something like this?
def delta(movement):
"""
Parse the string for movement instructions and
return resulting relative coordinates
"""
x = 0
y = 0
for letter in movement.lower():
if letter == "d": y -= 1
elif letter == "u": y += 1
elif letter == "l": x -= 1
elif letter == "r": x += 1
else:
print("warning: skipping undefined", letter)
return x, y
x_axis,y_axis = input('Initial position: ').split(',')
int_x_axix = int(x_axis)
int_y_axix = int(y_axis)
while True:
movement = input('Movement: ')
xdelta, ydelta = delta(movement)
int_x_axix += xdelta
int_y_axix += ydelta
print(f"resulting position: ({int_x_axix},{int_y_axix})")

Getting RecursionError: maximum recursion depth exceeded in comparison

creating a minesweeper game in pygame and i am getting a recursion error when running my code. how do i mitigate this? This is the code I have that checks to see if the clicked grid square is empty and if it is then it reveals that grid square as well as all the adjacent squares. the section that is getting this error is below:
def reveal_empty(rn,c, grid, revealed,box):
if grid[rn][c] != '0' and grid[rn][c] != '*':
revealed[rn][c] = True
if grid[rn][c] == '0':
revealed[rn][c] = True
# change row above
if rn-1 > -1:
r = grid[rn-1]
if c-1 > -1:
if not r[c-1] == '*':
revealed[rn-1][c-1] = True
reveal_empty(rn-1,c-1, grid, revealed,box)
if not r[c] == '*':
revealed[rn-1][c] = True
reveal_empty(rn-1,c, grid, revealed,box)
if c+1 < 10:
if not r[c+1] == '*':
revealed[rn-1][c+1] = True
reveal_empty(rn-1,c+1, grid, revealed,box)
#change same row
r = grid[rn]
if c-1 > -1:
if not r[c-1] == '*':
revealed[rn][c-1] + True
reveal_empty(rn,c-1, grid, revealed,box)
if c+1 < 10:
if not r[c+1] == '*':
revealed[rn][c+1] = True
reveal_empty(rn,c+1, grid, revealed,box)
#change row below
if rn+1 < 11:
r = grid[rn + 1]
if c-1 > -1:
if not r[c-1] == '*':
revealed[rn+1][c-1] = True
reveal_empty(rn+1,c-1, grid, revealed,box)
if not r[c] == '*':
revealed[rn+1][c] = True
reveal_empty(rn+1,c, grid, revealed,box)
if c+1 < 11:
if not r[c+1] == '*':
revealed[rn+1][c+1] = True
reveal_empty(rn+1,c+1, grid, revealed,box)
I guess you have this problem because there is no quick exit-clause for your recursive function. I suspect that because you don't check to see if the cell is already revealed ( revealed[row][col] == True ), then it never exits - it keeps recursing for ones already half-done in the processing queue (stack).
Maybe a quick check at the beginning of the function will fix it:
def reveal_empty( row, col, grid, revealed, box ):
if ( revealed[row][col] == False ):
# do recursive check else here!
else:
print("Cell[%d][%d] is already revealed" % ( row, col ) )
I figured it out. I had to add a check to each step of the recursion to check if the value has been revealed yet. see below:
# change row above
if rn-1 > -1:
r = grid[rn-1]
if c-1 >= -1:
if not r[c-1] == '*' and revealed[rn-1][c-1] == False:
revealed[rn-1][c-1] = True
if grid[rn-1][c-1] == '0':
reveal_empty(rn-1,c-1, grid, revealed,box)
if not r[c] == '*' and revealed[rn-1][c] == False:
revealed[rn-1][c] = True
if grid[rn-1][c] == '0':
reveal_empty(rn-1,c, grid, revealed,box)
if c+1 < 10:
if not r[c+1] == '*' and revealed[rn-1][c+1] == False:
revealed[rn-1][c+1] = True
if grid[rn-1][c+1] == '0':
reveal_empty(rn-1,c+1, grid, revealed,box)
#change same row
r = grid[rn]
if c-1 > -1:
if not r[c-1] == '*' and revealed[rn][c-1] == False:
revealed[rn][c-1] + True
if grid[rn][c-1] == '0':
reveal_empty(rn,c-1, grid, revealed,box)
if c+1 < 10:
if not r[c+1] == '*' and revealed[rn][c+1] == False:
revealed[rn][c+1] = True
if grid[rn][c+1] == '0':
reveal_empty(rn,c+1, grid, revealed,box)
#change row below
if rn+1 < 11:
r = grid[rn + 1]
if c-1 > -1:
if not r[c-1] == '*' and revealed[rn+1][c-1] == False:
revealed[rn+1][c-1] = True
if grid[rn+1][c-1] == '0':
reveal_empty(rn+1,c-1, grid, revealed,box)
if not r[c] == '*' and revealed[rn+1][c] == False:
revealed[rn+1][c] = True
if grid[rn+1][c] == '0':
reveal_empty(rn+1,c, grid, revealed,box)
if c+1 < 11:
if not r[c+1] == '*' and revealed[rn+1][c+1] == False:
revealed[rn+1][c+1] = True
if grid[rn+1][c+1] == '0':
reveal_empty(rn+1,c+1, grid, revealed,box)

Poker Hand Win Logic doesn't work correctly

Something's wrong with how the winner is determined in my poker game.
I've tried checking that the player score value is reset from the loop
and that all other logic related variables are too
TableCards = []
for Card in Flop:
TableCards.append(Card)
TableCards.append(Turn)
TableCards.append(River)
for Card in Player.Hand:
TableCards.append(Card)
TableCardValues = []
TableCardSuits = []
for Card in TableCards:
TableCardValues.append(Card.Value)
TableCardSuits.append(Card.Suit)
TableCardValues.sort()
TableCardSuits.sort()
ArrayLengthI = len(TableCardValues)
Straight = False
Flush = False
Pairs = []
ThreeOfAKinds = []
FourOfAKinds = []
StraightCount = 0
PlayerHandValues = []
DealerHandValues = []
for Card in Player.Hand:
PlayerHandValues.append(Card.Value)
for Card in Dealer.Hand:
DealerHandValues.append(Card.Value)
for X in range(ArrayLengthI - 1):
if TableCardValues[X + 1] == TableCardValues[X] + 1:
StraightCount += 1
if StraightCount >= 5:
Straight == True
for Suit in TableCardSuits:
if TableCardSuits.count(Suit) >= 5:
Flush = True
for Value in set(TableCardValues):
if TableCardValues.count(Value) == 2:
Pairs.append(Value)
elif TableCardValues.count(Value) == 3:
ThreeOfAKinds.append(Value)
elif TableCardValues.count(Value) == 4:
FourOfAKinds.append(Value)
if Straight == True or Flush == True:
if Straight == True and Flush == True:
Player.HandScore = PokerHands.StraightFlush * max(PlayerHandValues)
elif Straight == True:
Player.HandScore = PokerHands.Straight * max(PlayerHandValues)
elif Flush == True:
Player.HandScore = PokerHands.Flush * max(PlayerHandValues)
elif FourOfAKinds != []:
Player.HandScore = PokerHands.FourOfAKind * max(PlayerHandValues)
elif ThreeOfAKinds != []:
if len(Pairs) >= 1:
Player.HandScore = PokerHands.FullHouse * max(PlayerHandValues)
else:
Player.HandScore = PokerHands.ThreeOfAKind * max(PlayerHandValues)
elif len(Pairs) == 2:
Player.HandScore = PokerHands.TwoPair * max(PlayerHandValues)
elif len(Pairs) == 1:
Player.HandScore = PokerHands.OnePair * max(PlayerHandValues)
else:
Player.HandScore = PokerHands.HighCard * max(PlayerHandValues)
TableCardsDealer = []
TableCardValuesDealer = []
TableCardSuitsDealer = []
for Card in Flop:
TableCardsDealer.append(Card)
TableCardsDealer.append(Turn)
TableCardsDealer.append(River)
DealerStraight = False
DealerFlush = False
DealerStraightCount = 0
DealerPairs = []
DealerThreeOfAKinds = []
DealerFourOfAKinds = []
for Card in Dealer.Hand:
TableCardsDealer.append(Card)
for Card in TableCards:
TableCardValuesDealer.append(Card.Value)
TableCardSuitsDealer.append(Card.Suit)
TableCardSuitsDealer.sort()
TableCardValuesDealer.sort()
TableCardsDealerLength = len(TableCardSuitsDealer)
for X in range(TableCardsDealerLength - 1):
if TableCardValuesDealer[X + 1] == TableCardValuesDealer[X] + 1:
DealerStraightCount += 1
if DealerStraightCount >= 5:
DealerStraight == True
for Suit in TableCardSuitsDealer:
if TableCardSuitsDealer.count(Suit) >= 5:
DealerFlush == True
for Value in set(TableCardValuesDealer):
if TableCardValuesDealer.count(Value) == 2:
DealerPairs.append(Value)
elif TableCardValuesDealer.count(Value) == 3:
DealerThreeOfAKinds.append(Value)
elif TableCardValuesDealer.count(Value) == 4:
DealerFourOfAKinds.append(Value)
if DealerStraight == True or DealerFlush == True:
if DealerStraight == True and DealerFlush == True:
Dealer.HandScore = PokerHands.StraightFlush * max(DealerHandValues)
elif DealerStraight == True:
Dealer.HandScore = PokerHands.Straight * max(DealerHandValues)
elif DealerFlush == True:
Dealer.HandScore = PokerHands.Flush * max(DealerHandValues)
elif DealerFourOfAKinds != []:
Dealer.HandScore = PokerHands.FourOfAKind * max(DealerHandValues)
elif DealerThreeOfAKinds != []:
if len(DealerPairs) >= 1:
Dealer.HandScore = PokerHands.FullHouse * max(DealerHandValues)
else:
Dealer.HandScore = PokerHands.ThreeOfAKind * max(DealerHandValues)
elif len(DealerPairs) == 2:
Dealer.HandScore = PokerHands.TwoPair * max(DealerHandValues)
elif len(DealerPairs) == 1:
Dealer.HandScore = PokerHands.OnePair * max(DealerHandValues)
else:
Dealer.HandScore = PokerHands.HighCard * max(DealerHandValues)
if Player.HandScore > Dealer.HandScore:
print("Well Done, sir. You've won.")
Player.Money += Pot
Pot = 0
elif Player.HandScore < Dealer.HandScore:
print("I Apologise, but you've lost.")
Dealer.Money += Pot
Pot = 0
elif Player.HandScore == Dealer.HandScore:
print("You've tied")
Pot = 0
Junk = input()
Player.HandScore = 0
Dealer.HandScore = 0
system("cls")
There are no error messages, but it seems to determine the winner wrong, and I can't exactly pinpoint the reason why.

break the for statement loop

Why the output for this code is:
DRAW
A WINS
A WINS
ERROR
and not
DRAW
A WINS
ERROR
ERROR
as it supposed to be?
Why break doesn't work and doesn't give the result = 'ERROR' for string with not allowed letter "T" in strB? (strB = 'SRTR')
def RockPaperScissors(strA,strB):
A_win = 0
B_win = 0
allowed_letters = 'SRP'
if (len(strA) != len(strB)):
result = 'ERROR'
elif (len(strA) == len(strB)):
for char in strA:
for c in strB:
if char not in allowed_letters:
result = 'ERROR'
break
elif c not in allowed_letters:
result = 'ERROR'
break
for i in range(0,len(strA)):
if (strA[i] == 'R' and strB[i] == 'S'):
a_win = 1
A_win += a_win
if (strA[i] == 'S' and strB[i] == 'P'):
a_win = 1
A_win += a_win
if (strA[i] == 'P' and strB[i] == 'R'):
a_win = 1
A_win += a_win
if (strB[i] == 'R' and strA[i] == 'S'):
b_win = 1
B_win += b_win
if (strB[i] == 'S' and strA[i] == 'P'):
b_win = 1
B_win += b_win
if (strB[i] == 'P' and strA[i] == 'R'):
b_win = 1
B_win += b_win
if A_win > B_win:
result = 'A WINS'
if B_win > A_win:
result = 'B WINS'
if A_win == B_win:
result = 'DRAW'
return result
print(RockPaperScissors('RP','PR'))
print(RockPaperScissors('PPP','RRR'))
print(RockPaperScissors('RPSR','SRTR'))
print(RockPaperScissors('RPS','RPSRP'))
Break only break the current loop. What you want to do is not break but return directly that there was an error.
for char in strA:
for c in strB:
if char not in allowed_letters:
return 'ERROR'
elif c not in allowed_letters:
return 'ERROR'

How to handle functions call in RPN

I'm having a lot of trouble converting infix notation to postfix.
For instance, I want to convert this
test(a(b+c), d()) - 3
into this
b c + a , d test 3 -
I tried this solution,
def composition(s):
i = 0
rpnstack = []
stack = []
ret = []
count = 0
while i < len(s) :
if i + 1 < len(s) and s[i + 1] == "(":
stack.append([count, rpnstack, s[i]])
i += 2
count = 1
rpnstack = []
elif s[i] == "(":
count += 1
rpnstack.append(s[i])
i += 1
elif s[i] == ")":
count -= 1
if count == 0:
for a in rpn(rpnstack):
ret.append(a)
a = stack.pop()
count = a[0]
rpnstack = a[1]
ret.append(a[2])
else:
rpnstack.append(s[i])
i += 1
else:
rpnstack.append(s[i])
i += 1
for a in rpn(rpnstack):
ret.append(a)
return ret
where RPN is the standard algorithm for the reverse polish notation and is is the infix string splitted with this regex
(\+|\-|\*|\/|\>|\<|\(|\)|\,)
But it only works sometimes.
This is the full implementation of the rpn function
operator = -10
operand = -20
leftparentheses = -30
rightparentheses = -40
empty = -50
operands = ["+", "-", "*", "/", ">", "<", "=", ","]
def precedence(s):
if s is '(':
return 0
elif s is '+' or '-':
return 1
elif s is '*' or '/' or '%':
return 2
else:
return 99
def typeof(s):
if s is '(':
return leftparentheses
elif s is ')':
return rightparentheses
elif s in operands:
return operator
elif s is ' ':
return empty
else :
return operand
def rpn(infix):
postfix = []
temp = []
for i in infix :
type = typeof(i)
if type is leftparentheses :
temp.append(i)
elif type is rightparentheses :
next = temp.pop()
while next is not '(' or skip > 0:
postfix.append(next)
next = temp.pop()
elif type is operand:
postfix.append(i)
elif type is operator:
p = precedence(i)
while len(temp) is not 0 and p <= precedence(temp[-1]) :
postfix.append(temp.pop())
temp.append(i)
elif type is empty:
continue
while len(temp) > 0 :
postfix.append(temp.pop())
return postfix
if i try to use the code against this infix expression:
i < test.func()
i get:
[' test.func', 'i ', '<']
and against this
i < 10
i get:
['i ', ' 10', '<']
How can I fix this?

Categories