text:
# JavaScript events marking guide

The aim of the tasks is to demonstrate an understanding of the JavaScript features covered in the [Introduction to events](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events) lesson in Learn Web Development on MDN.

Note: If there is an error in your code, it will be outputted into the results panel on the page, to help you try to figure out the answer (or into the browser's JavaScript console, in the case of the downloadable version).

## Task 1

In our first events-related task, you need to create a simple event handler that causes the text inside the button to change when it is clicked on, and change back when it is clicked again.

The HTML should not be changed; just the JavaScript.

The finished code should look something like this:

```
const btn = document.querySelector('button');

btn.addEventListener('click', () => {
  if (btn.className === 'on') {
    btn.textContent = 'Machine is off';
    btn.className = "off";
  } else {
    btn.textContent = 'Machine is on';
    btn.className = "on";
  }
});
```

## Task 2

Now we'll look at keyboard events. To pass this assessment you need to build an event handler that moves the circle around the provided canvas when the WASD keys are pressed on the keyboard. The circle is drawn with the function `drawCircle()`.

The finished code should look something like this:

```
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

function drawCircle(x, y, size) {
  ctx.fillStyle = 'white';
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  ctx.beginPath();
  ctx.fillStyle = 'black';
  ctx.arc(x, y, size, 0, 2 * Math.PI);
  ctx.fill();
}

let x = 50;
let y = 50;
const size = 30;

drawCircle(x, y, size);

// Add your code here

window.addEventListener('keydown', e => {
  switch(e.key) {
    case 'a':
      x -= 2;
      break;
    case 'd':
      x += 2;
      break;
    case 'w':
      y -= 2;
      break;
    case 's':
      y += 2;
      break;
  }

  drawCircle(x, y, size);
});
```

## Task 3

Our final events-related task involves making use of bubbling and event objects. You need to set a click listener on the buttons' parent element, which when invoked by clicking any of the buttons will use `e.target` to grab the `data-color` attribute of the particular button that was clicked, and set the background of the `button-bar` to that color.

You should be able to solve this without looping through all the buttons and giving each one their own event listener.

The code should look like this:

```
const buttonBar = document.querySelector('.button-bar');

  // Add your code here

function setColor(e) {
  buttonBar.style.backgroundColor = e.target.getAttribute('data-color');
}

buttonBar.addEventListener('click', setColor);
```


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Events: Task 2</title>
    <link rel="stylesheet" href="../styles.css" />

    <canvas width="480" height="320" tabindex="0">

    </canvas>

    <textarea class="playable playable-js" style="height: 220px;">

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

function drawCircle(x, y, size) {
  ctx.fillStyle = 'white';
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  ctx.beginPath();
  ctx.fillStyle = 'black';
  ctx.arc(x, y, size, 0, 2 * Math.PI);
  ctx.fill();
}

let x = 50;
let y = 50;
const size = 30;

drawCircle(x, y, size);

// Add your code here

    </textarea>

      <input id="reset" type="button" value="Reset" />

repo_name: mdn/learning-area

repo_language: HTML

mime_type: text/plain


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Events: Task 1</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }

      button {
        display: block;
        margin: 20px 0 20px 20px;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">
    </section>

    <button class="off">Machine is off</button>

  <script>
    const btn = document.querySelector('.off');

    // Add your code here

  </script>

  </body>
</html>


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Events: Task 3</title>
    <link rel="stylesheet" href="../styles.css" />

      <button data-color="red">Red</button>
      <button data-color="yellow">Yellow</button>
      <button data-color="green">Green</button>
      <button data-color="purple">Purple</button>

    <textarea class="playable playable-js" style="height: 220px;">

      const buttonBar = document.querySelector('.button-bar');

      // Add your code here

    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Events: Task 1</title>
    <link rel="stylesheet" href="../styles.css" />

    <button class="off">Machine is off</button>

    <textarea class="playable playable-js" style="height: 220px;">

const btn = document.querySelector('.off');

// Add your code here
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Events: Task 2</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }

      canvas {
        border: 1px solid black;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">
    </section>

    <canvas width="480" height="320" tabindex="0">

    </canvas>

  <script>
    const canvas = document.querySelector('canvas');
    const ctx = canvas.getContext('2d');

    function drawCircle(x, y, size) {
      ctx.fillStyle = 'white';
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      ctx.beginPath();
      ctx.fillStyle = 'black';
      ctx.arc(x, y, size, 0, 2 * Math.PI);
      ctx.fill();
    }

    let x = 50;
    let y = 50;
    const size = 30;

    drawCircle(x, y, size);

    // Add your code here

  </script>
  </body>

</html>


text:
<!DOCTYPE html>

    <meta charset="utf-8"/>
    <title>Events: Task 3</title>

    <link rel="stylesheet" href="../styles.css" />

      <button data-color="red">Red</button>
      <button data-color="yellow">Yellow</button>
      <button data-color="green">Green</button>
      <button data-color="purple">Purple</button>


text:
# JavaScript functions marking guide

The aim of the tasks is to demonstrate an understanding of the JavaScript features covered in the [Functions — reusable blocks of code](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/conditionals), [Build your own function](https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function), and [https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Return_values](https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Return_values) lessons in Learn Web Development on MDN.

Note: If there is an error in your code, it will be outputted into the results panel on the page, to help you try to figure out the answer (or into the browser's JavaScript console, in the case of the downloadable version).

## Task 1

In the first task, you have to create a simple function that prints a random name from the provided array to the provided paragraph, and then run it once.

The finished code should look something like this:

```
const names = ['Chris', 'Li Kang', 'Anne', 'Francesca', 'Mustafa', 'Tina', 'Bert', 'Jada']
const para = document.querySelector('p');

function chooseName() {
  const randomNumber = Math.floor(Math.random() * names.length);
  const choice = names[randomNumber];
  para.textContent = choice;
}

chooseName();
```

## Task 2

For our second functions-related task, you need to create a function that draws a rectangle on the provided `<canvas>`, based on five input variables — `x`, `y`, `width`, `height`, and `color`.

You'll want to clear the canvas before drawing, so that when the code is updated in the case of the live version, you don't get lots of rectangles drawn on top of one another.

The finished code should look something like this:

```
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

const x = 50;
const y = 60;
const width = 100;
const height = 75;
const color = 'blue';

function drawSquare(x, y, width, height, color) {
  ctx.fillStyle = 'white';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = color;
  ctx.fillRect(x, y, width, height);
}

drawSquare(x, y, width, height, color);
```

## Task 3

In this task, you return to the problem posed in Task 1, with the aim of improving it. The three improvements we are expecting here are:

1. Refactor the code that generates the random number into a separate function that takes two generic bounds that the random number should be between, and returns the result.
2. Update the `chooseName()` function so that it makes use of the random number function, takes the array to choose from as a parameter (making it more flexible), and returns its result.
3. Print this returned result into the paragraph.

```
const names = ['Chris', 'Li Kang', 'Anne', 'Francesca', 'Mustafa', 'Tina', 'Bert', 'Jada']
const para = document.querySelector('p');

function random(min, max) {
  const num = Math.floor(Math.random() * (max - min)) + min;
  return num;
}

function chooseItem(array) {
  const choice = array[random(0, array.length)];
  return choice;
}

para.textContent = chooseItem(names);
```

## Task 4

In this task, you are asked to change the named `isShort()` function into an arrow function expression.

The finished code should look something like this:

```
const names = ['Chris', 'Li Kang', 'Anne', 'Francesca', 'Mustafa', 'Tina', 'Bert', 'Jada']
const para = document.createElement('p');

const shortNames = names.filter(name => name.length < 5);
para.textContent = shortNames;
```


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Functions: Task 3</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    const names = ['Chris', 'Li Kang', 'Anne', 'Francesca', 'Mustafa', 'Tina', 'Bert', 'Jada']
    const para = document.createElement('p');

    // Add your code here

    // Don't edit the code below here!

    const section = document.querySelector('section');

    section.appendChild(para);
  </script>

</html>


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Functions: Task 1</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    const names = ['Chris', 'Li Kang', 'Anne', 'Francesca', 'Mustafa', 'Tina', 'Bert', 'Jada']
    const para = document.createElement('p');

    // Add your code here

    // Don't edit the code below here!

    const section = document.querySelector('section');

    section.appendChild(para);
  </script>

</html>


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Functions: Task 2</title>
    <link rel="stylesheet" href="../styles.css" />

    <canvas width="480" height="320">

    </canvas>

    <textarea class="playable playable-js" style="height: 220px;">
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

const x = 50;
const y = 60;
const width = 100;
const height = 75;
const color = 'blue';

// Add your code here

    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Functions: Task 2</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }

      canvas {
        border: 1px solid black;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

    <canvas width="480" height="320">

    </canvas>

  </body>
  <script>
    const canvas = document.querySelector('canvas');
    const ctx = canvas.getContext('2d');

    const x = 50;
    const y = 60;
    const width = 100;
    const height = 75;
    const color = 'blue';

    // Add your code here

    // Don't edit the code below here!

    const section = document.querySelector('section');
  </script>

</html>


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Functions: Task 1</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">
const names = ['Chris', 'Li Kang', 'Anne', 'Francesca', 'Mustafa', 'Tina', 'Bert', 'Jada']
const para = document.createElement('p');

// Add your code here

// Don't edit the code below here!

section.innerHTML = ' ';

section.appendChild(para);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Functions: Task 3</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">
const names = ['Chris', 'Li Kang', 'Anne', 'Francesca', 'Mustafa', 'Tina', 'Bert', 'Jada']
const para = document.createElement('p');

// Add your code here

// Don't edit the code below here!

section.innerHTML = ' ';

section.appendChild(para);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Functions: Task 3</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">
const names = ['Chris', 'Li Kang', 'Anne', 'Francesca', 'Mustafa', 'Tina', 'Bert', 'Jada'];
const para = document.createElement('p');

function isShort(name) {
  return name.length < 5;
}

const shortNames = names.filter(isShort);
para.textContent = shortNames;

// Don't edit the code below here!

section.innerHTML = ' ';

section.appendChild(para);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Functions: Task 4</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    const names = ['Chris', 'Li Kang', 'Anne', 'Francesca', 'Mustafa', 'Tina', 'Bert', 'Jada'];
    const para = document.createElement('p');

    function isShort(name) {
      return name.length < 5;
    }

    const shortNames = names.filter(isShort);
    para.textContent = shortNames;

    // Don't edit the code below here!

    const section = document.querySelector('section');

    section.appendChild(para);
  </script>

</html>


text:
const name = 'Chris';
function greeting() {
  alert(`Hello ${name}: welcome to our company.`);
}


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Function library example</title>

  <input class="numberInput" type="text">


text:
<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Function stage 4</title>
    <style>
      .msgBox {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%,-50%);
        width: 242px;
        border-radius: 10px;
        background-color: #eee;
        background-image: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.1));
      }

      .msgBox p {
        line-height: 1.5;
        padding: 10px 20px;
        color: #333;
        padding-left: 82px;
        background-position: 25px center;
        background-repeat: no-repeat;
      }

      .msgBox button {
        background: none;
        border: none;
        position: absolute;
        top: 0;
        right: 0;
        font-size: 1.1rem;
        color: #aaa;
      }

    </style>
  </head>
  <body>
    <button>Display message box</button>

    <script>

      const btn = document.querySelector('button');
      btn.addEventListener('click', () => displayMessage('Brian: Hi there, how are you today?', 'chat'));

      function displayMessage(msgText,msgType) {
        const html = document.querySelector('html');

        const panel = document.createElement('div');
        panel.setAttribute('class','msgBox');
        html.appendChild(panel);

        const msg = document.createElement('p');
        msg.textContent = msgText;
        panel.appendChild(msg);

        const closeBtn = document.createElement('button');
        closeBtn.textContent = 'x';
        panel.appendChild(closeBtn);

        closeBtn.onclick = function() {
          panel.parentNode.removeChild(panel);
        }

        if(msgType === 'warning') {
          msg.style.backgroundImage = 'url(icons/warning.png)';
          panel.style.backgroundColor = 'red';
        } else if(msgType === 'chat') {
          msg.style.backgroundImage = 'url(icons/chat.png)';
          panel.style.backgroundColor = 'aqua';
        } else {
          msg.style.paddingLeft = '20px';
        }
      }

    </script>
  </body>
</html>


text:
<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Function start</title>
    <style>
      .msgBox {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%,-50%);
        width: 200px;
        background: #eee;
      }

      .msgBox p {
        line-height: 1.5;
        padding: 10px 20px;
        color: #333;
      }

      .msgBox button {
        background: none;
        border: none;
        position: absolute;
        top: 0;
        right: 0;
        font-size: 1.1rem;
        color: #aaa;
      }

    </style>
  </head>
  <body>
    <button>Display message box</button>

    <script>

    </script>
  </body>
</html>


text:
const name = 'Zaptec';
function greeting() {
  alert(`Our company is called ${name}.`);
}


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Conflict example</title>

My body


text:
<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Function stage 2</title>
    <style>
      .msgBox {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%,-50%);
        width: 200px;
        border-radius: 10px;
        background-color: #eee;
        background-image: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.1));
      }

      .msgBox p {
        line-height: 1.5;
        padding: 10px 20px;
        color: #333;
      }

      .msgBox button {
        background: none;
        border: none;
        position: absolute;
        top: 0;
        right: 0;
        font-size: 1.1rem;
        color: #aaa;
      }

    </style>
  </head>
  <body>
    <button>Display message box</button>

    <script>
      function displayMessage() {
        const html = document.querySelector('html');

        const panel = document.createElement('div');
        panel.setAttribute('class','msgBox');
        html.appendChild(panel);

        const msg = document.createElement('p');
        msg.textContent = 'This is a message box';
        panel.appendChild(msg);

        const closeBtn = document.createElement('button');
        closeBtn.textContent = 'x';
        panel.appendChild(closeBtn);

        closeBtn.addEventListener('click', () => panel.parentNode.removeChild(panel));
      }
    </script>
  </body>
</html>


text:
<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Function stage 3</title>
    <style>
      .msgBox {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%,-50%);
        width: 200px;
        border-radius: 10px;
        background-color: #eee;
        background-image: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.1));
      }

      .msgBox p {
        line-height: 1.5;
        padding: 10px 20px;
        color: #333;
      }

      .msgBox button {
        background: none;
        border: none;
        position: absolute;
        top: 0;
        right: 0;
        font-size: 1.1rem;
        color: #aaa;
      }

    </style>
  </head>
  <body>
    <button>Display message box</button>

    <script>

      const btn = document.querySelector('button');

      btn.addEventListener('click', displayMessage);

      function displayMessage() {
        const html = document.querySelector('html');

        const panel = document.createElement('div');
        panel.setAttribute('class','msgBox');
        html.appendChild(panel);

        const msg = document.createElement('p');
        msg.textContent = 'This is a message box';
        panel.appendChild(msg);

        const closeBtn = document.createElement('button');
        closeBtn.textContent = 'x';
        panel.appendChild(closeBtn);

        closeBtn.onclick = function() {
          panel.parentNode.removeChild(panel);
        }
      }

    </script>
  </body>
</html>


text:
<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Function scope example</title>
  </head>
<body>

  <script>
    const x = 1;

    function a() {
      const y = 2;
    }

    function b() {
      const z = 3;
    }

    function output(value) {
      const para = document.createElement('p');
      document.body.appendChild(para);
      para.textContent = `Value: ${value}`;
    }
  </script>
</body>
</html>


text:
<!DOCTYPE html>

    <meta charset="utf-8">

    <title>Number guessing game</title>

Number guessing game

We have selected a random number between 1 and 100. See if you can guess it in 10 turns or fewer. We'll tell you if your guess was too high or too low.

      Enter a guess:
      <input type="number" min="1" max="100" required id="guessField" class="guessField">
      <input type="submit" value="Submit guess" class="guessSubmit">


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>JavaScript label example</title>

Player 1: Chris


text:
<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Apply JavaScript example</title>
  </head>
  <body>
    <button>Click me</button>
  </body>
</html>


text:
<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>External JavaScript example</title>
    <script src="script.js" defer></script>
  </head>
  <body>
    <button>Click me</button>
  </body>
</html>


text:
function createParagraph() {
  const para = document.createElement('p');
  para.textContent = 'You clicked the button!';
  document.body.appendChild(para);
}

const buttons = document.querySelectorAll('button');

for (const button of buttons) {
  button.addEventListener('click', createParagraph);
}


text:
<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Internal JavaScript example</title>
    <script>
      document.addEventListener('DOMContentLoaded', () => {
        function createParagraph() {
          const para = document.createElement('p');
          para.textContent = 'You clicked the button!';
          document.body.appendChild(para);
        }

        const buttons = document.querySelectorAll('button');

        for (const button of buttons) {
          button.addEventListener('click', createParagraph);
        }
      });
    </script>
  </head>
  <body>
    <button>Click me</button>
  </body>
</html>


text:
/* Some default styling for cookbook examples */
/*
rgb(53,43,34)
rgb(75,70,74)
rgb(95,97,110)
rgb(137,151,188)
rgb(160,178,226)
*/
body {
    background-color: #fff;
    color: #333;
    font: 1em / 1.4 Helvetica Neue, Helvetica, Arial, sans-serif;
    padding: 0;
    margin: 0;
}

h1 {
  font-size: 2rem;
  margin: 0;
}

h2 {
  font-size: 1.6rem;
  margin: 0;
}

p {
  margin: 0.5em 0;
}

/* styles for the editor */

.playable {
    font-family: monospace;
    display: block;
    margin-bottom: 10px;
    background-color: #F4F7F8;
    border: none;
    border-left: 6px solid #558ABB;
    color: #4D4E53;
    width: 90%;
    max-width: 700px;
    padding: 10px 10px 0px;
    font-size: 90%;
  }

  .playable-css {
    height: 80px;
  }

  .playable-js {
    height: 160px;
  }

  .playable-buttons {
    text-align: right;
    width: 90%;
    max-width: 700px;
    padding: 5px 10px 5px 26px;
    font-size: 100%;
  }

  .preview {
    width: 90%;
    max-width: 700px;
    border: 1px solid #4D4E53;
    border-radius: 2px;
    padding: 10px 14px 10px 10px;
    margin-bottom: 10px;
  }

  .preview input {
    display: block;
    margin: 5px;
  }


text:
var section = document.querySelector('section');
var editable = document.querySelector('.editable');
var textareaJS = document.querySelector('.playable-js');
var reset = document.getElementById('reset');
var jsCode = textareaJS.value;

function fillCode() {
    editable.textContent = textareaJS.value;
    try {
      eval(editable.textContent);
    } catch(e) {
      section.innerHTML = ' ';
      let para = document.createElement('p');
      para.textContent = e;
      section.appendChild(para);
    }
}

reset.addEventListener('click', function () {
    textareaJS.value = jsCode;
    fillCode();
});

textareaJS.addEventListener('input', fillCode);
window.addEventListener('load', fillCode);


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Strings: Task 4</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    const theorem = 'Pythagorean theorem';

    const a = 5;
    const b = 8;

    const myString = 'Using *, we can work out that that if the two shortest sides of a right-angled triangle have lengths of * and *, the length of the hypotenuse is *.';

    // Don't edit the code below here!

    const section = document.querySelector('section');

    const para1 = document.createElement('p');
    para1.textContent = myString;
    section.appendChild(para1);
  </script>

</html>


text:
# JavaScript strings marking guide

The aim of the tasks is to demonstrate an understanding of the JavaScript features covered in the [Handling text — strings in JavaScript](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Strings) and [Useful string methods](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods) lessons in Learn Web Development on MDN.

Note: If there is an error in your code, it will be outputted into the results panel on the page, to help you try to figure out the answer (or into the browser's JavaScript console, in the case of the downloadable version).

## Task 1

The first task asks you to store a new string in a variable to go along wth the existing one, which contains the missing half of the famous quote. Call the new variable you add `quoteEnd`.

You'll also need to escape the apostrophe in the existing string so that it doesn't throw an error.

Finally, you'll need to concatenate the two strings together, and store the result in a variable called `finalQuote`.

The answer should look something like this:

```
const quoteStart = 'Don\'t judge each day by the harvest you reap ';
const quoteEnd = 'but by the seeds that you plant.'

const finalQuote = `${quoteStart}${quoteEnd}`;
```

## Task 2

Next up, task 2 requires the student to:

* Check the length of the provided string using `.length`, and store the result in a variable called `quoteLength`.
* Find the index of the substring 'green eggs and ham' using `.indexOf` and store it in `index`.
* Use a combination of the variables you have, `.length`, and `.slice()`, to trim down the original quote to 'I do not like green eggs and ham.', and store it in `revisedQuote`.

```
const quote = 'I do not like green eggs and ham. I do not like them, Sam-I-Am.';
const substring = 'green eggs and ham';

const quoteLength = quote.length;

const index = quote.indexOf(substring);

const revisedQuote = quote.slice(0, index + substring.length + 1);
```

## Task 3

For our next string task, we return to our Green Eggs and Ham revised quote, which someone has messed up. You need to:

* Fix the casing. The best way to do this is to put it all in lower case using `.toLowerCase()`, and then put the first letter in uppercase using `replace()`, `slice()`, and `toUpperCase()`. Store the new quote in `fixedQuote`.
* Replace `green eggs and ham` with whatever food you really don't like using `replace()`.
* Add a full stop to the end of the sentence using some means.

Your code should look something like this:

```
const quote = 'I dO nOT lIke gREen eGgS anD HAM';

let fixedQuote = quote.toLowerCase();
const firstLetter = fixedQuote.slice(0,1);
fixedQuote = fixedQuote.replace(firstLetter, firstLetter.toUpperCase());

fixedQuote = fixedQuote.replace('green eggs and ham', 'pickled onions');

const finalQuote = `${fixedQuote}.`;
```

## Task 4

Our final string task looks at your ability to use template literals. Your answer is expected to take the existing string literal, `myString`, turn it into a template literal, and include four placeholders in place of the asterisks:

* The `theorem` string.
* The value of `a`.
* The value of `b`.
* The length of the hypotenuse, if `a` and `b` are the lengths of the two shortest sides of a right-angled triangle. You can use pythagoras' theorem to work this out.

Your code should look something like this:

```
const theorem = 'Pythagorean theorem';

const a = 5;
const b = 8;

const myString = `Using ${ theorem }, we can work out that that if the two shortest sides of a right-angled triangle have lengths of ${ a } and ${ b }, the length of the hypotenuse is ${ Math.sqrt((a**2) + (b**2)) }.`;
```

You could use a different form of the fourth placeholder, such as `Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2))` or `${ Math.sqrt((a * a) + (b * b)) }`.


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Strings: Task 2</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">
const quote = 'I do not like green eggs and ham. I do not like them, Sam-I-Am.';
const substring = 'green eggs and ham';

// Add your code here

// Don't edit the code below here!

section.innerHTML = ' ';
const para1 = document.createElement('p');
para1.textContent = `The quote is ${ quoteLength } characters long.`;
const para2 = document.createElement('p');
para2.textContent = revisedQuote;

section.appendChild(para1);
section.appendChild(para2);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Strings: Task 1</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    // Add your code here

    const quoteStart = 'Don't judge each day by the harvest you reap ';

    // Don't edit the code below here!

    const section = document.querySelector('section');
    const para1 = document.createElement('p');
    para1.textContent = finalQuote;

    section.appendChild(para1);
  </script>

</html>


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Strings: Task 2</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    const quote = 'I do not like green eggs and ham. I do not like them, Sam-I-Am.';
    const substring = 'green eggs and ham';

    // Add your code here

    // Don't edit the code below here!

    const section = document.querySelector('section');

    section.innerHTML = ' ';
    const para1 = document.createElement('p');
    para1.textContent = `The quote is ${ quoteLength } characters long.`;
    const para2 = document.createElement('p');
    para2.textContent = revisedQuote;

    section.appendChild(para1);
    section.appendChild(para2);
  </script>

</html>


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Strings: Task 3</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    const quote = 'I dO nOT lIke gREen eGgS anD HAM';

    // Add your code here

    // Don't edit the code below here!

    const section = document.querySelector('section');

    const para1 = document.createElement('p');
    para1.textContent = fixedQuote;
    const para2 = document.createElement('p');
    para2.textContent = finalQuote;

    section.appendChild(para1);
    section.appendChild(para2);
  </script>

</html>


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Strings: Task 4</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">
const theorem = 'Pythagorean theorem';

const a = 5;
const b = 8;

const myString = 'Using *, we can work out that that if the two shortest sides of a right-angled triangle have lengths of * and *, the length of the hypotenuse is *.';

// Don't edit the code below here!

section.innerHTML = ' ';
const para1 = document.createElement('p');
para1.textContent = myString;

section.appendChild(para1);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Strings: Task 3</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">
const quote = 'I dO nOT lIke gREen eGgS anD HAM';

// Add your code here

// Don't edit the code below here!

section.innerHTML = ' ';
const para1 = document.createElement('p');
para1.textContent = fixedQuote;
const para2 = document.createElement('p');
para2.textContent = finalQuote;

section.appendChild(para1);
section.appendChild(para2);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Strings: Task 1</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">

// Add your code here

const quoteStart = 'Don't judge each day by the harvest you reap ';

// Don't edit the code below here!

section.innerHTML = ' ';
const para1 = document.createElement('p');
para1.textContent = finalQuote;

section.appendChild(para1);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Arrays: Task 2</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    // Add your code here

    let myString = 'Ryu+Ken+Chun-Li+Cammy+Guile+Sakura+Sagat+Juri';

    // Don't edit the code below here!

    const section = document.querySelector('section');

    let para1 = document.createElement('p');
    para1.textContent = `Array: ${ myArray }`;

    let para2 = document.createElement('p');
    para2.textContent = `The length of the array is ${ arrayLength }.`;

    let para3 = document.createElement('p');
    para3.textContent = `The last item in the array is "${ lastItem }".`;

    section.appendChild(para1);
    section.appendChild(para2);
    section.appendChild(para3);
  </script>

</html>


text:
# JavaScript arrays marking guide

The aim of the tasks is to demonstrate an understanding of the JavaScript features covered in the [Arrays](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Arrays) lesson in Learn Web Development on MDN.

Note: If there is an error in your code, it will be outputted into the results panel on the page, to help you try to figure out the answer (or into the browser's JavaScript console, in the case of the downloadable version).

## Task 1

We'll start off simple; the first thing you need to do here is create an array of three items. Choose whatever items you like — your favourite bands or foods, perhaps? Store in a variable called `myArray`.

Next, modify the first two items in the array to some different items, using simple bracket notation, e.g. `myArray[0] = 'pizza'`.

Last of all, add an item to the start of the array using `.unshift()`.

The answer should look something like this:

```js
let myArray = ['cats', 'dogs', 'chickens'];

myArray[0] = 'horses';
myArray[1] = 'pigs';

myArray.unshift('crocodiles');
```

## Task 2

Moving on, the next task provides a string for you to work on.

Here you are expected to start by splitting the string into an array using `.split('+')`. Store the array in `myArray`.

Next, store the length of the array (`myArray.length`) in a variable called `arrayLength`.

Last up, retrieve the last item in the array with `myArray[myArray.length - 1]`; store it in `lastItem`.

The example should look something like this:

```js
let myString = 'Ryu+Ken+Chun-Li+Cammy+Guile+Sakura+Sagat+Juri';

let myArray = myString.split('+');

let arrayLength = myArray.length;

let lastItem = myArray[arrayLength - 1];
```

## Task 3

You should start by popping the last item off the array using `myArray.pop()`.

Next, add two new names to the end of the array using `myArray.push()`

For an added challenge, you'll need to use `.forEach()` or some kind of loop (we didn't cover these in the array article, so look them up) to go over each item in the array and add its index number after the name inside parentheses. Note that when using `forEach` you are performing operations on a copy of the array elements, not the array elements themselves, so you can't change them directly — you have to create the new array item and copy it back over.

Finally you need to stitch the array items together into a string using `myArray.join(' - ')`, and store the result in `myString`.

```js
let myArray = [ "Ryu", "Ken", "Chun-Li", "Cammy", "Guile", "Sakura", "Sagat", "Juri" ];

myArray.pop();

myArray.push('Zangief');
myArray.push('Ibuki');

myArray.forEach(function(element, index) {
  let newElement = `${ element } (${index})`;
  myArray[index] = newElement;
});

let myString = myArray.join(' - ');
```

## Task 4

You should start by finding the index of ``"Eagles"``, using `birds.indexOf()`.

Next, use the index with `birds.splice()` to remove the ``"Eagles"`` item.

Finally, you can use `birds.filter()` to get an array containing only birds starting with "E".

The function passed to `filter()` can use `bird.startsWith()` to test whether the bird starts with "E".

```js
const eaglesIndex = birds.indexOf("Eagles");
birds.splice(eaglesIndex, 1);

function startsWithE(bird) {
  return bird.startsWith("E");
}
const eBirds = birds.filter(startsWithE);
```


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Arrays: Task 1</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    // Add your code here

    // Don't edit the code below here!

    const section = document.querySelector('section');

    let para1 = document.createElement('p');
    para1.textContent = `Array: ${ myArray }`;

    section.appendChild(para1);
  </script>

</html>


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Arrays: Task 4</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">
const birds = [ "Parrots", "Falcons", "Eagles", "Emus", "Caracaras", "Egrets" ];

// Add your code here

// Don't edit the code below here!

section.innerHTML = ' ';

const para1 = document.createElement('p');
para1.textContent = eBirds;

section.appendChild(para1);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Arrays: Task 3</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">
let myArray = [ "Ryu", "Ken", "Chun-Li", "Cammy", "Guile", "Sakura", "Sagat", "Juri" ];

// Add your code here

// Don't edit the code below here!

section.innerHTML = ' ';

let para1 = document.createElement('p');
para1.textContent = myString;

section.appendChild(para1);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Arrays: Task 4</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    const birds = [ "Parrots", "Falcons", "Eagles", "Emus", "Caracaras", "Egrets" ];

    // Add your code here

    // Don't edit the code below here!

    const section = document.querySelector('section');

    const para1 = document.createElement('p');
    para1.textContent = eBirds;

    section.appendChild(para1);
  </script>

</html>


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Arrays: Task 3</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    let myArray = [ "Ryu", "Ken", "Chun-Li", "Cammy", "Guile", "Sakura", "Sagat", "Juri" ];

    // Add your code here

    // Don't edit the code below here!

    const section = document.querySelector('section');

    let para1 = document.createElement('p');
    para1.textContent = myString;

    section.appendChild(para1);
  </script>

</html>


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Arrays: Task 1</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">

// Add your code here

// Don't edit the code below here!

section.innerHTML = ' ';
let para1 = document.createElement('p');
para1.textContent = `Array: ${ myArray }`;

section.appendChild(para1);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Arrays: Task 2</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">

// Add your code here

let myString = 'Ryu+Ken+Chun-Li+Cammy+Guile+Sakura+Sagat+Juri';

// Don't edit the code below here!

section.innerHTML = ' ';
let para1 = document.createElement('p');
para1.textContent = `Array: ${ myArray }`;

let para2 = document.createElement('p');
para2.textContent = `The length of the array is ${ arrayLength }.`;

let para3 = document.createElement('p');
para3.textContent = `The last item in the array is "${ lastItem }".`;

section.appendChild(para1);
section.appendChild(para2);
section.appendChild(para3);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Math: Task 3</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    // Statement 1: The elephant weighs less than the mouse
    const eleWeight = 1000;
    const mouseWeight = 2;

    // Statement 2: The Ostrich is taller than the duck
    const ostrichHeight = 2;
    const duckHeight = 0.3;

    // Statement 3: The two passwords match
    const pwd1 = 'stromboli';
    const pwd2 = 'stROmBoLi';

    // Add your code here

    // Don't edit the code below here!

    const section = document.querySelector('section');

    const para1 = document.createElement('p');
    const para2 = document.createElement('p');
    const para3 = document.createElement('p');

    const weightTest = weightComparison ? 'True — elephants do weigh less than mice!?' : 'False — of course an elephant is heavier than a mouse!';
    const heightTest = heightComparison ? 'True — an ostrich is indeed taller than a duck!' : 'False — apparently a duck is taller than an ostrich!?';
    const pwdTest = pwdMatch ? 'True — the passwords match.' : 'False — the passwords do not match; please check them';

    para1.textContent = weightTest;
    section.appendChild(para1);
    para2.textContent = heightTest;
    section.appendChild(para2);
    para3.textContent = pwdTest;
    section.appendChild(para3);
  </script>

</html>


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Math: Task 1</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">

let finalResult;

let evenOddResult;

// Add your code here

// Don't edit the code below here!

section.innerHTML = ' ';
const para1 = document.createElement('p');
const finalResultCheck = finalResult === 48 ? `Yes, well done!` : `No, it is ${ finalResult }`;
para1.textContent = `Is the finalResult 48? ${ finalResultCheck }`;
const para2 = document.createElement('p');
const evenOddResultCheck = evenOddResult === 0 ? 'The final result is even!' : 'The final result is odd. Hrm.';
para2.textContent = evenOddResultCheck;

section.appendChild(para1);
section.appendChild(para2);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
# JavaScript math marking guide

The aim of the tasks is to demonstrate an understanding of the JavaScript features covered in the [Basic math in JavaScript — numbers and operators](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Math) lesson in Learn Web Development on MDN.

Note: If there is an error in your code, it will be outputted into the results panel on the page, to help you try to figure out the answer (or into the browser's JavaScript console, in the case of the downloadable version).

## Task 1

In this task you need to create four variables that contain numbers. The first two need to be added together and stored, while the fourth needs to be subtracted from the third and the result stored. The two results of these operations need to be multiplied together to create another result, 48, which should be stored in the variable `finalResult`.

Finally, you need to write a calculation that checks whether this number is even or odd, with the result stored in `evenOddCheck`. The operator you need here is modulo (`%`). If your value modulo 2 equals 0, you know it is even.

The answer should look something like this:

```
const number1 = 4;
const number2 = 8;
const number3 = 12;
const number4 = 8;

const additionResult = number1 + number2;
const subtractionResult = number3 - number4;

finalResult = additionResult * subtractionResult;

evenOddResult = finalResult % 2;
```

This task also tests your variable naming abilities. An extra mark if the variables have sensible names that follow best practices (lower camel case, descriptive, not too long).

## Task 2

In our second task for this article we need to consider operator precedence and use parentheses to make the first two calculations give the result we were expecting.

Next, we ideally need to use the multiplication assignment operator to multiply the two results together and then assign the product of this back to `result`.

After that we need to use the `toFixed()` method available on numbers to round `result` to 2 decimal places, storing the product of this in a `finalResult` variable.

Finally, using `typeof` we can test if a variable contains a string. We need to use `Number()` to convert `finalResult` to a number type. This final number needs to be stored in a variable called `finalNumber`.

The result should look something like this:

```
let result = (7 + 13) / (9 + 7);
let result2 = 100 / (2 * 6);

result *= result2;

const finalResult = result.toFixed(2);

const finalNumber = Number(finalResult);
```

## Task 3

This last task tests the student's ability to use comparison operators. Here we need to write some tests to show that mathematically prove or disprove the statements in the question.

The test results should be stored inside variables called `weightComparison`, `heightComparison`, and `pwdMatch`, respectively.

Your code should look something like this:

```
const weightComparison = eleWeight < mouseWeight;

const heightComparison = ostrichHeight > duckHeight;

const pwdMatch = pwd1 === pwd2;
```


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Math: Task 2</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    // Final result should be 4633.33
    // Add/update your code here

    let result = 7 + 13 / 9 + 7;
    let result2 = 100 / 2 * 6;

    // Don't edit the code below here!

    const section = document.querySelector('section');

    const para1 = document.createElement('p');
    para1.textContent = `Your finalResult is ${ finalResult }`;
    const para2 = document.createElement('p');
    const finalNumberCheck = isNaN(finalNumber) === false ? 'finalNumber is a number type. Well done!' : `Ooops! finalNumber is not a number.`;
    para2.textContent = finalNumberCheck;

    section.appendChild(para1);
    section.appendChild(para2);
  </script>

</html>


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Math: Task 1</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    let finalResult;

    let evenOddResult;

    // Add your code here

    // Don't edit the code below here!

    const section = document.querySelector('section');

    const para1 = document.createElement('p');
    const finalResultCheck = finalResult === 48 ? `Yes, well done!` : `No, it is ${ finalResult }`;
    para1.textContent = `Is the finalResult 48? ${ finalResultCheck }`;
    const para2 = document.createElement('p');
    const evenOddResultCheck = evenOddResult === 0 ? 'The final result is even!' : 'The final result is odd. Hrm.';
    para2.textContent = evenOddResultCheck;

    section.appendChild(para1);
    section.appendChild(para2);
  </script>

</html>


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Math: Task 3</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 400px;">

// Statement 1: The elephant weighs less than the mouse
const eleWeight = 1000;
const mouseWeight = 2;

// Statement 2: The Ostrich is taller than the duck
const ostrichHeight = 2;
const duckHeight = 0.3;

// Statement 3: The two passwords match
const pwd1 = 'stromboli';
const pwd2 = 'stROmBoLi';

// Add your code here

// Don't edit the code below here!

section.innerHTML = ' ';
const para1 = document.createElement('p');
const para2 = document.createElement('p');
const para3 = document.createElement('p');

const weightTest = weightComparison ? 'True — elephants weigh less than mice!?' : 'False — of course an elephant is heavier than a mouse!';
const heightTest = heightComparison ? 'True — an ostrich is indeed taller than a duck!' : 'False — apparently a duck is taller than an ostrich!?';
const pwdTest = pwdMatch ? 'True — the passwords match.' : 'False — the passwords do not match; please check them';

para1.textContent = weightTest;
section.appendChild(para1);
para2.textContent = heightTest;
section.appendChild(para2);
para3.textContent = pwdTest;
section.appendChild(para3);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Math: Task 2</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">

// Final result should be 4633.33
// Add/update your code here

let result = 7 + 13 / 9 + 7;
let result2 = 100 / 2 * 6;

// Don't edit the code below here!

section.innerHTML = ' ';
const para1 = document.createElement('p');
para1.textContent = `Your finalResult is ${ finalResult }`;
const para2 = document.createElement('p');
const finalNumberCheck = isNaN(finalNumber) === false ? 'finalNumber is a number type. Well done!' : `Ooops! finalNumber is not a number.`;
para2.textContent = finalNumberCheck;

section.appendChild(para1);
section.appendChild(para2);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Variables: Task 1</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    // Add your code here

    // Don't edit the code below here!

    const section = document.querySelector('section');

    const para1 = document.createElement('p');
    para1.textContent = myName;
    const para2 = document.createElement('p');
    para2.textContent = myAge;
    section.appendChild(para1);
    section.appendChild(para2);
  </script>

</html>


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Variables: Task 2</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    // Add your code here

    let myName = 'Paul';

    // Don't edit the code below here!

    const section = document.querySelector('section');

    const para = document.createElement('p');
    para.textContent = myName;
    section.appendChild(para);
  </script>

</html>


text:
# JavaScript variables marking guide

The aim of the tasks is to demonstrate an understanding of the JavaScript features covered in the [Storing the information you need — Variables](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Variables) lesson in Learn Web Development on MDN.

Note: If there is an error in your code, it will be outputted into the results panel on the page, to help you try to figure out the answer (or into the browser's JavaScript console, in the case of the downloadable version).

## Task 1

This task covers basic understanding of declaring a variable with a value, and initializing it — both separately and at the same time. Ideally your code should look something like this:

```
let myName;
myName = 'Chris';
let myAge = 42;
```

`let` is ideal for both declarations. `const` is not really appropriate, as such values might change, and it won't work in the first instance.  `var` is not OK.

The `myAge` value will work whether you've initialised it with a numeric (no quotes) or string (quotes) value, however it is a numeric value, so using quotes for it isn't correct.

## Task 2

In task 2 the student needs to add a new line to correct the `myName` variable value so that it outputs their name on the screen.

The finished code should look something like this:

```
let myName = 'Paul';
myName = 'Chris';
```

## Task 3

The last task in this article focuses around fixing some variable-related errors. Basically:

1. The `myName` variable is not being outputted correctly because it is being declared once using `const`, and then an attempt is being made to change the value.
2. The result of the sum is not being outputted correctly because the `myAge` variable is being declared as a number. It needs to have the quotes removed.

The solution should look something like this:

```
let myName = 'Default';
myName = 'Chris'

let myAge = 42;
```


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Variables: Task 3</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    // Add your code here

    const myName = 'Default';
    myName = 'Chris';

    let myAge = '42';

    // Don't edit the code below here!

    const section = document.querySelector('section');

    const para1 = document.createElement('p');
    const para2 = document.createElement('p');
    para1.textContent = myName;
    para2.textContent = `In 20 years, I will be ${myAge + 20}`;
    section.appendChild(para1);
    section.appendChild(para2);
  </script>

</html>


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Variables: Task 2</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">

// Add your code here

let myName = 'Paul';

// Don't edit the code below here!

section.innerHTML = ' ';
const para = document.createElement('p');
para.textContent = myName;
section.appendChild(para);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Variables: Task 3</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">

// Add your code here

const myName = 'Default';
myName = 'Chris';

let myAge = '42';

// Don't edit the code below here!

section.innerHTML = ' ';
const para1 = document.createElement('p');
const para2 = document.createElement('p');
para1.textContent = myName;
para2.textContent = `In 20 years, I will be ${myAge + 20}`;
section.appendChild(para1);
section.appendChild(para2);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Variables: Task 1</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">

// Add your code here

// Don't edit the code below here!

section.innerHTML = ' ';
const para1 = document.createElement('p');
para1.textContent = myName;
const para2 = document.createElement('p');
para2.textContent = myAge;
section.appendChild(para1);
section.appendChild(para2);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />

    <title>Silly story generator</title>

      Enter custom name:
      <input id="customname" type="text" placeholder="" />

      US<input id="us" type="radio" name="ukus" value="us" checked />
      UK<input id="uk" type="radio" name="ukus" value="uk" />

      <button class="randomize">Generate random story</button>


text:
1. COMPLETE VARIABLE AND FUNCTION DEFINITIONS

const customName = document.getElementById('customname');
const randomize = document.querySelector('.randomize');
const story = document.querySelector('.story');

function randomValueFromArray(array){
  const random = Math.floor(Math.random()*array.length);
  return array[random];
}

2. RAW TEXT STRINGS

It was 94 fahrenheit outside, so :insertx: went for a walk. When they got to :inserty:, they stared in horror for a few moments, then :insertz:. Bob saw the whole thing, but was not surprised — :insertx: weighs 300 pounds, and it was a hot day.

Willy the Goblin
Big Daddy
Father Christmas

the soup kitchen
Disneyland
the White House

spontaneously combusted
melted into a puddle on the sidewalk
turned into a slug and crawled away

3. EVENT LISTENER AND PARTIAL FUNCTION DEFINITION

randomize.addEventListener('click', result);

function result() {

  if(customName.value !== '') {
    const name = customName.value;

  }

  if(document.getElementById("uk").checked) {
    const weight = Math.round(300);
    const temperature =  Math.round(94);

  }

  story.textContent = ;
  story.style.visibility = 'visible';
}


text:
const customName = document.getElementById('customname');
const randomize = document.querySelector('.randomize');
const story = document.querySelector('.story');

function randomValueFromArray(array){
  const random = Math.floor(Math.random()*array.length);
  return array[random];
}

const storyText = 'It was 94 fahrenheit outside, so :insertx: went for a walk. When they got to :inserty:, they stared in horror for a few moments, then :insertz:. Bob saw the whole thing, but was not surprised — :insertx: weighs 300 pounds, and it was a hot day.';
const insertX = ['Willy the Goblin', 'Big Daddy', 'Father Christmas'];
const insertY = ['the soup kitchen', 'Disneyland', 'the White House'];
const insertZ = ['spontaneously combusted', 'melted into a puddle on the sidewalk', 'turned into a slug and crawled away'];

randomize.addEventListener('click', result);

function result() {
  let newStory = storyText;

  const xItem = randomValueFromArray(insertX);
  const yItem = randomValueFromArray(insertY);
  const zItem = randomValueFromArray(insertZ);

  newStory = newStory.replaceAll(':insertx:',xItem);
  newStory = newStory.replaceAll(':inserty:',yItem);
  newStory = newStory.replaceAll(':insertz:',zItem);

  if (customName.value !== '') {
    const name = customName.value;
    newStory = newStory.replaceAll('Bob', name);
  }

  if (document.getElementById("uk").checked) {
    const weight = `${Math.round(300*0.0714286)} stone`;
    const temperature =  `${Math.round((94-32) * 5 / 9)} centigrade`;
    newStory = newStory.replaceAll('94 fahrenheit', temperature);
    newStory = newStory.replaceAll('300 pounds', weight);
  }

  story.textContent = newStory;
  story.style.visibility = 'visible';
}


text:
# Marking guide for "Silly story generator"
The following guide outlines a marking guide for the MDN Learning Area JavaScript Topic — [Silly story generator](https://developer.mozilla.org/en-US/Learn/JavaScript/First_steps/Silly_story_generator). Each subtask detailed in the assessment is listed below, along with an explanation of how many marks the task is worth, and the mark breakdown.

Note: These are guidelines, not set in stone rules — you are of course free to use your judgement on mark awarding when you meet an edge case, or something that isn't clear cut.

The overall mark awarded is out of 39. Work out their final mark, and then divide by 39 and multiply by 100 to give a percentage mark. For reference, you can find a [finished program](main.js) that would be awarded top marks.

## Basic setup

Create main.js

One mark for this; it is pretty simple.

Apply the external JS file to your HTML

One mark for this too.

## Initial variables and functions

Copy the code from section 1 of the raw text file into main.js.

One mark for this.

Store the big long text string inside a variable called storyText.

One mark for this — creating a simple variable and storing a string inside it is not complex.

Store the three sets of strings inside three arrays called insertX, insertY, and insertZ.

6 marks for this — 2 for each array. Creating an array of strings is not quite as simple as a string variable.

## Placing the event handler and incomplete function
Only one mark for this bit — it's just more simple copy and paste.

## Completing the result() function

Create a new variable called newStory, and set it's value to equal storyText.

One mark for this — another simple variable definition.

Create three new variables called xItem, yItem, and zItem...

6 marks for this, 2 for each correct definition. For each one they basically have to initialise the new variable, and declare it's value as the corresponding array passed to the randomValueFromArray() function. So for example, const xItem = randomValueFromArray(insertX);.

Next we want to replace the three placeholders in the newStory string...

8 marks, two for each of the four substitutions needed. For each of these lines, we need to call the replaceAll() string method on newStory, giving it as parameters the placeholder first of all (e.g. 'insertx:'), and then the variable value to replace the placeholder with (e.g. xItem). We need to store the result of that method call in newStory, so the result of each line is that newStory will be made equal to itself, but with some substitutions made. An example correct line is newStory = newStory.replaceAll(':insertx:',xItem);. This line will substitute both instances of ':insertx:'. If you use replace() instead of replaceAll() then this line needs to be called twice, as using replace() like this only replaces the first instance of the matched substring.

Inside the second if block, we are checking to see if the uk radio button has been selected...

There are four parts to this question. Let's go through each one in turn:

Four marks for this, 2 for each formula. The two required formulae are pounds x 0.0714286 = stone and (Fahrenheit - 32) * (5 / 9) = centigrade.

Two marks for this. They need to replace 300 with 300*0.0714286, and then concatenate ' stone' onto the end of the whole line, so in total, the value of weight is Math.round(300*0.0714286) + ' stone'.

Two marks for this. They need to replace 94 with (94-32) * 5 / 9, and then concatenate ' centigrade' onto the end of the whole line, so in total, the value of temperature is Math.round((94-32) * 5 / 9) + ' centigrade'.

Four marks in total for these; they are just the same as the other replaceAll() lines that came before them. For these two lines we need newStory = newStory.replaceAll('94 fahrenheit',temperature); and
    newStory = newStory.replaceAll('300 pounds',weight);

Finally, in the second-to-last line of the function, make the textContent property of the story variable...

One mark for this, as it's pretty easy; just add the newStory variable into the line — story.textContent = newStory;.


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Editable canvas example</title>

Live output

    <canvas id="canvas" width="400" height="250" class="playable-canvas">
    </canvas>

The rectangle is 50px wide and 50px high.

Editable code

Press Esc to move focus away from the code area (Tab inserts a tab character).

    <textarea id="code" class="playable-code" style="height: 150px;width: 95%">
let x = 50; let y = 50;

// Edit the two lines below here ONLY
x = 50;
y = 50;

ctx.fillStyle = 'green';
ctx.fillRect(10, 10, x, y);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>First conditional example</title>

    <button>Start machine</button>

The machine is stopped.


text:
<!DOCTYPE html>

    <meta charset="utf-8">

    <title>Number guessing game</title>

Number guessing game

We have selected a random number between 1 and 100. See if you can guess it in 10 turns or less. We'll tell you if your guess was too high or too low.

  Enter a guess:
  <input type="text" id="guessField" class="guessField">
  <input type="submit" value="Submit guess" class="guessSubmit">


text:
# Marking guide for "Sequencing animations"

The following guide outlines a marking guide for the MDN Learning Area JavaScript Topic — [Sequencing animations](https://developer.mozilla.org/en-US/Learn/JavaScript/Asynchronous/Sequencing_animations). Each subtask detailed in the assessment is listed below, along with an explanation of how many marks the task is worth, and the mark breakdown.

Note: These are guidelines, not set in stone rules — you are of course free to use your judgement on mark awarding when you meet an edge case, or something that isn't clear cut.

The overall mark awarded is out of 9.

The assessment asks for the animation sequence to be implemented in three different forms:

1. "Promise hell": something that works, but has the promise version of the "callback hell" problem.

2. "Promise chain": implemented as a promise chain. There are a few different ways to write this, because of the different forms an arrow function can take. We ask which is the most concise form.

3. "async/await": implemented using async and await.

## Promise hell

Three marks for this. The code should look something like:

```js
alice1.animate(aliceTumbling, aliceTiming).finished
  .then(() => {
    const alice2Animation = alice2.animate(aliceTumbling, aliceTiming).finished;
    alice2Animation.then(() => {
      alice3.animate(aliceTumbling, aliceTiming);
    });
  });
```

The main thing here is that we nest calls to `then()`, making the code much harder to read.

## Promise chain

Three marks for this. The code should look something like:

```js
alice1.animate(aliceTumbling, aliceTiming).finished
  .then(() => alice2.animate(aliceTumbling, aliceTiming).finished)
  .then(() => alice3.animate(aliceTumbling, aliceTiming).finished)
  .catch(error => console.error(`Error animating Alices: ${error}`));
```

This is the most concise version. It would be fine to have some different ways of writing the arrow functions, such as:

```js
alice1.animate(aliceTumbling, aliceTiming).finished
  .then(() => { return alice2.animate(aliceTumbling, aliceTiming).finished; })
  .then(() => { return alice3.animate(aliceTumbling, aliceTiming).finished; })
  .catch(error => console.error(`Error animating Alices: ${error}`));
```

## async/await

Three marks for this. The code should look something like:

```js
async function animateAlices() {
  try {
    await alice1.animate(aliceTumbling, aliceTiming).finished;
    await alice2.animate(aliceTumbling, aliceTiming).finished;
    await alice3.animate(aliceTumbling, aliceTiming).finished;
  }
  catch (error) {
    console.error(`Error animating Alices: ${error}`);
  }
}

animateAlices();
```


text:
<!DOCTYPE html>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <title>Sequencing animations</title>

    <link href="style.css"rel="stylesheet">


text:
body {
  background: #6c373f;
  display: flex;
  justify-content: center;
  }

#alice-container {
  width: 90vh;
  display: grid;
  place-items: center;
  grid-template-areas:
    "a1 . ."
    ". a2 ."
    ". . a3";
}

#alice1 {
  grid-area: a1;
}

#alice2 {
  grid-area: a2;
}

#alice3 {
  grid-area: a3;
}


text:
const aliceTumbling = [
  { transform: 'rotate(0) scale(1)' },
  { transform: 'rotate(360deg) scale(0)' }
];

const aliceTiming = {
  duration: 2000,
  iterations: 1,
  fill: 'forwards'
}

const alice1 = document.querySelector("#alice1");
const alice2 = document.querySelector("#alice2");
const alice3 = document.querySelector("#alice3");


text:
<!DOCTYPE html>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <title>Sequencing Animations</title>

    <link href="style.css"rel="stylesheet">


text:
const aliceTumbling = [
  { transform: 'rotate(0) scale(1)' },
  { transform: 'rotate(360deg) scale(0)' }
];

const aliceTiming = {
  duration: 2000,
  iterations: 1,
  fill: 'forwards'
}

const alice1 = document.querySelector("#alice1");
const alice2 = document.querySelector("#alice2");
const alice3 = document.querySelector("#alice3");

alice1.animate(aliceTumbling, aliceTiming).finished
  .then(() => alice2.animate(aliceTumbling, aliceTiming).finished)
  .then(() => alice3.animate(aliceTumbling, aliceTiming).finished)
  .catch(error => console.error(`Error animating Alices: ${error}`));


text:
<!DOCTYPE html>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <title>Number of primes</title>

    <link href="style.css"rel="stylesheet">

    Number of primes:
    <input type="text" id="quota" name="quota" value="1000000">

    <button id="generate">Generate primes</button>
    <button id="reload">Reload</button>

    <textarea id="user-input" rows="5" cols="62">Try typing in here immediately after pressing "Generate primes"</textarea>


text:
textarea {
  display: block;
  margin: 1rem 0;
}


text:
addEventListener("message", message => {
  if (message.data.command === 'generate') {
    generatePrimes(message.data.quota);
  }
});

function generatePrimes(quota) {

  function isPrime(n) {
    for (let c = 2; c <= Math.sqrt(n); ++c) {
      if (n % c === 0) {
          return false;
       }
    }
    return true;
  }

  const primes = [];
  const maximum = 1000000;

  while (primes.length < quota) {
    const candidate = Math.floor(Math.random() * (maximum + 1));
    if (isPrime(candidate)) {
      primes.push(candidate);
    }
  }

  postMessage(primes.length);
}


text:
<!DOCTYPE html>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <title>Prime numbers</title>

    <link href="style.css"rel="stylesheet">

    Number of primes:
    <input type="text" id="quota" name="quota" value="1000000">

    <button id="generate-primes">Generate primes</button>
    <button id="reload">Reload</button>

    <textarea id="user-input" rows="5" cols="62">Try typing in here immediately after pressing "Generate primes"</textarea>


text:
// Create a new worker, giving it the code in "generate.js"
const worker = new Worker('./generate.js');

// When the user clicks "Generate primes", send a message to the worker.
// The message command is "generate", and the message also contains "quota",
// which is the number of primes to generate.
document.querySelector('#generate-primes').addEventListener('click', () => {
  const quota = document.querySelector('#quota').value;
  worker.postMessage({
    command: 'generate',
    quota: quota
  });
});

// When the worker sends a message back to the main thread,
// update the output box with a message for the user, including the number of
// primes that were generated, taken from the message data.
worker.addEventListener('message', message => {
  document.querySelector('#output').textContent = `Finished generating ${message.data} primes!`;
});

document.querySelector('#reload').addEventListener('click', () => {
  document.querySelector('#user-input').value = 'Try typing in here immediately after pressing "Generate primes"';
  document.location.reload();
});


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Object-oriented JavaScript inheritance</title>

      Enter code:
      <input type="text" id="jscode">
      <button>Submit code</button>


text:
<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Object-oriented JavaScript inheritance</title>
  </head>

  <body>

  </body>

    <script>

    // Basic Person class

    class Person {
      constructor(first, last, age, gender, interests) {
        this.name = {
          first,
          last
        };
        this.age = age;
        this.gender = gender;
        this.interests = interests;
      }

      greeting() {
        console.log(`Hi! I'm ${this.name.first}`);
      };

      farewell() {
        console.log(`${this.name.first} has left the building. Bye for now!`);
      };
    }

    // Extend Person with Teacher

    class Teacher extends Person {
      constructor(first, last, age, gender, interests, subject, grade) {
        super(first, last, age, gender, interests);
        // subject and grade are specific to Teacher
        this._subject = subject;
        this.grade = grade;
      }

      get subject() {
        return this._subject;
      }

      set subject(newSubject) {
        this._subject = newSubject;
      }
    }

    // Instantiate Teacher

    let snape = new Teacher('Severus', 'Snape', 58, 'male', ['Potions'], 'Dark arts', 5);
    // Check the default value
    console.log(snape.subject) // Returns "Dark arts"

    // Change the value
    snape.subject = "Balloon animals" // Sets subject to "Balloon animals"

    // Check it again and see if it matches the new value
    console.log(snape.subject) // Returns "Balloon animals"

    </script>
</html>


text:
<!DOCTYPE html>
<html lang="en-us">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Object-oriented JavaScript inheritance</title>
  </head>

  <body>

  </body>

    <script>

    // Basic Person class

    class Person {
      constructor(first, last, age, gender, interests) {
        this.name = {
          first,
          last
        };
        this.age = age;
        this.gender = gender;
        this.interests = interests;
      }

      greeting() {
        console.log(`Hi! I'm ${this.name.first}`);
      };

      farewell() {
        console.log(`${this.name.first} has left the building. Bye for now!`);
      };
    }

    // Instantiate Person

    let han = new Person('Han', 'Solo', 25, 'male', ['Smuggling']);
    han.greeting();
    // Hi! I'm Han

    let leia = new Person('Leia', 'Organa', 19, 'female' ['Government']);
    leia.farewell();
    // Leia has left the building. Bye for now

    // Extend Person with Teacher

    class Teacher extends Person {
      constructor(first, last, age, gender, interests, subject, grade) {
        super(first, last, age, gender, interests);

        // subject and grade are specific to Teacher
        this.subject = subject;
        this.grade = grade;
      }
    }

    // Instantiate Teacher

    let snape = new Teacher('Severus', 'Snape', 58, 'male', ['Potions'], 'Dark arts', 5);
    snape.greeting(); // Hi! I'm Severus.
    snape.farewell(); // Severus has left the building. Bye for now.
    console.log(snape.age) // 58
    console.log(snape.subject) // Dark arts

    </script>
</html>


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Object-oriented JavaScript prototype addition</title>

      Enter code:
      <input type="text" id="jscode">
      <button>Submit code</button>


text:
/* Some default styling for cookbook examples */
/*
rgb(53,43,34)
rgb(75,70,74)
rgb(95,97,110)
rgb(137,151,188)
rgb(160,178,226)
*/
body {
    background-color: #fff;
    color: #333;
    font: 1em / 1.4 Helvetica Neue, Helvetica, Arial, sans-serif;
    padding: 0;
    margin: 0;
}

h1 {
  font-size: 2rem;
  margin: 0;
}

h2 {
  font-size: 1.6rem;
  margin: 0;
}

p {
  margin: 0.5em 0;
}

/* styles for the editor */

.playable {
    font-family: monospace;
    display: block;
    margin-bottom: 10px;
    background-color: #F4F7F8;
    border: none;
    border-left: 6px solid #558ABB;
    color: #4D4E53;
    width: 90%;
    max-width: 700px;
    padding: 10px 10px 0px;
    font-size: 90%;
  }

  .playable-css {
    height: 80px;
  }

  .playable-js {
    height: 160px;
  }

  .playable-buttons {
    text-align: right;
    width: 90%;
    max-width: 700px;
    padding: 5px 10px 5px 26px;
    font-size: 100%;
  }

  .preview {
    width: 90%;
    max-width: 700px;
    border: 1px solid #4D4E53;
    border-radius: 2px;
    padding: 10px 14px 10px 10px;
    margin-bottom: 10px;
  }

  .preview input {
    display: block;
    margin: 5px;
  }


text:
var section = document.querySelector('section');
var editable = document.querySelector('.editable');
var textareaJS = document.querySelector('.playable-js');
var reset = document.getElementById('reset');
var jsCode = textareaJS.value;

function fillCode() {
    editable.textContent = textareaJS.value;
    section.innerHTML = ' ';
    try {
      eval(editable.textContent);
    } catch(e) {
      let para = document.createElement('p');
      para.textContent = e;
      section.appendChild(para);
    }
}

reset.addEventListener('click', function () {
    textareaJS.value = jsCode;
    fillCode();
});

textareaJS.addEventListener('input', fillCode);
window.addEventListener('load', fillCode);


text:
# JavaScript object basics marking guide

The aim of the tasks is to demonstrate an understanding of the JavaScript features covered in the [JavaScript object basics](https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics) lesson in Learn Web Development on MDN.

Note: If there is an error in your code, it will be outputted into the results panel on the page, to help you try to figure out the answer (or into the browser's JavaScript console, in the case of the downloadable version).

## Task 1

In this task you are provided with an object literal, and your tasks are to

* Store the value of the `name` property inside `catName`, using bracket notation.
* Run the `greeting()` method using dot notation (it will log the greeting to the browser DevTools' console).
* Update the `color` property value to `black`.

The finished code should look something like this:

```
const cat = {
  name : 'Bertie',
  breed : 'Cymric',
  color : 'white',
  greeting: function() {
    console.log('Meow!');
  }
}

const catName = cat['name'];
cat.greeting();
cat.color = 'black';
```

## Task 2

In our next task, we want you to have a go at creating your own object literal to represent one of your favourite bands. The required members are:

* `name`: A string representing the band name.
* `nationality`: A string representing the country the band comes from.
* `genre`: What type of music the band plays.
* `members`: A number representing the number of members the band has.
* `formed`: A number representing the year the band formed.
* `split`: A number representing the year the band split up, or `false` if they are still together.
* `albums`: An array representing the albums released by the band. Each array item should be an object containing the following members:
  * `name`: A string representing the name of the album.
  * `released`: A number representing the year the album was released.

Include at least two albums in the `albums` array.

Once you've done this, you should then write a string to the variable `bandInfo`, which will contain a small biography detailing their name, nationality, years active, and style, and the title and release date of their first album.

The finished code should look something like this:

```
let bandInfo;

const band = {
  name : 'Black Sabbath',
  nationality : 'British',
  genre : 'heavy metal',
  members : 4,
  formed : 1968,
  split : 2017,
  albums : [
    {
       name : 'Black Sabbath',
       released : 1970
    },
    {
       name : 'Paranoid',
       released : 1970
    },
    {
       name : 'Master of Reality',
       released : 1971
    },
    {
       name : 'Vol. 4',
       released : 1972
    }
  ]
}

bandInfo = `The ${ band.nationality } ${ band.genre } band ${ band.name } were active ${ band.formed }–${ band.split }. Their first album, ${ band.albums[0].name }, was released in ${ band.albums[0].released }.`;
```

## Task 3

In this task we want you to return to the `cat` object literal from Task #1. We want you to rewrite the `greeting()` method so that it logs "Hello, said Bertie the Cymric." to the browser DevTools' console, but in a way that will work across _any_ cat object of the same structure, regardless of its name or breed.

When you are done, write your own object called `cat2`, which has the same structure, exactly the same `greeting()` method, but a different `name`, `breed`, and `color`.

Call both `greeting()` methods to check that they log appropriate greetings to the console.

The code should look like this:

```
const cat = {
  name : 'Bertie',
  breed : 'Cymric',
  color : 'white',
  greeting: function() {
    console.log(`Hello, said ${ this.name } the ${ this.breed }.`);
  }
}

const cat2 = {
  name : 'Elfie',
  breed : 'Aphrodite Giant',
  color : 'ginger',
  greeting: function() {
    console.log(`Hello, said ${ this.name } the ${ this.breed }.`);
  }
}

cat.greeting();
cat2.greeting();
```

## Task 4

In this task we want you to update the code from Task 3 to use a constructor for the cats, so we only have to define `greeting()` once.

The code should look like this:

```
function Cat(name, breed, color) {
  this.name = name;
  this.breed = breed;
  this.color = color;
  this.greeting = function() {
    console.log(`Hello, said ${ this.name } the ${ this.breed }.`);
  }
}

const cat = new Cat('Bertie', 'Cymric', 'white');
const cat2 = new Cat('Elfie', 'Aphrodite Giant', 'ginger');

cat.greeting();
cat2.greeting();
```


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Object basics: Task 3</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    const cat = {
      name : 'Bertie',
      breed : 'Cymric',
      color : 'white',
      greeting: function() {
        console.log('Meow!');
      }
    }
  </script>

</html>


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Object basics: Task 4</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    const cat = {
      name : 'Bertie',
      breed : 'Cymric',
      color : 'white',
      greeting: function() {
        console.log('Meow!');
      }
    }
  </script>

</html>


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Object basics: Task 2</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    let bandInfo;

    // Add your code here

    // Don't edit the code below here!

    const section = document.querySelector('section');
    let para1 = document.createElement('p');
    para1.textContent = bandInfo;
    section.appendChild(para1);
  </script>

</html>


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Object basics: Task 1</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    const cat = {
      name : 'Bertie',
      breed : 'Cymric',
      color : 'white',
      greeting: function() {
        console.log('Meow!');
      }
    }

    // Add your code here

    // Don't edit the code below here!

    const section = document.querySelector('section');

    let para1 = document.createElement('p');
    let para2 = document.createElement('p');

    para1.textContent = `The cat's name is ${ catName }.`;
    para2.textContent = `The cat's color is ${ cat.color }.`;

    section.appendChild(para1);
    section.appendChild(para2);
  </script>

</html>


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Object basics: Task 2</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">
let bandInfo;

// Put your code here

// Don't edit the code below here

let para1 = document.createElement('p');
para1.textContent = bandInfo;
section.appendChild(para1);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Object basics: Task 3</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">
const cat = {
  name : 'Bertie',
  breed : 'Cymric',
  color : 'white',
  greeting: function() {
    console.log('Meow!');
  }
}
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Object basics: Task 4</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">
const cat = {
  name : 'Bertie',
  breed : 'Cymric',
  color : 'white',
  greeting: function() {
    console.log(`Hello, said ${ this.name } the ${ this.breed }.`);
  }
}

const cat2 = {
  name : 'Elfie',
  breed : 'Aphrodite Giant',
  color : 'ginger',
  greeting: function() {
    console.log(`Hello, said ${ this.name } the ${ this.breed }.`);
  }
}

cat.greeting();
cat2.greeting();
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>Object basics: Task 1</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">
const cat = {
  name : 'Bertie',
  breed : 'Cymric',
  color : 'white',
  greeting: function() {
    console.log('Meow!');
  }
}

// Put your code here

// Don't edit the code below here

let para1 = document.createElement('p');
let para2 = document.createElement('p');

para1.textContent = `The cat's name is ${ catName }.`;
para2.textContent = `The cat's color is ${ cat.color }.`;

section.appendChild(para1);
section.appendChild(para2);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>JSON: Task 1</title>
    <link rel="stylesheet" href="../styles.css" />

    <textarea class="playable playable-js" style="height: 220px;">
const section = document.querySelector('section');

let para1 = document.createElement('p');
let para2 = document.createElement('p');
let motherInfo = 'The mother cats are called ';
let kittenInfo;
const requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/tasks/json/sample.json';

fetch(requestURL)
  .then(response => response.text())
  .then(text => displayCatInfo(text))

function displayCatInfo(catString) {
  let total = 0;
  let male = 0;

// Add your code here

// Don't edit the code below here!

  para1.textContent = motherInfo;
  para2.textContent = kittenInfo;
}

section.appendChild(para1);
section.appendChild(para2);
    </textarea>

      <input id="reset" type="button" value="Reset" />


text:
# JSON marking guide

The aim of the task is to demonstrate an understanding of the JavaScript features covered in the [Working with JSON](https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON) lesson in Learn Web Development on MDN.

Note: If there is an error in your code, it will be outputted into the results panel on the page, to help you try to figure out the answer (or into the browser's JavaScript console, in the case of the downloadable version).

## Task 1

The one and only task in this article concerns accessing JSON data and using it in your page. JSON data about some mother cats and their kittens is available in [sample.json](sample.json). The JSON is loaded into the page as a text string and made available in the `catString` parameter of the `displayCatInfo()` function, called when the provided promise chain (which starts by fetching the JSON data) is fulfilled. Your task is to fill in the missing parts of the `displayCatInfo()` function to store:

*  The names of the three mother cats, separated by commas, in the `motherInfo` variable.
*  The total number of kittens, and how many are male and female, in the `kittenInfo` variable.

The values of these variables are then printed to the screen inside paragraphs.

Some hints/questions:

* The JSON data is provided as text inside the `displayCatInfo()` function. You'll need to parse it into JSON using the `JSON.parse()` method.
* You'll probably want to use an outer loop to loop through the cats and add their names to the `motherInfo` variable string, and an inner loop to loop through all the kittens, add up the total of all/male/female kittens, and add those details to the `kittenInfo` variable string.
* The last mother cat name should have an "and" before it, and a full stop after it. How do you make sure this can work, no matter how many cats are in the JSON?
* Why are the `para1.textContent = motherInfo;` and `para2.textContent = kittenInfo;` lines inside the `displayCatInfo()` function, and. not at the end of the script? This has something to do with async code.

Your code should look something like this:

```
function displayCatInfo(catString) {
  let total = 0;
  let male = 0;

  // Add your code here
  const cats = JSON.parse(catString);

  for (let i = 0; i < cats.length; i++) {
    for (const kitten of cats[i].kittens) {
      total++;
      if (kitten.gender === 'm') {
        male++;
      }
    }

    if (i < (cats.length - 1)) {
      motherInfo += `${ cats[i].name }, `;
    } else {
      motherInfo += `and ${ cats[i].name }.`;
    }
  }

  kittenInfo  = `There are ${ total } kittens in total, ${ male } males and ${ total - male } females.`;

  // Don't edit the code below here!

  para1.textContent = motherInfo;
  para2.textContent = kittenInfo;
}
```


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>JSON: Task 1</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>
    const section = document.querySelector('section');

    let para1 = document.createElement('p');
    let para2 = document.createElement('p');
    let motherInfo = 'The mother cats are called ';
    let kittenInfo;
    const requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/tasks/json/sample.json';

    fetch(requestURL)
    .then(response => response.text())
    .then(text => displayCatInfo(text))

    function displayCatInfo(catString) {
      let total = 0;
      let male = 0;

      // Add your code here

      // Don't edit the code below here!

      para1.textContent = motherInfo;
      para2.textContent = kittenInfo;
    }

    section.appendChild(para1);
    section.appendChild(para2);
  </script>

</html>


text:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>OOJS: Task 2</title>
    <style>
      p {
        color: purple;
        margin: 0.5em 0;
      }

      * {
        box-sizing: border-box;
      }
    </style>
    <link rel="stylesheet" href="../styles.css" />
  </head>

  <body>

    <section class="preview">

    </section>

  </body>
  <script>

  </script>

</html>