Define a function using string variable - python

I am trying to create a function "a21" that takes a parameter x and adds 4 to it.
eq = 'x+4'
b=21
new='a'+str(b)+'(x)'
def eval(new):
return eval(eq)
c=5
print(a21(c))
The desired output is 9 but it's not recognizing a21 as a function. How do I write this to create a the function a21 that also takes a parameter x?

Write a fully-featured function definition:
new = '''
def a21(x):
return x + 4
'''
And then execute it: exec(new) and run: a21(678).
If you want to construct a function during runtime, use string formatting.
new = '''
def {}({}):
return {}
'''
exec(new.format('test', 'x', 'x+4'))
test(123)

The following is possible and does almost the same thing:
You can bind the function in a function like below.
eq = 'x+4'
def bindfunc(name):
def dynamicfunc(x):
return eval(eq)
dynamicfunc.__name__ = name
return dynamicfunc
The way you would use this would be a little different:
b=21
new='a'+str(b) #your function name
c=5
print(bindfunc(new)(c))
What the last line does is that it first runs bindfunc which returns a function with the given name. It then runs that function with the input c as needed and prints output.
Hope this helps!

Related

how can i use the output of one function to another function?

Let's assume I have two functions
def seq():
#here I wrote a code that evaluates the mean of a value from a csv file
print(x)#assuming the condition in the above code is true it prints x
seq()
and
def lenn():
p=4
d=#I want this variable to be the value that the 1st function produces
x=d/p
lenn()
One produces an integer and the other uses the output of the 1st function and then divides it with an integer to produce its own output. How do I call the function?
I tried calling the function name but when I tried to divide the function name with an integer it keeps saying that I have a None type. I also tried to put the 1st first function inside the 2nd function but I had the same problem.
How can i solve this?
Don't use print but return (print has no return value, so this defaults to None):
def seq():
return int(input())
def lenn():
p=4
d=seq()
x=d/p
return x
print(lenn())
The problem is that seq does not return the inputted value (x). Anyway, I wouldn't place int(input(x)) in its own function. You can try something like
def lenn():
p=4
d=int(input())
x=d/p
return x

Get returned value of function in function which called it

I am newbie in python, and I build two functions in which, I am calling second function with 1 parameters in first function and I am trying to access second function's returned data in first function.
def second_function(first_param):
final = first_param + 50
return final
def first_function():
second_function(50)
# trying to access second_function's returned data HERE
print(second_function)
But it is not showing any returned data.
Any help would be much Appreciated. Thank You in Advance.
The problem here is that you are using print(second_function), so that will simply output the name of the function. Now, if you want to output the result of the function, you should do:
def second_function(first_param):
final = first_param + 50
return final
def first_function():
output = second_function(50)
print(output)
you could first put the returned value in a variable like this
def second_function(first_param):
final = first_param + 50
return final
def first_function():
value = second_function(60)
print(value )
or print the returned value with out using any variable
def second_function(first_param):
final = first_param + 50
return final
def first_function():
print(second_function(50))
That's because second_function is an object in its own right. Try either of the following:
def first_function():
out = second_function(50)
# trying to access second_function's returned data HERE
print(out)
def first_function_alternate():
print(second_function(50))
What's happening when you do print(second_function) is that the computer is trying to print the value of the function itself, not what it returns. We can store this value to a variable (my first answer) or simply generate it on-the-fly (my second answer).
In Python, the returned data from a function will be assigned to a variable. So you would use:
my_value = second_function(60)
and the returned value would be stored in the variable my_value

Closure : a function that returns the value of its previous call

I'm trying to build a function that returns the value of its previous call using closure. The first time function is called, it will return None. I'm not sure how to update last_in from one call to another.
def last_in(x):
last_in = [None]
def get():
temp = last_in[0]
last_in[0] = x
# print(last_in)
return temp
return get()
For example, print(last_in(1),last_in(2),last_in(3)) should print: None 1 2
The problem with your approach is that whenever you call last_in, i.e. the "outer" function, the previous value stored in last_in (the array, not the function) is reset to None. Instead, the outer function should be called only once so that the value is not reset each time you call it.
Not sure what you need this for, but I think it would make sense to create a decorator function for this, i.e. a function modifying an existing function. This way, all the storing-and-retrieving-the-last-result can be done in the decorator without cluttering the actual function. The outer function (the decorator) is called only once, and the original function is replaced with the decorated version that will correctly retrieve the stored value.
def return_previous(f):
f.last_result = None
def _f(*args, **kwargs):
res = f.last_result
f.last_result = f(*args, **kwargs)
return res
return _f
#return_previous
def some_function(x):
return x**2
print(some_function(1), some_function(2), some_function(3))
# None 1 4
I like the solution that #tobias_k provides, but here is another alternative which conforms to the current organization/structure of your code.
def last_in(x):
def get():
temp = last_in.__dict__.get('prev', None)
last_in.__dict__['prev'] = x
return temp
return get()
print(last_in(1),last_in(2),last_in(3))
None 1 2
This is a slight deviation from the request since it requires a second keyword argument but you could take advantage of the fact that default arguments are only set once (see here) to do something like this:
def last_in(x, __last=[None]):
last = __last[0]
__last[0] = x
return last
__last is set once when the function is declared and since it is mutable, you can update it at each function call and the updated value will persist between calls.

Method Overriding?

I saw this particular piece of code:
def g(x,y):
return x+y
def g(x,y):
return x*y
x,y=6,7
print (g(x,y))
The output is obviously(but not to me) is 42. Can somebody please explain this behavior? This is method overriding I suppose, but I'm still not getting the flow here.
When you define a function, and you redefine it, it will use the last one you defined, even the parameter is different:
def g(x,y):
return x+y
def g(x,y):
return x*y
x,y=6,7
print (g(x,y))
def hello():
return 'hello'
def hello():
return 'bye'
print hello()
def withone(word):
return word
def withone():
return 1==1
print withone('ok')
Output:
42
bye
TypeError: withone() takes no arguments (1 given)
And function name in Python is more like simple variable:
def hello():
return 'hello'
iamhello = hello # bind to the old one
def hello():
return 'bye'
print hello() # here is the new guy
print iamhello()
OutPut:
bye
hello
The devil is in the order of function definitions.
This is not technically method overriding as that requires class inheritance, instead it's a result of how python declares and references functions.
When declaring a function, python stores a reference to that function in a variable named after the function definition. (e.g. variable would be "foo" for "def foo():")
By declaring the function twice, the value of that variable gets overwritten by the second definition.
A Python script is parsed from top till bottom.
So anytime the same name of a variable or function or class occurs, it overwrites any definitions that where associated with this name before.
def g(x,z):
print('first')
def g():
print('second')
g = 3
print g
print g()
So look at this example which will result in the printout of '3' and then in an Exception: 'TypeError: 'int' object is not callable'
The name g is at first a function with two parameters, then it gets redefined to be a function with no parameters, then it gets redefined to be an int.
Which cannot be called obviously :)
Everything in python is treated as object, whether it be a function name or class name. So, when we define a function using 'def', the memory allocation is done for that method. Then python points the name that we assign to the function, to this allocated memory location. So if we define a method :-
def demo():
print 'hi'
the memory is allocated for the method, and the name 'demo' is pointed to its memory location as follows :-
Now as described by zoosuck in his second example, when you assign the function name to another variable :-
demo2 = demo # bind to the old one
then in that case, the assigned memory location to demo, is assigned to demo2 as well. So both demo and demo2 points to same location 12506.
print id(demo) # will print 12506
print id(demo2) # will print 12506
Now if we modify the above piece of code and in the next line, define a new method with same name demo:-
def demo():
print 'hi'
demo2 = demo # bind to the old one
demo() # Will print hi
def demo():
print "hello"
demo() # Will print hello
demo2() # Will print hi
then a completely new memory location 12534 is allocated for this new method, and now demo will point to this new location 12534 instead of pointing to the old one i.e. to 12506. But demo2 is still pointing to the location 12506.
I hope this will give you a clear idea of what is going on and how the method name is over-written.
Order matters, if names are same,last function you defined is processing. In your case it's;
def g(x,y):
return x*y
g is just a variable. The fact that the object it refers to is a function doesn't make it special in Python, so you can assign and reassign it as you want. In this case, the second assignment (which is what a function definition is) simply replaces the object stored there with a different one.
Functions and methods are normal objects like any others. So in
def g(x, y):
return x + y
def g(x, y):
return x * y
the second object g will override(replace) the first one, just like object a does below:
a = 1
a = 2
The number, type or order of parameters does not make any difference, because Python does not support function/method override and does not allow two functions/methods to have the same name.
If you are familiar with lambda function, also often called anonymous\inline functions, this might clear things up a bit
These two code blocks are essentially equal
def g(x,y):
return x+y
def g(x,y):
return x*y
g = lambda x,y: x+y
g = lambda x,y: x*y

Using an argument from one Function in a separate function

I have a function:
def create_discs(noDiscs):
which when called creates a specified number of discs, so for example:
create_discs(5)
will create 5 discs.
I then want to use the integer inputted into the create_discs function in a separate function:
def hanoi(disc_int):
In other words I would like disc_int to equal 5 (or whatever number is inputted)
Can anyone help me?
If you want two functions to share state like this, they should be defined as methods of a class.
class Hanoi(object):
def __init__(self, num_discs):
self.num_discs = num_discs
def create_discs(self):
# use value of self.num_discs
def hanoi(self):
# use value of self.num_discs
h = Hanoi(5)
h.create_discs()
h.hanoi()
If you're passing 5 to create_discs, can you do:
num = 5
create_discs(num)
hanoi(num)
You could make a closure:
def create_discs(num):
# create some discs
def hanoi_closure():
# now num is available within this function
# do hanoi stuff
return
return hanoi_closure
hanoi = create_discs(5)
hanoi()
In this case, create_discs defined your hanoi function within itself so that num was within its scope (automatically, no need to store anything in a global or a class!) and it returned the inner function so you could call it later.
If create_discs was already supposed to return something, then you could just return a tuple with what it was returning plus the inner function:
def create_discs(num):
# ...
return what_it_normally_returns, hanoi_closure
create_discs_result, hanoi = create_discs(5)
hanoi()

Categories

Resources