object-oriented programming in python goldwasser and letscher chapter 5 additional control...

48
Object-Oriented Programming in Python Goldwasser and Letscher Chapter 5 Additional Control Structures Terry Scott University of Northern Colorado 2007 Prentice Hall

Post on 21-Dec-2015

232 views

Category:

Documents


1 download

TRANSCRIPT

Object-Oriented Programming in PythonGoldwasser and Letscher

Chapter 5Additional Control Structures

Terry Scott

University of Northern Colorado2007 Prentice Hall

2

Introduction: Chapter 5 Topics

• While loop.

– compare with for loop.

– infinite loop.

• Function.

– parts of function: call, heading, body, parameters.

– optional parameters.

• Avoiding duplicate code.

• Case study: Computing the square root.

• Error checking and exceptions.

• Case Study: Simulating a chain under force of gravity.

3

While Loop

• More flexible than for loop.while condition: body

• Example:ans=raw_input('Shall we play a game? ')while answer.lower() in ('y', 'yes'): #code for playing game ans= raw_input('Would you like to play again? ')

4

Semantics of a while loop

5

Finding the Greatest Common Divisor

u = input('Enter the first number: ')

v= input('Enter the second number: ')

guess=min(u,v)

while u% guess > 0 or v%guess > 0:

guess -= 1

print 'The gcd is', guess

6

Finding the Greatest Common Denominator (Euclid's Algorithm)

#more efficient than previous algorithm.

u = input('Enter the first number: ')

v= input('Enter the second number: ')

while v != 0:

r = u % v

u = v

v = r

print 'The gcd is', u

7

Checking whether an element is in a list

• Using for loop:found = Falsefor item in data: if item == val:

found = True

• This is inefficient since once val is found it continues to search.

• Can use break statement to exit loop once item is found.

8

Searching a List (continued)

#Using a while loop is more efficient

#Once val is found the loop is exited.

i = 0

found = False

while i<len(data) and not found:

if data[i] == val:

found = True

else:

i+= 1

9

Reading Data from the User:First Try

#must read name twiceguests = [ ]name=raw_input('Enter name: ')while name: #an empty string is False

guests.append(name) name=raw_input('Enter name: ')

print 'You entered', len(guests), 'guests.'

10

Reading Data from the User: Second Try

#an empty string is False

guests = [ ]

name='fake' #this primes the loop

while name:

name=raw_input('Enter name: ')

if name: #only add to list if not empty

guests.append(name)

print 'You entered', len(guests), 'guests.'

11

Reading Data from the UserThird Try

#an empty string is False

guests = [ ]

name='fake'#this primes the loop

while name:

name=raw_input('Enter name: ')

guests.append(name)

guests.pop() #remove last empty string

print 'You entered', len(guests), 'guests.'

12

Verifying Input Using a While Loop

ans = raw_input('Continue? (y/n): ')

while not ans in ('y', 'n'):

print 'Response must be y or n'

ans = raw_input('Continue? (y/n): ')

13

Infinite Loops

• for loops are automatically bounded by the number of times they execute.

• while loops are not automatically bounded, execution may become stuck in the loop. The following example is likely never to actually occur.

while True:

print 'Hello'

14

Infinite Loops (continued)

• Most infinite loops are more subtle than the previous one.

• In the code below i is never incremented. Unless val is the first item, the loop won't end.

i = 0

found = False

while i < len(data) and not found:

if data[i] == val:

found = True

15

Functions: Another Control Structure

• Calling a function: power(3,2)

• Implementation– heading: def power(base, power)– parameters:

• formal parameters: base and power• actual parameters: 3, 2

– body: return 3 ** 2

16

Calling a Function

ingredients = 'carbonated water', 'caramel color', 'phosphoric acid', 'sodium saccharin', 'caffeine', 'potassium benzoate', 'aspartame', 'citric acid', 'potassium citrate', 'aspartame', 'natural flavors', 'dimethylpolysiloxane']

concern = maxLength(ingredients) #function call

print concern

17

Parameter Passing

• The list is named ingredients at the call to the function. It is called stringSeq at the function definition.

18

Function Definition: Find Maximum Length of Strings.

def maxLength(stringSeq): longSoFar = "" #null string – nothing between two double quotes for entry in stringSeq: if len(entry) > len(longSoFar): longSoFar = entry return longSoFar

ingredients = 'carbonated water', 'caramel color', 'caffeine', 'phosphoric acid', 'sodium saccharin', 'potassium benzoate', 'aspartame', 'potassium citrate', 'citric acid', 'dimethylpolysiloxane', 'natural flavors']

concern = maxLength(ingredients)print concernOutput: dimethylpolysiloxane

19

Return Value

• The function return value is called longSoFar and is called concern at the call to the function

20

Function Flow

21

Nested Function Calls

• A called function can call other functions.

• Diagram shows flow of control.

22

Optional Parameters

def countdown(start = 10):

for count in range(start, 0, -1)

print count

countdown() #will countdown starting at 10

countdown(5) #will countdown starting at 5

23

Flow of Control

• The default is to have statements be executed in the order they appear, sometimes called sequencing.

• To change the order of execution from sequencing, use flow of control statements:– if, if-else, if-elif-. . . else– for– while– function

24

Avoiding Duplicate Code

print 'I will not chew gum in class'

#copy and paste 100 times

#A better way to do this is the following

for i in range(100):

print 'I will not chew gum in class'

25

Duplicate Code:Example

from time import sleeptimeDelay = 25car.move(-10,0)sleep(timeDelay)car.move(-30,0)sleep(timeDelay)car.move(-60,0)sleep(timeDelay)car.move(-100,0)sleep(timeDelay)

26

Avoiding Duplicated Code: Better Than Code on Previous Slide

# Better than previous slide

from time import sleep

timeDelay = .25

for deltaX in (-10, -30, -60, -100)

car.move(deltaX, 0)

sleep(timeDelay)

27

Using a Function to Avoid Duplication

• Drawing three circles as was done in Chapter 3 for the target.

• Could write code to do each one of the circles.

• Better: Write a function that can be called three times with different parameters.

28

Using a Function to Eliminate Repeated Code

def createRing(radius, color, depth):

c = Circle(radius)

c.setFillColor(color)

c.setDepth(depth)

return c

#call function three times.

target.add(createRing(30, 'white', 49)

target.add(createRing(20, 'blue', 48)

target.add(createRing(10, 'red', 47)

29

Conditional Statements with Duplicate Code.

#this has duplicate code

if destination == 'Missouri':

subtotal = sum(shoppingCart)

tax = subtotal * 0.04225

total = subtotal + tax

elif destination == 'Illinois':

subtotal = sum(shoppingCart)

tax = subtotal * 0.0625

total = subtotal + tax

30

Conditional Statements: Better than Previous slide

subtotal = sum(shoppingCart)

if destination == 'Missouri':

tax = subtotal * 0.04225

elif destination == 'Illinois':

tax = subtotal * 0.0625

total = subtotal + tax

31

Conditional Statements (Avoiding Duplicate Code)

# To improve readability call a function to

# lookup tax rates.subtotal = sum(shoppingCart)

tax = subtotal * lookupTaxRate(destination)

total = subtotal + tax

32

Computing Square Root: poor

#Does not always work. Gets stuck in infinite

#loop

def sqrtA(number):

guess = 1.0

while guess != number / guess:

guess = (guess + number / guess)/2.0

return guess

33

Computing Square Root: Good

#Fixed number of iterations

def sqrtB(number):

guess = 1.0

for trial in range(100):

guess = (guess + number / guess)/2.0

return guess

34

Computing the Square Root: Better

#Iterate until gap is small.

def sqrtC(number, Error=.000001):

guess = 1.0

while abs(guess-number/guess) > Error:

guess = (guess + number / guess)/2.0

return guess

35

Computing the Square Root: Best

#Best: Iterate until no more improvement

def sqrtD(number):

prevGuess = 0.0

guess = min(1.0, number)

while prevGuess < guess:

prevGuess = guess

avg = (guess+number/guess)/2.0

guess = min(avg, number/avg)

return guess

36

Exceptions: How to Deal with Error Situations

number = 0

while not 1 <= number <= 10:

try:

number= int(raw_input('Enter number from 1 to 10: '))

if not 1 <= number <= 10:

print 'Your number must be from 1 to 10:'

except ValueError:

print 'That is not a valid integer.'

37

Exceptions (continued)

• What if a negative is entered for square root?

• Can raise an exception when something unusual occurs.

def sqrE(number): if number < 0: raise ValueError('number must be positive') #do square root code as before

38

Exceptions (continued)

#What if value entered is not a number?

def sqrtF(number):

if not isinstance(number, (int, float)):

raise TypeError('number must be numeric')

if number < 0:

raise ValueError('number must be positive')

#do square root code as before

39

How Much Type Checking is Enough?

• A function with little type checking of its parameters may be difficult to diagnose errors.

• A function with much type checking of its parameters will be harder to write and consume more time executing.

• If the function is one that only you will use you may need less type checking.

• A function written for others should have more type checking.

40

A Chain at Equilibrium Under Force of Gravity

41

Three Forces Acting on Each Link

• Force from left chain link.• Force down from gravity.• Force from right chain link.

42

Computing Force on Point A Due to Neighbor B

43

Case Study:Simulating a Chain at Equilibrium

Under the Force of Gravity• Forces on each link are:

– the link to its left.– the link to its right.– gravity downward.

• As with other programs break the code down into functions:

#adding two or three tuples together.def combine(A, B, C = (0,0)): return (A[0]+B[0]+C[0], A[1]+B[1]+C[1])

44

Chain in Equilibrium (continued)

def calcForce(A,B):dX = B[0] – A[0]dY = B[1] – A[1]distance = sqrt(dX*dX + dY*dY)if distance > restingLength:

stretch = distance – restingLengthforceFactor = stretch*elasticityConstant

else:forceFactor = 0

return (forceFactor*dX, forceFactor*dY)

45

Chain in Equilibrium (continued)#continue to compute until movement is less than epsilon.somethingMoved = Truewhile somethingMoved: somethingMoved = False oldChain = list(chain) # a new list for k in range(1, numLinks):

gravForce = (0, gravityConstant) leftForce = calcForce(oldChain[k], oldChain[k-1]) rightForce = calcForce(oldChain[k], oldChain[k+1]) adjust = combine(leftForce, rightForce, gravForce) if abs(adjust[0]) > epsilon or abs(adjust[1]) > epsilon:

somethingMoved = True chain[k] = combine(oldChain[k], adjust)

46

Adding Graphics to Chain

paper=Canvas(totalSeparation,totalSeparation)

#many points to plot so make refresh manual

paper.setAutoRefresh(False)

curve = Path()

for p in chain:

curve.addPoint(Point(p[0], p[1]))

paper.add(curve)

47

Adding Graphics to Chain (continue)

# function to alter the graphical path and

# refresh canvas

def drawChain(chainData, chainPath, theCanvas):

for k in range(len(chainData)):

chainPath.setPoint(Point(chainData[k][0], chainData[k][1]),k)

theCanvas.refresh()

48

Rest of Graphics Code for Chain

• Book contains complete code for visualization of chain on pages 191 - 192