Dictionaries -- ahh the fun.. (newbie help)

R

rh0dium

Hi all,

Can someone help me out. I am trying to determing for each run whether
or not the test should pass or fail but I can't seem to access the
results ..

Alternatively can someone suggest a better structure ( and a lesson as
to the reasoning ) that would be great too!!

cells={}

cells["NOR3X1"]= {
'run' : [ 'lvs', 'drc' ],
'results' : [{ 'lvs' : 'pass' },
{ 'drc' : 'fail' }]
}

cells["OR3X1"] = {
'run' : [ 'lvs' ],
'results' : [{ 'lvs' : 'pass' }]
}

cells["AND3X1"] = {
'run' : [ 'drc' ],
'results' : [{ 'drc' : 'fail' }]
}


def main():

for cell in cells:
print cell
for run in cells[cell]['run']:
print cell, run, "should",
cells[cell]['results'].index(run)


I would expect the following

OR3X1
OR3X1 lvs should pass
NOR3X1
NOR3X1 lvs should pass
NOR3X1 drc should fail
AND3X1
AND3X1 drc should fail
 
J

James Stroud

rh0dium said:
Hi all,

Can someone help me out. I am trying to determing for each run whether
or not the test should pass or fail but I can't seem to access the
results ..

Alternatively can someone suggest a better structure ( and a lesson as
to the reasoning ) that would be great too!!

cells={}

cells["NOR3X1"]= {
'run' : [ 'lvs', 'drc' ],
'results' : [{ 'lvs' : 'pass' },
{ 'drc' : 'fail' }]
}

cells["OR3X1"] = {
'run' : [ 'lvs' ],
'results' : [{ 'lvs' : 'pass' }]
}

cells["AND3X1"] = {
'run' : [ 'drc' ],
'results' : [{ 'drc' : 'fail' }]
}


def main():

for cell in cells:
print cell
for run in cells[cell]['run']:
print cell, run, "should",
cells[cell]['results'].index(run)


I would expect the following

OR3X1
OR3X1 lvs should pass
NOR3X1
NOR3X1 lvs should pass
NOR3X1 drc should fail
AND3X1
AND3X1 drc should fail

This might be better



cells["NOR3X1"]= {
'run' : [ 'lvs', 'drc' ],
'results' : { 'lvs' : 'pass', 'drc' : 'fail' }
}
# etc.
print cell, run, "should", cells[cell]['results'][run]

James


--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
 
?

=?ISO-8859-1?Q?BJ=F6rn_Lindqvist?=

Can someone help me out. I am trying to determing for each run whether
or not the test should pass or fail but I can't seem to access the
results ..

Alternatively can someone suggest a better structure ( and a lesson as
to the reasoning ) that would be great too!!

Flat is better than nested. Pretend you write one billion cells in
your cells dict. To save disk space and memory (and make code
readable!) you wan't to make your structure as optimal as possible.

[snip]
cells["NOR3X1"]= {
'run' : [ 'lvs', 'drc' ],
'results' : [{ 'lvs' : 'pass' },
{ 'drc' : 'fail' }]
} [snip]
def main():

for cell in cells:
print cell
for run in cells[cell]['run']:
print cell, run, "should",
cells[cell]['results'].index(run)

That is good code and AFAICT it should work as you have described.
Just replace cells[cell]['results'].index(run) with
cells[cell]['results'][run]

However, notice how you have defined each cell:
cells["NOR3X1"]= {
'run' : [ 'lvs', 'drc' ],
'results' : [{ 'lvs' : 'pass' },
{ 'drc' : 'fail' }]
}

Here you have repetition, you are writing the string lvs and drc
twice. Imagine you have hundreds of these in each cell, wouldn't it be
annoying to have to type so much redundant data. So you optimize the
structure:

cells["NOR3X1"] = {'run' : [('lvs', 'pass'), ('drc', 'fail')]}

Your code for printing the results become:

for cell, d in cells.items():
print cell
for testname, testresult in d['run']:
print cell, testname, 'should', testresult

for cell, d in cells.items() runs through all the key-value pairs in
the dict. cell becomes "NOR3X1" (the key) and d becomes {'run' :
[('lvs', 'pass'), ('drc', 'fail')]} (the value) for one loop for
example. for testname, testresult in d['run'] runs through all items
in the list d['run'] and "unpacks" them. testname becomes 'lvs' and
testresult 'pass' for one loop for example.

The next step in this refactoring is realizing that all items in the
cell dict are a dict with just one element. I.e: {'run' : ('drc',
'fail')} for the 'AND3X1' item. So you can optimize your structure
another step:

cells["NOR3X1"] = [('lvs', 'pass'), ('drc', 'fail')]

Here, we have just removed the subdict. Dicts with just one item are
rarely useful so we replace the dict with its sole item. This I think
is the optimal structure for your example, because it contains no
needless repetition. The following is your original example using the
reworked cells structure.

P = 'pass'
F = 'fail'
cells['NOR3X1'] = [('lvs', P), ('drc', F)]
cells['OR3X1'] = [('lvs', P')]
cells['AND3X1] = [('drc', F)]

for cellname, celltests in cells.items():
print cellname
for testname, restresult in celltests:
print cellname, testname, 'should', testresult

As you can see I have replaced the 'pass' and 'fail' strings with the
variables P and F. Sometimes that is a useful technique because it
reduces repetitive typing. You are also less likely misspell things
like 'flai' instead of 'fail'. One golden rule of programming is that
you should never write the same thing twice. Ofcourse that is very
hard to achieve in practice, but the stronger you get the less often
you do it. If you can spot that you have written something twice or
more times in your code, then you have also spotted what is wrong with
your code.
 
S

Scott David Daniels

rh0dium said:
Hi all,

Can someone help me out. I am trying to determing for each run whether
or not the test should pass or fail but I can't seem to access the
results ..

Alternatively can someone suggest a better structure ( and a lesson as
to the reasoning ) that would be great too!!

Here's a little less convoluted version:

cells = dict(NOR3X1=dict(lvs='pass', drc='fail'),
OR3X=dict(lvs='pass'),
AND3X1=dict(drc='fail'))

for cell in cells:
print cell
for run, expect in cells[cell].items():
print cell, run, "should", expect

Or even:

for cell, expectations in cells.items():
print cell
for run, expect in expectations.items():
print cell, run, "should", expect

You might prefer .iteritems rather than .items if the lists get huge.

* I use the dict(name=val [, name=val)*) form if the keys are symbols.
* Don't get any more indirect than you need to.
* A list of single-entry dictionaries is almost never a good idea;
if you mean a list of pairs, use that. if you mean a dictionary
with a number of keys, use that.
 
B

Bruno Desthuilliers

rh0dium a écrit :
Hi all,

Can someone help me out. I am trying to determing for each run whether
or not the test should pass or fail but I can't seem to access the
results ..
(snip)
cells={}

cells["NOR3X1"]= {
'run' : [ 'lvs', 'drc' ],
'results' : [{ 'lvs' : 'pass' },
{ 'drc' : 'fail' }]
}

cells["OR3X1"] = {
'run' : [ 'lvs' ],
'results' : [{ 'lvs' : 'pass' }]
}

cells["AND3X1"] = {
'run' : [ 'drc' ],
'results' : [{ 'drc' : 'fail' }]
}


def main():

for cell in cells:
print cell
for run in cells[cell]['run']:
print cell, run, "should",
cells[cell]['results'].index(run)


I would expect the following

OR3X1
OR3X1 lvs should pass
NOR3X1
NOR3X1 lvs should pass
NOR3X1 drc should fail
AND3X1
AND3X1 drc should fail

Congratulations, almost a perfect post - you just forgot to tell the
actual result !-)
OR3X1
OR3X1 lvs should
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/usr/tmp/python-99973O0", line 24, in main
ValueError: list.index(x): x not in list

May I suggest that you type "help(list.index)" in your python shell ?
> Alternatively can someone suggest a better structure ( and a lesson as
> to the reasoning ) that would be great too!!

What seems flawed is the cell['results'] : you use a list of dicts, each
one having a single entry - which is somewhat useless. Since you want to
use the values of cell['run'] to lookup the expected results, using a
single dict for results makes things a bit more usable:

cells={}
cells["NOR3X1"]= {
'run' : [ 'lvs', 'drc' ],
'results' : {'lvs' : 'pass',
'drc' : 'fail' }
}
cells["OR3X1"] = {
'run' : [ 'lvs' ],
'results' : { 'lvs' : 'pass' }
}
cells["AND3X1"] = {
'run' : [ 'drc' ],
'results' : { 'drc' : 'fail' }
}

def main():
for cellname, cellcontent in cells.items():
print cellname
for run in cellcontent['run']:
print cellname, run, "should", cellcontent['results'][run]


This runs and produces the expected output. Now let's simplify. The
values of cell['run'] are uselessly duplicated as keys in
cell['results'] - and duplication is Bad(tm). So let's get rid of this:

cells={}
cells["NOR3X1"]= {
'results' : {'lvs' : 'pass',
'drc' : 'fail' }
}
cells["OR3X1"] = {
'results' : { 'lvs' : 'pass' }
}
cells["AND3X1"] = {
'results' : { 'drc' : 'fail' }
}


Now we only have a single entry ('results') for each cell. This is a
useless indirection level, so let's get rid of this too:

cells={
"NOR3X1": {
'lvs' : 'pass',
'drc' : 'fail',
},

"OR3X1" : {
'lvs' : 'pass',
},

"AND3X1" : {
'drc' : 'fail',
},
}

Looks simpler, isn't it ?-)

def main():
for cellname, cellcontent in cells.items():
print cellname
for run, result in cellcontent.items():
print cellname, run, "should", result

If you want to get the equivalent of cells[XXX]['runs'], just use
cells[XXX].keys().

HTH
 
G

Gerard Flanagan

rh0dium said:
Hi all,

Can someone help me out. I am trying to determing for each run whether
or not the test should pass or fail but I can't seem to access the
results ..

Alternatively can someone suggest a better structure ( and a lesson as
to the reasoning ) that would be great too!!

cells={}

cells["NOR3X1"]= {
'run' : [ 'lvs', 'drc' ],
'results' : [{ 'lvs' : 'pass' },
{ 'drc' : 'fail' }]
}

cells["OR3X1"] = {
'run' : [ 'lvs' ],
'results' : [{ 'lvs' : 'pass' }]
}

cells["AND3X1"] = {
'run' : [ 'drc' ],
'results' : [{ 'drc' : 'fail' }]
}

other suggestions:

cells={
"NOR3X1": {
'pass' : ['lvs'],
'fail' : ['drc']
},

"OR3X1" : {
'pass' : ['lvs'],
'fail' : []
},

"AND3X1" : {
'pass' : [],
'fail' : ['drc']
}

}

cells2={
"NOR3X1": [ ('lvs',1), ('drc', 0) ],

"OR3X1" : [ ('lvs', 1) ],

"AND3X1" : [ ('drc',0) ]
}

class cell(object):
def __init__(self, id, passes=None, fails=None):
self.id = id
self.passes = passes or []
self.fails = fails or []

Gerard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,294
Messages
2,571,511
Members
48,213
Latest member
DonnellTol

Latest Threads

Top