Currying in python - python-3.x

I wrote the following function
def addsub(a):
def add(a):
def subtract(b):
return a-b
return subtract
return add(a)
addsub(9)(4)
returns 5
but what if I do not know to number of add subtract I want to perform
addsub(9)(3)(4)(5).
The above function does not work for it
could I write something general which works for any length of input?
PS. I do not want to use functools

It is not possible exactly like you describe (with currying). But if all you want is to sum the numbers of a list with a varying sign, this looks the most straightforward to me:
import itertools
coefficients = itertools.cycle((1, -1))
numbers = [9, 3, 4, 5]
result = sum(a * c for a, c in zip(numbers, coefficients))

Related

I have problem with using the *mul* operator to multiply varibales

I splited and converted string into int and i want use the mul
operator to multiply directly. But they is an error when printing the last output.
from operator import mul
# mulptiply user input
input_string = input("Enter numbers for summing :")
print("/n")
user_list = input_string.split()
print('list:', user_list)
# for loop to iterate
for x in range(len(user_list)):
user_list[x] = int(user_list[x]
# calc the mul of the list
print("Multiplication of list =", mul(user_list))
The mul function takes 2 arguments at a time and returns their product. If you want to use mul to calculate the product of a list of numbers you can use functools.reduce to apply the function cumulatively to every list item for an aggregated result:
from functools import reduce
from operator import mul
user_list = [2, 3, 4]
print(reduce(mul, user_list)) # outputs 24
Beginning in Python 3.8 you can also use math.prod to calculate the product of a list of numbers directly.

Passing an arbitrary number of parameters to a function in python

I have a python function which takes as input an arbitrary number of parameters. I beleive this is implemented via *args (thanks #Anurag Wagh for pointing this out). I would like to be able to pass to it a list of values. Here is the specific code I have:
from sympy import solve_poly_system, symbols
x,y,z = symbols('x y z')
print(solve_poly_system([y**2 - x**3 + 1, y*x], x, y))
Instead of passing x and y to solve_poly_system, I want to be able to pass it a list L something like so:
print(solve_poly_system([y**2 - x**3 + 1, y*x], L))
where L = [x,y].
Is this possible? Please note, although I am interested in the specific case of the solve_poly_system function, I am more broadly interested in the passing a list to any function in python that takes an arbitrary number of inputs.
To put this another way, I want to know how to pass a list of values to a function which takes *args as input. In particular I am interested in the case where the length of the list is not known until run time and may change during run time.
From your question, it looks like you know how to use *args in function definition and you are looking for a way to pass all the elements of a list to that function regardless of the length of the list. If that's your question, then here's your answer:
def function(x, *args):
print(x)
print(args)
x = 10
l = [5, 6, 7, 8]
function(x, *l)
Output:
10
(5, 6, 7, 8)

Finding the median of an array of floating point numbers

I've looked through all the examples in here already of this and nothing quite answers my question. I'm very new to Groovy.
I want to create something like a list or an array of floating point numbers, prices such as 239.99.
I then want to pass that array or list to a method that will determine the median price in that array or list of numbers. The total size will vary.
Is there any quick and easy code to do this? How do I add each number to the array or list and must I use doubles?
Any help is appreciated, this one has me stuck and frustrated.
Thanks!
The following function determines the median for non-empty lists.
def median(data) {
def copy = data.toSorted()
def middle = data.size().intdiv(2)
// you can omit the return in groovy for the last statement
data.size() % 2 ? copy[middle] : (copy[middle - 1] + copy[middle]) / 2
}
It works with all types that support addition and division.
For example:
assert median([1, 7, 4, 3]) == 3.5
assert median([1, 7, 4]) == 4
assert median([1, 7]) == 4
assert median([1]) == 1
assert median([1.7, 3.4, 10.9, 4.2]) == 3.8
In terms of what you can do with lists check the Lists overview and then the List API.

Can you call 2 args from a function into another function? [duplicate]

So, Python functions can return multiple values. It struck me that it would be convenient (though a bit less readable) if the following were possible.
a = [[1,2],[3,4]]
def cord():
return 1, 1
def printa(y,x):
print a[y][x]
printa(cord())
...but it's not. I'm aware that you can do the same thing by dumping both return values into temporary variables, but it doesn't seem as elegant. I could also rewrite the last line as "printa(cord()[0], cord()[1])", but that would execute cord() twice.
Is there an elegant, efficient way to do this? Or should I just see that quote about premature optimization and forget about this?
printa(*cord())
The * here is an argument expansion operator... well I forget what it's technically called, but in this context it takes a list or tuple and expands it out so the function sees each list/tuple element as a separate argument.
It's basically the reverse of the * you might use to capture all non-keyword arguments in a function definition:
def fn(*args):
# args is now a tuple of the non-keyworded arguments
print args
fn(1, 2, 3, 4, 5)
prints (1, 2, 3, 4, 5)
fn(*[1, 2, 3, 4, 5])
does the same.
Try this:
>>> def cord():
... return (1, 1)
...
>>> def printa(y, x):
... print a[y][x]
...
>>> a=[[1,2],[3,4]]
>>> printa(*cord())
4
The star basically says "use the elements of this collection as positional arguments." You can do the same with a dict for keyword arguments using two stars:
>>> a = {'a' : 2, 'b' : 3}
>>> def foo(a, b):
... print a, b
...
>>> foo(**a)
2 3
Actually, Python doesn't really return multiple values, it returns one value which can be multiple values packed into a tuple. Which means that you need to "unpack" the returned value in order to have multiples.
A statement like
x,y = cord()
does that, but directly using the return value as you did in
printa(cord())
doesn't, that's why you need to use the asterisk. Perhaps a nice term for it might be "implicit tuple unpacking" or "tuple unpacking without assignment".

How I add values in a list I am using as the parameter for a function?

I am trying to understand these instructions.
Set up a new function in your main program file named “summer” that takes a list as a parameter and returns a value we will determine in the next steps.
In the “summer” function, set up a loop that uses a counter variable named “n” that will take on the values 0, 2, 4, 6, 8, 10, 12.
Each time through the loop, you are to call your “powerval” function from the “mymath” module passing as parameters item “n” and “n+1” from the list of data passed into “summer”. Add up all these values and return the final result to the caller.
So far I have:
def summer(list):
for n in range(0,13,2):
value=powerval(n,n+1)
After that I am lost. How do i perform step 3?
You add them up:
from mymath import powerval
def summer(somelist):
sum = 0
for n in range(0, 13, 2):
sum += powerval(somelist[n], somelist[n + 1])
return sum
So the return value of powerval() is added to the total sum so far, which was started at 0. You do need to pass in the somelist[n] and somelist[n + 1] values, not the indices themselves.
You need to add them up:
from mymath import powerval
def summer(lst):
total = 0
for n in range(0, 13, 2):
total += powerval(lst[n], lst[n + 1])
return total
I'm not sure where you use lst (I renamed list to lst, as list is a built-in function), so I'm guessing you're trying to get the nth and n + 1th elements from that list.
You can use the sum method to accomplish this in a very fashionable way :)
def summer(myList):
return sum(powerval(myList[n], myList[n+1]) for n in range(0, 13, 2))
This is also the fastest way.
PS: It's not a good idea to name you list "list", bacause that's a reserved name in python. That's why I have renamed it to myList in the example above.

Resources