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
)
 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


[Tutor] Dictionaries

2012-06-17 Thread Selby Rowley-Cannon
Hello,
            I am having a problem with a small application I am writing. I have 
to have the user input the key, then have the program output the value 
associated with it. A way to inform the user that the key they entered is not 
in the dictionary or somefing would be nice also.

Fank you for your help,
        -Selby
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Dictionaries

2012-06-17 Thread Emile van Sebille

On 6/17/2012 7:14 AM Selby Rowley-Cannon said...

Hello,
I am having a problem with a small application I am writing. I have to
have the user input the key, then have the program output the value
associated with it. A way to inform the user that the key they entered
is not in the dictionary or somefing would be nice also.
Fank you for your help,
-Selby



It's easiest for us to help you when you've posted a copy of your code 
and the resulting traceback information showing the error you're 
getting.  To be complete, include your platform and python version.


Then we can provide you the specific help you need to keep you moving 
forward.


You might also want to read the highly regarded article at
http://www.catb.org/~esr/faqs/smart-questions.html

Emile

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


Re: [Tutor] Dictionaries

2012-06-17 Thread Martin A. Brown

Greetings,

 : I am having a problem with a small application I am writing. I 
 : have to have the user input the key, then have the program output 
 : the value associated with it. A way to inform the user that the 
 : key they entered is not in the dictionary or somefing would be 
 : nice also.

I would agree also with Emile--in the future, you will probably get 
a better answer if you are more specific in your question.  This one 
is a pretty easy question to answer and show you some samples for 
how to approach this with code snippets.

I will assume that userinput is a variable with the contents of 
interest that your user typed.  I will use the variable d to 
represent some dictionary (any dictionary).

  if userinput in d:
  print 'Found', userinput, 'in dictionary, value was', d[userinput]
  else:
  print 'No entry'

Depending on what else you are doing (besides printing), you might 
also look into the get() method of dictionaries:

  default = ''
  string_to_print = d.get(userinput,default)
  print 'You typed %s.  The entry was %s.' % ( userinput, string_to_print)

These are pretty common usage patterns for dictionaries, so you 
might benefit from looking at the other sorts of things that you can 
do with dictionaries.

Good luck,

-Martin

-- 
Martin A. Brown
http://linux-ip.net/
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Dictionaries

2012-06-17 Thread Alan Gauld

On 17/06/12 15:14, Selby Rowley-Cannon wrote:

 I am having a problem with a small application I am writing. I have
to have the user input the key, then have the program output the value
associated with it. A way to inform the user that the key they entered
is not in the dictionary or somefing would be nice also.


So what's the problem?

This sounds a wee bit like a homework assignment and we have a policy of 
not doing those for you...


If you show us what you've done so far, and any errors then you can ask 
for more specific help.


--
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


[Tutor] Dictionary

2012-06-17 Thread Selby Rowley-Cannon
Version: 2.7

OS: Ubuntu 12.04 LTS


I am writing a small translation app for Rydish (A language that exists in the 
same way Klingon does, invented by my company for a[n] RPG).
Here is my current method of translation:

Edictionary = {'English keys':'Rydish values'}
TextEng = raw_input('Please enter your text: ')
if TextEng in Edictionary:
    print(TextEng + ' traslates to ' + Edictionary[TextEng])

But I have found that this is only going to translate one word at a time. I 
thought about a loop of somesort, but I can't seem to find one that won't still 
force the user to translate one word at a time. Can anyone tell me how to 
translate a full sentance/several sentances?
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Dictionary

2012-06-17 Thread James Reynolds
Does this language have grammar independent of english?

If no, just use .split() on the string and loop through that.

If yes, well, its much more complicated
On Jun 17, 2012 2:27 PM, "Selby Rowley-Cannon" 
wrote:

> Version: 2.7
> OS: Ubuntu 12.04 LTS
>
> I am writing a small translation app for Rydish (A language that exists in
> the same way Klingon does, invented by my company for a[n] RPG).
> Here is my current method of translation:
>
> Edictionary = {'English keys':'Rydish values'}
> TextEng = raw_input('Please enter your text: ')
> if TextEng in Edictionary:
> print(TextEng + ' traslates to ' + Edictionary[TextEng])
>
> But I have found that this is only going to translate one word at a time.
> I thought about a loop of somesort, but I can't seem to find one that won't
> still force the user to translate one word at a time. Can anyone tell me
> how to translate a full sentance/several sentances?
>
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>
>
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] python varying mulitple inheritance

2012-06-17 Thread kendy
Hello

I'm new to classes. And I hope the my question isn't too big.

I have electronic test equipment, but thought that a boat example
would be easier. Can you help me untangle my class design?
My problem is basically multiple inheritance, but I want to be
flexible for how many will inherit.

I'll put my example below and also as an attachment.

I'm running Python 2.7 on Linux. Python is the BEST!

Thanks
Ken

 cut here 
#!/usr/bin/env python
"""
Variable Multiple Inheritance.
email: ke...@kendy.org

A boat has a body and is powered by any combination 
of Battery and/or Solar and/or Gas or None.

If a boat is powered, it should have only one emergency_shutoff.
"""

class Body:
""" A boat has a body """
def __init__(self, length):
self.length = length


class Power:
""" 
Super Base class
If a boat is powered. 
"""
def __init__(self, emergency_shutoff):
self.emergency_shutoff = emergency_shutoff

def Emergency():
emergency_shutoff = True


class Battery(Power):
""" sub Child class """
def __init__(self, emergency_shutoff, battery_volt):
self.battery_volt = battery_volt
Power.__init__(self, emergency_shutoff)

def ChargeBattery():
pass

class Solar(Power):
""" sub Child class """
def __init__(self, emergency_shutoff, solar_volt):
self.solar_volt = solar_volt
Power.__init__(self, emergency_shutoff)

def DoSomethingSolar():
pass

class Gasoline(Power):
""" sub Child class """
def __init__(self, emergency_shutoff, liters):
self.liters = liters
Power.__init__(self, emergency_shutoff)

class Boat1(Body):
""" Sailboat """
pass

class Boat2(Body, Gasoline, Battery):
""" Gas, with battery backup powered """
def __init__(self, length, emergency_shutoff, liters, battery_volt):
Body.__init__(self, length)
Power.__init__(self, emergency_shutoff)
Gasoline.__init__(self, emergency_shutoff, liters)
Battery.__init__(self, emergency_shutoff, battery_volt)

class Boat3(Body, Battery, Solar):
""" Electric powered """
def __init__(self, length, emergency_shutoff, solar_volt, battery_volt):
Body.__init__(self, length)
Power.__init__(self, emergency_shutoff)
Solar.__init__(self, emergency_shutoff, solar_volt)
Battery.__init__(self, emergency_shutoff, battery_volt)


def ShowAssembly(assembly_queue):
for workon in assembly_queue:
pass


def main():
""" Acts like a container class"""
assembly_queue = []  # A list of boats to be assembled, in order.

assembly_queue.append(Boat2(30, False, 'half-full', 50))
assembly_queue.append(Boat3(25, False, 30, 10))
assembly_queue.append(Boat1(20))

ShowAssembly(assembly_queue)


if __name__ == '__main__': 
main()

 cut here 



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


Re: [Tutor] python varying mulitple inheritance

2012-06-17 Thread Steven D'Aprano

ke...@kendy.org wrote:

Hello

I'm new to classes. And I hope the my question isn't too big.

I have electronic test equipment, but thought that a boat example
would be easier. Can you help me untangle my class design?
My problem is basically multiple inheritance, but I want to be
flexible for how many will inherit.


Your first problem is that you are misusing inheritance when you should be 
using composition instead.


Inheritance is for "is-a" relationships. For example:

Bob is a Person, so Bob should be an instance of Person class.

A Person is a Mammal, so Person should inherit from Mammal class.

A Mammal is an Animal, so Mammal should inherit from Animal class.


Bob has a wallet, he is not a wallet himself. So the Bob instance should have 
an attribute "wallet", storing an instance of Wallet class. This is called 
composition.


In your example, you have a Boat class. Boat is pretty generic, so it might be 
the top-level class. Or it might be a subclass of Vehicle. You might then 
subclass Boat to give SailingBoat, MotorBoat, SpeedBoat, Battleship, etc.


But boats are not kinds of engines, so it is inappropriate for Boat to inherit 
from Engine. A boat (well, at least some boats) has an engine, so you might do 
something like this:



class Boat:
pass

class SailBoat(Boat):
def __init__(self, sails):
self.sails = sails

class RowBoat(Boat):
def __init__(self, oars):
self.oars = oars

class PowerBoat(Boat):
def __init__(self, engine):
self.engine = engine

class SpeedBoat(PowerBoat):
"""A SpeedBoat is a kind of PowerBoat with an outboard motor."""
def __init__(self):
super(SpeedBoat, self).__init__(outboard_motor)

class Yacht(SailBoat):
"""A Yacht is a kind of SailBoat."""
# Note that the name Yacht is ambiguous, as it is also used for
# a class of small power boats!
def __init__(self):
super(SailBoat, self).__init__(spinnaker)




A boat with both sails and an engine would then use multiple inheritance to 
inherit from both PowerBoat and SailBoat; it would have both an engine and a sail.


Note that when using single-inheritance, you have a choice in how to call the 
parent classes' method:


class K(C):
def method(self, arg):
result = C.method(self, arg)  # Call the parent method directly.
process(result)

or use super:

class K(C):
def method(self, arg):
result = super(K, self).method(arg)  # Let Python find the method.
process(result)


Either way is fine.

BUT once you intend to use multiple inheritance, you MUST use super, or your 
code risks being buggy. NEVER call a superclass method directly using multiple 
inheritance, or even if you might someday want to use multiple inheritance. 
Always use super instead.


(Note: in Python 3, you can simplify the call to super to just super() instead 
of super(K, self). This does not work in Python 2.)


Multiple inheritance is quite tricky to get right, which is why many 
programming languages prohibit it. If you google for "multiple inheritance 
python" you will find many discussions about it, explaining the pros and cons, 
difficulties and alternatives.



One last thing: you will save yourself a lot of pain in the future if you 
stick to a consistent convention for naming things. The usual convention used 
in Python is the classes are named with an initial Capital letter, using 
so-called "CamelCase" if the name has multiple words. Methods, functions, 
attributes and instances are named in lowercase, using underscores to separate 
words: bob_the_builder = Builder(name='Bob').


For more about the suggested (but not compulsory) naming conventions, see this:

http://www.python.org/dev/peps/pep-0008/



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