I went through the other post on this same topic.
UnboundLocalError: local variable … referenced before assignment
But in my case, I have never mentioned local variables in another part of the code. Pycharm is indicating the problem is following function specifically "shell_cost". Which Is a part of the module 'economic' I call in a separate script. It says
column_investment_cost = 4.74 * (shell_cost + (stages - 2) * sieve_tray_cost)
UnboundLocalError: local variable 'shell_cost' referenced before assignment
The function is
def column(tray_area, height, stages):
tray_diameter = (tray_area * 4 / 3.1415926)**0.5
if tray_diameter <= 0.5:
shell_cost = 15.401 * height**2 + 1588.5 * height + 1495.5
elif tray_diameter <= 1:
shell_cost = 13.929 * height ** 2 + 2028.4 * height + 1850.6
elif tray_diameter <= 2:
shell_cost = 3.011 * height ** 2 + 3139.4 * height + 7166.9
elif tray_diameter <= 3:
shell_cost = -23.555 * height ** 2 + 5119.4 * height + 10945
elif tray_diameter <= 4:
shell_cost = -4.9723 * height ** 2 + 5021.1 * height + 24285 #???
# else:
# shell_cost = 'out of range'
sieve_tray_cost = -32.7 * tray_diameter**3 + 234.91 * tray_diameter**2 - 66.321 * tray_diameter + 293.53
column_investment_cost = 4.74 * (shell_cost + (stages - 2) * sieve_tray_cost)
return column_investment_cost
I am using an optimization tool Rbfopt, which calls another function name Optimization and optimization uses the 'economic' module to calculate objective function.
bb = rbfopt.RbfoptUserBlackBox(3, lower_bound, upper_bound, ['I', 'I', 'I'], optimization)
settings = rbfopt.RbfoptSettings(minlp_solver_path='C://Python_package//bonmin.exe', nlp_solver_path='C://Python_package//ipopt.exe', max_evaluations=2000)
alg = rbfopt.RbfoptAlgorithm(settings, bb)
val, x, itercount, evalcount, fast_evalcount = alg.optimize()
print(x)
#update the bound based on the first optimization results
t1_stop = perf_counter()
print("Elapsed time:", t1_stop, t1_start)
print("Elapsed time during the whole program in seconds:", t1_stop - t1_start)
Total Error Massage
Traceback (most recent call last):
File "C:/Users/XXX/Desktop/L/EOoptx.py", line 144, in <module>
val, x, itercount, evalcount, fast_evalcount = alg.optimize()
File "C:\Users\XXX\Anaconda3\envs\Rdsk\lib\site-packages\rbfopt\rbfopt_algorithm.py", line 803, in optimize
self.optimize_serial(pause_after_iters)
File "C:\Users\XXX\Anaconda3\envs\Rdsk\lib\site-packages\rbfopt\rbfopt_algorithm.py", line 1131, in optimize_serial
self.fixed_vars])
File "C:\Users\XXX\Anaconda3\envs\Rdsk\lib\site-packages\rbfopt\rbfopt_algorithm.py", line 2829, in objfun
return data[0].evaluate(point)
File "C:\Users\czm0131\Anaconda3\envs\Rdsk\lib\site-packages\rbfopt\rbfopt_user_black_box.py", line 152, in evaluate
return self.obj_funct(x)
File "C:/Users/XXX/Desktop/L/EOoptx.py", line 120, in optimization
D2_column_cost = economic.column(Tray_area_D2, H_D2, C2_stages)
File "C:\Users\XXX\Desktop\L\Economic.py", line 89, in column
column_investment_cost = 4.74 * (shell_cost + (stages - 2) * sieve_tray_cost)
UnboundLocalError: local variable 'shell_cost' referenced before assignment
Your tray_diameter value goes above 4, and thus shell_cost is never assigned. It does not exist.
A 'quick fix' would be to avoid calculating the column_investment_cost when tray_diameter is above 4 and return a None value instead. But you'd need to be able to handle that value where you try to call column():
def column(tray_area, height, stages):
tray_diameter = (tray_area * 4 / 3.1415926)**0.5
if tray_diameter > 4:
return None
if tray_diameter <= 0.5:
shell_cost = 15.401 * height**2 + 1588.5 * height + 1495.5
elif tray_diameter <= 1:
shell_cost = 13.929 * height ** 2 + 2028.4 * height + 1850.6
elif tray_diameter <= 2:
shell_cost = 3.011 * height ** 2 + 3139.4 * height + 7166.9
elif tray_diameter <= 3:
shell_cost = -23.555 * height ** 2 + 5119.4 * height + 10945
elif tray_diameter <= 4:
shell_cost = -4.9723 * height ** 2 + 5021.1 * height + 24285 #???
# else:
# shell_cost = 'out of range'
sieve_tray_cost = -32.7 * tray_diameter**3 + 234.91 * tray_diameter**2 - 66.321 * tray_diameter + 293.53
column_investment_cost = 4.74 * (shell_cost + (stages - 2) * sieve_tray_cost)
return column_investment_cost
You could also move the tray_diameter to its own function, and only calculate shell_cost and the rest if the conditions are met:
def calculate_tray_diameter(tray_area):
tray_diameter = (tray_area * 4 / 3.1415926)**0.5
return tray_diameter
def column(tray_diameter, height, stages)
if tray_diameter <= 0.5:
shell_cost = 15.401 * height**2 + 1588.5 * height + 1495.5
elif tray_diameter <= 1:
shell_cost = 13.929 * height ** 2 + 2028.4 * height + 1850.6
elif tray_diameter <= 2:
shell_cost = 3.011 * height ** 2 + 3139.4 * height + 7166.9
elif tray_diameter <= 3:
shell_cost = -23.555 * height ** 2 + 5119.4 * height + 10945
else:
shell_cost = -4.9723 * height ** 2 + 5021.1 * height + 24285 #???
# else:
# shell_cost = 'out of range'
sieve_tray_cost = -32.7 * tray_diameter**3 + 234.91 * tray_diameter**2 - 66.321 * tray_diameter + 293.53
column_investment_cost = 4.74 * (shell_cost + (stages - 2) * sieve_tray_cost)
return column_investment_cost
tray_diameter = calculate_tray_diameter(some_value)
if tray_diameter > 4:
print("Cannot calculate cost!")
else:
column_investment_cost = column(tray_diameter, height_value, stages_value)
Related
I am trying to create a specific output pattern for a textfile I wanted to later load into C++.
I wrote a file in Python that creates random coordinates and movement values in a circle.
The output is supposed to have the output:
Place_1 Place_2 Place_3 Movement_1 Movement_2 Movement_3\n
Place_1 Place_2 Place_3 Movement_1 Movement_2 Movement_3\n
Place_1 Place_2 Place_3 Movement_1 Movement_2 Movement_3
The Code is use is
import numpy as np
file = open('log.txt', 'a')
def f(n, center, radius, ecc):
pos = np.zeros((n,6))
r = ecc * radius
for i in range(n):
while 1:
x_1 = -1 + 2 * np.random.rand(1)
x_2 = -1 + 2 * np.random.rand(1)
if (x_1*x_1 + x_2*x_2)<1 :
pos[i,0] = center[0] + r * 2 * x_1 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
pos[i,1] = center[1] + r * 2 * x_2 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
pos[i,2] = center[2] + r * (1 - 2 * (x_1*x_1 + x_2*x_2))
pos[i,3] = (-1 + 2 * np.random.rand(1))
pos[i,4] = (-1 + 2 * np.random.rand(1))
pos[i,5] = (-1 + 2 * np.random.rand(1))
break
string = str(pos[i,:]).strip('[]').rstrip('\n')
file.write(string)
return
f(10000, np.array((127,127,127)), 92, 0.9)
file.close()
The log I create is however very badly formated. How can I get the required format?
You're going to a lot of trouble here that you don't need. This seems to solve the problem, simply.
import numpy as np
file = open('log.txt', 'a')
def f(n, center, radius, ecc):
r = ecc * radius
for i in range(n):
while 1:
pos = [0]*6
x_1 = -1 + 2 * np.random.rand(1)[0]
x_2 = -1 + 2 * np.random.rand(1)[0]
if (x_1*x_1 + x_2*x_2) < 1:
pos[0] = center[0] + r * 2 * x_1 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
pos[1] = center[1] + r * 2 * x_2 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
pos[2] = center[2] + r * (1 - 2 * (x_1*x_1 + x_2*x_2))
pos[3] = (-1 + 2 * np.random.rand(1)[0])
pos[4] = (-1 + 2 * np.random.rand(1)[0])
pos[5] = (-1 + 2 * np.random.rand(1)[0])
break
print(*pos, file=file)
f(10000, np.array((127,127,127)), 92, 0.9)
file.close()
A solution without numpy:
import math
import random
file = open('log.txt', 'a')
def f(n, center, radius, ecc):
r = ecc * radius
for _ in range(n):
pos = [0]*6
while 1:
x_1 = 2 * random.random() - 1
x_2 = 2 * random.random() - 1
vector = x_1*x_1 + x_2*x_2
if vector < 1:
break
pos[0] = center[0] + r * 2 * x_1 * math.sqrt(1 - vector)
pos[1] = center[1] + r * 2 * x_2 * math.sqrt(1 - vector)
pos[2] = center[2] + r * (1 - 2 * vector)
pos[3] = 2 * random.random() -1
pos[4] = 2 * random.random() -1
pos[5] = 2 * random.random() -1
print(*pos, file=file)
f(10000, (127,127,127), 92, 0.9)
file.close()
Use np.savetxt:
import numpy as np
def f(n, center, radius, ecc):
pos = np.zeros((n,6))
r = ecc * radius
for i in range(n):
while 1:
x_1 = -1 + 2 * np.random.rand(1)
x_2 = -1 + 2 * np.random.rand(1)
if (x_1*x_1 + x_2*x_2)<1 :
pos[i,0] = center[0] + r * 2 * x_1 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
pos[i,1] = center[1] + r * 2 * x_2 * np.sqrt(1 - x_1*x_1 - x_2*x_2)
pos[i,2] = center[2] + r * (1 - 2 * (x_1*x_1 + x_2*x_2))
pos[i,3] = (-1 + 2 * np.random.rand(1))
pos[i,4] = (-1 + 2 * np.random.rand(1))
pos[i,5] = (-1 + 2 * np.random.rand(1))
break
np.savetxt('file.txt',pos,delimiter=';')
return
f(100, np.array((127,127,127)), 92, 0.9)
For the formatting issue you can make the coordinates into characters (What I mean is that turn coordinates into a character that would be printed like _ or / something like that) Also you can put empty space in a print like print(" Hello.") also to go to a different line in the console do print("\n Hello."). This probably was not what you were looking for but I hope this somewhat helps.
I have the following script:
guess = np.linspace(0,20/1000, num = 21)
def calc_U_LC_a(t)-> "U_LC_a":
alpha_c = calc_alpha_c(t)
S_p = calc_S_p(t)
M_p = calc_M_p(t)
p_b_LC = calc_p_b(t, min(fy,fu/1.15))
Y_p = calc_Y_p(t)
p_c_LC = calc_p_c(t)
if pl_net_LC >= 0:
U_P = (Y_p * pl_net_LC) / (alpha_c * p_b_LC)
else:
U_P = 1.02 * 2 * (- pl_net_LC / p_c_LC)
M_Sd_a = 500e3
S_Sd_a = 500e4
U_M = (1.02 * 2 / alpha_c) * (abs(M_Sd_a)/M_p)
U_S = (1.02 * 2 / alpha_c) * (S_Sd_a/S_p)
U_LC_a = ((U_M + U_S ** 2) ** 2) + U_P ** 2
return U_LC_a
def fun_LC_a(t):
return calc_U_LC_a(t) - 1
def calc_iter(fun,guess):
for i in range(0,len(guess)):
try:
tmin = optimize.newton(fun,guess[i]) #, disp = False)
except RuntimeError:
print('guess = ', guess[i],' failed to converge.')
else:
break
return tmin
tmin_X = calc_iter(fun_LC_a,guess)
All variables that are not defined here are constant values.
When I run this script, I get the error "UnboundLocalError: local variable 'Y_p' referenced before assignment"
and I am not sure why.
I am trying to solve a PDE using odeint and the method of lines. My code is definitely wrong - and I'm trying to figure out where it is going wrong.
I am calling the ode solver using odeint(odefunc,y0,tspan) where tspan = np.linspace(0.0, 0.5, 5) & y0 = 1.0*np.ones(3).
I tried printing t within odefunc and am confused by the output. Despite the fact that I am solving up to t=0.5, the last t-value to print is 0.015081203121127767. The number of outputs matches tspan, but I cannot see how it could possibly be solving up to t = 0.5 when the last time in the de function is 0.015. What am I missing?
My DE is time dependent - so this is making it very hard to figure out where things are going wrong because I don't seem to be seeing the times where everything fails.
ETA - this is failing, but running this without some of the irrelevant stuff I am getting the warning ODEintWarning: Excess work done on this call (perhaps wrong Dfun type). Run with full_output = 1 to get quantitative information., which I'm assuming is part of the issue - but it doesn't appear to be halting the code.
MWE
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
import math
import sys
plt.interactive(False)
sigma = 2320
rho = 1000
gravity = 9.81 # [m/s^2]
g = gravity*3600*3600 # [m/hour^2]
S = 0.01
settlingVelocity = 0.02 # [m/s]
ws = settlingVelocity*3600 # [m/hour]
n = 0.04 # [SI]
J = 400 # [Ws/m]
k = 0.02
Cstar = 0.2 * sigma # [kg/m^3]
W = 2 # [m]
D0 = 1.2
Lw = 20
L = 100
tend = 0.5 # in hours
tspan = np.linspace(0.0, tend, 5)
def d(t): # metres
if t < 50: # hours
return 0.5
else:
return 0.05
def Q(t):
return 3600 * (math.sqrt(S)/n)*((W*d(t))**(5/3))/((2*d(t) + W)**(2/3))
def h(t):
return d(t)/2
def beta(t):
return (sigma - rho) * g * h(t)/sigma
def Omega(t):
return rho * g * S * Q(t) # [W/m]
def PsiTime(t):
return rho * g * Q(t) * (D0 - d(t))/(Lw)
N = 10
X = np.linspace(0, L, N)
delX = L/ (N-1)
def odefunc(y, t):
def zetaEh(t):
return k * (PsiTime(t) + Omega(t)) / (J + beta(t))
def zetaEW(t):
return (2*d(t)/(W + 2*d(t))) * k * Omega(t)/(J + beta(t))
def zetaR(t):
return (W/(W + 2*d(t))) * k*Omega(t)/(beta(t))
def zetaEF(t,i):
return (W/(W + 2*d(t))) * k * Omega(t) / (J + beta(t))
C = y[:N]
M = y[N:]
print("time: ", t)
dCdt = np.zeros(X.shape)
dMdt = np.zeros(X.shape)
dCdt[0] = ( # forward difference for dCdx
-Q(t) / (W*d(t)) * (C[1] - C[0]) / delX
+ (zetaEh(t) / (W * d(t))) * ((Cstar - C[0]) / Cstar)
- (ws * C[0] * (beta(t))) / (d(t) * (J + beta(t)))
)
dMdt[0] = 0
# gully channel
for i in range (1, N-1): # central difference
if M[i] + W *C[i] * ws - zetaR(t) * (Cstar - C[i]) / Cstar < 0:
reMass = M[i] + W * C[i] * ws
dCdt[i] = (
-Q(t) / (W*d(t)) * (C[i+1] - C[i - 1]) / (2*delX)
+ 1 / (W * d(t)) * ((zetaEW(t) + zetaEF(t,i)) * (Cstar - C[i]) / Cstar
+ reMass * (1 - (beta(t))/ (J + beta(t))))
- C[i] * ws/d(t)
)
dMdt[i] = -M[i]
else:
dCdt[i] = (
-Q(t) / (W*d(t)) * (C[i+1] - C[i - 1]) / (2*delX)
+ 1 / (W * d(t)) * (zetaEW(t) + zetaR(t)) * (Cstar - C[i]) / Cstar
- C[i] * ws / d(t)
)
dMdt[i] = W * C[i] * ws - zetaR(t) * (Cstar - C[i]) / Cstar
# Final node - backward difference
if M[N-1] + W * C[N-1] * ws - zetaR(t) * (Cstar - C[N-1]) / Cstar < 0:
reMass = M[N-1] + W * C[N-1] * ws
dCdt[N-1] = (
-Q(t) / (W * d(t)) * (C[N-1] - C[N-2]) / delX
+ 1 / (W * d(t)) * ((zetaEW(t) + zetaEF(t, i)) * (Cstar - C[N-1]) / Cstar
+ reMass * (1 - (beta(t)) / (J + beta(t))))
- C[i] * ws / d(t)
)
dMdt[N-1] = -M[N-1]
else:
dCdt[N-1] = (
-Q(t) / (W * d(t)) * (C[N-2] - C[N - 1]) / delX
+ 1 / (W * d(t)) * (zetaEW(t) + zetaR(t)) * (Cstar - C[N-1]) / Cstar
- C[N-1] * ws / d(t)
)
dMdt[N-1] = W * C[N-1] * ws - zetaR(t) * (Cstar - C[N-1]) / Cstar
dydt = np.ravel([dCdt, dMdt])
return dydt
init_C = 0.0 * np.ones(X.shape)
init_M = 0.0 * np.ones(X.shape)
init= np.ravel([init_C, init_M])
sol = odeint(odefunc, init, tspan)
conc = sol[:, :N]
I have to make a calculator with argv.sys. When I run my code I keep getting this error:
>>> "C:\Users\admin\Desktop\uni\Informatik BW\assignment.py" + rect 0 0 10 10
File "<stdin>", line 1
"C:\Users\admin\Desktop\uni\Informatik BW\assignment.py" + rect 0 0 10 10
^
SyntaxError: invalid syntax
>>>
Here is my program:
import sys
import math
def area_rectangle(x,y,widht,height):
return (widht*height)
def xy_centroid_rectangle(x,y):
return (k + l * 0.5)
#def area_circle(x,y,r):
#return (r*r*math.pi)
#def xy_centroid_circle(k,r):
# return ((4 * r / 3 * math.pi) * 2)
#def area_half_circle(x,y,r):
# return (r * r * math.pi / 2)
#def xy_centroid_half_circle(k,r):
# return (4 * r / 3 * math.pi)
#def area_right_triangle(x,y,a,h):
# return (a * h / 2)
#def xy_centroid_right_triangle(k,l):
# return (a + h + math.sqrt((a * a) + (h * h)))
x = 0
y = 0
a = 0
fx = 0
fy = 0
f = 0
i = 1
while i < len(sys.argv):
vz = sys.argv[i]
print i
print vz
if sys.argv[i + 1] == "rect":
f = area_rectangle(float(sys.argv[i + 2]),float(sys.argv[i + 3]),float(sys.argv[i + 4]),float(sys.argv[i + 5]))
fx = xy_centroid_rectangle(float(sys.argv[i + 2]),float(sys.argv[i + 4]))
fy = xy_centroid_rectangle(float(sys.argv[i + 3]),float(sys.argv[i + 5]))
i += 6
#if sys.argv[i + 1] == "circ":
#f = area_circle(float(sys.argv[i + 2]),float(sys.argv[i + 3]),float(sys.argv[i + 4]))
#fx = xy_centroid_circle(foat(sys.argv[i + 2]),float(sys.argv[i + 4]))
#fy = xy_centroid_circle(foat(sys.argv[i + 3]),float(sys.argv[i + 4]))
#i += 5
#if sys.argv[i + 1] == "halfcirc":
#f = area_circle(float(sys.argv[i + 2]),float(sys.argv[i + 3]),float(sys.argv[i + 4]))
#fx = xy_centroid_circle(foat(sys.argv[i + 2]),float(sys.argv[i + 4]))
#fy = xy_centroid_circle(foat(sys.argv[i + 3]),float(sys.argv[i + 4]))
#i += 5
#if sys.argv[i + 1] == "righttri":
#f = area_rectangle(float(sys.argv[i + 2]),float(sys.argv[i + 3]),float(sys.argv[i + 4]),float(sys.argv[i + 5]))
#fx = xy_centroid_rectangle(float(sys.argv[i + 2]),float(sys.argv[i + 4]))
#fy = xy_centroid_rectangle(float(sys.argv[i + 3]),float(sys.argv[i + 5]))
#i += 6
if vz == "+":
x = (x * a + fx * f) / (a + f)
y = (y * a + fy * f) / (a + f)
a = a + f
if vz == "-":
x = (x * a - fx * f) / (a - f)
y = (y * a - fy * f) / (a - f)
a = a - f
print x
print y
print a
Why am I getting this error?
That's not how you run a python program. Open a CMD (Windows) prompt and write your command line there. You'll probably need to add python in front too.
My global variables are not working in my code. I'm fairly new to this and I can't seem to figure this out: I have set variables (only showing gna for this), which can be manipulated by an entry field, triggered by a corresponding button. For some reason, it's not taking the changes within the loop. I'm trying to make it to where the changed variable can be graphed as well, but it gives me the following error:
Exception in Tkinter callback Traceback (most recent call last):
File "C:\Program Files\Python35\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args) File "G:/PYTHON/Eulers.py", line 64, in graph
v[i + 1] = 1 / c * (gna * f[i] - gk * u[i]) * del_t + v[i]
TypeError: ufunc 'multiply' did not contain a loop with signature matching types dtype('< U32') dtype('< U32') dtype('< U32')
Here is the code:
gna = 0.9
gnalabel = Label(topFrame, text="gna = %s" % gna)
gnalabel.pack()
gnaEntry = Entry(topFrame, justify=CENTER)
gnaEntry.pack()
def gnacallback():
global gna
gna = gnaEntry.get()
gnalabel.config(text="C = %s" % gna)
gnaButton = Button(topFrame, text="Change", width=10, command=gnacallback)
gnaButton.pack()
def graph():
global c, gna, gk, beta, gamma
for i in range(0, len(t)-1):
stinum = np.floor(i / 3000)
stimt = 3000 + 3000 * (stinum - 1)
f[i] = v[i] * (1 - (((v[i]) ** 2) / 3))
v[i + 1] = 1 / c * (gna * f[i] - gk * u[i]) * del_t + v[i]
if(i == stimt):
v[i + 1] = v[i + 1] + v_stim
u[i + 1] = (v[i] + beta - gamma * u[i]) * del_t + u[i]
plt.plot(v)
plt.show()
gna = gnaEntry.get()
Entry.get returns a string, which is probably an unsuitable type for the arithmetic you're doing in graph. Try converting to a number first.
gna = float(gnaEntry.get()) #or perhaps `int` if it's always an integer