Computing FoundationsSystems Foundations: Storage, Observability, and Tooling › Day 42

Hands-on lab — Day 42: Section Review: Your Computing Foundations Toolkit

Commands

Setup

cd labs/sections/computing-foundations/day-042-section-review-your-computing-foundations-toolkit

Run

bash examples/toolkit_check.sh
bash starter/toolkit_check.sh

Test

bash tests/run_tests.sh

File tree

examples/toolkit_check.sh
expected-output/FIELDS.md
expected-output/sample-macos.txt
expected-output/tests-macos.txt
metadata.yml
README.md
requirements/README.md
security.md
starter/toolkit_check.sh
starter/toolkit-worksheet.md
tests/run_tests.sh
troubleshooting.md

Lab README

Day 042 lab — Your Computing Foundations Toolkit Check

Lesson

Purpose

Day 42 closes Course 1 by consolidating six weeks of foundations. This lab makes that consolidation concrete on your own machine: a capstone script inspects your computer for the core Course 1 toolkit — a shell, git, curl, python3, sqlite3, and an editor — reports each tool's version and the day that taught it, then runs three live skill checks (make a git repo, run a shell pipeline, query a SQLite database) that exercise skills from across the section. The output is a readiness report: proof that the foundation is real, and a pointer to any gap you should fill before Course 2.

Learning objectives

  • Run a capstone inspection script and read a readiness report.
  • Confirm the core Course 1 tools are installed and note their versions.
  • Perform three cross-section skills end to end: a git commit, a shell pipeline, and a SQLite query.
  • Map each tool and skill back to the day of Course 1 that taught it.
  • Complete a self-assessment worksheet and identify your weakest area and the exact day to revisit.

Prerequisites

  • The Day 42 lesson (read it first — it explains the six areas this lab checks).
  • Days 1-41 of Course 1, which taught every tool the check looks for.
  • A terminal: Terminal.app (macOS), any terminal (Linux), or PowerShell/WSL (Windows).

Supported operating systems

  • macOS — fully supported (tested on macOS with Apple Silicon).
  • Linux — fully supported (any distribution with a POSIX shell and the standard utilities).
  • Windows — run the scripts unmodified inside WSL, or run the individual version commands (git --version, etc.) manually in PowerShell and fill the worksheet by hand (see troubleshooting.md).

Hardware requirements

Any computer that ran the rest of Course 1. The lab only reads system information and runs tiny in-memory checks; it needs no minimum RAM, disk, or GPU.

Required software

  • bash (3.2 or newer — preinstalled on macOS and Linux).
  • Standard OS utilities: uname, date, command, mktemp, printf, grep, wc, tr. The tools the check inspects (git, curl, python3, sqlite3, an editor) are the section's toolkit — the script degrades gracefully if any are missing.

Free and open-source options

Everything in this lab is free: bash and every command used are open-source or ship with your OS. No account, API key, or purchase is needed. The tools the check looks for are all free and open-source too; requirements/README.md lists how to install any that are missing.

Installation

None. Clone the repository (or copy this directory) and you are ready:

cd labs/sections/computing-foundations/day-042-section-review-your-computing-foundations-toolkit

File structure

day-042-section-review-your-computing-foundations-toolkit/
├── README.md                          ← you are here
├── metadata.yml                       ← machine-readable lab metadata
├── starter/
│   ├── toolkit_check.sh               ← YOUR working file (4 exercises)
│   └── toolkit-worksheet.md           ← self-assessment for the practice assignment
├── examples/
│   └── toolkit_check.sh               ← completed reference implementation
├── tests/
│   └── run_tests.sh                   ← automated checks
├── expected-output/
│   ├── sample-macos.txt               ← real captured run (macOS, Apple Silicon)
│   ├── tests-macos.txt                ← real captured test run
│   └── FIELDS.md                      ← required fields on every platform
├── requirements/
│   └── README.md                      ← which day covers installing each tool
├── troubleshooting.md
└── security.md

How to run

From this directory:

## 1. See the finished readiness report first
bash examples/toolkit_check.sh

## 2. Your task: complete the four exercises in the starter, then run it
bash starter/toolkit_check.sh

## 3. Check your work
bash tests/run_tests.sh

What the commands do

  • bash examples/toolkit_check.sh — runs the reference capstone: detects your OS (uname -s), checks for and versions the six toolkit tools mapping each to its Course 1 day, then runs three skill checks (a throwaway git init + commit, a printf | grep | wc -l pipeline, and an in-memory SQLite CREATE/INSERT/SELECT), and prints a readiness score. It is read-only on your real files and makes no network calls.
  • bash starter/toolkit_check.sh — the same skeleton with four exercises left as FILL_ME_IN. Each exercise comment names the exact command to use: the git version, the git init/commit pair, the shell pipeline, and the final readiness test. Edit the file and replace each placeholder.
  • bash tests/run_tests.sh — runs the reference script and checks it exits 0, prints every report block, reports git/curl/python3 as present, passes all three skill checks, and uses no network. It then checks your starter structurally, and — once you have replaced every executable FILL_ME_IN — holds it to the same strict standard.

Expected output

See expected-output/sample-macos.txt — a real captured run:

=== Computing Foundations Toolkit Check ===
Generated on: 2026-07-12
Operating system kernel: Darwin

-- Tool inventory --
[ok]   shell     : /bin/zsh (maps to Day 8: Meet the Terminal)
[ok]   git       : git version 2.50.1 (Apple Git-155) (maps to Day 30: Git Fundamentals)
[ok]   curl      : curl 8.7.1 (maps to Day 21: Inspecting Traffic with curl)
[ok]   python3   : Python 3.14.0 (maps to Day 15+: used across the course)
[ok]   sqlite3   : 3.51.0 (maps to Day 39: Data Storage)
[ok]   editor    : found vim on PATH ($EDITOR unset) (maps to Day 36: Choosing an Editor)

-- Skill checks --
[ok]   git init + commit works        (Days 29-30)
[ok]   shell pipeline works           (Days 10-12)
[ok]   sqlite query works             (Day 39)

-- Readiness --
Tools present: 6 / 6   Skills passed: 3 / 3
You are ready for Course 2. Nice work finishing the foundations.
=== End of check ===

Your values will differ. A missing tool shows a [--] line naming its install day instead of [ok] — the script does not crash on a gap. expected-output/FIELDS.md lists the fields that must appear on every platform.

Validation steps

  1. Run bash examples/toolkit_check.sh — it must exit without errors and print the header, tool inventory, skill checks, readiness line, and footer.
  2. Confirm git, curl, and python3 report [ok] on your machine.
  3. Confirm all three skill checks (git commit, pipeline, SQLite query) pass.
  4. Complete starter/toolkit_check.sh and confirm it produces the same readiness report.
  5. Run the tests (next section) — all checks must pass.

Tests

bash tests/run_tests.sh

Expected final line: 22 checks, 0 failure(s). while the starter is unfinished (14 strict checks on the reference script plus 8 structural checks on your starter and the offline check). Once you have completed the starter it becomes 29 checks, 0 failure(s).. The command exits 0 on success and non-zero on any failure, so it can run in CI. No network is used.

Cleanup

Nothing to clean up: the scripts only read system information and use a throwaway temp directory and an in-memory database, both discarded automatically. To reset your work, restore the starter from git: git checkout -- starter/toolkit_check.sh.

Troubleshooting

See troubleshooting.md — it maps every possible [--] line back to the Course 1 day that fixes it (a missing tool, an unset editor, a failed skill check, Windows/WSL notes).

Security notes

See security.md. Short version: the scripts are read-only, make no network calls, need no elevated privileges, touch no secrets, and their only writes are a throwaway temp repo and an in-memory database that are both discarded.

Extension exercises

  1. Add one more check to the completed script from a Course 1 area the starter does not cover — e.g. a global git identity (git config --get user.name), or a Python JSON parse (python3 -c 'import json; ...') — map it to its day, degrade gracefully, and add a matching test assertion.
  2. Have the script write its readiness report to a timestamped file and keep a history, so you can re-run it after revisiting a weak day and see progress.
  3. Turn the readiness check into a git hook (Day 41) that runs on commit in a practice repo, refusing the commit if a core tool is missing.
  • Previous day: Day 41 — Thinking in Automation: Scripts, Hooks, and Pipelines (labs/sections/computing-foundations/day-041-thinking-in-automation-scripts-hooks-and/).
  • Next day: Day 43 — the first lesson of Course 2, Programming with Python (labs/sections/programming-with-python/, to be written).

Expected output

FIELDS.md

# Required output fields (all platforms)

A correct run of `toolkit_check.sh` prints, in order:

1. `=== Computing Foundations Toolkit Check ===`
2. `Generated on: YYYY-MM-DD`
3. `Operating system kernel: Darwin` (macOS) or `Linux`
4. `-- Tool inventory --`
5. Six tool lines, each `[ok]` or `[--]`, for: `shell`, `git`, `curl`,
   `python3`, `sqlite3`, `editor` — every line names the Course 1 day it
   maps to (contains `maps to Day`).
6. `-- Skill checks --`
7. Three skill lines, each `[ok]` or `[--]`:
   `git init + commit works`, `shell pipeline works`, `sqlite query works`.
8. `-- Readiness --`
9. `Tools present: <n> / 6   Skills passed: <n> / 3`
10. A verdict line: `You are ready for Course 2. ...` when git, the
    pipeline, and python3 are all present, otherwise the "Almost there" line.
11. `=== End of check ===`

`sample-macos.txt` in this directory is a real captured run (macOS, Apple
Silicon, 2026-07-12) where all six tools are present and all three skills
pass. `tests-macos.txt` is the captured test run (`22 checks, 0 failure(s).`).

## Platform differences

- **Linux** output has the same shape; the kernel line reads `Linux`, the
  `shell` line usually shows `/bin/bash`, and the `python3`/`sqlite3`
  versions differ. All six tools are present on a standard developer install.
- **Missing tool** (any platform): its line reads `[--] <tool> : not found —
  <install day>` instead of `[ok]`, the readiness counts drop accordingly,
  and — if git, the pipeline, or python3 is the missing piece — the verdict
  becomes the "Almost there" line. The script never crashes on a missing
  tool; that graceful degradation is the point.

sample-macos.txt

=== Computing Foundations Toolkit Check ===
Generated on: 2026-07-12
Operating system kernel: Darwin

-- Tool inventory --
[ok]   shell     : /bin/zsh (maps to Day 8: Meet the Terminal)
[ok]   git       : git version 2.50.1 (Apple Git-155) (maps to Day 30: Git Fundamentals)
[ok]   curl      : curl 8.7.1 (maps to Day 21: Inspecting Traffic with curl)
[ok]   python3   : Python 3.14.0 (maps to Day 15+: used across the course)
[ok]   sqlite3   : 3.51.0 (maps to Day 39: Data Storage)
[ok]   editor    : found vim on PATH ($EDITOR unset) (maps to Day 36: Choosing an Editor)

-- Skill checks --
[ok]   git init + commit works        (Days 29-30)
[ok]   shell pipeline works           (Days 10-12)
[ok]   sqlite query works             (Day 39)

-- Readiness --
Tools present: 6 / 6   Skills passed: 3 / 3
You are ready for Course 2. Nice work finishing the foundations.
=== End of check ===

tests-macos.txt

Testing <repo>/labs/sections/computing-foundations/day-042-section-review-your-computing-foundations-toolkit/examples/toolkit_check.sh ...
  ok: script exits successfully
  ok: prints report header
  ok: prints tool inventory block
  ok: prints skill checks block
  ok: prints readiness block
  ok: prints report footer
  ok: tool lines map to a day
  ok: reports git present ([ok])
  ok: reports curl present ([ok])
  ok: reports python3 present ([ok])
  ok: git init + commit skill passes
  ok: sqlite query skill passes
  ok: shell pipeline skill passes
  ok: reports ready for Course 2
Note: starter/toolkit_check.sh still has unfilled exercises — testing structure only.
Testing <repo>/labs/sections/computing-foundations/day-042-section-review-your-computing-foundations-toolkit/starter/toolkit_check.sh ...
  ok: script exits successfully
  ok: prints report header
  ok: prints tool inventory block
  ok: prints skill checks block
  ok: prints readiness block
  ok: prints report footer
  ok: tool lines map to a day
  ok: lab scripts make no network calls

22 checks, 0 failure(s).

Source files

examples/toolkit_check.sh (5051 bytes)
#!/usr/bin/env bash
# Day 042 lab — Computing Foundations Toolkit Check (completed reference).
#
# A capstone for Course 1: it inspects your own machine for the core tools
# you learned across days 1-41, reports each tool's version and the day that
# taught it, then runs three live skill checks that exercise skills from
# across the section (make a git repo, run a shell pipeline, query SQLite).
# It is read-only on your real files, needs no network, and degrades
# gracefully when a tool is missing — telling you which day covers it.
#
# Usage:  bash examples/toolkit_check.sh
set -uo pipefail

os="$(uname -s)"
tools_present=0
tools_total=0
skills_passed=0
skills_total=0

echo "=== Computing Foundations Toolkit Check ==="
echo "Generated on: $(date '+%Y-%m-%d')"
echo "Operating system kernel: ${os}"
echo
echo "-- Tool inventory --"

# report_tool <label> <version-string-or-empty> <maps-to-note>
report_tool() {
  local label="$1" version="$2" note="$3"
  tools_total=$((tools_total + 1))
  if [ -n "${version}" ]; then
    tools_present=$((tools_present + 1))
    printf '[ok]   %-9s : %s (%s)\n' "${label}" "${version}" "${note}"
  else
    printf '[--]   %-9s : not found — %s\n' "${label}" "${note}"
  fi
}

# --- shell (Day 8) ---
shell_path="${SHELL:-}"
[ -z "${shell_path}" ] && shell_path="$(command -v bash || true)"
report_tool "shell" "${shell_path}" "maps to Day 8: Meet the Terminal"

# --- git (Day 30) ---
if command -v git >/dev/null 2>&1; then
  report_tool "git" "$(git --version)" "maps to Day 30: Git Fundamentals"
else
  report_tool "git" "" "maps to Day 30: Git Fundamentals — install git to continue the course"
fi

# --- curl (Day 21) ---
if command -v curl >/dev/null 2>&1; then
  report_tool "curl" "$(curl --version 2>/dev/null | head -n 1 | cut -d' ' -f1-2)" "maps to Day 21: Inspecting Traffic with curl"
else
  report_tool "curl" "" "maps to Day 21: Inspecting Traffic with curl"
fi

# --- python3 (used across the course from Day 15 on) ---
if command -v python3 >/dev/null 2>&1; then
  report_tool "python3" "$(python3 --version 2>&1)" "maps to Day 15+: used across the course"
else
  report_tool "python3" "" "maps to Day 15+: install python3 before Course 2"
fi

# --- sqlite3 (Day 39) ---
if command -v sqlite3 >/dev/null 2>&1; then
  report_tool "sqlite3" "$(sqlite3 --version 2>/dev/null | cut -d' ' -f1)" "maps to Day 39: Data Storage"
else
  report_tool "sqlite3" "" "maps to Day 39: Data Storage — brew/apt install sqlite3"
fi

# --- editor (Day 36): prefer $EDITOR, else look for a common one ---
editor_found=""
if [ -n "${EDITOR:-}" ]; then
  editor_found="\$EDITOR=${EDITOR}"
else
  for e in nvim vim nano code emacs micro; do
    if command -v "${e}" >/dev/null 2>&1; then
      editor_found="found ${e} on PATH (\$EDITOR unset)"
      break
    fi
  done
fi
report_tool "editor" "${editor_found}" "maps to Day 36: Choosing an Editor"

echo
echo "-- Skill checks --"

# skill_result <label> <ok:yes/no> <days>
skill_result() {
  local label="$1" ok="$2" days="$3"
  skills_total=$((skills_total + 1))
  if [ "${ok}" = "yes" ]; then
    skills_passed=$((skills_passed + 1))
    printf '[ok]   %-30s (%s)\n' "${label}" "${days}"
  else
    printf '[--]   %-30s (%s)\n' "${label}" "${days}"
  fi
}

# Skill 1: version control — init a throwaway repo and commit (Days 29-30).
git_skill="no"
if command -v git >/dev/null 2>&1; then
  tmp_repo="$(mktemp -d "${TMPDIR:-/tmp}/toolkit-check-tmp.XXXXXX")"
  if (
    cd "${tmp_repo}" &&
    git init -q &&
    echo "hello foundations" > note.txt &&
    git add note.txt &&
    git -c user.name='Toolkit Check' -c user.email='check@example.com' commit -q -m 'first commit' &&
    git log --oneline | grep -q 'first commit'
  ) >/dev/null 2>&1; then
    git_skill="yes"
  fi
  rm -rf "${tmp_repo}"
fi
skill_result "git init + commit works" "${git_skill}" "Days 29-30"

# Skill 2: the command line — build a pipeline and count matching lines (Days 10-12).
pipe_skill="no"
count="$(printf 'apple\nbanana\napricot\ncherry\n' | grep '^a' | wc -l | tr -d ' ')"
[ "${count}" = "2" ] && pipe_skill="yes"
skill_result "shell pipeline works" "${pipe_skill}" "Days 10-12"

# Skill 3: storage — create and query an in-memory SQLite table (Day 39).
sql_skill="no"
if command -v sqlite3 >/dev/null 2>&1; then
  answer="$(sqlite3 ':memory:' 'CREATE TABLE t(x INTEGER); INSERT INTO t VALUES (42); SELECT x FROM t;' 2>/dev/null)"
  [ "${answer}" = "42" ] && sql_skill="yes"
fi
skill_result "sqlite query works" "${sql_skill}" "Day 39"

echo
echo "-- Readiness --"
echo "Tools present: ${tools_present} / ${tools_total}   Skills passed: ${skills_passed} / ${skills_total}"

# Core tools that Course 2 truly needs: git, python3, and a shell + pipeline.
if [ "${git_skill}" = "yes" ] && [ "${pipe_skill}" = "yes" ] && command -v python3 >/dev/null 2>&1; then
  echo "You are ready for Course 2. Nice work finishing the foundations."
else
  echo "Almost there — revisit the day(s) shown next to any [--] line above, then re-run."
fi
echo "=== End of check ==="
metadata.yml (598 bytes)
lesson_id: D042
day: 42
kind: command-line-inspection
languages: [bash]
setup_commands:
  - cd labs/sections/computing-foundations/day-042-section-review-your-computing-foundations-toolkit
run_commands:
  - bash examples/toolkit_check.sh
  - bash starter/toolkit_check.sh
test_commands:
  - bash tests/run_tests.sh
cleanup_commands:
  - 'git checkout -- starter/toolkit_check.sh  # optional: reset your work'
requires_network: false
requires_api_key: false
estimated_minutes: 30
last_executed: '2026-07-12'
executed_on: 'macOS (Apple Silicon), bash tests/run_tests.sh → 22 checks, 0 failure(s).'
requirements/README.md (1271 bytes)
# Dependencies — Day 042 lab

This lab checks for the core Course 1 toolkit on your machine; it does not
install anything. The check itself needs only a POSIX shell:

- `bash` ≥ 3.2 (preinstalled on macOS and every mainstream Linux distribution)
- Standard utilities the check calls: `uname`, `date`, `command`, `mktemp`,
  `printf`, `grep`, `wc`, `tr` — all part of the base system.

The tools the check *looks for* are the section's toolkit. They are not
required for the script to run (it degrades gracefully when one is missing),
but you will want them for the rest of the course:

| Tool | Course 1 day | Install if missing |
| ---- | ------------- | ------------------ |
| a shell | Day 8 | Already present — it is running the script |
| `git` | Days 29-35 | `brew install git` / `apt install git` (Day 13 covered package managers) |
| `curl` | Day 21 | `brew install curl` / `apt install curl` |
| `python3` | Day 15+ | `brew install python` / `apt install python3` |
| `sqlite3` | Day 39 | `brew install sqlite` / `apt install sqlite3` |
| an editor | Day 36 | `brew install vim`/`nano`, or set `$EDITOR` |

There is deliberately no `requirements.txt`/`package.json`: this capstone
must run on any machine that finished Course 1, including one with gaps.
starter/toolkit_check.sh (6429 bytes)
#!/usr/bin/env bash
# Day 042 lab — Computing Foundations Toolkit Check (YOUR working file).
#
# This starter already prints the report skeleton and detects your OS. Your
# job is the four numbered exercises below: each names the exact command to
# fill in, replacing the `FILL_ME_IN` placeholder. The completed reference is
# in examples/toolkit_check.sh — run that first, then rebuild these four
# pieces yourself. The script is read-only on your real files and needs no
# network.
#
# Usage:  bash starter/toolkit_check.sh
set -uo pipefail

os="$(uname -s)"
tools_present=0
tools_total=0
skills_passed=0
skills_total=0

echo "=== Computing Foundations Toolkit Check ==="
echo "Generated on: $(date '+%Y-%m-%d')"
echo "Operating system kernel: ${os}"
echo
echo "-- Tool inventory --"

report_tool() {
  local label="$1" version="$2" note="$3"
  tools_total=$((tools_total + 1))
  if [ -n "${version}" ]; then
    tools_present=$((tools_present + 1))
    printf '[ok]   %-9s : %s (%s)\n' "${label}" "${version}" "${note}"
  else
    printf '[--]   %-9s : not found — %s\n' "${label}" "${note}"
  fi
}

# --- shell (already done for you, as a worked example) ---
shell_path="${SHELL:-}"
[ -z "${shell_path}" ] && shell_path="$(command -v bash || true)"
report_tool "shell" "${shell_path}" "maps to Day 8: Meet the Terminal"

# ===========================================================================
# Exercise 1: report the git version.
#   Replace FILL_ME_IN with the command that prints git's version:
#       git --version
#   Keep it inside the "$(...)" so its output becomes the version string.
# ===========================================================================
if command -v git >/dev/null 2>&1; then
  git_version="$(FILL_ME_IN)"
  report_tool "git" "${git_version}" "maps to Day 30: Git Fundamentals"
else
  report_tool "git" "" "maps to Day 30: Git Fundamentals — install git to continue"
fi

# --- curl, python3, sqlite3, editor (done for you) ---
if command -v curl >/dev/null 2>&1; then
  report_tool "curl" "$(curl --version 2>/dev/null | head -n 1 | cut -d' ' -f1-2)" "maps to Day 21: Inspecting Traffic with curl"
else
  report_tool "curl" "" "maps to Day 21: Inspecting Traffic with curl"
fi
if command -v python3 >/dev/null 2>&1; then
  report_tool "python3" "$(python3 --version 2>&1)" "maps to Day 15+: used across the course"
else
  report_tool "python3" "" "maps to Day 15+: install python3 before Course 2"
fi
if command -v sqlite3 >/dev/null 2>&1; then
  report_tool "sqlite3" "$(sqlite3 --version 2>/dev/null | cut -d' ' -f1)" "maps to Day 39: Data Storage"
else
  report_tool "sqlite3" "" "maps to Day 39: Data Storage — brew/apt install sqlite3"
fi
editor_found=""
if [ -n "${EDITOR:-}" ]; then
  editor_found="\$EDITOR=${EDITOR}"
else
  for e in nvim vim nano code emacs micro; do
    if command -v "${e}" >/dev/null 2>&1; then
      editor_found="found ${e} on PATH (\$EDITOR unset)"
      break
    fi
  done
fi
report_tool "editor" "${editor_found}" "maps to Day 36: Choosing an Editor"

echo
echo "-- Skill checks --"

skill_result() {
  local label="$1" ok="$2" days="$3"
  skills_total=$((skills_total + 1))
  if [ "${ok}" = "yes" ]; then
    skills_passed=$((skills_passed + 1))
    printf '[ok]   %-30s (%s)\n' "${label}" "${days}"
  else
    printf '[--]   %-30s (%s)\n' "${label}" "${days}"
  fi
}

# ===========================================================================
# Exercise 2: verify git works by making a throwaway repo and committing.
#   Fill the two placeholder lines inside the subshell:
#     - initialise a repo quietly:   git init -q
#     - commit the staged file:      git -c user.name='Toolkit Check' \
#                                        -c user.email='check@example.com' \
#                                        commit -q -m 'first commit'
#   (The -c flags supply an identity so the commit works even if you have no
#    global git config — a trick from the git week.)
# ===========================================================================
git_skill="no"
if command -v git >/dev/null 2>&1; then
  tmp_repo="$(mktemp -d "${TMPDIR:-/tmp}/toolkit-check-tmp.XXXXXX")"
  if (
    cd "${tmp_repo}" &&
    FILL_ME_IN &&
    echo "hello foundations" > note.txt &&
    git add note.txt &&
    FILL_ME_IN &&
    git log --oneline | grep -q 'first commit'
  ) >/dev/null 2>&1; then
    git_skill="yes"
  fi
  rm -rf "${tmp_repo}"
fi
skill_result "git init + commit works" "${git_skill}" "Days 29-30"

# ===========================================================================
# Exercise 3: a mini end-to-end that touches the command-line core.
#   Build a shell pipeline (Days 10-12) that filters the four words below to
#   those starting with 'a' and counts them. Replace FILL_ME_IN with:
#       printf 'apple\nbanana\napricot\ncherry\n' | grep '^a' | wc -l | tr -d ' '
#   The expected count is 2 (apple, apricot). This one line exercises text
#   tools, pipes, and counting — the command-line core of the section.
# ===========================================================================
pipe_skill="no"
count="$(FILL_ME_IN)"
[ "${count}" = "2" ] && pipe_skill="yes"
skill_result "shell pipeline works" "${pipe_skill}" "Days 10-12"

# Skill 3 (storage): create and query an in-memory SQLite table (done for you).
sql_skill="no"
if command -v sqlite3 >/dev/null 2>&1; then
  answer="$(sqlite3 ':memory:' 'CREATE TABLE t(x INTEGER); INSERT INTO t VALUES (42); SELECT x FROM t;' 2>/dev/null)"
  [ "${answer}" = "42" ] && sql_skill="yes"
fi
skill_result "sqlite query works" "${sql_skill}" "Day 39"

echo
echo "-- Readiness --"
echo "Tools present: ${tools_present} / ${tools_total}   Skills passed: ${skills_passed} / ${skills_total}"

# ===========================================================================
# Exercise 4: self-score. Print the readiness verdict. Replace the
# placeholder with a test that says you are ready only when the git and
# pipeline skills both passed AND python3 is installed:
#     [ "${git_skill}" = "yes" ] && [ "${pipe_skill}" = "yes" ] \
#        && command -v python3 >/dev/null 2>&1
# ===========================================================================
if FILL_ME_IN; then
  echo "You are ready for Course 2. Nice work finishing the foundations."
else
  echo "Almost there — revisit the day(s) shown next to any [--] line above, then re-run."
fi
echo "=== End of check ==="
starter/toolkit-worksheet.md (1668 bytes)
# Computing Foundations self-assessment — Day 042 worksheet

This is the practice assignment. Fill it in honestly — it is a repair map,
not a grade. Rate your confidence in each of the six areas of Course 1 from
**1 (shaky)** to **5 (solid)**, and for each area note the exact day you would
revisit to improve. Keep this file: it is your personal map into Course 2.

## Confidence ratings

| # | Area | Days | Your rating (1-5) | Day you'd revisit | Why |
| - | ---- | ---- | ----------------- | ----------------- | --- |
| 1 | How computers work (the machine) | 1-7 |  |  |  |
| 2 | The command line | 8-14 |  |  |  |
| 3 | The internet | 15-21 |  |  |  |
| 4 | APIs | 22-28 |  |  |  |
| 5 | Git and GitHub | 29-35 |  |  |  |
| 6 | Systems foundations (storage, observability, automation) | 36-41 |  |  |  |

## Toolkit-check readiness line

Run `bash examples/toolkit_check.sh` and paste its readiness line here:

```
Tools present: __ / 6   Skills passed: __ / 3
Verdict: ______________________________________________
```

Note any tool that reported `[--]` and the day it maps to:

-

## My weakest area and my plan

Write one short paragraph (5-8 sentences) answering all three:

1. Which single area is your weakest, and why do you think so?
2. Which exact day will you revisit before or during Course 2?
3. What specifically do you expect to relearn there?

> _(write here)_

## One connection I now see

In one or two sentences, describe one way two of the six areas connect that
you did not appreciate before this review (for example, how an API failure is
really a networking question, or how git protects you from a storage mistake).

> _(write here)_
tests/run_tests.sh (3685 bytes)
#!/usr/bin/env bash
# Tests for the Day 042 lab. Run from the lab directory:
#   bash tests/run_tests.sh
#
# Verifies that the toolkit check runs, reports the core tools that this
# machine has (git, curl, python3), and that its end-to-end skill checks
# touch git, a SQLite query, and a shell pipeline. No network is used.
# If the learner has completed the starter (no FILL_ME_IN left), their
# version is held to the same standard.
set -u

lab_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
failures=0
checks=0

check() {
  local label="$1" ok="$2"
  checks=$((checks + 1))
  if [ "${ok}" = "yes" ]; then
    echo "  ok: ${label}"
  else
    echo "  FAIL: ${label}"
    failures=$((failures + 1))
  fi
}

has() { echo "$1" | grep -q "$2" && echo yes || echo no; }

run_check_script() {
  local script="$1" strict="$2" output
  echo "Testing ${script} ..."
  if ! output="$(bash "${script}" 2>&1)"; then
    check "script exits successfully" "no"
    echo "${output}" | sed 's/^/    /'
    return
  fi
  check "script exits successfully" "yes"

  # Structure: header, sections, footer.
  check "prints report header"        "$(has "${output}" '^=== Computing Foundations Toolkit Check ===$')"
  check "prints tool inventory block" "$(has "${output}" '^-- Tool inventory --$')"
  check "prints skill checks block"   "$(has "${output}" '^-- Skill checks --$')"
  check "prints readiness block"      "$(has "${output}" '^-- Readiness --$')"
  check "prints report footer"        "$(has "${output}" '^=== End of check ===$')"

  # Every tool line maps to a Course 1 day.
  check "tool lines map to a day" "$(has "${output}" 'maps to Day')"

  if [ "${strict}" = "strict" ]; then
    # Core tools known to be present on this machine must report [ok].
    for t in git curl python3; do
      check "reports ${t} present ([ok])" "$(echo "${output}" | grep -E "^\[ok\]   ${t}" >/dev/null && echo yes || echo no)"
    done
    # The end-to-end must exercise git + a query + a pipeline, all passing.
    check "git init + commit skill passes" "$(echo "${output}" | grep -E '^\[ok\]   git init \+ commit works' >/dev/null && echo yes || echo no)"
    check "sqlite query skill passes"      "$(echo "${output}" | grep -E '^\[ok\]   sqlite query works' >/dev/null && echo yes || echo no)"
    check "shell pipeline skill passes"    "$(echo "${output}" | grep -E '^\[ok\]   shell pipeline works' >/dev/null && echo yes || echo no)"
    # Readiness verdict for a fully-equipped machine.
    check "reports ready for Course 2" "$(has "${output}" 'You are ready for Course 2')"
  fi
}

# The completed reference must pass strictly on this machine.
run_check_script "${lab_dir}/examples/toolkit_check.sh" strict

# The starter ships with FILL_ME_IN placeholders in executable positions;
# once the learner replaces them all, hold their script to the same strict
# standard. (Match only the code forms, not the comment prose that names
# the placeholder, so a completed starter is graded strictly.)
if grep -qE '\$\(FILL_ME_IN\)|FILL_ME_IN &&|if FILL_ME_IN' "${lab_dir}/starter/toolkit_check.sh"; then
  echo "Note: starter/toolkit_check.sh still has unfilled exercises — testing structure only."
  run_check_script "${lab_dir}/starter/toolkit_check.sh" lenient
else
  run_check_script "${lab_dir}/starter/toolkit_check.sh" strict
fi

# Confirm the lab makes no network calls (offline by contract).
if grep -RIE 'curl [^|]*http|wget |ping ' "${lab_dir}/examples" "${lab_dir}/starter" >/dev/null 2>&1; then
  check "lab scripts make no network calls" "no"
else
  check "lab scripts make no network calls" "yes"
fi

echo
echo "${checks} checks, ${failures} failure(s)."
[ "${failures}" -eq 0 ]

Troubleshooting

Troubleshooting — Day 042 lab

This lab is a readiness report, so most "problems" are really the report doing its job: surfacing a gap and pointing you to the day that fixes it. Use this table to turn each [--] line into a plan.

A tool shows [--] (not found) — which day fixes it?

Missing tool Revisit What to do
git Days 29-35 Install git (Day 13 covered package managers), then redo Day 30's commit flow
curl Day 21 Install curl; Day 21 shows how to inspect traffic with it
python3 Day 15+ Install python3 — Course 2 needs it; the machine/OS week (1-7) covers what an install is
sqlite3 Day 39 brew install sqlite / apt install sqlite3; Day 39 explains when a database beats a file
editor (unset $EDITOR, none on PATH) Day 36 Choose and configure an editor, then export EDITOR=<your-editor>

A skill check shows [--]

  • git init + commit works failed. git is likely missing or unusually configured. The check supplies its own identity with -c user.name/-c user.email, so a missing global config is not the cause — revisit Days 29-30. Run git --version to confirm git is installed.
  • shell pipeline works failed. One of grep, wc, or tr is missing or your shell is very non-standard. Revisit Days 10-12 on text tools and pipes; on minimal containers install coreutils.
  • sqlite query works failed. sqlite3 is missing (see the table above) or an old build. Revisit Day 39.

sqlite3: command not found

SQLite ships with macOS and most Linux installs; if it is absent the check reports it as a gap rather than crashing. Install it with your package manager (Day 13) — brew install sqlite or apt install sqlite3.

editor shows as unset

You have no $EDITOR environment variable and no common editor was found on your PATH. That is exactly the situation Day 36 addresses: install and configure an editor, then set export EDITOR=<name> in your shell profile (Day 11 covered shell configuration).

The git skill check left a folder behind

It should not — it builds the throwaway repo under a temporary directory (mktemp -d) and removes it. If you interrupted the script mid-run, delete any leftover toolkit-check-tmp.* directory in your system temp folder ($TMPDIR on macOS, /tmp on Linux).

Permission denied when running the script

Run it through bash explicitly (bash starter/toolkit_check.sh) rather than ./starter/toolkit_check.sh. If you prefer the latter, make it executable first with chmod +x starter/toolkit_check.sh.

Windows: bash is not recognized

Use WSL (wsl --install, then open Ubuntu and follow the Linux path), or run the individual tool-version commands manually in PowerShell (git --version, curl --version, python --version) and fill the worksheet by hand.

Security notes

Security notes — Day 042 lab

  • What the scripts do: read-only inspection. They check whether tools are present (command -v), print each tool's version, and run three tiny self-contained skill checks. They make no network connections, need no elevated privileges, and change nothing on your real files.
  • The only writes are throwaway and temporary. The git skill check creates a disposable repository under a mktemp -d temporary directory and deletes it immediately; the SQLite check uses an in-memory database (:memory:) that never touches disk. Nothing is written to your working directory or your home folder.
  • Privileges: everything runs as your normal user. Nothing here needs sudo. As the course has stressed since Day 1, if any tutorial ever asks you to sudo a script you have not read, stop and read it first — these scripts are short and commented for exactly that reason.
  • Privacy: the report lists tool versions, your shell path, and your OS kernel. This is mildly identifying (it reveals patch levels), so treat a pasted readiness report the way you would a machine profile: fine for a class forum, but do not post reports for employer-managed machines. The lab deliberately collects no serial numbers, hostnames, or user identifiers.
  • No secrets are touched. The git commit uses a placeholder identity supplied on the command line, not your real git config, and no API keys, tokens, or credentials are read or displayed anywhere.