Skip to main content

SDS Tools - Simple Data Structures

PyPI version Documentation Python Version License Type Checked Code Style Static Badge

A comprehensive and educational Python library of fundamental data structures — from linked lists to probabilistic graphical models — and of the classic algorithms that operate on them, implemented with object-oriented programming principles and extensive academic-style documentation.

Package name note: the PyPI/pip distribution is named pysds-tools (sds-tools collides with an existing, unrelated package once PyPI normalizes names). The importable module is unaffected — it's still sds (import sds.linear, import sds.probabilistic, ...).

Goals

  • Educational: Clear, well-documented code for learning — not just working code, but code that explains why
  • Comprehensive: Exhaustive coverage of classic and advanced data structures
  • Typed: Full MyPy strict-mode support, pyright/basedpyright compatible
  • Tested: 80–90%+ coverage target per module, enforced via pytest-cov
  • Performant: __slots__ on every node and structure class

Installation

pip install pysds-tools

The base install has no dependency. Two optional extras add third-party packages for specific features:

Extra Installs For
image matplotlib Image export of the visualiser
yaml PyYAML YAML input of the pysds command
pip install "pysds-tools[image]"
pip install "pysds-tools[image,yaml]"

Using a feature without its extra raises an error that gives the install command.

Quick Start

from sds.linear import Stack
from sds.graph import DirectedGraph, GraphNode, DirectedEdge
from sds.probabilistic import BayesianNetwork, Factor, RandomVariable

# Linear structures
stack = Stack()
stack.push(1)
stack.push(2)
stack.pop()  # 2

# Graphs
task_graph = DirectedGraph()
design, backend = GraphNode("Design"), GraphNode("Backend")
task_graph.add_node(design)
task_graph.add_node(backend)
task_graph.add_edge(DirectedEdge(design, backend))
task_graph.is_acyclic()  # True

# Probabilistic graphical models
rain = RandomVariable("Rain", ("true", "false"))
bn = BayesianNetwork()
bn.add_variable(rain)
bn.set_cpt(rain, Factor((rain,), {("true",): 0.2, ("false",): 0.8}))

# Algorithms: free functions that take the structure as argument
from sds.algorithms.graph_algorithms import bfs
from sds.algorithms.sorting import merge_sort

[node.data for node in bfs(task_graph, design)]  # ['Design', 'Backend']
merge_sort([3, 1, 2])  # [1, 2, 3]

Visualisation

sds.utils.visualizer renders linear structures, trees and graphs as text, as Mermaid or, for graphs, as Graphviz DOT source, with no dependency; save_image() draws them with matplotlib (image extra).

from sds.tree import BinarySearchTree
from sds.utils.visualizer import save_image, to_mermaid, to_text

tree = BinarySearchTree()
for key in (50, 30, 70, 20, 40):
    tree.insert(key)

print(to_text(tree))
# 50
# ├── L: 30
# │   ├── L: 20
# │   └── R: 40
# └── R: 70

to_mermaid(tree)              # "flowchart TD\n    n0[\"50\"]\n..."
save_image(tree, "tree.png")  # needs pysds-tools[image]

Command Line

Installing the package also installs pysds, which builds a structure described in a JSON or YAML file and displays it:

$ cat roads.json
{"type": "WeightedGraph",
 "nodes": [{"id": "P", "data": "Paris"}, {"id": "L", "data": "Lyon"}],
 "edges": [["P", "L", 465]]}
$ pysds show roads.json
Paris -- Lyon (465.0)
Lyon -- Paris (465.0)
$ pysds show roads.json --format mermaid --output roads.mmd
$ pysds show roads.json --image roads.svg   # needs pysds-tools[image]

YAML files (.yaml, .yml) need the yaml extra; - reads JSON on standard input, and python -m sds runs the same command. The command-line guide describes the file format of each family of structures.

Architecture

The project is organized into thematic modules, one per family of structures:

src/sds/
├── core/           # Foundations: AbstractNode, AbstractContainer, exceptions
├── linear/         # Linear structures (linked list, stack, queue)
├── tree/           # Tree structures (binary, AVL, heaps, B-tree, trie, segment tree)
├── graph/          # Graph structures (directed, weighted, adjacency representations)
├── advanced/       # Deterministic advanced structures (disjoint set, Bloom filter, ...)
├── probabilistic/  # Probabilistic graphical models (Bayesian networks, MRF, HMM)
├── algorithms/     # Sorting, tree and graph algorithms, probabilistic inference
└── utils/          # Visualizer, pysds command, optional-dependency errors

Available Structures

sds.core — Foundations

Base abstractions shared by every other module: AbstractNode, AbstractContainer, and the common exception hierarchy. Contains no concrete data structure by design — every other module imports from here, never the reverse.

sds.linear — Linear Structures

  • LinkedList: doubly linked list — O(1) prepend/append
  • Stack: LIFO — push(), pop(), peek(), all O(1)
  • Queue: FIFO — enqueue(), dequeue(), all O(1)

sds.tree — Tree Structures

  • BinaryTree, AVLTree (self-balancing, guaranteed O(log n)), GeneralTree (n-ary)
  • MinHeap, MaxHeap
  • BTree, Trie (prefix search), SegmentTree (range queries)

sds.graph — Graph Structures

  • Graph, DirectedGraph, UndirectedGraph (strict wrapper — rejects directed edges explicitly rather than silently converting them)
  • WeightedGraph, WeightedDirectedGraph
  • AdjacencyListGraph (sparse, O(V+E) space), AdjacencyMatrixGraph (dense, O(1) edge lookup)

sds.advanced — Advanced Structures

Deterministic structures that don't fit cleanly into linear/tree/graph:

  • DisjointSet (Union-Find, path compression + union-by-rank — O(α(n)) amortized)
  • BloomFilter (probabilistic set membership), SkipList (probabilistic sorted structure)
  • HashTableChaining, HashTableOpenAddressing
  • LRUCache, FenwickTree (binary indexed tree), CountMinSketch (frequency estimation over streams)

sds.probabilistic — Probabilistic Graphical Models

Structures encoding probability distributions over discrete random variables. No inference logic (marginal queries, most-likely-explanation) is implemented here — inference lives in sds.algorithms.probabilistic_algorithms.

  • RandomVariable, Factor: shared building blocks (a discrete variable and a potential/CPT table over a scope of variables)
  • BayesianNetwork: directed acyclic graphical model with locally normalized CPTs, composes sds.graph.DirectedGraph for topology
  • MarkovRandomField: undirected graphical model (cycles allowed) with unnormalized potentials, composes sds.graph.Graph
  • HiddenMarkovModel: sequential model over a fixed states/observations pair, with initial/transition/emission components

Available Algorithms

Algorithms are kept out of the structure classes: each one is a free function of sds.algorithms that receives the structure it works on, typed against the broadest abstract interface that provides what it needs.

sds.algorithms.sorting

  • merge_sort (stable, returns a new list), quick_sort (in place, not stable) — both with sorted()-style key and reverse

sds.algorithms.tree_algorithms

  • inorder, preorder, postorder, level_order: iterative traversals of any binary tree
  • is_balanced, rebalance (rebuilds a BinarySearchTree to minimum height)

sds.algorithms.graph_algorithms

  • bfs, dfs: traversals of any graph, in reproducible order
  • dijkstra: shortest distances and paths, non-negative weights
  • kruskal: minimum spanning forest of an undirected weighted graph

sds.algorithms.probabilistic_algorithms

  • variable_elimination: exact posterior of query variables
  • belief_propagation: every marginal at once (exact on tree-shaped models)
  • forward, viterbi: likelihood, filtering and decoding for hidden Markov models

Deprecation (0.7.0): the inorder_traversal(), preorder_traversal(), postorder_traversal() and level_order_traversal() methods of binary trees are deprecated and will be removed in 1.0.0 — use sds.algorithms.tree_algorithms instead, e.g. inorder(tree).

Documentation

Full API reference and user guide, including mathematical foundations, Mermaid diagrams, complexity tables, and real-world examples for every module:

https://pysds-tools.readthedocs.io

Testing

# Run all tests
pytest

# Run with coverage
pytest --cov=sds --cov-report=html

# Run tests for a specific module
pytest tests/06_Probabilistic/

# Run in verbose mode
pytest -v

Test suite layout (mirrors the source tree, one directory per module):

tests/
├── 01_Core/
├── 02_Linear/
├── 03_Tree/
├── 04_Graph/
├── 05_Advanced/
└── 06_Probabilistic/

Static Analysis

The project is fully typed and verified with mypy, flake8, and bandit:

mypy src/sds/
flake8 src/sds/
bandit -r src/sds/

Or, via tox:

tox -e mypy,flake8,bandit

Contributing

Contributions are welcome!

  1. Fork the project
  2. Create a branch for your feature (git checkout -b feature/AmazingFeature)
  3. Commit your changes following Conventional Commits
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

Full project conventions (labels, issue templates, commit format, versioning, releases) are documented in CONVENTIONS.md in the shared .github repository.

Quality Standards

  • ✅ Type-checked with mypy (strict mode)
  • ✅ Style-compliant with flake8
  • ✅ Security-checked with bandit
  • ✅ Tests with pytest (80–90%+ coverage target)
  • ✅ NumPy-style docstrings
  • ✅ __slots__ on all node and structure classes

Roadmap

v0.1.0–v0.5.0 — Foundations through Advanced Structures ✅ Completed

  • sds.core, sds.linear, sds.tree, sds.graph, sds.advanced — fully implemented, tested, and documented

v0.6.0 — Probabilistic Structures ✅ Completed

  • sds.probabilistic: BayesianNetwork, MarkovRandomField, HiddenMarkovModel

v0.7.0 — Algorithms ✅ Completed

  • sds.algorithms: sorting (MergeSort, QuickSort), tree traversals and rebalancing, graph algorithms (BFS, DFS, Dijkstra, Kruskal), probabilistic inference (Variable Elimination, Belief Propagation, Forward, Viterbi)

v0.8.0 — Utilities ✅ Completed (this release)

  • sds.utils: visualizer (text, Mermaid, DOT, images), pysds command, optional extras image and yaml
  • Extended exception hierarchy in sds.core; Python 3.11 minimum

v0.9.0–v1.0.0 — Quality Consolidation & Stable Release Planned

  • Full coverage/mypy sweep, documentation polish, first stable API

v1.1.0–v1.2.0 — French Translation Planned

  • Bilingual documentation via a dedicated ReadTheDocs project

License

This project is licensed under the Apache License 2.0 — see the LICENSE file for details. Documentation is licensed separately under CC BY-NC 4.0 — see docs/source/license.rst.

Acknowledgments

  • Inspired by classic data structures and algorithms courses
  • Designed for learning
  • Thanks to the Python community for exceptional tools (pytest, mypy, flake8, bandit, Sphinx, Furo)

Resources


GitLab mirror: https://gitlab.com/open-works/sds

Metadata

Release files for pysds-tools 0.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pysds-tools 0.8.0
File Size Uploaded
pysds_tools-0.8.0.tar.gz 177.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pysds-tools 0.8.0
File Interpreter ABI Platform
pysds_tools-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 426.8 kB

Release files / pysds_tools-0.8.0.tar.gz

Download URL pysds_tools-0.8.0.tar.gz
Size 177.4 kB
Tags Source
SHA-256 checksum
How to use checksums
fac22bf66e3051f642a7d162514642e3370959586b9642356611be2b5c89df95
BLAKE2b-256 checksum
How to use checksums
645e1a8f36ae8a41ff8a364a5a593dde84f6efe85cc3a5916980d66f6b416f80
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / pysds_tools-0.8.0-py3-none-any.whl

Download URL pysds_tools-0.8.0-py3-none-any.whl
Size 249.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
89dcca5948a0b36b42f35daaaf3b30c052b9877fbe44d0ec37e3525d52965de3
BLAKE2b-256 checksum
How to use checksums
88dd50a47657727e93be480843a3688d7088404eb7b060c87c3206ce0f980d6f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.8.0 This release

2 release files

0.7.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page