Object-Oriented Programming in Python Goldwasser and Letscher Chapter 7 Good Software Practices...

Post on 15-Jan-2016

221 views 1 download

Tags:

Transcript of Object-Oriented Programming in Python Goldwasser and Letscher Chapter 7 Good Software Practices...

Object-Oriented Programming in PythonGoldwasser and Letscher

Chapter 7Good Software Practices

Terry ScottUniversity of Northern Colorado

2007 Prentice Hall

2

Introduction: Chapter 7 Topics

• Mastermind game.• Top down design and bottom up implementation.• Mastermind Design.• Naming Conventions.• Python Docstreams.• Encapsulation.• Modules and Unit Testing.• Error Checking.• Mastermind with graphical user input (GUI).

3

Overview of Mastermind

• One player makes up a pattern of colored pegs.• The other player tries to guess the pattern.• For each guess there are two numbers given:

– black is the number of pegs in the guessed pattern that match at the same spots with those in the original pattern.

– white is the number of colored pegs in the guessed string that are in the original but not in the right positions.

4

Mastermind Game During Play on the Left and at End on the Right.

5

Building a Larger Program

• Top-down design:– Design looks at the overall program.– Followed by more and more detail.

• Bottom-up Implementation:– Build program starting at bottom details.– Followed by putting details together.– Until final program is completed.

• Smaller pieces for making program is called modularity. Modularity promotes code reuse.

6

Top-down Design and Bottom-up Implementation

7

Example: Text-Based Mastermind Session

How many pegs are in the secret color code (1 to 10)? 5How many colors are available (2 to 8)? 5How many turns are allowed (1 to 20)? 10Enter a guess (colors are RBGWY): RRRRROn turn 1 of 10 guess RRRRR scored 1 black and 0 white.

Enter a guess (colors are RBGWY): RBBBBOn turn 2 of 10 guesses RBBBB scored 0 black and 1

white.. . .. . .. . .

8

Mastermind Major Components

9

Sequence Diagram for Mastermind

10

Methods for Mastermind

11

Naming Conventions

• classes – capitalize first letter.

• functions – first letter small, if suceeding words then they should be capitalized.

• data – same as functions.

• parameters – same as functions.

12

Formal Documentation

• Any string following a # is ignored by the Python interpreter.– used by programmer looking at code.

• Triple double quotes around comments makes docstrings.– visible in the code.– use pydoc to pull out comments.– help() will pull out these comments.

13

Webpage Created by pydoc

14

Television Class with docstrings

def __init__(self):

"""Create a new Television instance.

The power is initially off. The first time

the TV is turned on, it will be set to

channel 2 with a volume level of 5

(unmuted)"""

#use previous code

15

Encapsulation

• The internal details of the software are hidden from the user.

• Python uses the class concept to hide the details of the software.

• The behavior of the object is separate from how it is implemented.

• This is called abstraction and helps the software designer not to be bogged down in the details of the object.

16

Underscored Names

• Python does not enforce keeping data as private (not accessible from outside the class).

• The underscore in front of identifiers prevents pydoc or other documentation from having that item displayed.

• Sometimes methods are only used within the class. These are called private methods.

17

Unit Testing

• Larger software projects may consist of many files/classes.

• Waiting too long before testing may result in many errors which are difficult to find and fix.

• The solution is to test each module as it is developed.

• The unit test in Python can help with testing each module.

18

Unit Testing (continued)

class Pattern:

#implementation

if __name__ == '__main__':

#unit test here

19

Pattern Class with Unit Test

from Score import Scorefrom random import seed, randintclass Pattern:

def __init__(self, numPegs):"""construct a new pattern"""self._pegList = [0] * numPegsdef __len__(self):"""return length of current pattern return len(self._pegList) def getPegColor(self, index):"""Returns current color setting of the peg at index""" self._pegList[index]

20

Pattern Class with Unit Test (continued)

def setPegColor(self, index, colorID):"""set color of peg at index location""" self._pegList[index] = colorID

def compareTo(self, otherPattern):"""compare and score otherPattern to current pattern""" black = 0 for i in range(len(self._pegList)): if self.getPegColor(i)==otherPattern.getPegColor(i):

black += 1 colorsUsed = [ ] for color in self._pegList: if color not in colorsUsed:

colorsUsed.append(color)

21

Pattern Class with Unit Test (continued)

white = 0 for color in colorsUsed:

white += min(self._pegList.count(color), otherPattern._pegList.count(color))

white -= black return Score(black, white)def randomize(self, numColors):

"""Make a random pattern"""seed()for i in range(len(self._pegList)): self._pegList[i] = randint(0, numColors – 1)

22

Pattern Class with Unit Test (continued)

#unit test for the Pattern classif __name__ == '__main__': modelA = (1, 3, 0, 3, 2) patternA = Pattern(5) for i in range(len(modelA): patternA.setPegColor(I, modelA[i]) if len(patternA) != 5: print 'Pattern length is miscalculated' for i in range(5): if patternA.getPegColor(i) != modelA[i]: print 'Color at index', i, 'not properly set/ retrieved'

23

Pattern Class with Unit Test (continued)

copy = Pattern(5)

for I in range(5):

copy.setPegColor(i,patternA.getPegColor(i))

score = patternA.compareTo(copy)

if score.getNumBlack()!=5 or score.getNumWhite()!=0:

print 'Score miscalculated'

#can repeat this for another pattern.

24

Error Testing

• It is important to check user inputs to prevent input errors from crashing the program.

• Possible errors in Mastermind– 3 beginning integers.– at end when asked to play again.– color pattern during playing of game.

• Code on next page shows how to check some of these errors.

25

User Error Checking for Mastermind

#This is included in the classdef _readInt(self, prompt, small, large):

prompt=prompt+'(from '+str(small)+' to '+str(large) + ')?' answer = small – 1 while not small <= answer <= large:

try: answer = int(raw_input(prompt) if not small <= answer <= large: print 'Integer must be from ' + str(small) + ' to '

+ str(large) + '.'except ValueError: print 'That is not a valid integer.'

return answer

26

Further Code

• Book pages 259 – 260 has further error checking code.

• If the text based code is organized such that the input and output are separate methods, then converting to a GUI will be less trouble.

• See pages 264 – 266 in the book to see the code for the game using a GUI interface.