I've been creating a combination calculator, something I'm having a hard time creating. A problem I'm constantly trying to fix is dealing with any infinite loops in my code.
oglist = ["a","b","c","d"]
combocounter = 3
lists = {}
comboloop = True
combolist = ["lol"]
pendinglist = ["lol"]
for x in range(0, combocounter):
lists["list" + str(x)] = ["lol"]
def loop(counter1):
global recursion1
global recursion2
if len(lists["list" + str(counter1)]) == 0:
lists["list" + str(counter1 - 1)] = lists["list" + str(counter1 - 1)][1:]
print(lists)
recursion1 = True
recursion2 = True
else:
lists["list" + str(counter1 + 1)] = lists["list" + str(counter1)][1:]
print(lists)
recursion2 = False
return
def startingloop():
global recursion1
if len(lists["list0"]) == 0:
comboloop = False
else:
lists["list1"] = lists["list0"][1:]
print(lists)
recursion1 = False
return
def endingloop():
global counter2
global recursion2
if len(lists["list2"]) == 0:
lists["list1"] = lists["list1"][1:]
print(lists)
recursion2 = True
else:
combolist[counter2] = lists["list0"][0]
for y in range(1, combocounter):
combolist[counter2] = combolist[counter2] + lists["list" + str(y)][0]
combolist.append("lol")
lists["list2"] = lists["list2"][1:]
counter2 += 1
print(lists)
print(combolist)
return
lists["list0"] = oglist
counter2 = 0
while comboloop == True:
startingloop()
while recursion1 == False:
loop(1)
while recursion2 == False:
endingloop()
combolist.remove("lol")
print(combolist)
I've placed a bunch of print functions:
print(lists) and print(combolist).
When I run it, lists and combolist are constantly updated and printed. It then stops printing which is expected, but my program keeps running something. It also never reaches
combolist.remove("lol")
print(combolist)
I went through the effort of following the logic of my code to find any issues, but I didn't. What's constantly looping in my code?
comboloop = False is creating a local variable that shadows your global called comboloop. If you add
global comboloop
in your startingloop() function, the program exits
Related
I'm creating a calculator and here's part of the code:
def _digit_formatting(x):
numbers = '1234567890.'
start_idxs = []
end_idxs = []
is_start = True
try:
for idx, value in enumerate(x):
if value in numbers and is_start:
start_idxs.append(idx)
is_start = False
elif value in numbers and idx == len(x) - 1:
end_idxs.append(len(x) - 1)
elif value in numbers and not is_start:
pass
elif value not in numbers and len(start_idxs) > len(end_idxs):
end_idxs.append(idx-1)
is_start = True
except:
...
if len(start_idxs) > len(end_idxs):
end_idxs.append(start_idxs[-1])
start_idxs.reverse()
end_idxs.reverse()
x = list(x)
for idx in range(len(start_idxs)):
if start_idxs[idx] == end_idxs[idx]:
num = x[start_idxs[idx]:end_idxs[idx]+1]
else:
num = x[start_idxs[idx]:end_idxs[idx]+1]
num = ''.join(num)
x = ''.join(x)
x = x[::-1]
num = num[::-1]
x = x.replace(num, '', 1)
x = list(x)
x.reverse()
num = num[::-1]
temp = f'{int(num):,}'
x.insert(start_idxs[idx], temp)
x = ''.join(x)
return x
def calculate(sv):
# This function is called when there's changes in entry box
if self.input_string_var.get() == '':
self.result_string_var.set('')
# Start
real_result = self.input_string_var.get().replace(',', '')
percent_count = self.input_string_var.get().count('%')
# Formatting input string
x = _digit_formatting(real_result)
print(x)
self.input_string_var.set(x)
if percent_count != 0:
numbers = '0123456789.'
for cnt in range(percent_count):
percent_idx = real_result.find('%', 0)
limit_operator = 2
percent_number = ''
for i in range(percent_idx - 1, -1, -1):
if real_result[i] not in numbers:
limit_operator -= 1
if limit_operator == 0:
break
if limit_operator == 1:
if real_result[i] in '*/':
percent_number = ''
break
else:
percent_number += real_result[i]
if percent_number == '':
percent_number = '1'
else:
percent_number = percent_number[1:][::-1]
real_result = list(real_result)
real_result[percent_idx] = f'/100*{percent_number}'
real_result = ''.join(real_result)
else:
real_result = self.input_string_var.get().replace(',', '')
try:
if eval(real_result) == int(eval(real_result)):
self.result_string_var.set(f'{int(eval(real_result)):,}')
else:
self.result_string_var.set(f'{int(eval(real_result)):,}')
except:
None
if self.input_string_var.get() == '':
self.result_string_var.set('')
# Entry box string variable
self.input_string_var = tk.StringVar()
self.input_string_var.trace('w', lambda name, index, mode: calculate(self.input_string_var))
There is two functions, first is _digit_formatting which is to format the equation to put comma like thousands, million and billion. The calculate function is called every time there's changes on the input string variable. But when I try to set the string variable to equation after formatting there seems to be a mistake, but if I print the value, it is correct. Example if I enter 1200 the value I printed is 1,200 which is correct but the value on the text box is not correct. Sorry if the code is messy, I'm still learning to make a clean code.
I cannot reproduce your code.
If you can take a look of my example.
n = 1234567890
print(f"I have {n:,} Reputations")
Result:
I have 1,234,567,890 Reputations
My Problem is on line 25 when it says
if conformation == 1:
for i in range(l, len(lines[k]), 1):
if lines[k][i].isdigit() or lines[k][i].istitle():
f += lines[k][i]
if f in var:
print(var[f])
What my issue is is that the "f" string isn't being added to and its value stays as "". For context, I'm trying to make my own sort of mini programming language, and I'm trying to make prints read for variables. Every time it loops to set f to the variable name, nothing happens. The only way I get remotely close to finding the variable name is by doing "print(lines[k][i])" before the "if lines[k][i]" condition.
Note: I was using a debugger, and I'm not sure if the "if f in var" condition is even being checked.
Python code that reads my custom programming language:
⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄
code = open("HelloWorld.sabo", 'r')
lines = code.readlines()
var = {}
for k in range(0, len(lines), 1):
conformation = 0
temp = ""
temp2 = ""
if lines[k][0:5] == "print":
r = 0
l = 0
p = False
f = ""
for i in lines[k]:
r += 1
if not p:
l += 1
if i == "(":
p = True
conformation += 1
if i == "\"" and conformation == 1:
conformation += 1
if conformation == 2:
break
if conformation == 1:
for i in range(l, len(lines[k]), 1):
if lines[k][i].isdigit() or lines[k][i].istitle():
f += lines[k][i]
if f in var:
print(var[f])
if conformation == 2:
for i in range(r, len(lines[k]), 1):
if not lines[k][i] == "\"":
f += lines[k][i]
else:
break
print(f)
elif lines[k][0:4] == "var ":
for i in range(4, len(lines[k]), 1):
if not lines[k][i] == " ":
temp += lines[k][i]
else: break
for i in range(4, len(lines[k])):
if lines[k][i] == "=":
conformation = 1
elif conformation == 1:
if not lines[k][i] == " ":
temp2 += lines[k][i]
elif not temp2 == "":
break
var[temp] = temp2.strip()
Code that is being read by the above script:
⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄⌄
var val = hello
print(val)
So, I was being a bit dumb with this, but I found out that if I just account for Uppercase and Lowercase characters, then it will work.
if lines[k][i].islower() or lines[k][i].isdigit() or lines[k][i].isnumeric() or lines[k][i].istitle():
f += lines[k][i]
I might have gone overboard with the security though I'm just not sure about the difference isdigit and isnumeric.
I'm trying to follow a python tutorial on chess, but when i run the function to check for Checkmates and possible moves, I get the following error:
File "d:\Coding\Projects\Chess\stuff\ChessEngine.py", line 86, in getValidMoves
if not (moves[i].endRow, moves[i].endCol) in validSqaures:
UnboundLocalError: local variable 'validSqaures' referenced before assignment
This is the code I used for the function
def getValidMoves(self):
moves = []
self.inCheck, self.pins, self.checks = self.checkForPinsAndChecks()
if self.whiteToMove:
kingRow = self.whiteKingLocation[0]
kingCol = self.whiteKingLocation[1]
else:
kingRow = self.blackKingLocation[0]
kingCol = self.blackKingLocation[1]
if self.inCheck:
if len(self.checks) == 1: #Only 1 piece checking the King
moves = self.getAllPossibleMoves()
check = self.checks[0]
checkRow = check[0]
checkCol = check[1]
pieceChecking = self.board[checkRow][checkCol]
validSquares = [] #Sqaures pieces can move to
if pieceChecking[1] == "N":
validSqaures = [(checkRow, checkCol)]
else:
for i in range(1, 8):
validSquare = (kingRow + check[2] * i, kingCol + check[3] * i)
validSquares.append(validSquare)
if validSquares[0] == checkRow and validSquares[1] == checkCol:
break
for i in range(len(moves) -1 ,-1, -1):
if moves[i].pieceMoved[1] != 'K':
if len(moves) != 0:
if not (moves[i].endRow, moves[i].endCol) in validSqaures:
moves.remove(moves[i])
else: #Double check, King has to move
self.getKingMoves(kingRow, kingCol, moves)
else: #Not in check so any move is fine
moves = self.getAllPossibleMoves()
if len(moves) == 0: #either CheckMate or Stalemate
if self.inCheck == True:
self.checkMate = True
else:
self.staleMate = True
else:
self.checkMate = False
self.staleMate = False
return moves
When I try placing the list validSqaures anywhere else, it just turns blank and doesnt allow me to make anymore moves after putting the opponent king in check.
while not endgame:
cardsOnTable = OnTable()
faceUp1 = player1.dequeue()
cardsOnTable.place('player1',faceUp1,False)
faceUp2 = player2.dequeue()
cardsOnTable.place('player2',faceUp2,False)
print(str(cardsOnTable))
size1 = player1.size()
size2 = player2.size()
print('Player1 : '+str(size1),'Player2 : '+str(size2))
result = compareCard(faceUp1,faceUp2)
elif result == 0:
print('WAR STARTS!!!')
i = 0
player1war = [] #a list for placing player1's card in war(cards on table)
player2war = [] #a list for placing player2's card in war(cards on table)
while i < nbWarCards:
faceDown1 = player1.dequeue()
player1war.append(faceDown1)
faceDown2 = player2.dequeue()
player2war.append(faceDown2)
i += 1
for card in player1war:
cardsOnTable.place('player1',card,True)
player1war.clear()
for card in player2war:
cardsOnTable.place('player2',card,True)
player2war.clear()
if player1.size() == 0 or player2.size() == 0:
endgame = True
my problem happens when I tried to print(str(cardOnTable)) when the first time this while loop runs, it will give me [AS | AH], that's what I want. However, when this while loop runs second time, it is supposed to print [A3 XX XX XX AS | AH XX XX XX A5],it only prints [A3 | A5].
this is my class OnTable():
class OnTable:
def __init__(self):
self.__cards = []
self.__faceUp = []
def place(self,player,card,hidden):
if player == 'player2':
self.__cards.append(card)
if hidden == False:
self.__faceUp.append(False)
elif hidden == True:
self.__faceUp.append(True)
elif player == 'player1':
self.__cards.insert(0,card)
if hidden == False:
self.__faceUp.insert(0,False)
elif hidden == True:
self.__faceUp.insert(0,True)
#return self.__cards
def cleanTable(self):
self.__cards.clear()
self.__faceUp.clear()
def __str__(self):
for i in range(len(self.__faceUp)):
if self.__faceUp[i] == True:
self.__cards[i] = 'XX'
list1 = '['
for item in self.__cards:
list1 += (str(item)+' ')
list1 = re.sub(' ', ' ', list1.strip())
half = int(len(list1)//2)
list1 = list1[:half] + ' |' + list1[half:]
return list1 + ']'
I tried to track my code, and I found self.__cards have all variables before second time the player1.dequeue(), then it loses all the previous variables.
Could someone please tell how to fix this problem? Thank you
Is it possible to create a chain of loops or functions that are all nested within another. Using an if statement as an example, I want to chain...
if x == 0:
print(x)
while nesting them like this...
if x == 0:
print(x)
if x == 0:
print(x)
if x == 0:
print(x)
How can I do this using an automatic process?
The code I want to do this to is:
oglist = ["a","b","c"]
combolist = ["lol"]
comboloop = True
combocounter = 3
recursions = {}
for counterx in range(1, combocounter):
recursions["recursion" + str(counterx)] = False
def loopgen(counter2):
if counter2 == 0:
def loop():
global comboloop
global recursions
if len(lists["list0"]) == 0:
comboloop = False
recursions["recursion1"] = True
else:
lists["list1"] = lists["list0"][1:]
recursions["recursion1"] = False
return
elif counter2 != combocounter - 1:
def loop():
global recursions
if len(lists["list" + str(counter2)]) == 0:
lists["list" + str(counter2 - 1)] = lists["list" + str(counter2 - 1)][1:]
recursions["recursion" + str(counter2)] = True
recursions["recursion" + str(counter2 + 1)] = True
else:
lists["list" + str(counter2 + 1)] = lists["list" + str(counter2)][1:]
recursions["recursion" + str(counter2 + 1)] = False
return
else:
def loop():
global counter3
global recursions
if len(lists["list" + str(counter2)]) == 0:
lists["list" + str(counter2 - 1)] = lists["list" + str(counter2 - 1)][1:]
recursions["recursion" + str(counter2)] = True
else:
combolist[counter3] = lists["list0"][0]
for x in range(1, combocounter):
combolist[counter3] = combolist[counter3] + lists["list" + str(x)][0]
combolist.append("lol")
lists["list" + str(counter2)] = lists["list" + str(counter2)][1:]
counter3 += 1
recursions["recursion" + str(counter2)] = False
return
return loop
lists = {}
for x in range(0, combocounter):
lists["list" + str(x)] = ["lol"]
loops = {}
for counter1 in range(0, combocounter):
loops["loop" + str(counter1)] = loopgen(counter1)
lists["list0"] = oglist
counter3 = 0
while comboloop == True:
loops["loop0"]()
while recursions["recursion1"] == False:
loops["loop1"]()
while recursions["recursion2"] == False:
loops["loop2"]()
combolist.remove("lol")
print(combolist)
There are only 3 while loops on the bottom, because combocounter = 3
In future versions of this, combocounter will not be a static number.
While loop :
while x == 0:
print(x)
Recursion :
def f(x):
if x == 0:
print(x)
f(x)
I defined another function which would replicate the creation of a while loop inside another while loop with...
def otherloop(counter4):
while recursions["recursion" + str(counter4)] == False:
loops["loop" + str(counter4)]()
if counter4 != combocounter - 1:
return otherloop(counter4 + 1)
if counter4 != 1:
return otherloop(counter4 - 1)
return
Then of course I replaced
while recursions["recursion1"] == False:
loops["loop1"]()
while recursions["recursion2"] == False:
loops["loop2"]()
with
otherloop(1)