Re: Using pytest, sometimes does not capture stderr
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.
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.
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
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
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
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
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
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.
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
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.
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
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
> 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.
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.
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
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
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
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
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
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.
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.
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.
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.
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