Add Sphinx documentation, docs Makefile, and documentation URL

This commit is contained in:
Chris Proctor
2026-06-22 22:27:43 -04:00
parent ffed9f2d01
commit a7543b7b1b
12 changed files with 1026 additions and 5 deletions

20
docs/Makefile Normal file
View File

@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

15
docs/api.rst Normal file
View File

@@ -0,0 +1,15 @@
.. _api:
API
===
An API (Application Programming Interface) describes how software programs
can interact with a system. For a code package like `easybits`, the API
provides a complete listing of the functions available, along with
explanations of how to use them and example code.
.. toctree::
bits
util
errors

7
docs/bits.rst Normal file
View File

@@ -0,0 +1,7 @@
.. _bits:
Bits
====
.. automodule:: easybits
:members:

46
docs/conf.py Normal file
View File

@@ -0,0 +1,46 @@
# Configuration file for the Sphinx documentation builder.
#
# For a full list of options see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
import os
import sys
sys.path.insert(0, os.path.abspath('..'))
# -- Project information -----------------------------------------------------
project = 'easybits'
copyright = '2025, Chris Proctor'
author = 'Chris Proctor'
# The full version, including alpha/beta/rc tags
release = '0.1.4'
# -- General configuration ---------------------------------------------------
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.napoleon",
"sphinx.ext.viewcode",
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = []
# -- Options for HTML output -------------------------------------------------
html_theme = 'furo'
html_static_path = ['_static']
# -- Additional configuration -------------------------------------------------
autodoc_member_order = 'bysource'
autodoc_typehints = 'none'

7
docs/errors.rst Normal file
View File

@@ -0,0 +1,7 @@
.. _errors:
Errors
======
.. automodule:: easybits.errors
:members:

33
docs/index.rst Normal file
View File

@@ -0,0 +1,33 @@
easybits
========
This documentation explains how to use the functions provided
in the `easybits` package. `easybits` is distributed via pypi,
so you can install it using pip or poetry.
Every file on your computer is just a sequence of bits. Every message
that gets sent between computers is just a sequence of bits. Working
directly with bits is easy in lower-level languages, but a bit trickier
in Python. `easybits` exposes the bit representations of booleans,
integers, and text, so that you can see--and manipulate--the bits
underneath the values you already know how to use.
This documentation is organized according to a common pattern: the
:ref:`introduction` contains narrative documentation walking you through
how to use the system. The :ref:`api` contains a complete description of
each function and how to use it. If you're trying to learn what `easybits`
can do, start with the :ref:`introduction`. If you're trying to check a
detail about how to do it, head to the :ref:`api`.
`easybits` is part of the `Making With Code` introductory computer science
curriculum, with an intended audience of beginners. It is used in the
`Encoding lab <https://makingwithcode.org/courses/mwc2/unit2/lab_encoding/>`_.
If you are interested in `Making With Code`, or if you found `easybits`
helpful, `Dr. Chris Proctor <https://chrisproctor.net>`_ would love to hear
from you.
.. toctree::
:maxdepth: 2
introduction
api

113
docs/introduction.rst Normal file
View File

@@ -0,0 +1,113 @@
.. _introduction:
Introduction
============
Computers work exclusively with binary values: 0 and 1, called *bits*.
Every file on your computer is just a sequence of bits. Every message
that gets sent between computers is just a sequence of bits. Python
hides this from you most of the time--when you write ``True``, ``12``,
or ``"Chris"``, Python doesn't normally show you the bits underneath.
`easybits` provides the :class:`~easybits.Bits` class, which lets you
see and manipulate those bits directly.
Creating bits
-------------
The :class:`~easybits.Bits` class can be built from several different
kinds of values. The simplest is a string of ``0`` s and ``1`` s::
from easybits import Bits
b = Bits('1010')
print(b) # 1010
You can also build bits from Python's other building blocks. A
boolean becomes a single bit::
Bits(True) # 1
Bits(False) # 0
Bytes become eight bits each::
Bits(b'a') # 01100001
Booleans
--------
Because :class:`~easybits.Bits` is built on top of the `bitarray`
package, it supports the same bitwise operators you'd find in a
lower-level language: ``~`` (NOT), ``&`` (AND), ``|`` (OR), ``^``
(XOR), and the shift operators ``<<`` and ``>>``::
a = Bits('1100')
b = Bits('1010')
a & b # 1000
a | b # 1110
a ^ b # 0110
~a # 0011
a << 1 # 1000
a >> 1 # 0110
Integers
--------
Bits represent numbers in binary, where each position is worth twice
as much as the position to its right: 1, 2, 4, 8, and so on. Because
an integer's bits don't have a natural length the way a boolean's
single bit does, `easybits` requires you to say how many bits to use::
Bits(12, length=8) # 00001100
Negative numbers are represented using *two's complement*, which is
why `easybits` always treats integers as signed. To recover the
integer value of some bits, use the ``.int`` property::
b = Bits(-12, length=16)
b.int # -12
You can add and subtract bits just like integers, as long as both
operands have the same length::
Bits(5, length=8) + Bits(3, length=8) # 00001000
Bits(5, length=8) - Bits(3, length=8) # 00000010
This bitwise addition is implemented from scratch, carry bit and all,
so you can watch how addition really happens at the level of circuits.
Text
----
Text is the trickiest of the three. ASCII, an early standard for
representing text as bits, only has room for 128 characters--enough
for English, but not for the world's other languages, let alone emoji.
Unicode, and its common encoding UTF-8, supports more than 150,000
characters, covering world languages and emoji alike. Because of this,
encoding text requires choosing an encoding, and `easybits` lets you
say which one to use::
Bits("Chris") # ASCII by default
Bits("\N{SMILING FACE WITH HEART-EYES}", encoding='utf8')
To go the other direction--from bits back to text--use the ``.ascii``
property, or decode the ``.bytes`` yourself with whichever encoding
you used to create the bits::
b = Bits("Chris")
b.ascii # 'Chris'
Inspecting bits
----------------
However you created your bits, you can always ask what they look like
as a different kind of value, using the :class:`~easybits.Bits`
properties:
- ``.bool`` returns a list of booleans, one per bit
- ``.int`` interprets the bits as a signed integer
- ``.bytes`` returns the raw bytes
- ``.ascii`` decodes those bytes as ASCII text
The :ref:`api` describes each of these, along with the rest of the
:class:`~easybits.Bits` class, in full detail.

7
docs/util.rst Normal file
View File

@@ -0,0 +1,7 @@
.. _util:
Util
====
.. automodule:: easybits.util
:members: