-
Notifications
You must be signed in to change notification settings - Fork 393
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generates algorithmic environment from algpseudocode #152
Conversation
@odashi let me know what you think about this approach. Looking for a bit of early feedback before continuing. |
@ZibingZhang Could you open the pull request instead of leaving it as a draft? I'm using PR's status to manage my taskboard and sometimes draft PRs are overlooked. |
Thanks! I will take a look at the code later today. Some comments about the description:
This may be a typo.
If we provide this function, it must provide a way to correctly print the expression onto Jupyter. Since algorithm environmets are not supported by Jupyter (MathJax), we need to simulate it by ourselves. This means that the algorithm version of "LatexifiedFunction" needs two codegens for
At this point, I guessed the enum value should be |
I'm not sure if this is possible, due to the recursive nature of ASTs. If you look at the first commit I had something like def visit_SomeNode(node):
return self._function_codegen.visit(node) But something of this nature won't work since recursive calls will end up in the FunctionCodegen methods instead of back in the AlgorithmCodegen methods. I think to avoid the weird |
It should work as far as the subtree processing is completely delegated. Since both Unfortunately there is no private inheritance in Python, and many techniques available in other languages (such as C++) can't be used. |
Consider class ACodegen:
def visit_Attribute(self, node: ast.Attribute) -> str:
vstr = self.visit(node.value)
astr = self._identifier_converter.convert(node.attr)[0]
return vstr + "." + astr
def visit_If(self, node: ast.If) -> str:
raise Error("Unsupported")
class BCodegen:
def visit_Attribute(self, node: ast.Attribute) -> str:
return self._a_codegen.visit(node)
def visit_If(self, node: ast.If) -> str:
return "..." If we have some structure like: { "attribute": { "value": { "if": "..." } } The call stack would look like
whereas the desired behavior would be
Basically any edit: I guess this could be solved like so? class BCodegen:
def visit_Attribute(self, node: ast.Attribute) -> str:
return ACodegen.visit_Attribute(self, node) but at that point you may as well just use inheritance, since you're relying on |
Before continuing discussion, we need to understand how the Python AST is constructed. Overall, all ASTs look like as follows:
where In In this PR, |
The contrast between |
That makes sense ty for explaining! The only issue I can maybe see down the line if |
Do you think it's possible to merge this early somehow (i.e. without completing
Just worried about trying to deal with future merge conflicts, since this change is changing a fundamental part of the pipeline, and is touching a bunch of files. |
I think it's We should be able to treat this kind of subtrees safely as a part of either |
ExpressionCodegen should be separated into other pull request since this is an independent feature. |
Sounds good. Will tackle this within the next few days! |
Thanks! It looks your repository breaks the blame history when splitting FunctionCodegen. Since it makes debugging hard, make sure that the history is preserved appropriately: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dummy, please re-request afterwards
ff276d7
to
4ada4b5
Compare
node = ast.parse( | ||
textwrap.dedent( | ||
""" | ||
while True: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed whitespacing issues in function_codegen_test.py
to match this style, don't know what I was doing when I wrote those tests...
|
||
from typing import Any, Callable | ||
|
||
from latexify import frontend |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this file should be a unit test frontend_{algorithmic?}_test.py
because frontend
is not intended to be used directly.
Or it'd be okay to use just exported functions and Style
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can move it, but function_expansion_test
and regression_test
basically use frontend
directly, as they use frontend.function
.
Similarly, this file uses function.get_latex
. Both of these functions are exported in __init__.py
, so it feels somewhat like an integration test, because we're testing end-to-end behavior from function to generated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it turns that the issue comes from the old implementation of these tests, will consider it later.
"""Visit a While node.""" | ||
if node.orelse: | ||
raise exceptions.LatexifyNotSupportedError( | ||
"Codegen does not support while statements with an else clause." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tip: Users don't usually understand what "codegen" (or any other inner routines) is, so simplifying the message is more user-friendly.
"Codegen does not support while statements with an else clause." | |
"While statement with the else clause is not supported." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fair, was trying to model it off the error message in function_codegen
about only having assign nodes in multiline functions. Unsure how to change that message as well to be more user friendly
@@ -173,7 +190,7 @@ def expression( | |||
This function is a shortcut for `latexify.function` with the default parameter | |||
`use_signature=False`. | |||
""" | |||
kwargs["use_signature"] = kwargs.get("use_signature", False) | |||
kwargs["style"] = Style.EXPRESSION |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function no longer need to invoke function
, just invoking get_latex
directly is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
expression
returns a LatexifiedFunction
, while get_latex
returns str
. I think we still need the extra work that function
provides to wrap the result of get_latex
, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah sorry I was a bit confused! I will consider these implementations later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe good to merge, thanks!
|
||
from typing import Any, Callable | ||
|
||
from latexify import frontend |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So it turns that the issue comes from the old implementation of these tests, will consider it later.
Overview
Generates algorithmic environment from algpseudocode.
Details
Creates a new class$\LaTeX$ code in the following form:
algorithm_codegen
that should generateExample
Things to take into consideration:
function_codegen
, at least for the time being. Namelyuse_signature
will be disregarded if set.get_latex(style=Style.ALGORITHM
, but there should be a way to use it as@latexify.algorithm
. But what should the return type be?str
?LatexifiedFunction
?References
Described by this issue: #57
Blocked by
None