text:
# WEEK 3
*Intermediate JavaScript (Part 1)* {ignore=true}
________________________________________________________________________________

[**Asynchronous JS Learning Objectives**](#asynchronous-js-learning-objectives)
- [Better Late Than Never: An Intro to Asynchronous JavaScript](#better-late-than-never-an-intro-to-asynchronous-javascript)
  - [Synchronous vs asynchronous code](#synchronous-vs-asynchronous-code)
  - [Why do we need asynchronous code?](#why-do-we-need-asynchronous-code)
- [All in Good Time: Setting Timeouts and Intervals](#all-in-good-time-setting-timeouts-and-intervals)
  - [Time-out! What are the arguments?](#time-out-what-are-the-arguments)
  - [Cancelling timeouts](#cancelling-timeouts)
  - [Running Intervals](#running-intervals)
- [Hanging by a Single Thread: A Yarn on JavaScript's Execution](#hanging-by-a-single-thread-a-yarn-on-javascripts-execution)
  - [Single-threaded vs multi-threaded execution](#single-threaded-vs-multi-threaded-execution)
  - [Keeping the thread from unraveling](#keeping-the-thread-from-unraveling)
- [Stacking the Odds in our Favor: the Call Stack](#stacking-the-odds-in-our-favor-the-call-stack)
  - [The call stack](#the-call-stack)
  - [The practical consequences of the call stack](#the-practical-consequences-of-the-call-stack)
- [An Unexpected Turn of Events: the event loop and Message Queue](#an-unexpected-turn-of-events-the-event-loop-and-message-queue)
  - [The event loop](#the-event-loop)
- [Reading Between the Lines: Getting User Input and Callback Chaining](#reading-between-the-lines-getting-user-input-and-callback-chaining)
  - [Node's readline module](#nodes-readline-module)
  - [Callback chaining](#callback-chaining)
- [Timeout Project](#timeout-project)
- [Guessing Game Project](#guessing-game-project)
  - [The Objective](#the-objective)
  - [Phase I: Too High? Too Low? Who knows.](#phase-i-too-high-too-low-who-knows)
  - [Phase II: Making it Random](#phase-ii-making-it-random)
  - [Bonus: Limiting the number of turns](#bonus-limiting-the-number-of-turns)

[**Node.js Learning Objectives**](#nodejs-learning-objectives)
[**Git Learning Objectives**](#git-learning-objectives)
- [A Tale of Two Runtimes: Node.js vs Browser](#a-tale-of-two-runtimes-nodejs-vs-browser)
  - [Same specification, different implementation](#same-specification-different-implementation)
  - [Differences between Node.js and browsers](#differences-between-nodejs-and-browsers)
- [The Ins and Outs of File I/O in Node](#the-ins-and-outs-of-file-io-in-node)
  - [The fs module](#the-fs-module)
  - [Fancy File I/O](#fancy-file-io)
- ["Gitting" Started With Git!](#gitting-started-with-git)
  - [A little history](#a-little-history)
  - [Git basics](#git-basics)
  - [Connecting with the world via GitHub](#connecting-with-the-world-via-github)
- [Browsing Your Git Repository](#browsing-your-git-repository)
  - [Seeing changes in real time](#seeing-changes-in-real-time)
  - [Time travel](#time-travel)
- [Git Do-Overs: Reset & Rebase](#git-do-overs-reset-rebase)
  - [Resetting the past](#resetting-the-past)
  - [Starting small: Soft resets](#starting-small-soft-resets)
  - [Getting riskier: Mixed resets](#getting-riskier-mixed-resets)
  - [Red alert! Hard resets](#red-alert-hard-resets)
  - [Rebase: An alternative form of time travel](#rebase-an-alternative-form-of-time-travel)
  - [Okay, rebasing is risky! Show me anyway.](#okay-rebasing-is-risky-show-me-anyway)
  - [One last warning & the "Golden Rule of Git"](#one-last-warning-the-golden-rule-of-git)
- [Git Merge Conflicts & You](#git-merge-conflicts-you)
  - [What is a "merge conflict"?](#what-is-a-merge-conflict)
  - [Resolving a merge conflict](#resolving-a-merge-conflict)
  - [Conflict Resolution](#conflict-resolution)
  - [Back on solid ground](#back-on-solid-ground)
- ["Scrum" Stands For ... Nothing!](#scrum-stands-for-nothing)
  - [The standard Scrum process](#the-standard-scrum-process)
  - [The Scrum practices](#the-scrum-practices)
  - [Scrum roles](#scrum-roles)
  - [Scrum activities. Scrum artifacts.](#scrum-activities-scrum-artifacts)
  - [Running the sprint](#running-the-sprint)
- [Let's Talk About Sprints](#lets-talk-about-sprints)
  - [Put your sprint in a pretty timebox](#put-your-sprint-in-a-pretty-timebox)
  - [Take advantage of this short-term deal!](#take-advantage-of-this-short-term-deal)
  - [The duration remains the same](#the-duration-remains-the-same)
  - [Keeping your eye on the goal](#keeping-your-eye-on-the-goal)
  - [What is "done"?](#what-is-done)
- [Requirements and User Stories](#requirements-and-user-stories)
  - [A PBI is a conversation waiting to happen](#a-pbi-is-a-conversation-waiting-to-happen)
  - [Refining the refinements](#refining-the-refinements)
  - [User stories](#user-stories)
  - [How much detail is enough?](#how-much-detail-is-enough)
  - [Good stories are INVESTments](#good-stories-are-investments)
- [Censor Project](#censor-project)
  - [The Objective](#the-objective-1)
  - [Phase 1: Setting Up and Censoring Sentences](#phase-1-setting-up-and-censoring-sentences)
  - [Phase 2: Interacting with the user](#phase-2-interacting-with-the-user)
  - [Phase 3: Parsing the dictionary](#phase-3-parsing-the-dictionary)
  - [Bonus: Pick a file, any file](#bonus-pick-a-file-any-file)
- [Global Replace Project](#global-replace-project)
  - [The Objective](#the-objective-2)
  - [Phase 1: Setup and Command Line Arguments](#phase-1-setup-and-command-line-arguments)
  - [Phase 2: Simple string replacement and file reading](#phase-2-simple-string-replacement-and-file-reading)
  - [Phase 3:](#phase-3)
  - [Bonus: Replacing the first 'n' occurrences](#bonus-replacing-the-first-n-occurrences)
- [Repo Madness Project: Managing Your Code With Git](#repo-madness-project-managing-your-code-with-git)
  - [Phase 1: Laying the foundation](#phase-1-laying-the-foundation)
  - [Phase 2: Exploring our timeline](#phase-2-exploring-our-timeline)
  - [Phase 2a: Looking around without moving](#phase-2a-looking-around-without-moving)
  - [Phase 2b: Our first steps through time](#phase-2b-our-first-steps-through-time)
  - [Phase 3: Changing history](#phase-3-changing-history)
  - [Phase 4: Choose your fate](#phase-4-choose-your-fate)

[**Command Line Interface Basics Learning Objectives**](#command-line-interface-basics-learning-objectives)
- [Navigating Your Filesystem](#navigating-your-filesystem)
  - [Getting the lay of the land](#getting-the-lay-of-the-land)
  - [Getting around](#getting-around)
  - [Making changes](#making-changes)
- [Common Tasks On The Command Line](#common-tasks-on-the-command-line)
  - [`grep` marks the spot](#grep-marks-the-spot)
  - [Teach yourself anything](#teach-yourself-anything)
  - [Command redirection](#command-redirection)
  - [Editing files directly from the CLI](#editing-files-directly-from-the-cli)
  - [Bringing the internet into your terminal](#bringing-the-internet-into-your-terminal)
- [Understanding The Shell](#understanding-the-shell)
  - [No turtles here!](#no-turtles-here)
  - [Customizing your environment](#customizing-your-environment)
  - [To Login or Not to Login](#to-login-or-not-to-login)
  - [No turtles here!](#no-turtles-here-1)
  - [Customizing your environment](#customizing-your-environment-1)
  - [To Login or Not to Login](#to-login-or-not-to-login-1)
- [Bash Permissions & Scripting](#bash-permissions-scripting)
  - [Understanding `sudo` and file permissions](#understanding-sudo-and-file-permissions)
  - [Bash scripting](#bash-scripting)
  - [Understanding `sudo` and file permissions](#understanding-sudo-and-file-permissions-1)
  - [Bash scripting](#bash-scripting-1)

[**Recursion Learning Objectives**](#recursion-learning-objectives)
- [Re-learning Functions With Recursion](#re-learning-functions-with-recursion)
  - [Re-what now?](#re-what-now)
  - [Two cases](#two-cases)
  - [A recursive example](#a-recursive-example)
- [When To Hold & When To Fold(Fold(Fold())): Recursion vs. Iteration](#when-to-hold-when-to-foldfoldfold-recursion-vs-iteration)
  - [A deeper dive into recursion](#a-deeper-dive-into-recursion)
  - [When to iterate, when to recur](#when-to-iterate-when-to-recur)
  - [Compare these approaches](#compare-these-approaches)
- [Recursion Problems](#recursion-problems)
- [Debugging A Stack Overflow](#debugging-a-stack-overflow)

[**JS Trivia Learning Objectives**](#js-trivia-learning-objectives)
- [Stop Feeling Iffy about IIFEs!](#stop-feeling-iffy-about-iifes)
  - [Quick review of function expressions](#quick-review-of-function-expressions)
  - [IIFE syntax](#iife-syntax)
  - [IIFEs keep functions and variables private](#iifes-keep-functions-and-variables-private)
- [Interpolation in JavaScript](#interpolation-in-javascript)
  - [Let's talk syntax](#lets-talk-syntax)
- [Object Keys in JavaScript](#object-keys-in-javascript)
  - [A symbol of unique freedom](#a-symbol-of-unique-freedom)
  - [Symbols vs. Strings as keys in Objects](#symbols-vs-strings-as-keys-in-objects)
  - [Primitive Data Types in Depth](#primitive-data-types-in-depth)
  - [Data types in JavaScript](#data-types-in-javascript)
  - [Methods and the object type](#methods-and-the-object-type)
  - [Primitives with object wrappers](#primitives-with-object-wrappers)
- [Unassigned Variables in JavaScript](#unassigned-variables-in-javascript)
  - [The default value of variables](#the-default-value-of-variables)
  - [The difference between default values and hoisting](#the-difference-between-default-values-and-hoisting)
- [WhiteBoarding Problem](#whiteboarding-problem)
  - [The Question](#the-question)
  - [The Answer](#the-answer)

________________________________________________________________________________
# WEEK-03 DAY-1
*Asynchronous Functions* {ignore=true}
________________________________________________________________________________
# Asynchronous JS Learning Objectives

Below is a complete list of the terminal learning objectives for this lesson.
When you complete this lesson, you should be able to perform each of the
following objectives. These objectives capture how you may be evaluated on the
assessment for this lesson.

1. Identify JavaScript as a language that utilizes an event loop model
2. Identify JavaScript as a single threaded language
3. Describe the difference between asynchronous and synchronous code
4. Execute the asynchronous function setTimeout with a callback.
5. Given the function "function asyncy(cb) { setTimeout(cb, 1000);
   console.log("async") }" and the function "function callback() {
   console.log("callback"); }", predict the output of "asyncy(callback);"
6. Use setInterval to have a function execute 10 times with a 1 second period.
   After the 10th cycle, clear the interval.
7. Write a program that accepts user input using Node’s readline modulrminal learning objectives for this lesson.
When you complete this lesson, you should be able to perform each of the
following objectives. These objectives capture how you may be evaluated on the
assessment for this lesson.

1. Identify JavaScript as a language that utilizes an event loop model
2. Identify JavaScript as a single threaded language
3. Describe the difference between asynchronous and synchronous code
4. Execute the asynchronous function setTimeout with a callback.
5. Given the function "function asyncy(cb) { setTimeout(cb, 1000);
   console.log("async") }" and the function "function callback() {
   console.log("callback"); }", predict the output of "asyncy(callback);"
6. Use setInterval to have a function execute 10 times with a 1 second period.
   After the 10th cycle, clear the interval.
7. Write a program that accepts user input using Node’s readline module
________________________________________________________________________________
# Better Late Than Never: An Intro to Asynchronous JavaScript

Every programming language has features that distinguish it from the rest of the
pack. The heavy usage of callbacks is one such pattern that characterizes
JavaScript. We pass callbacks as arguments as a way to execute a series of
commands at a later time. However, what happens if there is no guarantee exactly
_when_ that callback is executed? We've explored callbacks extensively thus far
in the course, but it's time to add another wrinkle - how can we utilize
callbacks _asynchronously_?

When you finish this article, you should be able to:

- Describe the difference between synchronous and asynchronous code
- Give one example illustrating why we would need to deal with asynchronous code

## Synchronous vs asynchronous code

Let's begin by exploring the difference between **synchronous** and
**asynchronous** code. Luckily, you are already familiar with the former. In
fact, all of the code you have written thus far in the course has been
synchronous.

### Synchronous

If code is **synchronous**, that means that there is an inherent order among the
commands and this order of execution is _guaranteed_.

Here is a simple example of synchronous code:

```javascript
console.log("one");
console.log("two");
console.log("three");
```

This seems trivial, but it is important to recognize. It is guaranteed that
'one' will be printed before 'two' and 'two' will be printed before 'three'.
Taking this a step further, you also know that the order of execution may not
always simply be the positional order of the lines in the code:

```javascript
let foo = function() {
  console.log("two");
};

console.log("one");
foo();
console.log("three");
```

Although the command `console.log("two")` appears before `console.log("one")` in
terms of the line numbers of the script, we know that this code will still print
'one', 'two', 'three' because we understand the rules of JavaScript evaluation.
Although the execution may jump around to different line numbers as we call and
return from functions, the above code is still synchronous. The above code is
synchronous because we can predict with total certainty the relative order of
the print statements.

### Asynchronous

If code is **asynchronous**, that means that there is no guarantee in the total
order that commands are executed. Asynchronous is the opposite of synchronous.

Since this is our first encounter with asynchronicity, we'll need to introduce a
new function to illustrate this behavior. The [setTimeout][set-timeout] method
will execute a callback after a given amount of time. We can pass a callback and
an amount of time in milliseconds as arguments to the method:

```javascript
setTimeout(function() {
  console.log("time is up!");
}, 1500);
```

If we execute the above code, 'time is up!' will be print after about one and a
half seconds. Paste the above code to a `.js` file and execute it to see this
behavior for yourself!

Let's add some other print statements into the mix:

```javascript
console.log("start");

setTimeout(function() {
  console.log("time is up!");
}, 1500);

console.log("end");
```

If we execute the above snippet, we will see the output in this order inside of
our terminal:

```plaintext
start
end
time is up!
```

Surprised? Although we call the function `setTimeout`, it does not block
execution of the lines after it (like `console.log("end")`). That is, while the
timer ticks down for the `setTimeout` we will continue to execute other code.
This is because `setTimeout` is **asynchronous**!

#### Can't believe it's async?

The healthy skeptic may notice that we defined the term _asynchronous_ code as
code where there is no guaranteed order among its commands - but, couldn't we
just specify timeout periods such that we _could_ orchestrate some order to the
code? The skeptic may write the following code arguing that we can predict a
print order of 'first' then 'last':

```javascript
setTimeout(function() {
  console.log("last");
}, 3000);

setTimeout(function() {
  console.log("first");
}, 1000);
```

Surely if we wait 3 seconds for 'last' and only 1 second for 'first', then we'll
see 'first' then 'last', right? By providing sufficiently large timeout periods,
hasn't the skeptic proven `setTimeout` to be synchronous?

The answer is a resounding **no; we cannot treat `setTimeout` as synchronous
under any circumstance**. The reason is that the time period specified to
`setTimeout` is not exact, rather it is the _minimum_ amount of time that will
elapse before executing the callback (cue the title of this article). If we set
a timeout with 3 seconds, then we could wait 3 seconds, or 3.5 seconds, or even
10 seconds before the callback is invoked. If there is no guaranteed timing,
then it is asynchronous. The following snippet illustrates this concept
succinctly:

```javascript
console.log("first");

setTimeout(function() {
  console.log("second");
}, 0);

console.log("third");
```

This would print the following order:

```plaintext
first
third
second
```

Although we specify a delay of 0 milliseconds, the callback is not invoked
immediately, because the actual delay may be more than 0. This unintuitive
behavior is well known, in fact there is a [full section in the docs for
setTimeout][longer-timeouts-than-specified] devoted to this nuance. The reasons
for this discrepancy are not important for now. However, do take away the fact
that `setTimeout` is indeed asynchronous, no matter how hard we try to fight it.

> [setTimeout][set-timeout] is just one example of asynchronous behavior.
> Another asynchronous function is [setInterval][set-interval], which will
> continually execute a callback after a number of milliseconds, repeatedly.

## Why do we need asynchronous code?

We know how you are feeling. Asynchronous code seems intimidating. Before this
article, you've written exclusively synchronous code and have gotten quite far
using just that - so why do we need asynchronous code? The truth of the matter
is that the environment in which we run our applications is full of uncertainty;
there is seldom a guarantee of when actions occur, how long they will take, or
even if they will happen at all. A software engineer can write the code, but
they can't write the circumstances in which their code will run (we can dream).
Here are a few practical scenarios where asynchronous code is a necessity:

- When we request data from an external server over a network, we cannot predict
  when we will get receive a response back. The timing is susceptible to latency
  due to the amount of traffic on the network, the server being busy handling
  other requests, and much more.
- When we expect a user to interact with our programs by hitting a key, clicking
  a button, or scrolling down the page, we can never be certain when they will
  perform those actions.

These are a few problems that we will encounter in upcoming lessons and we'll
turn to asynchronous JavaScript for the solution!

## What you've learned

In this reading, we've introduced asynchronous code. In particular we have:

- explored the difference between synchronous and asynchronous with `setTimeout`
  as our asynchronous candidate
- identified asynchronous code as a solution to handle timing circumstances
  during our programs' runtime that we cannot predict with total certainty

[set-timeout]:
  https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
[set-interval]:
  https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval
[longer-timeouts-than-specified]:
  https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout#Reasons_for_delays_longer_than_specified

________________________________________________________________________________
# All in Good Time: Setting Timeouts and Intervals

During our introduction to asynchronicity, we used `setTimeout` as a prime
example of a function that exhibits asynchronous behavior. We'll turn time and
time again to `setTimeout` in order to illustrate asynchronous concepts. Because
of this, let's familiarize ourselves with all the ways we can use the function!

When you finish this article, you should be able to:

- name the arguments that can be passed to `setTimeout` and `setInterval`
- predict the asynchronous nature of code snippets that utilize `setTimeout` and
  `setInterval`

## Time-out! What are the arguments?

In it's most basic usage, the [setTimeout][set-timeout-mdn] function accepts a
callback and an amount of time in milliseconds. Open a new `.js` file and
execute the following code:

```javascript
function foo() {
  console.log("food");
}

setTimeout(foo, 2000);
```

The code above will print out 'food' after waiting about two seconds. We
previously explored this behavior, but it's worth reemphasizing. `setTimeout` is
asynchronous, so any commands that come after the `setTimeout` may be executed
before the callback is called:

```javascript
function foo() {
  console.log("food");
}

setTimeout(foo, 2000);
console.log("drink");
```

The code above will print out 'drink' first and then 'food'. You may hear
asynchronous functions like `setTimeout` referred to as "non-blocking" because
they don't prevent the code that follows their invocation from running. It's
also worth mentioning that the time amount argument for `setTimeout` is
optional. If no amount is specified, then the amount will default to zero
(`setTimeout(foo)` is equivalent to `setTimeout(foo, 0`). Embellishing on this
thought for a moment, a common JavaScript developer interview question asks
candidates to predict the print order of the following code:

```javascript
function foo() {
  console.log("food");
}

setTimeout(foo, 0);
console.log("drink");
```

The code above will will print out 'drink' first and then 'food'. This is
because `setTimeout` is asynchronous so it will not block execution of further
lines. We have also previously mentioned that the amount specified is the
minimum amount of time that will be waited, [sometimes the delay will be
longer][mdn-delays-longer].

In addition to the callback and delay amount, an unlimited number of additional
arguments may be provided. After the delay, the callback will be called with
those provided arguments:

```javascript
function foo(food1, food2) {
  console.log(food1 + " for breakfast");
  console.log(food2 + " for lunch");
}

setTimeout(foo, 2000, "pancakes", "couscous");
```

The code above will print the following after about two seconds:

```plaintext
pancakes for breakfast
couscous for lunch
```

## Cancelling timeouts

You now have complete knowledge of all possible arguments we can use for
`setTimeout`, but what does it return? If we executing the following snippet in
node:

```javascript
function foo() {
  console.log("food");
}

const val = setTimeout(foo, 2000);
console.log(val);
```

We'll see that the return value of `setTimeout` is some special `Timeout`
object:

```javascript
Timeout {
  _called: false,
  _idleTimeout: 2000,
  _idlePrev: [TimersList],
  _idleNext: [TimersList],
  _idleStart: 75,
  _onTimeout: [Function: foo],
  _timerArgs: undefined,
  _repeat: null,
  _destroyed: false,
  [Symbol(unrefed)]: false,
  [Symbol(asyncId)]: 5,
  [Symbol(triggerId)]: 1
}
```

You won't be finding this object too useful except for one thing, cancelling an
timeout that has yet to expire! We can pass this object into the
[clearTimeout][clear-timeout-mdn] function:

```javascript
function foo() {
  console.log("food");
}

const val = setTimeout(foo, 2000);
clearTimeout(val);
```

The code above will not print out anything because the `setTimeout` is cleared
before the timer expires.

> You may notice that the MDN documentation for `setTimeout` and `clearTimeout`
> show that `setTimeout` returns a simple id number that can be used to cancel a
> pending timeout and not a fancy Timeout object as we have described. This
> variation is due to the fact that we are executing our code with NodeJS and
> not in the browser (MDN is specific to the browser environment). Rest assured,
> in either environment, if you pass the data that is returned from `setTimeout`
> to `clearTimeout`, the timeout will be cancelled!

## Running Intervals

Similar to `setTimeout`, there also exists a [setInterval][set-interval-mdn]
that function that executes a callback repeatedly at the specified delay.
`setInterval` accepts the same arguments as `setTimeout`:

```javascript
function foo(food1, food2) {
  console.log(food1 + " and " + food2 + "!");
}

setInterval(foo, 1000, "pancakes", "couscous");
```

The code above will print out 'pancakes and couscous!' every second. Someone's
hungry! Like you would expect, there is also a [clearInterval][clear-interval-mdn] that
we can use to cancel an interval!

## What you've learned

In this reading we covered:

- what arguments `setTimeout` and `setInterval` can accept: callback, delay in
  ms, and any number of arguments to be passed to the callback
- how to cancel a timeout or interval with `clearTimeout` and `clearInterval`

[set-timeout-mdn]:
  https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
[set-interval-mdn]:
  https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval
[clear-timeout-mdn]:
  https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearTimeout
[clear-interval-mdn]:
  https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/clearInterval
[mdn-delays-longer]:
  https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout#Reasons_for_delays_longer_than_specified

________________________________________________________________________________
# Hanging by a Single Thread: A Yarn on JavaScript's Execution

The primary job of the programmer is to write code and to that end you have
written hundreds, possibly thousands of lines so far. However, it is important
for a programmer to understand the bigger picture. After we finish writing the
code, what should we do with it? Publish it in a book? Print it to frame on
wall? None of these. After we write the code, we run it! If writing code is the
birth of a program, then its execution is the lifetime that takes place after.
Instead of "lifetime", programmers use the word "runtime" to refer to the
execution of a program.

Let's take a peek under the hood of the JavaScript runtime environment to get a
glimpse at how the code we write is processed.

When you finish reading this article, you should be able to:

- explain the difference between _single-threaded_ and _multi-threaded_
  execution
- identify JavaScript as a _single-threaded_ language

## Single-threaded vs multi-threaded execution

In programming, we use the term _thread of execution_ (_thread_ for short) to
describe a sequence of commands. A thread consists of well-ordered commands in
the same way that a task may consist of multiple steps. For example, the task
(thread) of doing laundry may consist of the following steps (commands):

1. open the washing machine door
2. load the washing machine with clothes
3. add some detergent
4. close the washing machine door
5. turn the washing machine on

For the most part, the relative order of these steps is critical to the task.
For example, we can only load the clothes after opening the door and _should_
only turn the machine on after closing the door.

Now that we have an understanding of what a _thread_ is, let's use a similar
analogy to explore two different models of threading. Enter _Appetite Academy_,
the restaurant where patrons only have to pay the bill once they are full.

We'll be exploring these two models:

![single-vs-multi-threading][threading-image]

### Single-threaded

In **single-threaded** execution, only one command can be processed at a time.

Say that a patron at Appetite Academy ordered a three course meal including a
salad (appetizer), a burger (main entree), and a pie (dessert). Each dish has
its own steps to be made. If the restaurant had a single-threaded kitchen, we
might see one chef in the kitchen preparing each dish one after the other. To
ensure that the customer receives the dishes in order, the lone chef would
likely plate a dish fully before beginning preparation of the next dish. A
shortcoming of this single chef kitchen is that the customer may have to wait
some time between dishes. On the flip side, only employing one chef is cheap for
the restaurant. Having one chef also keeps the kitchen relatively simple;
multiple chefs may complicate things. With one chef the restaurant avoids any
confusion that can result from "too many cooks in the kitchen."

Similar to having a single chef in the kitchen, **JavaScript is a
single-threaded language.** This means at any instance in time during a program,
only one command is being executed.

### Multi-threaded

In **multi-threaded** execution, multiple commands can be processed at the same
time.

If Appetite Academy had a multi-threaded kitchen, it would be quite a different
scene. We might find three different chefs, each working on a different dish.
This would likely cut down on the amount of time the customer spends waiting for
dishes. This seems like a big enough reason to prefer multi-threading, but it's
not without tradeoffs. Employing more chefs would increase costs. Furthermore,
the amount of time that is saved may not be as large as we think. If the chefs
have to share resources like a single sink or single stove, then they would have
to wait for those resources to be freed up before continuing preparation of
their respective dishes. Finally, having multiple chefs can increase the
complexity inside of the kitchen; the chefs will have to painstakingly
communicate and coordinate their actions. If we don't orchestrate our chefs,then
they might fight over the stove or mistakenly serve the dishes in the wrong
order!

A thread (chef) can still only perform one command at a time, but with many
threads we could save some time by performing some steps in parallel across many
threads.

## Keeping the thread from unraveling

Now that we've identified JavaScript as a single-threaded language, let's
introduce a problem that all single-threaded runtimes must face. If we can only
execute a single command at a time, what happens if we are in the process of
carrying out a command and an "important" event occurs that we want to handle
immediately? For example, if the user of our program presses a key, we would
want to handle their input as quickly as possible in order to provide a smooth,
snappy experience. The JavaScript runtime's solution to this is quite simple:
the user will have to wait. If a command is in progress and some event occurs,
the current command will run to full completion before the event is handled. If
the current command takes a long time, too bad; you'll have to wait longer. Cue
the very frustrating "We're sorry, the page has become unresponsive" message you
may be familiar with.

Execute the following snippet to illustrate this behavior:

```javascript
setTimeout(function() {
  console.log("times up!");
}, 1000);

let i = 0;
while (true) {
  i++;
}
```

The above program will hang indefinitely, never printing 'times up!' (press
`ctrl/cmd + c` in your terminal to kill the program). Let's break this down.
When the program begins, we set a timeout for one second, then enter an infinite
loop. While the loop is running, the timer expires, triggering a timeout event.
However, JavaScript's policy for handling new events is to only handle the next
event _after_ the current command is complete. Since the current command is an
infinite loop, the current command will _never_ complete, so the timeout event
will _never_ be handled.

Although this example seems contrived, it highlights one of the primary causes
of slow, unresponsive pages. Up next, we'll take a closer look at this issue and
how we can mitigate it.

## What you've learned

In this reading we were able to:

- compare and contrast _single-threaded_ and _multi-threaded_ execution through
  the analogy of a single-chef and multi-chef kitchen
- identify JavaScript as a _single-threaded_ language and;
- bring awareness to how its _single-threaded_ nature can cause unresponsive
  programs if left unchecked

[threading-image]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/threading.png

________________________________________________________________________________
# Stacking the Odds in our Favor: the Call Stack

We've written a lot of programs so far in this course and sometimes they are
quite complex. They may be complex in their execution since function calls and
returns cause control flow to jump around to different lines, instead of just
sequentially by increasing line number. Ever wonder how the JavaScript runtime
is able to track all of those function calls? You're in luck! It's time to
explore an important component of the JavaScript runtime: the **call stack**.

When you finish reading this article, you should be able to:

- identify the two operations that characterize a **stack** data structure
- sketch how the **call stack** is manipulated during the runtime of a simple
  program like the one provided in this reading

## The call stack

The **call stack** is a structure that JavaScript uses to keep track of the
evaluation of function calls. It uses the **stack** data structure. In Computer
Science, a "stack" is a general pattern of organizing a collection of items. For
our current use of a stack, the items being organized are the function calls
that occur during the execution of our program. We'll be exploring stacks in
great detail further in the course. For now, we can imagine a stack as a
vertical pile that obeys the following pattern:

- new items must be placed on top of the pile - we refer to this as **pushing**
  a new item to the stack
- at any point, the only item that can be removed is the top of the pile - we
  refer to this as **popping** the top item from the stack

In JavaScript's call stack, we use the term "stack frames" to describe the items
that are being pushed and popped. With this new understanding, we can now
identify two ways that JavaScript leverages these stack mechanics during
runtime:

- when a function is called, a new frame is pushed onto the stack.
- when a function returns, the frame on the top of the stack is popped off the
  stack.

To illustrate how frames are pushed and popped to the call stack, we'll explore
the following program:

```javascript
function foo() {
  console.log("a");
  bar();
  console.log("e");
}

function bar() {
  console.log("b");
  baz();
  console.log("d");
}

function baz() {
  console.log("c");
}

foo();
```

Create a file for yourself and execute this code. It will print out the letters
in order. This code is a great example of how a program's execution may not
simply be top down. Instead of executing sequentially, line by line, we know
that function calls and returns will cause execution to hop back and forth to
different line numbers. Let's trace through this program, visualizing the stack.
We'll use a commented arrow to denote where we pause execution to visualize the
stack at that moment.

We begin by executing a function call, `foo()`. This will add a frame to the
stack:

![stack-trace-image-1][stack-trace-01]

Now that `foo()` is the topmost (and only) frame on the stack, we must execute
the code inside of that function definition. This means that we print 'a' and
call `bar()`. This causes a new frame to be pushed to the stack:

![stack-trace-image-2][stack-trace-02]

Note that the stack frame for `foo()` is still on the stack, but not on top
anymore. The only time a frame may entirely leave that stack is when it is
popped due to a function return. Bear in mind that a function can return due to
a explicit return with a literal line like `return someValue;` or it can
implicitly return after the last line of the function's definition is executed.
Since `bar()` is now on top of the stack, execution jumps into the definition of
`bar`. You may notice the trick now: the frame that is at the top of the stack
represents the function being executed currently. Back to the execution, we
print 'b' and call `baz()`:

![stack-trace-image-3][stack-trace-03]

Again, notice that `bar()` remains on the stack because that function has not
yet returned. Executing `baz`, we print out 'c' and return because there is no
other code in the definition of `baz`. This return means that `baz()` is popped
from the stack:

![stack-trace-image-4][stack-trace-04]

Now `bar()` is back on top of the stack; this makes sense because we must
continue to execute the remaining code within `bar` on line 10:

![stack-trace-image-5][stack-trace-05]

'd' is printed out and `bar` returns because there is no further code within its
definition. The top of stack is popped. `foo()` is now on top, which means
execution resumes inside of `foo`, line 4:

![stack-trace-image-6][stack-trace-06]

Finally, 'e' is printed and `foo` returns. This means the top frame is popped,
leaving the stack empty. Once the stack is empty, our program can exit:

![stack-trace-image-7][stack-trace-07]

That completes our stack trace! Here are three key points to take away from
these illustrations:

1. the frame on the top of the stack corresponds to the function currently being
   executed
2. calling a function will push a new frame to the top of the stack
3. returning from a function will pop the top frame from the stack

> This was a high level overview of the call stack. There is some detail that
> we've omitted to bring attention to the most important mechanics. In
> particular, we've glazed over what information is actually stored inside of a
> single stack frame. For example, a stack frame will contain data about a
> specific function call such as local variables, arguments, and which line to
> return to after the frame is popped!

## The practical consequences of the call stack

Now that we have an understanding of the call stack, let's discuss its practical
implications. We've previously identified JavaScript as a single-threaded
language and now you know why that's the case. The use of a single call stack
leads to a single thread of execution! The JavaScript runtime can only perform
one "command" at a time and the one "command" currently being executed is
whatever is at the top of the stack.

In the example program we just traced through, we mentioned that the program
will exit once the call stack is empty. This is not true of all programs. If a
program is asynchronously listening for an event to occur, such as waiting for a
`setTimeout` to expire, then the program will not exit. In this scenario, once
the `setTimeout` timer expires, a stack frame corresponding to the `setTimeout`
callback will be added to the stack. From here, the call stack would be
processed in the way we previously explored. Imagine that we had the same
functions as before, but we called `foo` asynchronously:

```javascript
function foo() {
  console.log("a");
  bar();
  console.log("e");
}

function bar() {
  console.log("b");
  baz();
  console.log("d");
}

function baz() {
  console.log("c");
}

setTimeout(foo, 2500);
```

The critical behavior to be aware of in the JavaScript runtime is this: **an
event can only be handled once the call stack is empty**. Recall that events can
be things other than timeouts, such as the user clicking a button or hitting a
key. Because we don't want to delay the handling of such important events, we
want minimize the amount of time that the call stack is non-empty. Take this
extreme scenario:

```javascript
function somethingTerrible() {
  let i = 0;
  while (true) {
    i++;
  }
}

setTimeout(function() {
  console.log("time to do something really important!");
}, 1000);

somethingTerrible();
```

`somethingTerrible()` will be pushed to the call stack and loop infinitely,
causing the function to never return. We expect the `setTimeout` timer to expire
while `somethingTerrible()` is still on the stack. Since `somethingTerrible()`
never returns, it will never be popped from the stack, so our `setTimeout`
callback will never have its own turn to be executed on the stack.

## What you've learned

In this reading, we have:

- explored how the _call stack_ is manipulated over the runtime of a program
- identified that events can only be handled once the _call stack_ is empty

[stack-trace-01]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/stack-trace/01.png
[stack-trace-02]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/stack-trace/02.png
[stack-trace-03]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/stack-trace/03.png
[stack-trace-04]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/stack-trace/04.png
[stack-trace-05]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/stack-trace/05.png
[stack-trace-06]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/stack-trace/06.png
[stack-trace-07]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/stack-trace/07.png

________________________________________________________________________________
# An Unexpected Turn of Events: the event loop and Message Queue

As of late, we've begun to uncover the asynchronous potential of JavaScript and
how we can harness that potential to handle unpredictable events that occur
during our application's runtime. JavaScript is the tool that enables web pages
to be interactive and dynamic. For example, if we head to a site like
[.io][aa-homepage] and click a button in the header, the page changes
due to that click event. We can click on that button _whenever_ we want and
somehow JavaScript is able to handle it _asynchronously_. How exactly does
JavaScript handle these events?

When you finish reading this article, you should be able to:

- explain how the JavaScript runtime uses the _call stack_ and **message queue**
  in its **event loop**
- identify the two operations that characterize a **queue** data structure

## The event loop

JavaScript uses an **event loop** model of execution. We've previously been
introduced to one component of the event loop, the _call stack_. We identified
the call stack as the structure used to keep track of the execution of function
calls. Think of the call stack as keeping track of the current "task" in
progress. To clarify, a single task may consist of multiple function calls. For
example if a function `foo` calls function `bar` and `bar` calls function `baz`,
then we consider all three functions as making progress toward the same task.

Along with the call stack, the event loop also consists of a **message queue**.
While the call stack tracks the task that is currently in progress, the message
queue keeps track of tasks that cannot be executed at this moment, but will be
executed once the current task is finished (recall that tasks can only be
performed one at a time because JavaScript is single-threaded). Because of this,
you may hear JavaScript's execution pattern referred to as "run to completion".
That is, the execution of an ongoing task will never be interrupted by another
task.

> In some other programming languages, it is possible for an ongoing task to be
> preempted or interrupted by another task, but this is not the case in
> JavaScript

### The message queue

The message queue is a structure used to track the handling of events. It uses
the **queue** data structure. A "queue" is a general pattern of organizing a
collection of things. A real world example of a queue is the line that you wait
on for checkout at a grocery store. A queue has a front and back, and obeys the
following pattern:

- new items are added to the back of queue - we refer to this as **enqueueing**
  an item
- items can only leave through the front of the queue - we refer to this as
  **dequeueing** an item

Events in JavaScript are handled asynchronously with callbacks. Like always, the
events can be things such as a `setTimeout` expiring or the user clicking a
button. The items stored on the message queue correspond to events that have
occurred but have not yet been processed. The items stored on the queue are
referred to as "messages".

To illustrate how the message queue and call stack interact, we'll trace the
runtime of the following program:

```javascript
function somethingSlow() {
  // some terribly slow implementation
  // assume that this function takes 4000 milliseconds to return
}

function foo() {
  console.log("food");
}

function bar() {
  console.log("bark");
  baz();
}

function baz() {
  console.log("bazaar");
}

setTimeout(foo, 1500);
setTimeout(bar, 1000);
somethingSlow();
```

The message queue only grows substantially when the current task takes a
nontrivial amount of time to complete. If the runtime isn't already busy tending
to a task, then new messages can be processed immediately because they wait
little to no time on the queue. For our illustration, we'll take creative
liberty and assume that some messages _do_ have to wait on the queue because the
`somethingSlow` function takes 4000 milliseconds to complete! We'll use absolute
time in milliseconds to tell our story in the following diagrams, but the
reality is that we can't be certain of the actual timing. The absolute time in
milliseconds is not important, instead focus your attention to the relative
order of the stack and queue manipulations that take place.

We begin by setting a timeout for both `foo` and `bar` with 1500 and 1000 ms
respectively. Apart from the stack frames for the calls to the `setTimeout`
function itself (which we'll ignore for simplicity), no items are added to the
stack or queue. We don't manipulate the queue because a new message is only
enqueued when an event occurs and our timeout events have not yet triggered. We
don't add `foo()` or `bar()` to the stack because they are only called after
their timeout events have triggered. However, we do add `somethingSlow()` to the
stack because it is called synchronously. Imagine we are at about the 500 ms
mark, `somethingSlow()` is being processed on the stack, while our two timeout
events have not yet triggered:

![event-loop-image-01][event-loop-01]

At the 1000 ms mark, `somethingSlow()` is still being processed on the stack
because it needs a total of 4000 ms to return. However, at this moment, the
timeout event for `bar` will trigger. Because there is something still on the
stack, `bar` cannot be executed yet. Instead, it must wait on the queue:

![event-loop-image-02][event-loop-02]

At the 1500 ms mark, a similar timeout event will occur for `foo`. Since new
messages are enqueued at the back of the queue, the message for the `foo` event
will wait behind our existing `bar` message. This is great because once the call
stack becomes available to execute the next message, we ought to execute the
message for the event that happened first! It's first come, first serve:

![event-loop-image-03][event-loop-03]

Jumping to the 4000 ms mark, `somethingSlow()` finally returns and is popped
from the call stack. The stack is now available to process the next message. The
message at the front of the queue, `bar`, is placed on the stack for evaluation:

![event-loop-image-04][event-loop-04]

At the 4100 ms mark, `bar()` execution is in full swing. We have just printed
"bark" to the console and `baz()` is called. This new call for `baz()` is pushed
to the stack.

![event-loop-image-05][event-loop-05]

You may have noticed that `baz` never had to wait on the queue; it went directly
to the stack. This is because `baz` is called synchronously during the execution
of `bar`.

At the 4200 ms mark, `baz()` has printed "bazaar" to the console and returns.
This means that the `baz()` stack frame is popped:

![event-loop-image-06][event-loop-06]

At the 4250 ms mark, execution resumes inside of `bar()` but there is no other
code to evaluate inside. The function returns and `bar()` is popped. Now that
the stack is free, the next message is taken from the queue to evaluate:

![event-loop-image-07][event-loop-07]

Finally, "food" is printed and the stack is popped. Leaving us with an empty
call stack and message queue:

![event-loop-image-08][event-loop-08]

That's all there is to it! Tracing the call stack and message queue for more
complex programs is very tedious, but the underlying mechanics are the same. To
summarize, synchronous tasks are performed on the stack. While the current task
is being processed on the stack, incoming asynchronous events wait on the queue.
The queue ensures that events which occurred first will be handled before those
that occurred later. Once the stack is empty, that means the current task is
complete, so the next task can be moved from the queue to the stack for
execution. This cycle repeats again and again, hence the _loop_!

> If you are interested in reading more about the event loop check out the MDN
> [documentation][mdn-event-loop]

## What you've learned

In this article we:

- introduced the queue data structure
- explored how the call stack and message queue interact to form JavaScript's
  event loop

[aa-homepage]: https://www..io/
[mdn-event-loop]:
  https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
[event-loop-01]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/event-loop/01.png
[event-loop-02]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/event-loop/02.png
[event-loop-03]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/event-loop/03.png
[event-loop-04]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/event-loop/04.png
[event-loop-05]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/event-loop/05.png
[event-loop-06]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/event-loop/06.png
[event-loop-07]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/event-loop/07.png
[event-loop-08]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/asynchronous-functions/assets/event-loop/08.png

________________________________________________________________________________
# Reading Between the Lines: Getting User Input and Callback Chaining

Up until this point, our programs have been deterministic in that they exhibit
the same behavior whenever we execute them. In order to change the behavior, we
have had to change the code. The human element has been missing! It would be
great if a user of our program could interact with it during _runtime_, possibly
influencing the _thread of execution_. Gathering input from the user during
runtime is an operation that is typically handled _asynchronously_ with
_events_. Why asynchronously? Well, we can't be certain _when_ the user will
decide to interact and we don't want our program to wait around idly for their
input. Don't forget that JavaScript is single-threaded; waiting for user input
synchronously would block the thread!

When you finish reading this article, you should be able to:

- write a program that accepts user input using Node's `readline` module
- utilize callback chaining to guarantee relative order of execution among
  multiple asynchronous functions

## Node's readline module

To take user input, we'll need to get acquainted with the
[readline][readline-doc] module. Recall that a module is just a package of
JavaScript code that provides some useful functionality (for example, `mocha` is
a module that we have been using frequently to test our code). Luckily, the
`readline` module already comes bundled with Node. No additional installations
are needed, we just need to "import" the module into our program. Let's begin
with a fresh `.js` file:

```javascript
// import the readline module into our file
const readline = require("readline");
```

The `readline` variable is an object that contains all of the methods we can use
from the module. Following the quick-start instructions in the
[docs][readline-doc], we'll also need to do some initial setup:

```javascript
const readline = require("readline");

// create an interface where we can talk to the user
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
```

The details of what `createInterface` does aren't super-duper important, but
here is the short story: it allows us to read and print information from the
terminal.

> A large part of using modules like `readline` is sifting through the
> documentation for what you need. You'll have to become comfortable with
> utilizing methods without understanding exactly _how_ they work. Abstraction
> is the name of the game here! We don't know exactly how the `createInterface`
> method works under the hood, but we can still use it effectively because the
> docs offer examples and guidance!

Now that we have the setup out of the way, let's ask the user something!
Referencing the docs, we can use the `question` method on our interface:

```javascript
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

// ask the user a question
rl.question("What's up, doc? ", answer => {
  // print their response
  console.log("you responded: " + answer);
  // close the interface
  rl.close();
});
```

Execute the code above and enter something when prompted! If we respond 'nothing
much', the total output would be:

```plaintext
What's up, doc? nothing much
you responded: nothing much
```

Pretty cool, huh? Notice that the `question` method accepts two arguments: a
question message to display and a callback. When the user types a response and
hits `enter`, the callback will be executed with their response as the argument.

> rl.close() is invoked after the question is answered to close the interface.
> If we don't close the interface, then the program will hang and not exit. In
> general, you'll want to close the interface after you are done asking all of
> your questions. Like usual, all of this info is provided in the
> [docs][readline-close-doc].

Let's emphasize a critical point: the `question` method is asynchronous! Similar
to how we illustrated the asynchronous nature of `setTimeout`, let's add a print
statement after we call `rl.question`:

```javascript
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.question("What's up, doc? ", answer => {
  console.log("you responded: " + answer);
  rl.close();
});

// try to print 'DONE!' after the question
console.log("DONE!");
```

If we respond 'nothing much', the total output would be:

```plaintext
What's up, doc? DONE!
nothing much
you responded: nothing much
```

Oops. It looks like the 'DONE!' message was printed out before the user finished
entering their response because the `question` method is asynchronous. We'll
introduce a pattern for overcoming this issue next.

## Callback chaining

In our last example, we saw how the asynchronous behavior of the `question`
method can lead to issues if we want to perform a command directly after the
user enters their response. The fix for this is trivial (some would even say
"low-tech"). Simply put the command you want to follow at the end of the
callback. In other words, the following code guarantees that we print 'DONE!'
**after** the user enters their response:

```javascript
// this code is a partial snippet from previous examples

rl.question("What's up, doc? ", answer => {
  console.log("you responded: " + answer);
  rl.close();
  console.log("DONE!");
});
```

The change above would yield a total output of:

```plaintext
What's up, doc? nothing much
you responded: nothing much
DONE!
```

In general, when we want to a command to occur directly "after" a callback is
invoked asynchronously, we'll really have to place that command inside of the
callback. This is a simple pattern, but one that we'll turn to often.

Imagine that we want to ask the user two questions in succession. That is, we
want to ask question one, get their response to question one, then ask question
two, and finally get their response to question two. The following code will
**not** meet this requirement:

```javascript
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

// ask question one
rl.question("What's up, doc? ", firstAnswer => {
  console.log(firstAnswer + " is up.");
});

// ask question two
rl.question("What's down, clown? ", secondAnswer => {
  console.log(secondAnswer + " is down.");
  rl.close();
});
```

The code above is broken and will never ask the second question. Like you can
probably guess, this is because the `question` method is asynchronous.
Specifically, the first call to `question` will occur and before the user can
enter their response, the second call to `question` also occurs. This is bad
because our program is still trying to finish the first question. Since we want to
ask question two only after the user responds to question one, we'll have to use
the pattern from before. That is, we should ask question two within the response
callback for question one:

```javascript
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

// ask question one
rl.question("What's up, doc? ", firstAnswer => {
  console.log(firstAnswer + " is up.");

  // only after the user responds to question one, then ask question two
  rl.question("What's down, clown? ", secondAnswer => {
    console.log(secondAnswer + " is down.");
    rl.close();
  });
});
```

If we respond to the questions with 'the sky' and 'the ground', the total output
is:

```plaintext
What's up, doc? the sky
the sky is up.
What's down, clown? the ground
the ground is down.
```

Nice! The program works as intended. The pattern we utilized is known as
_callback chaining_. While callback chaining allows us to perform a series of
asynchronous functions one after the other, if we don't manage our code neatly,
we can end up with a mess. Extending this pattern to three questions, we can
begin to see the awkward, nested structure:

```javascript
// this code is a partial snippet from previous examples

rl.question("What's up, doc? ", firstAnswer => {
  console.log(firstAnswer + " is up.");

  rl.question("What's down, clown? ", secondAnswer => {
    console.log(secondAnswer + " is down.");

    rl.question("What's left, Jeff? ", thirdAnswer => {
      console.log(thirdAnswer + " is left.");
      rl.close();
    });
  });
});
```

This overly nested structure is known colloquially in the JavaScript community
as ["callback hell"][callback-hell]. Don't worry! A way to refactor this type of
code for more readability is to use named functions instead of passing anonymous
functions. Here is an example of such a refactor:

```javascript
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.question("What's up, doc? ", handleResponseOne);

function handleResponseOne(firstAnswer) {
  console.log(firstAnswer + " is up.");
  rl.question("What's down, clown? ", handleResponseTwo);
}

function handleResponseTwo(secondAnswer) {
  console.log(secondAnswer + " is down.");
  rl.question("What's left, Jeff? ", handleResponseThree);
}

function handleResponseThree(thirdAnswer) {
  console.log(thirdAnswer + " is left.");
  rl.close();
}
```

Run the code above to check out our final product! Ah, much better. By using
named functions to handle the responses, our code structure appears flatter and
easier to read.

Callback chaining is a very common pattern in JavaScript, so get used to it! As
a rule of thumb, prefer to use named functions when creating a callback chain
longer than two. Later in the course, we'll learn about recent additions to
JavaScript that help reduce "callback hell" even further, so stay tuned!

## What you've learned

In this reading, we:

- learned how to use the `readline` module to gather user input asynchronously
- utilized callback chaining to serialize multiple asynchronous functions
- refactored a callback chain to keep our code readable and avoid "callback
  hell"

[readline-doc]: https://nodejs.org/api/readline.html#readline_readline
[readline-close-doc]: https://nodejs.org/api/readline.html#readline_rl_close
[callback-hell]: http://callbackhell.com/

________________________________________________________________________________
# Timeout Project

Time to practice dealing with asynchronous functions like `setTimeout` and
`setInterval`. Your objective is to implement the functions in each file
of the `/problems` directory. In addition to the prompts available at the
top of each file, Mocha specs are provided to test your work.

To get started, use the following commands:

1. `cd` into the project directory
2. `npm install` to install any dependencies
3. `mocha` to run the test cases

________________________________________________________________________________
# Guessing Game Project

It's time for our first non-spec guided project! There are many projects in the
course, some of which will not have test cases for you to run. These types of
projects will hold your hand less and force you to make design decisions.
Instead of specs, you will be provided with text instructions and example
snippets to guide you. In order to end up with a working project, you should
analyze these instructions closely. If you are stuck or don't understand an
instruction, ask a TA for clarification!

The solution for this project is available at the end of these instructions. Be
sure to give it an honest shot before you take a peek!

## The Objective

Our objective for this project is to build a simple game where the user has to
guess a secret number that is chosen at random. Upon making a guess, the user
will receive a hint indicating if their guess is too small or too large. Below
is an example of how the final product will play. We've denoted the user's input
with \*asterisks\*. All other text is produced by the computer:

```plaintext
Enter a max number: *20*
Enter a min number: *11*
I'm thinking of a number between 11 and 20...
Enter a guess: *15*
Too high.
Enter a guess: *11*
Too low.
Enter a guess: *13*
Too high.
Enter a guess: *12*
Correct!
YOU WON.
```

We'll be building this project in phases, with each phase bringing us closer to
the final product shown above. It's important that you follow the phases closely
and don't jump the gun by ignoring the instructions and attempting to create
your own game quickly. For these guided projects, the journey is more important
than the final destination. Without further ado, let's jump in!

## Phase I: Too High? Too Low? Who knows.

Begin by creating a folder called `guessing-game-project`. Open the folder in
VSCode. Inside of that folder create a `guessing-game.js` file. This is the file
where we will do all of the coding.

Begin by initializing a variable in the global scope named `secretNumber` to any
positive integer. Later we will program this variable to be assigned at random,
but for now we'll hard-code a value that we can test for quickly.

### checkGuess

Define a function named `checkGuess` that accepts a number as an argument. It
should compare that argument against the global `secretNumber`. It should have
the following behavior:

- when the argument is larger than `secretNumber`, it should print 'Too high.'
  and return `false`
- when the argument is smaller than `secretNumber`, it should print 'Too low.'
  and return `false`
- when the argument is equal to `secretNumber`, it should print 'Correct!' and
  return `true`

Let's take a moment to verify that our code is working as intended. Make a few
test calls to `checkGuess` in the global scope. Be sure to use a range of
numbers so we can verify that it behaves properly in all three scenarios. You'll
want to `console.log` the return values of `checkGuess` since it should return
booleans. Run your code with `node guessing-game.js`. When you are positive that
your function is working, remove the test calls from your file.

### askGuess

Since we will be taking user input during gameplay, we'll need to do some
standard setup for Node's `readline` module. Reference the [readline
docs][readline-doc] to create an interface for input and output that we will
use. To stay organized, we recommend that you import the module and create the
interface at the tippy top of your file.

Define a function named `askGuess`. The method should use the `readline`
module's `question` method to ask the user to 'Enter a guess: '. If you need a
refresher on how to use this method, check out the [question
docs][question-doc]. Once the user enters their number, the `checkGuess`
function should be called with their number as an argument and the interface
should be [closed][close-doc].

When accepting user input, there is a very important nuance to take into
account. When the user enters their guess it will be interpreted as a string of
numeric characters and not an actual number type! Depending on how you wrote
your `checkGuess` function, this could be disastrous because:

```javascript
console.log(42 === "42"); // false
```

To overcome this issue, we should explicitly turn their guess into a number
_before_ we pass it into `checkGuess`. You can do this by calling the `Number`
function. Here's an example of `Number` in action:

```javascript
let str = "42";
console.log(42 === Number(str)); // true
```

Test your `askGuess` by calling it once in the global scope. Then run your
program a few times, entering different numbers. After trying a single guess,
you will have to run the program again. Be sure to include an attempt with a
correct guess by entering the `secretNumber` value that you hard-coded.

Once you have verified that the user's guess is being properly checked, let's
work on having the function ask the user for another guess if they are
incorrect. Refactor the `askGuess` method with some conditional logic. Recall
that the `checkGuess` function returns a boolean - very convenient! Here is how
the `askGuess` function should flow:

- check the user's guess
  - if it is correct, print out 'You win!' and close the interface
  - if it is incorrect, call `askGuess` again

> You may find it a bit startling that you can reference the `askGuess` function
> from within the `askGuess` function. That is, you can a reference a function
> from within itself! This self-referential mechanism is leveraged quite
> frequently in programming. We will return to this concept in later lessons.

Run your program and test it out, being sure that you have a single call to
`askGuess` in the global scope so the game can begin. Woohoo! We now have our
minimal viable product (MVP) version of the game.

**Before moving onto the next phase, ask a TA for a code review.**

## Phase II: Making it Random

Now that we have the core gameplay down, we'll want to implement logic to allow
the `secretNumber` to be chosen at random. To do this, we'll utilize the
`Math#random` method. Take a look at the [docs][random-doc]. The method returns
a decimal number between 0 and 1 (excluding 1). For example:

```javascript
console.log(Math.random()); // 0.5719957072947224
console.log(Math.random()); // 0.08590173924968769
console.log(Math.random()); // 0.0965770175443883
```

By itself, this method won't be too useful because our game should only use
whole numbers. Luckily, the docs provide some insight into how we can design a
function that returns a random whole number that lies within a certain range.
Scroll through the docs and locate examples about "Getting a random integer
between two values." You'll use these examples to inspire your code. You may
notice that the examples provided rely on other methods like `Math.floor`.
Research those methods so that you understand how the code works. Googling
around and researching the docs is an important aspect of being a developer, so
take your time!

### randomInRange

Define a function called `randomInRange` that accepts a minimum and maximum
number as arguments. The function should return a random whole number between
the provided minimum and maximum (inclusive). Be sure to test your function,
here is an example of how it might behave:

```javascript
console.log(randomInRange(15, 20)); // 16
console.log(randomInRange(15, 20)); // 17
console.log(randomInRange(15, 20)); // 20
```

Once you have confirmed that your `randomInRange` function is returning numbers
properly, edit your initialization of `secretNumber`. Instead of setting it to a
hard-coded value, use your function's return value to set it to a random number
between 0 and 100. Play a few games! Remember that you'll have to call
`askGuess()` once in the global scope to begin the game. Next up, we'll allow
the user to choose the min and max for the game.

### askRange

Delete or comment out your global call to `askGuess` for now. Define a function
called `askRange`. This method should ask the user to enter a minimum number and
then ask them to enter a maximum number. We want to ask them for the maximum
only after they have responded to the first question. This means you will have
to use the `question` method twice! Recall what you learned from the readings.
The `question` method is asynchronous, so how can we ask two questions one after
the other? We'll leave the implementation to you. After the user enters their
min and max, you should print a message confirming the range. Here is an example
of how our `askRange` method behaves. We've put _asterisks_ around the user's
input:

```plaintext
Enter a max number: *20*
Enter a min number: *11*
I'm thinking of a number between 11 and 20...
```

As always, test your function thoroughly by adding a call to `askRange` in
global scope. Your program may hang because the interface is not closed after
the user enters their max. That's okay, since we are debugging; press `ctrl + c`
in your terminal to kill the program.

Once your function is able to properly take the min and max from your user, it's
time to put it all together! When the user enters both the min and the max, call
your `randomInRange` function with that min and max as arguments. Recall that
the user's input is automatically interpreted as strings and not numbers. You
should explicitly turn the min and max to actual numbers before passing them in.
Take the random number returned from your function and set that as the
`secretNumber`. Then call your old `askGuess` method so that gameplay can begin.
All of this should happen within the `askRange` function. We design it this way
because we only want to ask for a guess after the random number has been chosen.

The `askRange` function is the "main" function that will begin our game, so
you'll need call it once in the global scope. Run your program and play a few
games!

**Before moving onto the bonus ask a TA for a code review.**

## Bonus: Limiting the number of turns

With our main features complete, let's work on increasing the difficulty of the
game by limiting the number of guesses a user can make. If the player uses all
of their attempts without guessing the correct number, they will lose the game.

### Limiting turns to 5

Start by limiting the player to 5 attempts. You can accomplish this by
initializing a `numAttempts` variable in the global scope. Refactor your
`askGuess` method to decrement the number of remaining attempts whenever it is
called. If the `numAttempts` reaches 0 before the correct guess is made, end the
game by printing 'You Lose'. We'll leave the details of the implementation up to
you.

### Limiting turns dynamically

Make the limit dynamic by allowing the user to specify the number of attempts.
We recommend creating an `askLimit` function that behaves similarly to
`askRange`. Be sure to chain the callbacks in the right order to ensure the game
is configured properly. For example, one valid callback chain order would be
`askLimit` -> `askRange` -> `askGuess`. If you follow this order, you'll need to
call `askLimit` in the global scope to begin the game.

[readline-doc]: https://nodejs.org/api/readline.html#readline_readline
[question-doc]:
  https://nodejs.org/api/readline.html#readline_rl_question_query_callback
[close-doc]: https://nodejs.org/api/readline.html#readline_rl_close
[random-doc]:
  https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random

________________________________________________________________________________
# WEEK-03 DAY-2
*Git* {ignore=true}
________________________________________________________________________________
# Node.js Learning Objectives

Below is a complete list of the terminal learning objectives for this lesson.
When you complete this lesson, you should be able to perform each of the
following objectives. These objectives capture how you may be evaluated on the
assessment for this lesson.

1. Define NodeJS as distinct from browser based JavaScript runtimes.
2. Write a program that reads in a dictionary file using node's FS API and reads
   a line of text from the terminal input. The program should 'spell check' by
   putting asterisks around every word that is NOT found in the dictionaryearning objectives for this lesson.
When you complete this lesson, you should be able to perform each of the
following objectives. These objectives capture how you may be evaluated on the
assessment for this lesson.

1. Define NodeJS as distinct from browser based JavaScript runtimes.
2. Write a program that reads in a dictionary file using node's FS API and reads
   a line of text from the terminal input. The program should 'spell check' by
   putting asterisks around every word that is NOT found in the dictionary.
________________________________________________________________________________
# Git Learning Objectives

Below is a complete list of the terminal learning objectives for this lesson.
When you complete this lesson, you should be able to perform each of the
following objectives. These objectives capture how you may be evaluated on the
assessment for this lesson.

1. Use Git to initialize a repo
2. Explain the difference between Git and GitHub
3. Given 'adding to staging', 'committing', and 'pushing to remote', match attributes that apply to each.
4. Use Git to clone an existing repo from GitHub
6. Use Git to push a local commit to a remote branch
7. Use git to make a branch, push it to github, and make a pull request on GitHub to merge it to master
8. Given a git merge conflict, resolve it
9. Match the three types of git reset with appropriate descriptions of the operation.
10. Use Git reset to rollback local-only commits.
11. Identify what the git rebase command does
12. Use git diff to compare a local 'staging' branch and 'master' branch.
13. Use git checkout to check out a specific commit by commit iing objectives for this lesson.
When you complete this lesson, you should be able to perform each of the
following objectives. These objectives capture how you may be evaluated on the
assessment for this lesson.

1. Use Git to initialize a repo
2. Explain the difference between Git and GitHub
3. Given 'adding to staging', 'committing', and 'pushing to remote', match attributes that apply to each.
4. Use Git to clone an existing repo from GitHub
6. Use Git to push a local commit to a remote branch
7. Use git to make a branch, push it to github, and make a pull request on GitHub to merge it to master
8. Given a git merge conflict, resolve it
9. Match the three types of git reset with appropriate descriptions of the operation.
10. Use Git reset to rollback local-only commits.
11. Identify what the git rebase command does
12. Use git diff to compare a local 'staging' branch and 'master' branch.
13. Use git checkout to check out a specific commit by commit id
________________________________________________________________________________
# A Tale of Two Runtimes: Node.js vs Browser

Lately, we've been alluding to JavaScript running in the web browser. While we
are not quite ready to make that transition yet, the authors of JavaScript
really only intended their creation to be used in a browser environment when
they originally conceived of the language at Netscape in 1995. To prepare for
the coming transition to the browser, let's explore some of the differences
between Node.js and browser environments.

When you finish this article, you should be able to:

- identify Node.js as an environment that is _distinct_ from web browsers
- list several differences between the Node.JS and browser runtimes

## Same specification, different implementation

Since JavaScript is a single programming language, you may be wondering why
there are _any_ differences between Node.js and browsers in the first place. If
they are in fact different, why wouldn't we classify them as different
programming languages? The answer is complicated, but the key idea is this: even
if we just consider browser environments, different browsers themselves can
differ wildly because JavaScript is a _specification_. During the rise of the
World Wide Web in the 90s, companies competed for dominance (see [The First
Browser War][browser-wars]). As Netscape's "original" JavaScript language rose
to prominence along with their browser, other browser companies needed to also
support JavaScript to keep their users happy. Imagine if you could only visit
pages as they were intended if you used a certain browser. What a horrible
experience it would be (we're looking at you Internet Explorer)! As companies
"copied" Netscape's original implementation of JavaScript, they sometimes took
creative liberty in adding their own features.

In order to ensure a certain level of compatibility across browsers, the
European Computer Manufacturers Association (ECMA) defined specifications to
standardize the JavaScript language. This specification is known as _ECMAScript_
or _ES_ for short. This allows competing browsers like Google Chrome, Mozilla
Firefox, and Apple Safari to have a healthy level of competition that doesn't
compromise the customer experience. So now you know that when people use the
term "JavaScript" they are really referring to the core standards set by
ECMAScript, although exact implementation details may differ from browser to
browser.

The Node.js runtime was released in 2009 when there was a growing need to
execute JavaScript in a portable environment, without any browser.

> **Did you know?** Node.js is built on top of the same JavaScript engine as
> Google Chrome (V8). Neat.

## Differences between Node.js and browsers

There are many differences between Node.js and browser environments, but many of
them are small and inconsequential in practice. For example, in our
_Asynchronous_ lesson, we noted how [Node's setTimeout][node-set-timeout] has a
slightly different return value from [a browser's setTimeout][mdn-set-timeout].
Let's go over a few notable differences between the two environments.

### Global vs Window

In the Node.js runtime, the [global object][global-object] is the object where
global variables are stored. In browsers, the [window object][window] is where
global variables are stored. The window also includes properties and methods
that deal with drawing things on the screen like images, links, and buttons.
Node doesn't need to draw anything, and so it does not come with such
properties. This means that you can't reference `window` in Node.

> Most browsers allow you to reference `global` but it is really the same object
> as `window`.

### Document

Browsers have access to a `document` object that contains the HTML of a page
that will be rendered to the browser window. There is no `document` in Node.

### Location

Browsers have access to a `location` that contains information about the web
address being visited in the browser. There is no `location` in Node, since it
is not on the web.

### Require and module.exports

Node has a predefined `require` function that we can use to import installed
modules like `readline`. We can also import and export across our own files
using `require` and `module.exports`. For example, say we had two different
files, `animals.js` and `cat.js`, that existed in the same directory:

```javascript
// cat.js

const someCat = {
  name: "Sennacy",
  color: "orange",
  age: 3
};

module.exports = someCat;
```

```javascript
// animals.js

const myCat = require("./cat.js");

console.log(myCat.name + " is a great pet!");
```

If we execute `animals.js` in Node, the program would print
`'Sennacy is a great pet!'`.

Browsers don't have a notion of a file system so we cannot use `require` or `module.exports` in the same way.

## What you've learned

In this reading, we covered a few differences between Node and browser environments, including:
+ Node's `global` and browser's `window`
+ the browser specific `document` and `location` objects
+ the Node specific `require` and `module.exports`

[node-set-timeout]:
  https://nodejs.org/api/timers.html#timers_settimeout_callback_delay_args
[mdn-set-timeout]:
  https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
[global-object]: https://developer.mozilla.org/en-US/docs/Glossary/Global_object
[window]: https://developer.mozilla.org/en-US/docs/Web/API/Window
[browser-wars]: https://en.wikipedia.org/wiki/Browser_wars

________________________________________________________________________________
# The Ins and Outs of File I/O in Node

We have previously identified some differences between Node.js and browser
environments. One difference was the use of `require` to import different node
modules. It is often the case that these modules provide functionality that is
totally absent in the browser environment. While browsers support deliberate
file download or upload to the web, they typically don't support arbitrary file
access due to security concerns. Let's explore a node module that allows us to
read, write, and otherwise manipulate files on our computer.

When you finish this article, you should be able to use the `fs` module to
perform basic read and write operations on local files.

## The fs module

Node ships with an [fs module][fs-doc] that contains methods that allow us to
interact with our computer's **F**ile **S**ystem through JavaScript. No
additional installations are required; to access this module we can simply
`require` it. We recommend that you code along with this reading. Let's begin
with a `change-some-files.js` script that imports the module:

```javascript
// change-some-files.js

const fs = require("fs");
```

Similar to what we saw in the `readline` lesson, `require` will return to us a
object with many properties that will enable us to do file I/O.

> **Did you know?** I/O is short for input/output. It's usage is widespread and all
> the hip tech companies are using it, like .io.

The `fs` module contains tons of functionality! Chances are that if there is
some operation you need to perform regarding files, the `fs` module supports it. The
module also offers both synchronous and asynchronous implementations of these
methods. We prefer to not block the thread and so we'll opt for the
asynchronous flavors of these methods.

### Creating a new file

To create a file, we can use the [`writeFile`][fs-write-file] method. According
to the documentation, there are a few ways to use it. The most straight forward
way is:

```javascript
// change-some-file.js

const fs = require("fs");

fs.writeFile("foo.txt", "Hello world!", "utf8", err => {
  if (err) {
    console.log(err);
  }
  console.log("write is complete");
});
```

The code above will create a new file called `foo.txt` in the same directory as
our `change-some-file.js` script. It will write the string `'Hello world!'` into
that newly created file. The third argument specifies the encoding of the
characters. There are different ways to encode characters; [UTF-8][utf-8] is the
most common and you'll use this in most scenarios. The fourth argument to
`writeFile` is a callback that will be invoked when the write operation is
complete. The docs indicate that if there is an error during the operation (such
as an invalid encoding argument), an error object will be passed into the
callback. This type of error handling is quite common for asynchronous
functions. Like we are used to, since `writeFile` is asynchronous, we need to
utilize _callback chaining_ if we want to guarantee that commands occur _after_
the write is complete or fails.

> Beware! If the file name specified to `writeFile` already exists, it will
> completely overwrite the contents of that file.

We won't be using the `foo.txt` file in the rest of this reading.

### Reading existing files

To explore how to read a file, we'll use VSCode to manually create a
`poetry.txt` file within the same directory as our `change-some-file.js` script.
Be sure to create this if you are following along.

Our `poetry.txt` file will contain the following lines:

```plaintext
My code fails
I do not know why
My code works
I do not know why
```

We can use the [`readFile`][fs-read-file] method to read the contents of this
file. The method accepts very similar arguments to `writeFile`, except that the
callback may be passed an error object and string containing the file contents.
In the snippet below, we have replaced our previous `writeFile` code with
`readFile`:

```javascript
// change-some-file.js
const fs = require("fs");

fs.readFile("poetry.txt", "utf8", (err, data) => {
  if (err) {
    console.log(err);
  }
  console.log("THE CONTENTS ARE:");
  console.log(data);
});
```

Running the code above would print the following in the terminal:

```plaintext
THE CONTENTS ARE:
My code fails
I do not know why
My code works
I do not know why
```

Success! From here, you can do anything you please with the data read from the
file. For example, since `data` is a string, we could split the string on the
newline character `\n` to obtain an array of the file's lines:

```javascript
// change-some-file.js
const fs = require("fs");

fs.readFile("poetry.txt", "utf8", (err, data) => {
  if (err) {
    console.log(err);
  }

  let lines = data.split("\n");
  console.log("THE CONTENTS ARE:");
  console.log(lines);
  console.log("The third line is " + lines[2]);
});
```

Running this latest version would yield:

```plaintext
THE CONTENTS ARE:
[ 'My code fails',
  'I do not know why',
  'My code works',
  'I do not know why' ]
The third line is My code works
```

## Fancy File I/O

Now that we have an understanding of both `readFile` and `writeFile`, let's use
both to accomplish a task. Using the same `poetry.txt` file from before:

```plaintext
My code fails
I do not know why
My code works
I do not know why
```

Our goal is to design a program to replace occurrences of the phrase 'do not'
with the word 'should'. This is straightforward enough. We can read the contents
of the file as a string, manipulate this string, then write this new string back
into the file. We'll need to utilize callback chaining in order for this to work
since our file I/O is asynchronous:

```javascript
const fs = require("fs");

fs.readFile("poetry.txt", "utf8", (err, data) => {
  if (err) {
    console.log(err);
  }

  let newData = data.split("do not").join("should");

  fs.writeFile("poetry.txt", newData, "utf8", err => {
    if (err) {
      console.log(err);
    }

    console.log("done!");
  });
});
```

Executing the script above will edit the `poetry.txt` file to contain:

```plaintext
My code fails
I should know why
My code works
I should know why
```

As a bonus, we might also refactor this code to use named functions for better
readability and generality:

```javascript
const fs = require("fs");

function replaceContents(file, oldStr, newStr) {
  fs.readFile(file, "utf8", (err, data) => {
    if (err) {
      console.log(err);
    }
    let newData = data.split(oldStr).join(newStr);
    writeContents(file, newData);
  });
}

function writeContents(file, data) {
  fs.writeFile(file, data, "utf8", err => {
    if (err) {
      console.log(err);
    }
    console.log("done!");
  });
}

replaceContents("poetry.txt", "do not", "should");
```

## What you've learned

In this reading we explored the `fs` module. In particular, we:

- learned about basic file I/O via `readFile` and `writeFile`
- utilized callback chaining to edit a file based on its existing content

[fs-doc]: https://nodejs.org/api/fs.html
[fs-write-file]:
  https://nodejs.org/api/fs.html#fs_fs_writefile_file_data_options_callback
[fs-read-file]:
  https://nodejs.org/api/fs.html#fs_fs_readfile_path_options_callback
[utf-8]: https://en.wikipedia.org/wiki/UTF-8

________________________________________________________________________________
# "Gitting" Started With Git!

Good software is never limited to "right now"! Your code grows and changes over
time, and the people who work with it may come and go. How can you be certain
you're preserving your code's legacy? _Version control_ lets us keep track of
your changes over time. You'll discuss version control with _Git_, the tool of
choice for modern development teams.

After reading, you'll be able to:

- Explain the role of version control in the programmer's toolkit
- Create and manage a Git repository
- Share and collaborate on Git repositories via Github

## A little history

Think back to the dark ages of web development: a world of beeping modems and
marquee text. If you were going to build a web application in 1995, how might
you have done it? You'd start with an empty directory and add some JavaScript
and HTML files. As you made changes, you'd save them directly to your directory.
There's no history of the changes you've made, so you'd have to keep excellent
notes or have an incredible memory to revert your application to a previous
state.

What if you have teammates working with you on this project, or a client who
wants to review your work? Now each teammate needs a copy of the project
directory, and you need a way to share your work with clients. This results in
numerous copies of the same files and a lot of extra work keeping those files in
sync. If one file gets out of line, it could spell disaster for the whole
project. Yikes!

Instead of suffering from these problems, programmers designed a solution:
_Version Control Systems (VCS)_. VCS tools abstract the work of keeping projects
and programmers in sync with one another. They provide a shared language with
which you can discuss changes to source code. They also allow you to step back
in time and review your work. VCS tools save you hours of work each day, so
learning to use them is a great investment in your productivity.

### Git?

You'll be using Git (pronounced similarly to 'get' in English) as your VCS. Git
is the most popular VCS today and provides a good balance of power and ease of
use. It was created in 2005 by Linus Torvalds (who you may also recognize as the
creator of Linux) to address a number of shortcomings VCS tools of that time
had, including speed of code management and the ability to maintain workflow
when cut off from a remote server. Git is well-known for being reliable and
fast, and it brings with it an important online community you can leverage for
sharing your code with a wider audience.

## Git basics

Like many disciplines, learning Git is just a matter of learning a new language.
You'll cover a lot of new vocabulary in this lesson! Remember that the
vocabulary you'll learn will allow you to communicate clearly with other
developers worldwide, so it's important to understand the meaning of each term.

It's also important to note that Git is a complex and powerful tool. As such,
its documentation and advanced examples may be tough to understand. As your
knowledge grows, you may choose to dive deeper into Git. Today, you'll focus on
the commands you'll use every day - possibly for the rest of your programming
career! Get comfortable with these commands and resist the urge to copy/paste or
create keyboard shortcuts as you're getting started.

### See the world through Git's eyes

Before you look at any practical examples, let's talk about how Git works behind
the scenes.

Here is your first new word in Git-speak: _repository_, often shortened to
_repo_. A Git repo comprises all the source code for a particular project. In
the "dark ages" example above, the repo is the first directory you created,
where work is saved to, and which acts as the source for code shared to others.
Without a repo, Git has nothing to act on.

Git manages your project as a series of _commits_. A commit is a collection of
changes grouped towards a shared purpose. By tracking these commits, you can see
your project on a timeline instead of only as a finished project:

![image-git-timeline][image-git-timeline]

Notice the notes and seemingly random numbers by each commit? These are referred
to as _commit messages_ and _commit hashes_, respectively. Git identifies your
commits by their hash, a specially-generated series of letters and numbers. You
add commit messages to convey meaning and to help humans track your commits, as
those hashes aren't very friendly to read!

A Git hash is 40 characters long, but you only need the first few characters to
identify which hash you're referring to. By default, Git abbreviates hashes to 7
characters. You'll follow this convention, too.

Git provides a helpful way for us to "alias" a commit in plain English as well.
These aliases are called _refs_, short for "references". A special one that Git
creates for all repositories is `HEAD`, which references the most recent commit.
You'll learn more about creating your own refs when you learn about "branching".

Git maintains three separate lists of changes: the _working directory_, the
_staging area_, and the _commit history_.  You'll look more at these three lists soon.

Git only cares about changes that are "tracked". To track a file, you must add
it to the commit history. The working directory will always show the changes,
even if they aren't tracked. In the commit history, you'll only have a history
of files that have been formally tracked by your repository.

### Tracking changes in a repository

Now, let's get practical!

You can create a repository with `git init`. Running this command will
initialize a new Git repo in your current directory. It's important to remember
that you only want a repository for your project and not your whole hard drive,
so always run this command inside a project folder and not your home folder or
desktop. You can create a new repo in an empty folder or within a project
directory you've already created.

What good is an empty repo? Not much! To add content to your repository, use
`git add`. You can pass this command a specific filename, a directory, a
"wildcard" to select a series of similarly-named files, or a `.` to add every
untracked file in the current directory:

```sh
# This will add only my_app.js to the repo:
> git add my_app.js

# This will add all the files within ./objects:
> git add objects/

# This will add all the files in the current directory ending in `.js`:
> git add *.js

# This will add everything in your current directory:
> git add .
```

Adding a file (or files) moves them from Git's working directory to the staging
area. You can see what's been "staged" and what hasn't by using `git status`:

![image-git-status-output][image-git-status-output]

In this example, "Changes to be committed" is your staging area and "Changes not
staged for commit" is your working directory. Notice that you also have
"Untracked files", Git's way of reminding us that you may have forgotten to `git
add` a file to your repo. Most Git commands will include a bit of help text in
the output, so always read the messages carefully before moving forward. Thanks,
Git!

Once you're happy with your files and have staged them, you'll use `git commit`
to push them into the commit history. It's significantly more work to make
changes after a commit, so be sure your files are staged and exactly as you'd
like them before running this command. Your default text editor will pop up, and
you'll be asked to enter a commit message for this group of changes.

**Heads Up:** You may find yourself in an unfamiliar place! The default text
editor for MacOS (and many variants of Linux) is called _Vim_. Vim is a
terminal-based text editor you'll discuss in the near future. It's visually bare
and may just look like terminal text to you! If this happens, don't worry - just
type `:q` and press your "return" key to exit.

You'll want to ensure that future commit messages open in a more familiar
editor. You can run the following commands in your terminal to ensure that
Visual Studio Code is your `git commit` editor from now on:

```sh
> git config --global core.editor "code --wait"
> git config --global -e
```

If you experience any issues, you may be missing Visual Studio Code's command
line tools. You can find more details and some troubleshooting tips on
Microsoft's official [VS Code and macOS documentation].

 Use `git log` to see this history at any time. This command will show
all the commits in your repository's history, beginning with the most recent:

![image-git-log-output][image-git-log-output]

Like many Git commands, `git commit` includes some helpful shorthand. If you
need a rather short commit message, you can use the `-m` flag to include the
message inline. Here's an example:

```sh
> git commit -m "Fix typo"
```

This will commit your changes with the message "Fix typo" and avoid opening your
default text editor. Remember the commit messages are how you make your
project's history friendly to humans, so don't use the `-m` flag as an excuse to
write lame commit messages! A commit message should always explain why changes
were made in clear, concise language. It is also best practice to use imperative
voice in commit messages (i.e. use "Fix typo" instead of "Fixing the typo" or
"Typo was fixed").

 Let's explore a new realm with
_branches_. A branch is a separate timeline in Git, reserved for its own
changes. You'll use branches to make your own changes independently of others.
These branches can then be _merged_ back into the main branch at a later time.

Let's consider a common scenario: a school project. It's a lot of extra hassle
to schedule time together and argue over exactly what should be done next!
Instead, group members will often assign tasks amongst themselves, work
independently on their tasks, and reunite to bring it all together as a final
report. Git branches let us emulate this workflow for code: you can make a copy
of what's been done so far, complete a task on your new branch, and merge that
branch back into the shared repository for others to use.

By default, Git repos begin on the `master` branch. To create a new branch, use
`git branch <name-of-your-branch>`. This will create a named reference to your
current commit and let you add commits without affecting the `master` branch.
Here's what a branch looks like:

![image-git-branch][image-git-branch]

Notice how your refs help to identify branches here: `master` stays to itself
and can have changes added to it independently of your new branch (`footer`).
`HEAD`, Git's special ref, follows us around, so you know that in the above
diagram you're working on the `footer` branch.

You can create a new branch or visit an existing branch in your repository. This
is especially helpful for returning the `master` branch or for projects you've
received from teammates. To open an existing branch, use `git checkout
<name-of-branch>`.

### Bringing it back together

Once you're happy with the code in the branch you've been working on, you'll
likely want to integrate the code into the `master` branch. You can do this via
`git merge`. Merging will bring the changes in from another branch and integrate
them into yours. Here's an example workflow:

```sh
> git branch my-changes
> git add new-file.js
> git commit -m "Add new file"
> git checkout master
> git merge my-changes
```

Following these steps will integrate the commit from `my-changes` over to
`master`. Boom! Now you have your `new-file.js` on your default branch.

As you can imagine, branching can get _very_ complicated. Your repository's
history may look more like a shrub than a beautiful tree! You'll discuss
advanced merging and other options in an upcoming lesson.

## Connecting with the world via GitHub

Git can act as a great history tool and source code backup for your local
projects, but it can also help you work with a team! Git is classified as a
"DVCS", or "Distributed Version Control System". This means it has built-in
support for managing code both locally and from a distant source.

You can refer to a repository source that's not local as a _remote_. Your Git
repository can have any number of remotes, but you'll usually only have one. By
default you'll refer to the primary remote of a repo as the `origin`.

You can add a remote to an existing repository on your computer, or you can
retrieve a repository from a remote source. You can refer to this as _cloning_
the repo. Once you have a repository with a remote, you can update your local
code from the remote by _pulling_ code down, and you can _push_ up your own code
so others have access to it.

### Collaboration via Git and GitHub

While a remote Git server can be run anywhere, there are a few places online
that have become industry standards for hosting remote Git repositories. The
best-known and most widely-used Git source is a website called [GitHub]. As the
name suggests, GitHub is a global hub for Git repositories. It's free to make a
Github account, and you'll find literally millions of public repositories you
can browse.

GitHub takes a lot of work out of managing remote Git repositories. Instead of
having to manage your own server, GitHub provides managed hosting and even
includes some helpful graphical tools for complicated tasks like deployment,
branch merging, and code review.

Let's look at a typical workflow using Git and GitHub. Imagine it's your first
day on the job. How do you get access to your team's codebase? By cloning the
repository!

```sh
> git clone https://github.com/your-team/your-codebase.git
```

Using the `git clone` command will create a new folder in your current directory
named after the repo you're cloning (in this case, `your-codebase`).  Now you're ready to get started.

You'll likely start on the `master` branch, but remember that this is the
default branch and it's unlikely you want to make changes to it. Since you're
working on a team now, it's important to think of how your changes to the
repository might affect others. The safest way to make changes is to create a
new branch, make your changes there, and then push your branch up to the remote
repository for review. You'll use the `git push` command to do this. Let's look
at an example:

```sh
> git branch add-my-new-file
> git add my-new-file.js
> git commit -m "Add new file"
> git push -u origin add-my-new-file
```

Notice how you used the `-u` flag with `git push`. This flag, shorthand for
`--set-upstream`, lets Git know that you want your local branch to follow a
remote branch. You've passed the same name in, so you'll now have two branches
in your local repository: `add-my-new-file`, which is where your changes live
after being committed, and `origin/add-my-new-file`, which keeps up with your
remote branch and updates it after you use `git push`. You only need to use the
`-u` flag the first time you push each new branch - Git will know what to do
with a simple `git push` from then on.

You now know how to push your changes up, but what about getting the changes
your teammates have made? For this, you'll use `git pull`. Pulling from the
remote repo will update all of your local branches with the code from each
branch's remote counterpart. Behind the scenes, Git is running two separate
commands: `git fetch` and `git merge`. Fetching retrieves the repository code
and updates any remote tracking branches in your local repo, and merge does just
you've already explored: integrates changes into the local branches. Here's a
graphic to explain this a little better:

![image-git-pull-parts][image-git-pull-parts]

It's important to remember to use `git pull` often.  The more
often you `pull`, the more certain you can be that your own code is based on the
"latest and greatest".

### Merging your code on GitHub

If you're paying close attention, you may have noticed that there's a missing
step in your workflows so far: how do you get your code merged into your default
branch? This is done by a process called a _Pull Request_.

A pull request (or "PR") is a feature specific to GitHub, not a feature of Git.
It's a safety net to prevent bugs, and it's a critical part of the collaboration
workflow. Here's a high-level of overview of how it works:

- You push your code up to GitHub in its own branch.
- You open a pull request against a _base branch_.
- GitHub creates a comparison page just for your code, detailing the changes
  you've made.
- Other members of the team can review your code for errors.
- You make changes to your branch based on feedback and push the new commits up.
- The PR automatically updates with your changes.
- Once everyone is satisfied, a repo maintainer on GitHub can merge your branch.
- Huzzah! Your code is in the main branch and ready for everyone else to
  `git pull`.

You'll create and manage your pull requests via GitHub's web portal, instead of
the command line. You'll walk through the process of creating, reviewing, and
merging a pull request in an upcoming project.

## What you've learned

This lesson included lots of new lingo and two new tools you can take advantage
of immediately: Git and GitHub.

- You should feel comfortable exploring both of these more on your own.
- You should understand that a VCS is a critical part of your development
  workflow.
- You able to get started tracking your own projects and sharing code across a
  team.

If it's still a little hazy, never fear! Git will be a core part of your
projects going forward. You'll get lots of practice `pull`ing, `push`ing, and
`clone`-ing in the coming months.

[GitHub]: https://github.com
[VS Code and macOS documentation]:
  https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line
[image-git-timeline]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-timeline.svg
[image-git-status-output]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-status-output.svg
[image-git-log-output]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-log-output.svg
[image-git-branch]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-branch.svg
[image-git-pull-parts]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-pull-parts.svg

________________________________________________________________________________
# Browsing Your Git Repository

Repositories can feel intimidating at first, but it won't take you long to
navigate code like you own the place - because you do! Let's discuss a few tools
native to Git that help us browse our changes over time.

We'll be covering:

- Comparing changes with `git diff`
- Browsing through our code "checkpoints" with `git checkout`

## Seeing changes in real time

Git is all about change tracking, so it makes sense that it would include a
utility for visualizing a set of changes. We refer to a list of differences
between two files (or the same file over time) as a _diff_, and we can use
`git diff` to visualize diffs in our repo!

When run with no extra options, `git diff` will return any tracked changes in
our working directory since the last commit. **Tracked** is a key word here;
`git diff` won't show us changes to files that haven't been included in our repo
via `git add`. This is helpful for seeing what you've changed before committing!
Here's an example of a small change:

![git-diff][git-diff]

Let's break down some of the new syntax in this output.

- The diff opens with some Git-specific data, including the branch/files we're
  checking, and some unique hashes that Git uses to track each diff. You can
  skip past this to get to the important bits.

- `---` & `+++` let us know that there are both additions and subtractions in
  the file "App.js". A diff doesn't have a concept of inline changes - it treats
  a single change as removing something old and replacing it with something new.

- `@@` lets us know that we're starting a single "chunk" of the diff. A diff
  could have multiple chunks for a single file (for example: if you made changes
  far apart, like the header & footer). The numbers in between tell us how many
  lines we're seeing and where they start. For example: `@@ +1,3 -1,3 @@` means
  we'll see three lines of significant content, including both addition &
  removal, beginning at line one.

- In the code itself, lines that were removed are prefixed with a `-` and lines
  that were added are prefixed with a `+`. Remember that you won't see these on
  the same lines. Even if you only changed a few words, Git will still treat it
  like the whole line was replaced.

[git-diff]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-diff-output.svg

### Diff options

Remember that, by default, `git diff` compares the current working directory to
the last commit. You can compare the staging area instead of the working
directory with `git diff --staged`. This is another great way to double-check
your work before pushing up to a remote branch.

You're also not limited to your current branch - or even your current commit!
You can pass a base & target branch to compare, and you can use some special
characters to help you browse faster! Here are a few examples:

```sh
# See differences between the 'feature'
# branch and the 'master' branch.
> git diff master feature

# Compare two different commits
> git diff 1fc345a 2e3dff

# Compare a specific file across separate commits
> git diff 1fc345a 2e3dff my-file.js
```

## Time travel

`git diff` gives us the opportunity to explore our code's current state, but
what if we wanted to see its state at a different point in time? We can use
_checkout_! `git checkout` lets us take control of our `HEAD` to bounce around
our timeline as we please.

Remember that `HEAD` is a special Git reference that usually follows the latest
commit on our current branch. We can use `git checkout` to point our `HEAD`
reference at a different commit, letting us travel to any commit in our
repository's history. By reading the commit message and exploring the code at
the time of the commit, we can see not only what changed but also why it
changed! This can be great for debugging a problem or understanding how an app
evolved.

Let's look at a diagram to understand what `checkout` does a little better:

![checkout][img-checkout]

Notice that we haven't lost any commits, commit messages, or code changes. Using
`git checkout` is entirely non-destructive.

To browse to a different commit, simply pass in a reference or hash for the
commit you'd like to explore. `git checkout` also supports a few special
characters & reserved references:

```sh
# You can checkout a branch name.
# You'll be using this particular branch a lot!
> git checkout master

# You can also use commit hashes directly
> git checkout 7d3e2f1

# Using a hyphen instead of a hash will take
# you to the last branch you checked out
> git checkout -

# You can use "HEAD~N" to move N commits prior
# to the current HEAD
> git checkout HEAD~3
```

Once you're done browsing the repo's history, you can use
`git checkout <your-branch-name>` to move `HEAD` back to the front of the line
(your most recent commit). For example, in our diagram above, we could use
`git checkout master` to take our `HEAD` reference back to commit `42ffa1`.

[img-checkout]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-checkout.svg

### Why checkout?

Most of Git's power comes from a simple ability: viewing commits in the past and
understanding how they connect. This is why mastering the `git checkout` command
is so important: it lets you think more like Git and gives you full freedom of
navigation without risking damage to the repo's contents.

That said, you'll likely use shortcuts like `git checkout -` far more often than
specifically checking out commit hashes. Especially with the advent of
user-friendly tools like GitHub, it's much easier to visualize changes outside
the command line. We'll demonstrate browsing commit histories on GitHub in a
future lesson.

## What we've learned

We're building our skill set for navigating code efficiently, and we're starting
to got more accustomed to seeing our projects as a series of checkpoints we can
review instead of a single point in time.

- You should be able to compare code changes between commits or files.
- You should have confidence when switching between branches or commits.
- You should understand the role of `git checkout` as fundamental to how Git
  organizes our projects.

________________________________________________________________________________
# Git Do-Overs: Reset & Rebase

Git is designed to protect you - not only from others, but also from yourself!
Of course, there are times where you'd like to exercise your own judgement, even
if it may not be the best thing to do. For this, Git provides some helpful tools
to change commits and "time travel".

Before we talk about these, a warning: **The commands in this lesson are
destructive!** If used improperly, you could lose work, damage a teammate's
branch, or even rewrite the history of your entire project. You should exercise
caution when using these on production code, and don't hesitate to ask for help
if you're unsure what a command might do.

After this lesson, you should:

- Be able to roll back changes to particular commit.

- Know when to rebase/reset and when **not** to.

## Resetting the past

Remember how our commits form a timeline? We can see the state of our project at
any point using `git checkout`. What if we want to travel back in time to a
point before we caused a new bug or chose a terrible font? `git reset` is the
answer!

_Resetting_ involves moving our `HEAD` ref back to a different commit. No matter
how we reset, `HEAD` will move with us.  We can use some additional flags to determine how
our code changes are handled.

## Starting small: Soft resets

The least-dangerous reset of all is `git reset --soft`. A soft reset will move
our `HEAD` ref to the commit we've specified, and will leave any intermediate
changes in the staging area.

A practical example of when a soft reset would be handy is joining some small
commits into a larger one. We'll pretend we've been struggling with "their",
"there", and "they're" in our app.  We'll fix them with a soft reset:

```sh
git reset --soft 9c5e2fc
```

This moves our `HEAD` ref back to our first commit. Looking at our commit log
now, we might be worried we've lost our changes:

![image-git-reset-soft-history-during][image-git-reset-soft-history-during]

However, check out `git status`:

![image-git-reset-status-after-soft][image-git-reset-status-after-soft]

You'll see that our changes are still present in the staging area, ready to be
re-committed when we're ready! We can use `git commit` to re-apply those changes
to our commit history with a new, more helpful message instead:

![image-git-reset-soft-history-after][image-git-reset-soft-history-after]

Notice that the new commit has a totally new hash. The old commit messages (and
their associated hashes) have been lost, but our code changes are safe and
sound!

[reset-soft-history-before]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-reset-soft-history-before.svg
[image-git-reset-soft-history-during]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-reset-soft-history-during.svg
[image-git-reset-status-after-soft]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-reset-status-after-soft.svg
[image-git-reset-soft-history-after]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-reset-soft-history-after.svg

## Getting riskier: Mixed resets

If soft resets are the safest form of `git reset`, mixed resets are the most
average! This is exactly why they're the default: running `git reset` without
adding a flag is the same as running `git reset --mixed`.

In a mixed reset, your changes are preserved, but they're moved from the commit
history directly to the working directory. This means you'll have to use
`git add` to choose everything you want in future commits.

Mixed resets are a good option when you want to alter a change in a previous
commit. Let's use a mixed reset with our "their", "there", "they're" example
again.

We'll start with "they're":

![image-git-reset-mixed-history-before][image-git-reset-mixed-history-before]

Instead of pushing ahead, we'd like to revoke that change and try it again.
Let's use a mixed reset:

```sh
git reset 9c5e2fc
```

Now you'll see that your changes are in the working directory instead of the
staging area:

![image-git-reset-status-after-mixed][image-git-reset-status-after-mixed]

You can edit your files, make the changes you'd like, and use `git add` and
`git commit` to add a new commit to your repo:

![image-git-reset-mixed-history-after][image-git-reset-mixed-history-after]

Notice again that you don't lose your code with a mixed reset, but you do lose
your commit messages & hashes. The difference between `--soft` and `--mixed`
comes down to whether you'll be keeping the code exactly the same before
re-committing it or making changes.

[image-git-reset-mixed-history-before]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-reset-mixed-history-before.svg
[image-git-reset-status-after-mixed]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-reset-status-after-mixed.svg
[image-git-reset-mixed-history-after]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-reset-mixed-history-after.svg

## Red alert! Hard resets

Hard resets are the most dangerous type of reset in Git.  Poof. Gone forever.

There are very few good uses for a hard reset, but one is to get yourself out of
a tight spot. Let's say you've made a few changes to your repository but you now
realize those changes were unnecessary. You'd like to move back in time so that
your code looks exactly as it did before any changes were made.
`git reset --hard` can take you there.

It's our last round with "their", "there", and "they're". We've tried it all
three ways and decided we don't need to use that word at all! Let's walk through
a hard reset to get rid of our changes.

We'll start in the same place we began for our soft reset:

![image-git-reset-soft-history-before][image-git-reset-soft-history-before]

It turns out that we'll be using a video on our homepage and don't need text at
all! Let's step back in time:

```sh
git reset --hard 9c5e2fc
```

Our Git log output is much simpler now:

![image-git-reset-soft-history-during][image-git-reset-soft-history-during]

Take a look at `git status`:

![image-git-reset-status-before-after][image-git-reset-status-before-after]

It's empty - no changes in your working directory and no changes in your staging
area. This is major difference between a hard reset and a soft/mixed reset: you
will lose _all your changes_ back to the commit you've reset to.

If your teammate came rushing in to tell you that the boss has changed their
mind and wants that homepage text after all, you're going to be re-doing all
that work! Be very confident that the changes you're losing are unimportant
before embarking on a hard reset.

[image-git-reset-soft-history-before]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-reset-soft-history-before.svg
[image-git-reset-soft-history-during]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-reset-soft-history-during.svg
[image-git-reset-status-before-after]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-reset-status-before-after.svg

## Rebase: An alternative form of time travel

Sometimes we want to change more than a few commits on a linear timeline. What
if we want to move multiple commits across branches? `git rebase` is the tool
for us!

_Rebasing_ involves changing your current branch's base branch. We might do this
if we accidentally started our branch from the wrong commit or if we'd like to
incorporate changes from another branch into our own.

You're probably thinking "Gee, this sounds familiar! Can't we accomplish those
tasks with `git merge`?" In almost all cases, you'd be right. Rebasing is a
dangerous process that effectively rewrites history. There's a whole slew of
movies, books, and TV shows that explain why rewriting history is a bad idea!

## Okay, rebasing is risky! Show me anyway.

Let's look at a situation where we might be tempted to rebase. We've added a
couple commits to a feature branch while other team members have been merging
their code into the `master` branch. Once we're ready to merge our own branch,
we probably want to follow a tried-and-true procedure:

```sh
> git pull origin master
```

This will fetch our remote `master` branch and merge its changes into our own
feature branch, so it's safe to pull request or `git push`. However, every time
we do that, a merge commit will be created! This can make a big mess of our Git
commit history, especially if lots of people are making small changes.

We can use `git rebase` to move our changes silently onto the latest version of
`master`. Here's what the `git log` history of our two example branches looks
like:

### `master`

![image-git-rebase-master-before][image-git-rebase-master-before]

[image-git-rebase-master-before]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-rebase-master-before.svg

### `working-on-the-header` (our feature branch)

![image-git-rebase-feature-before][image-git-rebase-feature-before]

Notice that both branches start at `9c5e2fc`. That's our common ancestor commit,
and is where `git merge` would start stitching these branches together! We're
going to avoid that entirely with a rebase. We'll run this command while we have
`working-on-the-header` checked out:

```sh
git rebase master
```

Here's our new commit history:

![image-git-rebase-after][image-git-rebase-after]

And a diagram of what just happened:

![image-git-rebase-before-and-after][image-git-rebase-before-and-after]

See how we changed the color of our commits after the rebase? Take a close look
at the commit history changes as well. Even though our commits have the same
content, they have a new hash assigned, meaning they're entirely new commits!
This is what we mean by "rewriting history": we've actually changed how Git
refers to these changes now.

[image-git-rebase-feature-before]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-rebase-feature-before.svg
[image-git-rebase-after]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-rebase-after.svg
[image-git-rebase-before-and-after]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-rebase-before-and-after.svg

## One last warning & the "Golden Rule of Git"

These tools can all feel pretty nifty, but be very wary of using them too much!
While they can augment your Git skills from good to great, they can also have
catastrophic side effects.

There's a "Golden Rule of Git" you should know that directly relates to both
`git reset` and `git rebase`:

> Never change the history of a branch that's shared with others.

That's it! It's simple and to the point. If you're resetting or rebasing your
own code and you make a mistake, your worst case scenario is losing your own
changes. However, if you start changing the history of code that others have
contributed or are relying on, your accidental loss could affect many others!

## What we've learned

What a wild trip we've been on! Watching commits come and go as we `git reset`
and `get rebase` can get a little confusing. Remember that while these tools are
unlikely to be part of your everyday workflow, they're great topics for
technical interviews. You should:

- Understand how `git reset` differs from `git checkout`.
- Be able to list the 3 types of `git reset` and differentiate them.
- Be comfortable comparing and contrasting `git rebase` and `git merge`.
- Remember the "Golden Rule of Git": never rewrite history after a `git push`!

________________________________________________________________________________
# Git Merge Conflicts & You

Welcome to the arena! Let's discuss what you'll need to do when attempting to
merge two conflicting Git branches. You'll get to make the final say in which
code enters...and which code leaves!

In this lesson, we'll discuss:

- The `git merge` process in-depth
- Managing conflicting code across branches
- Common workflows to help know how & when to merge

## What is a "merge conflict"?

Whoa there - maybe we dove in a little too fast. Let's discuss what a merge
conflict is and how we can resolve it.

First off, what is a _merge conflict_? It's a special state Git presents us with
when two branches have code changes that are incompatible with each other.
Here's a very simple example:

- You're working on a team trying to design a new app. You're working on the Git
  branch `my-red-app`, because you've decided that the app's primary color
  should be red! You add the following code to line 3 of your app's main file,
  `App.js`:

```javascript
this.primaryColor = red;
```

- At the same time, one of your teammates has opened the `my-blue-app` branch
  with an alternative decision on your app's aesthetics. They add the following
  code to line of 3 of their `App.js` file:

```javascript
this.primaryColor = blue;
```

- Your friend types a little faster than you and has already merged their code
  into the `master` branch. You get ready to merge your own code and...**Merge
  Conflict!**

Git identifies changes to `master` since your branch began and flags similar
changes in the same place on your branch. Instead of trying to make a decision
on your behalf, it hands you control. A merge conflict is Git's way of saying
"I'm not sure what to do - help!".

Here's what a merge conflict looks like between branches:

![mrg-conflict][mrg-conflict]

Yikes! Remember that this looks awfully complicated, but the theory is pretty
simple. In the workplace you'll need to resolve much more complicated conflicts
than this so now's the time to get your practice in.

[mrg-conflict]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-merge-conflict.svg

## Resolving a merge conflict

Git is a complex tool, but it's built to help guide us as much as it can. Merge
conflicts are no different. You will find that resolving them is easy once you
know what you're looking at.

We'll stick with our "Red vs. Blue" example from above. When you attempt to
`git merge`, you'll get a message like the following:

![mrg-conflict-msg][mrg-conflict-msg]

Git is so helpful - it's telling us where to look _and_ what to do! Following
the instructions here, we'll look at `App.js`, resolve the conflict, and
`git commit` with our resolved file(s).

For even more info, check out `git status` during a merge conflict:

![mrg-conflict-status][mrg-conflict-status]

Notice the `both modified` prefix, reminding us that we have a conflict. "Both"
refers to our two branches, `my-red-app` and `master`, which each include
changes to the conflicting file. It's up to us to decide what code the file
should contain when we complete the merge.

[mrg-conflict-msg]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-merge-conflict-message.svg
[mrg-conflict-status]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-merge-conflict-status-output.svg

## Conflict Resolution

If we open the conflicting file, we'll see some new syntax:
![conflict-operators][conflict-operators]

Notice the `<<<<<<` (line 3), `======` (line 5), and `>>>>>>` (line 7). These
are special delimiters that Git uses to separate two pieces of conflicting code.

The first piece of code (between `<<<<<<` and `======`) comes from our _base
branch_ - the branch we're merging in to, which we're currently on. We can see
it's labelled "HEAD", and VS Code is helping us out by noting that this is the
"Current Change".

The second piece of code (between `======` and `>>>>>>`) comes from our
_incoming branch_. VS Code is again helping us out by labelling this as the
"Incoming Change".

To resolve this conflict, we need to decide which code to keep and which to get
rid of. This is where your communication skills become important! During a merge
conflict, you'll need to check in with teammates to decide what's best. Once
you've come to a decision, you can edit the file, leaving only the code you want
in the base branch when the conflict is over. If we decided to keep "red" in our
example, we would delete lines 3, 4, 5, and 7.

You can do this manually in other editors, but VS Code helps us by providing the
"Accept" buttons above our conflict. You can click "Accept Incoming Changes" to
automatically update the code for us. It will remove the "Current Changes" and
any delimiters related to this conflict, leaving only the "Incoming Changes" we
chose to keep.

[conflict-operators]:
  https://-open-assets.s3-us-west-1.amazonaws.com/Module-JavaScript/git/assets/image-git-merge-conflict-inline-operators.svg

## Back on solid ground

Once you've saved your resolved file, the process is more familiar. You'll save
your file, use `git add` to add it to the staging area, and `git commit` to
complete the merge. Git will help you out with the commit message: it should say
something like "Merge branch 'my-red-branch'", though you can change this during
the commit process if you'd like.

There are a few important things to note:

- Not every merge results in a conflict, and not every change between two
  branches requires resolution! Git is smart about bringing code together when
  it's in separate files or on different lines, so it won't need your help to
  resolve every single change. It's only when two pieces of code actually
  conflict that Git will ask you to get involved.

- `git merge` is the safest way to ensure your code is up to date. We've looked
  at merging a "finished" branch back into `master` here, but you can also merge
  `master` into your feature branch while you're working on it! While this may
  cause conflicts, you're well-equipped to handle them now.

- Merge conflicts will always result in a _merge commit_: an extra commit in
  your history documenting where code was merged in from other sources. We'll
  discuss more dangerous ways of merging in code without these commits in an
  upcoming lesson.

## What we've learned

Whew! We've emerged victorious from our merge conflict and can start work on a
new branch or feature. Merge conflicts are a nearly daily part of life as a
developer.

- You should now be able to identify the difference between a base branch and
  incoming branch.
- You should understand how `git merge` works and what it does when it's unable
  to proceed automatically.
- You're now familiar with resolving merge conflicts, both with VS Code's
  helpers and when in another editor by manually editing code.

________________________________________________________________________________
# "Scrum" Stands For ... Nothing!

The word "scrum" is not an acronym. Rather, it is a term borrowed from the sport
of rugby where it refers to the method of restarting a game after an accidental
infringement, or when the ball has gone out of play. The players of the two
teams group together around the rugby ball, arms locked, heads down, struggling
to gain possession of the ball. An article in the _Harvard Business Review_ used
this sports-based phenomenon as a metaphor for product development in the 1986
article "The New New Product Development Game".

> The ... "relay race" approach to product development ... may conflict with the
> goals of maximum speed and flexibility. Instead a holistic or “rugby”
> approach—where a team tries to go the distance as a unit, passing the ball
> back and forth—may better serve today’s competitive requirements.

This article inspired Jeff Sutherland to invent the "Scrum process" in 1993 for
use on a software development team. at Easel Corporation. Two years later, Ken
Schwaber published the first paper on Scrum at OOPSLA. From that conference,
others tried the methodology as Sutherland and Schwaber wrote books, articles,
and presented at conferences about their novel approach to creating software.

In this reading, you will learn about all of the different practices and
artifacts in the standard Scrum framework.

## The standard Scrum process

Surprise! There is _no_ standardized process! There is no series of sequential
steps for you and your team to methodically follow to produce high-quality
products. Instead, Scrum is a **framework** for organizing and managing work. It
is a framework based on a set of values, practices, and principles that provide
a foundation to which your team can add its unique practices and specific
approaches for realizing "Scrum". This results in a version of Scrum that
uniquely fits your team.

This is the reason that Scrum has become the leading contender in the pantheon
of certified Agile software development methodologies. Most of the other
methodologies have sets of strict rules about what must be done and actions that
people must take. These restrictions made those other Agile software development
methodologies unpalatable to many companies.

Of course, the flip side is that an organization's "unique practices and special
approaches" can pollute the Scrum process, turing it into an aberration and
rendering it a useless and frustrating morass of bureaucracy and bookkeeping.
So, best to keep it as pure and simple as the Scrum framework describes.

## The Scrum practices

Scrum has been described as a "refreshingly simple, people-centric framework
based on the values of honesty, openness, courage, respect, focus,