98
Informática para Ciências e Engenharias 2013/14 Teórica 2

Informática para Ciências e Engenharias 2013/14iceb.ssdi.di.fct.unl.pt/1314/b/files/ICE-B-T02.pdf · Tipos de ficheiro •todos os ficheiros são sequências de bits •em ficheiros

Embed Size (px)

Citation preview

Informática para Ciências e Engenharias

2013/14

Teórica 2

2

Na aula de hoje...

Decomposição de problemas• Abstracção, generalização e algoritmos

Ficheiros e código fonte• scripts, funções e como escrever código

Testes unitários Ciclo de vida de um programa Tipos de erros. Representação de números em binário.

3

Problema

Calcular pH do ácido benzóico 0.01M

• C6H

5COOH ↔ H+ + C

6H

5COO-

• Ka = 6.5 x 10-5

Como resolver

• sendo x = [H+] = [C6H

5COO- ]

• Ka = x2 / (C

i – x)

• x2 + Ka x – C

i K

a = 0

• pH = - log10

(x)

4

Como implementar, opção 1 Escrever directamente

• Raiz quadrada: sqrt( )

• Logaritmo de base 10: log10( )

octave:22> Ci=0.01Ci = 0.010000octave:23> Ka=6.5e-5Ka = 6.5000e-005octave:24> x=(-Ka+sqrt(Ka^2+4*Ka*Ci))/2x = 7.7438e-004octave:25> pH=-log10(x)pH = 3.1110octave:26>

5

Como implementar, opção 1 Escrever directamente

• Raiz quadrada: sqrt( )

• Logaritmo de base 10: log10( )

octave:22> Ci=0.01Ci = 0.010000octave:23> Ka=6.5e-5Ka = 6.5000e-005octave:24> x=(-Ka+sqrt(Ka^2+4*Ka*Ci))/2x = 7.7438e-004octave:25> pH=-log10(x)pH = 3.1110octave:26>

o valor da concentraçãotem de ser positivo

6

Como implementar, opção 1 Escrever directamente

• Má solução• mais difícil de corrigir erros

• temos de escrever tudo cada vez que precisamos calcular o pH

• só viável com problemas simples

• quanto maior a lista de instruções mais provável é haver erros e mais difícil é de os identificar

• impossível de resolver problemas complexos

7

Como implementar, opção 2 Criar um script

• um script Matlab é um ficheiro contendo código fonte e gravado com a extensão .m

Chamar o script• Escrever o nome do script (sem o .m)

• se não existe variável ou função definida, o interpretador procura o ficheiro nome.m

• tem de estar na pasta de trabalho (ou numa pasta que o interpretador conheça)

8

Ficheiros

Ficheiro• sequência de bits, agrupados em bytes

• 1 byte = 8 bits

• armazenado num suporte persistente• disco rígido, cartão de memória, CD...

• associado pelo SO a um identificador único• caminho e nome

• C:\My Documents\ICE\teste.m

• ~/ICE/teste.m

9

Ficheiros

Tipos de ficheiro• todos os ficheiros são sequências de bits

• em ficheiros de “tipo diferente” a sequência é interpretada de forma diferente

• Muitas vezes o tipo de ficheiro é identificado pela extensão• .pdf, .txt, .jpg, .wav, .doc, .mp3

• associada ao programa que interpreta o ficheiro

• (há excepções, depende do SO e, especialmente, do programa que usamos como interface)

10

Ficheiro de código fonte Na linguagem MATLAB, um ficheiro .m

• É interpretado como texto, código fonte

• Quando o interpretador encontra um identificador verifica

1º se é uma variável definida

2º se é uma função já carregada

3º se há um ficheiro com esse nome e extensão .m

• Se chega ao 3º executa o que está no ficheiro

11

Editar o código fonte

benzoico.m

Memória

Utilizador interage com o editor de texto, grava o código fonte num ficheiro.

12

Executar o código fonte

benzoico.m

Memória

Utilizador dá ao interpretador o comando para executar o código no ficheiro.O interpretador carrega o ficheiro, interpreta-o e dá ao CPU as instruções correspondentes.

13

Como implementar, opção 2 Criar um script

• Notepad ++ (ou equivalente)

• ficheiro benzoico.m

14

Como implementar, opção 2 Criar um script

• Notepad ++ (ou equivalente)

• ficheiro benzoico.mSintaxe é processada pelo editor quando

gravamos o ficheiro com extensão .m

15

Como implementar, opção 2 Criar um script

• Notepad ++ (ou equivalente)

• ficheiro benzoico.mA partir do símbolo % a linha é ignorada.

Podemos assim comentar o código

16

Como implementar, opção 2 Criar um script

• Notepad ++ (ou equivalente)

• ficheiro benzoico.mNumeração das linhas é útil em

caso de erros

17

Como implementar, opção 2 Criar um script

• Notepad ++ (ou equivalente)

• ficheiro benzoico.m

Executaroctave:26> cd 'C:\My Documents\ICE'octave:27> benzoicoCi = 0.010000Ka = 6.5000e-005x = 7.7438e-004pH = 3.1110octave:28>

18

Como implementar, opção 2 Criar um script

• Notepad ++ (ou equivalente)

• ficheiro benzoico.m

Executaroctave:26> cd 'C:\My Documents\ICE'octave:27> benzoicoCi = 0.010000Ka = 6.5000e-005x = 7.7438e-004pH = 3.1110octave:28>

Esta é a pasta onde guardámos o ficheiro.cd para “change directory”. Também pode ser:

cd ('C:\My Documents\ICE')Basta fazer uma vez.

19

Como implementar, opção 2 Criar um script

• Notepad ++ (ou equivalente)

• ficheiro benzoico.m

Executaroctave:26> cd 'C:\My Documents\ICE'octave:27> benzoicoCi = 0.010000Ka = 6.5000e-005x = 7.7438e-004pH = 3.1110octave:28>

Este é o nome do script, sem a extensão.Como não há variáveis ou funções benzoico,o interpretador procura o ficheiro benzoico.m

20

Como implementar, opção 2 Criar um script

• Notepad ++ (ou equivalente)

• ficheiro benzoico.m

Executaroctave:26> cd 'C:\My Documents\ICE'octave:27> benzoicoCi = 0.010000Ka = 6.5000e-005x = 7.7438e-004pH = 3.1110octave:28>

Isto é o eco dos cálculos no script.Se não quisermos ver estes resultados parciais

podemos acrescentar ; às linhas.

21

Como implementar, opção 2 Testar

octave:28> benzoicopH = 3.1110octave:29>

benzoico.m

22

Como implementar, opção 2 Criar um script

• Vantagens• mais fácil de executar e de editar

• comentários (mais inteligível)

• fica guardado

• Problemas• fica tudo junto

• variáveis comuns a todo o programa

• diferentes tarefas não são separadas

• não estruturado e mau para problemas complexos

23

Programação Estruturada

24

Programação estruturada

Decompor o problema em partes autónomas (dividir para conquistar)• perceber o problema e todas as tarefas

• abstrair e generalizar cada tarefa

Conceber o algoritmo• perceber como resolver cada tarefa

• perceber como as várias partes encaixam

Implementar e testar cada parte

25

Abstracção e generalização

Calcular pH do ácido benzóico• mas podia ser de outro ácido.

Variáveis

• Ka C

i

Passos semelhantes• Fórmula resolvente para obter x

• Calcular logaritmo de base 10 para pH

26

Algoritmo

Muhammad ibn Mūsā al-Khwārizmī “Compêndio do Cálculo por Completude

e Balanço.” “Cálculo com Numerais Hindu” Algoritmi de numero Indorum (sec. XII)

• Algoritmo

• Algarismo

http://en.wikipedia.org/wiki/Muhammad_ibn_Mūsā_al-Khwārizmī

27

Algoritmo

Conjunto finito de instruções. No sentido estrito, operações sobre

símbolos (matemática, lógica, programas)

No sentido lato: receitas, procedimentos de emergência, etc...

http://en.wikipedia.org/wiki/Algorithm

28

«Algoritmo» da torrada Pegar no pão Se faca na bancada,

• Pegar na faca Caso contrário

• Ir buscar faca à gaveta Cortar fatia, pôr na torradeira, ligar Enquanto não está pronta

• Esperar

29

Implementação estruturada Pegar no pão Se faca na bancada,

• Pegar na faca Caso contrário

• Ir buscar faca à gaveta Cortar fatia, pôr na torradeira, ligar Enquanto não está pronta

• Esperar

30

Implementação estruturada

Pegar no pão Encontrar faca Cortar fatia Pôr na torradeira, ligar Enquanto não está pronta

• Esperar

Se faca na bancada, Pegar na faca

Caso contrárioIr buscar à gaveta

31

Implementação estruturada

Pegar no pão Encontrar faca Cortar fatia Pôr na torradeira, ligar Enquanto não está pronta

• Esperar

32

Implementação estruturada

Pegar no pão Encontrar faca Cortar fatia Torrar pão

33

Programação estruturada

Resolver problemas complexos um problema simples de cada vez

Hierarquizar os problemas• Abstrair dos detalhes concretos

• Generalizar soluções

• Decompor as tarefas e implementar partes• Testar cada uma

• Juntar tudo no programa final

34

Funções

Entre function e end• As variáveis são locais e estão isoladas

• mesmo que tenham o mesmo nome

Função no ficheiro igualdois.m:

function igualdois a=2end

octave:13> a=4a = 4octave:14> igualdoisa = 2octave:15> aa = 4

A variável a dentro da função é independente da variável a fora da função.

35

Funções

Entre function e end• As variáveis são locais e estão isoladas

Função no ficheiro igualdois.m:

function igualdois a=2end

octave:3> clear aoctave:4> igualdoisa = 2octave:5> aerror: `a' undefined near line 5

column 1octave:5>

A variável a dentro da função só está acessível na função (dentro do seu contexto).

igualdois.m

36

Funções

Dentro do bloco function e end• As variáveis são locais e estão isoladas

• Não há acesso a variáveis exteriores

Permite estruturar o programa … • separar tarefas sem interferência

• controlar entrada e saída

• garantir que cada parte funciona

… e resolver problemas complexos

37

Funções

Normalmente queremos• fornecer valores (argumentos) à função

• obter valores da função.

(no soma.m)

function res=soma(a,b) res=a+bend

octave:16> soma(2,5)res = 7ans = 7octave:17>

38

Funções

function res=soma(a,b)

res=a+b

endAssinatura da função

39

Funções

function res=soma(a,b)

res=a+b

endNome da variável (na função) com o valor a devolver.

Operacionalmente: quando chega ao end final, o interpretador devolve uma cópia do valor guardado na variável indicada aqui.

40

Funções

function res=soma(a,b)

res=a+b

endNome da função.

Para o interpretador encontrar a função o nome da função tem de ser igual ao nome do ficheiro com o código fonte:

soma.m

41

Funções

function res=soma(a,b)

res=a+b

endParâmetros da função: variáveis que recebem os argumentos, cujo valor se desconhece na implementação mas é necessário à execução.e.g:soma(5,10)

Parâmetros: a, bArgumentos: 5, 10

42

Funções

function res=soma(a,b)

res=a+b

end

Os parâmetros a e b contêm cópias dos argumentos fornecidos à função.

Estas variáveis a, b e res só existem dentro da função.

43

Funções

function x=incrementa(x)

x=x+1

endx é cópia do valor

octave:17> x=3x = 3octave:18> incrementa(x)x = 4ans = 4octave:19> xx = 3

44

Funções

function res=soma(a,b)

res=a+b

end

Último detalhe:• Não queremos ver res

no cálculo intermédio

octave:16> soma(2,5)res = 7ans = 7octave:17>

45

Funções

function res=soma(a,b)

res=a+b;

end

Último detalhe:• Não queremos ver o res

• ; resolve o problema.

octave:16> soma(2,5)ans = 7octave:17>

46

Funções

Recapitulando:• Os parâmetros da função recebem cópias

dos valores dados como argumentos.

• As variáveis na função estão isoladas• não vêem nem são vistas fora da função.

• Só “sai” da função uma cópia do valor da variável indicada na assinatura da função:

function res=soma(x,y)

47

Funções

Nota:• O interpretador verifica primeiro se há uma

variável com esse nome:octave:21> soma = 0

soma = 0

octave:22> soma(2,5)

error: invalid row index = 2

error: invalid column index = 5

48

Funções

Nota:• O interpretador verifica primeiro se há uma

variável com esse nome.

• Se fosse ao contrário, um novo ficheiro .m podia estragar um programa já existente.

49

Funções

Nota:• A variável (ou variáveis) designada para

guardar o valor devolvido tem de ter um valor atribuído no final da função.

function res=soma(a,b) c=a+b;end

octave:24> a=soma(2,5)error: value on right hand side of assignment is undefinederror: evaluating assignment expression near line 24, column 2

50

De volta ao problema

Calcular pH ácido benzóico 0.01M

• C6H

5COOH ↔ H+ + C

6H

5COO-

• Ka = 6.5 x 10-5

Como resolver

• sendo x = [H+] = [C6H

5COO- ]

• Ka = x2 / (C

i – x)

• x2 + Ka x – C

i K

a = 0

• pH = - log10

(x)

51

Como implementar, opção 3 Compreender totalmente o problema

• dados de entrada

• resultado e saída

52

Como implementar, opção 3 Compreender totalmente o problema Algoritmo

• decompor o problema

• saber como resolver cada parte• Usar fórmula resolvente para obter x

• Calcular -logaritmo de x

53

Como implementar, opção 3 Compreender totalmente o problema Algoritmo Abstrair e generalizar

• pH para quaisquer valores de Ka e C

i

• não é só para o ácido benzóico

• raiz maior de uma equação quadrática com a positivo

• pode ser útil noutros casos

x2 + Ka x – C

i K

a = 0

54

Como implementar, opção 3 Compreender totalmente o problema Algoritmo Abstrair e generalizar Implementação

• Precisamos das assinaturas

function x=raizmaior(a,b,c)• calcula a maior raiz pela fórmula resolvente

function pH=calculaph(Ka,Ci)• calcula o pH usando raizmaior

55

Como implementar, opção 3 Criamos raizmaior.m

• (não sabemos ainda implementar a fórmula resolvente completa)

56

Como implementar, opção 3 Criamos raizmaior.m

Valor que queremos devolver

57

Como implementar, opção 3 Criamos raizmaior.m

Comentário explicando o funcionamentoPode haver comentários noutras partes do código, mas o primeiro bloco contíguo de linhas de comentário, antes ou depois da assinatura da função, é mostrado pela help

58

Documentar a função

octave:10> help raizmaior`raizmaior' is a function from the file C:\ICE\raizmaior.m

calcula a raiz maior do polinomio ax^2+bx+c assumindo o coeficiente a positivo NOTA: nao verifica se ha raiz real

help raizmaior

59

Testar a função

octave:5> raizmaior(1,-4,4)ans = 2

Pensamos num caso com solução conhecida.• x2-4x+4=0 (a=1, b=-4, c=4)

• deve dar x = 2

60

Testar a função

octave:7> raizmaior(1,0,0)ans = 0

Pensamos num caso com solução conhecida.• x2=0 (a=1, b=0, c=0)

• deve dar x = 0

61

Testes unitários

É importante testar cada função individualmente• é mais fácil diagnosticar e corrigir erros se

sabemos onde ocorrem

• depois da função estar implementada e testada já não precisamos pensar nessa parte do problema

62

Testes: quatro tipos de erro

Erro de sintaxe• na interpretação do código fonte

• parênteses, plicas, operadores em falta, …

6 + * 12

y = 2 * (5 + 3 (octave:1> 6 + * 12parse error: syntax error>>> 6 + * 12 ^octave:1>

63

Testes: quatro tipos de erro

Erro de sintaxe Erro de execução

• o programa é interrompido• variável não definida, função não definida, …

y = x+1 (sem ter definido x primeiro)

octave:1> y = x+1error: `x' undefined near line 1 column 5octave:1>

64

Testes: quatro tipos de erro

Erro de sintaxe Erro de execução Erro lógico

• não há mensagem de erro mas o resultado está errado

65

Testes: quatro tipos de erro

Erro de sintaxe Erro de execução Erro lógico Erro numérico

• se resultados das operações aritméticas não são exactos a falta de precisão pode afectar a saída do programa.

octave:10> sin(pi)ans = 1.2246e-016

66

Representação de inteiros

Um número inteiro pode ser representado com uma combinação de bits.• em base 2

• 2 bits, 22 possibilidades 00 01 10 11

• 4 bits, 24 possibilidades 0000 0001 … 1111

• 8 bits (1 byte), 256 possibilidades

• 00000000 … 11111111 em binário

• 0 … 255 em decimal

67

Representação de inteiros

Um número inteiro pode ser representado com uma combinação de bits.• por omissão, em MATLAB usa-se 32 bits para

representar cada número inteiro• 232 = 4294967296 combinações

• um bit para o sinal

• -2147483648 … 2147483647

68

Representação de inteiros

32 bits para representar um inteiro• funções intmax e intmin

octave:14> intmaxans = 2147483647octave:15> intminans = -2147483648octave:16> intmin-1ans = -2147483648octave:17> intmax+1ans = 2147483647

69

Representação de “reais”

Um número “real” é representado com 64 bits* (vírgula flutuante)• Sinal (+, -) : 1 bit

• Expoente: 11 bits (8)

• Fracção: 52 bits (23)

(-1)Sinal Fracção 2 Expoente

* em precisão dupla, por omissão em MATLAB.Em precisão simples são 32 bits.

Sinal Fracção

70

Representação de “reais” Maior valor:

• realmax 1.7977 10308

• 3.4028 1038 em precisão simples

Menor valor não nulo• realmin 2.2251 10-308

• 1.1755 10-38 em precisão simples

Precisão relativa (épsilon)• eps 2.2204x 10-16

• 1.1921 x 10-7 em precisão simples

71

Representação de “reais” Precisão relativa (épsilon)

• eps 2.2204x 10-16

• 1.1921 x 10-7 em precisão simples

• O menor número que somado a 1 dá um resultado diferente de 1:

octave:15> (1+eps) - 1

ans = 2.2204e-016

octave:16> (1+eps/2) - 1

ans = 0

numeros

72

Representação de “reais” Resumindo:

• Todos os dados no computador são sequências de bits.

• A memória é limitada (64 bits para os números), por isso a precisão é limitada.

• Normalmente não há problema, mas atenção aos arredondamentos:• erro numérico

octave:13> sqrt(2)^2-2ans = 4.4409e-016

73

Testes unitários

Testar casos diferentes• pode haver erros de execução em certas

condições

• pode não dar o resultado certo em certos casos

Testar casos com resultado conhecido• só assim podemos identificar erros lógicos e

numéricos, que não produzem mensagens de erro.

74

Implementação Decompor em

• function x=raizmaior(a,b,c)• calcula a maior raiz pela fórmula resolvente

function pH=calculaph(Ka,Ci)

• recebe os valores de Ka e C

i

• usa a função raizmaior

• calcula o pH (- log10

)

75

Como implementar Decompor

• função raizmaior

• função calculaph

76

Testar a função

octave:9> help calculaph

calculaph(Ka, Ci) calcula o pH de um acido fraco monoprotico Ka: constante de dissociacao Ci: concentracao inicial do acido

octave:10> calculaph(6.5e-5,0.01)ans = 3.1110octave:11>

77

Como implementar Decompor em funções

• Vantagens• Divide o problema em partes menores

• podemos pensar em cada tarefa individualmente

• Permite testes unitários

• Permite construir programas complexos

• dentro de function … end o código fica isolado

• Permite reutilizar código

• e.g. raizmaior pode servir noutros casos

• Permite obter aprovação a ICE...

78

Segundo problema Fazer a mesma coisa, mas dando

massa molar, massa em solução, volume e Ka.• e.g. qual o pH de 0.01g de ácido benzóico

em 0.250 dm3?

Decompor o problema• Calcular concentração

• Calcular pH• esta parte já está feita

79

Segundo problema pH dada a massa molar, massa em

solução, volume e Ka.function x=raizmaior(a,b,c)• calcula a raiz da equação quadrática que dá a

concentração de [H+]

function pH=calculaph(Ka,Ci)• calcula o pH a partir da constante de dissociação e a

concentração inicial usando raizmaior

function pH=phmassvol(mass,vol,massMol,Ka)

• calcula concentração e chama calculaph

80

Segundo problema pH dada a massa de soluto, volume, massa

molecular e Ka

81

Segundo problema• teste (massa molar do ácido benzóico: 122.12)

octave:27> help phmassvol`phmassvol' is a function from the file C:\ICE\phmassvol.m

phmassvol(mass, vol, massMol, Ka) calcula o pH de um acido fraco monoprotico mass: massa do acido vol: volume da solucao massMol: massa molar Ka: constante de dissociacao

octave:28> phmassvol(1.2212,1,122.12,6.5e-5)ans = 3.1110octave:29> phmassvol(0.01,0.25,122.12,6.5e-5)ans = 3.9319

82

script vs function Em ICE os ficheiros de script são opcionais

• ficheiros de código fonte que não definem uma função

• podem ser úteis para testes e desenvolvimento

• são úteis quando utilizam programas• reprodutibilidade, registo dos argumentos, conveniência

• mas em ICE não vamos pedir (nem querer) que entreguem os vossos programas como scripts. Sempre funções.

83

script vs function Funções function … end são fundamentais

• vão precisar delas para tudo em ICE• exercícios, trabalhos, testes, exame

• os programas que entregam devem ser executados chamando uma função.• isto garante que o programa é independente do que se

faça antes ou depois.

• sem saber escrever funções não se faz praticamente nada em MATLAB...

84

Ciclo de vida do programa Edição do código fonte

• escrito, guardado em ficheiros .m

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• e voltar à edição as vezes que for preciso...

Edição

85

Estilo do código

O código fonte serve• para o interpretador executar o programa

• para nós percebermos o programa

Código difícil de perceber• terá mais erros

• é mais difíceis de corrigir, melhorar, alterar ou reaproveitar

• dá pior nota a ICE

86

Estilo do código

Nomes de variáveis:Descritivos, começando em minúscula e indicando diferentes palavras com maiúscula. Exemplo: mass, vol, massMol

87

Estilo do código

Nomes de variáveis:Excepção quando os nomes correspondem a uma convenção prévia. Nesse caso os nomes das variáveis devem respeitar a convenção esperada.Exemplos: a b c e x na fórmula resolvente, ou Ka, Ci e pH

88

Estilo do código

Nomes de funções: Devem descrever o que a função faz.Há três convenções comuns:• só minúsculas, o que dá menos problemas com os nomes dos ficheiros• minúsculas e maiúsculas (e.g. phMassVol) • ou underscore (_) para separar temos (e.g. ph_mass_vol)

89

Estilo do código

Indentação:Cada bloco de código é alinhado à esquerda e indentado para indicar a que parte pertence (voltaremos a isto nas próximas aulas quando o código se tornar mais complexo).

90

Estilo do código

Inteligibilidade:Cada linha de código deve corresponder a um passo do programa que seja fácil de perceber e faça sentido naquele contexto.Também se deve evitar linhas demasiado longas, dividindo expressões complexas em vários passos.

91

Estilo do código

Documentação e comentários:As funções devem conter documentação que explique o seu funcionamento usando a função help.Outros comentários também devem ser acrescentados sempre que forem úteis para esclarecer algum ponto do funcionamento do código.

92

Estilo do código

Mais (muito mais...) sobre estilo em:• MATLAB Programming Style Guidelines, por

Richard Johnson, 2003

http://www.datatool.com/prod02.htm

93

Resumindo

Programação estruturada• Decompor um problema complexo em

problemas mais simples• E assim por diante, até ter problemas elementares

• Implementar soluções em módulos autónomos

• pensar primeiro na assinatura da função

• testar bem depois de implementar

Abstracção e generalização• Abstrair dos detalhes do problema

• Generalizar a solução

94

Resumindo

Perceber o enunciado• o que é fornecido e pedido

Perceber o problema• o que se tem de fazer

Conceber o algoritmo• tarefas, funções, assinatura de cada uma

Implementar o programa• e testar, testar, testar...

Por esta ordem!

95

Resumindo

Estilo de código• Nome de função deve ser descritivo

• usar umas das 3 convenções

• Nome de variável começando em minúscula e com maiúsculas a indicar composição de palavras• excepto variáveis que se espera obedecer a outras

convenções (Ka, pH, ...)

• Indentação, documentação e comentários

96

Cálculo da massa molecular

O que já sabemos fazer• operações algébricas

• variáveis (números e strings)

• funções• guardar código fonte

• decompor problemas

97

Para estudar a aula de hoje

Recomendado• Physical Modeling in MATLAB

• Capítulo 2 todo

• Capítulo 5, só secções 5.1 a 5.5

Opcional• Manual do Octave

• Secções 11.1 e 11.9

• (tem mais matéria do que é dada nesta disciplina)

98

Dúvidas