Issue with implementing sympy into newtons method - python

I was trying to make a calculator for newtons method given a function, I've got everything down except that I keep running into an issue when I'm trying to do log of a different base or ln(x).
I'd appreciate the help!
import sympy as sp
x = sp.symbols('x')
# ask for expression and initial guess
expression = input('input function: ')
initial = float(input('input an initial guess: '))
iterate = int(input('input how many times you want it to iterate: '))
# find derivative of function
f_prime = sp.diff(expression, x)
f = sp.lambdify(x, expression, 'numpy')
df = sp.lambdify(x, f_prime, 'numpy')
# newtons method rounded to 8 decimal places
for i in (1, iterate):
i = initial - (f(initial)/df(initial))
initial = round(i, 8)
print(f'The root is {initial} after {iterate} iterations')
Everytime I put in log of a different base it would give me
TypeError: return arrays must be of ArrayType or a name error
for ln(x) it would give me
AttributeError: 'Symbol' object has no attribute 'ln'. Did you mean: 'n'?

The output of your expression = input('input function: ') is of type string. Before creating f = sp.lambdify(...) you need to convert that expression into a symbolic expression. sympify is the command you need to use:
expression = sp.sympify(input('input function: '))

Related

User input in exponential function in Python3 returns nothing

I am just starting out with python3, and I'm trying to write a simple exponential function. Now, what I've written below does work, however, I want to change the code in such a way, that it would allow for user input and then give out the answer based on that input.
def raise_to_power(base_num, pow_num):
result = 1
for index in range(pow_num):
result = result*base_num
return result print(raise_to_power(2, 3))
print(raise_to_power(2, 3))
This is what my attempt at getting the new code to work looks like.
base_num = float(input("Enter base number: "))
pow_num = float(input("Enter power number"))
def raise_to_power(base_num, pow_num):
result = 1
for index in range(pow_num):
result = result*base_num
return result
print(raise_to_power)
However, I consistently get the following message as a result instead of an answer
<function raise_to_power at 0x7f8fe15baf70>
What do I do about this?
print(raise_to_power(base_num, pow_num))

'list' object is not callable, Trying to access an item in a list and assign it to an object

I am running code that is serving to balance chemical equations for general chemistry. The file that I'm running from contains this code:
from equation import Equation
from time import sleep
def run_balance():
# Runs the chemical equation balance algorithm
print('=================================================')
print('Insert chemical equation with elements in parentheses followed by the number of atoms:')
print('Example: (H)2 + (O)2 = (H)2(O)1')
user_input = str(input('>>> '))
try:
equation = Equation(user_input)
print('Balanced equation: ' + equation.balance())
sleep(3)
run_balance()
except IndexError:
print('Invalid input...')
sleep(3)
run_balance()
run_balance()
The file where the Equation class is located contains the following code:
class Equation:
# Create a class for chemical equations
def __init__(self, equation):
# Initialize equation into an object the code understands
self.left = list()
self.right = list()
self.balanced = True
integers = '0123456789'
split = equation.split(' = ')
left = split[0]
right = split[1]
left_components = left.split(' + ')
right_components = right.split(' + ')
total_left = dict()
total_right = dict()
When I give any input, I receive the following error:
14 integers = '0123456789'
15 split = equation.split(' = ')
---> 16 left = split[0]
17 right = split[1]
18 left_components = left.split(' + ')
TypeError: 'list' object is not callable
I'm confused as I understand this error normally comes from using parentheses when trying to access an item in a list, for which you would just change the parentheses to square brackets. However, I am trying to assign left as the first half of equation after splitting it. Any advice?
Your traceback doesn't make sense, probably for good reason. Try to find that reason.
Sometimes the problem in this situation is that you have an old .pyc file lying around from a previous version of the code. This can happen if e.g. you had an equation library, as well as a equation.py that got deleted at some point.

Get an expression as an input in python

I have an array of numbers that the user input. Now, I want the user to enter an expression (for example, sin (x)) and I want to evaluate the expression using the numbers from the array.
I don't know how to get the expression as an input from the user and then to evaluate it based on the array.
So far I have:
collection = list()
number = input("Enter the number of elements you want: ")
for i in range(int(number)):
n = input("Enter number:")
collection.append(int(n))
print ('ARRAY: ',collection)
def function_creator():
expr = input("Enter the function(in terms of x):")
x = int(input("Enter the value of x:"))
safe_dict['x'] = x
y = eval(expr, {"__builtins__":None}, safe_dict)
print("y = {}".format(y))
if __name__ == "__main__":
safe_list = ['acos', 'asin', 'atan', 'atan2', 'ceil', 'cos',
'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor',
'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10',
'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt',
'tan', 'tanh']
safe_dict = dict([(k, locals().get(k, None)) for k in safe_list])
function_creator()
I have tried getting the expression using the eval() function in python but couldn't get it to work. For the sake of working in steps, I'm not using the array right now as the x variable in the expression the user inputs. Instead, I'm just trying to evaluate the expression the user inputs with an x of their choice. Any ideas on how to make it work or any other way in which I can get the function as an input?
This code should work for expressions in x such as x*sin(x) + (x+1)*exp(2*x)
from math import * # import sin, cos, tan, etc. into globals
# to allow use by eval
def function_creator(arr):
" allows expressions such as x*sin(x) + x "
expr = input("Enter the function(in terms of x):")
# x is bound locally inside the list comprehension for use by eval
return [eval(expr) for x in arr] # compute expression on each data element
if __name__ == "__main__":
collection = list()
number = input("Enter the number of elements you want: ")
for i in range(int(number)):
n = input("Enter number:")
collection.append(float(n))
print ('ARRAY: ',collection)
result = function_creator(collection)
print(result)
Simple answer
You can import functions into the global scope, and then grab them from globals as follows:
from numpy import sin
collection = list()
number = input("Enter the number of elements you want: ")
for i in range(int(number)):
n = input("Enter number:")
collection.append(int(n))
print ('ARRAY: ',collection)
func_name = input("Enter function: ")
try:
ans = globals()[func_name](collection)
except KeyError:
raise AttributeError('Function not found in namespace!')
print(ans)
Slightly more sophisticated answer
You can try the following code snippet:
import numpy as np
collection = list()
number = input("Enter the number of elements you want: ")
for i in range(int(number)):
n = input("Enter number:")
collection.append(int(n))
print ('ARRAY: ',collection)
func_name = input("Enter function: ")
def getattr_loop(obj,attr):
'''getattr, or getitem, or error, in a loop, forever!'''
spl = attr.split('.')
if len(spl) > 1:
try:
return getattr_loop(getattr(obj,spl[0]),'.'.join(spl[1:]))
except AttributeError as err:
try:
return getattr_loop(obj[spl[0]],'.'.join(spl[1:]))
except KeyError:
raise err
else:
return getattr(obj,spl[0])
# Compute using user defined function
try:
ans = getattr_loop(globals(),func_name)(collection)
except AttributeError:
raise AttributeError('Function not found in namespace!')
print(ans)
getattr_loop is a function which will recursively search obj for attribute attr. The attribute given by attr automatically reads dot notation, and so you can use it to do some nifty tricks. It also has some handling to attempt .__getitem__() if there is no attribute (obj[attr])
The downside is that getattr_loop will give you a RecursionError if you have a really deeply nested attribute in obj.
For example, if one uses the Numpy module as the object:
>>> getattr_loop(np,'random.rand')
This would allow you to access np.random.rand. If you use globals() as is used in the code snippet, it will grab all objects defined at the global scope. So, a user of the above code snippet can type 'np.sin' as the function, and the code will compute np.sin(collection).
If you wish to use sin directly, you'll need to import that directly into the namespace.
Caveat about security
Grabbing things from globals() can be risky from a security perspective. If you need this to be secure, make sure to:
sanitise your inputs
construct an object which only contains the functions that you want someone to be able to access, lest you accidentally allow someone to patch into something like os.remove and do some harm...
Enjoy!

how to convert string to float in python?

I wrote a function that inputs a string expression and i want to split the expression and use some of the content as float. i tried writing num1 = float(temp[0])
but i got an error message saying i cant convert string to float.
How can i do that in python?
Here is the part of my code:
def calculate_from_string(expression):
temp = expression.split(" ")
num1 = float(int(temp[0]))
num2 = float(int(temp[1]))
oop = temp[2]
return calculate_mathematical_expression(num1, num2, oop)
The type of expression is string.
i tried converting it this way but it didn't work on the tester i was using because i got a message that it is an invalid expression. Does anyone know how i can do it?
It would be good if you provided a snippet of your data to us.
I don't know what you were doing but this should work (and it does for me):
str_expression = '1 57 34'
num = [float(i) for i in str_expression.split()]
you could also use a numpy array:
import numpy as np
nums = np.array(str_expression.split(), dtype=np.float)
If your expression contains some alphanumerics, you can just use regular expressions to extract the numbers.
For example:
str_expression = 'bdjsbd bdka2 23 (34 >> 4) * 2ds'
the right way to extract the numbers would be:
import re
nums = [float(i) for i in re.findall('\d+', str_expression)]
def calculate_from_string(expression):
temp = expression.split(" ")
num1 = float(temp[0])
num2 = float(temp[1])
oop = temp[2]
return calculate_mathematical_expression(num1, num2, oop)
float( int( "123.45" ) ) will raise ValueError since int expect [0-9]+ but you have . in the string, which will raise value error.
2nd point if you will call int(4.5) then it will give you 4, so be careful when using int function.
But you can use float(int(string)) if your input string doesn't contain . e.g. float(int("1234")) which will give you 1234.0

Can't figure out this filter() recursion error

The problem is I have to write a program which takes in a list of words and an integer and returns the words whose length is longer than that integer. I have to use filter() only.
This is what I wrote :
def filter(list,integer):
largenum = list(filter(lambda x: len(x) > integer, list ))
return largenum
inp = input("Enter the words: ").split()
intr = input("Enter the integer: ").split()
print (filter(inp,intr))
When I run this and give the inputs, it gives an error:
Runtime error: Maximum recursion depth exceeded.
What am I doing wrong?
edit: I got it. Such a silly mistake(s) XD.
1.) I changed filter(list,integet) to filterthis(string,integer)
2.) intr = input("Enter the integer: ").split() to intr = int(input("Enter the integer: ")
You are passing integer as list.So use integer[0].Then input returns str.So use int(integer[0]).
Then you are using filter as your function name.So this will override the builtin function filter.Also you are passing your list as variable list.It will also override the builtin callable list.You can try this
def myfilter(mylist,integer):
largenum = list(filter(lambda x: len(x) > int(integer[0]), mylist ))
return largenum
inp = input("Enter the words: ").split()
intr = input("Enter the integer: ").split()
>>>print(myfilter(inp,intr))
You have written filter function which calls itself without a base case.
Rename your filter function.
In [8]: def my_filter(l, i):
...: largenum = filter(lambda x: len(x)> i, l) # if python3, use list(filter)
...: return largenum
...:
In [9]: inp = ["LOL", "DA", "YAYASTRING"]
In [10]: intr = 2
In [11]: my_filter(inp, intr)
Out[11]: ['LOL', 'YAYASTRING']
Your version of filter will shadow the python built-in which has the same name. So when you make a call to it from inside your filter, it's not really to the built-in you are intending to call, but to your function itself. Since there is no stopping rule for the recursion, it ends up exceeding permissible stack depth.
Same goes for list. The function argument with the same name will shadow the builtin python list container.
Also, you'll need to cast the second argument to int before passing it to the function.
For code:
def fil(lst, integer):
return filter(lambda x: len(x) > integer, lst)
>>> fil(['Hello', 'how', 'are', 'you', 'doin'], 3)
['Hello', 'doin']

Categories