0% found this document useful (0 votes)
7 views49 pages

Post1up 03-Simpledata

The document explains the use of relational operators and Boolean values in Racket programming, emphasizing how expressions like 'x < 5' differ from traditional mathematical interpretations. It covers predicates, conditional expressions, and the use of logical operators such as 'and', 'or', and 'not' to combine conditions. Additionally, it discusses the evaluation of conditional expressions using 'cond' and the importance of handling all possible cases to avoid errors.

Uploaded by

lir589973
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views49 pages

Post1up 03-Simpledata

The document explains the use of relational operators and Boolean values in Racket programming, emphasizing how expressions like 'x < 5' differ from traditional mathematical interpretations. It covers predicates, conditional expressions, and the use of logical operators such as 'and', 'or', and 'not' to combine conditions. Additionally, it discusses the evaluation of conditional expressions using 'cond' and the importance of handling all possible cases to avoid errors.

Uploaded by

lir589973
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 49

03: Simple Data

What does “<” mean? M03 2/39

Consider the expression “x < 5”.


In math class, it tells us something about x: whatever value x has, that value is less than 5.
We might combine the statement “x < 5” with the statements “x is even” and “x is a perfect
square” to conclude “x is 4”.
In Racket, “<” means something different. A constant such as x already has a value.
What does “<” mean? M03 3/39

Suppose we define a constant:


(define x 2)

Now we create a Racket expression as close to “x < 5” as possible:


(< x 5)

This is asking “Is it true that the value of x is less than 5?”
If we evaluate (< x 5), we substitute in the value of the constant, so our expression
becomes (< 2 5). Since it is true that 2 < 5, the statement evaluates to true.
On the other hand, if we define the constant:
(define y 10)

Now (< y 5) ⇒ (< 10 5) ⇒ false since it is not the case that 10 < 5.
Booleans (Bool) M03 4/39

trueand false are values, just like 0, 100, and 22/7 are values. true and false are
Boolean values; the others are numeric values.
<, >, <=, >=, and = are functions, each of which produces a value, abbreviated Bool in
contracts.
(define x 4)
(< x 6) ⇒ is x (4) less than 6?
(> x 6) ⇒ is x greater than 6?
(= x 7) ⇒ is x equal to 7?
(>= 5 x) ⇒ is 5 greater than or equal to x?
(<= 5 x) ⇒ is 5 less than or equal to x?

Each produces true or false. These are the only values a Bool may take.
Predicates M03 5/39

A function which produces a Bool is called a predicate. For many predicates in Racket, the
name ends with ?.
We can also write our own predicates. For example:

;; (can-vote? age) produces true if the person is voting age.


(define (can-vote? age)
(>= age 18))

(check-expect (can-vote? 17) false)


(check-expect (can-vote? 20) true)
Figure out how to use each of the following predicates in DrRacket.
Be sure you understand when each produces true and when it produces false.
1 >
Ex. 1

2 even?
3 =
4 negative?
Combining predicates M03 6/39

Our previous version of can-vote? is too simplistic. In reality, you need to be at least 18
years old and a citizen.

;; (can-vote-v2? age citizen?) produces true if the person is eligible to vote.


(define (can-vote-v2? age citizen?)
(and (>= age 18) citizen?))

(check-expect (can-vote-v2? 18 true) true)


(check-expect (can-vote-v2? 18 false) false)
(check-expect (can-vote-v2? 16 true) false)

We combine predicates using the special forms and and or, and the function not. These all
consume and produce Bool values.
Combining predicates M03 7/39

We combine predicates using the special forms and and or, and the function not. These all
consume and produce Bool values.

and has value true when all of its arguments have value true; false otherwise.
or produces true if at least one of its arguments is true; false otherwise.
not produces true if its argument is false; false if its argument is true.

Both or and and require at least two arguments, but may have more.
Examples M03 8/39

;; (between? x a y) produces true ;; (go-run? rain? friends? temp)


;; if a is between x and y ;; determines whether one should go
(define (between? x a y) ;; for a run or not.
(and (<= x a) (<= a y))) (define (go-run? rain? friends? temp)
(and (not rain?)
(or (between? 13 temp 28)
;; (weak-password? p) produces true
friends?)))
;; if p is definitely a weak password
(define (weak-password? p)
(check-expect
(or (< (string-length p) 8)
(go-run? false true 33) true)
(string-numeric? p)
(string-lower-case? p)
(string-upper-case? p)))

(check-expect
(weak-password? "fooBar") true)
Write a function that consumes an Int, and produces
"baz" for even numbers in the interval [10, 40]
Ex. 2

"qux" for odd numbers in the interval [−20, 20]


"xyzzy" for numbers less than −100 or greater than 200
"corge" otherwise.
Predicates M03 9/39

Predicates defined in DrRacket include (read a row at a time):


(< 3 4) ⇒ true (< 4 3) ⇒ false similar for <=, >, >=, =
(number? 3) ⇒ true (number? 3.14) ⇒ true (number? true) ⇒ false
(integer? 3) ⇒ true (integer? 3.14) ⇒ false (integer? true) ⇒ false
(positive? 3) ⇒ true (positive? -3) ⇒ false (positive? true) ⇒ error
(negative? 3) ⇒ false (negative? -3) ⇒ true (negative? true) ⇒ error
(even? 3) ⇒ false (even? 4) ⇒ true (even? true) ⇒ error
(odd? 3) ⇒ true (odd? 4) ⇒ false (odd? true) ⇒ error
(zero? 0) ⇒ true (zero? 4) ⇒ false (zero? true) ⇒ error
(exact? 3) ⇒ true (exact? (/ 22 7)) ⇒ true (exact? true) ⇒ error
(exact? pi) ⇒ false
(boolean? true) ⇒ true (boolean? false) ⇒ true (boolean? 3) ⇒ false
(false? false) ⇒ true (false? true) ⇒ false (false? 3) ⇒ false
Short-circuit evaluation M03 10/39

Racket only evaluates as many arguments of and and or as is necessary to determine the
value. Examples:

;; Eliminate easy cases first; might not need to do


;; the much slower computation of prime?
(and (odd? x) (> x 2) (prime? x))

;; Is the line considered "steep"?


(define (steep? delta-x delta-y)
(or (= delta-x 0) ; Avoid dividing by zero
(>= (/ delta-y delta-x) 1)))

(define (not-steep? delta-x delta-y)


(and (not (= delta-x 0)) ; Avoid dividing by zero
(< (/ delta-y delta-x) 1)))
Rules 4-6: Substitution rules for and M03 11/39

Use the following substitution rules for tracing and:

(and false ...) => false

(and true ...) => (and ...)

(and) => true


Ex. 3 Perform a trace of

(and (= 3 3) (> 7 4) (< 7 4) (> 0 (/ 3 0)))

Check your work with the stepper in the commentary.

Perform a trace of:


Ex. 4

(define s "bravo")
(and (> 7 4) true (string=? s "bravo"))
Rules 7-9: Substitution rules for or M03 12/39

Use these substitution rules for tracing or:

(or true ...) ⇒ true

(or false ...) ⇒ (or ...)

(or) ⇒ false
Ex. 5 Perform a trace of

(or (< 7 4) (= 3 3) (> 7 4) (> 0 (/ 3 0)))

Check your work with the stepper in the commentary.

Perform a trace of
Ex. 6

(define s "bravo")
(or (< 7 4) false (string=? s "hooray"))
Conditional expressions M03 13/39

Sometimes expressions should take one value under some conditions, and other values
under other conditions.

2
A sin-squared window, used in signal
processing, can be described by the following
piecewise function:
1

0 for x < 0


f (x) = 1 for x ≥ 1

sin2 (xπ/2)

for 0 ≤ x < 1
0
−1 0 1 2

−1
> Conditional expressions (cont.) M03 14/39

We can compute the sin-squared window function f (x) with a conditional expression:

(cond [(< x 0) 0]
[(>= x 1) 1]
[(< x 1) (sqr (sin (* x pi 0.5)))])

Conditional expressions use the special form cond.


Each argument is a question/answer pair.
The question is a Boolean expression.
The answer is a possible value of the conditional expression.
Square brackets are used by convention, for readability.
Properly nested square brackets and parentheses are equivalent in the teaching
languages.
Evaluating a cond statement M03 15/39

How do we evaluate a cond?


Informally, evaluate a cond by considering the (define (ssqw x)
(cond
question/answer pairs in order, top to bottom. When
[(< x 0) 0]
considering a question/answer pair, evaluate the [(>= x 1) 1]
question. If the question evaluates to true, the whole [(< x 1)
cond produces the corresponding answer. (sqr (sin (* x pi 0.5)))]))

For example, consider (ssqw 4).


=> (cond [(< 4 0) 0]
[(>= 4 1) 1]
[(< 4 1) (sqr (sin (* 4 pi 0.5)))])
No satisfied questions M03 16/39

What happens if none of the questions evaluate to true?

(define (ssqw x)
(cond The second test has changed
[(< x 0) 0] from >= to just >.
[(> x 1) 1]
[(< x 1) (sqr (sin (* x pi 0.5)))]))

An error occurs if we try to run (ssqw 1)

This can be helpful – if we see this error we know we’ve missed a case in our code.
else M03 17/39

But sometimes we want to only describe some conditions, and do something different if
none of them are satisfied.
In these situations, the question in the last question/answer pair may be else.

(define (ssqw x)
(cond
[(< x 0) 0]
[(>= x 1) 1]
[else (sqr (sin (* x pi 0.5)))]))
Rules 10-12: Substitution in cond expressions M03 18/39

There are three rules: when the first expression is false, when it is true, and when it is else.

(cond [false exp] ...) ⇒ (cond ...)

(cond [true exp] ...) ⇒ exp

(cond [else exp]) ⇒ exp

These suffice to simplify any cond expression.


Here the ellipses are serving a different role. They are not showing a pattern, but showing
an omission. The first rule just says “whatever else appeared after the [false exp], you
just copy it over.”
Example: tracing cond M03 19/39

(define n 5) (define x 6) (define y 7) (define n 5) (define x 6)

(cond [(even? n) x][(odd? n) y]) (cond [(even? n) x][(odd? n) y])


⇒ (cond [(even? 5) x] [(odd? n) y]) ⇒ (cond [(even? 5) x] [(odd? n) y])
⇒ (cond [false x][(odd? n) y]) ⇒ (cond [false x][(odd? n) y])
⇒ (cond [(odd? n) y]) ⇒ (cond [(odd? n) y])
⇒ (cond [(odd? 5) y]) ⇒ (cond [(odd? 5) y])
⇒ (cond [true y]) ⇒ (cond [true y])
⇒ y ⇒ y
⇒ 7 ⇒ y: this variable is not defined

What happens if y is not defined? DrRacket’s rules differ. It scans the whole
cond expression before it starts, notes that
y is not defined, and shows an error. That’s
hard to explain with substitution rules!
Step through this program

(define (qux a b)
(cond
[(= a b) 42]
[(> a (+ 3 b)) (* a b)]
Ex. 7

[(> a b) (- b a)]
[else -42]))

(qux 5 4)

Verify your answer with the stepper in the commentary.


Simplifying conditional expressions M03 20/39

40 50 60

CS115 CS135 CS116 CS136


(check-expect
;; Constants for each CS course. (course-after-cs135 35) CS115)
(define CS115 1) (define CS116 2) (check-expect
(define CS135 3) (define CS136 4) (course-after-cs135 40) CS135)
(check-expect
;; (course-after-cs135 grade) produces the (course-after-cs135 45) CS135)
;; recommended course, depending on the (check-expect
;; CS135 grade. (course-after-cs135 50) CS116)
(define (course-after-cs135 grade) (check-expect
(cond (course-after-cs135 55) CS116)
[(< grade 40) CS115] (check-expect
[(and (>= grade 40) (< grade 50)) CS135] (course-after-cs135 60) CS136)
[(and (>= grade 50) (< grade 60)) CS116] (check-expect
[(>= grade 60) CS136])) (course-after-cs135 70) CS136)
Simplifying conditional expressions M03 21/39

40 50 60

CS115 CS135 CS116 CS136


(check-expect
;; Constants for each CS course. (course-after-cs135 35) CS115)
(define CS115 1) (define CS116 2) (check-expect
(define CS135 3) (define CS136 4) (course-after-cs135 40) CS135)
(check-expect
;; (course-after-cs135 grade) produces the (course-after-cs135 45) CS135)
;; recommended course, depending on the (check-expect
;; CS135 grade. (course-after-cs135 50) CS116)
(define (course-after-cs135 grade) (check-expect
(cond (course-after-cs135 55) CS116)
[(< grade 40) CS115] (check-expect
[(< grade 50) CS135] (course-after-cs135 60) CS136)
[(< grade 60) CS116] (check-expect
[else CS136])) (course-after-cs135 70) CS136)
Simplify the following conditional expression:

;; (flatten-me x) Say which interval x is in.

;; flatten-me: Nat -> Nat


Ex. 8

(define (flatten-me x)
(cond [(>= x 75) 4]
[(and (>= x 50) (< x 75)) 3]
[(and (>= x 25) (< x 50)) 2]
[(< x 25) 1]))
Nested Conditionals M03 22/39

A museum offers free admission for people


who arrive after 5 pm. Otherwise, the cost ;; (admission after5? age) ...
(define (admission after5? age)
of admission is based on a person’s age: (cond [after5? 0]
age 10 and under are charged $5 and [else
everyone else is charged $10. (cond [(<= age 10) 5]
[else 10])]))
A natural solution to this nests one
conditional expression inside another. We (check-expect (admission true 4) 0)
use one cond to pick off the free admission (check-expect (admission true 24) 0)
situation. For the paid situation, we have (check-expect (admission false 4) 5)
two conditions that are distinguished in the (check-expect (admission false 24) 10)
nested cond.
Flattening Nested Conditionals M03 23/39

Often “flat” conditionals are easier to read than “nested” conditionals.


That is, instead of having a cond with another cond inside, we can rework them so they are
multiple clauses of a single cond.
Here is an example:

; cond inside cond ; simplified


(define (admission after5? age) (define (admission after5? age)
(cond [after5? 0] ↔ (cond [after5? 0]
[else [(<= age 10) 5]
(cond [(<= age 10) 5] [else 10]))
[else 10])]))

[else (cond ... is considered amateurish code because it can always be easily flattened.
Testing conditional expressions M03 24/39

Write at least one test for each possible answer in the conditional expression.
That test should be simple and direct, aimed at testing that answer.
When the problem contains boundary conditions (like the cut-off between passing
and failing marks), they should be tested explicitly.
DrRacket highlights unused code.
> Intervals for testing M03 25/39

For the course-that-follows-CS135 example


40 50 60

CS115 CS135 CS116 CS136

(define (course-after-cs135 grade)


(cond
[(< grade 40) CS115]
[(< grade 50) CS135]
[(< grade 60) CS116]
[else CS136]))

there are four intervals and three boundary points, so seven tests are required (for example,
35, 40, 45 50, 55, 60, 70).
Write a function that consumes a Num, x, and produces
1 if 80 < x ≤ 100,
Ex. 9

-1 if 0 < x ≤ 80,
0 otherwise.
Write tests to verify the boundaries are where they should be.
> Testing and and or M03 26/39

Testing and and or expressions is similar. We need:


Consider one test case where dx is zero
;; Is the line considered "steep"?
(first argument to or is true; second is
(define (steep? dx dy) not evaluated)
(or (= dx 0) one test case where dx is nonzero and
(>= (/ dy dx) 1)))
dy /dx ≥ 1,
(first argument is false but second
argument is true)
one test case where dx is nonzero and
y /x < 1.
(both arguments are false)
A Taxing Exercise M03 27/39

In the land of Yendor, the currency is the


zorkmid, zm. 0
00
20, rate: 0.3

tax payable (zm)


Taxes are calculated as follows: 00 0
15,
For incomes of 45, 000 zm or less, 10% rate: 0.2
00 0
is paid as tax. 10,

For incomes of 90, 000 zm or less, taxes 00


5,0 rate: 0.1
are calculated on the first 45, 000 zm (as
0
above) plus 20% of each additional zm. 0 000 000 000 000 000 000
20, 40, 60, 80, 100, 120,
For incomes above 90, 000 zm, taxes are income (zm)
calculated on the first 90, 000 zm (as
above) plus 30% of each additional zm.
Write tax-payable. It consumes the income
and produces the taxes owed.
Ex. 10 Implement the function tax-payable. It consumes a number representing income and
produces the taxes to be paid on that income.
Include appropriate check-expects to test your function.
Define appropriate constants.

Examine your code for tax-payable. Are there opportunitites to improve it with a helper
Ex. 11

function? (Unless you used one the first time, the answer is probably "yes!". Look for
repeated code.)
Implement tax-payable using a helper function.
Symbolic data M03 28/39

Racket allows one to define and use symbols with meaning to us (not to Racket).
A symbol is defined using a leading apostrophe or ‘quote’: 'CS115. What follows is the same
as any other identifer.
'CS115 is a value just like 0 or 115, but it is more limited computationally.
Symbols allow a programmer to avoid using constants to represent names of courses,
colours, planets, or types of music.
Unlike numbers, symbols are self-documenting – you don’t need to define constants for
them. This is the primary reason we use them.
course-after-CS135 revisited M03 29/39

We can use symbols instead of the constants in our previous example.

;; No longer needed!!! (check-expect


;; (define CS115 1) (define CS116 2) (course-after-cs135 35) 'CS115)
;; (define CS135 3) (define CS136 4) (check-expect
(course-after-cs135 40) 'CS135)
;; (course-after-cs135 grade) produces (check-expect
... (course-after-cs135 45) 'CS135)
(define (course-after-cs135 grade) (check-expect
(cond (course-after-cs135 50) 'CS116)
[(< grade 40) 'CS115]
[(< grade 50) 'CS135]
[(< grade 60) 'CS116]
[else 'CS136]))
Symbolic data M03 30/39

Symbols can be compared using the predicate symbol=?.

(define home 'Earth)


(symbol=? home 'Mars) ⇒ false

symbol=? is the only function we’ll use in CS135 that is applied only to symbols.
Like other types, there is a predicate: symbol?.

(define mysymbol 'blue)


(symbol=? mysymbol 'blue) ⇒ true
(symbol=? mysymbol 'red) ⇒ false
(symbol=? mysymbol 42) ⇒ error
(symbol? mysymbol) ⇒ true
(symbol? '*@) ⇒ true
(symbol? 42) ⇒ false
Characters M03 31/39

A character is most commonly a printed letter, digit, or punctuation symbol. a, G, ., +, and


8 are all characters.
Other characters represent less visible things like a tab or a newline in text.
More recent characters include ⌣, , and 9.
For now, we’ll be interested in characters only because they are the simplest component of
a string. We’ll discuss the Racket representation of individual characters in a later module.
Strings M03 32/39

Strings are sequences of characters between double quotes. Examples: "blue" and
"These are not my shoes. My shoes are brown.".

What are the differences between strings and symbols?

Strings are really compound data


(a string is a sequence of characters).
Symbols can’t have certain characters in them
(such as spaces).
It is more efficient to compare two symbols than two strings.
There are more built-in functions for strings than symbols.
String predicates M03 33/39

Non-numeric types also have predicates. For example, these predicates consume strings
and will be useful when we do more work with strings.
We can tell if two strings are the same:

(string=? "pearls" "gems") ⇒ false


(string=? "pearls" "pearls") ⇒ true

We can also tell if a pair of strings are in alphabetic order. If one string comes before
another, it is “less than” it. If it comes after, it is “greater than”. Some examples:

(string<? "pearls" "swine") ⇒ true ; "pearls" before "swine".


(string<? "pearls" "pasta") ⇒ false ; the "e" should come after the "a".
(string>? "kneel" "zod") ⇒ false ; "kneel" before "zod".
(string<=? "pearls" "pearls") ⇒ true
(string<? "Pearls" "pearls") ⇒ true ; "P" before "p"
Functions on strings M03 34/39

Here are more functions which operate on strings:

(string-append "alpha" "bet") ⇒ "alphabet"


(string-length "perpetual") ⇒ 9
(string-upcase "Hello") ⇒ "HELLO"
(string-downcase "Hello") ⇒ "hello"
(substring "substring" 3 6) ⇒ "str"
Use string-append and substring to complete the function chop-word:

;; (chop-word s) selects some pieces of s.


;; Examples:
(check-expect (chop-word "In a hole in the ground there lived a hobbit.")
;; ^ ^ ^ ^ ^ ^ ^ ^ ^
;; index: 0 5 10 15 20 25 30 35 40
Ex. 12

"a hobbit lived in the ground")


(check-expect (chop-word "In a town by the forest there lived a rabbit.")
;; ^ ^ ^ ^ ^ ^ ^ ^ ^
;; index: 0 5 10 15 20 25 30 35 40
"a rabbit lived by the forest")
(check-expect (chop-word "ab c defg hi jkl mnopqr stuvw xyzAB C DEFGHIJ")
"C DEFGHI xyzAB hi jkl mnopqr")
Use the constants the-str and len-str, along with the string functions string-append,
string-length, and number->string to complete the function describe-string:

(define the-str "The string '")


(define len-str "' has length ")
Ex. 13

;; (describe-string s) says a few words about s.


;; Examples:
(check-expect (describe-string "foo") "The string 'foo' has length 3")
(check-expect (describe-string "") "The string '' has length 0")
Symbols vs. strings M03 35/39

Consider the use of symbols when a small, fixed number of labels are needed (e.g. planets)
that only need to be compared for equality.
Use strings when the set of values is more indeterminate (e.g. names of students), or when
more computation is needed (e.g. comparison in alphabetical order).
Type Predicates M03 36/39

Each built-in type has a predicate that consumes an Any, and produces true if the value is
of that type, and false otherwise.
For example:

(symbol? 4) ⇒ false
(symbol? 'asdf) ⇒ true
(number? "42") ⇒ false
(number? 42) ⇒ true
(integer? 3.14) ⇒ false
(integer? -3) ⇒ true
(boolean? true) ⇒ true
(boolean? false) ⇒ true
(boolean? "George Boole") ⇒ false
(string? 42) ⇒ false
Recap: Substitution rules (so far) M03 37/39

1 (f v1...vn) ⇒ v when f is built-in...


2 (f v1...vn) ⇒ exp' when (define (f x1...xn) exp) occurs to the left...
3 id ⇒ val when (define id val) occurs to the left.
4 (and false ...) ⇒ false
5 (and true ...) ⇒ (and ...) We will add to this semantic model as we
6 (and) ⇒ true introduce new Racket features.
7 (or true ...) ⇒ true Doing a step-by-step reduction with these
8 (or false ...) ⇒ (or ...) rules is called tracing a program. It is an
9 (or) ⇒ false important skill in any programming
10 (cond [false exp] ...) ⇒ (cond ...) language. We will test this skill on
assignments and exams.
11 (cond [true exp] ...) ⇒ exp
12 (cond [else exp]) ⇒ exp
Goals of this module M03 38/39

You should understand Boolean data, and be able to perform and combine
comparisons to test complex conditions on numbers.
You should understand the syntax and use of a conditional expression.
You should be aware of other types of data (symbols and strings), which will be used in
future lectures.
You should understand how to write tests with check-expect and use them in your
assignment submissions.
You should look for opportunities to use helper functions to structure your programs,
and gradually learn when and where they are appropriate.
You should be able to trace a program using the twelve substitution rules we’ve defined
so far.
Summary: built-in functions M03 39/39

The following functions and special forms have been introduced in this module:

< <= = > >= and boolean? check-error cond else even? integer? negative? not
number->string number? odd? or positive? string-append string-downcase
string-length string-lower-case? string-numeric? string-upcase
string-upper-case? string<=? string<? string=? string>=? string>? string?
substring symbol=? symbol? zero?

You should complete all exercises and assignments using only these and the functions and
special forms introduced in earlier modules. The complete list is:
* + - / < <= = > >= abs and boolean? ceiling check-error check-expect check-within cond
cos define e else even? exp expt floor integer? log max min modulo negative? not
number->string number? odd? or pi positive? quotient remainder round sgn sin sqr sqrt
string-append string-downcase string-length string-lower-case? string-numeric?
string-upcase string-upper-case? string<=? string<? string=? string>=? string>?
string? substring symbol=? symbol? tan zero?

You might also like