Skip to content

Commit cdfcc73

Browse files
committed
say: Implement new exercise
1 parent 59cd334 commit cdfcc73

3 files changed

Lines changed: 112 additions & 0 deletions

File tree

config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"sieve",
2020
"atbash-cipher",
2121
"sum-of-multiples",
22+
"say",
2223
"largest-series-product",
2324
"kindergarten-garden",
2425
"grade-school",

say/example.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
def say(number, recursive=False):
2+
small = dict(enumerate((
3+
'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight',
4+
'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen',
5+
'sixteen', 'seventeen', 'eighteen', 'ninteen', 'twenty')))
6+
7+
tens = {20: 'twenty', 30: 'thirty', 40: 'forty', 50: 'fifty',
8+
60: 'sixty', 70: 'seventy', 80: 'eighty', 90: 'ninty'}
9+
10+
k, m, b, t = 1e3, 1e6, 1e9, 1e12
11+
12+
if number < 0:
13+
raise AttributeError('number is negative')
14+
if number >= t:
15+
raise AttributeError('number is too large: %s' % str(number))
16+
17+
if number < 20:
18+
return small[number] if not recursive else 'and ' + small[number]
19+
20+
if number < 100:
21+
if number % 10 == 0:
22+
return small[number]
23+
return tens[number // 10 * 10] + '-' + small[number % 10]
24+
25+
if number < k:
26+
if number % 100 == 0:
27+
return small[number // 100] + ' hundred'
28+
return small[number // 100] + ' hundred and ' + say(number % 100, True)
29+
30+
if number < m:
31+
if number % k == 0:
32+
return say(number // k) + ' thousand'
33+
return say(number // k) + ' thousand ' + say(number % k, True)
34+
35+
if number < b:
36+
if number % m == 0:
37+
return say(number // m) + ' million'
38+
return say(number // m) + ' million ' + say(number % m, True)
39+
40+
if number % b == 0:
41+
return say(number // b) + ' billion'
42+
return say(number // b) + ' billion ' + say(number % b, True)

say/say_test.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import unittest
2+
3+
from say import say
4+
5+
6+
class SayTest(unittest.TestCase):
7+
8+
def test_one(self):
9+
self.assertEqual("one", say(1))
10+
11+
def test_fourteen(self):
12+
self.assertEqual("fourteen", say(14))
13+
14+
def test_twenty(self):
15+
self.assertEqual("twenty", say(20))
16+
17+
def test_twenty_two(self):
18+
self.assertEqual("twenty-two", say(22))
19+
20+
def test_one_hundred(self):
21+
self.assertEqual("one hundred", say(100))
22+
23+
def test_one_hundred_twenty(self):
24+
self.assertEqual("one hundred and twenty", say(120))
25+
26+
def test_one_hundred_twenty_three(self):
27+
self.assertEqual("one hundred and twenty-three", say(123))
28+
29+
def test_one_thousand(self):
30+
self.assertEqual("one thousand", say(1000))
31+
32+
def test_one_thousand_two_hundred_thirty_four(self):
33+
self.assertEqual("one thousand two hundred and thirty-four",
34+
say(1234))
35+
36+
def test_one_million(self):
37+
self.assertEqual("one million", say(1e6))
38+
39+
def test_one_million_two(self):
40+
self.assertEqual("one million and two", say(1000002))
41+
42+
def test_1002345(self):
43+
self.assertEqual(
44+
"one million two thousand three hundred and forty-five",
45+
say(1002345))
46+
47+
def test_one_billion(self):
48+
self.assertEqual("one billion", say(1e9))
49+
50+
def test_number_to_large(self):
51+
with self.assertRaises(AttributeError):
52+
say(1e12)
53+
54+
def test_number_negative(self):
55+
with self.assertRaises(AttributeError):
56+
say(-42)
57+
58+
def test_zero(self):
59+
self.assertEqual("zero", say(0))
60+
61+
def test_987654321123(self):
62+
self.assertEqual("nine hundred and eighty-seven billion " +
63+
"six hundred and fifty-four million " +
64+
"three hundred and twenty-one thousand " +
65+
"one hundred and twenty-three",
66+
say(987654321123))
67+
68+
if __name__ == '__main__':
69+
unittest.main()

0 commit comments

Comments
 (0)