CSC 151.03, Class 40: Pause for breath
Overview
- Preliminaries
- Notes and news
- Upcoming work
- Extra credit
- Questions
- A few more notes on searching and sorting
- About the final
- About presentations
- Presentation preparation time
News / Etc.
- Project grades delayed.
- I plan to have all your grades to you Monday of finals week.
- We will discuss quiz 13.
Upcoming work
- No lab writeup for class 39.
- Exam 4
- Exam due Tuesday
- Cover sheets due Wednesday
- Epilogues due Wednesday.
- No more readings.
- No more quizzes.
Extra credit (Academic/Artistic)
- CS Table Tuesday: Esoteric programming languages.
- CS Extras Thursday: Summer opportunities in CS.
Extra credit (Peer)
Extra credit (Misc)
- Newtown movie Tuesday night.
- Whoops! It conflicts with exam 4.
- If you see the movie, you can have an extra day on Exam 4.
Other good things
- Percussion ensemble Tuesday at 7:30 p.m. in Sebring Lewis.
- Musical: Next to Normal Friday at 7:30, Saturday and Sunday at 2:30. Tickets at box office.
- Stay healthy and sane during week 14.
Questions
- How much of the original should I preserve on problem 1?
- As much as possible. For example, your solution to the first problem
should continue to (a) use
letrec, (b) have a tripartitecond, and (c) return the original list when given an index out of bounds. - Any hints on problem 2?
- “Trust the magic recursion fairy.” Use direct recursion. Assume that the tally procedure will succeed on the cdr. Assume that you can use it on any sublist. Work from there.
- Should
vector-filterreturn anything? - Yes. The procedure builds a new vector. It should return that vector.
- Can
vector-filtermodify the original vector? - No.
- Does
next-largerhave to work with vectors that include negative numbers? - Yes.
- Any hints on
next-larger? - Make a list (human, not computer) of the possible cases.
- Make sure you try all of the examples we’ve given you.
- Any hints on flattening trees?
- The problem suggests writing a helper that keeps track of the flattened version of everthing that will appear to the right. That’s a good strategy. Start with the empty list.
- I keep getting the same result when I call
ioe. Is that intentional? - If you use the correct parameters, you should get a variety of results.
Perhaps you should figure outvss!first and see how it callsioe. - I trust the recursion fairy, but I’m not sure what he wants to do with the base case?
- When you’re working with lists, the empty list a good starting point for the base case. And NO elements match the predicate in the empty list, so you can return 0.
- For problem 3, how do I append vectors without using vector append?
- You don’t.
- You build one vector, then fill it in.
(vector-set! newvec newpos (vector-ref vec pos)) - Once you’ve built the vector, you can mutate it to your brains’s content.
- Do you care whether we have separate helpers?
- I tend to prefer internal helpers.
- But you won’t lose points for writing external helpers, provided you document them with the 4P’s.
- Of course, I do expect a sentence for local helpers.
- Ooh! If I make
ioelocal, can I avoid documenting it? - Good idea. But no.
A few more notes on searching and sorting
Some reminders
- Search: Given a list of compound values, find a value that matches.
- Compound: May have many parts.
'("Rebelsky" "Samuel" "samr" "4410")'#("Rebel" "Sam" "use-the-force-luke" "4410")'((lname "Rebelsky") (fname "Essay") (username "muser") (phone "4410"))'(("lname" "Rebelsky") ("fname" "Essay") ("username" "muser") ("phone" "4410"))
> (define sam '((lname "Rebelsky") (fname "Essay") (username "muser") (phone "4410")))
> (assoc sam 'lname)
. . assoc: not a proper list: 'lname
> (assoc 'lname sam)
'(lname "Rebelsky")
> (assoc 'phone sam)
'(phone "4410")
Sam prefers symbols to strings because it is supposedly faster to compare two symbols than two strings. You can also use eq? for symbols but not for strings.
> (eq? 'Rebelsky (string->symbol "Rebelsky"))
#t
> (eq? "Rebel" (substring "Rebelsky" 0 5))
#f
> (equal? "Rebel" (substring "Rebelsky" 0 5))
#t
- Search: Given a list of compound values, find a value that matches.
- The thing that we’re matching is the “key”.
- “Find a person whose last name is Rebelsky”
- “Find a person whose phone number is 4410”
- “Find a person whose username is the-recursion-fairy”
- We need to write procedures (named or anonymous) that extract keys.
- Extract phone from
'("Rebelsky" "Samuel" "samr" "4410"), use cadddr. - Extract username from
'#("Rebel" "Sam" "use-the-force-luke" "4410")we use(section vector-ref <> 2). - Etc.
- Extract phone from
What about sorting?
- Similar issues
- We may need to indicate what we are sorting by. (“The key”)
- We also need to indicate how we order things. “May precede”
Quiz 13
We’ve chosen a stupid way to represent compound data: Shove it all into one string of the form “LAST FIRST EXTENSION”. * It may be expensive to break it up. * Some names include spaces. “von Trapp” * (Ignore that issue in the next thing.)
Suppose we don’t have the string-split procedure. How would you extract
just the last name? E.g., from "Rebel Skye 4410". If you finish that,
how would you find just the first name?
Approach 1
- Convert the string to a list with
string->list - Use
index-ofto find the location of the space. - Use substring to extract the substring.
> (define str "Rebel Skye 1234")
> (string->list str)
'(#\R #\e #\b #\e #\l #\space #\S #\k #\y #\e #\space #\1 #\2 #\3 #\4)
> (index-of #\space (string->list str))
5
> (substring str 0 5)
"Rebel"
> (define str "Supercalifragilistic Expi 1234")
> (index-of #\space (string->list str))
20
> (substring str 0 5)
"Super"
> (substring str 0 20)
"Supercalifragilistic"
Effectively
(substring str 0 (index-of #\space (string->list str)))
Approach 2: Don’t build a list
Iterate through the string until you find a space. Then use that number for the substring.
> (define str "Last First Extension")
> (string-ref str 0)
#\L
> (string-ref str 1)
#\a
> (string-ref str 2)
#\s
> (string-ref str 3)
#\t
> (string-ref str 4)
#\space
> (substring str 0 4)
"Last"
This is more computer efficient but less programmer efficient. We need
to write the find-space procedure.
We decided this was too much for the quiz, so we gave you a helper.
With that procedure, we thought you would write the following.
(define get-last-name
(lambda (str)
(car (string-split str " "))))
We hoped you would write something else.
(define get-last-name
(o car (r-s string-split " ")))
(define get-first-name
(lambda (str)
(cadr (string-split str " "))))
“Sort the directory in reverse alphabetical order by last name”
(vector-sort! vec get-key may-precede?)
(vector-sort! contacts get-last-name string>=?)
What one mentor wrote
(vector-sort! contacts get-last-name (lambda (a b) (not (string<? a b))))
What that mentor should have written
(vector-sort! contacts get-last-name (negate string<?))
- What’s the difference between
string<=?andstring-ci<=? - The latter is case-insensitive (treats uppercase and lowercase the same)
“Sort the directory in alphabetical order by last and first name”
Incorrect
(vector-sort! contacts
(string-append (get-last-name str) ", " (get-first-name str))
string<=?)
The middle thing isn’t a procedure. So we need a lambda
(vector-sort! contacts
(lambda (str)
(string-append (get-last-name str) ", " (get-first-name str)))
string<=?)
“Assuming the directory is sorted by last name, search for Curtsinger””
Thoughts on merging
How does merge work? (Not merge-sort, just the merge procedure.)
- It takes two sorted lists, which it is trying to merge together
- Compare the first element of each one
- Add the “smaller” one to our new list and recurse
How many times do we call merge for the call (merge '(1 2 3 4) '(5 6 7 8))?
(merge '(1 2 3 4) '(5 6 7 8))
=> (cons 1 (merge '(2 3 4) '(5 6 7 8)))
=> (cons 1 (cons 2 (merge '(3 4) '(5 6 7 8))))
=> (cons 1 (cons 2 (cons 3 (merge '(4) '(5 6 7 8)))))
=> (cons 1 (cons 2 (cons 3 (cons 4 (merge '() '(5 6 7 8))))))
=> (cons 1 (cons 2 (cons 3 (cons 4 '(5 6 7 8)))))
=> ...
=> '(1 2 3 4 5 6 7 8)
Five (5) times!
How many times do we call merge for the call (merge '(1 3 5 7) '(2 4 6 8))?
(merge '(1 3 5 7) '(2 4 6 8))
=> (cons 1 (merge '(3 5 7) '(2 4 6 8)))
=> (cons 1 (cons 2 (merge '(3 5 7) '(4 6 8))))
=> ...
=> '(1 2 3 4 5 6 7 8)
Eight (8) times!
Point: merge is significantly affected by the distribution of values within the two lists.
Even at its worst, merge-sort is significantly better than insertion sort or selection sort.
About the final
A sample final is posted online.
Optional! If you do better on the final than on one of your exams, it replaces the lowest exam. If you do worse, it gets ignored. YOU DO NOT HAVE TO SHOW UP!
In-class, like a really hard quiz.
Four problems. All mostly correct: A. Three mostly correct: B. Two mostly correct: C. One mostly correct: D. Zero mostly correct: F. Don’t show up: zero.
Closed book, one page of hand-written notes. 8.5x11 or A4 page. Double sided.
You may take the final
- Wednesday, Dec 13, 2pm-5pm in Science 3813
- Thursday, Dec 14, 9-noon in Science 3813
- Friday, Dec 15, 9-noon in Science 3813
We try to make the final so that you can finish it in an hour if you’ve been keeping up with the material.
About presentations
Each group gets three to five minutes to talk about what they did. Demo, describe, show an algorithm, …
You may use this computer. You may use the whiteboard. You may use your own laptop (with HDMI)
- Slide decks not necessary.
- Prezis should not make people sick.
Presentation preparation time
Nope.