Changeset 10994:d93e616812c5 in orange


Ignore:
Timestamp:
10/08/12 19:07:42 (19 months ago)
Author:
Ales Erjavec <ales.erjavec@…>
Branch:
default
Message:

K-means widget coding style fix.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • Orange/OrangeWidgets/Unsupervised/OWKMeans.py

    r9671 r10994  
    1414import random 
    1515import statc 
    16 #from PyQt4.Qwt5 import * 
     16 
    1717from itertools import izip 
    1818 
    1919import orngDebugging 
    2020 
    21 ############################################################################## 
    22 # main class 
    2321 
    2422class OWKMeans(OWWidget): 
    25     settingsList = ["K", "optimized", "optimizationFrom", "optimizationTo", "scoring", "distanceMeasure", "classifySelected", "addIdAs", "classifyName", 
    26                     "initializationType", "restarts", "runAnyChange"] 
    27      
     23    settingsList = ["K", "optimized", "optimizationFrom", "optimizationTo", 
     24                    "scoring", "distanceMeasure", "classifySelected", 
     25                    "addIdAs", "classifyName", "initializationType", 
     26                    "restarts", "runAnyChange"] 
     27 
    2828    distanceMeasures = [ 
    29         ("Euclidean", orange.ExamplesDistanceConstructor_Euclidean), 
    30         ("Pearson Correlation", orngClustering.ExamplesDistanceConstructor_PearsonR), 
    31         ("Spearman Rank Correlation", orngClustering.ExamplesDistanceConstructor_SpearmanR), 
    32         ("Manhattan", orange.ExamplesDistanceConstructor_Manhattan), 
    33         ("Maximal", orange.ExamplesDistanceConstructor_Maximal), 
    34         ("Hamming", orange.ExamplesDistanceConstructor_Hamming), 
     29        ("Euclidean", 
     30         orange.ExamplesDistanceConstructor_Euclidean), 
     31        ("Pearson Correlation", 
     32         orngClustering.ExamplesDistanceConstructor_PearsonR), 
     33        ("Spearman Rank Correlation", 
     34         orngClustering.ExamplesDistanceConstructor_SpearmanR), 
     35        ("Manhattan", 
     36         orange.ExamplesDistanceConstructor_Manhattan), 
     37        ("Maximal", 
     38         orange.ExamplesDistanceConstructor_Maximal), 
     39        ("Hamming", 
     40         orange.ExamplesDistanceConstructor_Hamming), 
    3541        ] 
    3642 
    3743    initializations = [ 
    38         ("Random", orngClustering.kmeans_init_random), 
    39         ("Diversity", orngClustering.kmeans_init_diversity), 
    40         ("Agglomerative clustering", orngClustering.KMeans_init_hierarchicalClustering(n=100)), 
     44        ("Random", 
     45         orngClustering.kmeans_init_random), 
     46        ("Diversity", 
     47         orngClustering.kmeans_init_diversity), 
     48        ("Agglomerative clustering", 
     49         orngClustering.KMeans_init_hierarchicalClustering(n=100)), 
    4150        ] 
    42      
     51 
    4352    scoringMethods = [ 
    44         ("Silhouette (heuristic)", orngClustering.score_fastsilhouette), 
    45         ("Silhouette", orngClustering.score_silhouette), 
    46         ("Between cluster distance", orngClustering.score_betweenClusterDistance), 
    47         ("Distance to centroids", orngClustering.score_distance_to_centroids) 
    48         ]  
    49  
    50     def __init__(self, parent=None, signalManager = None): 
     53        ("Silhouette (heuristic)", 
     54         orngClustering.score_fastsilhouette), 
     55        ("Silhouette", 
     56         orngClustering.score_silhouette), 
     57        ("Between cluster distance", 
     58         orngClustering.score_betweenClusterDistance), 
     59        ("Distance to centroids", 
     60         orngClustering.score_distance_to_centroids) 
     61        ] 
     62 
     63    def __init__(self, parent=None, signalManager=None): 
    5164        OWWidget.__init__(self, parent, signalManager, 'k-Means Clustering') 
    5265 
     
    6780        self.runAnyChange = 1 
    6881        self.classifyName = "Cluster" 
    69          
     82 
    7083        self.settingsChanged = False 
    71          
     84 
    7285        self.loadSettings() 
    7386 
    74         self.data = None # holds input data 
    75         self.km = None   # holds clustering object 
     87        self.data = None  # holds input data 
     88        self.km = None    # holds clustering object 
    7689 
    7790        # GUI definition 
    7891        # settings 
    79          
    80         box = OWGUI.widgetBox(self.controlArea, "Clusters (k)", addSpace=True, spacing=0) 
    81         left, top, right, bottom = box.getContentsMargins() 
     92 
     93        box = OWGUI.widgetBox(self.controlArea, "Clusters (k)", 
     94                              addSpace=True, spacing=0) 
     95#        left, top, right, bottom = box.getContentsMargins() 
    8296#        box.setContentsMargins(left, 0, right, 0) 
    83         bg = OWGUI.radioButtonsInBox(box, self, "optimized", [], callback=self.setOptimization) 
    84         fixedBox = OWGUI.widgetBox(box, orientation="horizontal", margin=0, spacing=bg.layout().spacing()) 
    85         button = OWGUI.appendRadioButton(bg, self, "optimized", "Fixed",  
    86                                          insertInto=fixedBox, tooltip="Fixed number of clusters") 
     97        bg = OWGUI.radioButtonsInBox(box, self, "optimized", [], 
     98                                     callback=self.setOptimization) 
     99 
     100        fixedBox = OWGUI.widgetBox(box, orientation="horizontal", 
     101                                   margin=0, spacing=bg.layout().spacing()) 
     102 
     103        button = OWGUI.appendRadioButton(bg, self, "optimized", "Fixed", 
     104                                         insertInto=fixedBox, 
     105                                         tooltip="Fixed number of clusters") 
     106 
    87107        button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) 
    88108        fixedBox.layout().setAlignment(button, Qt.AlignLeft) 
    89         self.fixedSpinBox = OWGUI.spin(OWGUI.widgetBox(fixedBox), self, "K", min=2, max=30, tooltip="Fixed number of clusters", 
    90                                        callback=self.update, callbackOnReturn=True) 
    91          
    92         optimizedBox = OWGUI.widgetBox(box, margin=0, spacing=bg.layout().spacing()) 
    93         button = OWGUI.appendRadioButton(bg, self, "optimized", "Optimized", insertInto=optimizedBox) 
    94          
    95         box = OWGUI.indentedBox(optimizedBox, sep=OWGUI.checkButtonOffsetHint(button)) 
     109        self.fixedSpinBox = OWGUI.spin(OWGUI.widgetBox(fixedBox), self, "K", 
     110                                       min=2, max=30, 
     111                                       tooltip="Fixed number of clusters", 
     112                                       callback=self.update, 
     113                                       callbackOnReturn=True) 
     114 
     115        optimizedBox = OWGUI.widgetBox(box, margin=0, 
     116                                       spacing=bg.layout().spacing()) 
     117        button = OWGUI.appendRadioButton(bg, self, "optimized", "Optimized", 
     118                                         insertInto=optimizedBox) 
     119 
     120        box = OWGUI.indentedBox(optimizedBox, 
     121                                sep=OWGUI.checkButtonOffsetHint(button)) 
     122 
    96123        box.layout().setSpacing(0) 
    97124        self.optimizationBox = box 
    98         OWGUI.spin(box, self, "optimizationFrom", label="From", min=2, max=99, 
    99                    tooltip="Minimum number of clusters to try", callback=self.updateOptimizationFrom, callbackOnReturn=True) 
    100         b = OWGUI.spin(box, self, "optimizationTo", label="To", min=3, max=100, 
    101                    tooltip="Maximum number of clusters to try", callback=self.updateOptimizationTo, callbackOnReturn=True) 
    102 #        b.control.setLineEdit(OWGUI.LineEditWFocusOut(b)) 
    103         OWGUI.comboBox(box, self, "scoring", label="Scoring", orientation="horizontal", 
    104                        items=[m[0] for m in self.scoringMethods], callback=self.update) 
    105          
    106          
    107          
     125 
     126        OWGUI.spin(box, self, "optimizationFrom", label="From", 
     127                   min=2, max=99, 
     128                   tooltip="Minimum number of clusters to try", 
     129                   callback=self.updateOptimizationFrom, 
     130                   callbackOnReturn=True) 
     131 
     132        OWGUI.spin(box, self, "optimizationTo", label="To", 
     133                   min=3, max=100, 
     134                   tooltip="Maximum number of clusters to try", 
     135                   callback=self.updateOptimizationTo, 
     136                   callbackOnReturn=True) 
     137 
     138        OWGUI.comboBox(box, self, "scoring", label="Scoring", 
     139                       orientation="horizontal", 
     140                       items=[m[0] for m in self.scoringMethods], 
     141                       callback=self.update) 
     142 
    108143        box = OWGUI.widgetBox(self.controlArea, "Settings", addSpace=True) 
    109 #        OWGUI.spin(box, self, "K", label="Number of clusters"+"  ", min=1, max=30, step=1, 
    110 #                   callback = self.initializeClustering) 
     144 
    111145        OWGUI.comboBox(box, self, "distanceMeasure", label="Distance measures", 
    112                        items=[name for name, foo in self.distanceMeasures], 
    113                        tooltip=None, indent=20, 
    114                        callback = self.update) 
    115         cb = OWGUI.comboBox(box, self, "initializationType", label="Initialization", 
    116                        items=[name for name, foo in self.initializations], 
    117                        tooltip=None, indent=20, 
    118                        callback = self.update) 
    119         OWGUI.spin(cb.box, self, "restarts", label="Restarts", orientation="horizontal", 
    120                    min=1, max=100 if not orngDebugging.orngDebuggingEnabled else 5, 
    121                    callback=self.update, callbackOnReturn=True) 
     146                       items=[name for name, _ in self.distanceMeasures], 
     147                       tooltip=None, 
     148                       indent=20, 
     149                       callback=self.update) 
     150 
     151        cb = OWGUI.comboBox(box, self, "initializationType", 
     152                            label="Initialization", 
     153                            items=[name for name, _ in self.initializations], 
     154                            tooltip=None, 
     155                            indent=20, 
     156                            callback=self.update) 
     157 
     158        OWGUI.spin(cb.box, self, "restarts", label="Restarts", 
     159                   orientation="horizontal", 
     160                   min=1, 
     161                   max=100 if not orngDebugging.orngDebuggingEnabled else 5, 
     162                   callback=self.update, 
     163                   callbackOnReturn=True) 
    122164 
    123165        box = OWGUI.widgetBox(self.controlArea, "Cluster IDs", addSpace=True) 
    124         cb = OWGUI.checkBox(box, self, "classifySelected", "Append cluster indices") 
     166        cb = OWGUI.checkBox(box, self, "classifySelected", 
     167                            "Append cluster indices") 
     168 
    125169        box = OWGUI.indentedBox(box, sep=OWGUI.checkButtonOffsetHint(cb)) 
     170 
    126171        form = QWidget() 
    127         le = OWGUI.lineEdit(form, self, "classifyName", None, #"Name" + "  ", 
    128                             orientation="horizontal", #controlWidth=100,  
    129                             valueType=str, 
    130 #                            callback=self.sendData, 
    131 #                            callbackOnReturn=True 
    132                             ) 
    133          
    134         cc = OWGUI.comboBox(form, self, "addIdAs", label = " ", #"Place" + "  ", 
    135                             orientation="horizontal", items = ["Class attribute", "Attribute", "Meta attribute"], 
    136                             ) 
    137          
     172        le = OWGUI.lineEdit(form, self, "classifyName", None, 
     173                            orientation="horizontal", 
     174                            valueType=str) 
     175 
     176        cc = OWGUI.comboBox(form, self, "addIdAs", label=" ", 
     177                            orientation="horizontal", 
     178                            items=["Class attribute", 
     179                                   "Attribute", 
     180                                   "Meta attribute"]) 
     181 
    138182        layout = QFormLayout() 
    139183        layout.setSpacing(8) 
     
    142186        layout.addRow("Name  ", le) 
    143187        layout.addRow("Place  ", cc) 
    144 #        le.setFixedWidth(cc.sizeHint().width()) 
     188 
    145189        form.setLayout(layout) 
    146190        box.layout().addWidget(form) 
    147191        left, top, right, bottom = layout.getContentsMargins() 
    148192        layout.setContentsMargins(0, top, right, bottom) 
    149          
     193 
    150194        cb.disables.append(box) 
    151 #        cb.disables.append(cc.box) 
    152195        cb.makeConsistent() 
    153 #        OWGUI.separator(box) 
    154          
     196 
    155197        box = OWGUI.widgetBox(self.controlArea, "Run") 
    156198        cb = OWGUI.checkBox(box, self, "runAnyChange", "Run after any change") 
    157         self.runButton = b = OWGUI.button(box, self, "Run Clustering", callback = self.run) 
     199        self.runButton = b = OWGUI.button(box, self, "Run Clustering", 
     200                                          callback=self.run) 
     201 
    158202        OWGUI.setStopper(self, b, cb, "settingsChanged", callback=self.run) 
    159203 
    160204        OWGUI.rubber(self.controlArea) 
     205 
    161206        # display of clustering results 
    162          
    163          
    164207        self.optimizationReportBox = OWGUI.widgetBox(self.mainArea) 
    165         tableBox = OWGUI.widgetBox(self.optimizationReportBox, "Optimization Report") 
    166         self.table = OWGUI.table(tableBox, selectionMode=QTableWidget.SingleSelection) 
     208        tableBox = OWGUI.widgetBox(self.optimizationReportBox, 
     209                                   "Optimization Report") 
     210        self.table = OWGUI.table(tableBox, 
     211                                 selectionMode=QTableWidget.SingleSelection) 
     212 
    167213        self.table.setHorizontalScrollMode(QTableWidget.ScrollPerPixel) 
    168214        self.table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) 
     
    172218        self.table.verticalHeader().hide() 
    173219        self.table.horizontalHeader().setStretchLastSection(True) 
    174         self.table.setItemDelegateForColumn(2, OWGUI.TableBarItem(self, self.table)) 
    175         self.table.setItemDelegateForColumn(1, OWGUI.IndicatorItemDelegate(self)) 
    176         self.table.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) 
    177          
    178         self.connect(self.table, SIGNAL("itemSelectionChanged()"), self.tableItemSelected) 
    179          
    180         self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) 
    181         self.mainArea.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) 
    182          
    183          
     220 
     221        self.table.setItemDelegateForColumn( 
     222            2, OWGUI.TableBarItem(self, self.table)) 
     223 
     224        self.table.setItemDelegateForColumn( 
     225            1, OWGUI.IndicatorItemDelegate(self)) 
     226 
     227        self.table.setSizePolicy(QSizePolicy.MinimumExpanding, 
     228                                 QSizePolicy.MinimumExpanding) 
     229 
     230        self.connect(self.table, 
     231                     SIGNAL("itemSelectionChanged()"), 
     232                     self.tableItemSelected) 
     233 
     234        self.setSizePolicy(QSizePolicy.Preferred, 
     235                           QSizePolicy.Preferred) 
     236 
     237        self.mainArea.setSizePolicy(QSizePolicy.MinimumExpanding, 
     238                                    QSizePolicy.MinimumExpanding) 
     239 
    184240        OWGUI.rubber(self.topWidgetPart) 
    185          
     241 
    186242        self.updateOptimizationGui() 
    187  
    188 #        self.resize(100,100) 
    189243 
    190244    def adjustSize(self): 
     
    192246        s = self.sizeHint() 
    193247        self.resize(s) 
    194          
     248 
    195249    def hideOptResults(self): 
    196250        self.mainArea.hide() 
    197251        QTimer.singleShot(100, self.adjustSize) 
    198          
    199          
     252 
    200253    def showOptResults(self): 
    201254        self.mainArea.show() 
    202255        QTimer.singleShot(100, self.adjustSize) 
    203          
     256 
    204257    def sizeHint(self): 
    205258        s = self.leftWidgetPart.sizeHint() 
    206259        if self.optimized and not self.mainArea.isHidden(): 
    207             s.setWidth(s.width() + self.mainArea.sizeHint().width() + self.childrenRect().x() * 4) 
     260            s.setWidth(s.width() + self.mainArea.sizeHint().width() + \ 
     261                       self.childrenRect().x() * 4) 
    208262        return s 
    209          
     263 
    210264    def updateOptimizationGui(self): 
    211265        self.fixedSpinBox.setDisabled(bool(self.optimized)) 
     
    215269        else: 
    216270            self.hideOptResults() 
    217              
     271 
    218272    def updateOptimizationFrom(self): 
    219         self.optimizationTo = max([self.optimizationFrom + 1, self.optimizationTo]) 
     273        self.optimizationTo = max([self.optimizationFrom + 1, 
     274                                   self.optimizationTo]) 
    220275        self.update() 
    221          
     276 
    222277    def updateOptimizationTo(self): 
    223         self.optimizationFrom = min([self.optimizationFrom, self.optimizationTo - 1]) 
     278        self.optimizationFrom = min([self.optimizationFrom, 
     279                                     self.optimizationTo - 1]) 
    224280        self.update() 
    225          
     281 
    226282    def setOptimization(self): 
    227283        self.updateOptimizationGui() 
    228284        self.update() 
    229              
     285 
    230286    def runOptimization(self): 
    231287        if self.optimizationTo > len(set(self.data)): 
    232             self.error("Not enough unique data instances (%d) for given number of clusters (%d)." % \ 
     288            self.error("Not enough unique data instances (%d) for given " 
     289                       "number of clusters (%d)." % \ 
    233290                       (len(set(self.data)), self.optimizationTo)) 
    234291            return 
    235          
     292 
    236293        random.seed(0) 
     294        data = self.data 
     295        nstart = self.restarts 
     296        initialization = self.initializations[self.initializationType][1] 
     297        distance = self.distanceMeasures[self.distanceMeasure][1] 
     298        scoring = self.scoringMethods[self.scoring][1] 
    237299        try: 
    238300            self.progressBarInit() 
     
    244306                def outer_progress(km): 
    245307                    outer_callback_state["restart"] += 1 
    246                     self.progressBarSet(100.0 * outer_callback_state["restart"] / outer_callback_count) 
    247                      
     308                    self.progressBarSet( 
     309                        100.0 * outer_callback_state["restart"] \ 
     310                        / outer_callback_count 
     311                    ) 
     312 
    248313                def inner_progress(km): 
    249314                    estimate = self.progressEstimate(km) 
     
    252317                                            100.0 / outer_callback_count, 
    253318                                            100.0)) 
    254                       
     319 
    255320                kmeans = orngClustering.KMeans( 
    256                     self.data, 
    257                     centroids = k, 
     321                    data, 
     322                    centroids=k, 
    258323                    minscorechange=0, 
    259                     nstart = self.restarts, 
    260                     initialization = self.initializations[self.initializationType][1], 
    261                     distance = self.distanceMeasures[self.distanceMeasure][1], 
    262                     scoring = self.scoringMethods[self.scoring][1], 
    263                     outer_callback = outer_progress, 
    264                     inner_callback = inner_progress 
     324                    nstart=nstart, 
     325                    initialization=initialization, 
     326                    distance=distance, 
     327                    scoring=scoring, 
     328                    outer_callback=outer_progress, 
     329                    inner_callback=inner_progress 
    265330                    ) 
    266331                optimizationRun.append((k, kmeans)) 
    267                  
    268                 if self.restarts == 1: 
     332 
     333                if nstart == 1: 
    269334                    outer_progress(None) 
    270                      
    271             self.optimizationRun = optimizationRun  
     335 
     336            self.optimizationRun = optimizationRun 
     337            minimize = getattr(scoring, "minimize", False) 
     338            self.optimizationRunSorted = \ 
     339                    sorted(optimizationRun, 
     340                           key=lambda item: item[1].score, 
     341                           reverse=minimize) 
     342 
    272343            self.progressBarFinished() 
    273             self.bestRun = (min if getattr(self.scoringMethods[self.scoring][1], "minimize", False) else max)(self.optimizationRun, key=lambda (k, run): run.score) 
     344 
     345            self.bestRun = self.optimizationRunSorted[-1] 
    274346            self.showResults() 
    275347            self.sendData() 
    276348        except Exception, ex: 
    277             self.error(0, "An error occured while running optimization. Reason: " + str(ex)) 
     349            self.error(0, "An error occurred while running optimization. " 
     350                          "Reason: " + str(ex)) 
    278351            raise 
    279          
     352 
    280353    def cluster(self): 
    281354        if self.K > len(set(self.data)): 
    282             self.error("Not enough unique data instances (%d) for given number of clusters (%d)." % \ 
     355            self.error("Not enough unique data instances (%d) for given " 
     356                       "number of clusters (%d)." % \ 
    283357                       (len(set(self.data)), self.K)) 
    284358            return 
    285359        random.seed(0) 
    286          
     360 
    287361        self.km = orngClustering.KMeans( 
    288             centroids = self.K, 
     362            centroids=self.K, 
    289363            minscorechange=0, 
    290             nstart = self.restarts, 
    291             initialization = self.initializations[self.initializationType][1], 
    292             distance = self.distanceMeasures[self.distanceMeasure][1], 
    293             scoring = self.scoringMethods[self.scoring][1], 
    294             inner_callback = self.clusterCallback, 
     364            nstart=self.restarts, 
     365            initialization=self.initializations[self.initializationType][1], 
     366            distance=self.distanceMeasures[self.distanceMeasure][1], 
     367            scoring=self.scoringMethods[self.scoring][1], 
     368            inner_callback=self.clusterCallback, 
    295369            ) 
    296370        self.progressBarInit() 
     
    304378            self.progressBarSet(80.0 * km.iteration / norm) 
    305379        else: 
    306             self.progressBarSet(80.0 + 0.15 * (1.0 - math.exp(norm - km.iteration))) 
    307              
     380            self.progressBarSet(80.0 + 0.15 * \ 
     381                                (1.0 - math.exp(norm - km.iteration))) 
     382 
    308383    def progressEstimate(self, km): 
    309384        norm = math.log(len(km.data), 10) 
     
    311386            return min(80.0 * km.iteration / norm, 90.0) 
    312387        else: 
    313             return min(80.0 + 0.15 * (1.0 - math.exp(norm - km.iteration)), 90.0) 
    314          
     388            return min(80.0 + 0.15 * (1.0 - math.exp(norm - km.iteration)), 
     389                       90.0) 
     390 
     391    def scoreFmt(self, score, max_decimals=10): 
     392        if score > 0 and score < 1: 
     393            fmt = "%%.%if" % min(int(abs(math.log(max(score, 1e-10)))) + 2, 
     394                                 max_decimals) 
     395        else: 
     396            fmt = "%.1f" 
     397        return fmt 
     398 
    315399    def showResults(self): 
    316400        self.table.setRowCount(len(self.optimizationRun)) 
    317401        bestScore = self.bestRun[1].score 
    318         worstScore = (max if getattr(self.scoringMethods[self.scoring][1], "minimize", False) else min)([km.score for k, km in self.optimizationRun]) 
     402        worstScore = self.optimizationRunSorted[0][1].score 
     403        scoreSpan = (bestScore - worstScore) or 1 
     404 
    319405        for i, (k, run) in enumerate(self.optimizationRun): 
    320406            item = OWGUI.tableItem(self.table, i, 0, k) 
    321407            item.setData(Qt.TextAlignmentRole, QVariant(Qt.AlignCenter)) 
    322              
    323             item = OWGUI.tableItem(self.table, i, 1, None)#" " if (k, run) == self.bestRun else "") 
    324             item.setData(OWGUI.IndicatorItemDelegate.IndicatorRole, QVariant((k, run) == self.bestRun)) 
    325 #            item.setData(Qt.DecorationRole, QVariant(QIcon(os.path.join(os.path.dirname(OWGUI.__file__), "icons", "circle.png")))) 
     408 
     409            item = OWGUI.tableItem(self.table, i, 1, None) 
     410            item.setData(OWGUI.IndicatorItemDelegate.IndicatorRole, 
     411                         QVariant((k, run) == self.bestRun)) 
     412 
    326413            item.setData(Qt.TextAlignmentRole, QVariant(Qt.AlignCenter)) 
    327              
    328             fmt = lambda score, max_decimals=10: "%%.%if" % min(int(abs(math.log(max(score, 1e-10)))) + 2, max_decimals) if score > 0 and score < 1 else "%.1f" 
    329             item = OWGUI.tableItem(self.table, i, 2, fmt(run.score) % run.score) 
    330             item.setData(OWGUI.TableBarItem.BarRole, QVariant((bestScore - run.score) / ((bestScore - worstScore) or 1) * 0.95)) 
     414 
     415            fmt = self.scoreFmt(run.score) 
     416            item = OWGUI.tableItem(self.table, i, 2, fmt % run.score) 
     417            barRatio = 0.95 * (bestScore - run.score) / scoreSpan 
     418 
     419            item.setData(OWGUI.TableBarItem.BarRole, QVariant(barRatio)) 
    331420            if (k, run) == self.bestRun: 
    332421                self.table.selectRow(i) 
    333              
     422 
    334423        for i in range(2): 
    335424            self.table.resizeColumnToContents(i) 
     425 
    336426        self.table.show() 
    337         qApp.processEvents() 
    338         self.adjustSize() 
     427 
     428        QTimer.singleShot(0, self.adjustSize) 
    339429 
    340430    def run(self): 
     
    352442        else: 
    353443            self.settingsChanged = True 
    354              
     444 
    355445    def tableItemSelected(self): 
    356446        selectedItems = self.table.selectedItems() 
     
    362452    def sendData(self, km=None): 
    363453        if km is None: 
    364             km = self.bestRun[1] if self.optimized else self.km  
     454            km = self.bestRun[1] if self.optimized else self.km 
    365455        if not self.data or not km: 
    366456            self.send("Data", None) 
    367457            self.send("Centroids", None) 
    368458            return 
    369         clustVar = orange.EnumVariable(self.classifyName, values = ["C%d" % (x+1) for x in range(km.k)]) 
     459 
     460        clustVar = orange.EnumVariable(self.classifyName, 
     461                                       values=["C%d" % (x + 1) \ 
     462                                               for x in range(km.k)]) 
    370463 
    371464        origDomain = self.data.domain 
    372465        if self.addIdAs == 0: 
    373             domain=orange.Domain(origDomain.attributes,clustVar) 
     466            domain = orange.Domain(origDomain.attributes, clustVar) 
    374467            if origDomain.classVar: 
    375468                domain.addmeta(orange.newmetaid(), origDomain.classVar) 
    376469            aid = -1 
    377470        elif self.addIdAs == 1: 
    378             domain=orange.Domain(origDomain.attributes+[clustVar], origDomain.classVar) 
     471            domain = orange.Domain(origDomain.attributes + [clustVar], 
     472                                   origDomain.classVar) 
    379473            aid = len(origDomain.attributes) 
    380474        else: 
    381             domain=orange.Domain(origDomain.attributes, origDomain.classVar) 
    382             aid=orange.newmetaid() 
     475            domain = orange.Domain(origDomain.attributes, 
     476                                   origDomain.classVar) 
     477            aid = orange.newmetaid() 
    383478            domain.addmeta(aid, clustVar) 
    384479 
    385480        domain.addmetas(origDomain.getmetas()) 
    386481 
    387         # construct a new data set, with a class as assigned by k-means clustering 
     482        # construct a new data set, with a class as assigned by 
     483        # k-means clustering 
    388484        new = orange.ExampleTable(domain, self.data) 
    389485        for ex, midx in izip(new, km.clusters): 
    390486            ex[aid] = midx 
    391          
     487 
    392488        centroids = orange.ExampleTable(domain, km.centroids) 
    393489        for i, c in enumerate(centroids): 
     
    398494        self.send("Data", new) 
    399495        self.send("Centroids", centroids) 
    400          
     496 
    401497    def setData(self, data): 
    402498        """Handle data from the input signal.""" 
     
    410506 
    411507    def sendReport(self): 
    412         settings = [("Distance measure", self.distanceMeasures[self.distanceMeasure][0]), 
    413                     ("Initialization", self.initializations[self.initializationType][0]), 
    414                     ("Restarts", self.restarts)] 
     508        settings = [("Distance measure", 
     509                     self.distanceMeasures[self.distanceMeasure][0]), 
     510                    ("Initialization", 
     511                     self.initializations[self.initializationType][0]), 
     512                    ("Restarts", 
     513                     self.restarts)] 
    415514        if self.optimized: 
    416515            self.reportSettings("Settings", settings) 
    417             self.reportSettings("Optimization", [("Minimum num. of clusters", self.optimizationFrom), 
    418                                                  ("Maximum num. of clusters", self.optimizationTo), 
    419                                                  ("Scoring method", self.scoringMethods[self.scoring][0])]) 
    420         else: 
    421             self.reportSettings("Settings", settings + [("Number of clusters (K)", self.K)]) 
     516            self.reportSettings("Optimization", 
     517                                [("Minimum num. of clusters", 
     518                                  self.optimizationFrom), 
     519                                 ("Maximum num. of clusters", 
     520                                  self.optimizationTo), 
     521                                 ("Scoring method", 
     522                                  self.scoringMethods[self.scoring][0])]) 
     523        else: 
     524            self.reportSettings("Settings", 
     525                                settings + [("Number of clusters (K)", 
     526                                             self.K)]) 
     527 
    422528        self.reportData(self.data) 
    423529        if self.optimized: 
     530            import OWReport 
    424531            self.reportSection("Cluster size optimization report") 
    425             import OWReport  
    426532            self.reportRaw(OWReport.reportTable(self.table)) 
    427533 
    428  
    429 ############################################################################## 
    430  
    431 class colorItem(QTableWidgetItem): 
    432     def __init__(self, table, i, j, text, flags = Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable, color=Qt.lightGray): 
    433         self.color = color 
    434         QTableWidgetItem.__init__(self, unicode(text)) 
    435         self.setFlags(flags) 
    436         table.setItem(i, j, self) 
    437  
    438     def paint(self, painter, colorgroup, rect, selected): 
    439         g = QPalette(colorgroup) 
    440         g.setColor(QPalette.Base, self.color) 
    441         QTableWidgetItem.paint(self, painter, g, rect, selected) 
    442  
    443  
    444 ################################################################################################## 
     534############################################################################### 
    445535# Test this widget 
    446536 
    447 if __name__=="__main__": 
     537if __name__ == "__main__": 
    448538    import orange 
    449539    a = QApplication(sys.argv) 
    450540    ow = OWKMeans() 
    451     d = orange.ExampleTable("../../doc/datasets/iris.tab") 
     541    d = orange.ExampleTable("iris.tab") 
    452542    ow.setData(d) 
    453543    ow.show() 
Note: See TracChangeset for help on using the changeset viewer.