Lecture 21 - cs.cornell.edu
Transcript of Lecture 21 - cs.cornell.edu
![Page 1: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/1.jpg)
Dynamic Typing
Lecture 21
![Page 2: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/2.jpg)
Announcements for This Lecture
Prelim 2 Assignments
11/9/21 2Dynamic Typing
• Prelim, Thurs. at 7:30§ A–D in Kennedy 116§ E-Z in Bailey 101
• Material up to Nov. 4§ Recursion + Loops + Classes§ No dynamic typing
• Conflict with Prelim?§ Should have gotten e-mail
• A5 is now graded§ Mean: 48.1 Median: 49 § A: 47 (85%), B: 40 (12%)
§ Solutions posted in CMS
• Hopefully far enough on A6
• Lessons 24, 25 for today• Lesson 26 for next time
Optional Videos
![Page 3: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/3.jpg)
What is Typing?
• We know what a (Python) type is§ All values in Python have a type§ Typing: act of finding the type of a value§ Example: type(x) == int
• Commonly used in preconditions§ Definition assumes certain operations§ If operations are missing, def may crash§ So we use assert to check for operations
11/9/21 Dynamic Typing 3
![Page 4: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/4.jpg)
class Fraction(object):"""Instances are normal fractions n/d"""# INSTANCE ATTRIBUTES# _numerator: int# _denominator: int > 0
class BinaryFraction(Fraction):"""Instances are fractions k/2n """# INSTANCE ATTRIBUTES same but# _denominator: int = 2n, n ≥ 0
def __init__(self,k,n):"""Make fraction k/2n """assert type(n) == int and n >= 0super().__init__(k,2 ** n)
>>> p = Fraction(1,2)>>> q = BinaryFraction(1,2) # 1/4
>>> r = p*q
>>> r = p.__mul__(q) # ERROR
Python converts to
__mul__ has preconditiontype(q) == Fraction
11/9/21 Dynamic Typing 4
A Problem with Subclasses
![Page 5: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/5.jpg)
The isinstance Function
• isinstance(<obj>,<class>)§ True if <obj>’s class is same
as or a subclass of <class> § False otherwise
• Example:§ isinstance(e,Executive) is True§ isinstance(e,Employee) is True§ isinstance(e,object) is True§ isinstance(e,str) is False
• Generally preferable to type§ Works with base types too!
11/9/21 Dynamic Typing 5
e id4
id4Executive
_salary 0.0
_start 2012
_name 'Fred'
_bonus 0.0
object
Employee
Executive
![Page 6: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/6.jpg)
isinstance and Subclasses
>>> e = Employee('Bob',2011)>>> isinstance(e,Executive)???
11/9/21 Dynamic Typing 6
A: TrueB: FalseC: ErrorD: I don’t know
e id5
id5Employee
_salary 50k
_start 2012
_name 'Bob'
object
Employee
Executive
![Page 7: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/7.jpg)
isinstance and Subclasses
>>> e = Employee('Bob',2011)>>> isinstance(e,Executive)???
11/9/21 Dynamic Typing 7
A: TrueB: FalseC: ErrorD: I don’t know
object
Executive
Employee
→ means “extends” or “is an instance of”
Correct
![Page 8: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/8.jpg)
Fixing Multiplication
class Fraction(object):"""Instances are fractions n/d"""# _numerator: int# _denominator: int > 0
def __mul__(self,q):"""Returns: Product of self, qMakes a new Fraction; does not modify contents of self or qPrecondition: q a Fraction"""assert isinstance(q, Fraction)top = self.numerator*q.numeratorbot = self.denominator*q.denominatorreturn Fraction(top,bot)
>>> p = Fraction(1,2)>>> q = BinaryFraction(1,2) # 1/4
>>> r = p*q
>>> r = p.__mul__(q) # OKAY
Python converts to
Can multiply so long as it has numerator, denominator
11/9/21 Dynamic Typing 8
![Page 9: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/9.jpg)
Error Types in Python
def foo():assert 1 == 2, 'My error'…
>>> foo()AssertionError: My error
def foo():x = 5 / 0…
>>> foo()ZeroDivisionError: integer division or modulo by zero
11/9/21 Dynamic Typing 9
Class Names
![Page 10: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/10.jpg)
Error Types in Python
def foo():assert 1 == 2, 'My error'…
>>> foo()AssertionError: My error
def foo():x = 5 / 0…
>>> foo()ZeroDivisionError: integer division or modulo by zero
11/9/21 Dynamic Typing 10
Class Names
Information about an error is stored inside an object.The error type is the classof the error object.
![Page 11: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/11.jpg)
Error Types in Python• All errors are instances of class BaseException• This allows us to organize them in a hierarchy
11/9/21 Dynamic Typing 11
BaseException
AssertionError
Exception
id4
AssertionError
'My error'
→ means “extends” or “is an instance of”
__init__(self,msg)__str__(self)…
BaseException
Exception(BE)
AssError(E)
![Page 12: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/12.jpg)
Error Types in Python• All errors are instances of class BaseException• This allows us to organize them in a hierarchy
11/9/21 Dynamic Typing 12
id4
AssertionError
'My error'
→ means “extends” or “is an instance of”
BaseException
AssertionError
Exception
__init__(self,msg)__str__(self)…
BaseException
Exception(BE)
AssError(E)
All of these are actually empty!
Why?
![Page 13: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/13.jpg)
Python Error Type Hierarchy
11/9/21 Dynamic Typing 13
BaseException
ExceptionSystemExit
AssertionError ArithmeticErrorAttributeError ValueErrorTypeErrorIOError …
ZeroDivisionError OverflowError …
Argument has wrong type
(e.g. float([1]))
Argument has wrong value
(e.g. float('a'))
Why so many error types?http://docs.python.org/library/exceptions.html
![Page 14: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/14.jpg)
Recall: Recovering from Errors
• try-except blocks allow us to recover from errors§ Do the code that is in the try-block§ Once an error occurs, jump to the catch
• Example:try:
val = input() # get number from userx = float(val) # convert string to floatprint('The next number is '+str(x+1))
except:print('Hey! That is not a number!')
might have an error
executes if have an error
11/9/21 14Dynamic Typing
![Page 15: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/15.jpg)
Handling Errors by Type
• try-except blocks can be restricted to specific errors§ Doe except if error is an instance of that type§ If error not an instance, do not recover
• Example:try:
val = input() # get number from userx = float(val) # convert string to floatprint('The next number is '+str(x+1))
except ValueError:print('Hey! That is not a number!')
Only recovers ValueError.Other errors ignored.
11/9/21 15Dynamic Typing
May have ValueError
May have IOError
![Page 16: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/16.jpg)
Handling Errors by Type
• try-except blocks can be restricted to specific errors§ Doe except if error is an instance of that type§ If error not an instance, do not recover
• Example:try:
val = input() # get number from userx = float(val) # convert string to floatprint('The next number is '+str(x+1))
except IOError:print('Check your keyboard!')
Only recovers IOError.Other errors ignored.
11/9/21 16Dynamic Typing
May have ValueError
May have IOError
![Page 17: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/17.jpg)
Creating Errors in Python
def foo(x):assert x < 2, 'My error'…
def foo(x):if x >= 2:
m = 'My error'err = AssertionError(m)raise err
11/9/21 Dynamic Typing 17
• Create errors with raise§ Usage: raise <exp>§ exp evaluates to an object§ An instance of Exception
• Tailor your error types§ ValueError: Bad value§ TypeError: Bad type
• Still prefer asserts for preconditions, however§ Compact and easy to read
Identical
![Page 18: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/18.jpg)
Creating Errors in Python
def foo(x):assert x < 2, 'My error'…
def foo(x):if x >= 2:
m = 'My error'err = ValueError(m)raise err
11/9/21 Dynamic Typing 18
• Create errors with raise§ Usage: raise <exp>§ exp evaluates to an object§ An instance of Exception
• Tailor your error types§ ValueError: Bad value§ TypeError: Bad type
• Still prefer asserts for preconditions, however§ Compact and easy to read
Identical
![Page 19: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/19.jpg)
Raising and Try-Except
def foo():x = 0try:
raise Exception()x = 2
except Exception:x = 3
return x
• The value of foo()?
11/9/21 Dynamic Typing 19
A: 0B: 2C: 3D: No value. It stops!E: I don’t know
![Page 20: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/20.jpg)
Raising and Try-Except
def foo():x = 0try:
raise Exception()x = 2
except Exception:x = 3
return x
• The value of foo()?
11/9/21 Dynamic Typing 20
A: 0B: 2C: 3D: No value. It stops!E: I don’t know
Correct
![Page 21: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/21.jpg)
Raising and Try-Except
def foo():x = 0try:
raise Exception()x = 2
except BaseException:x = 3
return x
• The value of foo()?
11/9/21 Dynamic Typing 21
A: 0B: 2C: 3D: No value. It stops!E: I don’t know
![Page 22: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/22.jpg)
Raising and Try-Except
def foo():x = 0try:
raise Exception()x = 2
except BaseException:x = 3
return x
• The value of foo()?
11/9/21 Dynamic Typing 22
A: 0B: 2C: 3D: No value. It stops!E: I don’t know
Correct
![Page 23: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/23.jpg)
Raising and Try-Except
def foo():x = 0try:
raise Exception()x = 2
except AssertionError:x = 3
return x
• The value of foo()?
11/9/21 Dynamic Typing 23
A: 0B: 2C: 3D: No value. It stops!E: I don’t know
![Page 24: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/24.jpg)
Raising and Try-Except
def foo():x = 0try:
raise Exception()x = 2
except AssertionError:x = 3
return x
• The value of foo()?
11/9/21 Dynamic Typing 24
A: 0B: 2C: 3D: No value. It stops!E: I don’t know
Correct
Python uses isinstanceto match Error types
![Page 25: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/25.jpg)
Creating Your Own Exceptions
class CustomError(Exception):"""An instance is a custom exception"""pass
This is all you need§ No extra attributes§ No extra methods§ No constructorsInherit everything
11/9/21 25Dynamic Typing
Only issues is choice of parent error class.Use Exception if you
are unsure what.
![Page 26: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/26.jpg)
Handling Errors by Type
• try-except can put the error in a variable• Example:
try:val = input() # get number from userx = float(val) # convert string to floatprint('The next number is '+str(x+1))
except ValueError as e:print(e.args[0])print('Hey! That is not a number!')
11/9/21 26Dynamic Typing
Some Error subclasses have more attributes
![Page 27: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/27.jpg)
Accessing Attributes with Strings
• hasattr(<obj>,<name>)§ Checks if attribute exists
• getattr(<obj>,<name>)§ Reads contents of attribute
• delattr(<obj>,<name>)§ Deletes the given attribute
• setattr(<obj>,<name>,<val>)§ Sets the attribute value
• <obj>.__dict__§ List all attributes of object
11/9/21 Dynamic Typing 27
id1
2.0
3.0
5.0
Point3
x
y
z
id2
2.0
3.0
5.0
dict
'x'
'y'
'z'
Treat objectlike dictionary
![Page 28: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/28.jpg)
Typing Philosophy in Python
• Duck Typing:§ “Type” object is determined
by its methods and properties§ Not the same as type() value§ Preferred by Python experts
• Implement with hasattr()§ hasattr(<object>,<string>)§ Returns true if object has an
attribute/method of that name• This has many problems
§ The name tells you nothing about its specification
11/9/21 Dynamic Typing 28
class Fraction(object):"""Instances are fractions n/d"""# numerator: int# denominator: int > 0…def __eq__(self,q):
"""Returns: True if self, q equal, False if not, or q not a Fraction"""if type(q) != Fraction:
return Falseleft = self.numerator*q.denominatorrght = self.denominator*q.numeratorreturn left == rght
![Page 29: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/29.jpg)
Typing Philosophy in Python
• Duck Typing:§ “Type” object is determined
by its methods and properties§ Not the same as type() value§ Preferred by Python experts
• Implement with hasattr()§ hasattr(<object>,<string>)§ Returns true if object has an
attribute/method of that name• This has many problems
§ The name tells you nothing about its specification
11/9/21 Dynamic Typing 29
class Fraction(object):"""Instances are fractions n/d"""# numerator: int# denominator: int > 0…def __eq__(self,q):
"""Returns: True if self, q equal, False if not, or q not a Fraction"""if (not (hasattr(q,'numerator') and
hasattr(q,'denomenator')): return False
left = self.numerator*q.denominatorrght = self.denominator*q.numeratorreturn left == rght
![Page 30: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/30.jpg)
Typing Philosophy in Python
• Duck Typing:§ “Type” object is determined
by its methods and properties§ Not the same as type() value§ Preferred by Python experts
• Implement with hasattr()§ hasattr(<object>,<string>)§ Returns true if object has an
attribute/method of that name• This has many problems
§ The name tells you nothing about its specification
11/9/21 Dynamic Typing 30
class Fraction(object):"""Instances are fractions n/d"""# numerator: int# denominator: int > 0…def __eq__(self,q):
"""Returns: True if self, q equal, False if not, or q not a Fraction"""if (not (hasattr(q,'numerator') and
hasattr(q,'denomenator')): return False
left = self.numerator*q.denominatorrght = self.denominator*q.numeratorreturn left == rght
Compares anything with numerator & denominator
![Page 31: Lecture 21 - cs.cornell.edu](https://reader031.fdocuments.in/reader031/viewer/2022020916/61ad3b749e5731384c70cea7/html5/thumbnails/31.jpg)
Final Word on Typing
• How to implement/use typing is controversial§ Major focus in designing new languages§ Some langs have no types; others complex types
• Trade-of between ease-of-use and robustness§ Complex types allow automated bug finding§ But make they also make code harder to write
• What we really care about is specifications§ Duck Typing: we think the value meets a spec§ Types guarantee that a specification is met
11/9/21 Dynamic Typing 31