Re: [Tutor] Simple Python Address Book (Advice welcome!)

2012-06-18 Thread Prasad, Ramit
  def LoadAddresses():
Loads all addresses from file and places
   them in tuple in form (bool, list), where the list is each
   row from the file (a person's name | email). 
   success, lines = (False, [])
   try:
   f = open(addressBookPath, 'r')
   lines = f.readlines()
   f.close()
   success, lines = (True, lines)
   except IOError as e:
   print 'Error opening address book: ', e
   return (success, lines)
 
 The latest style preference in Python is to use with statements for file
 handling, so that would become:
 
 try:
with f as open(.):
   success,lines = True, f.readlines()
 except IOError as e:
print ...
 return (success,lines)

  def main():
 
   (success, lines) = LoadAddresses()
   if not success:

No real reason to return success as you can do this instead for the
same effect. The only difference would be on reading an empty file.
Not sure what you would want it to do...

def main():
lines = LoadAddressses()
if not lines:



Ramit


Ramit Prasad | JPMorgan Chase Investment Bank | Currencies Technology
712 Main Street | Houston, TX 77002
work phone: 713 - 216 - 5423

--
This email is confidential and subject to important disclaimers and
conditions including on offers for the purchase or sale of
securities, accuracy and completeness of information, viruses,
confidentiality, legal privilege, and legal entity disclaimers,
available at http://www.jpmorgan.com/pages/disclosures/email.  
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Simple Python Address Book (Advice welcome!)

2012-06-17 Thread Alan Gauld

On 17/06/12 02:45, mariocatch wrote:


I'm essentially asking if someone wouldn't mind taking a look at what I
have so far, and giving some advice on some of my weak areas,


Welcome, I've inserted a few comments below.
In general it's OK although personally I'd probably put the email 
validation in a short helper function (including the regex definition 
etc) just to tidy it up and avoid one level of indentation. (Its also 
potentially reusable so I'd probably put that function in its own module 
too...


I'd probably also put all the splitting logic into LoadAddresses so that 
what I get back is the actual address dictionary rather than the raw 
list of lines.


That would clean up main() quite a bit.

Also it's conventional to make function names start with lowerCase. 
UpperCase names usually imply it's a class.


Finally, I'd put all the functions above main() rather than having the 
lonely looking RecordAddresses() at the end.



import re # email validation
import textwrap
# forward declarations
addressBookPath = r'C:\temp\addresses.txt'
addressBook = {} # address book held in memory before dumped to file
emailFormatRegex = r'(\w[\w]*)@([\w]+\.[\w]+)'
recordDelimiter = ' | ' # split name | email in file
def LoadAddresses():
  Loads all addresses from file and places
 them in tuple in form (bool, list), where the list is each
 row from the file (a person's name | email). 
 success, lines = (False, [])
 try:
 f = open(addressBookPath, 'r')
 lines = f.readlines()
 f.close()
 success, lines = (True, lines)
 except IOError as e:
 print 'Error opening address book: ', e
 return (success, lines)


The latest style preference in Python is to use with statements for file 
handling, so that would become:


try:
  with f as open(.):
 success,lines = True, f.readlines()
except IOError as e:
  print ...
return (success,lines)


'with' guarantees file closure automatically.



def main():



 (success, lines) = LoadAddresses()
 if not success:
 shouldMakeNewBook = raw_input(textwrap.fill(You do not have
an address book yet.
 Would you like to
create one?))
 if shouldMakeNewBook in ('y', 'ye', 'yes'):
 f = open(addressBookPath, 'w')
 f.close()
 print 'New address book created.', addressBookPath
 else:
 print 'Exiting...'
 return
 else:
 # now that we have the file loaded into memory,
 #  fill out the addressbook from file
 for line in lines:
 splitStr = line.split(recordDelimiter)
 addressBook[splitStr[0]] = splitStr[-1]
 # main input loop (break with 'q' or 'quit' during input)
 while True:
 newPersonNameInput = raw_input('Enter new person\'s name:
(q/quit to stop):')
 if newPersonNameInput.lower() in ('q', 'quit'):
 break
 addressBook[newPersonNameInput] = newPersonNameInput
 while True: # loop until email is in valid format (x@y.z
mailto:x@y.z)
 newPersonEmailInput = raw_input('Enter new person\'s email:
(q/quit to stop):')
 match = re.search(emailFormatRegex, newPersonEmailInput)
 if not match:
 print 'email validation failed... try again.'
 continue


continue is not strictly needed here, but does make the intent clear.



 else:
 addressBook[newPersonNameInput] = newPersonEmailInput
 break # success
 RecordAddresses()
 print addressBook
def RecordAddresses():
  Writes out each address to the file in the form of name |
email. 
 f = open(addressBookPath, 'w')
 for k, v in sorted(addressBook.items()):


Should have a try in case the file fails to open.
Also slightly more pythonic to do

for k,v in open():

There is no point in sorting the data if you are going to read it into a 
dictionary, Python's dictionaries are unsorted. (Unless you plan on 
reading the file manually - in a text editor say)



 #is there a better way to do this without placing a newline
after each row?
 #it's causing multiple line separations when writing back out
to file (because each
 #  time we finish reading, it ends with a trailing newline).
 f.write({0}{1}{2}\n.format(k, recordDelimiter, v))


Sorry, you have to add a newline when writing to the file and strip it 
off when reading. Its just how it is...


--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/



___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Simple Python Address Book (Advice welcome!)

2012-06-17 Thread Wayne Werner


On Sun, 17 Jun 2012, Alan Gauld wrote:


On 17/06/12 02:45, mariocatch wrote:

after each row?
 #it's causing multiple line separations when writing back out
to file (because each
 #  time we finish reading, it ends with a trailing newline).
 f.write({0}{1}{2}\n.format(k, recordDelimiter, v))


Sorry, you have to add a newline when writing to the file and strip it off 
when reading. Its just how it is...


If you're using Python3 or from __future__ import print_function, you can do
this

print(k,v, sep=recordDelimiter, file=f)

Which might make things a little cleaner. There's also the end parameter which
defaults to end='\n'

HTH,
Wayne
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor