How to call my function n times within another function - python

I am writing a filter function such that when I insert my wave number, which is a list of numbers, the filter_wave_num function will be executed n times to change the wave number.
However, it doesnt seem to work, it repeats the output only once, when I want it to do it n times. Will appreciate your help in this.
def filter_wave_num(wave):
new_wave = []
for i in range(len(wave)):
if i == 0:
new_wave.append(int(wave[i]*0.6 + wave[i+1]*0.2))
elif i == len(wave)-1:
new_wave.append(int(wave[i-1]*0.2 + wave[i]*0.6))
else:
new_wave.append(int(wave[i-1]*0.2 + wave[i]*0.6 + wave[i+1]*0.2))
return new_wave
def filter_wave(wave,n):
for i in range(n):
filter_wave_num(wave)
return filter_wave_num(wave)
wave = [600, 3200, 7600, 13400, 18400, 22600, 24400]
# each element inside the list has to be changed n times

The filter_wave_num function works.
If you need to use it recursively n times (each time on the result obtained the previous time) modify your second function like this:
def filter_wave(wave, n):
for _ in range(n):
wave = filter_wave_num(wave)
return wave
The function you have written creates each time a new list, but you don't return the result each iteration and it's lost.

You do call your function n times, but you are calling it with the same input so you get the same output after all iterations.
Here's what you need to do:
Notice that I changed the name of 'i' to '_', this is a convention indicates we don't need to use the value of this variable
def filter_wave(wave,n):
result = wave
for _ in range(n):
result = filter_wave_num(result)
return result

Store all the iteration results in a list and then return it:
def filter_wave(wave,n):
result = []
for i in range(n):
wave = filter_wave_num(wave)
result.append(wave)
return result

Related

I need to find a way to reset "count" after completing one test sample with out reseting count during the recursive function

This is what my code needs to do:
Write a function, persistence, that takes in a positive parameter num and returns its multiplicative persistence, which is the number of times you must multiply the digits in num until you reach a single digit.
Test.it("Basic tests")
Test.assert_equals(persistence(39), 3)
Test.assert_equals(persistence(4), 0)
Test.assert_equals(persistence(25), 2)
Test.assert_equals(persistence(999), 4)
This is a Codewars challenge. I can test assert samples individually but not all at once. Codewars need to be able to run all its test samples all at once. I need to find a way to reset count after completing one test sample without resetting count during the recursive function.
count = 0
def persistence(n):
# your code
global count
#def recursion(result):
number_str = str(n)
ints = [int(i) for i in number_str if i != '0']
result = 1
for j in ints:
result = result * j
if result >= 10:
print(ints,"\n\n------------------------------------------")
count += 1
print(count)
print(result)
return persistence(result)
else:
if count > 0:
count += 1
return count
else:
return count
This is the code I came up with. I need my function to run all four tests at once. My function can recursively render one test at a time, but not all tests at once. I need to figure out how to reset count after each test sample assertion.
Your recursive function should not need a global variable. You can pass counts as a parameter instead, with a default value to handle the public API case where it's not passed in:
def persistence(n, count=0):
...
# everything is the same up until the recursion
return persistence(result, count)
You could simplify the code a bit by just doing inline addition rather than using += statements on count, if you want, but it won't change the behavior of the code.
I'd also note that since your function is tail recursive, you could pretty easily replace the recursion with a loop. I think something like this might do it:
def persistance(n):
count = 0
while n >= 10:
count += 1
ints = [int(i) for i in str(n) if i != '0']
n = 1
for i in ints:
n *= i
return count
You can just pass along the count down the recursive call, like this:
count = 0
def persistence(n, count):
# ..
# update count
# ..
return persistence(result, count)
# ...
return count
or if you cant change the signature of persistance, use an auxiliary function, which is very common in functional programming.
def persistance(n):
return persistance_aux(n, 0)
def persistance_aux(n, count):
# ....

Use a variable in the for loop as input for a function

Suppose I have a function that sums:
def sum(x=10, y=15):
return x + y
And then a for loop:
for i in range(5):
a = sum() # 25
b = sum(a) # 40
c = sum(b) # 55
d = sum(c) # 70
The above is not right, but hopefully gives the idea that first "a" is assigned 25. Then I would like the second iteration to call the sum function, but use the first iteration as input for the first parameter in the sum function. Then in a third iteration, there would be a call to the sum function, with the second interation's value. I just added letters to make the example more clear, but those letters would actually refer to the iterations of the for loop.
Does anyone know how can I implement something like this?
def sum(x, y=15):
return x + y
a = 10
for i in range(5):
a = sum(a)
print("Output of "+str(i)+" iteration is : "+str(a))
print("Final output is : "+str(a))
As you explained in question:
You just need to assign one variable (i.e a=10) and pass it to function, then in first iteration function take first parameter as 10 and second parameter 15 which is default, it return 25. then in second iteration it pass 25 as first parameter and and default parameter as 15, it return 40 and so on ... this loop iterate for five time and at the end you will get result.
An alternative using a while loop:
def sum_(x, n, y=15):
counter = 0
while n > counter:
x += y
print(x)
counter += 1
sum_(10, 5)
By passing another variable n, you can define the range of the loop which will run until the counter matches. I've added the _ to the function name as it is generally frowned upon to overwrite the built-in functions.

Using recursion to append to a list python

I wrote a recursive program with python2 to obtain the multiplicative persistence of numbers;which is the number of times you must multiply the digits in a number until you reach a single digit. I also want to store all the successive multiplications in the list.
import operator
def persistence(n, count = []):
n = list(str(n))
if len(n) == 1:
return len(count)
else:
n = list(map(int, n))
n = reduce(operator.mul, n)
count.append(n)
return persistence(n)
The code works for the first function call made, but instead of resetting the count list to an empty list, it retains the values of whatever previously obtained values.
For the first function call:
persistence(39)
The output is 3. Which is the expected output.
However, when another function call is made:
persistence(4)
Instead of getting output 0, it outputs 3; which is the result of the first function call.
I think the problem is the global list. I tried declaring the list inside the function, but it just kept on resetting the list to empty on every recursive call.Can anyone help?
You have hit the common 'mutable default argument' gotcha.
Fixed code:
import operator
def persistence(n, count=None):
if count is None:
count = []
n = list(str(n))
if len(n) == 1:
return len(count)
else:
n = list(map(int, n))
n = reduce(operator.mul, n)
count.append(n)
return persistence(n, count) # pass in the list
Calling:
print persistence(39)
print persistence(4)
Produces:
3
0
From here: http://docs.python-guide.org/en/latest/writing/gotchas/
You'll need to set your list inside each call if it's not already set, like this:
from functools import reduce
import operator
def persistence(n, count = None):
if count is None:
count = []
n = list(str(n))
if len(n) == 1:
return len(count)
else:
n = list(map(int, n))
n = reduce(operator.mul, n)
count.append(n)
return persistence(n, count)
Note the changed recursive call at the end.

Returning a list from an iterated object in Python

I need help creating a list of iterated values. In this example, I want to get all odd numbers in the range of x. Then make a list from it:
def x_list(x):
for i in range(x):
if x%2==0:
return i
Since return stops the function after iterating through the first object, I'm unable to get the rest of the values and create a list from it.
Could you advice what I should use instead of "return"?
Thank you.
If you use yield instead of return, then you should be able to iterate through the whole range. This example will print out the even numbers.
def x_list(x):
for i in range(x):
if i%2==1:
yield i
for n in x_list(10):
print(n)
I also assume you want if i%2==1: not if x%2==0:, otherwise you'll get every number instead of just the odd ones.
Based on hop's suggestion, you could also do this:
evens = range(0, 10, 2)
for n in evens:
print(n)
Where the 3rd parameter in range is the step size
Define ret as a list at the top of the function, fill it within the loop.
After the loop ends, return it.
def x_list(x):
ret = []
for i in range(x):
if i%2==0:
ret.append(i)
return ret
With range, you can specify a stepping.
Therefore, all you need to do is:
def oddlist(x):
return list(range(1, x, 2))
If you don't actually need a list, and just an iterable will do, you could omit the list generation:
def oddlist(x):
return range(1, x, 2)

While loop executes once during return, runs fine during print [python]

I have two functions I'm using. I'm trying to make a bifurcation map. The first function I have is making the map using matplotlib.
def print_bifurcation_map(initial,rmin,rmax,rstep,iterates,k):
xn_list = []
r_list = []
for r in np.linspace(rmin, rmax,rstep):
xn = []
xn.append(run_logistic(initial,r,iterates))
xn_list =xn_list + xn[-k:]
r_list = r_list + [r]*len(xn)
What this code does is take a range of Rs and calculates the limit as x approaches a large number (iterates). We take the last k numbers from the list. It calls a function run_logistic which is below.
def run_logistic(xn,r,iterates):
iteration = 1
while iteration <= iterates:
xn1 = logistic_map(xn,r)
iteration = iteration + 1
xn = xn1
print xn
Here is where things get a little weird. when I use return and call through the function 'print_bifurcation_map' it runs once and appends once. However if I i change return xn to the 'print xn' which is what is in the code block now it seems to run more correctly albeit very very slowly.
So what am I doing incorrectly in either the print_bifurcation_map definition or the run_logistic function. Below is the logistic_map function.
def logistic_map(xn,r):
xn1 = r*xn*(1-xn)
return xn1
return exits the function at that point and outputs the returned value. So after the first iteration your value is returned at then it's done.
What are you trying to do with the function run_logistic return a final value or all values obtained?
If you want the final value then -
def run_logistic(xn,r,iterates):
iteration = 1
while iteration <= iterates:
xn1 = logistic_map(xn,r)
iteration = iteration + 1
xn = xn1
return xn # Put return outside while-loop to get final value
Otherwise if you want all values then create a list to append to and return that list
def run_logistic(xn,r,iterates):
iteration = 1
xn_list = []
while iteration <= iterates:
xn1 = logistic_map(xn,r)
iteration = iteration + 1
xn = xn1
xn_list.append(xn)
return xn_list # Put return outside while-loop to get full list of values

Categories