EBoard 15: Pause for breath

This class was not recorded!

Approximate overview

  • General administrative stuff [~10 min]
  • Q&A [~80 min]

Administrative stuff

Notes and news

  • As the overview suggests, today is a talk day.
    • It ened up being more of a talk day than normal.
    • That’s okay; I think many people understand things better.
  • Sharing a Twitter DM
  • Conversations about SoLA 1 have been really useful (at least to me).
  • No token, no shame, no charge, no issue for redoing LAs.
    • The goal is that you master the material, not when you master the material.
  • I’ve heard from many of you that the time limits on the LAs make you nervous. The time limits are mostly there to prevent you from hitting your head against the wall for too long. (Remember: You can redo LAs.) I suppose there’s something about academic honesty there, but I’m less worried about that.
    • Option one: I can extend time for individuals (say to an hour).
    • Option three: I can leave things as they are.
    • Let me know which works best for you as an individual.
  • Is it hard to answer one of my questions when I call on you randomly?
    • Now: Sam’s rationale.
      • Build skills
      • Look, others are having problems, too
      • Experience suggests that learning is better.
    • Now: Ways to react.
      • Come up with an idea. It may be wrong. It may right.
      • Say “I don’t know.”
      • Say “Give me a minute.”
    • Later: Set up an appointment. We’ll work something out.
  • Sam is sorry about the beeping. It may be fixed.
  • On a separate note: It’s important that you try to finish labs problems, even if I don’t have you turn them in. For example, I’ve seen that folks who did not do the The Wizard of Oz exercises seem to be having more difficulty on MP3.

Tutoring reminders

  • Please use our tutors! They like to work.
  • Evening tutoring will be available
    • 8-10 p.m. Sundays through Thursdays
    • 3-5 p.m. Sundays
    • In the “Drop in tutoring” channel on the CS team.
    • Sam will generally not be available during these times.
  • Individual tutors are also available.

Upcoming activities

Attend (or watch recording) and send a one-paragraph reflection.

  • Noon, Thursday, Convocation (+1 token)
    • “Do you have One Hour to Give to Save a Life? QPR is the CPR of Mental Health”
    • One of the more important Convos I’m recommending (even though it isn’t quite a convo)
    • Link posted
  • Thursday open-mic night. [+1 token for attending or performing]
  • Noon, Friday, The Future of the Humanities.
  • 3:30, Saturday, Nov. 21st: Maker Space (+1 token)
  • 7:30-9:30 p.m. Saturday, 21 Nov 2020: Art SEPC Collage, Meet, and Greet

(+1 token)

Upcoming work

  • Mini-project 3 (due TONIGHT at 10:30 p.m. CST)
    • Evening tutors will likely stop helping at 10:00 p.m.
    • Sam needs to get the turn-in posted.
  • Mini-project 2 redo (due Sunday the 22nd at 10:30 p.m. CST)
    • Sam needs to get those back to you.
  • Reading for Thursday
  • Quiz today: Testing. You’ll write tests for a procedure given its documentation.
  • Quiz tomorrow: Recursion. (Almost certainly something simple.)

Q&A

MP3

Do we have to handle plurals?

Nope.

Do we have to deal with apostrophes and periods and stuff like that when looking at simple words?

Nope. You can still be E without that.

What score should we get for the Boynton story?

I haven’t written the code yet.

Share your score in the Q&A channel, see what others get, and cite each other.

Any hints on the first part?

Much of the first part is asking you to think about decomposition.

See the notes on lists below.

Do we really have to type out the incredibly repetitious code for the more efficient dale-chall?

I’ve done so. (Or at least I hope I’ve done so.)

If you want to write something that uses a similar technique (that is breaking up the longer list), but is more concise, feel free to do so. You may even earn a token. (It can still be considered “E” without it.)

Is there a good way to get rid of multiple punctuation marks?

    (list->string (filter not-punctuation? (string->list str)))

    (define not-punctuation? 
       (lambda (ch) 
         (not (or (char-=? ch ".") 
                  (char-=? ch ",") 
                  ...))))

    (define not-punctuation?
      (let ([punctuation (string->list ".,'?!;:")])
        (lambda (ch)
          (= (tally-value punctuation ch) 0))))

Do I really need to make the lists for dale-chall2 outside the lambda?

Yes. That’s part of the point. We do the expensive work once.

(define proc (let [...] (lambda (...))))

Do you have tips for less ugly code?

Not today.

How many words should we work with?

Arbitrary. Hint: Use map.

Testing

Should we run tests that we know will break the function.

Probably not. You should meet the preconditions of the function.

There is a way to check if it breaks in expected ways. We’re not going to worry about that right now.

    (check-exn exn:fail? (lambda () THING-TO-TEST))

For example

    > (check-exn exn:fail? (lambda () (/ 1 0)))
    ; No output.  The test succeeded.  Yay!
    > (check-exn exn:fail? (lambda () (/ 1 1)))
    --------------------
    . FAILURE
    name:       check-exn
    location:   interactions from an unsaved editor:25:2
    params:     '(#<procedure:exn:fail?> #<procedure>)
    message:    "No exception raised"
    --------------------

How do I write tests if I don’t know what the output is going to be?

(check-equal #t (easy-word? “baa”))

(check-equal #f (easy-word “penultimate”))

(check-equal 1 (tally-word “says” (list “the” “cow” “says” “moo”)))

(check-equal 0 (tally-word “pizzaays” (list “the” “cow” “says” “moo”)))

(check-equal 1 (tally-word “SAYS” (list “the” “cow” “says” “moo”)))

(check-equal 2 (tally-word “SAYS” (list “Says” “the” “cow” “says” “moo”)))

(check-equal 3 (tally-word “SAYS” (list “Says” “the” “cow” “says” “moo” “says”)))

What is the third parameter for check-=?

Accuracy mark. How close do the two numbers have to be?

> (sqrt 2)
1.4142135623730951
> (sqr (sqrt 2))
2.0000000000000004
> (check-= (sqr (sqrt 2))
           2.0
           0.000001)
> (check-= (sqr (sqrt 2))
           2.0
           0)
--------------------
. FAILURE
name:       check-=
location:   interactions from an unsaved editor:21:2
params:     '(2.0000000000000004 2.0 0)
--------------------

How do you know you’ve done enough testing?

It depends on the situation.

In many situtations, I look for three or four edge cases and three or four normal cases.

In some situations, I write code to write my tests. Sam has been known to write code that does thousands of tests.

Recursion

Could we go over self-check one?

Yes. I’ve added it to the agenda.

Miscellaneous

DrRacket regularly tells me that I’m out of memory. What do I do?

Cry.

Share your code with Sam and see if he can figure out why.

Become rich (or be rich) and buy a larger computer?

Bad recursion will run out of memory! Take it as a sign.

What’s the difference between tally and tally-value?

tally-value looks for a particular value.

(tally-value (list “the” “cow” “says” “moo”) “says”) —> 1

(tally-value (string-split “The cow says moo The sheep says baa”) “says”) —> 2

(tally-value (string-split “The cow says moo The sheep says baa”) “the”) —> 0

tally-value only does exact matches

(tally odd? (list 1 2 3)) –> 2

(tally (lambda (x) (> x 10)) (list 1 2 3)) –> 0

(tally (lambda (x) (< x 10)) (list 1 2 3)) –> 3

(tally (lambda (x) (< x 3)) (list 1 2 3)) –> 2

How does that help me on the assignment?

You have problem in which you have to do case-insensitive tallying.

You could use tally with a predicate that does case-insensistive comparison

(tally (section string-ci=? "THE" <>) (...))

You could use tally-value converting everything to lowercase.

(tally-value (map string-downcase (...)) (string-downcase "THE"))

Can you explain how you used section above?

Option 1. (define the? (lambda (str) (string-ci=? "THE" str)))

(tally the? (...))

Option 2. Just write the lambda.

(tally (lambda (str) (string-ci=? "THE" str)) (...))

Option 3: Section is a more concise way to write the lambda.

(section string-ci=? "THE" <>) - A procedure that takes one input and compares it to “THE” using string-ci=??

Or “The procedure that results from filling in one of the two parameters to string-ci=?, leaving the other waiting.”

Over time, section becomes natural.

Section is awesome because it encourages you to create new procedures on the fly because they are low friction.

Why do I keep seeing #<procedure> when I use section?

What is (section + 2 <>)?

Answer: “It’s a procedure that takes one parameter and adds 2.”

Answer: But it hasn’t been applied yet.

> (section + 2 <>)
#<procedure>
> +
#<procedure:+>
> (o (section 2 <>) sqr)
#<procedure:...s/csc151/hop.rkt:167:4>

End of class ————

It’s 9:30. But Sam will answer general questions and then particular questions.

Code from DrRacket

#lang racket
(require 2htdp/image)
(require csc151)
(require Desktop/csc151-helper)
(require rackunit)

; Code for class 15

(define not-punctuation?
  (let ([punctuation (string->list ".,'?!;:")])
    (lambda (ch)
      (= (tally-value punctuation ch) 0))))

(check-equal? #t (not-punctuation? #\a))
(check-equal? #f (not-punctuation? #\;))

;;; (um-sure str) -> string?
;;;   str : string?
;;; Removes all the punctuation from the given string.
(define um-sure
  (lambda (str)
    (list->string (filter not-punctuation? (string->list str)))))

(check-equal? (um-sure ".,?")
              ""
              "all punctuation")
(check-equal? (um-sure "the cow says 'moo'!")
              "the cow says moo"
              "Boynton")
(check-equal? (um-sure "Let me see.  I don't think I understand.")
              "Let me see  I dont think I understand"
              "misunderstanding")
(check-equal? (um-sure "um")
              "um"
              "edge case: no punctuation")
(check-equal?
 (um-sure "One sentence, like this one, with lots of punctuaation; perhaps one with multiple clauses: Please try now!.")
 "One sentence like this one with lots of punctuaation perhaps one with multiple clauses Please try now"
 "Long")
(check-equal? (um-sure "")
              ""
              "edge-case: empty string")

General question on HW3

How do I get a sectioned procedure to take from a list?

;;; (ncopies str n) -> string?
;;;   str : string?
;;;   n : non-negative integer?
;;; Makes a string consisting of `n` copies of `str`.
(define ncopies
  (lambda (str n)
    (apply string-append (make-list n str))))

(check-equal? (ncopies "hello" 0)
              ""
              "0 copies")
(check-equal? (ncopies "hello" 1)
              "hello"
              "1 copy")
(check-equal? (ncopies "hello" 2)
              "hellohello"
              2)

Let’s say I want to triplicate every word in the first sentence of my most-used book in class.

> (map (section ncopies <> 3)
     (string-split "the cow says moo"))
'("thethethe" "cowcowcow" "sayssayssays" "moomoomoo")

I can even turn it into a procedure (that I’m not going to document or test).

(define triplicate
  (lambda (lst)
    (map (section ncopies <> 3) lst)))
> (triplicate '("once" "upon" "a" "time"))
'("onceonceonce" "uponuponupon" "aaa" "timetimetime")
> (triplicate '())
'()
> (triplicate (triplicate (string-split "this is fun")))
'("thisthisthisthisthisthisthisthisthis" "isisisisisisisisis" "funfunfunfunfunfunfunfunfun")

Testing

Where should we write tests?

Not necessary for this mini-project.

Generally, I put them right after the code.

Doc Comments

Should we doc comment all of our procedures?

Specific questions for HW3

Lessons from those discussions.

  • Please put parens around your parameters!
  • Please document your procedures.
  • When things aren’t working, look at the smaller problems.
  • Decompose!