Joyofcoding Sampler
Joyofcoding Sampler
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
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
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
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
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
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
P i e zo arduino
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
#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();
}
}
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
}
2
NUMER ICS , AR ITHMETIC,
ASSIGNMENT, AND VECTOR S
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
R> log(x=243,base=3)
[1] 5
R> exp(x=3)
[1] 20.08554
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:
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
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.
R> x <- -5
R> x
[1] -5
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
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.
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.
This code creates and stores yet another vector, myvec3, which contains
the entries of myvec and myvec2 appended together in that order.
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> 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
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:
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:
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.
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
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:
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).
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> 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
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.
R> length(x=c(3,2,8,1))
[1] 4
R> length(x=5:13)
[1] 9
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
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:
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:
Again, the index in the square brackets can be the result of an appropri-
ate calculation, like so:
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.
• 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
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> foo[-c(1,3)]
[1] -2.3 4.0
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.
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:
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
32 Chapter 2
The Book of R, © 2016 by Tilman M. Davies
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
[1] [1]
[2] [2]
... ...
[n] [n]
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:
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.
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
R> foo
[1] 5.5 4.5 3.5 2.5 1.5 0.5
R> sum(foo)
[1] 18
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
Exercise 2.5
36 Chapter 2
The Book of R, © 2016 by Tilman M. Davies
2
Learning to Code in
a Playground
let numberOfWindows = 8 8
var numberOfWindowsOpen = 3 3
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!
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).
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:
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 = 3 3
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"
print(days) "365.25\n"
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:
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:
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.
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
Double(myAge) 11
v Int(multiplier) 0
w Int(1.9) 1
10 % 3 1
12 % 4 0
34 % 5 4
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
myMoney = 2 + 5 * 3 17
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
myMoney = 1 + ((2 + 3) * 4) 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.
a = a + b
becomes
a += b
// My favorite things
/*
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.
—1—
Search Problems
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.
3
How to Generate
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!
current
magnet moving
across wire
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.
Light bulb
turns on!
more
current
magnet moving
through coil of wire
Electronics for Kids, © 2016 by Øyvind Nydal Dahl
high-pressure
sluice gates water
power plant
water generator
dam
water wheel
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.
AC DC
Shopping List
magnets
alligator clips
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 multimeters 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
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.
positive electrode
electrolyte
negative electrode
lack of electrons
lots of electrons
lemon
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.
have six 1.5 V battery cells, as shown. Notice that the connec-
tors on the outside are attached to just two terminals.
9V
Shopping List
lemons
copper wire
alligator clips
nails
LED
Tools
multimeter
and leads
wire cutter
1 2 3 4
2 3
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?
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.
I got it!
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.
...we'll first
make this into a
Now... scatter plot...
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.
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?
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.
tch
scra
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.
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
Step 2
Step 3
What’s R ?
Calculate the correlation coefficient (R) and
assess our population and assumptions.
Step 4
diagnostics
regression
Step 5
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
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.
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
Let's find
a and b !
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.
Gulp
Find
• The sum of squares of x, Sxx: ( x − x )2
• The sum of squares of y, Syy: ( y − y)
2
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
Se = 77 − ( a × 29 + b ) + + 84 − ( a × 30 + b )
2 2
x y
dy
= n ( ax + b ) × a .
n −1
dx
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.
(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
.
( )
= 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
= ( 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.
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
=y 3.7 x − 36.4 .
Note: The values shown are rounded for the sake of printing, but
the result (36.4) was calculated using the full, unrounded values.
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
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.
next, we'll
determine the
accuracy of
the regression
equation we have
come up with.
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
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
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.
so
accurate
means yes, that's true.
realistic?
that's why we
need R !
Ta-da!
Correlation
Coefficient
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
...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.
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 =
2
correlation a × Sxy S
R =
2
= =1− e
coefficient Syy Syy
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.
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
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
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
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.
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]);
}
};
var person = {
name: "Nicholas",
sayName() {
[Link]([Link]);
}
};
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".
var 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
let person = {
"first name": "Nicholas",
[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 person = {
["first" + suffix]: "Nicholas",
["last" + suffix]: "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
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.
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:
[Link]("somethingChanged");
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:
var myObject = {}
[Link](myObject, [Link]);
[Link]("somethingChanged");
Understanding ECMAScript 6, © 2016 by Nicholas C. Zakas
[Link](receiver,
{
type: "js",
name: "[Link]"
},
{
type: "css"
}
);
[Link]([Link]); // "css"
[Link]([Link]); // "[Link]"
[Link](receiver, supplier);
[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
"use strict";
var person = {
name: "Nicholas",
name: "Greg" // syntax error in ES5 strict mode
};
"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.
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"
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.
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
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.
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!";
}
};
let friend = {
getGreeting() {
// in the previous example, this is the same as:
// [Link](this).[Link](this)
return [Link]() + ", hi!";
}
};
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!
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.
let person = {
// method
getGreeting() {
return "Hello";
}
};
// not a method
function shareGreeting() {
return "Hi!";
}
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);
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
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:
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.
The Code
#!/bin/bash
anonpass="$LOGNAME@$(hostname)"
if [ $# -ne 1 ] ; then
echo "Usage: $0 [Link] >&2
exit 1
fi
if [ $? -eq 0 ] ; then
ls -l $basefile
fi
exit 0
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
The Results
$ ftpget [Link]
ftpget: Downloading [Link] from server [Link]
-rw-r--r-- 1 taylor staff 4817 Aug 14 1998 [Link]
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]
open $server
cd $destdir
put "$filename"
quit
EOF
stty -echo
read password
stty echo
echo ""
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
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
exit 0
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.
The Results
A simple request is a list of all links on a specified website home page, as
Listing 7-5 shows.
$ 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:
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
The Code
#!/bin/bash
# githubuser--Given a GitHub username, pulls information about them.
if [ $# -ne 1 ]; then
echo "Usage: $0 <username>"
exit 1
fi
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.
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.
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]
exit 0
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]
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
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.
We’ll use this site to look up area codes in the script in Listing 7-10.
The Code
#!/bin/bash
source="[Link]
if [ -z "$1" ] ; then
echo "usage: areacode <three-digit US telephone area code>"; exit 1
fi
exit 0
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.
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
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
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)`
exit 0
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.
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.
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.
exit 0
}
Wicked Cool Shell Scripts, 2nd Edition, © 2016 by Dave Taylor and Brandon Perry
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.
##########
# It's not an IMDb title number, so let's go with the search...
url="$imdburl$fixedname"
# No results?
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
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.
The Results
$ 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.
The Code
#!/bin/bash
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
# Since this has multiple uses, let's grab this data before anything else.
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
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:]')"
exit 0
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?
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:
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`)
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
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
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
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
# 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....
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.
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?
mv $sitearchive/${fname}.new $sitearchive/$fname
chmod 755 $sitearchive/$fname
exit 0
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.
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.
Listing 7-21: Running the changetrack script for the first time
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:
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.