Closed igheorghita closed 3 years ago
Thanks for the report. I have never used Pycel interactively, so error state conditions that will cause problems in an interactive mode have, to my knowledge, never been addressed.
It has been my experience, that mechanisms to allow continued robust operation after error conditions are highly non-trivial to get right. I would be nervous about trying to "fix" the above with manipulations inside the internal state.
However, a mechanism to note the previous error and to issue a warning on subsequent evaluation attempts, should be easy enough to implement in a robust manner. Would you me interested in submitting a PR?
Thanks for the quick response! You probably understood what I wrote, but just to clarify - would you consider the following interactive?
model = ExcelCompiler(filename)
cell_names = ['A1', 'B1', 'C1', 'A2', 'B2', 'C2', 'A3']
for cell_name in cell_names:
try:
model.evaluate(cell_name)
except:
print('error evaluating cell', cell_name)
# This prints:
# error evaluating cell A1
# error evaluating cell B1
# error evaluating cell C1
# error evaluating cell A3
I imagine it's common to have functions in spreadsheets that aren't implemented and it could be confusing behavior to have certain cells fail after an error happens. I understand your point though. I can also look into it some more and if the warning is the best way to go, I can try to implement that.
As a side note, couple questions: 1) Would you recommend a way of evaluating that doesn't have this order dependence issue? 2) I'm particularly interested in recomputing all cells immediately and I saw there's a recalculate method for the ExcelCompiler class. But this only works if the cells are already in the cell_map. Is there a best way to get the cells in the cell_map besides just evaluating or using some of the internal methods?
Thanks again!
By interactive I meant using Jupyter, or another shell, to work interactively with objects. This is as opposed to restarting a program for each run against the workbook in question. The use case for missing functions that cause errors during evaluation, in which afterwards, continued calculation was expected to always behave reasonably, was, as far as I know, never considered as a design goal.
Missing functions are certainly a thing when bringing in new workbooks to use, but in my workflows, that is immediately followed by implementing the missing function, and then running the tests again. Which is to say, any results that follow an error are always suspect, and never expected to be useful beyond finding that first error.
You can implement a function, and tell pycel where to find it with the plugin parameter, and thus remove the unknown function error, and allow continued calcs with a less unstable calculator state.
Got it, thanks for clarifying!
What actually happened
I have a spreadsheet which contains a SWITCH function (not implemented) in certain cells (say A1) and in some lower row there's a cell containing a string (say A3). If I initiate an ExcelCompiler class, then immediately evaluate the string cell, everything works properly. But if I try to evaluate the SWITCH cell first, then try to evaluate the string cell, there's an error. At this point the string cell is not in the
cell_map
butrange_todos
is nonempty, so the chain of functions that's called is:_evaluate_non_iterative
-->_gen_graph
-->_process_gen_graph
-->_evaluate_range
, which ultimately fails because of the SWITCH related ranges being inrange_todos
. Funnily, the second time you try to evaluate the string cell after this failure, it works, because at that point the cell is already in thecell_map
and_gen_graph
never gets called.What was expected to happen
I would expect that the order in which you evaluate cells shouldn't matter. I wonder if range_todos should be cleared if there's an error in evaluation?
Problem description
If range_todos isn't cleared after there was an error in evaluating a cell, then it seems every time you try to evaluate a cell not in cell_map from that point onwards, you'll encounter an error.
Code Sample
Here's the example Excel file:
switch_test.xlsx
Here's the Traceback from the second example for the A3 cell:
Environment
Pycel version: 1.0b27 Python version: 3.8.11 OS: macOS Big Sur (version 11.5.1)