VT 2014 TDDC74 Programming: Abstraktion och modellering Johannes Schmidt

advertisement
TDDC74 Programming:
Abstraktion och modellering
VT 2014
Johannes Schmidt
Institutionen för datavetenskap
Linköpings universitet
Lecture 6
Data Abstraction
*
*
*
*
*
Manual debugging, find hidden syntax errors
Data Abstraktion: Family example
Data Abstraktion: Binary Tree example
PUTPROP, GETPROP, APPLY
Data Abstraktion: Data-Directed-Prog. example
* SICP 2, Del 3
Manual debugging
What is debugging?
Find and fix a bug.
What is a bug?
A semantic error.
(compilable / evaluabe but it does not behave as desired)
Manual debugging
Example:
(define pi 4.141592)
(define (get-circle-area r)
(* r r r pi))
(define my-circle-radius 5)
; radius is 6, => expected area: 113.097
> (get-circle-area my-circle-radius)
517.699
What to do:
Enrich your code (temporarily) with additional instructions,
such as checks (conditions) and display instructions, such
that it might display helpful information, in order to localize
the bug.
Find hidden syntax errors
Sometimes an expression (or a whole program) does not
compile (is not evaluable) but the compilers/interpreters
indications are not helpful to localize the faulty piece of code.
What to do?
Binary search with outcommenting (big) pieces of code!
#|
…
|#
Data Abstraction: What
properties does a person have?
A person has:
- Name
- Birth year
- Father
- Mother
- Sex
- …
Data Abstraktion:
Using a person object
; Constructor
(create-person name birthyear father mother sex)
; Selectors
(name person)
(birthyear person)
(father person)
(mother person)
(sex person)
; Recognizers
(define (female? person)
(eq? (sex person) 'w))
(define (male? person)
(eq? (sex person) 'm))
; Comparators
(define (older p1 p2)(< (birthyear p1) (birthyear p2)))
Implementation of Constructor
and Selectors (v1)
; Constructor
(define (create-person nameP birthyearP fatherP motherP sexP)
(list nameP birthyearP fatherP motherP sexP))
; Selectors
(define (name person) (car person))
(define (birthyear person) (cadr person))
(define (father person) (caddr person))
(define (mother person) (cadddr person))
(define (sex person) (cadddr (cdr person)))
Implementation of Constructor
and Selectors (v2)
; Constructor
(define (create-person nameP birthyearP fatherP motherP sexP)
(list birthyearP nameP fatherP motherP sexP))
; Selectors
(define (birthyear person) (car person))
(define (name person) (cadr person))
(define (father person) (caddr person))
(define (mother person) (cadddr person))
(define (sex person) (cadddr (cdr person)))
assv
(assv e lst)
– lst must be a list of
pairs. Locates the first element of lst whose
car is equal to e according to eqv?. If such an
element exists, the pair (i.e., an element of lst)
is returned. Otherwise, the result is #f.
(define mylist (list (cons
(cons
(cons
(cons
(assv 'key3 mylist )
> (key3 . 11)
'key1
'key2
'key3
'key4
3)
17)
11)
242)))
Implementation of Constructor
and Selectors (v3)
; Constructor
(define (create-person nameP birthyearP fatherP motherP sexP)
(list (cons 'name nameP)
(cons 'birthyear birthyearP)
(cons 'father fatherP)
(cons 'mother motherP)
(cons 'sex sexP)))
; Selectors
(define (name person)
(cdr (assv 'name person)))
(define (birthyear person) (cdr (assv 'birthyear person)))
(define (father person)
(cdr (assv 'father person)))
(define (mother person)
(cdr (assv 'mother person)))
(define (sex person)
(cdr (assv 'sex person)))
Binary trees in programming
root
3
parent
children
8
2
9
6
4
leaves
7
Each node has:
1. Value
2. left child
3. right child
What properties do we
need from a (binary) tree?
A node-entity, with methods:

get-value – returns the nodes value
get-left – returns the left branch
get-right – returns the right branch
leaf? – test if the tree is a leaf (no children)
empty? – test if the tree is empty

Constructor – (make-btree value left right)




Implementation of Constructor
and Selectors (v1)
; Constructors
(define (make-btree value left right)
(list value left right))
(define (make-empty-btree)
'())
; Selectors
(define (get-value btree)
(car btree))
(define (get-left btree)
(car (cdr btree)))
(define (get-right btree)
(car (cdr (cdr btree))))
; Predicates
(define (empty-btree? btree) (eqv? btree (make-empty-btree)))
(define (leaf? btree)
(and (empty-btree? (get-left btree))
(empty-btree? (get-right btree))))
Implementation of Constructor
and Selectors (v2)
; Constructors
(define (make-btree value left right)
(cons value (cons left right)))
(define (make-empty-btree)
'E)
; Selectors
(define (get-value btree)
(car btree))
(define (get-left btree)
(car (cdr btree)))
(define (get-right btree)
(cdr (cdr btree)))
; Predicates : unchanged!
(define (empty-btree? btree) (eqv? btree (make-empty-btree)))
(define (leaf? btree)
(and (empty-btree? (get-left btree))
(empty-btree? (get-right btree))))
Is e present in the tree?
Exhaustive search:
(define (btree-present? e btree)
(cond ((empty-btree? btree) #f)
((equal? (get-value btree) e) #t)
(else (or (btree-present? e (get-left btree))
(btree-present? e (get-right btree))))))
A remark on binary search
Intelligent search:
(only possible if the tree is a Binary Search Tree:
left branch = smaller elements, right branch = greater elements)
(define (bstree-present? e btree)
(cond ((empty-btree? btree) #f)
((equal? (get-value btree) e) #t)
(else (if (< e (get-value btree))
(bstree-present? e (get-left btree))
(bstree-present? e (get-right btree))))))
Scenario: represent
geometric objects v1
(define (make-circle radius) radius)
(define (make-square side)
side)
(define (make-rect a b)
(cons a b))
(define (circle-area radius)
(* radius radius pi))
(define (square-area side)
(* side side))
(define (rect-area param)
(* (car param) (cdr param)))
(define (circle-circ radius)
(* 2 radius pi))
(define (square-circ side)
(* side 4))
(define (rect-circ param)
(+ (* 2 (car param))
(* 2 (cdr param))))
Scenario: represent
geometric objects v2
(define (make-circle radius) (list 'circle radius))
(define (make-square side)
(list 'square side))
(define (make-rect a b)
(list 'rect a b))
(define (circle-area param)
(* (car param) (car param) pi))
(define (square-area param)
(* (car param) (car param)))
(define (rect-area param)
(* (car param) (cadr param)))
(define (circle-circ param)
(* 2 (car param) pi))
(define (square-circ param)
(* (car param) 4))
(define (rect-circ param)
(+ (* 2 (car param))
(* 2 (cadr param))))
(define (tag
object) (car object))
(define (data object) (cdr object))
Scenario: represent
geometric objects v2
(define (area object)
(cond ((eqv? (tag object) 'circle) (circle-area (data object)))
((eqv? (tag object) 'square) (square-area (data object)))
((eqv? (tag object) 'rect)
(rect-area
(data object)))))
(define (circ object)
(cond ((eqv? (tag object) 'circle) (circle-circ (data object)))
((eqv? (tag object) 'square) (square-circ (data object)))
((eqv? (tag object) 'rect)
(area mycircle)
(area mysquare)
(rect-circ
(data object)))))
Uniform area and circ methods
for all objects!
(circ mysquare)
But we can make that more elegant…
(circ myrect)
1. Use apply 2. use putprop / getprop
Apply
(apply proc l) – applies proc to the
parameters in the list l.
> (apply + '(1 2 3))
6
> (apply inc '(6))
7
> (apply cons '(4 a))
'(4 . a)
putprop / getprop
(putprop
object-type
operation-name
object-type-specific-operation)
Saves the 3-tuple in a table.
(getprop object-type
operation-name)
Allows to retrieve the accociated
object-type-specific-operation.
Scenario: represent
geometric objects v3
(define (make-circle radius) (list 'circle radius))
(define (make-square side)
(list 'square side))
(define (make-rect a b)
(list 'rect a b))
(define (circle-area radius)
(* radius radius pi))
(define (square-area side)
(* side side))
(define (rect-area a b)
(* a b))
(define (circle-circ radius)
(* 2 radius pi))
(define (square-circ side)
(* side 4))
(define (rect-circ a b)
(+ (* 2 a) (* 2 b)))
(define (tag
object) (car object))
(define (data object) (cdr object))
Scenario: represent
geometric objects v3
(putprop 'circle 'area
circle-area)
(putprop 'square 'area
square-area)
(putprop 'rect
rect-area)
'area
(define (area object)
(let* ((tag (tag object))
(proc (getprop tag 'area)))
(if (not proc)
(error "No area method found -- AREA" tag)
(apply proc (data object)))))
(area mycircle)
(area mysquare)
(area myrect)
SICP on Data Abstraction
The basic idea of data abstraction is to structure the
programs that are to use compound data objects so
that they operate on “abstract data.” That is, our
programs should use data in such a way as to make no
assumptions about the data that are not strictly
necessary for performing the task at hand. At the same
time, a “concrete” data representation is defined
independent of the programs that use the data. The
interface between these two parts of our system will be
a set of procedures, called selectors and constructors,
that implement the abstract data in terms of the
concrete representation.
– Abelson, Sussman, & Sussman: SICP
SICP on Data Abstraction
The basic idea of data abstraction is to structure the
programs that are to use compound data objects so
that they operate on “abstract data.” That is, our
programs should use data in such a way as to
make no assumptions about the data that are
not strictly necessary for performing the task at
hand. At the same time, a “concrete” data
representation is defined independent of the
programs that use the data. The interface between
these two parts of our system will be a set of
procedures, called selectors and constructors, that
implement the abstract data in terms of the concrete
representation.
– Abelson, Sussman, & Sussman: SICP
Data Abstraction - essence
Specify an interface.
Make its
Implementation
Independent from its
Usage.
Data Abstraktion:
Using a person object
Interface
Specification
No scheme code!
; Constructor
(create-person name birthyear father mother sex)
; Selectors
(name person)
(birthyear person)
(father person)
(mother person)
(sex person)
; Recognizers
(define (female? person)
(eq? (sex person) 'w))
(define (male? person)
(eq? (sex person) 'm))
; Comparators
(define (older p1 p2)(< (birthyear p1) (birthyear p2)))
Data Abstraktion:
Using a person object
Usage
; Constructor
(create-person name birthyear father mother sex)
; Selectors
(name person)
(birthyear person)
(father person)
(mother person)
(sex person)
; Recognizers
(define (female? person)
(eq? (sex person) 'w))
(define (male? person)
(eq? (sex person) 'm))
; Comparators
(define (older p1 p2)(< (birthyear p1) (birthyear p2)))
Implementation of Constructor
and Selectors (v1)
; Constructor
(define (create-person nameP birthyearP fatherP motherP sexP)
(list nameP birthyearP fatherP motherP sexP))
; Selectors
(define (name person) (car person))
(define (birthyear person) (cadr person))
(define (father person) (caddr person))
(define (mother person) (cadddr person))
(define (sex person) (cadddr (cdr person)))
Implementation
What properties do we
need from a (binary) tree?
A node-entity, with methods:
Interface
Specification

get-value – returns the nodes value
get-left – returns the left branch
get-right – returns the right branch
leaf? – test if the tree is a leaf (no children)
empty? – test if the tree is empty

Constructor – (make-btree value left right)




Is e present in the tree?
Usage
Exhaustive search:
(define (btree-present? e btree)
(cond ((empty-btree? btree) #f)
((equal? (get-value btree) e) #t)
(else (or (btree-present? e (get-left btree))
(btree-present? e (get-right btree))))))
Implementation of Constructor
Implementation
and Selectors (v1)
; Constructors
(define (make-btree value left right)
(list value left right))
(define (make-empty-btree)
'())
; Selectors
(define (get-value btree)
(car btree))
(define (get-left btree)
(car (cdr btree)))
(define (get-right btree)
(car (cdr (cdr btree))))
; Predicates
(define (empty-btree? btree) (eqv? btree (make-empty-btree)))
(define (leaf? btree)
(and (empty-btree? (get-left btree))
(empty-btree? (get-right btree))))
Download