1+ import enum
2+
13from collections import OrderedDict
24from itertools import chain
35
1416from Orange .data import (ContinuousVariable , DiscreteVariable , StringVariable ,
1517 Table , TimeVariable )
1618import Orange .data .filter as data_filter
19+ from Orange .data .filter import FilterContinuous , FilterString
1720from Orange .data .domain import filter_visible
1821from Orange .data .sql .table import SqlTable
1922from Orange .preprocess import Remove
@@ -32,6 +35,13 @@ def is_valid_item(self, setting, condition, attrs, metas):
3235 return varname in attrs or varname in metas
3336
3437
38+ class FilterDiscreteType (enum .Enum ):
39+ Equal = "Equal"
40+ NotEqual = "NotEqual"
41+ In = "In"
42+ IsDefined = "IsDefined"
43+
44+
3545class OWSelectRows (widget .OWWidget ):
3646 name = "Select Rows"
3747 id = "Orange.widgets.data.file"
@@ -51,20 +61,43 @@ class OWSelectRows(widget.OWWidget):
5161 purge_classes = Setting (True )
5262 auto_commit = Setting (True )
5363
54- operator_names = {
55- ContinuousVariable : ["equals" , "is not" ,
56- "is below" , "is at most" ,
57- "is greater than" , "is at least" ,
58- "is between" , "is outside" ,
59- "is defined" ],
60- DiscreteVariable : ["is" , "is not" , "is one of" , "is defined" ],
61- StringVariable : ["equals" , "is not" ,
62- "is before" , "is equal or before" ,
63- "is after" , "is equal or after" ,
64- "is between" , "is outside" , "contains" ,
65- "begins with" , "ends with" ,
66- "is defined" ]}
67- operator_names [TimeVariable ] = operator_names [ContinuousVariable ]
64+ Operators = {
65+ ContinuousVariable : [
66+ (FilterContinuous .Equal , "equals" ),
67+ (FilterContinuous .NotEqual , "is not" ),
68+ (FilterContinuous .Less , "is below" ),
69+ (FilterContinuous .LessEqual , "is at most" ),
70+ (FilterContinuous .Greater ,"is greater than" ),
71+ (FilterContinuous .GreaterEqual , "is at least" ),
72+ (FilterContinuous .Between , "is between" ),
73+ (FilterContinuous .Outside , "is outside" ),
74+ (FilterContinuous .IsDefined , "is defined" ),
75+ ],
76+ DiscreteVariable : [
77+ (FilterDiscreteType .Equal , "is" ),
78+ (FilterDiscreteType .NotEqual , "is not" ),
79+ (FilterDiscreteType .In , "is one of" ),
80+ (FilterDiscreteType .IsDefined , "is defined" )
81+ ],
82+ StringVariable : [
83+ (FilterString .Equal , "equals" ),
84+ (FilterString .NotEqual , "is not" ),
85+ (FilterString .Less , "is before" ),
86+ (FilterString .LessEqual , "is equal or before" ),
87+ (FilterString .Greater , "is after" ),
88+ (FilterString .GreaterEqual , "is equal or after" ),
89+ (FilterString .Between , "is between" ),
90+ (FilterString .Outside , "is outside" ),
91+ (FilterString .Contains , "contains" ),
92+ (FilterString .StartsWith , "begins with" ),
93+ (FilterString .EndsWith , "ends with" ),
94+ (FilterString .IsDefined , "is defined" ),
95+ ]
96+ }
97+ Operators [TimeVariable ] = Operators [ContinuousVariable ]
98+
99+ operator_names = {vtype : [name for _ , name in filters ]
100+ for vtype , filters in Operators .items ()}
68101
69102 def __init__ (self ):
70103 super ().__init__ ()
@@ -199,8 +232,8 @@ def set_new_operators(self, attr_combo, adding_all,
199232 var = self .data .domain [attr_combo .currentText ()]
200233 oper_combo .addItems (self .operator_names [type (var )])
201234 oper_combo .setCurrentIndex (selected_index or 0 )
202- self .set_new_values (oper_combo , adding_all , selected_values )
203235 self .cond_list .setCellWidget (oper_combo .row , 1 , oper_combo )
236+ self .set_new_values (oper_combo , adding_all , selected_values )
204237 oper_combo .currentIndexChanged .connect (
205238 lambda _ : self .set_new_values (oper_combo , False ))
206239
@@ -338,14 +371,17 @@ def set_data(self, data):
338371 except Exception :
339372 pass
340373
341- if not self .conditions and len (data .domain .variables ):
374+ variables = list (filter_visible (chain (data .domain .variables ,
375+ data .domain .metas )))
376+ varnames = [v .name for v in variables ]
377+ if self .conditions :
378+ for attr , cond_type , cond_value in self .conditions :
379+ if attr in varnames :
380+ self .add_row (varnames .index (attr ), cond_type , cond_value )
381+ elif variables :
342382 self .add_row ()
383+
343384 self .update_info (data , self .data_in_variables , "In: " )
344- for attr , cond_type , cond_value in self .conditions :
345- attrs = [a .name for a in
346- filter_visible (chain (data .domain .variables , data .domain .metas ))]
347- if attr in attrs :
348- self .add_row (attrs .index (attr ), cond_type , cond_value )
349385 self .unconditional_commit ()
350386
351387 def conditions_changed (self ):
@@ -372,10 +408,11 @@ def commit(self):
372408 if self .data :
373409 domain = self .data .domain
374410 conditions = []
375- for attr_name , oper , values in self .conditions :
411+ for attr_name , oper_idx , values in self .conditions :
376412 attr_index = domain .index (attr_name )
377413 attr = domain [attr_index ]
378-
414+ operators = self .Operators [type (attr )]
415+ opertype , _ = operators [oper_idx ]
379416 if attr .is_continuous :
380417 if any (not v for v in values ):
381418 continue
@@ -389,23 +426,23 @@ def commit(self):
389426 return
390427
391428 filter = data_filter .FilterContinuous (
392- attr_index , oper , * [float (v ) for v in values ])
429+ attr_index , opertype , * [float (v ) for v in values ])
393430 elif attr .is_string :
394431 filter = data_filter .FilterString (
395- attr_index , oper , * [str (v ) for v in values ])
432+ attr_index , opertype , * [str (v ) for v in values ])
396433 else :
397- if oper == 3 :
434+ if opertype == FilterDiscreteType . IsDefined :
398435 f_values = None
399436 else :
400437 if not values or not values [0 ]:
401438 continue
402439 values = [attr .values [i - 1 ] for i in values ]
403- if oper == 0 :
440+ if opertype == FilterDiscreteType . Equal :
404441 f_values = {values [0 ]}
405- elif oper == 1 :
442+ elif opertype == FilterDiscreteType . NotEqual :
406443 f_values = set (attr .values )
407444 f_values .remove (values [0 ])
408- elif oper == 2 :
445+ elif opertype == FilterDiscreteType . In :
409446 f_values = set (values )
410447 else :
411448 raise ValueError ("invalid operand" )
0 commit comments