build_tools.syllable_walk_tui.modules.analyzer.screen ===================================================== .. py:module:: build_tools.syllable_walk_tui.modules.analyzer.screen .. autoapi-nested-parse:: Analysis screen modal component. This module provides the AnalysisScreen modal for viewing corpus shape metrics. Displays raw, objective statistics about loaded corpora without interpretation. Design Philosophy: - Raw numbers only, no value judgments - Observable facts about corpus structure - Users draw their own conclusions - Percentages are objective facts, not interpretations Percentage Display Strategy: Percentages are shown in parentheses after raw counts where they provide meaningful context: - Length distribution: Count with percentage of total inventory e.g., "2:30 (20.0%)" means 30 syllables of length 2, which is 20% of all syllables - Hapax rate: Count with percentage of total unique syllables e.g., "Hapax (freq=1): 456 (37.0%)" means 456 syllables appear only once, comprising 37% of the vocabulary - Top 5 frequency: Count with percentage of total occurrences e.g., "the: 500 (4.1%)" means the syllable "the" accounts for 4.1% of all syllable occurrences in the corpus These percentages help users quickly understand: - How syllable lengths are distributed (length dist) - Vocabulary diversity / "long tail" characteristics (hapax rate) - Corpus concentration / Zipfian distribution (top N coverage) Attributes ---------- .. autoapisummary:: build_tools.syllable_walk_tui.modules.analyzer.screen.BAR_WIDTH build_tools.syllable_walk_tui.modules.analyzer.screen.BAR_FILLED build_tools.syllable_walk_tui.modules.analyzer.screen.BAR_EMPTY build_tools.syllable_walk_tui.modules.analyzer.screen.FEATURE_SHORT_NAMES Classes ------- .. autoapisummary:: build_tools.syllable_walk_tui.modules.analyzer.screen.TerrainDisplay build_tools.syllable_walk_tui.modules.analyzer.screen.WeightsModal build_tools.syllable_walk_tui.modules.analyzer.screen.FeatureSaturationDisplay build_tools.syllable_walk_tui.modules.analyzer.screen.MetricsDisplay build_tools.syllable_walk_tui.modules.analyzer.screen.AnalysisScreen Functions --------- .. autoapisummary:: build_tools.syllable_walk_tui.modules.analyzer.screen.format_delta build_tools.syllable_walk_tui.modules.analyzer.screen.render_terrain_bar build_tools.syllable_walk_tui.modules.analyzer.screen.render_exemplars_line build_tools.syllable_walk_tui.modules.analyzer.screen.format_weight_chip build_tools.syllable_walk_tui.modules.analyzer.screen.format_weights_row Module Contents --------------- .. py:data:: BAR_WIDTH :value: 30 .. py:data:: BAR_FILLED :value: '█' .. py:data:: BAR_EMPTY :value: '░' .. py:data:: FEATURE_SHORT_NAMES :type: dict[str, str] .. py:function:: format_delta(score) Format score as delta from neutral (0.5). :param score: Value from 0.0 to 1.0 :returns: Formatted string like "+0.047" or "-0.023" .. py:function:: render_terrain_bar(score, label) Render a terrain axis as an ASCII bar with pole labels. The bar shows position between two poles. Delta from neutral (0.5) is the key precision indicator. :param score: Value from 0.0 to 1.0 :param label: Text label to show after the bar (e.g., "JAGGED") :returns: Formatted string with bar, label, and delta .. py:function:: render_exemplars_line(exemplars, low_label, high_label) Render exemplar syllables for both poles of an axis. :param exemplars: PoleExemplars containing syllables from each pole, or None :param low_label: Label for low pole (e.g., "round") :param high_label: Label for high pole (e.g., "jagged") :returns: mala, luno jagged: krask, thrix" :rtype: Formatted string like " round .. py:function:: format_weight_chip(feature, weight, selected = False) Format a weight as a compact chip for display. :param feature: Feature name :param weight: Weight value :param selected: If True, highlight this chip :returns: -0.8]" or ">>liq:-0.8<<" if selected :rtype: Formatted chip like "[liq .. py:function:: format_weights_row(axis_weights, axis_index, selected_axis, selected_weight) Format all weights for an axis as a single row. :param axis_weights: The weights for this axis :param axis_index: Index of this axis (0=shape, 1=craft, 2=space) :param selected_axis: Currently selected axis index :param selected_weight: Currently selected weight index within the axis :returns: Formatted string with all weight chips .. py:class:: TerrainDisplay(terrain = None) Bases: :py:obj:`textual.containers.Vertical` Widget for displaying terrain visualization bars. Initialize terrain display. :param terrain: Computed terrain metrics, or None if not available .. py:attribute:: DEFAULT_CSS :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ TerrainDisplay { width: auto; height: auto; padding: 0 1; } TerrainDisplay .terrain-header { text-style: bold; color: $accent; } TerrainDisplay .terrain-row { color: $text; } TerrainDisplay .terrain-label { color: $text-muted; } TerrainDisplay .terrain-exemplars { color: $text-muted; text-style: italic; } """ .. raw:: html
Default TCSS. .. py:attribute:: terrain :value: None .. py:method:: compose() Create terrain display layout. .. py:class:: WeightsModal(weights_a, weights_b, on_close_callback = None) Bases: :py:obj:`textual.screen.Screen` Modal dialog for editing terrain weights for Patch A and Patch B independently. Initialize weights modal. :param weights_a: TerrainWeights for Patch A (modified in place) :param weights_b: TerrainWeights for Patch B (modified in place) :param on_close_callback: Function to call when modal closes .. py:attribute:: BINDINGS :value: [('escape', 'close_modal', 'Close'), ('q', 'close_modal', 'Close'), ('tab', 'next_weight', 'Next... A list of key bindings. .. py:attribute:: DEFAULT_CSS :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ WeightsModal { align: center middle; background: rgba(0, 0, 0, 0.7); } #weights-dialog { width: 100; height: auto; background: $surface; border: thick $accent; padding: 1 2; } .dialog-title { text-style: bold; color: $accent; text-align: center; width: 100%; margin-bottom: 1; } .patch-header { text-style: bold; color: $primary; margin-top: 1; text-align: center; } .axis-row { height: auto; width: 100%; } .axis-label { width: 8; color: $text-muted; } .weights-value { width: 1fr; color: $text; } .dialog-footer { color: $text-muted; text-align: center; margin-top: 1; border-top: solid $primary; padding-top: 1; } """ .. raw:: html
Default TCSS. .. py:attribute:: weights_a .. py:attribute:: weights_b .. py:attribute:: on_close_callback :value: None .. py:attribute:: selected_patch :value: 0 .. py:attribute:: selected_axis :value: 0 .. py:attribute:: selected_weight :value: 0 .. py:method:: compose() Create weights dialog layout. .. py:method:: on_mount() Initialize display after mounting. .. py:method:: action_close_modal() Close the modal and trigger callback. .. py:method:: action_next_weight() Navigate to next weight (Tab). .. py:method:: action_prev_weight() Navigate to previous weight (Shift+Tab). .. py:method:: action_decrease_weight() Decrease selected weight by 0.1 (j key). .. py:method:: action_increase_weight() Increase selected weight by 0.1 (k key). .. py:method:: action_reset_weights() Reset current patch's weights to defaults. .. py:class:: FeatureSaturationDisplay(metrics = None) Bases: :py:obj:`textual.containers.Vertical` Widget for displaying feature saturation metrics. Initialize feature saturation display. .. py:attribute:: DEFAULT_CSS :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ FeatureSaturationDisplay { width: auto; height: auto; } FeatureSaturationDisplay .feat-header { text-style: bold; color: $text; } FeatureSaturationDisplay .feat-row { color: $text; } FeatureSaturationDisplay .feat-label { color: $text-muted; } """ .. raw:: html
Default TCSS. .. py:attribute:: metrics :value: None .. py:method:: compose() Create feature saturation display. .. py:class:: MetricsDisplay(patch_name, metrics = None) Bases: :py:obj:`textual.containers.Vertical` Widget for displaying corpus shape metrics with percentages. Renders inventory, frequency, feature saturation, and terrain metrics for a single patch (A or B). Raw counts are displayed alongside derived percentages in parentheses where they provide meaningful context. Display Format: PATCH {A|B} ──────────────────────────────────────── INVENTORY Total syllables: 1,234 Length min: 2 Length max: 8 Length mean: 3.45 Length median: 3.0 Length std: 1.23 Length dist: 2:120 (9.7%), 3:456 (37.0%), ... FREQUENCY Total occurrences: 12,345 ... Hapax (freq=1): 456 (37.0%) ... Top 5 by frequency: the: 500 (4.1%) and: 350 (2.8%) ... FEATURE SATURATION TERRAIN (side-by-side display) Percentage Semantics: - Length dist %: Share of total inventory at each length - Hapax %: Proportion of vocabulary that appears only once - Top 5 %: Share of total occurrences for each top syllable .. attribute:: patch_name Identifier "A" or "B" for the corpus patch .. attribute:: metrics CorpusShapeMetrics instance or None if not loaded Initialize metrics display. :param patch_name: "A" or "B" to identify the patch :param metrics: Computed corpus shape metrics, or None if not loaded .. py:attribute:: DEFAULT_CSS :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ MetricsDisplay { width: 100%; height: auto; padding: 0 1; } MetricsDisplay .metrics-header { text-style: bold; color: $accent; margin-bottom: 0; } MetricsDisplay .metrics-subheader { text-style: bold; color: $text; margin-top: 1; } MetricsDisplay .metrics-row { color: $text; } MetricsDisplay .metrics-dim { color: $text-muted; } MetricsDisplay .feature-terrain-row { height: auto; margin-top: 1; } """ .. raw:: html
Default TCSS. .. py:attribute:: patch_name .. py:attribute:: metrics :value: None .. py:method:: compose() Create metrics display layout. .. py:class:: AnalysisScreen(metrics_a = None, metrics_b = None, corpus_path_a = None, corpus_path_b = None, export_dir = None, annotated_data_a = None, annotated_data_b = None) Bases: :py:obj:`textual.screen.Screen` Modal screen for viewing corpus shape metrics. Displays raw, objective statistics about loaded corpora: - Inventory metrics (counts, lengths) - Frequency distribution metrics - Feature saturation per phonetic feature - Terrain visualization Design Philosophy: Raw numbers only, no interpretation or judgment. Users observe and draw their own conclusions. Keybindings: Esc: Close screen and return to main view q: Close screen e: Export metrics to text file w: Open weights editor modal Initialize analysis screen with pre-computed metrics. :param metrics_a: Pre-computed metrics for Patch A, or None if not loaded :param metrics_b: Pre-computed metrics for Patch B, or None if not loaded :param corpus_path_a: Path to Patch A corpus directory :param corpus_path_b: Path to Patch B corpus directory :param export_dir: Directory for exports (defaults to _working/) :param annotated_data_a: Optional annotated data for Patch A (for exemplars) :param annotated_data_b: Optional annotated data for Patch B (for exemplars) .. note:: Metrics should be computed by the app before pushing this screen, as self.app is not available during compose(). .. py:attribute:: BINDINGS :value: [('escape', 'close_screen', 'Close'), ('q', 'close_screen', 'Close'), ('e', 'export_metrics',... A list of key bindings. .. py:attribute:: DEFAULT_CSS :value: Multiline-String .. raw:: html
Show Value .. code-block:: python """ AnalysisScreen { background: $surface; } #analysis-header { dock: top; height: 1; background: $boost; color: $text; text-style: bold; text-align: center; } #analysis-content { width: 100%; height: 1fr; } .patch-metrics { width: 1fr; height: auto; border: solid $primary; overflow-y: auto; } #analysis-footer { dock: bottom; height: 1; background: $boost; color: $text; padding: 0 1; text-align: center; } """ .. raw:: html
Default TCSS. .. py:attribute:: metrics_a :value: None .. py:attribute:: metrics_b :value: None .. py:attribute:: corpus_path_a :value: None .. py:attribute:: corpus_path_b :value: None .. py:attribute:: export_dir .. py:attribute:: annotated_data_a :value: None .. py:attribute:: annotated_data_b :value: None .. py:attribute:: feature_saturation_a .. py:attribute:: feature_saturation_b .. py:attribute:: weights_a .. py:attribute:: weights_b .. py:method:: compose() Create analysis screen layout. .. py:method:: action_close_screen() Close this screen and return to main view. .. py:method:: action_export_metrics() Export metrics to a text file. .. py:method:: action_open_weights() Open the weights editor modal. .. py:method:: action_refresh_exemplars() Resample exemplars with new RNG for variety.