Number words

In this lab, you will develop a marginally-useful program which writes out numbers as they are spoken in English:

% python nw.py 13
thirteen
% python nw.py 122
one hundred and twenty-two
% python nw.py 447
four hundred and forty-seven
% python nw.py 12003
twelve thousand three
% python nw.py 577911
five hundred and seventy-seven thousand nine hundred and eleven

This problem set builds on the scatterplot lab. You will take more responsibility for top-down thinking, planning how to break down the problem into simpler problems. Before we start, a few new ideas:

Top-down planning

Look at the examples of written-out numbers given above, and try writing out a few more examples yourself. Do you see any patterns in how numbers are written? Use planning.md to write dow your thinking.

Bottom-up implementation

Now implement the functions in numberwords.py. You can use python nw.py 1567 to try out your code, and you can run test_numberwords.py to test out your code more methodically. (You may find that running tests frequently is an efficient way to make progress.)

divide_with_remainder(dividend, divisor)

In regular division, 5 / 2 equals 2.5. However, in integer division (which you probably learned in elementary school), instead of returning a decimal number, you just return an integer and then you also return a remainder, the part that can't be evenly divided. This function implements integer division, returning both the quotient and the remainder. (In Python, the operator for integer division is // and the operator for remainder (also called modulo) is %.) For example:

>>> divide_with_remainder(5, 2)
2, 1
>>> divide_with_remainder(142, 100)
1, 42

In this problem set, you will find this function useful for splitting numbers into parts. For example, in English, the part of a number over 100 is always written out separately from the part under 100, so you can use this function to separate out the hundreds from anything less than 100.

IntegerPart over 100andPart under 100
101"one hundred"" and ""one"
265"two hundred"" and ""sixty-five"
12722"twelve thousand seven hundred"" and ""twenty-two"

int_under_10_to_str(number)

You are already given DIGIT_NAMES, a list of digit names. As described in your planning document, you can just return DIGIT_NAMES[number].

int_under_100_to_st(number)

You should probably start by checking if the number is less than 10; in this case just return int_under_10_to_str(number).

Now, if the number is less than 20, English has some pesky irregular number names. Fortunately these are provided in TWEEN_AND_TEEN_NAMES.

After 20, the numbers get more regular. You can use TENS_NAMES to get the tens-part of the name, and int_under_10_to_str to get the ones part of the name.

int_under_1000_to_str(number)

Again, if the number is less than 100, you already have a function for that.

Otherwise, the pattern is pretty straightforward: the hundreds part is something like "seven hundred", and the part less than 100 can be handled by int_under_100_to_str.

int_under_1000000_to_str(number)

Now we can jump all the way up to a million. What's the pattern here? How can you use the functions you have already written?

Just for fun

If you're on a mac, there is a neat built-in program called say which speaks in a human-like voice. For example, if you run say "hello", the computer will greet you. After you finish the problem set, try piping the output of nw.py into say:

python nw.py 144265 | say