A clean way to program an interface
rh0dium
steven.klass at gmail.com
Mon Jul 9 16:19:19 EDT 2007
On Jul 9, 9:59 am, Paul McGuire <p... at austin.rr.com> wrote:
> I believe the OP is talking about "interface" as in "hardware
> interface", using some form of serial communication. His example does
> not use pyserial, but it does refer to a "UnidenConnection" class,
> with parameters such as bitrate, port, etc. for what looks like serial
> communication.
Yes - You are correct UnidenConnection is nothing more than a pyserial
connection which handles all of the setup and returns (converting
strings to list objects etc).
> Some general comments:
>
> 1. Much of the OP's use of sys._getframe().f_code.co_name coincides
> with his naming of certain methods with the same name as the command
> to be sent down the serial line. "STS", "EPG", "PRG", "SIN", etc. are
> all 3-character command codes that get sent down the wire, along with
> the appropriate values for the particular command. While many of
> these routines have *some* code in common, only a few have their
> entire method body duplicated with one or more other methods.
> Refactoring a couple of these into code closures, you can get:
>
> @staticmethod
> def makeStatusCheckCommandFunction(cmd):
> def fn(self):
> return ( self.uniden.write(cmd)[0]=="OK" )
> return fn
> PRG = makeStatusCheckCommandFunction("PRG")
> EPG = makeStatusCheckCommandFunction("EPG")
>
> @staticmethod
> def makeCmdFunction(cmd,attrname):
> def fn(self):
> setattr(self, attrname, int(self.PRGWrite(cmd)[0]))
> return getattr(self,attrname)
> return fn
> SCT = makeCmdFunction("SCT","systems")
> SIH = makeCmdFunction("SIH","sih")
> SIT = makeCmdFunction("SIT","sit")
Hmm very interesting - I've never played with code closures. Very
cool - I need to learn me about these thingy's :)
> Now there is no sys._getframe().f_code.co_name legerdemain going on,
> the command strings are just passed along as the argument cmd, and the
> functions themselves are named the same for some level of self-
> documentation and/or convenience.
>
> For the remaining methods, I declare a local variable named cmd and
> assign to it the write mnemonic. Yes, I know it violates DRY ("Don't
> Repeat Yourself"), but it avoids the getframe() stuff and again, is at
> least a snippet of self-documentation.
>
> 2. This code for reading and unpacking all the non-blank values feels
> ugly:
>
> cmd = "SIF"
> if args is None:
> p=self.PRGWrite("%s,%s" % (cmd,idx))
> t={}
> t["site_type"],t["name"],t["quick_key"],t["hld"],t["lout"],\
> t["mod"],t["att"],t["cch"],t["apco"],t["threshold"],\
> t["rev_index"],t["fwd_index"],t["sys_index"],t["chn_head"],
> \
> t["chn_tail"],t["seq_no"],t["start_key"],t["latitude"],\
> t["longitude"],t["range"],t["gps_enable"],t["rsv"]=p
>
> delitems=[]
> for item in t:
> if t[item]=="": delitems.append(item)
> for x in delitems: del t[x]
>
> How about this instead?:
>
> cmd = "SIF"
> if args is None:
> p=self.PRGWrite("%s,%s" % (cmd,idx))
> names = "site_type name quick_key hld lout mod att cch "\
> "apco threshold rev_index fwd_index sys_index "\
> "chn_head chn_tail seq_no start_key latitude " \
> "longitude range gps_enable rsv".split()
>
> t = dict( k,v for k,v in zip(names,p) if v != "" )
This is absolutely the right way to do this - I totally like this -
Super!!
> HTH,
> -- Paul
Hey thanks a lot!!
More information about the Python-list
mailing list