switch

Tim Chase python.list at tim.thechases.com
Thu Dec 10 09:38:31 EST 2009


> Great example Tim.   This is something that many of us must be dealing
> with on a daily basis.  The problem has enough details (bar one), to
> allow an answer and not so detailed as to be confusing.  And for me
> it's a particularly good example, because your need accommodate
> mulitple provider formats makes me feel right at home.
>
>> which would nicely change into something like
>>
>>     switch row['recordtype']:
>>       case '01':
>>         phone.international += Decimal(row['internationalcost'])
>>         // optionally a "break" here depending on
>>         // C/C++/Java/PHP syntax vs. Pascal syntax which
>>         // doesn't have fall-through
>>       case '02':
>>         phone.text_messaging += (
>>           int(row['textmessages sent']) +
>>           int(row['pages received']) +
>>           int(row['textmessages sent']) +
>>           int(row['pages received'])
>>       ...
>>       default:
>>         raise WhatTheHeckIsThis()
>
> Cleaner yes.  But, with respect, not so clean as to justify the
> construct.  Following my advice you might express that switch
> statement like so:
>
>          phone.update_from_record(record)
>
> This switch statement belongs to one guy.  One guy who wants to know
> how to do everything that needs to be done to Phones no matter who
> asks

This is where you make a false assumption -- the contents and 
parsing of the "switch" are provider-specific in this case, 
mapping to a common ontology of the Phone object:

    class MonopolyProvider1Parser:
      ...
      switch row['recordtype']:
        case '01':
          phone.international += Decimal(row['internationalcost'])
          // optionally a "break" here depending on
          // C/C++/Java/PHP syntax vs. Pascal syntax which
          // doesn't have fall-through
        case '02':
          phone.text_messaging += (
            int(row['textmessages sent']) +
            int(row['pages received']) +
            int(row['textmessages sent']) +
            int(row['pages received'])
        ...
        default:
          raise WhatTheHeckIsThis()

    class MonopolyProvider2Parser:
      ...
      switch row['recordtype']:
        case 'abc':
          phone.international += (
            Decimal(row['canada cost']) +
            Decimal(row['eu cost']) +
            Decimal(row['mexico cost']) +
            Decimal(row['other intl cost'])
            )
        case 'xyz':
          phone.text_messaging += int(row['textmessages'])
        ...
        default:
          raise WhatTheHeckIsThis()

> # The one thing I'm sure I don't understand from the code is where the
> original rectypes comes into the process.

 From the provider data -- sometimes CSV files, sometimes 
tab-delimited text files, sometimes MS Access MDB files, 
sometimes a web service...varies per-provider (and some providers 
have multiple formats, like Verizon has MyBIZ and IBAS; ATT has 
their WinCD and Premier; etc).  No two formats are the same, so 
the logic needed to parse the data into our internal homogenized 
Phone data structure varies per each one.  And the logic (or lack 
thereof) used by many providers in creating their formats require 
reverse-engineering most of them through trial-and-error, and 
huge ugly if/elif/else chains.

> I wonder if you agree that it's bit cleaner now?  It's an effective
> solution. I'm making no representation that it's the best.

It's clean if it were the solution to my problem -- however, the 
mess comes from the profusion of provider formats.


> simple (and legible!) one liner.  A provider "enhances" their format,
> or a new provider format is added, code in one class, not in every
> switch they might be involved in.  But sorry, I don't mean to
> patronise, I'm sure you know the spiel.

Yes, having been programming since I was in middle-school (quick 
calculation yields a "boy I'm old" estimate of about 20 
years...does anybody miss 360k 5.25" floppy disks? :)  and have 
my degree in CS.  So it's not my lack of programming 
skill/knowledge, but rather your misunderstanding of the 
problem-space.  Not to patronize ;-)

-tkc







More information about the Python-list mailing list