Copyright (c) 2017 Kathi Fisler
This material goes with basic data and expressions, sections 2.1-2.4 and 2.7 from the textbook
A Note on these Notes: These notes give you the general outline of the examples and activities that we did in class sessions. They are not meant to substitute for the textbook, which gives more examples and more details. These notes are not a full transcript of all the points made in class (much of that detail is in the textbook). Each set of notes (or sometimes individual section) will have a link to the corresponding textbook chapter or sections.
The notes use colored highlighting for different content. Hands-on activities are in pale yellow, answers to (some of) those exercises are in light blue, tips on programming are in green, and core ideas about computer science are in pink.
A program (or script) instructs a computer to do something. Usually, that something is a computation that the computer should perform.
Start simple: compute the sum of 3 and 5.
To ask the computer to do this computation, we need to use a programming language and programming environment: we write our computation in the language, and we run the program in the environment. For the first part of this course, we are using a language called Pyret in an environment called code.pyret.org (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
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. I write this as
> num-min(2, 8)
Why num-? 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.
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 may be part of another computation)
Value: a computation that can’t be computed further
Program: the entire expression that you want to run
What if we wanted to write a program that used data other than numbers, such as someone’s name? For names and other text-like data, we use what are called strings. Here are some examples:
What do we notice? Strings can be used for any kind of textual data. They can contain spaces, punctuation, and numbers.
When you encounter a new kind of data, you need to know what operations you can perform on the data. On numbers, the operations were things like +, *, and num-min. What might we want to do with strings?
Find out how many characters they have: string-length("Kathi")
Put them together (also know as "concatenation"): "hi" + "kathi". Note you have to include the spaces if you want them.
- See whether two strings are the same:
"kathi" == "kathi"
"kathi" == "CS 50"
"kathi" == "Kathi"
Note that strings are case-sensitive, meaning that capitalization is considered when checking whether strings are equal.
Note that + appears to be an operation on both numbers and strings. That might look weird at first. What’s really going on is that Pyret is using the same notation for different behaviors, depending on the kind of data you have. When the arguments (also called operands or inputs) are numbers, the notation + means "add". When the inputs are strings, the notation + means "concatenate" or "append". The notation is the same, but the underlying behavior is different.
(If you are wondering what happens when you use + on one number and one string, just try it in the interactions window.)
Programming Tip: You can answer many questions such as this for yourself by just trying it out in the interactions window. Don’t shy away from doing this – you can’t break anything, and you’ll learn more in the process.
Programming Tip: Every programming language decides (a) what kinds of data to support, (b) what operations/behaviors to support on each kind of data, and (c) what notation to use to let the programmer request an operation. Decision (c) is called syntax. Decision (b) is called semantics. For now, we’re focusing on syntax.
We now have two kinds of data: numbers and strings. Have you seen other kinds of data in the applications that you use?
Sure, you’ve seen file (attachments), audio samples, and pictures. Are those just numbers or strings? No. Clearly there are other kinds of data. Let’s look next at images.
Images are "optional", in the sense that some programs use them but many do not. 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:
Here are some sample images:
circle(30, "solid", "red")
circle(30, "outline", "blue")
rectangle(20, 10, "solid", "purple")
What operations might you want to do on images?
put two of them side by side
change all the red parts to yellow
Many of these are supported in Pyret (the "swap colors" isn’t simple, but the rest are built-in).
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.
Put the following in the definitions window:
red-circ = circle(30, "solid", "red")
Hit run, then enter red-circ in the interactions window. You should see the red circle.
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. If you put a title in the white box at the upper left and hit save, Pyret will save the contents of your definitions window to the Google Drive account associated with how you logged into CPO.
Important note on saving files: Pyret saves your file when you press the save button or when you run the program after having saved the file at least once. When a Pyret session/browser window has been idle for a while, the session becomes inactive and you lose the ability to save the file until you reload the page. This means you should follow two guidelines:
Save often, especially when you plan to be away from your machine for more than a few minutes.
When you come back to your machine after more than a few minutes, reload the webpage before you start editing again (or try to save to make sure your connection is still active). Otherwise, changes you make to the file will get lost when you do try to save.
You will also notice that Pyret has options for both "saving" and "publishing" files. Saving stores a copy of your file in the Google Drive associated with your login account. Publishing lets you share the code file with others (like getting a share link in Google docs, if that’s familiar to you). If you share a file, others can view the file, or make a personal copy, but they can’t edit your copy of the file.
Part of the fun of images is combining them to create more complex images. Here’s an example (run the code to see what you get):
circle(15, "solid", "blue")
overlay(circle(15, "solid", "blue"),
circle(30, "outline", "black"))
overlay-xy(circle(15, "solid", "blue"),
circle(30, "outline", "black"))
eye = overlay-xy(circle(15, "solid", "blue"),
circle(30, "outline", "black"))
a blue triangle (you pick the size)
a blue triangle inside a yellow rectangle
a bullseye with 3 nested circles aligned in their centers (the Target logo)
a triangle oriented at an angle
whatever you want —
play around and have fun!
Key idea in CS: As you build up more complex images from simpler ones, you are following a core idea called composition. Programs are always built of smaller programs that do parts of the larger task you want to perform. We’ll often see composition in action in this course.