Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Resume, Portfolio & GitHub Profile  Module 6 – Portfolio projects

Writing a project case study

How to write a portfolio case study that a reader takes in within two minutes: the problem, constraints, approach, trade-offs, results and credits.

  • Intermediate
  • 20 minutes
  • Examples run with Python 3.14.8, Node.js 24.21.0 and Pyodide 314.0.7
  • By MySmartCoPilot
Free core, Pro depth: 6 of 20 minutes free
Free: A case study tells the reasoning a README leaves out · Write it in layers, because readers stop early. With a pass: 3 in-depth parts and 3 interview answers, about 14 minutes.

What you will learn

  • Structure a case study: problem, constraints, approach, trade-offs, results, next steps
  • Add diagrams and screenshots with alt text that says what they show
  • Name teammates, libraries and AI help, and claim only your own part
  • Write in layers for a reader who has two minutes

Before you start

GitHub’s tutorial for job seekers expects a hiring manager to look at a project for a couple of minutes, and a case study of 700 words takes three and a half minutes to read at 200 words a minute. Many readers stop before the end, so a case study has to work for them too.

This lesson writes one for Meera’s canteen queue tracker: the parts a case study needs and the question each part answers, written in layers so that its first 30 words already hold the result.

A case study tells the reasoning a README leaves out

Open the canteen tracker’s repository and its README does what GitHub’s tutorial asks of one: it lists what the project can do, gives the steps to install and start it, shows a demo and explains how to run its tests. An interviewer’s questions start where it stops. Why a token queue and not a second counter? Why SQLite? How was the wait measured? A case study: A short account of one project for a reader deciding whether to interview you: the problem and who had it, the constraints, the approach, the trade-offs, the results against a baseline and the next steps. answers them: it is the project’s reasoning, written down for a reader who was not there.

MySmartCoPilot’s template has seven parts, in this order, in 400 to 900 words:

Part The question it answers
Summary line What is it, and what did it achieve?
Problem Who had which problem, and how big was it?
Constraints What limited the solution: hardware, time, money, data?
Approach What was built, how does it fit together, and which part was yours?
Trade-offs Which choices were made, against which alternatives, and at what cost?
Results What changed, against what baseline, in which unit?
Next steps What would you really do next, and why?

Four things travel with the parts. Every image gets alt text: A short text that stands in for an image: screen readers read it aloud, and it shows when the image cannot load. It says what the image shows. that says what it shows. A credits section names each teammate’s part, every library and any AI help. Work you cannot show, such as an internship’s internal system, is described in general terms, with ranges in place of confidential figures. And the last line links the code.

Key idea

A README says how to run a project; a case study says why it was built that way and what it changed, in seven parts that a reader can scan in order.

Checkpoint

Check: The seven parts of a case study

  1. Question 1 of 2 An interviewer asks why the canteen tracker used a token queue rather than a second counter. Which document should already answer that?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: The case study, whose job is the reasoning behind the project

    The README tells a visitor how to use the project. The interviewer's questions start where it stops, and the case study answers them: the problem, the constraints, the approach and the trade-offs behind it.

  2. Question 2 of 2 A case study says: "We kept the queue in a spreadsheet file rather than a database, which made backups easy but allowed only one editor at a time." Which part of the template does this sentence belong to?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Trade-offs

    The template's Trade-offs part answers which choices were made, against which alternatives, and at what cost. A sentence with all three, as this one has, belongs there.

Write it in layers, because readers stop early

At a reading pace of 200 words a minute, a reader who gives your project two minutes reads 400 words. Write for that reader first, in three layers: a summary line of at most 30 words with the result; a card of up to 120 words for your portfolio page, with the problem, your part, the result and the link; and the full case study for the reader who stays. Step through what each reader takes away:

Interactive · stage by stage Three layers, for readers who stop at different points Step through what a reader takes away from each layer of Meera's case study, and where a reader with less time stops.
Three layers, for readers who stop at different points, step 5 of 5. Showing 1. Summary line, 2. The card, 3. The full case study, The code and the demo. In focus: The code and the demo.back to the list1. Summary line29 words, about 9 s2. The card102 words, about 31 s3. The full case study400–900 words, 2–4.5 minThe code and the demothe link at the end

The drawing shows the whole scene; its 5 steps are listed below.

Every step as text
  1. The summary line. A reader scanning Meera's portfolio page meets the summary line first, 29 words read in about 9 seconds. It names the project and its result, the wait falling from 14 to 6 minutes, so even this reader leaves with the point.
  2. The card. A reader who wants more reads the card, 102 words in about 31 seconds. It adds the problem, Meera's own part and the link, which is enough to decide whether the project is worth opening.
  3. A reader with less time. A reader with less time stops after the card and goes back to the list. Everything they needed to remember was already in the first two layers.
  4. The full case study. A reader who stays opens the full case study. At 200 words a minute, two minutes cover 400 words, so the problem, the constraints and the approach come first and the details later.
  5. The code. The case study ends with the link. The reader opens the repository with the questions the case study raised, such as how the wait was measured, and the README and tests answer them.

The program measures Meera’s first two layers, and checks that each one carries the result with its unit and that the card carries the link:

A summary line and a card, measured Python · layers/layers.py
# The first two layers of a case study for Meera's canteen queue tracker: a summary line and a card for her portfolio
# page. The program counts the words of each layer, gives its reading time at an assumed pace of 200 words a
# minute and checks that the layer carries the result, with its unit, and, on the card, the link.
# Meera, her project and its address are invented. Press Edit, write your own layers in LAYERS, and run it again.
import re

WORDS_A_MINUTE = 200
RESULT = re.compile(r"\b\d+(?:\.\d+)? to \d+(?:\.\d+)? (?:minutes|seconds|ms|%)")
LINK = re.compile(r"github\.com/[\w.-]+/[\w.-]+")

LAYERS = {  # name: (most words, needs the link, text)
    "summary line": (30, False, "Canteen queue tracker: a token queue for my college canteen, built with two "
                                "classmates in Flask and SQLite, that cut the average lunch-hour wait from 14 to 6 "
                                "minutes."),
    "card": (120, True, "Canteen queue tracker · Flask, SQLite · with two classmates. The college canteen sells about "
                        "450 lunches a day from one counter, and at lunch the queue took 14 minutes. We built a token "
                        "queue: students take a numbered token on a tablet and sit down until the counter screen "
                        "calls them. My part was the queue itself and its 31 tests. Over four weeks of use, the "
                        "average lunch-hour wait fell from 14 to 6 minutes, measured from the app's own log against "
                        "a week of timing by hand before it. Next: a pause button the staff asked for. Code and "
                        "demo: github.com/meera-iyer-example/canteen-queue"),
}


def words(text):
    return re.findall(r"[\w'’./:-]+", text)


for name, (most, needs_link, text) in LAYERS.items():
    n = len(words(text))
    checks = [f"result with its unit: {'yes' if RESULT.search(text) else 'missing'}"]
    if needs_link:
        checks.append(f"link: {'yes' if LINK.search(text) else 'missing'}")
    over = "" if n <= most else f" (over the limit of {most})"
    print(f"{name}: {n} words{over}, {round(n * 60 / WORDS_A_MINUTE)} s to read · {' · '.join(checks)}")

print(f"full case study: 400 to 900 words, {400 / WORDS_A_MINUTE} to {900 / WORDS_A_MINUTE} min to read")
print(f"what a reader gets through in two minutes: {2 * WORDS_A_MINUTE} words")

Output

summary line: 29 words, 9 s to read · result with its unit: yes
card: 102 words, 31 s to read · result with its unit: yes · link: yes
full case study: 400 to 900 words, 2.0 to 4.5 min to read
what a reader gets through in two minutes: 400 words

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 layers.py

Both layers fit their limits: 29 words in about 9 seconds, and 102 words in about 31. The summary line names the result, the wait falling from 14 to 6 minutes, so a reader who stops there still has it. The full 400 to 900 words take 2 to 4.5 minutes, so the problem and the approach come before the detail.

Saving the result for the end

Wrong: a case study that opens with the tech stack and states the result in its last paragraph. Right: the result in the summary line, then again in Results with its baseline and how it was measured. A reader who stops after two minutes never reaches the last paragraph.

Checkpoint

Check: Writing in layers for readers who stop early

  1. Question 1 of 2 What does this lesson ask of a case study's summary line?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: At most 30 words, naming the project and its result with the unit

    Write the first layer for the reader who reads least: at most 30 words that name the project and what it achieved, with the unit, as in "cut the average lunch-hour wait from 14 to 6 minutes".

  2. Question 2 of 2 At 200 words a minute, how many words does a reader who gives your project two minutes get through?

    Type a number.

    Show the answer: Question 2 of 2

    Answer: 400 words

    Two minutes at 200 words a minute is 400 words, the lower end of the template's 400 to 900. That is why the summary line, the card, the problem and the approach come first.

The canteen tracker's case study, written section by section Pro: opens with a Pro, Premium or Ultimate pass

This part writes the full case study of the canteen queue tracker from the records the project left behind. Each section gets the version a hurried writer produces, the version a reader can check, and the record behind its numbers.

In this part:

  • From the records to a problem and an approach a reader believes
  • Trade-offs written as decisions with a cost
  • Results with a baseline, a unit and their limits

1 diagram · 1 runnable example (Python, case_study.md, draft.md) · about 6 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Alt text, credits and work you cannot show Pro: opens with a Pro, Premium or Ultimate pass

Three things decide whether a reader trusts the rest of a case study: what its images say to someone who cannot see them, who it says did the work, and how it handles work it cannot show. This part writes each one, the weak version beside the one a reader can trust.

In this part:

  • Alt text that says what an image shows and why it matters
  • Credits that name each person’s part, every library and any AI help
  • Work you cannot show: the problem in general terms, figures as ranges

about 5 minutes

Opening this part with your pass…Pro part. It opens with the same pass as the part above.

A rubric for judging a case study, level by level Pro: opens with a Pro, Premium or Ultimate pass

A rubric turns “it reads well” into marks a writer can act on. This part scores the hurried draft and the finished canteen case study against five criteria, and names the edit that moved each mark.

In this part:

  • Five criteria, each marked from 0 to 2
  • The two drafts scored, and the edit behind each mark

about 3 minutes

Opening this part with your pass…Pro part. It opens with the same pass as the part above.

Practise: fix a case study draft

Arjun, the invented student of this track’s project entries, wrote a hurried case study for his library seat booker. Fix it from his records; the sample tests check the summary line, the seven sections, the length, the numbers, the result, the alt text, the credits and the link:

Exercise · Medium · Python

Fix a case study draft from the project's records

Arjun, the invented student of this track's project entries, wrote a case study for his library seat booker in a hurry. It is the Markdown text in CASE_STUDY in case_study.py. His records say what is true:

  • The problem: the college library's reading room has 120 seats, booked by writing a name in a register at the desk. In the semester before the project, 31 % of booked seats were never used, while students were turned away.
  • The constraints: one desk computer in the library, students on their phones, no budget, and the librarian wanted no phone numbers stored.
  • The approach: a Django site with a PostgreSQL database. A student books a seat for a 2-hour slot, checks in by scanning a code on the desk, and a booking with no check-in is released 15 minutes after its slot starts.
  • One trade-off: a seat is released after 15 minutes rather than 30, so empty seats come back quickly; the cost is that a student who is more than 15 minutes late loses the seat.
  • The result: over one semester, no-shows fell from 31 % to 12 %, counted from the site's check-in log against the register of the semester before.
  • Credits: he built it alone with Django and PostgreSQL, and used no AI help. Code: https://github.com/arjun-mehta-example/seat-booker

Fix the draft so that:

  • it opens with a summary line of at most 30 words, before the first heading, that names the result with its unit;
  • it has the seven sections of this lesson as ## headings, in order: Problem, Constraints, Approach, Trade-offs, Results, Next steps, Credits;
  • its text, without the image and the link, is 400 to 900 words long, and every number in it comes from his records;
  • the Results section gives the result with its baseline and its unit;
  • every image has alt text of at least five words that says what the image shows;
  • the Credits section has three lines that start "Team:", "Libraries:" and "AI help:";
  • it links the code.

Starter code · case_study.py

# Arjun's case study draft, written in a hurry. Fix it from his records in the prompt.
CASE_STUDY = """# Library seat booker

A seat booking site I made for my college library. It works really well and students like it.

## Problem

The reading room of our college library was always full during exams, but many seats had a bag on them and nobody in
them. Students booked seats by writing their name in a register at the desk, and there was no way to know whether
anyone would come. Students who needed a seat were turned away at the door while booked seats stood empty for
hours, and the librarian spent a lot of time settling arguments about who had booked what. I wanted to see
whether a simple booking site could free up those seats without making more work for the library staff.

## Approach

I built a website where a student picks a seat and a time slot. When the student arrives, they check in at the desk,
and the site marks the seat as taken. If nobody checks in, the seat goes back into the pool so that someone else can
book it. The librarian has a page that shows every seat, its bookings for the day and which ones are checked in, and
can release a seat by hand if something goes wrong. I kept the pages simple so that they load quickly on a phone and
work on the old computer at the desk.

![screenshot](images/seat-map.png)

## Results

No-shows went down a lot and the librarian was happy with it. Students also stopped arguing at the desk about who
had booked a seat first.

## Next steps

I would like to add a waiting list, so that a student is told by e-mail when a seat comes free, and a weekly report
for the librarian that shows how full the reading room was at each hour of the day.
"""
The sample tests · test_case_study.py
import re

from case_study import CASE_STUDY

SECTIONS = ["Problem", "Constraints", "Approach", "Trade-offs", "Results", "Next steps", "Credits"]
RECORDS = (
    "120 seats; 31 % of booked seats never used; a 2-hour slot; released 15 minutes after its slot starts, rather "
    "than 30; no-shows fell from 31 % to 12 % over one semester"
)
NUMBER = re.compile(r"(?<![\w.,/-])\d+(?:\.\d+)?(?![\w/])")
IMAGE = re.compile(r"!\[([^\]]*)\]\([^)]*\)")
LINK = "https://github.com/arjun-mehta-example/seat-booker"
RESULT = re.compile(r"from \d+(?:\.\d+)? ?(?:%|minutes|seconds)[^.]*?\bto \d+(?:\.\d+)? ?(?:%|minutes|seconds)")


def section(name):
    parts = re.split(r"^## ", CASE_STUDY, flags=re.M)
    for part in parts[1:]:
        title, _, body = part.partition("\n")
        if title.strip() == name:
            return body
    return ""


def prose():
    text = IMAGE.sub(" ", CASE_STUDY).replace(LINK, " ")
    return re.findall(r"[\w'’.-]+", text)


def test_summary_line_names_the_result():
    """opens with a summary line of at most 30 words that names the result with its unit"""
    before = CASE_STUDY.split("\n## ", 1)[0]
    lines = [line for line in before.splitlines() if line.strip() and not line.startswith("#")]
    assert lines, "write a summary line before the first heading"
    summary = " ".join(lines)
    assert len(summary.split()) <= 30, f"the summary line has {len(summary.split())} words: at most 30"
    assert re.search(r"\d+ ?%", summary), "the summary line names the result with its unit"


def test_seven_sections_in_order():
    """has the seven sections as ## headings, in order"""
    headings = [h.strip() for h in re.findall(r"^## (.+)$", CASE_STUDY, flags=re.M)]
    assert headings == SECTIONS, f"the headings are {headings}: they should be {SECTIONS}"


def test_length_and_numbers_from_the_records():
    """is 400 to 900 words long, and every number comes from the records"""
    words = prose()
    assert 400 <= len(words) <= 900, f"{len(words)} words: write 400 to 900"
    allowed = set(NUMBER.findall(RECORDS))
    found = set(NUMBER.findall(IMAGE.sub(" ", CASE_STUDY).replace(LINK, " ")))
    assert found <= allowed, f"numbers that the records do not hold: {sorted(found - allowed)}"


def test_result_with_baseline_and_unit():
    """gives the result in Results with its baseline and its unit"""
    assert RESULT.search(section("Results")), "write the result as 'from <baseline> to <result>', with the unit"


def test_alt_text_and_credits_and_link():
    """gives every image useful alt text, credits in three lines, and the link to the code"""
    for alt in IMAGE.findall(CASE_STUDY):
        assert len(alt.split()) >= 5, f"the alt text '{alt}' does not say what the image shows"
    credits = section("Credits")
    for start in ("Team:", "Libraries:", "AI help:"):
        assert re.search(rf"^\s*(?:- )?{re.escape(start)}", credits, flags=re.M), f"the credits need a line '{start}'"
    assert LINK in CASE_STUDY, "link the code"
A hint

Work through the records one at a time and give each its section, in the order of the list. Two sections are missing, Constraints and Trade-offs, and so is Credits. For the summary line, start from the project's name and end with the result, as in "Library seat booker: … cut no-shows from 31 % to 12 % in one semester."

The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.

Then answer questions on the parts and the layers of a case study, starting with the idea you have answered worst so far:

Practice that adapts to you

Practise this lesson

6 questions about 5 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 6 In this lesson's template, which part comes right after the problem?

    Choose one answer.

    Show the answer: Question 1 of 6

    Answer: Constraints

    The seven parts run summary line, problem, constraints, approach, trade-offs, results and next steps, with the credits and the link to the code at the end.

  2. Question 2 of 6 Which of these does GitHub's tutorial for job seekers list for a helpful README? Choose every one.

    Choose every answer that is right.

    Show the answer: Question 2 of 6

    Answer:

    • Instructions on testing the code
    • An example or a demo
    • A list of key features
    • How to set up and run the project

    GitHub's tutorial lists key features, setup and run steps, an example or demo, and testing instructions. The case study adds the reasoning: the problem, the constraints, the trade-offs and the results.

  3. Question 3 of 6 Meera's first full draft has all seven parts and runs to 1,400 words. What does the lesson's template ask her to do?

    Choose one answer.

    Show the answer: Question 3 of 6

    Answer: Cut it to 900 words or fewer, keeping every part and the result up front

    The template asks for 400 to 900 words. Cut the detail inside each part, not the parts themselves, and keep the result in the summary line, where readers who stop early still meet it.

  4. Question 4 of 6 What does the card, the second layer of up to 120 words, carry? Choose every one.

    Choose every answer that is right.

    Show the answer: Question 4 of 6

    Answer:

    • The result with its unit
    • The problem
    • The link to the code
    • Your own part

    The card is the layer for the portfolio page: the problem, your part, the result and the link, in up to 120 words. Meera's has 102.

  5. Question 5 of 6 At 200 words a minute, how many minutes does a case study of 900 words take to read?

    Type a number.

    Show the answer: Question 5 of 6

    Answer: 4.5 minutes (anything from 4.45 to 4.55 counts)

    900 words divided by 200 words a minute is 4.5 minutes, more than the couple of minutes GitHub's tutorial expects a hiring manager to spend on a project. The first layers must carry the result.

  6. Question 6 of 6 A recruiter skims your portfolio page and gives each project about 30 seconds. Where must your project's result be for this reader?

    Choose one answer.

    Show the answer: Question 6 of 6

    Answer: In the summary line, and again on the card

    At 200 words a minute, 30 seconds is about 100 words: the summary line and most of the card. The result must be in both, so every reader leaves with it, however early they stop.

Interview questions

Warm-up (fresher to mid-level): How does a project’s README differ from its case study?

The README tells a visitor how to use the project: what it does, how to install and start it, where to see it working, and how to test it. The case study tells a reader why it was built that way and what it changed: the problem, the constraints, the approach, the trade-offs with their costs, the results against a baseline and the next steps. The README serves someone who wants to run the code; the case study serves someone deciding whether to interview you, so it starts with the result and says which part was yours.

Three questions of this module’s bank go further:

  1. Fresher to mid

    Your strongest project was built during an internship, and its code, data and figures are confidential. How do you write a case study that a reader can trust, and what do you say when an interviewer asks for the numbers?

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Fresher to senior

    You used an AI assistant for parts of your project's code. How do you say so in the case study, and what do you answer when an interviewer asks which parts it wrote and how you checked them?

    Model answer, Pro. First step and follow-ups

  3. Fresher to mid

    A hiring manager says they read your case study for two minutes and still could not tell what you built or what it achieved. How do you rewrite its first 150 words, and how do you check the rewrite?

    Model answer, Pro. First step and follow-ups

Flashcards · 6 cards

Recall it, then check

Say the answer to yourself before you look: recalling it is what makes it stick.

  1. How does a project's case study differ from its README?

    The README tells a visitor how to use the project: what it does and how to install, start and test it. The case study tells someone deciding whether to interview you why it was built that way and what it changed.

  2. What are the seven parts of a case study, in order?

    A summary line, the problem, the constraints, the approach, the trade-offs, the results and the next steps, in about 400 to 900 words.

  3. What should the trade-offs and results parts of a case study answer?

    Trade-offs: which choices were made, against which alternatives, and at what cost. Results: what changed, against what baseline, and in which unit.

  4. Which four things go with the parts of a case study?

    Alt text on every image saying what it shows; credits naming each teammate's part, the libraries used and any AI help; general terms and ranges for work you cannot show; and a link to the code at the end.

  5. What are the three layers of a case study, and how long is each?

    A summary line of at most 30 words with the result; a card of up to 120 words with the problem, your part, the result and the link; and the full case study, 400 to 900 words, for readers who stay.

  6. How much of a case study does a reader who gives it two minutes read?

    About 400 words at 200 words a minute. The result belongs in the summary line, and the problem and approach before the detail, because a result kept for the last paragraph may never be seen.

Key takeaways

  • A README says how to run a project; a case study says why it was built that way and what it changed, in seven parts from the summary line to the next steps.
  • Write in layers: a summary line of at most 30 words with the result, a card of up to 120 words, then the full case study of 400 to 900 words.
  • A reader who gives a project two minutes reads about 400 words, so the result and the problem come first.

Terms in this lesson

alt text
A short text that stands in for an image: screen readers read it aloud, and it shows when the image cannot load. It says what the image shows.
case study
A short account of one project for a reader deciding whether to interview you: the problem and who had it, the constraints, the approach, the trade-offs, the results against a baseline and the next steps.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.