473,406 Members | 2,217 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

check for dictionary keys

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....

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....

thanks.

Jun 3 '06 #1
5 1664
def all(s):
for x in s:
if not x: return False
return True
bad_combos = [['-A', '-B'], ['-A', '-C'], ...]
for bad_combo in bad_combos:
assert not all([bad_elem in a for bad_elem in bad_combo])

mi*******@hotmail.com wrote:
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....

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....

thanks.


Jun 3 '06 #2
mi*******@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.

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...
]

def validate(options, rules):
keys = options.keys()
for predicate, message in rules:
if not predicate(keys):
raise ValueError(message)
Jun 5 '06 #3
On 5/06/2006 10:46 PM, Bruno Desthuilliers wrote:
mi*******@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. Simple code can weed out redundant
rules, including any accidental duplicates that may creep into a long
list. See code listing at end.

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 :-)
def validate(options, rules):
keys = options.keys()
for predicate, message in rules:
if not predicate(keys):
raise ValueError(message)


Cheers,
John

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

option_rules = rule_compaction(bad_combos, verbose=True)

def combo_disallowed_by(opt_set, rules):
for rule in rules:
if opt_set >= rule:
return rule
return None # redundantly, for emphasis

if __name__ == "__main__":
import sys
for opt_string in sys.argv[1:]:
failer = combo_disallowed_by(set(opt_string), option_rules)
if failer:
print repr(opt_string), "disallowed by", failer
else:
print repr(opt_string), "is OK"

=== a test ===

C:\junk>option_combos.py A AB AC AD BC ABD ABX XBA BX
bc_sets #1: [set(['A', 'C']), set(['A', 'B']), set(['A', 'C']),
set(['A', 'B', 'D'])]
set(['A', 'B', 'D']) knocked out by set(['A', 'B'])
set(['A', 'C']) knocked out by set(['A', 'C'])
bc_sets #2: [set(['A', 'C']), set(['A', 'B'])]
'A' is OK
'AB' disallowed by set(['A', 'B'])
'AC' disallowed by set(['A', 'C'])
'AD' is OK
'BC' is OK
'ABD' disallowed by set(['A', 'B'])
'ABX' disallowed by set(['A', 'B'])
'XBA' disallowed by set(['A', 'B'])
'BX' is OK

=== the end ===
Jun 6 '06 #4
John Machin wrote:
On 5/06/2006 10:46 PM, Bruno Desthuilliers wrote:
mi*******@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 'o****@xiludom.gro'.split('@')])"
Jun 6 '06 #5
On 6/06/2006 8:38 PM, bruno at modulix wrote:
John Machin wrote:
On 5/06/2006 10:46 PM, Bruno Desthuilliers wrote:
mi*******@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>


<ot> You must have some interesting conversations with yourself !-) </ot>

Don't like table-driven programming, John ?
I love table-driven programming. You seem to misunderstand; In this case
the "bad combos" list *is* the table.

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).
[snip]
Nice code - but how does it handle more complex predicates ? Seems you
can only deal with 'and' rules here.
More complex predicates are not in the OP's spec ... this is a defence I
learned from somebody in this newsgroup recently :-)
<nitpick>"Doesn't scale well", you
said ?-)</nitpick>


I understand 'scale' to relate to size, not to complexity.

Cheers,
John
Jun 6 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: none | last post by:
or is it just me? I am having a problem with using a dictionary as an attribute of a class. This happens in python 1.5.2 and 2.2.2 which I am accessing through pythonwin builds 150 and 148...
57
by: Egor Bolonev | last post by:
why functions created with lambda forms cannot contain statements? how to get unnamed function with statements?
5
by: Rakesh | last post by:
Hi, For a particular problem of mine, I want to sort <key, value> pairs by its value. Eg: Input: A, 4 B, 5
4
by: Noah | last post by:
I have a dictionary that I would like to expand to satisfy a function's agument list. I can used the ** syntax to pass a dictionary, but this only works if each key in the dictionary matches an...
2
by: jg | last post by:
I was trying to get custom dictionary class that can store generic or string; So I started with the example given by the visual studio 2005 c# online help for simpledictionay object That seem...
90
by: Christoph Zwerschke | last post by:
Ok, the answer is easy: For historical reasons - built-in sets exist only since Python 2.4. Anyway, I was thinking about whether it would be possible and desirable to change the old behavior in...
14
by: vatamane | last post by:
This has been bothering me for a while. Just want to find out if it just me or perhaps others have thought of this too: Why shouldn't the keyset of a dictionary be represented as a set instead of a...
11
by: John | last post by:
I am coding a radix sort in python and I think that Python's dictionary may be a choice for bucket. The only problem is that dictionary is a mapping without order. But I just found that if the...
8
by: Bob Altman | last post by:
Hi all, I'm trying to do something that should be really easy, but I can't think of an obvious way to do it. I have a dictionary whose value is a "value type" (as opposed to a reference type --...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.