Ignore:
Timestamp:
05/30/13 15:49:29 (11 months ago)
Author:
Ales Erjavec <ales.erjavec@…>
Branch:
default
Message:

Optimization of 'ExampleTableModel.data' method.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • Orange/OrangeWidgets/Data/OWDataTable.py

    r11358 r11564  
    66<contact>Peter Juvan (peter.juvan@fri.uni-lj.si)</contact> 
    77""" 
     8 
     9import Orange 
    810 
    911from OWWidget import * 
     
    5153 
    5254class ExampleTableModel(QAbstractItemModel): 
     55    Attribute, ClassVar, ClassVars, Meta = range(4) 
     56 
    5357    def __init__(self, examples, dist, *args): 
    5458        QAbstractItemModel.__init__(self, *args) 
    5559        self.examples = examples 
     60        self.domain = examples.domain 
    5661        self.dist = dist 
    57         self.attributes = list(self.examples.domain.attributes) 
    58         self.class_var = self.examples.domain.classVar 
     62        self.attributes = list(examples.domain.attributes) 
     63        self.class_var = self.examples.domain.class_var 
     64        self.class_vars = list(self.examples.domain.class_vars) 
    5965        self.metas = self.examples.domain.getmetas().values() 
    60         self.all_attrs = self.attributes + ([self.class_var] if self.class_var else []) + self.metas 
    61         self.cls_color = QColor(160,160,160) 
    62         self.meta_color = QColor(220,220,200) 
     66        # Attributes/features for all table columns 
     67        self.all_attrs = (self.attributes + 
     68                          ([self.class_var] if self.class_var else []) + 
     69                          self.class_vars + self.metas) 
     70        # Table roles for all table columns 
     71        self.table_roles = \ 
     72            (([ExampleTableModel.Attribute] * len(self.attributes)) + 
     73             ([ExampleTableModel.ClassVar] if self.class_var else []) + 
     74             ([ExampleTableModel.ClassVars] * len(self.class_vars)) + 
     75             ([ExampleTableModel.Meta] * len(self.metas))) 
     76 
     77        # True if an feature at column i is continuous 
     78        self._continuous_mask = [isinstance(attr, Orange.feature.Continuous) 
     79                                 for attr in self.all_attrs] 
     80 
     81        self._meta_mask = [role == ExampleTableModel.Meta 
     82                           for role in self.table_roles] 
     83 
     84        self.cls_color = QColor(160, 160, 160) 
     85        self.meta_color = QColor(220, 220, 200) 
     86 
     87        role_to_color = {ExampleTableModel.Attribute: None, 
     88                         ExampleTableModel.ClassVar: self.cls_color, 
     89                         ExampleTableModel.ClassVars: self.cls_color, 
     90                         ExampleTableModel.Meta: self.meta_color} 
     91 
     92        self.background_colors = map(role_to_color.get, self.table_roles) 
     93 
    6394        self.sorted_map = range(len(self.examples)) 
    64          
    65         self.attr_labels = sorted(reduce(set.union, [attr.attributes for attr in self.all_attrs], set())) 
     95 
     96        # all attribute labels (annotation) keys 
     97        self.attr_labels = sorted( 
     98            reduce(set.union, 
     99                   [attr.attributes for attr in self.all_attrs], 
     100                   set()) 
     101        ) 
     102 
    66103        self._show_attr_labels = False 
    67104        self._other_data = {} 
    68          
     105 
    69106    def get_show_attr_labels(self): 
    70107        return self._show_attr_labels 
    71      
     108 
    72109    def set_show_attr_labels(self, val): 
    73110        self.emit(SIGNAL("layoutAboutToBeChanged()")) 
    74111        self._show_attr_labels = val 
    75112        self.emit(SIGNAL("headerDataChanged(Qt::Orientation, int, int)"), 
    76                   Qt.Horizontal,  
    77                   0,  
     113                  Qt.Horizontal, 
     114                  0, 
    78115                  len(self.all_attrs) - 1 
    79116                  ) 
    80117        self.emit(SIGNAL("layoutChanged()")) 
    81         self.emit(SIGNAL("dataChanged(QModelIndex, QModelIndex)"),  
    82                   self.index(0,0), 
     118        self.emit(SIGNAL("dataChanged(QModelIndex, QModelIndex)"), 
     119                  self.index(0, 0), 
    83120                  self.index(len(self.examples) - 1, len(self.all_attrs) - 1) 
    84121                  ) 
    85          
    86     show_attr_labels = pyqtProperty("bool",  
    87                                    fget=get_show_attr_labels, 
    88                                    fset=set_show_attr_labels, 
    89                                    ) 
    90      
    91     @safe_call 
    92     def data(self, index, role): 
     122 
     123    show_attr_labels = pyqtProperty("bool", 
     124                                    fget=get_show_attr_labels, 
     125                                    fset=set_show_attr_labels) 
     126 
     127    def data(self, index, role, 
     128             # For optimizing out LOAD_GLOBAL byte code instructions in 
     129             # the item role tests (goes from 14 us to 9 us average). 
     130             _str=str, 
     131             _Qt_DisplayRole=Qt.DisplayRole, 
     132             _Qt_BackgroundRole=Qt.BackgroundRole, 
     133             _OWGUI_TableBarItem_BarRole=OWGUI.TableBarItem.BarRole, 
     134             _OWGUI_TableValueRole=OWGUI.TableValueRole, 
     135             _OWGUI_TableClassValueRole=OWGUI.TableClassValueRole, 
     136             _OWGUI_TableVariable=OWGUI.TableVariable, 
     137             # Some cached local precomputed values. 
     138             # All of the above roles we respond to 
     139             _recognizedRoles=set([Qt.DisplayRole, 
     140                                   Qt.BackgroundRole, 
     141                                   OWGUI.TableBarItem.BarRole, 
     142                                   OWGUI.TableValueRole, 
     143                                   OWGUI.TableClassValueRole, 
     144                                   OWGUI.TableVariable]), 
     145             ): 
     146        """ 
     147        Return the data for `role` for an value at `index`. 
     148        """ 
     149        if role not in _recognizedRoles: 
     150            return self._other_data.get((index.row(), index.column(), role), 
     151                                        None) 
     152 
    93153        row, col = self.sorted_map[index.row()], index.column() 
    94154        example, attr = self.examples[row], self.all_attrs[col] 
     155 
    95156        val = example[attr] 
    96         domain = self.examples.domain 
    97         if role == Qt.DisplayRole: 
    98                 return QVariant(str(val)) 
    99         elif role == Qt.BackgroundRole: 
    100             #check if attr is actual class or a duplication in the meta attributes 
    101             if attr == self.class_var and col == len(domain.attributes) and domain.classVar: 
    102                 return QVariant(self.cls_color) 
    103             elif attr in self.metas: 
    104                 return QVariant(self.meta_color) 
    105         elif role == OWGUI.TableBarItem.BarRole and val.varType == orange.VarTypes.Continuous \ 
    106                     and not val.isSpecial() and attr not in self.metas: 
     157 
     158        if role == _Qt_DisplayRole: 
     159            return _str(val) 
     160        elif role == _Qt_BackgroundRole: 
     161            return self.background_colors[col] 
     162        elif role == _OWGUI_TableBarItem_BarRole and \ 
     163                self._continuous_mask[col] and not val.isSpecial() and \ 
     164                col < len(self.dist): 
    107165            dist = self.dist[col] 
    108             return QVariant((float(val) - dist.min) / (dist.max - dist.min or 1)) 
    109         elif role == OWGUI.TableValueRole: 
    110             # The actual value 
    111             return QVariant(val) 
    112         elif role == OWGUI.TableClassValueRole:  
     166            return (float(val) - dist.min) / (dist.max - dist.min or 1) 
     167        elif role == _OWGUI_TableValueRole: 
     168            # The actual value instance (should it be EditRole?) 
     169            return val 
     170        elif role == _OWGUI_TableClassValueRole and self.class_var is not None: 
    113171            # The class value for the row's example 
    114             return QVariant(example.get_class()) 
    115         elif role == OWGUI.TableVariable:  
     172            return example.get_class() 
     173        elif role == _OWGUI_TableVariable: 
    116174            # The variable descriptor for column 
    117             return QVariant(val.variable) 
    118          
    119         return self._other_data.get((index.row(), index.column(), role), QVariant()) 
    120          
     175            return attr 
     176 
     177        return None 
     178 
    121179    def setData(self, index, variant, role): 
    122180        self._other_data[index.row(), index.column(), role] = variant 
     
    668726             
    669727        self.selectionChangedFlag = False 
    670              
    671          
    672  
    673 if __name__=="__main__": 
     728 
     729 
     730def test(): 
    674731    a = QApplication(sys.argv) 
    675732    ow = OWDataTable() 
    676733 
    677     #d1 = orange.ExampleTable(r'..\..\doc\datasets\auto-mpg') 
    678     #d2 = orange.ExampleTable('test-labels') 
    679     #d3 = orange.ExampleTable(r'..\..\doc\datasets\sponge.tab') 
    680     #d4 = orange.ExampleTable(r'..\..\doc\datasets\wpbc.csv') 
    681     d5 = orange.ExampleTable('../../doc/datasets/adult_sample.tab') 
    682     #d5 = orange.ExampleTable(r"E:\Development\Orange Datasets\UCI\wine.tab") 
    683 #    d5 = orange.ExampleTable("adult_sample") 
    684 #    d5 = orange.ExampleTable("/home/marko/tdw") 
    685     #d5 = orange.ExampleTable(r"e:\Development\Orange Datasets\Cancer\SRBCT.tab") 
     734    d1 = orange.ExampleTable("auto-mpg") 
     735    d2 = orange.ExampleTable("sponge.tab") 
     736    d3 = orange.ExampleTable("wpbc.csv") 
     737    d4 = orange.ExampleTable("adult_sample.tab") 
     738    d5 = orange.ExampleTable("wine.tab") 
     739 
    686740    ow.show() 
    687     #ow.dataset(d1,"auto-mpg") 
    688     #ow.dataset(d2,"voting") 
    689     #ow.dataset(d4,"wpbc") 
    690     ow.dataset(d5,"adult_sample") 
     741    ow.dataset(d1, "auto-mpg") 
     742    ow.dataset(d2, "sponge") 
     743    ow.dataset(d3, "wpbc") 
     744    ow.dataset(d4, "adult_sample") 
     745    ow.dataset(d5, "wine") 
    691746    a.exec_() 
    692747    ow.saveSettings() 
     748 
     749 
     750if __name__ == "__main__": 
     751    test() 
Note: See TracChangeset for help on using the changeset viewer.