function called in main() funcion isn't updating global variables' values - python

I defined the function 'actualizar_contadores()' and when called inside the main() function, its supossed to update the values of all the variables that were defined at the beginning of the script. First I didnt pass the actual variables as parameters to the function but that resulted in a "local variable referenced before assignment" error. Then I passed the references as parameters and that problem was gone but when I wanted to see the results they werent updated. I tried returning a tuple and assigning it to the variables in order to update their values, but it isnt working either and I get the local variable referenced before assignment error again. What can I do?
cant_motos = cant_autos = cant_camiones = 0
recaudacion_total = recaudacion_efectivo = recaudacion_telepeaje = 0
pasadas_primera_hora = pasadas_segunda_hora = pasadas_tercera_hora = pasadas_cuarta_hora = 0
cont_efectivo = cont_telepeaje = 0
patente_actual = ""
patente_nueva = ""
def actualizar_contadores(vehiculo, forma_de_pago, cant_motos,
cant_autos, cant_camiones,recaudacion_efectivo,
recaudacion_telepeaje,cont_efectivo,cont_telepeaje):
if vehiculo == "Moto":
cant_motos += 1
if forma_de_pago == 1:
recaudacion_efectivo += 20
cont_efectivo += 1
elif forma_de_pago== 2:
recaudacion_telepeaje += 20
cont_telepeaje += 1
elif vehiculo == "Auto":
cant_autos += 1
if forma_de_pago == 1:
recaudacion_efectivo += 40
cont_efectivo += 1
elif forma_de_pago == 2:
recaudacion_telepeaje += 40
cont_telepeaje += 1
elif vehiculo == "Camion":
cant_camiones += 1
if forma_de_pago == 1:
recaudacion_efectivo += 80
cont_efectivo += 1
elif forma_de_pago == 2:
recaudacion_telepeaje += 80
cont_telepeaje += 1
def main():
# menu principal
opcion = pedir_opcion(menu_principal, 4)
while opcion != 4:
while opcion != 3:
if opcion == 1:
carga = pedir_opcion(menu_ingreso_datos, 2)
print("Ingrese la siguiente operacion: ")
opcion = pedir_opcion(menu_principal, 4)
elif opcion == 2:
if carga == 1:
diferencia = 0
tiempo_inicial = time.time()
while diferencia < 32:
contar_pasadas(diferencia, pasadas_primera_hora,
pasadas_segunda_hora,
pasadas_tercera_hora,
pasadas_cuarta_hora)
tipo_vehiculo = pedir_opcion(menu_vehiculos, 3)
if tipo_vehiculo == 1:
vehiculo = "Moto"
elif tipo_vehiculo == 2:
vehiculo = "Auto"
elif tipo_vehiculo == 3:
vehiculo = "Camion"
forma_de_pago = pedir_opcion(menu_forma_de_pago, 2)
if forma_de_pago == 2:
patente = pedir_patente()
patente_nueva = definir_patente_nueva(patente)
actualizar_contadores(vehiculo, forma_de_pago, cant_motos,
cant_autos, cant_camiones, cont_efectivo,
cont_telepeaje, recaudacion_efectivo,
recaudacion_telepeaje)
tiempo_final = time.time()
diferencia = tiempo_final - tiempo_inicial
elif carga == 2:
vehiculos = "Moto", "Auto", "Camion"
formas_de_pago = "Efectivo", "Telepeaje"
diferencia = 0
tiempo_inicial = time.time()
while diferencia < 4:
contar_pasadas(diferencia, pasadas_primera_hora,
pasadas_segunda_hora,
pasadas_tercera_hora,
pasadas_cuarta_hora)
vehiculo = random.choice(vehiculos)
forma_de_pago = random.choice(formas_de_pago)
aviso_pasada = "{}. Pago con {}. Hora de pasada: {}.".format(vehiculo,
forma_de_pago,
str((round(diferencia / 60) + 1)))
if forma_de_pago == "Telepeaje":
patente = generar_patente()
aviso_pasada += "Patente: {}".format(patente)
patente_nueva = definir_patente_nueva(patente)
print(aviso_pasada)
actualizar_contadores(vehiculo, forma_de_pago, cant_motos,
cant_autos, cant_camiones, cont_efectivo,
cont_telepeaje, recaudacion_efectivo,
recaudacion_telepeaje)
tiempo_final = time.time()
diferencia = tiempo_final - tiempo_inicial
time.sleep(random.randint(0,1))
pago_mayor_uso = forma_de_pago_mas_usada(cont_telepeaje, cont_efectivo)
promedio_pasadas_por_hora = round((cant_autos + cant_motos + cant_camiones) / 4, 2)
hora_pico = definir_hora_pico(pasadas_primera_hora,
pasadas_segunda_hora,
pasadas_tercera_hora,
pasadas_cuarta_hora)
recaudacion_total = recaudacion_efectivo + recaudacion_telepeaje
pases_totales = cant_motos + cant_autos + cant_camiones
print("Ingrese la siguiente operacion: ")
opcion = pedir_opcion(menu_principal, 4)
main()```

You should not pass global vars to functions by parameters. Use global keyword.
Here is an example:
x = 10
y = 20
def myFunc():
global x
x = 3
y = 2
myFunc()
print(x, y) # output: 3 20

Related

Python says "UnboundLocalError: local variable 'key' referenced before assignment"

i understand that this error happens when a variable gets mentioned before its defined but "key" is assigned to its value. I started learning python a week ago so i am sorry if my question has a really simple answer.
the code:
from stat import SF_APPEND
import time
import random
keyType = 0
key = 0
deCypherKey = 0
operationType = 0
needToLoop = True
alphabet = "abcdefghijklmnopqrstuvwxyz "
print("ogulSifreleyici v1.0")
time.sleep(0.3)
print("Ipucu: Hem Sifrelemek Hem de Desifrelemek Icin Programi 2 Kere Calistirabilirsiniz")
def cypher():
message = input("Mesajini Gir:\n")
message = message.lower()
unCypheredMessageLength = len(message)
letterOfMessageInQueue = 0
keyStr = str(key)
keyStrInt = 0
whichOrderOfAlphabet = 0
whichLetterOfAlphabet = " "
whichDigitOfKey = 0
orderOfCypheredLetter = 0
cypheredLetter = "a"
cypheredMessageList = []
cypheredStr = ""
while unCypheredMessageLength > 0:
whichLetterOfAlphabet = alphabet[whichOrderOfAlphabet]
if message[letterOfMessageInQueue] == whichLetterOfAlphabet:
print("match")
print(whichOrderOfAlphabet, message[letterOfMessageInQueue], whichLetterOfAlphabet)
keyStrInt = int(keyStr[whichDigitOfKey])
orderOfCypheredLetter = whichOrderOfAlphabet + keyStrInt
if orderOfCypheredLetter > 26:
orderOfCypheredLetter = orderOfCypheredLetter - 26
cypheredLetter = alphabet[orderOfCypheredLetter]
cypheredMessageList.append(cypheredLetter)
unCypheredMessageLength = unCypheredMessageLength - 1
letterOfMessageInQueue = letterOfMessageInQueue + 1
whichOrderOfAlphabet = 0
whichDigitOfKey = whichDigitOfKey + 1
if whichDigitOfKey > 4:
whichDigitOfKey = whichDigitOfKey - 5
if len(cypheredMessageList) == len(message):
cypheredStr = "".join(cypheredMessageList)
print("Sifrelenmis Mesajiniz:\n" + cypheredStr)
time.sleep(1)
lastUserAnswer = input("1-Sifrele(Ayni Anahtar) 2-Sifrele(Farkli Anahtar)\n")
if lastUserAnswer == "1":
cypher()
if lastUserAnswer == "2":
key = input("Anahtar Giriniz(5 Haneli Sayi):\n")
while len(str(key)) != 5:
key = input("Lutfen Bes Haneli Bir Sayi Giriniz\n")
if len(str(key)) == 5:
cypher()
cypher()
else:
whichOrderOfAlphabet = whichOrderOfAlphabet + 1
def deCypher():
deCypherMessage = input("Sifreli Mesajinizi Giriniz:\n")
operationType = input("1-Sifrele 2-DeSifrele\n")
while needToLoop == True:
if operationType == "1":
keyType = input("1-Anahtar gir(5 haneli sayi) 2-Rastgele Anahtar\n")
if keyType == "1":
key = input("Anahtar Giriniz:\n")
while len(str(key)) != 5:
key = input("Lutfen Bes Haneli Bir Sayi Giriniz\n")
if len(str(key)) == 5:
needToLoop = False
cypher()
needToLoop = False
cypher()
if keyType == "2":
key = int(random.uniform(10000, 100000))
print("Anahtariniz: " + str(key))
cypher()
needToLoop = False
else:
print("Lutfen Seceneklerden Birini Seciniz")
needToLoop = True
if operationType == "2":
deCypherKey = input("Anahtarinizi Giriniz:\n")
while len(str(deCypherKey)) != 5:
key = input("Lutfen Bes Haneli Bir Sayi Giriniz\n")
if len(str(key)) == 5:
needToLoop = False
deCypher()
needToLoop = False
deCypher()
else:
print("Lutfen Seceneklerden Birini Seciniz")
needToLoop = True
this is not exactly the reason you wrote, the fact is that the function cannot see variables that are outside the function. In order for the function to see them, you need to pass the variable as an argument to the function. That is, you need to change line 86 like this: cypher(key). But as you can see, this will give an error, because your function initially does not accept any arguments, in order to fix this we need to add the key argument in line 16 like this: def cypher(key):. There is the site where you can read more about it https://levelup.gitconnected.com/5-types-of-arguments-in-python-function-definition-e0e2a2cafd29

Code returns TypeError and I'm not sure why

The code below returns 'TypeError: 'int' object is not subscriptable' when move_pas is called. The thnig is, is that the code affecting this is also in move_ag, but when I call that there is no error and I cant figure out why that is. I'm running this in python3.9.2 in vscode if that matters. Thanks in advance. (sorry for bad english)
import random
char_list = []
stance_list = []
spot_list = []
status_list = []
amount_list = []
def remake_name_list():
global name_list
name_list = ["Josh", "Jeff", "Lisa", "Addie", "Jack", "John", "Zac", "Evan", "Brayden", "Seb", "Sab", "Nick", "Dom", "Rex", "James", "Robert",
"John", "Michael", "William", "David", "Richard", "Joseph", "Thomas", "Charles", "Christopher", "Daniel", "Matthew", "Anthoney", "Mark"]
remake_name_list()
def gen(amount):
for i in range(0, amount):
rand = random.choice(name_list)
char_list.append(rand)
name_list.remove(rand)
rand = random.randint(0, 8)
if rand == 8:
stance_list.append("aggressive")
elif rand != 8:
stance_list.append("passive")
rand = random.randint(0, amount*2)
spot_list.append(rand)
amount_list.append(2)
amount_list.append(2)
rand = random.randint(1, 2)
if rand == 1:
amount_list.append(2)
elif rand == 2:
pass
for i in range(0, max(spot_list)):
if spot_list.count(i) >= 3:
amount_list.clear()
gen(amount)
def move_ag(amount_list, stance_list):
if 'aggressive' in stance_list:
for i in range(0, len(char_list)):
if stance_list[i] == "aggressive":
am = spot_list.count(spot_list[i])
if am == 1:
stance_list[i] = 2
amount_list[spot_list[i]] -= 2
elif am == 2:
stance_list[i] = 1.5
amount_list[spot_list[i]] -= 1.5
def move_pas(amount_list, stance_list):
if 'passive' in stance_list:
for i in range(0, len(char_list)):
if stance_list[i] == "passive":
am = spot_list.count(spot_list[i])
if am == 1:
stance_list[i] = 2
amount_list[spot_list[i]] -= 2
elif am == 2:
if amount_list[i] == 1:
stance_list = 1
amount_list[spot_list[i]] -= 1
if amount_list[i] == 2:
stance_list = 1
amount_list[spot_list[i]] -= 1
if amount_list[i] == 0.5:
stance_list = 0.5
amount_list[spot_list[i]] -= 0.5
amount = 10
gen(amount)
move_ag(amount_list, stance_list)
move_pas(amount_list, stance_list)
print(stance_list)
print(amount_list)
The way that you have it:
def move_pas(amount_list, stance_list):
if 'passive' in stance_list:
for i in range(0, len(char_list)):
if stance_list[i] == "passive":
am = spot_list.count(spot_list[i])
if am == 1:
stance_list[i] = 2
amount_list[spot_list[i]] -= 2
elif am == 2:
if amount_list[i] == 1:
stance_list = 1 #------------------------- here
amount_list[spot_list[i]] -= 1
if amount_list[i] == 2:
stance_list = 1 #------------------------- here
amount_list[spot_list[i]] -= 1
if amount_list[i] == 0.5:
stance_list = 0.5 #----------------------- here
amount_list[spot_list[i]] -= 0.5
If any of the if statements is met the stance_list is changed to an integer (1 or 0.5). So the next time the loop goes on it will meet this statement if stance_list[i] == "passive" and will tell you that a integer cannot be subscripted (Which is to be expected).
I assume what you want to do is to change the i-th element of stance_list to that number. Like this:
def move_pas(amount_list, stance_list):
if 'passive' in stance_list:
for i in range(0, len(char_list)):
print(stance_list)
if stance_list[i] == "passive":
am = spot_list.count(spot_list[i])
if am == 1:
stance_list[i] = 2
amount_list[spot_list[i]] -= 2
elif am == 2:
if amount_list[i] == 1:
stance_list[i] = 1 #------------------------- here
amount_list[spot_list[i]] -= 1
if amount_list[i] == 2:
stance_list[i] = 1 #------------------------- here
amount_list[spot_list[i]] -= 1
if amount_list[i] == 0.5:
stance_list[i] = 0.5 #----------------------- here
amount_list[spot_list[i]] -= 0.5

discordpy, bot crashs after simulate a lottery

I made this simulation as a discordpy cog, but the bot goes offline and the console is open and don't do anything if I write or quit it...
At an amount of 15000 the bot crashes, what can I do, why it crashs?
There are discord emojies, which are selected randomly and there are different chances with the numbers etc. I hope somebody can help me here!
#bot.command()
async def simulate(self, ctx, amount):
wnitro = 0
wkey = 0
wgold = 0
wred = 0
wblue = 0
wgreen = 0
wgrey = 0
for zaehler in range(1, int(amount)):
drehungen = randint(5, 20)
gone = randint(1, 1000)
gtwo = randint(1, 1000)
gthree = randint(1, 1000)
gfour = randint(1, 1000)
gfive = randint(1, 1000)
gsix = randint(1, 1000)
gseven = randint(1, 1000)
geight = randint(1, 1000)
gnine = randint(1, 1000)
randomitem = [gone, gtwo, gthree, gfour, gfive, gsix, gseven, geight, gnine]
slots = []
for item in range(len(randomitem)):
if randomitem[item] >= 950:
slots.append("<a:classic:802844186026049546>")
elif randomitem[item] >= 850:
slots.append("<a:geld:770235576539676682>")
elif randomitem[item] >= 800:
slots.append("<a:goldendia:802976550995755019>")
elif randomitem[item] >= 650:
slots.append("<a:darkbluedia:802976435500875836>")
elif randomitem[item] >= 500:
slots.append("<a:reddia:802873281841463296>")
elif randomitem[item] >= 300:
slots.append("<a:greendia:802875898353156138>")
else:
slots.append("<a:greydia:802977070627553311>")
cdrehung = 1
nitroextra = randint(1, 100)
keyextra = randint(1, 10)
coinsextra = randint(1, 5)
coins2extra = randint(1, 2)
i = 0
while i < drehungen:
if cdrehung == 0:
gewinn = slots[4]
elif cdrehung == 1:
gewinn = slots[5]
elif cdrehung == 2:
gewinn = slots[6]
elif cdrehung == 3:
gewinn = slots[7]
elif cdrehung == 4:
gewinn = slots[8]
elif cdrehung == 5:
gewinn = slots[0]
elif cdrehung == 6:
gewinn = slots[1]
elif cdrehung == 7:
gewinn = slots[2]
elif cdrehung == 8:
gewinn = slots[3]
cdrehung -= 9
cdrehung += 1
i += 1
if i == drehungen:
if gewinn == "<a:classic:802844186026049546>":
if nitroextra == 1:
wnitro += 1
else:
drehungen += 1
elif gewinn == "<a:geld:770235576539676682>":
if keyextra == 1:
wkey += 1
else:
drehungen += 1
elif gewinn == "<a:goldendia:802976550995755019>":
if coinsextra == 1:
wgold += 1
else:
drehungen += 1
elif gewinn == "<a:darkbluedia:802976435500875836>":
if coins2extra == 1:
wblue += 1
else:
drehungen += 1
elif gewinn == "<a:reddia:802873281841463296>":
wred += 1
elif gewinn == "<a:greendia:802875898353156138>":
wgreen += 1
elif gewinn == "<a:greydia:802977070627553311>":
wgrey += 1
await ctx.send(f"There are the results out of `{str(amount)}x` spins: {str(wnitro)}x Nitro, {str(wkey)} Key, {str(wgold)} <a:goldendia:802976550995755019>, {str(wblue)} <a:darkbluedia:802976435500875836>, {str(wred)} <a:reddia:802873281841463296>, {str(wgreen)}<a:greendia:802875898353156138>, {str(wgrey)}<a:greydia:802977070627553311>")
thanks to everyone who helps c:
Update: I take it back, theoretically your slots could all be the same thing, or a combination of things that cause drehungen to always implement. You really need to reconsider the logic on your loop.
Update: actually that is false, you do update cdrehung which updates gewinn... this is pretty convoluted, but it does seems like it should have to end at some point. That being said this loop is a bit complicated, I would consider some debug messages for all these different variables to figure out what is going on.
Just looking at it, inside your while loop the state of gewinn doesn't change, or any of the other items (wnitro wkey wgold wblue)... sooo if that is the case it could mean that drehungen is always being incremented... which means i == drehungen is always true... which means an infinite loop.

Issues with final output

Expected Output :
I was working on the functions to get the code for elementary cellular automaton. I got all the outputs correct but I could not get my desired output printed.
def main():
N= int(input("Enter number of steps,N:"))
C= int(input("Enter number of cells,C:"))
i_list=list(map(int,input("Enter the indices of occupied cells (space-separated):").split()))
cell= [0]*C
for i in i_list:
cell[int(i)] = 1
displayCells(cell)
for step in range(N):
newCells = updateCells(cell)
displayCells(newCells)
cells = []
cells += newCells # concatenates new state to new list
def displayCells(Cells):
for cell in Cells:
if cell == 1:
print("#", end='')
def updateCells(cells):
nc = [] # makes a new empty list
nc += cells # copy current state into new list
for a in range(1, len(nc)-1):
if nc[a-1] == 1 and nc[a] == 1 and nc[a+1] == 1:
nc[a] = 0
elif nc[a-1] == 1 and nc[a] == 1 and nc[a+1] == 0:
nc[a] = 1
elif nc[a-1] == 1 and nc[a] == 0 and nc[a+1] == 1:
nc[a] = 1
elif nc[a-1] == 1 and nc[a] == 0 and nc[a+1] == 0:
nc[a] = 0
elif nc[a-1] == 0 and nc[a] == 1 and nc[a+1] == 1:
nc[a] = 1
elif nc[a-1] == 0 and nc[a] == 1 and nc[a+1] == 0:
nc[a] = 1
elif nc[a-1] == 0 and nc[a] == 0 and nc[a+1] == 1:
nc[a] = 1
else:
nc[a] = 0
return nc
main()
I expect the output to be the loop that follows the rule of updateCells function and draw the # whenever the program sees 1.

list index out of range python 3.6

List index out of range error occurs at the line
if large_l[lg_index] ==small_l[sl_index]:
Here the code works fine when the values of following are,
correctword = "syria"
incorrectword = "siria"
but when assigning value as follows,
correctword = "syria"
incorrectword = "syri"
the above mentioned error has occurred. If could, tell me a way to get rid from this error.
Thank you
correctword = "syria"
incorrectword = "syri"
l1 = list(correctword)
l2 = list(incorrectword)
if len(l1) < len(l2):
large_l= l2
small_l = l1
else:
large_l =l1
small_l = l2
missmatchstart = False
lg_mismatch_start_index = 0
sl_mismatch_start_index = 0
lg_index = 0
sl_index = 0
del_count=0
add_count = 0
sub_count = 0
for l1_item in large_l:
for l2_item in small_l:
if large_l[lg_index] ==small_l[sl_index]:
if missmatchstart == False:
sl_mismatch_start_index = sl_index
lg_mismatch_start_index = lg_index
print(large_l[lg_index])
print("addition ")
print(add_count)
print("deletion ")
print(del_count)
print("substitution ")
print(sub_count)
if lg_index-lg_mismatch_start_index == sl_index-sl_mismatch_start_index:
sub_count += sl_index-sl_mismatch_start_index
lg_index+= 1
sl_index+= 1
elif lg_index-lg_mismatch_start_index > sl_index-sl_mismatch_start_index:
sub_count += sl_index-sl_mismatch_start_index
del_count += ((lg_index-lg_mismatch_start_index) - (sl_index-sl_mismatch_start_index))
lg_index+= 1
sl_index+= 1
elif lg_index-lg_mismatch_start_index < sl_index-sl_mismatch_start_index:
sub_count += lg_index-lg_mismatch_start_index
add_count += ((sl_index-sl_mismatch_start_index) - (lg_index-lg_mismatch_start_index))
lg_index+= 1
sl_index+= 1
missmatchstart = False
break
else:
print(large_l[lg_index])
if(missmatchstart == False):
lg_mismatch_start_index = lg_index
sl_mismatch_start_index = sl_index
print("missmatch large")
print(lg_mismatch_start_index)
print("missmatch small")
print(sl_mismatch_start_index)
missmatchstart =True
sl_index+=1
else:
sl_index+=1
if sl_index== len(small_l)-1:
lg_index +=1
sl_index = sl_mismatch_start_index
#del_count +=1
break
# elif lg_index == sl_index == len(small_l):
# sub_count +=
if lg_index >=len(large_l)-1:
del_count += len(large_l)- lg_index
#elif missmatchstart ==True:
print(add_count)
print(del_count)
print(sub_count)
You probably want to replace the condition on line 24:
if large_l[lg_index] ==small_l[sl_index]:
with:
if l1_item == l2_item:
There might be other bugs there, you should make your code more modular by splitting it into functions (in a reasonable matter) - it will be easier to maintain and debug!

Categories

Resources