Re: Using pytest, sometimes does not capture stderr

2021-04-05 Thread Peter Otten

On 05/04/2021 06:25, Cameron Simpson wrote:


If you truly need to test msg() _without_ the file= parameter, you could
monkey patch module_2:

 old_MSG_DESTINATION = module_2.MSG_DESTINATION
 module_2.MSG_DESTINATION = sys.stderr
 # now the module_2 module has an updated reference for sys.stderr
 ...
 msg("a", "message")
 ...
 module_2.MSG_DESTINATION = old_MSG_DESTINATION
 # normality restored


I was about to write "use contextlib.redirect_sterr()", and noted my
error just before hitting send. There is a tool in the stdlib that might
work though:

from unittest import mock

with mock.patch("module_2.MSG_DESTINATION", sys.stderr):
msg("a", "message")
--
https://mail.python.org/mailman/listinfo/python-list


Yield after the return in Python function.

2021-04-05 Thread Bischoop
The return suspends the function execution so how is it that in below
example I got output: 

def doit():
return 0
yield 0

print(doit())



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


Re: Yield after the return in Python function.

2021-04-05 Thread Frank Millman

On 2021-04-05 2:25 PM, Bischoop wrote:

The return suspends the function execution so how is it that in below
example I got output: 

def doit():
 return 0
 yield 0
 
print(doit())




The 'yield' in the function makes the function a 'generator' function.

'Calling' a generator function does not execute the function, it returns 
a generator object.


You have to iterate over the generator object (e.g. by calling next() on 
it) in order to execute the function and return values.


Frank Millman



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


Re: Friday Finking: initialising values and implied tuples

2021-04-05 Thread Rob Cliffe via Python-list



On 05/04/2021 00:47, dn via Python-list wrote:

On 04/04/2021 01.00, Rob Cliffe via Python-list wrote:


On 03/04/2021 04:09, 2qdxy4rzwzuui...@potatochowder.com wrote:

On 2021-04-03 at 02:41:59 +0100,
Rob Cliffe via Python-list  wrote:


  x1 = 42; y1 =  3;  z1 = 10
  x2 = 41; y2 = 12; z2 = 9
  x3 =  8;  y3 =  8;  z3 = 10
(please imagine it's in a fixed font with everything neatly vertically
aligned).
This has see-at-a-glance STRUCTURE: the letters are aligned vertically
and the "subscripts" horizontally.  Write it as 9 lines and it becomes
an amorphous mess in which mistakes are harder to spot.

I agree that writing it as 9 lines is an accident waiting to happen, but
if you must see that structure, then go all in:

  (x1, y1, z1) = (43,  3, 10)
  (x2, y2, z2) = (41, 12,  9)
  (x3, y3, z3) = ( 8,  8, 10)

Agreed, that is even easier to read.  (It would be kinda nice if the
compiler could optimise the tuples away, for those of us who are
paranoid about performance.)

I think I've read that the compiler is smart-enough to realise that the
RHS 'literal-tuples'?'tuple-literals' are being used as a 'mechanism',
and thus the inits are in-lined. Apologies: I can't find a web.ref.
Likely one of our colleagues, who is 'into' Python-internals, could
quickly clarify...
[snip]

It doesn't appear to, at least not always.  In Python 3.8.3:
from dis import dis
def f(): x = 1 ; y = 2
def g(): (x,y) = (1,2)
dis(f)
dis(g)

Output:
  2   0 LOAD_CONST   1 (1)
  2 STORE_FAST   0 (x)
  4 LOAD_CONST   2 (2)
  6 STORE_FAST   1 (y)
  8 LOAD_CONST   0 (None)
 10 RETURN_VALUE
  3   0 LOAD_CONST   1 ((1, 2))
  2 UNPACK_SEQUENCE  2
  4 STORE_FAST   0 (x)
  6 STORE_FAST   1 (y)
  8 LOAD_CONST   0 (None)
 10 RETURN_VALUE

Thinking some more about this, this (removing the tuples) is not a 
straightforward optimisation to do.

Example 1:
    (x, y) = (y, x)
is not the same as
    x = y ; y = x
Example 2:
    L[v], y = a, f()
is not the same as
    L[v] = a ; y = f()
if v is a global changed by f().
I guess it's safe if the RHS is a tuple containing only
    constants, by which I think I mean number/string literals and 
built-in constants (None, True etc.).
    variables (NOT expressions containing variables such as "z+1") 
which do not occur on the LHS
    tuple/list/dictionary/set displays which themselves contain only 
the above, or nested displays which themselves ... etc.
It appears (even though I use Windows where timing anything is a 
nightmare) that tuple versions are slightly slower.

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


Re: Friday Finking: initialising values and implied tuples

2021-04-05 Thread Chris Angelico
On Tue, Apr 6, 2021 at 2:32 AM Rob Cliffe via Python-list
 wrote:
>
>
>
> It doesn't appear to, at least not always.  In Python 3.8.3:
> from dis import dis
> def f(): x = 1 ; y = 2
> def g(): (x,y) = (1,2)
> dis(f)
> dis(g)
>
> Output:
>2   0 LOAD_CONST   1 (1)
>2 STORE_FAST   0 (x)
>4 LOAD_CONST   2 (2)
>6 STORE_FAST   1 (y)
>8 LOAD_CONST   0 (None)
>   10 RETURN_VALUE
>3   0 LOAD_CONST   1 ((1, 2))
>2 UNPACK_SEQUENCE  2
>4 STORE_FAST   0 (x)
>6 STORE_FAST   1 (y)
>8 LOAD_CONST   0 (None)
>   10 RETURN_VALUE
> Thinking some more about this, this (removing the tuples) is not a
> straightforward optimisation to do.

It's important to be aware of the semantics here. Saying "x = 1; y =
2" requires that x be set before 2 is calculated (imagine if it had
been "y = x + 2" or something), whereas "x, y = 1, 2" has to do the
opposite, fully evaluating the right hand side before doing any of the
assignments.

> I guess it's safe if the RHS is a tuple containing only
>  constants, by which I think I mean number/string literals and
> built-in constants (None, True etc.).
>  variables (NOT expressions containing variables such as "z+1")
> which do not occur on the LHS
>  tuple/list/dictionary/set displays which themselves contain only
> the above, or nested displays which themselves ... etc.

Nope, there's no "it's safe if" other than constants - which are
already handled differently. If there is ANY Python code executed to
calculate those values, it could depend on the previous assignments
being completed.

But the tuples aren't a problem here. They're a highly optimized way
of grabbing multiple things at once. In the "x, y = 1, 2" case, the
compiler would be free to implement it as "LOAD_CONST 1, LOAD_CONST 2,
ROT_TWO, STORE_FAST x, STORE_FAST y" (equivalent to what you'd see for
"x, y = y, x"), but it doesn't, so we can fairly confidently expect
that the tuple is faster.

BTW, if you want to play around with CPython's optimizations, there's
another case to consider:

def f(): x = y = 1
  1   0 LOAD_CONST   1 (1)
  2 DUP_TOP
  4 STORE_FAST   0 (x)
  6 STORE_FAST   1 (y)

The constant gets loaded once (which is semantically important), and
then duplicated on the stack, leaving two available for storing. Feel
free to play around with different combinations here. For instance,
"x, y = a, b = 1, 2" should now be unsurprising, but perhaps there'll
be some more complicated examples that are interesting to explore.

I love dis stuff. :)

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


Re: Friday Finking: initialising values and implied tuples

2021-04-05 Thread Rob Cliffe via Python-list



On 05/04/2021 17:52, Chris Angelico wrote:

On Tue, Apr 6, 2021 at 2:32 AM Rob Cliffe via Python-list
 wrote:



It doesn't appear to, at least not always.  In Python 3.8.3:
from dis import dis
def f(): x = 1 ; y = 2
def g(): (x,y) = (1,2)
dis(f)
dis(g)

Output:
2   0 LOAD_CONST   1 (1)
2 STORE_FAST   0 (x)
4 LOAD_CONST   2 (2)
6 STORE_FAST   1 (y)
8 LOAD_CONST   0 (None)
   10 RETURN_VALUE
3   0 LOAD_CONST   1 ((1, 2))
2 UNPACK_SEQUENCE  2
4 STORE_FAST   0 (x)
6 STORE_FAST   1 (y)
8 LOAD_CONST   0 (None)
   10 RETURN_VALUE
Thinking some more about this, this (removing the tuples) is not a
straightforward optimisation to do.

It's important to be aware of the semantics here. Saying "x = 1; y =
2" requires that x be set before 2 is calculated (imagine if it had
been "y = x + 2" or something), whereas "x, y = 1, 2" has to do the
opposite, fully evaluating the right hand side before doing any of the
assignments.


I guess it's safe if the RHS is a tuple containing only
  constants, by which I think I mean number/string literals and
built-in constants (None, True etc.).
  variables (NOT expressions containing variables such as "z+1")
which do not occur on the LHS
  tuple/list/dictionary/set displays which themselves contain only
the above, or nested displays which themselves ... etc.

Nope, there's no "it's safe if" other than constants - which are
already handled differently.
How are constants handled differently (apart from using LOAD_CONST)?  
See my dis example above.

  If there is ANY Python code executed to
calculate those values, it could depend on the previous assignments
being completed.

I don't understand.  What semantic difference could there be between
    x = { 1: 2 }    ;    y = [3, 4]   ;   z = (5, 6)
and
    x, y, z = { 1:2 }, [3, 4], (5, 6)
?  Why is it not safe to convert the latter to the former?
But I withdraw "set" from my "safe" list because I now realise that 
"set" could be reassigned.


But the tuples aren't a problem here. They're a highly optimized way
of grabbing multiple things at once. In the "x, y = 1, 2" case, the
compiler would be free to implement it as "LOAD_CONST 1, LOAD_CONST 2,
ROT_TWO, STORE_FAST x, STORE_FAST y" (equivalent to what you'd see for
"x, y = y, x"), but it doesn't, so we can fairly confidently expect
that the tuple is faster.

Not according to the Windows timings I mentioned in my previous post.


BTW, if you want to play around with CPython's optimizations, there's
another case to consider:

def f(): x = y = 1
   1   0 LOAD_CONST   1 (1)
   2 DUP_TOP
   4 STORE_FAST   0 (x)
   6 STORE_FAST   1 (y)

The constant gets loaded once (which is semantically important), and
then duplicated on the stack, leaving two available for storing. Feel
free to play around with different combinations here. For instance,
"x, y = a, b = 1, 2" should now be unsurprising, but perhaps there'll
be some more complicated examples that are interesting to explore.

I love dis stuff. :)

ChrisA

Best wishes
Rob Cliffe
--
https://mail.python.org/mailman/listinfo/python-list


Re: Friday Finking: initialising values and implied tuples

2021-04-05 Thread Rob Cliffe via Python-list



On 05/04/2021 17:52, Chris Angelico wrote:
I don't understand.  What semantic difference could there be between
    x = { 1: 2 }    ;    y = [3, 4]   ;   z = (5, 6)
and
    x, y, z = { 1:2 }, [3, 4], (5, 6)
?  Why is it not safe to convert the latter to the former?
But I withdraw "set" from my "safe" list because I now realise that 
"set" could be reassigned.


Correction: set literals like {7,8} should still be OK as far as I can see.
Rob Cliffe
--
https://mail.python.org/mailman/listinfo/python-list


Re: Friday Finking: initialising values and implied tuples

2021-04-05 Thread Chris Angelico
On Tue, Apr 6, 2021 at 3:26 AM Rob Cliffe via Python-list
 wrote:
>
>
>
> On 05/04/2021 17:52, Chris Angelico wrote:
> > On Tue, Apr 6, 2021 at 2:32 AM Rob Cliffe via Python-list
> >  wrote:
> >>
> >>
> >> It doesn't appear to, at least not always.  In Python 3.8.3:
> >> from dis import dis
> >> def f(): x = 1 ; y = 2
> >> def g(): (x,y) = (1,2)
> >> dis(f)
> >> dis(g)
> >>
> >> Output:
> >> 2   0 LOAD_CONST   1 (1)
> >> 2 STORE_FAST   0 (x)
> >> 4 LOAD_CONST   2 (2)
> >> 6 STORE_FAST   1 (y)
> >> 8 LOAD_CONST   0 (None)
> >>10 RETURN_VALUE
> >> 3   0 LOAD_CONST   1 ((1, 2))
> >> 2 UNPACK_SEQUENCE  2
> >> 4 STORE_FAST   0 (x)
> >> 6 STORE_FAST   1 (y)
> >> 8 LOAD_CONST   0 (None)
> >>10 RETURN_VALUE
> >> Thinking some more about this, this (removing the tuples) is not a
> >> straightforward optimisation to do.
> > It's important to be aware of the semantics here. Saying "x = 1; y =
> > 2" requires that x be set before 2 is calculated (imagine if it had
> > been "y = x + 2" or something), whereas "x, y = 1, 2" has to do the
> > opposite, fully evaluating the right hand side before doing any of the
> > assignments.
> >
> >> I guess it's safe if the RHS is a tuple containing only
> >>   constants, by which I think I mean number/string literals and
> >> built-in constants (None, True etc.).
> >>   variables (NOT expressions containing variables such as "z+1")
> >> which do not occur on the LHS
> >>   tuple/list/dictionary/set displays which themselves contain only
> >> the above, or nested displays which themselves ... etc.
> > Nope, there's no "it's safe if" other than constants - which are
> > already handled differently.
> How are constants handled differently (apart from using LOAD_CONST)?
> See my dis example above.
> >   If there is ANY Python code executed to
> > calculate those values, it could depend on the previous assignments
> > being completed.
> I don't understand.  What semantic difference could there be between
>  x = { 1: 2 };y = [3, 4]   ;   z = (5, 6)
> and
>  x, y, z = { 1:2 }, [3, 4], (5, 6)
> ?  Why is it not safe to convert the latter to the former?
> But I withdraw "set" from my "safe" list because I now realise that
> "set" could be reassigned.

Firstly, anything with any variable at all can involve a lookup, which
can trigger arbitrary code (so "variables which do not occur on the
LHS" is not sufficient). But in general, it's not safe to do too many
order-of-evaluation changes when it's not actual literals. The only
exception would be, as you put in this particular example,
list/dict/set display, but NOT the name "set" (so you can't make an
empty set this way). So basically, it's literals, and things that
people treat like literals; otherwise, the order of evaluation has to
be maintained.

One good way to get an idea for which non-literals are "likely to be
safe" (in scare quotes because, honestly, it's REALLY HARD to know
what's actually safe) would be to look at ast.literal_eval; if it
would accept the expression, it's quite probably safe. But even that
isn't actually a perfect indication:

>>> set = lambda: print("Wat")
>>> eval("set()")
Wat
>>> ast.literal_eval("set()")
set()

Generally, unless you can mathematically prove that there's absolutely
no way the result could possibly be different, it's best to maintain
the correct order of evaluation.

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


Re: Yield after the return in Python function.

2021-04-05 Thread Terry Reedy

On 4/5/2021 8:25 AM, Bischoop wrote:

The return suspends the function execution so how is it that in below
example I got output: 

def doit():
 return 0
 yield 0
 
print(doit())


*Any* use of 'yield' in a function makes the function a generator 
function.  This is a simple rule that any person, and just as important, 
any automated algorithm, can understand.  If there were a 'dead 
(unreachable) code' exception, a reader or compiler would have to 
analyze each use of 'yield' and decide whether it is reachable or not. 
And we would have to decide whether just 1 or all 'yield's had to be 
reachable.


In the following code, in 3.x, it is also clear that 'yield' is unreachable.

>>> def f():
if False:
yield 0
return 1

>>> f()


But 'False' could be a more complex and less obvious but still 
equivalent expression, such and 'a and  and not a'*.  Is 'log(a) = 
0' tautologically False?


*While 'a and not a' == False in logic, in Python it might raise 
NameError.  But that would still mean that it is never True, making 
'yield 0' still unreachable.


--
Terry Jan Reedy

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


error on os.open API

2021-04-05 Thread Rami Khaldi
 Hello,

It seems that the os.open API cannot distinguish between a permission error
and the fact that a directory cannot be opened like files.
The following script reproduces the scenario (tested on Python 3.8.2
(tags/v3.8.2:7b3ab59, Feb 25 2020, 22:45:29) [MSC v.1916 32 bit (Intel)] on
win32) :



*import osos.system('mkdir someDirectory')open("someDirectory")*


*Result:*



*Traceback (most recent call last):  File "", line 1, in
PermissionError: [Errno 13] Permission denied: 'someDirectory'*

Kind regards,
Rami Khaldi
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Yield after the return in Python function.

2021-04-05 Thread Chris Angelico
On Tue, Apr 6, 2021 at 3:46 AM Terry Reedy  wrote:
> *While 'a and not a' == False in logic, in Python it might raise
> NameError.  But that would still mean that it is never True, making
> 'yield 0' still unreachable.
>

And even just the lookup can have side effects, if your code is
pathologically stupid.

>>> class Wat(dict):
... def __missing__(self, key):
... global count
... count -= 1
... return count
...
>>> count = 2
>>> eval("print(a and not a)", Wat(print=print))
True

So Python can't afford to treat this as dead code.

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


Re: error on os.open API

2021-04-05 Thread Chris Angelico
On Tue, Apr 6, 2021 at 3:50 AM Rami Khaldi  wrote:
>
>  Hello,
>
> It seems that the os.open API cannot distinguish between a permission error
> and the fact that a directory cannot be opened like files.
> The following script reproduces the scenario (tested on Python 3.8.2
> (tags/v3.8.2:7b3ab59, Feb 25 2020, 22:45:29) [MSC v.1916 32 bit (Intel)] on
> win32) :
>
>
>
> *import osos.system('mkdir someDirectory')open("someDirectory")*
>
>
> *Result:*
>
>
>
> *Traceback (most recent call last):  File "", line 1, in
> PermissionError: [Errno 13] Permission denied: 'someDirectory'*
>

Is this the actual code? You're not using os.open() here, you're using
the built-in open() function. But also, it IS possible to open
directories:

>>> os.open(".", os.O_RDONLY)
3

Maybe you don't have permission to open that directory?

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


Re: error on os.open API

2021-04-05 Thread Marco Ippolito
> It seems that the os.open API cannot distinguish between a permission error
> and the fact that a directory cannot be opened like files.
> The following script reproduces the scenario (tested on Python 3.8.2
> (tags/v3.8.2:7b3ab59, Feb 25 2020, 22:45:29) [MSC v.1916 32 bit (Intel)] on
> win32) :
> 
> *import osos.system('mkdir someDirectory')open("someDirectory")*
> 
> *Result:*
> 
> *Traceback (most recent call last):  File "", line 1, in
> PermissionError: [Errno 13] Permission denied: 'someDirectory'*

It errors as expected for me:

```
Traceback (most recent call last):
  File "/tmp/throwaway.py", line 4, in 
open("someDirectory")
IsADirectoryError: [Errno 21] Is a directory: 'someDirectory'
```

Are you able to write a simple file instead?

```
import pathlib
pathlib.Path("throwaway.txt").write_text("Test successful")
```
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Yield after the return in Python function.

2021-04-05 Thread Terry Reedy

On 4/5/2021 1:53 PM, Chris Angelico wrote:

On Tue, Apr 6, 2021 at 3:46 AM Terry Reedy  wrote:

*While 'a and not a' == False in logic, in Python it might raise
NameError.  But that would still mean that it is never True, making
'yield 0' still unreachable.


When I wrote that, I knew I might be missing something else.


And even just the lookup can have side effects, if your code is
pathologically stupid.


Or pathologically clever.


class Wat(dict):

... def __missing__(self, key):
... global count
... count -= 1
... return count


'__missing__' is new since I learned Python.  I barely took note of its 
addition and have never used it.  Thanks for the example of what it can 
do.  One could also make it randomly return True or False.



count = 2
eval("print(a and not a)", Wat(print=print))

True

So Python can't afford to treat this as dead code.


This gets to the point that logic and math are usually atemporal or at 
least static (as in a frozen snapshot), while computing is dynamic.  In 
algebra, the canon is that all instances of a variable are replaced by 
the same value.


Python *could* do the same for expresssions: load 'a' (in this case) 
once into a register or stack slot and use that value consistently 
throughout the expression.  Replacing the eval with the following exec 
has the same effect.


exec("tem=a; print(tem and not tem)", Wat(print=print))
# print False

In this example, one could disable the binding with __setitem__ 
(resulting in printing 0), but python code cannot disable internal 
register or stack assignments.


--
Terry Jan Reedy

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


Re: Yield after the return in Python function.

2021-04-05 Thread Chris Angelico
On Tue, Apr 6, 2021 at 5:14 AM Terry Reedy  wrote:
>
> On 4/5/2021 1:53 PM, Chris Angelico wrote:
> > On Tue, Apr 6, 2021 at 3:46 AM Terry Reedy  wrote:
> >> *While 'a and not a' == False in logic, in Python it might raise
> >> NameError.  But that would still mean that it is never True, making
> >> 'yield 0' still unreachable.
>
> When I wrote that, I knew I might be missing something else.
>
> > And even just the lookup can have side effects, if your code is
> > pathologically stupid.
>
> Or pathologically clever.
>
>  class Wat(dict):
> > ... def __missing__(self, key):
> > ... global count
> > ... count -= 1
> > ... return count
>
> '__missing__' is new since I learned Python.  I barely took note of its
> addition and have never used it.  Thanks for the example of what it can
> do.  One could also make it randomly return True or False.

Yep. It could be done with a __getitem__ method instead; the point is
that simply looking up a simple name can have side effects and/or be
nondeterministic.

>  count = 2
>  eval("print(a and not a)", Wat(print=print))
> > True
> >
> > So Python can't afford to treat this as dead code.
>
> This gets to the point that logic and math are usually atemporal or at
> least static (as in a frozen snapshot), while computing is dynamic.  In
> algebra, the canon is that all instances of a variable are replaced by
> the same value.

Right - or rather, that in algebra, a "variable" is really a
placeholder for a single, specific value, which may perhaps be unknown
to us, but which has a very well-defined value.

(At least, that's the case with most values, and with a convergent
series. Things can break down a bit with a divergent series, but even
then, analytic continuation can sometimes give you a well-defined
value.)

> Python *could* do the same for expresssions: load 'a' (in this case)
> once into a register or stack slot and use that value consistently
> throughout the expression.  Replacing the eval with the following exec
> has the same effect.

True, but I think that this would be enough of a semantic change that
Python should be very VERY careful about doing it. A *programmer* can
choose to do this (and we see it sometimes as an optimization, since
global lookups can be a lot more costly), but the interpreter
shouldn't.

> exec("tem=a; print(tem and not tem)", Wat(print=print))
> # print False
>
> In this example, one could disable the binding with __setitem__
> (resulting in printing 0), but python code cannot disable internal
> register or stack assignments.
>

Indeed. That said, though, I think that any namespace in which
referencing the same simple name more than once produces this sort of
bizarre behaviour should be considered, well, unusual. NORMAL code
won't have to concern itself with this. But the language spec doesn't
require us to write normal code..

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


Re: Friday Finking: initialising values and implied tuples

2021-04-05 Thread Rob Cliffe via Python-list



On 05/04/2021 18:33, Chris Angelico wrote:


Firstly, anything with any variable at all can involve a lookup, which
can trigger arbitrary code (so "variables which do not occur on the
LHS" is not sufficient).
Interesting.  I was going to ask: How could you make a variable lookup 
trigger arbitrary code?
Then I saw your post in the "Yield after the return in Python function" 
thread.  (Took me a while to understand it.)  So I ask:
Can you make a variable lookup trigger arbitrary code, other than in 
code passed to eval/exec/compile?

TIA
Rob Cliffe
--
https://mail.python.org/mailman/listinfo/python-list


Re: Matplotlib scale

2021-04-05 Thread David Lowry-Duda
Hello,

> I've created a code to run a 2D mapping using matplotlib from a .csv 
> file.
> I've tried to set the maximum color (red) of the scale as 80% of the maximum 
> value and not as the maximum value of my .csv file.
> Does someone know how to modify that?

If I understand what you're trying to do, I think you might want to 
investigate `clim` and `set_clim`.

You can see more about this with `plt.clim?`, or 
https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.clim.html.

I didn't sit down to create an example data file to try this out 
explicitly, but if you still have trouble I could try to make a workable 
example.

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


Re: Friday Finking: initialising values and implied tuples

2021-04-05 Thread Chris Angelico
On Tue, Apr 6, 2021 at 5:36 AM Rob Cliffe via Python-list
 wrote:
>
>
>
> On 05/04/2021 18:33, Chris Angelico wrote:
> >
> > Firstly, anything with any variable at all can involve a lookup, which
> > can trigger arbitrary code (so "variables which do not occur on the
> > LHS" is not sufficient).
> Interesting.  I was going to ask: How could you make a variable lookup
> trigger arbitrary code?
> Then I saw your post in the "Yield after the return in Python function"
> thread.  (Took me a while to understand it.)  So I ask:
> Can you make a variable lookup trigger arbitrary code, other than in
> code passed to eval/exec/compile?

Hmm. When you're defining a class, the metaclass can set the namespace
dictionary, does that count?

class Wat(dict):
def __getitem__(self, name):
print("HEY! You're looking for %r!" % name)
return 42
def __setitem__(self, name, value):
print("Okay, I'm setting %r to %r." % (name, value))
# I'm totally not.
class WutFace(type):
@classmethod
def __prepare__(cls, name, bases):
return Wat()
class Gotcha(metaclass=WutFace):
a = b + 1

But for top-level code in a module, or for function locals, I'm not
sure of any way to do this. It might be possible to mess with
sys.modules[__name__] but the __dict__ attribute can't be changed, so
you might need to first subclass the module. In general, though, even
if you can't find an example of how to do it, you have to assume that
it could happen somewhere, some time.

(It might also be possible to mess with the builtins module, which
would effectively catch any name lookups that aren't resolved locally
or at module level. Again, not sure if that would count.)

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


Re: Matplotlib scale

2021-04-05 Thread Julien Hofmann
Le lundi 5 avril 2021 à 21:50:49 UTC+2, David Lowry-Duda a écrit :

Thank you for your response!
I just tried it but it doesn't make what I want.

Bassically, I would like to not put any color for every values above 0.8 times 
the maximum value (ie. 488).
Hence, the ''maximum'' color (ie. red) would correspond to 488 and not to 610 
as currently. 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Matplotlib scale

2021-04-05 Thread Thomas Jollans

On 04/04/2021 20:57, Julien Hofmann wrote:

Hi everyone,


I've created a code to run a 2D mapping using matplotlib from a .csv file.
I've tried to set the maximum color (red) of the scale as 80% of the maximum 
value and not as the maximum value of my .csv file.
Does someone know how to modify that?


Most (or all?) matplotlib functions and methods that take a cmap 
argument also take vmin and vmax arguments to specify the maximum and 
minimum values to assign colours to.


https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.contourf.html

So adding vmax=0.8*np.max(z) to your contourf() call should do the trick.

A couple of quick data visualisation tips:

1. if your colour map doesn't cover the full range of data, your colour 
bar should indicate this. Call fig.colorbar(, extend='max').


2. 'jet' is a *terrible* colour map and you should *never* use it. It 
distorts your data, making people see patterns that aren't there, and is 
all but useless in black & white printouts or to the colour-blind.


This seminal talk from 2015 explains why the default Matplotlib colour 
maps are what they are: https://www.youtube.com/watch?v=xAoljeRJ3lU



-- Thomas



I've tried different solution but it doesn't work.

Thanks

import os
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from matplotlib import colorbar, colors
import matplotlib.tri as tri
  
#os.chdir("C:/Users/Julien Hofmann/Desktop/Nano-indentation")

data = pd.read_csv("Cartographie.csv",sep=';')
  
nb_lignes=21

nb_colonnes=27
  
  
fig = plt.figure(figsize=(15,12))

ax = plt.subplot(1,1,1)
x=np.linspace(0,(data["x"][len(data["x"])-1]-data["x"][0])*1000,nb_colonnes)
y=np.linspace(0,(data["y"][len(data["y"])-1]-data["y"][0])*1000,nb_lignes)
X,Y=np.meshgrid(x,y)
  
  
z=np.array(data["Durete"])

triang = tri.Triangulation(data["x"], data["y"])
interpolator = tri.LinearTriInterpolator(triang, z)
Xi, Yi = np.meshgrid(x, y)
zi = interpolator(Xi, Yi)
cntr1 = ax.contourf(x, y, z.reshape(nb_lignes,nb_colonnes), levels=150, 
cmap="jet")
cbar = fig.colorbar(cntr1, ax=ax)
ax.axis('on')



--
Dr. Thomas Jollans

☎ +49 6201 8759879
✉ t...@tjol.eu

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


RE: Yield after the return in Python function.

2021-04-05 Thread Avi Gross via Python-list
Terry: ... '__missing__' is new since I learned Python ...

With so many new dunder variables added, I am wondering when some dunderhead
comes up with:

__mifflin__

The documented use paper is:

https://theoffice.fandom.com/wiki/Dunder_Mifflin_Paper_Company



-Original Message-
From: Python-list  On
Behalf Of Terry Reedy
Sent: Monday, April 5, 2021 3:01 PM
To: python-list@python.org
Subject: Re: Yield after the return in Python function.

On 4/5/2021 1:53 PM, Chris Angelico wrote:
> On Tue, Apr 6, 2021 at 3:46 AM Terry Reedy  wrote:
>> *While 'a and not a' == False in logic, in Python it might raise 
>> NameError.  But that would still mean that it is never True, making 
>> 'yield 0' still unreachable.

When I wrote that, I knew I might be missing something else.

> And even just the lookup can have side effects, if your code is 
> pathologically stupid.

Or pathologically clever.

 class Wat(dict):
> ... def __missing__(self, key):
> ... global count
> ... count -= 1
> ... return count

'__missing__' is new since I learned Python.  I barely took note of its
addition and have never used it.  Thanks for the example of what it can do.
One could also make it randomly return True or False.

 count = 2
 eval("print(a and not a)", Wat(print=print))
> True
> 
> So Python can't afford to treat this as dead code.

This gets to the point that logic and math are usually atemporal or at least
static (as in a frozen snapshot), while computing is dynamic.  In algebra,
the canon is that all instances of a variable are replaced by the same
value.

Python *could* do the same for expresssions: load 'a' (in this case) once
into a register or stack slot and use that value consistently throughout the
expression.  Replacing the eval with the following exec has the same effect.

exec("tem=a; print(tem and not tem)", Wat(print=print)) # print False

In this example, one could disable the binding with __setitem__ (resulting
in printing 0), but python code cannot disable internal register or stack
assignments.

--
Terry Jan Reedy

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

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


Re: Yield after the return in Python function.

2021-04-05 Thread Greg Ewing

On 6/04/21 4:02 am, Terry Reedy wrote:
*Any* use of 'yield' in a function makes the function a generator 
function.  ...  If there were a 'dead 
(unreachable) code' exception, a reader or compiler would have to 
analyze each use of 'yield' and decide whether it is reachable or not. 


It would also break existing code. An unreachable "yield" is
sometimes used as a way to get a generator that doesn't yield
anything.

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


Re: Yield after the return in Python function.

2021-04-05 Thread Dan Stromberg
On Mon, Apr 5, 2021 at 10:46 AM Terry Reedy  wrote:

> If there were a 'dead
> (unreachable) code' exception, a reader or compiler would have to
> analyze each use of 'yield' and decide whether it is reachable or not.
>

It's also subject to how hard the compiler feels like trying in any given
release.  Many compilers have simple unreachable code warnings.

But to do a 100% accurate job of yield detection would be equivalent to the
halting problem, which is a classic problem in computer science that cannot
be solved 100% accurately in finite time.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Yield after the return in Python function.

2021-04-05 Thread Terry Reedy

On 4/5/2021 3:32 PM, Chris Angelico wrote:


On Tue, Apr 6, 2021 at 5:14 AM Terry Reedy  wrote:

Python *could* do the same for expresssions: load 'a' (in this case)
once into a register or stack slot and use that value consistently
throughout the expression.  Replacing the eval with the following exec
has the same effect.


True, but I think that this would be enough of a semantic change that
Python should be very VERY careful about doing it.


I consider it beyond a possibility.


A *programmer* can
choose to do this (and we see it sometimes as an optimization, since
global lookups can be a lot more costly), but the interpreter
shouldn't.


Agreed.  My interest is in elucidating the different between math and 
computing.  The reason some prohibit rebinding bound names within a 
local context is to make code more like math.  But this example should 
that Python code can effectively rebind names 'invisibly'.


Side note: Since a loop is equivalent to a recursive tail call, I think 
rebinding once per loop should be considered to be consistent with 
no-rebinding.  When an compiler or interpreter re-writes tail recursion 
as while looping, the result is the same.  I don't believe in forcing 
people to take the detour of using recursion syntax, which for many is 
harder to write and understand.




exec("tem=a; print(tem and not tem)", Wat(print=print))
# print False

In this example, one could disable the binding with __setitem__
(resulting in printing 0), but python code cannot disable internal
register or stack assignments.



Indeed. That said, though, I think that any namespace in which
referencing the same simple name more than once produces this sort of
bizarre behaviour should be considered, well, unusual. NORMAL code
won't have to concern itself with this. But the language spec doesn't
require us to write normal code..


I believe in the freedom to write 'strange code'.  But my other interest 
is how to talk about Python and 'normal' code.


--
Terry Jan Reedy

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