Solution 1

``````try:
reduce
except NameError:
from functools import reduce

def factorial_terms(a_number):
if a_number < 0:
raise ValueError("Only defined for positive numbers")
return list(range(a_number or 1, 0, -1))

def compute_factorial(terms):
if not terms:
raise ValueError("Terms should have at least one element")
return reduce(lambda a, b: a*b, terms, 1)

def factorial(number):
return compute_factorial(factorial_terms(number))
``````

# Function Factorial

The objective of this assignment is to write a factorial function (https://en.wikipedia.org/wiki/Factorial).

In order to do that we'll define 2 helper functions:

• `factorial_terms`: will receive a number and return the list of terms to compute the factorial.
• `compute_factorial`: Will receive a list of terms and compute de factorial.

Finally, the `factorial` function will get a number and, using both helper functions, will compute

This assignment is designed to practice the `reduce` function. But if you think it's getting too complicated, you can just try using a for-loop and check the solution later.

Use the tests to see the complete specification of what you're required to write.

### Test Cases

test factorial terms with an invalid value -

``````import pytest

def test_factorial_terms_with_an_invalid_value():
"""Should raise an exception if an invalid number is provided"""
with pytest.raises(ValueError):
factorial_terms(-1)
``````

test compute factorial with no arguments -

``````import pytest

def test_compute_factorial_with_no_arguments():
"""Should raise an exception"""
with pytest.raises(ValueError):
compute_factorial([])
``````

test factorial for regular integers -

``````def test_factorial_for_regular_integers():
"""Should return the factorial number for the terms"""
assert factorial(5) == 120``````

test factorial with negative number -

``````import pytest

def test_factorial_with_negative_number():
"""Should raise an exception"""
with pytest.raises(ValueError):
factorial(-1)
``````

test compute factorial for regular integers -

``````def test_compute_factorial_for_regular_integers():
"""Should return the factorial number for the terms"""
assert compute_factorial([5, 4, 3, 2, 1]) == 120``````

test factorial of zero -

``````def test_factorial_of_zero():
"""Should return 1"""
assert factorial(0) == 1``````

test compute factorial invoked with one -

``````def test_compute_factorial_invoked_with_one():
"""Should return 1"""
assert compute_factorial() == 1``````

test factorial terms are generated ok -

``````def test_factorial_terms_are_generated_ok():
"""Should return the correct terms for a number"""
assert factorial_terms(5) == [5, 4, 3, 2, 1]``````

test factorial terms of zero -

``````def test_factorial_terms_of_zero():
"""Should return """
assert factorial_terms(0) == ``````
def factorial_terms(a_number): pass def compute_factorial(terms): pass def factorial(number): pass