Late submissions are a reality in most courses, and manually applying penalties can be tedious and inconsistent. With CodeGrade AutoTest, you can fully automate late point deductions using a small script and the built-in rubric system.
This guide walks you through setting up a penalty system that deducts 1 point per day late, up to a maximum of 10 points.
How It Works
Each submission in CodeGrade includes:
- submitted_at: When the student submitted the work.
- deadline: The assigned due date (automatically stored per assignment or per student).
Using this metadata, we’ll:
- Compare the submission time to the deadline.
- Calculate how many full days late the submission was.
- Deduct 1 point per day late.
- Apply that deduction to the rubric via AutoTest.

Step 1: Create a Rubric Category
Go to your assignment settings > Rubric and create a continuous rubric category to handle late penalties:
- Name: Late Penalty
- Minimum Points: -10
- Maximum Points: 0
This allows up to 10 points to be deducted automatically, without any manual grading required.

Step 2: Add a Hidden Custom Test Block
Now go to the AutoTest Test, and follow these steps:
1. Add a Connect Rubric Block: Link it to the Late Penalty rubric category you created.
2. Inside it, add a Hide Config Block: This prevents students from seeing the test script output or logic.
3. Inside that, add a Custom Test Block: Use the script below to calculate the late penalty and output it in a format CodeGrade Custom Test understands.

Script
-!- CODE language-py -!-#!/bin/bash
python3 <<EOF
import os
import json
import math
from datetime import datetime, timedelta
ONE_DAY = timedelta(days=1)
# Load submission info
cg_info = json.loads(os.environ["CG_INFO"])
submitted_at = datetime.fromisoformat(cg_info["submitted_at"].replace("Z", "+00:00"))
deadline = datetime.fromisoformat(cg_info["deadline"].replace("Z", "+00:00"))
# Calculate how many days late
days_late = math.ceil((submitted_at - deadline) / ONE_DAY)
# Determine score
if days_late <= 0:
print("Submitted on time")
print('{ "tag": "points", "points": "1" }', file=open(3, "w"))
elif days_late <= 10:
print(f"{days_late} day(s) late")
score = 1 - days_late / 10
print(f'{{ "tag": "points", "points": "{score}" }}', file=open(3, "w"))
else:
print("Very late, maximum penalty")
print('{ "tag": "points", "points": "0" }', file=open(3, "w"))
EOF
This setup ensures that late penalties are applied automatically, fairly, and invisibly, saving time for instructors and ensuring consistency for students.
You can use this configuration as a starting point and customize it to match your course policies. For example:
- Add a grace period before penalties begin.
- Reduce the penalty rate (e.g., 0.5 points per day).
- Apply maximum caps, weekend leniency, or per-student deadline overrides.
Click here for an overview of custom test blocks in CodeGrade.
Do you have more ideas for custom testing? Contact support@codegrade.com today!
%20(800%20x%20525%20px)%20(800%20x%20525%20px)%20(11).png)
%20(800%20x%20525%20px)%20(800%20x%20525%20px)%20(10).png)
%20(800%20x%20525%20px)%20(800%20x%20525%20px)%20(9).png)