[Tutor] how to create a persistent dictionary w/ cpickle?

Carter Danforth carter.danforth at gmail.com
Wed Sep 22 19:59:49 CEST 2010


Dave, Steve, and Alan: late reply here, but thanks a lot guys - really
appreciate the feedback. I had no idea what I was doing w/ that class in the
addressbook, needed to read up more, and I got the dictionary figured out w/
cpickle and now it's all working.

Thanks again, this input's really helping my learning curve.


On Thu, Sep 9, 2010 at 2:19 AM, <tutor-request at python.org> wrote:

> Send Tutor mailing list submissions to
>        tutor at python.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>        http://mail.python.org/mailman/listinfo/tutor
> or, via email, send a message with subject or body 'help' to
>        tutor-request at python.org
>
> You can reach the person managing the list at
>        tutor-owner at python.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Tutor digest..."
>
>
> Today's Topics:
>
>   1. Re: how to create a persistent dictionary w/ cpickle?
>      (Steven D'Aprano)
>   2. Re: how to create a persistent dictionary w/ cpickle? (Dave Angel)
>   3. Re: how to create a persistent dictionary w/ cpickle? (Alan Gauld)
>   4. Re: slicing a string (Sandip Bhattacharya)
>   5. Re: slicing a string (Evert Rol)
>   6. Re: slicing a string (Sandip Bhattacharya)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Thu, 9 Sep 2010 07:50:13 +1000
> From: Steven D'Aprano <steve at pearwood.info>
> To: tutor at python.org
> Subject: Re: [Tutor] how to create a persistent dictionary w/ cpickle?
> Message-ID: <201009090750.14230.steve at pearwood.info>
> Content-Type: text/plain;  charset="utf-8"
>
> On Thu, 9 Sep 2010 03:43:42 am Carter Danforth wrote:
> > Hi, I'm trying to a create a basic addressbook for practice. I'm
> > using a dictionary with cpickle, though I'm not sure how to
> > persistently store each instance in the dictionary. Below is the code
> > I have so far.
> >
> > If I run it once and add a contact and the details, it's fine.
> > p.load(f) shows the details next time I run it, but if I add another
> > contact, and run it again, the previous key:value doesn't show. It
> > gets replaced by the new one.
>
> Where do you think you are *adding* a new contact? You don't. You
> *replace* the existing contact with a brand new one, every time.
>
> The problem has nothing to do with pickle, or storing "each instance in
> the dictionary". Pickle is already storing each instance in the
> dictionary. The problem is that you never *add* anything to the address
> book, you *replace* it each time, so there is never more than two
> instances in the dictionary (one key, one value).
>
> You don't have an address BOOK, you only have a single address.
>
>
> > How can I fix this so that it adds the new key:value to the
> > dictionary instead of replacing the existing one? Appreciate any
> > help, thanks.
>
> I would dump the entire address class for now and just go for something
> nice and minimal. Get that working first, and then, *if necessary*,
> wrap it in a class. This is Python, not Java -- we use whatever works,
> and don't force everything to be a class when it doesn't have to be.
>
> What's the simplest address record you might have? How about a name
> linked to a telephone number and email?
>
> address_book = {name: (tel, email), another_name: (tel, email), ...}
>
> So, here's the basic algorithm:
>
> (1) Look for the address-book. If it doesn't exist, create an empty
> dictionary, and pickle it as the address-book.
>
> (2) Read the address-book from the pickle file. It will be a dictionary,
> possibly empty.
>
> (3) Add an address to the dictionary. Don't create a new dictionary:
>
> >>> addresses = {}  # creates a new, empty address book
> >>> addresses["Fred"] = ("1234 5678", "fred at example.com")
> >>> addresses["Betty"] = ("2468 1357", "betty at nowhere.com")
> >>> addresses  # not empty any more
> {'Betty': ('2468 1357', 'betty at nowhere.com'), 'Fred': ('1234
> 5678', 'fred at example.com')}
>
> (3) Save the dictionary to the pickle file.
>
>
> Once you have those steps happening manually, then wrap it into a class
> so they happen automatically.
>
>
> Some more comments on your code:
>
>
> > import cPickle as p
>
> Now that's just lazy. While laziness in a programmer in a good thing,
> this is taking it to extremes!!! You use pickle twice, three times if
> you count the import. Is it really such a burden on you to
> type "cPickle" (or "pickle") two more times, that you need to rename
> it "p"?
>
> Excessive use of one-character names is one of the worst programming
> habits you can have. Don't do this.
>
>
> > addressbook = 'addressbook.data'
>
> Misleading variable name. "addressbook" isn't an addressbook at all,
> it's a filename.
>
> > f = file(addressbook, 'r+')
>
> You shouldn't keep the file open for large periods of time. On Windows,
> it may mean that it will be locked from any other program accessing it
> during that time, and it risks data corruption if your program crashes
> or the power goes out.
>
> Open and close the file just when you need it.
>
>
> > class address:
>
> A minor point: it is the convention in Python that (most) classes start
> with a capital letter. So Address would be the class, leaving address
> available for an instance of the class:
>
> address = Address()
>
>
> >     def __init__(self, name, tel, email):
> >         self.name = name
> >         self.tel = tel
> >         self.email = email
> >         ab = {self.name : self.tel}
> >         f = file(addressbook, 'r+')
> >         p.dump(ab, f)
> >
> > print p.load(f)
> > x = raw_input()
> >
> > if x == 'add':
> >     name = raw_input('\nName: ')
>
> To get a blank line before the prompt, it might be nicer to do this:
>
> print
> name = raw_input('Name: ')
>
> That's a matter of personal preference though.
>
>
> >     tel = raw_input('Tel: ')
> >     email = raw_input('Email: ')
> >     contact = address(name, tel, email)
>
>
>
>
> Hope this helps,
>
>
>
> --
> Steven D'Aprano
>
>
> ------------------------------
>
> Message: 2
> Date: Wed, 08 Sep 2010 18:14:45 -0400
> From: Dave Angel <davea at ieee.org>
> To: Carter Danforth <carter.danforth at gmail.com>
> Cc: Tutor at python.org
> Subject: Re: [Tutor] how to create a persistent dictionary w/ cpickle?
> Message-ID: <4C880AD5.5040104 at ieee.org>
> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
>
>  On 2:59 PM, Carter Danforth wrote:
> > Hi, I'm trying to a create a basic addressbook for practice. I'm using a
> > dictionary with cpickle, though I'm not sure how to persistently store
> each
> > instance in the dictionary. Below is the code I have so far.
> >
> > If I run it once and add a contact and the details, it's fine. p.load(f)
> > shows the details next time I run it, but if I add another contact, and
> run
> > it again, the previous key:value doesn't show. It gets replaced by the
> new
> > one.
> >
> > How can I fix this so that it adds the new key:value to the dictionary
> > instead of replacing the existing one? Appreciate any help, thanks.
> >
> > import cPickle as p
> > addressbook = 'addressbook.data'
> > f = file(addressbook, 'r+')
> >
> > class address:
> >      def __init__(self, name, tel, email):
> >          self.name = name
> >          self.tel = tel
> >          self.email = email
> >
> >          ab = {self.name : self.tel}
> >
> >          f = file(addressbook, 'r+')
> >          p.dump(ab, f)
> >
> > print p.load(f)
> > x = raw_input()
> >
> > if x == 'add':
> >      name = raw_input('\nName: ')
> >      tel = raw_input('Tel: ')
> >      email = raw_input('Email: ')
> >
> >      contact = address(name, tel, email)
> >
> I have no clue what you're trying to do with that address object;  it's
> confusing initialization with persistence, and you create such an
> object, but never actually use it.  I would remove any reference to the
> address book from that object.  I'd also rename it to Address, since
> class names are supposed to be uppercase (PEP8)
>
> But anyway, in your flow, you do a p.load(), but never save the result.
> Every time you save to the addressbook file, you start over with just
> the one entry.
>
> One way to fix this is to save the p.load() result as a variable,
> presumably of type dictionary, then add the 'contact' to that
> dictionary, and at the end of the script, save that variable with
> p.dump(addresses, f)
>
> addresses =   p.load(f)
>
> interact with user --
>            addresses[name] = Address(name, tel, email)
>
> p.dump(addresses, f)
>
> I also don' t know how you get away with running your script the first
> time, since it blows up if there's no existing pickle file.
>
> DaveA
>
>
>
> ------------------------------
>
> Message: 3
> Date: Thu, 9 Sep 2010 01:17:12 +0100
> From: "Alan Gauld" <alan.gauld at btinternet.com>
> To: tutor at python.org
> Subject: Re: [Tutor] how to create a persistent dictionary w/ cpickle?
> Message-ID: <i69925$6rk$1 at dough.gmane.org>
> Content-Type: text/plain; format=flowed; charset="iso-8859-1";
>        reply-type=original
>
>
> "Carter Danforth" <carter.danforth at gmail.com> wrote
>
> > Hi, I'm trying to a create a basic addressbook for practice. I'm
> > using a
> > dictionary with cpickle, though I'm not sure how to persistently
> > store each
> > instance in the dictionary. Below is the code I have so far.
>
> If you use a dictionary it makes more sense to use shelve rather than
> pickle for storage.
> Shelve uses pickle under the hood but it makes a file look like a
> dictionary so you
> don't need to load all the data and store it all again as you would
> with pickle.
>
> Unfioortunately your code appears to be truncated, however...
>
> > import cPickle as p
> > addressbook = 'addressbook.data'
> > f = file(addressbook, 'r+')
>
> I think you should use a binary file for pickle so the mode should be
> 'rb' not 'r+'
>
> HTH,
>
> Alan G
>
>
>
>
> ------------------------------
>
> Message: 4
> Date: Thu, 9 Sep 2010 11:19:39 +0530
> From: Sandip Bhattacharya <sandipb at foss-community.com>
> To: Roel Schroeven <rschroev_nospam_ml at fastmail.fm>
> Cc: tutor at python.org
> Subject: Re: [Tutor] slicing a string
> Message-ID:
>        <AANLkTinnzizKw4Uadk6PDYpEczJJYra_OTxAAC7d8SNp at mail.gmail.com>
> Content-Type: text/plain; charset=ISO-8859-1
>
> On Tue, Sep 7, 2010 at 1:49 PM, Roel Schroeven
> <rschroev_nospam_ml at fastmail.fm> wrote:
> >
> > But remember that you can make it simpler if you simply don't specify
> > the start and end points:
> >
> >>>> 'hello'[::-1]
> > 'olleh'
> >
>
> While I know that idiom works, I haven't really found an explanation
> as to *why* it works that way.
>
> For a string S:
> * Using  range, you need range(len(S),-1,-1) to give you the indexes
> for the string in reverse.
> * For slices, if you dont specify the start and end indices, they are
> supposed to be filled in by 0 and len(S) respectively.
>  - So S[::-1] means, S[0:len(S):-1] , so why dont we start with index
> 0 here, and then go to -1 (last char) and then into an infinite loop?
>  - Especially, when S[0:len(S):1] works that way?
>
> - Sandip
>
>
> ------------------------------
>
> Message: 5
> Date: Thu, 9 Sep 2010 08:04:04 +0200
> From: Evert Rol <evert.rol at gmail.com>
> To: Sandip Bhattacharya <sandipb at foss-community.com>
> Cc: Roel Schroeven <rschroev_nospam_ml at fastmail.fm>, tutor at python.org
> Subject: Re: [Tutor] slicing a string
> Message-ID: <DBA494E3-37EE-4035-A4E4-616241BFE5F8 at gmail.com>
> Content-Type: text/plain; charset=windows-1252
>
> >> But remember that you can make it simpler if you simply don't specify
> >> the start and end points:
> >>
> >>>>> 'hello'[::-1]
> >> 'olleh'
> >>
> >
> > While I know that idiom works, I haven't really found an explanation
> > as to *why* it works that way.
> >
> > For a string S:
> > * Using  range, you need range(len(S),-1,-1) to give you the indexes
> > for the string in reverse.
> > * For slices, if you dont specify the start and end indices, they are
> > supposed to be filled in by 0 and len(S) respectively.
> >  - So S[::-1] means, S[0:len(S):-1] , so why dont we start with index
> > 0 here, and then go to -1 (last char) and then into an infinite loop?
>
> I guess because Python "is smart", and works the way you want/expect it to.
> Read
> http://docs.python.org/library/stdtypes.html#sequence-types-str-unicode-list-tuple-buffer-xrange, note 5 (about one "page" down), which explicitly says "If i or j are
> omitted or None, they become ?end? values (which end depends on the sign of
> k)", where the important bit for this discussion is actually between
> parentheses.
>
> And to quote part of the Zen of Python:
> "
> Special cases aren't special enough to break the rules.
> Although practicality beats purity.
> "
>
> Reversing the automatic end values is very practical when the step index <
> 0.
>
>
> >  - Especially, when S[0:len(S):1] works that way?
> >
> > - Sandip
> > _______________________________________________
> > Tutor maillist  -  Tutor at python.org
> > To unsubscribe or change subscription options:
> > http://mail.python.org/mailman/listinfo/tutor
>
>
>
> ------------------------------
>
> Message: 6
> Date: Thu, 9 Sep 2010 11:49:46 +0530
> From: Sandip Bhattacharya <sandipb at foss-community.com>
> To: Evert Rol <evert.rol at gmail.com>
> Cc: Roel Schroeven <rschroev_nospam_ml at fastmail.fm>, tutor at python.org
> Subject: Re: [Tutor] slicing a string
> Message-ID:
>        <AANLkTim+KPva5KPX2kq7v3EYFA68jL=dm5y87PYrkUdx at mail.gmail.com>
> Content-Type: text/plain; charset=windows-1252
>
> On Thu, Sep 9, 2010 at 11:34 AM, Evert Rol <evert.rol at gmail.com> wrote:
> > Read
> >
> http://docs.python.org/library/stdtypes.html#sequence-types-str-unicode-list-tuple-buffer-xrange
> > , note 5 (about one "page" down), which explicitly says "If i or j are
> > omitted or None, they become ?end? values (which end depends on the
> > sign of k)", where the important bit for this discussion is actually
> > between parentheses.
>
> Great! That is exactly what I needed to know. The reference I learnt
> extended slices from, probably didn't include this subtlety.
>
> Thanks,
>  Sandip
>
>
> ------------------------------
>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
>
>
> End of Tutor Digest, Vol 79, Issue 32
> *************************************
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20100922/08d893f7/attachment-0001.html>


More information about the Tutor mailing list