ClassesPlus

advertisement
More Control and
Expanded I/O options
Part 1: Defining classes
• By the end of this session, you should be
able to define a class, store it in a file,
import it and use it in another program.
– self as a parameter
– local variables
– parameters and arguments
– special operators
– polymorphism
Recall from first week
• A class is a definition of a category of
objects and the methods that operate on
those objects
– A specific instance of a class is called an object
• A class may be related to other classes, and
inherit properties from the other class or
extend the properties of another class.
– A class student is a subclass of person
• A student has all the characteristics of a person, but
has other characteristics as well (perhaps major,
gpa, etc.)
Backward references
• We will use examples that were
introduced earlier. Look back at the
previous slides and look at the book to
find the details that were provided then.
• Examples:
– greatest common divisor
– television class
Defining a class
• Similar to defining a function, which we
have done.
– We saw earlier that a class consists of
attributes for the data and methods for
operating on the data.
– These get translated into Python code as
• references to self
• functions defined on self, other parameters
• class introduces a class definition
– classes can reference each other
Point Class
This is what allows us to instantiate an
instance of the class – an object.
• class Point:
• __init__ called the constructor. Executed when a
new object is created from a class.
• self lets Python know that a method or data is a
member of the class.
– For a data member it should be self._x where
_x is the class data attribute. Without the self a
variable is only a local variable inside a class
method.
– For a method the self is the first parameter in
the parameter list. __init__(self, . . .)
6
Indentation Pattern for a Class
So, this one class
includes three
methods (function
definitions)
Notice the
indentation: Each
function definition
is indented and the
body of each
function is indented
within the function.
7
Creating an instance (an object)
from a class
class Point:
def __init__(self):
self._x = 0
self._y = 0
• __init__(self) defines the structure of the objects of this class.
There are two components to objects of this class: _x and _y
(yes, the _ is a significant part of the name.)
• When a program uses the Point class, the __init__ function
establishes its parts and assigns each of the parts the value 0 in
this example.
• Creating a Point object:
a = Point()
a is now a Point object. It consists of two
numbers, which we might think of as the x and y
components of the Point
The setX, setY methods
def setX(self, val):
self._x = val
def setY(self, val):
self._y = val
_x and _y make these
parameters invisible to
the caller.
• We can set the value of the Point a:
a = Point()
a.setX(5)
a.setY(2)
a is now the point <5,2>
(using < > to avoid confusion
with () and [] which already have
meaning.)
Referencing the components of
the Point
• Since _x and _y are hidden, the program
cannot reference
– a.x or a.y
• Instead,
– a.getX()
– a.getY()
Next example uses corner instead of a as
the name of the Point.
Connection Between a Method (setX)
for the object corner and setX
definition in the class.
11
Two Perspectives
• Left part of each box: perspective from
outside the Point class.
• Right part of each box: perspective from
inside the Point class.
Argument used to reference the
object’s methods from the program
Parameter used to
define the object
12
Accessors and Mutators
• Accessors and mutators let users of the
class access data members and change
data member values.
• getX(self) can return the X data member.
– This is an accessor
• setX(self, val) will change the X data
member to be val.
– This is a mutator
13
Summary: Creating a point class
class Point:
def __init__(self):
self._x = 0
self._y = 0
def getX(self, val):
return self._x
def getY(self, val):
return self._y
Point has two
components, x and y,
initially set to 0
Point has methods that
allows its x and y
components to be
referenced
14
Point Class (Continued)
def setX(self, val):
self._x = val
def setY(self.val):
self._y = val
Point has methods that
allow its x and y
components to be
modified.
15
Using the Point Class
#create a new object corner of type Point
from SimplePoint import Point
corner = Point()
corner.setX(8) #8 is value of _x in object corner
corner.setY(6) #6 is value of _y in object corner
This assumes that we have created a
file with the SimplePoint class
definition.
16
#Example SimplePoint code from Chapter 6 of text
class Point:
def __init__(self):
This code stored in file named
self._x = 0
SimplePoint.py
self._y = 0
def __str__(self):
return '<'+str(self._x)+','+str(self._y)+'>’
def getX(self):
return self._x
def setX(self, val):
self._x = val
def getY(self):
return self._y
def setY(self, val):
from SimplePoint import Point
self._y = val
a=Point()
a.setX(5)
a.setY(2)
b = Point()
b.setX(-8)
This code stored in file named
b.setY(-3)
class-import-test.py
print "a is ", a, " b is ",b
#Example SimplePoint code from Chapter 6 of text
class Point:
Class name match
def __init__(self):
self._x = 0
self._y = 0
def __str__(self):
return '<'+str(self._x)+','+str(self._y)+'>’
def getX(self):
This code stored in file named
return self._x
SimplePoint.py
def setX(self, val):
self._x = val
File name match
def getY(self):
return self._y
def setY(self, val):
from SimplePoint import Point
self._y = val
a=Point()
a.setX(5)
a.setY(2)
b = Point()
b.setX(-8)
This code stored in file named
b.setY(-3)
class-import-test.py
print "a is ", a, " b is ",b
class Echo:
def __init__(self, anyStr):
self.text = anyStr
def __str__(self):
return str(self.text) + " " + str(self.text)
Check Point
• Create a class
– Make a class called Echo
– It has one parameter, a string
– It uses __init__ to instantiate an object and __str__ to
cast the object as a string for printing and return the
string duplicated, with a space between the copies.
• Create a calling program to obtain a string from
the user and call Echo to print it out twice
Here is a sample
run
vu50390:ch06 lcassel$
vu50390:ch06 lcassel$ python useecho.py
Enter your string Greetings!!
Greetings!! Greetings!!
vu50390:ch06 lcassel$
Improved Point class
#if no values are specified for x and y then
#the values are set to 0.
def __init__(self, initX = 0, initY = 0)
self._x = initX
self._y = initY
#Scales the point by a value factor.
def scale(self, factor):
self._x *= factor
self._y *= factor
21
Improved Point Class (continued)
def distance(self, other):
dx = self._x - other._x
dy = self._y – other._y
return sqrt(dx*dx + dy*dy)
Note – this requires
import math
or
from math import sqrt
#using the distance method
point1 = Point(5,20)
point2 = Point(45,60)
apartAmt = point1.distance(point2)
22
Improved Point Class (continued)
#normalize point – make its distance to the
#origin 1
def normalize(self):
mag = self.distance(Point())
#Point() creates new point at origin
if mag > 0: #don't scale if point is at
origin
self.scale(1/mag)
23
Improved Point Class (continued)
#allow print to be able to print a point object.
def __str__(self):
return '<'+str(self._x)+', '+str(self._y)+ '>'
#using __str__ method
new = Point(3, 5)
print new
#output
<3, 5>
24
Improved Point Class (continued)
• Can not use <3,5> to initialize an object.
point = <3,5> #this is an error
• Can overload most operators so that
they have a new meaning when used
with new objects.
• An example is + operator when used
with int and float does addition. When
used with str it does concatenation
(sticks the two strings together).
25
Improved Point Class (continued)
#overloading operators: + overloading
def __add__(other):
return Point(self._x +other._x,
self._y+other._y
#using the __add__ method
new = Point(3, 5)
old = Point(4, 7)
total = new + old
print total
#output
<7, 12>
26
Polymorphism
• Operator may do a different operation
depending on the type that is passed
into the operator.
• Multiplication operator: int or float
multiply each component by the value,
point do a dot product.
• isinstance(variable, Type) returns True if
variable is of type Type.
27
Polymorphism
#if val is an int or float it does the
# if code
#if a Point it does the elif code.
def __mul__(self, val):
if isinstance(val, (int, float)):
#performs regular multiplication
#operation.
return Point(self._x*val, self._y*val)
elif isinstance(val, Point):
#performs dot product operation.
return self._x*val._x + self._y*val._y
28
Spot Check
• Do exercise 6.4 in the text.
– Enter the code shown.
– Execute each of the examples
– Explain the results
Other examples
• Look at the descriptions of the Television
and Fraction classes in the text for
further examples of class definition.
More control – Catching
exceptions
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.'
Here: recognize an error condition and deal with it
book slide
If the named error occurs, the “except” clause is
executed and the loop is terminated.
32
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
Note: ValueError is an existing, defined error class
book slide
33
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
book slide
34
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.
book slide
35
Spot check on Exceptions
• In pairs, write python code to do the
following:
– Accept input from the keyboard
• Prompt with instructions to enter a number, and to
enter some character you choose to end
– Verify that the value read is numeric
– Calculate the minimum, maximum and average
of the values read
– Terminate reading when a non numeric
character is entered
– Print out the values calculated
36
Formatting and File access
Building on basics
• We had
– Input from the keyboard
• nameIn = raw_input(“What is your name?”)
– and output to the console
• print “Hello”, nameIn
• Additions:
– default for value not input:
• nameIn = raw_input(“What is your name?”)
• if not nameIn:
No input provided
nameIn = “Anonymous”
More additions
• Printing a simple list of strings includes a
space between each pair.
>>> team = "Wildcats"
>>> rank = 5
>>> print team, ": ranked", rank, "this week."
Wildcats : ranked 5 this week.
>>>
– Unwanted space between team name and :
– to fix this use concatenation of strings (+
operator). Must explicitly convert numbers
to strings. Gain full control of the spacing
>>> print team+": ranked " + str(rank) +" this week."
Wildcats: ranked 5 this week.
Formatting Strings
• Further control of how individual fields
of output will be presented.
– % is used to indicate a formatting code and
also a tuple of items to be formatted
– %s for strings
– %d for integers (d for digits?)
– %f for floats (numbers with decimal parts)
• %.3f displays three decimal places
Formatted Strings (continued)
• Can write previous statement using
formatting strings like this.
Notice quotes
>>> print '%s: ranked %d this week.'%(team, rank) around the whole
Wildcats: ranked 5 this week.
specification of the
formatting.
• Format strings are:
– %s is for strings
– %d is for integers
– %f is for floats. %.2f gives two decimal places.
41
Formatting details
• Further options
– %10s -- string with 10 spaces, minimum
– %4d -- number with 4 spaces, minimum
– -%5.2f -- float with 5 places, of which two are decimal
positions
Note: %n.df makes the
>>> print 'Rank %5.2f as a float.'%rank
Rank 5.00 as a float.
>>> print 'Rank %10.2f as a float.'%rank
Rank
5.00 as a float.
total columns for the
number =n, of which d
are for the decimal places
>>> rank = 100
>>> print "Rank %3.2f with field too small"%rank
Rank 100.00 with field too small
%3.2f means total 3
spaces, one is for the
decimal point and two
for the decimal digits,
none for the whole
number. Automatically
expanded to fit the
actual value.
Short spot check
• Write code to print out
– Today is 10 October 2012
– Where the date consists of 3 variables
• Day is an integer
• Month is a string
• Year is an integer
– Use the formatting tools we just saw and
make the day number always 2 digits, the
month name a set length (long enough for
any month) and the year four digits.
Working with Files
• Information stored in RAM (main
memory) goes away (is volatile) when
the computer is shut off.
• Information stored on disk is nonvolatile (does not go away when the
computer is turned off).
• Writing to and reading from a file can
help preserve information between
different executions of a program.
44
Python File Type
• creating a new file instance is
accomplished in the same way that a
new list object is made.
fileObj = file(filename)
45
File Operations
Syntax
Semantics
close()
disconnect file from Python file variable
and save file.
flushes buffer of written characters.
flush()
read()
returns a string with remaining contents
of the file.
read(size) returns a string with size bytes
remaining in file.
readline() returns string that contains next line in
the file.
46
File Operations (continued)
Syntax
Semantics
readlines()
returns a list of strings of the
remaining lines in the file.
write(s)
writes s to the file. No newlines
are added.
writes the lines in seq to the file.
writelines(seq)
for line in f:
iterates through the line f, one line
at a time.
47
Reading from a File:
Counting lines, words, and characters
version 1 – corrected typos and added formatting
filename = raw_input('What is the filename? ')
source = file(filename)
text = source.read() # Read entire file as one string
numchars = len(text)
Note – this version reads the whole
numwords = len(text.split())
file at once, as a single string
numlines = len(text.split('\n'))
print '%10d Lines\n%10d Words\n%10d
Characters'%(numlines,numwords,numchars)
source.close()
What is the filename? citeseertermcount.txt
30002 Lines
156521 Words
920255 Characters
48
Reading from a File:
Counting lines, words, and characters
version 2
numlines=numwords=numchars=0
line=source.readline()
while line: # line length is not zero
numchars+=len(line)
numwords +=len(line.split())
numlines+=1
# Done with current line. Read the next
line=source.readline()
Now, we read one line
at a time, process it,
and read the next.
print '%10d Lines\n%10d Words\n%10d
Characters'%(numlines,numwords,numchars)
source.close()
What is the filename? citeseertermcount.txt
30001 Lines
156521 Words
Note different number of lines
920255 Characters
49
Reading from a File:
Counting lines, words, and characters
version 3
filename = raw_input('What is the filename? ')
source = file(filename)
numlines = numwords = numchars = 0
for line in source: #reads one line at a time until no more.
numchars += len(line)
Note that “for line in source” actually
numwords += len(line.split())
does the read of a line. No explicit
numlines += 1
readline is used.
print '%10d Lines\n%10d Words\n%10d
Characters'%(numlines,numwords,numchars)
source.close()
30001 Lines
156521 Words
920255 Characters
Note the number of lines
50
Spot check
• Read a file of your choice – anything you
have is fine
• Find the longest line
– Output the line number and its length in
characters
Writing to a File
• Creating a new file object that can be written
to in Python with a file name of filename.
result = file(filename, 'w')
• If the file with filename already exists then it
will be overwritten.
• Only strings can be written to a file
pi = 3.14159
result.write(pi)
result.write(str(pi))
#this is illegal
#this is legal
52
Writing to a File
• When is the information actually written
to a file?
• File writing is time expensive so files
may not be written immediately.
• A file can be forced to be written in two
ways:
– flush(): file written but not closed.
– close(): file written and then closed.
53
File Write Danger
• Note that there is no built-in protection
against destroying a file that already
exists!
• If you want to safeguard against
accidentally overwriting an existing file,
what would you do?
– Discuss
Trying to Read a File That
Doesn't Exist.
• What if opening file for reading and no file
with that name exists? IOError – crashes
program. To avoid this use an exception.
filename = raw_input('Enter filename: ')
try:
source = file(filename)
except IOError:
print 'Sorry, unable to open file', \
filename
55
File Utilities
# Prompt for filename until file is successfully opened.
def fileReadRobust():
source = None
while not source:
filename = raw_input('Input filename: ')
try:
source = file(filename)
except IOError:
print 'Sorry, unable to open file', filename
return source
56
File Utilities (continued)
def openFileWriteRobust(defaultName):
"""Repeatedly prompt user for filename until successfully opening with write
access.
Return a newly open file object with write access.
defaultName a suggested filename. This will be offered within the prompt and
used when the return key is pressed without specifying another name.
"""
writable = None
while not writable:
# still no successfully opened file
prompt = 'What should the output be named [%s]? '% defaultName
filename = raw_input(prompt)
if not filename:
# user gave blank response
filename = defaultName
# try the suggested default
try:
writable = file(filename, 'w')
except IOError:
print 'Sorry. Unable to write to file', filename
return writable
57
Spot check
• Enter the code shown for the robust file
open. Add a call to this function.
• How can you test this code?
Testing the File Utilities
from FileUtilities import *
sourceFile=openFileReadRobust()
if sourceFile <> None:
print "Successful read of ",sourceFile
filenone="anyname"
outFile=openFileWriteRobust(filenone)
if outFile <> None:
print "File ", outFile, " opened for writing"
What is the filename? citeseertermcount.txt
Successful read of <open file 'citeseertermcount.txt', mode 'r' at 0x60f9d0>
What should the output be named [anyname]? abc.txt
File <open file 'abc.txt', mode 'w' at 0x60fa20> opened for writing
Numbering lines
in a file
# Program: annotate.py
# Authors: Michael H. Goldwasser
#
David Letscher
#
# This example is discussed in Chapter 8 of the book
# Object-Oriented Programming in Python
#
from FileUtilities import openFileReadRobust, openFileWriteRobust
print 'This program annotates a file, by adding'
print 'Line numbers to the left of each line.\n'
source = openFileReadRobust()
annotated = openFileWriteRobust('annotated.txt')
# process the file
linenum = 1
for line in source:
annotated.write('%4d %s' % (linenum, line) )
linenum += 1
source.close()
annotated.close()
print 'The annotation is complete.'
Running the annotation program
This program annotates a file, by adding
Line numbers to the left of each line.
What is the filename? fileUtilities.py
What should the output be named [annotated.txt]?
annotatedUtilities.txt
The annotation is complete.
Directory after the program runs:
FileUtilities.pyc
abc.txt
annotate.py
annotatedUtilities.txt
citeseertermcount.txt readfile1.py
fileUtilTest.py
readfile2.py
fileUtilities.py
readfile3.py
readexception.py
61
The annotated file
1 # Program: FileUtilities.py
2 # Authors: Michael H. Goldwasser
3 #
David Letscher
4 #
5 # This example is discussed in Chapter 8 of the book
6 # Object-Oriented Programming in Python
7 #
8 """A few utility functions for opening files."""
9 def openFileReadRobust():
10 """Repeatedly prompt user for filename until successfully opening with read access.
11
12 Return the newly open file object.
13 """
14 source = None
15 while not source:
# still no successfully opened file
16 filename = raw_input('What is the filename? ')
17 try:
18
source = file(filename)
19 except IOError:
20
print 'Sorry. Unable to open file', filename
21 return source
22
23 def openFileWriteRobust(defaultName):
24 """Repeatedly prompt user for filename until successfully opening with write access.
25
26 Return a newly open file object with write access.
Rest not shown for space limitations
Spot Check 2
• Run the annotate program against a file
of your choosing and get the line
numbers added.
– Be careful not to overwrite the original file.
– Modify the code to remove the file
numbers from the file
Tally
• Read through the case study of
constructing a tally sheet class.
• Compare what you see here to the
frequency distribution content that you
saw in the NLTK book.
NLTK chapter 3
• That is written very much as a tutorial
and I don’t think I can do much with
slides and no narration.
• Please read through that chapter and do
the “Your turn” exercises. Use the
Discussion board to comment on what
you do and to share observations and
ask questions.
Assignment
• In Two weeks:
– Do either exercise 8.18 or exercise 8.21
– (Do you prefer to work with numbers or
words?)
– Be sure to design good test cases for your
program.
• For chapter review (and quiz
preparation) be sure you can do
exercises 8.7 – 8.9
Download