Skip to content

Commit

Permalink
Merge pull request #56 from navigating-stories/useful-defaults
Browse files Browse the repository at this point in the history
add error when input channel is not corpus
  • Loading branch information
kodymoodley committed Apr 18, 2024
2 parents 5e3b424 + 2f385ab commit 1b94d3e
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 38 deletions.
35 changes: 35 additions & 0 deletions orangecontrib/storynavigation/modules/error_handling.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"Define error messages to be used in the Actor and Action analysis"

from Orange.widgets.widget import Msg

msg_wrong_input_for_stories = (
"Wrong input to `Stories`. "
"The input to `Story elements` needs to be a `Table`. \n"
"The input to `Stories` needs to be a `Corpus`."
)

msg_wrong_input_for_elements = (
"Wrong input to `Story elements`. "
"The input to `Story elements` needs to be a `Table`. \n"
"The input to `Stories` needs to be a `Corpus`."
)

msg_wrong_story_input_for_elements = (
"Wrong input to `Stories`. "
"The input to `Stories` needs to be a `Corpus`. \n"
"The input to `Custom tags` needs to be a `Table`."
)

msg_residual_error = (
"Could not process data. Check the inputs to the widget."
)

wrong_input_for_stories = Msg(msg_wrong_input_for_stories)
residual_error = Msg(msg_residual_error)
wrong_input_for_elements = Msg(msg_wrong_input_for_elements)
wrong_story_input_for_elements = Msg(msg_wrong_story_input_for_elements)


__all__ = [
"wrong_input_for_stories", "wrong_input_for_elements", "residual_error"
]
42 changes: 34 additions & 8 deletions orangecontrib/storynavigation/widgets/OWSNActionAnalysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
from storynavigation.modules.actionanalysis import ActionTagger
import storynavigation.modules.constants as constants
import storynavigation.modules.util as util
import storynavigation.modules.error_handling as error_handling


HTML = """
<!doctype html>
Expand Down Expand Up @@ -326,6 +328,11 @@ class Outputs:
actor_action_table_selected = Output("Action table: selected", Table)
actor_action_table_full = Output("Action table: all", Table)

class Error(OWWidget.Error):
wrong_input_for_stories = error_handling.wrong_input_for_stories
wrong_input_for_elements = error_handling.wrong_input_for_elements
residual_error = error_handling.residual_error

settingsHandler = DomainContextHandler()
settings_version = 2
search_features: List[Variable] = ContextSetting([])
Expand Down Expand Up @@ -489,9 +496,20 @@ def rehighlight_entities(self):

@Inputs.stories
def set_stories(self, stories=None):
self.stories = stories
"""Stories expects a Corpus. Because Corpus is a subclass of Table, Orange type checking
misses wrongly connected inputs.
"""
if stories is not None:
if not isinstance(stories, Corpus):
self.Error.wrong_input_for_stories()
else:
self.stories = stories
self.Error.clear()
else:
self.Error.clear()

if self.story_elements is not None:
self.Error.clear()
self.start(
self.run,
self.story_elements
Expand All @@ -504,18 +522,26 @@ def set_stories(self, stories=None):

@Inputs.story_elements
def set_story_elements(self, story_elements=None):
"""Story elements expects a table. Because Corpus is a subclass of Table, Orange type checking
misses wrongly connected inputs."""

if story_elements is not None:
self.story_elements = util.convert_orangetable_to_dataframe(story_elements)
self.actiontagger = ActionTagger(self.story_elements['lang'].tolist()[0])
self.start(
self.run,
self.story_elements
)
self.postags_box.setEnabled(True)
if isinstance(story_elements, Corpus):
self.Error.wrong_input_for_elements()
else:
self.Error.clear()
self.story_elements = util.convert_orangetable_to_dataframe(story_elements)
self.actiontagger = ActionTagger(self.story_elements['lang'].tolist()[0])
self.start(
self.run,
self.story_elements
)
self.postags_box.setEnabled(True)
else:
self.custom_tags.setChecked(False)
self.custom_tags.setEnabled(False)
self.postags_box.setEnabled(False)
self.Error.clear()

self.setup_controls()
self.doc_list.model().set_filter_string(self.regexp_filter)
Expand Down
48 changes: 37 additions & 11 deletions orangecontrib/storynavigation/widgets/OWSNActorAnalysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
from storynavigation.modules.actoranalysis import ActorTagger
import storynavigation.modules.constants as constants
import storynavigation.modules.util as util
import storynavigation.modules.error_handling as error_handling

HTML = """
<!doctype html>
Expand Down Expand Up @@ -329,6 +330,12 @@ class Outputs:
selected_customfreq_table = Output("Custom tag stats: selected", Table)
customfreq_table = Output("Custom tag stats: all", Table)

class Error(OWWidget.Error):
wrong_input_for_stories = error_handling.wrong_input_for_stories
wrong_input_for_elements = error_handling.wrong_input_for_elements
residual_error = error_handling.residual_error


settingsHandler = DomainContextHandler()
settings_version = 2
search_features: List[Variable] = ContextSetting([])
Expand Down Expand Up @@ -556,9 +563,20 @@ def pos_selection_changed(self):

@Inputs.stories
def set_stories(self, stories=None):
self.stories = stories
"""Stories expects a Corpus. Because Corpus is a subclass of Table, Orange type checking
misses wrongly connected inputs.
"""
if (stories is not None):
if not isinstance(stories, Corpus):
self.Error.wrong_input_for_stories()
else:
self.stories = stories
self.Error.clear()
else:
self.Error.clear()

if self.story_elements is not None:
self.Error.clear()
self.start(
self.run,
self.story_elements
Expand All @@ -571,25 +589,32 @@ def set_stories(self, stories=None):

@Inputs.story_elements
def set_story_elements(self, story_elements=None):
"""Story elements expects a table. Because Corpus is a subclass of Table, Orange type checking
misses wrongly connected inputs."""

if story_elements is not None:
self.story_elements = util.convert_orangetable_to_dataframe(story_elements)
self.actortagger = ActorTagger(self.story_elements['lang'].tolist()[0])
self.start(
self.run,
self.story_elements
)
self.postags_box.setEnabled(True)
if isinstance(story_elements, Corpus):
self.Error.wrong_input_for_elements()
else:
self.Error.clear()
self.story_elements = util.convert_orangetable_to_dataframe(story_elements)
self.actortagger = ActorTagger(self.story_elements['lang'].tolist()[0])
self.start(
self.run,
self.story_elements
)
self.postags_box.setEnabled(True)
else:
self.nc.setChecked(False)
self.sc.setChecked(False)
self.allc.setChecked(False)
self.custom_tags.setChecked(False)

self.custom_tags.setEnabled(False)
self.postags_box.setEnabled(False)
self.main_agents_box.setEnabled(False)
self.metric_name_combo.setEnabled(False)

self.Error.clear()

self.setup_controls()
self.doc_list.model().set_filter_string(self.regexp_filter)
self.list_docs()
Expand Down Expand Up @@ -642,8 +667,9 @@ def reset_widget(self):
self.filter_input.clear()
# Models/vars
self.doc_list_model.clear()
# Warnings
# Warnings and Errors
self.Warning.clear()
self.Error.clear()
# WebView
self.doc_webview.setHtml("")

Expand Down
53 changes: 34 additions & 19 deletions orangecontrib/storynavigation/widgets/OWSNTagger.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from Orange.data.pandas_compat import table_to_frames
import pandas as pd
import numpy as np
import storynavigation.modules.error_handling as error_handling

class OWSNTagger(OWWidget, ConcurrentWidgetMixin):
name = 'Elements'
Expand All @@ -25,6 +26,11 @@ class Inputs:
class Outputs:
dataset_level_data = Output('Story elements', Table)

class Error(OWWidget.Error):
wrong_story_input_for_elements = error_handling.wrong_story_input_for_elements
# wrong_input_for_customtagselements = error_handling.wrong_input_for_elements
residual_error = error_handling.residual_error

settingsHandler = DomainContextHandler()
settings_version = 2
autocommit = Setting(True)
Expand Down Expand Up @@ -103,34 +109,43 @@ def __init__(self):
def set_stories(self, stories=None):
idx = 0
self.stories = []
for document in stories:
text = ''
for field in stories.domain.metas:
text_field_name = str(field)
if text_field_name.lower() in ['text', 'content']:
text = str(stories[idx, text_field_name])

if len(text) > 0:
self.stories.append((text, idx))
if stories is not None:
if not isinstance(stories, Corpus):
self.Error.wrong_story_input_for_elements()
else:
print(idx)

idx += 1
self.Error.clear()
for document in stories:
text = ''
for field in stories.domain.metas:
text_field_name = str(field)
if text_field_name.lower() in ['text', 'content']:
text = str(stories[idx, text_field_name])

if len(text) > 0:
self.stories.append((text, idx))

idx += 1
else:
self.Error.clear()

@Inputs.custom_tag_dict
def set_custom_tags(self, custom_tag_dict=None):
if custom_tag_dict is not None:
self.custom_tag_dict = pd.concat(table_to_frames(custom_tag_dict), axis=1) # convert the Orange data table to a pandas dataframe, the concat is needed to merge multiple dataframes (Orange splits into multiple frames whenever column uses a different data type)
if len(self.custom_tag_dict.columns) >= 2:
self.select_word_column_combo.setEnabled(True)
self.custom_tag_dict_columns = list(self.custom_tag_dict.columns)
self.select_word_column_combo.clear()
self.select_word_column_combo.addItems(self.custom_tag_dict_columns)

if isinstance(custom_tag_dict, Corpus):
self.Error.wrong_story_input_for_elements()
else:
self.Error.clear()
self.custom_tag_dict = pd.concat(table_to_frames(custom_tag_dict), axis=1) # convert the Orange data table to a pandas dataframe, the concat is needed to merge multiple dataframes (Orange splits into multiple frames whenever column uses a different data type)
if len(self.custom_tag_dict.columns) >= 2:
self.select_word_column_combo.setEnabled(True)
self.custom_tag_dict_columns = list(self.custom_tag_dict.columns)
self.select_word_column_combo.clear()
self.select_word_column_combo.addItems(self.custom_tag_dict_columns)
else:
self.custom_tag_dict = None
self.select_word_column_combo.clear()
self.select_word_column_combo.setEnabled(False)
self.Error.clear()

def reset_widget(self):
self.stories = None
Expand Down

0 comments on commit 1b94d3e

Please sign in to comment.