[ENH] Domain Model: order without separators#2697
Conversation
janezd
left a comment
There was a problem hiding this comment.
I don't think this PR is useful.
I somebody wants to have a list without separators, he would, with this PR, call DomainModel(order=SEPARATED, separators=False). Why would one use an order with separator and then override separators? Wouldn't it make more sense to define an unseparated order instead of adding yet another argument to the function?
As for the second commit: can you justify when would one want to redefine the order? I believe that every widget has a natural order (or, if it doesn't, the order doesn't matter). Changing it would only confuse the user. Or is there a situation where you would need it?
If one changes the order when the domain is already set, he has to set the domain again? Changing the order does not make sense then. What the second commit is trying to achieve is equivalent to constructing a new model and calling setModel on a view.
In summary, the first commit could be replaced by adding an order without separators, while the second can be removed since setting a new model is a simpler and cleaner option.
| valid_types=None, alphabetical=False, skip_hidden_vars=True, **kwargs): | ||
| """ | ||
|
|
||
| :param order: How attributes, metas and classes are ordered and where between |
There was a problem hiding this comment.
How attributes (...) -> Order of attributes, metas, classes, separators and other options
|
|
||
| model = DomainModel(order=DomainModel.SEPARATED, separators=False) | ||
| model.set_domain(Domain(attrs, classes, metas)) | ||
| self.assertEqual(list(model), classes + metas + attrs) |
There was a problem hiding this comment.
What about checking whether it works with separators=True?
There was a problem hiding this comment.
I actually added this test before you responded.
|
|
||
| :param order: How attributes, metas and classes are ordered and where between | ||
| them are separators. | ||
| :param separators: Separators are ignored when set to False despite being set in order. |
There was a problem hiding this comment.
Separators are ignored -> Ignore separators.
When set to False -> When what if set to False?
I tried to reformulate the sentence, but couldn't. I believe it is because I disagree with the commit as a whole.
| :param order: How attributes, metas and classes are ordered and where between | ||
| them are separators. | ||
| :param separators: Separators are ignored when set to False despite being set in order. | ||
| :param placeholder: The first element. |
There was a problem hiding this comment.
Wrong. Placeholder is the text that is shown when no variable is selected (i.e., None). It is usually, but not necessarily, the first element.
See: https://github.com/jerneju/orange3/blob/e62c7a6b785dab00f5c619c561d4cb361636bce0/Orange/widgets/utils/itemmodels.py#L888. None is inserted at the beginning of order only if it's not already there.
| them are separators. | ||
| :param separators: Separators are ignored when set to False despite being set in order. | ||
| :param placeholder: The first element. | ||
| :param valid_types: For instance continuous, discrete, etc. variables. |
There was a problem hiding this comment.
"For instance" is an example, not a description.
| :param separators: Separators are ignored when set to False despite being set in order. | ||
| :param placeholder: The first element. | ||
| :param valid_types: For instance continuous, discrete, etc. variables. | ||
| :param alphabetical: Alphabetical order of attributes or as they are ordered in domain. |
There was a problem hiding this comment.
If true, variables are sorted alphabetically.
| :param placeholder: The first element. | ||
| :param valid_types: For instance continuous, discrete, etc. variables. | ||
| :param alphabetical: Alphabetical order of attributes or as they are ordered in domain. | ||
| :param skip_hidden_vars: hidden vars can be hidden or shown |
There was a problem hiding this comment.
This is not a description of the option. It also does not explain what are hidden vars.
| :param valid_types: For instance continuous, discrete, etc. variables. | ||
| :param alphabetical: Alphabetical order of attributes or as they are ordered in domain. | ||
| :param skip_hidden_vars: hidden vars can be hidden or shown | ||
| :param kwargs: |
|
I removed the second commit very soon after opening this PR. @janezd sorry for wasting your time. |
|
@janezd The idea would be to keep "default order", and skip separators. When you override order, I agree, it does not make sense to skip separators, as you would not include them anyway. But we would prefer to have as many widgets as possible use the default order, which should include separators where they can be displayed and not where they cannot. |
|
What is better? If the latter, I'd prefer (and no further changes in the code) since this implementation corresponds to what the change (if I understand it correctly) is actually about: the default value for
Or, if you think it's better, we keep It's a bit longer, but more explicit. |
Codecov Report
@@ Coverage Diff @@
## master #2697 +/- ##
=========================================
+ Coverage 75.83% 76.03% +0.2%
=========================================
Files 338 338
Lines 59545 59627 +82
=========================================
+ Hits 45156 45340 +184
+ Misses 14389 14287 -102 |
|
It was the latter. I would prefer to keep one default order so I would go with |
|
This is just computing the same thing every time, instead of having it precomputed and stored as a class attribute. There actually are two different defaults, it's just the question of where do you compute the second one. |
|
Ok, I changed it as you two suggested. |
| PRIMITIVE = (DiscreteVariable, ContinuousVariable) | ||
|
|
||
| def __init__(self, order=SEPARATED, placeholder=None, | ||
| def __init__(self, order=SEPARATED, separators=True, placeholder=None, |
There was a problem hiding this comment.
In general, beware of changing the parameter order or inserting arguments within the existing arguments. If anybody constructed a DomainModel by calling DomainModel(DomainModel.Primitive, "(No color)") and not DomainModel(DomainModel.Primitive, placeholder="(No color)"), this change would break his/her code.
However, we seem to have always given these arguments with keywords.
There was a problem hiding this comment.
We could also add a *, before them to make it explicit that they can only be used as keyword arguments.
There was a problem hiding this comment.
I like it. Not just here.
- It makes it easier to manipulate arguments without breaking backward compatibility.
- It forces us to name arguments in calls, which makes the code more readable and prevents making some mistakes we've made in the past.
We should at least encourage adding a * in new functions.
Issue
Cannot set order and skip separators
Description of changes
Includes