Overview
I would certainly appreciate suggestions of other extra credit activities (preferably via email).
If you miss a quiz, what grade do you get?
Zero
Is the lowest quiz grade dropped?
Yes
So if you miss one quiz, it gets dropped?
In effect, yes.
Do you exempt people with facial recognition issues from Friday’s quiz?
Yes. Provided it is documented with academic advising.
I have random problems running loudhum on my computer.
Let’s talk offline.
Can we ask you broad questions on the exam?
Yes.
In the tweet problem, what should we do about things that have values that are numbers or true or false?
You need not support them.
What should our samples look like for the last problem?
(post->xml (post "Sample one" "Foo" "Bar" (list) 100))(post->xml (post "Sample two" "Qux" "Quux" (list "A" "B" "C") 23))(post->xml (post "Sample three" "Qux" "Quux" (make-list 100 "Charred") 123123123124512321))(xml->post '(post (title "T") (author "A") (content "C") (tags (tag "T")) (views "-5")))
Can you give an example in which you might want multiple consequents?
(define silly
(lambda (val)
(cond
[(list? val)
(for-each (lambda (x) (hash-set! hash x (string-upcase x))) val)
val]
...)))
That is,
for-eachreturns void. Perhaps I want something other than void back, such as my original input.
At the beginning of the semester, we learned about various parts of algorithms, including the following
And we’ve learned how to write them in Scheme/Racket.
Variables
(define name value)(let ([name value]) ...)Conditionals
(if (condition) true-thing false-thing)(cond [(guard) consequent consequent] [(guard) consequent] ... [else alternate])(when (condition) consequent1 consequent2 consequent3)Note:
cond or when when you want multiple consequents.if or when when you only need one test.when when you don’t have an alternate.Repetition
(for-each proc lst) - does the same procedure again and again on different
values.(map proc lst) - does the same procedure again and again on different
values, accumulating the results into a new list.(reduce binproc lst) - Repeatedly apply binproc to neighboring pairs
until the values are reduced to a single value.(filter pred lst) - Test each element of the list, returning a list
containing only those that match.Input/Output
Built-in Functions and Types
(make-string n char) - Makes a string with n copies of char. (Can
be helpful with repetition.)(make-list n thing) - Makes a list (Can be helpful with repetition)list->string, string-append, string-ref,
string-trim, substring, string-length, string?, all of the
wonderfully helpful regexp procedures, string-split,
string->number, number->string, string-ci<?Sequencing
(o proc2 proc1) Do proc1 then proc2.let*, evaluates its values one at a time.let or lambda, if there are multiple expressions, they
get evaluated one at a time, with the value of the last one being used
as the result.cond sequences tests.Subroutines
(lambda (params) body).(section proc param <>)(o proc2 proc1).define and let.Questions
What is the role of husk and kernel?
It’s a program design strategy; it is not strictly necessary for writing algorithms.
Or maybe a use of conditionals.
Recursion is a general technique for repeating actions.
Recursion involves delegation, of sorts
How many of these words have two consecutive identical letters?
Which words have two consecutive identical letters?
Turn the following into Racket.
;;; Procedure:
;;; tally-odd?
;;; Parameters:
;;; nums, a list of integers
;;; Purpose:
;;; Count how many odd numbers are in the list.
;;; Produces:
;;; count, a count of the odd numbers
(define tally-odd?
(lambda (nums)
(if (null? nums)
0
(+ (if (odd? (car nums)) 1 0)
(tally-odd? (cdr nums))))))
(tally-odd? '(2 3 1 4 5))
=> (+ (if (odd? 2) 1 0) (tally-odd? '(3 1 4 5)))
=> (+ 0 (tally-odd? '(3 1 4 5)))
=> (+ 0 (+ (if (odd? 3) 1 0) (tally-odd? '(1 4 5))))
=> (+ 0 (+ 1 (tally-odd? '(1 4 5))))
=> (+ 0 (+ 1 (+ (if (odd? 1) 1 0) (tally-odd? '(4 5)))))
=> (+ 0 (+ 1 (+ 1 (tally-odd? '(4 5)))))
=> (+ 0 (+ 1 (+ 1 (+ (if (odd? 4) 1 0) (tally-odd? '(5))))))
=> (+ 0 (+ 1 (+ 1 (+ 0 (tally-odd? '(5))))))
=> (+ 0 (+ 1 (+ 1 (+ 0 (+ (if (odd? 5) 1 0) (tally-odd? '()))))))
=> (+ 0 (+ 1 (+ 1 (+ 0 (+ 1 (tally-odd? '()))))))
=> (+ 0 (+ 1 (+ 1 (+ 0 (+ 1 0)))))
=> (+ 0 (+ 1 (+ 1 (+ 0 1))))
=> (+ 0 (+ 1 (+ 1 1)))
=> (+ 0 (+ 1 2))
=> (+ 0 3)
=> 3
Key ideas:
Why would we use recursion instead of filter or tally?
filter and tally (and reduce).range.(string-range str1 str2) generates all strings that come between
str1 and str2. (string-range "a" "f") -> ‘(“a” “b” “c” “d” “e” “f”)`.How about filtering?
(define filter-odd
(lambda (nums)
(if (null? nums)
null
(if (odd? (car nums))
(cons (car nums)
(filter-odd (cdr nums)))
(filter-odd (cdr nums))))))
(filter-odd '(5 2 1 4 3)) ; not null, car is odd
=> (cons 5 (filter-odd '(2 1 4 3))) ; not null, car is not odd
=> (cons 5 (filter-odd '(1 4 3))) ; not null, car is odd
=> (cons 5 (cons 1 (filter-odd '(4 3)))) ; not null, car is not odd
=> (cons 5 (cons 1 (filter-odd '(3)))) ; not null, car is odd
=> (cons 5 (cons 1 (cons 3 (filter-odd '())))) ; null
=> (cons 5 (cons 1 (cons 3 '())))
=> (cons 5 (cons 1 '(3)))
=> (cons 5 '(1 3))
=> '(5 1 3))
As I noted, we build up a lot of delayed work while waiting for the recursive calls to finish. (It’s a bit like waiting for the verb in German.)
How do you get the second element in a list?
> (list-ref lst 1)
> (car (cdr lst))
> (cadr lst) ; (car (cdr lst))