Import / Export

The knowledgespaces.io module reads and writes CSV and JSON files compatible with existing KST tools and R packages.

CSV formats

Skill map matrix

,skill1,skill2,skill3
item1,1,0,1
item2,0,1,0
from knowledgespaces.io import read_skill_map, write_skill_map

sm = read_skill_map("skill_map_matrix.csv")
write_skill_map(sm, "output_skill_map.csv")

Prerequisite matrix

,item_a,item_b,item_c
item_a,0,1,0
item_b,0,0,1
item_c,0,0,0

Row i, column j = 1 means item i is a prerequisite of item j.

from knowledgespaces.io import read_relation, write_relation

rel = read_relation("prerequisites_matrix.csv")
write_relation(rel, "output_prerequisites.csv")

Knowledge structure

state_size,state_id,item_a,item_b,item_c
0,0,0,0,0
1,1,1,0,0
2,2,1,1,0
3,3,1,1,1
from knowledgespaces.io import read_structure, write_structure

ks = read_structure("learning_space.csv")
write_structure(ks, "output_structure.csv")

JSON

JSON provides full serialization including structural properties:

from knowledgespaces.io import write_structure_json, read_structure_json

write_structure_json(ks, "structure.json")
loaded = read_structure_json("structure.json")

All types have symmetric read_X_json / write_X_json helpers (and dict_to_X / X_to_dict for in-memory conversion): KnowledgeStructure, SurmiseRelation, SkillMap, SurmiseFunction.

from knowledgespaces.io import write_surmise_function_json, read_surmise_function_json

write_surmise_function_json(sf, "surmise_function.json")
loaded = read_surmise_function_json("surmise_function.json")

Validation

All readers validate input strictly:

  • Column counts must match headers

  • Values must be binary (0 or 1)

  • Labels must be unique where they identify distinct items/skills; competency tables intentionally repeat item labels for alternatives

  • Prerequisite matrices must have matching row and column labels

  • JSON schemas are validated with clear error messages

Skill multimaps

SkillMultiMap.to_matrix() returns repeated item labels, skill labels and one binary row per alternative competency. from_matrix() reverses this representation. Unlike a conjunctive skill-map table, an item can have multiple rows; each row is sufficient independently. Unused skill columns and all-zero (empty competency) rows are retained.

from knowledgespaces import SkillMultiMap
from knowledgespaces.io import write_skill_multimap, read_skill_multimap

mapping = SkillMultiMap("ab", "xyz", {"a": ["x", "y"], "b": ["xy"]})
write_skill_multimap(mapping, "competencies.csv")
restored = read_skill_multimap("competencies.csv")
assert restored.to_matrix() == mapping.to_matrix()

The CSV layout is item,skill1,skill2,..., followed by competency rows. Standard CSV quoting handles commas, newlines and Unicode. This is the same logical table layout used by CbKST; native XLSX/ODS adapters are not supplied by these CSV functions. Labelled JSON is available through read_skill_multimap_json / write_skill_multimap_json and the corresponding dict_to_skill_multimap / skill_multimap_to_dict helpers.

General clauses and families

read_attribution / write_attribution use repeated-item CSV rows with one binary column per domain item. All items must have clause rows; empty clauses are all-zero rows. read_surmise_function reads the same table but requires the canonical axioms, without repairing it. This is the logical CSV layout of the kstIO surmise-function tables.

from knowledgespaces.io import read_attribution, write_surmise_function

attribution = read_attribution("prerequisite_clauses.csv")
function = attribution.to_surmise_function()
write_surmise_function(function, "canonical_clauses.csv")

read_attribution_json / write_attribution_json preserve the original general clauses. read_family_json / write_family_json preserve exactly the declared domain and member sets, without inserting endpoints. Both have symmetric dict_to_X / X_to_dict helpers. A compact base can be saved as base.as_family() and recovered explicitly with read_family_json(path).to_knowledge_base(). Nested label lists are validated before constructing the objects.

KST and SRBT legacy text

from knowledgespaces.io import write_legacy_structure, read_legacy_structure

columns = sorted(ks.domain)
write_legacy_structure(ks, "structure.kst", format="KST", items=columns)
restored = read_legacy_structure("structure.kst", format="KST", items=columns)
assert restored == ks

read_legacy_matrix / write_legacy_matrix preserve binary rows, their order and duplicates. The required kind declares structure, space, basis, data, relation or family. These are syntax-level matrix functions, not constructors that verify or close a knowledge space.

Format

Layout

Object kinds

KST

Number of items, number of rows, then contiguous binary rows

All except relation

SRBT

#SRBT v2.0 ... header, dimensions, optional comments, binary rows

Structure, space, basis, data, relation

matrix

Binary rows with no header

All six

SRBT relations contain one dimension because the matrix is square. The structure header ends in structure ASCII; space headers with or without ASCII are accepted. Comments are allowed after SRBT dimensions, before its data rows. CRLF and LF line endings and a UTF-8 BOM are accepted.

These formats do not contain item labels. Save the ordered items separately; otherwise readers assign string labels "1" through "n". Changing that external order changes the interpretation of the data. Filenames do not determine the format. Automatic detection validates syntax and refuses ambiguous unheaded files; supply format= to resolve them. Only complete binary rows are supported: no missing code, aggregated-count column, respondent ID or metadata is silently interpreted or discarded.

The object-level read_legacy_structure requires the empty and full state in the file. It does not add them automatically. A space header can be read as a structure; check is_knowledge_space before treating it as a space. read_legacy_relation requires a reflexive and transitive relation, and write_legacy_relation requires explicit closure of generating pairs. Both use row a, column b = a is a prerequisite of b, matching kstMatrix and kstIO. Duplicate matrix rows are retained by the low-level readers; structure construction naturally represents a set of states.

Files written by kstIO 0.5-1 source functions are covered by offline tests. Fresh R reads also check Python exports, including an asymmetric prerequisite chain. This verifies the documented text subset, not all spreadsheet formats or every kstIO option.

Course assignments

read_assignment_csv(taught_path, required_path) reads two UTF-8 tables, each with positional (learning object, skill) columns. header=False and delimiter=";" support alternate CSV layouts; quoted fields, whitespace and Unicode labels are preserved. Explicit learning_objects and skills domains can retain labels absent from the tables. Inspect diagnostics() after import.

write_assignment_csv supports single assignments whose domain labels occur in the tables. For alternatives or unused labels, use read_assignment_json / write_assignment_json, or the corresponding assignment_to_dict / dict_to_assignment functions. JSON includes a skills list and an objects list of records with id, taught and required fields. Repeated IDs express alternative requirements for the same taught skills. See the curriculum guide for derivation and scheduling.

read_assignment / write_assignment additionally detect native XLSX/ODS workbooks with Taught/Required sheets. See spreadsheet interchange for these layouts and strict KST object conversions in CSV/XLSX/ODS.