September 23-25

September 23-25

(updated by Michelle)

Exam update: If you are stressed about exam scores, take a deep breath. When the scores come out over the weekend, we will also be releasing a points-back packet. This is optional, but if you complete this packet by the end of the October 6th lab and hand it into your TA, you will get points back on the exam. How many points will depend on overall exam results and the correctness of your answers.

Functions using return values

We talked more about defining functions and using the return statement to return a value to the function call expression.

For example, suppose you write an expression with a function call, e.g. 1 + f(), and inside the definition of function f there is a return statement: return 5;. In this case, the value of the return expression, 5, becomes the value of f(), so after the return statement, we “return” to the original expression and compute 1 + 5.

So you now know about several types of functions. All functions do some sort of work like drawing something for you, printing something for you, or calculating something for you. Sometimes functions takes input, either using parameters or global variables. And you can mix and match the structure of these functions to create an appropriate behavior to your program.

Something to think about: Functions probably aren’t all that new to you. You see functions in math all the time that basically takes an input and then returns an output. You even see them in our everyday lives. For example, the human body is basically a program that uses many functions to do work. Eating is basically the function of taking in food, extracting what we need, and returning energy (amongst other things…) So look at the bigger picture of why it is important we have functions and really use them to give your code a meaningful structure.

Arrays

Today we introduced arrays. Arrays are data structures that allow us to store multiple values of the same type. This goes hand-in-hand with iteration in for loops because you can traverse the array, get the value you need, and then do something with that value.

You should read about arrays in the textbook and w3schools readings, but here are some key things to remember:

  • You access the elements of the array by its index.
  • Arrays are zero-indexed so if you try to index into the array outside of the range 0 to the array length – 1, you will break everything. So watch your for loops carefully.
  • Arrays only take values of the same type, so don’t try to make one array store strings and numbers.

With that said, here is the code we went over in class.

We started with a simple program with a single moving rect:

sketch

We modified this program so that every number was replaced by an array of numbers and every computation on a set of variables was replaced by a for loop to do the computation on each element of each array.

Here’s the resulting program with 100 rects rather than 1 rect:

sketch

Here’s another use of arrays: A row of buttons where the “state” of the button is stored in an array of boolean (true/false) values. In this case if a button state is has the value true, then it should be red. Otherwise, is the value is false, then it should be green.

The code to click on buttons is crude and imprecise. It could be much better, but I kept in minimal in order to focus on the use of arrays.

A note about booleans: Booleans are types just like integers, floating points, and strings. They are not variables, but variables can be assigned the values of booleans. And just like numbers, booleans have their own operators. You’ve seen these before. Whenever you use &&, ||, or not, you are performing an operation on boolean values much like addition and subtraction work for number values. Actually every conditional expression that you write evaluates to a boolean. For example, the expression 100 != 0 would evaluate to true. In addition, the expression (100 != 0) && (100 % 2 == 1) would be false since 100 is not an odd number. This is a very important concept because booleans go hand in with conditionals. If you don’t understand this concept, please ask an instructor or TA soon!

sketch

A note about the break statement: In class we used something we haven’t used before. It’s called the break statement. It is extremely useful for loops because it immediately breaks out of a loop. You could put this in combination with an if statement so that, if a condition is met, you don’t need to continue with the rest of the for loop. In the case of our square button code from class, we used the break so that, once the right square is found, we don’t want to uselessly test the other squares, so we break out. This is a way to make your code more efficient.

Strings

You’ve strings vaguely used in print statements and in text that can appear on the canvas. You’ve also learned about concatenation and the toString() method to convert numbers into strings. Now we’ll introduce more string methods that can allow you to search for substrings, convert them to all caps or all lowercase, and etcetera. This is super important for formatting string values and parsing data the way you want them to. It is frequently used in handling data. For example, if you gat a huge list of the 104 students by “First Name, Last Name”, you can use the string methods to change them to “Last Name, First initial”, and etcetera.

Here are a few examples of string methods. In this example, str is just a generic variable that holds a string value. Try running this code in setup and seeing what the statements print out. I also recommend reading the w3schools page on string methods. Remember, just like arrays, strings are zero-indexed.

var str = "Hello, World!"

print (str.search("World"));
print (str.search("Pie"));
print (str.slice(1, 4));
print (str.substr(1, 4));
print (str.replace("Hello", "Goodbye"));
print (str.toUpperCase());

var arr = str.split(" ");
for (var i = 0; i < str.length; i++) {
    print (arr[i]);
}

September 14-16

September 14

We reviewed material that’s already discussed in the September 11 notes, including:

  • Counting. Generally, computer scientists and computer programs count from zero, so to count 3 things, count 0, 1, 2. To count N things, count 0, 1, … N-1. See Sept. 11 notes on counting and templates for for loops.
  • Using declarations in for loops: Write “for (var i = 0; i < n; i = i + 1) { ... }" rather than "for (i = 0; i < n; i = i + 1) { ... }". The use of "var" in the first form declares "i" to be a local variable, which is good programming practice.
  • Random squares: see code in Sept. 11 notes.
  • Iteration – we made some examples do draw lots of random rectangles to illustrate for loops.
  • we talked about clearing the screen. The background() function clears the screen. You can call it in setup(), in draw(), or even inside an if statement depending on what you want to accomplish, and we saw examples of each of these cases.

We went over order of evaluation of sketch.js programs:

  1. Compile the program, evaluating all global variable declarations and initializations.
  2. Define all the p5.js library functions and variables such as random() and PI.
  3. Call setup().
  4. Call draw() repeatedly.

The point here is that random() and PI and other p5.js functions are not available for global variable initializations. Rather than writing “var myVar = random(10);” at the top of your program, write “var myVar;” at the top, and in setup (where random() will be defined), write “myVar = random(10);”.

We looked at rotations. A good tutorial is this one, although it is for Java/Processing rather than JavaScript. The principles are the same. See your textbook too: Chapter 6.

September 16

We started with a review of rotation: Make a square rotate in the center of the screen. The tutorial mentioned above is very nice (this one, although it is for Java/Processing rather than JavaScript). Here’s the example we did in class:

Rotation/Translate Example

rotation sketch

This example is slightly changed from class:

  • The canvas size is smaller — how do you control the canvas size?
  • Why is the box still in the middle of the canvas even though the canvas size changed?
  • The angle variable was changed to gAngle.

Global Variables Names

In future examples, I will be using the notation “gSomething” to mean global variables. The reason is that p5js defines a lot of global variables such as top, width, height, and scrollX — it’s just dangerous to pick a name for your own variable and hope there will not be a conflict. the “gSomething” notation (in the case, gAngle) safely generates non-p5js names and helpfully reminds the reader that the variables are global. You can use any naming scheme you want, but avoid simple names like top to stay out of trouble.

Iteration Examples

Next, we reviewed some iteration examples. Let’s draw 10 boxes:
sketch

Notice in this example that we completely separate the task of counting (10) boxes (with loop variable i) and deciding where to draw them (with local variable x).

Do we really need the extra variable x to compute location? I don’t think so! Try this:

pixel coordinates computed from counting variable

Here, we’ve used a little math (multiply to scale up to 20-pixel spacing, add to shift boxes by 50 pixels) to translate the counting variable i into a screen coordinate (formerly the x variable). Fun fact: Some programming languages like C have “optimizers” that actually convert the first program example into the second automatically to make them run faster. (Or in the old days, when multiplication hardware did not exist, “*” was really slow, so optimizers could convert the second form to the first, eliminating the multiplication!)

But do we really need to do the math to convert i from counting numbers to pixels? Why not just work with pixels directly? Here’s how that solution looks:

for loop working directly with pixel coordinates

Notice here that we have to be very careful about the condition in the for loop. Quick, look at “for (var i = 50; i < 250; i = i + 20)" and tell me how many boxes will this code draw. But it's still a good example of the flexibility of for loops.

Nested For Loops

Next, we look at nested loops. Remember that whatever is inside the for loop brackets is repeated, even another loop that draws an entire row. Here, the “outer” or first loop draws rows, and the “inner” or second embedded loop draws each box within the row.

nested loops

Notice that each rect location depends on what row it is in and on the value of i, which can be understood as the column number. What makes row a row and i a column? Try switching parameters in rect, i.e. write rect(row * 30 + 25, i * 20 + 50, 10, 10).

Here’s another way to approach the problem. Rather than changing the code to draw rows at different coordinates, let’s leave the row code the way it was, and instead use translate() to shift each row further down the screen.

using translate

Notice here that the 2nd parameter to rect (the Y coordinate) is always the same (25), but the actual location on the canvas changes for each row due to the translate() call.

Sine = Sin, Cosine = Cos, Radius, and Angle

Next, we talked about expressing locations in terms of angles and radius rather than X and Y.

Introducing Sin and Cos

Cos and Sin functions tell you X and Y coordinates of a point on a circle of radius 1. The input parameter for Cos and Sin is the angle: How far to rotate around the circle. The output is where you land in terms of X (cos) and Y (sin):

ucdefp
(From “The Amazing Unit Circle”)

Here’s a graph showing how the functions sin() and cos() translate angle (here represented by the x coordinate) into a value shown as displacement in the Y axis.

sketch

Rotating

Perhaps more interestingly, we can now write a program that creates circular motion by translating radius and angle into X and Y. You should understand how the following program works and why the circle moves in a circle. How would you make it go faster? How would you make the circle bigger? How would you make circle orbit bigger? What happens if the radius is zero?

sketch

Spiral

Finally, change the previous example as follows:

  • Start the radius at 1, but increase the radius for each frame.
  • Move the background() call to setup() so it does not erase every frame.
  • Remove the line, just draw the circle.
  • For this web page version, call background and reset radius after a bunch of draw
    calls.

Summary

Now you know:

  • How to use translate/rotate to rotate objects (or whole drawings)
  • How to write nested for loops and draw grids and 2-D arrays.
  • How to use cos/sin to convert from angle and radius to X and Y