Fundamentals of CS I (CS151 2001S) : Outlines

[Current]
[Discussions]
[Glance]
[Honesty]
[Instructions]
[Links]
[News]
[Search]
[Syllabus]
**Primary**

[Examples]
[Exams]
[Handouts]
[Homework]
[Labs]
[Outlines]
[Quizzes]
[Readings]
[Reference]
**Sets**

[Blackboard]
[Scheme Report]
[SamR's Schedule]
[Rebelsky/Fall 2000]
[Walker/Fall2000]
[Stone/Spring2000]
**Links**

Back to A Web Service. On to Records.

**Held** Monday, April 30, 2001

**Summary**

Today we go over some of the key issues from exam 2.

**Notes:**

- Read Records for Wednesday's class.
- Exam 2 returned.
- Coming up ...
- Friday: Take-home exam 3 assigned.
- Monday the 4th: In-class exam 3.
- Thursday the 10th: Project presentations
- Friday the 11th: Take-home exam 3 due; course evaluation
- Monday the 14thth: Exam 3 returned (I hope)
- 9:00 a.m. Friday the 18th: Final exam

- Some of you seem to be wondering whether you should go on to
152. You can probably use this exam as a gauge.
- 90 or better: I'd strongly encourage you to go on.
- 75 or better: You'll probably do okay in 152
- Below 75: Chat with me first

- Note that 151 is not always a great predictor for 152, since the two courses sometimes take advantage of very different thinking skills.

**Overview**

- General Issues
- Problem 1: Grading
- Justifying
- Detecting end of file

- Problem 2:
`map!`

- Efficiency: Don't recompute things

- Problem 3: Currying
- Many ways of looking at a curried procedure.

- Grading:
- Each problem worth 30 points
- 10 base points in addition
- Extra credit limited to talks

- Generally, I work backwards from 30
- If there are enough errors, I look for some glimmer of hope and award a base grade.

- I neither calculate nor announce averages, medians, minima, or maxima. You should know your grade because I do grade on an absolute scale.
- A few of you seem to have given output that, as far as I can tell, could never have happened. Please don't fake your output.
- Many of you still need more care in your pre- and post-conditions.
- A few of you wrote local helpers in which you passed parameters that you never changed. In such cases, there's no reason to include those things as parameters (and it clarifies your code to leave them out).

- Basic strategy:
- Read the list
- Map a procedure that builds the last/first/grade triplet onto the list.
- Map a procedure that writes each triplet to a file onto the new list.

- Typical penalties:
- Uses
file

andport

interchangably (-2) - Doesn't close input or output (-5)
- Preconditions don't mention format of input file (-2)
- Preconditions don't restric procedure to a function from lists of numbers to numbers (-2)
- Doesn't right-align numbers (-2)

- Uses
- Typical awards
- Determines the maximum-length first and last names (+2)
- Extracts numbers from the list (+2)

- Writing left-justify and right-justify.
- Just add spaces on the correct side.
- Make the proper number of spaces with
`make-string`

. - For example
(define left-align (lambda (str width) (let ((len (string-length str))) ; If the string is too long, chop it! (if (> len width) (substring str 0 width) ; Otherwise, add the appropriate number of spaces. (string-append str (make-string (- width len) #\space))))))

- You can figure out the maximum size last or first name with something
like
(apply min (map (compose string-length car) students))

- A few of you had problems determining the end of file because you
used
`peek-char`

. Unfortunately, if you're using`read`

to get each student, the next character after the last student is a newline, rather than the eof mark.- The solution is to just read first and then decide whether or not you read a student.

`map!`

- This problem should have been straightforward.
- I looked carefully at preconditions and efficiency.
- Typical errors:
- No preconditions for
`proc`

. (It should be a procedure of one parameter; it should be applyable to every element of`vec`

.) - Doesn't work correctly for the empty vector.
- Does extra computation (typically be recomputing the vector length each time).

- No preconditions for
- Here's a straightforward but imperfect solution. How many
problems can you identify?
(define map! (lambda (proc vec) (let helper ((hproc proc) (hvec vec) (pos 0)) (if (= pos (- (vector-length vec) 1)) (vector-set! vec pos (hproc (vector-ref vec pos))) (begin (vector-set! vec pos (hproc (vector-ref vec pos))) (helper proc vec (+ pos 1)))))))

- Here are some problems:
- It's not clear what purpose
`hproc`

and`hvec`

serve (or when you should use one rather than the other). - If the vector is empty, this will crash nastily.
- Each time through, this recomputes the vector's length.

- It's not clear what purpose
- Solutions:
- We don't need
`hproc`

and`hvec`

. - Use a different base case.
- Either precompute the length once (use
`let`

) or count down, rather than up.

- We don't need
- Here's a better version.
(define map! (lambda (proc vec) (let helper ((pos (- (vector-length vec) 1))) (if (>= pos 0) (begin (vector-set! vec pos (proc (vector-ref vec pos))) (helper proc vec (- pos 1)))))))

- The biggest problems here seemed to have to do with reading the
instructions.
- Writing left-section rather than right-section
- Writing non-curried procedures
- Taking non-curried procedures as parameters
- Forgetting to write documentation

- The other problem that stymied some person was a, in which they
mapped
`(lambda (x) ((cexpt 2) x))`

instead of just`(cexpt 2)`

, which was the point of the problem. - Because of the complexity of currying, I was more lenient in
grading preconditions. In particular,
`ccompose`

needs fairly careful preconditions. - A few of you got confused by the multiple ways you can read a
curried procedure. Consider
`c-right-section`

(define c-right-section (lambda (proc) (lambda (right) (lambda (left) ((proc right) left)))))

- Do we read this as
- A procedure of one parameter that returns a procedure of two parameters?
- A procedure of two parameters that returns a procedure of one parameter?
- A procedure of three parameters that returns a value?

- In the first case, we might call it
`reverse-args`

and say something like- Returns a procedure like
`proc`

except the order of parameters is reversed. That is,`(newproc a b)`

is the same as`(proc b a)`

.

- Returns a procedure like
- In the second case, we should think of it as the traditional right-section.
- In the third case, we might simply say
- Computes
`(proc right left)`

- Which will leave someone wondering why we bothered to write it in the first place.

- Computes

Back to A Web Service. On to Records.

[Current]
[Discussions]
[Glance]
[Honesty]
[Instructions]
[Links]
[News]
[Search]
[Syllabus]
**Primary**

[Examples]
[Exams]
[Handouts]
[Homework]
[Labs]
[Outlines]
[Quizzes]
[Readings]
[Reference]
**Sets**

[Blackboard]
[Scheme Report]
[SamR's Schedule]
[Rebelsky/Fall 2000]
[Walker/Fall2000]
[Stone/Spring2000]
**Links**

**Disclaimer**:
I usually create these pages on the fly. This means that they
are rarely proofread and may contain bad grammar and incorrect details.
It also means that I may update them regularly (see the history for
more details). Feel free to contact me with any suggestions for changes.

This page was generated by Siteweaver on Wed May 5 12:15:13 2004.

This page may be found at `http://www.cs.grinnell.edu/~rebelsky/Courses/CS151/2001S/outline.49.html`

.

You may validate
this page's HTML.

The source was last modified Tue Jan 23 16:01:59 2001.