can anyone can help me I was expected that the output is 625 but it shows the output is zero
def add(*args):
sum = 0
for i in args:
sum *= i
return sum
print(add(5, 5, 5, 5))
As the value of sum = 0
And, you multiplying the values with 0. Therefore, you are getting no answer.
Change this line
sum = 0
To:-
sum = 1
Thank You.
You are setting the sum variable to 0, an in the for loop you are multiplying the sum with i. Any number multiplied with 0 is 0.
>>> def multiply(*args):
... result = 1
... for i in args:
... result *= i
... return result
...
>>> print(multiply(5,5,5,5))
625
Or rather if you wanted to add
>>> def add(*args):
... result = 0
... for i in args:
... result += i
... return result
...
>>> print(add(5,5,5,5))
20
Or rather do this pythonic way
>>> mul = lambda x,y: x*y
>>> functools.reduce(mul, [5,5,5,5])
625
Or rather single liner
>>> functools.reduce(lambda x,y : x*y, [5,5,5,5])
625
>>> functools.reduce(lambda x,y : x+y, [5,5,5,5])
20
Please define your function to have meaningful names.
Don't use inbuilt names like "sum"
Have meaningful variable names
First of all, anything multiplied by zero is zero. Therefore if you want to multiply the numbers received, you need to change sum = 0 to sum = 1.
Secondly, don't use sum as a variable or function name, as it is a built-in function in python. It is also misleading as you want your function to multiply the given args (and therefore also don't call the function add). To achieve a readable code, you should have meaningful variable and function names.
Also, your first line isn't indented correctly. You can read about python indentation here.
Putting it all together:
def multiply(*args):
multiplication = 1
for i in args:
multiplication *= i
return multiplication
print(multiply(5, 5, 5, 5))
Output:
625
Related
I have a question about how Python(3) internally loops when computing multiple maps. Here's a nonsense example:
from random import randint
A = [randint(0,20) for _ in range(100)]
map1 = map(lambda a: a+1, A)
map2 = map(lambda a: a-1, map1)
B = list(map2)
Because map() produces a lazy expression, nothing is actually computed until list(map2) is called, correct?
When it does finally do this computation, which of these methods is it more akin to?
Loop method 1:
A = [randint(0,20) for _ in range(100)]
temp1 = []
for a in A:
temp1.append(a+1)
B = []
for t in temp1:
B.append(t-1)
Loop method 2:
A = [randint(0,20) for _ in range(100)]
B = []
for a in A:
temp = a+1
B.append(temp-1)
Or does it compute in some entirely different manner?
In general, the map() function produces a generator, which in turn doesn't produce any output or calculate anything until it's explicitly asked to. Converting a generator to a list is essentially akin to asking it for the next element until there is no next element.
We can do some experiments on the command line in order to find out more:
>>> B = [i for i in range(5)]
>>> map2 = map(lambda b:2*b, B)
>>> B[2] = 50
>>> list(map2)
[0, 2, 100, 6, 8]
We can see that, even though we modify B after creating the generator, our change is still reflected in the generator's output. Thus, it seems that map holds onto a reference to the original iterable from which it was created, and calculates one value at a time only when it's asked to.
In your example, that means the process goes something like this:
A = [2, 4, 6, 8, 10]
b = list(map2)
b[0] --> next(map2) = (lambda a: a-1)(next(map1))
--> next(map1) = (lambda a: a+1)(next(A))
--> next(A) = A[0] = 2
--> next(map1) = 2+1 = 3
--> next(map2) = 3-1 = 2
...
In human terms, the next value of map2 is calculated by asking for the next value of map1. That, in turn, is calculated from A that you originally set.
This can be investigated by using map on functions with side-effects. Generally speaking, you shouldn't do this for real code, but it's fine for investigating the behaviour.
def f1(x):
print('f1 called on', x)
return x
def f2(x):
print('f2 called on', x)
return x
nums = [1, 2, 3]
map1 = map(f1, nums)
map2 = map(f2, map1)
for x in map2:
print('printing', x)
Output:
f1 called on 1
f2 called on 1
printing 1
f1 called on 2
f2 called on 2
printing 2
f1 called on 3
f2 called on 3
printing 3
So, each function is called at the latest time it could possibly be called; f1(2) isn't called until the loop is finished with the number 1. Nothing needs to be done with the number 2 until the loop needs the second value from the map.
I am currently learning Python and would like some clarification on the difference between iterative and recursive functions. I understand that recursive functions call themselves but I am not exactly sure how to define an iterative function.
For instance, I wrote this code
random_list = ['6', 'hello', '10', 'find', '7']
def sum_digits(string):
return sum(int(x) for x in string if x.isdigit())
print "Digits:", sum_digits(random_list)
I thought that this was an iterative function but after doing some research I am not sure. I need to know specifically because the next exercise asks me to write a version of the function that is recursive/iterative (depending on what my first function is).
Recursive function call itself while does not reach the out poin whereas iterative function update calculating value through the iteration over the range.
so the question is "write an iterative and recursive version of sum". great.
don't use the built-in sum method, and write your own. i'll give you the iterative, you should figure out the recursive:
def my_iterative_sum(a):
res = 0
for n in a:
res += a
return res
this is iterative because it iterates over all the values and sums them up.
edit: clearly your post is iterative. are you calling function f from within function f? no.
maybe reading up on what recursion is will help with this. https://www.google.com/search?q=recursion
To those who might still want to see the difference between recursive and iterative function.
iterative
def iterative_sum(n):
result = 1
for i in range(2,n+1):
result *= i
return result
print(iterative_sum(5))
iteration is when a loop repeatedly executes until the controlling condition becomes false
recursive
def recursive_sum(n):
if n == 1:
return 1
else:
return n * recursive_sum(n-1)
print(recursive_sum(5))
recursive function is when a function calls itself
This link explains it much better
https://techdifferences.com/difference-between-recursion-and-iteration-2.html
In case you came here looking for recursive functions in Python, here is an example of a recursive sum
from typing import Optional
>>> def r_sum(v: int, sum: Optional[int] = None) -> int:
... if sum is None:
... sum = 0
... if v == 0:
... return sum
... else:
... sum = sum + v
... prev = v - 1
... return r_sum(prev, sum)
...
>>> r_sum(3)
6
>>> r_sum(4)
10
>>> r_sum(5)
15
i would like to perform a calculation using python, where the current value (i) of the equation is based on the previous value of the equation (i-1), which is really easy to do in a spreadsheet but i would rather learn to code it
i have noticed that there is loads of information on finding the previous value from a list, but i don't have a list i need to create it! my equation is shown below.
h=(2*b)-h[i-1]
can anyone give me tell me a method to do this ?
i tried this sort of thing, but that will not work as when i try to do the equation i'm calling a value i haven't created yet, if i set h=0 then i get an error that i am out of index range
i = 1
for i in range(1, len(b)):
h=[]
h=(2*b)-h[i-1]
x+=1
h = [b[0]]
for val in b[1:]:
h.append(2 * val - h[-1]) # As you add to h, you keep up with its tail
for large b list (brr, one-letter identifier), to avoid creating large slice
from itertools import islice # For big list it will keep code less wasteful
for val in islice(b, 1, None):
....
As pointed out by #pad, you simply need to handle the base case of receiving the first sample.
However, your equation makes no use of i other than to retrieve the previous result. It's looking more like a running filter than something which needs to maintain a list of past values (with an array which might never stop growing).
If that is the case, and you only ever want the most recent value,then you might want to go with a generator instead.
def gen():
def eqn(b):
eqn.h = 2*b - eqn.h
return eqn.h
eqn.h = 0
return eqn
And then use thus
>>> f = gen()
>>> f(2)
4
>>> f(3)
2
>>> f(2)
0
>>>
The same effect could be acheived with a true generator using yield and send.
First of, do you need all the intermediate values? That is, do you want a list h from 0 to i? Or do you just want h[i]?
If you just need the i-th value you could us recursion:
def get_h(i):
if i>0:
return (2*b) - get_h(i-1)
else:
return h_0
But be aware that this will not work for large i, as it will exceed the maximum recursion depth. (Thanks for pointing this out kdopen) In that case a simple for-loop or a generator is better.
Even better is to use a (mathematically) closed form of the equation (for your example that is possible, it might not be in other cases):
def get_h(i):
if i%2 == 0:
return h_0
else:
return (2*b)-h_0
In both cases h_0 is the initial value that you start out with.
h = []
for i in range(len(b)):
if i>0:
h.append(2*b - h[i-1])
else:
# handle i=0 case here
You are successively applying a function (equation) to the result of a previous application of that function - the process needs a seed to start it. Your result looks like this [seed, f(seed), f(f(seed)), f(f(f(seed)), ...]. This concept is function composition. You can create a generalized function that will do this for any sequence of functions, in Python functions are first class objects and can be passed around just like any other object. If you need to preserve the intermediate results use a generator.
def composition(functions, x):
""" yields f(x), f(f(x)), f(f(f(x)) ....
for each f in functions
functions is an iterable of callables taking one argument
"""
for f in functions:
x = f(x)
yield x
Your specs require a seed and a constant,
seed = 0
b = 10
The equation/function,
def f(x, b = b):
return 2*b - x
f is applied b times.
functions = [f]*b
Usage
print list(composition(functions, seed))
If the intermediate results are not needed composition can be redefined as
def composition(functions, x):
""" Returns f(x), g(f(x)), h(g(f(x)) ....
for each function in functions
functions is an iterable of callables taking one argument
"""
for f in functions:
x = f(x)
return x
print composition(functions, seed)
Or more generally, with no limitations on call signature:
def compose(funcs):
'''Return a callable composed of successive application of functions
funcs is an iterable producing callables
for [f, g, h] returns f(g(h(*args, **kwargs)))
'''
def outer(f, g):
def inner(*args, **kwargs):
return f(g(*args, **kwargs))
return inner
return reduce(outer, funcs)
def plus2(x):
return x + 2
def times2(x):
return x * 2
def mod16(x):
return x % 16
funcs = (mod16, plus2, times2)
eq = compose(funcs) # mod16(plus2(times2(x)))
print eq(15)
While the process definition appears to be recursive, I resisted the temptation so I could stay out of maximum recursion depth hades.
I got curious, searched SO for function composition and, of course, there are numerous relavent Q&A's.
There are two examples.
# 1st example
>>> def accum(sum, a):
return sum + a
>>> sum = 0
>>> for sum in iter(lambda:accum(sum, 2), 40):
print sum,
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32...
# 2nd example
>>> def accum(sum, a):
return sum + a
>>> sum = 0
>>> for sum in iter(accum(sum, 2), 40):
print sum,
TypeError: iter(v, w) : v must be callable
Why lambda function doesn't make error but accum function makes error?
Thanks in advance :)
In neither case you are passing a function that takes arguments. In second case the value of v is bound to the integer 2, whereas in the first case v refers to a callable anonymous lambda function () -> sum + a.
The following 2 are almost equivalent:
def x():
return sum + a
x = lambda: sum + a
except lambda does not provide nice debugging traceback, since lambda functions are unnamed.
Also, the names of the variables are a bit misleading, took me a some moments to figure out what is happening. There are exactly 2 variables called sum - the one within accum function, and the other in the global scope. There is also the 3rd, masked one that contains the global built-in function sum...
The lambda is an anonymous function and is callable. If the notation is confusing, you can replace it with a named function:
def wrapper():
return accum(sum, 2)
for sum in iter(wrapper, 40):
The v argument must be callable. The result of accum(sum, 2) is an integer, which isn't callable.
OK, our professor explained (kinda) this problem, but it still doesn't make much sense.
Question: Implement the function knice(f,a,b,k) that will return 1 if for some integer a <= x <= b and some integer n <= k, n applications of f on x will be x, (e.g. f(f(f...(f(x)))) = x) and 0 if not.
What the professor provided was:
def knice(f,a,b,k):
f(f(f(...(f(x)))) = x
for i = a to b:
y = f(i)
if y = i break
for j = z to k:
y = f(y)
if y = i break
Personally, that example makes no sense to me, so looking to see if I can get clarification.
OP EDIT 1/19/2012 3:03pm CST
This is the final function that was figured out with the help of the GTA:
def f(x):
return 2*x-3
def knice(f,a,b,k):
x = a
while x <= b:
n = 1
y = f(x)
if y == x:
return 1
while n <= k:
y = f(y)
n=n+1
if y == x:
return 1
x=x+1
return 0
Ignore his code; you should write whatever you feel comfortable with and work out the kinks later.
You want to work out whether
f(a) = a, or f(f(a)) = a, or ..., or f^n(a) = a, or,
f(a+1) = a+1, or f(f(a+1)) = a+1, or ..., or f^n(a+1) = a+1, or,
...
f(b) = b, or f(f(b)) = b, or ..., or f^n(b) = b.
An obvious algorithm should come to mind immediately: try all these values one-by-one! You will need two (nested) loops, because you are iterating over a rectangle of values. Can you now see what to do?
Yeah, I can see why that might be confusing.
Was f(f(f(...(f(x)))) = x wrapped in triple-double-quotes? That's a function documentation string, sort of like commenting your code. It shouldn't have been stand-alone without something protecting it.
Imagine f was called increment_by_one.
Calling increment_by_one 10 times like that on an x of 2 would give 12. No matter how many times you increment, you never seem to get back 2.
Now imagine f was called multiply_by_one.
Calling multiply_by_one 5 times like that on an x of 3 would give 3. Sweet.
So, some example outputs you can test against (you have to write the functions)
knice(increment_by_one, 1, 3, 5) would return 0.
knice(multiply_by_one, 1, 3, 5) would return 1.
As another hint, indentation is important in python.
Here's a concrete example. Start small, and suppose you called knice(f, a=1, b=2, k=1). For k==1, we don't have to worry about iterating the function. The only values of x to consider are 1 and 2, so knice can return 1 (i.e., True) if f(1)==1 or f(2)==2.
Now suppose you called knice(f, a=1, b=2, k=2). You'll have to check f(f(1)) and f(f(2)) as well.
As k gets bigger, you'll have to call f more. And as the range between a and b gets bigger, you'll have to try more values of x as an argument to f.