Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework 24 hour clock worked example prep #1033

Merged
merged 20 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
b63e7cc
Rework 24 hour clock worked example prep
illicitonion Oct 4, 2024
971dc01
Update common-content/en/module/js1/assertions/index.md
illicitonion Oct 23, 2024
a11aad3
Update common-content/en/module/js1/identifying-missing-tests/index.md
illicitonion Oct 23, 2024
f455c3c
Update common-content/en/module/js1/interpreting-errors/index.md
illicitonion Oct 23, 2024
2e82d12
Update common-content/en/module/js1/interpreting-errors/index.md
illicitonion Oct 23, 2024
1bbbc8b
Update common-content/en/module/js1/interpreting-errors/index.md
illicitonion Oct 23, 2024
ad7a518
Update common-content/en/module/js1/refactoring-repetition/index.md
illicitonion Oct 23, 2024
8b21223
Update common-content/en/module/js1/reusing-variable-names/index.md
illicitonion Oct 23, 2024
4697e38
Update common-content/en/module/js1/reusing-variable-names/index.md
illicitonion Oct 23, 2024
b0029ac
Update common-content/en/module/js1/reusing-variable-names/index.md
illicitonion Oct 23, 2024
7d2b054
Simplify more language, pull out more exercises
illicitonion Oct 23, 2024
de8b8ee
Update common-content/en/module/js1/sub-goal-2/index.md
illicitonion Oct 23, 2024
4bbceaa
Update common-content/en/module/js1/sub-goal-2/index.md
illicitonion Oct 23, 2024
8e46331
Update common-content/en/module/js1/strings/index.md
illicitonion Oct 23, 2024
cf717c4
Update common-content/en/module/js1/strings/index.md
illicitonion Oct 23, 2024
79ca8dd
Update common-content/en/module/js1/identifying-missing-tests/index.md
illicitonion Oct 23, 2024
0d0117e
Update common-content/en/module/js1/interpreting-errors/index.md
illicitonion Oct 23, 2024
0a55157
Update common-content/en/module/js1/assertions/index.md
illicitonion Oct 23, 2024
c70588c
Update common-content/en/module/js1/identifying-missing-tests/index.md
illicitonion Oct 23, 2024
412f52f
More review comments
illicitonion Oct 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 0 additions & 57 deletions common-content/en/module/js1/assembly/index.md

This file was deleted.

80 changes: 20 additions & 60 deletions common-content/en/module/js1/assertions/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ We now have 2 new concepts: **booleans** and **comparisons**. From these concept

> 🔑 An assertion is a _check_ that our code behaves in a particular way: this check can either succeed or fail.

So far we've used the log function `console.log`. We can write assertions using another function: [`console.assert`](https://developer.mozilla.org/en-US/docs/Web/API/console/assert). The documentation says that `console.assert` writes an error message to the console if the assertion is false. If the assertion is true, nothing happens. As `finalCharacter === "?"` evaluates to true, no message will be written to the console.
So far we've used the log function `console.log`. We can write assertions using another function: [`console.assert`](https://developer.mozilla.org/en-US/docs/Web/API/console/assert). The documentation says that `console.assert` writes an error message to the console if the assertion is false. If the assertion is true, nothing happens. As `10 + 32 === 42` evaluates to true, no message will be written to the console.

```js
const calculation = 10 + 32;
Expand All @@ -47,12 +47,13 @@ const result = 42;
console.assert(calculation === result);
```

Update the final character in the `sentence` variable string to make the assertion fail. Check the output you get in the console.
Change the value assigned to the `result` variable to make the assertion fail. Check the output you get in the console.

👉🏿 [Keep Going](#predict-explain-check-2)
{{</tab>}}

{{<tab name="Exercise 2">}}

{{<note type="exercise" title="Exercise 2">}}
Let's look at an example using `formatAs12HourClock`:

```js
Expand All @@ -62,8 +63,6 @@ console.assert(formatAs12HourClock("08:00") === "08:00 am");

Predict and explain if the assertion will succeed or fail. Pay particular attention to the return value of `formatAs12HourClock`.

{{</note>}}

{{</tab>}}

{{</tabs>}}
Expand All @@ -84,7 +83,7 @@ console.assert(
Let's break down these arguments to make sense of what's going on:

1. **first argument** - `formatAs12HourClock("08:00") === "08:00 am"` - the condition we're checking
2. **second argument** - `current output: ${formatAs12HourClock("08:00")}, target output: 08:00 am` - a message string that will be logged to the console if the condition is false.
2. **second argument** - `` `current output: ${formatAs12HourClock("08:00")}, target output: 08:00 am` `` - a message string that will be logged to the console if the condition is false.

#### 🧹 Refactor

Expand All @@ -109,13 +108,13 @@ Assertion failed: current output: undefined, target output: 08:00 am

## 🧰 Implementing the functionality

On line 4, the function is being passed a single argument `"08:00"`. But our function ignores it - it doesn't declare any parameters. We can parameterise the function and label the input as `time`:
On line 3, the function is being passed a single argument `"08:00"`. But our function ignores it - it doesn't declare any parameters. We can parameterise the function and label the input as `time`:
illicitonion marked this conversation as resolved.
Show resolved Hide resolved

```js
function formatAs12HourClock(time) {}
```

According to our assertion, when we call our function with an input of `"08:00"` we need to create an output of `"08:00 am"`. We can add `"am"` to the `time` to get the target output. We can update our function with a template literal, set the return value and then _re-run_ our code including our assertion to check the function is returning the correct value.
According to our assertion, when we call our function with an input of `"08:00"` we need to create an output of `"08:00 am"`. If we add `"am"` to the `time`, we'll get the target output. We can update our function with a template literal, set the return value and then _re-run_ our code including our assertion to check the function is returning the correct value.

📓 We can and should continually check our assertions to see if our function’s current output meets our target output.

Expand All @@ -140,49 +139,21 @@ Create a javascript file on your local machine and execute the code above. Doubl

## 💼 Checking different cases

So far we’ve only created assertions that check the function’s behaviour for times _after midnight and before midday_. In these cases, there is a pattern: take the current time and add `"am"` to the end.
So far we’ve only created assertions that check the function’s behaviour for times _between midnight and midday_. In these cases, there is a pattern: take the current time and add `" am"` to the end.

Now we need to assert that the function behaves correctly when the time is later than midday. Let’s create an assertion for our function when passed an input of `"23:00"`:
But this isn't the pattern we need to follow for _all_ times. To make sure our function works for all times, we need to write more assertions.
illicitonion marked this conversation as resolved.
Show resolved Hide resolved

```js {linenos=table,linenostart=1}
function formatAs12HourClock(time) {
return `${time} am`;
}
We need to assert that the function behaves correctly when the time is later than midday.

const currentOutput = formatAs12HourClock("08:00");
const targetOutput = "08:00 am";
console.assert(
currentOutput === targetOutput,
`current output: ${currentOutput}, target output: ${targetOutput}`
);
Before we think about any code, we should think about our problem. Separating _problem_ and _code_ lets us focus better. First we can focus on the data. Then we can focus on the code.

const currentOutput = formatAs12HourClock("23:00");
const targetOutput = "11:00 pm";
console.assert(
currentOutput === targetOutput,
`current output: ${currentOutput}, target output: ${targetOutput}`
);
```
First, let's think of an example time in 24 hour clock - we'll pick `23:00`.

## 🔄 Reusing variable names
Next, let's work out what we expect our example time to be in 12 hour clock: `11:00 pm`.

When we run the file with Node, we get an error in the console:
Now that we've thought about the problem, we can write the code. Let's create an assertion for our function when passed an input of `"23:00"`:

```bash
SyntaxError: Identifier 'currentOutput' has already been declared
```

In this case, identifier means name of a variable, so in a variable declaration like

```js
const currentOutput = formatAs12HourClock("08:23");
```

`currentOutput` is the **identifier**.

When an error is thrown, it means the execution of the program stops at this point and an error report is sent to the user. However, we want to do multiple assertions.

```js title="problem.js"
```js {linenos=table,linenostart=1}
function formatAs12HourClock(time) {
return `${time} am`;
}
Expand All @@ -194,23 +165,12 @@ console.assert(
`current output: ${currentOutput}, target output: ${targetOutput}`
);

// ❌ this assertion now fails
const currentOutput2 = formatAs12HourClock("23:00");
const targetOutput2 = "11:00 pm";
const currentOutput = formatAs12HourClock("23:00");
const targetOutput = "11:00 pm";
console.assert(
currentOutput2 === targetOutput2,
`current output: ${currentOutput2}, target output: ${targetOutput2}`
currentOutput === targetOutput,
`current output: ${currentOutput}, target output: ${targetOutput}`
);
```

Now the second assertion fails with the following message:

```bash
Assertion failed: current output: 23:00 am, target output: 11:00 pm
```

{{<note type="exercise" title="Exercise 2">}}

✏️ Write another assertion that checks `formatAs12HourClock` returns the target output when passed another _time input in the afternoon._

{{</note>}}
Save this code to a file. Before you run it in Node, write down what you think will happen. Then run it with Node - compare what you saw with what you predicted.
6 changes: 3 additions & 3 deletions common-content/en/module/js1/clocks/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ We use the notation "HH:MM". HH is our stand-in for the hours value. MM is our s

Let's pose a problem: given any time in 24 hour clock, we want to format it as a 12 hour clock time. To achieve this goal, we're going to implement a function `formatAs12HourClock`.

_Given_ a time in 24 hour clock
_When_ we call `formatAs12HourClock`
_Then_ we get back a string representing the same time in 12 hour clock
_Given_ a time in 24 hour clock
_When_ we call `formatAs12HourClock`
_Then_ we get back a string representing the same time in 12 hour clock.

### 🧪 Our tests:

Expand Down
2 changes: 1 addition & 1 deletion common-content/en/module/js1/comparison/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ b) the 🎯 target output?

We have learned how to log values to the console. We can also **compare** two values. We check that a function produces some target output with a comparison.

We compare the current output of `formatAs12HourClock("08:00")` with the target output of `"08:00 am"` and ask: **are these two values the same?**. We use a comparison operator to compare two expressions and check if they evaluate to the same value. We use the strict equality operator `===` to check if two values are the same.
We compare the current output of `formatAs12HourClock("08:00")` with the target output of `"08:00 am"` and ask: **are these two values the same?** We use a comparison operator to compare two expressions and check if they evaluate to the same value. We use the strict equality operator `===` to check if two values are the same.

### Left equals Right

Expand Down
74 changes: 74 additions & 0 deletions common-content/en/module/js1/identifying-missing-tests/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
+++
title = '🔬 Identifying missing tests'

time = 30
facilitation = false
emoji= '🔬'
[objectives]
1='Define groups of input'
2='Define edge cases'
3='Identify groups of input for a function'
4='Identify edge cases for a function'
[build]
render = 'never'
list = 'local'
publishResources = false

+++

We started off writing one test for our code - checking that it correctly handled the input `08:00`.

We wrote an implementation that passed all our (1) tests!
illicitonion marked this conversation as resolved.
Show resolved Hide resolved

Then we realised there was a bug - it didn't handle times after midday correctly.

So we wrote another test - for the input `23:00`. We saw our implementation failed that test. And we fixed it.

And we had an implementation that passed all our (2) tests!

> When will we be happy that our implementation works for all possible inputs? When do we have enough tests?

### Groups of input

One way to approach this is to think about what _groups_ of input there may be to our problem.
illicitonion marked this conversation as resolved.
Show resolved Hide resolved

We've already identified two examples of groups of input to the problem of converting 24 hour clocks to 12 hour clocks: Times before midday and times after midday.

One way to find extra cases to consider (and extra tests to write) is to try to think of different groups of input.

For example, some times are exactly on the hour (end in `:00`) and other times have a non-zero number of minutes.

{{<note type="exercise">}}
Try to think of as many groups of input to this problem as you can. Write an example assertion for each one.
illicitonion marked this conversation as resolved.
Show resolved Hide resolved

If you find any bugs in the implementation, go fix them!
{{</note>}}

### Edge cases

Another way to consider this question is to think about what _edge cases_ there are in the problem.

{{<note type="definition" title="Definition: edge case">}}
An edge case is an unusual value which may need special treatment.

Some examples are: the minimum value, the maximum value, and the boundary between two groups of input.
{{</note>}}

Some example edge cases for this problem are:
`00:00`
: The minimum time, which is `12:00 am` in 12 hour clock.
This is also the only hour that is _bigger_ in 12 hour clock than 24 hour clock.

`24:00`
: The maximum time.

`12:00`
: Where time changes from am to pm. The edge between morning times and afternoon times.

Often these edge cases are where bugs happen.

{{<note type="exercise">}}
Try to think of as many edge cases of input to this problem as you can. Write an example assertion for each one.
illicitonion marked this conversation as resolved.
Show resolved Hide resolved

If you find any bugs in the implementation, go fix them!
{{</note>}}
Loading
Loading