CT 301 — Homework 1 Walkthrough
Homework 1
NUI Hardware Inventory
An inventory system for lab hardware
- Track equipment, consumables, and gear borrowed from others.
- Items can be loaned (and returned), sold, or surplused (retired).
- The program reads two files, applies the changes, writes results to a file, and prints reports.
One idea runs through it all: select a collection of items, then print or act on it.
Three files, in order
make ./inventory <inventory_file> <transactions_file> <output_file>
- inventory file → the starting items, one per line.
- transactions file → the commands to apply, in order.
- output file → where the final inventory is written (created for you).
PRINT/REPORT/GROUP_BY go to the screen; the final state goes to the output file.
Same base, different behavior
| Type | Loanable? | Value | Notes |
|---|---|---|---|
| Equipment | Yes (unless broken) | Depreciates | Owned hardware; has conditions |
| Consumable | No | unit × quantity | Bulk supplies |
| Borrowed | No | 0 | Ours? No. Only returnable |
Each derives from Item and answers the same calls (canLoan, currentValue, attribute, printTo) its own way.
obsolete, broken, and the dates
- obsolete: end-of-life but still works. Informational only, value and loanability unchanged (a Magic Leap 1 still runs).
- broken: doesn't work. Value becomes
0.00and it can't be loaned. - warranty_end / support_end: vendor dates. Past warranty → NoRMA (no return path).
- surplus candidate = broken AND NoRMA (computed): worth retiring.
currentValue() must match exactly
// reference "today" = 2026-06-01
Equipment: broken → 0.00
else base × (1 − 0.20 × fullYears), floor = base × 0.10
Consumable: unit × quantity
Borrowed: 0.00
Grading compares your output exactly, so the value math has to be precise. The obsolete flag and dates do not change value.
Inventory owns; selections borrow
- The
Inventoryowns every item asunique_ptr<Item>, in four lists, one per state. - Selection returns borrowed
Item*pointers. Action moves items between lists. Output prints them. - Commands wrap each transaction verb; they call the matching inventory operation.
transactions file → Command objects → execute() → Inventory ops
A "current selection" carried line to line
- A selection verb sets the current selection (e.g.
BY brand Razer). - An output verb (
PRINT) shows it; an action verb (SURPLUS) acts on it. - After an action, the selection becomes the rejects, what it could not do, so a following
PRINTshows them.
OLDER_THAN 2021-01-01 # select old items SURPLUS # retire them; rejects become the selection IN_STATE OnLoan PRINT # list what is still on loan
Every action looks like this
for (Item* p : items) { if (p->state() != State::InStock || !p->canSurplus()) { rejects.push_back(p); continue; // not allowed } auto owned = extract(inStock_, p->id()); // take ownership out owned->setState(State::Surplus); surplus_.push_back(std::move(owned)); // move into new list } return rejects;
surplus is done for you. sell, loan, return follow the same shape.
What the system must refuse
- A Consumable can never be loaned.
- A broken item can't be loaned.
- An item OnLoan can't be sold or surplused.
- A Borrowed item can't be loaned, sold, or surplused, only returned.
- An item is in exactly one state at a time.
These hold on their own if each action accepts only items in the right starting state and type.
What's provided vs. what you write
Provided
- All headers, the input layer,
main, the makefile. - The three inventory helpers + one worked example (
surplus). PrintCommandas the command example.- Sample data + a starter test file.
You write
Dateoperators.- All of
items.cpp. - The rest of
inventory.cpp. - The remaining command
execute()bodies.
Stubs compile and run out of the box; each has a // remove when you implement this line.
Build clean, run clean
- C++26, GCC 15.2, built with the provided makefile.
- Flags include
-Wall -Wextra -Wpedantic: your code must compile with no warnings. - Sanitizers (
-fsanitize=address,undefined) must report zero issues. - No raw owning pointers,
new,delete,malloc,calloc,realloc, orfree.
With correct unique_ptr use, the sanitizers pass on their own, you write no delete.
Testing is part of the assignment
- A small sample ships with its expected output. Run it and
diffto compare. - A larger sample ships without expected output, reason about correctness yourself.
student_tests.cpphas a few example tests and a TODO list, you add more.
./inventory data/appx_inventory.txt data/appx_transactions.txt myout.txt > mystd.txt diff myout.txt data/appx_output.txt diff mystd.txt data/appx_stdout.txt
100 points, automated
| Component | Pts |
|---|---|
| Compiles cleanly (no warnings) | 5 |
| Runs clean under ASan/UBSan | 10 |
| Bookkeeping actions (add, loan, return, sell, surplus) | 15 |
| Selection, grouping, aggregation | 25 |
| Invariants enforced | 15 |
| Type behavior & value rules | 15 |
| Output & report format | 15 |
| Penalty: raw new/delete/malloc/free | −20 |
| The professor reserves the right to award or deduct points for any aspect of the assignment not explicitly listed above. | — |
A sensible order of attack
- 1.
Dateoperators, then run the build. - 2.
items.cpp:currentValue,attribute,printToper type. Match the sample output. - 3. Inventory selections, then aggregations.
- 4. Actions (copy the
surpluspattern), thenreportandwrite. - 5. Command
execute()bodies (each is one line).
Build and diff against the sample after each step. Read the spec, Appendix A is your target output.
Start early. Test often.
The ownership rules from Part 1 are the whole game. Move, don't copy; borrow, don't own.