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.14
2345
ROUND(PRODUCT(100--B3,1),2)135.3435.34ROUND(MOD(B3,1),2)0.34IF(B3<=2,"red","green")green
67
8
\ No newline at end of file
+37507.7713.14
2345
ROUND(PRODUCT(100--B3,1),2)135.3435.34ROUND(MOD(B3,1),2)0.34IF(B3<=2,"red","green")green
ROUND(MAX(999),2)999.00ROUND(MAX(111,222),2)222.00ROUND(MIN(333,444),2)333.00ROUND(IF(0,1/0,99),2)99.00
67
8
\ No newline at end of file