A minimal Python 3.11+ CLI package and reusable library function for converting semicolon-separated CSV input into grouped customer kickback rows and per-currency totals.
Project description
KickbackCalculator by packr.build
A tiny Python CLI and library for turning semicolon CSV rows into grouped kickback totals.
Table of Contents
- Why this package
- Features
- Requirements
- Installation
- Configuration
- Quick start
- Usage
- Testing
- Input and output rules
- Project layout
Why this package
KickbackCalculator is a minimal Python package for a very specific job: take semicolon-separated CSV input, group rows by currency, customer, and kickback percent, then emit a clean CSV report with per-group kickbacks and per-currency totals.
It is designed as both a reusable library and a command-line tool. That means you can call calculate_kickbacks(csv_text) directly in tests or scripts, or run the kickback-calculator command against files from your shell.
The implementation stays intentionally small and standard-library only. There is no web framework, no database, no external CSV dependency, and no runtime package beyond Python itself.
Features
- Library API:
kickbackcalculator.calculate_kickbacks(csv_text: str) -> str - CLI command:
kickback-calculator input.csv -o output.csv - Stdout fallback when
-o/--outputis omitted - UTF-8 input and output by default, with
--encodingsupport - Semicolon-delimited CSV parsing via the Python standard library
- Skips the first row as a header
- Ignores blank rows and rows with fewer than 11 columns
- Groups by currency, customer, and kickback percent
- Uses
decimal.Decimalinternally for money-like calculations - Emits per-currency
TOTALrows - Formats output with two decimals, decimal comma, and space thousands separators
- Deterministic output ordering
Requirements
- Python >=3.11 (Python 3.11 and 3.12 supported)
- Standard library only at runtime
pytest ^8.0for development and testing- No framework required
Installation
KickbackCalculator is published to PyPI as jake142-kickbackcalculator.
Install from PyPI
uv pip install jake142-kickbackcalculator
Development
If you cloned the repository, install the project and its dev dependencies with:
uv sync
Configuration
KickbackCalculator does not use environment variables or config keys.
- Environment variables: none
- Config keys: none
Quick start
Create a small input file and run the CLI:
cat > input.csv <<'CSV'
ignored;header;row;for;compatibility;only;not;used;here;0;0
x;y;Alice;z;z;z;z;z;EUR;100,00;10
CSV
kickback-calculator input.csv -o output.csv
cat output.csv
Expected output:
customer;kickback;currency
Alice;10,00;EUR
TOTAL;10,00;EUR
Usage
Python API
Use the public function when you want to convert CSV text in memory:
from kickbackcalculator import calculate_kickbacks
csv_text = """ignored;header;row;for;compatibility;only;not;used;here;0;0
x;y;Alice;z;z;z;z;z;EUR;100,00;10
"""
result = calculate_kickbacks(csv_text)
print(result)
CLI
Convert a file and write the result to another file:
kickback-calculator input.csv -o output.csv
Write to stdout instead:
kickback-calculator input.csv
Read and write using a different encoding if needed:
kickback-calculator input.csv -o output.csv --encoding latin-1
Input and output rules
Input format
- Delimiter: semicolon (
;) - The first row is always treated as a header and skipped
- Blank rows are ignored
- Rows with fewer than 11 columns are ignored
- Fixed zero-based columns:
- customer: column 2
- currency: column 8
- amount: column 9
- kickback percent: column 10
Parsing rules
- Amount and kickback percent values are trimmed before parsing
- Decimal commas are normalized to decimal points before conversion
- Malformed numeric rows are skipped by default
- The library does not print warnings
- The CLI reports user/input errors concisely on stderr
Grouping and totals
Rows are grouped by:
- currency
- customer
- kickback percent
For each group, kickback is calculated as:
summed amount * percent / 100
The output then appends one TOTAL row per currency.
Output format
- Header:
customer;kickback;currency - Rows:
{customer};{formatted_kickback};{currency} - Totals:
TOTAL;{formatted_total};{currency} - Numbers use exactly two decimals
- Decimal comma is used in output
- A space is used as the thousands separator
- Output ends with a trailing newline
Example formatting:
1234.5->1 234,5010->10,00
Testing
Run the test suite with uv:
uv run pytest
The tests cover the public library API and the CLI behavior, including file output and stdout fallback. No external services are called.
Project layout
The package uses a small src/ layout:
pyproject.toml
README.md
src/kickbackcalculator/__init__.py
src/kickbackcalculator/core.py
src/kickbackcalculator/cli.py
tests/test_core.py
tests/test_cli.py
The public import path is kickbackcalculator, and the console script is kickback-calculator.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jake142_kickbackcalculator-0.1.0.tar.gz.
File metadata
- Download URL: jake142_kickbackcalculator-0.1.0.tar.gz
- Upload date:
- Size: 6.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef3abeebcb8baff03ecbe6777a37c956684a2b70ea5c328d1f026b4f852fa72c
|
|
| MD5 |
4f2377c1ed42c3704f43c67aac04df2a
|
|
| BLAKE2b-256 |
b316d2d9da582467e5aa0006057eb27e295b5e97f0ad841760ac0eb3b2aee469
|
File details
Details for the file jake142_kickbackcalculator-0.1.0-py3-none-any.whl.
File metadata
- Download URL: jake142_kickbackcalculator-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c079061f683ed2d66d3e84d383c8774211e7988ae49dfe7e6c5df23629d1f23
|
|
| MD5 |
72d09138e1dd5b809d9cbbf22a32b060
|
|
| BLAKE2b-256 |
99f0bbaa5d6a0a58fea7f60eb5d52507caf152eec76e58efb969d23e9d0bc2b3
|