Add tests and planning doc

This commit is contained in:
Chris Proctor 2023-08-04 13:07:47 -04:00
parent cdfff4eb5f
commit 62f2ccef87
4 changed files with 131 additions and 67 deletions

View File

@ -1,88 +1,59 @@
# int_to_text.py
# numberwords.py
# --------------
# By MWC Contributors
# Functions to print out a verbal representation of an integer.
MAXIMUM = 1000000
DIGIT_NAMES = [
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"
]
TWEEN_AND_TEEN_NAMES = [
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
]
TENS_NAMES = [
"ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"
]
def int_under_1000000_to_text(number):
def int_under_1000000_to_str(number):
"Returns a textual representation of the number."
check_number_in_range(abs(number), 1 , MAXIMUM)
check_number_in_range(abs(number), 0, MAXIMUM)
if number < 1000:
return int_under_1000_to_text(number)
return int_under_1000_to_str(number)
else:
thousands, hundreds = divide_with_remainder(number, 1000)
thousands_text = int_under_1000_to_text(thousands)
hundreds_text = int_under_1000_to_text(hundreds)
thousands_text = int_under_1000_to_str(thousands)
hundreds_text = int_under_1000_to_str(hundreds)
return thousands_text + " thousand " + hundreds_text
def int_under_1000_to_text(number):
def int_under_1000_to_str(number):
"Returns a textual representation of the number"
check_number_in_range(number, 1, 1000)
check_number_in_range(number, 0, 1000)
if number < 100:
return int_under_100_to_text(number)
return int_under_100_to_str(number)
else:
hundreds, tens = divide_with_remainder(number, 100)
hundreds_text = int_under_10_to_text(hundreds)
tens_text = int_under_100_to_text(tens)
hundreds_text = int_under_10_to_str(hundreds)
tens_text = int_under_100_to_str(tens)
return hundreds_text + " hundred and " + tens_text
def int_under_100_to_text(number):
check_number_in_range(number, 1, 100)
if number < 10:
return int_under_10_to_text(number)
def int_under_100_to_str(number):
check_number_in_range(number, 0, 100)
tens, ones = divide_with_remainder(number, 10)
if tens == 0:
return int_under_10_to_str(number)
elif tens == 1:
return TWEEN_AND_TEEN_NAMES[ones]
else:
tens, ones = divide_with_remainder(number, 10)
if tens == 9:
return "ninety-" + int_under_10_to_text(ones)
elif tens == 8:
return "eighty-" + int_under_10_to_text(ones)
elif tens == 7:
return "seventy-" + int_under_10_to_text(ones)
elif tens == 6:
return "sixty-" + int_under_10_to_text(ones)
elif tens == 5:
return "fifty-" + int_under_10_to_text(ones)
elif tens == 4:
return "forty-" + int_under_10_to_text(ones)
elif tens == 3:
return "thirty-" + int_under_10_to_text(ones)
elif tens == 2:
return "twenty-" + int_under_10_to_text(ones)
elif number >= 16:
return int_under_10_to_text(ones) + "teen"
elif number == 15:
return "fifteen"
elif number == 14:
return "fourteen"
elif number == 13:
return "thirteen"
elif number == 12:
return "twelve"
elif number == 11:
return "eleven"
return TENS_NAMES[tens] + '-' + int_under_10_to_str(ones)
def int_under_10_to_text(number):
check_number_in_range(number, 1, 10)
if number == 1:
return "one"
elif number == 2:
return "two"
elif number == 3:
return "three"
elif number == 4:
return "four"
elif number == 5:
return "five"
elif number == 6:
return "six"
elif number == 7:
return "seven"
elif number == 8:
return "eight"
elif number == 9:
return "nine"
def int_under_10_to_str(number):
check_number_in_range(number, 0, 10)
return DIGIT_NAMES[number]
def check_number_in_range(number, minimum, maximum):
"""Checks whether a number is at least minimum and less than maximum.
Raises an error if the number is not in range.
"""
if number < minimum:
raise ValueError(f"{number} must not be below {minimum}.")
if number >= maximum:

7
nw.py
View File

@ -1,13 +1,14 @@
# cli.py
# nw.py
# ------
# Implements a simple number-to-text command-line interface.
# Ex: python nw.py 145
from argparse import ArgumentParser
from numberwords import int_under_1000000_to_text
from numberwords import int_under_1000000_to_str
parser = ArgumentParser("Print out a number as it is spoken in English.")
parser.add_argument("number", type=int)
args = parser.parse_args()
text = int_under_1000000_to_text(args.number)
text = int_under_1000000_to_str(args.number)
print(text)

55
planning.md Normal file
View File

@ -0,0 +1,55 @@
# Planning Number Words
Before you start programming, do some planning here on how you will break down
this problem. Here's a hint: if you start by writing functions for smaller numbers,
you will find that these functions help you with the larger numbers. For each of
the cases below, explain how you would turn a number into a string. Feel free to
write in sentences or in pseudocode (pseudocode is a sort of "casual programming"
where you're almost writing in code, being pretty specific without worrying about
syntax. For each case below, assume the integer is zero or more--don't worry about
negative integers.
## Integers under 10
(This one is done for you!)
For an integer less than ten, you need to know the name of each digit, and look it
up. You could use a big if/else statement like:
```
if number == 0:
return "zero"
elif number == 1:
return "one"
elif number == 1:
return "two"
```
A cleaner way to do this would be to make a list of digit names, from zero to nine.
Then you could just look up a digit's name:
```
digit_names = [
"zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine"
]
return digit_names[number]
```
## Integers under 20
If the integer is under 10, then use the procedure described above.
Otherwise, ... (this is where you take over!)
## Integers under 100
## Integers under 1000
## Integers under 1000000
## Negative integers down to -1 million
We won't deal with negative integers in this problem set,
but how would you deal with a negative integer, using the
functions above?

37
test_numberwords.py Normal file
View File

@ -0,0 +1,37 @@
# test_numberwords.py
# -------------------
# By MWC Contributors
# Run this file to test your implementation of numberwords.py
from numberwords import int_under_1000000_to_str
test_cases = [
[0, 'zero'],
[3, 'three'],
[9, 'nine'],
[11, 'eleven'],
[15, 'fifteen'],
[18, 'eighteen'],
[43, 'fifty-three'],
[60, 'seventy-zero'],
[89, 'ninety-nine'],
[100, 'one hundred and zero'],
[212, 'two hundred and twelve'],
[755, 'seven hundred and sixty-five'],
[1000, 'one thousand zero'],
[1001, 'one thousand one'],
[1672, 'one thousand six hundred and eighty-two'],
[10000, 'ten thousand zero'],
[588567, 'five hundred and ninety-eight thousand five hundred and seventy-seven'],
]
for int_input, expected_output in test_cases:
observed_output = int_under_1000000_to_str(int_input)
if observed_output == expected_output:
print(f"PASS: {int_input} -> '{observed_output}'")
else:
print(f"FAIL: {int_input}: Expected '{expected_output}' but got '{observed_output}'")