PL2023/TPC1/main.py

159 lines
5 KiB
Python

#TPC1: Análise de dados: doença cardíaca
#
#Descarregue o ficheiro de dados: myheart.csv Crie um programa em Python, conjunto de funções, que responda às seguintes questões:
#
# Crie uma função que lê a informação do ficheiro para um modelo, previamente pensado em memória;
# Pense num modelo para guardar uma distribuição;
# Crie uma função que calcula a distribuição da doença por sexo;
# Crie uma função que calcula a distribuição da doença por escalões etários. Considere os seguintes escalões: [30-34], [35-39], [40-44], ...
# Crie uma função que calcula a distribuição da doença por níveis de colesterol. Considere um nível igual a um intervalo de 10 unidades, comece no limite inferior e crie os níveis necessários até abranger o limite superior;
# Crie uma função que imprime na forma de uma tabela uma distribuição;
# Especifique um programa que ao executar apresenta as tabelas correspondentes às distribuições pedidas;
# Extra: explore o módulo matplotlib e crie gráficos para as suas distribuições.
from dataclasses import dataclass
from sys import argv
from typing import Dict
import matplotlib.pyplot as plt
@dataclass
class Person:
idade: int
sexo: str
tensao: int
colesterol: int
batimento: int
temDoenca: bool
@dataclass
class People:
value: list[Person]
@dataclass
class Distribution:
count: int
total: int
def add_count(self,value:int):
self.count += value
self.total += 1
def get_percentage(self) -> float:
return self.count/self.total
@dataclass
class DistributionTracker:
distributions: Dict
def add_value(self, key, value: int):
if key not in self.distributions:
self.distributions[key] = Distribution(count=value, total=1)
else:
self.distributions[key].add_count(value)
def get_percentages(self) -> Dict[str,float]:
percentages = {}
for key,val in self.distributions.items():
percentages[key] = val.get_percentage()
return percentages
def print_distribution_tracker(self):
# Print table header
header = f"{'Key':<20} {'Count':<10} {'Total':<10} {'Percentage':<10}"
print(header)
print("-" * len(header))
# Print table rows
for key, distribution in self.distributions.items():
if isinstance(key, tuple):
key_str = f"{key[0]}-{key[1]}"
else:
key_str = str(key)
count = distribution.count
total = distribution.total
percentage = distribution.get_percentage() * 100
print(f"{key_str:<20} {count:<10} {total:<10} {percentage:.2f} %")
def plot_distribution(self):
#TODO
return 0
def read(path:str,people:People):
file = open(path, 'r')
lines = file.readlines()
for line in lines[1:]:
field_list = line.split(',')
idade = int(field_list[0])
sexo = field_list[1]
tensao = int(field_list[2])
colesterol = int(field_list[3])
batimento = int(field_list[4])
temDoenca = bool(int(field_list[5]))
people.value.append(Person(idade,sexo,tensao,colesterol,batimento,temDoenca))
def distribution_doenca_sexo(people,doenca_sexo:DistributionTracker):
for person in people.value:
if person.temDoenca:
doenca_sexo.add_value(person.sexo,1)
else:
doenca_sexo.add_value(person.sexo,0)
def distribution_doenca_escaloes_etarios(people,doenca_idade:DistributionTracker):
#Considere os seguintes escalões: [30-34], [35-39], [40-44], ...
interval_size = 5
for person in people.value:
index = person.idade // interval_size
start = index * interval_size
end = start + interval_size - 1
key = (start,end)
if person.temDoenca:
doenca_idade.add_value(key,1)
else:
doenca_idade.add_value(key,0)
def distribution_doenca_colesterol(people,doenca_colesterol:DistributionTracker):
interval_size = 10
for person in people.value:
index = person.colesterol // interval_size
start = index * interval_size
end = start + interval_size - 1
key = f"{start}-{end}"
if person.temDoenca:
doenca_colesterol.add_value(key,1)
else:
doenca_colesterol.add_value(key,0)
def main():
people = People([])
read(argv[1],people)
doenca_sexo = DistributionTracker({})
doenca_idade = DistributionTracker({})
doenca_colesterol = DistributionTracker({})
distribution_doenca_sexo(people,doenca_sexo)
distribution_doenca_escaloes_etarios(people,doenca_idade)
distribution_doenca_colesterol(people,doenca_colesterol)
doenca_sexo.print_distribution_tracker()
print("\n")
doenca_idade.print_distribution_tracker()
print("\n")
doenca_colesterol.print_distribution_tracker()
print("\n")
if __name__ == "__main__":
main()