diff --git a/__pycache__/master_export2translate.cpython-310.pyc b/__pycache__/master_export2translate.cpython-310.pyc new file mode 100644 index 0000000..398c29a Binary files /dev/null and b/__pycache__/master_export2translate.cpython-310.pyc differ diff --git a/llm_translate_text.py b/llm_translate_text.py index 2133f91..c72b0fc 100644 --- a/llm_translate_text.py +++ b/llm_translate_text.py @@ -1,11 +1,12 @@ import pandas as pd -import openai +from openai import OpenAI import os import re -import argparse +import logging from openai_api_key import api_key +from master_export2translate import transformar_texto -openai_api_key = api_key() +client = OpenAI(api_key=api_key()) # Diccionario de idiomas IDIOMAS = { @@ -14,90 +15,147 @@ IDIOMAS = { 3: ("Spanish", "es"), 4: ("Russian", "ru"), 5: ("French", "fr"), - 6: ("German", "de") + 6: ("German", "de"), } + +def configurar_logger(): + logger = logging.getLogger("translate_logger") + logger.setLevel(logging.DEBUG) # Cambiado a DEBUG para más información + fh = logging.FileHandler("translate_log.log", encoding="utf-8") + fh.setLevel(logging.DEBUG) + formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s") + fh.setFormatter(formatter) + logger.addHandler(fh) + return logger + + +logger = configurar_logger() + + def mostrar_idiomas(): print("Selecciona el idioma de destino:") for numero, (nombre, _) in IDIOMAS.items(): print(f"{numero}: {nombre}") + def translate_text(text, source_lang, target_lang): - response = openai.Completion.create( - engine="davinci", - prompt=f"Translate the following text from {source_lang} to {target_lang} while preserving special fields like <> and <#>: {text}", - max_tokens=150, # Ajusta esto según tus necesidades - n=1, - stop=None, - temperature=0.3 + logger.info( + f"Solicitando traducción de {source_lang} a {target_lang} para el texto: {text}" ) - return response.choices[0].text.strip() + response = client.chat.completions.create( + model="gpt-3.5-turbo", + messages=[ + {"role": "system", "content": f"You are a translator."}, + { + "role": "user", + "content": f"Translate the following text from {source_lang} to {target_lang} while preserving special fields like <> and <#>. This texts are for an HMI industrial machine: {text}", + }, + ], + max_tokens=150, + temperature=0.3, + ) + translated_text = response.choices[0].message.content.strip() + logger.info(f"Respuesta recibida: {translated_text}") + return translated_text + def translate_batch(texts, source_lang, target_lang): joined_text = "\n".join(texts) - response = openai.Completion.create( - engine="davinci", - prompt=f"Translate the following texts from {source_lang} to {target_lang} while preserving special fields like <> and <#>:\n\n{joined_text}", - max_tokens=1500, # Ajusta esto según tus necesidades - n=1, - stop=None, - temperature=0.3 + logger.info( + f"Solicitando traducción de {source_lang} a {target_lang} para el lote de textos:\n{joined_text}" ) - translations = response.choices[0].text.strip().split('\n') + response = client.chat.completions.create( + model="gpt-3.5-turbo", + messages=[ + {"role": "system", "content": f"You are a translator."}, + { + "role": "user", + "content": f"Translate the following texts from {source_lang} to {target_lang} while preserving special fields like <> and <#>:\n\n{joined_text}", + }, + ], + max_tokens=1500, + temperature=0.3, + ) + translations = response.choices[0].message.content.strip().split("\n") + logger.info(f"Respuestas recibidas:\n{translations}") return translations + def texto_requiere_traduccion(texto): - # Comprobar si hay una palabra con más de 3 letras y si no es solo campos especiales - palabras = re.findall(r'\b\w{4,}\b', texto) - campos_especiales = re.findall(r'<.*?>', texto) - return len(palabras) > 0 and len(campos_especiales) < len(re.findall(r'<#>', texto)) + palabras = re.findall(r"\b\w{4,}\b", texto) + campos_especiales = re.findall(r"<.*?>", texto) + requiere_traduccion = len(palabras) > 0 or len(campos_especiales) != len( + re.findall(r"<#>", texto) + ) + logger.debug( + f"Decisión de traducción para texto '{texto}': {'Sí' if requiere_traduccion else 'No'} (palabras > 3 letras: {len(palabras) > 0}, solo campos especiales: {len(campos_especiales) == len(re.findall(r'<#>', texto))})" + ) + return requiere_traduccion + def main(file_path, target_lang_code, traducir_todo, batch_size=10): - # Cargar el archivo master_export2translate.xlsx df = pd.read_excel(file_path) - - # Identificar la columna clave y la columna de destino source_col = "it-IT" target_col = f"{target_lang_code} Translated" - # Si la columna de destino ya existe, mantenerla o eliminarla según la opción de traducción if target_col in df.columns and not traducir_todo: df[target_col] = df[target_col] else: df[target_col] = None - # Preparar los textos para traducir + texts_to_translate = [] + indices_to_translate = [] + if traducir_todo: - texts_to_translate = [text for text in df[source_col].astype(str).tolist() if texto_requiere_traduccion(text)] + for index, text in df[source_col].astype(str).items(): + processed_text = transformar_texto(text) + if texto_requiere_traduccion(processed_text): + texts_to_translate.append(text) + indices_to_translate.append(index) else: - texts_to_translate = [text for text in df.loc[df[target_col].isnull(), source_col].astype(str).tolist() if texto_requiere_traduccion(text)] + for index, text in ( + df.loc[df[target_col].isnull(), source_col].astype(str).items() + ): + processed_text = transformar_texto(text) + if texto_requiere_traduccion(processed_text): + texts_to_translate.append(text) + indices_to_translate.append(index) + + num_texts = len(texts_to_translate) + logger.info(f"Número total de textos a traducir: {num_texts}") - num_rows = len(texts_to_translate) translations = [] - - for start_idx in range(0, num_rows, batch_size): - end_idx = min(start_idx + batch_size, num_rows) + for start_idx in range(0, num_texts, batch_size): + end_idx = min(start_idx + batch_size, num_texts) batch_texts = texts_to_translate[start_idx:end_idx] - batch_translations = translate_batch(batch_texts, 'Italian', target_lang_code) + batch_translations = translate_batch(batch_texts, "Italian", target_lang_code) translations.extend(batch_translations) - # Asignar las traducciones al DataFrame - if traducir_todo: - df[target_col] = [translate_batch([text], 'Italian', target_lang_code)[0] if texto_requiere_traduccion(text) else text for text in df[source_col].astype(str).tolist()] - else: - indices = df.loc[df[target_col].isnull()].index - for i, index in enumerate(indices): - if texto_requiere_traduccion(df.at[index, source_col]): - df.at[index, target_col] = translations[i] + logger.info(f"Número total de traducciones recibidas: {len(translations)}") - # Guardar el archivo actualizado - output_path = os.path.join(os.path.dirname(file_path), 'master_export2translate_translated.xlsx') + if len(translations) != len(indices_to_translate): + logger.warning( + f"Desajuste entre el número de traducciones ({len(translations)}) y el número de índices ({len(indices_to_translate)})" + ) + + for i, index in enumerate(indices_to_translate): + if i < len(translations): + df.at[index, target_col] = translations[i] + else: + logger.error(f"No hay traducción disponible para el índice {index}") + + output_path = os.path.join( + os.path.dirname(file_path), "master_export2translate_translated.xlsx" + ) df.to_excel(output_path, index=False) + logger.info(f"Archivo traducido guardado en: {output_path}") print(f"Archivo traducido guardado en: {output_path}") + if __name__ == "__main__": batch_size = 10 - translate_file = 'master_export2translate.xlsx' + translate_file = "master_export2translate.xlsx" mostrar_idiomas() seleccion_idioma = int(input("Introduce el número del idioma de destino: ")) @@ -105,5 +163,7 @@ if __name__ == "__main__": print("Selección inválida.") else: _, target_lang_code = IDIOMAS[seleccion_idioma] - traducir_todo = input("¿Desea traducir todas las celdas (sí/no)? ").strip().lower() == 'sí' - main(translate_file, target_lang_code, traducir_todo, batch_size) \ No newline at end of file + traducir_todo = ( + input("¿Desea traducir todas las celdas (s/n)? ").strip().lower() == "s" + ) + main(translate_file, target_lang_code, traducir_todo, batch_size) diff --git a/master_export2translate_translated.xlsx b/master_export2translate_translated.xlsx deleted file mode 100644 index 0883edf..0000000 Binary files a/master_export2translate_translated.xlsx and /dev/null differ