### COMP203: Lecture 9

Syllabus | Homework and Assignments | Grading Rubric | Midterm Exam | Final Project

When circumstances allow, I'll be typing up bits of my lecture notes and posting them online. These may or may not bear any resemblance to the actual lectures.

### Vocabulary Quiz Wednesday

On clearscreen, back, forward, penup, pendown, sentence, word, first, butfirst, last, butlast, item, readlist, readword, memberp, equalp, lessp, numberp. Spelling counts!

### Chapter 4

In 1854, George Boole laid the foundations for the logical processes almost all computers use today. He considered a mathematical system of two values -- true and false -- which could be combined using logical operations. Your calculations of truth tables in MATH180 were based on his work.

Ninety years later, the first digital computers were invented. The information in these computers was electrically encoded. A wire was either carrying a current or not. A memory register was either holding a charge or not. George Boole's two value arithmetic was the perfect basis for computer calculation.

#### Predicates

In Logo, a predicate is a procedure which always outputs one of two values: true or false. We've used the predicate equalp to write a quiz procedure:

```to music.quiz
print [Who is the greatest musician ever?]
if equalp readlist [John Lennon] [print [That's right!] stop]
print [No, silly, its John Lennon!]
end
```

Try out the examples of predicates below:

```print equalp "hi [hi]
print lessp 3 5
if lessp 5 3 [print [less than]]
if memberp "t "that [print [There is a "t" in "that".]]
if memberp "q "that [print [There is a "q" in "that".]]
print memberp "t [a e i o u]
print memberp "dog [The quick brown fox jumped over the lazy dog.]
```
As you can see from the examples using if, predicates can be used to make Logo behave differently in different contexts.

#### Writing our own Predicates

Suppose I wanted Logo to check to see if a number was a multiple of 10. How would I do that?

You probably decide whether a number is divisible by 10 by looking at it to see if it ends in 0. What Logo procedures and predicates could we use to do this?

A solution that's easier to generalize -- to divisibility by 2, or 9, or 17 -- is to try dividing by 10 and see if there's a remainder. What Logo procedures and predicates could we use to do this?

We want to write a procedure which outputs "true if its input is divisible by 10 and "false otherwise. We know that all Logo's predicates always output either "true or "false, so we can write a predicate by using the output of another predicate as the input of output.

```to multipleoftenp :num
output equalp (remainder :num 10) 0
end
```
```to mult_of_ten_p :number
output equalp (last :number) 0
end
```
Which of these procedures do you like best? Why?

Now see if you can write a predicate negativep that uses another predicate to output "true if its input is less than 0 and "false otherwise.

1. How many inputs will your procedure require? What will you name them?
2. How will you tell if the input is negative or positive?
3. Make sure your procedure always outputs (not prints!) either true or false.
If you finish early, see if you can think of a different way to do the same thing.

#### if

We've been testing our predicates by printing their output, but in practice we'll want to use them to help the computer do different things under different circumstances. To do this, we use the commands if and ifelse. Remember if from music.quiz:
```to music.quiz
print [Who is the greatest musician ever?]
if equalp readlist [John Lennon] [print [Yes, that's right!] stop]
print [No, silly, it's John Lennon.]
end
```
Draw a plumbing diagram for the instruction starting with the command if.

The output of the predicate equalp is the input to if.

if is a command which requires two inputs. The first input must be a true or false value, and the second input is a list of instructions to run if the first input is true.

In procedure music.quiz, if the output of equalp is true then the name entered was [John Lennon] and Logo congratulates the user. For any other entry, equalp outputs false and the if command completes without doing anything further. The next instruction in music.quiz then corrects the user's taste in musicians.

Experiment with the instructions below to understand if better.

```if "true [print [It was true.]]
if "false [print [It was true.]]
if "false [print [It was false.]]
if numberp "a [print sum 3 5]
if numberp "2 [print sum 3 5]
if equalp readword "triangle [repeat 3 [forward 100 right 120]]
```
The instructions below don't work. What's wrong with them? Can you figure out what they were intended to do and fix them?
```if "true print "true
if [equalp 2 3] [print [They are equal.]]
if vowelp "a [word "a "n]
print if equalp 2 3 [sum 2 3]
```

#### Practice

• Write a procedure which accepts a number as input and prints the word big if the number is greater than 10 and does nothing if the number is less than or equal to 10.
• Write a procedure which asks the user for a favorite word and displays the message Fryd lykes that wyrd! if there is a y in the word they type in and otherwise does nothing.

#### Examples

For more examples using the if command, take a look at the haunted house game or work through the examples below.

In this example from the book, we use if to write a predicate that checks whether a phrase (list) is about computers. This helps the computer react appropriately to our response to a question.

```to about.computersp :phrase
if memberp "computers :phrase [output "true]
if memberp "programming :phrase [output "true]
if memberp "Logo :phrase [output "true]
output "false
end
```
We can test this out by sending its output to print:
```? print about.computersp [I like computers.]
true
? print about.computersp [7 8 9 10]
false
```
but it's more fun and interesting to use it in a program.
```to chat
print [What do you think of COMP203 so far?]
if about.computersp readlist [print [Yeah, computers are neat!] stop]
print [Interesting.  But do you like programming in Logo?]
end
```
Try it out! What happens if you answer The computer is my friend.? Is this a statement about computers? Change the predicate about.computersp so that chat responds correctly to this statement.

The predicate about.computersp responds positively to several different phrases. We can use a similar technique to allow multiple right answers to a question. Write a predicate that allows a quiz procedure to accept different versions of the correct answer like those demonstrated below. Or, if you prefer, you could write a program which asks the user "How are you?" and responds intelligently to their answer.

```? writers.quiz
Who is the greatest writer ever?
Tolkien
Yes, that's right!
? writers.quiz
Who is the greatest writer ever?
J. R. R. Tolkien
Yes, that's right!
? sports.quiz
What is your favorite baseball team?
Red Sox
Yeah, me too!
? sports.quiz
What is your favorite baseball team?
Boston Red Sox
Yeah, me too!
? sports.quiz
What is your favorite baseball team?
White Sox
Yeah, me too!
? sports.quiz
What is your favorite baseball team?
Yankees
Seriously?
?
```

#### ifelse

Once you understand if, you'll soon want to use the Logo command ifelse This procedure expects three inputs. The first input is, again, a true/false value. The second input is (again) a list of instructions to run if the first input is true. The third input is a list of instructions for Logo to run if the first input is false. Using ifelse we can rewrite our music.quiz procedure so that it no longer needs the stop command:
```to music.quiz
print [Who is the greatest musician ever?]
ifelse equalp readlist [John Lennon] ~
[print [Yes, that's right!]] [print [No, silly, it's John Lennon.]]
end
```
Draw a plumbing diagram for this ifelse instruction.

Use the command ifelse, and what we learned about testing for divisibility using Logo to write a program that asks the user to type in a number and then tells the user whether that number is even or odd.

```? isiteven
Please type in a number.
7
7 is odd.
? isiteven
Please type in a number.
6
6 is even.
?
```
What should your procedure do if you type in a number with a fractional part? Can you make it do that? (What tools do you need, and do they exist? Where in the procedure should you check for a fractional part? What should the program do if the number has a fractional part?)

What should your procedure do if you type something which isn't a number? Can you make it do that? (What tools do you need, and do they exist? Where in the procedure should you check whether it's a number? What should the program do if it's not a number?)