Configuring a contest

In the following text “user” and “contestant” are used interchangeably.

Configuration parameters will be referred to using their internal name, but it should always be easy to infer what fields control them in the AWS interface by using their label.


Contest administrators can limit the ability of users to submit submissions and user_tests, by setting the following parameters:

  • max_submission_number / max_user_test_number

    These set, respectively, the maximum number of submissions/user_tests that will be accepted for a certain user. Any attempt to send in additional submissions/user_tests after that limit has been reached will fail.

  • min_submission_interval / min_user_test_interval

    These set, respectively, the minimum amount of time the user is required to wait after a submission/user_test has been submitted before he’s allowed to send in new ones. Any attempt to submit a submission/user_test before this timeout has expired will fail.

The limits can be set both on individual tasks and on the whole contest. For a submission to be accepted it has to verify the conditions on both the task and the contest. This means that a submission/user_test will be accepted only if the number of submissions/user_tests received so far for that task is strictly less that the task’s “max_number” and the number of submissions/user_tests received so far for the whole contest (i.e. in all tasks) is strictly less than the contest’s “max_number”. The same holds for “min_interval” too: a submission/user_test will be accepted only if the time passed since the last submission/user_test for that task is greater than the task’s “min_interval” and the time passed since the last submission/user_test received for the whole contest (i.e. in any of the tasks) is greater than the contest’s “min_interval”.

Each of these fields can be left unset to prevent the corresponding limitation from being enforced.


Tokens are a concept introduced to provide contestants with limited access to the detailed results of their submissions on the private testcases.

For every submission sent in for evaluation, a contestant is always able to see if it succesfully compiled. He/she is also able to see its scores on the public testcases of the task, if any. All information about the other so-called private testcases is kept hidden. Yet, a contestant can choose to use one of its tokens to “unlock” a certain submission of his/her choice. After he/she does this, detailed results are available for all testcases, as if they were all public. A token, once used, is consumed and lost forever. Contestants have a set of available tokens at their disposal, where the ones they use are picked from. These sets are managed by CMS according to rules defined by the contest administrators, as explained later in this section. Note that the public/private results are arbitrarily provided by the score types and are usually based on public/private testcases, but they could actually use other criteria.

Tokens also affect the score computation. That is, all “tokened” submissions will be considered, together with the last submitted one, when computing the score for a task. See also Score rounding.

There are two types of tokens: contest-tokens and task-tokens. When a contestant uses a token to unlock a submission he/she is in reality using two tokens, one of each type, and therefore needs to have both available. As the names suggest, contest-tokens are bound to the contest while task-tokens are bound to a specific task. That means that there is just one set of contest-tokens but there can be many sets of task-tokens (precisely one for every task). These sets are controlled independently by rules defined either on the contest or on the task.

A token set can be disabled (i.e. there will never be tokens available for use), infinite (i.e. there will always be tokens tokens available for use) or finite.

Rules consist of six parameters: token_initial, token_gen_number, token_gen_time, token_max, token_total and token_min_interval. For a set to be disabled, the token_initial field has to be unset. For a set to be infinite, token_initial needs to be a non-negative integer, token_gen_number needs to be a positive integer and token_gen_time needs to be zero.

Otherwise the token set is finite. This means that the token set can be effectively represented by a non-negative integer counter: its cardinality. When the contest starts (or when the user starts its per-user time-frame, see USACO-like contests) the set will be filled with token_initial tokens (i.e. the counter is set to token_initial). If the set is not empty (i.e. the counter is not zero) the user can use a token. After that, the token is discarded (i.e. the counter is decremented by one). New tokens can be generated during the contest: token_gen_number new tokens will be given to the user after every token_gen_time minutes from the start (note that token_gen_number can be zero, thus disabling token generation). If token_max is set to a positive integer, the set cannot contain more than token_max tokens, therefore generation of new tokens will stop at that value (unset token_max to disable this limit).

The use of tokens can be limited with token_min_interval and token_total: users have to wait at least token_min_interval seconds after they used a token before they can use another one (this parameter can be zero), and they cannot use more that token_total tokens in total (this parameter can be unset). Note that token_total has no effect if the token set is infinite.

Having a finite set of both contest- and task-tokens can be very confusing, for the contestants as well as for the contest administrators. Therefore it’s common to limit just one type of tokens, setting the other type to be infinite, in order to make the general token availability depend only on the availability of that type (e.g. if you just want to enforce a contest-wide limit on tokens set the contest-token set to be finite and set all task-token sets to be infinite). CWS is aware of this “implementation details” and when one type is infinite it just shows information about the other type, calling it simply “token” (i.e. removing the “contest-” or “task-” prefix).

Note that “token sets” are “intangible”: they’re just a counter shown to the user, computed dynamically every time. Yet, once a token is used, a Token object will be created, stored in the database and associated with the submission it was used on.

Changing token rules during a contest may lead to inconsistencies. Do so at your own risk!

Score rounding

Based on the ScoreTypes in use and on how they are configured, some submissions may be given a floating-point score. Contest administrators will probably want to show only a small number of these decimal places in the scoreboard. This can be achieved with the score_precision fields on the contest and tasks.

The score of a user on a certain task is the maximum among the scores of the “tokened” submissions for that task, and the last one. This score is rounded to a number of decimal places equal to the score_precision field of the task. The score of a user on the whole contest is the sum of the rounded scores on each task. This score itself is then rounded to a number of decimal places equal to the score_precision field of the contest.

Note that some “internal” scores used by ScoreTypes (for example the subtask score) are not rounded using this procedure. At the moment the subtask scores are always rounded at two decimal places and there’s no way to configure that (note that the score of the submission is the sum of the unrounded scores of the subtasks). That will be changed soon. See issue #33.

The unrounded score is stored in the database (and it’s rounded only at presentation level) so you can change the score_precision at any time without having to rescore any submissions. Yet, you have to make sure that these values are also updated on the RankingWebServers. To do that you can either restart ScoringService or update the data manually (see RankingWebServer for further information).

Primary statements

When there are many statements for a certain task (which are often different translations of the same statement) contest administrators may want to highlight some of them to the users. These may include, for example, the “official” version of the statement (the one that is considered the reference version in case of questions or appeals) or the translations for the languages understood by that particular user. To do that the primary_statements field of the tasks and the users has to be used.

The primary_statements field for the tasks is a JSON-encoded list of strings: it specifies the language codes of the statements that will be highlighted to all users. A valid example is ["en_US", "it"]. The primary_statements field for the users is a JSON-encoded object of lists of strings. Each item in this object specifies a task by its name and provides a list of language codes of the statements to highlight. For example {"task1": ["de"], "task2": ["de_CH"]}.

Note that users will always be able to access all statements, regardless of the ones that are highlighted. Note also that language codes in the form xx or xx_YY (where xx is an ISO 639-1 code and YY is an ISO 3166-1 code) will be recognized and presented accordingly. For example en_AU will be shown as “English (Australia)”.


CMS stores all times as UTC timestamps and converts them to an appropriate timezone when displaying them. This timezone can be specified on a per-user and per-contest basis with the timezone field. It needs to contain a string in the format Europe/Rome (actually, any string recognized by pytz will work).

When CWS needs to show a timestamp to the user it first tries to show it according to the user’s timezone. If the string defining the timezone is unrecognized (for example it is the empty string), CWS will fallback to the contest’s timezone. If it is again unable to interpret that string it will use the local time of the server.

User login

Users log into CWS using a username and a password. These have to be specified, respectively, in the username and password fields (in cleartext!). These credentials need to be inserted (i.e. there’s no way to have an automatic login, a “guest” session, etc.) and, if they match, the login (usually) succeeds. The user needs to login again if he/she doesn’t navigate the site for cookie_duration seconds (specified in the cms.conf file).

In fact, there are other reasons that can cause the login to fail. If the ip_lock option (in cms.conf) is set to true then the login will fail if the IP address that attempted it is different from the ip field of the specified user. If ip is then this check will be skipped, even if ip_lock is true. Note that if a reverse-proxy (like nginx) is in use then it is necessary to set is_proxy_used (in cms.conf) to true.

The login can also fail if block_hidden_users (in cms.conf) is true and the user one wants to login as has the hidden field set.

USACO-like contests

The most peculiar trait of the USACO contests is that the contests themselves are many days long but each user is only able to compete for a few hours after their first login (after that he/she is not able to send any more submissions). This can be done in CMS too, using the per_user_time field of contests. If it is unset the contest will behave “normally”, that is all users will be able to submit solutions from the contest’s start until the contest’s stop. If, instead, per_user_time is set to a positive integer value then an use will only have a limited amount of time. In particular, after he/she logs in, he/she will be presented with an interface similar to the pre-contest one, with one addition: a “start” button. Clicking on this button starts the time-frame in which the user can compete (i.e. read statements, download attachments, submit solutions, use tokens, send user_tests, etc.). This time-frame ends after per_user_time seconds or when the contest stop time is reached, whichever comes first. After that the interface will be identical to the post-contest one: the user won’t be able to do anything. See issue #61.

The time at which the user clicks the “start” button is recorded in the starting_time field of the user. You can change that to shift the user’s time-frame (but we suggest to use extra_time for that, explained in Extra time) or unset it to make the user able to start its time-frame again. Do so at your own risk!

Extra time

Contest administrators may want to give some users a short additional amount of time in which they can compete to compensate for an incident (e.g. a hardware failure) that made them unable to compete for a while during the “intended” time-frame. That’s what the extra_time field of the users is for. The time-frame in which the user is allowed to submit solutions is expanded by its extra_time, even if this would lead the user to be able to submit after the end of the contest.

Note that in its extra time the user will continue to receive newly generated tokens. If you don’t want him/her to have more tokens that other contestants set the token_total parameter described above to the number of tokens you expect a user to have at his/her disposal during the whole contest (if it doesn’t already have a value less than or equal to this). See also issue #29.

Note also that submissions sent during the extra time will continue to be considered when computing the score, even if the extra_time field of the user is later reset to zero (for example in case the user loses the appeal): you need to completely delete them from the database.

Project Versions

Table Of Contents

Previous topic

Creating a contest

Next topic

Task types

This Page