This question already has answers here:
Why does my recursive function return None?
(4 answers)
Closed 3 years ago.
I'm trying to solve a problem on CodeWars with the following specifications:
"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."
My solution is as follows:
def persistence(n,count = 0):
n = list(str(n))
if len(n) <= 1 :
count = 0
return count
else :
num_per = 1
for i in n :
num_per = num_per * int(i)
num_dump = num_per
if len(str(num_dump)) > 1:
count += 1
n = num_per
persistence(n,count)
else:
count = count + 1
return count
When I choose any number with more than a single digit, I get a return value of 'None'. I've narrowed down the problem to the last return statement in the second else clause. The number of counts are calculated correctly,but the return statement still returns a value of 'None'. Any help would be greatly appreciated.
Just add return before your persistence line:
return persistence(n, count)
Going off of what #jasonharper suggested, your function has an if/else statement which is decided by len(n) <= 1. If the length of n is less than 1, count (which is 0) is returned.
In your else statement however, you have another if/else statement. In your if statement, which is decided by len(str(num_dump)) > 1, you decide to recursively call the same function, however, you return no value. Therefore, your program most likely makes a lot of recursive calls but has no way of storing the values to be returned at the end of the program.
This can be fixed by replacing
persistence(n, count)
with
return persistence(n, count)
Related
Lately am trying to do some Python programming, so am doing some mathematical exercices in some website.
I came across this example and at first I didn't understand the exercise. So I checked the solution to at least understand the question. As a consequence I found myself learning some coding tricks (like the while True loop).
The exercise is simple:
Write a Python program to find the smallest multiple of the first n numbers. Also, display the factors.
Below is the code:
def smallest_multiple(n):
if (n<=2):
return n
i = n * 2
factors = [number for number in range(n, 1, -1) if number * 2 > n]
print(factors)
while True:
for a in factors:
if i % a != 0:
i += n
break
if (a == factors[-1] and i % a == 0):
return i
My questions are:
Why does he create a list of numbers that are superior to the input by a factor of 2?
And then the while loop is just difficult to undestand. Could someone please explain it to me (I mean the content of the loop)?
I think we have here a tiny mixture of mathematic question and programming.
first of all, please note that the spaces are important in coding. see how the code should look like. (with the spaces)
def smallest_multiple(n):
if (n<=2):
return n
i = n * 2
factors = [number for number in range(n, 1, -1) if number * 2 > n]
print(factors)
while True:
for a in factors:
if i % a != 0:
i += n
break
if (a == factors[-1] and i % a == 0):
return i
1- Why does he create a list of numbers that are superior to the input by a factor of 2 ?
Answer : because the numbers that have their double smaller than the highest number will not affect / change the result. (This is a maths question) you can check that by removing the condition and you will see that you will get the same result (same smallest multiple)
2-And then the while loop is just difficult to understand. Could someone please explain it to me (I mean the content of the loop)? Thanks for your response?
Answer : The loop is using the boolean True as the code will only stops until it finds the smallest multiple for the first n numbers. the reason of the coder doing this because he has used the keyword return that will help him to exit the function, ultimately exiting the while loop.
The loop uses the value i which is the first multiple of the highest number of the first n numbers, meaning the double of the value n. Then will check if this first multiple (meaning i) is not dividable (i % a != 0) by the numbers in the list starting from the highest.
if i % a != 0:
i += n
break
this condition is there to increase the value of i as soon as i is not dividable by any number of the first n numbers meaning that the code keeps searching through the multiples of n (n being the highest number of the list) until i is dividable by all the numbers in the list
once the i value is able to satisfy the condition below
if (a == factors[-1] and i % a == 0):
then the while loop is exited through the keyword return which exits the function and the i value is sent as a response to the function call through the line return i
also note that factors[-1] is the last item (number) of the list.
I hope the above make sense and is clear to you.
This question already has answers here:
Why does my recursive function return None?
(4 answers)
Closed 2 years ago.
I'm having this extremely strange problem and I guess it's something simple but it just makes no sense to me.
CodeWars question states:
Define a function that takes a multi digit number and multiplies each digit until you get a single digit answer, so for example persistence(39) would compute 3*9 = 27, 2*7 = 14, 1*4 = 4, return 4
I wanted to try and solve this recursively, and I have the answer, but the program will never break out of the function. I've stepped through this program multiple times and it gets to the return statement and then jumps back up into the if statement and calls persistence again.
Code below:
def persistence(n):
arg_to_list = list(str(n))
# If the argument is > one digit
if len(arg_to_list) > 1:
total = int(arg_to_list[0])
for digit in arg_to_list[1:]:
# Don't want any muplication by 0
if digit != "0":
total *= int(digit)
# Call the function again on the total
persistence(total)
else:
return n
You are not returning anything unless the number is 1-digit already, so your recursion doesn't pass over the result up. Here is what your code should look like (note the return statement just before else: - it is the only change from the original code):
def persistence(n):
arg_to_list = list(str(n))
# If the argument is > one digit
if len(arg_to_list) > 1:
total = int(arg_to_list[0])
for digit in arg_to_list[1:]:
# Don't want any muplication by 0
if digit != "0":
total *= int(digit)
# Call the function again on the total
return persistence(total)
else:
return n
Note - Go down to the edits if you want the more recent code, look here if you want to see the original question. I have made edits to the code, however, so mistakes in this code block may be outdated.
As a self-taught Python 3 programmer, I have been working on a way to simplify radical expressions. The one part of the program that does not work, however, is the square factorization. I have a function that detects square numbers, which works fine. The function that does not work is the following-
def sqfactorslist(num):
factors = []
counter = num // 2 + 1
while counter > 0:
if counter == 1:
factors.append(num) #if no square ints other than 1 square into num, append and finish.
while is_square(counter) == True and counter != 1: #If counter is a valid square integer, append it's square and subtract it from num.
if (counter ** 2) >= num:
factors.append(counter ** 2)
num -= counter ** 2
else: #Else, continue with a program.
break
if counter > 0:
counter -= 1 #If counter more than 0, subtract 1 from it
else:
break #If number is equal to or less than 0, break
return factors #If the input is 32, this should return 16 and 2.
It doesn't return anything other than an infinite loop. Anyone know whats wrong?
Edit 1 -- I have changed the program so that it runs, but now I have a stranger issue: If I input a square number as num, for example 16, I get a number larger than the input, e.x. 81, in the return list. I get no returned elements for a non-square number.
To make it run, I indented the first if statement after the end of the second while loop.
Edit 2 -- I have changed the program again, but I come up with another issue similar to the one above. After eliminating another mistake, where I squared numbers already shown to be square, found in the second while loop, the program now has a new problem - If I use a non-square integer, it returns an empty list, and if I use a square integer, like 16, it gives me an infinite loop. Current code shown below --
def findsqfactors(num):
factors = []
counter = num // 2 + 1
while counter > 0:
if counter == 1:
factors.append(num) #If no square ints other than 1 square into num, append then finish.
while is_square(counter) == True and counter != 1: #
if counter >= num:
factors.append(counter)
num -= counter
else:
break
if counter > 0:
counter -= 1
else:
break
return factors
I am new to Python and I am taking Codecademy lessons required by my teacher. The instructions read, Define a function factorial that takes an integer x as input.
Calculate and return the factorial of that number.
For my code, I put,
def factorial(x):
if x == 1:
return factorial('n' - 1)
When I clicked save and submit code, it gave me this error message,
unsupported operand type(s) for -: 'str' and 'int'
I tried looking at the codecademy Q and A forum, but I didn't find anything feasible. I even went on this site and looked up what the error message meant. I looked at the hint provided by codecademy and it just made me more confused! Please help. Any feedback/ advice is always helpful. Thanks!
You are trying to subtract the number 1 from the letter n. Instead you should subtract 1 from the number you were given.
As far as I can tell, you are trying to make a factorial function using recursion. Your code has a few problems:
def factorial(x):
if x == 1:
return factorial('n' - 1)
First of all, on line 3 you are trying to subtract 'n' (a String) from 1 (an Integer). Remove the quotes to fix this.
Secondly, (if my previous statement was correct) your function takes input as x, not n. You are probably trying to do:
def factorial(x):
if x == 1:
return factorial(x - 1)
You are passing a string 'n' in to your factorial method. There are two problems with this:
1) You cannot perform a subtraction operation by trying to do 'n' - 1 (string type - int type).
2) You most likely meant to pass x instead of 'n'.
Next, your recursive algorithm for checking a factorial is incorrect.
You need to take the number, multiplied by the return of calling the factorial method again, but passing the number subtracted by 1. But then you need your "exit" condition, which is when the number reaches a value below 1:
def factorial(x):
if x < 1:
return 1
else:
return x * factorial(x - 1)
The error shows that you are trying to manipulate two things of different types, integer and string. Ans also it seems that your function "factorial" will only work if you give it an integer number 1. You can simply do this with while loop; (keep in mind the TYPES of things you want to manipulate).
def factorial(x):
n=1
total = x
last_int = x
while n < total:
x = x * (last_int-1)
n += 1
last_int -= 1
return x
if __name__ == "__main__":
while 1:
number = raw_input("enter number: ")
result = factorial(int(number))
print 'factorial number for ' + str(number) + ' is ' + str(result)
There's also another way to fix the task. You can use range with a negative step -1 and multiply from x to 1:
def factorial (x):
total = 1
if x < 1:
return total
else:
for i in range(x, 0, -1):
total *= i
return total
If you have another method that can help me I will appreciate your help, I tried my best to write a code that calculates the number of zeroes in a given number.
Here's the code I tried:
def zrc(n):
count=0
while n%10==0 and n!=0:
n=n%10
count=count+1
return count
print(zrc(2500))
it just gives 1 as output of the code, while it must print 2, but for numbers like 36, it gives 0 as output, what is the problem? I know there must be a problem with that while...
If n%10 is zero, n is zero in the next step, so the condition is always fulfilled after the first loop. You probably want to use // instead of %:
def zrc(n):
count = 0
while n%10 == 0 and n != 0:
n //= 10
count += 1
return count
while n%10==0 and n!=0:
n=n%10
See the above lines. If the condition in the while loop is true, n=n%10 line will be executed.
This line will make your n=0 no matter what. For example,
2500%10 = 0
25000%10 = 0
250000%10 = 0
So, there is no chance that your loop condition will be True during the second iteration, so no chance of increment count variable more than once.
So, no matter what is your n is, you always get the output 1.
In your code, Change this:
n=n%10
To this:
n=n/10
An alternative way, might help you.
from collections import Counter
def zrc(n):
valDict=Counter(str(n))
return valDict['0']
print(zrc(2500))