943,516 Members | Top Members by Rank

Ad:
  • Python Discussion Thread
  • Unsolved
  • Views: 1131
  • Python RSS
May 13th, 2008
0

strange dictionary definition/object instance problem

Expand Post »
I am trying to add entries to a dictionary with the following loop:

python Syntax (Toggle Plain Text)
  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:

Python Syntax (Toggle Plain Text)
  1. results{ '2.0':{'Conditions':{'Vane2INLET':{'WG': ####}}}}

SHOULD NOT CHANGE WITH ITERATION based on the loop
Reputation Points: 10
Solved Threads: 0
Newbie Poster
jmroach is offline Offline
6 posts
since May 2008
May 13th, 2008
0

Re: strange dictionary definition/object instance problem

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.
Python Syntax (Toggle Plain Text)
  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.
Reputation Points: 741
Solved Threads: 691
Nearly a Posting Maven
woooee is offline Offline
2,301 posts
since Dec 2006
May 13th, 2008
0

Re: strange dictionary definition/object instance problem

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:

python Syntax (Toggle Plain Text)
  1. dict = {}
  2. dict[0] = 0
  3. dict[1] = {}
  4. dict[2] = 2
  5. print dict

{0: 0, 1: {}, 2: 2}
Reputation Points: 10
Solved Threads: 0
Newbie Poster
jmroach is offline Offline
6 posts
since May 2008
May 13th, 2008
0

Re: strange dictionary definition/object instance problem

Click to Expand / Collapse  Quote originally posted by jmroach ...
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:

python Syntax (Toggle Plain Text)
  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.
Reputation Points: 741
Solved Threads: 691
Nearly a Posting Maven
woooee is offline Offline
2,301 posts
since Dec 2006
May 13th, 2008
0

Re: strange dictionary definition/object instance problem

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:

python Syntax (Toggle Plain Text)
  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'}}
Reputation Points: 10
Solved Threads: 0
Newbie Poster
jmroach is offline Offline
6 posts
since May 2008
May 13th, 2008
0

Re: strange dictionary definition/object instance problem

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:

Python Syntax (Toggle Plain Text)
  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:

Python Syntax (Toggle Plain Text)
  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.
Reputation Points: 92
Solved Threads: 156
Practically a Master Poster
jrcagle is offline Offline
608 posts
since Jul 2006
May 13th, 2008
0

Re: strange dictionary definition/object instance problem

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.
Python Syntax (Toggle Plain Text)
  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.
Reputation Points: 741
Solved Threads: 691
Nearly a Posting Maven
woooee is offline Offline
2,301 posts
since Dec 2006
May 14th, 2008
0

Re: strange dictionary definition/object instance problem

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
Reputation Points: 10
Solved Threads: 0
Newbie Poster
jmroach is offline Offline
6 posts
since May 2008

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in Python Forum Timeline: Adding tabs from plugins
Next Thread in Python Forum Timeline: Power Set List from Input List





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC