ICE-B ICE-B ICE-B ICE-BICE-BICE-B ICE-B ICE-BICE-BICE-B ICE-B ICE-BICE-BICE-B ICE-B
ICE-BICE-B
4 - Implementação
4 - Implementação
4 - Implementação
4 - Implementação
4 - Implementação
4 - Implementação
4 - Implementação
4 - Implementação
4 - Implementação
4 - Implementação
4 - Implementação
4 - Implementação
4 - Implementação
4 - Implementação
4 - Implementação
4 - Implementação
4 - Implementação
Implementação Implementação Implementação ImplementaçãoImplementaçãoImplementação Implementação ImplementaçãoImplementaçãoImplementação Implementação ImplementaçãoImplementaçãoImplementação Implementação
ImplementaçãoImplementação
Resumo
■ Exemplo: cálculo de pH, agora estruturado
■ Testes unitários
■ Ciclo de vida de um programa
Implementação Implementação Implementação ImplementaçãoImplementaçãoImplementação Implementação ImplementaçãoImplementaçãoImplementação Implementação ImplementaçãoImplementaçãoImplementação Implementação
ImplementaçãoImplementação
Exemplo:Calcular pH
Exemplo:Calcular pH
Exemplo:Calcular pH
Exemplo:Calcular pH
Exemplo:Calcular pH
Exemplo:Calcular pH
Exemplo:Calcular pH
Exemplo:Calcular pH
Exemplo:Calcular pH
Exemplo:Calcular pH
Exemplo:Calcular pH
Exemplo:Calcular pH
Exemplo:Calcular pH
Exemplo:Calcular pH
Exemplo:Calcular pH
Calcular pH Calcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pH
Solução de ácido benzóico
C H COOH H + C H COO6 5 ⇔ + 6 5 −
■ Constante de dissociação,
■ Ignorando auto-dissociação da água:
■ Resolvemos equação quadrática,
• (só precisamos da solução positiva)
■ Depois calculamos o pH: = 6.5 × Ka 10−5 = = ⇔ + x − = 0 Ka [H ][ CO ] + C 6H5 O− [C6H5COOH] x2 − x Ci x 2 K a CiKa x = −b±√2ab2−4ac pH = −lo ([g10 H+]) = −lo (x)g10
Calcular pH Calcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pH
Compreender, generalizar e decompor
■ Generalização: Calcular o pH de um ácido fraco monoprótico
■ Decomposição: Obter a raíz positiva e calcular o pH
■ Criamos ficheiro phcalc.py com o "esqueleto" do programa
# coding: utf-8
-*-"""
Computes pH of an acid from concentration """
def positive_root(a, b, c):
"return positive root of quadratic equation"
def compute_pH(Ka, Ci):
"""
return pH value for weak acid from
dissociation constant and initial concentration """
Calcular pH Calcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pH
"Esqueleto" do programa
■ É uma boa ideia fazer primeiro um esboço do programa
• Permite ver se encaixa tudo e se é preciso decompor mais
■ Estas funções ainda não fazem nada mas este código já cria os objectos.
def positive_root(a, b, c):
"return positive root of quadratic equation"
■ A string logo a seguir à assinatura é a documentação
• Podem usar ''' ou """ se o texto ocupar várias linhas
In : help(positive_root)
Help on function positive_root in module __main__: positive_root(a, b, c)
Calcular pH Calcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pH
Documentação do módulo
■ A string no início do módulo é útil como documentação
# coding: utf-8
-*-"""
Computes pH of an acid from concentration """
■ Depois de executar com F5, podemos importá-lo e pedir ajuda
• (F5 para gravar e mudar de pasta)
In : import phcalc In : help(phcalc)
Help on module phcalc: NAME
phcalc - Computes pH of an acid from concentration FUNCTIONS
compute_pH(Ka, Ci)
Calcular pH Calcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pH
Implementar as funções
■ Depois de perceber os objectivos e o algoritmo e de decompor em tarefas podemos implementar cada função
■ Devemos começar pelas "pontas", aquelas que não dependem de nenhuma outra que tenhamos de implementar
def positive_root(a, b, c):
"return positive root of quadratic equation" root = (-b + (b**2 - 4*a*c)**0.5)/(2*a)
return root
■ Depois devemos testar:
In : positive_root(1,0,-1) #x**2 + 0x - 1
Out: 1.0
In : positive_root(1,-2,0) #x**2 - 2x + 0
Calcular pH Calcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pH
Implementar as funções
■ Depois de implementar e testar uma função podemos passar a outra que dependa desta
■ Como o cálculo do pH precisa do logaritmo, temos de importar log10
• É melhor fazer todos os import no início do módulo
# coding: utf-8
-*-"""
Computes pH of an acid from concentration """
from numpy import log10
def positive_root(a, b, c):
...
def compute_pH(Ka, Ci):
Calcular pH Calcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pHCalcular pH Calcular pH Calcular pHCalcular pH
Implementar as funções
■ Agora implementamos e testamos esta também
def compute_pH(Ka, Ci):
"""
return pH value for weak acid from
dissociation constant and initial concentration """
H = positive_root(1, Ka, -Ka*Ci) return -log10(H)
■ Testar com valores que permitam confirmar o resultado:
In : compute_pH(6.5e-5,0.01) Out: 3.11104555393015
Testes Unitários Testes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes Unitários
Testar sempre cada função
■ Decompomos um problema complexo em problemas mais simples.
■ Mas depois vai ser preciso juntar tudo.
• Um erro descoberto só no final é mais difícil de encontrar e corrigir.
■ É preciso testar:
• Sempre que implementamos algo de novo.
• Sempre que corrigimos um erro, para confirmar.
Testes Unitários Testes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes Unitários
Sugestão: automatizar os testes todos
■ Opção 1: uma função no final do nosso módulo
• Numa função para não correr os testes sempre que usamos o módulo
...
def tests():
"""
run unit tests on all functions """
print("positive_root, 1.0:", positive_root(1,0,-1)) print("positive_root, 2.0:",positive_root(1,-2,0)) print("compute_pH, 3.111:",compute_pH(6.5e-5,0.01))
■ É importante que se possa verificar o resultado também
In : tests()
positive_root, 1.0: 1.0
positive_root, 2.0: 2.0
Testes Unitários Testes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes Unitários
Sugestão: automatizar os testes todos
■ Opção 2: um módulo só para testes (phtests.py)
# coding: utf-8
-*-"""
run unit tests on all functions in phcalc """
from phcalc import positive_root, compute_pH
print("positive_root, 1.0:", positive_root(1,0,-1)) print("positive_root, 2.0:",positive_root(1,-2,0)) print("compute_pH, 3.111:",compute_pH(6.5e-5,0.01))
■ Basta correr com F5
• Neste caso não é preciso função porque o módulo é só para testes
In : runfile('/pasta/phtests.py', wdir='/pasta') positive_root, 1.0: 1.0
Testes Unitários Testes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes Unitários
Atenção: funções são criadas na execução do def...
def tests():
"""
run unit tests on all functions """
print("positive_root, 1.0:", positive_root(1,0,-1)) print("positive_root, 2.0:",positive_root(1,-2,0)) print("compute_pH, 3.111:",compute_pH(6.5e-5,0.01))
■ Sempre que alterarem alguma coisa no vosso programa precisam de criar novamente os objectos das funções alteradas
■ Para isso o interpretador tem de reler a assinatura da função e toda a "receita" no corpo da função
■ A forma mais prática de fazer isso no Spyder é F5
• (Grava e corre todo o ficheiro)
Testes Unitários Testes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes Unitários
Atenção: funções são executadas só em nome( ... )
In : tests()
positive_root, 1.0: 1.0
positive_root, 2.0: 2.0
compute_pH, 3.111: 3.11104555393
■ Quando se corre módulo as funções são criadas mas não usadas
■ A menos que o módulo inclua também chamadas às funções
# coding: utf-8
-*-...
def tests():
print("positive_root, 1.0:", positive_root(1,0,-1)) print("positive_root, 2.0:",positive_root(1,-2,0)) print("compute_pH, 3.111:",compute_pH(6.5e-5,0.01)) tests()
Testes Unitários Testes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes UnitáriosTestes Unitários Testes Unitários Testes UnitáriosTestes Unitários
Atenção: função só devolve valor em return
# coding: utf-8
-*-...
def tests():
print("positive_root, 1.0:", positive_root(1,0,-1)) print("positive_root, 2.0:",positive_root(1,-2,0)) print("compute_pH, 3.111:",compute_pH(6.5e-5,0.01))
In : tests()
positive_root, 1.0: 1.0
positive_root, 2.0: 2.0
compute_pH, 3.111: 3.11104555393
■ O print escreve na consola mas a função tests() não devolveu valor (devolveu None).
Programação Estruturada Programação Estruturada Programação Estruturada Programação EstruturadaProgramação EstruturadaProgramação Estruturada Programação Estruturada Programação EstruturadaProgramação EstruturadaProgramação Estruturada Programação Estruturada Programação EstruturadaProgramação EstruturadaProgramação Estruturada Programação Estruturada
Programação EstruturadaProgramação Estruturada
Erros
Erros
Erros
Erros
Erros
Erros
Erros
Erros
Erros
Erros
Erros
Erros
Erros
Erros
Erros
Erros Erros Erros ErrosErrosErros Erros ErrosErrosErros Erros ErrosErrosErros Erros ErrosErros
Erro de sintaxe
■ Erro na escrita do código que impede o interpretador de o executar
• Este é o mais fácil de corrigir, porque sabemos logo que o cometemos
In : 6 * * 2
6 * * 2
^
SyntaxError: invalid syntax In : 8 + 5.3.2
8 + 5.3.2
^
SyntaxError: invalid syntax
■ Spyder analisa o código conforme o escrevemos e assinala a linha com o erro
Erros Erros Erros ErrosErrosErros Erros ErrosErrosErros Erros ErrosErrosErros Erros ErrosErros
Erro de execução (Exception)
■ O interpretador sabe o que deve fazer mas não consegue fazê-lo
• Estes erros só ocorrem durante a execução e podem ser mais difíceis de diagnosticar porque o erro pode estar noutra parte do código
In : y = z*2
y = z*2
NameError: name 'z' is not defined In : y = 0
In : z = 1 / y z = 1 / y
Erros Erros Erros ErrosErrosErros Erros ErrosErrosErros Erros ErrosErrosErros Erros ErrosErros
Erro lógico
■ O programa corre sem problemas mas não dá o resultado certo
• Estes erros tendem a ser os mais difíceis de corrigir
■ Exemplo: pH negativo?
def positive_root(a, b, c):
root = (-b + (b**2 - 4*a*c)**0.5)/(2*a) return root
def compute_pH(Ka, Ci):
H = positive_root(1, Ka, -Ka*Ci) return log10(H)
In : compute_pH(6.5e-5,0.01) Out: -3.11104555393015
Erros Erros Erros ErrosErrosErros Erros ErrosErrosErros Erros ErrosErrosErros Erros ErrosErros
Erro numérico
■ Devido à representação finita de números fraccionários, em 64 bits
• (Inteiros em Python 3.x usam o número de bits que for necessário)
• Obriga a arredondamentos e pode ser importante se o cálculo for iterado
In : (2**0.5)**2
Out: 2.0000000000000004
■ Representação de números fraccionários em 64 bits:
• 1 bit para sinal, 11 para expoente (base 2) e 52 para fracção
Erros Erros Erros ErrosErrosErros Erros ErrosErrosErros Erros ErrosErrosErros Erros ErrosErros
Erro numérico
■ Informação sobre a representação em 64 bits
In : import numpy In : info = numpy.finfo(float) In : info.bits Out: 64 In : info.eps Out: 2.2204460492503131e-16 In : info.tiny Out: 2.2250738585072014e-308 In : info.min Out: -1.7976931348623157e+308 In : info.max Out: 1.7976931348623157e+308 Informação:
Número de bits na representação Menor valor que somado a 1 dá >1
In : 1+info.eps-1
Out: 2.2204460492503131e-16
In : 1+0.5*info.eps-1
Out: 0.0
Mais pequeno com plena precisão
Menor valor representável
Programação Estruturada Programação Estruturada Programação Estruturada Programação EstruturadaProgramação EstruturadaProgramação Estruturada Programação Estruturada Programação EstruturadaProgramação EstruturadaProgramação Estruturada Programação Estruturada Programação EstruturadaProgramação EstruturadaProgramação Estruturada Programação Estruturada
Programação EstruturadaProgramação Estruturada
Código Fonte
Código Fonte
Código Fonte
Código Fonte
Código Fonte
Código Fonte
Código Fonte
Código Fonte
Código Fonte
Código Fonte
Código Fonte
Código Fonte
Código Fonte
Código Fonte
Código Fonte
Ciclo de vida Ciclo de vida Ciclo de vida Ciclo de vidaCiclo de vidaCiclo de vida Ciclo de vida Ciclo de vidaCiclo de vidaCiclo de vida Ciclo de vida Ciclo de vidaCiclo de vidaCiclo de vida Ciclo de vida Ciclo de vidaCiclo de vida
Ciclo de vida de um programa
■ Edição do código fonte
• Escrito, guardado em ficheiros .py
■ Interpretação do código fonte
• O interpretador traduz as instruções em instruções para o CPU
■ Execução
• O CPU executa o programa
■ Testar e avaliar o resultado
Ciclo de vida Ciclo de vida Ciclo de vida Ciclo de vidaCiclo de vidaCiclo de vida Ciclo de vida Ciclo de vidaCiclo de vidaCiclo de vida Ciclo de vida Ciclo de vidaCiclo de vidaCiclo de vida Ciclo de vida Ciclo de vidaCiclo de vida
Ciclo de vida de um programa, exemplo
■ Concebemos, implementámos e testámos o cálculo do pH
• A partir da concentração inicial e da constante de dissociação
Agora temos um novo problema
■ Qual o pH de 0.01g de ácido benzóico em 0.250 dm ?
• Calcular pH a partir da massa, volume e massa molecular
• Basta calcular a concentração e usar o que já temos
■ Solução: acrescentamos uma nova função
• Pensamos no algoritmo: calcular concentração
• Decompomos se necessário (não é; é simples)
• Implementamos e testamos
Ciclo de vida Ciclo de vida Ciclo de vida Ciclo de vidaCiclo de vidaCiclo de vida Ciclo de vida Ciclo de vidaCiclo de vidaCiclo de vida Ciclo de vida Ciclo de vidaCiclo de vidaCiclo de vida Ciclo de vida Ciclo de vidaCiclo de vida
Novo problema:
■ Qual o pH de 0.01g de ácido benzóico em 0.250 dm ?3
Solução:
■ Já temos praticamente tudo feito
■ Basta uma função que calcule a concentração
• Precisa da massa, massa molar e volume
■ E depois chamar a anterior com concentração e Ka
def compute_pH_mass(mass, mol_mass, volume, Ka):
"""
return pH value of a weak acid solution from mass of solute and volume of solution
"""
Ci = mass / mol_mass / volume return compute_pH(Ka,Ci)
Ciclo de vida Ciclo de vida Ciclo de vida Ciclo de vidaCiclo de vidaCiclo de vida Ciclo de vida Ciclo de vidaCiclo de vidaCiclo de vida Ciclo de vida Ciclo de vidaCiclo de vidaCiclo de vida Ciclo de vida Ciclo de vidaCiclo de vida
■ Uma maneira prática é acrescentar ao módulo phcalc
# coding: utf-8
-*-"""
Computes pH of an acid from concentration """
from numpy import log10
def positive_root(a, b, c):
...
def compute_pH(Ka, Ci):
...
def compute_pH_mass(mass, mol_mass, volume, Ka):
"""
return pH value of a weak acid solution from mass of solute and volume of solution
"""
Ci = mass / mol_mass / volume return compute_pH(Ka,Ci)
Ciclo de vida Ciclo de vida Ciclo de vida Ciclo de vidaCiclo de vidaCiclo de vida Ciclo de vida Ciclo de vidaCiclo de vidaCiclo de vida Ciclo de vida Ciclo de vidaCiclo de vidaCiclo de vida Ciclo de vida Ciclo de vidaCiclo de vida
Ciclo de vida de um programa, exemplo
■ Calcular o pH a partir da massa, volume e massa molecular:
def compute_pH_mass(mass, mol_mass, volume, Ka):
"""
return pH value of a weak acid solution from mass of solute and volume of solution
"""
Ci = mass / mol_mass / volume return compute_pH(Ka,Ci)
■ Testes:
def tests():
...
print("compute_pH, 3.111:",compute_pH(6.5e-5,0.01))
print("compute_pH_mass, 3.1111",compute_pH_mass(1.221, 122.1, 1, 6.5e-5)) print("compute_pH_mass, 3.000",compute_pH_mass(0.5, 122.1, 0.25, 6.5e-5))
Implementação Implementação Implementação ImplementaçãoImplementaçãoImplementação Implementação ImplementaçãoImplementaçãoImplementação Implementação ImplementaçãoImplementaçãoImplementação Implementação
ImplementaçãoImplementação
Estilo de Código
Estilo de Código
Estilo de Código
Estilo de Código
Estilo de Código
Estilo de Código
Estilo de Código
Estilo de Código
Estilo de Código
Estilo de Código
Estilo de Código
Estilo de Código
Estilo de Código
Estilo de Código
Estilo de Código
Estilo de Código Estilo de Código Estilo de Código Estilo de CódigoEstilo de CódigoEstilo de Código Estilo de Código Estilo de CódigoEstilo de CódigoEstilo de Código Estilo de Código Estilo de CódigoEstilo de CódigoEstilo de Código Estilo de Código Estilo de CódigoEstilo de Código
É importante escrever código legivel
■ Porque o código fonte serve:
• Para o interpretador executar
• Para humanos lerem
■ Código difícil de compreender
• É mais propenso a erros
• É mais difícil de corrigir, adaptar e melhorar
Estilo de Código Estilo de Código Estilo de Código Estilo de CódigoEstilo de CódigoEstilo de Código Estilo de Código Estilo de CódigoEstilo de CódigoEstilo de Código Estilo de Código Estilo de CódigoEstilo de CódigoEstilo de Código Estilo de Código Estilo de CódigoEstilo de Código
Nomes de variáveis
■ As variáveis devem ter nomes descritivos
• E.g. mass, mol_mass, volume
def compute_pH_mass(mass, mol_mass, volume, Ka):
Ci = mass / mol_mass / volume return compute_pH(Ka,Ci)
■ Excepto quando têm nomes convencionais
• E.g. a, b, c, Ci, pH, Ka
def positive_root(a, b, c):
root = (-b + (b**2 - 4*a*c)**0.5)/(2*a) return root
Estilo de Código Estilo de Código Estilo de Código Estilo de CódigoEstilo de CódigoEstilo de Código Estilo de Código Estilo de CódigoEstilo de CódigoEstilo de Código Estilo de Código Estilo de CódigoEstilo de CódigoEstilo de Código Estilo de Código Estilo de CódigoEstilo de Código
Nomes de funções
■ Devem descrever o que a função faz
■ Nomes compostos por várias palavras
• Convenção 1: usar letras maiúsculas e minúsculas phMassVol
• Convenção 2: (mais usado em Python) usar underscore compute_pH_mass
def compute_pH_mass(mass, mol_mass, volume, Ka):
Ci = mass / mol_mass / volume return compute_pH(Ka,Ci)
Estilo de Código Estilo de Código Estilo de Código Estilo de CódigoEstilo de CódigoEstilo de Código Estilo de Código Estilo de CódigoEstilo de CódigoEstilo de Código Estilo de Código Estilo de CódigoEstilo de CódigoEstilo de Código Estilo de Código Estilo de CódigoEstilo de Código
Inteligibilidade
■ Cada linha de código deve corresponder a um passo simples
■ Evitar linhas demasiado longas ou complexas
• Decompor em vários passos para ser mais inteligivel
■ Exemplo: menos claro
def compute_pH_mass(mass, mol_mass, volume, Ka):
return compute_pH(Ka, mass / mol_mass / volume)
■ Exemplo: mais claro
def compute_pH_mass(mass, mol_mass, volume, Ka):
Ci = mass / mol_mass / volume return compute_pH(Ka, Ci)
Estilo de Código Estilo de Código Estilo de Código Estilo de CódigoEstilo de CódigoEstilo de Código Estilo de Código Estilo de CódigoEstilo de CódigoEstilo de Código Estilo de Código Estilo de CódigoEstilo de CódigoEstilo de Código Estilo de Código Estilo de CódigoEstilo de Código
Documentação e comentários
■ Devemos documentar funções (e módulos)
■ Podemos também acrescentar comentários se for preciso
• Notas para o programador
def positive_root(a, b, c):
"return positive root of quadratic equation"
root = (-b + (b**2 - 4*a*c)**0.5)/(2*a) #This assumes a is greater than zero
return root
Mais informação:
■ https://www.python.org/dev/peps/pep-0008/ "PEP 8 -- Style Guide for Python Code"
Programação Estruturada Programação Estruturada Programação Estruturada Programação EstruturadaProgramação EstruturadaProgramação Estruturada Programação Estruturada Programação EstruturadaProgramação EstruturadaProgramação Estruturada Programação Estruturada Programação EstruturadaProgramação EstruturadaProgramação Estruturada Programação Estruturada
Programação EstruturadaProgramação Estruturada
Resumo
Resumo
Resumo
Resumo
Resumo
Resumo
Resumo
Resumo
Resumo
Resumo
Resumo
Resumo
Resumo
Resumo
Resumo
Implementação Implementação Implementação ImplementaçãoImplementaçãoImplementação Implementação ImplementaçãoImplementaçãoImplementação Implementação ImplementaçãoImplementaçãoImplementação Implementação
ImplementaçãoImplementação
Resumo
■ Programação estruturada: funções
■ Testes unitários
■ Tipos de erro: sintaxe, exception, lógicos e numéricos
■ Ciclo de vida e reutilização de código
■ Estilo de código
Leitura adicional:
■ Recomendada: Capítulo 4 dos apontamentos