gridcalc
A programmable terminal spreadsheet for developers and technical users, with Excel-ish formulas, Python escape hatches, XLSX interop, goal seek, and LP/MIP solving.
Inspired by Serge Zaitsev's kalk.
pip install gridcalc
gridcalc budget.json
What it gives you
- Excel-compatible formulas (
=IF(A1>=B1, A1*0.05, 0)) and arrays (=SUM(A1:A10 * B1:B10)) without leaving the terminal. - Multi-sheet workbooks with cross-sheet refs (
=Sheet2!A1) and a proper dep graph. - Three formula modes per file: strict Excel, Excel-plus-
py.*, or full Pythonevalwith numpy/pandas. - xlsx interop via OpenXLSX C++ -- read every sheet's formulas + values; export with cached values.
- Linear, mixed-integer & quadratic programming built in via HiGHS --
:opt max B4 vars A4:A5 st D4:D6solves from cells in the sheet, with shadow prices, infeasibility diagnosis, and RHS sweeps. Models persist in the workbook. - Goal-seek --
:goal B10 = 100 by A1adjusts a variable so a formula hits a target value. - Vim-style command line (
:w,:e,:q,/search,y/p, visual selection, undo), with system-clipboard copy/paste -- yank pushes values as TSV, paste pulls TSV in from other apps.
Try it on the provided examples:
gridcalc example_excel.json # sales report, named ranges, IF/MATCH
gridcalc example_hybrid.json # progressive tax via py.* + aggregations
gridcalc example.json # PYTHON: numpy/pandas, list-comprehensions
gridcalc example_multisheet.json # 3-sheet budget, cross-sheet formulas
gridcalc example_lp.json # LP/MIP demo -- type :opt to solve
gridcalc example_goal.json # goal-seek demo -- :goal B1 = 11 by A1
Install
Two options:
pip install gridcalc # core: zero third-party runtime deps
pip install 'gridcalc[extras]' # adds numpy, pandas, pygments
Or with uv: uv tool install 'gridcalc[extras]'.
The core install has zero third-party runtime dependencies on
Linux and macOS -- the full 300+ Excel function library (statistical
distributions, financial functions, LINEST/TREND regression, ...)
works on stdlib alone. (The 3.10 wheel pulls tomli for config-file
parsing; 3.11+ uses stdlib tomllib. On Windows only, windows-curses
is pulled in because curses is not in the Windows stdlib.)
The [extras] bundle enables, all at once:
np.array(...)in formulas; LAPACK-backed solvers; fasterLINEST.pd.DataFrame(...),:pd load/save, DataFrame cell display.- Pygments syntax-highlight in the load-time trust prompt.
Quick tour
Cells hold a number, a label (any non-=-prefixed string), or a formula
(prefixed with =). Arrow keys move; Enter commits and moves down;
Tab commits and moves right.
A B C
1 Revenue Cost Margin
2 1000 600 =(A2-B2)/A2*100 <- formula
3 1200 700 =(A3-B3)/A3*100
4 Total =SUM(B2:B3) =AVG(C2:C3)
Press : for the command line. The basics:
| Command | Purpose |
|---|---|
:w [file] |
save (extension .json or .xlsx) |
:o file |
open |
:q, :q! |
quit, force-quit |
:e |
edit the workbook's Python code block in $EDITOR |
u, Ctrl-R |
undo / redo |
v |
enter visual selection mode (then y yanks, p pastes) |
/text |
search (n/N to cycle matches) |
> |
go to a named cell (e.g. > AA10) |
A full command reference lives in the Reference section below.
Modes
Each workbook has one of three evaluation modes, controlling which formulas parse and what's reachable from them:
| Mode | Grammar | Python escape hatch | Sandbox | Use case |
|---|---|---|---|---|
EXCEL |
strict Excel | none | not needed (no eval) |
xlsx interop, untrusted files |
HYBRID |
Excel + py.* |
code-block functions reachable as py.foo(...) |
code blocks only | most new sheets |
PYTHON |
Python eval() |
full Python expressions | full AST sandbox | numpy/pandas-heavy work |
Switch with :mode <name> -- the change is refused if any current
formula doesn't parse in the target mode. Files without an explicit
mode field load as PYTHON (back-compat). :xlsx load switches to
EXCEL automatically.
Formulas
=A1 + B1 * 2 arithmetic, Excel precedence
=(A1 + A2) / 2 grouping
=2^10 exponent (PYTHON: ** also works)
=50% percent postfix -> 0.5
="hello " & A1 string concat
=IF(A1 > 0, "pos", "neg") conditionals
=IFERROR(B1/C1, 0) error catch -- #DIV/0!, #VALUE!, #N/A, ...
=SUM(A1:A10) range -> 1D array
=SUM(A1:A3 * B1:B3) element-wise array arithmetic
=LET(x, SUM(A1:A9), x/COUNT(A1:A9)) local bindings -- compute once, reuse
=FILTER(A1:A9, B1:B9 > 0) dynamic arrays: FILTER/SORT/UNIQUE
=SUM(revenue) named range
=py.margin(A1, B1) HYBRID: call a code-block function
Excel error values (#DIV/0!, #N/A, #NAME?, #REF!, #VALUE!,
#NUM!, #NULL!) propagate through arithmetic and are catchable with
IFERROR/IFNA.
Built-in functions (always available): SUM, AVG, MIN, MAX,
COUNT, ABS, SQRT, INT, plus everything in math (sin, cos,
log, pi, e, ...).
Excel-compatible library (auto-loaded in EXCEL/HYBRID): IF,
IFERROR, AND, OR, NOT, ROUND, AVERAGE, MEDIAN, SUMIF,
COUNTIF, AVERAGEIF, LET, VLOOKUP, HLOOKUP, XLOOKUP, XMATCH,
INDEX, MATCH, FILTER, SORT, UNIQUE, SEQUENCE, CONCATENATE,
LEFT, RIGHT, MID, LEN, TRIM, UPPER, LOWER, SUBSTITUTE,
and 280+ others. Dynamic-array functions return whole rows/columns and
compose (=INDEX(SORT(A1:B9), 1, 2)).
PYTHON-only extras: the math module, Python builtins (sum,
min, max, abs, len), list comprehensions, and -- when the
relevant extras are installed -- np.array(...), np.linalg, matrix
multiply (@), and pd.DataFrame(...).
Named ranges & custom functions
:name revenue A1:A12 Define a named range (workbook-global)
:names List
:unname revenue Remove
Used directly in formulas: =SUM(revenue), =MAX(revenue - costs).
Open the per-workbook Python code block with :e. Anything defined there
becomes callable from formulas:
def margin(rev, cost):
return (rev - cost) / rev * 100
In HYBRID: =py.margin(A1, B1). In PYTHON: =margin(A1, B1).
EXCEL mode forbids code blocks entirely.
Cell references
$A$1 fixes both; $A1 fixes the column; A$1 fixes the row.
References adjust automatically on insert/delete/replicate.
Multi-sheet workbooks
:sheet List sheets (active marked *)
:sheet Inputs Switch by name
:sheet 1 Switch by zero-based index
:sheet add Outputs Append (does not switch)
:sheet del Tmp Remove (refused if last sheet)
:sheet rename Old New Rename, rewriting `Old!` prefixes in formulas
:sheet move Inputs 0 Reorder
Reference cells on other sheets with Sheet!cell:
=Sheet2!A1
=SUM(Sheet2!A1:A10)
=Sheet1!A1 + Sheet2!B1
The dep graph is keyed on (sheet, col, row) so cross-sheet recalc
works transparently. Cross-sheet ranges (Sheet1!A1:Sheet2!B5) are
not supported (Excel doesn't either).
Optimization
:opt solves linear and mixed-integer programs defined by cells in the
active sheet, via a vendored copy of HiGHS (MIT).
Models are workbook-persistent: define once, save the file, re-run
on reopen.
:opt Run the saved 'default' model
:opt max|min (with a visual selection) Infer the model from the selected block
:opt max|min <cell> vars <cells> st <cells> [bounds <spec>] [int <cells>] [bin <cells>]
Solve inline AND save as 'default'
:opt def <name> max|min <cell> ... Save under <name>; does not execute
:opt run [<name>] Execute a saved model
:opt sens [<name>] [into[!] <cell>] Sensitivity report -- paged, or written into cells
:opt sweep <cell> <lo>:<hi> [steps] [<name>] Re-solve across a range of RHS values
:opt list List saved models
:opt undef <name> Remove a saved model
The model is sheet-resident: an objective formula in one cell,
decision-variable cells holding values, and constraint cells holding
comparison formulas like =A1+A2<=10. The constraint cells keep
evaluating during recalc, so the sheet shows live feasibility
(TRUE/FALSE) before and after the solve.
A worked example (also at examples/example_lp.json):
| A | B | C | D | |
|---|---|---|---|---|
| 3 | Decision | Objective | Constraints | |
| 4 | 0 |
=3*A4+5*A5 |
=A4<=4 |
|
| 5 | 0 |
=2*A5<=12 |
||
| 6 | =3*A4+2*A5<=18 |
:opt max B4 vars A4:A5 st D4:D6
Status bar shows opt: OPTIMAL obj=36; A4 and A5 become 2.0
and 6.0; u rolls back.
Quadratic objectives
Objectives may contain squared decision variables and cross terms --
=(A1-3)*(A1-3), =A1^2 + A2^2, =A1*A2, =2*A1^2 + 3*A1 -- which
covers least-squares fitting, quadratic cost curves, target tracking,
and covariance-style objectives.
:opt min C1 vars A1:A2 st D1
opt: OPTIMAL obj=0 (quadratic)
Solved exactly as a QP; there is no approximation and no accuracy knob.
The objective must be convex for a minimisation (or concave for a maximisation). Otherwise the optimum sits at a corner of the feasible region, which is a different and much harder problem, and gridcalc refuses it rather than returning a plausible wrong answer:
opt: objective is not convex, so it has no interior minimum -- ...
Convexity is checked directly on the Hessian (symmetric elimination, no numpy required), so the message names the real problem rather than surfacing a solver failure.
Sensitivity analysis and infeasibility diagnosis are withheld for quadratic models: their duals do not carry the shadow-price reading the report describes. Same call as for MIPs. Integer variables cannot be combined with a quadratic objective.
Inferring the model from a selection
The layout above already says what the model is. Select the block with
v, then type :opt max (or min) and the components are read off it:
| Cell contents | Read as |
|---|---|
formula rooted in a comparison (=A4<=4) |
a constraint |
any other formula (=3*A4+5*A5) |
the objective |
| a plain number | a decision variable |
| labels, blanks | ignored |
For the sheet above, selecting A3:D6 and typing :opt max is
equivalent to :opt max B4 vars A4:A5 st D4:D6.
Exactly one non-comparison formula must be in the selection; more than one is ambiguous and reports the candidates so you can narrow it. Blanks are deliberately not treated as decision variables -- a selected rectangle is mostly whitespace, and promoting every gap to a variable would build a model you never described.
The inferred model is saved as default, so the block only has to be
selected once: plain :opt re-runs it afterwards, and :w persists it.
Clauses (any order after st):
bounds A1=lo:hi, B2=lo:hi-- per-variable bounds.lo/hiacceptinf,+inf,-inf. Default is[0, +inf).int <cells>-- decision variables are integer-valued (branch-and-bound).bin <cells>-- decision variables are binary ({0,1}); bounds clamped to[0,1].
Cell lists everywhere accept ranges (A1:A5), comma-separated refs
(A1,A3,B5), or a mix.
Saved models live under "models": {<name>: ...} in the JSON file
and round-trip verbatim (the spec strings the user typed are stored,
not pre-resolved coords).
Sensitivity analysis
:opt sens [<name>] solves the model and then opens a report answering
the question a bare optimum does not: what would change the answer?
Variable cells
cell value reduced obj coef coef from coef till
A4 2 0 3 0 7.5
A5 6 0 5 2 inf
Constraints (* = binding)
cell shadow rhs activity slack rhs from rhs till
D4 0 4 2 2 -inf inf
* D5 1.5 12 12 0 6 18
* D6 1 18 18 0 12 24
- shadow price -- objective gain per extra unit of right-hand side.
D5is worth 1.5 per unit andD6is worth 1, so buying more of theD5resource pays better.D4has slack and is worth nothing. - rhs from/till -- the range over which that shadow price holds. Past it the optimal basis changes and the price no longer applies.
- reduced cost -- for a variable stuck at a bound, how much the objective would move per unit if it were forced in. Zero for any variable already active.
- coef from/till -- how far an objective coefficient can move before the optimal mix changes.
*-- the constraint is binding (zero slack). Derived from slack rather than from a non-zero shadow price, since a degenerate optimum can bind at a price of zero.
Sensitivity is not reported for integer or binary models: a
branch-and-bound dual describes one LP relaxation rather than the
integer problem, so there is no valid shadow-price reading. :opt sens
on such a model still solves it and says why the report is absent.
Writing the report into cells
:opt sens into <cell> writes the report into the sheet instead of
paging it, anchored at the given cell:
:opt sens into F1
The numbers land as values, not text, so downstream formulas can reference them:
F13: =G7*100 -> 150 (G7 holds a shadow price of 1.5)
That is the reason to write into cells rather than read a report: the results become part of the sheet's own computation. Re-running the command refreshes the block in place.
Layout, anchored at the target cell -- a blank row separates the two tables, and positions are stable so formulas keep working across re-runs:
Variables value reduced obj coef coef from coef till
<one row per decision variable>
Constraints shadow rhs activity slack rhs from rhs till
<one row per constraint>
The write refuses to overwrite non-empty cells and names the first
one blocking it; use into! to overwrite anyway. The whole rectangle
belongs to the report, including the separator row, so stray values
cannot end up sitting inside it. The write is a single undo step.
Unbounded ranging values are written as infinities and display as
inf / -inf.
Parametric sweep
A shadow price answers what is the next unit worth. It cannot answer
how much more should I buy, because it stops being valid at the edge
of its rhs from/till range. :opt sweep re-solves across a range and
shows where the value changes:
:opt sweep D5 6:24 9
D5 right-hand side from 6 to 24 (* = marginal value changed)
rhs objective delta shadow status
6 27 -- 2.5
* 8 30 3 1.5
12 36 3 1.5
18 45 3 1.5
* 20 45 0 0
24 45 0 0
Read that as: capacity is worth 1.5 per unit up to 18, and nothing at all beyond it. Buy up to 18.
steps is the number of intervals (default 10), so the report has
steps + 1 rows spanning the range inclusive. The optional trailing
name selects a saved model other than default.
The sweep is read-only -- each point substitutes the right-hand side internally rather than editing the constraint formula, so the sheet is untouched and there is nothing to undo. Points where the model becomes infeasible or unbounded are kept in the series with their status, since learning that a level is unattainable answers the question too.
Available programmatically as opt.sweep(...), and the underlying
substitution as solve(rhs_override={cell: value}) for one-off what-if
questions.
Infeasibility diagnosis
An infeasible model reports which constraints contradict each other, not just that the model failed:
opt: INFEASIBLE conflict: D1, D2 (2 of 5 constraints)
The named cells are an irreducible conflicting set: together they are still infeasible, and dropping any one of them makes the model solvable again. Constraints that merely happen to be present are not listed, which is the whole point -- narrowing 30 constraints to the 2 that actually fight is the difference between a dead end and a fix.
Found by a deletion filter (one solve per constraint, on the failure path only), so a three-way conflict with no contradictory pair is reported correctly where a pairwise check would miss it. Variable bounds are held fixed rather than dropped, so a constraint that contradicts its variable's bounds is reported as the conflict.
This runs automatically on every infeasible :opt; there is no
separate command.
Unboundedness diagnosis
The mirror case. An unbounded model names the variable that can run away, rather than only reporting that no optimum exists:
opt: UNBOUNDED unbounded: A5 -- add an upper bound or a constraint
A variable is reported when the constraints permit it to move without limit in the direction that improves the objective -- established by re-solving over the same feasible region with that variable as the objective, so it is an exact answer rather than a large-number heuristic. Variables with no objective coefficient are never blamed: moving them cannot change the objective, so they are not the cause even when they are themselves unbounded.
Like the infeasibility case, this runs automatically.
Programmatic access:
from gridcalc.engine import Grid
from gridcalc.opt import solve
g = Grid()
g.jsonload("examples/example_lp.json")
g.recalc()
r = solve(g, objective_cell=(1, 3), decision_vars=[(0, 3), (0, 4)],
constraint_cells=[(3, 3), (3, 4), (3, 5)], maximize=True)
print(r.status_name, r.objective, r.values)
Goal-seek
For 1-D what-if ("what input makes this output equal X?"), use :goal:
:goal <formula_cell> = <target> by <var_cell> [in <lo>:<hi>]
:goal B10 = 100 by A1 auto-bracket from A1's current value
:goal B10 = 0 by A1 in -50:50 explicit search bracket
Uses bisection over Grid.recalc(); converges in milliseconds at
spreadsheet scale. The variable cell must hold a value (not a formula).
On success the variable cell is overwritten; u rolls back. Unlike
:opt, goal-seek isn't persisted -- the three args fit on one line, so
retyping is faster than naming.
Formatting
:f b Toggle bold (also Ctrl-B)
:f u Toggle underline (also Ctrl-U)
:f i Toggle italic
:f bi Combine: bold + italic
:f $ Dollar (2 decimal places)
:f % Percentage (value*100, 2 decimals)
:f I Integer (truncate)
:f * Bar chart (asterisks proportional to value)
:f L | R | G | D Left / right / general / use-global-format
:f ,.2f Any Python format spec: 1,234.50
:f .1% 15.7%
:f .2e 1.23e+04
:gf <fmt> sets the workbook-wide default format. :width <n> sets
column width (4-40). Labels longer than the column width spill into
adjacent empty cells, Excel-style.
Import / export
| Command | Reads | Writes | Notes |
|---|---|---|---|
:csv save/load |
CSV | CSV | Plain text, fast |
:xlsx save/load |
.xlsx formulas + values |
EXCEL-mode: formulas + cached values; other modes: values only | :xlsx load switches to EXCEL |
:pd save/load |
CSV/TSV/Excel/JSON/Parquet | same | Uses pandas; row 1 as headers |
:xlsx load translates Excel formulas into gridcalc's EXCEL grammar
and reads every sheet. INDIRECT and 3D ranges (Sheet1:Sheet3!A1:B2)
are deliberately unsupported -- they'd defeat the static dep graph.
Functions outside the auto-loaded library produce #NAME?.
File format
JSON, v2. v1 (single sheet, top-level cells) still loads.
{
"version": 2,
"mode": "HYBRID",
"active": "Inputs",
"code": "def margin(rev, cost):\n return (rev - cost) / rev * 100\n",
"names": { "revenue": "A1:A12", "costs": "B1:B12" },
"models": { "default": { "sense": "max", "objective": "B4",
"vars": "A4:A5", "constraints": "D4:D6" } },
"sheets": [
{ "name": "Inputs", "cells": [["Rev","Cost"],[1000,600],[1200,700]] },
{ "name": "Summary","cells": [["Total","=SUM(Inputs!A2:A3)"]] }
],
"format": { "width": 10 }
}
- mode:
"EXCEL"|"HYBRID"|"PYTHON". Absent →PYTHON. - sheets (v2): each is
{name, cells}with a 2Dcellsarray. - active (v2): name of the sheet to focus on load.
- names: workbook-global named ranges (sheet-relative when used).
- models: persisted LP/MIP definitions (see Optimization).
- code: per-workbook Python module string, editable via
:e.
Configuration
Optional gridcalc.toml (lookup: $PWD then $XDG_CONFIG_HOME/gridcalc/):
sandbox = true # AST validation of formulas + code blocks
width = 12 # default column width
format = "G" # default cell format
[keys.grid]
next_sheet = ["Tab", "F4"]
prev_sheet = ["S-Tab", "F3"]
cursor_left = ["Left", "h"]
cursor_down = ["Down", "j"]
cursor_up = ["Up", "k"]
cursor_right= ["Right", "l"]
Every TUI context (grid, entry, visual, cmdline, search) is
rebindable. User bindings fire before the hardcoded fallback chain,
so Tab → next_sheet replaces the default cursor-right meaning. See
docs/keybindings.md for the keyspec grammar
(Tab, S-Tab, C-x, C-Right, F3, ...) and rejected combinations.
Command reference
File :w [file] :wq :q :q! :o file :e
Edit :b :clear :dr :dc :ir :ic :m :r
:sort [col] [desc] yank/paste: y/p (syncs system clipboard)
undo/redo: u / Ctrl-R (aliases: Ctrl-Z / Ctrl-Y)
Format :f <spec> :gf <spec> :width <n> Ctrl-B / Ctrl-U
Search /pattern n N
Sheets :sheet [name|N|add|del|rename|move]
Names :name <n> [range] :names :unname <n>
Modes :mode [excel|hybrid|python]
Import/export :csv save/load :xlsx save/load :pd save/load
Optimization :opt :opt def :opt run :opt sens :opt sweep
:opt list :opt undef
:goal <cell> = <target> by <cell> [in <lo>:<hi>]
View :view E :tv/:th/:tb/:tn (lock title rows/cols)
Limitations
INDIRECTis unsupported (would defeat the static dep graph).LAMBDAand its higher-order helpers (MAP,REDUCE,BYROW, ...) are unsupported;LETis supported. Dynamic-array results are packed into their origin cell rather than spilling into neighbours.- xlsx export of formulas is EXCEL-mode only -- PYTHON/HYBRID
syntax (
**, list comprehensions,py.*) isn't strict Excel. - 3D range refs (
Sheet1:Sheet3!A1:B2) are unsupported (returnsnan). Workaround: expand manually with+. - Cross-sheet ranges (
Sheet1!A1:Sheet2!B5) are rejected at parse time -- Excel doesn't support them either. - xlsx dates and styles aren't read or written; date serials arrive as floats.
Development
make build # rebuild the C++ extensions (_core, _opt)
make test # unit tests
make test-tty # PTY-driven curses integration tests (slow, requires xterm-256color)
make lint # ruff check
make typecheck # mypy
make qa # lint + typecheck + test + format
make wheel # cpXX-cpXX wheel for current Python
make wheel-abi3 # single cp312-abi3 wheel (Python>=3.12)
make sdist # source distribution
make publish # upload to PyPI (after make check)
The abi3 build is gated on GRIDCALC_STABLE_ABI=ON (CMake) +
wheel.py-api=cp312 (scikit-build-core). Per-version wheels and the
abi3 wheel have separate CI workflows under .github/workflows/.
Prior Art
- sc-im: A ncurses spreadsheet program for terminal
- sheets: A terminal based spreadsheet tool
- rustxl: A fast, keyboard-driven spreadsheet with vim-style navigation and Excel-compatible formulas.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
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 gridcalc-0.3.0.tar.gz.
File metadata
- Download URL: gridcalc-0.3.0.tar.gz
- Upload date:
- Size: 2.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d0e7eb55fe096c88d2cd030bfe62c0f3c484e6af25c3af1f2edfbeea6770bee
|
|
| MD5 |
bef3bfd2973f03674d58af91053bbc96
|
|
| BLAKE2b-256 |
2ebf9dc644a5f269a8abebc48b2d108b75dd64bc8d58f2717fdab4396997676d
|
File details
Details for the file gridcalc-0.3.0-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3bdab7f01c32e17cdc366adeaf062c6a67c6cd32ae7f51931855f6c4ee544edc
|
|
| MD5 |
94ddcb15df88d5b26f7d348b127734c1
|
|
| BLAKE2b-256 |
c31cd899268428963e90804c07e6c1e9e04db93814815d4923bbabdaf5950ac6
|
File details
Details for the file gridcalc-0.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.4 MB
- Tags: CPython 3.13, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81609bd46ca97531dd330a58b02e13e6737d87ba2d1fdbf031154b21f2f987e1
|
|
| MD5 |
417780f2795b9dc361db8b0c0fe63c8a
|
|
| BLAKE2b-256 |
2ad0a1d1f865d07212e5def987d25506e8d8425e8c1c9afb0de19fd5f09eff9b
|
File details
Details for the file gridcalc-0.3.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 3.1 MB
- Tags: CPython 3.13, manylinux: glibc 2.26+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c513029d20f65d867e80200cb96a50bc1c2c5d6deef5aebeb3dd28fff78b3fc7
|
|
| MD5 |
c523745bb8139a7ed879533f63a7f20b
|
|
| BLAKE2b-256 |
e9dad27cd441582ff08fa4fa604599deedb7fbd28a3acc558accdbb557025a4d
|
File details
Details for the file gridcalc-0.3.0-cp313-cp313-macosx_11_0_arm64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp313-cp313-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.13, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f2fbd7417398c3e571f417f778c1fa5a2491c86a3915c38e76120e546a9be04
|
|
| MD5 |
64140b4dd21aeb344f2602831250223f
|
|
| BLAKE2b-256 |
ae83226640fe7411b268c3af0d8b186b44700d1951cd7845b87e355a2efba0ce
|
File details
Details for the file gridcalc-0.3.0-cp313-cp313-macosx_10_15_x86_64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp313-cp313-macosx_10_15_x86_64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.13, macOS 10.15+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d50389fb76a693a9fbde1a817f056826c5f577f1f2c57f1f164da4359c54652b
|
|
| MD5 |
4aa7c5d0041ff401a171583c7baabe39
|
|
| BLAKE2b-256 |
4787a56e7cb6072bd2573e63b79ba73f891213b6eac5816bd96b77765ec01f9e
|
File details
Details for the file gridcalc-0.3.0-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3137a8db552ea30960d9ea486f50adb91ef2cee56bd0321a6d1bb1bc188f4864
|
|
| MD5 |
b89a01b4c85e16811de1839ad09f9aa2
|
|
| BLAKE2b-256 |
f7e77263cdc4a4e2a08d8fbf1e67ce58f6bb45b54dcec016480ffb8e14d12016
|
File details
Details for the file gridcalc-0.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.4 MB
- Tags: CPython 3.12, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef1c1fb0a0cb27b345bc3d92aa292e2c07e9e9ae21b0d715badbe2ef76bb074f
|
|
| MD5 |
d6111b93b9234b70184206d2599eac19
|
|
| BLAKE2b-256 |
77ab900b635ac427f5fd65e002c50023477a6380317e96dbff6e1ac994db11c4
|
File details
Details for the file gridcalc-0.3.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 3.1 MB
- Tags: CPython 3.12, manylinux: glibc 2.26+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
15a9cc28cb66e31b548e672ef1d177eea87fa508ad11b93d67bdf6af7ba5c39b
|
|
| MD5 |
c07901be5a6859ac447654905a4968de
|
|
| BLAKE2b-256 |
bd85a8d1b1bf6f93efd1db651f6abd4ab66c34f95d8cc290432d6b5a4a9384c6
|
File details
Details for the file gridcalc-0.3.0-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d51561820cafca68cb93b6d786d8944098cf5d385e5b01d3202562fad5a2ab7c
|
|
| MD5 |
eb50c904fd0c5044feb66b369a56e682
|
|
| BLAKE2b-256 |
c8ec4f863d929de021f0e3cef453fb77511e1b1c2dbb24c6e0bb1a4086bb3e5b
|
File details
Details for the file gridcalc-0.3.0-cp312-cp312-macosx_10_15_x86_64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp312-cp312-macosx_10_15_x86_64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.12, macOS 10.15+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ec786161f363d46f472c39517960f1d87d605c933fa81c290ec37818fba02aa1
|
|
| MD5 |
698499bdbf845730c7bd17bf87ec94c0
|
|
| BLAKE2b-256 |
2a1431887eae20045c8f892e34b500b0dcde25fbd0338536a45da5da1c1d3e61
|
File details
Details for the file gridcalc-0.3.0-cp312-abi3-win_amd64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp312-abi3-win_amd64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.12+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5492a8a129a381fd6f94075400cfad7ef23adf6214d6218e75cc9a64bd5f429b
|
|
| MD5 |
0ca125f3cfa695cf03707478a8066f13
|
|
| BLAKE2b-256 |
c0dbbd10964a9baeb80840c027105a76a04949dd9fc0d87d6a91b163215290c1
|
File details
Details for the file gridcalc-0.3.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.4 MB
- Tags: CPython 3.12+, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
03d98ee6f079eb4669bab0b574394d9e6cd26789d0c5478909815202c85b0fa4
|
|
| MD5 |
aed9e50b528468f4aa0dd2a982618f40
|
|
| BLAKE2b-256 |
4af6d929e6d326d2ee063eeb97804b024ee2421b6ad9f932d918a0e22f7098fb
|
File details
Details for the file gridcalc-0.3.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 3.1 MB
- Tags: CPython 3.12+, manylinux: glibc 2.26+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e7e25a238e58d70a3eaa3fb241e01f668719e5d27c7ea4df2649389ad509277f
|
|
| MD5 |
64c9ade8a11ad221d516683158e731e9
|
|
| BLAKE2b-256 |
8f55b87301e722ac1823927dd0794204cf0960a4d80adf57034fed2f719b3aa0
|
File details
Details for the file gridcalc-0.3.0-cp312-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp312-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.12+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73fb4d99b3fd468d7fbf4ffc8987052c79f7b25a98e87c3d1e7e5653fca3be2e
|
|
| MD5 |
4fd15df633326bd8c80e609fc4b38428
|
|
| BLAKE2b-256 |
cb8e8ccc7dedb2df050195067bf32247babff9448bcc13c70a22c4ace9549067
|
File details
Details for the file gridcalc-0.3.0-cp312-abi3-macosx_10_15_x86_64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp312-abi3-macosx_10_15_x86_64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.12+, macOS 10.15+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
133780421b1c8df75f4cc70933729fcb362127c42ef00e65256865346ab8b88d
|
|
| MD5 |
9b69591aa4b601981727289cd4bbac5f
|
|
| BLAKE2b-256 |
953a668b82b32d380131948ca8f81bdb0920af6cc13e20d1a689de7ecc3514a6
|
File details
Details for the file gridcalc-0.3.0-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3d76cf7b90c427d7b662d510559fbbcea1d6da3efd0b51ce8c544c3e4ffc306
|
|
| MD5 |
522d22bbee6f2fa1eac21a9a5a3f6887
|
|
| BLAKE2b-256 |
0bd9d58b639d6c03728fee0bcf45c3f5d0d3fb54c847f56a4e091a375a4b5fa8
|
File details
Details for the file gridcalc-0.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.4 MB
- Tags: CPython 3.11, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59cf6a69baa4b960db0b634201c9feba0c3ec1dcea93612ee1bba83710a26924
|
|
| MD5 |
10cb560c38e824e26423db29ec392d56
|
|
| BLAKE2b-256 |
c28011f6b94b1ac524e30a74a229274f656d18e2cb84180929949d265bc4db5c
|
File details
Details for the file gridcalc-0.3.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 3.1 MB
- Tags: CPython 3.11, manylinux: glibc 2.26+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cde6a8593efa274f7a70ad136a2e5b68138e491dee690394420e2eea45cd9849
|
|
| MD5 |
88590b9dc2743d6709e0664e8d6c467a
|
|
| BLAKE2b-256 |
0b46baa511cfb5973036ae5116bafc87ab1912e8cffa534b5f5055d65099a912
|
File details
Details for the file gridcalc-0.3.0-cp311-cp311-macosx_11_0_arm64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp311-cp311-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.11, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
469d3090b71612cbdcc3d3eadcfc12ce791ee66a8a1a0e1c7b25db3e32ee21f6
|
|
| MD5 |
725e9aba1dbf1bb4fc632edfd0818a55
|
|
| BLAKE2b-256 |
2c22cea5864d42a6fb08df559b267da20860a4576a378c6be0d841f0400c53c8
|
File details
Details for the file gridcalc-0.3.0-cp311-cp311-macosx_10_15_x86_64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp311-cp311-macosx_10_15_x86_64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.11, macOS 10.15+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cce3215d355f9d19dae3ee35bd9a53ea817ea987fee5816468babf0c9524b03e
|
|
| MD5 |
e48a2645090f2bea0ae7c57a238a19de
|
|
| BLAKE2b-256 |
369edf557603145f1f5fa236f827e9dc85e2da7e77958284278a887f2695bc0d
|
File details
Details for the file gridcalc-0.3.0-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
79e2945ec9fdae70197f1277f955d7e5ce136336b8fc1989d9b3374be3393b44
|
|
| MD5 |
79a42a101a05d819d22732315dd91dba
|
|
| BLAKE2b-256 |
1961bef11e807a6b1c5be9c999c86e204aecd04a38423bcbd113b3e43af04724
|
File details
Details for the file gridcalc-0.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 3.4 MB
- Tags: CPython 3.10, manylinux: glibc 2.27+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
87c9c7fc7e920e2bc3918b4ff6a1043a8f4d63c3e27d94417aa1b815bb946109
|
|
| MD5 |
b234eca6e9a80098ca0facac50bd6e5c
|
|
| BLAKE2b-256 |
83098f77f5a997524d8acb92cff617f2c0d8d3c22a7aea165c0f56d655eefc09
|
File details
Details for the file gridcalc-0.3.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp310-cp310-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 3.1 MB
- Tags: CPython 3.10, manylinux: glibc 2.26+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5427d49b4e74704153d726cf87d2610436729d7d669e97e80d55358d150a1455
|
|
| MD5 |
1eb733f1c88487c33975173da2d937d4
|
|
| BLAKE2b-256 |
e71ca9bafc8859c18c2b5274c8026ed819047fce718a3e4d1c3c12f36c8cccfd
|
File details
Details for the file gridcalc-0.3.0-cp310-cp310-macosx_11_0_arm64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp310-cp310-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.3 MB
- Tags: CPython 3.10, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1e959d72ce7bb7295caec0a1660f850345259db2195a688f2129d5176738810
|
|
| MD5 |
36c4605920de47692ae6c667c3701183
|
|
| BLAKE2b-256 |
ece95547cc2f5ecc2a8fbf30a6a13607b804a57ef89932f918819c60fe2b00f4
|
File details
Details for the file gridcalc-0.3.0-cp310-cp310-macosx_10_15_x86_64.whl.
File metadata
- Download URL: gridcalc-0.3.0-cp310-cp310-macosx_10_15_x86_64.whl
- Upload date:
- Size: 2.6 MB
- Tags: CPython 3.10, macOS 10.15+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0763a1464d41e503fa3330249d2a3e62919e418db31071e53bf6935d07f31fa6
|
|
| MD5 |
85ba2bbfdc7409dc4fac9485f8199007
|
|
| BLAKE2b-256 |
71c9f1b4ad490b68d5721c306e9fd8c02b9fa09992319258c02db910efaed6fd
|