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
LatticePoset creation, better error reporting #19163
Comments
Commit: |
Branch pushed to git repo; I updated commit sha1. New commits:
|
comment:3
This is ready for comments, even if it is not ready for review. |
Branch pushed to git repo; I updated commit sha1. New commits:
|
comment:5
Jeroen, can you check this until I do more? I.e. is This is kind of first time when I add something more than new functions to existing classes. |
comment:6
Replying to @jm58660:
Ping... |
Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:
|
This comment has been minimized.
This comment has been minimized.
Author: Jori Mäntysalo |
comment:8
As I got no comments for custom error class, I did this with string manipulation. |
comment:9
Daniel? This is more trivial than you could think from number of lines. |
comment:10
I think this approach of parsing the error message just makes things needlessly more complicated (and takes extra time if you, say, want to check if a set of posets are meet-semilattices). Instead, I would just allow the error from calling |
comment:11
Replying to @tscrim:
?? Error message is only parsed when there is a message. And to just check use
It is very irritating if the elements of the lattice are integers. Then we may got error saying that 5 and 8 have no meet, when actually it is 6 and 10 that have no meet. |
comment:12
Replying to @jm58660:
Suppose you iterate over a collection of posets and you want to determine which of them are (semi)lattices. Then for those that are lattices, you do some extra processing on them. Being Pythonic (and to avoid double checking things), you just cast the poset to a lattice and do nothing if an error is thrown. That is where the slowdown comes in.
That is a good point. However, I would much rather have a less informative error message than the (IMO fugly) string parsing code you currently have. It seems like Volker's suggestion of doing a custom error class will be what you want (if you think it is important to see (only) one instance where the lattice property fails). |
comment:13
Replying to @tscrim:
You mean something like
where
I guess this conflicts with performance you cared in a paragraph just before this one Actually I did a code using specific error class and tried to get comments on it, to be sure that I did nothing stupid. But as I got no comments, I decided to do this in a way that I know to work. (And added tests, so that if somebody changes the error string at |
comment:14
I tested with a list of all non-isomorphic posets of 8 elements. There are 16999 of those. Before the patch it took 0,69 seconds to run my test code for the first time. Second run took 0,39 seconds. After the patch timings were 0,70 and 0,41 second. So this will take something like 15 ms for 15000 posets, i.e. a microsecond per poset. (At i5-3470 CPU @ 3.20GHz). I think that this in not too much penalty for better usability. |
comment:15
Thanks for doing those timings. I didn't expect too much of a penalty, but if we can have cleaner and less fragile code with extra speed, then why shouldn't we? I would say the lack of response for your question (if it was "Am I doing something stupid?") is a strong indication that you are not. Personally, I don't think we need to include this in the error message as pdb can be used, but I'm neutral if we add it responsibly. In more detail, the fragility comes from the fact that we have to rewrite this error message if the underlying error message changes wording. By having a custom class, it means we can easily change the message without having to rewrite this (essentially unrelated) code. Also, the class LatticeException(ValueError):
def __init__(self, fail, x, y):
ValueError.__init__(self, None)
self.fail = fail
self.x = x
self.y = y
def __str__(self):
return "no {} for {} and {}".format(self.fail, self.x, self.y) The result would look like this:
|
comment:16
Replying to @tscrim:
No. I do not trust silence being acception. But see my commit on comment number 3. I guess it was something like what you suggested.
That's why I added tests. We could also add a comment to the code raising exception in
Maybe I can optimize if, it one microsecond is too much... |
comment:17
Replying to @jm58660:
Then consider this as acceptance of doing a custom error message (along with Volker's comment on the sage-devel thread). |
comment:18
Replying to @jm58660:
It's not about the tests; it is about the fact you have to change code in the frontend class anytime you change this error message in the backend. An analogy would be like you changed the background color attribute in a css file, but now you have to change html code of the webpage because of that.
That was mainly as a counterpoint to your statement creating objects is more costly than string parsing. I strongly believe string parsing is an evil practice. The fact that it is (micro) slower is just a small part of that belief. The much bigger issue is the readability, extendability, and fragility of the code. |
This comment has been minimized.
This comment has been minimized.
comment:33
Replying to @tscrim:
This is still an issue, both for readability and performance. I can write a modified version if you want. |
comment:34
Replying to @tscrim:
Please do so, as I think that I don't understand what you mean. |
comment:35
Replying to @jm58660:
Just pingin this. |
comment:36
Another ping. I don't get what you suggest until I see a code or at least a pseudocode. |
comment:37
Sorry it took so long, kept having other things come up. Here is what I am suggesting, where we don't recreate the error, just trap it long enough to change the element labels. New commits:
|
Reviewer: Travis Scrimshaw |
comment:38
Now I understand: Green solution, recycling of error message! Also test passed, and I manually checked meet- and join-semilattices. Hence positive review. Replying to @tscrim:
No horry. I have said to some developer (you?) earlier: it took about 2000 years to proof that squaring a circle is impossible. So there is no horry, this is mathematics. |
Changed reviewer from Travis Scrimshaw to Travis Scrimshaw, Jori Mäntysalo |
Changed author from Jori Mäntysalo to Jori Mäntysalo, Travis Scrimshaw |
Changed branch from u/tscrim/lattice_errors-19163 to |
There is an error in current exception for join-semilattices:
gives
i.e. the message is wrong for
_join
.What's more, currently sage outputs only
ValueError: Not a lattice.
when creating a lattice. After this it will outputValueError: Not a lattice: no meet for e and d.
CC: @dkrenn
Component: combinatorics
Author: Jori Mäntysalo, Travis Scrimshaw
Branch/Commit:
7d6e21b
Reviewer: Travis Scrimshaw, Jori Mäntysalo
Issue created by migration from https://trac.sagemath.org/ticket/19163
The text was updated successfully, but these errors were encountered: