plom.create module
Plom tools related to producing papers, and setting up servers.
- class plom.create.PlomClasslistValidator[source]
The Plom Classlist Validator has methods to help ensure compatible classlists.
- check_ID_column(classlist: list[dict[str, str | int]]) tuple[bool, list][source]
Check the ID column of the classlist.
- check_is_canvas_csv(csv_file_name: Path | str) bool[source]
Detect if a csv file is likely a Canvas-exported classlist.
- Parameters:
csv_file_name – csv file to be checked.
- Returns:
True if we think the input was from Canvas, based on presence of certain header names. Otherwise False.
- check_is_non_canvas_csv(csv_file_name: Path | str) bool[source]
Read the csv file and check if id and name columns exist.
Check if id is present.
Check if name is preset.
- Parameters:
csv_file_name – the csv file.
- Returns:
bool
- check_name_column(classlist: list[dict[str, str | int]]) list[source]
Check name column return any warnings.
- check_paper_number_column(classlist: list[dict[str, str | int]]) tuple[bool, list][source]
Check the papernumber column of the classlist.
Entries must either be blank, or integers >= -1. Note that:
no integer >=0 can be used twice, and
blank or -1 are sentinel values used to indicate ‘do not prename’
- static is_paper_number_sentinel(x: int | float | str | None) bool[source]
True if the input is None, blank, -1 or ‘-1’.
Note: zero is not sentinel.
- readClasslist(filename: Path | str) list[dict[str, Any]][source]
Read classlist from filename and return as list of dicts.
- Parameters:
filename – csv-file to be loaded. It must be UTF-8 encoded, or “utf-8-sig”.
- Returns:
List of dictionaries (keys are column titles). We canonicalize the header names so that we have at least
"id", "name", "paper_number"and"_src_line", the latter used for error messages in further validation. The"paper_number"key might or might not be present.- Raises:
ValueError – the file does not contain a header line, or the file does not contain any of the header names we might expect, or there is some other problem with the headers.
UnicodeDecodeError – encoding troubles, such as when the file isn’t in UTF-8.
- validate(cl_as_dicts: list[dict[str, Any]]) tuple[bool, list[dict[str, Any]]][source]
Validate a proposed classlist and return summaries of any errors and warnings.
- Parameters:
cl_as_dicts – a list of dicts with fields “id”, “name”, and optionally “paper_number”.
- Returns:
(valid, warnings_and_errors)as described in :method:`validate_csv`.
- validate_csv(filename: Path | str) tuple[bool, list[dict[str, Any]], list[dict[str, Any]]][source]
Validate the classlist csv and return summaries of any errors and warnings.
- Parameters:
filename – a csv file from which to try to load the classlist. It must be UTF-8-encoded. Microsoft’s “utf-8-sig” with “FEFF” byte-order-mark is also reluctantly accepted.
- Returns:
(valid, warnings_and_errors, cl_as_list_of_dicts)where “valid” is True/False, “warnings_and_errors” is a list of dicts and “cl_as_dicts” is a list of dicts of the actual classlist, with canonicalized fieldnames, at least “id”, “name”, “paper_number”. In the 2nd output, each dict encodes a single warning or an error: see code for precise format. It is possible for “valid” to be True and still have non-empty “warnings_and_errors” for example when there are only warnings.
- plom.create.build_bundle_separator_paper_pdf(destination_dir=None, *, latex_papersize: str = '') Path[source]
Build the bundle separator pdf file.
Similar to
build_extra_page_pdf().
- plom.create.build_extra_page_pdf(destination_dir=None, *, latex_papersize: str = '') Path[source]
Build the extra page pdf file.
- Parameters:
destination_dir – if specified, build here, else in the current working directory.
- Keyword Arguments:
latex_papersize – the latex-compatible papersize, e.g., “letterpaper” or “a4paper”. Defaults to file contents, current “letterpaper” if omitted.
- Returns:
The path to the file “extra_pages.pdf” that was built.
- plom.create.build_scrap_paper_pdf(destination_dir=None, *, latex_papersize: str = '') Path[source]
Build the scrap paper pdf file.
Similar to
build_extra_page_pdf().
- plom.create.make_PDF(spec, papernum: int, question_versions: dict[int | str, int], extra: dict[str, Any] | None = None, xcoord: float | None = None, ycoord: float | None = None, no_qr: bool = False, *, public_code: str | None = None, where: Path | None = None, source_versions_path: Path | str | None = None, source_versions: dict[int, Path] | None = None, font_subsetting: bool | None = None, paperstr: str | None = None, qr_code_size: float | int | None = None) Path[source]
Make a PDF of particular versions, with QR codes, and optionally name stamped.
Take pages from each source (using questions_versions/page_versions) and add QR codes and “DNW” staple-corner indicators. Optionally stamp the student name/id from extra onto the cover page. Save the new PDF file into the paperdir (typically “papersToPrint”).
- Parameters:
spec (dict | SpecVerifier) – A validated specification
papernum – the paper number.
question_versions – the version of each question for this paper. Note this is an input and must be predetermined before calling.
extra – Dictionary with student id and name or None to default not printing any prename.
xcoord – horizontal positioning of the prename box, or a default if None or omitted.
ycoord – vertical positioning of the prename box, or a default if None or omitted.
no_qr (bool) – determine whether or not to paste in qr-codes. Somewhat deprecated, definitely use it as kwarg if you’re writing new code.
- Keyword Arguments:
public_code – a short numeric code included in the QR codes to, will be taken from the spec if omitted (which should only be done in legacy situations as the public code is not longer stored in the spec!
where – where to save the files, with some default if omitted.
source_versions – ordered list of locations of the source-version files. Mutually-exclusive with
source_versions_path.source_versions_path – location of the source versions directory. Defaults to “./sourceVersions” if this and
source_versionsare omitted.font_subsetting – if None/omitted, do a generally-sensible default of using subsetting only when we added non-ascii characters. True forces subsetting and False disables it. We embed fonts for names and other overlay. But if there are non-Latin characters (e.g., CJK) in names, then the embedded font is quite large (several megabytes). Note: in theory, subsetting could muck around with fonts from the source (i.e., if they were NOT previously subsetted). So we only do the subsetting if we’re added non-ascii chars in any of the shortname, student name or question labels. Non-ascii is a stronger requirement than needed,
paperstr – override the default string version of the paper number. Probably you don’t need to do this, although Mocker does.
qr_code_size – width/height of the QR codes.
- Returns:
the file that was just written.
- Return type:
pathlib.Path
- Raises:
ValueError – Raise error if the student name and number is not encodable
- plom.create.make_hw_scribbles(server, password, basedir=PosixPath('.'), how_many=10)[source]
Fake homework submissions by scribbling on the pages of blank tests.
- Parameters:
server (str) – the name and port of the server.
password (str) – the “manager” password.
basedir (str/pathlib.Path) – the blank tests (for scribbling) will be taken from basedir/papersToPrint. The pdf files with scribbles will be created in basedir/submittedHWByQ.
how_many (int) – how many hws to create
Read in the existing papers.
Create the fake data filled pdfs
Generates second batch for first half of papers.
Generates some “semiloose” bundles; those that have all questions or more than one question in a single bundle.
- plom.create.make_scribbles(basedir=PosixPath('.'), *, msgr)[source]
Fake exam writing by scribbling on the pages of the blank exams.
After Plom exam PDF files have been generated, this can be used to scribble on them to simulate random student work. Note this tool does not upload those files, it just makes some PDF files for you to play with or for testing purposes.
- Parameters:
basedir (str/pathlib.Path) – the blank tests (for scribbling) will be taken from basedir/papersToPrint. The pdf files with scribbles will be created in basedir. Defaults to current directory.
- Keyword Arguments:
msgr (plom.Messenger/tuple) – either a connected Messenger or a tuple appropriate for credientials.
- Returns:
None
Read in the existing papers.
Create the fake data filled pdfs
Do some things to make the data unpleasant:
delete the last page of the first test.
Randomly add some extra pages