Please follow the standard start-of-class routine.
Warning! You are being recorded (and transcribed) (provided the technology is working correctly).
Approximate overview
Scholarly
Artistic/Cultural
Multicultural
Peer
Musical, theatric, sporting, academic, and similar events involving this section’s students are welcome.
Wellness
Misc
These do not earn tokens, but are worth your consideration.
CHANGES.txt that describes what you’ve changed.The submission for the first redo deadline is free. Remaining redos are one token each.
If you didn’t turn in the assignment for the original deadline (or its late deadline), the redo is free, but you are charged two tokens for failing to turn in the original. (This policy holds starting with MP2.)
If you don’t turn in a redo for the first redo deadline (or up to two days late with a token), you will be charged a token for each remaining redo deadline, even though they may be your “first” redo.
Please make sure that your redo is accompanied by a CHANGES.txt file that
summarizes the changes you’ve made. For example,
eye procedure to part 2 because I had neglected to
include a procedure for that part. I use it in making my cat.my-image was a procedure. It is now an image, as the assignment requested.char->digitMany of you wrote
(define char->digit
(lambda (char)
(- (char->integer char) 48)))
I’d prefer that you write
(define char->digit
(lambda (char)
(- (char->integer char) (char->integer #\0))))
Can you tell why?
The second seems a bit more consistent; instead of subtract some number from
(char->integer char), we are computingchar->integerto produce the thing we are subtracting.
Easier to understand. 48 is a “magic number”; it represents something, but many readers will not know what that is. (In this case, it’s the collating value of #\0 in ASCII.)
If we were using a different collating sequence, the second is more likely to continue working correctly (provided the different collating sequence put the digits in order).
I might even prefer
(define char->digit
(o (r-s - (char->integer #\0))
char->integer))
string->integerI hope this served as a useful example of decomposition and/or bottom-up design.
A sample thought process.
Some of you asked that we go over the last question from the lab.
b. Write a procedure,
(concentric-palette colors), that takes a list of colors as an input and makes an image of concentric squares of sizes 20, 30, 40, … (* 10 (length colors)).
We should decompose the problem a bit. I’ll try to ask the kinds of questions one might ask in developing a solution to the problem. YMMV.
How do I make the squares?
(solid-square side-length color)
Making a list of different size squares sounds hard. Maybe I can make a
list of all the same size square first. Let’s write procedure, square20,
that takes a color as input and builds a square of side-length 20 and
the given color.
(define square20 (lambda (color) (solid-square 20 color)))
That’s one square. Given a list of colors, how might we make a square for each color in the list?
(map square20 colors)
Yay! We have lots of squares. But we really want them different sizes.
We may recall that we can use map with multiple lists.
(map solid-square (list 20 30 40 ...) colors)
We need to figure out how to make the list (list 20 30 40 ...).
What tool(s) (function(s)) do we have for making lists of numbers?
(make-list size-of-result value)- make a list of the given size, with the specified number of copies ofvalue.
(range n)- make a list of the numbers 0, 1, 2, … n-1.
Yay! (range (length colors)) gives us 0 1 2 3 …. But we want 20 30 40 50 …
Can we convert the first list to the second using map?
Is there a pattern? How do I convert 0 to 20, 1 to 30, 2 to 40, 3 to 50 … Multiply by 10 and add 20. (Add 2 and multiply by 10.)
(map (r-s * 10) (map (r-s + 2) (range (length colors))))
Or
(define something (lambda (num) (* 10 (+ num 2))))
(map something (range (length colors)))
(map (o (r-s * 10) (r-s + 2)) (range (length colors)))
(map #(* 10 (+ 2 %1)) (range (length colors)))
We are close!
(define palette
(lambda (colors)
(map solid-square
(map #(* 10 (+ 2 %1)) (range (length colors))) ; sizes
colors)))
This looks good. I have a list of squares. I just need to combine them.
(define palette
(lambda (colors)
(apply overlay
(map solid-square
(map #(* 10 (+ 2 %1)) (range (length colors))) ; sizes
colors))))
map“I have to add 2 to each element of a list.”
(map (l-s + 2) lst)
(define add2
(lambda (val)
(+ 2 val)))
(map add2 lst)
“I have to add 2 to each element of a list and then multiply each element by 10.”
(map (o (l-s * 10) (l-s + 2)) lst)
(define something
(lambda (num)
(* 10 (+ 2 num))))
(map something lst)
(map #(* 10 (+ 2 %1)) lst)
Can we trace (map (o (l-s * 10) (l-s + 2)) lst)
(map (o (l-s * 10) (l-s + 2)) (list 0 1 2 3))
; Apply the function to each element of the list, putting the results
; in a list
--> (list ((o (l-s * 10) (l-s + 2)) 0)
((o (l-s * 10) (l-s + 2)) 1)
((o (l-s * 10) (l-s + 2)) 2)
((o (l-s * 10) (l-s + 2)) 3))
; Note ((o f g) val) --> (f (g val))
--> (list ((l-s * 10) ((l-s + 2) 0))
((o (l-s * 10) (l-s + 2)) 1)
((o (l-s * 10) (l-s + 2)) 2)
((o (l-s * 10) (l-s + 2)) 3))
; Note ((l-s fun left) right) --> (fun left right)
--> (list ((l-s * 10) (+ 2 0))
((o (l-s * 10) (l-s + 2)) 1)
((o (l-s * 10) (l-s + 2)) 2)
((o (l-s * 10) (l-s + 2)) 3))
--> (list ((l-s * 10) 2)
((o (l-s * 10) (l-s + 2)) 1)
((o (l-s * 10) (l-s + 2)) 2)
((o (l-s * 10) (l-s + 2)) 3))
--> (list (* 10 2)
((o (l-s * 10) (l-s + 2)) 1)
((o (l-s * 10) (l-s + 2)) 2)
((o (l-s * 10) (l-s + 2)) 3))
--> (list 20
((o (l-s * 10) (l-s + 2)) 1)
((o (l-s * 10) (l-s + 2)) 2)
((o (l-s * 10) (l-s + 2)) 3))
...
Will redos be available for the LAs that I’m still missing?
Yes. Redos for each LA will be available until everyone has passed that LA or we reach the end of the semester.
There’s an estimate of the number of classes I missed. Will I be charged tokens for missing those classes?
If I’ve charged you tokens for missing classes, you’ll see them under “Attendance” in the tokens section.
If I have an excused absence, does that count as an absence?
Yes. But it doesn’t cost you any tokens.
What determines how many semicolons you use at the start of a line?
We use three semicolons to mark the documentation for individual function or values.
We use two semicolons for broader comments for the reader.
We use one semicolon either to “comment out” code that is not yet ready to run or to insert comments in the middle of a function.
Can we see traces of reduce?
Not currently, but perhaps in the future.
Can I take quizzes tomorrow because I’ll be unavailable on Friday?
Yes, during office hours. You need not book a slot. I’ll hand you a quiz.
Why is and a keyword and not a function? I didn’t follow along
well with the given example.
We have a standard approach to evaluating procedure calls (function calls): Evaluate all of the arguments and then apply the function.
anddoesn’t behave that way. It evaluates its parameters one by one, making it similar to a function, but different.
Could you please explain further the difference between apply and reduce? How do we know which one to use?
Apply works with any function and a list that contains exactly as many values as the number of arguments the function expects. It calls the function on those values.
(apply fun (list a b c d e))->(fun a b c d e).
Reduce works with a binary procedure and a list of any length. It repeatedly replaces pairs of neighboring elements by the result of applying the procedure until we’re down to one element.
(reduce fun (list a b c d e))->(fun (fun a b) (fun c (fun d e)))
(reduce-left fun (list a b c d e))->(fun (fun (fun (fun a b) c) d) e)
(reduce-right fun (list a b c d e))->(fun a (fun b (fun c (fun d e))))
Some functions, like
+andstring-appendbehave the same way when used with eitherreduceorapply. In part, that’s because they can take a variable number of parameters. In part, that’s because their semantics are the same either way.
Other functions, like
list, may take an arbitrary number of parameters, but do not behave the same way if we do things pair-by-pair.
(apply list (list 1 2 3 4 5))->(list 1 2 3 4 5).
(reduce list (list 1 2 3 4 5))->(list (list (list (list 1 2) 3) 4) 5)).
Can you go over self-check 2b from Monday?
Sure!
b. Using
applyandmap, make a picture of seven outlined circles in darker versions of the rainbow colors (using two calls torgb-darker). Note that you’ll need to convert the color names to RGB colors withcolor-name->rgband then make them darker with two calls torgb-darker.
Note: You might need three or four calls to
map(or a particularly good composition of functions).
(define rainbow-colors (list "red" "orange" "yellow" "green" "indigo" "violet"))
(define thickly-outlined-circle
(lambda (color)
(overlay (outlined-circle 20 "black" 5)
(solid-circle 20 color))))
(map thickly-outlined-circle (map rgb-darker (map rgb-darker (map color-name->rgb rainbow-colors))))
(map (o thickly-outlined-circle rgb-darker rgb-darker color-name->rgb) rainbow-colors)
Don’t forget to reload Scamper to ensure that you are using 4.7.0.
The Scheme file should be called list-more.scm. If it’s not, go back to
the schedule, reload, click on the lab link, and cross your fingers.
We will continue this lab next class.