admin管理员组

文章数量:1123510

I have to create a program for a project in python where I register a patient and their information along with their vitals (Heart Rate Variability (VFC), Oxygen Saturation (VSO), Arterial Blood Pressure (VPA), Body Temperature (VTC)) but I also want to be able to add more values to one person's vitals without having to register the person again. (I'm Portuguese so some part of the code will be in that language)

This is the code I have so far:


import csv
import os
from datetime import datetime, date
import statistics
import matplotlib.pyplot as plt

registos_dir = "A52810_registos_pacientes_v01"
os.makedirs(registos_dir, exist_ok=True)

valores_normais = {"VFC": (50, 100), "VSO": (1, 3), "VPA": (0, 10), "VTC": (0.5, 1.0)}

def calcular_idade(data_nascimento):
    hoje = date.today()
    return hoje.year - data_nascimento.year - ((hoje.month, hoje.day) < (data_nascimento.month, data_nascimento.day))

def calcular_desvio_padrao_lista(dados):
    desv_pad = statistics.stdev(dados)
    return desv_pad

def calcular_desvio_padrao_arquivo(arquivo):
    try:
        with open(arquivo, 'r') as f:
            valores = [float(line.strip()) for line in f.readlines() if line.strip()]
            if len(valores) < 2:
                raise ValueError("O arquivo precisa conter pelo menos dois valores numéricos.")
            return statistics.stdev(valores)
    except Exception as e:
        print(f"Erro ao processar o arquivo {arquivo}: {e}")
        return None
    
def obter_float(prompt):
    while True:
        try:
            return float(input(prompt))
        except ValueError:
            print("Entrada inválida. Por favor, insira um número válido.")

def obter_data(prompt):
    while True:
        try:
            return datetime.strptime(input(prompt), "%d-%m-%Y").date()
        except ValueError:
            print("Formato inválido. Insira a data no formato DD-MM-AAAA.")

def obter_dados():
    dados = []
    while True:
        try:
            valor = float(input("Insira um valor numérico: "))
            dados.append(valor)
            while True:
                continua = input("Inserir mais dados? (s/n): ").strip().lower()    
                if continua == "n":
                    if len(dados) >= 2:
                        return dados
                    else:
                        print("É preciso fornecer pelo menos dois valores numéricos.")
                elif continua == "s":
                    break
                else:
                    print("Resposta inválida. Digite 's' para sim ou 'n' para não.")
        except ValueError:
            print("Erro. Insira um número válido.")

def obter_arquivo(prompt):
    while True:
        arquivo = input(prompt)
        if os.path.exists(arquivo):
            return arquivo
        print("Arquivo não encontrado. Tente novamente.")

def registar_paciente():
    nome = input("Nome completo do paciente: ").strip()
    data_nasc = obter_data("Data de nascimento (DD-MM-AAAA): ")
    peso = obter_float("Peso (kg): ")
    altura = obter_float("Altura (cm): ")
    idade = calcular_idade(data_nasc)
    
    resultados = {}

    while True:
        tipo = input("Deseja fornecer os dados manualmente ou através de um arquivo?\n1. Manual\n2. Arquivo\nEscolha: ").strip()
        if tipo == "1":
            for sinal in ["VFC", "VSO", "VPA", "VTC"]:
                print(f"\nInsira os dados para {sinal}:")
                valores = obter_dados()
                desv_pad = calcular_desvio_padrao_lista(valores)
                dentro_do_normal = valores_normais[sinal][0] <= desv_pad <= valores_normais[sinal][1]
                resultados[sinal] = (desv_pad, dentro_do_normal)
            break
        elif tipo == "2":
            arquivos = {}
            for sinal in ["VFC", "VSO", "VPA", "VTC"]:
                arquivos[sinal] = obter_arquivo(f"Insira o nome do arquivo para {sinal}: ")
            for sinal, arquivo in arquivos.items():
                desv_pad = calcular_desvio_padrao_arquivo(arquivo)
                if desv_pad is not None:
                    dentro_do_normal = valores_normais[sinal][0] <= desv_pad <= valores_normais[sinal][1]
                    resultados[sinal] = (desv_pad, dentro_do_normal)
                else:
                    resultados[sinal] = (None, False)
            break
        else:
            print("Escolha inválida. Digite '1' para Manual ou '2' para Arquivo.")

    data_hora_registo = datetime.now().strftime("%d-%m-%Y %H:%M:%S")

    registro_path = os.path.join(registos_dir, f"{nome.replace(' ', '_')}.csv")
    with open(registro_path, "w", newline="") as f:
        writer = csv.writer(f)
        writer.writerow(["Nome", "Data de Nascimento", "Idade", "Peso", "Altura", "Data e Hora do Registo"])
        writer.writerow([nome, data_nasc, idade, peso, altura, data_hora_registo])
        writer.writerow([])
        writer.writerow(["Sinal Vital", "Desvio Padrão", "Dentro do Normal"])
        for sinal, (dp, normal) in resultados.items():
            writer.writerow([sinal, dp, "Sim" if normal else "Não"])
    print(f"Paciente {nome} registado com sucesso!")

def listar_pacientes():
    pacientes = [f.replace(".csv", "").replace("_", " ") for f in os.listdir(registos_dir) if f.endswith(".csv")]
    if not pacientes:
        print("Nenhum paciente registado.")
    else:
        print("Pacientes registados:")
        for i, paciente in enumerate(pacientes, 1):
            print(f"{i}. {paciente}")

def acessar_paciente():
    listar_pacientes()
    try:
        escolha = int(input("Escolha o número do paciente que deseja acessar: "))
        arquivos = os.listdir(registos_dir)
        registo_path = os.path.join(registos_dir, arquivos[escolha - 1])
        with open(registo_path, "r") as f:
            reader = csv.reader(f)
            linhas = list(reader) 
            print("\n--- Dados Gerais do Paciente ---")
            dados_gerais = linhas[1]
            print(f"Nome: {dados_gerais[0]}")
            print(f"Data de Nascimento: {dados_gerais[1]}")
            print(f"Idade: {dados_gerais[2]} anos")
            print(f"Peso: {dados_gerais[3]} kg")
            print(f"Altura: {dados_gerais[4]} cm")
            print(f"Data e Hora do Registro: {dados_gerais[5]}")
            print("\n--- Sinais Vitais Registados ---")
            sinais_vitais = linhas[4:]
            for sinal in sinais_vitais:
                if sinal and len(sinal) == 3:
                    print(f"{sinal[0]}: Desvio Padrão = {sinal[1]}, Dentro do Normal = {sinal[2]}")
            for sinal in sinais_vitais:
                if sinal and len(sinal) == 3:
                    tipo, dp, dentro_normal = sinal
                    try:
                        dp = float(dp) if dp != "None" else None
                        if dp is not None:
                            plt.figure()
                            plt.title(f"{tipo} - Desvio Padrão")
                            plt.axhline(valores_normais[tipo][0], color="green", linestyle="--", label="Limite Inferior")
                            plt.axhline(valores_normais[tipo][1], color="red", linestyle="--", label="Limite Superior")
                            plt.bar([tipo], [dp], color="blue", label="Valor Calculado")
                            plt.legend()
                            plt.show()
                        else:
                            print(f"Dados insuficientes para gerar gráfico de {tipo}.")
                    except ValueError:
                        print(f"Erro ao processar os dados de {tipo}.")
    except (IndexError, ValueError):
        print("Opção inválida. Tente novamente.")

def menu():
    while True:
        print("\n--- Menu Principal ---")
        print("1. Registar Paciente")
        print("2. Listar Pacientes")
        print("3. Acessar Paciente")
        print("4. Sair")
        opcao = input("Escolha uma opção: ")
        if opcao == "1":
            registar_paciente()
        elif opcao == "2":
            listar_pacientes()
        elif opcao == "3":
            acessar_paciente()
        elif opcao == "4":
            print("Saindo...")
            break
        else:
            print("Opção inválida. Tente novamente.")

if __name__ == "__main__":
    menu()

The code allows the vitals to be sent manually (we write every value we got while testing the patient) or through an archive (we already have the values in an txt file and only have to send it) and each patient will have their data in a cvs file

本文标签: