EBoard 19: SoLA 2

This class will be recorded! Its use is limited to members of the class. Please do not share with others.

Approximate overview

  • Q&A [As much time as it takes]

Note: The approach I use is to gather questions from everyone who is here, do my best to answer those questions (perhaps calling on you)

General Policies

Do we have to be here?

No. It’s optional review / Q&A.

How long do we have for this exam?

All the SoLAs are due Saturday at 3pm CST.

I expect that you should be able to do any one SoLA in about twenty minutes.

You cannot spend more than 60 minutes on any one SoLA.

Seven new SoLAs: 140 minutes

Seven new SoLAs + two redos: 180 minutes

One SoLA: 20 minutes

How will the “missed SoLAs” work?

There are new questions for each of the seven topics from the first group of learning assessments. Take as many or as few as you’d like.

Please do not do LAs you’ve passed already.

What happens if I do nothing this time and missed two the first time?

Sam will get to write new versions of those two problems and the seven other problems.

Acronyms / First SoLA

Did you fix the bugs in the first sample SoLA problem?

Yes.

Local bindings

Could we go over the one on the sample?

Original version!

;;; (letter->number ch) -> either integer? boolean?
;;;   ch : char?
;;; Converts ch to the corresponding number in the English alphabet.
;;; (1 for #\a or #\A, 2 for #\b or #\B, etc.).  Returns false (#f)
;;; if ch is not a letter in the English alphabet.
(define letter->number
  (lambda (ch)
    (cond
      [(<= (char->integer #\a) (char->integer ch) (char->integer #\z))
       (+ 1 (- (char->integer ch) 97))]
      [(<= (char->integer #\a) (+ (char->integer ch) 32) (char->integer #\z))
       (+ 1 (- (+ (char->integer ch) 32) 97))]
      [else #f])))

(check-equal? (map letter->number (string->list "abcde"))
              '(1 2 3 4 5)
              "First five lowercase letters")
(check-equal? (map letter->number (string->list "ABCDE"))
              '(1 2 3 4 5)
              "First five uppercase letters")
(check-equal? (map letter->number (string->list "XYZ"))
              '(24 25 26)
              "Last three uppercase letters")
(check-equal? (map letter->number (string->list "xyz"))
              '(24 25 26)
              "Last three lowercase letters")
(check-equal? (letter->number #\.)
              #f
              "Not a letter")

What Sam would have expected

(define letter->number
  (let ([anum (char->integer #\a)]
        [znum (char->integer #\z)]
        [diff-cap (- (char->integer #\s) (char->integer #\S))])
    (lambda (ch)
      (let* ([charnum (char->integer ch)]
             [capital-num (+ charnum 32)]) ; Number of capital version
        (cond
          [(<= anum charnum znum)
           (+ 1 (- charnum anum))]
          [(<= anum capital-num znum)
           (+ 1 (- capital-num anum))]
          [else
           #f])))))

Or perhaps

(define letter->number
  (let* ([anum (char->integer #\a)]
         [znum (char->integer #\z)]
         [diff-cap (- (char->integer #\s) (char->integer #\S))]
         [number-of-lowercase-letter? (lambda (num)
                    (<= anum num znum))])
    (lambda (ch)
      (let* ([charnum (char->integer ch)]
             [capital-num (+ charnum 32)]) ; Number of capital version
        (cond
          [(number-of-lowercase-letter? charnum)
           (+ 1 (- charnum anum))]
          [(number-of-lowercase-letter? capital-num)
           (+ 1 (- capital-num anum))]
          [else
           #f])))))

Could we do another?

Original

(define dale-chall-score
  (lambda (num-difficult-words total-words num-sentences)
    (if (> (/ num-difficult-words total-words) 0.5)
        (+ 3.6365
           (+ (* 0.1579 (/ num-difficult-words total-words) 100)
              (* 0.0496 (/ total-words num-sentences))))
        (+ (* 0.1579 (/ num-difficult-words total-words) 100)
           (* 0.0496 (/ total-words num-sentences))))))

Identify percentage-of-difficult-words (PDW)

(define dale-chall-score
  (lambda (num-difficult-words total-words num-sentences)
    (let ([PDW (/ num-difficult-words total-words)])
      (if (> PDW 0.5)
          (+ 3.6365
             (+ (* 0.1579 PDW 100)
                (* 0.0496 (/ total-words num-sentences))))
          (+ (* 0.1579 PDW 100)
             (* 0.0496 (/ total-words num-sentences)))))))

Identify average sentence length.

(define dale-chall-score
  (lambda (num-difficult-words total-words num-sentences)
    (let ([PDW (/ num-difficult-words total-words)]
          [ASL (/ total-words num-sentences)])
      (if (> PDW 0.5)
          (+ 3.6365
             (+ (* 0.1579 PDW 100) (* 0.0496 ASL)))
          (+ (* 0.1579 PDW 100) (* 0.0496 ASL))))))

Extract the weird formula (base-score).

(define dale-chall-score
  (lambda (num-difficult-words total-words num-sentences)
    (let ([PDW (/ num-difficult-words total-words)]
          [ASL (/ total-words num-sentences)]
          [base-score (+ (* 0.1579 PDW 100) (* 0.0496 ASL))])
      (if (> PDW 0.5)
          (+ 3.6365 base-score)
          base-score))))

Do a let for the magic numbers?

What is a magic number?

A “magic number” is a number that just appears, with no context.

(define dale-chall-score
  (let ([enough-difficult-words-to-trigger-increment 0.5]
        [difficult-increment 3.6365]
        [difficult-contribution 0.1579])
    (lambda (num-difficult-words total-words num-sentences)
      (let ([PDW (/ num-difficult-words total-words)]
            [ASL (/ total-words num-sentences)]
            [base-score (+ (* difficult-contribution PDW 100) (* 0.0496 ASL))])
        (if (> PDW enough-difficult-words-to-trigger-increment)
            (+ difficult-increment base-score)
            base-score)))))

Or maybe that was overkill.

Program style

Can we do an example?

(define dim (lambda
(x y)
(cond [(= x 1)
31] [(= x 2)
(- 31 (- (if (= (mod y 4) 0) (if (= (mod y 100) 0) (if (= (mod y 400) 0) 3 2) 3) 2))]
[(= x 4) (- 31 1)]
[(= 6 x) (- 31
1)]
[(= (* 12 11) (* 12 x)) (
-
31
1)]
[else
31])))

[No, it won’t be this evil.]

Put it in DrRacket and realign.

(define dim
  (lambda (x y) 
    (cond
      [(= x 1)
       31]
      [(= x 2) 
       (- 31 (- (if (= (mod y 4) 0)) (if (= (mod y 100) 0) (if (= (mod y 400) 0) 3 2) 3) 2))]
      [(= x 4)
       (- 31 1)]
      [(= 6 x)
       (- 31 1)]
      [(= (* 12 11) (* 12 x))
       (- 31 1)]
      [else
       31])))

And then Sam realizes he screwed up the original code.

Regular Expressions

Could we discuss the end of the lab?

;;; (string->words str) -> listof? string?
;;;   str : string?
;;; Make a list of all the words (sequences of letters)
;;; that appear in str.
(define string->words
  (lambda (str)
    (rex-find-matches rex-word str)))

(define rex-word
  (rex-repeat (rex-any-of (rex-char-range #\a #\z)
                          (rex-char-range #\A #\Z))))

Note: Take notes on the procedures you don’t see.

; +—————+————————————————– ; | Documentation | ; +—————+

How do I get the “baby bear” of documentation? Not too much and not too little?