Download presentation
Presentation is loading. Please wait.
1
1 Teaching the development of algorithms Teach skill, not only facts David Gries Computer Science Department Cornell University November 2004 DrJava is a free IDE for Java; it has an “interactions pane” into which one can type any expression or statement and have it evaluated or executed immediately. It can revolutionize your teaching, because students can see you develop programs. For DrJava, type in DrJava download into google; you should get a download site. DrJava is itself a Java program. The book Multimedia Introduction to Programming Using Java by Gries & Gries is published by Springer Verlag. It comes with a CD that contains over 250 recorded lectures with synched animation. Great for teaching the development of programs. An objects-and-classes first approach.
2
2 Nato Software Engineering Conference 1968 Academicians and industrial people alike admitted that: We don’t know what we are doing. That conference sparked interest in programming, programming methodology, formal correctness ideas, software engineering
3
3 Tony Hoare Axiomatic basis for computer programs Niklaus Wirth stepwise refinement Edsger W. Dijkstra Structured Programming Late 1960’s — 1980 A Discipline of Programming David Gries 1973 text uses invariants The Science of Programming
4
4 Today We have failed to move what we knew in 1980 about programming methodology into the first and second programming courses where they belong
5
5 Pay lip service to stepwise refinement, but don’t really use it. Don’t show developments of programs. Many texts don’t mention loop invariant. Few texts use assertions and loop invariants in a meaningful way. Fail to make clear what the specification of a method is and to adhere to its use throughout. The situation with today’s texts
6
6 Consequences Many CS students graduate without every hearing the term assertion or invariant. Those that have heard about them view them only as academic exercises. Students don’t have good programming skills. Our teaching of basic algorithms (searching, sorting, dealing with links lists, etc.) is inefficient. We describe loops by showing how they execute. Students don’t value practical mathematical underpinnings of the field.
7
7 Algorithms are not memorable With current practices, the only way for a student to know an algorithm is to memorize its code. Neither effective nor efficient! Suppose we memorize code for selection sort of an array b We will still have difficulty writing an algorithm for Selection sort of an array segment b[h..k] Selection sort of an array segment b[h..k-1] Don’t memorize code. Instead, learn to Develop an algorithm from its specification
8
8 Specification of a method A contract between the programmer of a method and the user of the method. From the spec, a user should know how to write calls on the method. Precondition: constraints on the parameters. What the method does —stated as a postcondition, a command, or a formula (for a function). Formalism is not required. Precision and thoroughness is.
9
9 Stepwise refinement /** = the English equivalent of n, for 0 < n < 1,000,000, e.g. anglicize(5004) = “five thousand four” */ public static String anglicize(int n) Develop the method in class. If at all possible, use a computer and an IDE and show students incremental program development and testing. I can demo this at the end if you want. We should be teaching the thought processes behind good program design and development.
10
10 Software engineering reason for annotating a loop /** Sort array b */ int k= 0; while (k != b.length) { int j= index of minimum of b[k..b.length–1]; Swap b[j] and b[k]; k= k + 1; } Why is k set to 0 initially? You can’t tell until you have read all the code!!!! Why stop when k = b.length? You can’t tell until you have read all the code!!!! Why does the loop body do its first two steps? You can’t tell until you have read all the code!!!! Without proper annotation, one must understand the WHOLE LOOP before any part of it can be understood.
11
11 /** Sort array b */ int k= 0; while (k != b.length) { int j= index of minimum of b[k..b.length–1]; Swap b[j] and b[k]; k= k + 1; } loop with invariant // invariant P: b sorted, = 0 k b.length 1. Set k to 0 makes P true: b[0..–1] is empty, b[0..] is whole array 2. When loop stops, b[0..k–1] whole array and is sorted. 3. In each iteration, k= k+1 makes progress toward termination. 4. Each iteration maintains the invariant. With the invariant, we can understand the parts separately invariant is true before and after each iteration
12
12 /** Sort array b */ Find the invariant ? 0 b.length pre: b sorted 0 b.length post: b inv P: b sorted ? 0 b.length insertion sort invariantinv P: b sorted, = 0 b.length Selection sort invariant
13
13 /** Sort array b */ developing the loop from the invariant // invariant P: b sorted, = 0 k b.length 1. How does it start? 2. When does it stop? 3. How does it make progress toward termination 4. How does it maintain the invariant? k= 0; while ( k != b.length) { } k= k + 1; j= index of minimum of b[k..b.length – 1]; Swap b[k] and b[j]; Four loopy questions used to develop or understand any loop
14
14 Binary search 1. Dijkstra used to ask people to write one. Invariably, they couldn’t. 2. Backhouse recently found two texts with serious errors in their binary search. 3. Egghart Herwig in recent email: Asked 17 computer scientists to write a correct binary search. Most couldn’t. 4. Mark Weiss says in his text on data structures: “Binary search is surprisingly tricky to code”. Because he has no methodology for developing algorithms or understanding them.
15
15 Given sorted b[h..k], store in t to truthify R: b[h..t] ≤ x < b[t+1..k] How does it start? Make left segment empty and right segment empty: t= h–1; u= k+1; ? Q: b h k ≤ x > x R: b h t k ≤ x ? > x P: b h t ku When can it stop? When t + 1 = u. How does it make progress? Decrease size of middle segment. How does it keep invariant true?
16
16 t= h–1; u= k+1; while (t + 1 != u) { } ? Q: b h k ≤ x > x R: b h t k ≤ x ? > x P: b h t u ke int e= (t+u) / 2; // { h–1 ≤ t < e < u ≤ k+1 } if (b[e] <= x) t= e; else u= e; Memorable –develop it whenever you want. If x in, finds rightmost occurrence If x not in, finds where it belongs. Works when b[h..k] is empty (h+1 = k) Just as fast as other binary searches. WHY USE OTHERS?
17
17 Dutch National Flag ? Q: b h k contains red, white, blue balls. Permute elements to produce R: reds whites blues R: b h k reds whites blues ? P: b h k reds whites ? blues P: b h k
18
18 Dutch National Flag ? Q: b h k reds whites blues R: b h k reds whites ? blues P: b h d a c k d= h; a= h; c= k; while ( ) } a <= c if (b[a] is red) { Swap b[d], b[a]; d= d + 1; a= a + 1; } else if (b[a] is white ) a= a + 1; else { Swap b[a], b[c]; a= a + 1; }
19
19 On naming variables reds whites ? blues P: b h d a c k 1. The short names are perfectly reasonable, because their meaning is clear from the invariant – picture. 2. Short names make the program shorter and more readable. 3. Long names that try to incorporate meaning can be wrong and misleading. instead of d use firstWhite? wrong if no whites instead of d use firstNonRed?wrong at end if all reds
20
20 Summary We can teach students about program development. The problem is that we have to change our way of thinking first. Become more assertion oriented. Become more development oriented. ASSERT YOURSELVES! Mark Twain: Nothing needs changing so much as the habits of others. Textbooks need to be totally rewritten. Rest of time: Answer questions? Show you a multimedia text that has the “right” perspective”? Show you development of anglicize? Show you Dijkstra’s shortest path algorithm on one slide?
21
21 Dijkstra’s shortest path algorithm Nodes 0..n-1. Each edge has a positive weight. Start node v. For each node n, store in L[n] the length of shortest path from v to n v w 2 4 1 3 4 3 L[v] = 0 L[u] = 7 L[w] = 10 u
22
22 1. For red node r, L[r] is length of shortest v --> r path. 2. All edges leaving R go to F. Frontier F Red R 3. For node f, L[f] is length of shortest v --> f path using red nodes (except for f) 4. For black node b, L[b] = ∞ For all w, L[w]= ∞; L[v]= 0; F= { v }; R= { }; while ( ) { } For a node f in F with min L value, L[f] is shortest path length f F != {} f= node in F with min L value; Remove f from F, add it to R; for each edge (f,w) { } if (L[w] is ∞) add w to F; if (L[f] + weight (f,w) < L[w]) L[w]= L[f] + weight(f,w); Set R is not needed
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.