Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions orangecontrib/prototypes/widgets/owquickselect.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
from Orange.data import Table, DiscreteVariable
from Orange.widgets import widget, gui, settings
from Orange.widgets.utils.annotated_data import ANNOTATED_DATA_SIGNAL_NAME, \
create_annotated_table
lazy_annotated_table
from Orange.widgets.utils.signals import LazyValue
from Orange.widgets.utils.itemmodels import DomainModel
from Orange.widgets.utils.state_summary import format_summary_details
from Orange.widgets.utils.widgetpreview import WidgetPreview
Expand Down Expand Up @@ -69,8 +70,6 @@ def set_data(self, data):
self.closeContext()
self.data = data
self.Error.no_categorical.clear()
# TODO: Check that contexts are retrieved properly, also when removing
# and re-adding a connection

if data:
self.var_model.set_domain(data.domain)
Expand Down Expand Up @@ -114,10 +113,15 @@ def commit(self):
column = self.data.get_column(self.variable)
valind = self.variable.values.index(self.value)
mask = column == valind
annotated = create_annotated_table(self.data, np.flatnonzero(mask))
matching = self.data[mask]
unmatched = self.data[~mask]
self.n_matched = len(matching)
annotated = lazy_annotated_table(self.data, np.flatnonzero(mask))
self.n_matched = int(np.sum(mask))
# Don't use `mask` in lambdas because it wastes memory
matching = LazyValue[Table](
lambda: self.data[self.data.get_column(self.variable) == valind],
domain=self.data.domain, length=self.n_matched)
unmatched = LazyValue[Table](
lambda: self.data[self.data.get_column(self.variable) != valind],
domain=self.data.domain, length=len(self.data) - self.n_matched)

self.Outputs.matching.send(matching)
self.Outputs.unmatched.send(unmatched)
Expand Down
176 changes: 176 additions & 0 deletions orangecontrib/prototypes/widgets/tests/test_owquickselect.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import unittest

import numpy as np

from Orange.data import DiscreteVariable, ContinuousVariable, StringVariable, \
Domain, Table
from Orange.widgets.tests.base import WidgetTest
from Orange.widgets.tests.utils import simulate
from orangecontrib.prototypes.widgets.owquickselect import OWQuickSelect

class TestOWQuickSelect(WidgetTest):
def setUp(self):
self.widget: OWQuickSelect = self.create_widget(OWQuickSelect)
a = DiscreteVariable("A", values=("a", "b", "c"))
b = DiscreteVariable("B", values=("x", "y"))
c = DiscreteVariable("C", values=("1", "2", "3"))
d, e, f = (ContinuousVariable(c) for c in "DEF")
g = StringVariable("G")
self.domain = Domain([d, a, b, e], c, [f, g])

self.data = Table.from_numpy(
self.domain,
X=[[1, 0, 0, 2],
[0, 1, 1, 3],
[1, 2, 0, 4],
[2, np.nan, 1, 5],
[0, 0, 1, 6]],
Y=[0, 1, 0, 2, 2],
metas=[[2, "x"], [np.nan, "y"], [np.nan, "x"], [1, "y"], [2, "x"]]

)

def test_model_and_settings(self):
w = self.widget
var_combo = w.controls.variable
value_combo = w.controls.value

self.send_signal(self.data)
self.assertEqual(len(w.var_model), 3)
self.assertIs(w.variable, self.domain["A"])
self.assertEqual(len(w.value_model), 3)
self.assertEqual(w.value_model[0], "a")

simulate.combobox_activate_index(var_combo, 1)
self.assertEqual(len(w.value_model), 2)
self.assertEqual(w.value, "x")

simulate.combobox_activate_index(value_combo, 1)
self.assertEqual(w.value, "y")

self.send_signal(None)
self.assertEqual(len(w.var_model), 0)
self.assertIsNone(w.variable)
self.assertEqual(len(w.value_model), 0)
self.assertEqual(w.value, "")

self.send_signal(w.Inputs.data, self.data)
self.assertEqual(len(w.var_model), 3)
self.assertIs(w.variable, self.domain["B"])
self.assertEqual(len(w.value_model), 2)
self.assertEqual(w.value, "y")

def test_no_categorical(self):
w = self.widget
no_cat = self.data.transform(
Domain(
[self.domain["D"], self.domain["E"]],
None,
[self.domain["F"], self.domain["G"]]))

self.send_signal(no_cat)
self.assertEqual(len(w.var_model), 0)
self.assertIsNone(w.variable)
self.assertTrue(w.Error.no_categorical.is_shown())
self.assertIsNone(self.get_output(w.Outputs.annotated))
w.send_report()

self.send_signal(None)
self.assertEqual(len(w.var_model), 0)
self.assertIsNone(w.variable)
self.assertFalse(w.Error.no_categorical.is_shown())
self.assertIsNone(self.get_output(w.Outputs.annotated))
w.send_report()

self.send_signal(no_cat)
self.assertTrue(w.Error.no_categorical.is_shown())
self.assertIsNone(self.get_output(w.Outputs.annotated))
w.send_report()

self.send_signal(self.data)
self.assertFalse(w.Error.no_categorical.is_shown())
self.assertIsNotNone(self.get_output(w.Outputs.annotated))
w.send_report()

self.send_signal(no_cat)
self.assertIsNone(self.get_output(w.Outputs.annotated))

def test_missing_context_value(self):
w = self.widget
var_combo = w.controls.variable
value_combo = w.controls.value

self.send_signal(self.data)
simulate.combobox_activate_index(var_combo, 1)
simulate.combobox_activate_index(value_combo, 1)
self.assertEqual(w.value, "y")

new_b = DiscreteVariable("B", values=("x", ))
new_data = self.data.transform(
Domain(self.domain.attributes[:2] + (new_b, ),
self.domain.class_var,
self.domain.metas))

self.send_signal(None)
self.assertIsNone(w.variable)
self.assertEqual(w.value, "")

self.send_signal(new_data)
self.assertIs(w.variable, new_b)
self.assertEqual(w.value, "x")

def test_output(self):
w = self.widget
var_combo = w.controls.variable
value_combo = w.controls.value

self.send_signal(self.data)
simulate.combobox_activate_index(var_combo, 1)

np.testing.assert_equal(
self.get_output(w.Outputs.annotated).metas[:, -1],
[1, 0, 1, 0, 0])
np.testing.assert_equal(
self.get_output(w.Outputs.matching).X,
self.data.X[[0, 2]])
np.testing.assert_equal(
self.get_output(w.Outputs.unmatched).X,
self.data.X[[1, 3, 4]])

simulate.combobox_activate_index(value_combo, 1)
np.testing.assert_equal(
self.get_output(w.Outputs.annotated).metas[:, -1],
[0, 1, 0, 1, 1])
np.testing.assert_equal(
self.get_output(w.Outputs.matching).X,
self.data.X[[1, 3, 4]])
np.testing.assert_equal(
self.get_output(w.Outputs.unmatched).X,
self.data.X[[0, 2]])

# Test with nans
simulate.combobox_activate_index(var_combo, 0)
self.assertIs(w.variable, self.domain["A"])
self.assertEqual(w.value, "a")
np.testing.assert_equal(
self.get_output(w.Outputs.annotated).metas[:, -1],
[1, 0, 0, 0, 1])

simulate.combobox_activate_index(value_combo, 1)
np.testing.assert_equal(
self.get_output(w.Outputs.annotated).metas[:, -1],
[0, 1, 0, 0, 0])

simulate.combobox_activate_index(value_combo, 2)
np.testing.assert_equal(
self.get_output(w.Outputs.annotated).metas[:, -1],
[0, 0, 1, 0, 0])

self.send_signal(None)
self.send_signal(self.data)
np.testing.assert_equal(
self.get_output(w.Outputs.annotated).metas[:, -1],
[0, 0, 1, 0, 0])

if __name__ == "__main__":
unittest.main()
9 changes: 3 additions & 6 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,9 @@ def include_documentation(local_dir, install_dir):
"orangecontrib.prototypes.widgets": ["icons/*.svg", "tests/*.tab"]
},
install_requires=[
'Orange3>=3.34',
'numpy>=1.19.5',
'scipy>=1.9.0',
'scikit-learn>=1.0.1',
'pyqtgraph',
'AnyQt>=0.1.0',
'Orange3>=3.36.2',
'scipy>=1.9.2',
'AnyQt>=0.2.0',
'pandas>=1.3.0',
'openai>=1',
'tiktoken',
Expand Down
8 changes: 4 additions & 4 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ setenv =
deps =
{env:PYQT_PYPI_NAME:PyQt5}=={env:PYQT_PYPI_VERSION:5.15.*}
{env:WEBENGINE_PYPI_NAME:PyQtWebEngine}=={env:WEBENGINE_PYPI_VERSION:5.15.*}
oldest: orange3==3.34.0
oldest: orange-canvas-core==0.1.28
oldest: orange-widget-base==4.19.0
oldest: orange3==3.36.2
oldest: orange-canvas-core==0.1.30
oldest: orange-widget-base==4.22.0
oldest: scipy==1.9.2
oldest: pandas==1.4.0
oldest: anyqt==0.1.0
oldest: anyqt==0.2.0
oldest: openai==1.0.0
latest: https://github.com/biolab/orange3/archive/refs/heads/master.zip#egg=orange3
latest: https://github.com/biolab/orange-canvas-core/archive/refs/heads/master.zip#egg=orange-canvas-core
Expand Down