strange dictionary definition/object instance problem

Reply

Join Date: May 2008
Posts: 6
Reputation: jmroach is an unknown quantity at this point 
Solved Threads: 0
jmroach jmroach is offline Offline
Newbie Poster

strange dictionary definition/object instance problem

 
0
  #1
May 13th, 2008
I am trying to add entries to a dictionary with the following loop:

  1. for p in pressures:
  2. q70in.resetKeyword( "expansionRatio", p )
  3. q70in.writeInput( prefix + tempInput )
  4. commands.getstatusoutput( runq70 )
  5. q70out = q70.Q70Output( prefix + outputFile )
  6. results[p] = {}
  7. #results[p]['Performance'] = q70out.performance
  8. results[p]['Conditions'] = q70out.conditions
  9. print q70out
  10. print results
  11. print ''

however, earlier entries of the dictionary are being 'overwritten' with new values as follows:

(here's the output from the code print statements)

<q70.Q70Output instance at 0x400cbccc>
{'2.0': {'Conditions': {'Vane2INLET': {'WG': '3.200'}, 'Blade1INLET': {'WG': '3.191'}, 'Blade2INLET': {'WG': '3.200'}, 'Vane1INLET': {'WG': '3.191'}}}}

<q70.Q70Output instance at 0x400cbccc>
{'2.0': {'Conditions': {'Vane2INLET': {'WG': '3.320'}, 'Blade1INLET': {'WG': '3.311'}, 'Blade2INLET': {'WG': '3.320'}, 'Vane1INLET': {'WG': '3.311'}}}, '3.0': {'Conditions': {'Vane2INLET': {'WG': '3.320'}, 'Blade1INLET': {'WG': '3.311'}, 'Blade2INLET': {'WG': '3.320'}, 'Vane1INLET': {'WG': '3.311'}}}}

<q70.Q70Output instance at 0x400cbccc>
{'2.0': {'Conditions': {'Vane2INLET': {'WG': '3.326'}, 'Blade1INLET': {'WG': '3.316'}, 'Blade2INLET': {'WG': '3.326'}, 'Vane1INLET': {'WG': '3.316'}}}, '3.5': {'Conditions': {'Vane2INLET': {'WG': '3.326'}, 'Blade1INLET': {'WG': '3.316'}, 'Blade2INLET': {'WG': '3.326'}, 'Vane1INLET': {'WG': '3.316'}}}, '3.0': {'Conditions': {'Vane2INLET': {'WG': '3.326'}, 'Blade1INLET': {'WG': '3.316'}, 'Blade2INLET': {'WG': '3.326'}, 'Vane1INLET': {'WG': '3.316'}}}}


So what's happening?

Note that #### in:

  1. results{ '2.0':{'Conditions':{'Vane2INLET':{'WG': ####}}}}

SHOULD NOT CHANGE WITH ITERATION based on the loop
Reply With Quote Quick reply to this message  
Join Date: Dec 2006
Posts: 1,008
Reputation: woooee is a jewel in the rough woooee is a jewel in the rough woooee is a jewel in the rough 
Solved Threads: 285
woooee woooee is offline Offline
Veteran Poster

Re: strange dictionary definition/object instance problem

 
0
  #2
May 13th, 2008
New entries are not being over-written. You are initializing to an empty dictionary with the statement results[p] = {}. Perhaps (and just perhaps) a dictionary of classes would serve better. Note that SQLite can also be used in memory, i.e you can store and lookup '2.0' + 'Conditions' + 'Vane2INLET', etc. or however you want to store it. Either would be less confusing IMHO.
  1. class Class1 :
  2. def __init__ (self) :
  3. self.field1 = ""
  4. self.field2 = 0
  5. self.field3 = "***"
  6.  
  7. #====================================================
  8. sample_dic = {}
  9. C = Class1()
  10. C.field1 = "Test1"
  11. C.field2 = 1
  12. C.field3 = "Test1A"
  13. sample_dic["test1"] = C
  14.  
  15. C = Class1()
  16. C.field1 = "Test2"
  17. C.field2 = 2
  18. C.field3 = "Test2A"
  19. sample_dic["test2"] = C
  20.  
  21. C = Class1()
  22. sample_dic["test3"] = C
  23.  
  24. ## note that dictionary keys are not in any order
  25. for key in sample_dic.keys() :
  26. print key, sample_dic[key].field1, sample_dic[key].field2, \
  27. sample_dic[key].field3
  28.  
  29. sample_dic["test3"].field2=3
  30. print "updated field2 =", sample_dic["test3"].field2
Last edited by woooee; May 13th, 2008 at 5:00 pm.
Reply With Quote Quick reply to this message  
Join Date: May 2008
Posts: 6
Reputation: jmroach is an unknown quantity at this point 
Solved Threads: 0
jmroach jmroach is offline Offline
Newbie Poster

Re: strange dictionary definition/object instance problem

 
0
  #3
May 13th, 2008
i'll definitely give the dictionary of classes a try, but i still think i might be missing something...

'results[p] = {}' should only initialize that key's value since every value of 'p' is unique. for example:

  1. dict = {}
  2. dict[0] = 0
  3. dict[1] = {}
  4. dict[2] = 2
  5. print dict

{0: 0, 1: {}, 2: 2}
Reply With Quote Quick reply to this message  
Join Date: Dec 2006
Posts: 1,008
Reputation: woooee is a jewel in the rough woooee is a jewel in the rough woooee is a jewel in the rough 
Solved Threads: 285
woooee woooee is offline Offline
Veteran Poster

Re: strange dictionary definition/object instance problem

 
0
  #4
May 13th, 2008
Originally Posted by jmroach View Post
i'll definitely give the dictionary of classes a try, but i still think i might be missing something...

'results[p] = {}' should only initialize that key's value since every value of 'p' is unique. for example:

  1. dict = {}
  2. dict[0] = 0
  3. dict[1] = {}
  4. dict[2] = 2
  5. print dict

{0: 0, 1: {}, 2: 2}
Either results[p] is unique or it's being overwritten/initialized to an empty dictionary. I don't know which it is without being able to see more data. Add a print statement so you can see what p is in every loop.
Last edited by woooee; May 13th, 2008 at 5:11 pm.
Reply With Quote Quick reply to this message  
Join Date: May 2008
Posts: 6
Reputation: jmroach is an unknown quantity at this point 
Solved Threads: 0
jmroach jmroach is offline Offline
Newbie Poster

Re: strange dictionary definition/object instance problem

 
0
  #5
May 13th, 2008
i just tried the dictionary of classes approach and it didn't work... I also added some more printing. Here's the snippet and output:

  1. for p in pressures:
  2. q70in.resetKeyword( "expansionRatio", float(p) )
  3. q70in.writeInput( prefix + tempInput )
  4. commands.getstatusoutput( runq70 )
  5. q70out = q70.Q70Output( prefix + outputFile )
  6. #results[p] = {}
  7. #results[p]['Performance'] = q70out.performance
  8. #results[p]['Conditions'] = q70out.conditions
  9. results[p] = indyResult()
  10. results[p].performance = q70out.performance
  11. results[p].conditions = q70out.conditions
  12. print type(p), len(p), p
  13. for i in results:
  14. print i
  15. print results[i].performance

<type 'str'> 3 2.0
2.0
{'Stage1': {'REAC-PS': '0.509', 'WR(T)/P': '4.3010', 'TT0': '1602.30', 'REAC-W': '0.515', 'W0': '3.191', '0WR(THCR)E/D': '2.8191', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.488', 'WR(T)/P': '6.0074', 'TT0': '1470.43', 'REAC-W': '0.500', 'W0': '3.200', '0WR(THCR)E/D': '3.9309', 'PT0': '20.4275'}}
<type 'str'> 3 3.0
2.0
{'Stage1': {'REAC-PS': '0.524', 'WR(T)/P': '4.4623', 'TT0': '1602.30', 'REAC-W': '0.560', 'W0': '3.311', '0WR(THCR)E/D': '2.9243', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.579', 'WR(T)/P': '6.6682', 'TT0': '1444.78', 'REAC-W': '0.700', 'W0': '3.320', '0WR(THCR)E/D': '4.3593', 'PT0': '18.9262'}}
3.0
{'Stage1': {'REAC-PS': '0.524', 'WR(T)/P': '4.4623', 'TT0': '1602.30', 'REAC-W': '0.560', 'W0': '3.311', '0WR(THCR)E/D': '2.9243', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.579', 'WR(T)/P': '6.6682', 'TT0': '1444.78', 'REAC-W': '0.700', 'W0': '3.320', '0WR(THCR)E/D': '4.3593', 'PT0': '18.9262'}}
<type 'str'> 3 3.5
2.0
{'Stage1': {'REAC-PS': '0.525', 'WR(T)/P': '4.4695', 'TT0': '1602.30', 'REAC-W': '0.563', 'W0': '3.316', '0WR(THCR)E/D': '2.9290', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.633', 'WR(T)/P': '6.7033', 'TT0': '1443.42', 'REAC-W': '0.842', 'W0': '3.326', '0WR(THCR)E/D': '4.3819', 'PT0': '18.8486'}}
3.5
{'Stage1': {'REAC-PS': '0.525', 'WR(T)/P': '4.4695', 'TT0': '1602.30', 'REAC-W': '0.563', 'W0': '3.316', '0WR(THCR)E/D': '2.9290', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.633', 'WR(T)/P': '6.7033', 'TT0': '1443.42', 'REAC-W': '0.842', 'W0': '3.326', '0WR(THCR)E/D': '4.3819', 'PT0': '18.8486'}}
3.0
{'Stage1': {'REAC-PS': '0.525', 'WR(T)/P': '4.4695', 'TT0': '1602.30', 'REAC-W': '0.563', 'W0': '3.316', '0WR(THCR)E/D': '2.9290', 'PT0': '29.7010'}, 'Stage2': {'REAC-PS': '0.633', 'WR(T)/P': '6.7033', 'TT0': '1443.42', 'REAC-W': '0.842', 'W0': '3.326', '0WR(THCR)E/D': '4.3819', 'PT0': '18.8486'}}
Reply With Quote Quick reply to this message  
Join Date: Jul 2006
Posts: 608
Reputation: jrcagle is on a distinguished road 
Solved Threads: 150
jrcagle jrcagle is offline Offline
Practically a Master Poster

Re: strange dictionary definition/object instance problem

 
0
  #6
May 13th, 2008
What's happening is that dictionaries, like lists, are mutable objects. Furthermore, they are assigned by reference and not by value. So under certain conditions, you might think you are changing one mutable object when in fact you are changing all of the ones that are referenced:

  1. >>> a = []
  2. >>> b = a # b and a point to the same list now.
  3. >>> b.append(1)
  4. >>> b
  5. [1]
  6. >>> a
  7. [1]
  8. >>>

Now as far as I can tell, the issue here is subtle. These two functions illustrate the problem:

  1. >>> def test_func():
  2. results = {}
  3. for x in range(4):
  4. results[x] = {}
  5. results[x]["conditions"] = x
  6. print results
  7.  
  8.  
  9. >>> test_func()
  10. {0: {'conditions': 0}, 1: {'conditions': 1}, 2: {'conditions': 2}, 3: {'conditions': 3}}
  11. >>>
  12. >>> def test_func2():
  13. results = {}
  14. mydict = {}
  15. for x in range(4):
  16. results[x] = mydict
  17. results[x]["conditions"] = x
  18. print results
  19.  
  20.  
  21. >>> test_func2()
  22. {0: {'conditions': 3}, 1: {'conditions': 3}, 2: {'conditions': 3}, 3: {'conditions': 3}}
  23. >>>

The difference between the first version and the second is that mydict is getting clobbered successively. I *think* that's what's happening with q70out.conditions. I suspect there's a bug in the code for q70.Q70Output( prefix + outputFile ) that returns a mutable object that's getting clobbered every time.

I whole-heartedly agree with wooeee ... your data structure would be a whole lot happier as a class object with members called .conditions and .performance.

Jeff
Last edited by jrcagle; May 13th, 2008 at 9:52 pm.
Reply With Quote Quick reply to this message  
Join Date: Dec 2006
Posts: 1,008
Reputation: woooee is a jewel in the rough woooee is a jewel in the rough woooee is a jewel in the rough 
Solved Threads: 285
woooee woooee is offline Offline
Veteran Poster

Re: strange dictionary definition/object instance problem

 
0
  #7
May 13th, 2008
This is a very simple example of how you could use SQLite in memory. This may be a case of the difficult way actually being the simpliest. Note that this is just a simple/quick example. There is a lot more on the web. If this is of some help you can thank The Blues. I was looking for something that I could do while listening to Bad Dog Blues.
  1. import sqlite3 as sqlite
  2.  
  3. ##----------------------------------------------------------------------
  4. def add_rec(cur, con, add_tuple):
  5. print "add_rec", len(add_tuple)
  6. cur.execute("insert into test_it values (?, ?, ?, ?, ?, ?, ?, ?, ?)", add_tuple)
  7. con.commit()
  8.  
  9. ##----------------------------------------------------------------------
  10. def print_all_recs(cur):
  11. # Execute the SELECT statement:
  12. print "Printing all recs"
  13. cur.execute("select * from test_it")
  14.  
  15. # Retrieve all rows as a sequence and print that sequence:
  16. recs_list = cur.fetchall()
  17. for rec in recs_list:
  18. print rec
  19. print " stage, REAC_W =", rec[1], rec[5]
  20.  
  21. ##----------------------------------------------------------------------
  22. def add_test_data(cur, con):
  23. #-----> Stage REAC_PS WR(T)/P TTO REAC_W W0 0wR(THCR)E/D PTO
  24. data_list=[ ('2.0', 'Stage1', '0.509', '4.3010', '1602.30', '0.515', '3.191', '2.8191', '29.7010'), \
  25. ('2.0', 'Stage2', '0.488', '6.0074', '1470.43', '0.500', '3.200', '3.9309', '20.4275'), \
  26. ('2.0', 'Stage1', '0.524', '4.4623', '1602.30', '0.560', '3.311', '2.9243', '29.7010'), \
  27. ('2.0', 'Stage2', '0.579', '6.6682', '1444.78', '0.700', '3.320', '4.3593', '18.9262'), \
  28. ('3.0', 'Stage1', '0.524', '4.4623', '1602.30', '0.560', '3.311', '2.9243', '29.7010'), \
  29. ('3.0', 'Stage2', '0.579', '6.6682', '1444.78', '0.700', '3.320', '4.3593', '18.9262'), \
  30. ('3.5', 'Stage1', '0.525', '4.4695', '1602.30', '0.563', '3.316', '2.9290', '29.7010') ]
  31.  
  32. for data_tuple in data_list :
  33. add_rec(cur, con, data_tuple)
  34.  
  35. ##----------------------------------------------------------------------
  36. if __name__ == "__main__":
  37. # Create a connection to the (memory) database file
  38. con = sqlite.connect(':memory:')
  39.  
  40. # Get a Cursor object that operates in the context of Connection con
  41. cur = con.cursor()
  42.  
  43. cur.execute("CREATE TABLE test_it (number varchar, stage varchar, REAC_PS varchar, WR_T_P varchar, TTO varchar, REAC_W varchar, W0 varchar, wR_THCR_E_D varchar, PTO varchar)")
  44.  
  45. add_test_data(cur, con)
  46. print_all_recs(cur)
  47.  
  48. ##----------------------------------------------------------------------
  49. print '\n-----SELECT * FROM test_it where number="2.0"-------'
  50. recs_list=cur.execute('SELECT * FROM test_it where number="2.0"')
  51. ctr=0
  52. for row in recs_list:
  53. print row
  54. ctr += 1
  55. print ctr, "recs found"
  56.  
  57. print '\n-----SELECT * FROM test_it where number="2.0" and stage="Stage1"'
  58. lookup_dic={"dic_num":"2.0", "dic_st":"Stage1"}
  59. recs_list=cur.execute('SELECT * FROM test_it where number=:dic_num and stage=:dic_st', \
  60. lookup_dic)
  61. ctr=0
  62. for row in recs_list:
  63. print row
  64. ctr += 1
  65. print ctr, "recs found"
Last edited by woooee; May 13th, 2008 at 11:55 pm.
Reply With Quote Quick reply to this message  
Join Date: May 2008
Posts: 6
Reputation: jmroach is an unknown quantity at this point 
Solved Threads: 0
jmroach jmroach is offline Offline
Newbie Poster

Re: strange dictionary definition/object instance problem

 
0
  #8
May 14th, 2008
Thanks a ton for the help and great example, woooee & jrcagle! i did a little google'ing since i have absolutely no experience with sql, but it does seem like a really good fit for this type of application. i'll give it a try this morning and see if i can't get things working. i'll post the resolution upon completion.

-john
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Other Threads in the Python Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC