Skip to content

Commit c6577df

Browse files
Add UnsignedInt docs and update README
- docs/UnsignedInt.md: documents the data structure class, all operations, and the visualization alignment and colour-coding scheme - docs/UnsignedIntTUI.md: documents the TUI app, all commands, overflow reporting, and edge cases - README.md: adds uint/uint-app to all lists, updates TUI count to seven, adds demo-uint target, adds UnsignedIntTUI.md to walkthrough list Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent cae2d79 commit c6577df

3 files changed

Lines changed: 291 additions & 3 deletions

File tree

‎README.md‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ make test-stack
2626
make run-stack
2727
```
2828

29-
The repo includes interactive Textual TUIs for six data structures. Launch any of them with a dedicated `make run-*-app` target:
29+
The repo includes interactive Textual TUIs for seven data structures. Launch any of them with a dedicated `make run-*-app` target:
3030

3131
```bash
3232
make run-stack-app
@@ -35,6 +35,7 @@ make run-deque-app
3535
make run-list-app
3636
make run-sll-app
3737
make run-dll-app
38+
make run-uint-app
3839
```
3940

4041
You can also run a TUI directly:
@@ -52,6 +53,7 @@ For walkthroughs of the interactive apps, see:
5253
- `docs/ListTUI.md`
5354
- `docs/SinglyLinkedListTUI.md`
5455
- `docs/DoublyLinkedListTUI.md`
56+
- `docs/UnsignedIntTUI.md`
5557

5658
## Producing Demo Videos
5759

@@ -76,6 +78,7 @@ make demo-deque
7678
make demo-list
7779
make demo-sll
7880
make demo-dll
81+
make demo-uint
7982
```
8083

8184
Produce all videos at once:
@@ -84,7 +87,7 @@ Produce all videos at once:
8487
make demo-all
8588
```
8689

87-
Individual theme variants are also available, for example `make demo-stack-dark` or `make demo-dll-light`. Generated `.mp4` files are written to `demos/`.
90+
Individual theme variants are also available, for example `make demo-stack-dark` or `make demo-uint-light`. Generated `.mp4` files are written to `demos/`.
8891

8992
For maintenance details about timing, caption placement, and caption wording, see:
9093
- `docs/DemoVideoMaintenance.md`
@@ -99,7 +102,7 @@ For maintenance details about timing, caption placement, and caption wording, se
99102
| `make run-<name>-app` | Launch a TUI app interactively |
100103
| `make test-<name>` | Run a single test module with verbose output |
101104
| `make demo-<name>` | Produce dark+light demo videos for one TUI (requires [vhs](https://github.com/charmbracelet/vhs)) |
102-
| `make demo-all` | Produce demo videos for all six TUIs |
105+
| `make demo-all` | Produce demo videos for all seven TUIs |
103106

104107
Valid `<name>` values (short alias or full name both work):
105108

@@ -124,3 +127,5 @@ Valid `<name>` values (short alias or full name both work):
124127
| `list-app` | `list_app` | `data_structures/tui/list_app.py` | `tests/test_list_app.py` |
125128
| `dll-app` | `doubly_linked_list_app` | `data_structures/tui/doubly_linked_list_app.py` | `tests/test_doubly_linked_list_app.py` |
126129
| `trie` | `trie_demo` | `data_structures/trie_demo.py` | `tests/test_trie_demo.py` |
130+
| `uint` | `unsigned_int` | `data_structures/unsigned_int.py` | `tests/test_unsigned_int.py` |
131+
| `uint-app` | `unsigned_int_app` | `data_structures/tui/unsigned_int_app.py` | `tests/test_unsigned_int_app.py` |

‎docs/UnsignedInt.md‎

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# UnsignedInt
2+
3+
## Purpose
4+
5+
`data_structures/unsigned_int.py` implements a fixed-width unsigned integer that exposes its internal bit, octal, and hexadecimal structure. It is designed as an educational tool for understanding binary number representation — how the same bit pattern looks different depending on the base used to group and read the bits.
6+
7+
The module provides:
8+
9+
- `UnsignedInt` — the data structure class
10+
- `render_visualization()` — a pure function that produces the aligned multi-row box display
11+
12+
## Supported Sizes
13+
14+
| Size | Bits | Hex digits | Octal digits | Phantom bits |
15+
|---|---|---|---|---|
16+
| nibble | 4 | 1 | 2 | 2 |
17+
| byte | 8 | 2 | 3 | 1 |
18+
| short | 16 | 4 | 6 | 2 |
19+
| int | 32 | 8 | 11 | 1 |
20+
| long | 64 | 16 | 22 | 2 |
21+
22+
*Phantom bits* are extra zero bits added on the left so that octal groups (3 bits each) tile evenly across the full display width.
23+
24+
## Operations
25+
26+
### Value
27+
28+
| Method | Description |
29+
|---|---|
30+
| `set_value(n)` | Set the integer value; raises `ValueError` if out of range |
31+
| `clear()` | Reset to zero |
32+
| `value` | Read-only property returning the current integer value |
33+
34+
### Bit operations
35+
36+
| Method | Description |
37+
|---|---|
38+
| `get_bit(pos)` | Return the bit at position `pos` (0 = LSB) |
39+
| `set_bit(pos)` | Set bit `pos` to 1 |
40+
| `reset_bit(pos)` | Set bit `pos` to 0 |
41+
| `toggle_bit(pos)` | Flip bit `pos` |
42+
43+
### Shift and rotate
44+
45+
| Method | Description |
46+
|---|---|
47+
| `shift_left(n)` | Logical shift left; returns the bits shifted out (non-zero signals overflow) |
48+
| `shift_right(n)` | Logical shift right; zeros fill from the left |
49+
| `rotate_left(n)` | Circular left rotation; no bits lost |
50+
| `rotate_right(n)` | Circular right rotation; no bits lost |
51+
52+
### Logical
53+
54+
| Method | Description |
55+
|---|---|
56+
| `complement()` | Bitwise NOT within the current bit width |
57+
| `bitwise_and(other)` | AND with an unsigned integer constant |
58+
| `bitwise_or(other)` | OR with an unsigned integer constant |
59+
| `bitwise_xor(other)` | XOR with an unsigned integer constant |
60+
61+
### Group operations
62+
63+
| Method | Description |
64+
|---|---|
65+
| `set_octal_group(pos, digit)` | Set the octal group at `pos` (0 = rightmost) to `digit` (0–7) |
66+
| `set_hex_group(pos, digit)` | Set the hex nibble at `pos` (0 = rightmost) to `digit` (0–15) |
67+
68+
### Query
69+
70+
| Method | Description |
71+
|---|---|
72+
| `bit_list()` | List of bits MSB-first, length == `size` |
73+
| `octal_groups()` | List of octal digit values MSB-first (including phantom MSB group) |
74+
| `hex_groups()` | List of hex nibble values MSB-first |
75+
| `phantom_bit_count()` | Number of phantom bits required for octal alignment |
76+
| `display_bit_width()` | Total bit columns shown (real + phantom) |
77+
| `to_bin()` | `"0b..."` string, zero-padded to `size` |
78+
| `to_oct()` | `"0o..."` string |
79+
| `to_hex()` | `"0x..."` string, zero-padded to `size // 4` hex digits |
80+
81+
## Visualization
82+
83+
`render_visualization(uint, markup=False)` returns a multi-line string showing three aligned rows:
84+
85+
```
86+
Binary
87+
┌───┬───┬───┳───┬───╥───┳───┬───┬───┐
88+
│ · │ 0 │ 1 ┃ 0 │ 1 ║ 0 ┃ 1 │ 0 │ 1 │
89+
└───┴───┴───┻───┴───╨───┻───┴───┴───┘
90+
Hex
91+
┌───┬───────────────┬───────────────┐
92+
│ · │ 5 │ 5 │
93+
└───┴───────────────┴───────────────┘
94+
Octal
95+
┌───────────┬───────────┬───────────┐
96+
│ 1 │ 2 │ 5 │
97+
└───────────┴───────────┴───────────┘
98+
```
99+
100+
All three rows have the same total character width. Alignment rules:
101+
102+
- **Binary row** — one cell per display bit (real bits + phantom `·` on the left)
103+
- **Hex row** — each cell spans 4 bit columns; a phantom cell on the left accounts for unused display columns
104+
- **Octal row** — each cell spans 3 bit columns; always tiles the full display width
105+
106+
### Group boundary indicators
107+
108+
The binary row uses different separator characters to show where groups begin and end:
109+
110+
| Separator | Colour (when `markup=True`) | Meaning |
111+
|---|---|---|
112+
| `┃` / `┳` / `┻` | Yellow | Octal group boundary (every 3 bits from the right) |
113+
| `║` / `╥` / `╨` | Cyan | Hex group boundary (every 4 bits from the right) |
114+
| `┃` / `┳` / `┻` | Magenta | Both coincide (every 12 bits, LCM(3, 4)) |
115+
116+
Pass `markup=True` to get Rich markup colour tags suitable for use in a Textual `Static` widget.

‎docs/UnsignedIntTUI.md‎

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# UnsignedInt TUI
2+
3+
## Purpose
4+
5+
`data_structures/tui/unsigned_int_app.py` is an interactive terminal app for exploring how unsigned integers are represented in binary, hexadecimal, and octal. It lets you manipulate individual bits, shift and rotate, apply logical operations, and immediately see how every change ripples through all three representations simultaneously.
6+
7+
The visualization panel shows three aligned rows — binary, hex, and octal — at all times. Group boundaries in the binary row are colour-coded so you can see where octal groups (every 3 bits) and hex nibbles (every 4 bits) begin and end, including positions where both coincide (every 12 bits).
8+
9+
## Running the App
10+
11+
Install dependencies first:
12+
13+
```bash
14+
make install
15+
```
16+
17+
Run the TUI:
18+
19+
```bash
20+
make run-uint-app
21+
```
22+
23+
You can also run the module directly with an initial bit width:
24+
25+
```bash
26+
.venv/bin/python -m data_structures.tui.unsigned_int_app
27+
.venv/bin/python -m data_structures.tui.unsigned_int_app --size 16
28+
```
29+
30+
## Command-Line Options
31+
32+
### `--size 4|8|16|32|64`
33+
34+
Set the initial bit width (default: `8`). You can also change the width at runtime with `/size`.
35+
36+
## Layout
37+
38+
The interface has three parts:
39+
40+
1. **Visualization panel** (top) — the current value shown as aligned binary, hex, and octal box rows, plus a summary line with the decimal, binary, octal, and hex values.
41+
2. **Log panel** (middle) — records each command's result, overflow warnings, and execution time.
42+
3. **Input box** (bottom) — where commands are entered.
43+
44+
### Boundary colour key
45+
46+
In the binary row:
47+
48+
| Colour | Separator | Meaning |
49+
|---|---|---|
50+
| Yellow | `┃` | Octal group boundary (every 3 bits from the right) |
51+
| Cyan | `║` | Hex group boundary (every 4 bits from the right) |
52+
| Magenta | `┃` | Both coincide (LCM = 12 bits) |
53+
54+
## Commands
55+
56+
### Value
57+
58+
| Command | Description |
59+
|---|---|
60+
| `/set N` | Set the value; accepts decimal, `0b` binary, `0o` octal, or `0x` hex |
61+
| `/random` | Set a random value uniformly across the full bit range |
62+
| `/clear` | Reset all bits to zero |
63+
| `/size 4\|8\|16\|32\|64` | Change the bit width (resets value to zero) |
64+
65+
### Display
66+
67+
| Command | Description |
68+
|---|---|
69+
| `/show` | Display the value in all four bases |
70+
| `/dec` | Display decimal value |
71+
| `/bin` | Display binary value |
72+
| `/oct` | Display octal value |
73+
| `/hex` | Display hexadecimal value |
74+
75+
### Bit operations
76+
77+
| Command | Description |
78+
|---|---|
79+
| `/set-bit POS` | Set the bit at position `POS` to 1 (0 = LSB) |
80+
| `/reset-bit POS` | Set the bit at position `POS` to 0 |
81+
| `/toggle-bit POS` | Flip the bit at position `POS` |
82+
83+
### Shift, rotate, and logical
84+
85+
| Command | Description |
86+
|---|---|
87+
| `/shl N` | Shift left N bits; overflow is reported in yellow if any 1-bits are lost |
88+
| `/shr N` | Logical shift right N bits; zeros fill from the left |
89+
| `/rol N` | Rotate left N bits; bits wrap around, nothing is lost |
90+
| `/ror N` | Rotate right N bits; bits wrap around, nothing is lost |
91+
| `/not` | Bitwise complement (flip all bits within the current width) |
92+
| `/and CONST` | Bitwise AND with a constant |
93+
| `/or CONST` | Bitwise OR with a constant |
94+
| `/xor CONST` | Bitwise XOR with a constant |
95+
96+
Constants for `/and`, `/or`, `/xor` accept any Python-style prefix: `0b101010`, `0o17`, `0xFF`, or plain decimal. The constant must fit within the current bit width.
97+
98+
### Group operations
99+
100+
| Command | Description |
101+
|---|---|
102+
| `/set-octal GRP DIGIT` | Set the octal group at `GRP` (0 = rightmost) to `DIGIT` (0–7) |
103+
| `/set-hex GRP DIGIT` | Set the hex nibble at `GRP` (0 = rightmost) to `DIGIT` (0–15) |
104+
105+
### Session
106+
107+
| Command | Description |
108+
|---|---|
109+
| `/save PATH` | Save the current bit width and value to a JSON file |
110+
| `/load PATH` | Restore the bit width and value from a saved file |
111+
| `/undo` | Restore the previous state |
112+
| `/redo` | Reapply the most recently undone state |
113+
| `/help` | Show the command summary |
114+
| `/quit` or `Ctrl+D` | Exit the app |
115+
116+
## Typical Session
117+
118+
```text
119+
/size 8
120+
/set 0b10110101
121+
/show
122+
/set-bit 0
123+
/toggle-bit 7
124+
/not
125+
/shl 1
126+
/shr 1
127+
/rol 4
128+
/and 0xF0
129+
/or 0x0F
130+
/xor 0xAA
131+
/set-octal 0 7
132+
/set-hex 1 10
133+
/random
134+
/save /tmp/session.json
135+
/undo
136+
/redo
137+
/size 16
138+
/set 0xABCD
139+
/load /tmp/session.json
140+
/quit
141+
```
142+
143+
## Overflow Reporting
144+
145+
`/shl N` checks whether any 1-bits will be lost before shifting. If so, the log records a yellow warning showing how many bits were shifted out and their combined value:
146+
147+
```
148+
shl(1) → 0b01100100 dec=100
149+
overflow: 1 bit(s) shifted out — lost value 0b1
150+
```
151+
152+
Rotate operations (`/rol`, `/ror`) never produce overflow because bits wrap around.
153+
154+
## Errors and Edge Cases
155+
156+
- `/set` raises an error if the value exceeds the current bit width's maximum.
157+
- `/set-bit`, `/reset-bit`, `/toggle-bit` require a position in `[0, size-1]`.
158+
- `/set-octal` validates that the digit fits within the group; the MSB group may have a smaller maximum when phantom bits are present.
159+
- `/set-hex` validates that the digit is in `[0, 15]` and the group index is valid.
160+
- `/and`, `/or`, `/xor` require the constant to fit within the current bit width.
161+
- `/shl` and `/shr` with `N >= size` clear the value (with overflow reported for `/shl` if the value was non-zero).
162+
- `/load` restores both the saved bit width and the saved value, replacing the current configuration.
163+
- Any mutating command after `/undo` clears the redo history.
164+
165+
## Verification
166+
167+
The data structure and rendering logic are covered by `tests/test_unsigned_int.py` (60 tests). TUI-level construction, snapshot, and parser behaviour are covered by `tests/test_unsigned_int_app.py` (11 tests).

0 commit comments

Comments
 (0)