Hi I am working on a script that will solve and plot an ODE using the Runge Kutta method. I want to have the script use different functions so I can expand upon it later. If I write it with out the function definition it works fine, but with the def() it will not open a plot window or print the results. Than you!
from numpy import *
import matplotlib.pyplot as plt
#H=p^2/2-cosq
#p=dp=-dH/dq
#q=dq=dH/dp
t = 0
h = 0.5
pfa = [] #Create arrays that will hold pf,qf values
qfa = []
while t < 10:
q = 1*t
p = -sin(q*t)
p1 = p
q1 = q
p2 = p + h/2*q1
q2 = q + h/2*p1
p3 = p+ h/2*q2
q3 = q+ h/2*p2
p4 = p+ h/2*q3
q4 = q+ h/2*p4
pf = (p +(h/6.0)*(p1+2*p2+3*p3+p4))
qf = (q +(h/6.0)*(q1+2*q2+3*q3+q4))
pfa.append(pf) #append arrays
qfa.append(qf)
t += h #increase time step
print("test")
plt.plot(pfa,qfa)
print("test1")
plt.show()
print("tes2t")
If you have a function declared, you'll need to call it at some point, e.g.:
def rk(p,q,h):
pass # your code here
if __name__ == '__main__':
rk(1,2,1)
Putting the function call within the if __name__ == '__main__' block will ensure that the function is called only when you run the script directly, not when you import it from another script. ( More on that here in case you're interested: What does if __name__ == "__main__": do? )
And here's an even better option; to avoid hard-coding fn args (your real code should have some error-handling for unexpected command-line input):
def rk(p,q,h):
pass # your code here
if __name__ == '__main__':
import argparse
the_parser = argparse.ArgumentParser()
the_parser.add_argument('integers', type=int, nargs=3)
args = the_parser.parse_args()
p,q,h = args.integers
rk(p,q,h)
Related
I am trying to concurrently execute methods from two objects concurrently for a computer vision task. My idea is to use two different feature detectors to compute their respective feature descriptions inside a base class.
In this regard, I built the following toy example to understand python concurrent.futures.ProcessPoolExecutor class.
When executed, the first part of the code runs as expected with 20 Heartbeat (10 from each method executed 10 times in total) strings printed out with the sum for two objects coming out correctly as 100, -100.
But in the second half of the code, it appears the ProcessPoolExecutor is not running the do_math(self, numx) method at all. What am I doing wrong here?
With best,
Azmyin
import numpy as np
import concurrent.futures as cf
import time
def current_milli_time():
# CORE FUNCTION
# Function that returns a time tick in milliseconds
return round(time.time() * 1000)
class masterClass(object):
super_multiplier = 1 # Class variable
def __init__(self, ls):
# Attributes of masterClass
self.var1 = ls[0]
self.sumx = ls[1]
def __rep__(self):
print(f"sumx value -- {self.sumx}")
def apply_sup_mult(self, var_in):
self.sumx = self.sumx + (var_in * masterClass.super_multiplier)
time.sleep(0.025)
print(f"Hearbeat!!")
# This is a regular method
def do_math(self, numx):
self.apply_sup_mult(numx)
ls = [10,0]
ls2 = [-10,0]
numx = 10
obj1 = masterClass(ls)
obj2 = masterClass(ls2)
t1 = current_milli_time()
# Run methods one by one
for _ in range(numx):
obj1.do_math(ls[0])
obj2.do_math(ls2[0])
obj1.__rep__()
obj2.__rep__()
t2 = current_milli_time()
print(f"Time taken -- {t2 - t1} ms")
print()
## Using multiprocessing to concurrently run two methods
# Intentionally reinitialize objects
obj1 = masterClass(ls)
obj1 = masterClass(ls2)
t1 = current_milli_time()
resx = []
with cf.ProcessPoolExecutor() as executor:
for i in range(numx):
#fs = [executor.submit(obj3.do_math, ls[0]), executor.submit(obj4.do_math, ls2[0])]
f1 = executor.submit(obj1.do_math, ls[0])
f2 = executor.submit(obj2.do_math, ls2[0])
# for i,f in enumerate(cf.as_completed(fs)):
# print(f"Done with {f}")
# # State of sumx
obj1.__rep__()
obj2.__rep__()
t2 = current_milli_time()
print(f"Time taken -- {t2 - t1} ms")
This is the code. I think the solver could be glpk instead of gurobi. I got the error before it tries to solve the problem.
from pyomo.environ import *
from pyomo.opt import SolverFactory, SolverStatus
PrintSolverOutput = False ###
model = ConcreteModel()
model.dual = Suffix(direction =Suffix.IMPORT)
model.X = Var(I,T, within = NonNegativeReals)
model.In = Var(I,T, within = NonNegativeReals)
model.S = Var(T, within = NonNegativeReals)
def Objetivo(model):
return (sum(C[i]*model.X[i,t]*((1+tau[i])**(t-1))+Ch[i]*model.In[i,t]
for i in I for t in T)
+sum(Cs*model.S[t]
for t in T)
)
model.Total_Cost = Objective(rule = Objetivo, sense= minimize)
def Balance(model,i,t):
if t==1:
return model.X[i,t]+I0[i]-model.In[i,t]==D[i,t]
elif t>=2:
return model.X[i,t]+model.IN[i,t-1]-model.In[i,t]==D[i,t]
def Horas(model, t):
return sum(r[i]*model.X[i,t] for i in I) <= H+model.S[t]
def Limite(model,t):
return model.S[T]<=LS
model.RBalance = Constraint(I,T,rule=Balance)
model.RHoras = Constraint(T,rule=Horas)
model.RLimiteoras = Constraint(T,rule=Limite)
opt = SolverFactory("gurobi")
This is the data
I forgot to put the data before.
T = [1,2,3,4,5,6]
I = ['A','B']
D = {('A',1):300,
('A',2):400,
('A',3):500,
('A',4):600,
('A',5):800,
('A',6):700,
('B',1):700,
('B',2):600,
('B',3):500,
('B',4):400,
('B',5):300,
('B',6):400}
tau = {'A':0.02,'B':0.01}
r = {'A':5,'B':3}
H = 3520
LS = 800
C = {'A':150,'B':120}
Ch = {'A':8,'B':4}
Cs = 6
I0 = {'A':100,'B':250}
error
The code is from a youtube tutorial and it worked for him but not for me. Why?
Aside from fixing two typos in your code, this model computes and solves for me without that error. Make these fixes, run it again, re-post the exact error with line number and the exact code that produces the error if stuck...
SyntaxError: invalid syntax
I have a syntax error, but i could not solve it, need help
error: for k, g in groupby(enumerate(ranges), lambda (i,x):i-x):
Also, 1 question if anyone is able to help me
i am using Ubuntu 18.04, i rosrun this file but got [rosrun] Couldn't find executable named sensor_data_listerner.py below /home/sk/catkin_ws/src/testbot_description
is it because of the ROS python version i am using that caused the error?
the following is the code:
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
import sensor_msgs.msg
import random
import numpy as np
from geometry_msgs.msg import Twist
from itertools import *
from operator import itemgetter
LINX = 0.0 #Always forward linear velocity.
THRESHOLD = 1.5 #THRESHOLD value for laser scan.
PI = 3.14
Kp = 0.05
angz = 0
def LaserScanProcess(data):
range_angels = np.arange(len(data.ranges))
ranges = np.array(data.ranges)
range_mask = (ranges > THRESHOLD)
ranges = list(range_angels[range_mask])
max_gap = 40
# print(ranges)
gap_list = []
for k, g in groupby(enumerate(ranges), lambda (i,x):i-x):
gap_list.append(map(itemgetter(1), g))
gap_list.sort(key=len)
largest_gap = gap_list[-1]
min_angle, max_angle = largest_gap[0]*((data.angle_increment)*180/PI), largest_gap[-1]*((data.angle_increment)*180/PI)
average_gap = (max_angle - min_angle)/2
turn_angle = min_angle + average_gap
print(min_angle, max_angle)
print(max_gap,average_gap,turn_angle)
global LINX
global angz
if average_gap < max_gap:
angz = -0.5
else:
LINX = 0.5
angz = Kp*(-1)*(90 - turn_angle)
def main():
rospy.init_node('listener', anonymous=True)
pub = rospy.Publisher('/cmd_vel', Twist, queue_size=10)
rospy.Subscriber("scan", sensor_msgs.msg.LaserScan , LaserScanProcess)
rate = rospy.Rate(10) # 10hz
while not rospy.is_shutdown():
command = Twist()
command.linear.x = LINX
command.angular.z = angz
pub.publish(command)
rate.sleep()
if __name__ == '__main__':
main()
You can't unpack a tuple in the argument list of a lambda expression (or of a def statement) in Python 3. (That's a change from Python 2, where your lambda expression would have been valid.)
You'll have to use
lambda t: t[0] - t[1]
instead.
I have created a PyQt5 GUI in my main.py file which is in a main app folder. In the file for the interface, a button initiates a new class called Calculation (in the file entry.py) passing in the values of several inputs on the page and in this class the startCalculation() method is called. In this method, the different variables are passed to methods in imported python files, then the result of those calculation is returned and passed to the next calculation in another python file. These returns are in the form of arrays containing values (for the y axis which is then displayed using numpy and plotly).
When I run the app and click on the button in the main interface, the app starts loading (rainbow animation on Mac) and it says it is not responding. It is not a problem with the class itself as a normal print test works in the startCalculation() method, but the function from the imported file causes this to happen. Also, no errors are given in the terminal.
The following is code in the PyQt interface file (main.py)
from app import entry
def startButton(self):
massaTotale = float(self.lineEdit.text())
dragCoefficient = float(self.lineEdit_5.text())
liftCoefficient = float(self.lineEdit_6.text())
powerAvionics = float(self.lineEdit_3.text())
powerPayload = float(self.lineEdit_4.text())
airSpeed = float(self.lineEdit_8.text())
valoreUnico = float(self.valoreUnicoEdit.text())
engineEfficiency = float(self.lineEdit_9.text())
turbolenceCoeff = float(self.lineEdit_10.text())
dayOfYear = float(self.day_LineEdit.text())
latitude = float(self.latitude_LineEdit.text())
sunsetHourAngle = float(self.sunsetHourAngle_LineEdit.text())
declination = float(self.declination_LineEdit.text())
newCaluclation = entry.Calculation(massaTotale, dragCoefficient, liftCoefficient, powerAvionics, powerPayload, airSpeed, valoreUnico, engineEfficiency, turbolenceCoeff, dayOfYear, latitude, sunsetHourAngle, declination)
newCaluclation.startCalculation()
And this is the code in the class calling the function in the external file
from app.mainFunctions import pLevel
#constructor method
def __init__(self, massaTotale, dragCoefficient, liftCoefficient, powerAvionics, powerPayload, airSpeed, valoreUnico, efficiencyEngine, turbolenceCoeff, dayOfYear, latitude, sunsetHourAngle, declination):
# calculate plevel
self.totM = massaTotale
self.vair = airSpeed
self.cl = liftCoefficient
self.cd = dragCoefficient
self.efficiencyEngine = efficiencyEngine
self.valoreUnico = valoreUnico
self.powerAvionics = powerAvionics
self.powerPayload = powerPayload
self.turbolenceCoeff = turbolenceCoeff
self.day_of_year = dayOfYear
self.latitude = latitude
self.sunset_hour_angle = sunsetHourAngle
self.declination = declination
#starting the calculation
def startCalculation(self):
self.x_values, self.pLevel_values = pLevel.calculate_pLevel(self.valoreUnico, self.cd, self.cl, self.totM)
'''
self.pEngine_values = pEngine.calculate_pEngine(self.x_values, self.pLevel_values, self.efficiencyEngine, self.turbolenceCoeff)
self.pOut_values = pOut.calculate_pOut(self.x_values, self.pEngine_values, self.powerAvionics, self.powerPayload)
self.I_loctime = I_loctime.calculate_I_loctime(self.day_of_year, self.latitude, self.sunset_hour_angle, self.declination)
self.asm_values = area_Solar_Module.calculate_asm(self.x_values, self.pOut_values, self.I_loctime)
'''
The pLevel.py file has the following code in it and should return the array of values to pass to the second function in the entry Calculation class file.
import math
import numpy as np
import plotly as py
import plotly.graph_objs as go
import ipywidgets as widgets
import plotly.io as pio
import sys
sys.dont_write_bytecode = True
py.offline.init_notebook_mode(connected=True)
pio.renderers.default = "browser"
# calculating pLevel
x_values = []
y_values = []
layoutPLevel = go.Layout(
title="pLevel",
yaxis=dict(
title='pLevel'
),
xaxis=dict(
title='Surface Area Wing'
)
)
def calculate_pLevel(valoreUnico, cd, cl, totM):
x_values = []
count = 0
while (count < 5):
x_values.append(count)
count = count + 0.01
y_values = []
iteration = 0
while (iteration < len(x_values)):
x_value = x_values[iteration]
if (x_value == 0):
y_value = 0
y_values.append(y_value)
else:
if (valoreUnico == 0.0):
# nessun dato per valoreUnico dato, utilizza i due valori separati
y_value = firstPart(cd, cl) * math.sqrt(secondPart(x_value, totM))
y_values.append(y_value)
else:
y_value = valoreUnico * \
math.sqrt(secondPart(x_value, totM))
y_values.append(y_value)
iteration = iteration + 1
else:
yNpArray = np.array(y_values)
xNpArray = np.array(x_values)
tracePLevel = go.Scatter(
x=xNpArray,
y=yNpArray,
mode='lines',
name='pLevel',
line=dict(
shape='spline'
)
)
figPLevel = go.Figure(data=[tracePLevel], layout=layoutPLevel)
figPLevel.show()
return x_values, y_values
def firstPart(cd, cl):
return (cd / cl**(3/2))
def secondPart(x_value, totM):
return (2*(totM * 9.81)**3) / (1.225 * x_value)
The structure of the files is as follows:
-app
-- __main__.py
-- entry.py
-- __init__.py
-- mainFunctions
--- pLevel.py
--- __init__.py
The loop for the x_values in the pLevel function was not adding one to the iteration so the loop went on forever. I just did not notice my error.
Instead of being
while (iteration < len(x_values)):
x_value = x_values[iteration]
if (x_value == 0):
y_value = 0
y_values.append(y_value)
It should be
while (iteration < len(x_values)):
x_value = x_values[iteration]
if (x_value == 0):
y_value = 0
y_values.append(y_value)
iteration = iteration+1
Purpose: Given a PDB file, prints out all pairs of Cysteine residues forming disulfide bonds in the tertiary protein structure. Licence: GNU GPL Written By: Eric Miller
#!/usr/bin/env python
import math
def getDistance((x1,y1,z1),(x2,y2,z2)):
d = math.sqrt(pow((x1-x2),2)+pow((y1-y2),2)+pow((z1-z2),2));
return round(d,3);
def prettyPrint(dsBonds):
print "Residue 1\tResidue 2\tDistance";
for (r1,r2,d) in dsBonds:
print " {0}\t\t {1}\t\t {2}".format(r1,r2,d);
def main():
pdbFile = open('2v5t.pdb','r');
maxBondDist = 2.5;
isCysLine = lambda line: (line[0:4] == "ATOM" and line[13:15] == "SG");
cysLines = [line for line in pdbFile if isCysLine(line)];
pdbFile.close();
getCoords = lambda line:(float(line[31:38]),
float(line[39:46]),float(line[47:54]));
cysCoords = map(getCoords, cysLines);
dsBonds = [];
for i in range(len(cysCoords)-1):
for j in range(i+1,len(cysCoords)):
dist = getDistance(cysCoords[i],cysCoords[j]);
residue1 = int(cysLines[i][23:27]);
residue2 = int(cysLines[j][23:27]);
if (dist < maxBondDist):
dsBonds.append((residue1,residue2,dist));
prettyPrint(dsBonds);
if __name__ == "__main__":
main()
When I try to run this script I get indentation problem. I have 2v5t.pdb (required to run the above script) in my working directory. Any solution?
For me the indentation is broken within 'prettyPrint' and in 'main'. Also no need to use ';'. Try this:
#!/usr/bin/env python
import math
# Input: Two 3D points of the form (x,y,z).
# Output: Euclidean distance between the points.
def getDistance((x1, y1, z1), (x2, y2, z2)):
d = math.sqrt(pow((x1 - x2), 2) + pow((y1 - y2), 2) + pow((z1 - z2), 2))
return round(d, 3)
# Purpose: Prints a list of 3-tuples (r1,r2,d). R1 and r2 are
# residue numbers, and d is the distance between their respective
# gamma sulfur atoms.
def prettyPrint(dsBonds):
print "Residue 1\tResidue 2\tDistance"
for r1, r2, d in dsBonds:
print " {0}\t\t {1}\t\t {2}".format(r1, r2, d)
# Purpose: Find all pairs of cysteine residues whose gamma sulfur atoms
# are within maxBondDist of each other.
def main():
pdbFile = open('2v5t.pdb','r')
#Max distance to consider a disulfide bond.
maxBondDist = 2.5
# Anonymous function to check if a line from the PDB file is a gamma
# sulfur atom from a cysteine residue.
isCysLine = lambda line: (line[0:4] == "ATOM" and line[13:15] == "SG")
cysLines = [line for line in pdbFile if isCysLine(line)]
pdbFile.close()
# Anonymous function to get (x,y,z) coordinates in angstroms for
# the location of a cysteine residue's gamma sulfur atom.
getCoords = lambda line:(float(line[31:38]),
float(line[39:46]), float(line[47:54]))
cysCoords = map(getCoords, cysLines)
# Make a list of all residue pairs classified as disulfide bonds.
dsBonds = []
for i in range(len(cysCoords)-1):
for j in range(i+1, len(cysCoords)):
dist = getDistance(cysCoords[i], cysCoords[j])
residue1 = int(cysLines[i][23:27])
residue2 = int(cysLines[j][23:27])
if dist < maxBondDist:
dsBonds.append((residue1,residue2,dist))
prettyPrint(dsBonds)
if __name__ == "__main__":
main()
This:
if __name__ == "__main__":
main()
Should be:
if __name__ == "__main__":
main()
Also, the python interpreter will give you information on the IndentationError down to the line. I strongly suggest reading the error messages provided, as developers write them for a reason.
You didn't say where the error was flagged to be but:
if __name__ == "__main__":
main()
Should be:
if __name__ == "__main__":
main()