34
83 Writing a Fraction Class So far we have worked with floa0ng-point numbers but computers store binary values, so not all real numbers can be represented precisely In applica0ons where the precision of real numbers is important, we can use ra#onal numbers to store exact values This helps to reduce or eliminate round-off errors that can occur when performing arithme0c opera0ons A ra0onal number is a number that can be expressed as a ra0o of two integers: 7/8 The top value is called the numerator and the boFom value, which cannot be zero, is called the denominator 11/4/16

Writing a Fraction Class - Westmont College

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

83

Writing a Fraction Class •  Sofarwehaveworkedwithfloa0ng-pointnumbersbutcomputersstorebinaryvalues,sonotallrealnumberscanberepresentedprecisely

•  Inapplica0onswheretheprecisionofrealnumbersisimportant,wecanusera#onalnumberstostoreexactvalues•  Thishelpstoreduceoreliminateround-offerrorsthatcanoccurwhenperformingarithme0copera0ons

•  Ara0onalnumberisanumberthatcanbeexpressedasara0ooftwointegers:7/8

•  ThetopvalueiscalledthenumeratorandtheboFomvalue,whichcannotbezero,iscalledthedenominator

11/4/16

84

Designing the Fraction Class •  Wewanttouseourra0onalnumbersaswewoulduseintegersandfloa0ngpointvalues

•  Thus,ourFractionclassmustperformthefollowingopera0ons:1.  Createara0onalnumber2.  Accessthenumeratoranddenominatorvalues,individually3.  Determineifthera0onalnumberisnega0veorzero4.  Performnormalmathema0calopera0onsontwora0onal

numbers(addi0on,subtrac0on,mul0plica0on,division,exponen0a0on)

5.  Logicallycomparetwora0onalnumbers6.  Produceastringrepresenta0onofthera0onalnumber

•  TheobjectsoftheFrac0onclasswillbeimmutablebecausenoneoftheopera0onsmodifytheobjects’instancevariables

11/4/16

85

Required Data Attributes •  Becauseara0onalnumberconsistsoftwointegers,weneedtwoinstancevariablestostorethosevalues:

self._numerator=0self._denominator=1

11/4/16

•  Atno0meshouldthera0onalnumberbeconvertedtoafloa0ng-pointvalueorwewilllosetheprecisiongainedfromworkingwithra0onalnumbers

86

Representing Values Equivalently •  Signedvalues

•  Nega0veandposi0vera0onalnumberseachhavetwoformsthatcanbeusedtospecifythecorrespondingvalue

•  Posi0vevaluescanbeindicatedas1/2 or –1/–2,andnega0vevaluesas–2/5 or 2/–5

•  Whenperforminganarithme0copera0onorlogicallycomparingtwora0onalnumbers,itwillbemucheasierifwehaveasinglewaytorepresentanega0vevalue

•  Forsimplicity,wechoosetosetonlythenumeratortoanega0vevaluewhenthera0onalnumberisnega0ve,andboththenumeratoranddenominatorwillbeposi0veintegerswhenthera0onalnumberisposi0ve

11/4/16

87

Representing Values Equivalently •  Equivalentfrac0ons

•  Forexample,1/4canbewriFenas1/4,2/8,16/64,or123/492•  Itwillbemucheasiertoperformtheopera0onifthenumberisstoredinreducedform

11/4/16

88

The Constructor (1) •  BecauseFractionobjectsareimmutable,theirvaluesmustbesetwhentheyarecreated.Thisrequiresparametervariablesforboththenumeratoranddenominator

def__init__(self,numerator,denominator):

11/4/16

•  Themethodmustcheckforspecialcases:•  Zerodenominators•  Thenumberrepresentszerooranega0venumber

89

The Constructor def__init__(self,numerator=0,denominator=1):ifdenominator==0:raiseZeroDivisionError("Denominatorcannotbezero.")ifnumerator==0:self._numerator=0self._denominator=1else:if(numerator<0anddenominator>=0ornumerator>=0anddenominator<0):sign=-1else:sign=1

11/4/16

90

The Constructor a=abs(numerator)b=abs(denominator)whilea%b!=0:tempA=atempB=ba=tempBb=tempA%tempBself._numerator=abs(numerator)#b*signself._denominator=abs(denominator)#b

11/4/16

91

Testing the Constructor frac1=Fraction(1,8)#Storedas1/8frac2=Fraction(-2,-4)#Storedas1/2frac3=Fraction(-2,4)#Storedas-1/2frac4=Fraction(3,-7)#Storedas-3/7frac5=Fraction(0,15)#Storedas0/1frac6=Fraction(8,0)#Error!exceptionisraised.

11/4/16

92

Comparing Fractions (1) •  InPython,wecandefineandimplementmethodsthatwillbecalledautoma0callywhenastandardPythonoperator(+,*,==,<)isappliedtoaninstanceoftheclass

•  Forexample,totestwhethertwofrac0onsareequal,wecouldimplementamethod:•  isequal()anduseitasfollows:

iffrac1.isequal(frac2):print("Thefractionsareequal.")

11/4/16

93

Comparing Fractions (2)

•  Automa0callycallsthismethodwhenwecomparetwoFractionobjectsusingthe==operator:

def__eq__(self,rhsValue):return(self._numerator==rhsValue.numeratorandself._denominator==rhsValue.denominator)

iffrac1==frac2:#Callsfrac1.__eq__(frac2)print("Thefractionsareequal.")

11/4/16

•  Ofcourse,wewouldprefertousetheoperator==•  Thisisachievedbydefiningthespecialmethod:

__eq__():

94

Special Methods

•  Thenthe__float__()specialmethodiscalled.

•  Hereisadefini0onofthatmethod:

x=float(frac1)

def__float__(self):returnself._numerator/self._denominator

11/4/16

•  Somespecialmethodsarecalledwhenaninstanceoftheclassispassedtoabuilt-infunc0on.Forexample,supposeyouaFempttoconvertaFractionobjecttoafloa0ngpointnumberusingthefloat()func0on:

95

Common Special Methods

11/4/16

96

Common Special Methods

11/4/16

97

Addition of Fractions •  Allofthearithme0copera0onsthatcanbeperformedonaFractionobjectshouldreturntheresultinanewFractionobject

•  Forexample,whenthestatementbelowisexecuted,frac1shouldbeaddedtofrac2andtheresultreturnedasanewFractionobjectthatisassignedtothenewFracvariable

newFrac=frac1+frac2

11/4/16

98

Fractional Addition •  Fromelementaryarithme0c,youknowthattwofrac0onsmusthaveacommondenominatorinordertoaddthem.Iftheydonothaveacommondenominator,wecans0lladdthemusingtheformula:

11/4/16

99

Defining the Method For Addition def__add__(self,rhsValue):num=(self._numerator*rhsValue._denominator+self._denominator*rhsValue._numerator)den=self._denominator*rhsValue._denominatorreturnFraction(num,den)

11/4/16

100

Logic: Less Than •  Notethata / b < c / dwhend · a < b · c.(Mul0plybothsideswithb ·

d.)

•  Basedonthisobserva0on,thelessthanopera0onisimplementedbythe__lt__()methodasfollows:

def__lt__(self,rhsValue):return(self._numerator*rhsValue._denominatorself._denominator*rhsValue._numerator)

11/4/16

101

Fraction.py

11/4/16

102

Fraction.py

11/4/16

103

Fraction.py

11/4/16

104

Fraction.py

11/4/16

105

Checking Type •  Toensurethatvariablesarethecorrecttype,Pythonprovidesthebuilt-inisinstance()func0onthatcanbeusedtocheckthetypeofobjectreferencedbyavariable.

•  Forexample,theconstructorfortheFractionclassrequirestwointegers

classFraction:def__init__(self,numerator,denominator):if(notisinstance(numerator,int)ornotisinstance(denominator,int)):raiseTypeError("Thenumeratoranddenominatormustbeintegers.")

11/4/16

106

Summary: Classes and Objects •  Aclassdescribesasetofobjectswiththesamebehavior

•  Everyclasshasapublicinterface:acollec0onofmethodsthroughwhichtheobjectsoftheclasscanbemanipulated

•  Encapsula0onistheactofprovidingapublicinterfaceandhidingtheimplementa0ondetails

•  Encapsula0onenableschangesintheimplementa0onwithoutaffec0ngusersofaclass

11/4/16

107

Summary: Variables and Methods •  Anobject’sinstancevariablesstorethedatarequiredforexecu0ngitsmethods

•  Eachobjectofaclasshasitsownsetofinstancevariables•  Aninstancemethodcanaccesstheinstancevariablesoftheobjectonwhichitacts

•  Aprivateinstancevariableshouldonlybeaccessedbythemethodsofitsownclass

•  Classvariableshaveasinglecopyofthevariablesharedamongalloftheinstancesoftheclass

11/4/16

108

Summary: Method Headers, Data •  MethodHeaders

•  Youcanusemethodheadersandmethodcommentstospecifythepublicinterfaceofaclass

•  Amutatormethodchangestheobjectonwhichitoperates•  Anaccessormethoddoesnotchangetheobjectonwhichitoperates

•  DataRepresenta0on•  Foreachaccessormethod,anobjectmusteitherstoreorcomputetheresult

•  Commonly,thereismorethanonewayofrepresen0ngthedataofanobject,andyoumustmakeachoice

•  Besurethatyourdatarepresenta0onsupportsmethodcallsinanyorder

11/4/16

109

Summary: Constructors •  Aconstructorini0alizestheobject’sinstancevariables•  Aconstructorisinvokedwhenanobjectiscreated

•  Theconstructorisdefinedusingthespecialmethodname:__init__()

•  Defaultargumentscanbeusedwithaconstructortoprovidedifferentwaysofcrea0nganobject

11/4/16

110

Summary: Method Implementation •  Theobjectonwhichamethodisappliedisautoma0callypassedtotheselfparametervariableofthemethod

•  Inamethod,youaccessinstancevariablesthroughtheselfparametervariable

11/4/16

111

Summary: Testing Classes •  Aunittestverifiesthataclassworkscorrectlyinisola0on,outsideacompleteprogram

•  Totestaclass,useanenvironmentforinterac0vetes0ng,orwriteatesterclasstoexecutetestinstruc0ons

•  Determiningtheexpectedresultinadvanceisanimportantpartoftes0ng

11/4/16

112

Summary: Object Tracing •  Objecttracingisusedtovisualizeobjectbehavior•  Writethemethodsonthefrontofacard,andtheinstancevariablesontheback

•  Updatethevaluesoftheinstancevariableswhenamutatormethodiscalled

11/4/16

113

Summary: Patterns for Classes •  Aninstancevariableforthetotalisupdatedinmethodsthatincreaseordecreasethetotalamount

•  Acounterthatcountseventsisincrementedinmethodsthatcorrespondtotheevents

•  Anobjectcancollectotherobjectsinalist

•  AnobjectpropertycanbeaccessedwithageFermethodandchangedwithaseFermethod

•  Ifyourobjectcanhaveoneofseveralstatesthataffectthebehavior,supplyaninstancevariableforthecurrentstate

11/4/16

114

Summary: Patterns for Classes •  Tomodelamovingobject,youneedtostoreandupdateitsposi0on

11/4/16

115

Summary: Object References •  Anobjectreferencespecifiestheloca0onofanobject•  Mul0pleobjectvariablescancontainreferencestothesameobject

•  Usetheisandisnotoperatorstotestwhethertwovariablesarealiases

•  TheNonereferencereferstonoobject

11/4/16

116

Summary: Defining Special Methods •  Touseastandardoperatorwithobjects,definethecorrespondingspecialmethod

•  Definethespecial__repr__()methodtocreateastringrepresenta0onofanobject

11/4/16