Skip to content
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

Add assign feature #51

Merged
merged 13 commits into from
Oct 20, 2022
Merged

Add assign feature #51

merged 13 commits into from
Oct 20, 2022

Conversation

Raphael-CV
Copy link
Contributor

Add assign feature (cf #23). When there are assignments, variables and values are stored to be displayed at the end. These lines:

@latexify.with_latex
def f(x):
    res = x**2
    return res

are the same as:

@latexify.with_latex
def f(x):
    return x**2

@Raphael-CV Raphael-CV requested a review from odashi as a code owner October 14, 2022 08:32
Copy link
Collaborator

@odashi odashi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add several unit tests to cover the feature proposed in this change?

def visit_Assign(self, node, action):
del action

self.assign_var[node.targets[0].id] = self.visit(node.value)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this doesn't work correctly if the function has nested defs:

def foo(x):
    y = 42
    def bar(x):
        y = 123
    return y

Copy link
Collaborator

@odashi odashi Oct 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this moment, I guessed that it would be better to raise an error when the parser found nested functions or classes (all things that define an inner namespace).

@@ -135,6 +150,8 @@ def visit_Attribute(self, node, action): # pylint: disable=invalid-name

def visit_Name(self, node, action): # pylint: disable=invalid-name
del action
if node.id in self.assign_var.keys():
return self.assign_var[node.id]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some concerns around this:

  • It may cause exponential expansion. An extreme case:

    def fn(x):
        a = x + x
        b = a + a
        c = b + b
        return c

    This may return $x+x+x+x+x+x+x+x$.

  • If the assigned string has some structure, we need to add appropriate parentheses around the string.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid exponential expansion, I suggest to add an option to activate or not the assignment.
For example:

@latexify.with_latex(assign_mode=False)
def h(x):
    a = abs(x)
    b = math.exp(math.sqrt(x))
    return a * b

will return a = \left|{x}\right| \\ b = \exp{\left({\sqrt{x}}\right)} \\ \mathrm{h}(x) \triangleq ab

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also a problem when assignment refers to several numbers with a product like:

@with_latex
def f(x):
    a = 1
    b = 2
    return a * b

return \mathrm{f}(x) \triangleq 12

image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I think reduce_assignments is good for the option name (assign_mode boolean option is somewhat confusing to users)

@Raphael-CV
Copy link
Contributor Author

It seems I break some tests ahah, I am going to correct this

@odashi odashi added this to the v0.2 milestone Oct 14, 2022
@Raphael-CV
Copy link
Contributor Author

There are still some problems with parenthesis. To avoid some problems like this function:

@with_latex(reduce_assignments=True)
def f(x):
    y = 1 + x
    return y ** 2

that would returns $\mathrm{f}(x) \triangleq 1 + x^{2}$, I added parenthesis around each assigned functions in order to have $\mathrm{f}(x) \triangleq \left( 1 + x \right)^{2}$.

But there are some cases where it is useless and unsightly, for example:

@with_latex(reduce_assignments=True)
def f(x):
    y = math.exp(x)
    return y ** 2

returns $\mathrm{f}(x) \triangleq \left( \exp{\left({x}\right)} \right)^{2}$.

@odashi
Copy link
Collaborator

odashi commented Oct 17, 2022

I think it is okay. redundant parentheses are general problems on this library and we need some entire solution on this, but it is somewhat off-topic of this pull request.

@odashi odashi self-requested a review October 18, 2022 07:01
@odashi odashi merged commit 901f89f into google:main Oct 20, 2022
@Raphael-CV Raphael-CV deleted the assign-feature branch October 20, 2022 07:36
@odashi odashi added the feature label Nov 1, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants