Recursion functions for factorial - python-3.x

I am writing this code to get the 10! ,however, I believe I have an infinite loop in there since it keeps repeating the same error code. I am trying to find the issue but can not seem to.
def calculatingfactor(num2cal):
"""this fuction will be calculating a mathematical factorial"""
if num2cal == 1:
returnvalue = 1
elif num2cal <= 0:
returnvalue = 0
else:
print("Calculating the facterial of {}".format(num2cal))
variable2 = calculatingfactor(num2cal - 1)
returnvalue = calculatingfactor(num2cal*variable2)
return
#main code
first_fact=calculatingfactor(10)
print (first_fact)

The recursive case of your code looks incorrect to me. You should be calling the same function with num2cal decremented by one, then returning the current value multiplied by whatever that recursive call returned.
def calculatingfactor(num2cal):
if num2cal == 1:
return 1
elif num2cal <= 0:
return 0
else:
print("Calculating the facterial of {}".format(num2cal))
variable2 = calculatingfactor(num2cal - 1)
return num2cal*variable2
# main code
first_fact=calculatingfactor(10)
print (first_fact)

Related

How to fix this loop for special cases in Python

So I got assigned a homework where I have to do the convexHull problem by brute force (this is to then later compare the complexity vs the normal complexHull), and I have this code:
def determineSideLocation(A,B,P):
#Takes point A and B and creates a vector (A ---> B), direction sensitive
d = ((P[0] - A[0])*(B[1] - A[1])) - ((P[1] - A[1])*(B[0] - A[0]))
if d < 0:
#To the left of AB
return -1
elif d > 0:
#To the right of AB
return 1
elif d == 0:
#On AB
return 0
And now I determine if all the points I want to compare are on one side or not:
def isAllPointsOnOneSide(vector, pointList):
pointSideList = []
print("vector: " + str(vector))
print("pointList: " + str(pointList))
for i in pointList:
pointSideList.append(determineSideLocation(vector[0], vector[1], i))
print("pointSideList: " + str(pointSideList))
for j in range(0, len(pointSideList) - 1):
if pointSideList[j] == 0:
continue
elif pointSideList[j+1] == 0:
#2 options:
#1. pointSideList[j+1] is at the end of the list (j+1 = len(pointSideList) - 1)
#2. pointSideList[j+1] is not at the end of the list
if j+1 == (len(pointSideList) - 1):
continue
else:
if pointSideList[j+2] == 0:
if j+2 == (len(pointSideList) - 1):
continue
else:
if pointSideList[j] != pointSideList[j+3]:
return False
else:
continue
elif pointSideList[j] != pointSideList[j+2]:
return False
else:
continue
elif pointSideList[j] != pointSideList[j+1]:
return False
else:
continue
return True
There is the convexHull function but its not where the problem lies. The thing is: in the isAllPointsOnOneSide function, it takes the list of points and makes a list of values relative to the vector, which can only be 1 (to the right), -1 (to the left) and 0 (in the vector).
I got an ankward case where the relative values were this: [-1,0,0,0,0] and the function breaks itself and gives a False value despite being True (all points are on the vector or on one side). I know its in the exception part, where it tries to skip comparing the current value to a 0, but I know its not ideal to keep writing more exceptions to that part.
How can I fix it to avoid the cases where the function breaks? Where it has to compare with 0 at the end of the list
#Heike gave me the answer, and it was rather simple :P
def isAllPointsOnOneSide(vector, pointList):
pointSideList = []
for i in pointList:
pointSideList.append(determineSideLocation(vector[0], vector[1], i))
minValue = min(pointSideList)
maxValue = max(pointSideList)
#If max - min is higher than 1, its a False result.
if maxValue - minValue > 1:
return False
else:
return True
I'm sorry, and after all it was a rather simple problem, but I have been on this for several hours now (brute forcing the convexhull) and it frustated me.
Thanks to Heike again

Next Palindrome number

I want the final number as returned by the function, the following code is running, but not returning the correct value, the correct value is printed by the print statement above return satatement, how can return it ??
the correct answer is 22. but 13 is too printed.
def palindrome(num):
num = num+1
num = str(num)
if num[::-1]!=num:
palindrome(int(num))
else:
print(int(num))
return int(num)
palindrome(12)
>RESULT---
22
13
Seems that this could be done in a better way.
def palindrome(num):
if str(num) == str(num)[::-1]:
print(num)
return num
else:
palindrome(num+1)
Your recursive function returns 13 because this is the result of the first call to your function. The other iterations from your recursion are lost since you don't save it in your recursive call to palindrome.
You'll want to set your call to palindrome as your return also:
if num[::-1] != num:
return palindrome(int(num))
a = int(input("enter the no. of choices"))
for i in range(a):
b = int(input("enter all no."))
for j in range(b , 10000000000000000):
count = 0
pal = str(j)
b += 1
if (pal == pal[::-1]):
print(j)
break
else:
continue

Count not incrementing properly in python while loop

Can anyone tell me why when I input 1, 2, 3, and 4 into this code, my output is 6, 2, 3.00? I thought that every time my while loop evaluated to true it would increment the count by one, but the output is not making sense. It's taking the total of 3 of the numbers, but only 2 for the count? I'm probably just overlooking something so an extra pair of eyes would be awesome.
def calcAverage(total, count):
average = float(total)/float(count)
return format(average, ',.2f')
def inputPositiveInteger():
str_in = input("Please enter a positive integer, anything else to quit: ")
if not str_in.isdigit():
return -1
else:
try:
pos_int = int(str_in)
return pos_int
except:
return -1
def main():
total = 0
count = 0
while inputPositiveInteger() != -1:
total += inputPositiveInteger()
count += 1
else:
if count != 0:
print(total)
print(count)
print(calcAverage(total, count))
main()
The error with your code is that on this piece of code...
while inputPositiveInteger() != -1:
total += inputPositiveInteger()
You first call inputPositiveInteger and throw out the result in your condition. You need to store the result, otherwise one input out of two is ignored and the other is added even if it is -1.
num = inputPositiveInteger()
while num != -1:
total += num
count += 1
num = inputPositiveInteger()
Improvements
Although, note that your code can be significantly improved. See the comments in the following improved version of your code.
def calcAverage(total, count):
# In Python3, / is a float division you do not need a float cast
average = total / count
return format(average, ',.2f')
def inputPositiveInteger():
str_int = input("Please enter a positive integer, anything else to quit: ")
# If str_int.isdigit() returns True you can safely assume the int cast will work
return int(str_int) if str_int.isdigit() else -1
# In Python, we usually rely on this format to run the main script
if __name__ == '__main__':
# Using the second form of iter is a neat way to loop over user inputs
nums = iter(inputPositiveInteger, -1)
sum_ = sum(nums)
print(sum_)
print(len(nums))
print(calcAverage(sum_, len(nums)))
One detail worth reading about in the above code is the second form of iter.

why is the print() function prints none in this case

I've been working on a problem I don't understand why the recursive function step returns None?
here is the code :
import sys
def minIndx(list):
x=10
indx=0
for i in range(len(list)):
if (list[i]<x):
x=list[i]
indx=i
return indx
def steps(arr,sum1,sum2,x):
i = minIndx(arr)
del arr[i]
sum1 = sum(arr)
if (sum1 + 9*x >= sum2):
return x
else: steps(arr,sum1,sum2,x+1)
s=input()
digits1=[]
digits2=[]
for i in range(len(s)):
if (i>2):break
digits1.append(int(s[i]))
for i in range(len(s)):
if (i<3):continue
digits2.append(int(s[i]))
sumLeft = sum(digits1)
sumRight = sum(digits2)
print(steps(digits1,sumLeft,sumRight,1))
for the test case : 123456,
the step function prints None as well as the print function
It could be because you're not returning your recursive call. What is your expected output here? When I return the recursive call to steps I get a value of 2 for an input of 123456.

Python recursive function returning none after completion

My code is supposed to countdown from n to 1. The code completes but returns None at the end. Any suggestions as to why this is happening and how to fix it? Thanks in advance!
def countdown(n):
'''prints values from n to 1, one per line
pre: n is an integer > 0
post: prints values from n to 1, one per line'''
# Base case is if n is <= 0
if n > 0:
print(n)
countdown(n-1)
else:
return 0
def main():
# Main function to test countdown
n = eval(input("Enter n: "))
print(countdown(n))
if __name__ == '__main__':
main()
print(countdown(n)) prints the value returned by countdown(n). If n > 0, the returned value is None, since Python functions return None by default if there is no return statement executed.
Since you are printing values inside countdown, the easiest way to fix the code is to simply remove the print call in main():
def countdown(n):
'''prints values from n to 1, one per line
pre: n is an integer > 0
post: prints values from n to 1, one per line'''
# Base case is if n is <= 0
if n > 0:
print(n)
countdown(n-1)
def main():
# Main function to test countdown
n = eval(input("Enter n: "))
countdown(n)
if __name__ == '__main__':
main()
Edit: Removed the else-clause since the docstring says the last value printed is 1, not 0.
Remove the print(countdown(n)) and replace it with just countdown(n).
What happens is your countdown function returns nothing when n is greater than 0, so that print statement is printing None. You can also remove your else statement in countdown(n) - since you never care about the return value of countdown, it serves no purpose.
def countdown(n):
'''prints values from n to 1, one per line
pre: n is an integer > 0
post: prints values from n to 1, one per line'''
# Base case is if n is <= 0
if n > 0:
print(n)
countdown(n-1)
# No need to return a value from here ever - unused in the recursion and
# you don't mention wanting to have zero printed.
#else:
# return 0
def main():
# Main function to test countdown
n = eval(input("Enter n: "))
# Don't print the result of countdown - just call it
#print(countdown(n))
countdown(n)
if __name__ == '__main__':
main()
You want to return the recursive call to the next invocation of countdown:
def countdown(n):
'''prints values from n to 1, one per line
pre: n is an integer > 0
post: prints values from n to 1, one per line'''
# Base case is if n is <= 0
if n > 0:
print(n)
return countdown(n-1)
else:
return 0
def main():
# Main function to test countdown
n = eval(input("Enter n: "))
print(countdown(n))
if __name__ == '__main__':
main()
In this way, when the base case is reached, the return value of 0 should propagate back up the stack and be returned.
Unfortunately, however, since your base case returns 0, this results in the printing of 0. But, if you want to return something (think about whether or not you actually need to in this case) this would be how you do it.
If you don't need to return anything, then you don't need to print the result. Further modify
print(countdown(n))
to
countdown(n)

Resources