Aleš Erjavec avatar Aleš Erjavec committed 6edc44e

Updated Widget development tutorial.

Comments (0)

Files changed (36)

Add a comment to this file

docs/extend-widgets/rst/DataSamplerA.svg

Added
New image
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 48 48">
+	<metadata>
+		<rdf:RDF>
+			<cc:Work rdf:about="">
+				<dc:format>image/svg+xml</dc:format>
+				<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+				<dc:title/>
+			</cc:Work>
+		</rdf:RDF>
+	</metadata>
+	<path d="m24,10.5a12.5,11,0,1,1,-25,0,12.5,11,0,1,1,25,0z" transform="translate(3.5,2.5)" stroke="#39394c" stroke-dasharray="none" stroke-miterlimit="4" stroke-width="1.7" fill="none"/>
+	<path d="m24.5,10.5a13,11,0,1,1,-26,0,13,11,0,1,1,26,0z" transform="translate(20.893908,24.5)" stroke="#39394c" stroke-dasharray="none" stroke-miterlimit="4" stroke-width="1.7" fill="none"/>
+	<path stroke-linejoin="round" d="m30,10,10,0,1,0,0,9,3-1-4,4-4-4,3,1,0-7-9,0z" stroke="#2b2827" stroke-linecap="butt" stroke-miterlimit="4" stroke-dasharray="none" stroke-width="1.5" fill="none"/>
+	<path stroke-linejoin="miter" d="M10,9,8,7m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="M19,8,17,6m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="m15,14-2-2m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="M9,17,7,15m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="m21,17-2-2m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="m27,33-2-2m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="m38,36-2-2m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<text style="writing-mode:lr;letter-spacing:0px;text-anchor:start;word-spacing:0px;text-align:start;" font-weight="bold" xml:space="preserve" font-size="10px" font-style="normal" font-stretch="normal" font-variant="normal" y="44" x="4" font-family="Sans" line-height="125%" fill="#000000"><tspan x="4" y="44">A</tspan></text>
+</svg>
Add a comment to this file

docs/extend-widgets/rst/DataSamplerB.png

Removed
Old image
Add a comment to this file

docs/extend-widgets/rst/DataSamplerB.svg

Added
New image
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 48 48">
+	<metadata>
+		<rdf:RDF>
+			<cc:Work rdf:about="">
+				<dc:format>image/svg+xml</dc:format>
+				<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+				<dc:title/>
+			</cc:Work>
+		</rdf:RDF>
+	</metadata>
+	<path d="m24,10.5a12.5,11,0,1,1,-25,0,12.5,11,0,1,1,25,0z" transform="translate(3.5,2.5)" stroke="#39394c" stroke-dasharray="none" stroke-miterlimit="4" stroke-width="1.7" fill="none"/>
+	<path d="m24.5,10.5a13,11,0,1,1,-26,0,13,11,0,1,1,26,0z" transform="translate(20.893908,24.5)" stroke="#39394c" stroke-dasharray="none" stroke-miterlimit="4" stroke-width="1.7" fill="none"/>
+	<path stroke-linejoin="round" d="m30,10,10,0,1,0,0,9,3-1-4,4-4-4,3,1,0-7-9,0z" stroke="#2b2827" stroke-linecap="butt" stroke-miterlimit="4" stroke-dasharray="none" stroke-width="1.5" fill="none"/>
+	<path stroke-linejoin="miter" d="M10,9,8,7m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="M19,8,17,6m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="m15,14-2-2m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="M9,17,7,15m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="m21,17-2-2m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="m27,33-2-2m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="m38,36-2-2m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<text style="writing-mode:lr-tb;letter-spacing:0px;text-anchor:start;word-spacing:0px;text-align:start;" font-weight="bold" xml:space="preserve" font-size="10px" font-style="normal" font-stretch="normal" font-variant="normal" y="44" x="4" font-family="Sans" line-height="125%" fill="#000000"><tspan x="4" y="44">B</tspan></text>
+</svg>
Add a comment to this file

docs/extend-widgets/rst/DataSamplerC.svg

Added
New image
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 48 48">
+	<metadata>
+		<rdf:RDF>
+			<cc:Work rdf:about="">
+				<dc:format>image/svg+xml</dc:format>
+				<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
+				<dc:title/>
+			</cc:Work>
+		</rdf:RDF>
+	</metadata>
+	<path d="m24,10.5a12.5,11,0,1,1,-25,0,12.5,11,0,1,1,25,0z" transform="translate(3.5,2.5)" stroke="#39394c" stroke-dasharray="none" stroke-miterlimit="4" stroke-width="1.7" fill="none"/>
+	<path d="m24.5,10.5a13,11,0,1,1,-26,0,13,11,0,1,1,26,0z" transform="translate(20.893908,24.5)" stroke="#39394c" stroke-dasharray="none" stroke-miterlimit="4" stroke-width="1.7" fill="none"/>
+	<path stroke-linejoin="round" d="m30,10,10,0,1,0,0,9,3-1-4,4-4-4,3,1,0-7-9,0z" stroke="#2b2827" stroke-linecap="butt" stroke-miterlimit="4" stroke-dasharray="none" stroke-width="1.5" fill="none"/>
+	<path stroke-linejoin="miter" d="M10,9,8,7m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="M19,8,17,6m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="m15,14-2-2m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="M9,17,7,15m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="m21,17-2-2m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="m27,33-2-2m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<path stroke-linejoin="miter" d="m38,36-2-2m2,2-2,2m4-4-2,2,2,2" stroke="#252b2d" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+	<text style="writing-mode:lr-tb;letter-spacing:0px;text-anchor:start;word-spacing:0px;text-align:start;" font-weight="bold" xml:space="preserve" font-size="10px" font-style="normal" font-stretch="normal" font-variant="normal" y="44" x="4" font-family="Sans" line-height="125%" fill="#000000"><tspan x="4" y="44">C</tspan></text>
+</svg>
Add a comment to this file

docs/extend-widgets/rst/LearningCurve.svg

Added
New image
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 48 48">
+	<g style="writing-mode:lr-tb;letter-spacing:0px;text-anchor:start;word-spacing:0px;text-align:start;" line-height="125%" font-weight="bold" font-size="12px" transform="matrix(1,0,0,1.2314815,0.479353,-5.883444)" font-stretch="normal" font-variant="normal" font-style="normal" font-family="Sans" fill="#707070">
+		<path d="m10.956,31.463c-0.27849,0.000004-0.49422,0.12909-0.64718,0.38727-0.15298,0.25402-0.22946,0.61838-0.22946,1.0931-0.000009,0.47888,0.07451,0.84741,0.22357,1.1056,0.15296,0.25402,0.37065,0.38102,0.65307,0.38102,0.2824,0.000001,0.49813-0.12701,0.64719-0.38102,0.14904-0.25818,0.22356-0.62671,0.22357-1.1056-0.00001-0.47471-0.07649-0.83908-0.22946-1.0931-0.14906-0.25818-0.36282-0.38726-0.6413-0.38727m0-1.0494c0.72954,0.000004,1.3042,0.22487,1.7239,0.6746,0.41968,0.44973,0.62952,1.0681,0.62954,1.8551-0.000011,0.78703-0.20986,1.4096-0.62954,1.8676-0.4197,0.4539-0.99432,0.68084-1.7239,0.68084-0.72956,0-1.3061-0.22695-1.7297-0.68084-0.4197-0.45806-0.62954-1.0806-0.62953-1.8676-0.000007-0.78286,0.20984-1.3992,0.62953-1.8489,0.4236-0.45389,1.0002-0.68084,1.7297-0.68084m-5.3952,5.0782-1.3003,0,5.4893-9.6755,1.3061,0-5.4952,9.6755m-1.2061-9.6755c0.72955,0.000009,1.3022,0.22696,1.718,0.68084,0.41969,0.44974,0.62953,1.0681,0.62953,1.8551-0.000005,0.78704-0.20985,1.4075-0.62953,1.8614-0.41577,0.4539-0.98843,0.68085-1.718,0.68084-0.72956,0.000004-1.3042-0.22694-1.7239-0.68084-0.41577-0.45389-0.62365-1.0744-0.62365-1.8614-3E-7-0.78702,0.20788-1.4054,0.62365-1.8551,0.41969-0.45388,0.99431-0.68083,1.7239-0.68084m0,1.0494c-0.28241,0.00001-0.5001,0.1291-0.65307,0.38727-0.15297,0.25819-0.22946,0.62464-0.22946,1.0993-0.000001,0.47889,0.076484,0.8495,0.22946,1.1118,0.15297,0.25818,0.37066,0.38727,0.65307,0.38727,0.28241,0.000007,0.49813-0.12908,0.64719-0.38727,0.15297-0.26234,0.22945-0.63295,0.22946-1.1118-0.000004-0.47471-0.076494-0.84116-0.22946-1.0993-0.15297-0.25817-0.3687-0.38726-0.64719-0.38727"/>
+		<path d="m25.834,33.719c-0.31454,0.000006-0.55818,0.17814-0.73094,0.53442-0.17278,0.35054-0.25916,0.85336-0.25915,1.5085-0.00001,0.66085,0.08415,1.1694,0.25251,1.5257,0.17276,0.35054,0.41862,0.52581,0.73759,0.5258,0.31895,0.000001,0.56259-0.17527,0.73094-0.5258,0.16833-0.35628,0.2525-0.86484,0.25251-1.5257-0.000011-0.6551-0.08639-1.1579-0.25915-1.5085-0.16835-0.35628-0.40978-0.53442-0.7243-0.53442m0-1.4481c0.82396,0.000007,1.4729,0.31032,1.947,0.93093,0.47399,0.62063,0.71099,1.474,0.71101,2.5601-0.000013,1.0861-0.23702,1.9452-0.71101,2.5773-0.47402,0.62637-1.123,0.93955-1.947,0.93955-0.82398,0-1.4752-0.31318-1.9536-0.93955-0.47401-0.63211-0.71102-1.4912-0.71101-2.5773-0.000008-1.0803,0.23699-1.9308,0.71101-2.5514,0.47842-0.62636,1.1296-0.93954,1.9536-0.93955m-6.0934,7.0079-1.4685,0,6.1997-13.352,1.4752,0-6.2064,13.352m-1.3622-13.352c0.82397,0.000015,1.4707,0.3132,1.9403,0.93955,0.474,0.62064,0.711,1.474,0.71101,2.5601-0.000006,1.0861-0.23701,1.9423-0.71101,2.5687-0.46958,0.62637-1.1164,0.93956-1.9403,0.93955-0.82397,0.000005-1.473-0.31318-1.947-0.93955-0.46958-0.62636-0.70436-1.4826-0.70436-2.5687s0.23479-1.9394,0.70436-2.5601c0.474-0.62635,1.123-0.93954,1.947-0.93955m0,1.4481c-0.31896,0.000011-0.56482,0.17815-0.73759,0.53442-0.17277,0.35629-0.25915,0.86198-0.25915,1.5171-0.000001,0.66086,0.08638,1.1723,0.25915,1.5343,0.17277,0.35629,0.41863,0.53443,0.73759,0.53442,0.31895,0.00001,0.5626-0.17813,0.73094-0.53442,0.17276-0.36202,0.25915-0.87346,0.25915-1.5343-0.000005-0.65509-0.08639-1.1608-0.25915-1.5171-0.17277-0.35627-0.41642-0.53441-0.73094-0.53442"/>
+		<path d="m42.439,35.057c-0.36705,0.000006-0.65138,0.20974-0.85298,0.62919-0.20162,0.4127-0.30243,1.0047-0.30242,1.7759-0.000012,0.77804,0.0982,1.3768,0.29467,1.7962,0.2016,0.4127,0.48851,0.61905,0.86074,0.61904,0.3722,0.000003,0.65652-0.20634,0.85298-0.61904,0.19643-0.41946,0.29465-1.0182,0.29467-1.7962-0.000013-0.77126-0.10081-1.3632-0.30242-1.7759-0.198-0.419-0.48-0.629-0.847-0.629m0-1.7049c0.96153,0.000007,1.7189,0.36534,2.272,1.096,0.55313,0.73068,0.8297,1.7354,0.82972,3.014-0.000015,1.2787-0.27659,2.2901-0.82972,3.0343-0.55316,0.73744-1.3105,1.1062-2.272,1.1062-0.96155,0-1.7215-0.36872-2.2798-1.1062-0.55316-0.7442-0.82973-1.7556-0.82972-3.0343-0.000009-1.2719,0.27656-2.2732,0.82972-3.0039,0.5583-0.73743,1.3182-1.1062,2.2798-1.1062m-7.1108,8.2505-1.7137,0,7.2348-15.72,1.7215,0-7.2426,15.72m-1.588-15.719c0.96154,0.000017,1.7163,0.36874,2.2643,1.1062,0.55314,0.73069,0.82971,1.7354,0.82972,3.014-0.000007,1.2787-0.27658,2.2868-0.82972,3.0242-0.54798,0.73745-1.3027,1.1062-2.2643,1.1062-0.96154,0.000006-1.7189-0.36871-2.272-1.1062-0.54798-0.73743-0.82196-1.7455-0.82196-3.0242s0.27399-2.2833,0.82196-3.014c0.55314-0.73742,1.3105-1.1061,2.272-1.1062m0,1.7049c-0.37221,0.000016-0.65912,0.20975-0.86074,0.62919-0.20162,0.41947-0.30242,1.0148-0.30242,1.7861-0.000001,0.77804,0.1008,1.3802,0.30242,1.8064,0.20161,0.41947,0.48852,0.6292,0.86074,0.62919,0.37221,0.000012,0.65653-0.20972,0.85298-0.62919,0.20161-0.42622,0.30241-1.0283,0.30242-1.8064-0.000006-0.77126-0.10081-1.3666-0.30242-1.7861-0.20162-0.41945-0.48595-0.62918-0.85298-0.62919"/>
+	</g>
+	<path stroke-linejoin="miter" d="M5,21c8-16,26-15,39-15" stroke="#583e3e" stroke-linecap="round" stroke-miterlimit="4" stroke-dasharray="none" stroke-width="2.70000005" fill="none"/>
+	<path stroke-linejoin="miter" d="m2,3,0,21,44,0" stroke="#AAA" stroke-linecap="butt" stroke-width="1px" fill="none"/>
+</svg>

docs/extend-widgets/rst/OWAttributeSampler.py

 <icon>icons/AttributeSampler.png</icon>
 <priority>1020</priority>
 """
+import Orange
 
 from OWWidget import *
 import OWGUI
 
 class OWAttributeSampler(OWWidget):
     settingsList = []
-    contextHandlers = {"": DomainContextHandler("", [
-            ContextField("classAttribute", DomainContextHandler.Required),
-            ContextField("attributeList", DomainContextHandler.List + DomainContextHandler.SelectedRequired,
-                         selected="selectedAttributes")])}
+
+    # ~start context handler~
+    contextHandlers = {
+        "": DomainContextHandler(
+            "",
+            [ContextField("classAttribute", DomainContextHandler.Required),
+             ContextField("attributeList",
+                          DomainContextHandler.List +
+                          DomainContextHandler.SelectedRequired,
+                          selected="selectedAttributes")])}
+    # ~end context handler~
 
     def __init__(self, parent=None, signalManager=None):
         OWWidget.__init__(self, parent, signalManager, 'AttributeSampler')
 
-        self.inputs = [("Examples", ExampleTable, self.dataset)]
-        self.outputs = [("Examples", ExampleTable)]
+        self.inputs = [("Examples", Orange.data.Table, self.dataset)]
+        self.outputs = [("Examples", Orange.data.Table)]
 
         self.icons = self.createAttributeIconDict()
 
         self.classAttribute = None
         self.loadSettings()
 
-        OWGUI.listBox(self.controlArea, self, "selectedAttributes", "attributeList", box="Selected attributes", selectionMode = QListWidget.ExtendedSelection)
+        OWGUI.listBox(self.controlArea, self, "selectedAttributes",
+                      "attributeList",
+                      box="Selected attributes",
+                      selectionMode=QListWidget.ExtendedSelection)
+
         OWGUI.separator(self.controlArea)
-        self.classAttrCombo = OWGUI.comboBox(self.controlArea, self, "classAttribute", box="Class attribute")
+        self.classAttrCombo = OWGUI.comboBox(
+            self.controlArea, self, "classAttribute",
+            box="Class attribute")
+
         OWGUI.separator(self.controlArea)
-        OWGUI.button(self.controlArea, self, "Commit", callback = self.outputData)
+        OWGUI.button(self.controlArea, self, "Commit",
+                     callback=self.outputData)
 
         self.resize(150,400)
 
 
         self.classAttrCombo.clear()
         if data:
-            self.attributeList = [(attr.name, attr.varType) for attr in data.domain]
+            self.attributeList = [(attr.name, attr.varType)
+                                  for attr in data.domain]
             self.selectedAttributes = []
             for attrName, attrType in self.attributeList:
                 self.classAttrCombo.addItem(self.icons[attrType], attrName)
         if not self.data:
             self.send("Examples", None)
         else:
-            newDomain = orange.Domain([self.data.domain[i] for i in self.selectedAttributes], self.data.domain[self.classAttribute])
-            newData = orange.ExampleTable(newDomain, self.data)
+            newDomain = Orange.data.Domain(
+                [self.data.domain[i] for i in self.selectedAttributes],
+                self.data.domain[self.classAttribute])
+
+            newData = Orange.data.Table(newDomain, self.data)
             self.send("Examples", newData)
 
 
-##############################################################################
-# Test the widget, run from prompt
-
 if __name__=="__main__":
     appl = QApplication(sys.argv)
     ow = OWAttributeSampler()
     ow.show()
 
-    data = orange.ExampleTable('iris.tab')
+    data = Orange.data.Table('iris.tab')
     ow.dataset(data)
 
     appl.exec_()

docs/extend-widgets/rst/OWDataSamplerA.py

+"""
+<name>Data Sampler</name>
+<description>Randomly selects a subset of instances from the data set</description>
+<icon>icons/DataSamplerA.svg</icon>
+<priority>10</priority>
+"""
+
+import Orange
+from OWWidget import *
+import OWGUI
+
+class OWDataSamplerA(OWWidget):
+
+    def __init__(self, parent=None, signalManager=None):
+        OWWidget.__init__(self, parent, signalManager)
+
+        self.inputs = [("Data", Orange.data.Table, self.data)]
+        self.outputs = [("Sampled Data", Orange.data.Table)]
+
+        # GUI
+        box = OWGUI.widgetBox(self.controlArea, "Info")
+        self.infoa = OWGUI.widgetLabel(box, 'No data on input yet, waiting to get something.')
+        self.infob = OWGUI.widgetLabel(box, '')
+        self.resize(100,50)
+
+    def data(self, dataset):
+        if dataset:
+            self.infoa.setText('%d instances in input data set' % len(dataset))
+            indices = Orange.data.sample.SubsetIndices2(p0=0.1)
+            ind = indices(dataset)
+            sample = dataset.select(ind, 0)
+            self.infob.setText('%d sampled instances' % len(sample))
+            self.send("Sampled Data", sample)
+        else:
+            self.infoa.setText('No data on input yet, waiting to get something.')
+            self.infob.setText('')
+            self.send("Sampled Data", None)
+
+
+if __name__=="__main__":
+    appl = QApplication(sys.argv)
+    ow = OWDataSamplerA()
+    ow.show()
+    dataset = Orange.data.Table('iris.tab')
+    ow.data(dataset)
+    appl.exec_()
+

docs/extend-widgets/rst/OWDataSamplerB.py

 """
 <name>Data Sampler (B)</name>
 <description>Randomly selects a subset of instances from the data set</description>
-<icon>icons/DataSamplerB.png</icon>
+<icon>icons/DataSamplerB.svg</icon>
 <priority>20</priority>
 """
+import Orange
 from OWWidget import *
 import OWGUI
 
 class OWDataSamplerB(OWWidget):
     settingsList = ['proportion', 'commitOnChange']
     def __init__(self, parent=None, signalManager=None):
-        OWWidget.__init__(self, parent, signalManager, 'SampleDataB')
+        OWWidget.__init__(self, parent, signalManager)
 
-        self.inputs = [("Data", ExampleTable, self.data)]
-        self.outputs = [("Sampled Data", ExampleTable)]
+        self.inputs = [("Data", Orange.data.Table, self.data)]
+        self.outputs = [("Sampled Data", Orange.data.Table)]
 
         self.proportion = 50
         self.commitOnChange = 0
             self.infob.setText('')
 
     def selection(self):
-        indices = orange.MakeRandomIndices2(p0=self.proportion / 100.)
+        indices = Orange.data.sample.SubsetIndices2(p0=self.proportion / 100.)
         ind = indices(self.dataset)
         self.sample = self.dataset.select(ind, 0)
         self.infob.setText('%d sampled instances' % len(self.sample))
         if self.commitOnChange:
             self.commit()
 
-##############################################################################
-# Test the widget, run from prompt
 
 if __name__=="__main__":
     appl = QApplication(sys.argv)
     ow = OWDataSamplerB()
     ow.show()
-    dataset = orange.ExampleTable('iris.tab')
+    dataset = Orange.data.Table('iris.tab')
     ow.data(dataset)
     appl.exec_()

docs/extend-widgets/rst/OWDataSamplerC.py

 """
 <name>Data Sampler (C)</name>
 <description>Randomly selects a subset of instances from the data set</description>
-<icon>icons/DataSamplerC.png</icon>
+<icon>icons/DataSamplerC.svg</icon>
 <priority>30</priority>
 """
+import Orange
+
 from OWWidget import *
 import OWGUI
 
     def __init__(self, parent=None, signalManager=None):
         OWWidget.__init__(self, parent, signalManager, 'SampleDataC')
         
-        self.inputs = [("Data", ExampleTable, self.data)]
-        self.outputs = [("Sampled Data", ExampleTable), ("Other Data", ExampleTable)]
+        self.inputs = [("Data", Orange.data.Table, self.data)]
+        self.outputs = [("Sampled Data", Orange.data.Table),
+                        ("Other Data", Orange.data.Table)]
 
         self.proportion = 50
         self.commitOnChange = 0
             self.infob.setText('')
 
     def selection(self):
-        indices = orange.MakeRandomIndices2(p0=self.proportion / 100.)
+        indices = Orange.data.sample.SubsetIndices2(p0=self.proportion / 100.)
         ind = indices(self.dataset)
         self.sample = self.dataset.select(ind, 0)
         self.otherdata = self.dataset.select(ind, 1)
         if self.commitOnChange:
             self.commit()
 
-##############################################################################
-# Test the widget, run from prompt
 
 if __name__=="__main__":
     appl = QApplication(sys.argv)
     ow = OWDataSamplerC()
     ow.show()
-    dataset = orange.ExampleTable('iris.tab')
+    dataset = Orange.data.Table('iris.tab')
     ow.data(dataset)
     appl.exec_()

docs/extend-widgets/rst/OWLearningCurveA.py

 """
 <name>Learning Curve (A)</name>
 <description>Takes a data set and a set of learners and shows a learning curve in a table</description>
-<icon>icons/LearningCurveA.png</icon>
+<icon>icons/LearningCurve.svg</icon>
 <priority>1000</priority>
 """
 
+import Orange
+
 from OWWidget import *
-import OWGUI, orngTest, orngStat
+import OWGUI
 
 class OWLearningCurveA(OWWidget):
     settingsList = ["folds", "steps", "scoringF", "commitOnChange"]
-    
+
     def __init__(self, parent=None, signalManager=None):
         OWWidget.__init__(self, parent, signalManager, 'LearningCurveA')
 
-        self.inputs = [("Data", ExampleTable, self.dataset),
-                       ("Learner", orange.Learner, self.learner, Multiple)]
-        
+        self.inputs = [("Data", Orange.data.Table, self.dataset),
+                       ("Learner", Orange.core.Learner, self.learner,
+                        Multiple)]
+
         self.folds = 5     # cross validation folds
         self.steps = 10    # points in the learning curve
         self.scoringF = 0  # scoring function
         self.commitOnChange = 1 # compute curve on any change of parameters
         self.loadSettings()
-        self.setCurvePoints() # sets self.curvePoints, self.steps equidistantpoints from 1/self.steps to 1
-        self.scoring = [("Classification Accuracy", orngStat.CA), ("AUC", orngStat.AUC), ("BrierScore", orngStat.BrierScore), ("Information Score", orngStat.IS), ("Sensitivity", orngStat.sens), ("Specificity", orngStat.spec)]
+        self.setCurvePoints() # sets self.curvePoints, self.steps equidistant points from 1/self.steps to 1
+        self.scoring = [("Classification Accuracy", Orange.evaluation.scoring.CA),
+                        ("AUC", Orange.evaluation.scoring.AUC),
+                        ("BrierScore", Orange.evaluation.scoring.Brier_score),
+                        ("Information Score", Orange.evaluation.scoring.IS),
+                        ("Sensitivity", Orange.evaluation.scoring.Sensitivity),
+                        ("Specificity", Orange.evaluation.scoring.Specificity)]
         self.learners = [] # list of current learners from input channel, tuples (id, learner)
         self.data = None   # data on which to construct the learning curve
         self.curves = []   # list of evaluation results (one per learning curve point)
         self.infob = OWGUI.widgetLabel(box, 'No learners.')
 
         OWGUI.separator(self.controlArea)
+
         box = OWGUI.widgetBox(self.controlArea, "Evaluation Scores")
         scoringNames = [x[0] for x in self.scoring]
-        OWGUI.comboBox(box, self, "scoringF", items=scoringNames, callback=self.computeScores)
+        OWGUI.comboBox(box, self, "scoringF", items=scoringNames,
+                       callback=self.computeScores)
 
         OWGUI.separator(self.controlArea)
+
         box = OWGUI.widgetBox(self.controlArea, "Options")
-        OWGUI.spin(box, self, 'folds', 2, 100, step=1, label='Cross validation folds:  ',
+        OWGUI.spin(box, self, 'folds', 2, 100, step=1,
+                   label='Cross validation folds:  ',
                    callback=lambda: self.computeCurve(self.commitOnChange))
-        OWGUI.spin(box, self, 'steps', 2, 100, step=1, label='Learning curve points:  ',
-                   callback=[self.setCurvePoints, lambda: self.computeCurve(self.commitOnChange)])
+        OWGUI.spin(box, self, 'steps', 2, 100, step=1,
+                   label='Learning curve points:  ',
+                   callback=[self.setCurvePoints,
+                             lambda: self.computeCurve(self.commitOnChange)])
+        OWGUI.checkBox(box, self, 'commitOnChange', 'Apply setting on any change')
+        self.commitBtn = OWGUI.button(box, self, "Apply Setting",
+                                      callback=self.computeCurve, disabled=1)
 
-        OWGUI.checkBox(box, self, 'commitOnChange', 'Apply setting on any change')
-        self.commitBtn = OWGUI.button(box, self, "Apply Setting", callback=self.computeCurve, disabled=1)
+        OWGUI.rubber(self.controlArea)
 
         # table widget
-        self.table = OWGUI.table(self.mainArea, selectionMode=QTableWidget.NoSelection)
-                
+        self.table = OWGUI.table(self.mainArea,
+                                 selectionMode=QTableWidget.NoSelection)
+
         self.resize(500,200)
 
     ##############################################################################    
-    # slots: handle input signals        
+    # slots: handle input signals
 
     def dataset(self, data):
         if data:
             self.infoa.setText('No data on input.')
             self.curves = []
             self.scores = []
-        self.commitBtn.setEnabled(self.data<>None)
+        self.commitBtn.setEnabled(self.data is not None)
 
     def learner(self, learner, id=None):
         ids = [x[0] for x in self.learners]
         else:
             self.infob.setText("No learners.")
         self.commitBtn.setEnabled(len(self.learners))
-##        if len(self.scores):
+
         if self.data:
             self.setTable()
 
 
     def getLearningCurve(self, learners):   
         pb = OWGUI.ProgressBar(self, iterations=self.steps*self.folds)
-        curve = orngTest.learningCurveN(learners, self.data, folds=self.folds, proportions=self.curvePoints, callback=pb.advance)
+        curve = Orange.evaluation.testing.learning_curve_n(
+            learners, self.data, folds=self.folds,
+            proportions=self.curvePoints, callback=pb.advance)
         pb.finish()
         return curve
 
     def setCurvePoints(self):
-        self.curvePoints = [(x+1.)/self.steps for x in range(self.steps)]
+        self.curvePoints = [(x + 1.)/self.steps for x in range(self.steps)]
 
     def setTable(self):
         self.table.setColumnCount(0)
         for i in range(len(self.learners)):
             self.table.setColumnWidth(i, 80)
 
-##############################################################################
-# Test the widget, run from prompt
 
 if __name__=="__main__":
     appl = QApplication(sys.argv)
     ow = OWLearningCurveA()
     ow.show()
     
-    l1 = orange.BayesLearner()
+    l1 = Orange.classification.bayes.NaiveLearner()
     l1.name = 'Naive Bayes'
     ow.learner(l1, 1)
 
-    data = orange.ExampleTable('iris.tab')
+    data = Orange.data.Table('iris.tab')
     ow.dataset(data)
 
-    l2 = orange.BayesLearner()
+    l2 = Orange.classification.bayes.NaiveLearner()
     l2.name = 'Naive Bayes (m=10)'
-    l2.estimatorConstructor = orange.ProbabilityEstimatorConstructor_m(m=10)
-    l2.conditionalEstimatorConstructor = orange.ConditionalProbabilityEstimatorConstructor_ByRows(estimatorConstructor = orange.ProbabilityEstimatorConstructor_m(m=10))
+    l2.estimatorConstructor = Orange.statistics.estimate.M(m=10)
+    l2.conditionalEstimatorConstructor = \
+        Orange.statistics.estimate.ConditionalByRows(
+            estimatorConstructor = Orange.statistics.estimate.M(m=10))
     ow.learner(l2, 2)
 
-    import orngTree
-    l4 = orngTree.TreeLearner(minSubset=2)
+    l4 = Orange.classification.tree.TreeLearner(minSubset=2)
     l4.name = "Decision Tree"
     ow.learner(l4, 4)
 

docs/extend-widgets/rst/OWLearningCurveB.py

 """
 <name>Learning Curve (B)</name>
 <description>Takes a data set and a set of learners and shows a learning curve in a table</description>
-<icon>icons/LearningCurveB.png</icon>
+<icon>icons/LearningCurve.svg</icon>
 <priority>1010</priority>
 """
 
+import Orange
+
 from OWWidget import *
-import OWGUI, orngTest, orngStat
+import OWGUI
+
 
 class OWLearningCurveB(OWWidget):
     settingsList = ["folds", "steps", "scoringF", "commitOnChange"]
     def __init__(self, parent=None, signalManager=None):
         OWWidget.__init__(self, parent, signalManager, 'LearningCurveA')
 
-        self.inputs = [("Train Data", ExampleTable, self.trainset, Default),
-                       ("Test Data", ExampleTable, self.testset),
-                       ("Learner", orange.Learner, self.learner, Multiple)]
+        self.inputs = [("Train Data", Orange.data.Table, self.trainset, Default),
+                       ("Test Data", Orange.data.Table, self.testset),
+                       ("Learner", Orange.classification.Learner,
+                        self.learner, Multiple)]
         
         self.folds = 5     # cross validation folds
         self.steps = 10    # points in the learning curve
         self.scoringF = 0  # scoring function
         self.commitOnChange = 1 # compute curve on any change of parameters
         self.loadSettings()
-        self.setCurvePoints() # sets self.curvePoints, self.steps equidistantpoints from 1/self.steps to 1
-        self.scoring = [("Classification Accuracy", orngStat.CA), ("AUC", orngStat.AUC), ("BrierScore", orngStat.BrierScore), ("Information Score", orngStat.IS), ("Sensitivity", orngStat.sens), ("Specificity", orngStat.spec)]
+        self.setCurvePoints() # sets self.curvePoints, self.steps equidistan points from 1/self.steps to 1
+        self.scoring = [("Classification Accuracy", Orange.evaluation.scoring.CA),
+                        ("AUC", Orange.evaluation.scoring.AUC),
+                        ("BrierScore", Orange.evaluation.scoring.Brier_score),
+                        ("Information Score", Orange.evaluation.scoring.IS),
+                        ("Sensitivity", Orange.evaluation.scoring.Sensitivity),
+                        ("Specificity", Orange.evaluation.scoring.Specificity)]
         self.learners = [] # list of current learners from input channel, tuples (id, learner)
         self.data = None   # data on which to construct the learning curve
         self.testdata = None # optional test data
         self.infob = OWGUI.widgetLabel(box, 'No learners.')
 
         OWGUI.separator(self.controlArea)
+
         box = OWGUI.widgetBox(self.controlArea, "Evaluation Scores")
         scoringNames = [x[0] for x in self.scoring]
-        OWGUI.comboBox(box, self, "scoringF", items=scoringNames, callback=self.computeScores)
+        OWGUI.comboBox(box, self, "scoringF", items=scoringNames,
+                       callback=self.computeScores)
 
         OWGUI.separator(self.controlArea)
+
         box = OWGUI.widgetBox(self.controlArea, "Options")
-        OWGUI.spin(box, self, 'folds', 2, 100, step=1, label='Cross validation folds:  ',
+        OWGUI.spin(box, self, 'folds', 2, 100, step=1,
+                   label='Cross validation folds:  ',
                    callback=lambda: self.computeCurve(self.commitOnChange))
-        OWGUI.spin(box, self, 'steps', 2, 100, step=1, label='Learning curve points:  ',
-                   callback=[self.setCurvePoints, lambda: self.computeCurve(self.commitOnChange)])
+
+        OWGUI.spin(box, self, 'steps', 2, 100, step=1,
+                   label='Learning curve points:  ',
+                   callback=[self.setCurvePoints,
+                             lambda: self.computeCurve(self.commitOnChange)])
 
         OWGUI.checkBox(box, self, 'commitOnChange', 'Apply setting on any change')
-        self.commitBtn = OWGUI.button(box, self, "Apply Setting", callback=self.computeCurve, disabled=1)
+        self.commitBtn = OWGUI.button(box, self, "Apply Setting",
+                                      callback=self.computeCurve, disabled=1)
 
         # table widget
-        self.table = OWGUI.table(self.mainArea, selectionMode=QTableWidget.NoSelection)
+        self.table = OWGUI.table(self.mainArea,
+                                 selectionMode=QTableWidget.NoSelection)
                 
         self.resize(500,200)
 
-    ##############################################################################    
-    # slots: handle input signals        
+    ##############################################################################
+    # slots: handle input signals
 
     def trainset(self, data):
         if data:
             self.infoa.setText('No data on input.')
             self.curves = []
             self.scores = []
-        self.commitBtn.setEnabled(self.data<>None)
+        self.commitBtn.setEnabled(self.data is not None)
 
     def testset(self, testdata):
         if not testdata and not self.testdata:
     def getLearningCurve(self, learners):   
         pb = OWGUI.ProgressBar(self, iterations=self.steps*self.folds)
         if not self.testdata:
-            curve = orngTest.learningCurveN(learners, self.data, folds=self.folds, proportions=self.curvePoints, callback=pb.advance)
+            curve = Orange.evaluation.testing.learning_curve_n(
+                learners, self.data, folds=self.folds,
+                proportions=self.curvePoints,
+                callback=pb.advance)
         else:
-            curve = orngTest.learningCurveWithTestData(learners,
-              self.data, self.testdata, times=self.folds, proportions=self.curvePoints, callback=pb.advance)            
+            curve = Orange.evaluation.testing.learning_curve_with_test_data(
+                learners, self.data, self.testdata, times=self.folds,
+                proportions=self.curvePoints,
+#                callback=pb.advance
+                )
         pb.finish()
         return curve
 
     def setCurvePoints(self):
-        self.curvePoints = [(x+1.)/self.steps for x in range(self.steps)]
+        self.curvePoints = [(x + 1.)/self.steps for x in range(self.steps)]
 
     def setTable(self):
         self.table.setColumnCount(0)
         for i in range(len(self.learners)):
             self.table.setColumnWidth(i, 80)
 
-##############################################################################
-# Test the widget, run from prompt
 
 if __name__=="__main__":
     appl = QApplication(sys.argv)
     ow = OWLearningCurveB()
     ow.show()
     
-    l1 = orange.BayesLearner()
+    l1 = Orange.classification.bayes.NaiveLearner()
     l1.name = 'Naive Bayes'
     ow.learner(l1, 1)
 
-    data = orange.ExampleTable('iris.tab')
-    indices = orange.MakeRandomIndices2(data, p0 = 0.7)
+    data = Orange.data.Table('iris.tab')
+    indices = Orange.data.sample.SubsetIndices2(data, p0 = 0.7)
     train = data.select(indices, 0)
     test = data.select(indices, 1)
 
     ow.trainset(train)
     ow.testset(test)
 
-    l2 = orange.BayesLearner()
+    l2 = Orange.classification.bayes.NaiveLearner()
     l2.name = 'Naive Bayes (m=10)'
-    l2.estimatorConstructor = orange.ProbabilityEstimatorConstructor_m(m=10)
-    l2.conditionalEstimatorConstructor = orange.ConditionalProbabilityEstimatorConstructor_ByRows(estimatorConstructor = orange.ProbabilityEstimatorConstructor_m(m=10))
+    l2.estimatorConstructor = Orange.statistics.estimate.M(m=10)
+    l2.conditionalEstimatorConstructor = \
+        Orange.statistics.estimate.ConditionalByRows(
+            estimatorConstructor = Orange.statistics.estimate.M(m=10))
     ow.learner(l2, 2)
 
-    import orngTree
-    l4 = orngTree.TreeLearner(minSubset=2)
+    l4 = Orange.classification.tree.TreeLearner(minSubset=2)
     l4.name = "Decision Tree"
     ow.learner(l4, 4)
 

docs/extend-widgets/rst/OWLearningCurveC.py

 <priority>1020</priority>
 """
 
+import Orange
+
 from OWWidget import *
 from OWColorPalette import ColorPixmap
-import OWGUI, orngTest, orngStat
 from OWGraph import *
 
+import OWGUI
+
 import warnings
 
 class OWLearningCurveC(OWWidget):
     def __init__(self, parent=None, signalManager=None):
         OWWidget.__init__(self, parent, signalManager, 'LearningCurveC')
 
-        self.inputs = [("Data", ExampleTable, self.dataset),
-                       ("Learner", orange.Learner, self.learner, Multiple)]
+        self.inputs = [("Data", Orange.data.Table, self.dataset),
+                       ("Learner", Orange.classification.Learner,
+                        self.learner, Multiple)]
 
         self.folds = 5     # cross validation folds
         self.steps = 10    # points in the learning curve
         self.graphPointSize = 5 # size of points in the graphs
         self.graphDrawLines = 1 # draw lines between points in the graph
         self.graphShowGrid = 1  # show gridlines in the graph
-        self.selectedLearners = [] 
+        self.selectedLearners = []
+
         self.loadSettings()
 
-        warnings.filterwarnings("ignore", ".*builtin attribute.*", orange.AttributeWarning)
+        warnings.filterwarnings("ignore", ".*builtin attribute.*", Orange.core.AttributeWarning)
 
-        self.setCurvePoints() # sets self.curvePoints, self.steps equidistantpoints from 1/self.steps to 1
-        self.scoring = [("Classification Accuracy", orngStat.CA), ("AUC", orngStat.AUC), ("BrierScore", orngStat.BrierScore), ("Information Score", orngStat.IS), ("Sensitivity", orngStat.sens), ("Specificity", orngStat.spec)]
+        self.setCurvePoints() # sets self.curvePoints, self.steps equidistant points from 1/self.steps to 1
+        self.scoring = [("Classification Accuracy",
+                         Orange.evaluation.scoring.CA),
+                        ("AUC", Orange.evaluation.scoring.AUC),
+                        ("BrierScore", Orange.evaluation.scoring.Brier_score),
+                        ("Information Score", Orange.evaluation.scoring.IS),
+                        ("Sensitivity", Orange.evaluation.scoring.sens),
+                        ("Specificity", Orange.evaluation.scoring.spec)]
         self.learners = [] # list of current learners from input channel, tuples (id, learner)
         self.data = None   # data on which to construct the learning curve
         self.curves = []   # list of evaluation results (one per learning curve point)
 
         ## class selection (classQLB)
         OWGUI.separator(self.controlArea)
+
+        # ~SPHINX start color cb~
         self.cbox = OWGUI.widgetBox(self.controlArea, "Learners")
-        self.llb = OWGUI.listBox(self.cbox, self, "selectedLearners", selectionMode=QListWidget.MultiSelection, callback=self.learnerSelectionChanged)
+        self.llb = OWGUI.listBox(self.cbox, self, "selectedLearners",
+                                 selectionMode=QListWidget.MultiSelection,
+                                 callback=self.learnerSelectionChanged)
         
         self.llb.setMinimumHeight(50)
         self.blockSelectionChanges = 0
+        # ~SPHINX end color cb~
 
         OWGUI.separator(self.controlArea)
+
         box = OWGUI.widgetBox(self.controlArea, "Evaluation Scores")
         scoringNames = [x[0] for x in self.scoring]
         OWGUI.comboBox(box, self, "scoringF", items=scoringNames,
                        callback=self.computeScores)
 
         OWGUI.separator(self.controlArea)
+
         box = OWGUI.widgetBox(self.controlArea, "Options")
         OWGUI.spin(box, self, 'folds', 2, 100, step=1,
                    label='Cross validation folds:  ',
                    callback=lambda: self.computeCurve(self.commitOnChange))
         OWGUI.spin(box, self, 'steps', 2, 100, step=1,
                    label='Learning curve points:  ',
-                   callback=[self.setCurvePoints, lambda: self.computeCurve(self.commitOnChange)])
+                   callback=[self.setCurvePoints,
+                             lambda: self.computeCurve(self.commitOnChange)])
 
         OWGUI.checkBox(box, self, 'commitOnChange', 'Apply setting on any change')
-        self.commitBtn = OWGUI.button(box, self, "Apply Setting", callback=self.computeCurve, disabled=1)
+        self.commitBtn = OWGUI.button(box, self, "Apply Setting",
+                                      callback=self.computeCurve, disabled=1)
 
+        # ~SPHINX start main area tabs~
         # start of content (right) area
         tabs = OWGUI.tabWidget(self.mainArea)
 
-        # graph widget
+        # graph tab
         tab = OWGUI.createTabPage(tabs, "Graph")
         self.graph = OWGraph(tab)
         self.graph.setAxisAutoScale(QwtPlot.xBottom)
         tab.layout().addWidget(self.graph)
         self.setGraphGrid()
 
-        # table widget
+        # table tab
         tab = OWGUI.createTabPage(tabs, "Table")
         self.table = OWGUI.table(tab, selectionMode=QTableWidget.NoSelection)
+        # ~SPHINX end main area tabs~
 
         self.resize(550,200)
 
 
     def getLearningCurve(self, learners):
         pb = OWGUI.ProgressBar(self, iterations=self.steps*self.folds)
-        curve = orngTest.learningCurveN(learners, self.data, folds=self.folds, proportions=self.curvePoints, callback=pb.advance)
+        curve = Orange.evaluation.testing.learning_curve_n(
+            learners, self.data, folds=self.folds,
+            proportions=self.curvePoints,
+            callback=pb.advance)
+
         pb.finish()
         return curve
 
             curve.setStyle(QwtPlotCurve.Lines)
         else:
             curve.setStyle(QwtPlotCurve.NoCurve)
-        curve.setSymbol(QwtSymbol(QwtSymbol.Ellipse, \
-          QBrush(QColor(0,0,0)), QPen(QColor(0,0,0)),
-          QSize(self.graphPointSize, self.graphPointSize)))
+
+        curve.setSymbol(
+            QwtSymbol(QwtSymbol.Ellipse,
+                      QBrush(QColor(0,0,0)), QPen(QColor(0,0,0)),
+                      QSize(self.graphPointSize, self.graphPointSize)))
+
         curve.setPen(QPen(learner.color, 5))
 
     def drawLearningCurve(self, learner):
-        if not self.data: return
-        curve = self.graph.addCurve(learner.name, xData=self.curvePoints, yData=learner.score, autoScale=True)
+        if not self.data:
+            return
+        curve = self.graph.addCurve(
+            learner.name,
+            xData=self.curvePoints,
+            yData=learner.score,
+            autoScale=True)
         
         learner.curve = curve
         self.setGraphStyle(learner)
         for l in self.learners:
             self.drawLearningCurve(l[1])
 
-##############################################################################
-# Test the widget, run from prompt
 
 if __name__=="__main__":
     appl = QApplication(sys.argv)
     ow = OWLearningCurveC()
     ow.show()
 
-    l1 = orange.BayesLearner()
+    l1 = Orange.classification.bayes.NaiveLearner()
     l1.name = 'Naive Bayes'
     ow.learner(l1, 1)
 
-    data = orange.ExampleTable('iris.tab')
+    data = Orange.data.Table('iris.tab')
     ow.dataset(data)
 
-    l2 = orange.BayesLearner()
+    l2 = Orange.classification.bayes.NaiveLearner()
     l2.name = 'Naive Bayes (m=10)'
-    l2.estimatorConstructor = orange.ProbabilityEstimatorConstructor_m(m=10)
-    l2.conditionalEstimatorConstructor = orange.ConditionalProbabilityEstimatorConstructor_ByRows(estimatorConstructor = orange.ProbabilityEstimatorConstructor_m(m=10))
+    l2.estimatorConstructor = Orange.statistics.estimate.M(m=10)
+    l2.conditionalEstimatorConstructor = Orange.statistics.estimate.ConditionalByRows(estimatorConstructor = Orange.statistics.estimate.M(m=10))
 
-    l3 = orange.kNNLearner(name="k-NN")
+    l3 = Orange.classification.knn.kNNLearner(name="k-NN")
     ow.learner(l3, 3)
 
-    import orngTree
-    l4 = orngTree.TreeLearner(minSubset=2)
+    l4 = Orange.classification.tree.TreeLearner(minSubset=2)
     l4.name = "Decision Tree"
     ow.learner(l4, 4)
 
 #    ow.learner(None, 1)
 #    ow.learner(None, 2)
 #    ow.learner(None, 4)
-    
-
 
     appl.exec_()

docs/extend-widgets/rst/OWLearningCurve_plot.py

         OWGUI.checkBox(box, self, 'commitOnChange', 'Apply setting on any change')
         self.commitBtn = OWGUI.button(box, self, "Apply Setting", callback=self.computeCurve, disabled=1)
 
+        # ~start main area tabs~
         # start of content (right) area
         tabs = OWGUI.tabWidget(self.mainArea)
 
-        # graph widget
+        # graph tab
         tab = OWGUI.createTabPage(tabs, "Graph")
         self.graph = OWPlot(tab)
         self.graph.set_axis_autoscale(xBottom)
         tab.layout().addWidget(self.graph)
         self.setGraphGrid()
 
-        # table widget
+        # table tab
         tab = OWGUI.createTabPage(tabs, "Table")
         self.table = OWGUI.table(tab, selectionMode=QTableWidget.NoSelection)
+        # ~end main area tabs~
 
         self.resize(550,200)
 
         curve.set_pen(QPen(learner.color, 5))
 
     def drawLearningCurve(self, learner):
-        if not self.data: return
-        curve = self.graph.add_curve(learner.name, xData=self.curvePoints, yData=learner.score, autoScale=True)
+        if not self.data:
+            return
+        curve = self.graph.add_curve(
+            learner.name,
+            xData=self.curvePoints,
+            yData=learner.score,
+            autoScale=True)
         
         learner.curve = curve
         self.setGraphStyle(learner)

docs/extend-widgets/rst/basics.rst

 often implement some fancy graphical display of data and allow for
 some really nice interaction may be over 1000 lines long.
 
-When we have started to write this tutorial, we have been working
-on widgets for quite a while. There are now (now being in the very
-time this page has been crafted) about 50 widgets available, and we
-have pretty much defined how widgets and their interfaces should look
-like. We have also made some libraries that help set up GUI with only
-a few lines of code, and some mechanisms that one may found useful and
-user friendly, like progress bars and alike.
-
 On this page, we will start with some simple essentials, and then
 show how to build a simple widget that will be ready to run within
 Orange Canvas, our visual programming environment.
 Each Orange widget belongs to a category and within a
 category has an associated priority. Opening Orange Canvas, a visual
 programming environment that comes with Orange, widgets are listed in
-toolbox on the top of the window:
+a toolbox on the left:
 
 .. image:: widgettoolbox.png
 
-By default, Orange is installed in site-packages directory of
-Python libraries. Widgets are all put in the subdirectories of
-OrangeWidget directory; these subdirectories define widget
-categories. For instance, under windows and default settings, a
-directory that stores all the widgets displayed in the Evaluate pane is
-*C:\\Python23\\Lib\\site-packages\\Orange\\OrangeWidgets\\Evaluate*. Figure
-above shows that at the time of writing of this text there were five
-widgets for evaluation of classifiers, and this is how my Evaluate
-directory looked like:
+The widgets and categories to which they belong are discovered at Orange
+Canvas startup leveraging setuptools/distribute and it's `entry points
+<http://pythonhosted.org/distribute/setuptools.html#dynamic-discovery-of-services-and-plugins>`_
+protocol. In particular Orange Canvas looks for widgets using a
+`orange.widgets` entry point.
 
-.. image:: explorer.png
 
-Notice that there are a number of files in Evaluate directory, so
-how does Orange Canvas distinguish those that define widgets? Well,
-widgets are Python script files that start with a header. Here is a
-header for OWTestLearners.py::
+First we will examine an existing widget in Orange. The Test Learners
+widget which is implemented in `OWTestLearners.py
+<http://orange.biolab.si/trac/browser/orange/Orange/OrangeWidgets/Evaluate/OWTestLearners.py>`_.
 
+Here is its header::
+
+    """
     <name>Test Learners</name>
     <description>Estimates the predictive performance of learners on a data set.</description>
-    <icon>icons/TestLearners.png</icon>
+    <icon>icons/TestLearners1.svg</icon>
     <priority>200</priority>
+    """
 
-OWTestLearners is a Python script, so the header information we
+OWTestLearners is a Python module, so the header information we
 show about lies within the comment block, with triple quote opening
 and closing the comment. Header defines the name of the widget, its
 description, the name of the picture file the widget will use for an
 icon, and a number expressing the priority of the widget. The name of
 the widget as given in the header will be the one that will be used
-throughout in Orange Canvas. As for naming, the actual file name of
-the widget is not important. The description of the widget is shown
-once mouse rests on an toolbar icon representing the widget. And for
+throughout in Orange Canvas. The description of the widget is shown
+once mouse rests on an toolbox icon representing the widget. And for
 the priority: this determines the order in which widgets appear in the
-toolbox. The one shown above for Evaluate groups has widget named Test
-Learners with priority 200, Classifications with 300, ROC Analysis
-with 1010, Lift Curve with 1020 and Calibration Plot with 1030. Notice
-that every time the priority number crosses a multiplier of a 1000,
-there is a gap in the toolbox between the widgets; in this way, a
-subgroups of the widgets within the same group can be imposed.
+toolbox within a category.
 
 Widgets communicate. They use typed channels, and exchange
 tokens. Each widget would define its input and output channels in
                    ("Learner", orange.Learner, self.learner, 0)]
     self.outputs = [("Evaluation Results", orngTest.ExperimentResults)]
 
-Above two lines are for Test Learners widget, so hovering with your
-mouse over its icon in the widget toolbox would yield:
-
-.. image:: mouseoverwidgetintoolbox.png
 
 We will go over the syntax of channel definitions later, but for
 now the following is important:
 
    - Widgets are defined in a Python files.
-   - For Orange and Orange canvas to find them, they reside in subdirectories
-     in OrangeWidgets directory of Orange installation. The name of the
-     subdirectory matters, as this is the name of the widget category. Widgets
-     in the same directory will be grouped in the same pane of widget toolbox
-     in Orange Canvas.
-   - A file describing a widget starts with a header. This, given in sort of
-     XMLish style, tells about the name, short description, location of an
-     icon and priority of the widget.
+   - Widgets are registered through entry points and are discovered at
+     runtime.
+   - A python module implementing a widget starts with a header. This, given
+     in sort of XMLish style, tells about the name, short description,
+     location of an icon and priority of the widget.
    - The sole role of priority is to specify the placement (order) of widgets
      in the Orange Canvas toolbox.
    - Somewhere in the code (where we will learn later) there are two lines
      together with the header information, completely specify the widget as it
      is seen from the outside.
 
-Oh, by the way. Orange caches widget descriptions to achieve a faster
-startup, but this cache is automatically refreshed at startup if any change
-is detected in widgets' files.
+.. note::
+   Orange caches widget descriptions to achieve a faster startup,
+   but this cache is automatically refreshed at startup if any change
+   is detected in widgets' file.
 
 ***********
 Let's Start
 Now that we went through some of the more boring stuff, let us now
 have some fun and write a widget. We will start with a very simple
 one, that will receive a data set on the input and will output a data
-set with 10% of the data instances. Not to mess with other widgets, we
-will create a Test directory within OrangeWidgets directory, and write
-the widget in a file called `OWDataSamplerA.py`: OW for Orange Widget,
-DataSampler since this is what widget will be doing, and A since we
-prototype a number of this widgets in our tutorial.
+set with 10% of the data instances. We will call this widget
+`OWDataSamplerA.py` (OW for Orange Widget, DataSampler since this is what
+widget will be doing, and A since we prototype a number of this widgets
+in our tutorial).
 
-The script defining the OWDataSamplerA widget starts with a follwing header::
+But first we must create a simple `python project`_ layout called *Demo*,
+that we will use in the rest of this tutorial.
+
+.. _`python project`: http://docs.python.org/2/distutils/examples.html#pure-python-distribution-by-package
+
+The layout should be::
+
+   Demo/
+         setup.py
+         orangedemo/
+                     __init__.py
+                     OWDataSamplerA.py
+
+and the :download:`setup.py` should contain
+
+.. literalinclude:: setup.py
+
+Note that we declare our *orangedemo* package as containing widgets
+from an ad hoc defined category *Demo*.
+
+Following the previous example of OWTestLearners, our module defining
+the OWDataSamplerA widget starts with a following header::
 
     <name>Data Sampler</name>
     <description>Randomly selects a subset of instances from the data set</description>
-    <icon>icons/DataSamplerA.png</icon>
+    <icon>icons/DataSamplerA.svg</icon>
     <priority>10</priority>
 
 This should all be clear now, perhaps just a remark on an icon. We
 with a question mark).
 
 Orange Widgets are all derived from the class OWWidget. The name of
-the class should be match the file name, so the lines following the
+the class should match the file name, so the lines following the
 header in our Data Sampler widget should look something like::
 
+    import Orange
     from OWWidget import *
     import OWGUI
 
     class OWDataSamplerA(OWWidget):
 
         def __init__(self, parent=None, signalManager=None):
-            OWWidget.__init__(self, parent, signalManager, 'SampleDataA')
+            OWWidget.__init__(self, parent, signalManager)
 
-            self.inputs = [("Data", ExampleTable, self.data)]
-            self.outputs = [("Sampled Data", ExampleTable)]
+            self.inputs = [("Data", Orange.data.Table, self.data)]
+            self.outputs = [("Sampled Data", Orange.data.Table)]
 
             # GUI
             box = OWGUI.widgetBox(self.controlArea, "Info")
             self.infob = OWGUI.widgetLabel(box, '')
             self.resize(100,50)
 
-In initialization, the widget calls the :obj:`__init__` function
-of a base class, passing the name 'SampleData' which will,
-essentially, be used for nothing else than a stem of a file for saving
-the parameters of the widgets (we will regress on these somehow
-latter in tutorial). Widget then defines inputs and outputs. For
-input, widget defines a "Data" channel, accepting tokens of the type
-orange.ExampleTable and specifying that :obj:`data` function will
+In initialization, the widget calls the :func:`__init__` method
+of a base class. Widget then defines inputs and outputs. For input,
+this is a *Data* channel, accepting tokens of the type
+:class:`Orange.data.Table` and specifying that :func:`data` method will
 be used to handle them. For now, we will use a single output channel
 called "Sampled Data", which will be of the same type
-(orange.ExampleTable).
+(Orange.data.Table).
 
-Notice that the types of the channels are
-specified by a class name; you can use any classes here, but if your
-widgets need to talk with other widgets in Orange, you will need to
-check which classes are used there. Luckily, and as one of the main
-design principles, there are just a few channel types that current
-Orange widgets are using.
+Notice that the types of the channels are specified by a class;
+you can use any class here, but if your widgets need to talk with
+other widgets in Orange, you will need to check which classes are
+used there. Luckily, and as one of the main design principles,
+there are just a few channel types that current Orange widgets are
+using.
 
 The next four lines specify the GUI of our widget. This will be
 simple, and will include only two lines of text of which, if nothing
 "Info".
 
 In order to complete our widget, we now need to define how will it
-handle the input data. This is done in a function called
-:obj:`data` (remember, we did introduce this name in the
-specification of the input channel)::
+handle the input data. This is done in a method called :func:`data`
+(remember, we did introduce this name in the specification of the
+input channel)::
 
     def data(self, dataset):
         if dataset:
             self.infob.setText('')
             self.send("Sampled Data", None)
 
-The function is defined within a class definition, so its first
-argument has to be :obj:`self`. The second argument called
-:obj:`dataset` is the token sent through the input channel which
-our function needs to handle.
+The :obj:`dataset` argument is the token sent through the input
+channel which our method needs to handle.
 
 To handle the non-empty token, the widget updates the interface
 reporting on number of data items on the input, then does the data
 sampled data is sent as a token to the output channel with a name
 "Sampled Data".
 
-Notice that the token can be empty (``dataset is None``),
-resulting from either the sending widget to which we have connected
-intentionally emptying the channel, or when the link between the two
-widgets is removed. In any case, it is important that we always write
-token handlers that appropriately handle the empty tokens. In our
-implementation, we took care of empty input data set by appropriately
-setting the GUI of a widget and sending an empty token to the
-output channel.
+Notice that the token can be empty (``None``), resulting from either
+the sending widget to which we have connected intentionally emptying
+the channel, or when the link between the two widgets is removed.
+In any case, it is important that we always write token handlers
+that appropriately handle the empty tokens. In our implementation,
+we took care of empty input data set by appropriately setting the
+GUI of a widget and sending an empty token to the output channel.
 
-..
-   Although our widget is now ready to test, for a final touch, let's
-   design an icon for our widget. As specified in the widget header, we
-   will call it :download:`DataSamplerA.png <DataSamplerA.png>` and will
-   put it in icons subdirectory of OrangeWidgets directory (together with
-   all other icons of other widgets).
+
+Although our widget is now ready to test, for a final touch, let's
+design an icon for our widget. As specified in the widget header, we
+will call it :download:`DataSamplerA.svg <DataSamplerA.svg>` and will
+put it in `icons` subdirectory of `orangedemo` directory.
+
+With this we cen now go ahead and install the orangedemo package. We
+will do this by running :code:`python setup.py develop` command from
+the `Demo` directory.
+
+.. note::
+   Depending on your python installation you might need
+   administrator/superuser privileges.
 
 For a test, we now open Orange Canvas. There should be a new pane in a
-widget toolbox called Test (this is the name of the directory we have
-used to put in our widget). If we click on this pane, it displays an
-icon of our widget. Try to hoover on it to see if the header and
-channel info was processed correctly:
+widget toolbox called Demo. If we click on this pane, it displays an
+icon of our widget. Try to hover on it to see if the header and channel
+info was processed correctly:
 
 .. image:: samplewidgetontoolbox.png
 
 Now for the real test. We put the File widget on the schema (from
-Data pane), read iris.tab data set. We also put our Data Sampler widget on the pane and
-open it (double click on the icon, or right-click and choose
-Open):
+Data pane) and load the iris.tab data set. We also put our Data
+Sampler widget on the scheme and open it (double click on the icon,
+or right-click and choose Open):
 
 .. image:: datasamplerAempty.png
 
-Drag this window off the window with the widget schema of Orange
-Canvas, and connect File and Data Sampler widget (click on an ouput
-connector - green box - of the File widget, and drag the line to the
-input connector of the Data Sampler). If everything is ok, as soon as
-you release the mouse the connection is established and, the token
-that was waiting on the output of the file widget was sent to the Data
-Sampler widget, which in turn updated its window:
+Now connect the File and Data Sampler widget (click on an output
+connector of the File widget, and drag the line to the input connector
+of the Data Sampler). If everything is ok, as soon as you release the
+mouse, the connection is established and, the token that was waiting
+on the output of the file widget was sent to the Data Sampler widget,
+which in turn updated its window:
 
 .. image:: datasamplerAupdated.png
 
         appl = QApplication(sys.argv)
         ow = OWDataSamplerA()
         ow.show()
-        dataset = orange.ExampleTable('iris.tab')
+        dataset = Orange.data.Table('iris.tab')
         ow.data(dataset)
         appl.exec_()
 
 These are essentially some calls to Qt routines that run GUI for our
-widgets. At the core, however, notice that instead of sending the
-token to the input channel, we directly called the routine for token
-handling (:obj:`data`).
-
-To test your widget in more complex environment, that for instance
-requires to set a complex schema in which your widget collaborates,
-use Orange Canvas to set the schema and then either 1) save the schema
-to be opened every time you run Orange Canvas, or 2) save this schema
-(File menu) as an application within a single file you will need to
-run each time you will test your widget.
+widgets. Notice that we call the :func:`data` method directly.

docs/extend-widgets/rst/channels.rst

 Multi-Input Channels
 ********************
 
-First, I do not like the name, but can't make up anything better. In
-essence, the basic idea about "multi-input" channels is that they can
+In essence, the basic idea about "multi-input" channels is that they can
 be used to connect them with several output channels. That is, if a
 widget supports such a channel, several widgets can feed their input
 to that widget simultaneously.
 
 Say we want to build a widget that takes a data set and test
-various predictive modelling techniques on it. A widget has to have an
+various predictive modeling techniques on it. A widget has to have an
 input data channel, and this we know how to deal with from our
 :doc:`previous <settings>` lesson. But, somehow differently, we
 want to connect any number of widgets which define learners to our
 Now back to channels and tokens. Input and output channels for our
 widget are defined by::
 
-    self.inputs = [("Data", ExampleTable, self.dataset),
-                   ("Learner", orange.Learner, self.learner, Multiple + Default)]
+    self.inputs = [("Data", Orange.data.Table, self.dataset),
+                   ("Learner", Orange.classification.Learner,
+                    self.learner, Multiple + Default)]
 
 Notice that everything is pretty much the same as it was with
 widgets from previous lessons, the only difference being
 widget can receive the input only from one widget and is not the default input
 channel for its type (more on default channels later).
 
-.. note:: :obj:`Default` flag here is used for illustration. Since *Learner*
-          channel is the only channel for a :class:`orange.Learner` type
-          it is also the default.
+.. note::
+   :obj:`Default` flag here is used for illustration. Since *"Learner"*
+   channel is the only channel for a :class:`Orange.classification.Learner`
+   type it is also the default.
 
 How does the widget know from which widget did the token come from?
 In Orange, tokens are sent around with an id of a widget that is
 sending the token, and having a multi-input channel only tells Orange to
 send a token together with sending widget id, the two arguments with
-which the receiving function is called. For our :obj:`Learner`
-channel the receiving function is :obj:`learner`, and this looks
+which the receiving function is called. For our *"Learner"*
+channel the receiving function is :func:`learner`, and this looks
 like the following::
 
     def learner(self, learner, id=None):
 The function above first checks if the learner sent is empty
 (:obj:`None`). Remember that sending an empty learner
 essentially means that the link with the sending widget was removed,
-hance we need to remove such learner from our list. If a non-empty
+hence we need to remove such learner from our list. If a non-empty
 learner was sent, then it is either a new learner (say, from a widget
 we have just linked to our learning curve widget), or an update
 version of the previously sent learner. If the later is the case, then
 the easy by which new scoring functions are added to the widget, since
 all that is needed is the augmenting the list::
 
-    self.scoring = [("Classification Accuracy", orngStat.CA),
-                    ("AUC", orngStat.AUC),
-                    ("BrierScore", orngStat.BrierScore),
-                    ("Information Score", orngStat.IS),
-                    ("Sensitivity", orngStat.sens),
-                    ("Specificity", orngStat.spec)]
+    self.scoring = [("Classification Accuracy", Orange.evaluation.scoring.CA),
+                    ("AUC", Orange.evaluation.scoring.AUC),
+                    ("BrierScore", Orange.evaluation.scoring.Brier_score),
+                    ("Information Score", Orange.evaluation.scoring.IS),
+                    ("Sensitivity", Orange.evaluation.scoring.Sensitivity),
+                    ("Specificity", Orange.evaluation.scoring.Specificity)]
 
 which is defined in the initialization part of the widget. The
 other useful trick in this widget is that evaluation (k-fold cross
 another channel. The corresponding channel definition of this widget
 is::
 
-    self.outputs = [("Sampled Data", ExampleTable), ("Other Data", ExampleTable)]
+    self.outputs = [("Sampled Data", Orange.data.Table),
+                    ("Other Data", Orange.data.Table)]
 
 We used this in the third incarnation of :download:`data sampler widget <OWDataSamplerC.py>`,
-with essentially the only other change in the code in the :obj:`selection` and
-:obj:`commit` functions::
+with essentially the only other change in the code in the :func:`selection` and
+:func:`commit` functions::
 
     def selection(self):
-        indices = orange.MakeRandomIndices2(p0=self.proportion / 100.)
+        indices = Orange.data.sample.SubsetIndices2(p0=self.proportion / 100.)
         ind = indices(self.dataset)
         self.sample = self.dataset.select(ind, 0)
         self.otherdata = self.dataset.select(ind, 1)
 
 If a widget that has multiple channels of the same type is
 connected to a widget that accepts such tokens, Orange Canvas opens a
-window asking the user to confirm which channels to connect. The
-channel mentioned in :obj:`self.outputs` is connected by
-default. Hence, if we have just connected Data Sampler
-(C) widget to a Data Table widget in a schema below:
+window asking the user to confirm which channels to connect. Hence,
+if we have just connected *Data Sampler (C)* widget to a Data Table
+widget in a schema below:
 
 .. image:: datasampler-totable.png
 
 Orange Canvas) with the dialog which channel to connect to, as the
 training data set channel will be the default one.
 
-When enlisting the input channel of the same type, the non-default
+When enlisting the input channel of the same type, the default
 channels have a special flag in the channel specification list. So for
 our new :download:`learning curve <OWLearningCurveB.py>` widget, the
 channel specification is::
 
-    self.inputs = [("Train Data", ExampleTable, self.trainset, Default),
-                   ("Test Data", ExampleTable, self.testset),
-                   ("Learner", orange.Learner, self.learner, Multiple)]
+    self.inputs = [("Train Data", Orange.data.Table, self.trainset, Default),
+                   ("Test Data", Orange.data.Table, self.testset),
+                   ("Learner", Orange.classification.Learner, self.learner, Multiple)]
 
 That is, the :obj:`Train Data` channel is a single-token
 channel which is a default one (third parameter). Note that the flags can
 
 .. image:: file-to-learningcurveb.png
 
-That is, no window with a query on which channels
-to connect to will open. To find out which channels got connected,
-double click on the green link between the two widgets:
-
-.. image:: file-to-learningcurveb-channels.png
+That is, no window with a query on which channels to connect to will
+open, as the default *"Train Data"* was selected.

docs/extend-widgets/rst/contextsettings.rst

 To learn how to do it yourself, consider the widget below used for
 selecting a subset of attributes and the class attributes (note that a
 better widget for this task is already included in your Orange
-instalation).
+installation).
 
 .. image:: attributesampler.png
 
 with the attributes and the class chosen by the user. We'd like to
 somehow store the user's selection.
 
-Here's the widget's :obj:`__init__` function.
+Here's the widget's :func:`__init__` function.
 
-Part of :download:`OWAttributeSampler.py <OWAttributeSampler.py>`::
+Part of :download:`OWAttributeSampler.py <OWAttributeSampler.py>`
 
-    def __init__(self, parent=None, signalManager=None):
-        OWWidget.__init__(self, parent, signalManager, 'AttributeSampler')
-
-        self.inputs = [("Examples", ExampleTable, self.dataset)]
-        self.outputs = [("Examples", ExampleTable)]
-
-        self.icons = self.createAttributeIconDict()
-
-        self.attributeList = []
-        self.selectedAttributes = []
-        self.classAttribute = None
-        self.loadSettings()
-
-        OWGUI.listBox(self.controlArea, self, "selectedAttributes", "attributeList", box="Selected attributes", selectionMode = QListWidget.ExtendedSelection)
-        OWGUI.separator(self.controlArea)
-        self.classAttrCombo = OWGUI.comboBox(self.controlArea, self, "classAttribute", box="Class attribute")
-        OWGUI.separator(self.controlArea)
-        OWGUI.button(self.controlArea, self, "Commit", callback = self.outputData)
-
-        self.resize(150,400)
+.. literalinclude:: OWAttributeSampler.py
+   :pyobject: OWAttributeSampler.__init__
 
 Note that we are strictly using controls from OWGUI. As for the
 usual settings, if you use Qt controls directly, their state won't get
 into :obj:`classAttribute`.
 
 When the widget gets the data, a function :obj:`dataset` is
-called.
-
-Part of :download:`OWAttributeSampler.py`::
+called::
 
     def dataset(self, data):
         self.classAttrCombo.clear()
         self.outputData()
 
 
-    def outputData(self):
-        if not self.data:
-            self.send("Examples", None)
-        else:
-            newDomain = orange.Domain([self.data.domain[i] for i in self.selectedAttributes], self.data.domain[self.classAttribute])
-            newData = orange.ExampleTable(newDomain, self.data)
-            self.send("Examples", newData)
+.. literalinclude:: OWAttributeSampler.py
+   :pyobject: OWAttributeSampler.outputData
+
 
 Nothing special here (yet). We fill the list box, deselect all
 attributes and set the last attribute to be the class
 would usually try to assign, say, the class attribute which doesn't
 exist in the actual domain at all.
 
-To make the setting dependent on the context, we put ::
+To make the setting dependent on the context, we put
 
-    contextHandlers = {"": DomainContextHandler("", [
-            ContextField("classAttribute", DomainContextHandler.Required),
-            ContextField("attributeList", DomainContextHandler.List +
-                                          DomainContextHandler.SelectedRequired,
-                         selected="selectedAttributes")])}
+.. literalinclude:: OWAttributeSampler.py
+   :start-after: # ~start context handler~
+   :end-before: # ~end context handler~
 
 at the same place where we usually declare :obj:`settingsList`.
 
 As you have guessed, we can also have optional attributes
 (:obj:`DomainContextHandler.Optional`); sometimes certain
 attribute doesn't really matter, so if it is present in the domain,
-it's gonna be used, otherwise not. And for the list, we could say
+it's going to be used, otherwise not. And for the list, we could say
 :obj:`DomainContextHandler.List + DomainContextHandler.Required`
 in which case all the attributes on the list would be required for the
 domain to match.
 
-The default flag is :obj:`DomainContextHandler.Required`, and there are other shortcuts for declaring the context, too. The above code could be simplified as ::
+The default flag is :obj:`DomainContextHandler.Required`, and there
+are other shortcuts for declaring the context, too. The above code could
+be simplified as ::
 
-    contextHandlers = {"": DomainContextHandler("", [
-            "classAttribute",
-            ContextField("attributeList", DomainContextHandler.SelectedRequiredList,
-                         selected="selectedAttributes")])}
+    contextHandlers = {
+        "": DomainContextHandler(
+            "",
+            ["classAttribute",
+             ContextField("attributeList",
+                          DomainContextHandler.SelectedRequiredList,
+                          selected="selectedAttributes")])}
 
 Why the dictionary and the empty string as the key? A widget can
 have multiple contexts, depending, usually, on multiple input
 changing functions yourself. Here's what you have to do with the
 function :obj:`dataset`
 
-Part of :download:`OWAttributeSampler.py`::
+.. literalinclude:: OWAttributeSampler.py
+   :pyobject: OWAttributeSampler.dataset
 
-    def dataset(self, data):
-        self.closeContext()
-    
-        self.classAttrCombo.clear()
-        if data:
-            self.attributeList = [(attr.name, attr.varType) for attr in data.domain]
-            self.selectedAttributes = []
-            for attrName, attrType in self.attributeList:
-                self.classAttrCombo.addItem(self.icons[attrType], attrName)
-            self.classAttribute = 0
-        else:
-            self.attributeList = []
-            self.selectedAttributes = []
-            self.classAttrCombo.addItem("")
-    
-        self.openContext("", data)
-    
-        self.data = data
-        self.outputData()
-
-We added only two lines. First, before you change any controls in the widget, you need to call :obj:`self.closeContext` (the function has an optional argument, the context name, but since we use the default name, an empty string, we can omit it). This reads the data from the widget into the stored context. Then the function proceeds as before: the controls (the list box and combo box) are filled in as if there were no context handling (this is important, so once again: widget should be set up as if there were not context dependent settings). When the controls are put in a consistent state, we call :obj:`self.openContext`. The first argument is the context name and the second is the object from which the handler reads the context. In case of :obj:`DomainContextHandler` this can be either a domain or the data. :obj:`openContext` will make the context handler search through the stored context for the one that (best) matches the data, and if one is find the widget's state is set accordingly (that is, the list boxes are filled, attributes in it are selected etc.). If no context is found, a new context is established and the data from widget is copied to the context.
+We added only two lines. First, before you change any controls in
+the widget, you need to call :obj:`self.closeContext` (the function
+has an optional argument, the context name, but since we use the
+default name, an empty string, we can omit it). This reads the
+data from the widget into the stored context. Then the function
+proceeds as before: the controls (the list box and combo box)
+are filled in as if there were no context handling (this is
+important, so once again: widget should be set up as if there
+were not context dependent settings). When the controls are put
+in a consistent state, we call :obj:`self.openContext`. The first
+argument is the context name and the second is the object from
+which the handler reads the context. In case of
+:obj:`DomainContextHandler` this can be either a domain or the
+data. :obj:`openContext` will make the context handler search
+through the stored context for the one that (best) matches the
+data, and if one is find the widget's state is set accordingly
+(that is, the list boxes are filled, attributes in it are selected
+etc.). If no context is found, a new context is established and the
+data from widget is copied to the context.
 
 What can be stored as a context dependent setting? Anything, even
 the state of check boxes if you want to. But don't do that. Make
Add a comment to this file

docs/extend-widgets/rst/dataSamplerBWidget.png

Old
Old image
New
New image
Add a comment to this file

docs/extend-widgets/rst/datasampler-channelquerry.png

Old
Old image
New
New image
Add a comment to this file

docs/extend-widgets/rst/datasampler-totable.png

Old
Old image
New
New image
Add a comment to this file

docs/extend-widgets/rst/datasamplerAempty.png

Old
Old image
New
New image
Add a comment to this file

docs/extend-widgets/rst/datasamplerAupdated.png

Old
Old image
New
New image
Add a comment to this file

docs/extend-widgets/rst/explorer.png

Removed
Old image
Add a comment to this file

docs/extend-widgets/rst/file-to-learningcurveb.png

Old
Old image
New
New image

docs/extend-widgets/rst/graphing.rst

 ###########################
 
 The most fun widgets are of course those that include graphics. For
-this we either use control called canvas, which is Qt's general
-control for doing any graphics of choice (widgets for tree and heat map
-visualizations, for instance, use this), or use a special control for
-drawing data plots as provided in Qwt library and PyQwt
+this we either use Qt's :class:`QGraphicsScene` (widgets for tree and
+heat map visualizations, for instance, use this), or use a special
+control for drawing data plots as provided in Qwt library and :mod:`PyQwt`
 interface. Here we look at the latter, and extend our learning curve
 widget with a control that plots the curve.
 
 
 The widget still provides learning curve table, but this is now
 offered in a tabbed pane together with a graph. The code for
-definition of the tabbed pane, and initialization of the graph is::
+definition of the tabbed pane, and initialization of the graph is
 
-    # start of content (right) area
-    tabs = OWGUI.tabWidget(self.mainArea)
+.. literalinclude:: OWLearningCurveC.py
+   :start-after: # ~SPHINX start main area tabs~
+   :end-before: # ~SPHINX end main area tabs~
 
-    # graph widget
-    tab = OWGUI.createTabPage(tabs, "Graph")
-    self.graph = OWGraph(tab)
-    self.graph.setAxisAutoScale(QwtPlot.xBottom)
-    self.graph.setAxisAutoScale(QwtPlot.yLeft)
-    tab.layout().addWidget(self.graph)
-    self.setGraphGrid()
+:class:`~OWGraph.OWGrap` is a convenience subclass of :class:`QwtPlot`
+and is imported from OWGraph module. For the graph, we use
+:func:`setAxisAutoScale` to request that the axis are automatically
+set in regard to the data that is plotted in the graph. We plot
+the graph in using the following code
 
-:obj:`OWGrap` is a convenience subclass of QwtPlot and is imported from
-OWGraph module. For the graph, we use :obj:`setAxisAutoScale` to
-request that the axis are automatically set in regard to the data that
-is plotted in the graph. We plot the graph in using the following
-code::
-
-    def drawLearningCurve(self, learner):
-        if not self.data: return
-        curve = self.graph.addCurve(learner.name, xData=self.curvePoints, yData=learner.score, autoScale=True)
-
-        learner.curve = curve
-        self.setGraphStyle(learner)
-        self.graph.replot()
+.. literalinclude:: OWLearningCurveC.py
+   :pyobject: OWLearningCurveC.drawLearningCurve
 
 This is simple. We store the curve returned from :obj:`addCurve` with a
-learner, and use a trick allowed in Orange that we can simply store
-this as a new attribute to the learning object. By default, Orange
-would give a warning of the type::
-
-    c:\Python23\Lib\site-packages\orange\OrangeWidgets\Test\OWLearningCurveC.py:269:
-     AttributeWarning: 'curve' is not a builtin attribute of 'kNNLearner'
-      setattr(learner, "curve", curve)
-
-but we surpress such warnings with a line::
-
-    warnings.filterwarnings("ignore", ".*builtin attribute.*", orange.AttributeWarning)
-
+learner.
 
 .. warning::
 
-   This is a very bad design. Please do **not** store widget data in the
-   input objects.
+   This is a very bad design. Please do **not** store widget specific
+   data in the input objects.
 
 
-in the initialization part of the widget. In this way, each learner
-also stores the current scores, which is a list of numbers to be
-plotted in Qwt graph. The details on how the plot is set are dealt
-with in :obj:`setGraphStyle` function:` ::
+In this way, each learner also stores the current scores, which is a
+list of numbers to be plotted in Qwt graph. The details on how the
+plot is set are dealt with in :obj:`setGraphStyle` function:
 
-    def setGraphStyle(self, learner):
-        curve = learner.curve
-        if self.graphDrawLines:
-            curve.setStyle(QwtPlotCurve.Lines)
-        else:
-            curve.setStyle(QwtPlotCurve.NoCurve)
-        curve.setSymbol(QwtSymbol(QwtSymbol.Ellipse, \
-          QBrush(QColor(0,0,0)), QPen(QColor(0,0,0)),
-          QSize(self.graphPointSize, self.graphPointSize)))
-        curve.setPen(QPen(learner.color, 5))
+.. literalinclude:: OWLearningCurveC.py
+   :pyobject: OWLearningCurveC.setGraphStyle
+
 
 Notice that the color of the plot line that is specific to the
 learner is stored in its attribute :obj:`color`
 expect that the color we used in a consistent way; for instance data
 instances of one class should be plotted in scatter plot and parallel
 axis plot using the same color. Developers are thus advised to use
-:obj:`ColorPaletteHSV`, which is provided as a method within
-:mod:`OWWidget` module. :obj:`ColorPaletteHSV` takes an
-integer as an attribute, and returns a list of corresponding number of
+:obj:`ColorPaletteHSV`, which can be imported from :mod:`OWWidget`
+module. :obj:`ColorPaletteHSV` takes an
+integer as an parameter, and returns a list of corresponding number of
 colors. In our learning curve widget, we use it within a function that
-sets the list box with learners::
+sets the list box with learners
 
-    def updatellb(self):
-        self.blockSelectionChanges = 1
-        self.llb.clear()
-        colors = ColorPaletteHSV(len(self.learners))
-        for (i,lt) in enumerate(self.learners):
-            l = lt[1]
-            item = QListWidgetItem(ColorPixmap(colors[i]), l.name)
-            self.llb.addItem(item)
-            item.setSelected(l.isSelected)
-            l.color = colors[i]
-        self.blockSelectionChanges = 0
+.. literalinclude:: OWLearningCurveC.py
+   :pyobject: OWLearningCurveC.updatellb
 
 The code above sets the items of the list box, where each item
 includes a learner and a small box in learner's color, which is in
 this widget also used as a sort of a legend for the graph. This box is
 returned by :obj:`ColorPixmap` function defined in
 :obj:`OWColorPalette.py`. Else, the classifier's list box control is
-defined in the initialization of the widget using::
+defined in the initialization of the widget using
 
-    self.cbox = OWGUI.widgetBox(self.controlArea, "Learners")
-    self.llb = OWGUI.listBox(self.cbox, self, "selectedLearners",
-                             selectionMode=QListWidget.MultiSelection,
-                             callback=self.learnerSelectionChanged)
-
-    self.llb.setMinimumHeight(50)
-    self.blockSelectionChanges = 0
+.. literalinclude:: OWLearningCurveC.py
+   :start-after: # ~SPHINX start color cb~
+   :end-before: # ~SPHINX end color cb~
 
 Now, what is this :obj:`blockSelectionChanges`? Any time
 user makes a selection change in list box of classifiers, we want to
 invoke the procedure called
-:obj:`learnerSelectionChanged`. But we want to perform
+:func:`learnerSelectionChanged`. But we want to perform
 actions there when changes in the list box are invoked from clicking
 by a user, and not by changing list box items from a program. This is
-why, every time we want :obj:`learnerSelectionChanged` not to
+why, every time we want :func:`learnerSelectionChanged` not to
 perform its function, we set :obj:`self.blockSelectionChanges`
 to 1.
 
-In our widget, :obj:`learnerSelectionChanged` figures out
+In our widget, :func:`learnerSelectionChanged` figures out
 if any curve should be removed from the graph (the user has just
 deselected the corresponding item in the list box) or added to the
-graph (the user just selected a learner)::
+graph (the user just selected a learner)
 
+.. literalinclude:: OWLearningCurveC.py
+   :pyobject: OWLearningCurveC.learnerSelectionChanged
+
+..
     def learnerSelectionChanged(self):
         if self.blockSelectionChanges:
             return
Add a comment to this file

docs/extend-widgets/rst/learningcurve-output.png

Old
Old image
New
New image
Add a comment to this file

docs/extend-widgets/rst/learningcurve.png

Old
Old image
New
New image
Add a comment to this file

docs/extend-widgets/rst/mouseoverwidgetintoolbox.png

Removed
Old image
Add a comment to this file

docs/extend-widgets/rst/progressbar-canvas.png

Removed
Old image
Add a comment to this file

docs/extend-widgets/rst/progressbar-widget.png

Removed
Old image

docs/extend-widgets/rst/progressbar.rst

 slower than split second, should report on the progress of their
 computation. For that purpose orange widgets use progress bar
 functions, to which they report progress in terms of per-cent
-completion of the task. The progress is then either reported above the
-icon of the widget in Orange Canvas.
+completion of the task. The progress is then either on the icon
+of the widget in Orange Canvas
 
-.. image:: progressbar-canvas.png
+.. image:: learningcurve.png
 
 or in the title bar of the widget's window. There, Orange also
 reports on the estimated time of completion of the task:
 
-.. image:: progressbar-widget.png
+.. image:: learningcurve-output.png
 
-Class :obj:`OWWidget`, the mother class of all
-widgets, has for this purpose a set of functions, which include:
+:class:`OWWidget` has for this purpose a set of functions, which include:
 
 .. method:: progressBarInit()
 
 
 .. method:: progressBarFinished()
 
-
 where value is any number between 0 and 100. Sometimes, like it is
 the case for our widgets, we know about the number of iterations involved in
 computation, and we would only like to advance the progress bar for
 some constant at the end of the iteration. For this, we use
-:obj:`ProgressBar` class in :obj:`OWGUI`, and the code in
+:class:`ProgressBar` class in :mod:`OWGUI`, and the code in
 the learning curve widget described in the previous lesson that does
 it is as follows::
 
     def getLearningCurve(self, learners):
-        pb = OWGUI.ProgressBar(self, iterations=self.steps*self.folds)
-        curve = orngTest.learningCurveN(learners, self.data,
-            folds=self.folds, proportions=self.curvePoints, callback=pb.advance)
+        pb = OWGUI.ProgressBar(self, iterations=self.steps * self.folds)
+        curve = Orange.evaluation.testing.learning_curve_n(
+            learners, self.data, folds=self.folds,
+            proportions=self.curvePoints, callback=pb.advance)
         pb.finish()
         return curve
 
-:obj:`ProgressBar` class removes the need to define any
-special function to compute the percent of the task done and set the
-progress bar, and instead uses :obj:`ProgressBar`'s method
-:obj:`advance` for this purpose.
+:class:`ProgressBar` class removes the need to define any special
+function to compute the percent of the task done and set the
+progress bar, and instead uses :class:`ProgressBar`'s method
+:func:`advance` for this purpose.
Add a comment to this file

docs/extend-widgets/rst/samplewidgetontoolbox.png

Old
Old image
New
New image
Add a comment to this file

docs/extend-widgets/rst/schemawithdatasamplerB.png

Old
Old image
New
New image
Add a comment to this file

docs/extend-widgets/rst/schemawithdatatable.png

Old
Old image
New
New image

docs/extend-widgets/rst/settings.rst

 
     class OWDataSamplerB(OWWidget):
         settingsList = ['proportion', 'commitOnChange']
-        def __init__(self, parent=None, signalManager=None):
 
 Any setting has to be initialized, and then we need to call
 :obj:`loadSettings()` to override defaults in case we have used
 You can now also inspect the :download:`complete code <OWDataSamplerB.py>`
 of this widget. To distinguish it with a widget we have developed in the
 previous section, we have designed a special
-:download:`icon <DataSamplerB.png>` for it. If you wish to test is
+:download:`icon <DataSamplerB.svg>` for it. If you wish to test is
 widget in the Orange Canvas, put its code in the Test directory w