[Tutor] Thanks, you prevented "Coder's Remorse"

Ron Phillips RPhillips at engineer.co.summit.oh.us
Mon Oct 3 16:17:10 CEST 2005


Thanks to everyone who responded to my "Prevent Coder's Remorse"
posting;
the result of combining the ideas that you contributed is below. 

It's a little long, but I'm delighted with it so far, and maybe someone
else can use it. 
It's nice for representing a sparse table, where all the records share
columns, 
but a lot of the values in any given column are the same. Geographic
points (my original
question) are just a special case.

One example is a table where the Null value isn't predefined but is
represented by a
'magic value' that means null in that table. I realize now that I might
have been
better off just to use a database; they know all about nulls, tables.
types, defaults, etc. 

Still, I learned a LOT.  So, no remorse!

Thanks again,
 
Ron

#magicvaluetable.py
###################################
# -*- coding: utf-8 -*-

#may use a guid to keep things straight
import guid

# Make it work with Python 2.3
try:
    set
except NameError:
    from sets import Set as set

class MVTRecord(dict):
    """A record belonging to a magic value table (MVTable).
    Requires a parent MVTable and an id assigned by it.
    Other attributes (column values) may be assigned.
    Attributes not specifically assigned at the record level
    are deferred to the parent MVTable's attDict."""
    
    def __init__(self,mvtParent,id,**args):
        dict.__init__(self)
        self.mvtParent = mvtParent
        self.id = id
        for arg in args:
            self[arg]=args[arg]

    def __getitem__(self, key):
        if key in self.keys():
            return dict.__getitem__(self, key)
        else: 
            return self.mvtParent.attDict[key]
        raise KeyError,'Key "%s" was not found in MVTRecord or
MVTable'%key

    def __setitem__(self, key, value):
        (nullValue,valueType)=self.__testType(value)
        if key not in self.mvtParent.attDict.keys():
            self.mvtParent.addAttribute(key,nullValue)
       
(whoCares,columnType)=self.__testType(self.mvtParent.attDict[key])
         # make sure what's set is proper type or can degrade to proper
type
        if valueType == columnType:
            dict.__setitem__(self, key, value)
        else:
            if columnType == 'float'and valueType=='int':
                dict.__setitem__(self, key, float(value))
            elif columnType == 'string':
                dict.__setitem__(self, key, str(value))
            else:
                msg = 'The %s attribute requires %s data'%(key,
columnType)
                raise ValueError,msg
        
    def __delitem__(self, key):
        if key in self.keys():
            dict.__delitem__(self, key)
        elif key in self.mvtParent.attDict.keys():
            pass
        else:
            raise KeyError,'Key "%s" was not found in MVTRecord or
MVTable'%key
            

    def __testType(self, value):
        try:
            if str(value)==str(int(value)):
                test = (self.mvtParent.nullInt,'int')
            else: 
                test = (self.mvtParent.nullFloat,'float')
        except ValueError:
            test=(self.mvtParent.nullString,'string')
        return test


class MVTable(object):
    """Defines a group of records (MVTRecord) with
    common columns. Attributes (record values in a given
    column) which are not specified at the record level are
    deferred to the MVTable attDict.
    
    Note: the nullInt, nullFloat, and nullString
    are designed to hold 'magic values' for use with
    data structures(CSV, DBF) having no defined 'null'."""
    def __init__(self, nullInt=0, nullFloat=0.0, nullString='null'):
        self.nullInt=nullInt
        self.nullFloat = nullFloat
        self.nullString = nullString
        self.attDict = {}
        self.membersDict = {}

    def addMember(self,id=None,**args):
        if not id: id = guid.generate()
        self.membersDict[id]=MVTRecord(self,id=id,**args)
        return self.membersDict[id]

    def delMember(self,member):
        del self.membersDict[member.id]

    def addAttribute(self, name, nullValue=None):
        if nullValue == None:nullValue=self.nullString
        self.attDict[name]=nullValue
        
    def delAttribute(self, name):
        for member in self.membersDict:
            if member.has_key(name):del member[name]
        del self.attDict[name]            
       
    def compactAttributesDictionary(self):
        """removes unreferenced attributes"""
        newkeys = set()
        for member in self.membersDict:
            for key in self.membersDict[member].keys():
                newkeys.add(key)
        for key in self.attDict.keys():
            if key not in newkeys: del self.attDict[key]
            
if __name__ == "__main__":
    mvt = MVTable()
    me=mvt.addMember()
    he=mvt.addMember(third=3, fourth=4)
    mvt.addAttribute('first', 5)
    #print basic functionality outputs
    for column in mvt.attDict:
        print 'Column:%s, me:%s, he:%s'%(column,me[column],he[column])

###########################


More information about the Tutor mailing list