computação cientí ca com python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf ·...

305

Upload: lykhuong

Post on 22-May-2018

263 views

Category:

Documents


6 download

TRANSCRIPT

Page 1: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Computação

Cientíca

com Python

Page 2: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas
Page 3: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Computação

Cientíca

com Python

Uma introdução à programação

para cientistas

Flávio Codeço Coelho

Petrópolis RJEdição do Autor

2007

Page 4: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

c© 2007 Flávio Codeço CoelhoTodos os direitos reservados.

ISBN: 978-85-907346-0-4

Capa: Mosaico construído com as guras deste livro imitando o logotipo dalinguagem Python. Concebido e realizado pelo autor, com o auxílio do softwarelivre Metapixel.

Revisão ortográca: Paulo F. Coelho e Luciene C. Coelho.

Edição do autor. Petrópolis - RJ - Brasil

Primeira Edição: Julho 2007

Page 5: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Este livro é dedicado à minha esposa e meu lho, semos quais nada disso valeria a pena.

Page 6: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas
Page 7: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Agradecimentos

Muitas pessoas foram indispensáveis para que este livro se tornasseuma realidade. Seria impossível listar todas elas. Mas algumasguras fundamentais merecem uma menção especial.

Richard M. Stallman. Sem o Software Livre tudo o que eu seisobre programação, provavelmente se reduziria a alguns co-mandos de DOS.

Linus Torvalds. Sem o Linux, nunca teria me aproximado o su-ciente da programação para conhecer a linguagem Python.

Guido van Rossum. Muito obrigado por esta bela linguagem, epor acreditar que elegância e clareza são atributos importan-tes de uma linguagem de programação.

Comunidade Python. Obrigado por todas esta extensões ma-ravilhosas ao Python. À comunidade de desenvolvedores doNumpy e Scipy segue um agradecimento especial por facilitara adoção do Python por cientistas.

Alem destas pessoas gostaria ainda de agradecer ao Fernando Pe-rez (criador e mantenedor do Ipython) por este incrivelmente útilsoftware e por permitir que eu utilizasse alguns dos exemplos dasua documentação neste livro.

Page 8: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas
Page 9: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Sumário

Sumário i

Lista de Figuras vii

Lista de Tabelas x

Listagens xi

Prefácio: Computação Cientíca xviiDa Computação Cientíca e sua denição pragmática.

Do porquê esta se diferencia, em metas e ferramentas, daCiência da Computação.

I Python 1

1 Fundamentos da Linguagem 3Breve introdução a conceitos básicos de programação

e à linguagem Python. A maioria dos elementos básicosda linguagem são abordados neste capítulo, com exceçãode classes, que são discutidas em detalhe no capítulo 2.Pré-requisitos: Conhecimentos básicos de programaçãoem qualquer linguagem.

i

Page 10: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

ii SUMÁRIO

1.1 Primeiras impressões . . . . . . . . . . . . . . . . . . 31.2 Uso Interativo vs. Execução a Partir de Scripts . . . 5

Operações com Números . . . . . . . . . . . . . . . . 81.3 Nomes, Objetos e Espaços de Nomes . . . . . . . . . 111.4 Estruturas de Dados . . . . . . . . . . . . . . . . . . 13

Listas . . . . . . . . . . . . . . . . . . . . . . . . . . 13Tuplas . . . . . . . . . . . . . . . . . . . . . . . . . . 20Strings . . . . . . . . . . . . . . . . . . . . . . . . . . 22Dicionários . . . . . . . . . . . . . . . . . . . . . . . 24Conjuntos . . . . . . . . . . . . . . . . . . . . . . . . 27

1.5 Controle de uxo . . . . . . . . . . . . . . . . . . . . 28Condições . . . . . . . . . . . . . . . . . . . . . . . . 28Iteração . . . . . . . . . . . . . . . . . . . . . . . . . 29Lidando com erros: Exceções . . . . . . . . . . . . . 32

1.6 Funções . . . . . . . . . . . . . . . . . . . . . . . . . 34Funções lambda . . . . . . . . . . . . . . . . . . . . . 37Geradores . . . . . . . . . . . . . . . . . . . . . . . . 38Decoradores . . . . . . . . . . . . . . . . . . . . . . . 39Strings de Documentação . . . . . . . . . . . . . . . 41

1.7 Módulos e Pacotes . . . . . . . . . . . . . . . . . . . 42Pacotes Úteis para Computação Cientíca . . . . . . 45

1.8 Documentando Programas . . . . . . . . . . . . . . . 47Pydoc . . . . . . . . . . . . . . . . . . . . . . . . . . 48Epydoc . . . . . . . . . . . . . . . . . . . . . . . . . 49

1.9 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . 50

2 Orientação a Objeto 51Introdução à programação orientada a objetos e sua

implementação na linguagem Python. Pré-requisitos:

Ter lido o capítulo 1.2.1 Objetos . . . . . . . . . . . . . . . . . . . . . . . . . 52

Denindo Objetos e seus Atributos em Python . . . 53Adicionando Funcionalidade a Objetos . . . . . . . . 55Herança . . . . . . . . . . . . . . . . . . . . . . . . . 56

Page 11: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

iii

Utilizando Classes como Estruturas de Dados Gené-ricas. . . . . . . . . . . . . . . . . . . . . . . . 57

2.2 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . 57

3 Criando Grácos em Python 59Introdução à produção de guras de alta qualidade uti-

lizando o pacote matplotlib. Pré-requisitos: Capítulo 1.3.1 Introdução ao Matplotlib . . . . . . . . . . . . . . . 59

Congurando o MPL . . . . . . . . . . . . . . . . . . 61Comandos Básicos . . . . . . . . . . . . . . . . . . . 62

3.2 Exemplos Simples . . . . . . . . . . . . . . . . . . . 63O comando plot . . . . . . . . . . . . . . . . . . . . 63O Comando subplot . . . . . . . . . . . . . . . . . . 65Adicionando Texto a Grácos . . . . . . . . . . . . . 68

3.3 Exemplos Avançados . . . . . . . . . . . . . . . . . . 69Mapas . . . . . . . . . . . . . . . . . . . . . . . . . . 69

4 Ferramentas de Desenvolvimento 73Exposição de ferramentas voltadas para o aumento da

produtividade em um ambiente de trabalho em computa-ção cientíca. Pré-requisitos: Capítulos 1 e 24.1 Ipython . . . . . . . . . . . . . . . . . . . . . . . . . 73

Primeiros Passos . . . . . . . . . . . . . . . . . . . . 74Comandos Mágicos . . . . . . . . . . . . . . . . . . . 75

4.2 Editores de Código . . . . . . . . . . . . . . . . . . . 80Editores Genéricos . . . . . . . . . . . . . . . . . . . 80Editores Especializados . . . . . . . . . . . . . . . . 83

4.3 Controle de Versões em Software . . . . . . . . . . . 86Entendendo o Mercurial . . . . . . . . . . . . . . . . 88

5 Interagindo com Outras Linguagens 99Introdução a vários métodos de integração do Python

com outras linguagens. Pré-requisitos: Capítulos 1 e 2.5.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . 99

Page 12: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

iv SUMÁRIO

5.2 Integração com a Linguagem C . . . . . . . . . . . . 100Weave . . . . . . . . . . . . . . . . . . . . . . . . . . 100Ctypes . . . . . . . . . . . . . . . . . . . . . . . . . . 105Pyrex . . . . . . . . . . . . . . . . . . . . . . . . . . 106

5.3 Integração com C++ . . . . . . . . . . . . . . . . . . . 111Shedskin . . . . . . . . . . . . . . . . . . . . . . . . . 112

5.4 Integração com a Linguagem Fortran . . . . . . . . 117f2py . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

5.5 A Píton que sabia Javanês Integração com Java . 126O interpretador Jython . . . . . . . . . . . . . . . . 126Criando Applets em Jython . . . . . . . . . . . . . 128

5.6 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . 131

II Aplicações 133

6 Modelagem Matemática 135Introdução à modelagem matemática e sua implemen-

tação computacional. Discussão sobre a importância daAnálise dimensional na modelagem e apresentação do pa-cote Unum para lidar com unidades em Python. Pré-

requisitos:Conhecimentos básicos de cálculo.

6.1 Modelos . . . . . . . . . . . . . . . . . . . . . . . . . 137Lineares . . . . . . . . . . . . . . . . . . . . . . . . . 137Exponenciais . . . . . . . . . . . . . . . . . . . . . . 142

6.2 Construindo Modelos Dinâmicos . . . . . . . . . . . 145Modelando Iterativamente . . . . . . . . . . . . . . . 145Integração Numérica . . . . . . . . . . . . . . . . . . 148

6.3 Grandezas, Dimensões e Unidades . . . . . . . . . . 155Análise Dimensional . . . . . . . . . . . . . . . . . . 158O Pacote Unum . . . . . . . . . . . . . . . . . . . . . 159

6.4 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . 167

Page 13: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

v

7 Teoria de Grafos 169Breve introdução a teoria de grafos e sua represen-

tação computacional. Introdução ao Pacote NetworkX,voltado para a manipulação de grafos. Pré-requisitos:

Programação orientada a objetos.7.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . 1697.2 NetworkX . . . . . . . . . . . . . . . . . . . . . . . . 172

Construindo Grafos . . . . . . . . . . . . . . . . . . . 173Manipulando Grafos . . . . . . . . . . . . . . . . . . 174Criando Grafos a Partir de Outros Grafos . . . . . . 175Gerando um Grafo Dinamicamente . . . . . . . . . . 176Construindo um Grafo a Partir de Dados . . . . . . 179

7.3 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . 182

8 Interação com Bancos de Dados 185Apresentação dos módulos de armazenamento de da-

dos Pickle e Sqlite3 que fazem parte da distribuição pa-drão do Python. Apresentação do pacote SQLObject paracomunicação com os principais sistemas de bancos de da-dos existentes. Pré-requisitos: Conhecimentos básicosde bancos de dados e SQL.8.1 O Módulo Pickle . . . . . . . . . . . . . . . . . . . . 1868.2 O módulo Sqlite3 . . . . . . . . . . . . . . . . . . . . 1878.3 O Pacote SQLObject . . . . . . . . . . . . . . . . . . 190

Construindo um aranha digital . . . . . . . . . . . . 1908.4 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . 197

9 Simulações Estocásticas 199Seleção de problemas relacionados com a simulação e

análise de processos estocásticos. Pré-requisitos: Co-nhecimentos avançados de estatística.9.1 Números Aleatórios . . . . . . . . . . . . . . . . . . . 199

Hipercubo Latino - LHS . . . . . . . . . . . . . . . . 2009.2 Inferência Bayesiana . . . . . . . . . . . . . . . . . . 203

Page 14: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

vi SUMÁRIO

9.3 Simulaçoes Estocásticas . . . . . . . . . . . . . . . . 205Integração Monte Carlo . . . . . . . . . . . . . . . . 205

9.4 Amostragem por Rejeição . . . . . . . . . . . . . . . 207Método do Envelope . . . . . . . . . . . . . . . . . . 208Aplicando ao Teorema de Bayes . . . . . . . . . . . . 210

9.5 Cadeias de Markov . . . . . . . . . . . . . . . . . . . 2149.6 MCMC (Markov Chain Monte Carlo) . . . . . . . . 217

O Amostrador de Metropolis-Hastings . . . . . . . . 217O Amostrador de Gibbs . . . . . . . . . . . . . . . . 220

9.7 Métodos Monte Carlo Sequenciais . . . . . . . . . . 223Sampling Importance Resampling SIR . . . . . . . 224

9.8 Funções de Verossimilhança . . . . . . . . . . . . . . 229Denição da função de verossimilhança . . . . . . . . 229

9.9 Inferência Bayesiana com Objetos. . . . . . . . . . . 2359.10 Exercícios . . . . . . . . . . . . . . . . . . . . . . . . 248

Console Gnu/Linux 253Guia de sobrevivência no console do Gnu/Linux

A linguagem BASH . . . . . . . . . . . . . . . . . . . . . 254Alguns Comando Úteis . . . . . . . . . . . . . . . . . 254

Entradas e Saídas, redirecionamento e "Pipes". . . . . . . 257Redirecionamento . . . . . . . . . . . . . . . . . . . . 258Pipelines . . . . . . . . . . . . . . . . . . . . . . . . 258

Pérolas Cientícas do Console Gnu/Linux . . . . . . . . . 259Gnu plotutils . . . . . . . . . . . . . . . . . . . . . . 259

Índice Remissivo 267

Page 15: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Lista de Figuras

1.1 Versão HTML da documentação gerada pelo Epydoc. . . . 50

3.1 Histograma simples a partir da listagem 3.2 . . . . . . . 613.2 Reta simples a partir da listagem 3.3 . . . . . . . . . . . 633.3 Gráco com símbolos circulares a partir da listagem 3.4 653.4 Figura com dois grácos utilizando o comando subplot,

a partir da listagem 3.5 . . . . . . . . . . . . . . . . . . 673.5 Formatação de texto em guras. Gerada pela listagem

3.6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703.6 Mapa mundi na projeção de Robinson. . . . . . . . . . . 72

4.1 Editor emacs em modo Python e com Code Browserativado . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

4.2 Editor Scite. . . . . . . . . . . . . . . . . . . . . . . . . 834.3 Editor Gnu Nano. . . . . . . . . . . . . . . . . . . . . . 844.4 Editor Jython Jedit . . . . . . . . . . . . . . . . . . . 854.5 IDE Boa-Constructor . . . . . . . . . . . . . . . . . . . 864.6 IDE Eric. . . . . . . . . . . . . . . . . . . . . . . . . . . 874.7 IDE Pydev . . . . . . . . . . . . . . . . . . . . . . . . . 884.8 Diagrama de um repositório do Mercurial. . . . . . . . . 894.9 Operação de commit. . . . . . . . . . . . . . . . . . . . 904.10 Repositório da Ana. . . . . . . . . . . . . . . . . . . . . 91

vii

Page 16: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

viii LISTA DE FIGURAS

4.11 Modicações de Bruno. . . . . . . . . . . . . . . . . . . 924.12 Modicações de Ana. . . . . . . . . . . . . . . . . . . . . 924.13 Repositório atualizado de Bruno. . . . . . . . . . . . . . 934.14 Repositório de Bruno após a fusão. . . . . . . . . . . . . 94

5.1 Comparação da performance entre o Python e o C (we-ave) para um loop simples. O eixo y está em escalalogaritmica para facilitar a visualização das curvas. . . . 103

5.2 Regra trapezoidal para integração aproximada de umafunção. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

5.3 Saída da listagem 5.25. . . . . . . . . . . . . . . . . . . . 129

6.1 Diagrama de dispersão do exemplo do taxi. A reta su-perior descreve o cenário com bandeirada e a inferior,sem bandeirada. . . . . . . . . . . . . . . . . . . . . . . 139

6.2 População crescendo de forma linear, devido à chegadade um número constante de novos indivíduos por ano. . 140

6.3 População diminui de forma linear, devido à saida deum número constante de indivíduos por ano. . . . . . . 141

6.4 Representação gráca de um modelo linear. Efeito doparâmetro a. . . . . . . . . . . . . . . . . . . . . . . . . 142

6.5 Representação gráca de um modelo linear. Efeito doparâmetro b. . . . . . . . . . . . . . . . . . . . . . . . . 143

6.6 Crescimento de uma população de bactérias por bipar-tição. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144

6.7 Modelos populacionais discretos. Modelo 2 à esquerdae modelo 1 à direita. . . . . . . . . . . . . . . . . . . . . 146

6.8 Gráco com o resultado da integração do modelo 6.2. . 153

7.1 Um grafo simples. . . . . . . . . . . . . . . . . . . . . . 1717.2 Diagrama de um grafo . . . . . . . . . . . . . . . . . . . 1747.3 Grafo, produto cartesiano e complemento. . . . . . . . . 1777.4 Resultado da simulação do exemplo 7.5. . . . . . . . . . 1807.5 Rede social a partir de mensagens de email. . . . . . . . 183

Page 17: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

ix

9.1 Amostragem (n=20) de uma distribuição normal commédia 0 por LHS (histograma mais escuro) e amostra-gem padrão do scipy (histograma mais claro). . . . . . . 201

9.2 Distribuição acumulada da variável x ∼ N(0, 1), mos-trando o particionamento do espaço amostral em seg-mentos equiprováveis. . . . . . . . . . . . . . . . . . . . 202

9.3 Resultado da amostragem por envelope de uma distri-buição beta(1,1) . . . . . . . . . . . . . . . . . . . . . . 211

9.4 Amostragem por rejeição da posterior Bayesiana. . . . . 2149.5 Cadeia de Markov com kernel de transição exponencial. 2169.6 Amostrador de Metropolis-Hastings(n=10000). . . . . . 2209.7 Estrutura de dependência circular utilizada na listagem

9.7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2239.8 Amostrador de Gibbs aplicado a uma distribuição tri-

variada. . . . . . . . . . . . . . . . . . . . . . . . . . . . 2249.9 Processo markoviano e suas observações. . . . . . . . . . 2259.10 Função de verossimilhança para a comparação de sequên-

cias de DNA. . . . . . . . . . . . . . . . . . . . . . . . . 2329.11 Log-verossimilhança da função descrita anteriormente. . 2349.12 Resultado da listagem 9.21. . . . . . . . . . . . . . . . . 243

1 Konsole: janela contendo uma sessão bash (ou outra)no KDE. . . . . . . . . . . . . . . . . . . . . . . . . . . . 255

2 Usando spline. . . . . . . . . . . . . . . . . . . . . . . . 2623 Interpolando uma curva em um plano. . . . . . . . . . . 2634 Atrator de Lorenz. . . . . . . . . . . . . . . . . . . . . . 266

Page 18: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Lista de Tabelas

1.1 Métodos de Listas. . . . . . . . . . . . . . . . . . . . . . 161.2 Métodos de Dicionários. . . . . . . . . . . . . . . . . . . 26

3.1 Principais comandos de plotagem do MPL . . . . . . . . 623.2 Argumentos que podem ser passados juntamente com a

função plot para controlar propriedades de linhas. . . . 663.3 Argumentos opcionais dos comandos de inserção de texto. 68

6.1 Valor de corridas de taxi . . . . . . . . . . . . . . . . . . 1386.2 Dimensões básicas. . . . . . . . . . . . . . . . . . . . . . 1566.3 Dimensões derivadas. . . . . . . . . . . . . . . . . . . . . 1576.4 Prexos de Unidades . . . . . . . . . . . . . . . . . . . . 165

x

Page 19: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Listagens

1.1 O console interativo do Python . . . . . . . . . . . . 31.2 Palavras reservadas não podem ser utilizadas como

nomes de variáveis . . . . . . . . . . . . . . . . . . . 41.3 Denição da palavra reservada for. . . . . . . . . . . 51.4 Usando o Python como uma calculadora. . . . . . . 61.5 Executando script.py via comando de linha. . . . . . 61.7 Executando um script Python executável. . . . . . . 61.6 Tornando um script executável . . . . . . . . . . . . 71.8 Operações aritméticas . . . . . . . . . . . . . . . . . 81.9 Atribuindo valores . . . . . . . . . . . . . . . . . . . 91.10 Atribuindo o mesmo valor a múltiplas variáveis . . . 91.11 Números complexos . . . . . . . . . . . . . . . . . . 101.12 Explorando números complexos . . . . . . . . . . . . 101.13 Atribuindo objetos a nomes (variáveis) . . . . . . . . 111.14 Exemplo de NameError . . . . . . . . . . . . . . . . 121.15 Criando listas. . . . . . . . . . . . . . . . . . . . . . 141.16 Fatiando uma lista . . . . . . . . . . . . . . . . . . . 141.17 Selecionando o nal de uma lista. . . . . . . . . . . . 151.18 selecionando todos os elementos de uma lista. . . . . 151.19 Adicionando elementos a listas. . . . . . . . . . . . . 161.20 Estendendo uma lista. . . . . . . . . . . . . . . . . . 171.21 Efetuando buscas em listas. . . . . . . . . . . . . . . 171.22 Removendo elementos de uma lista. . . . . . . . . . . 18

xi

Page 20: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

xii LISTAGENS

1.23 Operações com listas . . . . . . . . . . . . . . . . . . 181.24 Criando listas numéricas sequenciais. . . . . . . . . . 191.25 Denindo uma Tupla. . . . . . . . . . . . . . . . . . 201.26 Outras formas de denir tuplas. . . . . . . . . . . . . 201.27 Strings. . . . . . . . . . . . . . . . . . . . . . . . . . 221.28 Formatando strings. . . . . . . . . . . . . . . . . . . 231.29 Problemas com a concatenação de strings. . . . . . . 241.30 Criando e manipulando dicionários. . . . . . . . . . . 241.31 Iterando dicionários. . . . . . . . . . . . . . . . . . . 251.32 Exemplo do emprego de ramicações. . . . . . . . . 281.33 Implementando a funcionalidade de if e elif por

meio de um dicionário. . . . . . . . . . . . . . . . . . 291.34 Comandos de laço no Python. . . . . . . . . . . . . . 301.35 A função enumerate. . . . . . . . . . . . . . . . . . . 301.36 Iterando sobre mais de uma sequência. . . . . . . . . 311.37 Iterando sobre uma sequência ordenada. . . . . . . . 311.38 Exemplo de uma exceção . . . . . . . . . . . . . . . 321.39 Contornando uma divisão por zero . . . . . . . . . . 331.40 Lidando com diferentes tipos de erros. . . . . . . . . 341.41 Denindo uma função com um argumento obrigató-

rio e outro opcional (com valor default"). . . . . . . 351.42 lista de argumentos variável . . . . . . . . . . . . . . 361.43 Desempacotando argumentos. . . . . . . . . . . . . . 361.44 Passando todos os argumentos por meio de um dici-

onário. . . . . . . . . . . . . . . . . . . . . . . . . . . 371.45 Retornando valores a partir de uma função. . . . . . 371.46 Funções lambda . . . . . . . . . . . . . . . . . . . . . 381.47 Geradores . . . . . . . . . . . . . . . . . . . . . . . . 381.48 Decorador básico. . . . . . . . . . . . . . . . . . . . . 391.49 Utilizando um decorador . . . . . . . . . . . . . . . . 391.50 Limpando a geração de decoradores . . . . . . . . . . 401.51 Usando Docstrings . . . . . . . . . . . . . . . . . . . 411.52 Módulo exemplo . . . . . . . . . . . . . . . . . . . . 431.53 Executing a module from the console. . . . . . . . . 44

Page 21: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

xiii

1.54 importing a package . . . . . . . . . . . . . . . . . . 451.55 Calculando e mostrando o determinante de uma ma-

triz. . . . . . . . . . . . . . . . . . . . . . . . . . . . 451.56 Listando as opções do Epydoc. . . . . . . . . . . . . 492.1 Denindo uma classe . . . . . . . . . . . . . . . . . . 532.2 Denindo atributos de uma classe . . . . . . . . . . . 54caption=Instanciando uma classe.,label=ex:classe3 . . . . 542.3 Passando atributos na criação de um objeto . . . . . 542.4 Herança . . . . . . . . . . . . . . . . . . . . . . . . . 562.5 Classe como uma estrura de dados . . . . . . . . . . 573.1 Instalando o matplotlib . . . . . . . . . . . . . . . . 603.2 Criando um histograma no modo interativo . . . . . 603.3 Gráco de linha . . . . . . . . . . . . . . . . . . . . . 633.4 Gráco de pontos com valores de x e y especicados. 643.5 Figura com dois grácos utilizando o comando subplot. 663.6 Formatando texto e expressões matemáticas . . . . . 693.7 Plotando o globo terrestre . . . . . . . . . . . . . . . 705.1 Otimização de loops com o weave . . . . . . . . . . . 1005.2 Calculando iterativamente a série de Fibonacci em

Python e em C(weave.inline) . . . . . . . . . . . . 1025.3 Executando o código do exemplo 5.2. . . . . . . . . . 1055.4 Carregando bibliotecas em C . . . . . . . . . . . . . . 1065.5 Chamando fuções em bibliotecas importadas com o

ctypes . . . . . . . . . . . . . . . . . . . . . . . . . . 1065.6 Calculando números primos em Pyrex . . . . . . . . 1075.7 Gerando Compilando e linkando . . . . . . . . . . . 1085.8 Calculando números primos em Python . . . . . . . 1095.9 Comparando performances dentro do ipython . . . . 1105.10 Automatizando a compilação de extensões em Pyrex

por meio do setuptools . . . . . . . . . . . . . . . . . 1105.11 Utilizando Setuptools para compilar extensões em

Pyrex . . . . . . . . . . . . . . . . . . . . . . . . . . 1115.12 implementação da regra trapezoidal(utilizando laço

for) conforme especicada na equação 5.3 . . . . . . 112

Page 22: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

xiv LISTAGENS

5.13 Executando a listagem 5.12 . . . . . . . . . . . . . . 1145.14 Vericando o tempo de execução em C++ . . . . . . . 1145.15 Código C++ gerado pelo Shed-skin a partir do script

trapintloopy.py . . . . . . . . . . . . . . . . . . . . . 1155.16 implementação em Fortran da regra trapezoidal. label1185.17 Compilando e executando o programa da listagem ?? 1205.18 Compilando com f2py . . . . . . . . . . . . . . . . . 1215.19 Script para comparação entre Python e Fortran via

f2py . . . . . . . . . . . . . . . . . . . . . . . . . . . 1215.20 Executando trapintloopcomp.py . . . . . . . . . . 1235.21 Implementação vetorizada da regra trapezoidal . . . 1235.22 setup.py para distribuir programas com extensões

em Fortran . . . . . . . . . . . . . . . . . . . . . . . 1255.23 Usando o interpretador Jython . . . . . . . . . . . . 1275.24 Um programa simples em Java usando a classe Swing.1275.25 Versão Jython do programa da listagem 5.24. . . . . 1285.26 Criando um applet em Jython . . . . . . . . . . . . 1285.27 Compilando appletp.py . . . . . . . . . . . . . . . . 1295.28 Documento HTML contendo o applet. . . . . . . . 1306.1 Dois modelos discretos de crescimento populacional . 1476.2 Integrando um sistema de equações diferenciais or-

dinárias . . . . . . . . . . . . . . . . . . . . . . . . . 1496.3 Integração numérica utilizando a classe ODE. . . . . 1536.4 Criando novas unidades. . . . . . . . . . . . . . . . . 1627.1 Denindo um grafo como um dicionário. . . . . . . . 1707.2 Obtendo a lista de vértices. . . . . . . . . . . . . . . 1717.3 Denindo um grafo através de seus vértices . . . . . 1727.4 Diagrama de um grafo . . . . . . . . . . . . . . . . . 1727.5 Construindo um grafo dinamicamente . . . . . . . . 1767.6 Construindo uma rede social a partir de e-mails . . . 1798.1 Exemplo de uso do módulo pickle . . . . . . . . . . 1868.2 Módulos necessários . . . . . . . . . . . . . . . . . . 1908.3 Especicando o banco de dados. . . . . . . . . . . . 1918.4 Especicando a tabela ideia do banco de dados. . . 192

Page 23: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

xv

8.5 Restante do código da aranha. . . . . . . . . . . . . 1939.1 Amostragem por Hipercubo latino (LHS) . . . . . . 2019.2 Integração Monte Carlo . . . . . . . . . . . . . . . . 2069.3 Amostragem por rejeição utilizando o método do en-

velope . . . . . . . . . . . . . . . . . . . . . . . . . . 2099.4 Amostragem da Posterior Bayesiana por rejeição. . . 2129.5 Cadeia de Markov com kernel de transição exponencial2159.6 Amostrador de Metropolis-Hastings . . . . . . . . . . 2189.7 Amostrador de Gibbs aplicado à uma distribuição

tri-variada . . . . . . . . . . . . . . . . . . . . . . . . 2219.8 Filtro de partículas usando algoritmo SIR . . . . . . 2259.9 Função de verossimilhança para x igual a 0. . . . . . 2309.10 Calculando a verossimilhança da comparação de duas

sequências de DNA . . . . . . . . . . . . . . . . . . . 2319.11 Log-verossimilhança . . . . . . . . . . . . . . . . . . 2349.12 Maximizando a verossimilhança . . . . . . . . . . . . 2359.13 Classe Variável Aleatória Bayesiana Requisitos. . . 2369.14 Classe Variável Aleatória Bayesiana Inicialização. . 2379.15 Classe Variável Aleatória Bayesiana Herança dinâ-

mica de métodos. . . . . . . . . . . . . . . . . . . . . 2389.16 Classe Variável Aleatória Bayesiana Herança dinâ-

mica de métodos. . . . . . . . . . . . . . . . . . . . . 2389.17 Classe Variável Aleatória Bayesiana Adição de da-

dos e cálculo da Verossimilhança. . . . . . . . . . . . 2399.18 Classe Variável Aleatória Bayesiana Amostras e

PDF da a priori. . . . . . . . . . . . . . . . . . . . . 2409.19 Classe Variável Aleatória Bayesiana Gerando a

posterior. . . . . . . . . . . . . . . . . . . . . . . . . 2419.20 Classe Variável Aleatória Bayesiana Código de teste.2429.21 Classe Variável Aleatória Bayesiana Listagem com-

pleta . . . . . . . . . . . . . . . . . . . . . . . . . . . 24422 Redirecionando STDIN e STDOUT . . . . . . . . . . 25823 Lista ordenada dos usuários do sistema. . . . . . . . 25824 Plotando dados em um arquivo. . . . . . . . . . . . . 260

Page 24: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

xvi LISTAGENS

25 Desenhando um quadrado. . . . . . . . . . . . . . . . 26126 Uso do spline . . . . . . . . . . . . . . . . . . . . . 26127 Interpolando uma curva em um plano. . . . . . . . . 26128 Resolvendo uma equação diferencial simples no con-

sole do Linux. . . . . . . . . . . . . . . . . . . . . . . 26429 Sistema de três equações diferenciais acopladas . . . 265

Page 25: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Prefácio: ComputaçãoCientíca

Da Computação Cientíca e sua denição pragmática.Do porquê esta se diferencia, em metas e ferramentas,da Ciência da Computação.

Computação cientíca não é uma área do conhecimento muitobem denida. A denição utilizada neste livro é a de uma área

de atividade/conhecimento que envolve a utilização de ferramentascomputacionais (software) para a solução de problemas cientícosem áreas da ciência não necessariamente ligadas à disciplina daciência da computação, ou seja, a computação para o restante dacomunidade cientíca.

Nos últimos tempos, a computação em suas várias facetas, temse tornado uma ferramenta universal para quase todos os segmentosda atividade humana. Em decorrência, podemos encontrar produ-tos computacionais desenvolvidos para uma enorme variedade deaplicações, sejam elas cientícas ou não. No entanto, a diversidadede aplicações cientícas da computação é quase tão vasta quantoo próprio conhecimento humano. Por isso, o cientista frequente-mente se encontra com problemas para os quais as ferramentascomputacionais adequadas não existem.

No desenvolvimento de softwares cientícos, temos dois modosprincipais de produção de software: o desenvolvimento de softwarescomerciais, feito por empresas de software que contratam progra-

xvii

Page 26: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

xviii PREFÁCIO: COMPUTAÇÃO CIENTÍFICA

madores prossionais para o desenvolvimento de produtos voltadospara uma determinada aplicação cientíca, e o desenvolvimentofeito por cientistas (físicos, matemáticos, biólogos, etc., que nãosão programadores prossionais), geralmente de forma colabora-tiva através do compartilhamento de códigos fonte.

Algumas disciplinas cientícas, como a estatística por exemplo,representam um grande mercado para o desenvolvimento de softwa-res comerciais genéricos voltados para as suas principais aplicações,enquanto que outras disciplinas cientícas carecem de massa crítica(em termos de número de prossionais) para estimular o desenvol-vimento de softwares comerciais para a solução dos seus problemascomputacionais especícos. Como agravante, o desenvolvimentolento e centralizado de softwares comerciais, tem se mostrado inca-paz de acompanhar a demanda da comunidade cientíca, que pre-cisa ter acesso a métodos que evoluem a passo rápido. Além disso,estão se multiplicando as disciplinas cientícas que têm como suaferramenta principal de trabalho os métodos computacionais, comopor exemplo a bio-informática, a modelagem de sistemas comple-xos, dinâmica molecular e etc.

Cientistas que se vêem na situação de terem de desenvolversoftwares para poder viabilizar seus projetos de pesquisa, geral-mente têm de buscar uma formação improvisada em programaçãoe produzem programas que tem como característica básica seremminimalistas, ou seja, os programas contêm o mínimo número delinhas de código possível para resolver o problema em questão. Istose deve à conjugação de dois fatos: 1) O cientista raramente possuihabilidades como programador para construir programas mais so-sticados e 2) Frequentemente o cientista dispõe de pouco tempoentre suas tarefas cientícas para dedicar-se à programação.

Para complicar ainda mais a vida do cientista-programador, aslinguagens de programação tradicionais foram projetadas e desen-volvidas por programadores para programadores e voltadas ao de-senvolvimento de softwares prossionais com dezenas de milharesde linhas de código. Devido a isso, o número de linhas de código

Page 27: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

xix

mínimo para escrever um programa cientíco nestas linguagens émuitas vezes maior do que o número de linhas de código associadocom a resolução do problema em questão.

Quando este problema foi percebido pelas empresas de soft-ware cientíco, surgiu uma nova classe de software, voltado para ademanda de cientistas que precisavam implementar métodos com-putacionais especícos e que não podiam esperar por soluções co-merciais.

Esta nova classe de aplicativos cientícos, geralmente inclui umalinguagem de programação de alto nível, por meio da qual os ci-entistas podem implementar seus próprios algoritmos, sem ter queperder tempo tentando explicar a um programador prossional oque, exatamente, ele deseja. Exemplos destes produtos incluemMATLABTM, MathematicaTM, MapleTM, entre outros. Nestesaplicativos, os programas são escritos e executados dentro do pró-prio aplicativo, não podendo ser executados fora dos mesmos. Estesambientes, entretanto, não possuem várias características impor-tantes das linguagens de programação: Não são portáteis, ou seja,não podem ser levados de uma máquina para a outra e executa-dos a menos que a máquina-destino possua o aplicativo gerador doprograma (MATLABTM, etc.) que custa milhares de dólares porlicença, Os programas não podem ser portados para outra plata-forma computacional para a qual não exista uma versão do aplica-tivo gerador. E, por último e não menos importante, o programaproduzido pelo cientista não lhe pertence, pois, para ser executado,necessita de código proprietário do ambiente de desenvolvimentocomercial.

Este livro se propõe a apresentar uma alternativa livre (base-ada em Software Livre), que combina a facilidade de aprendizado erapidez de desenvolvimento, características dos ambientes de desen-volvimento comerciais apresentados acima, com toda a exibilidadedas linguagens de programação tradicionais. Programas cientícosdesenvolvidos inteiramente com ferramentas de código aberto tema vantagem adicional de serem plenamente escrutináveis pelo sis-

Page 28: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

xx PREFÁCIO: COMPUTAÇÃO CIENTÍFICA

tema de revisão por pares (peer review), mecanismo central daciência para validação de resultados.

A linguagem Python apresenta as mesmas soluções propostaspelos ambientes de programação cientíca, mantendo as vantagensde ser uma linguagem de programação completa e de alto nível.

Apresentando o Python

O Python é uma linguagem de programação dinâmica e orientadaa objetos, que pode ser utilizada no desenvolvimento de qualquertipo de aplicação, cientíca ou não. O Python oferece suporte àintegração com outras linguagens e ferramentas, e é distribuido comuma vasta biblioteca padrão. Além disso, a linguagem possui umasintaxe simples e clara, podendo ser aprendida em poucos dias.O uso do Python é frequentemente associado com grandes ganhosde produtividade e ainda, com a produção de programas de altaqualidade e de fácil manutenção.

A linguagem de programação Python1 começou a ser desen-volvida ao nal dos anos 80, na Holanda, por Guido van Rossum.Guido foi o principal autor da linguagem e continua até hoje desem-penhando um papel central no direcionamento da evolução. Guidoé reconhecido pela comunidade de usuários do Python como Bene-volent Dictator For Life (BDFL), ou ditador benevolente vitalícioda linguagem.

A primeira versão pública da linguagem (0.9.0) foi disponibi-lizada. Guido continou avançando o desenvolvimento da lingua-gem, que alcançou a versão 1.0 em 1994. Em 1995, Guido emigroupara os EUA levando a responsabilidade pelo desenvolvimento doPython, já na versão 1.2, consigo. Durante o período em que Guidotrabalhou para o CNRI2, o Python atingiu a versão 1.6, que foi rápi-damente seguida pela versão 2.0. A partir desta versão, o Python

1www.python.org2Corporation for National Research Initiatives

Page 29: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

xxi

passa a ser distribuído sob a Python License, compatível com aGPL3, tornando-se ocialmente software livre. A linguagem passaa pertencer ocialmente à Python Software Foundation. Apesar daimplementação original do Python ser desenvolvida na LinguagemC (CPython), Logo surgiram outras implementações da Lingua-gem, inicialmente em Java (Jython4), e depois na própria lingua-gem Python (PYPY5), e na plataforma .NET (IronPython6).

Dentre as várias características da linguagem que a tornam in-teressante para computação cientíca, destacam-se:

Multiplataforma: O Python pode ser instalado em qualquer pla-taforma computacional: Desde PDAs até supercomputadorescom processamento paralelo, passando por todas as platafor-mas de computação pessoal.

Portabilidade: Aplicativos desenvolvidos em Python podem serfacilmente distribuídos para várias plataformas diferentes da-quela em que foi desenvolvido, mesmo que estas não possuamo Python instalado.

Software Livre: O Python é software livre, não impondo qual-quer limitação à distribuição gratuita ou venda de progra-mas.

Extensibilidade: O Python pode ser extendido através de mó-dulos,escritos em Python ou rotinas escritas em outras lin-guagens, tais como C ou Fortran (Mais sobre isso no capítulo5).

Orientação a objeto: Tudo em Python é um objeto: funções,variáveis de todos os tipos e até módulos (programas escritosem Python) são objetos.

3GNU General Public License4www.jython.org5pypy.org6www.codeplex.com/Wiki/View.aspx?ProjectName=IronPython

Page 30: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

xxii PREFÁCIO: COMPUTAÇÃO CIENTÍFICA

Tipagem automática: O tipo de uma variável (string, inteiro,oat, etc.) é determinado durante a execução do código;desta forma, você não necessita perder tempo denindo tiposde variáveis no seu programa.

Tipagem forte: Variáveis de um determinado tipo não podemser tratadas como sendo de outro tipo. Assim, você não podesomar a string '123' com o inteiro 3. Isto reduz a chance deerros em seu programa. A variáveis podem, ainda assim, serconvertidas para outros tipos.

Código legível: O Python, por utilizar uma sintaxe simplicadae forçar a divisão de blocos de código por meio de indenta-ção, torna-se bastante legível, mesmo para pessoas que nãoestejam familiarizadas com o programa.

Flexibilidade: O Python já conta com módulos para diversasaplicações, cientícas ou não, incluindo módulos para intera-ção com os protocolos mais comuns da Internet (FTP, HTTP,XMLRPC, etc.). A maior parte destes módulos já faz parteda distribuição básica do Python.

Operação com arquivos: A manipulação de arquivos, tais comoa leitura e escrita de dados em arquivos texto e binário, émuito simplicada no Python, facilitando a tarefa de muitospesquisadores ao acessar dados em diversos formatos.

Uso interativo: O Python pode ser utilizado interativamente, ouinvocado para a execucão de scripts completos. O uso intera-tivo permite experimentar comandos antes de incluí-los emprogramas mais complexos, ou usar o Python simplesmentecomo uma calculadora.

etc...

Entretanto, para melhor compreender todas estas vantagensapresentadas, nada melhor do que começar a explorar exemplos

Page 31: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

xxiii

de computação cientíca na linguagem Python. Mas para inspiraro trabalho técnico, nada melhor do que um poema:

1 >>> import t h i s2 The Zen o f Python , by Tim Peters3

4 Beaut i f u l i s be t t e r than ugly .5 Exp l i c i t i s be t t e r than imp l i c i t .6 Simple i s be t t e r than complex .7 Complex i s be t t e r than compl icated .8 Flat i s be t t e r than nested .9 Sparse i s be t t e r than dense .

10 Readab i l i ty counts .11 Spe c i a l c a s e s aren ' t s p e c i a l enough to break

the r u l e s .12 Although p r a c t i c a l i t y beats pur i ty .13 Errors should never pass s i l e n t l y .14 Unless e x p l i c i t l y s i l e n c e d .15 In the f a c e o f ambiguity , r e f u s e the

temptation to guess .16 There should be one−− and p r e f e r ab l y only

one −−obvious way to do i t .17 Although that way may not be obvious at

f i r s t un l e s s you ' re Dutch .18 Now i s be t t e r than never .19 Although never i s o f t en be t t e r than ∗ r i g h t ∗

now .20 I f the implementation i s hard to expla in , i t

' s a bad idea .21 I f the implementation i s easy to expla in , i t

may be a good idea .22 Namespaces are one honking grea t idea −− l e t

' s do more o f those !23 >>>

Page 32: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

xxiv PREFÁCIO: COMPUTAÇÃO CIENTÍFICA

Usando este Livro

Este livro foi planejado visando a versatilidade de uso. Sendo assim,ele pode ser utilizado como livro didático (em cursos formais) oucomo referência pessoal para auto-aprendizagem ou consulta.

Como livro didático, apresenta, pelo menos, dois níveis de apli-cação possíveis:

1. Um curso introdutório à linguagem Python, no qual se fariauso dos capítulos da primeira parte. O único pré-requisitoseria uma exposição prévia dos alunos a conceitos básicosde programação (que poderia ser condensada em uma únicaaula).

2. Um curso combinado de Python e computação cientíca. Oautor tem ministrado este tipo de curso com grande sucesso.Este curso faria uso da maior parte do conteúdo do livro, oinstrutor pode selecionar capítulos de acordo com o interessedos alunos.

Como referência pessoal, este livro atende a um público bas-tante amplo, de leigos a cientistas. No início de cada capítuloencontram-se os pré-requisitos para se entender o seu conteúdo.Mas não se deixe inibir; as aplicações cientícas são apresentadasjuntamente com uma breve introdução à teoria que as inspira.

Recomendo aos auto-didatas que explorem cada exemplo con-tido no livro; eles ajudarão enormemente na compreensão dos tó-picos apresentados7. Para os leitores sem sorte, que não dispõemde um computador com o sistema operacional GNU/Linux insta-lado, sugiro que o instalem, facilitará muito o acompanhamento dosexemplos. Para os que ainda não estão prontos para abandonar o

7O código fonte do exemplos está disponível na seguinte URL: http://fccoelho.googlepages.com/CCP_code.zip

Page 33: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

xxv

WindowsTM, instalem o Linux em uma máquina virtual8! A dis-tribuição que recomendo para iniciantes é o Ubuntu (www.ubuntu.com).

Enm, este livro foi concebido para ser uma leitura prazeirosapara indivíduos curiosos como eu, que estão sempre interessadosem aprender coisas novas!

Bom Proveito! Flávio Codeço Coelho

Petrópolis, 2007

8Recomendo o VirtualBox (www.virtualbox.org), é software livre e fan-tástico!

Page 34: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas
Page 35: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Parte I

Introdução ao Python eFerramentas deDesenvolvimento

1

Page 36: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas
Page 37: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Capítulo 1

Fundamentos da LinguagemBreve introdução a conceitos básicos de programação eà linguagem Python. A maioria dos elementos básicosda linguagem são abordados neste capítulo, com exceçãode classes, que são discutidas em detalhe no capítulo 2.Pré-requisitos: Conhecimentos básicos de programa-ção em qualquer linguagem.

Neste Capítulo, faremos uma breve introdução à linguagemPython. Esta introdução servirá de base para os exemplos

dos capítulos subseqüentes. Para uma introdução mais completa àlinguagem, recomendamos ao leitor a consulta a livros e outros do-cumentos voltados especicamente para programação em Python.

1.1 Primeiras impressões

Para uma primeira aproximação à linguagem, vamos examinar suascaracterísticas básicas. Façamos isso interativamente, a partir doconsole Python. Vejamos como invocá-lo:

Listagem 1.1: O console interativo do Python

1 $ python

3

Page 38: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

4 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

2 Python 2 . 5 . 1 ( r251 :54863 , May 2 2007 ,1 6 : 5 6 : 3 5 )

3 [GCC 4 . 1 . 2 (Ubuntu 4.1.2−0 ubuntu4 ) ] onl inux2

4 Type " help " , " copyr ight " , " c r e d i t s " or "l i c e n s e " for more in fo rmat ion .

5 >>>

Toda linguagem, seja ela de programação ou linguagem natural,possui um conjunto de palavras que a caracteriza. As linguagensde programação tendem a ser muito mais compactas do que aslinguagens naturais. O Python pode ser considerado uma lingua-gem compacta, mesmo em comparação com outras linguagens deprogramação.

As palavras que compõem uma linguagem de programação sãoditas reservadas, ou seja, não podem ser utilizadas para nomearvariáveis. Se o programador tentar utilizar uma das palavras re-servadas como variável, incorrerá em um erro de sintaxe.

Listagem 1.2: Palavras reservadas não podem ser utilizadas comonomes de variáveis

1 >>> for=12 F i l e "<std in>" , l i n e 13 for=14 ^5 SyntaxError : i n v a l i d syntax

A linguagem Python em sua versão atual (2.5), possui 30 pala-vras reservadas. São elas: and, as, assert, break, class, continue,def, del, elif, else, except, exec, finally, for, from, global,if, import, in, is, lambda, not, or, pass, print, raise, return,try, while e yield. Além destas palavras, existem constantes,tipos e funções internas ao Python, que estão disponíveis para aconstrução de programas. Estes elementos podem ser inspeciona-dos através do comando dir(__builtins__). Nenhum dos ele-

Page 39: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.2. USO INTERATIVO VS. EXECUÇÃO A PARTIR DESCRIPTS 5

mentos do módulo __builtins__ deve ser redenido1. O consoleinterativo do Python possui um sistema de ajuda integrado quepode ser usado para acessar a documentação de qualquer elementoda linguagem. O comando help(), inicia a ajuda interativa. Apartir daí, podemos por exemplo, digitar keywords para acessar aajuda das palavras reservadas listadas acima. Se digitarmos for

em seguida, obteremos a seguinte ajuda:

Listagem 1.3: Denição da palavra reservada for.

1 7 .3 The for statement2

3 The for statement i s used to i t e r a t e overthe e lements o f a sequence

4 ( such as a s t r i ng , tup l e or l i s t ) or otheri t e r a b l e ob j e c t :

5 . . .

1.2 Uso Interativo vs. Execução a Partir deScripts

Usuários familiarizados com ambientes de programação cientícostais como Matlab, R e similares, carão satisfeitos em saber que oPython também pode ser utilizado de forma interativa. Para isso,basta invocar o interpretador na linha de comando (Python shell,em Unix) ou invocar um shell mais sosticado como o Idle, quevem com a distribuição padrão do Python, ou o Ipython (ver 4.1).

Tanto no uso interativo, como na execução a partir de scripts, ointerpretador espera encontrar apenas uma expressão por linha doprograma. Caso se deseje inserir mais de uma expressão em umalinha, as expressões devem ser separadas por ;. Mas esta prática

1Atenção, os componentes de __builtins__, não geram erros de sintaxeao ser redenidos.

Page 40: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

deve ser evitada. Expressões podem continuar em outra linha sealgum de seus parênteses, colchetes, chaves ou aspas ainda não tiversido fechado. Alternativamente, linhas podem ser quebradas pelaaposição do caractere \ ao nal da linha.

Listagem 1.4: Usando o Python como uma calculadora.

1 >>> 1+12 23 >>>

No cabeçalho da shell do Python, acima (listagem 1.1), o interpre-tador identica a versão instalada, data e hora em que foi compi-lada, o compilador C utilizado, detalhes sobre o sistema operacionale uma linhazinha de ajuda para situar o novato.

Para executar um programa, a maneira usual (em Unix) é digi-tar: python script.py. No Windows basta um duplo clique sobrearquivos *.py.

Listagem 1.5: Executando script.py via comando de linha.

1 $ python s c r i p t . py

No Linux e em vários UNIXes, podemos criar scripts que sãoexecutáveis diretamente, sem precisar invocar o interpretador an-tes. Para isso, basta incluir a seguinte linha no topo do nossoscript:

1 #! / usr /bin /env python

Note que os caracteres #! devem ser os dois primeiros caracteresdo arquivo (como na listagem 1.6).

Depois, resta apenas ajustar as permissões do arquivo para quepossamos executá-lo: chmod +x script.py (listagem 1.7).

Listagem 1.7: Executando um script Python executável.

1 $ chmod +x s c r i p t . py

Page 41: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.2. USO INTERATIVO VS. EXECUÇÃO A PARTIR DESCRIPTS 7

Listagem 1.6: Tornando um script executável

1 #! / usr /bin /env python2

3 print "Alô Mundo ! "

2 $ . / s c r i p t . py3 sys : 1 : DeprecationWarning : Non−ASCII

cha rac t e r ' \ xf4 ' in f i l e . / t e s t e on l i n e3 , but no encoding dec l a r ed ; s ee http

://www. python . org /peps/pep−0263. html ford e t a i l s

4 Alô Mundo !

Mas que lixo é aquele antes do nosso Alô mundo? Trata-se do interpretador reclamando do acento circunexo em Alô.Para que o Python não reclame de acentos e outros caracteres dalíngua portuguesa não contidos na tabela ASCII, precisamos adi-cionar a seguinte linha ao script: # -*- coding: latin-1 -*-.Experimente editar o script acima e veja o resultado.

No exemplo da listagem 1.6, utilizamos o comando print parafazer com que nosso script produzisse uma string como saída, ouseja, para escrever no stdout2. Como podemos receber informa-ções pelo stdin? O Python nos oferece duas funções para isso:input('texto'), que executa o que o usuário digitar, sendo por-tanto perigoso, e raw_input('texto'), que retorna uma stringcom a resposta do usuário.

Nas listagens que se seguem, alternaremos entre a utilizaçãode scripts e a utilização do Python no modo interativo (como nalistagem 1.4). A presença do símbolo >>>, característico da shell

2Todos os processos no Linux e outros sistemas operacionais possuem viasde entrada e saída de dados denominados de stdin e stdout, respectivamente.

Page 42: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

8 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

do Python será suciente para diferenciar os dois casos. Exemplosde scripts virão dentro de caixas.

Operações com Números

Noventa e nove por cento das aplicações cientícas envolvem algumtipo de processamento numérico. Vamos iniciar nosso contato como Python através dos números (Listagem 1.8).

Listagem 1.8: Operações aritméticas

1 >>> 2+22 43 >>> # Comentário4 . . . 2∗25 46 >>> 2∗∗2 # Comentário na mesma l i nha7 48 >>> (50−5∗6)/49 5

10 >>> # Divi são de i n t e i r o s r e to rna " f l o o r " :11 . . . 7/312 213 >>> 7/−314 −315 >>> 7/3 .16 2.3333333333333335

Nosso primeiro exemplo numérico (Listagem 1.8)3, trata núme-ros em sua representação mais simples: como constantes. É destaforma que utilizamos uma calculadora comum. Em programaçãoé mais comum termos números associados a quantidades, a que

3Repare como o Python trata a divisão de dois inteiros. Ela retorna oresultado arredondado para baixo

Page 43: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.2. USO INTERATIVO VS. EXECUÇÃO A PARTIR DESCRIPTS 9

precisamos nos referenciar e que podem se modicar. Esta repre-sentação de números chama-se variável.

O sinal de = é utilizado para atribuir valores a variáveis(Listagem1.9).

Listagem 1.9: Atribuindo valores

1 >>> largura = 202 >>> a l tu ra = 5∗93 >>> largura ∗ a l tu r a4 900

Um valor pode ser atribuído a diversas variáveis com uma únicaoperação de atribuição, ou múltiplos valores a múltiplas variáveis(Listagem 1.10). Note que no exemplo de atribuição de múltiplosvalores a múltiplas variáveis (Listagem 1.10, linha 9) os valorespoderiam estar em uma tupla.

Listagem 1.10: Atribuindo o mesmo valor a múltiplas variáveis

1 >>> x = y = z = 0 # Zero x , y e z2 >>> x3 04 >>> y5 06 >>> z7 08 >>> a , b , c=1 ,2 ,39 >>> a

10 111 >>> b12 213 >>> c14 3

O Python também reconhece números reais (ponto-utuante)e complexos naturalmente. Em operações entre números reais e

Page 44: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

10 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

inteiros o resultado será sempre real. Da mesma forma, operaçõesentre números reais e complexos resultam sempre em um númerocomplexo. Números complexos são sempre representados por doisnúmeros ponto-utuante: a parte real e a parte imaginária. Aparte imaginária é representada com um suxo j ou J.

Listagem 1.11: Números complexos

1 >>> 1 j ∗ 1J2 (−1+0 j )3 >>> 1 j ∗ complex (0 , 1 )4 (−1+0 j )5 >>> 3+1 j ∗36 (3+3 j )7 >>> (3+1 j ) ∗38 (9+3 j )9 >>> (1+2 j ) /(1+1 j )

10 (1 .5+0.5 j )

Um Número complexo para o Python, é um objeto4. Podemos ex-trair as partes componentes de um número complexo c utilizandoatributos do tipo complexo: c.real e c.imag. A função abs, queretorna o módulo de um numero inteiro ou real, retorna o compri-mento do vetor no plano complexo, quando aplicada a um númerocomplexo. O módulo de um número complexo é também denomi-nado magnitude (listagem 1.12).

Listagem 1.12: Explorando números complexos

1 >>> a=3.0+3.0 j2 >>> a . r e a l3 3 .04 >>> a . imag5 3 .06 >>> abs ( a ) # sq r t ( a . r e a l ∗∗2 + a . imag ∗∗2)

4Assim como os outros tipos de números.

Page 45: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.3. NOMES, OBJETOS E ESPAÇOS DE NOMES 11

7 4.2426406871192848

1.3 Nomes, Objetos e Espaços de Nomes

Nomes em Python são identicadores de objetos, e também sãochamados de variáveis. Nomes devem ser iniciados por letras maiús-culas ou minúsculas e podem conter algarismos, desde que não se-jam o primeiro caractere. O Python faz distinção entre maiúsculase minúsculas portanto, nome != Nome.

No Python, todos os dados são objetos tipados, que são associ-ados dinamicamente a nomes. O sinal de igual (=), liga o resultadoda avaliação da expressão do seu lado direito a um nome situadoà sua esquerda. A esta operação damos o nome de atribuição (verexemplo na listagem 1.13).

Listagem 1.13: Atribuindo objetos a nomes (variáveis)

1 >>> a=3∗2∗∗72 >>> a , b = ( ' l a r an j a ' , ' banana ' )

As variáveis criadas por atribuição cam guardadas na memóriado computador. Para evitar preenchimento total da memória, as-sim que um objeto deixa de ser referenciado por um nome (deixa deexistir no espaço de nomes corrente), ele é imediatamente apagadoda memória pelo interpretador.

O conceito de espaço de nomes é uma característica da lingua-gem Python que contribui para sua robustez e eciência. Espaçosde nomes são dicionários (ver 1.4) contendo as variáveis, objetose funções disponíveis durante a execução de um programa. A umdado ponto da execução de um programa, existem sempre dois di-cionários disponíveis para a resolução de nomes: um local e umglobal. Estes dicionários podem ser acessados para leitura atravésdas funções locals() e globals(), respectivamente. Sempre queo interpretador Python encontra uma palavra que não pertence ao

Page 46: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

12 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

conjunto de palavras reservadas da linguagem, ele a procura, pri-meiro no espaço de nomes local e depois no global. Se a palavranão é encontrada, um erro do tipo NameError é acionado (exemplo1.14).

Listagem 1.14: Exemplo de NameError

1 >>> maria2 Traceback (most r e c ent c a l l l a s t ) :3 F i l e "<std in>" , l i n e 1 , in ?4 NameError : name ' maria ' i s not de f ined

O espaço de nomes local, muda ao longo da execução de umprograma. Toda a vez que a execução adentra uma função, o espaçode nomes local passa a reetir apenas as variáveis denidas dentrodaquela função5. Ao sair da função, o dicionário local torna-seigual ao global.

1 >>> a=12 >>> len ( g l ob a l s ( ) . i tems ( ) )3 44 >>> len ( l o c a l s ( ) . i tems ( ) )5 46 >>> def fun ( ) :7 . . . a=' novo va l o r '8 . . . print l en ( l o c a l s ( ) . i tems ( ) )9 . . . print a

10 . . .11 >>> fun ( )12 113 novo va lo r14 >>> print a15 116 >>> len ( l o c a l s ( ) . i tems ( ) )

5Mais quaisquer variáveis explicitamente denidas como globais

Page 47: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.4. ESTRUTURAS DE DADOS 13

17 518 >>> l o c a l s ( )19 '__builtins__ ' : <module '__builtin__ ' (

bu i l t−in )>, '__name__' : '__main__ ' , ' fun' : <func t i on fun at 0xb7c18ed4 >, '__doc__ ' : None , ' a ' : 1

Também é importante lembrar que o espaço de nomes localsempre inclui os __builtins__ como vemos na listagem 1.3.

1.4 Estruturas de Dados

Qualquer linguagem de programação pode ser simplisticamentedescrita como uma ferramenta, através da qual, dados e algorit-mos são implementados e interagem para a solução de um dadoproblema. Nesta seção vamos conhecer os tipos e estruturas dedados do Python para que possamos, mais adiante, utilizar toda asua exibilidade em nossos programas.

No Python, uma grande ênfase é dada à simplicidade e à exibi-lidade de forma a maximizar a produtividade do programador. Notocante aos tipos e estruturas de dados, esta losoa se apresentana forma de uma tipagem dinâmica, porém forte. Isto quer dizerque os tipos das variáveis não precisam ser declarados pelo pro-gramador, como é obrigatório em linguagens de tipagem estáticacomo o C, FORTRAN, Visual Basic, etc. Os tipos das variáveissão inferidos pelo interpretador. As principais estruturas de dadoscomo Listas e Dicionários, podem ter suas dimensões alteradas,dinamicamente durante a execução do Programa , o que facilitaenormemente a vida do programador, como veremos mais adiante.

Listas

As listas formam o tipo de dados mais utilizado e versátil doPython. Listas são denidas como uma sequência de valores se-

Page 48: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

14 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

parados por vírgulas e delimitada por colchetes:

Listagem 1.15: Criando listas.

1 >>> l i s t a =[1 , ' a ' , ' pe ' ]2 >>> l i s t a3 [ 1 , ' a ' , ' pe ' ]4 >>> l i s t a [ 0 ]5 16 >>> l i s t a [ 2 ]7 ' pe '8 >>> l i s t a [−1]9 ' pe '

Na listagem 1.15, criamos uma lista de três elementos. Umalista é uma sequência ordenada de elementos, de forma que pode-mos selecionar elementos de uma lista por meio de sua posição.Note que o primeiro elemento da lista é lista[0]. Todas as con-tagens em Python começam em 0.

Uma lista também pode possuir elementos de tipos diferentes.Na listagem 1.15, o elemento 0 é um inteiro enquanto que os ou-tros elementos são strings. Para vericar isso, digite o comandotype(lista[0]).

Uma característica muito interessante das listas do Python, éque elas podem ser indexadas de trás para frente, ou seja, lista[-1]é o último elemento da lista. Como listas são sequências de tama-nho variável, podemos assessar os últimos n elementos, sem ter quecontar os elementos da lista.

Listas podem ser fatiadas, ou seja, podemos selecionar umaporção de uma lista que contenha mais de um elemento.

Listagem 1.16: Fatiando uma lista

1 >>> l i s t a =[ ' a ' , ' pe ' , ' que ' , 1 ]2 >>> l i s t a [ 1 : 3 ]3 [ ' pe ' , ' que ' ]

Page 49: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.4. ESTRUTURAS DE DADOS 15

4 >>> l i s t a [−1]5 16 >>> l i s t a [ 3 ]7 18 >>>

O comando lista[1:3], delimita uma fatia que vai do ele-mento 1 (o segundo elemento) ao elemento imediatamente anteriorao elemento 3. Note que esta seleção inclui o elemento correspon-dente ao limite inferior do intervalo, mas não o limite superior.Isto pode gerar alguma confusão, mas tem suas utilidades. Índicesnegativos também podem ser utilizados nestas expressões.

Para retirar uma fatia que inclua o último elemento, temos queusar uma variação deste comando seletor de intervalos:

Listagem 1.17: Selecionando o nal de uma lista.

1 >>> l i s t a [ 2 : ]2 [ ' que ' , 1 ]3 >>>

Este comando signica todos os elementos a partir do elemento2 (o terceiro), até o nal da lista. Este comando poderia ser uti-lizado para selecionar elementos do início da lista: lista[:3], sóque desta vez não incluindo o elemento 3 (o quarto elemento).

Se os dois elementos forem deixados de fora, são selecionadostodos os elementos da lista:

Listagem 1.18: selecionando todos os elementos de uma lista.

1 >>> l i s t a [ : ]2 [ ' a ' , ' pe ' , ' que ' , 1 ]3 >>>

Só que não é a mesma lista, é uma nova lista com os mesmoselementos. Desta forma, lista[:] é uma maneira de fazer umacópia completa de uma lista. Normalmente este recurso é utilizadojunto com uma atribuição a = lista[:].

Page 50: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

16 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

Listagem 1.19: Adicionando elementos a listas.

1 >>> l i s t a [ : ]2 [ ' a ' , ' pe ' , ' que ' , 1 ]3 >>> l i s t a . append (2 ) #ad i c i ona 2 ao f i n a l4 [ ' a ' , ' pe ' , ' que ' , 1 , 2 ]5 >>> l i s t a . i n s e r t ( 2 , [ ' a ' , ' b ' ] )6 >>> l i s t a7 [ ' a ' , ' pe ' , [ ' a ' , ' b ' ] , ' que ' , 1 , 2 ]8 >>>

As listas são conjuntos mutáveis, ao contrário de tuplas e strings,portanto pode-se adicionar(listagem 1.19), modicar ou remover(tabela 1.1) elementos de uma lista.

Tabela 1.1: Métodos de Listas.

Método Efeito

L.append(objeto) Adiciona um elemento ao nal da lista.L.count(elemento) Retorna o número de ocorrências do elemento.L.extend( list ) Concatena listas.L.index(value) Retorna índice da primeira ocorrência do valor.L. insert ( i , o) Insere objeto (o) antes de índice (i).L.pop([indice ]) Remove e retorna objeto no índice.

ou o último elemento.L.remove(value) remove primeira ocorrência do valor.L.reverse () Inverte lista. In situ

L.sort () Ordena lista. In locus

Note que as operações in situ não alocam memória extra paraa operação, ou seja, a inversão ou a ordenação descritas na tabela1.1, são realizadas no mesmo espaço de memória da lista original.Operações in situ alteram a variável em si sem fazer uma cópia damesma e, portanto não retornam nada.

O método L.insert insere um objeto antes da posição indicadapelo índice. Repare, na listagem 1.19, que o objeto em questão era

Page 51: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.4. ESTRUTURAS DE DADOS 17

uma lista, e o método insert não a fundiu com a lista original. Esteexemplo nos mostra mais um aspecto da versatilidade do objetolista, que pode ser composto por objetos de qualquer tipo.

Listagem 1.20: Estendendo uma lista.1 >>> l i s t a 2 =[ ' a ' , ' b ' ]2 >>> l i s t a . extend ( l i s t a 2 )3 >>> l i s t a4 [ ' a ' , ' pe ' , [ ' a ' , ' b ' ] , ' que ' , 1 , 2 , ' a ' , ' b

' ]

Já na listagem 1.20, os elementos da segunda lista são adicio-nados, individualmente, ao nal da lista original.

Listagem 1.21: Efetuando buscas em listas.1 >>> l i s t a . index ( ' que ' )2 33 >>> l i s t a . index ( ' a ' )4 05 >>> l i s t a . index ( ' z ' )6 Traceback (most r e c ent c a l l l a s t ) :7 F i l e "<input>" , l i n e 1 , in ?8 ValueError : l i s t . index (x ) : x not in l i s t9 >>> ' z ' in l i s t a

10 0

Conforme ilustrado na listagem 1.21, o método L.index retornao índice da primeira ocorrência do valor dado. Se o valor nãoexistir, o interpretador retorna um ValueError. Para testar se umelemento está presente em uma lista, pode-se utilizar o comandoin6 como ilustrado na listagem 1.21. Caso o elemento faça parteda lista, este comando retornará 1, caso contrário retornará 07.

6O inverso do operador in, é o operador not in e também é válido paratodas as sequências.

7Verdadeiro e falso: Em Python, quase qualquer coisa pode ser utilizadaem um contexto booleano, ou seja, como verdadeiro ou falso. Por exemplo 0 é

Page 52: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

18 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

Existem dois métodos básicos para remover elementos de umalista: L.remove e L.pop listagem 1.22. O primeiro remove oelemento nomeado sem nada retornar, o segundo elimina e retornao último ou o elemento da lista (se chamado sem argumentos), ou odeterminado pelo índice, passado como argumento (Listagem 1.22).

Listagem 1.22: Removendo elementos de uma lista.

1 >>> l i s t a . remove ( "que" )2 >>> l i s t a3 [ ' a ' , ' pe ' , [ ' a ' , ' b ' ] , 1 , 2 , ' a ' , ' b ' ]4 >>> l i s t a . pop (2 )5 [ ' a ' , ' b ' ]6 >>> l i s t a7 [ ' a ' , ' pe ' , 1 , 2 , ' a ' , ' b ' ]8 >>>

Operadores aritméticos também podem ser utilizados para ope-rações com listas. O operador de soma, +, concatena duas listas.O operador += é um atalho para o método L.extend conformemostrado na listagem 1.23.

Listagem 1.23: Operações com listas

1 >>> l i s t a =[ ' a ' , ' pe ' , 1 , 2 , ' a ' , ' b ' ]2 >>> l i s t a = l i s t a + [ ' novo ' , ' e lemento ' ]3 >>> l i s t a4 [ ' a ' , ' pe ' , 1 , 2 , ' a ' , ' b ' , ' novo ' , '

e lemento ' ]5 >>> l i s t a += ' do i s '6 >>> l i s t a7 [ ' a ' , ' pe ' , 1 , 2 , ' a ' , ' b ' , ' d ' , ' o ' , ' i ' , '

s ' ]8 >>> l i s t a += [ ' do i s ' ]

falso enquanto que todos os outros números são verdadeiros.Uma string, lista,dicionário ou tupla vazias sào falsas enquanto que as demais são verdadeiras.

Page 53: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.4. ESTRUTURAS DE DADOS 19

Listagem 1.24: Criando listas numéricas sequenciais.

1 >>> range (10)2 [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]3 >>> range (2 , 20 , 2 )#números pares4 [ 2 , 4 , 6 , 8 , 10 , 12 , 14 , 16 , 18 ]5 >>> range (1 , 20 , 2 )#números ímpares6 [ 1 , 3 , 5 , 7 , 9 , 11 , 13 , 15 , 17 , 19 ]

9 >>> l i s t a10 [ ' a ' , ' pe ' , 1 , 2 , ' a ' , ' b ' , ' d ' , ' o ' , ' i ' , '

s ' , ' do i s ' ]11 >>> l i =[1 ,2 ]12 >>> l i ∗313 [ 1 , 2 , 1 , 2 , 1 , 2 ]14 >>>

Note que a operação lista = lista + lista2 cria uma novalista enquanto que o comando += aproveita a lista original e aextende. Esta diferença faz com que o operador += seja muitomais rápido, especialmente para grandes listas. O operador demultiplicação, *, é um repetidor/concatenador de listas conformemostrado ao nal da listagem 1.23. A operação de multiplicaçãoin situ(*=) também é válida.

Um tipo de lista muito útil em aplicações cientícas, é listanumérica sequencial. Para construir estas listas podemos utilizar ocomando range (exemplo 1.24). O comando range aceita 1, 2 outrês argumentos: início, m e passo, respectivamente (ver exemplo1.24).

Page 54: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

20 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

Tuplas

Uma tupla, é uma lista imutável, ou seja, ao contrário de uma lista,após a sua criação, ela não pode ser alterada. Uma tupla é denidade maneira similar a uma lista, com exceção dos delimitadores doconjunto de elementos que no caso de uma tupla são parênteses(listagem 1.25).

Listagem 1.25: Denindo uma Tupla.

1 >>> tu = ( 'Genero ' , ' e s p e c i e ' , ' peso ' , 'e s t a g i o ' )

2 >>> tu [ 0 ]3 ' Genero '4 >>> tu [ 1 : 3 ]5 ( ' e s p e c i e ' , ' peso ' )6 >>>

Os elementos de uma tupla podem ser referenciados através deíndices, (posição) de forma idêntica a como é feito em listas. Tuplastambém podem ser fatiadas, gerando outras tuplas.

As tuplas não possuem métodos. Isto se deve ao fato de astuplas serem imutáveis. Os métodos append, extend, e pop natu-ralmente não se aplicam a tuplas, uma vez que não se pode adicio-nar ou remover elementos de uma tupla. Não podemos fazer buscaem tuplas, visto que não dispomos do método index. No entanto,podemos usar in para determinar se um elemento existe em umatupla, como se faz em listas.

Listagem 1.26: Outras formas de denir tuplas.

1 >>> tu=()2 >>> tu3 ( )4 >>> tu=' casa ' , #<−−Repare na v í r gu l a ao

f i n a l !5 >>> tu

Page 55: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.4. ESTRUTURAS DE DADOS 21

6 ( ' casa ' , )7 >>> tu=1 ,2 ,3 ,48 >>> tu9 (1 , 2 , 3 , 4)

10 >>> var =w, x , y , z11 >>> var12 (w, x , y , z )13 >>> var = tu14 >>> w15 116 >>> x17 218 >>> y19 320 >>> z21 4

Conforme exemplicado em 1.26, uma tupla vazia, é denidapela expressão (), já no caso de uma tupla unitária, isto é, com ape-nas um elemento, fazemos a atribuição com uma vírgula após o ele-mento, caso contrário (tu=('casa') ), o interpretador não poderádistinguir se os parênteses estão sendo utilizados como delimitado-res normais ou delimitadores de tupla. O comando tu=('casa',)

é equivalente ao apresentado na quarta linha da listagem 1.26, ape-nas mais longo.

Na sétima linha da listagem 1.26, temos uma extensão do con-ceito apresentado na linha anterior: a denição de uma tupla sema necessidade de parênteses. A este processo, se dá o nome de em-pacotamento de sequência. O empacotamento de vários elementossempre gera uma tupla.

As tuplas, apesar de não serem tão versáteis quanto as listas, sãomais rápidas. Portanto, sempre que se precisar de uma sequêncade elementos para servir apenas de referência, sem a necessidadede edição, deve-se utilizar uma tupla. Tuplas também são úteis na

Page 56: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

22 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

formatação de strings como veremos na listagem 1.28.Apesar das tuplas serem imutáveis, pode-se contornar esta li-

mitação fatiando e concatenando tuplas. Listas também podemser convertidas em tuplas, com a função tuple(lista), assimcomo tuplas podem ser convertidas em listas através da funçãolist(tupla).

Uma outra aplicação interessante para tuplas, mostrada na lis-tagem 1.26, é a atribuição múltipla, em que uma tupla de valores, éatribuída a uma lista de nomes de variáveis armazenados em umatupla. Neste caso, as duas sequências devem ter, exatamente, omesmo número de elementos.

Strings

Strings são um terceiro tipo de sequências em Python. Strings sãosequências de caracteres delimitados por aspas simples, 'string345'ou duplas "string". Todos os operadores discutidos até agora paraoutras sequências, tais como +, *, in, not in, s[i] e s[i:j], tam-bém são válidos para strings. Strings também podem ser denidascom três aspas (duplas ou simples). Esta última forma é utilizadapara denir strings contendo quebras de linha.

Listagem 1.27: Strings.

1 >>> st=' 123 de o l i v e i r a 4 '2 >>> len ( s t )3 164 >>> min( s t )5 ' '6 >>> max( s t )7 ' v '8 >>> texto = """ pr ime i ra l i nha9 segunda l i nha

10 t e r c e i r a l i nha """11 >>> print t exto

Page 57: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.4. ESTRUTURAS DE DADOS 23

12 pr ime i ra l i nha13 segunda l i nha14 t e r c e i r a l i nha

Conforme ilustrado na listagem 1.27, uma string é uma sequên-cia de quaisquer caracteres alfanuméricos, incluindos espaços. Afunção len(), retorna o comprimento da string, ou de uma listaou tupla. As funções min() e max() retornam o valor mínimo e omáximo de uma sequência, respectivamente. Neste caso, como asequência é uma string, os valores são os códigos ASCII de cadacaracter. Estes comandos também são válidos para listas e tuplas.

O tipo String possui 33 métodos distintos (na versão 2.2.1 doPython). Seria por demais enfadonho listar e descrever cada umdestes métodos neste capítulo. Nesta seção vamos ver alguns mé-todos de strings em ação no contexto de alguns exemplos. Outrosmétodos aparecerão em outros exemplos nos demais capítulos.

O uso mais comum dado a strings é a manipulação de textos quefazem parte da entrada ou saída de um programa. Nestes casos,é interessante poder montar strings, facilmente, a partir de outrasestruturas de dados. Em Python, a inserção de valores em stringsenvolve o marcador %s.

Listagem 1.28: Formatando strings.

1 >>> animal='Hamster 1 '2 >>> peso=983 >>> '%s : %s gramas ' % ( animal , peso )4 ' Hamster 1 : 98 gramas '

Na listagem 1.28, temos uma expressão de sintaxe não tão ób-via mas de grande valor na geração de strings. O operador % (mó-dulo), indica que os elementos da tupla seguinte serão mapeados,em sequência, nas posições indicadas pelos marcadores %s na string.

Esta expressão pode parecer uma complicação desnecessáriapara uma simples concatenação de strings. Mas não é. Vejamosporquê:

Page 58: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

24 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

Listagem 1.29: Problemas com a concatenação de strings.

1 >>> animal='Hamster 1 '2 >>> peso=983 >>> '%s : %s gramas ' % ( animal , peso )4 ' Hamster 1 : 98 gramas '5 >>> animal+' : '+peso+' gramas '6 Traceback (most r e c ent c a l l l a s t ) :7 F i l e "<input>" , l i n e 1 , in ?8 TypeError : cannot concatenate ' s t r ' and ' i n t

' ob j e c t s9 >>>

Pelo erro apresentado na listagem 1.29, vemos que a formataçãoda string utilizando o operador módulo e os marcadores %s, faz maisdo que apenas concatenar strings, também converte a variável peso(inteiro) em uma string.

Dicionários

O dicionário é um tipo de dado muito interessante do Python: Éuma estrutura que funciona como um banco de dados em minia-tura, no sentido de que seus elementos consistem de pares chave: valor, armazenados sem ordenação. Isto signica que não exis-tem índices para os elementos de um dicionário, a informação éacessada através das chaves.

Listagem 1.30: Criando e manipulando dicionários.

1 >>> Z= 'C ' : 1 2 , 'O ' : 1 6 , 'N ' : 1 2 , 'Na ' :402 >>> Z [ 'O' ]3 164 >>> Z [ 'H ' ]=15 >>> Z6 'Na ' : 40 , 'C ' : 12 , 'H ' : 1 , 'O ' : 16 , 'N ' :

12

Page 59: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.4. ESTRUTURAS DE DADOS 25

7 >>> Z . keys ( )8 [ 'Na ' , 'C ' , 'H ' , 'O ' , 'N ' ]9 >>> Z . has_key ( 'N ' )

10 1

As chaves podem ser de qualquer tipo imutável: números, strings,tuplas (que contenham apenas tipos imutáveis). Dicionários pos-suem os métodos listados na tabela 1.2.

Os conjuntos (chave:valor) são chamados de ítens do dicioná-rios. Esta terminologia é importante pois podemos acessar, sepa-radamente, chaves, valores ou ítens de um dicionário.

Os valores de um dicionário podem ser de qualquer tipo, núme-ros, strings, listas, tuplas e até mesmo outros dicionários. Tambémnão há qualquer restrição para o armazenamento de diferentes tiposde dados em um mesmo dicionário.

Conforme exemplicado em 1.30, pode-se adicionar novos ítensa um dicionário, a qualquer momento, bastando atribuir um valora uma chave. Contudo, é preciso ter cuidado. Se você tentar criarum ítem com uma chave que já existe, o novo ítem substituirá oantigo.

Os métodos D.iteritems(), D.iterkeys() e D.itervalues()

criam iteradores. Iteradores permitem iterar através dos ítens, cha-ves ou valores de um dicionário. Veja a listagem 1.31:

Listagem 1.31: Iterando dicionários.

1 >>> Z . items ( )2 [ ( 'Na ' , 40) , ( 'C ' , 12) , ( 'H ' , 1) , ( 'O ' , 16) ,

( 'N ' , 12) ]3 >>> i=Z . i t e r i t em s ( )4 >>> i5 <dic t i onary−i t e r a t o r ob j e c t at 0x8985d00>6 >>> i . next ( )7 ( 'Na ' , 40)8 >>> i . next ( )

Page 60: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

26 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

Tabela 1.2: Métodos de Dicionários.

Método Efeito

D.clear() Remove todos os itens do dicionário.D.copy() Cria uma cópia de um dicionário.D.get(k[,d]) Retorna D[k], se a chave k existir. Senão, d.D.has_key(k) Retorna 1 se D possuir a chave k.D.items() Retorna lista de tuplas (chave:valor).D.iteritems() Retorna objeto iterador para D.D.iterkeys() Idem para chaves.D. itervalues () Idem para valores.D.keys() Retorna lista com todas as chaves.D.popitem() Remove e retorna um ítem (chave:valor).D.update(E) Copia itens de E para D.D.values() Retorna lista com todas os valores.

9 ( 'C ' , 12)10 >>> # e assim por d iante . . .11 >>> k=Z . i t e r k e y s ( )12 >>> k . next ( )13 'Na '14 >>> k . next ( )15 'C '16 >>> k . next ( )17 'H '18 >>> k . next ( )19 'O '20 >>> k . next ( )21 'N '22 >>> k . next ( )23 Traceback (most r e c ent c a l l l a s t ) :24 F i l e "<input>" , l i n e 1 , in ?25 S top I t e r a t i on

Page 61: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.4. ESTRUTURAS DE DADOS 27

O uso de iteradores é interessante quando se precisa acessaro conteúdo de um dicionário, elemento-a-elemento, sem repetição.Ao nal da iteração, o iterador retorna um aviso: StopIteration.

Conjuntos

Rearmando sua vocação cientíca, a partir da versão 2.4, umaestrutura de dados para representar o conceito matemático de con-junto foi introduzida na linguagem Python. Um conjunto no Pythoné uma coleção de elementos sem ordenação e sem repetições. Oobjeto conjunto em Python aceita operações matemáticas de con-juntos tais como união, interseção, diferença e diferença simétrica(exemplo 1.4).

1 >>> a = se t ( ' p i rapora ' )2 >>> b = se t ( ' paranapanema ' )3 >>> a #l e t r a s em a4 s e t ( [ ' i ' , ' p ' , ' r ' , ' a ' , ' o ' ] )5 >>> a − b #Letras em a mas não em b6 s e t ( [ ' i ' , ' o ' ] )7 >>> a | b #l e t r a s em a ou b8 s e t ( [ ' a ' , ' e ' , ' i ' , 'm' , ' o ' , ' n ' , ' p ' , ' r '

] )9 >>> a & b #l e t r a s em a e b

10 s e t ( [ ' a ' , ' p ' , ' r ' ] )11 >>> a ^ b #l e t r a s em a ou b mas não em ambos12 s e t ( [ ' i ' , 'm' , ' e ' , ' o ' , ' n ' ] )

No exemplo 1.4 pode-se observar as seguintes correspondências en-tre a notação do Python e a notação matemática convencional:

a - b: A−B8

a | b: A ∪B

8Por convenção representa-se conjuntos por letras maiúsculas.

Page 62: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

28 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

a & b: A ∩B

aˆb: (A ∪B)− (A ∩B)

1.5 Controle de uxo

Em condições normais o interpretador executa as linhas de umprograma uma a uma. As exceções a este caso são linhas perten-centes à denição de função e classe, que são executadas apenasquando a respectiva função ou classe é chamada. Entretanto algu-mas palavras reservadas tem o poder de alterar a direção do uxode execução das linhas de um programa.

Condições

Toda linguagem de programação possui estruturas condicionais quenos permitem representar decisões: se isso, faça isso, caso contráriofaça aquilo. Estas estruturas também são conhecidas por ramica-ções. O Python nos disponibiliza três palavras reservadas para estem: if , elif e else. O seu uso é melhor demonstrado através deum exemplo (Listagem 1.32).

Listagem 1.32: Exemplo do emprego de ramicações.

1 i f a == 1 :2 #es t e b loco é executado se a f o r 13 pass4 e l i f a == 2 :5 #es t e b loco é executado se a f o r 26 pass7 else :8 #es t e b loco é executado se9 #se se nenhum dos b loco s

10 #an t e r i o r e s t i v e r s i do executado11 pass

Page 63: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.5. CONTROLE DE FLUXO 29

No exemplo 1.32, vemos também emprego da palavra reservadapass, que apesar de não fazer nada é muito útil quando ainda nãosabemos quais devem ser as consequências de determinada condi-ção.

Uma outra forma elegante e compacta de implementar umaramicação condicional da execução de um programa é através dedicionários (Listagem 1.33). As condições são as chaves de umdicionário cujos valores são funções. Esta solução não contempla oelse, porém.

Listagem 1.33: Implementando a funcionalidade de if e elif pormeio de um dicionário.

1 de s f e cho s = 1 : fun1 , 2 : fun22 de s f e cho s [ a ]

Iteração

Muitas vezes em problemas computacionais precisamos executaruma tarefa, repetidas vezes. Entretanto não desejamos ter que es-crever os mesmos comandos em sequência, pois além de ser umatarefa tediosa, iria transformar nosso belo programa em algo si-milar a uma lista telefônica. A solução tradicional para resolvereste problema é a utilização de laços (loops) que indicam ao inter-pretador que ele deve executar um ou mais comandos um númeroarbitrário de vezes. Existem vários tipos de laços disponíveis noPython.

O laço while: O laço while repete uma tarefa enquanto umacondição for verdadeira (Listagem 1.34). Esta tarefa consiste emum ou mais comandos indentados em relação ao comando que iniciao laço. O m da indentação indica o m do bloco de instruçõesque deve ser executado pelo laço.

Page 64: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

30 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

Listagem 1.34: Comandos de laço no Python.

1 >>> while True :2 pass#repe t e inde f in idamente3 >>> i=04 >>> while i < 10 :5 i +=16 print i7 # sa ida omit ida8 >>> for i in range (1 ) :9 print i

O laço for: O laço for nos permite iterar sobre uma sequên-cia atribuindo os elementos da mesma a uma variável, sequencial-mente, à medida que prossegue. Este laço se interrompe automa-ticamente ao nal da sequência.

Iteração avançada: O Python nos oferece outras técnicas deiteração sobre sequências que podem ser bastante úteis na redu-ção da complexidade do código. No exemplo 1.31 nós vimos quedicionários possuem métodos especícos para iterar sobre seus com-ponentes. Agora suponhamos que desejássemos iterar sobre umalista e seu índice?

Listagem 1.35: A função enumerate.

1 >>> for n , e in enumerate ( [ ' a ' , ' b ' , ' c ' , ' d ' , ' e' ] ) :

2 print "%s : %s "%(n , e )3

4 0 : a5 1 : b6 2 : c7 3 : d8 4 : e

Page 65: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.5. CONTROLE DE FLUXO 31

A função enumerate (exemplo 1.35) gera um iterador similar aovisto no exemplo 1.31. O laço for chama o método next deste ite-rador repetidas vezes, até que receba a mensagem StopIteration

(ver exemplo 1.31).O comando zip nos permite iterar sobre um conjunto de seqûen-

cias pareando sequencialmente os elementos das múltiplas listas(exemplo 1.36).

Listagem 1.36: Iterando sobre mais de uma sequência.

1 >>> perguntas = [ 'nome ' , ' cargo ' , ' pa r t ido ' ]2 >>> re spo s t a s = [ ' Lula ' , ' Pre s idente ' , 'PT ' ]3 >>> for p , r in z ip ( perguntas , r e s po s t a s ) :4 print " qual o seu %s ? %s"%(p , r )5

6

7 qual o seu nome? Lula8 qual o seu cargo ? Pre s idente9 qual o seu par t ido ? PT

Podemos ainda desejar iterar sobre uma sequência em ordemreversa (exemplo 1.5), ou iterar sobre uma sequência ordenada semalterar a sequência original (exemplo 1.37). Note que no exemplo1.37, a lista original foi convertida em um conjunto (set) paraeliminar as repetições.

1 >>> for i in r eve r s ed ( range (5 ) ) :2 print i3 44 35 26 17 0

Listagem 1.37: Iterando sobre uma sequência ordenada.

1 >>> for i in so r t ed ( s e t ( l ) ) :

Page 66: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

32 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

2 print i3 l a r an j a4 l e i t e5 manga6 ovos7 uva

Iterações podem ser interrompidas por meio da palavra reser-vada break. Esta pode ser invocada quando alguma condição seconcretiza. Podemos também saltar para a próxima iteração (semcompletar todas as instruções do bloco) por meio da palavra re-servada continue. A palavra reservada else também pode seraplicada ao nal de um bloco iterativo. Neste caso o bloco denidopor else só será executado se a iteração se completar normalmente,isto é, sem a ocorrência de break.

Lidando com erros: Exceções

O método da tentativa e erro não é exatamente aceito na ortodoxiacientíca mas, frequentemente, é utilizado no dia a dia do trabalhocientíco. No contexto de um programa, muitas vezes somos força-dos a lidar com possibilidades de erros e precisamos de ferramentaspara lidar com eles.

Muitas vezes queremos apenas continuar nossa análise, mesmoquando certos erros de menor importância ocorrem; outras vezes,o erro é justamente o que nos interessa, pois nos permite examinarcasos particulares onde nossa lógica não se aplica.

Como de costume o Python nos oferece ferramentas bastanteintuitivas para interação com erros9.

Listagem 1.38: Exemplo de uma exceção1 >>> 1/0

9Os erros tratados nesta seção não são erros de sintaxe mas erros queocorrem durante a execução de programas sintaticamente corretos. Estes errosserão denomidados exceções

Page 67: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.5. CONTROLE DE FLUXO 33

2 Traceback (most r e c ent c a l l l a s t ) :3 F i l e "<std in>" , l i n e 1 , in ?4 ZeroDiv i s i onError : i n t e g e r d i v i s i o n or

modulo by zero

Suponhamos que você escreva um programa que realiza divisõesem algum ponto, e dependendo dos dados fornecidos ao programa,o denominador torna-se zero. Como a divisão por zero não é possí-vel, o seu programa para, retornando uma mensagem similar a dalistagem 1.38. Caso você queira continuar com a execução do pro-grama apesar do erro, poderíamos solucionar o problema conformeo exposto na listagem 1.39

Listagem 1.39: Contornando uma divisão por zero

1 >>> for i in range (5 ) :2 . . . try :3 . . . q=1./ i4 . . . print q5 . . . except ZeroDiv i s i onError :6 . . . print "Div i são por zero ! "7 . . .8 Divi são por zero !9 1 .0

10 0 .511 0.33333333333312 0 .25

A construção try:...except: nos permite vericar a ocorrên-cia de erros em partes de nossos programas e responder adequa-damente a ele. o Python reconhece um grande número de tiposde exceções, chamadas built-in exceptions. Mas não precisamossabê-las de cor, basta causar o erro e anotar o seu nome.

Certas situações podem estar sujeitas à ocorrência de mais deum tipo de erro. neste caso, podemos passar uma tupla de exceçõespara a palavra-chave except: except (NameError, ValueError,IOError):pass,

Page 68: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

34 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

ou simplesmente não passar nada: except: pass. Pode aconte-cer ainda que queiramos lidar de forma diferente com cada tipo deerro (listagem 1.40).

Listagem 1.40: Lidando com diferentes tipos de erros.

1 >>> try :2 f = open ( ' arq . txt ' )3 s = f . r e ad l i n e ( )4 i = i n t ( s . s t r i p ( ) )5 except IOError , ( errno , s t r e r r o r ) :6 print "Erro de I /O (%s ) : %s " % (

errno , s t r e r r o r )7 except ValueError :8 print "Não f o i p o s s í v e l conve r t e r o

dado em I n t e i r o . "9 except :

10 print "Erro desconhec ido . "

A construção try:...except: acomoda ainda uma cláusulaelse opcional, que será executada sempre que o erro esperado nãoocorrer, ou seja, caso ocorra um erro imprevisto a cláusula else

será executada (ao contrário de linhas adicionais dentro da cláusulatry).

Finalmente, try permite uma outra cláusula opcional, finally,que é sempre executada (quer haja erros quer não). Ela é util paratarefas que precisam ser executadas de qualquer forma, como fechararquivos ou conexões de rede.

1.6 Funções

No Python, uma função é um bloco de código denido por umcabeçalho especíco e um conjunto de linhas indentadas, abaixodeste. Funções, uma vez denidas, podem ser chamadas de qual-quer ponto do programa (desde que pertençam ao espaço de no-

Page 69: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.6. FUNÇÕES 35

mes). Na verdade, uma diferença fundamental entre uma função eoutros objetos é o fato de ser chamável. Isto decorre do fato de to-das as funções possuirem um método10 chamado __call__. Todosos objetos que possuam este método poderão ser chamados11.

O ato de chamar um objeto, em Python, é caracterizado pelaaposição de parênteses ao nome do objeto. Por exemplo: func().Estes parênteses podem ou não conter argumentos. Continuelendo para uma explicação do que são argumentos.

Funções também possuem seu próprio espaço de nomes, ou seja,todas as variáveis denidas no escopo de uma função só existemdentro desta. Funções são denidas pelo seguinte cabeçalho:

1 def nome( par1 , par2 , par3=va l o rd e f au l t , ∗args , ∗∗kwargs ) :

A palavra reservada def indica a denição de uma função; emseguida deve vir o nome da função que deve seguir as regras deformação de qualquer nome em Python. Entre parênteses vem,opcionalmente, uma lista de argumentos que serão ser passadospara a função quando ela for chamada. Argumentos podem tervalores default se listados da forma a=1. Argumentos com valoresdefault devem vir necessariamente após todos os argumentos semvalores default(Listagem 1.41).

Listagem 1.41: Denindo uma função com um argumento obriga-tório e outro opcional (com valor default").

1 >>> def fun (a , b=1) :2 . . . print a , b3 . . .4 >>> fun (2)5 2 1

10Veja o capítulo 2 para uma explicação do que são métodos.11O leitor, neste ponto deve estar imaginando todo tipo de coisas inte-

ressantes que podem advir de se adicionar um método __call__ a objetosnormalmente não chamáveis.

Page 70: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

36 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

6 >>> fun (2 , 3 )7 2 38 fun (b=5 ,2)9 SyntaxError : non−keyword arg a f t e r keyword

arg

Por m, um número variável de argumentos adicionais pode serprevisto através de argumentos precedidos por * ou **. No exemploacima, argumentos passados anonimamente (não associados a umnome) serão colocados em uma tupla de nome t, e argumentospassados de forma nominal (z=2,q='asd')serão adicionados a umdicionário, chamado d(Listagem 1.42).

Listagem 1.42: lista de argumentos variável

1 >>> def fun (∗ t , ∗∗d) :2 print t , d3 >>> fun (1 ,2 , c=2,d=4)4 ( 1 , 2 ) ' c ' : 3 , ' d ' : 4

Funções são chamadas conforme ilustrado na linha 3 da listagem1.42. Argumentos obrigatórios, sem valor default, devem ser pas-sados primeiro. Argumentos opcionais podem ser passados fora deordem, desde que após os argumentos obrigatórios, que serão atri-buídos sequencialmente aos primeiros nomes da lista denida nocabeçalho da função(Listagem 1.41).

Muitas vezes é conveniente desempacotar os argumentos pas-sados para uma função a partir de uma tupla ou dicionário.

Listagem 1.43: Desempacotando argumentos.

1 >>> def fun (a , b , c , d ) :2 print a , b , c , d3 >>> t=(1 ,2) ; d i = 'd ' : 3 , ' c ' : 44 >>> fun (∗ t ,∗∗ di )5 1 2 4 3

Page 71: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.6. FUNÇÕES 37

Argumentos passados dentro de um dicionário podem ser utili-zados simultâneamente para argumentos de passagem obrigatória(declarados no cabeçalho da função sem valor default) e para ar-gumentos opcionais, declarados ou não(Listagem 1.44).

Listagem 1.44: Passando todos os argumentos por meio de umdicionário.

1 >>> def fun2 (a , b=1 ,∗∗ outros ) :2 . . . print a , b , outros3 . . .4 >>> dic = ' a ' : 1 , ' b ' : 2 , ' c ' : 3 , ' d ' : 45 >>> fun2 (∗∗ d i c )6 1 2 ' c ' : 3 , ' d ' : 4

Note que no exemplo 1.44, os valores cujas chaves correspon-dem a argumentos declarados, são atribuídos a estes e retirados dodicionário, que ca apenas com os ítens restantes.

Funções podem retornar valores por meio da palavra reservadareturn.

Listagem 1.45: Retornando valores a partir de uma função.

1 >>> def soma(a , b) :2 return a+b3 print " ignorado ! "4 >>> soma (3 , 4 )5 7

A palavra return indica saída imediata do bloco da função le-vando consigo o resultado da expressão à sua direita.

Funções lambda

Funções lambda são pequenas funções anônimas que podem serdenidas em apenas uma linha. Por denição, podem conter umaúnica expressão.

Page 72: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

38 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

Listagem 1.46: Funções lambda

1 >>> def r a i z (n) :#de f i n indo uma r a i z de ordemn

2 return lambda( x ) : x ∗∗ (1 . / n)3 >>> r4 = r a i z (4 )#r4 c a l c u l a a r a i z de ordem

44 >>> r4 (16) #u t i l i z a ndo5 2

Observe no exemplo (1.46), que lambda lembra a denição devariáveis do espaço de nome em que foi criada. Assim, r4 passaa ser uma função que calcula a raiz quarta de um número. Esteexemplo nos mostra que podemos modicar o funcionamento deuma função durante a execução do programa: a função raiz retornauma função raiz de qualquer ordem, dependendo do argumento quereceba.

Geradores

Geradores são um tipo especial de função que retém o seu estadode uma chamada para outra. São muito convenientes para criariteradores, ou seja, objetos que possuem o método next().

Listagem 1.47: Geradores

1 >>> def l e t r a s ( pa lavra ) :2 for i in palavra :3 y i e l d i4 >>> for L in l e t r a s ( ' gato ' ) : print L5 g6 a7 t8 o

Como vemos na listagem 1.47 um gerador é uma função sobrea qual podemos iterar.

Page 73: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.6. FUNÇÕES 39

Decoradores

Decoradores são uma alteração da sintaxe do Python, introdu-zida a partir da versão 2.4, para facilitar a modicação de funções(sem alterá-las), adicionando funcionalidade. Nesta seção vamosilustrar o uso básico de decoradores. Usos mais avançados po-dem ser encontrados nesta url: http://wiki.python.org/moin/

PythonDecoratorLibrary.

Listagem 1.48: Decorador básico.

1 def faznada ( f ) :2 def novaf (∗ args ,∗∗ kwargs ) :3 print "chamando . . . " , args , kwargs4 return f (∗ args ,∗∗ kwargs )5 novaf .__name__ = f .__name__6 novaf .__doc__ = f .__doc__7 novaf .__dict__ . update ( f .__dict__)8 return novaf

Na listagem 1.48, vemos um decorador muito simples. Comoseu nome diz, não faz nada, além de ilustrar a mecânica de um de-corador. Decoradores esperam um único argumento: uma função.A listagem 1.49, nos mostra como utilizar o decorador.

Listagem 1.49: Utilizando um decorador

1 >>>@faznada2 def soma(a , b) :3 return a+b4

5 >>> soma (1 , 2 )6 chamando . . . (1 , 2) 7 Out [ 5 ] : 3

O decorador da listagem 1.48, na verdade adiciona uma linhade código à função que decora: print "chamando...",args,kwargs.

Page 74: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

40 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

Repare que o decorador da listagem 1.48, passa alguns atribu-tos básicos da função original para a nova função, de forma quea função decorada possua o mesmo nome, docstring, etc. que afunçao original. No entanto, esta passagem de atributos poluio código da função decoradora. Podemos evitar a poluição e otrabalho extra utilizando a funcionalidade do módulo functools.

Listagem 1.50: Limpando a geração de decoradores

1 >>> from f u n c t o o l s import wraps2 >>> def meuDecorador ( f ) :3 . . . @wraps ( f )4 . . . def novaf (∗ args , ∗∗kwds ) :5 . . . print 'Chamando funcao

decorada '6 . . . return f (∗ args , ∗∗kwds )7 . . . return novaf8 . . .9 >>> @meuDecorador

10 . . . def exemplo ( ) :11 . . . """Docstr ing """12 . . . print ' funcao exemplo

executada ! '13 . . .14 >>> exemplo ( )15 Chamando funcao decorada16 funcao exemplo executada !17 >>> exemplo .__name__18 ' exemplo '19 >>> exemplo .__doc__20 ' Docstr ing '

Decoradores nao adicionam nenhuma funcionalidade nova aoque já é possível fazer com funções, mas ajudam a organizar ocódigo e reduzir a necessidade duplicação. Aplicações cientícas

Page 75: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.6. FUNÇÕES 41

de decoradores são raras, mas a sua presença em pacotes e módu-los de utilização genérica vem se tornando cada vez mais comum.Portanto, familiaridade com sua sintaxe é aconselhada.

Strings de Documentação

Strings posicionadas na primeira linha de uma função, ou seja,diretamente abaixo do cabeçalho, são denominadas strings de do-cumentação, ou simplesmente docstrings.

Estas strings devem ser utilizadas para documentar a funçãoexplicitando sua funcionalidade e seus argumentos. O conteúdo deuma docstring está disponível no atributo __doc__ da função.

Ferramentas de documentação de programas em Python ex-traem estas strings para montar uma documentação automáticade um programa. A função help(nome_da_função) também re-torna a docstring. Portanto a inclusão de docstrings auxilia tantoo programador quanto o usuário.

Listagem 1.51: Usando Docstrings

1 >>> def soma(a , b) :2 """3 Esta funcao soma do i s numeros :4 >>> soma (2 , 3 )5 56 """7 return a+b8 >>> help ( soma)9 Help on func t i on soma in module __main__:

10

11 soma(a , b)12 Esta funcao soma do i s numeros :13 >>> soma (2 , 3 )14 5

Page 76: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

42 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

No exemplo 1.51, adicionamos uma docstring explicando a na-lidade da função soma e ainda incluímos um exemplo. Incluir umexemplo de uso da função cortado e colado diretamente do consolePython (incluindo o resultado), nos permitirá utilizar o módulodoctest para testar funções, como veremos mais adiante.

1.7 Módulos e Pacotes

Para escrever programas de maior porte ou agregar coleções defunções e/ou objetos criados pelo usuário, o código Python podeser escrito em um arquivo de texto, salvo com a terminação .py,facilitando a re-utilização daquele código. Arquivos com códigoPython contruídos para serem importados, são denominados mó-dulo. Existem algumas variações na forma de se importar módu-los. O comando import meumodulo cria no espaço de nomes umobjeto com o mesmo nome do módulo importado. Funções, classes(ver capítulo 2) e variáveis denidas no módulo são acessíveis comoatributos deste objeto. O comando from modulo import * im-porta todas as funções e classes denidas pelo módulo diretamentepara o espaço de nomes global12 do nosso script. Deve ser utilizadocom cuidado pois nomes iguais pré-existentes no espaço de nomesglobal serão redenidos. Para evitar este risco, podemos substituiro * por uma sequência de nomes correspondente aos objetos quedesejamos importar: from modulo import nome1, nome2. Pode-mos ainda renomear um objeto ao importá-lo: import numpy as

N ou ainda from numpy import det as D.Seja um pequeno módulo como o do exemplo 1.52. Podemos

importar este módulo em uma sessão do interpretador iniciada nomesmo diretório que contém o módulo (exemplo 1.7).

1 >>> import f i b o

12Dicionário de nomes de variáveis e funções válidos durante a execução deum script

Page 77: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.7. MÓDULOS E PACOTES 43

Listagem 1.52: Módulo exemplo

1 # Disponvel no pacote de programas como :f i b o . py

2 #modulo para c a l c u l a r a s e r i e de f i b on a c c iate o numero n .

3

4 def f i b (n) :5 a , b = 0 , 16 while b < n :7 print b ,8 a , b = b , a+b9

10 i f __name__=="__main__" :11 import sys12 print __name__13 print sys . argv14 f i b ( i n t ( sys . argv [ 1 ] ) )

2 >>> f i b o . f i b (50)3 1 1 2 3 5 8 13 21 344 >>> f i b o .__name__5 ' f i b o '

Note que a função declarada em fibo.py é chamada como ummétodo de fibo. Isto é porque módulos importados são objetos(como tudo o mais em Python).

Quando um módulo é importado ou executado diretamente ,torna-se um objeto com um atributo __name__. O conteúdo desteatributo depende de como o módulo foi executado. Se foi executadopor meio de importação, __name__ é igual ao nome do módulo(sem a terminação .py). Se foi executado diretamente (pythonmodulo.py), __name__ é igual a __main__.

Page 78: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

44 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

Durante a importação de um módulo, todo o código contido nomesmo é executado, entretanto como o __name__ de bo é fiboe não __main__, as linhas abaixo do if não são executadas.Qual então a função destas linhas de código? Módulos podem serexecutados diretamente pelo interpretador, sem serem importadosprimeiro. Vejamos isso no exemplo 1.53. Podemos ver que agorao __name__ do módulo é __main__ e, portanto, as linhas decódigo dentro do bloco if são executadas. Note que neste casoimportamos o módulo sys, cujo atributo argv nos retorna umalista com os argumentos passados para o módulo a partir da posição1. A posição 0 é sempre o nome do módulo.

Listagem 1.53: Executing a module from the console.

1 $ python f i b o . py 602 __main__3 [ ' f i b o . py ' , ' 6 0 ' ]4 1 1 2 3 5 8 13 21 34 55

Qualquer arquivo com terminação .py é considerado um mó-dulo Python pelo interpretador Python. Módulos podem ser exe-cutados diretamente ou importados por outros módulos.

A linguagem Python tem como uma de suas principais vanta-gens uma biblioteca bastante ampla de módulos, incluída com adistribuição básica da linguagem. Nesta seção vamos explorar al-guns módulos da biblioteca padrão do Python, assim como outros,módulos que podem ser obtidos e adicionados à sua instalação doPython.

Para simplicidade de distribuição e utilização, módulos podemser agrupados em pacotes. Um pacote nada mais é do que umdiretório contendo um arquivo denominado __init__.py (este ar-quivo não precisa conter nada). Portanto, pode-se criar um pacotesimplesmente criando um diretório chamado, por exemplo, pacotecontendo os seguintes módulos: modulo1.py e modulo2.py13. Um

13Além de __init__.py, naturalmente.

Page 79: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.7. MÓDULOS E PACOTES 45

pacote pode conter um número arbitrário de módulos, assim comooutros pacotes.

Como tudo o mais em Python, um pacote também é um objeto.Portanto, ao importar o pacote pacote em uma sessão Python,modulo1 e modulo2 aparecerão como seus atributos (listagem 1.54).

Listagem 1.54: importing a package

1 >>> import pacote2 >>> d i r ( pacote )3 [ ' modulo1 ' , 'modulo2 ' ]

Pacotes Úteis para Computação Cientíca

Numpy

Um dos pacotes mais importantes, senão o mais importante paraquem deseja utilizar o Python em computação cientíca, é o numpy.Este pacote contém uma grande variedade de módulos voltadospara resolução de problemas numéricos de forma eciente.

Exemplos de objetos e funções pertencentes ao pacote numpy

aparecerão regularmente na maioria dos exemplos deste livro. Umalista extensiva de exemplos de Utilização do Numpy pode ser con-sultada neste endereço: http://www.scipy.org/Numpy_Example_List

Na listagem 1.55, vemos um exemplo de uso típico do numpy. Onumpy nos oferece um objeto matriz, que visa representar o conceitomatemático de matriz. Operações matriciais derivadas da algebralinear, são ainda oferecidas como funções através do subpacote li-nalg (Listagem 1.55).

Listagem 1.55: Calculando e mostrando o determinante de umamatriz.

1 >>> from numpy import ∗2 >>> a = arange (9 )

Page 80: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

46 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

3 >>> print a4 [ 0 1 2 3 4 5 6 7 8 ]5 >>> a . shape =(3 ,3)6 >>> print a7 [ [ 0 1 2 ]8 [ 3 4 5 ]9 [ 6 7 8 ] ]

10 >>> from numpy . l i n a l g import det11 >>> det ( a )12 0 .013 >>>

Na primeira linha do exemplo 1.55, importamos todas as fun-ções e classes denidas no módulo numpy.

Na segunda linha, usamos o comando arange(9) para criarum vetor a de 9 elementos. Este comando é equivalente ao range

para criar listas, só que retorna um vetor (matriz unidimensional).Note que este vetor é composto de números inteiros sucessivos co-meçando em zero. Todas as enumerações em Python começamem zero. Como em uma lista, a[0] é o primeiro elemento do ve-tor a. O objeto que criamos, é do tipo array, denido no mó-dulo numpy. Uma outra forma de criar o mesmo objeto seria: a =

array([0,1,2,3,4,5,6,7,8]).Na terceira linha, nós mostramos o conteúdo da variável a com

o comando print. Este comando imprime na tela o valor de umavariável.

Como tudo em Python é um objeto, o objeto array apresentadiversos métodos e atributos. O atributo chamado shape contém oformato da matriz como uma tupla, que pode ser multi-dimensionalou não. Portanto, para converter vetor a em uma matriz 3×3, bastaatribuir o valor (3,3) a shape. Conforme já vimos, atributos emétodos de objetos são referenciados usando-se esta notação deponto14.

14nome_da_variável.atributo

Page 81: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.8. DOCUMENTANDO PROGRAMAS 47

Na quinta linha, usamos o comando print para mostrar a al-teração na forma da variável a.

Na sexta linha importamos a função det do módulo numpy.linalgpara calcular o determinante da nossa matriz. A função det(a) nosinforma, então, que o determinante da matriz a é 0.0.

Scipy

Outro módulo muito útil para quem faz computação numérica comPython, é o scipy. O scipy depende do numpy e provê umagrande coleção de rotinas numéricas voltadas para aplicações emmatemática, engenharia e estatística.

Diversos exemplos da segunda parte deste livro se utilizarãodo scipy, portanto, não nos extenderemos em exemplos de uso doscipy.

Uma lista extensa de exemplos de utilização do scipy pode serencontrada no seguinte endereço:http://www.scipy.org/Documentation.

1.8 Documentando Programas

Parte importante de um bom estilo de trabalho em computação ci-entíca é a documentação do código produzido. Apesar do Pythonser uma linguagem bastante clara e de fácil leitura por humanos,uma boa dose de documentação é sempre positiva.

O Python facilita muito a tarefa tanto do documentador quantodo usuário da documentação de um programa. Naturalmente, otrabalho de documentar o código deve ser feito pelo programador,mas todo o resto é feito pela própria linguagem.

A principal maneira de documentar programas em Python éatravés da adição de strings de documentação (docstrings) a fun-ções e classes ao redigir o código. Módulos também podem possuirdocstrings contendo uma sinopse da sua funcionalidade. Estasstrings servem não somente como referência para o próprio progra-mador durante o desenvolvimento, como também como material

Page 82: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

48 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

para ferramentas de documentação automática. A principal ferra-menta de documentação disponível para desenvolvedores é o pydoc,que vem junto com a distribuição da linguagem.

Pydoc

O pydoc é uma ferramenta que extrai e formata a documentaçãode programas Python. Ela pode ser utilizada de dentro do consoledo interpretador Python, ou diretamente do console do Linux.

1 $ pydoc pydoc

No exemplo acima, utilizamos o pydoc para examinar a documen-tação do próprio módulo pydoc. Podemos fazer o mesmo paraacessar qualquer módulo disponível no PYTHONPATH.

O pydoc possui algumas opções de comando muito úteis:

-k <palavra> Procura por palavras na documentação de todosos módulos.

-p <porta> <nome> Gera a documentação em html iniciandoum servidor HTTP na porta especicada da máquina local.

-g Útil para sistemas sem fácil acesso ao console, inicia um servidorHTTP e abre uma pequena janela para busca.

-w <nome> escreve a documentação requisitada em formato HTML,no arquivo <nome>.html, onde <nome> pode ser um móduloinstalado na biblioteca local do Python ou um módulo ou pa-cote em outra parte do sistema de arquivos. Muito útil paragerar documentação para programas que criamos.

Além do pydoc, outras ferramentas mais sosticadas, desen-volvidas por terceiros, estão disponíveis para automatizar a docu-mentação de programas Python. Exploraremos uma alternativa aseguir.

Page 83: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

1.8. DOCUMENTANDO PROGRAMAS 49

Epydoc

O Epydoc é uma ferramenta consideravelmente mais sosticada doque o módulos pydoc. Além de prover a funcionalidade já demon-trada para o pydoc, oferece outras facilidades como a geração dadocumentação em formato PDF ou HTML e suporte à formatação dasdocstrings.

O uso do Epydoc é similar ao do pydoc. Entretanto, devidoà sua maior versatilidade, suas opções são bem mais numerosas(1.56).

Listagem 1.56: Listando as opções do Epydoc.

1 $ epydoc −h

Não vamos discutir em detalhes as várias opções do Epydoc

pois estas encontram-se bem descritas na página man do programa.Ainda assim, vamos comentar algumas funcionalidades interessan-tes.

A capacidade de gerar a documentação em LATEX, facilita acustomização da mesma pelo usuário e a exportação para outrosformatos. A opção url, nos permite adicionar um link para owebsite de nosso projeto ao cabeçalho da documentação. O Epydoc

também verica o quão bem nosso programa ou pacote encontra-se documentado. Usando-se a opção check somos avisados sobretodos os objetos não documentados.

A partir da versão 3.0, o Epydoc adiciona links para o códigofonte na íntegra, de cada elemento de nosso módulo ou pacote. Aopção graph pode gerar três tipos de grácos sobre nosso pro-grama, incluindo um diagrama UML(Figura 1.1).

Dada toda esta funcionalidade, vale apena conferir o Epydoc15.

15http://epydoc.sourceforge.net

Page 84: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

50 CAPÍTULO 1. FUNDAMENTOS DA LINGUAGEM

Figura 1.1: Versão HTML da documentação gerada pelo Epydoc.

1.9 Exercícios

1. Repita a iteração do exemplo 1.35 sem utilizar a função enu-merate. Execute a iteração do objeto gerado por enumeratemanualmente, sem o auxílio do laço for e observe o seu re-sultado.

2. Adicione a funcionalidade else à listagem 1.33 utilizandoexceções.

3. Escreva um exemplo de iteração empregando break, continuee else(ao nal).

Page 85: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Capítulo 2

Programação Orientada aObjetos

Introdução à programação orientada a objetos e sua im-plementação na linguagem Python. Pré-requisitos:

Ter lido o capítulo 1.

Programação orientada a objetos é um tema vasto na litera-tura computacional. Neste capítulo introduziremos os recur-

sos presentes na linguagem Python para criar objetos e, através deexemplos, nos familiarizaremos com o paradigma da programaçãoorientada a objetos.

Historicamente, a elaboração de programas de computador pas-sou por diversos paradigmas. Programas de computador começa-ram como uma simples lista de instruções a serem executadas, emsequência, pela CPU. Este paradigma de programação foi maistarde denominado de programação não-estruturada. Sua principalcaracterística é a presença de comandos para desviar a execuçãopara pontos especícos do programa (goto, jump, etc.) Exem-plos de linguagens não-estruturadas são Basic, Assembly e Fortran.Mais tarde surgiram as linguagens estruturadas, que permitiam aorganização do programa em blocos que podiam ser executados emqualquer ordem. As Linguagens C e Pascal ganham grande popu-

51

Page 86: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

52 CAPÍTULO 2. ORIENTAÇÃO A OBJETO

laridade, e linguagens até então não estruturadas (Basic, Fortran,etc.) ganham versões estruturadas. Outros exemplos de lingua-gens não estruturadas incluem Ada, D, Forth,PL/1, Perl, maple,Matlab, Mathematica, etc.

A estruturação de programas deu origem a diversos paradig-mas de programação, tais como a programação funcional, na quala computação é vista como a avaliação sequencial de funções mate-máticas, e cujos principais exemplos atuais são as linguagens Lispe Haskell.

A programação estruturada atingiu seu pico em versatilidade epopularidade com o paradigma da programação orientada a obje-tos. Na programação orientada a objetos, o programa é divididoem unidades (objetos) contendo dados (estado) e funcionalidade(métodos) própria. Objetos são capazes de receber mensagens,processar dados (de acordo com seus métodos) e enviar mensagensa outros objetos. Cada objeto pode ser visto como uma máquinaindependente ou um ator que desempenha um papel especíco.

2.1 Objetos

Um tema frequente em computação cientíca, é a simulação desistemas naturais de vários tipos, físicos, químicos, biológicos, etc.A orientação a objetos é uma ferramenta natural na construção desimulações, pois nos permite replicar a arquitetura do sistema natu-ral em nossos programas, representando componentes de sistemasnaturais como objetos computacionais.

A orientação a objeto pode ser compreendida em analogia aoconceito gramatical de objeto. Os componentes principais de umafrase são: sujeito, verbo e objeto. Na programação orientada aobjeto, a ação está sempre associada ao objeto e não ao sujeito,como em outros paradigmas de programação.

Um dos pontos altos da linguagem Python que facilita sua assi-milação por cientistas com experiência prévia em outras linguagens

Page 87: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

2.1. OBJETOS 53

Listagem 2.1: Denindo uma classe

1 class Objeto :2 pass

de programação, é que a linguagem não impõe nenhum estilo deprogramação ao usuário. Em Python pode-se programar de formanão estruturada, estruturada, procedural, funcional ou orientada aobjeto. Além de acomodar as preferências de cada usuário, per-mite acomodar as conveniências do problema a ser resolvido peloprograma.

Neste capítulo, introduziremos as técnicas básicas de progra-mação orientada a objetos em Python. Em exemplos de outroscapítulos, outros estilos de programação aparecerão, justicadospelo tipo de aplicação a que se propõe.

Denindo Objetos e seus Atributos em Python

Ao se construir um modelo de um sistema natural, uma das carac-terísticas desejáveis deste modelo, é um certo grau de generalidade.Por exemplo, ao construir um modelo computacional de um auto-móvel, desejamos que ele (o modelo) represente uma categoria deautomóveis e não apenas nosso automóvel particular. Ao mesmotempo, queremos ser capazes de ajustar este modelo para que elepossa representar nosso automóvel ou o de nosso vizinho sem pre-cisar re-escrever o modelo inteiramente do zero. A estes modelosde objetos dá-se o nome de classes.

A denição de classes em Python pode ser feita de forma maisou menos genérica. À partir das classes, podemos construir instân-cias ajustadas para representar exemplares especícos de objetosrepresentados pela classe. Na listagem 2.1, temos uma deniçãomínima de uma classe de objetos. Criamos uma classe chamada

Page 88: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

54 CAPÍTULO 2. ORIENTAÇÃO A OBJETO

Listagem 2.2: Denindo atributos de uma classe

1 class pessoa :2 idade=203 a l tu r a=1704 sexo=' mascul ino '5 peso=70

Objeto, inteiramente em branco. Como uma classe completamentevazia não é possível em Python, adicionamos o comando pass quenão tem qualquer efeito.

Para criar uma classe mais útil de objetos, precisamos deniralguns de seus atributos. Como exemplo vamos criar uma classeque represente pessoas. Na listagem 2.2, denimos alguns atribu-tos para a classe pessoa. Agora, podemos criar instâncias do objetopessoa e estas instâncias herdarão estes atributos.

1 >>> maria = pessoa ( )2 >>> maria . peso3 704 >>> maria . sexo5 ' mascul ino '6 >>> maria7 <__main__. pessoa in s t ance at 0 x402f196c>

Entretanto, os atributos denidos para o objeto pessoa (listagem2.2), são atributos que não se espera que permaneçam os mesmospara todas as possíveis instâncias (pessoas). O mais comum é queos atributos especícos das instâncias sejam fornecidos no momentoda sua criação. Para isso, podemos denir quais as informaçõesnecessárias para criar uma instância do objeto pessoa.

Listagem 2.3: Passando atributos na criação de um objeto

1 >>> class pessoa :

Page 89: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

2.1. OBJETOS 55

2 . . . def __init__( s e l f , idade , a l tura , sexo ,peso ) :

3 . . . s e l f . idade=idade4 . . . s e l f . a l t u r a=a l tu r a5 . . . s e l f . sexo=sexo6 . . . s e l f . peso=707 >>> maria = pessoa ( )8 Traceback (most r e c ent c a l l l a s t ) :9 F i l e "<std in>" , l i n e 1 , in ?

10 TypeError : __init__ ( ) takes exac t l y 5arguments (1 g iven )

11 maria=pessoa (35 ,155 , ' f emin ino ' ,50)12 >>> maria . sexo13 ' f eminino '

A função __init__ que denimos na nova versão da classe pessoa(listagem 2.3), é uma função padrão de classes, que é executadaautomaticamente, sempre que uma nova instância é criada. Assim,se não passarmos as informações requeridas como argumentos pelafunção __init__ (listagem 2.3, linha 7), recebemos uma mensagemde erro. Na linha 11 da listagem 2.3 vemos como instanciar a novaversão da classe pessoa.

Adicionando Funcionalidade a Objetos

Continuando com a analogia com objetos reais, os objetos computa-cionais também podem possuir funcionalidades, além de atributos.Estas funcionalidades são denominadas métodos de objeto. Méto-dos são denidos como funções pertencentes ao objeto. A função__init__ que vimos há pouco é um método presente em todos osobjetos, ainda que não seja denida pelo programador. Métodossão sempre denidos com, pelo menos, um argumento: self, quepode ser omitido ao se invocar o método em uma instância do ob-jeto (veja linha 11 da listagem 2.3). O argumento self também

Page 90: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

56 CAPÍTULO 2. ORIENTAÇÃO A OBJETO

deve ser o primeiro argumento a ser declarado na lista de argumen-tos de um método.

Herança

Para simplicar a denição de classes complexas, classes podemherdar atributos e métodos de outras classes. Por exemplo, umaclasse Felino, poderia herdar de uma classe mamífero, que por suavez herdaria de outra classe, vertebrados. Esta cadeia de herançapode ser extendida, conforme necessário (Listagem 2.4).

Listagem 2.4: Herança

1 >>> class Vertebrado :2 ver tebra = True3 >>> class Mamifero ( Vertebrado ) :4 mamas = True5 >>> class Carnivoro (Mamifero ) :6 longos_caninos = True7 >>> bicho = Carnivoro ( )8 >>> d i r ( bicho )9 [ '__doc__ ' , '__module__ ' , ' longos_caninos ' ,

'mamas ' , ' ve r t ebra ' ]10 >>> i s s u b c l a s s ( Carnivoro , Vertebrado )11 True12 >>> bicho . __class__13 <class __main__. Carnivoro at 0xb7a1d17c>14 >>> i s i n s t a n c e ( bicho , Mamifero )15 True

Na listagem 2.4, vemos um exemplo de criação de um objeto,instância da classe Carnivoro, herdando os atributos dos ancestraisdesta. Vemos também que é possivel testar a pertinência de umobjeto a uma dada classe, através da função isinstance. A funçãoissubclass, de forma análoga, nos permite vericar as relaçõesparentais de duas classes.

Page 91: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

2.2. EXERCÍCIOS 57

Utilizando Classes como Estruturas de DadosGenéricas.

Devido à natureza dinâmica do Python, podemos utilizar umaclasse como um compartimento para quaisquer tipos de dados. Talconstruto seria equivalente ao tipo struct da linguagem C. Paraexemplicar, vamos denir uma classe vazia:

Listagem 2.5: Classe como uma estrura de dados

1 >>> class Cachorro :2 pass3 >>> rex=Cachorro ( )4 >>> rex . dono = ' Pedro '5 >>> rex . raca = ' Pastor '6 >>> rex . peso=257 >>> rex . dono8 ' Pedro '9 >>> la i k a = Cachorro ( )

10 >>> la i k a . dono11 Attr ibuteError : Cachorro in s t anc e has no

a t t r i b u t e ' dono '

No exemplo 2.5, a classe Cachorro é criada vazia, mas aindaassim, atributos podem ser atribuidos a suas instâncias, sem alterara estrutura da classe.

2.2 Exercícios

1. Utilizando os conceitos de herança e os exemplos de classesapresentados, construa uma classe Cachorro que herde atri-butos das classes Carnivoro e Mamífero e crie instâncias quepossuam donos, raças, etc.

2. No Python, o que dene um objeto como chamável (funções,por exemplo) é a presença do método __call__. Crie uma

Page 92: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

58 CAPÍTULO 2. ORIENTAÇÃO A OBJETO

classe, cujas instâncias podem ser chamadas, por possuíremo método __call__.

Page 93: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Capítulo 3

Criando Grácos em PythonIntrodução à produção de guras de alta qualidade uti-lizando o pacote matplotlib. Pré-requisitos: Capítulo1.

Existe um número crescente de módulos para a criação de grá-cos cientícos com Python. Entretanto, até o momento da

publicação deste livro, nenhum deles fazia parte da distribuiçãoocial do Python.

Para manter este livro prático e conciso, foi necessário escolherapenas um dos módulos de grácos disponíveis, para apresentaçãoneste capítulo.

O critério de escolha levou em consideração os principais valoresda losoa da linguagem Python (ver listagem ): simplicidade,elegância, versatilidade, etc. À época, a aplicação destes critériosnos deixou apenas uma opção: o módulo matplotlib1.

3.1 Introdução ao Matplotlib

O módulo matplotlib (MPL) é voltado para a geração de grácosbi-dimensionais de vários tipos, e se presta para utilização tanto in-

1http://matplotlib.sourceforge.net

59

Page 94: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

60 CAPÍTULO 3. CRIANDO GRÁFICOS EM PYTHON

terativa quanto em scripts, aplicações web ou integrada a interfacesgrácas (GUIs) de vários tipos.

A instalação do MPL também segue o padrão de simplicidadedo Python (listagem 3.1). Basta baixar o pacote tar.gz do sítio,descompactar e executar o comando de instalação.

Listagem 3.1: Instalando o matplotlib

1 $ python setup . py i n s t a l l

O MPL procura tornar simples tarefas de plotagem, simples etarefas complexas, possíveis (listagem3.2, gura 3.1). Os grácosgerados podem ser salvos em diversos formatos: jpg, png, ps, eps esvg. Ou seja, o MPL exporta em formatos raster e vetoriais (svg)o que torna sua saída adequada para inserção em diversos tipos dedocumentos.

Listagem 3.2: Criando um histograma no modo interativo

1 >>> from pylab import ∗2 >>> from numpy . random import ∗3 >>> x=normal (0 ,1 ,1000)4 >>> h i s t (x , 3 0 )5 . . .6 >>> show ( )

Podemos também embutir a saída gráca do MPL em diver-sas GUIs: GTK, WX e TKinter. Naturalmente a utilização doMPL dentro de uma GUI requer que os módulos adequados parao desenvolvimento com a GUI em questão estejam instalados2.

Para gerar os grácos e se integrar a interfaces grácas, o MPLse utiliza de diferentes backends de acordo com nossa escolha(Wx, GTK, Tk, etc).

2Veja no sitio do MPL os pré-requisitos para cada uma das GUIs

Page 95: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

3.1. INTRODUÇÃO AO MATPLOTLIB 61

Figura 3.1: Histograma simples a partir da listagem 3.2

Congurando o MPL

O MPL possui valores default para propriedades genéricas dos grá-cos gerados. Estas congurações cam em um arquivo textochamado matplotlibrc, que deve ser copiado da distribuição doMPL, editado conforme as preferências do usuário e renomeadopara ∼/.matplotlibrc, ou seja, deve ser colocado como um ar-quivo oculto no diretório home do usuário.

A utilização de congurações padrão a partir do matplotlibrcé mais útil na utilização interativa do MPL, pois evita a necessidadede congurar cada gura de acordo com as nossas preferências, a

Page 96: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

62 CAPÍTULO 3. CRIANDO GRÁFICOS EM PYTHON

bar Gráco de barrascohere Gráco da função de coerênciacsd Densidade espectral cruzadaerrorbar Gráco com barras de errohist Histogramaimshow Plota imagenspcolor Gráco de pseudocoresplot Gráco de linhapsd Densidade espectral de potênciascatter Diagrama de espalhamentospecgram Espectrogramastem Pontos com linhas verticais

Tabela 3.1: Principais comandos de plotagem do MPL

cada vez que usamos o MPL3.

Comandos Básicos

Os comandos relacionados diretamente à geração de grácos sãobastante numerosos(tabela 3.1); mas, além destes, existe um outroconjunto ainda maior de comandos, voltados para o ajuste no dedetalhes dos grácos (ver tabela 3.2, para uma amostra), tais comotipos de linha, símbolos, cores, etc. Uma explicação mais detalhadados comandos apresentados na tabela 3.1, será dada nas próximasseções no contexto de exemplos.

3Para uma descrição completa das características de grácos que podemser conguradas, veja o ememplo de matplotlibrc que é fornecido com adistribuição do MPL.

Page 97: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

3.2. EXEMPLOS SIMPLES 63

Figura 3.2: Reta simples a partir da listagem 3.3

3.2 Exemplos Simples

O comando plot

O comando plot é um comando muito versátil, pode receber umnúmero variável de argumentos, com diferentes saídas.

Listagem 3.3: Gráco de linha

1 from pylab import ∗2 p lo t ( [ 1 , 2 , 3 , 4 ] )3 show ( )

Page 98: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

64 CAPÍTULO 3. CRIANDO GRÁFICOS EM PYTHON

Quando plot recebe apenas uma sequência de números (lista, tuplaou array), ele gera um gráco (listagem 3.3) utilizando os valoresrecebidos como valores de y enquanto que os valores de x são asposições destes valores na sequência.

Caso duas sequências de valores sejam passadas para plot (lis-tagem 3.4), a primeira é atribuida a x e a segunda a y. Note que,neste exemplo, ilustra-se também a especicação do tipo de saídagráca como uma sequência de pontos. O parâmtero 'ro' indicaque o símbolo a ser usado é um círculo vermelho.

Listagem 3.4: Gráco de pontos com valores de x e y especicados.

1 from pylab import ∗2 p lo t ( [ 1 , 2 , 3 , 4 ] , [ 1 , 4 , 9 , 1 6 ] , ' ro ' )3 ax i s ( [ 0 , 6 , 0 , 2 0 ] )4 s a v e f i g ( ' ponto . png ' )5 show ( )

Na linha 3 da listagem 3.4 especica-se também os limites dos eixoscomo uma lista de quatro elementos: os valores mínimo e máximodos eixos x e y, respectivamente. Na linha 4, vemos o comandosavefig que nos permite salvar a gura gerada no arquivo cujonome é dado pela string recebida. O tipo de arquivo é determinadopela extensão (.png, .ps, .eps, .svg, etc).

O MPL nos permite controlar as propriedades da linha queforma o gráco. Existe mais de uma maneira de determinar aspropriedades das linhas geradas pelo comando plot. Uma dasmaneiras mais diretas é através dos argumentos listados na tabela3.2. Nos diversos exemplos apresentados neste capítulo, algunsoutros métodos serão apresentados e explicados4.

Vale a pena ressaltar que o comando plot aceita, tanto listas,quanto arrays dos módulos Numpy, Numeric ou numarray. Na ver-

4Para maiores detalhes consulte a documentação do MPL(http://matplotlib.sourceforge.net).

Page 99: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

3.2. EXEMPLOS SIMPLES 65

Figura 3.3: Gráco com símbolos circulares a partir da listagem3.4

dade todas a sequências de números passadas para o comando plotsão convertidas internamente para arrays.

O Comando subplot

O MPL trabalha com o conceito de gura independente do de ei-xos. O comando gcf() retorna a gura atual, e o comando gca()

retorna os eixos atuais. Este detalhe nos permite posicionar os ei-xos de um gráco em posições arbitrárias dentro da gura. Todosos comandos de plotagem são realizados nos eixos atuais. Mas,para a maioria dos usuários, estes detalhes são transparentes, ou

Page 100: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

66 CAPÍTULO 3. CRIANDO GRÁFICOS EM PYTHON

Tabela 3.2: Argumentos que podem ser passados juntamente coma função plot para controlar propriedades de linhas.

Propriedade Valoresalpha transparência (0-1)antialiased true | falsecolor Cor: b,g,r,c,m,y,k,wlabel legendalinestyle -- : -. -

linewidth Espessura da linha (pontos)marker + o . s v x > < ^

markeredgewidth Espessura da margem do símbolomarkeredgecolor Cor da margem do símbolomarkerfacecolor Cor do símbolomarkersize Tamanho do símbolo (pontos)

seja, o usúário não precisa tomar conhecimento deles. A listagem3.5 apresenta uma gura com dois eixos feita de maneira bastantesimples.

Listagem 3.5: Figura com dois grácos utilizando o comando sub-plot.

1 # Dispon ive l no pacote de programas como :subplot . py

2 from pylab import ∗3

4 def f ( t ) :5 s1 = cos (2∗ pi ∗ t )6 e1 = exp(−t )7 return mult ip ly ( s1 , e1 )8

9 t1 = arange ( 0 . 0 , 5 . 0 , 0 . 1 )10 t2 = arange ( 0 . 0 , 5 . 0 , 0 . 02 )

Page 101: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

3.2. EXEMPLOS SIMPLES 67

Figura 3.4: Figura com dois grácos utilizando o comando subplot,a partir da listagem 3.5

11

12 f i g u r e (1 )13 subplot (211)14 p lo t ( t1 , f ( t1 ) , ' bo ' , t2 , f ( t2 ) , ' k ' )15

16 subplot (212)17 p lo t ( t2 , cos (2∗ pi ∗ t2 ) , ' r−− ' )18 s a v e f i g ( ' subplot . png ' , dpi=400)19 show ( )

Page 102: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

68 CAPÍTULO 3. CRIANDO GRÁFICOS EM PYTHON

Tabela 3.3: Argumentos opcionais dos comandos de inserção detexto.

Propriedades Valoresalpha Transparência (0-1)color Corfontangle italic | normal | obliquefontname Nome da fontefontsize Tamanho da fontefontweight normal | bold | light4horizontalalignment left | center | rightrotation horizontal | verticalverticalalignment bottom | center | top

O comando figure(1), na linha 11 da listagem 3.5, é opcional,mas pode vir a ser importante quando se deseja criar múltiplasguras, antes de dar o comando show(). Note pelo primeiro co-mando plot da listagem 3.5, que o comando plot aceita mais deum par (x,y), cada qual com seu tipo de linha especicado inde-pendentemente.

Adicionando Texto a Grácos

O MPL nos oferece quatro comandos para a adição de texto a gu-ras: title, xlabel, ylabel, e text. O três primeiros adicionamtítulo e nomes para os eixos x e y, respectivamente.

Todos os comandos de inserção de texto aceitam argumentos(tabela 3.3) adicionais para formatação do texto. O MPL tam-bém nos permite utilizar um subconjunto da linguagem TEXparaformatar expressões matemáticas (Listagem 3.6 e gura 3.5. Parainserir expressões em TEX, é necessário que as strings contendoas expressões matemáticas sejam raw strings5, e delimitadas por

5exemplo: r'raw string'

Page 103: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

3.3. EXEMPLOS AVANÇADOS 69

cifrões($).

Listagem 3.6: Formatando texto e expressões matemáticas

1 # Dispon ive l no pacote de programas como :mathtext . py

2 from pylab import ∗3 t = arange ( 0 . 0 , 2 . 0 , 0 . 0 1 )4 s = s i n (2∗ pi ∗ t )5 p lo t ( t , s )6 t i t l e ( r ' $\ alpha_i > \beta_i$ ' , f o n t s i z e =20)7 t ex t (1 , −0.6 , r ' $\sum_ i=0^\ i n f t y x_i$ ' ,

f o n t s i z e =20)8 t ex t ( 0 . 6 , 0 . 6 , r ' $\ c a l A\rm s i n (2 \omega t

) $ ' ,9 f o n t s i z e =20)

10 x l ab e l ( ' time ( s ) ' )11 y l ab e l ( r ' $Voltagem (\mu V)$ ' )12 s a v e f i g ( ' mathtext . png ' , dpi=400)13 show ( )

3.3 Exemplos Avançados

O MPL é capaz produzir uma grande variedade grácos mais so-sticados do que os apresentados até agora. Explorar todas aspossibilidades do MPL, foge ao escopo deste texto, mas diversosexemplos de outros tipos de grácos serão apresentados junto comos exemplos da segunda parte deste livro.

Mapas

O matplotlib pode ser extendido para plotar mapas. Para isso pre-cisamos instalar o Basemap toolkit. Se você já instalou o matplo-

Page 104: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

70 CAPÍTULO 3. CRIANDO GRÁFICOS EM PYTHON

Figura 3.5: Formatação de texto em guras. Gerada pela listagem3.6

tlib, basta baixar o arquivo tar.gz do Basemap, descompactar paraum diretório e executar o já conhecido python setup.py install.

O Basemap já vem com um mapa mundi incluído para demons-tração. Vamos utilizar este mapa em nosso exemplo (Listagem3.7).

Listagem 3.7: Plotando o globo terrestre

1 # Dispon ive l no pacote de programas como :mapa . py

2 from matp lo t l i b . t o o l k i t s . basemap importBasemap

Page 105: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

3.3. EXEMPLOS AVANÇADOS 71

3 import pylab as p4

5 map = Basemap( p r o j e c t i o n=' rob in ' , lat_0=−23,lon_0=−46,

6 r e s o l u t i o n=' l ' , area_thresh=1000.)

7 map . d rawcoa s t l i n e s ( )8 map . drawcountr ie s ( )9 map . f i l l c o n t i n e n t s ( c o l o r=' c o r a l ' )

10 map . drawmapboundary ( )11 map . drawmeridians (p . arange (0 ,360 ,30 ) )12 map . d r awpa ra l l e l s (p . arange (−90 ,90 ,30) )13 p . show ( )

Na listagem 3.6, criamos um objeto map, que é uma instância,da classe Basemap (linha 4). A classe Basemap possui diversos atri-butos, mas neste exemplo estamos denindo apenas alguns comoa projeção (Robinson), coordenadas do centro do mapa, lat_0 elon_0, resolução dos contornos, ajustada para baixa, e tamanhomínimo de detalhes a serem desenhados, area_thresh, denidocomo 1000km2.

Page 106: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

72 CAPÍTULO 3. CRIANDO GRÁFICOS EM PYTHON

Figura 3.6: Mapa mundi na projeção de Robinson.

Page 107: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Capítulo 4

Ferramentas deDesenvolvimento

Exposição de ferramentas voltadas para o aumento daprodutividade em um ambiente de trabalho em compu-tação cientíca. Pré-requisitos: Capítulos 1 e 2

Como em todo ambiente de trabalho, para aumentar a nossaprodutividade em Computação Cientíca, existem várias fer-

ramentas além da linguagem de programação. Neste capítulo fala-remos das ferramentas mais importantes, na opinião do autor.

4.1 Ipython

A utilização interativa do Python é de extrema valia. Outros am-bientes voltados para computação cientíca, tais como MatlabTM,R, MathematicaTMdentre outros, usam o modo interativo como seuprincipal modo de operação. Os que desejam fazer o mesmo com oPython, podem se beneciar imensamente do Ipython.

O Ipython é uma versão muito sosticada da shell do Pythonvoltada para tornar mais eciente a utilização interativa da lingua-gem Python.

73

Page 108: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

74 CAPÍTULO 4. FERRAMENTAS DE DESENVOLVIMENTO

Primeiros Passos

Para iniciar o Ipython, digitamos o seguinte comando:

1 $ ipython [ opções ] a rqu ivos

Muita das opções que controlam o funcionamento do Ipython nãosão passadas na linha de comando, estão especicadas no arquivoipythonrc dentro do diretório /.ipython.

Quatro opções do Ipython são consideradas especiais e devemaparecer em primeiro lugar, antes de qualquer outra opção: -gthread,-qthread, -wthread, -pylab. As três primeiras opções são vol-tadas para o uso interativo de módulos na construção de GUIs(interfaces grácas), respectivamente GTK, Qt, WxPython. Estasopções iniciam o Ipython em um thread separado, de forma a per-mitir o controle interativo de elementos grácos. A opção -pylab

permite o uso interativo do pacote matplotlib (Ver capítulo 3).Esta opção executará from pylab import ∗ ao iniciar, e permiteque grácos sejam exibidos sem necessidade de invocar o comandoshow(), mas executará scripts que contém show() ao nal, corre-tamente.

Após uma das quatro opções acima terem sido especicadas,as opções regulares podem seguir em qualquer ordem. Todas asopções podem ser abreviadas à forma mais curta não-ambígua,mas devem respeitar maiúsculas e minúsculas (como nas lingua-gens Python e Bash, por sinal). Um ou dois hífens podem serutilizados na especicação de opções.

Todas as opções podem ser prexadas por no para serem des-ligadas (no caso de serem ativas por default).

Devido ao grande número de opções existentes, não iremos listá-las aqui. consulte a documentação do Ipython para aprender sobreelas. Entretanto, algumas opções poderão aparecer ao longo destaseção e serão explicadas à medida em que surgirem.

Page 109: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

4.1. IPYTHON 75

Comandos Mágicos

Uma das características mais úteis do Ipython é o conceito de co-mandos mágicos. No console do Ipython, qualquer linha come-çada pelo caractere %, é considerada uma chamada a um comandomágico. Por exemplo, %autoindent liga a indentação automáticadentro do Ipython.

Existe uma opção que vem ativada por default no ipythonrc,denomidada automagic. Com esta função, os comandos mági-cos podem ser chamados sem o %, ou seja autoindent é enten-dido como %autoindent. Variáveis denidas pelo usuário podemmascarar comandos mágicos. Portanto, se eu denir uma variá-vel autoindent = 1, a palavra autoindent não é mais reconhecidacomo um comando mágico e sim como o nome da variável criadapor mim. Porém, ainda posso chamar o comando mágico colocandoo caractere % no início.

O usuário pode extender o conjunto de comandos mágicos comsuas próprias criações. Veja a documentação do Ipython sobrecomo fazer isso.

O comando mágico %magic retorna um explicação dos coman-dos mágicos existentes.

%Exit Sai do console Ipython.

%Pprint Liga/desliga formatação do texto.

%Quit Sai do Ipython sem pedir conrmação.

%alias Dene um sinônimo para um comando.

Você pode usar %1 para representar a linha em que o comandoalias foi chamado, por exemplo:

1 In [ 2 ] : a l i a s a l l echo "Entrada ent r epa r ên t e s e s : (% l ) "

2 In [ 3 ] : a l l Ola mundo3 Entrada ent re pa r ên t e s e s : (Ola mundo)

Page 110: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

76 CAPÍTULO 4. FERRAMENTAS DE DESENVOLVIMENTO

%autocall Liga/desliga modo que permite chamar funções sem osparênteses. Por exemplo: fun 1 vira fun(1).

%autoindent Liga/desliga auto-indentação.

%automagic Liga/desliga auto-mágica.

%bg Executa um comando em segundo plano, em um thread sepa-rado. Por exemplo: %bg func(x,y,z=1). Assim que a exe-cução se inicia, uma mensagem é impressa no console infor-mando o número da tarefa. Assim, pode-se ter acesso ao re-sultado da tarefa número 5 por meio do comando jobs.results[5]

O Ipython possui um gerenciador de tarefas acessível atravésdo objeto jobs. Para maiores informações sobre este objeto di-gite jobs?. O Ipython permite completar automaticamente umcomando digitado parcialmente. Para ver todos os métodos doobjeto jobs experimente digitar jobs.seguido da tecla <TAB>.

%bookmark Gerencia o sistema de marcadores do Ipython. Parasaber mais sobre marcadores digite %bookmark?.

%cd Muda de diretório.

%colors Troca o esquema de cores.

%cpaste Cola e executa um bloco pré-formatado da área de trans-ferência (clipboard). O bloco tem que ser terminado por umalinha contendo −−.

%dhist Imprime o histórico de diretórios.

%ed Sinônimo para %edit

%edit Abre um editor e executa o código editado ao sair. Estecomando aceita diversas opções, veja a documentação.

Page 111: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

4.1. IPYTHON 77

O editor a ser aberto pelo comando %edit é o que estiver de-nido na variável de ambiente $EDITOR. Se esta variável não estiverdenida, o Ipython abrirá o vi. Se não for especicado o nome deum arquivo, o Ipython abrirá um arquivo temporário para a edição.

O comando %edit apresenta algumas conveniências. Por exem-plo: se denirmos uma funcão fun em uma sessão de edição ao saire executar o código, esta função permanecerá denida no espaçode nomes corrente. Então podemos digitar apenas %edit fun eo Ipython abrirá o arquivo que a contém, posicionando o cursor,automaticamente, na linha que a dene. Ao sair desta sessão deedição, a função editada será atualizada.

1 In [ 6 ] :% ed2 IPython w i l l make a temporary f i l e named : /

tmp/ipython_edit_GuUWr_ . py3 done . Executing ed i t ed code . . .4 Out [ 6 ] : " de f fun ( ) : \ n p r in t ' fun '\n \

ndef funa ( ) : \ n p r in t ' funa '\n"5

6 In [ 7 ] : fun ( )7 fun8

9 In [ 8 ] : funa ( )10 funa11

12 In [ 9 ] :% ed fun13 done . Executing ed i t ed code . . .

%hist Sinônimo para %history.

%history Imprime o histórico de comandos. Comandos anteriorestambém podem ser acessados através da variável _i<n>, queé o n-ésimo comando do histórico.

Page 112: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

78 CAPÍTULO 4. FERRAMENTAS DE DESENVOLVIMENTO

1 In [ 1 ] :% h i s t2 1 : _ip . magic ( "%h i s t " )3

4 In [ 2 ] :% h i s t5 1 : _ip . magic ( "%h i s t " )6 2 : _ip . magic ( "%h i s t " )

O Ipython possui um sosticado sistema de registro das ses-sões. Este sistema é controlado pelos seguintes comandos mágicos:%logon, %logoff, %logstart e %logstate. Para maiores infor-mações consulte a documentação.

%lsmagic Lista os comandos mágicos disponíveis.

%macro Dene um conjunto de linhas de comando como uma macropara uso posterior: %macro teste 1 2 ou %macro macro2

44-47 49.

%p Sinônimo para print.

%pdb liga/desliga depurador interativo.

%pdef Imprime o cabeçalho de qualquer objeto chamável. Se oobjeto for uma classe, retorna informação sobre o construtorda classe.

%pdoc Imprime a docstring de um objeto.

%pfile Imprime o arquivo onde o objeto encontra-se denido.

%psearch Busca por objetos em espaços de nomes.

%psource Imprime o código fonte de um objeto. O objeto tem queter sido importado a partir de um arquivo.

%quickref Mostra um guia de referência rápida

%quit Sai do Ipython.

Page 113: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

4.1. IPYTHON 79

%r Repete o comando anterior.

%rehash Atualiza a tabela de sinônimos com todas as entradas em$PATH. Este comando não verica permissões de execução ese as entradas são mesmo arquivos. %rehashx faz isso, mas émais lento.

%rehashdir Adiciona os executáveis dos diretórios especicados àtabela de sinônimos.

%rehashx Atualiza a tabela de sinônimos com todos os arquivosexecutáveis em $PATH.

%reset Re-inicializa o espaço de nomes removendo todos os nomesdenidos pelo usuário.

%run Executa o arquivo especicado dentro do Ipython como umprograma.

%runlog Executa arquivos como logs.

%save Salva um conjunto de linhas em um arquivo.

%sx Executa um comando no console do Linux e captura sua saída.

%store Armazena variáveis para que estejam disponíveis em umasessão futura.

%time Cronometra a execução de um comando ou expressão.

%timeit Cronometra a execução de um comando ou expressão uti-lizando o módulo timeit.

%unalias Remove um sinônimo.

%upgrade Atualiza a instalação do Ipython.

%who Imprime todas as variáveis interativas com um mínimo deformatação.

Page 114: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

80 CAPÍTULO 4. FERRAMENTAS DE DESENVOLVIMENTO

%who_ls Retorna uma lista de todas as variáveis interativas.

%whos Similar ao %who, com mais informação sobre cada variável.

Para nalizar, o Ipython é um excelente ambiente de traba-lho interativo para computação cientíca, especialmente quandoinvocado coma opção -pylab. O modo pylab além de grácos,também oferece uma série de comandos de compatibilidade com oMATLABTM(veja capítulo 3). O pacote principal do numpy tam-bém ca exposto no modo pylab. Subpacotes do numpy precisamser importados manualmente.

4.2 Editores de Código

Na edição de programas em Python, um bom editor de código podefazer uma grande diferença em produtividade. Devido a signicân-cia dos espaços em branco para a linguagem, um editor que mantéma indentação do código consistente, é muito importante para evitarbugs. Também é desejável que o editor conheça as regras de in-dentação do Python, por exemplo: indentar após :, indentar comespaços ao invés de tabulações. Outra característica desejável é acolorização do código de forma a ressaltar a sintaxe da linguagem.Esta característica aumenta, em muito, a legibilidade do código.

Os editores que podem ser utilizados com sucesso para a ediçãode programas em Python, se dividem em duas categorias básicas:editores genéricos e editores especializados na linguagem Python.Nesta seção, vamos examinar as principais características de algunseditores de cada categoria.

Editores Genéricos

Existe um sem-número de editores de texto disponíveis para o Am-biente Gnu/Linux. A grande maioria deles cumpre nossos requisi-tos básicos de indentação automática e colorização. Selecionei al-

Page 115: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

4.2. EDITORES DE CÓDIGO 81

guns que se destacam na minha preferência, quanto a usabilidadee versatilidade.

Emacs: Editor incrivelmente completo e versátil, funciona comoambiente integrado de desenvolvimento (gura 4.1). Precisater python-modeinstalado. Para quem não tem experiênciaprévia com o Emacs, recomendo que o pacote Easymacs1 sejatambém instalado. este pacote facilita muito a interface doEmacs, principalmente para adição de atalhos de teclado pa-drão CUA. Pode-se ainda utilizar o Ipython dentro do Emacs.

Scite: Editor leve e eciente, suporta bem o Python (executa oscript com <F5>) assim como diversas outras linguagens.Permite congurar comando de compilação de C e Fortran, oque facilita o desenvolvimento de extensões. Completamentecongurável (gura 4.2).

Gnu Nano: Levíssimo editor para ambientes de console, possuisuporte a auto indentação e colorização em diversas lingua-gens, incluindo o Python (gura 4.3). Ideal para utilizar emconjunção com o Ipython (comando %edit).

Jedit: Incluí o Jedit nesta lista, pois oferece suporte ao desenvol-vimento em Jython (ver Seção 5.5). Afora isso, é um edi-tor bastante poderoso para java e não tão pesado quanto oEclipse (gura 4.4).

Kate/Gedit Editores padrão do KDE e Gnome respectivamente.Bons para uso casual, o Kate tem a vantagem de um consoleembutido.

1http://www.dur.ac.uk/p.j.heslin/Software/Emacs/Easymacs/

Page 116: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

82 CAPÍTULO 4. FERRAMENTAS DE DESENVOLVIMENTO

Figura 4.1: Editor emacs em modo Python e com Code Browserativado

Page 117: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

4.2. EDITORES DE CÓDIGO 83

Figura 4.2: Editor Scite.

Editores Especializados

Editores especializados em Python tendem a ser mais do tipo IDE(ambiente integrado de desenvolvimento), oferecendo funcionalida-des que só fazem sentido para gerenciar projetos de médio a grandeporte, sendo demais para se editar um simples Script.

Boa-Constructor: O Boa-constructor é um IDE, voltado para oprojetos que pretendam utilizar o WxPython como interface

Page 118: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

84 CAPÍTULO 4. FERRAMENTAS DE DESENVOLVIMENTO

Figura 4.3: Editor Gnu Nano.

gráca. Neste aspecto ele é muito bom, permitindo cons-trução visual da interface, gerando todo o código associadocom a interface. Também traz um excelente depurador paraprogramas em Python e dá suporte a módulos de extensãoescritos em outras linguagens, como Pyrex ou C(gura 4.5).

Eric: O Eric também é um IDE desenvolvido em Python com ainterface em PyQt. Possui boa integração com o gerador deinterfaces Qt Designer, tornando muito fácil o desenvolvi-mento de interfaces grácas com esta ferramenta. Tambémdispõe de ótimo depurador. Além disso o Eric oferece muitasoutras funções, tais como integração com sistemas de controle

Page 119: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

4.2. EDITORES DE CÓDIGO 85

Figura 4.4: Editor Jython Jedit

de versão, geradores de documentação, etc.(Figura 4.6).

Pydev (Eclipse): O Pydev, é um IDE para Python e Jythondesenvolvido como um plugin para Eclipse. Para quem játem experiência com a plataforma Eclipse, pode ser uma boaalternativa, caso contrário, pode ser bem mais complicadode operar do que as alternativas mencionadas acima (Figura4.7). Em termos de funcionalidade, equipara-se ao Eric e aoBoa-constructor.

Page 120: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

86 CAPÍTULO 4. FERRAMENTAS DE DESENVOLVIMENTO

Figura 4.5: IDE Boa-Constructor

4.3 Controle de Versões em Software

Ao se desenvolver software, em qualquer escala, experimentamosum processo de aperfeiçoamento progressivo no qual o softwarepassa por várias versões. Neste processo é muito comum, a umcerto estágio, recuperar alguma funcionalidade que estava presenteem uma versão anterior, e que, por alguma razão, foi eliminada docódigo.

Outro desao do desenvolvimento de produtos cientícos (soft-ware ou outros) é o trabalho em equipe em torno do mesmo ob-jeto (frequentemente um programa). Normalmente cada membroda equipe trabalha individualmente e apresenta os seus resultados

Page 121: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

4.3. CONTROLE DE VERSÕES EM SOFTWARE 87

Figura 4.6: IDE Eric.

para a equipe em reuniões regulares. O que fazer quando modica-ções desenvolvidas por diferentes membros de uma mesma equipese tornam incompatíveis? Ou mesmo, quando dois ou mais colabo-radores estão trabalhando em partes diferentes de um programa,mas que precisam uma da outra para funcionar?

O tipo de ferramenta que vamos introduzir nesta seção, buscaresolver ou minimizar os problemas supracitados e pode ser apli-cado também ao desenvolvimento colaborativo de outros tipos dedocumentos, não somente programas.

Como este é um livro baseado na linguagem Python, vamos uti-lizar um sistema de controle de versões desenvolvido inteiramente

Page 122: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

88 CAPÍTULO 4. FERRAMENTAS DE DESENVOLVIMENTO

Figura 4.7: IDE Pydev

em Python: Mercurial2. Na prática o mecanismo por trás detodos os sistemas de controle de versão é muito similar. Migrarde um para outro é uma questão de aprender novos nomes paraas mesmas operações. Além do mais, o uso diário de sistema decontrole de versões envolve apenas dois ou três comandos.

Entendendo o Mercurial

O Mercurial é um sistema de controle de versões descentralizado,ou seja, não há nenhuma noção de um servidor central onde ca

2http://www.selenic.com/mercurial

Page 123: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

4.3. CONTROLE DE VERSÕES EM SOFTWARE 89

Figura 4.8: Diagrama de um repositório do Mercurial.

depositado o código. Repositórios de códigos são diretórios quepodem ser clonados de uma máquina para outra.

Então, em que consiste um repositório? A gura 4.8 é umarepresentação diagramática de um repositório. Para simplicarnossa explanação, consideremos que o repositório já foi criado ouclonado de alguém que o criou. Veremos como criar um repositórioa partir do zero, mais adiante.

De acordo com a gura 4.8, um repositório é composto porum Arquivo3 e por um diretório de trabalho. O Arquivo contéma história completa do projeto. O diretório de trabalho contémuma cópia dos arquivos do projeto em um determinado ponto notempo (por exemplo, na revisão 2). É no diretório de trabalho queo pesquisador trabalha e atualiza os arquivos.

3Doravante grafado com A maiúsculo para diferenciar de arquivos co-muns(les).

Page 124: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

90 CAPÍTULO 4. FERRAMENTAS DE DESENVOLVIMENTO

Figura 4.9: Operação de commit.

Ao nal de cada ciclo de trabalho, o pesquisador envia suasmodicações para o arquivo numa operação denominada com-mit(gura 4.9)4.

Após um commit, como as fontes do diretório de trabalho nãocorrespondiam à última revisão do projeto, o Mercurial automati-camente cria uma ramicação no arquivo. Com isso passamos a terduas linhas de desenvolvimento seguindo em paralelo, com o nossodiretório de trabalho pertencendo ao ramo iniciado pela revisão 4.

O Mercurial agrupa as mudanças enviadas por um usuário(via commit), em um conjunto de mudanças atômico, que constitui

4Vou adotar o uso da palavra commit para me referir a esta operação daquiem diante. Optei por não tentar uma tradução pois este termo é um jargãodos sistemas de controle de versão.

Page 125: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

4.3. CONTROLE DE VERSÕES EM SOFTWARE 91

Figura 4.10: Repositório da Ana.

uma revisão. Estas revisões recebem uma numeração sequencial(gura 4.9). Mas como o Mercurial permite desenvolvimento deum mesmo projeto em paralelo, os números de revisão para di-ferentes desenvolvedores poderiam diferir. Por isso cada revisãotambém recebe um identicador global, consistindo de um númerohexadecimal de quarenta dígitos.

Além de ramicações, fusões (merge) entre ramos podem ocor-rer a qualquer momento. Sempre que houver mais de um ramoem desenvolvimento, o Mercurial denominará as revisões mais re-centes de cada ramo(heads, cabeças). Dentre estas, a que tivermaior número de revisão será considerada a ponta (tip) do repo-sitório.

Exemplo de uso:

Nestes exemplos, exploraremos as operações mais comuns num am-biente de desenvolvimento em colaboração utilizando o Mercurial.

Vamos começar com nossa primeira desenvolvedora, chamadaAna. Ana possui um arquivo como mostrado na gura 4.10.

Nosso segundo desenvolvedor, Bruno, acabou de se juntar aotime e clona o repositório Ana5.

1 $ hg c lone ssh ://maquinadana/ p ro j e t omeuprojeto

2 r eque s t i ng a l l changes

5Assumimos aqui que a máquina da ana está executando um servidor ssh

Page 126: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

92 CAPÍTULO 4. FERRAMENTAS DE DESENVOLVIMENTO

Figura 4.11: Modicações de Bruno.

Figura 4.12: Modicações de Ana.

3 adding changese t s4 adding man i f e s t s5 adding f i l e changes6 added 4 changese t s with 4 changes to 2 f i l e s

URLs válidas:le://http://https://ssh://static-http://

Após o comando acima, Bruno receberá uma cópia completado arquivo de Ana, mas seu diretório de trabalho, meu projeto,permanecerá independente. Bruno está ansioso para começar atrabalhar e logo faz dois commits (gura 4.11).

Enquanto isso, em paralelo, Ana também faz suas modicações(gura 4.12).

Bruno então decide puxar o repositório de Ana para sincronizá-lo com o seu.

1 $ hg pu l l

Page 127: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

4.3. CONTROLE DE VERSÕES EM SOFTWARE 93

Figura 4.13: Repositório atualizado de Bruno.

2 pu l l i n g from ssh ://maquinadaana/ p ro j e t o3 s ea r ch ing f o r changes4 adding changese t s5 adding man i f e s t s6 adding f i l e changes7 added 1 changese t s with 1 changes to 1 f i l e s8 ( run ' hg heads ' to see heads , ' hg merge ' to

merge )

O comando hg pull, se não especicada a fonte, irá puxarda fonte de onde o repositório local foi clonado. Este comandoatualizará o Arquivo local, mas não o diretório de trabalho.

Após esta operação o repositório de Bruno ca como mostradona gura 4.13. Como as mudanças feitas por Ana, foram as últimasadicionadas ao repositório de Bruno, esta revisão passa a ser aponta do Arquivo.

Bruno agora deseja fundir seu ramo de desenvolvimento, coma ponta do seu Arquivo que corresponde às modicações feitaspor Ana. Normalmente, após puxar modicações, executamos hgupdate para sincronizar nosso diretório de trabalho com o Arquivorecém atualizado. Então Bruno faz isso.

1 $ hg update2 t h i s update spans a branch a f f e c t i n g the

f o l l ow i ng f i l e s :3 h e l l o . py ( r e s o l v e )

Page 128: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

94 CAPÍTULO 4. FERRAMENTAS DE DESENVOLVIMENTO

Figura 4.14: Repositório de Bruno após a fusão.

4 abort ing update spanning branches !5 ( use ' hg merge ' to merge a c ro s s branches or

' hg update −C' to l o s e changes )

Devido à ramicação no Arquivo de Bruno, o comando update

não sabe a que ramo fundir as modicações existentes no diretóriode trabalho de Bruno. Para resolver isto, Bruno precisará fundiros dois ramos. Felizmente esta é uma tarefa trivial.

1 $ hg merge t i p2 merging h e l l o . py

No comando merge, se nenhuma revisão é especicada, o dire-tório de trabalho é cabeça de um ramo e existe apenas uma outracabeça, as duas cabeças serão fundidas. Caso contrário uma revisãodeve ser especicada.

Pronto! agora o repositório de Bruno cou como a gura 4.14.

Agora, se Ana puxar de Bruno, receberá todas as mocações deBruno e seus repositórios estarão plenamente sincronizados, comoa gura 4.14.

Criando um Repositório

Para criar um repositório do zero, é preciso apenas um comando:

1 $ hg i n i t

Page 129: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

4.3. CONTROLE DE VERSÕES EM SOFTWARE 95

Quando o diretório é criado, um diretório chamado .hg é criadodentro do diretório de trabalho. O Mercurial irá armazenar todasas informações sobre o repositório no diretório .hg. O conteúdodeste diretório não deve ser alterado pelo usuário.

Para saber mais

Naturalmente, muitas outras coisas podem ser feitas com um sis-tema de controle de versões. O leitor é encorajado a consultar adocumentação do Mercurial para descobrí-las. Para servir de re-ferência rápida, use o comando hg help -v <comando> com qual-quer comando da lista abaixo.

add Adiciona o(s) arquivo(s) especicado(s) no próximo commit.

addremove Adiciona todos os arquivos novos, removendo os faltan-tes.

annotate Mostra informação sobre modicações por linha de ar-quivo.

archive Cria um arquivo (compactado) não versionado, de umarevisão especicada.

backout Reverte os efeitos de uma modicação anterior.

branch Altera ou mostra o nome do ramo atual.

branches Lista todas os ramos do repositório.

bundle Cria um arquivo compactado contendo todas as modica-ções não presentes em um outro repositório.

cat Retorna o arquivo especicado, na forma em que ele era emdada revisão.

clone Replica um repositório.

Page 130: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

96 CAPÍTULO 4. FERRAMENTAS DE DESENVOLVIMENTO

commit Arquiva todas as modicações ou os arquivos especicados.

copy Copia os arquivos especicados, para outro diretório no pró-ximo commit.

diff Mostra diferenças entre revisões ou entre os arquivos especi-cados.

export Imprime o cabeçalho e as diferenças para um ou mais con-juntos de modicações.

grep Busca por palavras em arquivos e revisões especícas.

heads Mostra cabeças atuais.

help Mostra ajuda para um comando, extensão ou lista de coman-dos.

identify Imprime informações sobre a cópia de trabalho atual.

import Importa um conjunto ordenado de atualizações (patches).Este comando é a contrapartida de Export.

incoming Mostra novos conjuntos de modicações existentes emum dado repositório.

init Cria um novo repositório no diretório especicado. Se o di-retório não existir, ele será criado.

locate Localiza arquivos.

log Mostra histórico de revisões para o repositório como um todoou para alguns arquivos.

manifest Retorna o manifesto (lista de arquivos controlados) darevisão atual ou outra.

merge Funde o diretório de trabalho com outra revisão.

Page 131: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

4.3. CONTROLE DE VERSÕES EM SOFTWARE 97

outgoing Mostra conjunto de modicações não presentes no repo-sitório de destino.

parents Mostra os pais do diretório de trabalho ou revisão.

paths Mostra denição de nomes simbólicos de caminho.

pull Puxa atualizações da fonte especicada.

push Envia modicações para o repositório destino especicado.É a contra-partida de pull.

recover Desfaz uma transação interrompida.

remove Remove os arquivos especicados no próximo commit.

rename Renomeia arquivos; Equivalente a copy + remove.

revert Reverte arquivos ao estado em que estavam em uma dadarevisão.

rollback Desfaz a última transação neste repositório.

root Imprime a raiz do diretório de trabalho corrente.

serve Exporta o diretório via HTTP.

showconfig Mostra a conguração combinada de todos os arqui-vos hgrc.

status Mostra arquivos modicados no diretório de trabalho.

tag Adiciona um marcador para a revisão corrente ou outra.

tags Lista marcadores do repositório.

tip Mostra a revisão ponta.

unbundle Aplica um arquivo de modicações.

Page 132: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

98 CAPÍTULO 4. FERRAMENTAS DE DESENVOLVIMENTO

update Atualiza ou funde o diretório de trabalho.

verify Verica a integridade do repositório.

version Retorna versão e informação de copyright.

Page 133: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Capítulo 5

Interagindo com OutrasLinguagens

Introdução a vários métodos de integração do Pythoncom outras linguagens. Pré-requisitos: Capítulos 1 e2.

5.1 Introdução

O Python é uma linguagem extremamente poderosa e versátil, per-feitamente apta a ser, não somente a primeira, como a última lin-guagem de programação que um cientista precisará aprender. En-tretanto, existem várias situações nas quais torna-se interessantecombinar o seu código escrito em Python com códigos escritos emoutras linguagens. Uma das situações mais comuns, é a necessi-dade de obter maior performance em certos algoritmos através dare-implementação em uma linguagem compilada. Outra Situaçãocomum é possibilidade de se utilizar de bibliotecas desenvolvidasem outras linguagens e assim evitar ter que reimplementá-las emPython.

O Python é uma linguagem que se presta. extremamente bem.a estas tarefas existindo diversos métodos para se alcançar os obje-

99

Page 134: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

100CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

tivos descritos no parágrafo acima. Neste capítulo, vamos explorarapenas os mais práticos e ecientes, do ponto de vista do tempo deimplementação.

5.2 Integração com a Linguagem C

A linguagem C é uma das linguagens mais utilizadas no desenvol-vimento de softwares que requerem alta performance. Um bomexemplo é o Linux (kernel) e a própria linguagem Python. Estefato torna o C um candidato natural para melhorar a performancede programas em Python.

Vários pacotes cientícos para Python como o Numpy e Scipy,por exemplo, tem uma grande porção do seu código escrito emC para máxima performance. Coincidentemente, o primeiro mé-todo que vamos explorar para incorporar código C em programasPython, é oferecido como parte do pacote Scipy.

Weave

O weave é um módulo do pacote scipy, que permite inserir trechosde código escrito em C ou C++ dentro de programas em Python.Existem várias formas de se utilizar o weave dependendo do tipode aplicação que se tem. Nesta seção, vamos explorar apenas aaplicação do módulo inline do weave, por ser mais simples e co-brir uma ampla gama de aplicações. Além disso, utilizações maisavançadas do weave, exigem um conhecimento mais profundo dalinguagem C, o que está fora do escopo deste livro. Caso os exem-plos incluídos não satisfaçam os anseios do leitor, existe uma fartadocumentação no site www.scipy.org.

Vamos começar a explorar o weave com um exemplo trivial(computacionalmente) um simples loop com uma única operação(exemplo 5.1).

Page 135: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.2. INTEGRAÇÃO COM A LINGUAGEM C 101

Listagem 5.1: Otimização de loops com o weave

1 #−∗−encoding : l a t i n −1−∗−2 # Dispon ive l no pacote de programas como :

weaveloop . py3 from s c ipy . weave import i n l i n e , c onve r t e r s4 import time5 from pylab import ∗6

7 code="""8 i n t i =0;9 whi le ( i < n)

10 11 i ^3;12 i++;13 """14 def loopp (n) :15 i=016 while i < n :17 i ∗∗318 i+=119

20 def l oopc (n) :21 return i n l i n e ( code , [ ' n ' ] ,

type_converters=conve r t e r s . b l i t z, compi le r=' gcc ' )

22

23 def bench (max) :24 ptim = [ ]25 ctim = [ ]26 for n in xrange (100 ,max, 100 ) :27 t = time . time ( )28 loopp (n)29 t1=time . time ( )−t

Page 136: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

102CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

30 ptim . append ( t1 )31 t = time . time ( )32 l oopc (n)33 t1=time . time ( )−t34 ctim . append ( t1 )35 return ptim , ctim ,max36

37 ptim , ctim ,max = bench (10000)38 semi logy ( xrange (100 ,max, 100 ) , ptim , 'b−o ' ,

xrange (100 ,max, 100 ) , ctim , ' g−o ' )39 y l ab e l ( ' tempo em segundos ' ) ; x l ab e l (u 'Número

de operações ' ) ; g r i d ( )40 l egend ( [ ' Python ' , 'C ' ] )41 s a v e f i g ( ' weaveloop . png ' , dpi=400)42 show ( )

No exemplo 5.1 podemos ver como funciona o weave. Umastring contém o código C a ser compilado. A função inline com-pila o código em questão, passando para o mesmo as variáveis ne-cessárias.

Note que, na primeira execução do loop, o weave é mais lentoque o Python, devido à compilação do código; mas em seguida,com a rotina já compilada e carregada na memória, este atraso nãoexiste mais.

O weave.inline tem uma performance inferior à de um pro-grama em C equivalente, executado fora do Python. Mas a suasimplicidade de utilização, compensa sempre que se puder obterum ganho de performance sobre o Python puro.

Listagem 5.2: Calculando iterativamente a série de Fibonacci emPython e em C(weave.inline)

1 # Dispon ive l no pacote de programas como :weavef ib . py

2 from s c ipy import weave

Page 137: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.2. INTEGRAÇÃO COM A LINGUAGEM C 103

Figura 5.1: Comparação da performance entre o Python e o C

(weave) para um loop simples. O eixo y está em escala logaritmicapara facilitar a visualização das curvas.

3 from s c ipy . weave import conve r t e r s4 import time5 from s c ipy . s t a t s import bayes_mvs6 from pylab import ∗7

8 code=\9 """

10 whi le (b < n)11 12 i n t savea = a ;

Page 138: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

104CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

13 a=b ;14 b=savea+b ;15 16 return_val = a ;17 """18 def f i bp (n) :19 """20 Calcula s é r i e de Fibonacc i em Python21 """22 a , b = 0 ,123 while b < n :24 a , b = b , a+b25 return a26

27 def f ibw (n) :28 """29 Versão weave . i n l i n e30 """31 a = 032 b = 133 return weave . i n l i n e ( code , [ ' n ' , ' a ' , ' b

' ] ,34 type_converters=conve r t e r s . b l i t z ,

compi le r=' gcc ' )35 ptim = [ ] ; ctim =[ ]36 for i in range (100) :37 t = time . time ( )38 pn = f i bp (1000000000)39 pt = time . time ( )−t ; ptim . append ( pt )40 f ibw (10)#to compi le be f o r e t iming41 t = time . time ( )42 cn = fibw (1000000000)43 ct = time . time ( )−t ; ctim . append ( ct )44 print 'Tempo médio no python : %g segundos '%

Page 139: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.2. INTEGRAÇÃO COM A LINGUAGEM C 105

pt45 print 'Tempo médio no weave : %g segundos '%

ct46 Stat s = bayes_mvs ( array ( ptim ) / array ( ctim ) )47 print "Ace leração média : %g +− %g "% ( Stat s

[ 0 ] [ 0 ] ,48 Stat s [ 2 ] [ 0 ] )

No exemplo 5.2, o ganho de performance do weave.inline jánão é tão acentuado.

Listagem 5.3: Executando o código do exemplo 5.2.

1 $ python weavef ib . py2 Tempo médio no python : 1 .69277 e−05 segundos3 Tempo médio no weave : 1 .3113 e−05 segundos4 Aceleração média : 1 .49554 +− 0.764275

Ctypes

O pacote ctypes, parte integrante do Python a partir da versão2.5, é um módulo que nos permite invocar funções de bibliotecasem C pré-compiladas, como se fossem funções em Python. Apesarda aparente facilidade de uso, ainda é necessário ter consciência dotipo de dados a função, que se deseja utilizar, requer. Por conse-guinte, é necessário que o usuario tenha um bom conhecimento dalinguagem C.

Apenas alguns objetos do python podem ser passados parafunções através do ctypes: None, inteiros, inteiros longos,

strings, e strings unicode. Outros tipos de dados devem serconvertidos, utilizando tipos fornecidos pelo ctypes, compatíveiscom C.

Dado seu estágio atual de desenvolvimento, o ctypes não éa ferramenta mais indicada ao cientista que deseja fazer uso das

Page 140: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

106CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

conveniências do C em seus programas Python. Portanto, vamosapenas dar dois exemplos básicos para que o leitor tenha uma ideiade como funciona o ctypes. Para maiores informações recomen-damos o tutorial do ctypes (http://python.net/crew/theller/ctypes/tutorial.html)

Nos exemplos abaixo assumimos que o leitor está utilizandoLinux pois o uso do ctypes no Windows não é idêntico.

Listagem 5.4: Carregando bibliotecas em C

1 >>> from ctypes import ∗2 >>> l i b c = c d l l . LoadLibrary ( " l i b c . so . 6 " )3 >>> l i b c4 <CDLL ' l i b c . so . 6 ' , handle . . . at . . . >

Uma vez importada uma biblioteca (listagem 5.4), podemoschamar funções como atributos das mesmas.

Listagem 5.5: Chamando fuções em bibliotecas importadas com octypes

1 >>> l i b c . p r i n t f2 <_FuncPtr ob j e c t at 0x . . . >3 >>> print l i b c . time (None )4 11506407925 >>> p r i n t f = l i b c . p r i n t f6 >>> p r i n t f ( "Ola , %s \n" , "Mundo ! " )7 Ola , Mundo !

Pyrex

O Pyrex é uma linguagem muito similar ao Python feita para gerarmódulos em C para o Python. Desta forma, envolve um poucomais de trabalho por parte do usuário, mas é de grande valor paraacelerar código escrito em Python com pouquíssimas modicações.

Page 141: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.2. INTEGRAÇÃO COM A LINGUAGEM C 107

O Pyrex não inclui todas as possibilidades da linguagem Python.As principais modicações são as que se seguem:

• Não é permitido denir funções dentro de outras funções;

• denições de classe devem ocorrer apenas no espaço de no-mes global do módulo, nunca dentro de funções ou de outrasclasses;

• Não é permitido import *. As outras formas de import sãopermitidas;

• Geradores não podem ser denidos em Pyrex;

• As funções globals() e locals() não podem ser utilizadas.

Além das limitações acima, existe um outro conjunto de limita-ções que é considerado temporário pelos desenvolvedores do Pyrex.São as seguintes:

• Denições de classes e funções não podem ocorrer dentro deestruturas de controle (if, elif, etc.);

• Operadores in situ (+=, *=, etc.) não são suportados peloPyrex;

• List comprehensions não são suportadas;

• Não há suporte a Unicode.

Para exemplicar o uso do Pyrex, vamos implementar uma fun-ção geradora de números primos em Pyrex (listagem 5.6).

Listagem 5.6: Calculando números primos em Pyrex

1 # Calcula numeros primos2 def primes ( i n t kmax) :3 cde f i n t n , k , i4 cde f i n t p [ 1 0 0 0 ]

Page 142: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

108CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

5 r e s u l t = [ ]6 i f kmax > 1000 :7 kmax = 10008 k = 09 n = 2

10 while k < kmax :11 i = 012 while i < k and n % p [ i ] <> 0 :13 i = i + 114 i f i == k :15 p [ k ] = n16 k = k + 117 r e s u l t . append (n)18 n = n + 119 return r e s u l t

Vamos analisar o código Pyrex, nas linhas onde ele difere do queseria escrito em Python. Na linha 2 encontramos a primeira pe-culiaridade: o argumento de entrada kmax é denido como inteiropor meio da expressão int kmax. Em Pyrex, devemos declarar ostipos das variáveis. Nas linhas 3 e 4 também ocorre a declaraçãodos tipos das variáveis que serão utilizadas na função. Note comoé denida uma lista de inteiros. Se uma variável não é declarada,o Pyrex assume que ela é um objeto Python.

Quanto mais variáveis conseguirmos declarar como tipos básicosde C, mais eciente será o código C gerado pelo Pyrex. A variávelresult(linha 5) não é declarada como uma lista de inteiros, poisnão sabemos ainda qual será seu tamanho. O restante do códigoé equivalente ao Python. Devemos apenas notar a preferência dolaço while ao invés de um laço do tipo for i in range(x). Esteultimo seria mais lento devido a incluir a função range do Python.

O próximo passo é gerar a versão em C da listagem 5.6, compilare linká-lo, transformando-o em um módulo Python.

Page 143: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.2. INTEGRAÇÃO COM A LINGUAGEM C 109

Listagem 5.7: Gerando Compilando e linkando

1 $ pyrexc primes . pyx2 $ gcc −c −fPIC −I / usr / in c lude /python2 .4/

primes . c3 $ gcc −shared primes . o −o primes . so

Agora vamos comparar a performance da nossa função comuma função em Python razoávelmente bem implementada (Lista-gem 5.8). Anal temos que dar uma chance ao Python, não?

Listagem 5.8: Calculando números primos em Python

1 # Dispon ive l no pacote de programas como :primes2 . py

2 def primes (N) :3 i f N <= 3 :4 return range (2 ,N)5 #te s t a apenas os numeros impares6 primos = [ 2 ] + range (3 ,N, 2 )7 index = 18 #convertendo em i n t e i r o9 #para a c e l e r a r comparacao abaixo

10 top = in t (N ∗∗ 0 . 5 )11 while 1 :12 i = primos [ index ]13 i f i>top :14 break15 index += 116 primos = [ x for x in primos i f ( x %

i ) or ( x == i ) ]17 return primos18 primes (100000)

Comparemos agora a performance das duas funções para en-contrar todos os números primos menores que 100000. Para esta

Page 144: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

110CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

comparação utilizaremos o ipython que nos facilita esta tarefa atra-vés da função mágica %timeit.

Listagem 5.9: Comparando performances dentro do ipython

1 In [ 1 ] : from primes import primes2 In [ 2 ] : from primes2 import primes as primesp3 In [ 3 ] : \% t ime i t primes (100000)4 10 loops , bes t o f 3 : 19 .6 ms per loop5 In [ 4 ] : \% t ime i t primesp (100000)6 10 loops , bes t o f 3 : 512 ms per loop

Uma das desvantagens do Pyrex é a necessidade de compilar elinkar os programas antes de poder utilizá-los. Este problema seacentua se seu programa Python utiliza extensões em Pyrex e pre-cisa ser distribuido a outros usuários. Felizmente, existe um meiode automatizar a compilação das extensões em Pyrex, durante ainstalação de um módulo. O pacote setuptools, dá suporte à compi-lação automática de extensões em Pyrex. Basta escrever um scriptde instalação similar ao da listagem 5.10. Uma vez criado o script(batizado, por exemplo, de setupyx.py), para compilar a nossa ex-tensão, basta executar o seguinte comando: python setupix.py

build.Para compilar uma extensão Pyrex, o usuário deve natural-

mente ter o Pyrex instalado. Entretanto para facilitar a distribui-ção destas extensões, o pacote setuptools, na ausência do Pyrex,procura a versão em C gerada pelo autor do programa, e se ela esti-ver incluida na distribuição do programa, o setuptools passa entãopara a etapa de compilação e linkagem do código C.

Listagem 5.10: Automatizando a compilação de extensões emPyrex por meio do setuptools

1 # Dispon ive l no pacote de programas como :setupyx . py

2 from s e t up t oo l s import setup

Page 145: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.3. INTEGRAÇÃO COM C++ 111

Listagem 5.11: Utilizando Setuptools para compilar extensões emPyrex

1 import s e t up t oo l s2 from s e t up t oo l s . ex t ens i on import Extension

3 from s e t up t oo l s . ex t ens i on import Extension4

5 pr imespix = Extension (name = ' pr imespix ' ,6 sou r c e s = [ ' primes . pyx

' ]7 )8

9 setup (name = ' primes ' ,10 ext_modules = [ pr imespix ]11 )

5.3 Integração com C++

A integração de programas em Python com bibliotecas em C++ énormalmente feita por meio ferramentas como SWIG (www.swig.org), SIP(www.riverbankcomputing.co.uk/sip/) ou Boost.Python(http://www.boost.org/libs/python/). Estas ferramentas, ape-sar de relativamente simples, requerem um bom conhecimento deC++ por parte do usuário e, por esta razão, fogem ao escopo destecapítulo. No entanto, o leitor que deseja utilizar código já escritoem C++ pode e deve se valer das ferramentas supracitadas, cujadocumentação é bastante clara.

Elegemos para esta seção sobre C++. uma ferramenta original.O ShedSkin.

Page 146: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

112CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

Shedskin

O ShedSkin (http://shed-skin.blogspot.com/)se auto intitulaum compilador de Python para C++ otimizado. O que ele faz ,na verdade, é converter programas escritos em Python para C++,permitindo assim grandes ganhos de velocidade. Apesar de seupotencial, o ShedSkin ainda é uma ferramenta um pouco limitada.Uma de suas principais limitações, é que o programa em Python aser convertido deve possuir apenas variáveis estáticas, ou seja asvariáveis devem manter-se do mesmo tipo durante toda a execuçãodo programa. Se uma variável é denida como um número inteiro,nunca poderá receber um número real, uma lista ou qualquer outrotipo de dado.

O ShedSkin também não suporta toda a biblioteca padrão doPython na versão testada (0.0.15). Entretanto, mesmo com estaslimitações, esta ferramenta pode ser muito útil. Vejamos um exem-plo: A integração numérica de uma função, pela regra do trapézio.Esta regra envolve dividir a área sob a função em um dado intervaloem multiplos trapézios e somar as suas áreas(gura 5.2.

Matemáticamente, podemos expressar a regra trapezoidal daseguinte fórmula.∫ b

a

f(x) dx ≈ h

2(f(a) + f(b)) + h

n−1∑i=1

f(a + ih), h =b− a

n(5.1)

Na listagem 5.12 podemos ver uma implementação simples daregra trapezoidal.

Listagem 5.12: implementação da regra trapezoidal(utilizando laçofor) conforme especicada na equação 5.3

1 #−∗−encoding : l a t i n −1−∗−2 # Dispon ive l no pacote de programas como :

t r ap i n t l o op . py3 # copyr ight 2007 by Fláv io Codeço Coelho

Page 147: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.3. INTEGRAÇÃO COM C++ 113

Figura 5.2: Regra trapezoidal para integração aproximada de umafunção.

4 from time import c l o ck5 from math import exp , log , s i n6

7 def t i n t ( a , b , fun ) :8 """9 In teg ração numérica pe la r eg ra

t r ap e z o i d a l10 """11 n = 500000012 h2 = (b−a ) /(n ∗2 . )13 r e s = h2∗ fun ( a )+h2∗ fun (b)14 for i in xrange (n) :15 p = a+i ∗2∗h216 r e s += 2∗h2∗ fun (p)

Page 148: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

114CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

17 return r e s18

19 # Rodando as funcoes em Python20 s t a r t = c lo ck ( )21 r = t i n t ( 1 . 0 , 5 . 0 , lambda( x ) :1+x)22 stop = c lo ck ( )23 print ' r e su l t ado : %d\nTempo : %s seg '%(r , stop

−s t a r t )24 s t a r t = c lo ck ( )25 r = t i n t ( 1 . 0 , 5 . 0 , lambda( x ) : exp (x∗∗2∗ l og ( x+x∗

s i n (x ) ) ) )26 stop = c lo ck ( )27 print ' r e su l t ado : %d\nTempo : %s seg '%(r , stop

−s t a r t )

Executando o script da Listagem 5.12 (trapintloop.py) obser-vamos o tempo de execução da integração das duas funções.

Listagem 5.13: Executando a listagem 5.12

1 $ python t r ap in t l o op . py2 r e su l t ado : 163 Tempo : 11 .68 seg4 r e su l t ado : 490295 Tempo : 26 .96 seg

Para converter o script 5.12 em C++ tudo o que precisamos fazeré:

Listagem 5.14: Vericando o tempo de execução em C++

1 $ s s t r ap i n t l o op . py2 ∗∗∗ SHED SKIN Python−to−C++ Compiler 0 . 0 . 1 5

∗∗∗3 Copyright 2005 , 2006 Mark Dufour ; L i cense

GNU GPL ve r s i on 2 or l a t e r ( See LICENSE)

Page 149: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.3. INTEGRAÇÃO COM C++ 115

4 ( I f your program does not compile , p l e a s email me at mark . dufour@gmail . com ! ! )

5

6 ∗WARNING∗ t r ap i n t l o op : 1 3 : ' xrange ' , 'enumerate ' and ' reversed ' r e turn l i s t sf o r now

7 [ i t e r a t i v e type ana l y s i s . . ]8 ∗∗9 i t e r a t i o n s : 2 templates : 55

10 [ g ene ra t ing c++ code . . ]11 $ make run12 g++ −O3 −I . . .13 . / t r ap i n t l o op14 r e su l t ado : 1615 Tempo : 0 .06 seg16 r e su l t ado : 4902917 Tempo : 1 .57 seg

Com estes dois comandos, geramos, compilamos e executamosuma versão C++ do programa listado em 5.12. O código C++ geradopelo Shed-Skin pode ser conferido na listagem 5.15

Como pudemos vericar, o ganho em performance é conside-rável. Lamentávelmente, o Shed-Skin não permite criar módulosde extensão que possam ser importados por outros programas emPython, só programas independentes. Mas esta limitação pode vira ser superada no futuro.

Listagem 5.15: Código C++ gerado pelo Shed-skin a partir do scripttrapintloopy.py

1 #include " t r ap in t l o op . hpp"2

3 namespace __trapintloop__ 4

5 s t r ∗const_0 ;

Page 150: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

116CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

6

7 double r , s t a r t , stop ;8

9 double __lambda0__(double x ) 10

11 return (1+x) ;12 13

14 double __lambda1__(double x ) 15

16 return exp ( ( ( x∗x ) ∗ l og ( ( x+(x∗ s i n (x ) ) ) ) ) ) ;17 18

19 int __main( ) 20 const_0 = new s t r ( " r e su l t ado : %d\nTempo :

%s seg " ) ;21

22 s t a r t = c lo ck ( ) ;23 r = t i n t ( 1 . 0 , 5 . 0 , __lambda0__) ;24 stop = c lo ck ( ) ;25 pr in t ( "%s \n" , __mod( const_0 , __int ( r ) ,

new f l oat_ ( ( stop−s t a r t ) ) ) ) ;26 s t a r t = c lo ck ( ) ;27 r = t i n t ( 1 . 0 , 5 . 0 , __lambda1__) ;28 stop = c lo ck ( ) ;29 pr in t ( "%s \n" , __mod( const_0 , __int ( r ) ,

new f l oat_ ( ( stop−s t a r t ) ) ) ) ;30 31

32 /∗∗33 In teg ração numérica pe la r eg ra

t r ap e z i oda l34 ∗/35 double t i n t (double a , double b , lambda0 fun )

Page 151: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.4. INTEGRAÇÃO COM A LINGUAGEM FORTRAN 117

36 double h2 , p , r e s ;37 int __0, __1, i , n ;38

39 n = 5000000;40 h2 = ( ( b−a ) /(n ∗2 . 0 ) ) ;41 r e s = ( ( h2∗ fun ( a ) )+(h2∗ fun (b) ) ) ;42

43 FAST_FOR( i , 0 , n , 1 , 0 , 1 )44 p = ( a+(( i ∗2) ∗h2 ) ) ;45 r e s += ((2∗ h2 ) ∗ fun (p) ) ;46 END_FOR47

48 return r e s ;49 50

51 // module namespace52

53 int main ( int argc , char ∗∗ argv ) 54 __shedskin__ : : __init ( ) ;55 __math__ : : __init ( ) ;56 __time__ : : __init ( ) ;57 __trapintloop__ : : __main( ) ;58

5.4 Integração com a Linguagem Fortran

A linguagem Fortran é uma das mais antigas linguagens de pro-gramação ainda em uso. Desenvolvida nos anos 50 pela IBM,foi projetada especicamente para aplicações cientícas. A siglaFortran deriva de IBM mathematical FORmula TRANslationsystem. Dada a sua longa existência, existe uma grande quan-tidade de código cientíco escrito em Fortran disponível para uso.

Page 152: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

118CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

Felizmente, a integração do Fortran com o Python pode ser feitade forma extremamente simples, através da ferramenta f2py, quedemonstraremos a seguir.

f2py

Esta ferramenta está disponível como parte do Pacote numpy (www.scipy.org). Para ilustrar o uso do f2py, vamos voltar ao problemada integração pela regra trapezoidal (equação 5.3). Como vimos, aimplementação deste algoritmo em Python, utilizando um laço for,é ineciente. Para linguagens compiladas como C++ ou Fortran,laços são executados com grande eciência. Vejamos a performancede uma implementação em Fortran da regra trapezoidal (listagem??).

Listagem 5.16: implementação em Fortran da regra trapezoidal.label

1 program t r ap e z i o2 intr ins ic exp , log , s i n3 real l i n e a r , nonl4 external l i n e a r5 external nonl6 ca l l t i n t ( 1 . 0 , 5 . 0 , l i n e a r , r e s )7 print ∗ , "Resultado : " , r e s8 ca l l t i n t ( 1 . 0 , 5 . 0 , nonl , r e s )9 print ∗ , "Resultado : " , r e s

10 end11

12 subroutine t i n t ( a , b , fun , r e s )13 real a , b , r e s14 integer ∗8 n15 real h2 , a l f a16 real fun17 external fun

Page 153: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.4. INTEGRAÇÃO COM A LINGUAGEM FORTRAN 119

18 n = 500000019 Cf2py intent ( in ) a20 Cf2py intent ( in ) b21 Cf2py intent ( in ) fun22 Cf2py intent (out , hide , cache ) r e s23 h2 = (b−a ) /(2∗n)24 a l f a=h2∗ fun ( a )+h2∗ fun (b)25 r e s =0.026 do i =1,n27 p = a+i ∗2∗h228 r e s = r e s+2∗h2∗ fun (p)29 end do30 r e s = r e s+a l f a31 return32 end33

34 real function l i n e a r ( x )35 real x36 Cf2py intent ( in , out ) x37 l i n e a r = x+1.038 return39 end40

41 real function nonl ( x )42 real x43 Cf2py intent ( in , out ) x44 nonl = exp (x∗∗2∗ l og ( x+x∗ s i n (x ) ) )45 return46 end

A listagem 5.17 nos mostra como compilar e executar o códigoda listagem ??. Este comando de compilação pressupõe que vocêpossua o GCC (Gnu Compiler Collection) versão 4.0 ou superior.No caso de versões mais antigas deve-se substituir gfortran por

Page 154: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

120CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

g77 ou f77.

Listagem 5.17: Compilando e executando o programa da listagem??

1 $ g f o r t r an −o t r ap i n t t r ap i n t . f2 $ time . / t r ap i n t3 Resultado : 16 .014284 Resultado : 48941.405

6 r e a l 0m2.028 s7 user 0m1.712 s8 sys 0m0.013 s

Como em Fortran não temos a conveniência de uma funçãopara cronometrar nossa função, utilizamos o comando time doUnix. Podemos constatar que o tempo de execução é similar aoobtido com a versão em C++ (listagem 5.15).

Ainda que não seja estritamente necessário, é recomendávelque o código Fortran seja preparado com comentários especiais(Cf2py), antes de ser processado e compilado pelo f2py. A lista-gem ?? já inclui estes comentários, para facilitar a nossa exposição.Estes comentários nos permitem informar ao f2py as variáveis deentrada e saída de cada função e algumas outras coisas. No exemplo??, os principais parametros passados ao f2py, através das linhasde comentário Cf2py intent(), são in, out, hide e cache. Asduas primeiras identicam as variáveis de entrada e saída da fun-ção ou procedure. O parâmetro hide faz com que a variável desaída res, obrigatoriamente declarada no cabeçalho da procedureem Fortran que oculta ao ser importada no Python. O parâme-tro cache reduz o custo da realocação de memória em variáveis quesão redenidas dentro de um laço em Fortran.

Antes que possamos importar nossas funções em Fortran parauso em um programa em Python, precisamos compilar nossos fontes

Page 155: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.4. INTEGRAÇÃO COM A LINGUAGEM FORTRAN 121

em Fortran com o f2py. A listagem 5.18 nos mostra como fazerisso.

Listagem 5.18: Compilando com f2py

1 $ f2py −m t r a p i n t f −c t r ap i n t . f

Uma vez compilados os fontes em Fortran com o f2py, pode-mos então escrever uma variação do script trapintloop.py (lis-tagem 5.12) para vericar os ganhos de performance. A listagem5.19 contém nosso script de teste.

Listagem 5.19: Script para comparação entre Python e Fortran

via f2py

1 #−∗−encoding : l a t i n −1−∗−2 # Dispon ive l no pacote de programas como :

trapint loopcomp . py3 from time import c l o ck4 from math import exp , log , s i n5 from t r a p i n t f import t i n t as f t i n t , l i n e a r ,

nonl6 def t i n t ( a , b , f ) :7 n = 50000008 h2 = (b−a ) /(n ∗2 . )9 r e s = h2∗ f ( a )+h2∗ f (b )

10 for i in xrange (n) :11 p = a+i ∗2∗h212 r e s += 2∗h2∗ f (p )13 return r e s14 # Rodando as funcoes em Python15 s t a r t = c lo ck ( )16 r = t i n t (1 , 5 , lambda( x ) :1+x)17 stop = c lo ck ( )18 print ' r e su l t ado : %d\nTempo : %s seg '%(r , stop

−s t a r t )

Page 156: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

122CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

19 s t a r t = c lo ck ( )20 r = t i n t (1 , 5 , lambda( x ) : exp (x∗∗2∗ l og ( x+x∗ s i n (

x ) ) ) )21 stop = c lo ck ( )22 print ' r e su l t ado : %d\nTempo : %s seg '%(r , stop

−s t a r t )23 #Rodando as funções em Fortran chamando

Python24 print "tempo do Fortran com funcoes em

Python"25 s t a r t = c lo ck ( )26 r = f t i n t ( 1 . , 5 . , lambda( x ) :1+x)27 print ' r e su l t ado : %d\nTempo : %s seg '%(r ,

c l o ck ( )−s t a r t )28 s t a r t = c lo ck ( )29 r = f t i n t ( 1 . , 5 . , lambda( x ) : exp (x∗∗2∗ l og ( x+x∗

s i n (x ) ) ) )30 print ' r e su l t ado : %d\nTempo : %s seg '%(r ,

c l o ck ( )−s t a r t )31 #Rodando as funções em Fortran puro32 print "tempo do Fortran com funcoes em

Fortran "33 s t a r t = c lo ck ( )34 r = f t i n t ( 1 . , 5 . , l i n e a r )35 print ' r e su l t ado : %d\nTempo : %s seg '%(r ,

c l o ck ( )−s t a r t )36 s t a r t = c lo ck ( )37 r = f t i n t ( 1 . , 5 . , nonl )38 print ' r e su l t ado : %d\nTempo : %s seg '%(r ,

c l o ck ( )−s t a r t )

A listagem 5.19 contem uma versão da regra trapezoidal emPython puro e importa a função tint do nosso programa em Fortran.A função em Fortran é chamado de duas formas: uma para inte-

Page 157: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.4. INTEGRAÇÃO COM A LINGUAGEM FORTRAN 123

grar funções implementadas em Python (na forma funções lambda)e outra substituindo as funções lambda pelos seus equivalentes emFortran.

Executando trapintloopcomp.py, podemos avaliar os ganhosem performance (listagem 5.20). Em ambas as formas de utilizaçãoda função ftint, existem chamadas para objetos Python dentrodo laço DO. Vem daí a degradação da performance, em relação àexecução do programa em Fortran, puramente.

Listagem 5.20: Executando trapintloopcomp.py

1 $ python trapint loopcomp . py2 r e su l t ado : 163 Tempo : 13 .29 seg4 r e su l t ado : 490295 Tempo : 29 .14 seg6 tempo do Fortran com funcoes em Python7 r e su l t ado : 168 Tempo : 7 .31 seg9 r e su l t ado : 48941

10 Tempo : 24 .95 seg11 tempo do Fortran com funcoes em Fortran12 r e su l t ado : 1613 Tempo : 4 .85 seg14 r e su l t ado : 4894115 Tempo : 6 .42 seg

Neste ponto, devemos parar e fazer uma reexão. Será justocomparar a pior implementação possível em Python (utilizandolaços for), com códigos compilados em C++ e Fortran? Realmente,não é justo. Vejamos como se sai uma implementação competenteda regra trapezoidal em Python (com uma ajudinha do pacotenumpy). Consideremos a listagem 5.21.

Listagem 5.21: Implementação vetorizada da regra trapezoidal

Page 158: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

124CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

1 #−∗−encoding : l a t i n −1−∗−2 # Dispon ive l no pacote de programas como :

t r ap i n t v e c t . pt3 from numpy import ∗4 from time import c l o ck5

6 def t i n t ( a , b , fun ) :7 """8 In teg ração numérica pe la r eg ra

t r ap e z o i d a l9 """

10 n = 5000000.11 h = (b−a ) /n12 r e s = h/2∗ fun ( a )+h/2∗ fun (b)+h∗sum(

fun ( arange (a , b , h ) ) )13 return r e s14

15 i f __name__=='__main__ ' :16 s t a r t = c lo ck ( )17 r = t i n t (1 , 5 , lambda( x ) :1+x)18 print ' r e su l t ado : %d\nTempo : %s seg '

%(r , c l o ck ( )−s t a r t )19 s t a r t = c lo ck ( )20 r = t i n t (1 , 5 , lambda( x ) : exp (x∗∗2∗ l og (

x+x∗ s i n (x ) ) ) )21 print ' r e su l t ado : %d\nTempo : %s seg '

%(r , c l o ck ( )−s t a r t )

Executando a listagem 5.21, vemos que a implementação veto-rizada em Python ganha (0.28 e 2.57 segundos)de nossas soluçõesutilizando f2py.

Da mesma forma que com o Pyrex, podemos distribuir progra-mas escritos em Python com extensões escritas em Fortran, coma ajuda do pacote setuptools. Na listagem 5.22 vemos o exem-

Page 159: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.4. INTEGRAÇÃO COM A LINGUAGEM FORTRAN 125

plo de como escrever um setup.py para este m. Neste exemplo,temos um setup.py extrememente limitado, contendo apenas osparâmetros necessarios para a compilação de uma extensão deno-minada flib, a partir de uma programa em Fortran, localizado noarquivo flib.f, dentro do pacote meupacote. Observe, que aodenir módulos de extensão através da função Extension, podemospassar também outros argumentos, tais como outras bibliotecas dasquais nosso código dependa.

Listagem 5.22: setup.py para distribuir programas com extensõesem Fortran

1 import ez_setup2 ez_setup . use_setuptoo l s ( )3 import s e t up t oo l s4 from numpy . d i s t u t i l s . core import setup ,

Extension5 f l i b = Extension (name='meupacote . f l i b ' ,6 l i b r a r i e s = [ ] ,7 l i b r a r y_d i r s = [ ] ,8 f2py_options =[ ] ,9 sou r c e s =[ ' meupacote/

f l i b . f ' ]10 )11 setup (name = 'mypackage ' ,12 ve r s i on = ' 0 . 3 . 5 ' ,13 packages = [ ' meupacote ' ] ,14 ext_modules = [ f l i b ]15 )

Page 160: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

126CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

5.5 A Píton que sabia Javanês Integraçãocom Java

Peço licença ao mestre Lima Barreto, para parodiar o título do seuexcelente conto, pois não pude resistir à analogia. A linguagemPython, conforme descobrimos ao longo deste livro, é extrema-mente versátil, e deve esta versatilidade, em parte, à sua bibliotecapadrão. Entretanto existe uma outra linguagem que excede emmuito o Python (ao menos atualmente), na quantidade de módu-los disponíveis para os mais variados ns: o Java.

A linguagem Java tem, todavia, contra si uma série de fatores:A complexidade de sua sintaxe rivaliza com a do C++, e não é e-ciente, como esperaríamos que o fosse, uma linguagem compilada,com tipagem estática. Mas todos estes aspectos negativos não sãosucientes para anular as vantagens do vasto número de bibliotecasdisponíveis e da sua portabilidade.

Como poderíamos capturar o que o Java tem de bom, sem levarcomo brinde seus aspectos negativos? É aqui que entra o Jython.

O Jython é uma implementação completa do Python 2.21 emJava. Com o Jython programadores Java podem embutir o Pythonem seus aplicativos e applets e nós, programadores Python, pode-mos utilizar, livremente, toda (ou quase toda) a biblioteca padrãodo Python com classes em Java. Além destas vantagens, O Jython

também é uma linguagem Open Source, ou seja de código aberto.

O interpretador Jython

Para iniciar nossa aventura com o Jython, precisaremos instalá-lo,e ter instalada uma máquina virtual Java (ou JVM) versão 1.4 oumais recente.

1O desenvolvimento do Jython continua, mas não se sabe ainda

quando alcançará o CPython (implementação em C do Python).

Page 161: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.5. A PÍTON QUE SABIA JAVANÊS INTEGRAÇÃO COMJAVA 127

Vamos tentar usá-lo como usaríamos o interpretador Python ever se notamos alguma diferença.

Listagem 5.23: Usando o interpretador Jython

1 $ jython2 Jython 2 .1 on java1 .4.2−01 ( JIT : nu l l )3 Type " copyr ight " , " c r e d i t s " or " l i c e n s e " for

more in fo rmat ion .4 >>> print ' h e l l o world '5 h e l l o world6 >>> import math ( )7 >>> d i r (math)8 [ ' acos ' , ' a s i n ' , ' atan ' , ' atan2 ' , ' c e i l ' , '

c l a s sD i c t I n i t ' , ' cos ' , ' cosh ' , ' e ' , ' exp' , ' f abs ' , ' f l o o r ' , ' fmod ' , ' f r exp ' , 'hypot ' , ' ldexp ' , ' l og ' , ' l og10 ' , 'modf ' ,' p i ' , 'pow ' , ' s i n ' , ' s inh ' , ' s q r t ' , '

tan ' , ' tanh ' ]9 >>> math . p i

10 3.141592653589793

Até agora, tudo parece funcionar muito bem. Vamos tentar umexemplo um pouco mais avançado e ver de que forma o Jython

pode simplicar um programa em Java.

Listagem 5.24: Um programa simples em Java usando a classeSwing.

1 import javax . swing . JOptionPane ;2 class t e s tD i a l o g 3 public stat ic void main ( St r ing [ ] a rgs )

4 javax . swing . JOptionPane .

showMessageDialog ( null , " I s t o eum t e s t e . " ) ;

Page 162: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

128CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

5 6

A versão apresentada na listagem 5.24 está escrita em Java.Vamos ver como caria a versão em Jython.

Listagem 5.25: Versão Jython do programa da listagem 5.24.

1 >>> import javax . swing . JOptionPane2 >>> javax . swing . JOptionPane .

showMessageDialog (None , " I s t o e um t e s t e ." )

Podemos observar, na listagem 5.25, que eliminamos a verbor-ragia característica do Java, e que o programa em Jython coubem mais pitônico. Outro detalhe que vale a pena comentar, éque não precisamos compilar (mas podemos se quisermos) o códigoem Jython, como seria necessário com o Java. Só isto já é umagrande vantagem do Jython. Em suma, utilizado-se o Jython aoinvés do Java, ganha-se em produtividade duas vezes: Uma, aoescrever menos linhas de código e outra, ao não ter que recompilaro programa a cada vez que se introduz uma pequena modicação.

Para não deixar os leitores curiosos acerca da nalidade do có-digo apresentado na listagem 5.25, seu resultado encontra-se nagura 5.3.

Criando Applets em Jython

Para os conhecedores de Java, o Jython pode ser utilizado paracriar servlets, beans e applets com a mesma facilidade quecriamos um aplicativo em Jython. Vamos ver um exemplo de ap-plet(listagem 5.26).

Listagem 5.26: Criando um applet em Jython

1 import java . app le t . Applet ;

Page 163: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.5. A PÍTON QUE SABIA JAVANÊS INTEGRAÇÃO COMJAVA 129

Figura 5.3: Saída da listagem 5.25.

2 class appletp ( java . app le t . Applet ) :3 def pa int ( s e l f , g ) :4 g . drawString ( ` `Eu sou um Applet

Jython ! ' ' , 5 , 5 )

Para quem não conhece Java, um applet é um mini-aplicativofeito para ser executado dentro de um Navegador (Mozilla, Operaetc.) que disponha de um plug-in para executar código em Java.Portanto, desta vez, precisaremos compilar o código da listagem5.26 para que a máquina virtual Java possa executá-lo. Para isso,salvamos o código e utilizamos o compilador do Jython, o jythonc.

Listagem 5.27: Compilando appletp.py

1 $ jythonc −−deep −−core −j appletp . j a rappletp . py

2 pro c e s s i ng appletp3

4 Required packages :5 java . app le t6

7 Creat ing adapters :8

9 Creat ing . java f i l e s :

Page 164: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

130CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

10 appletp module11 appletp extends java . app le t . Applet12

13 Compiling . java to . c l a s s . . .14 Compiling with args : [ ' / opt/blackdown−jdk

−1 .4 .2 .01/ bin / javac ' , '− c la s spath ' , '/usr / share / jython / l i b / jython −2.1 . j a r : / usr/ share / l i b r e a d l i n e−java / l i b / l i b r e a d l i n e−java . j a r : . : . / jpywork : : / usr / share / jython /t o o l s / jythonc : /home/ f c c o e l h o /Documents/LivroPython / . : / usr / share / jython /Lib ' ,' . / jpywork/ appletp . java ' ]

15 0 Note : . / jpywork/ appletp . java uses orov e r r i d e s a deprecated API .

16 Note : Recompile with −deprecat ion f o rd e t a i l s .

17

18 Bui ld ing a rch ive : appletp . j a r19 Tracking java dependenc ies :

Uma vez compilado nosso applet, precisamos embuti-lo emum documento HTML (listagem 5.28. Então, basta apontar nossonavegador para este documento e veremos o applet ser executado.

Listagem 5.28: Documento HTML contendo o applet.

1 <html>2 <head>3 <meta content=" text /html ; cha r s e t=ISO

−8859−1"4 http−equiv=" content−type ">5 <t i t l e>jython app le t</ t i t l e>6 </head>7 <body>8 Este

Page 165: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

5.6. EXERCÍCIOS 131

9 &eacute ; o seu app le t em Jython :<br>10 <br>11 <br>12 <center>13 <applet code="appletp " archive="appletp . j a r "

name="Applet em Jython"14 alt="This browser doesn ' t support JDK 1.1

app l e t s . " align="bottom"15 height="50" width="160">16 <PARAMNAME="codebase " VALUE=" . ">17 <h3>Algo sa iu errado ao ca r r ega r18 e s t e app le t .</h3>19 </applet>20 </center>21 <br>22 <br>23 </body>24 </html>

Na compilação, o código em Jython é convertido completa-mente em código Java e então compilado através do compiladorJava padrão.

5.6 Exercícios

1. Compile a listagem 5.1 com o Shed-skin e veja se há ganho deperformance. Antes de compilar, remova as linhas associadasao uso do Weave.

2. Após executar a função primes (listagem 5.6), determine otamanho da lista de números primos menor do que 1000.Em seguida modique o código Pyrex, declarando a variávelresults como uma lista de inteiros, e eliminando a função

Page 166: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

132CAPÍTULO 5. INTERAGINDO COM OUTRAS

LINGUAGENS

append do laço while. Compare a performance desta novaversão com a da versão original.

Page 167: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Parte II

Aplicando o Python aProblemas Cientícos

Concretos

133

Page 168: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas
Page 169: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Capítulo 6

Modelagem Matemática

Introdução à modelagem matemática e sua implementa-ção computacional. Discussão sobre a importância daAnálise dimensional na modelagem e apresentação dopacote Unum para lidar com unidades em Python. Pré-

requisitos:Conhecimentos básicos de cálculo.

A construção de modelos é uma etapa imprescindível, na ca-deia de procedimentos normalmente associada ao método cientíco.Modelos matemáticos são uma tentativa de representar de formalógico/quantitativa, mecanismos que observamos na natureza.

Todo modelo é por denição falso. O modelo é um instrumentode organização de idéias e hipóteses. Como tal, o modelo bom éaquele que representa bem nossas idéias. O que o fará útil para oconhecimento do mundo, dependerá, em grande parte, da qualidadede nossa concepção de mundo. Assim, bons modelos exigem umaboa compreensão do sistema a ser modelado. Alguém pode estarpensando: Se é preciso conhecer bem para modelar, então paraque modelar, se o objetivo for conhecer bem? O grande segredo damodelagem é que o ato de modelar é, em si, um ato de conhecer.Isto é, para criar um modelo, o autor precisa escrutinar todo oseu conhecimento do sistema-alvo: identicar seus componentes,

135

Page 170: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

136 CAPÍTULO 6. MODELAGEM MATEMÁTICA

discriminar o que é relevante do que não é, hipotetizar sobre asrelações causais que regem os processos observados, etc.

Ao se deter nestes detalhes, começam a surgir os vazios do co-nhecimento, buracos a serem preenchidos com experimentos e ob-servações ainda não pensados. Do mesmo modo, observações e in-tuições que antes não faziam muito sentido, começam a se encaixarmelhor. . .

Muitas vezes, o resultado nal de um modelo parece tão óbvio,que nos perguntamos para que serviu. No entanto, o óbvio só setornou óbvio, por causa do ato de modelar.

E aquilo que neste momento se revelará aos povos, nãosurpreenderá a todos por ser exótico, mas pelo fato deter sempre estado oculto, quando terá sido, o óbvio

Caetano Veloso

Outras vezes, os modelos abrem novas avenidas de escrutínio,ao apontar para fenômenos pouco intuitivos (como o caos determi-nístico).

Para matematizar um modelo, existem dois pontos de partida.Podemos construir do zero ou pegar emprestado. Pegar emprestadosignica adaptar um modelo proposto por alguém. A vantagem depegar emprestado é que o modelo já vem com alguma bagagemanalítica. A desvantagem é que ele tolhe a nossa liberdade cri-ativa. Ao olharmos para a história da modelagem, encontramosalguns modelos que caram de tal forma inseridos no imagináriodo modelador que parecem ser os únicos existentes. Um exemploé o modelo de Lotka-Volterra. Ele é tão usado, que as vezes setorna difícil escrever alguma coisa nova sem, inconscientemente,comparar o modelo novo com este padrão.

Modelos, embora falsos, devem ser corretos. Existem dois ní-veis de correção de um modelo matemático: modelos devem tercoerência lógica (isto é, não se pode somar alhos com bugalhos) ecoerência com o modelo mental proposto (isto é, ele deve represen-tar aquilo que o autor quer dizer).

Page 171: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.1. MODELOS 137

Computacionalmente falando, modelos são como máquinas trans-formadoras, produzem informação a partir de informação. Sãoequivalentes, portanto, a funções que, a partir de argumentos, pro-duzem um resultado que consiste na transformação do argumentode entrada, de acordo com o mecanismo codicado dentro de si.

Vamos começar nossa jornada, em direção à representação com-putacional de modelos matemáticos, com uma breve introdução aomodelos mais simples e suas implementações.

6.1 Modelos

Lineares

Modelos lineares representam a relação entre grandezas que variamde forma proporcional. Um exemplo simples é o da corrida detaxi. O valor pago ao motorista numa corrida de taxi é calculadoem função da quilometragem rodada, mais o valor da bandeiradainicial. Digamos que João cobre 0.50 reais por quilômetro rodado euma bandeirada de 2,00. Se rodarmos 10km, pagaremos 0.5x10 =5 reais (+ a bandeirada); se rodarmos o dobro (20km), pagaremoso dobro pela corrida (10 reais) + bandeirada. As duas grandezas -quilometragem rodada e valor pago pela quilometragem - variam deforma proporcional. Vamos supor que João tenha um caderno ondeele registra todas as corridas que faz, incluindo quilometragem,valor pago pela quilometragem e valor total pago (quilometragem+ bandeirada).

Se zermos um diagrama de dispersão com os dados da tabela6.1, obteremos uma reta representando o cenário sem bandeiradae outra para o cenário com bandeirada.

O cálculo da corrida nal é feito pela equação:

R$ = a×Km + b

Page 172: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

138 CAPÍTULO 6. MODELAGEM MATEMÁTICA

Tabela 6.1: Valor de corridas de taxi

corrida km valor/kilometragem valor total1 5 2,50 4,502 8 4,00 6,003 3 1,50 3,504 10 5,00 7,005 9 4,50 6,506 4 2,00 4,007 15 7,50 9,50

onde a é o valor pago por quilômetro rodado (a = 0, 50) e b é ovalor inicial pago (isto é, a bandeirada). Em Python:

1 >>> def t ax i ( t a r i f a ,km, band=2) :2 return t a r i f a ∗km+band3 >>> pr = tax i ( 0 . 5 , 1 0 )4 >>> pr5 7 .0

Vamos ver outros exemplos:Crescimento populacional por imigração constante. Uma po-

pulação é composta inicialmente por 100 indivíduos. A partir doano que chamaremos 0, passaram a chegar 10 novos indivíduos porano. Esta população crescerá, isto é, terá 110 indivíduos no ano1, 120 indivíduos no ano 2, 130 indivíduos no ano 3, etc. Se nószermos um gráco da relação ano x número de indivíduos, tere-mos uma reta crescente. Esta reta intercepta o eixo vertical noponto 100 (população inicial) e tem inclinação dada pelo númerode individuos acrescidos por unidade de tempo (isto é, a = 10).

Decrescimento populacional por emigração constante. Agora,suponha que ao invés de entrar, estão saindo 10 indivíduos a cadaano. Se a população é composta inicialmente por 100 indivíduos,então teremos 90 indivíduos no ano 1; 80 indivíduos no ano 2; 70

Page 173: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.1. MODELOS 139

Figura 6.1: Diagrama de dispersão do exemplo do taxi. A retasuperior descreve o cenário com bandeirada e a inferior, sem ban-deirada.

indivíduos no ano 3, etc. Se nós zermos um gráco da relaçãoentre ano e número de indivíduos, teremos uma reta decrescente.Esta reta intercepta o eixo vertical no ponto 100 (população inicial)e tem inclinação negativa, cujo valor absoluto é dado pelo númerode individuos perdidos por unidade de tempo (isto é, a = −10).

Todos os exemplos dados são especicações de modelos cujoformato geral é:

Page 174: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

140 CAPÍTULO 6. MODELAGEM MATEMÁTICA

Figura 6.2: População crescendo de forma linear, devido à chegadade um número constante de novos indivíduos por ano.

Y = a×X + b

onde a, chamado de coeciente angular, é a taxa de variação dagrandeza Y por unidade de X e b, chamado de coeciente linear, éo valor de Y quando X = 0. Este modelo se expressa gracamentecomo uma reta com ângulo a em relação a linha horizontal e quecruza o eixo vertical no ponto b. Esta reta será crescente se afor maior do que 0; horizontal, se a = 0, e decrescente, se a fornegativo.

Page 175: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.1. MODELOS 141

Figura 6.3: População diminui de forma linear, devido à saida deum número constante de indivíduos por ano.

Propriedades Uma propriedade importante do modelo linear éque a variação de crescimento ou decrescimento é constante e in-dependente do valor de X. No caso da imigração, por exemplo,estavam entrando 10 pessoas todos os anos, independentemente donúmero de pessoas já existentes na população. No caso do taxi, ovalor pago por quilômetro rodado não mudava se a pessoa já tivesserodado 5 ou 20 km.

Page 176: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

142 CAPÍTULO 6. MODELAGEM MATEMÁTICA

Figura 6.4: Representação gráca de um modelo linear. Efeito doparâmetro a.

Exponenciais

O modelo linear descrito na seção anterior, pode ser um bom mo-delo para descrever o crescimento de uma população por imigraçãoconstante. Porém, não nos serve para descrever o crescimento porreprodução. Vejamos o clássico exemplo do crescimento bacterianopor bipartição. Digamos que temos uma população com uma bac-téria no tempo t=0. Após 1 hora, cada bactéria se divide e formaduas bactérias-lha. Estas duas bactérias geram 4 novas bactérias

Page 177: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.1. MODELOS 143

Figura 6.5: Representação gráca de um modelo linear. Efeito doparâmetro b.

em mais uma hora e assim por diante. Se zermos um gráco donúmero de bactérias na população, teremos algo como a gura 6.6.

Veja que o número de novos indivíduos a cada geração não éconstante, como no modelo linear. Agora, ele aumenta de formageométrica. Na primeira geração foram 2 novos indivíduos, nasegunda geração foram 4 e assim por diante. O crescimento é muitomais acelerado e parece tender para uma explosão demográca! Emapenas 10 horas, teremos uma população com 1024 indivíduos e,em um dia, 16.677.216 bactérias!

Page 178: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

144 CAPÍTULO 6. MODELAGEM MATEMÁTICA

Figura 6.6: Crescimento de uma população de bactérias por bipar-tição.

No entanto, embora o crescimento não seja constante no tempo,ele é constante por indivíduo. O que isso quer dizer? Cada indiví-duo na população contribui com o mesmo número de lhos para ageração seguinte,de forma que uma população pequena gerará umnúmero menor de lhotes do que uma população grande.

Este tipo de crescimento dependente do número de indivíduospresentes é chamado de exponencial, pelo fato da variável indepen-

Page 179: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.2. CONSTRUINDO MODELOS DINÂMICOS 145

dente estar no expoente. Matematicamente, ele tem o formato:

Y = wBX

onde w é o número inicial de bactérias (w = 1).Ao contrário do modelo linear, onde a taxa de variação era

independente do número de indivíduos presentes, no modelo ex-ponencial, a taxa de variação é uma função, isto é, depende, donúmero de indivíduos presentes.

6.2 Construindo Modelos Dinâmicos

Na seção anterior vimos como representar fenômenos simples comoexpressões matemáticas. Agora vamos explorar representações maissosticadas: Vamos modelar processos dinâmicos. Processos dinâ-micos modicam-se em função de uma variável independente que,nos casos mais comuns, pode ser o tempo ou o espaço.

Nos modelos estáticos da seção anterior, buscamos expressar oestado do sistema em função de outras variáveis. Uma vez deter-minado os valor destas variáveis, o estado do sistema permaneceinalterado. Agora, não sabemos o que determina o estado do sis-tema, necessáriamente, mas podemos descrever mecanismos quealteram um estado inicial dado.

Neste tipo de modelagem utilizamos equações de diferença(variávelindependente discreta) ou diferenciais (variável independente con-tínua), para modelar a taxa de variação do sistema, representadapelas chamadas variáveis de estado.

Modelando Iterativamente

Vamos começar a explorar os modelos dinâmicos, através de mo-delos com dinâmica temporal discreta. Neste caso, podemos repre-sentar o tempo discreto como a execução iterativa de uma função.

Page 180: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

146 CAPÍTULO 6. MODELAGEM MATEMÁTICA

Figura 6.7: Modelos populacionais discretos. Modelo 2 à esquerdae modelo 1 à direita.

Na listagem 6.1, vemos dois modelos populacionais:

Modelo 1 : Nt+1 = Nt + rNt −mNt + i− eNt

Modelo 2 :

Ct+1 = Ct + raAt −mcCt − eCt

At+1 = At + eCt −maAt

No modelo 1, temos o tamanho da população no tempo seguinte(Nt+1) sendo expresso como uma alteração da população atual pelonascimento de indivíduos a uma taxa r, pela mortalidade (m), epor uxos migratórios (eNt e i).

No modelo 2, temos uma demograa similar, porém agora coma população dividida em dois grupos: crianças (Ct) e adultos (At).

Page 181: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.2. CONSTRUINDO MODELOS DINÂMICOS 147

Nestes modelos, utilizamos um simples laço for para resolvernumericamente as equações de diferença. Representações recursi-vas também seriam possíveis, mas para este exemplo não são ne-cessárias.

Listagem 6.1: Dois modelos discretos de crescimento populacional

1 # Dispon ive l no pacote de programas como :modelo . py

2 #−∗−encoding : l a t i n −1−∗−3 from pylab import ∗4

5 N = [10000 ] #s e r i e temporal de populacao6 n0 = 10000 #populacao i n i c i a l7 t = 100 #per iodo de tempo da

s imulacao8 r = 0 .02 #nata l idade9 m = 0.03 #taxa de morta l idade

10 im = 0 #taxa de imigração11 em = 0 #taxa de emigração12 #parâmetros modelo213 mc = 0.01 #taxa de morta l idade

i n f a n t i l14 ma = 0.01 #taxa de morta l idade adulta15 ra = 0.02 #taxa de reproducao16 e = 0 .1 #taxa de enve lhec imento17 C = [10000 ] #s e r i e temporal de c r i an ça s18 A = [ 0 ] #s e r i e temporal de adu l to s19 a0 = 0 #populacao i n i c i a l de

adu l to s20 c0 = 10000 #populacao i n i c i a l de

c r i an ca s21

22 def Modelo ( n0 ) :23 nf = n0 + r ∗n0 −m∗n0 +im −em∗n0

Page 182: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

148 CAPÍTULO 6. MODELAGEM MATEMÁTICA

24 N. append ( nf )25 return nf26

27 def Modelo2 ( c0 , a0 ) :28 c f = c0 + ra ∗a0 −mc∗ c0 −e∗ c029 a f = a0 + e∗ c0 − ma∗a030 C. append ( c f )31 A. append ( a f )32 return c f , a f33

34 for i in xrange ( t ) :35 c0 , a0 = Modelo2 ( c0 , a0 )36 n0 = Modelo ( n0 )37

38 subplot (121)39 p lo t (A, ' . ' , C, ' r^ ' )40 l egend ( [ ' Adultos ' , ' Cr iancas ' ] )41 x l ab e l ( ' tempo ' )42 subplot (122)43 p lo t (N, ' . ' )44 l egend ( [ u ' População ' ] )45 x l ab e l ( ' tempo ' )46 s a v e f i g ( ' pop . png ' , dpi=400)47 show ( )

Integração Numérica

A simulação de modelos onde a variável independente é contínua, étécnicamente mais complexa. Por isso, neste caso, lançaremos mãodo pacote scipy1.

1http://www.scipy.org

Page 183: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.2. CONSTRUINDO MODELOS DINÂMICOS 149

Modelos dinâmicos contínuos são comumente representados porsistemas de equações diferenciais ordinárias, e sua resolução envolvea integração destas numericamente.

O pacote scipy contém um pacote dedicado à integração nu-mérica de equações diferenciais: o integrate.

1 In [ 1 ] : from s c ipy import i n t e g r a t e

Nesta seção utilizaremos o pacote integrate para resolver umsistema de equações diferenciais ordinárias bem simples:

dP

dt= rP − pPQ (6.1)

dQ

dt= −mQ + PQ

O sistema de equações 6.2, representa a dinâmica de duas popu-lações, P e Q onde Q(predador) alimenta-se de P(presa). Em nossaimplementação, utilizaremos a função odeint do pacote integrate2.Esta função tem como argumentos uma função que retorna as de-rivadas, a partir das condições iniciais, e um vetor de valores davariável independente(t) para os quais os valores das variáveis deestado serão calculados.

Listagem 6.2: Integrando um sistema de equações diferenciais or-dinárias

1 #modelo_ode . py2 # Dispon ive l no pacote de programas como :

modelo_ode . py3 #−∗−encoding : utf−8−∗−4 from s c ipy import i n t e g r a t e

2A função odeint encapsula a tradicional biblioteca lsoda implementada emFortran. Esta biblioteca determina dinâmicamente o algoritmo de integraçãomais adequado a cada passo de integração, selecionando entre o método deAdams e o BDF.

Page 184: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

150 CAPÍTULO 6. MODELAGEM MATEMÁTICA

5 from numpy import ∗6 import pylab as P7

8 class Model :9 def __init__( s e l f , equat ions , i n i t s ,

trange , ) :10 """11 Equations : L i s t a com as equações

d i f e r e n c i a i s na forma de s t r i n g s12 i n i t s : s equenc ia de cond i çõe s

i n i c i a i s13 trange : extensão da s imulação14 """15 s e l f . eqs = equat ions16

17 s e l f . I n i t s = i n i t s18 s e l f . Trange = arange (0 , trange , 0 . 1 )19 s e l f . compileEqs ( )20

21 def compileEqs ( s e l f ) :22 """23 Compila as equações .24 """25 try :26 s e l f . ceqs = [ compi le ( i , '<

equation>' , ' eva l ' ) for i ins e l f . eqs ]

27 except SyntaxError :28 print 'Há um er ro de s i n taxe nas

equações , \ nConserte−o etente novamente '

29

30 def Run( s e l f ) :31 """

Page 185: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.2. CONSTRUINDO MODELOS DINÂMICOS 151

32 Faz a in t eg ra ção numérica .33 """34 t_courseL i s t = [ ]35 t_courseL i s t . append ( i n t e g r a t e . ode int

( s e l f . Equations , s e l f . I n i t s , s e l f .Trange ) )

36 return ( t_courseList , s e l f . Trange )37

38 def Equations ( s e l f , y , t ) :39 """40 Def ine os s i s tema de EDOs ca l cu lando

cada equação41 com base no va lo r an t e r i o r e

retornando as der ivadas .42 """43 #−−−Cria vetor de equações

−−−−−−−−−−−−−−−−−−−−44 eqs = s e l f . ceqs45 Neq=len ( eqs )46 ydot = ze ro s ( (Neq) , 'd ' )47 for k in xrange (Neq) :48 ydot [ k ] = eva l ( eqs [ k ] )49 return ydot50

51 i f __name__=="__main__" :52 i n i t s = [ 1 , 1 ]53 eqs = [ ' 3 .0∗ y [0 ] −2 .0∗y [ 0 ] ∗ y [ 1 ] ' , ' −2.0∗y

[1 ]+y [ 0 ] ∗ y [ 1 ] ' ]54 ODE = Model ( eqs , i n i t s , 1 0 )55 y , t = ODE.Run( )56 #pr in t y57 P. p l o t ( t , y [ 0 ] [ : , 0 ] , ' v− ' , t , y [ 0 ] [ : , 1 ] , ' o

− ' )58 P. legend ( [ ' Presa ' , ' Predador ' ] )

Page 186: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

152 CAPÍTULO 6. MODELAGEM MATEMÁTICA

59 P. s a v e f i g ( ' l v . png ' , dpi=400)60 P. show ( )

O modelo é implementado como uma classe. A implementaçãopoderia ser mais simples, até mesmo feita diretamente do console doPython. Entretanto, esta implementação mais longa nos permiteapresentar algumas outras técnicas interessantes.

O modelo é denido durante a inicialização do objeto, através deatributos obrigatórios. Um método Run() é utilizado para executara integração numérica. É neste método que chamamos a funçãoodeint, passando os argumentos requeridos, a saber: a função queimplementa as equações, os valores iniciais das variáveis de estadoe o vetor de tempos.

A equações são passadas pelo usuário na forma de strings. Estasstrings devem conter uma expressão Python válida.

O método Equations precisa combinar as expressões das equa-ções para poder calcular o valor das derivadas em cada ponto dotempo. Por isso, uma notação de lista foi utilizada para permitirreferências entre as equações. Desta forma, cada variável de estadoé um elemento da lista y.

As expressões representando as equações, são interpretadas pormeio da função eval, a cada passo da integração numérica. Istorequer que as strings contendo as expressões, sejam compiladaspara byte-code, e então interpretadas pelo Python. Para evitarque esta operação seja repetida a cada passo, o método compileEqspré-compila estas expressões, o que acelera em muito a execuçãodo programa 6.2.

Ao nal da listagem 6.2, vemos a especicação do modelo e, nagura 6.8, o seu resultado.

O pacote integrate também nos oferece uma outra interfacepara a integração numérica chamada ode. A classe ode é uma al-ternativa orientada a objetos, à função odeint. A listagem 6.3,mostra como implementar o mesmo sistema de equações (6.2) uti-lizando a classe ode.

Page 187: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.2. CONSTRUINDO MODELOS DINÂMICOS 153

Figura 6.8: Gráco com o resultado da integração do modelo 6.2.

Listagem 6.3: Integração numérica utilizando a classe ODE.

1 # Dispon ive l no pacote de programas como :modelo_ode_minimo . py

2 #−∗−encoding : utf−8−∗−3 from s c ipy import i n t e g r a t e4 from numpy import ∗5 import pylab as P6

7 def Equations ( t , y ) :8 """9 Def ine os s i s tema de EDOs ca l cu lando

cada equacao10 com base no va lo r an t e r i o r e retornando

Page 188: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

154 CAPÍTULO 6. MODELAGEM MATEMÁTICA

as der ivadas .11 """12 #−−−Cria vetor de equacoes

−−−−−−−−−−−−−−−−−−−−13 eqs = [ ' 3 .0∗ y [0 ] −2 .0∗y [ 0 ] ∗ y [ 1 ] ' , ' −2.0∗y

[1 ]+y [ 0 ] ∗ y [ 1 ] ' ]14 Neq=len ( eqs )15 ydot = ze ro s ( (Neq) , 'd ' )16 for k in xrange (Neq) :17 ydot [ k ] = eva l ( eqs [ k ] )18 return ydot19

20 i f __name__=="__main__" :21 r = i n t e g r a t e . ode ( Equations ) .

s e t_ in t eg ra to r ( ' vode ' )22 r . s e t_ in i t i a l_va lu e ( [ 1 , 1 ] , 0 )23 t f = 10 #tempo f i n a l24 dt = 0 .125 t = [ ]26 y = [ ]27 while r . s u c c e s s f u l ( ) and r . t <= t f :28 r . i n t e g r a t e ( r . t+dt )29 t . append ( r . t )30 y . append ( r . y )31 print r . y32 #Plota r e su l t ado s33 P. p l o t ( t , array (y ) [ : , 0 ] , ' v− ' , t , array (y )

[ : , 1 ] , ' o− ' )34 P. t i t l e ( ' In tegrador Vode ' )35 P. legend ( [ ' Presa ' , ' Predador ' ] )36 P. s a v e f i g ( ' lv2 . png ' , dpi=400)37 P. show ( )

Se você necessita construir, simular e analisar modelos de equa-

Page 189: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.3. GRANDEZAS, DIMENSÕES E UNIDADES 155

ções diferenciais com freqüência, talvez prera utilizar um softwaremais completo, desenvolvido por mim, chamado Model-Builder3.

6.3 Grandezas, Dimensões e Unidades

Ao se construir modelos matemáticos, cedo ou tarde nos deparamoscom a necessidade de aproximar o modelo conceitual do sistemareal para dar valor preditivo ao modelo. Este processo envolve omapeamento da métrica do sistema real no modelo matemático,ou seja, fazer com que os parâmetros ou constantes do nosso mo-delo correspondam, numericamente, a mensurações efetuadas nosistema real.

Este processo de parametrização envolve, frequentemente, a uti-lização de medidas das diferentes dimensões do sistema real (massa,comprimento, temperatura, etc). Estas mensurações raramente sãoefetuadas pelo modelador. Este, frequentemente, se utiliza de me-didas publicadas na literatura cientíca, expressas nas mais varia-das unidades de medida. A escolha das unidades de medida nãoaltera as dimensões do objeto de estudo (medir a nossa mesa detrabalho em milímetros ao invés de metros não a torna mais longa),mas altera a ordem de grandeza do valor numérico que representaa dimensão medida.

Os modelos matemáticos relacionam as várias dimensões do sis-tema estudado, por meio das grandezas numéricas que as represen-tam. Por isso, é fundamental que as variáveis e parâmetros donosso modelo que representem uma mesma dimensão do objeto,sejam expressas nas mesmas unidades de medida. Por exemplo,se desenvolvemos um modelo que pretende correlacionar massa docoração com massa corporal, não podemos expressar a massa docoração em gramas(g) e a massa corporal em quilogramas(kg)4.

3http://model-builder.sourceforge.net4A menos que adicionemos contantes ao modelo que re-equilibrem a equa-

ção do ponto de vista dimensional

Page 190: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

156 CAPÍTULO 6. MODELAGEM MATEMÁTICA

Tabela 6.2: Dimensões básicas.

Grandeza física Dimensão Unidade (SI) SímboloComprimento L metro mMassa M quilograma kgTempo T segundo sTemperatura θ kelvin KQuantidadede uma substância N mol molCorrente elétrica I ampére AIntensidade luminosa J candela cd

Grandeza, dimensão e unidade não são sinônimos e devido àubiquidade da sua utilização em modelagem, são conceitos que de-vem estar muito bem denidos na mente de todo modelador.

Unidades derivadas de nomes próprios (e.g. Lord Kelvin,tabela 6.2),têm seu símbolo maiúsculo, mas o nome da unidadeé grafado em minúsculas.

As dimensões de variáveis e parâmetros utilizados em um mo-delo podem representar dimensões físicas diretamente mensuráveisdo sistema, como massa, comprimento, etc. ou podem ser constru-tos do investigador, que visam representar propriedades do sistemaque interessam ao modelo (preço, periculosidade, fecundidade etc.).Devido a isso, antes de começar um trabalho de modelagem, deve-mos denir quais são as nossas dimensões básicas. Estas dimensõessão escolhidas de forma a que todas as outras dimensões utilizadasno modelo, possam ser expressas em termos destas dimensões bá-sicas, ou seja, através de operações algébricas entre as dimensõesbásicas. A tabela 6.2 lista algumas dimensões básicas que podemser úteis no contexto da modelagem de sistemas biológicos.

Várias dimensões derivadas podem ser construídas a partir dolimitado conjunto de dimensões básicas apresentado na tabela 6.2.

Page 191: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.3. GRANDEZAS, DIMENSÕES E UNIDADES 157

Tabela 6.3: Dimensões derivadas.

Grandeza física Dimensão Unidade (SI) Símbolo(derivação)

Área L2 metro2 m2

Volume L3 metro3 m3

Velocidade LT−1 metro/segundo m/sAceleração LT−2 metro/segundo2 m/s2

Força MLT−2 newton N (kg m s−2)Energia ML2T−2 joule J (kg m2 s−2)Potência ML2T−3 watt W (kg m2 s−3)Pressão ML−1T−2 pascal Pa (Nm−2)Viscosidade ML−1T−1 × 10−1 poise PVoltagem ML2T−3I−1 volt VResistência elét. ML2T−3I−2 ohm Ω (V/A)Ângulo graus, radianos graus, radianosVeloc. angular T−1 radianos/seg. radianos/sFrequência T−1 hertz Hz (s−1)

A tabela 6.3 lista dimensões familiares ao leitor e suas derivações.É interessante notar que algumas grandezas físicas são adimen-

sionais (e.g. ângulo, tabela 6.3). Este fato não as impede, entre-tanto, de possuir unidades.

Um ângulo é calculado como a razão entre um dado arco eo raio da circunferência que o dene. Portanto, sua dimensão éL/L = 1.

O fato de um ângulo ser adimensional, faz com que seu valornumérico não se altere, ao se utilizar diferentes unidades de medidapara o raio e o arco da circunferência que o contém. Funções trigo-nométricas são adimensionais pois o argumento destas é um ângulo,que é adimensional. O expoente de uma função exponencial nadamais é do que um logaritmo, e se os logaritmos são adimensionais,

Page 192: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

158 CAPÍTULO 6. MODELAGEM MATEMÁTICA

os expoentes também o serão.

Outros adimensionais:Funções trigonométricas,

Expoentes,Logaritmos,Contagens,π, e, etc.

Por exemplo, em uma equação de crescimento exponencial y =ekt, onde t é o tempo, o parâmetro k deve ter dimensão T−1 paraque o expoente seja adimensional.

Análise Dimensional

Um modo eciente de evitar erros dimensionais na construção dasequações que compõem o nosso modelo, consiste em construir umaversão da equação em questão, substituindo-se as variáveis e parâ-metros por suas unidades ou dimensões. Em seguida, expande-seas expressões em ambos os lados da igualdade em termos das di-mensões básicas. Então simplicamos ao máximo os dois lados daequação e vericamos se são de fato iguais. A este processo dá-seo nome de análise dimensional.

Todas as equações cientícas devem estar dimensionalmentecorretas, assim sendo, a análise dimensional é uma excelente fer-ramentar para analisar nossas formulações. Vamos listar algumasregras básicas da análise dimensional:

1. Dimensões e unidades podem ser combinadas e manipuladas,utilizando-se regras algébricas.

2. Os dois lados de uma equação devem ser dimensionalmenteidênticos.

3. Deve-se tomar cuidado para não cancelar unidades idênticasde objetos independentes. Por exemplo, ml CO2

ml sangue não é uma

Page 193: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.3. GRANDEZAS, DIMENSÕES E UNIDADES 159

expressão adimensional, apesar de ser uma razão entre doisvolumes.

4. Grandezas de dimensões diferentes não podem ser somadasnem subtraídas.

Unidades também podem ser utilizadas, diretamente, em aná-lise dimensional. Unidades derivadas podem ser construídas a par-tir de unidades básicas. Porém, frequentemente, as unidades deri-vadas recebem símbolos especiais para simplicar sua notação (e.g.N , W , J etc. na tabela 6.3).

O Pacote Unum

5 Quando escrevemos nossos modelos em Python, podemos fazeruso de unidades para nossas variáveis de forma a não cometer errosquanto às dimensões do nosso problema. Vamos explorar algumaspossibilidades interativamente dentro do Ipython.

1 In [ 1 ] : from unum. un i t s import ∗2 In [ 2 ] :M3 Out [ 2 ] : 1 . 0 [m]

Uma vez importadas as unidades do módulo units, podemosrepresentar números com unidades. No exemplo acima temos arepresentação de 1 metro. As classes que representam as unida-des são derivadas das classes que representam os números purosem Python; portanto, todas as operações aritméticas válidas paranúmeros, são possíveis para números com unidades. O Unum vemcom muitas unidades pré denidas, mas estas podem ser redeni-das, durante a sessão, assim como novas unidades podem ser de-nidas. Todas as unidades prédenidas são denidas em maiúsculaspara facilitar a sua diferenciação de nomes associados a variáveis.

5O pacote Unum pode ser baxado de http://home.scarlet.be/be052320/Unum.html.

Page 194: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

160 CAPÍTULO 6. MODELAGEM MATEMÁTICA

Qualquer grandeza pode ser denida multiplicando-se um númeropor uma unidade.

1 In [ 3 ] : a=3∗M2 In [ 4 ] : t=1∗S3 In [ 5 ] : a/ t4 Out [ 5 ] : 3 . 0 [m/ s ]5 In [ 6 ] : 1 / ( 3 ∗M/S)6 Out [ 6 ] : 0 . 3 33333333333 [ s /m]7 In [ 7 ] : 2 5 ∗M∗∗28 Out [ 7 ] : 2 5 . 0 [m2]9 In [ 8 ] : ( 3 ∗M) ∗(4∗M)

10 Out [ 8 ] : 1 2 . 0 [m2]11 In [ 9 ] : 1 3 ∗KG∗M/S∗∗212 Out [ 9 ] : 1 3 . 0 [ kg .m/ s2 ]

Grandeza adimensionais também podem ser representadas.

1 In [ 1 0 ] : ( 2 ∗ M/S) ∗ (3 ∗ S/M)2 Out [ 1 0 ] : 6 . 0 [ ]

Agora que já aprendemos a operar com unidades, vamos imple-mentar um simples modelo com unidades.

1 In [ 1 1 ] : massa=1.5∗KG2 In [ 1 2 ] : v e l o c idade=2∗M/S3 In [ 1 3 ] : en e r g i a_c in e t i c a=(massa∗ ve l o c idade

∗∗2) /24 In [ 1 4 ] : en e r g i a_c in e t i c a5 Out [ 1 4 ] : 3 . 0 [ kg .m2/ s2 ]

Evitando Erros

Utilizar unidades não é apenas uma questao estética, também podeajudar a evitar enganos:

Page 195: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.3. GRANDEZAS, DIMENSÕES E UNIDADES 161

1 In [ 1 5 ] : en e r g i a_c in e t i c a+3∗KG2 DimensionError : [ kg .m2/ s2 ] incompat ib le with

[ kg ]3 In [ 1 6 ] :M∗∗KG4 DimensionError : un i t [ kg ] unexpected

No exemplo acima, somos lembrados de que não podemos somargrandezas com unidades diferentes, nem elevar metros a quilogra-mas! Expoentes devem sempre ser adimensionais.

Também podemos fazer conversões de unidades. Vamos con-verter nossa energia cinética em joules:

1 In [ 1 7 ] : en e r g i a_c in e t i c a . as ( J )2 Out [ 1 7 ] : 3 . 0 [ J ]

Integração com Funções Matemáticas

Já vimos que logaritmos e ângulos são adimensionais; portanto fun-ções logarítmicas e trigonométricas não aceitam números com uni-dades. No caso dos ângulos podemos usar pseudo-unidades comoRAD(radianos) e ARCDEG(graus).

1 In [ 1 8 ] : from math import pi , log10 , s in , cos2 In [ 1 9 ] : l og10 (M/ANGSTROM)3 Out [ 1 9 ] : 1 0 . 04 In [ 2 0 ] : cos (180∗ARCDEG)5 Out [ 20 ] : −1 . 06 In [ 2 4 ] : cos ( p i ∗RAD)7 Out [ 24 ] : −1 . 08 In [ 2 5 ] : f = 440∗HZ9 In [ 2 6 ] : s i n ( f )

10 DimensionError : un i t [ Hz ] unexpected11 In [ 2 7 ] : dt = 0 .1 ∗ S12 In [ 2 8 ] : s i n ( f ∗dt ∗2∗ pi )13 Out [28 ] :−3.9198245344040927 e−14

Page 196: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

162 CAPÍTULO 6. MODELAGEM MATEMÁTICA

As unidade do Unum também funcionam bem com outras estru-turas de dados, como matrizes do Numpy, por exemplo.

1 In [ 1 ] : from unum. un i t s import ∗2 In [ 2 ] : from numpy import ∗3 In [ 3 ] : a= arange (10) ∗M4 In [ 4 ] : a5 Out [ 4 ] :6 array ( [ 0 . 0 [m] , 1 . 0 [m] , 2 . 0 [m] , 3 . 0 [m] ,

4 . 0 [m] , 5 . 0 [m] , 6 . 0 [m] ,7 7 .0 [m] , 8 . 0 [m] , 9 . 0 [m] ] , dtype=

ob j e c t )8 In [ 5 ] : a∗∗29 Out [ 5 ] :

10 array ( [ 0 . 0 [m2] , 1 . 0 [m2] , 4 . 0 [m2] , 9 . 0 [m2] , 16 .0 [m2] , 25 .0 [m2] ,

11 36 .0 [m2] , 49 .0 [m2] , 64 .0 [m2] , 81 .0[m2 ] ] , dtype=ob j e c t )

Por m, o Unum também simplica automáticamente expres-sões de unidades. No exemplo abaixo, o Unum sabe que uma pressãomultiplicada por uma área é uma força. Portanto, converte a uni-dade para Newtons (N).

1 In [ 6 ] : f o r c a = PA ∗ M∗∗22 In [ 7 ] : f o r c a3 Out [ 7 ] : 1 . 0 [N]

Conforme já mencionamos, também podemos criar novas uni-dades. Vejamos abaixo como fazer isso:

Listagem 6.4: Criando novas unidades.

1 In [ 1 ] : from unum import Unum2 In [ 2 ] : un i t = Unum. un i t3 In [ 3 ] :LEGUA = uni t ( ' l egua ' )4 In [ 4 ] :LEGUA

Page 197: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.3. GRANDEZAS, DIMENSÕES E UNIDADES 163

5 Out [ 4 ] : 1 . 0 [ l egua ]6 In [ 5 ] :KLEGUA = unit ( ' k i l o l e g u a ' ,1000∗LEGUA)7 In [ 6 ] : 2 0 ∗KLEGUA+1∗LEGUA8 Out [ 6 ] : 2 0 . 0 0 1 [ k i l o l e g u a ]

Uma Aplicação Concreta

Muitas vezes, ao modelar um sistema biológico, a relação entregrandezas biológicas e físicas não é óbvia. Nestes casos, a análisedimensional pode ajudar a validar nossas formulações. Suponhaque um pesquisador deseje determinar o trabalho realizado pelocoração. Ele se lembra da física que:

Trabalho(J) = Forca(N)× distancia(m)

Esta equação não é diretamente aplicável ao coração, pois este nãose desloca e a força que exerce não é facilmente mensurável. Con-tudo, a força exercida pelo coração se reete na pressão sanguínea,e o volume de sangue bombeado parece ser análogo à distânciada fórmula original. Então nosso pesquisador-modelador escreve,timidamente, a seguinte fórmula:

Trabalho = Pressao× V olume

Mas como saber se esta relação é correta? Fazendo a análise di-mensional.

Trabalho(J) = Pressao× V olume =N

m2×m3 = N m = J

Esta denição de Trabalho (N m), não é a mesma da tabela 6.3mas um pouco de álgebra pode demonstrar a sua validade6. Como Unum, isso seria uma tarefa trivial:

6Lembre-se de que Trabalho=Energia.

Page 198: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

164 CAPÍTULO 6. MODELAGEM MATEMÁTICA

1 In [ 8 ] : J == PA ∗ M∗∗32 Out [ 8 ] : True

Para que uma análise dimensional funcione com unidades, de-vemos nos manter em um mesmo sistema de unidades. O sistemautilizado em ciência é o chamado Sistema Internacional (SI). Asunidades apresentadas nas tabelas 6.2 e 6.3 estão de acordo com oSI.

Um detalhe em relação a unidades que é frequentemente malentendido, é a aplicação de fatores de escala normalmente expressoscomo prexos às unidades (ver tabela 6.4). Devido a este fato oSI é frequentemente denominado sistema MKS (metro, kilograma,segundo). Um outro sistema que frequentemente é confundido como SI é o CGS (centímetro, grama, segundo). Apesar deste último sediferenciar do SI apenas nos prexos, é um sistema completamentediferente.

MKS vs. CGS

Força(MKS):Newton (m · kg/s2)Força(CGS):Dyne (cm · g/s2)

Ao adicionar ou modicar prexos de unidades estamos aban-donando nosso sistema de unidades original e nossas equações nãoestarão mais equilibradas dimensionalmente, a menos que realize-mos as correções necessárias nos demais termos da equação.

Para re-equilibrar dimensionalmente equações cujas unidadesde uma ou mais de suas variáveis tenham sido modicadas, preci-samos incluir fatores de correção.

Consideremos a relação entre a massa corporal e a massa doCoração:

Y = 0.006M

Page 199: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.3. GRANDEZAS, DIMENSÕES E UNIDADES 165

Tabela 6.4: Prexos de Unidades

Prexo Símbolo Fator Prexo Símbolo Fatoryocto y 10−24 deca da 10zepto z 10−21 hecto h 102

atto a 10−18 kilo k 103

femto f 10−15 mega M 106

pico p 10−12 giga G 109

nano n 10−9 tera T 1012

micro µ 10−6 peta P 1015

mili m 10−3 exa E 1018

centi c 10−2 zetta Z 1021

deci d 10−1 yotta Y 1024

colocando esta equação em termos dimensionais:

M = 1 ·M

se quisermos expressar a massa do coração em gramas (CGS), man-tendo a massa corporal em kg (SI/MKS), basta apenas multiplicar-mos o lado direito da equação por 1000 para reequilibrar a equação.Assim, teríamos:

Y = 6M

Contudo, nem sempre a determinação dos fatores de correção étão óbvia. Vejamos a seguinte equação, que relaciona a massa dofígado com a massa corporal (ambas em kg):

Mf = 0.082 ·M0.87c (6.2)

Esta relação se mantém, para mamíferos, ao longo de várias ordensde magnitude de tamanho. Se estivéssemos interessados apenas empequenos roedores, seria mais conveniente trabalhar com gramas aoinvés de kilogramas. O investigador desavisado, determina a massade um hamster (200g), o aplica na equação 6.2: e obtém o seguinte

Page 200: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

166 CAPÍTULO 6. MODELAGEM MATEMÁTICA

resultado:Mf = 8.24

Este valor não seria correto nem em gramas e muito menos emkg! O que poderia estar errado? Por desencargo de consciência,ele decide realizar o cálculo novamente aplicando a massa em kg(0.2kg):

Mf = 0.020kg

este resultado (20g) parece mais realístico. Analisando dimensio-nalmente a equação, podemos entender o que deu errado em nossaconversão de unidades:

Mf = 0.082 · (1000 ·Mc)0.87

Se esta equação possui apenas duas variáveis, ambas de massa,porque a simples substituição de unidades não funciona? A res-posta está no fato de que a massa corporal está elevada a 0.87,portanto sua unidade não é mais Kg, da mesma forma que 1 metroquadrado não é igual a 1 metro. Para a equação ser válida dimen-sionalmente, a constante 0.082 não pode ser adimensional. Paradescobrir a sua unidade basta rearranjarmos a equação,

Mf

M0.87c

= 0.082

e resolvê-la com o Unum. Como vemos a unidade de nossa constanteé kg0.13.

1 In [ 1 3 ] :KG/KG∗∗0 .872 Out [ 1 3 ] : 1 . 0 [ kg0 . 1 3 ]

se quisermos multiplicar a unidade da massa do coração por 1000(Kg → g), temos que multiplicar a unidade da constante por 1000também e isso representa multiplicá-la por 10000.13. Podemos ve-ricar que esta operação retorna um número 1000 vezes o valor emKg, ou seja, o valor em gramas.

Page 201: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

6.4. EXERCÍCIOS 167

1 In [ 2 0 ] : 1 0 00∗∗0 . 1 3∗KG∗∗0 .13 ∗1000∗∗0.87∗KG∗∗0 .87

2 Out [ 2 0 ] : 1 0 0 0 . 0 [ kg ]3 In [ 2 1 ] : 0 . 0 8 2 ∗ ( 1 0 0 0 ∗ ∗ 0 . 1 3 ) ∗ (200∗∗0 .87)4 Out [21 ] : 20 . 216685199791563

6.4 Exercícios

1. Determine as dimensões das seguintes grandezas (manual-mente e depois utilizando o Unum):

a) Volume

b) Aceleração (velocidade/tempo)

c) Densidade (massa/volume)

d) Força (massa × aceleração)

e) Carga elétrica (corrente × tempo)

2. Utilizando as repostas da questão anterior determine as di-mensões das seguintes grandezas:

a) Pressão (força/área)

b) (volume)2

c) Campo elétrico (força/carga elétrica)

d) Trabalho (força × distância)

e) Energia Potencial Gravitacional (= mgh =massa× ace-leração gravitacional × altura)

Page 202: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas
Page 203: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Capítulo 7

Teoria de GrafosBreve introdução a teoria de grafos e sua representaçãocomputacional. Introdução ao Pacote NetworkX, vol-tado para a manipulação de grafos. Pré-requisitos:

Programação orientada a objetos.

7.1 Introdução

A teoria de grafos é uma disciplina da matemática cujo objeto deestudo se presta, muito bem, a uma representação computacionalcomo um objeto. Matematicamente, um grafo é denido por umconjunto nito de vértices (V ) e por um segundo conjunto (A) derelações entre estes vértices, denominadas arestas. Grafos tem apli-cações muito variadas, por exemplo: uma árvore genealógica é umgrafo onde as pessoas são os vértices e suas relações de parentescosão as arestas do grafo.

Um grafo pode ser denido de forma não ambígua, por sua listade arestas (A), que implica no conjunto de vértices que compõemo grafo. Grafos podem ser descritos ou mensurados através de umconjunto de propriedades:

• Grafos podem ser direcionados ou não;

169

Page 204: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

170 CAPÍTULO 7. TEORIA DE GRAFOS

• A ordem de um grafo corresponde ao seu número de vértices;

• O tamanho de um grafo corresponde ao seu número de ares-tas;

• Vértices, conectados por uma aresta, são ditos vizinhos ouadjacentes;

• A ordem de um vértice corresponde ao seu número de vizi-nhos;

• Um caminho é uma lista de arestas que conectam dois vérti-ces;

• Um ciclo é um caminho que começa e termina no mesmovértice;

• Um grafo sem ciclos é denominado acíclico.

A lista acima não exaure as propriedades dos grafos, mas ésuciente para esta introdução.

Podemos representar um grafo como um objeto Python de vá-rias maneiras, dependendo de como desejamos utilizá-lo. A formamais trivial de representação de um grafo em Python seria feitautilizando-se um dicionário. A Listagem 7.1 mostra um dicionáriorepresentando o grafo da gura 7.1. Neste dicionário, utilizamoscomo chaves os vértices do grafo associados a suas respectivas listasde vizinhos. Como tudo em Python é um objeto, poderíamos jános aproveitar dos métodos de dicionário para analisar nosso grafo(Listagem 7.2).

Listagem 7.1: Denindo um grafo como um dicionário.

1 >>> g = ' a ' : [ ' c ' , ' d ' , ' e ' ] , ' b ' : [ ' d ' , ' e ' ] , ' c ': [ ' a ' , ' d ' ] , ' d ' : [ ' b ' , ' c ' , ' a ' ] , ' e ' : [ ' a ' , ' b' ]

Page 205: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

7.1. INTRODUÇÃO 171

Figura 7.1: Um grafo simples.

Podemos utilizar o método keys para obter uma lista dos vér-tices de nosso grafo.

Listagem 7.2: Obtendo a lista de vértices.

1 >>> g . keys ( )2 [ ' a ' , ' c ' , ' b ' , ' e ' , ' d ' ]

Uma extensão do conceito de grafos é o conceito de redes. Redessão grafos nos quais valores numéricos são associados às suas ares-tas. Redes herdam as propriedade dos grafos e possuem algumaspropriedades especícas.

A representação de redes, a partir de objetos pitônicos simples,como um dicionário, também é possivel. Porém, para dar maisalcance aos nossos exemplos sobre teoria de grafos, vamos nos uti-

Page 206: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

172 CAPÍTULO 7. TEORIA DE GRAFOS

lizar do pacote NetworkX1 que já implementa uma representaçãobastante completa de grafos e redes em Python.

7.2 NetworkX

O pacote NetworkX se presta à criação, manipulação e estudo daestrutura, dinâmica e funções de redes complexas.

A criação de um objeto grafo a partir de seu conjunto de ares-tas, A, é muito simples. Seja um grafo G com vértices V =W,X, Y, Z:

G : A = (W,Z), (Z, Y ), (Y, X), (X, Z)

Listagem 7.3: Denindo um grafo através de seus vértices

1 # Dispon ive l no pacote de programas como :graph1 . py

2 import networkx as NX3

4 G = NX. Graph ( )5 G. add_edges_from ( [ ( 'W' , 'Z ' ) , ( 'Z ' , 'Y ' ) , ( 'Y ' , '

X ' ) , ( 'X ' , 'Z ' ) ] )6 print G. nodes ( ) , G. edges ( )

Executando o código acima, obtemos:

[′Y ′,′X ′,′ Z ′,′W ′][(′Y ′,′X ′), (′Y ′,′ Z ′), (′X ′,′ Z ′), (′Z ′,′W ′)]

Ao lidar com grafos, é conveniente representá-los gracamente.Vejamos como obter o diagrama do grafo da listagem 7.3:

Listagem 7.4: Diagrama de um grafo

1https://networkx.lanl.gov/

Page 207: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

7.2. NETWORKX 173

1 # Dispon ive l no pacote de programas como :graph2 . py

2 import networkx as NX3

4 G = NX. Graph ( )5 G. add_edges_from ( [ ( 'W' , 'Z ' ) , ( 'Z ' , 'Y ' ) , ( 'Y ' , '

X ' ) , ( 'X ' , 'Z ' ) ] )6

7 import pylab as P8 NX. draw (G)9 P. show ( )

A funcionalidade do pacote NetworkX é bastante ampla. Aseguir exploraremos um pouco desta funcionalidade.

Construindo Grafos

O NetworkX oferece diferentes classes de grafos, dependendo do tipode aplicação que desejada. Abaixo, temos uma lista dos comandospara criar cada tipo de grafo.

G=Graph() Cria um grafo simples e vazio G.

G=DiGraph() Cria grafo direcionado e vazio G.

G=XGraph() Cria uma rede vazia, ou seja, com arestas que po-dem receber dados.

G=XDiGraph() Cria uma rede direcionada.

G=empty_graph(n) Cria um grafo vazio com n vértices.

G=empty_graph(n,create_using=DiGraph()) Cria um grafodirecionado vazio com n vértices.

G=create_empty_copy(H) Cria um novo grafo vazio do mesmotipo que H.

Page 208: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

174 CAPÍTULO 7. TEORIA DE GRAFOS

Figura 7.2: Diagrama de um grafo

Manipulando Grafos

Uma vez de posse de um objeto grafo instanciado a partir de umadas classes listadas anteriormente, é de interesse poder manipulá-lode várias formas. O próprio objeto dispõe de métodos para estem:

G.add_node(n) Adiciona um único vértice a G.

G.add_nodes_from(lista) Adiciona uma lista de vértices a G.

G.delete_node(n) Remove o vértice n de G.

G.delete_nodes_from(lista) Remove uma lista de vértices deG.

Page 209: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

7.2. NETWORKX 175

G.add_edge(u,v) Adiciona a aresta (u,v) a G. Se G for umgrafo direcionado, adiciona uma aresta direcionada u −→ v.Equivalente a G.add_edge((u,v)).

G.add_edges_from(lista) Adiciona uma lista de arestas a G.

G.delete_edge(u,v) Remove a aresta (u,v).

G.delete_edges_from(lista) Remove uma lista de arestas deG.

G.add_path(listadevertices) Adiciona vértices e arestas de formaa compor um caminho ordenado.

G.add_cycle(listadevertices) O mesmo que add_path, excetoque o primeiro e o último vértice são conectados, formandoum ciclo.

G.clear() Remove todos os vértices e arestas de G.

G.copy() Retorna uma cópia rasa do grafo G.2

G.subgraph(listadevertices) Retorna subgrafo correspondenteà lista de vértices.

Criando Grafos a Partir de Outros Grafos

subgraph(G, listadevertices) Retorna subgrafo de G correspon-dente à lista de vértices.

union(G1,G2) União de grafos.

disjoint_union(G1,G2) União disjunta, ou seja, assumindo quetodos os vértices são diferentes.

2Uma cópia rasa signica que se cria um novo objeto grafo referenciandoo mesmo conteúdo. Ou seja, se algum vértice ou aresta for alterado no grafooriginal, a mudança se reete no novo grafo.

Page 210: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

176 CAPÍTULO 7. TEORIA DE GRAFOS

cartesian_product(G1,G2) Produto cartesiano de dois grafos(Figura 7.3).

compose(G1,G2) Combina grafos, identicando vértices commesmonome.

complement(G) Retorna o complemento do grafo(Figura 7.3).

create_empty_copy(G) Cópia vazia de G.

convert_to_undirected(G) Retorna uma cópia não direcionadade G.

convert_to_directed(G) Retorna uma cópia não direcionadade G.

convert_node_labels_to_integers(G) Retorna uma cópia comos vértices renomeados como números inteiros.

Gerando um Grafo Dinamicamente

Muitas vezes, a topologia da associação entre componentes de umsistema complexo não está dada a priori. Frequentemente, estaestrutura é dada pela própria dinâmica do sistema.

No exemplo que se segue, simulamos um processo de contágioentre os elementos de um conjunto de vértices, observando ao nal,a estrutura produzida pelo contágio.

Listagem 7.5: Construindo um grafo dinamicamente

1 # Dispon ive l no pacote de programas como :g ra f od in . py

2 import networkx as NX3 import threading , random , pylab as P4

5 class Contagio :

Page 211: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

7.2. NETWORKX 177

Figura 7.3: Grafo, produto cartesiano e complemento.

6 def __init__( s e l f , nome) :7 s e l f . nome = nome8 s e l f . doente = 09 s e l f . t ransmite ( )

10 def t ransmite ( s e l f ) :11 i f G. doentes == G. order ( ) :12 return13 for a lvo in random . sample (G. nodes ( )

, 3 ) :14 i f not a lvo . doente :15 G. add_edge ( ( s e l f , a lvo ) )16 print "%s i n f e c t ou %s"%( s e l f

Page 212: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

178 CAPÍTULO 7. TEORIA DE GRAFOS

. nome , a lvo . nome)17 t = thread ing . Thread ( t a r g e t=

alvo . cont ra iu ( ) )18 t . s t a r t ( )19 def cont ra iu ( s e l f ) :20 s e l f . doente +=121 G. doentes +=122 s e l f . t ransmite ( )23

24 G = NX.XDiGraph ( )25 G. doentes = 026 nos = [ Contagio (n) for n in xrange (80) ]27 G. add_nodes_from ( nos )28 caso_indice = G. nodes ( ) [ 0 ]29 caso_indice . cont ra iu ( )30 print "usamos %s das a r e s t a s p o s s i v e i s "%(NX.

dens i ty (G) )31 print NX. degree_histogram (G) , G. doentes32 nomes = d i c t ( [ ( no , no . nome) for no in G. nodes

( ) ] )33 NX. draw (G, l a b e l s=nomes , alpha =0.7 , width=2,

s t y l e=' dotted ' , node_size=450 , f on t_s i z e=14)

34 P. s a v e f i g ( ' contag io . png ' , dpi=400)35 P. show ( )

Módulo threading: Permite executar mais de uma parte doprograma em paralelo, em um o de execução independente.Este os, compartilham todas as variáveis globais e qualqueralteração nestas é imediatamente visível a todos os outros os.

O objeto grafo do NetworkX aceita qualquer objeto como umvértice. Na listagem 7.5, nos valemos deste fato para colocar ins-

Page 213: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

7.2. NETWORKX 179

tâncias da classe Contagio como vértices do grafo G. O grafo G écontruído somente por vértices (desconectado). Então infectamosum vértice do grafo, chamando o seu método contraiu(). O vér-tice, após declarar-se doente e incrementar o contador de doentesa nível do grafo, chama o método transmite().

O método transmite assume que durante seu período infec-cioso, cada vértice tem contatos efetivos com apenas dez outrosvértices. Então cada vértice irá transmitir para cada um destes,desde que não estejam já doentes.

Cada vértice infectado inicia o método contraiu em um th-read separado. Isto signica que cada vértice sai infectando osrestantes, em paralelo. Na verdade, como o interpretador Pythonsó executa uma instrução por vez, cada um destes objetos recebedo interpretador uma fatia de tempo por vez, para executar suastarefas. Pode ser que o tempo de uma destas fatias seja sucientepara infectar a todos no seu grupo, ou não. Depois que o processose desenrola, temos a estrutura do grafo como resultado (Figura7.4)

Construindo um Grafo a Partir de Dados

O conceito de grafos e redes é extremamente útil na representaçãoe análise de sistemas complexos, com muitos componentes que serelacionam entre si. Um bom exemplo é uma rede social, ou seja,uma estrutura de interação entre pessoas. Esta interação podeser medida de diversas formas. No exemplo que se segue, vamostentar inferir a rede social de um indivíduo, por meio de sua caixade mensagens.

Listagem 7.6: Construindo uma rede social a partir de e-mails

1 # Dispon ive l no pacote de programas como :mnet . py

2 import email , sys3 import emai l . Errors

Page 214: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

180 CAPÍTULO 7. TEORIA DE GRAFOS

Figura 7.4: Resultado da simulação do exemplo 7.5.

4 import mailbox5 import networkx as NX6 from pylab import show7

8 def msgfactory ( fp ) :9 try :

10 return emai l . message_from_file ( fp )11 except emai l . Errors . MessageParseError :12 return ' '13

14 def starG (mess ,G) :15 try :

Page 215: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

7.2. NETWORKX 181

16 centro = mess . get ( ' from ' ) . s p l i t ( )[ −1 ] . s t r i p ( '<> ' )

17 pontas = [ j . s p l i t ( ) [ −1 ] . s t r i p ( '<> ' )for j in mess . ge t_a l l ( ' to ' ) [ 0 ] .s p l i t ( ' , ' ) ]

18 a r e s t a s = [ ( centro , k ) for k inpontas ]

19 G. add_edges_from ( a r e s t a s )20 return G21 except :22 print ' f a lhou '23

24 d i r=' /home/ f l a v i o /Mail / inbox '25 # Veja documentacao do modulo mailbox26 # para outros t i po de mai lboxes .27 mbox = mailbox . Mai ld i r ( d i r , msgfactory ) #

mailbox do kmail28 G = NX. DiGraph ( )29 for n in xrange (50) :30 i = mbox . next ( )31 starG ( i ,G)32 print G. nodes ( )33 G = NX. convert_node_labels_to_integers (G)34 NX. draw (G, width=2, s t y l e=' dotted ' , alpha

=0.5)35 show ( )

Na Listagem 7.6, usamos dois módulos interessantes da bibli-oteca padrão do Python: O módulo email e o módulo mailbox.mailbox.

Módulo email: Módulo para decodicar, manusear, e com-por emails.

Page 216: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

182 CAPÍTULO 7. TEORIA DE GRAFOS

Módulo mailbox: Conjuto de classes para lidar com caixasde correio no formato Unix, MMDF e MH.

Neste exemplo, utilizei a minha mailbox associada com o pro-grama Kmail; portanto, se você usa este mesmo programa, bastasubstituir o diretório de sua mailbox e o programa irá funcionarpara você. Caso use outro tipo de programa de email, consulte adocumentaçao do Python para buscar a forma correta de ler o seumailbox.

A classe Maildir retorna um iterador, que por sua vez, retor-nará mensagens decodicadas pela função msgfactory, denida pornós. Esta função se utiliza do módulo email para decodicar amensagem.

Cada mensagem recebida é processada para gerar um grafo dotipo estrela, com o remetente no centro e todos os destinatáriosda mensagem nas pontas. Este grafo é então adicionado ao grafooriginal, na forma de uma lista de arestas. Depois de todas asmensagens terem sido assim processadas, geramos a visualizaçãodo grafo (Figura 7.5).

7.3 Exercícios

1. Determine o conjunto de arestas A que maximiza o tamanhodo grafo cujos vértices são dados por V = a, b, c, d, e.

2. No exemplo do contágio, verique se existe alguma relaçãoentre o tamanho da amostra de cada vértice e a densidadenal do grafo.

3. Ainda no exemplo do contágio, refaça o experimento com umgrafo de topologia dada a priori no qual os vértices só podeminfectar seus vizinhos.

Page 217: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

7.3. EXERCÍCIOS 183

Figura 7.5: Rede social a partir de mensagens de email.

4. Insira um print no laço for do exemplo 7.6 para ver o formatode saída do iterador mbox.

5. Modique o programa 7.6 para associar apenas mensagensque contêm uma palavra em comum.

Page 218: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas
Page 219: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Capítulo 8

Interação com Bancos deDados

Apresentação dos módulos de armazenamento de dadosPickle e Sqlite3 que fazem parte da distribuição padrãodo Python. Apresentação do pacote SQLObject paracomunicação com os principais sistemas de bancos dedados existentes. Pré-requisitos: Conhecimentos bá-sicos de bancos de dados e SQL.

Ogerenciamento de dados não se constitui numa disciplina cien-tíca per se. Entretanto, cada vez mais, permeia as atividades

básicas de trabalho cientíco. O volume crescente de dados e o au-mento de sua complexidade há muito ultrapassou a capacidade degerenciamento através de simples planilhas.

Atualmente, é muito comum a necessidade de se armazenar da-dos quantitativos, qualitativos e mídias dos mais diferentes forma-tos(imagens, vídeos, sons) em uma plataforma integrada de ondepossam ser facilmente acessados para ns de análise, visualizacãoou simplesmente consulta.

A linguagem Python dispõe de soluções simples para resolveresta necessidade em seus mais distintos níveis de sosticação. Se-guindo a losoa de baterias incluídas do Python, a sua biblioteca

185

Page 220: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

186 CAPÍTULO 8. INTERAÇÃO COM BANCOS DE DADOS

padrão nos apresenta o módulo Pickle e cPickle e, a partir da versão2.5, o banco de dados relacional sqlite3.

8.1 O Módulo Pickle

O módulo pickle e seu primo mais veloz cPickle, implementamalgoritmos que permitem armazenar, em um arquivo, objetos im-plementados em Python.

Listagem 8.1: Exemplo de uso do módulo pickle

1 In [ 1 ] : import p i c k l e2 In [ 2 ] : class o i :3 . 2 . : def d i gao i ( s e l f ) :4 . 2 . : print " o i "5 In [ 3 ] : a= o i ( )6 In [ 4 ] : f = open ( ' p i c t e s t e ' , 'w ' )7 In [ 5 ] : p i c k l e . dump(a , f )8 In [ 6 ] : f . c l o s e ( )9 In [ 7 ] : f = open ( ' p i c t e s t e ' , ' r ' )

10 In [ 8 ] : b=p i c k l e . load ( f )11 In [ 9 ] : b . d i g ao i ( )12 o i

Como vemos na listagem 8.1, com o módulo pickle podemos arma-zenar objetos em um arquivo, e recuperá-lo sem problemas para usoposterior. Contudo, uma característica importante deste módulonão ca evidente no exemplo 8.1. Quando um objeto é armaze-nado por meio do módulo pickle, nem o código da classe, nemseus dados, são incluidos, apenas os dados da instância.

1 In [ 1 0 ] : class o i :2 . 1 0 . : def d i gao i ( s e l f , nome=' f l a v i o ' ) :3 . 1 0 . : print ' o i %s ! '%nome4

5 In [ 1 1 ] : f = open ( ' p i c t e s t e ' , ' r ' )

Page 221: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

8.2. O MÓDULO SQLITE3 187

6 In [ 1 2 ] : b=p i c k l e . load ( f )7 In [ 1 3 ] : b . d i g ao i ( )8 o i f l a v i o !

Desta forma, podemos modicar a classe, e a instância arma-zenada reconhecerá o novo código ao ser restaurada a partir doarquivo, como podemos ver acima. Esta característica signicaque os pickles não se tornam obsoletos quando o código em queforam baseados é atualizado (naturalmente isto vale apenas paramodicações que não removam atributos já incluídos nos pickles).

O módulo pickle não foi construído para armazenamento dedados, pura e simplesmente, mas de objetos computacionais com-plexos, que podem conter em si, dados. Apesar desta versatilidade,peca por consistir em uma estrutura de armazenamento legível ape-nas pelo próprio módulo pickle em um programa Python.

8.2 O módulo Sqlite3

Este módulo passa a integrar a biblioteca padrão do Python a partirda versão 2.5. Portanto, passa a ser uma excelente alternativapara usuários que requerem a funcionalidade de um banco de dadosrelacional compatível com SQL1.

O Sqlite nasceu de uma biblioteca em C que disponibilizavaum banco de dados extremamente leve e que dispensa o conceitoservidor-cliente. No sqlite, o banco de dados é um arquivo ma-nipulado através da biblioteca sqlite.

Para utilizar o sqlite em um programa Python, precisamos im-portar o módulo sqlite3.

1 In [ 1 ] : import s q l i t e 3

1SQL signica Structured Query Language. o SQL é um padrão internaci-onal na interação com bancos de dados relacionais. Para saber mais, consultehttp://pt.wikipedia.org/wiki/SQL

Page 222: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

188 CAPÍTULO 8. INTERAÇÃO COM BANCOS DE DADOS

O próximo passo é a criação de um objeto conexão, atravésdo qual podemos executar comandos SQL.

1 In [ 2 ] : c = s q l i t e 3 . connect ( ' /tmp/exemplo ' )

Agora dispomos de um banco de dados vazio, consistindo noarquivo exemplo, localizado no diretório /tmp. O sqlite tambémpermite a criação de bancos de dados em RAM; para isso bastasubstituir o nome do arquivo pela string :memory:. Para po-dermos inserir dados neste banco, precisamos primeiro criar umatabela.

1 In [ 3 ] : c . execute ( ' ' ' c r e a t e t ab l e espec imes (nome text , a l t u r a r ea l , peso r e a l ) ' ' ' )

2 Out [3 ] : < s q l i t e 3 . Cursor ob j e c t at 0x83fed10>

Note que os comandos SQL são enviados como strings através doobjeto Connection, método execute. O comando create table

cria uma tabela; ele deve ser necessáriamente seguido do nome databela e de uma lista de variáveis tipadas(entre parênteses), cor-respondendo às variáveis contidas nesta tabela. Este comando criaapenas a estrutura da tabela. Cada variável especicada corres-ponderá a uma coluna da tabela. Cada registro, inserido subse-quentemente, formará uma linha da tabela.

1 In [ 4 ] : c . execute ( ' ' ' i n s e r t i n to espec imesva lue s ( ' tom ' , 1 2 . 5 , 2 . 3 ) ' ' '

O comando insert é mais um comando SQL útil para inserirregistros em uma tabela.

Apesar dos comandos SQL serem enviados como strings atravésda conexão, não se recomenda, por questão de segurança, utilizaros métodos de formatação de strings (' ... values(%s,%s)'%(1,2))do Python. Ao invés, deve-se fazer o seguinte:

1 In [ 5 ] : t = ( ' tom ' , )2 In [ 6 ] : c . execute ( ' s e l e c t ∗ from espec imes

where nome=? ' , t )

Page 223: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

8.2. O MÓDULO SQLITE3 189

3 In [ 7 ] : c . f e t c h a l l ( )4 [ ( ' tom ' , 12 . 5 , 2 .2999999999999998) ]

No exemplo acima utilizamos o método fetchall para recupe-rar o resultado da operação. Caso desejássemos obter um únicoregistro, usaríamos fetchone.

Abaixo, vemos como inserir mais de um registro a partir deestruturas de dados existentes. Neste caso, trata-se de repetir aoperação descrita no exemplo anterior, com uma sequência de tu-plas representando a sequência de registros que se deseja inserir.

1 In [ 8 ] : t = ( ( ' j e r r y ' , 5 . 1 , 0 . 2 ) , ( ' butch ', 4 2 . 4 , 1 0 . 3 ) )

2 In [ 9 ] : for i in t :3 . 9 . : c . execute ( ' i n s e r t i n to espec imes

va lue s ( ? , ? , ? ) ' , i )

O objeto cursor também pode ser utilizado como um iteradorpara obter o resultado de uma consulta.

1 In [ 1 0 ] : c . execute ( ' s e l e c t ∗ from espec imesby peso ' )

2 In [ 1 1 ] : for reg in c :3 print reg4 ( ' j e r r y ' , 5 . 1 , 0 . 2 )5 ( ' tom ' , 12 . 5 , 2 .2999999999999998)6 ( ' butch ' , 4 2 . 4 , 1 0 . 3 )

O módulo sqlite é realmente versátil e útil, porém, requer queo usuário conheça, pelo menos, os rudimentos da linguagem SQL.A solução apresentada a seguir procura resolver este problema deuma forma mais pitônica.

Page 224: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

190 CAPÍTULO 8. INTERAÇÃO COM BANCOS DE DADOS

8.3 O Pacote SQLObject

O pacote SQLObject2 estende as soluções apresentadas até agorade duas maneiras: oferece uma interface orientada a objetos parabancos de dados relacionais e, também, nos permite interagir comdiversos bancos de dados sem ter que alterar nosso código.

Para exemplicar o sqlobject, continuaremos utilizando o sqlitedevido à sua praticidade.

Construindo um aranha digital

Neste exemplo, teremos a oportunidade de construir uma aranhadigital que recolherá informações da web (Wikipedia3) e as arma-zenará em um banco sqlite via sqlobject.

Para este exemplo, precisaremos de algumas ferramentas quevão além do banco de dados. Vamos explorar a capacidade dabiblioteca padrão do Python para interagir com a internet, e va-mos nos utilizar de um pacote externo para decodicar as páginasobtidas.

Listagem 8.2: Módulos necessários

1 # d i spon i v e l no pacote de programas como :aranha . py

2 import networkx as NX3 from Beaut i fu lSoup import SoupStrainer ,

Beaut i fu lSoup as BS4 from Beaut i fu lSoup import Beaut i fu lStoneSoup

as XS5 import sys , os , u r l l i b 2 , u r l l i b , re6 from s q l o b j e c t import ∗

2http://www.sqlobject.org/3http://pt.wikipedia.org

Page 225: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

8.3. O PACOTE SQLOBJECT 191

O pacote BeautifulSoup4 é um destrinchador de páginas daweb. Um dos problemas mais comuns ao se lidar com páginas html,é que muitas delas possuem pequenos defeitos em sua construçãoque nossos navegadores ignoram, mas que podem atrapalhar umaanálise mais minuciosa. Daí o valor do BeautifulSoup; ele é ca-paz de lidar com páginas defeituosas, retornando uma estrutura dedados com métodos que permitem uma rápida e simples extraçãoda informação que se deseja. Além disso, se a página foi criadacom outra codicação, o BeautifulSoup, retorna todo o conteúdoem Unicode, automaticamente, sem necessidade de intervenção dousuário.

Da biblioteca padrão, vamos nos servir dos módulos sys, os,

urllib, urllib2 e re. A utilidade de cada um cará clara àmedida que avançarmos no exemplo.

O primeiro passo é especicar o banco de dados. O sqlobjectnos permite escolher entre MySQL, PostgreSQL, sqlite, Firebird,MAXDB, Sybase, MSSQL, ou ADODBAPI. Entretanto, conforme já ex-plicamos, nos restringiremos ao uso do banco sqlite.

Listagem 8.3: Especicando o banco de dados.

8 l a r a cnad i r = os . path . expanduser ( ' ~/. l a racna ')

9 i f not os . path . e x i s t s ( l a r a cnad i r ) :10 os . mkdir ( l a r a cnad i r )11 sqlhub . processConnect ion = connectionForURI (

' s q l i t e : // '+l a r a cnad i r+' /knowdb ' )

Na listagem 8.3, criamos o diretório(os.mkdir) onde o bancode dados residirá (se necessário) e denimos a conexão com obanco. Utilizamos os.path.exists para vericar se o diretórioexiste. Como desejamos que o diretório que na pasta do usuário,e não temos como saber, de antemão, qual é este diretório, utiliza-

4http://www.crummy.com/software/BeautifulSoup/

Page 226: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

192 CAPÍTULO 8. INTERAÇÃO COM BANCOS DE DADOS

mos os.path.expanduser para substituir o por /home/usuariocomo aconteceria no console unix normalmente.

Na linha 11 da listagem 8.3, vemos o comando que cria a cone-xão a ser utilizada por todos os objetos criados neste módulo.

Em seguida, passamos a especicar a tabela do nosso bancode dados como se fora uma classe, na qual seus atributos são ascolunas da tabela.

Listagem 8.4: Especicando a tabela ideia do banco de dados.

16 class I d e i a ( SQLObject ) :17 nome = UnicodeCol ( )18 n l i nk s = IntCol ( )19 l i n k s = Pick leCo l ( )20 ender = Str ingCol ( )

A classe que representa nossa tabela é herdeira da classe SQLObject.Nesta classe, a cada atributo (coluna da tabela) deve ser atribuidoum objeto que dene o tipo de dados a ser armazenado. Nesteexemplo, vemos quatro tipos distintos, mas existem vários outros.UnicodeCol representa textos codicados como Unicode, ou seja,podendo conter caracteres de qualquer língua. IntCol correspondea números inteiros. PickleCol é um tipo muito interessante poispermite armazenar qualquer tipo de objeto Python. O mais in-teressante deste tipo de coluna, é que não requer que o usuárioinvoque o módulo pickle para armazernar ou ler este tipo de variá-vel, As variáveis são convertidas/reconvertidas automaticamente,de acordo com a operação. Por m, temos StringCol que é umaversão mais simples de UnicodeCol, aceitando apenas strings decaracteres ascii. Em SQL é comum termos que especicar dife-rentes tipos, de acordo com o comprimento do texto que se desejaarmazenar em uma variável. No sqlobject, não há limite parao tamanho do texto que se pode armazenar tanto em StringCol

quanto em UnicodeCol

Page 227: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

8.3. O PACOTE SQLOBJECT 193

A funcionalidade da nossa aranha foi dividida em duas classes:Crawler, que é o rastejador propriamente dito, e a classe UrlFac

que constrói as urls a partir da palavra que se deseja buscar naWikipedia.

Cada página é puxada pelo módulo urllib2. A função urlencodedo módulo urllib, facilita a adição de dados ao nosso pedido, deforma a não deixar transparecer que este provém de uma aranhadigital. Sem este disfarce, a Wikipedia recusa a conexão.

A páginas são então analisadas pelo método verResp, no qualo BeautifulSoup tem a chance de fazer o seu trabalho. Usandoa função SoupStrainer, podemos ltrar o resto do documento,que não nos interessa, analizando apenas os links (tags 'a') cujodestino são urls começadas pela string /wiki/. Todos os artigosda wikipedia, começam desta forma. Assim, evitamos perseguirlinks externos. A partir da sopa produzida, extraímos apenas asurls, ou seja, o que vem depois de href=. Podemos ver na listagem8.5 que fazemos toda esta ltragem sosticada em duas linhas decódigo(55 e 56), graças ao BeautifulSoup.

Listagem 8.5: Restante do código da aranha.

15 u r l a t u a l = ' '16 class I d e i a ( SQLObject ) :17 nome = UnicodeCol ( )18 n l i nk s = IntCol ( )19 l i n k s = Pick leCo l ( )20 ender = Str ingCol ( )21

22 class Crawler :23 def __init__( s e l f , s t a r t u r l , depth ) :24 try :25 I d e i a . c reateTab le ( )26 except :27 pass28 s e l f .SU = s t a r t u r l

Page 228: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

194 CAPÍTULO 8. INTERAÇÃO COM BANCOS DE DADOS

29 s e l f . depth = depth30 s e l f . f i l a =[ ]31 s e l f . depth = depth32 s e l f . curdepth = 033 s e l f . s t a r t ed = 034 s e l f . n l i nk s = 035 s e l f . h i s t o r y = [ ]36 s e l f .G = NX. Graph ( )37 def parsePag ( s e l f , ur lend ) :38 u r l a t u a l = ur lend39 user_agent = ' Moz i l l a /4 .0 (

compatible ; MSIE 5 . 5 ; Windows NT) '

40 va lue s = 'name ' : ' John Smith ' ,41 ' l o c a t i o n ' : ' Northampton ' ,42 ' language ' : ' Python ' 43 headers = ' User−Agent ' :

user_agent 44 data = u r l l i b . ur l encode ( va lue s )45 print "Abrindo " , ur lend46 req = u r l l i b 2 . Request ( urlend , data ,

headers )47 fd = u r l l i b 2 . ur lopen ( req )48 html = fd . read ( )49 return html50

51 def verResp ( s e l f , html ) :52 ' ' '53 Ve r i f i c a se r e spo s ta e um h i t ou nao54 ' ' '55 l nka r t = SoupStra iner ( ' a ' , h r e f=re .

compi le ( '^/wik i /∗ ' ) )56 a r t l i s t = [ tag [ ' h r e f ' ] for tag in

BS( html , parseOnlyThese=lnka r t ) ]

Page 229: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

8.3. O PACOTE SQLOBJECT 195

57 i f a r t l i s t [ 0 ] . endswith ( ' Disambig . svg' ) :

58 s e l f . f i l a . append ( ' http :// '+langa tua l+' . w ik iped ia . org '+a r t l i s t [ 3 ] )

59 s e l f . c u r l i n k s = a r t l i s t60 else :61 s e l f . c u r l i n k s = a r t l i s t62 I d e i a (nome=nomeatual , n l i nk s =

len ( a r t l i s t ) , l i n k s =a r t l i s t , ender = u r l a t u a l )

63 s e l f .G. add_edges_from ( [ (nomeatual , i ) for i in s e l f .c u r l i n k s ] )

64 i f s e l f . curdepth > s e l f . depth :65 return66 s e l f . f i l a . extend ( [ ' http :// '+

langa tua l+' . w ik iped ia . org ' +i for i in a r t l i s t ] )

67 s e l f . curdepth +=168

69 def move( s e l f ) :70 i f not s e l f . f i l a :71 i f not s e l f . s t a r t ed :72 s e l f . f i l a . append ( s e l f .SU)73 while s e l f . f i l a :74 s e l f . s t a r t ed = 175 u r l a t u a l = s e l f . f i l a . pop (0 )76 nomeatual = u r l a t u a l . s p l i t ( ' / ' )

[−1]77 i f " : " in nomeatual : continue78 i f nomeatual in [ 'Main_page ' ]+

s e l f . h i s t o r y : continue79 print "buscando " , nomeatual ,

Page 230: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

196 CAPÍTULO 8. INTERAÇÃO COM BANCOS DE DADOS

80 print "Faltam " , l en ( s e l f . f i l a )81 try :82 html = s e l f . parsePag (

u r l a t u a l )83 except :84 continue85 s e l f . verResp ( html )86 s e l f . n l i nk s +=187 s e l f . h i s t o r y . append ( nomeatual )88

89

90 class UrlFac :91 def __init__( s e l f , lang=' en ' ) :92 global l anga tua l93 s e l f . lang = lang94 l anga tua l = lang95 def u r l i f i c a ( s e l f , pa lavra ) :96 nomeatual = palavra97 u = "http :// "+s e l f . lang+" . wik iped ia .

org /wik i /"+palavra98 u r l a t u a l = u99 return u

100

101 i f __name__=="__main__" :102 UF = UrlFac ( ' pt ' )103 u = UF. u r l i f i c a ( sys . argv [ 1 ] )104 Cr = Crawler (u , 1 )105 Cr .move ( )

A listagem 8.5 mostra o restante do código da aranha e o lei-tor poderá explorar outras solução implementadas para otimizaro trabalho da aranha. Note que não estamos guardando o htmlcompleto das páginas para minimizar o espaço de armazenamento,mas este programa pode ser modicado facilmente de forma a reter

Page 231: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

8.4. EXERCÍCIOS 197

todo o conteúdo dos artigos.

8.4 Exercícios

1. Modique a aranha apresentada neste capítulo, para guardaros documentos varridos.

2. Crie uma classe capaz de conter os vários aspectos (links,guras, etc) de um artigo da wikipedia, e utilize a aranha paracriar instâncias desta classe para cada artigo encontrado, apartir de uma única palavra chave. Dica: para simplicar apersistência, armazene o objeto artigo como um Pickle, nobanco de dados.

Page 232: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas
Page 233: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Capítulo 9

Simulações EstocásticasSeleção de problemas relacionados com a simulação eanálise de processos estocásticos. Pré-requisitos: Co-nhecimentos avançados de estatística.

Neste capítulo, ilustraremos métodos computacionais voltadospara a geração e análise de processos estocásticos.

Em probabilidade, um processo estocástico é uma função queproduz resultados aleatórios. Se o domínio desta função for otempo, o processo estocástico se manifestará como uma série tem-poral. Processos estocásticos espaciais, geram os chamados camposaleatórios

Exemplos de processo estocáticos são séries temporais de preçosde ações, utuações de populações, distribuição espacial de polui-ção particulada.

Muitos processos estocásticos naturais possuem estrutura emmeio à aleatoriedade. Muitas das técnicas desenvolvidas para lidarcom estes processos visam encontrar esta estrutura.

9.1 Números Aleatórios

Ao se estudar processos estocásticos por meio computacional, oprimeiro problema que se precisa resolver é o da geração de núme-

199

Page 234: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

200 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

ros aleatórios de forma conável. Felizmente, hoje em dia, pacotescomo o numpy ou o scipy, fornecem geradores de números aleató-rios de qualidade para muitas famílias de distribuições, de formaque na maioria das vezes não precisamos nos preocupar com esteproblema. Vez por outra, problemas de amostragem mais com-plexos podem exigir geradores mais sosticados. Neste capítuloexploraremos algumas destas situações.

Hipercubo Latino - LHS

A técnica de amostragem do hipercubo latino, mais conhecida peloseu nome original Latin Hypercube Sampling ou simplesmenteLHS, é uma técnica de geração de amostras aleatórias a partir deuma distribuição conhecida. O diferencial deste algoritmo é queele garante a amostragem de áreas de baixa probabilidade, mesmoem amostras de tamanho pequeno a moderado (Figura 9.1).

A vantagem de se utilizar o LHS está na redução do custo com-putacional necessário para cobrir o espaço amostral, sem deixarbrechas signicativas.

O algoritmo do LHS funciona particionando o suporte da va-riável em um número n de intervalos equiprováveis, onde n é onúmero de amostras que se deseja obter (Figura 9.2). Então re-tiramos uma amostra de cada intervalo (quantis) denido no eixoy da gura 9.21. Isto é feito por amostragem uniforme naquelesintervalos (Linha 8 da listagem 9.1). Invertendo-se a função dedensidade acumulada, obtemos as amostras de x correspondentes.Esta inversão é calculada por meio da função ppf (percentile pointfunction) que é o inverso da função de densidade acumulada (Li-nha 9 da listagem 9.1). As amostras assim geradas equivalem aamostras retiradas da distribuição de x, mas com uma coberturahomogênea do seu suporte. Na listagem 9.1, a amostragem porHipercubo Latino é implementadada como uma função de apenas

1Veja no programa lhsexp.py como o gráco da gura 9.2 foi gerado

Page 235: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.1. NÚMEROS ALEATÓRIOS 201

Figura 9.1: Amostragem (n=20) de uma distribuição normal commédia 0 por LHS (histograma mais escuro) e amostragem padrãodo scipy (histograma mais claro).

três linhas, graças à utização dos geradores de números aleatóriosdisponíveis no módulo stats do scipy. Neste módulo os geradoressão classes portadoras de métodos muito convenientes como o rvs

que gera amostras aleatórias, e o ppf(ou percentile point function)que representa a inversa da função de densidade acumulada. Alémdos métodos utilizados neste exemplo, existem muitos outros. Oleitor é encorajado a explorar estas classes e seus métodos.

Listagem 9.1: Amostragem por Hipercubo latino (LHS)

1 #!/ usr /bin /python2 # Dispon ive l no pacote de programas como :

Page 236: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

202 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

Figura 9.2: Distribuição acumulada da variável x ∼ N(0, 1), mos-trando o particionamento do espaço amostral em segmentos equi-prováveis.

l h s . py3 from pylab import plot , f i gu r e , h i s t , show ,

s a v e f i g4 import s c ipy . s t a t s as s t a t s5 import numpy6

7 def l h s ( d i s t , parms , n=100) :8 perc = numpy . arange ( 0 , 1 . , 1 . / n)9 smp = [ s t a t s . uniform ( i , 1 . / n) . rvs ( ) for i

in perc ]10 v = d i s t ( parms [ 0 ] , 1 . / parms [ 1 ] ) . ppf (smp)

Page 237: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.2. INFERÊNCIA BAYESIANA 203

11 return v12

13 i f __name__=='__main__ ' :14 c=lh s ( s t a t s . norm , [ 0 , 1 ] , 2 0 )15 h i s t ( c )16 n = s t a t s . norm . rvs ( s i z e =20)17 h i s t (n . r av e l ( ) , f a c e c o l o r=' r ' , alpha =0.3)18 s a v e f i g ( ' l h s . png ' , dpi=400)19 show ( )

9.2 Inferência Bayesiana

Atualmente, a resolução de problemas de inferência Bayesiana deconsiderável complexidade, tem se tornado cada vez mais acessível,graças à utilização de métodos computacionais. Isto não signicaque a computação bayesiana seja simples; pelo contrário. Entre-tanto, as vantagens da inferência Bayesiana sobre a abordagemfrequentista, justicam um certo esforço por parte do pesquisadorno sentido de dominar estas técnicas.

Antes de chegarmos às técnicas computacionais utilizadas pararesolver os problemas da inferência Bayesiana, vamos nos deterum pouco sobre o porquê da intratabilidade analítica da inferênciaBayesiana, aplicada a modelos complexos.

Sejam dois eventos E e F . A probabilidade condicional de Edado F é dada por:

P (E | F ) =P (E ∩ F )

P (F )

A partir desta fórmula, podemos obter a versão mais simplesdo teorema de Bayes.

P (E | F ) =P (F | E)P (E)

P (F )

Page 238: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

204 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

Se particionarmos o eventos E em n eventos, mutuamente ex-cludentes, pelo teorema da probabilidade total, chegaremos à ver-são mais comumente utilizada da fórmula de Bayes:

P (Ei | F ) =P (F | Ei)P (Ei)∑ni=1 P (F | Ei)P (Ei)

O teorema de Bayes nos permite calcular as probabilidades de umconjunto de hipóteses explanatórias (Ei), dado que observamos cer-tos fatos (F ): P (Ei | F ). Mas o teorema de Bayes também nosdiz que estas probabilidades dependem das probabilidades a pri-ori das hipóteses P (Ei) (antes da observação dos fatos). Dadasestas, o teorema de Bayes nos fornece uma excelente ferramentapara atualização de nossos conhecimentos prévios, P (Ei) à luz denovos fatos P (Ei | F ).

A denição acima reete uma situação em que temos um con-junto discreto de hipóteses explanatórias (Ei), sobre as quais de-sejamos realizar nossa inferência. Quando nossas hipóteses sãorepresentadas, não por um conjunto enumerável de opções, maspelo valor de uma ou mais variáveis contínuas, Θ, e os fatos ou da-dos denotados por X, nossos conhecimentos prévios passam a serrepresentados por distribuições de probabilidade p(θ) e os dados,condicionados às hipóteses, f(x | θ), são representados pela funçãode verossimilhança L(θ;x).

Com a ajuda de alguma álgebra e do teorema da probabilidadetotal, em sua versão contínua, chegamos à forma contínua do teo-rema de Bayes:

π(θ | x) =p(θ)L(θ;x)∫

ΘL(θ;x)p(θ)dθ

Ao resolvermos a integral no denominador, este deixa de seruma função de θ e torna-se apenas uma constante de proporciona-lidade que garante que a integral de π(θ | x) seja igual a 1. Istonos permite re-escrever a equação acima como:

Page 239: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.3. SIMULAÇOES ESTOCÁSTICAS 205

π(θ | x) ∝ p(θ)L(θ;x)

Logo, a densidade posterior de θ é proporcional à sua densidadea priori multiplicada pela verossimilhança.

Conforme vimos acima, a inferência Bayesiana pode ser bas-tante intuitiva, conceitualmente. Na prática, porém, quando que-remos calcular a distribuição posterior dos parâmetros, nos depa-ramos com vários problemas numéricos de considerável diculdade.

Para encontrar a constante de proporcionalidade mencionadana seção anterior, precisamos integrar o produto da distribuiçãoa priori dos parâmetros pela verossimilhança, sobre o suporte deΘ. Se este suporte é innito e/ou multidimensional, temos umproblema de integração numérica complicadíssimo.

Uma vez obtida a constante de proporcionalidade, se o espaçode parâmetros é multidimensional, encontrar as distribuições mar-ginais para cada um deles, também é um problema de integraçãonumérica difícil.

9.3 Simulaçoes Estocásticas

Se não podemos determinar de forma exata, analítica ou numerica-mente, as distribuições posteriores geradas pelo teoremas de Bayes,só nos resta tentar simular amostras destas distribuições e estudá-las. Esta abordagem é denominada método de Monte Carlo, emhomenagem ao famoso cassino de Mônaco.

Integração Monte Carlo

Suponhamos que precisemos resolver a seguinte integral2:

2Para humanizar um pouco esta equação, imagine que f(y | x) representaa probabilidade condicional de y dado x, e que g(x) a função de densidade deprobabilidade de x.

Page 240: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

206 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

J(y) =∫

f(y | x)g(x)dx = E[f(y | x)] < +∞

Se g(x) é uma densidade da qual podemos amostrar, podemosaproximar nossa integral da seguinte forma:

J(y) =1n

n∑i=1

f(y | xi)

onde xi, . . . , xn ∼ g(x). Pela lei dos grandes números, estaestimativa se aproximará assintoticamente de J(y).

Vejamos um exemplo: gostaríamos de encontrar a integral dafunção y = x no intervalo [0, 1]. Pela fórmula da área do triân-gulo, (base × altura)/2 o resultado exato é 0.5. Na listagem 9.2,nosso g(x) passa a ser uma distribuição uniforme entre 0 e 1, vistoque este é o intervalo sobre qual desejamos integrar nossa função.Vemos que quanto maior o número de amostras de x, mais nossaestimativa se aproximará de 0.5

Listagem 9.2: Integração Monte Carlo

1 from numpy import ∗2 from numpy . random import ∗3 # desejamos área embaixo de uma re ta4 # dada pe la função y=x5 # ou s e j a : 0 . 56 x = uniform (0 ,1 ,5000)7 # Seja f ( y | x ) = x8 J = 1./5000∗sum(x )9 print J

Page 241: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.4. AMOSTRAGEM POR REJEIÇÃO 207

9.4 Amostragem por Rejeição

Suponhamos que se deseje obter amostras de uma função de den-sidade p(x), com suporte no intervalo [a, b], tal que p(x) ≤ m,∀x ∈ [a, b]. Então denimos:

X ∼ U [a, b)

eY ∼ U [0,m)

Geramos x e y a partir destas distribuições e aceitamos x comoum valor de p(x) se y < f(x), caso contrario, rejeitamos a amostrae tentamos novamente. Este procedimento signica que denimosuma função constante f(x) = m, que funciona como um envelopepara o nosso processo de amostragem.

Em suma, geramos um valor x a partir do suporte de X eaceitamos este valor com uma probabilidade f(x)/m, caso contráriorejeitamos e tentamos novamente.

A eciência deste método depende da proporção de pontosamostrados que são aceitos. A probabilidade de aceitação paraeste método é:

P (aceitar) = P ((X, Y ) ∈ A)

=∫ b

a

P ((X, Y ) ∈ A | X = x) × 1b− a

dx

=∫ b

a

f(x)m

× 1b− a

dx

=1

m(b− a)

∫ b

a

f(x) dx

=1

m(b− a)

Page 242: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

208 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

Se a probabilidade de aceitação for muito baixa, devemos bus-car um outro método mais eciente. Especialmente para distribui-ções com suporte innito, a escolha de uma função envelope maisadequada, pode ajudar a aumentar a eciência da amostragem.

Método do Envelope

Suponhamos que desejemos simular X com uma densidade de pro-babilidade (PDF) f(·) e que podemos obter amostras de Y (quepossui o mesmo suporte de X), cuja PDF é g(·). Suponhamosainda que exista uma constante a tal que:

f(x) ≤ ag(x), ∀x

ou seja, a é um limite superior para f(x)/g(x).Então, amostramos Y = y de g(·), e U = u ∼ U [0, ag(y)].

Aceitamos y como uma amostra de X se u < f(y)); caso contrá-rio, rejeitamos e tentamos novamente. Este método funciona poisdistribui pontos uniformemente sobre a região que envolve f(x), eaceita apenas os pontos que cumprem o requisito de pertencer àregião delimitada por f(x).

Qual a probabilidade de aceitação?

P (U < f(Y )) =∫ ∞

−∞P (U < f(Y ) | Y = y)g(y) dy

=∫ ∞

−∞

f(y)ag(y)

g(y) dy

=∫ ∞

−∞

f(y)a

dy

=1a

Page 243: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.4. AMOSTRAGEM POR REJEIÇÃO 209

Naturalmente, devemos escolher g(x) de forma que a seja omenor possível.

Vamos ver como podemos representar estas idéias em Python.

Listagem 9.3: Amostragem por rejeição utilizando o método doenvelope

1 # Dispon ive l no pacote de programas como :enve lope . py

2 from numpy import ∗3 from numpy . random import ∗4 from pylab import ∗5

6 def amostra (n) :7 """8 Esta funcao amostra de x e re to rna9 um vetor mais curto que n .

10 """11 x=uniform (0 ,1 , n )12 y=uniform (0 ,1 , n ) ∗1 .513 fx=6∗x∗(1−x ) # x tem d i s t r i b u i c a o beta14 #retorna so os va l o r e s que sa t i f a z em a

segu in t e condicao :15 s=compress (y<fx , x )16 return s17

18 def e f i c i e n c i a ( vector , n ) :19 """20 Testa a e f i c i e n c i a da amostragem .21 r e to rna a probab i l i dade de ac e i t a cao .22 """23 l = l en ( vec to r )24 prob = l / f l o a t (n)25 d i f f = n−l

Page 244: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

210 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

26 #n ne c e s s a r i o para obter as amostras quefa l tam

27 n2 = in t ( d i f f /prob )28 vec2 = amostra ( n2 )29 s = concatenate ( ( vector , vec2 ) )30 #gera histograma31 nb , bins , patches = h i s t ( s , b ins=50,

normed=0)32 x l ab e l ( ' Amostra ' )33 y l ab e l ( ' Probab i l idade ' )34 t i t l e ( ' Histograma de s : n=%s '% n)35 s a v e f i g ( ' enve lope . png ' , dpi=400)36 show ( )37 return s38

39 def testRS ( ) :40 """41 Esta funcao t e s t a o modulo42 """43 n=10000044 sample=amostra (n)45 e f i c i e n c i a ( sample , n )46

47 i f __name__ == '__main__ ' :48 testRS ( )

Aplicando ao Teorema de Bayes

Podemos aplicar o conceito de amostragem por rejeição a proble-mas de inferência Bayesiana. Frequentemente, em inferência Baye-siana, conhecemos bem a distribuição a priori, a ponto de poderamostrá-la e, também, possuimos dados com os quais podemosconstruir a função de verossimilhança.

Page 245: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.4. AMOSTRAGEM POR REJEIÇÃO 211

Figura 9.3: Resultado da amostragem por envelope de uma distri-buição beta(1,1)

De posse destes elementos podemos invocar a técnica de amos-tragem por rejeição para nos ajudar a amostrar da distribuiçãoposterior. Dado que:

π(θ) = p(θ)L(θ;x)

temos que, sendo LMax o valor máximo da nossa função deverossimilhança,

π(θ) ≤ p(θ)LMax

,π(θ)

LMaxp(θ)=

p(θ)L(θ;x)LMaxp(θ)

=L(θ;x)LMax

Page 246: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

212 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

.Assim sendo, podemos utilizar o método do envelope, amos-

trando da distribuição a priori e aceitando as amostras com pro-babilidade igual a L(θ;x)

LMax.

Listagem 9.4: Amostragem da Posterior Bayesiana por rejeição.

1 # Dispon ive l no pacote de programas como :p o s t r e j . py

2 from numpy import ∗3 from numpy . random import ∗4 from pylab import ∗5

6 def L i k e l i ( data , l im i t s , n l ) :7 n = len ( data ) # Numero de amostras8 data = array ( data )9 ( l l , u l ) = l im i t s #l im i t e s do espaco de

params .10 s tep = ( ul− l l ) / f l o a t ( n l )11 r e s = [ ] #l i s t a de r e su l t ado s12 sd = std ( data ) #DP dos dados13 for mu in arange ( l l , ul , s t ep ) :14 r e s . append ( exp (−0.5∗sum ( ( ( data−mu)/

sd ) ∗∗2) ) )15 l i k = array ( r e s ) /max( array ( r e s ) ) #

Veross imi lhanca16 return l i k17

18 def amostra (n , data , p l o t t ed=0) :19 x=uniform (0 ,1 , n ) #suporte20 l im i t s = 0 ,121 L=L i k e l i ( data , l im i t s , n )22 fx=6∗x∗(1−x ) # p r i o r i , beta (2 , 2 )23 s=compress (L [ : l en (x ) ]<fx , x ) #Reje i cao24 i f not p lo t t ed :

Page 247: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.4. AMOSTRAGEM POR REJEIÇÃO 213

25 p1 = s c a t t e r (x , fx )26 p2 = p lo t ( s o r t ( x ) ,L)27 l egend ( [ p1 , p2 ] , [ ' P r i o r i ' , '

Veross imi lhanca ' ] )28 return s29

30 def e f i c i e n c i a ( vector , n , data ) :31 l = l en ( vec to r )32 prob = l / f l o a t (n)33 d i f f = n−l34 n2 = in t ( d i f f /prob )35 vec2 = amostra (n2 , data , p l o t t ed=1)36 s = concatenate ( ( vector , vec2 ) )37 return s , prob38

39 def main ( ) :40 n=9000041 data = uniform (0 , 1 , 3 )42 sample=amostra (n , data )43 s , prob = e f i c i e n c i a ( sample , n , data )44 f i g u r e (2 ) #gera histograma45 h i s t ( s , b ins =50,normed=1)46 x l ab e l ( ' x ' )47 t ex t ( 0 . 8 , 1 . 2 , ' E f i c i e n c i a :%s '%round ( prob

, 2 ) )48 y l ab e l ( ' f r e quenc i a ' )49 t i t l e ( ' Po s t e r i o r : n=%s '% n)50 s a v e f i g ( ' r e j e i c a o . png ' , dpi=400)51 show ( )52 return s53

54 i f __name__ == '__main__ ' :55 main ( )

Page 248: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

214 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

Figura 9.4: Amostragem por rejeição da posterior Bayesiana.

Na linha 22 da listagem 9.4, vemos a rejeição de acordo com averossimilhança. Note que a verossimilhança é calculada a partir deum modelo normal enquanto que a distribuição a priori apresentauma distribuição beta(2,2).

A gura 9.4 mostra o resultado da amostragem da posterior,junto com a eciência do processo(canto superior direito).

9.5 Cadeias de Markov

Cadeias de Markov são um tipo particular de processo estocásticono qual o estado atual do sistema depende apenas do estado imedi-atamente anterior. Um exemplo muito conhecido de um processo

Page 249: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.5. CADEIAS DE MARKOV 215

de markov é o modelo auto-regressivo de primeira ordem:

Zt = αZt−1 + εt, εt ∼ N(0, σ2)

O processo apresentado acima, à medida em que o número deiterações cresce, converge para uma distribuição π(z). Esta distri-buição é denominada distribuição estacionária da cadeia. Entre-tanto, a cadeia necessita de um determinado número de iteraçõespara alcançar π(z). Se desejamos fazer inferências sobre π(z), pre-cisamos descartar os resultados iniciais da cadeia. Este períodonecessário para a convergência, é denominado de burn-in.

Listagem 9.5: Cadeia de Markov com kernel de transição exponen-cial

1 #−∗−coding : l a t i n −1−∗−2 # Dispon ive l no pacote de programas como :

markov . py3 #gerando uma cade ia de markov4 from numpy . random import ∗5 import random as rn6 from pylab import ∗7

8 n=100009 alpha=0.99

10 x=ze ro s (10000 , Float )11 for i in xrange (1 , n) :12 x [ i ]=alpha ∗x [ i −1] + exponent i a l ( 1 , 1 ) [ 0 ]13 # p l o t t i n g14 subplot (211)15 t i t l e ( ' Processo de Markov ' )16 p lo t ( x )17 x l ab e l (u ' I t e r a ç õ e s ' )18 y l ab e l ( ' x ' )19 subplot (212)

Page 250: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

216 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

20 h i s t (x , b ins=50)21 x l ab e l ( ' x ' )22 y l ab e l (u ' f r e quênc i a ' )23 s a v e f i g ( 'markov . png ' , dpi=400)24 show ( )

Executando o código apresentado na listagem 9.5 obtêm-se agura 9.5. Note o período até a convergência. Como exercício,refaça o histograma eliminando os valores do período burn-in, ecompare com o apresentado na gura 9.5.

Figura 9.5: Cadeia de Markov com kernel de transição exponencial.

Page 251: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.6. MCMC (MARKOV CHAIN MONTE CARLO) 217

9.6 MCMC (Markov Chain Monte Carlo)

Nós já discutimos algumas ferramentas básicas da simulação esto-cástica, como o método de Monte Carlo e as cadeias de Markov.Agora vamos ver como estes dois métodos podem ser combinadospara dar origem ao famoso método MCMC.

As técnicas aqui apresentadas, são de grande utilidade na esta-tística, particularmente na inferência Bayesiana.

O MCMC é uma classe de algoritmos que tem como objetivocontruir cadeias de Markov cuja distribuição estacionária seja idên-tica a de uma distribuição alvo. Após alcançarem esta distribuiçãoestacionária, as cadeias podem ser usadas para se obter amostrasda distribuição alvo.

As cadeias de Markov utilizadas na maioria dos algoritmosde MCMC, percorrem o espaço amostral utilizando-se de algumaforma de passeio aleatório. Portanto, podem levar muito tempopara cobrir o espaço desejado. Isto se deve ao fato de que a cadeiapode voltar atrás percorrendo partes do espaço já percorridas. Aseguir descreveremos e implementaremos dois dos mais utilizadosmétodos de MCMC: os amostradores de Metropolis-Hastings e deGibbs.

O Amostrador de Metropolis-Hastings

Este amostrador consiste em gerar amostras sequenciais de forma aaproximar uma distribuição da qual não temos meios de amostrardiretamente. Este algoritmo pode amostrar de qualquer distribui-ção de probabilidade p(x), desde que a densidade em x possa sercalculada.

Como qualquer cadeia de markov, o amostrador começa em umdado valor arbitrário para a variável x e prossegue em um passeioaleatório, onde cada deslocamento é amostrado de uma distribuiçãode Propostas. Cada proposta(x′) é avaliada de acordo com a se-guinte regra: u é amostrado de uma distribuição uniforme, U(0, 1).

Page 252: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

218 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

Se

u <p(x′)p(xt)

x′ se torna xt+1, caso contrário xt+1 = xt.

Listagem 9.6: Amostrador de Metropolis-Hastings

1 #−∗−encoding : l a t i n −1−∗−2 # Dispon ive l no pacote de programas como : MH

. py3 from numpy import ∗4 from s c ipy . s t a t s import ∗5

6 class Amostrador :7 def __init__( s e l f , alvo , proposta ) :8 """9 I n c i a l i z a o amostrador

10 a lvo : dados de f i n indo dens idade a lvo11 proposta : ob j e to gerador de

propostas .12 """13 s e l f . a lvo = kde . gaussian_kde ( a lvo )14 s e l f . prop = proposta15

16 def Run( s e l f , n , burnin=100) :17 ' ' '18 Roda o amostrador por n passos19 ' ' '20 amostra = ze ro s (n , f l o a t )21 a lvo = s e l f . a lvo22 i = 023 while i < n−1:24 x = amostra [ i ]25 inova = s e l f . prop . rvs ( ) [ 0 ]26 can = x + inova

Page 253: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.6. MCMC (MARKOV CHAIN MONTE CARLO) 219

27 aprob = min ( [ 1 , a lvo . eva luate ( can) / a lvo . eva luate ( x ) ] )

28 u = uniform . rvs ( ) [ 0 ]29 i f u < aprob :30 amostra [ i +1] = x = can31 i += 132 return amostra [ burnin : ]33

34 i f __name__=="__main__" :35 import pylab as P36 dados = concatenate ( ( norm . rvs ( s i z e =500) ,

norm . rvs (4 , 1 , s i z e =500) ) )37 a = Amostrador ( dados , norm (0 , 1 ) )38 r e s = a .Run(10000)39 P. p l o t ( arange (−5 ,10 , .01) , a . a lvo . eva luate

( arange (−5 ,10 , .01) ) , ' r ' , lw=2)40 P. h i s t ( res , normed=1, alpha =0.5)41 P. legend ( [ ' Alvo ' , ' Amostra ' ] )42 P. s a v e f i g ( 'MH. png ' , dpi=400)43 P. show ( )

Normalmente, utiliza-se um amostrador como este para amos-trar de distribuições das quais toda a informação que se tem pro-vém de uma amostra. Portanto, a Listagem 9.6, aceita um con-junto de dados como alvo. A partir desta amostra, uma funçãode densidade de probabilidade (PDF) é estimada por meio da fun-ção gaussian_kde do Scipy. Esta função será utilizada como alvopara o amostrador.

Note que a distribuição de propostas passada para o objetoAmostrador é uma das classes geradoras de números aleatóriosoferecidos por scipy.stats3. A Figura 9.6, mostra o resultado

3Estas classes podem ser chamadas diretamente com seus parâmetros comomostrado na linha 36 da listagem 9.6, retornando um objeto frozen com os

Page 254: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

220 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

do amostrador após a remoção de um número de amostras do iní-cio da cadeia determinado pelo parâmetro burnin. Esta remoçãoé importante, pois a cadeia leva algum tempo para convergir paraa área sob a curva alvo.

Figura 9.6: Amostrador de Metropolis-Hastings(n=10000).

O Amostrador de Gibbs

O amostrador de Gibbs foi desenvolvido para permitir a geração deamostras a partir de distribuições conjuntas de duas ou mais va-riáveis. O amostrador de Gibbs é um caso especial do amostradorde Metropolis-Hastings. Na listagem 9.7, vemos uma implementa-

mesmos métodos mas com os parâmetros xos

Page 255: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.6. MCMC (MARKOV CHAIN MONTE CARLO) 221

ção do amostrador de Gibbs, que envolve a denição de uma classeamostradora.

Listagem 9.7: Amostrador de Gibbs aplicado à uma distribuiçãotri-variada

1 # Dispon ive l no pacote de programas como :g ibbs . py

2 #−∗−encoding : l a t i n −1−∗−3 from numpy import zeros , sqrt , array4 from numpy . random import ∗5

6 class Amostra :7 def __init__( s e l f , n , v a r l i s t , loc , s ca l e ,

cormat , burnin=1000) :8 ' ' '9 n é o tamanho da amostra

10 v a r l i s t é a l i s t a de funçõesgeradoras do numpy

11 l o c e s c a l e sao l i s t a s para cadagerador em v a r l i s t

12 geradore s t e s t ado s :13 normal , beta , gamma, gumbel14 l o g i s t i c , lognormal , wald , l a p l a c e15 ' ' '16 s e l f . n = n17 s e l f . vars = v a r l i s t18 s e l f . l o c = l o c19 s e l f . s c a l e = s c a l e20 s e l f . ro = cormat21 s e l f . burnin = burnin22 def Run( s e l f ) :23 r e s u l t s = ze ro s ( ( l en ( s e l f . vars ) , s e l f

. n ) , f l o a t )24 dp = sq r t (1− s e l f . ro ∗∗2)

Page 256: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

222 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

25 ms = s e l f . l o c26 dps = s e l f . s c a l e27 ro = s e l f . ro28 for i in xrange (1 , s e l f . n ) :29 for n , j in enumerate ( s e l f . vars ) :30 r e s u l t s [ n , i ] = j (ms [ n]+ ro [ n ,

n−1]∗( r e s u l t s [ n−1, i−1]−ms [ n ] ) /dps [ n−1] , dps [ n ]∗dp [ n , n−1])

31 return r e s u l t s [ : , s e l f . burnin : ]32

33 i f __name__=="__main__" :34 import pylab as P35 n = 1000036 v a r l i s t = ( beta , gamma, normal )37 l o c = ( 2 . , 9 . , 5 , )38 s c a l e = ( 2 , . 5 , 1 . )39 cormat = ze ro s ( ( 3 , 3 ) , f l o a t )40 #cormat = array

( [ [ 1 , 0 . 6 , 0 . 7 ] , [ 0 . 6 , 1 , 0 . 8 ] , [ 0 . 7 , 0 . 8 , 1 ] ] )

41 s = Amostra (n , v a r l i s t , loc , s ca l e , cormat )42 r e s = s .Run( )43 s1=P. p l o t ( r e s [ 0 ] , r e s [ 2 ] , ' . ' )#marker='p ' ,

c='y ' ,mec='k ' , lw=0)44 s2=P. p l o t ( r e s [ 1 ] , r e s [ 2 ] , '+ ' )#marker='v ' ,

c='y ' ,mec='k ' , lw=0)45 P. legend ( [ ' Beta x Normal ' , 'Gamma x

Normal ' ] )46 P. s a v e f i g ( ' g ibbs . png ' , dpi=400)47 P. show ( )

O amostrador de Gibbs pode ser aplicado quando não se co-nhece a distribuição conjunta, mas a distribuição condicional de

Page 257: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.7. MÉTODOS MONTE CARLO SEQUENCIAIS 223

cada variável é conhecida. No amostrador de Gibbs convencional,cada nova amostra xi

t+1 é calculada de forma condicional ao valorde todas outras variáveis no tempo t. No exemplo mostrado na lis-tagem 9.7, uma variante deste método é implementado, na qual asvariáveis são calculadas a partir de uma estrutura de dependênciacircular(Figura 9.7).

Figura 9.7: Estrutura de dependência circular utilizada na listagem9.7.

9.7 Métodos Monte Carlo Sequenciais

Estes métodos, também chamados de ltros de partículas, visamdeterminar a distribuição de um processo markoviano pela análiseseqüencial de observações. Seja xk uma sequência de parâmetrosdesconhecidos (por exemplo o valor esperado de um sistema dinâ-mico) onde k = 0, 1, 2, 3, . . . e yk ∈ [y0, y1, . . . , yk] o conjunto deobservações sobre X (Figura 9.9).

Os métodos sequenciais procuram estimar xk a partir da distri-buição posterior

p(xk | y0, y1, . . . , yk)

ao passo que os métodos MCMC, modelam a posterior com-pleta:

p(x + 0, x1, . . . , xk | y0, y1, . . . , yk)

Page 258: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

224 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

Figura 9.8: Amostrador de Gibbs aplicado a uma distribuição tri-variada.

Sampling Importance Resampling SIR

O algoritmo de amostragem e re-amostragem por importância é umdos métodos Monte Carlo sequenciais mais utilizados. Ele procuraaproximar p(xk | y0, y1, . . . , yk) por meio de valores de x pondera-dos por uma função de importância,W que é uma aproximação dadistribuição posterior de X

A descrição de um passo do SIR, é a seguinte:

1. Retiramos P amostras (x) da distribuição a priori de transi-ção de X, p(xk | xk−1);

Page 259: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.7. MÉTODOS MONTE CARLO SEQUENCIAIS 225

Figura 9.9: Processo markoviano e suas observações.

2. Calculamos a p(yk | xk) (verossimilhança, no caso da distri-buição alvo ser a posterior Bayesiana);

3. Calculamos W = p(xk | xk−1)p(yk | xk);

4. Normalizamos W;

5. Re-amostramos P valores de x com probabilidades dadas porW;

A re-amostra (distribuição posterior de xk)passa a ser a a prioride transição para a o próximo passo.

Listagem 9.8: Filtro de partículas usando algoritmo SIR

1 #−∗−encoding : l a t i n −1−∗−2 # Dispon ive l no pacote de programas como :

s i r . py

Page 260: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

226 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

3 from numpy import ∗4 import l i k e5 import pylab as P6 from s c ipy . s t a t s import ∗7

8 class SMC:9 """

10 Monte Carlo Sequenc ia l usando SIR11 """12 def __init__( s e l f , p r io r type , pars , range

, r e s o l u t i o n =512) :13 ' ' '14 I n i c i a l i z a F i l t r o .15 pr i o r type deve s e r um RNG de sc ipy .

s t a t s16 pars são os parâmetros da p r i o r i .17 ' ' '18 s e l f . p r i o r i = pr i o r type19 s e l f . pars = pars20 s e l f . range = range21 s e l f . r e s = ( range [1]− range [ 0 ] ) ∗1 ./

r e s o l u t i o n22 s e l f . l i k e l i h o o d = None23 s e l f . p o s t e r i o r=array ( [ ] )24

25 def __call__( s e l f , datum) :26 sc = s e l f . pars [ 1 ]27 m = s e l f . range [ 0 ]28 M = s e l f . range [ 1 ]29 s tep = s e l f . r e s30 sup = arange (m,M, step )31 l i k = exp ( array ( [ l i k e . Normal (datum , i

, s c ) for i in sup ] ) )32 s e l f . l i k e l i h o o d = l i k /sum( l i k )

Page 261: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.7. MÉTODOS MONTE CARLO SEQUENCIAIS 227

33 post = s e l f . c a l cPo s t e r i o r (1000)34 return post35

36 def c a l cPo s t e r i o r ( s e l f , n ) :37 """38 Calcula a d i s t r i b u i ç ã o p o s t e r i o r39 """40 i f s e l f . p o s t e r i o r . any ( ) :41 s = s e l f . p r i o r i . rvs ( s i z e=n , l o c=

s e l f . pars [ 0 ] , s c a l e=s e l f .pars [ 1 ] )

42 #pdens= kde . gaussian_kde ( s e l f .p o s t e r i o r )

43 #s= pdens . resample (n)44 else :45 s = s e l f . p r i o r i . rvs ( s i z e=n ,

l o c=s e l f . pars [ 0 ] , s c a l e=s e l f . pars [ 1 ] )

46 m = array ( [ s e l f . range [ 0 ] ] )47 M = array ( [ s e l f . range [ 1 ] ] )48 s tep = s e l f . r e s49 supp = arange (m,M, step )50 s = compress ( l e s s ( s . r a v e l ( ) ,M) &

gr ea t e r ( s . r av e l ( ) ,m) , s )51 d = uniform . rvs ( l o c =0, s c a l e =1, s i z e=s

. s i z e )52 i f s e l f . p o s t e r i o r . any ( ) :53 w= s e l f . p r i o r i . pdf ( supp ) ∗ s e l f .

l i k e l i h o o d54 else :55 w = s e l f . p r i o r i . pdf ( supp , l o c=

s e l f . pars [ 0 ] , s c a l e=s e l f . pars[ 1 ] ) ∗ s e l f . l i k e l i h o o d

56 w = w/sum(w)

Page 262: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

228 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

57 sx = sea r ch so r t ed ( supp , s )58 w = w[ sx−1]59 w = w. r av e l ( )60 post = compress (d<w, s )61 post = post . r av e l ( )62 s e l f . p o s t e r i o r = post63 return post64

65 i f __name__=="__main__" :66 pf = SMC(norm , ( 3 , 3 ) , range=(−10 ,15) )67 data = 2∗ s i n ( arange ( 0 , 7 , . 2 ) )+2#ones (10)68 sup = arange (−10 ,15 ,25/512.)69 p r i o r i = norm . pdf ( sup , l o c =3, s c a l e =1)70 P. ion ( )71 l i n , = P. p l o t ( sup , p r i o r i )72 pt , = P. p l o t ( [ data [ 0 ] ] , [ 0 . 0 5 ] , ' o ' )73 P. g r id ( )74 for i in data :75 e s t = pf ( [ i ] )76 l i n . set_ydata ( kde . gaussian_kde ( e s t ) .

eva luate ( sup ) )77 pt . set_xdata ( [ i ] )78 P. draw ( )79 print i , compress ( pf . l i k e l i h o o d==max(

pf . l i k e l i h o o d ) , sup ) ,median ( e s t )

Na Listagem 9.8, vemos uma implementação de um ltro departículas utilizando o algoritmo SIR. O ltro é denido como umaclasse. Nesta classe denimos o método __call__, característicode funções. Desta forma, uma vez criado o objeto (instância daclasse SMC), ele poderá ser chamado diretamente pelo nome. Se oobjeto não possuísse tal método, teríamos que nos utilizar de umde seus métodos para acionar sua maquinaria.

Parametrizamos o objeto SMC com uma distribuição a priori

Page 263: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.8. FUNÇÕES DE VEROSSIMILHANÇA 229

dada pela classe norm do módulo scipy.stats com média µ = 3 edesvio padrão σ = 3. Também precisamos especicar os limites debusca do algoritmo, o que é feito através do argumento range pas-sado durante a inicialização. Neste exemplo as funções de cálculodas verossimilhanças foram implementadas de um módulo sepa-rado chamado like.py. Este módulo está no pacote de programasdisponível no website deste livro.

A convergência dos métodos sequenciais, depende fortementeda qualidade do algoritmo de amostragem da priori, uma vez queestas amostras formam a matéria-prima do algoritmo SIR.

9.8 Funções de Verossimilhança

Ser capaz de calcular funções de verossimilhança é essencial quandose deseja utilizar a inferência Bayesiana. A verossimilhança é otermo da fórmula de Bayes que representa a evidência contida emum conjunto de dados, e que é utilizada para atualizar nosso co-nhecimento a priori do problema, de forma a gerar uma nova des-crição para suas variávieis, denominada de distribuição posteriorconjunta.

Denição da função de verossimilhança

Variável Discreta

Seja Θ um espaço de parâmetros. Seja pθ; θ ∈ Θ uma famíla pa-rametrizada de modelos probabilísticos para um vetor de variáveisdiscretas X = (X1, . . . , Xn). A função de verossimilhança para(x1, . . . , xn) é dada por:

L(θ | x1, . . . , xn) , pθ(x1, . . . , xn)

e é uma função de θ.A função de verossimilhança nos dá a probabilidade de que

(X1, . . . , Xn) = (x1, . . . , xn), ou seja um determinado conjunto de

Page 264: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

230 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

dados será amostrado em uma realização do processo gerador, paracada valor possível de θ. Matematicamente, a função de verossimi-lhança é apenas uma notação diferente para a função de probabili-dade. Contudo, conceitualmente existe uma distinção importante:Quando se estuda a função de probabilidade, xa-se o parâmetro eobtêm-se a variação da probabilidade em função do valor da variá-vel, x. Quando estudamos a verossimilhança, consideramos o valorde x xo e variamos o parâmetro, obtendo a verossimilhança decada valor. Para uma única observação de uma variável discreta,a verossimilhança é igual à probabilidade de se observar aquelevalor. Por exemplo: Seja Pp uma distribuição Bernoulli com parâ-metro p, 0 < p < 1. Uma variável aleatória com uma distribuiçãoBernoulli, só pode assumir dois valores, 0 e 1.

Para x = 0,L(p | 0) = 1− p

Para x = 1,L(p | 1) = p

Um pouco de álgebra, nos permite combinar ambas as fórmulasacima escrevendo:

L(p | x) = px(1− p)1−x, x ∈ 0, 1Podemos visualizar a forma da verossimilhança com quatro li-

nhas de código:

Listagem 9.9: Função de verossimilhança para x igual a 0.1 >>> from pylab import ∗2 >>> L=[1−p for p in arange ( 0 , 1 , . 0 1 ) ]3 >>> plo t ( arange ( 0 , 1 , . 0 1 ) ,L)4 >>> show ( )

Para múltiplas observações independentes, a função de verossi-milhança caria assim:

L(p | x1, . . . , xn) = [px1(1− p)1−x1 ][px2(1− p)1−x2 ] . . . [pxn(1− p)1−xn ]= p

Pni xi(1− p)n−

Pni xi (9.1)

Page 265: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.8. FUNÇÕES DE VEROSSIMILHANÇA 231

Isto dito, vamos a um exemplo cientíco mais concreto: umpesquisador deseja comparar duas sequências de DNA, buscandoquanticar a homologia entre elas, ou seja, em quantas posiçõespossuem nucleotídeos idênticos. Sejam as duas sequências:

ATTAGCCCTTGGGAACATCCC

ATGAGCTCTTGGTTAAGACCC

Assumindo independência entre os loci, podemos representaresta comparação como uma variável Bernoulli (Xi)que assume valor1 para loci com letras iguais e 0 para loci com letras distintas.Vamos resolver este problema aplicando a equação 9.1.

Listagem 9.10: Calculando a verossimilhança da comparação deduas sequências de DNA

1 #−∗−coding : l a t i n −1−∗−2 # Dispon ive l no pacote de programas como :

l i k 1 . py3 from pylab import ∗4 a ="ATTAGCCCTTGGGAACATCCC"5 b ="ATGAGCTCTTGGTTAAGACCC"6 n = len ( a )7 # Comparando as s equênc i a s :8 comp = [ i n t ( a [ i ]==b [ i ] ) for i in range ( l en ( a

) ) ]9 # Contando número de co r r e spondênc ia s

10 soma = sum( array (comp) )11 # Calculando L12 L = [ p∗∗soma∗(1−p) ∗∗(n−soma) for p in arange

( 0 , 1 , . 0 1 ) ]13 p lo t ( arange ( 0 , 1 , . 0 1 ) , L)14 s a v e f i g ( ' l i k 1 . png ' , dpi=400)15 show ( )

Page 266: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

232 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

A gura 9.10 mostra a função de verossimilhança gerada pelalistagem 9.10. Mais adiante usaremos este resultado em outroexemplo.

Analisando o código da listagem 9.10, utilizamos a técnica delist comprehension para comparar as duas sequências locus a locusretornando 1 quando fossem iguais e 0, caso contrário. Como acomparação retorna verdadeiro (True) ou falso (False), aplicamosa função int para transformar estas saídas em 1 e 0, respectiva-mente. Na linha 9, convertemos a lista de resultados da comparaçãoem vetor para poder somar os seus elementos com sum. Na linha11, usamos técnica similar à da linha 7 para calcular a função deverossimilhança.

Figura 9.10: Função de verossimilhança para a comparação desequências de DNA.

Page 267: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.8. FUNÇÕES DE VEROSSIMILHANÇA 233

Variável Contínua

A função de verossimilhança para variáveis aleatórias contínuas ésimilar ao caso discreto apresentado acima. Para uma variável con-tínua, substituímos a função de probabilidade da denição discretapela função de densidade de probabilidade. Se gθ(x1, . . . , xn), θ ∈Θ, representa uma família de funções de densidade de probabili-dade conjuntas para (X1, . . . , Xn), então

L(θ | x1, . . . , xn) =n∏

i=1

fθ(xi)

se X1, . . . , Xn forem independentes e identicamente distribuí-das.

A título de exemplo, vamos escrever a função de verossimilhançapara uma variável aleatória normal X com média µ e variância 1.Neste caso, µ é o nosso parâmetro θ. Dado que a densidade de Xi

é (2π)−1/2e−(x−µ)2/2, para n=3 temos

L(µ | x1, x2, x3) = (2π)3/2e1/2P3

1(xi−µ)2 . (9.2)

Como podemos ver pelas equações 9.2 e 9.1, a verossimilhança éuma família de funções que difere por um fator que não dependede θ. Portanto, apenas seu valor relativo (forma) nos interessa.

Log-verossimilhança

Na função de verossimilhança, o termo que não depende de θ, de-pende de n (o tamanho amostral), com isso o valor da verossimi-lhança facilmente torna-se extremo4. Devido a esta característicada função de verossimilhança, frequentemente utiliza-se o seu loga-ritmo. Vamos plotar a log-verossimilhança calculada na listagem5

9.10.4Se isto não é óbvio para você, utilize seus conhecimentos de Python para

investigar numericamente este fato.5Modique a listagem anterior incluindo estas linhas

Page 268: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

234 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

Listagem 9.11: Log-verossimilhança

1 L[0 ]=L [ 1 ] #removendo o zero do i n í c i o dal i s t a

2 p lo t ( arange ( 0 , 1 , . 0 1 ) , l og ( array (L) ) )3 show ( )

Compare agora os dois grácos(?? e 9.11). Preste atenção aos va-lores do eixo y. A função mudou de forma, porém preservou umacoisa muito importante: o seu máximo continua com a mesma abs-cissa. Isto nos leva a uma aplicação muito importante da funçãoverossimilhança: a estimação de parâmetros por máxima verossi-milhança.

Figura 9.11: Log-verossimilhança da função descrita anteriormente.

Page 269: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.9. INFERÊNCIA BAYESIANA COM OBJETOS. 235

Vimos na listagem 9.10 que, quando calculamos a função deverossimilhança sobre dados obtidos experimentalmente, ela repre-senta a probabilidade de cada valor de parâmetro no eixo x tergerado aquele conjunto de dados. Logo, se desejamos estimar esteparâmetro a partir dos dados, devemos escolher o valor que maxi-miza a função de verossimilhança. Felizmente, este valor é o mesmopara a log-verossimilhança.

Voltando ao problema da comparação de duas sequências deDNA, vamos maximizar a função de verossimilhança para estimarp (ver listagem 9.12).

Listagem 9.12: Maximizando a verossimilhança

1 MLE = compress ( equal (L ,max(L) ) , arange( 0 , 1 , . 0 1 ) )

2 print MLE3 [ 0 . 6 7 ]

Na linha 1 da listagem 9.12, utiliza-se uma função provenientedo módulo numpy6. Esta função (compress) nos retorna os elemen-tos do segundo argumento arange(0,1,.01), nas posições em queo vetor de condições, equal(L,max(L)), for verdadeiro. Trocandoem miúdos: nos retorna o valor do parâmetro p para o qual o valorda verossimilhança é máximo. As funções max e equal também sãoprovenientes do módulo numpy.

9.9 Inferência Bayesiana com Objetos.

Na visão Bayesiana de mundo, nosso conhecimento sobre o mundoé representado por nossas crenças que, por sua vez, são representa-das por variáveis aleatórias com suas distribuições de probabilidade(PDFs). Como nosso conhecimento do mundo não é perfeito, es-tas distribuições não têm precisão innita, ou seja, não podem ser

6Importado, neste exemplo, pelo módulo pylab.

Page 270: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

236 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

representadas por um simples número. Por exemplo, minha alturanão é 1, 73m mas uma distribuição de valores em torno deste, vistoque depende de vários fatores tais como postura, quantidade decabelo, etc.

Naturalmente, nossas crenças podem ser modicadas. A cadavez que nós nos expomos a novas evidências(dados) a respeito deum fato, podemos reforçar nossa crença original (aumentando suaprecisão). Ou podemos car mais confusos, se os dados não con-cordam com nossa crença original, e esta última perderá precisão.

O objetivo desta seção, é construir um objeto que emule as ca-racterísticas de variável aleatória Bayesiana, facilitando-nos a rea-lização das operações mencionadas acima.

Em computação se desejarmos representar uma distribuiçãop(x), teremos que fazê-lo por meio de uma função (se esta fun-ção for conhecida e computável) que recebe x como argumento ena sua probabilidade, ou por alguma outra estrutura de dados quecombine todos valores de x e suas respectivas probabilidades, comopor exemplo um dicionário. Naturalmente esta última representa-ção se presta apenas a uma gama bastante limitada de variáveis.

1 >>> # Di s t r i bu i ç ã o de p robab i l i dade s de umdado cúbico

2 >>> dado = 1 : 1 / 6 . , 2 : 1 / 6 . , 3 : 1 / 6 . , 4 : 1 / 6 . , 5 : 1 / 6 . , 6 : 1 / 6 .

Listagem 9.13: Classe Variável Aleatória Bayesiana Requisitos.

3 # copyr ight 2007 Flav io Codeco Coelho4 # Licensed under GPL v35 from numpy import ∗6 import l i k e , sys

Como toda variável Bayesiana, nossa classe deve possuir umadistribuição a priori, neste exemplo denida de forma paramétrica.

Page 271: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.9. INFERÊNCIA BAYESIANA COM OBJETOS. 237

Deve também conter dados referentes a ela, e uma distribuiçãoposterior. Naturalmente deve possuir os métodos para atualizar asua distribuição a priori, transformando-a em posterior.

Listagem 9.14: Classe Variável Aleatória Bayesiana Inicialização.

8 from s c ipy . s t a t s import ∗9

10 class BayesVar :11 """12 Bayesian random va r i a t e .13 """14 def __init__( s e l f , p r io r type , pars , range

, r e s o l u t i o n =512) :15 ' ' '16 I n i c i a l i z a v a r i á v e l a l e a t ó r i a .17 Adquire métodos da c l a s s e p r i o r type

.18 pr i o r type deve s e r um RNG de sc ipy .

s t a t s19 pars são os parâmetros da p r i o r i .20 ' ' '21 s e l f . p r i o rn = pr i o r type . name22 s e l f . _ f l avo r i z e ( p r i o r type (∗ pars ) ,

p r i o r type )23 s e l f . pars = pars24 s e l f . range = range25 s e l f . r e s = ( range [1]− range [ 0 ] ) ∗1 ./

r e s o l u t i o n26 s e l f . l i k e f u n = s e l f . _Likel ihood ( s e l f

. p r i o rn )27 s e l f . l i k e l i h o o d = None

Esta classe deve solicitar estas informações na sua inicializa-ção(Listagem 9.14). O pacote scipy.stats já possui classes cor-

Page 272: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

238 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

respondendo a várias famílias paramétricas. Portanto nossa classerequer que o argumento priortype seja uma destas classes. Re-quer também os parâmetros da a priori, a extensão do suporte paraa variável,e a resolução da representação das distribuições(númerode pontos em se subdividirá o suporte).

Durante a inicialização da classe, importamos os métodos dadistribuição a priori para se juntar aos métodos de nossa classe.Esta absorção de funcionalidade não poderia ser conseguida atravésde herança comum, pois não se sabe de antemão de qual classedesejamos herdá-los. Felizmente, a natureza dinâmica do Pythonnos ajudou neste ponto, permitindo uma herança dinâmica. Estaherança é feita no método _flavorize (Listagem 9.15).

Listagem 9.15: Classe Variável Aleatória Bayesiana Herança di-nâmica de métodos.

29 s e l f . p o s t e r i o r=array ( [ ] )30

31 def _f l avo r i z e ( s e l f , pt , ptbase ) :32 ' ' '33 add methods from d i s t r i b u t i o n type34 ' ' '35 s e l f . cd f = pt . cd f36 s e l f . i s f = pt . i s f37 i f i s i n s t a n c e ( ptbase , rv_continuous ) :38 s e l f . pdf = pt . pdf39 e l i f i s i n s t a n c e ( ptbase , rv_d i s c r e t e ) :40 s e l f . pdf = pt . pmf41 else : sys . e x i t ( ' I nva l i d d i s t r i b u t i o n

ob j e c t ' )

De acordo com o tipo de distribuição a priori, o método Like-lihood escolhe e retorna a função de verossimilhança adequada(Listagem9.16).

Page 273: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.9. INFERÊNCIA BAYESIANA COM OBJETOS. 239

Listagem 9.16: Classe Variável Aleatória Bayesiana Herança di-nâmica de métodos.

100 return [ ]101

102 def _Likel ihood ( s e l f , typ ) :103 ' ' '104 Def ine f am i l i a paramétr ica da

ve ro s s im i lhança .105 Retorna função de ve ro s s im i lhança .106 typ deve s e r uma s t r i n g .107 ' ' '108 i f typ == 'norm ' :109 return lambda( x ) : l i k e . Normal ( x

[ 0 ] , x [ 1 ] , 1 . / x [ 2 ] )110 e l i f typ == ' expon ' :111 return lambda( x ) : ( 1 . / x [ 2 ] ) ∗∗x

[ 0 ] . s i z e ∗exp (−(1./x [ 2 ] ) ∗sum(x [ 0 ] ) )

Durante a inicialização da variável, uma lista vazia de dadosé criada. Esta lista conterá todos os conjuntos de dados indepen-dentes que forem atribuídos à variável. Isto é importante pois ateoria Bayesiana opera por atualizações sucessivas da distribuiçãoposterior a cada novo conjunto de evidências. Uma vez gerada, adistribuição posterior ca guardada no atributo posterior.

Nossa classe possui ainda um método chamado addData, cujafunção é a de armazenar os dados, e recalcular a função de veros-similhança chamando o método _update(Listagem 9.17).

Listagem 9.17: Classe Variável Aleatória Bayesiana Adição dedados e cálculo da Verossimilhança.

42 s e l f . ppf = pt . ppf43 s e l f . rvs = pt . rvs44 def _update ( s e l f ) :

Page 274: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

240 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

45 """46 Calcu la te l i k e l i h o o d func t i on47 """48 i f s e l f . data :49 d = s e l f . data [−1]50 sc = s e l f . pars [ 1 ]51 m = s e l f . range [ 0 ]52 M = s e l f . range [ 1 ]53 s tep = s e l f . r e s54 #s e l f . l i k e f u n r e tu rn s log−

l i k e l i h o o d55 l i k = exp ( array ( [ s e l f . l i k e f u n ( ( d

, i , s c ) ) for i in arange (m,M,step ) ] ) )

56 s e l f . l i k e l i h o o d = l i k /sum( l i k )57

58 def addData ( s e l f , data = [ ] ) :59 """60 Adds datase t to va r i ab l e ' s data

s t o r e61 """

Os métodos getPriorSample e getPriorDist retornam amos-tras e a PDF da distribuição a priori, respectivamente(Listagem9.18).

Listagem 9.18: Classe Variável Aleatória Bayesiana Amostras ePDF da a priori.

63 s e l f . _update ( )64

65 def getPriorSample ( s e l f , n ) :66 ' ' '67 Returns a sample from the p r i o r

d i s t r i b u t i o n

Page 275: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.9. INFERÊNCIA BAYESIANA COM OBJETOS. 241

68 ' ' '69 return s e l f . rvs ( s i z e=n)70

71 def ge tPr i o rD i s t ( s e l f ) :72 """73 Returns the p r i o r PDF.

Por m temos o método mais complexo: getPosteriorSample(Listagem 9.19). Este método é responsável por atualizar a distri-buição posterior da variável sempre que se solicitar uma amostra.Utiliza um método de amostragem por importância no qual se rea-mostra a distribuição a priori com um probabilidade proporcionalao produto da verossimilhança e da distribuição a priori. Vale no-tar, que se existir alguma posterior já calculada, esta é utilizadacomo a priori. Como deve ser.

Listagem 9.19: Classe Variável Aleatória Bayesiana Gerando aposterior.

74 """75 re turn s e l f . pdf ( arange ( s e l f . range

[ 0 ] , s e l f . range [ 1 ] , s e l f . r e s ) )76 de f getPoster iorSample ( s e l f , n ) :77 """78 Return a sample o f the p o s t e r i o r

d i s t r i b u t i o n .79 """80 i f s e l f . p o s t e r i o r . any ( ) :# Use l a s t

p o s t e r i o r as p r i o r81 k= kde . gausian_kde ( s e l f .

p o s t e r i o r )82 s= k . resample (n)83 e l s e :84 s = s e l f . getPriorSample (n)85 i f s e l f . data :

Page 276: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

242 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

86 m = s e l f . range [ 0 ]87 M = s e l f . range [ 1 ]88 s tep = s e l f . r e s89 supp = arange (m,M, step )#support90 s = compress ( l e s s ( s . r a v e l ( ) ,M) &

gr ea t e r ( s . r av e l ( ) ,m) , s )#removing out−of−rangesamples

91 d = uniform . rvs ( l o c =0, s c a l e =1,s i z e=len ( s ) )#Uniform 0−1samples

92 w = s e l f . pdf ( supp ) ∗ s e l f .l i k e l i h o o d

93 w = w/sum(w) #normal i z ingweights

94 sx = sea r ch so r t ed ( supp , s )95 w = w[ sx−1]#search so r t ed

r e tu rn s 1−based b i n l i s t96 post = compress (d<w, s )97 s e l f . p o s t e r i o r = post98 re turn post

O código completo deste programa(Listagem 9.21) inclui, ainda,algumas linhas para testar a classe (Listagem 9.20). Este testeconsiste em inicializar a variável com uma distribuição a prioriNormal com média µ = 3 e desvio padrão σ = 1. Um pequenoconjunto de observações, escolhido de forma a não concordar coma distribuição a priori, é utilizado para demonstrar a atualizaçãoda variável(Figura 9.12).

Listagem 9.20: Classe Variável Aleatória Bayesiana Código deteste.

113 return lambda( x ) : l i k e . Beta (x[ 0 ] , x [ 1 ] , x [ 2 ] )

Page 277: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.9. INFERÊNCIA BAYESIANA COM OBJETOS. 243

114

115 i f __name__=="__main__" :116 bv = BayesVar (norm , ( 3 , 1 ) , range =(0 ,5) )117 data = ones (20)118 bv . addData ( data )119 p = bv . getPoster io rSample (200000)120 P. p l o t ( arange (bv . range [ 0 ] , bv . range [ 1 ] ,

bv . r e s ) , bv . l i k e l i h o od , ' ro ' , lw=2)121 P. p l o t ( arange (bv . range [ 0 ] , bv . range [ 1 ] ,

bv . r e s ) , bv . g e tPr i o rD i s t ( ) , ' g+' , lw=2)122 P. h i s t (p , normed=1)123 P. legend ( [ ' L ike l i hood ' , ' Pr io r ' ] )

Figura 9.12: Resultado da listagem 9.21.

Page 278: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

244 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

Listagem 9.21: Classe Variável Aleatória Bayesiana Listagemcompleta

1 #−∗−encoding : l a t i n −1−∗−2 # Dispon ive l no pacote de programas como :

Bayes . py3 # copyr ight 2007 Flav io Codeco Coelho4 # Licensed under GPL v35 from numpy import ∗6 import l i k e , sys7 import pylab as P8 from s c ipy . s t a t s import ∗9

10 class BayesVar :11 """12 Bayesian random va r i a t e .13 """14 def __init__( s e l f , p r io r type , pars , range

, r e s o l u t i o n =512) :15 ' ' '16 I n i c i a l i z a v a r i á v e l a l e a t ó r i a .17 Adquire métodos da c l a s s e p r i o r type

.18 pr i o r type deve s e r um RNG de sc ipy .

s t a t s19 pars são os parâmetros da p r i o r i .20 ' ' '21 s e l f . p r i o rn = pr i o r type . name22 s e l f . _ f l avo r i z e ( p r i o r type (∗ pars ) ,

p r i o r type )23 s e l f . pars = pars24 s e l f . range = range25 s e l f . r e s = ( range [1]− range [ 0 ] ) ∗1 ./

r e s o l u t i o n

Page 279: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.9. INFERÊNCIA BAYESIANA COM OBJETOS. 245

26 s e l f . l i k e f u n = s e l f . _Likel ihood ( s e l f. p r i o rn )

27 s e l f . l i k e l i h o o d = None28 s e l f . data = [ ]29 s e l f . p o s t e r i o r=array ( [ ] )30

31 def _f l avo r i z e ( s e l f , pt , ptbase ) :32 ' ' '33 add methods from d i s t r i b u t i o n type34 ' ' '35 s e l f . cd f = pt . cd f36 s e l f . i s f = pt . i s f37 i f i s i n s t a n c e ( ptbase , rv_continuous ) :38 s e l f . pdf = pt . pdf39 e l i f i s i n s t a n c e ( ptbase , rv_d i s c r e t e ) :40 s e l f . pdf = pt . pmf41 else : sys . e x i t ( ' I nva l i d d i s t r i b u t i o n

ob j e c t ' )42 s e l f . ppf = pt . ppf43 s e l f . rvs = pt . rvs44 def _update ( s e l f ) :45 """46 Calcu la te l i k e l i h o o d func t i on47 """48 i f s e l f . data :49 d = s e l f . data [−1]50 sc = s e l f . pars [ 1 ]51 m = s e l f . range [ 0 ]52 M = s e l f . range [ 1 ]53 s tep = s e l f . r e s54 #s e l f . l i k e f u n r e tu rn s log−

l i k e l i h o o d55 l i k = exp ( array ( [ s e l f . l i k e f u n ( ( d

, i , s c ) ) for i in arange (m,M,

Page 280: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

246 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

s tep ) ] ) )56 s e l f . l i k e l i h o o d = l i k /sum( l i k )57

58 def addData ( s e l f , data = [ ] ) :59 """60 Adds datase t to va r i ab l e ' s data

s t o r e61 """62 s e l f . data . append ( array ( data ) )63 s e l f . _update ( )64

65 def getPriorSample ( s e l f , n ) :66 ' ' '67 Returns a sample from the p r i o r

d i s t r i b u t i o n68 ' ' '69 return s e l f . rvs ( s i z e=n)70

71 def ge tPr i o rD i s t ( s e l f ) :72 """73 Returns the p r i o r PDF.74 """75 return s e l f . pdf ( arange ( s e l f . range

[ 0 ] , s e l f . range [ 1 ] , s e l f . r e s ) )76 def getPoster io rSample ( s e l f , n ) :77 """78 Return a sample o f the p o s t e r i o r

d i s t r i b u t i o n .79 """80 i f s e l f . p o s t e r i o r . any ( ) :# Use l a s t

p o s t e r i o r as p r i o r81 k= kde . gausian_kde ( s e l f .

p o s t e r i o r )82 s= k . resample (n)

Page 281: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.9. INFERÊNCIA BAYESIANA COM OBJETOS. 247

83 else :84 s = s e l f . getPriorSample (n)85 i f s e l f . data :86 m = s e l f . range [ 0 ]87 M = s e l f . range [ 1 ]88 s tep = s e l f . r e s89 supp = arange (m,M, step )#support90 s = compress ( l e s s ( s . r a v e l ( ) ,M) &

gr ea t e r ( s . r av e l ( ) ,m) , s )#removing out−of−rangesamples

91 d = uniform . rvs ( l o c =0, s c a l e =1,s i z e=len ( s ) )#Uniform 0−1samples

92 w = s e l f . pdf ( supp ) ∗ s e l f .l i k e l i h o o d

93 w = w/sum(w) #normal i z ingweights

94 sx = sea r ch so r t ed ( supp , s )95 w = w[ sx−1]#search so r t ed

r e tu rn s 1−based b i n l i s t96 post = compress (d<w, s )97 s e l f . p o s t e r i o r = post98 return post99 else :

100 return [ ]101

102 def _Likel ihood ( s e l f , typ ) :103 ' ' '104 Def ine f am i l i a paramétr ica da

ve ro s s im i lhança .105 Retorna função de ve ro s s im i lhança .106 typ deve s e r uma s t r i n g .107 ' ' '

Page 282: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

248 CAPÍTULO 9. SIMULAÇÕES ESTOCÁSTICAS

108 i f typ == 'norm ' :109 return lambda( x ) : l i k e . Normal ( x

[ 0 ] , x [ 1 ] , 1 . / x [ 2 ] )110 e l i f typ == ' expon ' :111 return lambda( x ) : ( 1 . / x [ 2 ] ) ∗∗x

[ 0 ] . s i z e ∗exp (−(1./x [ 2 ] ) ∗sum(x [ 0 ] ) )

112 e l i f typ == ' beta ' :113 return lambda( x ) : l i k e . Beta (x

[ 0 ] , x [ 1 ] , x [ 2 ] )114

115 i f __name__=="__main__" :116 bv = BayesVar (norm , ( 3 , 1 ) , range =(0 ,5) )117 data = ones (20)118 bv . addData ( data )119 p = bv . getPoster io rSample (200000)120 P. p l o t ( arange (bv . range [ 0 ] , bv . range [ 1 ] ,

bv . r e s ) , bv . l i k e l i h o od , ' ro ' , lw=2)121 P. p l o t ( arange (bv . range [ 0 ] , bv . range [ 1 ] ,

bv . r e s ) , bv . g e tPr i o rD i s t ( ) , ' g+' , lw=2)122 P. h i s t (p , normed=1)123 P. legend ( [ ' L ike l i hood ' , ' Pr io r ' ] )124 P. t i t l e ( ' Bayesian i n f e r e n c e ' )125 P. s a v e f i g ( ' bayesvar . png ' , dpi=400)126 P. show ( )

9.10 Exercícios

1. Compare a acurácia do amostrador de Metropolis-Hastingscom o amostrador oferecido pelo método resample do objetoretornado por gaussian kde. Teste com diferentes formas dedistribuição. O método resample é uma mera amostragemcom reposição.

Page 283: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

9.10. EXERCÍCIOS 249

2. Verique a importância do tamanho amostral na atualizaçãoda distribuição posterior de uma variável, utilizando o pro-grama da listagem 9.21

3. Experimente diferentes valores para a variância da distribui-ção a priori do exemplo 9.8, e verique o efeito na conver-gência do algoritmo.

4. Utilize o método do hipercubo latino ilustrado na listagem 9.1para gerar amostras das distribuições a priori nos exemplos9.8 e 9.21 e avalie o seu impacto na qualidade das estimativas.

Page 284: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas
Page 285: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Apêndices

251

Page 286: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas
Page 287: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Introdução ao ConsoleGnu/Linux

Guia de sobrevivência no console do Gnu/Linux

Oconsole Gnu/Linux é um poderoso ambiente de trabalho, emcontraste com a interface limitada, oferecida pelo sistema ope-

racional DOS, ao qual é comumente comparado. O console Gnu/-Linux tem uma longa história desde sua origem no Bourne shell,distribuido com o Sistema operacional(SO) UNIX versão 7. Emsua evolução, deu origem a algumas variantes. A variante maisamplamente utilizada e que será objeto de utilização e análise nestecapítulo é o Bash ou Bourne Again Shell. Ao longo deste capí-tulo o termo console e shell serão utilizados com o mesmo sentido,ainda que, tecnicamente não sejam sinônimos. Isto se deve à faltade uma tradução mais adequada para a palavra inglesa shell".

Qual a relevância de um tutorial sobre shell em um livro sobrecomputação cientíca? Qualquer cientista com alguma experiên-cia em computação está plenamente consciente do fato de que amaior parte do seu trabalho, se dá através da combinação da fun-cionalidade de diversos aplicativos cientícos para a realização detarefas cientícas de maior complexidade. Neste caso, o ambientede trabalho é chave para agilizar esta articulação entre aplicati-vos. Este capítulo se propõe a demonstrar, através de exemplos,que o GNU/Linux é um ambiente muito superior para este tipode atividade, se comparado com Sistemas Operacionais voltados

253

Page 288: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Console Gnu/Linux

principalmente para usuários leigos.Além do Console e sua linguagem (bash), neste capítulo va-

mos conhecer diversos aplicativos disponíveis no sistema operacio-nal Gnu/Linux, desenvolvidos para serem utilizados no console.

A linguagem BASH

A primeira coisa que se deve entender antes de começar a estudaro shell do Linux, é que este é uma linguagem de programação bas-tante poderosa em si mesmo. O termo Shell, cápsula, traduzidoliteralmente, se refere à sua função como uma interface entre ousuário e o sistema operacional. A shell nos oferece uma interfacetextual para invocarmos aplicativos e lidarmos com suas entradase saídas. A segunda coisa que se deve entender é que a shell não é osistema operacional, mas um aplicativo que nos facilita a interaçãocom o SO.

O Shell não depende de interfaces grácas sosticadas, mas co-mumente é utilizado através de uma janela, do conforto de umainterface gráca. Na gura 1, vemos um exemplo de uma sessãodo bash rodando em uma janela.

Alguns Comando Úteis

ls Lista arquivos.

cp Copia arquivos.

mv Renomeia ou move arqui-vos.

rm Apaga arquivos (de ver-dade!).

ln Cria links para arquivos.

pwd Imprime o nome do di-retório corrente (caminhocompleto).

mkdir Cria um diretório.

rmdir Remove um diretório.Para remover recursiva-mente toda uma árvorede diretórios use rm -rf(cuidado!).

254

Page 289: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

A linguagem BASH

Figura 1: Konsole: janela contendo uma sessão bash (ou outra) noKDE.

cat Joga o arquivo inteiro natela.

less Visualiza o arquivo compossibilidade de movimen-tação e busca dentro domesmo.

head Visualiza o início do ar-quivo.

tail Visualiza o nal do ar-quivo.

nl Visualiza com numeraçãodas linhas.

od Visualiza arquivo binárioem base octal.

xxd Visualiza arquivo binárioem base hexadecimal.

255

Page 290: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Console Gnu/Linux

gv Visualiza arquivos Posts-cript/PDF.

xdvi Visualiza arquivos DVIgerados pelo TEX.

stat Mostra atributos dos ar-quivos.

wc Conta bytes/palavras/li-nhas.

du Uso de espaço em disco.

le Identica tipo do arquivo.

touch Atualiza registro de úl-tima atualização do ar-quivo. Caso o arquivo nãoexista, é criado.

chown Altera o dono do ar-quivo.

chgrp Altera o grupo do ar-quivo.

chmod Altera as permissões deum arquivo.

chattr Altera atributos avan-çados de um arquivo.

lsattr Lista atributos avança-dos do arquivo.

nd Localiza arquivos.

locate Localiza arquivo pormeio de índice criado comupdatedb.

which Localiza comandos.

whereis Localiza o binário(executável), fontes, e pá-gina man de um comando.

grep Busca em texto retor-nando linhas.

cut Extrai colunas de um ar-quivo.

paste Anexa colunas de um ar-quivo texto.

sort Ordena linhas.

uniq Localiza linhas idênticas.

gzip Compacta arquivos no for-mato GNU Zip.

compress Compacta arquivos.

bzip2 Compacta arqui-vos(maior compactação doque o gzip, porém maislento.

zip Compacta arquivos no for-mato zip(Windows).

di Compara arquivos linha alinha.

256

Page 291: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Entradas e Saídas, redirecionamento e "Pipes".

comm Compara arquivos orde-nados.

cmp Compara arquivos bytepor byte.

md5sum Calcula checksums.

df Espaço livre em todos os dis-cos(pendrives e etc.) mon-tados.

mount Torna um disco acessí-vel.

fsck Verica um disco procu-rando por erros.

sync Esvazia caches de disco.

ps Lista todos os processos.

w Lista os processos do usuário.

uptime Retorna tempo desde oúltimo boot, e carga dosistema.

top Monitora processos em exe-cução.

free Mostra memória livre.

kill Mata processos.

nice Ajusta a prioridade de umprocesso.

renice Altera a prioridade deum processo.

watch Executa programas a in-tervalos regulares.

crontab Agenda tarefas perió-dicas.

Entradas e Saídas, redirecionamento e "Pipes".

O esquema padrão de entradas e saídas dos SOs derivados doUNIX, está baseado em duas idéias muito simples: toda comunica-çao é formada por uma sequência arbitrária de caracteres (Bytes),e qualquer elemento do SO que produza ou aceite dados é tratadocomo um arquivo, desde dispositivos de hardware até programas.

Por convenção um programa UNIX apresenta três canais decomunicação com o mundo externo: entrada padrão ou STDIN,saída padrao ou STDOUT e saída de erros padrão ou STDERR.

O Bash(assim como praticamente todas as outras shells) tornamuito simples a utilização destes canais padrão. Normalmente, um

257

Page 292: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Console Gnu/Linux

usuário utiliza estes canais com a nalidade de redirecionar dadosatravés de uma sequência de passos de processamento. Como esteprocesso se assemelha ao modo como canalizamos àgua para levá-lade um ponto ao outro, Estas construções receberam o apelido depipelines"ou tubulações onde cada segmento é chamado de pipe".

Devido a essa facilidade, muitos dos utilitários disponíveis nashell do Gnu/Linux foram desenvolvidos para fazer uma única coisabem, uma vez que funções mais complexas poderiam ser obtidascombinando programas através de pipelines".

Redirecionamento

Para redirecionar algum dado para o STDIN de um programa, utili-zamos o caracter <. Por exemplo, suponha que temos um arquivochamado nomes contendo uma lista de nomes, um por linha. Ocomando sort < nomes irá lançar na tela os nomes ordenados al-fabeticamente. De maneira similar, podemos utilizar o caracter >para redirecionar a saida de um programa para um arquivo, porexemplo.

Listagem 22: Redirecionando STDIN e STDOUT

1 $ s o r t < nomes > nomes_ordenados

O comando do exemplo 22, cria um novo arquivo com o con-teúdo do arquivo nomes, ordenado.

Pipelines

Podemos também redirecionar saídas de comandos para outros co-mandos, ao invés de arquivos, como vimos anteriormente. O carac-tere que usamos para isto é o | conhecido como pipe. Qualquerlinha de comando conectando dois ou mais comandos através depipes é denominada de pipeline.

258

Page 293: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Pérolas Cientícas do Console Gnu/Linux

Listagem 23: Lista ordenada dos usuários do sistema.

1 $ cut −d : −f 1 < / etc /passwd | s o r t2 ajaxterm3 avahi4 avahi−autoipd5 backup6 beag l e index7 bin8 boinc9 . . .

O simples exemplo apresentado dá uma idéia do poder dos pipe-lines, além da sua conveniência para realizar tarefas complexas,sem a necessidade de armazenar dados intermediários em arquivos,antes de redirecioná-los a outros programas.

Pérolas Cientícas do Console Gnu/Linux

O console Gnu/Linux extrai a maior parte da sua extrema versati-lidade de uma extensa coleção de aplicativos leves desenvolvidos7

para serem utilizados diretamente do console. Nesta seção, vamosver alguns exemplos, uma vez que seria impossível explorar todoseles, neste simples apêndice.

Gnu plotutils

O GNu Ploting Utilities é uma suite de aplicativos grácos ematemáticos desenvolvidos para o console Gnu/Linux. São eles:

graph Lê um ou mais conjuntos de dados a partir de arquivos oude STDIN e prepara um gráco;

7Desenvolvidos principalmente pelo projeto Gnu

259

Page 294: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Console Gnu/Linux

plot Converte Gnu metale para qualquer dos formatos listadosacima;

pic2plot Converte diagramas criados na linguagem pic para qual-quer dos formatos acima;

tek2plot Converte do formato Tektronix para qualquer dos for-matos acima.

Estes aplicativos grácos podem criar e exportar grácos bi-dimensionais em treze formatos diferentes: SVG, PNG, PNM, pseudo-GIF,

WebCGM, Illustrator, Postscript, PCL 5, HP-GL/2, Fig (editável

com o editor de desenhos xfig), ReGIS, Tektronix ou GNU Metafile.

Aplicativos Matemáticos:

ode Integra numericamente sistemas de equações diferenciais or-dinárias (EDO);

spline Interpola curvas utilizando splines cúbicas ou exponenci-ais. Pode ser utilizado como ltro em tempo real.

graph

A cada vez que chamamos o programa graph, ele lê um ou maisconjuntos de dados a partir de arquivos especicados na linha decomando, ou diretamente da STDIN, e produz um gráco. O grácopode ser mostrado em uma janela, ou salvo em um arquivo emqualquer dos formatos suportados.

Listagem 24: Plotando dados em um arquivo.

1 $ graph −T png < arquivo_de_dados_ascii >p lo t . png

Se o arquivo_de_dados_ascii contiver duas colunas de núme-ros, o programa as atribuirá a x e y, respectivamente. Os pares

260

Page 295: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Pérolas Cientícas do Console Gnu/Linux

ordenados que darão origem aos pontos do gráco não precisamestar em linhas diferentes. por exemplo:

Listagem 25: Desenhando um quadrado.

1 $ echo . 1 . 1 . 1 . 9 . 9 . 9 . 9 . 1 . 1 . 1 | graph−T X −C −m 1 −q 0 .3

A listagem 25 plotará um quadrado com vértices em (0.1,0.1),(0.1,0.9), (0.9,0.9) e (0.9,0.1). A repetição do primeiro vér-tice garante que o polígono será fechado. A opção -m indica o tipoda linha utilizada: 1-linha sólida, 2-pontilhada, 3-ponto e traço,4-traços curtos e 5-traços longos. A opção -q indica que o qua-drado será preenchido (densidade 30%) com a mesma cor da linha:vermelho (-C indica gráco colorido).

O programa graph aceita ainda muitas outras opções. Leia omanual(man graph) para descobrí-las.

spline

O programa funciona de forma similar ao graph no que diz res-peito à entradas e saídas. Como todos os aplicativos de console,benecia-se muito da interação com outros programas via pipes.

Listagem 26: Uso do spline

1 $ echo 0 0 1 1 2 0 | s p l i n e | graph −T X

Spline não serve apenas para interpolar funções, também podeser usado para interpolar curvas em um espaço d-dimensional utilizando-se a opçao -d.

Listagem 27: Interpolando uma curva em um plano.

1 echo 0 0 1 0 1 1 0 1 | s p l i n e −d 2 −a −s |graph −T X

O comando da listagem 27 traçará uma curva passando pelospontos (0,0), (1,0), (1,1) e (0,1). A opção -d 2 indica que

261

Page 296: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Console Gnu/Linux

Figura 2: Usando spline.

262

Page 297: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Pérolas Cientícas do Console Gnu/Linux

Figura 3: Interpolando uma curva em um plano.

a variável dependente é bi-dimensional. A opção -a indica que avariável independente deve ser gerada automáticamente e depoisremovida da saída (opção -s).

263

Page 298: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Console Gnu/Linux

ode

O utilitário ode é capaz de produzir uma solução numérica de sis-temas de equações diferenciais ordinárias. A saída de ode podeser redirecionada para o utilitário graph, que já discutimos anteri-ormente, de forma que as soluções sejam plotadas diretamente, àmedida em que são calculadas.

Vejamos um exemplo simples:

dy

dt= y(t) (3)

A solução desta equação é:

y(t) = et (4)

Se nós resolvermos esta equação numericamente, a partir dovalor inicial y(0) = 1, até t = 1 esperaríamos obter o valor de ecomo último valor da nossa curva (e1 = 2.718282, com 7 algarismossignicativos). Para isso digitamos no console:

Listagem 28: Resolvendo uma equação diferencial simples no con-sole do Linux.

1 $ ode2 y'=y3 y=14 print t , y5 s tep 0 ,1

Após digitar a ultima linha do exemplo 28, duas colunas denúmeros aparecerão: a primeira correspondendo ao valor de t ea segunda ao valor de y; a ultima linha será 1 2.718282. Comoesperávamos.

Para facilitar a re-utilização dos modelos, podemos colocar oscomandos do exemplo 28 em um arquivo texto. Abra o seu editorfavorito, e digite o seguinte modelo:

264

Page 299: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Pérolas Cientícas do Console Gnu/Linux

Listagem 29: Sistema de três equações diferenciais acopladas

1 # O modelo de Lorenz , Um si s tema de t r ê sEDOs acopladas ,

2 # com um parâmetro r .3 x ' = −3∗(x−y )4 y ' = −x∗z+r ∗x−y5 z ' = x∗y−z6

7 r = 268 x = 0 ; y = 1 ; z = 09 print x , y

10 s tep 0 , 200

Salve o arquivo com o nome lorenz. Agora digite no console aseguinte linha de comandos:

1 $ ode < lo r enz | graph −T X −C −x −10 10 −y−20 20

E eis que surgirá a bela curva da gura 4.

265

Page 300: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Console Gnu/Linux

Figura 4: Atrator de Lorenz.

266

Page 301: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Índice Remissivo

arange, 46aranha, 190array, 46

.shape, 46

bancos de dados, 185break, 32

cadeias de Markov, 214classe, 53

atributos, 54métodos, 55

conjuntos, 27Console Python, 4Controle de Versões, 86

Mercurial, 88Ctypes, 105

decoradores, 38dicionários, 24

métodos, 25

Editores, 80editores, 80

EDO, 258elif, 28else, 28Emacs, 81enumerate, 30equações de diferença, 145equações diferenciais, 148espaço de nomes, 10exceções, 32except, 32

nally, 32for, 30FORTRAN, 117funções, 34

lista de argumentos va-riável, 36

passando argumentos, 36funçoes

argumentos opcionais, 35

geradores, 38Gibbs, 219Gnu Nano, 81

267

Page 302: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Índice Remissivo

Grafos, 169graph, 258

Herança, 56

IDEs, 83if, 28import, 42Inferência Bayesiana, 203integração numérica, 148Ipython, 73

Comandos mágicos, 75iteração, 29

Java, 125Jedit, 81Jython, 126

lambda, 37LHS, 200listas, 13

métodos, 16

módulonumpy.linalg, 46scipy, 46

MódulosBeautifulSoup, 190email, 181mailbox, 182threading, 178

módulos, 41numpy, 45

Mathematica, xixMatlab, xix

MCMC, 216Mercurial, 88Metropolis-Hastings, 217modelagem matemática, 135modelos dinâmicos, 145modelos exponenciais, 142modelos lineares, 137monte carlo, 205

Números complexos, 10NetworkX, 172numpy, 45

objetos, 52operadores aritméticos, 8

pacotes, 44Palavras reservadas, 4pickle, 186print, 46pydoc, 47Pyrex, 106

R, xixreturn, 37

scipy, 46Scite, 81Shedskin, 111sqlite, 187SQLObject, 190strings, 22

formatando, 23

try, 32

268

Page 303: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

tuplas, 19

unidades, 155unum, 159urllib, 193urllib2, 193uso interativo, 5

verossimilhança, 228

weave, 100web-spider, 190while, 29

zip, 31

269

Page 304: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas
Page 305: Computação Cientí ca com Python - complex.if.uff.brcomplex.if.uff.br/_media/python_flavio.pdf · Computação Cientí ca com Python Uma introdução à programação para cientistas

Colophon

Este livro foi formatado usandoLATEX, criado por Leslie

Lamport e a classe memoir. Ocorpo do texto utiliza fontes detamanho 10 Modern Roman,criadas por Donald Knuth.Outras fontes incluem Sans,Smallcaps, Italic, Slanted andTypewriter, todas da família

Computer Modern desenvolvidapor Knuth.