Source code for ipyannotations.text.classification

from typing import Sequence

import IPython.display
import ipywidgets as widgets
import traitlets

from ..base import LabellingWidgetMixin
from .. import generic
from ..generic.generic_mixin import GenericWidgetMixin


def _text_display_function(item: str):
    IPython.display.display(IPython.display.Markdown(item))


[docs]class ClassLabeller(generic.ClassLabeller): """A text classification widget. This widget lets you assign a single class to text. """ def __init__( self, options: Sequence[str] = (), max_buttons: int = 12, allow_freetext: bool = True, *args, **kwargs, ): """Create a widget for classifying text. Parameters ---------- options : Sequence[str], optional The classes, by default () max_buttons : int, optional The number of buttons to allow, before switching to a dropdown menu, by default 12 allow_freetext : bool, optional If a text box should be available for new classes, by default True """ super().__init__( options=options, max_buttons=max_buttons, allow_freetext=allow_freetext, display_function=_text_display_function, *args, **kwargs, ) # type: ignore
[docs]class MulticlassLabeller(generic.MulticlassLabeller): def __init__( self, options: Sequence[str] = (), max_buttons: int = 12, allow_freetext: bool = True, *args, **kwargs, ): """Create a widget for multi-class assignment. Parameters ---------- options : Sequence[str], optional The options for classes, by default () max_buttons : int, optional How many buttons to display before switching to a multi-select tool, by default 12 allow_freetext : bool, optional Whether to allow free-text submission in a text box, by default True """ super().__init__( options=options, max_buttons=max_buttons, allow_freetext=allow_freetext, display_function=_text_display_function, *args, **kwargs, ) # type: ignore
[docs]class SentimentLabeller( GenericWidgetMixin, LabellingWidgetMixin, widgets.VBox ): """A sentiment classification widget. This widget presents three label options, for classifying text into one of negative, neutral, or positive sentiment. """ data = traitlets.Unicode() def __init__(self, *args, **kwargs): """Create a sentiment classification widget.""" super().__init__( display_function=_text_display_function, *args, **kwargs ) self.buttons = [ widgets.Button( description="negative", icon="thumbs-down", button_style="danger", # layout=button_layout, ), widgets.Button( description="neutral", icon="equals", # layout=button_layout, ), widgets.Button( description="positive", icon="thumbs-up", button_style="success", # layout=button_layout, ), ] for button in self.buttons: button.on_click(self.submit) self.display_widget = widgets.Output( layout=widgets.Layout(margin="auto") ) self.children = [ widgets.Box( (self.display_widget,), layout=widgets.Layout( justify_content="center", padding="2.5% 0", display="flex", width="100%", ), ), widgets.HBox( [ widgets.HBox(), widgets.HBox(self.buttons), widgets.HBox([self.skip_button, self.undo_button]), ], layout=widgets.Layout(justify_content="space-between"), ), ]
[docs] def submit(self, sender: widgets.Button): # type: ignore """Submit the label. Parameters ---------- sender : widgets.Button One of the three interface buttons. """ value = sender.description self.data = value super().submit()
def _handle_keystroke(self, event): # the default enter shouldn't apply if event.get("key") == "Enter": return super()._handle_keystroke(event) keys = [str(i) for i in range(1, 10)] + ["0"] for key, btn in zip(keys, self.buttons): if event.get("key") == key: self.submit(btn)