Numerals

This program takes a number and calculate it’s linguistic numeral.
The number 3 returns the numeral \text{three}, 58 returns \text{fifty-eight} and 31415.926535 returns \text{thirty-one thousand four hundred fifteen point nine two six five three five}.

The code executed on a shell.


# Python 2.7.7 Code
# Jonathan Frech 24th of May , 2016
#         edited 17th of June, 2016
#         edited 29th of June, 2017
#         * fixed spelling of 'forty'
#         * (In the post's image you can
#           still see the incorrect version.)
#         * Errare humanum est.

# import needed modules
import re

# get three digit's name
def section(n):
	# variables
	name = []
	
	# in case it is zero
	if n == 0:
		return "zero"
	
	# hundreds
	if n > 99:
		name.append(["", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"][int(n/100)])
		name.append("hundred")
		n -= int(n/100)*100
	
	# special number names
	if n > 10 and n < 20: name.append(["eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"][n - 11]) return join(name) # tens if n > 9:
		name.append(["", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"][int(n/10)])
		name.append("-")
		n -= int(n/10)*10
		if n == 0:
			name.pop(-1)
	
	# ones
	if n > 0:
		name.append(["", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"][n])
	
	# return joined name
	return join(name)

# joins the name list together
def join(name):
	# variables
	n = ""
	
	# add a space between
	for _ in name:
		if _ != "":
			n += " " + _
	
	# for example 'fifty-five' instead of 'fifty - five'
	n = re.sub("\ \-\ ", "-", n)
	
	# remove space at the end
	n = n[1:len(n)]
	
	# special zero case
	if n == "":
		n = "zero"
	
	# return joined name
	return n

# get n's name
def name(n):
	# variables
	name = []
	
	# special cases
	global cases
	if n in cases:
		return cases[n]
	
	# remove zeros at the front
	n = re.sub("^0+", "0", n)
	
	# check for negative numbers
	if n[0] == "-":
		# split off the minus sign
		n = n[1:len(n)]
		
		# add negativity to the name
		name.append("minus")	
	
	# check for floats
	f = None
	if "." in n:
		_ = re.split("\.", n)
		n = _[0]
		f = _[1]
	
	# make the number's length a multiple of three
	while len(n)%3 != 0:
		n = "0" + n
	
	# go through pairs of three and determine names
	for _ in range(0, len(n)/3):
		if int(n[(_*3):(_*3+3)]) != 0:
			name.append(section(int(n[(_*3):(_*3+3)])))
			powers = ["", "", "thousand", "million", "billion", "trillion", "quadrillion"]
			if (len(n)/3-_) >= len(powers):
				name.append("e" + str(3*(len(n)/3-_-1)))
			else:
				name.append(powers[len(n)/3-_])
	
	# add the number's float part
	if f:
		name.append("point")
		for _ in f:
			name.append(["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"][int(_)])
	
	# return joined name
	return join(name)

# check if n even is a number
def check(n):
	# number is a float
	flt = False
	
	# special cases
	global cases
	if n in cases:
		return True
	
	# go through number
	for _ in range(0, len(n)):
		
		# at first place there can be a minus sign
		if n[_] == "-":
			if _ != 0:
				return False
		
		# number could be a float (but not twice!)
		elif n[_] == ".":
			if flt:
				return False
			else:
				flt = True	
		
		# numbers in base ten consist of ten different digits
		else:
			if n[_] not in "0123456789":
				return False
			
	# number is fine
	return True

print "================="
print " N U M E R A L S "
print "================="
print ""

# special cases
global cases
cases = {"":""}
cases = {
	"pi" : name("3.1415") + " and so on...",
	"tau": name("6.2831") + " and so on...",
	"e"  : name("2.7182") + " and so on...",
	"phi": name("1.6180") + " and so on..."
	}

# main loop
while True:
	# get input
	n = raw_input("> ")
	
	# check input
	if check(n):
		print name(n)
	else:
		print "'" + n + "' is not a number..."
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s