Skip to content

Commit ac7f404

Browse files
rootulpbehrtam
authored andcommitted
luhn: Update tests and example (#409)
- implement new tests as described in: https://github.com/exercism/x-common/blob/master/exercises/luhn/canonical-data.json - update example to satisfy new tests
1 parent c944dac commit ac7f404

File tree

2 files changed

+39
-32
lines changed

2 files changed

+39
-32
lines changed

exercises/luhn/example.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
class Luhn(object):
2-
def __init__(self, number):
3-
self.number = number
2+
def __init__(self, string):
3+
self.string = string.replace(" ", "")
44

55
def addends(self):
66
def luhn_transform(n):
77
return (2 * n - 9) if (n > 4) else (2 * n)
8-
old_digits = [int(d) for d in str(self.number)]
8+
old_digits = [int(d) for d in str(self.string)]
99
return [(luhn_transform(n) if (i % 2 == 0) else n)
1010
for i, n in enumerate(old_digits, start=len(old_digits) % 2)]
1111

1212
def checksum(self):
1313
return sum(self.addends())
1414

1515
def is_valid(self):
16+
if len(self.string) <= 1 or not self.string.isdigit():
17+
return False
1618
return self.checksum() % 10 == 0
17-
18-
@staticmethod
19-
def create(n):
20-
diff = (10 - Luhn(n * 10).checksum()) % 10
21-
return 10 * n + diff

exercises/luhn/luhn_test.py

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,56 @@
1-
from collections import Counter
1+
# -*- coding: utf-8 -*-
2+
23
import unittest
34

45
from luhn import Luhn
56

67

78
class LuhnTests(unittest.TestCase):
8-
def test_addends(self):
9-
# uses a Counter to avoid specifying order of return value
10-
self.assertEqual(Counter([1, 4, 1, 4, 1]),
11-
Counter(Luhn(12121).addends()))
9+
def test_single_digit_strings_can_not_be_valid(self):
10+
self.assertFalse(Luhn("1").is_valid())
11+
12+
def test_a_single_zero_is_invalid(self):
13+
self.assertFalse(Luhn("0").is_valid())
14+
15+
def test_a_simple_valid_SIN_that_remains_valid_if_reversed(self):
16+
self.assertTrue(Luhn("059").is_valid())
17+
18+
def test_a_simple_valid_SIN_that_becomes_invalid_if_reversed(self):
19+
self.assertTrue(Luhn("59").is_valid())
20+
21+
def test_a_valid_Canadian_SIN(self):
22+
self.assertTrue(Luhn("055 444 285").is_valid())
1223

13-
def test_addends_large(self):
14-
# uses a Counter to avoid specifying order of return value
15-
self.assertEqual(Counter([7, 6, 6, 1]),
16-
Counter(Luhn(8631).addends()))
24+
def test_invalid_Canadian_SIN(self):
25+
self.assertFalse(Luhn("055 444 286").is_valid())
1726

18-
def test_checksum1(self):
19-
self.assertEqual(22, Luhn(4913).checksum())
27+
def test_invalid_credit_card(self):
28+
self.assertFalse(Luhn("8273 1232 7352 0569").is_valid())
2029

21-
def test_ckecksum2(self):
22-
self.assertEqual(21, Luhn(201773).checksum())
30+
def test_valid_strings_with_a_non_digit_included_become_invalid(self):
31+
self.assertFalse(Luhn("055a 444 285").is_valid())
2332

24-
def test_invalid_number(self):
25-
self.assertFalse(Luhn(738).is_valid())
33+
def test_valid_strings_with_punctuation_included_become_invalid(self):
34+
self.assertFalse(Luhn("055-444-285").is_valid())
2635

27-
def test_valid_number(self):
28-
self.assertTrue(Luhn(8739567).is_valid())
36+
def test_valid_strings_with_symbols_included_become_invalid(self):
37+
self.assertFalse(Luhn("055£ 444$ 285").is_valid())
2938

30-
def test_create_valid_number1(self):
31-
self.assertEqual(1230, Luhn.create(123))
39+
def test_single_zero_with_space_is_invalid(self):
40+
self.assertFalse(Luhn("0").is_valid())
3241

33-
def test_create_valid_number2(self):
34-
self.assertEqual(8739567, Luhn.create(873956))
42+
def test_more_than_a_single_zero_is_valid(self):
43+
self.assertTrue(Luhn("0000 0").is_valid())
3544

36-
def test_create_valid_number3(self):
37-
self.assertEqual(8372637564, Luhn.create(837263756))
45+
def test_input_digit_9_is_correctly_converted_to_output_digit_9(self):
46+
self.assertTrue(Luhn("091").is_valid())
3847

3948
def test_is_valid_can_be_called_repeatedly(self):
49+
# Additional track specific test case
4050
# This test was added, because we saw many implementations
4151
# in which the first call to is_valid() worked, but the
4252
# second call failed().
43-
number = Luhn(8739567)
53+
number = Luhn("055 444 285")
4454
self.assertTrue(number.is_valid())
4555
self.assertTrue(number.is_valid())
4656

0 commit comments

Comments
 (0)