check for dictionary keys
bruno at modulix
onurb at xiludom.gro
Tue Jun 6 06:38:36 EDT 2006
John Machin wrote:
> On 5/06/2006 10:46 PM, Bruno Desthuilliers wrote:
>
>> micklee74 at hotmail.com a écrit :
>>
>>> hi
>>> in my code, i use dict(a) to make to "a" into a dictionary , "a" comes
>>> from user input, so my program does not know in the first place. Then
>>> say , it becomes
>>>
>>> a = { '-A' : 'value1' , '-B' : "value2" , "-C" : "value3" , '-D' :
>>> 'value4' }
>>>
>>> somewhere next in my code, i will check for these..:
>>>
>>> 1) -A and -B cannot exist together
>>> 2) -A and -C cannot exist together
>>> 3) -A and -B and -D cannot exist together
>>> 4) and lots of other combinations to check for....
>>
>>
>> Looks like an option parser... If so, there's all you need in the
>> standard lib (look for the optparse module).
>>
>>>
>>> how can i efficiently check for the above? At first as i do simple
>>> checks , i use if and else.
>>> But as i began to check for more combinatoiuns, it gets messy....
>>
>>
>> First : use boolean logic (truth table, Kernaugh diagram, etc) to
>> simplify things. As an example, rule #3 is useless - it's a subset of
>> rule #1 (-A and -B and -D implies -A and -B). This should greatly
>> reduce the number of needed tests.
>
>
> Good idea, but doesn't scale well.
Does it need to scale ? If there are lot of rules and frequently
changing, yes, automating the process will be a good idea - but if it's
about a program options, just using one's brain might be enough. At
least it forces one to think about what's going on...
> Simple code can weed out redundant
> rules,
Simple code can weed out redundant *simple* rules !-)
(snip)
>> Then, write a simple rule system describing either valid inputs or
>> invalid inputs (preferably the smallest set !-). FWIW, it can be as
>> simple as a list of lambdas/error messages pairs, with lambdas being
>> predicate taking dict keys as params:
>>
>>
>> _RULES = [
>> (lambda keys : '-A' in keys and '-B' in keys,
>> "can't have both options -A and -B"),
>> (lambda keys : '-A' in keys and '-C' in keys,
>> "can't have both options -A and -C"),
>> # etc...
>> ]
>>
>
> The evil HR director won't let the PHB pay me on a per LOC basis, so
> I've had to come up with a compact table-driven approach :-)
<ot>I'm my own evil HR director and PHB !-)</ot>
Don't like table-driven programming, John ?
This solution takes very few lines, and while it's surely not a
full-blown rule engine, it's at least reasonably flexible.
(Not to say it's better than yours - it's of course a matter of
effective use case).
>> def validate(options, rules):
>> keys = options.keys()
>> for predicate, message in rules:
>> if not predicate(keys):
>> raise ValueError(message)
>
>
>
> C:\junk>type option_combos.py
> bad_combos = ['ABD', 'AC', 'AB', 'CA']
>
> def rule_compaction(bc_list, verbose=False):
> # The next few lines are admittedly oldfashioned :-)
> bc_sets = [set(x) for x in bc_list]
> deco = [(len(y), y) for y in bc_sets]
> deco.sort()
> bc_sets = [z[1] for z in deco]
> del deco
> if verbose:
> print "bc_sets #1:", bc_sets
> for k in xrange(len(bc_sets)-1, 0, -1):
> candidate = bc_sets[k]
> for ko in bc_sets[:k]:
> if ko <= candidate:
> if verbose:
> print candidate, "knocked out by", ko
> del bc_sets[k]
> break
> if verbose:
> print "bc_sets #2:", bc_sets
> return bc_sets
>
Nice code - but how does it handle more complex predicates ? Seems you
can only deal with 'and' rules here. <nitpick>"Doesn't scale well", you
said ?-)</nitpick>
(snip)
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"
More information about the Python-list
mailing list