JairoCesar commited on
Commit
2f59c3d
·
verified ·
1 Parent(s): 70d5d0d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +215 -203
app.py CHANGED
@@ -1,4 +1,4 @@
1
- # ==================== Interprete de manchas de Test de Rorschach =====================================
2
  #
3
  # (o\ | /o)
4
  # \.\_/. /
@@ -6,238 +6,250 @@
6
  # \ VVVV/ \VVVV /
7
  # \____/ \____/
8
  # __________________________________________________________________________________________________________
9
- # DIANA MILENA SOLER Psicologa Est Medicina U. Juan N Corpas JAIRO ALEXANDER ERASO MD U Nacional de Colombia
10
- #
11
 
12
  import streamlit as st
13
- import google.generativeai as genai # Import Gemini
14
- from docx import Document
15
- import tempfile
16
  import os
17
- import re
18
  import logging
19
  import datetime
20
 
21
- # Configurar logging para monitorear las llamadas al API
22
- logging.basicConfig(
23
- level=logging.INFO,
24
- format='%(asctime)s - %(levelname)s - %(message)s',
25
- handlers=[
26
- logging.StreamHandler()
27
- ]
28
- )
29
- logger = logging.getLogger("rorschach_gemini_app")
30
-
31
- # Configuración mínima de Streamlit
32
  st.set_page_config(
33
- page_title="Interpretación Rorschach con Gemini",
34
- page_icon="🧠",
 
35
  )
36
 
37
- # --- CONFIGURACIÓN Gemini ---
38
- GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
39
- if not GEMINI_API_KEY:
40
- st.error("GEMINI_API_KEY no encontrada. Por favor configúrala en tus variables de entorno.")
41
- logger.error("GEMINI_API_KEY no encontrada.")
42
- st.stop()
43
 
 
44
  try:
 
 
 
 
 
45
  genai.configure(api_key=GEMINI_API_KEY)
46
  logger.info("✅ Configuración de Gemini API realizada.")
47
  except Exception as e:
48
- error_msg = f"❌ Error al configurar Gemini API: {str(e)}"
49
- logger.error(error_msg)
50
- st.error(error_msg)
51
  st.stop()
52
 
53
  @st.cache_resource
54
  def get_gemini_model():
55
- logger.info("🔄 Cargando modelo Gemini...")
56
- # Puedes cambiar a "gemini-pro" si lo prefieres, gemini-1.5-flash es más rápido y económico
57
- return genai.GenerativeModel("gemini-1.5-flash-latest")
58
-
59
- # Inicializar modelo Gemini
60
- model = None
61
- try:
62
- model = get_gemini_model()
63
- logger.info("✅ Modelo Gemini cargado correctamente (gemini-1.5-flash-latest)")
64
- except Exception as e:
65
- error_msg = f"❌ Error al inicializar modelo Gemini: {str(e)}"
66
- logger.error(error_msg)
67
- st.error(error_msg)
68
- # st.stop() # Decidir si detener la app si el modelo no carga
69
-
70
- # Formatear prompt para interpretación Rorschach con Gemini
71
- def format_prompt_gemini(message):
72
- system_prompt = """Eres un experto en interpretación del Test de Rorschach.
73
- Analiza las respuestas del usuario a las láminas y proporciona una interpretación
74
- psicológica detallada basada en el método de Exner.
75
-
76
- Considera:
77
- - Localización de las respuestas
78
- - Determinantes (forma, color, movimiento)
79
- - Contenido de las respuestas
80
- - Originalidad/popularidad
81
- - Funcionamiento cognitivo, afectivo e interpersonal
82
- Al final describe una conclusion creativa en terminos sencillos de la personalidad del usuario
83
- con recomendaciones generales.
84
- """
85
 
86
- # Gemini prefiere una concatenación más directa o el uso de 'parts' para roles.
87
- # Para una única llamada de generación de texto, concatenar es simple.
88
- prompt = f"{system_prompt}\n\nInterpretación Rorschach para las siguientes respuestas del usuario:\n{message}"
89
- logger.info(f"Prompt para Gemini generado con {len(prompt)} caracteres")
90
- return prompt
91
 
92
- # Generar respuesta desde Gemini
93
- def generate_with_gemini(user_input_message):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  if not model:
95
- logger.error(" No hay modelo Gemini disponible para generar respuesta")
96
- return "Error de conexión con el modelo Gemini. Por favor, inténtelo de nuevo más tarde."
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  try:
99
- logger.info(f"🔄 Iniciando llamada al API de Gemini - {datetime.datetime.now()}")
100
-
101
- generation_config = genai.types.GenerationConfig(
102
- temperature=0.7, # Gemini usa un rango similar, 0.9 es bastante creativo
103
- max_output_tokens=1024, # Aumentado un poco para asegurar respuestas completas
104
- top_p=0.95,
105
- # top_k es otro parámetro que podrías usar en Gemini
106
- # repetition_penalty no es un parámetro directo en GenerationConfig
107
- # do_sample es implícito si temperature > 0
108
- # seed no es un parámetro directo de GenerationConfig para `generate_content`
109
- )
110
-
111
- formatted_prompt = format_prompt_gemini(user_input_message)
112
- start_time = datetime.datetime.now()
113
-
114
- # Llamada a Gemini
115
- response = model.generate_content(
116
- formatted_prompt,
117
- generation_config=generation_config
118
- )
119
-
120
- end_time = datetime.datetime.now()
121
- duration = (end_time - start_time).total_seconds()
122
-
123
- logger.info(f"✅ Respuesta de Gemini generada en {duration:.2f} segundos")
124
-
125
- # Acceder al texto de la respuesta
126
  if response.parts:
127
- output_text = response.text
 
 
 
 
 
128
  else:
129
- # Esto podría ocurrir si la respuesta fue bloqueada por filtros de seguridad
130
  logger.warning(f"⚠️ Respuesta de Gemini vacía o bloqueada. Razón: {response.prompt_feedback}")
131
- output_text = (
132
- "No se pudo generar una respuesta. Esto podría deberse a filtros de seguridad "
133
- f"o a un problema con la solicitud. Razón del feedback: {response.prompt_feedback}"
134
- )
135
- return output_text
136
-
137
  except Exception as e:
138
- error_msg = f"❌ Error en la generación con Gemini: {str(e)}"
139
- logger.error(error_msg)
140
- # Verificar si el error es por API key inválida (aunque ya se verifica al inicio)
141
- if "API_KEY_INVALID" in str(e):
142
- st.error("La clave API de Gemini es inválida o ha expirado. Verifica tu configuración.")
143
- return f"Lo siento, ocurrió un error durante la interpretación con Gemini. Detalles: {str(e)}"
144
-
145
- # Reemplazo de variables en documento Word
146
- from docx.enum.text import WD_ALIGN_PARAGRAPH
147
-
148
- def replace_variables_word(doc, variables):
149
- for paragraph in doc.paragraphs:
150
- for key, value in variables.items():
151
- if f'<{key}>' in paragraph.text:
152
- # Usar run para preservar formato si es posible, pero simple replace es más robusto para placeholder
153
- # Si el placeholder está solo, paragraph.text es suficiente
154
- # Si está entre otro texto, se necesita más cuidado con runs
155
- new_text = paragraph.text.replace(f'<{key}>', str(value)) # Asegurar que value sea string
156
- if paragraph.text != new_text: # Solo si hubo cambio
157
- paragraph.text = new_text
158
- paragraph.alignment = WD_ALIGN_PARAGRAPH.LEFT # Justificación
159
- for table in doc.tables:
160
- for row in table.rows:
161
- for cell in row.cells:
162
- for paragraph in cell.paragraphs:
163
- for key, value in variables.items():
164
- if f'<{key}>' in paragraph.text:
165
- new_text = paragraph.text.replace(f'<{key}>', str(value))
166
- if paragraph.text != new_text:
167
- paragraph.text = new_text
168
- paragraph.alignment = WD_ALIGN_PARAGRAPH.LEFT
169
-
170
-
171
- # Generar documento Word con interpretación
172
- def generate_word_document(interpretation):
173
- try:
174
- template_path = os.path.join('PLANTILLAS', 'PLANTILLA_INTERPRETACION.docx')
175
-
176
- if not os.path.exists(template_path):
177
- logger.warning(f"⚠️ No se encontró la plantilla en {template_path}")
178
- st.warning(f"No se encontró la plantilla en {template_path}")
179
- return None
180
-
181
- doc = Document(template_path)
182
- variables = {'INTERPRETACION': interpretation}
183
- replace_variables_word(doc, variables)
184
 
185
- with tempfile.NamedTemporaryFile(delete=False, suffix='.docx') as tmp:
186
- doc.save(tmp.name)
187
- logger.info(f"✅ Documento Word generado correctamente: {tmp.name}")
188
- return tmp.name
189
 
190
- except Exception as e:
191
- error_msg = f"❌ Error al generar el documento: {str(e)}"
192
- logger.error(error_msg)
193
- st.error(error_msg)
194
- return None
195
 
196
- # Interfaz Streamlit
197
- st.title("Interpretación del Test de Rorschach (con Gemini)")
198
- logger.info("🚀 Aplicación (Gemini) iniciada")
199
 
200
- entrada_usuario = st.text_area(
201
- "Ingrese respuestas del Test de Rorschach:",
202
- height=150,
203
- placeholder="Ejemplo: Lámina I: Veo un murciélago sobre un noche estrellada..."
204
  )
205
 
206
- if st.button("Enviar Interpretación", type="primary"):
207
- if not entrada_usuario:
208
- st.warning("Por favor ingrese texto para interpretar")
209
- elif not model: # Verificar si el modelo se cargó
210
- st.error("El modelo de IA no está disponible. Por favor, revise la configuración y los logs.")
211
- logger.error("Intento de generar interpretación sin modelo cargado.")
212
  else:
213
- logger.info(f"🔄 Procesando entrada de {len(entrada_usuario)} caracteres para Gemini")
214
- with st.spinner("Generando interpretación con Gemini..."):
215
- bot_response = generate_with_gemini(entrada_usuario) # Llamada a la nueva función
216
- st.subheader("Interpretación (Gemini)")
217
- st.markdown(bot_response) # Usar markdown para mejor formato si Gemini lo usa
218
-
219
- if "No se pudo generar una respuesta" not in bot_response and "ocurrió un error" not in bot_response :
220
- document_path = generate_word_document(bot_response)
221
- if document_path:
222
- with open(document_path, "rb") as file:
223
- file_data = file.read()
224
- st.download_button(
225
- label="Descargar Interpretación",
226
- data=file_data,
227
- file_name="Interpretacion_Rorschach_Gemini.docx",
228
- mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
229
- )
230
- logger.info("📄 Botón de descarga (Gemini) mostrado al usuario")
231
- # Clean up the temporary file
232
- try:
233
- os.remove(document_path)
234
- logger.info(f"🧹 Archivo temporal {document_path} eliminado.")
235
- except OSError as e_rm:
236
- logger.error(f"⚠️ Error al eliminar archivo temporal {document_path}: {e_rm}")
237
-
238
- else:
239
- logger.error("❌ No se pudo generar el documento Word (Gemini)")
240
- else:
241
- logger.warning("⚠️ No se generó documento Word debido a error en la interpretación.")
242
-
243
- # --- END OF FILE manchas_gemini.py ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ==================== Asesor de Notificación SIVIGILA - Colombia =====================================
2
  #
3
  # (o\ | /o)
4
  # \.\_/. /
 
6
  # \ VVVV/ \VVVV /
7
  # \____/ \____/
8
  # __________________________________________________________________________________________________________
9
+ # Adaptado por JAIRO ALEXANDER ERASO MD U Nacional de Colombia, basado en la solicitud del usuario.
10
+ #
11
 
12
  import streamlit as st
13
+ import google.generativeai as genai
 
 
14
  import os
15
+ import json
16
  import logging
17
  import datetime
18
 
19
+ # --- CONFIGURACIÓN BÁSICA ---
 
 
 
 
 
 
 
 
 
 
20
  st.set_page_config(
21
+ page_title="Asesor SIVIGILA Colombia",
22
+ page_icon="🇨🇴",
23
+ layout="wide"
24
  )
25
 
26
+ # Configurar logging
27
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
28
+ logger = logging.getLogger("sivigila_app")
 
 
 
29
 
30
+ # --- CONFIGURACIÓN DE GEMINI ---
31
  try:
32
+ GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
33
+ if not GEMINI_API_KEY:
34
+ st.error("No se encontró la variable de entorno GEMINI_API_KEY. Por favor, configúrala.")
35
+ logger.error("GEMINI_API_KEY no encontrada.")
36
+ st.stop()
37
  genai.configure(api_key=GEMINI_API_KEY)
38
  logger.info("✅ Configuración de Gemini API realizada.")
39
  except Exception as e:
40
+ st.error(f"❌ Error al configurar Gemini API: {e}")
41
+ logger.error(f"Error al configurar Gemini API: {e}")
 
42
  st.stop()
43
 
44
  @st.cache_resource
45
  def get_gemini_model():
46
+ """Carga el modelo de Gemini y lo cachea para no recargarlo."""
47
+ logger.info("🔄 Cargando modelo Gemini (gemini-1.5-flash-latest)...")
48
+ try:
49
+ return genai.GenerativeModel("gemini-1.5-flash-latest")
50
+ except Exception as e:
51
+ st.error(f"❌ No se pudo cargar el modelo Gemini: {e}")
52
+ logger.error(f"Error cargando modelo Gemini: {e}")
53
+ return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
+ model = get_gemini_model()
 
 
 
 
56
 
57
+ # --- CARGA Y PROCESAMIENTO DE DATOS ---
58
+ @st.cache_data
59
+ def load_data():
60
+ """Carga y procesa los archivos JSON, uniéndolos para un acceso rápido."""
61
+ try:
62
+ path_codigos = os.path.join('PLANTILLAS', 'DIC_NOMBRES_CODIGOS_FICHAS.json')
63
+ path_notificacion = os.path.join('PLANTILLAS', 'DATOS_NOTIFICACION.json')
64
+
65
+ with open(path_codigos, 'r', encoding='utf-8') as f:
66
+ data_codigos = json.load(f)
67
+
68
+ with open(path_notificacion, 'r', encoding='utf-8') as f:
69
+ data_notificacion = json.load(f)
70
+
71
+ # Crear un diccionario para búsqueda rápida de datos de notificación por FICHA
72
+ notificacion_map = {item['FICHA']: item for item in data_notificacion}
73
+
74
+ # Generar una lista de nombres de eventos únicos para la búsqueda con IA
75
+ nombres_eventos_unicos = sorted(list(set(item['NOMBRES DE PROTOCOLOS'] for item in data_codigos)))
76
+
77
+ logger.info(f"✅ Datos cargados: {len(data_codigos)} registros de códigos y {len(data_notificacion)} eventos de notificación.")
78
+ return data_codigos, notificacion_map, nombres_eventos_unicos
79
+
80
+ except FileNotFoundError as e:
81
+ st.error(f"❌ Error: No se encontró el archivo {e.filename}. Asegúrate de que los archivos JSON estén en la carpeta 'PLANTILLAS'.")
82
+ logger.error(f"Archivo no encontrado: {e.filename}")
83
+ return None, None, None
84
+ except json.JSONDecodeError as e:
85
+ st.error(f"❌ Error: El archivo JSON tiene un formato incorrecto: {e}")
86
+ logger.error(f"Error de formato JSON: {e}")
87
+ return None, None, None
88
+
89
+ data_codigos, notificacion_map, nombres_eventos_unicos = load_data()
90
+
91
+
92
+ # --- LÓGICA DE BÚSQUEDA ---
93
+
94
+ def search_direct(query, data, notif_map):
95
+ """Realiza una búsqueda directa por código, nombre exacto o ficha."""
96
+ query_lower = query.lower().strip()
97
+ results = set() # Usar un set para evitar duplicados de fichas
98
+
99
+ for item in data:
100
+ ficha = item.get("FICHA")
101
+ if not ficha:
102
+ continue
103
+
104
+ # Comprobar coincidencias en varios campos
105
+ if (query_lower == item.get("CIE 10", "").lower().strip() or
106
+ query_lower == item.get("CIE 11", "").lower().strip() or
107
+ query_lower == ficha.lower().strip() or
108
+ query_lower in item.get("NOMBRES DE PROTOCOLOS", "").lower()):
109
+ results.add(ficha)
110
+
111
+ if not results:
112
+ return []
113
+
114
+ # Construir la lista de resultados completos
115
+ final_results = []
116
+ for ficha in results:
117
+ # Encontrar todos los detalles de códigos para esa ficha
118
+ detalles_codigos = [d for d in data if d.get("FICHA") == ficha]
119
+ # Obtener los datos de notificación
120
+ info_notificacion = notif_map.get(ficha)
121
+ if info_notificacion:
122
+ final_results.append({
123
+ "info_notificacion": info_notificacion,
124
+ "detalles_codigos": detalles_codigos
125
+ })
126
+
127
+ return final_results
128
+
129
+
130
+ def search_with_gemini(query, event_list):
131
+ """Usa Gemini para encontrar el evento más relevante a partir de una consulta en lenguaje natural."""
132
  if not model:
133
+ return "Error: Modelo de IA no disponible."
134
+
135
+ # Prompt cuidadosamente diseñado para obtener una respuesta estructurada
136
+ system_prompt = f"""
137
+ Eres un asesor experto en SIVIGILA, el sistema de vigilancia en salud pública de Colombia.
138
+ Tu tarea es identificar el evento de notificación más relevante basado en la consulta de un profesional de la salud.
139
+ A continuación, te proporciono una lista de los nombres oficiales de los protocolos de notificación.
140
+
141
+ LISTA DE PROTOCOLOS OFICIALES:
142
+ {'; '.join(event_list)}
143
+
144
+ Analiza la siguiente consulta del usuario y devuelve ÚNICAMENTE el nombre exacto del protocolo o protocolos de la lista que mejor correspondan.
145
+ Si encuentras varios, sepáralos con un punto y coma (;).
146
+ Si la consulta no corresponde a ningún protocolo de la lista, responde con "NO_ENCONTRADO".
147
+ No añadas explicaciones, saludos ni texto adicional. Solo el nombre del protocolo.
148
+
149
+ Consulta del usuario: "{query}"
150
+ """
151
+
152
  try:
153
+ logger.info(f"🔄 Enviando consulta a Gemini: '{query}'")
154
+ response = model.generate_content(system_prompt)
155
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  if response.parts:
157
+ result_text = response.text.strip()
158
+ logger.info(f"✅ Respuesta de Gemini: '{result_text}'")
159
+ if result_text == "NO_ENCONTRADO":
160
+ return []
161
+ # Devolver una lista de nombres de protocolos encontrados
162
+ return [name.strip() for name in result_text.split(';') if name.strip()]
163
  else:
 
164
  logger.warning(f"⚠️ Respuesta de Gemini vacía o bloqueada. Razón: {response.prompt_feedback}")
165
+ return "Respuesta bloqueada por filtros de seguridad."
166
+
 
 
 
 
167
  except Exception as e:
168
+ logger.error(f"❌ Error en la llamada a Gemini: {e}")
169
+ return f"Error en la comunicación con la IA: {e}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
 
 
 
 
 
171
 
172
+ # --- INTERFAZ DE USUARIO (UI) ---
 
 
 
 
173
 
174
+ st.title("👨‍⚕️ Asesor Experto en Notificación SIVIGILA - Colombia")
175
+ st.markdown("Busque una enfermedad por nombre, sinónimo, código CIE-10 o CIE-11 para obtener información de notificación.")
 
176
 
177
+ query = st.text_input(
178
+ "Ingrese su búsqueda:",
179
+ placeholder="Ej: Dengue, T630, mordedura de serpiente, intoxicación por mercurio...",
180
+ help="Puede buscar por nombre de la enfermedad, palabras clave, o códigos CIE."
181
  )
182
 
183
+ if st.button("Buscar", type="primary"):
184
+ if not query:
185
+ st.warning("Por favor, ingrese un término de búsqueda.")
186
+ elif data_codigos is None or notificacion_map is None:
187
+ st.error("Los datos no se pudieron cargar. La aplicación no puede funcionar.")
 
188
  else:
189
+ # --- Lógica principal al hacer clic en el botón ---
190
+ with st.spinner("Buscando..."):
191
+
192
+ # 1. Intento de búsqueda directa
193
+ results = search_direct(query, data_codigos, notificacion_map)
194
+
195
+ # 2. Si no hay resultados directos, usar IA
196
+ if not results:
197
+ logger.info(f"Búsqueda directa para '{query}' no arrojó resultados. Usando Gemini...")
198
+ protocol_names = search_with_gemini(query, nombres_eventos_unicos)
199
+
200
+ if isinstance(protocol_names, str): # Manejo de errores de Gemini
201
+ st.error(protocol_names)
202
+ protocol_names = []
203
+
204
+ if protocol_names:
205
+ # Usamos los nombres devueltos por Gemini para hacer una búsqueda directa
206
+ temp_results = []
207
+ for name in protocol_names:
208
+ temp_results.extend(search_direct(name, data_codigos, notificacion_map))
209
+
210
+ # Eliminar duplicados si Gemini devuelve protocolos que caen en la misma ficha
211
+ unique_fichas = set()
212
+ for res in temp_results:
213
+ ficha = res["info_notificacion"]["FICHA"]
214
+ if ficha not in unique_fichas:
215
+ results.append(res)
216
+ unique_fichas.add(ficha)
217
+
218
+ # 3. Mostrar resultados
219
+ st.markdown("---")
220
+ if not results:
221
+ st.info(f"No se encontraron eventos de notificación obligatoria para su búsqueda: '{query}'.")
222
+ else:
223
+ st.success(f"Se encontraron {len(results)} evento(s) relacionado(s) con su búsqueda:")
224
+
225
+ for result in results:
226
+ info = result["info_notificacion"]
227
+ codigos = result["detalles_codigos"]
228
+
229
+ with st.expander(f"**Evento: {info.get('Evento', 'Sin nombre')} (Ficha: {info.get('FICHA', 'N/A')})**", expanded=True):
230
+
231
+ # Resumen de notificación
232
+ st.subheader("Información de Notificación")
233
+ col1, col2, col3 = st.columns(3)
234
+
235
+ notif_inmediata = info.get("Notificación Inmediata", "NO") == "SI"
236
+ notif_super = info.get("Notificación superinmedita", "NO") == "SI"
237
+
238
+ if notif_inmediata or notif_super:
239
+ st.success("**Requiere Notificación Inmediata.**")
240
+ if notif_super:
241
+ st.warning(f"**¡ATENCIÓN! Requiere Notificación SUPERINMEDIATA:** {info.get('Descripción superinmediata', '')}")
242
+ else:
243
+ st.info("**Notificación Semanal.**")
244
+
245
+ st.markdown(f"**Requisito:** {info.get('REQUISITO', 'No especificado')}")
246
+ st.markdown(f"**Fichas a utilizar:** {info.get('Fichas a Utilizar', 'No especificado').replace('+', '\n+')}")
247
+
248
+ # Detalles de códigos
249
+ st.subheader("Códigos Relacionados (CIE-10 y CIE-11)")
250
+ for codigo in codigos:
251
+ st.markdown(f"""
252
+ - **Nombre Protocolo:** `{codigo.get('NOMBRES DE PROTOCOLOS', 'N/A')}`
253
+ - **CIE-10:** `{codigo.get('CIE 10', 'N/A')}`
254
+ - **CIE-11:** `{codigo.get('CIE 11', 'N/A')}` | **Nombre CIE-11:** *{codigo.get('NOMBRES DE CIE 11', 'N/A')}*
255
+ """)