iterative definition of functions in Python [duplicate] - python

This question already has answers here:
True dynamic and anonymous functions possible in Python?
(8 answers)
Closed 6 years ago.
I am getting crazy with this kind of problem:
I have a list of string representing functions (for eval), I need first to replace the variables with generic x[0], x[1],....
Some time ago I discovered that I can do this using subs(). Then I need to generate a list of functions (to define constraints in SciPy minimize).
I am trying something like:
el=[budget.v.values()[0],silly.v.values()[0]] # my list of string/equations
fl=[]
for i in range(len(el)):
def sos(v):
vdict = dict(zip(q.v.values(),v))
return eval(el[i]).subs(vdict)
fl.append(sos)
del sos # this may be unnecessary
The result for fl is:
[<function sos at 0x19a26aa28>, <function sos at 0x199e3f398>]
but the two functions always give the same result (corresponding to the last 'sos' definition). How can I retain different function definitions?

Your comment:
but the two functions always give the same result (corresponding to the last 'sos' definition)
Is a big clue that you've likely run into this common gotcha!
Your code isn't in a runnable form so I can't verify this but it clearly has this bug. There are various ways to fix this including using functools.partial as explained in the first link.
For example (untested as your code isn't runnable as-is):
import functools
for i in range(len(el)):
def sos(i, v):
vdict = dict(zip(q.v.values(),v))
return eval(el[i]).subs(vdict)
fl.append(functools.partial(sos, i))
Given this you can now refactor this code to avoid redefining the function inside the loop:
def sos(i, v):
vdict = dict(zip([2], v))
return eval(el[i]).subs(vdict)
for i in range(len(el)):
fl.append(functools.partial(sos, i))
To give you a complete and runnable example:
import functools
def add_x(x, v):
return x + v
add_5 = functools.partial(add_x, 5)
print add_5(1)
Produces:
6

Related

Iteration in a for loop overwrites previously defined distinct dict keys when linking new keys to new lambda functions. Is this expected? [duplicate]

This question already has answers here:
What do lambda function closures capture?
(7 answers)
Creating functions (or lambdas) in a loop (or comprehension)
(6 answers)
Closed last year.
I am possibly very naive, but I find the following behaviour unexpected.
Introduction: I need a wrapper to address dynamically the methods of my own class, model. I am trying to use a dict to have a separate entry for each of a given number of members of the class that are dynamically requested. I link the dict keys to the chosen members iteratively and I find that the doc string is preserved, but the methods get overwritten by the last item in the iteration, despite their distinct keys. Here is a snippet where I reproduce the behaviour with numpy, in place of my own class.
import numpy as np
name = ["sin","cos"]
bnd = {}
print('Within the defining loop, it works!\n')
for nam in name:
# useless indirect function (with doc string)
# equivalent to sin(2*pi*x)
# or to cos(2*pi*x)
bnd[nam] = lambda x, par: np.__getattribute__(nam)(x*par)
bnd[nam].__doc__ = '"""'+nam+'"""'
print('bnd doc in-loop: {} = {}'.format(nam,bnd[nam].__doc__))
print('bnd method in-loop {}(0,2*pi) = {}'.format(nam,bnd[nam](0,2*np.pi)))
print('\n However after the loop...')
print('bnd keys {}'.format(bnd.keys()))
print('\nfirst function doc: {}'.format(bnd["sin"].__doc__))
print('doc is preserved, but instead the method')
print('(should be sin(2 pi *0)) yields {}'.format(bnd["sin"](0,2*np.pi)))
print('\nsecond trial_function doc: {}'.format(bnd["cos"].__doc__))
print('doc is preserved, again, and this time the method')
print('(should be cos(2 pi *0)) yields correctly {}'.format(bnd["cos"](0,2*np.pi)))
print('\nSummary: bnd[nam] gets overwritten by the last lambda definition in the loop. \n\nWhy????')
If you run the code you get the following
Within the defining loop, it works!
bnd doc in-loop: sin = """sin"""
bnd method in-loop sin(0,2*pi) = 0.0
bnd doc in-loop: cos = """cos"""
bnd method in-loop cos(0,2*pi) = 1.0
However after the loop...
bnd keys dict_keys(['sin', 'cos'])
first function doc: """sin"""
doc is preserved, but instead the method
(should be sin(2 pi *0)) yields 1.0
second trial_function doc: """cos"""
doc is preserved, again, and this time the method
(should be cos(2 pi *0)) yields correctly 1.0
Summary: bnd[nam] gets overwritten by the last lambda definition in the loop.
Why????
which I hope is clarifying my question.
As others have explained. There is only one variable nam in your function. When you create the lambda, it doesn't capture the value of nam as it was when created the lambda. Rather all the lambdas share the same nam, and it has whatever value it had at the end of the function.
There are several get arounds. Essentially you need to capture nam as a variable.
The "official" way to do this is that you could just write:
def attribute_getter(nam):
return lambda x, par: np.__getattribute__(nam)(x*par)
bind[nam] = attribute_getter(nam)
The quick and dirty solution is:
bind[nam] = lambda x, par, nam=nam: np.__getattribute__(name)(x * par)
The variable nam is turned into an optional which is set to the current value of nam.
Edit: Changed "program" to "function".

Automatic method extensions? [duplicate]

This question already has answers here:
Local variables in nested functions
(4 answers)
Closed 2 years ago.
I have a Python class MyObject (a subclass of tuple) and another class for a set of these objects, MyObjectSet (a subclass of set). I’d like that, for any non-builtin method that I define for MyObject, a method of the same name be defined for MyObjectSet with value equal to the sum of the method over the contents of the MyObjectSet.
I had thought that something like the code below would work, but the result doesn’t match my intended outcome. In practice MyObject and MyObjectSet have a lot more to them and are justified.
class MyObject(tuple):
def stat_1(self):
return len(self)
def stat_2(self):
return sum(self)
class MyObjectSet(set):
pass
for stat_name in dir(MyObject):
if not stat_name.startswith("__"):
stat_func = getattr(MyObject, stat_name)
if callable(stat_func):
setattr(MyObjectSet, stat_name, lambda S: sum(stat_func(p) for p in S))
if __name__ == "__main__":
S = MyObjectSet(MyObject(t) for t in [(1,2), (3,4)])
result, expected = S.stat_1(), sum(p.stat_1() for p in S)
print(f"S.size() = {result}, expected {expected}")
result, expected = S.stat_2(), sum(p.stat_2() for p in S)
print(f"S.sum() = {result}, expected {expected}")
Is there any way to achieve this functionality?
replace your lambda with this:
lambda S, f=stat_func: sum(f(p) for p in S)
It copies the stat_func into f, instead of capturing a reference to it, which was what happened in your original code (so all stat_funcs inside your different lambdas ended up being the last value assigned to the stat_func in the for loop.
You can simply override __getattr__ to treat any possible method call as a summing wrapper around the object's method of the same name. This simple example will just raise an AttributeError if the underlying method doesn't exist; you may want to catch the exception and raise another error of your own.
class MyObjectSet(set):
def __getattr__(self, mn):
return lambda: sum(methodcaller(mn)(x) for x in self)

Can i use PRINT function instead of RETURN at the end of every function i create? [duplicate]

This question already has answers here:
What is the purpose of the return statement? How is it different from printing?
(15 answers)
Closed 3 years ago.
i just can not understand the importance of return at the end of functions.with return u have to type print(function()) anyways so why cant we just type print(value) at the and of the function and when we need to use that function just call it like function()?
def example():
value = 5+5
print(value)
example()
print and return are not doing the same thing. The former is displaying information to the user, while the latter is giving a raw value out of a function. Consider the following:
>>> def print_10():
... print(10)
...
>>> def return_10():
... return 10
...
>>> print(return_10() + return_10())
20
>>> print(print_10() + print_10())
Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'
return_10 gives back the number 10, while print_10 prints the value 10 to the console and returns None (since you don't specify a return value). Trying to use that value elsewhere is possible (None is a valid result), but it probably doesn't do what you want it to do.
Thinking of this in explicit typing makes this very clear:
def print_10() -> None:
print(10)
def return_10() -> int:
return 10
the print statement only prints what is inside the Parenthesis to the console to be seen and can't be stored in variables or do any operations on it as it is a NoneType
i will show you with an example:
def example():
a = 5
b = 6
print(a + b)
x = example() + 5
print(x)
the above code will return a TypeError.
but if you change it to this:
def example():
a = 5
b = 6
return(a + b)
x = example() + 5
print(x)
you get 16
if you want to display info and not use it again use print else use return
There's a principle called separation of concerns that proposes that each unit of code (function, class, module, etc.) should be responsible for doing just one thing (where the definition of "one thing" is flexible to account for the size of the unit of code being discussed). The benefit is that code that follows this principle is easier to test, debug, combine, and reuse.
If you write a function that prints its result, it is harder to reuse that code in situations where you don't want to print the result, but rather use it in some other way. The function is doing two things: calculating its result, and printing it. If you don't want it to do the second thing, or want it to do the second thing in a slightly different way, you are S.O.L. On the other hand, if the function just calculates its result, doing just one thing, the caller can easily print it if that's what they want.
That said, if you often find yourself printing a result, then it might make sense to provide a second function that calls the first and prints the result, especially if printing it is complicated. But having the first function available is a win for future code reuse.
Some development methodologies advise you to write the simplest thing that works. But I think preserving separation of concerns is an obvious and logical reason to ignore this advice in many cases.

Python specifying function as input [duplicate]

This question already has answers here:
how to define a function from a string using python
(4 answers)
Closed 4 years ago.
import math
def g(x):
return x**2+3
def Integrate(f, a , b, n):
h=(b-a)/n
result=0
for k in range(n):
x=k*h+h/2
result+=f(x)*h
return result
F=input("f:")
A=float(input("a:"))
B=float(input("b:"))
N=int(input("n:"))
print(Integrate(F, A, B, N))
Whenever i try to run this code, it reads F to be a string and gives an error when called in integrate(f, a, b, n). I found that there is no way in python to define F as a function, but calling a function in another function is definitely possible. Then how can i still pull this way of using an input to specify what function to use off?
error:
line 14, in Integrate
result+=f(x)*h
TypeError: 'str' object is not callable
You can input a function on the console by using a lambda (as a string), and use eval to convert the string to an actual function object. Your code would look like this:
F = eval(input("f:"))
On the console, if you want to integrate the function f(x) = 2 * x + 1, you'd input:
lambda x: 2 * x + 1
as a string. However, note that eval will execute (as Python code) whatever you input on the console, and this could be a security concern depending on how your program is used.
I don't know if you want to use function from math module, but if yes then you can obtain method from module by string like this:
function_to_call = getattr(math, f)
result += function_to_call(x) * h
When doing this you should surround with try except block to check if given function name exit in math module.

Can I implement a function or better a decorator that makes func(a1)(a2)(a3)...(an) == func(a1, a2, a3,...,an)? [duplicate]

On Codewars.com I encountered the following task:
Create a function add that adds numbers together when called in succession. So add(1) should return 1, add(1)(2) should return 1+2, ...
While I'm familiar with the basics of Python, I've never encountered a function that is able to be called in such succession, i.e. a function f(x) that can be called as f(x)(y)(z).... Thus far, I'm not even sure how to interpret this notation.
As a mathematician, I'd suspect that f(x)(y) is a function that assigns to every x a function g_{x} and then returns g_{x}(y) and likewise for f(x)(y)(z).
Should this interpretation be correct, Python would allow me to dynamically create functions which seems very interesting to me. I've searched the web for the past hour, but wasn't able to find a lead in the right direction. Since I don't know how this programming concept is called, however, this may not be too surprising.
How do you call this concept and where can I read more about it?
I don't know whether this is function chaining as much as it's callable chaining, but, since functions are callables I guess there's no harm done. Either way, there's two ways I can think of doing this:
Sub-classing int and defining __call__:
The first way would be with a custom int subclass that defines __call__ which returns a new instance of itself with the updated value:
class CustomInt(int):
def __call__(self, v):
return CustomInt(self + v)
Function add can now be defined to return a CustomInt instance, which, as a callable that returns an updated value of itself, can be called in succession:
>>> def add(v):
... return CustomInt(v)
>>> add(1)
1
>>> add(1)(2)
3
>>> add(1)(2)(3)(44) # and so on..
50
In addition, as an int subclass, the returned value retains the __repr__ and __str__ behavior of ints. For more complex operations though, you should define other dunders appropriately.
As #Caridorc noted in a comment, add could also be simply written as:
add = CustomInt
Renaming the class to add instead of CustomInt also works similarly.
Define a closure, requires extra call to yield value:
The only other way I can think of involves a nested function that requires an extra empty argument call in order to return the result. I'm not using nonlocal and opt for attaching attributes to the function objects to make it portable between Pythons:
def add(v):
def _inner_adder(val=None):
"""
if val is None we return _inner_adder.v
else we increment and return ourselves
"""
if val is None:
return _inner_adder.v
_inner_adder.v += val
return _inner_adder
_inner_adder.v = v # save value
return _inner_adder
This continuously returns itself (_inner_adder) which, if a val is supplied, increments it (_inner_adder += val) and if not, returns the value as it is. Like I mentioned, it requires an extra () call in order to return the incremented value:
>>> add(1)(2)()
3
>>> add(1)(2)(3)() # and so on..
6
You can hate me, but here is a one-liner :)
add = lambda v: type("", (int,), {"__call__": lambda self, v: self.__class__(self + v)})(v)
Edit: Ok, how this works? The code is identical to answer of #Jim, but everything happens on a single line.
type can be used to construct new types: type(name, bases, dict) -> a new type. For name we provide empty string, as name is not really needed in this case. For bases (tuple) we provide an (int,), which is identical to inheriting int. dict are the class attributes, where we attach the __call__ lambda.
self.__class__(self + v) is identical to return CustomInt(self + v)
The new type is constructed and returned within the outer lambda.
If you want to define a function to be called multiple times, first you need to return a callable object each time (for example a function) otherwise you have to create your own object by defining a __call__ attribute, in order for it to be callable.
The next point is that you need to preserve all the arguments, which in this case means you might want to use Coroutines or a recursive function. But note that Coroutines are much more optimized/flexible than recursive functions, specially for such tasks.
Here is a sample function using Coroutines, that preserves the latest state of itself. Note that it can't be called multiple times since the return value is an integer which is not callable, but you might think about turning this into your expected object ;-).
def add():
current = yield
while True:
value = yield current
current = value + current
it = add()
next(it)
print(it.send(10))
print(it.send(2))
print(it.send(4))
10
12
16
Simply:
class add(int):
def __call__(self, n):
return add(self + n)
If you are willing to accept an additional () in order to retrieve the result you can use functools.partial:
from functools import partial
def add(*args, result=0):
return partial(add, result=sum(args)+result) if args else result
For example:
>>> add(1)
functools.partial(<function add at 0x7ffbcf3ff430>, result=1)
>>> add(1)(2)
functools.partial(<function add at 0x7ffbcf3ff430>, result=3)
>>> add(1)(2)()
3
This also allows specifying multiple numbers at once:
>>> add(1, 2, 3)(4, 5)(6)()
21
If you want to restrict it to a single number you can do the following:
def add(x=None, *, result=0):
return partial(add, result=x+result) if x is not None else result
If you want add(x)(y)(z) to readily return the result and be further callable then sub-classing int is the way to go.
The pythonic way to do this would be to use dynamic arguments:
def add(*args):
return sum(args)
This is not the answer you're looking for, and you may know this, but I thought I would give it anyway because if someone was wondering about doing this not out of curiosity but for work. They should probably have the "right thing to do" answer.

Categories

Resources