Blame

2ebc08 lisa 2026-06-11 07:46:24
Add C05 page: From SRS to Detailed Designs — Data and Logic Traces one SRS sentence ('computed, never stored') through all four C05-1 data/logic tools — data dictionary, IPO charts, pseudocode, object descriptions — using the real SAT-grader project as a worked example with faded guidance. Sibling of the Mock-ups page; links added both ways and from C05-home. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1
# From SRS to Detailed Designs — Data and Logic
2
3
The Hamilton and Alexandra College · Year 12 · 2026
4
5
The [Mock-ups sibling of this page](From%20SRS%20to%20Detailed%20Designs%20-%20Mock-ups) traces a *screen* back to a requirement. This page traces the **data and logic** the same way, using the same real project — `vsd-sat-grader`, the SAT folio grader your teacher actually built.
6
7
C05-1 asks for four data/logic design tools: a **data dictionary**, **IPO charts**, **pseudocode**, and **object descriptions**. The trap is to treat them as four separate deliverables you grind out one after another. They are not. They are **four views of one design**, and the proof is simple: a single sentence from your SRS shows up in all four of them.
8
9
Here is that sentence. It is from §7 (Data model) of the real SRS, quoted exactly:
10
11
> Derived values (bands, calculated scores, totals, ranks) are **computed, never stored**.
12
13
That one rule — *store the inputs, compute everything you can derive from them* — is the spine of this page. We follow it through all four tools, then through the built UI, and you will see the same idea each time wearing a different costume.
14
15
---
16
17
## The four tools are one design
18
19
The SRS data model is the source. Each design tool is a different lens on it, and each lens also surfaces in the app you can run.
20
21
```mermaid
22
flowchart TD
23
SRS["C03 · SRS §7<br/>Data model<br/>'computed, never stored'"]
24
SRS --> DD["Data dictionary<br/><i>what is stored vs derived</i>"]
25
SRS --> OD["Object descriptions<br/><i>attribute vs method</i>"]
26
SRS --> PC["Pseudocode<br/><i>how a value is derived</i>"]
27
SRS --> IPO["IPO charts<br/><i>input → process → output</i>"]
28
DD --> UI["Built UI"]
29
OD --> UI
30
PC --> UI
31
IPO --> UI
32
UI --> SEE["You can see the rule<br/>on screen:<br/>totals, bands, live summary"]
33
```
34
35
The four tools answer four questions about the *same* truth — and because the SRS forbids storing derived values, every tool has to agree on which values those are. Disagreement between tools is a design bug. Agreement is traceability.
36
37
---
38
39
## Fully worked: "computed, never stored", through all four tools
40
41
We will now walk the one SRS sentence through every tool, quoting each artefact's own wording so you can see the rule restated in each language.
42
43
### Tool 1 — Data dictionary: a separate section for what is *not* stored
44
510c7d lisa 2026-06-11 07:57:42
Build data-dictionary section easy to hard: small tables first Tool 1 now opens with the two complete two-row tables (Criteria, Band scale) reproduced verbatim, then an abbreviated four-row cut of the student record (student, grades, indicator_scores, final) linking to the full table on GitHub, before the existing §5 derived-values punchline. Requested by Jeremy after review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
45
Before the big table, meet two **complete, small** ones. The real data dictionary opens with these — each just two rows, but already carrying the full six-column format (Field / Data type / Format / Description / Example / Validation). The column set itself is the teaching point: every field, however small, gets a type, a format, an example *and* a validation rule. Both tables verbatim:
46
78300f Jeremy Chen 2026-06-10 22:01:56
heading level fixed
47
> #### 1. Criteria (`CRITERIA`)
510c7d lisa 2026-06-11 07:57:42
Build data-dictionary section easy to hard: small tables first Tool 1 now opens with the two complete two-row tables (Criteria, Band scale) reproduced verbatim, then an abbreviated four-row cut of the student record (student, grades, indicator_scores, final) linking to the full table on GitHub, before the existing §5 derived-values punchline. Requested by Jeremy after review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
48
49
| Field | Data type | Format / range | Description | Example | Validation |
50
| --- | --- | --- | --- | --- | --- |
51
| `cid` | str | `C` + 2 digits, `C01`–`C10` | Criterion identifier; also keys the rubric filename | `C03` | Must have a matching `data/rubrics/<cid>-rubric.md` |
52
| `name` | str | ≤ 80 chars | Criterion title from the VCAA rubric heading | `Skills in documenting a software requirements specification` | Non-empty |
53
78300f Jeremy Chen 2026-06-10 22:01:56
heading level fixed
54
> #### 2. Band scale (`BANDS`, `BAND_LABELS`)
510c7d lisa 2026-06-11 07:57:42
Build data-dictionary section easy to hard: small tables first Tool 1 now opens with the two complete two-row tables (Criteria, Band scale) reproduced verbatim, then an abbreviated four-row cut of the student record (student, grades, indicator_scores, final) linking to the full table on GitHub, before the existing §5 derived-values punchline. Requested by Jeremy after review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
55
56
| Field | Data type | Format / range | Description | Example | Validation |
57
| --- | --- | --- | --- | --- | --- |
58
| `band` | str | `low-high`, 5 fixed values | Rubric band a score falls in: `1-2`, `3-4`, `5-6`, `7-8`, `9-10` | `7-8` | One of the 5 values |
59
| `band_label` | str | band + qualifier | Display label for evidence grids | `7-8 (high)` | Derived 1:1 from `band` |
60
f826cf lisa 2026-06-11 08:05:50
Add Grade-tab screenshot showing the Band scale data dictionary on screen Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
61
Four rows do not look like much — until you see how much of the screen they drive. Here is the Grade tab; look at the labels:
62
63
![The SAT grader Grade tab for Cohen, criterion C03. At the top, a live summary line reads "8 × 60% + 7 × 40% = 7.6 → Criterion score: 8" above indicator tabs "SRS Document (60%)" and "Critical Thinking (40%)". Indicator 1's rubric descriptor table has band columns from "1--2 (very low)" to "9--10 (very high)". Below it, an Observation evidence grid and a Validation evidence grid each have five columns headed "1-2 (very low)", "3-4 (low)", "5-6 (medium)", "7-8 (high)" and "9-10 (very high)", with evidence notes sitting under the 5-6 and 7-8 columns. At the bottom, a Band row of radio buttons 1-2, 3-4, 5-6, 7-8, 9-10 with 7-8 selected, an Indicator score of 8, and an orange Save button.](From%20SRS%20to%20Detailed%20Designs%20-%20Data%20and%20Logic/correction-05-after-ai-removed-from-grade.png)
64
65
The five **Band** radio buttons (`1-2` … `9-10`) are exactly the five fixed values of `band` — "One of the 5 values", nothing else can exist. And the column headers across both evidence grids — "1-2 (very low)" … "9-10 (very high)" — are `band_label`, the "band + qualifier" display form, "Derived 1:1 from `band`". Two tiny tables, and every band label on the screen is accounted for: the `cid` in the Criteria dropdown comes from the first, every band marking on the page comes from the second.
66
510c7d lisa 2026-06-11 07:57:42
Build data-dictionary section easy to hard: small tables first Tool 1 now opens with the two complete two-row tables (Criteria, Band scale) reproduced verbatim, then an abbreviated four-row cut of the student record (student, grades, indicator_scores, final) linking to the full table on GitHub, before the existing §5 derived-values punchline. Requested by Jeremy after review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
67
That is a complete data dictionary in miniature — you can read it end to end in thirty seconds. Now you are ready for the real thing: §4, the **student record**, the shape that becomes one markdown file per student in Sprint 2. Here is an abbreviated cut — four rows chosen to show the variety the format can carry, each verbatim:
68
78300f Jeremy Chen 2026-06-10 22:01:56
heading level fixed
69
> #### 4. Student record (`MOCK_STUDENTS` → one markdown file per student in Sprint 2)
510c7d lisa 2026-06-11 07:57:42
Build data-dictionary section easy to hard: small tables first Tool 1 now opens with the two complete two-row tables (Criteria, Band scale) reproduced verbatim, then an abbreviated four-row cut of the student record (student, grades, indicator_scores, final) linking to the full table on GitHub, before the existing §5 derived-values punchline. Requested by Jeremy after review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
70
71
| Field | Data type | Format / range | Description | Example | Validation |
72
| --- | --- | --- | --- | --- | --- |
73
| `student` | str | ≤ 50 chars | Student name; keys the record and the leaderboard | `Cohen` | Unique within cohort; non-empty |
74
| `grades` | dict | keyed by `cid` | Grading record per criterion (absent = not graded yet) | `{"C03": {...}}` | Keys ∈ `CRITERIA` |
75
| `grades[cid].indicator_scores` | list[int \| None] | 0–10 whole numbers, one per indicator | Teacher's score per indicator | `[8, 7]` | Length ≤ indicator count; each 0–10 or empty |
76
| `grades[cid].final` | int \| None | 0–10 | Final criterion score after the teacher reconciles calculated vs AI vs cross-marker; never auto-filled | `8` | 0–10 or absent |
77
78
*… plus 10 more fields (evidence grids, AI score and evidence, cross-mark, reconciliation note, report comment and advice) — read the [full table on GitHub](https://github.com/vce-soft-dev/SD26-Students/blob/main/Proj-SAT-Grader-UI/C05/data-dictionary.md).*
79
80
Notice the variety those four rows carry: a simple string with a uniqueness rule (`student`), a dict keyed by criterion (`grades`), a list validated per item (`indicator_scores`), and a nullable int whose description states a *policy* — `final` is "never auto-filled". Same six columns every time.
81
82
So §§1–4 document everything **stored**. The punchline is what comes next: a separate §5 for **derived values** — the things the dictionary deliberately does *not* let you store. The heading is exact:
2ebc08 lisa 2026-06-11 07:46:24
Add C05 page: From SRS to Detailed Designs — Data and Logic Traces one SRS sentence ('computed, never stored') through all four C05-1 data/logic tools — data dictionary, IPO charts, pseudocode, object descriptions — using the real SAT-grader project as a worked example with faded guidance. Sibling of the Mock-ups page; links added both ways and from C05-home. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
83
78300f Jeremy Chen 2026-06-10 22:01:56
heading level fixed
84
> #### 5. Derived values (computed, never stored)
2ebc08 lisa 2026-06-11 07:46:24
Add C05 page: From SRS to Detailed Designs — Data and Logic Traces one SRS sentence ('computed, never stored') through all four C05-1 data/logic tools — data dictionary, IPO charts, pseudocode, object descriptions — using the real SAT-grader project as a worked example with faded guidance. Sibling of the Mock-ups page; links added both ways and from C05-home. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
85
86
A few of its rows:
87
88
| Value | Derivation | Example |
89
| --- | --- | --- |
90
| Total 1 | Sum of criterion results for C01–C05 (Unit 3 Outcome 2) | `15` |
91
| Total 2 | Sum of criterion results for C06–C10 (Unit 4 Outcome 1) | `0` |
92
| Rank | Cohort summary row order: sorted by Total, descending | top row |
93
94
Now look at the built Leaderboard. Those rows are not abstractions — they are columns on screen:
95
96
![The SAT grader Leaderboard tab, Cohort summary sub-tab. A table with one row per student and columns C01 to C10, then Total 1 (C01-C05), Total 2 (C06-C10) and Total. Cohen sits in the top row with C03 = 8, C04 = 7, Total 1 = 15, Total = 15; Connor is next with C03 = 9, Total = 9; the remaining students show 0. A caption above the table reads "One row per student, best total first".](From%20SRS%20to%20Detailed%20Designs%20-%20Data%20and%20Logic/correction-08-after-leaderboard-cohort.png)
97
98
The column headers **Total 1 (C01–C05)**, **Total 2 (C06–C10)** and **Total** are the three data-dictionary rows above, made visible. And the **row order is the derived "Rank"**: Cohen (Total 15) sits above Connor (Total 9) because the table is "sorted by Total, descending" — the app never stores a rank number, it sorts and the position *is* the rank.
99
100
> [!NOTE]
101
> The scores here are **Sprint 1 mock data**, not real grades. Cohen's C03 indicators are `[8, 7]` — the exact example student record shown in the SRS §7 code block. That is why the same numbers reappear throughout this page: they are the SRS's own worked example travelling from artefact to artefact.
102
103
### Tool 2 — Object descriptions: stored is an attribute, derived is a method
104
105
The object descriptions say the same thing in object-oriented language. Teaching point 3, quoted exactly:
106
107
> **Stored vs derived, as attribute vs method** — `final` is an attribute (a teacher's decision, stored); `calculated()` is a method (a weighted average, derived). This is the class-diagram form of our data rule "derived values are never stored".
108
5eef4a lisa 2026-06-11 08:14:51
Tool 2: add Student + CriterionGrade class boxes; pre-render class diagrams to PNG OtterWiki's bundled mermaid renders classDiagram poorly, so both diagrams are now rendered locally with mermaid-cli 11 and embedded as images. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
109
Here are the two classes you have already met in the data dictionary — `Student` and `CriterionGrade` — with the relationships left out so you can concentrate on reading each box:
110
111
![Two UML class boxes side by side with no connecting lines. Student has an upper compartment with attributes name, comment and advice, and a lower compartment with methods criterion_result(cid), total1(), total2() and total(). CriterionGrade has an upper compartment with attributes indicator_scores, ai, ai_evidence, cross, cross_note, final and final_note, and a lower compartment with methods weighted(), calculated() and is_reconciled().](From%20SRS%20to%20Detailed%20Designs%20-%20Data%20and%20Logic/class-student-criteriongrade.png)
112
113
Read each box top to bottom: the upper compartment is the **attributes** — everything stored, and every one of them is a row you saw in the data dictionary's student record (`indicator_scores`, `ai`, `cross`, `final`, …). The lower compartment is the **methods** — everything derived, and every one of them is a row from the data dictionary's §5 (`calculated`, the totals behind the leaderboard). The horizontal line between the compartments *is* the stored/derived split, drawn in UML.
114
2ebc08 lisa 2026-06-11 07:46:24
Add C05 page: From SRS to Detailed Designs — Data and Logic Traces one SRS sentence ('computed, never stored') through all four C05-1 data/logic tools — data dictionary, IPO charts, pseudocode, object descriptions — using the real SAT-grader project as a worked example with faded guidance. Sibling of the Mock-ups page; links added both ways and from C05-home. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
115
So the data dictionary's "stored vs derived" split is the object model's "attribute vs method" split. `final` carries `()` nowhere — it is a value you keep. `calculated()` carries `()` — it is a value you *compute on demand* and throw away.
116
9c736f lisa 2026-06-11 08:22:12
Tool 2: add VCAA object description table for Student, CriterionGrade as exercise Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
117
#### The same class as an object description table
118
119
A class diagram is the *drawn* form. The **object description** is the written form VCAA asks for, and its layout is slightly different — a small table, one per object, with three rows:
120
121
> An object description is used to design an object to be used within a software module. Object descriptions include the name of the object, a list of the required attributes/properties (data) and a list of the required methods (behaviours) that are required to maximise the potential future use of the object. The data type of each property/attribute may or may not be listed with the property/attribute. Where required, parameters should be included in the description of methods.
122
123
Here is `Student` — the same class you just read as a UML box — written as an object description:
124
125
| | |
126
| ---------------------- | ----------------------------------------------------------------------------------- |
127
| Name | Student |
128
| Properties/ Attributes | name (string) <br><br>comment (string) <br><br>advice (string) |
129
| Methods | criterion_result(cid) <br><br>total1() <br><br>total2() <br><br>total() |
130
131
Same information, different costume: the UML box's upper compartment became the **Properties/Attributes** row, the lower compartment became the **Methods** row. Notice the conventions at work — every property lists its data type in brackets (optional, but do it), and `criterion_result(cid)` includes its parameter because the method needs one.
132
133
> **Your design log:** write the object description table for `CriterionGrade` from its UML box above. It has seven properties and three methods — and when you list `calculated()` in the Methods row, you have restated "computed, never stored" in a third costume.
134
2ebc08 lisa 2026-06-11 07:46:24
Add C05 page: From SRS to Detailed Designs — Data and Logic Traces one SRS sentence ('computed, never stored') through all four C05-1 data/logic tools — data dictionary, IPO charts, pseudocode, object descriptions — using the real SAT-grader project as a worked example with faded guidance. Sibling of the Mock-ups page; links added both ways and from C05-home. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
135
### Tool 3 — Pseudocode: how the derived value is actually computed
136
122a35 lisa 2026-06-11 09:10:54
Tool 3: show Algorithm 1 pseudocode verbatim before the hand-trace Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
137
The data dictionary says a calculated score *is* derived. The object model says `calculated()` is a method. The pseudocode says **how**. Algorithm 1, verbatim from the artefact:
138
139
```
140
ALGORITHM CalculateCriterionScore
141
INPUT: indicatorScores[1..n] // teacher's score per indicator, 0–10 or empty
142
weights[1..n] // from the criterion's checklist, sums to 100
143
OUTPUT: calculated // whole number 0–10, or NONE
144
145
BEGIN
146
totalWeighted ← 0
147
totalWeight ← 0
148
FOR i ← 1 TO n DO
149
IF indicatorScores[i] IS NOT EMPTY THEN
150
totalWeighted ← totalWeighted + indicatorScores[i] × weights[i]
151
totalWeight ← totalWeight + weights[i]
152
END IF
153
END FOR
154
155
IF totalWeight = 0 THEN
156
RETURN NONE // nothing graded yet
157
END IF
158
159
weighted ← totalWeighted / totalWeight // e.g. 8×60 + 7×40 → 7.6
160
RETURN RoundHalfUp(weighted) // 7.6 → 8, 7.5 → 8, 7.4 → 7
161
END
162
```
163
164
Now run it by hand for Cohen's C03 (`[8, 7]`, weights `[60, 40]`):
2ebc08 lisa 2026-06-11 07:46:24
Add C05 page: From SRS to Detailed Designs — Data and Logic Traces one SRS sentence ('computed, never stored') through all four C05-1 data/logic tools — data dictionary, IPO charts, pseudocode, object descriptions — using the real SAT-grader project as a worked example with faded guidance. Sibling of the Mock-ups page; links added both ways and from C05-home. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
165
166
- For each scored indicator, add `indicatorScore × weight` to `totalWeighted` and `weight` to `totalWeight`: `8 × 60 = 480`, `7 × 40 = 280`, so `totalWeighted = 760`, `totalWeight = 100`.
167
- `weighted ← totalWeighted / totalWeight` → `760 / 100 = 7.6`.
168
- `RETURN RoundHalfUp(weighted)` → `7.6 → 8`.
169
170
Nothing in that algorithm reads a stored score. It reads the **inputs** (indicator scores, weights) and derives the result fresh every time — exactly what "computed, never stored" demands.
171
172
### Tool 4 — IPO charts: it can recompute live *because* nothing is stored
173
174
The IPO charts have an event row that only makes sense if derived values are never stored. Quoted exactly from the event-level table:
175
176
> `live_summary` — Recompute the criterion score as indicator scores are typed.
177
178
And a sibling row:
179
180
> `band_of` — Which rubric band a score falls in.
181
182
If the calculated score were stored, you would have to save it before it could update. Because it is derived, the app can **recompute it on every keystroke**. Here is the Grade tab where both rows fire:
183
184
![The SAT grader Grade tab for student Cohen, criterion C03. Under a "Holistic" heading, a "Rubric band (1-10)" row of radio buttons 1-2, 3-4, 5-6, 7-8, 9-10 with 7-8 selected and highlighted in orange. Below it a Score field showing 8, then an Observations text box with two bullet reasons, and an AI Grader panel showing an AI suggested score of 8 with its justification. An orange Save button sits at the bottom.](From%20SRS%20to%20Detailed%20Designs%20-%20Data%20and%20Logic/01-grade-tab.png)
185
186
The **7-8 band is highlighted in orange** because `band_of(8)` returns the `7-8` band — that highlight is the `band_of` IPO output rendered on screen. As you type a score, `live_summary` re-derives the criterion score behind the Score tab. Neither value is written to disk until you Save; both are derived live. That is the IPO chart's restatement of the same one rule.
187
188
Four tools, four costumes, one sentence. That is what "four views of one design" means.
189
190
---
191
192
## Each tool, anchored to a requirement (your turn to finish each)
193
194
Above, the guidance was full. Below, it fades: each tool gets a short section that names *which requirement it answers*, then ends with **one question** for you to take into your design log.
195
196
### Data dictionary ← FR2 + SRS §7
197
198
FR2 quoted exactly:
199
200
> All data is persisted as **markdown files** (one file per student) — the single source of truth, editable by hand or by AI tools.
201
202
"One file per student" is why the data dictionary's §4 documents a single **student record** shape (`student`, `grades`, `comment`, `advice`) rather than a database schema. SRS §7 shows that record as YAML frontmatter; the data dictionary gives each field a type, format, example and validation rule. The frontmatter shape *is* the data dictionary, written out as a file.
203
204
> **Your design log:** find one field in data-dictionary §4 whose **Validation** column would be impossible to enforce if data lived in a database instead of one markdown file per student. (Hint: look at `student` — "Unique within cohort".)
205
206
### IPO charts ← the context diagram
207
208
You met **context diagrams** back in C02 — one process, the external entities around it, the data flowing in and out. The IPO charts pick up exactly there. The system-level IPO row is built straight from the context diagram:
209
210
| Input | Process | Output |
211
| --- | --- | --- |
212
| Indicator scores + evidence, cross-mark + note, final score + note, report comments (Teacher 1); AI suggested score + evidence (Claude Code, via markdown) | Grade each criterion per indicator; weight indicator scores into calculated criterion scores; support reconciliation; aggregate cohort totals | Rubric descriptors, calculated scores with working, reconcile view, cohort summary (Teacher 1); evidence + rubric + scores as markdown (to Claude Code); final scores + report (to School Report System) |
213
214
The external entities from the context diagram (Teacher 1, Claude Code, the School Report System) reappear here as the *sources* of inputs and the *destinations* of outputs.
215
216
> [!TIP]
217
> The event-level IPO charts are **generated from the app's own event wiring**, so design and build cannot drift apart. The artefact says so: every Gradio handler is `trigger.change(process, [inputs], [outputs])`, so the charts are produced by `tools/generate_ipo.py` and you "regenerate after any wiring change with `uv run python tools/generate_ipo.py`". Change the build, regenerate, the design updates — they are never out of sync.
218
219
Here is one clean event row — `band_of`, the band highlight you saw on the Grade tab:
220
221
| Event (trigger) | Input | Process | Output |
222
| --- | --- | --- | --- |
223
| Indicator score → change ×4 | Indicator score | `band_of` — Which rubric band a score falls in. | Band |
224
225
The big `refresh` row — the one fired by changing student or criterion — has an Output column listing every component on every tab (`Grade 1, Grade 2, … Cohort summary`). It is auto-generated and gloriously long, so it is not reproduced here. Read it in the [full ipo-charts.md on GitHub](https://github.com/vce-soft-dev/SD26-Students/blob/main/Proj-SAT-Grader-UI/C05/ipo-charts.md); its length is a feature, not a flaw — it is the machine listing every output one reload must refresh.
226
227
> **Your design log:** the `refresh` row has a huge Output column but a tiny Input column (just Name, Criteria). Why does one small input produce so many outputs? (What does "reload every tab" have to do with NFR1, "fresh reads, no caches"?)
228
229
### Pseudocode ← FR5 + corrections 06/07
230
231
FR5 quoted exactly:
232
233
> The app **displays an AI-suggested score + evidence** when present in the markdown (produced externally — see §6). The app is read-only toward these fields.
234
235
The app *shows* the AI score; it never trusts it blindly. Deciding the **final** score is a human job, and the pseudocode has two algorithms precisely to make that split explicit. Algorithm 1 (above) is automated. **Algorithm 2 is a teacher procedure the app deliberately never automates.** Design note 1, quoted exactly:
236
237
> **The final score is never computed** — Algorithm 2 contains teacher decisions ("teacher's choice", "teacher's judgement") by design. The app automates the references, not the judgement.
238
239
The reconcile view is Algorithm 2 on screen:
240
241
![The SAT grader Score tab for Cohen, criterion C03, showing the reconcile view. Section 1, "Calculated score (from Grade tab x weightings)", lists SRS Document 8 x 60% and Critical Thinking 7 x 40%, then "= 7.6, rounded half-up -> Calculated criterion score: 8". Section 2, "AI suggested score", shows 8 with its justification. Section 3, "Reconcile - final criterion score", shows a Final score field of 8 and a Reconciliation note "AI (8) matches calculated (8) - confirmed.", above an orange "Save final score" button. Below, an "All criteria for this student" table has Calculated, AI and Final columns; the C03 row reads 8, 8, 8 and the C04 row reads 7, 7 with Final blank.](From%20SRS%20to%20Detailed%20Designs%20-%20Data%20and%20Logic/correction-06-after-score-reconcile.png)
242
243
Three reference scores are shown side by side — Calculated (8), AI (8), and a place for the cross-mark — and the teacher types the **Final** and a note. The app presents; the human decides. Algorithm 2's decision structure, quoted from the pseudocode:
244
245
```
246
IF references = {calculated} THEN // no second opinion available
247
final ← calculated
248
ELSE IF Max(references) − Min(references) = 0 THEN
249
final ← calculated // unanimous
250
ELSE IF Max(references) − Min(references) ≤ 1 THEN
251
final ← teacher's choice IN [Min(references), Max(references)]
252
ELSE
253
// Major disagreement (gap ≥ 2): do not split the difference.
254
final ← teacher's judgement after review
255
END IF
256
```
257
258
On screen, Calculated 8 and AI 8 agree — the `Max − Min = 0` branch — so the note reads "AI (8) matches calculated (8) — confirmed."
259
260
> **Your design log:** the last branch forbids "split the difference" when references disagree by 2 or more. Quote design note 3 and explain what a gap of 2 is taken to *mean* about the evidence.
261
262
### Object descriptions ← the problem domain
263
5eef4a lisa 2026-06-11 08:14:51
Tool 2: add Student + CriterionGrade class boxes; pre-render class diagrams to PNG OtterWiki's bundled mermaid renders classDiagram poorly, so both diagrams are now rendered locally with mermaid-cli 11 and embedded as images. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
264
The object descriptions model the **problem domain** — the classes you would design *before* choosing an implementation style. (The real app is built function-over-data, not from these classes; more on that below.) The full class diagram, rendered from the artefact's mermaid source:
2ebc08 lisa 2026-06-11 07:46:24
Add C05 page: From SRS to Detailed Designs — Data and Logic Traces one SRS sentence ('computed, never stored') through all four C05-1 data/logic tools — data dictionary, IPO charts, pseudocode, object descriptions — using the real SAT-grader project as a worked example with faded guidance. Sibling of the Mock-ups page; links added both ways and from C05-home. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
265
5eef4a lisa 2026-06-11 08:14:51
Tool 2: add Student + CriterionGrade class boxes; pre-render class diagrams to PNG OtterWiki's bundled mermaid renders classDiagram poorly, so both diagrams are now rendered locally with mermaid-cli 11 and embedded as images. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
266
![UML class diagram of the whole problem domain. GradeBook at the top, connected by an open diamond labelled "loads / saves" to Student (multiplicity 1 to 0..*). Student connects by a filled diamond labelled "grades" to CriterionGrade (1 to 0..10). CriterionGrade has a plain arrow labelled "graded against" to Criterion (0..* to 1) and a filled diamond labelled "evidence" to IndicatorEvidence (1 to 2..4). Criterion connects by a filled diamond labelled "assessed by" to Indicator (1 to 2..4), and Indicator has a dashed arrow labelled "maps scores to" pointing at Band, an enumeration of the five values VERY_LOW_1_2 through VERY_HIGH_9_10.](From%20SRS%20to%20Detailed%20Designs%20-%20Data%20and%20Logic/class-diagram-full.png)
2ebc08 lisa 2026-06-11 07:46:24
Add C05 page: From SRS to Detailed Designs — Data and Logic Traces one SRS sentence ('computed, never stored') through all four C05-1 data/logic tools — data dictionary, IPO charts, pseudocode, object descriptions — using the real SAT-grader project as a worked example with faded guidance. Sibling of the Mock-ups page; links added both ways and from C05-home. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
267
268
Notice the line shapes. Teaching point 1, quoted exactly:
269
270
> **Composition vs association** — a `Student` *owns* their `CriterionGrade`s (delete the student, the grades go too: filled diamond), but a grade merely *refers to* its `Criterion` — the rubric exists independently and is shared by every student (arrow, not diamond).
271
272
So `Student *-- CriterionGrade` is a filled diamond (composition: the grades belong to that student and die with them), while `CriterionGrade --> Criterion` is a plain arrow (association: the rubric is shared, not owned). The diamond is not decoration — it encodes who owns what.
273
274
> **Class discussion** — the app's author chose to *not* build these classes, using dicts and pure functions instead. From the artefact:
275
>
276
> > the implementation chose dicts + pure functions over these classes. What did that trade away (encapsulation, invariants living next to the data) and what did it buy (markdown round-tripping is trivial, functions are easy to unit test, no object/file mapping layer)? Both are valid detailed designs; the object description is how you *communicate* the domain either way.
277
278
---
279
280
## Your turn — trace `validation_gap` through three tools
281
282
You have seen "computed, never stored" appear in four tools. Now trace a different idea **yourself**. The anti-AI-cheating check — *the standard observed in class was not reproduced under assessment conditions* — lives, like that sentence, in three artefacts at once:
283
284
1. **Pseudocode**, as the guard at the top of Algorithm 2: a `FOR EACH indicator` loop that flags `REVIEW` when `HighestBand(indicator.validation) < HighestBand(indicator.observation)` — in [pseudocode-final-score.md](https://github.com/vce-soft-dev/SD26-Students/blob/main/Proj-SAT-Grader-UI/C05/pseudocode-final-score.md).
285
2. **Object descriptions**, as the method `validation_gap()` on `IndicatorEvidence` — in [object-descriptions.md](https://github.com/vce-soft-dev/SD26-Students/blob/main/Proj-SAT-Grader-UI/C05/object-descriptions.md).
286
3. **Data dictionary**, as the two evidence fields it compares: `…evidence[i].observation` and `…evidence[i].validation` — in [data-dictionary.md](https://github.com/vce-soft-dev/SD26-Students/blob/main/Proj-SAT-Grader-UI/C05/data-dictionary.md).
287
288
Open all three and answer in your design log:
289
290
1. The pseudocode guard and the `validation_gap()` method describe the *same* comparison. Quote the condition from each and show they are the same test written two ways.
291
2. The data dictionary says `validation` is "Evidence under assessment conditions (no AI / outside help); confirms the judgement." Why does a *lower* validation band than observation band suggest a problem worth reviewing?
292
3. Is `validation_gap` a **stored** value or a **derived** one? Which tool would you cite to justify your answer, and how does that connect back to "computed, never stored"?
293
294
---
295
296
## The real files
297
298
Open these on GitHub and read the originals. Each is the artefact a section above quotes.
299
300
| Artefact | Link |
301
| --- | --- |
302
| SRS (FR/NFR tables, §7 data model, MoSCoW scope) | [SRS/SRS.md](https://github.com/vce-soft-dev/SD26-Students/blob/main/Proj-SAT-Grader-UI/SRS/SRS.md) |
303
| Data dictionary (stored §4, derived §5) | [C05/data-dictionary.md](https://github.com/vce-soft-dev/SD26-Students/blob/main/Proj-SAT-Grader-UI/C05/data-dictionary.md) |
304
| IPO charts (system-level + generated event rows) | [C05/ipo-charts.md](https://github.com/vce-soft-dev/SD26-Students/blob/main/Proj-SAT-Grader-UI/C05/ipo-charts.md) |
305
| Pseudocode (Algorithm 1 automated, Algorithm 2 teacher procedure) | [C05/pseudocode-final-score.md](https://github.com/vce-soft-dev/SD26-Students/blob/main/Proj-SAT-Grader-UI/C05/pseudocode-final-score.md) |
306
| Object descriptions (class diagram + teaching points) | [C05/object-descriptions.md](https://github.com/vce-soft-dev/SD26-Students/blob/main/Proj-SAT-Grader-UI/C05/object-descriptions.md) |
307
308
> [!NOTE]
309
> The `SD26-Students` repository is **private**. To open these links you must be signed in to GitHub with your class account. If you get a 404, you are not signed in — log in and try again.
310
311
---
312
313
## Check Your Understanding
314
315
1. One SRS sentence appears in all four design tools. Quote it, then name the **form** it takes in each tool: the data dictionary, the object descriptions, the pseudocode, and the IPO charts.
316
317
>| The sentence is SRS §7: "Derived values (bands, calculated scores, totals, ranks) are computed, never stored." In the **data dictionary** it is a separate §5 "Derived values (computed, never stored)" table. In the **object descriptions** it is the attribute-vs-method split — `final` is a stored attribute, `calculated()` is a derived method. In the **pseudocode** it is Algorithm 1, which derives the calculated score from inputs every time. In the **IPO charts** it is the `live_summary` / `band_of` rows that recompute on every keystroke — only possible because the values are never stored.
318
319
2. Why is `final` an **attribute** but `calculated()` a **method**?
320
321
>| `final` is the teacher's reconciled decision — a value you *store*, because it cannot be re-derived from anything (it is a judgement). `calculated()` is a weighted average of the indicator scores — a value you *derive on demand* from inputs that already exist, so storing it would break "computed, never stored". Attribute = stored input; method = derived output.
322
323
3. Algorithm 2 contains the words "teacher's judgement" instead of a formula. Why is that a deliberate design decision, not a missing piece of the algorithm?
324
325
>| Design note 1 says so: "The final score is never computed … the app automates the references, not the judgement." FR5 makes the app read-only toward the AI score, and reconciling calculated vs AI vs cross-mark is a moderation decision a human must own. Replacing the judgement with a formula (e.g. averaging) would make the app decide grades — and design note 3 explicitly forbids averaging across a disagreement of 2 or more, because a large gap signals mis-banded evidence to re-examine, not a number to split.
326
327
4. What makes the IPO charts unable to drift apart from the build?
328
329
>| They are **generated from the app's own event wiring** by `tools/generate_ipo.py` — each chart is read straight out of the Gradio `trigger.change(process, [inputs], [outputs])` handlers. The build *is* the source of the chart, so you regenerate after any wiring change (`uv run python tools/generate_ipo.py`) and the design updates with it. A hand-written chart can fall out of date; a generated one cannot.
330
331
---
332
333
## See also
334
335
- [From SRS to Detailed Designs — Mock-ups](From%20SRS%20to%20Detailed%20Designs%20-%20Mock-ups) — the sibling page: traces a *screen* (FR3, FR9, FR6) from SRS → wireframe → build → correction, where this page traces the *data and logic*.
336
- [Data Dictionary](Data%20Dictionary) — teaches the data-dictionary tool in general (headings, why "format" is not "type"); this page shows it working with the other three on a real project.
337
- [IPO Charts - Process Means Steps](IPO%20Charts%20-%20Process%20Means%20Steps) — teaches the IPO tool in general (Process = numbered steps); this page shows a generated IPO chart in context.
338
- [VCAA Pseudocode Not Python](VCAA%20Pseudocode%20Not%20Python) — teaches language-independent pseudocode in general; this page shows two real algorithms doing the work.
339
- [Object Descriptions and Class Diagrams](Object%20Descriptions%20and%20Class%20Diagrams) — teaches the object-description tool in general (attributes, methods, reading a class diagram); this page shows a real class diagram tied to the data rule.
340
341
---
342
343
← Back to [C05 Home](/sd/C05/C05-home) · [VCE Software Development Hub](/sd/VCE%20Software%20Development%20Hub)