Warning! You are being recorded (and transcribed). (Provided Otter.ai is working today. It says I have a slow network connection.)
Approximate overview
Academic/Scholarly
Cultural
Peer
Wellness
Misc
Quiz 7 was taken directly from the list recursion lab. Remember to review the labs as you study.
For quiz 8, many of you got partway there, but not all the way. Your goal is no repeated code (or as little as possible). I was a bit generous in grading because I know quizzes can be stressful (and it was just before break).
I’ll go over quiz 8, but not on the eboard. Take notes.
Note: We use local bindings for (at least) two reasons:
Have you finished tallying tokens?
No.
;;; (v2c-ratio str) -> rational?
;;; str : string
;;; Determine the ratio of vowels to consonants in str
(define v2c-ratio
(lambda (str)
(/ (tally vowel? (string->list str))
(tally consonant? (string->list str)))))
How would a helper procedure avoid redundant work?
(define v2c-ratio
(lambda (str)
(v2c-ratio/helper (string->list str))))
(define v2c-ratio/helper
(lambda (chars)
(/ (tally vowel? chars)
(tally consonant? chars))))
How does Racket choose a “random” number?
https://docs.racket-lang.org/reference/generic-numbers.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._random%29%29
“The random number generator uses L’Ecuyer’s MRG32k3a algorithm [L’Ecuyer02] that has a state space of practically 192 bits.”
Pierre L’Ecuyer, Richard Simard, E. Jack Chen, and W. David Kelton, “An Object-Oriented Random-Number Package With Many Long Streams and Substreams,” Operations Research, 50(6), 2002.
https://www.iro.umontreal.ca/~lecuyer/myftp/papers/streams00.pdf
I’ll let you read the rest.
Why did random with no parameter give us a decimal number?
The designers chose to make it behave that way. You will always get a number between 0 (inclusive) and 1 (exclusive) when you call
randomwith no parameters.
Are there other procedures that take no parameters (at least some of the time)?
We’ve seen that
(+)returns 0 and(*)returns 1. We’ll also start writing some of our own (primarily ones that end up using some form ofrandom).
I observed that on the MP5 post-reflections, many people said that they wished they had asked questions earlier. Can we try to generate a few questions to help people who haven’t started yet or who are just starting?
What basic shapes are there other than triangles, squares, and rectangles?
Hexagons? Circles? Ellipses? Pentagons? Stars? Something else you design?
How do we reach a base case in the first one? (The basic Sierpinski triangle.)
We should subtract one from
nuntil we reach zero.
(define st
(lambda (side color n)
(if (zero? n)
(equilateral-triangle side color)
...)))
We saw in the notes on the MP that we want to try to avoid repeated code, which shows a recursive call.
How do I avoid identical recursive calls?
Let’s start with the following.
(above (fractal-triangle (/ side 2) color (- n 1))
(beside (fractal-triangle (/ side 2) color (- n 1))
(fractal-triangle (/ side 2) color (- n 1))))
I can rewrite that as
(let ([smaller-triangle (fractal-triangle (/ side 2) color (- n 1)))
(above smaller-triangle
(beside smaller-triangle
smaller-triangle)))
Note that you have to do that within the
if.
When we generalize procedures, can we define the previous procedures in terms of the generalized procedure?
Sure.
Most of you would benefit from writing the individual ones first to better understand the recursion.
Why do you recurse forever if you put the let in the wrong place?
(define fractal-triangle
(lambda (side color n)
(let ([smaller-triangle (fractal-triangle (/ side 2) color (- n 1))])
(if (<= n 0)
(solid-equilateral-triangle side color)
(above smaller-triangle
(beside smaller-triangle
smaller-triangle))))))
Suppose we call
(fractal-triangle 128 "blue" 1)
The
letis evaluated first
(fractal-triangle 128 "blue" 1)
--> (let ([smaller-triangle (fractal-triangle 64 "blue 0)]) ...)
--> (let ([smaller-triangle (let ([smaller-triangle (fractal-triangle 32 "blue" -1)]) ...)]) ...)
--> (let ([smaller-triangle (let ([smaller-triangle (let ([smaller-triangle (fractal-triangle 16 "blue" -2)]) ...)]) ...) ...)
Can we talk more about (ormap <procedure> <list>)?
Sure. As you may recall,
(or exp1 exp2 ... expn)evaluates each expression in turn, stopping when it hits a truish value, which it then returns. If it runs out of values, it returns false.
Similarly,
(ormap pred? (list v1 v2 ... vn))appliespred?to each ofv1,v2, … in turn, stopping when it returns a truish value. If it reaches the end of the list, it returns false.
For example, if we want to check if some element of a list is a number, we could use
(ormap number? lst).
> (ormap number? (list "a" "b" "c" 23 "d"))
#t
> (ormap number? (list "a" "b" "c" "d"))
#f
> (ormap exact? (list "a" "b" 23 "c" "d"))
. . exact?: contract violation
expected: number?
given: "a"
There’s also an
andmap.
Why can’t you apply exact? to a string? After all, you can apply number?.
The designers chose to make it behave that way.
number?is intended to say “given any kind of type of input, decide if it’s a number.”
exact?is intended to say “given any kind of number, decide if its an exact number.”
Similarly,
odd?only works for integers.
You can achieve what you want by writing your own function.
> (define exact-number?
(lambda (x)
(and (number? x) (exact? x))))
> (exact-number? "a")
#f
> (exact-number? 23)
#t
I think
all-ofmay also work.
> (define en? (all-of number? exact?))
> (en? "a")
#f
> (en? 23)
#t
The LA on randomness assumes that you’ve done exercises 1–5 and understood the implications and how to address them.
Problem 5’s theme songs are “Proud Mary” by Ike and Tina Turner and “Rawhide” as performed by the Blues Brothers.
Yes, it’s weird that we have to do (lambda () ...) for things like
pair-a-dice. But it means that we have a procedure (that may run
differently each time) rather than a named value (that always has the
same value).
Isn’t pair-a-dice a great name for a procedure?
Grab a sticker (optional), grab a booklet (optional), have a nice day! (also optional, but preferable)