• Nenhum resultado encontrado

14 - Dados Estruturados

N/A
N/A
Protected

Academic year: 2021

Share "14 - Dados Estruturados"

Copied!
29
0
0

Texto

(1)

ICE-B

14 - Dados Estruturados

(2)

1

Dados Estruturados

Resumo

Organizar os dados de forma estruturada

Dicionários:

Estruturas de dados associando chave e valor

Exemplo: calcular massa molecular

Classes (extra):

Criar objectos em Python

(3)

Dados Estruturados

(4)

3

Dados Estruturados

Motivação para estruturar os dados

Se usarmos tuplos ou listas precisamos de

Lembrar onde está cada valor (e.g. Id, sequência)

Procurar o elemento que queremos (e.g.

find)

É mais difícil alterar informação guardada

E.g. passar a ter tuplos (id, organismo, sequência)

O que dava jeito é poder organizar os dados por nome

(5)

Dicionários

Conjuntos não ordenados de chave:valor

Sintaxe: {chave1:valor1,chave2:valor2, ...}

A chave tem de ser um objecto imutável

Número, string, tuplo, por exemplo

O valor pode ser qualquer objecto

A indexação é feita pela chave

In : capitals = {'Paris':'France','Lisbon':'Portugal','London':'United Kingdom' In : capitals['Paris']

Out: 'France'

In : capitals['Lisbon'] Out: 'Portugal'

(6)

5

Dicionários

Conjuntos não ordenados de chave:valor

Podemos acrescentar ou substituir valores atribuindo a uma chave

In : capitals['Madrid']='Spain' In : capitals

Out:

{'Lisbon': 'Portugal',

'London': 'United Kingdom', 'Madrid': 'Spain',

'Paris': 'France'}

(7)

Dicionários

Exemplo: enzimas, da aula anterior

def enzyme_dictionary(file_name):

"""Read enzyme data to dictionary id: recon,cut)""" enzymes = {} lines = open(file_name).readlines() for el in lines: e_id,recon,cut = el.split(';') enzymes[e_id]={'recon':recon,'cut':cut} return enzymes In : enzymes = enzyme_dictionary('enzymes.txt') Out: {'AluI': {'cut': 'AG-CT', 'recon': 'AGCT'},

'BamHI': {'cut': 'G-GATCC\n', 'recon': 'GGATCC'}, 'EcoRI': {'cut': 'G-AATTC\n', 'recon': 'GAATTC'}, ...}

In : enzymes['AluI']['cut'] Out: 'AG-CT'

In : enzymes['TaqI']['recon'] Out: 'TCGA'

(8)

7

Dados Estruturados

(9)

Massa Molecular

Calcular a massa molecular dada a fórmula

In : molecular_mass('CaCO3') # calcium carbonate

Out: 100.08747

In : molecular_mass('CH3COOC6H4COOH') # aspirin

Out: 180.15829200000002

In : molecular_mass('K[PtCl3(C2H4)]') # Zeise's salt

Out: 368.59614600000003

Precisamos de:

Massas atómicas

Algoritmo

(10)

9

Massa Molecular

Ficheiro com massa atómica:

Ficheiro com valores separados por tabs (periodic_table.txt)

atomicNumber symbol name atomicMass 1 H Hydrogen 1.007944 2 He Helium 4.0026022 3 Li Lithium 6.9412 4 Be Beryllium 9.0121823 5 B Boron 10.8117 6 C Carbon 12.01078 7 N Nitrogen 14.00672 ...

(11)

Massa Molecular

Algoritmo

Do ficheiro criar um dicionário com símbolo:massa dos átomos

Da fórmula um dicionário com símbolo:número para cada átomo

Como? Decompor em sub problemas

Procurar a primeira letra maiúscula (e.g. 'CaCO3')

Procurar a letra maiúscula seguinte (ou o fim)

Retirar slice entre ambas (e.g. Ca, C, O3)

Letras dão símbolo, números dão o número de átomos

Se não tem número, o número é 1

Percorrer o dicionário dos átomos da fórmula, somar massa

consultando o dicionáro das massas atómicas

(12)

11

Massa Molecular

Plano do programa

def read_mass(file):

"return dictionary with atom and atomic mass"

def next_upper(formula, index):

"position of next uppercase from index"

def convert(fragment):

"converts a fragment from a formula into dictionary"

def decompose(formula):

"return list of dictionaries with element and amount"

def molecular_mass(formula):

(13)

Massa Molecular

Ler massa atómica do ficheiro para um dicionário

def read_mass(file):

"return dictionary with atom and atomic mass" lines = open(file).readlines()

masses = {}

for line in lines[1:]:

cells = line.split('\t')

masses[cells[1]] = float(cells[3]) return masses

atomicNumber symbol name atomicMass 1 H Hydrogen 1.007944 In : read_mass('periodic_table.txt') Out: {'Ac': 227.0, 'Ag': 107.86822, 'Al': 26.98153868,

(14)

13

Massa Molecular

Encontrar a próxima maiúscula

Usar método isupper das strings

Podíamos usar um while, mas o return no for serve

O segundo return só acontece se chegar ao fim sem encontrar maiúscula

def next_upper(formula, index):

"position of next uppercase from index" for ix in range(index,len(formula)): if formula[ix].isupper(): return ix return len(formula) In : next_upper('CaCO3',2) Out: 2 In : next_upper('CaCO3',1) Out: 2

(15)

Massa Molecular

Converter fragmento num dicionário com dois campos

def convert(fragment):

"converts a fragment from a formula into dictionary" symb='' num='' for c in fragment: if c.isdigit(): num=num+c elif c.isalpha(): symb=symb+c if num=='': number=1 else: number=int(num) return {'symbol':symb,'number':number} In : convert('O3')

Out: {'number': 3, 'symbol': 'O'} In : convert('Ca')

(16)

15

Massa Molecular

Decompor a fórmula química numa lista de dicionários

def decompose(formula):

"return list of dictionaries with element and amount" atoms = [] current = next_upper(formula,0) while current<len(formula): next_el = next_upper(formula,current+1) atoms.append(convert(formula[current:next_el])) current = next_el return atoms In : decompose('CaCO3')

Out: [{'number': 1, 'symbol': 'Ca'}, {'number': 1, 'symbol': 'C'}, {'number': 3, 'symbol': 'O'}] In : decompose('K[PtCl3(C2H4)]') Out: [{'number': 1, 'symbol': 'K'}, {'number': 1, 'symbol': 'Pt'}, {'number': 3, 'symbol': 'Cl'}, {'number': 2, 'symbol': 'C'}, {'number': 4, 'symbol': 'H'}]

(17)

Massa Molecular

Função final, junta tudo

MASS_FILE='periodic_table.txt' ...

def molecular_mass(formula): "return molecular mass"

masses = read_mass(MASS_FILE) parts = decompose(formula) mass = 0

for p in parts:

mass = mass + p['number']*masses[p['symbol']] return mass

In : molecular_mass('CaCO3') Out: 100.08747

In : molecular_mass('CH3COOC6H4COOH') Out: 180.15829200000002

(18)

17

Massa Molecular

Problema adicional: processar ficheiro

Temos um ficheiro com fórmulas:

CaCO3

CH3COOC6H4COOH K[PtCl3(C2H4)] CH3COOH

C6H9N3O2

Queremos uma tabela com fórmulas e massas, separadas por ;

CaCO3;100.09

CH3COOC6H4COOH;180.16 K[PtCl3(C2H4)];368.60 CH3COOH;60.05

(19)

Massa Molecular

Problema adicional: processar ficheiro

def mass_table(in_file,out_file):

"""writes to out_file table with molecular masses from in_file""" formulas = open(in_file).readlines()

ofil = open(out_file,'w') for formula in formulas:

mass = molecular_mass(formula) ofil.write('{0};{1:.2f}\n'.format(formula.strip(),mass)) ofil.close() In : mass_table('formulas.txt','mass_table.txt') CaCO3 CH3COOC6H4COOH K[PtCl3(C2H4)] CH3COOH C6H9N3O2 CaCO3;100.09 CH3COOC6H4COOH;180.16 K[PtCl3(C2H4)];368.60 CH3COOH;60.05 C6H9N3O2;155.16

(20)

19

Ficheiros

(21)

Classes

Uma class é uma "fábrica" de objectos

Permite-nos criar os objectos que quisermos

Pontos importantes:

Todos os objectos de uma classe partilham os atributos e métodos da classe

Os métodos recebem o objecto como primeiro argumento

O método __init__ serve para inicializar o objecto

Vamos ver um exemplo:

class Element:

def __init__(self,at_number,symbol,name,mass): "initialize element"

self.at_number = at_number self.symbol = symbol

(22)

21

Classes

Exemplo: uma classe para elementos químicos

class Element:

def __init__(self,at_number,symbol,name,mass): "initialize element"

self.at_number = at_number self.symbol = symbol

self.name = name self.mass = mass

Cada objecto fica com os atributos dados pelo __init__

In : h=Element(1,'H','Hydrogen',1) In : h.name Out: 'Hydrogen' In : h.symbol Out: 'H' In : h.at_number Out: 1 In : h.mass Out: 1 In : he=Element(2,'He','Helium',4) In : he.name Out: 'Helium' In : he.symbol Out: 'He' In : he.at_number Out: 2 In : he.mass Out: 4

(23)

Classes

Vamos ler a tabela periódica toda,

Um dicionário de Element, com o símbolo como chave

def read_elements(file):

"return dictionary with elements by symbol" lines = open(file).readlines()

elements = {}

for line in lines[1:]:

at_n,symb,name,mass = line.split('\t') elements[symb] = Element(int(at_n),symb,name,float(mass)) return elements In : elements = read_elements('periodic_table.txt') In : elements['Ar'].mass Out: 39.9481 In : elements['Pb'].at_number Out: 82 In : elements['Ca'].name Out: 'Calcium'

(24)

23

Classes

Configuração electrónica

Vamos criar um método mas, primeiro, precisamos de alguns

dados

Estes vão ser partilhados por todos os objectos Element

Por isso ficam na classe, e não no

__init__

class Element: orbitals = ['1s', '2s', '2p', '3s', '3p', '4s', '3d', '4p', '5s', '4d', '5p', '6s', '4f', '5d', '6p', '7s', '5f', '6d', '7p', '8s'] capacity = {'s':2,'p':6,'d':10,'f':14}

def __init__(self,at_number,symbol,name,mass): "initialize atom"

self.at_number = at_number ...

(25)

Classes

Agora criamos o método

Recebe o objecto como argumento, mas implícito

Os atributos

orbitals e capacity são iguais para todos os Element porque

estão definidos na classe

class Element: ...

def el_configuration(self):

"return electronic configuration as string" electrons = self.at_number orbital = 0 configuration = '' while electrons>0: current = self.orbitals[orbital] full = self.capacity[current[-1]] place_els = min(electrons, full) electrons = electrons - place_els

configuration = configuration + current + str(place_els) + ' ' orbital = orbital +1

(26)

25

Classes

Agora criamos o método

Recebe o objecto como argumento, mas implícito

Os atributos

orbitals e capacity são iguais para todos os Element porque

estão definidos na classe

In : elements['Ca'].orbitals Out: ['1s', '2s', '2p', '3s', '3p', '4s', '3d', '4p', '5s',...] In : elements['U'].capacity Out: {'d': 10, 'f': 14, 'p': 6, 's': 2} In : elements['Ca'].el_configuration() Out: '1s2 2s2 2p6 3s2 3p6 4s2 ' In : elements['U'].el_configuration() Out: '1s2 2s2 2p6 3s2 3p6 4s2 3d10 4p6 5s2 4d10 5p6 6s2 4f14 5d10 6p6 7s2 5f4 ' In : elements['Ar'].el_configuration() Out: '1s2 2s2 2p6 3s2 3p6 '

(27)

Dados Estruturados

(28)

27

Resumo

Dados Estruturados

Como organizar informação quando temos vários valores

Podemos usar tuplos e listas, mas é preciso fixar a posição

Dicionários tornam eficiente encontrar o que precisamos

E podemos usar as chaves para os atributos

Ou então podemos criar objectos

Leitura adicional:

Recomendada: Capítulo 14 dos apontamentos

Livro: capítulo 7 (strings, format) e 8 (listas e dicionários)

(29)

Referências

Documentos relacionados