Python - Define a function based on user's input - python

I have a function taking a function and a float as inputs, for example
def func_2(func, x):
return func(x)
If a function is defined in advance, such as
def func_1(x):
return x**3
then the following call works nicely
func_2(func_1,3)
Now, I would like the user to be able to input the function to be passed as an argument to func_2.
A naive attempt such as
print("enter a function")
inpo = input()
user types e.g. x**3
func_2(inpo)
returns an error as a string is not callable.
At the moment I have a workaround allowing user to only input coefficients of polynomials, as in the following toy example
def funcfoo (x,a):
return x**a
print("enter a coefficient")
inpo = input()
funcfoo(3,int(inpo))
it works as I convert the input string to an integer, which is what the function call expects.
What is the the correct type to convert the input function, to work as first argument of func_2 ?

I think you're looking for the eval() function. This will change a string to a function.
For instance:
x = 3
string = 'x + 3'
eval(string)
# Returns 6
This does require you to modify your initial function a bit. This would work:
def func_2(func, x):
func_new = func.replace('x', str(x))
return eval(func_new)
inpo = 'x + 3'
func_2(inpo, 3)

Related

How can I call a lambda without defining it as a function?

For lambda functions in the following code,
def myfunc(n):
return lambda a : a * n
mydoubler = myfunc(2)
print(mydoubler(11))
I am trying to understand why mydoubler becomes <class 'function'> and how I can call mydoubler(11) without defining it as a function.
A lambda is a function, but with only one expression (line of code).
That expression is executed when the function is called, and the result is returned.
So the equivalent of this lambda:
double = lambda x: x * 2
is this def function:
def double(x):
return x * 2
You can read more here
A lambda is a function, so your code is doing something like
def myfunc(n):
def result(a):
return a * n
return result # returns a function
mydoubler = myfunc(2)
print(f(11))
You're asking how to call mydoubler without defining it as a function, which isn't the clearest question, but you can call it without naming it like so
print( myfunc(2)(11) )
Your myfunc is returning a lambda. Lambda is a small anonymous function. A lambda can take any number of arguments, but can only have one expression.
So after execution of the 3rd line, your mydoubler will become a lambda that's why when you try print(type(mydoubler)) it will return <class 'function'>.
Also in order to call mydoubler with 11, it must be function.
A lambda expression, like a def statement, defines functions. Your code could be equivalently written as
def myfunc(n):
def _(a):
return a * n
return _
mydoubler = myfunc(2)
print(mydoubler(11))
Because the inner function is simple enough to be defined as a single expression, using a lambda expression saves you the trouble of coming up with the otherwise unused name the def statement requires.
The key here is that the inner function closes over the value of n, so that the function returned by myfunc retains a reference to the value of the argument passed to myfunc. That is, mydoubler is hard-coded to multiply its argument by 2, rather than whatever value n may get later. (Indeed, the purpose of the closure is to create a new variable n used by the inner function, one which cannot easily be changed from outside myfunc.)
using decorator you can achive this
from functools import wraps
def decorator_func_with_args(arg1):
def decorator(f):
#wraps(f)
def wrapper(val):
result = f(val)
return result(arg1)
return wrapper
return decorator
#decorator_func_with_args(arg1=2)
def myfunc(n):
return lambda arg:arg*n
result = myfunc(1211)
print(result)
output
2422
Do you mean this?
mydoubler = lambda a : a * 2
mydoubler(11)

Understanding Nested functions in python

I am new in stackflow. I will so thankful if someone can help me.
I have to resolve this:
Define a nested function called nested_sum, where in the first part of the function you accept an argument called x, and in the second part (the function inside) you take another argument called y. In the function inside you have to calculate the sum of x and y.
To test your function create a variable called res_1 where you pass the x argument to nested_sum, and then create a variable called res_2 where you pass the y argument of the res_1 variable to get the final solution.
Have x equal 2 for res_1 and y equal 10 for res_2.
After looking on the internet I found a similar code, but I don't really understand how it works!
def nested_sum(x):
def in_sum(y):
return x+y
return in_sum
res_1 = nested_sum(2)
res_2 = res_1(10)
Thank you
First of all you need to realise res_1 is simply the in_sum() function.
Therefore as per your code:
nested_sum(2) puts x = 2 and then returns the in_sum() function.
res_2 = res_1(10) = in_sum(10)
Therefore x = 2 and y = 10, so thus
x + y = 2 + 10 = 12
You can write the code (easier to understand) as follows:
def nested_sum(x):
def in_sum(y):
return x+y
return in_sum
res_1 = nested_sum(2) #nested_sum return in_sum(y) location with x=2 so --> res_1= in_sum (2+y)
res_2 = res_1(10) #Cause res_1 points in_sum(2+y) res2=in_sum(2+10)=12
First of all, function in Python is an object. Think of it as a piece of paper where it is written what arguments it needs an what to do with them.
nested_sum(2) creates a new piece of paper where it is writen: «take the 𝑦 argument, add 2 to and return it.»
nested_sum(𝑥) creates a new piece of paper where it is writen: «take the 𝑦 argument, add 𝑥 and return it.»
Let me rename variables in your code:
def increaser_function_maker(x):
def the_new_function(y):
return x + y
return the_new_function
function_that_takes_number_and_adds_two_to_it = increaser_function_maker(2)
result = function_that_takes_number_and_adds_two_to_it(10)
There is another way to make this function. Maybe it will be easier to understand:
def increaser_function_maker(value_to_add):
return lambda i: i + value_to_add

IVT Theorem Calculator in Python

I am having a problem.
def f(x):
function = input("Enter yoru Function: ")
return function
a = -1
b = 2
a_Applied = f(a)
b_Applied = f(b)
if a_Applied < 0 and b_Applied > 0:
print "IVT Applies."
elif a_Applied > 0 and b_Applied < 0:
print "IVT Applies"
else:
print "IVT Does Not Apply"
This is my current code. I am trying to let the user make a function in line 2. However this breaks the program because it is a string. How do I get it to not be a string, and instead for it to be able to take a function.
Ex.
User inputs "2*x + 1"
In a perfect world the program then runs 2(a) +1 and 2(b) + 1 and then compares them using the if statement. Because the input is a string ti doesn't work.
Any help?
Use lambda expression and eval function. Like this.
def read_user_function():
function_str = input("Enter your Function: ")
return lambda x: eval(function_str, { 'x' : x })
Call user function by
f = read_user_function()
print(f(2))
Here is a demo https://repl.it/ITuU/2.
Explanation
The function above, read_user_function returns a lambda expression, basically a function, that will evaluate the user's input with the variable, sort of like a parameter, x set to the x value that is passed to the lambda expression. This can get confusing if your new to this sort of thing but just think of read_user_function as returning an anonymous function that accepts a single argument and its body equals eval(function_str, { 'x' : x })
Warning
This is a quick and dirty solution to evaluating mathematical expression. The function would execute any valid python code and not only mathematical expression. This may be dangerous if your application is sensitive - you wouldn't want the user executing custom code.
What you're asking to do is very hard (in general). You'd need to define rigorous semantics for all your supported operations (for example, is power ^ or is it ** like you'd do in python?).
The sympy library has a start on this for you. If you assume your input is a polynomial, for example:
import sympy
y = sympy.Poly("x^2 + 2*x + 1")
print(y(3))
# outputs 16
sympy also has the advantage that it will accept "python-like" input as well:
import sympy
y = sympy.Poly("x**2 + 2*x + 1")
print(y(3))
Note that sympy is not limited to polynomials, just included them here as an example because polynomials are relatively simple.

Missing Required Positional Arguments in Python

below is my an example of what i am trying to do in my code...
def func():
x = int (input ('enter x: '))
return x
def func2():
y = int (input( 'enter y: '))
return y
def func3(x,y):
print(randomint(x,y))
def main():
func()
func2()
func3()
main()
What i am wondering is, why cant i use the x and y variables that i have defined via input and returned at the end of my functions? When this program tries to run it says the functions are missing required arguments. Silly i know, i am new to python.
furthermore, how can i use variable in one function i am creating, that were defined within another separate function? thanks!
You stated that you know how to indent so I'm not going to discuss that, the problem at hand is that you will need to catch the return value from func and func2 after they are caught.
You can do so like this:
def func():
x = int (input ('enter x: '))
return x
def func2():
y = int (input( 'enter y: '))
return y
def func3(x,y): # there's two positional value so you will need to pass two values to it when calling
print(randomint(x,y))
def main():
x = func() # catch the x
y = func2() # catch the y
func3(x,y) # pass along x and y which acts as the two positional values
# if you're lazy, you can directly do:
# func3(func(), func2()) which passes the return values directly to func3
main()
Another method is to use the global statement, but that isn't the best way for your case.
Just a hint: if you are using the random module, the random integer is called by: random.randint(x,y)
Your variables only live within the functions, there is no way for func3 to get x and y, but you have defined x and y as parameters. So far you're just not passing them in. The following should do.
def func():
x = int (input ('enter x: '))
return x
def func2():
y = int (input( 'enter y: '))
return y
def func3(x,y):
print(randomint(x,y))
def main():
x_val = func()
y_val = func2()
func3(x_val, y_val)
main()
Or just like this, if you don't want to use variables.
Just remember, same name doesn't mean it's the same variable. The scope can be different (method, function, elsewhere), and the name makes the variable unique ("the same") withhin the same scope. That is similar across all higher programming languages, but also, scopes can intersect, and in different ways. So that reuse example above, might, for example work in JavaScript.
This is probably closest to what you attempted to achieve:
def inX():
return int (input ('enter x: '))
def inY():
return int (input( 'enter y: '))
def PrintRand(x,y):
print(randomint(x,y))
def main():
PrintRand(InX(),InY()) # is probably closest to what you attempted to do.
main()
note that those slight renames do not have an effect other than understanding the code, but good names of methods telling what they actually do, are very important. You read the code many more times. You write it once.

python calling function twice one after another but second storing value from first

I am using python so can someone tell me how to call same function twice in python but when you call it the second time it should be changed an already have value stored in it when you called the function the first time, so I basically mean you are calling the function first time and right after that you are calling it again but with the return value from the first time you called that function.
Assuming you have a function that has both a parameter and a return value:
def myFunction(input):
# do something with input
return input
To have a second instance of the function use the result of the first instance, you can simply nest the functions:
result = myFunction(myFunction(value))
you can create function that will apply n-times
def multf(f, n, x):
if n == 0:
return x
return multf(f, n-1, f(x))
so here we apply lambda sqr 3 times, it becomes f(f(f(x)))
sqr = lambda x: x**2
print(multf(sqr,3,2))
256

Categories