Looping a value into a list (changing value) - python

Im trying to produce a list with 360 values, determined by the formula provided. I keep getting a syntax error on the "Elist" portion highlighted. This is using python 3.4.
SRate = [5,5,5]
Bots = 120
NQueue = 3
TSim = 100
Exp = 2
DDistance = 1
Lambda = 40 # 120/3 = 40
import random
AvgSRate = 5
def Initilization(AvgSRate,Lambda,Exp,x):
Elist = []
for a in range(1,361):
x = (Lambda/(AvgSRate**Exp))*(1+(1/10)*(2*(random.random()) - 1)
Elist.append(x) # <--- Error is in this line.
return Expectation_list

You are missing a closing paren:
x = (Lambda/(AvgSRate**Exp))*(1+(1/10)*(2*(random.random()) - 1) <-
Just add a closing paren and your error will be gone:
x = (Lambda/(AvgSRate**Exp))*(1+(1/10)*(2*(random.random()) - 1))
Make sure Expectation_list is also defined somewhere or more likely you should be returning Elist.
You are reassigning x also so you don't actually ever use the parameter x passed in so remove it if you are not using it, if you just want to return Elist then you can return a list comp:
def Initilization(AvgSRate, Lambda, Exp):
return [(Lambda / (AvgSRate ** Exp)) * (1 + (1 / 10) * (2 * (random.random()) - 1))
for a in range(1, 361)]

Related

I don't know why it's an empty list? max()

# Plot the highest score in history
def draw_best(background):
ip = 'redis-16784.c89.us-east-1-3.ec2.cloud.redislabs.com'
r = redis.Redis(host=ip, password=1206, port=16784, db=0, decode_responses = True)
scores = [eval(i) for i in list(r.hgetall('2048').values())]
best_scores = max(scores)
scoreSurf = BasicFont01.render('Top score:{}'.format(best_scores), True, (0, 0, 0))
scoreRect = scoreSurf.get_rect()
scoreRect.width = math.floor((rate - 0.15) / 2 * screen.get_width())
scoreRect.height = math.floor((1 - rate2) / 3 * 2 * screen.get_height())
scoreRect.topright = (math.floor(0.9 * screen.get_width()), math.floor(0.05 * screen.get_height()))
py.draw.rect(screen, background, [scoreRect.topleft[0], scoreRect.topleft[1], scoreRect.width, scoreRect.height], 0)
screen.blit(scoreSurf, scoreRect)
I think the problem is in these two lines:
scores = [eval(i) for i in list(r.hgetall('2048').values())]
best_scores = max(scores)
The error it showed me was:
ValueError: max() arg is an empty sequence
Obviously, it seems like list(r.hgetall('2048').values()) is a blank sequence/list/array.
Check if it is really empty by defining a variable with the value list(r.hgetall('2048').values()) and then print it out to check.
There is a default keyword that may be helpful. It will return a value if the list is empty. It works as follows:
my_list = []
result = max(my_list, default=None)
print(result) # It will print "None"
You already think that the problem exists in those two lines, then what better way to solve this is to check if it is really in those two lines!

Optimizing mathematical formula implementation with concatenations of summations

I'm trying to implement this following formula in Python. It's basically a long concatenation os summations, where an additional summation is added each time a new 'element' is needed. To simply explain the formula's structure, here's how this formula goes in order from 2 to 5 elements:
2 elements
3 elements
4 elements
5 elements
By the way, here's the g function shown in the formulas:
g function
Now, I foolishly tried coding this formula with my extremely barebones python programming skills. The initial goal was to try this with 15 elements, but given that it contained a lot of nested for loops and factorials, I quickly noticed that I could not really obtain a result from that.
At the end I ended up with this monstrous code, that would finish just after the heat death of the universe:
from ast import Str
import math
pNuevos = [0,2,2,2,2,1,1,1,2,2,2,1,2,2,1,1]
pTotales = [0,10,10,7,8,7,7,7,7,7,10,7,8,7,8,8]
def PTirada (personajes):
tirada = 0.05/personajes
return tirada
def Ppers1 (personajes, intentos):
p1pers = ((math.factorial(intentos-1)) / ((math.factorial(4))*(math.factorial(intentos-5)))) * (PTirada(personajes)**5) * ((1-PTirada(personajes))**(intentos-5))
return p1pers
def Ppers2 (personajes, intentos):
p2pers = 0
for i in range(10,intentos+1):
p2pers = p2pers + ( (math.factorial(intentos-1)) / ((math.factorial(4))*(math.factorial(i-5))*(math.factorial(intentos-i))) ) * (PTirada(personajes)**i) * ((1 - 2*(PTirada(personajes))) **(intentos-i))
p2pers = 2*p2pers
return p2pers
def Activate (z) :
probability1 = 0
probability2 = 0
probability3 = 0
probability4 = 0
probability5 = 0
probability6 = 0
probability7 = 0
probability8 = 0
probability9 = 0
probability10 = 0
probability11 = 0
probability12 = 0
probability13 = 0
probability14 = 0
for i in range (5*pNuevos[1], z-5*pNuevos[2]+1):
for j in range (5*pNuevos[2], z-i-5*pNuevos[3]+1):
for k in range (5*pNuevos[3], z-j-i-5*pNuevos[4]+1):
for l in range (5*pNuevos[4], z-k-j-i-5*pNuevos[5]+1):
for m in range (5*pNuevos[5], z-l-k-j-i-5*pNuevos[6]+1):
for n in range (5*pNuevos[6], z-m-l-k-j-i-5*pNuevos[7]+1):
for o in range (5*pNuevos[7], z-n-m-l-k-j-i-5*pNuevos[8]+1):
for p in range (5*pNuevos[8], z-o-n-m-l-k-j-i-5*pNuevos[9]+1):
for q in range (5*pNuevos[9], z-p-o-n-m-l-k-j-i-5*pNuevos[10]+1):
for r in range (5*pNuevos[10], z-q-p-o-n-m-l-k-j-i-5*pNuevos[11]+1):
for s in range (5*pNuevos[11], z-r-q-p-o-n-m-l-k-j-i-5*pNuevos[12]+1):
for t in range (5*pNuevos[12], z-s-r-q-p-o-n-m-l-k-j-i-5*pNuevos[13]+1):
for u in range (5*pNuevos[13], z-t-s-r-q-p-o-n-m-l-k-j-i-5*pNuevos[14]+1):
for v in range (5*pNuevos[14], z-u-t-s-r-q-p-o-n-m-l-k-j-i-5*pNuevos[15]+1):
probability14 = probability14 + eval("Ppers"+str(pNuevos[14])+"("+str(pTotales[14])+","+str(v)+")") * eval("Ppers"+str(pNuevos[15])+"("+str(pTotales[15])+","+str(z-v-u-t-s-r-q-p-o-n-m-l-k-j-i)+")")
probability13 = probability13 + eval("Ppers"+str(pNuevos[13])+"("+str(pTotales[13])+","+str(u)+")") * probability14
probability12 = probability12 + eval("Ppers"+str(pNuevos[12])+"("+str(pTotales[12])+","+str(t)+")") * probability13
probability11 = probability11 + eval("Ppers"+str(pNuevos[11])+"("+str(pTotales[11])+","+str(s)+")") * probability12
probability10 = probability10 + eval("Ppers"+str(pNuevos[10])+"("+str(pTotales[10])+","+str(r)+")") * probability11
probability9 = probability9 + eval("Ppers"+str(pNuevos[9])+"("+str(pTotales[9])+","+str(q)+")") * probability10
probability8 = probability8 + eval("Ppers"+str(pNuevos[8])+"("+str(pTotales[8])+","+str(p)+")") * probability9
probability7 = probability7 + eval("Ppers"+str(pNuevos[7])+"("+str(pTotales[7])+","+str(o)+")") * probability8
probability6 = probability6 + eval("Ppers"+str(pNuevos[6])+"("+str(pTotales[6])+","+str(n)+")") * probability7
probability5 = probability5 + eval("Ppers"+str(pNuevos[5])+"("+str(pTotales[5])+","+str(m)+")") * probability6
probability4 = probability4 + eval("Ppers"+str(pNuevos[4])+"("+str(pTotales[4])+","+str(l)+")") * probability5
probability3 += eval("Ppers"+str(pNuevos[3]) + "("+str(pTotales[3])+","+str(k)+")") * probability4
probability2 += eval("Ppers"+str(pNuevos[2]) + "("+str(pTotales[2])+","+str(j)+")") * probability3
probability1 += eval("Ppers"+str(pNuevos[1]) + "("+str(pTotales[1])+","+str(i)+")") * probability2
return probability1
print (str(Activate(700)))
Edit: Alright I think it would be helpful to explain a couple things:
-First of all, I was trying to find ways the code could run faster, as I'm aware the nested for loops are a performance hog. I was also hoping there would be a way to optimize so many factorial operations.
-Also, the P(A) function described in the g function represents the probability of an event happening, which is already in the code, in the first function from the top.
There's also the function f in the formula, which is just a simplification of the function g for specific cases.
The function f is the second function in the code, whereas g is the third function in the code.
I will try to find a way to simplify the multiple summations, and thanks for the tip of not using eval()!
I'm sorry again for not specifying the question more, and for that mess of code also.
I would expect to break it down with something like this:
def main():
A = 0.5
m = 10
result = g(A, m)
return
def sigma(k, m):
''' function to deal with the sum loop'''
for k in range(10, m+1):
# the bits in the formula
pass
return
def g(A, m):
''' function to deal with g '''
k=10
return 2 * sigma(k,m)
if __name__=='__main__':
''' This is executed when run from the command line '''
main()
Or alternatively to do similar with classes.
I expect you also need a function for p(A) and one for factorials.

How to get a value of function corresponding to certain coordinates without actually replacing the values in code?

I have an array of values x and y and have a function f(x,y). I want to get the value of f(x1,y1) corresponding to (x1,y1). How can we get it?
khmax = np.arange(0,0.5,0.001)
Ncmax = np.arange(0,0.5,0.001)
[X, Y] = np.meshgrid(Ncmax,khmax)
sum_real = 0
sum_imag = 0
for l in range (0,N): # C_jl * P_lj
sum_imag = sum_imag + (matrix_C[j_node-1][l])*(np.sin(Y*(x_j(l+1)-x_j(j_node)) / hmax))
sum_real = sum_real + (matrix_C[j_node-1][l])*(np.cos(Y*(x_j(l+1)-x_j(j_node)) / hmax))
Aj_real = (X * sum_real)
Aj_imag = (X * sum_imag)
G_imag = -Aj_imag + (2 * (Aj_real) * (Aj_imag)) / 2 - ((3 * ((Aj_real)**2) * (Aj_imag)) -((Aj_imag)**3)) + ((4*(Aj_real)*(Aj_imag))*((Aj_real)**2 - (Aj_imag)**2))/24
G_real = 1 - (Aj_real) + (((Aj_real)**2 - (Aj_imag)**2)/2) - ((((Aj_real)**3 - 3*(Aj_real)*((Aj_imag)**2)))/6) + ((((((Aj_real)**2 - (Aj_imag)**2 )**2- 4*((Aj_real)**2)*((Aj_imag)**2))))/ 24)
mod_G = (((G_real)**2) + ((G_imag)**2))**(0.5)
In this code mod_G is a function of (khmax, Ncmax). I want to get the value of mod_G corresponding to (khmax,Ncmax) suppose(0.1,0.1). I don't want to put the value of (khmax, Ncmax) into the function directly(i.e not replacing khmax with 0.1 and Ncmax with 0.1). How can I get mod_G without doing this?
Could you try defining it as an actual python function, i.e. using the def keyword and then calling it with the two parameters? This way you could just easily call it as mod_G(0.1,0.1) without changing anything else.

How can I change my output in this scenario? [duplicate]

This question already has an answer here:
Unexpected None in python print statement
(1 answer)
Closed 1 year ago.
So I made this code and its great, but once again the problem is that my output has a 'none' under it. How do I change it. btw, my code is this..
def up_and_down(k):
return (*range(1, k), *range(k, 0, -1))
def diamond(k):
pad = '#'
fill = '*'
w = (2 * k) - 1
for i in up_and_down(k):
print(f'{fill * len(up_and_down(i)):{pad}^{w}}')
print(diamond(k))
def triangle(k):
w = (2 * k) - 1
pad = '#'
fill = '*'
for i in range(1, k+1):
print(f'{fill * len(up_and_down(i)):{pad}^{w}}')
print(triangle(k))
and my output prints out...
######*######
#####***#####
####*****####
###*******###
##*********##
#***********#
*************
#***********#
##*********##
###*******###
####*****####
#####***#####
######*######
None
######*######
#####***#####
####*****####
###*******###
##*********##
#***********#
*************
None
How can I make sure that the image is RETURNED and 'none' doesn't appear under when I use the PRINT statement either??
Btw, I need to use print because its a requirement placed by my professor.
Based on what you described (i.e., need to use print), you need to return a string, and then print that string outside the function.
def up_and_down(k):
return (*range(1, k), *range(k, 0, -1))
def diamond(k):
pad = '#'
fill = '*'
w = (2 * k) - 1
return '\n'.join(f'{fill * len(up_and_down(i)):{pad}^{w}}' for i in up_and_down(k))
def triangle(k):
w = (2 * k) - 1
pad = '#'
fill = '*'
return '\n'.join(f'{fill * len(up_and_down(i)):{pad}^{w}}' for i in range(1, k+1))
k = 10
print(diamond(k))
print(triangle(k))
Without an explicit return, a function returns None. So in your original code, print(diamond(k)) would be like print(None), which is the reason why you see None.
If you can't use \n for a reason I can't understand (but apparently due to your instructor's preference), use the following returns instead (to return a generator of lines, instead of one single multi-line string):
return (f'{fill * len(up_and_down(i)):{pad}^{w}}' for i in up_and_down(k))
return (f'{fill * len(up_and_down(i)):{pad}^{w}}' for i in range(1, k+1))
respectively, and then print the output using
for line in diamond(k):
print(line)
for line in triangle(k):
print(line)

How to structure python programs? Tried making it more structured, now runs 13 times slower

Im very new to programming, I wrote a simple program for a school project and wanted to make the code "prettier" by not just having the program be one giant function but instead be made up of multiple smaller functions with a singe purpose. I seemed to have messed up royally since the program now runs 13 times slower. How should I structured the program to make it run faster and just in general make programs easier to write, read and edit?
Here are the two programs:
First program (for reference values runs in ≈0:20):
import numpy as np
import matplotlib.pyplot as plt
def graf(a,b,H,p):
GM = 39.5216489684
x_0 = a + np.sqrt(a**2 - b**2)
v_0 = np.sqrt(GM*(2/x_0 - 1/a))
konstant_period = np.sqrt(a**3)*H
h = 1/H
'''starting position given by an elliptic orbit '''
stor_x_lista = [x_0]
stor_y_lista = [0]
hastighet_x = [0]
hastighet_y = [v_0]
liten_x_lista = []
liten_y_lista = []
''' a loop that approximates the points of the orbit'''
t = 0
tid_lista = []
n = 0
while n < konstant_period:
hastighet_x.append(hastighet_x[n] - h*GM* stor_x_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
stor_x_lista.append(stor_x_lista[n] + h*hastighet_x[n])
hastighet_y.append(hastighet_y[n] - h*GM*stor_y_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
stor_y_lista.append(stor_y_lista[n] + h*hastighet_y[n])
'''smaller list of points to run faster'''
if n % p == 0:
liten_x_lista.append(stor_x_lista[n])
liten_y_lista.append(stor_y_lista[n])
tid_lista.append(t)
n += 1
t += h
''' function that finds the angle'''
vinkel = []
siffra = 0
while siffra < len(liten_x_lista):
if liten_y_lista[siffra ] >= 0:
vinkel.append( np.arccos( liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2)))
siffra += 1
elif liten_y_lista[siffra] < 0 :
vinkel.append( np.pi + np.arccos( -liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2) ))
siffra += 1
'''get rid of line to find periodic function'''
mod_lista = []
modn = 0
while modn < len(vinkel):
mod_lista.append(vinkel[modn] - (2*np.pi*tid_lista[modn])/np.sqrt(a**3))
modn += 1
'''make all inputs have period 1'''
squeeze_tid = []
squeezen = 0
while squeezen < len(tid_lista):
squeeze_tid.append(tid_lista[squeezen]/np.sqrt(a**3))
squeezen += 1
del mod_lista[-1:]
del tid_lista[-1:]
del squeeze_tid[-1:]
plt.plot(squeeze_tid,mod_lista)
plt.title('p(t) där a = ' + str(a) + ' och b = ' + str(b))
plt.show
Second more split up program (for reference values runs in ≈4:20):
import numpy as np
import matplotlib.pyplot as plt
'''function that generates the points of the orbit'''
def punkt(a,b,H,p):
GM = 39.5216489684
x_0 = a + np.sqrt(a**2 - b**2)
v_0 = np.sqrt(GM*(2/x_0 - 1/a))
konstant_period = np.sqrt(a**3)*H
h = 1/H
'''starting position given by an elliptic orbit '''
stor_x_lista = [x_0]
stor_y_lista = [0]
hastighet_x = [0]
hastighet_y = [v_0]
liten_x_lista = []
liten_y_lista = []
''' a loop that approximates the points of the orbit'''
t = 0
tid_lista = []
n = 0
while n < konstant_period:
hastighet_x.append(hastighet_x[n] - h*GM* stor_x_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
stor_x_lista.append(stor_x_lista[n] + h*hastighet_x[n])
hastighet_y.append(hastighet_y[n] - h*GM*stor_y_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
stor_y_lista.append(stor_y_lista[n] + h*hastighet_y[n])
'''smaller list of points to run faster'''
if n % p == 0:
liten_x_lista.append(stor_x_lista[n])
liten_y_lista.append(stor_y_lista[n])
tid_lista.append(t)
n += 1
t += h
return (liten_x_lista,liten_y_lista,tid_lista)
''' function that finds the angle'''
def vinkel(a,b,H,p):
'''import lists'''
liten_x_lista = punkt(a,b,H,p)[0]
liten_y_lista = punkt(a,b,H,p)[1]
tid_lista = punkt(a,b,H,p)[2]
'''find the angle'''
vinkel_lista = []
siffra = 0
while siffra < len(liten_x_lista):
if liten_y_lista[siffra ] >= 0:
vinkel_lista.append( np.arccos( liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2)))
siffra += 1
elif liten_y_lista[siffra] < 0 :
vinkel_lista.append( np.pi + np.arccos( -liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2) ))
siffra += 1
return (vinkel_lista, tid_lista)
def periodisk(a,b,H,p):
'''import lists'''
tid_lista = vinkel(a,b,H,p)[1]
vinkel_lista = vinkel(a,b,H,p)[0]
'''get rid of linear line to find p(t)'''
mod_lista = []
modn = 0
while modn < len(vinkel_lista):
mod_lista.append((vinkel_lista[modn] - (2*np.pi*tid_lista[modn])/np.sqrt(a**3)))
modn += 1
'''make all inputs have period 1'''
squeeze_tid = []
squeezen = 0
while squeezen < len(tid_lista):
squeeze_tid.append(tid_lista[squeezen]/np.sqrt(a**3))
squeezen += 1
del mod_lista[-1:]
del tid_lista[-1:]
del squeeze_tid[-1:]
return (squeeze_tid,mod_lista)
'''fixa 3d-punkt av p(a,b) a är konstant b varierar??? '''
def hitta_amp(a):
x_b = []
y_b = []
n_b = 0.1
while n_b <= a:
x_b.append(n_b)
y_b.append(punkt(a,n_b,10**5,10**3))
return 0
def graf(a,b,H,p):
plt.plot(periodisk(a,b,H,p)[0],periodisk(a,b,H,p)[1])
plt.show
I would assume the thing that is going wrong is that the program is running the same, slow code multiple times instead of just running it once and then accessing the data. Is the problem that everything is done locally and nothing is stored globally or is it something else?
Just as a heads up, the only thing I know about programming is basic syntax, I have no clue how to actually write and run programs. I ran all the code in spyder if that affects anything.
plt.plot(periodisk(a,b,H,p)[0],periodisk(a,b,H,p)[1])
This code runs periodisk twice with the same arguments, thus at this point we know we run things at least 2 times slower.
You should do some_var = periodisk(a,b,H,p) and then some_var[0], some_var[1]. Or just use unpacking:
plt.plot(*periodisk(a,b,H,p))
tid_lista = vinkel(a,b,H,p)[1]
vinkel_lista = vinkel(a,b,H,p)[0]
Again doing the same thing twice (total: 4*time of (current) vinkel function). Again, smart assignment to fix this:
vinkel_lista, tid_lista = vinkel(a,b,H,p)
liten_x_lista = punkt(a,b,H,p)[0]
liten_y_lista = punkt(a,b,H,p)[1]
tid_lista = punkt(a,b,H,p)[2]
And now you repeat yourself thrice. (total: 12 * time of current punkt function)
liten_x_lista, liten_y_lista, tid_lista = punkt(a,b,H,p)
punkt function is like in original, so we arrived as total being 12 times slower - which quite matches your time estimations. :)
You are calling the functions once per returned list, you should only call them once.
When a method returns multiple variables, (e.g. punkt):
def punkt(a,b,H,p):
# Here is all your code
return (liten_x_lista,liten_y_lista,tid_lista)
You must be careful to only call the function once:
result = punkt(a,b,H,p)
liten_x_lista = result[0]
liten_y_lista = result[1]
tid_lista = result[2]
# As opposed to:
liten_x_lista = punkt(a,b,H,p)[0] # 1st call, ignoring results 2 and 3
liten_y_lista = punkt(a,b,H,p)[1] # 2nd call, ignoring results 1 and 3
tid_lista = punkt(a,b,H,p)[2] # 3rd call, ignoring results 1 and 2
Note: I would personally not return a list, but use python's unpacking:
def punkt(a,b,H,p):
# Here is all your code
return liten_x_lista, liten_y_lista, tid_lista
And you'd access it:
liten_x_lista, liten_y_lista, tid_lista = punkt(a,b,H,p)

Categories