Java syntax practice — 3 real programs to stop fearing the semicolon

In the theory article we covered Java’s structure — class, main method, System.out.println and semicolons. Now it’s time to write real programs from scratch. The goal of this practice is one: make the structure come out automatically without having to think about it, and make the semicolon stop costing you failed compilations.

Open VS Code, create a folder syntax_practice and a .java file for each program. Remember: the filename must match the class name exactly, including capitalisation.

Java syntax practice — Program 1: Basic calculator with Scanner

This program asks the user for two numbers and shows the result of the four operations. It’s the first real contact with Scanner and with the write → compile → execute cycle you’ll use in every FP2 lab.

import java.util.Scanner;

public class Calculator {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.println("=== BASIC CALCULATOR ===");
        System.out.println();

        System.out.print("First number: ");
        double a = sc.nextDouble();

        System.out.print("Second number: ");
        double b = sc.nextDouble();

        System.out.println();
        System.out.println("--- Results ---");
        System.out.printf("%.2f + %.2f = %.2f%n", a, b, a + b);
        System.out.printf("%.2f - %.2f = %.2f%n", a, b, a - b);
        System.out.printf("%.2f × %.2f = %.2f%n", a, b, a * b);

        if (b != 0) {
            System.out.printf("%.2f / %.2f = %.2f%n", a, b, a / b);
        } else {
            System.out.println("Division: cannot divide by zero");
        }

        // Integer division and remainder
        int ia = (int) a;
        int ib = (int) b;
        if (ib != 0) {
            System.out.printf("%d / %d = %d (integer division)%n", ia, ib, ia / ib);
            System.out.printf("%d %% %d = %d (remainder)%n", ia, ib, ia % ib);
        }

        System.out.println();
        System.out.printf("Power: %.2f ^ 2 = %.2f%n", a, a * a);
        System.out.printf("Absolute value of %.2f = %.2f%n", a, Math.abs(a));

        sc.close();
    }
}

Compile and run:

javac Calculator.java
java Calculator

Output with 7 and 3:

=== BASIC CALCULATOR ===

First number: 7
Second number: 3

--- Results ---
7.00 + 3.00 = 10.00
7.00 - 3.00 = 4.00
7.00 × 3.00 = 21.00
7.00 / 3.00 = 2.33
7 / 3 = 2 (integer division)
7 % 3 = 1 (remainder)

Power: 7.00 ^ 2 = 49.00
Absolute value of 7.00 = 7.00

Two things to pay attention to. %% inside printf produces a literal % — a single % would be interpreted as the start of a format specifier and cause an error. And Math.abs() is the first function from Java’s math library — you don’t need to import it, Math is always available.

The error that will appear most in this program

System.out.printf("%.2f + %.2f = %.2f%n", a, b, a + b)   // ERROR — missing ;
System.out.printf("%.2f + %.2f = %.2f%n", a, b, a + b);  // CORRECT

The compiler will tell you exactly which line is missing the semicolon. Read the error message — it always points to the problem line or the line immediately after.

Java syntax practice — Program 2: Student profile

This program collects a student’s data and generates a formatted report. It shows how to combine nextLine(), nextInt(), nextDouble() and printf in a real program, and introduces the nextLine() trick after nextInt().

import java.util.Scanner;

public class StudentProfile {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.println("=== STUDENT REGISTRATION ===");
        System.out.println();

        // Personal data
        System.out.print("Full name: ");
        String name = sc.nextLine();

        System.out.print("Age: ");
        int age = sc.nextInt();
        sc.nextLine();    // consume leftover newline

        System.out.print("Degree: ");
        String degree = sc.nextLine();

        System.out.print("Average grade (0-10): ");
        double grade = sc.nextDouble();

        // Calculations
        int birthYear = 2025 - age;
        double gradeOutOf100 = grade * 10;
        String status = (grade >= 5.0) ? "Passed" : "Failed";

        // Classification
        String classification;
        if (grade >= 9.0)      classification = "Outstanding";
        else if (grade >= 7.0) classification = "Merit";
        else if (grade >= 5.0) classification = "Passed";
        else                   classification = "Failed";

        // Formatted output
        System.out.println();
        System.out.println("================================");
        System.out.println("        STUDENT PROFILE         ");
        System.out.println("================================");
        System.out.printf("Name:           %s%n", name);
        System.out.printf("Age:            %d years (born %d)%n", age, birthYear);
        System.out.printf("Degree:         %s%n", degree);
        System.out.println("--------------------------------");
        System.out.printf("Grade:          %.2f / 10.00%n", grade);
        System.out.printf("Out of 100:     %.1f%%%n", gradeOutOf100);
        System.out.printf("Classification: %s%n", classification);
        System.out.printf("Status:         %s%n", status);
        System.out.println("================================");

        // String operations
        System.out.printf("%nName has %d characters%n", name.length());
        System.out.printf("First letter: %c%n", name.charAt(0));
        System.out.printf("Uppercase: %s%n", name.toUpperCase());

        sc.close();
    }
}

Output with “Sergio Medina”, 20, “GCID”, 7.85:

================================
        STUDENT PROFILE         
================================
Name:           Sergio Medina
Age:            20 years (born 2005)
Degree:         GCID
--------------------------------
Grade:          7.85 / 10.00
Out of 100:     78.5%
Classification: Merit
Status:         Passed
================================

Name has 13 characters
First letter: S
Uppercase: SERGIO MEDINA

The lone sc.nextLine() after sc.nextInt() is the most important trick in this program. Without it, the next sc.nextLine() call would read the newline character left behind by nextInt() and degree would appear empty. Always add it after nextInt(), nextDouble() or any method that isn’t nextLine().

Java syntax practice — Program 3: Text patterns and ASCII art

Patterns with loops are a staple of the first FP2 labs. This program generates several using printf and the concatenation operator, showing how to control exactly what gets printed character by character.

import java.util.Scanner;

public class Patterns {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.println("=== TEXT PATTERNS ===");
        System.out.println();

        System.out.print("Size (3-10): ");
        int n = sc.nextInt();

        // Pattern 1 — Asterisk triangle
        System.out.println("\n--- Triangle ---");
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < i; j++) {
                System.out.print("* ");
            }
            System.out.println();
        }

        // Pattern 2 — Square with border
        System.out.println("\n--- Square with border ---");
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i == 0 || i == n-1 || j == 0 || j == n-1) {
                    System.out.print("# ");
                } else {
                    System.out.print("  ");
                }
            }
            System.out.println();
        }

        // Pattern 3 — Formatted multiplication table
        System.out.println("\n--- Multiplication table (1 to " + n + ") ---");
        System.out.print("   ");
        for (int j = 1; j <= n; j++) {
            System.out.printf("%4d", j);
        }
        System.out.println();
        System.out.print("   ");
        System.out.println("----".repeat(n));

        for (int i = 1; i <= n; i++) {
            System.out.printf("%2d |", i);
            for (int j = 1; j <= n; j++) {
                System.out.printf("%4d", i * j);
            }
            System.out.println();
        }

        // Pattern 4 — Number pyramid
        System.out.println("\n--- Pyramid ---");
        for (int i = 1; i <= n; i++) {
            for (int s = 0; s < n - i; s++) {
                System.out.print("  ");
            }
            for (int j = 1; j <= i; j++) {
                System.out.printf("%2d", j);
            }
            for (int j = i - 1; j >= 1; j--) {
                System.out.printf("%2d", j);
            }
            System.out.println();
        }

        // ASCII art — letter J
        System.out.println("\n--- Letter J in ASCII ---");
        System.out.println("  * * * *");
        System.out.println("      *  ");
        System.out.println("      *  ");
        System.out.println("*     *  ");
        System.out.println("* * * *  ");

        sc.close();
    }
}

Output with n=4:

--- Triangle ---
* 
* * 
* * * 
* * * * 

--- Square with border ---
# # # # 
#       # 
#       # 
# # # # 

--- Multiplication table (1 to 4) ---
      1   2   3   4
   ----------------
 1 |   1   2   3   4
 2 |   2   4   6   8
 3 |   3   6   9  12
 4 |   4   8  12  16

--- Pyramid ---
       1
     1 2 1
   1 2 3 2 1
 1 2 3 4 3 2 1

--- Letter J in ASCII ---
  * * * *
      *  
      *  
*     *  
* * * *

Nested patterns are the first place where a misplaced semicolon causes real damage. Watch out for this classic mistake:

for (int j = 0; j < i; j++);    // ERROR — ; ends the for here
{                                // this block only runs once
    System.out.print("* ");
}

The compiler won’t warn you — the program compiles and runs, but the output is wrong. If a loop doesn’t seem to be working, check that it doesn’t have a semicolon after the closing parenthesis.

Visualise with Python Tutor

Select Java from the dropdown and paste in pythontutor.com:

public class Demo {
    public static void main(String[] args) {
        String name = "Sergio";
        int age = 20;
        double grade = 7.85;

        System.out.printf("Name:  %s%n", name);
        System.out.printf("Age:   %d%n", age);
        System.out.printf("Grade: %.2f%n", grade);

        for (int i = 1; i <= 4; i++) {
            for (int j = 0; j < i; j++) {
                System.out.print("* ");
            }
            System.out.println();
        }
    }
}

Step through and observe three things. Each declared variable appears in the main frame with its type and value. The printf with %s, %d and %.2f replaces each specifier with the corresponding value in order. In the nested loop, the inner counter j is created and destroyed on each iteration of the outer i — Python Tutor shows exactly when each variable appears and disappears.

Summary and next step

In this practice you wrote three complete Java programs from scratch. The semicolon should no longer catch you off guard — it comes at the end of every statement, never after the parenthesis of a for or if. In the next article you’ll find exercises to solve on your own.

Next step: exercisesJava syntax exercises — write code that works first time

Sigue aprendiendo

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *