In some academic books I found that python, for its arithmetic operators, has specific priorities and associativities that guide the order of execution of operations.
Here are the related values for the basic arithmetic operators (table found in a python book and consistent with other websites, such as https://www.programiz.com/python-programming/precedence-associativity ):
However, when I perform some expressions in python, I get a result that is not consistent with that hierarchy and associativity of operations:
I give examples:
>>>-13//-2
6
Which is consistent (first the sign change of both terms (-13) and (-2) is performed and then the integer division.
>>>1-13//-2
8
Which is also consistent. Following the reasoning given in the table, first the sign of 2 → (-2) would be changed, then the integer division is performed, which gives -7, since -7 is the value less than -6.5, which would give the result of the division normal; Finally, the subtraction 1-(-7) = 8 should be performed and from there the result.
However, when performing:
>>>13//-2%2
1
This result does not seem to obey the left associativity of the integer division and modulo operators belonging to the same precedence (hierarchy). I also can't get to the same result by following precedence and associativity. Since the sign change 2→(-2) should be done first, then the integer division should be associated from the left, giving (-7) and finally the modulo operation whose result should be -1 should be done.
Is there anything you're not taking into account? Is my way of using precedence and associativity values wrong? Or is it due to some consideration about python that I am unaware of.
Thanks in advance.
Your understanding of precedence and associativity is correct. What you are not taking into account is that the result of the module is positive:
This is because (by convention) in Python the result of the modulus operation always has the same sign as the divisor (2 in this case). This convention is different from the one used by C for example, in which the sign of the numerator is preserved.
Why?
The logic behind this decision is that it is often more useful to do so in practice. For example, consider using modulo 7 to calculate the day of the week. If the year started on Monday and it is January 27, what day of the week is it?
Response:
I mean, it would be Sunday. And what day of the week is 28 days before?
I mean, it was also Sunday. In a language like C the result would have been -1, which is not valid as a day of the week (and would have to be corrected by adding 7).
Notice that in modulo 7, -1 equals 6 (or 6 equals -1, whichever you prefer).
In the particular case in which you divide by 2, things are more confusing, since -1 is equal to 1. It is not simply a matter of changing the sign of the result if it is negative, but of adding the divisor to it. Only in this particular case -1 results in 1, hence probably your confusion.
To complement abulafia's answer, I recommend you always consult the official documentation . there we read
What translated medium is it?
And to answer one of your questions, the way you understand operator precedence in Python is correct . (I am not going to put the complete table of the official documentation because it is very long)
PS In my opinion, Python is one of the best documented projects.