Python % Percent - python

I was wondering if anyone can help me understand the following Python calculation which the answer calculates into 97:
100 - 25 * 3 % 4
I understand that the % sign in Python represents the remaining of an amount, however, I'm still not seeing how the answer comes out to 97. If someone could break the calculation down for so I understand it I would very grateful.. Thanks!

The operators * and % are evaluated first 1. Both have the same precedence, so they are evaluated from left to right 2. Then the operator - is evaluated:
100 - 25 * 3 % 4
100 - 75 % 4
100 - 3
97
1: Because of operators precedence
2: Operator are left-associative, in other words, the two leftmost items will be operated on, then the result and the 3rd item will be operated on, so on

It's just to do with what is evaluated in what order by Python:
Explanation of your sum
* and % take precedence over -, so we first evaluate 25 * 3 % 4. * and % have the same priority and associativity from left to right, so we evaluate from left to right, starting with 25 * 3. This yields 75. Now we evaluate 75 % 4, yielding 3. Finally, 100 - 3 is 97.

Let me add brackets to make it unambigious:
100 - ((25 * 3) % 4)
First, the multiplication: 25 * 3 = 75.
Then, the modulus: 75 % 4 = 3.
And finally, 100 - 3 = 97.

So following the normal order of operations, you get:
25 * 3 = 75
75 / 4 = 18 R 3
100 - 3 = 97

Related

Why is 2 * x * x faster than 2 * ( x * x ) in Python 3.x, for integers?

The following Python 3.x integer multiplication takes on average between 1.66s and 1.77s:
import time
start_time = time.time()
num = 0
for x in range(0, 10000000):
# num += 2 * (x * x)
num += 2 * x * x
print("--- %s seconds ---" % (time.time() - start_time))
if I replace 2 * x * x with 2 *(x * x), it takes between 2.04 and 2.25. How come?
On the other hand it is the opposite in Java: 2 * (x * x) is faster in Java. Java test link: Why is 2 * (i * i) faster than 2 * i * i in Java?
I ran each version of the program 10 times, here are the results.
2 * x * x | 2 * (x * x)
---------------------------------------
1.7717654705047607 | 2.0789272785186768
1.735931396484375 | 2.1166207790374756
1.7093875408172607 | 2.024367570877075
1.7004504203796387 | 2.047525405883789
1.6676218509674072 | 2.254328966140747
1.699510097503662 | 2.0949244499206543
1.6889283657073975 | 2.0841963291168213
1.7243537902832031 | 2.1290600299835205
1.712965488433838 | 2.1942825317382812
1.7622807025909424 | 2.1200053691864014
First of all, note that we don't see the same thing in Python 2.x:
>>> timeit("for i in range(1000): 2*i*i")
51.00784397125244
>>> timeit("for i in range(1000): 2*(i*i)")
50.48330092430115
So this leads us to believe that this is due to how integers changed in Python 3: specifically, Python 3 uses long (arbitrarily large integers) everywhere.
For small enough integers (including the ones we're considering here), CPython actually just uses the O(MN) grade-school digit by digit multiplication algorithm (for larger integers it switches to the Karatsuba algorithm). You can see this yourself in the source.
The number of digits in x*x is roughly twice that of 2*x or x (since log(x2) = 2 log(x)). Note that a "digit" in this context is not a base-10 digit, but a 30-bit value (which are treated as single digits in CPython's implementation). Hence, 2 is a single-digit value, and x and 2*x are single-digit values for all iterations of the loop, but x*x is two-digit for x >= 2**15. Hence, for x >= 2**15, 2*x*x only requires single-by-single-digit multiplications whereas 2*(x*x) requires a single-by-single and a single-by-double-digit multiplication (since x*x has 2 30-bit digits).
Here's a direct way to see this (Python 3):
>>> timeit("a*b", "a,b = 2, 123456**2", number=100000000)
5.796971936999967
>>> timeit("a*b", "a,b = 2*123456, 123456", number=100000000)
4.3559221399999615
Again, compare this to Python 2, which doesn't use arbitrary-length integers everywhere:
>>> timeit("a*b", "a,b = 2, 123456**2", number=100000000)
3.0912468433380127
>>> timeit("a*b", "a,b = 2*123456, 123456", number=100000000)
3.1120400428771973
(One interesting note: If you look at the source, you'll see that the algorithm actually has a special case for squaring numbers (which we're doing here), but even still this is not enough to overcome the fact that 2*(x*x) just requires processing more digits.)
Python intern representation of integers is special, it uses slots of 30 bits :
In [6]: sys.getsizeof(2**30-1)
Out[6]: 28 # one slot + heading
In [7]: sys.getsizeof(2**30)
Out[7]: 32 # two slots
So everything happens as if Python counts in base B = 2**30 = 1 073 741 824 ~1 billion.
For a human who want to calculate 2*4*4, two ways :
(2*4)*4 = 8*4 =32 = 30 + 2 is immediate if you knows your add tables.
2*(4*4) = 2*16 = 2*10 + 2*6 = (2*10+10) + 2 = 30 + 2 since we have to put the operation down.
Python have the same problem. If x is a number such than 2x < B < x² , let x² = aB+b , with a,b <B. x² is stored in 2 slots, which I note (a|b). Computations leads to (without managing carries here):
(x*x)*2 => (a|b)*2 => (2*a|2*b)
(2*x)*x => (2x)*x =>(2a|2b)
in the first case the 2* operation is done two times, against only one in the first case. That explains the difference.
If your benchmark is right (didn't check), it may come from the fact that Python integers may be two different things : native integers when they are small (with a quick computation), and big integers when they increase in size (slower computation). The first syntax keeps the size smaller after the first operation while the second syntax may lead to two operations involving big integers.
From what I can tell, it comes down to a little bit more memory access in the version using 2 * (x * x). I printed the disassembled bytecode and it seems to prove that:
Relevant part of 2 * x * x:
7 28 LOAD_FAST 1 (num)
30 LOAD_CONST 3 (2)
32 LOAD_FAST 2 (x)
34 BINARY_MULTIPLY
36 LOAD_FAST 2 (x)
38 BINARY_MULTIPLY
40 INPLACE_ADD
42 STORE_FAST 1 (num)
44 JUMP_ABSOLUTE 24
Relevant part of 2 * (x * x):
7 28 LOAD_FAST 1 (num)
30 LOAD_CONST 3 (2)
32 LOAD_FAST 2 (x)
34 LOAD_FAST 2 (x)
36 BINARY_MULTIPLY <=== 1st multiply x*x in a temp value
38 BINARY_MULTIPLY <=== then multiply result with 2
40 INPLACE_ADD
42 STORE_FAST 1 (num)
44 JUMP_ABSOLUTE 24

Order of Operations - Python 3

Can someone explain why c is equal to 25 and not 30? I keep getting 30 by multiplying a*(b//a) and then adding b to it after.
a=10
b=3*(a-5)
c=b+(b//a)*a
Just do it step by step and you'll see that you're doing
c = 15 + 1*10
Hence c is 25. b//a is floor division, meaning 15/10 becomes 1
An easy way to understand whats going on is to print each steps:
a=10
b=3*(a-5)
print(b)
print(b//a)
print((b//a)*a)
print(b+(b//a)*a)
c=b+(b//a)*a
output
15
1
10
25
(15//10) is equal to 1 so the formula for c is equivalent to 15+1*10 The // operator is floor division which round down to the nearest integer. In additon all the values you are using are integers. To get 30 you need to use the normal divsion operator / and case one of the operands in the division to a floating point number, like this: c = b+(float(b)/a)*a That code sets c to 30.0.
c = b + (b//a)*a = b + ((b//a)*a) = 15 + ((15//10)*10) = 15 + (1*10) = 25
Does this clear it up?
The crucial part is 15//10, because // performs integer division which rounds down to the next integer. Note the difference between / and // in Python 3.
>>> 15/10
1.5
>>> 15//10
1

Fast modular exponentiation, help me find the mistake

I am trying to implement a scheme of fast exponentiation. Degree is represented in binary form:
def pow_h(base, degree, module):
degree = bin(degree)[2:]
r = 1
for i in range(len(degree) - 1, -1, -1):
r = (r ** 2) % module
r = (r * base ** int(degree[i])) % module
return r
But function is not working properly, where is the mistake?
As I said in the comments, the built-in pow function already does fast modular exponentiation, but I guess it's a reasonable coding exercise to implement it yourself.
Your algorithm is close, but you're squaring the wrong thing. You need to square base, not r, and you should do it after the multiplying step.
def pow_h(base, degree, module):
degree = bin(degree)[2:]
r = 1
for i in range(len(degree) - 1, -1, -1):
r = (r * base ** int(degree[i])) % module
base = (base ** 2) % module
return r
#test
for i in range(16):
print(i, 2**i, pow_h(2, i, 100))
output
0 1 1
1 2 2
2 4 4
3 8 8
4 16 16
5 32 32
6 64 64
7 128 28
8 256 56
9 512 12
10 1024 24
11 2048 48
12 4096 96
13 8192 92
14 16384 84
15 32768 68
Using r * base ** int(degree[i]) is a cute trick, but it's probably more efficient to use a if statement than exponentiation. And you can use arithmetic to get the bits of degree, rather than using string, although bin is rather efficient. Anyway, here's my version:
def pow_h(base, power, modulus):
a = 1
while power:
power, d = power // 2, power % 2
if d:
a = a * base % modulus
base = base * base % modulus
return a
Such fast exponentiation must act differently if the current exponent is even or odd, but you have no such check in your code. Here are some hints:
To find x**y, you need an "accumulator" variable to hold the value calculated so far. Let's use a. So you are finding a*(x**y), with your code decreasing y and increasing a and/or x until y becomes zero and a is your final answer.
If y is even, say y==2*k, then a*x**(2*k) == a*(x**2)**k. This decreased y to y//2 and increased x to x**2.
If y is odd, say y==2k+1, then a*x**(2*k+1) == (a*x)*x**(2*k). This decreased y to y-1 and increased a to a*x.
You should be able to figure the algorithm from here. I did not include using the modulus: that should be easy.

modulus of negative numbers in Python [duplicate]

This question already has answers here:
How does the modulo (%) operator work on negative numbers in Python?
(12 answers)
Closed last month.
23 % -5 = -2
23 % 5 = 3
Can someone explain to me how I can understand this because I have an exam tomorrow. I want to say its because -5 * -5 =25 then 25 -2 = 23 which is how they get the 23. Is this correct?
In Python, the sign of the remainder is the same as the sign of the denominator (which differs from languages like C, where it is the same as the sign of the numerator).
Mathematically, you are always guaranteed that if a, b = divmod(n, d), then a*d + b == n.
Note that 23//5 == 4 and 23//-5 == -5 (Python always does floor division). Thus, we have 4*5 + 3 == 23 and -5*-5 - 2 == 23, as you have said.
Lets write it out as N=kM+R.
We have 23 = -5*(-5) - 2, and 23 = 4*5 + 3.
The simplest way of looking at problem for your purposes is to consider the definition that:
a mod n = R where the remainder R must satisfy 0<= R
So for mod -5 arithmetic, 0<= R < -4 i.e. R can be one of 0, -1, -2, -3, -4
that is you effectively subtract (or add) n from a until you bring R into the range above:
So
23 % 5 is (23-4*5) = 23-20 = 3
but
23 % -5 is (23+5*(-5)) = 23-25 = -2
Well, 23 % 5 = 3 since 4*5 = 20 and when you divide 23 by 20 you obtain a remainder of 3. You can think of it as the closet you can go without going over.
As for 23 % -5, well that answer differs from one programming language to another.
For Python it's -2 because it will always return the value of the divisor and it's because 5*5 = 25 and when you divide 23 by 25 in Python you obtain a remainder of -2 (since it must be negative because the divisor was negative) so we have 25 - 2 = 23.
It's worth noting that the formal mathematical definition states that b is a positive integer.
% in Python uses "Modulo operation" ; it's different from taking the reminder of a division operation such that.
a - int(a/n) * n
although it is sometimes equivalent in some computer languages.
The math expression can be found explict here: http://en.wikipedia.org/wiki/Modulo_operation
So obviously, in Python "%" operation uses the following expression:
mod(a, n) = a - n * floor(a / n)
Therefore,
23%-5 = mod(23,-5) = 23 - (-5) * floor(23/-5) = 23 - (-5) * -5 = -2
and
23%5 = mod(23, 5) = 23 - 5 * floor(23/5) = 23 - 5 * 4 = 3
In addition, you my find it's interesting that
-23%5 = mod(-23,5) = (-23) - 5 * floor(-23/5) = -23 - 5 * (-5) = 2
since floor() action will take the integer value toward negative infinity.

List comprehension in Haskell, Python and Ruby

I have started looking at the project Euler site as a way to learn Haskell, and improve my Python and Ruby. I think the Haskell and Python versions are ok, but I'm sure there must be a cleaner way for Ruby.
This is not about how can I make one language look like another one.
This is Problem 1:
Q: Add all the natural numbers below one thousand that are multiples of 3 or 5.
Haskell:
sum [ x | x <- [1..999], mod x 3 == 0 || mod x 5 == 0 ]
Python:
sum ( [ x for x in range(1,1000) if x % 3 == 0 or x % 5 == 0 ] )
Ruby:
(1..999) . map {|x| x if x % 3 == 0 || x % 5 == 0 } . compact . inject(:+)
They all give the same answer.
OK, so Python can become:
sum ( x for x in range(1,1000) if x % 3 == 0 or x % 5 == 0 )
it is now a generator (a good thing as we are not storing the list)
but even more fun is:
sum( set(range(0,1000,3)) | set(range(0,1000,5)) )
For some reason I was looking at this again and tried a summation approach which should be constant time. In Python 3:
def step_sum(mn,mx,step):
amax = mx - (mx - mn) % step
return (mn + amax) * ((1 + ((amax - mn) / step)) / 2)
step_sum(3,999,3) + step_sum(5,999,5) - step_sum(15,999,15)
Ruby can become:
(1..999) . select {|x| x % 3 == 0 || x % 5 == 0} . inject(:+)
or
(1..999) . select {|x| x % 3 == 0 or x % 5 == 0} . reduce(:+)
I am presuming as unlike map, select doesn't produce 'nul' and therefore there is no need to call compact. nice.
Haskell can also be:
let ƒ n = sum [0,n..999] in ƒ 3 + ƒ 5 - ƒ 15
or to be clearer:
let ƒ n = sum [ 0 , n .. 999 ] in ƒ 3 + ƒ 5 - ƒ (lcm 3 5)
as a function that lets us provide the two numbers ourselves:
ƒ :: (Integral a) => a -> a -> a
ƒ x y = let ƒ n = sum [0,n..999] in ƒ x + ƒ y - ƒ (lcm x y)
For Haskell I like
let s n = sum [0,n..999] in s 3 + s 5 - s 15
or
sum $ filter ((>1).(gcd 15)) [0..999]
For fun the Rube-Goldberg version:
import Data.Bits
sum $ zipWith (*) [1..999] $ zipWith (.|.) (cycle [0,0,1]) (cycle [0,0,0,0,1])
Okay, explanation time.
The first version defines a little function s that sums up all multiples of n up to 999. If we sum all multiples of 3 and all multiples of 5, we included all multiples of 15 twice (once in every list), hence we need to subtract them one time.
The second version uses the fact that 3 and 5 are primes. If a number contains one or both of the factors 3 and 5, the gcd of this number and 15 will be 3, 5 or 15, so in every case the gcd will be bigger than one. For other numbers without a common factor with 15 the gcd becomes 1. This is a nice trick to test both conditions in one step. But be careful, it won't work for arbitrary numbers, e.g. when we had 4 and 9, the test gdc x 36 > 1 won't work, as gcd 6 36 == 6, but neither mod 6 4 == 0 nor mod 6 9 == 0.
The third version is quite funny. cycle repeats a list over and over. cycle [0,0,1] codes the "divisibility pattern" for 3, and cycle [0,0,0,0,1] does the same for 5. Then we "or" both lists together using zipWith, which gives us [0,0,1,0,1,1,0,0,1,1,0,1...]. Now we use zipWith again to multiply this with the actual numbers, resulting in [0,0,3,0,5,6,0,0,9,10,0,12...]. Then we just add it up.
Knowing different ways to do the same thing might be wasteful for other languages, but for Haskell it is essential. You need to spot patterns, pick up tricks and idioms, and play around a lot in order to gain the mental flexibility to use this language effectively. Challenges like the project Euler problems are a good opportunity to do so.
Try this for Ruby:
(1..999).select {|x| x % 3 == 0 or x % 5 == 0}.reduce(:+)
Or a little different approach:
(1..999).reduce(0) {|m, x| (x % 3 == 0 or x % 5 == 0) ? m+x : m }
Not a list comprehension, I know, but to solve that I would use:
3*((999/3)**2+999/3)/2+5*((999/5)**2+999/5)/2-15*((999/15)**2+999/15)/2
Faster then any list comprehension one might come up with, and works in any language ;)
Only posting to show another way of looking at the same problem using http://en.wikipedia.org/wiki/Summation.
I think the following is a better Ruby one:
(1..999).select{|x| x % 3 == 0 || x % 5 == 0}.reduce(:+)
Try something like this:
(1...1000).inject(0) do |sum, i|
if (i % 3 == 0) or (i % 5 == 0)
sum + i
else
sum
end

Categories

Resources