| import os |
| import pandas as pd |
| from rapidfuzz import process, fuzz |
|
|
| |
| |
| |
|
|
| BASE_DIR = os.path.dirname( |
| os.path.dirname( |
| os.path.abspath(__file__) |
| ) |
| ) |
|
|
| DICTIONARY_FILE = os.path.join( |
| BASE_DIR, |
| "data", |
| "kiembu_dictionary.csv" |
| ) |
|
|
| |
| |
| |
|
|
| def load_dictionary(): |
|
|
| try: |
|
|
| |
| df = pd.read_csv( |
| DICTIONARY_FILE, |
| sep="\t", |
| encoding="utf-8" |
| ) |
|
|
| |
| |
| if len(df.columns) < 2: |
|
|
| df = pd.read_csv( |
| DICTIONARY_FILE, |
| sep=",", |
| encoding="utf-8" |
| ) |
|
|
| df.columns = ( |
| df.columns |
| .str.strip() |
| ) |
|
|
| df.fillna("", inplace=True) |
|
|
| print("Dictionary loaded successfully") |
| print("Columns:", df.columns.tolist()) |
| print("Records:", len(df)) |
|
|
| return df |
|
|
| except Exception as e: |
|
|
| print( |
| f"Dictionary loading error: {e}" |
| ) |
|
|
| return pd.DataFrame() |
|
|
| |
| |
| |
|
|
| dictionary_df = load_dictionary() |
|
|
| |
| |
| |
|
|
| def translate_word( |
| word, |
| direction="English → Kiembu", |
| df=None |
| ): |
|
|
| if df is None: |
| df = dictionary_df |
|
|
| if df.empty: |
| return "Dictionary data unavailable." |
|
|
| if not word: |
| return "Please enter a word." |
|
|
| query = word.strip() |
|
|
| if not query: |
| return "Please enter a word." |
|
|
| query_lower = query.lower() |
|
|
| |
| |
| |
|
|
| if direction == "English → Kiembu": |
|
|
| source_col = "English" |
| target_col = "Kiembu" |
|
|
| else: |
|
|
| source_col = "Kiembu" |
| target_col = "English" |
|
|
| |
| |
| |
|
|
| if source_col not in df.columns: |
|
|
| return ( |
| f"Column '{source_col}' " |
| f"not found in dictionary." |
| ) |
|
|
| if target_col not in df.columns: |
|
|
| return ( |
| f"Column '{target_col}' " |
| f"not found in dictionary." |
| ) |
|
|
| |
| |
| |
|
|
| exact_match = df[ |
| df[source_col] |
| .astype(str) |
| .str.strip() |
| .str.lower() |
| == query_lower |
| ] |
|
|
| if not exact_match.empty: |
|
|
| source_word = str( |
| exact_match.iloc[0][source_col] |
| ).strip() |
|
|
| translated_word = str( |
| exact_match.iloc[0][target_col] |
| ).strip() |
|
|
| return ( |
| f"{source_word}\n\n" |
| f"➜ {translated_word}" |
| ) |
|
|
| |
| |
| |
|
|
| choices = ( |
| df[source_col] |
| .astype(str) |
| .str.strip() |
| .tolist() |
| ) |
|
|
| best_match = process.extractOne( |
| query, |
| choices, |
| scorer=fuzz.WRatio |
| ) |
|
|
| if not best_match: |
|
|
| return "No translation found." |
|
|
| matched_word = best_match[0] |
| score = best_match[1] |
|
|
| if score < 75: |
|
|
| return ( |
| "No close translation found.\n\n" |
| f"Best score: {score}" |
| ) |
|
|
| row = df[ |
| df[source_col] |
| .astype(str) |
| .str.strip() |
| == matched_word |
| ] |
|
|
| if row.empty: |
|
|
| return "No translation found." |
|
|
| translated_word = str( |
| row.iloc[0][target_col] |
| ).strip() |
|
|
| return ( |
| f"Suggested Match: {matched_word}\n\n" |
| f"➜ {translated_word}" |
| ) |
|
|
| |
| |
| |
|
|
| if __name__ == "__main__": |
|
|
| print( |
| translate_word( |
| "house", |
| "English → Kiembu" |
| ) |
| ) |
|
|
| print( |
| translate_word( |
| "Nyomba", |
| "Kiembu → English" |
| ) |
| ) |