+124
@@ -0,0 +1,124 @@
|
||||
// SPDX-License-Identifier: Prosperity-3.0.0
|
||||
// Copyright Scientific Computing Studio
|
||||
// Source: https://git.scient.ing/education/coursebank
|
||||
|
||||
//! # coursebank
|
||||
//!
|
||||
//! A tool for running the assessment side of a course as version-controlled data.
|
||||
//!
|
||||
//! The premise is that the artifacts you already produce (questions, exams,
|
||||
//! grading exports) are worth treating as a dataset rather than as a pile of
|
||||
//! documents. Once they are, several things you cannot otherwise do become
|
||||
//! routine: knowing which questions actually discriminate, catching a poorly worded
|
||||
//! item from the pattern of who chose which distractor, telling a student which
|
||||
//! misconception their specific wrong answer indicates, and never accidentally
|
||||
//! reusing the same question three terms in a row.
|
||||
//!
|
||||
//! ## The four kinds of file
|
||||
//!
|
||||
//! | File | Holds | Written by |
|
||||
//! |:--|:--|:--|
|
||||
//! | `course.yaml` | identity, policy, objectives, lectures | you |
|
||||
//! | `banks/*.yaml` | items, with design intent and pooled statistics | you, then `calibrate` |
|
||||
//! | `assessments/*.yaml` | what was given, to whom, when | `assemble`, then you |
|
||||
//! | `data/*.parquet` | one row per student per item | `ingest` |
|
||||
//!
|
||||
//! Three of the four are hand-editable YAML meant to be reviewed in a pull request.
|
||||
//! Only the response data is machine-only, and it is stored in an open columnar
|
||||
//! format so pandas, polars, R, and DuckDB can all read it without this tool.
|
||||
//!
|
||||
//! ## The loop
|
||||
//!
|
||||
//! ```text
|
||||
//! author items ──▶ validate ──▶ lint ──▶ assemble ──▶ export ──┐
|
||||
//! ▲ │
|
||||
//! │ administer
|
||||
//! │ │
|
||||
//! calibrate ◀── analyze ◀── ingest ◀───────────────────────────┘
|
||||
//! │
|
||||
//! └──▶ report (students and cohort)
|
||||
//! ```
|
||||
//!
|
||||
//! The arrow back from `calibrate` to authoring is the point of the whole design.
|
||||
//! Statistics written onto the item are there the next time you consider using it,
|
||||
//! and they accumulate across terms: twenty-four students tells you very little,
|
||||
//! but ninety-six across four terms tells you something real.
|
||||
//!
|
||||
//! ## Design commitments
|
||||
//!
|
||||
//! Assessment records are the single source of truth for reuse history. There
|
||||
//! is no separate ledger file, because a ledger duplicates what the records must
|
||||
//! already get right and then drifts from it. [`history::History`] derives usage
|
||||
//! by scanning the records.
|
||||
//!
|
||||
//! Fingerprints cover only what a student saw. Retag an item's metadata and its
|
||||
//! pooled statistics stay valid; reword the stem and they are marked stale. See
|
||||
//! [`item::Item::fingerprint`].
|
||||
//!
|
||||
//! Validation reports everything at once. Fixing one typo per run is not a
|
||||
//! workflow. [`error::Error::Invalid`] carries a list.
|
||||
//!
|
||||
//! Validation and linting are separate. [`bank::BankFile::validate`] enforces
|
||||
//! what must be true; [`lint`] advises on what is usually a mistake, and every rule
|
||||
//! has a code you can silence.
|
||||
//!
|
||||
//! Small samples are labelled as such. Every statistic computed from a class of
|
||||
//! twenty-five is reported with the caveat it deserves rather than three decimal
|
||||
//! places of false precision.
|
||||
//!
|
||||
//! ## Dependency posture
|
||||
//!
|
||||
//! Deliberately small: serde, a YAML parser, clap, thiserror, and csv, plus arrow
|
||||
//! and parquet behind a default-on feature that can be switched off. Dates, PRNG,
|
||||
//! hashing, ZIP writing, and the psychometrics are implemented here rather than
|
||||
//! pulled in — see [`date`], [`rng`], [`hash`], [`zipfile`], [`irt`]. For a tool
|
||||
//! whose job is to still open a course repository in five years, that tradeoff
|
||||
//! favours fewer moving parts.
|
||||
//!
|
||||
//! ## Where to start
|
||||
//!
|
||||
//! This page describes the shape of the crate. For a walkthrough, [`guide`] holds
|
||||
//! setup, authoring, and tutorials, starting with [`guide::setup`].
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(rustdoc::broken_intra_doc_links)]
|
||||
#![warn(rustdoc::invalid_codeblock_attributes)]
|
||||
#![warn(rustdoc::invalid_html_tags)]
|
||||
#![warn(rustdoc::bare_urls)]
|
||||
#![warn(rustdoc::private_intra_doc_links)]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
|
||||
pub mod analysis;
|
||||
pub mod authoring;
|
||||
pub mod data;
|
||||
pub mod error;
|
||||
pub mod export;
|
||||
pub mod guide;
|
||||
pub mod model;
|
||||
pub mod util;
|
||||
|
||||
pub use util::{date, hash, markup, rng, yaml, zipfile};
|
||||
|
||||
pub use model::{assessment, bank, catalog, course, history, item, layout, taxonomy};
|
||||
|
||||
pub use authoring::{jsonschema, lint, select};
|
||||
|
||||
#[cfg(feature = "parquet")]
|
||||
pub use data::store_parquet;
|
||||
pub use data::{canvas, gradescope, responses, store};
|
||||
|
||||
pub use analysis::{calibrate, classical, irt, students};
|
||||
|
||||
pub use export::{qti, report, typst};
|
||||
|
||||
pub use catalog::Catalog;
|
||||
pub use course::{CourseFile, SCHEMA_VERSION};
|
||||
pub use error::{Error, Result};
|
||||
pub use history::History;
|
||||
pub use item::Item;
|
||||
pub use layout::Layout;
|
||||
pub use taxonomy::{CognitiveProcess, ErrorType, Flag, Format, Level, Status};
|
||||
|
||||
/// Version of package.
|
||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
Reference in New Issue
Block a user