-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
[Demo PR] Format sympy/solvers with yapf #22437
Conversation
Applied formatting as follows: ```shell yapf -i -p $(git ls-files | grep -E "sympy/solvers/.*\.py") ```
✅ Hi, I am the SymPy bot (v162). I'm here to help you write a release notes entry. Please read the guide on how to write release notes.
Click here to see the pull request description that was parsed.
|
🟠Hi, I am the SymPy bot (v162). I've noticed that some of your commits add or delete files. Since this is sometimes done unintentionally, I wanted to alert you about it. This is an experimental feature of SymPy Bot. If you have any feedback on it, please comment at sympy/sympy-bot#75. The following commits add new files:
If these files were added/deleted on purpose, you can ignore this message. |
sympy/solvers/ode/hypergeometric.py
Outdated
I0_num, I0_dem = I0.as_numer_denom() | ||
# collecting coeff of (x**2, x), of the standerd equation. | ||
# substituting (a-b) = s, (a+b) = r | ||
dict_I0 = {x**2:s**2 - 1, x:(2*(1-r)*c + (r+s)*(r-s)), 1:c*(c-2)} | ||
dict_I0 = {x**2: s**2 - 1, x: (2*(1-r)*c + (r+s)*(r-s)), 1: c*(c-2)} |
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.
it is reluctant to make changes in values of the dict; compare this to the addition of space arount the +
at line 198 a few lines below
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 is due to this option:
Line 95 in 2d90dc1
arithmetic_precedence_indication = True |
If you remove that option, it becomes:
dict_I0 = {
x**2: s**2 - 1,
x: (2*(1 - r)*c + (r + s)*(r - s)),
1: c*(c - 2)
}
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.
(line-breaks are just because this didn't fit within 79 anymore)
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 looks better
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.
Agreed. I switched it off (ba85647), but we have to check if that has undesired consequences elsewhere.
Benchmark results from GitHub Actions Lower numbers are good, higher numbers are bad. A ratio less than 1 Significantly changed benchmark results (PR vs master) Significantly changed benchmark results (master vs previous release) before after ratio
[907895ac] [6247eefd]
- 5.56±0.02s 340±4ms 0.06 polygon.PolygonArbitraryPoint.time_bench01
Full benchmark results can be found as artifacts in GitHub Actions |
hints = classifier(eq, func, dict=True, ics=ics, xi=xi, eta=eta, | ||
n=terms, x0=x0, hint=hint, prep=prep) | ||
hints = classifier( | ||
eq, | ||
func, | ||
dict=True, | ||
ics=ics, | ||
xi=xi, | ||
eta=eta, | ||
n=terms, | ||
x0=x0, | ||
hint=hint, | ||
prep=prep | ||
) |
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 don't really like this change. Maybe I would make a **opts
dict or something but I'm not sure.
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.
The line breaks are there because of the 79 column limit. If you set it to something like 100, it becomes:
hints = classifier(
eq, func, dict=True, ics=ics, xi=xi, eta=eta, n=terms, x0=x0, hint=hint, prep=prep
)
(I would stick with PEP8's 79, but it illustrates that arguments are put on one line if possible.)
The dedenting is the same effect as you noted here #22437 (comment). But yapf's default profile ("pep8
") looks worse imo:
hints = classifier(eq,
func,
dict=True,
ics=ics,
xi=xi,
eta=eta,
n=terms,
x0=x0,
hint=hint,
prep=prep)
Note that the same happens in function with many arguments:
sympy/sympy/solvers/deutils.py
Lines 143 to 152 in 357fae9
def _desolve( | |
eq, | |
func=None, | |
hint="default", | |
ics=None, | |
simplify=True, | |
*, | |
prep=True, | |
**kwargs | |
): |
For function definitions, this style is quite helpful when type hints are added.
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.
Type hints may change it, but I'm not a fan of this either. OK if it re-breaks the lines to have 80 characters, but having a separate line for each argument... (similar to the init-files)
s = BinaryQuadratic(self.equation, free_symbols=[y, x]).solve(parameters=[t, u]) | ||
s = BinaryQuadratic(self.equation, | ||
free_symbols=[y, | ||
x]).solve(parameters=[t, u]) |
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 seems like an odd choice of line breaks
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.
it's left -aligning elements at the opening bracket position if there is more than 1. It's kind of nice because you can scan vertically to see what the given brackets args are -- breadth first.
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.
Tbh I don't understand the formatting here :S It looks like this also with the default yapf profile... But with split_before_expression_after_opening_paren = True
, you get:
s = BinaryQuadratic(
self.equation, free_symbols=[y, x]
).solve(parameters=[t, u])
See d864ba2
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 guess this is another situation where an intermediate variable with a good name would be better
if ( | ||
divisible(sqa*g*z0**2 + D*z0 + sqa*F, _c) | ||
and divisible(e*sqc*g*z0**2 + E*z0 + e*sqc*F, _c) | ||
): |
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 don't understand why both black and yapf seem to prefer the unindented reverse smiley ):
.
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 the issue page on which you commented recently at black mentioned about how they tokenize and without looking ahead or back, that is just the simplest thing to do. It also visually marks the range of the if
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 don't understand why both black and yapf seem to prefer the unindented reverse smiley
):
.
Haha reverse smiley. Actually, this is not the default yapf behaviour. It's a consequence of this option, which I added to mimic black:
Lines 95 to 96 in 2d90dc1
arithmetic_precedence_indication = True | |
dedent_closing_brackets = True |
If you remove that option, you get:
if (divisible(sqa*g*z0**2 + D*z0 + sqa*F, _c) and
divisible(e*sqc*g*z0**2 + E*z0 + e*sqc*F, _c)):
result.add((solve_x(z0), solve_y(z0)))
Even if the above is more 'concise', I think the split 'black' version is easier to understand at one glance.
Note: I had hoped split_before_logical_operator = True
may improve the above a bit, but this seems to have no effect.
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.
If you remove that option, you get:
if (divisible(sqa*g*z0**2 + D*z0 + sqa*F, _c) and divisible(e*sqc*g*z0**2 + E*z0 + e*sqc*F, _c)): result.add((solve_x(z0), solve_y(z0)))
That looks more like what I would have done when editing the code myself.
4*A*r*u*v + 4*A*D*(B*v + r*u + r*v - B*u) + | ||
2*A*4*A*E*(u - v) + 4*A*r*4*A*F) | ||
4*A*r*u*v + 4*A*D*(B*v + r*u + r*v - B*u) + 2*A*4*A*E* | ||
(u-v) + 4*A*r*4*A*F |
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 is odd. I'd rather break on +
than *
.
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.
Well spotted, looks strange indeed... It seems that split_before_arithmetic_operator = True
(c9054b1) helps here, and it's also more in line with black style:
eq = _mexpand(
4*A*r*u*v + 4*A*D*(B*v + r*u + r*v - B*u)
+ 2*A*4*A*E*(u-v) + 4*A*r*4*A*F
)
s = BinaryQuadratic(self.equation, free_symbols=var[::-1]).solve(parameters=[t, u]) # Interchange x and y | ||
s = BinaryQuadratic(self.equation, | ||
free_symbols=var[::-1]).solve( | ||
parameters=[t, u] | ||
) # Interchange x and y |
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 guess this is the kind of situation where an intermediate variable would help.
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.
Last time (above) it didn't break on the single argument. I guess it did now because of line length.
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 guess this is the kind of situation where an intermediate variable would help.
True, although same as #22437 (comment), I don't really get why the formatting looks like this. But split_before_expression_after_opening_paren = True
(d864ba2) improves it:
s = BinaryQuadratic(
self.equation, free_symbols=var[::-1]
).solve(parameters=[t, u]) # Interchange x and y
Last time (above) it didn't break on the single argument. I guess it did now because of line length.
With black? Could be; black wraps at 88 by default.
I haven't been through the whole diff but this looks a lot better than black because it has much better handling of mathematical expressions. |
I agree. With the recently added commits I'm also more satisfied with the diff. So I think the current config is quite suitable. The next question is how to apply this formatting. For sure it has to be done by a bot, because this will result in a large amount of line changes ('contributions'). |
No, I think the next step is to go back to the original issue and ask for the opinions of others. I think that this is better than black but that doesn't mean I'm convinced that we should go with this (or indeed with any automatic formatting). There are many others whose inputs are needed and there needs to be something like consensus before adopting anything as invasive as this across the codebase. Actually applying the changes is straight-forward once the basic idea is agreed and the details are worked out. We don't need a bot, we just need some people to make a bunch of PRs of manageable size and then others to review and merge those PRs. |
Sounds like a good next step. I think that question about applying formatting by a bot vs individuals will still have to be discussed as well though. |
This is a follow-up demo to #22434 (now with yapf) and is not to be merged. See also #17287 (comment).
I played around a bit with the yapf configuration to improve the spacing around arithmetic operators and get it to look a bit more like black (see comparison):
sympy/setup.cfg
Lines 91 to 98 in 2d90dc1
Release Notes
NO ENTRY