Practice Makes Perfect factorial - python

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

Related

WAP in python script to input a multidigit number and find each of the number's factorial

The output shows a different result. Yes, the factorials of those numbers are right but the numbers outputted aren't right.
Here's the code:
input:
n = int(input("Enter a number: "))
s = 0
fact = 1
a = 1
for i in range(len(str(n))):
r = n % 10
s += r
n //= 10
while a <= s:
fact *= a
a += 1
print('The factorial of', s, 'is', fact)
Output:
Enter a number: 123
The factorial of 3 is 6
The factorial of 5 is 120
The factorial of 6 is 720
You're confusing yourself by doing it all in one logic block. The logic for finding a factorial is easy, as is the logic for parsing through strings character by character. However, it is easy to get lost in trying to keep the program "simple," as you have.
Programming is taking your problem, designing a solution, breaking that solution down into as many simple, repeatable individual logic steps as possible, and then telling the computer how to do every simple step you need, and what order they need to be done in to accomplish your goal.
Your program has 3 functions.
The first is taking in input data.
input("Give number. Now.")
The second is finding individual numbers in that input.
for character in input("Give number. Now."):
try:
int(character)
except:
pass
The third is calculating factorials for the number from step 2. I won't give an example of this.
Here is a working program, that is, in my opinion, much more readable and easier to look at than yours and others here. Edit: it also prevents a non numerical character from halting execution, as well as using only basic Python logic.
def factorialize(int_in):
int_out = int_in
int_multiplier = int_in - 1
while int_multiplier >= 1:
int_out = int_out * int_multiplier
int_multiplier -= 1
return int_out
def factorialize_multinumber_string(str_in):
for value in str_in:
print(value)
try:
print("The factorial of {} is {}".format(value, factorialize(int(value))))
except:
pass
factorialize_multinumber_string(input("Please enter a series of single digits."))
You can use map function to get every single digit from number:
n = int(input("Enter a number: "))
digits = map(int, str(n))
for i in digits:
fact = 1
a = 1
while a <= i:
fact *= a
a += 1
print('The factorial of', i, 'is', fact)
Ok, apart from the fact that you print the wrong variable, there's a bigger error. You are assuming that your digits are ever increasing, like in 123. Try your code with 321... (this is true of Karol's answer as well). And you need to handle digit zero, too
What you need is to restart the calculation of the factorial from scratch for every digit. For example:
n = '2063'
for ch in reversed(n):
x = int(ch)
if x == 0:
print(f'fact of {x} is 1')
else:
fact = 1
for k in range(2,x+1):
fact *= k
print(f'fact of {x} is {fact}')

TypeError: collatz_seq() missing 1 required positional argument: 'n'

If I don't put any random (I guess) number inside the function (at the end of the code) it shows the above error. I don't understand why it wants any random number as "n". Does anybody know? Thank you.
def collatz_seq(n):
n = int(input("\nEnter a positive integer: "))
seq = [n]
while n > 1:
if (n % 2 == 0):
n = n / 2
else:
n = 3*n + 1
seq.append(n)
return seq
print(collatz_seq(15))
I tried of course (by accident) to put any random number inside the function and it works properly...But I don't understand why do I have to put a number, and it can't work just by typing print(collatz_seq()).
Because you defined it that way?!
def collatz_seq(n):
The (n) is one parameter. Did you mean
def collatz_seq():
?

Asterisk Triangle in Python (using recursion)

I have seen multiple "python asterisk triangles" and their solutions, but I am stuck on creating an asterisk triangle using recursion (without a loop, which would make it much easier in my opinion.) Below is the current code I have:
def main():
num = int(input("Enter an integer: "))
triangle = draw_triangle(num)
print(triangle)
def draw_triangle(n):
if n == 0:
return
else:
return ("*" * n + '\n') + draw_triangle(n - 1)
main()
When I run the code, I receive "TypeError: must be str, not NoneType." I have done some research and still do not completely understand what this error is telling me. I apologize if this question was asked before, I was unable to find one dealing with any recursive functions. Thank you.
return to return ""
Input: 5
Output:
*****
****
***
**
*
This error occurs because you return a blank value. Try returning a blank string instead
Solution:
In line 9:
replace return with return ''
The code is working properly but there is just a slight problem.
When testing with base case i.e. if n == 0: the return must be set to something, if not it will return None. Thus after the input number reaches 0 it returns None anything that returns None is interpreted as a failed case in python so
Here is a work around:
def draw_triangle(n):
if n == 0:
return ''
else:
return ("*" * n + '\n') + draw_triangle(n - 1)
def main():
num = int(input("Enter an integer: "))
triangle = draw_triangle(num)
print(triangle)
main()
Thus after reaching n == 0 case the program will return a blank string and continue.

Square number sequence in Python

I'm new to python and I am trying to make a code to print all the square numbers until the square of the desired value entered by the user.
n = raw_input("Enter number")
a = 1
while a < n:
a = 1
print(a*a)
a += 1
if a > n:
break
When I run this code it infinitely prints "1" ... I'm guessing that the value of a does not increase by += so it's a=1 forever. How do I fix this?
There are some problems. First, your input (what raw_input() returns) is a string, so you must convert it to integer:
n = int(raw_input(...))
Second, you are setting a = 1 each iteration, so, since the loop condition is a < n, the loop will run forever ( if n > 1). You should delete the line
a = 1
Finally, it's not necesary to check if a > n, because the loop condition will handle it:
while a < n:
print a * a
a += 1
# 'if' is not necessary
There is a small error in your code:
while a < n:
a=1 # `a` is always 1 :)
print a*a
a += 1
if a > n:
break
You're setting the value of a back to 1 on every iteration of the loop, so every time it checks against n, the value is 2. Remove the a=1 line.
As others have noted, your specific problem is resetting a each time you loop. A much more Pythonic approach to this is the for loop:
for a in range(1, n):
print(a ** 2)
This means you don't have to manually increment a or decide when to break or otherwise exit a while loop, and is generally less prone to mistakes like resetting a.
Also, note that raw_input returns a string, you need to make it into an int:
n = int(raw_input("Enter number: "))
an even better idea is to make a simple function
def do_square(x):
return x*x
then just run a list comprehension on it
n = int(raw_input("Enter #:")) #this is your problem with the original code
#notice we made it into an integer
squares = [do_square(i) for i in range(1,n+1)]
this is a more pythonic way to do what you are trying to do
you really want to use functions to define functional blocks that are easy to digest and potentially can be reused
you can extend this concept and create a function to get input from the user and do some validation on it
def get_user_int():
#a function to make sure the user enters an integer > 0
while True:
try:
n = int(raw_input("Enter a number greater than zero:"))
except TypeError:
print "Error!! expecting a number!"
continue;
if n > 0:
return n
print "Error: Expecting a number greater than zero!"
and then you can build your input right into your list
squares = [do_square(i) for i in range(1,get_user_int()+1)]
and really do_square is such a simple function we could easily just do it in our loop
squares = [x*x for x in range(1,get_user_int())]
The first line in your loop sets's a to one on every iteration.
You assign a=1 inside the loop. That means it's overwriting the a+=1.
try this:
n = eval(raw_input("Enter number"))
a=1
while a < n:
print a*a
a += 1
The issue here is that the value of a gets overridden every time you enter in the loop
Problem is in the condition of the while loop, to print squares of numbers upto a limiting value, try this..
def powers(x):
n=1
while((n**2)<=x):
print(n**2, end =' ')
n +=1

Collatz Conjecture and printing statements

I am trying to create a simple program to apply the statement of the Collatz Conjecture to an integer that the user can enter, I have:
def collatz(n):
print n,
if n % 2 ==0:
n = n / 2
elif n == 0:
Print "Collatz Conjecture true for" , 'n'
else:
n = n *3 + 1
input("\n\nInsert a positive integer:")
def collatz(n)
However it is saying there is a syntax error in the line:
Print "Collatz Conjecture true for" , 'n'
I can't see what mistake ther is in this line.
Also as I haven't been able to test it yet, does this look as though it will work ok?
Python is case sensitive. Use "print" not "Print".
Well, your syntax error is that python is case-sensitive, so you need print rather than Print.
But you've got more problems:
'n' prints the string n. I think what you want is n to print the value of the variable (or if not, then you can just make a single string "... true for n").
Finally (I think), in order to run the function collatz, you don't need the def; that's just for the definition.
More problems:
The stopping condition should be n == 1, not n == 0.
You have to recur or iterate, as is you're only making one step.
Check the input, make sure it really is a positive number.
def collatz_steps(n):
steps=0
if n==1:
return 0
else:
while n!=1:
if n%2==0:
n=n/2
steps+=1
else:
n = 3*n+1
steps+=1
return steps

Categories

Resources