0% found this document useful (0 votes)
3 views179 pages

Joyofcoding Sampler

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views179 pages

Joyofcoding Sampler

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

No Starch Press

t h e f i n e s t i n g e e k e n t e rta i n m e n t
Featuring Excerpts from

ar d ui n o p roj ec t handbook ............................... 1


m a r k g e d d e s ● 9 78-1 -5 9 3 2 7-69 0-4 ● 6/ 16 ● 2 7 2 pag e s ● F u l l Co lo r ● $24.95

T h e BOo k o f R . . . . . ........................................................ 13
T i l m a n M . Dav i e s ● 9 78-1 -5 9 3 2 7-6 51-5 ● 7/ 16 ● 832 pag e s ● $49.95

C o d i n g i P h o n e Apps for Ki ds............................ 37


G lo r i a Wi nqui s t et al. ● 978-1-59327-756-7 ● 11/16 ● 320 page s ● Ful l color ● $34.95

T h e C S D e t ec t i ve ...................................................... 65
J e r e m y Ku b i ca ● 9 78-1 -5 9 3 2 7-74 9 - 9 ● 8/ 16 ● 256 pag e s ● $17.95

E lect ro n i c s fo r Ki ds............................................. 75
Øy v i n d N y da l Da h l ● 9 78-1 -5 9 3 2 7-7 25-3 ● 7/ 16 ● 328 pag e s ● F u l l co lo r ● $24.95

T h e Man g a G u i d e to
R eg r e ssi o n Analysi s . . ........................................... 101
S h i n Ta k a h as h i e t a l . ● 9 78-1 -5 9 32 7-7 28-4 ● 5/ 16 ● 232 pag e s ● $24.95

Un d e r stan d i n g ECMAS c ri pt 6 ......................... 12 7


N i c h o l as C . Z a k as ● 9 78-1 -5 9 3 2 7-757-4 ● 8/ 16 ● 352 pag e s ● $34.95

W ic k e d C o o l S h ell S cri pts,


2 n d E d i t i o n .. . . . . . . . . . ...................................................... 145
Dav e Tay lo r e t a l . ● 9 78-1 -5 9 3 2 7- 602-7 ● 9/ 16 ● 368 pag e s ● $29.95
Arduino Project Handbook, © 2016 by Mark Geddes

Project 8:
Memory Game
In this project we’ll create
ou r own version of an
Atari arcade memory game
called Touch Me, using four
LEDs, fou r pushbutton
switch es, a pi ezo buzzer,
an d some resistors an d
j umper wires.
Arduino Project Handbook, © 2016 by Mark Geddes

Pa r t s R e q u i r e d Libraries
• Arduino board
Required
• Breadboard • Tone
• Jumper wires
• Piezo buzzer
• 4 momentary tactile four-pin
pushbuttons
• 4 LEDs
• 4 220-ohm resistors
Arduino Project Handbook, © 2016 by Mark Geddes

How It Works
The original Atari game had four colored panels, each with an LED
that lit up in a particular pattern that players had to repeat back (see
Figure 8-1).

Figure 8-1:
The original
Touch Me game

This memory game plays a short introductory tune and flashes


an LED. When you press the correct corresponding button, the lights
flash again in a longer sequence. Each time you repeat the sequence
back correctly, the game adds an extra step to make the sequence
more challenging for you. When you make an error, the game resets
itself.

Th e B u i l d
1. Place the pushbuttons in the breadboard so they straddle the
center break with pins A and B on one side of the break, and C
and D on the other, as shown in Figure 8-2. (See Project 1 for
more information on how the pushbutton works.)

A B
Figure 8-2:
A pushbutton has four pins.

D C

2. Connect pin B of each pushbutton to the GND rail of your bread-


board, and connect the rail to Arduino GND.
3. Connect pin D of each pushbutton to Arduino’s digital pins 2
through 5 in order.
Arduino Project Handbook, © 2016 by Mark Geddes

4. Insert the LEDs into the breadboard with the shorter, negative
legs connected to pin C of each pushbutton. Insert the positive
leg into the hole on the right, as shown in the circuit diagram in
Figure 12-3.

P u s h b ut to n a r d u i n o/ LED

Pin B GND
Pin C LED negative legs
Pin D Arduino pins 2–5

5. Place a 220-ohm resistor into the breadboard with one wire con-
nected to the positive leg of each LED. Connect the other wire of
the resistor to the Arduino as follows.

a r d u i n o/
LED s P u s h b ut to n

Arduino pins 8–11


Positive legs
via 220-ohm resistors
Negative legs Pushbutton pin C

Make sure the red LED connected to pin 11 is paired with


the pushbutton connected to pin 5, the yellow LED connected
to pin 10 is paired with the pushbutton connected to pin 4, the
green LED connected to pin 9 is paired with the pushbutton con-
nected to pin 3, and the blue LED connected to pin 8 is paired
with the pushbutton connected to pin 2.
6. Connect the black wire of the piezo directly to Arduino GND, and
the red wire to Arduino pin 12.

P i e zo arduino

Red wire Pin 12


Black wire GND

7. Check your setup against Figure 8-3, and then upload the code
in “The Sketch” on page 7.
Arduino Project Handbook, © 2016 by Mark Geddes

Figure 8-3:
Circuit diagram for
the memory game

Th e S k e tc h
The sketch generates a random sequence in which the LEDs will
light; a random value generated for y in the pattern loop determines
which LED is lit (e.g., if y is 2, the LED connected to pin 2 will light).
You have to follow and repeat back the pattern to advance to the
next level.
In each level, the previous lights are repeated and one more
randomly generated light is added to the pattern. Each light is associ-
ated with a different tone from the piezo, so you get a different tune
each time, too. When you get a sequence wrong, the sketch restarts
with a different random sequence. For the sketch to compile cor-
rectly, you will need to install the Tone library (available from http://
[Link]/arduinohandbook/). See “Libraries” on page 7
for details.
Arduino Project Handbook, © 2016 by Mark Geddes

// Used with kind permission from Abdullah Alhazmy [Link]

#include <Tone.h>
Tone speakerpin;
int starttune[] = {NOTE_C4, NOTE_F4, NOTE_C4, NOTE_F4, NOTE_C4,
NOTE_F4, NOTE_C4, NOTE_F4, NOTE_G4, NOTE_F4,
NOTE_E4, NOTE_F4, NOTE_G4};
int duration2[] = {100, 200, 100, 200, 100, 400, 100, 100, 100, 100,
200, 100, 500};
int note[] = {NOTE_C4, NOTE_C4, NOTE_G4, NOTE_C5, NOTE_G4, NOTE_C5};
int duration[] = {100, 100, 100, 300, 100, 300};
boolean button[] = {2, 3, 4, 5}; // Pins connected to
// pushbutton inputs
boolean ledpin[] = {8, 9, 10, 11}; // Pins connected to LEDs
int turn = 0; // Turn counter
int buttonstate = 0; // Check pushbutton state
int randomArray[100]; // Array that can store up to 100 inputs
int inputArray[100];

void setup() {
[Link](9600);
[Link](12); // Pin connected to piezo buzzer
for (int x = 0; x < 4; x++) {
pinMode(ledpin[x], OUTPUT); // Set LED pins as output
}
for (int x = 0; x < 4; x++) {
pinMode(button[x], INPUT); // Set pushbutton pins as inputs
digitalWrite(button[x], HIGH); // Enable internal pullup;
// pushbuttons start in high
// position; logic reversed
}
// Generate "more randomness" with randomArray for the output
// function so pattern is different each time
randomSeed(analogRead(0));
for (int thisNote = 0; thisNote < 13; thisNote ++) {
[Link](starttune[thisNote]); // Play the next note
if (thisNote == 0 || thisNote == 2 || thisNote == 4 ||
thisNote == 6) { // Hold the note
digitalWrite(ledpin[0], HIGH);
}
if (thisNote == 1 || thisNote == 3 || thisNote == 5 ||
thisNote == 7 || thisNote == 9 || thisNote == 11) {
digitalWrite(ledpin[1], HIGH);
}
if (thisNote == 8 || thisNote == 12) {
digitalWrite(ledpin[2], HIGH);
}
if (thisNote == 10) {
digitalWrite(ledpin[3], HIGH);
}
delay(duration2[thisNote]);
[Link](); // Stop for the next note
digitalWrite(ledpin[0], LOW);
Arduino Project Handbook, © 2016 by Mark Geddes

digitalWrite(ledpin[1], LOW);
digitalWrite(ledpin[2], LOW);
digitalWrite(ledpin[3], LOW);
delay(25);
}
delay(1000);
}

void loop() {
// Generate the array to be matched by the player
for (int y = 0; y <= 99; y++) {
digitalWrite(ledpin[0], HIGH);
digitalWrite(ledpin[1], HIGH);
digitalWrite(ledpin[2], HIGH);
digitalWrite(ledpin[3], HIGH);
// Play the next note
for (int thisNote = 0; thisNote < 6; thisNote ++) {
[Link](note[thisNote]); // Hold the note
delay(duration[thisNote]); // Stop for the next note
[Link]();
delay(25);
}
digitalWrite(ledpin[0], LOW);
digitalWrite(ledpin[1], LOW);
digitalWrite(ledpin[2], LOW);
digitalWrite(ledpin[3], LOW);
delay(1000);
// Limited by the turn variable
for (int y = turn; y <= turn; y++) {
[Link]("");
[Link]("Turn: ");
[Link](y);
[Link]("");
randomArray[y] = random(1, 5); // Assign a random number (1-4)
// Light LEDs in random order
for (int x = 0; x <= turn; x++) {
[Link](randomArray[x]);
for (int y = 0; y < 4; y++) {
if (randomArray[x] == 1 && ledpin[y] == 8) {
digitalWrite(ledpin[y], HIGH);
[Link](NOTE_G3, 100);
delay(400);
digitalWrite(ledpin[y], LOW);
delay(100);
}
if (randomArray[x] == 2 && ledpin[y] == 9) {
digitalWrite(ledpin[y], HIGH);
[Link](NOTE_A3, 100);
delay(400);
digitalWrite(ledpin[y], LOW);
delay(100);
}
if (randomArray[x] == 3 && ledpin[y] == 10) {
digitalWrite(ledpin[y], HIGH);
Arduino Project Handbook, © 2016 by Mark Geddes

[Link](NOTE_B3, 100);
delay(400);
digitalWrite(ledpin[y], LOW);
delay(100);
}
if (randomArray[x] == 4 && ledpin[y] == 11) {
digitalWrite(ledpin[y], HIGH);
[Link](NOTE_C4, 100);
delay(400);
digitalWrite(ledpin[y], LOW);
delay(100);
}
}
}
}
input();
}
}

// Check whether input matches the pattern


void input() {
for (int x = 0; x <= turn;) {
for (int y = 0; y < 4; y++) {
buttonstate = digitalRead(button[y]); // Check for button push
if (buttonstate == LOW && button[y] == 2) {
digitalWrite(ledpin[0], HIGH);
[Link](NOTE_G3, 100);
delay(200);
digitalWrite(ledpin[0], LOW);
inputArray[x] = 1;
delay(250);
[Link](" ");
[Link](1);
// Check if value of user input matches the generated array
if (inputArray[x] != randomArray[x]) {
fail(); // If not, fail function is called
}
x++;
}
if (buttonstate == LOW && button[y] == 3) {
digitalWrite(ledpin[1], HIGH);
[Link](NOTE_A3, 100);
delay(200);
digitalWrite(ledpin[1], LOW);
inputArray[x] = 2;
delay(250);
[Link](" ");
[Link](2);
if (inputArray[x] != randomArray[x]) {
fail();
}
x++;
}
if (buttonstate == LOW && button[y] == 4) {
Arduino Project Handbook, © 2016 by Mark Geddes

digitalWrite(ledpin[2], HIGH);
[Link](NOTE_B3, 100);
delay(200);
digitalWrite(ledpin[2], LOW);
inputArray[x] = 3;
delay(250);
[Link](" ");
[Link](3);
if (inputArray[x] != randomArray[x]) {
fail();
}
x++;
}
if (buttonstate == LOW && button[y] == 5) {
digitalWrite(ledpin[3], HIGH);
[Link](NOTE_C4, 100);
delay(200);
digitalWrite(ledpin[3], LOW);
inputArray[x] = 4;
delay(250);
[Link](" ");
[Link](4);
if (inputArray[x] != randomArray[x]) {
fail();
}
x++;
}
}
}
delay(500);
turn++; // Increment turn count
}

// Function used if player fails to match the sequence


void fail() {
for (int y = 0; y <= 2; y++) { // Flash lights to indicate failure
digitalWrite(ledpin[0], HIGH);
digitalWrite(ledpin[1], HIGH);
digitalWrite(ledpin[2], HIGH);
digitalWrite(ledpin[3], HIGH);
[Link](NOTE_G3, 300);
delay(200);
digitalWrite(ledpin[0], LOW);
digitalWrite(ledpin[1], LOW);
digitalWrite(ledpin[2], LOW);
digitalWrite(ledpin[3], LOW);
[Link](NOTE_C3, 300);
delay(200);
}
delay(500);
turn = -1; // Reset turn value to start the game again
}
13
1
The Book of R, © 2016 by Tilman M. Davies

2
NUMER ICS , AR ITHMETIC,
ASSIGNMENT, AND VECTOR S

In its simplest role, R can function as a


mere desktop calculator. In this chapter,
I’ll discuss how to use the software for arith-
metic. I’ll also show how to store results so you
can use them later in other calculations. Then, you’ll
learn about vectors, which let you handle multiple
values at once. Vectors are an essential tool in R, and much of R’s function-
ality was designed with vector operations in mind. You’ll examine some
common and useful ways to manipulate vectors and take advantage of
vector-oriented behavior.

2.1 R for Basic Math


All common arithmetic operations and mathematical functionality are ready
to use at the console prompt. You can perform addition, subtraction, mul-
tiplication, and division with the symbols +, -, *, and /, respectively. You can
create exponents (also referred to as powers or indices) using ^, and you con-
trol the order of the calculations in a single command using parentheses, ().
The Book of R, © 2016 by Tilman M. Davies

2.1.1 Arithmetic
In R, standard mathematical rules apply throughout and follow the usual
left-to-right order of operations: parentheses, exponents, multiplication,
division, addition, subtraction (PEMDAS). Here’s an example in the
console:

R> 2+3
[1] 5
R> 14/6
[1] 2.333333
R> 14/6+5
[1] 7.333333
R> 14/(6+5)
[1] 1.272727
R> 3^2
[1] 9
R> 2^3
[1] 8

You can find the square root of any non-negative number with the sqrt
function. You simply provide the desired number to x as shown here:

R> sqrt(x=9)
[1] 3
R> sqrt(x=5.311)
[1] 2.304561

When using R, you’ll often find that you need to translate a complicated
arithmetic formula into code for evaluation (for example, when replicating
a calculation from a textbook or research paper). The next examples pro-
vide a mathematically expressed calculation, followed by its execution in R:

3 × 60 R> 10^2+3*60/8-3
102 + −3 [1] 119.5
8

53 × (6 − 2) R> 5^3*(6-2)/(61-3+4)
[1] 8.064516
61 − 3 + 4

2.25− 1
R> 2^(2+1)-4+64^((-2)^(2.25-1/4))
22+1 − 4 + 64−2 4
[1] 16777220

  12
0.44 × (1 − 0.44) R> (0.44*(1-0.44)/34)^(1/2)
34 [1] 0.08512966

18 Chapter 2
The Book of R, © 2016 by Tilman M. Davies

Note that some R expressions require extra parentheses that aren’t


present in the mathematical expressions. Missing or misplaced parenthe-
ses are common causes of arithmetic errors in R, especially when dealing
with exponents. If the exponent is itself an arithmetic calculation, it must
always appear in parentheses. For example, in the third expression, you
need parentheses around 2.25-1/4. You also need to use parentheses if the
number being raised to some power is a calculation, such as the expression
22+1 in the third example. Note that R considers a negative number a cal-
culation because it interprets, for example, -2 as -1*2. This is why you also
need the parentheses around -2 in that same expression. It’s important to
highlight these issues early because they can easily be overlooked in large
chunks of code.

2.1.2 Logarithms and Exponentials


You’ll often see or read about researchers performing a log transformation
on certain data. This refers to rescaling numbers according to the logarithm.
When supplied a given number x and a value referred to as a base, the log-
arithm calculates the power to which you must raise the base to get to x.
For example, the logarithm of x = 243 to base 3 (written mathematically as
log3 243) is 5, because 35 = 243. In R, the log transformation is achieved
with the log function. You supply log with the number to transform, assigned
to the value x, and the base, assigned to base, as follows:

R> log(x=243,base=3)
[1] 5

Here are some things to consider:


• Both x and the base must be positive.
• The log of any number x when the base is equal to x is 1.
• The log of x = 1 is always 0, regardless of the base.

There’s a particular kind of log transformation often used in mathe-


matics called the natural log, which fixes the base at a special mathematical
number—Euler’s number. This is conventionally written as e and is approxi-
mately equal to 2.718.
Euler’s number gives rise to the exponential function, defined as e raised
to the power of x, where x can be any number (negative, zero, or positive).
The exponential function, f (x) = e x , is often written as exp(x) and repre-
sents the inverse of the natural log such that exp(loge x) = loge exp(x) = x.
The R command for the exponential function is exp:

R> exp(x=3)
[1] 20.08554

Numerics, Arithmetic, Assignment, and Vectors 19


The Book of R, © 2016 by Tilman M. Davies

The default behavior of log is to assume the natural log:

R> log(x=20.08554)
[1] 3

You must provide the value of base yourself if you want to use a value
other than e. The logarithm and exponential functions are mentioned here
because they become important later on in the book—many statistical meth-
ods use them because of their various helpful mathematical properties.

2.1.3 E-Notation
When R prints large or small numbers beyond a certain threshold of sig-
nificant figures, set at 7 by default, the numbers are displayed using the
classic scientific e-notation. The e-notation is typical to most programming
languages—and even many desktop calculators—to allow easier interpreta-
tion of extreme values. In e-notation, any number x can be expressed as xey,
which represents exactly x × 10y . Consider the number 2, 342, 151, 012, 900.
It could, for example, be represented as follows:

• 2.3421510129e12, which is equivalent to writing 2.3421510129 × 1012


• 234.21510129e10, which is equivalent to writing 234.21510129 × 1010

You could use any value for the power of y, but standard e-notation
uses the power that places a decimal just after the first significant digit. Put
simply, for a positive power +y, the e-notation can be interpreted as “move
the decimal point y positions to the right.” For a negative power −y, the inter-
pretation is “move the decimal point y positions to the left.” This is exactly
how R presents e-notation:

R> 2342151012900
[1] 2.342151e+12
R> 0.0000002533
[1] 2.533e-07

In the first example, R shows only the first seven significant digits and
hides the rest. Note that no information is lost in any calculations even if
R hides digits; the e-notation is purely for ease of readability by the user, and
the extra digits are still stored by R, even though they aren’t shown.
Finally, note that R must impose constraints on how extreme a number
can be before it is treated as either infinity (for large numbers) or zero (for
small numbers). These constraints depend on your individual system, and
I’ll discuss the technical details a bit more in Section 6.1.1. However, any
modern desktop system can be trusted to be precise enough by default for
most computational and statistical endeavors in R.

20 Chapter 2
The Book of R, © 2016 by Tilman M. Davies

Exercise 2.1

a. Using R, verify that

6a + 42
= 29.50556
34.2−3.62
when a = 2.3.
b. Which of the following squares negative 4 and adds 2 to the
result?
i. (-4)^2+2
ii. -4^2+2
iii. (-4)^(2+2)
iv. -4^(2+2)
c. Using R, how would you calculate the square root of half of the
average of the numbers 25.2, 15, 16.44, 15.3, and 18.6?
d. Find loge 0.3.
e. Compute the exponential transform of your answer to (d).
f. Identify R’s representation of −0.00000000423546322 when
printing this number to the console.

2.2 Assigning Objects


So far, R has simply displayed the results of the example calculations by
printing them to the console. If you want to save the results and perform fur-
ther operations, you need to be able to assign the results of a given computa-
tion to an object in the current workspace. Put simply, this amounts to storing
some item or result under a given name so it can be accessed later, without
having to write out that calculation again. In this book, I will use the terms
assign and store interchangeably. Note that some programming books refer
to a stored object as a variable because of the ability to easily overwrite that
object and change it to something different, meaning that what it represents
can vary throughout a session. However, I’ll use the term object throughout
this book because we’ll discuss variables in Part III as a distinctly different
statistical concept.
You can specify an assignment in R in two ways: using arrow notation
(<-) and using a single equal sign (=). Both methods are shown here:

R> x <- -5
R> x
[1] -5

Numerics, Arithmetic, Assignment, and Vectors 21


The Book of R, © 2016 by Tilman M. Davies

R> x = x + 1 # this overwrites the previous value of x


R> x
[1] -4

R> mynumber = 45.2

R> y <- mynumber*x


R> y
[1] -180.8

R> ls()
[1] "mynumber" "x" "y"

As you can see from these examples, R will display the value assigned
to an object when you enter the name of the object into the console. When
you use the object in subsequent operations, R will substitute the value you
assigned to it. Finally, if you use the ls command (which you saw in Sec-
tion 1.3.1) to examine the contents of the current workspace, it will reveal
the names of the objects in alphabetical order (along with any other previ-
ously created items).
Although = and <- do the same thing, it is wise (for the neatness of code
if nothing else) to be consistent. Many users choose to stick with the <-, how-
ever, because of the potential for confusion in using the = (for example, I
clearly didn’t mean that x is mathematically equal to x + 1 earlier). In this
book, I’ll do the same and reserve = for setting function arguments, which
begins in Section 2.3.2. So far you’ve used only numeric values, but note that
the procedure for assignment is universal for all types and classes of objects,
which you’ll examine in the coming chapters.
Objects can be named almost anything as long as the name begins with
a letter (in other words, not a number), avoids symbols (though underscores
and periods are fine), and avoids the handful of “reserved” words such as
those used for defining special values (see Section 6.1) or for controlling
code flow (see Chapter 10). You can find a useful summary of these naming
rules in Section 9.1.2.

Exercise 2.2

a. Create an object that stores the value 32 × 41/8 .


b. Overwrite your object in (a) by itself divided by 2.33. Print the
result to the console.
c. Create a new object with the value −8.2 × 10−13 .
d. Print directly to the console the result of multiplying (b) by (c).

22 Chapter 2
The Book of R, © 2016 by Tilman M. Davies

2.3 Vectors
Often you’ll want to perform the same calculations or comparisons upon
multiple entities, for example if you’re rescaling measurements in a data set.
You could do this type of operation one entry at a time, though this is clearly
not ideal, especially if you have a large number of items. R provides a far
more efficient solution to this problem with vectors.
For the moment, to keep things simple, you’ll continue to work with
numeric entries only, though many of the utility functions discussed here
may also be applied to structures containing non-numeric values. You’ll start
looking at these other kinds of data in Chapter 4.

2.3.1 Creating a Vector


The vector is the essential building block for handling multiple items in R.
In a numeric sense, you can think of a vector as a collection of observations
or measurements concerning a single variable, for example, the heights of
50 people or the number of coffees you drink daily. More complicated data
structures may consist of several vectors. The function for creating a vector
is the single letter c, with the desired entries in parentheses separated by
commas.

R> myvec <- c(1,3,1,42)


R> myvec
[1] 1 3 1 42

Vector entries can be calculations or previously stored items (including


vectors themselves).

R> foo <- 32.1


R> myvec2 <- c(3,-3,2,3.45,1e+03,64^0.5,2+(3-1.1)/9.44,foo)
R> myvec2
[1] 3.000000 -3.000000 2.000000 3.450000 1000.000000 8.000000
[7] 2.201271 32.100000

This code created a new vector assigned to the object myvec2. Some of
the entries are defined as arithmetic expressions, and it’s the result of the
expression that’s stored in the vector. The last element, foo, is an existing
numeric object defined as 32.1.
Let’s look at another example.

R> myvec3 <- c(myvec,myvec2)


R> myvec3
[1] 1.000000 3.000000 1.000000 42.000000 3.000000 -3.000000
[7] 2.000000 3.450000 1000.000000 8.000000 2.201271 32.100000

This code creates and stores yet another vector, myvec3, which contains
the entries of myvec and myvec2 appended together in that order.

Numerics, Arithmetic, Assignment, and Vectors 23


The Book of R, © 2016 by Tilman M. Davies

2.3.2 Sequences, Repetition, Sorting, and Lengths


Here I’ll discuss some common and useful functions associated with R vec-
tors: seq, rep, sort, and length.
Let’s create an equally spaced sequence of increasing or decreasing
numeric values. This is something you’ll need often, for example when
programming loops (see Chapter 10) or when plotting data points (see
Chapter 7). The easiest way to create such a sequence, with numeric values
separated by intervals of 1, is to use the colon operator.

R> 3:27
[1] 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

The example 3:27 should be read as “from 3 to 27 (by 1).” The result is
a numeric vector just as if you had listed each number manually in parenthe-
ses with c. As always, you can also provide either a previously stored value or
a (strictly parenthesized) calculation when using the colon operator:

R> foo <- 5.3


R> bar <- foo:(-47+1.5)
R> bar
[1] 5.3 4.3 3.3 2.3 1.3 0.3 -0.7 -1.7 -2.7 -3.7 -4.7
[12] -5.7 -6.7 -7.7 -8.7 -9.7 -10.7 -11.7 -12.7 -13.7 -14.7 -15.7
[23] -16.7 -17.7 -18.7 -19.7 -20.7 -21.7 -22.7 -23.7 -24.7 -25.7 -26.7
[34] -27.7 -28.7 -29.7 -30.7 -31.7 -32.7 -33.7 -34.7 -35.7 -36.7 -37.7
[45] -38.7 -39.7 -40.7 -41.7 -42.7 -43.7 -44.7

Sequences with seq


You can also use the seq command, which allows for more flexible creations
of sequences. This ready-to-use function takes in a from value, a to value, and
a by value, and it returns the corresponding sequence as a numeric vector.

R> seq(from=3,to=27,by=3)
[1] 3 6 9 12 15 18 21 24 27

This gives you a sequence with intervals of 3 rather than 1. Note that
these kinds of sequences will always start at the from number but will not
always include the to number, depending on what you are asking R to
increase (or decrease) them by. For example, if you are increasing (or
decreasing) by even numbers and your sequence ends in an odd number,
the final number won’t be included. Instead of providing a by value, how-
ever, you can specify a [Link] value to produce a vector with that many
numbers, evenly spaced between the from and to values.

R> seq(from=3,to=27,[Link]=40)
[1] 3.000000 3.615385 4.230769 4.846154 5.461538 6.076923 6.692308
[8] 7.307692 7.923077 8.538462 9.153846 9.769231 10.384615 11.000000
[15] 11.615385 12.230769 12.846154 13.461538 14.076923 14.692308 15.307692

24 Chapter 2
The Book of R, © 2016 by Tilman M. Davies

[22] 15.923077 16.538462 17.153846 17.769231 18.384615 19.000000 19.615385


[29] 20.230769 20.846154 21.461538 22.076923 22.692308 23.307692 23.923077
[36] 24.538462 25.153846 25.769231 26.384615 27.000000

By setting [Link] to 40, you make the program print exactly 40 evenly
spaced numbers from 3 to 27.
For decreasing sequences, the use of by must be negative. Here’s an
example:

R> foo <- 5.3


R> myseq <- seq(from=foo,to=(-47+1.5),by=-2.4)
R> myseq
[1] 5.3 2.9 0.5 -1.9 -4.3 -6.7 -9.1 -11.5 -13.9 -16.3 -18.7 -21.1
[13] -23.5 -25.9 -28.3 -30.7 -33.1 -35.5 -37.9 -40.3 -42.7 -45.1

This code uses the previously stored object foo as the value for from and
uses the parenthesized calculation (-47+1.5) as the to value. Given those
values (that is, with foo being greater than (-47+1.5)), the sequence can
progress only in negative steps; directly above, we set by to be -2.4. The use
of [Link] to create decreasing sequences, however, remains the same
(it would make no sense to specify a “negative length”). For the same from
and to values, you can create a decreasing sequence of length 5 easily, as
shown here:

R> myseq2 <- seq(from=foo,to=(-47+1.5),[Link]=5)


R> myseq2
[1] 5.3 -7.4 -20.1 -32.8 -45.5

There are shorthand ways of calling these functions, which you’ll learn
about in Chapter 9, but in these early stages I’ll stick with the explicit usage.

Repetition with rep


Sequences are extremely useful, but sometimes you may want simply to
repeat a certain value. You do this using rep.

R> rep(x=1,times=4)
[1] 1 1 1 1
R> rep(x=c(3,62,8.3),times=3)
[1] 3.0 62.0 8.3 3.0 62.0 8.3 3.0 62.0 8.3
R> rep(x=c(3,62,8.3),each=2)
[1] 3.0 3.0 62.0 62.0 8.3 8.3
R> rep(x=c(3,62,8.3),times=3,each=2)
[1] 3.0 3.0 62.0 62.0 8.3 8.3 3.0 3.0 62.0 62.0 8.3 8.3 3.0 3.0 62.0
[16] 62.0 8.3 8.3

The rep function is given a single value or a vector of values as its


argument x, as well as a value for the arguments times and each. The value
for times provides the number of times to repeat x, and each provides the

Numerics, Arithmetic, Assignment, and Vectors 25


The Book of R, © 2016 by Tilman M. Davies

number of times to repeat each element of x. In the first line directly above,
you simply repeat a single value four times. The other examples first use
rep and times on a vector to repeat the entire vector, then use each to repeat
each member of the vector, and finally use both times and each to do both
at once.
If neither times nor each is specified, R’s default is to treat the values of
times and each as 1 so that a call of rep(x=c(3,62,8.3)) will just return the origi-
nally supplied x with no changes.
As with seq, you can include the result of rep in a vector of the same data
type, as shown in the following example:

R> foo <- 4


R> c(3,8.3,rep(x=32,times=foo),seq(from=-2,to=1,[Link]=foo+1))
[1] 3.00 8.30 32.00 32.00 32.00 32.00 -2.00 -1.25 -0.50 0.25 1.00

Here, I’ve constructed a vector where the third to sixth entries (inclu-
sive) are governed by the evaluation of a rep command—the single value
32 repeated foo times (where foo is stored as 4). The last five entries are the
result of an evaluation of seq, namely a sequence from −2 to 1 of length
foo+1 (5).

Sorting with sort


Sorting a vector in increasing or decreasing order of its elements is another
simple operation that crops up in everyday tasks. The conveniently named
sort function does just that.

R> sort(x=c(2.5,-1,-10,3.44),decreasing=FALSE)
[1] -10.00 -1.00 2.50 3.44

R> sort(x=c(2.5,-1,-10,3.44),decreasing=TRUE)
[1] 3.44 2.50 -1.00 -10.00

R> foo <- seq(from=4.3,to=5.5,[Link]=8)


R> foo
[1] 4.300000 4.471429 4.642857 4.814286 4.985714 5.157143 5.328571 5.500000
R> bar <- sort(x=foo,decreasing=TRUE)
R> bar
[1] 5.500000 5.328571 5.157143 4.985714 4.814286 4.642857 4.471429 4.300000

R> sort(x=c(foo,bar),decreasing=FALSE)
[1] 4.300000 4.300000 4.471429 4.471429 4.642857 4.642857 4.814286 4.814286
[9] 4.985714 4.985714 5.157143 5.157143 5.328571 5.328571 5.500000 5.500000

The sort function is pretty straightforward. You supply a vector to the


function as the argument x, and a second argument, decreasing, indicates
the order in which you want to sort. This argument takes a type of value
you have not yet met: one of the all-important logical values. A logical value

26 Chapter 2
The Book of R, © 2016 by Tilman M. Davies

can be only one of two specific, case-sensitive values: TRUE or FALSE. Gener-
ally speaking, logicals are used to indicate the satisfaction or failure of a
certain condition, and they form an integral part of all programming lan-
guages. You’ll investigate logical values in R in greater detail in Section 4.1.
For now, in regards to sort, you set decreasing=FALSE to sort from smallest to
largest, and decreasing=TRUE sorts from largest to smallest.

Finding a Vector Length with length


I’ll round off this section with the length function, which determines how
many entries exist in a vector given as the argument x.

R> length(x=c(3,2,8,1))
[1] 4

R> length(x=5:13)
[1] 9

R> foo <- 4


R> bar <- c(3,8.3,rep(x=32,times=foo),seq(from=-2,to=1,[Link]=foo+1))
R> length(x=bar)
[1] 11

Note that if you include entries that depend on the evaluation of other
functions (in this case, calls to rep and seq), length tells you the number of
entries after those inner functions have been executed.

Exercise 2.3

a. Create and store a sequence of values from 5 to −11 that pro-


gresses in steps of 0.3.
b. Overwrite the object from (a) using the same sequence with the
order reversed.
c. Repeat the vector c(-1,3,-5,7,-9) twice, with each element
repeated 10 times, and store the result. Display the result sorted
from largest to smallest.
d. Create and store a vector that contains, in any configuration, the
following:
i. A sequence of integers from 6 to 12 (inclusive)
ii. A threefold repetition of the value 5.3
iii. The number −3
iv. A sequence of nine values starting at 102 and ending at the
number that is the total length of the vector created in (c)
e. Confirm that the length of the vector created in (d) is 20.

Numerics, Arithmetic, Assignment, and Vectors 27


The Book of R, © 2016 by Tilman M. Davies

2.3.3 Subsetting and Element Extraction


In all the results you have seen printed to the console screen so far, you may
have noticed a curious feature. Immediately to the left of the output there
is a square-bracketed [1]. When the output is a long vector that spans the
width of the console and wraps onto the following line, another square-
bracketed number appears to the left of the new line. These numbers rep-
resent the index of the entry directly to the right. Quite simply, the index
corresponds to the position of a value within a vector, and that’s precisely why
the first value always has a [1] next to it (even if it’s the only value and not
part of a larger vector).
These indexes allow you to retrieve specific elements from a vector,
which is known as subsetting. Suppose you have a vector called myvec in
your workspace. Then there will be exactly length(x=myvec) entries in myvec,
with each entry having a specific position: 1 or 2 or 3, all the way up to
length(x=myvec). You can access individual elements by asking R to return
the values of myvec at specific locations, done by entering the name of the
vector followed by the position in square brackets.

R> myvec <- c(5,-2.3,4,4,4,6,8,10,40221,-8)


R> length(x=myvec)
[1] 10
R> myvec[1]
[1] 5

R> foo <- myvec[2]


R> foo
[1] -2.3

R> myvec[length(x=myvec)]
[1] -8

Because length(x=myvec) results in the final index of the vector (in this
case, 10), entering this phrase in the square brackets extracts the final ele-
ment, -8. Similarly, you could extract the second-to-last element by subtract-
ing 1 from the length; let’s try that, and also assign the result to a new object:

R> [Link] <- length(x=myvec)


R> bar <- myvec[[Link]-1]
R> bar
[1] 40221

As these examples show, the index may be an arithmetic function of


other numbers or previously stored values. You can assign the result to a new
object in your workspace in the usual way with the <- notation. Using your
knowledge of sequences, you can use the colon notation with the length of

28 Chapter 2
The Book of R, © 2016 by Tilman M. Davies

the specific vector to obtain all possible indexes for extracting a particular
element in the vector:

R> 1:[Link]
[1] 1 2 3 4 5 6 7 8 9 10

You can also delete individual elements by using negative versions of the
indexes supplied in the square brackets. Continuing with the objects myvec,
foo, bar, and [Link] as defined earlier, consider the following operations:

R> myvec[-1]
[1] -2.3 4.0 4.0 4.0 6.0 8.0 10.0 40221.0 -8.0

This line produces the contents of myvec without the first element. Sim-
ilarly, the following code assigns to the object baz the contents of myvec with-
out its second element:

R> baz <- myvec[-2]


R> baz
[1] 5 4 4 4 6 8 10 40221 -8

Again, the index in the square brackets can be the result of an appropri-
ate calculation, like so:

R> qux <- myvec[-([Link]-1)]


R> qux
[1] 5.0 -2.3 4.0 4.0 4.0 6.0 8.0 10.0 -8.0

Using the square-bracket operator to extract or delete values from a


vector does not change the original vector you are subsetting unless you
explicitly overwrite the vector with the subsetted version. For instance, in
this example, qux is a new vector defined as myvec without its second-to-last
entry, but in your workspace, myvec itself remains unchanged. In other words,
subsetting vectors in this way simply returns the requested elements, which
can be assigned to a new object if you want, but doesn’t alter the original
object in the workspace.
Now, suppose you want to piece myvec back together from qux and bar.
You can call something like this:

R> c(qux[-length(x=qux)],bar,qux[length(x=qux)])
[1] 5.0 -2.3 4.0 4.0 4.0 6.0 8.0 10.0 40221.0
[10] -8.0

As you can see, this line uses c to reconstruct the vector in three parts:
qux[-length(x=qux)], the object bar defined earlier, and qux[length(x=qux)]. For
clarity, let’s examine each part in turn.

Numerics, Arithmetic, Assignment, and Vectors 29


The Book of R, © 2016 by Tilman M. Davies

• qux[-length(x=qux)]
This piece of code returns the values of qux except for its last element.
R> length(x=qux)
[1] 9
R> qux[-length(x=qux)]
[1] 5.0 -2.3 4.0 4.0 4.0 6.0 8.0 10.0

Now you have a vector that’s the same as the first eight entries of
myvec.
• bar
Earlier, you had stored bar as the following:
R> bar <- myvec[[Link]-1]
R> bar
[1] 40221

This is precisely the second-to-last element of myvec that qux is missing.


So, you’ll slot this value in after qux[-length(x=qux)].
• qux[length(x=qux)]
Finally, you just need the last element of qux that matches the last ele-
ment of myvec. This is extracted from qux (not deleted as earlier) using
length.

R> qux[length(x=qux)]
[1] -8

Now it should be clear how calling these three parts of code together, in
this order, is one way to reconstruct myvec.
As with most operations in R, you are not restricted to doing things one
by one. You can also subset objects using vectors of indexes, rather than indi-
vidual indexes. Using myvec again from earlier, you get the following:

R> myvec[c(1,3,5)]
[1] 5 4 4

This returns the first, third, and fifth elements of myvec in one go.
Another common and convenient subsetting tool is the colon operator
(discussed in Section 2.3.2), which creates a sequence of indexes. Here’s
an example:

R> 1:4
[1] 1 2 3 4
R> foo <- myvec[1:4]
R> foo
[1] 5.0 -2.3 4.0 4.0

30 Chapter 2
The Book of R, © 2016 by Tilman M. Davies

This provides the first four elements of myvec (recall that the colon oper-
ator returns a numeric vector, so there is no need to explicitly wrap this
using c).
The order of the returned elements depends entirely upon the index
vector supplied in the square brackets. For example, using foo again, con-
sider the order of the indexes and the resulting extractions, shown here:

R> length(x=foo):2
[1] 4 3 2
R> foo[length(foo):2]
[1] 4.0 4.0 -2.3

Here you extracted elements starting at the end of the vector, working
backward. You can also use rep to repeat an index, as shown here:

R> indexes <- c(4,rep(x=2,times=3),1,1,2,3:1)


R> indexes
[1] 4 2 2 2 1 1 2 3 2 1
R> foo[indexes]
[1] 4.0 -2.3 -2.3 -2.3 5.0 5.0 -2.3 4.0 -2.3 5.0

This is now something a little more general than strictly “subsetting”—


by using an index vector, you can create an entirely new vector of any length
consisting of some or all of the elements in the original vector. As shown
earlier, this index vector can contain the desired element positions in any
order and can repeat indexes.
You can also return the elements of a vector after deleting more than
one element. For example, to create a vector after removing the first and
third elements of foo, you can execute the following:

R> foo[-c(1,3)]
[1] -2.3 4.0

Note that it is not possible to mix positive and negative indexes in a


single index vector.
Sometimes you’ll need to overwrite certain elements in an existing vec-
tor with new values. In this situation, you first specify the elements you want
to overwrite using square brackets and then use the assignment operator to
assign the new values. Here’s an example:

R> bar <- c(3,2,4,4,1,2,4,1,0,0,5)


R> bar
[1] 3 2 4 4 1 2 4 1 0 0 5
R> bar[1] <- 6
R> bar
[1] 6 2 4 4 1 2 4 1 0 0 5

Numerics, Arithmetic, Assignment, and Vectors 31


The Book of R, © 2016 by Tilman M. Davies

This overwrites the first element of bar, which was originally 3, with a
new value, 6. When selecting multiple elements, you can specify a single
value to replace them all or enter a vector of values that’s equal in length
to the number of elements selected to replace them one for one. Let’s try
this with the same bar vector from earlier.

R> bar[c(2,4,6)] <- c(-2,-0.5,-1)


R> bar
[1] 6.0 -2.0 4.0 -0.5 1.0 -1.0 4.0 1.0 0.0 0.0 5.0

Here you overwrite the second, fourth, and sixth elements with -2, -0.5,
and -1, respectively; all else remains the same. By contrast, the following
code overwrites elements 7 to 10 (inclusive), replacing them all with 100:

R> bar[7:10] <- 100


R> bar
[1] 6.0 -2.0 4.0 -0.5 1.0 -1.0 100.0 100.0 100.0 100.0 5.0

Finally, it’s important to mention that this section has focused on just
one of the two main methods, or “flavors,” of vector element extraction in R.
You’ll look at the alternative method, using logical flags, in Section 4.1.5.

Exercise 2.4

a. Create and store a vector that contains the following, in this


order:
– A sequence of length 5 from 3 to 6 (inclusive)
– A twofold repetition of the vector c(2,-5.1,-33)
7
– The value 42 +2
b. Extract the first and last elements of your vector from (a), storing
them as a new object.
c. Store as a third object the values returned by omitting the first
and last values of your vector from (a).
d. Use only (b) and (c) to reconstruct (a).
e. Overwrite (a) with the same values sorted from smallest to
largest.
f. Use the colon operator as an index vector to reverse the order
of (e), and confirm this is identical to using sort on (e) with
decreasing=TRUE.
g. Create a vector from (c) that repeats the third element of (c)
three times, the sixth element four times, and the last ele-
ment once.

32 Chapter 2
The Book of R, © 2016 by Tilman M. Davies

h. Create a new vector as a copy of (e) by assigning (e) as is to a


newly named object. Using this new copy of (e), overwrite the
first, the fifth to the seventh (inclusive), and the last element with
the values 99 to 95 (inclusive), respectively.

2.3.4 Vector-Oriented Behavior


Vectors are so useful because they allow R to carry out operations on
multiple elements simultaneously with speed and efficiency. This vector-
oriented, vectorized, or element-wise behavior is a key feature of the language,
one that you will briefly examine here through some examples of rescaling
measurements.
Let’s start with this simple example:

R> foo <- 5.5:0.5


R> foo
[1] 5.5 4.5 3.5 2.5 1.5 0.5
R> foo-c(2,4,6,8,10,12)
[1] 3.5 0.5 -2.5 -5.5 -8.5 -11.5

This code creates a sequence of six values between 5.5 and 0.5, in incre-
ments of 1. From this vector, you subtract another vector containing 2, 4,
6, 8, 10, and 12. What does this do? Well, quite simply, R matches up the
elements according to their respective positions and performs the operation
on each corresponding pair of elements. The resulting vector is obtained by
subtracting the first element of c(2,4,6,8,10,12) from the first element of foo
(5.5 − 2 = 3.5), then by subtracting the second element of c(2,4,6,8,10,12)
from the second element of foo (4.5 − 4 = 0.5), and so on. Thus, rather than
inelegantly cycling through each element in turn (as you could do by hand
or by explicitly using a loop), R permits a fast and efficient alternative using
vector-oriented behavior. Figure 2-1 illustrates how you can understand this
type of calculation and highlights the fact that the positions of the elements
are crucial in terms of the final result; elements in differing positions have
no effect on one another.
The situation is made more complicated when using vectors of different
lengths, which can happen in two distinct ways. The first is when the length
of the longer vector can be evenly divided by the length of the shorter vec-
tor. The second is when the length of the longer vector cannot be divided by
the length of the shorter vector—this is usually unintentional on the user’s
part. In both of these situations, R essentially attempts to replicate, or recycle,
the shorter vector by as many times as needed to match the length of the
longer vector, before completing the specified operation. As an example,
suppose you wanted to alternate the entries of foo shown earlier as negative

Numerics, Arithmetic, Assignment, and Vectors 33


The Book of R, © 2016 by Tilman M. Davies

Vector A Operation/Comparison Vector B

[1] [1]

[2] [2]

... ...

[n] [n]

Figure 2-1: A conceptual diagram of the element-wise behavior of a


comparison or operation carried out on two vectors of equal length
in R. Note that the operation is performed by matching up the element
positions.

and positive. You could explicitly multiply foo by c(1,-1,1,-1,1,-1), but you
don’t need to write out the full latter vector. Instead, you can write the
following:

R> bar <- c(1,-1)


R> foo*bar
[1] 5.5 -4.5 3.5 -2.5 1.5 -0.5

Here bar has been applied repeatedly throughout the length of foo until
completion. The left plot of Figure 2-2 illustrates this particular example.
Now let’s see what happens when the vector lengths are not evenly divisible.

R> baz <- c(1,-1,0.5,-0.5)


R> foo*baz
[1] 5.50 -4.50 1.75 -1.25 1.50 -0.50
Warning message:
In foo * baz :
longer object length is not a multiple of shorter object length

Here you see that R has matched the first four elements of foo with the
entirety of baz, but it’s not able to fully repeat the vector again. The repeti-
tion has been attempted, with the first two elements of baz being matched
with the last two of the longer foo, though not without a protest from R,
which notifies the user of the unevenly divisible lengths (you’ll look at warn-
ings in more detail in Section 12.1). The plot on the right in Figure 2-2 illus-
trates this example.

34 Chapter 2
The Book of R, © 2016 by Tilman M. Davies

foo * bar foo * baz

[1] [1] [1] [1]

[2] [2] [2] [2]

[3] [1] [3] [3]

[4] [2] [4] [4]

[5] [1] [5] [1]

[6] [2] [6] [2]

Figure 2-2: An element-wise operation on two vectors of differing lengths.


Left: foo multiplied by bar; lengths are evenly divisible. Right: foo multiplied
by baz; lengths are not evenly divisible, and a warning is issued.

As I noted in Section 2.3.3, you can consider single values to be vectors


of length 1, so you can use a single value to repeat an operation on all the
values of a vector of any length. Here’s an example, using the same vec-
tor foo:

R> qux <- 3


R> foo+qux
[1] 8.5 7.5 6.5 5.5 4.5 3.5

This is far easier than executing foo+c(3,3,3,3,3,3) or the more general


foo+rep(x=3,times=length(x=foo)). Operating on vectors using a single value in
this fashion is quite common, such as if you want to rescale or translate a set
of measurements by some constant amount.
Another benefit of vector-oriented behavior is that you can use vector-
ized functions to complete potentially laborious tasks. For example, if you
want to sum or multiply all the entries in a numeric vector, you can just use
a built-in function.

Numerics, Arithmetic, Assignment, and Vectors 35


The Book of R, © 2016 by Tilman M. Davies

Recall foo, shown earlier:

R> foo
[1] 5.5 4.5 3.5 2.5 1.5 0.5

You can find the sum of these six elements with

R> sum(foo)
[1] 18

and their product with

R> prod(foo)
[1] 162.4219

Far from being just convenient, vectorized functions are faster and more
efficient than an explicitly coded iterative approach like a loop. The main
takeaway from these examples is that much of R’s functionality is designed
specifically for certain data structures, ensuring neatness of code as well as
optimization of performance.
Lastly, as mentioned earlier, this vector-oriented behavior applies in the
same way to overwriting multiple elements. Again using foo, examine the
following:

R> foo
[1] 5.5 4.5 3.5 2.5 1.5 0.5
R> foo[c(1,3,5,6)] <- c(-99,99)
R> foo
[1] -99.0 4.5 99.0 2.5 -99.0 99.0

You see four specific elements being overwritten by a vector of length 2,


which is recycled in the same fashion you’re familiar with. Again, the length
of the vector of replacements must evenly divide the number of elements
being overwritten, or else a warning similar to the one shown earlier will be
issued when R cannot complete a full-length recycle.

Exercise 2.5

a. Convert the vector c(2,0.5,1,2,0.5,1,2,0.5,1) to a vector of only


1s, using a vector of length 3.
b. The conversion from a temperature measurement in degrees
Fahrenheit F to Celsius C is performed using the following
equation:
5
C = (F − 32)
9

36 Chapter 2
The Book of R, © 2016 by Tilman M. Davies

Use vector-oriented behavior in R to convert the tempera-


tures 45, 77, 20, 19, 101, 120, and 212 in degrees Fahrenheit to
degrees Celsius.
c. Use the vector c(2,4,6) and the vector c(1,2) in conjunction with
rep and * to produce the vector c(2,4,6,4,8,12).
d. Overwrite the middle four elements of the resulting vector from
(c) with the two recycled values -0.1 and -100, in that order.

Important Code in This Chapter

Function/operator Brief description First occurrence

+, *, -, /, ^ Arithmetic Section 2.1, p. 17


sqrt Square root Section 2.1.1, p. 18
log Logarithm Section 2.1.2, p. 19
exp Exponential Section 2.1.2, p. 19
<-, = Object assignment Section 2.2, p. 21
c Vector creation Section 2.3.1, p. 23
:, seq Sequence creation Section 2.3.2, p. 24
rep Value/vector repetition Section 2.3.2, p. 25
sort Vector sorting Section 2.3.2, p. 26
length Determine vector length Section 2.3.2, p. 27
[ ] Vector subsetting/extraction Section 2.3.3, p. 28
sum Sum all vector elements Section 2.3.4, p. 36
prod Multiply all vector elements Section 2.3.4, p. 36

Numerics, Arithmetic, Assignment, and Vectors 37


Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

2
Learning to Code in
a Playground

“Hello World” app is no small accom-


plishment, but now it’s time to really
learn how to write some code. Xcode pro-
vides a special type of document called a playground,
which is a great place to learn how to program using
Swift. In a playground, you can write lines of code
and immediately see what happens when that code
runs, without going through the trouble of writing a
whole app, as we did in Chapter 1.
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

Let’s get started by opening up a playground. Open Xcode


and select Get started with a playground, as shown in the
Welcome to Xcode dialog in Figure 2-1. If this window doesn’t
automatically open for you when you launch Xcode, select
Welcome to Xcode from the Window option in the menu or
press ⌘-shift-1.

Figure 2-1: Getting started with a playground

You’ll be asked to name your playground (Figure 2-2). In


this example, we’ll keep the name MyPlayground, but feel free
to name it whatever you want. Make sure that you choose iOS
as the platform to run the playground.
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

Figure 2-2: Naming the playground and selecting the platform

When the playground first opens, you’ll see two panels


in the window, just like in Figure 2-3. On the left is the play-
ground editor, where you’ll write your code. On the right is the
results sidebar, which displays the results of your code.

Figure 2-3: Playground editor and results sidebar


Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

The line var str = "Hello, playground" in Figure 2-3 creates


a variable named str. A variable is like a container; you can
use it to hold almost anything—a simple number, a string
of letters, or a complex object. Let’s take a closer look at how
variables work.

Constants and Variables


Here's the line of code from Figure 2-3 again:

var str = "Hello, playground" "Hello, playground"

It does two things. First, it creates a variable named str.


This is called a declaration because we are declaring that we
would like to create a variable. To create a variable, you type
the word var and then type a name for your variable. In this
case, we named it str. There are some rules when it comes to
naming variables, but we’ll go over them later, so for now stick
with this example.
Second, this line of code gives a value of "Hello, playground"
to str using the = operator. This is called an assignment because
we are assigning a value to our newly created variable. Remem-
ber, you can think of a variable as a container that holds
something. So now we have a container named str that holds
"Hello, playground".
You can read this line of code as “the variable str equals
Hello, playground.” As you can see, Swift is often very readable;
this line of code practically tells you in English what it’s doing.
Variables are handy because now if you want to print the
words “Hello, playground” all you have to do is use the com-
mand print on str, just like in the following code:

print(str) "Hello, playground\n"

This prints "Hello, playground\n" in the results sidebar. The


\n is added automatically to the end of whatever you print. It
is known as the newline character and tells the computer to go
to a new line. To see the results of your program as it would
actually run, bring up the debug area, which will appear
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

below the two panels as shown in Figure 2-4. To do this, go to


ViewDebug Area4Show Debug Area in the Xcode menu
or press ⌘-shift-Y. When str is printed in the debug area, you
can see that the quotes around Hello, playground and the new-
line character do not appear. This is what str would really look
like if you were to officially compile and run this program!

Figure 2-4: Viewing the real output of your program in the


debug area

Variables can change (or vary!) in your programs, so


you can change the value of a variable if you want it to hold
something else. Let’s try that now. Add these lines to your
playground program:

 str = "Hello, world" "Hello, world"


print(str) "Hello, world\n"

To change the value of a variable, type its name and use


the = operator to set it to a new value. We do this at  to
change the value of str to "Hello, world". The computer throws
away whatever str used to hold, and says, “Okay, boss, str is
now Hello, world” (that is, it would say that if it could talk!).
Notice that when we change the value of str, we don’t write
var again. The computer remembers that we declared str in a
previous line of code and knows that str already exists. So we
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

don’t need to create str again, we just want to put something


different in it.
You can also declare constants. Like variables, constants
hold values. The big difference between a constant and a vari-
able is that a constant can never change its value. Variables
can vary, and constants are, well, constant! Declaring a con-
stant is similar to declaring a variable, but we use the word
let instead of var:

let myName = "Gloria" "Gloria"

Here we create a constant called myName and assign it the


value of "Gloria".
Once you create a constant and give it a value, it will
have that value until the end of time. Think of a constant as
a big rock into which you’ve carved your value. If you try to
give myName another value, like "Matt", you’ll get an error like
the one in Figure 2-5.

Figure 2-5: Trying to change the value of a constant won’t work.

N o t e In the playground, an error will appear as a red circle with a


tiny white circle inside it. Clicking the error mark will show
the error message and tell you what’s wrong. If you have your
debug area showing, you should also see information describ-
ing what happened and sometimes even how to fix it.
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

When to Use Constants vs. Variables


Now you’ve successfully created
a variable and a constant—good
job! But when should you use one
over the other? In Swift, it is best
practice to use constants instead of
variables unless you expect that the
value will change. Constants help
make code “safer.” If you know the
value of something is never going to
change, why not etch it into stone
and avoid any possible confusion
later?
For example, say you want to keep track of the total num-
ber of windows in your classroom and the number of windows
that are open today. The number of windows in your classroom
isn’t going to change, so you should use a constant to store this
value. The number of windows that are open in your classroom
will change depending on the weather and time of day, however,
so you should use a variable to store this value.

let numberOfWindows = 8 8
var numberOfWindowsOpen = 3 3

Here we make numberOfWindows a con-


stant and set it to 8 because the total
number of windows will always be 8. We
make numberOfWindowsOpen a variable and
set it to 3 because we’ll want to change
that value when we open or close any
windows.
Remember: use var for variables and
let for constants!
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

Naming Constants and Variables


You can name a variable or constant almost anything you
want, with a few exceptions. You can’t name them something
that is already a word in Swift. For example, you can’t name
a variable var. Writing var var would just be confusing, to you
and the computer. You will get an error if you try to name a
variable or constant using one of Swift’s reserved words. You
also can’t have two variables or constants with the same name
in the same block of code.
In addition to these rules, there are some other good pro-
gramming guidelines to follow when naming things in Swift.
Your names should always start with a lowercase letter. It’s
also a good idea to have very descriptive variable and con-
stant names (they can be as long as you want). When you use
a descriptive name, it’s a lot easier to figure out what that
variable or constant is supposed to be. If you were looking
at someone else’s code, which variable name would you find
easier to understand: numKids or numberOfKidsInMyClass? The first
one is vague, but the second one is descriptive. It is quite com-
mon to see variables and constants that are a bunch of words
strung together, like numberOfKidsInMyClass. This capitalization
style, where the first letter of each word is capitalized when
multiple words are joined together to make a variable name,
is called camel case. That’s because the pattern of lowercase
and uppercase letters looks like the humps on a camel’s back.
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

Data Types
In Swift, you can choose what kind of data—the data type—
you want a variable or constant to hold. Remember how we
said you can think of a variable as a container that holds
something? Well, the data type is like the container type.
The computer needs to know what kind of things we will be
putting in each container. In Swift pro-
gramming, once you tell the computer
you want a variable or constant to hold a
certain data type, it won’t let you put any-
thing but that data type in that variable or
constant. If you have a basket designed to
hold potatoes, it’d be a bad idea to fill that
basket with water—unless you like water
leaking all over your shoes!

Declaring Data Types


When you create a variable or a constant, you can tell the
computer what type of data it will hold. In our example about
classroom windows, we know this variable will always be a
whole number (you can’t really have half a window), so we
could specify an integer data type, like this:

var numberOfWindowsOpen: Int = 3 3

The colon means “is of type.” In plain English, this line of


code says, “the variable numberOfWindowsOpen, which is an integer,
is equal to 3.” So this line of code creates a variable, gives it
a name, tells the computer what sort of data it will hold, and
then assigns it a value. Phew! One line of code did all that?
Did we mention that Swift is a very concise language? Some
languages might require several lines of code to do this same
thing. Swift is designed so that you can do a bunch of things
with just one line of code!
You only have to declare the data type once. When we tell
the computer that a variable will hold integers, we don’t have
to tell it again. In fact, if we try to do that, Xcode will give us
an error. Once the data type is declared, a variable or constant
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

will hold that same type of data forever. Once an integer,


always an integer!
There’s one more thing you need to know about data types:
a variable or constant cannot hold something that is not its
data type. For example, if you try to put a decimal number
into numberOfWindowsOpen, you’ll get an error, as shown in Fig-
ure 2-6.

Figure 2-6: You can’t put a decimal number into a variable


that is supposed to hold an integer.

Setting numberOfWindowsOpen = 5 and numberOfWindowsOpen = 0


is valid and works. But you can’t set numberOfWindowsOpen = 1.5.

Common Data Types


As you just learned, a data type lets the computer know what
kind of data it is working with and how to store it in its mem-
ory. But what are the data types? Here are some common ones
that you’ll be working with:
XX Int
XX Double
XX Float
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

XX Bool
XX String

Let’s dig in and see what each one of these actually is!

Int (Integers)
We already talked a little bit about integers, but let’s go over
them in more detail. An integer, called an Int in Swift, is a
whole number that has no decimal or fractional part. You
can think of them as counting numbers. Integers are signed,
meaning that they can be negative or positive (or zero).

Double and Float (Decimal Numbers)


Decimal numbers are numbers that have digits after the deci-
mal point, like 3.14. (An integer like 3 would be written as 3.0
if you wanted it to be a decimal number.) There are two data
types that can store decimal numbers: a Double and a Float.
Doubles are more common in Swift because they can hold big-
ger numbers, so we’ll focus on those.
When you assign a Double, you must always have a digit
to the left of the decimal place or you will get an error. For
example, suppose bananas cost 19 cents each:

 var bananaPrice: Double = .19 // ERROR


v var bananaPrice: Double = 0.19 // CORRECT 0.19

The code at  will result in an error because it doesn’t


have a digit to the left of the decimal point. The code at 
works fine because it has a leading zero.

Bool (Booleans, or True/False)


A Boolean value can only be one of two things: true or false. In
Swift, the Boolean data type is called a Bool.

let swiftIsFun = true true


var iAmSleeping = false false
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

Bools are often used in if-else statements to tell the com-


puter which path a program should take. (We’ll cover Bools and
if-else statements in more detail in Chapter 3.)

String
The String data type is used to store words and phrases. A
string is a collection of characters enclosed in quotation marks.
For example, "Hello, playground" is a string. Strings can be
made up of all sorts of characters: letters, numbers, symbols,
and more. The quotation marks are important because they
tell the computer that everything in between the quotes is part
of a string that you’re creating.
You can use strings to build sentences by adding strings
together in a process called string concatenation. Let’s see how
it works! Try this in your playground:

let morningGreeting = "Good Morning" "Good Morning"


let friend = "Jude" "Jude"
let specialGreeting = morningGreeting + " " + friend "Good Morning Jude"

By adding strings together with the plus sign (+), this code
creates a variable called specialGreeting with the string "Good
Morning Jude" as its value.

Type Inference
You may have noticed that sometimes when we declare a vari-
able, we include the data type:

var numberOfWindowsOpen: Int = 3 3


Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

And sometimes we do not include the data type:

var numberOfWindowsOpen = 3 3

What gives? The computer is actually smart enough to


figure out the data type, most of the time. This is called type
inference—because the computer will infer, or guess, the type
of data we are using based on clues that we give it. When you
create a variable and give it an initial value, that value is a big
clue for the computer. Here are some examples:
XX If you assign a number with no decimal value (like 3), the
computer will assume it’s an Int.
XX If you assign a number with a decimal value (like 3.14),
the computer will assume it’s a Double.
XX If you assign the word true or false (with no quotes around
it), the computer will assume it’s a Bool.
XX If you assign something with quotes around it, the com-
puter will assume it’s a String.
When the type is inferred, the variable or constant is set to
that data type just as if you had declared the data type yourself.
This is done purely for convenience. You can include the data
type every time you declare a new constant or variable, and
that’s perfectly fine. But why not let the computer figure it out
and save yourself the time and extra typing?

Casting
Casting is a way to temporarily transform the data type of a
variable or constant. You can think of this as casting a spell
on a variable—you make its value behave like a different data
type, but just for a short while. To do this, you write a new data
type followed by parentheses that hold the variable you are cast-
ing. Note that this doesn’t actually change the data type, it just
gives you a temporary value for that one line of code. Here are
a few examples of casting between Int and Double. Take a look at
the results of your code in the results sidebar.
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

let months = 12 12
print(months) "12\n"
 let doubleMonths = Double(months) 12
print(doubleMonths) "12.0\n"

At , we cast our Int variable months to a Double and store


it in a new variable called doubleMonths. This adds a decimal
place, and the result of this casting is 12.0.
You can also cast a Double to an Int:

let days = 365.25 365.25


 Int(days) 365

At , we assign we cast our Double, days, to an Int. You can


see that the decimal place and all the digits following it were
removed: our number became 365 when cast to an Int. This is
because an Int is not capable of holding a decimal number—it
can contain only whole numbers, as we learned earlier. So any-
thing after the decimal point is chopped off.
Again, casting does not actually change a data type. In
our example, even after casting, days is still a Double. We can
verify this by printing days:

print(days) "365.25\n"

In the results sidebar,


you’ll see that days is still equal
to 365.25.
In the next section, we’ll
cover some examples of where
and when you would use cast-
ing. So if it’s not clear right
now why you would cast a vari-
able, just hold on a bit longer!
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

Operators
There are a number of arithmetic operators in Swift that you
can use to do math. You have already seen the basic assign-
ment operator, =. You are probably also familiar with what
these four operators do:
+ Addition
- Subtraction
* Multiplication
/ Division
You can use these operators to perform math on Ints,
Floats, and Doubles. The numbers being operated on are called
operands. Experiment with these mathematical operators in
your playground by writing code like the following:

6.2 + 1.4 7.6


3 * 5 15
16 – 2 14
9 / 3 3

If you type this code in your playground, you will see the
results of each mathematical expression in the results sidebar.
As you can see, writing mathematical expressions in code is
not that different from writing them normally. For example,
16 minus 2 is written as 16 – 2.
You can even save the result of a mathematical expres-
sion in a variable or constant so you can use it somewhere else
in your code. To see how this works, type these lines in your
playground:

var sum = 6.2 + 1.4 7.6


 print(sum) "7.6\n"
let threeTimesFive = 3 * 5 15

When you print sum , you’ll see the value 7.6 in the
results sidebar.
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

Spaces Matter
In Swift, the spaces around an operator are important. You can either
write a blank space on both sides of the mathematical operator or
leave out the spaces altogether. But you cannot just put a space on
one side of the operator and not the other. That will cause an error,
and it makes your code look messy. Take a look at Figure 2-7.

Figure 2-7: Make sure that you have the same number of spaces on
each side of your operators.

So far, we have used only numbers in our mathematical


expressions, but mathematical operators will also work on
variables and constants.
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

Add the following code to your playground:

let three = 3 3
let five = 5 5
let half = 0.5 0.5
let quarter = 0.25 0.25
var luckyNumber = 7 5

three * luckyNumber 21
five + three 8
half + quarter 0.75

As you can see, you can use the mathematical operators on


variables and constants in the same way you did on numbers.
There is one important thing to note: you can only use a
mathematical operator on two variables or constants that are
the same data type. In the previous code, three and five are
both Ints. The constants half and quarter are Doubles because
they are decimal numbers. If you try to add or multiply one of
the Ints and one of the Doubles, you’ll get an error like the one
in Figure 2-8.

Figure 2-8: In Swift, you cannot do math on mixed data types.


Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

But what if you really want to do math on mixed data


types? For example, let’s say you want to calculate one-tenth
of your age:

var myAge = 11 // This is an Int 11


let multiplier = 0.1 // This is a Double 0.1
var oneTenthMyAge = myAge * multiplier

The last line will result in an error because we are


attempting to multiply an Int by a Double. But don’t worry!
You have a couple of options to make sure your operands are
the same data type.
One option is to declare myAge as a Double, like this:

var myAge = 11.0 // This is a Double 11.0


let multiplier = 0.1 // This is a Double 0.1
var oneTenthMyAge = myAge * multiplier 1.1

This code works because now we’re multiplying two


Doubles.
The second option is to use casting (I told you we would
come back to this!). Let’s take a look at an example:

var myAge = 11 // This is an Int 11


let multiplier = 0.1 // This is a Double 0.1
 var oneTenthMyAge = Double(myAge) * multiplier 1.1
v oneTenthMyAge = myAge * multiplier

At , we cast myAge to a Double before multiplying it. This


means we no longer have mixed types, so the code works. But
at  we will get an error. That’s because myAge is still an Int.
Casting it to a Double at  did not permanently change it to a
Double. Casting is a great solution in this case because we don’t
want to permanently change myAge to a Double, we just want to
be able to perform math with it as if it were a Double.
Could we cast multiplier to an Int? You bet! Then we are
doing math on two integers, which works fine. However, this
results in a less precise calculation because we’ll lose the deci-
mal place. When you cast a variable from a Double to an Int,
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

the computer simply removes any digits after the decimal to


make it a whole number. In this case, your multiplier of 0.1
would cast to an Int of 0. Let’s cast some variables in the play-
ground and see what we get:

 Double(myAge) 11
v Int(multiplier) 0
w Int(1.9) 1

At , casting our Int, myAge, to a Double gives us 11.0. So the


value hasn’t changed, but it now has a decimal place. At ,
casting our Double, multiplier, to an Int gives us 0. This value is
quite different after casting, because we lost the decimal place:
0.1 became 0. This could be a very bad thing in our code if we
were not expecting it to happen. You must be careful when
casting to make sure you aren’t unexpectedly changing your
values. At , there’s another example of casting a Double to an
Int, and as you can see, 1.9 does not get rounded up to 2. Its
decimal value just gets removed and we are left with 1.
There’s another mathematical operator, the modulo
operator (written as %), which might not be as familiar to you.
The modulo operator (also called modulus) gives the remainder
after division. For example, 7 % 2 = 1 because 7 divided by 2
has a remainder of 1. Try out the modulo operator with these
examples in your playground:

10 % 3 1
12 % 4 0
34 % 5 4

var evenNumber = 864 864


 evenNumber % 2 0

var oddNumber = 571 571


v oddNumber % 2 1

As you can see, the modulo operator is useful for determin-


ing whether a number is even (x % 2 equals 0)  or odd (x % 2
equals 1) .
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

Order of Operations
So far we’ve only done one mathematical operation on each line
of code, but it’s common to do more than one operation on a
single line. Let’s look at an example.
You have three five-dollar bills and two one-dollar bills.
How much money do you have? Let’s do this calculation on one
line of code:

var myMoney = 5 * 3 + 2 17

This assigns a value of 17 to myMoney. The computer mul-


tiplies 5 times 3 and then adds 2. But how does the computer
know to multiply first and then add 2? Does it just work from
left to right? No! Take a look at this:

myMoney = 2 + 5 * 3 17

We moved the numbers around and the result is still 17.


If the computer just went from left to right, it would add 2 + 5
and get 7. Then it would multiply that result, 7, times 3, and
get 21. Even though we changed the order of the numbers in
our mathematical expression, the computer still does the mul-
tiplication first (which gives us 15) and then adds the 2 to get
17. The computer will always do multiplication and division
first, then addition and subtraction. This is called the order of
operations.

Parentheses
You don’t have to rely on the computer to figure out which
step to do first like we did in the money example. You, the
programmer, have the power to decide! You can use parenthe-
ses to group operations together. When you put parentheses
around something, you tell the computer to do that step first:

 myMoney = 2 + (5 * 3) 17
v myMoney = (2 + 5) * 3 21
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

At , the parentheses tell the computer to multiply 5 times


3 first and then add 2. This will give you 17. At  the paren-
theses tell the computer to add 2 plus 5 first and then multiply
that by 3, which gives you 21.
You can make your code even more specific by using
parentheses inside of other parentheses. The computer will
evaluate the inside parentheses first, then the outside ones.
Try this example:

myMoney = 1 + ((2 + 3) * 4) 21

First the computer adds 2 and 3 because that’s between the


inner set of parentheses. Then it multiplies the result by 4,
since that’s within the outer set of parentheses. It will add the
1 last because it’s outside of both sets of parentheses. The final
result is 21.

Unary Operators
So far, the arithmetic operators we’ve looked at require two
numbers. But there are three operators that operate on a
single number. These are called unary operators:
- Negation
++ Increment
-- Decrement
The first unary operator we’ll cover is negation. The minus
sign (-) negates a value, and it works for both numbers and
variables, like -10 or -y.

var myNumber = 534 534


var myNegativeNumber = -myNumber -534
var myOtherNumber = -245 -245
 var myPositiveNumber = -myOtherNumber 245

As you can see at , negation returns a positive value if


you use it on a negative number.
The increment operator (++) increments, or increases, the
value of the operand by 1. It is written as ++x, which can be
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

read as “add one to x.” Similarly, the decrement operator (--)


decrements, or decreases, the value by 1. It is written as --x,
which can be read as “subtract one from x.” You will see the
++ and -- operators a lot in loops, which you’ll learn about in
Chapter 4.

Compound Assignment Operators


The final category of operators that you’ll use is the compound
assignment operators. These are “shortcut” operators that com-
bine a mathematical operator with the assignment operator (=).
For example, this expression

a = a + b

becomes

a += b

You can use these operators to update the value of a vari-


able or constant by performing an operation on it. In plain
English, an expression like a += b says “add b to a and store
the new value in a.” Table 2-1 shows mathematical expressions
using compound assignment operators and the same expres-
sions in their longer forms.

Table 2-1: Expressions Using Compound


Assignment Operators vs. Expressions
in Long Form
Short form Long form
a += b a = a + b
a -= b a = a - b
a *= b a = a * b
a /= b a = a / b

Let’s watch these operators in action. Imagine that we’re


trying to write a program to calculate the number of ani-
mals on an ark. First we create a variable called animalsOnArk
and set it to 0 because there aren’t animals on the ark yet.
As the different types of animals board the ark, we want to
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

increase animalsOnArk to count all of the animals. If two giraffes


board the ark, then we need to add 2 to animalsOnArk. If two
elephants board the ark, then we need to add 2 again. If four
antelopes board the ark, then we need to increase animalsOnArk
by 4. You can see this code in Figure 2-9.

Figure 2-9: Using a compound assignment operator to tally


animalsOnArk

After the giraffes, elephants, and antelopes board the ark,


the final value for animalsOnArk is 8. What a zoo!
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

A Few Quick Comments About


Comments
Most programming languages come with a way to write comments
directly inline with the code. Comments are notes added to the code
that are ignored by the computer and are there to help the humans
reading the code understand what’s going on. Although a program
will run completely fine without any comments, it’s a good idea to
include comments for sections of code that might be unclear or confus-
ing. Even if you’re not going to show your program to anybody else,
your comments will help you remember what you were doing or think-
ing when you wrote that code. It’s not uncommon to come back to a
piece of code you wrote months or years ago and have no idea what
you were thinking at the time.
There are two ways to add comments to code in Swift. The first
way is to put two forward slashes (//) in front of the text you want to
add. These comments can be placed on their own line, like this:

// My favorite things

Or they can be placed on the same line as a line of code—as long


as the comment comes after the code:

var myFavoriteAnimal = "Horse" // does not have to be a pet

The second way of adding comments is used for long comments,


or multiline comments, where the start and end of the comment is
marked by /* and */.

/*
This block of code will add up the animals
that walk onto an ark.
*/
{
var animalsOnArk = 0
let numberOfGiraffes = 2
animalsOnArk += numberOfGiraffes
--snip--
}
Coding iPhone Apps for Kids, © 2016 by Gloria Winquist and Matt McCarthy

Multiline comments are also very useful when you are debugging
your code. For example, if you don’t want the computer to run some
part of your code because you’re trying to find a bug, but you also
don’t want to delete all of your hard work, you can use multiline com-
ments to comment out large sections of code temporarily. When you
format a chunk of code as a comment, the computer will ignore that
code just like it ignores any other comment.

What You Learned


In this chapter, you learned how to write code in a Swift play-
ground, which lets you see results right away. You learned how
to create variables and constants. You also learned the basic
data types and operators that you’ll be using when writing
your own computer programs.
The CS Detective, © 2016 by Jeremy Kubica

—1—
Search Problems

T he door opened without a knock—only the hinge’s creak


announced the visitor. Frank started for his crossbow, but
pulled up short. If the Vinettees were coming for him, they would
have knocked—with an axe. Whoever was coming through the door
must want to talk. Frank reached for his mug instead and downed
the remainder of his now-cold coffee.
“Captain Donovan,” he said as the man entered. “What brings
you to this fine neighborhood? I thought you didn’t venture below
Fifteenth Street anymore.”
“It’s been a while,” the captain said simply. “How’ve you been,
Frank?”
“Spectacular,” Frank answered dryly, eyeing the captain as he
walked a slow circuit around the room.
Donovan scanned Frank’s shabby office. His red officer’s cloak
swished gently behind him. “How’s the private eye game?”
“It pays the bills,” Frank lied.
The captain nodded. He paused for a moment, then moved to the
bookshelf and browsed the contents.
“So is this a social visit then?” Frank said. “Should I be asking
after Marlene and the kids?”
The CS Detective, © 2016 by Jeremy Kubica

“They’re quite well,” replied Donovan without turning around.


“Marlene’s turtle-grooming business is doing well these days. Bill
joined the force last year. And Veronica is an accountant, just about
the last thing we would have—”
“I wasn’t actually asking,” Frank interrupted.
The captain shrugged. He pulled a book from the shelf and leafed
through the pages. Frank craned his neck to see the cover—Police
Academy Yearbook: Class XXI.
“What do you want, Captain?” Frank demanded.
The captain met Frank’s stare at last. “I need your help, Frank,”
he said.
Frank straightened. In the five years since Frank had left the
force, the captain had paid him exactly two visits, and both had been
to warn him to stay away from active cases. Threats were all Frank
had come to expect, but now it seemed the captain had a special
kind of problem—perhaps the kind that would mean an end to
Frank’s delinquent rent.
“I’m not on the force anymore,” said Frank airily. “Why don’t you
get one of your trusted detectives to do it?”
“I need someone outside of the force,” said the captain. “Drop the
act, Frank. If you don’t know what it means for me to be here, you’re
not the person I need.”
The CS Detective, © 2016 by Jeremy Kubica

Frank chuckled. “A leak? On your force?”


“Worse. Last night someone broke into the station’s record room
and stole over 500 scrolls.”
“What were they after?” asked Frank. Without thinking, he
leaned forward in his chair and reached for a fresh scroll and a
quill. The movement came automatically to him, like drinking coffee
or avoiding stairs.
“I don’t know,” said Donovan. “There was no pattern. They stole
whole shelves of documents, everything from property disputes to
expense reports. They took all the ledgers we keep on assassins,
celebrities, private investigators, notaries . . . They even took both
boxes of Farmer Swinson’s noise complaints. But other shelves
were completely untouched. We counted at least 512 missing
documents.”
“Maybe it was one of Farmer Swinson’s neighbors,” joked Frank.
“They must’ve heard that after a mere hundred complaints, an
intern will come to your house and give you a stern lecture.”
Captain Donovan didn’t bother to reply. He just stared pityingly
until Frank cleared his throat and broke the silence. “So you want
me to find these documents?”
The captain shook his head. “I want you to find the thieves. We
have backups of the documents. I want to know what information
they needed and what they plan to do with it.”
“A search problem,” Frank mused. During his time on the force,
his two specialties had been search problems and annoying the
captain.
“Does the king know?” Frank asked.
“I briefed him yesterday,” said the captain, a hint of annoyance
in his voice. “Ever since the trouble with that crackpot wizard, the
king insists on daily briefings on everything.” Two years ago, a
megalomaniac wizard named Exponentious had tried to destroy the
entire kingdom. Since then King Fredrick had personally instituted
The CS Detective, © 2016 by Jeremy Kubica

sweeping upgrades to the kingdom’s security, with over 300 new


security regulations, at least 5 of which dealt with the storage of
official documents in government buildings under 10 stories tall.
“I can’t blame him though,” Donovan grumbled. “It was a close
call. If it hadn’t been for Princess Ann, who knows where the king-
dom would be now.”
Frank nodded silently. Exponentious had attacked the algorithmic
foundations of the kingdom by cursing the scholars who studied
those algorithms. Within months he had rendered even simple oper-
ations inefficient, and the kingdom had started to grind to a halt.
Evidence of the damage had been everywhere; even in his local
bakery, Frank had himself witnessed panic break out as customers
discovered they couldn’t remember how to arrange themselves into
a line.
“The king has, of course, taken a personal interest in the matter,”
the captain continued irritably. “He wants all the details: Who’s
assigned to the case? Which search algorithms are we using? Have
we scoured all of the neighboring buildings?”
Frank stifled a chuckle and mulled over the proposition. A con-
sulting gig for the capital’s police force would be good money. He
glanced down at his feet, where the tip of a toe peeked through a
hole in his shoe. “If I’m going to consult,” he said, “I’m going to do
things my way.”
This was the moment of truth. Five years ago he’d been kicked off
the force for doing things his way. The captain was a man of rules
and order. Frank’s last use of heuristics had been the final straw—
Captain Donovan had claimed his badge that very afternoon. But,
then again, doing things his own way had always gotten Frank
results.
“I figured as much,” the captain responded at last. He pulled a thin
folder from under his trench cloak and dropped it on Frank’s desk.
The CS Detective, © 2016 by Jeremy Kubica

“I’ll be in touch,” Donovan said. Then, without ceremony, he


turned and left the office.

Three hours and twelve mugs of coffee later, Frank sat hunched
over his desk and thumbed through the thin folder of information
for the seventh time. The words jumped and swayed in the flickering
candlelight, but didn’t provide any new insights.
There wasn’t a lot to go on. The captain had given him a list of
missing documents and the duty roster for the night in question, but
nothing more.
Finally, with an exaggerated sigh, Frank grabbed a piece of
parchment and started making notes.
The first step in any search problem is determining what it is
you hope to find—the target, as his old instructor in Police
Algorithms 101 called it. Frank had learned that lesson early; he’d
been tasked in his first week as an officer with finding the duke’s
prize stallion, and he’d proudly returned to the station that same
afternoon with a 42-pound horned turtle. Apparently, the impres-
sive reptile wasn’t good enough. A good search algorithm means
nothing if you’re looking for the wrong thing.
In this case it wasn’t a what, but rather a who. The captain had
been right about that point. Once the thieves had the documents, it
didn’t matter if the police got them back. The thieves already had
whatever information they needed.
So his target was simple: the person or persons who stole the
documents.
The second step in any search problem is identifying the search
space. What are you searching? During Frank’s daily search for his
keys, the search space was every flat surface in his office. And when
The CS Detective, © 2016 by Jeremy Kubica

Frank wanted to find a criminal, his search space was every person
in the vicinity of the capital.
Frank sat back and rubbed his eyes. It was a big search problem,
finding a specific criminal in a city of criminals. But he had seen
worse.
Now that he had defined the problem, he could start on an algo-
rithm. A linear search was out; he couldn’t afford to question
everyone in the city. He could also rule out many of the other, fancier
algorithms he had studied in the academy. For a problem like this,
he would have to go back to his toolkit of basic search algorithms—
the private investigator’s most trusted friends.
Frank made a note on the parchment. He had the target to find,
he knew the search space, and he had his algorithm. It was time to
get to work.

police algorithms 101: search problems


Excerpt from Professor Drecker’s Lecture

In this class we’ll discuss several different algorithms (and


related data structures) for solving search problems. A
search problem is defined as any problem that requires us
to find a specific value (or target) within a space of possible
values (a search space).
Those of you who graduate and go on to become police
officers will find yourselves facing problems that fall into
this category every single day. This broad definition of a
search problem encompasses a lot of different computa-
tional problems, from searching the police log for a specific
entry to finding rooms within a hideout to finding all
The CS Detective, © 2016 by Jeremy Kubica

arrest records that match some criteria. This class won’t


be exhaustive—that would take years—but I’ll give you
some simple examples of basic and important algorithms
as we go.
The algorithms described in this class will have three
common components:

Target The piece of data you’re searching for. The target


can be either a specific value or a criterion that signifies
the successful completion of a search.

Search space The set of all possibilities to test for the


target. For example, the search space could be a list of
values or all the nodes in a graph. A single possibility
within the search space is called a state.

Search algorithm The set of specific steps or instruc-


tions for conducting the search.

Some search problems will have additional requirements


or complexities, which we’ll touch upon as we go over differ-
ent algorithms.
75
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

3
How to Generate
Electricity

hapter 1 described why you need a closed


loop to get current flowing through a
circuit, and Chapter 2 showed you how
to build your own electromagnet and motor. The
projects in those chapters used electricity from a
battery, but in this chapter, you’ll make your own
electricity sources!
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

Specifically, you’ll learn how to build your own genera-


tor, which creates electricity from movement, and your own
battery, which creates electricity through chemical reactions.
These are two of the most common ways to obtain electricity.

Generating Electricity
with Magnets
When you run current through a wire, it creates a magnetic
field around the wire, but there’s another connection between
electricity and magnetism. You can also create electricity
using a wire and a magnet!

A Changing Magnetic Field Creates Electricity


If you move a magnet back and forth over a wire connected in
a closed loop, you’ll create a current in the wire. Moving the
magnet changes the magnetic field around the wire, and the
changing magnetic field pushes the electrons through the wire.

current

magnet moving
across wire

If you stop moving the magnet, the current also stops—


even if the wire is still within the magnetic field—because the
magnetic field is no longer changing.
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

If you connect the two ends of the wire to a light bulb and
create a closed loop, then the current can flow. Unfortunately,
however, the current created by moving a magnet over a single
wire doesn’t provide enough energy quickly enough to actu-
ally light the bulb. To light a bulb, or to power anything else,
you need to find a way to generate more power, which is the
amount of energy produced in a certain time.

How Does a Generator Work?


A generator is a device that turns movement—such as the
movement of a magnet over a wire—into electricity. To create
more power with a wire and a magnet, you can wind that
wire into a coil. The coiled wire acts like a group of wires,
and when the magnetic field passes through it, a current
flows through each coil, creating more power than you could
with a straight wire.

Light bulb
turns on!

more
current

magnet moving
through coil of wire
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

Creating Electricity from


Water or Wind
If you place a coil in a magnetic field and rotate the coil
with a handle, you’re converting your own movement
into electricity. If you replaced the handle with a water
wheel and placed it into a stream of water, the water
would push the wheel so that the coil would rotate in the
magnetic field and create a current. This is how some
power plants generate electricity! The power plant just
lets water run through a wheel that’s connected to a
generator. Then this electricity is transferred, through
power lines, to the power outlets in people’s houses.

high-pressure
sluice gates water
power plant

water generator
dam
water wheel

You can make electricity out of other natural forces


in the same way. For example, to create electricity out
of wind, you can connect the coil to a windmill so that
when the wind blows, it rotates the coil.
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

Meet the Multimeter


You can measure exactly how much energy a simple generator
creates with a basic multimeter. Multimeters are handy when
building any circuit because they can measure a lot of differ-
ent values, including resistance, current, and voltage.

The red lead is the positive lead, the black lead is the
negative lead, and the big dial in the middle lets you tell the
multimeter what to measure. If you’re having problems with a
circuit, measuring the voltage at key points in your circuit is
one practical way to figure out what’s wrong.

How to Measure Voltage


To measure voltage with a multimeter, first turn the dial to
one of the V options. (In this book, I’ll tell you which setting
to choose, but in your own projects, pick one that has a num-
ber higher than the highest voltage you expect to see in your
circuit.) Then, at the bottom of the multimeter, connect the
black lead to the COM socket and the red lead to the V socket.
Finally, place one lead on each side of the part you want to
measure the voltage across.
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

In this example, the meter is measuring the voltage


between the positive and negative terminals of a 9 V battery.
Notice that my dial is turned to 20 V, in the range showing
a V with a straight-line symbol. But there’s another V on the
multimeter with a wavy line next to it. Let’s look at what these
symbols mean.

What Are AC and DC?


How you set your multimeter depends on whether you want to
measure the voltage from a battery or a generator. A battery
has a positive and a negative side, but a generator doesn’t!
A generator has two wires that alternate between being
positive and negative. This is because when one side of the
magnet moves past the coil, current in the coil flows in one
direction, and when the other side of the magnet moves past
the coil, current flows in the other direction.
When the current direction switches like that, we call it
alternating current (AC); when the direction of the current
stays the same all the time, we call it direct current (DC).
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

Usually, you’ll find these symbols on your multimeter to indi-


cate the AC and DC ranges of measurement:

AC DC

You need to set the multimeter to measure either AC


or DC to get the correct reading. For example, batteries have
a DC voltage.

Project #5: Make a Shake


Generator
Grab your multimeter—this project will show you how to make
a generator and measure its voltage. One quick way to create a
simple generator is to manually move a magnet back and forth
inside a coil. In this project, you’ll put a magnet inside a tube
and wind a coil around the tube. When you shake the tube, the
magnet should move back and forth inside the coil and create a
voltage.
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

Shopping List

insulated wire plastic tube

magnets

alligator clips

XX Insulated solid-core wire (Jameco #36792, Bitsbox


#W106BK), about 9 feet. Standard hookup wire works fine.
XX A small plastic tube, such as an old pen.
XX Five disc magnets (Jameco #2181319, Bitsbox #HW145)
stacked to form a magnet rod.
XX Two alligator clips (Jameco #256525, Bitsbox #CN262)
to connect the multimeter to the coil.

Tools
XX A multimeter to measure the voltage of your generator.
The multimeter should be able to measure very low AC
voltages, down to 0.01 V or less. Suitable mul­timeters are
Jameco #2206061, Bitsbox #TL057, or Rapid Electronics
#55-6662. These multimeters are a bit more expensive
than the cheapest ones, but they will serve you for many
years to come.
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

multimeter

Step 1: Prepare Your Tube


Find a tube that’s big enough to let the magnets slide easily
back and forth. If you’re using a pen, disassemble the pen and
make sure your magnets fit inside the tube.
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

Step 2: Wind Your Coil


Wind about 50 turns of wire around the middle of your tube.
After winding, make a simple knot with the two ends to keep
your coil together. Then, strip the insulation from the two wire
ends, as shown.

Step 3: Connect the Multimeter


Connect the multimeter to both ends of the coil using alligator
clips and set the multimeter to measure AC. Choose the lowest
AC voltage setting available.
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

Step 4: Shake That Thing!


Next, put the magnets inside the tube. They should fit inside
without coming apart.

Holding the tube and multimeter leads in your hand, place


one finger on each side of the tube so that the magnets don’t
fall out. Then, shake it like you mean it!
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

Observe the voltage value on the multimeter. How much


voltage do you get? I was able to get only 0.02 V from my gen-
erator, so it’s not very powerful.

Step 5: What If There’s No Voltage?


If you can’t measure any voltage from your generator, first
check that your multimeter leads are connected well to the
exposed coil wires. If you still don’t see a voltage higher than
0 V, make sure your multimeter is set to measure really low
voltages; my dial was turned to 2 V AC. You won’t get a high
voltage from this simple generator, so if the multimeter isn’t on
the lowest setting possible, it will keep reading 0 V. Note that
not all multimeters are able to measure such low voltages.
This generator isn’t very powerful right now. How can you
make it more powerful? Try to increase the voltage from the
generator by shaking it faster, adding more loops of wire to the
coil, or using a more powerful magnet.

N o t e Standard hookup wire is a bit bulky; even 50 turns


take up a lot of space! If you want to get a lot more turns, try
using magnet wire instead. It’s really thin wire with a thin
layer of insulating coating.
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

Try It Out:
Using a Motor as a Generator
A motor already has a magnet and a coil of wire that can
rotate in the magnet’s magnetic field. If you rotate the
rotor with your hand, you can generate a voltage on the
motor’s wires.
You could create a generator by reversing the motor
you built in Chapter 2, but the power you’d get from it
would be too small to measure. Instead, try to find an
old motor from a computer fan or a radio-controlled toy
car that you don’t want to play with anymore. Then,
set your multimeter to a low-voltage DC range, such as
2 V DC. Attach the multimeter leads to the motor wires,
just as you did with the shake generator, and turn the
rotor with your fingers. Some motors have internal
circuits that control the motor, and those circuits can
prevent the electricity generated inside the motor from
going out to the wires. But if you’re lucky and find a
motor that doesn’t have such circuits, you should see a
reading on the multimeter. Try a low-voltage AC range
on your multimeter if you see nothing with DC.

How Do Batteries Work?


I’ve shown you how to generate electricity manually, but that
doesn’t explain how you’ve powered circuits up to this point in
the book. You’ve been using batteries, and in this section, we’ll
look at what lets those batteries create electricity.

What’s Inside a Battery?


To create a battery, you need three things:
XX A positive electrode
XX A negative electrode
XX An electrolyte
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

An electrode is a wire that is used to make contact


with something nonmetallic, like the inside of a battery. An
electrolyte is a substance that can release or gain electrons.
Here’s how these three pieces fit inside a typical battery:

positive electrode
electrolyte

negative electrode

You can actually make your own battery by using a simple


nail for one electrode and a copper wire for the other. Stick
both into a lemon, and the lemon juice is your electrolyte.
positive electrode
(copper wire)
negative electrode
(nail)

lack of electrons
lots of electrons

lemon

The copper wire becomes the positive terminal of the


battery, and the nail becomes the negative terminal.

The Chemistry Behind Batteries


When you combine the lemon, the copper wire, and the nail,
two chemical reactions happen: one between the lemon juice
and the nail, and another between the lemon juice and the
copper wire. In the first reaction, electrons build up on the
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

nail; in the second, electrons leave the copper wire. The nail
gets too crowded with electrons, and the copper wire ends up
with too few. Electrons don’t like to be in crowded places, so
the electrons on the nail want to go over to the copper wire
to even things out. But the chemical reactions with the lemon
juice are pushing the electrons the other way.
Now, what do you think will happen if you connect a light
bulb between the nail and the copper wire? The electrons on the
nail really want to get to the copper wire, so they’ll take the
easiest path they can find, and when you create this closed-
loop circuit, they flow from the nail to the copper wire through
the light bulb. Recall that current is just electrons flowing in
a wire; if you have enough current flowing through the light
bulb, it lights up!
After a while, the chemical reactions in the battery stop.
When this happens, the battery is dead. Some batteries can be
recharged when they die, while others must be thrown away.
The materials chosen for the electrodes and electrolyte deter-
mine whether the battery can be recharged or not.
The batteries you buy in the store are not made of
lemons, of course! Modern batteries are made from different
materials, and scientists are always looking for new ways to
create batteries that have more energy, while being small
and lightweight.

What Determines a Battery’s Voltage?


The materials used for the electrodes and electrolyte deter-
mine the voltage you get from a battery, but the size of the
electrodes and the amount of electrolyte don’t matter when it
comes to voltage.
To create higher battery voltages, several battery cells are
connected in series. Connecting two battery cells in series
means that you connect the positive side of one battery to the
negative side of the other. The two unconnected terminals
become the bigger battery’s new positive and negative termi-
nals, and the resulting voltage is the sum of the voltages from
the two batteries. For example, in a standard 9 V battery, you
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

have six 1.5 V battery cells, as shown. Notice that the connec-
tors on the outside are attached to just two terminals.

9V

Project #6: Turn On a Light


with Lemon Power
You can make a battery out of many different things; for
example, in “What’s Inside a Battery?” on page 89, I showed
you how a lemon battery might work. In this project, you’ll
learn how to build a lemon battery of your own and power a
light with it.

Wa r n i n g When you’re finished with this project,


throw the lemons away. The chemical reactions that happen
with the nail and copper wire will leave the lemons unsuitable
for eating.

Meet the LED


A lemon battery can’t create a lot of electricity, so you need to
connect the battery to something that needs very little power
to see the effect. Most light bulbs need more power than you’ll
generate in this project, so let me introduce a component called
a light-emitting diode, or LED.
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

This little electronic component gives off, or emits, light


when you apply a little bit of power to it. LEDs come in many
colors: red, green, yellow, blue, and more. You’ll learn more
about this component in Chapter 4, and you’ll use LEDs a lot
in this book. For now, you’re just going to use an LED to see
the power generated by your lemon battery.

Shopping List

lemons

copper wire

alligator clips

nails
LED

XX Four lemons or one lemon cut into four pieces.


XX 24 inches of copper wire (any copper wire will do, but
it’s important that the wire be copper).
XX Four galvanized nails (most common nails for outdoor
projects are galvanized).
XX Two alligator clips (Jameco #256525, Bitsbox #CN262)
for connecting the LED.
XX A standard LED (Jameco #333973, Bitsbox #OP002 for
just this one, or Jameco #18041, Bitsbox #K033 for a vari-
ety pack). You’ll need several LEDs for the projects in this
book, so order at least 10 or a variety pack.
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

Tools

multimeter
and leads

wire cutter

XX A wire cutter (Jameco #35482, Bitsbox #TL008) to pre-


pare the copper wire.
XX A multimeter (Jameco #2206061, Bitsbox #TL057, Rapid
Electronics #55-6662) to see whether your battery is work-
ing correctly.

Step 1: Prepare Your Wires


First, cut your copper wire into four 6-inch lengths. Strip
about 1 inch of insulation from both ends of each wire. These
will become the electrodes.
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

Step 2: Insert Electrodes into a Lemon


Roll and squeeze a lemon so that you break up the small juice
packets inside it, but not enough to break the skin. Then, use
a nail to make one hole in one end, push a copper wire into
that hole, and push the nail into the other end, as shown. This
is the first lemon battery!

Get your multimeter, set it for DC voltage measurement,


and test your lemon battery now. Place the positive test lead
on the copper wire and the negative test lead on the nail. If
everything works correctly, you should see a voltage of around
1 V on your multimeter.
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

Step 3: Create Four Lemon Batteries


Even if you get 1 V out of your lemon, that’s not enough to
light an LED. Let’s create several lemon batteries so we can
get more electricity!
Just repeat the process described in Step 2 for the other
lemons; each will become a battery. (If you don’t have four
lemons to spare, you can cut one lemon into four pieces.) Now
you should have four lemon batteries.

1 2 3 4

Step 4: Connect the Lemons in Series


To get a higher voltage with your lemon batteries, you’ll need
to connect them in series. To connect two lemons in series, you
just connect the positive side of one lemon to the negative side
of another. Remember, the copper wire is positive, and the nail
is negative.
negative (−) negative (−)

positive (+) positive (+)


Electronics for Kids, © 2016 by Øyvind Nydal Dahl

To wire four lemons in series, just repeat that process


a couple more times. Line your lemons up in a row with the
copper wires pointing to the right and number the lemons
from 1 to 4, beginning from the left. Connect the copper
wire from lemon 1 to the nail in lemon 2. Twist the wire
onto the nail so that the metals connect without coming
apart.
Connect the copper wire of lemon 2 to the nail in
lemon 3, and connect the copper wire from lemon 3 to the
nail in lemon 4. This should give you a row of four lemons,
with an unconnected nail on lemon 1 and an unconnected
copper wire on lemon 4. These are the positive and negative
terminals for your big lemon battery, respectively.

2 3

When you connect batteries in series, you can add their


voltages to find your total. Four 1 V lemon batteries should
give you 4 V. If you have a multimeter, measure the voltage
between the two ends to see whether everything is connected.
You should get a voltage of around 3.5 to 4 V.
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

Step 5: Test Your Lemon Battery


Let’s connect the LED to the lemons! Connect the long leg
from the LED to the copper wire, and connect the short leg
to the nail, as shown. The LED should now light up.
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

Lemons aren’t super powerful batteries (you’d never


see anyone with a lemon connected to their computer, for
example), so your LED will probably be very dim. After you
finish building your lemon-powered circuit, turn off the light
in your room, and you should see the LED glow.
Remember, when you’re finished with your lemon battery,
throw the lemons away—don’t eat them!

Try It Out:
More Food Batteries!
When you’re done making lemon batteries, test to see
whether you can make batteries out of other fruits or
vegetables. For example, what about a potato battery?
Are you able to get more voltage, or is it the same as the
voltage from the lemon?

Step 6: What If Your Lemon Light Doesn’t Work?


If you can’t see light from your LED, even in a dark room,
check to see whether your LED is connected the right way.
The long leg should be connected to the positive side of the
battery, which is the copper wire.
Make sure the lemons are connected to each other only
through the wires and nails. For example, if your lemons are
sitting in a puddle of lemon juice, they could be connected
through that. Just dry them off and move them somewhere
else. Next, check that the copper wires are properly con-
nected to the nails and that the nails and copper wires are
actually touching the juice inside the lemons. Also, check
that the nails and copper wires are not touching each other
inside any of the lemons.
If the circuit still doesn’t work, disconnect all the lemon
batteries from each other. Then, use a multimeter to check
that each lemon battery has some voltage. Connect two lemons
in series, and check that you see a higher voltage. Connect the
third lemon, and check that the voltage has increased again.
Then, connect the fourth lemon and check that you have even
more voltage.
Electronics for Kids, © 2016 by Øyvind Nydal Dahl

If you see a voltage but the LED doesn’t light, then you
probably just need some more power. Get another lemon or
two, create some more batteries, and connect them in series
with the rest.

What’s Next?
In this chapter, you learned how to create your own electric-
ity from magnetism and chemical reactions. You made your
own shake generator, and you built a lemon battery to power
an LED.
If you want to explore generators even more, I suggest
trying to find a dynamo from an old bike. Unlike the genera-
tor you built in this chapter, a dynamo is a generator that
gives you a DC voltage, like a battery, and dynamos are com-
monly used to power headlights on bikes. Cut some windmill
blades out of some stiff cardboard or plastic, connect them
to the dynamo, and see whether you can harvest energy from
the wind.
You’ve now met a few electronic components, including
switches, LEDs, and motors. In the following chapters, you’ll
learn about even more components and graduate to build-
ing some real electronic circuits, like lights that blink, a
touch-sensitive switch, and even your own electronic musical
instrument!
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

2
Simple
Regression
Analysis
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

First Steps

Exactly!

That means...
there is a Where did you
connection learn so much
between the about regression
two, right? analysis, miu?

Miu!

blink
blink

Earth to
Miu! Are you
there?
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

You were staring Ack, you


at that couple. caught me!

I got it!

that's why I am pat


It’s just...
Teaching you! And
they're studying
there’s no crying
together.
in statistics!

pat

I’m y!
rr
so
There,
I wish I
there.
could study with
him like that.

We're finally
doing regression
Yes. I want
analysis today.
to learn.
Doesn't that
cheer you up?

sigh
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

High temp. (°C) Iced tea orders


All right 22nd (Mon.) 29 77
then, let’s go! 23rd (Tues.) 28 62
This table shows the
24th (Wed.) 34 93
high temperature and
the number of iced 25th (Thurs.) 31 84
tea orders every day 26th (Fri.) 25 59
for two weeks. 27th (Sat.) 29 64
28th (Sun.) 32 80
29th (Mon.) 31 75
30th (Tues.) 24 58
31st (Wed.) 33 91
1st (Thurs.) 25 51
2nd (Fri.) 31 73
3rd (Sat.) 26 65
4th (Sun.) 30 84

Plotting the Data

...we'll first
make this into a
Now... scatter plot...

See how the dots


100
roughly line up? That
95 suggests these variables
90 are correlated. The
Iced tea orders

85
correlation coefficient,
called R, indicates
80 how strong the
75 correlation is.
70
65
R = 0.9069
60
55
50
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 R ranges from +1 to
-1, and the further it is
High temp. (°C)
from zero, the stronger
the correlation.* I’ll show
you how to work out the
correlation coefficient
...Like this. I see. on page 78.

* A positive R value indicates a


positive relationship, meaning as
x increases, so does y. A negative
R value means as the x value
increases, the y value decreases.
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

but it’s not really


surprising.

Here, R is large,
indicating iced
tea really does Yes, That Obviously more
people order
sell better on makes sense! iced tea when
hotter days. it's hot out.

True, this
information isn't
very useful by
itself. You mean
there's
more?

rEmember what you can predict


I told you the the number of
other day? Using iced tea orders
regression from the high
analysis... temperature.

31°C

today's high
will be 31° C

Bin
g!

today's high
high will be 27° C
of
31°...

ice
d
te today, there
a
will be 61
orders of
iced tea!
Sure! We iced te
a

haven't even
begun the
regression oh, yeah...
analysis. but how?
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

The Regression Equation


Basically, Are you
the goal of ready?
regression
analysis is... Hold on!
Let me grab
a pencil.

...To obtain the ...in the form of


regression equation... y = ax + b.
Iced tea orders

Iced tea orders

High temp. (°C) High temp. (°C)

What ca If you input a high


n that temperature for x...
tell us
?
ch
scrit

tch
scra

...You can predict


how many
orders of iced
tea there will
be (y).
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

As I said earlier, y is the


I see! Regression dependent (or outcome)
analysis doesn't variable and x is the
seem too hard. independent (or predictor)
variable.

dependent variable Independent variable

Just
you
wait... a is the regression coefficient,
which tells us the slope of
the line we make.

That leaves
us with b, the
intercept. This okay, got it. So how do I get the
tells us where regression equation?
our line crosses
the y-axis.

Hold on, Miu.

Finding the
equation is
only part of
the story.
You also need to
learn how to verify
the accuracy of
your equation by
testing for certain
circumstances. Let’s
look at the process
as a whole.
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

Here's an
General Regression overview of
regression
Analysis Procedure
analysis.

Step 1

Draw a scatter plot of the independent variable


versus the dependent variable. If the dots line up,
the variables may be correlated.

Step 2

Calculate the regression equation.

Step 3
What’s R ?
Calculate the correlation coefficient (R) and
assess our population and assumptions.

Step 4

Conduct the analysis of Variance.

diagnostics
regression

Step 5

Calculate the confidence intervals.

Step 6

Make a prediction!
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

We have to
do all these
steps?

For a
thorough
analysis, yes.

It's easier to
What do steps 4 and 5 explain with an all
even mean? example. let's use right!
sales data from
Norns.

?
Variance

dia gnostics?
ence?
confid

we'll go over
that later. independent dependent
variable variable

Step 1: Draw a scatter plot of the independent


variable versus the dependent variable. If the
dots line up, the variables may be correlated.

High temp. (°C) Iced tea orders


22nd (Mon.) 29 77 100
23rd (Tues.) 28 62 95
24th (Wed.) 34 93 90
Iced tea orders

25th (Thurs.) 31 84
85
26th (Fri.) 25 59
80
27th (Sat.) 29 64
28th (Sun.) 32 80
75

29th (Mon.) 31 75 70
30th (Tues.) 24 58 65
First, draw31sta(Wed.) 33 91 60
1st (Thurs.) 25 51
scatter plot of the
2nd (Fri.) 31 73
55
50 We’ve
independent variable
3rd (Sat.)
4th (Sun.)
26
30
65
84
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
done that
High temp. (°C)
and the dependent already.
variable.
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

When we plot
each day’s high
temperature against
iced tea orders, they
seem to line up.

And we know from


earlier that the
value of R is 0.9069,
which is pretty
high.
It looks like
these variables
are correlated.

100

Do you really 95
90
Iced tea orders

learn anything 85

from all 80
75
those dots? 70
Why not just 65

calculate R ? 60
The shape
55 of our
50
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 data is
High temp. (°C) important!

always draw a
100 100 plot first to
95 95
get a sense of
90 90
Iced tea orders

Iced tea orders

85 85 the data's shape.


80 80
y = 0.2x + 69.5
75 75
70 70
65 65
60 60
55 55
50 50
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
High temp. (°C) High temp. (°C)

You can still find a


regression equation,
Look at this chart. Rather but it's meaningless. The
than flowing in a line, low R value confirms
the dots are scattered it, but the scatter plot Oh, I see.
randomly. lets you see it with Plots...are...
your own eyes. important!
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

Step 2: Calculate the regression equation.

Now, let's make Finally,


a regression the time
equation! has come.

Let's find
a and b !

The little arrows are


the distances from the
line, which represents
the estimated values
of each dot, which are
Iced tea orders

the actual measured


values. The distances
are called residuals.
The goal is to find the
line that best minimizes
all the residuals.

This is called
Let’s draw a Linear Least
High temp. (°C)
straight line, Squares
following the regression.
pattern in the data
as best we can.

We square the Calculate Sxx (sum of squares of


residuals to
x), Syy (sum of squares of y), and I'll add
find the sum of
Sxy (sum of products of x and y). this to my
squares, which
we use to find notes.
the regression
Calculate Se (residual sum of
equation. squares).
Differentiate Se with respect to a Steps with in
steps?!
and b, and set it equal to 0.
Separate out a and b.

Isolate the a component.

Find the regression equation.


The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

Okay, let's start


calculating!

Gulp

Find
• The sum of squares of x, Sxx: ( x − x )2
• The sum of squares of y, Syy: ( y − y)
2

• The sum of products of x and y, Sxy: ( x − x ) ( y − y)

Note: The bar over a variable (like x ) is a notation that means


­average. We can call this variable x-bar.

High temp. Iced tea


in °C orders
(x − x ) (y − y ) (x − x ) (y − y )
2 2
x y x−x y −y
22nd (Mon.) 29 77 −0.1 4.4 0.0 19.6 −0.6
23rd (Tues.) 28 62 −1.1 −10.6 1.3 111.8 12.1
24th (Wed.) 34 93 4.9 20.4 23.6 417.3 99.2
25th (Thurs.) 31 84 1.9 11.4 3.4 130.6 21.2
26th (Fri.) 25 59 −4.1 −13.6 17.2 184.2 56.2
27th (Sat.) 29 64 −0.1 −8.6 0.0 73.5 1.2
28th (Sun.) 32 80 2.9 7.4 8.2 55.2 21.2
29th (Mon.) 31 75 1.9 2.4 3.4 5.9 4.5
30th (Tues.) 24 58 −5.1 −14.6 26.4 212.3 74.9
31st (Wed.) 33 91 3.9 18.4 14.9 339.6 71.1
1st (Thurs.) 25 51 −4.1 −21.6 17.2 465.3 89.4
2nd (Fri.) 31 73 1.9 0.4 3.4 0.2 0.8
3rd (Sat.) 26 65 −3.1 −7.6 9.9 57.8 23.8
4th (Sun.) 30 84 0.9 11.4 0.7 130.6 9.8
Sum 408 1016 0 0 129.7 2203.4 484.9
Average 29.1 72.6

x y Sxx Syy Sxy


* Some of the figures in this chapter are rounded
for the sake of printing, but calculations are
done using the full, unrounded values resulting
from the raw data unless otherwise stated.
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

Find the residual sum of squares, Se.


• y is the observed value.
• ŷ is the the estimated value based on our regression equation.
• y − ŷ is called the residual and is written as e.

Note: The caret in ŷ is affectionately called a hat, so we call this


parameter estimate y-hat.

High Predicted
temp. Actual iced iced tea
in °C tea orders orders Residuals (e) Squared residuals
 y  yˆ 
2
x y ŷ  ax  b y  yˆ
22nd (Mon.) 29 77 a × 29 + b 77 − (a × 29 + b) [77 − (a × 29 + b)] 2

23rd (Tues.) 28 62 a × 28 + b 62 − (a × 28 + b) [62 − (a × 28 + b)] 2

24th (Wed.) 34 93 a × 34 + b 93 − (a × 34 + b) [93 − (a × 34 + b)] 2

25th (Thurs.) 31 84 a × 31 + b 84 − (a × 31 + b) [84 − (a × 31 + b)] 2

26th (Fri.) 25 59 a × 25 + b 59 − (a × 25 + b) [59 − (a × 25 + b)] 2

27th (Sat.) 29 64 a × 29 + b 64 − (a × 29 + b) [64 − (a × 29 + b)] 2

28th (Sun.) 32 80 a × 32 + b 80 − (a × 32 + b) [80 − (a × 32 + b)] 2

29th (Mon.) 31 75 a × 31 + b 75 − (a × 31 + b) [75 − (a × 31 + b)] 2

30th (Tues.) 24 58 a × 24 + b 58 − (a × 24 + b) [58 − (a × 24 + b)] 2

31st (Wed.) 33 91 a × 33 + b 91 − (a × 33 + b) [91 − (a × 33 + b)] 2

1st (Thurs.) 25 51 a × 25 + b 51 − (a × 25 + b) [51 − (a × 25 + b)] 2

2nd (Fri.) 31 73 a × 31 + b 73 − (a × 31 + b) [73 − (a × 31 + b)] 2

3rd (Sat.) 26 65 a × 26 + b 65 − (a × 26 + b) [65 − (a × 26 + b)] 2

4th (Sun.) 30 84 a × 30 + b 84 − (a × 30 + b) [84 − (a × 30 + b)] 2

Sum 408 1016 408a + 14b 1016 − (408a + 14b) Se


Average 29.1 72.6 29.1a + b 72.6 − (29.1a + b) Se
=
= xa + b = y − ( xa + b ) 14

Se = 77 − ( a × 29 + b )  +  + 84 − ( a × 30 + b ) 
2 2
x y

The sum of the residuals squared is


called the residual sum of squares.
It is written as Se or RSS.
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

Differentiate Se with respect to a and b, and set it equal to 0.


When differentiating y = ( ax + b ) with respect to x, the result is
n −1

dy
= n ( ax + b ) × a .
n −1

dx

• Differentiate with respect to a.


dSe
= 2 77 − ( 29a + b )  × ( −29 ) +  + 2 84 − ( 30a + b )  × ( −30 ) = 0 u
da
• Differentiate with respect to b.
dSe
= 2 77 − ( 29a + b )  × ( −1) +  + 2 84 − ( 30a + b )  × ( −1) = 0 v
db

Rearrange u and v from the previous step.


Rearrange u.

2 77 − ( 29a + b )  × ( −29 ) +  + 2 84 − ( 30a + b )  × ( −30 ) = 0


77 − ( 29a + b )  × ( −29 ) +  + 84 − ( 30a + b )  × ( −30 ) = 0 Divide both sides by 2.
29 ( 29a + b ) − 77  +  + 30 ( 30a + b ) − 84  = 0 Multiply by -1.

( 29 × 29a + 29 × b − 29 × 77 ) +  + ( 30 × 30a + 30 × b − 30 × 84 ) = 0 multiply.

w ( 292 +  + 302 ) a + (29 +  + 30 ) b − (29 × 77 +  + 30 × 84 ) = 0 separate out


a and b .

Rearrange v.
2 77 − ( 29a + b )  × ( −1) +  + 2 84 − ( 30a + b )  × ( −1) = 0
2 77 − ( 29a + b )  × ( −1) +  + 2 84 − ( 30a + b )  × ( −1) = 0
77 − ( 29a + b )  × ( −1) +  + 84 − ( 30a + b )  × ( −1) = 0 Divide both sides by 2.
77 − ( 29a + b )  × ( −1) +  + 84 − ( 30a + b )  × ( −1) = 0
( 29a + b ) − 77  +  + ( 30a + b ) − 84  = 0 Multiply by -1.
( 29a + b ) − 77  +  + ( 30a + b ) − 84  = 0
(( 29 +  + 30 ) a + b
29 +  + 30 ) a + b +

+
+
+
b − ( 77 +  + 84 ) = 0
b − ( 77 +  + 84 ) = 0
separate out
a and b .
 
14 

(( 29 +  + 30 ) a + 14b − ( 77 +  + 84 ) = 0
14

29 +  + 30 ) a + 14b − ( 77 +  + 84 ) = 0
14b = ( 77 +  + 84 ) − ( 29 +  + 30 ) a subtract 14b from both sides
14b = ( 77 +  + 84 ) − ( 29 +  + 30 ) a and multiply by -1.
77 +  + 84 29 +  + 30
x b = 77 +  + 84 − 29 +  + 30 a Isolate b on the left side of the equation.
b= 14 − 14 a
14 14
b = y − xa The components in x are the
y b = y − xa averages of y and x .
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

Plug the value of b found in x into line w (w and x are the results
from Step 4).
x
 77 +  + 84 29 +  + 30 
w (29 2
)
+  + 302 a + ( 29 +  + 30 ) 
 14

14
a  − ( 29 × 77 +  + 30 × 84 ) = 0

Now a is the
only variable.

( 29 +  + 30 ) ( 77 +  + 84 ) − ( 29 +  + 30 )
2

(29 2
+  + 302 a + ) 14 14
a − ( 29 × 77 +  + 30 × 84 ) = 0

 ( 29 +  + 30 )  a + ( 29 +  + 30 ) ( 77 +  + 84 ) − 29 × 77 +  + 30 × 84 = 0
2

(
 292 +  + 302

) −
14  14
( ) Combine the
a terms.
 
 ( 29 +  + 30 )  a = 29 × 77 +  + 30 × 84 − ( 29 +  + 30 ) ( 77 +  + 84 )
2

(
 292 +  + 302

) −
14 
( ) 14
Transpose.
 

Rearrange the left side of the equation.


( 29 +  + 30 )
2

(29 2
+  + 302 − ) 14
( 29 +  + 30 )
2
( 29 +  + 30 ) ( 29 +  + 30 )
2 2

(
= 29 +  + 30
2 2
) − 2×
14
+
14
We add and subtract
14
.

2 The last term is


29 +  + 30  29 +  + 30 
( )
= 292 +  + 302 − 2 × ( 29 +  + 30 ) ×
14
+
 14  × 14
 multiplied by
14
.
14
29 +  + 30
( )
= 292 +  + 302 − 2 × ( 29 +  + 30 ) × x + ( x ) × 14
2
x=
14

( )
= 292 +  + 302 − 2 × ( 29 +  + 30 ) × x + ( x ) +  + ( x )

2 2

14

= 292 − 2 × 29 × x + ( x )  +  + 302 − 2 × 30 × x + ( x ) 
2 2

   
= ( 29 − x ) +  + ( 30 − x )
2 2

= Sxx

Rearrange the right side of the equation.


( 29 +  + 30 ) ( 77 +  + 84 )
( 29 × 77 +  + 30 × 84 ) − 14
29 +  + 30 77 +  + 84
= ( 29 × 77 +  + 30 × 84 ) − × × 14
14 14
= ( 29 × 77 +  + 30 × 84 ) − x × y × 14
= ( 29 × 77 +  + 30 × 84 ) − x × y × 14 − x × y × 14 + x × y × 14 We add and subtract x × y × 14 .
29 +  + 30 77 +  + 84
= ( 29 × 77 +  + 30 × 84 ) − × y × 14 − x × × 14 + x × y × 14
14 14
= ( 29 × 77 +  + 30 × 84 ) − ( 29 +  + 30 ) y − x ( 77 +  + 84 ) + x × y × 14
= ( 29 × 77 +  + 30 × 84 ) − ( 29 +  + 30 ) y − ( 77 +  + 84 ) x + x × y +  + x × y
  
14

= ( 29 − x ) ( 77 − y ) +  + ( 30 − x ) ( 84 − y )
= Sxy

Sxx a = Sxy
Sxy
z a= isolate a on the left side of the equation.
Sxx
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

Calculate the regression equation.

Sxy
From z in Step 5, a = . From y in Step 4, b= y − xa .
Sxx
If we plug in the values we calculated in Step 1,

 Sxx 484.9
a = S = 129.7 = 3.7
 xy
b = y − xa = 72.6 − 29.1 × 3.7 = −36.4

then the regression equation is

=y 3.7 x − 36.4 .

It’s that simple!

Note: The values shown are rounded for the sake of printing, but
the result (36.4) was calculated using the full, unrounded values.

the relationship between the


residuals and the slope a and
intercept b is always
Iced tea orders

sum of products of x and y Sxy


a= =
sum of squares of x Sxx
b = y − xa

this is true for any


linear regression.

High temp. (°C)

we did it!
we actually
did it!

nice
job!
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

Remember,
So, Miu, What the average

Iced tea orders


are the average temperature is x
values for the and the average
high temperature number of orders
and the iced tea is y . Now for a
orders? little magic.

High temp. (°C)


Let me
see... Without
looking, I can
tell you that the
regression equation
29.1°C and crosses the point
72.6 orders. es!
(29.1, 72.6). It do

The regression
equation can be...

...rearranged
like this.
That’s fr
om Step
4!
I see!

Now, if we
set x to  the
average value when x is the
( x )  we found average, so is y!
see what
before...
happens?
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

Step 3: Calculate the correlation coefficient (R ) and


r-square?

assess our population and assumptions.

next, we'll
determine the
accuracy of
the regression
equation we have
come up with.

why? what will


that tell us?

Our data and its regression equation example data and its regression equation
100 100
95 95
90 y = 3.7x − 36.4 90
Iced tea orders

Iced tea orders

85 85
80 80
75 75
70 70
65 65
60 60
55 55
50 50
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

High temp. (°C) High temp. (°C)

miu, can you see a


difference between
these two graphs?

well, the
graph on hmm...
the left has
a steeper
slope...
the dots are
closer to the
regression line
in the left graph.

anything
else? right!
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

When a regression right. Accuracy


equation is is important, but
accurate, the determining it by
estimated values looking at a graph
(the line) are is pretty subjective.
closer to the
observed values
the dots
(dots). are kind
the dots
are of far.
close.

so
accurate
means yes, that's true.
realistic?

that's why we
need R !

Ta-da!

Correlation
Coefficient

The correlation R is also called


coefficient from the pearson
earlier, right?
product moment
correlation
coefficient
in honor of
mathematician
karl pearson.

Right! we use R to represent an


index that measures the accuracy
of a regression equation. The index
compares our data to our predictions—
in other words, the measured x and y I see!
to the estimated x̂ and ŷ .
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

Here’s the equation.


We calculate these
like we did Sxx and
Sxy before.

sum of products y and yˆ Syyˆ


R= =
sum of squares of y × sum of squares of yˆ Syy × Syy
ˆˆ

1812.3
= = 0.9069
2203.4 × 1812.3
THAT’S NOT
TOO BAD!

this looks
familiar.
Regression function!

Actual Estimated
values values
( ŷ − yˆ ) ( y − y ) ( yˆ − yˆ ) ( y − yˆ )
2
(y − y )
2 2
y ŷ = 3.7x − 36.4 y −y ŷ − yˆ
22nd (Mon.) 77 72.0 4.4 –0.5 19.6 0.3 –2.4 24.6
23rd (Tues.) 62 68.3 −10.6 –4.3 111.8 18.2 45.2 39.7
24th (Wed.) 93 90.7 20.4 18.2 417.3 329.6 370.9 5.2
25th (Thurs.) 84 79.5 11.4 6.9 130.6 48.2 79.3 20.1
26th (Fri.) 59 57.1 −13.6 –15.5 184.2 239.8 210.2 3.7
27th (Sat.) 64 72.0 −8.6 –0.5 73.5 0.3 4.6 64.6
28th (Sun.) 80 83.3 7.4 10.7 55.2 114.1 79.3 10.6
29th (Mon.) 75 79.5 2.4 6.9 5.9 48.2 16.9 20.4
30th (Tues.) 58 53.3 −14.6 –19.2 212.3 369.5 280.1 21.6
31st (Wed.) 91 87.0 18.4 14.4 339.6 207.9 265.7 16.1
1st (Thurs.) 51 57.1 −21.6 –15.5 465.3 239.8 334.0 37.0
2nd (Fri.) 73 79.5 0.4 6.9 0.2 48.2 3.0 42.4
3rd (Sat.) 65 60.8 −7.6 –11.7 57.3 138.0 88.9 17.4
4th (Sun.) 84 75.8 11.4 3.2 130.6 10.3 36.6 67.6
Sum 1016 1016 0 0 2203.4 1812.3 1812.3 391.1
Average 72.6 72.6

y ŷ Syy Sŷ ŷ Sŷ ŷ Se

Se isn't necessary for


calculating R, but I included
it because we'll need it later.
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

...how much
if we square R, variance is
it's called the explained by
i am a
coefficient of coefficient of our regression
determination and determination.
equation.
is written as R2.

i am a
correla
R2 can be an i am a ti
coeffic on
correl ient,
indicator of... coeffic
ation too.
ient.

An R2 of zero indicates that


the outcome variable can’t so how high does R2
be reliably predicted from need to be for the
the predictor variable. regression equation
to be considered
accurate?

the higher the


accuracy of the
unfortunately, there
regression equation, is no universal
the closer the R2 value standard in statistics.
is to 1, and vice versa.

but generally we now try finding the


want a value of at value of R2.
least .5.

It's .8225.
sure
lowest... thing.
.5...
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

the value
of R2 for our
regression equation R2 =

Iced tea orders


is well over .5, so our .822
equation should be 5
able to estimate iced
tea orders relatively
accurately.
Yay
R 2!

High temp. (°C)

2
 correlation  a × Sxy S
R =
2
 = =1− e
 coefficient  Syy Syy

we've finished the


first three steps.
Jot this equation
down. R2 can be
calculated directly That’s
from these values. handy!
Using our Norns data,
1 − (391.1 / 2203.4) = hooray!
.8225 !

Samples and Populations


I meant to ask
Now to assess the you about that.
population and what population?
verify that our japan? earth?
assumptions
actually, the
are met!
population
we're talking
about isn't
people—
it's data.

oh...
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

here, look
High temp. (°C) Iced tea orders
at the tea how many days
room data 22nd (Mon.) 29 77 are there
23rd (Tues.) 28 62 with a high
again.
24th (Wed.) 34 93 temperature
25th (Thurs.) 31 84 of 31°C?
26th (Fri.) 25 59
27th (Sat.) 29 64
28th (Sun.) 32 80
29th (Mon.) 31 75
30th (Tues.) 24 58
31st (Wed.) 33 91
the 25th, 29th,
1st (Thurs.) 25 51
and 2nd...
2nd (Fri.) 31 73
so three.
3rd (Sat.) 26 65
4th (Sun.) 30 84

So...
I can make a
chart like this
from your
answer.

now, there must have been


consider ...these three days many others in the
are not the only past, and there will
that...
days in history be many more in the
with a high of 31°C, future, right?
are they?

29 t h

25th
of course.

2nd
The Manga Guide to Regression Analysis, © 2016 by Shin Takahashi and TREND-PRO Co., Ltd.

Population

29th sampling
sample
these three
days are a all days with high
sample... temperature of 31° 29th

25th
25th 2 nd
2nd

r s
r de s
ao r
te r de
ed ao
Ic te
e d
ea Ic
dt
Ice ders Hi
g for days with the

25
or h same number of
te Hig

th
29 d
m h

2
orders, the dots

th
p.

n
(°C te
are stacked. m p.
)
(°C
Hi

)
25
g (°C

29 d

th
2
h

th
n
te

...from the population of all


m
)
p.

days with a high temperature of


That makes
31°C. We use sample data when it’s
sense.
unlikely we’ll be able to get the
information we need from every
flip single member of the population.

Population
Population sample
high of 29°
sample 22nd 27th Population
high of 28°
23rd sample
Population high of 30°
sample s 4th
r
high of 26° de Population
3rd or
a sample
te
e d
Population Ic high of 32°
28th
3o
sample th
26 3 rd 22
Population
4

high of 25°
th
th

nd

26th 1st 25
31

sample
s

th
t
1s

23 29 28
t

24

27 high of 33°
Population
rd
th

th th
th
31st
2

Hig
nd

days with sample ht


Population
em
high of 24° p. sample
3oth (°C
)
high of 34°
24th

samples
represent the I see!
population.

thanks, risa.
I get it now.
good! on to
diagnostics,
then.
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas

4
E x pa nde d Objec t
Functionalit y

ECMAScript 6 focuses heavily on making


objects more useful, which makes sense
because nearly every value in JavaScript is
some type of object. The number of objects
developers use in an average JavaScript program
continues to increase as the complexity of JavaScript
applications increases. With more objects in a pro­
gram, it has become necessary to use them more
effectively.
ECMAScript 6 improves the use of objects in a number of ways, from
simple syntax extensions to options for manipulating and interacting with
them, and this chapter covers those improvements in detail.
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas

Object Categories
JavaScript uses different terminology to describe objects in the standard as
opposed to those added by execution environments, such as the browser.
The ECMAScript 6 specification has clear definitions for each object cate­
gory. It’s essential to understand this terminology to grasp the language as
a whole. The object categories are:
Ordinary objects Have all the default internal behaviors for objects in
JavaScript.
Exotic objects Have internal behavior that differs from the default in
some way.
Standard objects Defined by ECMAScript 6, such as Array, Date, and
so on. Standard objects can be ordinary or exotic.
Built-in objects Present in a JavaScript execution environment when a
script begins to execute. All standard objects are built-in objects.
I’ll use these terms throughout the book to explain the various objects
that ECMAScript 6 defines.

Object Literal Syntax Extensions


The object literal is one of the most popular patterns in JavaScript. JSON is
built on its syntax, and it’s in nearly every JavaScript file on the Internet. The
object literal’s popularity is due to its succinct syntax for creating objects that
would otherwise take several lines of code to create. Fortunately for develop­
ers, ECMAScript 6 makes object literals more powerful and even more suc­
cinct by extending the syntax in several ways.

Property Initializer Shorthand


In ECMAScript 5 and earlier, object literals were simply collections of
name-value pairs, meaning that some duplication could occur when prop­
erty values are initialized. For example:

function createPerson(name, age) {


return {
name: name,
age: age
};
}

The createPerson() function creates an object whose property names are


the same as the function parameter names. The result appears to be the
duplication of name and age, even though one is the name of an object prop­
erty and the other provides the value of that property. The key name in the
returned object is assigned the value contained in the variable name, and the
key age in the returned object is assigned the value contained in the vari­
able age.
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas

In ECMAScript 6, you can eliminate the duplication that exists around


property names and local variables by using the property initializer shorthand
syntax. When an object property name is the same as the local variable
name, you can simply include the name without a colon and value. For
example, createPerson() can be rewritten for ECMAScript 6 as follows:

function createPerson(name, age) {


return {
name,
age
};
}

When a property in an object literal only has a name, the JavaScript


engine looks in the surrounding scope for a variable of the same name. If
it finds one, that variable’s value is assigned to the same name on the object
literal. In this example, the object literal property name is assigned the value
of the local variable name.
Shorthand property syntax makes object literal initialization even more
succinct and helps to eliminate naming errors. Assigning a property with
the same name as a local variable is a very common pattern in JavaScript,
making this extension a welcome addition.

Concise Methods
ECMAScript 6 also improves the syntax for assigning methods to object
literals. In ECMAScript 5 and earlier, you must specify a name and then the
full function definition to add a method to an object, as follows:

var person = {
name: "Nicholas",
sayName: function() {
[Link]([Link]);
}
};

In ECMAScript 6, the syntax is made more concise by eliminating the


colon and the function keyword. That means you can rewrite the example
like this:

var person = {
name: "Nicholas",
sayName() {
[Link]([Link]);
}
};

This shorthand syntax, also called concise method syntax, creates a


method on the person object just as the previous example did. The sayName()
property is assigned an anonymous function expression and has all the
same characteristics as the ECMAScript 5 sayName() function. The one
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas

difference is that concise methods can use super (discussed in “Easy


Prototype Access with Super References” on page 139), whereas the non­
concise methods cannot.

No t e The name property of a method created using concise method shorthand is the name
used before the parentheses. In this example, the name property for [Link]() is
"sayName".

Computed Property Names


ECMAScript 5 and earlier could compute property names on object instances
when those properties were set with square brackets instead of dot notation.
The square brackets allow you to specify property names using variables and
string literals that might contain characters that would cause a syntax error if
they were used in an identifier. Here’s an example:

var person = {},


lastName = "last name";

person["first name"] = "Nicholas";


person[lastName] = "Zakas";

[Link](person["first name"]); // "Nicholas"


[Link](person[lastName]); // "Zakas"

Because lastName is assigned a value of "last name", both property names


in this example use a space, making it impossible to reference them using
dot notation. However, bracket notation allows any string value to be used
as a property name, so assigning "first name" to "Nicholas" and "last name" to
"Zakas" works.
Additionally, you can use string literals directly as property names in
object literals, like this:

var person = {
"first name": "Nicholas"
};

[Link](person["first name"]); // "Nicholas"

This pattern works for property names that are known ahead of time
and can be represented with a string literal. However, if the property name
"first name" were contained in a variable (as in the previous example) or
had to be calculated, there would be no way to define that property using
an object literal in ECMAScript 5.
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas

In ECMAScript 6, computed property names are part of the object


literal syntax, and they use the same square bracket notation that has
been used to reference computed property names in object instances. For
example:

let lastName = "last name";

let person = {
"first name": "Nicholas",
[lastName]: "Zakas"
};

[Link](person["first name"]); // "Nicholas"


[Link](person[lastName]); // "Zakas"

The square brackets inside the object literal indicate that the property
name is computed, so its contents are evaluated as a string. That means you
can also include expressions, such as the following:

var suffix = " name";

var person = {
["first" + suffix]: "Nicholas",
["last" + suffix]: "Zakas"
};

[Link](person["first name"]); // "Nicholas"


[Link](person["last name"]); // "Zakas"

These properties evaluate to "first name" and "last name", and you can
use those strings to reference the properties later. Anything you would put
inside square brackets while using bracket notation on object instances will
also work for computed property names inside object literals.

New Methods
One of the design goals of ECMAScript, beginning with ECMAScript 5,
was to avoid both creating new global functions and creating methods on
[Link]. Instead, when the developers want to add new methods to
the standard, they make those methods available on an appropriate exist­
ing object. As a result, the Object global has received an increasing number
of methods when no other objects are more appropriate. ECMAScript 6
introduces a couple of new methods on the Object global that are designed
to make certain tasks easier.
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas

The [Link]() Method


When you want to compare two values in JavaScript, you’re probably used
to using either the equals operator (==) or the identically equals operator
(===). Many developers prefer the latter to avoid type coercion during com­
parison. But even the identically equals operator isn’t entirely accurate. For
example, the values +0 and −0 are considered equal by ===, even though
they’re represented differently in the JavaScript engine. Also, NaN === NaN
returns false, which necessitates using isNaN() to detect NaN properly.
ECMAScript 6 introduces the [Link]() method to remedy the
remaining inaccuracies of the identically equals operator. This method
accepts two arguments and returns true if the values are equivalent. Two
values are considered equivalent when they’re the same type and have the
same value. Here are some examples:

[Link](+0 == -0); // true


[Link](+0 === -0); // true
[Link]([Link](+0, -0)); // false

[Link](NaN == NaN); // false


[Link](NaN === NaN); // false
[Link]([Link](NaN, NaN)); // true

[Link](5 == 5); // true


[Link](5 == "5"); // true
[Link](5 === 5); // true
[Link](5 === "5"); // false
[Link]([Link](5, 5)); // true
[Link]([Link](5, "5")); // false

In many cases, [Link]() works the same as the === operator. The only
differences are that +0 and −0 are considered not equivalent, and NaN is con­
sidered equivalent to NaN. But there’s no need to stop using equality opera­
tors. Choose whether to use [Link]() instead of == or === based on how
those special cases affect your code.

The [Link]() Method


Mixins are among the most popular patterns for object composition in
JavaScript. In a mixin, one object receives properties and methods from
another object. Many JavaScript libraries have a mixin method similar
to this:

function mixin(receiver, supplier) {


[Link](supplier).forEach(function(key) {
receiver[key] = supplier[key];
});

return receiver;
}
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas

The mixin() function iterates over the own properties of supplier and
copies them onto receiver (a shallow copy, where object references are
shared when property values are objects). This allows the receiver to gain
new properties without inheritance, as in this code:

function EventTarget() { /*...*/ }


[Link] = {
constructor: EventTarget,
emit: function() { /*...*/ },
on: function() { /*...*/ }
};

var myObject = {};


mixin(myObject, [Link]);

[Link]("somethingChanged");

Here, myObject receives behavior from the [Link] object.


This gives myObject the ability to publish events and subscribe to them using
the emit() and on() methods, respectively.
This mixin pattern became popular enough that ECMAScript 6
added the [Link]() method, which behaves the same way, accepting
a receiver and any number of suppliers and then returning the receiver.
The name change from mixin() to assign() reflects the actual operation
that occurs. Because the mixin() function uses the assignment operator (=),
it cannot copy accessor properties to the receiver as accessor properties.
The name [Link]() was chosen to reflect this distinction.

No t e Similar methods in various libraries might have other names for the same basic
functionality; popular alternates include the extend() and mix() methods. In addi-
tion to the [Link]() method, an [Link]() method was briefly added
in ECMAScript 6. The primary difference was that [Link]() also copied over
accessor properties, but the method was removed due to concerns over the use of super
(discussed in “Easy Prototype Access with Super References” on page 139).

You can use [Link]() anywhere you would have used the mixin()
function. Here’s an example:

function EventTarget() { /*...*/ }


[Link] = {
constructor: EventTarget,
emit: function() { /*...*/ },
on: function() { /*...*/ }
}

var myObject = {}
[Link](myObject, [Link]);

[Link]("somethingChanged");
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas

The [Link]() method accepts any number of suppliers, and the


receiver receives the properties in the order in which the suppliers are spec­
ified. That means the second supplier might overwrite a value from the first
supplier on the receiver, which is what happens in this code snippet:

var receiver = {};

[Link](receiver,
{
type: "js",
name: "[Link]"
},
{
type: "css"
}
);

[Link]([Link]); // "css"
[Link]([Link]); // "[Link]"

The value of [Link] is "css" because the second supplier over­


wrote the value of the first.
The [Link]() method isn’t a significant addition to ECMAScript 6,
but it does formalize a common function found in many JavaScript libraries.

Working w ith Acce ssor Prope r t ie s

Keep in mind that [Link]() doesn’t create accessor properties on the


receiver when a supplier has accessor properties. Because [Link]() uses
the assignment operator, an accessor property on a supplier will become a
data property on the receiver. For example:

var receiver = {},


supplier = {
get name() {
return "[Link]"
}
};

[Link](receiver, supplier);

var descriptor = [Link](receiver, "name");

[Link]([Link]); // "[Link]"
[Link]([Link]); // undefined

In this code, the supplier has an accessor property called name. After
using the [Link]() method, [Link] exists as a data property
with a value of "[Link]" because [Link] returned "[Link]" when
[Link]() was called.
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas

Duplicate Object Literal Properties


ECMAScript 5 strict mode introduced a check for duplicate object literal
properties that would throw an error if a duplicate was found. For example,
this code was problematic:

"use strict";

var person = {
name: "Nicholas",
name: "Greg" // syntax error in ES5 strict mode
};

When running in ECMAScript 5 strict mode, the second name property


causes a syntax error. But in ECMAScript 6, the duplicate property check
was removed. Strict and non-strict mode code no longer check for duplicate
properties. Instead, the last property of the given name becomes the prop­
erty’s actual value, as shown here:

"use strict";

var person = {
name: "Nicholas",
name: "Greg" // no error in ES6 strict mode
};

[Link]([Link]); // "Greg"

In this example, the value of [Link] is "Greg" because that’s the last
value assigned to the property.

Own Property Enumeration Order


ECMAScript 5 didn’t define the enumeration order of object properties; the
JavaScript engine vendors did. However, ECMAScript 6 strictly defines the
order in which own properties must be returned when they’re enumerated.
This affects how properties are returned using [Link]()
and [Link] (covered in Chapter 12). It also affects the order in which
properties are processed by [Link]().
The basic order for own property enumeration is:

1. All numeric keys in ascending order


2. All string keys in the order in which they were added to the object
3. All symbol keys (covered in Chapter 6) in the order in which they were
added to the object

Here’s an example:

var obj = {
a: 1,
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas

0: 1,
c: 1,
2: 1,
b: 1,
1: 1
};

obj.d = 1;

[Link]([Link](obj).join("")); // "012acbd"

The [Link]() method returns the properties in obj in


the order 0, 1, 2, a, c, b, d. Note that the numeric keys are grouped together
and sorted, even though they appear out of order in the object literal. The
string keys come after the numeric keys and appear in the order in which
they were added to obj. The keys in the object literal come first, followed by
any dynamic keys that were added later (in this case, d).

No t e The for-in loop still has an unspecified enumeration order because not all JavaScript
engines implement it the same way. The [Link]() method and [Link]()
are both specified to use the same (unspecified) enumeration order as for-in.

Although enumeration order is a subtle change to how JavaScript


works, it’s not uncommon to find programs that rely on a specific enumera­
tion order to work correctly. ECMAScript 6, by defining the enumeration
order, ensures that JavaScript code relying on enumeration will work cor­
rectly regardless of where it is executed.

Enhancements for Prototypes


Prototypes are the foundation of inheritance in JavaScript, and ECMA­
Script 6 continues to make prototypes more useful. Early versions of
JavaScript severely limited what you could do with prototypes. However,
as the language matured and developers became more familiar with
how prototypes work, it became clear that developers wanted more
control over prototypes and easier ways to work with them. As a result,
ECMAScript 6 introduced some improvements to prototypes.

Changing an Object’s Prototype


Normally, an object’s prototype is specified when the object is created, via
either a constructor or the [Link]() method. The idea that an object’s
prototype remains unchanged after instantiation was one of the predomi­
nant assumptions in JavaScript programming through ECMAScript 5.
ECMAScript 5 did add the [Link]() method for retriev­
ing the prototype of any given object, but it still lacked a standard way to
change an object’s prototype after instantiation.
ECMAScript 6 changes that assumption with the addition of the
[Link]() method, which allows you to change the prototype
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas

of any given object. The [Link]() method accepts two argu­


ments: the object whose prototype should change and the object that should
become the first argument’s prototype. For example:

let person = {
getGreeting() {
return "Hello";
}
};

let dog = {
getGreeting() {
return "Woof";
}
};

// prototype is person
let friend = [Link](person);
[Link]([Link]()); // "Hello"
[Link]([Link](friend) === person); // true

// set prototype to dog


[Link](friend, dog);
[Link]([Link]()); // "Woof"
[Link]([Link](friend) === dog); // true

This code defines two base objects: person and dog. Both objects have a
getGreeting() method that returns a string. The object friend first inherits
from the person object, meaning that getGreeting() outputs "Hello". When
the prototype becomes the dog object, [Link]() outputs "Woof"
because the original relationship to person is broken.
The actual value of an object’s prototype is stored in an internal-only
property called [[Prototype]]. The [Link]() method returns
the value stored in [[Prototype]] and [Link]() changes the
value stored in [[Prototype]]. However, these aren’t the only ways to work
with the [[Prototype]] value.

Easy Prototype Access with Super References


As previously mentioned, prototypes are very important in JavaScript, and a
lot of work went into making them easier to use in ECMAScript 6. Another
improvement is the introduction of super references, which make accessing
functionality on an object’s prototype easier. For example, to override a
method on an object instance so it also calls the prototype method of the
same name, you’d do the following in ECMAScript 5:

let person = {
getGreeting() {
return "Hello";
}
};
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas

let dog = {
getGreeting() {
return "Woof";
}
};

let friend = {
getGreeting() {
return [Link](this).[Link](this) + ", hi!";
}
};

// set prototype to person


[Link](friend, person);
[Link]([Link]()); // "Hello, hi!"
[Link]([Link](friend) === person); // true

// set prototype to dog


[Link](friend, dog);
[Link]([Link]()); // "Woof, hi!"
[Link]([Link](friend) === dog); // true

In this example, getGreeting() on friend calls the prototype method of


the same name. The [Link]() method ensures the correct
prototype is called, and then an additional string is appended to the out­
put. The additional .call(this) ensures that the this value inside the proto­
type method is set correctly.
Remembering to use [Link]() and .call(this) to call a
method on the prototype is a bit involved, so ECMAScript 6 introduced
super. At its simplest, super is a pointer to the current object’s prototype,
effectively the [Link](this) value. Knowing that, you can
simplify the getGreeting() method as follows:

let friend = {
getGreeting() {
// in the previous example, this is the same as:
// [Link](this).[Link](this)
return [Link]() + ", hi!";
}
};

The call to [Link]() is the same as [Link](this)


.[Link](this) in this context. Similarly, you can call any method on
an object’s prototype by using a super reference, as long as it’s inside a con­
cise method. Attempting to use super outside of concise methods results in a
syntax error, as in this example:

let friend = {
getGreeting: function() {
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas

// syntax error
return [Link]() + ", hi!";
}
};

This example uses a named property with a function, and the call to
[Link]() results in a syntax error because super is invalid in this
context.
The super reference is really helpful when you have multiple levels of
inheritance, because in that case, [Link]() no longer works in
all circumstances. For example:

let person = {
getGreeting() {
return "Hello";
}
};

// prototype is person
let friend = {
getGreeting() {
return [Link](this).[Link](this) + ", hi!";
}
};
[Link](friend, person);

// prototype is friend
let relative = [Link](friend);

[Link]([Link]()); // "Hello"
[Link]([Link]()); // "Hello, hi!"
[Link]([Link]()); // error!

When [Link]() is called, the call to [Link]()


results in an error. The reason is that this is relative, and the prototype
of relative is the friend object. When [Link]().call() is called
with relative as this, the process starts over again and continues to call
recursively until a stack overflow error occurs.
This problem is difficult to solve in ECMAScript 5, but with ECMA­
Script 6 and super, it’s easy:

let person = {
getGreeting() {
return "Hello";
}
};

// prototype is person
let friend = {
getGreeting() {
return [Link]() + ", hi!";
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas

}
};
[Link](friend, person);

// prototype is friend
let relative = [Link](friend);

[Link]([Link]()); // "Hello"
[Link]([Link]()); // "Hello, hi!"
[Link]([Link]()); // "Hello, hi!"

Because super references are not dynamic, they always refer to the correct
object. In this case, [Link]() always refers to [Link]()
regardless of how many other objects inherit the method.

A Formal Method Definition


Prior to ECMAScript 6, the concept of a “method” wasn’t formally defined.
Methods were just object properties that contained functions instead of
data. ECMAScript 6 formally defines a method as a function that has an
internal [[HomeObject]] property containing the object to which the method
belongs. Consider the following:

let person = {

// method
getGreeting() {
return "Hello";
}
};

// not a method
function shareGreeting() {
return "Hi!";
}

This code example defines person with a single method called


getGreeting(). The [[HomeObject]] for getGreeting() is person by virtue of
assigning the function directly to an object. However, the shareGreeting()
function has no [[HomeObject]] specified because it wasn’t assigned to an
object when it was created. In most cases, this difference isn’t important,
but it becomes very important when using super references.
Any reference to super uses the [[HomeObject]] to determine what to
do. The first step in the process is to call [Link]() on the
[[HomeObject]] to retrieve a reference to the prototype. Next, the prototype
is searched for a function with the same name. Then, the this binding is set
and the method is called. Here’s an example:

let person = {
getGreeting() {
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas

return "Hello";
}
};

// prototype is person
let friend = {
getGreeting() {
return [Link]() + ", hi!";
}
};
[Link](friend, person);

[Link]([Link]()); // "Hello, hi!"

Calling [Link]() returns a string, which combines the


value from [Link]() with ", hi!". The [[HomeObject]] of
[Link]() is friend, and the prototype of friend is person, so
[Link]() is equivalent to [Link](this).

Summary
Objects are the center of JavaScript programming, and ECMAScript 6
makes some helpful changes to objects that make them easier to work with
and more flexible.
ECMAScript 6 makes several changes to object literals. Shorthand
property definitions make assigning properties with the same names as
in-scope variables simpler. Computed property names allow you to specify
non-literal values as property names, which you’ve been able to do in other
areas of the language. Shorthand methods let you type far fewer characters
to define methods on object literals by completely omitting the colon and
function keyword. ECMAScript 6 loosens the strict mode check for duplicate
object literal property names as well, meaning two properties with the same
name can be in a single object literal without throwing an error.
The [Link]() method makes it easier to change multiple proper­
ties on a single object at once and is very useful when you use the mixin
pattern. The [Link]() method performs strict equality on any value,
effectively becoming a safer version of === when you’re working with spe­
cial JavaScript values.
ECMAScript 6 clearly defines enumeration order for own properties.
When enumerating properties, numeric keys always come first in ascending
order followed by string keys in insertion order and symbol keys in insertion
order.
It’s now possible to modify an object’s prototype after it’s been created
thanks to ECMAScript 6’s [Link]() method.
In addition, you can use the super keyword to call methods on an
object’s prototype. The this binding inside a method invoked using super
is set up to automatically work with the current value of this.
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

Web and Interne t Users


7
One area where Unix really shines is the
internet. Whether you want to run a fast
server from under your desk or simply surf
the web intelligently and efficiently, there’s little
you can’t embed in a shell script when it comes to
internet interaction.
Internet tools are scriptable, even though you might never have thought
of them that way. For example, FTP, a program that is perpetually trapped in
debug mode, can be scripted in some very interesting ways, as is explored in
Script #53 on page 148. Shell scripting can often improve the performance
and output of most command line utilities that work with some facet of the
internet.
In the first edition of this book, I (Dave) assured readers that the best
tool in the internet scripter’s toolbox is lynx; now we recommend using curl
instead. Both tools offer a text-only interface to the web, but while lynx tries
to offer a browser-like experience, curl is designed specifically for scripts,
dumping out the raw HTML source of any page you’d like to examine.
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

For example, the following shows the top seven lines of the source from
the home page of my film review blog [Link] courtesy
of curl:

$ curl -s [Link] | head -7


<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<link rel="profile" href="[Link] />
<link rel="pingback" href="[Link] />
<title>Dave On Film: Smart Movie Reviews from Dave Taylor</title>

You can accomplish the same result with lynx if curl isn’t available, but
if you have both, we recommend curl. That’s what we’ll work with in this
chapter.

Warning One limitation to the website scraper scripts in this chapter is that if the script depends
on a website that’s changed its layout or API in the time since this book was written,
the script might be broken. But if you can read HTML or JSON (even if you don’t
understand it all), you should be able to fix any of these scripts. The problem of track-
ing other sites is exactly why Extensible Markup Language (XML) was created: it
allows site developers to provide the content of a web page separately from the rules for
its layout.

#53 Downloading Files via FTP


One of the original killer apps of the internet was file transfer, and one of
the simplest solutions is FTP, File Transfer Protocol. At a fundamental level,
all internet interaction is based on file transfer, whether it’s a web browser
requesting an HTML document and its accompanying image files, a chat
server relaying lines of discussion back and forth, or an email message trav­
eling from one end of the earth to the other.
The original FTP program still lingers on, and while its interface is
crude, the program is powerful, capable, and well worth taking advantage
of. There are plenty of newer FTP programs around, notably FileZilla
([Link] or NcFTP ([Link] plus lots of
nice graphical interfaces you can add to FTP to make it more user-friendly.
With the help of some shell script wrappers, however, FTP does just fine for
uploading and downloading files.
For example, a typical use case for FTP is to download files from the
internet, which we’ll do with the script in Listing 7-1. Quite often, the files
will be located on anonymous FTP servers and will have URLs similar to
[Link]
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

The Code

#!/bin/bash

# ftpget--Given an ftp-style URL, unwraps it and tries to obtain the


# file using anonymous ftp.

anonpass="$LOGNAME@$(hostname)"

if [ $# -ne 1 ] ; then
echo "Usage: $0 [Link] >&2
exit 1
fi

# Typical URL: [Link]

if [ "$(echo $1 | cut -c1-6)" != "[Link] ] ; then


echo "$0: Malformed url. I need it to start with [Link] >&2;
exit 1
fi

server="$(echo $1 | cut -d/ -f3)"


filename="$(echo $1 | cut -d/ -f4-)"
basefile="$(basename $filename)"

echo ${0}: Downloading $basefile from server $server

 ftp -np << EOF


open $server
user ftp $anonpass
get "$filename" "$basefile"
quit
EOF

if [ $? -eq 0 ] ; then
ls -l $basefile
fi

exit 0

Listing 7-1: The ftpget script

How It Works
The heart of this script is the sequence of commands fed to the FTP pro­
gram starting at . This illustrates the essence of a batch file: a sequence of
instructions that’s fed to a separate program so that the receiving program
(in this case FTP) thinks the instructions are being entered by the user.
Here we specify the server connection to open, specify the anonymous user
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

(FTP) and whatever default password is specified in the script configura­


tion (typically your email address), and then get the specified file from the
FTP site and quit the transfer.

Running the Script


This script is straightforward to use: just fully specify an FTP URL, and it’ll
download the file to the current working directory, as Listing 7-2 details.

The Results

$ ftpget [Link]
ftpget: Downloading [Link] from server [Link]
-rw-r--r-- 1 taylor staff 4817 Aug 14 1998 [Link]

Listing 7-2: Running the ftpget script

Some versions of FTP are more verbose than others, and because it’s
not too uncommon to find a slight mismatch in the client and server pro­
tocol, those verbose versions of FTP can spit out scary-looking errors, like
Unimplemented command. You can safely ignore these. For example, Listing 7-3
shows the same script run on OS X.

$ ftpget [Link]
../[Link]/[Link]: Downloading [Link] from server ftp.
[Link]
Connected to [Link].
220 [Link] NcFTPd Server (licensed copy) ready.
331 Guest login ok, send your complete e-mail address as password.
230-You are user #2 of 16 simultaneous users allowed.
230-
230 Logged in anonymously.
Remote system type is UNIX.
Using binary mode to transfer files.
local: [Link] remote: unixstuff/[Link]
227 Entering Passive Mode (209,197,102,38,194,11)
150 Data connection accepted from [Link]:57849; transfer starting for
[Link] (4817 bytes).
100% |*******************************************************| 4817
67.41 KiB/s 00:00 ETA
226 Transfer completed.
4817 bytes received in 00:00 (63.28 KiB/s)
221 Goodbye.
-rw-r--r-- 1 taylor staff 4817 Aug 14 1998 [Link]

Listing 7-3: Running the ftpget script on OS X

If your FTP is excessively verbose and you’re on OS X, you can quiet it


down by adding a –V flag to the FTP invocation in the script (that is, instead
of FTP –n, use FTP –nV).
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

Hacking the Script


This script can be expanded to decompress the downloaded file automati­
cally (see Script #33 on page 101 for an example of how to do this) if it
has certain file extensions. Many compressed files such as .[Link] and .tar.bz2
can be decompressed by default with the system tar command.
You can also tweak this script to make it a simple tool for uploading a
specified file to an FTP server. If the server supports anonymous connec­
tions (few do nowadays, thanks to script kiddies and other delinquents, but
that’s another story), all you really have to do is specify a destination direc­
tory on the command line or in the script and change the get to a put in the
main script, as shown here:

ftp -np << EOF

open $server

user ftp $anonpass

cd $destdir

put "$filename"

quit
EOF

To work with a password-protected account, you could have the script


prompt for the password interactively by turning off echoing before a read
statement and then turning it back on when you’re done:

/bin/echo -n "Password for ${user}: "

stty -echo

read password

stty echo
echo ""

A smarter way to prompt for a password, however, is to just let the


FTP program do the work itself. This will happen as written in our script
because if a password is required to gain access to the specified FTP
account, the FTP program itself will prompt for it.

#54 Extracting URLs from a Web Page


A straightforward shell script application of lynx is to extract a list of URLs
on a given web page, which can be quite helpful when scraping the inter­
net for links. We said we’d switched from lynx to curl for this edition of the
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

book, but it turns out that lynx is about a hundred times easier to use for
this script (see Listing 7-4) than curl, because lynx parses HTML automati­
cally whereas curl forces you to parse the HTML yourself.
Don’t have lynx on your system? Most Unix systems today have package
managers such as yum on Red Hat, apt on Debian, and brew on OS X (though
brew is not installed by default) that you can use to install lynx. If you prefer
to compile lynx yourself, or just want to download prebuilt binaries, you can
download it from [Link]

The Code

#!/bin/bash

# getlinks--Given a URL, returns all of its relative and absolute links.


# Has three options: -d to generate the primary domains of every link,
# -i to list just those links that are internal to the site (that is,
# other pages on the same site), and -x to produce external links only
# (the opposite of –i).

if [ $# -eq 0 ] ; then
echo "Usage: $0 [-d|-i|-x] url" >&2
echo "-d=domains only, -i=internal refs only, -x=external only" >&2
exit 1
fi

if [ $# -gt 1 ] ; then
case "$1" in
 -d) lastcmd="cut -d/ -f3|sort|uniq"
shift
;;
-r) basedomain="[Link] $2 | cut -d/ -f3)/"
 lastcmd="grep \"^$basedomain\"|sed \"s|$basedomain||g\"|sort|uniq"
shift
;;
-a) basedomain="[Link] $2 | cut -d/ -f3)/"
 lastcmd="grep -v \"^$basedomain\"|sort|uniq"
shift
;;
*) echo "$0: unknown option specified: $1" >&2; exit 1
esac
else
 lastcmd="sort|uniq"
fi

lynx -dump "$1"|\


 sed -n '/^References$/,$p'|\
grep -E '[[:digit:]]+\.'|\
awk '{print $2}'|\
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

cut -d\? -f1|\


 eval $lastcmd

exit 0

Listing 7-4: The getlinks script

How It Works
When displaying a page, lynx shows the text of the page formatted as best
it can followed by a list of all hypertext references, or links, found on that
page. This script extracts just the links by using a sed invocation to print
everything after the "References" string in the web page text . Then the
script processes the list of links as needed based on the user-specified flags.
One interesting technique demonstrated by this script is the way the
variable lastcmd (, , , ) is set to filter the list of links that it extracts
according to the flags specified by the user. Once lastcmd is set, the amaz­
ingly handy eval command z is used to force the shell to interpret the con­
tent of the variable as if it were a command instead of a variable.

Running the Script


By default, this script outputs a list of all links found on the specified web
page, not just those that are prefaced with http:. There are three optional
command flags that can be specified to change the results, however: -d pro­
duces just the domain names of all matching URLs, -r produces a list of just
the relative references (that is, those references that are found on the same
server as the current page), and -a produces just the absolute references
(those URLs that point to a different server).

The Results
A simple request is a list of all links on a specified website home page, as
Listing 7-5 shows.

$ getlinks [Link] | head -10


[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]

Listing 7-5: Running the getlinks script


Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

Another possibility is to request a list of all domain names referenced


at a specific site. This time, let’s first use the standard Unix tool wc to check
how many links are found overall:

$ getlinks [Link] | wc -l
219

Amazon has 219 links on its home page. Impressive! How many differ­
ent domains does that represent? Let’s generate a list with the -d flag:

$ getlinks -d [Link] | head -10


[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]

Amazon doesn’t tend to point outside its own site, but there are some
partner links that creep onto the home page. Other sites are different, of
course.
What if we split the links on the Amazon page into relative and absolute
links?

$ getlinks -a [Link] | wc -l
51
$ getlinks -r [Link] | wc -l
222

As I expected, Amazon has four times more relative links pointing


inside its own site than it has absolute links, which would lead to a different
website. Gotta keep those customers on your own page!

Hacking the Script


You can see where getlinks could be quite useful as a site analysis tool. For
a way to enhance the script, stay tuned: Script #69 on page 209 comple­
ments this script nicely, allowing us to quickly check that all hypertext refer­
ences on a site are valid.

#55 Getting GitHub User Information


GitHub has grown to be a huge boon to the open source industry and open
collaboration across the world. Many system administrators and developers
have visited GitHub to pull down some source code or report an issue to
an open source project. Because GitHub is essentially a social platform for
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

developers, getting to know a user’s basic information quickly can be use­


ful. The script in Listing 7-6 prints some information about a given GitHub
user, and it gives a good introduction to the very powerful GitHub API.

The Code

#!/bin/bash
# githubuser--Given a GitHub username, pulls information about them.

if [ $# -ne 1 ]; then
echo "Usage: $0 <username>"
exit 1
fi

# The -s silences curl's normally verbose output.


 curl -s "[Link] | \
awk -F'"' '
/\"name\":/ {
print $4" is the name of the Github user."
}
/\"followers\":/{
split($3, a, " ")
sub(/,/, "", a[2])
print "They have "a[2]" followers."
}
/\"following\":/{
split($3, a, " ")
sub(/,/, "", a[2])
print "They are following "a[2]" other users."
}
/\"created_at\":/{
print "Their account was created on "$4"."
}
'
exit 0

Listing 7-6: The githubuser script

How It Works
I’ll admit, this is almost more of an awk script than a Bash script, but some­
times you need the extra horsepower awk provides for parsing (the GitHub
API returns JSON). We use curl to ask GitHub for the user , given as the
argument of the script, and pipe the JSON to awk. With awk, we specify a
field separator of the double quotes character, as this will make parsing the
JSON much simpler. Then we match the JSON with a handful of regular
expressions in the awk script and print the results in a user-friendly way.

Running the Script


The script accepts a single argument: the user to look up on GitHub. If the
username provided doesn’t exist, nothing will be printed.
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

The Results
When passed a valid username, the script should print a user-friendly sum­
mary of the GitHub user, as Listing 7-7 shows.

$ githubuser brandonprry
Brandon Perry is the name of the Github user.
They have 67 followers.
They are following 0 other users.
Their account was created on 2010-11-16T02:06:41Z.

Listing 7-7: Running the githubuser script

Hacking the Script


This script has a lot of potential due to the information that can be retrieved
from the GitHub API. In this script, we are only printing four values from the
JSON returned. Generating a “résumé” for a given user based on the infor­
mation provided by the API, like those provided by many web services, is just
one possibility.

#56 ZIP Code Lookup


To demonstrate a different technique for scraping the web, this time using
curl, let’s create a simple ZIP code lookup tool. Give the script in Listing 7-8
a ZIP code, and it’ll report the city and state the code belongs to. Easy
enough.
Your first instinct might be to use the official US Postal Service website,
but we’re going to tap into a different site, [Link] which config­
ures each ZIP code as its own web page so information is far easier to extract.

The Code

#!/bin/bash

# zipcode--Given a ZIP code, identifies the city and state. Use [Link],
# which has every ZIP code configured as its own web page.

baseURL="[Link]

/bin/echo -n "ZIP code $1 is in "

curl -s -dump "$baseURL/$[Link]" | \


grep -i '<title>' | \
cut -d\( -f2 | cut -d\) -f1

exit 0

Listing 7-8: The zipcode script


Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

How It Works
The URLs for ZIP code information pages on [Link] are struc­
tured consistently, with the ZIP code itself as the final part of the URL.

[Link]

This consistency makes it quite easy to create an appropriate URL for a


given ZIP code on the fly. The resultant page has the city name in the title,
conveniently denoted by open and close parentheses. So the page for the
previous example has this as its title:

<title>80304 Zip Code (Boulder, Colorado) Profile - homes, apartments,


schools, population, income, averages, housing, demographics, location,
statistics, residents and real estate info</title>

Long, but pretty easy to work with!

Running the Script


The standard way to invoke the script is to specify the desired ZIP code on
the command line. If it’s valid, the city and state will be displayed, as shown
in Listing 7-9.

The Results

$ zipcode 10010
ZIP code 10010 is in New York, New York
$ zipcode 30001
ZIP code 30001 is in <title>Page not found – [Link]</title>
$ zipcode 50111
ZIP code 50111 is in Grimes, Iowa

Listing 7-9: Running the zipcode script

Since 30001 isn’t a real ZIP code, the script generates a Page not found
error. That’s a bit sloppy, and we can do better.

Hacking the Script


The most obvious hack to this script would be to do something in response
to errors other than just spew out that ugly <title>Page not found – City-Data​
.com</title> sequence. More useful still would be to add a -a flag that tells the
script to display more information about the specified region, since http://
city​- data​.com/ offers quite a bit of information beyond city names—includ­
ing land area, population demographics, and home prices.
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

#57 Area Code Lookup


A variation on the theme of the ZIP code lookup in Script #56 is an area
code lookup. This one turns out to be really simple, because there are some
very easy-to-parse web pages with area codes. The page at [Link]
.org/ucsd-pages/[Link] is particularly easy to parse, not only because it is in
tabular form but also because the author has identified elements with HTML
attributes. For example, the line that defines area code 207 reads like so:

<tr><td align=center><a name="207">207</a></td><td align=center>ME</td><td


align=center>-5</td><td> Maine</td></tr>

We’ll use this site to look up area codes in the script in Listing 7-10.

The Code

#!/bin/bash

# areacode--Given a three-digit US telephone area code, identifies the city


# and state using the simple tabular data at Bennet Yee's website.

source="[Link]

if [ -z "$1" ] ; then
echo "usage: areacode <three-digit US telephone area code>"; exit 1
fi

# wc -c returns characters + end of line char, so 3 digits = 4 chars


if [ "$(echo $1 | wc -c)" -ne 4 ] ; then
echo "areacode: wrong length: only works with three-digit US area codes"
exit 1
fi

# Are they all digits?


if [ ! -z "$(echo $1 | sed 's/[[:digit:]]//g')" ] ; then
echo "areacode: not-digits: area codes can only be made up of digits";
exit 1
fi

# Now, finally, let's look up the area code...

result="$(curl -s -dump $source | grep "name=\"$1" | \


sed 's/<[^>]*>//g;s/^ //g' | \
cut -f2- -d\ | cut -f1 -d\( )"

echo "Area code $1 =$result"

exit 0

Listing 7-10: The areacode script


Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

How It Works
The code in this shell script is mainly input validation, ensuring the data
provided by the user is a valid area code. The core of the script is a curl
call , whose output is piped to sed for cleaning up and then trimmed with
cut to what we want to display to the user.

Running the Script


This script takes a single argument, the area code to look up information
for. Listing 7-11 gives examples of the script in use.

The Results

$ areacode 817
Area code 817 = N Cent. Texas: Fort Worth area
$ areacode 512
Area code 512 = S Texas: Austin
$ areacode 903
Area code 903 = NE Texas: Tyler

Listing 7-11: Testing the areacode script

Hacking the Script


A simple hack would be to invert the search so that you provide a state and
city and the script prints all of the area codes for the given city.

#58 Keeping Track of the Weather


Being inside an office or server room with your nose to a terminal all day
sometimes makes you yearn to be outside, especially when the weather is
really nice. [Link] is a great website, and it actually
offers a free API for developers if you sign up for an API key. With the API
key, we can write a quick shell script (shown in Listing 7-12) to tell us just
how nice (or poor) the weather is outside. Then we can decide whether
taking a quick walk is really a good idea.

The Code

#!/bin/bash
# weather--Gets the weather for a specific region or ZIP code.

if [ $# -ne 1 ]; then
echo "Usage: $0 <zipcode>"
exit 1
fi

apikey="b03fdsaf3b2e7cd23" # Not a real API key--you need your own.


Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

 weather=`curl -s \
"[Link]
 state=`xmllint --xpath \
//response/current_observation/display_location/full/text\(\) \
<(echo $weather)`
zip=`xmllint --xpath \
//response/current_observation/display_location/zip/text\(\) \
<(echo $weather)`
current=`xmllint --xpath \
//response/current_observation/temp_f/text\(\) \
<(echo $weather)`
condition=`xmllint --xpath \
//response/current_observation/weather/text\(\) \
<(echo $weather)`

echo $state" ("$zip") : Current temp "$current"F and "$condition" outside."

exit 0

Listing 7-12: The weather script

How It Works
In this script, we use curl to call the Wunderground API and save the HTTP
response data in the weather variable . We then use the xmllint (easily install­
able with your favorite package manager such as apt, yum, or brew) utility to
perform an XPath query on the data returned . We also use an interesting
syntax in Bash when calling xmllint with the <(echo $weather) at the end.
This syntax takes the output of the inner command and passes it to the
command as a file descriptor, so the program thinks it’s reading a real file.
After gathering all the relevant information from the XML returned, we
print a friendly message with general weather stats.

Running the Script


When you invoke the script, just specify the desired ZIP code, as Listing 7-13
shows. Easy enough!

The Results

$ weather 78727
Austin, TX (78727) : Current temp 59.0F and Clear outside.
$ weather 80304
Boulder, CO (80304) : Current temp 59.2F and Clear outside.
$ weather 10010
New York, NY (10010) : Current temp 68.7F and Clear outside.

Listing 7-13: Testing the weather script


Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

Hacking the Script


We have a secret. This script can actually take more than just ZIP codes.
You can also specify regions in the Wunderground API, such as CA/San_
Francisco (try it as an argument to the weather script!). However, this format
isn’t incredibly user-friendly: it requires underscores instead of spaces and
the slash in the middle. Adding the ability to ask for the state abbreviation
and the city and then replacing any spaces with underscores if no argu­
ments are passed would be a useful addition. As usual, this script could do
with more error-checking code. What happens if you enter a four-digit ZIP
code? Or a ZIP code that’s not assigned?

#59 Digging Up Movie Info from IMDb


The script in Listing 7-14 demonstrates a more sophisticated way to access
the internet through lynx, by searching the Internet Movie Database (http://
[Link]/) to find films that match a specified pattern. IMDb assigns
every movie, TV series, and even TV episode a unique numeric code; if
the user specifies that code, this script will return a synopsis of the film.
Otherwise, it will return a list of matching films from a title or partial title.
The script accesses different URLs depending on the type of query
(numeric ID or file title) and then caches the results so it can dig through
the page multiple times to extract different pieces of information. And it
uses a lot—a lot!—of calls to sed and grep, as you’ll see.

The Code

#!/bin/bash
# moviedata--Given a movie or TV title, returns a list of matches. If the user
# specifies an IMDb numeric index number, however, returns the synopsis of
# the film instead. Uses the Internet Movie Database.

titleurl="[Link]
imdburl="[Link]
tempout="/tmp/moviedata.$$"

 summarize_film()
{
# Produce an attractive synopsis of the film.

grep "<title>" $tempout | sed 's/<[^>]*>//g;s/(more)//'

grep --color=never -A2 '<h5>Plot:' $tempout | tail -1 | \


cut -d\< -f1 | fmt | sed 's/^/ /'

exit 0
}
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

trap "rm -f $tempout" 0 1 15

if [ $# -eq 0 ] ; then
echo "Usage: $0 {movie title | movie ID}" >&2
exit 1
fi

#########
# Checks whether we're asking for a title by IMDb title number.

nodigits="$(echo $1 | sed 's/[[:digit:]]*//g')"

if [ $# -eq 1 -a -z "$nodigits" ] ; then


lynx -source "$titleurl$1/combined" > $tempout
summarize_film
exit 0
fi

##########
# It's not an IMDb title number, so let's go with the search...

fixedname="$(echo $@ | tr ' ' '+')" # for the URL

url="$imdburl$fixedname"

 lynx -source $imdburl$fixedname > $tempout

# No results?

 fail="$(grep --color=never '<h1 class="findHeader">No ' $tempout)"

# If there's more than one matching title...

if [ ! -z "$fail" ] ; then
echo "Failed: no results found for $1"
exit 1
elif [ ! -z "$(grep '<h1 class="findHeader">Displaying' $tempout)" ] ; then
grep --color=never '/title/tt' $tempout | \
sed 's/</\
</g' | \
grep -vE '(.png|.jpg|>[ ]*$)' | \
grep -A 1 "a href=" | \
grep -v '^--$' | \
sed 's/<a href="\/title\/tt//g;s/<\/a> //' | \
 awk '(NR % 2 == 1) { title=$0 } (NR % 2 == 0) { print title " " $0 }' | \
sed 's/\/.*>/: /' | \
sort
fi

exit 0

Listing 7-14: The moviedata script


Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

How It Works
This script builds a different URL depending on whether the command
argument specified is a film title or an IMDb ID number. If the user speci­
fies a title by ID number, the script builds the appropriate URL, downloads
it, saves the lynx output to the $tempout file , and finally calls summarize_
film() . Not too difficult.
But if the user specifies a title, then the script builds a URL for a search
query on IMDb and saves the results page to the temp file. If IMDb can’t
find a match, then the <h1> tag with class="findHeader" value in the returned
HTML will say No results. That’s what the invocation at  checks. Then the
test is easy: if $fail is not zero length, the script can report that no results
were found.
If the result is zero length, however, that means that $tempfile now con­
tains one or more successful search results for the user’s pattern. These
results can all be extracted by searching for /title/tt as a pattern within the
source, but there’s a caveat: IMDb doesn’t make it easy to parse the results
because there are multiple matches to any given title link. The rest of that
gnarly sed|grep|sed sequence tries to identify and remove the duplicate
matches, while still retaining the ones that matter.
Further, when IMDb has a match like "Lawrence of Arabia (1962)", it
turns out that the title and year are two different HTML elements on two
different lines in the result. Ugh. We need the year, however, to differenti­
ate films with the same title that were released in different years. That’s
what the awk statement at  does, in a tricky sort of way.
If you’re unfamiliar with awk, the general format for an awk script is
(condition) { action }. This line saves odd-numbered lines in $title and
then, on even-numbered lines (the year and match type data), it outputs
both the previous and the current line’s data as one line of output.

Running the Script


Though short, this script is quite flexible with input formats, as can be seen
in Listing 7-15. You can specify a film title in quotes or as separate words,
and you can then specify the eight-digit IMDb ID value to select a specific
match.

The Results

$ moviedata lawrence of arabia


0056172: Lawrence of Arabia (1962)
0245226: Lawrence of Arabia (1935)
0390742: Mighty Moments from World History (1985) (TV Series)
1471868: Mystery Files (2010) (TV Series)
1471868: Mystery Files (2010) (TV Series)
1478071: Lawrence of Arabia (1985) (TV Episode)
1942509: Lawrence of Arabia (TV Episode)
1952822: Lawrence of Arabia (2011) (TV Episode)
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

$ moviedata 0056172
Lawrence of Arabia (1962)
A flamboyant and controversial British military figure and his
conflicted loyalties during his World War I service in the Middle East.

Listing 7-15: Running the moviedata script

Hacking the Script


The most obvious hack to this script would be to get rid of the ugly IMDb
movie ID numbers in the output. It would be straightforward to hide
the movie IDs (because the IDs as shown are rather unfriendly and prone
to mistyping) and have the shell script output a simple menu with unique
index values that can then be typed in to select a particular film.
In situations where there’s exactly one film matched (try moviedata
monsoon wedding), it would be great for the script to recognize that it’s the
only match, grab the movie number for the film, and reinvoke itself to get
that data. Give it a whirl!
A problem with this script, as with most scripts that scrape values from
a third-party website, is that if IMDb changes its page layout, the script
will break and you’ll need to rebuild the script sequence. It’s a lurking
bug but, with a site like IMDb that hasn’t changed in years, probably not a
dangerous one.

#60 Calculating Currency Values


In the first edition of this book, currency conversion was a remarkably diffi­
cult task requiring two scripts: one to pull conversion rates from a financial
website and save them in a special format and another to use that data to
actually do the conversion—say from US dollars to Euros. In the interven­
ing years, however, the web has become quite a bit more sophisticated, and
there’s no reason for us to go through tons of work when sites like Google
offer simple, script-friendly calculators.
For this version of the currency conversion script, shown in Listing 7-16,
we’re just going to tap into the currency calculator at [Link]
finance/converter.

The Code

#!/bin/bash

# convertcurrency--Given an amount and base currency, converts it to the


# specified target currency using ISO currency identifiers.
# Uses Google's finance converter for the heavy lifting:
# [Link]
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

if [ $# -eq 0 ]; then
echo "Usage: $(basename $0) amount currency to currency"
echo "Most common currencies are CAD, CNY, EUR, USD, INR, JPY, and MXN"
echo "Use \"$(basename $0) list\" for the full list of supported
currencies."
fi

if [ $(uname) = "Darwin" ]; then


LANG=C # For an issue on OS X with invalid byte sequences and lynx
fi
url="[Link]
tempfile="/tmp/converter.$$"
lynx=$(which lynx)

# Since this has multiple uses, let's grab this data before anything else.

currencies=$($lynx -source "$url" | grep "option value=" | \


cut -d\" -f2- | sed 's/">/ /' | cut -d\( -f1 | sort | uniq)

########### Deal with all non-conversion requests.

if [ $# -ne 4 ] ; then
if [ "$1" = "list" ] ; then
# Produce a listing of all currency symbols known by the converter.
echo "List of supported currencies:"
echo "$currencies"
fi
exit 0
fi

########### Now let's do a conversion.

if [ $3 != "to" ] ; then
echo "Usage: $(basename $0) value currency TO currency"
echo "(use \"$(basename $0) list\" to get a list of all currency values)"
exit 0
fi

amount=$1
basecurrency="$(echo $2 | tr '[:lower:]' '[:upper:]')"
targetcurrency="$(echo $4 | tr '[:lower:]' '[:upper:]')"

# And let's do it--finally!

$lynx -source "$url?a=$amount&from=$basecurrency&to=$targetcurrency" | \


grep 'id=currency_converter_result' | sed 's/<[^>]*>//g'

exit 0

Listing 7-16: The convertcurrency script


Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

How It Works
The Google Currency Converter has three parameters that are passed via
the URL itself: the amount, the original currency, and the currency you
want to convert to. You can see this in action in the following request to
convert 100 US dollars into Mexican pesos.

[Link]

In the most basic use case, then, the script expects the user to specify
each of those three fields as arguments, and then passes it all to Google in
the URL.
The script also has some usage messages that make it a lot easier to use.
To see those, let’s just jump to the demonstration portion, shall we?

Running the Script


This script is designed to be easy to use, as Listing 7-17 details, though a
basic knowledge of at least a few countries’ currencies is beneficial.

The Results

$ convertcurrency
Usage: convert amount currency to currency
Most common currencies are CAD, CNY, EUR, USD, INR, JPY, and MXN
Use "convertcurrency list" for the full list of supported currencies.
$ convertcurrency list | head -10
List of supported currencies:

AED United Arab Emirates Dirham


AFN Afghan Afghani
ALL Albanian Lek
AMD Armenian Dram
ANG Netherlands Antillean Guilder
AOA Angolan Kwanza
ARS Argentine Peso
AUD Australian Dollar
AWG Aruban Florin
$ convertcurrency 75 eur to usd
75 EUR = 84.5132 USD

Listing 7-17: Running the convertcurrency script

Hacking the Script


While this web-based calculator is austere and simple to work with, the output
could do with some cleaning up. For example, the output in Listing 7-17
doesn’t entirely make sense because it expresses US dollars with four digits
after the decimal point, even though cents only go to two digits. The correct
output should be 84.51, or if rounded up, 84.52. That’s something fixable in
the script.
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

While you’re at it, validating currency abbreviations would be benefi­


cial. And in a similar vein, changing those abbreviated currency codes to
proper currency names would be a nice feature, too, so you’d know that
AWG is the Aruban florin or that BTC is Bitcoin.

#61 Retrieving Bitcoin Address Information


Bitcoin has taken the world by storm, with whole businesses built around
the technology of the blockchain (which is the core of how Bitcoin works).
For anyone who works with Bitcoin at all, getting useful information about
specific Bitcoin addresses can be a major hassle. However, we can easily auto­
mate data gathering using a quick shell script, like that in Listing 7-18.

The Code

#!/bin/bash
# getbtcaddr--Given a Bitcoin address, reports useful information.

if [ $# -ne 1 ]; then
echo "Usage: $0 <address>"
exit 1
fi

base_url="[Link]

balance=`$(curl -s $base_url"addressbalance/"$1`)
recv=`$(curl -s $base_url"getreceivedbyaddress/"$1`)
sent=`$(curl -s $base_url"getsentbyaddress/"$1`)
first_made=`$(curl -s $base_url"addressfirstseen/"$1`)

echo "Details for address $1"


echo -e "\tFirst seen: "`date -d @$first_made`
echo -e "\tCurrent balance: "$balance
echo -e "\tSatoshis sent: "$sent
echo -e "\tSatoshis recv: "$recv

Listing 7-18: The getbtcaddr script

How It Works
This script automates a handful of curl calls to retrieve a few key pieces
of information about a given Bitcoin address. The API available on [Link]
[Link]/ gives us very easy access to all kinds of Bitcoin and block­
chain information. In fact, we don’t even need to parse the responses com­
ing back from the API, because it returns only single, simple values. After
making calls to retrieve the given address’s balance, how many BTC have
been sent and received by it, and when it was made, we print the informa­
tion to the screen for the user.
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

Running the Script


The script accepts only a single argument, the Bitcoin address we want infor­
mation about. However, I should mention that a string passed in that is not a
real Bitcoin address will simply print all 0s for the sent, received, and current
balance values, as well as a creation date in the year 1969. Any nonzero values
are in a unit called satoshis, which is the smallest denomination of a Bitcoin
(like pennies, but to many more decimal places).

The Results
Running the getbtcaddr shell script is simple as it only takes a single argu­
ment, the Bitcoin address to request data about, as Listing 7-19 shows.

$ getbtcaddr 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
Details for address 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
First seen: Sat Jan 3 12:15:05 CST 2009
Current balance: 6554034549
Satoshis sent: 0
Satoshis recv: 6554034549
$ getbtcaddr 1EzwoHtiXB4iFwedPr49iywjZn2nnekhoj
Details for address 1EzwoHtiXB4iFwedPr49iywjZn2nnekhoj
First seen: Sun Mar 11 11:11:41 CDT 2012
Current balance: 2000000
Satoshis sent: 716369585974
Satoshis recv: 716371585974

Listing 7-19: Running the getbtcaddr script

Hacking the Script


The numbers printed to the screen by default are pretty large and a bit
difficult for most people to comprehend. The scriptbc script (Script #9
on page 26) can easily be used to report in more reasonable units, such
as whole Bitcoins. Adding a scale argument to the script would be an easy
way for the user to get a more readable printout.

#62 Tracking Changes on Web Pages


Sometimes great inspiration comes from seeing an existing business and
saying to yourself, “That doesn’t seem too hard.” The task of tracking
changes on a website is a surprisingly simple way of collecting such inspira­
tional material. The script in Listing 7-20, changetrack, automates that task.
This script has one interesting nuance: when it detects changes to the site,
it emails the new web page to the user, rather than just reporting the infor­
mation on the command line.
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

The Code

#!/bin/bash

# changetrack--Tracks a given URL and, if it's changed since the last visit,
# emails the new page to the specified address.

sendmail=$(which sendmail)
sitearchive="/tmp/changetrack"
tmpchanges="$sitearchive/changes.$$" # Temp file
fromaddr="webscraper@[Link]"
dirperm=755 # read+write+execute for dir owner
fileperm=644 # read+write for owner, read only for others

trap "$(which rm) -f $tmpchanges" 0 1 15 # Remove temp file on exit

if [ $# -ne 2 ] ; then
echo "Usage: $(basename $0) url email" >&2
echo " tip: to have changes displayed on screen, use email addr '-'" >&2
exit 1
fi

if [ ! -d $sitearchive ] ; then
if ! mkdir $sitearchive ; then
echo "$(basename $0) failed: couldn't create $sitearchive." >&2
exit 1
fi
chmod $dirperm $sitearchive
fi

if [ "$(echo $1 | cut -c1-5)" != "http:" ] ; then


echo "Please use fully qualified URLs (e.g. start with '[Link] >&2
exit 1
fi

fname="$(echo $1 | sed 's/http:\/\///g' | tr '/?&' '...')"


baseurl="$(echo $1 | cut -d/ -f1-3)/"

# Grab a copy of the web page and put it in an archive file. Note that we
# can track changes by looking just at the content (that is, -dump, not
# -source), so we can skip any HTML parsing....

lynx -dump "$1" | uniq > $sitearchive/${fname}.new


if [ -f "$sitearchive/$fname" ] ; then
# We've seen this site before, so compare the two with diff.
diff $sitearchive/$fname $sitearchive/${fname}.new > $tmpchanges
if [ -s $tmpchanges ] ; then
echo "Status: Site $1 has changed since our last check."
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

else
echo "Status: No changes for site $1 since last check"
rm -f $sitearchive/${fname}.new # Nothing new...
exit 0 # No change--we're outta here.
fi
else
echo "Status: first visit to $1. Copy archived for future analysis."
mv $sitearchive/${fname}.new $sitearchive/$fname
chmod $fileperm $sitearchive/$fname
exit 0
fi

# If we're here, the site has changed, and we need to send the contents
# of the .new file to the user and replace the original with the .new
# for the next invocation of the script.

if [ "$2" != "-" ] ; then

( echo "Content-type: text/html"


echo "From: $fromaddr (Web Site Change Tracker)"
echo "Subject: Web Site $1 Has Changed"
 echo "To: $2"
echo ""

 lynx -s -dump $1 | \
 sed -e "s|src=\"|SRC=\"$baseurl|gi" \
 -e "s|href=\"|HREF=\"$baseurl|gi" \
 -e "s|$baseurl\/http:|http:|g"
) | $sendmail -t

else
# Just showing the differences on the screen is ugly. Solution?

diff $sitearchive/$fname $sitearchive/${fname}.new


fi

# Update the saved snapshot of the website.

mv $sitearchive/${fname}.new $sitearchive/$fname
chmod 755 $sitearchive/$fname
exit 0

Listing 7-20: The changetrack script

How It Works
Given a URL and a destination email address, this script grabs the web
page content and compares it to the content of the site from the previous
check. If the site has changed, the new web page is emailed to the specified
recipient, with some simple rewrites to try to keep the graphics and HREFs
working. These HTML rewrites starting at  are worth examining.
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

The call to curl retrieves the source of the specified web page , and
then sed performs three different translations. First, SRC=" is rewritten
as SRC="baseurl/  to ensure that any relative pathnames of the form
SRC="[Link]" are rewritten to work properly as full pathnames with the
domain name. If the domain name of the site is [Link]
the rewritten HTML would be SRC="[Link]
Likewise, HREF attributes are rewritten . Then, to ensure we haven’t bro­
ken anything, the third translation pulls the baseurl back out of the HTML
source in situations where it’s been erroneously added . For example,
HREF="[Link] is clearly
broken and must be fixed for the link to work.
Notice also that the recipient address is specified in the echo state­
ment  (echo "To: $2") rather than as an argument to sendmail. This is
a simple security trick: by having the address within the sendmail input
stream (which sendmail knows to parse for recipients because of the -t flag),
there’s no worry about users playing games with addresses like "joe;cat /
etc/passwd|mail larry". This is a good technique to use whenever you invoke
sendmail within shell scripts.

Running the Script


This script requires two parameters: the URL of the site being tracked (and
you’ll need to use a fully qualified URL that begins with http:// for it to
work properly) and the email address of the person (or comma-separated
group of people) who should receive the updated web page, as appropriate.
Or, if you’d prefer, just use – (a hyphen) as the email address, and the diff
output will instead be displayed on screen.

The Results
The first time the script sees a web page, the page is automatically mailed to
the specified user, as Listing 7-21 shows.

$ changetrack [Link] taylor@[Link]


Status: first visit to [Link] Copy archived for future
analysis.

Listing 7-21: Running the changetrack script for the first time

All subsequent checks on [Link] will produce an email


copy of the site only if the page has changed since the last invocation of
the script. This change can be as simple as a single typo fix or as complex
as a complete redesign. While this script can be used for tracking any web­
site, sites that don’t change frequently will probably work best: if the site is
the BBC News home page, checking for changes is a waste of CPU cycles
because this site is constantly updated.
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry

If a site has not changed when the script is invoked the second time, the
script has no output and sends no email to the specified recipient:

$ changetrack [Link] taylor@[Link]


$

Hacking the Script


An obvious deficiency in the current script is that it’s hardcoded to look
for http:// links, which means it will reject any HTTP web pages served over
HTTPS with SSL. Updating the script to work with both would require
some fancier regular expressions, but is totally possible!
Another change to make the script more useful could be to have a
granularity option that would allow users to specify that if only one line
has changed, the script should not consider the website updated. You could
implement this by piping the diff output to wc -l to count lines of output
changed. (Keep in mind that diff generally produces three lines of output
for each line changed.)
This script is also more useful when invoked from a cron job on a daily
or weekly basis. We have similar scripts that run every night and send us
updated web pages from various sites that we like to track.
A particularly interesting possibility is to modify this script to work off a
data file of URLs and email addresses, rather than requiring those as input
parameters. Drop that modified version of the script into a cron job, write
a web-based front end to the utility (similar to shell scripts in Chapter 8),
and you’ve just duplicated a function that some companies charge people
money to use. No kidding.
Founded in 1994, No Starch Press is one of the few remaining independent technical
book publishers. We publish the finest in geek entertainment—unique books on
technology, with a focus on open source, security, hacking, programming, alternative
operating systems, and LEGO®. Our titles have personality, our authors are passionate,
and our books tackle topics that people care about.

Vi si t W W W.N O STAR C H .C O M for a com p l ete cata l o g .



M or e from N o S tarch Pr ess!

No Starch Press 2016 Joy of coding bundle Sampler. Copyright © 2016 No Starch Press, Inc., All rights reserved. arduino project handbook © mark geddes. The Book
of R © Tilman M. Davies. Coding iPhone Apps for Kids © Gloria Winquist and Matt McCarthy. The CS Detective © Jeremy Kubica. Electronics for Kids © Øyvind Nydal Dahl.
The Manga Guide to Regression Analysis © Shin Takahashi and Trend-Pro Co., Ltd. Understanding ECMAScript 6 © Nicholas C. Zakas. Wicked Cool Shell Scripts, 2nd
Edition © Dave Taylor and Brandon Perry. No Starch Press and the No Starch Press logo are registered trademarks of No Starch Press, Inc. No part of this work may
be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording, or by any information storage or retrieval
system, without the prior written permission of No Starch Press, Inc.

You might also like