Skip to content

modeleon 0.2.3 - #4

Merged
adilkhanovkz merged 2 commits into
mainfrom
release/0.2.3
Oct 26, 2026
Merged

adilkhanovkz merged 2 commits into
mainfrom
release/0.2.3

Conversation

@adilkhanovkz

Copy link
Copy Markdown
Member

Release 0.2.3.

  • 80 more spreadsheet functions, each written as a live formula — errors and branches (IFERROR, ISERROR, ISNUMBER, XOR, IFS, SWITCH); rounding, powers and logarithms (ROUNDUP, CEILING, POWER, SQRT, LN, PRODUCT, …); loan schedules and depreciation (NPER, RATE, IPMT, PPMT, CUMIPMT, CUMPRINC, SLN, DB, DDB, SYD); dates (DATEDIF, WEEKDAY, WEEKNUM, NETWORKDAYS, WORKDAY); text (LEFT, MID, FIND, SUBSTITUTE, TEXT, TEXTJOIN, …); conditional sums and counts (SUMIF(S), COUNTIF(S), AVERAGEIF(S), MAXIFS, MINIFS, COUNT, COUNTA); lookups (XLOOKUP, INDEX, MATCH, VLOOKUP, HLOOKUP); and statistics (MEDIAN, STDEV_S, VAR_S, PERCENTILE_INC, QUARTILE_INC, LARGE, SMALL, RANK_EQ, …).
  • More grains of time — hours on a fixed-offset zone, ISO weeks and ISO years, and the half-year, each with its mo.time, header formulas and totals columns; a day sheet totals by month; modeleon.core.calendar and period_bounds / year_back_index give each period's dates to your own code.
  • Named Excel views — with mo.applied_view(model.board): model.to_excel(path) writes the same model under another look.
  • Every function reads a line on another time window by date, and lines along keys key by key, as a + b does — in Python and in the workbook.
  • Units are checked wherever values are combined — functions that add, compare or pick refuse two units; a bps or pp count beside a % fraction is refused; a recurrence is in its start's unit; a unit with several slashes reads as written.
  • Faster — a 2,000-line model builds in about three quarters of the time; a records table of thousands of rows is written in linear time.
  • Fixes: a tracked row reads by position (closing[-1]), a container cannot hold itself, a view hung where nothing reads it warns with the slot to use, a grain or totals kind the engine does not know is refused where it is given, and more.

Behaviour changes: mo.SUM(a, b) and mo.AVERAGE(a, b) over two or more series now work period by period (a subtotal, =SUM(C5, C9) in each column); the total of several rows over all their periods is mo.SUM(a) + mo.SUM(b). A model that mixed units in a function, a comparison, a lag's fill or a loan's amounts, or added a bps / pp count to a % fraction, is refused with a message that names the fix. A line on another time window is read by date; one that does not cover the combined window needs a rule, extend=mo.zero() or extend=mo.hold(). .shift(n, fill_value=<line>) writes the fill as a live cell.

The full list is in CHANGELOG.md.

Modeleon added 2 commits October 26, 2026 13:27
A parametrized case with a 32,767-character expected string gets a short
id (pytest writes the id to an environment variable, which Windows caps
at 32,767 characters), and a test checks an expression by its parts
rather than with ==, which since Python 3.13 compares dataclass fields
without the identity shortcut.
@adilkhanovkz
adilkhanovkz merged commit a94ac78 into main Oct 26, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant