<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ro">
	<id>http://wiki.dcae.pub.ro/index.php?action=history&amp;feed=atom&amp;title=Lab_6</id>
	<title>Lab 6 - Revizia istoricului</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.dcae.pub.ro/index.php?action=history&amp;feed=atom&amp;title=Lab_6"/>
	<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Lab_6&amp;action=history"/>
	<updated>2026-10-05T12:06:23Z</updated>
	<subtitle>Istoricul versiunilor pentru această pagină din wiki</subtitle>
	<generator>MediaWiki 1.35.14</generator>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Lab_6&amp;diff=8375&amp;oldid=prev</id>
		<title>Andrei.ulmamei: Pagină nouă: = Lab 6 — Project Development II =  == Objectives ==  This laboratory continues the supervised development of the semester project.  The objective is to move from a working minim...</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Lab_6&amp;diff=8375&amp;oldid=prev"/>
		<updated>2026-09-26T10:12:53Z</updated>

		<summary type="html">&lt;p&gt;Pagină nouă: = Lab 6 — Project Development II =  == Objectives ==  This laboratory continues the supervised development of the semester project.  The objective is to move from a working minim...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Pagină nouă&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Lab 6 — Project Development II =&lt;br /&gt;
&lt;br /&gt;
== Objectives ==&lt;br /&gt;
&lt;br /&gt;
This laboratory continues the supervised development of the semester project.&lt;br /&gt;
&lt;br /&gt;
The objective is to move from a working minimum viable product to a stable &amp;#039;&amp;#039;&amp;#039;release candidate&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
At this stage, the central functionality should already exist. The focus is therefore on completing missing features, improving reliability, removing technical debt, expanding tests, documenting the project and ensuring that another person can install and run it reproducibly.&lt;br /&gt;
&lt;br /&gt;
After completing this laboratory, you should be able to:&lt;br /&gt;
&lt;br /&gt;
* identify and prioritize remaining work;&lt;br /&gt;
* distinguish critical defects from optional improvements;&lt;br /&gt;
* complete the central functionality of the project;&lt;br /&gt;
* add regression tests for discovered bugs;&lt;br /&gt;
* test important edge cases;&lt;br /&gt;
* refactor code safely using tests;&lt;br /&gt;
* improve logging and diagnostics;&lt;br /&gt;
* improve project documentation;&lt;br /&gt;
* validate installation from a clean environment;&lt;br /&gt;
* verify dependency declarations;&lt;br /&gt;
* document known limitations;&lt;br /&gt;
* prepare a stable release candidate.&lt;br /&gt;
&lt;br /&gt;
Most of the laboratory should be spent working directly on the project.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== 1. Laboratory structure ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Time&lt;br /&gt;
! Activity&lt;br /&gt;
|-&lt;br /&gt;
| 0–15 min&lt;br /&gt;
| Project status and remaining-work review&lt;br /&gt;
|-&lt;br /&gt;
| 15–30 min&lt;br /&gt;
| Short discussion: release quality and regression testing&lt;br /&gt;
|-&lt;br /&gt;
| 30–90 min&lt;br /&gt;
| Supervised implementation and refactoring&lt;br /&gt;
|-&lt;br /&gt;
| 90–105 min&lt;br /&gt;
| Test and documentation review&lt;br /&gt;
|-&lt;br /&gt;
| 105–120 min&lt;br /&gt;
| Release-candidate verification&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 2. From MVP to release candidate ==&lt;br /&gt;
&lt;br /&gt;
The MVP demonstrated that the main technical idea works.&lt;br /&gt;
&lt;br /&gt;
A release candidate should demonstrate that the project is close to final delivery.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
prototype&lt;br /&gt;
    ↓&lt;br /&gt;
MVP&lt;br /&gt;
    ↓&lt;br /&gt;
feature complete&lt;br /&gt;
    ↓&lt;br /&gt;
tested&lt;br /&gt;
    ↓&lt;br /&gt;
documented&lt;br /&gt;
    ↓&lt;br /&gt;
release candidate&lt;br /&gt;
    ↓&lt;br /&gt;
final release&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A release candidate does not need to be perfect, but no major known defect should prevent the primary workflow from operating correctly.&lt;br /&gt;
&lt;br /&gt;
== 3. Feature completeness ==&lt;br /&gt;
&lt;br /&gt;
Before adding new features, classify remaining work.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Category&lt;br /&gt;
! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| required&lt;br /&gt;
| necessary for the project to satisfy its main objective&lt;br /&gt;
|-&lt;br /&gt;
| important&lt;br /&gt;
| significantly improves usability or robustness&lt;br /&gt;
|-&lt;br /&gt;
| optional&lt;br /&gt;
| useful enhancement but not required&lt;br /&gt;
|-&lt;br /&gt;
| experimental&lt;br /&gt;
| interesting idea that may not be stable enough for final integration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Required functionality should be completed before optional extensions.&lt;br /&gt;
&lt;br /&gt;
== 4. Priority levels ==&lt;br /&gt;
&lt;br /&gt;
A simple priority system is sufficient.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Priority&lt;br /&gt;
! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| P0&lt;br /&gt;
| application cannot perform its primary function&lt;br /&gt;
|-&lt;br /&gt;
| P1&lt;br /&gt;
| major defect affecting normal use&lt;br /&gt;
|-&lt;br /&gt;
| P2&lt;br /&gt;
| important improvement or non-critical defect&lt;br /&gt;
|-&lt;br /&gt;
| P3&lt;br /&gt;
| optional improvement&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
P0 and P1 issues should be resolved before adding new optional features.&lt;br /&gt;
&lt;br /&gt;
== 5. Remaining-work list ==&lt;br /&gt;
&lt;br /&gt;
Maintain a short actionable list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
[ ] Handle malformed input&lt;br /&gt;
[ ] Add timeout handling&lt;br /&gt;
[ ] Add pipeline tests&lt;br /&gt;
[ ] Document configuration&lt;br /&gt;
[ ] Remove debug output&lt;br /&gt;
[ ] Verify clean installation&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Avoid vague items such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
[ ] Improve code&lt;br /&gt;
[ ] Fix things&lt;br /&gt;
[ ] Finish project&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 6. Stable software before more features ==&lt;br /&gt;
&lt;br /&gt;
At this stage, a smaller stable project is generally preferable to a larger unstable one.&lt;br /&gt;
&lt;br /&gt;
Prefer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
working feature A&lt;br /&gt;
working feature B&lt;br /&gt;
working feature C&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
over:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
feature A mostly works&lt;br /&gt;
feature B sometimes works&lt;br /&gt;
feature C works&lt;br /&gt;
feature D unfinished&lt;br /&gt;
feature E experimental&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 7. Regression testing ==&lt;br /&gt;
&lt;br /&gt;
When a defect is discovered:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
discover bug&lt;br /&gt;
    ↓&lt;br /&gt;
reproduce bug&lt;br /&gt;
    ↓&lt;br /&gt;
write failing test&lt;br /&gt;
    ↓&lt;br /&gt;
fix implementation&lt;br /&gt;
    ↓&lt;br /&gt;
test passes&lt;br /&gt;
    ↓&lt;br /&gt;
keep test permanently&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The resulting test is a &amp;#039;&amp;#039;&amp;#039;regression test&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== 8. Regression test example ==&lt;br /&gt;
&lt;br /&gt;
Suppose:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def average(values):&lt;br /&gt;
    return sum(values) / len(values)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function fails incorrectly for an empty list.&lt;br /&gt;
&lt;br /&gt;
Add a test:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import pytest&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def test_average_rejects_empty_list():&lt;br /&gt;
    with pytest.raises(ValueError):&lt;br /&gt;
        average([])&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then update the function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def average(values):&lt;br /&gt;
    if not values:&lt;br /&gt;
        raise ValueError(&lt;br /&gt;
            &amp;quot;values cannot be empty&amp;quot;&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
    return sum(values) / len(values)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The test should remain in the project after the defect is fixed.&lt;br /&gt;
&lt;br /&gt;
== 9. Edge-case review ==&lt;br /&gt;
&lt;br /&gt;
Normal input is not sufficient.&lt;br /&gt;
&lt;br /&gt;
For numerical data, consider:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
minimum valid value&lt;br /&gt;
maximum valid value&lt;br /&gt;
zero&lt;br /&gt;
negative values&lt;br /&gt;
very large values&lt;br /&gt;
empty input&lt;br /&gt;
one-element input&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For text:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
empty string&lt;br /&gt;
whitespace-only string&lt;br /&gt;
Unicode characters&lt;br /&gt;
very long strings&lt;br /&gt;
unexpected encoding&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For files:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
missing file&lt;br /&gt;
empty file&lt;br /&gt;
malformed file&lt;br /&gt;
permission error&lt;br /&gt;
missing output directory&lt;br /&gt;
unexpected format&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10. Network projects ==&lt;br /&gt;
&lt;br /&gt;
Network projects should consider:&lt;br /&gt;
&lt;br /&gt;
* connection refused;&lt;br /&gt;
* timeout;&lt;br /&gt;
* server unavailable;&lt;br /&gt;
* malformed response;&lt;br /&gt;
* unexpected status code;&lt;br /&gt;
* lost connection;&lt;br /&gt;
* incomplete message.&lt;br /&gt;
&lt;br /&gt;
Do not assume every network operation succeeds.&lt;br /&gt;
&lt;br /&gt;
== 11. Hardware projects ==&lt;br /&gt;
&lt;br /&gt;
Hardware projects should consider:&lt;br /&gt;
&lt;br /&gt;
* device unavailable;&lt;br /&gt;
* device disconnected;&lt;br /&gt;
* incomplete data;&lt;br /&gt;
* invalid data;&lt;br /&gt;
* timeout;&lt;br /&gt;
* permission error;&lt;br /&gt;
* unsupported device or firmware version.&lt;br /&gt;
&lt;br /&gt;
Expected hardware failures should produce understandable application behavior.&lt;br /&gt;
&lt;br /&gt;
== 12. Image-processing projects ==&lt;br /&gt;
&lt;br /&gt;
Image-processing projects should consider:&lt;br /&gt;
&lt;br /&gt;
* unsupported format;&lt;br /&gt;
* invalid dimensions;&lt;br /&gt;
* empty image;&lt;br /&gt;
* grayscale versus color input;&lt;br /&gt;
* unexpected channel count;&lt;br /&gt;
* corrupted input;&lt;br /&gt;
* very large images.&lt;br /&gt;
&lt;br /&gt;
Validate assumptions close to the input boundary.&lt;br /&gt;
&lt;br /&gt;
== 13. Public behavior versus implementation detail ==&lt;br /&gt;
&lt;br /&gt;
Tests should focus on public behavior.&lt;br /&gt;
&lt;br /&gt;
Prefer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
result = process(image)&lt;br /&gt;
&lt;br /&gt;
assert result.shape == expected_shape&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
over:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
assert processor._temporary_buffer == ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Private implementation details should remain free to change during refactoring.&lt;br /&gt;
&lt;br /&gt;
== 14. Do not delete inconvenient tests ==&lt;br /&gt;
&lt;br /&gt;
If a valid test fails after a code change, investigate the reason.&lt;br /&gt;
&lt;br /&gt;
A test should normally be removed only when:&lt;br /&gt;
&lt;br /&gt;
* the requirement changed;&lt;br /&gt;
* the tested behavior no longer exists;&lt;br /&gt;
* the test itself is incorrect.&lt;br /&gt;
&lt;br /&gt;
== 15. Test organization ==&lt;br /&gt;
&lt;br /&gt;
A larger project can organize tests by component:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
tests/&lt;br /&gt;
├── test_models.py&lt;br /&gt;
├── test_services.py&lt;br /&gt;
├── test_storage.py&lt;br /&gt;
├── test_protocol.py&lt;br /&gt;
└── test_pipeline.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For larger projects:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
tests/&lt;br /&gt;
├── unit/&lt;br /&gt;
│   ├── test_filters.py&lt;br /&gt;
│   └── test_protocol.py&lt;br /&gt;
└── integration/&lt;br /&gt;
    ├── test_storage.py&lt;br /&gt;
    └── test_pipeline.py&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Use the simplest structure that remains understandable.&lt;br /&gt;
&lt;br /&gt;
== 16. Unit versus integration tests ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Example&lt;br /&gt;
! Type&lt;br /&gt;
|-&lt;br /&gt;
| validate one grade value&lt;br /&gt;
| unit&lt;br /&gt;
|-&lt;br /&gt;
| decode one packet&lt;br /&gt;
| unit&lt;br /&gt;
|-&lt;br /&gt;
| encode and then decode a packet&lt;br /&gt;
| integration&lt;br /&gt;
|-&lt;br /&gt;
| save and reload data from a temporary file&lt;br /&gt;
| integration&lt;br /&gt;
|-&lt;br /&gt;
| run a complete processing pipeline&lt;br /&gt;
| integration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Both kinds of tests are useful.&lt;br /&gt;
&lt;br /&gt;
== 17. End-to-end testing ==&lt;br /&gt;
&lt;br /&gt;
An end-to-end test exercises a complete workflow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
input&lt;br /&gt;
  ↓&lt;br /&gt;
application&lt;br /&gt;
  ↓&lt;br /&gt;
processing&lt;br /&gt;
  ↓&lt;br /&gt;
output&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
End-to-end tests are valuable but should not replace focused unit tests.&lt;br /&gt;
&lt;br /&gt;
== 18. Testing CLI applications ==&lt;br /&gt;
&lt;br /&gt;
Separate argument parsing from application logic.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%; table-layout:fixed;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:50%;&amp;quot; | Tightly coupled&lt;br /&gt;
! style=&amp;quot;width:50%;&amp;quot; | Easier to test&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def main():&lt;br /&gt;
    args = parse_args()&lt;br /&gt;
&lt;br /&gt;
    # All processing here.&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def process_file(&lt;br /&gt;
    input_path,&lt;br /&gt;
    output_path,&lt;br /&gt;
):&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    args = parse_args()&lt;br /&gt;
&lt;br /&gt;
    process_file(&lt;br /&gt;
        args.input,&lt;br /&gt;
        args.output,&lt;br /&gt;
    )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The processing function can now be tested without command-line parsing.&lt;br /&gt;
&lt;br /&gt;
== 19. Deterministic tests ==&lt;br /&gt;
&lt;br /&gt;
Good tests produce the same result every time under the same conditions.&lt;br /&gt;
&lt;br /&gt;
Avoid uncontrolled dependencies on:&lt;br /&gt;
&lt;br /&gt;
* current time;&lt;br /&gt;
* random values;&lt;br /&gt;
* network availability;&lt;br /&gt;
* arbitrary filesystem state;&lt;br /&gt;
* execution order.&lt;br /&gt;
&lt;br /&gt;
For controlled randomness:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import random&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
rng = random.Random(1234)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 20. Refactoring with tests ==&lt;br /&gt;
&lt;br /&gt;
Use short cycles:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
run tests&lt;br /&gt;
   ↓&lt;br /&gt;
all pass&lt;br /&gt;
   ↓&lt;br /&gt;
small refactor&lt;br /&gt;
   ↓&lt;br /&gt;
run tests&lt;br /&gt;
   ↓&lt;br /&gt;
all pass&lt;br /&gt;
   ↓&lt;br /&gt;
commit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not perform a very large refactoring before checking whether behavior is still correct.&lt;br /&gt;
&lt;br /&gt;
== 21. Refactoring nested control flow ==&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def process(record):&lt;br /&gt;
    if record is not None:&lt;br /&gt;
        if record.valid:&lt;br /&gt;
            if record.enabled:&lt;br /&gt;
                return transform(record)&lt;br /&gt;
&lt;br /&gt;
    return None&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using guard clauses:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def process(record):&lt;br /&gt;
    if record is None:&lt;br /&gt;
        return None&lt;br /&gt;
&lt;br /&gt;
    if not record.valid:&lt;br /&gt;
        return None&lt;br /&gt;
&lt;br /&gt;
    if not record.enabled:&lt;br /&gt;
        return None&lt;br /&gt;
&lt;br /&gt;
    return transform(record)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The second version reduces nesting.&lt;br /&gt;
&lt;br /&gt;
== 22. Refactoring long conditions ==&lt;br /&gt;
&lt;br /&gt;
Before:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
if (&lt;br /&gt;
    device.connected&lt;br /&gt;
    and device.enabled&lt;br /&gt;
    and not device.error&lt;br /&gt;
    and device.temperature &amp;lt; 80&lt;br /&gt;
    and device.mode == &amp;quot;ready&amp;quot;&lt;br /&gt;
):&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def is_ready(device):&lt;br /&gt;
    return (&lt;br /&gt;
        device.connected&lt;br /&gt;
        and device.enabled&lt;br /&gt;
        and not device.error&lt;br /&gt;
        and device.temperature &amp;lt; 80&lt;br /&gt;
        and device.mode == &amp;quot;ready&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if is_ready(device):&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function name expresses the meaning of the condition.&lt;br /&gt;
&lt;br /&gt;
== 23. Structured data instead of loose dictionaries ==&lt;br /&gt;
&lt;br /&gt;
For stable domain data, a dataclass may be clearer than an unstructured dictionary.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%; table-layout:fixed;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:50%;&amp;quot; | Dictionary&lt;br /&gt;
! style=&amp;quot;width:50%;&amp;quot; | Dataclass&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
student = {&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;Alice&amp;quot;,&lt;br /&gt;
    &amp;quot;grade&amp;quot;: 9.5,&lt;br /&gt;
    &amp;quot;year&amp;quot;: 2,&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
from dataclasses import dataclass&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
@dataclass&lt;br /&gt;
class Student:&lt;br /&gt;
    name: str&lt;br /&gt;
    grade: float&lt;br /&gt;
    year: int&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Do not convert every dictionary into a class. Use the structure that best represents the data.&lt;br /&gt;
&lt;br /&gt;
== 24. Avoid over-refactoring ==&lt;br /&gt;
&lt;br /&gt;
Refactor when it improves:&lt;br /&gt;
&lt;br /&gt;
* clarity;&lt;br /&gt;
* correctness;&lt;br /&gt;
* maintainability;&lt;br /&gt;
* testability;&lt;br /&gt;
* reuse.&lt;br /&gt;
&lt;br /&gt;
Do not introduce abstractions simply to make the architecture appear more complicated.&lt;br /&gt;
&lt;br /&gt;
== 25. Logging review ==&lt;br /&gt;
&lt;br /&gt;
Search for temporary debug output such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
print(&amp;quot;debug&amp;quot;)&lt;br /&gt;
print(variable)&lt;br /&gt;
print(&amp;quot;here&amp;quot;)&lt;br /&gt;
print(&amp;quot;test&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For each occurrence, decide whether it should be:&lt;br /&gt;
&lt;br /&gt;
* removed;&lt;br /&gt;
* replaced with logging;&lt;br /&gt;
* retained as intentional user output.&lt;br /&gt;
&lt;br /&gt;
== 26. Logging levels ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Level&lt;br /&gt;
! Typical use&lt;br /&gt;
|-&lt;br /&gt;
| DEBUG&lt;br /&gt;
| detailed internal processing information&lt;br /&gt;
|-&lt;br /&gt;
| INFO&lt;br /&gt;
| normal application events&lt;br /&gt;
|-&lt;br /&gt;
| WARNING&lt;br /&gt;
| unusual condition from which execution can continue&lt;br /&gt;
|-&lt;br /&gt;
| ERROR&lt;br /&gt;
| requested operation failed&lt;br /&gt;
|-&lt;br /&gt;
| CRITICAL&lt;br /&gt;
| application cannot continue&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 27. Useful logging context ==&lt;br /&gt;
&lt;br /&gt;
Poor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
logger.error(&amp;quot;Failed&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Better:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
logger.error(&lt;br /&gt;
    &amp;quot;Failed to load configuration from %s&amp;quot;,&lt;br /&gt;
    path,&lt;br /&gt;
)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diagnostic messages should contain enough context to be useful.&lt;br /&gt;
&lt;br /&gt;
== 28. Exception logging ==&lt;br /&gt;
&lt;br /&gt;
Inside an exception handler:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    load_device()&lt;br /&gt;
except DeviceError:&lt;br /&gt;
    logger.exception(&lt;br /&gt;
        &amp;quot;Device initialization failed&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    raise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;logger.exception()&amp;lt;/code&amp;gt; includes traceback information.&lt;br /&gt;
&lt;br /&gt;
== 29. User-facing errors ==&lt;br /&gt;
&lt;br /&gt;
Expected errors should usually produce concise user-facing messages.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Error: input file &amp;#039;data.json&amp;#039; does not exist.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A predictable user error does not normally require displaying an internal traceback.&lt;br /&gt;
&lt;br /&gt;
== 30. Documentation layers ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Documentation&lt;br /&gt;
! Audience&lt;br /&gt;
|-&lt;br /&gt;
| README&lt;br /&gt;
| user or developer starting the project&lt;br /&gt;
|-&lt;br /&gt;
| docstrings&lt;br /&gt;
| developer using functions and classes&lt;br /&gt;
|-&lt;br /&gt;
| comments&lt;br /&gt;
| developer understanding non-obvious implementation decisions&lt;br /&gt;
|-&lt;br /&gt;
| release notes&lt;br /&gt;
| user/evaluator understanding changes and limitations&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 31. README checklist ==&lt;br /&gt;
&lt;br /&gt;
The README should include:&lt;br /&gt;
&lt;br /&gt;
* project name;&lt;br /&gt;
* short description;&lt;br /&gt;
* main features;&lt;br /&gt;
* requirements;&lt;br /&gt;
* installation;&lt;br /&gt;
* configuration;&lt;br /&gt;
* how to run;&lt;br /&gt;
* example usage;&lt;br /&gt;
* how to run tests;&lt;br /&gt;
* high-level architecture;&lt;br /&gt;
* known limitations.&lt;br /&gt;
&lt;br /&gt;
== 32. Reproducible installation ==&lt;br /&gt;
&lt;br /&gt;
Installation instructions should be explicit.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git clone ...&lt;br /&gt;
cd project&lt;br /&gt;
&lt;br /&gt;
python -m venv .venv&lt;br /&gt;
source .venv/bin/activate&lt;br /&gt;
&lt;br /&gt;
python -m pip install -e .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Windows PowerShell:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;powershell&amp;quot;&amp;gt;&lt;br /&gt;
.venv\Scripts\Activate.ps1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 33. Running instructions ==&lt;br /&gt;
&lt;br /&gt;
Document the actual command.&lt;br /&gt;
&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python -m project_name&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python -m project_name \&lt;br /&gt;
    --input data/input.json \&lt;br /&gt;
    --output results/output.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 34. Document configuration ==&lt;br /&gt;
&lt;br /&gt;
If a project uses:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    &amp;quot;server&amp;quot;: &amp;quot;localhost&amp;quot;,&lt;br /&gt;
    &amp;quot;port&amp;quot;: 8000,&lt;br /&gt;
    &amp;quot;timeout&amp;quot;: 5.0&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
document every field.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Field&lt;br /&gt;
! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;server&amp;lt;/code&amp;gt;&lt;br /&gt;
| remote server hostname&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;port&amp;lt;/code&amp;gt;&lt;br /&gt;
| remote service port&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;timeout&amp;lt;/code&amp;gt;&lt;br /&gt;
| request timeout in seconds&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 35. Environment variables ==&lt;br /&gt;
&lt;br /&gt;
Do not document or commit real secrets.&lt;br /&gt;
&lt;br /&gt;
Document variable names:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
API_KEY&lt;br /&gt;
SERVER_URL&lt;br /&gt;
LOG_LEVEL&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
export API_KEY=&amp;quot;...&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 36. Docstrings ==&lt;br /&gt;
&lt;br /&gt;
Use docstrings when behavior is not obvious.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def normalize(&lt;br /&gt;
    values: list[float],&lt;br /&gt;
) -&amp;gt; list[float]:&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;Scale values to the interval [0, 1].&lt;br /&gt;
&lt;br /&gt;
    Raises:&lt;br /&gt;
        ValueError: If all values are equal.&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not duplicate obvious type information already expressed by type hints.&lt;br /&gt;
&lt;br /&gt;
== 37. Public versus internal API ==&lt;br /&gt;
&lt;br /&gt;
Internal names can begin with an underscore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def _parse_header(data):&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def load_frame(path):&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This indicates that &amp;lt;code&amp;gt;_parse_header()&amp;lt;/code&amp;gt; is an implementation detail.&lt;br /&gt;
&lt;br /&gt;
== 38. Keep the public API small ==&lt;br /&gt;
&lt;br /&gt;
Prefer a small meaningful interface:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
load_image()&lt;br /&gt;
process_image()&lt;br /&gt;
save_image()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
rather than exposing every internal intermediate operation.&lt;br /&gt;
&lt;br /&gt;
== 39. Clean-environment verification ==&lt;br /&gt;
&lt;br /&gt;
Do not rely on globally installed packages.&lt;br /&gt;
&lt;br /&gt;
A useful verification is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
python -m venv test-env&lt;br /&gt;
source test-env/bin/activate&lt;br /&gt;
&lt;br /&gt;
python -m pip install -e .&lt;br /&gt;
pytest&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If this fails, installation instructions or dependency declarations are incomplete.&lt;br /&gt;
&lt;br /&gt;
== 40. Verify declared dependencies ==&lt;br /&gt;
&lt;br /&gt;
If code contains:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import requests&lt;br /&gt;
import numpy&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
the required packages must be declared in project metadata.&lt;br /&gt;
&lt;br /&gt;
Another machine should not depend on packages that happened to be installed on the developer&amp;#039;s system.&lt;br /&gt;
&lt;br /&gt;
== 41. Remove unused dependencies ==&lt;br /&gt;
&lt;br /&gt;
If the project declares:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;toml&amp;quot;&amp;gt;&lt;br /&gt;
dependencies = [&lt;br /&gt;
    &amp;quot;requests&amp;quot;,&lt;br /&gt;
    &amp;quot;numpy&amp;quot;,&lt;br /&gt;
    &amp;quot;pandas&amp;quot;,&lt;br /&gt;
    &amp;quot;matplotlib&amp;quot;,&lt;br /&gt;
    &amp;quot;opencv-python&amp;quot;,&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
but only uses &amp;lt;code&amp;gt;requests&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;numpy&amp;lt;/code&amp;gt;, remove unnecessary packages.&lt;br /&gt;
&lt;br /&gt;
== 42. Version constraints ==&lt;br /&gt;
&lt;br /&gt;
Avoid unnecessarily strict pinning unless required.&lt;br /&gt;
&lt;br /&gt;
Possibly too strict:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;toml&amp;quot;&amp;gt;&lt;br /&gt;
dependencies = [&lt;br /&gt;
    &amp;quot;requests==2.32.4&amp;quot;,&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Potentially more flexible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;toml&amp;quot;&amp;gt;&lt;br /&gt;
dependencies = [&lt;br /&gt;
    &amp;quot;requests&amp;gt;=2.32,&amp;lt;3&amp;quot;,&lt;br /&gt;
]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The exact constraint depends on project compatibility requirements.&lt;br /&gt;
&lt;br /&gt;
== 43. Supported Python version ==&lt;br /&gt;
&lt;br /&gt;
Declare the expected Python version:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;toml&amp;quot;&amp;gt;&lt;br /&gt;
[project]&lt;br /&gt;
requires-python = &amp;quot;&amp;gt;=3.11&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not claim compatibility with an older version while using unsupported newer syntax.&lt;br /&gt;
&lt;br /&gt;
== 44. Clean repository ==&lt;br /&gt;
&lt;br /&gt;
The repository should generally exclude generated content such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
.venv/&lt;br /&gt;
__pycache__/&lt;br /&gt;
*.pyc&lt;br /&gt;
.coverage&lt;br /&gt;
.pytest_cache/&lt;br /&gt;
.mypy_cache/&lt;br /&gt;
.ruff_cache/&lt;br /&gt;
build/&lt;br /&gt;
dist/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 45. Example .gitignore ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
.venv/&lt;br /&gt;
__pycache__/&lt;br /&gt;
*.pyc&lt;br /&gt;
&lt;br /&gt;
.pytest_cache/&lt;br /&gt;
.mypy_cache/&lt;br /&gt;
.ruff_cache/&lt;br /&gt;
&lt;br /&gt;
.coverage&lt;br /&gt;
htmlcov/&lt;br /&gt;
&lt;br /&gt;
build/&lt;br /&gt;
dist/&lt;br /&gt;
*.egg-info/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add project-specific generated files where appropriate.&lt;br /&gt;
&lt;br /&gt;
== 46. Sample data ==&lt;br /&gt;
&lt;br /&gt;
If the project requires sample input for demonstration, include a small suitable example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
examples/&lt;br /&gt;
├── sample_input.json&lt;br /&gt;
└── expected_output.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not rely on private local data that cannot be reproduced.&lt;br /&gt;
&lt;br /&gt;
== 47. Sample configuration ==&lt;br /&gt;
&lt;br /&gt;
For machine-specific configuration, provide:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
config.example.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
rather than committing real credentials in:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
config.json&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 48. Security review ==&lt;br /&gt;
&lt;br /&gt;
Check for accidental secrets:&lt;br /&gt;
&lt;br /&gt;
* passwords;&lt;br /&gt;
* API keys;&lt;br /&gt;
* private keys;&lt;br /&gt;
* access tokens;&lt;br /&gt;
* database credentials;&lt;br /&gt;
* credential-bearing URLs.&lt;br /&gt;
&lt;br /&gt;
If a credential was committed, removing it from the latest version may not be sufficient. The credential should be rotated.&lt;br /&gt;
&lt;br /&gt;
== 49. Input validation review ==&lt;br /&gt;
&lt;br /&gt;
Review every external input boundary:&lt;br /&gt;
&lt;br /&gt;
* command-line arguments;&lt;br /&gt;
* configuration;&lt;br /&gt;
* files;&lt;br /&gt;
* network messages;&lt;br /&gt;
* user input;&lt;br /&gt;
* hardware data;&lt;br /&gt;
* API responses.&lt;br /&gt;
&lt;br /&gt;
Ask:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
What assumptions does this code make?&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Validate important assumptions before processing the data.&lt;br /&gt;
&lt;br /&gt;
== 50. Serialization round trip ==&lt;br /&gt;
&lt;br /&gt;
If data is stored and later loaded, test a round trip.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
object&lt;br /&gt;
  ↓&lt;br /&gt;
serialize&lt;br /&gt;
  ↓&lt;br /&gt;
file&lt;br /&gt;
  ↓&lt;br /&gt;
deserialize&lt;br /&gt;
  ↓&lt;br /&gt;
object&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def test_round_trip(tmp_path):&lt;br /&gt;
    path = tmp_path / &amp;quot;data.json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    original = [&lt;br /&gt;
        Student(&amp;quot;Alice&amp;quot;, 9.5),&lt;br /&gt;
        Student(&amp;quot;Bob&amp;quot;, 8.0),&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    save_students(path, original)&lt;br /&gt;
&lt;br /&gt;
    restored = load_students(path)&lt;br /&gt;
&lt;br /&gt;
    assert restored == original&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 51. Performance sanity check ==&lt;br /&gt;
&lt;br /&gt;
Full optimization is not required, but the application should be tested on representative input.&lt;br /&gt;
&lt;br /&gt;
If the intended workload is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
100000 records&lt;br /&gt;
100 images&lt;br /&gt;
continuous packets&lt;br /&gt;
large matrices&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
do not test only with one tiny input and assume performance is acceptable.&lt;br /&gt;
&lt;br /&gt;
== 52. Resource review ==&lt;br /&gt;
&lt;br /&gt;
Check for:&lt;br /&gt;
&lt;br /&gt;
* files left open;&lt;br /&gt;
* sockets not closed;&lt;br /&gt;
* unnecessary large copies;&lt;br /&gt;
* unbounded queues/lists;&lt;br /&gt;
* repeated loading of large data;&lt;br /&gt;
* infinite retry loops;&lt;br /&gt;
* threads or processes not terminated.&lt;br /&gt;
&lt;br /&gt;
Use context managers where appropriate.&lt;br /&gt;
&lt;br /&gt;
== 53. Graceful shutdown ==&lt;br /&gt;
&lt;br /&gt;
Applications managing external resources should stop predictably.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
try:&lt;br /&gt;
    application.run()&lt;br /&gt;
finally:&lt;br /&gt;
    application.close()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When appropriate, make resources context managers.&lt;br /&gt;
&lt;br /&gt;
== 54. Keyboard interrupt ==&lt;br /&gt;
&lt;br /&gt;
A CLI application may handle &amp;lt;code&amp;gt;Ctrl+C&amp;lt;/code&amp;gt; cleanly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
def main():&lt;br /&gt;
    try:&lt;br /&gt;
        run()&lt;br /&gt;
    except KeyboardInterrupt:&lt;br /&gt;
        print(&amp;quot;\nInterrupted.&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Only add this behavior when it improves the application.&lt;br /&gt;
&lt;br /&gt;
== 55. Release version ==&lt;br /&gt;
&lt;br /&gt;
The project should have a version identifier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;toml&amp;quot;&amp;gt;&lt;br /&gt;
[project]&lt;br /&gt;
version = &amp;quot;0.9.0&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A release candidate can be described as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
0.9.0-rc1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 56. Release notes ==&lt;br /&gt;
&lt;br /&gt;
A short release note can contain:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Version&lt;br /&gt;
Main features&lt;br /&gt;
Important fixes&lt;br /&gt;
Known limitations&lt;br /&gt;
Installation notes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It does not need to be long.&lt;br /&gt;
&lt;br /&gt;
== 57. Known limitations ==&lt;br /&gt;
&lt;br /&gt;
Document real limitations explicitly.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Only PNG input is supported.&lt;br /&gt;
IPv6 is not supported.&lt;br /&gt;
The program has only been tested on Linux.&lt;br /&gt;
Maximum tested image size is 4096×4096.&lt;br /&gt;
Device reconnect requires restart.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 58. Known issue versus critical defect ==&lt;br /&gt;
&lt;br /&gt;
A known issue may remain if:&lt;br /&gt;
&lt;br /&gt;
* it does not prevent the primary workflow;&lt;br /&gt;
* its scope is clear;&lt;br /&gt;
* fixing it immediately would create disproportionate risk.&lt;br /&gt;
&lt;br /&gt;
A critical defect should not simply be renamed a limitation.&lt;br /&gt;
&lt;br /&gt;
== 59. Manual acceptance test ==&lt;br /&gt;
&lt;br /&gt;
In addition to automated tests, perform a manual end-to-end test.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
[ ] clean startup&lt;br /&gt;
[ ] representative input accepted&lt;br /&gt;
[ ] main feature works&lt;br /&gt;
[ ] output correct&lt;br /&gt;
[ ] expected error handled&lt;br /&gt;
[ ] application exits cleanly&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 60. Clean-machine test ==&lt;br /&gt;
&lt;br /&gt;
Ask:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Could another student clone this repository&lt;br /&gt;
and run the project using only the README?&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test it:&lt;br /&gt;
&lt;br /&gt;
# create a clean environment;&lt;br /&gt;
# install dependencies;&lt;br /&gt;
# run tests;&lt;br /&gt;
# start the application;&lt;br /&gt;
# follow only documented steps.&lt;br /&gt;
&lt;br /&gt;
== 61. Project review checklist ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Area&lt;br /&gt;
! Question&lt;br /&gt;
|-&lt;br /&gt;
| features&lt;br /&gt;
| Are all required features implemented?&lt;br /&gt;
|-&lt;br /&gt;
| defects&lt;br /&gt;
| Are any P0 or P1 defects open?&lt;br /&gt;
|-&lt;br /&gt;
| tests&lt;br /&gt;
| Are central behavior and major failures tested?&lt;br /&gt;
|-&lt;br /&gt;
| architecture&lt;br /&gt;
| Is remaining technical debt acceptable?&lt;br /&gt;
|-&lt;br /&gt;
| logging&lt;br /&gt;
| Are diagnostics useful and appropriately leveled?&lt;br /&gt;
|-&lt;br /&gt;
| errors&lt;br /&gt;
| Are expected failures handled?&lt;br /&gt;
|-&lt;br /&gt;
| documentation&lt;br /&gt;
| Can another user install and run the project?&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| Are all required packages declared?&lt;br /&gt;
|-&lt;br /&gt;
| repository&lt;br /&gt;
| Is generated and sensitive content excluded?&lt;br /&gt;
|-&lt;br /&gt;
| release&lt;br /&gt;
| Can the application be demonstrated reliably?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 62. Exercise 1 — Remaining-work triage ==&lt;br /&gt;
&lt;br /&gt;
List all remaining tasks.&lt;br /&gt;
&lt;br /&gt;
Assign:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
P0&lt;br /&gt;
P1&lt;br /&gt;
P2&lt;br /&gt;
P3&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Resolve P0 and P1 issues before optional work.&lt;br /&gt;
&lt;br /&gt;
== 63. Exercise 2 — Regression test ==&lt;br /&gt;
&lt;br /&gt;
Choose one defect discovered since Lab 5.&lt;br /&gt;
&lt;br /&gt;
Then:&lt;br /&gt;
&lt;br /&gt;
# reproduce the defect;&lt;br /&gt;
# add a failing automated test;&lt;br /&gt;
# fix the implementation;&lt;br /&gt;
# confirm the new test passes;&lt;br /&gt;
# run the complete test suite.&lt;br /&gt;
&lt;br /&gt;
== 64. Exercise 3 — Edge-case audit ==&lt;br /&gt;
&lt;br /&gt;
Choose the most important input to the project.&lt;br /&gt;
&lt;br /&gt;
Document at least five edge cases.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Input&lt;br /&gt;
! Expected behavior&lt;br /&gt;
|-&lt;br /&gt;
| empty input&lt;br /&gt;
| clear validation error or defined empty result&lt;br /&gt;
|-&lt;br /&gt;
| valid minimal input&lt;br /&gt;
| processed successfully&lt;br /&gt;
|-&lt;br /&gt;
| malformed input&lt;br /&gt;
| parsing error reported&lt;br /&gt;
|-&lt;br /&gt;
| missing input&lt;br /&gt;
| missing-resource error&lt;br /&gt;
|-&lt;br /&gt;
| large representative input&lt;br /&gt;
| completes within reasonable resources&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Add missing tests where practical.&lt;br /&gt;
&lt;br /&gt;
== 65. Exercise 4 — Test-suite cleanup ==&lt;br /&gt;
&lt;br /&gt;
Review the test suite for:&lt;br /&gt;
&lt;br /&gt;
* duplicated setup;&lt;br /&gt;
* unclear names;&lt;br /&gt;
* order dependencies;&lt;br /&gt;
* permanent local test files;&lt;br /&gt;
* unnecessary real network access;&lt;br /&gt;
* missing assertions;&lt;br /&gt;
* disabled tests.&lt;br /&gt;
&lt;br /&gt;
Refactor where appropriate.&lt;br /&gt;
&lt;br /&gt;
== 66. Exercise 5 — Refactoring checkpoint ==&lt;br /&gt;
&lt;br /&gt;
Choose one area with technical debt:&lt;br /&gt;
&lt;br /&gt;
* long function;&lt;br /&gt;
* large class;&lt;br /&gt;
* duplicated logic;&lt;br /&gt;
* deep nesting;&lt;br /&gt;
* hard-coded configuration;&lt;br /&gt;
* global state.&lt;br /&gt;
&lt;br /&gt;
Use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
tests pass&lt;br /&gt;
   ↓&lt;br /&gt;
small refactor&lt;br /&gt;
   ↓&lt;br /&gt;
tests pass&lt;br /&gt;
   ↓&lt;br /&gt;
commit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 67. Exercise 6 — Logging audit ==&lt;br /&gt;
&lt;br /&gt;
Search for:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
print(&lt;br /&gt;
logger.debug(&lt;br /&gt;
logger.info(&lt;br /&gt;
logger.warning(&lt;br /&gt;
logger.error(&lt;br /&gt;
logger.exception(&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Check that:&lt;br /&gt;
&lt;br /&gt;
* user output intentionally uses &amp;lt;code&amp;gt;print()&amp;lt;/code&amp;gt;;&lt;br /&gt;
* diagnostics use logging;&lt;br /&gt;
* levels are appropriate;&lt;br /&gt;
* errors include context;&lt;br /&gt;
* secrets are never logged.&lt;br /&gt;
&lt;br /&gt;
== 68. Exercise 7 — README installation test ==&lt;br /&gt;
&lt;br /&gt;
Follow the README in a clean environment.&lt;br /&gt;
&lt;br /&gt;
Record every missing step.&lt;br /&gt;
&lt;br /&gt;
Update the README until no undocumented knowledge is required to start the project.&lt;br /&gt;
&lt;br /&gt;
== 69. Exercise 8 — Dependency verification ==&lt;br /&gt;
&lt;br /&gt;
Create a fresh virtual environment.&lt;br /&gt;
&lt;br /&gt;
Install the project using its documented procedure.&lt;br /&gt;
&lt;br /&gt;
Then run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
pytest&lt;br /&gt;
ruff check .&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If used by the project:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
mypy src&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fix dependency or configuration problems.&lt;br /&gt;
&lt;br /&gt;
== 70. Exercise 9 — Repository audit ==&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
git status&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspect the repository for:&lt;br /&gt;
&lt;br /&gt;
* virtual environments;&lt;br /&gt;
* caches;&lt;br /&gt;
* generated output;&lt;br /&gt;
* secrets;&lt;br /&gt;
* large temporary files;&lt;br /&gt;
* local configuration;&lt;br /&gt;
* editor-specific files.&lt;br /&gt;
&lt;br /&gt;
Update &amp;lt;code&amp;gt;.gitignore&amp;lt;/code&amp;gt; if required.&lt;br /&gt;
&lt;br /&gt;
== 71. Exercise 10 — Known limitations ==&lt;br /&gt;
&lt;br /&gt;
Add:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
## Known limitations&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to the README.&lt;br /&gt;
&lt;br /&gt;
List only real limitations of the current implementation.&lt;br /&gt;
&lt;br /&gt;
== 72. Exercise 11 — Release notes ==&lt;br /&gt;
&lt;br /&gt;
Write:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Release candidate: 0.9&lt;br /&gt;
&lt;br /&gt;
Implemented:&lt;br /&gt;
- ...&lt;br /&gt;
&lt;br /&gt;
Fixed:&lt;br /&gt;
- ...&lt;br /&gt;
&lt;br /&gt;
Known limitations:&lt;br /&gt;
- ...&lt;br /&gt;
&lt;br /&gt;
Run:&lt;br /&gt;
- ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 73. Exercise 12 — Acceptance test ==&lt;br /&gt;
&lt;br /&gt;
Execute the complete main workflow.&lt;br /&gt;
&lt;br /&gt;
Record:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
Input:&lt;br /&gt;
Command:&lt;br /&gt;
Expected output:&lt;br /&gt;
Actual output:&lt;br /&gt;
Result: PASS / FAIL&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A failure in the primary workflow should be treated as a high-priority issue.&lt;br /&gt;
&lt;br /&gt;
== 74. Release-candidate requirements ==&lt;br /&gt;
&lt;br /&gt;
By the end of Lab 6:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Requirement&lt;br /&gt;
! Expected state&lt;br /&gt;
|-&lt;br /&gt;
| core functionality&lt;br /&gt;
| complete&lt;br /&gt;
|-&lt;br /&gt;
| P0 defects&lt;br /&gt;
| none known&lt;br /&gt;
|-&lt;br /&gt;
| P1 defects&lt;br /&gt;
| ideally none&lt;br /&gt;
|-&lt;br /&gt;
| tests&lt;br /&gt;
| central functionality and major failures covered&lt;br /&gt;
|-&lt;br /&gt;
| regression tests&lt;br /&gt;
| added for important discovered defects&lt;br /&gt;
|-&lt;br /&gt;
| documentation&lt;br /&gt;
| installation and usage complete&lt;br /&gt;
|-&lt;br /&gt;
| dependencies&lt;br /&gt;
| reproducible in a clean environment&lt;br /&gt;
|-&lt;br /&gt;
| logging&lt;br /&gt;
| temporary debug output removed&lt;br /&gt;
|-&lt;br /&gt;
| repository&lt;br /&gt;
| clean and free of secrets&lt;br /&gt;
|-&lt;br /&gt;
| limitations&lt;br /&gt;
| explicitly documented&lt;br /&gt;
|-&lt;br /&gt;
| demonstration&lt;br /&gt;
| repeatable end-to-end&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 75. Instructor review ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! Area&lt;br /&gt;
! Review question&lt;br /&gt;
|-&lt;br /&gt;
| stability&lt;br /&gt;
| Does the primary workflow work consistently?&lt;br /&gt;
|-&lt;br /&gt;
| completeness&lt;br /&gt;
| Are required features implemented?&lt;br /&gt;
|-&lt;br /&gt;
| testing&lt;br /&gt;
| Are important edge cases tested?&lt;br /&gt;
|-&lt;br /&gt;
| regression&lt;br /&gt;
| Were discovered defects converted into tests?&lt;br /&gt;
|-&lt;br /&gt;
| design&lt;br /&gt;
| Is the architecture still understandable?&lt;br /&gt;
|-&lt;br /&gt;
| documentation&lt;br /&gt;
| Can the project be installed without assistance?&lt;br /&gt;
|-&lt;br /&gt;
| robustness&lt;br /&gt;
| Are predictable failures handled?&lt;br /&gt;
|-&lt;br /&gt;
| release readiness&lt;br /&gt;
| Can the team demonstrate the project reliably?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 76. C/C++ habits to reconsider ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
! C/C++ habit&lt;br /&gt;
! Typical Python project approach&lt;br /&gt;
|-&lt;br /&gt;
| rely mainly on compile success&lt;br /&gt;
| verify tests, linting and runtime behavior&lt;br /&gt;
|-&lt;br /&gt;
| test manually only at the end&lt;br /&gt;
| maintain regression tests continuously&lt;br /&gt;
|-&lt;br /&gt;
| treat documentation as optional&lt;br /&gt;
| document installation, configuration and execution&lt;br /&gt;
|-&lt;br /&gt;
| assume the developer machine represents deployment&lt;br /&gt;
| verify in a clean virtual environment&lt;br /&gt;
|-&lt;br /&gt;
| leave debug output in code&lt;br /&gt;
| use structured logging&lt;br /&gt;
|-&lt;br /&gt;
| keep redesigning until submission&lt;br /&gt;
| stabilize architecture before final delivery&lt;br /&gt;
|-&lt;br /&gt;
| add features until the last moment&lt;br /&gt;
| freeze core features and focus on reliability&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 77. Feature freeze ==&lt;br /&gt;
&lt;br /&gt;
After Lab 6, the project should enter a practical &amp;#039;&amp;#039;&amp;#039;feature freeze&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
This means:&lt;br /&gt;
&lt;br /&gt;
* no major architecture changes;&lt;br /&gt;
* no unnecessary new dependencies;&lt;br /&gt;
* no large experimental features;&lt;br /&gt;
* focus on defects;&lt;br /&gt;
* focus on documentation;&lt;br /&gt;
* focus on final demonstration reliability.&lt;br /&gt;
&lt;br /&gt;
Small low-risk improvements may still be made.&lt;br /&gt;
&lt;br /&gt;
== 78. Final preparation order ==&lt;br /&gt;
&lt;br /&gt;
A useful order is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
critical defects&lt;br /&gt;
     ↓&lt;br /&gt;
required features&lt;br /&gt;
     ↓&lt;br /&gt;
tests&lt;br /&gt;
     ↓&lt;br /&gt;
documentation&lt;br /&gt;
     ↓&lt;br /&gt;
clean installation&lt;br /&gt;
     ↓&lt;br /&gt;
demo preparation&lt;br /&gt;
     ↓&lt;br /&gt;
optional polish&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Do not prioritize presentation polish while critical project defects remain.&lt;br /&gt;
&lt;br /&gt;
== 79. Summary ==&lt;br /&gt;
&lt;br /&gt;
Lab 6 is primarily a stabilization laboratory.&lt;br /&gt;
&lt;br /&gt;
The project should move from:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;It basically works.&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
&amp;quot;It can be installed,&lt;br /&gt;
tested,&lt;br /&gt;
run,&lt;br /&gt;
demonstrated,&lt;br /&gt;
and understood&lt;br /&gt;
by another person.&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The central idea is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
A release candidate is not simply code with all planned features. It is software whose behavior, dependencies, limitations and execution procedure are sufficiently controlled to be demonstrated and evaluated reliably.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 80. Preparation for Lab 7 ==&lt;br /&gt;
&lt;br /&gt;
Before the final laboratory:&lt;br /&gt;
&lt;br /&gt;
# freeze the main feature set;&lt;br /&gt;
# fix remaining critical defects;&lt;br /&gt;
# run the complete automated test suite;&lt;br /&gt;
# perform a clean-environment installation;&lt;br /&gt;
# verify the README;&lt;br /&gt;
# document known limitations;&lt;br /&gt;
# prepare a stable demonstration dataset or scenario;&lt;br /&gt;
# ensure the demonstration does not depend on unavailable external resources;&lt;br /&gt;
# prepare a concise architecture explanation;&lt;br /&gt;
# prepare to explain one important design decision;&lt;br /&gt;
# prepare to explain one significant technical difficulty.&lt;br /&gt;
&lt;br /&gt;
In &amp;#039;&amp;#039;&amp;#039;Lab 7&amp;#039;&amp;#039;&amp;#039;, each team will perform the final demonstration, code walkthrough and technical discussion.&lt;/div&gt;</summary>
		<author><name>Andrei.ulmamei</name></author>
	</entry>
</feed>