changing numbers to spellings

  • Thread starter flyingisfun1217
  • Start date
F

flyingisfun1217

Hey,

Sorry to bother everybody again, but this group seems to have quite a
few knowledgeable people perusing it.

Here's my most recent problem: For a small project I am doing, I need
to change numbers into letters, for example, a person typing in the
number '3', and getting the output 'Three'. So far, I have an interface
that only collects numbers (or letters), and displays them in a text
variable label (as you can see below). Heres the code I have:

+--------------------------------+-----------------------------------+

var=StringVar()

def collect():
var.set(entrybox.get())

spelledentry=Label(root, textvariable=var)
spelledentry.grid(row=5, column=1)

filler1=Label(root, text=" ")
filler1.grid(row=0, column=0)

titletext=Label(root, text="NumberSpeller2")
titletext.grid(row=0, column=1)

filler2=Label(root, text=" ")
filler2.grid(row=0, column=2)

filler3=Label(root, text="\n")
filler3.grid(row=1, column=0)

entrybox=Entry(root)
entrybox.grid(row=1, column=1, sticky=N)

enterbutton=Button(root, text="Spell!", command=collect)
enterbutton.grid(row=3, column=1, sticky=N)

filler4=Label(root, text="")
filler4.grid(row=4, column=1)

filler5=Label(root, text="")
filler5.grid(row=6, column=1)

website=Label(root, text="Visit the NS2 Website")
website.grid(row=7, column=1, sticky=S)

+-------------------------------------+----------------------------------------+

Like I explained a little before, I need to keep users from entering
any letters, and I need to have the numbers they typed in translated to
text.

Can someone explain how I could go across doing this?

Thanks!
Tanner
 
M

MonkeeSage

Hey,

Sorry to bother everybody again, but this group seems to have quite a
few knowledgeable people perusing it.

Hi Tanner,

I've seen a few of those people; but let a dummy (me) try to help. ;)
As to the numbers to names question: do you need to know the names of
numbers higher than 9? I assume you do...but on the off chance you
don't, just make a list of names and get the index of the current
number in it. E.g.,

num2name = ['Zero', 'One', 'Two', 'Three', 'Four',
'Five', 'Six', 'Seven', 'Eight', 'Nine']
numbers = '1238573620'
names = []
for n in numbers:
names.append(num2name[int(n)])
print '-'.join(names)

If you need the actual names for like "Five Hundred and Sixty Seven", I
think one of the smart people 'round here will have to help with that.
I have some ideas, but I'm not very good at creating complex
algorithms.

Regards,
Jordan
 
S

Steve Holden

Hey,

Sorry to bother everybody again, but this group seems to have quite a
few knowledgeable people perusing it.

Here's my most recent problem: For a small project I am doing, I need
to change numbers into letters, for example, a person typing in the
number '3', and getting the output 'Three'. So far, I have an interface
that only collects numbers (or letters), and displays them in a text
variable label (as you can see below). Heres the code I have:

+--------------------------------+-----------------------------------+

var=StringVar()

def collect():
var.set(entrybox.get())

spelledentry=Label(root, textvariable=var)
spelledentry.grid(row=5, column=1)

filler1=Label(root, text=" ")
filler1.grid(row=0, column=0)

titletext=Label(root, text="NumberSpeller2")
titletext.grid(row=0, column=1)

filler2=Label(root, text=" ")
filler2.grid(row=0, column=2)

filler3=Label(root, text="\n")
filler3.grid(row=1, column=0)

entrybox=Entry(root)
entrybox.grid(row=1, column=1, sticky=N)

enterbutton=Button(root, text="Spell!", command=collect)
enterbutton.grid(row=3, column=1, sticky=N)

filler4=Label(root, text="")
filler4.grid(row=4, column=1)

filler5=Label(root, text="")
filler5.grid(row=6, column=1)

website=Label(root, text="Visit the NS2 Website")
website.grid(row=7, column=1, sticky=S)

+-------------------------------------+----------------------------------------+

Like I explained a little before, I need to keep users from entering
any letters, and I need to have the numbers they typed in translated to
text.

Can someone explain how I could go across doing this?
You should get some clue about the number conversion (not to menion a
bunch of code you can lift :) from

http://www.python.org/pycon/dc2004/papers/42/ex1-C/num2eng.py

regards
Steve
 
P

Paul Rubin

MonkeeSage said:
If you need the actual names for like "Five Hundred and Sixty Seven", I
think one of the smart people 'round here will have to help with that.
I have some ideas, but I'm not very good at creating complex
algorithms.

These kinds of things are generally most easily done with recursion.
================================================================

def spell(n):
# return n spelled out in words
if type(n) not in (int, long):
raise ValueError, n
if n == 0: return 'zero'
return zspell(n)

def zspell(n):
# return n (assumed integer) spelled out in words, with zero = empty string
if n < 0:
return 'minus ' + spell(-n)
elif n == 0:
return ''
elif n < 20:
return ('zero', 'one', 'two', 'three', 'four',
'five', 'six', 'seven', 'eight', 'nine',
'ten', 'eleven', 'twelve', 'thirteen', 'fourteen',
'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen')[n]
elif n < 100:
a,b = divmod(n, 10)
return '%s%s'% (('twenty', 'thirty', 'forty', 'fifty', 'sixty',
'seventy', 'eighty', 'ninety')[a-2],
((b > 0) and '-'+zspell(b)) or '')
elif n < 1000:
return '%s hundred %s'% (zspell(n // 100), zspell(n % 100))
elif n < 10**6:
return '%s thousand %s'% (zspell(n // 1000), zspell(n % 1000))
elif n < 10**66:
def xillion(n, d=0):
illions = ('m', 'b', 'tr', 'quadr', 'quint',
'sext', 'sept', 'oct', 'non', 'dec',
'undec', 'duodec', 'tredec', 'quattuordec', 'quinquadec',
'sextemdec', 'septemdec', 'octodec', 'novemdec', 'vigint')
if n == 0: return ''
elif n < 1000:
return '%s %s'% \
(zspell(n),
illions[d] + 'illion')
else:
return '%s %s'% (xillion(n // 1000, d+1),
xillion(n % 1000, d))
return '%s %s' % (xillion(n // 10**6), zspell(n % 10**6))
else:
# I can't count that high!
from math import log10
ch,m = divmod(log10(n), 1.0)
return '%fe%d'% (10.**m, int(ch))
 
F

flyingisfun1217

I guess I'm just looking for a small code sample hooked up to the code
I gave, that would collect the input, compare it to code such as:

if x==5
print "Five"
elif x==6
print "Six"
elif x==7
print "Seven"

Something along those lines. That was actually like the code I used for
something else a while ago.

My only problem is, I want it to be printed to a textvariable for use
in the label.

Thanks again for all your help!

Tanner
 
T

Tim Williams

I guess I'm just looking for a small code sample hooked up to the code
I gave, that would collect the input, compare it to code such as:

if x==5
print "Five"
elif x==6
print "Six"
elif x==7
print "Seven"

Something along those lines. That was actually like the code I used for
something else a while ago.

My only problem is, I want it to be printed to a textvariable for use
in the label.

You can replace the above snippet with:

my_nums = { 1 : 'One' , 2 : 'Two' , 3 : 'Three' , 4 : 'Four' } # etc etc
print my_nums[x]

so...
x = 2
print my_nums[x] 'Two'
x = 4
print my_nums[x]
'Four'

and my_nums[x] is a "variable" for you to use.

HTH :)
 
M

MonkeeSage

Tim said:
my_nums = { 1 : 'One' , 2 : 'Two' , 3 : 'Three' , 4 : 'Four' } # etc etc
print my_nums[x]

That's what I suggested, but since a list is already zero indexed I
used that rather than a dictionary. And Paul Rubin posted a very nice
solution that handles numbers larger than 9. I think the OP wants us to
write their GUI code for them or something...

Regards,
Jordan
 
P

Paul McGuire

Steve Holden said:
You should get some clue about the number conversion (not to menion a
bunch of code you can lift :) from

http://www.python.org/pycon/dc2004/papers/42/ex1-C/num2eng.py

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

.... and pyparsing has an example that goes from words back to numbers!
http://pyparsing.wikispaces.com/space/showimage/wordsToNum.py

-- Paul
 
P

Paul Rubin

Steve Holden said:
You should get some clue about the number conversion (not to menion a
bunch of code you can lift :) from

http://www.python.org/pycon/dc2004/papers/42/ex1-C/num2eng.py

For some reason I felt like writing another one, that doesn't use as
much recursion as the last one I posted. This one is more like
old-fashioned Python and is shorter, but took several refactorings
and was harder to debug:

def spell(n, d=0):
# spell arbitrary integer n, restricted to |n| < 10**66
assert abs(n) < 10**66
if n == 0: return 'zero'
if n < 0: return 'minus ' + spell(-n, d)

bigtab = ('thousand', 'million', 'billion', 'trillion',
'quadrillion', 'quintillion', 'sextillion', 'septillion',
'octillion', 'nonillion', 'decillion', 'undecillion',
'duodecillion', 'tredecillion', 'quattuordecillion',
'quinquadecillion', 'sextemdecillion', 'septemdecillion',
'octodecillion', 'novemdecillion', 'vigintillion')
smalltab = ('', 'one', 'two', 'three', 'four',
'five', 'six', 'seven', 'eight', 'nine',
'ten', 'eleven', 'twelve', 'thirteen', 'fourteen',
'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen')
out = []
def maybe(cond,s): return (cond and s) or ''

a,n = divmod(n, 1000)
if a:
out.extend((spell(a,d+1), maybe(a % 1000, bigtab[d])))

a,n = divmod(n, 100)
out.append(maybe(a, '%s hundred'% spell(a)))

a,b = divmod(n, 10)
if a > 1:
out.append(('twenty', 'thirty', 'forty', 'fifty', 'sixty',
'seventy', 'eighty', 'ninety')[a-2] +
maybe(b, '-' + smalltab))
else:
out.append(smalltab[n])
return (' '.join(filter(bool, out)))

# example
print spell(9**69)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top