Get the number of letters in a number

jcao219 0 Tallied Votes 193 Views Share

This is not my code! Taken from this SO post.

You can use this to get the number of letters in the English representation of an integer, from 0 to 99.
So for example 5 (five) is len("five") which is 4.

len_of_num = lambda x: 3+int('1yrof7i9b1lsi207bozyzg2m7\
sclycst0zsczde5oks6zt8pedm\
nup5omwfx56b29',36)/10**x%10

for x in range(100):
    print "The length of the word for {0} is {1}.".format(x,
                                                         len_of_num(x))

Dani AI

Generated

Short summary: the compact, code‑golf trick pasted from StackOverflow is a neat way to get letter counts for 0..99 without writing a full parser. As observed, those packed-string solutions are brittle: they ignore hyphens/spaces, they assume a particular counting convention, and they don't scale past two digits.

Decide the counting rules first (these change the result): count only alphabetic characters (common), or include hyphens/spaces; use British "and" in numbers like "one hundred and one" or omit it (US style). Once the rule is fixed, a clear, maintainable approach is to build a small number-to-words generator (units, tens, hundreds, then group thousands/millions), then strip non-letters and take the length. That makes behavior explicit and easily extendable.

units = {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'}
tens = {20:'twenty',30:'thirty',40:'forty',50:'fifty',60:'sixty',70:'seventy',80:'eighty',90:'ninety'}

def _under_100(n):
    if n < 20: return units[n]
    t = (n//10)*10
    u = n%10
    return tens[t] + ('-' + units[u] if u else '')

def _under_1000(n, use_and=False):
    h, r = divmod(n, 100)
    if h:
        if r:
            sep = ' and ' if use_and else ' '
            return units[h] + ' hundred' + sep + _under_100(r)
        return units[h] + ' hundred'
    return _under_100(r)

def num_to_words(n, use_and=False):
    if n == 0: return 'zero'
    scales = ['', 'thousand', 'million', 'billion']
    parts, i = [], 0
    while n:
        chunk = n % 1000
        if chunk:
            w = _under_1000(chunk, use_and)
            parts.append(w + (' ' + scales[i] if scales[i] else ''))
        n //= 1000; i += 1
    return ' '.join(reversed(parts))

def letter_count(n, use_and=False):
    w = num_to_words(n, use_and)
    return sum(1 for c in w if c.isalpha())

Notes and tips: for bulk work precompute counts for 0..999 and compose larger numbers arithmetically to avoid repeated string building. If localization or very large numbers are needed, consider a tested library such as num2words. Clarify the hyphen/space/and rules upfront so results are reproducible.

TrustyTony 888 ex-Moderator Team Colleague Featured Poster

Seems to work until 20, then does not count dash in numbers like twenty-one, over 99 does not work.

Here my test and suggestion if you need number as string using more conventinal base than 36 (16)

from __future__ import print_function   ## let's practice Python 3 printing
import sys
sys.path.append('D:\test')  ## put here the location of the snippet
from intoeng import inttoeng ## replace with name of the file you saved integer to English snippet

def numberlength(x):
    try:
        return int('433544355436688779886aacbbaccb6aacbbaccb599baa9bba599baa9bba599baa9bba7bbdccbddc6aacbbaccb6aacbbaccb'[x],16)
    except IndexError:
        raise ValueError,'Number word length out of range 0..99'

##  string copied from run from:
##  res=''
##  for i in range(100):
##      res+=hex(len(inttoeng(i)))[-1]
##  print res


### from original post
len_of_num = lambda x: 3+int('1yrof7i9b1lsi207bozyzg2m7\
sclycst0zsczde5oks6zt8pedm\
nup5omwfx56b29',36)/10**x%10

for x in range(101): ## extended to see behaviour with wrong input
    # this is test of string, will of course match as the
    # inttoeng is source of information in string,
    # 100 will raise error from numberlength if next line uncommented
    len_of_num=numberlength 
    diff = len(inttoeng(x))-len_of_num(x)
    print("The length of the word for {0} is {1}".
          format(x,
                 len_of_num(x),
                 ),
          ", {0}, difference {1}".
          format(len(inttoeng(x)), diff) if diff
          else ' matching.'
    )
TrustyTony 888 ex-Moderator Team Colleague Featured Poster

Posted my version to SO link with original '-' does not count counts:

n=input();r='%i is '%n
while n-4:n=int('43354435543668877988699baa9bba699baa9bba588a998aa9588a998aa9588a998aa97aacbbaccb699baa9bba699baa9bba'[n],16);r+='%i.\n%i is '%(n,n)
print r+'magic.'
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.