Skip to main content

How to Calculate and Format Factorials in Python

The factorial of a non-negative integer n, denoted as n!, is the product of all positive integers less than or equal to n. For example, 5! = 1 × 2 × 3 × 4 × 5 = 120. By definition, the factorial of 0 is 1.

This guide explains how to write a Python function that not only calculates the factorial but also formats the output to show the multiplication process (e.g., 3! = 1 * 2 * 3 = 6), while handling invalid inputs gracefully.

Understanding the Logic

To calculate a factorial manually in Python without using the math library, we typically use an iterative approach (a loop).

  1. Initialize a result variable to 1.
  2. Iterate from 1 up to n.
  3. Multiply the current number into the result.
  4. Track the numbers to create a formatted string string.

Step 1: Handling Edge Cases (Negatives and Zero)

Mathematically, factorials are not defined for negative numbers. Your function should reject negative inputs and explicitly handle the special case of 0!.

def check_input(n):
# ⛔️ Incorrect: Ignoring negative inputs leads to infinite loops or wrong logic
# if n == 0: return 1

# ✅ Correct: Raise an error for negatives, handle 0 explicitly
if n < 0:
raise ValueError("Please enter a non-negative integer.")
elif n == 0:
return "0! = 1"

return "Input is valid"
warning

Always validate input boundaries. Passing a negative number to a standard factorial loop might result in 1 (because the loop range 1 to -5 is empty), which is mathematically incorrect.

Step 2: Implementing the Calculation Loop

To display the full calculation (e.g., 1 * 2 * 3), we need to store each number as a string in a list, then join them together.

n = 5
result = 1
factors = []

# Loop from 1 to n (inclusive)
for i in range(1, n + 1):
result *= i # Multiply to get the math result
factors.append(str(i)) # Store string for display

# Join list with multiplication symbol
factors_str = " * ".join(factors)

print(f"{n}! = {factors_str} = {result}")

Output:

5! = 1 * 2 * 3 * 4 * 5 = 120

Complete Code Implementation

Here is the complete factorial.py script. It includes docstrings, error handling, and the logic to format the output string exactly as requested.

def factorial(n):
"""
Calculate the factorial of a non-negative integer.

Args:
n (int): The non-negative integer.

Returns:
str: Formatted string "{n}! = {factors} = {result}"

Raises:
ValueError: If input is negative.
"""
# 1. Handle Edge Cases
if n < 0:
raise ValueError("Please enter a non-negative integer.")
elif n == 0:
return "0! = 1"

# 2. Perform Calculation
else:
result = 1
factors = []

# Iterate from 1 to n
for i in range(1, n + 1):
result *= i
factors.append(str(i))

# 3. Format Output
factors_str = " * ".join(factors)
return f"{n}! = {factors_str} = {result}"

if __name__ == "__main__":
# Test Cases
try:
print(factorial(2))
print(factorial(8))

# Uncomment to test error handling:
# print(factorial(-5))
except ValueError as e:
print(f"Error: {e}")

Execution Output:

2! = 1 * 2 = 2
8! = 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 = 40320
tip

For pure mathematical calculation in production code (where you don't need the string formatting), use the standard library: import math; print(math.factorial(5))

Conclusion

Building a custom factorial function helps understand iterative logic and string manipulation.

  1. Validate Input: Ensure n >= 0.
  2. Accumulate: Use result *= i inside a loop.
  3. Format: Use a list and .join() to construct detailed output strings dynamically.