Plan: Transitioning to Forward Deployed Engineer / AI Engineer
백엔드 엔지니어가 FDE·AI 엔지니어로 전환하기 위한 단계별 로드맵
연속 희석 플레이트 수치로부터 원래 농도(CFU/mL)를 계산하는 미생물학 학생용 인터랙티브 연습 도구
An interactive practice tool for microbiology students learning to calculate the original concentration in CFU/mL from serial dilution plate counts.
교육JavaScript · CSSGitHub @CalebHendren온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기An interactive web app for microbiology students to practice calculating original concentrations (CFU/mL) from serial dilution plate counts.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗An interactive web app for microbiology students to practice calculating original concentrations (CFU/mL) from serial dilution plate counts. Built for classroom use in a Preliminary Microbiology course.
Each problem presents four test tubes — Tube 1 holds the original sample, Tubes 2–4 are stepwise dilutions — along with three petri dishes showing colony counts from each dilution. Students work backward from the countable plate (30–300 colonies) through the dilution series to find the concentration in the original tube.
The dilution factors aren't given. Students determine them from the labeled transfer and diluent volumes shown between tubes. For example, transferring 100 µL into 900 µL of diluent is a 1/10 dilution — students need to recognize that themselves.
Students get three attempts per problem (configurable). After a correct answer or three wrong attempts, the app reveals a worked solution showing each stepwise dilution, the cumulative total at each tube, identification of the countable plate, and the final calculation.
# From the repo root, serve over http (modules need it):
python3 -m http.server 8000
# Then open http://localhost:8000
Deploys unchanged to GitHub Pages — push the repo and enable Pages from main.
Open config.js in the repo root. Every classroom-relevant knob lives there:
| Key | What it does |
|---|---|
appTitle | Page title and header. Defaults to "Serial Dilution Practice". |
courseName / instructorName | Optional banner under the subtitle. |
attemptsAllowed | Attempts per problem before the solution reveals. Default 3. |
toleranceFraction | ± acceptance band around the true answer. Default 0.02 (±2%). |
countableRange | The "countable plate" range. Default [30, 300]. |
cleanLogProbability | Fraction of problems where every step is 1/10 or 1/100. Default 0.75. |
factorPool | Dilution factors + weights used in mixed problems. |
volumePool | Plated volumes (mL) + weights. |
unitPool | µL vs mL weighting for the per-problem unit. |
stepVolumes | Realistic [transfer, diluent] pairs for each factor and unit. |
defaultTheme | First-load theme key. See Themes below. |
defaultColorMode | "light", "dark", or "system" (follows OS). |
showCalculatorOnDesktop | Whether the calculator auto-opens on desktop. |
Edit, save, reload — no build step.
Six themes ship out of the box. All meet WCAG 2.1 AA contrast; the two High Contrast themes meet AAA.
| Key | Mode | Notes |
|---|---|---|
light-default | light | Chattanooga State light theme (navy, royal blue, orange), shared with MicroGrade. Shown as "Light" in the picker (default). |
clean-slate | light | Clinical white background, slate text, blue-teal accent. |
hc-light | light | Near-white background, near-black text, deep navy/burgundy. AAA. |
lab-slate | dark | Warm dark blue-gray paper, cream text, muted teal/coral. Paired with light-default. |
midnight | dark | Deep navy, soft sky text, electric teal/amber. Paired with clean-slate. |
hc-dark | dark | Pure black background, pure white text, bright brass focus. AAA. |
Two controls live in the page toolbar:
<select> listing all six themes, grouped Light / Dark.Choices persist via localStorage. With no saved choice, the page follows the OS prefers-color-scheme setting and continues listening for mid-session changes until the student picks a theme manually.
10⁻ⁿ form. Choice is saved across refreshes.CFU/mL = (colonies × reciprocal of total dilution) / volume plated. Hidden by default and not persisted.Designed to meet federal accessibility guidelines for higher education (WCAG 2.1 AA / Section 508):
<header>, <main>, <section> with aria-labelledby).aria-live regions announce attempt count, feedback, solution updates, and theme changes.hc-light and hc-dark exceed 7:1 (WCAG AAA).prefers-reduced-motion support — animations disabled when the OS setting is on.<select> and <button> elements, fully keyboard-operable, with associated labels and aria-pressed.serialdilution/
├── index.html # slim shell — landmarks, controls, module loads
├── config.js # instructor config (edit this)
├── README.md
├── LICENSE
├── styles/
│ ├── tokens.css non-color design tokens
│ ├── themes.css 6 theme variants — color tokens only
│ ├── base.css resets, body, skip link, focus, reduced motion
│ ├── header.css site header + toolbar + theme controls
│ ├── layout.css main grid + .card + problem statement
│ ├── tubes.css dilution tubes row
│ ├── plates.css petri plates row
│ ├── answer.css answer input, attempts dots, feedback
│ ├── buttons.css .btn variants — 44px touch targets
│ ├── solution.css worked solution, dilution table, derivation list, equation reveal
│ ├── calculator.css floating calculator
│ └── responsive.css mobile overrides
└── js/ # ES modules, no build step
├── main.js entry — DOM wiring + init
├── config.js merges user config with defaults
├── state.js shared mutable state
├── storage.js localStorage wrappers
├── utils.js random pickers, gcd, seeded RNG
├── format.js number formatting, parsing, sci notation
├── problem.js problem generation (uses config pools)
├── svg.js tube/arrow/plate SVG generators — themed via CSS vars
├── render.js DOM render for tubes, plates, attempts, feedback
├── equation.js equation reveal panel
├── calculator.js 4-function calculator widget
├── solution.js worked solution renderer
├── answer.js answer parsing + tolerance check
├── lifecycle.js new-problem reset
└── theme.js theme registry, light/dark toggle, persistence
<link>/<script type="module"> only.main.Because ES modules require http(s), the app does not work when opened via file://. Run a local server (python3 -m http.server) during development, or deploy to Pages.
(plate index, count) so the same problem renders identically on re-render but different problems get visually distinct dishes.repeat(7, minmax(0, 1fr))) for tubes + arrow cells, ensuring the arrows sit at the exact midpoint between tubes regardless of label content.[data-theme="..."] on <html> for the named theme plus [data-color-mode="light|dark"] for the resolved mode (the latter drives color-scheme so browser-native widgets match).