Re: Is there a way to implement the ** operator on a custom object

2024-02-09 Thread Cameron Simpson via Python-list

On 09Feb2024 18:56, Left Right  wrote:

But, more to the point: extending collections.abc.Mapping may or may
not be possible in OP's case.


We don't yet know if that's what the OP had in mind yet, anyway.


Also, if you are doing this through inheritance, this seems really
convoluted: why not just inherit from dict? -- less methods to
implement, less stuff to import etc.


There's a rule of thumb that we _tend_ not to subclass the builtins; it 
certainly has its pitfalls to do with object creation/initialisation.  
That said, I have some classes which subclass dict, int, str and 
namedtuple.


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


Re: Is there a way to implement the ** operator on a custom object

2024-02-09 Thread Left Right via Python-list
> Looks like it can simply be done in Python, no tp_as_mapping needed.

It's not that it isn't needed. You've just shown a way to add it using
Python code.

But, more to the point: extending collections.abc.Mapping may or may
not be possible in OP's case.

Also, if you are doing this through inheritance, this seems really
convoluted: why not just inherit from dict? -- less methods to
implement, less stuff to import etc.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is there a way to implement the ** operator on a custom object

2024-02-09 Thread Roel Schroeven via Python-list

Left Right via Python-list schreef op 9/02/2024 om 17:09:

In order for the "splat" operator to work, the type of the object must
populate slot `tp_as_mapping` with a struct of this type:
https://docs.python.org/3/c-api/typeobj.html#c.PyMappingMethods and
have some non-null implementations of the methods this struct is
supposed to contain.

I can do this in C, but I cannot think of a way to do this in Python
proper.


Looks like it can simply be done in Python, no tp_as_mapping needed. I 
tried it like Alan Bawden suggested (sibling post of yours):


import random # just as an example
import time   # just as an example
from collections.abc import Mapping

class VirtualKwargs(Mapping):

    def __init__(self):
    self.fncs = {
    # Simple examples of functions with varying return values to be
    # called for each lookup, instead of fixed values.
    'time': time.time,
    'random': random.random,
    }

    def __len__(self):
    return len(self.fncs)

    def __iter__(self):
    return iter(self.fncs)

    def __getitem__(self, key):
    return self.fncs[key]()


def func(**kwargs):
    for k, v in kwargs.items():
    print(f'{k}: {v}')


obj = VirtualKwargs()
func(**obj)


Output (obviously changes every run):

time: 1707497521.175763
random: 0.6765831287385126

--

"Man had always assumed that he was more intelligent than dolphins because
he had achieved so much — the wheel, New York, wars and so on — whilst all
the dolphins had ever done was muck about in the water having a good time.
But conversely, the dolphins had always believed that they were far more
intelligent than man — for precisely the same reasons."
-- Douglas Adams

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


Re: Is there a way to implement the ** operator on a custom object

2024-02-09 Thread Left Right via Python-list
In order for the "splat" operator to work, the type of the object must
populate slot `tp_as_mapping` with a struct of this type:
https://docs.python.org/3/c-api/typeobj.html#c.PyMappingMethods and
have some non-null implementations of the methods this struct is
supposed to contain.

I can do this in C, but I cannot think of a way to do this in Python
proper. Defining all the methods mentioned in PyMappingMethods doesn't
seem to do it. You could try to research this further, and if, indeed
defining all the methods of PyMappingMethods on the Python side
doesn't produce an object that behaves like a proper mapping, you
could probably file a bug report for that.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Is there a way to implement the ** operator on a custom object

2024-02-09 Thread Alan Bawden via Python-list
Chris Angelico  writes:

   > On 08Feb2024 12:21, tony.fl...@btinternet.com  
wrote:
   > >I know that mappings by default support the ** operator, to unpack the
   > >mapping into key word arguments.
   > >
   > >Has it been considered implementing a dunder method for the **
   > >operator so you could unpack an object into a key word argument, and
   > >the developer could choose which keywords would be generated (or could
   > >even generate 'virtual' attributes).

   I presume this is more like:

   obj = SomeObject()
   func(**obj)

   ie making the object behave in a dict-like way. I can't remember how
   this is implemented, but you can create the necessary methods to have
   your object produce whatever it likes.

All you need to do is subclass collections.abc.Mapping, and
implement __len__, __iter__, and __getitem__.  Pretty easy.

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


Re: Is there a way to implement the ** operator on a custom object

2024-02-08 Thread Chris Angelico via Python-list
On Fri, 9 Feb 2024 at 17:03, Cameron Simpson via Python-list
 wrote:
>
> On 08Feb2024 12:21, tony.fl...@btinternet.com  
> wrote:
> >I know that mappings by default support the ** operator, to unpack the
> >mapping into key word arguments.
> >
> >Has it been considered implementing a dunder method for the **
> >operator so you could unpack an object into a key word argument, and
> >the developer could choose which keywords would be generated (or could
> >even generate 'virtual' attributes).
>
> Can you show us why you think that would look like in code?
>
> Note that Python already has `a ** b` to raise `a` to the power of `b`,
> and it has a bunder method `__pow__` which you can define.

I presume this is more like:

obj = SomeObject()
func(**obj)

ie making the object behave in a dict-like way. I can't remember how
this is implemented, but you can create the necessary methods to have
your object produce whatever it likes.

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


Re: Is there a way to implement the ** operator on a custom object

2024-02-08 Thread Cameron Simpson via Python-list

On 08Feb2024 12:21, tony.fl...@btinternet.com  wrote:
I know that mappings by default support the ** operator, to unpack the 
mapping into key word arguments.


Has it been considered implementing a dunder method for the ** 
operator so you could unpack an object into a key word argument, and 
the developer could choose which keywords would be generated (or could 
even generate 'virtual' attributes).


Can you show us why you think that would look like in code?

Note that Python already has `a ** b` to raise `a` to the power of `b`, 
and it has a bunder method `__pow__` which you can define.

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


Is there a way to implement the ** operator on a custom object

2024-02-08 Thread Tony Flury via Python-list
I know that mappings by default support the ** operator, to unpack the 
mapping into key word arguments.


Has it been considered implementing a dunder method for the ** operator 
so you could unpack an object into a key word argument, and the 
developer could choose which keywords would be generated (or could even 
generate 'virtual' attributes).


--
Anthony Flury
email : anthony.fl...@btinternet.com

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


RE: extend behaviour of assignment operator

2024-01-19 Thread AVI GROSS via Python-list
Guenther,

It is best not to suggest a drastic fix for a more limited problem.

As a general rule, many programming languages only have a pointer concept
even vaguely along the lines you want for garbage collection purposes. An
area of memory may have stored alongside it how many other things point at
it but not which ones. As long as it is decremented when a pointer leaves,
it works.

If you want to design objects that can store additional info when invoked
properly, go for it. No change to python would be needed. In your example,
you could create an object initialized by cube([10,1,1], "a") which now
might remember that something called "a" once pointed at it. But you then
have to figure out how to ensure than when "a" is deleted or reset or goes
out of the current environment, that things are properly updated.

I am not so sure how easy it would be to change the language so it pays
attention to what it is giving a pointer too and then goes and tells ...



-Original Message-
From: Python-list  On
Behalf Of Guenther Sohler via Python-list
Sent: Tuesday, January 9, 2024 2:15 AM
To: python-list@python.org
Subject: extend behaviour of assignment operator

Hi,

when i run this code

a = cube([10,1,1])
b = a

i'd like to extend the behaviour  of the assignment operator
a shall not only contain the cube, but  the cube shall also know which
variable name it
was assigned to, lately. I'd like to use that for improved user interaction.

effective code should be:

a=cube([10,1,1])
a.name='a'

b=a
b.name='b' # i am aware that a.name also changes


can decorators also be used with assignment operators ?

thank you for your hints
-- 
https://mail.python.org/mailman/listinfo/python-list

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


Re: extend behaviour of assignment operator

2024-01-10 Thread Dieter Maurer via Python-list
Guenther Sohler wrote at 2024-1-9 08:14 +0100:
>when i run this code
>
>a = cube([10,1,1])
>b = a
>
>i'd like to extend the behaviour  of the assignment operator
>a shall not only contain the cube, but  the cube shall also know which
>variable name it
>was assigned to, lately. I'd like to use that for improved user interaction.

`Acquisition` (--> `PyPI`) implements something similar.

It does not work for variables -- but for attribute access.
Look at the following code:

```
from Acquisition import Implicit

class AccessAwareContainer(Implicit):
  ...

class AccessAwareContent(Implicit):
 ...

container = AccessAwareContainer()
container.content = AccessAwareContent()
```

When you now assign `content = container.content`, then
`content` knows that it has been accessed via `container`.


If fact `content` is not a true `AccessAwareContent` instance
but a wrapper proxy for it. It mostly behaves like an
`AccessAwareContent` object but has additional information
(e.g. it knows the access parent).


It works via a special `__getattribute__` method, essentially
implemented by:

```
   def __getattribute__(self, k):
 v = super().__getattribute__(k)
 return v.__of__(self) if hasattr(v, "__of__") else v
```

Your use case could be implemented similarly (again not for variables
and all objects, but for special classes (and maybe special objects)).

Your `__getattribute__` could look like:
```
   def __getattribute__(self, k):
 v = super().__getattribute__(k)
 try:
   v.name = k
 except TypeError: pass
 return v
```
-- 
https://mail.python.org/mailman/listinfo/python-list


extend behaviour of assignment operator

2024-01-10 Thread Guenther Sohler via Python-list
Hi,

when i run this code

a = cube([10,1,1])
b = a

i'd like to extend the behaviour  of the assignment operator
a shall not only contain the cube, but  the cube shall also know which
variable name it
was assigned to, lately. I'd like to use that for improved user interaction.

effective code should be:

a=cube([10,1,1])
a.name='a'

b=a
b.name='b' # i am aware that a.name also changes


can decorators also be used with assignment operators ?

thank you for your hints
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: xor operator

2023-11-15 Thread Dom Grigonis via Python-list
In case someone is actually going to execute the code, there is a bug:

`set` need to be wrapped in `len` for criteria args.

> On 15 Nov 2023, at 20:13, Dom Grigonis  wrote:
> 
> 
> The specific situation was related to truth values and following out of that 
> my considerations regarding equivalent of all and any for counting `truths`.
> 
> So one of the specific examples:
> class Publisher:
> def __init__(self):
> self.subscribers = dict()
> 
> def subscribe(self, sub, criteria, agg=all):
> self.subscribers[sub] = (criteria, agg)
> 
> def publish(self, msg):
> for sub, criteria in self.subscribers.items():
> if criteria(msg):
> sub.handle(msg)
> 
> p = Publisher()
> p.subscribe(sub, lambda x: all(r > 3 for r in x.ratings))
> 
> # So what I needed is:
> p.subscribe(sub, lambda x: set(r > 3 for r in x.ratings) > 50)
> # Note, that elements might not necessarily be bool.
> # E.g. at least 51 non-empty pages
> p.subscribe(sub, lambda x: set(bool(p) for p in x.pages) > 50)
> # So the function:
> p.subscribe(sub, lambda x: xor_more_than(x.pages, 50)
> # would ideally deal with truth values too.
> The question is: can you construct a function? which:
> a) performs: lambda x: set(bool(el) for el in iterable) > n
> b) is in line with performance of python’s `all`
> 
> Then, as I said the case where one would need `set() == n` is hard to think 
> of, but it seems fairly probable to need `set() > n` and `set() < n`.
> 
> Regards,
> DG
> 
>> On 15 Nov 2023, at 19:16, Peter J. Holzer via Python-list 
>> mailto:python-list@python.org>> wrote:
>> 
>> On 2023-11-15 12:26:32 +0200, Dom Grigonis wrote:
>>> 
>>> Thank you,
>>> 
>>> 
>>> test2 = [True] * 100 + [False] * 2
>>> test2i = list(range(100))
>>> 
>>> %timeit len(set(test2i)) == 1   # 1.6 µs ± 63.6 ns per loop (mean ± std. 
>>> dev. of 7 runs, 1,000,000 loops each)
>>> %timeit all(test2)  # 386 ns ± 9.58 ns per loop (mean ± std. 
>>> dev. of 7 runs, 1,000,000 loops each)
>>> 
>>> test2s = set(test2i)
>>> %timeit len(test2s) == 1# 46.1 ns ± 1.65 ns per loop (mean ± std. 
>>> dev. of 7 runs, 10,000,000 loops each)
>>> 
>>> If you pre-convert to set it is obviously faster. However, set
>>> operation is most likely going to be part of the procedure. In which
>>> case it ends up to be significantly slower.
>> 
>> Obviously, if you convert a list to a set just to count the elements
>> it's going to be slow. My suggestion was to use the set *instead* of the
>> list. I don't know whether that's possible in your situation, because
>> you haven't told us anything about it. All I'm suggesting is taking a
>> step back and reconsider your choice of data structure.
>> 
>>hp
>> -- 
>>   _  | Peter J. Holzer| Story must make more sense than reality.
>> |_|_) ||
>> | |   | h...@hjp.at  |-- Charles Stross, 
>> "Creative writing
>> __/   | http://www.hjp.at/  |   challenge!"
>> -- 
>> https://mail.python.org/mailman/listinfo/python-list 
>> 
> 

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


Re: xor operator

2023-11-15 Thread Dom Grigonis via Python-list

The specific situation was related to truth values and following out of that my 
considerations regarding equivalent of all and any for counting `truths`.

So one of the specific examples:
class Publisher:
def __init__(self):
self.subscribers = dict()

def subscribe(self, sub, criteria, agg=all):
self.subscribers[sub] = (criteria, agg)

def publish(self, msg):
for sub, criteria in self.subscribers.items():
if criteria(msg):
sub.handle(msg)

p = Publisher()
p.subscribe(sub, lambda x: all(r > 3 for r in x.ratings))

# So what I needed is:
p.subscribe(sub, lambda x: set(r > 3 for r in x.ratings) > 50)
# Note, that elements might not necessarily be bool.
# E.g. at least 51 non-empty pages
p.subscribe(sub, lambda x: set(bool(p) for p in x.pages) > 50)
# So the function:
p.subscribe(sub, lambda x: xor_more_than(x.pages, 50)
# would ideally deal with truth values too.
The question is: can you construct a function? which:
a) performs: lambda x: set(bool(el) for el in iterable) > n
b) is in line with performance of python’s `all`

Then, as I said the case where one would need `set() == n` is hard to think of, 
but it seems fairly probable to need `set() > n` and `set() < n`.

Regards,
DG

> On 15 Nov 2023, at 19:16, Peter J. Holzer via Python-list 
>  wrote:
> 
> On 2023-11-15 12:26:32 +0200, Dom Grigonis wrote:
>> 
>> Thank you,
>> 
>> 
>> test2 = [True] * 100 + [False] * 2
>> test2i = list(range(100))
>> 
>> %timeit len(set(test2i)) == 1   # 1.6 µs ± 63.6 ns per loop (mean ± std. 
>> dev. of 7 runs, 1,000,000 loops each)
>> %timeit all(test2)  # 386 ns ± 9.58 ns per loop (mean ± std. 
>> dev. of 7 runs, 1,000,000 loops each)
>> 
>> test2s = set(test2i)
>> %timeit len(test2s) == 1# 46.1 ns ± 1.65 ns per loop (mean ± std. 
>> dev. of 7 runs, 10,000,000 loops each)
>> 
>> If you pre-convert to set it is obviously faster. However, set
>> operation is most likely going to be part of the procedure. In which
>> case it ends up to be significantly slower.
> 
> Obviously, if you convert a list to a set just to count the elements
> it's going to be slow. My suggestion was to use the set *instead* of the
> list. I don't know whether that's possible in your situation, because
> you haven't told us anything about it. All I'm suggesting is taking a
> step back and reconsider your choice of data structure.
> 
>hp
> -- 
>   _  | Peter J. Holzer| Story must make more sense than reality.
> |_|_) ||
> | |   | h...@hjp.at |-- Charles Stross, "Creative writing
> __/   | http://www.hjp.at/ |   challenge!"
> -- 
> https://mail.python.org/mailman/listinfo/python-list

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


Re: xor operator

2023-11-15 Thread Peter J. Holzer via Python-list
On 2023-11-15 12:26:32 +0200, Dom Grigonis wrote:
> 
> Thank you,
> 
> 
> test2 = [True] * 100 + [False] * 2
> test2i = list(range(100))
> 
> %timeit len(set(test2i)) == 1   # 1.6 µs ± 63.6 ns per loop (mean ± std. dev. 
> of 7 runs, 1,000,000 loops each)
> %timeit all(test2)  # 386 ns ± 9.58 ns per loop (mean ± std. dev. 
> of 7 runs, 1,000,000 loops each)
> 
> test2s = set(test2i)
> %timeit len(test2s) == 1# 46.1 ns ± 1.65 ns per loop (mean ± std. 
> dev. of 7 runs, 10,000,000 loops each)
> 
> If you pre-convert to set it is obviously faster. However, set
> operation is most likely going to be part of the procedure. In which
> case it ends up to be significantly slower.

Obviously, if you convert a list to a set just to count the elements
it's going to be slow. My suggestion was to use the set *instead* of the
list. I don't know whether that's possible in your situation, because
you haven't told us anything about it. All I'm suggesting is taking a
step back and reconsider your choice of data structure.

hp
-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: xor operator

2023-11-15 Thread Dom Grigonis via Python-list
Thank you,

test2 = [True] * 100 + [False] * 2
test2i = list(range(100))

%timeit len(set(test2i)) == 1   # 1.6 µs ± 63.6 ns per loop (mean ± std. dev. 
of 7 runs, 1,000,000 loops each)
%timeit all(test2)  # 386 ns ± 9.58 ns per loop (mean ± std. dev. 
of 7 runs, 1,000,000 loops each)

test2s = set(test2i)
%timeit len(test2s) == 1# 46.1 ns ± 1.65 ns per loop (mean ± std. dev. 
of 7 runs, 10,000,000 loops each)
If you pre-convert to set it is obviously faster. However, set operation is 
most likely going to be part of the procedure. In which case it ends up to be 
significantly slower.

Regards,
DG


> On 15 Nov 2023, at 02:34, Peter J. Holzer via Python-list 
>  wrote:
> 
> On 2023-11-14 00:11:30 +0200, Dom Grigonis via Python-list wrote:
>> Benchmarks:
>> test1 = [False] * 100 + [True] * 2
>> test2 = [True] * 100 + [False] * 2
>> 
>> TIMER.repeat([
>>lambda: xor(test1), # 0.0168
>>lambda: xor(test2), # 0.0172
>>lambda: xor_ss(test1),  # 0.1392
>>lambda: xor_ss(test2),  # 0.0084
>>lambda: xor_new(test1), # 0.0116
>>lambda: xor_new(test2), # 0.0074
>>lambda: all(test1), # 0.0016
>>lambda: all(test2)  # 0.0046
>> ])
>> Your first function is fairly slow.
>> Second one deals with short-circuiting, but is super slow on full search.
>> 
>> `xor_new` is the best what I could achieve using python builtins.
>> 
>> But builtin `all` has the best performance.
> 
> One question worth asking is if a list of bool is the best data
> structure for the job. This is essentially a bitmap, and a bitmap is
> equivalent to a set of integers. len(s) == 1 is also a fairly quick
> operation if s is small. On my system, len(test1s) == 1 (where test1s is
> {100, 101}) is about as fast as all(test1) and len(test2s) == 1 (where
> test2s is set(range(100))) is about twice as fast as all(test2).
> 
> If you are willing to stray from the standard library, you could e.g.
> use pyroaring instead of sets: This is about as fast as all(test1)
> whether there are two bits set or a hundred.
> 
>hp
> 
> -- 
>   _  | Peter J. Holzer| Story must make more sense than reality.
> |_|_) ||
> | |   | h...@hjp.at  |-- Charles Stross, 
> "Creative writing
> __/   | http://www.hjp.at/  |   challenge!"
> -- 
> https://mail.python.org/mailman/listinfo/python-list 
> 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: xor operator

2023-11-14 Thread Peter J. Holzer via Python-list
On 2023-11-14 00:11:30 +0200, Dom Grigonis via Python-list wrote:
> Benchmarks:
> test1 = [False] * 100 + [True] * 2
> test2 = [True] * 100 + [False] * 2
> 
> TIMER.repeat([
> lambda: xor(test1), # 0.0168
> lambda: xor(test2), # 0.0172
> lambda: xor_ss(test1),  # 0.1392
> lambda: xor_ss(test2),  # 0.0084
> lambda: xor_new(test1), # 0.0116
> lambda: xor_new(test2), # 0.0074
> lambda: all(test1), # 0.0016
> lambda: all(test2)  # 0.0046
> ])
> Your first function is fairly slow.
> Second one deals with short-circuiting, but is super slow on full search.
> 
> `xor_new` is the best what I could achieve using python builtins.
> 
> But builtin `all` has the best performance.

One question worth asking is if a list of bool is the best data
structure for the job. This is essentially a bitmap, and a bitmap is
equivalent to a set of integers. len(s) == 1 is also a fairly quick
operation if s is small. On my system, len(test1s) == 1 (where test1s is
{100, 101}) is about as fast as all(test1) and len(test2s) == 1 (where
test2s is set(range(100))) is about twice as fast as all(test2).

If you are willing to stray from the standard library, you could e.g.
use pyroaring instead of sets: This is about as fast as all(test1)
whether there are two bits set or a hundred.

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: xor operator (DEPRECATED)

2023-11-13 Thread Dom Grigonis via Python-list
Thank you, I have spent a fair bit of time on these and found optimal solutions 
(at least I think so), but they are still multiple times slower than python 
builtin function.

I am currently out of ideas, maybe will dig something out in time.

> On 14 Nov 2023, at 07:23, Thomas Passin via Python-list 
>  wrote:
> 
> On 11/13/2023 11:44 PM, AVI GROSS via Python-list wrote:
>> Dom,
>> I hear you.
>> As you say, writing your own extension in something like C++ may not appeal 
>> to you even if it is faster.
>> I was wondering if using a generator or something similar in R might make 
>> sense.
>> I mean what happens if you write a function that includes a "yield" or two 
>> and does a part of what you want. It maintains some internal state between 
>> invocations. So you can call it once to setup things then call it repeatedly 
>> to keep processing the next item. You stop calling it when you get a result 
>> you want, such as that it has seen what you want N times.
>> Since the code stays in memory, it may effectively run faster than some 
>> other kinds of functions calls. It can keep things in internal storage such 
>> as not just how many N you want but how many it has seen.
> 
> I'm inclined to just turn the iterable into a set to get the values, then 
> iterate through those values calling count() on a listified version of the 
> iterable. If the count >= target, return.
> 
> It may not be the fastest one could do but it's simple and probably pretty 
> fast for many uses.  I suppose that for some iterables it would be better not 
> to turn them into lists, but one could figure out about that after working 
> out more carefully what cases need to be covered.
> 
>> Your outer function can maintain a list of the items you want to XOR or 
>> generate a new one dynamically as needed. It can use functional programming 
>> techniques to create a new customized version of the iterator, such as with 
>> a value of N built in. You would then call the outer function and let it use 
>> the inner function till the result is available or until the data in the 
>> iterator runs out or perhaps other tweaks involving two way communication of 
>> sorts between the functions.
>> I am NOT suggesting this approach is optimal or fast but merely wondering if 
>> something along these lines is worth trying that might speed things up even 
>> if not very fast. Such approaches can be even more effective if what you are 
>> working on need not all be instantiated up front but can be dynamically 
>> calculated or incrementally read from files. With care, you can make 
>> multiple instantiations that each iterate over their own sets of data 
>> without interference.
>> Just a thought. In a sense, this can be a slightly decent substitute for the 
>> non-standard evaluation in R where you can arrange for lots of your data to 
>> not be interpreted till absolutely needed.
>> -Original Message-
>> From: Dom Grigonis 
>> Sent: Monday, November 13, 2023 10:12 PM
>> To: avi.e.gr...@gmail.com
>> Cc: Grant Edwards ; Python 
>> 
>> Subject: Re: xor operator (DEPRECATED)
>> Fair point. However, I gave it a shot for the following reason:
>> I couldn’t find a way to make such performant function. Using python builtin 
>> components still ends up several times slower than builtin `all`. Cython or 
>> numba or similar is not an option as they do not support `truth` values. Or 
>> if they do, it ends up slower than pure python variant.
>> So all what is left is writing a proper extension. Which I would prefer not 
>> to do for 1 function. I thought maybe `xor`, as in logical XOR functionality 
>> in its vanilla case could be compelling. And after doing a bit of search I 
>> see that very very few languages have that and it seems for a good reason.
>> Some that do: R, thats all I could find. Although some (if not many) went 
>> through the proposal phase. And yes, none of them have a function that I am 
>> proposing.
>> So yes, you are right, not a good proposal.
>> But there still seems to be the need for short-circuiting performant 
>> implementations in python space. The issue is that there are many variants 
>> of what might be needed while there is no efficient solution to sourcing 
>> predicates from python to lower level implementations. Someone mentioned 
>> that numpy experimented with such implementations in C, but they did not get 
>> anywhere with it.
>> The best I could come up with is cached numba for numpy problems, which does 
>> perform very well and more than worth it if function is re-used. It even 
>&g

Re: xor operator (DEPRECATED)

2023-11-13 Thread Thomas Passin via Python-list

On 11/13/2023 11:44 PM, AVI GROSS via Python-list wrote:

Dom,

I hear you.

As you say, writing your own extension in something like C++ may not appeal to 
you even if it is faster.

I was wondering if using a generator or something similar in R might make sense.

I mean what happens if you write a function that includes a "yield" or two and 
does a part of what you want. It maintains some internal state between invocations. So 
you can call it once to setup things then call it repeatedly to keep processing the next 
item. You stop calling it when you get a result you want, such as that it has seen what 
you want N times.

Since the code stays in memory, it may effectively run faster than some other 
kinds of functions calls. It can keep things in internal storage such as not 
just how many N you want but how many it has seen.


I'm inclined to just turn the iterable into a set to get the values, 
then iterate through those values calling count() on a listified version 
of the iterable. If the count >= target, return.


It may not be the fastest one could do but it's simple and probably 
pretty fast for many uses.  I suppose that for some iterables it would 
be better not to turn them into lists, but one could figure out about 
that after working out more carefully what cases need to be covered.



Your outer function can maintain a list of the items you want to XOR or 
generate a new one dynamically as needed. It can use functional programming 
techniques to create a new customized version of the iterator, such as with a 
value of N built in. You would then call the outer function and let it use the 
inner function till the result is available or until the data in the iterator 
runs out or perhaps other tweaks involving two way communication of sorts 
between the functions.

I am NOT suggesting this approach is optimal or fast but merely wondering if 
something along these lines is worth trying that might speed things up even if 
not very fast. Such approaches can be even more effective if what you are 
working on need not all be instantiated up front but can be dynamically 
calculated or incrementally read from files. With care, you can make multiple 
instantiations that each iterate over their own sets of data without 
interference.

Just a thought. In a sense, this can be a slightly decent substitute for the 
non-standard evaluation in R where you can arrange for lots of your data to not 
be interpreted till absolutely needed.



-Original Message-
From: Dom Grigonis 
Sent: Monday, November 13, 2023 10:12 PM
To: avi.e.gr...@gmail.com
Cc: Grant Edwards ; Python 
Subject: Re: xor operator (DEPRECATED)

Fair point. However, I gave it a shot for the following reason:

I couldn’t find a way to make such performant function. Using python builtin 
components still ends up several times slower than builtin `all`. Cython or 
numba or similar is not an option as they do not support `truth` values. Or if 
they do, it ends up slower than pure python variant.

So all what is left is writing a proper extension. Which I would prefer not to 
do for 1 function. I thought maybe `xor`, as in logical XOR functionality in 
its vanilla case could be compelling. And after doing a bit of search I see 
that very very few languages have that and it seems for a good reason.

Some that do: R, thats all I could find. Although some (if not many) went 
through the proposal phase. And yes, none of them have a function that I am 
proposing.

So yes, you are right, not a good proposal.

But there still seems to be the need for short-circuiting performant 
implementations in python space. The issue is that there are many variants of 
what might be needed while there is no efficient solution to sourcing 
predicates from python to lower level implementations. Someone mentioned that 
numpy experimented with such implementations in C, but they did not get 
anywhere with it.

The best I could come up with is cached numba for numpy problems, which does 
perform very well and more than worth it if function is re-used. It even ends 
up faster than cython or cffi extensions, however can’t have many of those due 
to JIT and AOT is currently being deprecated (which wouldn’t solve anything 
anyway). However, as I mentioned earlier it does not apply to this case.

So it’s either:
a) Something very clever and flexible implemented that covers most of such 
needs and doesn’t require predicates.
b) I welcome any thoughts on this.

DG


On 14 Nov 2023, at 04:27, AVI GROSS via Python-list  
wrote:

I was going to ask a dumb question. Has any other language you know of made
something available that does what is being asked for and included it in the
main program environment rather than an add-on?

A secondary mention here has been whether short-circuiting functions like
"any" and "all" have been augmented with something like "has_n" that
evaluates arguments till it has found n or perhaps n+1 of 

RE: xor operator (DEPRECATED)

2023-11-13 Thread AVI GROSS via Python-list
Dom,

I hear you.

As you say, writing your own extension in something like C++ may not appeal to 
you even if it is faster.

I was wondering if using a generator or something similar in R might make sense.

I mean what happens if you write a function that includes a "yield" or two and 
does a part of what you want. It maintains some internal state between 
invocations. So you can call it once to setup things then call it repeatedly to 
keep processing the next item. You stop calling it when you get a result you 
want, such as that it has seen what you want N times.

Since the code stays in memory, it may effectively run faster than some other 
kinds of functions calls. It can keep things in internal storage such as not 
just how many N you want but how many it has seen.

Your outer function can maintain a list of the items you want to XOR or 
generate a new one dynamically as needed. It can use functional programming 
techniques to create a new customized version of the iterator, such as with a 
value of N built in. You would then call the outer function and let it use the 
inner function till the result is available or until the data in the iterator 
runs out or perhaps other tweaks involving two way communication of sorts 
between the functions.

I am NOT suggesting this approach is optimal or fast but merely wondering if 
something along these lines is worth trying that might speed things up even if 
not very fast. Such approaches can be even more effective if what you are 
working on need not all be instantiated up front but can be dynamically 
calculated or incrementally read from files. With care, you can make multiple 
instantiations that each iterate over their own sets of data without 
interference.

Just a thought. In a sense, this can be a slightly decent substitute for the 
non-standard evaluation in R where you can arrange for lots of your data to not 
be interpreted till absolutely needed.



-Original Message-
From: Dom Grigonis  
Sent: Monday, November 13, 2023 10:12 PM
To: avi.e.gr...@gmail.com
Cc: Grant Edwards ; Python 
Subject: Re: xor operator (DEPRECATED)

Fair point. However, I gave it a shot for the following reason:

I couldn’t find a way to make such performant function. Using python builtin 
components still ends up several times slower than builtin `all`. Cython or 
numba or similar is not an option as they do not support `truth` values. Or if 
they do, it ends up slower than pure python variant.

So all what is left is writing a proper extension. Which I would prefer not to 
do for 1 function. I thought maybe `xor`, as in logical XOR functionality in 
its vanilla case could be compelling. And after doing a bit of search I see 
that very very few languages have that and it seems for a good reason.

Some that do: R, thats all I could find. Although some (if not many) went 
through the proposal phase. And yes, none of them have a function that I am 
proposing.

So yes, you are right, not a good proposal.

But there still seems to be the need for short-circuiting performant 
implementations in python space. The issue is that there are many variants of 
what might be needed while there is no efficient solution to sourcing 
predicates from python to lower level implementations. Someone mentioned that 
numpy experimented with such implementations in C, but they did not get 
anywhere with it.

The best I could come up with is cached numba for numpy problems, which does 
perform very well and more than worth it if function is re-used. It even ends 
up faster than cython or cffi extensions, however can’t have many of those due 
to JIT and AOT is currently being deprecated (which wouldn’t solve anything 
anyway). However, as I mentioned earlier it does not apply to this case.

So it’s either:
a) Something very clever and flexible implemented that covers most of such 
needs and doesn’t require predicates.
b) I welcome any thoughts on this.

DG

> On 14 Nov 2023, at 04:27, AVI GROSS via Python-list  
> wrote:
> 
> I was going to ask a dumb question. Has any other language you know of made
> something available that does what is being asked for and included it in the
> main program environment rather than an add-on?
> 
> A secondary mention here has been whether short-circuiting functions like
> "any" and "all" have been augmented with something like "has_n" that
> evaluates arguments till it has found n or perhaps n+1 of what it wants then
> skips the rest. Does any language supply something like that? What would
> such a function return and does it have an "any" or an "all" side?
> 
> It sounds like if I asked if a list of integers has at least n prime numbers
> in "any" mode, it should ignore any that are not primes till it finds n
> primes or fails and returns true or false. If in "all" mode, I assume it
> would have to be the first n items without

Re: xor operator (DEPRECATED)

2023-11-13 Thread Dom Grigonis via Python-list
Fair point. However, I gave it a shot for the following reason:

I couldn’t find a way to make such performant function. Using python builtin 
components still ends up several times slower than builtin `all`. Cython or 
numba or similar is not an option as they do not support `truth` values. Or if 
they do, it ends up slower than pure python variant.

So all what is left is writing a proper extension. Which I would prefer not to 
do for 1 function. I thought maybe `xor`, as in logical XOR functionality in 
its vanilla case could be compelling. And after doing a bit of search I see 
that very very few languages have that and it seems for a good reason.

Some that do: R, thats all I could find. Although some (if not many) went 
through the proposal phase. And yes, none of them have a function that I am 
proposing.

So yes, you are right, not a good proposal.

But there still seems to be the need for short-circuiting performant 
implementations in python space. The issue is that there are many variants of 
what might be needed while there is no efficient solution to sourcing 
predicates from python to lower level implementations. Someone mentioned that 
numpy experimented with such implementations in C, but they did not get 
anywhere with it.

The best I could come up with is cached numba for numpy problems, which does 
perform very well and more than worth it if function is re-used. It even ends 
up faster than cython or cffi extensions, however can’t have many of those due 
to JIT and AOT is currently being deprecated (which wouldn’t solve anything 
anyway). However, as I mentioned earlier it does not apply to this case.

So it’s either:
a) Something very clever and flexible implemented that covers most of such 
needs and doesn’t require predicates.
b) I welcome any thoughts on this.

DG

> On 14 Nov 2023, at 04:27, AVI GROSS via Python-list  
> wrote:
> 
> I was going to ask a dumb question. Has any other language you know of made
> something available that does what is being asked for and included it in the
> main program environment rather than an add-on?
> 
> A secondary mention here has been whether short-circuiting functions like
> "any" and "all" have been augmented with something like "has_n" that
> evaluates arguments till it has found n or perhaps n+1 of what it wants then
> skips the rest. Does any language supply something like that? What would
> such a function return and does it have an "any" or an "all" side?
> 
> It sounds like if I asked if a list of integers has at least n prime numbers
> in "any" mode, it should ignore any that are not primes till it finds n
> primes or fails and returns true or false. If in "all" mode, I assume it
> would have to be the first n items without a failure.
> 
> Fine, but then someone may want to know WHERE you stopped or for you to
> return the sublist of the ones that made the match, or even return
> everything that was skipped so you can later process that. Consider a long
> list of jurors you process to place a dozen that qualify on a jury and then
> later you want to choose from among the rest for another jury.
> 
> Human minds can come up with an amazing number of ideas including for
> "useful" functions or features but I find the vast majority would rarely be
> used as nobody remembers it is available and some fairly simple method using
> other functions can easily be cobbled together.
> 
> -Original Message-
> From: Python-list  On
> Behalf Of Grant Edwards via Python-list
> Sent: Monday, November 13, 2023 8:19 PM
> To: python-list@python.org
> Subject: Re: xor operator
> 
> On 2023-11-14, Dom Grigonis via Python-list  wrote:
>> 
>>> Except the 'any' and 'all' builtins are _exactly_ the same as bitwise
>>> or and and applided to many bits. To do something "in line" with that
>>> using the 'xor' operator would return True for an odd number of True
>>> values and False for an even Number of True values.
>> 
>> Fair point.
>> 
>> Have you ever encountered the need for xor for many bits (the one
>> that I am NOT referring to)? Would be interested in what sort of
>> case it could be useful.
> 
> Yes, it's used all the time in low-level communications protocols,
> where it's often implemented in hardware. But, it is also not at all
> unusual to implement it in software.
> 
> It's also not that unusual for the "count-ones" part of the function
> you're asking for to be implemented in hardware by a CPU having an
> instruction that counts the number of 1 bits in a register.
> 
> GCC has a low-level builtins called __builtin_popcount() and
> __builtin-popcountl() that counts the number of 1's in an unsigned
> (long) int.
> 
> 
> -- 
> https://mail.python.org/mailman/listinfo/python-list
> 
> -- 
> https://mail.python.org/mailman/listinfo/python-list

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


RE: xor operator

2023-11-13 Thread AVI GROSS via Python-list
I was going to ask a dumb question. Has any other language you know of made
something available that does what is being asked for and included it in the
main program environment rather than an add-on?

A secondary mention here has been whether short-circuiting functions like
"any" and "all" have been augmented with something like "has_n" that
evaluates arguments till it has found n or perhaps n+1 of what it wants then
skips the rest. Does any language supply something like that? What would
such a function return and does it have an "any" or an "all" side?

It sounds like if I asked if a list of integers has at least n prime numbers
in "any" mode, it should ignore any that are not primes till it finds n
primes or fails and returns true or false. If in "all" mode, I assume it
would have to be the first n items without a failure.

Fine, but then someone may want to know WHERE you stopped or for you to
return the sublist of the ones that made the match, or even return
everything that was skipped so you can later process that. Consider a long
list of jurors you process to place a dozen that qualify on a jury and then
later you want to choose from among the rest for another jury.

Human minds can come up with an amazing number of ideas including for
"useful" functions or features but I find the vast majority would rarely be
used as nobody remembers it is available and some fairly simple method using
other functions can easily be cobbled together.

-Original Message-
From: Python-list  On
Behalf Of Grant Edwards via Python-list
Sent: Monday, November 13, 2023 8:19 PM
To: python-list@python.org
Subject: Re: xor operator

On 2023-11-14, Dom Grigonis via Python-list  wrote:
>
>> Except the 'any' and 'all' builtins are _exactly_ the same as bitwise
>> or and and applided to many bits. To do something "in line" with that
>> using the 'xor' operator would return True for an odd number of True
>> values and False for an even Number of True values.
>
> Fair point.
>
> Have you ever encountered the need for xor for many bits (the one
> that I am NOT referring to)? Would be interested in what sort of
> case it could be useful.

Yes, it's used all the time in low-level communications protocols,
where it's often implemented in hardware. But, it is also not at all
unusual to implement it in software.

It's also not that unusual for the "count-ones" part of the function
you're asking for to be implemented in hardware by a CPU having an
instruction that counts the number of 1 bits in a register.

GCC has a low-level builtins called __builtin_popcount() and
__builtin-popcountl() that counts the number of 1's in an unsigned
(long) int.


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

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


Re: xor operator

2023-11-13 Thread Grant Edwards via Python-list
On 2023-11-14, Dom Grigonis via Python-list  wrote:
>
>> Except the 'any' and 'all' builtins are _exactly_ the same as bitwise
>> or and and applided to many bits. To do something "in line" with that
>> using the 'xor' operator would return True for an odd number of True
>> values and False for an even Number of True values.
>
> Fair point.
>
> Have you ever encountered the need for xor for many bits (the one
> that I am NOT referring to)? Would be interested in what sort of
> case it could be useful.

Yes, it's used all the time in low-level communications protocols,
where it's often implemented in hardware. But, it is also not at all
unusual to implement it in software.

It's also not that unusual for the "count-ones" part of the function
you're asking for to be implemented in hardware by a CPU having an
instruction that counts the number of 1 bits in a register.

GCC has a low-level builtins called __builtin_popcount() and
__builtin-popcountl() that counts the number of 1's in an unsigned
(long) int.


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


Re: xor operator

2023-11-13 Thread Chris Angelico via Python-list
On Tue, 14 Nov 2023 at 11:40, Chris Angelico  wrote:
> Here's a couple of excellent videos on error correction, and you'll
> see XOR showing up as a crucial feature:
>
> https://www.youtube.com/watch?v=X8jsijhllIA
> https://www.youtube.com/watch?v=h0jloehRKas
>

I just flipped through that 3blue1brown video again, and as it turns
out, the actual part where he talks about multi-argument XOR happens
in part two (it's barely touched on at the very end as he's
introducing part two).

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

Honestly though, the full video is well worth watching. More modern
error correction systems are slightly different, but will still be
built on many of the same principles.

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


Re: xor operator

2023-11-13 Thread Alan Gauld via Python-list
On 14/11/2023 00:33, Mats Wichmann via Python-list wrote:
> Hardware and software people may have somewhat different views of xor

I've come at it from both sides. I started life as a telecomms
technician and we learned about xor in the context of switching
and relays and xor was a wiring configuration for scenarios where
you wanted any single change of switch state to toggle the
entire system (think a stairwell with switches on every
landing).

Later, I got into software engineering and we studied Boolean
algebra and xor was an odd number of Truth values, used in
parity tests (and in encryption).

But from both perspectives xor is pretty clearly defined
in how it operates and not, I suspect, what the OP really
wants in this case.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


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


Re: xor operator

2023-11-13 Thread Chris Angelico via Python-list
On Tue, 14 Nov 2023 at 12:02, Dom Grigonis via Python-list
 wrote:
> As I am here, I will dare to ask if there is no way that `sign` function is 
> going to be added to `math` or `builtins`.
>

https://docs.python.org/3/library/math.html#math.copysign

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


Re: xor operator

2023-11-13 Thread Dom Grigonis via Python-list
I agree, from perspective of standard `all` and `any` use cases this does not 
seem very useful.

However, in my experience it has its usages. E.g.:
* If sum(map(bool, iterable) [> | <] n can be useful. Counting dead processes 
and similar, optimisation problems where need to re-initialise if less than 
certain number of nodes reached certain threshold.
* If sum(map(bool, iterable) [== | !=] n is an edge case. Can’t even think of 
an example
* Finally, it would be a convenient shorthand for `bool(a) ^ bool(b)`

I sometimes think that there is also a case when certain function is not in 
one’s mind he doesn’t see the usefulness, but sometimes the sheer knowledge of 
its existence can twist certain situations in a positive manner.

What about an alternative, which does seem more useful:

def count_compare(iterable, n):
return np.sign(sum(map(bool, iterable)) - n)

print(count_compare([False, False, False], 1))
As I am here, I will dare to ask if there is no way that `sign` function is 
going to be added to `math` or `builtins`. `np.sign` does the trick, but it is 
very slow to be used on a single number. And yes, I know that `copysign` 
exists, it just doesn’t do the same thing.

DG

> On 14 Nov 2023, at 02:33, Mats Wichmann via Python-list 
>  wrote:
> 
> On 11/13/23 16:24, Dom Grigonis via Python-list wrote:
>> I am not arguing that it is a generalised xor.
>> I don’t want anything, I am just gauging if it is specialised or if there is 
>> a need for it. So just thought could suggest it as I have encountered such 
>> need several times already.
>> It is fairly clear by now that it is not a common one given it took some 
>> time to even convey what I mean. Bad naming didn’t help ofc, but if it was 
>> something that is needed I think it would have clicked much faster.
> 
> There are things that If You Need Them You Know, and If You Do Not You Do Not 
> Understand - and you seem to have found one.  The problem is that forums like 
> this are not a statistically great sampling mechanism - a few dozen people, 
> perhaps, chime in on many topics; there are millions of people using Python. 
> Still, the folks here like to think they're at least somewhat representative 
> :)
> 
> Hardware and software people may have somewhat different views of xor, so 
> *maybe* the topic title added a bit to the muddle.  To me (one of those 
> millions), any/all falsy, any/all truthy have some interest, and Python does 
> provide those. Once you get into How Many True question - whether that's the 
> odd-is-true, even-is-false model, or the bail-after-X-truthy-values model, 
> it's not terribly interesting to me: once it gets more complex than an 
> all/any decision, I need to check for particular combinations specifically. 
> Two-of-six means nothing to me until I know which combination of two it is.
> 
> 
> -- 
> https://mail.python.org/mailman/listinfo/python-list

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


Re: xor operator

2023-11-13 Thread Chris Angelico via Python-list
On Tue, 14 Nov 2023 at 11:29, Dom Grigonis via Python-list
 wrote:
>
>
> > Except the 'any' and 'all' builtins are _exactly_ the same as bitwise
> > or and and applided to many bits. To do something "in line" with that
> > using the 'xor' operator would return True for an odd number of True
> > values and False for an even Number of True values.
>
> Fair point.
>
> Have you ever encountered the need for xor for many bits (the one that I am 
> NOT referring to)? Would be interested in what sort of case it could be 
> useful.

Yes, parity checking. That's why I namedropped that in my prior
response - it's an easy thing to search the web for if you want to
know more about it.

Here's a couple of excellent videos on error correction, and you'll
see XOR showing up as a crucial feature:

https://www.youtube.com/watch?v=X8jsijhllIA
https://www.youtube.com/watch?v=h0jloehRKas

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


Re: xor operator

2023-11-13 Thread Michael Speer via Python-list
>AFAICT, it's not nothing at all to do with 'xor' in any sense.

As much as I agree that the function needn't be in the base of python, I
can easily follow the OP's logic on the function name.

With two items in the iterator, it is a standard binary exclusive or.

It is true if one of but not both of the items is true.

OP then generalized this to is exclusively one of any number of these
options are true, which is different than the repetitious binary operator
application, certainly, but is still very much an 'or' that excludes the
case of other options being true.

OP then generalized this from exclusively one truth in the set of variables
to some other specific number of truths that need be.

I expect the OP could then generalize this to a range of truthiness for the
set with a minimum and maximum allowable truthiness, and probably a key
function to extract some facet from the iterable for consideration.

I understand why you find it disagreeable, but I cannot find it necessarily
illogical, and it is easy, I think, to see what it has to do with xor.

A better name for OP's generalization, however, could likely be 'aut', from
the Latin exclusive or.


On Mon, Nov 13, 2023 at 7:20 PM Grant Edwards via Python-list <
python-list@python.org> wrote:

> On 2023-11-13, Dom Grigonis via Python-list 
> wrote:
>
> > I am not asking. Just inquiring if the function that I described
> > could be useful for more people.
> >
> > Which is: a function with API that of `all` and `any` and returns
> > `True` if specified number of elements is True.
>
> I've got no objection to a function that counts True objects returned
> by an iterator and returns True IFF count == .
>
> I've got no objection to a function that counts True objects returned
> by an iterator and returns True IFF count >= .
>
> I've got no objection if that latter function short-circuits by
> stopping the iteration and returning True when it has seen  true
> objects.
>
> I don't recall ever having a need for such a function in the 25 years
> I've been writing Python code, but I'm not going to claim that nobody
> else has a need for such a function.
>
> I would object to that being called 'xor', and would fight to the
> death (yes, I'm being hyperbolic) the addition of a builtin with the
> name 'xor' that does what you describe.
>
> > It is not a generalised `xor` in strict programatic space.
>
> AFAICT, it's not nothing at all to do with 'xor' in any sense.
>
> > I.e. NOT bitwise xor applied to many bits.  This is more in line
> > with cases that `any` and `all` builtins are used.
>
> Except the 'any' and 'all' builtins are _exactly_ the same as bitwise
> or and and applided to many bits. To do something "in line" with that
> using the 'xor' operator would return True for an odd number of True
> values and False for an even Number of True values.
>
> --
> Grant
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: xor operator

2023-11-13 Thread Mats Wichmann via Python-list

On 11/13/23 16:24, Dom Grigonis via Python-list wrote:

I am not arguing that it is a generalised xor.

I don’t want anything, I am just gauging if it is specialised or if there is a 
need for it. So just thought could suggest it as I have encountered such need 
several times already.

It is fairly clear by now that it is not a common one given it took some time 
to even convey what I mean. Bad naming didn’t help ofc, but if it was something 
that is needed I think it would have clicked much faster.


There are things that If You Need Them You Know, and If You Do Not You 
Do Not Understand - and you seem to have found one.  The problem is that 
forums like this are not a statistically great sampling mechanism - a 
few dozen people, perhaps, chime in on many topics; there are millions 
of people using Python. Still, the folks here like to think they're at 
least somewhat representative :)


Hardware and software people may have somewhat different views of xor, 
so *maybe* the topic title added a bit to the muddle.  To me (one of 
those millions), any/all falsy, any/all truthy have some interest, and 
Python does provide those. Once you get into How Many True question - 
whether that's the odd-is-true, even-is-false model, or the 
bail-after-X-truthy-values model, it's not terribly interesting to me: 
once it gets more complex than an all/any decision, I need to check for 
particular combinations specifically. Two-of-six means nothing to me 
until I know which combination of two it is.



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


Re: xor operator

2023-11-13 Thread Dom Grigonis via Python-list


> Except the 'any' and 'all' builtins are _exactly_ the same as bitwise
> or and and applided to many bits. To do something "in line" with that
> using the 'xor' operator would return True for an odd number of True
> values and False for an even Number of True values.

Fair point.

Have you ever encountered the need for xor for many bits (the one that I am NOT 
referring to)? Would be interested in what sort of case it could be useful.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: xor operator

2023-11-13 Thread Grant Edwards via Python-list
On 2023-11-13, Dom Grigonis via Python-list  wrote:

> I am not asking. Just inquiring if the function that I described
> could be useful for more people.
>
> Which is: a function with API that of `all` and `any` and returns
> `True` if specified number of elements is True.

I've got no objection to a function that counts True objects returned
by an iterator and returns True IFF count == .

I've got no objection to a function that counts True objects returned
by an iterator and returns True IFF count >= .

I've got no objection if that latter function short-circuits by
stopping the iteration and returning True when it has seen  true
objects.

I don't recall ever having a need for such a function in the 25 years
I've been writing Python code, but I'm not going to claim that nobody
else has a need for such a function.

I would object to that being called 'xor', and would fight to the
death (yes, I'm being hyperbolic) the addition of a builtin with the
name 'xor' that does what you describe.

> It is not a generalised `xor` in strict programatic space.

AFAICT, it's not nothing at all to do with 'xor' in any sense.

> I.e. NOT bitwise xor applied to many bits.  This is more in line
> with cases that `any` and `all` builtins are used.

Except the 'any' and 'all' builtins are _exactly_ the same as bitwise
or and and applided to many bits. To do something "in line" with that
using the 'xor' operator would return True for an odd number of True
values and False for an even Number of True values.

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


Re: xor operator

2023-11-13 Thread Dom Grigonis via Python-list
I am not arguing that it is a generalised xor.

I don’t want anything, I am just gauging if it is specialised or if there is a 
need for it. So just thought could suggest it as I have encountered such need 
several times already.

It is fairly clear by now that it is not a common one given it took some time 
to even convey what I mean. Bad naming didn’t help ofc, but if it was something 
that is needed I think it would have clicked much faster.

Thanks,
DG

> On 14 Nov 2023, at 01:12, Chris Angelico via Python-list 
>  wrote:
> 
> On Tue, 14 Nov 2023 at 10:00, Dom Grigonis via Python-list
>  wrote:
>> 
>> I am not asking. Just inquiring if the function that I described could be 
>> useful for more people.
>> 
>> Which is: a function with API that of `all` and `any` and returns `True` if 
>> specified number of elements is True.
>> 
>> It is not a generalised `xor` in strict programatic space. I.e. NOT bitwise 
>> xor applied to many bits.
>> This is more in line with cases that `any` and `all` builtins are used.
>> 
> 
> A generalization of XOR is exactly what Grant and I said, though: a
> parity check. See for example:
> 
> https://en.wikipedia.org/wiki/Exclusive_or
> https://reference.wolfram.com/language/ref/Xor.html
> 
> It tells you whether you have an odd or even number of true values.
> 
> Now, if you want something that short-circuits a counting function,
> that's definitely doable, but it's a sum-and-compare, not xor. Also,
> it's quite specialized so it's unlikely to end up in the stdlib.
> 
> ChrisA
> -- 
> https://mail.python.org/mailman/listinfo/python-list

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


Re: xor operator

2023-11-13 Thread Chris Angelico via Python-list
On Tue, 14 Nov 2023 at 10:00, Dom Grigonis via Python-list
 wrote:
>
> I am not asking. Just inquiring if the function that I described could be 
> useful for more people.
>
> Which is: a function with API that of `all` and `any` and returns `True` if 
> specified number of elements is True.
>
> It is not a generalised `xor` in strict programatic space. I.e. NOT bitwise 
> xor applied to many bits.
> This is more in line with cases that `any` and `all` builtins are used.
>

A generalization of XOR is exactly what Grant and I said, though: a
parity check. See for example:

https://en.wikipedia.org/wiki/Exclusive_or
https://reference.wolfram.com/language/ref/Xor.html

It tells you whether you have an odd or even number of true values.

Now, if you want something that short-circuits a counting function,
that's definitely doable, but it's a sum-and-compare, not xor. Also,
it's quite specialized so it's unlikely to end up in the stdlib.

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


Re: xor operator

2023-11-13 Thread Dom Grigonis via Python-list
I am not asking. Just inquiring if the function that I described could be 
useful for more people.

Which is: a function with API that of `all` and `any` and returns `True` if 
specified number of elements is True.

It is not a generalised `xor` in strict programatic space. I.e. NOT bitwise xor 
applied to many bits.
This is more in line with cases that `any` and `all` builtins are used.

> On 14 Nov 2023, at 00:51, Grant Edwards via Python-list 
>  wrote:
> 
> On 2023-11-13, Dom Grigonis via Python-list  wrote:
>> Hi All,
>> 
>> I think it could be useful to have `xor` builtin, which has API similar to 
>> the one of `any` and `all`.
>> 
>> * Also, it could have optional second argument `n=1`, which
>> * indicates how many positives indicates `True` return.  For
>> * complete flexibility 3rd argument could indicate if `the number`
>> * is equal, greater, less, ... than `n`
> 
> I would expect "xor" to return true if there are an odd number of
> trues, and false if there are an even number of trues.  It's not clear
> to me what you're asking for.
> 
> 
> 
> -- 
> https://mail.python.org/mailman/listinfo/python-list

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


Re: xor operator

2023-11-13 Thread Grant Edwards via Python-list
On 2023-11-13, Dom Grigonis via Python-list  wrote:
> Hi All,
>
> I think it could be useful to have `xor` builtin, which has API similar to 
> the one of `any` and `all`.
>
> * Also, it could have optional second argument `n=1`, which
> * indicates how many positives indicates `True` return.  For
> * complete flexibility 3rd argument could indicate if `the number`
> * is equal, greater, less, ... than `n`

I would expect "xor" to return true if there are an odd number of
trues, and false if there are an even number of trues.  It's not clear
to me what you're asking for.



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


Re: xor operator

2023-11-13 Thread Dom Grigonis via Python-list
Benchmarks:
test1 = [False] * 100 + [True] * 2
test2 = [True] * 100 + [False] * 2

TIMER.repeat([
lambda: xor(test1), # 0.0168
lambda: xor(test2), # 0.0172
lambda: xor_ss(test1),  # 0.1392
lambda: xor_ss(test2),  # 0.0084
lambda: xor_new(test1), # 0.0116
lambda: xor_new(test2), # 0.0074
lambda: all(test1), # 0.0016
lambda: all(test2)  # 0.0046
])
Your first function is fairly slow.
Second one deals with short-circuiting, but is super slow on full search.

`xor_new` is the best what I could achieve using python builtins.

But builtin `all` has the best performance.

DG

> On 13 Nov 2023, at 23:20, Michael Speer  wrote:
> 
> I don't think an exclusive-or/truthy-entries-count-checker needs to be a 
> builtin by any stretch.
> 
> >>> def xor( iterable, n = 1 ):
> ... return sum( map( bool, iterable ) ) == n
> 
> Or if you insist on short circuiting:
> 
> >>> def xor_ss( iterable, n = 1 ):
> ...   for intermediate in itertools.accumulate( iterable, (lambda x, y: x + 
> bool(y)), initial = 0 ):
> ... if intermediate > n:
> ...   return False
> ...   return intermediate == n
> 
> 
> 
> On Mon, Nov 13, 2023 at 4:05 PM Barry via Python-list  > wrote:
> 
> 
> > On 13 Nov 2023, at 17:48, Dom Grigonis  > > wrote:
> > 
> > Short circuiting happens, when:
> > xor([True, True, False, False], n=1)
> > At index 1 it is clear that the answer is false.
> 
> Can you share an example with 4 values that is true?
> And explain why it is xor.
> 
> Barry
> 
> -- 
> https://mail.python.org/mailman/listinfo/python-list 
> 

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


Re: xor operator

2023-11-13 Thread Chris Angelico via Python-list
On Tue, 14 Nov 2023 at 08:57, Axel Reichert via Python-list
 wrote:
>
> Barry  writes:
>
> > I do not understand how xor(iterator) works.
> > I thought xor takes exactly 2 args.
>
> See
>
>   https://mathworld.wolfram.com/XOR.html
>
> for some background (I was not aware of any generalizations for more
> than 2 arguments either).
>

Generalization to more arguments usually means calculating parity -
that is, it tells you whether you have an odd or even number of true
results. Which means that short-circuiting is nonsensical.

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


Re: xor operator

2023-11-13 Thread Axel Reichert via Python-list
Barry  writes:

> I do not understand how xor(iterator) works.
> I thought xor takes exactly 2 args.

See

  https://mathworld.wolfram.com/XOR.html

for some background (I was not aware of any generalizations for more
than 2 arguments either).

> I also do not understand how xor can be short circuited.

Me neither, but that could be related to the meaning of n (which I did
not get) in the OP's question. Maybe he can clarify.

Best regards

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


Re: xor operator

2023-11-13 Thread Dom Grigonis via Python-list
xor([True, False, False, False], n=1)
xor([False, False, False, True], n=1)
Both of the above would evaluate to true.

Well, it depends how you interpret it.
In binary case it reads: “exclusively one positive bit or the other, but not 
both”
In this case one could read: “exclusively one positive set of certain length, 
but not more than one such set at the same time" 

But I completely see how one could argue, that “exclusive” refers to slightly 
different thing. And multivariate `xor` is a function which defines fixed 
subsets out of which only one is true, but not the others, but this is 
theoretical, as in practice each set would need to always have all values 
switched on or off, which boils down to my proposed `xor` with `n=1`.

But the point is if there is a need for such function or I am the only one who 
happens to use it.

DG

> On 13 Nov 2023, at 23:03, Barry  wrote:
> 
> 
> 
>> On 13 Nov 2023, at 17:48, Dom Grigonis  wrote:
>> 
>> Short circuiting happens, when:
>> xor([True, True, False, False], n=1)
>> At index 1 it is clear that the answer is false.
> 
> Can you share an example with 4 values that is true?
> And explain why it is xor.
> 
> Barry
> 

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


Re: xor operator

2023-11-13 Thread MRAB via Python-list

On 2023-11-13 21:03, Barry via Python-list wrote:




On 13 Nov 2023, at 17:48, Dom Grigonis  wrote:

Short circuiting happens, when:
xor([True, True, False, False], n=1)
At index 1 it is clear that the answer is false.


Can you share an example with 4 values that is true?
And explain why it is xor.

I think what the OP wants is something that stops after finding n true 
items.


It's a more general form of what 'any' and 'all' do - 'any' stops when 
it finds 1 true item and 'all' stops when it finds 1 false item.


In general, you might want to stop when you find n true items or n false 
items, or whatever.


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


Re: xor operator

2023-11-13 Thread Michael Speer via Python-list
I don't think an exclusive-or/truthy-entries-count-checker needs to be a
builtin by any stretch.

>>> def xor( iterable, n = 1 ):
... return sum( map( bool, iterable ) ) == n

Or if you insist on short circuiting:

>>> def xor_ss( iterable, n = 1 ):
...   for intermediate in itertools.accumulate( iterable, (lambda x, y: x +
bool(y)), initial = 0 ):
... if intermediate > n:
...   return False
...   return intermediate == n



On Mon, Nov 13, 2023 at 4:05 PM Barry via Python-list <
python-list@python.org> wrote:

>
>
> > On 13 Nov 2023, at 17:48, Dom Grigonis  wrote:
> >
> > Short circuiting happens, when:
> > xor([True, True, False, False], n=1)
> > At index 1 it is clear that the answer is false.
>
> Can you share an example with 4 values that is true?
> And explain why it is xor.
>
> Barry
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: xor operator

2023-11-13 Thread Barry via Python-list



> On 13 Nov 2023, at 17:48, Dom Grigonis  wrote:
> 
> Short circuiting happens, when:
> xor([True, True, False, False], n=1)
> At index 1 it is clear that the answer is false.

Can you share an example with 4 values that is true?
And explain why it is xor.

Barry

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


Re: xor operator

2023-11-13 Thread Dom Grigonis via Python-list
Well yes, I don’t think naming is very accurate. If iterable has 2 elements, 
then it is `xor`, otherwise it is something else - it checks the number of 
truth values in iterable.

Short circuiting happens, when:
xor([True, True, False, False], n=1)
At index 1 it is clear that the answer is false.

Regards,
DG

> On 13 Nov 2023, at 19:42, Barry  wrote:
> 
> 
> 
>> On 13 Nov 2023, at 15:16, Dom Grigonis via Python-list 
>>  wrote:
>> 
>> I think it could be useful to have `xor` builtin, which has API similar to 
>> the one of `any` and `all`.
> 
> I do not understand how xor(iterator) works.
> I thought xor takes exactly 2 args.
> 
> I also do not understand how xor can be short circuited.
> For AND or OR only looking at the first arg works.
> But that does not work for xor right?
> 
> Barry
> 
> 

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


Re: xor operator

2023-11-13 Thread Barry via Python-list



> On 13 Nov 2023, at 15:16, Dom Grigonis via Python-list 
>  wrote:
> 
> I think it could be useful to have `xor` builtin, which has API similar to 
> the one of `any` and `all`.

I do not understand how xor(iterator) works.
I thought xor takes exactly 2 args.

I also do not understand how xor can be short circuited.
For AND or OR only looking at the first arg works.
But that does not work for xor right?

Barry


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


xor operator

2023-11-13 Thread Dom Grigonis via Python-list
Hi All,

I think it could be useful to have `xor` builtin, which has API similar to the 
one of `any` and `all`.

* Also, it could have optional second argument `n=1`, which indicates how many 
positives indicates `True` return.
* For complete flexibility 3rd argument could indicate if `the number` is 
equal, greater, less, ... than `n`

I find I sometimes need it when dealing with pub-sub filters and multiple 
predicates in general.

What is the current situation that led me to writing this e-mail?
Dealing with circular import in low level component space: library builtins 
depend on validation utilities, while validation utilities want to use xor from 
library builtins.

Not a big issue, but seen there are fairly large threads in stack everyone 
inventing their own `xor`. And surprisingly there aren’t many good solutions. 
Almost none of them deal with short-circuiting well. And those that do contain 
loops that result in very poor performance.


Regards,
DG
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Fallback for operator and other dunder methods

2023-08-04 Thread Dom Grigonis via Python-list
The issue was more of a wrapping around numpy array. Found the solution 
already. Unfortunately, there is no equivalent to __getattr__, the only way is 
to dynamically define them from meta. It seems it’s pretty standard to just 
have a collection of special method names and using them for similar cases. 
Well, at least it’s what I got to. __getattr__ feels very hacky for such case, 
so maybe it’s for the best.

> On 2 Aug 2023, at 19:54, Edmondo Giovannozzi via Python-list 
>  wrote:
> 
> Il giorno mercoledì 26 luglio 2023 alle 20:35:53 UTC+2 Dom Grigonis ha 
> scritto:
>> Tried exactly that and didn’t work. Neither __getattr__, nor 
>> __getattribute__ of meta is being invoked.
>>> On 26 Jul 2023, at 10:01, Chris Angelico via Python-list 
>>> http://python.org/>> wrote: 
>>> 
>>> On Wed, 26 Jul 2023 at 16:52, Dom Grigonis >> ...@gmail.com > wrote: 
 
 Could you give an example? Something isn’t working for me. 
 
>>> 
>>> This is a metaclass: 
>>> 
>>> class Meta(type): 
>>> ... 
>>> class Demo(metaclass=Meta): 
>>> ... 
>>> 
>>> In order to catch those kinds of attribute lookups, you'll need the 
>>> metaclass to hook them. And you might need to use __getattribute__ 
>>> rather than __getattr__. However, there may also be some checks that 
>>> simply look for the presence of the attribute (see: slots), so you may 
>>> find that it's even more complicated. It's usually easiest to just 
>>> create the slots you want. 
>>> 
>>> ChrisA
>>> -- 
>>> https://mail.python.org/mailman/listinfo/python-list
> 
> 
> For numpy arrays you can find some suggestion at: 
> https://numpy.org/doc/stable/user/basics.dispatch.html 
> 
> -- 
> https://mail.python.org/mailman/listinfo/python-list 
> 
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Fallback for operator and other dunder methods

2023-08-04 Thread Edmondo Giovannozzi via Python-list
Il giorno mercoledì 26 luglio 2023 alle 20:35:53 UTC+2 Dom Grigonis ha scritto:
> Tried exactly that and didn’t work. Neither __getattr__, nor __getattribute__ 
> of meta is being invoked.
> > On 26 Jul 2023, at 10:01, Chris Angelico via Python-list 
> >  wrote: 
> > 
> > On Wed, 26 Jul 2023 at 16:52, Dom Grigonis  wrote: 
> >> 
> >> Could you give an example? Something isn’t working for me. 
> >> 
> > 
> > This is a metaclass: 
> > 
> > class Meta(type): 
> > ... 
> > class Demo(metaclass=Meta): 
> > ... 
> > 
> > In order to catch those kinds of attribute lookups, you'll need the 
> > metaclass to hook them. And you might need to use __getattribute__ 
> > rather than __getattr__. However, there may also be some checks that 
> > simply look for the presence of the attribute (see: slots), so you may 
> > find that it's even more complicated. It's usually easiest to just 
> > create the slots you want. 
> > 
> > ChrisA
> > -- 
> > https://mail.python.org/mailman/listinfo/python-list


For numpy arrays you can find some suggestion at: 
https://numpy.org/doc/stable/user/basics.dispatch.html
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Fallback for operator and other dunder methods

2023-07-26 Thread Dom Grigonis via Python-list
Tried exactly that and didn’t work. Neither __getattr__, nor __getattribute__ 
of meta is being invoked.

> On 26 Jul 2023, at 10:01, Chris Angelico via Python-list 
>  wrote:
> 
> On Wed, 26 Jul 2023 at 16:52, Dom Grigonis  wrote:
>> 
>> Could you give an example? Something isn’t working for me.
>> 
> 
> This is a metaclass:
> 
> class Meta(type):
>...
> class Demo(metaclass=Meta):
>...
> 
> In order to catch those kinds of attribute lookups, you'll need the
> metaclass to hook them. And you might need to use __getattribute__
> rather than __getattr__. However, there may also be some checks that
> simply look for the presence of the attribute (see: slots), so you may
> find that it's even more complicated. It's usually easiest to just
> create the slots you want.
> 
> ChrisA
> -- 
> https://mail.python.org/mailman/listinfo/python-list

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


Re: Fallback for operator and other dunder methods

2023-07-26 Thread Dieter Maurer via Python-list
Dom Grigonis wrote at 2023-7-26 05:22 +0300:
> ...
>Is there a way to achieve it without actually implementing operators?
>I have looked at Proxy objects, but they do not seem suited to achieve this.

Proxying is a good approach:
you might have a look at `dm.reuse.proxy.OverridingProxy` (--> `dm.reuse`
on PyPI).
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Fallback for operator and other dunder methods

2023-07-26 Thread Chris Angelico via Python-list
On Wed, 26 Jul 2023 at 16:52, Dom Grigonis  wrote:
>
> Could you give an example? Something isn’t working for me.
>

This is a metaclass:

class Meta(type):
...
class Demo(metaclass=Meta):
...

In order to catch those kinds of attribute lookups, you'll need the
metaclass to hook them. And you might need to use __getattribute__
rather than __getattr__. However, there may also be some checks that
simply look for the presence of the attribute (see: slots), so you may
find that it's even more complicated. It's usually easiest to just
create the slots you want.

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


Re: Fallback for operator and other dunder methods

2023-07-26 Thread Dom Grigonis via Python-list
Could you give an example? Something isn’t working for me.

> On 26 Jul 2023, at 09:40, Chris Angelico via Python-list 
>  wrote:
> 
> On Wed, 26 Jul 2023 at 12:23, Dom Grigonis via Python-list
>  wrote:
>> print(a + 1)# TypeError: unsupported operand type(s) for +: 'A' 
>> and 'int'
>> 
>> Is there a way to achieve it without actually implementing operators?
>> I have looked at Proxy objects, but they do not seem suited to achieve this. 
>> (e.g. wrapt)
> 
> These kinds of special methods are not looked up on the object, but on
> the type. It's more like type(a).__add__(a, 1). So you would need a
> metaclass for this.
> 
> ChrisA
> -- 
> https://mail.python.org/mailman/listinfo/python-list

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


Re: Fallback for operator and other dunder methods

2023-07-26 Thread Chris Angelico via Python-list
On Wed, 26 Jul 2023 at 12:23, Dom Grigonis via Python-list
 wrote:
> print(a + 1)# TypeError: unsupported operand type(s) for +: 'A' 
> and 'int'
>
> Is there a way to achieve it without actually implementing operators?
> I have looked at Proxy objects, but they do not seem suited to achieve this. 
> (e.g. wrapt)

These kinds of special methods are not looked up on the object, but on
the type. It's more like type(a).__add__(a, 1). So you would need a
metaclass for this.

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


Fallback for operator and other dunder methods

2023-07-25 Thread Dom Grigonis via Python-list
To illustrate what I was trying to achieve:

class A:
def __init__(self, arr):
self.arr = arr

def __getattr__(self, name):
arr_method = getattr(self.arr, name)
def wrapper(*args, **kwargs):
new_arr = arr_method(*args, **kwargs)
return type(self)(new_arr)
return wrapper

a = A(np.ones((1, 1)))
print(a.sum().arr)  # 1
print(a + 1)# TypeError: unsupported operand type(s) for +: 'A' and 
'int'

Is there a way to achieve it without actually implementing operators?
I have looked at Proxy objects, but they do not seem suited to achieve this. 
(e.g. wrapt)

If there is no way to do this, wouldn’t it be sensible to have a new method, 
say ‘__getattrspecial__’? Either with ability to customise for which operators 
it is being called or not.


—Nothing ever dies, just enters the state of deferred evaluation—
Dg

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


Re: OT: Addition of a .= operator

2023-06-09 Thread Simon Ward via Python-list

On Wed, May 24, 2023 at 05:18:52PM +1200, dn via Python-list wrote:

Note that the line numbers correctly show the true cause of the
problem, despite both of them being ValueErrors. So if you have to
debug this sort of thing, make sure the key parts are on separate
lines (even if they're all one expression, as in this example), and
then the tracebacks should tell you what you need to know.



Yes, an excellent example to show newcomers to make use of 'the 
information *provided*' - take a deep breath and read through it all, 
picking-out the important information...



However, returning to "condense this into a single line", the 
frequently-seen coding is (in my experience, at least):


   quantity = float( input( "How many would you like? " ) )

which would not produce the helpful distinction between 
line-numbers/function-calls which the above (better-formatted) code 
does!


Old thread I know, but thought it was worth pointing out that Python 3.11
brought in fine-graned error locations in tracebacks[1]:

   $ python3.10 asin.py
   Enter a small number: 4
   Traceback (most recent call last):
 File "/home/p10365088/asin.py", line 3, in 
   print(math.asin(float(input("Enter a small number: "
   ValueError: math domain error

   $ python3.11 asin.py
   Enter a small number: 4
   Traceback (most recent call last):
 File "/home/p10365088/asin.py", line 3, in 
   print(math.asin(float(input("Enter a small number: "
 ^
   ValueError: math domain error

[1]: https://docs.python.org/3/whatsnew/3.11.html#whatsnew311-pep657

Regards,
Simon
--
A complex system that works is invariably found to have evolved from a
simple system that works.—John Gall
--
https://mail.python.org/mailman/listinfo/python-list


Re: OT: Addition of a .= operator

2023-05-24 Thread Peter J. Holzer
On 2023-05-24 12:10:09 +1200, dn via Python-list wrote:
> Perhaps more psychology rather than coding?

Both. As they say, coding means writing for other people first, for
the computer second. So that means anticipating what will be least
confusing for that other person[1] who's going to read that code.

hp

[1] Which is often yourself, a few months older. Or it could be an
experienced colleague who's very familiar with the codebase. Or a new
colleague trying to understand what this is all about (possibly while
learning Python).

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Addition of a .= operator

2023-05-24 Thread Peter J. Holzer
On 2023-05-24 08:51:19 +1000, Chris Angelico wrote:
> On Wed, 24 May 2023 at 08:48, Peter J. Holzer  wrote:
> > Yes, that probably wasn't the best example. I sort of deliberately
> > avoided method chaining here to make my point that you don't have to
> > invent a new variable name for every intermediate result, but of course
> > that backfired because in this case you don't need a variable name at
> > all. I should have used regular function calls ...
> >
> 
> In the context of a .= operator, though, that is *in itself* an
> interesting data point: in order to find an example wherein the .=
> operator would be plausible, you had to make the .= operator
> unnecessary.

Another communication failure on my part, I'm afraid: I was going off on
a tangent about variable naming and didn't intend to show anything about
the usefulness (or lack thereof) of a .= operator.

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


RE: OT: Addition of a .= operator

2023-05-24 Thread avi.e.gross
It may be a matter of taste and policies, Dave.

I am talking about whether to write your code so it looks good to you, and
dealing with issues like error messages only when needed, or whether to
first do all kinds of things to catch errors or make it easier if they pop
up.

Python can be written fairly compactly and elegantly when trying out an
algorithm. But if you pepper it with print statements all over the place
showing the current values of variables and return codes (perhaps commented
out or hiding in an IF statement set to False) then you have a version
harder to read even if it can potentially be very useful. If your code is
constantly specifying what types variables must be or testing constraints,
it may well compile but for some users all that gets in the way of seeing
the big picture. 

In this case, we are discussing issues like how to spread code onto multiple
lines and opinions differ. In languages that do not use indentation as
having special meaning, I often like to stretch out and use lots of lines
for something like a function call with umpteen arguments and especially one
containing nested similar dense function calls. A good text editor can be
helpful in lining up the code so things at the same indentation level have
meaning as do things at other levels.

I will say that the try/catch type idioms that surround every piece of code,
often nested, can make code unreadable.

Similarly, some languages make it easy to do chaining in ways that use
multiple lines.

Since python is (justifiably) picky about indentation, I use such features
less and more cautiously and sometimes need to carefully do things like add
parentheses around a region to avoid inadvertent misunderstandings. 

When I do my work for myself and am not expecting serious errors I tend to
write the main program first and only then enhance it as needed. If working
with a group and established standards, of course, we follow whatever
methods are needed, and especially if a large part of the effort is to test
thoroughly against requirements.



-Original Message-
From: Python-list  On
Behalf Of dn via Python-list
Sent: Wednesday, May 24, 2023 1:19 AM
To: python-list@python.org
Subject: Re: OT: Addition of a .= operator

On 24/05/2023 12.27, Chris Angelico wrote:
> On Wed, 24 May 2023 at 10:12, dn via Python-list 
wrote:
>> However, (continuing @Peter's theme) such confuses things when something
>> goes wrong - was the error in the input() or in the float()?
>> - particularly for 'beginners'
>> - and yes, we can expand the above discussion to talk about
>> error-handling, and repetition until satisfactory data is input by the
>> user or (?frustration leads to) EOD...
> 
> A fair consideration! Fortunately, Python has you covered.
> 
> $ cat asin.py
> import math
> 
> print(
>  math.asin(
>  float(
>  input("Enter a small number: ")
>  )
>  )
> )
> $ python3 asin.py
> Enter a small number: 1
> 1.5707963267948966
> $ python3 asin.py
> Enter a small number: 4
> Traceback (most recent call last):
>File "/home/rosuav/tmp/asin.py", line 4, in 
>  math.asin(
> ValueError: math domain error
> $ python3 asin.py
> Enter a small number: spam
> Traceback (most recent call last):
>File "/home/rosuav/tmp/asin.py", line 5, in 
>  float(
> ValueError: could not convert string to float: 'spam'
> 
> Note that the line numbers correctly show the true cause of the
> problem, despite both of them being ValueErrors. So if you have to
> debug this sort of thing, make sure the key parts are on separate
> lines (even if they're all one expression, as in this example), and
> then the tracebacks should tell you what you need to know.


Yes, an excellent example to show newcomers to make use of 'the 
information *provided*' - take a deep breath and read through it all, 
picking-out the important information...


However, returning to "condense this into a single line", the 
frequently-seen coding is (in my experience, at least):

 quantity = float( input( "How many would you like? " ) )

which would not produce the helpful distinction between 
line-numbers/function-calls which the above (better-formatted) code does!


Summarising (albeit IMHO):

- if relatively trivial/likely to be well-known: collect the calls into 
a chain, eg

 user = user.strip().lower()

- otherwise use separate lines in order to benefit from the stack-trace

- (still saying) use separate assignments, rather than chaining more 
complex/lesser-known combinations

- ensure that the 'final' identifier is meaningful (and perhaps the 
first, and/or even an 'intermediate' if pertinent or kept for re-use later)

- perhaps re-use a single identifier-name as a temp-variable, if can 
reasonably 'get away with it'
(and not confuse simple minds, like yours-truly)


-- 
Regards,
=dn
-- 
https://mail.python.org/mailman/listinfo/python-list

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


Re: OT: Addition of a .= operator

2023-05-23 Thread dn via Python-list

On 24/05/2023 12.27, Chris Angelico wrote:

On Wed, 24 May 2023 at 10:12, dn via Python-list  wrote:

However, (continuing @Peter's theme) such confuses things when something
goes wrong - was the error in the input() or in the float()?
- particularly for 'beginners'
- and yes, we can expand the above discussion to talk about
error-handling, and repetition until satisfactory data is input by the
user or (?frustration leads to) EOD...


A fair consideration! Fortunately, Python has you covered.

$ cat asin.py
import math

print(
 math.asin(
 float(
 input("Enter a small number: ")
 )
 )
)
$ python3 asin.py
Enter a small number: 1
1.5707963267948966
$ python3 asin.py
Enter a small number: 4
Traceback (most recent call last):
   File "/home/rosuav/tmp/asin.py", line 4, in 
 math.asin(
ValueError: math domain error
$ python3 asin.py
Enter a small number: spam
Traceback (most recent call last):
   File "/home/rosuav/tmp/asin.py", line 5, in 
 float(
ValueError: could not convert string to float: 'spam'

Note that the line numbers correctly show the true cause of the
problem, despite both of them being ValueErrors. So if you have to
debug this sort of thing, make sure the key parts are on separate
lines (even if they're all one expression, as in this example), and
then the tracebacks should tell you what you need to know.



Yes, an excellent example to show newcomers to make use of 'the 
information *provided*' - take a deep breath and read through it all, 
picking-out the important information...



However, returning to "condense this into a single line", the 
frequently-seen coding is (in my experience, at least):


quantity = float( input( "How many would you like? " ) )

which would not produce the helpful distinction between 
line-numbers/function-calls which the above (better-formatted) code does!



Summarising (albeit IMHO):

- if relatively trivial/likely to be well-known: collect the calls into 
a chain, eg


user = user.strip().lower()

- otherwise use separate lines in order to benefit from the stack-trace

- (still saying) use separate assignments, rather than chaining more 
complex/lesser-known combinations


- ensure that the 'final' identifier is meaningful (and perhaps the 
first, and/or even an 'intermediate' if pertinent or kept for re-use later)


- perhaps re-use a single identifier-name as a temp-variable, if can 
reasonably 'get away with it'

(and not confuse simple minds, like yours-truly)


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: OT: Addition of a .= operator

2023-05-23 Thread Chris Angelico
On Wed, 24 May 2023 at 10:12, dn via Python-list  wrote:
> However, (continuing @Peter's theme) such confuses things when something
> goes wrong - was the error in the input() or in the float()?
> - particularly for 'beginners'
> - and yes, we can expand the above discussion to talk about
> error-handling, and repetition until satisfactory data is input by the
> user or (?frustration leads to) EOD...

A fair consideration! Fortunately, Python has you covered.

$ cat asin.py
import math

print(
math.asin(
float(
input("Enter a small number: ")
)
)
)
$ python3 asin.py
Enter a small number: 1
1.5707963267948966
$ python3 asin.py
Enter a small number: 4
Traceback (most recent call last):
  File "/home/rosuav/tmp/asin.py", line 4, in 
math.asin(
ValueError: math domain error
$ python3 asin.py
Enter a small number: spam
Traceback (most recent call last):
  File "/home/rosuav/tmp/asin.py", line 5, in 
float(
ValueError: could not convert string to float: 'spam'

Note that the line numbers correctly show the true cause of the
problem, despite both of them being ValueErrors. So if you have to
debug this sort of thing, make sure the key parts are on separate
lines (even if they're all one expression, as in this example), and
then the tracebacks should tell you what you need to know.

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


OT: Addition of a .= operator

2023-05-23 Thread dn via Python-list

On 24/05/2023 10.21, Rob Cliffe via Python-list wrote:



This sort of code might be better as a single expression. For example:

user = (
 request.GET["user"]
 .decode("utf-8")
 .strip()
 .lower()
)
user = orm.user.get(name=user)


LOL.  And I thought I was the one with a (self-confessed) tendency to 
write too slick, dense, smart-alec code. 
Indeed, I was itching to shorten it (starting with the low-hanging 
fruit: user = user.strip().lower() ).
Seriously though: this kind of condensation can come unstuck when any of 
the steps need to be made more complicated.

...

Peter's actual code feels more Pythonic to me.  (It's even 2 lines 
shorter! )


On 24/05/2023 09.03, Peter J. Holzer wrote:
> I sometimes have a chain of transformations (e.g. first decode it, then
> strip extra spaces, then normalize spelling, then look it up in a
> database and replace it with the record, ...). Technically, of course
> all these intermediate objects are different, and I could make that
> explicit by using different variable names:
>
>  user_param = request.GET["user"]
>  user_decoded = str(user_param, encoding="utf-8")
>  user_stripped = user_decoded.strip()
>  user_normalized = user_stripped.lower()
>  user_object = orm.user.get(name=user_normalized)
>
> But I find it easier to read if I just reuse the same variable name:
>
>  user = request.GET["user"]
>  user = str(user, encoding="utf-8")
>  user = user.strip()
>  user = user.lower()
>  user = orm.user.get(name=user)
>
> Each instance only has a livetime of a single line (or maybe two or
> three lines if I have to combine variables), so there's little risk of
> confusion, and reusing the variable name makes it very clear that all
> those intermediate results are gone and won't be used again.


Once again/recently/another trainee came with a question about input() 
because he expected an number (cf input() providing a string). In this 
case, and to drive-home the point, preferred training illustration is:


quantity_input = input( "How many would you like? " )
quantity = float( quantity_input )

Many others, and I dare so all those who suffer from the aforementioned 
"itch", want to condense this into a single line.


However, (continuing @Peter's theme) such confuses things when something 
goes wrong - was the error in the input() or in the float()?

- particularly for 'beginners'
- and yes, we can expand the above discussion to talk about 
error-handling, and repetition until satisfactory data is input by the 
user or (?frustration leads to) EOD...


Accordingly, I'd start by favoring @Peter's "explicit" approach. However 
(as mentioned), we end-up with a bunch of names (storage-space) which 
are essentially unused - and many lint-er types will deplore such 
single-use [like it's s-u plastic].


Thus, advice becomes somewhat the opposite(!) of function parameter 
handling - there, I'm happy with one or two positional-parameters, but 
by three-or-more, this over-taxed brain starts begging/itching for 
named-parameters instead.


Now, the "easier" approach appeals. Indeed, if something goes wrong (per 
input()/float(), above), at least one has the assistance of a 
line-number (where error was noted). Further, using the PyCharm 
Debugger/pdb makes locating the design-error/coder's mistaken 
assumption, a snap.


A debatable-point is how much we should consider more junior-level 
programmers. IMHO more common functions such as strip() and lower() can 
be combined without much loss of readability or comprehension (apart 
from 'function-chaining' adding complication). Whereas, the other three 
lines are more likely to challenge - and/or become a source of concern 
if mods are requested...


However, some disagreement - which comes back to why the "_input" suffix 
(above) acts as an aide-memoire: When "user" is first used (hah!), it is 
the result of an http request. It is then transmogrified, until at the 
end where it is a query-result/object. Yes, however contrived and 
deliberately drawn-out the example, there is still a difference between 
the value which the code first produces (request/input) and that which 
eventually settles-out (orm/float).


Accordingly (perhaps), "user_request" or "user_requested" and "user" or 
"user_record" (according to the way 'that' ORM operates). Perhaps more 
psychology rather than coding?


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Addition of a .= operator

2023-05-23 Thread Rob Cliffe via Python-list



On 23/05/2023 22:03, Peter J. Holzer wrote:

On 2023-05-21 20:30:45 +0100, Rob Cliffe via Python-list wrote:

On 20/05/2023 18:54, Alex Jando wrote:

So what I'm suggesting is something like this:


hash = hashlib.sha256(b'word')
hash.=hexdigest()

num = Number.One
num.=value


It seems to me that this would encourage bad style.  When you write
     num = num.value
you are using num with two different meanings (an object and an
attribute of it).

I think that's ok if it's the same thing at a high level.

I sometimes have a chain of transformations (e.g. first decode it, then
strip extra spaces, then normalize spelling, then look it up in a
database and replace it with the record, ...). Technically, of course
all these intermediate objects are different, and I could make that
explicit by using different variable names:

 user_param = request.GET["user"]
 user_decoded = str(user_param, encoding="utf-8")
 user_stripped = user_decoded.strip()
 user_normalized = user_stripped.lower()
 user_object = orm.user.get(name=user_normalized)

But I find it easier to read if I just reuse the same variable name:

 user = request.GET["user"]
 user = str(user, encoding="utf-8")
 user = user.strip()
 user = user.lower()
 user = orm.user.get(name=user)

Each instance only has a livetime of a single line (or maybe two or
three lines if I have to combine variables), so there's little risk of
confusion, and reusing the variable name makes it very clear that all
those intermediate results are gone and won't be used again.

 hp



Quite so.  I did imply in my full answer that this kind of thing can be 
appropriate in the right context.  I'm sure I've done it myself.
Your code is a beautiful example of when such "level-crossing" IS 
appropriate; creating a plethora of variables with a short useful life
would be a distraction which HINDERS readability ("Are any of these 
variables used later on?").
(Not to mention the effort of thinking up suitable variable names, and 
the effort of someone reading the code to assimilate them.)

But IMO your code would not really benefit from writing
        user .= strip()
        user .= lower()
and allowing it would have the disadvantage (apart from all the known 
costs of adding a new feature to Python) of encouraging bad style in the 
cases where it IS bad style.

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


Re: Addition of a .= operator

2023-05-23 Thread Chris Angelico
On Wed, 24 May 2023 at 08:57, Rob Cliffe  wrote:
> > Do you mean "ASCII or UTF-8"? Because decoding as UTF-8 is fine with
> > ASCII (it's a superset). You should always consistently get the same
> > data type (bytes or text) based on the library you're using.
> >
> > ChrisA
> OK, bad example.  The point remains: condensing each step to a single
> chained function can come unstuck when one of the steps needs to be made
> more complicated for some reason.

That's fair. Still, I wouldn't over-complicate a piece of code "just
in case" it needs to become more complicated in the future. I'd rather
code to what's needed now, and if that's a simple "decode as UTF-8",
that's great; maybe in the future I need to cope with an insane system
like "decode line by line, attempting UTF-8 first and falling back on
Windows-1252, then rejoin the lines", and that's the time to implement
that.

(Yes, I have had to do that. Although I think I cheated and used
ISO-8859-1 instead. It was a lot easier and I didn't really care about
precise handling, so long as MOST things were readable.)

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


Re: Addition of a .= operator

2023-05-23 Thread Chris Angelico
On Wed, 24 May 2023 at 08:48, Peter J. Holzer  wrote:
>
> On 2023-05-24 07:12:32 +1000, Chris Angelico wrote:
> > On Wed, 24 May 2023 at 07:04, Peter J. Holzer  wrote:
> > > But I find it easier to read if I just reuse the same variable name:
> > >
> > > user = request.GET["user"]
> > > user = str(user, encoding="utf-8")
> > > user = user.strip()
> > > user = user.lower()
> > > user = orm.user.get(name=user)
> > >
> > > Each instance only has a livetime of a single line (or maybe two or
> > > three lines if I have to combine variables), so there's little risk of
> > > confusion, and reusing the variable name makes it very clear that all
> > > those intermediate results are gone and won't be used again.
> > >
> >
> > Small side point: You can make use of the bytes object's decode()
> > method to make the chaining much more useful here, rather than the
> > str() constructor.
> >
> > This sort of code might be better as a single expression. For example:
> >
> > user = (
> > request.GET["user"]
> > .decode("utf-8")
> > .strip()
> > .lower()
> > )
> > user = orm.user.get(name=user)
>
> Yes, that probably wasn't the best example. I sort of deliberately
> avoided method chaining here to make my point that you don't have to
> invent a new variable name for every intermediate result, but of course
> that backfired because in this case you don't need a variable name at
> all. I should have used regular function calls ...
>

In the context of a .= operator, though, that is *in itself* an
interesting data point: in order to find an example wherein the .=
operator would be plausible, you had to make the .= operator
unnecessary.

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


Re: Addition of a .= operator

2023-05-23 Thread Peter J. Holzer
On 2023-05-24 07:12:32 +1000, Chris Angelico wrote:
> On Wed, 24 May 2023 at 07:04, Peter J. Holzer  wrote:
> > But I find it easier to read if I just reuse the same variable name:
> >
> > user = request.GET["user"]
> > user = str(user, encoding="utf-8")
> > user = user.strip()
> > user = user.lower()
> > user = orm.user.get(name=user)
> >
> > Each instance only has a livetime of a single line (or maybe two or
> > three lines if I have to combine variables), so there's little risk of
> > confusion, and reusing the variable name makes it very clear that all
> > those intermediate results are gone and won't be used again.
> >
> 
> Small side point: You can make use of the bytes object's decode()
> method to make the chaining much more useful here, rather than the
> str() constructor.
> 
> This sort of code might be better as a single expression. For example:
> 
> user = (
> request.GET["user"]
> .decode("utf-8")
> .strip()
> .lower()
> )
> user = orm.user.get(name=user)

Yes, that probably wasn't the best example. I sort of deliberately
avoided method chaining here to make my point that you don't have to
invent a new variable name for every intermediate result, but of course
that backfired because in this case you don't need a variable name at
all. I should have used regular function calls ...

hp


-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Addition of a .= operator

2023-05-23 Thread Rob Cliffe via Python-list



This sort of code might be better as a single expression. For example:

user = (
 request.GET["user"]
 .decode("utf-8")
 .strip()
 .lower()
)
user = orm.user.get(name=user)


LOL.  And I thought I was the one with a (self-confessed) tendency to 
write too slick, dense, smart-alec code. 
Indeed, I was itching to shorten it (starting with the low-hanging 
fruit: user = user.strip().lower() ).
Seriously though: this kind of condensation can come unstuck when any of 
the steps need to be made more complicated.
(Suppose request.GET might return ASCII, might return Unicode, depending 
on which server it was talking to.)
Peter's actual code feels more Pythonic to me.  (It's even 2 lines 
shorter! )

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


Re: Addition of a .= operator

2023-05-23 Thread Chris Angelico
On Wed, 24 May 2023 at 08:22, Rob Cliffe  wrote:
>
>
> > This sort of code might be better as a single expression. For example:
> >
> > user = (
> >  request.GET["user"]
> >  .decode("utf-8")
> >  .strip()
> >  .lower()
> > )
> > user = orm.user.get(name=user)
> >
> >
> LOL.  And I thought I was the one with a (self-confessed) tendency to
> write too slick, dense, smart-alec code. 
> Indeed, I was itching to shorten it (starting with the low-hanging
> fruit: user = user.strip().lower() ).
> Seriously though: this kind of condensation can come unstuck when any of
> the steps need to be made more complicated.
> (Suppose request.GET might return ASCII, might return Unicode, depending
> on which server it was talking to.)

Do you mean "ASCII or UTF-8"? Because decoding as UTF-8 is fine with
ASCII (it's a superset). You should always consistently get the same
data type (bytes or text) based on the library you're using.

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


Re: Addition of a .= operator

2023-05-23 Thread Chris Angelico
On Wed, 24 May 2023 at 07:04, Peter J. Holzer  wrote:
> But I find it easier to read if I just reuse the same variable name:
>
> user = request.GET["user"]
> user = str(user, encoding="utf-8")
> user = user.strip()
> user = user.lower()
> user = orm.user.get(name=user)
>
> Each instance only has a livetime of a single line (or maybe two or
> three lines if I have to combine variables), so there's little risk of
> confusion, and reusing the variable name makes it very clear that all
> those intermediate results are gone and won't be used again.
>

Small side point: You can make use of the bytes object's decode()
method to make the chaining much more useful here, rather than the
str() constructor.

This sort of code might be better as a single expression. For example:

user = (
request.GET["user"]
.decode("utf-8")
.strip()
.lower()
)
user = orm.user.get(name=user)

The pipeline is still visible, you've avoided the "user = user ."
replication, and you've ALSO avoided duplicating "user = " on each
line too.

IMO the ".=" syntax would actually be a bit of a nuisance in this
style of code. Consider how it would look, with your original str
constructor in the middle:

user = request.GET["user"]
user = str(user, encoding="utf-8")
user .= strip()
user .= lower()
user = orm.user.get(name=user)

The fact that two of them are ".=" rather than "=" is a bit too subtle
for my liking, possibly because the dot is so small.

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


Re: Addition of a .= operator

2023-05-23 Thread Peter J. Holzer
On 2023-05-21 20:30:45 +0100, Rob Cliffe via Python-list wrote:
> On 20/05/2023 18:54, Alex Jando wrote:
> > So what I'm suggesting is something like this:
> > 
> > 
> > hash = hashlib.sha256(b'word')
> > hash.=hexdigest()
> > 
> > num = Number.One
> > num.=value
> > 
> It seems to me that this would encourage bad style.  When you write
>     num = num.value
> you are using num with two different meanings (an object and an
> attribute of it).

I think that's ok if it's the same thing at a high level.

I sometimes have a chain of transformations (e.g. first decode it, then
strip extra spaces, then normalize spelling, then look it up in a
database and replace it with the record, ...). Technically, of course
all these intermediate objects are different, and I could make that
explicit by using different variable names:

user_param = request.GET["user"]
user_decoded = str(user_param, encoding="utf-8")
user_stripped = user_decoded.strip()
user_normalized = user_stripped.lower()
user_object = orm.user.get(name=user_normalized)

But I find it easier to read if I just reuse the same variable name:

user = request.GET["user"]
user = str(user, encoding="utf-8")
user = user.strip()
user = user.lower()
user = orm.user.get(name=user)

Each instance only has a livetime of a single line (or maybe two or
three lines if I have to combine variables), so there's little risk of
confusion, and reusing the variable name makes it very clear that all
those intermediate results are gone and won't be used again.

hp


-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Addition of a .= operator

2023-05-23 Thread Rob Cliffe via Python-list



On 20/05/2023 18:54, Alex Jando wrote:

I have many times had situations where I had a variable of a certain type, all 
I cared about it was one of it's methods.

For example:


import hashlib
hash = hashlib.sha256(b'word')
hash = hash.hexdigest()

import enum
class Number(enum.Enum):
 One: int = 1
 Two: int = 2
 Three: int = 3
num = Number.One
num = num.value


Now to be fair, in the two situations above, I could just access the method 
right as I declare the object, however, sometimes when passing values into 
functions, it's a lot messier to do that.

So what I'm suggesting is something like this:


import hashlib
hash = hashlib.sha256(b'word')
hash.=hexdigest()

import enum
class Number(enum.Enum):
 One: int = 1
 Two: int = 2
 Three: int = 3
num = Number.One
num.=value


It seems to me that this would encourage bad style.  When you write
    num = num.value
you are using num with two different meanings (an object and an 
attribute of it).  The original object is lost.
If down the line you needed to access another attribute of the object, 
you would have to backtrack:

    val = num.value
    spam = num.spam
or at least write the statements in the right order, so that you only 
overwrite num at the end:

    spam = num.spam
    num = num.value
Either way, you are making the code more fragile i.e. harder to maintain.
Now of course, in your use case it may be perfectly appropriate to write 
"num = num.value" as you did.

But IMO it's not something that should be encouraged in general.
Best wishes
Rob Cliffe
--
https://mail.python.org/mailman/listinfo/python-list


Re: Addition of a .= operator

2023-05-20 Thread Greg Ewing via Python-list

On 21/05/23 9:18 am, Richard Damon wrote:
This just can't happen (as far as I can figure) for .= unless the object 
is defining something weird for the inplace version of the operation, 


Indeed. There are clear use cases for overriding +=, but it's hard to
think of one for this. So it would just be syntactic sugar, which is
harder to justify.

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


Re: Addition of a .= operator

2023-05-20 Thread Greg Ewing via Python-list

On 21/05/23 5:54 am, Alex Jando wrote:


hash.=hexdigest()


That would be a very strange and unprecedented syntax that
munges together an attribute lookup and a call.

Keep in mind that a method call in Python is actually two
separate things:

y = x.m()

is equivalent to

f = x.m
y = f()

But it would not be possible to break down your .= syntax
in that way.

Another oddity is that these are equivalent:

x += y
x += (y)

i.e. the RHS is evaluated as usual before doing the +=.

But these would not be equivalent:

hash .= hexdigest()
hash .= (hexdigest())

In fact the latter would probably have to be disallowed, as it's
not at all clear what it should mean.

--
Greg

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


Re: Addition of a .= operator

2023-05-20 Thread Richard Damon

On 5/20/23 4:15 PM, Peter J. Holzer wrote:

On 2023-05-20 10:54:59 -0700, Alex Jando wrote:

I have many times had situations where I had a variable of a certain
type, all I cared about it was one of it's methods.

For example:


hash = hash.hexdigest()

num = num.value


So what I'm suggesting is something like this:


hash.=hexdigest()

num.=value


I actually needed to read those twice to get their meaning. I think

hash .= hexdigest()
num .= value

would have been clearer (yes, I nag my colleagues about white-space,
too).

Do you have any examples (preferably from real code) where you don't
assign to a simple variable? I feel that
 x += 1
isn't much of an improvement over
 x = x + 1
but
 self.data[line+len(chars)-1] += after
is definitely an improvement over
 self.data[line+len(chars)-1] + self.data[line+len(chars)-1] + after

 hp


For immutable types, it is just syntactic sugar, but for mutable type 
there is an important difference



x = []

y = x

x += [1]

changes the list named by y, but

x = []

y = x

x = x + []

does not.


The key is that if a type actually implements the inplace operator, then 
using the op= version doesn't bind the name to a new object but mutates 
the object to a new value.


This just can't happen (as far as I can figure) for .= unless the object 
is defining something weird for the inplace version of the operation, 
which is probably best to not actually allow.


--
Richard Damon

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


Re: Addition of a .= operator

2023-05-20 Thread Peter J. Holzer
On 2023-05-20 10:54:59 -0700, Alex Jando wrote:
> I have many times had situations where I had a variable of a certain
> type, all I cared about it was one of it's methods.
> 
> For example:
> 
> 
> hash = hash.hexdigest()
> 
> num = num.value
> 
> 
> So what I'm suggesting is something like this:
> 
> 
> hash.=hexdigest()
> 
> num.=value
> 

I actually needed to read those twice to get their meaning. I think

hash .= hexdigest()
num .= value

would have been clearer (yes, I nag my colleagues about white-space,
too).

Do you have any examples (preferably from real code) where you don't
assign to a simple variable? I feel that
x += 1
isn't much of an improvement over
x = x + 1
but
self.data[line+len(chars)-1] += after
is definitely an improvement over
self.data[line+len(chars)-1] + self.data[line+len(chars)-1] + after

hp

-- 
   _  | Peter J. Holzer| Story must make more sense than reality.
|_|_) ||
| |   | h...@hjp.at |-- Charles Stross, "Creative writing
__/   | http://www.hjp.at/ |   challenge!"


signature.asc
Description: PGP signature
-- 
https://mail.python.org/mailman/listinfo/python-list


RE: Addition of a .= operator

2023-05-20 Thread avi.e.gross
I would suggest thinking carefully about ramifications as well as any benefits 
of adding some or .=operator.

It sounds substantially different than the whole slew of +=, *= and so on  
types of operators. The goal some would say of those is to either allow the 
interpreter optimize by not evaluating twice as in x = x + 1 or python 
extensions of the dunder type like __iadd__() that allow you to control what 
exactly is done and which sometimes make a += b do things a bit different than 
a= a+b.

So what would a __i_invoke_method__() function look like? It seems you want the 
command to sort of replace
Object = Object.method(args)

But for any method whatsoever.

But Python objects can have methods all over the place as they may be 
subclasses that inherit methods, or may implement an abstract method or use 
multiple inheritance. All that searching happens in the current way, so if 

Object.method(args))

Works as expected, would your new method be just syntactic sugar, or would it 
look for a dunder method that may have no idea initially what you want?

Just curious.

Is there an alternative way you could get the functionality without using the 
same way that is used for a very different circumstance?


-Original Message-
From: Python-list  On 
Behalf Of 2qdxy4rzwzuui...@potatochowder.com
Sent: Saturday, May 20, 2023 2:49 PM
To: python-list@python.org
Subject: Re: Addition of a .= operator

On 2023-05-21 at 06:11:02 +1200,
dn via Python-list  wrote:

> On 21/05/2023 05.54, Alex Jando wrote:
> > I have many times had situations where I had a variable of a certain type, 
> > all I cared about it was one of it's methods.
> > 
> > For example:
> > 
> > 
> > import hashlib
> > hash = hashlib.sha256(b'word')
> > hash = hash.hexdigest()
> > 
> > import enum
> > class Number(enum.Enum):
> >  One: int = 1
> >  Two: int = 2
> >  Three: int = 3
> > num = Number.One
> > num = num.value
> > 
> > 
> > Now to be fair, in the two situations above, I could just access the method 
> > right as I declare the object, however, sometimes when passing values into 
> > functions, it's a lot messier to do that.

Can you give an example, preferably one from an actual program, that
shows the mess?  Is it More Messier™ than the difference between the
following examples?

# example 1
hash = hashlib.sha256(b'word')
f(hash.hexdigest()) # call f with hash's hexdigest

# example 2
hash = hashlib.sha256(b'word')
hash = hash.hexdigest() # extract hash's hexdigest
f(hash) # call f with hash's hexdigest

Can you also show what your code would look like with a .= operator?

> > So what I'm suggesting is something like this:
> > 
> > 
> > import hashlib
> > hash = hashlib.sha256(b'word')
> > hash.=hexdigest()
> > 
> > import enum
> > class Number(enum.Enum):
> >  One: int = 1
> >  Two: int = 2
> >  Three: int = 3
> > num = Number.One
> > num.=value
> > 
> 
> A custom-class wrapper?
> Even, a decorator-able function?
-- 
https://mail.python.org/mailman/listinfo/python-list

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


Re: Addition of a .= operator

2023-05-20 Thread 2QdxY4RzWzUUiLuE
On 2023-05-21 at 06:11:02 +1200,
dn via Python-list  wrote:

> On 21/05/2023 05.54, Alex Jando wrote:
> > I have many times had situations where I had a variable of a certain type, 
> > all I cared about it was one of it's methods.
> > 
> > For example:
> > 
> > 
> > import hashlib
> > hash = hashlib.sha256(b'word')
> > hash = hash.hexdigest()
> > 
> > import enum
> > class Number(enum.Enum):
> >  One: int = 1
> >  Two: int = 2
> >  Three: int = 3
> > num = Number.One
> > num = num.value
> > 
> > 
> > Now to be fair, in the two situations above, I could just access the method 
> > right as I declare the object, however, sometimes when passing values into 
> > functions, it's a lot messier to do that.

Can you give an example, preferably one from an actual program, that
shows the mess?  Is it More Messier™ than the difference between the
following examples?

# example 1
hash = hashlib.sha256(b'word')
f(hash.hexdigest()) # call f with hash's hexdigest

# example 2
hash = hashlib.sha256(b'word')
hash = hash.hexdigest() # extract hash's hexdigest
f(hash) # call f with hash's hexdigest

Can you also show what your code would look like with a .= operator?

> > So what I'm suggesting is something like this:
> > 
> > 
> > import hashlib
> > hash = hashlib.sha256(b'word')
> > hash.=hexdigest()
> > 
> > import enum
> > class Number(enum.Enum):
> >  One: int = 1
> >  Two: int = 2
> >  Three: int = 3
> > num = Number.One
> > num.=value
> > 
> 
> A custom-class wrapper?
> Even, a decorator-able function?
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Addition of a .= operator

2023-05-20 Thread dn via Python-list

On 21/05/2023 05.54, Alex Jando wrote:

I have many times had situations where I had a variable of a certain type, all 
I cared about it was one of it's methods.

For example:


import hashlib
hash = hashlib.sha256(b'word')
hash = hash.hexdigest()

import enum
class Number(enum.Enum):
 One: int = 1
 Two: int = 2
 Three: int = 3
num = Number.One
num = num.value


Now to be fair, in the two situations above, I could just access the method 
right as I declare the object, however, sometimes when passing values into 
functions, it's a lot messier to do that.

So what I'm suggesting is something like this:


import hashlib
hash = hashlib.sha256(b'word')
hash.=hexdigest()

import enum
class Number(enum.Enum):
 One: int = 1
 Two: int = 2
 Three: int = 3
num = Number.One
num.=value



A custom-class wrapper?
Even, a decorator-able function?

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Addition of a .= operator

2023-05-20 Thread Alex Jando
I have many times had situations where I had a variable of a certain type, all 
I cared about it was one of it's methods.

For example:


import hashlib
hash = hashlib.sha256(b'word')
hash = hash.hexdigest()

import enum
class Number(enum.Enum):
One: int = 1
Two: int = 2
Three: int = 3
num = Number.One
num = num.value


Now to be fair, in the two situations above, I could just access the method 
right as I declare the object, however, sometimes when passing values into 
functions, it's a lot messier to do that.

So what I'm suggesting is something like this:


import hashlib
hash = hashlib.sha256(b'word')
hash.=hexdigest()

import enum
class Number(enum.Enum):
One: int = 1
Two: int = 2
Three: int = 3
num = Number.One
num.=value

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


Re: What is the reason from different output generate using logical 'and' and 'or' operator in Python 3.10.8

2022-11-11 Thread Exam Guide Publishers
On Tuesday, 8 November 2022 at 05:36:49 UTC+5:30, David wrote:
> On Tue, 8 Nov 2022 at 03:08, ICT Ezy  wrote: 
> 
> > Please explain how to generate different output in following logical 
> > operations 
> 
> > >>> 0 and True 
> > 0 
> > >>> 0 or True 
> > True 
> > >>> 1 and True 
> > True 
> > >>> 1 or True 
> > 1
> Hi, 
> 
> The exact explanation of how 'and' and 'or' behave can be read here: 
> https://docs.python.org/3/library/stdtypes.html#boolean-operations-and-or-not 
> The "Notes" there explain what you see.
Thank you very much, I understood Cleary.
Before I have doubt, but now clear.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: What is the reason from different output generate using logical 'and' and 'or' operator in Python 3.10.8

2022-11-07 Thread David
On Tue, 8 Nov 2022 at 03:08, ICT Ezy  wrote:

> Please explain how to generate different output in following logical 
> operations

> >>> 0 and True
> 0
> >>> 0 or True
> True
> >>> 1 and True
> True
> >>> 1 or True
> 1

Hi,

The exact explanation of how 'and' and 'or' behave can be read here:
  https://docs.python.org/3/library/stdtypes.html#boolean-operations-and-or-not
The "Notes" there explain what you see.
-- 
https://mail.python.org/mailman/listinfo/python-list


What is the reason from different output generate using logical 'and' and 'or' operator in Python 3.10.8

2022-11-07 Thread ICT Ezy
Please explain how to generate different output in following logical operations
>>> 0 and True
0
>>> 0 or True
True
>>> 1 and True
True
>>> 1 or True
1
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Operator: inappropriate wording?

2022-11-04 Thread elas tica
Le vendredi 4 novembre 2022 à 16:29:34 UTC+1, Chris Angelico a écrit :

> Yep. The word "operator" is incorrect when referring to Python's comma 
> (in contrast to, say, C, where the comma actually *is* an operator); 
> and from my understanding, the docs have already been updated to fix 
> this. 
> 
> ChrisA

Thanks Chris for your response. 

This problem of an imaginary comma operator was quite clear. The issue I opened 
is more about the so-called = operator which is not considered as such by the 
official Python FAQ, at the same place where it was said that comma was not an 
operator either.

By the way, I opened another issue because the dot operator is missing in the 
list of tokens that are operators and R. Hettinger seems to consider my 
objection as admissible. The issue is here: 
https://github.com/python/cpython/issues/99000

It seems that there are some problems with the use of the term operator in the 
official documentation ;)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Operator: inappropriate wording?

2022-11-04 Thread Chris Angelico
On Thu, 3 Nov 2022 at 10:17, elas tica  wrote:
>
> Le lundi 31 octobre 2022 à 22:18:57 UTC+1, Chris Angelico a ecrit :
> > Wording is hard. Just ask the SQL standard whether NULL is a value.
> >
>
> Indeed, but I think our problem here is simpler ;)
>
> One could for example omit the incorrect term "operator" while remaining 
> unambiguous. This would give:

Yep. The word "operator" is incorrect when referring to Python's comma
(in contrast to, say, C, where the comma actually *is* an operator);
and from my understanding, the docs have already been updated to fix
this.

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


Re: Operator: inappropriate wording?

2022-11-02 Thread elas tica
Le lundi 31 octobre 2022 à 22:18:57 UTC+1, Chris Angelico a ecrit :
> Wording is hard. Just ask the SQL standard whether NULL is a value. 
> 

Indeed, but I think our problem here is simpler ;)

One could for example omit the incorrect term "operator" while remaining 
unambiguous. This would give:

If the object is a class instance and the attribute reference occurs on both 
sides of the assignment, the right-hand side expression,...

Now, as for the other formulation from the reference document:

The second half of the list, the augmented assignment operators, serve 
lexically as delimiters, but also perform an operation.

(link: https://docs.python.org/3/reference/lexical_analysis.html#delimiters)

it is incorrect (as explained by the FAQ I quoted in my last post) and the 
explanations it gives are even more incorrect suggesting that anything that 
performs an operation is the result of the action of an operator. Under these 
conditions, we could say that del is an operator and even that return is an 
operator!


I opened an issue on the CPython GitHub repository, here: 
https://github.com/python/cpython/issues/98814





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


Re: Operator: inappropriate wording?

2022-10-31 Thread Chris Angelico
On Tue, 1 Nov 2022 at 08:15, elas tica  wrote:
>
> Le mercredi 26 octobre 2022 à 22:12:59 UTC+2, Weatherby,Gerard a ecrit :
> > No. If the docs say in one place a comma is not an operator, they shouldn’t 
> > call it an operator in another place.
> >
> > I’ve submitted a pull request https://github.com/python/cpython/pull/98736 
> > -- we’ll have to see what The Powers That Be think.
>
>
> Thanks for the (merged) pull request about the "comma operator"!
>
> I return to the last two quotes in the Reference Document regarding these 
> so-called "assignment operators".
>
> The entry in the glossary explains that the comma symbol is not an operator. 
> Well, I just realized that this same entry also explains that the = symbol is 
> not an operator, as you can see by reading the end of their response:
>
> The same is true of the various assignment operators (=, += etc). They are 
> not truly operators but syntactic delimiters in assignment statements.
>
> (glossary entry link: 
> https://docs.python.org/3/faq/programming.html#what-s-up-with-the-comma-operator-s-precedence)
>
> Talking about an assignment operator in Python is even more confusing 
> because, since Python 3.8, there is a real assignment operator, namely the 
> walrus operator. As explained above, the correct expression would be 
> "assignement delimiter" or "assignement statement" or "assignement symbol".
>

Wording is hard. Just ask the SQL standard whether NULL is a value.

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


Re: Operator: inappropriate wording?

2022-10-31 Thread elas tica
Le mercredi 26 octobre 2022 à 22:12:59 UTC+2, Weatherby,Gerard a ecrit :
> No. If the docs say in one place a comma is not an operator, they shouldn’t 
> call it an operator in another place. 
> 
> I’ve submitted a pull request https://github.com/python/cpython/pull/98736 -- 
> we’ll have to see what The Powers That Be think.


Thanks for the (merged) pull request about the "comma operator"!

I return to the last two quotes in the Reference Document regarding these 
so-called "assignment operators".

The entry in the glossary explains that the comma symbol is not an operator. 
Well, I just realized that this same entry also explains that the = symbol is 
not an operator, as you can see by reading the end of their response:

The same is true of the various assignment operators (=, += etc). They are not 
truly operators but syntactic delimiters in assignment statements.

(glossary entry link: 
https://docs.python.org/3/faq/programming.html#what-s-up-with-the-comma-operator-s-precedence)

Talking about an assignment operator in Python is even more confusing because, 
since Python 3.8, there is a real assignment operator, namely the walrus 
operator. As explained above, the correct expression would be "assignement 
delimiter" or "assignement statement" or "assignement symbol".


By the way, Alex Martelli shares this view, explaining:

The "=" operator in Python ... doesn't exist, since '=' is not an operator in 
Python (just like it isn't, say, in VB). But, OK, you mean "assignment".

(source: 
https://groups.google.com/g/comp.lang.python/c/K6HfK6HANR4/m/OG9QBzFmTR8J)
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Operator: inappropriate wording?

2022-10-26 Thread Weatherby,Gerard
No. If the docs say in one place a comma is not an operator, they shouldn’t 
call it an operator in another place.

I’ve submitted a pull request https://github.com/python/cpython/pull/98736 -- 
we’ll have to see what The Powers That Be think.

From: Python-list  on 
behalf of elas tica 
Date: Wednesday, October 26, 2022 at 3:32 PM
To: python-list@python.org 
Subject: Operator: inappropriate wording?
*** Attention: This is an external email. Use caution responding, opening 
attachments or clicking on links. ***

Quotes from The Python Language Reference, Release 3.10.8:

- Note that tuples are not formed by the parentheses, but rather by use of the 
comma operator (p. 66)
- Note: If the object is a class instance and the attribute reference occurs on 
both sides of the assignment operator (p. 86)
- The second half of the list, the augmented assignment operators, serve 
lexically as delimiters, but also perform an operation (p. 15)



Do you agree with this use of the term "operator"?

Because there is no such "comma operator" in Python as explained by the 
official FAQ: 
https://urldefense.com/v3/__https://docs.python.org/3/faq/programming.html*what-s-up-with-the-comma-operator-s-precedence__;Iw!!Cn_UX_p3!nL9TZBaXZH87JOWNN7D_3E0ytfdXH8tkUxvTdF4dXbVqOJS0yF0C7idVg4ZGee7FiFyPQqqNRcNeVeWVu5edfg$<https://urldefense.com/v3/__https:/docs.python.org/3/faq/programming.html*what-s-up-with-the-comma-operator-s-precedence__;Iw!!Cn_UX_p3!nL9TZBaXZH87JOWNN7D_3E0ytfdXH8tkUxvTdF4dXbVqOJS0yF0C7idVg4ZGee7FiFyPQqqNRcNeVeWVu5edfg$>

And, =, += and the like are not operators since (a=b), (a+=b), etc have no 
value. There is no assignment operator instead there exists an assignment 
statement. The only assignment operator I can figure out is the walrus 
operator. To confirm, The Python Language Reference gives here:

https://urldefense.com/v3/__https://docs.python.org/3/reference/lexical_analysis.html*operators__;Iw!!Cn_UX_p3!nL9TZBaXZH87JOWNN7D_3E0ytfdXH8tkUxvTdF4dXbVqOJS0yF0C7idVg4ZGee7FiFyPQqqNRcNeVeVnKYO3BA$<https://urldefense.com/v3/__https:/docs.python.org/3/reference/lexical_analysis.html*operators__;Iw!!Cn_UX_p3!nL9TZBaXZH87JOWNN7D_3E0ytfdXH8tkUxvTdF4dXbVqOJS0yF0C7idVg4ZGee7FiFyPQqqNRcNeVeVnKYO3BA$>

the set of tokens considered as operator and the =, += tokens are not listed 
whereas := is.
--
https://urldefense.com/v3/__https://mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!nL9TZBaXZH87JOWNN7D_3E0ytfdXH8tkUxvTdF4dXbVqOJS0yF0C7idVg4ZGee7FiFyPQqqNRcNeVeW3iNHD7g$<https://urldefense.com/v3/__https:/mail.python.org/mailman/listinfo/python-list__;!!Cn_UX_p3!nL9TZBaXZH87JOWNN7D_3E0ytfdXH8tkUxvTdF4dXbVqOJS0yF0C7idVg4ZGee7FiFyPQqqNRcNeVeW3iNHD7g$>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Operator: inappropriate wording?

2022-10-26 Thread Roel Schroeven




elas tica schreef op 26/10/2022 om 21:01:

Quotes from The Python Language Reference, Release 3.10.8:

- Note that tuples are not formed by the parentheses, but rather by use of the 
comma operator (p. 66)
- Note: If the object is a class instance and the attribute reference occurs on 
both sides of the assignment operator (p. 86)
- The second half of the list, the augmented assignment operators, serve 
lexically as delimiters, but also perform an operation (p. 15)



Do you agree with this use of the term "operator"?
It's a bit fuzzy, I guess. Comma, =, +=, *= etc. are in section 2.6 
"Delimiters" and not in section 2.5 "Operators" of The Python Language 
Reference, which would seem to imply that those are not operators. But 
the text in section 2.6 then says "The second half of the list, the 
augmented assignment _operators_, serve lexically as delimiters, but 
also perform an operation.", so at least the augmented assignment 
operators are seen as operators despite not being in the Operators section.



Because there is no such "comma operator" in Python as explained by the 
official FAQ: 
https://docs.python.org/3/faq/programming.html#what-s-up-with-the-comma-operator-s-precedence

That does seem to contradict the text in the language reference.

And, =, += and the like are not operators since (a=b), (a+=b), etc have no 
value. There is no assignment operator instead there exists an assignment 
statement. The only assignment operator I can figure out is the walrus operator.
I think that's a good point too. The language reference calls those 
things 'delimiters', which doesn't feel like a good description either 
for many of them. I find it weird to think of =, *+, +=as a delimiter. 
Maybe that's why those things are called operators anyway instead of 
delimiters in many places? Things like "Note: If the object is a class 
instance and the attribute reference occurs on both sides of the 
assignment _delimiter_" sound a bit weird I feel, even though completely 
correct according to the language reference.


So yeah I think you have a point that the terminology regarding those 
tokens is not very consistent at the least.


--
"Honest criticism is hard to take, particularly from a relative, a friend,
an acquaintance, or a stranger."
-- Franklin P. Jones

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


Operator: inappropriate wording?

2022-10-26 Thread elas tica
Quotes from The Python Language Reference, Release 3.10.8:

- Note that tuples are not formed by the parentheses, but rather by use of the 
comma operator (p. 66)
- Note: If the object is a class instance and the attribute reference occurs on 
both sides of the assignment operator (p. 86)
- The second half of the list, the augmented assignment operators, serve 
lexically as delimiters, but also perform an operation (p. 15)



Do you agree with this use of the term "operator"? 

Because there is no such "comma operator" in Python as explained by the 
official FAQ: 
https://docs.python.org/3/faq/programming.html#what-s-up-with-the-comma-operator-s-precedence

And, =, += and the like are not operators since (a=b), (a+=b), etc have no 
value. There is no assignment operator instead there exists an assignment 
statement. The only assignment operator I can figure out is the walrus 
operator. To confirm, The Python Language Reference gives here:

https://docs.python.org/3/reference/lexical_analysis.html#operators

the set of tokens considered as operator and the =, += tokens are not listed 
whereas := is.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Typing: Is there a "cast operator"?

2022-10-26 Thread Peter Otten

On 24/10/2022 05:19, Chris Angelico wrote:

On Mon, 24 Oct 2022 at 14:15, Dan Stromberg  wrote:

I've found that mypy understands simple assert statements.

So if you:
if f is not None:
 assert f is not None
 os.write(f, ...)

You might be in good shape.


Why can't it simply understand the if statement?


Could it be that this specific problem is fixed in current mypy?
I get

$ type .\tmp.py
import os

f = None
if f is None:
f = os.open("tmp.txt", os.O_RDWR|os.O_CREAT)
os.write(f, b"yadda")
$ mypy tmp.py
Success: no issues found in 1 source file

My attempt to verify that

if name is None: ...

is recognized:

$ type .\tmp2.py
import os
import random

f = None
if random.randrange(2):
f = os.open("tmp.txt", os.O_RDWR|os.O_CREAT)
os.write(f, b"yadda")
$ mypy tmp2.py
tmp2.py:7: error: Argument 1 to "write" has incompatible type
"Optional[int]"; expected "int"
Found 1 error in 1 file (checked 1 source file)
$ mypy --version
mypy 0.982 (compiled: yes)
$

I'm not a fan of

coddling a type system like this. The entire point of type checking is
to help you find bugs more efficiently, so if you have to repeat
yourself every time you do these kinds of checks just so that mypy is
satisfied, that's counter-productive (case in point: what happens if
you say "if fn is not None: assert f is not None"? Now you've
introduced a bug just to deal with the type system).

ChrisA


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


Re: Typing: Is there a "cast operator"?

2022-10-24 Thread Thomas Passin

On 10/23/2022 11:14 PM, Dan Stromberg wrote:

On Sun, Oct 23, 2022 at 2:11 PM Paulo da Silva <
p_d_a_s_i_l_v_a...@nonetnoaddress.pt> wrote:


Hello!

I am in the process of "typing" of some of my scripts.
Using it should help a lot to avoid some errors.
But this is new for me and I'm facing some problems.

Let's I have the following code (please don't look at the program content):

f=None  # mypy naturally assumes Optional(int) because later, at open,
it is assigned an int.
..
if f is None:
 f=os.open(...
..
if f is not None:
 os.write(f, ...)
..
if f is not None:
 os.close(f)

When I use mypy, it claims
Argument 1 to "write" has incompatible type "Optional[int]"; expected "int"
Argument 1 to "close" has incompatible type "Optional[int]"; expected "int"

How to solve this?
Is there a way to specify that when calling os.open f is an int only?

I use None a lot for specify uninitialized vars.



I've found that mypy understands simple assert statements.

So if you:
if f is not None:
 assert f is not None
 os.write(f, ...)

You might be in good shape.


I'm not very familiar with anything but the simplest typing cases as 
yet, but mypy is happy with these two fragments.


if f:
os.write(int(f)) # f must be an int if it is not None, so we can 
cast it to int.


Or something like this (substitute write() for print() as needed) -

from typing import Optional, Any

def f1(x:int)->Optional[int]:
if x == 42:
return x
return None

def zprint(arg:Any):
if type(arg) == int:
print(arg)

y0 = f1(0)  # None
y42 = f1(42) # 42

zprint(y0)  # Prints nothing
zprint(y42) # Prints 42

Another possibility that mypy is happy with (and probably the simplest) 
- just declare g:int = None instead of g = None:


g: int = None
def yprint(arg: int):
if arg:
yprint(arg)
else:
print('arg is None')

yprint(g)  # Prints "arg is None"


And **please** let's not go doing this kind of redundant and inelegant 
construction:


if f is not None:
assert f is not None
os.write(f, ...)
--
https://mail.python.org/mailman/listinfo/python-list


Re: Typing: Is there a "cast operator"?

2022-10-23 Thread Chris Angelico
On Mon, 24 Oct 2022 at 14:15, Dan Stromberg  wrote:
> I've found that mypy understands simple assert statements.
>
> So if you:
> if f is not None:
> assert f is not None
> os.write(f, ...)
>
> You might be in good shape.

Why can't it simply understand the if statement? I'm not a fan of
coddling a type system like this. The entire point of type checking is
to help you find bugs more efficiently, so if you have to repeat
yourself every time you do these kinds of checks just so that mypy is
satisfied, that's counter-productive (case in point: what happens if
you say "if fn is not None: assert f is not None"? Now you've
introduced a bug just to deal with the type system).

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


Re: Typing: Is there a "cast operator"?

2022-10-23 Thread Dan Stromberg
On Sun, Oct 23, 2022 at 2:11 PM Paulo da Silva <
p_d_a_s_i_l_v_a...@nonetnoaddress.pt> wrote:

> Hello!
>
> I am in the process of "typing" of some of my scripts.
> Using it should help a lot to avoid some errors.
> But this is new for me and I'm facing some problems.
>
> Let's I have the following code (please don't look at the program content):
>
> f=None  # mypy naturally assumes Optional(int) because later, at open,
> it is assigned an int.
> ..
> if f is None:
> f=os.open(...
> ..
> if f is not None:
> os.write(f, ...)
> ..
> if f is not None:
> os.close(f)
>
> When I use mypy, it claims
> Argument 1 to "write" has incompatible type "Optional[int]"; expected "int"
> Argument 1 to "close" has incompatible type "Optional[int]"; expected "int"
>
> How to solve this?
> Is there a way to specify that when calling os.open f is an int only?
>
> I use None a lot for specify uninitialized vars.
>

I've found that mypy understands simple assert statements.

So if you:
if f is not None:
assert f is not None
os.write(f, ...)

You might be in good shape.
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Typing: Is there a "cast operator"?

2022-10-23 Thread Paulo da Silva

Às 23:56 de 23/10/22, Cameron Simpson escreveu:
On 23Oct2022 21:36, Paulo da Silva 
 wrote:

I am in the process of "typing" of some of my scripts.
Using it should help a lot to avoid some errors.
But this is new for me and I'm facing some problems.

Let's I have the following code (please don't look at the program 
content):


f=None  # mypy naturally assumes Optional(int) because later, at open, 
it is assigned an int.

..
if f is None:
f=os.open(...
..
if f is not None:
os.write(f, ...)
..
if f is not None:
os.close(f)

When I use mypy, it claims
Argument 1 to "write" has incompatible type "Optional[int]"; expected 
"int"
Argument 1 to "close" has incompatible type "Optional[int]"; expected 
"int"


How to solve this?
Is there a way to specify that when calling os.open f is an int only?

I use None a lot for specify uninitialized vars.


Maybe you shouldn't. The other way is to just not initialise the var at 
all. You could then just specify a type. Example:


    Python 3.8.13 (default, Aug 11 2022, 15:46:53)
    [Clang 12.0.0 (clang-1200.0.32.29)] on darwin
    Type "help", "copyright", "credits" or "license" for more
information.

    >>> f:int
    >>> f
    Traceback (most recent call last):
  File "", line 1, in 
    NameError: name 'f' is not defined
    >>>

So now `f` has `int` type definitely (for `mypy`'s purposes), and if 
used before assignment raises a distinctive error (versus having the 
value `None`, which you might then pass around, and perhaps successfully 
use in some contexts).


It is probably better on the whole to specify types up front rather than 
relying on `mypy` or similar to infer them. That way (a) you're stating 
your intent and (b) not relying on an inferred type, which if you've got 
bugs may be inferred _wrong_. If `mypy` infers a type incorrectly all 
the subsequent checks will also be flawed, perhaps subtly.



Yes.
I also use to make f unavailable (f=None) when something goes wrong and 
I don't want to stop the script but of course I could use "del f". I 
also need to care about using "try", which might be better than "if" tests.

A thing to think of ...

Thanks.
Paulo


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


Re: Typing: Is there a "cast operator"? [RESOLVED]

2022-10-23 Thread Paulo da Silva

Às 21:36 de 23/10/22, Paulo da Silva escreveu:

Hello!

I am in the process of "typing" of some of my scripts.
Using it should help a lot to avoid some errors.
But this is new for me and I'm facing some problems.

Let's I have the following code (please don't look at the program content):

f=None  # mypy naturally assumes Optional(int) because later, at open, 
it is assigned an int.

..
if f is None:
 f=os.open(...
..
if f is not None:
 os.write(f, ...)
..
if f is not None:
 os.close(f)

When I use mypy, it claims
Argument 1 to "write" has incompatible type "Optional[int]"; expected "int"
Argument 1 to "close" has incompatible type "Optional[int]"; expected "int"

How to solve this?
Is there a way to specify that when calling os.open f is an int only?
And yes there is! Exactly the "cast" operator. A mistype led me to wrong 
search results. I'm sorry.


So, in the above code, we have to do:
os.write(cast(int,f), ...)
and
os.close(cast(int,f), ...)

Regards.
Paulo



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


Re: Typing: Is there a "cast operator"?

2022-10-23 Thread Cameron Simpson

On 23Oct2022 21:36, Paulo da Silva  wrote:

I am in the process of "typing" of some of my scripts.
Using it should help a lot to avoid some errors.
But this is new for me and I'm facing some problems.

Let's I have the following code (please don't look at the program content):

f=None  # mypy naturally assumes Optional(int) because later, at open, 
it is assigned an int.

..
if f is None:
f=os.open(...
..
if f is not None:
os.write(f, ...)
..
if f is not None:
os.close(f)

When I use mypy, it claims
Argument 1 to "write" has incompatible type "Optional[int]"; expected "int"
Argument 1 to "close" has incompatible type "Optional[int]"; expected "int"

How to solve this?
Is there a way to specify that when calling os.open f is an int only?

I use None a lot for specify uninitialized vars.


Maybe you shouldn't. The other way is to just not initialise the var at 
all. You could then just specify a type. Example:


   Python 3.8.13 (default, Aug 11 2022, 15:46:53)
   [Clang 12.0.0 (clang-1200.0.32.29)] on darwin
   Type "help", "copyright", "credits" or "license" for more 
   information.

   >>> f:int
   >>> f
   Traceback (most recent call last):
 File "", line 1, in 
   NameError: name 'f' is not defined
   >>>

So now `f` has `int` type definitely (for `mypy`'s purposes), and if 
used before assignment raises a distinctive error (versus having the 
value `None`, which you might then pass around, and perhaps successfully 
use in some contexts).


It is probably better on the whole to specify types up front rather than 
relying on `mypy` or similar to infer them. That way (a) you're stating 
your intent and (b) not relying on an inferred type, which if you've got 
bugs may be inferred _wrong_. If `mypy` infers a type incorrectly all 
the subsequent checks will also be flawed, perhaps subtly.


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


Typing: Is there a "cast operator"?

2022-10-23 Thread Paulo da Silva

Hello!

I am in the process of "typing" of some of my scripts.
Using it should help a lot to avoid some errors.
But this is new for me and I'm facing some problems.

Let's I have the following code (please don't look at the program content):

f=None  # mypy naturally assumes Optional(int) because later, at open, 
it is assigned an int.

..
if f is None:
f=os.open(...
..
if f is not None:
os.write(f, ...)
..
if f is not None:
os.close(f)

When I use mypy, it claims
Argument 1 to "write" has incompatible type "Optional[int]"; expected "int"
Argument 1 to "close" has incompatible type "Optional[int]"; expected "int"

How to solve this?
Is there a way to specify that when calling os.open f is an int only?

I use None a lot for specify uninitialized vars.

Thank you.

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


[issue228830] re is greedy with non-greedy operator

2022-04-10 Thread admin


Change by admin :


--
github: None -> 33719

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue221207] % operator on strings not documented

2022-04-10 Thread admin


Change by admin :


--
github: None -> 33443

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue471202] bit shift operator << precedence

2022-04-10 Thread admin


Change by admin :


--
github: None -> 35327

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue519230] hook method for 'is' operator

2022-04-10 Thread admin


Change by admin :


--
github: None -> 36121

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



  1   2   3   4   5   6   7   8   9   10   >