Grade by Grade
B. Software Development · Software Development: Problem Solving, Design, Testing and the Life Cycle

Mini Project: Building a Program Through the Whole Life Cycle

B4.1 B4.2 B4.4 B4.6 B1.2 B1.3 B2.1 B2.5About 75 minutes
Learning goals
  • I can take a small project through every phase of the life cycle and produce each phase's product.
  • I can turn a client's request into a specification, a design and a skeleton, then into a working, user-friendly program.
  • I can test the finished program against a test plan and debug what fails.
  • I can track the project with a Gantt chart and report its status in writing.

Words to know

deliverable
A product handed to the client or teacher at a milestone: the specification, the design, the program, the test results, the user guide.
scope
What the project will and will not include. Keeping scope clear stops a project from growing out of control.
change request
A written request from the client to change the specification after it was approved. It is assessed for its effect on time and cost.
user guide
Short documentation that explains to users how to run and use the program.
version
A numbered release of the program. Changes not in this version's scope can be planned for the next one.
handover
The implementation step where the finished program, guide and test results are given to the client.

Putting it all together

This lesson follows a small project from first conversation to finished program, using every tool from this unit. Read it as a model, then use the activity to run your own project the same way. (The Ontario curriculum asks you to apply a life-cycle model to a software development project, so this is the heart of the unit.)

The request: The school's Community Service Club is running a winter coat drive. The club president, Priya, says: "We need something to keep track of how many coats each homeroom brings in, and who's winning." Jordan and Mei, two Grade 11 students, take the job. They have 10 school days.

Phase 1 and 2: Problem definition and analysis

Problem statement: "Club volunteers need to record coat donations by homeroom and see a ranked leaderboard and the total, during lunch-hour drop-offs."

Jordan and Mei interview Priya (dialogue) and send a three-question survey to the volunteers. They learn: one laptop at the drop-off table; volunteers type, not homeroom students; a single drop-off is never more than about 50 coats; homerooms are written like "11B" but people type "11b" too; no internet needed.

Specification (version 1):

  1. A menu offers: add coats, show leaderboard, quit.
  2. Add coats asks for a homeroom and a number of coats from 1 to 50. Homeroom names ignore case and extra spaces ("11b" = "11B").
  3. Invalid numbers are rejected with a friendly message and asked again; the program never crashes.
  4. The leaderboard lists homerooms from most to fewest coats, with places, and the total of all coats.
  5. Non-functional: runs in Python 3 on the club laptop, no extra installs.

Out of scope (version 1): saving data to a file, printing certificates.

Priya signs the spec on day 2: the first milestone.

Phase 3: Design

IPO: Input: menu choices, homeroom names, coat counts. Processing: validate counts, add to the right homeroom (or create it), sort for the leaderboard, total. Output: messages, the leaderboard, the total.

Structure chart: main() runs the menu loop and calls three modules. leaderboard() is kept separate from show_leaderboard() so the ranking can be tested without printing (modularity).

Data design: two parallel lists, rooms and counts, where counts[i] belongs to rooms[i].

main()get_count()add_donation()show_leaderboard()leaderboard()menu loop, input() andmessages live in main()get_count: prompt ↓ n ↑add_donation: rooms, counts, room, n ↓returns sorted[count, room] pairs
The structure chart for the coat-drive program. main() owns the menu and messages; each module has one job. The notes show the data passed down (↓) and returned (↑).

Plan: Jordan and Mei split the work (teamwork, divide and conquer) and draw a Gantt chart. Mei builds the menu and messages and writes the user guide; Jordan builds the calculation modules. Both test.

012345678910dayInterview client, write specDesign: IPO, structure chart, testsSkeleton + get_count()add_donation(), leaderboard()Menu and messages (Mei)User guide (Mei)Test plan run + debuggingDemo and hand overspec approvedcode completedelivered
The project's Gantt chart. Highlighted bars form the critical path; Mei's two tasks have slack. Diamonds mark the three milestones.
#ScenarioInputExpectedActualPass/Fail
1count, normal4accepted, returns 4
2count, lower boundary1accepted
3count, below range0"Please enter between 1 and 50 coats."
4count, upper boundary50accepted
5count, above range51range message, ask again
6count, not a numberfive, or blank"Please type a whole number, like 3."
7same room, different case11b then 11Bone room, counts added
8leaderboard order9A: 12, 10C: 59A first, then 10C
9leaderboard, no data(nothing added)the heading, then only "Total: 0 coats"
10invalid menu choice7"Please type 1, 2 or 3."
The test plan, written during design, before any code exists. The Actual and Pass/Fail columns are filled in during testing.

Phase 4: Writing code from a skeleton

Jordan first writes a skeleton: main() with the menu, and stubs for the three modules, so the program runs on day 4. Then each stub is filled in and tested on its own. Here is the finished program.

def get_count(prompt):
"""Ask until the user types a whole number from 1 to 50."""
while True:
text = input(prompt).strip()
try:
n = int(text)
except ValueError:
print("Please type a whole number, like 3.")
continue
if n < 1 or n > 50:
print("Please enter between 1 and 50 coats.")
else:
return n
def add_donation(rooms, counts, room, n):
"""Add n coats to a homeroom, creating it if it is new."""
room = room.strip().upper()
for i in range(len(rooms)):
if rooms[i] == room:
counts[i] = counts[i] + n
return
rooms.append(room)
counts.append(n)
def leaderboard(rooms, counts):
"""Return [count, room] pairs, most coats first."""
pairs = []
for i in range(len(rooms)):
pairs.append([counts[i], rooms[i]])
pairs.sort(reverse=True)
return pairs
def show_leaderboard(rooms, counts):
print("--- Coat Drive Leaderboard ---")
place = 1
for pair in leaderboard(rooms, counts):
print(f"{place}. Room {pair[1]}: {pair[0]} coats")
place = place + 1
print("Total:", sum(counts), "coats")
def main():
rooms = []
counts = []
while True:
print("1. Add coats 2. Leaderboard 3. Quit")
choice = input("Choose 1-3: ").strip()
if choice == "1":
room = input("Homeroom (e.g. 11B): ")
n = get_count("Number of coats (1-50): ")
add_donation(rooms, counts, room, n)
print("Thank you! Recorded.")
elif choice == "2":
show_leaderboard(rooms, counts)
elif choice == "3":
print("Goodbye!")
break
else:
print("Please type 1, 2 or 3.")
main()

Sample run: add 4 coats for 11b; add coats for 12A with two bad counts (five, then 60) before 7; add 5 more for 11B; show the leaderboard; quit. The leaderboard shows 1. Room 11B: 9 coats, 2. Room 12A: 7 coats and Total: 16 coats.

Phase 5: Testing and debugging

The team runs the test plan. Because the modules return values, most tests are automated by calling the functions directly. For example, add_donation(rooms, counts, ' 10C ', 2) after '10c' with 3 coats should leave one room, 10C, with 5 coats. Every failure is investigated with the debugging process.

Worked example

Example: Test 8 fails

On day 7, test 8 (9A has 12 coats, 10C has 5; expected order 9A then 10C) fails: the program shows 10C first. Debug it.

  1. Reproduce: call leaderboard(['10C', '9A'], [5, 12]) directly. It returns [[5, '10C'], [12, '9A']] every time.
  2. Locate: a debug print of pairs just before return shows the list is sorted, but from smallest to largest.
  3. Understand: pairs.sort() sorts in ascending order by default, so the homeroom with the fewest coats comes first.
  4. Fix: change it to pairs.sort(reverse=True), then remove the debug print.
  5. Retest: rerun all ten tests. All pass on day 9. Testing also shows something the spec never covered: two homerooms tied at 6 coats appear as 11B before 11A, because equal counts are then compared by name, in reverse. It is not wrong according to the spec, so the team records it for later.

One argument fixed the bug; rerunning every test confirmed nothing else broke.

Status report at the end of day 6

Status report 2: Coat Drive Tracker (end of day 6) · Team: Jordan and Mei

Milestones: Spec approved (day 2) ✓ on time. Next: code complete (day 7).

Work completed: skeleton; get_count() (passes tests 1-6); menu and messages; add_donation().

In progress / outstanding: leaderboard() (half done, due day 7); user guide (Mei, due day 8); full test run (days 7-9).

Issues and risks: the client asked on day 5 for ties to be shown "fairly". We have recorded it as a change request for version 2, so it will not delay delivery.

Next steps: Jordan finishes leaderboard() by day 7; both run the whole test plan on day 8.

Phases 6 and 7: Implementation and maintenance

Implementation (day 10): the team copies the program to the club laptop, gives the volunteers a one-page user guide (how to start the program, what each menu option does, what the messages mean), demonstrates it, and hands over the test results. Final milestone reached.

Maintenance: after the first week, Priya submits two change requests: show ties in alphabetical order, and save the totals to a file so they survive if the laptop restarts. These go into version 2, which starts the life cycle again with a short analysis, design, code and test round.

Just for fun

A famous programming rule of thumb jokes: "The first 90% of the code takes the first 90% of the time. The remaining 10% takes the other 90% of the time." That is why the Gantt chart has a testing bar, and why it is not optional.

Hands-on activity

Your own mini project

You need: a computer with Python, paper, a "client" (a family member, a friend, a club or a team you belong to) and about 6 to 8 hours spread over one or two weeks.

Choose a project (or propose your own of similar size): a reading log that ranks family members by pages read; a hockey or soccer league standings program (wins 2 points, ties 1); a grocery budget tracker that warns when you are near the limit.

Produce these deliverables, in order:

  1. Problem statement and specification (after interviewing your client), with what is out of scope.
  2. Design: IPO chart, structure chart, pseudocode or a flow chart for the hardest function, and screen designs for the menu and messages.
  3. A Gantt chart with at least 6 tasks and 3 milestones; mark the critical path.
  4. A test plan with at least 10 tests (normal, boundary, invalid), written before coding.
  5. A skeleton, then the finished program, modular, with docstrings and user-friendly prompts and messages.
  6. The completed test plan, with at least one bug report describing how you found the bug (trace table or debug prints).
  7. Two written status reports (one midway, one at the end) and a one-page user guide.
  8. Hand it over to your client and write down one change request for version 2.

What to look for: each deliverable is finished before the next phase depends on it; the program meets every numbered requirement in the spec; tests have specific expected values; status reports use real dates and honest progress.

Your turn

1

Match each product to its phase: specification, user guide, structure chart, bug report, change request.

2

Which requirement in the specification makes "11b" and "11B" the same homeroom, and which line of code meets it?

3

Why did the team keep leaderboard() separate from show_leaderboard()?

4

In the sample run, how many coats does 11B have, and why?

5

What does get_count print for the input 0? For an empty answer?

6

Which tasks in the Gantt chart have slack, and why?

7

Give one reason saving data to a file was put out of scope for version 1.

More practice: warm-up

1

Name the seven phases the project went through.

2

What was the first milestone, and on which day?

3

Which data structure holds the homerooms and their coat counts?

4

What is a change request?

5

Which test in the plan checks an upper boundary?

More practice: on your own

1

What does leaderboard(['10C', '9A'], [5, 12]) return?

2

Write two more tests for the test plan: one for an invalid menu choice typed as a word, and one for a homeroom typed with spaces.

3

The client says halfway through: "Can it also show the homeroom with the fewest coats?" Write a short reply as the team, following good change-request practice.

4

Explain how the coat-drive program shows the principle of modularity.

5

The first version of leaderboard() forgot reverse=True. Which test caught it, and how would the actual result have looked?

Challenge

1

Tied homerooms appear in reverse alphabetical order. Design a fix for version 2 so ties appear alphabetically, still with the most coats first.

2

Write a status-report paragraph (issues and next steps) for this situation: on day 8, Jordan is sick, testing has not started, and the demo is booked for day 10.

3

Version 2 must save the totals to a file. Which phases of the life cycle will that change go through, and name one product of each?

Check your understanding

Quiz

1.

In the project, when was the specification approved?

2.

Why was the test plan written during design?

3.

What does add_donation do when the homeroom already exists?

4.

A feature requested after the spec was approved should usually be:

5.

Which deliverable belongs to the implementation phase?

6.

What does the sample run's leaderboard show as the total?

For parents and teachers

Big idea: This lesson pulls the whole strand together. B4.1 asks students to apply a software development life-cycle model to a project; the project also uses specification techniques (B4.2), a test plan (B4.4), written status reports (B4.6), teamwork (B1.2), the IPO model (B1.3), a skeleton (B2.1) and user-friendly interfaces (B2.5).

How to help: Be the client for your teen's mini project. Have a real conversation about what you need, sign their specification, read their status reports and test the finished program. Ask to see each deliverable before they move on to the next phase.

Common difficulties:

  • Choosing a project that is too big. A small, finished, tested program is worth far more than a large unfinished one.
  • Skipping the specification and test plan to "save time", then running out of time during debugging.
  • Status reports that say "going well" without dates or specifics.
  • Adding features during coding (scope creep) instead of recording them for version 2.