Converting Numbers to English Equivalents

This will convert any number from 1 to 9,999 into a word. I am aware that I could have shaved a few more lines off with an ignore error command and I could have made it work with negatives, decimals, and fractions with three more arrays. I am also aware that I could have made it work up to trillions. But I did it this way because I made this script as a school requirement so I am just showing it to you. Lastly, I didn’t make notes because I had to keep it in limited space for my school to accept it.

property num : ""
tell application "Finder"
	display dialog "Input Number:" with title "Num2WordConverter" default answer num
	set num to text returned of result
	set thousandsList to {"one thousand", "two thousand", "three thousand", "four thousand", "five thousand", "six thousand", "seven thousand", "eight thousand", "nine thousand", "zero"}
	set hundredsList to {"one hundred", "two hundred", "three hundred", "four hundred", "five hundred", "six hundred", "seven hundred", "eight hundred", "nine hundred", "zero"}
	set tensList to {"teenies", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety", "zero"}
	set teeniesList to {"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "zero"}
	set onesList to {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "zero"}
	set userInput to items of num
	set helper to 4
	set initiallimiter to count of userInput
	set thisisFirst to 1
	if item 2 of userInput is "," and initiallimiter is equal to 5 then
		set item 2 of userInput to item 3 of userInput
		set item 3 of userInput to item 4 of userInput
		set item 4 of userInput to item 5 of userInput
		set userInput2 to (items 1 thru 4 of userInput)
		set userInput to (items 1 thru 4 of userInput2)
	end if
	set limitofAll to count userInput
	set initiallimiter to count of userInput
	repeat until limitofAll is 0
		if limitofAll is greater than 4 then
			display dialog "Too many"
			set limitofAll to 0
		else if limitofAll is equal to 4 and thisisFirst is equal to 1 then
			set helper to (limitofAll - (limitofAll - 1))
			set thisisFirst to 0
			set bug to item helper of userInput
			set final to item bug of thousandsList
			set limitofAll to limitofAll - 1
		else if limitofAll is equal to 4 then
			set helper to (limitofAll - (limitofAll - 1))
			set bug to item helper of userInput
			set final to item bug of thousandsList
			set limitofAll to limitofAll - 1
		else if limitofAll is equal to 3 and thisisFirst is equal to 1 then
			set helper to (limitofAll - (limitofAll - 1))
			set thisisFirst to 0
			set bug to item helper of userInput
			set final2 to item bug of hundredsList
			set limitofAll to limitofAll - 1
		else if limitofAll is equal to 3 then
			set helper to helper + 1
			set bug to item helper of userInput
			set final2 to item bug of hundredsList
			set limitofAll to limitofAll - 1
		else if limitofAll is equal to 2 and thisisFirst is equal to 1 then
			set helper to (limitofAll - (limitofAll - 1))
			set thisisFirst to 0
			set bug to item helper of userInput
			set final3 to item bug of tensList
			set limitofAll to limitofAll - 1
		else if limitofAll is equal to 2 then
			set helper to helper + 1
			set bug to item helper of userInput
			set final3 to item bug of tensList
			set limitofAll to limitofAll - 1
		else if limitofAll is equal to 1 and thisisFirst is equal to 1 then
			set helper to (limitofAll - (limitofAll - 1))
			set thisisFirst to 0
			set bug to item helper of userInput
			set final4 to item bug of onesList
			set limitofAll to limitofAll - 1
		else if limitofAll is equal to 1 then
			set helper to helper + 1
			set bug to item helper of userInput
			set final4 to item bug of onesList
			set limitofAll to limitofAll - 1
		else
			nullplace
		end if
	end repeat
	if initiallimiter is equal to 4 and final3 is equal to "teenies" then
		display dialog "" & final & ", " & final2 & " " & item bug of teeniesList & ""
	else if initiallimiter is equal to 4 then
		display dialog "" & final & ", " & final2 & " " & final3 & " " & final4 & ""
	else if initiallimiter is equal to 3 and final3 is equal to "teenies" then
		display dialog "" & final2 & " " & item bug of teeniesList & ""
	else if initiallimiter is equal to 3 then
		display dialog "" & final2 & " " & final3 & " " & final4 & ""
	else if initiallimiter is equal to 2 and final3 is equal to "teenies" then
		display dialog item bug of teeniesList
	else if initiallimiter is equal to 2 then
		display dialog "" & final3 & " " & final4 & ""
	else if initiallimiter is equal to 1 then
		display dialog "" & final4 & ""
	end if
	
	set final to 0
	set final2 to 0
	set final3 to 0
	set final4 to 0
end tell

Model: MacBook Pro
AppleScript: 2.1
Browser: Safari 532.0
Operating System: Mac OS X (10.6)

I made the new one more efficient:


property num : ""
tell application "Finder"
	display dialog "Input Number" default answer num
	set num to text returned of result
	set ones to {"p1", " one", " two", " three", " four", " five", " six", " seven", " eight", " nine", " ten", " eleven", " twelve", " thirteen", " fourteen", " fifteen", " sixteen", " seventeen", " eighteen", " nineteen"}
	set tens to {"p2", " twenty", " thirty", " forty", " fifty", " sixty", " seventy", " eighty", " ninety"}
	set answer to {""}
	set userInput to items of num
	set initiallimiter to count of userInput
	if (count of userInput) is greater than 1 then
		if item 2 of userInput is "," then
			set item 2 of userInput to item 3 of userInput
			set item 3 of userInput to item 4 of userInput
			set item 4 of userInput to item 5 of userInput
			set userInput to (items 1 thru 4 of userInput)
		else
			set program to "happy"
		end if
	end if
	set userInput to reverse of userInput
	if (count of items of userInput) is not equal to 4 then
		repeat with i from 1 to (4 - (count of userInput))
			set userInput to userInput & "0"
		end repeat
	else
		set program to "happy"
	end if
	set userInput to reverse of userInput
	set helper to count of userInput
	set teenies to not true
	if item 1 of userInput is not equal to "0" then
		set helpertwo to item 1 of userInput
		set answer to answer & ((item (helpertwo + 1)) of ones) & " thousand"
		set helper to helper - 1
	end if
	set helper to helper - 1
	if item 2 of userInput is not equal to "0" then
		set helpertwo to item 2 of userInput
		set answer to answer & ((item (helpertwo + 1)) of ones) & " hundred"
		set helper to helper - 1
	end if
	set helper to helper - 1
	if item 3 of userInput is not equal to "0" then
		if item 3 of userInput is equal to "1" then
			set answer to answer & item ((item 4 of userInput) + 11) of ones
			set teenies to true
		else if item 3 of userInput is greater than "1" then
			set helpertwo to item 3 of userInput
			set answer to answer & item (helpertwo) of tens
		end if
	end if
	set helper to helper - 1
	if item 4 of userInput is not equal to "0" then
		set helpertwo to item 4 of userInput
		set answer to answer & ((item (helpertwo + 1)) of ones)
		set helper to helper - 1
	end if
	if teenies is true then
		set answer to reverse of rest of reverse of answer
		set answer to items 1 thru (count of answer) of answer
	end if
	display dialog answer as string
end tell

Got bored yesterday. Made this.

set userInput to text -4 thru -1 of ("0000" & text returned of (display dialog "Input Number" default answer ""))
set ones to {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}
set tens to {"twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"}
set answer to {}

repeat with i from 1 to 4
	set theNumber to (text item i of userInput) as number
	if i = 1 and theNumber ≠ 0 then
		set end of answer to item theNumber of ones
		set end of answer to "thousand"
	else if i = 2 and theNumber ≠ 0 then
		set end of answer to item theNumber of ones
		set end of answer to "hundred"
	else if i = 3 and theNumber ≠ 0 and (text -2 thru -1 of userInput) as number < 20 then
		set end of answer to item ((text -2 thru -1 of userInput) as number) of ones
		exit repeat
	else if i = 3 and theNumber ≠ 0 then
		set end of answer to item (theNumber - 1) of tens
	else if i = 4 and theNumber ≠ 0 then
		set end of answer to item theNumber of ones
	end if
end repeat

set ASTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to space
set answer to answer as text
set AppleScript's text item delimiters to ASTID

display dialog answer

That code is impressive. I did not understand some of the lines before I read this. Unfortunately, I wish we could see what the code would look like in machine language because that can affect the running time. Applescript is very deceptive that way. One line of code in applescript, on many instances, is 3 lines machine language. (not exactly but I think that you understand the point.)

I wonder how many lines my code would be if I did not include the comma support feature. Anyway, the only thing I would not have done with your code, if I were you, would be removing the ≠and replacing it with something that is a basic form and understood by logic gates in the simplest like, greater than and less than. I think that could make it run the slightest bit faster, although it would remain unnoticeable.

I did notice that you did virtually the same thing as I did, however you made it more english-based, thus making any compilation time slower. But it does not matter because programs at this level are going to run at the same speed, for the most part.

Impressive code though.

The code can be as far as I know even smaller. But I never bothered about that. Using ≠instead of is not is one of my coding habits… I remember I did a test once to see the difference (in speed that is) between those two so I repeated it a few million times and measured the time in milliseconds (thanks to Nigel’s Lotsa routine) I don’t remember the exact result but the difference was so small that you could say exactly it were only a few milliseconds and for repeating it a few millions, that’s just nothing…

One thing you can always do is make a list of all numbers like {“one”,“two”,…,“three thousand”} and then using something like item answer of theList. This could be faster but it’s not like the best way to do it.

To make the code shorter (and faster ?) you can get rid of the repeat loop etc…

Hi,

this is another approach, it considers integers from -(1.0E+15 -1) to 1.0E+15 -1


property oneToNineList : {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"}
property tenToNineteenList : {"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"}
property twentyToNinetyList : {"", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"}
property thousendToTrillionList : {"", " Thousand ", " Million ", " Billion ", " Trillion "}

display dialog "enter number" default answer "12345"
set textNumber to text returned of result
set theResult to convertNumberToWords(textNumber as integer)
display dialog theResult buttons {"Cancel", "Say It!"} default button 2
say theResult

on convertNumberToWords(intValue)
	try
		set minus to ""
		if intValue < 0 then
			set minus to "minus"
			set intValue to -intValue
		end if
		set intWords to ""
		if intValue is not 0 then
			set x to 1
			repeat until intValue = 0
				set intWords to GetHundreds(intValue mod 1000) & item x of thousendToTrillionList & intWords
				set x to x + 1
				set intValue to intValue div 1000
			end repeat
			return minus & space & intWords
		end if
	on error
		say "number out of range"
		error number -128
	end try
end convertNumberToWords

on GetHundreds(numValue)
	if numValue > 99 then
		return GetDigit(numValue div 100) & " Hundred " & GetTens(numValue mod 100)
	else
		return GetTens(numValue)
	end if
end GetHundreds

on GetTens(tt)
	if tt < 10 then
		return GetDigit(tt)
	else if tt < 20 then
		return item (tt - 9) of tenToNineteenList
	else
		return item (tt div 10) of twentyToNinetyList & item ((((tt mod 10) = 0) as integer) + 1) of {" ", ""} & GetDigit(tt mod 10)
	end if
end GetTens

on GetDigit(digit)
	return item (digit + 1) of oneToNineList
end GetDigit

I understand the difference is very minimal. The percentage gets especially smaller the faster your processor because ≠breaks down into two functions. A regular processor is 2.3+ GHz which is 2,300,000,000. So if that can be done in one second then, only two functions should take an unnoticeable amount of time. And doing that function with parallel processing is at least half the time. I know it is no big deal but then in any program you could just say, “Oh. It’s only two extra functions.” Anyway, it was still really good. I like it.

@Stefan

That one is pretty impressive.

That was my theory however I did mine for a project that had specific needs. If you can solve for each group of three then you can just give it a suffix depending on what group of three it is in.

1,000,120 → 001,000,120
one " " one hundred twenty

one million " " one hundred twenty

At that point all you have to look out for are special conditions like when there are all 0’s in a group.

I’m very keen about speed while coding, I never knew the difference but whenever I wrote something I checked all alternatives and if there was a faster (harder to code or not) I’d used it. May I ask, how do you know all those details?

I noticed that none of the four scripts here work with the number 0. To make Stefan’s script working with 0 you’d have to use

if intValue is not 0 then
			set x to 1
			repeat until intValue = 0
				set intWords to GetHundreds(intValue mod 1000) & item x of thousendToTrillionList & intWords
				set x to x + 1
				set intValue to intValue div 1000
			end repeat
			return minus & space & intWords
		else
			return 0
		end if

Using the 1,000,120 → 001,000,120 is a very smart approach, I didn’t think of that. :wink:

replace this part


.
if intValue is not 0 then
	set x to 1
	repeat until intValue = 0
		set i to intValue mod 1000
		if i is not 0 then
			set intWords to GetHundreds(i) & item x of thousendToTrillionList & intWords
		end if
		set x to x + 1
		set intValue to intValue div 1000
	end repeat
	return minus & space & intWords
end if
.

I know that stuff because when I am programming I think of the process that has to happen in English and/or pseudocode. So then I can say to my self if 1 is the input it will do this, if zero is the input blah blah blah. Then, I act like the computer and go through my code. So, I follow where the input is sort of like a debugger. So, when there was a zero and I would go through my code, not what should happen but what my code says, if I couldn’t do it I knew that the computer can’t do it. Then, I would make my code so that I could do it.

Model: MacBook
AppleScript: 2.3
Browser: Safari 531.21.10
Operating System: Mac OS X (10.6)