I have post the similar question before,however,I think I may have misinterpreted my question,so may I just post my origin code here,and looking for someone can help me,I am really stuck now..thanks alot.
from numpy import *
import math as M
#initial condition All in SI unit
G=6.673*10**-11 #Gravitational constant
ms=1.9889*10**30 #mass of the sun
me=5.9742*10**24 #mass of the earth
dt=10 #time step
#Creat arrays
vs=array([[0,0,0]]) #1st element stand for x component of V of earth
ve=array([[29770,0,0]])
rs=array([[0,0,0]])
re=array([[0,1.4960*10**11,0]])
#First update velocity in order to start leapfrog approximation
fs=-G*ms*me*((rs-re)/(M.sqrt((rs-re)[0][0]**2+(rs-re)[0][1]**2+(rs-re)[0][2]**2))**3)
fe=-fs
vs=vs+fs*dt/ms
ve=ve+fe*dt/me
n=input('please enter the number of timestep you want it evolve:')
#update force
def force(n,ms,me,rs,re,G):
rs,re=update_r(rs,re,n,dt)
fs=-G*ms*me*((rs-re)/(M.sqrt((rs-re)[0][0]**2+(rs-re)[0][1]**2+(rs-re)[0][2]**2))**3)
fe=-fs
return fs,fe
#update velocities
def update_v(n,vs,ve,ms,me,dt,fs,fe):
fs,fe=force(n,ms,me,rs,re,G)
i=arange(n)
vs=vs+fs[:]*i[:,newaxis]*dt/ms
ve=ve+fe[:]*i[:,newaxis]*dt/me
return vs,ve
#update position
def update_r(rs,re,n,dt):
vs,ve=update_v(n,vs,ve,ms,me,dt,fs,fe)
i=arange(n)
rs=rs+vs[:]*i[:,newaxis]*dt
re=re+ve[:]*i[:,newaxis]*dt
return rs,re
#there is start position,v,r,f all have initial arrays(when n=0).
#then it should calculate f(n=1) then use this to update v(n=0)
#to v(n=1),then use v(n=1) update r(n=0) to r(n=1),then use r(n=1)
#update f(n=1) to f(n=2)....and so on until finish n.but this code seems doesnt do this,,how can I make it? –
when i call force python gives:
please enter the number of timestep you want it evolve:4Traceback (most recent call last):
File "<pyshell#391>", line 1, in <module>
force(n,ms,me,rs,re,G)
File "/Users/Code.py", line 24, in force
rs,re=update_r(rs,re,n,dt)
File "/Users/Code.py", line 39, in update_r
vs,ve=update_v(n,vs,ve,ms,me,dt,fs,fe)
UnboundLocalError: local variable 'vs' referenced before assignment
can anyone give me some tips?thanks......
where do you call force in this code?
In any event, the problem is in update_r. You reference vs in the first line of update_r even though vs is not defined in this function. Python is not looking at the vs defined above. Try adding
global vs
as the first line of update_r or adding vs to the parameter list for update_r
In the first line of update_r, you have vs,ve=update_v(n,vs,ve,ms,me,dt,fs,fe). Look at the function that you are calling. You are calling update_v with a bunch of parameters. One of these parameters is vs. However, that is the first time in that function that vs appears. The variable vs does not have a value associated with it yet. Try initializing it first, and your error should disappear
Put an additional global statement containing all your globals after each def statement. Otherwise, all globals are transformed into locals within your def without it.
def update_v(n,vs,ve,ms,me,dt,fs,fe):
global vs, ve, ...
On line 39 you do
vs,ve=update_v(n,vs,ve,ms,me,dt,fs,fe)
while you are inside a function.
Since you defined a global variable called vs, you would expect this to work.
It would have worked if you had:
vs_new,ve_new = update_v(n,vs,ve,ms,me,dt,fs,fe)
because then the interpreter knows vs in the function arguments is the global one. But since you had vs in the left hand side, you created an uninitialized local variable.
But dude, you have a much bigger problem in your code:
update_r calls update_v, update_v calls force, and force calls update_r - you will get a stack overflow :)
I got that error when my class name was assigned to a variable that is called exactly like its name. example ClassName = ClassName. You may do this if you come from .Net
Related
Issue
I'm trying to call CAPL general functions (in my case timeNowNS) but I don't know if it's possible.
What I'm using?
I'm using Python 3.7 and Vector CANoe 11.0.
The connection is done using the .NET CANoe API.
This is how i've accesed the DLLs.
import clr
sys.path.append("C:\Program Files\Vector CANoe 11.0\Exec64") # path to CANoe DLL Files
clr.AddReference('Vector.CANoe.Interop') # add reference to .NET DLL file
import CANoe # import namespace from DLL file
What I've tried?
I opened the CANoe simulation succesfully, started the measure and I'm having access to signals, env variables and sys variables.
Then I've created the CAPL Object and tried using the GetFunction method to obtain the CAPLFunction object so i could call it.
def begin_can(self, sCfgFile, fPrjInitFunc = None):
self.open_can()
self.load_can_configuration(sCfgFile)
self.start_can_measurement(fPrjInitFunc)
def open_can(self):
self.mCANoeApp = CANoe.Application()
self.mCANoeMeasurement = CANoe.Measurement(self.mCANoeApp.Measurement)
self.mCANoeEnv = CANoe.Environment(self.mCANoeApp.Environment)
self.mCANoeBus = CANoe.Bus(self.mCANoeApp.get_Bus("CAN"))
self.mCANoeSys = CANoe.System(self.mCANoeApp.System)
self.mCANoeNamespaces = CANoe.Namespaces(self.mCANoeSys.Namespaces)
self.mCANoeCAPL = CANoe.CAPL(self.mCANoeApp.CAPL)
self.mCANoeCAPL.Compile()
def getFunction(self):
function1 = self.mCANoeCAPL.GetFunction('timeNowNS')
# here I tried also CANoe.CAPLFunction(self.mCANoeCAPL.GetFunction('timeNowNS'))
# but i got attribute error: doesn't exist or something like that
result = function1.Call()
Expected results
I should get the current simulation time using this function.
Actual results
Using the above code I get:
**COMException**: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
at CANoe.ICAPL5.GetFunction(String Name)
I've tried different variations of the code but didn't get anywhere.
Is it possible to be a hardware problem?
Should I do some settings in the CANoe Simulation?
If you need more information, please ask me! Thanks in advance
Update: I've added a photo of my measure setup after adding the CAPL block
You have to write a CAPL function in which you call timeNowNS. This CAPL function can then be called from Python in the way you have implemented.
GetFunction only works with (user-written) CAPL functions. You cannot call CAPL intrinsics (i.e. built-in CAPL functions) directly.
Put this into a CAPL file:
int MyFunc()
{
return timeNowNS();
}
and call like this from Python:
def getFunction(self):
function1 = self.mCANoeCAPL.GetFunction('MyFunc')
result = function1.Call()
After a long session of try and error and the help of #m-spiller I found the solution.
function2 = None
def open_can(self):
self.mCANoeApp = CANoe.Application()
self.mCANoeMeasurement = self.mCANoeApp.Measurement # change here: no cast necessary
self.mCANoeEnv = CANoe.Environment(self.mCANoeApp.Environment)
self.mCANoeBus = CANoe.Bus(self.mCANoeApp.get_Bus("CAN"))
self.mCANoeSys = CANoe.System(self.mCANoeApp.System)
self.mCANoeNamespaces = CANoe.Namespaces(self.mCANoeSys.Namespaces)
self.mCANoeCAPL = CANoe.CAPL(self.mCANoeApp.CAPL)
self.mCANoeMeasurement.OnInit += CANoe._IMeasurementEvents_OnInitEventHandler(self.OnInit)
# change here also: explained below
def OnInit(self):
global function2
function2 = CANoe.CAPLFunction(mCANoeCAPL.GetFunction('MyTime')) # cast here is necessary
def callFunction(self):
result = function2.Call()
What was the problem with the initial code?
The problem was that i tried to assign a function to a variable after the measure has started.
As stated here in chapter 2.7, the assignment of a CAPL Function to a variable can only be done in the OnInit event handler of the Measurement object.
I've added this line, studying the documentation:
self.mCANoeMeasurement.OnInit += CANoe._IMeasurementEvents_OnInitEventHandler(self.OnInit)
After adding it, on init the OnInit function was executed and the CAPL function was assigned to a variable and afterwards i could use that variable to call the function.
Thank you again, #m-spiller !
*I'm a Beginner...
My friend tried to help me a bit with this but I can't seem to solve it. I'm not really sure what to do so any help would be greatly appreciated.I get the following error in averageMPG,"name stats city is parameter and global".I also wasn't really sure how to write both functions in my readData function as you can see. The problem is in the picture. I haven't succeeded in part b so I haven't moved on,
def readData(carmodelData_city):
global stats_city,stats_hwy
infile=open("carModelData_city", 'r')
stats_city=[]
for s in infile.read.split():
stats.append(float(s))
return stats_city
def read_Data(carmodelData_hwy):
global stats_city,stats_hwy
infile=open("carModelData_hwy", 'r')
stats_hwy=[]
for s in infile.read.split():
stats.append(float(s))
return stats_hwy
def averageMPG(stats_city, stats_hwy):
global stats_city,stats_hwy
totals=sum(stats_city)
length=len(stats_city)
avg1=totals/length
print("The averge mpg city is", avg1)
totals1=sum(stats_hwy)
length1=len(stats_hwy)
avg2=totals/length
print("The average mpg highway is", avg2)
average=(avg1+avg2)/2
print("The combined averge mpg is", average)
def main():
global stats_city,stats_hwy
stats_city=readData("carModelData_city", "r")
stats_hwy=read_Data("carModelData_hwy", "r")
[enter image description here][1]main()
You named a function parameter stats_city, and also declared it a global value. Those two things are incompatible.
AFAICT, none of your code actually requires anything to be global in the first place, so stop declaring everything global, and you should be fine.
Well, fine on that specific error anyway. The massive overuse of global here feels an awful lot like cargo cult programming, and you have many other problems (e.g. infile.read.split() is going to try to split the read method of the file; you forgot parens, so it's not actually calling read to get data back). You're also returning at the end of the first iteration of each loop, when I suspect you want to finish the loops and return the accumulated values. You need to learn a lot more of the basics here; please talk to a professor or a tutor.
Also, your "stats.append()" calls should probably be "stats_city.append" in the first function and "stats_hwy.append" in the second. You will return after one iteration in each function unless you adjust your idents on the return call.
I am teaching myself Python and am trying out a challenge I found to create a quote program for a gardener. I have almost all of it working and have added in iteration so that the user can make more than one quote without re-starting the program.
It produces the quote perfectly the first time but on the second run it presents this error:
Traceback (most recent call last):
File "/Users/shaunrogers/Desktop/Plymstock Prep/GCSE CS/SOL/Controlled Assessment/Sample Papers Solutions/gardening Task 2.py", line 105, in <module>
lawn = m2_items("lawn",0)
File "/Users/shaunrogers/Desktop/Plymstock Prep/GCSE CS/SOL/Controlled Assessment/Sample Papers Solutions/gardening Task 2.py", line 23, in m2_items
minutes = area*time[index]
TypeError: 'float' object is not subscriptable
I have the following code as a function that is producing the error:
def m2_items (item,index):
global costs, time, LABOUR
length = int(input("How long is the "+ item+"?\n"))
width = int(input("How wide is the "+item+"?\n"))
area = length*width
cost_m2 = float(costs[index])
total_cost = area*cost_m2
minutes = area*time[index]
hours = int(minutes/60)
labour = LABOUR*hours
labour_cost=round(labour,2)
m2_details = [area, cost_m2, total_cost,hours, labour_cost]
return m2_details
I have tried re-setting the local variables on the running of the function (but I didn't think this was needed as the variables should be removed from memory once the function has run).
I hope the question is clear and that I can get some insight. To re-iterate, what I want the program to do is allow me to call this function multiple times.
You are using the global time variable, which is initially subscriptable (probably an array). As your program continues, some other part of your code will assign a new value to time, maybe accidentally because you wrote time = some_calculation() instead of time[i] = some_calculation(), or maybe you are using the name time somewhere else without realizing it's already in use.
Do a search for all the places where you use the name time and you will probably find your error.
This is a common problem with global variables. Sometimes something updates them from another part of the code, and the error will sneak up on you like this.
I'm fairly new to python and understand that recursion is an important concept to grasp. I've been dabbling with various scripts to exercise my knowledge and have come up with the following script to simulate a lottery draw, where you simply draw six from 49 numbers and compare them with another six to see if you've won. I'm struggling though with the recursive function taking the value of another function.
I'm sure it's going to be straightforwardish, but cannot fathom it myself.
Here's my code so far:
from random import randint
def drawSix():
six = []
while len(six) < 6:
a = randint(1,49)
if a not in six:
six.append(a)
return sorted(six)
def lottery(draw,ticket):
if draw == ticket:
return 'win'
return lottery(drawSix(),drawSix())
I call the function with lottery(drawSix(),drawSix())
and get the following recursively.
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
lottery(drawSix(),drawSix())
File "/Users/johnhopkins/Desktop/lottery.py", line 14, in lottery
return lottery(drawSix(),drawSix())
def lottery(draw,ticket):
if draw == ticket:
return 'win'
return lottery(drawSix(),drawSix())
The odds of you actually generating two identical tickets are quite large, well over 1000 which is the maximum stack size of Python.
You need to either do this iteratively to avoid blowing your stack.
def lottery(draw,ticket):
while draw != ticket:
draw, ticket = drawSix(), drawSix()
return "win"
Note this has a very ugly O(n) of O(inf) you could end up running this forever if you were unlucky and still not finding a winning pair
Well, your question has has been answered, but I would suggest changing your drawSix function. As it is now, it could technically run forever. random has a sample method to generate unique numbers.
def drawSix():
return sorted(random.sample(range(1, 50), 6))
Yes - the lottery function will keep on calling itself, each time putting a new version of itself onto the call stack, going deeper and deeper into itself until there are two matching numbers.
This can take a long time, and Python will eventually say "oi! stop it!" and crash.
Some programming languages have a feature called 'tail call optimisation', which means if you try to return the result of the same function, instead of making a new call to the function inside the current one, it simply replaces itself in the stack.
Python doesn't do that.
def lottery():
while (drawSix() != drawSix()):
continue
return 'win!'
will have the same effect as your recursive version, but won't die with recursion errors.
You have not made any programming mistakes. However, the probility of winning the lottery is very small, so you need to generate a lot. Easy recursion add something to the stack.
Number of lotto tickets can be found by the formula for combinations with repetition:
(49+6-1)! / (6! * (49-1)!) = 25827165
This is a lot... Decrease the number 6 or 49, add some debugging lines and you'll see that the code works fine!
I'm new to Python. I've been trying to familiarize myself with Numpy, Scipy, and Matplotlib, as I have a background in the sciences, and hope to make myself a more competitive candidate for work in neuroscience laboratories.
I've been browsing through the Matplotlib documentation, trying to learn by example. I will reference an example from the following URL: http://matplotlib.org/users/pyplot_tutorial.html
I am under the impression that these examples are written in Python 3.x, and that I am having trouble because I am using Python 2.7. I am using 2.7 because some of the libraries I wanted weren't available for 3.x.
The website gave an example of using subplots. Their code is as follows:
import numpy as np
import matplotlib.pyplot as plt
def f(t):
return np.exp(-t) * np.cos(2*np.pi*t)
t1 = np.arange(0.0, 5.0, 0.1)
t2 = np.arange(0.0, 5.0, 0.02)
plt.figure(1)
plt.subplot(211)
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')
plt.subplot(212)
plt.plot(t2, np.cos(2*np.pi*t2), 'r--')
This is supposed to return a Figure like this: http://i.stack.imgur.com/ejNDu.png
When I copy the same code into IDLE, it gives me an error. On the line
t1 = np.arange(0.0, 5.0, 0.1)
, IDLE tells me that "t1" is invalid syntax.
My first question: What is the problem with using t1 as a variable?
If I copy in similar code, but with a few things tweaked, I can avoid this error. However, I am then presented with another error. When I add the line equivalent to
plt.plot(t1, f(t1), 'bo', t2, f(t2), 'k')
, IDLE presents me with the error:
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
plt.plot(ty, f(tx), 'bo', ty, f(ty), 'k')
NameError: name 'f' is not defined
I'm not sure how Python expects me to define "f" separately from the function "f(t)".
My second and MAIN question: Could somebody please explain why "f" must be defined separately? How do I use functions like this correctly in Python 2.7?
If anybody needs me to explain the Numpy/Matplotlib mechanisms used here, I will do my best to explain how they work to bring about the graphs.
For the syntax error, check the line or two before. t1 is a perfectly valid variable name (the rules are similar to various other languages: variable names can contain letters, numbers and _, but can't start with a number) - but if you've forgotten a close bracket or similar above, then the interpreter will get confused and tell you you can't have an assignment statement there (newlines don't count as 'end of statement' if they're inside (), {} or [], or if the last character before the newline is \).
Defining a function does give you a variable in that namespace with that name - you don't need to define f separately. It is difficult to tell without seeing your exact code, but what has likely happened is either you have defined it in a different scope (so the name isn't visible), or you have renamed the function to something other than f.
Try typing everything again, in a new window. 'f' isn't supposed to be defined separately.
That error of invalid syntax seams to appear because the missing of a new line, and an unexpected indentation.
In the IDLE, after defining the function f(t) you have to press again <return> to finish the declaration of f(t) - putting an empty line after the declaration of f(t).
If you don't add that additional new line in the IDLE, you would get a syntax error because the unexpected indentation, and the definition of f(t) wouldn't be finished, so you also get the next error that says 'f' is not defined.