Projects¶
Forty pieces of work, in four tiers, where you design rather than follow a brief to the letter.
The labs teach you each technique with a defined target. The projects ask a harder question: given a problem, what should be built, and why that way? That is the actual work of a programmer, and it is the only part of this course that cannot be taught by reading.
No project in this section comes with a complete solution. The mini and intermediate briefs give you the requirements, a design discussion that raises the questions, and checklists strict enough to act as a code review. The advanced and capstone briefs give you the requirements and nothing else. Reading a solution would replace the work with reading.
What is available¶
| Tier | Projects | Size | Effort each | Start after | Where |
|---|---|---|---|---|---|
| Mini | 10 | One idea, 1–3 classes | 2–5 hours | Module 2 | Mini projects |
| Intermediate | 10 | A small system, 4–8 classes | 10–18 hours | Module 8 | Intermediate projects |
| Advanced | 10 | A design you defend, 8–15 classes | 1–3 weeks | Module 12 | Advanced projects |
| Capstone | 10 | A system you own | One term | Module 15 | Capstone options |
The project roadmap sequences all four tiers: what to do after which module, what each tier is testing, and where every concept in the course is first forced rather than merely allowed.
There are also the sixteen sequential module labs and thirty-two practice labs. The practice labs share this page's difficulty labels and the same self-assessment discipline; do them when you need more of one idea, and do the projects when you need to build something without being told how.
Every project brief contains the same seventeen things¶
The tiers differ in scope and in how much design they hand you. They do not differ in what they tell you, because a project you cannot assess yourself against is not a project.
| # | Element | What it is |
|---|---|---|
| 1 | Title | What you are building, in words |
| 2 | Difficulty | Beginner, Intermediate, Advanced or Expert — about design freedom, not size |
| 3 | Estimated effort | So you can plan, not so you can rush |
| 4 | Scenario | The situation, in a paragraph, as a person would describe it |
| 5 | Problem statement | What must be built, and what makes it hard |
| 6 | User requirements | What the people in the scenario want to be able to do |
| 7 | Functional requirements | What the program must do, in checkable terms |
| 8 | Non-functional requirements | Warnings, determinism, money handling, layout — the constraints that get skipped |
| 9 | Suggested features | Optional additions, so you can choose scope deliberately |
| 10 | OOP concepts involved | The concept table, with where each one appears |
| 11 | Suggested design considerations | The questions a good design has to answer — not the answers |
| 12 | Minimum viable version | The smallest thing that counts as done |
| 13 | Intermediate extension | The next increment, if the minimum went quickly |
| 14 | Advanced extension | The increment that turns it into something you would show |
| 15 | Testing checklist | The cases that catch what you would otherwise ship broken |
| 16 | Documentation checklist | What you must be able to explain about what you built |
| 17 | Self-evaluation rubric | Weighted criteria, so your honest self-assessment has a scale |
The ten capstone specifications predate this template and are richer than it: they add actors, use cases, suggested classes, relationships, design constraints, milestones and a capstone-specific report requirement. For those, the equivalent of each element above is mapped out in Capstone options.
The seven integration elements¶
Every intermediate and advanced project must use all seven of these, explicitly and in writing. They are the difference between a project that practises object orientation and a program that happens to be written in C++.
| Element | What "yes" looks like |
|---|---|
| Multiple classes | Four or more types with single responsibilities, none of them a namespace in disguise |
| Relationships between classes | Composition, aggregation and association, each named in an ownership diagram |
| Encapsulation | Every invariant unreachable from outside the class that owns it |
| Inheritance or composition | Used where it genuinely fits, with the alternative considered |
| Polymorphism | At least one operation dispatching through an interface, with no type tags in the core |
| The STL | Containers and algorithms doing the work, each with a stated reason |
| Exception handling | A failure policy: what is refused, what is thrown, what is left unchanged |
Each brief's concept table marks these rows yes, so you can see at a glance which project is
asking for which.
Three advanced projects require design-pattern decisions: every advanced project names at least two patterns that must be justified by a requirement, and one pattern that must be considered and declined, with the reason. Declining a pattern on purpose is marked as highly as using one.
How to approach a project¶
Design before code, and write the design down. A UML class diagram (Module 15) with responsibilities and ownership marked. If you cannot name a class's single responsibility in one sentence, the design is not ready.
Build the smallest thing that runs. Get one object working end to end before adding the second kind of anything. A program that does one thing and runs beats a perfect design that does not compile. Every brief has a minimum viable version for exactly this reason: aim at it first, and treat the extensions as rewards.
Write the second version. Your first design will be wrong somewhere, because that is what first designs are. The valuable skill is noticing where it is wrong once the code exists — which is why the rubric rewards refactoring and reflection, not only the final state. Advanced and capstone projects require a written decision you would reverse; that item is the whole point, not a formality.
Test as you go. Tests are not a formality: they are what make it safe to refactor, and refactoring is what turns a working program into a good one. A test without an assertion is a printout with a nicer name.
Keep the ownership question in front of you. For every class: what does it own, and where is that expressed in the code? Most serious bugs in student projects are lifetime bugs.
Assessment rubric¶
The same criteria apply to every project, weighted towards the larger ones. Use this for self-assessment whether or not anybody else is marking your work.
| Criterion | What an excellent submission shows | Weight |
|---|---|---|
| Correctness | The program does what the brief asks, including stated failure cases; it builds clean with -Wall -Wextra; it does not crash on bad input |
25% |
| Design | Responsibilities are clear and single; relationships are the right kind (composition where ownership, inheritance only for genuine is-a); interfaces are small and const-correct |
20% |
| Object orientation | Encapsulation genuinely protects invariants; inheritance and polymorphism are used where they fit and not where they do not | 15% |
| Resource management | Ownership is explicit and expressed with smart pointers or values; no leaks, no double frees; copy and move semantics are correct or unnecessary | 15% |
| Failure handling | Errors are detected and reported; invalid data from files or input does not corrupt state; exceptions do not leak resources | 10% |
| Code quality | One style applied consistently: names that say what a thing is, formatting that matches the code around it, comments that explain why rather than restating what, and no dead code | 5% |
| Documentation | A UML class diagram matching the code; a short design report that explains the decisions and names what you would change | 5% |
| Testing | Invariant, boundary and failure cases covered; tests actually assert behaviour rather than printing it | 5% |
Each project brief carries its own weighted rubric as well, adapted to what that project is for. When the two disagree, the project's own rubric is the more specific one — and both are the same kind of judgement.
Capstone-specific requirements¶
The capstone additionally requires:
- [ ] A factory for creating items, a strategy for lending or fine policy, and an observer for notifications — each with a written justification of why the pattern was warranted
- [ ] Persistence: the catalogue loads on start and saves on exit, and a corrupted or hand-edited file is handled without crashing
- [ ] A multi-file layout using namespaces, with the build command documented
- [ ] A save → load round trip demonstrated to preserve data exactly
- [ ] A design report that includes one decision you would reverse, with the reason
That last item is not a trick. Being able to say what is wrong with your own work is the most reliable sign that you understand it.
Submitting and reviewing¶
If you are studying this course for credit, your institution's submission rules apply. If you are studying independently, the useful discipline is to review your own work against the rubric above, honestly, before reading any reference solution.
A short self-review template:
Project:
Does it build with -Wall -Wextra with no warnings? yes / no
What owns what, in one line per resource:
The invariant my design protects, and where:
The decision I would reverse, and why:
What I could not get working, and what I tried:
Answering the last line honestly is worth more than a clean-looking submission.
Related: Project roadmap · Mini projects · Intermediate projects · Advanced projects · Capstone options · Labs · Practice assessments