Re: unintuitive for-loop behavior

2016-10-01 Thread Steve D'Aprano
Earlier, I wrote:

> On Sat, 1 Oct 2016 10:46 am, Gregory Ewing wrote:
[...]
>> Whenever there's binding going on, it's necessary to decide
>> whether it should be creating a new binding or updating an
>> existing one.
> 
> Right.

I changed my mind -- I don't think that's correct.

I think Greg's suggestion only makes sense for languages where variables are
boxes with fixed locations, like C or Pascal. In that case, the difference
between creating a new binding and updating a new one is *possibly*
meaningful:

# create a new binding
x: address 1234 > [  box contains 999 ]
x: address 5678 > [  a different box, containing 888 ]

What happens to the old x? I have no idea, but the new x is a different box.
Maybe the old box remains there, for any existing code that refers to the
address of (old) x. Maybe the compiler is smart enough to add address 1234
to the free list of addresses ready to be used for the next variable. Maybe
its just lost and unavailable until this function exists.

# update an existing binding
x: address 1234 > [  box contains 999 ]
x: address 1234 > [  same box, now contains 888 ]


That's the normal behaviour of languages like C and Pascal. But its distinct
from the previous, hypothetical behaviour.

But Python doesn't work that way! Variables aren't modelled by boxes in
fixed locations, and there is no difference between "create a new binding"
and "update an existing one". They are indistinguishable. In both
cases, 'x' is a key in a namespace dict, which is associated with a value.
There's no difference between:

x = 999
del x
x = 888

and 

x = 999
x = 888


If you consider the namespace dict as a hash table, e.g. something like this
(actual implementations may differ):

[ UNUSED, UNUSED, (key='y', value=23), (key='a', value=True), 
  UNUSED, (key='x', value=999), UNUSED ]

then binding 888 to 'x' must put the key in the same place in the dict,
since that's where hash('x') will point.

Subject to linear addressing, chaining, re-sizes, or other implementation
details of hash tables of course. But all else being equal, you cannot
distinguish between the "new binding" and "update existing binding"
cases -- in both cases, the same cell in the hash table gets affected,
because that's where hash('x') points. If you put it somewhere else, it
cannot be found.

So I think I was wrong to agree with Greg's statement. I think that for
languages like Python where variables are semantically name bindings in a
namespace rather than fixed addresses, there is no difference between
updating an existing binding and creating a new one.

In a language like Python, the only distinction we can make between name
bindings is, which namespace is the binding in? In other words, what is the
current block of code's scope?




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: unintuitive for-loop behavior

2016-10-01 Thread Chris Angelico
On Sat, Oct 1, 2016 at 5:06 PM, Steve D'Aprano
 wrote:
> Earlier, I wrote:
>
>> On Sat, 1 Oct 2016 10:46 am, Gregory Ewing wrote:
> [...]
>>> Whenever there's binding going on, it's necessary to decide
>>> whether it should be creating a new binding or updating an
>>> existing one.
>>
>> Right.
>
> I changed my mind -- I don't think that's correct.
>
> I think Greg's suggestion only makes sense for languages where variables are
> boxes with fixed locations, like C or Pascal. In that case, the difference
> between creating a new binding and updating a new one is *possibly*
> meaningful:
>
> # create a new binding
> x: address 1234 > [  box contains 999 ]
> x: address 5678 > [  a different box, containing 888 ]
>
> What happens to the old x? I have no idea, but the new x is a different box.
> Maybe the old box remains there, for any existing code that refers to the
> address of (old) x. Maybe the compiler is smart enough to add address 1234
> to the free list of addresses ready to be used for the next variable. Maybe
> its just lost and unavailable until this function exists.
>
> # update an existing binding
> x: address 1234 > [  box contains 999 ]
> x: address 1234 > [  same box, now contains 888 ]
>
>
> That's the normal behaviour of languages like C and Pascal. But its distinct
> from the previous, hypothetical behaviour.
>
> But Python doesn't work that way! Variables aren't modelled by boxes in
> fixed locations, and there is no difference between "create a new binding"
> and "update an existing one". They are indistinguishable. In both
> cases, 'x' is a key in a namespace dict, which is associated with a value.
> ...
> In a language like Python, the only distinction we can make between name
> bindings is, which namespace is the binding in? In other words, what is the
> current block of code's scope?

Yes, this is true; however, it's not difficult to create subscopes. I
put together a POC patch a while ago to make 'with' blocks able to put
their capture names into a separate subscope, transparently. I don't
think it's what Python wants, but it would be reasonably coherent
semantically ("with expr as name:" puts name, and name alone, into a
subscope - any other assignments are not), and wasn't difficult to
implement in CPython.

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


Re: unintuitive for-loop behavior

2016-10-01 Thread Steve D'Aprano
On Sat, 1 Oct 2016 02:39 am, Chris Angelico wrote:

> On Sat, Oct 1, 2016 at 12:36 AM, Grant Edwards
>  wrote:

>> In C99 a for loop has its own namespac:
[...]

> I believe that's the same semantics as C++ uses, and I agree, it's
> very convenient. Among other things, it means that nested loops behave
> more like they do in Python, with independent iterators:

*scratches head*

So let me see if I understand this... 

You're suggesting that C99, where for-loops have their own namespaces, is
MORE like Python (where for-loops DON'T have their own namespace), than
C89, which, like Python, DOESN'T give for-loops their own namespace?

That's ... curious.

I'm not saying you're wrong: after spending three quarters of an hour trying
to fix a six line (including one blank line) C program because I
accidentally closed a comment with /* instead of */, I will believe
anything about C[1]. If you tell me that void causes birth defects and
printf is responsible for the police shootings of unarmed black men, I'll
believe every word of it.



> int main(void)
> {
> for (int i=0; i<5; ++i)
> {
> printf("%d:", i);
> for (int i=0; i<3; ++i)
> printf(" %d", i);
> printf("\n");
> }
> }
> 
> Now, granted, this is not something I would ever actually recommend
> doing, and code review is absolutely justified in rejecting this...

So let me see if I understand your argument... for-loop namespaces are good,
because they let you write code that you personally wouldn't write and
would, in fact, reject in a code review.

O-kay.


> but it's a lot better than pure function-scope variables, where you'd
> get stuck in an infinite loop.

That's the risk that you take when you have a C-style for loop and you
modify the loop variable. There's nothing special about the inner loop in
that regard:


#include  /* for printf */
int main(void)
  {
for (int i=0; i<5; ++i)
  {
printf("%d:", i);
i = 0;
  }
  }


Solution: don't do that.







[1] Apparently useful error messages are one of those things C programmers
eschew, like type safety, memory safety, and correctness.


-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: unintuitive for-loop behavior

2016-10-01 Thread Jussi Piitulainen
Steve D'Aprano writes:

> In a language like Python, the only distinction we can make between
> name bindings is, which namespace is the binding in? In other words,
> what is the current block of code's scope?

Python already has nested scopes. A local scope for just those variables
introduced in for-loops could be carved out as in the following example.

The following example function has three parameters and two local
variables, one of which is only assigned inside the loop (and it also
references one global variable), in addition to the variable introduced
in the loop.

def eg(wev, a, b):
   y = 0
   for x in wev: # to be given a new semantics
   f(a, x)
   f(x, b)
   y += 1
   z = (y > 12)
   return y, z

Replace the loop with a call to a thunk that refers to the variables in
the outer scopes, except for the one variable that the loop introduces -
that variable is to be local to the thunk. So the example function
should be equivalent to something like the following translation.

def eg(wev, a, b):
   y = 0
   def g31():
   nonlocal y, z # the assigned variables
   g32 = iter(wev)
   while 1: # need to catch StopIteration
  x = next(g32) # now local to g31
  f(a, x)
  f(x, b)
  y += 1
  z = (y > 12)
   g31()
   return y, z

A different translation would introduce each x in a different function
for each step in the iteration. That's just a variation on the overall
theme.
-- 
https://mail.python.org/mailman/listinfo/python-list


generator no iter - how do I call it from another function

2016-10-01 Thread Sayth Renshaw
Evening

My file list handler I have created a generator.

Before I created it as a generator I was able to use iter on my lxml root 
objects, now I cannot iter.

± |master U:2 ?:1 ✗| → python3 race.py data/ -e *.xml
Traceback (most recent call last):
  File "race.py", line 83, in 
dataAttr(rootObs)
  File "race.py", line 61, in dataAttr
for meet in roots.iter("meeting"):
AttributeError: 'generator' object has no attribute 'iter'


How do I now pull the next iterations through from the other function?

from lxml import etree
import csv
import re
import argparse
import os

parser = argparse.ArgumentParser()
parser.add_argument("path", type=str, nargs="+")
parser.add_argument(
'-e', '--extension', default='', help='File extension to filter by.')

# >python race.py XML_examples/ -e .xml

args = parser.parse_args()
name_pattern = "*" + args.extension
my_dir = args.path[0]

for dir_path, subdir_list, file_list in os.walk(my_dir):
for name_pattern in file_list:
full_path = os.path.join(dir_path, name_pattern)


def return_files(file_list):
"""
Take a list of files and return file when called.

Calling function to supply attributes
"""
for filename in sorted(file_list):
with open(dir_path + filename) as fd:
tree = etree.parse(fd)
root = tree.getroot()
yield root


def clean(attr):
"""
Split list into lists of 5 elements.

if list is less than 5 in length then a 0
is appended and the list returned
"""
p = re.compile('\d+')
myList = p.findall(attr)
if len(myList) < 5:
myList.append('0')
return myList[0], myList[1], myList[2], myList[3], myList[4]


def dataAttr(roots):
"""Get the root object and iter items."""
with open("output/first2.csv", 'w', newline='') as csvf:
race_writer = csv.writer(csvf, delimiter=',')
for meet in roots.iter("meeting"):
print(meet)
for race in roots.iter("race"):
for nom in roots.iter("nomination"):
meetattr = meet.attrib
raceattr = race.attrib
nomattr = nom.attrib
if nomattr['number'] != '0':
firsts = clean(nomattr['firstup'])
race_writer.writerow(
[meetattr['id'], meetattr['date'],
 meetattr['venue'], raceattr['id'],
 raceattr['number'], raceattr['distance'],
 nomattr['id'], nomattr['barrier'],
 nomattr['weight'], nomattr['rating'],
 nomattr['description'], nomattr['dob'],
 nomattr['age'], nomattr['decimalmargin'],
 nomattr['saddlecloth'], nomattr['sex'],
 firsts[4]])


rootObs = return_files(file_list)
dataAttr(rootObs)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: rocket simulation game with just using tkinter

2016-10-01 Thread Sayth Renshaw
On Saturday, 1 October 2016 08:59:28 UTC+10, Irmen de Jong  wrote:
> Hi,
> 
> I've made a very simple rocket simulation game, inspired by the recent 
> success of SpaceX
> where they managed to land the Falcon-9 rocket back on a platform.
> 
> I was curious if you can make a simple graphics animation game with just 
> using Tkinter,
> instead of using other game libraries such as PyGame.
> As it turns out, that works pretty well and it was quite easy to write. 
> Granted, there's
> not much going on on the screen, but still the game runs very smoothly and I 
> think it is
> fun for a little while where you try to learn to control the rocket and 
> attempt to
> successfully land it on the other launchpad!
> 
> The physics simulation is tied to the game's frame rate boohoo, but the 
> upside is that
> you can change the framerate to control the game's difficulty. It's easy at 
> <=20, fun at
> 30 and impossible at 60 :)  It's running on 30 by default.
> 
> 
> You can get the code here if you want to give it a try:
> https://github.com/irmen/rocketsimulator
> 
> So you just need python 2/3 with tkinter to play this!
> 
> 
> Have fun
> Irmen

Well done. An interesting listen that might be up your alley, 
how-i-built-an-entire-game-and-toolchain-100-in-python on talkpython

https://talkpython.fm/episodes/show/78/how-i-built-an-entire-game-and-toolchain-100-in-python

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


Re: unintuitive for-loop behavior

2016-10-01 Thread Chris Angelico
On Sat, Oct 1, 2016 at 6:35 PM, Steve D'Aprano
 wrote:
> On Sat, 1 Oct 2016 02:39 am, Chris Angelico wrote:
>
>> On Sat, Oct 1, 2016 at 12:36 AM, Grant Edwards
>>  wrote:
>
>>> In C99 a for loop has its own namespac:
> [...]
>
>> I believe that's the same semantics as C++ uses, and I agree, it's
>> very convenient. Among other things, it means that nested loops behave
>> more like they do in Python, with independent iterators:
>
> *scratches head*
>
> So let me see if I understand this...
>
> You're suggesting that C99, where for-loops have their own namespaces, is
> MORE like Python (where for-loops DON'T have their own namespace), than
> C89, which, like Python, DOESN'T give for-loops their own namespace?
>
> That's ... curious.

Well, when you put it like that, it does sound very curious!!

Here's how I read it:

# Python
def main():
for i in range(5):
print(i, end=": ")
for i in range(3):
print(i, end=" ")
print("")

/* Classic C */
int main() {
int i;
for (i=0; i<5; ++i) {
printf("%d:", i);
for (i=0; i<3; ++i)
printf(" %d", i);
printf("\n");
}

//C++ or C99
int main() {
for (int i=0; i<5; ++i) {
printf("%d:", i);
for (int i=0; i<3; ++i)
printf(" %d", i);
printf("\n");
}

The first and last have *independent iterators*. When you complete the
inner loop, the outer loop picks up where *it* left off, not where you
happen to have reassigned the iteration variable. The middle one is an
infinite loop.

> I'm not saying you're wrong: after spending three quarters of an hour trying
> to fix a six line (including one blank line) C program because I
> accidentally closed a comment with /* instead of */, I will believe
> anything about C[1]. If you tell me that void causes birth defects and
> printf is responsible for the police shootings of unarmed black men, I'll
> believe every word of it.

Did you turn all warnings on? Look for a "pedantic" mode. You'll get a
lot more information, assuming you're using a modern decent C
compiler. (GCC, for instance, will even warn about situations where it
looks like the braces and indentation don't match, thus bringing a
Python feature to C, more-or-less.)

>> int main(void)
>> {
>> for (int i=0; i<5; ++i)
>> {
>> printf("%d:", i);
>> for (int i=0; i<3; ++i)
>> printf(" %d", i);
>> printf("\n");
>> }
>> }
>>
>> Now, granted, this is not something I would ever actually recommend
>> doing, and code review is absolutely justified in rejecting this...
>
> So let me see if I understand your argument... for-loop namespaces are good,
> because they let you write code that you personally wouldn't write and
> would, in fact, reject in a code review.
>
> O-kay.

Yes. In the first place, I wouldn't necessarily reject this code; it's
a minor issue only, thanks to the namespacing and nested scoping. It
does cost a little in clarity, and I would point it out to a student,
but in less trivial examples than this, it's really not that big a
deal.

*Without* namespacing to keep them apart, this is a serious problem.
Thanks to namespacing, it's only a minor problem (you've shadowed one
variable with another). It's comparable to this Python code:

def send_message(from, to, subj, body):
str = "Mail: From " + from
str += "\nRecipient: To " + to
str += "\nSubject: " + subj
str += "\n\n" + body
send_raw_data(str)

Would you reject this in a code review? Maybe. I wouldn't yell at you
saying "shadowing is fine, you have no right to reject that". But it's
also not inherently a problem. The rules of name shadowing are
well-defined (in both languages) and designed to *permit*, not reject,
constructs like this.

>> but it's a lot better than pure function-scope variables, where you'd
>> get stuck in an infinite loop.
>
> That's the risk that you take when you have a C-style for loop and you
> modify the loop variable. There's nothing special about the inner loop in
> that regard:
>
>
> #include  /* for printf */
> int main(void)
>   {
> for (int i=0; i<5; ++i)
>   {
> printf("%d:", i);
> i = 0;
>   }
>   }
>
>
> Solution: don't do that.

Actually, I would call this version a feature. If you deliberately and
consciously reassign the iteration variable, it's usually because you
wanted to adjust the loop. Classic example: iterating through a series
of tokens, and sometimes needing to grab a second token. Python lets
you do this by explicitly calling iter() and next(); C lets you do
this by incrementing the loop counter (which works only with the
less-flexible looping style it has).

But when you didn't intend to reassign it, it's usually because you
had a local name that happened to collide. Sure, that can happen
anywhere, especially with abbreviated variable names (I once had the
amusing situation of trying to use "cursor" and "current" in the same
namespace, both abbreviated "cur"), b

Re: How to make a foreign function run as fast as possible in Windows?

2016-10-01 Thread jfong
Chris Angelico at 2016/10/1 11:25:03AM wrote:
> What's it doing? Not every task can saturate the CPU - sometimes they
> need the disk or network more.
> 
This function has no I/O or similar activity, just pure data processing, and it 
takes less than 200 bytes of data area to work with.

My CPU is an i3 (4 threads/2 cores). I suppose after this job was assigned to 
run on a particular core, the OS shouldn't bother it by other system related 
tasks anymore. If it does, won't be this OS designed stupidly?

I was puzzled why the core has no 100% usage? Why always has some percentage of 
idle?

--Jach

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


Re: generator no iter - how do I call it from another function

2016-10-01 Thread Sayth Renshaw
My main issue is that usually its just x in ,,, for a generator.

But if I change the code
for meet in roots.iter("meeting"):

to
for meet in roots("meeting"):

Well its invalid but I need to be able to reference the node, how do I achieve 
this?

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


Re: generator no iter - how do I call it from another function

2016-10-01 Thread Vlastimil Brom
2016-10-01 12:09 GMT+02:00 Sayth Renshaw :
> My main issue is that usually its just x in ,,, for a generator.
>
> But if I change the code
> for meet in roots.iter("meeting"):
>
> to
> for meet in roots("meeting"):
>
> Well its invalid but I need to be able to reference the node, how do I 
> achieve this?
>
> Sayth
> --

Hi,
i think, you identified the problem correctly in the previous mail:
>> Before I created it as a generator I was able to use iter on my lxml root 
>> objects, now I cannot iter.

It is not clear, what the previous - working - version was, but there
is a difference between using built-in iteration handling (with
built-in iter(...) or implicitly via "for elem in
some_iterable_object: ...") and with the specialised "iter" method of
root in the lxml library (which has specific functionalities).
I don't have much experience with that library, but if your change was
basically adding a "generator" layer around "roots",
you may try to iterate over it to get its elements, which might
supposedly support the method, you were using previously.
e.g. (completely untested, as there is no xml underlying given in your sample)
for root in roots:
for meet in root.iter("meeting"):
...

hth,
   vbr
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: unintuitive for-loop behavior

2016-10-01 Thread Gregory Ewing

Random832 wrote:

> for a in collection:
> b = some_calculation_of(a)
> final b: do_something_with(lambda: ... b ...)

I would prefer something like

  for a in collection:
let b = some_calculation_of(a):
  do_something_with(lambda: ... b ...)

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


Re: generator no iter - how do I call it from another function

2016-10-01 Thread Steve D'Aprano
On Sat, 1 Oct 2016 06:52 pm, Sayth Renshaw wrote:

> Evening
> 
> My file list handler I have created a generator.
> 
> Before I created it as a generator I was able to use iter on my lxml root
> objects, now I cannot iter.

lxml root objects have an iter method. Other objects do not.


Thank you for showing your code, but it is MUCH too complicated. Most of the
code has nothing to do with your question. You are asking a question about
generators, but your code shows argument processing, file processing,
regexes, all sorts of things that we have to read and understand before we
can answer your question, and none of it is relevant.

That's too much work. We are volunteers. If you want to pay us, we'll be
happy to spend hours on your code. But if you want free consulting, then
you have to do some of the work to make it easy for us.

Please cut your code down to the smallest possible amount that shows the
problem:

http://sscce.org/

If you have a generator, you can iterate over it like this:

def generator():
yield 1
yield 2
yield 4


for value in generator():  # NOT generator.iter()
print(value)


Does that answer your question? If not, then cut your code down to the
smallest possible amount that shows the problem:

http://sscce.org/

and I'll read it again.





-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Copying a compiled Python from one system to another

2016-10-01 Thread Steve D'Aprano
Long story short: I have no working systems capable of compiling the latest
Python 3.6, and no time to upgrade my usual machines to something which
will work.

However I do have access to another machine (actually a VM) which can
compile Python 3.6. It's not practical for me to use it as a my main
development machine, but as a temporary measure, I thought I could compile
3.6 on this VM, then copy the python binary to my usual desktop machine.

What sort of challenges am I likely to find? Both machines are Linux, but
different distros.


-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: unintuitive for-loop behavior

2016-10-01 Thread Steve D'Aprano
On Sat, 1 Oct 2016 01:44 pm, Rustom Mody wrote:

> Yes one basic problem with comprehensions in python is that they are
> defined by assignment not binding to the comprehension variable

¿Que Mr Fawlty?

I'm sorry, I don't understand you.

In Python, all assignments are name bindings. So you seem to be saying:

one basic problem with comprehensions in python is that they 
are defined by binding (to the comprehension variable) not 
binding to the comprehension variable

which confuses me. How do you think that comprehension variables are
different from all other variables?

And while we're at it, what do you mean by "comprehension variable"? Are you
talking about the variable that the comprehension is bound to:

comprehension_variable = [x+1 for x in sequence]

or are you talking about the loop variable inside the comprehension?

foo = [comprehension_variable+1 for comprehension_variable in sequence]


It is not clear what you mean. Although I suspect it makes no difference --
either way, the nature of the assignment is identical: its a name binding.



> Python copied comprehensions from haskell and copied them wrong
> Here are all the things (that I can think of) that are wrong:
> 1. Scope leakage from inside to outside the comprehension

The core devs agree that this was a mistake. It was rectified in generator
expressions, and for comprehensions in Python 3. This is no longer an
issue.


> 2. Scope leakage from one value to the next

I don't know what that means.


> 3. The name 'for' misleadingly associates for-loops and comprehensions

What is misleading about it?


> 4. The for-loop based implementation strategy made into definitional
> semantics 
> 5. The absence of simple binding inside comprehensions: 
>[f(newvar) for v in l newvar = rhs]

I don't know what this means.


> 1 was considered sufficiently important to make a breaking change from
> python2 to 3 

Correct.


> 2 is what causes the lambda gotcha 

I don't think so.


> 3 is what makes noobs to take longer than necessary to grok them

You haven't shown any evidence that beginners take longer than necessary to
grok list comprehensions. Perhaps they take exactly as long as necessary.

And you CERTAINLY haven't demonstrated that the average beginner would
understand Haskell's list comprehensions more easily than Python's.


https://wiki.haskell.org/List_comprehension

https://www.haskell.org/onlinereport/exps.html#sect3.11



> 4 is what causes a useless distinction between 1 and 2 — scope leakage is
> scope leakage. 

What is scope leakage?


> The explanatory mechanisms of why/whither/what etc should 
> at best be secondary 5. is workaroundable with a [... for newvar in [rhs]] 
>Possible and clunky

I don't know what this means.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: unintuitive for-loop behavior

2016-10-01 Thread Gregory Ewing

Steve D'Aprano wrote:


# create a new binding
x: address 1234 > [  box contains 999 ]
x: address 5678 > [  a different box, containing 888 ]


In the context of CPython and nested functions, replace
"box" with "cell".

When I said "creating a new binding" I meant that the
name x refers to different cells at different times.
When I said "updating an existing binding" I meant that
the name x still refers to the same cell, but that cell
refers to a different object.

In a wider context, replace "box" with "slot in a
stack frame" or "slot in a namespace dictionary".


But Python doesn't work that way! Variables aren't modelled by boxes in
fixed locations, and there is no difference between "create a new binding"
and "update an existing one".


There is very much a distintion. Each time you invoke
a function, a new set of bindings is created for all of
its parameters and local names. Assigning to those names
within the function, on the other hand, updates existing
bindings.

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


Re: Copying a compiled Python from one system to another

2016-10-01 Thread Chris Angelico
On Sat, Oct 1, 2016 at 9:21 PM, Steve D'Aprano
 wrote:
> Long story short: I have no working systems capable of compiling the latest
> Python 3.6, and no time to upgrade my usual machines to something which
> will work.
>
> However I do have access to another machine (actually a VM) which can
> compile Python 3.6. It's not practical for me to use it as a my main
> development machine, but as a temporary measure, I thought I could compile
> 3.6 on this VM, then copy the python binary to my usual desktop machine.
>
> What sort of challenges am I likely to find? Both machines are Linux, but
> different distros.

First off, are they the same CPU architecture? If not, you're going to
have a lot of hassles. (This includes x86_64 vs i386. You *can* run a
32-bit Python on a 64-bit Linux, but it'll be a pain.) I'm going to
assume that they are.

Are both Linuxes of broadly similar vintage? The most likely problems
you'll face will be library versions - CPython will happily link
against any of several compatible versions of a library, but once it's
linked against one, it'll want to find the same version thereafter.
Worst case, you could symlink, but that could cause trouble when you
upgrade, so I'd advise against it.

In fact, your best bet might actually be to *minimize* the number of
dev libraries on the build machine. You'll have build failures in
optional modules (and thus less modules), but less chances of running
into difficulties.

Other than that, it should be possible. You'll probably want to export
the built Python as a package manager file, eg using checkinstall [1]
on Debian-based systems, as it'll be a lot easier to pick up and carry
around. But it shouldn't be too hard even working manually.

ChrisA

[1] https://wiki.debian.org/CheckInstall
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: unintuitive for-loop behavior

2016-10-01 Thread Rustom Mody
On Saturday, October 1, 2016 at 5:02:30 PM UTC+5:30, Steve D'Aprano wrote:
> On Sat, 1 Oct 2016 01:44 pm, Rustom Mody wrote:
> 
> > Yes one basic problem with comprehensions in python is that they are
> > defined by assignment not binding to the comprehension variable
> 
> ¿Que Mr Fawlty?
> 
> I'm sorry, I don't understand you.
> 
> In Python, all assignments are name bindings. So you seem to be saying:
> 
> one basic problem with comprehensions in python is that they 
> are defined by binding (to the comprehension variable) not 
> binding to the comprehension variable
> 
> which confuses me. How do you think that comprehension variables are
> different from all other variables?

Sorry... I guess you are right [for once ;-) ]
I was making a *generic* distinction between binding-constructs that *create*
variables, eg function-defs, lambdas, excepts, withs etc and assignment
that *changes* a binding.
This distinction is standard in compiled languages like C where a 
int x;
creates the x and 
x=rhs;
modifies it

C++ preserves this distinction in user defined types making sure that
the constructor called for an assignment and for an initialization are distinct
even though they look very similar:
x = rhs;
vs
T x = rhs;

In functional languages, both the dynamic ones like lisp as well as the static
ones like Haskell are very strict and sacrosanct about this distinction.

However in python this does not work because assignment both assigns and 
creates  the variable.

Interestingly there is this thread running right now on haskell-cafe:
https://groups.google.com/forum/#!topic/haskell-cafe/6tqMdy9nGdc
which is inspired by python's “batteries included” 
And there there is this comment:
«Python is even more imperative than C++ or Java, it's dynamically typed…» 
which (I guess) is because of exactly such features

Long story short: My saying “binding” is meaningless in python.
I should have said function-binding; ie the mechanism by which functions bind
their arguments *anew*
And then define comprehensions not as now done in terms of for loops that
mutatingly extend the list being built up but as recursive functions that get 
(re)called for every new value of the comprehension variable passed and 
therefore
fresh-bound as parameter


> 
> And while we're at it, what do you mean by "comprehension variable"? Are you
> talking about the variable that the comprehension is bound to:

> 
> comprehension_variable = [x+1 for x in sequence]
> 
> or are you talking about the loop variable inside the comprehension?
> 
> foo = [comprehension_variable+1 for comprehension_variable in sequence]
> 

Yeah by comprehension-variable I mean the one that sits left of the ‘in’ inside
The other obviously needn't exist
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Copying a compiled Python from one system to another

2016-10-01 Thread Steve D'Aprano
On Sat, 1 Oct 2016 10:01 pm, Chris Angelico wrote:

>> [...] I thought I could
>> compile 3.6 on this VM, then copy the python binary to my usual desktop
>> machine.
>>
>> What sort of challenges am I likely to find? Both machines are Linux, but
>> different distros.
> 
> First off, are they the same CPU architecture? 

I'll say yes.


> Are both Linuxes of broadly similar vintage? 

That depends on what you mean by "broadly similar". As far as I am
concerned, a five year difference is not very much, and is broadly
similar -- it's not like I'm using Linux from 1991. But the whole point is
that I need something with gcc 4.8 (maybe 4.7 will do, not sure) but
certainly not 4.4 which is the most recent I can get on my current systems.



> The most likely problems 
> you'll face will be library versions - CPython will happily link
> against any of several compatible versions of a library, but once it's
> linked against one, it'll want to find the same version thereafter.
> Worst case, you could symlink, but that could cause trouble when you
> upgrade, so I'd advise against it.

Does gcc support static linking? Even if I end up with a much bigger binary,
at least I know it will have everything it needs to run and I won't have to
deal with DLL hell.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: unintuitive for-loop behavior

2016-10-01 Thread Steve D'Aprano
On Sat, 1 Oct 2016 09:33 pm, Gregory Ewing wrote:

> Steve D'Aprano wrote:
> 
>> # create a new binding
>> x: address 1234 > [  box contains 999 ]
>> x: address 5678 > [  a different box, containing 888 ]
> 
> In the context of CPython and nested functions, replace
> "box" with "cell".


Cells in Python are an implementation detail. It only applies to CPython (as
far as I know), certainly not to IronPython, and the interpreter takes care
to ensure that the user-visible behaviour of local variables in cells is
identical to the behaviour of name bindings in dicts.

The only user-visible semantic differences between variables in a dict and
variables in cells are:

- writing to locals() won't necessarily affect the actual locals;
- in Python 3 only, import * and exec in the local names space may be
prohibited.

Everything else (that I know of) is indistinguishable. Python takes care to
hide the differences, for example even though local variables have a cell
pre-allocated when the function is called, trying to access that cell
before a value is bound to the local gives a NameError (UnboundLocalError)
rather than accessing uninitialised memory, as a naive implementation might
have done.

In any case, I think this is going off on a rather wide tangent -- how is
this specifically relevant to the "unintuitive for-loop behavior" the OP
was surprised by?



> When I said "creating a new binding" I meant that the
> name x refers to different cells at different times.
> When I said "updating an existing binding" I meant that
> the name x still refers to the same cell, but that cell
> refers to a different object.

I don't believe that there is any test you can write in Python that will
distinguish those two cases. (Excluding introspection of implementation
details, such as byte-code, undocumented C-level structures, etc.) As far
as ordinary Python operations go, I don't see that there's any difference
between the two.

When you say:

x = 0
x = 1

inside a function, and the interpreter does the name binding twice, there's
no way of telling whether it writes to the same cell each time or not.
Apart from possible performance and memory use, what difference would it
make? It is still the same 'x' name binding, regardless of the
implementation details.



> In a wider context, replace "box" with "slot in a
> stack frame" or "slot in a namespace dictionary".
> 
>> But Python doesn't work that way! Variables aren't modelled by boxes in
>> fixed locations, and there is no difference between "create a new
>> binding" and "update an existing one".
> 
> There is very much a distintion. Each time you invoke
> a function, a new set of bindings is created for all of
> its parameters and local names. Assigning to those names
> within the function, on the other hand, updates existing
> bindings.

Certainly when you call a function, the local bindings need to be created.
Obviously they didn't exist prior to calling the function! I didn't think
that was the difference you were referring to, and I fail to see how it
could be relevant to the question of for-loop behaviour.

As I understood you, you were referring to assignments to *existing* names.
If a binding for x already exists, then and only then do you have a choice
between:

- update the existing binding for x;
- or create a new binding for x.


If there is no binding for x yet (such as before the function is called),
then you have no choice in the matter: you cannot possibly update what
doesn't exist.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: unintuitive for-loop behavior

2016-10-01 Thread Jussi Piitulainen
Rustom Mody writes:

> And then define comprehensions not as now done in terms of for loops
> that mutatingly extend the list being built up but as recursive
> functions that get (re)called for every new value of the comprehension
> variable passed and therefore fresh-bound as parameter

You'd get the magical semantics for comprehensions from the current
definition of comprehension semantics in terms of the loop, if the loop
semantics was magical. Let me demonstrate. (The b-word is unfortunately
not available, so I substitute "magical" instead.)

# delayd = [ lambda : c for c in "abracadabra" ]
# is roughly/almost equal to the following.

delayd = []
for c in "abracadabra":
delayd.append(lambda : c)

print('Python:', ''.join(f() for f in delayd))

# But that for-loop could have been roughly equal to the following,
# giving both the comprehension and the underlying for-loop a
# semantics that some people say they would prefer.

delayd = [] # reset the list, not part of the loop

g1 = iter("abracadabra")
try:
while True:
def g2(c):
delayd.append(lambda : c)
g2(next(g1))
except StopIteration:
pass

print('Magick:', ''.join(f() for f in delayd))

# Output from the above:
# Python: aaa
# Magick: abracadabra
-- 
https://mail.python.org/mailman/listinfo/python-list


announcing fython

2016-10-01 Thread nicolasessisbreton
Hi All,

I would like to announce a new project call Fython.
In short, Fython is Fortran with a Python syntax.

Fython permits to write numerical code with the same syntax then Python.
Under the hood, the code is transpiled to Fortran and run at top speed.

Fython primary goal is to facilitate numerical coding:
- Fython code can be easily shared, because a Fython package behaves as a 
regular Python package.
- Fython offers many syntaxtic sugars, such as template and automatic variable 
completion, increasing programmer productivity.
- Fython assists for debugging, and can report the precise line where a 
segfault happen.

Compared to Cython, Fython is dedicated to numerical computing. This dedication 
produces often clearer and faster code.

Compared to Julia, Fython compiles directly to machine instructions. The 
programmer has total control over the compiled instructions, and this is 
desirable in some situations.

Fython is alpha code, but the code is sufficently stable to be used.
I think Fython has the potential to integrate the Python scientific stack. 
I hope some people will try it and provide feedback on how best to reach this 
goal.

Fython can be find here:

fython.readthedocs.io

Thanks,

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


Re: rocket simulation game with just using tkinter

2016-10-01 Thread Christian Gollwitzer

Am 01.10.16 um 00:59 schrieb Irmen de Jong:

Hi,

I've made a very simple rocket simulation game, inspired by the recent success 
of SpaceX



You can get the code here if you want to give it a try:
https://github.com/irmen/rocketsimulator


Nice! I'll have to rebind the keys before I can successfully play this, 
though. My [] "keys" are in fact combinations of Alt+5 and Alt+6 on a 
German Macbook keyboard (on a German PC, it is AltGr+8, AltGr+9). Why 
not using the arrow keys? These should be pretty universal


Christian


So you just need python 2/3 with tkinter to play this!


Have fun
Irmen



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


Re: Copying a compiled Python from one system to another

2016-10-01 Thread Grant Edwards
On 2016-10-01, Steve D'Aprano  wrote:

> Long story short: I have no working systems capable of compiling the
> latest Python 3.6, and no time to upgrade my usual machines to
> something which will work.
>
> However I do have access to another machine (actually a VM) which can
> compile Python 3.6. It's not practical for me to use it as a my main
> development machine, but as a temporary measure, I thought I could compile
> 3.6 on this VM, then copy the python binary to my usual desktop machine.

You'll probably need to copy more than just the binary.

> What sort of challenges am I likely to find?

Missing or incompatible libraries.  Wrong CPU type.

> Both machines are Linux, but different distros.

If they were the same distros, you'd have a much better chance. Then,
the right way to do it would be to build a binary package (.rpm, .deb,
.whatever) on one machine for installation on the other machine using
the normal package manager.  That way the library situation would get
verified (if perhaps not remedied).

-- 
Grant



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


Re: Copying a compiled Python from one system to another

2016-10-01 Thread Grant Edwards
On 2016-10-01, Steve D'Aprano  wrote:

> Does gcc support static linking?

Yes, but the real question is the CPython makefile includes recipes
for a statically-linked target.

> Even if I end up with a much bigger binary, at least I know it will
> have everything it needs to run and I won't have to deal with DLL
> hell.

-- 
Grant



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


Re: generator no iter - how do I call it from another function

2016-10-01 Thread Sayth Renshaw

> Steve
> “Cheer up,” they said, “things could be worse.” So I cheered up, and sure
> enough, things got worse.

Loving life.

I first started with a simple with open on a file, which allowed me to use code 
that "iter"'s.
for example:
for meet in root.iter("meeting"):
for race in root.iter("race"):
for nom in root.iter("nomination"):
meetattr = meet.attrib

I then got correct output so wanted to scale up to passing a directory of 
files. So skipping the code that deals with getting it off the command line I 
implemented a generator to yield the file root object as needed.

This is that code
def return_files(file_list):
"""
Take a list of files and return file when called.

Calling function to supply attributes
"""
for filename in sorted(file_list):
with open(dir_path + filename) as fd:
tree = etree.parse(fd)
root = tree.getroot()
yield root

My question is though now that I have implemented it this way my

I pull in the root via a function first few lines are
def dataAttr(roots):
"""Get the root object and iter items."""
with open("output/first2.csv", 'w', newline='') as csvf:
race_writer = csv.writer(csvf, delimiter=',')
for meet in roots.iter("meeting"):

which I call as
rootObs = return_files(file_list)
dataAttr(rootObs)

So if I use a generator to pass in the root lxml object to a function how do I 
iter since python provides an error that iters don't exist on python objects?

This is said error

± |master U:1 ?:1 ✗| → python3 race.py data/ -e *.xml
Traceback (most recent call last):
  File "race.py", line 77, in 
dataAttr(rootObs)
  File "race.py", line 55, in dataAttr
for meet in roots.iter("meeting"):
AttributeError: 'generator' object has no attribute 'iter'

Cheers

Sayth

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


Re: Copying a compiled Python from one system to another

2016-10-01 Thread Michael Torrie
On 10/01/2016 05:21 AM, Steve D'Aprano wrote:
> Long story short: I have no working systems capable of compiling the
> latest Python 3.6, and no time to upgrade my usual machines to
> something which will work.
> 
> However I do have access to another machine (actually a VM) which
> can compile Python 3.6. It's not practical for me to use it as a my
> main development machine, but as a temporary measure, I thought I
> could compile 3.6 on this VM, then copy the python binary to my usual
> desktop machine.
> 
> What sort of challenges am I likely to find? Both machines are Linux,
> but different distros.

If they use the same major version of glibc, both are either 64-bit or
32-bit, then if you compile to a self-contained location like /opt and
then copy that folder over it will run just fine.

If you compile to /usr, you'll have to make sure you tar up all the bits
that are scattered around the various directories under /usr.

What distros are we talking about here?  Ideally it would be nice to
build install-able packages for the target OS.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: unintuitive for-loop behavior

2016-10-01 Thread Jussi Piitulainen
I'm not sure any more to what message this should be a followup, but
here is a demonstration of two different semantics of the for-loop
variable scope/update, this time with nested loops using the same loop
variable name. The first function, tabulate, uses Python semantics ("t"
for true, if you like); the second, fabulate, is a translation ("f" for
false, if you like) that uses the magical semantics where the loop
variable is not only local to the loop but also a different variable on
each iteration. The latter property makes no difference in this
demonstration, but the former does; there's also a spurious counter that
is not local to the nested loops, just to be sure that it works as
expected (it does).

A summary of sorts: it's possible to demonstrate the scope difference in
Python code, with no box in sight; boxes are irrelevant; the relevant
issue is what function and when the loop variable is associated with,
explicitly or implicitly.

def tabulate(m, n):
for i in range(m):
print(i, end = ': ')
c = 0
for i in range(n):
print(i, end = ', ' if i + 1 < n else ' : ')
c += 1
print(i, c)

def fabulate(m, n):
c = None # because c belong in this scope
g1 = iter(range(m))
try:
while True:
def g2(i):
nonlocal c
print(i, end = ': ')
c = 0
g3 = iter(range(n))
try:
while True:
def g4(i):
nonlocal c
print(i, end = ', ' if i + 1 < n else ' : ')
c += 1
g4(next(g3))
except StopIteration:
pass
print(i, c)
g2(next(g1))
except StopIteration:
pass

print('Python:')
tabulate(3, 4)
print()
print('Magick:')
fabulate(3, 4)

# Output from the above, each line being
# outer i: each inner i : i after inner loop, c
# where either c correctly counts inner steps but
# Python inner i clobbers outer i, Magick not.
#
# Python:
# 0: 0, 1, 2, 3 : 3 4
# 1: 0, 1, 2, 3 : 3 4
# 2: 0, 1, 2, 3 : 3 4
#
# Magick:
# 0: 0, 1, 2, 3 : 0 4
# 1: 0, 1, 2, 3 : 1 4
# 2: 0, 1, 2, 3 : 2 4
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Copying a compiled Python from one system to another

2016-10-01 Thread Zachary Ware
On Oct 1, 2016 06:25, "Steve D'Aprano"  wrote:
>
> Long story short: I have no working systems capable of compiling the
latest
> Python 3.6, and no time to upgrade my usual machines to something which
> will work.

Since you're working on a pure-Python module (statistics), I'd recommend
updating to the latest changeset that will build, and work from there. I
don't know of any changes that would make it impossible for you to update
to the last working changeset, build, update to 3.6 tip, and develop and
test your statistics changes without rebuilding. You may have some test
failures, just run the full test suite after update to determine which
failures are not due to your development.

Otherwise, I'd suggest compiling your own GCC, but I haven't tried that
myself without the aid of Gentoo's package manager.

--
Zach
(On a phone)
-- 
https://mail.python.org/mailman/listinfo/python-list


ConfigParser: use newline in INI file

2016-10-01 Thread Thorsten Kampe
Hi,

ConfigParser escapes `\n` in ini values as `\\n`. Is there a way to 
signal to ConfigParser that there is a line break?

Thorsten


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


Re: unintuitive for-loop behavior

2016-10-01 Thread Rustom Mody
On Saturday, October 1, 2016 at 7:02:58 PM UTC+5:30, Jussi Piitulainen wrote:
> Rustom Mody writes:
> 
> > And then define comprehensions not as now done in terms of for loops
> > that mutatingly extend the list being built up but as recursive
> > functions that get (re)called for every new value of the comprehension
> > variable passed and therefore fresh-bound as parameter
> 
> You'd get the magical semantics for comprehensions from the current
> definition of comprehension semantics in terms of the loop, if the loop
> semantics was magical. Let me demonstrate. (The b-word is unfortunately
> not available, so I substitute "magical" instead.)
> 
> # delayd = [ lambda : c for c in "abracadabra" ]
> # is roughly/almost equal to the following.
> 
> delayd = []
> for c in "abracadabra":
> delayd.append(lambda : c)
> 
> print('Python:', ''.join(f() for f in delayd))
> 
> # But that for-loop could have been roughly equal to the following,
> # giving both the comprehension and the underlying for-loop a
> # semantics that some people say they would prefer.
> 
> delayd = [] # reset the list, not part of the loop
> 
> g1 = iter("abracadabra")
> try:
> while True:
> def g2(c):
> delayd.append(lambda : c)
> g2(next(g1))
> except StopIteration:
> pass
> 
> print('Magick:', ''.join(f() for f in delayd))
> 
> # Output from the above:
> # Python: aaa
> # Magick: abracadabra

Hoo boy1
Thats some tour de force and makes my head spin

Point can be made more simply with map
ie if we *define*
[exp for cv in l]
as
map(lambda cv: exp, l)

the problem vanishes

Demo:

First a helper function for demoing:

def pam(fl,x):
return map(lambda f: f(x), fl)
# pam is the complement to map; map runs one fnc on a list of args
# pam runs a list of funcs on one arg

Trying to make a list of functions that add one, two and three to their 
arguments

fl = [lambda x: x + cv for cv in [1,2,3]]

Broken because of python's wrong LC semantics:
>>> pam(fl, 3)
[6, 6, 6]

Transform the LC into a map with the rule above:
fl_good = map((lambda cv :lambda x: x+cv), [1,2,3])

Works!
>>> pam(fl_good, 3)
[4, 5, 6]
>>> 

Which is not very far from the standard workaround for this gotcha:
>>> fl_workaround = [lambda x, cv=cv: x+cv for cv in [1,2,3]]
>>> pam(fl_workaround, 3)
[4, 5, 6]
>>> 

Maybe we could say the workaround is the map definition uncurried
And then re-comprehension-ified
-- 
https://mail.python.org/mailman/listinfo/python-list


RASTER analysis(slope)

2016-10-01 Thread Xristos Xristoou
hello team

i want to calculate slope and aspect from some RASTER IMAGE(.grid,tiff,geotiff)
who is the better method to can i do this ?
with numpy and scipy or with some package?


thnx you team
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: unintuitive for-loop behavior

2016-10-01 Thread Steve D'Aprano
On Sun, 2 Oct 2016 03:57 am, Rustom Mody wrote:

> Hoo boy1
> Thats some tour de force and makes my head spin

I certainly agree with the second part of your sentence.


> Point can be made more simply with map
> ie if we *define*
> [exp for cv in l]
> as
> map(lambda cv: exp, l)
> 
> the problem vanishes

> 
> Demo:
> 
> First a helper function for demoing:
> 
> def pam(fl,x):
> return map(lambda f: f(x), fl)
> # pam is the complement to map; map runs one fnc on a list of args
> # pam runs a list of funcs on one arg
> 
> Trying to make a list of functions that add one, two and three to their
> arguments
> 
> fl = [lambda x: x + cv for cv in [1,2,3]]
> 
> Broken because of python's wrong LC semantics:
 pam(fl, 3)
> [6, 6, 6]

Its not *broken*, its doing *exactly what you told it to do*. You said,
define a function that takes a single argument x, and return x + cv. Then
you delayed evaluating it until cv = 3, and passed the argument 3, so of
course it returns 6. That's exactly what you told it to calculate.

You seem to have the concept that lambda should be magical, and just
miraculously know how far back in time to look for the value of cv. And
then when it doesn't, you're angry that Python is "broken". But why should
it be magical? cv is just an ordinary variable, and like all variables,
looking it up returns the value it has at the time you do the look-up, not
some time in the past. Let's unroll the loop:

fl = []
cv = 1
def f(x): return x + cv
fl.append(f)
cv = 2
def f(x): return x + cv
fl.append(f)
cv = 3
def f(x): return x + cv
fl.append(f)

pam(fl, 3)

Are you still surprised that it returns [6, 6, 6]?




> Transform the LC into a map with the rule above:
> fl_good = map((lambda cv :lambda x: x+cv), [1,2,3])


This is equivalent to something completely different, using a closure over
cv, so of course it works:

def factory(cv):
def inner(x):
return x + cv
return inner

fl_good = []
fl_good.append(factory(1))
fl_good.append(factory(2))
fl_good.append(factory(3))


Each time you call factory(), you get a new scope, with its own independent
variable cv. The inner function captures that environment (a closure),
which includes that local variable cv. Each invocation of factory leads to
an inner function that sees a different local variable which is independent
of the others but happens to have the same name. Instead of three functions
all looking up a single cv variable, you have three functions looking up
three different cv variables.

This is essentially why closures exist.


> Which is not very far from the standard workaround for this gotcha:
 fl_workaround = [lambda x, cv=cv: x+cv for cv in [1,2,3]]
 pam(fl_workaround, 3)
> [4, 5, 6]
 
> 
> Maybe we could say the workaround is the map definition uncurried
> And then re-comprehension-ified

If your students think in terms of map, then fine, but I think it would
confuse more people than it would help. Your mileage may vary.

There are certainly a number of ways to get the desired behaviour. If you
prefer to work with map, go right ahead.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: ConfigParser: use newline in INI file

2016-10-01 Thread Terry Reedy

On 10/1/2016 10:56 AM, Thorsten Kampe wrote:


ConfigParser escapes `\n` in ini values as `\\n`. Is there a way to
signal to ConfigParser that there is a line break?


Without an example or two, I don't really understand the question enough 
to answer.


--
Terry Jan Reedy

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


Re: rocket simulation game with just using tkinter

2016-10-01 Thread Irmen de Jong
On 1-10-2016 15:44, Christian Gollwitzer wrote:
> Am 01.10.16 um 00:59 schrieb Irmen de Jong:
>> Hi,
>>
>> I've made a very simple rocket simulation game, inspired by the recent 
>> success of SpaceX
> 
>> You can get the code here if you want to give it a try:
>> https://github.com/irmen/rocketsimulator
> 
> Nice! I'll have to rebind the keys before I can successfully play this, 
> though. My []
> "keys" are in fact combinations of Alt+5 and Alt+6 on a German Macbook 
> keyboard (on a
> German PC, it is AltGr+8, AltGr+9). Why not using the arrow keys? These 
> should be pretty
> universal

Oh, I'm sorry about that, my little knowledge of non-US keyboard layouts shows.
Arrow keys could be an option.   For my education what are the 2 keys to the 
right of
the P then on your keyboard?

Rebinding the keys should be easy though just change them in the keypress and 
keyrelease
methods.

Irmen

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


Re: ConfigParser: use newline in INI file

2016-10-01 Thread Ben Finney
Thorsten Kampe  writes:

> ConfigParser escapes `\n` in ini values as `\\n`.

How do you demonstrate that?

Here is an example text of a config file::

>>> import io
>>> import textwrap

>>> config_text = textwrap.dedent(r"""
... [foo]
... wibble = Lorem\nipsum.
... """)
>>> print(config_text)

[foo]
wibble = Lorem\nipsum.

So that text has the characters “\n” in it. (Note that I had to use the
‘r’ prefix on the string literal, in order to turn off the special
meaning of “\” and get that character literally.)

When I use a ConfigParser it reads “\n” and reproduces exactly those
characters::

>>> import configparser

>>> config_file = io.StringIO(config_text)
>>> config = configparser.ConfigParser()
>>> config.read_file(config_file)
>>> print(config['foo']['wibble'])
Lorem\nipsum.

So you see that the “\n” characters are preserved exactly by the
ConfigParser.

> Is there a way to signal to ConfigParser that there is a line break?

Yes, you use a line break. See the ‘configparser’ module documentation:

Values can also span multiple lines, as long as they are indented
deeper than the first line of the value. Depending on the parser’s
mode, blank lines may be treated as parts of multiline values or
ignored.


https://docs.python.org/3/library/configparser.html#supported-ini-file-structure>

Thus::

>>> config_text = textwrap.dedent(r"""
... [foo]
... wibble = Lorem
... ipsum.
... """)
>>> print(config_text)

[foo]
wibble = Lorem
ipsum.

>>> config_file = io.StringIO(config_text)
>>> config = configparser.ConfigParser()
>>> config.read_file(config_file)
>>> print(config['foo']['wibble'])
Lorem
ipsum.

-- 
 \  “Only the shallow know themselves.” —Oscar Wilde, _Phrases and |
  `\  Philosophies for the Use of the Young_, 1894 |
_o__)  |
Ben Finney

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


Re: unintuitive for-loop behavior

2016-10-01 Thread Terry Reedy

On 10/1/2016 8:24 AM, Rustom Mody wrote:


Yeah by comprehension-variable I mean the one that sits left of the
‘in’ inside the conprehension.


In other words, a 'loop variable within a comprehension'.  Keep in mind 
that there may be multiple targets for the implicit (hidden) assignment, 
so there may be multiple loop (comprehension) variables even without 
nested loops.


--
Terry Jan Reedy


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


Re: ConfigParser: use newline in INI file

2016-10-01 Thread Thorsten Kampe
* Terry Reedy (Sat, 1 Oct 2016 15:44:39 -0400)
> 
> On 10/1/2016 10:56 AM, Thorsten Kampe wrote:
> 
> > ConfigParser escapes `\n` in ini values as `\\n`. Is there a way to
> > signal to ConfigParser that there is a line break?
> 
> Without an example or two, I don't really understand the question enough 
> to answer.

>>> !cat INI.ini
[Asciidoc]
_test_stdout = \nHello, World!\n

>>> import configparser

>>> config = configparser.ConfigParser()

>>> config.read('INI.ini')
['INI.ini']

>>> config['Asciidoc']['_test_stdout']
'\\nHello, World!\\n'

...as you can see, ConfigParser escaped the backslash by doubling it. 
Which is fine in most cases - except when I want to have something 
indicating an newline.

Thorsten

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


Re: announcing fython

2016-10-01 Thread Chris Angelico
On Sat, Oct 1, 2016 at 11:41 PM,   wrote:
> Fython permits to write numerical code with the same syntax then Python.
> Under the hood, the code is transpiled to Fortran and run at top speed.

How does this compare to Python+Numpy? How much faster is Fython, and
what are the restrictions on the Python code?

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


Re: Copying a compiled Python from one system to another

2016-10-01 Thread Chris Angelico
On Sat, Oct 1, 2016 at 11:03 PM, Steve D'Aprano
 wrote:
>> Are both Linuxes of broadly similar vintage?
>
> That depends on what you mean by "broadly similar". As far as I am
> concerned, a five year difference is not very much, and is broadly
> similar -- it's not like I'm using Linux from 1991. But the whole point is
> that I need something with gcc 4.8 (maybe 4.7 will do, not sure) but
> certainly not 4.4 which is the most recent I can get on my current systems.

It's a rubbery term, but basically take the year of release of the
distro versions you're using, push 'em forward if they're
bleeding-edge distros or back if they're uber-stable, and try to guess
the age of the libraries they're running. Or check by looking at some
nice over-arching version number like Linux kernel; if they use
similar versions of Linux and libc, they probably have roughly similar
versions of a lot of other libraries, too.

The more similar the library versions, the less issues you'll have.

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


Re: ConfigParser: use newline in INI file

2016-10-01 Thread Thorsten Kampe
* Ben Finney (Sun, 02 Oct 2016 07:12:46 +1100)
> 
> Thorsten Kampe  writes:
> 
> > ConfigParser escapes `\n` in ini values as `\\n`.

Indenting solves the problem. I'd rather keep it one line per value 
but it solves the problem.

Thorsten

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


Re: RASTER analysis(slope)

2016-10-01 Thread Sayth Renshaw
On Sunday, 2 October 2016 04:52:13 UTC+11, Xristos Xristoou  wrote:
> hello team
> 
> i want to calculate slope and aspect from some RASTER 
> IMAGE(.grid,tiff,geotiff)
> who is the better method to can i do this ?
> with numpy and scipy or with some package?
> 
> 
> thnx you team

I don't know much about the topic however pyDem seems like the appropriate 
library to use.

https://pypi.python.org/pypi/pyDEM/0.1.1

Here is a standford article on it
https://pangea.stanford.edu/~samuelj/musings/dems-in-python-pt-3-slope-and-hillshades-.html

and a pdf from scipy conference.

https://conference.scipy.org/proceedings/scipy2015/pdfs/mattheus_ueckermann.pdf

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


Re: Copying a compiled Python from one system to another

2016-10-01 Thread Paul Rubin
Steve D'Aprano  writes:
> However I do have access to another machine (actually a VM) which can
> compile Python 3.6. It's not practical for me to use it as a my main
> development machine, but as a temporary measure, I thought I could
> compile 3.6 on this VM, then copy the python binary to my usual
> desktop machine.

How about installing the same OS on the VM that you're running on the
development machine?  

You can get powerful hourly VM's (x86) and dedicated servers (x86 and
ARM) really cheap at Scaleway.com.  I've used them for a while and they
work well.
-- 
https://mail.python.org/mailman/listinfo/python-list


Byte code descriptions somewhere?

2016-10-01 Thread Cem Karan
Hi all, I've all of a sudden gotten interested in the CPython interpreter, and 
started trying to understand how it ingests and runs byte code.  I found 
Include/opcode.h in the python sources, and I found some basic documentation on 
how to add in new opcodes online, but I haven't found the equivalent of an 
assembly manual like you might for x86, etc.  Is there something similar to a 
manual dedicated to python byte code?  Also, is there a manual for how the 
interpreter expects the stack, etc. to be setup so that all interactions go as 
expected (garbage collections works, exceptions work, etc.)?  Basically, I want 
a manual similar to what Intel or AMD might put out for their chips so that all 
executables behave nicely with one another.

Thanks,
Cem Karan
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Byte code descriptions somewhere?

2016-10-01 Thread Ben Finney
Cem Karan  writes:

> Hi all, I've all of a sudden gotten interested in the CPython
> interpreter, and started trying to understand how it ingests and runs
> byte code.

That sounds like fun!

> Is there something similar to a manual dedicated to python byte code?

The Python documentation for the ‘dis’ module shows not only how to use
that module for dis-assembly of Python byte code, but also a reference
for the byte code.

32.12. dis — Disassembler for Python bytecode

https://docs.python.org/3/library/dis.html>

-- 
 \ “Skepticism is the highest duty and blind faith the one |
  `\   unpardonable sin.” —Thomas Henry Huxley, _Essays on |
_o__)   Controversial Questions_, 1889 |
Ben Finney

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


Re: Byte code descriptions somewhere?

2016-10-01 Thread Cem Karan
Cool, thank you!  Quick experimentation suggests that I don't need to worry 
about marking anything for garbage collection, correct?  The next question is, 
how do I create a stream of byte codes that can be interpreted by CPython 
directly?  I don't mean 'use the compile module', I mean writing my own byte 
array with bytes that CPython can directly interpret.

Thanks,
Cem Karan


On Oct 1, 2016, at 7:02 PM, Ben Finney  wrote:

> Cem Karan  writes:
> 
>> Hi all, I've all of a sudden gotten interested in the CPython
>> interpreter, and started trying to understand how it ingests and runs
>> byte code.
> 
> That sounds like fun!
> 
>> Is there something similar to a manual dedicated to python byte code?
> 
> The Python documentation for the ‘dis’ module shows not only how to use
> that module for dis-assembly of Python byte code, but also a reference
> for the byte code.
> 
>32.12. dis — Disassembler for Python bytecode
> 
>https://docs.python.org/3/library/dis.html>
> 
> -- 
> \ “Skepticism is the highest duty and blind faith the one |
>  `\   unpardonable sin.” —Thomas Henry Huxley, _Essays on |
> _o__)   Controversial Questions_, 1889 |
> Ben Finney
> 
> -- 
> https://mail.python.org/mailman/listinfo/python-list

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


Re: Byte code descriptions somewhere?

2016-10-01 Thread Paul Rubin
Cem Karan  writes:
> how do I create a stream of byte codes that can be interpreted by
> CPython directly?

Basically, study the already existing code and do something similar.
The CPython bytecode isn't standardized like JVM bytecode.  It's
designed for the interpreter's convenience, not officially documented,
and (somewhat) subject to change between versions.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Byte code descriptions somewhere?

2016-10-01 Thread Chris Angelico
On Sun, Oct 2, 2016 at 10:47 AM, Cem Karan  wrote:
> Cool, thank you!  Quick experimentation suggests that I don't need to worry 
> about marking anything for garbage collection, correct?  The next question 
> is, how do I create a stream of byte codes that can be interpreted by CPython 
> directly?  I don't mean 'use the compile module', I mean writing my own byte 
> array with bytes that CPython can directly interpret.
>

"Marking for garbage collection" in CPython is done by refcounts; the
bytecode is at a higher level than that.

>>> dis.dis("x = y*2")
  1   0 LOAD_NAME0 (y)
  3 LOAD_CONST   0 (2)
  6 BINARY_MULTIPLY
  7 STORE_NAME   1 (x)
 10 LOAD_CONST   1 (None)
 13 RETURN_VALUE

A LOAD operation will increase the refcount (a ref is on the stack),
BINARY_MULTIPLY dereferences the multiplicands and adds a ref to the
product, STORE will deref whatever previously was stored, etc.

To execute your own code, look at types.FunctionType and
types.CodeType, particularly the latter's 'codestring' argument
(stored as the co_code attribute). Be careful: you can easily crash
CPython if you mess this stuff up :)

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


Converting PyMember_Get usage to PyMember_GetOne - no docs?

2016-10-01 Thread Skip Montanaro
I'm trying to convert the python-sybase module C code from oldish Python 2
usage to work in Python 3. The code currently calls PyMember_Get(), which
is obsolete. In later versions of Python 2, PyMember_GetOne became the
official way to do things, the the former function was still available. In
Python 3, PyMember_Get() is gone.

This is all well and good, but I can't find documentation for either
function, or seemingly examples of code which converted from one to the
other. Any pointers?

Thx,

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


Re: announcing fython

2016-10-01 Thread Raoul Fleckman
On 2016-10-01, Chris Angelico  wrote:
> On Sat, Oct 1, 2016 at 11:41 PM,   wrote:
>> Fython permits to write numerical code with the same syntax then Python.
>> Under the hood, the code is transpiled to Fortran and run at top speed.
>
> How does this compare to Python+Numpy? How much faster is Fython, and
> what are the restrictions on the Python code?
>
> ChrisA

Interested to hear the answers to those questions, and whether Fython is
pass by reference (Fortran) or value (python, unless passing a list, for
example); and then there's the 'little' matter of one-based (Fortran) or
zero-based (python) arrays?

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


inplace text filter - without writing file

2016-10-01 Thread Sayth Renshaw
Hi

I have a fileobject which was fine however now I want to delete a line from the 
file object before yielding.

def return_files(file_list):
for filename in sorted(file_list):
with open(dir_path + filename) as fd:
 for fileItem in fd:
 yield fileItem

Ned gave an answer over here http://stackoverflow.com/a/6985814/461887

for i, line in enumerate(input_file):
if i == 0 or not line.startswith('#'):
output.write(line)

which I would change because it is the first line and I want to rid 

Re: Byte code descriptions somewhere?

2016-10-01 Thread Ned Batchelder
On Saturday, October 1, 2016 at 7:48:09 PM UTC-4, Cem Karan wrote:
> Cool, thank you!  Quick experimentation suggests that I don't need to worry 
> about marking anything for garbage collection, correct?  The next question 
> is, how do I create a stream of byte codes that can be interpreted by CPython 
> directly?  I don't mean 'use the compile module', I mean writing my own byte 
> array with bytes that CPython can directly interpret.

In Python 2, you use new.code: 
https://docs.python.org/2/library/new.html#new.code  It takes a bytestring of 
byte codes as one of its
twelve (!) arguments.

Something that might help (indirectly) with understanding bytecode:
byterun (https://github.com/nedbat/byterun) is a pure-Python implementation
of a Python bytecode VM.

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


Re: announcing fython

2016-10-01 Thread Chris Angelico
On Sun, Oct 2, 2016 at 11:18 AM, Raoul Fleckman
 wrote:
> Interested to hear the answers to those questions, and whether Fython is
> pass by reference (Fortran) or value (python, unless passing a list, for
> example); and then there's the 'little' matter of one-based (Fortran) or
> zero-based (python) arrays?

Python doesn't have two different pass-by-X conventions. Please read
and comprehend:

http://nedbatchelder.com/text/names1.html

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


Re: ConfigParser: use newline in INI file

2016-10-01 Thread Ned Batchelder
On Saturday, October 1, 2016 at 6:25:16 PM UTC-4, Thorsten Kampe wrote:
> * Ben Finney (Sun, 02 Oct 2016 07:12:46 +1100)
> > 
> > Thorsten Kampe  writes:
> > 
> > > ConfigParser escapes `\n` in ini values as `\\n`.
> 
> Indenting solves the problem. I'd rather keep it one line per value 
> but it solves the problem.

If you want to have \n mean a newline in your config file, you can 
do the conversion after you read the value:

>>> "a\\nb".decode("string-escape")
'a\nb'

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


Re: unintuitive for-loop behavior

2016-10-01 Thread Gregory Ewing

Steve D'Aprano wrote:

When you say:

x = 0
x = 1

inside a function, and the interpreter does the name binding twice, there's
no way of telling whether it writes to the same cell each time or not.


Yes, there is:

...  x = 0
...  f1 = lambda: x
...  x = 1
...  f2 = lambda: x
...  print(f1(), f2())
...
>>> f()
1 1

This indicates that both assignments updated the same slot.
Otherwise the result would have been "0 1".

It's not currently possible to observe the other behaviour in
Python, because the only way to create new bindings for local
names is to enter a function. The change to for-loop semantics
I'm talking about would introduce another way.


Certainly when you call a function, the local bindings need to be created.
Obviously they didn't exist prior to calling the function! I didn't think
that was the difference you were referring to, and I fail to see how it
could be relevant to the question of for-loop behaviour.


My proposed change is (mostly) equivalent to turning the
loop body into a thunk and passing the loop variable in as
a parameter.

This is the way for-loops or their equivalent are actually
implemented in Scheme, Ruby, Smalltalk and many other similar
languages, which is why they don't have the same "gotcha".
(Incidentally, this is why some people describe Python's
behaviour here as "broken". They ask -- it works perfectly
well in these other languages, why is Python different?)

The trick with cells is a way to get the same effect in
CPython, without the overhead of an actual function call
on each iteration (and avoiding some of the other problems
that using a thunk would entail).

The cell trick isn't strictly necessary, though -- other
Python implementations could use a thunk if they had to.

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


Re: generator no iter - how do I call it from another function

2016-10-01 Thread Gregory Ewing

Sayth Renshaw wrote:

def dataAttr(roots):
"""Get the root object and iter items."""
with open("output/first2.csv", 'w', newline='') as csvf:
race_writer = csv.writer(csvf, delimiter=',')
for meet in roots.iter("meeting"):


The value of roots you're passing in here is a generator
object that yields root instances, not a root instance itself.
So it looks like you need another level of iteration:

   for root in roots:
  for meet in root.iter("meeting"):
 ...

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


Re: Lawrence D'Oliveiro

2016-10-01 Thread Gregory Ewing

On Fri, 30 Sep 2016 23:29:41 -0700, Paul Rubin 
declaimed the following:


That's the weird Italian spam that the newsgroup has been getting for a
while.  I've been wondering for a while if anyone knows what the story
is, i.e. why it's on comp.lang.python but not on other newsgroups that
I've noticed.


The Spanish Inquisition is trying to get the Pope
impeached, or something?

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


Re: inplace text filter - without writing file

2016-10-01 Thread MRAB

On 2016-10-02 01:21, Sayth Renshaw wrote:

Hi

I have a fileobject which was fine however now I want to delete a line from the 
file object before yielding.

def return_files(file_list):
for filename in sorted(file_list):


When joining paths together, it's better to use 'os.path.join'.


with open(dir_path + filename) as fd:
 for fileItem in fd:
 yield fileItem

Ned gave an answer over here http://stackoverflow.com/a/6985814/461887

for i, line in enumerate(input_file):
if i == 0 or not line.startswith('#'):
output.write(line)

which I would change because it is the first line and I want to rid 

Need help for the print() function with a better order

2016-10-01 Thread 380162267qq
I am trying to print a simple decision tree for my homework.
The answer must keep in this format:

Top 7,4,0.95
career gain = 100
1.Management 2, 3, 0.9709505944546686
2.Service 5, 1, 0.6500224216483541
location gain = 100
1.Oregon 4, 1, 0.7219280948873623
2.California 3, 3, 1.0
edu_level gain = 100
1.High School 5, 1, 0.6500224216483541
2.College 2, 3, 0.9709505944546686
years_exp gain = 100
1.Less than 3 3, 1, 0.8112781244591328
2.3 to 10 2, 1, 0.9182958340544896
3.More than 10 2, 2, 1.0

Here is my code:
features={'edu_level':['High School','College'],'career':
['Management','Service'],'years_exp':['Less than 3','3 to 10','More than 
10'],'location':['Oregon','California']}

print('Top 7,4,0.95')
for key in features:
print('{} gain = {}'.format(key,100))
attributes_list=features[key]
kargs={}
for i in range(len(attributes_list)):
kargs[key]=attributes_list[i]
low=table.count('Low',**kargs)
high=table.count('High',**kargs)
print('\t{}.{} {}, {}, 
{}'.format(i+1,attributes_list[i],low,high,entropy(low,high)))





I set all the gain as 100 now.But actually the gain must calculate with the 
data below.
For example, the career gain need the data of 'Management' and 'Service'.
I don't know how to do.
or Anyone can provide me a better logic?



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


Thonny 2.0 released (Python IDE for beginners)

2016-10-01 Thread Aivar Annamaa
 

Hi! 

Thonny is Python IDE for learning and teaching programming. It is
developed in University of Tartu, Estonia. 

It has an easy to use debugger which shows clearly how Python executes
your programs. Unlike most debuggers, it can even show the steps of
evaluating an expression, visually explain references, function calls,
exceptions etc. 

For more info and downloads see http://thonny.cs.ut.ee/ [1] 

best regards, 

Aivar Annamaa
University of Tartu
Institute of Computer Science 

 

http://thonny.cs.ut.ee";>Thonny 2.0 - Python IDE for
beginners (01-Oct-16) 
 

Links:
--
[1] http://thonny.cs.ut.ee/
-- 
https://mail.python.org/mailman/listinfo/python-list


Merecurial and Python-2.7.x, Python-3.Y

2016-10-01 Thread Michael Felt
Finally, I got to where I understood what needed to be done to get both 
Mercurial built - and the the new SSL requirements met.


So, running:

# hg clone https://hg.python.org/cpython

works. What is the next step to getting Python-2.7 AND Python-3.7 so I 
can submit patches against both versions and/or other versions?


Is it going to be a command like in the developer guide (that references 
Python3.5)?


Does this create a new directory, or just undo a lot of things that was 
just cloned - or was 3.5 the development branch when the guide was last 
updated?


Will I need to clone (as above) several times - one for each version I 
want to test against - and then run a second command -- OR --


is there an hg clone command to get a specific version (If that is in 
the guide - my apologies, as I missed it.


Thanks for hints and patience!

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


Re: Byte code descriptions somewhere?

2016-10-01 Thread breamoreboy
On Saturday, October 1, 2016 at 11:57:17 PM UTC+1, Cem Karan wrote:
> Hi all, I've all of a sudden gotten interested in the CPython interpreter, 
> and started trying to understand how it ingests and runs byte code.  I found 
> Include/opcode.h in the python sources, and I found some basic documentation 
> on how to add in new opcodes online, but I haven't found the equivalent of an 
> assembly manual like you might for x86, etc.  Is there something similar to a 
> manual dedicated to python byte code?  Also, is there a manual for how the 
> interpreter expects the stack, etc. to be setup so that all interactions go 
> as expected (garbage collections works, exceptions work, etc.)?  Basically, I 
> want a manual similar to what Intel or AMD might put out for their chips so 
> that all executables behave nicely with one another.
> 
> Thanks,
> Cem Karan

Further to Ben Finney's answer this 
https://docs.python.org/devguide/compiler.html should help.

Kindest regards.

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


Reading the Windows Location API

2016-10-01 Thread Glenn Linderman
I found some GeoLocation stuff on PyPi, but it seems to be focused on 
turning an IP address into a (rough) location rather than reading a GPS. 
Seems like if a GPS is attached, reading it would be the best way to 
obtain a more accurate location, falling back to approximations if there 
is no GPS.


But I'm not sure where to start with reading the Windows Location API.  
Anyone have some clues or sample code?

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


Re: Copying a compiled Python from one system to another

2016-10-01 Thread Steve D'Aprano
On Sun, 2 Oct 2016 09:31 am, Paul Rubin wrote:

> Steve D'Aprano  writes:
>> However I do have access to another machine (actually a VM) which can
>> compile Python 3.6. It's not practical for me to use it as a my main
>> development machine, but as a temporary measure, I thought I could
>> compile 3.6 on this VM, then copy the python binary to my usual
>> desktop machine.
> 
> How about installing the same OS on the VM that you're running on the
> development machine?

Because then I won't be able to build Python on the VM either, which
completely misses the point. I already have three machines that cannot
build Python. I don't need a fourth. I need one which *can* build Python.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: announcing fython

2016-10-01 Thread Steve D'Aprano
On Sun, 2 Oct 2016 11:18 am, Raoul Fleckman wrote:

> Interested to hear the answers to those questions, and whether Fython is
> pass by reference (Fortran) or value (python, unless passing a list, for
> example); 

That's not how Python works. Ints and lists are passed exactly the same way,
neither by value nor by reference.

http://import-that.dreamwidth.org/1130.html



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: announcing fython

2016-10-01 Thread nicolasessisbreton
**How does this compare to Python+Numpy? 
**How much faster is Fython, and what are the restrictions on the Python code? 

Python+Numpy allows easy processing of vector, but there is a limit to how much
user-defined logic can be used with Numpy.
For example, operating on three different arrays to do something like

if x[i]  > 0 :
temp = get_value( y[i] )

if temp > 0:
z[i] = another_operation( z[i] )

may require three different Numpy calls.
With Fython, the if statements and the loop around them is directly compiled to 
machine code.

Fython speed is the same as Fortran speed.
In some applications, I get a speed-up of 100 compared to Cython, and a 
speed-up of 10 compared to C.
I'm not a Cython nor a C expert, and I know that with some good compiler flags, 
one may make the performance of these two languages similar two Fortran.
The advantage of Fython is that everything is tune out-of-box because of its 
connection to Fortran.

There is no restriction on the Python code.
Once a Fython program is avalaible, Python can throw any scalar or Numpy array 
at it.

**whether Fython is pass by reference (Fortran) or value 
**and then there's the 'little' matter of one-based (Fortran) or zero-based 
(python) arrays? 

Fython is passed by reference, so that any modification made to a variable in 
Fython is propagated back to Python.

Fython follows Fortran syntax and is one-based by default.
This doesn't give any interop problem with Python, because what matters is to 
know the pointer to the first element of an array, and Fython knows it.

For the programmer convenience, like Fortran, Fython allows the choice between 
one-based and zero-based indexing at array declaration.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Copying a compiled Python from one system to another

2016-10-01 Thread Chris Angelico
On Sun, Oct 2, 2016 at 1:51 PM, Steve D'Aprano
 wrote:
> On Sun, 2 Oct 2016 09:31 am, Paul Rubin wrote:
>
>> Steve D'Aprano  writes:
>>> However I do have access to another machine (actually a VM) which can
>>> compile Python 3.6. It's not practical for me to use it as a my main
>>> development machine, but as a temporary measure, I thought I could
>>> compile 3.6 on this VM, then copy the python binary to my usual
>>> desktop machine.
>>
>> How about installing the same OS on the VM that you're running on the
>> development machine?
>
> Because then I won't be able to build Python on the VM either, which
> completely misses the point. I already have three machines that cannot
> build Python. I don't need a fourth. I need one which *can* build Python.

Hmm, I've possibly missed something here, which may indicate a
problem. Why can't your existing machines build? Is it because they
have too-old versions of tools, and if so, which?

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


Re: announcing fython

2016-10-01 Thread Chris Angelico
On Sun, Oct 2, 2016 at 1:58 PM,   wrote:
> Fython speed is the same as Fortran speed.
>
> There is no restriction on the Python code.
> Once a Fython program is avalaible, Python can throw any scalar or Numpy 
> array at it.
>
> For the programmer convenience, like Fortran, Fython allows the choice between
> one-based and zero-based indexing at array declaration.

This is where I'm a little confused. Is Fython a full-featured Python
implementation that compiles to Fortran, or a thin wrapper around
Fortran that uses Python syntax, or something in between?

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


Re: announcing fython

2016-10-01 Thread Michael Torrie
On 10/01/2016 09:06 PM, Chris Angelico wrote:
> On Sun, Oct 2, 2016 at 1:58 PM,   wrote:
>> Fython speed is the same as Fortran speed.
>>
>> There is no restriction on the Python code.
>> Once a Fython program is avalaible, Python can throw any scalar or Numpy 
>> array at it.
>>
>> For the programmer convenience, like Fortran, Fython allows the choice 
>> between
>> one-based and zero-based indexing at array declaration.
> 
> This is where I'm a little confused. Is Fython a full-featured Python
> implementation that compiles to Fortran, or a thin wrapper around
> Fortran that uses Python syntax, or something in between?

>From the web page, it's appears to be just Fortran with a Python-ish
syntax, but with a special Python module ("import fython") to more
easily allow the use of Fortran or Fython constructs (compiled fortran
code) from within actual Python.  Seems to allow the blending of
Fortran, Python, and Numpy.  Sounds pretty useful.  A transpiler and
also a Python bridge.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: inplace text filter - without writing file

2016-10-01 Thread Sayth Renshaw
Thank you
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: announcing fython

2016-10-01 Thread Raoul Fleckman
On 2016-10-02, nicolasessisbre...@gmail.com :
> **How does this compare to Python+Numpy? 
> **How much faster is Fython, and what are the restrictions on the
> **Python code? 
>
> Python+Numpy allows easy processing of vector, but there is a limit to
> how much user-defined logic can be used with Numpy.  For example,
> operating on three different arrays to do something like
>
>   if x[i]  > 0 :
>   temp = get_value( y[i] )
>
>   if temp > 0:
>   z[i] = another_operation( z[i] )
>
> may require three different Numpy calls.
> With Fython, the if statements and the loop around them is directly
>  compiled to machine code.

> Fython speed is the same as Fortran speed.
>
> In some applications, I get a speed-up of 100 compared to Cython, and
>  a speed-up of 10 compared to C.
>
> I'm not a Cython nor a C expert, and I know that with some good
> compiler flags, one may make the performance of these two languages
> similar two Fortran.  The advantage of Fython is that everything is
> tune out-of-box because of its connection to Fortran.
>
> There is no restriction on the Python code.
> Once a Fython program is avalaible, Python can throw any scalar or
>  Numpy array at it.
>
> **whether Fython is pass by reference (Fortran) or value 
> **and then there's the 'little' matter of one-based (Fortran) or
> **zero-based (python) arrays? 
>
> Fython is passed by reference, so that any modification made to a
>  variable in Fython is propagated back to Python.
>
> Fython follows Fortran syntax and is one-based by default.

> This doesn't give any interop problem with Python, because what
>  matters is to know the pointer to the first element of an array, and
>  Fython knows it.
>
> For the programmer convenience, like Fortran, Fython allows the choice
>  between one-based and zero-based indexing at array declaration.

Thank you!  it sounds very interesting indeed, particularly for those of
us with a substantial Fortran code base which needs to be updated.
Please keep us posted on your progress!

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


Re: unintuitive for-loop behavior

2016-10-01 Thread Steve D'Aprano
On Sun, 2 Oct 2016 12:28 am, Jussi Piitulainen wrote:

> I'm not sure any more to what message this should be a followup, but
> here is a demonstration of two different semantics of the for-loop
> variable scope/update, this time with nested loops using the same loop
> variable name. The first function, tabulate, uses Python semantics ("t"
> for true, if you like); the second, fabulate, is a translation ("f" for
> false, if you like) that uses the magical semantics where the loop
> variable is not only local to the loop but also a different variable on
> each iteration. 

I'm sorry, I don't understand what you mean by "Python semantics" versus "a
translation". A translation of what? In what way is it "magical semantics"?
I see nothing magical in your code: it is Python code.

Of course, it is complex, complicated, convoluted, obfuscated, hard to
understand, non-idiomatic Python code, but there's nothing magical in it
(unless you count nonlocal as magic). And it does nothing that can't be
done more simply: just change the tabulate inner loop variable to a
different name.


def fabulate2(m, n):
# The simple, Pythonic, non-complicated way.
for i in range(m):
print(i, end = ': ')
c = 0
for j in range(n):
print(j, end = ', ' if j + 1 < n else ' : ')
c += 1
print(i, c)


Your version of tabulate and fabulate:
py> tabulate(3, 4)
0: 0, 1, 2, 3 : 3 4
1: 0, 1, 2, 3 : 3 4
2: 0, 1, 2, 3 : 3 4

py> fabulate(3, 4)
0: 0, 1, 2, 3 : 0 4
1: 0, 1, 2, 3 : 1 4
2: 0, 1, 2, 3 : 2 4

My simple version of fabulate:

py> fabulate2(3, 4)
0: 0, 1, 2, 3 : 0 4
1: 0, 1, 2, 3 : 1 4
2: 0, 1, 2, 3 : 2 4


> The latter property makes no difference in this 
> demonstration, but the former does; there's also a spurious counter that
> is not local to the nested loops, just to be sure that it works as
> expected (it does).
> 
> A summary of sorts: it's possible to demonstrate the scope difference in
> Python code, with no box in sight; boxes are irrelevant; the relevant
> issue is what function and when the loop variable is associated with,
> explicitly or implicitly.

I don't know what "scope difference" you think you are demonstrating.
tabulate() has a single scope, fabulate() has multiple scopes because it
has inner functions that take i as argument, making them local to the inner
functions. Um, yeah, of course they are different. They're different
because you've written them differently. What's your point?

As far as I can see, all you have demonstrated is that it is possible to
write obfuscated code in Python. But we already knew that.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: Copying a compiled Python from one system to another

2016-10-01 Thread Steve D'Aprano
On Sun, 2 Oct 2016 12:30 am, Zachary Ware wrote:

> On Oct 1, 2016 06:25, "Steve D'Aprano"  wrote:
>>
>> Long story short: I have no working systems capable of compiling the
> latest
>> Python 3.6, and no time to upgrade my usual machines to something which
>> will work.
> 
> Since you're working on a pure-Python module (statistics), I'd recommend
> updating to the latest changeset that will build, and work from there. I
> don't know of any changes that would make it impossible for you to update
> to the last working changeset, build, update to 3.6 tip, and develop and
> test your statistics changes without rebuilding.

That actually sounds like it might be workable.

Thanks for the suggestion. Now I just need to work out the latest changeset
that works...





-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: Copying a compiled Python from one system to another

2016-10-01 Thread Steve D'Aprano
On Sun, 2 Oct 2016 01:58 pm, Chris Angelico wrote:

> Hmm, I've possibly missed something here, which may indicate a
> problem. Why can't your existing machines build? Is it because they
> have too-old versions of tools, and if so, which?

Yes, this. You need gcc 4.8 or better to build CPython 3.6, and the most
recent any of my systems support is 4.4.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

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


Re: unintuitive for-loop behavior

2016-10-01 Thread Steve D'Aprano
On Sun, 2 Oct 2016 11:44 am, Gregory Ewing wrote:

> Steve D'Aprano wrote:
>> When you say:
>> 
>> x = 0
>> x = 1
>> 
>> inside a function, and the interpreter does the name binding twice,
>> there's no way of telling whether it writes to the same cell each time or
>> not.
> 
> Yes, there is:
> 
> ...  x = 0
> ...  f1 = lambda: x
> ...  x = 1
> ...  f2 = lambda: x
> ...  print(f1(), f2())
> ...
>  >>> f()
> 1 1
> 
> This indicates that both assignments updated the same slot.
> Otherwise the result would have been "0 1".


No it doesn't mean that at all. The result you see is compatible with *both*
the "update existing slot" behaviour and "create a new slot" behavior. The
*easiest* way to prove that is to categorically delete the existing "slot"
and re-create it:

x = 0
f1 = lambda: x
del x
assert 'x' not in locals()
x = 1
f2 = lambda: x
print(f1(), f2())


which will still print exactly the same results. 

Objection: I predict that you're going to object that despite the `del x`
and the assertion, *if* this code is run inside a function, the "x slot"
actually does still exist. It's not "really" deleted, the interpreter just
makes sure that the high-level behaviour is the same as if it actually were
deleted.

Well yes, but that's exactly what I'm saying: that's not an objection, it
supports my argument! The way CPython handles local variables is an
implementation detail. The high-level semantics is *identical* between
CPython functions, where local variables live in a static array of "slots"
and re-binding always updates an existing slot, and IronPython, where they
don't. The only way you can tell them apart is by studying the
implementation.

In IronPython, you could have the following occur in a function locals, just
as it could happen CPython for globals:

- delete the name binding "x"
- which triggers a dictionary resize
- bind a value to x again
- because the dictionary is resized, the new "slot" for x is in a 
  completely different position of the dictionary to the old one

There is no user-visible difference between these two situations. Your code
works the same way whether it is executed inside a function or at the
global top level, whether functions use the CPython local variable
optimization or not.


> It's not currently possible to observe the other behaviour in
> Python, because the only way to create new bindings for local
> names is to enter a function.

Not at all. Delete a name, and the binding for that name is gone. Now assign
to that name again, and a new binding must be created, by definition, since
a moment ago it no longer existed.

x = 1
del x
assert 'x' not in locals()
x = 2


> The change to for-loop semantics 
> I'm talking about would introduce another way.

I have lost track of how this is supposed to change for-loop semantics.

I'm especially confused because you seem to be arguing that by using an
implementation which CPython already uses, for-loops would behave
differently. So either I'm not reading you right or you're not explaining
yourself well.



>> Certainly when you call a function, the local bindings need to be
>> created. Obviously they didn't exist prior to calling the function! I
>> didn't think that was the difference you were referring to, and I fail to
>> see how it could be relevant to the question of for-loop behaviour.
> 
> My proposed change is (mostly) equivalent to turning the
> loop body into a thunk and passing the loop variable in as
> a parameter.

A thunk is not really well-defined in Python, because it doesn't exist, and
therefore we don't know what properties it will have. But generally when
people talk about thunks, they mean something like a light-weight anonymous
function without any parameters:

https://en.wikipedia.org/wiki/Thunk


You say "passing the loop variable in as a parameter" -- this doesn't make
sense. Variables are not values in Python. You cannot pass in a
*variable* -- you can pass in a name (the string 'x') or the *value* bound
to the name, but there's no existing facility in Python to pass in a
variable. If there was, you could do the classic "pass by reference" test:

Write a *procedure* which takes as argument two variables 
and swaps their contents

but there's no facility to do something like that in Python. So its hard to
talk about your hypothetical change except in hand-wavy terms:

"Something magically and undefined happens, which somehow gives the result I
want."



> This is the way for-loops or their equivalent are actually
> implemented in Scheme, Ruby, Smalltalk and many other similar
> languages, which is why they don't have the same "gotcha".

Instead, they presumably have some other gotcha -- "why don't for loops work
the same as unrolled loops?", perhaps.

In Python, the most obvious gotcha would be that if for-loops introduced
their own scope, you would have to declare any other variables in the outer
scope nonlocal. So this would work fine as top-level code:

x = 1
for i in range(10):
print(

Re: Copying a compiled Python from one system to another

2016-10-01 Thread Chris Angelico
On Sun, Oct 2, 2016 at 3:25 PM, Steve D'Aprano
 wrote:
> On Sun, 2 Oct 2016 01:58 pm, Chris Angelico wrote:
>
>> Hmm, I've possibly missed something here, which may indicate a
>> problem. Why can't your existing machines build? Is it because they
>> have too-old versions of tools, and if so, which?
>
> Yes, this. You need gcc 4.8 or better to build CPython 3.6, and the most
> recent any of my systems support is 4.4.

In itself not a problem, but you might find that libc is an
incompatibly different version, which would be a pain.

But, give it a try. Worst case, it fails with a linker error straight
away. (And you MAY be able to just copy in some libraries from the
other system.)

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


Re: unintuitive for-loop behavior

2016-10-01 Thread Chris Angelico
On Sun, Oct 2, 2016 at 3:19 PM, Steve D'Aprano
 wrote:
> In IronPython, you could have the following occur in a function locals, just
> as it could happen CPython for globals:
>
> - delete the name binding "x"
> - which triggers a dictionary resize
> - bind a value to x again
> - because the dictionary is resized, the new "slot" for x is in a
>   completely different position of the dictionary to the old one
>
> There is no user-visible difference between these two situations. Your code
> works the same way whether it is executed inside a function or at the
> global top level, whether functions use the CPython local variable
> optimization or not.

Hmm, interesting. I don't have IronPython here, but maybe you can tell
me what this does:

print(str)
str = "demo"
print(str)
del str
print(str)

and the same inside a function. In CPython, the presence of 'str =
"demo"' makes str function-local, ergo UnboundLocalError on the first
reference; but globals quietly shadow built-ins, so this will print
the class, demo, and the class again. If IronPython locals behave the
way CPython globals behave, that would most definitely be a
user-visible change to shadowing semantics.

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


Re: inplace text filter - without writing file

2016-10-01 Thread Sayth Renshaw
On Sunday, 2 October 2016 12:14:43 UTC+11, MRAB  wrote:
> On 2016-10-02 01:21, Sayth Renshaw wrote:
> > Hi
> >
> > I have a fileobject which was fine however now I want to delete a line from 
> > the file object before yielding.
> >
> > def return_files(file_list):
> > for filename in sorted(file_list):
> 
> When joining paths together, it's better to use 'os.path.join'.
> 
> > with open(dir_path + filename) as fd:
> >  for fileItem in fd:
> >  yield fileItem
> >
> > Ned gave an answer over here http://stackoverflow.com/a/6985814/461887
> >
> > for i, line in enumerate(input_file):
> > if i == 0 or not line.startswith('#'):
> > output.write(line)
> >
> > which I would change because it is the first line and I want to rid 

Re: inplace text filter - without writing file

2016-10-01 Thread Sayth Renshaw
On Sunday, 2 October 2016 16:19:14 UTC+11, Sayth Renshaw  wrote:
> On Sunday, 2 October 2016 12:14:43 UTC+11, MRAB  wrote:
> > On 2016-10-02 01:21, Sayth Renshaw wrote:
> > > Hi
> > >
> > > I have a fileobject which was fine however now I want to delete a line 
> > > from the file object before yielding.
> > >
> > > def return_files(file_list):
> > > for filename in sorted(file_list):
> > 
> > When joining paths together, it's better to use 'os.path.join'.
> > 
> > > with open(dir_path + filename) as fd:
> > >  for fileItem in fd:
> > >  yield fileItem
> > >
> > > Ned gave an answer over here http://stackoverflow.com/a/6985814/461887
> > >
> > > for i, line in enumerate(input_file):
> > > if i == 0 or not line.startswith('#'):
> > > output.write(line)
> > >
> > > which I would change because it is the first line and I want to rid 

Re: Copying a compiled Python from one system to another

2016-10-01 Thread Paul Rubin
Steve D'Aprano  writes:
> Yes, this. You need gcc 4.8 or better to build CPython 3.6, and the most
> recent any of my systems support is 4.4.

Building gcc takes a while but it's reasonably simple.  Just start it
going and read a book for a while.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: unintuitive for-loop behavior

2016-10-01 Thread Rustom Mody
On Saturday, October 1, 2016 at 11:35:31 PM UTC+5:30, Steve D'Aprano wrote:
> On Sun, 2 Oct 2016 03:57 am, Rustom Mody wrote:
> 
> > Hoo boy1
> > Thats some tour de force and makes my head spin
> 
> I certainly agree with the second part of your sentence.
> 
> 
> > Point can be made more simply with map
> > ie if we *define*
> > [exp for cv in l]
> > as
> > map(lambda cv: exp, l)
> > 
> > the problem vanishes
> 
> > 
> > Demo:
> > 
> > First a helper function for demoing:
> > 
> > def pam(fl,x):
> > return map(lambda f: f(x), fl)
> > # pam is the complement to map; map runs one fnc on a list of args
> > # pam runs a list of funcs on one arg
> > 
> > Trying to make a list of functions that add one, two and three to their
> > arguments
> > 
> > fl = [lambda x: x + cv for cv in [1,2,3]]
> > 
> > Broken because of python's wrong LC semantics:
>  pam(fl, 3)
> > [6, 6, 6]
> 
> Its not *broken*, its doing *exactly what you told it to do*. You said,
> define a function that takes a single argument x, and return x + cv. Then
> you delayed evaluating it until cv = 3, and passed the argument 3, so of
> course it returns 6. That's exactly what you told it to calculate.
> 
> You seem to have the concept that lambda should be magical, and just
> miraculously know how far back in time to look for the value of cv. And
> then when it doesn't, you're angry that Python is "broken". But why should
> it be magical? cv is just an ordinary variable, and like all variables,
> looking it up returns the value it has at the time you do the look-up, not
> some time in the past. Let's unroll the loop:
> 
> fl = []
> cv = 1
> def f(x): return x + cv
> fl.append(f)
> cv = 2
> def f(x): return x + cv
> fl.append(f)
> cv = 3
> def f(x): return x + cv
> fl.append(f)
> 
> pam(fl, 3)
> 
> Are you still surprised that it returns [6, 6, 6]?
> 
You are explaining the mechanism behind the bug. Thanks. The bug remains.
My new car goes in reverse when I put it in first gear but only on full-moon 
nights with the tank on reserve when the left light is blinking
The engineer explains the interesting software bug in the new PCB.
Interesting. But the bug remains

Likewise here:

[2 ** i for i in[1,2]] == [2**1, 2**2]

yet this fails 

[lambda x: x + i for i in [1,2]] == [lambda x:x+1, lambda x:x=2]

is a bug for anyone including the OP of this thread

> 
> 
> 
> > Transform the LC into a map with the rule above:
> > fl_good = map((lambda cv :lambda x: x+cv), [1,2,3])
> 
> 
> This is equivalent to something completely different, using a closure over
> cv, so of course it works:
> 
> def factory(cv):
> def inner(x):
> return x + cv
> return inner
> 
> fl_good = []
> fl_good.append(factory(1))
> fl_good.append(factory(2))
> fl_good.append(factory(3))
> 
> 
> Each time you call factory(), you get a new scope, with its own independent
> variable cv. The inner function captures that environment (a closure),
> which includes that local variable cv. Each invocation of factory leads to
> an inner function that sees a different local variable which is independent
> of the others but happens to have the same name. Instead of three functions
> all looking up a single cv variable, you have three functions looking up
> three different cv variables.
> 
> This is essentially why closures exist.

Closures and lambdas are synonymous:
martin Fowler's article on lambda has this first sentence:

«a programming concept called Lambdas (also called Closures, Anonymous 
Functions or Blocks)»
http://martinfowler.com/bliki/Lambda.html

So if you like you can say the bug here is that python lambdas fail to close
variables properly.
Which is a double-bug because the blame for closure-failure is falling
onto the lambda whereas it is the comprehension semantics in terms of loops
rather than in terms of closures/cells as Jussi/Greg are trying to show, that
is at fault
> 
> 
> > Which is not very far from the standard workaround for this gotcha:
>  fl_workaround = [lambda x, cv=cv: x+cv for cv in [1,2,3]]
>  pam(fl_workaround, 3)
> > [4, 5, 6]
>  
> > 
> > Maybe we could say the workaround is the map definition uncurried
> > And then re-comprehension-ified
> 
> If your students think in terms of map, then fine, but I think it would
> confuse more people than it would help. Your mileage may vary.

You are as usual putting words in my mouth.
I did not talk of my students or that map is easier than comprehensions
I was taking the Haskell comprehension-semantics link (which BTW you posted!)
https://www.haskell.org/onlinereport/exps.html#sect3.11

Simplifying it to the simple case of only one for, no ifs
This allows the flatmap to become a map and the multiple cases to go
Thereby more succinctly highlighting the problem
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Merecurial and Python-2.7.x, Python-3.Y

2016-10-01 Thread Terry Reedy

On 10/1/2016 5:31 AM, Michael Felt wrote:

Finally, I got to where I understood what needed to be done to get both
Mercurial built - and the the new SSL requirements met.

So, running:

# hg clone https://hg.python.org/cpython

works. What is the next step to getting Python-2.7 AND Python-3.7 so I
can submit patches against both versions and/or other versions?


What OS?


Is it going to be a command like in the developer guide (that references
Python3.5)?


I use TortoiseHG on Windows and love it relative to command lines.


Does this create a new directory, or just undo a lot of things that was
just cloned - or was 3.5 the development branch when the guide was last
updated?

Will I need to clone (as above) several times - one for each version I
want to test against - and then run a second command -- OR --


I recommend one clone from hg.python.org and a share clone for each 
branch you care about linked to the master clone.  Details in the 
devguide.  But I don't know what will have to change when the repository 
is switched to git and gethup, perhaps next January.



is there an hg clone command to get a specific version (If that is in
the guide - my apologies, as I missed it.


No.  By default, the working directory for a clone is for the default 
branch.  Any clone can be 'updated' to any branch.  I have each share 
clone updated to a different branch, so I never update to a different 
branch.


--
Terry Jan Reedy

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


Re: unintuitive for-loop behavior

2016-10-01 Thread Jussi Piitulainen
Steve D'Aprano writes:

> On Sun, 2 Oct 2016 12:28 am, Jussi Piitulainen wrote:
>
>> I'm not sure any more to what message this should be a followup, but
>> here is a demonstration of two different semantics of the for-loop
>> variable scope/update, this time with nested loops using the same
>> loop variable name. The first function, tabulate, uses Python
>> semantics ("t" for true, if you like); the second, fabulate, is a
>> translation ("f" for false, if you like) that uses the magical
>> semantics where the loop variable is not only local to the loop but
>> also a different variable on each iteration.
>
> I'm sorry, I don't understand what you mean by "Python semantics" versus "a
> translation". A translation of what? In what way is it "magical semantics"?
> I see nothing magical in your code: it is Python code.

"Python semantics" is the semantics that Python actually uses when it
updated the variables of a for-loop. I would like to call it "assignment
semantics".

The second function is an executable translation of the first function
under a different semantics. I would like to call it "binding semantics"
to distinguish it from "assignment semantics", but that doesn't work
when people insist that "binding" and "assignment" are the same thing in
Python, so I called it "magical semantics" instead.

The method of using equivalent code as an explanation is known in Python
documentation, as in the explanation of list comprehensions in terms of
list.append and for-loops. This is what I called "translation" above. In
another community it might be called "syntactic transformation" or
"macro expansion".

> Of course, it is complex, complicated, convoluted, obfuscated, hard to
> understand, non-idiomatic Python code, but there's nothing magical in
> it (unless you count nonlocal as magic). And it does nothing that
> can't be done more simply: just change the tabulate inner loop
> variable to a different name.

It was stated, in this thread, that it would have been impossible to
make Python for-loops behave the way the corresponding Python code in my
translations of the two nested for-loops behaves. I thought it would be
a good idea to *show* how the "impossible" thing can be done.

I could have just posted that yes, it *could* be done, there's nothing
so special about variables and scope in Python. But I pretty much know
that the response to *that* would have been yet another round of "You
don't understand that Python variables are different, they are not boxes
in fixes locations but name bindings, and no, it cannot be done."

> def fabulate2(m, n):
> # The simple, Pythonic, non-complicated way.
> for i in range(m):
> print(i, end = ': ')
> c = 0
> for j in range(n):
> print(j, end = ', ' if j + 1 < n else ' : ')
> c += 1
> print(i, c)

It misses only the point of the exercise.

> Your version of tabulate and fabulate:
> py> tabulate(3, 4)
> 0: 0, 1, 2, 3 : 3 4
> 1: 0, 1, 2, 3 : 3 4
> 2: 0, 1, 2, 3 : 3 4
>
> py> fabulate(3, 4)
> 0: 0, 1, 2, 3 : 0 4
> 1: 0, 1, 2, 3 : 1 4
> 2: 0, 1, 2, 3 : 2 4
>
> My simple version of fabulate:
>
> py> fabulate2(3, 4)
> 0: 0, 1, 2, 3 : 0 4
> 1: 0, 1, 2, 3 : 1 4
> 2: 0, 1, 2, 3 : 2 4
>
>
>> The latter property makes no difference in this 
>> demonstration, but the former does; there's also a spurious counter that
>> is not local to the nested loops, just to be sure that it works as
>> expected (it does).
>> 
>> A summary of sorts: it's possible to demonstrate the scope difference in
>> Python code, with no box in sight; boxes are irrelevant; the relevant
>> issue is what function and when the loop variable is associated with,
>> explicitly or implicitly.
>
> I don't know what "scope difference" you think you are demonstrating.
> tabulate() has a single scope, fabulate() has multiple scopes because it
> has inner functions that take i as argument, making them local to the inner
> functions. Um, yeah, of course they are different. They're different
> because you've written them differently. What's your point?

The scope difference is the topic of this thread.

My point is that the for-loops could be translated/compiled/expanded
into the lower-level code so that the loop variables would be in their
own scopes.

> As far as I can see, all you have demonstrated is that it is possible to
> write obfuscated code in Python. But we already knew that.

The point is that the straightforward code *could* have the same meaning
as the "obfuscated" code. That for-loops *could* be magicking constructs
even in Python. (What word should I use instead of "magic"?)

The code might not seem so obfuscated to you if you thought of it not as
source code but as compiled code. Except it's still Python. What word
should I use instead of "translation"? Would "transformation" be
understood?
-- 
https://mail.python.org/mailman/listinfo/python-list