University of California, Berkeley
EECS Department - Computer Science Division
CS3 Lecture 21 : Input / Output
Overview of today's lecture
Review
Trees
- We saw trees, a data structure for hierarchical data
- We learned a lot of new vocabulary words
- We saw how we represented trees as lists
- We talked about respecting and violating the data abstraction
- We saw how we used mutual recursion to walk the tree
- We saw how tree recursion was similar to car/cdr
recursion
Strings
- Another data type (other than number, symbol and list)
- The following is taken from MacGambit's Online Help (under
Apple menu)
- Strings are sequences of characters enclosed within doublequotes
("), e.g.,
"This sentence has five words"
- A doublequote can be written inside a string only by escaping
it with a backslash (\), as in:
"The word \"recursion\" has many
meanings."
- There are lots of string manipulation functions should you
care to look at them
- MacGambit's Online Help (under Apple menu, choose "S"
commands)
- Dr. Scheme's Help (search for String)
: "Go Bears"
==>
: (string? "Go Bears")
==>
: (string-length "Go Bears")
==>
Sequential Programming
Effect, Sequence and State
- Effect
- Calling our procedures now has some side-effect, like
printing to the screen, writing a file, drawing lines, running
a toaster, etc.
- Sequence
- Some problems decompose into a sequence of actions (like
a recipe)
- We're now doing sequential programming (unlike functional
programming), a different metaphor where the order of events
really matters.
- State
- Our results may now depend on the past history, or past state
of the world, unlike anything we've seen before!
Input / Output
"This is the point at which there is usually
some ..."
Output functions
- Up to now, you haven't seen any procedures with side-effects.
- It's time to look at some functions that perform output side-effects
- (newline)
- [side-effect] Prints out a blank line
- Return value undefined (implementation-dependent -- MacGambit
returns #f)
- (display expression)
- [side-effect] Prints out the value of the expression
- Prints strings without quotes
- Return value undefined (implementation-dependent -- MacGambit
returns the number of characters it outputs)
- (write expression)
- [side-effect] Prints out the value of the expression
- Prints strings with quotes
- Return value undefined (implementation-dependent -- MacGambit
returns the number of characters it outputs)
- display and write differ primarily in their
printing of strings, mostly you'll want to use display.
: (display 'a-symbol)
==>
: (write 'a-symbol)
==>
: (display "a string")
==>
: (write "a string")
==>
for-each - the mapping
function for side-effects
- (for-each function list )
- Returns: #[undefined], but applies function
to elements of list
- It is identical to map, except it does not return the results
of the function applications
- It guarantees that it applies the function to elements of
the list in left-to-right order
- (for-each function list1 list2 ... list3
)
- Requires: function must be a procedure taking
as many arguments as there are lists
- It applies function element-wise to the elements
of lists and returns a list of results from left
to right.
- The lists must be the same length.
- There is no guarantee what order the function will be applied
to the elements
- Examples with functions taking a single argument:
: (for-each abs '(-1 2 -3.4 -5/6))
side-effects ==>
==>
: (for-each msword-2050-command
'(launch open-term-paper print-it crash-as-usual))
side-effects ==>
==>
- Examples with functions taking more than one argument (taking
multiple lists).
: (for-each robot-command
'(write prepare massage))
'(my-term-paper lunch feet))
side-effects ==>
==>
- Let's write print-list-one-elt-per-line, which prints
out all the elements of a list, one per line:
;; : (print-list-one-elt-per-line '("Cal Bears" (we are) Number 1)) ==>
;; Cal Bears
;; (we are)
;; number
;; 1
;; done!
(define (print-list-one-elt-per-line L)
==>
==>
==>
==>
: (print-list-one-elt-per-line '("Cal Bears" (we are) Number 1))
==>
==>
==>
==>
==>
- Note the difference between Cal Bears (remained
capitalized) and Number (lowercase)
- Also note what happens if we don't add 'done! as
the return expression.
Output: What about if? (solution:
begin)
- Let's say we want to write big-game-winner-prediction
- This is a function to print a response to a prediction about
which school will win the big game. E.g.,
;; : (big-game-winner-prediction 'cal)
;; ==P Party on! You were right that
;; ==P Cal will win the Big Game!
;; ==> done!
;;
;; : (big-game-winner-prediction 'stanfurd)
;; ==P Bzzt! Thanks for trying...
;; ==P stanfurd will not win the Big Game, Cal will!
;; ==> done!
;;
;; : (big-game-winner-prediction 'eat-my-shorts)
;; ==P Bzzt! Thanks for trying...
;; ==P eat-my-shorts will not win the Big Game, Cal will!
;; ==> done!
(define (big-game-winner-prediction team)
(if (equal? team 'cal)
;; They predicted Cal
(display "Party on! You were right that")
(newline)
(display "Cal will win the Big Game!")
;; They didn't predict Cal
(display "Bzzt! Thanks for trying...")
(newline)
(display team)
(display " will not win the Big Game, Cal will!"))
(newline)
'done!)
- What is wrong with this? ==>
- Allow us to introduce begin
- (begin expression1 expression2 ...
expressionN)
- The expressions are evaluated sequentially from left to right.
- The value of the last expression is returned.
- This expression is used to sequence side effects such as
input and output.
- begin is useful when we want many expressions (mostly
with side-effects) to be evaluated but are stuck with syntax
which won't allow us to do it easily.
- Now, modify the code above so that it will work.
Input: read
- read is used to get a value from the user
- (read)
- Prints out nothing
- side-effects: Pauses execution of the program, waits for
the user to enter a value
- Returns: the unevaluated last expression the user
entered
- Typically let is used to save the value
- Examples:
: (read)
42
==>
: (read)
cs3
==>
: (read)
cs3 is the best class
==>
: (read)
"cs3 is the best class"
==>
: (read)
(cs3 is the best class)
==>
: (read)
(+ 1 1) (+ 150 150)
==>
Input example: get-valid-input
;; read until input is in valid-input
;; print intro message to user first - prompt
(define (get-valid-input valid-input message)
(display message)
(display " ")
(let ((input (read)))
(cond ((member input valid-input)
input)
(else (display "Bad value entered: ")
(display input)
(newline)
(get-valid-input valid-input message)))))
: (get-valid-input '(yes yep sure uh-huh) "Is CS3 cool?")
==>
==>
==>
==>
==>
==>
Summary
- We discussed ways of getting data in and out of your programs
-- and learned about our first side-effect functions!
Next Time
- We will see some interesting applications of recursion --
fractals!
Puzzle : Y3K NCAA Basketball Tournament
- In the year 3000 there are 1024 teams that make it to the
NCAA tournament
- How many games will there be to determine the winner?
Game : Seega ["Pentagames" by
Pentagram, Fireside Publishing, 1990]
- Two players each have 12 counters, and open the game by placing
two at a time on any two vacant squares except the central one.
- The objective is to capture all the opponent's counters.
- Take it in turns to move a counter to any vacant adjacent
square, including the central one, horizontally or vertically.
- If you trap an enemy counter between two of yours, remove
it from the board.
- You may then continue moving the same counter as long as
captures are made with it.
- More than one capture can also be made as below (on the right),
where X by moving onto the center square captures three O pieces.
- A counter on the center square is safe from attack, even
if it is trapped between two enemy counters, and a counter can
safely move between two enemy counters.
- If one player cannot move, the other must take an extra turn
and make an opening for the blocked player.
Blank Board |
Example Game (X to move) |