CSC 153 Grinnell College Spring, 2005 Computer Science Fundamentals Laboratory Exercise

Input and Output

Goals

This laboratory exercise considers output procedures to aid in the tracing of a program. This lab also discusses interactive Scheme programming, using read, display and write statements. Finally, the lab mentions the use of sentinel values to halt the reading of data from the keyboard.

Tracing Program Execution

Consider the following two versions of a procedure to add 2 to each element in a list:

```
(lambda (L)
;Pre-condition:  L is a list of numbers
;Post-condition:  returns a new list where 2 is added to each value in L
(if (null? L)
'()
(cons (+ 2 (car L)) (simple-add2 (cdr L))))
)
)

(lambda (L)
;Pre-condition:  L is a list of numbers
;Post-condition:  returns a new list where 2 is added to each value in L
(display L) (newline) ;;NEW: print out current list on separate line
(if (null? L)
'()
(cons (+ 2 (car L)) (simple-add2-trace (cdr L))))
)
)
```

1. Check that procedure simple-add2 works correctly, by running it with the command

(simple-add2 '(2 6 -3 0 4.689))
2. Run the revised proceduresimple-add2-trace with the same data you used in styp 1, by typing
(simple-add2-trace '(2 6 -3 0 4.689))

3. Write a few sentences to explain what appears at your screen:

• What produces each of the first six lines of the output?
• Where does the last line of output come from?

Side Effects

Experiment further with display and newline.

1. How does the output from simple-add2-trace change if a second expression (newline) is added, immediately after the first? In a sentence or two, explain why the output appears in this format.

2. How does the output from simple-add2-trace change if the (newline) expression is removed entirely? Explain briefly.

3. What happens if the line (display L) (newline) is moved from immediately before the if expression to immediately after it? Explain briefly.

4. What happens if the line (display L) (newline) appears both before and after the if expression? Explain briefly.

5. In Scheme, the display procedure is designed to print only one parameter. Determine what happens when more parameters are given by typing (display 'x 'y).

Sequencing

Now consider this further-revised version of simple-add2-trace:

```
(lambda (L)
;Pre-condition:  L is a list of numbers
;Post-condition:  returns a new list where 2 is added to each value in L
(display L)
(if (null? L)
(begin
(display "  then clause") (newline)
'()
)
(begin
(display "  else clause") (newline)
(cons (+ 2 (car L)) (simple-add2-trace (cdr L)))
)
)
)
)
```
1. Run this revised procedure with the same data: (simple-add2-trace '(2 6 -3 0 4.689))
Write a few sentences to explain what appears at your screen.
When several expressions are executed in a begin expression, the value of the final expression is returned as the value of the begin expression. Now consider what happens when the display expression is moved to the end of each begin expression:
```
(lambda (L)
;Pre-condition:  L is a list of numbers
;Post-condition:  returns a new list where 2 is added to each value in L
(display L)
(if (null? L)
(begin
'()
(display "  then clause") (newline)
)
(begin
(cons (+ 2 (car L)) (simple-add2-trace (cdr L)))
(display "  else clause") (newline)
)
)
)
)
```
1. Again, run this revised procedure with (simple-add2-trace '(2 6 -3 0 4.689)), and explain the output carefully.

Consider the following procedure that reads 3 scores from the keyboard and averages them:

```
(define average-3
(lambda ()
;Pre-condition:  None
;Post-condition:  returns the average of 3 numbers read from the keyboard
(display "Enter three numbers:  ")
(display " is the average of the three numbers")
(newline)
)
)
```
1. What happens if you enter three fractions or some negative numbers when you run this procedure?

2. What happens if you enter a string instead of a number when you run this procedure?

3. Suppose you wanted to average any number of values; you might ask the computer to continue reading numbers until you entered a 0. In this context, you could pass the current sum and the number of values read to the kernel procedure. The base case would be identified by checking if the current value read was zero.

Write an average procedure which reads successive numbers until 0 is entered and computes and prints the average of these numbers. Be sure you do not include 0 in your computation of the average.

Note: In this problem, the number 0 is called a sentinel. Generally, a sentinel is a value read that tells the computer something special about how processing should proceed.

Formatted Output

Consider the following procedures to create a table of square roots:

```(define sqrt-table
(lambda (n)
(display "Number   Square Root")
(newline)
(sqrt-table-helper n)
)
)

(define sqrt-table-helper
(lambda (n)
(if (>= n 1)
(begin
(sqrt-table-helper (- n 1))
(display n)
(display (sqrt n))
(newline))
)
)
)
```
1. Run this procedure to obtain a table of the square roots of the integers 1, 2, 3, 4, and 5.

2. Within your Scheme environment, load the customized I/O package ~walker/151s/labs/write-formatted.ss with the statement:

```(load "~walker/151s/labs/write-formatted.ss")
```

This package, written by John David Stone, contains procedures write-int and write-real for formatting integer and real numbers, respectively. The write-int procedure asks for the number to be printed and the width of the field for printing. In our example, we want 4 spaces for our integer n (3 blank spaces plus the digit). Thus, we write

```(write-int n 4)
```
Similarly, for real numbers, we supply write-real with the number to be printed, the total width for printing the number, and the desired number of decimal places. In this example, the number takes 14 characters overall, with 5 decimal place accuracy:
```(write-real (sqrt n) 14 5)
```

Replace the `display` statements in `sqrt-table-helper` by the corresponding `write-int` and write-real statements, and check that the new formatting works as required.

3. Run `write-int` with various integers and widths to check that it runs correctly. What happens if `write-int` is given a width that is narrower than required by the number to be printed (e.g., 2 spaces allocated for the printing of 456)?

4. Run write-real with a several real numbers, widths, and fractional-lengths to check that it also runs correctly.

This document is available on the World Wide Web as

```http://www.cs.grinnell.edu/~walker/courses/153.sp05/labs/lab-i-o.shtml
```