drguilhermeapolinario commited on
Commit
499c6d2
·
verified ·
1 Parent(s): 76bc832

Update views/pdf_chat.py

Browse files
Files changed (1) hide show
  1. views/pdf_chat.py +451 -5
views/pdf_chat.py CHANGED
@@ -11,9 +11,9 @@ st.title("Utilidades")
11
  nested_menu = option_menu(
12
  menu_title=None,
13
  options=[
14
- "Incidências radiológicas", "Calculadora TFG", "Escala de Risco de Coelho e Savassi", "Escore de Risco Global (ERG)"
15
  ],
16
- icons=['lungs', 'gear', 'envelope', 'heart'],
17
  menu_icon="cast",
18
  default_index=0,
19
  orientation="horizontal",
@@ -135,7 +135,7 @@ if nested_menu == "Incidências radiológicas":
135
  Desenvolvedor ☕ **Dr. Guilherme**
136
  """)
137
 
138
- elif nested_menu == "Calculadora TFG":
139
  import pathlib
140
 
141
  import streamlit as st
@@ -634,7 +634,7 @@ elif nested_menu == "Calculadora TFG":
634
  Desenvolvedor ☕ **Dr. Guilherme**
635
  """)
636
 
637
- elif nested_menu == "Escala de Risco de Coelho e Savassi":
638
  import pandas as pd
639
  import streamlit as st
640
 
@@ -824,7 +824,7 @@ elif nested_menu == "Escala de Risco de Coelho e Savassi":
824
  with col4:
825
  st.write('')
826
 
827
- elif nested_menu == "Escore de Risco Global (ERG)":
828
  import numpy as np
829
  import pandas as pd
830
  import streamlit as st
@@ -1334,4 +1334,450 @@ elif nested_menu == "Escore de Risco Global (ERG)":
1334
  with cft3:
1335
  st.write('')
1336
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1337
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  nested_menu = option_menu(
12
  menu_title=None,
13
  options=[
14
+ "Incidências radiológicas", "TFG", "Coelho e Savassi", "Escore de Risco Global", "Noripurun",
15
  ],
16
+ icons=['lungs', 'nephrology', 'clinical_notes', 'heart', 'syrenge'],
17
  menu_icon="cast",
18
  default_index=0,
19
  orientation="horizontal",
 
135
  Desenvolvedor ☕ **Dr. Guilherme**
136
  """)
137
 
138
+ elif nested_menu == "TFG":
139
  import pathlib
140
 
141
  import streamlit as st
 
634
  Desenvolvedor ☕ **Dr. Guilherme**
635
  """)
636
 
637
+ elif nested_menu == "Coelho e Savassi":
638
  import pandas as pd
639
  import streamlit as st
640
 
 
824
  with col4:
825
  st.write('')
826
 
827
+ elif nested_menu == "Escore de Risco Global":
828
  import numpy as np
829
  import pandas as pd
830
  import streamlit as st
 
1334
  with cft3:
1335
  st.write('')
1336
 
1337
+ elif nested_menu == "Noripurun":
1338
+ import pathlib
1339
+
1340
+ import streamlit as st
1341
+ import streamlit.components.v1 as components
1342
+ from streamlit_extras.add_vertical_space import add_vertical_space
1343
+
1344
+ st.header("Calculadora TFG")
1345
+
1346
+ static_dir = pathlib.Path('static').absolute()
1347
+ html_with_js= ''
1348
+
1349
+ @st.fragment
1350
+ def estil():
1351
+ css_file_path = static_dir / 'styles.css'
1352
+ if css_file_path.exists():
1353
+ with open(css_file_path, "r", encoding="utf-8") as f:
1354
+ st_css = st.html(f"<style>{f.read()}</style>")
1355
+ return st_css
1356
+ else:
1357
+ st.error(f"CSS file not found: {css_file_path}")
1358
+ return None
1359
 
1360
+ @st.fragment
1361
+ def noripurun(html_with_js):
1362
+ html_with_js = '''
1363
+ <!DOCTYPE html>
1364
+ <html>
1365
+ <head>
1366
+ <style>
1367
+ :root {
1368
+ --primary-color: #2196F3;
1369
+ --bg-color: #e0e5ec;
1370
+ --text-color: #2d4059;
1371
+ --shadow-light: #ffffff;
1372
+ --shadow-dark: #a3b1c6;
1373
+ }
1374
+
1375
+ body {
1376
+ background-color: var(--bg-color);
1377
+ color: var(--text-color);
1378
+ font-family: 'Segoe UI', Arial, sans-serif;
1379
+ line-height: 1.6;
1380
+ margin: 0;
1381
+ padding: 20px;
1382
+ }
1383
+
1384
+ .calculator-container {
1385
+ max-width: 800px;
1386
+ margin: 40px auto;
1387
+ padding: 30px;
1388
+ background: var(--bg-color);
1389
+ border-radius: 20px;
1390
+ box-shadow:
1391
+ 8px 8px 15px var(--shadow-dark),
1392
+ -8px -8px 15px var(--shadow-light);
1393
+ }
1394
+
1395
+ .header {
1396
+ text-align: center;
1397
+ margin-bottom: 30px;
1398
+ }
1399
+
1400
+ .header h2 {
1401
+ color: var(--primary-color);
1402
+ margin: 0;
1403
+ padding: 15px;
1404
+ border-radius: 10px;
1405
+ box-shadow:
1406
+ inset 5px 5px 10px var(--shadow-dark),
1407
+ inset -5px -5px 10px var(--shadow-light);
1408
+ }
1409
+
1410
+ .info-box, .details-box {
1411
+ padding: 20px;
1412
+ margin: 20px 0;
1413
+ border-radius: 15px;
1414
+ box-shadow:
1415
+ inset 5px 5px 10px var(--shadow-dark),
1416
+ inset -5px -5px 10px var(--shadow-light);
1417
+ }
1418
+
1419
+ .form-group {
1420
+ margin: 25px 0;
1421
+ }
1422
+
1423
+ label {
1424
+ display: block;
1425
+ margin-bottom: 10px;
1426
+ font-weight: 600;
1427
+ color: var(--text-color);
1428
+ }
1429
+
1430
+ input, select {
1431
+ width: 60%;
1432
+ padding: 12px;
1433
+ border: none;
1434
+ border-radius: 10px;
1435
+ background: var(--bg-color);
1436
+ box-shadow:
1437
+ inset 5px 5px 10px var(--shadow-dark),
1438
+ inset -5px -5px 10px var(--shadow-light);
1439
+ color: var(--text-color);
1440
+ font-size: 16px;
1441
+ transition: all 0.3s ease;
1442
+ }
1443
+
1444
+ input:focus, select:focus {
1445
+ outline: none;
1446
+ box-shadow:
1447
+ inset 3px 3px 5px var(--shadow-dark),
1448
+ inset -3px -3px 5px var(--shadow-light);
1449
+ }
1450
+
1451
+ .calculate-btn {
1452
+ width: 100%;
1453
+ padding: 15px;
1454
+ border: none;
1455
+ border-radius: 10px;
1456
+ background: var(--bg-color);
1457
+ color: var(--primary-color);
1458
+ font-size: 18px;
1459
+ font-weight: bold;
1460
+ cursor: pointer;
1461
+ box-shadow:
1462
+ 5px 5px 10px var(--shadow-dark),
1463
+ -5px -5px 10px var(--shadow-light);
1464
+ transition: all 0.3s ease;
1465
+ }
1466
+
1467
+ .calculate-btn:hover {
1468
+ box-shadow:
1469
+ 3px 3px 5px var(--shadow-dark),
1470
+ -3px -3px 5px var(--shadow-light);
1471
+ }
1472
+
1473
+ .calculate-btn:active {
1474
+ box-shadow:
1475
+ inset 3px 3px 5px var(--shadow-dark),
1476
+ inset -3px -3px 5px var(--shadow-light);
1477
+ }
1478
+
1479
+ .result-box {
1480
+ margin-top: 30px;
1481
+ padding: 20px;
1482
+ border-radius: 15px;
1483
+ box-shadow:
1484
+ inset 5px 5px 10px var(--shadow-dark),
1485
+ inset -5px -5px 10px var(--shadow-light);
1486
+ }
1487
+
1488
+ .formula-box {
1489
+ background: var(--bg-color);
1490
+ padding: 20px;
1491
+ border-radius: 10px;
1492
+ box-shadow:
1493
+ inset 3px 3px 5px var(--shadow-dark),
1494
+ inset -3px -3px 5px var(--shadow-light);
1495
+ font-family: monospace;
1496
+ font-size: 14px;
1497
+ line-height: 1.8;
1498
+ }
1499
+
1500
+ table {
1501
+ width: 100%;
1502
+ border-spacing: 10px;
1503
+ border-collapse: separate;
1504
+ margin: 20px 0;
1505
+ }
1506
+
1507
+ th, td {
1508
+ padding: 10px;
1509
+ text-align: left;
1510
+ background: var(--bg-color);
1511
+ border-radius: 12px;
1512
+ box-shadow:
1513
+ 1px 1px 2px var(--shadow-dark),
1514
+ -1px -1px 2px var(--shadow-light);
1515
+ }
1516
+
1517
+ th {
1518
+ background: var(--primary-color);
1519
+ color: white;
1520
+ font-weight: 600;
1521
+ }
1522
+
1523
+ .alert {
1524
+ padding: 15px;
1525
+ margin: 15px 0;
1526
+ border-radius: 10px;
1527
+ background: #fff3e0;
1528
+ box-shadow:
1529
+ 3px 3px 5px var(--shadow-dark),
1530
+ -3px -3px 5px var(--shadow-light);
1531
+ }
1532
+
1533
+ .warning {
1534
+ background: #ffebee;
1535
+ }
1536
+
1537
+ .dilution-info {
1538
+ background: var(--bg-color);
1539
+ padding: 15px;
1540
+ margin: 15px 0;
1541
+ border-radius: 10px;
1542
+ box-shadow:
1543
+ inset 3px 3px 5px var(--shadow-dark),
1544
+ inset -3px -3px 5px var(--shadow-light);
1545
+ }
1546
+
1547
+ .info-grid {
1548
+ display: flex;
1549
+ gap: 20px;
1550
+ }
1551
+
1552
+ details {
1553
+ flex: 1;
1554
+ }
1555
+
1556
+ summary {
1557
+ cursor: pointer;
1558
+ }
1559
+
1560
+ section {
1561
+ display: flex;
1562
+ flex-direction: row;
1563
+ gap: 20px;
1564
+ }
1565
+
1566
+ @media (max-width: 768px) {
1567
+ .info-grid {
1568
+ grid-template-columns: 1fr;
1569
+ }
1570
+ }
1571
+ </style>
1572
+ </head>
1573
+ <body>
1574
+ <div class="calculator-container">
1575
+ <div class="header">
1576
+ <h2>Calculadora de Dose - Noripurum</h2>
1577
+ <strong>Parâmetros Importantes:</strong>
1578
+ </div>
1579
+ <div class="info-box">
1580
+ <div class="info-grid">
1581
+ <details>
1582
+ <summary><h4>Limites de Dose:</h4></summary>
1583
+ <ul>
1584
+ <li>Dose máxima por aplicação: 200mg</li>
1585
+ <li>Dose máxima semanal: 500mg</li>
1586
+ <li>Intervalo mínimo entre doses: 24h</li>
1587
+ </ul>
1588
+ </details>
1589
+ <details>
1590
+ <summary><h4>Diluição e Administração:</h4></summary>
1591
+ <ul>
1592
+ <li>Diluição mínima: 100mL SF 0,9% por ampola</li>
1593
+ <li>Tempo mínimo de infusão: 15 min/ampola</li>
1594
+ <li>Administrar exclusivamente em SF 0,9%</li>
1595
+ </ul>
1596
+ </details>
1597
+ <details>
1598
+ <summary><h4>Reserva de Ferro:</h4></summary>
1599
+ <ul>
1600
+ <li>Pacientes < 35kg: 15mg/kg</li>
1601
+ <li>Pacientes ≥ 35kg: 500mg fixo</li>
1602
+ </ul>
1603
+ </details>
1604
+ </div>
1605
+ </div>
1606
+ <section>
1607
+ <div class="form-group">
1608
+ <label for="peso">Peso do Paciente (kg):</label>
1609
+ <input type="number" id="peso" min="0" step="0.1" required>
1610
+ </div>
1611
+
1612
+ <div class="form-group">
1613
+ <label for="hb-atual">Hemoglobina Atual (g/dL):</label>
1614
+ <input type="number" id="hb-atual" min="0" step="0.1" required>
1615
+ </div>
1616
+
1617
+ <div class="form-group">
1618
+ <label for="hb-alvo">Hemoglobina Alvo (g/dL):</label>
1619
+ <select id="hb-alvo" required>
1620
+ <option value="12">12 g/dL</option>
1621
+ <option value="13">13 g/dL</option>
1622
+ <option value="14">14 g/dL</option>
1623
+ <option value="15">15 g/dL</option>
1624
+ </select>
1625
+
1626
+ </div>
1627
+
1628
+ </section>
1629
+ <small style="color: #666; display:grid">Padrão: 12 g/dL (mulheres) / 13 g/dL (homens)</small>
1630
+ <div style="display: grid; justify-content: center;">
1631
+ <button class="calculate-btn" onclick="calcularDose()">Calcular Dose</button>
1632
+ </div>
1633
+ <div id="resultado" class="result-box">
1634
+ <div id="alert-box"></div>
1635
+ <div class="details-box">
1636
+ <strong>Detalhes do Cálculo:</strong>
1637
+ <div id="calculo-detalhado"></div>
1638
+ </div>
1639
+ <div class="result-item">
1640
+ <strong>Déficit Total de Ferro:</strong> <span id="deficit-total"></span>
1641
+ </div>
1642
+ <div class="result-item">
1643
+ <strong>Esquema de Administração Recomendado:</strong>
1644
+ <div id="esquema-admin"></div>
1645
+ </div>
1646
+ </div>
1647
+ </div>
1648
+ <script>
1649
+ function calcularDose() {
1650
+ // Obter e validar valores de entrada
1651
+ const peso = parseFloat(document.getElementById('peso').value);
1652
+ const hbAtual = parseFloat(document.getElementById('hb-atual').value);
1653
+ const hbAlvo = parseFloat(document.getElementById('hb-alvo').value);
1654
+
1655
+ if (!validarEntradas(peso, hbAtual, hbAlvo)) {
1656
+ return;
1657
+ }
1658
+
1659
+ // Cálculos principais
1660
+ const reservaFerro = calcularReservaFerro(peso);
1661
+ const dhb = hbAlvo - hbAtual;
1662
+ const deficitTotal = Math.round((peso * dhb * 2.4) + reservaFerro);
1663
+
1664
+ // Exibir resultados
1665
+ mostrarResultados(peso, hbAtual, hbAlvo, dhb, reservaFerro, deficitTotal);
1666
+ criarEsquemaAdministracao(deficitTotal);
1667
+ mostrarAlertas(hbAtual, hbAlvo, deficitTotal);
1668
+ }
1669
+
1670
+ function validarEntradas(peso, hbAtual, hbAlvo) {
1671
+ if (!peso || !hbAtual || !hbAlvo) {
1672
+ alert('Por favor, preencha todos os campos!');
1673
+ return false;
1674
+ }
1675
+ if (peso <= 0 || hbAtual <= 0 || hbAlvo <= 0) {
1676
+ alert('Os valores devem ser maiores que zero!');
1677
+ return false;
1678
+ }
1679
+ return true;
1680
+ }
1681
+
1682
+ function calcularReservaFerro(peso) {
1683
+ return peso < 35 ? Math.round(peso * 15) : 500;
1684
+ }
1685
+
1686
+ function mostrarResultados(peso, hbAtual, hbAlvo, dhb, reservaFerro, deficitTotal) {
1687
+ document.getElementById('resultado').style.display = 'block';
1688
+
1689
+ const calculoHtml = `
1690
+ <p><strong>Fórmula utilizada:</strong></p>
1691
+ <div class="formula-box">
1692
+ Déficit Total = (Peso × ΔHb × 2.4) + Reserva de Ferro<br>
1693
+ Onde:<br>
1694
+ - Peso = ${peso} kg<br>
1695
+ - ΔHb (diferença de Hb) = ${hbAlvo} - ${hbAtual.toFixed(1)} = ${dhb.toFixed(1)} g/dL<br>
1696
+ - Reserva de Ferro = ${reservaFerro} mg (${peso < 35 ? '15mg/kg' : 'fixo 500mg'})<br>
1697
+ <br>
1698
+ Cálculo: (${peso} × ${dhb.toFixed(1)} × 2.4) + ${reservaFerro} = ${deficitTotal} mg
1699
+ </div>`;
1700
+
1701
+ document.getElementById('calculo-detalhado').innerHTML = calculoHtml;
1702
+ document.getElementById('deficit-total').textContent = `${deficitTotal}mg`;
1703
+ }
1704
+
1705
+ function criarEsquemaAdministracao(deficitTotal) {
1706
+ const numDoses = Math.ceil(deficitTotal / 200);
1707
+ const dosesPorSemana = Math.min(2, numDoses);
1708
+ const numSemanas = Math.ceil(numDoses / dosesPorSemana);
1709
+
1710
+ let esquemaHtml = `
1711
+ <table>
1712
+ <tr>
1713
+ <th>Semana</th>
1714
+ <th>Terça-feira</th>
1715
+ <th>Sexta-feira</th>
1716
+ <th>Total Semanal</th>
1717
+ </tr>`;
1718
+
1719
+ let ferroRestante = deficitTotal;
1720
+
1721
+ for (let semana = 1; semana <= numSemanas; semana++) {
1722
+ const doseTerca = calcularDoseSemanal(ferroRestante);
1723
+ ferroRestante -= doseTerca;
1724
+ const doseSexta = calcularDoseSemanal(ferroRestante);
1725
+ ferroRestante -= doseSexta;
1726
+
1727
+ esquemaHtml += `
1728
+ <tr>
1729
+ <td>${semana}</td>
1730
+ <td>${formatarDose(doseTerca)}</td>
1731
+ <td>${formatarDose(doseSexta)}</td>
1732
+ <td>${doseTerca + doseSexta}mg</td>
1733
+ </tr>`;
1734
+ }
1735
+
1736
+ esquemaHtml += '</table>';
1737
+ document.getElementById('esquema-admin').innerHTML = esquemaHtml;
1738
+ }
1739
+
1740
+ function calcularDoseSemanal(ferroRestante) {
1741
+ if (ferroRestante <= 0) return 0;
1742
+ // Arredonda para múltiplos de 100 e limita a 200mg
1743
+ return Math.min(200, Math.round(Math.min(ferroRestante, 200) / 100) * 100);
1744
+ }
1745
+
1746
+ function formatarDose(dose) {
1747
+ if (dose <= 0) return '-';
1748
+ const numAmpolas = dose / 100;
1749
+ return `${dose}mg (${numAmpolas} ${numAmpolas === 1 ? 'ampola' : 'ampolas'})`;
1750
+ }
1751
+
1752
+ function mostrarAlertas(hbAtual, hbAlvo, deficitTotal) {
1753
+ let alertas = [];
1754
+
1755
+ if (hbAtual >= hbAlvo) {
1756
+ alertas.push(`
1757
+ <div class="alert warning">
1758
+ ATENÇÃO: Hemoglobina atual maior ou igual à meta.
1759
+ Verificar necessidade real de reposição.
1760
+ </div>`);
1761
+ }
1762
+
1763
+ if (deficitTotal > 1000) {
1764
+ alertas.push(`
1765
+ <div class="alert">
1766
+ Tratamento prolongado necessário.
1767
+ Considerar reavaliação após 4-6 semanas de tratamento.
1768
+ </div>`);
1769
+ }
1770
+
1771
+ document.getElementById('alert-box').innerHTML = alertas.join('');
1772
+ }
1773
+ </script>
1774
+ </body>
1775
+ </html>
1776
+ '''
1777
+ nori = components.html(html_with_js, width=600,height=900)
1778
+ return nori
1779
+
1780
+ noripurun()
1781
+ estil()
1782
+
1783
+