Skip to content

Latest commit

 

History

History
245 lines (169 loc) · 6.2 KB

File metadata and controls

245 lines (169 loc) · 6.2 KB

i18n

Internationalization (i18n) module for the RegressionLab application.

Overview

The i18n.py module provides language support for the application, allowing all UI messages, logs, and errors to be displayed in different languages based on the LANGUAGE environment variable.

Supported Languages

  • Spanish ('es', 'español', 'spanish', 'esp'): Default language
  • English ('en', 'english', 'eng', etc.): Secondary language
  • German ('de', 'german', 'deutsch', 'ger'): Supported via src/locales/de.json

Key Functions

Initialization

initialize_i18n(language: Optional[str] = None) -> None

Initialize the internationalization system.

This function should be called once at application startup. If no language is specified, it reads from the LANGUAGE environment variable.

Parameters:

  • language: Optional language code ('es', 'en', or 'de'). If None, reads from env var.

Example:

from i18n import initialize_i18n

# Initialize with default (from env var)
initialize_i18n()

# Initialize with specific language
initialize_i18n('en')

Translation

t(key: str, **kwargs) -> str

Translate a key to the current language.

This function retrieves the translation for a given key in the current language. The key uses dot notation to navigate nested dictionaries.

Parameters:

  • key: Translation key in dot notation (e.g., 'menu.welcome')
  • **kwargs: Optional format parameters for string interpolation

Returns:

  • Translated string, or the key itself if translation not found

Examples:

from i18n import t

# Simple translation
message = t('menu.welcome')
# Returns: 'Welcome, scientist. What would you like to do?' (in English)

# Translation with formatting
error_msg = t('error.fitting_failed_details', error='Invalid data')
# Returns: 'RegressionLab was unable to fit the data.\n\nDetails: Invalid data'

Translation File Structure

Translations are stored in JSON files in the locales/ directory (pretty-printed for readability and maintainability):

src/locales/
├── en.json  # English translations
├── es.json  # Spanish translations
└── de.json  # German translations

Translation Key Format

Keys use dot notation to represent nested structure:

{
  "menu": {
    "title": "RegressionLab",
    "welcome": "Welcome, scientist. What would you like to do?",
    "exit": "Exit"
  },
  "error": {
    "title": "Error",
    "fitting_failed": "Fitting failed"
  }
}

Access with: t('menu.welcome'), t('error.fitting_failed')

Usage Examples

In UI Code

from tkinter import messagebox
from i18n import t

# Show error dialog
messagebox.showerror(
    t('error.title'),
    t('error.fitting_failed')
)

In Logger Code

from utils.logger import get_logger
from i18n import t

logger = get_logger(__name__)
logger.info(t('log.application_starting'))

With String Formatting

from i18n import t

# Translation with placeholders
message = t('log.data_loaded', rows=100, cols=5)
# Translation file: "Data loaded: {rows} rows, {cols} columns"
# Result: "Data loaded: 100 rows, 5 columns"

Language Detection

The module automatically detects language from:

  1. Environment variable: LANGUAGE (e.g., LANGUAGE=es)
  2. Function parameter: When calling initialize_i18n('en')
  3. Default fallback: Spanish ('es') if not specified

Supported Language Values

The module accepts various formats and normalizes them:

  • Spanish: 'es', 'español', 'spanish', 'esp'
  • English: 'en', 'english', 'inglés', 'ingles', 'eng'
  • German: 'de', 'german', 'deutsch', 'ger'

Error Handling

If a translation file is missing or a key is not found:

  • Missing file: Falls back to default language (Spanish)
  • Missing key: Returns the key itself as fallback
# If 'menu.unknown_key' doesn't exist
result = t('menu.unknown_key')
# Returns: 'menu.unknown_key' (the key itself)

Initialization

The module does not automatically initialize on import for performance reasons. Applications should call initialize_i18n() explicitly:

# In main_program.py or app.py
from i18n import initialize_i18n

# Initialize at startup
initialize_i18n()

# Now translations are available
from i18n import t
message = t('menu.welcome')

Best Practices

For End Users

  1. Set language: Use LANGUAGE environment variable in .env:

    LANGUAGE=es
  2. Restart app: Language changes require application restart

For Developers

  1. Always initialize: Call initialize_i18n() before using t()

  2. Use descriptive keys: Use clear, hierarchical key names

    # Good
    t('error.fitting.failed')
    
    # Bad
    t('err1')
  3. Provide context: Include format parameters for dynamic content

    t('log.file_loaded', filename='data.csv', size=1024)
  4. Add translations: When adding new UI text, add keys to en.json, es.json, and de.json

Adding New Translations

To add a new translation:

  1. Add key to English file (locales/en.json):

    {
      "new_section": {
        "new_key": "English text"
      }
    }
  2. Add key to Spanish and German files (locales/es.json, locales/de.json) with the same structure and translated values.

  3. Use in code:

    message = t('new_section.new_key')

Technical Details

Translation Loading

  • Translations are loaded on first use of each language and cached in memory
  • Each language file is read at most once; switching language (e.g. en → es → en) reuses the cached data
  • After initialization, no file I/O for the current language

Performance

  • Per-language cache: Loaded translation dicts are kept in _translation_cache; switching back to a language does not re-read or re-parse the JSON file
  • Resolved-key cache: For the current language, each resolved key (e.g. menu.welcome) is cached so repeated t('menu.welcome') calls avoid repeated nested lookups
  • Key resolution is O(n) in key depth on first lookup, then O(1) for the same key

For more information about internationalization, see Customization Guide.