Overview
How did you write merge-lines
?
There are multiple approaches. The simplest that I could come up with was drop newlines that follow a character, which gives us each “paragraph” as a single line, then convert each newline to two newlines (to get a blank space), then convert each sequence of more than two newlines to just two newlines.
(define merge-lines-stage-1
(lambda (str)
(regexp-replace* #px"([^\n])\n" str "\\1 ")))
(define merge-lines-stage-2
(lambda (str)
(regexp-replace* #px"([^\n])\n" str "\\1\n\n")))
(define merge-lines-stage-3
(lambda (str)
(regexp-replace* #px"\n\n+" str "\n\n")))
(define merge-lines
(lambda (infile outfile)
(string->file (merge-lines-stage-3
(merge-lines-stage-2
(merge-lines-stage-1
(file->string infile))))
outfile)))
There’s a bit more cleanup we could do beforehand (e.g., removing spaces at the end of a line) or afterwards (e.g., removing blank lines at the beginning or end), but this suffices.
Moral: Do things step-by-step and then combine.
Do the prospies have any questions for the students?
Nope.
All of exercise 3 from Friday’s class about the maxim “Solve for one or two, then solve for a list. That is, the process should be that you come up with an appropriate procedure and use it with one of the “list combining” procedures. Some of you missed that idea, so we’re going to reinforce it a bit here.
Suppose we’ve figured out how to combine two strings with a space
in between (combine-with-space
), who do we combine a list of
strings?
map
. But map gives us back a list.reduce
, which tends to turn lists into single values.First, combine two words with a space.
(define combine-with-space
(lambda (str1 str2)
(string-append str1 " " str2)))
; or
(define combine-with-space (section string-append <> " " <>))
Then, use reduce
to bring all the words together.
> (reduce combine-with-space (list "a" "b" "c"))
> (reduce (section string-append <> " " <>) (list "a" "b" "c"))
E.g., from '("a" "beta" "c")
to '("aa" "betabeta" "cc")
Suppose we can double one string, how do we double all of them?
map
.First, write a procedure that duplicates a string.
(define duplicate-string
(lambda (str)
(string-append str str)))
; or
(define duplicate-string
(lambda (str)
(regexp-replace* #px"(.*)" str "\\1\\1")))
; or
(define duplicate-string
(section regexp-replace* #px"(.*)" <> "\\1\\1"))
Then, use map
to to double all of the words.
> (map duplicate-string (list "a" "b" "c"))
> (map (lambda (x) (string-append x x)) (list "a" "b" "c"))
First, write a procedure that compares two strings for length
(define shorter?
(lambda (str1 str2)
(< (string-length str1) (string-length str2))))
Then, use that with sort
to sort the list.
> (sort (list "twas" "brillig" "and" "the" "slithy") shorter?)
First, write a procedure that returns true only for odd integers.
(define odd-integer?
(lambda (val)
(and (integer? val) (odd? val))))
; or
(define odd-integer? (conjoin integer? odd?))
Then, use it with all
to check all of the list.
> (all odd-integer? (list 1 3 5 3 -1))
> (all odd-integer? (list 7 5 4 3 1))
> (all odd-integer? (list 3+3i 4))
Today is the day we pretend to be “scientists”.
Today we apply the scientific method. How?
Sam and Fahmida clearly did not test their code. (It’s Sam’s fault,
as usual.) The parameters to index-of
are backwards. We’ll trust
you to fix them.
Note: max
and min
return inexact numbers if any of their parameters
are inexact. (The rounding that happens with an inexact number can
lead it to be smaller or bigger than it should be, which means that
we can’t be absolutely sure that our comparison is correct. Isn’t
that sad?)
Note: check-equal?
returns nothing if the check succeeds. That’s
so that the failures don’t get buried in a lot of “OK”. See the silly
story at the end of the reading.
Note: If you are comparing numbers, please use check-=
rather than
check-equal?
.
Writeup is exercise 7. You can describe the tests in English.
(Sam is Sad. No one listens when he tries to make end-of-class announcements.)