Incrementing a string

Andrew Dalke adalke at mindspring.com
Thu Sep 16 07:49:36 CEST 2004


Phil Frost wrote:
> import string
> 
> class LabelCounter(object):
>     digits = string.lowercase
   ....
>     # define other operators as needed; it's a shame this can't inherit from
>     # int and get these for free. It can't do this because all of int's
>     # operators return ints, not LabelCounters.

Try this instead.  As usual with clever solutions, you
probably shouldn't use this in real code.

import string

def fixup(klass):
   for name, meth in inspect.getmembers(klass):
     # Find all the methods except for a few special ones
     # we know won't return integers
     if (callable(meth) and name not in
         ["__class__", "__new__", "__init__", "__str__", "__repr__"]):

       # Need to make a wrapper function (g) for each of these methods.
       # The wrapper function needs to know the original method, which
       # is stored in the newly created scope (f).
       def f(meth = meth):
         def g(self, *args, **kwargs):
           retval = meth(self, *args, **kwargs)
           if isinstance(retval, int):
             return LabelCounter(retval)
           return retval
         return g
       g = f()
       setattr(klass, name, g)  # replace with the wrapped version

class LabelCounter(int):
   digits = string.ascii_lowercase
   def __str__(self):
     letters = []
     i = int(self)
     while i:
       d, m = divmod(i, len(self.digits))
       letters.append(self.digits[m])
       i = d
     return "".join(letters[::-1]) or self.digits[0]
   __repr__ = __str__


Here it is in use.

 >>> a = LabelCounter(4)
 >>> print a
e
 >>> print a+1
f
 >>> print a+10
o
 >>> print (a+10)/2
h
 >>> print a
e
 >>> print a/2
c
 >>> print a/3
b
 >>> print a/30
a
 >>> print a**4
jw
 >>>

> You can set 'digits' to any sequence at all. Set it to '01' to get
> output in binary, or to ['01','23','45','67','89'] to get base 5 in a
> very confusing notation *g*

I set it to ascii_lowercase since string.lowercase is locale
dependent.

 >>> import string, locale
 >>> string.lowercase
'abcdefghijklmnopqrstuvwxyz'
 >>> locale.setlocale(locale.LC_ALL, "de_DE")
'de_DE'
 >>> string.lowercase
'abcdefghijklmnopqrstuvwxyz\xaa\xb5\xba\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff'
 >>>

OTOH, that might be what you wanted ...

				Andrew
				dalke at dalkescientific.com



More information about the Python-list mailing list