Ignore:
Files:
3 added
27 edited

Legend:

Unmodified
Added
Removed
  • .hgignore

    r10825 r11577  
    3232 
    3333# Ignore files created by setup.py. 
     34_build 
    3435build 
    3536dist 
  • .hgtags

    r11530 r11554  
    6684d3895ad2a55acb7e69173e22314a602c87a29f 2.6 
    778adaabe1a15bdc88d3baa633042c02c1a7bc7fa9 2.6.1 
     819b97395b702366db35cc58615e3d016ce1c9701 2.7 
  • MANIFEST.in

    r11537 r11552  
    2121exclude source/orangene/lib_vectors.cpp 
    2222 
    23 recursive-include docs *.rst *.py *.png *.css *.txt Makefile 
     23recursive-include docs *.rst *.py *.png *.gif *.css *.txt *.tab *.basket *.arff *.csv *.res Makefile 
     24prune docs/build 
    2425 
    2526graft docs/sphinx-ext 
  • Orange/OrangeCanvas/application/canvasmain.py

    r11547 r11557  
    434434            QAction(self.tr("Get Started"), self, 
    435435                    objectName="get-started-action", 
    436                     toolTip=self.tr("View a 'Getting Started' video."), 
     436                    toolTip=self.tr("View a 'Get Started' introduction."), 
    437437                    triggered=self.get_started, 
    438438                    icon=canvas_icons("Get Started.svg") 
  • Orange/OrangeCanvas/canvas/scene.py

    r11464 r11558  
    771771        return items[0] if items else None 
    772772 
    773     if PYQT_VERSION_STR < "4.9": 
     773    if map(int, PYQT_VERSION_STR.split('.')) < [4, 9]: 
    774774        # For QGraphicsObject subclasses items, itemAt ... return a 
    775775        # QGraphicsItem wrapper instance and not the actual class instance. 
  • Orange/OrangeCanvas/scheme/widgetsscheme.py

    r11540 r11563  
    1717 
    1818""" 
     19import sys 
    1920import logging 
    2021 
     
    392393                handler(*args) 
    393394            except Exception: 
    394                 log.exception("Error") 
     395                sys.excepthook(*sys.exc_info()) 
     396                log.exception("Error calling '%s' of '%s'", 
     397                              handler.__name__, node.title) 
    395398            finally: 
    396399                app.restoreOverrideCursor() 
     
    400403            widget.handleNewSignals() 
    401404        except Exception: 
    402             log.exception("Error") 
     405            sys.excepthook(*sys.exc_info()) 
     406            log.exception("Error calling 'handleNewSignals()' of '%s'", 
     407                          node.title) 
    403408        finally: 
    404409            app.restoreOverrideCursor() 
  • Orange/OrangeWidgets/Data/OWDataTable.py

    r11358 r11573  
    77""" 
    88 
     9from xml.sax.saxutils import escape 
     10import Orange 
     11 
    912from OWWidget import * 
    1013import OWGUI 
     
    1316import OWColorPalette 
    1417 
    15  
    1618NAME = "Data Table" 
    1719 
     
    3638           ("Other Data", ExampleTable)] 
    3739 
    38 ############################################################################## 
    39  
    40 def safe_call(func): 
    41     from functools import wraps 
    42     @wraps(func) 
    43     def wrapper(*args, **kwargs): 
    44         try: 
    45             return func(*args, **kwargs) 
    46         except Exception, ex: 
    47             print >> sys.stderr, func.__name__, "call error", ex  
    48             return QVariant() 
    49     return wrapper 
    50      
     40 
     41def header_text(feature, labels=None): 
     42    """ 
     43    Return an header text for an `Orange.feature.Descriptor` instance 
     44    `feature`. If labels is not none it should be a sequence of keys into 
     45    `feature.attributes` to include in the header (one per line). If the 
     46    `feature.attribures` does not contain a value for the key the returned 
     47    text will include an empty line for it. 
     48 
     49    """ 
     50    lines = [feature.name] 
     51    if labels is not None: 
     52        lines += [str(feature.attributes.get(label, "")) 
     53                  for label in labels] 
     54    return "\n".join(lines) 
     55 
     56 
     57def header_tooltip(feature, labels=None): 
     58    """ 
     59    Return an header tooltip text for an `Orange.feature.Decriptor` instance. 
     60    """ 
     61 
     62    if labels is None: 
     63        labels = feature.attributes.keys() 
     64 
     65    pairs = [(escape(key), escape(str(feature.attributes[key]))) 
     66             for key in labels if key in feature.attributes] 
     67    tip = "<b>%s</b>" % escape(feature.name) 
     68    tip = "<br/>".join([tip] + ["%s = %s" % pair for pair in pairs]) 
     69    return tip 
     70 
    5171 
    5272class ExampleTableModel(QAbstractItemModel): 
     73    Attribute, ClassVar, ClassVars, Meta = range(4) 
     74 
    5375    def __init__(self, examples, dist, *args): 
    5476        QAbstractItemModel.__init__(self, *args) 
    5577        self.examples = examples 
     78        self.domain = examples.domain 
    5679        self.dist = dist 
    57         self.attributes = list(self.examples.domain.attributes) 
    58         self.class_var = self.examples.domain.classVar 
     80        self.attributes = list(examples.domain.attributes) 
     81        self.class_var = self.examples.domain.class_var 
     82        self.class_vars = list(self.examples.domain.class_vars) 
    5983        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) 
     84        # Attributes/features for all table columns 
     85        self.all_attrs = (self.attributes + 
     86                          ([self.class_var] if self.class_var else []) + 
     87                          self.class_vars + self.metas) 
     88        # Table roles for all table columns 
     89        self.table_roles = \ 
     90            (([ExampleTableModel.Attribute] * len(self.attributes)) + 
     91             ([ExampleTableModel.ClassVar] if self.class_var else []) + 
     92             ([ExampleTableModel.ClassVars] * len(self.class_vars)) + 
     93             ([ExampleTableModel.Meta] * len(self.metas))) 
     94 
     95        # True if an feature at column i is continuous 
     96        self._continuous_mask = [isinstance(attr, Orange.feature.Continuous) 
     97                                 for attr in self.all_attrs] 
     98 
     99        self._meta_mask = [role == ExampleTableModel.Meta 
     100                           for role in self.table_roles] 
     101 
     102        self.cls_color = QColor(160, 160, 160) 
     103        self.meta_color = QColor(220, 220, 200) 
     104 
     105        role_to_color = {ExampleTableModel.Attribute: None, 
     106                         ExampleTableModel.ClassVar: self.cls_color, 
     107                         ExampleTableModel.ClassVars: self.cls_color, 
     108                         ExampleTableModel.Meta: self.meta_color} 
     109 
     110        self.background_colors = map(role_to_color.get, self.table_roles) 
     111 
     112        # all attribute labels (annotation) keys 
     113        self.attr_labels = sorted( 
     114            reduce(set.union, 
     115                   [attr.attributes for attr in self.all_attrs], 
     116                   set()) 
     117        ) 
     118 
     119        # text for all header items (no attr labels by default) 
     120        self.header_labels = [header_text(feature) 
     121                              for feature in self.all_attrs] 
     122 
    63123        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())) 
     124 
    66125        self._show_attr_labels = False 
    67126        self._other_data = {} 
    68          
     127 
    69128    def get_show_attr_labels(self): 
    70129        return self._show_attr_labels 
    71      
     130 
    72131    def set_show_attr_labels(self, val): 
    73         self.emit(SIGNAL("layoutAboutToBeChanged()")) 
    74         self._show_attr_labels = val 
    75         self.emit(SIGNAL("headerDataChanged(Qt::Orientation, int, int)"), 
    76                   Qt.Horizontal,  
    77                   0,  
    78                   len(self.all_attrs) - 1 
    79                   ) 
    80         self.emit(SIGNAL("layoutChanged()")) 
    81         self.emit(SIGNAL("dataChanged(QModelIndex, QModelIndex)"),  
    82                   self.index(0,0), 
    83                   self.index(len(self.examples) - 1, len(self.all_attrs) - 1) 
    84                   ) 
    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): 
     132        if self._show_attr_labels != val: 
     133            self.emit(SIGNAL("layoutAboutToBeChanged()")) 
     134            self._show_attr_labels = val 
     135            if val: 
     136                labels = self.attr_labels 
     137            else: 
     138                labels = None 
     139            self.header_labels = [header_text(feature, labels) 
     140                                  for feature in self.all_attrs] 
     141 
     142            self.emit(SIGNAL("headerDataChanged(Qt::Orientation, int, int)"), 
     143                      Qt.Horizontal, 
     144                      0, 
     145                      len(self.all_attrs) - 1) 
     146 
     147            self.emit(SIGNAL("layoutChanged()")) 
     148 
     149            self.emit(SIGNAL("dataChanged(QModelIndex, QModelIndex)"), 
     150                      self.index(0, 0), 
     151                      self.index(len(self.examples) - 1, 
     152                                 len(self.all_attrs) - 1) 
     153                      ) 
     154 
     155    show_attr_labels = pyqtProperty("bool", 
     156                                    fget=get_show_attr_labels, 
     157                                    fset=set_show_attr_labels) 
     158 
     159    def data(self, index, role, 
     160             # For optimizing out LOAD_GLOBAL byte code instructions in 
     161             # the item role tests (goes from 14 us to 9 us average). 
     162             _str=str, 
     163             _Qt_DisplayRole=Qt.DisplayRole, 
     164             _Qt_BackgroundRole=Qt.BackgroundRole, 
     165             _OWGUI_TableBarItem_BarRole=OWGUI.TableBarItem.BarRole, 
     166             _OWGUI_TableValueRole=OWGUI.TableValueRole, 
     167             _OWGUI_TableClassValueRole=OWGUI.TableClassValueRole, 
     168             _OWGUI_TableVariable=OWGUI.TableVariable, 
     169             # Some cached local precomputed values. 
     170             # All of the above roles we respond to 
     171             _recognizedRoles=set([Qt.DisplayRole, 
     172                                   Qt.BackgroundRole, 
     173                                   OWGUI.TableBarItem.BarRole, 
     174                                   OWGUI.TableValueRole, 
     175                                   OWGUI.TableClassValueRole, 
     176                                   OWGUI.TableVariable]), 
     177             ): 
     178        """ 
     179        Return the data for `role` for an value at `index`. 
     180        """ 
     181        if role not in _recognizedRoles: 
     182            return self._other_data.get((index.row(), index.column(), role), 
     183                                        None) 
     184 
    93185        row, col = self.sorted_map[index.row()], index.column() 
    94186        example, attr = self.examples[row], self.all_attrs[col] 
     187 
    95188        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: 
     189 
     190        if role == _Qt_DisplayRole: 
     191            return _str(val) 
     192        elif role == _Qt_BackgroundRole: 
     193            return self.background_colors[col] 
     194        elif role == _OWGUI_TableBarItem_BarRole and \ 
     195                self._continuous_mask[col] and not val.isSpecial() and \ 
     196                col < len(self.dist): 
    107197            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:  
     198            return (float(val) - dist.min) / (dist.max - dist.min or 1) 
     199        elif role == _OWGUI_TableValueRole: 
     200            # The actual value instance (should it be EditRole?) 
     201            return val 
     202        elif role == _OWGUI_TableClassValueRole and self.class_var is not None: 
    113203            # The class value for the row's example 
    114             return QVariant(example.get_class()) 
    115         elif role == OWGUI.TableVariable:  
     204            return example.get_class() 
     205        elif role == _OWGUI_TableVariable: 
    116206            # The variable descriptor for column 
    117             return QVariant(val.variable) 
    118          
    119         return self._other_data.get((index.row(), index.column(), role), QVariant()) 
    120          
     207            return attr 
     208 
     209        return None 
     210 
    121211    def setData(self, index, variant, role): 
    122212        self._other_data[index.row(), index.column(), role] = variant 
     
    133223            return 0 
    134224        else: 
    135             return max([len(self.examples)] + [row for row, _, _ in self._other_data.keys()]) 
    136          
    137     def columnCount(self, index=QModelIndex()): 
    138         return max([len(self.all_attrs)] + [col for _, col, _ in self._other_data.keys()]) 
    139      
    140     @safe_call 
     225            return len(self.examples) 
     226 
     227    def columnCount(self, parent=QModelIndex()): 
     228        if parent.isValid(): 
     229            return 0 
     230        else: 
     231            return len(self.all_attrs) 
     232 
    141233    def headerData(self, section, orientation, role): 
    142234        if orientation == Qt.Horizontal: 
    143235            attr = self.all_attrs[section] 
    144             if role ==Qt.DisplayRole: 
    145                 values = [attr.name] + ([str(attr.attributes.get(label, "")) for label in self.attr_labels] if self.show_attr_labels else []) 
    146                 return QVariant("\n".join(values)) 
     236            if role == Qt.DisplayRole: 
     237                return self.header_labels[section] 
    147238            if role == Qt.ToolTipRole: 
    148                 pairs = [(key, str(attr.attributes[key])) for key in self.attr_labels if key in attr.attributes] 
    149                 tip = "<b>%s</b>" % attr.name 
    150                 tip = "<br>".join([tip] + ["%s = %s" % pair for pair in pairs]) 
    151                 return QVariant(tip)   
     239                return header_tooltip(attr, self.attr_labels) 
    152240        else: 
    153241            if role == Qt.DisplayRole: 
    154242                return QVariant(section + 1) 
    155243        return QVariant() 
    156      
     244 
    157245    def sort(self, column, order=Qt.AscendingOrder): 
    158246        self.emit(SIGNAL("layoutAboutToBeChanged()")) 
     
    302390            self.selectedSchemaIndex = dlg.selectedSchemaIndex 
    303391            self.discPalette = dlg.getDiscretePalette("discPalette") 
    304             self.distColorRgb = dlg.getColor("Default") 
     392            self.distColor = color = dlg.getColor("Default") 
     393            self.distColorRgb = (color.red(), color.green(), color.red()) 
     394 
     395            if self.showDistributions: 
     396                # Update the views 
     397                self.cbShowDistributions() 
    305398 
    306399    def increaseColWidth(self): 
     
    668761             
    669762        self.selectionChangedFlag = False 
    670              
    671          
    672  
    673 if __name__=="__main__": 
     763 
     764 
     765def test(): 
    674766    a = QApplication(sys.argv) 
    675767    ow = OWDataTable() 
    676768 
    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") 
     769    d1 = orange.ExampleTable("auto-mpg") 
     770    d2 = orange.ExampleTable("sponge.tab") 
     771    d3 = orange.ExampleTable("wpbc.csv") 
     772    d4 = orange.ExampleTable("adult_sample.tab") 
     773    d5 = orange.ExampleTable("wine.tab") 
     774 
    686775    ow.show() 
    687     #ow.dataset(d1,"auto-mpg") 
    688     #ow.dataset(d2,"voting") 
    689     #ow.dataset(d4,"wpbc") 
    690     ow.dataset(d5,"adult_sample") 
     776    ow.dataset(d1, "auto-mpg") 
     777    ow.dataset(d2, "sponge") 
     778    ow.dataset(d3, "wpbc") 
     779    ow.dataset(d4, "adult_sample") 
     780    ow.dataset(d5, "wine") 
    691781    a.exec_() 
    692782    ow.saveSettings() 
     783 
     784 
     785if __name__ == "__main__": 
     786    test() 
  • Orange/OrangeWidgets/Data/OWPaintData.py

    r11672 r11673  
    922922        # if we start updating from previously undone actions, we cut off redos in our history 
    923923        if not self.historyCounter == len(self.dataHistory)-1: 
    924             self.dataHistory = self.dataHistory[0:self.historyCounter+1] 
     924            self.dataHistory = self.dataHistory[:self.historyCounter+1] 
    925925        # append an update of labels and data 
    926926        labels = list(self.classValuesModel) 
     
    947947            # if not, update data 
    948948            else: 
    949                 self.graph.data = data 
     949                self.graph.data = copy.deepcopy(data) 
    950950                self.graph.updateGraph() 
    951951            self.updateHistoryBool = True 
     
    962962                self.addNewClassLabel() 
    963963            else: 
    964                 self.graph.data = data 
     964                self.graph.data = copy.deepcopy(data) 
    965965                self.graph.updateGraph() 
    966966            self.updateHistoryBool = True 
  • Orange/OrangeWidgets/Evaluate/OWTestLearners.py

    r11217 r11562  
    1414import warnings 
    1515from orngWrap import PreprocessedLearner 
    16 warnings.filterwarnings("ignore", "'id' is not a builtin attribute", 
    17                         orange.AttributeWarning) 
    1816 
    1917import Orange 
     
    338336            try: 
    339337                predictor = learner(new) 
     338            except Exception, ex: 
     339                learner_exceptions.append((l, ex)) 
     340                l.scores = [] 
     341                l.results = None 
     342            else: 
    340343                if (multilabel and isinstance(learner, Orange.multilabel.MultiLabelLearner)) or predictor(new[0]).varType == new.domain.classVar.varType: 
    341344                    learners.append(learner) 
     
    344347                    l.scores = [] 
    345348                    l.results = None 
    346  
    347             except Exception, ex: 
    348                 learner_exceptions.append((l, ex)) 
    349                 l.scores = [] 
    350                 l.results = None 
    351349 
    352350        if learner_exceptions: 
     
    447445         
    448446    def clearScores(self, ids=None): 
     447        """ 
     448        Clear/invalidate evaluation results/scores for learners for an 
     449        `ids` sequence (keys into self.learners). If `ids` is None then 
     450        invalidate data for all learners. 
     451 
     452        """ 
    449453        if ids is None: 
    450454            ids = self.learners.keys() 
     
    456460    # handle input signals 
    457461    def setData(self, data): 
    458         """handle input train data set""" 
     462        """ 
     463        Set the input train data set. 
     464        """ 
    459465        self.closeContext() 
    460          
    461         multilabel= self.ismultilabel(data) 
     466 
     467        self.clearScores() 
     468 
     469        multilabel = self.ismultilabel(data) 
    462470        if not multilabel: 
    463             self.data = self.isDataWithClass(data, checkMissing=True) and data or None 
     471            if self.isDataWithClass(data, checkMissing=True): 
     472                self.data = orange.Filter_hasClassValue(data) 
     473            else: 
     474                self.data = None 
    464475        else: 
    465476            self.data = data 
    466          
     477 
    467478        self.fillClassCombo() 
    468         if not self.data: 
    469             # data was removed, remove the scores 
    470             self.clearScores() 
    471             self.send("Evaluation Results", None) 
    472         else: 
    473             # new data has arrived 
    474             self.clearScores() 
    475  
    476             if not multilabel: 
    477                 self.data = orange.Filter_hasClassValue(self.data) 
    478  
    479             self.statLayout.setCurrentWidget([self.rbox, self.cbox, self.mbox][2 if self.ismultilabel() else self.isclassification()]) 
    480  
    481             self.stat = [self.rStatistics, self.cStatistics, self.mStatistics][2 if self.ismultilabel() else self.isclassification()] 
    482  
    483             if self.learners: 
    484                 self.recompute() 
    485              
    486         self.openContext("", data) 
    487         self.paintscores() 
     479 
     480        if self.data is not None: 
     481            # Ensure the correct statistics selection is visible. 
     482            if self.ismultilabel(): 
     483                statwidget = self.mbox 
     484                stat = self.mStatistics 
     485            elif self.isclassification(): 
     486                statwidget = self.cbox 
     487                stat = self.cStatistics 
     488            else: 
     489                statwidget = self.rbox 
     490                stat = self.rStatistics 
     491 
     492            self.statLayout.setCurrentWidget(statwidget) 
     493 
     494            self.stat = stat 
    488495 
    489496    def setTestData(self, data): 
    490         """handle test data set""" 
     497        """ 
     498        Set the 'Separate Test Data' input. 
     499        """ 
    491500        if data is None: 
    492501            self.testdata = None 
     
    496505        if self.testdata is not None: 
    497506            if self.resampling == 4: 
    498                 if self.data: 
    499                     self.recompute() 
    500                 else: 
    501                     for l in self.learners.values(): 
    502                         l.scores = [] 
    503                 self.paintscores() 
     507                self.clearScores() 
     508 
    504509        elif self.resampling == 4 and self.data: 
    505510            # test data removed, switch to testing on train data 
    506511            self.resampling = 3 
    507             self.recompute() 
     512            self.clearScores() 
    508513 
    509514    def fillClassCombo(self): 
     
    523528 
    524529    def setLearner(self, learner, id=None): 
    525         """add/remove a learner""" 
    526         if learner: # a new or updated learner 
    527             if id in self.learners: # updated learner 
     530        """ 
     531        Set the input learner with `id`. 
     532        """ 
     533        if learner is not None: 
     534            # a new or updated learner 
     535            if id in self.learners: 
    528536                time = self.learners[id].time 
    529537                self.learners[id] = Learner(learner, id) 
    530538                self.learners[id].time = time 
    531             else: # new learner 
     539                self.learners[id] = self.learners[id] 
     540                self.clearScores([id]) 
     541            else: 
    532542                self.learners[id] = Learner(learner, id) 
    533             if self.applyOnAnyChange: 
    534                 self.score([id]) 
    535             else: 
    536                 self.recompute() 
    537         else: # remove a learner and corresponding results 
     543        else: 
     544            # remove a learner and corresponding results 
    538545            if id in self.learners: 
    539546                res = self.learners[id].results 
    540547                if res and res.numberOfLearners > 1: 
     548                    # Remove the learner from the shared results instance 
    541549                    old_learner = self.learners[id].learner 
    542550                    indx = res.learners.index(old_learner) 
     
    544552                    del res.learners[indx] 
    545553                del self.learners[id] 
    546             self.sendResults() 
    547         self.paintscores() 
    548          
     554 
    549555    def setPreprocessor(self, pp): 
    550556        self.preprocessor = pp 
    551         if self.learners: 
    552             self.recompute() 
     557        self.clearScores() 
     558 
     559    def handleNewSignals(self): 
     560        """ 
     561        Update the evaluations/scores after new inputs were received. 
     562        """ 
     563        def needsupdate(learner_id): 
     564            return not (self.learners[learner_id].scores or 
     565                        self.learners[learner_id].results) 
     566 
     567        if self.applyOnAnyChange: 
     568            self.score(filter(needsupdate, self.learners)) 
     569            self.applyBtn.setEnabled(False) 
     570        else: 
     571            self.applyBtn.setEnabled(True) 
     572 
     573        self.paintscores() 
     574 
     575        if self.data is not None: 
     576            self.openContext("", self.data) 
     577        else: 
     578            self.send("Evaluation Results", None) 
    553579 
    554580    # handle output signals 
     
    594620            self.applyBtn.setDisabled(self.applyOnAnyChange) 
    595621        else: 
     622            self.clearScores() 
    596623            if self.learners: 
    597624                self.recompute() 
     
    623650 
    624651    def applyChange(self): 
     652        """ 
     653        A change of 'Apply on any change' check box. 
     654        """ 
     655        def needsupdate(learner_id): 
     656            return not (self.learners[learner_id].scores or 
     657                        self.learners[learner_id].results) 
     658 
    625659        if self.applyOnAnyChange: 
    626660            self.applyBtn.setDisabled(True) 
    627          
     661            pending = filter(needsupdate, self.learners) 
     662            if pending: 
     663                self.score(pending) 
     664                self.paintscores() 
     665 
    628666    def changedTarget(self): 
    629667        self.recomputeCM() 
  • Orange/OrangeWidgets/OWGUI.py

    r10939 r11572  
    17551755    BarRole = OrangeUserRole.next() 
    17561756    ColorRole = OrangeUserRole.next() 
    1757     def __init__(self, widget, table = None, color = QColor(255, 170, 127), color_schema=None): 
     1757 
     1758    def __init__(self, parent, table=None, color=QColor(255, 170, 127), 
     1759                 color_schema=None): 
    17581760        """ 
    1759         :param widget: OWWidget instance 
    1760         :type widget: :class:`OWWidget.OWWidget 
    1761         :param table: Table 
     1761        :param parent: OWWidget instance 
     1762        :type parent: :class:`PyQt4.QtCore.QObject` 
     1763        :param table: Table (unused, here for backwards compatibility). 
    17621764        :type table: :class:`Orange.data.Table` 
    17631765        :param color: Color of the distribution bar. 
     
    17651767        :param color_schema: If not None it must be an instance of 
    17661768            :class:`OWColorPalette.ColorPaletteGenerator` (note: this 
    1767             parameter, if set, overrides the ``color``) 
     1769            parameter, if set, overrides the ``color``). 
    17681770        :type color_schema: :class:`OWColorPalette.ColorPaletteGenerator` 
    1769            
     1771 
    17701772        """ 
    1771         QItemDelegate.__init__(self, widget) 
     1773        QItemDelegate.__init__(self, parent) 
    17721774        self.color = color 
    17731775        self.color_schema = color_schema 
    1774         self.widget = widget 
    17751776        self.table = table 
    17761777 
     
    17781779        painter.save() 
    17791780        self.drawBackground(painter, option, index) 
    1780         if self.table is None: 
    1781             table = getattr(index.model(), "examples", None) 
    1782         else: 
    1783             table = self.table 
    1784         ratio = None 
     1781 
    17851782        ratio, ok = index.data(TableBarItem.BarRole).toDouble() 
    1786         if ratio != ratio: # NaN 
     1783        if not ok or ratio > 1.0 or ratio < 0.0 or ratio != ratio: 
     1784            # not a float, out of 0..1 range or a NaN. 
    17871785            ratio = None 
    1788         if not ok: 
    1789             ratio = None 
    1790             value, ok = index.data(Qt.DisplayRole).toDouble() 
    1791             if ok and getattr(self.widget, "showBars", False) and table is not None: 
    1792                 col = index.column() 
    1793                 if col < len(table.normalizers): 
    1794                     max, span = table.normalizers[col] 
    1795                     ratio = (max - value) / span 
    17961786 
    17971787        color = self.color 
    1798         if self.color_schema is not None and table is not None \ 
    1799             and table.domain.classVar \ 
    1800             and isinstance(table.domain.classVar, orange.EnumVariable): 
     1788        if self.color_schema is not None: 
    18011789            class_ = index.data(TableClassValueRole).toPyObject() 
    1802             if not class_.isSpecial(): 
     1790            if isinstance(class_, orange.Value) and \ 
     1791                    isinstance(class_.variable, orange.EnumVariable) and \ 
     1792                    not class_.isSpecial(): 
    18031793                color = self.color_schema[int(class_)] 
    1804         else: 
    1805             color = self.color 
    18061794 
    18071795        if ratio is not None: 
    1808 #            painter.save() 
    1809 #            pen = QPen(QBrush(color), 3, Qt.SolidLine, Qt.FlatCap, Qt.BevelJoin) 
    1810 #            painter.setPen(pen) 
    1811 #            painter.drawRect(option.rect.adjusted(0, 3, -option.rect.width() * ratio, -3)) 
    1812 #            painter.restore() 
    1813  
    1814 #            painter.fillRect(option.rect.adjusted(0, 3, -option.rect.width() * ratio, -3), color) 
    1815  
    18161796            painter.save() 
    18171797            painter.setPen(QPen(QBrush(color), 5, Qt.SolidLine, Qt.RoundCap)) 
     
    18281808        self.drawDisplay(painter, option, text_rect, text) 
    18291809        painter.restore() 
    1830          
     1810 
     1811 
    18311812class BarItemDelegate(QStyledItemDelegate): 
    18321813    def __init__(self, parent, brush=QBrush(QColor(255, 170, 127)), scale=(0.0, 1.0)): 
  • Orange/classification/neural.py

    r10984 r11559  
    127127class NeuralNetworkLearner(Orange.classification.Learner): 
    128128    """ 
    129     NeuralNetworkLearner uses jzbontar's implementation of neural networks and wraps it in 
    130     an Orange compatible learner.  
    131  
    132     NeuralNetworkLearner supports all types of data and returns a classifier, regression is currently not supported. 
    133  
    134     More information about neural networks can be found at http://en.wikipedia.org/wiki/Artificial_neural_network. 
     129    NeuralNetworkLearner implements a multilayer perceptron. Learning is performed by minimizing an L2-regularized 
     130    cost function with scipy's implementation of L-BFGS. The current implementations is limited to a single 
     131    hidden layer.  
     132 
     133    Regression is currently not supported. 
    135134 
    136135    :param name: learner name. 
     
    138137 
    139138    :param n_mid: Number of nodes in the hidden layer 
    140     :type n_mid: integer 
     139    :type n_mid: int 
    141140 
    142141    :param reg_fact: Regularization factor. 
     
    144143 
    145144    :param max_iter: Maximum number of iterations. 
    146     :type max_iter: integer 
     145    :type max_iter: int 
     146 
     147    :param normalize: Normalize the data prior to learning (subtract each column by the mean and divide by the standard deviation) 
     148    :type normalize: bool 
    147149 
    148150    :rtype: :class:`Orange.multitarget.neural.neuralNetworkLearner` or  
     
    159161            return self(data,weight) 
    160162 
    161     def __init__(self, name="NeuralNetwork", n_mid=10, reg_fact=1, max_iter=1000, rand=None): 
     163    def __init__(self, name="NeuralNetwork", n_mid=10, reg_fact=1, max_iter=300, normalize=True, rand=None): 
    162164        """ 
    163165        Current default values are the same as in the original implementation (neural_networks.py) 
    164166        """ 
    165  
    166167        self.name = name 
    167168        self.n_mid = n_mid 
     
    169170        self.max_iter = max_iter 
    170171        self.rand = rand 
     172        self.normalize = normalize 
    171173 
    172174        if not self.rand: 
     
    193195        X = data.to_numpy()[0]  
    194196 
     197        mean = X.mean(axis=0) 
     198        std = X.std(axis=0) 
     199        if self.normalize: 
     200            X = (X - mean) / std 
     201 
    195202        #converts multi-target or single-target classes to numpy 
    196  
    197  
    198203        if data.domain.class_vars: 
    199204            for cv in data.domain.class_vars: 
     
    228233        self.nn.fit(X,Y) 
    229234                
    230         return NeuralNetworkClassifier(classifier=self.nn.predict, domain = data.domain) 
     235        return NeuralNetworkClassifier(classifier=self.nn.predict, 
     236            domain=data.domain, normalize=self.normalize, mean=mean, std=std) 
    231237 
    232238class NeuralNetworkClassifier(): 
     
    258264        input = np.array([[float(e) for e in example]]) 
    259265 
     266        if self.normalize: 
     267            input = (input - self.mean) / self.std 
     268 
    260269        # transform results from numpy 
    261270        results = self.classifier(input).tolist()[0] 
     271        if len(results) == 1: 
     272            prob_positive = results[0] 
     273            results = [1 - prob_positive, prob_positive] 
    262274        mt_prob = [] 
    263275        mt_value = [] 
     
    295307    global_timer = time.time() 
    296308 
    297     data = Orange.data.Table('iris') 
    298     l1 = NeuralNetworkLearner(n_mid=10, reg_fact=1, max_iter=1000) 
    299     res = Orange.evaluation.testing.cross_validation([l1],data, 3) 
     309    data = Orange.data.Table('wine') 
     310    l1 = NeuralNetworkLearner(n_mid=40, reg_fact=1, max_iter=200) 
     311 
     312#    c1 = l1(data) 
     313#    print c1(data[0], 3), data[0] 
     314 
     315    l2 = Orange.classification.bayes.NaiveLearner() 
     316    res = Orange.evaluation.testing.cross_validation([l1, l2],data, 5) 
    300317    scores = Orange.evaluation.scoring.CA(res) 
    301  
    302318    for i in range(len(scores)): 
    303319        print res.classifierNames[i], scores[i] 
  • Orange/data/discretization.py

    r11091 r11586  
    11import Orange 
    22 
    3 from Orange.core import\ 
    4     EquiNDiscretization as EqualFreq,\ 
    5     BiModalDiscretization as BiModal,\ 
    6     Preprocessor_discretize 
    7  
     3from Orange.core import Preprocessor_discretize 
    84 
    95class DiscretizeTable(object): 
     
    2925    """ 
    3026    def __new__(cls, data=None, features=None, discretize_class=False, 
    31                 method=EqualFreq(n=3), clean=True): 
     27                method=Orange.feature.discretization.EqualFreq(n=3), clean=True): 
    3228        if data is None: 
    3329            self = object.__new__(cls) 
     
    3935 
    4036    def __init__(self, features=None, discretize_class=False, 
    41                  method=EqualFreq(n=3), clean=True): 
     37                 method=Orange.feature.discretization.EqualFreq(n=3), clean=True): 
    4238        self.features = features 
    4339        self.discretize_class = discretize_class 
  • Orange/fixes/fix_changed_names.py

    r11004 r11585  
    8484           "orange.EntropyDiscretization": "Orange.feature.discretization.Entropy", 
    8585           "orange.EquiDistDiscretization": "Orange.feature.discretization.EqualWidth", 
    86            "orange.EquiNDiscretization": "Orange.data.discretization.EqualFreq", 
    87            "orange.BiModalDiscretization": "Orange.data.discretization.BiModal", 
     86           "orange.EquiNDiscretization": "Orange.feature.discretization.EqualFreq", 
     87           "orange.BiModalDiscretization": "Orange.feature.discretization.BiModal", 
    8888 
    8989           "orngFSS.attMeasure": "Orange.feature.scoring.score_all", 
  • Orange/orng/orngPCA.py

    r9676 r11590  
    99from numpy import sqrt, abs, dot, transpose 
    1010from numpy.linalg import eig, inv 
    11  
    12 mathlib_import = True 
    13 try: 
    14     import matplotlib.pyplot as plt 
    15 except: 
    16     import warnings 
    17     warnings.warn("Importing of matplotlib has failed.\nPlotting functions will be unavailable.") 
    18     mathlib_import = False 
    1911 
    2012#color table for biplot 
     
    354346            If None, plot will be shown 
    355347        """ 
    356  
    357         if not mathlib_import: 
    358             raise orange.KernelException, "Matplotlib was not imported!" 
    359  
    360         #plt.clf() -> opens two windows 
     348        import pylab as plt 
    361349        fig = plt.figure() 
    362350        ax = fig.add_subplot(111) 
     
    392380            If None, plot will be shown 
    393381        """ 
    394  
    395         if not mathlib_import: 
    396             raise orange.KernelException, "Matplotlib was not imported!" 
     382        import pylab as plt 
    397383 
    398384        if self._dataMatrix == None: 
  • Orange/testing/regression/tests_20/exclude-from-regression.txt

    r10290 r11588  
    2323reference_matrix.py 
    2424__init__.py 
     25reference_c45.py 
  • Orange/testing/testing.py

    r11088 r11580  
    614614    if getattr(__IPYTHON__.shell, "call_pdb", None): # Is pdb enabled 
    615615        enable_pdb() 
    616 except NameError: 
     616except: 
    617617    pass 
    618618 
  • Orange/testing/unit/tests/__init__.py

    r9679 r11582  
     1import os 
     2import unittest 
     3if not hasattr(unittest.TestLoader, 'discover'): 
     4    import unittest2 as unittest 
     5 
     6 
     7def suite(): 
     8    test_dir = os.path.dirname(__file__) 
     9    return unittest.TestLoader().discover(test_dir, ) 
     10 
     11test_suite = suite() 
     12 
     13 
     14if __name__ == '__main__': 
     15    unittest.main(defaultTest='suite') 
  • Orange/testing/unit/tests/test_regression.py

    r10655 r11591  
    77import subprocess 
    88 
     9import Orange 
    910from Orange.utils import environ 
    1011from Orange.testing import testing 
     
    1213 
    1314class TestRegression(unittest.TestCase): 
    14  
    1515    PLATFORM = sys.platform 
    1616    PYVERSION = sys.version[:3] 
    1717    STATES = ["OK", "timedout", "changed", "random", "error", "crash"] 
     18    maxDiff = None 
     19 
     20    def __init__(self, methodName='runTest'): 
     21        super(TestRegression, self).__init__(methodName) 
     22        self.orange_dir = os.path.dirname(Orange.__file__) 
     23        self.orange_dir = os.path.join(self.orange_dir, '..') 
     24        self.orange_dir = os.path.realpath(self.orange_dir) 
    1825 
    1926    def setUp(self): 
    20         pass 
     27        sys.path.append(self.orange_dir) 
     28 
     29    def tearDown(self): 
     30        del sys.path[-1] 
    2131 
    2232    def test_regression_on(self, roottest, indir, outdir, name): 
     
    3848        stdout, stderr = p.communicate() 
    3949        rv = stdout.strip().lower() 
     50        if rv == 'error': 
     51            self.assertEqual(stderr.split('\n'), []) 
     52        elif rv == 'changed': 
     53            expected_results = self.get_expected_results(outdir, name) 
     54            actual_results = self.get_actual_results(outdir, name) 
     55            self.assertEqual(actual_results, expected_results) 
     56 
     57 
    4058        self.assertEqual(rv, "ok", "Regression test %s: %s" % (rv, name) \ 
    4159                        if stderr == "" else \ 
    4260                        "Regression test %s: %s\n\n%s" % (rv, name, stderr)) 
    4361        os.chdir(tmpdir) 
     62 
     63    def get_expected_results(self, outputdir, name): 
     64        expected_results = "%s/%s.%s.%s.txt" % (outputdir, name, sys.platform, sys.version[:3]) 
     65        if not os.path.exists(expected_results): 
     66            expected_results = "%s/%s.%s.txt" % (outputdir, name, sys.platform) 
     67            if not os.path.exists(expected_results): 
     68                expected_results = "%s/%s.txt" % (outputdir, name) 
     69 
     70        with open(expected_results, 'r') as results: 
     71            return results.read().split('\n') 
     72 
     73    def get_actual_results(self, outputdir, name): 
     74        for state in TestRegression.STATES: 
     75            actual_results = "%s/%s.%s.%s.%s.txt" % ( 
     76                outputdir, name, TestRegression.PLATFORM, 
     77                TestRegression.PYVERSION, state) 
     78 
     79            if os.path.exists(actual_results): 
     80                with open(actual_results, 'r') as results: 
     81                    return results.read().split('\n') 
     82 
    4483 
    4584root = os.path.normpath(os.path.join(environ.install_dir, "..")) 
  • README.txt

    r10845 r11589  
    1919in that file for instructions on how to do that). 
    2020 
     21Running tests 
     22------------- 
     23After Orange is installed, you can check if everything is working OK by running the included tests:: 
     24 
     25    python setup.py test 
     26 
     27This command runs all the unit tests and documentation examples. Some of the latter have additional dependencies you can satisfy by installing matplotlib, PIL and scipy. 
     28 
    2129Starting Orange Canvas 
    2230---------------------- 
  • docs/development/rst/index.rst

    r10437 r11577  
    66   :maxdepth: 3 
    77 
     8   c 
    89   testing 
    910 
  • docs/index.rst

    r11366 r11579  
    1313Development documentation: 
    1414 
     15- :doc:`Canvas development reference <canvas/index>` 
    1516- :doc:`Widget development manual <extend-widgets/rst/index>` 
    16 - :doc:`Canvas development reference <canvas/index>` 
     17- :doc:`Writing Extensions in C++ <development/rst/c>` 
     18- :doc:`Testing <development/rst/testing>` 
    1719- `Wiki pages for developers <http://orange.biolab.si/trac>`_ 
    1820 
  • docs/reference/rst/code/exclude-from-regression.txt

    r10291 r11588  
    88kmeans-silhouette.py 
    99kmeans-trace.py 
     10tree_c45.py 
     11tree_c45_printtree.py 
  • docs/tutorial/rst/code/data-instances1.py

    r11052 r11556  
    77 
    88print "25-th data instance:" 
    9 print data[26] 
     9print data[24] 
    1010 
    1111name = "sepal width" 
    1212print "Value of '%s' for the first instance:" % name, data[0][name] 
    13 print "The 3rd value of the 25th data instance:", data[26][2] 
     13print "The 3rd value of the 25th data instance:", data[24][2] 
  • docs/tutorial/rst/data.rst

    r11052 r11556  
    113113   [4.7, 3.2, 1.3, 0.2, 'Iris-setosa'] 
    114114   25-th data instance: 
    115    [5.0, 3.4, 1.6, 0.4, 'Iris-setosa'] 
     115   [4.8, 3.4, 1.9, 0.2, 'Iris-setosa'] 
    116116   Value of 'sepal width' for the first instance: 3.5 
    117    The 3rd value of the 25th data instance: 1.6 
     117   The 3rd value of the 25th data instance: 1.9 
    118118 
    119119Iris data set we have used above has four continous attributes. Here's a script that computes their mean: 
  • docs/widgets/rst/classify/randomforest.rst

    r11359 r11551  
    2222   - Random Forest Classifier 
    2323      Trained random forest 
    24    - Choosen Tree 
    25       One of the classification trees from the random forest classifer 
    2624 
    2725 
     
    7068   :alt: Random forest evaluation 
    7169 
    72 A simple use of this widget where we wanted to explore how do the actual 
    73 trees in the forest look like is presented in the following snapshot. In 
    74 our case, the 5-th tree from the forest was rendered in the Classification 
    75 Tree Graph widget. 
    76  
    77 .. image:: images/RandomForest-TreeGraph.png 
    78    :alt: Visualization of a tree from random forest 
    7970 
    8071References 
  • setup.py

    r11537 r11580  
    3232NAME = 'Orange' 
    3333 
    34 VERSION = '2.7rc1' 
     34VERSION = '2.7.1' 
    3535ISRELEASED = False 
    3636 
     
    784784        include_package_data = True, 
    785785        zip_safe = False, 
    786  
     786        test_suite = 'Orange.testing.unit.tests.test_suite', 
    787787        cmdclass = cmdclass, 
    788788        ext_modules = ext_modules, 
  • source/orange/discretize.cpp

    r7665 r11583  
    726726      break; 
    727727 
    728       float entro1 = S1dist.abs*float(getEntropy(S1dist))/N; 
    729       float entro2 = S2dist.abs*float(getEntropy(S2dist))/N; 
    730       float E = entro1+entro2; 
     728    float entro1 = S1dist.abs*float(getEntropy(S1dist))/N; 
     729    float entro2 = S2dist.abs*float(getEntropy(S2dist))/N; 
     730    float E = entro1+entro2; 
    731731    if (   (!wins || (E<bestE)) && ((wins=1)==1) 
    732732        || (E==bestE) && rgen.randbool(++wins)) { 
Note: See TracChangeset for help on using the changeset viewer.