Skip to content

Commit

Permalink
Fix #494 add min and max functions (#496)
Browse files Browse the repository at this point in the history
- Fix #495 defer evaluation of py_value
- pkdebug=xlsx provides significant trace output
- added blank_table to sheet
  • Loading branch information
robnagler authored Jul 23, 2024
1 parent c150211 commit b7fe7f1
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 9 deletions.
25 changes: 17 additions & 8 deletions pykern/xlsx.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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,
)
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions tests/xlsx_data/1.in/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions tests/xlsx_data/1.out/case1.csv
Original file line number Diff line number Diff line change
@@ -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,,,,,
2 changes: 1 addition & 1 deletion tests/xlsx_data/1.out/xl/worksheets/sheet1.xml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><dimension ref="A1:F5"/><sheetViews><sheetView tabSelected="1" workbookViewId="0"/></sheetViews><sheetFormatPr defaultRowHeight="15"/><cols><col min="1" max="1" width="9.7109375" customWidth="1"/><col min="2" max="2" width="20.7109375" customWidth="1"/><col min="3" max="3" width="5.7109375" customWidth="1"/><col min="4" max="4" width="8.7109375" customWidth="1"/><col min="5" max="5" width="0" customWidth="1"/><col min="6" max="6" width="4.7109375" customWidth="1"/></cols><sheetData><row r="1" spans="1:6"><c r="A1" s="1"><v>375</v></c><c r="B1" s="2" t="s"><v>0</v></c><c r="C1" s="1"><v>7.77</v></c><c r="D1" s="2" t="s"><v>1</v></c><c r="E1" s="2"/><c r="F1" s="1"><v>3.14</v></c></row><row r="2" spans="1:6"><c r="A2" s="3" t="s"><v>2</v></c><c r="B2" s="3" t="s"><v>3</v></c><c r="C2" s="3" t="s"><v>4</v></c><c r="D2" s="3" t="s"><v>5</v></c></row><row r="3" spans="1:6"><c r="A3" s="4"><f>ROUND(PRODUCT(100--B3,1),2)</f><v>135.34</v></c><c r="B3" s="5"><v>35.34</v></c><c r="C3" s="1"><f>ROUND(MOD(B3,1),2)</f><v>0.34</v></c><c r="D3" s="5" t="str"><f>IF(B3&lt;=2,"red","green")</f><v>green</v></c></row><row r="4" spans="1:6"><c r="A4" s="6" t="s"><v>6</v></c><c r="B4" s="6"/><c r="C4" s="7" t="s"><v>7</v></c><c r="D4" s="6"/></row><row r="5" spans="1:6"><c r="A5" s="2" t="s"><v>8</v></c><c r="B5" s="2"/><c r="C5" s="2"/><c r="D5" s="2"/></row></sheetData><pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/><ignoredErrors><ignoredError sqref="A1 C1 F1 A3 B3 C3" numberStoredAsText="1"/></ignoredErrors></worksheet>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><dimension ref="A1:F6"/><sheetViews><sheetView tabSelected="1" workbookViewId="0"/></sheetViews><sheetFormatPr defaultRowHeight="15"/><cols><col min="1" max="1" width="9.7109375" customWidth="1"/><col min="2" max="2" width="20.7109375" customWidth="1"/><col min="3" max="4" width="8.7109375" customWidth="1"/><col min="5" max="5" width="0" customWidth="1"/><col min="6" max="6" width="4.7109375" customWidth="1"/></cols><sheetData><row r="1" spans="1:6"><c r="A1" s="1"><v>375</v></c><c r="B1" s="2" t="s"><v>0</v></c><c r="C1" s="1"><v>7.77</v></c><c r="D1" s="2" t="s"><v>1</v></c><c r="E1" s="2"/><c r="F1" s="1"><v>3.14</v></c></row><row r="2" spans="1:6"><c r="A2" s="3" t="s"><v>2</v></c><c r="B2" s="3" t="s"><v>3</v></c><c r="C2" s="3" t="s"><v>4</v></c><c r="D2" s="3" t="s"><v>5</v></c></row><row r="3" spans="1:6"><c r="A3" s="4"><f>ROUND(PRODUCT(100--B3,1),2)</f><v>135.34</v></c><c r="B3" s="5"><v>35.34</v></c><c r="C3" s="1"><f>ROUND(MOD(B3,1),2)</f><v>0.34</v></c><c r="D3" s="5" t="str"><f>IF(B3&lt;=2,"red","green")</f><v>green</v></c></row><row r="4" spans="1:6"><c r="A4" s="6"><f>ROUND(MAX(999),2)</f><v>999.00</v></c><c r="B4" s="6"><f>ROUND(MAX(111,222),2)</f><v>222.00</v></c><c r="C4" s="6"><f>ROUND(MIN(333,444),2)</f><v>333.00</v></c><c r="D4" s="6"><f>ROUND(IF(0,1/0,99),2)</f><v>99.00</v></c></row><row r="5" spans="1:6"><c r="A5" s="7" t="s"><v>6</v></c><c r="B5" s="7"/><c r="C5" s="8" t="s"><v>7</v></c><c r="D5" s="7"/></row><row r="6" spans="1:6"><c r="A6" s="2" t="s"><v>8</v></c><c r="B6" s="2"/><c r="C6" s="2"/><c r="D6" s="2"/></row></sheetData><pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/><ignoredErrors><ignoredError sqref="A1 C1 F1 A3 B3 C3 A4 B4 C4 D4" numberStoredAsText="1"/></ignoredErrors></worksheet>

0 comments on commit b7fe7f1

Please sign in to comment.