MIL-003: wiki in three languages #21
No files matched your search
@@ -16,7 +16,7 @@ document of a type. `Primary File` may contain a glob (e.g.
|
||||
| PP | Project Plan | docs/project-plan.md | 002 |
|
||||
| MIL | Milestone / Gateway | docs/milestones/mil-*.md | 004 |
|
||||
| TM | Traceability Matrix | docs/sqa/traceability-matrix.md | 002 |
|
||||
| RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 008 |
|
||||
| RC | SQA Review Record | docs/sqa/reviews/rc-*.md | 009 |
|
||||
| ADR | Architecture Decision Record | docs/adr/adr-*.md | 0002 |
|
||||
|
||||
## Languages
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
# SQA Review Record
|
||||
|
||||
## Metadata
|
||||
| Key | Value |
|
||||
| --- | --- |
|
||||
| ID | RC-008 |
|
||||
| CrossReference | [MIL-003], [QC-WIKI-001] |
|
||||
|
||||
## Version History
|
||||
| Date | Status | Author | Reviewer | Change | Commit |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 2026-11-06 | Proposed | Jens Tirsvad Nielsen | AI as stand-in for S01 | Initial version | [0227b10] |
|
||||
|
||||
---
|
||||
|
||||
## Artifact Under Review
|
||||
|
||||
- Instance reviewed: [MIL-003] deliverable, the wiki in `docs/wiki/` (18 pages and `_Sidebar.md`)
|
||||
- Checklist used: [QC-WIKI-001] (`framework/qc/docs/wiki/` holds the framework's own wiki, not a checklist, so no second checklist applies)
|
||||
- Scope: full review, 1 round, no defects found. Page content in Danish and Bahasa Malaysia was read for translation quality (the language checks of QC-LANG-001 apply to the page text); no language reviewer other than the stand-in
|
||||
- Language and domain: en, da, ms / it (wiki pages)
|
||||
- Language reviewer: none (the stand-in reads the three languages; `S01` confirmed the language checks for MIL-003 in RC-005)
|
||||
- Mode: autonomous, not independent (reviewer `AI as stand-in for S01`)
|
||||
|
||||
Checks were run with a script that compares the pages: fenced code blocks, inline code spans and image URLs of each `-da` and `-ms` page against English (all identical), the language line of all 18 pages against the expected text, and every internal link against the files in the folder.
|
||||
|
||||
## Checklist Results
|
||||
|
||||
| # | Criterion | Status | Evidence/Notes |
|
||||
| --- | --- | --- | --- |
|
||||
| 1 | `_Sidebar.md` exists | Pass | Present |
|
||||
| 2 | Bold title, then one English list, `Home` first | Pass | `**Speed Calc Decorator**`, then Home, Setup, Steps 1 to 4 |
|
||||
| 3 | List links every English page, no dead link | Pass | 6 links, 6 English pages, all targets exist |
|
||||
| 4 | `Related` only when related wikis exist | Pass | No related wikis; no such section |
|
||||
| 5 | `Languages` last, one line per language in its language, linking to Home | Pass | `English: [Home](Home)`, `Dansk: [Hjem](Home-da)`, `Bahasa Malaysia: [Utama](Home-ms)` |
|
||||
| 6 | List not repeated per language | Pass | Listed once |
|
||||
| 7 | Generated sidebar carries a generator comment | N-A | Written by hand, not generated |
|
||||
| 8 | `Languages` line on each page (Optional) | Pass | See criterion 11 |
|
||||
| 9 | English plus the PO language | Pass | English, Danish and Bahasa Malaysia; the Business Case names da and ms |
|
||||
| 10 | Page sets identical | Pass | 6 pages x 3 languages |
|
||||
| 11 | Language line on every page, current language bold, links to same page | Pass | 18 of 18 match the expected line; targets exist |
|
||||
| 12 | Naming `<Page>-<code>.md`, English unsuffixed | Pass | `-da`, `-ms` suffixes, BCP 47 |
|
||||
| 13 | Code, commands, file names, IDs stay English | Pass | Code blocks, inline code spans and image URLs identical to English in all 12 translations. Code comments such as `# seconds since Jan 1st, 1970` stay English as code |
|
||||
| 14 | Checked on the published wiki after the change | Pending | Cannot be done before merge and publication; checked after publication |
|
||||
| 15 | Layout change made in generator and checklist (Optional) | N-A | No layout rule changed |
|
||||
| 16 | Folder flat | Pass | All 19 files directly in `docs/wiki/`, no subfolder |
|
||||
|
||||
Further findings:
|
||||
|
||||
- Internal links: every non-external link in all pages points to an existing file in the same language (content links keep the language suffix; only the language line crosses languages, as intended).
|
||||
- Screenshots: the 4 image URLs (`raw/branch/main/docs/screenshots/...`) are the same in all languages and the 4 files exist in `docs/screenshots/`. The URLs resolve only after merge to `main`, which is part of criterion 14.
|
||||
- Danish and Bahasa Malaysia read correctly and idiomatically; technical terms (decorator, closure, wrapper, float) are used consistently, and "What we gained" is rendered as "Hvad vi lærte" and "Apa yang kita peroleh". No errors found, nothing edited.
|
||||
|
||||
## MIL-003 Go criteria (verdict part excluded)
|
||||
|
||||
| # | Criterion | Status | Evidence |
|
||||
| --- | --- | --- | --- |
|
||||
| 1 | Flat; each English page has `-da` and `-ms` | Pass | Criteria 10 and 16 |
|
||||
| 2 | Each page starts with the language switch line | Pass | Criterion 11; the line follows the title heading, as in the checklist example |
|
||||
| 3 | Each step page shows its screenshot and a "What we gained" section | Pass | Steps 1 to 4 in all three languages have an image and the section (also `Setup`) |
|
||||
| 4 | Sidebar shape | Pass | Criteria 2 to 6 |
|
||||
| 5 | Review against QC-WIKI-001 is a Go | Pending | This record; see the verdict |
|
||||
|
||||
## Overall Verdict
|
||||
|
||||
Go-with-conditions. All Mandatory criteria that can be checked in the repository pass and no defect was found. Criterion 14 is `Pending` because the published wiki exists only after the merge, so the verdict is Go-with-conditions at most. The status of this record and of MIL-003 criterion 5 is settled when criterion 14 is checked after publication.
|
||||
|
||||
## Action Items
|
||||
|
||||
| Action | Owner | Due |
|
||||
| --- | --- | --- |
|
||||
| After the merge and publication, open the published wiki and check the sidebar, every page, every link and the four screenshots (criterion 14); then re-review criterion 14 and close the conditions | S01 | 2026-11-09 |
|
||||
|
||||
---
|
||||
|
||||
[MIL-003]: ../../milestones/mil-003-wiki-and-screenshots.md
|
||||
[QC-WIKI-001]: ../../../framework/qc/artifacts/qc-wiki.md
|
||||
[0227b10]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/054-speed-calc-decorator/commit/0227b109d9b4031b137f6c1e7833ccbb8fd54f06
|
||||
@@ -1,90 +1,92 @@
|
||||
# Traceability Matrix
|
||||
|
||||
## Metadata
|
||||
| Key | Value |
|
||||
| --- | --- |
|
||||
| ID | TM-001 |
|
||||
| CrossReference | [BC-001], [SA-001] |
|
||||
|
||||
## Version History
|
||||
| Date | Status | Author | Reviewer | Change | Commit |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 2026-11-06 | Proposed | Jens Tirsvad Nielsen | S01 | Initial version: BC, SA, PP, MIL-001 to MIL-003 and RC-001 to RC-005 | [a07d05b] |
|
||||
|
||||
---
|
||||
|
||||
## Purpose
|
||||
|
||||
Tracks backward/forward links between artifact instances so that the Business Case's
|
||||
cross-artifact traceability success criterion is measurable. A row is added or
|
||||
updated whenever an artifact instance is created or reviewed.
|
||||
|
||||
## Traceability Table
|
||||
|
||||
| Artifact Instance | Type | Language | Domain | Upstream (Backward Link) | Downstream (Forward Link) | Last Reviewed (RC-ID) |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| [SA-001] | Stakeholder Analysis | en | it | - | [BC-001], [PP-001] | [RC-002] (Go) |
|
||||
| [BC-001] | Business Case | en | it | [SA-001] | [PP-001], [MIL-001], [MIL-002], [MIL-003] | [RC-001] (Go) |
|
||||
| [PP-001] | Project Plan | en | it | [BC-001], [SA-001] | [MIL-001], [MIL-002], [MIL-003] | - (no review gate; accepted by S01 through the accepted plan) |
|
||||
| [MIL-001] | Milestone / Gateway | en | it | [BC-001], [PP-001] | [MIL-002]; source code is not built yet; ADR-0001 is written | [RC-003] (Go) |
|
||||
| [MIL-002] | Milestone / Gateway | en | it | [BC-001], [PP-001], [MIL-001] | [MIL-003]; Python source and tests (reviewed in RC-007) | [RC-004] (Go) |
|
||||
| [MIL-003] | Milestone / Gateway | en | it | [BC-001], [PP-001], [MIL-002] | - | [RC-005] (Go) |
|
||||
| [ADR-0001] | Architecture Decision Record | n/a | n/a | [BC-001], [PP-001] | source code and tests are not built yet | [RC-006] (Go) |
|
||||
| [RC-001] | SQA Review Record | - | - | [BC-001] | - | - |
|
||||
| [RC-002] | SQA Review Record | - | - | [SA-001] | - | - |
|
||||
| [RC-003] | SQA Review Record | - | - | [MIL-001] | - | - |
|
||||
| [RC-004] | SQA Review Record | - | - | [MIL-002] | - | - |
|
||||
| [RC-005] | SQA Review Record | - | - | [MIL-003] | - | - |
|
||||
| [RC-006] | SQA Review Record | - | - | [ADR-0001] | - | - |
|
||||
| [RC-007] | SQA Review Record | - | - | [MIL-002] | - | - |
|
||||
|
||||
## Concern Coverage
|
||||
|
||||
No view (architecture, design or use case artifact) exists yet, and none is planned
|
||||
before the milestones: the exercise is one function and the reason for skipping
|
||||
user stories and use cases is recorded in ADR-0001, a task of [MIL-001]
|
||||
(accepted). Each concern is delivered by a milestone Go criterion; that is
|
||||
noted in the first column. There is no Architecture Description, so the gaps
|
||||
are not listed there.
|
||||
|
||||
| Concern (CN-ID) | Views that answer it | Decisions (ADR) | Quality check (TP) | Status |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| CN-001 | none; delivered by [MIL-002] Go criteria 1 and 2 | none (ADR-0001 does not address it) | none | Gap |
|
||||
| CN-002 | none; delivered by [MIL-002] Go criterion 1 | none (ADR-0001 does not address it) | none | Gap |
|
||||
| CN-003 | none; delivered by [MIL-003] Go criteria 1 to 3 | none (ADR-0001 does not address it) | none | Gap |
|
||||
| CN-004 | none; delivered by [MIL-002] Go criterion 3 | none (ADR-0001 does not address it) | none | Gap |
|
||||
| CN-005 | none; delivered by [MIL-001] Go criterion 3 | none (ADR-0001 does not address it) | none | Gap |
|
||||
| CN-006 | none; delivered by [MIL-001] Go criteria 3 and 5 | none (ADR-0001 does not address it) | none | Gap |
|
||||
| CN-007 | none; delivered by [MIL-001] Go criterion 1 and [MIL-002] Go criterion 6 | none (ADR-0001 does not address it) | none | Gap |
|
||||
|
||||
## Open Inconsistencies
|
||||
|
||||
| # | Views | Inconsistency | Found in (RC-ID) | Status | Resolved in |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 1 | [SA-001], [BC-001] | CN-007 (no runtime dependencies) was traced to Business Case objective 3 (venv and run instructions), which does not cover it | [RC-002] | Closed | [SA-001] version of 2026-11-06 |
|
||||
| 2 | [BC-001] | The constraint "No runtime dependencies unless needed" contradicted success criterion 3 (0 runtime dependencies) | [RC-001] | Closed | [BC-001] version of 2026-11-06 |
|
||||
| 3 | [PP-001], [MIL-002] | The plan placed `constants.py` at [MIL-001], while [MIL-002] task 1 creates it | informal review of [PP-001] (no RC) | Closed | [PP-001] version of 2026-11-06 |
|
||||
|
||||
## Coverage Notes
|
||||
|
||||
- Types with no instance yet: KPI, BMC, BPMN, UCD, US, UC, DM, SSD, OC, SD, DCD, ERD, TP, AD, GOV, DICT. User stories and use cases are skipped on purpose (recorded in [ADR-0001]); GOV and DICT are not in the plan, which leaves QC-LANG-001 criterion 5 without a dictionary to check against.
|
||||
- `-` in Upstream means foundational; in Downstream, nothing is built on it yet; in Last Reviewed, no `RC-*` exists yet.
|
||||
- All five reviews are `Mode: autonomous, not independent` and `Go`: S01 confirmed criteria 3, 5 and 9 of QC-LANG-001 as a person in chat on 2026-11-06, so BC-001, SA-001 and MIL-001 to MIL-003 are `Accepted`.
|
||||
|
||||
---
|
||||
|
||||
[BC-001]: ../business-case.md
|
||||
[SA-001]: ../stakeholder-analysis.md
|
||||
[PP-001]: ../project-plan.md
|
||||
[MIL-001]: ../milestones/mil-001-project-baseline.md
|
||||
[MIL-002]: ../milestones/mil-002-speed-calc-decorator.md
|
||||
[MIL-003]: ../milestones/mil-003-wiki-and-screenshots.md
|
||||
[RC-001]: ./reviews/rc-001-business-case.md
|
||||
[RC-002]: ./reviews/rc-002-stakeholder-analysis.md
|
||||
[RC-003]: ./reviews/rc-003-mil-001-project-baseline.md
|
||||
[RC-004]: ./reviews/rc-004-mil-002-speed-calc-decorator.md
|
||||
[RC-005]: ./reviews/rc-005-mil-003-wiki.md
|
||||
[RC-006]: ./reviews/rc-006-adr-0001.md
|
||||
[RC-007]: ./reviews/rc-007-python-source-mil-002.md
|
||||
[ADR-0001]: ../adr/adr-0001-skip-stories-plain-package.md
|
||||
[a07d05b]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/054-speed-calc-decorator/commit/a07d05b385e6b831b90731aefe08f078ebb951ca
|
||||
# Traceability Matrix
|
||||
|
||||
## Metadata
|
||||
| Key | Value |
|
||||
| --- | --- |
|
||||
| ID | TM-001 |
|
||||
| CrossReference | [BC-001], [SA-001] |
|
||||
|
||||
## Version History
|
||||
| Date | Status | Author | Reviewer | Change | Commit |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 2026-11-06 | Proposed | Jens Tirsvad Nielsen | S01 | Initial version: BC, SA, PP, MIL-001 to MIL-003 and RC-001 to RC-005 | [a07d05b] |
|
||||
|
||||
---
|
||||
|
||||
## Purpose
|
||||
|
||||
Tracks backward/forward links between artifact instances so that the Business Case's
|
||||
cross-artifact traceability success criterion is measurable. A row is added or
|
||||
updated whenever an artifact instance is created or reviewed.
|
||||
|
||||
## Traceability Table
|
||||
|
||||
| Artifact Instance | Type | Language | Domain | Upstream (Backward Link) | Downstream (Forward Link) | Last Reviewed (RC-ID) |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| [SA-001] | Stakeholder Analysis | en | it | - | [BC-001], [PP-001] | [RC-002] (Go) |
|
||||
| [BC-001] | Business Case | en | it | [SA-001] | [PP-001], [MIL-001], [MIL-002], [MIL-003] | [RC-001] (Go) |
|
||||
| [PP-001] | Project Plan | en | it | [BC-001], [SA-001] | [MIL-001], [MIL-002], [MIL-003] | - (no review gate; accepted by S01 through the accepted plan) |
|
||||
| [MIL-001] | Milestone / Gateway | en | it | [BC-001], [PP-001] | [MIL-002]; source code is not built yet; ADR-0001 is written | [RC-003] (Go) |
|
||||
| [MIL-002] | Milestone / Gateway | en | it | [BC-001], [PP-001], [MIL-001] | [MIL-003]; Python source and tests (reviewed in RC-007) | [RC-004] (Go) |
|
||||
| [MIL-003] | Milestone / Gateway | en | it | [BC-001], [PP-001], [MIL-002] | - | [RC-005] (Go), [RC-008] (Go-with-conditions, wiki) |
|
||||
| [ADR-0001] | Architecture Decision Record | n/a | n/a | [BC-001], [PP-001] | source code and tests are not built yet | [RC-006] (Go) |
|
||||
| [RC-001] | SQA Review Record | - | - | [BC-001] | - | - |
|
||||
| [RC-002] | SQA Review Record | - | - | [SA-001] | - | - |
|
||||
| [RC-003] | SQA Review Record | - | - | [MIL-001] | - | - |
|
||||
| [RC-004] | SQA Review Record | - | - | [MIL-002] | - | - |
|
||||
| [RC-005] | SQA Review Record | - | - | [MIL-003] | - | - |
|
||||
| [RC-006] | SQA Review Record | - | - | [ADR-0001] | - | - |
|
||||
| [RC-007] | SQA Review Record | - | - | [MIL-002] | - | - |
|
||||
| [RC-008] | SQA Review Record | - | - | [MIL-003] | - | - |
|
||||
|
||||
## Concern Coverage
|
||||
|
||||
No view (architecture, design or use case artifact) exists yet, and none is planned
|
||||
before the milestones: the exercise is one function and the reason for skipping
|
||||
user stories and use cases is recorded in ADR-0001, a task of [MIL-001]
|
||||
(accepted). Each concern is delivered by a milestone Go criterion; that is
|
||||
noted in the first column. There is no Architecture Description, so the gaps
|
||||
are not listed there.
|
||||
|
||||
| Concern (CN-ID) | Views that answer it | Decisions (ADR) | Quality check (TP) | Status |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| CN-001 | none; delivered by [MIL-002] Go criteria 1 and 2 | none (ADR-0001 does not address it) | none | Gap |
|
||||
| CN-002 | none; delivered by [MIL-002] Go criterion 1 | none (ADR-0001 does not address it) | none | Gap |
|
||||
| CN-003 | none; delivered by [MIL-003] Go criteria 1 to 3 | none (ADR-0001 does not address it) | none | Gap |
|
||||
| CN-004 | none; delivered by [MIL-002] Go criterion 3 | none (ADR-0001 does not address it) | none | Gap |
|
||||
| CN-005 | none; delivered by [MIL-001] Go criterion 3 | none (ADR-0001 does not address it) | none | Gap |
|
||||
| CN-006 | none; delivered by [MIL-001] Go criteria 3 and 5 | none (ADR-0001 does not address it) | none | Gap |
|
||||
| CN-007 | none; delivered by [MIL-001] Go criterion 1 and [MIL-002] Go criterion 6 | none (ADR-0001 does not address it) | none | Gap |
|
||||
|
||||
## Open Inconsistencies
|
||||
|
||||
| # | Views | Inconsistency | Found in (RC-ID) | Status | Resolved in |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 1 | [SA-001], [BC-001] | CN-007 (no runtime dependencies) was traced to Business Case objective 3 (venv and run instructions), which does not cover it | [RC-002] | Closed | [SA-001] version of 2026-11-06 |
|
||||
| 2 | [BC-001] | The constraint "No runtime dependencies unless needed" contradicted success criterion 3 (0 runtime dependencies) | [RC-001] | Closed | [BC-001] version of 2026-11-06 |
|
||||
| 3 | [PP-001], [MIL-002] | The plan placed `constants.py` at [MIL-001], while [MIL-002] task 1 creates it | informal review of [PP-001] (no RC) | Closed | [PP-001] version of 2026-11-06 |
|
||||
|
||||
## Coverage Notes
|
||||
|
||||
- Types with no instance yet: KPI, BMC, BPMN, UCD, US, UC, DM, SSD, OC, SD, DCD, ERD, TP, AD, GOV, DICT. User stories and use cases are skipped on purpose (recorded in [ADR-0001]); GOV and DICT are not in the plan, which leaves QC-LANG-001 criterion 5 without a dictionary to check against.
|
||||
- `-` in Upstream means foundational; in Downstream, nothing is built on it yet; in Last Reviewed, no `RC-*` exists yet.
|
||||
- All five reviews are `Mode: autonomous, not independent` and `Go`: S01 confirmed criteria 3, 5 and 9 of QC-LANG-001 as a person in chat on 2026-11-06, so BC-001, SA-001 and MIL-001 to MIL-003 are `Accepted`.
|
||||
|
||||
---
|
||||
|
||||
[BC-001]: ../business-case.md
|
||||
[SA-001]: ../stakeholder-analysis.md
|
||||
[PP-001]: ../project-plan.md
|
||||
[MIL-001]: ../milestones/mil-001-project-baseline.md
|
||||
[MIL-002]: ../milestones/mil-002-speed-calc-decorator.md
|
||||
[MIL-003]: ../milestones/mil-003-wiki-and-screenshots.md
|
||||
[RC-001]: ./reviews/rc-001-business-case.md
|
||||
[RC-002]: ./reviews/rc-002-stakeholder-analysis.md
|
||||
[RC-003]: ./reviews/rc-003-mil-001-project-baseline.md
|
||||
[RC-004]: ./reviews/rc-004-mil-002-speed-calc-decorator.md
|
||||
[RC-005]: ./reviews/rc-005-mil-003-wiki.md
|
||||
[RC-006]: ./reviews/rc-006-adr-0001.md
|
||||
[RC-007]: ./reviews/rc-007-python-source-mil-002.md
|
||||
[RC-008]: ./reviews/rc-008-wiki-mil-003.md
|
||||
[ADR-0001]: ../adr/adr-0001-skip-stories-plain-package.md
|
||||
[a07d05b]: https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/054-speed-calc-decorator/commit/a07d05b385e6b831b90731aefe08f078ebb951ca
|
||||
@@ -0,0 +1,21 @@
|
||||
# Speed Calc Decorator
|
||||
|
||||
[English](Home) · **Dansk** · [Bahasa Malaysia](Home-ms)
|
||||
|
||||
En Python-dekorator, der måler, hvor mange sekunder en funktion er om at køre. Den er løsningen på en øvelse fra Udemy-kurset *100 Days of Code: The Complete Python Pro Bootcamp*. Denne wiki forklarer, hvad hvert trin i lektionen lærte. [README](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/054-speed-calc-decorator) er den korte version.
|
||||
|
||||
Det forventede output fra det færdige program har denne form (tallene er forskellige på hver maskine):
|
||||
|
||||
```text
|
||||
1695050908.1985211
|
||||
fast_function run speed: 0.33974480628967285s
|
||||
slow_function run speed: 2.9590742588043213s
|
||||
```
|
||||
|
||||
| Side | Læs den, når du vil |
|
||||
| --- | --- |
|
||||
| [Opsætning](Setup-da) | Oprette en lokal `.venv`, køre programmet og køre testene |
|
||||
| [Trin 1: det aktuelle tidspunkt](Step-1-Current-Time-da) | Lære, hvad `time.time()` returnerer, og hvordan man måler en varighed |
|
||||
| [Trin 2: dekoratorens skelet](Step-2-Decorator-Skeleton-da) | Lære, hvad en dekorator er, og hvorfor `functools.wraps` er vigtig |
|
||||
| [Trin 3: tidtagnings-wrapperen](Step-3-Timing-Wrapper-da) | Se, hvordan wrapperen tager tid på kaldet, og hvordan testene undgår rigtig tid |
|
||||
| [Trin 4: hurtig mod langsom](Step-4-Fast-vs-Slow-da) | Samle det hele og læse resultatet |
|
||||
@@ -0,0 +1,21 @@
|
||||
# Speed Calc Decorator
|
||||
|
||||
[English](Home) · [Dansk](Home-da) · **Bahasa Malaysia**
|
||||
|
||||
Sebuah decorator Python yang mengukur berapa saat sesebuah fungsi mengambil masa untuk dijalankan. Ia ialah penyelesaian bagi latihan kuliah dalam *100 Days of Code: The Complete Python Pro Bootcamp* di Udemy. Wiki ini menerangkan apa yang diajar oleh setiap langkah kuliah. [README](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/054-speed-calc-decorator) ialah versi ringkasnya.
|
||||
|
||||
Output yang dijangka bagi program yang siap mempunyai bentuk berikut (nombornya berbeza pada setiap mesin):
|
||||
|
||||
```text
|
||||
1695050908.1985211
|
||||
fast_function run speed: 0.33974480628967285s
|
||||
slow_function run speed: 2.9590742588043213s
|
||||
```
|
||||
|
||||
| Halaman | Baca apabila anda ingin |
|
||||
| --- | --- |
|
||||
| [Persediaan](Setup-ms) | Mencipta `.venv` setempat, menjalankan program dan menjalankan ujian |
|
||||
| [Langkah 1: masa semasa](Step-1-Current-Time-ms) | Memahami apa yang dipulangkan oleh `time.time()` dan cara mengukur tempoh |
|
||||
| [Langkah 2: rangka decorator](Step-2-Decorator-Skeleton-ms) | Memahami apa itu decorator dan mengapa `functools.wraps` penting |
|
||||
| [Langkah 3: pembungkus pemasaan](Step-3-Timing-Wrapper-ms) | Melihat bagaimana pembungkus mengukur masa panggilan dan bagaimana ujian mengelak masa sebenar |
|
||||
| [Langkah 4: pantas lawan perlahan](Step-4-Fast-vs-Slow-ms) | Menggabungkan semuanya dan membaca hasilnya |
|
||||
@@ -0,0 +1,21 @@
|
||||
# Speed Calc Decorator
|
||||
|
||||
**English** · [Dansk](Home-da) · [Bahasa Malaysia](Home-ms)
|
||||
|
||||
A Python decorator that measures how many seconds a function takes to run. It is the solution to a lecture exercise of Udemy's *100 Days of Code: The Complete Python Pro Bootcamp*. This wiki explains what each lecture step taught. The [README](https://git.tirsystem.com/Tirsvad-Udemy-100-days-of-code/054-speed-calc-decorator) is the short version.
|
||||
|
||||
The expected output of the finished program has this shape (the numbers differ on every machine):
|
||||
|
||||
```text
|
||||
1695050908.1985211
|
||||
fast_function run speed: 0.33974480628967285s
|
||||
slow_function run speed: 2.9590742588043213s
|
||||
```
|
||||
|
||||
| Page | Read when you want to |
|
||||
| --- | --- |
|
||||
| [Setup](Setup) | Create a local `.venv`, run the program and run the tests |
|
||||
| [Step 1: the current time](Step-1-Current-Time) | Learn what `time.time()` returns and how to measure a duration |
|
||||
| [Step 2: the decorator skeleton](Step-2-Decorator-Skeleton) | Learn what a decorator is and why `functools.wraps` matters |
|
||||
| [Step 3: the timing wrapper](Step-3-Timing-Wrapper) | See how the wrapper times the call and how tests avoid real time |
|
||||
| [Step 4: fast against slow](Step-4-Fast-vs-Slow) | Put it together and read the result |
|
||||
@@ -0,0 +1,46 @@
|
||||
# Opsætning
|
||||
|
||||
[English](Setup) · **Dansk** · [Bahasa Malaysia](Setup-ms)
|
||||
|
||||
## Det skal du bruge
|
||||
|
||||
Python 3.13 eller nyere og `git`. Programmet har ingen afhængigheder ved kørsel. `pytest` skal kun bruges til testene.
|
||||
|
||||
## Opret og brug en lokal `.venv`
|
||||
|
||||
Et virtuelt miljø holder projektets pakker adskilt fra resten af dit system. Windows (PowerShell):
|
||||
|
||||
```powershell
|
||||
python -m venv .venv
|
||||
.venv\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
Linux og macOS:
|
||||
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
```
|
||||
|
||||
Opgradér pip og installér projektet med dets testværktøjer:
|
||||
|
||||
```bash
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install -e ".[dev]"
|
||||
```
|
||||
|
||||
Forlad miljøet med `deactivate`.
|
||||
|
||||
## Kør og test
|
||||
|
||||
```bash
|
||||
python -m speed_calc
|
||||
python -m pytest
|
||||
```
|
||||
|
||||
Kør ét lektionstrin for sig med `python -m speed_calc.lecture_steps N` (N er 1 til 4).
|
||||
|
||||
## Hvad vi lærte
|
||||
|
||||
- En gentagelig opsætning: alle kan genskabe det samme miljø med tre kommandoer.
|
||||
- En vane med at holde et projekts pakker i sin egen `.venv`, som git ignorerer.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Persediaan
|
||||
|
||||
[English](Setup) · [Dansk](Setup-da) · **Bahasa Malaysia**
|
||||
|
||||
## Apa yang anda perlukan
|
||||
|
||||
Python 3.13 atau lebih baharu dan `git`. Program ini tidak mempunyai kebergantungan masa jalan. `pytest` hanya diperlukan untuk ujian.
|
||||
|
||||
## Cipta dan gunakan `.venv` setempat
|
||||
|
||||
Persekitaran maya mengasingkan pakej projek daripada bahagian lain sistem anda. Windows (PowerShell):
|
||||
|
||||
```powershell
|
||||
python -m venv .venv
|
||||
.venv\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
Linux dan macOS:
|
||||
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
```
|
||||
|
||||
Naik taraf pip dan pasang projek bersama alat ujiannya:
|
||||
|
||||
```bash
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install -e ".[dev]"
|
||||
```
|
||||
|
||||
Keluar daripada persekitaran dengan `deactivate`.
|
||||
|
||||
## Jalankan dan uji
|
||||
|
||||
```bash
|
||||
python -m speed_calc
|
||||
python -m pytest
|
||||
```
|
||||
|
||||
Jalankan satu langkah kuliah secara berasingan dengan `python -m speed_calc.lecture_steps N` (N ialah 1 hingga 4).
|
||||
|
||||
## Apa yang kita peroleh
|
||||
|
||||
- Persediaan yang boleh diulang: sesiapa sahaja boleh mencipta semula persekitaran yang sama dengan tiga arahan.
|
||||
- Tabiat menyimpan pakej projek dalam `.venv` tersendiri, yang diabaikan oleh git.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Setup
|
||||
|
||||
**English** · [Dansk](Setup-da) · [Bahasa Malaysia](Setup-ms)
|
||||
|
||||
## What you need
|
||||
|
||||
Python 3.13 or newer and `git`. The program has no runtime dependencies. `pytest` is needed only for the tests.
|
||||
|
||||
## Create and use a local `.venv`
|
||||
|
||||
A virtual environment keeps the project's packages apart from the rest of your system. Windows (PowerShell):
|
||||
|
||||
```powershell
|
||||
python -m venv .venv
|
||||
.venv\Scripts\Activate.ps1
|
||||
```
|
||||
|
||||
Linux and macOS:
|
||||
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
```
|
||||
|
||||
Upgrade pip and install the project with its test tools:
|
||||
|
||||
```bash
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install -e ".[dev]"
|
||||
```
|
||||
|
||||
Leave the environment with `deactivate`.
|
||||
|
||||
## Run and test
|
||||
|
||||
```bash
|
||||
python -m speed_calc
|
||||
python -m pytest
|
||||
```
|
||||
|
||||
Run one lecture step on its own with `python -m speed_calc.lecture_steps N` (N is 1 to 4).
|
||||
|
||||
## What we gained
|
||||
|
||||
- A repeatable setup: anyone can recreate the same environment in three commands.
|
||||
- A habit of keeping a project's packages in its own `.venv`, ignored by git.
|
||||
@@ -0,0 +1,21 @@
|
||||
# Trin 1: det aktuelle tidspunkt
|
||||
|
||||
[English](Step-1-Current-Time) · **Dansk** · [Bahasa Malaysia](Step-1-Current-Time-ms)
|
||||
|
||||
Lektionens startkode udskriver det aktuelle tidspunkt:
|
||||
|
||||
```python
|
||||
import time
|
||||
|
||||
print(time.time()) # seconds since Jan 1st, 1970
|
||||
```
|
||||
|
||||

|
||||
|
||||
Kør den med `python -m speed_calc.lecture_steps 1`. Kør den igen lidt senere, og tallet er større.
|
||||
|
||||
## Hvad vi lærte
|
||||
|
||||
- `time.time()` returnerer sekunderne siden 1. januar 1970 som et flydende tal (float).
|
||||
- Forskellen mellem to aflæsninger er en varighed i sekunder: anden kørsel minus første kørsel.
|
||||
- Den forskel er alt, en timer behøver. De næste trin lægger den ind i en dekorator.
|
||||
@@ -0,0 +1,21 @@
|
||||
# Langkah 1: masa semasa
|
||||
|
||||
[English](Step-1-Current-Time) · [Dansk](Step-1-Current-Time-da) · **Bahasa Malaysia**
|
||||
|
||||
Kod permulaan kuliah mencetak masa semasa:
|
||||
|
||||
```python
|
||||
import time
|
||||
|
||||
print(time.time()) # seconds since Jan 1st, 1970
|
||||
```
|
||||
|
||||

|
||||
|
||||
Jalankannya dengan `python -m speed_calc.lecture_steps 1`. Jalankan sekali lagi sebentar kemudian dan nombornya lebih besar.
|
||||
|
||||
## Apa yang kita peroleh
|
||||
|
||||
- `time.time()` memulangkan bilangan saat sejak 1 Januari 1970 sebagai float.
|
||||
- Perbezaan antara dua bacaan ialah tempoh dalam saat: larian kedua tolak larian pertama.
|
||||
- Perbezaan itu sahaja sudah cukup untuk sebuah pemasa. Langkah seterusnya meletakkannya di dalam decorator.
|
||||
@@ -0,0 +1,21 @@
|
||||
# Step 1: the current time
|
||||
|
||||
**English** · [Dansk](Step-1-Current-Time-da) · [Bahasa Malaysia](Step-1-Current-Time-ms)
|
||||
|
||||
The starting code of the lecture prints the current time:
|
||||
|
||||
```python
|
||||
import time
|
||||
|
||||
print(time.time()) # seconds since Jan 1st, 1970
|
||||
```
|
||||
|
||||

|
||||
|
||||
Run it with `python -m speed_calc.lecture_steps 1`. Run it again a little later and the number is larger.
|
||||
|
||||
## What we gained
|
||||
|
||||
- `time.time()` returns the seconds since January 1st, 1970 as a float.
|
||||
- The difference between two readings is a duration in seconds: second run minus first run.
|
||||
- That difference is all a timer needs. The next steps put it inside a decorator.
|
||||
@@ -0,0 +1,27 @@
|
||||
# Trin 2: dekoratorens skelet
|
||||
|
||||
[English](Step-2-Decorator-Skeleton) · **Dansk** · [Bahasa Malaysia](Step-2-Decorator-Skeleton-ms)
|
||||
|
||||
En dekorator er en funktion, der tager en funktion og returnerer en anden funktion. Dette skelet melder blot kaldet:
|
||||
|
||||
```python
|
||||
def skeleton(function):
|
||||
@functools.wraps(function)
|
||||
def wrapper(*args, **kwargs):
|
||||
print(f"calling {function.__name__}")
|
||||
return function(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
```
|
||||
|
||||

|
||||
|
||||
Kør den med `python -m speed_calc.lecture_steps 2`.
|
||||
|
||||
## Hvad vi lærte
|
||||
|
||||
- Funktioner er værdier: du kan give dem videre til andre funktioner og returnere dem.
|
||||
- Den indre `wrapper` er en closure; den husker `function`, efter at `skeleton` er returneret.
|
||||
- `*args, **kwargs` lader wrapperen tage imod argumenterne fra enhver funktion og give dem videre.
|
||||
- `functools.wraps` bevarer det oprindelige navn og docstring, så den dekorerede funktion stadig hedder `fast_function`.
|
||||
- `@name` over en funktion er en genvej til `function = name(function)`.
|
||||
@@ -0,0 +1,27 @@
|
||||
# Langkah 2: rangka decorator
|
||||
|
||||
[English](Step-2-Decorator-Skeleton) · [Dansk](Step-2-Decorator-Skeleton-da) · **Bahasa Malaysia**
|
||||
|
||||
Decorator ialah fungsi yang menerima sebuah fungsi dan memulangkan fungsi lain. Rangka ini hanya mengumumkan panggilan:
|
||||
|
||||
```python
|
||||
def skeleton(function):
|
||||
@functools.wraps(function)
|
||||
def wrapper(*args, **kwargs):
|
||||
print(f"calling {function.__name__}")
|
||||
return function(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
```
|
||||
|
||||

|
||||
|
||||
Jalankannya dengan `python -m speed_calc.lecture_steps 2`.
|
||||
|
||||
## Apa yang kita peroleh
|
||||
|
||||
- Fungsi ialah nilai: anda boleh menghantarnya kepada fungsi lain dan memulangkannya.
|
||||
- `wrapper` di dalam ialah satu closure; ia mengingati `function` selepas `skeleton` selesai dipulangkan.
|
||||
- `*args, **kwargs` membolehkan pembungkus menerima argumen bagi sebarang fungsi dan meneruskannya.
|
||||
- `functools.wraps` mengekalkan nama dan docstring asal, jadi fungsi yang didekorasi masih menyebut `fast_function`.
|
||||
- `@name` di atas sebuah fungsi ialah singkatan bagi `function = name(function)`.
|
||||
@@ -0,0 +1,27 @@
|
||||
# Step 2: the decorator skeleton
|
||||
|
||||
**English** · [Dansk](Step-2-Decorator-Skeleton-da) · [Bahasa Malaysia](Step-2-Decorator-Skeleton-ms)
|
||||
|
||||
A decorator is a function that takes a function and returns another function. This skeleton only announces the call:
|
||||
|
||||
```python
|
||||
def skeleton(function):
|
||||
@functools.wraps(function)
|
||||
def wrapper(*args, **kwargs):
|
||||
print(f"calling {function.__name__}")
|
||||
return function(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
```
|
||||
|
||||

|
||||
|
||||
Run it with `python -m speed_calc.lecture_steps 2`.
|
||||
|
||||
## What we gained
|
||||
|
||||
- Functions are values: you can pass them to other functions and return them.
|
||||
- The inner `wrapper` is a closure; it remembers `function` after `skeleton` has returned.
|
||||
- `*args, **kwargs` let the wrapper accept the arguments of any function and pass them on.
|
||||
- `functools.wraps` keeps the original name and docstring, so the decorated function still says `fast_function`.
|
||||
- `@name` above a function is shorthand for `function = name(function)`.
|
||||
@@ -0,0 +1,24 @@
|
||||
# Trin 3: tidtagnings-wrapperen
|
||||
|
||||
[English](Step-3-Timing-Wrapper) · **Dansk** · [Bahasa Malaysia](Step-3-Timing-Wrapper-ms)
|
||||
|
||||
Wrapperen aflæser uret før og efter kaldet og udskriver forskellen:
|
||||
|
||||
```python
|
||||
start = clock()
|
||||
result = function(*args, **kwargs)
|
||||
seconds = clock() - start
|
||||
output(RESULT_TEMPLATE.format(name=function.__name__, seconds=seconds))
|
||||
return result
|
||||
```
|
||||
|
||||

|
||||
|
||||
Kør den med `python -m speed_calc.lecture_steps 3`.
|
||||
|
||||
## Hvad vi lærte
|
||||
|
||||
- En dekorator kan køre kode før og efter funktionen uden at ændre funktionen.
|
||||
- Wrapperen returnerer funktionens resultat, så den dekorerede funktion stadig virker som før.
|
||||
- `make_speed_calc_decorator(clock, output)` tager uret og outputtet som parametre. Testene giver den et falsk ur, så de kontrollerer præcise værdier og aldrig venter på rigtig tid.
|
||||
- Tekstformatet ligger i `constants.py`, det ene sted for konstanter.
|
||||
@@ -0,0 +1,24 @@
|
||||
# Langkah 3: pembungkus pemasaan
|
||||
|
||||
[English](Step-3-Timing-Wrapper) · [Dansk](Step-3-Timing-Wrapper-da) · **Bahasa Malaysia**
|
||||
|
||||
Pembungkus membaca jam sebelum dan selepas panggilan, lalu mencetak perbezaannya:
|
||||
|
||||
```python
|
||||
start = clock()
|
||||
result = function(*args, **kwargs)
|
||||
seconds = clock() - start
|
||||
output(RESULT_TEMPLATE.format(name=function.__name__, seconds=seconds))
|
||||
return result
|
||||
```
|
||||
|
||||

|
||||
|
||||
Jalankannya dengan `python -m speed_calc.lecture_steps 3`.
|
||||
|
||||
## Apa yang kita peroleh
|
||||
|
||||
- Sebuah decorator boleh menjalankan kod sebelum dan selepas fungsi tanpa mengubah fungsi itu.
|
||||
- Pembungkus memulangkan hasil fungsi, jadi fungsi yang didekorasi masih berfungsi seperti dahulu.
|
||||
- `make_speed_calc_decorator(clock, output)` menerima jam dan output sebagai parameter. Ujian memberinya jam palsu, jadi ia menyemak nilai yang tepat dan tidak pernah menunggu masa sebenar.
|
||||
- Format teks terletak dalam `constants.py`, satu-satunya tempat untuk pemalar.
|
||||
@@ -0,0 +1,24 @@
|
||||
# Step 3: the timing wrapper
|
||||
|
||||
**English** · [Dansk](Step-3-Timing-Wrapper-da) · [Bahasa Malaysia](Step-3-Timing-Wrapper-ms)
|
||||
|
||||
The wrapper reads the clock before and after the call and prints the difference:
|
||||
|
||||
```python
|
||||
start = clock()
|
||||
result = function(*args, **kwargs)
|
||||
seconds = clock() - start
|
||||
output(RESULT_TEMPLATE.format(name=function.__name__, seconds=seconds))
|
||||
return result
|
||||
```
|
||||
|
||||

|
||||
|
||||
Run it with `python -m speed_calc.lecture_steps 3`.
|
||||
|
||||
## What we gained
|
||||
|
||||
- A decorator can run code before and after the function without changing the function.
|
||||
- The wrapper returns the function's result, so the decorated function still works as before.
|
||||
- `make_speed_calc_decorator(clock, output)` takes the clock and the output as parameters. The tests give it a fake clock, so they check exact values and never wait for real time.
|
||||
- The text format lives in `constants.py`, the one place for constants.
|
||||
@@ -0,0 +1,28 @@
|
||||
# Trin 4: hurtig mod langsom
|
||||
|
||||
[English](Step-4-Fast-vs-Slow) · **Dansk** · [Bahasa Malaysia](Step-4-Fast-vs-Slow-ms)
|
||||
|
||||
`@speed_calc_decorator` over begge opgavens funktioner giver det forventede output:
|
||||
|
||||
```python
|
||||
@speed_calc_decorator
|
||||
def fast_function():
|
||||
for i in range(1_000_000):
|
||||
i * i
|
||||
|
||||
|
||||
@speed_calc_decorator
|
||||
def slow_function():
|
||||
for i in range(10_000_000):
|
||||
i * i
|
||||
```
|
||||
|
||||

|
||||
|
||||
Kør den med `python -m speed_calc`.
|
||||
|
||||
## Hvad vi lærte
|
||||
|
||||
- Én dekorator tager tid på et vilkårligt antal funktioner; tidtagningskoden skrives kun én gang.
|
||||
- `slow_function` gennemløber sin løkke ti gange så mange gange som `fast_function`, så den tager cirka ti gange så lang tid. Tallene er forskellige på hver maskine, men forholdet er det ikke.
|
||||
- En ren struktur til en lille øvelse: `src/` til kode, `tests/` til tests, `docs/` til dokumenter, `constants.py` til konstanter og Doxygen-kommentarer til API'et.
|
||||
@@ -0,0 +1,28 @@
|
||||
# Langkah 4: pantas lawan perlahan
|
||||
|
||||
[English](Step-4-Fast-vs-Slow) · [Dansk](Step-4-Fast-vs-Slow-da) · **Bahasa Malaysia**
|
||||
|
||||
`@speed_calc_decorator` di atas kedua-dua fungsi tugasan memberikan output yang dijangka:
|
||||
|
||||
```python
|
||||
@speed_calc_decorator
|
||||
def fast_function():
|
||||
for i in range(1_000_000):
|
||||
i * i
|
||||
|
||||
|
||||
@speed_calc_decorator
|
||||
def slow_function():
|
||||
for i in range(10_000_000):
|
||||
i * i
|
||||
```
|
||||
|
||||

|
||||
|
||||
Jalankannya dengan `python -m speed_calc`.
|
||||
|
||||
## Apa yang kita peroleh
|
||||
|
||||
- Satu decorator mengukur masa mana-mana bilangan fungsi; kod pemasaan ditulis sekali sahaja.
|
||||
- `slow_function` mengulang sepuluh kali lebih banyak daripada `fast_function`, jadi ia mengambil masa kira-kira sepuluh kali lebih lama. Nombornya berbeza pada setiap mesin, tetapi nisbahnya tidak.
|
||||
- Susun atur yang kemas untuk latihan kecil: `src/` untuk kod, `tests/` untuk ujian, `docs/` untuk dokumen, `constants.py` untuk pemalar, dan komen Doxygen untuk API.
|
||||
@@ -0,0 +1,28 @@
|
||||
# Step 4: fast against slow
|
||||
|
||||
**English** · [Dansk](Step-4-Fast-vs-Slow-da) · [Bahasa Malaysia](Step-4-Fast-vs-Slow-ms)
|
||||
|
||||
`@speed_calc_decorator` above both functions of the assignment gives the expected output:
|
||||
|
||||
```python
|
||||
@speed_calc_decorator
|
||||
def fast_function():
|
||||
for i in range(1_000_000):
|
||||
i * i
|
||||
|
||||
|
||||
@speed_calc_decorator
|
||||
def slow_function():
|
||||
for i in range(10_000_000):
|
||||
i * i
|
||||
```
|
||||
|
||||

|
||||
|
||||
Run it with `python -m speed_calc`.
|
||||
|
||||
## What we gained
|
||||
|
||||
- One decorator times any number of functions; the timing code is written once.
|
||||
- `slow_function` loops ten times as often as `fast_function`, so it takes about ten times as long. The numbers differ on every machine, but the ratio does not.
|
||||
- A clean layout for a small exercise: `src/` for code, `tests/` for tests, `docs/` for documents, `constants.py` for constants, and Doxygen comments for the API.
|
||||
@@ -0,0 +1,14 @@
|
||||
**Speed Calc Decorator**
|
||||
|
||||
- [Home](Home)
|
||||
- [Setup](Setup)
|
||||
- [Step 1: the current time](Step-1-Current-Time)
|
||||
- [Step 2: the decorator skeleton](Step-2-Decorator-Skeleton)
|
||||
- [Step 3: the timing wrapper](Step-3-Timing-Wrapper)
|
||||
- [Step 4: fast against slow](Step-4-Fast-vs-Slow)
|
||||
|
||||
**Languages**
|
||||
|
||||
- English: [Home](Home)
|
||||
- Dansk: [Hjem](Home-da)
|
||||
- Bahasa Malaysia: [Utama](Home-ms)
|
||||
Reference in new issue
Block a user