Transcript of Recitation 6 Programming for Engineers in Python.
- Slide 1
- Recitation 6 Programming for Engineers in Python
- Slide 2
- Agenda Object Oriented Programming: Old McDonald Had a Farm
Time Class 2
- Slide 3
- Example Old McDonald 3 __str__ - Called by the str() built-in
function and by the print statement to compute the informal string
representation of an object: https://gist.github.com/1397677
- Slide 4
- Animal class 4 class Animal: def __init__(self, name, noise):
self.name = name self.noise = noise
- Slide 5
- Farm class 5 class Farm: def __init__(self): self.animals = []
def add(self, animal): self.animals.append(animal)
- Slide 6
- Farm class 6 def __str__(self): s = for animal in self.animals:
s += 'Old MacDonald had a farm, EE-I-EE-I-O,\n' s += 'And on that
farm he had a '+animal.name+', EE-I-EE-I-O,\n' s += 'With a '+
animal.noise + animal.noise+' here and a s += animal.noise +
animal.noise +' there\n' s += 'Here a '+ animal.noise +', there a s
+= animal.noise + ', everywhere a + animal.noise s += animal.noise
+ '\n' s += 'Old MacDonald had a farm, EE-I-EE-I-O.\n return s
- Slide 7
- Sing the song! 7 >>> farm = Farm() >>>
farm.add(Animal('cow','moo')) >>> print farm Old MacDonald
had a farm, EE-I-EE-I-O, And on that farm he had a cow,
EE-I-EE-I-O, With a moomoo here and a moomoo there Here a moo,
there a moo, everywhere a moomoo Old MacDonald had a farm,
EE-I-EE-I-O. >>> farm.add(Animal('duck','kwak'))
>>> farm.add(Animal('dog','woof')) >>>
farm.add(Animal('cat','miaoo'))
- Slide 8
- Sing the song! 8 >>> print farm Old MacDonald had a
farm, EE-I-EE-I-O, And on that farm he had a cow, EE-I-EE-I-O, With
a moomoo here and a moomoo there Here a moo, there a moo,
everywhere a moomoo Old MacDonald had a farm, EE-I-EE-I-O, And on
that farm he had a duck, EE-I-EE-I-O, With a kwakkwak here and a
kwakkwak there Here a kwak, there a kwak, everywhere a kwakkwak Old
MacDonald had a farm, EE-I-EE-I-O, And on that farm he had a dog,
EE-I-EE-I-O, With a woofwoof here and a woofwoof there Here a woof,
there a woof, everywhere a woofwoof Old MacDonald had a farm,
EE-I-EE-I-O, And on that farm he had a cat, EE-I-EE-I-O, With a
miaoomiaoo here and a miaoomiaoo there Here a miaoo, there a miaoo,
everywhere a miaoomiaoo Old MacDonald had a farm, EE-I-EE-I-O.
- Slide 9 >> time = Time(11, 9, 30)">
- A Time class 9 Well define a class called Time that records the
time of day (The Think Python Book, ch. 16 & 17): class
Time(object): """represents the time of day. attributes: hour,
minute, second"" def __init__(self, hour, minute, second):
self.hour = hour self.minute = minute self.second = second
>>> time = Time(11, 9, 30)
- Slide 10 >> print time 11:59:30 >>> time.hour =
0 >>> print time 00:59:30 String formatting:
http://docs.python.org/release/2.5.2/lib/types seq-strings.html
http://docs.python.org/release/2.5.2/lib/types
seq-strings.html"> >> time = Time(11, 59, 30) How would we
print a Time instance? def __str__(self): return "%.2d:%.2d:%.2d" %
(self.hour, self.mi">
- Time class cont. 10 >>> time = Time(11, 59, 30) How
would we print a Time instance? def __str__(self): return
"%.2d:%.2d:%.2d" % (self.hour, self.minute, self.second)
>>> print time 11:59:30 >>> time.hour = 0
>>> print time 00:59:30 String formatting:
http://docs.python.org/release/2.5.2/lib/types seq-strings.html
http://docs.python.org/release/2.5.2/lib/types
seq-strings.html
- Slide 11
- Time class cont. 11 We want to add times for example, its
16:00:00 and I have a meeting in 2 hours: 16:00:00 + 02:00:00 =
18:00:00 def __add__(self, other): hour = self.hour+other.hour
minute = self.minute+other.minute second = self.second+other.second
return Time(hour, minute, second) Is this right? What will happen
when adding 16:00:00 to 16:00:00?
- Slide 12
- Adding times cont. 12 0 hour
- Adding times cont. 13 >>> t1 = Time(16,0,0)
>>> t2 = Time(2,0,0) >>> print t1+t2 18:00:00
>>> print t1+t1 08:00:00
- Slide 14
- Subtracting times 14 Just like addition: def __sub__(self,
other): hour = self.hour - other.hour minute = self.minute -
other.minute second = self.second - other.second minute += second /
60 second = second % 60 hour += minute/60 minute = minute % 60 hour
= hour % 24 return Time(hour, minute, second)
- Slide 15
- Even better 15 def __init__(self, hour, minute, second): minute
= minute + second / 60 hour = hour + minute / 60 self.hour = hour %
24 self.minute = minute % 60 self.second = second % 60 def
__add__(self, other): hour = this.hour + other.hour minute =
this.minute + other.minute second = this.second + other.second
return Time(hour, minute, second)
- Slide 16
- Debugging 16 We want to write a method that verifies that a
Time instance is valid: def valid(self): if self.hour < 0 or
self.minute < 0 or self.second < 0: return False if
self.hour>=24 or self.minute >= 60 or self.second >= 60:
return False return True
- Slide 17
- Exceptions 17 When the program reaches a state it cant handle
or an error it cannot recover from, it raises an exception. This
means it sends an error to the user There are different types of
errors. Examples: IndexError ZeroDivisionError ValueError TypeError
Full list:
http://docs.python.org/library/exceptions.htmlhttp://docs.python.org/library/exceptions.html
- Slide 18
- Debugging cont. 18 We want to verify that a time is valid
before using it and raise an exception if a time is invalid: def
__add__(self,other): if not self.valid() or not other.valid():
raise ValueError(invalid Time object in addition) . This will help
us find errors and alert users of the code on wrong usage Optional:
This can also be written using assert: def __add__(self,other):
assert self.valid() and other.valid() .
- Slide 19
- Comparing Time instances 19 Wed like to be able to compare
times. Right now: >>> t1 = Time(16,0,0) >>> t2 =
Time(5,0,0) >>> t1>t2 False >>> t1 =
Time(16,0,0) >>> t1>t2 True This happens because python
compares the addresses!
- Slide 20
- Comparing Time instances cont. 20 Wed like to be able to
compare times: def __cmp__(self, other): tup1 = (self.hour,
self.minute, self.second) tup2 = (other.hour, other.minute,
other.second) return cmp(tup1, tup2) >>>
Time(16,0,0)>Time(11,30,0) True >>>
Time(16,0,0)>Time(16,0,1) False
- Slide 21
- Object representation 21 >>> t1 = Time(16,0,0)
>>> print t1 # calls __str__ 16:00:00 >>> t1 If
we want a different output we must override the __repr__
method
- Slide 22
- Object representation cont. 22 def __repr__(self): return
self.__class__.__name__+" instance: "+self.__str__() >>> t
= Time(16,0,0) >>> t Time instance: 16:00:00 Note the use
of these attributes: >>> cls = t.__class__ >>>
cls >>> cls.__name__ Time
- Slide 23
- Time as number of seconds 23 We note that the time of day can
also be denoted by the number of seconds since the beginning of the
day: def to_seconds(self): return self.hour*3600 + self.minute*60 +
self.second >>> time = Time(16,0,0) >>>
time.to_seconds() 5760 We already have the other direction from
__init__ (see here)see here
- Slide 24
- Time as number of seconds cont. 24 This also simplifies the
_add__ and __sub__ methods: def __add__(self, other): secs =
self.to_seconds() + other.to_seconds() return Time(0,0, secs) def
__sub__(self,other): secs = self.to_seconds() - other.to_seconds()
return Time(0,0, secs)
- Slide 25
- Comparing is also easier 25 We can also change __cmp__: def
__cmp__(self, other): return cmp(self.to_seconds(),
other.to_seconds()) >>> t1 = Time(16,0,0) >>> t2
= Time(21,0,0) >>> t1>t2 False
- Slide 26
- Type checking, adding integers 26 The next step is to allow
__add__ to add either seconds or Time def __add__(self, other):
secs = self.to_seconds() if isinstance(other, Time):# is other a
Time? secs += other.to_seconds() elif isinstance(other, int):# is
other an int? secs += other return Time(0,0,secs) # creating a new
time
- Slide 27
- Type checking, adding integers 27 Now we can use the + operator
with either int or Time: >>> time = Time(16,0,0)
>>> print time+60 16:01:00 >>> print
time+Time(0,1,0) 16:01:00
- Slide 28
- Type checking, adding integers 28 What if we add a float? Lets
change the if-else: def __add__(self, other): secs =
self.to_seconds() if isinstance(other,Time): secs +=
other.to_seconds() elif isinstance(other,int): secs += other else:
raise TypeError("Can't add Time and +other.__class__.__name__)
return Time(0,0,secs)
- Slide 29 >> time + 5.0 Traceback (most recent call last):
File " ", line 1, in t1+5. File "C:/python_course/Time.py", line
3">
- Type checking, adding integers 29 >>> time + 5.0
Traceback (most recent call last): File " ", line 1, in t1+5. File
"C:/python_course/Time.py", line 38, in __add__ raise
TypeError("Can't add Time and "+other.__class__.__name__)
TypeError: Can't add Time and float
- Slide 30
- Right-side addition 30 >>> print time + 60 16:01:00
>>> print 60 + time Traceback (most recent call last):
File " ", line 1, in 60 + time TypeError: unsupported operand
type(s) for +: 'int' and 'Time We need to implement __radd__!
- Slide 31
- Right-side addition cont. 31 def __radd__(self,other): return
self.__add__(other) >>> print 60 + time 16:01:00
Alternatively we can write: def __radd__(self,other): return
self+other
- Slide 32
- The benefits of overriding + 32 We can use the built-in sum:
>>> sum([Time(1,0,1),Time(2,0,2), Time(3,0,3)]) Time
instance: 06:00:06
- Slide 33
- Home work 6: Point class 33 We will write a class for a Point -
2-D vector Operator overloading:
http://docs.python.org/library/operator.html All instructions in
hw6.pdf Use what we learned: class Rational class Time