Calculation problem in a function in Python - python

I'm trying to calculate something in a function with numbers from an imported list.
def calculate_powers(velocities_list):
power_list = []
for i in velocities_list:
power = 8/27 * 1.225 * i * 8659
power_list.append(power)
print(power_list)
However, I get the following error:
File "C:\Users\Omistaja\PycharmProjects\7_1\wind_turbine.py", line 6, in calculate_powers
power = 8/27 * 1.225 * i * 8659
TypeError: can't multiply sequence by non-int of type 'float'
What to do?

try this :
def calculate_powers(velocities_list):
power_list = []
for i in velocities_list:
power = float(8/27) * 1.225 * float(i) * float(8659)
power_list.append(power)
print(power_list)

your variable 'i' is probably string, you need to cenvert it to number(float or int,..)
power = 8/27 * 1.225 * float(i) * 8659
can you provide example of your velocities_list?

Related

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.

Simple python histogram

result1 = ["Progress","Progress(MT)","ModuleRT","Exclude"]
result2 = [3,4,3,5]
def histogram (list1,list2):
for i in range (len(list1)):
print(list1[i])
for j in range (list2[i]):
print("","*")
histogram(result1,result2)
I'm trying to get the output like this, but I can't seem to get that.
Progress Progress(MT) ModuleRT Excluded
* * * *
*
Using center(), you can build the columns with the width corresponding to their respective title size. The histogram itself will need as many lines as the maximum value in result2. Each column should only print a star if the line index is less than the corresponding value.
result1 = ["Progress","Progress(MT)","ModuleRT","Exclude"]
result2 = [3,4,3,5]
print(*result1)
for i in range(max(result2)):
print(*( " *"[i<r].center(len(t)) for t,r in zip(result1,result2)))
Progress Progress(MT) ModuleRT Exclude
* * * *
* * * *
* * * *
* *
*
The histogram would look better if the columns were above the titles. You can do this by simply reversing the order of the line index:
for i in reversed(range(max(result2))):
print(*( " *"[i<r].center(len(t)) for t,r in zip(result1,result2)))
print(*result1)
*
* *
* * * *
* * * *
* * * *
Progress Progress(MT) ModuleRT Exclude
Converted to a function:
def histogram(titles,values):
print(*titles)
for i in range(max(values)):
print(*( " *"[i<v].center(len(t)) for t,v in zip(titles,values)))
Hello Alex and welcome on the Stackoverflow
I assume that, you want to get something like this below:
Progress * * *
Progress(MT) * * * *
ModuleRT * * *
Exclude * * * * *
Then, you have to modify your code, so that the print method does not add a new line after every * printed. To do so, you use end argument and set it to an empty character, like this: print("some string", end='')
So your new code would be:
result1 = ["Progress","Progress(MT)","ModuleRT","Exclude"]
result2 = [3,4,3,5]
def histogram (list1,list2):
for i in range (len(list1)):
print(list1[i], end='') # here is the end added
for j in range (list2[i]):
print("","*", end='') # here is the end added
histogram(result1,result2)
Nevertheless, it won't end-up in something like this:
Progress * * *Progress(MT) * * * *ModuleRT * * *Exclude * * * * *
The thing is, that there's no new line character after first outer for loop iteration. So you print a new line with an empty print at the end of the outer loop like this print("").
So finally your code would look like this:
result1 = ["Progress","Progress(MT)","ModuleRT","Exclude"]
result2 = [3,4,3,5]
def histogram (list1,list2):
for i in range (len(list1)):
print(list1[i], end='')
for j in range (list2[i]):
print("","*", end='')
print("") # here is the print
histogram(result1,result2)

Fraction Value Problem in Ctypes to PARI/GP

I have written a code to compare the solution of sympy and PARI/GP, but when I give a fraction value D=13/12, I get error, TypeError: int expected instead of float.
So I changed p1[i] = pari.stoi(c_long(numbers[i - 1])) to p1[i] = pari.stoi(c_float(numbers[i - 1])), but then nfroots gives no output, note that I have to use fraction in A, B, C, D which might take $10^10$ digits after decimal point.
How can I solve this problem?
The code is given below to download the libpari.dll file, click here -
from ctypes import *
from sympy.solvers import solve
from sympy import Symbol
pari = cdll.LoadLibrary("libpari.dll")
pari.stoi.restype = POINTER(c_long)
pari.cgetg.restype = POINTER(POINTER(c_long))
pari.gtopoly.restype = POINTER(c_long)
pari.nfroots.restype = POINTER(POINTER(c_long))
(t_VEC, t_COL, t_MAT) = (17, 18, 19) # incomplete
pari.pari_init(2 ** 19, 0)
def t_vec(numbers):
l = len(numbers) + 1
p1 = pari.cgetg(c_long(l), c_long(t_VEC))
for i in range(1, l):
#Changed c_long to c_float, but got no output
p1[i] = pari.stoi(c_long(numbers[i - 1]))
return p1
def Quartic_Comparison():
x = Symbol('x')
a=0;A=0;B=1;C=-7;D=13/12 #PROBLEM 1
solution=solve(a*x**4+A*x**3+B*x**2+ C*x + D, x)
print(solution)
V=(A,B,C,D)
P = pari.gtopoly(t_vec(V), c_long(-1))
res = pari.nfroots(None, P)
print("elements as long (only if of type t_INT): ")
for i in range(1, pari.glength(res) + 1):
print(pari.itos(res[i]))
return res #PROBLEM 2
f=Quartic_Comparison()
print(f)
The error is -
[0.158343724039430, 6.84165627596057]
Traceback (most recent call last):
File "C:\Users\Desktop\PARI Function ellisdivisible - Copy.py", line 40, in <module>
f=Quartic_Comparison()
File "C:\Users\Desktop\PARI Function ellisdivisible - Copy.py", line 32, in Quartic_Comparison
P = pari.gtopoly(t_vec(V), c_long(-1))
File "C:\Users\Desktop\PARI Function ellisdivisible - Copy.py", line 20, in t_vec
p1[i] = pari.stoi(c_long(numbers[i - 1]))
TypeError: int expected instead of float
The PARI/C type system is very powerful and can also work with user-defined precision. Therefore PARI/C needs to use its own types system, see e.g. Implementation of the PARI types https://pari.math.u-bordeaux.fr/pub/pari/manuals/2.7.6/libpari.pdf.
All these internal types are handled as pointer to long in the PARI/C world. Don't be fooled by this, but the type has nothing to do with long. It is perhaps best thought of as an index or handle, representing a variable whose internal representation is hidden from the caller.
So whenever switching between PARI/C world and Python you need to convert types.
Conversion are described e.g. in section 4.4.6 in the above mentioned PDF file.
To convert a double to the corresponding PARI type (= t_REAL) one would therefore call the conversion function dbltor.
With the definition of
pari.dbltor.restype = POINTER(c_long)
pari.dbltor.argtypes = (c_double,)
one could get a PARI vector (t_VEC) like this:
def t_vec(numbers):
l = len(numbers) + 1
p1 = pari.cgetg(c_long(l), c_long(t_VEC))
for i in range(1, l):
p1[i] = pari.dbltor(numbers[i - 1])
return p1
User-defined Precision
But the type Python type double has limited precision (search e.g. for floating point precision on stackoverflow).
Therefore if you want to work with defined precision I would recommend to use gdiv.
Define it e.g. like so:
V = (pari.stoi(A), pari.stoi(B), pari.stoi(C), pari.gdiv(pari.stoi(13), pari.stoi(12)))
and adjust t_vec accordingly, to get a vector of these PARI numbers:
def t_vec(numbers):
l = len(numbers) + 1
p1 = pari.cgetg(c_long(l), c_long(t_VEC))
for i in range(1, l):
p1[i] = numbers[i - 1]
return p1
You then need to use realroots to calculate the roots in this case, see https://pari.math.u-bordeaux.fr/dochtml/html-stable/Polynomials_and_power_series.html#polrootsreal.
You could likewise use rtodbl to convert a PARI type t_REAL back to a double. But the same applies, since with using a floating point number you would loose precision. One solution here could be to convert the result to a string and display the list with the strings in the output.
Python Program
A self-contained Python program that considers the above points might look like this:
from ctypes import *
from sympy.solvers import solve
from sympy import Symbol
pari = cdll.LoadLibrary("libpari.so")
pari.stoi.restype = POINTER(c_long)
pari.stoi.argtypes = (c_long,)
pari.cgetg.restype = POINTER(POINTER(c_long))
pari.cgetg.argtypes = (c_long, c_long)
pari.gtopoly.restype = POINTER(c_long)
pari.gtopoly.argtypes = (POINTER(POINTER(c_long)), c_long)
pari.dbltor.restype = POINTER(c_long)
pari.dbltor.argtypes = (c_double,)
pari.rtodbl.restype = c_double
pari.rtodbl.argtypes = (POINTER(c_long),)
pari.realroots.restype = POINTER(POINTER(c_long))
pari.realroots.argtypes = (POINTER(c_long), POINTER(POINTER(c_long)), c_long)
pari.GENtostr.restype = c_char_p
pari.GENtostr.argtypes = (POINTER(c_long),)
pari.gdiv.restype = POINTER(c_long)
pari.gdiv.argtypes = (POINTER(c_long), POINTER(c_long))
(t_VEC, t_COL, t_MAT) = (17, 18, 19) # incomplete
precision = c_long(38)
pari.pari_init(2 ** 19, 0)
def t_vec(numbers):
l = len(numbers) + 1
p1 = pari.cgetg(c_long(l), c_long(t_VEC))
for i in range(1, l):
p1[i] = numbers[i - 1]
return p1
def quartic_comparison():
x = Symbol('x')
a = 0
A = 0
B = 1
C = -7
D = 13 / 12
solution = solve(a * x ** 4 + A * x ** 3 + B * x ** 2 + C * x + D, x)
print(f"sympy: {solution}")
V = (pari.stoi(A), pari.stoi(B), pari.stoi(C), pari.gdiv(pari.stoi(13), pari.stoi(12)))
P = pari.gtopoly(t_vec(V), -1)
roots = pari.realroots(P, None, precision)
res = []
for i in range(1, pari.glength(roots) + 1):
res.append(pari.GENtostr(roots[i]).decode("utf-8")) #res.append(pari.rtodbl(roots[i]))
return res
f = quartic_comparison()
print(f"PARI: {f}")
Test
The output on the console would look like:
sympy: [0.158343724039430, 6.84165627596057]
PARI: ['0.15834372403942977487354358292473161327', '6.8416562759605702251264564170752683867']
Side Note
Not really asked in the question, but just in case you want to avoid 13/12 you could transform your formula from
to

Unable to fix a 'float' object is not callable error

I keep getting the error: TypeError: 'float' object is not callable on this section of code.
for data in list:
latitude = float(data[1])
longitude = float(data[2])
distance = ((6371*math.pi)/180)(math.sqrt((-35.276159-latitude)**2+(149.120893-longitude)**2))
print(distance)
When I print the type of latitude and longitude, they both return 'float'. Any help with what I could be doing wrong would be much appreciated!
You are iterating over your sequence and are calling the item data; this got you confused that data is the sequence.
You are also missing an operator between two expressions in parenthesis: distance = ((6371 * math.pi) / 180) MISSING OPERATOR HERE (math.sqrt((-35.276159 - latitude) ** 2 + (149.120893 - longitude) ** 2)) - this corresponds to (float)(float) after partial evaluation, which is attempting to call a float.
for item in seq:
latitude = float(item)
longitude = float(item)
distance = ((6371 * math.pi) / 180)**2 + (math.sqrt((-35.276159 - latitude) ** 2 + (149.120893 - longitude) ** 2))
print(distance)
Note:
Please do not use python keywords (list) to name variables.

Non-sequential substitution in SymPy

I'm trying to use [SymPy][1] to substitute multiple terms in an expression at the same time. I tried the [subs function][2] with a dictionary as parameter, but found out that it substitutes sequentially.
In : a.subs({a:b, b:c})
Out: c
The problem is the first substitution resulted in a term that can be substituted by the second substitution, but it should not (for my cause).
Any idea on how to perform the substitutions simultaneously, without them interfering with each other?
Edit:
This is a real example
In [1]: I_x, I_y, I_z = Symbol("I_x"), Symbol("I_y"), Symbol("I_z")
In [2]: S_x, S_y, S_z = Symbol("S_x"), Symbol("S_y"), Symbol("S_z")
In [3]: J_is = Symbol("J_IS")
In [4]: t = Symbol("t")
In [5]: substitutions = (
(2 * I_x * S_z, 2 * I_x * S_z * cos(2 * pi * J_is * t) + I_y * sin(2 * pi * J_is * t)),
(I_x, I_x * cos(2 * pi * J_is * t) + 2 * I_x * S_z * sin(2 * pi * J_is * t)),
(I_y, I_y * cos(2 * pi * J_is * t) - 2 * I_x * S_z * sin(2 * pi * J_is * t))
)
In [6]: (2 * I_x * S_z).subs(substitutions)
Out[7]: (I_y*cos(2*pi*J_IS*t) - 2*I_x*S_z*sin(2*pi*J_IS*t))*sin(2*pi*J_IS*t) + 2*S_z*(I_x*cos(2*pi*J_IS*t) + 2*I_x*S_z*sin(2*pi*J_IS*t))*cos(2*pi*J_IS*t)
Only the appropriate substitution should happen, in this case only the first one. So the expected output should be the following:
In [6]: (2 * I_x * S_z).subs(substitutions)
Out[7]: I_y*sin(2*pi*J_IS*t) + 2*I_x*S_z*cos(2*pi*J_IS*t)
The current version of sympy provides the keyword simultaneous. The complicated operations in the previous answers are no more necessary:
In [1]: (x*sin(y)).subs([(x,y),(y,x)],simultaneous=True)
Out[1]: y⋅sin(x)
The subs(self,*args) method is defined (in part) this way:
In [11]: x.subs??
...
sequence = args[0]
if isinstance(sequence, dict):
return self._subs_dict(sequence)
elif isinstance(sequence, (list, tuple)):
return self._subs_list(sequence)
If you pass subs a dict, you lose control over the order of the substitutions.
While if you pass subs a list or tuple, you can control the order.
This doesn't allow you to do simultaneous substitutions. That would lead to difficulties if the user were to pass stuff like x.subs([(x,y),(y,x)]). So I doubt sympy has a method for doing simultaneous substitutions. Instead I believe all substutions are either unordered (if you pass a dict) or, at best, done by a 1-pass ordered substitution (if you pass a list or tuple):
In [17]: x.subs([(x,y),(y,z)])
Out[18]: z
In [19]: x.subs([(y,z),(x,y)])
Out[19]: y
PS. _subs_list(self, sequence) is defined (in part) like this:
In [14]: x._subs_list??
...
for old, new in sequence:
result = result.subs(old, new)
This nails down the order in which the subs are done.
Example for #~unutbu's answer:
>>> import ordereddict # collections.OrderedDict in Python 2.7+
>>> from sympy import *
>>> x,y,z = symbols('xyz')
>>> x.subs(ordereddict.OrderedDict([(x,y),(y,z)]))
y
>>> x.subs(ordereddict.OrderedDict([(y,z),(x,y)]))
z
Answering the edited question.
In your example you can use some temporary variables which will not be over-written be subsequent substitutions. Then, once all of the potentially overlapping substitutions have been made, you can replace the temporary variables with the real ones.
This example works for the question, if your full problem contains more complex substitutions, I think you should still be able to create temporary variables to avoid overlapping substitutions.
from sympy import Symbol, sin, cos, pi
I_x, I_y, I_z = Symbol("I_x"), Symbol("I_y"), Symbol("I_z")
S_x, S_y, S_z = Symbol("S_x"), Symbol("S_y"), Symbol("S_z")
J_is = Symbol("J_IS")
t = Symbol("t")
I_x_temp, I_y_temp, I_z_temp = Symbol("I_x_temp"), Symbol("I_y_temp"), Symbol("I_z_temp")
f = 2*I_x*S_z
answer = I_y*sin(2*pi*J_is*t) + 2*I_x*S_z*cos(2*pi*J_is*t)
subs1a = [
(2*I_x*S_z, 2*I_x_temp*S_z*cos(2*pi*J_is*t) + I_y_temp*sin(2*pi*J_is*t)),
(I_x, I_x_temp*cos(2* pi*J_is*t) + 2*I_x_temp*S_z*sin(2*pi*J_is*t)),
(I_y, I_y_temp*cos(2*pi*J_is*t) - 2*I_x_temp*S_z* sin(2*pi*J_is*t))
]
subs_temp = [(I_x_temp, I_x), (I_y_temp, I_y), (I_z_temp, I_z)]
print f
f = f.subs(subs1a)
print f
f = f.subs(subs_temp)
print f
print f == answer # True
Note, you can also perform two substitutions back to back:
f.subs(subs1a).subs(subs_temp) == answer
The Keyword simultaneous will do non-clashing subs regardless of the input (dict or sequence):
>>> x.subs([(x,y),(y,z)],simultaneous=1)
y
>>> x.subs([(y,z),(x,y)],simultaneous=1)
y

Categories