[Tutor] Creating sub-menus?

2008-12-30 Thread nathan virgil
I was reading the Non-Programmer's Tutorial for Python, and became really
proud of myself when I realized I could create a menu for functions. I
decided to try to take this one step further and see if I could create not
just a menu, but a menu with sub-menus, too! Ultimately, the idea I
came up with is this:

Each menu is a function that prints out options, saves a raw_input as the
variable choice, and returns choice. In the main menu, each option leads to
a sub-menu. After choice is defined, however, the sub-menu "tags" the value
of choice. Each sub-menu has it's own "tag", so that the program can tell
the first choice of sub-menu A from the first choice of sub-menu B. A
sub-menu function would end with code similar to:

choice = raw_input("What's your choice?")
choice = "a" + choice
return choice

Once I get all the menus and other functions out of the way, I get to the
part of the code that actually chooses which function to run. Here, I start
out with:

choice = "start"
current_menu = main_menu()

Then create a loop of while choice !=q, run current_menu, and include a
bunch of statements along the lines of:

if choice == :
current_menu = 
elif choice == 


This seems like it would work, but for some reason, every time I run the
code, it freezes after I give input from the main menu. Can anybody help? I
can show my source code, but indentation doesn't seem to copy/paste very
well, so it may be a bit hard to read...
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Exception Handling

2008-12-30 Thread Jervis Whitley
On Wed, Dec 31, 2008 at 11:18 AM, David  wrote:

>
> . I still need to get it to prduce an error if the year is 0 or 2009, the
> month is 0 or 13 and the day is 0 or 32.


Try using the datetime module to check validity of entered data.

example:
>>> import datetime

>>> datetime.datetime(2008, 12, 32) # should be an error, there are only 31
days in December!
ValueError: day is out of range for month




> david [06:56 PM] opteron ~ $ ./py_get_age.py
> Please enter the date format as:  2008 12 30
>
> What year were you born? 2010
> What month were you born? 14
> What day were you born? 34
> You are -3 years old.


You can also use it to check if the input is in the future.

>>> userdate = datetime.datetime(2010, 1, 1)
>>> datetime.datetime.now() > userdate # a check to see if userdate is in
the past.
False

Cheers,

Jervis
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Exception Handling

2008-12-30 Thread David

Jervis Whitley wrote:



On Wed, Dec 31, 2008 at 8:33 AM, David > wrote:


On Mon, 29 Dec 2008 16:57:44 +0100, spir wrote:

 > On Mon, 29 Dec 2008 09:10:45 -
 > "Alan Gauld" mailto:alan.ga...@btinternet.com>> wrote:
 > >

 >> "bob gailer" mailto:bgai...@gmail.com>> wrote
 >>



Hi David,

If the user enters incorrect data for the month or day, a ValueError 
will still be raised 
on the conversion to integer.


I suggest that you wrap your request for user information in a function 
that does the checking
for you. You can re-use this function for each piece of integer 
information you require from the user.


example:

import time


class BadUserError(Exception):
pass

def get_integer(retrieve, question, attempts=3):
""" 
A small function to attempt to retrieve 
information from a user, given a prompt question.


retrive - any function that will accept a string as an argument
and return a string or otherwise response from the user.
question - a string type question that you would like to ask the user to
respond to.
attempts[optional] - how many times the user can incorrectly
enter data before the BadUserError is raised.
"""

while attempts > 0:
num = retrieve(question)
try:
# try casting the user input as an integer.
return int(num)
except ValueError:
print "Oops, You must enter a number!"

attempts -= 1
raise BadUserError("Too many incorrect tries!") 



WOW, thanks Jervis, I had to edit some of my mistakes to get it to work 
right if your birthday is today. I also looked at tm_year, tm_mon, and 
tm_day. I still need to get it to prduce an error if the year is 0 or 
2009, the month is 0 or 13 and the day is 0 or 32.

david [06:56 PM] opteron ~ $ ./py_get_age.py
Please enter the date format as:  2008 12 30

What year were you born? 2010
What month were you born? 14
What day were you born? 34
You are -3 years old.

Here is a link to the current program;
http://dwabbott.com/code/
Thanks again everyone,
-david


--
Powered by Gentoo GNU/LINUX
http://www.linuxcrazy.com
pgp.mit.edu

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Exception Handling

2008-12-30 Thread Kent Johnson
On Tue, Dec 30, 2008 at 4:33 PM, David  wrote:
> Thank you all for the tips. Next to do is to get the dates in one raw_input
> with the correct format and to check for a valid year, month, and day. Here
> is what I have now;

>ynum = int(time.strftime("%Y", time.gmtime())) - int(yr)
>mnum = int(time.strftime("%m", time.gmtime()))
>dnum = int(time.strftime("%d", time.gmtime()))

Yikes! How about time.gmtime().tm_year, etc, instead of all the calls
to strftime() and int()? And you might want to put the value of
time.gmtime() in a variable so you always use the same value, just in
case someone runs your program on New Year's Eve at midnight.

You might also want to look at the datetime module, in particular
datetime.timedelta.

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] optimize code

2008-12-30 Thread Kent Johnson
On Tue, Dec 30, 2008 at 3:42 PM, Norman Khine  wrote:
> Hi,
> I have an updated version at http://paste.lisp.org/display/72843
> Thanks for the advice, the code is much smaller and leaner than the first
> attempt.

The level2-4 code could all be consolidated into a loop:

for levelName in 'level2 level3 level4'.split():
  level = context.get_form_value(levelName)
  if level is None: break
  title = '%s: %s' % (title, level)

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Exception Handling

2008-12-30 Thread Jervis Whitley
On Wed, Dec 31, 2008 at 8:33 AM, David  wrote:

>  On Mon, 29 Dec 2008 16:57:44 +0100, spir wrote:
>>
>>  > On Mon, 29 Dec 2008 09:10:45 -
>>> > "Alan Gauld"  wrote:
>>> > >
>>>
 >> "bob gailer"  wrote
 >>

> >> > Also IMHO it is bad design to put a lot of code inside a try
> block.
> >> > In this case the user might make a mistake on day and then is
> forced
> >> > to reenter the year and month!
>
 >> >> Obviously there is no absolute rule here but I disagree. One of
 the
 >> biggest advantages of try/except error handling is that it keeps the
 >> mess of handling errors out of the main logic of the code. This has
 two
 >> effects:
 >> 1) Code that is much easier to read
 >> 2) a lot less error handling code

>>> Also, I'd rather ask for the dates in one raw_input, cuts much of the
>> mess for the user (although it's a bit of extra codes)
>>
> Thank you all for the tips. Next to do is to get the dates in one raw_input
> with the correct format and to check for a valid year, month, and day. Here
> is what I have now;
> #!/usr/bin/python
> import time
>
> curr_date = time.strftime("%Y %m %d", time.gmtime())
> print "Please enter the date format as: ", curr_date
>
> while True:
>yr = raw_input("\nWhat year were you born? ")
>mn = raw_input("What month were you born? ")
>dy = raw_input("What day were you born? ")
>try:
>ynum = int(time.strftime("%Y", time.gmtime())) - int(yr)
>mnum = int(time.strftime("%m", time.gmtime()))
>dnum = int(time.strftime("%d", time.gmtime()))
>except ValueError:
>print "Oops, You must enter a number!"
>else:
>mn = int(mn)
>dy = int(dy)
>
>if mn <= mnum:
>print "You are", ynum, "years old."
>break
>elif mn == mnum and dy < dnum:
>print "You are", ynum, "years old."
>break
>else:
>ret = int(ynum) - 1
>print "You are", ret, "years old."
>break
>
>
> --
> Powered by Gentoo GNU/LINUX
> http://www.linuxcrazy.com
> pgp.mit.edu
>
> ___
> Tutor maillist  -  Tutor@python.org
> http://mail.python.org/mailman/listinfo/tutor
>

Hi David,

If the user enters incorrect data for the month or day, a ValueError will
still be raised
on the conversion to integer.

I suggest that you wrap your request for user information in a function that
does the checking
for you. You can re-use this function for each piece of integer information
you require from the user.

example:

import time


class BadUserError(Exception):
pass

def get_integer(retrieve, question, attempts=3):
"""
A small function to attempt to retrieve
information from a user, given a prompt question.

retrive - any function that will accept a string as an argument
and return a string or otherwise response from the user.
question - a string type question that you would like to ask the user to
respond to.
attempts[optional] - how many times the user can incorrectly
enter data before the BadUserError is raised.
"""

while attempts > 0:
num = retrieve(question)
try:
# try casting the user input as an integer.
return int(num)
except ValueError:
print "Oops, You must enter a number!"

attempts -= 1
raise BadUserError("Too many incorrect tries!")

curr_date = time.strftime("%Y %m %d", time.gmtime())
print "Please enter the date format as: ", curr_date


yr = get_integer(raw_input, "\nWhat year were you born? ")
mn = get_integer(raw_input, "What month were you born? ")
dy = get_integer(raw_input, "What day were you born? ")

today = time.gmtime()

ynum = today.tm_year - yr
mnum = today.tm_mon
dnum = today.tm_mday

if mn <= mnum:
print "You are", ynum, "years old."
elif mn == mnum and dy < dnum:
print "You are", ynum, "years old."
else:
ret = int(ynum) - 1
print "You are", ret, "years old."
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Exception Handling

2008-12-30 Thread David

On Mon, 29 Dec 2008 16:57:44 +0100, spir wrote:


> On Mon, 29 Dec 2008 09:10:45 -
> "Alan Gauld"  wrote:
> 
> 

>> "bob gailer"  wrote
>> 

>> > Also IMHO it is bad design to put a lot of code inside a try block.
>> > In this case the user might make a mistake on day and then is forced
>> > to reenter the year and month!
>> 
>> Obviously there is no absolute rule here but I disagree. One of the

>> biggest advantages of try/except error handling is that it keeps the
>> mess of handling errors out of the main logic of the code. This has two
>> effects:
>> 1) Code that is much easier to read
>> 2) a lot less error handling code
Also, I'd rather ask for the dates in one raw_input, cuts much of the 
mess for the user (although it's a bit of extra codes)
Thank you all for the tips. Next to do is to get the dates in one 
raw_input with the correct format and to check for a valid year, month, 
and day. Here is what I have now;

#!/usr/bin/python
import time

curr_date = time.strftime("%Y %m %d", time.gmtime())
print "Please enter the date format as: ", curr_date

while True:
yr = raw_input("\nWhat year were you born? ")
mn = raw_input("What month were you born? ")
dy = raw_input("What day were you born? ")
try:
ynum = int(time.strftime("%Y", time.gmtime())) - int(yr)
mnum = int(time.strftime("%m", time.gmtime()))
dnum = int(time.strftime("%d", time.gmtime()))
except ValueError:
print "Oops, You must enter a number!"
else:
mn = int(mn)
dy = int(dy)

if mn <= mnum:
print "You are", ynum, "years old."
break
elif mn == mnum and dy < dnum:
print "You are", ynum, "years old."
break
else:
ret = int(ynum) - 1
print "You are", ret, "years old."
break


--
Powered by Gentoo GNU/LINUX
http://www.linuxcrazy.com
pgp.mit.edu

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] optimize code

2008-12-30 Thread Norman Khine

Hi,
I have an updated version at http://paste.lisp.org/display/72843
Thanks for the advice, the code is much smaller and leaner than the 
first attempt.

Norman

Kent Johnson wrote:

On Tue, Dec 30, 2008 at 9:32 AM, Norman Khine  wrote:

Hello,
I have this piece of code which I would like to further streamline it.


There is no need to re-create the mapping at each level of if; you can
just add new key/value pairs. For example
if level2 is not None:
mapping['level2'] = level2


What the code does is that it takes a form value and builds a dictionary


It seems that the you are really returning a string, or at least
building a string to pass to gettext(). I would have each if statement
just append to the string. That would consolidate the return
statements. For example, if value is the string being built,
if level2 is not None:
value = '%s: %s' % (value, level2)

Kent


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] IDLE problems

2008-12-30 Thread Kent Johnson
On Tue, Dec 30, 2008 at 12:05 PM, Pearce Michal
 wrote:
> ok, so I just started working with python, however I have been working with
> Java for awhile, and am fairly familiar with it. my problem with Python is
> for the IDLE editor, and it is this: the return key, or enter key not only
> moves the editor to the next line, but also executes the script.

IDLE has two kinds of windows - a shell window, which executes
commands as they are typed, and an editor window. The shell window is
handy for interactive exploration but, as you discovered, pretty
useless for creating a real program.

File / New Window will open an editor window that behaves the way you want.

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


[Tutor] IDLE problems

2008-12-30 Thread Pearce Michal
ok, so I just started working with python, however I have been working with
Java for awhile, and am fairly familiar with it. my problem with Python is
for the IDLE editor, and it is this: the return key, or enter key not only
moves the editor to the next line, but also executes the script. so if I
tried to enter a line like:

x = input("enter a value: ")
if x == 1:
 print "you entered one"
elif x == 2:
 print "you entered two"
elif x == 3:
 print "you entered three"

after I entered the line " x = input("enter a value: ") and ask "enter a
value: " I would type a number, and the script would end.

basically, I am wondering if there is a way to make it not execute when you
press return. I looked through the options, and it said the F5 key is what
executes the script, (but I am on a laptop, so pressing F5 turns up the
volume)


anyway, please help!
thanking to you in advance,

Yoda Almighty.
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] optimize code

2008-12-30 Thread Norman Khine



Kent Johnson wrote:

On Tue, Dec 30, 2008 at 9:32 AM, Norman Khine  wrote:

Hello,
I have this piece of code which I would like to further streamline it.


There is no need to re-create the mapping at each level of if; you can
just add new key/value pairs. For example
if level2 is not None:
mapping['level2'] = level2


What the code does is that it takes a form value and builds a dictionary


It seems that the you are really returning a string, or at least
building a string to pass to gettext(). I would have each if statement
just append to the string. That would consolidate the return
statements. For example, if value is the string being built,
if level2 is not None:
value = '%s: %s' % (value, level2)


Thanks, it is very helpful.

Norman
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] optimize code

2008-12-30 Thread Kent Johnson
On Tue, Dec 30, 2008 at 9:32 AM, Norman Khine  wrote:
> Hello,
> I have this piece of code which I would like to further streamline it.

There is no need to re-create the mapping at each level of if; you can
just add new key/value pairs. For example
if level2 is not None:
mapping['level2'] = level2

> What the code does is that it takes a form value and builds a dictionary

It seems that the you are really returning a string, or at least
building a string to pass to gettext(). I would have each if statement
just append to the string. That would consolidate the return
statements. For example, if value is the string being built,
if level2 is not None:
value = '%s: %s' % (value, level2)

Kent
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


[Tutor] optimize code

2008-12-30 Thread Norman Khine

Hello,
I have this piece of code which I would like to further streamline it.

http://paste.lisp.org/display/72830

More specifically, I feel there is too many if statements.

What the code does is that it takes a form value and builds a dictionary

http://localhost/;search?level1=air-brokers-or-charters

returns

{'root_title': u'Expert Travel', 'here_title': 'Air brokers/air 
charter', 'country': 'UK'}


http://localhost/;search?level1=air-brokers-or-charters&level2=East+Anglia

returns

{'root_title': u'Expert Travel', 'level2': 'East Anglia', 'here_title': 
'Air brokers/air charter', 'country': 'UK'}



etc..

Thanks

Norman




___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Exception Handling

2008-12-30 Thread Lie Ryan
On Mon, 29 Dec 2008 16:57:44 +0100, spir wrote:

> On Mon, 29 Dec 2008 09:10:45 -
> "Alan Gauld"  wrote:
> 
> 
>> "bob gailer"  wrote
>> 
>> > Also IMHO it is bad design to put a lot of code inside a try block.
>> > In this case the user might make a mistake on day and then is forced
>> > to reenter the year and month!
>> 
>> Obviously there is no absolute rule here but I disagree. One of the
>> biggest advantages of try/except error handling is that it keeps the
>> mess of handling errors out of the main logic of the code. This has two
>> effects:
>> 1) Code that is much easier to read
>> 2) a lot less error handling code
>> 
>> Using "big bite" try/except does mean the except clauses become more
>> complex if you want to find out exactly which line caused the error, as
>> in the example above, but it can be done by examining the traceback,
>> but in general I much prefer to wrap logical blocks of code using
>> try/except rather than only one or two lines
>  
> I often use the else clause of try...except. This allows putting only
> the minimum problematic code lines inside the try block, which is good
> both for legibility andto avoid catching unexpected errors. The else
> will be executed only in case of no exception:

I think it's better to put less in a try-clause so I'd rather not catch 
errors on the raw_input, and put validation code in a function, which I'd 
enclose in a try block, like this:

while True:
yr = raw_input("What year were you born? ")
mn = raw_input("What month were you born? ")
dy = raw_input("What day were you born? ")

try:
date = is_valid_date(yr, mn, dy)
except InvalidDate, e:
# e might contain input not a number, or there is no 31 february
print 'You entered an Invalid Date: ', e
else:
do_things(date)

Also, I'd rather ask for the dates in one raw_input, cuts much of the 
mess for the user (although it's a bit of extra codes)

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


[Tutor] reply

2008-12-30 Thread prasad rao
Hello.   Thank you.Just a small change at the optional parameter made
all the
difference. It seems to be a mirracle.It is an enlitenment to me.
Thank you.
Prasad
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor