diff --git a/exercises/perfect-numbers/example.py b/exercises/perfect-numbers/example.py index e80fefdcad..f2bc2d5a57 100644 --- a/exercises/perfect-numbers/example.py +++ b/exercises/perfect-numbers/example.py @@ -7,6 +7,17 @@ def divisor_generator(n): yield n // i -def is_perfect(n): +def classify(n): ''' A perfect number equals the sum of its positive divisors. ''' - return sum(divisor_generator(n)) + 1 == n + if n <= 0: + raise ValueError("Classification is only possible" + + " for positive whole numbers.") + + aliquot_sum = sum(divisor_generator(n)) + (1 if n > 1 else 0) + + if aliquot_sum < n: + return "deficient" + elif aliquot_sum == n: + return "perfect" + else: + return "abundant" diff --git a/exercises/perfect-numbers/perfect_numbers.py b/exercises/perfect-numbers/perfect_numbers.py index df010e7b8c..0377abc50c 100644 --- a/exercises/perfect-numbers/perfect_numbers.py +++ b/exercises/perfect-numbers/perfect_numbers.py @@ -1,6 +1,2 @@ -def divisor_generator(number): - pass - - -def is_perfect(number): +def classify(number): pass diff --git a/exercises/perfect-numbers/perfect_numbers_test.py b/exercises/perfect-numbers/perfect_numbers_test.py index bb6de15d56..dd350818a6 100644 --- a/exercises/perfect-numbers/perfect_numbers_test.py +++ b/exercises/perfect-numbers/perfect_numbers_test.py @@ -1,42 +1,80 @@ import unittest -from perfect_numbers import is_perfect +from perfect_numbers import classify + +# Tests adapted from `problem-specifications//canonical-data.json` @ v1.0.1 class PerfectNumbersTest(unittest.TestCase): + def test_smallest_perfect_number(self): + self.assertIs(classify(6), "perfect") - def test_first_perfect_number(self): - self.assertIs(is_perfect(6), True) + def test_medium_perfect_number(self): + self.assertIs(classify(28), "perfect") - def test_no_perfect_number(self): - self.assertIs(is_perfect(8), False) + def test_large_perfect_number(self): + self.assertIs(classify(33550336), "perfect") - def test_second_perfect_number(self): - self.assertIs(is_perfect(28), True) + # Additional tests for this track + def test_third_perfect_number(self): + self.assertIs(classify(496), "perfect") - def test_abundant(self): - self.assertIs(is_perfect(20), False) + def test_fourth_perfect_number(self): + self.assertIs(classify(8128), "perfect") - def test_answer_to_the_ultimate_question_of_life(self): - self.assertIs(is_perfect(42), False) + def test_sixth_perfect_number(self): + self.assertIs(classify(8589869056), "perfect") - def test_third_perfect_number(self): - self.assertIs(is_perfect(496), True) + def test_seventh_perfect_number(self): + self.assertIs(classify(137438691328), "perfect") + + +class AbundantNumbersTest(unittest.TestCase): + def test_smallest_abundant_number(self): + self.assertIs(classify(12), "abundant") + + def test_medium_abundant_number(self): + self.assertIs(classify(30), "abundant") + + def test_large_abundant_number(self): + self.assertIs(classify(33550335), "abundant") + + # Additional tests for this track + def test_answer_to_the_ultimate_question_of_life(self): + self.assertIs(classify(42), "abundant") def test_odd_abundant(self): - self.assertIs(is_perfect(945), False) + self.assertIs(classify(945), "abundant") - def test_fourth_perfect_number(self): - self.assertIs(is_perfect(8128), True) + def test_even_abundant(self): + self.assertIs(classify(20), "abundant") - def test_fifth_perfect_number(self): - self.assertIs(is_perfect(33550336), True) - def test_sixth_perfect_number(self): - self.assertIs(is_perfect(8589869056), True) +class DeficientNumbersTest(unittest.TestCase): + def test_smallest_prime_deficient_number(self): + self.assertIs(classify(2), "deficient") - def test_seventh_perfect_number(self): - self.assertIs(is_perfect(137438691328), True) + def test_smallest_nonprime_deficient_number(self): + self.assertIs(classify(4), "deficient") + + def test_medium_deficient_number(self): + self.assertIs(classify(32), "deficient") + + def test_large_deficient_number(self): + self.assertIs(classify(33550337), "deficient") + + def test_edge_case(self): + self.assertIs(classify(1), "deficient") + + +class InvalidInputsTest(unittest.TestCase): + def test_zero(self): + with self.assertRaises(ValueError): + classify(0) + + def test_negative(self): + with self.assertRaises(ValueError): + classify(-1) if __name__ == '__main__':