1. """
    
  2. Doctest example from the official Python documentation.
    
  3. https://docs.python.org/library/doctest.html
    
  4. """
    
  5. 
    
  6. 
    
  7. def factorial(n):
    
  8.     """Return the factorial of n, an exact integer >= 0.
    
  9. 
    
  10.     >>> [factorial(n) for n in range(6)]
    
  11.     [1, 1, 2, 6, 24, 120]
    
  12.     >>> factorial(30)  # doctest: +ELLIPSIS
    
  13.     265252859812191058636308480000000...
    
  14.     >>> factorial(-1)
    
  15.     Traceback (most recent call last):
    
  16.         ...
    
  17.     ValueError: n must be >= 0
    
  18. 
    
  19.     Factorials of floats are OK, but the float must be an exact integer:
    
  20.     >>> factorial(30.1)
    
  21.     Traceback (most recent call last):
    
  22.         ...
    
  23.     ValueError: n must be exact integer
    
  24.     >>> factorial(30.0)  # doctest: +ELLIPSIS
    
  25.     265252859812191058636308480000000...
    
  26. 
    
  27.     It must also not be ridiculously large:
    
  28.     >>> factorial(1e100)
    
  29.     Traceback (most recent call last):
    
  30.         ...
    
  31.     OverflowError: n too large
    
  32.     """
    
  33. 
    
  34.     import math
    
  35. 
    
  36.     if not n >= 0:
    
  37.         raise ValueError("n must be >= 0")
    
  38.     if math.floor(n) != n:
    
  39.         raise ValueError("n must be exact integer")
    
  40.     if n + 1 == n:  # catch a value like 1e300
    
  41.         raise OverflowError("n too large")
    
  42.     result = 1
    
  43.     factor = 2
    
  44.     while factor <= n:
    
  45.         result *= factor
    
  46.         factor += 1
    
  47.     return result