Calculating a factorial using loops in Python3 - python

I am currently studying Software Development as a beginner and I have a task in my programming class to calculate and display a factorial using a loop. I've been given the pseudo-code and have to translate it into true code and test it in the REPL to make sure it returns the expected results.
I almost have it but I've run into two issues that I just can't seem to resolve.
1) The function is returning an extra line of "None" after the calculation and
2) The answer is displaying over multiple lines when I want it to display on a single line.
My current code (which does return the correct answer) is as follows:
def calcFactorial(number):
factorial = 1
print(str(number)+"! =", number)
for count in range (1, number):
if number-count > 0:
factorial = factorial*number-count
print("x", str(number-count))
factorial = factorial*number
print("=", factorial)
When I test, using 3 for example, the REPL returns the following:
>>> print(calcFactorial(3))
3! = 3
x 2
x 1
= 12
None
So I have the correct answer but with an extra line of "None" which I would like to remove (I believe it has something to do with the print function?) and I don't know how to format it correctly.
Any help would be much appreciated.

your function calcFactorial(3) prints already, so you shouldn't call it with
print(calcFactorial(3))
just call it with
calcFactorial(3)
without the print function.
you might think about calling the function calc_and_print_factorial() in order to make it clear, that this function does already the printing

Regarding your second question:
Blockquote
2) The answer is displaying over multiple lines when I want it to display on a single line.
You can fix it by using a single print statement:
def calcFactorial(number):
factorial = 1
string = str(number) + "! = " + str(number)
for count in range (1, number):
if number-count > 0:
factorial = factorial*(number-count)
string = string + " x " + str(number-count)
factorial = factorial * number
print(string + " = " + str(factorial))
This will give you:
IN: calcFactorial(3)
OUT: 3! = 3 x 2 x 1 = 6
On a side note: you might want to think of how to implement this recursively. Maybe that comes later in your class but this would be one of the first go-to examples for it.

Adding to the blhsing's answer, you should choose between these built-in ways to print the "returned" value.
First way:
def calcFactorial(number):
... # <- Your function content
return factorial
Then, call your function with a print() to get the explicitly returned value, as you can see in the return factorial line. See this reference for more details:
print(calcFactorial(3))
Second way:
Having the same function definition with its return statement, just call the function with its instance statement:
calcFactorial(8)
By default, python will print the returned value without a print()
Third way:
Just call the function (without the explicit return statement, this will return a "None" (null-like) value by default), using the print() method. Do NOT use print() inside another print().

Your calcFactorial function does not explicitly return a value, so it would return None by default, so print(calcFactorial(3)) would always print None.
You should make the calcFactorial function return factorial as a result at the end:
def calcFactorial(number):
factorial = 1
print(str(number)+"! =", number)
for count in range (1, number):
if number-count > 0:
factorial = factorial*number-count
print("x", str(number-count))
factorial = factorial*number
print("=", factorial)
return factorial

So I have the correct answer but with an extra line of "None" which I would like to remove
You are printing the return value from your function. In this case, you haven't specified a return value with a return statement so the function automatically returns None.
To fix the problem, you should return a value from your function. Note that you don't need to call print() for final answer because the REPL already does this for you.
Note that the REPL will automatically print the return value for you, so you can just type calcFactorial(3) instead of print(calcFactorial(3)).
Additionally, you are not getting the correct answer. You should get 6 instead of 12. It looks like you are trying to count down from number and multiplying each number together. You can get the same result by counting up from 1. This will lead to much simpler code and avoid the error.
If you want to understand why your code isn't doing the correct thing, look closely at factorial = factorial*number-count and think about the order of operations that are used to calculate the result here.

Related

Unable to properly return python data in function

I've been at this for hours and hours. I think my problem is I need to use a return in my first function so that I can use this function as an argument in my second function. However, it seems that if I use a return, the data is somehow not being passed properly to the second function. I say that because I can't seem to format it properly if i comment out my print statement and only use a return (the return statement won't let me include the end = '' so it comes out vertically instead). Then the second function just spits out the first digit of my first function's return. I'm so lost and i need to get some sleep now I guess. Been up all night with this. Is there some way I can return the data int he first function and make it be a nice horizontal string like it would be if I used my print statement instead? (Or does that not matter and I'm way off track?) Please let me know if I can clarify something. Just a nudge in the right direction would help.
Instructions: Write a program that takes in a positive integer as
input, and outputs a string of 1's and 0's representing the integer in
binary. For an integer x, the algorithm is:
As long as x is greater than 0
Output x % 2 (remainder is either 0 or 1)
x = x // 2
Note: The above algorithm outputs the 0's and 1's
in reverse order. You will need to write a second function to reverse
the string.
Ex: If the input is:6
the output is:
110
The program must define and call the following two functions.
Define a function named int_to_reverse_binary() that takes an integer
as a parameter and returns a string of 1's and 0's representing the
integer in binary (in reverse).
Define a function named
string_reverse() that takes an input string as a parameter and returns
a string representing the input string in reverse. def
int_to_reverse_binary(integer_value) def string_reverse(input_string)
My code:
Define your functions here.
def int_to_reverse_binary(int_number):
while int_number > 0:
#print (int_number % 2, end='')
return int_number % 2
int_number = int_number // 2
def string_reverse(input_string):
for i in reversed(str(input_string)):
print(i,end='')
if __name__ == '__main__':
# Type your code here.
# Your code must call int_to_reverse_binary() to get
# the binary string of an integer in a reverse order.
# Then call string_reverse() to reverse the string
# returned from int_to_reverse_binary().
x = int(input())
int_to_reverse_binary(x)
string_reverse(int_to_reverse_binary(x))
1: Compare output
0 / 2
Output differs. See highlights below.
Input
6
Your output
0
Expected output
110
2: Unit test
0 / 2
Convert 19 to binary using int_to_reverse_binary() and string_reverse()
Your output
1
Test feedback
string_reverse(user_input) did not return a value.
Your function may be missing a return statement.
3: Unit test
0 / 3
Convert 255 to binary using int_to_reverse_binary() and string_reverse()
Your output
1
Test feedback
string_reverse(user_input) did not return a value.
Your function may be missing a return statement.
The return statement in Python also acts as the ending point of the function. i.e. no statement will be executed once a return statement is encountered in a function. So, when the while loop is being executed, the interpreter sees a return statement and stops executing any further. If you wish to return multiple values from the function you can do 2 things,
Instead of using a while loop in s function, use the function in the while loop:
Sample Code:
def foo(num):
return num % 2
i = 0
while i< 10:
print(foo(i))
i += 1
Use a list to return all values at once. Sample Code:
def foo(num):
a = []
i = 0
while i < num:
a.append(i)
i+=1
print(foo(10))
Code With corrections:
def int_to_reverse_binary(int_number):
# print('i', int_number)
a = []
while int_number > 0:
a.append(int_number % 2)
int_number = int_number // 2
# print('a', a)
return a
def string_reverse(input_string):
print(''.join([str(i) for i in input_string])[::-1])
if __name__ == '__main__':
x = int(input())
# a = int_to_reverse_binary(x)
string_reverse(int_to_reverse_binary(x))
You seem to have made this unnecessarily complex. f-string formatting will give you the binary representation of your integer then reverse the string with a slice as follows:
def int_to_reverse_binary(int_number):
return f'{int_number:b}'[::-1]
print(int_to_reverse_binary(100))
Output:
0010011

Finding multiples using recursion

Given 1 to 100 numbers, for multiples of 3 it should print "he" ,for multiples of 5 it should print "llo" ,for both multiples of 3 and 5 it should print "hello".
This is what I have:
for i in range (1,100):
if(i%3==0):
print("he")
elif(i%5==0):
print("llo")
elif(i%3==0 and i%5==0):
print("hello")
How would I do this recursively?
How about the code below?
def find_multiples(current, last_num=100):
# Base Case
if current > last_num:
return
result = ""
if current % 3 == 0:
result += "he"
if current % 5 == 0:
result += "llo"
if result:
print(f"{current}: {result}")
find_multiples(current+1, last_num)
find_multiples(1)
Base case is if current reaches last_num or the maximum number you'd like to check.
Here is a general outline for doing simple recursive things in python:
BASE_CASE = 1 #TODO
def f(current_case):
if current_case == BASE_CASE:
return #TODO: program logic here
new_case = current_case - 2 #TODO: program logic here ("decrement" the current_case somehow)
#TODO: even more program logic here
return f(new_case) + 1 #TODO: program logic here
Of course, this doesn't handle all possible recursive programs. However, it fits your case, and many others. You would call f(100), 100 would be current_value, you check to see if you've gotten to the bottom yet, and if so, return the appropriate value up the call stack. If not, you create a new case, which, in your case, is the "decrement" logic normally handled by the "loop" construct. You then do things for the current case, and then call the function again on the new case. This repeated function calling is what makes it "recursive". If you don't have an "if then" at the beginning of the function to handle the base case, and somewhere in the function recall the function on a "smaller" value, you're probably going to have a bad time with recursion.
This recursive function prints multiples of a number! hope it helps
def multi(n,x):
if x == 12:
print(n*x)
else :
print(n*x,end =",")
multi(n,x+1)
print(multi(4,1));

How does the code prints 1 2 6 24 as output and not 24 6 2 1

def recurr(k):
if (k>0):
result =k*recurr(k-1)
print(result)
else:
result=1
return result
recurr(4)
Output:
1
2
6
24
Because you're printing result after you recurse.
When you call recurr(4), the first thing it does is call recurr(3). This calls recurr(2), then recurr(1), and finally recurr(0). This last one is the base case, so it returns 1.
After that returns, you calculate result = k * 1, which is result = 1 * 1, then it prints that, so it prints 1 and then returns 1.
Then the previous recursion calculates result = k * 1, which is result = 2 * 1, then it prints that, so it prints 2 and returns it.
This repeats through all the recursions.
Its because you were printing result everytime you called it inside function instead of print what first call of function returned.
def recurr(k):
if (k>0):
return k*recurr(k-1)
return 1
print(recurr(4)) # -> 24
Because in every call of the function recurr() the print() function is executed.
If you want to print 24 that's the code:
def recurr(k):
if (k>0):
result =k*recurr(k-1)
else:
result=1
return result
print(recurr(4))
The recursion stack will print your message multiple times. This snippet may clarify why:
def factorial(k):
if (k>0):
print(f'factorial({k}) calls factorial({k-1})')
result = k*factorial(k-1)
else:
print(f'factorial({k}) is the base case')
result=1
return result
print(factorial(4))
you have to remove the print part in your function. Instead, you should write the code like this at the end of the code:
print(recurr(4))
The point is, the function is calling itself, and each time the function is called and processes the "if" block, it throws out a print. as for the order, the function evaluates the brackets inside out. As stated by #timgeb in comments,
recurr(4) --> 4*recurr(3*recurr(2*recurr(1*recurr(0))))
This evaluates recurr(0), which then successfully evaluates recurr(1) and so on.
The recursion in your code occurs on line 3, and the print statement occurs on line 4, after the recursion. When executing recurr(4), the entire code for recurr(3) (including the print statement for recurr(3)) is executed before the print statement for recurr(4).
Get 4 friends. Label them 1!, 2!, 3! and 4!. Tell them that if asked what their value is they must ask (n-1)! for their value, and then multiply by n, write it on a bit of paper and hand to the asker. All asking, must also be done on a bit of paper.
Now ask 4! for their value, when you get it shout it out.
Next tell them to do the same but whenever they pass a bit of paper to someone, they mast also shout out the value. Record what happens.
Which of the shouters is the one to keep?
When you use recursion, you build up a set of operation on the way down to the last call. Then you unroll them from the last, backwards up out to the first.
In this toy, you build up your result from the highest number, by putting your operation (k*next_value) at the bottom, and build it up. Then you get the result of each operation, from the top to the bottom.

Incrementation to a list's for method

I am trying to implement an incrementation to a previously defined variable called sum.
return [sum = sum + number for number in range(a,b)]
Of course this format brings up error but using the similar:
return [sum = number for number in range(a,b)]
The code is faulty but runs. If there's a way to implement it and return sum the code would work.
And also if someone could inform me about the nomenclature I'd forever be grateful.
Here are a few possible answers. What you are using is called a list comprehension.
s += (b*(b-1) - a*(a-1))//2
s += sum([n for n in range(a,b)])
for n in range(a,b):
s += n
It's not a good idea to name a variable sum as it is a built in Python function.
Try the following:
return sum([number for number in range(a,b)])
As said in the commentaries, sum is a python built-in function which, given an array, it returns the result of the addtion of all elements in it
You essentially reimplemented the built-in function sum. Just call the function directly:
return sum(range(a, b))

I need help wrapping my head around the return statement with Python and its role in this recursive statement

No this isn't homework but it is on our study guide for a test. I need to understand the role the return statement plays and the role recursion plays. I don't understand why the function doesn't break after x = 1.
def thisFunc(x):
print(x)
if x>1:
result=thisFunc(x-1)
print(result)
return x+1
Sorry, I understand how elementary this is but I could really use some help. Probably why I can't find an explanation anywhere...because it's so simple.
edit: Why does it print out what it does and what and why is the value of x at the end? sorry if I'm asking a lot I'm just frustrated
When you enter the function with a value n>1 it prints the current value, and then calls it's self with n-1. When the inner function returns it returns the value n - 1 + 1 which is just n. Hence, the function prints out the value n twice, once before the inner recursion and once after.
If n == 1, which is the base case, the function only prints 1 once and does not call it self again (and hence does not get result back to print). Instead it just returns, hence why 1 is only printed once.
Think of it like an onion.
calling thisFunc(n) will result in
n
# what ever the output (via print) of thisFunc(n-1) is
n
I don't understand why the function doesn't break after x = 1.
But it does:
>>> ================================ RESTART ================================
>>> x = 1
>>> def thisFunc(x):
print("Function called on x-value: ", x)
if x > 1:
result = thisFunc(x-1)
print(result)
return x+1
>>> thisFunc(x)
Function called on x-value: 1
2
>>>
edit: Why does it print out what it does and what and why is the value of x at the end?
Well, it prints it out because you're telling it to. Try following the value of x as you go through the function ("x is one, one is not bigger than 1; return 1+1. Ok. [new case] x is two, two is bigger than 1..." and so on).
return and recursion are part and parcel of programming; return statements designates the end of a function (even if you might have several lines more of code) and they also pass data back to whatever asked them for it. In your case you're asking "what happens when x is 1, given these rules?"; the returned data is your answer.
Recursion is simply the matter of letting the function call itself, should it (you) need to. You simply tell the program that "hey, as long as x is bigger than 1, call this function [that just so happens to be the same function initially called] on it and let it do its thing". To get a better understanding of your function I'd suggest that you add the line "Function called on x-value: " to the first print statement inside the function, or at least something that lets you identify which printed line is x and which is result.
For a more in-depth explanation on recursion, I recommend Recursion explained with the flood fill algorithm and zombies and cats

Categories

Resources