The DCS grading programs — file format

Contents

Essentials

A file accepted by the grading programs is called a "grades file". A grades file has two parts:

Between the header and the body is an empty line, which may contain blanks and tabs but nothing else.

We'll show an example of a simple grades file, and then discuss the rules in the light of the example. Then, after a more complex example, we'll discuss the rules it exemplifies.

A simple example, and why it's like that

* A simple grades file
* Lines starting with '*' are comments.
a1 / 10 * the first assignment
a2 / 10
* A comment on a line by itself is acceptable.
a3 / 10
a4 / 10
p / 20
t / 50
e / 100
asts = a1 : 5 a2 : 5 a3 : 10 a4 : 10 p : 15
term = asts : 45 t : 15
finl = term : 60 e : 40

0123456789    Alice	10	10	10	10	20 L	50	100
0123456790 d  Brian	5	5	5	5	10	25	50
0123456791  x Carla	0	10	0	10	10	20	65

There are tab characters in the last three lines. Here they are with each tab shown as "---":

0123456789    Alice---10---10---10---10---20 L---50---100
0123456790 d  Brian---5---5---5---5---10---25---50
0123456791  x Carla---0---10---0---10---10---20---65

The header

The grading scheme contained in the file header consists of a list of mark names, together with instructions on how to get a value for each one. Mark names can consist of letters, digits, and the underscore character. The first character must be a letter or underscore. The name can be as long as you like, but if it's longer than five characters, it may be truncated by some of the display programs.

Comments are allowed in the header. They begin with the character '*' and extend to the end of the line. A comment line does not terminate the header like an empty line, even if it contains no mark definition.

A mark can be a "raw" mark or a "calculated" mark. For a raw mark, the person marking the work determines a number to be assigned to each student, and all the marking scheme needs to do is to specify the name and the "maximum" mark for the item. ("Maximum" is in quotation marks because if there are bonus marks or a generous marker, the maximum may be exceeded. A better name would be something like the "out-of mark".)

For a calculated mark, we need to specify the formula used for the calculation. This will consist of a list of other marks, with the weight assigned to each of those items in the calculation.

In our example, the grades-file header consists of every line down to the one beginning "finl = …". The raw marks are called a1, a2, a3, a4, p, t, and e, and you can tell that they are raw marks because all that is given is the symbol '/' and then the maximum mark given by the person marking.

The calculated marks are called asts, term, and finl. For these marks, you see the symbol '=' and then the formula used to do the calculation. Each formula consists of a series of terms, and each term consists of the name of another mark and the weight of that other mark in the formula. For example, the mark "finl" is determined by giving the mark "term" a weight of 60 and "e" a weight of 40. That is, the value for "term" is taken as a fraction of the maximum possible and multiplied by 60, and then the same is done with "e", multiplying by 40. The maximum mark for "finl" is then 100.

The body

Each line in the body gives what we know about one student. A student record consists of these fields:

A couple of points need clarification.

First, the marks in a student record are associated with a mark definition in the grades-file header by their sequence number in the record, so if a mark is omitted you must still include the tab character preceding it, unless there are no more marks in this student record.

Secondly, the "tab character" preceding each mark is really a separator character. Probably you will want it to be a tab, but you're allowed to specify something else: if the first three characters of the marks file are */K, where K is any character, then the grading programs use K as the separator character for that marks file. Obviously, this is a facility to be used with some caution.

Thirdly, a word about the flag character. It can be used to select or de-select student records in many of the grades programs, but the particular values have no meaning except as you decide to use them. By contrast, the idea of dropping a course is so important that it has its own field, even though you could manage the same idea with the flag character.

Finally, notice that you can add short comments at the end of a mark value, as long as the first part of the string in the mark field is a representation of a legal value for the mark. For instance, Alice's mark p has a trailing 'L' as a comment.

In our simple example, Brian has dropped the course, while Carla is flagged 'x', for what reason we cannot say. (Well, we can guess: I often use 'x' for students who are still on the official class list but give every other sign of having dropped, such as not writing assignments after the drop deadline.)

The simple example, after calculating the grades

Here is what the simple example looks like after we calculate the marks with the grades program gen:

* A simple grades file
* Lines starting with '*' are comments.
a1 / 10 * the first assignment
a2 / 10
* A comment on a line by itself is acceptable.
a3 / 10
a4 / 10
p / 20
t / 50
e / 100
asts = a1 : 5 a2 : 5 a3 : 10 a4 : 10 p : 15
term = asts : 45 t : 15
finl = term : 60 e : 40

0123456789    Alice	10	10	10	10	20 L	50	100	45	60	100
0123456790 d  Brian	5	5	5	5	10	25	50	22	30	50
0123456791  x Carla	0	10	0	10	10	20	65	22	28	54

A more complex example

Unless you need to construct complex grades files yourself, you can stop reading here. For example, course instructors probably need to keep reading, while TAs can probably quit now.

a1 / 10
a2 / 10
a3 / 10
a4 / 10
p / 20
t / 50
e / 100
tutor " ! ,9
asts = $desc (a1 a2 a3 : 10 5 5) a4 : 10 p : 15 ! 1
term = asts : 45 t : 15 $pick (tutor ? "Larry" ($add (1.1)) "Curly" ($mul(0.9)) "Einstein" ()) ! 1
finl = term : 60 e : 40 ! 1

0123456789    Alice	10	10	10	10	20	50	100	Larry
0123456790    Brian	7	5	5	5	10	25	50	Einstein
0123456790* Was sick for all of November. Medical note seen.
0123456791    Carla	7	5	5	5	10	25	50	Curly
0123456792    David	7	5	5	5	10	25	50	Larry
0123456793    Ellen	0	10	0	10	10	20	65	Curly
0123456794    Filip	0	10		10	10	20	65	Curly
0123456794* a3 = a1:5 a2:5

Beyond the basics

Sometimes, the kind of simple calculation described in the previous section is sufficient. More often, you'll discover that you marked something too hard or too generously, or that some of your TAs marked differently from others. You need to make adjustments, and adjustments mean a departure from the basic "sum of weighted marks" scheme.

(It's not against the University's rules to make adjustments. But some adjustments are indeed contrary to the rules, and you should check if you're not sure you're doing something legal. The grading programs try not to cater to illicit schemes, but they don't guarantee you can't do something illegal.)

The header

Departures from the basics in mark definitions are represented by the grading programs in the form of functions. For a function "f", a function call looks like this:

$f ( argument-string )

The argument string takes different forms for different functions. For example, the function $mul, which multiplies by a constant, requires that the argument string represent a number. Here's how you would increase everyone's final grade by 10%:

finl = term : 60 e : 40 $mul(1.1)

You could also achieve this by increasing the weight of each part of the formula, giving "term" a weight of 66 and "e" a weight of 44; but then the total weight of "finl" would be 110, whereas $mul doesn't change the weight, so in the formula above the maximum mark for "finl" is still 100, even though some students may actually have their marks increased above 100.

In a moment, we'll tell you about all the functions you can use, but first you need to know about data types. It turns out that it's helpful to allow general strings rather than just numbers, so there are two data types for marks: numbers and strings. For example, if you want to include the tutor's name in every student record, you could do it with a "mark" defined like this:

tutor "

Instead of the '/' that denotes a raw numerical mark, the double-quotation-mark character indicates a raw string mark. It's a raw mark in the sense that it would be entered by some human; but there are ways of generating it automatically too. (See $setstring, below.)

Calculated marks can have either data type, string or number. All calculated marks have the character '=' after the mark name, followed by a formula. The data type is determined from the formula, and it is illegal to have a formula of undetermined or mixed data type.

Thus for each function we have to specify the resulting data type and the effect on the weight (if it's a numerical formula) — as well as the obvious requirements to know the form of the arguments and the value calculated.

Order of evaluation

Mark formulas are evaluated left-to-right. Function arguments are enclosed in parentheses, but no other parentheses are allowed, so you can't use parentheses to alter the order of evaluation. Thus, the formula

a = a1 : 10 $mul(1.1) a2 : 10

gives the value of "a1" a weight of 10 and then multiplies by 1.1. The value of "a2" is not multiplied by 1.1.

Output format

At the end of a mark definition, you can provide an output format like this:

… ! f,w

Here f is the precision and w is the width. Calculated numeric marks are the only ones that can have a precision, but any mark can have a width.

The precision is used when a program such as gen calculates the marks in a grades file. The calculation produces both a number that is the value of the mark, and a string representing the number. If the precision f is an integer, then that many decimal places are provided in the string, and the number is rounded to match the string. If f is the character 'A', then the value of the mark is converted to a letter grade. If f is omitted, it is by default 0: marks are rounded to the nearest integer.

Rounding to match the precision is not the same as the rounding done by the $round function.

If you write a comment line for a student giving an individual formula for a mark, and you want to use the same precision as in the header definition for the same mark, then you can simply omit it from the individual formula.

The width w is used when displaying marks, for example by gpr. It gives the number of columns used for the mark, and it overrides the default width provided by the program or its options.

You can leave out either f or w; if you leave out w, you can also leave out the comma.

The functions

mul
The $mul function multiplies the current value of the formula by its argument, which must be a number. The data type is numeric. There is no effect on the weight.
add
The $add function adds the value of its argument to the current value of the formula. The argument is either a number or the name of another mark. If it is another mark, then the actual value of that mark is added, without scaling or weighting. The data type is numeric. There is no effect on the weight.
set
The $set function sets the current value of the formula to be the value of its argument. The argument is either a number or the name of another mark. If it is another mark, then the actual value of that mark is used, without scaling or weighting. The data type is numeric. The weight of the formula is changed to 0, because all previous terms of the formula are effectively discarded.
desc
The $desc function lets you do "best 4 of 5" or "highest weight for the best". It takes an argument consisting of a sequence of mark names, followed by the character ':', followed by a sequence of numeric weights. There must be the same number of weights as of mark names. The values of each of the named marks are scaled by their maximum marks, and then sorted in descending order. Each scaled mark is then multiplied by the corresponding numeric weight, and the result is added to the current value of the formula. The data type is numeric. The weight of the formula is increased by the total of all the weights in the argument. Here is an example call of $desc:
                    a1 / 10
                    a2 / 10
                    a = $desc (a1 a2 : 14 7)
                

If the values of "a1" and "a2" are 6 and 8 respectively, then the value of a is (8/10)*14 + (6/10)*7 = 15.4, with a weight of 21.

You are not obliged to put the weights in descending order, but your students may not be pleased if you don't.

pick
The $pick function allows you to choose a formula on the basis of the value of another mark. The other mark must be a string. Thus, if the mark "tutor" contains the tutor's name, then
a = a1:10 a2:10 $pick(tutor ? <series of labelled formulas>)

selects one of the "series of labelled formulas", using the value of "tutor" as the selection criterion. Each labelled formula is of the form:

"<string>" ( <formula> )

Here is an example of a complete $pick call:

a = a1:10 a2:10 $pick(tutor ? "Larry" ($add(1.1)) "Curly" ($mul(1.05)))

If the value in "tutor" is Larry, then 1.1 is added to the current formula value; if the value in "tutor" is Curly, then the current formula value is multiplied by 1.05.

You can also use $pick to choose a string value:

m2 = $pick(m1 ? "hi" ($setstring("some")) "mom" ($setstring("half")) "" ($setstring("none")))

That example also shows the use of the labelling string "" (the null string). This matches any selecting value, like the default label in a switch or case statement in many programming languages. If present, it must be the last label in the series.

There must be quotation marks around the strings used to label selections. If the labels need to contain quotation marks or parentheses, you can escape those characters with the backslash '\'. (Then you should spend time reconsidering why your grades file has become so complicated.)

The labelled formulas in a $pick call must have zero weight, so they can only contain function calls, to any functions except $desc. (That's not quite true. You can include plain weighted terms or $desc calls, as long as the total weight is zero. Zero-weight formulas look odd and may have even odder effects, so should be avoided.) A $pick call itself has zero weight and has no effect on the weight of the formula as a whole, even if the call contains a $set call.

If there is no default label ("") in a $pick call, one is automatically supplied, and its formula is $fail(). Thus, if you have a student enrolled, for example, in a tutorial run by a TA whose name you forgot to include in the formula, then the automatically supplied default label will match this student, and the automatically supplied $fail will be called, and you'll be confused and sorry.

fail
The $fail function causes the formula evaluation to fail, producing an error message if it is called from a sensibly-implemented grading program. It takes no arguments. It has no data type. It has no effect on the weight of the formula.

Obviously, the only use for the $fail function is as one of the labelled formulas in a $pick call — a formula, presumably, that should not be evaluated for any actual student.

setstring
The $setstring function sets the current value of the formula to be the value of its argument. The argument is a string. The data type is string, and therefore the formula has no weight.

It is expected that a typical use of $setstring would be to insert some standard value in all students' records in a file that is later to be combined with other files, as from other tutorials. After combining the files, you would change the definition for this mark from

tutor = $setstring(…)

to

tutor "

That's not to deny, of course, that you might think of some other use for this function.

round
The $round function rounds the current value of the formula to the nearest multiple of its argument. For example, to round to the nearest integer, use
rnd = … $round(1)

Rounding is not so simple as you might imagine. Some instructors and students expect that all calculated marks should be rounded before being used in further calculations; however, most of us don't agree, and the grading programs use unrounded values, with all the precision they can get, until it's time to save the results. At that point all values are rounded to whatever precision is specified by the output format.

This has nothing to do with the $round function.

Instead, $round allows you to round the value of the mark currently being calculated before the next step of the calculation — or, and this is in fact why it was introduced, to allow you to calculate letter grades properly, if you insist on using calculated letter grades.

Let me rephrase all that. The use of $round by itself does not determine the rounding of the mark inserted into a grades file by gen; it determines the number that is used in further calculations, but this number may be rounded further before being put back into the file, because gen formats its output mark according to the specifications in the mark format.

For example, suppose we have these mark specifications:

                    m1 / 8
                    m2 = m1 : 100 $round(0.1)
                

If m1 is 6.999, then m2 will be calculated as 87.5. However, m2 will appear as 88 in the file after processing by gen, because there is an implicit "! 0" at the end of the definition.

The argument for $round is not the same as the argument for the output format specification.

The body

Comments

You may put comments after the marks in the line representing a student's record, but long comments are awkward to insert and don't sit well with the grading programs intended to make printable representations of grades files. Instead, you can put comments on a separate line, as in the case of the student Brian.

Comments must follow the line containing the student's main record, and must begin with the student number, followed by the comment character, '*'.

Individual formulas

Some students are exceptions: they miss a piece of work with a good excuse, for example, or there is some other reason to evaluate their marks differently from everybody else's. For these students, you may want to specify an individual formula.

An individual formula is given as a comment with the student's marks, not in the header with the general marking scheme. The contents of the comment must be the mark-definition formula that you want to use, as in the case of the student Filip in our example.

Either a raw or a calculated mark can have an individual formula, and you can have individual formulas for more than one of a student's marks. The type of the individual formula must match the type of that mark in the regular marking scheme. If the mark is numeric and the total weight of the individual formula is different from the total weight in the regular marking scheme, a warning message is given (unless the individual formula, or the regular mark, or both, have zero weight).

The complex example, after calculating the grades

Here is what the complex example looks like after we calculate the marks with the grades program gen:

a1 / 10
a2 / 10
a3 / 10
a4 / 10
p / 20
t / 50
e / 100
tutor " ! ,9
asts = $desc (a1 a2 a3 : 10 5 5) a4 : 10 p : 15 ! 1
term = asts : 45 t : 15 $pick (tutor ? "Larry" ($add (1.1)) "Curly" ($mul(0.9)) "Einstein" ()) ! 1
finl = term : 60 e : 40 ! 1

0123456789    Alice	10	10	10	10	20	50	100	Larry	45.0	61.1	101.1
0123456790    Brian	7	5	5	5	10	25	50	Einstein	24.5	32.0	52.0
0123456790* Was sick for all of November. Medical note seen.
0123456791    Carla	7	5	5	5	10	25	50	Curly	24.5	28.8	48.8
0123456792    David	7	5	5	5	10	25	50	Larry	24.5	33.1	53.1
0123456793    Ellen	0	10	0	10	10	20	65	Curly	27.5	30.2	56.2
0123456794    Filip	0	10	5	10	10	20	65	Curly	30.0	32.4	58.4
0123456794* a3 = a1:5 a2:5

What happens when there's an error?

If there's an error in a grades file, you should see an error message when the file is read. Depending on the program and the error, input may continue or be terminated; usually, the more critical the program, the more likely it is to be terminated. For example, gpr is somewhat more forgiving of errors than gen.

Sometimes, however, the treatment of errors may surprise you. Here are some special cases.


Back to the top of this page