Previous: , Up: Python   [Contents][Index]


5.6.3 Python Example

In this subsection we will show a simple database module written in Python. This module handles simple textual databases in the following format:

Now, let’s create a module for handling this format. First, we need to import Dico primitives (see Dico Python Primitives) and the ‘sys’ module. The latter is needed for output functions:

import dico
import sys

Then, a result class will be needed for match_word and define_word methods. It will contain the actual data in the variable ‘result’:

class DicoResult:
    # actual data.
    result = {}
    # number of comparisons.
    compcount = 0
    
    def __init__ (self, *argv):
        self.result = argv[0]
        if len (argv) == 2:
             self.compcount = argv[1]

    def count (self):
        return len (self.result)

    def output (self, n):
        pass

    def append (self, elt):
        self.result.append (elt)

The following two classes extend ‘DicoResult’ for use with ‘DEFINE’ and ‘MATCH’ operations. The define_word method will return an instance of the ‘DicoDefineResult’ class:

class DicoDefineResult (DicoResult):
    def output (self, n):
        print "%d. %s" % (n + 1, self.result[n])
        print "---------",

The match_word method will return an instance of the ‘MatchResult’ class:

class DicoMatchResult (DicoResult):
    def output (self, n):
        sys.stdout.softspace = 0
        print self.result[n],

Now, let’s define the dictionary class:

class DicoModule:
    # The dictionary converted to associative array.
    adict =  {}
    # The database name.
    dbname = ''
    # The name of the corresponding disk file.
    filename = ''
    # A sort information about the database.
    mod_descr = ''
    # A verbose description of the database is kept.
    # as an array of strings.
    mod_info = []
    # A list of source and destination languages:
    langlist = ()

The class constructor takes a single argument, defining the name of the database file:

    def __init__ (self, *argv):
        self.filename = argv[0]
        pass

The ‘open’ method opens the database and reads its data:

    def open (self, dbname):
        self.dbname = dbname
        file = open (self.filename, "r")
        for line in file:
            if line.startswith ('--'):
                continue
            if line.startswith ('descr: '):
                self.mod_descr = line[7:].strip (' \n')
                continue
            if line.startswith ('info: '):
                self.mod_info.append (line[6:].strip (' \n'))
                continue
            if line.startswith ('lang: '):
                s = line[6:].strip (' \n').split(':', 2)
                if (len(s) == 1):
                    self.langlist = (s[0].split (), \
                                     s[0].split ())
                else:
                    self.langlist = (s[0].split (), \
                                     s[1].split ())
                continue
            f = line.strip (' \n').split (' ', 1)
            if len (f) == 2:
                self.adict[f[0].lower()] = f[1].strip (' ')
        file.close()
        return True

The database is kept entirely in memory, so there is no need for ‘close’ method. However, it must be declared anyway:

    def close (self):
        return True

The methods returning database information are trivial:

    def descr (self):
        return self.mod_descr

    def info (self):
        return '\n'.join (self.mod_info)
    
    def lang (self):
        return self.langlist

The ‘define_word’ method checks if the search term is present in the dictionary, and, if so, converts it to the DicoDefineResult:

    def define_word (self, word):
        if self.adict.has_key (word):
            return DicoDefineResult ([self.adict[word]])
        return False

The ‘match_word’ method supports the ‘exact’ strategy natively via the has_key attribute of adict:

    def match_word (self, strat, key):
        if strat.name == "exact":
            if self.adict.has_key (key.word.lower ()):
                return DicoMatchResult \
                        ([self.adict[key.word.lower()]])

Other strategies are supported as long as they have selectors:

        elif strat.has_selector:
            res = DicoMatchResult ([], len (self.adict))
            for k in self.adict:
                if strat.select (k, key):
                    res.append (k)
            if res.count > 0:
                return res
        return False

The rest of methods rely on the result object to do the right thing:

    def output (self, rh, n):
        rh.output (n)
        return True

    def result_count (self, rh):
        return rh.count ()

    def compare_count (self, rh):
        return rh.compcount

Previous: Dico Python Primitives, Up: Python   [Contents][Index]