Passing a function (with arguments) as an argument in Python - python-3.x

I am measuring performance of different sorting methods using Python built-in library timeit. I would like to pass a function and an integer as arguments to the statement being tested in timeit(). I tried the following:
def sort_1(l):
...
return l_sorted
def test(f: Callable, l_len: int):
l = np.random.rand(low=-1000, high=1000, size=l_len)
f(l)
timeit.timeit(stmt=test(sort_1, l_len=10), number=1000)
... with a ValueError saying that stmt is neither a string nor callable. The error doesn't occur when I call it like this:
timeit.timeit(stmt=test, number=1000)
... but then I cannot pass any argument to test(). What is a general solution if someone wants to pass arguments to a function given as an argument? (let's say, when a method is already implemented and there is not way to pass arguments in a separate argument)
Cheers
Edit:
#jonrsharpe, thanks! The solution looks like this:
timeit.timeit(stmt='test(f=sort_1, l_len=10)', number=100, globals=globals())

Related

How to use unquoted keyword-only function args in Python

It is easy to create optional arguments in a function by specifying a default in the def.
for example sorted([1,3,2],reverse=True)
if I were defining this function I might say
def sorted(l:list, reverse:bool=False)
is there any way to define a function's parameters so that I can specify keywords without values? Simply mentioning the keyword makes it true. If there were I could define a function that accepts this
sorted([1,3,2],reverse)
I tried using **kwargs but apparently, it only accepts keywords that are included with values.
The closest to what I was looking for would be to use an Enum
import enum
class SortDirection(enum.Enum):
REGULAR = None
REVERSE = 2
def sorted(l:list, reverse:SortDirection=None):
print(reverse)
sorted([], SortDirection.REVERSE)
So the above program outputs
SortDirection.REVERSE

Python starmap got multiple values for argument

I hava a multiprocess program whcich using starmap. But when I run it, a TypeError occured. While normally when I run it in map.
def process_single_image(img_path, target_dir="", func=None, severity=1):
print(target_dir)
...
pool.starmap(
partial(
process_single_image,
target_dir=target_dir,
func=iaa.imgcorruptlike.apply_shot_noise,
severity=4,
),
img_paths,
)
I don't know why I got this error. I think it should run normally as pool.map(....).
Here is the traceback.
The arguments you pass to .starmap are unpacked to the target function. Therefore, the arguments must be an iterable of iterables (even if the argument length the target function accepts is one).
Therefore, if the argument length is one, then explicitly convert each element of img_path into a tuple before passing it to starmap:
img_path = [(arg,) for arg in img_path]

What's the difference between the method .get() and the method .get in python? Both are appliable to dictionaries

Imagine I have a dict.
d = ['a': 1 , 'b':3]
I'm having a hard time to understand the difference between d.get and d.get().
I know that d.get() get the value from the key, like this:
print(d.get('a') )
output: 1
But when I write d.get, it shows this:
print(d.get)
output: <built-in method get of dict object at .........>
What is 'd.get' doing in my code?
I'm using python 3X
A method is literally just an attribute of an object that happens to be of type <class function>. The output you see is essentially what happens when you try to call print() on any function object, and is essentially a concise string representation that python creates for the function.
Actually calling a function is done with parentheses: d.get('a'), which means to execute the behavior the function refers to. It doesn't especially matter where the function is, though: I could do the following, and it would still work:
d = {'a': 1 , 'b':3}
freefunc = d.get
freefunc('a')
This is what the term "first class functions" refers to, when people compare python to something like Java. An entire function can be encapsulated in a variable and treated no differently than any other variable or attribute.
The short answer? There is no difference between the two methods. They are the same exact method.
The difference in your code is at when you write .get() you call the method, but when you write .get you just get a pointer (or location in the memory, to be exact) for that method, to call it later on if needed.
In the first scenario, you are calling print on the result of executing get('a'), which in this case is 1.
In your second scenario, you are calling print on the get function itself, instead of on an execution of it, which evaluates to its documentation, i.e. <built-in method get of dict object at... etc.

Python: signature with Numba

I have a function that is doing some computation and at a certain point is calling another one. For example, the main function is something like:
import numba
#numba.njit(some signature here)
def my_funct():
...
value = cosd(angle)
Since the function cosd is inside another function decorated with numba.njit, it has to be decorated as well, and in my case it is:
from numba import float64
#numba.njit(float64(float64))
def cosd(angle):
return np.cos(np.radians(angle))
My problem now is that in another function, the input value angle is an array and the related output is an array as well. I know that I could decorate my function as #numba.njit(float64[:](float64[:])) but doing so the function would not accept scalars anymore. How can I can tell numba that input is something like Union[float64, float64[:]]? Of course this applies to the output as well. Thanks a lot!
I finally found an answer myself.
The solution is to create a list of signatures so, for my example, it would be:
from numba import float64
#njit([float64(float64), float64[:](float64[:])])
def cosd(angle):
return np.cos(np.radians(angle))
I hope this will be helpful to others.

Where are user defined functions stored?

I want to make a sort of help() function for my module. My idea is to have something like module.help() that just prints out the __doc__ of my functions. My first approach was just to hardcode them and then iterate over them, but I feel there has to be a better way to do so. I looked through the docs for a reference as to where they are stored but couldn't find any. What I want is the python equivalent to this but for function names. I would appreciate if anyone could help me out. Thanks!
Edit: Ok so as of now the functions I have are:
BoyleGraph
Boyle_Resolve
Boyle_k
Boyle_k_solve
GayLussacGraph
GayLussac_Resolve
`
and what I have tried so far is:
funcs = list()
for f in dir():
funcs.append(f)
def helper():
for f in funcs[:-13]:
print(help(f))
and this returns something like (redacted):
No Python documentation found for 'GayLussac_Resolve'.
Use help() to get the interactive help utility.
Use help(str) for help on the str class.
Now using:
def helper():
for f in funcs[:-13]:
print(f)
will give me:
BoyleGraph
Boyle_Resolve
Boyle_k
Boyle_k_solve
GayLussacGraph
GayLussac_Resolve
but doing:
def helper():
for f in funcs[:-13]:
print(f, '\n', '#' * 50)
print(f.__doc__)
gives me (redacted):
GayLussac_Resolve
##################################################
str(object='') -> str
str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or
errors is specified, then the object must expose a data buffer
that will be decoded using the given encoding and error handler.
Otherwise, returns the result of object.__str__() (if defined)
or repr(object).
encoding defaults to sys.getdefaultencoding().
errors defaults to 'strict'.
which is the __doc__ of str() which is not even in the funcs list. I feel I'm so close yet so far.
PS: I know the funcs definition looks sloppy but when I try to assign directly or use list comprehensions I only get the first element of dir()'s output
dir() gets you a list of names, not objects. You could use the values of globals() instead, but you would need to filter out special names like __builtins__ and imports. Instead, just use help(module). It does everything you want, automatically.

Resources