KirbyBase : replacing string exceptions

Brendan brendandetracey at yahoo.com
Mon Nov 23 18:05:48 CET 2009


On Nov 23, 12:21 pm, Steve Howell <showel... at yahoo.com> wrote:
> On Nov 23, 7:22 am, Brendan <brendandetra... at yahoo.com> wrote:
>
> > In KirbyBase there is a method that uses string exceptions for
> > control, even though it has a defined exception. Is there any reason
> > the string exceptions below could not be replaced?
> > i.e. in code below replace:
> > raise "No Match"
> > with:
> > raise KBError()
> > and
> > except 'No Match':
> > with:
> > except KBError:
>
> It looks like in some cases KBError() should fall through and only 'No
> Match' was intended to be silently caught.
>
> I would consider either leaving it alone if it works, or doing more
> serious surgery on the code to simplify the control flow.  The method
> is awfully long and nested.
>
>
>
> > I have pasted the relevant method and the class definition of KBError
> > below
>
> > #----------------------------------------------------------------------
> >     # _getMatches
>
> > #----------------------------------------------------------------------
> >     def _getMatches(self, fptr, fields, patterns, useRegExp):
> >         # Initialize a list to hold all records that match the search
> >         # criteria.
> >         match_list = []
>
> >         # If one of the fields to search on is 'recno', which is the
> >         # table's primary key, then search just on that field and
> > return
> >         # at most one record.
> >         if 'recno' in fields:
> >             return self._getMatchByRecno(fptr,patterns)
> >         # Otherwise, search table, using all search fields and
> > patterns
> >         # specified in arguments lists.
> >         else:
> >             new_patterns = []
> >             fieldNrs = [self.field_names.index(x) for x in fields]
> >             for fieldPos, pattern in zip(fieldNrs, patterns):
> >                 if self.field_types[fieldPos] == str:
> >                     # If useRegExp is True, compile the pattern to a
> >                     # regular expression object and add it to the
> >                     # new_patterns list.  Otherwise,  just add it to
> >                     # the new_patterns list.  This will be used below
> >                     # when matching table records against the
> > patterns.
> >                     if useRegExp:
> >                         new_patterns.append(re.compile(pattern))
> >                         # the pattern can be a tuple with re flags
> > like re.I
> >                     else:
> >                         new_patterns.append(pattern)
> >                 elif self.field_types[fieldPos] == bool:
> >                     # If type is boolean, I am going to coerce it to
> > be
> >                     # either True or False by applying bool to it.
> > This
> >                     # is because it could be '' or [].  Next, I am
> > going
> >                     # to convert it to the string representation:
> > either
> >                     # 'True' or 'False'.  The reason I do this is
> > because
> >                     # that is how it is stored in each record of the
> > table
> >                     # and it is a lot faster to change this one value
> > from
> >                     # boolean to string than to change possibly
> > thousands
> >                     # of table values from string to boolean.  And, if
> > they
> >                     # both are either 'True' or 'False' I can still
> >                     # compare them using the equality test and get the
> > same
> >                     # result as if they were both booleans.
> >                     new_patterns.append(str(bool(pattern)))
> >                 else:
> >                     # If type is int, float, date, or datetime, this
> > next
> >                     # bit of code will split the the comparison string
> >                     # into the string representing the comparison
> >                     # operator (i.e. ">=" and the actual value we are
> > going
> >                     # to compare the table records against from the
> > input
> >                     # pattern, (i.e. "5").  So, for example, ">5"
> > would be
> >                     # split into ">" and "5".
> >                     r = re.search('[\s]*[\+-]?\d', pattern)
> >                     if self.field_types[fieldPos] == int:
> >                         patternValue = int(pattern[r.start():])
> >                     elif self.field_types[fieldPos] == float:
> >                         patternValue = float(pattern[r.start():])
> >                     else:
> >                         patternValue = pattern[r.start():]
> >                     new_patterns.append(
> >                      [self.cmpFuncs[pattern[:r.start()]],
> > patternValue]
> >                     )
>
> >             fieldPos_new_patterns = zip(fieldNrs, new_patterns)
> >             maxfield = max(fieldNrs)+1
>
> >             # Record current position in table. Then read first detail
> >             # record.
> >             fpos = fptr.tell()
> >             line = fptr.readline()
>
> >             # Loop through entire table.
> >             while line:
> >                 # Strip off newline character and any trailing spaces.
> >                 line = line[:-1].strip()
> >                 try:
> >                     # If blank line, skip this record.
> >                     if line == "": raise 'No Match'
> >                     # Split the line up into fields.
> >                     record = line.split("|", maxfield)
>
> >                     # Foreach correspond field and pattern, check to
> > see
> >                     # if the table record's field matches
> > successfully.
> >                     for fieldPos, pattern in fieldPos_new_patterns:
> >                         # If the field type is string, it
> >                         # must be an exact match or a regular
> > expression,
> >                         # so we will compare the table record's field
> > to it
> >                         # using either '==' or the regular expression
> >                         # engine.  Since it is a string field, we will
> > need
> >                         # to run it through the unencodeString
> > function to
> >                         # change any special characters back to their
> >                         # original values.
> >                         if self.field_types[fieldPos] == str:
> >                             try:
> >                                 if useRegExp:
> >                                     if not pattern.search(
> >                                      self._unencodeString(record
> > [fieldPos])
> >                                      ):
> >                                         raise 'No Match'
> >                                 else:
> >                                     if record[fieldPos] != pattern:
> >                                         raise 'No Match'
> >                             except Exception:
> >                                 raise KBError(
> >                                  'Invalid match expression for %s'
> >                                  % self.field_names[fieldPos])
> >                         # If the field type is boolean, then I will
> > simply
> >                         # do an equality comparison.  See comments
> > above
> >                         # about why I am actually doing a string
> > compare
> >                         # here rather than a boolean compare.
> >                         elif self.field_types[fieldPos] == bool:
> >                             if record[fieldPos] != pattern:
> >                                 raise 'No Match'
> >                         # If it is not a string or a boolean, then it
> > must
> >                         # be a number or a date.
> >                         else:
> >                             # Convert the table's field value, which
> > is a
> >                             # string, back into it's native type so
> > that
> >                             # we can do the comparison.
> >                             if record[fieldPos] == '':
> >                                 tableValue = None
> >                             elif self.field_types[fieldPos] == int:
> >                                 tableValue = int(record[fieldPos])
> >                             elif self.field_types[fieldPos] == float:
> >                                 tableValue = float(record[fieldPos])
> >                             # I don't convert datetime values from
> > strings
> >                             # back into their native types because it
> > is
> >                             # faster to just leave them as strings
> > and
> >                             # convert the comparison value that the
> > user
> >                             # supplied into a string.  Comparing the
> > two
> >                             # strings works out the same as comparing
> > two
> >                             # datetime values anyway.
> >                             elif self.field_types[fieldPos] in (
> >                            - Hide quoted text -
>
> - Show quoted text -...
>
> read more »

Okay. Thanks.



More information about the Python-list mailing list