5 factorial


#1

The instructions:

"Define a function factorial that takes an integer x as input."

Far as I can get with this:

Defining a function with the argument x :

def factorial(x):

I might have to start over or something because I don't understand how to do this next instruction:

"Calculate and return the factorial of that number."


#2

How would you compute it manually? Surely that has a fairly direct translation into code?


#3

Not sure how that would look sorry.


#5

This seems to work :smile:

def factorial(x):
        x_sum = 1
        x_i =0
        for i in range(x):
            if x == 0 or x ==1:
                x_sum = 1
                break
            else:
                x_i += 1
                x_sum = x_sum * x_i
            print x_sum
        return x_sum

#12

This what I have. It works perfectly.

def factorial (x):
    ans = 1
    while (x!=0):
        ans *= x
        x -= 1
    return ans

#15

Just assume that you have a working factorial function.

You could then use that to get the factorial for x-1, and multiply it by x, right?
Each time you do this, x is reduced by 1, eventually that will reach the case 0, which is trivial, so the function who got the argument 0 will return 1, and then those that called that can return their results as well, one after another until the last one has been resolved.

In general, recursive functions work by making the problem smaller each time they call themselves, until the problem is trivial at which point they just solve them.

The problem always has to get smaller, because if it grows, then the trivial case won't be reached and nothing gets solved.


#18
"""def factorial(n):
    sum_of_all = n
    while n > 1:
        n = n - 1
        sum_of_all = sum_of_all * n
    return sum_of_all

"""


#19
 def factorial(x):
     if x > 1:
         result = x*factorial(x-1)
     else:       
         return x
     return result

I still don't even understand how it works.


Factorial
Factorial
#20

Yeah that one is hurting my brain. Just slow it down and go step by step. Let's say that we do factorial(3) as an example.

So go through the function.
if x > 1:
3 is greater than 1, so then result = 3 * factorial(3 - 1), that is to say

result = 3 * factorial(2)

So now we're going through the factorial function again, but with 2. i.e. factorial(2)
Again, we have
if x > 1:
Two is greater than 1, so result = 2 * factorial(2 - 1), or rather

result = 2 * factorial(1)

Now we're going through the factorial function again with 1. i.e. factorial(1)
if x > 1:
Is 1 > 1? Nope! So we get this:
else:
return x
Which means that factorial(1) == 1.

Now we go backwards and look at the results.

Remember when we looked at this?
result = 2 * factorial(2 - 1)

which is the same thing as
result = 2 * factorial(1)

which we now know is the same thing as
result = 2 * 1

So that means that factorial(2) == 2

Now we look back again. Remember this?
result = 3 * factorial(3 - 1)

which is the same thing as
result = 3 * factorial(2)

which we now know is the same thing as
result = 3 * 2

Which of course means result == 6

Does that help? I know it's convoluted, but if you start small and go step by step, it starts to make sense.


#21

What makes this difficult to grasp is the result variable. It is standing in for the call stack that would normally be in use in a recursive function. @ccrawfod2004 does a nice job of explaining the code in question, but let's look at it with only a call stack, and no accumulating variable.

def factorial(x):
     return x * factorial(x - 1) if x > 0 else 1

This may look a little strange, but less verbose code is easier to envision, and it works. Consider,

print factorial(5)

We start with x == 5

[5 * f(4)]

which can be written as,

[5 * [4 * f(3)]]

and continuing with the pattern,

[5 * [4 * [3 * [2 * f(1)]]]]

Each ] is a return value that is pushed to the stack during recursion, then recovered (wound back down) once the base case is reached.

return 1  =>    1
     * 2  =>    2
     * 3  =>    6
     * 4  =>   24
     * 5  =>  120

#23

def factorial(x):
    p = 1
    for i in range(x):
        if (x-i) > 0:
            p = p * (x - i)
    return p


using the for function, as factorial x is exactly the product of x number. As long as the integer is positive, the process continues.


#24

What will happen if x (the input) is negative?

Answer: Nothing. Unless otherwise modified, range() is always increasing from the left. 0, 1, 2, 3, .., x.

What will make (x-i) less than or equal to zero?

Answer: i == x. In the case of range(), this too will never happen. i is always less than x, save for the breaking condition, when i == x, but no code runs, then.

So we can simplify your code to just return 1 or a positive number.

def factorial(x):
    p = 1
    for i in range(1,x+1):
        p *= i
    return p

print(factorial(-5))     # 1 
print(factorial(5))      # 120

#25

If you don't mind explaining, why does this work? Shouldn't only multiply once? If I had factorial(7). Shouldn't it just simply do 7 * 6 and return 42 and that would be the end? Why does it just naturally loop? Sorry I'm just extremely confused as to why this works


#26

We must remember how factorial (!) works.

7! == 7 * 6!
   == 7 * 6 * 5!
   == 7 * 6 * 5 * 4!
   == 7 * 6 * 5 * 4 * 3!
   == 7 * 6 * 5 * 4 * 3 * 2!
   == 7 * 6 * 5 * 4 * 3 * 2 * 1!
   ==   42  *   20  *   6
   ==      840      *   6
   ==             5040

#28

A negative x should not return any result. Thanks for the simplification. I think a little bit modification would be better, as follow:
def factorial(x):
if x >= 0:
p = 1
for i in range(x):
p *= i + 1
return p

print(factorial(0)) #1
print(factorial(1)) #1
print(factorial(-5)) #None


#29

Correct. This proof of concept does not contain enough validation of any sort. A default return of 1 is not all bad, even incorrect as it is. Even a stopped watch (timepiece) is correct twice a day. Technically, None is not a return, but a compiler response. We need better trapping that is readable.

I still think that returning 1 is the best approach to a stripped down, unvalidated factorial function. If validation is to be applied then it will not be piecemeal, but thorough and tested. What happens when inputs are, ...

  1. float?
  2. string?
  3. not number?
  4. empty?
  5. .... ?

In other words, if not all traps are in a place, then what will be the default?
(Please don't say, None.)


#30

Hey could anyone tell me whats wrong with my code for this part

def factorial(x):
    factorial_x = [x]
    while x > 1:
        reduced_x = x - 1
        factorial_x.append(reduced_x)
    for num in factorial_x:
        product_x = 1*num
    return product_x

#31

This needs to be an augmented product, meaning it accumulates on each iteration.

product_x = 1
for num in factorial_x:
    product_x *= num
return product_x

#33

This worked for me... please tell me what i could improve :slightly_smiling: The spaces are for the indentations

def factorial(x):
fact = []
b = 1
while x > 0:

fact.append(x)
x -= 1

for i in fact:
b *= i

return b

#34