Skip to content

Instantly share code, notes, and snippets.

@kennethreitz
Created January 13, 2013 11:16
Show Gist options
  • Select an option

  • Save kennethreitz/4523594 to your computer and use it in GitHub Desktop.

Select an option

Save kennethreitz/4523594 to your computer and use it in GitHub Desktop.
Spoken numbers and roman numerals
# -*- coding: utf-8 -*-
import sys
def int_to_roman(input):
"""
Convert an integer to Roman numerals.
Examples:
>>> int_to_roman(0)
Traceback (most recent call last):
ValueError: Argument must be between 1 and 3999
>>> int_to_roman(-1)
Traceback (most recent call last):
ValueError: Argument must be between 1 and 3999
>>> int_to_roman(1.5)
Traceback (most recent call last):
TypeError: expected integer, got <type 'float'>
>>> for i in range(1, 21): print int_to_roman(i)
...
I
II
III
IV
V
VI
VII
VIII
IX
X
XI
XII
XIII
XIV
XV
XVI
XVII
XVIII
XIX
XX
>>> print int_to_roman(2000)
MM
>>> print int_to_roman(1999)
MCMXCIX
"""
if type(input) != type(1):
raise TypeError, "expected integer, got %s" % type(input)
if not 0 < input < 4000:
raise ValueError, "Argument must be between 1 and 3999"
ints = (1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1)
nums = ('M', 'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I')
result = ""
for i in range(len(ints)):
count = int(input / ints[i])
result += nums[i] * count
input -= ints[i] * count
return result
## {{{ http://code.activestate.com/recipes/413172/ (r3)
_known = {
0: 'zero',
1: 'one',
2: 'two',
3: 'three',
4: 'four',
5: 'five',
6: 'six',
7: 'seven',
8: 'eight',
9: 'nine',
10: 'ten',
11: 'eleven',
12: 'twelve',
13: 'thirteen',
14: 'fourteen',
15: 'fifteen',
16: 'sixteen',
17: 'seventeen',
18: 'eighteen',
19: 'nineteen',
20: 'twenty',
30: 'thirty',
40: 'forty',
50: 'fifty',
60: 'sixty',
70: 'seventy',
80: 'eighty',
90: 'ninety'
}
def _positive_spoken_number(n):
"""Assume n is a positive integer.
>>> _positive_spoken_number(900)
'nine hundred'
>>> _positive_spoken_number(100)
'one hundred'
>>> _positive_spoken_number(100000000000)
'one hundred billion'
>>> _positive_spoken_number(1000000000000)
'one trillion'
>>> _positive_spoken_number(33000000000000)
'thirty-three trillion'
>>> _positive_spoken_number(34954523539)
'thirty-four billion, nine hundred fifty-four million, five hundred twenty-three thousand, five hundred thirty-nine'
"""
#import sys; print >>sys.stderr, n
if n in _known:
return _known[n]
bestguess = str(n)
remainder = 0
if n<=20:
print >>sys.stderr, n, "How did this happen?"
assert 0
elif n < 100:
bestguess= _positive_spoken_number((n//10)*10) + '-' + \
_positive_spoken_number(n%10)
return bestguess
elif n < 1000:
bestguess= _positive_spoken_number(n//100) + ' ' + 'hundred'
remainder = n%100
elif n < 1000000:
bestguess= _positive_spoken_number(n//1000) + ' ' + 'thousand'
remainder = n%1000
elif n < 1000000000:
bestguess= _positive_spoken_number(n//1000000) + ' ' + 'million'
remainder = n%1000000
elif n < 1000000000000:
bestguess= _positive_spoken_number(n//1000000000) + ' ' + 'billion'
remainder = n%1000000000
else:
bestguess= _positive_spoken_number(n//1000000000000)+' '+'trillion'
remainder = n%1000000000000
if remainder:
if remainder >= 100: comma = ','
else: comma = ''
return bestguess + comma + ' ' + _positive_spoken_number(remainder)
else:
return bestguess
def spoken_number(n):
"""Return the number as it would be spoken, or just str(n) if unknown.
>>> spoken_number(0)
'zero'
>>> spoken_number(1)
'one'
>>> spoken_number(2)
'two'
>>> spoken_number(-2)
'minus two'
>>> spoken_number(42)
'forty-two'
>>> spoken_number(-1011)
'minus one thousand eleven'
>>> spoken_number(1111)
'one thousand, one hundred eleven'
"""
if not isinstance(n, int) and not isinstance(n, long): return n
if n<0:
if n in _known: return _known[n]
else: return 'minus ' + _positive_spoken_number(-n)
return _positive_spoken_number(n)
if __name__ == '__main__':
print spoken_number(101).replace(' ', '-')
print int_to_roman(23)
## end of http://code.activestate.com/recipes/413172/ }}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment