Lecture 4 Slides - Lecture Slides

1 of 50

Iteration and Iterators

Iteration and Iterators

2 of 50

Project Bullseye.

Write a function that takes as input a bullseye radius, and makes a 4-circle bullseye where the largest circle is that radius and the colors alternate between blue and green.

3 of 50

Project Bullseye.

;; bullseye: number -> image

;; creates a bullseye shape with the outermost circle the specified size

We'd call your function like this:

(bullseye 100)

4 of 50

Note on color objects

(make-color r g b)

(make-color r g b a)

(color r g b)

You can also specify a color using a color object:

  • Specifies the amount of red, green, and blue light in the color, on a 0-255 scale
  • Note: when Racket prints a color object, it prints it in a text format, not as the color itself. To test a color, you must draw with it!

5 of 50

What’s wrong with this?

(overlay (square 50 "solid" (color 0 250 0))

(square 100 "solid" (color 0 200 0))

(square 150 "solid" (color 0 150 0))

(square 200 "solid" (color 0 100 0))

(square 250 "solid" (color 0 50 0)))

6 of 50

What’s wrong with this?

(overlay (square 50 "solid" (color 0 250 0))

(square 100 "solid" (color 0 200 0))

(square 150 "solid" (color 0 150 0))

(square 200 "solid" (color 0 100 0))

(square 250 "solid" (color 0 50 0)))

It’s (almost) the same code

repeated over and over again!

It's an expression.

7 of 50

What’s wrong with this?

;; box: number -> image

;; makes a size x size square

(define box

(λ (size)

(square size

"solid"

(color 0

(- 300 size)

0))))

; actually make the shape

(overlay (box 50)

(box 100)

(box 150)

(box 200)

(box 250))

8 of 50

What’s wrong with this?

;; box: number -> image

;; makes a size x size square

(define box

(λ (size)

(square size

"solid"

(color 0

(- 300 size)

0))))

; actually make the shape

(overlay (box 50)

(box 100)

(box 150)

(box 200)

(box 250))

This has saved us some work, but doesn't save us that much trouble.

9 of 50

What’s wrong with this?

;; box: number -> image

;; makes a size x size square

(define box

(λ (size)

(square size

"solid"

(color 0

(- 260 size)

0))))

; draw the shape

(overlay (box 10) (box 20) (box 30) (box 40)

(box 50) (box 60) (box 70) (box 80) (box 90)

(box 100) (box 110) (box 120) (box 130) (box 140)

(box 150) (box 160) (box 170) (box 180) (box 190)

(box 200) (box 210) (box 220) (box 230) (box 240)

(box 250))

It does scale better to more boxes though!

10 of 50

What’s wrong with this?

;; box: number -> image

;; makes a size x size square

(define box

(λ (size)

(square size

"solid"

(color 0

(- 260 size)

0))))

; draw the shape

; what do we put here?

Imagine explaining how to make this shape to a human…

11 of 50

What’s wrong with this?

;; box: number -> image

;; makes a size x size square

(define box

(λ (size)

(square size

"solid"

(color 0

(- 260 size)

0))))

; draw the shape

; what do we put here?

Imagine explaining how to make this shape to a human…

Place 25 boxes on top of each other, each one bigger than the last with a slightly different color.

12 of 50

Good software design is about structured laziness

13 of 50

Iteration

  • Means doing something repeatedly
  • Examples:
    • Multiplication can be broken down into repeated addition
    • Addition can be broken down into repeated addition of single digits
    • Showing a video can be broken down into showing each frame of the video

14 of 50

Iterators

  • For the moment, we’ll do iteration by calling functions that iterate for us
    • That is, that will do things repeatedly for us
    • Primitive iterators that can be combined to make more complex ones

  • But how will they know what to do repeatedly?
    • They’ll take the thing to repeat as input

  • What kind of input?
    • A function!

15 of 50

Theme and variation

  • When you iterate, you generally don’t do exactly the same thing each time
    • The digits you add, or the frame you display, change from iteration to iteration

  • So we parameterize the function to be repeated by whatever should change from iteration to iteration

16 of 50

image iterators

17 of 50

Goal: Turn the Left side into the RIght Side

(overlay (box 50)

(box 100)

(box 150)

(box 200)

(box 250))

(some-iterator (λ (some-name)

(box some-argument))

5)

18 of 50

higher-order functions

19 of 50

Higher Order Functions

  • This is an important concept of functional programming.
  • It means that functions can:
    • Accept other functions as inputs
    • Create other functions as output
    • Or both!
  • There are some examples of these in the lecture slides posted…but today we're going to actually write and use some higher-level functions!

20 of 50

Functions can return other functions

;; add: number -> (number -> number)�;; Make a function called add that �;; adds x to its input

(define add (λ (x) � (λ (y)� (+ x y))))

Note: the return type is a function that takes a number as input and returns a number, so its type, (number -> number) has its own ->

(add 2)

> ((λ (x) (λ (y) (+ x y))) 2)

is the same thing as…

(λ (y) (+ 2 y))

is the same thing as…

A function that adds 2 to its argument

21 of 50

Functions can return other functions

;; add: number -> (number -> number)�;; Make a function called add that �;; adds x to its input

(define add (λ (x) � (λ (y)� (+ x y))))

Note: the return type is a function that takes a number as input and returns a number, so its type, (number -> number) has its own ->

((add 2) 4)

(((λ (x) (λ (y) (+ x y))) 2) 4)

((λ (y) (+ 2 y)) 4)

(+ 2 4)

6

22 of 50

Functions can be arguments

;; squarish: picture-func -> image�;; where picture-func is�;; number number string color�;; -> image�;; Makes a square picture using �;; procedure

(define squarish(λ (func)� (func 10

10 � "outline" � "white")))

(squarish rectangle)

((λ (func)� (func 10 10 "outline" "white")) � rectangle)

(rectangle 10 10 "outline" "white")

—---------------------------------

(squarish ellipse)

((λ (func)� (func 10 10 "outline" "white")) � ellipse)

(ellipse 10 10 "outline" "white")

23 of 50

Or both

(define f (my-compose squared sin))

(define f ((λ (f1 f2) � (λ (arg) � (f1 (f2 arg))))� squared� sin))

(define f ((λ (f1 f2) � (λ (arg) � (f1 (f2 arg))))(λ (n) (* n n))� sin))

(define f (λ (arg)� ((λ (n) (* n n))� (sin arg))))

;; my-compose: (number -> number)�;; (number -> number)�;; -> (number -> number)�;; Makes a function that runs both its�;; input function

(define my-compose (λ (f1 f2)� (λ (arg)� (f1 (f2 arg)))))

;; squared: number -> number�;; Compute the square of a number

(define squared(λ (n)� (* n n)))

24 of 50

Or both

;; my-compose: (number -> number)�;; (number -> number)�;; -> (number -> number)�;; Makes a function that runs both its�;; input function

(define my-compose (λ (f1 f2)� (λ (arg)� (f1 (f2 arg)))))

;; squared: number -> number�;; Compute the square of a number

(define squared(λ (n)� (* n n)))

(f 0)

= ((λ (arg)

((λ (n) (* n n))(sin arg)))

0)

= ((λ (n) (* n n))

(sin 0))

= ((λ (n) (* n n))

0)

= (* 0 0)

= 0

25 of 50

The iterated-overlay function

;; iterated-overlay: (number -> image) number -> image

;; Makes a series of pictures using function, then overlays them.

(iterated-overlay picture-making-function count)

  • Calls picture-making-function repeatedly with the input of the current value of our counter!
  • Calls it count times, with inputs starting at 0 and going up to count - 1
  • Overlays/underlays/aboves/besides all the pictures

26 of 50

The iterated-overlay function & friends

;; iterated-overlay: (number -> image) number -> image

;; Makes a series of pictures using function, then overlays them.

(iterated-overlay picture-making-function count)

(iterated-underlay picture-making-function count)

(iterated-above picture-making-function count)

(iterated-beside picture-making-function count)

  • Calls picture-making-function repeatedly with the input of the current value of our counter!
  • Calls it count times, with inputs starting at 0 and going up to count - 1
  • Overlays/underlays/aboves/besides all the pictures

27 of 50

These functions aren’t built in

(require "iterated-images.rkt")

  • These aren’t built-in functions, you HAVE to run this require either in your Definitions File (and then hit RUN) or in your REPL (hit enter)
  • They’re easy to define, but you we don't have the tools to make them ourselves yet
    • So we’re giving you a file that defines them
    • Called iterated-images.rkt
    • We’ll include it in any assignments we give you that involve it
    • It's also linked on Today's lecture page on Canvas (click the purple button)
  • When you want to use them
    • Put your RKT file in the same directory as iterated-images.rkt
    • Add a require at the top of your file

28 of 50

Semantics

(iterated-overlay func 4)

(overlay (func 0)

(func 1)

(func 2)

(func 3))

  • These two things are essentially equivalent.
  • Important note: software tends to count:
    • 0, 1, 2, 3
    • not 1, 2, 3, 4

29 of 50

iterated-overlay example

30 of 50

Example

> (iterated-overlay ;; number -> image

;; makes a square rotated by n degrees

(λ (n)

(rotate n

(square 100 "outline" "blue")))

10)

>

31 of 50

How to read this program

> (iterated-overlay ;; number -> image

;; makes a square rotated by n degrees

(λ (n)

(rotate n

(square 100 "outline" "blue")))

10)

  • Make a group picture

32 of 50

How to read this program

> (iterated-overlay ;; number -> image

;; makes a square rotated by n degrees

(λ (n)

(rotate n

(square 100 "outline" "blue")))

10)

  • Make a group picture
  • Of 10 pictures, numbered 0 through 9

33 of 50

How to read this program

> (iterated-overlay ;; number -> image

;; makes a square rotated by n degrees

(λ (n)

(rotate n

(square 100 "outline" "blue")))

10)

  • Make a group picture
  • Of 10 pictures, numbered 0 through 9
  • Call my picture-making-function with the number of the picture n

34 of 50

How to read this program

> (iterated-overlay ;; number -> image

;; makes a square rotated by n degrees

(λ (n)

(rotate n

(square 100 "outline" "blue")))

10)

  • Make a group picture
  • Of 10 pictures, numbered 0 through 9
  • Call my picture-making-function with the number of the picture n
  • Actually draw the picture by rotating a square by n degrees

35 of 50

Example

> (iterated-overlay (λ (n)

(rotate (* 36 n)

(square 100 "outline" "blue")))

10)�

>

36 of 50

concentric�box example

37 of 50

Our original example - now with iteration!

(overlay (square 50 "solid" (color 0 250 0))

(square 100 "solid" (color 0 200 0))

(square 150 "solid" (color 0 150 0))

(square 200 "solid" (color 0 100 0))

(square 250 "solid" (color 0 50 0)))

Has evolved into…

38 of 50

Our original example - now with iteration!

(iterated-overlay

;; number -> image

;; make a square rotated and colored

;; based on n

(λ (n)

(square (* (+ n 1)

50)

"solid"

(color 0

(- 250

(* n 50))

0)))

5)

39 of 50

Wait, why is that easier?

40 of 50

Changing the number of boxes

(overlay (square 50 "solid" (color 0 250 0))

(square 100 "solid" (color 0 200 0))

(square 150 "solid" (color 0 150 0))

(square 200 "solid" (color 0 100 0))

(square 250 "solid" (color 0 50 0))

...type more here...)

41 of 50

Changing the number of boxes

Rather than this…

(iterated-overlay

(λ (n)

(square (* (+ n 1)

50)

"solid"

(color 0

(- 250

(* n 50))

0)))

5)

42 of 50

We can do even better!

43 of 50

Making a function out of it

;; boxes: number -> image

;; Makes an image with a specified number of boxes

(define boxes

(λ (count)

(iterated-overlay

;; number -> image

;; make a box sized and colored based on n.

(λ (n)

(square (* (+ n 1)

(quotient 250 count))

"solid"

(color 0

(- 250

(* n

(quotient 250

count)))

0)))

count)))

Note: quotient divides two integers and rounds down

44 of 50

I still think it’s easier to do it by hand!

Okay, you’re probably right

but …

45 of 50

This is not easier to do by hand …

46 of 50

This is not easier to do by hand …

> (iterated-beside boxes 10)

47 of 50

on counting from zero

48 of 50

Annoying subtle point…

> (iterated-beside boxes 10)

Why are there only 9 sets of boxes?

49 of 50

Computers count from zero

> (beside (boxes 0) (boxes 1) (boxes 2) (boxes 3)

(boxes 4) (boxes 5) (boxes 6) (boxes 7)

(boxes 8) (boxes 9))

So the first call produces zero boxes, i.e. nothing

50 of 50

Computers count from zero

> (beside (boxes 0) (boxes 1) (boxes 2) (boxes 3)

(boxes 4) (boxes 5) (boxes 6) (boxes 7)

(boxes 8) (boxes 9))

This is actually useful much of the time