Lecture notes: Our first computer programs

Our first computer programs

For the first homework assignment, you’ll be creating images based on patterns found on snakes. In order to produce those images, you’ll write some short computer programs. In today’s class, we’ll learn how those programs are written.

Let’s take a look at a simple program that produces an image:

circle(50, "solid", "red")

There are a bunch of things going on here–let’s go through them slowly!

Numbers

Let’s open up our programming environment. For the first part of this class we’ll be using the Pyret programming language, which you’ll (mostly) access at https://code.pyret.org (often abbreviated to “CPO”).

CPO has two windows: definitions (left) and interactions (right). For now, we’ll work in the interactions window.

The > is called the “prompt” – that’s where we tell CPO to run a program. Let’s tell it to run 3+5.

> 3 + 5

From now on, whenever a line starts with the prompt character, I’m suggesting that you run it in the interactions window.

Not surprisingly, we can do other arithmetic computations:

> 2 * 6

(Note: * is the sign for multiplication)

What if we try:

> 3 + 4 * 5

Pyret isn’t sure whether we mean (3 + 4) * 5 or 3 + (4 * 5). So it asks us to include parentheses to make that explicit. Every programming language has a set of rules about how you have to write down programs. Pyret’s rules require parentheses to avoid ambiguity.

What if you want to get beyond basic arithmetic operators? Let’s say we want the minimum of two numbers. We can write this as:

> num-min(2, 8)

Why the num- prefix? It turns out that “minimum” is a concept that makes sense on data other than numbers; Pyret calls the min operator num-min to avoid ambiguity.

Note that when we run num-min, we get a number in return (as we did for +, *, …). This means we should be able to use the result of num-min in other computations where a number is expected:

> 5 * num-min(2, 8)
> (1 + 5) * num-min(2, 8)

Hopefully you are starting to see a pattern. We can build up more complicated programs from smaller ones, using operations to combine answers from the smaller programs.

Go to http://code.pyret.org and press “start coding”. Try to write the programs for each of the following computations:

  • subtract 3 from 7, then multiply the result by 4
  • subtract 3 from the multiplication of 7 and 4
  • the sum of 3 and 5, divided by 2
  • the max of 5, - 10, and -20
  • 2 divided by the sum of 3 and 5

What if you get a fraction as a response? (try it!) You can type fractions directly (as in 1/3), and you can toggle whether it displays as a fraction or decimal by clicking on the result in the interactions window.

How about

> 3 * 1/3

Pyret’s answer, 1, is what you might expect. A computer scientist might expect a different answer, though–something like 0.99999999. This is because many programming languages default to fast but inexact math. “We shape our tools and thereafter our tools shape us.”1

Look at an interaction like

> (3 + 4) * (5 + 1)

There are actually several kinds of information in this interaction, and we should give them names :

Expression
a computation that produces an answer (it may be part of another computation)
Value
a computation that can’t be computed further (it is its own answer)
Program
a sequence of computations that you want to run

Strings

Going back to our earlier example, what does "solid" mean? What about "red"?

Names, addresses, words, and other text-like data are represented as strings, which are enclosed in double-quotes. Some examples of strings:

  • "red"
  • "CSCI 0111"
  • "It was the best of times, it was the worst of times"

So strings can contain any kind of textual data, including numbers and punctuation. In this class session, and on the homework, you’ll use them for names of colors.

Images

OK, so now we can talk about what circle(50, "solid", "red") means. 50 is a number, and "solid" and "red" are strings. circle(50, "solid", "red") is an image.

Images are “optional,” in the sense that some programs use them but many do not (whereas most programs use numbers and strings). When we want to use a feature that isn’t common to most programs, we have to tell Pyret that we plan to use that feature (these are called “libraries”). For images, we do this by running the following line:

> include image

Here are some sample images:

> circle(50, "solid", "red")
> circle(30, "outline", "blue")
> rectangle(20, 10, "solid", "purple")

Naming Values and Using the Definitions Window

The expressions that create images involve a bit of typing. It would be nice to have shorthands so we can “name” images and refer to them by their names. This is what the definitions window is for: you can put expressions and programs in the definitions window, then use the “Run” button in CPO to make the definitions available in the interactions window.

Let’s put the following in the definitions window:

include image
red-circ = circle(30, "solid", "red")

Then hit “Run”, then enter red-circ in the interactions window. We see a red circle.

What happens if we put red-circ in the definitions window and hit the run button? The red circle is printed to the interactions window.

Here, we used the form

NAME = EXPRESSION

to tell Pyret to associate the value of EXPRESSION with NAME. With this definition in place, you can type NAME and Pyret will replace it with the value of EXPRESSION. For example

x = 5
> x + 4

The definitions window also lets you create files of code. Under the Pyret File menu, you’ll find the option to save a file. CPO will save the contents of your definitions window to the Google Drive account associated with how you logged into CPO.

Additional notes on using CPO are provided on the course website.

Building images

What are some operations we might want in order to combine images together? Let’s say we have

include image
red-circ = circle(50, "solid", "red")
blue-rec = rectangle(20, 10, "solid", "purple")

How can we combine these?

> beside(blue-rec, red-circ)
> above(blue-rec, red-circ)
> above(red-circ, blue-rec)
> overlay(blue-rec, red-circ)
> overlay-align("left", "top", blue-rec, red-circ)

How about this?

> above(red-circ, red-circ)

Note that all of these combinations are expressions. Expressions are built out of other expressions (and values)!

Baseball diamond exercise

Let’s say we want to create an image of a baseball diamond. How can we do that? What operations would we need? How would we break down the problem?

In class, we built up the field this way:

include image
field = rectangle(100, 100, "solid", "dark-green")
base = rectangle(20, 20, "solid", "white")

field-with-one-base = overlay-align("left", "top", base, field)
field-with-two-bases = overlay-align("left", "bottom", base, field-with-one-base)
field-with-three-bases = overlay-align("right", "top", base, field-with-two-bases)
field-with-four-bases = overlay-align("right", "bottom", base, field-with-three-bases)

rotate(45, field-with-four-bases)

We also saw how to simplify this into one expression:

include image
field = rectangle(100, 100, "solid", "dark-green")
base = rectangle(20, 20, "solid", "white")

rotate(45,
  overlay-align("right", "bottom", base,
    overlay-align("right", "top", base,
      overlay-align("left", "bottom", base,
        overlay-align("left", "top", base,
          field)))))

Footnotes:

1
John Culkin, summarizing the work of Marshall McLuhan