Re: [Tutor] What's the keyword for the Python creed?

2011-09-16 Thread Richard D. Moores
On Thu, Sep 15, 2011 at 23:47, Christian Witts  wrote:

> from __future__ import braces

Ha! (2.7 and 3.x)

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


[Tutor] If statement optimization

2011-09-16 Thread bodsda
Hi,

In a normal if,elif,elif,...,else statement, are the conditions checked in a 
linear fashion?

I am wondering if I should be making an effort to put the most likely true 
condition at the beginning of the block

Thanks,
Bodsda 
Sent from my BlackBerry® wireless device
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] If statement optimization

2011-09-16 Thread Steven D'Aprano

bod...@googlemail.com wrote:

Hi,

In a normal if,elif,elif,...,else statement, are the conditions checked in a 
linear fashion?


Yes.



I am wondering if I should be making an effort to put the most likely true 
condition at the beginning of the block


Probably not. The amount of time used in the average if...elif is 
unlikely to be significant itself. Don't waste your time trying to 
optimize something like this:



if n < 0:
   ...
elif n == 0:
   ...
else:
   ...


However, there are exceptions.

If the tests are very expensive, then it might be worthwhile putting the 
most likely case first. Or at least, put the cheapest cases first, leave 
the expensive ones for last:


if sum(mylist[1:]) > 1000 and mylist.count(42) == 3 and min(mylist) < 0:
...
elif len(mylist) < 5:
...

I probably should swap the order there, get the cheap len() test out of 
the way, and only perform the expensive test if that fails.



If you have LOTS of elif cases, like *dozens*, then firstly you should 
think very hard about re-writing your code, because that's pretty poor 
design... but if you can't change the design, then maybe it is 
worthwhile to rearrange the cases.


If you have something like this:


if s == "spam":
func_spam(x)
elif s == "ham":
func_ham(x)
elif s == "cheese":
func_cheese(x)


you can often turn this into a dispatch table:


table = {"spam": func_spam, "ham": func_ham, "cheese": func_cheese}
func = table[s]  # lookup in the dispatch table
func(x)  # finally call the function


Note that inside table, you don't call the functions.

This pattern is especially useful, as lookup in a table in this manner 
takes close enough to constant time, whether there is one item or a million.




--
Steven

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


Re: [Tutor] If statement optimization

2011-09-16 Thread bodsda
Thanks for the explanation - very clear.

Cheers,
Bodsda 
Sent from my BlackBerry® wireless device

-Original Message-
From: Steven D'Aprano 
Sender: tutor-bounces+bodsda=googlemail@python.org
Date: Fri, 16 Sep 2011 20:43:45 
To: Tutor - python List
Subject: Re: [Tutor] If statement optimization

bod...@googlemail.com wrote:
> Hi,
> 
> In a normal if,elif,elif,...,else statement, are the conditions checked in a 
> linear fashion?

Yes.


> I am wondering if I should be making an effort to put the most likely true 
> condition at the beginning of the block

Probably not. The amount of time used in the average if...elif is 
unlikely to be significant itself. Don't waste your time trying to 
optimize something like this:


if n < 0:
...
elif n == 0:
...
else:
...


However, there are exceptions.

If the tests are very expensive, then it might be worthwhile putting the 
most likely case first. Or at least, put the cheapest cases first, leave 
the expensive ones for last:

if sum(mylist[1:]) > 1000 and mylist.count(42) == 3 and min(mylist) < 0:
 ...
elif len(mylist) < 5:
 ...

I probably should swap the order there, get the cheap len() test out of 
the way, and only perform the expensive test if that fails.


If you have LOTS of elif cases, like *dozens*, then firstly you should 
think very hard about re-writing your code, because that's pretty poor 
design... but if you can't change the design, then maybe it is 
worthwhile to rearrange the cases.

If you have something like this:


if s == "spam":
 func_spam(x)
elif s == "ham":
 func_ham(x)
elif s == "cheese":
 func_cheese(x)


you can often turn this into a dispatch table:


table = {"spam": func_spam, "ham": func_ham, "cheese": func_cheese}
func = table[s]  # lookup in the dispatch table
func(x)  # finally call the function


Note that inside table, you don't call the functions.

This pattern is especially useful, as lookup in a table in this manner 
takes close enough to constant time, whether there is one item or a million.



-- 
Steven

___
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] Please review my code

2011-09-16 Thread R. Alan Monroe

> It was only tested on a Windows Box, but I see no reason why it would not
> work on Unix family. https://github.com/janus/Text-Twist
> I need you comments.

I think you forgot to upload some needed images along with the python
code:

['abase', 'abased', 'abed', 'ads', 'baa', 'baas', 'bad', 'bade', 'bas', 'base', 
'based', 'bead', 'beads', 'bed', 'beds', 'dab', 'dab
s', 'debs', 'sad', 'sea']
Traceback (most recent call last):
  File "haPu3.py", line 36, in 
IMAGE = PhotoImage(file=doom_image)  #'C:\Python_way\doom2.gif')
  File "c:\python25\lib\lib-tk\Tkinter.py", line 3294, in __init__
Image.__init__(self, 'photo', name, cnf, master, **kw)
  File "c:\python25\lib\lib-tk\Tkinter.py", line 3250, in __init__
self.tk.call(('image', 'create', imgtype, name,) + options)
_tkinter.TclError: couldn't open ".\doom2.gif": no such file or directory

Alan

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


Re: [Tutor] Strange zip syntax

2011-09-16 Thread Albert-Jan Roskam
Hi,
 
I would write the slightly longer, but more readable (for me at least) code:
>>> a = ['a','1','b','2','c','3']
>>> [(a[i], a[i+1]) for i in range(0, len(a), 2)]
[('a', '1'), ('b', '2'), ('c', '3')]
>>> zip(*[iter(a)]*2)
[('a', '1'), ('b', '2'), ('c', '3')]
 
And it's also faster:
 
>>> import timeit
>>> t = timeit.Timer("zip(*[iter(['a', '1', 'b', '2', 'c', '3'])]*2)")
>>> t.timeit()
5.1758860413823555
>>> t = timeit.Timer("a=['a', '1', 'b', '2', 'c', '3']; [(a[i], a[i+1]) for i 
>>> in range(0, len(a), 2)]")
>>> t.timeit()
2.5330216549868823
>>> 

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: Brett Ritter 
>To: *tutor python 
>Sent: Friday, September 16, 2011 4:35 AM
>Subject: [Tutor] Strange zip syntax
>
>I ran into this article (
>http://blog.adku.com/2011/09/hodgepodge-of-python.html ) and found
>myself temporarily stymied by one line it in:
>
>zip(*[iter(a)]*2)
>
>Used like this:
>
 a = ['a','1','b','2','c','3']
 zip(*[iter(a)]*2)
>[('a', '1'), ('b', '2'), ('c', '3')]
>
>While I'm unlikely to use such a construct (if I can't easily follow
>it now, I or my successor likely won't follow it should it need to be
>debugged sometime in the future), I found the education I got in
>deciphering it was worth the effort.  I'm sharing it here so others
>can benefit from my puzzlement.
>
>iter(a) returns a list iterator for a.  See help(iter) for more.
>[iter(a)] is a list containing one element, an iterator.  This is
>created only so we can do the below:
>[iter(a)]*2 is a list containing two elements, each the SAME list iterator.
>For simplicity, let's break this out for further analysis:
>
 b = iter(a)
 c = [b,b]
>
>*[iter(a)]*2 flattens the list when passed into a function call.
>Using our more verbose but simple syntax: *c.  This only works when
>passed to a function.
>zip() creates tuples each holding the Nth elements from a number of
>sequences.  See help(zip) for more.
>Thus, zip(a) or zip(a,a) would return:
 zip(a)
>[('a',), ('1',), ('b',), ('2',), ('c',), ('3',)]
 zip(a,a)
>[('a', 'a'), ('1', '1'), ('b', 'b'), ('2', '2'), ('c', 'c'), ('3', '3')]
>
>What happens when we pass an iterator to zip?  That's not mentioned in
>the docstring blurb.
 zip(iter(a))
>[('a',), ('1',), ('b',), ('2',), ('c',), ('3',)]
>Answer: It works as intended.
>
>Now we come to the magic of this little snippet.
>zip(iter(a),iter(a)) wouldn't work, because each call to iter(a)
>returns a DIFFERENT iterator.
 zip(iter(a), iter(a))
>[('a', 'a'), ('1', '1'), ('b', 'b'), ('2', '2'), ('c', 'c'), ('3', '3')]
>
>But by creating the list of two elements each of which is the SAME
>iterator, as each is asked to iterate it advances the common element
>indicator:
 zip(*c)
>[('a', '1'), ('b', '2'), ('c', '3')]
>Notice that the flattening is required, because zip needs to get
>multiple arguments:
 b = iter(a)  #our original iterator is spent, so we're assigning a new one
 c = [b,b]
 zip(c)  #Not flattened, is just a single list, like a.
>[(,), (0x024E32D0>,)]
 zip(b,b)  # here it is two iterators sent to zip() (though they happen to 
 be the SAME iterator)
>[('a', '1'), ('b', '2'), ('c', '3')]
>
>I hope some of you enjoy playing with this, and hopefully someone
>learned something useful!  While I'm not likely to use the listed
>form, I can very well see myself saying:
>
 a = ['a','1','b','2','c','3']  #well, I can see myself using this with 
 meaningful variable names
 b = iter(a)
 zip(b,b)  # Group in sets of 2 elements
>
>-- 
>Brett Ritter / SwiftOne
>swift...@swiftone.org
>___
>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] Strange zip syntax

2011-09-16 Thread Emeka
iBrett,

iter

On Fri, Sep 16, 2011 at 3:35 AM, Brett Ritter  wrote:

> I ran into this article (
> http://blog.adku.com/2011/09/hodgepodge-of-python.html ) and found
> myself temporarily stymied by one line it in:
>
> zip(*[iter(a)]*2)
>
> Used like this:
>
> >>> a = ['a','1','b','2','c','3']
> >>> zip(*[iter(a)]*2)
> [('a', '1'), ('b', '2'), ('c', '3')]
>
> While I'm unlikely to use such a construct (if I can't easily follow
> it now, I or my successor likely won't follow it should it need to be
> debugged sometime in the future), I found the education I got in
> deciphering it was worth the effort.  I'm sharing it here so others
> can benefit from my puzzlement.
>
> iter(a) returns a list iterator for a.  See help(iter) for more.
> [iter(a)] is a list containing one element, an iterator.  This is
> created only so we can do the below:
> [iter(a)]*2 is a list containing two elements, each the SAME list iterator.
> For simplicity, let's break this out for further analysis:
>
> >>> b = iter(a)
> >>> c = [b,b]
>

iter(c) returns listiterator



>
> *[iter(a)]*2 flattens the list when passed into a function call.
> Using our more verbose but simple syntax: *c.  This only works when
> passed to a function.
> zip() creates tuples each holding the Nth elements from a number of
> sequences.  See help(zip) for more.
> Thus, zip(a) or zip(a,a) would return:
> >>> zip(a)
> [('a',), ('1',), ('b',), ('2',), ('c',), ('3',)]
> >>> zip(a,a)
> [('a', 'a'), ('1', '1'), ('b', 'b'), ('2', '2'), ('c', 'c'), ('3', '3')]
>
> What happens when we pass an iterator to zip?  That's not mentioned in
> the docstring blurb.
> >>> zip(iter(a))
> [('a',), ('1',), ('b',), ('2',), ('c',), ('3',)]
> Answer: It works as intended.
>
> Now we come to the magic of this little snippet.
> zip(iter(a),iter(a)) wouldn't work, because each call to iter(a)
> returns a DIFFERENT iterator.
> >>> zip(iter(a), iter(a))
> [('a', 'a'), ('1', '1'), ('b', 'b'), ('2', '2'), ('c', 'c'), ('3', '3')]
>
> But by creating the list of two elements each of which is the SAME
> iterator, as each is asked to iterate it advances the common element
> indicator:
> >>> zip(*c)
> [('a', '1'), ('b', '2'), ('c', '3')]
> Notice that the flattening is required, because zip needs to get
> multiple arguments:
> >>> b = iter(a)  #our original iterator is spent, so we're assigning a new
> one
> >>> c = [b,b]
> >>> zip(c)   #Not flattened, is just a single list, like a.
> [(,), ( 0x024E32D0>,)]
> >>> zip(b,b)   # here it is two iterators sent to zip() (though they happen
> to be the SAME iterator)
> [('a', '1'), ('b', '2'), ('c', '3')]
>
> I hope some of you enjoy playing with this, and hopefully someone
> learned something useful!  While I'm not likely to use the listed
> form, I can very well see myself saying:
>
> >>> a = ['a','1','b','2','c','3']   #well, I can see myself using this with
> meaningful variable names
> >>> b = iter(a)
> >>> zip(b,b)  # Group in sets of 2 elements
>
> --
> Brett Ritter / SwiftOne
> swift...@swiftone.org
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>



-- 
*Satajanus  Nig. Ltd


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


Re: [Tutor] Please review my code

2011-09-16 Thread Emeka
Hello Alan,

My bad, I have added the missing folder.

To all, please make out time and review my code. I would like to have your
comments.

https://github.com/janus/Text-Twist

Regards,
emeka

On Fri, Sep 16, 2011 at 1:20 PM, R. Alan Monroe wrote:

>
> > It was only tested on a Windows Box, but I see no reason why it would not
> > work on Unix family. https://github.com/janus/Text-Twist
> > I need you comments.
>
> I think you forgot to upload some needed images along with the python
> code:
>
> ['abase', 'abased', 'abed', 'ads', 'baa', 'baas', 'bad', 'bade', 'bas',
> 'base', 'based', 'bead', 'beads', 'bed', 'beds', 'dab', 'dab
> s', 'debs', 'sad', 'sea']
> Traceback (most recent call last):
>  File "haPu3.py", line 36, in 
>IMAGE = PhotoImage(file=doom_image)  #'C:\Python_way\doom2.gif')
>  File "c:\python25\lib\lib-tk\Tkinter.py", line 3294, in __init__
>Image.__init__(self, 'photo', name, cnf, master, **kw)
>  File "c:\python25\lib\lib-tk\Tkinter.py", line 3250, in __init__
>self.tk.call(('image', 'create', imgtype, name,) + options)
> _tkinter.TclError: couldn't open ".\doom2.gif": no such file or directory
>
> Alan
>
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>



-- 
*Satajanus  Nig. Ltd


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