Mailing List Archive

Understanding the working mechanis of python unary arithmetic operators.
See the following testings:

In [24]: a=3.1415926535897932384626433832795028841971
In [27]: -a
Out[27]: -3.141592653589793

In [28]: +a
Out[28]: 3.141592653589793

In [17]: ~-+1
Out[17]: 0

In [18]: -~+1
Out[18]: 2

In [19]: -+~1
Out[19]: 2

In [20]: +~-1
Out[20]: 0

I'm very puzzled by these operators. Any hints will be highly appreciated.

Regards,
HZ

--
https://mail.python.org/mailman/listinfo/python-list
Re: Understanding the working mechanis of python unary arithmetic operators. [ In reply to ]
On Saturday, October 2, 2021 at 4:59:54 PM UTC+8, ju...@diegidio.name wrote:
> On Saturday, 2 October 2021 at 10:34:27 UTC+2, hongy...@gmail.com wrote:
> > See the following testings:
> >
> > In [24]: a=3.1415926535897932384626433832795028841971
> > In [27]: -a
> > Out[27]: -3.141592653589793
> You've never heard of floating-point? Double precision has 53 significant bits of mantissa, corresponding approximately to 16 decimal digits.
> <https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64>
> > In [17]: ~-+1
> > Out[17]: 0
> << The unary ~ (invert) operator yields the bitwise inversion of its integer argument. The bitwise inversion of x is defined as -(x+1). It only applies to integral numbers or to custom objects that override the __invert__() special method. >>
> <https://docs.python.org/3/reference/expressions.html#unary-arithmetic-and-bitwise-operations>
> > I'm very puzzled by these operators. Any hints will be highly appreciated.
> Try and read the proverbial manual: that's truly a fundamental skill...

Thank you for your explanation. Then what about the following questions?:

1. Should `+' and `-' be classified as binary operators or unary operators? As we all know, `a + b', and `a - b' are the normal ways we do basic arithmetic operations.

2. See the following testings:

In [20]: bool(int(True))
Out[20]: True

In [21]: bool(~int(True))
Out[21]: True

In [22]: bool(~~int(True))
Out[22]: True

In [23]: bool(~~~int(True))
Out[23]: True

In [24]: bool(int(False))
Out[24]: False

In [25]: bool(~int(False))
Out[25]: True

In [26]: bool(~~int(False))
Out[26]: False

In [27]: bool(~~~int(False))
Out[27]: True

Why can’t/shouldn't we get something similar results for both `True' and `False' in the above testings?

HZ
--
https://mail.python.org/mailman/listinfo/python-list
Re: Understanding the working mechanis of python unary arithmetic operators. [ In reply to ]
On Sunday, October 3, 2021 at 3:05:23 AM UTC+8, ju...@diegidio.name wrote:
> On Saturday, 2 October 2021 at 14:48:39 UTC+2, hongy...@gmail.com wrote:
> > On Saturday, October 2, 2021 at 4:59:54 PM UTC+8, ju...@diegidio.name wrote:
> > > On Saturday, 2 October 2021 at 10:34:27 UTC+2, hongy...@gmail.com wrote:
> > > > See the following testings:
> > > >
> > > > In [24]: a=3.1415926535897932384626433832795028841971
> > > > In [27]: -a
> > > > Out[27]: -3.141592653589793
> > >
> > > You've never heard of floating-point? Double precision has 53 significant bits of mantissa, corresponding approximately to 16 decimal digits.
> > > <https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64>
> > >
> > > > In [17]: ~-+1
> > > > Out[17]: 0
> > >
> > > << The unary ~ (invert) operator yields the bitwise inversion of its integer argument. The bitwise inversion of x is defined as -(x+1). It only applies to integral numbers or to custom objects that override the __invert__() special method. >>
> > > <https://docs.python.org/3/reference/expressions.html#unary-arithmetic-and-bitwise-operations>
> > >
> > > > I'm very puzzled by these operators. Any hints will be highly appreciated.
> > >
> > > Try and read the proverbial manual: that's truly a fundamental skill...
> >
> > Thank you for your explanation. Then what about the following questions?:
> >
> > 1. Should `+' and `-' be classified as binary operators or unary operators?
> "Symbol overloading": a+b is binary *addition*, +a is unary *identity* (or however you may like to call it). The meaning of a symbol or name depends on context.

As I understand now, it can be used to identify/normalize the operand by the corresponding precision in the given context.

> > As we all know, `a + b', and `a - b' are the normal ways we do basic arithmetic operations.
> Nonsense. You yourself wrote ~(-(+1)) above, just without parentheses.

Thank you for pointing out my contradictory assertion.

> > 2. See the following testings:
> Read the bloody manual.
>
> Given that:
> int(True) = 1
> int(False) = 0
>
> and that:
> bool(x) is True iff x <> 0

In [8]: bool(None)
Out[8]: False

In [9]: bool('')
Out[9]: False

In [10]: bool(0)
Out[10]: False

So, bool(x) is True iff x <> 0 , None, and '', as shown here [1]:

In [3]: import numpy as np
In [11]: np.array([1, 0.5, 0, None, 'a', '', True, False], dtype=bool)
Out[11]: array([ True, True, False, False, True, False, True, False])

[1] https://riptutorial.com/numpy/example/21181/creating-a-boolean-array#example

> and that:
> ~~x = x for all x (integer)
>
> These:
> ~1 = -(1+1) = -2
> ~~1 = ~-2 = -(-2+1) = 1
> ~~~1 = ~1 = -2
> ...
> all evaluate to True.
>
> And these:
> ~0 = -(0+1) = -1
> ~~0 = ~-1 = -(-1+1) = 0
> ~~~0 = ~0 = -1
> ...
> evaluate to True and False alternatingly.
>
> In short, ~1=-2 (and ~-2=1) and 1 and -2 both convert to True, while ~0=1 but 0 converts to False while 1 converts to True.
> > Why can’t/shouldn't we get something similar results for both `True' and `False' in the above testings?
> Because bitwise complement is not symmetric around 0. For comparison, try with negation instead.

Thanks again. I see, as follows:

In [1]: ~1
Out[1]: -2

In [2]: ~-1
Out[2]: 0


> But don't just guess, try and unpack those expressions while trying and reading the docs: which is a necessary skill in itself.

Thank you for the advice that showed me the way to truth.

HZ
--
https://mail.python.org/mailman/listinfo/python-list
Re: Understanding the working mechanis of python unary arithmetic operators. [ In reply to ]
On Saturday, October 2, 2021 at 4:59:54 PM UTC+8, ju...@diegidio.name wrote:
> On Saturday, 2 October 2021 at 10:34:27 UTC+2, hongy...@gmail.com wrote:
> > See the following testings:
> >
> > In [24]: a=3.1415926535897932384626433832795028841971
> > In [27]: -a
> > Out[27]: -3.141592653589793
> You've never heard of floating-point? Double precision has 53 significant bits of mantissa, corresponding approximately to 16 decimal digits.
> <https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64>
> > In [17]: ~-+1
> > Out[17]: 0
> << The unary ~ (invert) operator yields the bitwise inversion of its integer argument. The bitwise inversion of x is defined as -(x+1). It only applies to integral numbers or to custom objects that override the __invert__() special method. >>
> <https://docs.python.org/3/reference/expressions.html#unary-arithmetic-and-bitwise-operations>

A further inference based on the above description:

Let us consider this equation: -(x+1) = x, the solution is -0.5, which is not an integer. So we can safely come to a conclusion:

If bool(a) == True, \forall a \in integer, then ~bool(a) == False; and vice versa.

This is exactly the theoretical basis to filter some specific columns in pandas, just as the issue discussed here [1].

[1] https://github.com/pandas-dev/pandas/issues/43832#issue-1013375587

HZ
--
https://mail.python.org/mailman/listinfo/python-list
Re: Understanding the working mechanis of python unary arithmetic operators. [ In reply to ]
On Sunday, October 3, 2021 at 2:18:17 PM UTC+8, hongy...@gmail.com wrote:
> On Saturday, October 2, 2021 at 4:59:54 PM UTC+8, ju...@diegidio.name wrote:
> > On Saturday, 2 October 2021 at 10:34:27 UTC+2, hongy...@gmail.com wrote:
> > > See the following testings:
> > >
> > > In [24]: a=3.1415926535897932384626433832795028841971
> > > In [27]: -a
> > > Out[27]: -3.141592653589793
> > You've never heard of floating-point? Double precision has 53 significant bits of mantissa, corresponding approximately to 16 decimal digits.
> > <https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64>
> > > In [17]: ~-+1
> > > Out[17]: 0
> > << The unary ~ (invert) operator yields the bitwise inversion of its integer argument. The bitwise inversion of x is defined as -(x+1). It only applies to integral numbers or to custom objects that override the __invert__() special method. >>
> > <https://docs.python.org/3/reference/expressions.html#unary-arithmetic-and-bitwise-operations>
> A further inference based on the above description:
>
> Let us consider this equation: -(x+1) = x, the solution is -0.5, which is not an integer. So we can safely come to a conclusion:
>
> If bool(a) == True, \forall a \in integer, then ~bool(a) == False; and vice versa.
>
> This is exactly the theoretical basis to filter some specific columns in pandas, just as the issue discussed here [1].

Sorry my not very precise description above. I should have wanted to express the fact that I observed below:

In [3]: import numpy as np
In [15]: ~np.array([True])
Out[15]: array([False])

In [16]: ~np.array([False])
Out[16]: array([ True])

But the normal `True' and `False' don't the good symmetric feature as shown above:

In [21]: bool(~True)
Out[21]: True

In [22]: bool(~False)
Out[22]: True


> [1] https://github.com/pandas-dev/pandas/issues/43832#issue-1013375587
>
> HZ
--
https://mail.python.org/mailman/listinfo/python-list
Re: Understanding the working mechanis of python unary arithmetic operators. [ In reply to ]
On Sunday, October 3, 2021 at 6:31:05 PM UTC+8, ju...@diegidio.name wrote:
> On Sunday, 3 October 2021 at 11:24:58 UTC+2, hongy...@gmail.com wrote:
> > On Sunday, October 3, 2021 at 2:18:17 PM UTC+8, hongy...@gmail.com wrote:
> > > On Saturday, October 2, 2021 at 4:59:54 PM UTC+8, ju...@diegidio.name wrote:
> > > > On Saturday, 2 October 2021 at 10:34:27 UTC+2, hongy...@gmail.com wrote:
> > > > > See the following testings:
> > > > >
> > > > > In [24]: a=3.1415926535897932384626433832795028841971
> > > > > In [27]: -a
> > > > > Out[27]: -3.141592653589793
> > > > You've never heard of floating-point? Double precision has 53 significant bits of mantissa, corresponding approximately to 16 decimal digits.
> > > > <https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64>
> > > > > In [17]: ~-+1
> > > > > Out[17]: 0
> > > > << The unary ~ (invert) operator yields the bitwise inversion of its integer argument. The bitwise inversion of x is defined as -(x+1). It only applies to integral numbers or to custom objects that override the __invert__() special method. >>
> > > > <https://docs.python.org/3/reference/expressions.html#unary-arithmetic-and-bitwise-operations>
> > > A further inference based on the above description:
> > >
> > > Let us consider this equation: -(x+1) = x, the solution is -0.5, which is not an integer. So we can safely come to a conclusion:
> > >
> > > If bool(a) == True, \forall a \in integer, then ~bool(a) == False; and vice versa.
> > >
> > > This is exactly the theoretical basis to filter some specific columns in pandas, just as the issue discussed here [1].
> > Sorry my not very precise description above. I should have wanted to express the fact that I observed below:
> > In [3]: import numpy as np
> > In [15]: ~np.array([True])
> > Out[15]: array([False])
> >
> > In [16]: ~np.array([False])
> > Out[16]: array([ True])
> >
> > But the normal `True' and `False' don't the good symmetric feature as shown above:
> >
> > In [21]: bool(~True)
> > Out[21]: True
> >
> > In [22]: bool(~False)
> > Out[22]: True
> You keep missing the point:
> << The unary ~ (invert) operator yields the bitwise inversion of its integer argument. The bitwise inversion of x is defined as -(x+1). It only applies to integral numbers or to custom objects that override the __invert__() special method. >>
> Then you can guess that numpy overrides it and gives you *logical* negation of boolean values,

I try to dig through the numpy source code to pinning point the overriding/monkey patching/decorating code snippets, as follows:

$ rg -A5 -uu 'def __invert__' .
./numpy/__init__.pyi
2022: def __invert__(self: NDArray[bool_]) -> NDArray[bool_]: ...
2023- @overload
2024: def __invert__(self: NDArray[_IntType]) -> NDArray[_IntType]: ...
2025- @overload
2026: def __invert__(self: NDArray[object_]) -> Any: ...
2027-
2028- @overload
2029- def __pos__(self: NDArray[_NumberType]) -> NDArray[_NumberType]: ...
2030- @overload
2031- def __pos__(self: NDArray[timedelta64]) -> NDArray[timedelta64]: ...
--
2885: def __invert__(self) -> bool_: ...
2886- __lshift__: _BoolBitOp[int8]
2887- __rlshift__: _BoolBitOp[int8]
2888- __rshift__: _BoolBitOp[int8]
2889- __rrshift__: _BoolBitOp[int8]
2890- __and__: _BoolBitOp[bool_]
--
2993: def __invert__(self: _IntType) -> _IntType: ...
2994- # Ensure that objects annotated as `integer` support bit-wise operations
2995- def __lshift__(self, other: _IntLike_co) -> integer: ...
2996- def __rlshift__(self, other: _IntLike_co) -> integer: ...
2997- def __rshift__(self, other: _IntLike_co) -> integer: ...
2998- def __rrshift__(self, other: _IntLike_co) -> integer: ...

./numpy/array_api/_array_object.py
510: def __invert__(self: Array, /) -> Array:
511- """
512- Performs the operation __invert__.
513- """
514- if self.dtype not in _integer_or_boolean_dtypes:
515- raise TypeError("Only integer or boolean dtypes are allowed in __invert__")

./numpy/lib/user_array.py
179: def __invert__(self):
180- return self._rc(invert(self.array))
181-
182- def _scalarfunc(self, func):
183- if self.ndim == 0:
184- return func(self[0])

./numpy/lib/mixins.pyi
62: def __invert__(self): ...

Which is corresponding to the overriding mentioned above by you?

> while on primitives you get the usual *arithmetic* behaviour, where bool(~False) implicitly is bool(~int(False)) = bool(~0) = bool(-1) = True.

Implicit cast happens here automatically.

> Please take note: (typically!) ~ denotes a bitwise operation on integers, not logical negation on booleans.

Thank you for stressing the point again.

HZ
--
https://mail.python.org/mailman/listinfo/python-list
Re: Understanding the working mechanis of python unary arithmetic operators. [ In reply to ]
On Sunday, October 3, 2021 at 8:38:16 PM UTC+8, ju...@diegidio.name wrote:
> On Sunday, 3 October 2021 at 14:21:13 UTC+2, hongy...@gmail.com wrote:
> > On Sunday, October 3, 2021 at 6:31:05 PM UTC+8, ju...@diegidio.name wrote:
>
> > > Then you can guess that numpy overrides it and gives you *logical* negation of boolean values,
> >
> > I try to dig through the numpy source code to pinning point the overriding/monkey patching/decorating code snippets, as follows:
> And you keep missing the point: look up numpy's *documentation* for that, not any source code.

I find the relevant explanation here [1]:

numpy.invert
[...]
Compute bit-wise inversion, or bit-wise NOT, element-wise.

Computes the bit-wise NOT of the underlying binary representation of the integers in the input arrays. This ufunc implements the C/Python operator ~.
[...]
The ~ operator can be used as a shorthand for np.invert on ndarrays.

x1 = np.array([True, False])

~x1
array([False, True])

[1] https://numpy.org/doc/stable/reference/generated/numpy.invert.html#numpy-invert

HZ
--
https://mail.python.org/mailman/listinfo/python-list
Re: Understanding the working mechanis of python unary arithmetic operators. [ In reply to ]
On Sunday, October 3, 2021 at 9:55:15 PM UTC+8, hongy...@gmail.com wrote:
> On Sunday, October 3, 2021 at 8:38:16 PM UTC+8, ju...@diegidio.name wrote:
> > On Sunday, 3 October 2021 at 14:21:13 UTC+2, hongy...@gmail.com wrote:
> > > On Sunday, October 3, 2021 at 6:31:05 PM UTC+8, ju...@diegidio.name wrote:
> >
> > > > Then you can guess that numpy overrides it and gives you *logical* negation of boolean values,
> > >
> > > I try to dig through the numpy source code to pinning point the overriding/monkey patching/decorating code snippets, as follows:
> > And you keep missing the point: look up numpy's *documentation* for that, not any source code.
> I find the relevant explanation here [1]:
>
> numpy.invert
> [...]
> Compute bit-wise inversion, or bit-wise NOT, element-wise.
>
> Computes the bit-wise NOT of the underlying binary representation of the integers in the input arrays. This ufunc implements the C/Python operator ~.
> [...]
> The ~ operator can be used as a shorthand for np.invert on ndarrays.
>
> x1 = np.array([True, False])
>
> ~x1
> array([False, True])
>
> [1] https://numpy.org/doc/stable/reference/generated/numpy.invert.html#numpy-invert

Or use the following commands in IPython:

import numpy as np
np.invert?
np.info(np.invert)


> HZ
--
https://mail.python.org/mailman/listinfo/python-list
Re: Understanding the working mechanis of python unary arithmetic operators. [ In reply to ]
On Wed, Oct 6, 2021 at 7:52 AM hongy...@gmail.com <hongyi.zhao@gmail.com> wrote:
>
> On Saturday, October 2, 2021 at 4:59:54 PM UTC+8, ju...@diegidio.name wrote:
> > On Saturday, 2 October 2021 at 10:34:27 UTC+2, hongy...@gmail.com wrote:
> > > See the following testings:
> > >
> > > In [24]: a=3.1415926535897932384626433832795028841971
> > > In [27]: -a
> > > Out[27]: -3.141592653589793
> > You've never heard of floating-point? Double precision has 53 significant bits of mantissa, corresponding approximately to 16 decimal digits.
> > <https://en.wikipedia.org/wiki/Double-precision_floating-point_format#IEEE_754_double-precision_binary_floating-point_format:_binary64>
> > > In [17]: ~-+1
> > > Out[17]: 0
> > << The unary ~ (invert) operator yields the bitwise inversion of its integer argument. The bitwise inversion of x is defined as -(x+1). It only applies to integral numbers or to custom objects that override the __invert__() special method. >>
> > <https://docs.python.org/3/reference/expressions.html#unary-arithmetic-and-bitwise-operations>
>
> A further inference based on the above description:
>
> Let us consider this equation: -(x+1) = x, the solution is -0.5, which is not an integer. So we can safely come to a conclusion:
>
> If bool(a) == True, \forall a \in integer, then ~bool(a) == False; and vice versa.
>

If bool(a) is True, then ~bool(a) is exactly the same as writing
~True, and a has become irrelevant. That is simply how expression
evaluation works.

ChrisA
--
https://mail.python.org/mailman/listinfo/python-list
Re: Understanding the working mechanis of python unary arithmetic operators. [ In reply to ]
On 06/10/2021 10.10, Chris Angelico wrote:
> On Wed, Oct 6, 2021 at 7:52 AM hongy...@gmail.com <hongyi.zhao@gmail.com> wrote:
>>
>> On Saturday, October 2, 2021 at 4:59:54 PM UTC+8, ju...@diegidio.name wrote:

This thread seems to have been very one-sided. Either I've forgotten
selective use of the DEL-key, or the above contributor has been
forgetting to reply to the list (or didn't intend contribution?) Please
share your knowledge with all!


>>> On Saturday, 2 October 2021 at 10:34:27 UTC+2, hongy...@gmail.com wrote:

> If bool(a) is True, then ~bool(a) is exactly the same as writing
> ~True, and a has become irrelevant. That is simply how expression
> evaluation works.

@Chris and I presented at a recent PUG meeting on the subject of
'operators'.
(I was the 'warm-up act', @Chris the 'star'...)

I covered unary operators
(https://docs.python.org/3/reference/expressions.html#unary-arithmetic-and-bitwise-operations)
- and very briefly, because that's proportional to their application 'in
the real world'. Negation is sometimes used, binary inversion very
occasionally, but the 'unary plus' almost never!

Thus:

>>> a = 3
>>> +a
3
>>> -a
-3

Why would one use the plus operator?

Particularly when it confuses some, ie if negation changes the sign,
won't the unary-plus?

>>> b = -3
>>> +b
-3
>>> -b
3

What has the unary-plus achieved in either/both of these cases? Not
much, but may not be doing something that was 'expected'!

The bitwise inversion (~) is also widely misunderstood (just like the
story of my life). It is not "bit inversion", as in, a single bit being
inverted:
(values here are expressed in base-2!)

~0 -> 1
~1 -> 0

Instead, it involves the inversion of every bit. Thus, if we are talking
about a nibble/nybble (because I'm too lazy to type more binary digits):

~0000 -> 1111
~0001 -> 1110

which accounts for the problem discussed earlier in the thread.

To make things work the way you seemed to imagine:

~1111 -> 0000 # and thus, is False
~0000 -> 1111 # and thus, is True

ie a bitwise inter-change that works binary ints and booleans.


Where some (other) thinking may have come-adrift from Python's model, is
the mixing of objects/types, eg the 'truthiness' of any integer other
than 0. Also, whilst coercion from one type to another may work
satisfactorily in one 'direction', it may not be so amenable in reverse.


Another bemusing (OP) point was the concept of "-+~1". I'd never, ever,
think of doing that! Hey, maybe that says something about me?

The term "unary operator" involves the word "one". Rather than
"operator", the "one" is the number of "operands". (yes, you know this)
However, having already talked about the infrequency with which
unary-operators are employed, the idea of nesting (is that the word?) a
series of unary-operators, almost blew my mind. Why? Please show an
example scenario...


Finally, there is the process of "over-loading" operators. Thus, "1 + 2"
translates to "add the value 2 to 1"; whereas "a" + "b" means
"concatenate" the two strings. In both cases, the result becomes a third
value. When we choose the correct terminology, the words for "+" are
different - as are the resultant processes!

We could also code "instance_a + instance_b". What does this mean?
Addition? Concatenation? Bitwise?

If I tell you that both are instances of MyClass, does that answer the
question?

The only way to work-out what craziness I hold in store, is to find
where MyClass is defined and look for the __add__() 'magic method'*. At
which point, you discover that the instance-attributes are split into
components, and the components merged together in a random sequence,
with today's date mixed-in for (no) good measure.

* or you could ask me
(although neither explanation will have a +impact on your mental health)


So, the fact that two object instances, eg an integer and a
floating-point number, both utilise the same operator-symbol, enables us
to draw analogies (and in this case, probably get it 100% correct), but
this does not imply a complete equivalence across-the-board
(particularly when crazy-people are let-loose with custom classes! Thus
"a" + "b" should not be pronounced "add", even though the operator looks
very much like the one we use to add two numbers!

For fun, and quickly now, what happens here:

2 + 2
2 + 2.0
2.0 + 2
2.0 + 2.0
"2" + "2"
2 + "2"
"2" + 2

(they're all 'the same', except the last two?three - aren't they???)

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list
RE: Understanding the working mechanis of python unary arithmetic operators. [ In reply to ]
Dave,

Just one point.

many things are allowed by a language even if normal people would NOT have
any reason to do it NOR should use it.

Although when used in one context + and - can be considered unary operators,
the evaluation may result in successive unary operations being done one
after another. Here are examples I just typed:

+1
1
+++++1
1
+-+-+-1
-1
---1
-1
--1
1

Luckily since Python has no ++ or -- pre or post operators, these are legal,
albeit a tad weird.



-----Original Message-----
From: Python-list <python-list-bounces+avigross=verizon.net@python.org> On
Behalf Of dn via Python-list
Sent: Tuesday, October 5, 2021 7:11 PM
To: python-list@python.org
Subject: Re: Understanding the working mechanis of python unary arithmetic
operators.

On 06/10/2021 10.10, Chris Angelico wrote:
> On Wed, Oct 6, 2021 at 7:52 AM hongy...@gmail.com <hongyi.zhao@gmail.com>
wrote:
>>
>> On Saturday, October 2, 2021 at 4:59:54 PM UTC+8, ju...@diegidio.name
wrote:

This thread seems to have been very one-sided. Either I've forgotten
selective use of the DEL-key, or the above contributor has been forgetting
to reply to the list (or didn't intend contribution?) Please share your
knowledge with all!


>>> On Saturday, 2 October 2021 at 10:34:27 UTC+2, hongy...@gmail.com wrote:

> If bool(a) is True, then ~bool(a) is exactly the same as writing
> ~True, and a has become irrelevant. That is simply how expression
> evaluation works.

@Chris and I presented at a recent PUG meeting on the subject of
'operators'.
(I was the 'warm-up act', @Chris the 'star'...)

I covered unary operators
(https://docs.python.org/3/reference/expressions.html#unary-arithmetic-and-b
itwise-operations)
- and very briefly, because that's proportional to their application 'in the
real world'. Negation is sometimes used, binary inversion very occasionally,
but the 'unary plus' almost never!

Thus:

>>> a = 3
>>> +a
3
>>> -a
-3

Why would one use the plus operator?

Particularly when it confuses some, ie if negation changes the sign, won't
the unary-plus?

>>> b = -3
>>> +b
-3
>>> -b
3

What has the unary-plus achieved in either/both of these cases? Not much,
but may not be doing something that was 'expected'!

The bitwise inversion (~) is also widely misunderstood (just like the story
of my life). It is not "bit inversion", as in, a single bit being
inverted:
(values here are expressed in base-2!)

~0 -> 1
~1 -> 0

Instead, it involves the inversion of every bit. Thus, if we are talking
about a nibble/nybble (because I'm too lazy to type more binary digits):

~0000 -> 1111
~0001 -> 1110

which accounts for the problem discussed earlier in the thread.

To make things work the way you seemed to imagine:

~1111 -> 0000 # and thus, is False
~0000 -> 1111 # and thus, is True

ie a bitwise inter-change that works binary ints and booleans.


Where some (other) thinking may have come-adrift from Python's model, is the
mixing of objects/types, eg the 'truthiness' of any integer other than 0.
Also, whilst coercion from one type to another may work satisfactorily in
one 'direction', it may not be so amenable in reverse.


Another bemusing (OP) point was the concept of "-+~1". I'd never, ever,
think of doing that! Hey, maybe that says something about me?

The term "unary operator" involves the word "one". Rather than "operator",
the "one" is the number of "operands". (yes, you know this) However, having
already talked about the infrequency with which unary-operators are
employed, the idea of nesting (is that the word?) a series of
unary-operators, almost blew my mind. Why? Please show an example
scenario...


Finally, there is the process of "over-loading" operators. Thus, "1 + 2"
translates to "add the value 2 to 1"; whereas "a" + "b" means "concatenate"
the two strings. In both cases, the result becomes a third value. When we
choose the correct terminology, the words for "+" are different - as are the
resultant processes!

We could also code "instance_a + instance_b". What does this mean?
Addition? Concatenation? Bitwise?

If I tell you that both are instances of MyClass, does that answer the
question?

The only way to work-out what craziness I hold in store, is to find where
MyClass is defined and look for the __add__() 'magic method'*. At which
point, you discover that the instance-attributes are split into components,
and the components merged together in a random sequence, with today's date
mixed-in for (no) good measure.

* or you could ask me
(although neither explanation will have a +impact on your mental health)


So, the fact that two object instances, eg an integer and a floating-point
number, both utilise the same operator-symbol, enables us to draw analogies
(and in this case, probably get it 100% correct), but this does not imply a
complete equivalence across-the-board (particularly when crazy-people are
let-loose with custom classes! Thus "a" + "b" should not be pronounced
"add", even though the operator looks very much like the one we use to add
two numbers!

For fun, and quickly now, what happens here:

2 + 2
2 + 2.0
2.0 + 2
2.0 + 2.0
"2" + "2"
2 + "2"
"2" + 2

(they're all 'the same', except the last two?three - aren't they???)

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

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