660 likes | 785 Views
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.
E N D
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, . . .)
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.
Creating an instance (an object) from a class • __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() class Point: def __init__(self): self._x = 0 self._y = 0 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 • We can set the value of the Point a: a = Point() a.setX(5) a.setY(2) def setX(self, val): self._x = val _x and _y make these parameters invisible to the caller. def setY(self, val): self._y = val 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.
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
Accessors and Mutators • Accessorsand mutatorslet 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
Summary: Creating a point class class Point: def __init__(self): self._x = 0 self._y = 0 defgetX(self, val): returnself._x defgetY(self, val): returnself._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
Point Class (Continued) defsetX(self, val): self._x = val defsetY(self.val): self._y = val Point has methods that allow its x and y components to be modified.
Using the Point Class #create a new object corner of type Point fromSimplePointimport 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.
#Example SimplePoint code from Chapter 6 of text class Point: def __init__(self): self._x = 0 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): self._y = val This code stored in file named SimplePoint.py from SimplePoint import Point a=Point() a.setX(5) a.setY(2) b = Point() b.setX(-8) b.setY(-3) print "a is ", a, " b is ",b This code stored in file named class-import-test.py
#Example SimplePoint code from Chapter 6 of text class Point: def __init__(self): self._x = 0 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): self._y = val Class name match This code stored in file named SimplePoint.py File name match from SimplePoint import Point a=Point() a.setX(5) a.setY(2) b = Point() b.setX(-8) b.setY(-3) print "a is ", a, " b is ",b This code stored in file named class-import-test.py
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 vu50390:ch06 lcassel$ vu50390:ch06 lcassel$ python useecho.py Enter your string Greetings!! Greetings!! Greetings!! vu50390:ch06 lcassel$ Here is a sample run
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
Improved Point Class (continued) def distance(self, other): dx = self._x - other._x dy = self._y – other._y return sqrt(dx*dx + dy*dy) #using the distance method point1 = Point(5,20) point2 = Point(45,60) apartAmt = point1.distance(point2) Note – this requires import math or from math import sqrt
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)
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>
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).
Improved Point Class (continued) #overloading operators: + overloading def __add__(other): returnPoint(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>
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.
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): ifisinstance(val, (int, float)): #performs regular multiplication #operation. return Point(self._x*val, self._y*val) elifisinstance(val, Point): #performs dot product operation. return self._x*val._x + self._y*val._y
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.
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 If the named error occurs, the “except” clause is executed and the loop is terminated. book slide
Exceptions (continued) • What if a negative is entered for square root? • Can raise an exception when something unusual occurs. defsqrE(number): if number < 0: raiseValueError('number must be positive') #do square root code as before Note: ValueError is an existing, defined error class book slide
Exceptions (continued) #What if value entered is not a number? defsqrtF(number): if notisinstance(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
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
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
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: nameIn = “Anonymous” No input provided
More additions • Printing a simple list of strings includes a space between each pair. • 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 >>> team = "Wildcats" >>> rank = 5 >>> print team, ": ranked", rank, "this week." Wildcats : ranked 5 this week. >>> >>> 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. • Format strings are: • %s is for strings • %d is for integers • %f is for floats. %.2f gives two decimal places. Notice quotes around the whole specification of the formatting. >>> print '%s: ranked %d this week.'%(team, rank) Wildcats: ranked 5 this week.
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 total columns for the number =n, of whichd are for the decimal places >>> 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. >>> 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 non-volatile (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.
Python File Type • creating a new file instance is accomplished in the same way that a new list object is made. fileObj = file(filename)
Reading from a File:Counting lines, words, and charactersversion 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) numwords = len(text.split()) numlines = len(text.split('\n')) print '%10d Lines\n%10d Words\n%10d Characters'%(numlines,numwords,numchars) source.close() Note – this version reads the whole file at once, as a single string What is the filename? citeseertermcount.txt 30002 Lines 156521 Words 920255 Characters
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() print '%10d Lines\n%10d Words\n%10d Characters'%(numlines,numwords,numchars) source.close() Now, we read one line at a time, process it, and read the next. What is the filename? citeseertermcount.txt 30001 Lines 156521 Words 920255 Characters Note different number of lines
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) numwords += len(line.split()) numlines += 1 print '%10d Lines\n%10d Words\n%10d Characters'%(numlines,numwords,numchars) source.close() Note that “for line in source” actually does the read of a line. No explicit readline is used. 30001 Lines 156521 Words 920255 Characters Note the number of lines