Computer Science 15-112, Summer 2012
Class Notes: Data and Expressions
Data and Expressions
Category | Operators |
Arithmetic | +, -, *, /, //, **, %, - (unary), + (unary) |
Relational | <. <=, >=, >, ==, !=, <> |
Bitwise | <<, >>, &, |, ^, ~ |
Assignment | +=, -=, *=, /=, //=, **=, %=, <<=, >>=, &=, |=, ^= |
Logical | and, or, not |
print 2+3*4 # prints 14, not 20 print 9**1/2 # prints 4, not 3
print "20/3 =", (20/3)
print " 6/3 =", ( 6/3)
print " 5/3 =", ( 5/3)
print " 2/3 =", ( 2/3)
print " 0/3 =", ( 0/3)
print "-2/3 =", (-2/3)
print "-3/3 =", (-3/3)
print "-4/3 =", (-4/3)
print "20%3 =", (20%3)
print " 6%3 =", ( 6%3)
print " 5%3 =", ( 5%3)
print " 2%3 =", ( 2%3)
print " 0%3 =", ( 0%3)
print "-2%3 =", (-2%3)
print "-3%3 =", (-3%3)
print "-4%3 =", (-4%3)
print " 3%0 =", ( 3%0)
print 10 / 3
print 10.0 / 3
print 10 / 3.0
x = 10
print x / 3
print 1.0 * x / 3
print float(x) / 3
d1 = 0.1 + 0.1 + 0.1
d2 = 0.3
print (d1 == d2) # False!
print (d2 - d1) # -5.55111512313e-17 (tiny!)
d1 = 0.1 + 0.1 + 0.1
d2 = 0.3
print (d1 == d2) # still false, of course
epsilon = 0.000001
print (abs(d2 - d1) < epsilon) # True!
Once again, using an almostEqual function (that we will write) def almostEqual(d1, d2): epsilon = 0.000001 return (abs(d2 - d1) < epsilon)
d1 = 0.1 + 0.1 + 0.1
d2 = 0.3
print (d1 == d2) # still false, of course
print almostEqual(d1, d2) # True, and now packaged in a handy reusable function!
x = 0
y = 0
print ((y != 0) and ((x/y) != 0)) # Works!
print (((x/y) != 0) and (y != 0)) # Crashes!
Once again, using the "or" operator
x = 0
y = 0
print ((y == 0) or ((x/y) == 0)) # Works!
print (((x/y) == 0) or (y == 0)) # Crashes!
Yet another example:
def isPositive(n): result = (n > 0) print "isPositive(",n,") =", result return result def isEven(n): result = (n % 2 == 0) print "isEven(",n,") =", result return result print "Test 1: isEven(-4) and isPositive(-4)" print (isEven(-4) and isPositive(-4)) # Calls both functions print "----------" print "Test 2: isEven(-3) and isPositive(-3)" print (isEven(-3) and isPositive(-3)) # Calls only one function!
A | B | A and B | not A | not B | (not A) or (not B) | not ((not A) or (not B)) |
0 | 0 | 0 | 1 | 1 | 1 | 0 |
0 | 1 | 0 | 1 | 0 | 1 | 0 |
1 | 0 | 0 | 0 | 1 | 1 | 0 |
1 | 1 | 1 | 0 | 0 | 0 | 1 |
# 0 1 1 0 = 4 + 2 = 6 # 0 1 0 1 = 4 + 1 = 5 print "6 & 5 =", (6&5) print "6 | 5 =", (6|5) print "6 ^ 5 =", (6^5) print "6 << 1 =", (6 << 1) print "6 << 2 =", (6 << 2) print "6 >> 1 =", (6 >> 1) print "~6 =", (~6) print "~6+1 =", (~6+1) print "~432+1 =", (~432+1) print "Bitwise DeMorgan's Law: a&b == ~(~a|~b)" print "6 & 5 =", (6&5) print "~(~6|~5) =", (~(~6|~5))
def setLower4Bits(n): # SET bits with an OR mask of 1's mask = 0b00001111 # 0x0F (15) return n | mask print "setLower4Bits(0b11010110) =", bin(setLower4Bits(0b11010110)) def clearLower4Bits(n): # CLEAR bits with an AND mask of 0's # Due to leading zeroes, this clears all the bits above the 8th bit, too! mask = 0b11110000 # 0xF0 (240) return n & mask print "clearLower4Bits(0b11010110) =", bin(clearLower4Bits(0b11010110)) def getSecondLowestNybble(n): # A 'nybble' is half a 'byte', or 4 bits. # It is a value from 0b0000 (0) to 0b1111 (15). # First clear everything except the bits we want, # then bit-shift them into place: return clearLower4Bits(n) >> 4 print "getSecondLowestNybble(0b110011010110) =", bin(getSecondLowestNybble(0b110011010110))
# Note: you may not use conditional expressions until we cover # conditional ("if") statements in a week or two. # They are included here, though, as they are expressions, not statements, # so deserve some mention in the section on expressions.
x = 2 y = 3 if (x < 4) else 5 z = 4 if (x > 4) else 5 print x, y, z
Bits | Decimal Value |
000 | 0 |
001 | 1 |
010 | 2 |
011 | 3 |
100 | -4 |
101 | -3 |
110 | -2 |
111 | -1 |
# Boolean logic via arithmetic!
# These functions demonstrate how you can use (ok, STRETCH) arithmetic
# to compute seemingly boolean logical (ie, True/False) functions.
# As is standard, we'll use 1 for True and 0 for False.
# The functions operate over integer values.
# These are not unique -- there are equivalent functions
# that use other (possibly more clever) arithmetic approaches.
# Still, these work, and provide a glimpse of the
# remarkable computational power of good ol' arithmetic.
def _not(x): return 1-x
def _and(x,y): return x*y
def _or(x,y): return x+y-x*y
def isNonZero(x): return (x**2+2)%(x**2+1)
def isZero(x): return 1-((x**2+2)%(x**2+1))
def isPositive(x): return (1 +(2*x)/(2*x-1))/2
def isNegative(x): return (1 +(2*(-x))/(2*(-x)-1))/2
def isGreaterThan(x, y): return (1 +(2*(x-y))/(2*(x-y)-1))/2
def isLessThan(x, y): return (1 +(2*(y-x))/(2*(y-x)-1))/2
def isEqual(x, y): return 1-(((x-y)**2+2)%((x-y)**2+1))
def testBooleanLogicViaArithmetic():
print "Testing 'boolean logic via arithmetic' functions... ",
for x in xrange(-50,50):
assert(isZero(x) == (x==0))
assert(isNonZero(x) == (x != 0))
assert(isPositive(x) == (x > 0))
assert(isNegative(x) == (x < 0))
assert(isGreaterThan(x,5) == (x > 5))
assert(isGreaterThan(5,x) == (5 > x))
assert(isLessThan(x,5) == (x < 5))
assert(isLessThan(5,x) == (5 < x))
assert(isEqual(x,5) == (x == 5))
print "passed!"
testBooleanLogicViaArithmetic()
def _not(x): return 1-x
def _and(x,y): return x*y
def _or(x,y):
# equivalent to: x+y-x*y
return _not(_and(_not(x), _not(y))) # DeMorgan's Law
def isNonZero(x): return (x**2+2)%(x**2+1)
def isZero(x):
# equivalent to: 1-((x**2+2)%(x**2+1))
return _not(isNonZero(x))
def isPositive(x): return (1 +(2*x)/(2*x-1))/2
def isNegative(x):
# equivalent to: (1 +(2*(-x))/(2*(-x)-1))/2
# or: _and(_not(isPositive(x), _not(isZero(x))))
return isPositive(-x)
def isGreaterThan(x, y):
# equivalent to: (1 +(2*(x-y))/(2*(x-y)-1))/2
return isPositive(x-y)
def isLessThan(x, y):
# equivalent to: (1 +(2*(y-x))/(2*(y-x)-1))/2
return isGreaterThan(y,x)
def isEqual(x, y):
# equivalent to: 1-(((x-y)**2+2)%((x-y)**2+1))
return isZero(x-y)
# This is a function from the notes on loops (coming soon!),
# rewritten here using the techniques above,
# and with the variables anonymized to make the
# outcome a welcome surprise. Run the code below
# to see what it does. All without booleans. Amazing!
def np(n):
n += 1
g = 0
while (n):
g += 1
c = 0
f = g
while (f):
c += 1-(((g%f)**2+2)%((g%f)**2+1))
f -= 1
n -= (((1 +(2*(g-1))/(2*(g-1)-1))/2) *
(1-(((c-2)**2+2)%((c-2)**2+1))))
return g
for n in range(10):
print n, np(n)
# Enter these expressions and statements into the interpreter. # Predict the results of each line before advancing to the next line. # Be precise. print 3*3/4, 3/4*3, 3**3/4 x = 1000*1000*1000*1000 # one trillion x print x type(x) x /= 1000*1000*1000 # divide by one billion x x/1000 x x = 123 x.bit_length() import sys x = sys.maxint # 2^31-1, or 2147483647 x.bit_length() x x+1 -x -(x+1) -x-1 -x-2 not 43 not 43/99 43/99 or 99/43 or 99 print 0xff print hex(255) print 255 == 0xff print 255 == hex(255) print "-----------------" x = 5 print 42 if (x == 5) else 99 print ((x == 5) and 42) or 99 print ((x == 5) * 42) + ((x != 5) * 99) print 42 + (x/6)*(99-42) print 42 + ((x-5)*(99-42)) print "-----------------" x = 6 print 42 if (x == 5) else 99 print ((x == 5) and 42) or 99 print ((x == 5) * 42) + ((x != 5) * 99) print 42 + (x/6)*(99-42) print 42 + ((x-5)*(99-42))
carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem - carpe diem