How does the syntax "exp1 << variable << exp2" work in Python? [closed] - python

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 11 months ago.
Improve this question
While I was reading a book, I found this example.
def apply_discount(product, discount):
price = int(product['price'] * (1.0 - discount))
assert 0 <= price <= product['price']
return price
I never saw the syntax 0 <= price <= product['price'] before, and it's clear that here it's testing the price, which should >= 0 and <= product['price']. I tested the function and it works as expected. I want to do more testing about the syntax 0 <= price <= product['price'].
a = 7
if 0 << a << 10:
print('a is greater than or equal to 0 and less than or equal to 10')
else:
print('a is not greater than or equal to 0 and less than or equal to 10')
It always prints a is not greater than or equal to 0 and less than or equal to 10. Why does it happen? What exactly does 0 << a << 10 work?

<< is a shift operator, you need to use < or <=:
a = 7
if 0 <= a <= 10:
print('a is greater than or equal to 0 and less than or equal to 10')
else:
print('a is not greater than or equal to 0 and less than or equal to 10')

<< is a bitwise operation that correspond to a left shift. A left shift is analogous to multiplying by two.
For example:
print(2 << 1)
# 4
print(2 << 2) # Do two left-shifts
# 8
In general, n << m will be equal to n * (2 ** m).
Now shifting has a left to right associativity so your condition will be interpreted as ((0 << a) << 10). Using the formula above, you'll notice that this will always give us 0, regardless of what the value of a is. 0 is equivalent to a boolean False so your condition will always be False

Your check uses bit-shifting, not comparison operations. It will always produce a falsey value.
<< is the left shift operator. It is not a comparison operation (use < or <= if you want comparison).
To see how this expression works, we evaluate the operations left to right. So, 0 << a << 10 is equivalent to (0 << a) << 10.
(0 << a) is 0 shifted over a bits, which is 0. a happens to be 7 here, but shifting 0 over by any number of bits would still produce zero.
0 << 10 is 0 shifted over 10 bits, which is still 0.
Zero is a falsey value, so the if check fails, and the else branch is executed.

Related

the use of value >> i << i != value:

I encountered such a function:
import math
import random
def low_zeros(value):
for i in xrange(1, 32):
if value >> i << i != value:
break
return i - 1
I googled but not found any useful material about value >> i << i != value:
It's checking how many right-side bits are set to zero.
>> bitshifts right, then << bitshifts left by the same amount. Consider:
0b1000 >> 3 << 3
the first shift will do 0b1000 -> 0b0001. The second will do 0b0001 -> 0b1000. That's still equal to the original, so we're set.
Now let's see
0b1000 >> 4 << 4
the first shift will do 0b1000 -> 0b0000 because it shifts the one off the right side of the number. The second shift will try to shift back, but there's nothing to shift (0 << n == 0 for any natural number n). The function is left to compare 0 != 0b1000 and of course breaks execution of the for block.
The function then returns 4-1, which is 3, which is how many zeroes are on the right side of the number.

Need help understanding Python Code

Please help in understanding the logic behind the following function:
def bit_rev (x, b): # reverse b lower bits of x
return sum (1<<(b-1-i) for i in range (0, b) if (x>>i) & 1)
I took a look at the code and it doesn't seem to account for bits past the b'th bit. So, I added another addition. (Unless all you want is up to the b'th bit):
def bit_rev (x, b): # reverse b lower bits of x
return (x >> b << b) + sum(1 << (b - 1 - i) for i in range (0, b) if (x >> i) & 1)
Now for the explaining the logic.
x >> b << b
So, let's say we're using 5 (as x) in this example with 2 as b.
The binary representation of 5 is 101. So, we want to switch only the last 2 bits. Which is 01. However, in our other code we are swapping them, but we are ignoring the bits past b. So, we are ignoring the first (from left to right) 1.
Now the first operations:
x >> b in our case is 5 >> 2. 101 moving to the right 2 is 1, since we end up chopping off the 01.
Next we shift it back. We are guaranteed (in Python) to get 0's back from the bit shift, so we now have 100, or 4.
Now for the meaty part,
sum(1 << (b - 1 - i) for i in range (0, b) if (x >> i) & 1)
It's probably would be easier to understand this outside of a list comprehension, so I rewrote it as a for-loop.
summation = 0
for i in range (0, b):
if (x >> i) & 1:
summation += 1 << (b - 1 - i)
Basically on each iteration we are finding the reverse bit an then adding it to the total (summation).
This code seems to be kind of difficult to understand because there is a lot going on.
Let's start with the for loop itself. for i in range (0, b) is iterating over all values between 0 and b. (Or the last bit you want to change). All the reversing happens later on in the code.
Next we check to see if the bit we are going to swap is a 1. In binary only 1's add value to the total number, so its logical to ignore all 0's. In if (x >> i) & 1:. We bitshift x to the right i bits. So, 101 bit shifted to the right 1 bit is 10. We now check to see if that last bit is a 1 by doing & 1. Basically what & 1 does in this program is ignore all bits beyond the first bit.
The and bitwise operator works as follows:
0101
&1100
=0100
And requires both to be true. Since all bits past 1 would be 0, it effectively ignores the rest.
Now we get a 0 or a 1 from (x >> i) & 1 and Python processes all non-zero integers as True and zero as False. This will make use ignore all bits that are zero.
Next, we add to summation using: summation += 1 << (b - 1 - i). We get the location of where it the bit is going to be by using b - 1 - i. Then we shift 1 over to that location and then add it to the total.
When adding two binary integers, you can add a 1 to a location in the number similar to how you would base 10. So, if I had the number 9000 and I wanted a 1 in the hundredths digit I could do 9000 + 100. That is similar to what we are doing here. We are moving it over to the left in base 2 by using the << operator instead of taking 10^i. So we are setting the newly reversed bit to whatever the original bit was.

Python factorization program [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'm new to programming and I am trying to write a program that takes a positive integer n from input, and then outputs all factorizations of n.
For example if n=10 the program would output
1 times 10 equals 10
2 times 5 equals 10
5 times 2 equals 10
10 times 1 equals 10
I believe the easiest way to do it is to use an if statement nested within for loops. Can anybody provide me with any guidance to help create this? So far I have...
n = int(input())
a = 0
b = n
for a in range(0, n):
if a * b !=n:
continue
if a * b ==n:
print (a+ "times" +b+ "equals" +n)
a=a+1
b=n-1
But for some reason it isn't working. I think I have the right general idea but my code is obviously incorrect.
There are a few issues with your code, but also with your logic. You are increasing a twice (with for and addition), b becomes n-1 the first time through the loop and stays that way, but even if it didn't (eg b = b - 1), it wouldn't work, because if you are increasing a and decreasing b simultaneously, you won't find the correct values unless they happen to match by chance.
Other than that, it's unnecessary to check for a * b != n, you need to call str on the integers to add them to strings and the 0 in your range call is redundant.
whncode's answer is an elegant solution (except for a couple of errors I tried to correct), but to use your logic, you might do this:
for a in range(1, n+1):
for b in range(1, n+1):
if a * b == n:
print str(a) + " times " + str(b) + " equals " + str(n)
n = 10
for divisor in range(n, 0, -1): # reverse range
if (n%divisor == 0): # if modulo is 0
print("%d times %d equals %d", (n/divisor, divisor, n)

Why is 1%2 is equal to 1? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 9 years ago.
Improve this question
I'm confused with the logic of 1% 2 will be 1. Because from what I know 1/2 is 0 so there is no remainder for this.
1/2 is 0 with a remainder of 1. The % operator returns that remainder.
% returns the remainder of a / b:
>>> 1 % 2
1
>>> 1/2
0
>>> 1 - 0
1
Also, the modulo expression can be expressed as:
r = a - nq
Where q is floor(a/n). So:
>>> import math
>>> 1 - 2 * math.floor(1/2)
1.0
% is the modulo operator. It returns the remainder after dividing the left hand side by the right hand side. Since 2 divides zero times into 1, the remainder is one.
In general, if a and b are positive integers, and a < b, then a % b == a.
The arguments do not need to be integers, though. More detail is available from the python reference documentation (http://docs.python.org/2/reference/expressions.html):
The % (modulo) operator yields the remainder from the division of the first argument by the second. The numeric arguments are first converted to a common type. A zero right argument raises the ZeroDivisionError exception. The arguments may be floating point numbers, e.g., 3.14%0.7 equals 0.34 (since 3.14 equals 4*0.7 + 0.34.) The modulo operator always yields a result with the same sign as its second operand (or zero); the absolute value of the result is strictly smaller than the absolute value of the second operand [2].
The integer division and modulo operators are connected by the following identity: x == (x/y)*y + (x%y). Integer division and modulo are also connected with the built-in function divmod(): divmod(x, y) == (x/y, x%y). These identities don’t hold for floating point numbers; there similar identities hold approximately where x/y is replaced by floor(x/y) or floor(x/y) - 1 [3].
Certainly there is a remainder. How many 2s can you get out of 1? 0 of them, with 1 left over.
Ok, the answer has been posted like 6 times already, just adding this for completeness, If there's one way to understand modulo (%), it's converting from base 10 to base 2, 1 can't be divided by 2 so we leave it alone (get a remainder of 1). You can imagine the binary numbers in the third column to be the results of a modulo operation.
eg. 9 (base 10) to (base 2)..
2 | 9 | 1
2 | 4 | 0
2 | 2 | 0
2 | 1 | 1
2*0 is 0
hence the remainder is 1
if the question is to find m%n
we find smallest or equal q such that n*(some whole number) = q and q<=m
we then find (m-q) which is the remainder..
What the % operator is doing:
a % b equals a value c such as 0 <= c < b and there exists a number k so that b * k + c = a.

Bitwise subtraction in Python

This is a follow-up to my question yesterday:
CMS kindly provided this example of using bitwise operators to add two numbers in C:
#include<stdio.h>
int add(int x, int y) {
int a, b;
do {
a = x & y;
b = x ^ y;
x = a << 1;
y = b;
} while (a);
return b;
}
int main( void ){
printf( "6 + 3 = %d", add(6,3));
printf( "6 - 3 = %d", add(6,-3));
return 0;
}
It works great and I then ported it to Python as follows:
def add(x, y):
while True:
a = x & y
b = x ^ y
x = a << 1
y = b
if a == 0:
break
return b
print "6 + 3 = %d" % add(6,3)
print "6 - 3 = %d" % add(6,-3)
They both work for addition and the C program works for subtraction as well. However, the Python program enters an infinite loop for subtraction. I am trying to get to the bottom of this and have posted the program here for further experimentation: http://codepad.org/pb8IuLnY
Can anyone advise why there would be a difference between the way C handles this and the way CPython handles this?
As I pointed out in my response to CMS' answer yesterday, left-shifting a negative number is undefined behavior in C so this isn't even guaranteed to work in C (the problem is how to handle the signed bit, do you shift it like a value bit or is it not affected by a shift? The standards committee couldn't agree on a behavior so it was left undefined).
When this happens to work in C it relies on fixed bit-width integers so that the leftmost bit gets pushed off the end when you do a shift (it also requires the sign bit to be treated as a value bit for shifting purposes). All integer types in C are fixed-bit but Python numbers can be arbitrarily large. Left-shifting a number in Python just causes it to keep getting larger:
>>> 1 << 100
1267650600228229401496703205376L
You could try something like this:
x = (a << 1) & 0xffffffff
To limit the result to 32-bits, the problem is that the left shift operator in Python doesn't shift the sign bit of a signed number (which is part of what is required to make this particular solution work). There might be a way to change the behavior of the shift operator but I don't know how.
Shifting negative numbers doesn't have consistent interpretation between python and C.
if i, j are two integers:
addition:
printf("%d",(i^j)|((i&j)<<1));
I've noticed that you're assuming that python works with numbers the same way as C does.
Thats not entirely true. Meaning C's int numbers have a fixed length of 16 bits. For detailed info on C datatypes you can refer to C_data_types on en.wikipedia.org
Python, on the other hand, is said to have a virtually infinite length for int numbers.
Adding positive integers may work the same way. But subtracting or adding negative integers shouldn't be a simple mapping translation.
An easy way to understand this is a little example on negative numbers:
Imagine a fixed length integer representation of 3 bits:
#Unsigned#
000 : 0
001 : 1
010 : 2
011 : 3
100 : 4
101 : 5
110 : 6
111 : 7
#Signed:#
000 : 0
001 : 1
010 : 2
011 : 3
100 : -4
101 : -3
110 : -2
111 : -1
This works cool because you can see that 1-3=1+(-3), -3 is 101 that's 5 if unsigned. So 1+5=6, 6 : 110 : -2. This means that 1-3=-2.
it also becomes buggy when overflowing:
-4 + -1 = 3 not -5 because it's out of range!
3 + 1 = -4 not 4 because it's out of range!
As you may see this works for fixed length but it doesn't work this way in Python.
For anyone are still interested, to resolve issue in python, just add a new case and switch the order of x and y inside the function, and return the negative value, though this put "-" in the function, but this presented a way using bit-wise operator. For anyone still wish to argue using operator "-" in the following question, I could argue that for the case of 2 - 6, the right answer is -4 where "-" exists in the answer, so it might be okay to add it when x is smaller than y. Hope this helps.
#A substract to substract two integers using bits operators
#refer to: https://www.geeksforgeeks.org/subtract-two-numbers-without-using-arithmetic-operators/
def subtractBits(x, y):
xRAW = x
yRAW = y
if x < y:
x = y
y = xRAW
# Iterate till there
# is no carry
while (y != 0):
# borrow contains common
# set bits of y and unset
# bits of x
borrow = (~x) & y
# Subtraction of bits of x
# and y where at least one
# of the bits is not set
x = x ^ y
# Borrow is shifted by one
# so that subtracting it from
# x gives the required sum
y = borrow << 1
if xRAW < yRAW:
return -x
else:
return x
print(subtractBits(100, 50))
print(subtractBits(1, 3))
print(subtractBits(40, 0))
print(subtractBits(0, 40))
print(subtractBits(5, 5))

Categories