What does parentheses mean after list brackets in python - python

I saw a question they wanted me to make a function to calculate the area of some shapes
the example code is below, I just don't understand what do that parenthesis work after brackets and how can I create a function to solve the question this way
code:
ls = area_func(['square', 'circle', 'rectangle', 'triangle'])
print(ls[0](1))
print(ls[1](2))
print(ls[2](2, 4))
print(ls[3](4, 5))
output:
1
12.566370614359172
8
10.0

From your code, I assume that area_function return 4 functions as list like
def area_func():
def square(x):
return x*x
# other functions
return [square,circle, rectangle, triangle]
and from this code, below it seems like you are calling these function at index 0,1,2,3
print(ls[0](1)) # ls[0] has reference to square function
print(ls[1](2)) # ls[1] has reference to circle function
print(ls[2](2, 4)) #ls[2] has reference to rectangle function
print(ls[3](4, 5)) #ls[3] has reference to triangle function
So, essecially doing
ls[0](1)
is equivalent to
square(1)

Could be many different things, for example - scope for passing parameters to a function:
def area_func(arr):
return [func1, func2, func3, func4]
def func1(x):
return '1'
def func2(x):
return '12.566370614359172'
def func3(x, y):
return '8'
def func4(x, y):
return '10.0'
ls = area_func(['square', 'circle', 'rectangle', 'triangle'])
print(ls[0](1))
print(ls[1](2))
print(ls[2](2, 4))
print(ls[3](4, 5))

area_func returns a list of functions.
Then the functions are call with different parameters.
ls[0] probably computes the area of a square, ls[1] for circle, and so on.

The area func is probably supposed to generate a list of functions based on the input given to it, so calling it with ['circle','square'] for example should return a list with just those two functions, in the specified order? For that, you probably want to have a dictionary of functions, something like this:
def area_func(func_list):
def square(x):
def circle(r):
def rectangle(h, w):
def triangle(h, b):
funcs = {'square':square, 'circle':circle, 'rectangle':rectangle,
'triangle':triangle}
return [funcs.get(x) for x in func_list if funcs.get(x) is not None] #avoids KeyError
Dictionaries of functions are a common way to do this kind of thing.

Related

How to find out which values a function f is called when using scipy.integrate.quad?

I have a function f(x) = 1/x^2 and I evaluate the integral from 0 to 1 using scipy.integrate.quad. scipy.integrate.quad is an adaptive integration routine and I would like to know in which regions of [0,1] is the function f evaluated. So, for which values of x is the function f called when making an estimate of the integral?
I'm thinking of using a global variable and appending the x values called to it to keep track of the which x values get used. However, I'm not too familiar on how to do this and any help would be greatly apprecaited, thanks.
The plan is to then plot a histogram to see what regions in the interval [0,1] are evaluated the most.
You could use a decorator class that saves each value x before evaluating the function:
class MemoizePoints:
def __init__(self, fun):
self.fun = fun
self.points = []
def __call__(self, x, *args):
self.points.append(x)
return self.fun(x, *args)
#MemoizePoints
def fun(x):
return 1 / x**2
quad(fun, a = 1e-6, b = 1.0)
Then, fun.points contains all the x values for which the function f was evaluated.
Here, the decorator #MemoizePoints is just syntactic sugar for
def fun(x):
return 1 / x**2
fun = MemoizePoints(fun)

iterating through a function's sub functions python

The goal is to try and access any function's sub functions. I've looked around and I'm not too sure there is a way to do it. When I've tried using
functions = [name for name, obj in inspect.getmembers(sys.modules[__name__], inspect.isfunction)]
which returns the functions in some module (in the above __name__==__main__). When I have used that method, it doesn't return any sub functions. However I'd like to access sub functions that look something like
def f(x):
def y(x):
return x += 3
def z(x):
return x**2 - 1
x += y(x)
x += z(x)
return x
So it seems to me like there should be some way to access them with a magic method of f or some attribute of f. I have a hard time believing that those sub functions aren't stored as some attribute of f, but I have no idea.
In the end, what I need to do is to iterate through the sub functions of some function, so I thought the solution would look something like
for subfunc in f.__method_that_returns_subfuncs__():
if 'my_string' == subfunc.__name__:
out = subfunc(args)
I just need to be able to compare a string to a subfunction name then call that subfunction.
Thanks
There's no implicit list of functions to iterate over. You need to define it yourself. Simply functions can be assigned directly to a list by defining them with lambda expressions; more complex functions will need to be defined first, then added. Examples of each:
def f(x):
funcs = []
def y(x):
return x += 3
f.append(y)
f.append(lambda x: x**2 - 1)
for func in funcs:
x = func(x)
return x
If you care about the name, you can access it via the function object's __name__ attribute.
for func in funcs:
if func.__name__ == "some_func":
x = func(x)

Why my function (f(x)=x*2) doesn't returns anything?

I know that there are way simpler ways to calculate the square of a number and store it in an array, but for the sake of another problem. I need to understand why nothing happens in this code and its structure (is the return(a) necessary ?):
s=[1,2,3,4,5]
def square(x):
return x*x
def iterate(b):
sol=[]
for b in s:
a=square(b)
return(a)
sol.append(a)
print(sol)
The goal is to store the square in sol : sol = [1,4,9,16,25]. But the code runs without printing anything. What make the following code work and not the previous one ?
s=[1,2,3,4,5]
def square(x):
return x*x
sol=[]
for b in s:
a=square(b)
sol.append(a)
print(sol)
(My problem involves curve fitting, and this structure doesnt fit my needs)
The problem is that you define iterate within square but you never call iterate. It would be better to have iterate be a separate function that calls square:
values = [1,2,3,4,5] # do not call your variable set - it is a Python keyword
def square(x):
return x*x
def iterate(values):
solution = []
for value in values:
value_squared = square(value)
solution.append(value_squared)
return solution
You could also do this without defining iterate using a list comprehension:
[square(value) for value in values]
Edit:
To answer your other questions, here is your code:
s=[1,2,3,4,5]
def square(x):
return x*x
def iterate(b):
sol=[]
for b in s:
a=square(b)
return(a)
sol.append(a)
print(sol)
In square, you never call iterate so this part of the code never runs.
If you add a call to iterate within square, you will end up in an infinite loop. This is because within iterate you call square, but you always iterate over your list s. This means that inside iterate, square(b) will always be square(1).
Within iterate you use the global variable s but it would be better to restructure your code so that you take s as input.
If you are learning about inner functions, you could define iterate and within this define square:
values = [1,2,3,4,5]
def iterate(values):
def _square(x):
return x*x
solution = []
for value in values:
value_squared = _square(value)
solution.append(value_squared)
return solution

Generating a sorting function for counter-clockwise sort

As part of a script I am making, I want to sort a series of points in a counter-clockwise order around a central point, which we will call 'a'.
I have a function that determines, for two points 'b' and 'c', if c is to the right of or left of the ray a->b. This function is right_of(a, b, c), and it is tested and works.
I want to use this function to sort a list of tuples with 2-d coordinates e.g. [(0, 0), (0, 1), (1, 1),...]. However, each time I sort, there will be a different point 'a' to pass to the function right_of(). What I want is a 'function' returnSortFunction(a) that will return a function with two arguments, f(b, c), and and when f(b, c) is called on each pair of coordinates as I sort, it should return the result of right_of(a, b, c) with 'a' already filled in.
I have tried to implement this using a factory, but I don't think I understand factories well enough to do it correctly, or determine if that is not what a factory is for. How can I build this feature?
You can have a function return a function, no problem. A simple way to do it is something like
def returnSortFunction(a):
return lambda b,c: right_of(a,b,c)
You need a wrapper function around your right_of function. You could use a lambda, but I think your logic is going to be more complicated than that. Assuming you want to pass in a function as a comparator to your sorting method, it's going to look something like this:
def returnSortFunction(a):
def comparator(p1, p2, a = a):
if p1 == p2:
return 0
elif right_of(a, p1, p2):
return 1
else:
return -1
return comparator
Functions are first class objects in python, so you can do something like this:
def prepare_funcs(number):
def inc(a):
return number + a
def mult(a):
return number * a
return inc, mult
inc5, mult5 = prepare_funcs(5)
inc2, mult2 = prepare_funcs(2)
inc5(2) #Out: 7
mult2(10) #Out: 20
For your specific context you should also check out functools module, specifically partial function. With it, you can 'partially' prepare arguments to your function like this:
right_of_5 = functools(right_of, 5)
right_of_5(b, c)
That will work, because right_of_5 will automatically fill right_of first argument - a - with number 5.

Using a list from one function, inside another function python

I am new to python. This might be a simple question, but if I have many functions that are dependent on each other how would I access lists from one function to use in another.
So...
def function_1():
list_1=[]
def function_2():
list_2= [2*x for x in list_1]
def function_3():
list_3= [x * y for x, y in zip(list_1, list_2)]
That is not the exact code but that is the idea of my problem. I would just put them all together in one function but I need them to be separate.
The correct way to do this would be to use a class. A class is an object that has internal variables (in your case, the three lists), and methods (functions that can access the internal methods). So, this would be:
class Foo(object):
def __init__(self, data=None):
self.list_1 = data if not data is None else []
def function_2():
self.list_2 = [2 * x for x in self.list_1]
And so on. For calling it:
foo = Foo() # list_1 is empty
foo2 = Foo([1,2,3]) # list_1 is not empty
foo2.function_2()
print foo2.list_2
# prints [2, 4, 6]
Make them arguments and return values:
def function_1():
return []
def function_2(list_1):
return [2*x for x in list_1]
def function_3(list_1, list_2):
return [x * y for x, y in zip(list_1, list_2)]
(this suggests that function_1 isn't much worth having...)
The exact way will depend on exactly how you want things to work, but here is a simple example:
def function_1():
return []
def function_2():
return [2*x for x in function_1()]
def function_3():
return [x * y for x, y in zip(function_1(), function_2())]
The key point is that functions do not generally just "do" things, they return things. If you have a value in one function that you want to use in another function, the first function should return that value. The second function should call the first function, and use its return value.
Functions are basically black boxes -- the outside world doesn't really know what goes on inside or what variables exist there. From the outside, other code only sees what goes in (the function's arguments) and what goes out (its return value).
So if your function computes some value that is to be used elsewhere, it should be returned as the result of the function.
E.g.,
def square(x):
return x * x
Takes a number, computes its square, and returns it.
Then you could do:
print(square(5))
and it will print 25.
So in your case you can return the lists and use them in the other functions, as the other answers showed:
def function_1():
return []
def function_2():
return [2*x for x in function_1()]
def function_3():
return [x * y for x, y in zip(function_1(), function_2())]

Categories

Resources