Writing more efficient code

Paul McGuire ptmcg at austin.rr._bogus_.com
Mon Jan 1 19:43:32 EST 2007


"gonzlobo" <gonzlobo at gmail.com> wrote in message 
news:mailman.2185.1167676577.32031.python-list at python.org...
> Greetings, and happyNewYear to all.
>
> I picked up Python a few weeks ago, and have been able to parse large
> files and process data pretty easily, but I believe my code isn't too
> efficient. I'm hoping dictionaries will help out, but I'm not sure the
> best way to implement them.
>
> I've been using a bunch of nested if/elif/else statements to select
> slices (0317 & 03de) from a file, then parse the data (aa, hh, bb,
> d2-d9) into parameters (a = airspeed, h = heading) & flags.
>
> #sample file contents
> 0000007d 03 0317 aa aa aa aa aa hh hh hh bb bb
> 0000007e 06 03de d2 d3 d4 d5 d6 d7 d8 d9 10 11
>
> # some pseudo code
> if PID == '03de':
>    flapsCmd = int(d3, 16)
>   if flapsCmd == 0xc0:
>      <flaps up code>
>   elif flapsCmd == 0x03:
>      <flaps down code>
> if PID == '0317':
>   airspeed == 'combine aa for airspeed & multiply by 0.1'
>   heading == 'combine hh for heading'
>   mach == 'combine bb for mach & multiply by 0.01'
>
> Might dictionaries help in this case... say Label0317(parameterName,
> slice (d3), scaleFactor(0.1))... I'd like to use them if they'll
> replace the dozens of nested conditionals.  I have roughly 75
> different parameters to decode from a file containing ~2.5 million
> lines of data.
>
> I know my pseudo code lacks details, but hopefully I'm getting my
> point across...
>
> (I suppose switch/select/case statements would help a bit, but python
> doesn't seem to use them... not to start a religious war or anything).
>
> Any help (or encouragement) is appreciated.

First, your data is so regularly formatted, I suspect you are using the 
split() method of string to get at the pieces.  Good, this keeps things 
simple.

It *would* help if you posted actual data lines, instead of aa's, and bb's. 
So I took a guess that these were hex representations of characters 
representing decimal numbers.

Instead of switch/case, I selected a dict that creates a dispatch table, 
selecting one of several object classes whose __init__ constructors are 
written to pick apart the relevant fields from the 10-element list following 
the 4-digit selection code.  I then just created an object dumping method to 
show what objects were created from what lines of data, and perhaps you can 
take it from there.

-- Paul


test = """\
0000007d 03 0317 30 33 32 38 38 32 37 35 34 31
0000007e 06 03de af c0 fe d5 d6 d7 d8 d9 10 11
0000007e 06 junk af c0 fe d5 d6 d7 d8 d9 10 11
0000007f 06 03de af 03 fe d5 d6 d7 d8 d9 10 11"""

hex2int = lambda hh : int(hh,16)
class AirspeedHeadingMach(object):
    def __init__(self,datalist):
        self.airspeed = int("".join(map(chr,map(hex2int,datalist[:5]))))*0.1
        self.heading = "".join(map(chr,map(hex2int,datalist[5:8])))
        self.mach = int("".join(map(chr,map(hex2int,datalist[8:]))))*0.01

UP,DOWN = 0,1
class FlapsStatus(object):
    def __init__(self,datalist):
        self.flaps = { 0xc0:UP, 0x03:DOWN } [ int(datalist[1],16) ]

class UnknownRec(object):
    def __init__(self,code,datalist):
        self.code = code
        self.datalist = datalist[:]

def dump(o):
    print o.__class__.__name__
    print o.__dict__
    print

recCodeTypeMap = {
    '0317' : AirspeedHeadingMach,
    '03de' : FlapsStatus,
    }
for line in test.split("\n"):
    toks = line.split()
    code = toks[2]
    datalist = toks[3:]
    if code in recCodeTypeMap:
        dataObject = recCodeTypeMap[code](datalist)
    else:
        dataObject = UnknownRec(code,datalist)
    dump(dataObject)

Prints:
AirspeedHeadingMach
{'mach': 0.41000000000000003, 'airspeed': 328.80000000000001, 'heading': 
'275'}

FlapsStatus
{'flaps': 0}

UnknownRec
{'datalist': ['af', 'c0', 'fe', 'd5', 'd6', 'd7', 'd8', 'd9', '10', '11'], 
'code': 'junk'}

FlapsStatus
{'flaps': 1}







More information about the Python-list mailing list