This class will be recorded! Its use is limited to members of the class. Please do not share with others.
Approximate overview
Attend (or watch recording) and send a one-paragraph reflection.
product-of-positives, many of you ignored the case in
which numbers were zero. I still gave you credit for that.'a or the string “a” as a character.Reading from files is expensive. If you can reduce the number of times you call, say file->words, you will make your program much faster.
(define count-word-1
(lambda (word filename)
(list word (tally-value (file->words filename)))))
(define count-word-2
(lambda (word list-of-words)
(list word (tally-value list-of-words))))
(define count-words-1
(lambda (words filename)
(map (section count-word-1 <> filename) words)))
(define count-words-2
(lambda (words filename)
(let ([file-words (file->words filename)])
(map (section count-word-2 <> file-words) words))))
What’s the difference in design between the -1 procedures and
the -2 procedures?
count-word-1 does (file->words filename) for each word
in the list.count-word-2 assumes that we’ve already called file->words.How does count-words-2 ensure that that we’ve already called file->words?
(That is, how does it meet the goal of count-word-2?)
If I use the following list: (list "moo" "baa" "the" "cow" "says"),
how many times will I call file->words in the -1 case and how
many times in the -2 case?
Let’s check
(define file2words
(lambda (filename)
(display "Calling file->words") (newline)
(file->words filename)))
> (count-words-1 sample-words "DaleChallEasyWordList.txt")
Calling file->words
Calling file->words
Calling file->words
Calling file->words
Calling file->words
'(("moo" 1) ("baa" 1) ("the" 1) ("cow" 1) ("says" 0))
> (count-words-2 sample-words "DaleChallEasyWordList.txt")
Calling file->words
'(("moo" 1) ("baa" 1) ("the" 1) ("cow" 1) ("says" 0))
Let’s check the difference in performance. (Your compute speed may vary.)
(define sample-words
(list "moo" "baa" "the" "cow" "says"))
(define long-list-of-words
(apply append (make-list 50 sample-words)))
> (time (count-words-1 sample-words "DaleChallEasyWordList.txt"))
cpu time: 53 real time: 58 gc time: 34
'(("moo" 1) ("baa" 1) ("the" 1) ("cow" 1) ("says" 0))
> (time (count-words-2 sample-words "DaleChallEasyWordList.txt"))
cpu time: 4 real time: 4 gc time: 0
'(("moo" 1) ("baa" 1) ("the" 1) ("cow" 1) ("says" 0))
> (time (take (count-words-1 long-list-of-words "DaleChallEasyWordList.txt") 5))
cpu time: 1047 real time: 1174 gc time: 283
'(("moo" 1) ("baa" 1) ("the" 1) ("cow" 1) ("says" 0))
> (time (take (count-words-2 long-list-of-words "DaleChallEasyWordList.txt") 5))
cpu time: 41 real time: 41 gc time: 0
'(("moo" 1) ("baa" 1) ("the" 1) ("cow" 1) ("says" 0))
Wow! That was much faster. This is a factor of ten faster. We only expected a factor of five.
Can we speed up count-words-2 any more?
(map (lambda (word) (count-word word (file->words filename))) list-of-words)
vs.
(map (section count-word <> (file->words filename)) list-of-words)
The former should read the file for each element of list-of-words.
The latter should read the file once.
(Experiments ssuggest that I’m mistaken.)
Please do not use (= (length lst) 1) to check for a list with one
value. And definitely don’t use (= (length lst) 0) to look for
an empty list.
(list x) ;(and (not (null? lst)) (null? (cdr lst)));(null? (cdr lst)) (if you know it’s nonempty).(list).'().(null? lst).let or
something similar.
let.Can we use things we’ve learned since MP2?
Yes.
Can we get an E without using new things?
Certainly.
Could we just define the file in Part the First?
No. Our goal was a procedure that would work with any file.
Can I use a token on MPs?
Yes.
???
There’s a FAQ for that. (Or perhaps There an FAQ for that.)
Could you explain rule d?
Rule d says: “The pattern ‘(join P1 P2) matches a list of at least one element if P1 matches the car of the list and P2 matches the cdr of the list. (Sounds like recursion, doesn’t it?) The pattern (join 1 xs) matches nonempty lists that start with 1. The pattern (join x (join y z)) matches lists with at least two elements.”
If we have
'(join 1 xs), we should match1against the car of the value, andxsagainst the cdr of the value.
Note that
'(xs)is not the same as'xs.
How do you get the
xsout of'(join 1 xs)? Perhaps usinglist-ref.
(list-ref '(join 1 xs) 2)->'xs
Do I need to generalize?
joinis always accompanied by two things. You can uselist-refto get each of them, using the right index.
What are join and seq?
They are just symbols to which we’ve assigned meaning.
joinis likecons(for our patterns).
seqis likelist(for our patterns).
Is it okay if I still use list and cons?
Yes. But I’d prefer that you switch (which wouldn’t take long).
Should I make a procedure for each guard and each consequent?
It’s up to you.
(define match?
(lambda (pattern value)
(cond
...
; Empty list: '(seq)
; "If the pattern is '(seq) then check whether the value is an empty list
[(and (list? pattern)
(not (null? pattern))
(null? (cdr pattern))
(equal? (car pattern) 'seq)
(null? (cdr pattern)))
(null? value)]
; Alternate
[(empty-list-pattern? pattern)
(empty-list-value? value)]
...)))
...
;;; (empty-list-pattern? pattern) -> boolean
;;; pattern : a pattern (see MP4 assignment)
;;; Determine if pattern represents the empty list.
(define empty-list-pattern?
(lambda (pattern)
(and (list? pattern)
(not (null? pattern))
(null? (cdr pattern))
(equal? (car pattern) 'seq))))
;;; (empty-list-value? value) -> boolean
;;; value : a Racket value
;;; Determine if value represents the empty list.
(define empty-list-value?
(lambda (value)
(null? value)))
Can we take this code as long as we credit you?
Sure.
Will you explain why I did not get a point on a LA if I ask on Teams?
I will try. Make sure you’ve checked the comments.
What happens if I did an LA late and had not asked for an extension?
You get a zero on it. But you’ll still have a chance to make it up on the next SoLA.
Is it “a LA” or “an LA”?
I say the latter.
Will there really be twenty-one LAs on SoLA three?
There could be as many as twenty-one. But I hope not. I sincerely hope that all of you covered some of the Group 1 LAs with two tries.
You only have to redo the ones you missed!
Is there any way to make up an LA other than doing it again on the next SoLA?
No.
Can I get practice on SoLAs?
Write your own? Ask a classmate to write a variant? Look back at labs and readings.
The reverse fib seemed like magic. The tail recursion helped.
I agree that it’s really weird.
We’ll discuss it tomorrow.
Cancelled
Here’s what you would have done.
Write a recursive procedure, (termial n), that takes a list of non-negative integer, n, as a parameter and returns 1 + 2 + 3 + … + n.
> (termial 0)
0
> (termial 1)
1
> (termial 4)
10 ; 4 + 3 + 2 + 1
Note: There is a famous formula for this sum. You may not use it. Your goal is to write a recursive procedure.