PASS — Preparing Programming Assignments for Submission System
This application was written for the School of Computing Sciences, UEA to help prepare programming assignments for submission according to the school requirements. Source code is now available on GitHub.
Requirements
Variants
The following applications all use the same passlib.jar backend:
- PASS GUI
- the original application with a GUI frontend.
- PASS CLI
- a command line alternative for devices that don’t support a graphical user interface.
- Server PASS
- a variation of PASS CLI used in a Docker image running on a server for student’s studying remotely.
- PASS Editor
- provides a primitive text editor interface
for use by students sitting a practical exam in the lab. Unlike common
IDEs, this doesn’t provide any hints or autofilling. (So it’s like
switching off the spellchecker and grammar checker for students who
are allowed to use a word processor when sitting an English exam.)
Basic editing functions (undo/redo, copy, cut, paste, go to line, and search) are provided. There is a basic project file navigation panel with the ability to create additional files. Required files are created automatically and assignment resource files are fetched. The editor panel doesn’t allow the resource files to be edited. However it is possible for the student to use another installed text editor to modify them.
There is a function for compiling and running the code in the project directory for testing purposes. As with other PASS applications, this obeys the
compile
,run
andbuild
attributes. However, this function doesn’t refresh the project resource files from the original remote location as it’s designed for quick testing.There is another function that runs the PASS backend which copies the project files to PASS’s working directory and will fetch the project resource files from their remote location. So if the student does use another editor to modify their local copy of the resource files those modifications won’t make it into the version used by the backend.
Resource Files (Courses)
The local and remote resource XML files have the same syntax.
Note that the URL must be the exact address. Redirects aren’t permitted (including
any redirects from http:
to https:
). SSL/TCP requires a valid
certificate in Java’s cacerts file. The same applies for URL
references in other elements described below.
There’s a dummy course available for testing in the referenced
dummy-resources.xml file:
<resource name="CMP-123XY" href="http://www.dickimaw-books.com/software/pass/dummy-assignments.xml"> Dummy Course for Testing </resource>You can use this as a template for new courses but I recommend a better naming scheme. For example, CMP-123XY.xml. Remember to use one
<resource>
tag per course.
You may omit the remote resource file and just have all the courses defined within the local lib/resources.xml file. The disadvantage with this is that if you need to add a new course you will need to update the local lib/resources.xml file for each installed version of PASS (for all variants). This is particularly awkward for Server PASS as it would require rebuilding the Docker image.
Each course that uses PASS for student submissions needs to have
an assignment XML file that the lecturer can edit to add the assignment data.
These XML files need to be placed somewhere on the university’s
site in a location that can be accessed by the PASS application.
For each course, a corresponding resource
block must be
added to the local lib/resources.xml file
or remote resource file (as described earlier), with
the name
element set to the course code ("CMP-123XY" in
the above example) and the
href
element set to the URL of the assignment database.
The content of the resource
block ("Dummy Course for
Testing" in the above example) is the course title. You may
additionally add debug="true"
or
debug="on"
if you only want the course available when
PASS is running in debug mode.
The PASS application will search for the compiler on the OS
path. If the compiler isn’t on the system path, you can specify the
location in the lib/resources.xml file using the
application
tag with the name
element set
to the application identifier (e.g. javac
) and the
uri
element set to the URI of the application’s path.
For example:
<application name="javac" uri="file:///usr/java/latest/bin/javac" />You can have multiple
application
tags. One for each
application. Currently supported applications: javac,
java, g++, gcc, perl,
lua.
Whilst you can have <application>
in a
remote resource XML file, it’s more appropriate to put it in the
local resource file as the paths are likely to be different for
different installations of PASS.
Note that pdflatex or lualatex is also required to build the PDF file. (The attachfile package doesn’t work with xelatex.)
Testing
The PASS application can be tested using the dummy course.
If there’s only one resource
tag in the
local or remote resource XML file, that course will automatically
be selected on startup. If there are multiple courses, the
application will present a list from which you can select the
required course. The dummy course comes with a number of different
assignments allowing you to test each supported programming
language. The PASS GUI application will automatically select the
assignment closest to its due date. You can use the drop-down menu
to select a different assignment. The dummy assignments are listed
below. These only require the creation of a single file containing
the assignment code. In practice, assignments are likely to require
multiple files, but the same instructions apply. It’s also possible
for students to add additional source files if they have created more than the
required set.
Hello World C
This assignment requires a C program that prints “Hello World!” to STDOUT. The code must be supplied in a single file called helloworld.c. To test PASS with this dummy assignment, create a file called helloworld.c that contains the following:
#include <stdio.h> int main() { printf("Hello World!"); return 0; }Start up PASS GUI and select "Hello World C" from the assignment list. Click on "Next" to move to the next panel. Select the directory containing the helloworld.c file and click "Next". Hopefully, the full path to helloworld.c should be listed. If the file is simply listed as helloworld.c without the full path, then the file wasn’t found. You can use the file selector button to find it or go back to the previous panel and check that you selected the correct directory. (If the student wasn’t able to complete the assignment, they can continue with the submission process even if some of the required files are missing.)
Once the file has been found, click on "Next" and PASS will process the assignment. If successful, it will open a save dialogue window allowing you to save the PDF. (If you click "Cancel", a "Save As..." button will appear at the bottom of the PASS window.) After the PDF file has been saved an "Open PDF" button will appear at the bottom of the PASS window, which should launch your default PDF viewer and open the PDF file in it.
Hello World C++
This assignment is much the same as the previous except that it requires C++ instead of C. The assignment must be supplied in the file helloworld.cpp. If you want to test it, the file contents are:
#include <iostream> using namespace std; int main() { cout << "Hello World!\n"; return 0; }Follow the same instructions as above.
Hello World Java
This assignment is much the same as the previous two except that it requires Java. The assignment must be supplied in the file HelloWorld.java. If you want to test it, the file contents are:
package helloworld; public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } }Follow the same instructions as above.
Test Read File Java
This dummy assignment requires a Java application that reads the file dummy.txt and writes the contents to STDOUT with the line number prefixed. The file dummy.txt is available at http://www.dickimaw-books.com/software/pass/dummy.txt. The assignment resource file indicates this with the following element:
<resourcefile src="http://www.dickimaw-books.com/software/pass/dummy.txt" />PASS will fetch it from that location when it tries to compile and run the code. To test this example, create a file called TestReadFile.java that contains the following:
package testreadfile; import java.io.*; public class TestReadFile { public static void main(String[] args) { try { File file = new File("dummy.txt"); BufferedReader in = new BufferedReader(new FileReader(file)); String line; int lineNum=0; while ((line = in.readLine()) != null) { lineNum++; System.out.println(String.format("%d. %s", lineNum, line)); } in.close(); } catch (Exception e) { e.printStackTrace(); } } }
Make a PNG Image Java
This is a dummy Java assignment that must create an image file called image.png and a text file called output.txt. This is indicated with:<resultfile type="image/png" name="image.png" /> <resultfile type="text/plain" name="output.txt"/>The code must be supplied in the file MakeImage.java. The file contents are shown below:
package makeimage; import java.io.*; import java.awt.image.*; import java.awt.*; import javax.imageio.ImageIO; public class MakeImage { private static void test() throws IOException { BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = image.createGraphics(); if (g2 != null) { g2.setComposite(AlphaComposite.Src); g2.setColor(Color.YELLOW); g2.fillRect(0, 0, 100, 100); g2.setColor(Color.BLUE); g2.drawRect(10, 10, 80, 60); g2.dispose(); } ImageIO.write(image, "png", new File("image.png")); File file = new File("output.txt"); PrintWriter writer = new PrintWriter(file); writer.println("Test output."); writer.close(); } public static void main(String[] args) { try { test(); } catch (IOException e) { e.printStackTrace(); } } }
Hello Input Perl
This dummy assignment requires the creation of a Perl script called hello.pl that requires the user to input a name and a colour. The assignment resource file provides dummy input that’s used when testing the script:
<input>Sample Name</input> <input>Sample Colour</input>The required Perl code is listed below:
#!/usr/bin/perl print "What's your name? "; my $name = <STDIN>; chomp $name; print "Hello ", $name, "!\n"; print "What's your favourite colour? "; my $colour = <STDIN>; chomp $colour; print "Your favourite colour is '$colour'.\n"; 1;
Hello Arg Lua
This dummy assignment requires Lua code in a file called hello.lua that takes a command line argument. The assignment resource file supplies a dummy argument that’s used when testing the script:
<arg>Sample Name</arg>The Lua code is:
#!/usr/bin/lua if #arg < 1 then error("Syntax error: argument missing") end print("Hello ".. arg[1] .."!\n")
Free-Form Example
This example requires at least PASS v1.06 as it doesn’t have a
mainfile
element. It represents an assignment
that only requires the student to include a report file
called reportdoc1.pdf or reportdoc1.doc or
reportdoc1.docx.
They may submit other files as well, but there are no
required source code files. The assignment is identified as follows:
<assignment name="freeform" compile="false" > <title>Free-Form</title> <due>2017-04-30 15:00</due> <report>reportdoc1</report> </assignment>
In this case, PASS won’t attempt to compile or run any code because there is no main
file. Without the compile="false"
attribute this will cause a warning
in case the main file was omitted by accident.
Test Build Hello Lua
This dummy assignment requires Lua code in a file called
hello.lua but unlike the earlier "Hello Lua"
example, this one comes with a custom build script, which is
identified with the build
attribute:
build="http://www.dickimaw-books.com/software/pass/dummy-build.sh"This automatically switches off the
compile
and
run
attributes and instead fetches the build script
and uses that to perform the appropriate steps required to build
and test the application. In this case, there’s no compilation
required as Lua is a scripting language. The build script simply
prints text to STDOUT and runs the script:
#!/usr/bin/env sh echo "Test Build Script" texlua hello.lua TestThe hello.lua script from the earlier "Hello Lua" example can be used for this example as well.
Test Build Hello Lua (With Output File)
This is like the above but the custom shell script runs hello.lua with STDOUT redirected to the file output.txt. This file needs to be included in the PDF generated by PASS, so it’s necessary to list it as a result file:
<assignment name="testbuild2" build="http://www.dickimaw-books.com/software/pass/dummy-build2.sh" > <title>Test Build Hello Lua (With Output File)</title> <due>2021-01-02 15:00</due> <mainfile>hello.lua</mainfile> <resultfile type="text/plain" name="output.txt"/> </assignment>
Note that this example requires at least PASS GUI v1.23 or PASS CLI v1.04.
Hello World Template (Java)
This example is essentially the same as the earlier
Hello World Java assignment but it’s designed
for PASS Editor with a template file that contains bugs and a stub method
that the students have to correct. The template is identified with the
template
attribute:
<mainfile template="http://www.dickimaw-books.com/software/pass/dummy-HelloWorld.java">HelloWorld.java</mainfile>When PASS Editor is used with this assignment, it will create a file called HelloWorld.java and add the contents of the referenced template to it. When used with the other PASS applications, the template will be ignored.
Assignment XML Files
Each course has a separate XML file that’s identified in the
local lib/resource.xml file or in the
remote resources XML file (identified in lib/resource.xml with the
<courses>
element). For example:
<?xml version="1.0"?> <resources> <resource name="CMP-1234X" href="http://www.example.com/pass/CMP-1234X.xml"> Introductory Programming </resource> <resource name="CMP-1234Y" href="http://www.example.com/pass/CMP-1234Y.xml"> Advanced Programming </resource> </resources>
The assignment XML file for the given course is identified by the
href
attribute. The referenced assignment XML file should have the structure:
<assignments> <assignment name="label"> assignment settings </assignment> ... <assignment name="label"> assignment settings </assignment> options for all assignments </assignments>Within the
assignments
block but outside of any assignment
tags (options for all
assignments), you can optionally have the following elements:
- listings
- The
listings
element can be used to adjust the listings style. For example, to make the identifiers blue:<listings>identifierstyle=\color{blue}</listings>
(See the listings documentation for further details.) This will be applied to all the assignments for the given course. This tag is cumulative. For example:<listings>identifierstyle=\color{blue}</listings> <listings>stringstyle=\color{lightgray}</listings>
is equivalent to:<listings>identifierstyle=\color{blue},stringstyle=\color{lightgray}</listings>
- geometry
- Similarly as from v1.05 there’s now a
geometry
tag, which can be used to adjust the page geometry. For example:<geometry>margin=10mm,includeheadfoot</geometry>
See the geometry documentation for further details. - fontspec
- If LuaLaTeX is used (UTF-8) then the fontspec package will be loaded. You can provide
commands that should be loaded after this package with the
fontspec
tag. For example:<fontspec> \setromanfont{FreeSerif} \setsansfont{FreeSans} \setmonofont{FreeMono} </fontspec>
Theoptions
attribute may be set to specify any options that should be passed to fontspec. This tag is cumulative. If omitted the default is:<fontspec> \usepackage{lmodern} </fontspec>
If LuaLaTeX isn’t used this tag has no effect. - fontenc
- If PDFLaTeX is used (ASCII or Latin-1) then the fontenc package will be loaded. You can provide
commands that should be loaded after this package with the
fontenc
tag. For example:<fontenc> \usepackage{noto} </fontenc>
Theoptions
attribute may be set to specify any options that should be passed to fontenc. This tag is cumulative. If omitted the default is:<fontenc options="T1" > \usepackage{lmodern} </fontenc>
- maxoutput
- To guard against excessive chatter to STDOUT, PASS will truncate
any output that exceeds maxoutput. The default value for
this setting is 10240 but you may change it in the XML file with:
<maxoutput>value</maxoutput>
- verbatim
-
Known languages are typeset using
\lstinputlisting
but other verbatim content (plain text files, messages to STDOUT/STDERR) is written to a temporary file (rather than using theverbatim
environment) and input with\verbatiminput
. The content is preprocessed by PASS to break up long lines and replace TAB characters with spaces (since this is something that’s easier to do in Java than in TeX). The default is to break up lines that exceed 80 characters and use 8 spaces for TAB characters. You can change these values with theverbatim
tag, which has the attributesmaxchars
andtabcount
to set the maximum characters per line and TAB character count, respectively. For example:<verbatim maxchars="85" tabcount="4" />
assignment
element may have the following
attributes:
- name
-
The
name
attribute should be a short label identifying the assignment. For example:<assignment name="helloworld">
The only permitted characters within thename
attribute are:a
-z
,A
-Z
,0
-9
,.
(dot),+
(plus) and-
(hyphen). Note that the name may be used to form filenames. - run
-
PASS will automatically try to test the application (after the code
has been compiled if required). If you want to skip this test, set
the
run
attribute tofalse
. For example:<assignment name="helloworld" run="false" >
- compile
-
You can also skip the compile step if required with the
compile
attribute set tofalse
. Note that this will automatically implementrun="false"
as well. The compile step is automatically skipped for non-compiled languages (such as Lua) but sincecompile="false"
setsrun="false"
, this setting will prevent non-compiled languages from being run, so only use it for compiled languages. - build
- If you require a custom build, you can now (v1.19+) use the
build
attribute. The value should be the URL where the build script can be fetched from. This option automatically switches off thecompile
andrun
attributes. Any required compiling or execution should be performed by the build script. - language
- The programming language that the code is written in (see below).
- variant
- The variant of the programming language (see below).
The contents of the assignment
tag must include
<title>Assignment Title</title> <due>Due Date</due> <mainfile>filename</mainfile>(As from PASS v1.06, the mainfile element is now optional. If omitted, PASS won’t attempt to compile or run any code.) The due date must be given in the format
YYYY-MM-DD
HH:mm
. For example, a minimal assignment
where the students are
only required to submit the file helloworld.c:
<assignment name="helloworld"> <title>Hello World</title> <due>2016-10-02 16:30</due> <mainfile>helloworld.c</mainfile> </assignment>Additional required files are marked up with the optional
file
tag. For example, if the students are required to submit
Foo.java, Bar.jar and FooMain.java, where
the main
method is in FooMain.java:
<assignment name="foobar"> <title>Foo Bar</title> <due>2016-10-02 16:30</due> <file>Foo.java</file> <file>Bar.java</file> <mainfile>FooMain.java</mainfile> </assignment>
The order of the file
and mainfile
tags determines the listing order in the PDF.
Both the file
and mainfile
tags allow the following attribute:
- template
- The value should be a URL to a file containing template code used by PASS Editor when initialising a project. Other PASS applications ignore the value (but the value is still parsed and so must be a well-formed URL).
There are two optional attributes to the assignment
tag
related to the code listings:
language
and variant
. PASS tries to determine the
appropriate language setting for the listings package when
creating the PDF file by testing for known file extensions.
For example, if the extension is .c
then "C" is assumed.
If it’s unable to determine the language from the extension,
then \verbatiminput
is used instead. The
language
tag
provides a fallback to use as a default if this happens.
The value must be recognised by the listings package.
If you have files that don’t have file extensions (for example, bash
scripts) you’ll need to set the language
attribute.
The listings package also recognises some variants for various languages. This can be supplied in the variant attribute. The value must be recognised by listings.sty. For example:
<assignment name="helloarg" language="Lua" variant="5.0">
If the project code should be compiled, additional compiler
arguments can be specified using the compiler-arg
tag. There should be one tag per command line argument. For example:
<compiler-arg>-encoding</compiler-arg> <compiler-arg>UTF-8</compiler-arg>
There is an analogous tag invoker-arg
for arguments that
should be passed to the invoker. For example, to set the default
line ending for the JVM to "\r\n"
:
<invoker-arg>-Dline.separator=
</invoker-arg>
(Note the use of entities to specify the carriage return and line
feed characters as you can’t use \r\n
in this context.)
If the project needs to read any files provided by the assignment,
each file should be identified using the resourcefile
tag with
the
location of the original file given in the src
attribute. For
example, if the project needs to load the files foo.txt and
bar.txt that the students were able to download from
http://www.example.com/projects/foo.txt and
http://www.example.com/projects/bar.txt:
<resourcefile src="http://www.example.com/projects/foo.txt" /> <resourcefile src="http://www.example.com/projects/bar.txt" />
If the project should be accompanied by PDF or Word reports,
then these can be specified using the <report>
tag.
If the extension is omitted, PASS will try to search for the
files according to the extensions ".pdf", ".doc" and ".docx".
For example:
<report>projectreport1</report> <report>projectreport2</report>
If the project must generate a file or files, each file name
should be listed in the resultfile
tag with the
name
attribute set to the file name and the
type
attribute
set to the mime type for that file. For example, if the project
must create an image file called image.png and a text file
called output.txt, then:
<resultfile type="image/png" name="image.png" /> <resultfile type="text/plain" name="output.txt" />
Each file will be attached to the PDF.
In addition, if the mime type starts with text
the
contents will be listed and if the mime type starts with
image
the file will be included with
\includegraphics
. If you want to skip the file
inclusion and only have it attached, set the listing
attribute to "false"
. For example:
<resultfile type="text/plain" name="output.txt" listing="false"/>
If the project application requires command line arguments,
use the arg
tag for each argument. For example:
<arg>Sample Name</arg>
If the project application requires reading information from
STDIN, use the input
tag to provide each line of test data.
For example:
<input>Sample Name</input> <input>Sample Address</input>