diff --git a/examples/stage0/snippets/src/Arrays.java b/examples/stage0/snippets/src/Arrays.java new file mode 100644 index 00000000..ae57c5c1 --- /dev/null +++ b/examples/stage0/snippets/src/Arrays.java @@ -0,0 +1,67 @@ +/* + * Copyright 2026 FRCSoftware + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +void main() { + // [motorSpeedsLiteral] + double[] motorSpeeds = {0.5, 0.5, 0.5, 0.5}; + // [/motorSpeedsLiteral] + + // [motorSpeedsEmpty] + double[] emptyMotorSpeeds = new double[4]; + // [/motorSpeedsEmpty] + + // [setSpeed] + motorSpeeds[0] = 0.7; + System.out.println(motorSpeeds[0]); // 0.7 + // [/setSpeed] + + // [speedsLength] + System.out.println(motorSpeeds.length); // 4 + // [/speedsLength] + + // [pathArray] + Point[] path = { + new Point(0, 0), + new Point(1, 2), + new Point(3, 3), + }; + // [/pathArray] + + // [pathArrayEmpty] + Point[] emptyPath = new Point[3]; + // [/pathArrayEmpty] + + try { + // [pathArrayNull] + emptyPath[0].norm(); // error: emptyPath[0] is null + // [/pathArrayNull] + } catch (NullPointerException e) { + // for demo purposes we don't care about the exception' + } + + // [indexLoopSpeeds] + double total = 0; + for (int i = 0; i < motorSpeeds.length; i++) { + total += motorSpeeds[i]; + } + System.out.println(total); // 2.2 + // [/indexLoopSpeeds] + + // [forEachPath] + for (Point waypoint : path) { + System.out.println(waypoint.getX() + ", " + waypoint.getY()); + } + // [/forEachPath] + + // [pathLength] + double pathLength = 0; + for (int i = 1; i < path.length; i++) { + Point segment = path[i].minus(path[i - 1]); + pathLength += segment.norm(); + } + System.out.println(pathLength); // 4.47213595499958 + // [/pathLength] +} diff --git a/examples/stage0/snippets/src/Loops.java b/examples/stage0/snippets/src/Loops.java new file mode 100644 index 00000000..a7856a5b --- /dev/null +++ b/examples/stage0/snippets/src/Loops.java @@ -0,0 +1,82 @@ +/* + * Copyright 2026 FRCSoftware + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +class Drivetrain { + public void setThrottle(double speed) {} +} + +boolean condition = false; +Drivetrain drivetrain = new Drivetrain(); +Drivetrain drivetrain = new Drivetrain(); + +void main() { + // [whileSyntax] + while (condition) { + // code to run when condition is true + } + // [/whileSyntax] + + { + // [whileExample] + int i = 0; + while (i < 6) { + System.out.println(i); // prints 0, 1, 2, 3, 4, 5 + i++; + } + // [/whileExample] + } + + // [whileExample2] + int autoTimer = 0; + while (autoTimer <= 15){ + System.out.println("AutoMode is happening"); + autoTimer++; + } + // [/whileExample2] + + + { + // [ForExample1] + int i = 0; + while (i < 6) { + System.out.println("Hi!"); + i++; + } + // [/ForExample1] + } + + // [ForExample2] + for (int i = 0; i < 6; i++) { + System.out.println("Hi!"); + } + //[/ForExample2] + + // + // [forExample] + for (int i = 0; i < 5; i++){ + System.out.println(i); // prints 0, 1, 2, 3, 4 + } + // [/forExample] + + if (false) { + // [Infinite1] + int timer = 0; + while (timer < 7){ + drivetrain.setThrottle(1); // sets drive motors to full speed + } + // [/Infinite1] + } + + { + // [Infinite2] + int timer = 0; + while (timer < 7) { + drivetrain.setThrottle(1); // sets drive motors to full speed + timer++; // increments timer by 1 + } + // [/Infinite2] + } +} \ No newline at end of file diff --git a/examples/stage0/snippets/src/interfaces-lists/DistanceSensor.java b/examples/stage0/snippets/src/interfaces-lists/DistanceSensor.java new file mode 100644 index 00000000..888695bf --- /dev/null +++ b/examples/stage0/snippets/src/interfaces-lists/DistanceSensor.java @@ -0,0 +1,11 @@ +/* + * Copyright 2026 FRCSoftware + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// [distanceSensorInterface] +interface DistanceSensor { + double getDistanceMeters(); +} +// [/distanceSensorInterface] diff --git a/examples/stage0/snippets/src/interfaces-lists/InterfacesListsUsage.java b/examples/stage0/snippets/src/interfaces-lists/InterfacesListsUsage.java new file mode 100644 index 00000000..2447f3ef --- /dev/null +++ b/examples/stage0/snippets/src/interfaces-lists/InterfacesListsUsage.java @@ -0,0 +1,59 @@ +/* + * Copyright 2026 FRCSoftware + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// [importList] +import java.util.ArrayList; +import java.util.List; +// [/importList] + +// [isTooClose] +boolean isTooClose(DistanceSensor sensor) { + return sensor.getDistanceMeters() < 1.0; +} +// [/isTooClose] + +// [genericLast] + T last(T[] items) { + return items[items.length - 1]; +} +// [/genericLast] + +void main() { + // [useDistanceSensorCall] + DistanceSensor ultrasonic = new UltrasonicSensor(); + DistanceSensor lidar = new LidarSensor(); + System.out.println(isTooClose(ultrasonic)); // false + System.out.println(isTooClose(lidar)); // false + // [/useDistanceSensorCall] + + // [genericLastCall] + Point[] path = {new Point(0, 0), new Point(1, 2), new Point(3, 3)}; + DistanceSensor[] sensors = {ultrasonic, lidar}; + + System.out.println(last(path).getX()); // 3.0 + System.out.println(last(sensors).getClass()); // class LidarSensor + // [/genericLastCall] + + // [historyList] + List waypoints = new ArrayList<>(); + // [/historyList] + + // [historyAdd] + waypoints.add(new Point(0, 0)); + waypoints.add(new Point(1, 2)); + System.out.println(waypoints.size()); // 2 + // [/historyAdd] + + // [forEachHistory] + RobotHistoryTracker tracker = new RobotHistoryTracker(Point.ORIGIN); + tracker.move(new Point(3, 0)); + tracker.move(new Point(0, 4)); + + for (Point visited : tracker.getHistory()) { + System.out.println(visited.getX() + ", " + visited.getY()); + } + // [/forEachHistory] +} diff --git a/examples/stage0/snippets/src/interfaces-lists/LidarSensor.java b/examples/stage0/snippets/src/interfaces-lists/LidarSensor.java new file mode 100644 index 00000000..eba15f4f --- /dev/null +++ b/examples/stage0/snippets/src/interfaces-lists/LidarSensor.java @@ -0,0 +1,15 @@ +/* + * Copyright 2026 FRCSoftware + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// [lidarSensorClass] +class LidarSensor implements DistanceSensor { + @Override + public double getDistanceMeters() { + // In real life, this would actually interact with hardware + return 1.2; + } +} +// [/lidarSensorClass] diff --git a/examples/stage0/snippets/src/interfaces-lists/RobotHistoryTracker.java b/examples/stage0/snippets/src/interfaces-lists/RobotHistoryTracker.java new file mode 100644 index 00000000..3e1d9921 --- /dev/null +++ b/examples/stage0/snippets/src/interfaces-lists/RobotHistoryTracker.java @@ -0,0 +1,33 @@ +/* + * Copyright 2026 FRCSoftware + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +import java.util.ArrayList; +import java.util.List; + +// [robotHistoryTrackerClass] +class RobotHistoryTracker { + private Point position; + private final List history = new ArrayList<>(); + + public RobotHistoryTracker(Point startPosition) { + this.position = startPosition; + this.history.add(startPosition); + } + + public void move(Point delta) { + this.position = this.position.plus(delta); + this.history.add(this.position); + } + + public Point getPosition() { + return this.position; + } + + public List getHistory() { + return this.history; + } +} +// [/robotHistoryTrackerClass] diff --git a/examples/stage0/snippets/src/interfaces-lists/UltrasonicSensor.java b/examples/stage0/snippets/src/interfaces-lists/UltrasonicSensor.java new file mode 100644 index 00000000..5c305e46 --- /dev/null +++ b/examples/stage0/snippets/src/interfaces-lists/UltrasonicSensor.java @@ -0,0 +1,15 @@ +/* + * Copyright 2026 FRCSoftware + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +// [ultrasonicSensorClass] +class UltrasonicSensor implements DistanceSensor { + @Override + public double getDistanceMeters() { + // In real life, this would actually interact with hardware + return 1.5; + } +} +// [/ultrasonicSensorClass] diff --git a/public/learning-course/stage0/loops/ForLoop.webp b/public/learning-course/stage0/loops/ForLoop.webp new file mode 100644 index 00000000..d1acde98 Binary files /dev/null and b/public/learning-course/stage0/loops/ForLoop.webp differ diff --git a/public/learning-course/stage0/loops/WhileLoop.webp b/public/learning-course/stage0/loops/WhileLoop.webp new file mode 100644 index 00000000..74e485d0 Binary files /dev/null and b/public/learning-course/stage0/loops/WhileLoop.webp differ diff --git a/src/config/sidebarConfig.ts b/src/config/sidebarConfig.ts index aa086a4e..9c23f986 100644 --- a/src/config/sidebarConfig.ts +++ b/src/config/sidebarConfig.ts @@ -69,10 +69,10 @@ export const sidebarSections: Record = { label: 'Conditionals', slug: 'learning-course/stage0/conditionals', }, - // { - // label: 'Loops', - // slug: 'learning-course/stage0/loops', - // }, + { + label: 'Loops', + slug: 'learning-course/stage0/loops', + }, { label: 'Classes, Fields, and Methods', slug: 'learning-course/stage0/classes-methods', @@ -81,6 +81,14 @@ export const sidebarSections: Record = { // label: 'Methods', // slug: 'learning-course/stage0/methods', // }, + { + label: 'Arrays and For-Each Loops', + slug: 'learning-course/stage0/arrays', + }, + { + label: 'Interfaces, Generics, and Lists', + slug: 'learning-course/stage0/interfaces-lists', + }, ], }, { diff --git a/src/content/docs/learning-course/stage0/arrays.mdx b/src/content/docs/learning-course/stage0/arrays.mdx new file mode 100644 index 00000000..39bbf81a --- /dev/null +++ b/src/content/docs/learning-course/stage0/arrays.mdx @@ -0,0 +1,169 @@ +--- +title: Arrays and For-Each Loops +description: An introduction to arrays and the for-each loop in Java +prev: learning-course/stage0/classes-methods +next: learning-course/stage0/interfaces-lists +codeRegionSources: + default: stage0/snippets/src/Arrays.java +--- + +In an [earlier lesson](/learning-course/stage0/classes-methods/), we defined a `Point` class to represent a location on the field. +In this lesson, we're going to learn about **arrays**, which let us store many values of the same type together, +and the **for-each loop**, a way to loop over those values that's often cleaner than the `for` loop you already know. + +## Why Arrays? + +Suppose your drivetrain has four motors, and you want to keep track of the speed you've commanded for each one. +Without arrays, you'd need a separate variable for every motor: + +{/* rli:ignore */} + +```java +double motor1Speed = 0.5; +double motor2Speed = 0.5; +double motor3Speed = 0.5; +double motor4Speed = 0.5; +``` + +This works for four motors, but it doesn't scale. +If your robot has eight motors, you need eight variables, and any code that operates on "all the motor speeds" has to repeat itself once per variable. +An **array** solves this by storing multiple values of the same type together, as a single variable. + +## Declaring and Creating Arrays + +An array's type is written as the element type followed by square brackets, like `double[]` for an array of `double`s. +The simplest way to create an array is with an "array literal", a comma-separated list of values inside curly braces: + +```java #motorSpeedsLiteral + +``` + +This creates an array of four `double`s, and stores it in the variable `motorSpeeds`. +An array's size is fixed once it's created, so `motorSpeeds` will always hold exactly four values, for as long as it exists. +However, the values in the array can be changed at any time. + + + +## Indexing and Length + +Each value in an array is called an **element**, and you access a specific element using its **index**, the element's position in the array. +Just like `String` and `List` (which we'll see in the next lesson), array indices in Java start at `0`, not `1`. +So in `motorSpeeds`, the first motor's speed is at index `0`, and the last is at index `3`. + +You read and write an element using square brackets after the array's variable name. +Let's update the first motor's speed and print it back: + +```java #setSpeed + +``` + +An array also has a `length`, the number of elements it holds. +Unlike `String.length()`, which is a method, an array's `length` is a **field**, so it's accessed without parentheses: + +```java #speedsLength + +``` + + + +## Arrays of Objects + +An array's element type isn't limited to primitives like `double`; it can be any type, including a class you defined yourself, like `Point`. +Let's define a fixed autonomous path as an array of waypoints, in the order the robot should drive through them: + +```java #pathArray + +``` + +Just like `motorSpeeds`, `path` has a fixed size, which in this case is three, because we created it with three waypoints. +This fits an autonomous path well: the route is planned out ahead of time, so we already know exactly how many waypoints it has. + + + +## Looping Over Arrays + +Arrays are useful because you can loop over their elements instead of writing out each one by hand. +You've already seen the index-based `for` loop; let's use it to add up every motor speed in `motorSpeeds`: + +```java #indexLoopSpeeds + +``` + +This loop's condition, `i < motorSpeeds.length`, is what makes it work for an array of any size: +it always stops right after the last valid index, whether `motorSpeeds` has four elements or forty. + +## The For-Each Loop + +Often, all we need from a loop like this one is "do something with every element," without caring about the index at all. +Java's **for-each loop** makes it easy to do that, with no index variable to manage: + +{/* rli:ignore */} + +```java +for (ElementType element : array) { + // code that uses element +} +``` + +The type before the colon must match the array's element type, and the name after it is a new local variable that holds one element per iteration. +Let's use a for-each loop to print every waypoint in `path`: + +```java #forEachPath + +``` + +This is easier to read than the equivalent index-based loop, since there's no `path[i]` to keep track of; +`waypoint` simply becomes each `Point` in `path`, in order, for one iteration each. + +Sometimes, an index-based loop is unavoidable because you need more than just "the current element." +For example, to find the total distance of the path, we need each waypoint _and_ the one before it, which a for-each loop has no way to express: + +```java #pathLength + +``` + +Here, `path[i - 1]` is the previous waypoint, and `path[i]` is the current one; `i` starts at `1`, since index `0` has no previous waypoint to compare against. +A for-each loop can't reach the previous element, so the index-based `for` loop is the right choice here. + +## Arrays and For-Each Loops Exercise + + diff --git a/src/content/docs/learning-course/stage0/classes-methods.mdx b/src/content/docs/learning-course/stage0/classes-methods.mdx index 615fb2a6..42c194cd 100644 --- a/src/content/docs/learning-course/stage0/classes-methods.mdx +++ b/src/content/docs/learning-course/stage0/classes-methods.mdx @@ -1,8 +1,8 @@ --- title: Classes, Fields, and Methods description: An Introduction to Java classes and objects, as well as their members (fields and methods) -prev: learning-course/stage0/conditionals -next: false +prev: learning-course/stage0/loops +next: learning-course/stage0/arrays codeRegionSources: point: stage0/snippets/src/classes-methods/Point.java tracker: stage0/snippets/src/classes-methods/RobotTracker.java diff --git a/src/content/docs/learning-course/stage0/conditionals.mdx b/src/content/docs/learning-course/stage0/conditionals.mdx index c785037b..34f14421 100644 --- a/src/content/docs/learning-course/stage0/conditionals.mdx +++ b/src/content/docs/learning-course/stage0/conditionals.mdx @@ -2,7 +2,7 @@ title: Conditionals description: An Intro To Conditional Statements prev: learning-course/stage0/operators -next: false +next: learning-course/stage0/loops codeRegionSources: default: stage0/snippets/src/Conditionals.java --- diff --git a/src/content/docs/learning-course/stage0/interfaces-lists.mdx b/src/content/docs/learning-course/stage0/interfaces-lists.mdx new file mode 100644 index 00000000..9f586d8f --- /dev/null +++ b/src/content/docs/learning-course/stage0/interfaces-lists.mdx @@ -0,0 +1,155 @@ +--- +title: Interfaces, Generics, and Lists +description: An introduction to interfaces, generic methods, and the List interface in Java +prev: learning-course/stage0/arrays +next: false +codeRegionSources: + sensor: stage0/snippets/src/interfaces-lists/DistanceSensor.java + ultrasonic: stage0/snippets/src/interfaces-lists/UltrasonicSensor.java + lidar: stage0/snippets/src/interfaces-lists/LidarSensor.java + tracker: stage0/snippets/src/interfaces-lists/RobotHistoryTracker.java + usage: stage0/snippets/src/interfaces-lists/InterfacesListsUsage.java +--- + +In earlier lessons, we wrote classes like `Point` and `RobotTracker` to represent things in our program. +In this lesson, we'll learn about **interfaces**, a way to describe what a class can do without saying how it does it, +**generics**, a way to write code that works with more than one type, and the **`List`** interface, a more flexible alternative to arrays. + +## Why Interfaces? + +Suppose your robot needs to measure its distance from a wall during autonomous. +One year, your team might use an ultrasonic sensor; the next, a LiDAR sensor. +Both measure distance, but they're different pieces of hardware, controlled by different code. + +If the rest of your robot code is written to only work with one specific sensor class, swapping hardware means rewriting everything that used it. +An **interface** solves this by describing what a sensor can do, without saying which specific sensor it is: + +```java {sensor}#distanceSensorInterface + +``` + +An interface looks like a class, but its methods have no bodies, just a signature ending in a semicolon. +It's a contract: any class that **implements** `DistanceSensor` must provide a `getDistanceMeters()` method. + +Here are two classes that each implement that contract, in their own way: + +```java {ultrasonic}#ultrasonicSensorClass + +``` + +```java {lidar}#lidarSensorClass + +``` + + + +Because both classes implement `DistanceSensor`, code that only knows about `DistanceSensor` can work with either one: + +```java {usage}#useDistanceSensorCall + +``` + +Here, `isTooClose` is defined to take a `DistanceSensor`, so it doesn't matter whether we pass in an `UltrasonicSensor` or a `LidarSensor`. +If your team switches sensors next season, this method doesn't need to change at all. + +## A Generic Method + +Interfaces let one piece of code work with several related types. +**Generics** go a step further, letting a method work with _any_ type. +Here's a method that returns the last element of an array, no matter what it's an array of: + +```java {usage}#genericLast + +``` + +The `` before the return type introduces a **type parameter**, a placeholder for a type that isn't decided until the method is called. +Inside the method, `T` acts like a real type: the parameter is `T[]`, and the return type is `T`. + +We can call `last` with completely unrelated array types, and it works for both: + +```java {usage}#genericLastCall + +``` + +When we call `last(path)`, Java fills in `T` with `Point`; when we call `last(sensors)`, it fills in `T` with `DistanceSensor`. +We didn't have to write a separate method for each case. + +## Packages and Imports + +So far, every class we've written has had no package, which is why our classes could use each other with no `import` statements at all. +Classes built into the Java Development Kit (JDK), classes from external libraries like WPILib, +and classes in our projects live in **packages**, named groups of classes. +A package's name exactly matches the directory it lives in. +For example, all of the classes in the `java.util` package live in the `java/util` directory of the JDK library. +Robot code typically lives in the `first.robot` package, which you'll see when you start Stage 1 of this course. + +To use a class from a package, you need an `import` statement at the top of the file, naming the exact class you want: + +```java {usage}#importList + +``` + +This imports `ArrayList` and `List` from the `java.util` package, which we'll use next. +Later in the course, you'll import classes the same way from WPILib packages, such as `org.wpilib.math.geometry.Translation2d`. + +## The `List` Interface and `ArrayList` + +In the [previous lesson](/learning-course/stage0/arrays/), we used arrays to store multiple values together. +An array's size is fixed once it's created, which works well when you know exactly how many elements you'll need, like a fixed autonomous path. +But sometimes you don't know the size ahead of time, for example, if you want to record the robot's position every time it moves, for as long as the match lasts. + +`List` is an interface, like `DistanceSensor`, that describes a collection that can grow and shrink. +`ArrayList` is a class that implements `List`: + +```java {usage}#historyList + +``` + +Just like `DistanceSensor sensor = new UltrasonicSensor();`, the declared type (`List`) is an interface, and the object we create (`new ArrayList<>()`) is one specific implementation of it. +`` tells Java that this particular `List` holds `Point`s; `List` itself is generic, the same way `last` was. + +A `List` doesn't have a fixed size, you add elements to it as you go, and it grows to fit: + +```java {usage}#historyAdd + +``` + + + +## Giving `RobotTracker` a Memory + +`RobotTracker`, from a [previous lesson](/learning-course/stage0/classes-methods/), keeps track of the robot's current position, but forgets everywhere it's been. +Let's add the ability to remember every position the robot has visited, not just the current one, using a `List`: + +```java {tracker}#robotHistoryTrackerClass + +``` + + + +`getHistory()` returns the `List` of every position `move` has ever moved to, in order. +We can loop over it with a for-each loop, exactly the way we looped over arrays in the previous lesson: + +```java {usage}#forEachHistory + +``` + +Even though `history` grows every time `move` is called, the for-each loop doesn't need to know how many positions it will visit; it simply visits all of them. + +## Interfaces, Generics, and Lists Exercise + + diff --git a/src/content/docs/learning-course/stage0/loops.mdx b/src/content/docs/learning-course/stage0/loops.mdx new file mode 100644 index 00000000..e6261bb1 --- /dev/null +++ b/src/content/docs/learning-course/stage0/loops.mdx @@ -0,0 +1,181 @@ +--- +title: Loops +description: An Intro loops in Java +prev: learning-course/stage0/conditionals +next: learning-course/stage0/classes-methods +codeRegionSources: + default: stage0/snippets/src/Loops.java +--- + +Oftentimes we want to do the same action multiple times in a row. +For instance, if you know your grades are about to be released, you might repeatedly check them until they come out. +In Java we can use loops to do this. + +We will be going over two types of loops which are: + +- while +- for + + + +Conditionals and loops may seem similar but they have different purposes. +Conditionals are used to make decisions based on whether the condition is true or false. +Loops are used to repeat code until the condition is met. +This can be thought of conditionals make decisions, and loops are for repeating. + +## while + +`while` loops are the most simple type of loops. +If you have used block coding before, this is similar to the repeat block. +If you have taken an CS class, you might already be familiar with a `while` loop. + +The syntax of a `while` loops is as shown: + +```java #whileSyntax + +``` + +You might notice that a `while` loop has a similar syntax to conditionals, which was discussed in the previous section. +A `while` loop's syntax includes: + +- `while` is a keyword +- `( )` holds the condition that is either true or false. + Example: (5 > 1) is a condition and it is true because 5 is greater than 1 +- `{` an open bracket is used to denote the opening of the loop +- `}` a closed bracket is used to denote the end of the loop + +Another way of understanding how a `while` loop works is with the flow chart below + + + +Similar to conditionals, a `while` loop will run the code block inside the `while` loop when the condition is true. +After the code block is run, it goes back to the condition. +If the condition is true, the code block will run again. +This will repeat until the condition is false. +When it's false, the loop will be skipped. +To understand how this works, let's look at an example. + +```java #whileExample + +``` + +In the example, there is an `int` called `i` which holds the value 0. The `while` loop has the condition `i < 6`. +First, the compiler checks if the condition is true. +We know that 0 is less than 6 so the `while` code block runs and the value of `i`, which is currently 0, is printed to the terminal. +The value of `i` is also updated because of `i++` and it changes to 1. +Now the condition checks if 1 is less than 6. We know that it is true, so the value of `i` gets printed and the value of `i` is increased by 1. +This repeats and eventually `i`'s value becomes 6. +6 is not less than 6, therefore the loop is done and the `while` code block does not run. + + + +Lets look at an another example! +In the example below we have: + +```java #whileExample2 + +``` + +Without running the code, what do you think happens? + +`autoTimer` is set to 0. The `while` loop's condition is `autoTimer <= 15`. +0 is less than 15 so the code enters the `while` code block, and prints outs `Auto is happening`. +`autoTimer++` is run which increases `autoTimer`'s value by one. +The code goes back to the condition, 1 is less than 15, so the code enters the `while` code block again, printing out `Auto is happening`. +Like before, `autoTimer++` runs which increases `autoTimer` by one again making the value be 2. This repeats until `autoTimer` is 16. When that happens the condition is false and the `while` loop is skipped. + +## for + +With the power of while loops, we're able to repeat a block of code any number of times, like so: + +```java #ForExample1 + +``` + +This loop depends on 3 important statements: +`int i = 0;`, `i < 6`, and `i++`. +For loops allow us to inline these statements: + +```java #ForExample2 + +``` + +Using the example above, we can see that the `for` loop syntax goes as follows: + +- `for` is a keyword +- `()` holds the three statements +- `{` an open bracket is used to denote the opening of the loop +- `}` a closed bracket is used to denote the end of the loop + +The three statements are + +- **initialization**: creates a variable that sets the starting point of the loop. + This is the `int i = 0;` seen in the example above. +- **condition**: a condition, which uses the variable, that is checked before each iteration. + This is `i < 6;`. + If the condition is true, the code inside the loop runs +- **update**: updates the variable created in initialization after each iteration. + Lastly, that's `i++`; + +Let's look at another example: + +```java #forExample + +``` + +In this example, we create a variable `i` that is set to 0. When `i` is less than 5, the `for` code block runs, printing the value of `i` which is 0. +Then it goes back to the update statement which is `i++`, `i` has increased by 1 and `i`'s value is now 1. +We check the condition, 1 is less than 5, so `for` code block runs, the new value of `i` is printed, `i` is updated and this repeats until `i` is no longer less than 5. +When `i` is no longer less than 5, the `for` loop is skipped. + +## Be Careful about Infinite Loops + +It is important to make sure that the condition can become false. +If the condition is always true, the loop will always run causing an infinite loop. +Infinite loops can be prevented by ensuring that the value inside the condition changes by incrementing or decrementing. + + + +```java #Infinite1 + +``` + +In this example, we want our drive train to run for 7 seconds. +We have our variable called `timer` which is set to 0. +0 is less than 7 so the code inside runs and the robot drives forward at full speed. +However, `timer`'s value never changes. +This means `timer` will always be 0. 0 is less than 7 so the loop will continuously run and the robot never stops driving! + +To fix this, we would make sure to increment the timer value as shown below. + +```java #Infinite2 + +``` + +`timer` now increments by 1 each time the loop is run, and the robot will stop driving after 7 seconds. + +## Loops Exercise + +