Re: for / while else doesn't make sense

2016-05-19 Thread Stephen Hansen
On Thu, May 19, 2016, at 07:02 PM, gst wrote:
> Python 4.0 ? My son will thank us !

No, he won't, because while Python 4.0 will happen, likely after Python
3.9, it will not be a major backwards compatible breaking point.

Some people infer that because 3.0 was, 4.0, 5.0, 6.0 are open to it.
They aren't.

-- 
Stephen Hansen
  m e @ i x o k a i . i o
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-19 Thread Bob Martin
in 759855 20160519 185500 Jon Ribbens  wrote:
>On 2016-05-19, Steven D'Aprano  wrote:
>> On Fri, 20 May 2016 02:31 am, Herkermer Sherwood wrote:
>>> Most keywords in Python make linguistic sense, but using "else" in for and
>>> while structures is kludgy and misleading. I am under the assumption that
>>> this was just utilizing an already existing keyword. Adding another like
>>> "andthen" would not be good.
>>
>> If I could steal the keys to Guido's time machine, I would go back in time
>> and change the for...else and while...else keywords to for...then and
>> while...then.
>
>I guess we should thank our lucky stars that you don't have a time
>machine then, since that change would very much be one for the worse
>in my opinion. for...else is perfectly straightforward and clearly
>the right keywords to use. for...then would be entirely wrong.

Yes.  "else" and "then" have opposite meanings.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Summing/combining tuples

2016-05-19 Thread Larry Hudson via Python-list

On 05/18/2016 09:53 PM, DFS wrote:

On 5/18/2016 10:58 PM, Larry Hudson wrote:

[snip...]

Why two loops?  Put both summations in a single loop.  Then you're only
scanning the alist once instead of twice.

groups1 = defaultdict(int)
groups2 = defaultdict(int)
for nm, matches, words in alist:
groups1[nm] += matches
groups2[nm] += words

 -=- Larry -=-



That gives me two lists - how do I combine them?

In the end that'll be at least 6 lines of code.  Do you have a one-liner to 
summarize the data?

Thanks


One-liner?  No way.  I did manage to get the whole conversion down to 6 lines...
(And I am far from an expert pythonista, a more experienced/expert programmer can probably do 
better.)


A two-line helper function
A two-line for loop
A one-line list comprehension
One line to declare a dictionary as an intermediate variable

#  A helper function -- adds two tuples
#  Could add square brackets to return a 2-element list instead of
#  a tuple, but the final result is the same either way.
def addtpl(t1, t2):
return t1[0]+t2[0], t1[1]+t2[1]

#  Accumulate alist data into an intermediate temporary dictionary
tdic = {}
for dat in alist:
tdic[dat[1]] = addtpl(tdic.get(dat[1], (0,0)), dat[2:])

#  Convert the dictionary back to a list of tuples
result = [(str(n), tdic[n][0], tdic[n][1]) for n in tdic]

Of course, this doesn't retain the original order, but you can use the sorted() function to sort 
the results by the names.


Here is the same thing as a single function that returns the sorted list...
(It also automatically throws away the temporary dictionary.  But it's now 7 lines because of 
the added def line.)


def combine(lst):
def addtpl(t1, t2):
return [t1[0]+t2[0], t1[1]+t2[1]
tdic = {}
for dat in lst:
tdic[dat[1]] = addtpl(tdic.get(dat[1], (0,0)), dat[2:])
return sorted([(str(n), tdic[n][0], tdic[n][1]) for n in tdic])

 -=-Larry -=-

--
https://mail.python.org/mailman/listinfo/python-list


Re: OrderedDict

2016-05-19 Thread silver0346
On Wednesday, May 18, 2016 at 2:25:16 PM UTC+2, Peter Otten wrote:
> Chris Angelico wrote:
> 
> > On Wed, May 18, 2016 at 7:28 PM, Peter Otten <__pete...@web.de> wrote:
> >> I don't see an official way to pass a custom dict type to the library,
> >> but if you are not afraid to change its source code the following patch
> >> will allow you to access the value of dictionaries with a single entry as
> >> d[0]:
> >>
> >> $ diff -u py2b_xmltodict/local/lib/python2.7/site-packages/xmltodict.py
> >> py2_xmltodict/local/lib/python2.7/site-packages/xmltodict.py
> >> --- py2b_xmltodict/local/lib/python2.7/site-packages/xmltodict.py  
> >> 2016-05-18 11:18:44.0 +0200
> >> +++ py2_xmltodict/local/lib/python2.7/site-packages/xmltodict.py   
> >> 2016-05-18 11:11:13.417665697 +0200 @@ -35,6 +35,13 @@
> >>  __version__ = '0.10.1'
> >>  __license__ = 'MIT'
> >>
> >> +_OrderedDict = OrderedDict
> >> +class OrderedDict(_OrderedDict):
> >> +def __getitem__(self, key):
> >> +if key == 0:
> >> +[result] = self.values()
> >> +return result
> >> +return _OrderedDict.__getitem__(self, key)
> >>
> >>  class ParsingInterrupted(Exception):
> >>  pass
> > 
> > Easier than patching might be monkeypatching.
> > 
> > class OrderedDict(OrderedDict):
> > ... getitem code as above ...
> > xmltodict.OrderedDict = OrderedDict
> > 
> > Try it, see if it works.
> 
> It turns out I was wrong on (at least) two accounts: 
> 
> - xmltodict does offer a way to specify the dict type
> - the proposed dict implementation will not solve the OP's problem
> 
> Here is an improved fix which should work:
> 
> 
> $ cat sample.xml 
> 
> 
>   
>   
>   
> 
> $ cat sample2.xml 
> 
> 
>   
>   
>   
>   
> 
> $ cat demo.py
> import collections
> import sys
> import xmltodict
> 
> 
> class MyOrderedDict(collections.OrderedDict):
> def __getitem__(self, key):
> if key == 0 and len(self) == 1:
> return self
> return super(MyOrderedDict, self).__getitem__(key)
> 
> 
> def main():
> filename = sys.argv[1]
> with open(filename) as f:
> doc = xmltodict.parse(f.read(), dict_constructor=MyOrderedDict)
> 
> print "doc:\n{}\n".format(doc)
> print "package-id: {}".format(
> doc['profiles']['profile']['package'][0]['@package-id'])
> 
> 
> if __name__ == "__main__":
> main()
> $ python demo.py sample.xml 
> doc:
> MyOrderedDict([(u'profiles', MyOrderedDict([(u'profile', 
> MyOrderedDict([(u'@id', u'visio02'), (u'@revision', u'2015051501'), 
> (u'package', MyOrderedDict([(u'@package-id', u'0964-gpg4win')]))]))]))])
> 
> package-id: 0964-gpg4win
> $ python demo.py sample2.xml 
> doc:
> MyOrderedDict([(u'profiles', MyOrderedDict([(u'profile', 
> MyOrderedDict([(u'@id', u'visio02'), (u'@revision', u'2015051501'), 
> (u'package', [MyOrderedDict([(u'@package-id', u'0964-gpg4win')]), 
> MyOrderedDict([(u'@package-id', u'0965-gpg4win')])])]))]))])
> 
> package-id: 0964-gpg4win

I have tested the first solution. Works nice. Before I used xml.etree to parse 
2000 xml files. 

Execution time decrease from more then 5 min to 20 sec. Great. On weekend I 
will test the solution with the own class.

Many thanks.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-19 Thread gst
I know this does not bring anything valuable but:

Definitively agree with your mental model !! 'then' and only "then" is the best 
keyword in the situation which is on the table right now.

it totally fix the confusing "else" actual mess (for at least 2 reasons).

Python 4.0 ? My son will thank us !

NB: 
- I'm not a native English speaker
- but I'm using the "(for,while)/else" way sometimes, but damn the "then" 
keyword is at least better here !
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-19 Thread Steven D'Aprano
On Fri, 20 May 2016 03:55 am, Jon Ribbens wrote:

> I guess we should thank our lucky stars that you don't have a time
> machine then, since that change would very much be one for the worse
> in my opinion. for...else is perfectly straightforward and clearly
> the right keywords to use. for...then would be entirely wrong.

"Entirely" wrong? "Clearly" the right keyword? "Perfectly" straightforward?

They are extremely strong words given the posts where *even the defenders*
of "else" have admitted that it is a hard keyword to understand. But that's
okay. Maybe you've thought of something the rest of us haven't, and have an
entire consistent mental model of for...else that is easy to understand and
makes it "perfectly straightforward and clearly the right keyword".

Can you explain your model which makes "else" appropriate?

In my experience, some people (including me) misunderstand "for...else" to
mean that the else block runs if the for block *doesn't*. It took me the
longest time to understand why this didn't work as I expected:

for x in seq:
pass
else:
print("seq is empty")

because like many people, my mental model was "the for block runs, OR ELSE
the else block runs". This *incorrect* model seems like it works: if you
set seq=[], say, it prints "seq is empty" as expected.

But its wrong: set seq=[1, 2, 3], and it *still* prints "seq is empty". My
model of what was going on was faulty.

I never would have thought of that model if it had been called "then":

for x in seq:
pass
then:
print("executes after the for block completes")

which describes what actually happens: regardless of whether seq is empty or
not, the loop runs, THEN the "else" block unconditionally executes. That
has the advantage of also matching the implementation, both as byte-code,
and in C.

I've seen people assume that the for loop actually sets a hidden flag to
record whether or not a break was executed. There is no flag. It simply
doesn't get executed because code execution jumps past it.

But please do explain your execution model of "for...else". If it is better
than mine, I'll be happy to use it instead.



-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-19 Thread Gregory Ewing

Herkermer Sherwood wrote:

But there is already a reserved keyword that would work great here.
"finally".

Unfortunately, it wouldn't follow the semantics of try/except/else/finally.

Is it better to follow the semantics used elsewhere in the language, or
have the language itself make sense semantically?


I think using "finally" this way would be more confusing
than the status quo. Currently, if you see a "finally"
somewhere, it means the block following is always executed
come what may. But with this change, you would need to
look up some arbitrary distance to see whether it belonged
to a "try" or a "for".

It's not so bad with "else" because you need to look back
to find out what condition the "else" refers to anyway.

--
Greg
\
--
https://mail.python.org/mailman/listinfo/python-list


Re: Resources/pointers for writing maintable, testable Python

2016-05-19 Thread Terry Reedy

On 5/19/2016 4:10 PM, Mike Driscoll wrote:

On Thursday, May 19, 2016 at 11:23:53 AM UTC-5, Terry Reedy wrote:



In my case, I learned better how to test IDLE from a user perspective.
For tkinter apps, an external program such as Selenium is not needed.
Tk/tkinter have the simulated event generation and introspection needed
to simulate a user hitting keys, clicking mouse buttons, and reading the
screen.



I am curious. Where is this documented? Are you referring to calling

> the invoke() method on each widget?

For widget commands, yes.  (And thanks for reminding of the method.)

For events:
http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/universal.html
(An indispensible tkinter reference) says:
'''
w.event_generate(sequence, **kw)

This method causes an event to trigger without any external 
stimulus. The handling of the event is the same as if it had been 
triggered by an external stimulus. The sequence argument describes the 
event to be triggered. You can set values for selected fields in the 
Event object by providing keyword=value arguments, where the keyword 
specifies the name of a field in the Event object.


See Section 54, “Events” for a full discussion of events.
'''
This omits some essentials.  tcl.tk/man/tcl8.6/TkCmd/event.htm
has much more, including the need to put focus on Text and Entry.

From Stackoverflow, I learned that .update() is needed *before* 
.event_generate.  The following works.


import tkinter as tk
root = tk.Tk()
def prt():
print('Handler called')
button = tk.Button(root, text='Click', command=prt)
button.place(x=20, y=20)
def ev(e):
print(e.x, e.y)
button.bind('', ev)
button.update()
button.event_generate('', x=0, y=0)
button.event_generate('')
button.invoke()
entry=tk.Entry(root)
entry.place(x=20, y=50)
entry.focus_force()
entry.update()
entry.event_generate('')

The event is reported, the handler is called, and 'a' is inserted. 
(Inserting text could be done more easily, but some key events such as 
 do have text equivalents.)


--
Terry Jan Reedy



--
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-19 Thread David Jardine
On Thu, May 19, 2016 at 11:47:28AM -0700, theh...@gmail.com wrote:
> This is exactly what I'm referencing. We can do mental gymnastics for it 
> to make sense, but remove the `break` in your code and what happens? The 
> logic goes away. 

Quite.  What would the code mean?  Why would you use "else" if you were
always going to drop out of the end of the loop anyway?  You need it in
a situation where you're "hoping" to find something: meet the 6.30 train
at the station, look at each passenger that gets off and if one is
wearing a pink carnation in his/her buttonhole go off together and live 
happily ever after.  But when the last passenger has got off and you 
haven't seen a pink carnation?  That's where the "else" clause comes in.
You hope you won't need it.

> [...]

> On Thursday, May 19, 2016 at 10:22:31 AM UTC-7, Ned Batchelder wrote:
> > 
> > [...]
> > 
> > For/else has always caused people consternation.
> > 
> > My best stab at explaining it is this: the else clause is executed if no
> > break was encountered in the body of the for loop.  A simple structure
> > would look like this:
> > 
> > for thing in container:
> > if something_about(thing):
> > # Found it!
> > do_something(thing)
> > break
> > else:
> > # Didn't find it..
> > no_such_thing()
> > 
> > I think of the "else" as being paired with the "if" inside the loop.
> > At run time, you execute a number of "if"s, one for each iteration
> > around the loop.  The "else" is what gets executed if none of the
> > "if"s was true.  In that sense, it's exactly the right keyword to
> > use.
> > 

Cheers,
David
-- 
https://mail.python.org/mailman/listinfo/python-list


Python script reading from sys.stdin and debugger

2016-05-19 Thread Fillmore

Hello PyMasters!

Long story short:

cat myfile.txt | python -m pdb myscript.py

doens't work (pdb hijacking stdin?).

Google indicates that someone has fixed this with named pipes, but, call 
me stupid, I don't understand how I need to set up those pipes, how I 
need to modify my script and, above all, how I now need to invoke the 
program.


Help and suggestions appreciated. I am using Python 3.4 on Cygwin and 
Ubuntu.


Thanks

--
https://mail.python.org/mailman/listinfo/python-list


Re: Python 3.5.1

2016-05-19 Thread Terry Reedy

On 5/19/2016 12:47 PM, Bella via Python-list wrote:


Thisis my first encountering with Python. I have successfully
downloaded Python3.5.1 for Windows but see only a black window with
command prompt.


If you start Python from the Python directory on the Start menu, you 
should see a black window with a '>>> ' prompt.  This is the interactive 
Python prompt.  The title bar should also say 'Python'.  If you open a 
Windows Command Prompt window, it will have a different title and a 
'/User/login_name>' prompt (on Win 10).


> I do not see IDLE under PYthon on Windows Start Menu.

Perhaps you unclicked the option to install tkinter, IDLE, and turtle. 
In the Python window, enter 'import tkinter' and report the result.



Downloaded version of Python is based on 32-bit and my PC is 64-bit.


That is not a problem.  What Windows version?  If XP, 3.5 will not work.

--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-19 Thread Marko Rauhamaa
theh...@gmail.com:

> This is exactly what I'm referencing. We can do mental gymnastics for
> it to make sense,

Programming languages are not English. Any resemblance is purely
coincidental.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-19 Thread Chris Angelico
On Fri, May 20, 2016 at 6:11 AM, Ian Kelly  wrote:
> On Thu, May 19, 2016 at 2:01 PM, Chris Angelico  wrote:
>> On Fri, May 20, 2016 at 3:46 AM, Steven D'Aprano  wrote:
>>> The idea of finally is
>>> that it executes no matter what happens[1].
>>>
>>> [1] Well, *almost* no matter what. If you pull the power from the computer,
>>> the finally block never gets a chance to run.
>>
>> Nor if you kill -9 the process, or get into an infinite loop, or any
>> number of other things. Specifically, what the finally block
>> guarantees is that it will be executed *before any code following the
>> try block*. In this example:
>>
>> try:
>> code1
>> except Exception:
>> code2
>> else:
>> code3
>> finally:
>> code4
>> code5
>>
>> Once you hit code1, you are absolutely guaranteed that code5 *will
>> not* be run prior to code4.
>
> The guarantee is stronger than that. It's possible to exit the try
> block without passing execution to code5 at all. The finally block is
> still guaranteed to be executed in this case.

Yes, but I don't know how to depict "other code outside of the try
block" in a way that doesn't fall foul of other nitpicks like "well,
you could call that function from within the try block" :)

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-19 Thread Ian Kelly
On Thu, May 19, 2016 at 2:01 PM, Chris Angelico  wrote:
> On Fri, May 20, 2016 at 3:46 AM, Steven D'Aprano  wrote:
>> The idea of finally is
>> that it executes no matter what happens[1].
>>
>> [1] Well, *almost* no matter what. If you pull the power from the computer,
>> the finally block never gets a chance to run.
>
> Nor if you kill -9 the process, or get into an infinite loop, or any
> number of other things. Specifically, what the finally block
> guarantees is that it will be executed *before any code following the
> try block*. In this example:
>
> try:
> code1
> except Exception:
> code2
> else:
> code3
> finally:
> code4
> code5
>
> Once you hit code1, you are absolutely guaranteed that code5 *will
> not* be run prior to code4.

The guarantee is stronger than that. It's possible to exit the try
block without passing execution to code5 at all. The finally block is
still guaranteed to be executed in this case.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Resources/pointers for writing maintable, testable Python

2016-05-19 Thread Mike Driscoll
On Thursday, May 19, 2016 at 11:23:53 AM UTC-5, Terry Reedy wrote:
> On 5/19/2016 11:33 AM, Mike Driscoll wrote:
> > On Wednesday, May 18, 2016 at 4:48:28 PM UTC-5, Andrew Farrell wrote:
> >> Hi Jacob,
> >>
> >> You are probably looking for the book Test-Driven Development with Python
> >> .
> 
> Electronic version is free online.
> 
> > I was under the impression that this book is primarily aimed at 
> > Python/Django web testing. I saw
> 
> It is.  However, the first four chapters cover the general principles of 
> TDD, so one can read them while thinking of web development as just an 
> illustrative example.
> 
> In my case, I learned better how to test IDLE from a user perspective. 
> For tkinter apps, an external program such as Selenium is not needed. 
> Tk/tkinter have the simulated event generation and introspection needed 
> to simulate a user hitting keys, clicking mouse buttons, and reading the 
> screen.
> 
> -- 
> Terry Jan Reedy

I am curious. Where is this documented? Are you referring to calling the 
invoke() method on each widget?

Mike
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Python 3.5.1

2016-05-19 Thread Mike Driscoll
On Thursday, May 19, 2016 at 12:21:52 PM UTC-5, kbell...@aol.com wrote:
> Thisis my first encountering with Python. I have successfully downloaded 
> Python3.5.1 for Windows but see only a black window with command prompt. I do 
> not see IDLE under PYthon on Windows Start Menu.
> 
> 
> Downloaded version of Python is based on 32-bit and my PC is 64-bit. 
>  
> Couldyo please help and provide guidance?
> 
> 
> Thank you very much.
> 
> 
> Bella

You should have a folder in your Start Menu for Python. Inside of that, there 
should be a shortcut for IDLE. If there's not, then I'm guessing it didn't 
install correctly. I haven't had any problems installing Python 3.5 on my 
Windows PCs, although I have had issues getting it installed in certain locked 
down virtual environments.

Try uninstalling and then reinstalling Python 3.5

Mike
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-19 Thread Chris Angelico
On Fri, May 20, 2016 at 3:46 AM, Steven D'Aprano  wrote:
> The idea of finally is
> that it executes no matter what happens[1].
>
> [1] Well, *almost* no matter what. If you pull the power from the computer,
> the finally block never gets a chance to run.

Nor if you kill -9 the process, or get into an infinite loop, or any
number of other things. Specifically, what the finally block
guarantees is that it will be executed *before any code following the
try block*. In this example:

try:
code1
except Exception:
code2
else:
code3
finally:
code4
code5

Once you hit code1, you are absolutely guaranteed that code5 *will
not* be run prior to code4.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-19 Thread theherk
This is exactly what I'm referencing. We can do mental gymnastics for it to 
make sense, but remove the `break` in your code and what happens? The logic 
goes away. The code ends up executing anyway, which is what makes it more like 
"finally" to me. Although, as Ian pointed out that would cause breakages for 
the "finally" meaning, because with the break you wouldn't expect it to 
execute, but we expect "finally" always to execute.

It is a great example for sure, but it only makes sense in specific constructs. 
I think this is a really interesting topic to which there may not be a better 
answer.

On Thursday, May 19, 2016 at 10:22:31 AM UTC-7, Ned Batchelder wrote:
> On Thursday, May 19, 2016 at 12:43:56 PM UTC-4, Herkermer Sherwood wrote:
> > Most keywords in Python make linguistic sense, but using "else" in for and
> > while structures is kludgy and misleading. I am under the assumption that
> > this was just utilizing an already existing keyword. Adding another like
> > "andthen" would not be good.
> > 
> > But there is already a reserved keyword that would work great here.
> > "finally". It is already a known keyword used in try blocks, but would work
> > perfectly here. Best of all, it would actually make sense.
> > 
> > Unfortunately, it wouldn't follow the semantics of try/except/else/finally.
> > 
> > Is it better to follow the semantics used elsewhere in the language, or
> > have the language itself make sense semantically?
> > 
> > I think perhaps "finally" should be added to for and while to do the same
> > thing as "else". What do you think?
> 
> For/else has always caused people consternation.
> 
> My best stab at explaining it is this: the else clause is executed if no
> break was encountered in the body of the for loop.  A simple structure
> would look like this:
> 
> for thing in container:
> if something_about(thing):
> # Found it!
> do_something(thing)
> break
> else:
> # Didn't find it..
> no_such_thing()
> 
> I think of the "else" as being paired with the "if" inside the loop.
> At run time, you execute a number of "if"s, one for each iteration
> around the loop.  The "else" is what gets executed if none of the
> "if"s was true.  In that sense, it's exactly the right keyword to
> use.
> 
> --Ned.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-19 Thread Steven D'Aprano
On Fri, 20 May 2016 03:22 am, Ned Batchelder wrote:

> On Thursday, May 19, 2016 at 12:43:56 PM UTC-4, Herkermer Sherwood wrote:
>> Most keywords in Python make linguistic sense, but using "else" in for
>> and while structures is kludgy and misleading. I am under the assumption
>> that this was just utilizing an already existing keyword. Adding another
>> like "andthen" would not be good.
>> 
>> But there is already a reserved keyword that would work great here.
>> "finally". It is already a known keyword used in try blocks, but would
>> work perfectly here. Best of all, it would actually make sense.
>> 
>> Unfortunately, it wouldn't follow the semantics of
>> try/except/else/finally.
>> 
>> Is it better to follow the semantics used elsewhere in the language, or
>> have the language itself make sense semantically?
>> 
>> I think perhaps "finally" should be added to for and while to do the same
>> thing as "else". What do you think?
> 
> For/else has always caused people consternation.
> 
> My best stab at explaining it is this: the else clause is executed if no
> break was encountered in the body of the for loop.

You're describing the consequences of the break: it breaks out of the entire
for statement, which includes the (badly named) "else" clause.

It's also misleading: break is not the only way to skip the else clause. You
can also return, or raise.

As far as I can determine, if you consider all the corner cases, the best
description of the behaviour is:

- the "else" clause is UNCONDITIONALLY executed after the for-loop has
completed, but before any code past the for...else blocks gets to run.

- anything which breaks outside of the for...else will prevent execution of
the else clause. returns jumps all the way out of the function, break
doesn't jump out of the function but it jumps out of the combined
for...else block.



> A simple structure would look like this:
> 
> for thing in container:
> if something_about(thing):
> # Found it!
> do_something(thing)
> break
> else:
> # Didn't find it..
> no_such_thing()
> 
> I think of the "else" as being paired with the "if" inside the loop.

The fatal flaw with that is that there is no requirement that there be any
such "if" inside the loop. In fact, there's no need to even have a break in
the loop at all! 


> At run time, you execute a number of "if"s, one for each iteration 

"One"?

for x in sequence:
if condition: break
if x < 0: break
if today is Tuesday: break
if i.feel_like_it(): break
else:
print("which `if` matches this `else`?")


> around the loop.  The "else" is what gets executed if none of the
> "if"s was true.  In that sense, it's exactly the right keyword to
> use.

So long as you don't think too hard about what's actually going on, and only
consider the most obvious case, it almost makes a bit of sense :-)

But really, the else clause *actually is* an unconditional block which
executes after the loop. That's how it is implemented, and that's how it is
best understood.




-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-19 Thread Jon Ribbens
On 2016-05-19, Steven D'Aprano  wrote:
> On Fri, 20 May 2016 02:31 am, Herkermer Sherwood wrote:
>> Most keywords in Python make linguistic sense, but using "else" in for and
>> while structures is kludgy and misleading. I am under the assumption that
>> this was just utilizing an already existing keyword. Adding another like
>> "andthen" would not be good.
>
> If I could steal the keys to Guido's time machine, I would go back in time
> and change the for...else and while...else keywords to for...then and
> while...then.

I guess we should thank our lucky stars that you don't have a time
machine then, since that change would very much be one for the worse
in my opinion. for...else is perfectly straightforward and clearly
the right keywords to use. for...then would be entirely wrong.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-19 Thread Steven D'Aprano
On Fri, 20 May 2016 02:31 am, Herkermer Sherwood wrote:

> Most keywords in Python make linguistic sense, but using "else" in for and
> while structures is kludgy and misleading. I am under the assumption that
> this was just utilizing an already existing keyword. Adding another like
> "andthen" would not be good.

If I could steal the keys to Guido's time machine, I would go back in time
and change the for...else and while...else keywords to for...then and
while...then.

Alas, we missed the opportunity for a major backwards-incompatible change.
Python 3.0 is long past, we're up to 3.5 now, 3.6 is in alpha, there's no
way the keyword is going to be changed :-(


> But there is already a reserved keyword that would work great here.
> "finally". It is already a known keyword used in try blocks, but would
> work perfectly here. Best of all, it would actually make sense.

No. for...else doesn't operate like a finally block. The idea of finally is
that it executes no matter what happens[1]. That's completely the opposite
of for...else: the whole point of for...else is that "break" will jump out
of the block without executing the else part.

> Unfortunately, it wouldn't follow the semantics of
> try/except/else/finally.

Exactly.


> Is it better to follow the semantics used elsewhere in the language, or
> have the language itself make sense semantically?

If Python was a younger language with fewer users, less existing code, and
no backwards-compatibility guarantees, I would argue for changing
for...else to for...then. But Python is over 20 years old, has tens or
hundreds of thousands of users, tens of millions of lines of code, and
quite strict backwards-compatibility guarantees.


> I think perhaps "finally" should be added to for and while to do the same
> thing as "else". What do you think?

I think adding "finally" as an alias is just needlessly confusing.

Think of the millions of people who aren't English speakers who nevertheless
had to memorise weird and unintuitive words like "for", "while", "if" etc.
The least we English speakers can do is suck it up and memorise *one* weird
case, "else".






[1] Well, *almost* no matter what. If you pull the power from the computer,
the finally block never gets a chance to run.


-- 
Steven

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-19 Thread Ned Batchelder
On Thursday, May 19, 2016 at 12:43:56 PM UTC-4, Herkermer Sherwood wrote:
> Most keywords in Python make linguistic sense, but using "else" in for and
> while structures is kludgy and misleading. I am under the assumption that
> this was just utilizing an already existing keyword. Adding another like
> "andthen" would not be good.
> 
> But there is already a reserved keyword that would work great here.
> "finally". It is already a known keyword used in try blocks, but would work
> perfectly here. Best of all, it would actually make sense.
> 
> Unfortunately, it wouldn't follow the semantics of try/except/else/finally.
> 
> Is it better to follow the semantics used elsewhere in the language, or
> have the language itself make sense semantically?
> 
> I think perhaps "finally" should be added to for and while to do the same
> thing as "else". What do you think?

For/else has always caused people consternation.

My best stab at explaining it is this: the else clause is executed if no
break was encountered in the body of the for loop.  A simple structure
would look like this:

for thing in container:
if something_about(thing):
# Found it!
do_something(thing)
break
else:
# Didn't find it..
no_such_thing()

I think of the "else" as being paired with the "if" inside the loop.
At run time, you execute a number of "if"s, one for each iteration
around the loop.  The "else" is what gets executed if none of the
"if"s was true.  In that sense, it's exactly the right keyword to
use.

--Ned.
-- 
https://mail.python.org/mailman/listinfo/python-list


Python 3.5.1

2016-05-19 Thread Bella via Python-list

Thisis my first encountering with Python. I have successfully downloaded 
Python3.5.1 for Windows but see only a black window with command prompt. I do 
not see IDLE under PYthon on Windows Start Menu.


Downloaded version of Python is based on 32-bit and my PC is 64-bit. 
 
Couldyo please help and provide guidance?


Thank you very much.


Bella
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: for / while else doesn't make sense

2016-05-19 Thread Ian Kelly
On Thu, May 19, 2016 at 10:31 AM, Herkermer Sherwood  wrote:
> Most keywords in Python make linguistic sense, but using "else" in for and
> while structures is kludgy and misleading. I am under the assumption that
> this was just utilizing an already existing keyword. Adding another like
> "andthen" would not be good.

"else" makes sense from a certain point of view, but I think that
logic may not be communicated well. At the start of each loop
iteration, the loop construct makes a test for whether the loop should
continue or not. If that test ever fails (i.e. if the condition of the
while loop is false), the else block is executed instead. So you can
think of it as a repeated if-else where the else block has the
additional effect of exiting the loop.

> But there is already a reserved keyword that would work great here.
> "finally". It is already a known keyword used in try blocks, but would work
> perfectly here. Best of all, it would actually make sense.
>
> Unfortunately, it wouldn't follow the semantics of try/except/else/finally.

"finally" in exception handling denotes a block that is *always*
executed. Using it for a block that is only sometimes executed would
dilute that meaning.
-- 
https://mail.python.org/mailman/listinfo/python-list


for / while else doesn't make sense

2016-05-19 Thread Herkermer Sherwood
Most keywords in Python make linguistic sense, but using "else" in for and
while structures is kludgy and misleading. I am under the assumption that
this was just utilizing an already existing keyword. Adding another like
"andthen" would not be good.

But there is already a reserved keyword that would work great here.
"finally". It is already a known keyword used in try blocks, but would work
perfectly here. Best of all, it would actually make sense.

Unfortunately, it wouldn't follow the semantics of try/except/else/finally.

Is it better to follow the semantics used elsewhere in the language, or
have the language itself make sense semantically?

I think perhaps "finally" should be added to for and while to do the same
thing as "else". What do you think?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Resources/pointers for writing maintable, testable Python

2016-05-19 Thread Terry Reedy

On 5/19/2016 11:33 AM, Mike Driscoll wrote:

On Wednesday, May 18, 2016 at 4:48:28 PM UTC-5, Andrew Farrell wrote:

Hi Jacob,

You are probably looking for the book Test-Driven Development with Python
.


Electronic version is free online.


I was under the impression that this book is primarily aimed at Python/Django 
web testing. I saw


It is.  However, the first four chapters cover the general principles of 
TDD, so one can read them while thinking of web development as just an 
illustrative example.


In my case, I learned better how to test IDLE from a user perspective. 
For tkinter apps, an external program such as Selenium is not needed. 
Tk/tkinter have the simulated event generation and introspection needed 
to simulate a user hitting keys, clicking mouse buttons, and reading the 
screen.


--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list


Re: Resources/pointers for writing maintable, testable Python

2016-05-19 Thread Jacob Scott
Indeed, I skimmed the TOC for Test-Driven Development with Python and it
does look to be rather Django-centric (which makes it a bit less helpful to
me). I will take a look at "Testing Python: Applying Unit Testing, TDD, BDD
and Acceptance Testing"!

Thanks,

Jacob

On Thu, May 19, 2016 at 8:33 AM, Mike Driscoll  wrote:

> On Wednesday, May 18, 2016 at 4:48:28 PM UTC-5, Andrew Farrell wrote:
> > Hi Jacob,
> >
> > You are probably looking for the book Test-Driven Development with Python
> > .
> > You'll also want to look at py.test 
> >
> > Cheers!
> > Andrew Farrell
>
> I was under the impression that this book is primarily aimed at
> Python/Django web testing. I saw "Testing Python: Applying Unit Testing,
> TDD, BDD and Acceptance Testing" is getting good reviews too though.
>
> Mike
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Resources/pointers for writing maintable, testable Python

2016-05-19 Thread Mike Driscoll
On Wednesday, May 18, 2016 at 4:48:28 PM UTC-5, Andrew Farrell wrote:
> Hi Jacob,
> 
> You are probably looking for the book Test-Driven Development with Python
> .
> You'll also want to look at py.test 
> 
> Cheers!
> Andrew Farrell

I was under the impression that this book is primarily aimed at Python/Django 
web testing. I saw "Testing Python: Applying Unit Testing, TDD, BDD and 
Acceptance Testing" is getting good reviews too though. 

Mike
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: setrecursionlimit

2016-05-19 Thread Nobody
On Wed, 18 May 2016 09:19:25 -0700, Ned Batchelder wrote:

> Is there a way to know how large the C stack can grow,

Yes. For the main thread, getrlimit(RLIMIT_STACK). For other threads,
pthread_attr_getstacksize().

> and how much it will grow for each Python function call?

No.

Depending upon the interpreter implementation, the stack might not grow
at all in the case where a function written in Python calls another
function written in Python. Calling out into native code (which may then
call back into Python code) is bound to grow the thread by some amount.

While the interpreter could keep track of how much space is left on the
stack, there's no way of knowing in advance how much any given C function
will need. If there isn't enough, there is no robust way to recover from
the resulting segfault.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: setrecursionlimit

2016-05-19 Thread Oscar Benjamin
On 18 May 2016 at 17:11, Steven D'Aprano  wrote:
> The documentation for setrecursion limit warns against setting the limit too
> high:
>
> [quote]
> The highest possible limit is platform-dependent. A user may need to
> set the limit higher when they have a program that requires deep
> recursion and a platform that supports a higher limit. This should
> be done with care, because a too-high limit can lead to a crash.
> [end quote]
>
> https://docs.python.org/3/library/sys.html#sys.setrecursionlimit
>
> Indeed, if you set the recursion limit too high, you can smash the memory
> heap and get a segfault. How exactly does that work?
>
> Why doesn't setrecursionlimit() raise an exception when you try to set it
> too high? For example:
>
> sys.setrecursionlimit(20)
>
> succeeds on my system, even though that's a ludicrously high number. (It is
> more than half the number of bytes of memory my computer has.)
>
>
> So why can't Python tell if I'm setting the limit too high?
>
> (I'm assuming that if it could, it would.)

It's not altogether impossible to do this but it requires ducking
underneath the C level to the machine code level. The C standard
doesn't define the exact number of bytes that should be used by a
stack frame. The exact number depends on the calling convention used
for your OS/hardware/compiler combination and also on the
optimisation/debug settings used by the compiler. A good optimiser
might be able to completely eliminate your function so that it doesn't
touch the stack for example.

Also it depends ultimately on the code path that leads to
PyEval_EvalFrameEx calling itself recursively. The recursion here is
indirect and there are multiple paths for it, depending on whether the
function is called with no arguments or whether it is a generator etc.
Then after that you need to consider extension modules. For example a
numpy array can store Python objects and perform operations on them.
If we have an ndarray of Fractions then there's no way at compile time
to know how much stack space ndarray.__add__ (implemented with a load
of complex C code) will need before calling e.g. Fraction.__add__.

Given the extension module case it's clearly impossible to compute the
hardware-stack memory requirements of a Python-level frame at compile
time. Christian has already explained why this wouldn't really work at
runtime either. There isn't even a portable way at the C level to
query the current value of the stack pointer. And even if you could
you'd have to make hardware-specific assumptions to be able to use
that information.

My understanding (although I have no direct experience here) is that
Stackless Python is an alternative implementation that gets around all
of these problems by avoiding the recursion altogether.

--
Oscar
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Resources/pointers for writing maintable, testable Python

2016-05-19 Thread Chris Angelico
On Thu, May 19, 2016 at 7:13 PM, Gregory Ewing
 wrote:
> Chris Angelico wrote:
>>
>> [1] Some people's names can't be represented in Unicode.
>
>
> Like this fellow's, for instance:
>
> https://www.youtube.com/watch?v=hNoS2BU6bbQ

His name actually CAN be represented in Unicode. It's his address that
I'd have trouble with.

(Smart copper, by the way.)

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Resources/pointers for writing maintable, testable Python

2016-05-19 Thread Gregory Ewing

Chris Angelico wrote:

[1] Some people's names can't be represented in Unicode.


Like this fellow's, for instance:

https://www.youtube.com/watch?v=hNoS2BU6bbQ

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: setrecursionlimit

2016-05-19 Thread Gregory Ewing

Rustom Mody wrote:

Both the mess in catching numeric overflow as well as stackoverflow looks like
its C's fault. 
I consider it as the fault of currently fashionable stock hardware


The sad thing about C is that it doesn't even help you
detect integer overflow in *software*.

Every machine I've ever seen has a flag that gets set
if an integer addition overflows. But C doesn't provide
any portable way of testing that flag, even if you
wanted to.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list


Re: setrecursionlimit

2016-05-19 Thread Gregory Ewing

Steven D'Aprano wrote:

I don't really understand why the system can't track the current top of the
stack and bottom of the heap, and if they're going to collide, halt the
process.


That effectively *is* what it does.

The reason it manifests as a segfault is because of the way it
goes about detecting the heap/stack collision. It would be very
expensive to explicitly check for this every time something is
pushed or popped on the stack, so what OSes typically do instead
is reserve a buffer zone of unmapped memory between the stack
and the heap. If the stack overflows, you end up trying to
reference memory in the unmapped area, and a segfault results.

This is not foolproof -- if you allocate a *really* big stack
frame, you could leap right over the buffer zone and clobber
the heap. But it works well enough most of the time and
succeeds in stopping the program before it accidentally
launches the nuclear missiles.

Hardware support for stack bounds checkinbg would of course make
all this easier and more reliable, but the x86 architecture
doesn't provide anything like that, unfortunately.

--
Greg
--
https://mail.python.org/mailman/listinfo/python-list