943,965 Members | Top Members by Rank

Ad:
  • Python Discussion Thread
  • Unsolved
  • Views: 1876
  • Python RSS
You are currently viewing page 1 of this multi-page discussion thread
Oct 31st, 2007
0

Saving pickled info and reloading info

Expand Post »
Hello, I am fairly new to Python and starting to get it. But I am having some difficulty with pickle. I am trying to get a account program to pickle user input and to save that in a data file and then reload said info and read as input for the program. I have finally got the pickle portion down, I am able to send the info I want but I cannot figure out the correct syntax to be able to keep adding to the file instead of simply overwriting what is in the data file. I want to be able to pickle info into set keys I guess, so that I can recall certain portions, vice versa. I am assuming it should be a list with a counter, that will keep adding to the file but not sure how to accomplish that. The code is below. I would appreciate any help. This is homework, but I am not trying to get anyone to just do it. I would really like to find out how to do this.

I have tried finding examples online but cannot find any code that does not totally confuse me but that also contains what I am trying to accomplish in it.

Thanks for any help!!!

Python Syntax (Toggle Plain Text)
  1. import pickle as p
  2.  
  3. acctHist = 'acctHist.data'
  4.  
  5. class pettyAccount:
  6. def __init__(self, initial, open='05 Sep 07'):
  7. self.balance = initial
  8. openDate = open
  9. def deposit(self, amt, dDate='30 Oct 07'):
  10. self.balance = self.balance + amt
  11. self.date = dDate
  12. def withdraw(self, amt, wDate='30 Oct 07'):
  13. self.balance = self.balance - amt
  14. self.date = wDate
  15. def getbalance(self, gDate='30 Oct 07'):
  16. self.date = gDate
  17. return self.balance
  18.  
  19. def welcome(self):
  20. prompt = input ('Welcome to the petty cash account: \
  21. Enter 1 to Record a Deposit \
  22. Enter 2 to Record a Withdrawal \
  23. Enter 3 to Get the Balance')
  24. if prompt == 1:
  25. newDep = input ('Amount of deposit:')
  26. newDate = raw_input ('Date of deposit:')
  27. a.deposit(newDep)
  28. f = file(acctHist, 'w')
  29. pickFile = 'Deposit:',newDep, newDate
  30. p.dump(pickFile, f)
  31. f.close()
  32. g = file(acctHist)
  33. dTest = p.load(g) # A test so I could make sure that pickle was working
  34. print dTest
  35. print
  36. print 'The new balance is $',a.getbalance(), 'on %s.' % newDate
  37. return a.welcome()
  38. elif prompt == 2:
  39. newWith = input ('Amount of withdrawal:')
  40. balance = a.getbalance()
  41. if newWith > balance:
  42. print 'Withdrawal exceeded account balance: $',balance, ' Reduce withdrawal amount.'
  43. return a.welcome()
  44. else:
  45. newDate = raw_input ('Date of withdrawal:')
  46. a.withdraw(newWith)
  47. f = file(acctHist, 'w')
  48. pickFile = 'Withdrawl:',newWith, newDate
  49. p.dump(pickFile, f)
  50. f.close()
  51. g = file(acctHist)
  52. wTest = p.load(g)
  53. print wTest # A test so I could make sure that pickle was working
  54. print
  55. print 'The new balance is $',a.getbalance(), 'on %s.' % newDate
  56. return a.welcome()
  57. elif prompt == 3:
  58. today = raw_input ("Enter today's date:")
  59. print 'The current balance is $',a.getbalance(), 'on %s.' % today
  60. return a.welcome()
  61. else:
  62. print 'Thank you, goodbye'
  63.  
  64. a = pettyAccount(1000)
  65. a.welcome()
Similar Threads
Reputation Points: 10
Solved Threads: 0
Newbie Poster
sibdizzle is offline Offline
2 posts
since Oct 2007
Nov 1st, 2007
0

Re: Saving pickled info and reloading info

Is there a better way for me to accomplish my goal? As in write the info to a file and not use pickle. Any help is appreciated, even a suggestion for a different way to give me a new search term to help me find a new angle.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
sibdizzle is offline Offline
2 posts
since Oct 2007
Nov 1st, 2007
0

Re: Saving pickled info and reloading info

Hi sidbizzle,

So if I am understanding your code correctly, you are trying to set up a program that prints a welcome prompt with a menu, then allows the user to deposit or withdraw from an account. The amount of money in the account is stored in acctHist.data, along with the date of the last transaction. Yes?

Problem #1: the account object 'a' always begins with 1000. Shouldn't it begin with whatever is in acctHist.data? In other words, the first time you create the account it should contain 1000, but every time the program is executed after that it ought to read acctHist.data and get the amount, then add to or subtract from that amount.

Problem #2: does the acctHist.data file store the account or the transaction history for the account? Because the name of the file and the way you describe it make it sound like it's a transaction history, but your code makes it look like just a raw deposit of the amount of money currently in the account + the last transaction date.

If you would like to make acctHist.data a transaction history, may I make a recommendation? Rather than pickling individual tuples of ('Transaction Type:',newAmt, newDate), create a dictionary of transactions and pickle that, instead. Dictionaries are primitive data structures which contain key-value pairs. So what you'd want to do is something like this:
Python Syntax (Toggle Plain Text)
  1. transactions = dict()
  2. transactions['TRANSACTION_ID'] = ('Transaction Type:', newAmt, newDate)
  3. pickle.dump(transactions, f)
It might be smarter to simply make this transaction dictionary an instance variable of the pettyAccount class, then pickle the whole pettyAccount object!

Hope this helps.
Last edited by G-Do; Nov 1st, 2007 at 4:05 pm.
Reputation Points: 41
Solved Threads: 31
Junior Poster
G-Do is offline Offline
146 posts
since Jun 2005
Jun 14th, 2008
0

Re: Saving pickled info and reloading info

I'm sure that this a major Newbie question... but looking the code that you 2 have posted I am still WAY lost. I have been working on it for hours and hours and have flipped back and forth from a dictionary to using a list... I am so lost in the code that I have typed right now that I don't know which way is up.
I'll attach what I have (plz be kind as I know it's a complete mess), and if you can point me in the right direction that would be GREAT!!! (also... could you please dumb it down as much as possible for me?)
Thanks in advance!

Python Syntax (Toggle Plain Text)
  1. import pickle as p
  2. import operator
  3.  
  4. class pettyAccount():
  5. def __init__(self, initial=0,date='13 June 08'):
  6. self.balance = initial
  7. self.id= id
  8. self.date= date
  9.  
  10. def deposit(self, amt):
  11. self.balance = self.balance + amt
  12. return self.balance
  13. def withdraw(self, amt):
  14. self.balance = self.balance - amt
  15. return self.balance
  16. def getbalance(self):
  17. f = open(acctHist, 'r')
  18. account_list=p.load(f)
  19. f.close()
  20. return (account_list)
  21.  
  22.  
  23. def welcome(self):
  24. #print account_list[1:0]
  25. prompt = 0
  26. while prompt < 4:
  27. print ('Welcome to the petty cash account: \n\n\
  28. Enter 1 to Record a Deposit \n\
  29. Enter 2 to Record a Withdrawal \n\
  30. Enter 3 to Get the Balance\n\
  31. Enter 4 to Exit\n ')
  32. prompt=input('Enter option: ')
  33.  
  34. if prompt == 1:
  35. newDep = input ('Amount of deposit: ')
  36. newDate = raw_input ('Date of deposit: ')
  37. newid=input('Enter a ID number for this transaction')
  38. newAmt=a.deposit(newDep)
  39. depList=dict (a=newAmt, b=newDate, c= newid) # Makeing the deposit List
  40. if id in id_list:
  41. print "This id already exists, try again!"
  42. else:
  43. id_list.append(id)
  44. break
  45. #depList[newid]=('Deposit: ', newAmt, newDate)
  46. #depList.append((newAmt, newDate, newid)) #Putting the List together
  47. f = open(acctHist, 'w')
  48. p.dump(depList,f) #Dumping the List
  49. #p.dump(a.deposit(newDep), f)
  50. #p.dump(newDate,f)
  51. f.close()
  52.  
  53. print '--------------------------------------------------------'
  54. print 'The new balance is $ %s on .' % newAmt, newDate
  55. #print 'The new balance is $',a.getbalance(), 'on %s.' % newDate
  56. print '--------------------------------------------------------\n'
  57.  
  58.  
  59. elif prompt == 2:
  60. newWith = input ('Amount of withdrawal: ')
  61. balance = a.getbalance()
  62. if newWith > balance:
  63. print '--------------------------------------------------------'
  64. print 'Withdrawal exceeded account balance: $',balance, ' \nReduce withdrawal amount.'
  65. print '--------------------------------------------------------\n'
  66.  
  67. else:
  68. newDate = raw_input ('Date of withdrawal: ')
  69. f = file(acctHist, 'w')
  70. p.dump(a.withdraw(newWith), f)
  71. p.dump(newDate,f)
  72. f.close()
  73. print '--------------------------------------------------------'
  74. print 'The new balance is $',a.getbalance(), 'on %s.' % newDate
  75. print '--------------------------------------------------------\n'
  76.  
  77. elif prompt == 3:
  78.  
  79. newAmt= account_list['a']
  80. print '--------------------------------------------------------'
  81. print 'The current balance is $ %s' %newAmt
  82. print '--------------------------------------------------------\n'
  83.  
  84.  
  85. else:
  86. print 'Thank you, goodbye'
  87.  
  88.  
  89. a=pettyAccount()
  90. acctHist = 'acctHist.data'
  91. try:
  92. fin = open(acctHist, "r")
  93. account_list = p.load(fin)
  94. fin.close()
  95. print "Account database file %s has been loaded!" % acctHist
  96. print account_list
  97. welcome(account_list)
  98. except IOError:
  99. print "Cannot find account database file %s" % acctHist
  100. welcome(0)

ps. I know that the program doesn't work right now... the major problem that I am having is trying to get the correct input from the file (and vice-versa) so that I can update it with a new entry.
If you have more questions about what I am trying to do PLEASE don't hesitate to ask!
Reputation Points: 10
Solved Threads: 0
Newbie Poster
count_chockula is offline Offline
4 posts
since Jun 2008
Jun 14th, 2008
0

Re: Saving pickled info and reloading info

Hi count_chockula,

First of all, class definitions do not have parentheses after them. So:
python Syntax (Toggle Plain Text)
  1. class pettyAccount():
should be:
python Syntax (Toggle Plain Text)
  1. class pettyAccount:

Second of all, why are you asking the user for the date and time? Python can calculate that for you. See the datetime module. A good rule of thumb in design is, don't make the user do more than the minimum necessary amount of work. If you go to an ATM, does it force you to enter the date? Or an ID? Of course not; it calculates these things for you.

So by that reasoning, you should also have the program make its own IDs. If you don't feel like doing a whole lot of work, the ID could just be a timestamp from the datetime module. Or you could just keep a running counter - one, two, three, and so on.

Third of all, what is "id_list" supposed to be? You never create it - you only append to it - so the program craps out with an "id_list not defined" message. Maybe you should make this a field of the pettyAccount object?

Hope this helps.
Reputation Points: 41
Solved Threads: 31
Junior Poster
G-Do is offline Offline
146 posts
since Jun 2005
Jun 16th, 2008
0

Re: Saving pickled info and reloading info

Thanks for getting back with me. I have fixed the pettyAccount thing... not real sure why I left it in there to begin with.
As for the time stamp... I was going to work on getting the time mod. in there later. I was just trying to get the "date" to save in the file to begin with. I would love to put just the time stamp in there and use that as an "id" string, but I'm having trouble saving the information every time that I add or subtract something. I can get it to save... but every time that I add something it just updates the file... that is, it doesn't add to the file.
What's more, I can't seem to read the information back from the file so that if I need to change just 1 of the entries all I would have to do is put in the correct "id" in and edit it.
(This above is where I need the help)
If you could help me out I would GREATLY apprish!
Reputation Points: 10
Solved Threads: 0
Newbie Poster
count_chockula is offline Offline
4 posts
since Jun 2008
Jun 16th, 2008
0

Re: Saving pickled info and reloading info

Hi count_chockula,

The file is being overwritten because your file handles are created with an option of "w" which is short for "write." To add extra data to a file without overwriting, you need an option of "a" which is short for "append."

If you use pickle.dump() with an appending file handle, it will add objects to the file as if the file were a queue. Doing pickle.load() on a file like that will cause the objects to be popped one at a time, in FIFO order. This is generally how pickle works.

My suggestion to you is this. Don't write to the file every time you perform a transaction. If I was writing this program, I would stick only one object inside the text file - a dictionary containing all transactions, keyed by their IDs. I would load the dictionary when the program begins, before the user makes any choices. Then I would alter the dictionary whenever the user does something. Then I would re-pickle it when the program ends. That way, you only need to worry about reading and writing once - at the beginning and the end of the program, respectively.

Hope this helps.
Reputation Points: 41
Solved Threads: 31
Junior Poster
G-Do is offline Offline
146 posts
since Jun 2005
Jun 16th, 2008
0

Re: Saving pickled info and reloading info

Thanks for that quick responce!!! I knew that it had to be a reason for my mess up's in the Pickle.
I like where you are going with the dictionary... and I can build the dictionary with the 'date' stamp as the key. But, what I don't know how to do is add the next key:val everytime that I add something (you can't append a dictionary...right?). Also... how does one 'add' to the total if you are putting a new value with a new key.
In other words... this is what I get when I call the dictionary back in...
{'16 Jun 2008 01:41:17': ('Deposit: ', 6, '3')}
With my current code...
Python Syntax (Toggle Plain Text)
  1. import pickle as p
  2. import sys
  3. import time
  4.  
  5. class pettyAccount:
  6. def __init__(self, initial=0,date='13 June 08'):
  7. self.balance = initial
  8. self.id= id
  9. self.date= date
  10.  
  11. def deposit(self, amt):
  12. self.balance = self.balance + amt
  13. return self.balance
  14. def withdraw(self, amt):
  15. self.balance = self.balance - amt
  16. return self.balance
  17. def getbalance(self):
  18. f = open(acctHist, 'r')
  19. account_list=p.load(f)
  20. f.close()
  21. return account_list
  22.  
  23.  
  24. def welcome(self):
  25. prompt = 0
  26. while prompt < 4:
  27. print ('Welcome to the petty cash account: \n\n\
  28. Enter 1 to Record a Deposit \n\
  29. Enter 2 to Record a Withdrawal \n\
  30. Enter 3 to Get the Balance\n\
  31. Enter 4 to Exit\n ')
  32. prompt=input('Enter option: ')
  33.  
  34. if prompt == 1:
  35. newDep = input ('Amount of deposit: ')
  36. newDate = raw_input ('Date of deposit: ')
  37. newid=input('Enter a ID number for this transaction')
  38. newAmt=a.deposit(newDep)
  39. depList={}
  40. depList[time.strftime('%d %b %Y %H:%M:%S')]=('Deposit: ', newAmt, newDate)
  41. f = open(acctHist, 'w')
  42. p.dump(depList,f) #Dumping the List
  43. f.close()
  44.  
  45. print '--------------------------------------------------------'
  46. print 'The new balance is $ %s on .' % newAmt, newDate
  47.  
  48. print '--------------------------------------------------------\n'
  49.  
  50.  
  51. elif prompt == 2:
  52. newWith = input ('Amount of withdrawal: ')
  53. balance = a.getbalance()
  54. if newWith > balance:
  55. print '--------------------------------------------------------'
  56. print 'Withdrawal exceeded account balance: $',balance, ' \nReduce withdrawal amount.'
  57. print '--------------------------------------------------------\n'
  58.  
  59. else:
  60. newDate = raw_input ('Date of withdrawal: ')
  61. f = file(acctHist, 'w')
  62. p.dump(a.withdraw(newWith), f)
  63. p.dump(newDate,f)
  64. f.close()
  65. print '--------------------------------------------------------'
  66. print 'The new balance is $',a.getbalance(), 'on %s.' % newDate
  67. print '--------------------------------------------------------\n'
  68.  
  69. elif prompt == 3:
  70. print account_list
  71. newAmt= account_list[:1]
  72. print '--------------------------------------------------------'
  73. print 'The current balance is $ %s' %newAmt
  74. print '--------------------------------------------------------\n'
  75.  
  76.  
  77. else:
  78. print 'Thank you, goodbye'
  79.  
  80.  
  81. a=pettyAccount()
  82. acctHist = 'acctHist.data'
  83. try:
  84. fin = open(acctHist, "r")
  85. account_list = p.load(fin)
  86. fin.close()
  87. print "Account database file %s has been loaded!" % acctHist
  88. print account_list
  89. welcome(account_list)
  90. except IOError:
  91. print "Cannot find account database file %s" % acctHist
  92. welcome(0)
How do I 'add' a new deposit to the total now?
Thanks for being so understanding with me... I know it must be hard!
Last edited by count_chockula; Jun 16th, 2008 at 3:58 am.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
count_chockula is offline Offline
4 posts
since Jun 2008
Jun 16th, 2008
0

Re: Saving pickled info and reloading info

BTW, I do like only pickeling one time... but for now I am just adding it in there for testing
Reputation Points: 10
Solved Threads: 0
Newbie Poster
count_chockula is offline Offline
4 posts
since Jun 2008
Jun 16th, 2008
0

Re: Saving pickled info and reloading info

Um just a quick note:
Im under the impression you do have parentheses after a class definition becuase this can be used to set class parents and attibutes as well as making it a new-style class.
python Syntax (Toggle Plain Text)
  1. # a few examples
  2. import wx
  3.  
  4. class MainFrame(wx.Frame):
  5. pass
  6. #this means this class has all the attributes of wx.Frame
  7. class Parent(object):
  8. #new style class
  9. class Child(Parent):
  10. #child has all attributes of Parent
Reputation Points: 264
Solved Threads: 183
Veteran Poster
Paul Thompson is offline Offline
1,095 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: new Python user has Export Problems
Next Thread in Python Forum Timeline: Creating Install Module





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


Follow us on Twitter


© 2011 DaniWeb® LLC