Skip to content

Commit

Permalink
Merge pull request #42 from MIT-Emerging-Talent/factorial
Browse files Browse the repository at this point in the history
factorial function
  • Loading branch information
Luyando-Chitindi authored Jan 1, 2025
2 parents 347d834 + 27ca7c6 commit 13ef565
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 0 deletions.
56 changes: 56 additions & 0 deletions solutions/factorial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
A module for Computing the factorial of a non-negative integer n.
Module contents:
- factorial: is the product of all positive integers less than or equal to n.
Created on XX XX XX
@author: Saad M. Ashour
"""


def factorial(n: int) -> int:
"""
Computes the factorial of a non-negative integer n.
The factorial of a non-negative integer n
is the product of all positive integers less than or equal to n.
Parameters:
n (int): A non-negative integer.
Returns:
int: The factorial of the input integer n.
Raises:
ValueError: If n is negative, as factorial is not defined for negative numbers.
TypeError: If n is not an integer, as factorials are only defined for integers.
Examples:
>>> factorial(0)
1
>>> factorial(1)
1
>>> factorial(5)
120
>>> factorial(3)
6
"""
# Validate input type and value
if not isinstance(n, int):
raise TypeError("Input must be an integer.")

if n < 0:
raise ValueError("Factorial is not defined for negative numbers.")

# Base case for recursion: 0! = 1
if n == 0 or n == 1:
return 1

# Recursive case: n! = n * (n-1)!
return n * factorial(n - 1)
59 changes: 59 additions & 0 deletions solutions/tests/test_factorial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Unit tests for factorial function.
@author: Saad M. Ashour
"""

import unittest
from solutions.factorial import factorial


class TestFactorial(unittest.TestCase):
"""
Unit tests for the factorial function.
The factorial function computes the factorial of a non-negative integer using recursion.
These tests verify its correctness for various inputs,
including edge cases, valid cases, and invalid cases.
"""


def test_factorial_zero(self):
"""It should evaluate 0 to 1"""
actual = factorial(0)
expected = 1
self.assertEqual(actual, expected)


def test_factorial_one(self):
"""It should evaluate 1 to 1"""
actual = factorial(1)
expected = 1
self.assertEqual(actual, expected)


def test_factorial_positive(self):
"""It should evaluate 5 to 120"""
actual = factorial(5)
expected = 120
self.assertEqual(actual, expected)


def test_factorial_negative(self):
"""factorial of negative integer will raise Error"""
with self.assertRaises(ValueError):
factorial(-1)


def test_factorial_non_integer(self):
"""factorial of non integer will raise Error"""
with self.assertRaises(TypeError):
factorial(3.5)
with self.assertRaises(TypeError):
factorial("string")


if __name__ == "__main__":
unittest.main()

0 comments on commit 13ef565

Please sign in to comment.