I am reading an Intro to Python textbook and came across this line:
Operators on the same row have equal precedence and are applied left to right, except for exponentiation, which is applied right to left.
I understand most of this, but I do not understand why they say exponentiation is applied right to left. They do not provide any examples either. Also, am I allowed to ask general questions like this, or are only problem solving questions preferred?
The ** operator follows normal mathematical conventions; it is right-associative:
In the usual computer science jargon, exponentiation in mathematics is right-associative, which means that xyz should be read as x(yz), not (xy)z. In expositions of the BODMAS rules that are careful enough to address this question, the rule is to evaluate the top exponent first.
and from Wikipedia on the Order of Operations:
If exponentiation is indicated by stacked symbols, the usual rule is to work from the top down, because exponention is right-associative in mathematics.
So 2 ** 3 ** 4 is calculated as 2 ** (3 ** 4) (== 2417851639229258349412352) not (2 ** 3) ** 4 (== 4096).
This is pretty universal across programming languages; it is called right-associativity, although there are exceptions, with Excel and MATLAB being the most notable.
from http://docs.python.org/reference/expressions.html
Operators in the same box group left to right (except for comparisons, including tests, which all have the same precedence and chain from left to right — see section Comparisons — and exponentiation, which groups from right to left).
>>> 2 ** 2 ** 2
16
>>> 2 ** 2 ** 2 ** 2
65536
>>> (2 ** 2 ** 2) ** 2
256
For the middle case 2 ** 2 ** 2 ** 2, this are the intermediate steps -
broken down to 2 ** (2 ** (2 ** 2))
2 ** (2 ** (4)) # progressing right to left
2 ** (16) # this is 2 to the power 16
which finally evals to 65536
Hope that helps!
This explanation seems quite clear to me. Let me show you an example that might enlighten this :
print 2 ** 2 ** 3 # prints 256
If you would read this from left to right, you would first do 2 ** 2, which would result in 4, and then 4 ** 3, which would give us 64.
It seems we have a wrong answer. :)
However, from right to left...
You would first do 2 ** 3, which would be 8, and then, 2 ** 8, giving us 256 !
I hope I was able to enlighten this point for you. :)
EDIT : Martijn Pieters answered more accurately to your question, sorry. I forgot to say it was mathematical conventions.
Power operator, exponentiation, is handled differently across applications and languages.
If it has LEFT associativity then 2^3^4 = (2^3)^4 = 4096.
If it has RIGHT associativity then 2^3^4 = 2^(3^4) = 2417851639229260000000000.
In Excel, Matlab, Apple Numbers and more others exponentiation has LEFT associativity.
In Python, Ruby, Google Sheets, ... - RIGHT associativity.
Here is a vast list of how different languages and apps handle exponentiation: Exponentiation Associativity and Standard Math Notation
Related
I want to know why does the following happen.
The code below evaluates right side 1**3 first then 2**1
2**1**3 has the value of 2
However, for the below code left side 7//3 is evaluated first then 2*3. Finally 1+6-1=6.
1+7//3*3-1 has the value of 6
Take a look at the documentation of operator precedence. Although multiplication * and floor division // have the same precedence, you should take note of this part:
Operators in the same box group left to right (except for exponentiation, which groups from right to left).
For the convention of 213 being evaluated right-associative, see cross-site dupe on the math stackexchange site: What is the order when doing xyz and why?
The TL;DR is this: since the left-associative version (xy)z would just equal xy*z, it's not useful to have another (worse) notation for the same thing, so exponentiation should be right associative.
Almost all operators in Python (that share the same precedence) have left-to-right associativity. For example:
1 / 2 / 3 ≡ (1 / 2) / 3
One exception is the exponent operator which is right-to-left associativity:
2 ** 3 ** 4 ≡ 2 ** (3 ** 4)
That's just the way the language is defined, matching mathematical notation where abc ≡ a(bc).
If it were (ab)c, that would just be abc.
Per Operator Precedence, the operator is right associative: a**b**c**d == a**(b**(c**d)).
So, if you do this:
a,b,c,d = 2,3,5,7
a**b**c**d == a**(b**(c**d))
you should get true after a looooong time.
The Exponent operator in python has a Right to Left precedence. That is out of all the occurrences in an expression the calculation will be done from Rightmost to Leftmost. The exponent operator is an exception among all the other operators as most of them follow a Left to Right associativity rule.
2**1**3 = 2
The expression
1+7//3*3-1
It is a simple case of Left to Right associativity. As // and * operator share the same precedence, Associativity(one is the Left) is taken into account.
This is just how math typically works
213
This is the same as the first expression you used. To evaluate this with math, you'd work your way down, so 13=1 and then 21 which equals 2.
You can make sense of this just by thinking about the classic PEMDAS (or Please Excuse My Dear Aunt Sally) order of operations from mathematics. In your first one, 2**1**3 is equivalent to , which is really read as . Looking at it this way, you see that you do parenthesis (P) first (the 1**3).
In the second one, 1+7//3*3-1 == 6 you have to note that the MD and AS of PEMDAS are actually done in order of whichever comes first reading from left-to-right. It's simply a fault of language that we have to write one letter before another (that is, we could write this as PEDMAS and it still be correct if we treat the D and M appropriately).
All that to say, Python is treating the math exactly the same way as we should even if this were written with pen and paper.
I've been programming in Python for years but something extremely trivial has surprised me:
>>> -1 ** 2
-1
Of course, squaring any negative real number should produce a positive result. Probably Python's math is not completely broken. Let's look at how it parsed this expression:
>>> ast.dump(ast.parse('-1 ** 2').body[0])
Expr(
value=UnaryOp(
op=USub(),
operand=BinOp(
left=Num(n=1),
op=Pow(),
right=Num(n=2)
)
)
)
Ok, so it is treating it as if I had written -(1 ** 2). But why is the - prefix to 1 being treated as a separate unary subtraction operator, instead of the sign of the constant?
Note that the expression -1 is not parsed as the unary subtraction of the constant 1, but just the constant -1:
>>> ast.dump(ast.parse('-1').body[0])
Expr(
value=Num(n=-1)
)
The same goes for -1 * 2, even though it is syntactically nearly identical to the first expression.
>>> ast.dump(ast.parse('-1 * 2').body[0])
Expr(
value=BinOp(
left=Num(n=-1),
op=Mult(),
right=Num(n=2)
)
)
This behavior turns out to be common to many languages including perl, PHP, and Ruby.
It behaves just like the docs explain here:
2.4.4. Numeric literals
[...] Note that numeric literals do not include a sign; a phrase like -1 is actually an expression composed of the unary operator - and the literal 1.
and here:
6.5. The power operator
The power operator binds more tightly than unary operators on its
left; [...]
See also the precedence table from this part. Here is the relevant part from that table:
Operator | Description
-------------|---------------------------------
* | Multiplication, ...
+x, -x, ~x | Positive, negative, bitwise NOT
** | Exponentiation
This explains why the parse tree is different between the ** and * examples.
When I run my python 3 program:
exp = 211
p = 199
q = 337
d = (exp ** (-1)) % ((p - 1)*(q - 1))
results in 211^(-1).
But when I run the calculation in wolfram alpha I get the result I was expecting.
I did some test outputs and the variables exp, p and q in the program are all the integer values I used in wolfram alpha.
My goal is to derive a private key from a (weakly) encrypted integer.
If I test my wolfram alpha result, I can decrypt the encrypted message correctly.
Wolfram Alpha is computing the modular inverse. That is, it's finding the integer x such that
exp*x == 1 mod (p - 1)*(q - 1)
This is not the same as the modulo operator %. Here, Python is simply calculating the remainder when 1/exp is divided by (p - 1)*(q - 1) when given the expression in your question.
Copying the Python code from this answer, you can compute the desired value with Python too:
>>> modinv(exp, (p - 1)*(q - 1))
45403
Wolfram Alpha does not have well-defined syntax. It takes arbitrary text you provide and attempts to figure out what you meant by that input. In this case, it decided you were probably looking for a modular inverse, and it gave you one.
Python has well-defined syntax. In Python, the parser does not take the ** and the % together and guess that that combination makes the two operators have a meaning other than their usual meaning. The ** is computed the usual way, and then % is the modulo operator. If you want a modular inverse, you'll have to write one yourself.
I think the idea here is that wolfram alpha and python define the modulo operation differently depending on the fact that you are dealing with integers or real numbers.
In this case, Wolfram Alpha is using the modulo inverse because it detects the first number is 0 < x < 1
More information about the definition on real numbers here
Python evaluates immediately (211^(-1) gets computed as 0.004739... and not ekpt as 1/211) and the modular Euclidan remainder for x and y is conventinally defined as x-floor(x/y)*y if any of x,y is a rational number. If you do your calculation with some dedicated number theoretic program like e.g.: GP/Pari
ep = 211;p = 199;q = 337;(ep ^ (-1)) % ((p - 1)*(q - 1))
you will get the result you expected to get because a) it keeps fractions as fractions as long as possible and b) knows about modular arithmetic.
Is you like Python you may take a look at the programms an libraries offered at SciPy. SymPy might be what you are looking for.
ok so I am feeling a little stupid for not knowing this, but a coworker asked so I am asking here: I have written a python algorithm that solves his problem. given x > 0 add all numbers together from 1 to x.
def intsum(x):
if x > 0:
return x + intsum(x - 1)
else:
return 0
intsum(10)
55
first what is this type of equation is this and what is the correct way to get this answer as it is clearly easier using some other method?
This is recursion, though for some reason you're labeling it like it's factorial.
In any case, the sum from 1 to n is also simply:
n * ( n + 1 ) / 2
(You can special case it for negative values if you like.)
Transforming recursively-defined sequences of integers into ones that can be expressed in a closed form is a fascinating part of discrete mathematics -- I heartily recommend Concrete Mathematics: A Foundation for Computer Science, by Ronald Graham, Donald Knuth, and Oren Patashnik (see. e.g. the wikipedia entry about it).
However, the specific sequence you show, fac(x) = fac(x - 1) + x, according to a famous anecdote, was solved by Gauss when he was a child in first grade -- the teacher had given the pupils the taksk of summing numbers from 1 to 100 to keep them quet for a while, but two minutes later there was young Gauss with the answer, 5050, and the explanation: "I noticed that I can sum the first, 1, and the last, 100, that's 101; and the second, 2, and the next-to-last, 99, and that's again 101; and clearly that repeats 50 times, so, 50 times 101, 5050". Not rigorous as proofs go, but quite correct and appropriate for a 6-years-old;-).
In the same way (plus really elementary algebra) you can see that the general case is, as many have already said, (N * (N+1)) / 2 (the product is always even, since one of the numbers must be odd and one even; so the division by two will always produce an integer, as desired, with no remainder).
Here is how to prove the closed form for an arithmetic progression
S = 1 + 2 + ... + (n-1) + n
S = n + (n-1) + ... + 2 + 1
2S = (n+1) + (n+1) + ... + (n+1) + (n+1)
^ you'll note that there are n terms there.
2S = n(n+1)
S = n(n+1)/2
I'm not allowed to comment yet so I'll just add that you'll want to be careful in using range() as it's 0 base. You'll need to use range(n+1) to get the desired effect.
Sorry for the duplication...
sum(range(10)) != 55
sum(range(11)) == 55
OP has asked, in a comment, for a link to the story about Gauss as a schoolchild.
He may want to check out this fascinating article by Brian Hayes. It not only rather convincingly suggests that the Gauss story may be a modern fabrication, but outlines how it would be rather difficult not to see the patterns involved in summing the numbers from 1 to 100. That in fact the only way to miss these patterns would be to solve the problem by writing a program.
The article also talks about different ways to sum arithmetic progressions, which is at the heart of OP's question. There is also an ad-free version here.
Larry is very correct with his formula, and its the fastest way to calculate the sum of all integers up to n.
But for completeness, there are built-in Python functions, that perform what you have done, on lists with arbitrary elements. E.g.
sum()
>>> sum(range(11))
55
>>> sum([2,4,6])
12
or more general, reduce()
>>> import operator
>>> reduce(operator.add, range(11))
55
Consider that N+1, N-1+2, N-2+3, and so on all add up to the same number, and there are approximately N/2 instances like that (exactly N/2 if N is even).
What you have there is called arithmetic sequence and as suggested, you can compute it directly without overhead which might result from the recursion.
And I would say this is a homework despite what you say.
What is the difference between the following statements?
Statement 1:
var=2**2*3
Statement 2:
var2=2*2*3
I see no difference.
This raises the following question.
Why is Statement 1 used if we can use Statement 2?
Try:
2**3*2
and
2*3*2
to see the difference.
** is the operator for "power of". In your particular operation, 2 to the power of 2 yields the same as 2 times 2.
Double stars (**) are exponentiation. So "2 times 2" and "2 to the power 2" are the same. Change the numbers and you'll see a difference.
2**2 means 2 squared (2^2)
2*2 mean 2 times 2 (2x2)
In this case they happen to have the same value, but...
3**3*4 != 3*3*4
For visual learners.........................
To specifically answer your question Why is the code1 used if we can use code2? I might suggest that the programmer was thinking in a mathematically broader sense. Specifically, perhaps the broader equation is a power equation, and the fact that both first numbers are "2" is more coincidence than mathematical reality. I'd want to make sure that the broader context of the code supports it being var = x * x * y in all cases, rather than in this specific case alone. This could get you in big trouble if x is anything but 2.
2**2 = 2 power-of 2
2*2 = 2 times 2
The ** operator in Python is really "power;" that is, 2**3 = 8.
The top one is a "power" operator, so in this case it is the same as 2 * 2 equal to is 2 to the power of 2. If you put a 3 in the middle position, you will see a difference.
A double asterisk means to the power of. A single asterisk means multiplied by. 22 is the same as 2x2 which is why both answers came out as 4.
Power has more precedence than multiply, so:
2**2*3 = (2^2)*3
2*2*3 = 2*2*3