1. Reference Guide

Key Topics


Term Definition Example
System reliability A program performs as expected, under stated conditions, without failure. Thermostat gives correct status for every valid temperature
Edge case An input at or beyond the limits of what is valid. 0, -400, "", null, Double.NaN
Guard clause A check at the top of a method that rejects invalid input before anything else runs. if (temp < 50 \|\| temp > 90) throw ...
Silent failure Bad input is accepted and produces a confident wrong answer. -400 degrees reports HEATING
Unintended consequence Harm beyond a program’s intended use, even when the code works as designed. +2 degrees x 50,000 homes
Open source Code published with a license that says how others may reuse it. MIT, Apache-2.0
  • A rejected call leaves the object unchanged: failing is safer than corrupting.
  • No license means no permission: visible code is not free code.

The Five Big Ideas

# Big Idea You will be able to
1 System Reliability Explain why one passing test is not evidence of reliability
2 Guarding Against Bad Input Write a guard clause that protects an object
3 Social, Economic, and Cultural Impact Name beneficial and harmful effects of one program
4 Unintended Consequences Explain how scale turns a small change into harm
5 Intellectual Property and Code Reuse Decide if code may be reused from its license

2. LxD Cycle Process

Empathize: Watching classmates write their first validated methods, the same pattern showed up: they tested one input, it returned the expected value, and they moved on. Asked “what happens if someone passes a negative number,” the common answer was “why would they?” The misconception underneath is that invalid input is the user’s problem, not the method’s. It produces no error, so it surfaces later where nobody is looking.

Define:

  • POV: CSA students who can write a working method need to see that a method owns its own invalid input, because they test to confirm success instead of finding failure, which hides silent corruption.
  • Learning Goal: Students will explain system reliability, add a guard clause that rejects invalid input, describe beneficial and harmful impacts of one program, and decide whether code may be reused from its license.

Ideate:

  • HMW Question: How might we make a silent failure visible to someone whose code has never errored?
  • HMW Question: How might we show that harm can come from scale rather than from a bug?
  • Activity: A trace table with a deliberately wrong row, so students watch a method accept -400 degrees and report a status. Thermostat was chosen because an impossible value needs no domain knowledge to spot, and it scales into the impact ideas.

Prototype:

  • A reference guide, one running example (ClimateSense), five short big ideas with runnable Java, four Popcorn Hacks, and a predict-the-output check.
  • Students revise the broken method into a guarded one after seeing it fail.

Test:

  • Peers complete the Popcorn Hacks without extra explanation.
  • Observe whether peers test edge cases before declaring a method done.
  • Use what did not land to revise the lesson after teaching.

3. College Board Requirements

AP CSA Unit 3, Topic 3.2 Impact of Program Design. Quoted from the course and exam description (College Board, 2025, p. 82):

  • 3.2.A “Explain the social and ethical implications of computing systems.” (Learning Objective; suggested skill 5.A)
  • 3.2.A.1 “System reliability refers to the program being able to perform its tasks as expected under stated conditions without failure. Programmers should make an effort to maximize system reliability by testing the program with a variety of conditions.”
  • 3.2.A.2 “The creation of programs has impacts on society, the economy, and culture. These impacts can be both beneficial and harmful. Programs meant to fill a need or solve a problem can have unintended harmful effects beyond their intended use.”
  • 3.2.A.3 “Legal issues and intellectual property concerns arise when creating programs. Programmers often reuse code written by others and published as open source and free to use. Incorporation of code that is not published as open source requires the programmer to obtain permission and often purchase the code before integrating it into their program.”
Big Idea Covers
1 and 2 3.2.A.1
3 and 4 3.2.A.2
5 3.2.A.3

4. Lesson Plan

Learning Objective: Explain why a program must be tested beyond one input, protect an object with a guard clause, and weigh the impacts and legal limits of the code you write.

Success Criteria: You can name edge cases for a method, write a guard that rejects them, describe a benefit and a harm of one program, and decide if online code is reusable from its license.

Time Segment
5 min Tech Talk and the running example
25 min Five big ideas with Popcorn Hacks 1 to 3
10 min Practice: predict the output, Popcorn Hack 4
5 min Answer check and quick review

Tech Talk (5 minutes)

A program that runs is not a program that works. One passing test says nothing about the input you did not imagine, and once code ships it affects real people in ways its author never intended.

ClimateSense is a hypothetical connected thermostat in tens of thousands of homes. Everything below centers on its Thermostat class, which holds a target temperature and reports a status:

%%{init: {'theme':'base','fontFamily':'JetBrains Mono, monospace','themeVariables':{'fontFamily':'JetBrains Mono, monospace','fontSize':'14px','primaryColor':'#1e293b','primaryTextColor':'#f8fafc','primaryBorderColor':'#60a5fa','lineColor':'#94a3b8','edgeLabelBackground':'#0f172a'},'flowchart':{'curve':'basis','padding':16,'nodeSpacing':40,'rankSpacing':50}}}%%
flowchart LR
    T(["targetTemp"]):::start --> A{"≥ 78 ?"}:::ask
    A -- yes --> C(["COOLING"]):::info
    A -- no --> B{"≤ 65 ?"}:::ask
    B -- yes --> H(["HEATING"]):::bad
    B -- no --> I(["IDLE"]):::good
    classDef start fill:#1e3a8a,stroke:#60a5fa,color:#fff,stroke-width:2px
    classDef ask fill:#78350f,stroke:#fbbf24,color:#fff,stroke-width:2px
    classDef good fill:#14532d,stroke:#4ade80,color:#fff,stroke-width:2px
    classDef bad fill:#7f1d1d,stroke:#f87171,color:#fff,stroke-width:2px
    classDef info fill:#1e293b,stroke:#94a3b8,color:#f8fafc,stroke-width:2px

5. Code Examples

Big Idea 1: System Reliability

System reliability means a program performs as expected, under stated conditions, without failure, not just for the one input you tried. Here is ClimateSense’s unguarded first version. Predict all three outputs before reading on.

Code Runner Challenge

Predict all three outputs first, then press Run -- does anything look wrong?

View IPYNB Source
// CODE_RUNNER: Predict all three outputs first, then press Run -- does anything look wrong?
public class Thermostat {
    private String roomName;
    private double targetTemp;

    public Thermostat(String roomName, double targetTemp) {
        this.roomName = roomName;
        this.targetTemp = targetTemp;
    }

    public void setTargetTemp(double temp) {
        targetTemp = temp;
    }

    public double getTargetTemp() { return targetTemp; }

    public String getStatus() {
        if (targetTemp >= 78) return "COOLING";
        if (targetTemp <= 65) return "HEATING";
        return "IDLE";
    }

    public static void main(String[] args) {
        Thermostat t = new Thermostat("Lab", 72);
        System.out.println(t.getStatus());

        t.setTargetTemp(80);
        System.out.println(t.getStatus());

        t.setTargetTemp(-400);          // below absolute zero
        System.out.println(t.getStatus());
    }
}
Thermostat.main(null);
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...
Call targetTemp after getStatus() Correct?
new Thermostat("Lab", 72) 72.0 IDLE Yes
setTargetTemp(80) 80.0 COOLING Yes
setTargetTemp(-400) -400.0 HEATING No, below absolute zero

No crash, no warning, just a confident wrong answer. A silent failure is worse than a crash, because a crash tells you where to look.

Popcorn Hack 1

What does getStatus() return for exactly 78? For exactly 65?

Code Runner Challenge

Popcorn Hack 1 -- Press Run and read the status for exactly 78 and exactly 65.

View IPYNB Source
// CODE_RUNNER: Popcorn Hack 1 -- Press Run and read the status for exactly 78 and exactly 65.
public class Thermostat {
    private String roomName;
    private double targetTemp;

    public Thermostat(String roomName, double targetTemp) {
        this.roomName = roomName;
        this.targetTemp = targetTemp;
    }

    public void setTargetTemp(double temp) {
        targetTemp = temp;
    }

    public double getTargetTemp() { return targetTemp; }

    public String getStatus() {
        if (targetTemp >= 78) return "COOLING";
        if (targetTemp <= 65) return "HEATING";
        return "IDLE";
    }

    public static void main(String[] args) {
        Thermostat t = new Thermostat("Lab", 72);
        t.setTargetTemp(78);
        System.out.println("78 -> " + t.getStatus());
        t.setTargetTemp(65);
        System.out.println("65 -> " + t.getStatus());
    }
}
Thermostat.main(null);
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Big Idea 2: Guarding Against Bad Input

A guard clause sits at the top of a method and rejects invalid input before anything else happens. The first version had none, so -400, 9999, and Double.NaN all succeeded silently.

%%{init: {'theme':'base','fontFamily':'JetBrains Mono, monospace','themeVariables':{'fontFamily':'JetBrains Mono, monospace','fontSize':'14px','primaryColor':'#1e293b','primaryTextColor':'#f8fafc','primaryBorderColor':'#60a5fa','lineColor':'#94a3b8','edgeLabelBackground':'#0f172a'},'flowchart':{'curve':'basis','padding':16,'nodeSpacing':40,'rankSpacing':50}}}%%
flowchart LR
    S("setTargetTemp(temp)"):::start --> V{"NaN, or outside
50 - 90 ?"}:::ask V -- yes --> X("throw IllegalArgumentException
object unchanged"):::bad V -- no --> OK("targetTemp = temp
value stored"):::good classDef start fill:#1e3a8a,stroke:#60a5fa,color:#fff,stroke-width:2px classDef ask fill:#78350f,stroke:#fbbf24,color:#fff,stroke-width:2px classDef good fill:#14532d,stroke:#4ade80,color:#fff,stroke-width:2px classDef bad fill:#7f1d1d,stroke:#f87171,color:#fff,stroke-width:2px classDef info fill:#1e293b,stroke:#94a3b8,color:#f8fafc,stroke-width:2px

Code Runner Challenge

Press Run to see the guard reject -400 and leave the object unchanged.

View IPYNB Source
// CODE_RUNNER: Press Run to see the guard reject -400 and leave the object unchanged.
public class Thermostat {
    private String roomName;
    private double targetTemp;

    public Thermostat(String roomName, double targetTemp) {
        this.roomName = roomName;
        this.targetTemp = targetTemp;
    }

    public void setTargetTemp(double temp) {
        if (Double.isNaN(temp) || temp < 50 || temp > 90) {
            throw new IllegalArgumentException("Target temp out of range: " + temp);
        }
        targetTemp = temp;
    }

    public double getTargetTemp() { return targetTemp; }

    public String getStatus() {
        if (targetTemp >= 78) return "COOLING";
        if (targetTemp <= 65) return "HEATING";
        return "IDLE";
    }

    public static void main(String[] args) {
        Thermostat t = new Thermostat("Lab", 72);
        try {
            t.setTargetTemp(-400);
        } catch (IllegalArgumentException e) {
            System.out.println("rejected -> " + e.getMessage());
        }
        System.out.println(t.getTargetTemp());   // still 72.0 -- the exception ran before the assignment
    }
}
Thermostat.main(null);
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

A rejected call leaves the object exactly as it was. NaN needs its own check because it fails every comparison: NaN < 50 and NaN > 90 are both false, so a range check alone lets it through.

Popcorn Hack 2

Delete the Double.isNaN(temp) clause and predict what setTargetTemp(Double.NaN) does. Explain in one sentence.

Code Runner Challenge

Popcorn Hack 2 -- Press Run, then delete the Double.isNaN(temp) clause and run again. What changes?

View IPYNB Source
// CODE_RUNNER: Popcorn Hack 2 -- Press Run, then delete the Double.isNaN(temp) clause and run again. What changes?
public class Thermostat {
    private String roomName;
    private double targetTemp;

    public Thermostat(String roomName, double targetTemp) {
        this.roomName = roomName;
        this.targetTemp = targetTemp;
    }

    public void setTargetTemp(double temp) {
        if (Double.isNaN(temp) || temp < 50 || temp > 90) {
            throw new IllegalArgumentException("Target temp out of range: " + temp);
        }
        targetTemp = temp;
    }

    public double getTargetTemp() { return targetTemp; }

    public String getStatus() {
        if (targetTemp >= 78) return "COOLING";
        if (targetTemp <= 65) return "HEATING";
        return "IDLE";
    }

    public static void main(String[] args) {
        Thermostat t = new Thermostat("Lab", 72);
        try {
            t.setTargetTemp(Double.NaN);
            System.out.println("accepted -> " + t.getTargetTemp());
        } catch (IllegalArgumentException e) {
            System.out.println("rejected -> " + e.getMessage());
        }
    }
}
Thermostat.main(null);
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Big Idea 3: Social, Economic, and Cultural Impact

One program can be beneficial and harmful at once, and the harm does not cancel the benefit. ClimateSense in fifty thousand homes:

%%{init: {'theme':'base','fontFamily':'JetBrains Mono, monospace','themeVariables':{'fontFamily':'JetBrains Mono, monospace','fontSize':'14px','primaryColor':'#1e293b','primaryTextColor':'#f8fafc','primaryBorderColor':'#60a5fa','lineColor':'#94a3b8','edgeLabelBackground':'#0f172a'},'flowchart':{'curve':'basis','padding':16,'nodeSpacing':40,'rankSpacing':50}}}%%
flowchart LR
    C("ClimateSense
50,000 homes"):::start C --> E("Energy use"):::info C --> S("Auto scheduling"):::info C --> R("Remote access"):::info E --> E1("Lower bills,
less grid strain"):::good S --> S1("Comfort without
manual effort"):::good S --> S2("Penalizes
shift workers"):::bad R --> R1("Adjust before
arriving"):::good R --> R2("Needs smartphone
+ home internet"):::bad classDef start fill:#1e3a8a,stroke:#60a5fa,color:#fff,stroke-width:2px classDef ask fill:#78350f,stroke:#fbbf24,color:#fff,stroke-width:2px classDef good fill:#14532d,stroke:#4ade80,color:#fff,stroke-width:2px classDef bad fill:#7f1d1d,stroke:#f87171,color:#fff,stroke-width:2px classDef info fill:#1e293b,stroke:#94a3b8,color:#f8fafc,stroke-width:2px

None of the harms are bugs. They are consequences of reasonable design choices. Ask who is excluded, not just who is served.


Big Idea 4: Unintended Consequences

An unintended consequence is harm beyond a program’s intended use, even when the code works exactly as designed. Suppose ClimateSense raises every target 2 degrees during a heat wave to ease grid load:

%%{init: {'theme':'base','fontFamily':'JetBrains Mono, monospace','themeVariables':{'fontFamily':'JetBrains Mono, monospace','fontSize':'14px','primaryColor':'#1e293b','primaryTextColor':'#f8fafc','primaryBorderColor':'#60a5fa','lineColor':'#94a3b8','edgeLabelBackground':'#0f172a'},'flowchart':{'curve':'basis','padding':16,'nodeSpacing':40,'rankSpacing':50}}}%%
flowchart LR
    A("+2 degrees
in one house"):::start --> B("Barely noticeable"):::good A --> C("x 50,000 houses at once
demand shock on the grid"):::bad A --> H("Medically vulnerable resident
real health risk"):::bad classDef start fill:#1e3a8a,stroke:#60a5fa,color:#fff,stroke-width:2px classDef ask fill:#78350f,stroke:#fbbf24,color:#fff,stroke-width:2px classDef good fill:#14532d,stroke:#4ade80,color:#fff,stroke-width:2px classDef bad fill:#7f1d1d,stroke:#f87171,color:#fff,stroke-width:2px classDef info fill:#1e293b,stroke:#94a3b8,color:#f8fafc,stroke-width:2px

Nobody wrote a harmful feature. The harm comes from scale, not intent.


Big Idea 5: Intellectual Property and Code Reuse

Reusing code is normal. The rules are about which code, under what terms.

%%{init: {'theme':'base','fontFamily':'JetBrains Mono, monospace','themeVariables':{'fontFamily':'JetBrains Mono, monospace','fontSize':'14px','primaryColor':'#1e293b','primaryTextColor':'#f8fafc','primaryBorderColor':'#60a5fa','lineColor':'#94a3b8','edgeLabelBackground':'#0f172a'},'flowchart':{'curve':'basis','padding':16,'nodeSpacing':40,'rankSpacing':50}}}%%
flowchart TD
    Q("Found code online"):::start --> L{"License stated?"}:::ask
    L -- no --> N("Treat as NOT free to use
write your own"):::bad L -- yes --> O{"Open source?"}:::ask O -- yes --> Y("Use it,
follow the license"):::good O -- no --> P("Only with permission"):::bad classDef start fill:#1e3a8a,stroke:#60a5fa,color:#fff,stroke-width:2px classDef ask fill:#78350f,stroke:#fbbf24,color:#fff,stroke-width:2px classDef good fill:#14532d,stroke:#4ade80,color:#fff,stroke-width:2px classDef bad fill:#7f1d1d,stroke:#f87171,color:#fff,stroke-width:2px classDef info fill:#1e293b,stroke:#94a3b8,color:#f8fafc,stroke-width:2px

Readable is not reusable. A public repo is visible to everyone, which says nothing about permission.

Popcorn Hack 3

A classmate says a four-line snippet is too short for licensing to apply. Respond.

Code Runner Challenge

Popcorn Hack 3 -- A classmate says a four-line snippet is too short for licensing. Run it, then change license to "MIT" and "proprietary" and compare.

View IPYNB Source
// CODE_RUNNER: Popcorn Hack 3 -- A classmate says a four-line snippet is too short for licensing. Run it, then change license to "MIT" and "proprietary" and compare.
public class LicenseCheck {
    static String mayReuse(String license) {
        if (license.equals("none")) return "NO -- no license means no permission. Write your own.";
        if (license.equals("MIT") || license.equals("Apache-2.0")) return "YES -- follow the license (keep the notice).";
        if (license.equals("proprietary")) return "ONLY with the owner's permission.";
        return "Unknown license -- read it before reusing.";
    }

    public static void main(String[] args) {
        String snippet = "int add(int a, int b) { return a + b; }";   // short, but still someone's work
        String license = "none";                                      // try "MIT", "proprietary"

        System.out.println("Snippet: " + snippet);
        System.out.println("License: " + license);
        System.out.println("May I reuse it? " + mayReuse(license));
    }
}
LicenseCheck.main(null);
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

6. Hacks & Practice Tasks

Predict the Output

Using the guarded setTargetTemp, pick your answer (A to D) first, then run the cell to check it.

Code Runner Challenge

Pick your answer (A-D) below first, then press Run to check it.

View IPYNB Source
// CODE_RUNNER: Pick your answer (A-D) below first, then press Run to check it.
public class Thermostat {
    private String roomName;
    private double targetTemp;

    public Thermostat(String roomName, double targetTemp) {
        this.roomName = roomName;
        this.targetTemp = targetTemp;
    }

    public void setTargetTemp(double temp) {
        if (Double.isNaN(temp) || temp < 50 || temp > 90) {
            throw new IllegalArgumentException("Target temp out of range: " + temp);
        }
        targetTemp = temp;
    }

    public double getTargetTemp() { return targetTemp; }

    public String getStatus() {
        if (targetTemp >= 78) return "COOLING";
        if (targetTemp <= 65) return "HEATING";
        return "IDLE";
    }

    public static void main(String[] args) {
        Thermostat t = new Thermostat("Lab", 72);
        try {
            t.setTargetTemp(95);
        } catch (IllegalArgumentException e) {
            System.out.println("rejected");
        }
        System.out.println(t.getTargetTemp());
        System.out.println(t.getStatus());
    }
}
Thermostat.main(null);
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

A. 95.0, then COOLING

B. rejected, then 72.0, then IDLE

C. rejected, then 95.0, then COOLING

D. rejected, then 72.0, then COOLING

Popcorn Hack 4

Finish setRoomName so it rejects null, empty, and whitespace-only names, validating before assigning. The first attempt should be accepted and the next three rejected.

Code Runner Challenge

Popcorn Hack 4 -- Finish setRoomName so it rejects null, empty, and whitespace-only names, then press Run. Expect 1 accepted, 3 rejected.

View IPYNB Source
// CODE_RUNNER: Popcorn Hack 4 -- Finish setRoomName so it rejects null, empty, and whitespace-only names, then press Run. Expect 1 accepted, 3 rejected.
public class Room {
    private String roomName;

    public Room(String roomName) { this.roomName = roomName; }

    public void setRoomName(String name) {
        // TODO: reject null, empty, and whitespace-only names.
        roomName = name;
    }

    public String getRoomName() { return roomName; }

    public static void main(String[] args) {
        Room r = new Room("Lab");
        String[] attempts = { "Nursery", null, "", "   " };
        for (String a : attempts) {
            try {
                r.setRoomName(a);
                System.out.println("accepted -> [" + r.getRoomName() + "]");
            } catch (IllegalArgumentException e) {
                System.out.println("rejected -> " + e.getMessage());
            }
        }
    }
}
Room.main(null);
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

Answer Check

Predict the Output: B. 95 is outside 50-90, so the guard throws before the assignment; the object keeps 72.0 and getStatus() returns IDLE. (A and C assume the value was stored anyway; D contradicts its own state.)

Popcorn Hack 4. Reject null (a later method call on it would throw NullPointerException far from the real cause) and empty or whitespace-only names (an unidentifiable room is unusable). The rule: a mutator rejects anything that leaves the object unable to function.

Quick Review

  • Reliability: works under all stated conditions, not just the one input you tried.
  • Test edges: zero, negative, empty, null, NaN, boundaries.
  • Guard clause: runs before assignment, so invalid input is never stored.
  • Silent acceptance is more dangerous than a crash.
  • Impact: one program can help and harm, and harm beyond intended use comes from scale, not intent.
  • Reuse: visible code is not free code. No license means no permission.

7. References

College Board. (2025). AP Computer Science A course and exam description [Effective fall 2025], Unit 3, Topic 3.2, p. 82.

Learn more about Topic 3.2 (College Board):

Further reading:

Submit Assignment

Click to upload or drag and drop
PDF, ZIP, images, documents, or Jupyter notebooks (.ipynb) (Max 10MB per file)

Need to update a submission later? Open the submissions dashboard.