CS61A Lecture 26 Amir Kamil and Hamilton Nguyen UC Berkeley March - - PowerPoint PPT Presentation
CS61A Lecture 26 Amir Kamil and Hamilton Nguyen UC Berkeley March - - PowerPoint PPT Presentation
CS61A Lecture 26 Amir Kamil and Hamilton Nguyen UC Berkeley March 22, 2013 Announcements HW9 out tonight, due 4/3 Ants extra credit due 4/3 See Piazza for submission instructions Data Structure Applications Data
HW9 out tonight, due 4/3 Ants extra credit due 4/3
See Piazza for submission instructions
Announcements
Data Structure Applications
The data structures we cover in 61A are used everywhere in CS
Data Structure Applications
The data structures we cover in 61A are used everywhere in CS More about data structures in 61B
Data Structure Applications
The data structures we cover in 61A are used everywhere in CS More about data structures in 61B Example: recursive lists (also called linked lists)
Data Structure Applications
The data structures we cover in 61A are used everywhere in CS More about data structures in 61B Example: recursive lists (also called linked lists)
- Operating systems
Data Structure Applications
The data structures we cover in 61A are used everywhere in CS More about data structures in 61B Example: recursive lists (also called linked lists)
- Operating systems
- Interpreters and compilers
Data Structure Applications
The data structures we cover in 61A are used everywhere in CS More about data structures in 61B Example: recursive lists (also called linked lists)
- Operating systems
- Interpreters and compilers
- Anything that uses a queue
Data Structure Applications
The data structures we cover in 61A are used everywhere in CS More about data structures in 61B Example: recursive lists (also called linked lists)
- Operating systems
- Interpreters and compilers
- Anything that uses a queue
The Scheme programming language, which we will learn soon, uses recursive lists as its primary data structure
Data Structure Applications
Example: Environments
Example: http://goo.gl/8DNY1
Example: Environments
Example: http://goo.gl/8DNY1
Recursive List
Example: Environments
Example: http://goo.gl/8DNY1
Recursive List
Example: Environments
Example: http://goo.gl/8DNY1
Recursive List
Example: Environments
Example: http://goo.gl/8DNY1
Recursive List
Example: Environments
Example: http://goo.gl/8DNY1
Recursive List
Example: Environments
Example: http://goo.gl/8DNY1
Recursive List
Example: Environments
Example: http://goo.gl/8DNY1
Recursive List
Example: Environments
Example: http://goo.gl/8DNY1
Recursive List
Example: Environments
Example: http://goo.gl/8DNY1
Recursive List Rest is Empty
Trees with Internal Node Values
Trees can have values at internal nodes as well as their leaves.
class Tree(object): def __init__(self, entry, left=None, right=None): self.entry = entry self.left = left self.right = right def fib_tree(n): if n == 1: return Tree(0) if n == 2: return Tree(1) left = fib_tree(n - 2) right = fib_tree(n - 1) return Tree(left.entry + right.entry, left, right)
Implementing Sets
What we should be able to do with a set:
- Membership testing: Is a value an element of a set?
- Union: Return a set with all elements in set1 or set2
- Intersection: Return a set with any elements in set1 and set2
- Adjunction: Return a set with all elements in s and a value v
Union
1 3 4 2 3 5 1 3 4 2 5
Intersection
1 3 4 2 3 5 3
Adjunction
1 3 4 2 1 3 4 2
Sets as Unordered Sequences
Proposal 1: A set is represented by a recursive list that contains no duplicate items This is how we implemented dictionaries
def empty(s): return s is Rlist.empty def set_contains(s, v): if empty(s): return False elif s.first == v: return True return set_contains(s.rest, v)
Sets as Unordered Sequences
Sets as Unordered Sequences
def adjoin_set(s, v):
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v):
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v): return s
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v): return s return Rlist(v, s)
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v): return s return Rlist(v, s)
Time order of growth
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v): return s return Rlist(v, s)
Time order of growth
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v): return s return Rlist(v, s)
Time order of growth The size of the set
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v): return s return Rlist(v, s) def intersect_set(set1, set2):
Time order of growth The size of the set
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v): return s return Rlist(v, s) def intersect_set(set1, set2): f = lambda v: set_contains(set2, v)
Time order of growth The size of the set
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v): return s return Rlist(v, s) def intersect_set(set1, set2): f = lambda v: set_contains(set2, v) return filter_rlist(set1, f)
Time order of growth The size of the set
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v): return s return Rlist(v, s) def intersect_set(set1, set2): f = lambda v: set_contains(set2, v) return filter_rlist(set1, f)
Time order of growth The size of the set
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v): return s return Rlist(v, s) def intersect_set(set1, set2): f = lambda v: set_contains(set2, v) return filter_rlist(set1, f)
Time order of growth The size of the set Assume sets are the same size
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v): return s return Rlist(v, s) def intersect_set(set1, set2): f = lambda v: set_contains(set2, v) return filter_rlist(set1, f) def union_set(set1, set2):
Time order of growth The size of the set Assume sets are the same size
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v): return s return Rlist(v, s) def intersect_set(set1, set2): f = lambda v: set_contains(set2, v) return filter_rlist(set1, f) def union_set(set1, set2): f = lambda v: not set_contains(set2, v)
Time order of growth The size of the set Assume sets are the same size
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v): return s return Rlist(v, s) def intersect_set(set1, set2): f = lambda v: set_contains(set2, v) return filter_rlist(set1, f) def union_set(set1, set2): f = lambda v: not set_contains(set2, v) set1_not_set2 = filter_rlist(set1, f)
Time order of growth The size of the set Assume sets are the same size
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v): return s return Rlist(v, s) def intersect_set(set1, set2): f = lambda v: set_contains(set2, v) return filter_rlist(set1, f) def union_set(set1, set2): f = lambda v: not set_contains(set2, v) set1_not_set2 = filter_rlist(set1, f) return extend_rlist(set1_not_set2, set2)
Time order of growth The size of the set Assume sets are the same size
Sets as Unordered Sequences
def adjoin_set(s, v): if set_contains(s, v): return s return Rlist(v, s) def intersect_set(set1, set2): f = lambda v: set_contains(set2, v) return filter_rlist(set1, f) def union_set(set1, set2): f = lambda v: not set_contains(set2, v) set1_not_set2 = filter_rlist(set1, f) return extend_rlist(set1_not_set2, set2)
Time order of growth The size of the set Assume sets are the same size
Sets as Ordered Sequences
Proposal 2: A set is represented by a recursive list with unique elements ordered from least to greatest
Sets as Ordered Sequences
Proposal 2: A set is represented by a recursive list with unique elements ordered from least to greatest Order of growth?
Sets as Ordered Sequences
Proposal 2: A set is represented by a recursive list with unique elements ordered from least to greatest Order of growth?
Sets as Ordered Sequences
Proposal 2: A set is represented by a recursive list with unique elements ordered from least to greatest Order of growth?
def set_contains2(s, v):
Sets as Ordered Sequences
Proposal 2: A set is represented by a recursive list with unique elements ordered from least to greatest Order of growth?
def set_contains2(s, v): if empty(s) or s.first > v:
Sets as Ordered Sequences
Proposal 2: A set is represented by a recursive list with unique elements ordered from least to greatest Order of growth?
def set_contains2(s, v): if empty(s) or s.first > v: return False
Sets as Ordered Sequences
Proposal 2: A set is represented by a recursive list with unique elements ordered from least to greatest Order of growth?
def set_contains2(s, v): if empty(s) or s.first > v: return False elif s.first == v:
Sets as Ordered Sequences
Proposal 2: A set is represented by a recursive list with unique elements ordered from least to greatest Order of growth?
def set_contains2(s, v): if empty(s) or s.first > v: return False elif s.first == v: return True
Sets as Ordered Sequences
Proposal 2: A set is represented by a recursive list with unique elements ordered from least to greatest Order of growth?
def set_contains2(s, v): if empty(s) or s.first > v: return False elif s.first == v: return True return set_contains(s.rest, v)
Set Intersection Using Ordered Sequences
Set Intersection Using Ordered Sequences
This algorithm assumes that elements are in order.
Set Intersection Using Ordered Sequences
This algorithm assumes that elements are in order. Order of growth?
Set Intersection Using Ordered Sequences
This algorithm assumes that elements are in order. Order of growth?
Set Intersection Using Ordered Sequences
This algorithm assumes that elements are in order. Order of growth?
def intersect_set2(set1, set2):
Set Intersection Using Ordered Sequences
This algorithm assumes that elements are in order. Order of growth?
def intersect_set2(set1, set2): if empty(set1) or empty(set2):
Set Intersection Using Ordered Sequences
This algorithm assumes that elements are in order. Order of growth?
def intersect_set2(set1, set2): if empty(set1) or empty(set2): return Rlist.empty
Set Intersection Using Ordered Sequences
This algorithm assumes that elements are in order. Order of growth?
def intersect_set2(set1, set2): if empty(set1) or empty(set2): return Rlist.empty e1, e2 = set1.first, set2.first
Set Intersection Using Ordered Sequences
This algorithm assumes that elements are in order. Order of growth?
def intersect_set2(set1, set2): if empty(set1) or empty(set2): return Rlist.empty e1, e2 = set1.first, set2.first if e1 == e2:
Set Intersection Using Ordered Sequences
This algorithm assumes that elements are in order. Order of growth?
def intersect_set2(set1, set2): if empty(set1) or empty(set2): return Rlist.empty e1, e2 = set1.first, set2.first if e1 == e2: rest = intersect_set2(set1.rest, set2.rest)
Set Intersection Using Ordered Sequences
This algorithm assumes that elements are in order. Order of growth?
def intersect_set2(set1, set2): if empty(set1) or empty(set2): return Rlist.empty e1, e2 = set1.first, set2.first if e1 == e2: rest = intersect_set2(set1.rest, set2.rest) return Rlist(e1, rest)
Set Intersection Using Ordered Sequences
This algorithm assumes that elements are in order. Order of growth?
def intersect_set2(set1, set2): if empty(set1) or empty(set2): return Rlist.empty e1, e2 = set1.first, set2.first if e1 == e2: rest = intersect_set2(set1.rest, set2.rest) return Rlist(e1, rest) elif e1 < e2:
Set Intersection Using Ordered Sequences
This algorithm assumes that elements are in order. Order of growth?
def intersect_set2(set1, set2): if empty(set1) or empty(set2): return Rlist.empty e1, e2 = set1.first, set2.first if e1 == e2: rest = intersect_set2(set1.rest, set2.rest) return Rlist(e1, rest) elif e1 < e2: return intersect_set2(set1.rest, set2)
Set Intersection Using Ordered Sequences
This algorithm assumes that elements are in order. Order of growth?
def intersect_set2(set1, set2): if empty(set1) or empty(set2): return Rlist.empty e1, e2 = set1.first, set2.first if e1 == e2: rest = intersect_set2(set1.rest, set2.rest) return Rlist(e1, rest) elif e1 < e2: return intersect_set2(set1.rest, set2) elif e2 < e1:
Set Intersection Using Ordered Sequences
This algorithm assumes that elements are in order. Order of growth?
def intersect_set2(set1, set2): if empty(set1) or empty(set2): return Rlist.empty e1, e2 = set1.first, set2.first if e1 == e2: rest = intersect_set2(set1.rest, set2.rest) return Rlist(e1, rest) elif e1 < e2: return intersect_set2(set1.rest, set2) elif e2 < e1: return intersect_set2(set1, set2.rest)
Tree Sets
Tree Sets
Proposal 3: A set is represented as a Tree. Each entry is:
Tree Sets
Proposal 3: A set is represented as a Tree. Each entry is:
- Larger than all entries in its left branch and
Tree Sets
Proposal 3: A set is represented as a Tree. Each entry is:
- Larger than all entries in its left branch and
- Smaller than all entries in its right branch
Tree Sets
Proposal 3: A set is represented as a Tree. Each entry is:
- Larger than all entries in its left branch and
- Smaller than all entries in its right branch
7 3 1 5 9 11
Tree Sets
Proposal 3: A set is represented as a Tree. Each entry is:
- Larger than all entries in its left branch and
- Smaller than all entries in its right branch
7 3 1 5 9 11 7 3 1 5 9 11
Tree Sets
Proposal 3: A set is represented as a Tree. Each entry is:
- Larger than all entries in its left branch and
- Smaller than all entries in its right branch
7 3 1 5 9 11 7 3 1 5 9 11 5 3 1 7 9 11
Membership in Tree Sets
Membership in Tree Sets
Set membership tests traverse the tree
Membership in Tree Sets
Set membership tests traverse the tree
- The element is either in the left or right sub‐branch
Membership in Tree Sets
Set membership tests traverse the tree
- The element is either in the left or right sub‐branch
- By focusing on one branch, we reduce the set by about half
Membership in Tree Sets
Set membership tests traverse the tree
- The element is either in the left or right sub‐branch
- By focusing on one branch, we reduce the set by about half
def set_contains3(s, v):
Membership in Tree Sets
Set membership tests traverse the tree
- The element is either in the left or right sub‐branch
- By focusing on one branch, we reduce the set by about half
def set_contains3(s, v): if s is None:
Membership in Tree Sets
Set membership tests traverse the tree
- The element is either in the left or right sub‐branch
- By focusing on one branch, we reduce the set by about half
def set_contains3(s, v): if s is None: return False
Membership in Tree Sets
Set membership tests traverse the tree
- The element is either in the left or right sub‐branch
- By focusing on one branch, we reduce the set by about half
def set_contains3(s, v): if s is None: return False elif s.entry == v:
Membership in Tree Sets
Set membership tests traverse the tree
- The element is either in the left or right sub‐branch
- By focusing on one branch, we reduce the set by about half
def set_contains3(s, v): if s is None: return False elif s.entry == v: return True
Membership in Tree Sets
Set membership tests traverse the tree
- The element is either in the left or right sub‐branch
- By focusing on one branch, we reduce the set by about half
def set_contains3(s, v): if s is None: return False elif s.entry == v: return True elif s.entry < v:
Membership in Tree Sets
Set membership tests traverse the tree
- The element is either in the left or right sub‐branch
- By focusing on one branch, we reduce the set by about half
def set_contains3(s, v): if s is None: return False elif s.entry == v: return True elif s.entry < v: return set_contains3(s.right, v)
Membership in Tree Sets
Set membership tests traverse the tree
- The element is either in the left or right sub‐branch
- By focusing on one branch, we reduce the set by about half
def set_contains3(s, v): if s is None: return False elif s.entry == v: return True elif s.entry < v: return set_contains3(s.right, v) elif s.entry > v:
Membership in Tree Sets
Set membership tests traverse the tree
- The element is either in the left or right sub‐branch
- By focusing on one branch, we reduce the set by about half
def set_contains3(s, v): if s is None: return False elif s.entry == v: return True elif s.entry < v: return set_contains3(s.right, v) elif s.entry > v: return set_contains3(s.left, v)
Membership in Tree Sets
Set membership tests traverse the tree
- The element is either in the left or right sub‐branch
- By focusing on one branch, we reduce the set by about half
5 3 1 7 9 11
def set_contains3(s, v): if s is None: return False elif s.entry == v: return True elif s.entry < v: return set_contains3(s.right, v) elif s.entry > v: return set_contains3(s.left, v)
Membership in Tree Sets
Set membership tests traverse the tree
- The element is either in the left or right sub‐branch
- By focusing on one branch, we reduce the set by about half
5 3 1 7 9 11
def set_contains3(s, v): if s is None: return False elif s.entry == v: return True elif s.entry < v: return set_contains3(s.right, v) elif s.entry > v: return set_contains3(s.left, v)
9
Membership in Tree Sets
Set membership tests traverse the tree
- The element is either in the left or right sub‐branch
- By focusing on one branch, we reduce the set by about half
5 3 1 7 9 11
def set_contains3(s, v): if s is None: return False elif s.entry == v: return True elif s.entry < v: return set_contains3(s.right, v) elif s.entry > v: return set_contains3(s.left, v)
9
If 9 is in the set, it is in this branch
Membership in Tree Sets
Set membership tests traverse the tree
- The element is either in the left or right sub‐branch
- By focusing on one branch, we reduce the set by about half
5 3 1 7 9 11
def set_contains3(s, v): if s is None: return False elif s.entry == v: return True elif s.entry < v: return set_contains3(s.right, v) elif s.entry > v: return set_contains3(s.left, v)
9
If 9 is in the set, it is in this branch Order of growth?
Adjoining to a Tree Set
Adjoining to a Tree Set
5 3 1 7 9 11 8
Adjoining to a Tree Set
5 3 1 7 9 11 8
Right!
Adjoining to a Tree Set
5 3 1 7 9 11 8
Right!
Adjoining to a Tree Set
5 3 1 7 9 11 8 7 9 11 8
Right!
Adjoining to a Tree Set
5 3 1 7 9 11 8 7 9 11 8
Right! Left!
Adjoining to a Tree Set
5 3 1 7 9 11 8 7 9 11 8 7 8
Right! Left!
Adjoining to a Tree Set
5 3 1 7 9 11 8 7 9 11 8 7 8
Right! Left!
None None
Adjoining to a Tree Set
5 3 1 7 9 11 8 7 9 11 8 7 8
Right! Left! Right!
None None
Adjoining to a Tree Set
5 3 1 7 9 11 8 7 9 11 8 7 8
Right! Left! Right!
None None 8 None
Adjoining to a Tree Set
5 3 1 7 9 11 8 7 9 11 8 7 8
Right! Left! Right!
None None 8 None
Stop!
Adjoining to a Tree Set
5 3 1 7 9 11 8 7 9 11 8 7 8
Right! Left! Right!
None None 8 None
Stop!
Adjoining to a Tree Set
5 3 1 7 9 11 8 7 9 11 8 7 8
Right! Left! Right!
None None 8 None
Stop!
8
Adjoining to a Tree Set
5 3 1 7 9 11 8 7 9 11 8 7 8
Right! Left! Right!
None None 8 None
Stop!
8 7 8
Adjoining to a Tree Set
5 3 1 7 9 11 8 7 9 11 8 7 8
Right! Left! Right!
None None 8 None
Stop!
8 7 8 7 9 11 8
Adjoining to a Tree Set
5 3 1 7 9 11 8 7 9 11 8 7 8
Right! Left! Right!
None None 8 None
Stop!
8 7 8 7 9 11 8 5 3 1 7 9 11 8
What Did I Leave Out?
What Did I Leave Out?
Sets as ordered sequences:
What Did I Leave Out?
Sets as ordered sequences:
- Adjoining an element to a set
What Did I Leave Out?
Sets as ordered sequences:
- Adjoining an element to a set
- Union of two sets
What Did I Leave Out?
Sets as ordered sequences:
- Adjoining an element to a set
- Union of two sets
Sets as binary trees:
What Did I Leave Out?
Sets as ordered sequences:
- Adjoining an element to a set
- Union of two sets
Sets as binary trees:
- Intersection of two sets
What Did I Leave Out?
Sets as ordered sequences:
- Adjoining an element to a set
- Union of two sets
Sets as binary trees:
- Intersection of two sets
- Union of two sets
What Did I Leave Out?
Sets as ordered sequences:
- Adjoining an element to a set
- Union of two sets
Sets as binary trees:
- Intersection of two sets
- Union of two sets
That's homework 9!
Why things go wrong What can we do about this
Social Implications / Programming Practices
Therac‐25 Case Study
Therac‐25 Case Study
Medical imaging
device
Therac‐25 Case Study
Therac‐25 Case Study
What happened?
Therac‐25 Case Study
What happened? 6 serious injuries
Therac‐25 Case Study
What happened? 6 serious injuries 4 deaths
Therac‐25 Case Study
What happened? 6 serious injuries 4 deaths Otherwise effective – saved hundreds of lives
Therac‐25 Case Study
Lesson to be learned
Social responsibility in engineering
Lesson to be learned
Social responsibility in engineering First real incident of fatal software failure
Lesson to be learned
Social responsibility in engineering First real incident of fatal software failure Bigger issue
No bad guys Honestly believed there was nothing wrong
Lesson to be learned
Other engineering fields: clear sense of
degradation and decay
Can software become brittle or fractured?
“Software Rot”
A bigger picture
All software is part of a bigger system
A bigger picture
All software is part of a bigger system
Software degrades because:
Other piece of software changes Hardware changes Environment changes
A bigger picture
Ex: Compatibility Issues
The makers of the Therac did not fully
understand the complexity of their software
Complexity of constructs in other fields more
apparent
A bigger issue
A “simple” program
A “simple” program
This program can delete any file you can
A “simple” program
Complexity in the Therac‐25
Abundant user interface issues
Complexity in the Therac‐25
Abundant user interface issues Cursor position and field entry
Complexity in the Therac‐25
Abundant user interface issues Cursor position and field entry Default values
Complexity in the Therac‐25
Abundant user interface issues Cursor position and field entry Default values Too many error messages
Complexity in the Therac‐25
Too many error messages
Too many error messages
No atomic test‐and‐set No hardware interlocks
(More) Complexity in the Therac‐25
Know your user Fail‐Soft (or Fail‐Safe) Audit Trail Correctness from the start Redundancy
How can we solve these things?
Fail‐Soft (or Fail‐Safe)
def mutable_rlist(): def dispatch(message, value=None): nonlocal contents if message == 'first': return first(contents) if message == 'rest': return rest(contents) if message == 'len': return len_rlist(contents) ... return dispatch
Fail‐Soft (or Fail‐Safe)
def mutable_rlist(): def dispatch(message, value=None): nonlocal contents if message == 'first': return first(contents) if message == 'rest': return rest(contents) if message == 'len': return len_rlist(contents) ... else: print('Unknown message') return dispatch
Edsger Dijkstra: “On the Cruelty of Really
Teaching Computing Sciences”
CS students shouldn’t use computers Rigorously prove correctness of their programs Correctness proofs Compilation (pre‐execution) analysis
Correctness from the start
Black box debugging Glass box debugging Don’t break what works Golden rule of debugging…
On debugging
“Debug by subtraction, not by
addition”
Prof. Brian Harvey