drguilhermeapolinario commited on
Commit
f001425
·
verified ·
1 Parent(s): 8e0a434

Update views/rci.py

Browse files
Files changed (1) hide show
  1. views/rci.py +632 -632
views/rci.py CHANGED
@@ -1,632 +1,632 @@
1
- """
2
- This module contains the code for the 'rci' view of the application.
3
- """
4
-
5
- import plotly.express as px
6
- import streamlit as st
7
- from groq import Groq
8
- from streamlit_extras.add_vertical_space import add_vertical_space
9
- from streamlit_extras.stylable_container import stylable_container
10
- from streamlit_option_menu import option_menu
11
-
12
- from data_cleaning import processar_arquivo
13
-
14
-
15
-
16
- #################################
17
- ############ BANNER #############
18
- #################################
19
-
20
- with stylable_container(
21
- key="banner",
22
- css_styles="""
23
- img {
24
- width: 1800px;
25
- height: 400px;
26
- overflow: hidden;
27
- position: relative;
28
- object-fit: cover;
29
- border-radius: 14px; /* Adiciona bordas arredondadas */
30
- mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
31
- -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); /* For Safari */
32
- }
33
- """,
34
- ):
35
- st.image("src/images/banner.png")
36
-
37
- st.title("Análise de microárea")
38
-
39
-
40
- #################################
41
- ############ BANNER #############
42
- #################################
43
-
44
-
45
- def clear_chat_history():
46
- """
47
- Clears the chat history and resets the initial analysis in the session state.
48
- This function clears the chat history and resets the initial analysis in the session state.
49
- It sets the value of "groq_chat_history" in the session state to an empty list and the value of "initial_analysis" to an empty string.
50
- """
51
- st.session_state["groq_chat_history"] = []
52
- st.session_state["initial_analysis"] = ""
53
-
54
-
55
- #################################
56
- ############ DATA ###############
57
- #################################
58
-
59
- uploaded_file = st.sidebar.file_uploader("Escolha um arquivo CSV", type="csv")
60
- if uploaded_file is not None:
61
- dataframes = processar_arquivo(uploaded_file)
62
- DF_DATA = dataframes.get("Data")
63
- DF_HEAD = dataframes.get("Head")
64
- DF_IDADE = dataframes.get("Idade")
65
- DF_GENERO = dataframes.get("genero")
66
- DF_COR = dataframes.get("cor")
67
- DF_DEFICIENCIA = dataframes.get("deficiencia")
68
- DF_DOENCAS = dataframes.get("doencas")
69
- DF_ESCOLA = dataframes.get("Escola")
70
- DF_TRANSGEN = dataframes.get("transgen")
71
- for df in [
72
- DF_IDADE,
73
- DF_GENERO,
74
- DF_COR,
75
- DF_DEFICIENCIA,
76
- DF_DOENCAS,
77
- DF_ESCOLA,
78
- DF_TRANSGEN,
79
- ]:
80
- if df is not None:
81
- df["Descrição"] = df["Descrição"].str.capitalize()
82
- else:
83
- st.sidebar.info("Adicione um arquivo .csv.")
84
-
85
- if st.sidebar.button("Limpar", type="primary"):
86
- clear_chat_history()
87
-
88
-
89
- def gerar_resumo_df():
90
- """
91
- Generates a summary of the dataframes.
92
- This function creates a summary of the dataframes by concatenating the
93
- string representation of each dataframe.
94
- The summary includes the name of the dataframe and its content.
95
- Returns:
96
- str: The summary of the dataframes.
97
- """
98
- resumo = ""
99
- if DF_DATA is not None:
100
- resumo += "Resumo DF_DATA:\n"
101
- resumo += DF_DATA.to_string(index=False) + "\n\n"
102
- if DF_HEAD is not None:
103
- resumo += "Resumo DF_HEAD:\n"
104
- resumo += DF_HEAD.to_string(index=False) + "\n\n"
105
- if DF_IDADE is not None:
106
- resumo += "Resumo DF_IDADE:\n"
107
- resumo += DF_IDADE.to_string(index=False) + "\n\n"
108
- if DF_GENERO is not None:
109
- resumo += f"Resumo DF_GENERO:\n{DF_GENERO.to_string(index=False)}\n\n"
110
- if DF_COR is not None:
111
- resumo += f"Resumo DF_COR:\n{DF_COR.to_string(index=False)}\n\n"
112
- if DF_DEFICIENCIA is not None:
113
- resumo += f"Resumo DF_DEFICIENCIA:\n{DF_DEFICIENCIA.to_string(index=False)}\n\n"
114
- if DF_DOENCAS is not None:
115
- resumo += f"Resumo DF_DOENCAS:\n{DF_DOENCAS.to_string(index=False)}\n\n"
116
- if DF_ESCOLA is not None:
117
- resumo += f"Resumo DF_ESCOLA:\n{DF_ESCOLA.to_string(index=False)}\n\n"
118
- if DF_TRANSGEN is not None:
119
- resumo += f"Resumo DF_TRANSGEN:\n{DF_TRANSGEN.to_string(index=False)}\n\n"
120
- return resumo
121
-
122
-
123
- #################################
124
- ############ DATA ###############
125
- #################################
126
-
127
-
128
- ###########################################
129
- ############### LATERAL ##################
130
- ###########################################
131
-
132
- st.sidebar.markdown(
133
- """
134
- ### Informações:
135
- - Análise - Relatório de cadastro individual.
136
- - Iniciativa - Ubs Flamengo
137
- - Acesso livre
138
- ### Links:
139
- ##
140
- ##### - [PEC SUS](https://sape.pecsus.com.br/) 📝
141
- ###
142
- ##### - [Obsidian - Dr Guilherme](http://dr-guilhermeapolinario.com) 🌎
143
- ##### - [GitHub - Dr Guilherme](http://dr-guilhermeapolinario.com) 🌎
144
- """
145
- )
146
- st.markdown(
147
- """
148
- #### Instruções:
149
- ##### - Acesse o site :orange[PEC SUS], na aba esquerda selecione consolidado, :blue[*RELATÓRIO DE CADASTRO INDIVIDUAL*]
150
- ##### - Selecione a opção :orange[baixar arquivo .csv]. Após baixar o arquivo, selecione o arquivo .csv na aba ao lado, e pronto.
151
- ##### - Clique no botão de expansão abaixo para iniciar o processo.
152
- ##### - Utilize o chatbot com a inteligência artificial 🤖 Zé Flamengo para tirar suas dúvidas.
153
- """
154
- )
155
- st.write("-----")
156
-
157
- st.markdown(
158
- """
159
- #### Dados de saúde Relatório de cadastro individual.
160
- """
161
- )
162
-
163
- ###########################################
164
- ############### LATERAL ##################
165
- ###########################################
166
-
167
-
168
- ###########################################
169
- ############### EXPANDERCOM GRÁFICOS ######
170
- ###########################################
171
-
172
-
173
- def criar_grafico_personalizado(df, x_col, y_col, titulo):
174
- """
175
- A function to create a customized bar chart based on the input data, x
176
- and y columns, and title.
177
- Parameters:
178
- df (DataFrame): The input DataFrame containing the data.
179
- x_col (str): The column name for the x-axis data.
180
- y_col (str): The column name for the y-axis data.
181
- titulo (str): The title of the chart.
182
- Returns:
183
- fig: The customized bar chart figure.
184
- """
185
- fig = px.bar(
186
- df,
187
- x=x_col,
188
- y=y_col,
189
- title=titulo,
190
- text=y_col,
191
- color=x_col,
192
- color_discrete_sequence=px.colors.qualitative.Bold,
193
- )
194
- fig.update_traces(texttemplate="%{text:.2s}", textposition="outside")
195
- fig.update_layout(
196
- uniformtext_minsize=8,
197
- uniformtext_mode="hide",
198
- xaxis_title=x_col,
199
- yaxis_title=y_col,
200
- title_font_size=24,
201
- title_font_family="Arial",
202
- title_font_color="white",
203
- title_x=0.2,
204
- paper_bgcolor="rgba(0,0,0,0)",
205
- plot_bgcolor="rgba(0,0,0,0)",
206
- xaxis_tickangle=-45,
207
- )
208
- return fig
209
-
210
-
211
- if uploaded_file is not None:
212
- c1, c2 = st.columns(2)
213
- with c1:
214
- if DF_DATA is not None:
215
- st.dataframe(DF_DATA, hide_index=True)
216
- else:
217
- st.write("Data não disponível")
218
- with c2:
219
- if DF_HEAD is not None:
220
- st.dataframe(DF_HEAD, hide_index=True)
221
- else:
222
- st.write("Informações não disponíveis")
223
-
224
- if uploaded_file is not None:
225
- with st.expander("Visualização", expanded=True):
226
- selected_tab = option_menu(
227
- menu_title=None,
228
- options=[
229
- "Faixa Etária",
230
- "Gênero",
231
- "Cor",
232
- "Deficiência",
233
- "Doenças",
234
- "Escolaridade",
235
- "Identidade de Gênero",
236
- ],
237
- icons=[
238
- "person",
239
- "gender-female",
240
- "person-plus",
241
- "person-wheelchair",
242
- "capsule-pill",
243
- "stars",
244
- "gender-trans",
245
- ],
246
- menu_icon="cast",
247
- default_index=0,
248
- orientation="horizontal",
249
- styles={
250
- "container": {
251
- "padding": "0!important",
252
- "background-color": "#262730",
253
- },
254
- "icon": {"color": "#4FCBFC", "font-size": "18px"},
255
- "nav-link": {
256
- "font-size": "14px",
257
- "text-align": "center",
258
- "margin": "0px",
259
- "padding": "10px",
260
- "--hover-color": "#363940",
261
- "color": "#FFFFFF",
262
- },
263
- "nav-link-selected": {"background-color": "#0083B8"},
264
- "separator": {"border-color": "#4B4B4B"},
265
- },
266
- )
267
- if selected_tab == "Faixa Etária" and DF_IDADE is not None:
268
- st.subheader("Distribuição por Faixa Etária")
269
- col1, col2 = st.columns(2)
270
- with col1:
271
- st.dataframe(DF_IDADE, hide_index=True)
272
- with col2:
273
- DF_IDADE["Masculino"] = DF_IDADE["Masculino"].astype(int) * -1
274
- DF_IDADE["Feminino"] = DF_IDADE["Feminino"].astype(int)
275
- fig_idade = px.bar(
276
- DF_IDADE,
277
- x=["Masculino", "Feminino"],
278
- y="Descrição",
279
- orientation="h",
280
- title="Pirâmide Etária",
281
- labels={"value": "População", "Descrição": "Faixa Etária"},
282
- color="Descrição",
283
- color_discrete_sequence=px.colors.qualitative.Set3,
284
- )
285
- fig_idade.update_layout(
286
- barmode="relative",
287
- xaxis_title="População",
288
- yaxis_title="Faixa Etária",
289
- )
290
- st.plotly_chart(fig_idade)
291
- DF_IDADE["Masculino"] = DF_IDADE["Masculino"].abs()
292
-
293
- elif selected_tab == "Gênero" and DF_GENERO is not None:
294
- st.subheader("Distribuição por Gênero")
295
- col1, col2 = st.columns(2)
296
- with col1:
297
- st.dataframe(DF_GENERO, hide_index=True)
298
- with col2:
299
- fig_genero = px.pie(
300
- DF_GENERO,
301
- names="Descrição",
302
- values="Valor",
303
- title="Distribuição por Gênero",
304
- color_discrete_sequence=px.colors.qualitative.Pastel,
305
- )
306
- st.plotly_chart(fig_genero)
307
-
308
- elif selected_tab == "Cor" and DF_COR is not None:
309
- st.subheader("Distribuição por Cor")
310
- col1, col2 = st.columns(2)
311
- with col1:
312
- st.dataframe(DF_COR, hide_index=True)
313
- with col2:
314
- fig_cor = px.pie(
315
- DF_COR,
316
- names="Descrição",
317
- values="Valor",
318
- title="Distribuição por Cor",
319
- color_discrete_sequence=px.colors.qualitative.Vivid,
320
- )
321
- st.plotly_chart(fig_cor)
322
-
323
- elif selected_tab == "Deficiência" and DF_DEFICIENCIA is not None:
324
- st.subheader("Distribuição por Deficiência")
325
- col1, col2 = st.columns(2)
326
- with col1:
327
- st.dataframe(DF_DEFICIENCIA, hide_index=True)
328
- with col2:
329
- fig_deficiencia = criar_grafico_personalizado(
330
- DF_DEFICIENCIA,
331
- x_col="Descrição",
332
- y_col="Valor",
333
- titulo="Distribuição por Deficiência",
334
- )
335
- st.plotly_chart(fig_deficiencia)
336
-
337
- elif selected_tab == "Doenças" and DF_DOENCAS is not None:
338
- st.subheader("Distribuição por Doenças")
339
- col1, col2 = st.columns(2)
340
- with col1:
341
- st.dataframe(DF_DOENCAS, hide_index=True)
342
- with col2:
343
- fig_doencas = criar_grafico_personalizado(
344
- DF_DOENCAS,
345
- x_col="Descrição",
346
- y_col="Valor",
347
- titulo="Distribuição por Doenças",
348
- )
349
- st.plotly_chart(fig_doencas)
350
-
351
- elif selected_tab == "Escolaridade" and DF_ESCOLA is not None:
352
- st.subheader("Distribuição por Escolaridade")
353
- col1, col2 = st.columns(2)
354
- with col1:
355
- st.dataframe(DF_ESCOLA, hide_index=True)
356
- with col2:
357
- fig_escola = criar_grafico_personalizado(
358
- DF_ESCOLA,
359
- x_col="Descrição",
360
- y_col="Valor",
361
- titulo="Distribuição por Escolaridade",
362
- )
363
- st.plotly_chart(fig_escola)
364
-
365
- elif selected_tab == "Identidade de Gênero" and DF_TRANSGEN is not None:
366
- st.subheader("Distribuição por Identidade de Gênero")
367
- col1, col2 = st.columns(2)
368
- with col1:
369
- st.dataframe(DF_TRANSGEN, hide_index=True)
370
- with col2:
371
- fig_transgen = criar_grafico_personalizado(
372
- DF_TRANSGEN,
373
- x_col="Descrição",
374
- y_col="Valor",
375
- titulo="Distribuição por Identidade de Gênero",
376
- )
377
- st.plotly_chart(fig_transgen)
378
-
379
-
380
- ###########################################
381
- ############### EXPANDERCOM GRÁFICOS ######
382
- ###########################################
383
-
384
- add_vertical_space(5)
385
-
386
- ###########################################
387
- ############### FOTO DO BOT ###############
388
- ###########################################
389
-
390
- with stylable_container(
391
- key="bot",
392
- css_styles="""
393
- img {
394
- width: 120px;
395
- height: 100px;
396
- overflow: hidden;
397
- position: relative;
398
- object-fit: cover;
399
- border-radius: 14px; /* Adiciona bordas arredondadas */
400
- }
401
- """,
402
- ):
403
- st.image("src/images/b.png")
404
-
405
- ###########################################
406
- ############### FOTO DO BOT ###############
407
- ###########################################
408
-
409
-
410
- ###########################################
411
- ############### CHATBOT RCI ###############
412
- ###########################################
413
-
414
- # Configuração inicial do Groq client
415
- client = Groq(api_key=st.secrets["GROQ_API_KEY"])
416
-
417
-
418
- # Função para gerar a análise inicial
419
- def generate_initial_analysis(resumo_rci):
420
- """
421
- Generates an initial analysis report based on the provided resumo_rci.
422
- Parameters:
423
- resumo_rci (str): The resumo_rci to be analyzed.
424
- Returns:
425
- str: The generated initial analysis report.
426
- Raises:
427
- Exception: If there is an error generating the initial analysis.
428
- Examples:
429
- >>> generate_initial_analysis("Resumo do RCI")
430
- "Cabeçalho com informações gerais (data, cidadãos ativos, saída, mudança de território,
431
- óbito)\n\nAnálise de Faixa Etária (Crianças de 0 a 2 anos, 0 a 4 anos, mulheres na faixa etária
432
- de preventivo 25 a 64 anos, mulehres na faixa etária de mamomagrafia 50a 69 anos)\n\nComparação
433
- de Sexo\n\nAnálise de Raça / Cor\n\nAnálise de
434
- Escolaridade\n\nOrientação Sexual\n\nDeficiências\n\nSituações de Saúde Gerais\n\n\nFormate seu
435
- relatório usando negrito para títulos de seções e subtítulos. Use listas com marcadores
436
- quando apropriado para melhorar a legibilidade. Apresente seu relatório final dentro de tags
437
- <relatorio></relatorio>."
438
- """
439
- try:
440
- initial_analysis = client.chat.completions.create(
441
- messages=[
442
- {
443
- "role": "system",
444
- "content": "Você é um assistente de análise de dados de saúde. Sua tarefa é analisar os dados fornecidos e criar um relatório detalhado seguindo o modelo especificado. O relatório deve ser escrito em português.",
445
- },
446
- {
447
- "role": "user",
448
- "content": f"""
449
- Aqui estão os dados para análise:
450
- <resumo_rci>
451
- {resumo_rci}
452
- </resumo_rci>
453
-
454
- Analise cuidadosamente os dados fornecidos e crie um relatório
455
- seguindo o modelo apresentado. O relatório deve incluir as seguintes
456
- seções:
457
- 1. Cabeçalho com informações gerais (data, cidadãos ativos, saída,
458
- mudança de território, óbito)
459
- 2. Análise de Faixa Etária (Crianças de 0 a 2 anos, 0 a 4 anos, mulheres
460
- na faixa etária de preventivo 25 a 64 anos, mulehres na faixa etária de
461
- mamomagrafia 50a 69 anos)
462
- 3. Comparação de Sexo
463
- 4. Análise de Raça / Cor
464
- 5. Análise de Escolaridade
465
- 6. Orientação Sexual
466
- 7. Deficiências
467
- 8. Situações de Saúde Gerais
468
-
469
- Para cada seção:
470
- - Calcule os totais e percentuais relevantes
471
- - Faça comparações quando apropriado (por exemplo, entre masculino
472
- e feminino)
473
- - Destaque as 3 informações mais significativas
474
-
475
- Formate seu relatório usando negrito para títulos de seções e subtítulos.
476
- Use o título de Análise parcial, use listas com marcadores quando apropriado
477
- para melhorar a legibilidade.
478
-
479
- """,
480
- },
481
- ],
482
- model="llama3-70b-8192",
483
- temperature=0.2,
484
- max_tokens=1500,
485
- )
486
- return initial_analysis.choices[0].message.content
487
- except Exception as e:
488
- st.error(f"Erro ao gerar a análise inicial: {e}")
489
- return "Não foi possível gerar a análise inicial."
490
-
491
-
492
- # Carregar arquivo
493
- # uploaded_file = st.file_uploader("Escolha um arquivo CSV", type="csv")
494
-
495
- if uploaded_file is not None:
496
- if (
497
- "current_file" not in st.session_state
498
- or st.session_state.current_file != uploaded_file.name
499
- ):
500
- st.session_state.current_file = uploaded_file.name
501
- st.session_state.initial_analysis = None # Reset da análise anterior
502
- st.session_state.resumo_rci = None # Reset do resumo
503
-
504
- # Botão para gerar o resumo
505
- if st.button("Gerar Resumo"):
506
- with st.spinner("Gerando resumo..."):
507
- st.session_state.resumo_rci = (
508
- gerar_resumo_df()
509
- ) # Gera o resumo do DataFrame
510
- st.session_state.initial_analysis = generate_initial_analysis(
511
- st.session_state.resumo_rci
512
- )
513
- st.success("Resumo gerado com sucesso!")
514
-
515
- col1, col2 = st.columns(2)
516
-
517
- with col1:
518
- with st.expander("Resumo Inicial", expanded=True):
519
- if "initial_analysis" in st.session_state:
520
- st.write("**Panorama Geral dos Dados:**")
521
- st.text_area(
522
- "Análise Inicial",
523
- value=st.session_state.initial_analysis,
524
- height=300,
525
- disabled=False,
526
- )
527
- else:
528
- st.write("**Clique em 'Gerar Resumo' para analisar os dados.**")
529
-
530
- with col2:
531
- with st.expander("Converse com o 🤖 Zé Flamengo", expanded=True):
532
- # Inicialização do histórico do chat
533
- if "groq_chat_history" not in st.session_state:
534
- st.session_state.groq_chat_history = []
535
-
536
- # Exibição do histórico do chat
537
- for message in st.session_state.groq_chat_history:
538
- with st.chat_message(message["role"]):
539
- st.markdown(message["content"])
540
-
541
- # Input do usuário e processamento da resposta
542
- if user_message := st.chat_input(
543
- "Digite sua pergunta sobre saúde na microárea:"
544
- ):
545
- # Adiciona a mensagem do usuário ao histórico
546
- st.session_state.groq_chat_history.append(
547
- {"role": "user", "content": user_message}
548
- )
549
-
550
- try:
551
- # Usar o resumo já gerado
552
- if "resumo_rci" not in st.session_state:
553
- st.warning("Por favor, gere o resumo antes de fazer perguntas.")
554
- else:
555
- resumo_rci = st.session_state.resumo_rci
556
-
557
- # Preparação do contexto para a API
558
- context = f"""
559
- Seu nome é Zé Flamengo, você é um assistente virtual especializado em análise de dados
560
- médicos epidemiológicos. Você tem 20 anos de experiência em análise de dados de saúde de
561
- microáreas de um PSF (Programa Saúde da Família).
562
- Sua função é:
563
- 1. Analisar dados de uma unidade básica de saúde.
564
- 2. Os dados que irá analisar são provenientes do Relatório de Cadastro Individual, advindos do PEC SUS.
565
- 3. Suas respostas devem ser sempre em português.
566
- 4. Seja conciso e evite conversar sobre outros temas.
567
- 5. Sempre retome o tema da conversa.
568
- 6. Realize sempre os cálculos novamente para garantir que os resultados fornecidos sejam precisos e atualizados.
569
- Os dataframes que irá analisar são do Relatório de cadastro indiviual.
570
- ele foi transformados em texto aqui disponíveis:
571
- {resumo_rci}
572
- As faixas etárias recomendadas para exames preventivos são:
573
- - **Papanicolau (Preventivo):** Mulheres entre 25 e 64 anos, com frequência anual nos primeiros dois exames
574
- consecutivos com resultados normais, depois a cada três anos.
575
- - **Mamografia:** Mulheres entre 50 e 69 anos, com frequência bienal.
576
- Informações sobre o Relatório de Cadastro Individual:
577
- - **Objetivo:** Coletar dados sociodemográficos e de saúde dos indivíduos cadastrados em uma unidade básica de saúde.
578
- - **Principais Indicadores:** Idade, sexo, condições de saúde (doenças crônicas, gestantes, etc.), status de
579
- vacinação, hábitos de vida (tabagismo, alcoolismo, atividade física), entre outros.
580
- Exemplos de perguntas esperadas:
581
- - Qual a porcentagem de mulheres na faixa etária de preventivo?
582
- - Qual a porcentagem de mulheres na faixa etária de mamografia?
583
- - Quantas mulheres estão nas faixas etárias de preventivo e mamografia?
584
- - Qual a relação masculino/feminino?
585
- - Qual a porcentagem das doenças em relação à população total?
586
- - Use essas informações para responder às perguntas do usuário.
587
- Regras:
588
- 1. Seja sempre cortês.
589
- 2. Responda somente assuntos referentes ao resumo.
590
- 3. Caso seja feita alguma pergunta a você diferente de resumos, responda: "Vamos voltar ao trabalho que interessa?"
591
- 4. Responda sempre em português.
592
- 5. Se não souber a resposta, responda: "Desculpe, mas não tenho esta informação."
593
- 6. Nas suas respostas, não forneça os nomes dos dataframes, apenas responda às perguntas.
594
- 7. Destaque os principais achados e tendências nos dados sempre que possível.
595
- 8. Se aplicável, sugira possíveis ações ou recomendações baseadas nos dados analisados.
596
- """
597
-
598
- # Chamada à API Groq
599
- chat_rci = client.chat.completions.create(
600
- messages=[
601
- {"role": "system", "content": context},
602
- *st.session_state.groq_chat_history,
603
- ],
604
- model="llama3-70b-8192",
605
- temperature=0.3,
606
- max_tokens=2500,
607
- )
608
-
609
- # Processamento da resposta
610
- if chat_rci.choices and len(chat_rci.choices) > 0:
611
- response_message = chat_rci.choices[0].message.content
612
- else:
613
- response_message = (
614
- "Desculpe, não foi possível gerar uma resposta."
615
- )
616
-
617
- # Adição da resposta ao histórico
618
- st.session_state.groq_chat_history.append(
619
- {"role": "assistant", "content": response_message}
620
- )
621
-
622
- # Exibição da resposta
623
- with st.chat_message("assistant"):
624
- st.markdown(response_message)
625
-
626
- except Exception as e:
627
- st.error(f"Erro ao gerar a resposta: {e}")
628
-
629
- # Botão para limpar o histórico do chat
630
- if st.button("Limpar histórico do chat"):
631
- st.session_state.groq_chat_history = []
632
- st.rerun()
 
1
+ """
2
+ This module contains the code for the 'rci' view of the application.
3
+ """
4
+
5
+ import plotly.express as px
6
+ import streamlit as st
7
+ from groq import Groq
8
+ from streamlit_extras.add_vertical_space import add_vertical_space
9
+ from streamlit_extras.stylable_container import stylable_container
10
+ from streamlit_option_menu import option_menu
11
+
12
+ from data_cleaning import processar_arquivo
13
+
14
+
15
+
16
+ #################################
17
+ ############ BANNER #############
18
+ #################################
19
+
20
+ with stylable_container(
21
+ key="banner",
22
+ css_styles="""
23
+ img {
24
+ width: 1800px;
25
+ height: 400px;
26
+ overflow: hidden;
27
+ position: relative;
28
+ object-fit: cover;
29
+ border-radius: 14px; /* Adiciona bordas arredondadas */
30
+ mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
31
+ -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); /* For Safari */
32
+ }
33
+ """,
34
+ ):
35
+ st.image("25.jpg")
36
+
37
+ st.title("Análise de microárea")
38
+
39
+
40
+ #################################
41
+ ############ BANNER #############
42
+ #################################
43
+
44
+
45
+ def clear_chat_history():
46
+ """
47
+ Clears the chat history and resets the initial analysis in the session state.
48
+ This function clears the chat history and resets the initial analysis in the session state.
49
+ It sets the value of "groq_chat_history" in the session state to an empty list and the value of "initial_analysis" to an empty string.
50
+ """
51
+ st.session_state["groq_chat_history"] = []
52
+ st.session_state["initial_analysis"] = ""
53
+
54
+
55
+ #################################
56
+ ############ DATA ###############
57
+ #################################
58
+
59
+ uploaded_file = st.sidebar.file_uploader("Escolha um arquivo CSV", type="csv")
60
+ if uploaded_file is not None:
61
+ dataframes = processar_arquivo(uploaded_file)
62
+ DF_DATA = dataframes.get("Data")
63
+ DF_HEAD = dataframes.get("Head")
64
+ DF_IDADE = dataframes.get("Idade")
65
+ DF_GENERO = dataframes.get("genero")
66
+ DF_COR = dataframes.get("cor")
67
+ DF_DEFICIENCIA = dataframes.get("deficiencia")
68
+ DF_DOENCAS = dataframes.get("doencas")
69
+ DF_ESCOLA = dataframes.get("Escola")
70
+ DF_TRANSGEN = dataframes.get("transgen")
71
+ for df in [
72
+ DF_IDADE,
73
+ DF_GENERO,
74
+ DF_COR,
75
+ DF_DEFICIENCIA,
76
+ DF_DOENCAS,
77
+ DF_ESCOLA,
78
+ DF_TRANSGEN,
79
+ ]:
80
+ if df is not None:
81
+ df["Descrição"] = df["Descrição"].str.capitalize()
82
+ else:
83
+ st.sidebar.info("Adicione um arquivo .csv.")
84
+
85
+ if st.sidebar.button("Limpar", type="primary"):
86
+ clear_chat_history()
87
+
88
+
89
+ def gerar_resumo_df():
90
+ """
91
+ Generates a summary of the dataframes.
92
+ This function creates a summary of the dataframes by concatenating the
93
+ string representation of each dataframe.
94
+ The summary includes the name of the dataframe and its content.
95
+ Returns:
96
+ str: The summary of the dataframes.
97
+ """
98
+ resumo = ""
99
+ if DF_DATA is not None:
100
+ resumo += "Resumo DF_DATA:\n"
101
+ resumo += DF_DATA.to_string(index=False) + "\n\n"
102
+ if DF_HEAD is not None:
103
+ resumo += "Resumo DF_HEAD:\n"
104
+ resumo += DF_HEAD.to_string(index=False) + "\n\n"
105
+ if DF_IDADE is not None:
106
+ resumo += "Resumo DF_IDADE:\n"
107
+ resumo += DF_IDADE.to_string(index=False) + "\n\n"
108
+ if DF_GENERO is not None:
109
+ resumo += f"Resumo DF_GENERO:\n{DF_GENERO.to_string(index=False)}\n\n"
110
+ if DF_COR is not None:
111
+ resumo += f"Resumo DF_COR:\n{DF_COR.to_string(index=False)}\n\n"
112
+ if DF_DEFICIENCIA is not None:
113
+ resumo += f"Resumo DF_DEFICIENCIA:\n{DF_DEFICIENCIA.to_string(index=False)}\n\n"
114
+ if DF_DOENCAS is not None:
115
+ resumo += f"Resumo DF_DOENCAS:\n{DF_DOENCAS.to_string(index=False)}\n\n"
116
+ if DF_ESCOLA is not None:
117
+ resumo += f"Resumo DF_ESCOLA:\n{DF_ESCOLA.to_string(index=False)}\n\n"
118
+ if DF_TRANSGEN is not None:
119
+ resumo += f"Resumo DF_TRANSGEN:\n{DF_TRANSGEN.to_string(index=False)}\n\n"
120
+ return resumo
121
+
122
+
123
+ #################################
124
+ ############ DATA ###############
125
+ #################################
126
+
127
+
128
+ ###########################################
129
+ ############### LATERAL ##################
130
+ ###########################################
131
+
132
+ st.sidebar.markdown(
133
+ """
134
+ ### Informações:
135
+ - Análise - Relatório de cadastro individual.
136
+ - Iniciativa - Ubs Flamengo
137
+ - Acesso livre
138
+ ### Links:
139
+ ##
140
+ ##### - [PEC SUS](https://sape.pecsus.com.br/) 📝
141
+ ###
142
+ ##### - [Obsidian - Dr Guilherme](http://dr-guilhermeapolinario.com) 🌎
143
+ ##### - [GitHub - Dr Guilherme](http://dr-guilhermeapolinario.com) 🌎
144
+ """
145
+ )
146
+ st.markdown(
147
+ """
148
+ #### Instruções:
149
+ ##### - Acesse o site :orange[PEC SUS], na aba esquerda selecione consolidado, :blue[*RELATÓRIO DE CADASTRO INDIVIDUAL*]
150
+ ##### - Selecione a opção :orange[baixar arquivo .csv]. Após baixar o arquivo, selecione o arquivo .csv na aba ao lado, e pronto.
151
+ ##### - Clique no botão de expansão abaixo para iniciar o processo.
152
+ ##### - Utilize o chatbot com a inteligência artificial 🤖 Zé Flamengo para tirar suas dúvidas.
153
+ """
154
+ )
155
+ st.write("-----")
156
+
157
+ st.markdown(
158
+ """
159
+ #### Dados de saúde Relatório de cadastro individual.
160
+ """
161
+ )
162
+
163
+ ###########################################
164
+ ############### LATERAL ##################
165
+ ###########################################
166
+
167
+
168
+ ###########################################
169
+ ############### EXPANDERCOM GRÁFICOS ######
170
+ ###########################################
171
+
172
+
173
+ def criar_grafico_personalizado(df, x_col, y_col, titulo):
174
+ """
175
+ A function to create a customized bar chart based on the input data, x
176
+ and y columns, and title.
177
+ Parameters:
178
+ df (DataFrame): The input DataFrame containing the data.
179
+ x_col (str): The column name for the x-axis data.
180
+ y_col (str): The column name for the y-axis data.
181
+ titulo (str): The title of the chart.
182
+ Returns:
183
+ fig: The customized bar chart figure.
184
+ """
185
+ fig = px.bar(
186
+ df,
187
+ x=x_col,
188
+ y=y_col,
189
+ title=titulo,
190
+ text=y_col,
191
+ color=x_col,
192
+ color_discrete_sequence=px.colors.qualitative.Bold,
193
+ )
194
+ fig.update_traces(texttemplate="%{text:.2s}", textposition="outside")
195
+ fig.update_layout(
196
+ uniformtext_minsize=8,
197
+ uniformtext_mode="hide",
198
+ xaxis_title=x_col,
199
+ yaxis_title=y_col,
200
+ title_font_size=24,
201
+ title_font_family="Arial",
202
+ title_font_color="white",
203
+ title_x=0.2,
204
+ paper_bgcolor="rgba(0,0,0,0)",
205
+ plot_bgcolor="rgba(0,0,0,0)",
206
+ xaxis_tickangle=-45,
207
+ )
208
+ return fig
209
+
210
+
211
+ if uploaded_file is not None:
212
+ c1, c2 = st.columns(2)
213
+ with c1:
214
+ if DF_DATA is not None:
215
+ st.dataframe(DF_DATA, hide_index=True)
216
+ else:
217
+ st.write("Data não disponível")
218
+ with c2:
219
+ if DF_HEAD is not None:
220
+ st.dataframe(DF_HEAD, hide_index=True)
221
+ else:
222
+ st.write("Informações não disponíveis")
223
+
224
+ if uploaded_file is not None:
225
+ with st.expander("Visualização", expanded=True):
226
+ selected_tab = option_menu(
227
+ menu_title=None,
228
+ options=[
229
+ "Faixa Etária",
230
+ "Gênero",
231
+ "Cor",
232
+ "Deficiência",
233
+ "Doenças",
234
+ "Escolaridade",
235
+ "Identidade de Gênero",
236
+ ],
237
+ icons=[
238
+ "person",
239
+ "gender-female",
240
+ "person-plus",
241
+ "person-wheelchair",
242
+ "capsule-pill",
243
+ "stars",
244
+ "gender-trans",
245
+ ],
246
+ menu_icon="cast",
247
+ default_index=0,
248
+ orientation="horizontal",
249
+ styles={
250
+ "container": {
251
+ "padding": "0!important",
252
+ "background-color": "#262730",
253
+ },
254
+ "icon": {"color": "#4FCBFC", "font-size": "18px"},
255
+ "nav-link": {
256
+ "font-size": "14px",
257
+ "text-align": "center",
258
+ "margin": "0px",
259
+ "padding": "10px",
260
+ "--hover-color": "#363940",
261
+ "color": "#FFFFFF",
262
+ },
263
+ "nav-link-selected": {"background-color": "#0083B8"},
264
+ "separator": {"border-color": "#4B4B4B"},
265
+ },
266
+ )
267
+ if selected_tab == "Faixa Etária" and DF_IDADE is not None:
268
+ st.subheader("Distribuição por Faixa Etária")
269
+ col1, col2 = st.columns(2)
270
+ with col1:
271
+ st.dataframe(DF_IDADE, hide_index=True)
272
+ with col2:
273
+ DF_IDADE["Masculino"] = DF_IDADE["Masculino"].astype(int) * -1
274
+ DF_IDADE["Feminino"] = DF_IDADE["Feminino"].astype(int)
275
+ fig_idade = px.bar(
276
+ DF_IDADE,
277
+ x=["Masculino", "Feminino"],
278
+ y="Descrição",
279
+ orientation="h",
280
+ title="Pirâmide Etária",
281
+ labels={"value": "População", "Descrição": "Faixa Etária"},
282
+ color="Descrição",
283
+ color_discrete_sequence=px.colors.qualitative.Set3,
284
+ )
285
+ fig_idade.update_layout(
286
+ barmode="relative",
287
+ xaxis_title="População",
288
+ yaxis_title="Faixa Etária",
289
+ )
290
+ st.plotly_chart(fig_idade)
291
+ DF_IDADE["Masculino"] = DF_IDADE["Masculino"].abs()
292
+
293
+ elif selected_tab == "Gênero" and DF_GENERO is not None:
294
+ st.subheader("Distribuição por Gênero")
295
+ col1, col2 = st.columns(2)
296
+ with col1:
297
+ st.dataframe(DF_GENERO, hide_index=True)
298
+ with col2:
299
+ fig_genero = px.pie(
300
+ DF_GENERO,
301
+ names="Descrição",
302
+ values="Valor",
303
+ title="Distribuição por Gênero",
304
+ color_discrete_sequence=px.colors.qualitative.Pastel,
305
+ )
306
+ st.plotly_chart(fig_genero)
307
+
308
+ elif selected_tab == "Cor" and DF_COR is not None:
309
+ st.subheader("Distribuição por Cor")
310
+ col1, col2 = st.columns(2)
311
+ with col1:
312
+ st.dataframe(DF_COR, hide_index=True)
313
+ with col2:
314
+ fig_cor = px.pie(
315
+ DF_COR,
316
+ names="Descrição",
317
+ values="Valor",
318
+ title="Distribuição por Cor",
319
+ color_discrete_sequence=px.colors.qualitative.Vivid,
320
+ )
321
+ st.plotly_chart(fig_cor)
322
+
323
+ elif selected_tab == "Deficiência" and DF_DEFICIENCIA is not None:
324
+ st.subheader("Distribuição por Deficiência")
325
+ col1, col2 = st.columns(2)
326
+ with col1:
327
+ st.dataframe(DF_DEFICIENCIA, hide_index=True)
328
+ with col2:
329
+ fig_deficiencia = criar_grafico_personalizado(
330
+ DF_DEFICIENCIA,
331
+ x_col="Descrição",
332
+ y_col="Valor",
333
+ titulo="Distribuição por Deficiência",
334
+ )
335
+ st.plotly_chart(fig_deficiencia)
336
+
337
+ elif selected_tab == "Doenças" and DF_DOENCAS is not None:
338
+ st.subheader("Distribuição por Doenças")
339
+ col1, col2 = st.columns(2)
340
+ with col1:
341
+ st.dataframe(DF_DOENCAS, hide_index=True)
342
+ with col2:
343
+ fig_doencas = criar_grafico_personalizado(
344
+ DF_DOENCAS,
345
+ x_col="Descrição",
346
+ y_col="Valor",
347
+ titulo="Distribuição por Doenças",
348
+ )
349
+ st.plotly_chart(fig_doencas)
350
+
351
+ elif selected_tab == "Escolaridade" and DF_ESCOLA is not None:
352
+ st.subheader("Distribuição por Escolaridade")
353
+ col1, col2 = st.columns(2)
354
+ with col1:
355
+ st.dataframe(DF_ESCOLA, hide_index=True)
356
+ with col2:
357
+ fig_escola = criar_grafico_personalizado(
358
+ DF_ESCOLA,
359
+ x_col="Descrição",
360
+ y_col="Valor",
361
+ titulo="Distribuição por Escolaridade",
362
+ )
363
+ st.plotly_chart(fig_escola)
364
+
365
+ elif selected_tab == "Identidade de Gênero" and DF_TRANSGEN is not None:
366
+ st.subheader("Distribuição por Identidade de Gênero")
367
+ col1, col2 = st.columns(2)
368
+ with col1:
369
+ st.dataframe(DF_TRANSGEN, hide_index=True)
370
+ with col2:
371
+ fig_transgen = criar_grafico_personalizado(
372
+ DF_TRANSGEN,
373
+ x_col="Descrição",
374
+ y_col="Valor",
375
+ titulo="Distribuição por Identidade de Gênero",
376
+ )
377
+ st.plotly_chart(fig_transgen)
378
+
379
+
380
+ ###########################################
381
+ ############### EXPANDERCOM GRÁFICOS ######
382
+ ###########################################
383
+
384
+ add_vertical_space(5)
385
+
386
+ ###########################################
387
+ ############### FOTO DO BOT ###############
388
+ ###########################################
389
+
390
+ with stylable_container(
391
+ key="bot",
392
+ css_styles="""
393
+ img {
394
+ width: 120px;
395
+ height: 100px;
396
+ overflow: hidden;
397
+ position: relative;
398
+ object-fit: cover;
399
+ border-radius: 14px; /* Adiciona bordas arredondadas */
400
+ }
401
+ """,
402
+ ):
403
+ st.image("src/images/b.png")
404
+
405
+ ###########################################
406
+ ############### FOTO DO BOT ###############
407
+ ###########################################
408
+
409
+
410
+ ###########################################
411
+ ############### CHATBOT RCI ###############
412
+ ###########################################
413
+
414
+ # Configuração inicial do Groq client
415
+ client = Groq(api_key=st.secrets["GROQ_API_KEY"])
416
+
417
+
418
+ # Função para gerar a análise inicial
419
+ def generate_initial_analysis(resumo_rci):
420
+ """
421
+ Generates an initial analysis report based on the provided resumo_rci.
422
+ Parameters:
423
+ resumo_rci (str): The resumo_rci to be analyzed.
424
+ Returns:
425
+ str: The generated initial analysis report.
426
+ Raises:
427
+ Exception: If there is an error generating the initial analysis.
428
+ Examples:
429
+ >>> generate_initial_analysis("Resumo do RCI")
430
+ "Cabeçalho com informações gerais (data, cidadãos ativos, saída, mudança de território,
431
+ óbito)\n\nAnálise de Faixa Etária (Crianças de 0 a 2 anos, 0 a 4 anos, mulheres na faixa etária
432
+ de preventivo 25 a 64 anos, mulehres na faixa etária de mamomagrafia 50a 69 anos)\n\nComparação
433
+ de Sexo\n\nAnálise de Raça / Cor\n\nAnálise de
434
+ Escolaridade\n\nOrientação Sexual\n\nDeficiências\n\nSituações de Saúde Gerais\n\n\nFormate seu
435
+ relatório usando negrito para títulos de seções e subtítulos. Use listas com marcadores
436
+ quando apropriado para melhorar a legibilidade. Apresente seu relatório final dentro de tags
437
+ <relatorio></relatorio>."
438
+ """
439
+ try:
440
+ initial_analysis = client.chat.completions.create(
441
+ messages=[
442
+ {
443
+ "role": "system",
444
+ "content": "Você é um assistente de análise de dados de saúde. Sua tarefa é analisar os dados fornecidos e criar um relatório detalhado seguindo o modelo especificado. O relatório deve ser escrito em português.",
445
+ },
446
+ {
447
+ "role": "user",
448
+ "content": f"""
449
+ Aqui estão os dados para análise:
450
+ <resumo_rci>
451
+ {resumo_rci}
452
+ </resumo_rci>
453
+
454
+ Analise cuidadosamente os dados fornecidos e crie um relatório
455
+ seguindo o modelo apresentado. O relatório deve incluir as seguintes
456
+ seções:
457
+ 1. Cabeçalho com informações gerais (data, cidadãos ativos, saída,
458
+ mudança de território, óbito)
459
+ 2. Análise de Faixa Etária (Crianças de 0 a 2 anos, 0 a 4 anos, mulheres
460
+ na faixa etária de preventivo 25 a 64 anos, mulehres na faixa etária de
461
+ mamomagrafia 50a 69 anos)
462
+ 3. Comparação de Sexo
463
+ 4. Análise de Raça / Cor
464
+ 5. Análise de Escolaridade
465
+ 6. Orientação Sexual
466
+ 7. Deficiências
467
+ 8. Situações de Saúde Gerais
468
+
469
+ Para cada seção:
470
+ - Calcule os totais e percentuais relevantes
471
+ - Faça comparações quando apropriado (por exemplo, entre masculino
472
+ e feminino)
473
+ - Destaque as 3 informações mais significativas
474
+
475
+ Formate seu relatório usando negrito para títulos de seções e subtítulos.
476
+ Use o título de Análise parcial, use listas com marcadores quando apropriado
477
+ para melhorar a legibilidade.
478
+
479
+ """,
480
+ },
481
+ ],
482
+ model="llama3-70b-8192",
483
+ temperature=0.2,
484
+ max_tokens=1500,
485
+ )
486
+ return initial_analysis.choices[0].message.content
487
+ except Exception as e:
488
+ st.error(f"Erro ao gerar a análise inicial: {e}")
489
+ return "Não foi possível gerar a análise inicial."
490
+
491
+
492
+ # Carregar arquivo
493
+ # uploaded_file = st.file_uploader("Escolha um arquivo CSV", type="csv")
494
+
495
+ if uploaded_file is not None:
496
+ if (
497
+ "current_file" not in st.session_state
498
+ or st.session_state.current_file != uploaded_file.name
499
+ ):
500
+ st.session_state.current_file = uploaded_file.name
501
+ st.session_state.initial_analysis = None # Reset da análise anterior
502
+ st.session_state.resumo_rci = None # Reset do resumo
503
+
504
+ # Botão para gerar o resumo
505
+ if st.button("Gerar Resumo"):
506
+ with st.spinner("Gerando resumo..."):
507
+ st.session_state.resumo_rci = (
508
+ gerar_resumo_df()
509
+ ) # Gera o resumo do DataFrame
510
+ st.session_state.initial_analysis = generate_initial_analysis(
511
+ st.session_state.resumo_rci
512
+ )
513
+ st.success("Resumo gerado com sucesso!")
514
+
515
+ col1, col2 = st.columns(2)
516
+
517
+ with col1:
518
+ with st.expander("Resumo Inicial", expanded=True):
519
+ if "initial_analysis" in st.session_state:
520
+ st.write("**Panorama Geral dos Dados:**")
521
+ st.text_area(
522
+ "Análise Inicial",
523
+ value=st.session_state.initial_analysis,
524
+ height=300,
525
+ disabled=False,
526
+ )
527
+ else:
528
+ st.write("**Clique em 'Gerar Resumo' para analisar os dados.**")
529
+
530
+ with col2:
531
+ with st.expander("Converse com o 🤖 Zé Flamengo", expanded=True):
532
+ # Inicialização do histórico do chat
533
+ if "groq_chat_history" not in st.session_state:
534
+ st.session_state.groq_chat_history = []
535
+
536
+ # Exibição do histórico do chat
537
+ for message in st.session_state.groq_chat_history:
538
+ with st.chat_message(message["role"]):
539
+ st.markdown(message["content"])
540
+
541
+ # Input do usuário e processamento da resposta
542
+ if user_message := st.chat_input(
543
+ "Digite sua pergunta sobre saúde na microárea:"
544
+ ):
545
+ # Adiciona a mensagem do usuário ao histórico
546
+ st.session_state.groq_chat_history.append(
547
+ {"role": "user", "content": user_message}
548
+ )
549
+
550
+ try:
551
+ # Usar o resumo já gerado
552
+ if "resumo_rci" not in st.session_state:
553
+ st.warning("Por favor, gere o resumo antes de fazer perguntas.")
554
+ else:
555
+ resumo_rci = st.session_state.resumo_rci
556
+
557
+ # Preparação do contexto para a API
558
+ context = f"""
559
+ Seu nome é Zé Flamengo, você é um assistente virtual especializado em análise de dados
560
+ médicos epidemiológicos. Você tem 20 anos de experiência em análise de dados de saúde de
561
+ microáreas de um PSF (Programa Saúde da Família).
562
+ Sua função é:
563
+ 1. Analisar dados de uma unidade básica de saúde.
564
+ 2. Os dados que irá analisar são provenientes do Relatório de Cadastro Individual, advindos do PEC SUS.
565
+ 3. Suas respostas devem ser sempre em português.
566
+ 4. Seja conciso e evite conversar sobre outros temas.
567
+ 5. Sempre retome o tema da conversa.
568
+ 6. Realize sempre os cálculos novamente para garantir que os resultados fornecidos sejam precisos e atualizados.
569
+ Os dataframes que irá analisar são do Relatório de cadastro indiviual.
570
+ ele foi transformados em texto aqui disponíveis:
571
+ {resumo_rci}
572
+ As faixas etárias recomendadas para exames preventivos são:
573
+ - **Papanicolau (Preventivo):** Mulheres entre 25 e 64 anos, com frequência anual nos primeiros dois exames
574
+ consecutivos com resultados normais, depois a cada três anos.
575
+ - **Mamografia:** Mulheres entre 50 e 69 anos, com frequência bienal.
576
+ Informações sobre o Relatório de Cadastro Individual:
577
+ - **Objetivo:** Coletar dados sociodemográficos e de saúde dos indivíduos cadastrados em uma unidade básica de saúde.
578
+ - **Principais Indicadores:** Idade, sexo, condições de saúde (doenças crônicas, gestantes, etc.), status de
579
+ vacinação, hábitos de vida (tabagismo, alcoolismo, atividade física), entre outros.
580
+ Exemplos de perguntas esperadas:
581
+ - Qual a porcentagem de mulheres na faixa etária de preventivo?
582
+ - Qual a porcentagem de mulheres na faixa etária de mamografia?
583
+ - Quantas mulheres estão nas faixas etárias de preventivo e mamografia?
584
+ - Qual a relação masculino/feminino?
585
+ - Qual a porcentagem das doenças em relação à população total?
586
+ - Use essas informações para responder às perguntas do usuário.
587
+ Regras:
588
+ 1. Seja sempre cortês.
589
+ 2. Responda somente assuntos referentes ao resumo.
590
+ 3. Caso seja feita alguma pergunta a você diferente de resumos, responda: "Vamos voltar ao trabalho que interessa?"
591
+ 4. Responda sempre em português.
592
+ 5. Se não souber a resposta, responda: "Desculpe, mas não tenho esta informação."
593
+ 6. Nas suas respostas, não forneça os nomes dos dataframes, apenas responda às perguntas.
594
+ 7. Destaque os principais achados e tendências nos dados sempre que possível.
595
+ 8. Se aplicável, sugira possíveis ações ou recomendações baseadas nos dados analisados.
596
+ """
597
+
598
+ # Chamada à API Groq
599
+ chat_rci = client.chat.completions.create(
600
+ messages=[
601
+ {"role": "system", "content": context},
602
+ *st.session_state.groq_chat_history,
603
+ ],
604
+ model="llama3-70b-8192",
605
+ temperature=0.3,
606
+ max_tokens=2500,
607
+ )
608
+
609
+ # Processamento da resposta
610
+ if chat_rci.choices and len(chat_rci.choices) > 0:
611
+ response_message = chat_rci.choices[0].message.content
612
+ else:
613
+ response_message = (
614
+ "Desculpe, não foi possível gerar uma resposta."
615
+ )
616
+
617
+ # Adição da resposta ao histórico
618
+ st.session_state.groq_chat_history.append(
619
+ {"role": "assistant", "content": response_message}
620
+ )
621
+
622
+ # Exibição da resposta
623
+ with st.chat_message("assistant"):
624
+ st.markdown(response_message)
625
+
626
+ except Exception as e:
627
+ st.error(f"Erro ao gerar a resposta: {e}")
628
+
629
+ # Botão para limpar o histórico do chat
630
+ if st.button("Limpar histórico do chat"):
631
+ st.session_state.groq_chat_history = []
632
+ st.rerun()