15-112 Fundamentals of Programming

Notes - Lecture 1.2


More on Operators

Here are the operators you need to know.

CategoryOperators
Arithmetic+, -, *, /, //, **, %
Relational <, <=, >=, >, ==, !=
Assignment+=, -=, *=, /=, //=, **=, %=
Logicaland, or, not

Types Affect Semantics

print(3 * 2)
print(3 * "abc")
print(3 + 2)
print("abc" + "def")
print(3 + "def")

Integer division

print("The / operator does 'normal' float division:")
print(" 5/3  =", ( 5/3))
print()
print("The // operator does integer division:")
print(" 5//3 =", ( 5//3))
print(" 2//3 =", ( 2//3))
print("-1//3 =", (-1//3))
print("-4//3 =", (-4//3))

The Modulus or Remainder Operator (%)

What does n mod m represent?

The distance between the largest multiple of m that is no larger than n and n itself. So for example 8 % 3 = 2, because the largest multiple of 3 that is less than 8 is 6 and the distance between 6 and 8 is 2. Similarly -4 % 3 = 2 because the largest multiple of 3 that is less than -4 is -6. The distance between -6 and -4 is 2.

To get a feel for what how the mod operator behaves, take a look at the following cases:

print(" 6%3 =", ( 6%3))
print(" 5%3 =", ( 5%3))
print(" 2%3 =", ( 2%3))
print(" 0%3 =", ( 0%3))
print("-4%3 =", (-4%3))
print(" 3%0 =", ( 3%0))

Verify that (a%b) is equivalent to (a - (a//b)*b)

def mod(a, b):
  return a - (a//b)*b

print(41%14, mod(41,14))
print(14%41, mod(14,41))
print(-32%9, mod(-32,9))
print(32%-9, mod(32,-9))

A couple of useful things you can do with the mod operator

Boolean operators: not, or, and

not boolean-expression
Flips the value of the expression.

x = 10
print(not(x == 10))  #prints False

boolean-exp1 and boolean-exp2
Evaluates to True only if both expressions are True.

y = 5

# Checking if y is a positive even number
print(y > 0 and y%2 == 0)  #prints False

# Checking if y is a positive odd number
print(y > 0 and y%2 == 1)  #prints True

boolean-exp1 or boolean-exp2
Evaluates to True only if at least one of the expressions is True.


x = 10.2
y = 5

# Checking if one of x or y is an integer
print(type(x) == int or type(y) == int)  #prints True

x = 10.2
y = 5.1

# Checking if one of x or y is an integer
print(type(x) == int or type(y) == int)  #prints False


Order precedence of boolean operators from low to high

  1. or
  2. and
  3. not

More on Functions

Function composition

 
def f(w):
    return 10*w

def g(x, y):
    return f(3*x) + y

def h(z):
    return f(g(z, f(z+1)))

print(h(1))

Helper functions

 
def onesDigit(n):
    return n%10

def largerOnesDigit(x, y):
    return max(onesDigit(x), onesDigit(y))

print(largerOnesDigit(134, 672)) # 4
print(largerOnesDigit(132, 674)) # Still 4

Test functions

A broken test function: Can you think why the following test function is not effective?

 
def onesDigit(n):
    return n%10

def testOnesDigit():
    print("Testing onesDigit()...", end="")
    assert(onesDigit(5) == 5)
    assert(onesDigit(123) == 3)
    assert(onesDigit(100) == 0)
    assert(onesDigit(999) == 9)
    print("Passed!")

testOnesDigit() # Passed!  

A better version

 
def onesDigit(n):
    return n%10

def testOnesDigit():
    print("Testing onesDigit()...", end="")
    assert(onesDigit(5) == 5)
    assert(onesDigit(123) == 3)
    assert(onesDigit(100) == 0)
    assert(onesDigit(999) == 9)
    assert(onesDigit(-123) == 3) # Added this test
    print("Passed!")

testOnesDigit() # Crashed!  So the test function worked!

Variable scope

Not all variables are accessible from all parts of our program. Where a variable is accessible depend on how it is defined. We call the part of a program where a variable is accessible its scope .

A variable which is defined in the main body of a file is called a global variable. It will be visible throughout the file. Global variables can have unintended consequences because of their wide-ranging effects – that is why we should almost never use them.

A variable which is defined inside a function is local to that function. It is accessible from the point at which it is defined until the end of the function, and exists for as long as the function is executing.

Here's a picture to illustrate local and global variables:




Now consider the following examples:

Local variables
 
def f(x):
    print("In f, x =", x)
    x += 5
    return x

def g(x):
    return f(x*2) + f(x*3)

print(g(2))

Another example
 
def f(x):
    print("In f, x =", x)
    x += 7
    return round(x / 3)

def g(x):
    x *= 10
    return 2 * f(x)

def h(x):
    x += 3
    return f(x+4) + g(x)

print(h(f(1)))

Global variables
 
# In general, you should avoid using global variables.
# You will even lose style points if you use them!
# Still, you need to understand how they work, since others
# will use them, and there may also be some very few occasions
# where you should use them, too!

g = 100

def f(x):
    return x + g

print(f(5)) # 105
print(f(6)) # 106
print(g)    # 100

Another example
 
g = 100

def f(x):
    # If we modify a global variable, we must declare it as global.
    # Otherwise, Python will assume it is a local variable.
    global g
    g += 1
    return x + g

print(f(5)) # 106
print(f(6)) # 108
print(g)    # 102

Conditional Statements

There are three types of conditional statements:

  1. if statement
  2. if-else statement
  3. if-elif-...-elif-else statement

If statement

First example
 
def f(x):
    print("A", end="")
    if (x == 0):
        print("B", end="")
        print("C", end="")
    print("D")

f(0)
f(1)

A more interesting example
 
def abs1(n):
    if (n < 0):
        n = -n
    return n

# again, with same-line indenting

def abs2(n):
    if (n < 0): n = -n # only indent this way for very short lines (if at all)
    return n

# again, with multiple return statements

def abs3(n):
    if (n < 0):
        return -n
    return n

# aside: you can do this with boolean arithmetic, but don't!

def abs4(n):
    return (n < 0)*(-n) + (n>=0)*(n) # this is awful!

# now show that they all work properly:

print("abs1(5) =", abs1(5), "and abs1(-5) =", abs1(-5))
print("abs2(5) =", abs2(5), "and abs2(-5) =", abs2(-5))
print("abs3(5) =", abs3(5), "and abs3(-5) =", abs3(-5))
print("abs4(5) =", abs4(5), "and abs4(-5) =", abs4(-5))

Multiple blocks of if statements
If the first expression is true, we don’t skip checking the second one.
 
def message(age):
    if (age < 16):
        print("You can\'t drive.")
    if (age < 18):
        print("You can\'t vote.")
    if (age < 21):
        print("You can\'t drink alcohol.")
    if (age >= 21):
        print("You can do anything that\'s legal.")
    print("Bye!")

message(15)
message(21)

If-else statement

First example
 
def f(x):
    print("A", end="")
    if (x == 0):
        print("B", end="")
        print("C", end="")
    else:
        print("D", end="")
        if (x == 1):
            print("E", end="")
        else:
            print("F", end="")
    print("G")

f(0)
f(1)
f(2)

Revisiting abs(n)
 
def abs5(n):
    if (n >= 0):
        return n
    else:
        return -n

# or, if you prefer...

def abs6(n):
    if (n >= 0):
        sign = +1
    else:
        sign = -1
    return sign * n

print("abs5(5) =", abs5(5), "and abs5(-5) =", abs5(-5))
print("abs6(5) =", abs6(5), "and abs6(-5) =", abs6(-5))

If-elif-...-elif-else statement

First example
 
def f(x):
    print("A", end="")
    if (x == 0):
        print("B", end="")
        print("C", end="")
    elif (x == 1):
        print("D", end="")
    else:
        print("E", end="")
        if (x == 2):
            print("F", end="")
        else:
            print("G", end="")
    print("H")

f(0)
f(1)
f(2)
f(3)

A more interesting example
 
def numberOfRoots(a, b, c):
    # Returns number of roots (zeros) of y = a*x**2 + b*x + c
    d = b**2 - 4*a*c
    if (d > 0):
        return 2
    elif (d == 0):
        return 1
    else:
        return 0

print("y = 4*x**2 + 5*x + 1 has", numberOfRoots(4,5,1), "root(s).")
print("y = 4*x**2 + 4*x + 1 has", numberOfRoots(4,4,1), "root(s).")
print("y = 4*x**2 + 3*x + 1 has", numberOfRoots(4,3,1), "root(s).")

Another example
 
def getGrade(score):
    if (score >= 90):
        grade = "A"
    elif (score >= 80):
        grade = "B"
    elif (score >= 70):
        grade = "C"
    elif (score >= 60):
        grade = "D"
    else:
        grade = "F"
    return grade

print("103 -->", getGrade(103))
print(" 88 -->", getGrade(88))
print(" 70 -->", getGrade(70))
print(" 61 -->", getGrade(61))
print(" 22 -->", getGrade(22))

Some guidelines

Some guidelines on correct usage of conditional statements can be found here.


Valid CSS! Valid XHTML 1.0 Strict