159 lines
5 KiB
Python
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()
|