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