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
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
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
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))
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
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 :)
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
... and pyparsing has an example that goes from words back to numbers!
http://pyparsing.wikispaces.com/space/showimage/wordsToNum.py
-- Paul
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[b]))
else:
out.append(smalltab[n])
return (' '.join(filter(bool, out)))
# example
print spell(9**69)