@@ -1746,19 +1746,139 @@ def _naive_prod(iterable, start=1):
1746
1746
self .assertEqual (type (prod ([1 , decimal .Decimal (2.0 ), 3 , 4 , 5 , 6 ])),
1747
1747
decimal .Decimal )
1748
1748
1749
- # Custom assertions.
1749
+ def testPerm (self ):
1750
+ perm = math .perm
1751
+ factorial = math .factorial
1752
+ # Test if factorial definition is satisfied
1753
+ for n in range (100 ):
1754
+ for k in range (n + 1 ):
1755
+ self .assertEqual (perm (n , k ),
1756
+ factorial (n ) // factorial (n - k ))
1750
1757
1751
- def assertIsNaN (self , value ):
1752
- if not math .isnan (value ):
1753
- self .fail ("Expected a NaN, got {!r}." .format (value ))
1758
+ # Test for Pascal's identity
1759
+ for n in range (1 , 100 ):
1760
+ for k in range (1 , n ):
1761
+ self .assertEqual (perm (n , k ), perm (n - 1 , k - 1 ) * k + perm (n - 1 , k ))
1754
1762
1755
- def assertEqualSign (self , x , y ):
1756
- """Similar to assertEqual(), but compare also the sign.
1763
+ # Test corner cases
1764
+ for n in range (1 , 100 ):
1765
+ self .assertEqual (perm (n , 0 ), 1 )
1766
+ self .assertEqual (perm (n , 1 ), n )
1767
+ self .assertEqual (perm (n , n ), factorial (n ))
1757
1768
1758
- Function useful to compare signed zeros.
1759
- """
1760
- self .assertEqual (x , y )
1761
- self .assertEqual (math .copysign (1.0 , x ), math .copysign (1.0 , y ))
1769
+ # Test one argument form
1770
+ for n in range (20 ):
1771
+ self .assertEqual (perm (n ), factorial (n ))
1772
+ self .assertEqual (perm (n , None ), factorial (n ))
1773
+
1774
+ # Raises TypeError if any argument is non-integer or argument count is
1775
+ # not 1 or 2
1776
+ self .assertRaises (TypeError , perm , 10 , 1.0 )
1777
+ self .assertRaises (TypeError , perm , 10 , decimal .Decimal (1.0 ))
1778
+ self .assertRaises (TypeError , perm , 10 , "1" )
1779
+ self .assertRaises (TypeError , perm , 10.0 , 1 )
1780
+ self .assertRaises (TypeError , perm , decimal .Decimal (10.0 ), 1 )
1781
+ self .assertRaises (TypeError , perm , "10" , 1 )
1782
+
1783
+ self .assertRaises (TypeError , perm )
1784
+ self .assertRaises (TypeError , perm , 10 , 1 , 3 )
1785
+ self .assertRaises (TypeError , perm )
1786
+
1787
+ # Raises Value error if not k or n are negative numbers
1788
+ self .assertRaises (ValueError , perm , - 1 , 1 )
1789
+ self .assertRaises (ValueError , perm , - 2 ** 1000 , 1 )
1790
+ self .assertRaises (ValueError , perm , 1 , - 1 )
1791
+ self .assertRaises (ValueError , perm , 1 , - 2 ** 1000 )
1792
+
1793
+ # Returns zero if k is greater than n
1794
+ self .assertEqual (perm (1 , 2 ), 0 )
1795
+ self .assertEqual (perm (1 , 2 ** 1000 ), 0 )
1796
+
1797
+ n = 2 ** 1000
1798
+ self .assertEqual (perm (n , 0 ), 1 )
1799
+ self .assertEqual (perm (n , 1 ), n )
1800
+ self .assertEqual (perm (n , 2 ), n * (n - 1 ))
1801
+ if support .check_impl_detail (cpython = True ):
1802
+ self .assertRaises (OverflowError , perm , n , n )
1803
+
1804
+ for n , k in (True , True ), (True , False ), (False , False ):
1805
+ self .assertEqual (perm (n , k ), 1 )
1806
+ self .assertIs (type (perm (n , k )), int )
1807
+ self .assertEqual (perm (IntSubclass (5 ), IntSubclass (2 )), 20 )
1808
+ self .assertEqual (perm (MyIndexable (5 ), MyIndexable (2 )), 20 )
1809
+ for k in range (3 ):
1810
+ self .assertIs (type (perm (IntSubclass (5 ), IntSubclass (k ))), int )
1811
+ self .assertIs (type (perm (MyIndexable (5 ), MyIndexable (k ))), int )
1812
+
1813
+ def testComb (self ):
1814
+ comb = math .comb
1815
+ factorial = math .factorial
1816
+ # Test if factorial definition is satisfied
1817
+ for n in range (100 ):
1818
+ for k in range (n + 1 ):
1819
+ self .assertEqual (comb (n , k ), factorial (n )
1820
+ // (factorial (k ) * factorial (n - k )))
1821
+
1822
+ # Test for Pascal's identity
1823
+ for n in range (1 , 100 ):
1824
+ for k in range (1 , n ):
1825
+ self .assertEqual (comb (n , k ), comb (n - 1 , k - 1 ) + comb (n - 1 , k ))
1826
+
1827
+ # Test corner cases
1828
+ for n in range (100 ):
1829
+ self .assertEqual (comb (n , 0 ), 1 )
1830
+ self .assertEqual (comb (n , n ), 1 )
1831
+
1832
+ for n in range (1 , 100 ):
1833
+ self .assertEqual (comb (n , 1 ), n )
1834
+ self .assertEqual (comb (n , n - 1 ), n )
1835
+
1836
+ # Test Symmetry
1837
+ for n in range (100 ):
1838
+ for k in range (n // 2 ):
1839
+ self .assertEqual (comb (n , k ), comb (n , n - k ))
1840
+
1841
+ # Raises TypeError if any argument is non-integer or argument count is
1842
+ # not 2
1843
+ self .assertRaises (TypeError , comb , 10 , 1.0 )
1844
+ self .assertRaises (TypeError , comb , 10 , decimal .Decimal (1.0 ))
1845
+ self .assertRaises (TypeError , comb , 10 , "1" )
1846
+ self .assertRaises (TypeError , comb , 10.0 , 1 )
1847
+ self .assertRaises (TypeError , comb , decimal .Decimal (10.0 ), 1 )
1848
+ self .assertRaises (TypeError , comb , "10" , 1 )
1849
+
1850
+ self .assertRaises (TypeError , comb , 10 )
1851
+ self .assertRaises (TypeError , comb , 10 , 1 , 3 )
1852
+ self .assertRaises (TypeError , comb )
1853
+
1854
+ # Raises Value error if not k or n are negative numbers
1855
+ self .assertRaises (ValueError , comb , - 1 , 1 )
1856
+ self .assertRaises (ValueError , comb , - 2 ** 1000 , 1 )
1857
+ self .assertRaises (ValueError , comb , 1 , - 1 )
1858
+ self .assertRaises (ValueError , comb , 1 , - 2 ** 1000 )
1859
+
1860
+ # Returns zero if k is greater than n
1861
+ self .assertEqual (comb (1 , 2 ), 0 )
1862
+ self .assertEqual (comb (1 , 2 ** 1000 ), 0 )
1863
+
1864
+ n = 2 ** 1000
1865
+ self .assertEqual (comb (n , 0 ), 1 )
1866
+ self .assertEqual (comb (n , 1 ), n )
1867
+ self .assertEqual (comb (n , 2 ), n * (n - 1 ) // 2 )
1868
+ self .assertEqual (comb (n , n ), 1 )
1869
+ self .assertEqual (comb (n , n - 1 ), n )
1870
+ self .assertEqual (comb (n , n - 2 ), n * (n - 1 ) // 2 )
1871
+ if support .check_impl_detail (cpython = True ):
1872
+ self .assertRaises (OverflowError , comb , n , n // 2 )
1873
+
1874
+ for n , k in (True , True ), (True , False ), (False , False ):
1875
+ self .assertEqual (comb (n , k ), 1 )
1876
+ self .assertIs (type (comb (n , k )), int )
1877
+ self .assertEqual (comb (IntSubclass (5 ), IntSubclass (2 )), 10 )
1878
+ self .assertEqual (comb (MyIndexable (5 ), MyIndexable (2 )), 10 )
1879
+ for k in range (3 ):
1880
+ self .assertIs (type (comb (IntSubclass (5 ), IntSubclass (k ))), int )
1881
+ self .assertIs (type (comb (MyIndexable (5 ), MyIndexable (k ))), int )
1762
1882
1763
1883
@requires_IEEE_754
1764
1884
def test_nextafter (self ):
@@ -1802,9 +1922,9 @@ def test_nextafter(self):
1802
1922
self .assertEqual (math .nextafter (- largest_normal , - INF ), - INF )
1803
1923
1804
1924
# NaN
1805
- self .assertTrue (math .isnan ( math . nextafter (NAN , 1.0 ) ))
1806
- self .assertTrue (math .isnan ( math . nextafter (1.0 , NAN ) ))
1807
- self .assertTrue (math .isnan ( math . nextafter (NAN , NAN ) ))
1925
+ self .assertIsNaN (math .nextafter (NAN , 1.0 ))
1926
+ self .assertIsNaN (math .nextafter (1.0 , NAN ))
1927
+ self .assertIsNaN (math .nextafter (NAN , NAN ))
1808
1928
1809
1929
@requires_IEEE_754
1810
1930
def test_ulp (self ):
@@ -1822,13 +1942,27 @@ def test_ulp(self):
1822
1942
1823
1943
# special cases
1824
1944
self .assertEqual (math .ulp (INF ), INF )
1825
- self .assertTrue (math .isnan ( math . ulp (math .nan ) ))
1945
+ self .assertIsNaN (math .ulp (math .nan ))
1826
1946
1827
1947
# negative number: ulp(-x) == ulp(x)
1828
1948
for x in (0.0 , 1.0 , 2 ** 52 , 2 ** 64 , INF ):
1829
1949
with self .subTest (x = x ):
1830
1950
self .assertEqual (math .ulp (- x ), math .ulp (x ))
1831
1951
1952
+ # Custom assertions.
1953
+
1954
+ def assertIsNaN (self , value ):
1955
+ if not math .isnan (value ):
1956
+ self .fail ("Expected a NaN, got {!r}." .format (value ))
1957
+
1958
+ def assertEqualSign (self , x , y ):
1959
+ """Similar to assertEqual(), but compare also the sign with copysign().
1960
+
1961
+ Function useful to compare signed zeros.
1962
+ """
1963
+ self .assertEqual (x , y )
1964
+ self .assertEqual (math .copysign (1.0 , x ), math .copysign (1.0 , y ))
1965
+
1832
1966
1833
1967
class IsCloseTests (unittest .TestCase ):
1834
1968
isclose = math .isclose # subclasses should override this
@@ -1952,140 +2086,6 @@ def test_fractions(self):
1952
2086
self .assertAllClose (fraction_examples , rel_tol = 1e-8 )
1953
2087
self .assertAllNotClose (fraction_examples , rel_tol = 1e-9 )
1954
2088
1955
- def testPerm (self ):
1956
- perm = math .perm
1957
- factorial = math .factorial
1958
- # Test if factorial definition is satisfied
1959
- for n in range (100 ):
1960
- for k in range (n + 1 ):
1961
- self .assertEqual (perm (n , k ),
1962
- factorial (n ) // factorial (n - k ))
1963
-
1964
- # Test for Pascal's identity
1965
- for n in range (1 , 100 ):
1966
- for k in range (1 , n ):
1967
- self .assertEqual (perm (n , k ), perm (n - 1 , k - 1 ) * k + perm (n - 1 , k ))
1968
-
1969
- # Test corner cases
1970
- for n in range (1 , 100 ):
1971
- self .assertEqual (perm (n , 0 ), 1 )
1972
- self .assertEqual (perm (n , 1 ), n )
1973
- self .assertEqual (perm (n , n ), factorial (n ))
1974
-
1975
- # Test one argument form
1976
- for n in range (20 ):
1977
- self .assertEqual (perm (n ), factorial (n ))
1978
- self .assertEqual (perm (n , None ), factorial (n ))
1979
-
1980
- # Raises TypeError if any argument is non-integer or argument count is
1981
- # not 1 or 2
1982
- self .assertRaises (TypeError , perm , 10 , 1.0 )
1983
- self .assertRaises (TypeError , perm , 10 , decimal .Decimal (1.0 ))
1984
- self .assertRaises (TypeError , perm , 10 , "1" )
1985
- self .assertRaises (TypeError , perm , 10.0 , 1 )
1986
- self .assertRaises (TypeError , perm , decimal .Decimal (10.0 ), 1 )
1987
- self .assertRaises (TypeError , perm , "10" , 1 )
1988
-
1989
- self .assertRaises (TypeError , perm )
1990
- self .assertRaises (TypeError , perm , 10 , 1 , 3 )
1991
- self .assertRaises (TypeError , perm )
1992
-
1993
- # Raises Value error if not k or n are negative numbers
1994
- self .assertRaises (ValueError , perm , - 1 , 1 )
1995
- self .assertRaises (ValueError , perm , - 2 ** 1000 , 1 )
1996
- self .assertRaises (ValueError , perm , 1 , - 1 )
1997
- self .assertRaises (ValueError , perm , 1 , - 2 ** 1000 )
1998
-
1999
- # Returns zero if k is greater than n
2000
- self .assertEqual (perm (1 , 2 ), 0 )
2001
- self .assertEqual (perm (1 , 2 ** 1000 ), 0 )
2002
-
2003
- n = 2 ** 1000
2004
- self .assertEqual (perm (n , 0 ), 1 )
2005
- self .assertEqual (perm (n , 1 ), n )
2006
- self .assertEqual (perm (n , 2 ), n * (n - 1 ))
2007
- if support .check_impl_detail (cpython = True ):
2008
- self .assertRaises (OverflowError , perm , n , n )
2009
-
2010
- for n , k in (True , True ), (True , False ), (False , False ):
2011
- self .assertEqual (perm (n , k ), 1 )
2012
- self .assertIs (type (perm (n , k )), int )
2013
- self .assertEqual (perm (IntSubclass (5 ), IntSubclass (2 )), 20 )
2014
- self .assertEqual (perm (MyIndexable (5 ), MyIndexable (2 )), 20 )
2015
- for k in range (3 ):
2016
- self .assertIs (type (perm (IntSubclass (5 ), IntSubclass (k ))), int )
2017
- self .assertIs (type (perm (MyIndexable (5 ), MyIndexable (k ))), int )
2018
-
2019
- def testComb (self ):
2020
- comb = math .comb
2021
- factorial = math .factorial
2022
- # Test if factorial definition is satisfied
2023
- for n in range (100 ):
2024
- for k in range (n + 1 ):
2025
- self .assertEqual (comb (n , k ), factorial (n )
2026
- // (factorial (k ) * factorial (n - k )))
2027
-
2028
- # Test for Pascal's identity
2029
- for n in range (1 , 100 ):
2030
- for k in range (1 , n ):
2031
- self .assertEqual (comb (n , k ), comb (n - 1 , k - 1 ) + comb (n - 1 , k ))
2032
-
2033
- # Test corner cases
2034
- for n in range (100 ):
2035
- self .assertEqual (comb (n , 0 ), 1 )
2036
- self .assertEqual (comb (n , n ), 1 )
2037
-
2038
- for n in range (1 , 100 ):
2039
- self .assertEqual (comb (n , 1 ), n )
2040
- self .assertEqual (comb (n , n - 1 ), n )
2041
-
2042
- # Test Symmetry
2043
- for n in range (100 ):
2044
- for k in range (n // 2 ):
2045
- self .assertEqual (comb (n , k ), comb (n , n - k ))
2046
-
2047
- # Raises TypeError if any argument is non-integer or argument count is
2048
- # not 2
2049
- self .assertRaises (TypeError , comb , 10 , 1.0 )
2050
- self .assertRaises (TypeError , comb , 10 , decimal .Decimal (1.0 ))
2051
- self .assertRaises (TypeError , comb , 10 , "1" )
2052
- self .assertRaises (TypeError , comb , 10.0 , 1 )
2053
- self .assertRaises (TypeError , comb , decimal .Decimal (10.0 ), 1 )
2054
- self .assertRaises (TypeError , comb , "10" , 1 )
2055
-
2056
- self .assertRaises (TypeError , comb , 10 )
2057
- self .assertRaises (TypeError , comb , 10 , 1 , 3 )
2058
- self .assertRaises (TypeError , comb )
2059
-
2060
- # Raises Value error if not k or n are negative numbers
2061
- self .assertRaises (ValueError , comb , - 1 , 1 )
2062
- self .assertRaises (ValueError , comb , - 2 ** 1000 , 1 )
2063
- self .assertRaises (ValueError , comb , 1 , - 1 )
2064
- self .assertRaises (ValueError , comb , 1 , - 2 ** 1000 )
2065
-
2066
- # Returns zero if k is greater than n
2067
- self .assertEqual (comb (1 , 2 ), 0 )
2068
- self .assertEqual (comb (1 , 2 ** 1000 ), 0 )
2069
-
2070
- n = 2 ** 1000
2071
- self .assertEqual (comb (n , 0 ), 1 )
2072
- self .assertEqual (comb (n , 1 ), n )
2073
- self .assertEqual (comb (n , 2 ), n * (n - 1 ) // 2 )
2074
- self .assertEqual (comb (n , n ), 1 )
2075
- self .assertEqual (comb (n , n - 1 ), n )
2076
- self .assertEqual (comb (n , n - 2 ), n * (n - 1 ) // 2 )
2077
- if support .check_impl_detail (cpython = True ):
2078
- self .assertRaises (OverflowError , comb , n , n // 2 )
2079
-
2080
- for n , k in (True , True ), (True , False ), (False , False ):
2081
- self .assertEqual (comb (n , k ), 1 )
2082
- self .assertIs (type (comb (n , k )), int )
2083
- self .assertEqual (comb (IntSubclass (5 ), IntSubclass (2 )), 10 )
2084
- self .assertEqual (comb (MyIndexable (5 ), MyIndexable (2 )), 10 )
2085
- for k in range (3 ):
2086
- self .assertIs (type (comb (IntSubclass (5 ), IntSubclass (k ))), int )
2087
- self .assertIs (type (comb (MyIndexable (5 ), MyIndexable (k ))), int )
2088
-
2089
2089
2090
2090
def test_main ():
2091
2091
from doctest import DocFileSuite
0 commit comments