Implement compact integer encoding for a nine-byte telemetry buffer in Python 3.11 or later with pytest. Setup is complete when the existing test suite passes.
This kata complements Clean Code: Advanced TDD, Ep. 20 and Clean Code: Advanced TDD, Ep. 21.
This repository contains two exercises designed to improve your skills in test-driven development.
We will work on a telemetry system for a remote control car project. Bandwidth in the telemetry system is at a premium and you have been asked to implement a message protocol for communicating telemetry data.
Data is transmitted in a buffer (byte array). When integers are sent, the number of payload bytes is reduced by employing the protocol described below.
Each value should be represented in the smallest possible C integral type
(types of char and unsigned char are not included because the space savings
would be trivial):
| From | To | Type |
|---|---|---|
| 4,294,967,296 | 9,223,372,036,854,775,807 | long |
| 2,147,483,648 | 4,294,967,295 | unsigned int |
| 65,536 | 2,147,483,647 | int |
| 0 | 65,535 | unsigned short |
| -32,768 | -1 | short |
| -2,147,483,648 | -32,769 | int |
| -9,223,372,036,854,775,808 | -2,147,483,649 | long |
The value should be converted to the appropriate number of bytes for its assigned type. The complete internal 9-byte buffer comprises three parts:
- prefix byte: a byte indicating the number of payload bytes in the buffer;
- payload bytes: the bytes holding the integer;
- trailing bytes: the zero-fill bytes to complete the buffer.
To distinguish between signed and unsigned types, the protocol introduces a
little trick: for signed types, the prefix byte is 256 minus the number of
payload bytes in the buffer.
Implement the static method TelemetryBuffer.to_buffer() to encode an integer
value into a buffer.
# Type: unsigned short, bytes: 2, signed: no, prefix byte: 2TelemetryBuffer.to_buffer(5)
# => [0x2, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]# Type: int, bytes: 4, signed: yes, prefix byte: 256 - 4TelemetryBuffer.to_buffer(2_147_483_647)
# => [0xfc, 0xff, 0xff, 0xff, 0x7f, 0x0, 0x0, 0x0, 0x0]Tip
The BitConverter class provides a convenient way of converting integer
types to and from arrays of bytes.
Implement the static method TelemetryBuffer.from_buffer() to decode a
received buffer and return its integer value.
TelemetryBuffer.from_buffer([0xfc, 0xff, 0xff, 0xff, 0x7f, 0x0, 0x0, 0x0, 0x0])
# => 2_147_483_647If the prefix byte has an unexpected value, return 0.
Note
For type sizes, we assume a typical 64-bit system.
The C language provides several integer types, each with its own range of values. The system's storage width for each type determines its range:
| Type | Width | Minimum | Maximum |
|---|---|---|---|
char | 8 bits | -128 | +127 |
short | 16 bits | -32,768 | +32,767 |
int | 32 bits | -2,147,483,648 | +2,147,483,647 |
long | 64 bits | -9,223,372,036,854,775,808 | +9,223,372,036,854,775,807 |
unsigned char | 8 bits | 0 | +255 |
unsigned short | 16 bits | 0 | +65,535 |
unsigned int | 32 bits | 0 | +4,294,967,295 |
unsigned long | 64 bits | 0 | +18,446,744,073,709,551,615 |
Required:
Optional:
- GNU Make, for shorter commands. Every required task also
has a direct
uvcommand.
You do not need to install Python or pytest separately. uv installs a compatible Python version
and the locked project dependencies when needed.
Clone the repository:
git clone https://github.com/Coding-Cuddles/hyper-optimized-telemetry-python-kata.gitEnter the repository directory:
cd hyper-optimized-telemetry-python-kataRun the existing tests. Use Make when it is installed:
make testOtherwise, run pytest through
uvdirectly:uv run pytestThe first run may install Python and the project dependencies. Setup is complete when pytest reports
65 passed.If the command fails with
uv: command not found, install uv and repeat this step.
Implement TelemetryBuffer.to_buffer() and TelemetryBuffer.from_buffer() in
telemetry_buffer.py. bit_converter.py contains the integer conversion helpers.
Run the tests after each change. Use Make when it is installed:
make testOtherwise, run pytest through uv directly:
uv run pytestContinue when the test run passes.
Make is optional. Run make or make help to list these commands in the terminal.
| Command | Result |
|---|---|
make all | Run the test suite |
make help | Show the command reference |
make test | Run the test suite |
make format | Format tracked Python files |
make format-check | Check formatting without changing files |
make clean | Remove generated caches |