sign in
Start typing to search across all 16 weeks…
home / summer / week 2
Summer · Week 2 of 8

Logic & Control Flow

Booleans, if/else, switch statements, and logical operators.

Booleans & Logical Operators

a boolean is the simplest piece of information in computing. it can only be two things: true or false. that's it. like a light switch — on or off, nothing in between.

that might sound too simple to be useful, but booleans are actually the backbone of everything a robot does. every decision the robot makes — every "should i do this right now?" question — is a boolean under the hood. is the robot allowed to move? is the intake (the intake is the mechanism that picks up game pieces) holding something? has the shooter (the shooter launches game pieces into scoring targets) wheel spun up to speed? all booleans. all the time.

the boolean mental model

ok so imagine you have a yes/no checklist. "is the robot enabled?" yes. "does the intake have a game piece (game pieces are the objects FRC robots pick up and score each season — changes every year)?" no. "is the shooter at target speed?" yes. each of those answers is exactly one bit of information — true or false. that's what a boolean is.

at a hardware level, a boolean is literally just 1 bit of memory. the whole entire concept boils down to: is this bit a 1 (true) or a 0 (false)? everything your robot decides — every motion command, every state transition, every safety check — eventually collapses into a bunch of these yes/no decisions chained together.

your robot code is FULL of state. is the shooter running? is the limit switch pressed? is the robot in auto or teleop (teleop = the 2-minute period where drivers control the robot manually)? is the alliance station red or blue? every single one of those is a boolean. state machines (a design pattern where the robot switches between named modes like INTAKING, SHOOTING, IDLE) also rely on boolean-reliant things, known as triggers. state machines are one of the more complex things in FRC, so I won't burden y'all with that quite yet. (those who know)

declaring a boolean

you already saw boolean as a type in week 1. here's a full annotated look with real FRC variable examples:

java
// a boolean can only be true or false — that's the whole type
boolean isEnabled     = true;   // is the robot allowed to move right now?
boolean hasGamePiece  = false;  // is the intake holding something?
boolean isAtSpeed     = false;  // has the shooter wheel spun up?
boolean isAtTarget    = true;   // is the robot aimed at the goal?

// booleans are also what comparisons return
double speed = 0.85;
boolean isFast = speed > 0.5;  // true — speed is greater than 0.5
boolean isSlow = speed < 0.3;  // false — speed is NOT less than 0.3

// member variable convention on WRT: m_ prefix
private boolean m_isRunning  = false;  // belongs to the class (instance var)
private boolean m_hasTarget  = false;  // changes during robot operation

notice how boolean variable names almost always start with "is" or "has" — like isEnabled, hasGamePiece, isAtSpeed. this is a naming convention everyone uses because it reads like a yes/no question: "is the robot enabled? yes, true." it makes code way easier to read at a glance.

comparison operators — making booleans from math

you create booleans all the time by comparing two numbers. these comparison operators all return either true or false. you've seen most of these from math class, just written differently:

==
equals
x == 5 — is x equal to 5? (two equals signs, NOT one — we'll come back to this)
!=
not equals
x != 5 — is x something other than 5?
< and >
less / greater
speed > 0.5 — is speed more than 0.5? returns true or false.
<= and >=
less/greater or equal
distance <= 24.0 — is distance 24 or less? includes the boundary value.
java
double distanceInches = 18.5;
double motorSpeed     = 0.72;
int    encoderTicks   = 4096;  // encoder ticks — raw count of how many pulses the encoder has measured (more ticks = more rotation)

// each of these evaluates to true or false
boolean inRange     = distanceInches <= 24.0;   // true — 18.5 is less than 24
boolean atFullSpeed = motorSpeed >= 0.8;         // false — 0.72 is not >= 0.8
boolean fullTurn    = encoderTicks == 4096;      // true — exactly equal
boolean notHome     = encoderTicks != 0;          // true — ticks are not 0

logical operators — combining booleans

what if you need to check more than one thing at once? that's what logical operators are for. you can chain booleans together to build more powerful conditions. there are three: && (AND), || (OR), and ! (NOT). story time for each one.

&& (AND) — the two security guards

imagine the entrance to a competition field has two security guards. guard one checks if you have a wristband. guard two checks if you have a safety vest. you only get in if BOTH say yes. if either one says no, you're not getting through. that's &&.

in FRC: the robot should only shoot if it HAS a game piece AND is close enough to the goal. if either condition is false — no piece, or too far away — there's no point shooting. both must be true simultaneously.

java
boolean hasGamePiece  = true;
boolean isCloseEnough = false;

// && means BOTH must be true
boolean canShoot = hasGamePiece && isCloseEnough;
// canShoot = false — because isCloseEnough is false
// it doesn't matter that hasGamePiece is true
// both sides MUST be true for && to give true

here's the full truth table for &&. a truth table just shows every possible input combination and what you get out:

true && true
= true
both sides are true, so AND is true. robot has piece AND is close. shoot!
true && false
= false
one side is false. has piece but NOT close enough. can't shoot yet.
false && true
= false
other side is false. close enough but NO piece. can't shoot.
false && false
= false
both are false. no piece AND not close. definitely can't shoot.

|| (OR) — at least one guard says yes

now imagine the intake motor. you want it to run if either button A OR button B on the gamepad is pressed. you don't care which one — if either is pressed, run the intake. that's OR.

java
boolean buttonA = false;
boolean buttonB = true;

// || means AT LEAST ONE must be true
boolean runIntake = buttonA || buttonB;
// runIntake = true — because buttonB is true
// even though buttonA is false, that's fine
// OR only needs ONE side to be true
true || true
= true
both are true. either button works. run intake.
true || false
= true
first side is true. button A pressed. run intake.
false || true
= true
second side is true. button B pressed. run intake.
false || false
= false
neither button is pressed. don't run intake.

! (NOT) — flip it

! just flips a boolean. true becomes false, false becomes true. it's useful when you want to say "if this thing is NOT happening." you'll see it constantly in real robot code.

java
boolean isShooterRunning = false;

// ! flips the value
boolean shouldStartShooter = !isShooterRunning;
// shouldStartShooter = true
// "if the shooter is NOT running, we should start it"

// !true  = false
// !false = true
// that's literally the whole thing

// you'll see this all the time:
if (!isEnabled)    { /* robot disabled, do nothing */ }
if (!hasGamePiece) { /* run intake */ }
if (!isAtTarget)   { /* keep aiming */ }

WRT convention: you'll see ! constantly in robot code as "guard conditions" — conditions that block things from happening when they shouldn't. things like if (!isEnabled) at the top of a method to bail out early. it reads naturally in English: "if NOT enabled" — super clean.

combining multiple operators

you can chain all three together to build complex conditions. let's say the robot should only shoot if it's enabled, has a game piece, AND is not already at the target:

java
boolean isEnabled    = true;
boolean hasGamePiece = true;
boolean isAtTarget   = false;

// all three conditions must be met to shoot
boolean shouldShoot = isEnabled && hasGamePiece && !isAtTarget;
// shouldShoot = true
// enabled? yes. has piece? yes. NOT already at target? yes (isAtTarget is false, !false = true)

// you can also mix && and ||, but use parentheses to be explicit
boolean shouldIntake = isEnabled && (!hasGamePiece || isAtTarget);
// run intake if enabled AND (either: no piece, OR at target and can cycle again)

short-circuit evaluation

here's something interesting about how Java handles && and ||: it's lazy. it only evaluates as much as it needs to.

with &&, if the first part is false, Java immediately knows the whole thing is false (since both sides need to be true). it doesn't even look at the second part. same deal with || — if the first part is true, it stops immediately because it already knows the result is true. this is called short-circuit evaluation.

java
boolean isEnabled = false;
boolean hasTarget = true;

// Java sees isEnabled is false first
// it STOPS RIGHT THERE and returns false
// it never even evaluates hasTarget
boolean result = isEnabled && hasTarget; // false (short-circuited after isEnabled)

// same with || — if the first part is true, Java stops
// it already knows the result is true, no point checking the rest
boolean result2 = hasTarget || isEnabled; // true (stopped after hasTarget)

short-circuit evaluation is really useful in advanced code — you can put the "cheapest" or "most likely to be false" check first in an && chain so Java skips the expensive operations when they aren't needed. not critical right now, but good to know it exists and that Java does it automatically.

the operator precedence gotcha (this WILL bite you)

ok story time. you want to check: "NOT (a AND b)" — meaning the combined condition is false. so you write !a && b. but wait — that's actually "NOT a, AND b". those are very different things and Java evaluates them differently.

java — BAD (wrong precedence)
boolean isEnabled    = true;
boolean hasGamePiece = true;

// intent: "NOT (enabled AND has piece)"
// i.e. fire a warning if the ready-to-shoot condition is NOT fully met
boolean notReady = !isEnabled && hasGamePiece;
// actual evaluation: (!isEnabled) && hasGamePiece
// !isEnabled = !true = false
// false && true = false
// notReady = false — NOT what you meant!
java — GOOD (explicit parentheses)
// intent: "NOT (enabled AND has piece)"
boolean notReady = !(isEnabled && hasGamePiece);
// (isEnabled && hasGamePiece) = (true && true) = true
// !(true) = false
// notReady = false — correct!

// rule of thumb: when mixing ! with && or ||, use parentheses to be explicit
// don't rely on your memory of operator precedence — it trips up everyone

common gotcha: ! has higher precedence than && and ||, so !a && b is always read as (!a) && b, not !(a && b). if you mean to negate the whole combined expression, wrap it in parentheses: !(a && b). when in doubt, add parens. they never hurt.

Topic 1 — Coding Prompt

Robot Ready Check
Combine booleans with logical operators

Start with these variables:
boolean isEnabled = true;
boolean hasGamePiece = true;
boolean isAtSpeed = false;
double distanceInches = 20.0;

Create two new booleans using &&, ||, and !:
readyToShoot — true only if ALL of these are true: enabled, has piece, at speed, AND distance is 24 or less
shouldIntake — true if enabled AND does NOT have a game piece

Print both. With these values, what should each one be?

Topic 1 — Quick Check


If / Else

if/else is how your program makes decisions. every single decision your robot makes — whether to spin a motor, which auto routine to run, whether to extend a mechanism — is an if/else somewhere inside. honestly if/else is like 80% of programming, it's that important.

the idea is simple: "IF this condition is true, run this code. ELSE (otherwise), run this other code." Java reads your program line by line, and when it hits an if, it checks the condition. if the condition is true, it runs the block inside the braces. if the condition is false, it skips that block entirely.

if/else — programs that make decisions

imagine a bouncer at the door of a venue. they have a guest list. for every person who walks up, they run through a mental checklist: "are you on the list? are you 18+? do you have valid ID?" if all conditions pass, you get in. otherwise, you don't. the bouncer isn't doing math or calculating anything complex — they're just checking yes/no conditions in order and branching based on the result.

your Java program's if/else works exactly like that bouncer. you give it a boolean condition (the check), and it either runs the block inside (let them in) or skips it (turn them away). no guessing, no "maybe" — it's a clean binary branch.

every robot behavior is conditional. "if the shooter is at speed, allow firing." "if the sensor sees a game piece, stop the intake." "if we're in auto mode, run the preloaded trajectory." if you can't write if/else well, you literally can't program a robot. this is the single most important topic in week 2.

the simplest possible example

before we get to robots, here's a completely basic example so you can see exactly what's happening line by line:

java
boolean isSunny = true;

if (isSunny) {                              // check: is isSunny true?
    System.out.println("wear sunglasses");  // YES: run this block
}
// if isSunny were false, this whole block would be skipped
// Java would jump straight past it and continue with whatever comes next

now let's add an else — what to do when the condition is false:

java
boolean isSunny = false;

if (isSunny) {
    System.out.println("wear sunglasses");  // skipped (isSunny is false)
} else {
    System.out.println("grab an umbrella");  // this runs
}

// output: "grab an umbrella"
// the if block was skipped, the else block ran instead

else if — checking multiple conditions

sometimes you need more than two outcomes. else if lets you chain conditions: "if this... otherwise if this other thing... otherwise..." you can stack as many else if blocks as you want.

java
double distanceInches = 18.5;

if (distanceInches < 12.0) {
    // runs if distance is less than 12 inches
    System.out.println("Too close — stop!");

} else if (distanceInches < 24.0) {
    // runs if distance is between 12 and 24
    // (already know it's >= 12 because that check failed above)
    System.out.println("In range — score!");

} else {
    // runs if nothing above was true — distance is 24 or more
    System.out.println("Too far — drive closer");
}

// distanceInches is 18.5
// check 1: 18.5 < 12.0? no, skip
// check 2: 18.5 < 24.0? YES — prints "In range — score!"
// else block skipped — we already found a match

once Java finds a condition that's true in an if/else chain, it runs that block and jumps PAST all remaining else if and else blocks. it doesn't keep checking. that's why order matters — put the most specific or most important checks first.

how Java reads an if/else chain, step by step

let's slow down and trace through exactly what Java is doing. this mental model will help you debug if/else logic when it doesn't do what you expect:

java
int score = 75;

if (score >= 90) {        // step 1: is 75 >= 90? NO. skip this block.
    System.out.println("A");
} else if (score >= 80) { // step 2: is 75 >= 80? NO. skip this block.
    System.out.println("B");
} else if (score >= 70) { // step 3: is 75 >= 70? YES! run this block.
    System.out.println("C");  // this line runs
} else {                    // step 4: skipped — already found match above
    System.out.println("F");
}
// output: C

nested if/else — an if inside an if

you can put an if/else inside another if/else. this is called nesting. you do this when you only want to check a second condition after the first one passes — like a two-stage gate:

java
boolean isEnabled     = true;
boolean hasGamePiece  = true;
double  distanceInches = 20.0;

// first gate: is the robot even allowed to move?
if (isEnabled) {

    // only check game piece status if we're enabled
    if (hasGamePiece) {

        // only check distance if we have a piece
        if (distanceInches <= 24.0) {
            System.out.println("Shoot!");
        } else {
            System.out.println("Drive closer");
        }

    } else {
        System.out.println("Run intake — no game piece");
    }

} else {
    System.out.println("Robot is disabled");
}

// enabled=true, hasGamePiece=true, distance=20 (<=24)
// output: "Shoot!"

notice the indentation — each nested level is indented one more step. this is super important for readability. the indentation shows you which if/else belongs to which outer block. if your indentation is a mess, your code is a mess. Java ignores whitespace but your teammates (and future you) don't.

the = vs == gotcha (this WILL bite you)

ok this is the #1 most common if/else bug for new programmers. here's the story. you're checking if a button ID equals 2, and you write: if (buttonID = 2). your code compiles... but does the wrong thing completely. why?

java — BAD (single equals in an if)
int buttonID = 1;

// WRONG — this is assignment, not comparison
// this sets buttonID to 2 AND evaluates to 2 (non-zero = true in some langs)
// in Java this is actually a compile error for booleans — but easy to mix up
if (buttonID = 2) {  // COMPILE ERROR in Java — but the confusion is real
    System.out.println("button 2 pressed");
}
java — GOOD (double equals for comparison)
int buttonID = 1;

// CORRECT — == is comparison, asks "are these equal?"
if (buttonID == 2) {   // is buttonID equal to 2? no, it's 1, so skip
    System.out.println("button 2 pressed");  // skipped
}

// where it REALLY bites you — booleans:
boolean isRunning = false;
if (isRunning = true) {   // this SETS isRunning to true AND always runs!
    System.out.println("running");  // this ALWAYS prints now — bug!
}

// fix:
if (isRunning == true) {   // correct comparison
    System.out.println("running");
}
// even cleaner — booleans don't need == true, just use the variable directly:
if (isRunning) {
    System.out.println("running");
}

danger: single = is assignment — you're SETTING a value. double == is comparison — you're ASKING if two things are equal. using = inside an if with booleans in Java assigns the value AND uses it as the condition — so if (isRunning = true) will set isRunning to true and ALWAYS execute the block. super sneaky bug that's hard to spot. always double-check your equals signs.

the missing braces gotcha

technically, if your if block only has one line inside it, you can skip the curly braces. please don't. here's why:

java — the missing braces trap
boolean isEnabled = true;

// this LOOKS like both lines are inside the if... but they're not
if (isEnabled)
    System.out.println("robot is enabled");
    System.out.println("running motors");  // ALWAYS runs, not inside the if!

// Java ignores indentation. only the FIRST line after a brace-less if is conditional.
// the second println runs regardless of isEnabled

// fix — always use braces:
if (isEnabled) {
    System.out.println("robot is enabled");
    System.out.println("running motors");  // now correctly inside the if
}

always use curly braces { }, even for single-line if blocks. it takes two seconds and prevents a really sneaky class of bugs. real code review at WRT will flag missing braces. just make it a habit from day one.

a full robot decision tree

here's a realistic decision tree that could live in an autonomous routine. read through it and make sure you can follow the logic step by step:

java
boolean isEnabled      = true;
boolean hasGamePiece   = false;
double  distanceInches = 30.0;

// check the most blocking condition FIRST
if (!isEnabled) {
    System.out.println("DISABLED — doing nothing");

} else if (!hasGamePiece) {
    // enabled but no piece — intake is the job
    System.out.println("INTAKE — go pick up a piece");

} else if (distanceInches > 24.0) {
    // enabled, has a piece, but too far
    System.out.println("DRIVE CLOSER — not in range yet");

} else {
    // enabled, has piece, in range — all conditions met
    System.out.println("SHOOT — all conditions met!");
}

// current values: enabled=true, hasGamePiece=false
// output: "INTAKE — go pick up a piece"

notice that we check !isEnabled first. if the robot is disabled, nothing else matters — no point running through the rest of the logic. this pattern (handling the most blocking condition first, then progressively less critical ones) is how real robot code is structured. it reads like a priority list from most important to least.

Fill in the Blanks

// True only if both speed is high AND target is locked
boolean canShoot = isAtSpeed hasTarget;
// Run this block if speed is greater than 0.5
(speed ) { }
// What keyword runs when none of the if / else if conditions matched?
{ System.out.println("fallback"); }

Topic 2 — Coding Prompt

Robot State Checker
Use if/else and booleans in an FRC scenario

Start with these variables:
boolean isEnabled = true;
boolean hasGamePiece = false;
double distanceToTarget = 18.5;

Write an if/else chain that checks conditions in this exact order and prints the matching message:
1. not enabled → print "Robot disabled"
2. no game piece → print "Intake"
3. has piece but distance > 24 → print "Drive closer"
4. has piece and distance <= 24 → print "Shoot!"

With these starting values, which line should print?

Topic 2 — Quick Check


Switch Statements

a switch is like a train track switch that routes trains to different tracks based on a signal. you tell it which track to route to, and it goes directly there — no checking all the other tracks along the way. it's an alternative to writing a huge chain of if / else if / else if... when you're testing one variable against a bunch of specific values.

think about a vending machine. you press B3 and get chips. press B4, get water. press B5, get a soda. the machine doesn't check "is the code greater than B2? is it less than B6?" — it just looks at what you pressed and jumps straight to that slot. that's a switch.

switch — jump to the matching case

ok so here's the mental model. with if/else, you're running through a checklist one by one: check condition 1, nope, check condition 2, nope, check condition 3... you're evaluating multiple different expressions. a switch is different. you say "i have this ONE value, and i want to jump directly to whichever case matches." Java evaluates the variable once and routes to the matching case.

robot code often has a concept of "states" — the robot is either INTAKING, SHOOTING, CLIMBING, or IDLE. when you want different behavior for each state, a switch is much cleaner than a chain of if/else-if. you can look at a switch and immediately see every possible state and what happens in each one. it's way more readable at a glance.

the syntax, line by line

java
int buttonID = 2;

switch (buttonID) {        // which variable are we routing on?

    case 1:                // if buttonID == 1...
        System.out.println("Run intake");
        break;             // STOP HERE — exit the switch entirely

    case 2:                // if buttonID == 2...
        System.out.println("Spin up shooter");
        break;             // stop — don't run any more cases

    case 3:                // if buttonID == 3...
        System.out.println("Deploy climber");
        break;             // stop

    default:               // if none of the cases matched...
        System.out.println("Unknown button");
        // no break needed at the end — it's the last case
}

// buttonID is 2, so output: "Spin up shooter"

let's break down every keyword:

switch
the variable to route on
switch (buttonID) — you're telling Java "look at this variable and find which case matches its value."
case
a specific value to match
case 2: — "if the variable equals 2, start running code from here." note the colon, not braces.
break
exit the switch
break; — tells Java to stop and jump out of the switch block. without it, Java falls through into the next case (more on this below).
default
the fallback
like else — runs if no case matched. optional but almost always a good idea so you handle unexpected values instead of silently ignoring them.

the fall-through gotcha (this WILL bite you)

story time. you're writing a robot state machine — different behavior for INTAKING, SHOOTING, and CLIMBING. you write the switch, test button 2 (shooting)... and the robot runs the shooter AND deploys the climber. you look at the code for 10 minutes trying to figure out why. then you realize: you forgot break. this is called fall-through.

java — BAD (missing break, fall-through bug)
int buttonID = 2;

switch (buttonID) {
    case 1:
        System.out.println("Run intake");
        // oops — no break here
    case 2:
        System.out.println("Spin up shooter");
        // oops — no break here either
    case 3:
        System.out.println("Deploy climber");
        // no break — falls into default too
    default:
        System.out.println("Unknown button");
}

// buttonID is 2, Java jumps to case 2...
// no break, so falls into case 3...
// no break, so falls into default...
// output:
// "Spin up shooter"
// "Deploy climber"       <-- unintended!!
// "Unknown button"       <-- unintended!!
java — GOOD (break in every case)
int buttonID = 2;

switch (buttonID) {
    case 1:
        System.out.println("Run intake");
        break;  // case 1 done, exit switch
    case 2:
        System.out.println("Spin up shooter");
        break;  // case 2 done, exit switch
    case 3:
        System.out.println("Deploy climber");
        break;  // case 3 done, exit switch
    default:
        System.out.println("Unknown button");
}
// output: "Spin up shooter"
// only case 2 ran — correct!

danger: fall-through is almost never what you want. when your robot accidentally deploys the climber because you forgot a break on the shooter case... yeah, that's a bad day at competition. always add break at the end of every case unless you intentionally want fall-through (which is rare and should be documented with a comment).

switch with Strings — robot state machines

switch also works with String values, not just numbers. this is perfect for robot game states where you have named modes:

java
String robotState = "SHOOTING";

switch (robotState) {
    case "INTAKING":
        System.out.println("running intake motors");
        break;

    case "SHOOTING":
        System.out.println("spinning up flywheels");
        break;

    case "CLIMBING":
        System.out.println("deploying hooks");
        break;

    case "IDLE":
        System.out.println("stopped, waiting for command");
        break;

    default:
        System.out.println("unknown state!");
}

// robotState = "SHOOTING"
// output: "spinning up flywheels"

in real WRT robot code you'd use an enum instead of a String for states (enums are a type we'll see later), but the switch logic is identical. the pattern is the same: one variable, many possible named values, each routes to its own behavior block.

switch vs if-else — when to use which

they can often do the same thing, but each has a use case where it's clearly better:

SituationUseReason
One variable, many exact values (1, 2, 3 or "SHOOT", "INTAKE")switchCleaner, reads like a menu, easier to add new cases
Checking ranges (speed > 0.5, distance < 24)if/elseSwitch can't do ranges — cases must be exact values
Multiple variables combined with && / ||if/elseSwitch only works on one variable at a time
Complex boolean logicif/elseSwitch doesn't support arbitrary boolean expressions
java — switch CANNOT do this (ranges)
// this is WRONG — switch cases can't use comparisons or ranges
switch (speed) {
    case > 0.5:  // COMPILE ERROR — not valid Java
        ...
}

// correct — use if/else for range checks
if (speed > 0.5) {
    // this works fine
}

Fill in the Blanks — Switch

// what keyword starts a switch block?
(gameState) { }
// prevent fall-through — what goes at the end of each case?
case 1: doSomething(); ;
// what keyword is the switch "else" fallback?
: System.out.println("unknown");

Topic 3 — Coding Prompt

Robot State Router
Write a switch for a robot state machine

Declare String robotState = "SHOOTING"; and write a switch on it with four cases:
"INTAKING" → print "running intake"
"SHOOTING" → print "shooting game piece"
"CLIMBING" → print "deploying climber"
• default → print "idle"

Run it with "SHOOTING", then change the value to "CLIMBING" and verify the right case runs. Don't forget break; after each case.

Topic 3 — Quick Check


Ternary Operator

the ternary operator is basically a one-line if/else. it's shorthand for a simple "yes or no, pick one of two values" decision. once you see it a few times you'll start using it constantly for quick, compact checks.

it's called "ternary" because it takes THREE operands: a condition, a value if true, and a value if false. most operators take one or two operands, so three is unusual — hence the special name.

the ternary — a one-line if/else

ok so imagine someone asks you "hey, do you want pizza or tacos?" and you just say "pizza" or "tacos" — a quick yes/no pick between two options. that's the ternary. instead of writing a whole if/else block to choose between two values, you write it on one line:

the format is: condition ? valueIfTrue : valueIfFalse

read it as: "is the condition true? if yes, give me valueIfTrue. if no, give me valueIfFalse."

you'll see ternaries constantly in robot code for compact value selection — picking a motor direction based on a flag, clamping a speed to 0 if disabled, selecting a string label for the dashboard. it keeps simple conditional assignments short and readable instead of taking up 5 lines for an if/else.

ternary vs if/else — they're equivalent

java
boolean isEnabled = true;

// if/else version — fine but takes 5 lines
double speed1;
if (isEnabled) {
    speed1 = 0.8;
} else {
    speed1 = 0.0;
}

// ternary version — same thing in one line
double speed2 = isEnabled ? 0.8 : 0.0;
//                ^           ^      ^
//          condition     if true   if false

// both produce the same result: speed = 0.8 (isEnabled is true)

let's annotate the syntax more carefully:

java
// general form:
// result = condition ? valueIfTrue : valueIfFalse;

boolean isReversed = true;
double  intakeSpeed = isReversed ? -0.5 : 0.5;
// isReversed is true, so intakeSpeed = -0.5

boolean hasGamePiece = false;
String  statusLabel = hasGamePiece ? "LOADED" : "EMPTY";
// hasGamePiece is false, so statusLabel = "EMPTY"

boolean isAutoMode = true;
double  driveSpeed = isAutoMode ? 0.6 : 1.0;
// isAutoMode is true, so driveSpeed = 0.6 (slower in auto for precision)

FRC examples — where ternary shines

ternary is perfect for quick value selection in robot code. here are the patterns you'll actually see:

java
// clamp speed to 0 when disabled
double m_outputSpeed = isEnabled ? motorSpeed : 0.0;

// direction flag — run motor forward or backward
double direction = isReversed ? -1.0 : 1.0;
double finalSpeed = baseSpeed * direction;

// dashboard label — compact string selection
String pieceLabel = hasGamePiece ? "LOADED" : "NO PIECE";

// return a default value if something's null (advanced usage)
String autoName = (selectedAuto != null) ? selectedAuto : "Default Auto";

the nested ternary gotcha (don't do this)

ok so now that you know ternary exists, someone will show you that you can nest them — a ternary inside a ternary. resist this. it becomes completely unreadable almost immediately. here's what i mean:

java — BAD (nested ternary, unreadable)
double distanceInches = 18.0;

// what does this even say?? you have to trace it for 30 seconds
String action = distanceInches < 12.0 ? "TOO CLOSE"
               : distanceInches < 24.0 ? "IN RANGE"
               : "TOO FAR";

// technically works but nobody should write this — use if/else instead
java — GOOD (if/else for multi-branch logic)
double distanceInches = 18.0;

String action;
if (distanceInches < 12.0) {
    action = "TOO CLOSE";
} else if (distanceInches < 24.0) {
    action = "IN RANGE";      // 18.0 hits this case
} else {
    action = "TOO FAR";
}
// clear, readable, easy to modify

common gotcha: ternary is for simple two-option picks — use it when the logic is truly one line and immediately obvious. if you're nesting ternaries or the condition is getting complex, switch to if/else. code review will catch this. readability is more important than compactness.

Topic 4 — Coding Prompt

Compact Motor Direction
Use ternary for quick value selection

Start with these two booleans:
boolean isRunning = true;
boolean isReversed = false;

Using ternary operators only (no if/else allowed):
double intakeSpeed — should be 0.7 if running, 0.0 if not
String directionLabel — should be "FORWARD" if not reversed, "REVERSE" if reversed

Print both. Then flip isRunning to false, recalculate, and print again to check.

Topic 4 — Quick Check


Project Task — Week 2
AutoLogic.java

Create AutoLogic.java in your minibot-project folder. This class simulates autonomous decision making — the logic your robot uses when it's driving itself without a driver.

  • Write a static String decideAction(boolean hasGamePiece, double distanceInches, boolean isEnabled) method
  • Returns "DISABLED" if not enabled
  • Returns "INTAKE" if no game piece
  • Returns "DRIVE_CLOSER" if game piece held but distance > 24.0 inches
  • Returns "SHOOT" if game piece held and distance <= 24.0 inches
  • Add a Javadoc comment above the method explaining each parameter
  • Add a main method that tests all 4 cases with System.out.println()
save this file — you'll connect it to your subsystem classes in later weeks.

Knowledge Check

Weekly Test

covers everything from week 2. a bit longer than topic quizzes and your score gets sent to the leads :) try without looking back first!!

week 2 test
booleans, logical operators, if/else, switch · 8 questions · good luck!!