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

Use strings for colors in Python tutorials #17026

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

guitargeek
Copy link
Contributor

@guitargeek guitargeek commented Nov 25, 2024

This makes the code less verbose and more pythonic.

Sister PR in roottest:
root-project/roottest#1227

@linev
Copy link
Member

linev commented Nov 25, 2024

I would provide return value for all Set...Color methods with color index.
One could check then if method really changed something.

@guitargeek
Copy link
Contributor Author

I know, that would be nice, but the existing versions of the Set*Color( methods are virtual, so we can't change their return types without causing incompatibilities :(
For example:
https://github.com/root-project/root/blob/master/core/base/inc/TAttLine.h#L40

h_cmb.SetLineWidth(2)
h_cmb.SetMaximum(18)
h_cmb.SetStats(False)

h_bkg.SetLineWidth(2)
h_bkg.SetFillStyle(1001)
h_bkg.SetLineColor(ROOT.kBlack)
h_bkg.SetFillColor(ROOT.kAzure - 9)
h_bkg.SetLineColor("kBlack")
Copy link
Member

Choose a reason for hiding this comment

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

What is the typical Python behavior if the name is incorrect spelt? I.e. should the new SetLineColor (and co) print an error message?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right now, it will just silently do nothing. Not sure yet if this should be treated as an Error: also when you call the old SetLineColor() with an invalid integer, it doesn't complain, and when drawing it falls back to black.

Copy link
Member

Choose a reason for hiding this comment

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

For reference, an arbitrary example of what is done by a python library:

>>> color_name_to_rgba("unknown")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/igraph/drawing/colors.py", line 517, in color_name_to_rgba
    components = palette.get(int(color))
                 ^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'

So I guess the answer to my original question is likely 'throw' an exception that is caught by the interpreter.

also when you call the old SetLineColor() with an invalid integer,

The difference is that with: SetColor(some_arbitrary_number), I might expect to have to check the return value, since there is no reason to expect that all numbers are valid. With SetColor(ROOT.kBlue), I am guaranteed that it just works (if it misspelt there will be am interpretation error). With SetColor("Bleue"), I confident I got it right, humm or did I spelt in French :).

More concretely, if the goal is to be "more pythonic." we should also seriously consider applying the python recommendation on how to handle those kind of error cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right, the cases are not comparable. Would raising a std::invalid_argument be okay for you?

It would look like this:

Traceback (most recent call last):
  File "/home/rembserj/spaces/master/root/src/root/test.py", line 5, in <module>
    h.SetLineColor("kReed")
cppyy.gbl.std.invalid_argument: void TAttLine::SetLineColor(const string& lcolor) =>
    invalid_argument: "kReed" is not a valid color name

Copy link
Member

Choose a reason for hiding this comment

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

Sounds fair.

@guitargeek guitargeek force-pushed the enum_pythonizations branch 10 times, most recently from ec0d74e to 865e2a1 Compare November 25, 2024 22:49
@guitargeek guitargeek closed this Nov 26, 2024
@guitargeek guitargeek reopened this Nov 26, 2024
Copy link

github-actions bot commented Nov 26, 2024

Test Results

    18 files      18 suites   3d 23h 29m 0s ⏱️
 2 678 tests  2 678 ✅ 0 💤 0 ❌
46 490 runs  46 490 ✅ 0 💤 0 ❌

Results for commit 8ff4f78.

♻️ This comment has been updated with latest results.

@guitargeek guitargeek force-pushed the enum_pythonizations branch 2 times, most recently from 75ed8cc to 259809c Compare November 27, 2024 12:29
@guitargeek guitargeek requested a review from aaronj0 November 27, 2024 12:58
@couet couet removed their request for review December 4, 2024 09:21
Copy link
Member

@pcanal pcanal left a comment

Choose a reason for hiding this comment

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

LGTM but we need to rebase ...

These new overloads are intended for use via Python.

This generalizes a pythonization that has been so far localized to
RooFit.
This makes the code less verbose and more pythonic.
This allows pass Python tuples to any of the `Set*Color` methods.
@guitargeek
Copy link
Contributor Author

Thanks for the ping @pcanal! Is it okay now? Could you approve together with the roottest PR?

By the way there was recently a forum discussion about color names in Python, which tells us again that this is a feature that our users will appreciate:
https://root-forum.cern.ch/t/color-names-in-python/62543/3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants