Jim Qiu wrote:
Hi everyone,

Following is the code i am reading, i don't see anywhere the declaration of
Message.root object,
Where is it from?

#bots-modules
import bots.botslib as botslib
import bots.node as node
from bots.botsconfig import *


class Message(object):
    ''' abstract class; represents a edi message.
        is subclassed as outmessage or inmessage object.
    '''
    def __init__(self):
        self.recordnumber=0                #segment counter. Is not used for
UNT of SE record; some editypes want sequential recordnumbering

    @staticmethod
    def display(records):
        '''for debugging lexed records.'''
        for record in records:
            t = 0
            for veld in record:
                if t==0:
                    print '%s    (Record-id)'%(veld[VALUE])
                else:
                    if veld[SFIELD]:
                        print '        %s    (sub)'%(veld[VALUE])
                    else:
                        print '    %s    (veld)'%(veld[VALUE])
                t += 1

    def get(self,*mpaths):
        ''' query tree (self.root) with mpath; get value (string); get None
if not found.'''
        if self.root.record is None:
            raise botslib.MpathRootError('get("%s"): "root" of incoming
message is empty; either split messages or use inn.getloop'%(str(mpaths)))
        return self.root.get(*mpaths)

    def getnozero(self,*mpaths):
        ''' like get, returns None is value is zero (0) or not numeric.
            Is sometimes usefull in mapping.'''
        if self.root.record is None:
            raise botslib.MpathRootError('get("%s"): "root" of incoming
message is empty; either split messages or use inn.getloop'%(str(mpaths)))
        return self.root.getnozero(*mpaths)

    def getindicator(self,ind,*mpaths):
        ''' like get, returns None is value is zero (0) or not numeric.
            Is sometimes usefull in mapping.'''
        if self.root.record is None:
            raise botslib.MpathRootError('get("%s"): "root" of incoming
message is empty; either split messages or use inn.getloop'%(str(mpaths)))
        return self.root.getindicator(ind,*mpaths)

    def getcount(self):
        ''' count number of nodes in self.root. Number of nodes is number of
records.'''
        return self.root.getcount()

    def getcountoccurrences(self,*mpaths):
        ''' count number of nodes in self.root. Number of nodes is number of
records.'''
        count = 0
        for value in self.getloop(*mpaths):
            count += 1
        return count

    def getcountsum(self,*mpaths):
        ''' return the sum for all values found in mpath. Eg total number of
ordered quantities.'''
        if self.root.record is None:
            raise botslib.MpathRootError('get("%s"): "root" of incoming
message is empty; either split messages or use inn.getloop'%(str(mpaths)))
        return self.root.getcountsum(*mpaths)

    def getloop(self,*mpaths):
        ''' query tree with mpath; generates all the nodes. Is typically
used as: for record in inn.get(mpath):
        '''
        if self.root.record:    #self.root is a real root
            for terug in self.root.getloop(*mpaths): #search recursive for
rest of mpaths
                yield terug
        else:   #self.root is dummy root
            for childnode in self.root.children:
                for terug in childnode.getloop(*mpaths): #search recursive
for rest of mpaths
                    yield terug

    def put(self,*mpaths):
        if self.root.record is None and self.root.children:
            raise botslib.MpathRootError('put("%s"): "root" of outgoing
message is empty; use out.putloop'%(str(mpaths)))
        return self.root.put(*mpaths)

    def putloop(self,*mpaths):
        if not self.root.record:    #no input yet, and start with a
putloop(): dummy root
            if len(mpaths) == 1:
                self.root.append(node.Node(mpaths[0]))
                return self.root.children[-1]
            else: #TODO: what if self.root.record is None and len(mpaths) >
1?
                raise botslib.MpathRootError('putloop("%s"): mpath too
long???'%(str(mpaths)))
        return self.root.putloop(*mpaths)

    def sort(self,*mpaths):
        if self.root.record is None:
            raise botslib.MpathRootError('get("%s"): "root" of message is
empty; either split messages or use inn.getloop'%(str(mpaths)))
        self.root.sort(*mpaths)

    def normalisetree(self,node):
        ''' The node tree is check, sorted, fields are formated etc.
            Always use this method before writing output.
        '''
        #~ node.display()
        #~ print 'normalisetree'
        self._checktree(node,self.defmessage.structure[0])
        self._canonicaltree(node,self.defmessage.structure[0])

    def _checktree(self,tree,structure):
        ''' checks tree with table:
            -   all records should be in table at the right place in
hierarchy
            -   for each record, all fields should be in grammar
            This function checks the root of grammar-structure with root of
node tree
        '''
        if tree.record['BOTSID'] == structure[ID]:
            #check tree recursively with structure
            self._checktreecore(tree,structure)
        else:
            raise botslib.MessageError('(Root)record %s of %s not in table
%s'%(tree.record['BOTSID'],tree.record,self.defmessage.grammarname))

    def _checktreecore(self,node,structure):
        ''' recursive
        '''
        deletelist=[]
        self._checkfields(node.record,structure)
        if node.children and not LEVEL in structure:
            if self.ta_info['checkunknownentities']:
                raise botslib.MessageError('Record "%s" in message has
children, but structure of grammar "%s" not. Found gg
"%s".'%(node.record['BOTSID'],self.defmessage.grammarname,node.children[0].record['BOTSID']))
            node.children=[]
            return
        for childnode in node.children:          #for every node:
            for structure_record in structure[LEVEL]:           #search in
grammar-records
                if childnode.record['BOTSID'] == structure_record[ID]:   #if
found right structure_record
                    #check children recursive
                    self._checktreecore(childnode,structure_record)
                    break    #check next mpathnode
            else:   #checked all structure_record in grammar, but nothing
found
                if self.ta_info['checkunknownentities']:
                    raise botslib.MessageError('Record "%s" in message not
in structure of grammar "%s". Whole record:
"%s".'%(childnode.record['BOTSID'],self.defmessage.grammarname,childnode.record))
                deletelist.append(childnode)
        for child in deletelist:
            node.children.remove(child)


    def _checkfields(self,record,structure_record):
        ''' checks for every field in record if field exists in
structure_record (from grammar).
        '''
        deletelist=[]
        for field in record.keys():          #all fields in record should
exist in structure_record
            for grammarfield in structure_record[FIELDS]:
                if grammarfield[ISFIELD]:    #if field (no composite)
                    if field == grammarfield[ID]:
                        break
                else:   #if composite
                    for grammarsubfield in grammarfield[SUBFIELDS]:   #loop
subfields
                        if field == grammarsubfield[ID]:
                            break
                    else:
                        continue
                    break
            else:
                if self.ta_info['checkunknownentities']:
                    raise botslib.MessageError('Field "%s" does not exist in
record: %s'%(field,structure_record[MPATH]))
                    #~ raise botslib.MessageError('Field "%s" does not exist
in record: %s'%(field,structure_record[ID]))       #alt voor MPATH
                    #~ raise botslib.MessageError('Field "%s" does not exist
in record: %s'%(field,structure_record[FIELDS]))   #folder, text is too long
                deletelist.append(field)
        for field in deletelist:
            del record[field]

    def _canonicaltree(self,node,structure,headerrecordnumber=0):
        ''' For nodes: check min and max occurence; sort the nodes conform
grammar
            For fields: check M/C; format the fields.
        '''
        sortednodelist = []
        self._canonicalfields(node.record,structure,headerrecordnumber)
 #write the fields
        if LEVEL in structure:
            for structure_record in structure[LEVEL]:  #for structure_record
of this level in grammar
                count = 0                           #count number of
occurences of record
                for childnode in node.children:            #for every node
in mpathtree; SPEED: delete nodes from list when found
                    if childnode.record['BOTSID'] != structure_record[ID]:
#if it is not the right NODE":
                        continue
                    count += 1

 self._canonicaltree(childnode,structure_record,self.recordnumber)
#use rest of index in deeper level
                    sortednodelist.append(childnode)
                if structure_record[MIN] > count:
                    raise botslib.MessageError('Record "%s": mandatory but
not present.'%(structure_record[MPATH]))
                if structure_record[MAX] < count:
                    raise botslib.MessageError('Record "%s": occures to
often (%s times).'%(structure_record[MPATH],count))
            node.children=sortednodelist
            if hasattr(self,'do_queries'):
                self.do_queries(node,structure)

    def
_canonicalfields(self,noderecord,structure_record,headerrecordnumber):
        ''' For fields: check M/C; format the fields. Field are not sorted
here (a dict can not be sorted)
        '''
        #~ print noderecord
        for grammarfield in structure_record[FIELDS]:
            if grammarfield[ISFIELD]:    #if field (no composite)
                value = noderecord.get(grammarfield[ID],'')
                #~ print 'check field',grammarfield,value
                if not value:
                    if grammarfield[MANDATORY] == 'M':
                        raise botslib.MessageError('Record "%s": mandatory
field "%s" not filled.'%(structure_record[MPATH],grammarfield[ID]))
                    elif not grammarfield[MINLENGTH]:   #if minlength=0
                        continue
                noderecord[grammarfield[ID]] =
self._formatfield(value,grammarfield,structure_record)
            else:               #if composite
                compositefilled = False
                for grammarsubfield in grammarfield[SUBFIELDS]:   #loop
subfields to see if one of them is there
                    if noderecord.get(grammarsubfield[ID],''):
                        compositefilled = True
                if not compositefilled:
                    if grammarfield[MANDATORY]=='M':
                        raise botslib.MessageError('Record "%s": mandatory
composite "%s" not filled.'%(structure_record[MPATH],grammarfield[ID]))
                    continue
                for grammarsubfield in grammarfield[SUBFIELDS]:   #loop
subfields
                    value = noderecord.get(grammarsubfield[ID],'')
                    #~ print 'check subfield',grammarsubfield,value
                    if not value:
                        if grammarsubfield[MANDATORY]=='M':
                            #~ print 'Record "%s": mandatory subfield "%s"
not filled: "%s".'%(structure_record[MPATH],grammarsubfield[ID],noderecord)
                            raise botslib.MessageError('Record "%s":
mandatory subfield "%s" not filled:
"%s".'%(structure_record[MPATH],grammarsubfield[ID],noderecord))
                        else:
                            continue
                    noderecord[grammarsubfield[ID]] =
self._formatfield(value,grammarsubfield,structure_record)
                    #~ print 'fill',grammarfield[ID]

Thanks in advance.

Jim

Unlike your previous question, this attribute is not referenced in __init__(). That, plus the comment about being an abstract class, leads me to guess that the derived classes are required to define this attribute. That's one of the characteristics of an abstract class; some of the details are missing, and intended to be supplied by a child class.

What do the docs for this abstract class say? If they don't discuss how to implement a concrete class, they're sadly lacking.

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to