AbleVLabs tools: kami, a machine-learning tutor that builds models and explains them in plain English; lana, a weighted record-comparison engine that weighs records attribute by attribute and tells you which wins; and vita, a resistance-training coach that estimates reps in reserve and tracks fatigue, powered by the Vivanco Proximity-to-Failure Model.
Project description
ablevlabs
Small, friendly Python tools by AbleVLabs - each one takes something that usually feels intimidating and makes it feel easy.
Two tools live in the package today: kami, a machine-learning tutor that builds your model and explains what it means in plain English, and lana, a weighted matchup engine that decides which of two or more records comes out on top.
kami - your machine-learning tutor
You bring the data. kami brings the patience.
Most machine-learning tools hand you a number and walk away. kami stays. It cleans your messy spreadsheet, trains a solid model, quietly catches the mistakes that trip up every beginner - and then it turns around and explains the whole thing to you in plain English, like a good tutor leaning over your shoulder.
Three lines:
from ablevlabs import kami
df = kami.load("houses.csv") # read it
df = kami.clean(df) # tidy it
result = kami.train(df, target="price") # learn from it
...and kami talks back:
======================================================================
WHAT KAMI FOUND
======================================================================
Question Can 'price' be predicted from the other columns?
Answer Yes - and quite well.
How good R2 = 0.97. In plain terms, the model explains about 97% of
why 'price' changes from one row to the next.
Typical miss the model is usually off by about 17324 (e.g. predicted
159179, actual 173500).
Verdict [*****] Excellent
Confidence Moderate - 60 unseen test rows.
What we learned:
- 'size_sqft' and 'age_years' look most related to 'price' (related to,
not necessarily the cause).
- There's real signal here - your columns do help predict 'price'.
Do next kami.feature_importance(result)
======================================================================
No jargon to google. No charts to squint at. Just the four things that matter: what's the question, how good is the answer, how much should you trust it, and what to do next.
lana - Logical Attribute Node Aligner
Point lana at two records and it weighs them attribute by attribute, then
tells you which one wins. It works on anything with comparable fields - job
candidates, products, ML model runs, vehicles, portfolios, game characters.
Unlike a diff tool (which tells you what changed between two versions of the
same thing), lana is a matchup tool: it relates two distinct records and
renders a weighted verdict based on the fields you decide matter most.
Install
pip install ablevlabs
Optional, for the DataFrame export:
pip install "ablevlabs[pandas]"
Quick start
from ablevlabs import lana
laptop_a = {"name": "Aero 14", "price": 1200, "ram_gb": 16, "battery_hrs": 10}
laptop_b = {"name": "Vortex 15", "price": 1500, "ram_gb": 32, "battery_hrs": 8}
result = lana.compare(
laptop_a, laptop_b,
priority={"ram_gb": 5, "battery_hrs": 2, "price": 2}, # 1-5: how much each matters
lower_better=["price"], # cheaper wins
)
lana.show(result)
Aero 14 vs Vortex 15
--------------------------------------------------
battery_hrs 10 <-- 8 (priority 2)
name Aero 14 != Vortex 15
price 1200 <-- 1500 (priority 2)
ram_gb 16 --> 32 (priority 5)
--------------------------------------------------
OVERALL: Vortex 15 wins (Aero 14 44.4% / Vortex 15 55.6%)
The Aero wins two fields (battery, price) - but they're lower priority. The
Vortex wins only RAM, but RAM is rated 5, and that one high-priority win
carries the verdict. That is the whole point of lana.
How the verdict works
Each field you list in priority is rated 1-5 (1 = barely matters,
5 = matters most). Whichever record wins a field takes its full priority
points; a tie splits them. The record with more total points wins overall.
The per-field margins are shown as delta, but they do not secretly sway
the verdict - winning a field is winning a field.
compare() options
| Argument | What it does |
|---|---|
a, b |
The two records (dicts). Required. |
name_a, name_b |
Labels for the output. If omitted, lana reads a name/model/id field, else uses A/B. |
priority |
{field: 1-5} - how much each numeric field counts toward the winner. |
lower_better |
List of fields where a smaller number wins (price, latency, weight). |
aliases |
{variant: canonical} to reconcile differing field names between records. |
Ranking many items - rank()
compare() is head-to-head. To rank three or more records into a
leaderboard, use rank():
from ablevlabs import lana
fighters = [
{"name": "Goku", "power_level": 9100, "attack": 22, "defense": 14},
{"name": "Vegeta", "power_level": 9000, "attack": 25, "defense": 10},
{"name": "Frieza", "power_level": 10500, "attack": 24, "defense": 16},
]
board = lana.rank(fighters, priority={"power_level": 5, "attack": 4, "defense": 3})
lana.show(board)
LEADERBOARD
------------------------------------------
* 1. Frieza 10.0 pts
2. Vegeta 4.33 pts
3. Goku 1.67 pts
Pass a list of records (names are read from each record's
name/model/id field) or a {name: record} dict. Scoring is
rank-weighted: on each field, items earn points by placement - best gets
the field's full priority, worst gets 0, evenly spaced; ties split the
average. For exactly two items, rank() matches compare(). If you omit
priority, every numeric field shared by all items counts equally.
All the exporters below (show, to_json, to_csv, to_markdown,
to_df, save) work on rank() results too.
Getting the result out
compare() returns a plain dict. From there:
lana.show(result) # readable scorecard (terminal)
lana.to_json(result) # JSON string
lana.to_csv(result) # CSV string (Excel / Sheets)
lana.to_markdown(result) # Markdown table (docs / GitHub)
lana.to_df(result) # pandas DataFrame (needs pandas)
lana.save(result, "out.json") # format chosen from the extension
lana.save(result, "out.csv")
lana.save(result, "out.md")
Nested fields
If a field holds a dict, lana compares inside it - shared keys get a winner,
and keys unique to one side are flagged:
a = {"stats": {"hp": 100, "atk": 20}}
b = {"stats": {"hp": 80, "atk": 30, "def": 5}}
lana.show(lana.compare(a, b, "A", "B"))
Guardrails
priorityvalues must be 1-5; anything else raises a clearValueError.- Misspelled
priority/lower_betterfield names emit a warning instead of silently doing nothing. - Booleans are treated as text, not numbers (so
True/Falsearen't scored as1/0).
License
MIT (c) 2026 Carlos Able Vivanco / AbleVLabs - see LICENSE.
Project details
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 ablevlabs-0.6.0.tar.gz.
File metadata
- Download URL: ablevlabs-0.6.0.tar.gz
- Upload date:
- Size: 108.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c8369d3ea0495a99722e93f275345f7d316080187d94195ccc6cc747bff04c3
|
|
| MD5 |
da9f673e1a90b623b892075d526f90e2
|
|
| BLAKE2b-256 |
38c99c4866a4a13e5d6c75441a7e1c5197fe4893855988dd5429a337c7096e6d
|
File details
Details for the file ablevlabs-0.6.0-py3-none-any.whl.
File metadata
- Download URL: ablevlabs-0.6.0-py3-none-any.whl
- Upload date:
- Size: 87.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6bac0fcb3428a55ce38bf3280ee1f8268d8559b6863059f64231583351596417
|
|
| MD5 |
06f286fc7ae14ccf6d4c2f38b710fb56
|
|
| BLAKE2b-256 |
8d705b2d1ab39876943b0fc5e32a5b41d341f9da8db1c2db86ce72716d2eea3f
|