generated from mwc/problemset_numberwords
	Initial commit
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
__pycache__/*
 | 
			
		||||
*.swp
 | 
			
		||||
*.swo
 | 
			
		||||
							
								
								
									
										69
									
								
								numberwords.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								numberwords.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
# 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_str(number):
 | 
			
		||||
    "Returns a textual representation of the number."
 | 
			
		||||
    check_number_in_range(abs(number), 0, MAXIMUM)
 | 
			
		||||
    if number < 1000:
 | 
			
		||||
        return int_under_1000_to_str(number)
 | 
			
		||||
    else:
 | 
			
		||||
        thousands, hundreds = divide_with_remainder(number, 1000)
 | 
			
		||||
        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_str(number):
 | 
			
		||||
    "Returns a textual representation of the number"
 | 
			
		||||
    check_number_in_range(number, 0, 1000)
 | 
			
		||||
    if number < 100:
 | 
			
		||||
        return int_under_100_to_str(number)
 | 
			
		||||
    else:
 | 
			
		||||
        hundreds, tens = divide_with_remainder(number, 100)
 | 
			
		||||
        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_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:
 | 
			
		||||
        return TENS_NAMES[tens] + '-' + int_under_10_to_str(ones)
 | 
			
		||||
 | 
			
		||||
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:
 | 
			
		||||
        raise ValueError(f"{number} must be less than {maximum}.")
 | 
			
		||||
 | 
			
		||||
def divide_with_remainder(dividend, divisor):
 | 
			
		||||
    """Divides one number by another, using whole-number division. 
 | 
			
		||||
    Returns the quotient and the remainder.
 | 
			
		||||
    Note how a function can return more than one value!
 | 
			
		||||
    """
 | 
			
		||||
    quotient = dividend // divisor
 | 
			
		||||
    remainder = dividend % divisor
 | 
			
		||||
    return quotient, remainder
 | 
			
		||||
							
								
								
									
										14
									
								
								nw.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								nw.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
# 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_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_str(args.number)
 | 
			
		||||
print(text)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										55
									
								
								planning.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								planning.md
									
									
									
									
									
										Normal 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?
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										7
									
								
								poetry.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								poetry.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand.
 | 
			
		||||
package = []
 | 
			
		||||
 | 
			
		||||
[metadata]
 | 
			
		||||
lock-version = "2.0"
 | 
			
		||||
python-versions = "^3.10"
 | 
			
		||||
content-hash = "53f2eabc9c26446fbcc00d348c47878e118afc2054778c3c803a0a8028af27d9"
 | 
			
		||||
							
								
								
									
										16
									
								
								pyproject.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								pyproject.toml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
[tool.poetry]
 | 
			
		||||
name = "problemset-numberwords"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
description = ""
 | 
			
		||||
authors = ["Chris Proctor <chris@chrisproctor.net>"]
 | 
			
		||||
readme = "README.md"
 | 
			
		||||
 | 
			
		||||
[tool.poetry.dependencies]
 | 
			
		||||
python = "^3.10"
 | 
			
		||||
 | 
			
		||||
[build-system]
 | 
			
		||||
requires = ["poetry-core"]
 | 
			
		||||
build-backend = "poetry.core.masonry.api"
 | 
			
		||||
 | 
			
		||||
[tool.poetry.scripts]
 | 
			
		||||
numwords = "cli:cli"
 | 
			
		||||
							
								
								
									
										37
									
								
								test_numberwords.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								test_numberwords.py
									
									
									
									
									
										Normal 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}'")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user