Lecture 5 Slides - Iteration and Iterators

1 of 51

Lecture 5

Iteration and Iterators

2 of 51

Logistics and Week Ahead

For some - Ethics Module 2 – Accessibility

  • Monday - Higher-Order Functions and Iterators! (Ex 2 Posted)
  • Wednesday - Lambda Abstraction (Pre-Recorded + MQ4) + Tutorial 2
  • Friday - Conditional Expressions (MQ 5) (Exercise 2 due)

Reminders:

  • A deadline is a deadline!
  • If you're missing class you should spend time to catch-up.
  • Take 10 seconds each week to check your grades in the course. edSTEM posts whenever grades go live. If you're expecting a participation grade and don't get it, fill out the petition form. Pre-Recorded MQs will time out! (all grades except Ex1 and Eth1 are posted as of 1pm - Ex1 will be posted by 5pm)

3 of 51

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.

4 of 51

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)

5 of 51

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!

6 of 51

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)))

7 of 51

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.

8 of 51

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))

9 of 51

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.

10 of 51

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!

11 of 51

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…

12 of 51

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.

13 of 51

Good software design is about structured laziness

14 of 51

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

15 of 51

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!

16 of 51

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

17 of 51

image iterators

18 of 51

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)

19 of 51

higher-order functions

20 of 51

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!

21 of 51

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

22 of 51

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

23 of 51

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")

24 of 51

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)))

25 of 51

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

26 of 51

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

27 of 51

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

28 of 51

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

29 of 51

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

30 of 51

iterated-overlay example

31 of 51

Example

> (iterated-overlay ;; number -> image

;; makes a square rotated by n degrees

(λ (n)

(rotate n

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

10)

>

32 of 51

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

33 of 51

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

34 of 51

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

35 of 51

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

36 of 51

Example

> (iterated-overlay (λ (n)

(rotate (* 36 n)

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

10)�

>

37 of 51

concentric�box example

38 of 51

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…

39 of 51

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)

40 of 51

Wait, why is that easier?

41 of 51

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...)

42 of 51

Changing the number of boxes

Rather than this…

(iterated-overlay

(λ (n)

(square (* (+ n 1)

50)

"solid"

(color 0

(- 250

(* n 50))

0)))

5)

43 of 51

We can do even better!

44 of 51

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

45 of 51

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

Okay, you’re probably right

but …

46 of 51

This is not easier to do by hand …

47 of 51

This is not easier to do by hand …

> (iterated-beside boxes 10)

48 of 51

on counting from zero

49 of 51

Annoying subtle point…

> (iterated-beside boxes 10)

Why are there only 9 sets of boxes?

50 of 51

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

51 of 51

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