Skip to content

Code grading examples

At a glance

CuraCourse Code Grading does not run unittest or JUnit. It runs a command in the sandbox and compares stdout to Expected Output.

When you add a hidden grader file, that file should do the checking and print:

  • PASS when a check succeeds
  • FAILED plus a short reason when it does not (what was called, what it got, what you expected)

Set Expected Output to one PASS line per check. Turn on Show diff of actual output and expected output so learners see the FAILED line. Use Exact match.

Whole programs with no grader file still compare printed output the usual way (Pattern A).

Prerequisites

How to set up each example

  1. Add Code Grading on the Code Editor.
  2. Set Run command as shown in the example (it must compile/run the grader, not only the starter filename).
  3. Fill Input only when the student program reads stdin. Put each value on its own line.
  4. Paste Expected Output: for grader files, one PASS per check; for whole programs, the program’s printed text.
  5. Optionally Add File for grader.py or Grader.java.
  6. Click Run Test with a sample solution before you assign the lesson.

Do not name a rubric file the same as the student file (main.py, Main.java). Same path replaces the student file.

Pattern A — Whole program (print / input)

Use this when students write a complete program. No extra grader file. Run their file and compare what it prints.

Python: Hello World

Run command: python3 main.py

Expected Output:

Hello World

Student main.py:

print("Hello World")

Java: Hello World

Run command: javac Main.java && java Main

Expected Output:

Hello World

Student Main.java:

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}

Python: input and output

Students prompt for first and last name, then print Hello, Jane Doe!

Run command: python3 main.py

Input (one value per line):

Jane
Doe

Expected Output (prompts are part of stdout in Python):

What is your first name? Jane
What is your last name? Doe
Hello, Jane Doe!

If you only care about the greeting, turn on Ignore Case / Ignore Whitespace, or use Partial match with Hello, Jane Doe! as expected output. Add a second Code Grading item with different names (for example Joe / Mazzone) so they cannot hardcode one sample.

Student main.py:

fname = input("What is your first name? ")
lname = input("What is your last name? ")
print("Hello, " + fname + " " + lname + "!")

Java: Scanner input and output

Run command: javac Main.java && java Main

Input:

Jane
Doe

Expected Output (Java nextLine() does not echo the typed text — match what your starter actually prints):

What is your first name?
What is your last name?
Hello, Jane Doe!

Student Main.java:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.println("What is your first name?");
        String fname = in.nextLine();
        System.out.println("What is your last name?");
        String lname = in.nextLine();
        System.out.println("Hello, " + fname + " " + lname + "!");
    }
}

Pattern B — Return values (hidden grader that prints PASS / FAILED)

Students write a function/method and do not need a main. You add a hidden grader that calls it, compares the result, and prints PASS or FAILED. CuraCourse only needs to match a list of PASS lines.

Starter should be only the function stub so importing/compiling it does not wait for input. The grader should print only PASS / FAILED lines — not the raw return values.

Python: add_five

Students write add_five(number) that returns the argument plus 5.

Run command: python3 grader.py

Files → add grader.py:

from main import add_five

def check(label, actual, expected):
    if actual == expected:
        print('PASS')
    else:
        print('FAILED: ' + label + ' got ' + str(actual) + ', expected ' + str(expected))

check('add_five(5)', add_five(5), 10)
check('add_five(0)', add_five(0), 5)
check('add_five(6)', add_five(6), 11)

Expected Output:

PASS
PASS
PASS

If a student returns the wrong value, they see something like FAILED: add_five(0) got 0, expected 5 in the diff.

Student main.py:

def add_five(number):
    return number + 5

Java: addFive

Students write a class with public static int addFive(int number).

Run command: javac Main.java Grader.java && java Grader

Files → add Grader.java:

public class Grader {
    static void check(String label, int actual, int expected) {
        if (actual == expected) {
            System.out.println("PASS");
        } else {
            System.out.println("FAILED: " + label + " got " + actual + ", expected " + expected);
        }
    }

    public static void main(String[] args) {
        check("addFive(5)", Main.addFive(5), 10);
        check("addFive(0)", Main.addFive(0), 5);
        check("addFive(6)", Main.addFive(6), 11);
    }
}

Expected Output:

PASS
PASS
PASS

Student Main.java:

public class Main {
    public static int addFive(int number) {
        return number + 5;
    }
}

Python: average (five numbers → float)

Calling average(1, 5, 7, 4, 10) should return 5.4. Compare with a small tolerance so float noise does not fail the check.

Run command: python3 grader.py

Files → grader.py:

from main import average

def check(label, actual, expected):
    if abs(actual - expected) < 0.001:
        print('PASS')
    else:
        print('FAILED: ' + label + ' got ' + str(actual) + ', expected ' + str(expected))

check('average(1, 5, 7, 4, 10)', average(1, 5, 7, 4, 10), 5.4)
check('average(5, 9, 24, 6, 4)', average(5, 9, 24, 6, 4), 9.6)

Expected Output:

PASS
PASS

Student main.py:

def average(a, b, c, d, e):
    return (a + b + c + d + e) / 5

Java: average

Run command: javac Main.java Grader.java && java Grader

Files → Grader.java:

public class Grader {
    static void check(String label, double actual, double expected) {
        if (Math.abs(actual - expected) < 0.001) {
            System.out.println("PASS");
        } else {
            System.out.println("FAILED: " + label + " got " + actual + ", expected " + expected);
        }
    }

    public static void main(String[] args) {
        check("average(1, 5, 7, 4, 10)", Main.average(1, 5, 7, 4, 10), 5.4);
        check("average(5, 9, 24, 6, 4)", Main.average(5, 9, 24, 6, 4), 9.6);
    }
}

Expected Output:

PASS
PASS

Student Main.java:

public class Main {
    public static double average(int a, int b, int c, int d, int e) {
        int s = a + b + c + d + e;
        return (double) s / 5;
    }
}

Python: has_repeat

Return True if a string contains the same letter twice in a row.

Run command: python3 grader.py

Files → grader.py:

from main import has_repeat

def check(label, actual, expected):
    if actual == expected:
        print('PASS')
    else:
        print('FAILED: ' + label + ' got ' + str(actual) + ', expected ' + str(expected))

check('has_repeat(mississippi)', has_repeat('mississippi'), True)
check('has_repeat(capsized)', has_repeat('capsized'), False)
check('has_repeat(mazzone)', has_repeat('mazzone'), True)
check('has_repeat(this)', has_repeat('this'), False)

Expected Output:

PASS
PASS
PASS
PASS

Student main.py:

def has_repeat(word):
    for i in range(len(word) - 1):
        if word[i] == word[i + 1]:
            return True
    return False

Java: hasRepeat

Run command: javac Main.java Grader.java && java Grader

Files → Grader.java:

public class Grader {
    static void check(String label, boolean actual, boolean expected) {
        if (actual == expected) {
            System.out.println("PASS");
        } else {
            System.out.println("FAILED: " + label + " got " + actual + ", expected " + expected);
        }
    }

    public static void main(String[] args) {
        check("hasRepeat(mississippi)", Main.hasRepeat("mississippi"), true);
        check("hasRepeat(capsized)", Main.hasRepeat("capsized"), false);
        check("hasRepeat(mazzone)", Main.hasRepeat("mazzone"), true);
        check("hasRepeat(this)", Main.hasRepeat("this"), false);
    }
}

Expected Output:

PASS
PASS
PASS
PASS

Student Main.java:

public class Main {
    public static boolean hasRepeat(String str) {
        for (int i = 0; i < str.length() - 1; i++) {
            if (str.substring(i, i + 1).equals(str.substring(i + 1, i + 2))) {
                return true;
            }
        }
        return false;
    }
}

Python: print function (void that prints)

Students write print_hello() that prints Hello World (it returns nothing). Capture that print, then emit PASS or FAILED — otherwise the student text would mix with the grader output.

Run command: python3 grader.py

Files → grader.py:

import io
import sys
from main import print_hello

def check(label, actual, expected):
    if actual == expected:
        print('PASS')
    else:
        print('FAILED: ' + label + ' got ' + repr(actual) + ', expected ' + repr(expected))

buf = io.StringIO()
old = sys.stdout
sys.stdout = buf
print_hello()
sys.stdout = old
check('print_hello()', buf.getvalue().strip(), 'Hello World')

Expected Output:

PASS

Student main.py:

def print_hello():
    print("Hello World")

Pattern C — Classes (toString and void methods)

Construct the object in a hidden grader, compare toString / __str__, and capture anything void methods print so only PASS / FAILED reach stdout.

Java: Employee

Students create Employee with name, 4-digit id, hourly salary, a constructor, toString() in the form:

John Doe -- 4545 -- $15.67 per hour

and getRaise(double amount) that increases salary and prints Nice you got a $1.0 raise!

Run command: javac Employee.java Grader.java && java Grader

Files → Grader.java:

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

public class Grader {
    static void check(String label, String actual, String expected) {
        if (actual.equals(expected)) {
            System.out.println("PASS");
        } else {
            System.out.println("FAILED: " + label + " got \"" + actual + "\", expected \"" + expected + "\"");
        }
    }

    public static void main(String[] args) {
        Employee e = new Employee("John Doe", 4545, 15.67);
        check("toString()", e.toString(), "John Doe -- 4545 -- $15.67 per hour");

        PrintStream original = System.out;
        ByteArrayOutputStream buf = new ByteArrayOutputStream();
        System.setOut(new PrintStream(buf));
        e.getRaise(1.0);
        System.setOut(original);
        check("getRaise(1.0) message", buf.toString().trim(), "Nice you got a $1.0 raise!");
        check("toString() after raise", e.toString(), "John Doe -- 4545 -- $16.67 per hour");
    }
}

Expected Output:

PASS
PASS
PASS

Add a second Code Grading item for another employee (for example Bob Bobbington, 5555, 10.5, raise 0.4). Use a different grader filename per item, or one rubric item per test, so Files do not collide.

Sample student Employee.java:

public class Employee {
    private String name;
    private int id;
    private double salary;

    public Employee(String n, int i, double s) {
        name = n;
        id = i;
        salary = s;
    }

    public String toString() {
        return name + " -- " + id + " -- $" + salary + " per hour";
    }

    public void getRaise(double amount) {
        salary += amount;
        System.out.println("Nice you got a $" + amount + " raise!");
    }
}

Gotcha: 1.0 vs 1 in the raise message depends on how students print amount. If that is not part of the spec, skip the message check and only compare toString() after the raise.

Python: same Employee idea

Run command: python3 grader.py

Files → grader.py:

import io
import sys
from main import Employee

def check(label, actual, expected):
    if actual == expected:
        print('PASS')
    else:
        print('FAILED: ' + label + ' got ' + repr(actual) + ', expected ' + repr(expected))

e = Employee('John Doe', 4545, 15.67)
check('str(employee)', str(e), 'John Doe -- 4545 -- $15.67 per hour')

buf = io.StringIO()
old = sys.stdout
sys.stdout = buf
e.get_raise(1.0)
sys.stdout = old
check('get_raise(1.0) message', buf.getvalue().strip(), 'Nice you got a $1.0 raise!')
check('str(employee) after raise', str(e), 'John Doe -- 4545 -- $16.67 per hour')

Expected Output:

PASS
PASS
PASS

Student main.py:

class Employee:
    def __init__(self, name, id, salary):
        self.name = name
        self.id = id
        self.salary = salary

    def __str__(self):
        return f"{self.name} -- {self.id} -- ${self.salary} per hour"

    def get_raise(self, amount):
        self.salary += amount
        print(f"Nice you got a ${amount} raise!")

Partial credit

Each Code Grading item is all-or-nothing. Several PASS lines in one grader still succeed or fail together. To give “2 of 3 tests,” add three items (for example 1 point each), each with its own grader calls or stdin pair.