2014-04-12 11:42:06 +02:00
|
|
|
"""
|
|
|
|
Doctest example from the official Python documentation.
|
2018-09-23 03:30:38 +02:00
|
|
|
https://docs.python.org/library/doctest.html
|
2014-04-12 11:42:06 +02:00
|
|
|
"""
|
|
|
|
|
2014-04-16 22:49:37 +02:00
|
|
|
|
2014-04-12 11:42:06 +02:00
|
|
|
def factorial(n):
|
|
|
|
"""Return the factorial of n, an exact integer >= 0.
|
|
|
|
|
|
|
|
>>> [factorial(n) for n in range(6)]
|
|
|
|
[1, 1, 2, 6, 24, 120]
|
2014-10-23 11:16:17 +02:00
|
|
|
>>> factorial(30) # doctest: +ELLIPSIS
|
|
|
|
265252859812191058636308480000000...
|
2014-04-12 11:42:06 +02:00
|
|
|
>>> factorial(-1)
|
|
|
|
Traceback (most recent call last):
|
|
|
|
...
|
|
|
|
ValueError: n must be >= 0
|
|
|
|
|
|
|
|
Factorials of floats are OK, but the float must be an exact integer:
|
|
|
|
>>> factorial(30.1)
|
|
|
|
Traceback (most recent call last):
|
|
|
|
...
|
|
|
|
ValueError: n must be exact integer
|
2014-10-23 11:16:17 +02:00
|
|
|
>>> factorial(30.0) # doctest: +ELLIPSIS
|
|
|
|
265252859812191058636308480000000...
|
2014-04-12 11:42:06 +02:00
|
|
|
|
|
|
|
It must also not be ridiculously large:
|
|
|
|
>>> factorial(1e100)
|
|
|
|
Traceback (most recent call last):
|
|
|
|
...
|
|
|
|
OverflowError: n too large
|
|
|
|
"""
|
|
|
|
|
|
|
|
import math
|
|
|
|
if not n >= 0:
|
|
|
|
raise ValueError("n must be >= 0")
|
|
|
|
if math.floor(n) != n:
|
|
|
|
raise ValueError("n must be exact integer")
|
2014-04-16 22:49:37 +02:00
|
|
|
if n + 1 == n: # catch a value like 1e300
|
2014-04-12 11:42:06 +02:00
|
|
|
raise OverflowError("n too large")
|
|
|
|
result = 1
|
|
|
|
factor = 2
|
|
|
|
while factor <= n:
|
|
|
|
result *= factor
|
|
|
|
factor += 1
|
|
|
|
return result
|