Download 61A-008-Data_6pp.pdf

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Data Abstraction
All
Programmers
• Compound objects combine primitive objects together
• A date: a year, a month, and a day
• A geographic position: latitude and longitude
• An abstract data type lets us manipulate compound
objects as units
61A Lecture 8
Great
Programmers
• Isolate two parts of any program that uses data:
Wednesday, September 14
! How data are represented (as parts)
! How data are manipulated (as units)
• Data abstraction: A methodology by which functions
enforce an abstraction barrier between
representation and use
2
Rational Numbers
Rational Number Arithmetic
numerator
Example:
denominator
Exact representation of fractions
3
General Form:
3
*
A pair of integers
2
9
nx
=
5
ny
*
10
dx
21
nx
10
dx
nx*ny
=
dy
dx*dy
As soon as division occurs, the exact representation is lost!
Assume we can compose and decompose rational numbers:
Constructor
Selectors
•
make_rat(n, d) returns a rational number x
3
•
numer(x) returns the numerator of x
2
•
denom(x) returns the denominator of x
3
+
=
5
ny
+
nx*dy + ny*dx
=
dy
dx*dy
3
8_rat.py
def add_rat(x, y):
"""Add rational numbers x and y."""
nx, dx = numer(x), denom(x)
ny, dy = numer(y), denom(y)
Rational
Number
Arithmetic
Implementation
return
make_rat(nx
* dy +
ny * dx, dx * dy)
8_rat.py
def mul_rat(x, y):
"""Multiply rational numbers x and y."""
# Arithmetic
return make_rat(numer(x) * numer(y), denom(x) * denom(y))
def add_rat(x, y):
def """Add
equal_rat(x,
y): numbers x and Selectors
Constructor
rational
y."""
"""Return
whether rational
8_rat.py
nx,
dx = numer(x),
denom(x)numbers x and y are equal."""
return
numer(x)
* denom(y)
ny, dy = numer(y),
denom(y)== numer(y) * denom(x)
def return
add_rat(x,
y):
make_rat(nx
* dy + ny * dx, dx * dy)
"""Add rational numbers x and y."""
nx, dx = numer(x),
denom(x)
def mul_rat(x,
y):
ny, dy = numer(y),
denom(y)
"""Multiply
rational
numbers x and y."""
return make_rat(nx
* dy + *nynumer(y),
* dx, dx *
dy)
return
make_rat(numer(x)
denom(x)
* denom(y))
def eq_rat(x,
mul_rat(x, y):
y):
def
"""Multiplywhether
rational
numbersnumbers
x and y."""
"""Return
rational
x and y are equal."""
return
make_rat(numer(x)
* numer(y),
denom(x)
* denom(y))
return numer(x) * denom(y)
== numer(y)
* denom(x)
def equal_rat(x, y):
returnsx aand
rational
number x
"""Return whether
rationald)numbers
y are equal."""
• make_rat(n,
# Constructor
and
selectors
return numer(x) * denom(y) == numer(y) * denom(x)
Wishful
numer(x) returns the numerator of x
•
thinking
from
operator import getitem
• denom(x) returns the denominator of x
def make_rat(n, d):
"""Construct a rational number x that represents n/d."""
5
return (n, d)
def numer(x):
"""Return the numerator of rational number x."""
return getitem(x, 0)
def denom(x):
"""Return the denominator of rational number x."""
4
Page 1
Tuples
Page 1
>>> pair = (1, 2)
>>> pair
(1, 2)
A tuple literal:
Comma-separated expressions
Page 1
>>> x, y = pair
>>> x
1
>>> y
2
"Unpacking" a tuple
>>> from operator import getitem
>>> getitem(pair, 0)
1
>>> getitem(pair, 1)
2
Element selection
More tuples next lecture
6
# Combination
def mul_rat(x, y):
8_rat.py
"""Multiplyy):
rational numbers x and y."""
def
add_rat(x,
return rational
make_rat(numer(x)
numer(y),
"""Add
numbers x *and
y.""" denom(x) * denom(y))
# Combination
nx, dx = numer(x), denom(x)
def ny,
equal_rat(x,
y):
dy = numer(y), denom(y)
def return
add_rat(x,
y):
"""Return
whether
rational
x and
y are equal."""
make_rat(nx
* dy + nynumbers
* dx, dx
* dy)
"""Add
x and
return rational
numer(x) numbers
* denom(y)
== y."""
numer(y) * denom(x)
nx,
dx
=
numer(x),
denom(x)
def mul_rat(x, y):
ny, dy = numer(y),
denom(y)
"""Multiply
rational
numbers x and y."""
return make_rat(numer(x)
make_rat(nx
* dy +* ny
* dx, dxdenom(x)
* dy)
# Constructor
and selectors
Representing
Rational
Numbers
return
numer(y),
* denom(y))
def
mul_rat(x,
y):
fromequal_rat(x,
operator import
def
y): getitem
"""Multiply
rational
numbers
x and x
y."""
"""Return
whether
rational
numbers
and y are equal."""
return
make_rat(numer(x)
* ==
numer(y),
denom(x)
* denom(y))
def return
make_rat(n,
d): * denom(y)
numer(x)
numer(y)
* denom(x)
"""Construct a rational number x that represents n/d."""
def equal_rat(x,
return (n, d)y):
"""Return and
whether
rational numbers x and y are equal."""
# Constructor
selectors
numer(x) * denom(y) == numer(y) * denom(x)
def return
numer(x):
Construct
a
tuple
the numerator
from """Return
operator import
getitem of rational number x."""
return getitem(x, 0)
#
Constructor
and
selectors
def make_rat(n, d):
def """Construct
denom(x):
a rational number x that represents n/d."""
fromreturn
operator
getitem of rational number x."""
"""Return
the
(n, import
d) denominator
return getitem(x, 1)
def
make_rat(n,
d):
def numer(x):
"""Construct
rational of
number
x that
represents
"""Return
the anumerator
rational
number
x.""" n/d."""
return
(n, d)
# String
conversion
return
getitem(x,
0)
return make_rat(nx * dy + ny * dx, dx * dy)
def mul_rat(x,
Page 1 y):
"""Multiply rational numbers x and y."""
return make_rat(numer(x) * numer(y), denom(x) * denom(y))
def equal_rat(x, y):
"""Return whether rational numbers x and y are equal."""
return numer(x) * denom(y) == numer(y) * denom(x)
# Constructor and selectors
Reducing
to Lowest Terms
from operator import getitem
def make_rat(n, d):
"""Construct a rational number x that represents n/d."""
Example:
return (n, d)
def numer(x):
"""Return the numerator of rational number x."""
2
3
5
5
return
getitem(x,
0)
*
# String conversion
15
1/3
25
1/25
2
1
# Improved constructor
from fractions import gcd
def make_rat(n, d):
"""Construct a rational number x that represents n/d in lowest terms."""
g = gcd(n, d)
return (n//g, d//g)
Greatest common divisor
def denom(x):
"""Return
the
denominator
of rational number x."""
Improved
constructor
Select
from
a tuple
## String
conversion
return getitem(x, 1)
fromstr_rat(x):
fractions import gcd
def
def """Return
make_rat(n,
d):
a string
'n/d' for numerator n and denominator d."""
7
# String
conversion
"""Construct
a rational number x that
represents n/d in lowest
terms."""
return
'{0}/{1}'.format(numer(x),
denom(x))
g = gcd(n, d)
def str_rat(x):
return (n//g, d//g)
"""Return
a string 'n/d' for numerator n and denominator d."""
# Improved
constructor
return '{0}/{1}'.format(numer(x), denom(x))
from fractions import gcd
def make_rat(n, d):
# Improved
constructor
"""Construct
a rational number x that represents n/d in lowest terms."""
g = gcd(n, d)
fromreturn
fractions
import
gcd
(n//g,
d//g)
def make_rat(n, d):
"""Construct a rational number x that represents n/d in lowest terms."""
Abstraction
Barriers
Violating
g = gcd(n,
d)
return (n//g, d//g)
8
Abstraction Barriers
Does not use
constructors
Rational numbers in the problem domain
mul_rat
5
1
=
def str_rat(x):
*
=
*
=
"""Return a string 'n/d' for numerator n and denominator d."""
6
1/3
2
50
1/25
2
return
'{0}/{1}'.format(numer(x),
denom(x))
def denom(x):
numer(x):
str_rat(x):
def
"""Return the
the
numerator
rational
number
x."""
a string
'n/d'of
for
numerator
n and
denominator d."""
"""Return
denominator
of
rational
number
x."""
return getitem(x,
getitem(x,
0)
'{0}/{1}'.format(numer(x),
denom(x))
return
1)
add_rat
1
+
=
def denom(x):
5
10
2
3 denominator
2 of rational number
"""Return
the
x."""
return getitem(x, 1)
eq_rat
Twice!
add_rat( (1, 2), (1, 4) )
Rational numbers as numerators & denominators
make_rat
numer
def divide_rat(x, y):
denom
Rational numbers as tuples
tuple
return (x[0] * y[1], x[1] * y[0])
getitem
No selectors!
However tuples are implemented in Python
And no constructor!
9
What is Data?
10
Behavior Conditions of a Pair
To implement our rational number abstract data type,
we used a two-element tuple (also known as a pair).
• We need to guarantee that constructor and selector functions
together specify the right behavior.
What is a pair?
• Rational numbers: If we construct x from n and d,
then numer(x)/denom(x) must equal n/d.
Constructors, selectors, and behavior conditions:
• An abstract data type is some collection of selectors and
constructors, together with some behavior conditions.
If a pair p was constructed from values x and y, then
• If behavior conditions are met, the representation is valid.
•
getitem_pair(p, 0) returns x, and
•
getitem_pair(p, 1) returns y.
You can recognize data types by behavior, not by bits
Together, selectors are the inverse of the constructor
Generally true of container types.
11
Not true for
rational
numbers
12
# Improved constructor
return '{0}/{1}'.format(numer(x), denom(x))
from fractions import gcd
def make_rat(n, d):
# Improved
constructor
"""Construct
a rational number x that represents n/d in lowest terms."""
g = gcd(n, d)
fromreturn
fractions
import
(n//g,
d//g)gcd
def make_rat(n, d):
"""Construct
a rational number x that represents n/d in lowest
Functional
Pair Implementation
Using aterms."""
Functionally Implemented Pair
g = gcd(n,
d)
# Functional
pair
return (n//g, d//g)
>>> p = make_pair(1, 2)
def make_pair(x, y):
As long as we do not violate
"""Return a functional pair."""
the abstraction barrier,
>>> getitem_pair(p, 0)
# Functional
pair
def dispatch(m):
we don't need to know that
1
if m == 0:
pairs are just functions
This function
def make_pair(x,
returny):
x
represents
a pair
>>> getitem_pair(p, 1)
"""Return
pair."""
elif m a==functional
1:
2
def dispatch(m):
return y
if dispatch
m == 0:
return
return x
elif m == 1:i):
def getitem_pair(p,
Constructor is a
If a pair p was constructed from values x and y, then
y
"""Returnreturn
the element
at index
i of pair p."""
higher-order function
return p(i)
dispatch
return
• getitem_pair(p, 0) returns x, and
def getitem_pair(p, i):
"""Return the element at index i of pair p."""
• getitem_pair(p, 1) returns y.
return p(i)
Selector defers to
the object itself
This pair representation is valid!
13
14
Related documents