connorferster / handcalcs

Python library for converting Python calculations into rendered latex.
Apache License 2.0
5.63k stars 428 forks source link

Error when no variable assigned to equation after %%render #54

Open michaellisitsa opened 3 years ago

michaellisitsa commented 3 years ago

When entering an arithmetic equation without a variable assignment, handcalcs creates an error.

How to reproduce IMG_0560

Expected Behaviour IMG_0561

Error Message


KeyError                                  Traceback (most recent call last)
<ipython-input-8-306984f7e9b7> in <module>
----> 1 get_ipython().run_cell_magic('render', '', '2+2\n')

~/opt/miniconda3/envs/mywork1/lib/python3.8/site-packages/IPython/core/interactiveshell.py in run_cell_magic(self, magic_name, line, cell)
   2369             with self.builtin_trap:
   2370                 args = (magic_arg_s, cell)
-> 2371                 result = fn(*args, **kwargs)
   2372             return result
   2373 

~/opt/miniconda3/envs/mywork1/lib/python3.8/site-packages/handcalcs/render.py in render(line, cell)
    102     # Do the handcalc conversion
    103     renderer = hand.LatexRenderer(cell, user_ns_postrun, line_args)
--> 104     latex_code = renderer.render()
    105 
    106     # Display, but not as an "output"

~/opt/miniconda3/envs/mywork1/lib/python3.8/site-packages/handcalcs/handcalcs.py in render(self)
    222             self.precision,
    223             LatexRenderer.dec_sep,
--> 224         )
    225 
    226 

~/opt/miniconda3/envs/mywork1/lib/python3.8/site-packages/handcalcs/handcalcs.py in latex(raw_python_source, calculated_results, override, precision, dec_sep)
    244 
    245 
--> 246 def create_param_cell(
    247     raw_source: str, calculated_result: dict, precision: int
    248 ) -> ParameterCell:

~/opt/miniconda3/envs/mywork1/lib/python3.8/site-packages/handcalcs/handcalcs.py in categorize_lines(cell)
    427         incoming.append(categorized_w_result_appended)
    428     cell.lines = incoming
--> 429     return cell
    430 
    431 

~/opt/miniconda3/envs/mywork1/lib/python3.8/site-packages/handcalcs/handcalcs.py in categorize_line(line, calculated_results, override)
    515         categorized_line = create_conditional_line(
    516             line, calculated_results, override, comment
--> 517         )
    518 
    519     elif "=" in line:

~/opt/miniconda3/envs/mywork1/lib/python3.8/site-packages/handcalcs/handcalcs.py in split_parameter_line(line, calculated_results)
   1463     param_line = deque([param, "=", calculated_results[param]])
   1464     return param_line
-> 1465 
   1466 
   1467 def format_strings(string: str, comment: bool) -> deque:

KeyError: '2+2')```
connorferster commented 3 years ago

Hi @michaellisitsa,

This is another limitation of handcalcs: I do not know of a way to handle this scenario, in general, without handcalcs doing some eval work which I would like to avoid. handcalcs just gathers two pieces of data: the raw source in a cell and a dictionary of variables. It then, artfully I think, swaps variable names for variable values and then replaces a bunch of substrings contained within the raw cell source. Without a variable name to assign the answer to, e.g. a = 2+2, there is not much I can do to get the resulting value.

Note, that when using IPython, the variable _ stores the output of the most recently run cell. This could potentially work for solving this problem but it would only work in IPython/Jupyter and it would not work with the decorator which is why I am reluctant to implement it. It would also require the other feature you suggested (#55) which I plan on implementing at some point because I think it's a good move.

So, perhaps this might be possible but it will be a lower priority for me.

michaellisitsa commented 3 years ago

I like the idea of having it in Jupyter, if you can easily extract the resultant value from the _ variable. I was thinking that for newcomers who are trying to get handcalcs to work, it will probably be the first thing they try, particularly if they've come from Mathcad etc. They are unlikely to start learning handcalcs via the decorator methods.

Completely understand the low priority, I don't have too many uses for having above functionality.

connorferster commented 3 years ago

@michaellisitsa,

I have been thinking about this and I want to tackle this next. I think it would be really cool if handcalcs could do this, especially now that #55 has been implemented.

connorferster commented 3 years ago

55 has been implemented. Will start thinking about this one more.

michaellisitsa commented 3 years ago

That's great to hear. If you figure how to decouple the rendering from a variable assignment, may it can open up the gates to comment lines #Line only has comment to be rendered (providing commentary in between calculations, without having to split with Markdown cells in Jupyter)