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]) == 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 [1]"""
assert factorial_terms(0) == [1]
def factorial_terms(a_number): pass def compute_factorial(terms): pass def factorial(number): pass