<a id="ch-09"></a>

## Chapter 9 — The word ok is an empty note list

<!-- open-cyber-academy:lesson-figures:start ch-09 -->
### Lesson map

Lesson 09. Map, example, EX055.

```mermaid
flowchart TD
  N["notes starts empty"] --> A["Three ifs may append"]
  A --> J{"Is the joined text empty?"}
  J -->|Yes| O["Print ok"]
  J -->|No| P["Print the joined notes"]
```

`ok` is the fallback string. It is not a grade.

### Logical drawing

```text
newsletter
  fixed is None
  30 > 730 is false
  in use is True
joined notes: empty
printed token: ok
```
<!-- open-cyber-academy:lesson-figures:end ch-09 -->

### Learning outcomes

After this chapter, you should be able to:

1. Derive `ok` from an empty note list.
2. Name the three tests newsletter fails to trigger.
3. Refuse to read `ok` as a clearance or a scan.

### 9.1 The `or` runs only because `join` returned an empty string.

Each row starts with `notes = []`. Three conditions may append. The print expression is `'; '.join(notes) or 'ok'`. `join` of an empty list is `''`, and `''` is false in Python, so the `or` yields the literal `ok`. That literal is two characters. It is not the word "safe", and it is not the output of a vulnerability scanner. The script imports only `datetime`.

newsletter reaches that fallback for three separate reasons. `fixed` is `None`, so the version comparison is skipped. Thirty days is not greater than 730, so the age note is skipped. `used` is `True`, so REMOVE is skipped. If any one of those three had appended, the joined string would be non-empty and `ok` would not appear. The fallback is the absence of notes, not a fourth positive test.

An empty note list also does not record who looked, how long they looked, or which advisory feed they opened. Kula et al. (2018) discuss how often library dependencies stay stale in a studied population. Zimmermann et al. (2019) discuss concentration of maintenance in the npm ecosystem. Neither paper's counts are cells in this list, and newsletter's `ok` is not a citation of those papers. Jacobs et al. (2021) define EPSS for an identified vulnerability. This row has no identifier, so an EPSS value is undefined here rather than low.

| Test on newsletter | Result | Note appended? |
|---|---|---|
| `fixed` is present and installed `<` fixed | `fixed` is `None` | no |
| age `> 730` | 30 days | no |
| `not used` | the Boolean is true | no |
| joined text | empty, so `ok` | the fallback |

### 9.2 Worked example

| Reading of `ok` | What the expression did | Decision |
|---|---|---|
| No note was appended | Empty join is false, so the literal prints | Keep |
| Three different tests each declined | Version, age, and use | Keep |
| "`ok` means the plugin was scanned." | The file imports no scanner | Refuse |
| "`ok` is an EPSS result." | No vulnerability identifier is stored | Refuse |

> **Synthetic case.** newsletter's version string is `5.1.3`, and no score is attached to it.

### Errors and limits

Do not promote the fallback word into a clearance the script never computed.

### Apply

- **EX055 — Empty join.** newsletter prints `ok`. A classmate calls that a passed scan and an EPSS result. Which three tests declined to append a note, and what does the `or` actually substitute? *Rubric:* 3 = `fixed` is `None`, 30 days is not greater than 730, and the component is in use; empty join is false, so the literal `ok` prints; there is no scan and no EPSS;; 2 = `ok` is the empty-list fallback and the three tests declined;; 1 = one test;; 0 = none.

<!-- open-cyber-academy:chapter-navigation:start ch-09 -->
### Continue studying — lesson 09 (chapter 09 of 20)

[← Chapter 08](#ch-08) · [Course chapter index](../SUBJECTS.md) · [Chapter 10 →](#ch-10)

Continue to the next authored lesson.
<!-- open-cyber-academy:chapter-navigation:end -->

## Worked answers

<a id="answer-ex055"></a>
**EX055.** newsletter has no fixed version, an age of 30 days, and `in_use` true, so no note is appended. Empty `join` is false, and the literal `ok` prints. That is not a scan and not an EPSS value.
