Flexable Collating (feedback please)

bearophileHUGS at lycos.com bearophileHUGS at lycos.com
Wed Oct 18 16:53:07 EDT 2006


This part of code uses integer "constants" to be or-ed (or added):

CAPS_FIRST = 1
NUMERICAL = 2
HYPHEN_AS_SPACE = 4
UNDERSCORE_AS_SPACE = 8
IGNORE_LEADING_WS = 16
COMMA_IN_NUMERALS = 32

...

def __init__(self, flag):
    self.flag = flag
def transform(self, s):
    """ Transform a string for collating.
    """
    if self.flag & CAPS_FIRST:
        s = s.swapcase()
    if self.flag & HYPHEN_AS_SPACE:
        s = s.replace('-', ' ')
    if self.flag & UNDERSCORE_AS_SPACE:
        s = s.replace('_', ' ')
    if self.flag & IGNORE_LEADING_WS:
        s = s.strip()
    if self.flag & NUMERICAL:
        if self.flag & COMMA_IN_NUMERALS:

This is used in C, but maybe for Python other solutions may be better.
I can see some different (untested) solutions:

1)

def selfassign(self, locals):
    # Code from web.py, modified.
    for key, value in locals.iteritems():
        if key != 'self':
            setattr(self, key, value)

def __init__(self,
             caps_first=False,
             hyphen_as_space=False,
             underscore_as_space=False,
             ignore_leading_ws=False,
             numerical=False,
             comma_in_numerals=False):
    selfassign(self, locals())

def transform(self, s):
    if self.caps_first:
        ...

Disadvangages: if a flag is added/modified, the code has to be modified
in two places.


2)

def __init__(self, **kwds):
    self.lflags = [k for k,v in kwds.items() if v]
def transform(self, s):
    if "caps_first" in self.lflags:
        ...

This class can be created with 1 instead of Trues, to shorten the code.

Disadvantages: the user of this class has to read from the class
doctring or from from the docs the list of possible flags (and such
docs can be out of sync from the code).


3)

Tkinter (Tcl) shows that sometimes strings are better than int
constants (like using "left" instead of tkinter.LEFT, etc), so this is
another possibile solution:

def __init__(self, flags=""):
    self.lflags = flags.lower().split()
def transform(self, s):
    if "caps_first" in self.lflags:
        ...

An example of calling this class:

... = Collate("caps_first  hyphen_as_space  numerical")

I like this third (nonstandard) solution enough.

Bye,
bearophile




More information about the Python-list mailing list