From b7fe7f19f984d30e4745035be5ba27026f4b56cc Mon Sep 17 00:00:00 2001 From: Rob Nagler <5495179+robnagler@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:11:16 -0600 Subject: [PATCH] Fix #494 add min and max functions (#496) - Fix #495 defer evaluation of py_value - pkdebug=xlsx provides significant trace output - added blank_table to sheet --- pykern/xlsx.py | 25 +++++++++++++------ tests/xlsx_data/1.in/case.py | 6 +++++ tests/xlsx_data/1.out/case1.csv | 1 + .../xlsx_data/1.out/xl/worksheets/sheet1.xml | 2 +- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/pykern/xlsx.py b/pykern/xlsx.py index d6b8a14a..6644ef25 100644 --- a/pykern/xlsx.py +++ b/pykern/xlsx.py @@ -287,6 +287,7 @@ def _literal(): _is_decimal=isinstance(content, decimal.Decimal), ) + pkdc("{}!{}={}", cell.sheet.title, cell.xl_id, content) self.is_formula = isinstance(content, (list, tuple)) if self.is_formula: _formula() @@ -300,6 +301,8 @@ def is_decimal(self): def py_value(self): if (rv := self.get("_py_value")) is None: self._error("expected an expression with a single value expr={}", self) + if callable(rv): + self._py_value = rv = rv() if not isinstance(rv, (bool, str, decimal.Decimal)): self._error("unexpected expression value={} expr={}", rv, self) return rv @@ -393,7 +396,7 @@ def _xl_id(cell): self.pkupdate( _link_ref=content, _is_decimal=l.expr.is_decimal(), - _py_value=l.expr.py_value() if c.resolved_count == 1 else None, + _py_value=(lambda: l.expr.py_value()) if c.resolved_count == 1 else None, _xl_formula=_xl_formula(c.pairs), cells=c.cells, resolved_count=c.resolved_count, @@ -525,21 +528,23 @@ def init(cls): def _bool(token, func): cls(token, func, _is_decimal=False, _infix=True) - def _multi(token, func, init, xl): + def _multi(token, func, init=None, xl=None): cls( token, "multi", _py_func_multi_func=func, - _py_func_multi_init=decimal.Decimal(init), - _xl_func=xl, + _py_func_multi_init=None if init is None else decimal.Decimal(init), + _xl_func=xl or token, operand_count=(1, 65535), _is_multi=True, _is_decimal=True, ) cls("%", lambda x, y: x % y, _xl_func="MOD", _is_decimal=True) - _multi("*", lambda x, y: x * y, 1, "PRODUCT") - _multi("+", lambda x, y: x + y, 0, "SUM") + _multi("*", lambda rv, y: rv * y, 1, "PRODUCT") + _multi("+", lambda rv, y: rv + y, 0, "SUM") + _multi("MAX", max) + _multi("MIN", min) cls( "-", "minus", @@ -570,7 +575,7 @@ def evaluate(self, operands, cell): ), _op_spec=self, _operands=o, - _py_value=self._py_func(o), + _py_value=lambda: self._py_func(o), _xl_formula=self._xl_func(o), resolved_count=1, ) @@ -646,7 +651,7 @@ def _iter(): self._error( "not decimal operand type={} value={} operand={}", type(v), v, e ) - rv = self._py_func_multi_func(rv, v) + rv = v if rv is None else self._py_func_multi_func(rv, v) return rv def _xl_func_default(self, operands): @@ -766,6 +771,10 @@ def __init__(self, cfg): super().__init__(cfg) self.tables = [] + def blank_table(self): + """Create a table with one row, which is blank""" + self.table(title=f"blank_table-{len(self.tables)}").row() + def table(self, **kwargs): """Appends table to sheets diff --git a/tests/xlsx_data/1.in/case.py b/tests/xlsx_data/1.in/case.py index c03d427f..085696ac 100644 --- a/tests/xlsx_data/1.in/case.py +++ b/tests/xlsx_data/1.in/case.py @@ -44,6 +44,12 @@ ("IF", ["<=", ["n"], 2], "red", "green"), ), ).pkupdate(defaults=PKDict(num_fmt="currency")) +t.row( + Left=["MAX", 999], + Middle=["MAX", 111, 222], + three=["MIN", 333, 444], + four=["IF", 0, ["/", 1, 0], 99], +).pkupdate(defaults=PKDict(num_fmt="currency")) t.footer( Left="L", Middle=None, diff --git a/tests/xlsx_data/1.out/case1.csv b/tests/xlsx_data/1.out/case1.csv index e7997bcf..b301efea 100644 --- a/tests/xlsx_data/1.out/case1.csv +++ b/tests/xlsx_data/1.out/case1.csv @@ -1,5 +1,6 @@ 375,a fairly long string,7.77,TRUE,,3.14 Left,Middle,Right,Very End,, 135.34,35.34,0.34,green,, +999,222,333,99,, L,,R,,, No Totals,,,,, diff --git a/tests/xlsx_data/1.out/xl/worksheets/sheet1.xml b/tests/xlsx_data/1.out/xl/worksheets/sheet1.xml index 1346d90a..9c9f6b2f 100644 --- a/tests/xlsx_data/1.out/xl/worksheets/sheet1.xml +++ b/tests/xlsx_data/1.out/xl/worksheets/sheet1.xml @@ -1,2 +1,2 @@ -37507.7713.142345ROUND(PRODUCT(100--B3,1),2)135.3435.34ROUND(MOD(B3,1),2)0.34IF(B3<=2,"red","green")green678 \ No newline at end of file +37507.7713.142345ROUND(PRODUCT(100--B3,1),2)135.3435.34ROUND(MOD(B3,1),2)0.34IF(B3<=2,"red","green")greenROUND(MAX(999),2)999.00ROUND(MAX(111,222),2)222.00ROUND(MIN(333,444),2)333.00ROUND(IF(0,1/0,99),2)99.00678 \ No newline at end of file