Re: [Tutor] design question

2010-09-11 Thread Knacktus

Am 10.09.2010 16:11, schrieb Albert-Jan Roskam:

Hi Jan,

Here's a screendump of my program: http://nl.tinypic.com/r/2qtlojc/7 .
This might make my description a little bit clearer. The beautiful
sunset will in reality be a dull, handwritten form. ;-)

Regarding the iterator pattern, I was referring to this:
http://www.suttoncourtenay.org.uk/duncan/accu/pythonpatterns.html#iterators-and-generators
Inside my program I have to keep a list of all the image files that are
scheduled for data entry. The main purpose is to be able to read in the
image files one by one. Another one of the purposes of this list is to
show some information on the title bar. Currently, my program only has a
'next' button and the fact that implementing a 'previous' button is
causing problems suggests to me that I have to look for a more
fundamentally better solution.
Sounds to me that the easiest solution would be to simply use a list to 
hold the images, a reference to the current image and your desired 
methods in a class.


class ImageStack(object):

def __init__(self, images=None)
self.images = images or []
self.current_image = None

def next_image(self):
if self.current_image:
current_index = self.images.index(self.current_image)
try:
next_image = self.images[current_index + 1]
except IndexError:
print "All images done" # or return the first one
else:
next_image = self.images[0]
self.current_image = next_image
return next_image

def prev_image(self):
if self.current_image:
current_index = self.images.index(self.current_image)
try:
prev_image = self.images[current_index - 1]
self.current_image = next_image
return next_image
except IndexError:
print "There's no prev image"
print "There's no current image"


You could also track the current_index instead of the current_image. 
That would make the class easier, but how to track the current image 
depends on what other methods you need.


HTH,

Jan


Cheers!!
Albert-Jan

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


Re: [Tutor] design question

2010-09-11 Thread Steven D'Aprano
On Sat, 11 Sep 2010 12:11:37 am Albert-Jan Roskam wrote:

> Inside my program I have to keep a list of all the image files that
> are scheduled for data entry. 

Sounds like you need to keep a list of all the image files that are 
scheduled for data entry then.


> The main purpose is to be able to read 
> in the image files one by one. Another one of the purposes of this
> list is to show some information on the title bar. 

No it isn't. You don't need a list of image files in order to show "some 
information" in the title bar (unless that information is the list of 
files). From your earlier post, you want to show:

filename 23 of 245 (9.4%)

or similar. For that, all you need is three pieces of information:

* the name of the current file
* the number of the current file
* the total number of files

You don't need all 245 files for that.

I'm being pedantic here. Obviously you need the list of files 
*somewhere*, and you need it for other reasons, but you don't *need* a 
list of 243 files in order to show the name of one of them!

You may decide that it is *convenient* to give the function which 
changes the title bar access to the entire list, but it's not a 
*requirement*. Think about alternatives: 

def change_titlebar(name, count, total):
template = "%s %d of %d (%.1f %%)"
percentage = count*100.0/total
title = template % (name, count, total, percentage)
do_magic_with(title)  # whatever it takes to change the title

It doesn't need the entire list.


> Currently, my 
> program only has a 'next' button and the fact that implementing a
> 'previous' button is causing problems suggests to me that I have to
> look for a more fundamentally better solution.

Sounds to me that you *don't* want the iterator pattern. The iterator 
pattern generally means that you step forward through each item. If you 
want to advance backwards or forwards, something with random access is 
probably better. That would probably mean a list.

Don't be too hung up about "design patterns". Most design patterns just 
exist to work around limitations of the language, lack of power, or 
slavish devotion to object oriented programming when the problem is 
crying out for a functional or procedural solution. Don't be afraid to 
write functions instead of classes -- there's no need for a 
TitlebarManipulator class just to change the titlebar.

My solution would be to keep *two* pieces of information:

* the list of filenames;
* the current position in that list

Set the current position to 0, and have the Next button add one to the 
position and refresh the page, and Prev subtract one and refresh the 
page. Obviously you need code to ensure that the position doesn't go 
out of bounds, code to save the data in the fields, and so forth. The 
page refresh code should do something like:

* given the current position, extract the filename to use;
* change the title bar;
* open and display the appropriate image;
* pre-populate any fields;
etc.

Good luck!


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


Re: [Tutor] What Design Pattern for Document class (NOT URGENT)

2010-09-11 Thread Knacktus

Hi Karim,

it's difficult to comment as to me the problem is not quite clear.
But I try ;-)

You have a complex xml and need to read different data types. For each 
type you have certain rules, how to extract them from the xml (docrules).


You could create a DocRule class, that do nothing but hold instructions 
of how to read and write the xml for each data, e.g. xpathes. For each 
data type you create an instance of that class.


Then, in your main xml Reader class you define a method, that accepts a 
doc rule instance as argument.


doc_rule_1 = DocRule("some_pattern")
doc_rule_2 = DocRule("another_pattern")

class Reader(object):

def __init__(self, filename):
... # create the etree

def get_data_by_doc_rule(self, doc_rule):
... # search the tree based on the doc_rule
... # you can use any type here if it has the correct mehtods

In your "get_data_by_doc_rule" method you can use any type for the 
doc_rule, that has corresponding attributes and methods ("duck typing"). 
So you have a lot of flexibility of how to create your doc_rules.


Is that what you're looking for?

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


Re: [Tutor] exceptions problem

2010-09-11 Thread Francesco Loffredo

On 11/09/2010 1.56, bob gailer wrote:

  On 9/10/2010 2:48 PM, Roelof Wobben wrote:



Date: Fri, 10 Sep 2010 20:23:09 +0200
From: f...@libero.it
To: tutor@python.org
Subject: Re: [Tutor] exceptions problem
...
> ...
>  Roelof
Francesco
Thank you.
I never thought that you can use a float and a integer to look if the number is 
a integer.


You can't.

How enlightening! A REAL Tutor advice...

Francesco
Nessun virus nel messaggio in uscita.
Controllato da AVG - www.avg.com
Versione: 9.0.851 / Database dei virus: 271.1.1/3126 -  Data di rilascio: 
09/10/10 09:08:00
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Trapping HTTP Authentication Failure

2010-09-11 Thread Michael Powe
On Sat, Sep 11, 2010 at 01:28:26AM +0200, Evert Rol wrote:
> > My script to call a web service authenticates.  
 
> Sorry, but where is the (full) script? I missed an attachment or (preferably) 
> a link.

Hello,

Sorry, the verb of the sentence is "authenticates," as in, "My script
... authenticates."

But I can show the authentication portion.

8<-- start >8

# Creates an authentication object with the credentials for a given URL
def createPasswordManager(headers) :
passwordManager = urllib2.HTTPPasswordMgrWithDefaultRealm()
passwordManager.add_password(None,overview_url,headers[0],headers[1])
return passwordManager

# Creates an authentication handler for the authentication object created above
def createAuthenticationHandler(passwordManager) :
authenticationHandler = urllib2.HTTPBasicAuthHandler(passwordManager)
return authenticationHandler

# Creates an opener that sets the credentials in the Request
def createOpener(authHandler) :
return urllib2.build_opener(authHandler)


# Retrieves the data
def getData(authHeaders) :
opener = 
createOpener(createAuthenticationHandler(createPasswordManager(authHeaders)))
data = opener.open(overview_url)
return data
8<--- end >8

So, to restate the question, how can I trap an exception in the cases
in which authentication fails? 

Right now, the whole script is complete and working (thanks for your
help with my other exception-handling question).  Except for the case
of bad credentials.  The use case is that the user misspells a
username or password or puts in a wrong account information.  Then, I
don't want them to sit for 10 minutes while the script makes 30 data
connections, retries and fails each time.

Thanks.

mp

-- 
Michael Powemich...@trollope.orgNaugatuck CT USA
I hate a fellow whom pride, or cowardice, or laziness drives into a
corner, and who does nothing when he is there but sit and ; let
him come out as I do, and . -- Samuel Johnson


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


Re: [Tutor] Exception Handling and Stack traces

2010-09-11 Thread Steven D'Aprano
On Sat, 11 Sep 2010 04:47:13 am Michael Powe wrote:

> No problem, I am working on getting this sorted out.  The
> documentation seems to be written as reminder for people who already
> know how this stuff works, rather than as a clear explanation for
> anybody working with it.

That's because the job of documentation is to be documentation, not a 
tutorial.

Admittedly, sometimes it's hard to draw a line between the two, but you 
have to assume *some* knowledge of the reader -- imagine if every time 
you tried to document some piece of code, you had to start explaining 
what variables are.

In this case, the Fine Manual is plenty clear. The example in the 
tutorial shows:

try:
...
except ValueError:
...

http://docs.python.org/tutorial/errors.html#handling-exceptions


There's no need to add an error message to the ValueError:

# this does NOT work
except ValueError("I never know what message to expect"):

There's nothing in any of the documentation I've ever seen that suggests 
that catching an exception requires you to specify the exact error 
message. Since error messages are subject to change without warning, or 
translation into other languages, this wouldn't be practical even if it 
could work (which it doesn't).


It does require a bit more knowledge to decipher the main documentation:

http://docs.python.org/reference/compound_stmts.html#try
http://docs.python.org/reference/executionmodel.html#exceptions

but as I said, this is not a tutorial. They are written for 
non-beginners. If you need a tutorial, do the tutorial, and don't 
expect the documentation to be all things to all users.

Or read example code in the standard library. If you pick a random 
module and read it, you can expect to find exception handling. See what 
other coders do.


> Eventually, I arrived at a workable conclusion by wrapping only the
> call in main and using your suggested 'as' clause.

If you're focused on the 'as' clause part, you're still missing the 
point.


> This successfully 
> suppresses the traceback and gives a useable error message. 
> Although, in the case of URLError, 'getaddrinfo failed' may not
> actually mean much to the end user, it'll have to do.
>
> I don't like the fact that I cannot locate my thrown exception at the
> point of throwing

Of course you can.



> -- i.e., I don't necessarily mind catching the 
> exception in main but I would like to be able to print out exactly
> where the exception occurred.  This is more useful when
> troubleshooting. 

Err, that's exactly what the stacktrace is for -- it shows the execution 
chain that failed.

> However, an entire stacktrace is unacceptably verbose.

For who? You, the developer, or for an end user?

If you mean for an end user, I agree. Stack traces aren't written for 
them. 

If you mean for you, the developer, then I'm sorry, but I find that a 
bogus attitude. It's true that *most of the time* the only part of the 
stack trace that you (generic you) will look at is the final call, but 
there are many, many times when you need to see the entire call chain 
to determine what's going on.

Anyway, be glad this is Python. In a former life, I worked for a company 
that had just installed a SAP accounting application. One day the 
application crashed, and printed out a stack trace direct to the 
printer. It was over fifty pages of tightly-written 9pt font. 
Seriously.

We called the developers and asked what they wanted us to do with it, 
and they said to throw it out.


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


Re: [Tutor] classmethod, staticmethod functions (decorator related)

2010-09-11 Thread Steven D'Aprano
On Sat, 11 Sep 2010 12:35:48 am Huy Ton That wrote:
> I am reading the decorator section within Expert Python Programming
> and I am very confused in the first example, of a method that was
> done before decorators. It reads:
>
> class WhatFor(object):
> def it(cls):
> print 'work with %s' % cls
> it = classmethod(it)
> def uncommon():
> print 'I could be a global function'
> uncommon = staticmethod(uncommon)
>
> But I can't seem to understand the above. Under what circumstance
> would staticmethod be useful? I am just deriving that you are not
> passing self.


They usually aren't, in Python, because if you think you want a 
staticmethod, you're usually better off making it an ordinary function. 
E.g. instead of this:


class Food(object):
@staticmethod
def spam(x):
return "spam"
def ham(self):
return "%s is a processed meat-like substance" % self.spam()


it is often better to do this:


class Food(object):
def ham(self):
return "%s is a processed meat-like substance" % spam()

def spam(x):
return "spam"



There are exceptions, but you can consider that staticmethod is rarely 
needed. 



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


Re: [Tutor] exceptions problem

2010-09-11 Thread Steven D'Aprano
On Sat, 11 Sep 2010 09:56:41 am bob gailer wrote:
> > I never thought that you can use a float and a integer to look if
> > the number is a integer.
>
> You can't.

What? Of course you can.

def is_integer(x):
"""Return True if x is an integer."""
try:
return 1.0*x == int(x)
except (TypeError, ValueError):
return False



And in use:

>>> is_integer("12")
False
>>> is_integer(2.3)
False
>>> is_integer(2.0)
True
>>> is_integer(2)
True


The multiplication by 1.0 is not actually needed, but it doesn't hurt.

[thinks more carefully...] Actually it does hurt:

>>> is_integer(Decimal(2))
False


So although you *can* use float and int to determine if a value is an 
integer, it's best to avoid the float.




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


Re: [Tutor] exceptions problem

2010-09-11 Thread Peter Otten
Steven D'Aprano wrote:

> On Sat, 11 Sep 2010 09:56:41 am bob gailer wrote:
>> > I never thought that you can use a float and a integer to look if
>> > the number is a integer.
>>
>> You can't.
> 
> What? Of course you can.
> 
> def is_integer(x):
> """Return True if x is an integer."""
> try:
> return 1.0*x == int(x)
> except (TypeError, ValueError):
> return False

> The multiplication by 1.0 is not actually needed, but it doesn't hurt.
> 
> [thinks more carefully...] Actually it does hurt:
> 
 is_integer(Decimal(2))
> False

Another problem is the limited precision of floats:

>>> x = 10**22
>>> 1.0*x == x
True
>>> x *= 10
>>> 1.0*x == x
False
 
Peter

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


Re: [Tutor] changing list index start

2010-09-11 Thread Francesco Loffredo

On 10/09/2010 23.36, Rance Hall wrote:

I'm using the following function style I found on the net to create
menus for a command line python script:

def mainmenu():
 # the main menu
 todolist()
 mainmenuoptions = ['Clients','Jobs','Billing','Quotes','To Do
Items','Employee','Exit']
 mainmenucalls = [clientsmenu, jobsmenu, billingmenu, quotesmenu,
todomenu, empmenu, quit]
 for i,option in enumerate(mainmenuoptions):
 print('%s. %s' % (i, option))
 mainchoice = int(input('\nYour Choice? '))
 clearscreen(osname)
 mainmenucalls[mainchoice]()
 return

It works well, but the first item is the list is item 0.  This is
normal in most computing situations, but because this index is part of
the output It would be nice if the first item in the list is item 1.

php provided a way to change this, but I can find no documentation
that says python can do this as well.
I don't know of any way to change this, but I can think may ways to 
bypass the "problem"  or to make good use of it. For example:


mainmenuoptions = ["Main Menu:\n", 
'Clients','Jobs','Billing','Quotes','To Do Items','Employee','Exit']
mainmenucalls = [do_nothing, clientsmenu, jobsmenu, billingmenu, 
quotesmenu, todomenu, empmenu, quit]

def do_nothing()
pass

What about this?

Francesco
Nessun virus nel messaggio in uscita.
Controllato da AVG - www.avg.com
Versione: 9.0.851 / Database dei virus: 271.1.1/3126 -  Data di rilascio: 
09/10/10 09:08:00
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] hashlib problems

2010-09-11 Thread Steven D'Aprano
On Sat, 11 Sep 2010 06:54:39 am Rance Hall wrote:

> I will apologize for the tone and using the word "bug" without
> sufficient evidence, and I will be more thorough in the future.

Using the word "bug" itself isn't the problem. Nor is it that you made a 
mistake -- we've all done that. A few days ago I wrote to the 
comp.lang.python newsgroup with what I was *convinced* was a bug in the 
doctest module. After somebody wrote back and said they didn't get the 
same results as me, I tried it again, and *I* couldn't get the same 
results as me!

You wrote:

"Either there is a bug in the module hashlib, or the module changed and 
the docs don't keep up."

But you neglected the third all-important option:

"...or I'm missing something here and have made a mistake."

Leaving out the third possibility makes all the difference in how people 
will react to you misdiagnosing a non-bug as a bug. Particularly if 
you're still a beginner, or a newbie to Python.

If you're Guido van Rossum (Python's creator), or the Timbot (Tim 
Peters, who designed Python's amazing sort routine), and you 
misdiagnose a bug, nobody will blink. We all make mistakes. But when 
you're a newbie (generic you, not you personally), and haven't learned 
the language yet, and you think you've spotted something which tens or 
hundreds of thousands of experienced Python coders have failed to 
notice *without* considering that maybe the bug is in *your* code, 
well, people will either write you off as arrogant or laugh in your 
face. (Still generic you.)

Anyway, welcome on board!


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


Re: [Tutor] Trapping HTTP Authentication Failure

2010-09-11 Thread Evert Rol
>>> My script to call a web service authenticates.  
> 
>> Sorry, but where is the (full) script? I missed an attachment or 
>> (preferably) a link.
> 
> Hello,
> 
> Sorry, the verb of the sentence is "authenticates," as in, "My script
> ... authenticates."

Sorry, misread that.
Although code does help :-). 
I assume the rest of the code is just the loop around the items you want to 
fetch, calling getData each time with a new URL.


> But I can show the authentication portion.
> 
> 8<-- start >8
> 
> # Creates an authentication object with the credentials for a given URL
> def createPasswordManager(headers) :
>passwordManager = urllib2.HTTPPasswordMgrWithDefaultRealm()
>passwordManager.add_password(None,overview_url,headers[0],headers[1])
>return passwordManager
> 
> # Creates an authentication handler for the authentication object created 
> above
> def createAuthenticationHandler(passwordManager) :
>authenticationHandler = urllib2.HTTPBasicAuthHandler(passwordManager)
>return authenticationHandler
> 
> # Creates an opener that sets the credentials in the Request
> def createOpener(authHandler) :
>return urllib2.build_opener(authHandler)
> 
> 
> # Retrieves the data
> def getData(authHeaders) :
>opener = 
> createOpener(createAuthenticationHandler(createPasswordManager(authHeaders)))
>data = opener.open(overview_url)
>return data
> 8<--- end >8
> 
> So, to restate the question, how can I trap an exception in the cases
> in which authentication fails? 
> 
> Right now, the whole script is complete and working (thanks for your
> help with my other exception-handling question).  Except for the case
> of bad credentials.  The use case is that the user misspells a
> username or password or puts in a wrong account information.  Then, I
> don't want them to sit for 10 minutes while the script makes 30 data
> connections, retries and fails each time.

I'm not sure what you're exactly doing here, or what you're getting, but I did 
get curious and dug around urllib2.py. Apparently, there is a hardcoded 5 
retries before the authentication really fails. So any stack trace would be the 
normal stack trace times 5. Not the 30 you mentioned, but annoying enough 
anyway (I don't see how it would fail for every element in the loop though. 
Once it raises an exception, the program basically ends).
I don't know why it's hard-coded that way, and not just an option with a 
default of 5, but that's currently how it is (maybe someone else on this list 
knows?).
If that's what you're finding, perhaps the quickest way is to subclass 
urllib2.HTTPBasicAuthHandler, and override the http_error_auth_reqed method 
(essentially keeping it exactly the same apart from the hard-coded 5).

Otherwise, I'm afraid I still don't know what's the problem you're having.

  Evert

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


Re: [Tutor] smtp connection problem --- socket error 10061

2010-09-11 Thread Steven D'Aprano
On Sat, 11 Sep 2010 04:09:20 am goodh...@gmail.com wrote:
>   I could not connect with gmail smtp server in Vista 32( worked ok
> in XP 32). Both vista and xp have same anti-virus software.
>
> >>> smtplib.SMTP("smtp.gmail.com",587)
>
> Traceback (most recent call last):
>File "", line 1, in 
>  smtplib.SMTP("smtp.gmail.com",587)
>File "C:\Program Files\Python25\lib\smtplib.py", line 244, in
> __init__ (code, msg) = self.connect(host, port)
>File "C:\Program Files\Python25\lib\smtplib.py", line 310, in
> connect raise socket.error, msg
> error: (10061, 'Connection refused')


Works for me:

>>> import smtplib
>>> smtplib.SMTP("smtp.gmail.com",587)



> I am using IPV4 for my vista wireless connection. No improvement with
> firewall disabled.

Which firewall? On the router, or on Windows?

Perhaps your ISP is blocking the port, or maybe it was just that Gmail 
was not allowing connections at that moment.

Have you verified that you can connect to the server outside of Python 
(say, with telnet)?


> Any one has this problem? any solution?

Have you tried Googling? The second hit for "smtp 10061, 'Connection 
refused'" is this:

http://bytes.com/topic/python/answers/32889-sending-mail-smtp-connection-refused-but-smtp-server-isrunning

Does that help?


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


Re: [Tutor] Trapping HTTP Authentication Failure

2010-09-11 Thread Michael Powe
On Sat, Sep 11, 2010 at 01:09:31PM +0200, Evert Rol wrote:

> >>> My script to call a web service authenticates.  
> > 
> >> Sorry, but where is the (full) script? I missed an attachment or 
> >> (preferably) a link.
> > 
> > Hello,
> > 
> > Sorry, the verb of the sentence is "authenticates," as in, "My script
> > ... authenticates."
> 
> Sorry, misread that.
> Although code does help :-). 

> I assume the rest of the code is just the loop around the items you
> want to fetch, calling getData each time with a new URL.

Yes, it's looping over a list.  Specifically, at startup the script
does a date detection and creates a list of identifiers for each week
of the year up to the point of invocation.  So, if it is week 36, I
get a list of 36 weeks.

Then, the data retrieval and processing takes place like this:

[processData(w) for w in weeks]

Where the processData function calls getData() and passes in the
current week to process.

[ code snipped ]
 
> > So, to restate the question, how can I trap an exception in the cases
> > in which authentication fails? 

[ snip ]
 
> I'm not sure what you're exactly doing here, or what you're getting,
>but I did get curious and dug around urllib2.py. Apparently, there is
>a hardcoded 5 retries before the authentication really fails. So any
>stack trace would be the normal stack trace times 5. Not the 30 you
>mentioned, but annoying enough anyway (I don't see how it would fail
>for every element in the loop though. Once it raises an exception,
>the program basically ends).

It never throws an exception.  Or, if it does, something about the way
I'm calling suppresses it.  IOW, I can put in a bogus credential and
start the script and sit here for 5 minutes and see nothing.  Then ^C
and I get a huge stacktrace that shows the repeated calls.  After the
timeout on one element in the list, it goes to the next element, times
out, goes to the next.

> I don't know why it's hard-coded that way, and not just an option
> with a default of 5, but that's currently how it is (maybe someone
> else on this list knows?).

I don't know, but even if I could set it to 1, I'm not helped unless
there's a way for me to make it throw an exception and exit the loop. 

> If that's what you're finding, perhaps the quickest way is to
> subclass urllib2.HTTPBasicAuthHandler, and override the
> http_error_auth_reqed method (essentially keeping it exactly the
> same apart from the hard-coded 5).

Now there's a challenge!  ;-)

Thanks.

mp

-- 
Michael Powemich...@trollope.orgNaugatuck CT USA


Is it time for your medication or mine?


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


Re: [Tutor] Trapping HTTP Authentication Failure

2010-09-11 Thread Evert Rol


>> I'm not sure what you're exactly doing here, or what you're getting,
>> but I did get curious and dug around urllib2.py. Apparently, there is
>> a hardcoded 5 retries before the authentication really fails. So any
>> stack trace would be the normal stack trace times 5. Not the 30 you
>> mentioned, but annoying enough anyway (I don't see how it would fail
>> for every element in the loop though. Once it raises an exception,
>> the program basically ends).
> 
> It never throws an exception.  Or, if it does, something about the way
> I'm calling suppresses it.  IOW, I can put in a bogus credential and
> start the script and sit here for 5 minutes and see nothing.  Then ^C
> and I get a huge stacktrace that shows the repeated calls.  After the
> timeout on one element in the list, it goes to the next element, times
> out, goes to the next.

Ok, now I had to try and recreate something myself. So my processData is:

def processData(f):
   global overview_url
   overview_url = baseurl + f
   getData(authHeaders)

(f being a filename, out of a list of many). Other code same as yours.

It definitely throws a 401 exception after 5 retries. No time-outs, no long 
waits. In fact, a time-out would to me indicate another problem (it still 
should throw an exception, though). So, unless you're catching the exception in 
processData somehow, I don't see where things could go wrong. 
I assume you have no problem with correct credentials or simply using a 
webbrowser?



>> I don't know why it's hard-coded that way, and not just an option
>> with a default of 5, but that's currently how it is (maybe someone
>> else on this list knows?).
> 
> I don't know, but even if I could set it to 1, I'm not helped unless
> there's a way for me to make it throw an exception and exit the loop. 
> 
>> If that's what you're finding, perhaps the quickest way is to
>> subclass urllib2.HTTPBasicAuthHandler, and override the
>> http_error_auth_reqed method (essentially keeping it exactly the
>> same apart from the hard-coded 5).
> 
> Now there's a challenge!  ;-)

It'd be straightforward, but not solve your current problem, I'm afraid.

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


Re: [Tutor] changing list index start

2010-09-11 Thread Rance Hall
On Fri, Sep 10, 2010 at 6:14 PM, Lie Ryan  wrote:
> On 09/11/10 07:36, Rance Hall wrote:



> In most cases in Python, you would almost never need to reference the
> list's index directly since python makes it easy to use iterators;
> however in your particular case, which is a valid exception, enumerate()
> takes an optional second argument `start` which defines the number that
> enumerate start to count with, i.e. you can do:
>
> for i, option in enumerate(mainmenuoptions, 1):
>    print('%s. %s' % (i, option))
>
>> php provided a way to change this, but I can find no documentation
>> that says python can do this as well.
>


Thanks everyone for responding,  Because this menu structure is
repeated many times in my code, the ideal solution would have been to
"set index start = 1" in the beginning of the script.

something like sysctl variables in Linux perhaps but in this case only
valid for this program.

Its clear from the responses that this solution is not available in
python, I wish it were, it would make my life much easier for this
project.

I like the approach that Lie suggested, as it seems more "natural
python" to me as opposed to a workaround.

However this is also only half a solution since it applies to the
printed menus only and not to the response afterward.

It seems that Luke is right looks like we have to do math with the indexes.

Lie also referred to my particular case as a valid exception, are
there enough other such valid exceptions that requesting a feature
enhancement would gain some traction?

If this is but one of a few special cases, I doubt it would be worth
the time or trouble to formally make the request.

Maybe I should ask if there is a better way to do what I want to do
here. Is there?
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] changing list index start

2010-09-11 Thread Joel Goldstick
On Sat, Sep 11, 2010 at 9:25 AM, Rance Hall  wrote:

> On Fri, Sep 10, 2010 at 6:14 PM, Lie Ryan  wrote:
> > On 09/11/10 07:36, Rance Hall wrote:
>
> 
>
> > In most cases in Python, you would almost never need to reference the
> > list's index directly since python makes it easy to use iterators;
> > however in your particular case, which is a valid exception, enumerate()
> > takes an optional second argument `start` which defines the number that
> > enumerate start to count with, i.e. you can do:
> >
> > for i, option in enumerate(mainmenuoptions, 1):
> >print('%s. %s' % (i, option))
> >
> >> php provided a way to change this, but I can find no documentation
> >> that says python can do this as well.
> >
>
>
> Thanks everyone for responding,  Because this menu structure is
> repeated many times in my code, the ideal solution would have been to
> "set index start = 1" in the beginning of the script.
>
> something like sysctl variables in Linux perhaps but in this case only
> valid for this program.
>
> Its clear from the responses that this solution is not available in
> python, I wish it were, it would make my life much easier for this
> project.
>
> I like the approach that Lie suggested, as it seems more "natural
> python" to me as opposed to a workaround.
>
> However this is also only half a solution since it applies to the
> printed menus only and not to the response afterward.
>

It might be more trouble than its worth, but you could use a dictionary:
Instead of this:
mainmenuoptions = ['Clients','Jobs','Billing','Quotes','To Do
Items','Employee','Exit']

do this:
mainmenuoptions = {'Clients': 1,'Jobs': 2,'Billing': 3,'Quotes': 4,'To
Do
Items': 5,'Employee': 6,'Exit': 7}

Use the phrases as key, and the value as your numeric index.  Or you could
reverse {1: 'Clients', ...

if that suites your already written code.

If you use this pattern in many places, could you not refactor so that you
call
the process with the menu data structures as parameters, and fix the code
in a single place?



>
> It seems that Luke is right looks like we have to do math with the indexes.
>
> Lie also referred to my particular case as a valid exception, are
> there enough other such valid exceptions that requesting a feature
> enhancement would gain some traction?
>
> If this is but one of a few special cases, I doubt it would be worth
> the time or trouble to formally make the request.
>
> Maybe I should ask if there is a better way to do what I want to do
> here. Is there?
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>



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


Re: [Tutor] changing list index start

2010-09-11 Thread Knacktus

Am 11.09.2010 15:46, schrieb Joel Goldstick:



On Sat, Sep 11, 2010 at 9:25 AM, Rance Hall mailto:ran...@gmail.com>> wrote:

On Fri, Sep 10, 2010 at 6:14 PM, Lie Ryan mailto:lie.1...@gmail.com>> wrote:
 > On 09/11/10 07:36, Rance Hall wrote:



 > In most cases in Python, you would almost never need to reference the
 > list's index directly since python makes it easy to use iterators;
 > however in your particular case, which is a valid exception,
enumerate()
 > takes an optional second argument `start` which defines the
number that
 > enumerate start to count with, i.e. you can do:
 >
 > for i, option in enumerate(mainmenuoptions, 1):
 >print('%s. %s' % (i, option))
 >
 >> php provided a way to change this, but I can find no documentation
 >> that says python can do this as well.
 >


Thanks everyone for responding,  Because this menu structure is
repeated many times in my code, the ideal solution would have been to
"set index start = 1" in the beginning of the script.

something like sysctl variables in Linux perhaps but in this case only
valid for this program.

Its clear from the responses that this solution is not available in
python, I wish it were, it would make my life much easier for this
project.

I like the approach that Lie suggested, as it seems more "natural
python" to me as opposed to a workaround.

However this is also only half a solution since it applies to the
printed menus only and not to the response afterward.


It might be more trouble than its worth, but you could use a dictionary:
Instead of this:
 mainmenuoptions = ['Clients','Jobs','Billing','Quotes','To Do
Items','Employee','Exit']

do this:
 mainmenuoptions = {'Clients': 1,'Jobs': 2,'Billing': 3,'Quotes':
4,'To Do
Items': 5,'Employee': 6,'Exit': 7}

Use the phrases as key, and the value as your numeric index.  Or you could
reverse {1: 'Clients', ...

if that suites your already written code.

If you use this pattern in many places, could you not refactor so that
you call
the process with the menu data structures as parameters, and fix the code
in a single place?




+1 for the dictionary. A variation of Joels suggestion might be:

shortcuts_to_name_and_functions = {1: ['Clients', clientsmenu], 2: 
['Jobs', jobsmenu]}


for shortcut, name_and_func in shortcuts_to_name_and_functions.items():
print "%s. %s" % (shortcut, name_and_func[0])

# later make your call
shortcuts_to_name_and_functions[mainchoice][1]()







It seems that Luke is right looks like we have to do math with the
indexes.

Lie also referred to my particular case as a valid exception, are
there enough other such valid exceptions that requesting a feature
enhancement would gain some traction?

If this is but one of a few special cases, I doubt it would be worth
the time or trouble to formally make the request.

Maybe I should ask if there is a better way to do what I want to do
here. Is there?
___
Tutor maillist  - Tutor@python.org 
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor




--
Joel Goldstick



___
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


Re: [Tutor] Trapping HTTP Authentication Failure

2010-09-11 Thread Michael Powe
On Sat, Sep 11, 2010 at 02:25:24PM +0200, Evert Rol wrote:
> 
 
> >> I'm not sure what you're exactly doing here, or what you're getting,
> >> but I did get curious and dug around urllib2.py. Apparently, there is
> >> a hardcoded 5 retries before the authentication really fails. So any
> >> stack trace would be the normal stack trace times 5. Not the 30 you
> >> mentioned, but annoying enough anyway (I don't see how it would fail
> >> for every element in the loop though. Once it raises an exception,
> >> the program basically ends).

> > It never throws an exception.  Or, if it does, something about the way
> > I'm calling suppresses it.  IOW, I can put in a bogus credential and
> > start the script and sit here for 5 minutes and see nothing.  Then ^C
> > and I get a huge stacktrace that shows the repeated calls.  After the
> > timeout on one element in the list, it goes to the next element, times
> > out, goes to the next.
 
> Ok, now I had to try and recreate something myself. So my processData is:
 
> def processData(f):
>global overview_url
>overview_url = baseurl + f
>getData(authHeaders)
> 
> (f being a filename, out of a list of many). Other code same as yours.
 
> It definitely throws a 401 exception after 5 retries. No time-outs,
> no long waits. In fact, a time-out would to me indicate another
> problem (it still should throw an exception, though). So, unless
> you're catching the exception in processData somehow, I don't see
> where things could go wrong.

> I assume you have no problem with correct credentials or simply
> using a webbrowser?

Hello,

Yes, I can retrieve data without any problem.  I can break the URL and
generate a 404 exception that is trapped and I can break it in other
ways that generate other types of exceptions.  And trap them.

I went back and looked at the code in urllib2.py and I see the
timeout counter and that it raises an HTTPError after 5 tries.  But I
don't get anything back.  If I just let the code run to completion, I
get sent back to the prompt.  I put a try/catch in the method and I
already have one on the call in main.

 
 
> >> I don't know why it's hard-coded that way, and not just an option
> >> with a default of 5, but that's currently how it is (maybe someone
> >> else on this list knows?).
> > 
> > I don't know, but even if I could set it to 1, I'm not helped unless
> > there's a way for me to make it throw an exception and exit the loop. 

Actually, there's a comment in the code about why it is set to 5 --
it's arbitrary, and allows for the Password Manager to prompt for
credentials while not letting the request be reissued until 'recursion
depth is exceeded.'

I guess I'll have to go back to ground zero and write a stub to
generate the error and then build back up to where it disappears.

Thanks.

mp

-- 
Michael Powemich...@trollope.orgNaugatuck CT USA
It turns out that it will be easier to simply block the top offenders
manually; the rules for pattern matching are too arcane, obscure, and
difficult to program. -- t. pascal, comp.mail.misc, "procmail to
filter spam"


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


Re: [Tutor] exceptions problem

2010-09-11 Thread bob gailer

 On 9/11/2010 6:56 AM, Peter Otten wrote:

Steven D'Aprano wrote:


On Sat, 11 Sep 2010 09:56:41 am bob gailer wrote:

I never thought that you can use a float and a integer to look if
the number is a integer.

You can't.



I made that comment in the context of the OPs function:

def readposint():
  x = raw_input("Please enter a positive integer :")
  try:
if (int(x)<0 or (float(x) - int(x) > 0)): raise(ValueError)
  except:
print x , "is not a positive integer. Try again."
return -1
  return x

The OP thought (incorrectly) that, given for example:
x = '3.1'
float(x) - int(x) would evaluate to 0.1

In reality int(x) in this case raises an exception.
ValueError: invalid literal for int() with base 10: '3.1'

Since the expression was in a try he could not tell exactly what was 
happening.


I also don't quite understand the use of raise in the try.

I wish and hope that Roelof will learn how to do program walkthroughs 
and use the interactive prompt to solve things himself. I applaud the 
patience some of you have ih hand-holding him. I don't have that 
patience. I wish him to learn to fish.


--
Bob Gailer
919-636-4239
Chapel Hill NC

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


Re: [Tutor] changing list index start

2010-09-11 Thread Steven D'Aprano
On Sat, 11 Sep 2010 11:25:12 pm Rance Hall wrote:

> Thanks everyone for responding,  Because this menu structure is
> repeated many times in my code, the ideal solution would have been to
> "set index start = 1" in the beginning of the script.

That is exactly the wrong solution. That will break anything and 
everything that assumes "set index start = 0" is applying. Fortunately 
Python doesn't allow such a bad "solution".

The right solution is to get rid of all that duplicated code. Put the 
menu structure in one place, a function, and then call that function 
whenever you need it:


def display_menu(menu):
for i,option in enumerate(menu, 1):
print('%s. %s' % (i, option))
choice = int(input('\nYour Choice? '))
clearscreen(osname)
return choice-1


Now your mainmenu function becomes:

def mainmenu():
    # the main menu, in case you can't read the function name
    todolist()  # why is this here? 
    menu = ['Clients','Jobs','Billing','Quotes','To Do 
Items','Employee','Exit']
    calls = [clientsmenu, jobsmenu, billingmenu, quotesmenu,
todomenu, empmenu, quit]
n = display_menu(menu)
    calls[n]()


And similarly for your other menus:

def secondmenu():
menu = ['About','Help','Exit']
calls = [aboutmenu, helpmenu, quit]
n = display_menu(menu)
calls[n]()




> something like sysctl variables in Linux perhaps but in this case
> only valid for this program.
>
> Its clear from the responses that this solution is not available in
> python, I wish it were, it would make my life much easier for this
> project.

No, you only *think* it would make your life easier. This is probably 
the time to quote Yoda's speech about the Dark Side of the Force 
from "The Empire Strikes Back".

Such global settings are "easier, faster, simpler"... for about fifteen 
minutes. The right solution is to build reusable building blocks, then 
put them together.


[...]
> Lie also referred to my particular case as a valid exception, are
> there enough other such valid exceptions that requesting a feature
> enhancement would gain some traction?

Not a hope in hell.

You have misunderstood Lie's comment. He's talking about the use of an 
index *at all*. Normally in Python you shouldn't need to use indexes, 
regardless of whether they start with 0 or 1 or 3.1425 Your example 
of a text menu is an exception to the rule (more of a guideline 
really) "you shouldn't care about indexes".



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


Re: [Tutor] changing list index start

2010-09-11 Thread Joel Goldstick
On Sat, Sep 11, 2010 at 11:15 AM, Steven D'Aprano wrote:

> On Sat, 11 Sep 2010 11:25:12 pm Rance Hall wrote:
>
> > Thanks everyone for responding,  Because this menu structure is
> > repeated many times in my code, the ideal solution would have been to
> > "set index start = 1" in the beginning of the script.
>
> That is exactly the wrong solution. That will break anything and
> everything that assumes "set index start = 0" is applying. Fortunately
> Python doesn't allow such a bad "solution".
>
> The right solution is to get rid of all that duplicated code. Put the
> menu structure in one place, a function, and then call that function
> whenever you need it:
>
>
> def display_menu(menu):
>for i,option in enumerate(menu, 1):
> print('%s. %s' % (i, option))
> choice = int(input('\nYour Choice? '))
>clearscreen(osname)
> return choice-1
>
>
> Now your mainmenu function becomes:
>
> def mainmenu():
> # the main menu, in case you can't read the function name
> todolist()  # why is this here?
> menu = ['Clients','Jobs','Billing','Quotes','To Do
> Items','Employee','Exit']
> calls = [clientsmenu, jobsmenu, billingmenu, quotesmenu,
> todomenu, empmenu, quit]
> n = display_menu(menu)
> calls[n]()
>
>
> And similarly for your other menus:
>
> def secondmenu():
>menu = ['About','Help','Exit']
>calls = [aboutmenu, helpmenu, quit]
>n = display_menu(menu)
>calls[n]()
>
>
>
>
> > something like sysctl variables in Linux perhaps but in this case
> > only valid for this program.
> >
> > Its clear from the responses that this solution is not available in
> > python, I wish it were, it would make my life much easier for this
> > project.
>
> No, you only *think* it would make your life easier. This is probably
> the time to quote Yoda's speech about the Dark Side of the Force
> from "The Empire Strikes Back".
>
> Such global settings are "easier, faster, simpler"... for about fifteen
> minutes. The right solution is to build reusable building blocks, then
> put them together.
>
>
> [...]
> > Lie also referred to my particular case as a valid exception, are
> > there enough other such valid exceptions that requesting a feature
> > enhancement would gain some traction?
>
> Not a hope in hell.
>
> You have misunderstood Lie's comment. He's talking about the use of an
> index *at all*. Normally in Python you shouldn't need to use indexes,
> regardless of whether they start with 0 or 1 or 3.1425 Your example
> of a text menu is an exception to the rule (more of a guideline
> really) "you shouldn't care about indexes".
>
>
>
> --
> Steven D'Aprano
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>


I think the first message in the original post is instructive:

"I'm using the following function style I found on the net to create
menus for a command line python script:"

I (sometimes!) love looking at other peoples code to learn.  However taking
some code and
using it in your application demands that you understand it, or it will bite
you later.  In this case,
the code might have been appropriate to the original author, but not for its
new use.

Using index starting with 1 sounds to me idiomatic of BASIC programming.
While I'm too inexperienced
with Python to consider myself good at it, I think the key to using python
is to 'get it' as to the fundamental
data types in python and how they make things easier to solve problems.
One of the earliest programming
books I read was 'Algorithms + Data Structures = Programs' by Niklaus
Wirth.  The book used Pascal, which I think
the author wrote.  But no matter the language, learn what data structures it
offers, and why and then your algorithms
will become simpler and more elegant.  If you find yourself doing weird
things with your code, see if you can rethink
how you organize your data



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


Re: [Tutor] changing list index start

2010-09-11 Thread Lie Ryan
On 09/11/10 23:25, Rance Hall wrote:
> On Fri, Sep 10, 2010 at 6:14 PM, Lie Ryan  wrote:
>> On 09/11/10 07:36, Rance Hall wrote:
> 
> 
> 
>> In most cases in Python, you would almost never need to reference the
>> list's index directly since python makes it easy to use iterators;
>> however in your particular case, which is a valid exception, enumerate()
>> takes an optional second argument `start` which defines the number that
>> enumerate start to count with, i.e. you can do:
>>
>> for i, option in enumerate(mainmenuoptions, 1):
>>print('%s. %s' % (i, option))
>>
>>> php provided a way to change this, but I can find no documentation
>>> that says python can do this as well.
>>
> 
> 
> Thanks everyone for responding,  Because this menu structure is
> repeated many times in my code, the ideal solution would have been to
> "set index start = 1" in the beginning of the script.

That would produce a catastrophic effect. What would happen to standard
library modules or external modules now that they have to work in a
different base?

> something like sysctl variables in Linux perhaps but in this case only
> valid for this program.
> 
> Its clear from the responses that this solution is not available in
> python, I wish it were, it would make my life much easier for this
> project.

Personally I think it's a bad idea. Being able to globally rebase list
index would triple the code's WTF count.

> I like the approach that Lie suggested, as it seems more "natural
> python" to me as opposed to a workaround.
> 
> However this is also only half a solution since it applies to the
> printed menus only and not to the response afterward.
>
> It seems that Luke is right looks like we have to do math with the indexes.
>
> Lie also referred to my particular case as a valid exception, are
> there enough other such valid exceptions that requesting a feature
> enhancement would gain some traction?

When I mean, a valid exception, it's referring to "knowing the index
number" of a list, not to the ability of changing the list's base.

> If this is but one of a few special cases, I doubt it would be worth
> the time or trouble to formally make the request.

As an alternative solution, you can derive from UserList and overload
the __getitem__ and __setitem__ operator:

from UserList import UserList
class RebasedList(UserList):
def __init__(self, base=1, *args, **kwargs):
UserList.__init__(self, *args, **kwargs)
self.base = base
def __getitem__(self, index):
if self.base <= index < self.base + len(self):
return UserList.__getitem__(self, index - self.base)
else:
raise IndexError(
"RebasedList index out of range [%s-%s), "
"given index %s" %
(self.base, self.base+len(self), index))
def __setitem__(self, index, item):
if self.base <= index < self.base + len(self):
return UserList.__setitem__(self, index - self.base, item)
else:
raise IndexError(
"RebasedList assignment index out of range [%s-%s), "
"given index %s" %
(self.base, self.base+len(self), index))
# for complete emulation, you will also need to override:
# __iter__, __delitem__, __getslice__, __setslice__,
# __delslice__, __add__, __mul__, index, insert, pop,
# remove, and possibly others

You can use it like this:

rl = RebasedList(10, [3, 1, 2, 4, 2, 1]
rl[10] # rl[0]
rl[11] = 29 # rl[1] = 29
print rl # [3, 29, 2, 4, 2, 1]

Then there is the case that negative index no longer work cleanly with a
custom list base.

> Maybe I should ask if there is a better way to do what I want to do
> here. Is there?


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


Re: [Tutor] changing list index start

2010-09-11 Thread Rance Hall
On Sat, Sep 11, 2010 at 10:40 AM, Joel Goldstick
 wrote:



>
> I think the first message in the original post is instructive:
>
> "I'm using the following function style I found on the net to create
> menus for a command line python script:"
>
> I (sometimes!) love looking at other peoples code to learn.  However taking
> some code and
> using it in your application demands that you understand it, or it will bite
> you later.  In this case,
> the code might have been appropriate to the original author, but not for its
> new use.
>

I agree completely and I did understand what this code snippet was
doing, and I also understood why the first menu item was labeled 0

My question revolves around the theme of "this is the idea I want to
use, it does this, I like what it does, but I'd like to alter it
slightly, how do I turn this into what I want?

> Using index starting with 1 sounds to me idiomatic of BASIC programming.
> While I'm too inexperienced
> with Python to consider myself good at it, I think the key to using python
> is to 'get it' as to the fundamental
> data types in python and how they make things easier to solve problems.
> One of the earliest programming
> books I read was 'Algorithms + Data Structures = Programs' by Niklaus
> Wirth.  The book used Pascal, which I think
> the author wrote.  But no matter the language, learn what data structures it
> offers, and why and then your algorithms
> will become simpler and more elegant.  If you find yourself doing weird
> things with your code, see if you can rethink
> how you organize your data
>

Yea, it does a little bit, doesn't it.  (at least reminding of BASIC)

I can't disagree with you on the rest of your comments either

I can't say that I thought my original idea was weird at all,  BASIC,
PHP and probably other languages allow you to approach the problem in
the same way I thought of.
But this is python and not any other language, so for me I'm finding
that the biggest issue on my plate now is not "What is this?" but more
of "Why is this better or worse than that?"

Steven reply in an example of what I'm talking about, Steven said "You
*think* its a good idea"

In some ways python is a very flexible flowing language.  In other
ways its very restrictive.  For example: I *like* how whitespace
matters in python, it forces you to structure your code.correctly.
Other languages don't care about the whitespace, you dont have to
indent your code (which is a disaster to read I know)

This is the stuff I need to learn, where is python rigid and where is
it flexible.  This gives me a framework to use for evaluating tasks.

I think my original question has been answered and I'm glad I wasn't
barking up the wrong tree.

As to the philosophical stuff maybe its time to start a new thread.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] exceptions problem

2010-09-11 Thread Roelof Wobben




> Date: Sat, 11 Sep 2010 11:05:54 -0400
> From: bgai...@gmail.com
> To: tutor@python.org
> Subject: Re: [Tutor] exceptions problem
>
> On 9/11/2010 6:56 AM, Peter Otten wrote:
>> Steven D'Aprano wrote:
>>
>>> On Sat, 11 Sep 2010 09:56:41 am bob gailer wrote:
> I never thought that you can use a float and a integer to look if
> the number is a integer.
 You can't.
>>>
> I made that comment in the context of the OPs function:
>
> def readposint():
> x = raw_input("Please enter a positive integer :")
> try:
> if (int(x)<0 or (float(x) - int(x)> 0)): raise(ValueError)
> except:
> print x , "is not a positive integer. Try again."
> return -1
> return x
>
> The OP thought (incorrectly) that, given for example:
> x = '3.1'
> float(x) - int(x) would evaluate to 0.1
>
> In reality int(x) in this case raises an exception.
> ValueError: invalid literal for int() with base 10: '3.1'
>
> Since the expression was in a try he could not tell exactly what was
> happening.
>
> I also don't quite understand the use of raise in the try.
>
> I wish and hope that Roelof will learn how to do program walkthroughs
> and use the interactive prompt to solve things himself. I applaud the
> patience some of you have ih hand-holding him. I don't have that
> patience. I wish him to learn to fish.
>
> --
> Bob Gailer
> 919-636-4239
> Chapel Hill NC
>
> ___
> Tutor maillist - Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor

Hello Bob, 
 
Oke, I try to  fish.
 
When I do 
 
x= "a"
y= int(x) 
Then I get ValueError.
 
When I do 
 
x= 1.2
y=int(x)
No exception is raised.
But when I do then x ==y I get a false.
When I now do float(x) - int(x) I get 1.2 - 1 = 0.2 and that's greater then 0 
 
Because one of the two is true the Raise is executed.
 
 
x = -9 
y=int(x) 
No exception is raised.
X == y is True.
But float(x) - int(x) I get 0.0 and 0.0> 0 is False.
Because x == y is True the Raise is executed.
 
Are these the right conclusions ??
 
Roelof
 
 
  
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] recursive problem

2010-09-11 Thread Steven D'Aprano
On Fri, 10 Sep 2010 09:30:23 pm Ewald Horn wrote:

> While EAFP is great, it's not
> always the best way to proceed. 

That, at least, is correct. But what you say next is not:

> Sometimes you want programs to be 
> very robust and secure, this is where LBYL comes in - it is quite
> often used in online transaction processing and other areas where
> absolute certainty is more important than any other consideration.

If what you are saying is correct, and I doubt seriously that it is, 
then chances are good that they're not succeeding in their aim.

> EAFP tends to use less code and is faster to use, while LBYL
> principles makes your program more bulletproof.

That's almost 100% backwards.

Let's take a simple example: you want to open a file, and deal with the 
case of the file being missing:

filename = 'myfile.txt'  # whatever...
fp = open(filename)
do_something_with(fp)

Let's add some error checking. With EAFP, you get this:

try:
fp = open(filename)
except IOError:
handle_error()


With LBYL, you get:

if os.path.exists(filename):
fp = open(filename)
else:
handle_error()


The amount of code is about the same, but the try...except block 
automatically handles a whole slew of errors -- missing files, 
permission denied, bad file names, corrupt disks, all sorts of things 
that would be difficult or tedious to Look Before You Leap. Some of 
these things -- like disk corruption -- you simply can't check ahead of 
time. There is no way of knowing if a file is corrupt without actually 
opening and/or reading from it.

It gets worse. Your computer is a multitasking system. Virtually all 
computers are these days, yes, even the iPhone. Even if os.path.exists 
returns True, there is no guarantee that the file will still be there a 
millisecond later when you try to open it. Perhaps the operating 
system, or some other process, has deleted the file or renamed it. 
That's a bug waiting to happen -- a "race condition".

So if you're silly, you write this:

if os.path.exists(filename):
try:
fp = open(filename)
except IOError:
handle_error()
else:
handle_error()

If you're sensible, you realise that for reliable, secure code, checking 
for existence *before* opening the file is a waste of time and energy. 
It's barely acceptable for quick and dirty scripts, certainly not for 
high reliability applications.

This is not the only sort of race condition. Imagine you're writing one 
of these high reliability online transactions you talked about, and you 
want to transfer money from one account to another:

amount = 1000.00
if balance >= amount:
transfer(old_account, new_account, amount)
else:
insufficient_balance()


Wait a second... that looks almost exactly like the LBYL code above, and 
it is vulnerable to the same sort of race condition if multiple 
processes can connect to the account at the same time. Does your bank 
allow you to log in twice? Does it have automatic transfers? If so, 
then one process can be transferring money while the other is checking 
the balance, and you have a bug waiting to happen.

In practice, the banks allow accounts to become temporarily overdrawn, 
and often charge you for the privilege. And they write complicated code 
that looks like this:


lock_id = lock_account()  # Stop anything else from transferring funds.
while lock_id == 0
# Lock failed, wait a second and try again.
time.sleep(1)
lock_id = lock_account()
if number_of_attempts() > 10:
handle_error("internal error, please try again")
# Now it's safe to check the balance.
if balance >= amount:
transfer(old_account, new_account, amount, lock_id)
else:
insufficient_balance()
# Don't forget to unlock the account, or there will be trouble later!
errcode = unlock_account(lock_id)
if errcode != 0:
# This should never happen. If it does, it might mean the lock ID 
# is incorrect (how?), but probably means the database is corrupt.
log_serious_error(errcode, lock_id)


It's ugly and error-prone, but it's also a kind of EAFP: instead of 
checking whether a lock is available, and then taking it, you just try 
to acquire a lock, and deal with the consequences of not receiving one 
if it fails. The only difference is that you're manually checking an 
error code rather than catching an exception.

Whatever mechanism is used for EAFP, it is most often shorter, simpler, 
more reliable and safer than LBYL.

So why would anyone ever use LBYL? Well, sometimes it is more convenient 
for quick and dirty scripts, such as using os.path.exists. But more 
importantly, sometimes you need a transaction to apply in full, or not 
at all. You can't do this:

try:
do_this()
do_that()
do_something_else()
except Exception:
do_error()


because if do_this() succeeds and do_that() fails, you might leave your 
data is a seriously inconsistent or broken state. You could do this:


failed = False
save_state()
try:
do_this()
try:
do_that(

Re: [Tutor] recursive problem

2010-09-11 Thread Roelof Wobben




> From: st...@pearwood.info
> To: tutor@python.org
> Date: Sun, 12 Sep 2010 03:18:19 +1000
> Subject: Re: [Tutor] recursive problem
>
> On Fri, 10 Sep 2010 09:30:23 pm Ewald Horn wrote:
>
>> While EAFP is great, it's not
>> always the best way to proceed.
>
> That, at least, is correct. But what you say next is not:
>
>> Sometimes you want programs to be
>> very robust and secure, this is where LBYL comes in - it is quite
>> often used in online transaction processing and other areas where
>> absolute certainty is more important than any other consideration.
>
> If what you are saying is correct, and I doubt seriously that it is,
> then chances are good that they're not succeeding in their aim.
>
>> EAFP tends to use less code and is faster to use, while LBYL
>> principles makes your program more bulletproof.
>
> That's almost 100% backwards.
>
> Let's take a simple example: you want to open a file, and deal with the
> case of the file being missing:
>
> filename = 'myfile.txt' # whatever...
> fp = open(filename)
> do_something_with(fp)
>
> Let's add some error checking. With EAFP, you get this:
>
> try:
> fp = open(filename)
> except IOError:
> handle_error()
>
>
> With LBYL, you get:
>
> if os.path.exists(filename):
> fp = open(filename)
> else:
> handle_error()
>
>
> The amount of code is about the same, but the try...except block
> automatically handles a whole slew of errors -- missing files,
> permission denied, bad file names, corrupt disks, all sorts of things
> that would be difficult or tedious to Look Before You Leap. Some of
> these things -- like disk corruption -- you simply can't check ahead of
> time. There is no way of knowing if a file is corrupt without actually
> opening and/or reading from it.
>
> It gets worse. Your computer is a multitasking system. Virtually all
> computers are these days, yes, even the iPhone. Even if os.path.exists
> returns True, there is no guarantee that the file will still be there a
> millisecond later when you try to open it. Perhaps the operating
> system, or some other process, has deleted the file or renamed it.
> That's a bug waiting to happen -- a "race condition".
>
> So if you're silly, you write this:
>
> if os.path.exists(filename):
> try:
> fp = open(filename)
> except IOError:
> handle_error()
> else:
> handle_error()
>
> If you're sensible, you realise that for reliable, secure code, checking
> for existence *before* opening the file is a waste of time and energy.
> It's barely acceptable for quick and dirty scripts, certainly not for
> high reliability applications.
>
> This is not the only sort of race condition. Imagine you're writing one
> of these high reliability online transactions you talked about, and you
> want to transfer money from one account to another:
>
> amount = 1000.00
> if balance>= amount:
> transfer(old_account, new_account, amount)
> else:
> insufficient_balance()
>
>
> Wait a second... that looks almost exactly like the LBYL code above, and
> it is vulnerable to the same sort of race condition if multiple
> processes can connect to the account at the same time. Does your bank
> allow you to log in twice? Does it have automatic transfers? If so,
> then one process can be transferring money while the other is checking
> the balance, and you have a bug waiting to happen.
>
> In practice, the banks allow accounts to become temporarily overdrawn,
> and often charge you for the privilege. And they write complicated code
> that looks like this:
>
>
> lock_id = lock_account() # Stop anything else from transferring funds.
> while lock_id == 0
> # Lock failed, wait a second and try again.
> time.sleep(1)
> lock_id = lock_account()
> if number_of_attempts()> 10:
> handle_error("internal error, please try again")
> # Now it's safe to check the balance.
> if balance>= amount:
> transfer(old_account, new_account, amount, lock_id)
> else:
> insufficient_balance()
> # Don't forget to unlock the account, or there will be trouble later!
> errcode = unlock_account(lock_id)
> if errcode != 0:
> # This should never happen. If it does, it might mean the lock ID
> # is incorrect (how?), but probably means the database is corrupt.
> log_serious_error(errcode, lock_id)
>
>
> It's ugly and error-prone, but it's also a kind of EAFP: instead of
> checking whether a lock is available, and then taking it, you just try
> to acquire a lock, and deal with the consequences of not receiving one
> if it fails. The only difference is that you're manually checking an
> error code rather than catching an exception.
>
> Whatever mechanism is used for EAFP, it is most often shorter, simpler,
> more reliable and safer than LBYL.
>
> So why would anyone ever use LBYL? Well, sometimes it is more convenient
> for quick and dirty scripts, such as using os.path.exists. But more
> importantly, sometimes you need a transaction to apply in full, or not
> at all. You can't do this:
>
> try:
> do_this()
> do_that()
> do_something_

Re: [Tutor] recursive problem

2010-09-11 Thread Steven D'Aprano
On Sun, 12 Sep 2010 03:18:19 am Steven D'Aprano wrote:

> But that hasn't done anything to prevent race conditions. So the real
> reason people use LBYL is that they're too lazy to write hideously
> ugly, but reliable, code, and they're just hoping that they will
> never expose the race condition. (Often this is a pretty safe hope,
> but not always.)

http://en.wikipedia.org/wiki/Ostrich_algorithm


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


Re: [Tutor] recursive problem

2010-09-11 Thread Roelof Wobben




> From: st...@pearwood.info
> To: tutor@python.org
> Date: Sun, 12 Sep 2010 03:27:42 +1000
> Subject: Re: [Tutor] recursive problem
>
> On Sun, 12 Sep 2010 03:18:19 am Steven D'Aprano wrote:
>
>> But that hasn't done anything to prevent race conditions. So the real
>> reason people use LBYL is that they're too lazy to write hideously
>> ugly, but reliable, code, and they're just hoping that they will
>> never expose the race condition. (Often this is a pretty safe hope,
>> but not always.)
>
> http://en.wikipedia.org/wiki/Ostrich_algorithm
>
>
> --
> Steven D'Aprano
> ___
> Tutor maillist - Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor

Oke,
 
But why is type checking then wrong.
Lets says I want a module who must work on strings, tuple and lists.
 
Can I then use EAFP ?
 
Without type checking I never know which one is used now.
 
Roelof
  
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] recursive problem

2010-09-11 Thread Luke Paireepinart

On Sep 11, 2010, at 12:40 PM, Roelof Wobben  wrote:

> 
> 
> 
> 
>> From: st...@pearwood.info
>> To: tutor@python.org
>> Date: Sun, 12 Sep 2010 03:27:42 +1000
>> Subject: Re: [Tutor] recursive problem
>> 
>> On Sun, 12 Sep 2010 03:18:19 am Steven D'Aprano wrote:
>> 
>>> But that hasn't done anything to prevent race conditions. So the real
>>> reason people use LBYL is that they're too lazy to write hideously
>>> ugly, but reliable, code, and they're just hoping that they will
>>> never expose the race condition. (Often this is a pretty safe hope,
>>> but not always.)
>> 
>> http://en.wikipedia.org/wiki/Ostrich_algorithm
>> 
>> 
>> --
>> Steven D'Aprano
>> ___
>> Tutor maillist - Tutor@python.org
>> To unsubscribe or change subscription options:
>> http://mail.python.org/mailman/listinfo/tutor
> 
> Oke,
> 
> But why is type checking then wrong.
> Lets says I want a module who must work on strings, tuple and lists.
> 
> Can I then use EAFP ?
> 
> Without type checking I never know which one is used now.
> 
> Roelof
>   

That's the whole point! You don't WANT to know what type it is. You want to 
just use it how you want, an if it behaves properly, who cares what type it is?

See when you type check you are forcing the user to use those types. What if 
they want to derive a subclass from list? Is there really a reason why you 
should prevent them from using that subclass with your function?
If there is a valid reason, type checking is fine. But if there isn't, type 
checking is just making your code more inflexible.

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


Re: [Tutor] exceptions problem

2010-09-11 Thread Dave Angel



On 2:59 PM, Roelof Wobben wrote:


Hello Bob,

Oke, I try to  fish.

When I do

x="a"
y=nt(x)
Then I get ValueError.

When I do

x= 1.2
y=int(x)
No exception is raised.
But when I do then x = I get a false.
When I now do float(x) - int(x) I get 1.2 - 1 =.2 and that's greater then 0

Because one of the two is true the Raise is executed.


x = -9
y= int(x)
No exception is raised.
X =y is True.
But float(x) - int(x) I get 0.0 and 0.0>  0 is False.
Because x =y is True the Raise is executed.

Are these the right conclusions ??

Roelof



But in your original code, x was a string.  raw_input() produces a 
string, not a float.  So the middle case is different than what you're 
trying now.


DaveA

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


Re: [Tutor] recursive problem

2010-09-11 Thread Walter Prins
> That's the whole point! You don't WANT to know what type it is. You want to
> just use it how you want, an if it behaves properly, who cares what type it
> is?
>
> See when you type check you are forcing the user to use those types. What
> if they want to derive a subclass from list? Is there really a reason why
> you should prevent them from using that subclass with your function?
> If there is a valid reason, type checking is fine. But if there isn't, type
> checking is just making your code more inflexible.
>
>
Well, I would submit that if were going to do type checking in such a
context you'd probably check for a base class, so deriving a subclass
wouldn't break entirely.  Your point still stands however, we don't even
want to require from users to derive from class list.  We'd be quite happy
to work with any object that "walks like a list" and "quacks like a list",
that's the beauty of duck typing...

I guess the question to ask/consider is: How can be establish whether a
particular object supports a particular interface/set of behaviours that we
require?  E.g. how do we most pythonically check whether some object "walks
like a list" and "quacks like a list" without tying such code to explicit
type checking?

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


Re: [Tutor] recursive problem

2010-09-11 Thread Steven D'Aprano
On Sun, 12 Sep 2010 03:40:38 am Roelof Wobben wrote:

> But why is type checking then wrong.
> Lets says I want a module who must work on strings, tuple and lists.

It's not *always* wrong, but let me ask you... why do you want to 
*limit* the function to work on ONLY strings, tuples and lists?

The Python philosophy is "duck typing" -- if it walks like a duck, and 
swims like a duck, it is close enough to a duck that we don't care that 
it's not actually a duck, but a goose.

Here's an example:


def f1(x):
if type(x) is int or type(x) is float:
print("x + 1 = %s" % (x+1))
else:
print("x is not a number")


def f2(x):
try:
print("x + 1 = %s" % (x+1))
except (ValueError, TypeError):
print("x is not a number")

>>> f1(3)
x + 1 = 4
>>> from decimal import Decimal
>>> f1(Decimal(3))
x is not a number
>>> f2(Decimal(3))
x + 1 = 4

Function f1 makes the assumption that only ints and floats can be added, 
and so it gives the wrong results with Decimal numbers. But function f2 
uses "duck typing" -- it doesn't care what sort of number x is, only 
that it can be added.



> Can I then use EAFP ?
>
> Without type checking I never know which one is used now.


Going back to type-checking... sometimes you can't avoid it. Sometimes 
you use it because it is easier, and you don't care enough to write 
more complicated code. Sometimes you really do care what the type is:

>>> "abc"[2.0]
Traceback (most recent call last):
  File "", line 1, in 
TypeError: string indices must be integers



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


Re: [Tutor] changing list index start

2010-09-11 Thread Steven D'Aprano
On Sun, 12 Sep 2010 02:00:02 am Lie Ryan wrote:

> As an alternative solution, you can derive from UserList and overload
> the __getitem__ and __setitem__ operator:

We've been able to inherit from list directly since at least Python 2.2. 
Why are you using UserList?



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


Re: [Tutor] recursive problem

2010-09-11 Thread Roelof Wobben




> From: rwob...@hotmail.com
> To: wpr...@gmail.com
> Subject: RE: [Tutor] recursive problem
> Date: Sat, 11 Sep 2010 18:05:12 +
>
>
>
>
> 
>> Date: Sat, 11 Sep 2010 19:01:39 +0100
>> Subject: Re: [Tutor] recursive problem
>> From: wpr...@gmail.com
>> To: rabidpoob...@gmail.com
>> CC: rwob...@hotmail.com; tutor@python.org
>>
>>
>> That's the whole point! You don't WANT to know what type it is. You
>> want to just use it how you want, an if it behaves properly, who cares
>> what type it is?
>>
>> See when you type check you are forcing the user to use those types.
>> What if they want to derive a subclass from list? Is there really a
>> reason why you should prevent them from using that subclass with your
>> function?
>> If there is a valid reason, type checking is fine. But if there isn't,
>> type checking is just making your code more inflexible.
>>
>>
>> Well, I would submit that if were going to do type checking in such a
>> context you'd probably check for a base class, so deriving a subclass
>> wouldn't break entirely. Your point still stands however, we don't
>> even want to require from users to derive from class list. We'd be
>> quite happy to work with any object that "walks like a list" and
>> "quacks like a list", that's the beauty of duck typing...
>>
>> I guess the question to ask/consider is: How can be establish whether a
>> particular object supports a particular interface/set of behaviours
>> that we require? E.g. how do we most pythonically check whether some
>> object "walks like a list" and "quacks like a list" without tying such
>> code to explicit type checking?
>>
>> Walter
>
> Exactly what I mean.
>
> With the knowlegde I have from the few chapters of thinking like a computer 
> scientist I don't know the answer to the last question.
>
>
> Roelof
>
> 
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] recursive problem

2010-09-11 Thread Lie Ryan
On 09/12/10 04:01, Walter Prins wrote:
> I guess the question to ask/consider is: How can be establish whether a
> particular object supports a particular interface/set of behaviours that
> we require?  E.g. how do we most pythonically check whether some object
> "walks like a list" and "quacks like a list" without tying such code to
> explicit type checking?

In Python? By treating it like a list; and shooting the duck in their
webby feet when it doesn't act like a list.

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


Re: [Tutor] recursive problem

2010-09-11 Thread Roelof Wobben




> From: st...@pearwood.info
> To: tutor@python.org
> Date: Sun, 12 Sep 2010 04:03:43 +1000
> Subject: Re: [Tutor] recursive problem
>
> On Sun, 12 Sep 2010 03:40:38 am Roelof Wobben wrote:
>
>> But why is type checking then wrong.
>> Lets says I want a module who must work on strings, tuple and lists.
>
> It's not *always* wrong, but let me ask you... why do you want to
> *limit* the function to work on ONLY strings, tuples and lists?
>
> The Python philosophy is "duck typing" -- if it walks like a duck, and
> swims like a duck, it is close enough to a duck that we don't care that
> it's not actually a duck, but a goose.
>
> Here's an example:
>
>
> def f1(x):
> if type(x) is int or type(x) is float:
> print("x + 1 = %s" % (x+1))
> else:
> print("x is not a number")
>
>
> def f2(x):
> try:
> print("x + 1 = %s" % (x+1))
> except (ValueError, TypeError):
> print("x is not a number")
>
 f1(3)
> x + 1 = 4
 from decimal import Decimal
 f1(Decimal(3))
> x is not a number
 f2(Decimal(3))
> x + 1 = 4
>
> Function f1 makes the assumption that only ints and floats can be added,
> and so it gives the wrong results with Decimal numbers. But function f2
> uses "duck typing" -- it doesn't care what sort of number x is, only
> that it can be added.
>
>
>
>> Can I then use EAFP ?
>>
>> Without type checking I never know which one is used now.
>
>
> Going back to type-checking... sometimes you can't avoid it. Sometimes
> you use it because it is easier, and you don't care enough to write
> more complicated code. Sometimes you really do care what the type is:
>
 "abc"[2.0]
> Traceback (most recent call last):
> File "", line 1, in 
> TypeError: string indices must be integers
>
>
>
> --
> Steven D'Aprano
> ___
> Tutor maillist - Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor

Hello Steven,
 
Because I follow this book "Thinking like a computer scientist" and I have only 
read the chapters about strings. lists and tuples.

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


Re: [Tutor] Trapping HTTP Authentication Failure

2010-09-11 Thread Michael Powe
On Sat, Sep 11, 2010 at 10:48:13AM -0400, Michael Powe wrote:
> On Sat, Sep 11, 2010 at 02:25:24PM +0200, Evert Rol wrote:
> > 
>  
> > >> I'm not sure what you're exactly doing here, or what you're getting,
> > >> but I did get curious and dug around urllib2.py. Apparently, there is
> > >> a hardcoded 5 retries before the authentication really fails. So any
> > >> stack trace would be the normal stack trace times 5. Not the 30 you
> > >> mentioned, but annoying enough anyway (I don't see how it would fail
> > >> for every element in the loop though. Once it raises an exception,
> > >> the program basically ends).
 
> > > It never throws an exception.  Or, if it does, something about the way
> > > I'm calling suppresses it.  IOW, I can put in a bogus credential and
> > > start the script and sit here for 5 minutes and see nothing.  Then ^C
> > > and I get a huge stacktrace that shows the repeated calls.  After the
> > > timeout on one element in the list, it goes to the next element, times
> > > out, goes to the next.

Hello,

More experimentation revealed that one problem was testing the script
in Idle.  Idle does something to suppress the script failure for that
particular case (IOW, it correctly returns HTTPError for things like
'404' and URLError for things like a bad domain name).

When I run the script from the command line (cmd), it actually ignores
the '5' retry limit, seemingly.  I added another catch block:

except Exception as e:
   print "exception: ",e

That prints out "exception: maximum recursion depth exceeded."

I wonder if there is something hinky in Windows that is causing this
to happen.

Thanks.

mp
  
> > Ok, now I had to try and recreate something myself. So my processData is:
>  
> > def processData(f):
> >global overview_url
> >overview_url = baseurl + f
> >getData(authHeaders)
> > 
> > (f being a filename, out of a list of many). Other code same as yours.
>  
> > It definitely throws a 401 exception after 5 retries. No time-outs,
> > no long waits. In fact, a time-out would to me indicate another
> > problem (it still should throw an exception, though). So, unless
> > you're catching the exception in processData somehow, I don't see
> > where things could go wrong.
> 
> > I assume you have no problem with correct credentials or simply
> > using a webbrowser?
> 
> Hello,
> 
> Yes, I can retrieve data without any problem.  I can break the URL and
> generate a 404 exception that is trapped and I can break it in other
> ways that generate other types of exceptions.  And trap them.
> 
> I went back and looked at the code in urllib2.py and I see the
> timeout counter and that it raises an HTTPError after 5 tries.  But I
> don't get anything back.  If I just let the code run to completion, I
> get sent back to the prompt.  I put a try/catch in the method and I
> already have one on the call in main.
> 
>  
>  
> > >> I don't know why it's hard-coded that way, and not just an option
> > >> with a default of 5, but that's currently how it is (maybe someone
> > >> else on this list knows?).
> > > 
> > > I don't know, but even if I could set it to 1, I'm not helped unless
> > > there's a way for me to make it throw an exception and exit the loop. 
> 
> Actually, there's a comment in the code about why it is set to 5 --
> it's arbitrary, and allows for the Password Manager to prompt for
> credentials while not letting the request be reissued until 'recursion
> depth is exceeded.'
> 
> I guess I'll have to go back to ground zero and write a stub to
> generate the error and then build back up to where it disappears.
> 
> Thanks.
> 
> mp
> 
> -- 
> Michael Powe  mich...@trollope.orgNaugatuck CT USA
> It turns out that it will be easier to simply block the top offenders
> manually; the rules for pattern matching are too arcane, obscure, and
> difficult to program. -- t. pascal, comp.mail.misc, "procmail to
> filter spam"



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


-- 
Michael Powemich...@trollope.orgNaugatuck CT USA
I hate a fellow whom pride, or cowardice, or laziness drives into a
corner, and who does nothing when he is there but sit and ; let
him come out as I do, and . -- Samuel Johnson


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


Re: [Tutor] recursive problem

2010-09-11 Thread Steven D'Aprano
On Sun, 12 Sep 2010 04:01:39 am Walter Prins wrote:

> I guess the question to ask/consider is: How can be establish whether
> a particular object supports a particular interface/set of behaviours
> that we require?  E.g. how do we most pythonically check whether some
> object "walks like a list" and "quacks like a list" without tying
> such code to explicit type checking?

isinstance(object, base_class) becomes even more useful in Python 2.6 
and beyond, because when you create a class, you can register it as a 
list even if you didn't inherit from list. You're essentially 
promising "this class will walk and quack and swim like a list".

But often you don't care that something walks, quacks, and swims like a 
list. You might only care that it walks. We can combine "Look Before 
You Leap" with duck-typing:


def swap_items(sequence):
try:
sequence[0] = sequence[0]
except Exception:
print("does not support item lookup or item assignment")
else:
for i in range(0, len(sequence)-1, 2):
sequence[i], sequence[i+1] = sequence[i+1], sequence[i]
return sequence


>>> swap_items("abcd")
does not support item lookup or item assignment
>>> swap_items(['a', 'b', 'c', 'd', 'e', 'f'])
['b', 'a', 'd', 'c', 'f', 'e']




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


Re: [Tutor] recursive problem

2010-09-11 Thread Steven D'Aprano
On Sun, 12 Sep 2010 04:09:20 am Roelof Wobben wrote:

> > On Sun, 12 Sep 2010 03:40:38 am Roelof Wobben wrote:
> >> But why is type checking then wrong.
> >> Lets says I want a module who must work on strings, tuple and
> >> lists.
> >
> > It's not *always* wrong, but let me ask you... why do you want to
> > *limit* the function to work on ONLY strings, tuples and lists?

> Because I follow this book "Thinking like a computer scientist" and I
> have only read the chapters about strings. lists and tuples.

Good answer!

Don't worry about all the complications. Learn to walk first, then learn 
to run.



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


Re: [Tutor] exceptions problem

2010-09-11 Thread bob gailer

 On 9/11/2010 12:12 PM, Roelof Wobben wrote:





Date: Sat, 11 Sep 2010 11:05:54 -0400
From: bgai...@gmail.com
To: tutor@python.org
Subject: Re: [Tutor] exceptions problem

On 9/11/2010 6:56 AM, Peter Otten wrote:

Steven D'Aprano wrote:


On Sat, 11 Sep 2010 09:56:41 am bob gailer wrote:

I never thought that you can use a float and a integer to look if
the number is a integer.

You can't.

I made that comment in the context of the OPs function:

def readposint():
x = raw_input("Please enter a positive integer :")
try:
if (int(x)<0 or (float(x) - int(x)>  0)): raise(ValueError)
except:
print x , "is not a positive integer. Try again."
return -1
return x

The OP thought (incorrectly) that, given for example:
x = '3.1'
float(x) - int(x) would evaluate to 0.1

In reality int(x) in this case raises an exception.
ValueError: invalid literal for int() with base 10: '3.1'

Since the expression was in a try he could not tell exactly what was
happening.

I also don't quite understand the use of raise in the try.

I wish and hope that Roelof will learn how to do program walkthroughs
and use the interactive prompt to solve things himself. I applaud the
patience some of you have ih hand-holding him. I don't have that
patience. I wish him to learn to fish.

Hello Bob,

Oke, I try to  fish.


Thank you.



When I do

x= "a"
y= int(x)
Then I get ValueError.

When I do

x= 1.2
y=int(x)
No exception is raised.


As Dave pointed out you switched from string to numeric. Try instead x = 
'1.2'



But when I do then x ==y I get a false.
When I now do float(x) - int(x) I get 1.2 - 1 = 0.2 and that's greater then 0

Because one of the two is true the Raise is executed.


x = -9
y=int(x)
No exception is raised.
X == y is True.
But float(x) - int(x) I get 0.0 and 0.0>  0 is False.
Because x == y is True the Raise is executed.

Are these the right conclusions ??

Roelof



--
Bob Gailer
919-636-4239
Chapel Hill NC

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


[Tutor] SOLVED: Re: Trapping HTTP Authentication Failure

2010-09-11 Thread Michael Powe
Hello,

It is bloody Winblows.  The script works as designed and traps the 401
exception on my slackware box ... something in the implementation of
urllib2 on Windoze is broken.  This has to be a known issue.  Just did
not see it known anywhere.

Thanks.

mp

On Sat, Sep 11, 2010 at 02:16:07PM -0400, Michael Powe wrote:
> On Sat, Sep 11, 2010 at 10:48:13AM -0400, Michael Powe wrote:
> > On Sat, Sep 11, 2010 at 02:25:24PM +0200, Evert Rol wrote:
> > > 
> >  
> > > >> I'm not sure what you're exactly doing here, or what you're getting,
> > > >> but I did get curious and dug around urllib2.py. Apparently, there is
> > > >> a hardcoded 5 retries before the authentication really fails. So any
> > > >> stack trace would be the normal stack trace times 5. Not the 30 you
> > > >> mentioned, but annoying enough anyway (I don't see how it would fail
> > > >> for every element in the loop though. Once it raises an exception,
> > > >> the program basically ends).
>  
> > > > It never throws an exception.  Or, if it does, something about the way
> > > > I'm calling suppresses it.  IOW, I can put in a bogus credential and
> > > > start the script and sit here for 5 minutes and see nothing.  Then ^C
> > > > and I get a huge stacktrace that shows the repeated calls.  After the
> > > > timeout on one element in the list, it goes to the next element, times
> > > > out, goes to the next.
> 
> Hello,
> 
> More experimentation revealed that one problem was testing the script
> in Idle.  Idle does something to suppress the script failure for that
> particular case (IOW, it correctly returns HTTPError for things like
> '404' and URLError for things like a bad domain name).
> 
> When I run the script from the command line (cmd), it actually ignores
> the '5' retry limit, seemingly.  I added another catch block:
> 
> except Exception as e:
>  print "exception: ",e
> 
> That prints out "exception: maximum recursion depth exceeded."
> 
> I wonder if there is something hinky in Windows that is causing this
> to happen.
> 
> Thanks.
> 
> mp
>   
> > > Ok, now I had to try and recreate something myself. So my processData is:
> >  
> > > def processData(f):
> > >global overview_url
> > >overview_url = baseurl + f
> > >getData(authHeaders)
> > > 
> > > (f being a filename, out of a list of many). Other code same as yours.
> >  
> > > It definitely throws a 401 exception after 5 retries. No time-outs,
> > > no long waits. In fact, a time-out would to me indicate another
> > > problem (it still should throw an exception, though). So, unless
> > > you're catching the exception in processData somehow, I don't see
> > > where things could go wrong.
> > 
> > > I assume you have no problem with correct credentials or simply
> > > using a webbrowser?
> > 
> > Hello,
> > 
> > Yes, I can retrieve data without any problem.  I can break the URL and
> > generate a 404 exception that is trapped and I can break it in other
> > ways that generate other types of exceptions.  And trap them.
> > 
> > I went back and looked at the code in urllib2.py and I see the
> > timeout counter and that it raises an HTTPError after 5 tries.  But I
> > don't get anything back.  If I just let the code run to completion, I
> > get sent back to the prompt.  I put a try/catch in the method and I
> > already have one on the call in main.
> > 
> >  
> >  
> > > >> I don't know why it's hard-coded that way, and not just an option
> > > >> with a default of 5, but that's currently how it is (maybe someone
> > > >> else on this list knows?).
> > > > 
> > > > I don't know, but even if I could set it to 1, I'm not helped unless
> > > > there's a way for me to make it throw an exception and exit the loop. 
> > 
> > Actually, there's a comment in the code about why it is set to 5 --
> > it's arbitrary, and allows for the Password Manager to prompt for
> > credentials while not letting the request be reissued until 'recursion
> > depth is exceeded.'
> > 
> > I guess I'll have to go back to ground zero and write a stub to
> > generate the error and then build back up to where it disappears.
> > 
> > Thanks.
> > 
> > mp
> > 
> > -- 
> > Michael Powemich...@trollope.orgNaugatuck CT USA
> > It turns out that it will be easier to simply block the top offenders
> > manually; the rules for pattern matching are too arcane, obscure, and
> > difficult to program. -- t. pascal, comp.mail.misc, "procmail to
> > filter spam"
> 
> 
> 
> > ___
> > Tutor maillist  -  Tutor@python.org
> > To unsubscribe or change subscription options:
> > http://mail.python.org/mailman/listinfo/tutor
> 
> 
> -- 
> Michael Powe  mich...@trollope.orgNaugatuck CT USA
> I hate a fellow whom pride, or cowardice, or laziness drives into a
> corner, and who does nothing when he is there but sit and ; let
> him come out as I do, and . -- Samuel Johnson



> ___
> Tutor ma

Re: [Tutor] recursive problem

2010-09-11 Thread Lie Ryan
On 09/12/10 03:18, Steven D'Aprano wrote:
> Or you could do this:
> 
> if do_this_will_succeed() and do_that_will_succeed() \
> and do_something_else_will_succeed():
> do_this()
> do_that()
> do_something_else()
> else:
> do_error()
> 
> But that hasn't done anything to prevent race conditions. So the real 
> reason people use LBYL is that they're too lazy to write hideously 
> ugly, but reliable, code, and they're just hoping that they will never 
> expose the race condition. (Often this is a pretty safe hope, but not 
> always.)

Or, probably the best alternative is to mix LBYL and EAFP, e.g.:

attempt = 0
while attempt < 10:
# first acquire the lock using EAFP
try:
lock = acquire_lock()
except FailToAcquireLock:
attempt += 1
time.sleep(1)
else:
# Now apply LBYL, since there is no point in doing
# operations that may be expensive if they will definitely
# fail by the quick check
if account_active(fromAcc) and account_active(toAcc)
and can_withdraw(fromAcc, amount):

# this operations only writes to a scratch space
withdraw(fromAcc, amount)
deposit(toAcc, amount)

# back to EAFP, since there is no way of assuring
# this with LBYL
try:
# mark the scratch space as permanent change
commit()
except CommitFailure:
raise SeriousError("this can't be happening")
else:
finally:
# LBYL:
# there is no point in releasing unacquired lock;
# should probably be done inside release_lock() so that
# calling release_lock() an unacquired lock safely does nothing
if not lock:
release_lock(lock)
else:
raise Failure("failed to acquire lock")




else:
do_error("no privilege")

release_lock(lock)

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


[Tutor] recursive problem

2010-09-11 Thread Roelof Wobben




> From: rwob...@hotmail.com
> To: st...@pearwood.info
> Subject: RE: [Tutor] recursive problem
> Date: Sat, 11 Sep 2010 18:39:31 +
>
>
>
>
> 
>> From: st...@pearwood.info
>> To: tutor@python.org
>> Date: Sun, 12 Sep 2010 04:19:57 +1000
>> Subject: Re: [Tutor] recursive problem
>>
>> On Sun, 12 Sep 2010 04:09:20 am Roelof Wobben wrote:
>>
 On Sun, 12 Sep 2010 03:40:38 am Roelof Wobben wrote:
> But why is type checking then wrong.
> Lets says I want a module who must work on strings, tuple and
> lists.

 It's not *always* wrong, but let me ask you... why do you want to
 *limit* the function to work on ONLY strings, tuples and lists?
>>
>>> Because I follow this book "Thinking like a computer scientist" and I
>>> have only read the chapters about strings. lists and tuples.
>>
>> Good answer!
>>
>> Don't worry about all the complications. Learn to walk first, then learn
>> to run.
>>
>>
>>
>> --
>> Steven D'Aprano
>> ___
>> Tutor maillist - Tutor@python.org
>> To unsubscribe or change subscription options:
>> http://mail.python.org/mailman/listinfo/tutor
>

 Oke,

So EAFP for me is one step to far ?

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


[Tutor] exceptions problem

2010-09-11 Thread Roelof Wobben




> From: rwob...@hotmail.com
> To: bgai...@gmail.com
> Subject: RE: [Tutor] exceptions problem
> Date: Sat, 11 Sep 2010 18:51:12 +
>
>
>
>
> 
>> Date: Sat, 11 Sep 2010 14:43:28 -0400
>> From: bgai...@gmail.com
>> To: tutor@python.org
>> Subject: Re: [Tutor] exceptions problem
>>
>> On 9/11/2010 12:12 PM, Roelof Wobben wrote:
>>>
>>>
>>> 
 Date: Sat, 11 Sep 2010 11:05:54 -0400
 From: bgai...@gmail.com
 To: tutor@python.org
 Subject: Re: [Tutor] exceptions problem

 On 9/11/2010 6:56 AM, Peter Otten wrote:
> Steven D'Aprano wrote:
>
>> On Sat, 11 Sep 2010 09:56:41 am bob gailer wrote:
 I never thought that you can use a float and a integer to look if
 the number is a integer.
>>> You can't.
 I made that comment in the context of the OPs function:

 def readposint():
 x = raw_input("Please enter a positive integer :")
 try:
 if (int(x)<0 or (float(x) - int(x)> 0)): raise(ValueError)
 except:
 print x , "is not a positive integer. Try again."
 return -1
 return x

 The OP thought (incorrectly) that, given for example:
 x = '3.1'
 float(x) - int(x) would evaluate to 0.1

 In reality int(x) in this case raises an exception.
 ValueError: invalid literal for int() with base 10: '3.1'

 Since the expression was in a try he could not tell exactly what was
 happening.

 I also don't quite understand the use of raise in the try.

 I wish and hope that Roelof will learn how to do program walkthroughs
 and use the interactive prompt to solve things himself. I applaud the
 patience some of you have ih hand-holding him. I don't have that
 patience. I wish him to learn to fish.
>>> Hello Bob,
>>>
>>> Oke, I try to fish.
>>
>> Thank you.
>>
>>>
>>> When I do
>>>
>>> x= "a"
>>> y= int(x)
>>> Then I get ValueError.
>>>
>>> When I do
>>>
>>> x= 1.2
>>> y=int(x)
>>> No exception is raised.
>>
>> As Dave pointed out you switched from string to numeric. Try instead x =
>> '1.2'

Then I get a ValueError when I do y=int('1.2')
So it will Raise the error.

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


Re: [Tutor] design question

2010-09-11 Thread Albert-Jan Roskam
Hi Jan and Steven,

Thanks a lot for your valuable comments. I greatly appreciate you looking into 
it.

Steven, you recommend to <>. On 
one website it was mentioned that "To a young boy with a hammer, everything 
looks like a nail". Which meant to say that just because you CAN use a design 
pattern, it doesn't mean you SHOULD. This corresponds with your advice!

 Cheers!!
Albert-Jan


~~
All right, but apart from the sanitation, the medicine, education, wine, public 
order, irrigation, roads, a fresh water system, and public health, what have 
the 
Romans ever done for us?
~~





From: Steven D'Aprano 
To: tutor@python.org
Sent: Sat, September 11, 2010 10:40:17 AM
Subject: Re: [Tutor] design question

On Sat, 11 Sep 2010 12:11:37 am Albert-Jan Roskam wrote:

> Inside my program I have to keep a list of all the image files that
> are scheduled for data entry. 

Sounds like you need to keep a list of all the image files that are 
scheduled for data entry then.


> The main purpose is to be able to read 
> in the image files one by one. Another one of the purposes of this
> list is to show some information on the title bar. 

No it isn't. You don't need a list of image files in order to show "some 
information" in the title bar (unless that information is the list of 
files). From your earlier post, you want to show:

filename 23 of 245 (9.4%)

or similar. For that, all you need is three pieces of information:

* the name of the current file
* the number of the current file
* the total number of files

You don't need all 245 files for that.

I'm being pedantic here. Obviously you need the list of files 
*somewhere*, and you need it for other reasons, but you don't *need* a 
list of 243 files in order to show the name of one of them!

You may decide that it is *convenient* to give the function which 
changes the title bar access to the entire list, but it's not a 
*requirement*. Think about alternatives: 

def change_titlebar(name, count, total):
template = "%s %d of %d (%.1f %%)"
percentage = count*100.0/total
title = template % (name, count, total, percentage)
do_magic_with(title)  # whatever it takes to change the title

It doesn't need the entire list.


> Currently, my 
> program only has a 'next' button and the fact that implementing a
> 'previous' button is causing problems suggests to me that I have to
> look for a more fundamentally better solution.

Sounds to me that you *don't* want the iterator pattern. The iterator 
pattern generally means that you step forward through each item. If you 
want to advance backwards or forwards, something with random access is 
probably better. That would probably mean a list.

Don't be too hung up about "design patterns". Most design patterns just 
exist to work around limitations of the language, lack of power, or 
slavish devotion to object oriented programming when the problem is 
crying out for a functional or procedural solution. Don't be afraid to 
write functions instead of classes -- there's no need for a 
TitlebarManipulator class just to change the titlebar.

My solution would be to keep *two* pieces of information:

* the list of filenames;
* the current position in that list

Set the current position to 0, and have the Next button add one to the 
position and refresh the page, and Prev subtract one and refresh the 
page. Obviously you need code to ensure that the position doesn't go 
out of bounds, code to save the data in the fields, and so forth. The 
page refresh code should do something like:

* given the current position, extract the filename to use;
* change the title bar;
* open and display the appropriate image;
* pre-populate any fields;
etc.

Good luck!


-- 
Steven D'Aprano
___
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


Re: [Tutor] recursive problem

2010-09-11 Thread Walter Prins
Just a quick contribution for what it's worth: One of the subjects being
implicitly talked about here is "introspection" -- you may want to google
that and see else you can find. That said, a nice article covering some of
Python's introspection features is presented here on IBM's site:
http://www.ibm.com/developerworks/library/l-pyint.html

Actually any user
that's used to doing introspection in the Python shell already has that same
tool at their disposal for programmatic introspection, e.g. the dir()
method.  (This is covered in the above article.)

So, perhaps it's an idea to call dir() on a given object and see whether the
object provides the necessary methods to function, e.g. __iter__,
__delitem__, __setitem__ and friends?

Here's some code which constructs a class from scratch, which contains 2
member variables, which are made available via list indexing by implementing
__getitem__ and _setitem__ and shows how you can then use that object as if
it's a list, as least as far as the first 2 elements are concerned.  Also
does some interrogation with dir() at the end.

http://pastebin.com/rRZpbham

Hope that helps,

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


Re: [Tutor] recursive problem

2010-09-11 Thread Steven D'Aprano
On Sun, 12 Sep 2010 09:03:49 am Walter Prins wrote:

> So, perhaps it's an idea to call dir() on a given object and see
> whether the object provides the necessary methods to function, e.g.
> __iter__, __delitem__, __setitem__ and friends?

There's no need to do this:

attributes = dir(obj)
if '__iter__' in attributes and '__len__' in attributes:
print "Quacks like a list"
else:
print "Not like a list"


when you can do this:


if hasattr(obj, '__iter__') and hasattr(obj, '__len__'):
print "Quacks like a list"
else:
print "Not like a list"


or this:

try:
obj.__iter__
obj.__len__
except AttributeError:
print "Not like a list"
else:
print "Quacks like a list"


or even 

try:
iter(obj)
len(obj)
except TypeError:
print "Not like a list"
else:
print "Quacks like a list"


Where possible, the last version is to be preferred, because it doesn't 
care about internal details which might change.



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