Python para oceanógrafos/Engatinhando

Instalação

editar

A primeira coisa que você deve fazer antes escrever seu primeiro programa em Python é instalá-lo em seu computador. As distribuições Linux mais populares já vêm com Python instalado por padrão. O Mac OS em suas versões mais recentes também possui uma versão instalada. Entretanto, se você utiliza Windows, terá que instalar o Python em seu computador. Há diversas maneiras simples para instalá-lo e na maioria das vezes muito bem documentadas. Acesse o sítio Internet python.org, procure pelas instruções de instalação e siga-as. Não se esqueça também de instalar as bibliotecas utilizadas ao longo deste guia, listadas mais adiante.

Para instalação das bibliotecas, uma das ferramentas disponíveis para essa finalidade, é o pip (pip installs packages)[1] que permite a instalação e a manutenção dos módulos instalados, com um simples comando: pip install nome_da_biblioteca .

Outra indicação para uso do Python na linha de comando, é a interfácie interativa do Python através do Ipython[2], permitindo facilidades como autocompletar e teclas de atalho para funções.

Se você não quiser aventurar-se na instalação individual do Python e as principais bibliotecas utilizadas neste guia, recomendamos uma alternativa: Enthought Python Distribution. É uma distribuição de Python gratuita para fins não comerciais que vem com uma série de bibliotecas e ferramentas instaladas.


Lógica de programação

editar

O objetivo deste guia não é transformá-lo em um guru em programação, mas introduzir conceitos importantes de uma ferramenta para análise de dados oceanográficos. No entanto é necessário desenvolver uma forma de pensar e organizar as ideias de modo a traduzi-las em uma linguagem computacional. Esta forma de pensar combina elementos matemáticos, de engenharia e das ciências naturais. Assim como os matemáticos, cientistas da computação utilizam linguagens formais para denotar ideias (principalmente cálculos computacionais). Como os engenheiros, eles criam coisas, montam componentes para formar sistemas e avaliam os benefícios de alternativas. Como cientistas, eles observam o comportamento de sistemas complexos, formam hipóteses e testam previsões (Downey, 2008).

Uma das habilidades mais importantes a serem desenvolvidas é a capacidade de solucionar problemas de maneira lógica. Mas, para solucioná-los, é preciso saber formular estes problemas, usar sua criatividade para encontrar soluções e expressar estas soluções de maneira clara e acurada.

A forma mais simplificada de se ver um programa é considerá-lo uma sequência de instruções que especificam como executar cálculos computacionais. Estes cálculos computacionais podem ser puramente matemáticos, como o cálculo da média de um conjunto de números, ou simbólicos, como agrupar uma lista de espécies por gênero e organizá-la em ordem alfabética.

As instruções de qualquer linguagem de programação podem ser agrupadas de diferentes formas ou de acordo com a sua função:

  • Entrada. Adquire dados a partir do teclado, de um arquivo ou outro dispositivo.
  • Saída. Exibe dados ou resultados na tela, armazena-os em um arquivo ou os envia a outro dispositivo.
  • Matemática. Performa operações matemáticas como adição ou multiplicação.
  • Execução condicional. Verifica por determinadas condições e executa a sequência de instruções apropriada.
  • Repetição. Performa ação repetitiva, em geral com alguma variação.

Por mais simplista que possa parecer, qualquer programa, independente de sua complexidade, pode ser resumido por instruções de um destes cinco grupos. Desta forma, a programação consiste em dividir um problema grande e complexo em tarefas cada vez menores e simplificadas até que elas possam ser executadas por instruções básicas. E este é talvez o maior desafio para qualquer programador, compreender o problema a ser resolvido e dividi-lo em tarefas distintas.

Linguagens de programação são linguagens formais criadas por pessoas para aplicações específicas. Elas foram criadas para serem completamente, ou quase, desambigues, de modo que uma declaração tenha apenas um único sentido, independente do contexto. Elas são menos redundantes e mais concisas que as línguas naturais. A expressão “a vaca foi para o brejo”, em uma linguagem formal, a expressão será interpretada em seu significado literal. Por analogia, pode-se dizer que a poesia está para a prosa como a prosa está para a programação.

Para iniciantes na programação, é preciso acostumar-se a ler uma linguagem formal e tomar certos cuidados. Linguagens formais são mais densas, de modo que leva mais tempo para lê-las. Sua estrutura é muito importante e detalhes fazem a diferença. Pequenos erros de grafia ou pontuação podem fazer uma grande diferença e dar muita dor de cabeça.

Primeiros comandos

editar

Python é uma linguagem interpretada que possibilita seu uso de duas formas: pelo modo interativo e pelo modo de script. Inicie o seu interpretador Python e, dependendo da versão instalada, aparecerá na tela texto semelhante a este,

 Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
 [GCC 4.4.3] on linux2
 Type "help", "copyright", "credits" or "license" for more information.
 >>>

A divisa >>> é a linha de comandos do interpretador e indica que ele está pronto para receber um comando. Digite 1 + 1, pressione a tecla enter e o interpretador retornará como resposta 2. Alternativamente, você também pode armazenar uma sequência de comandos em arquivos de código e utilizar o interpretador para executar o conteúdo deste arquivo, chamado de script.

Trabalhar no modo interativo é bastante conveniente para testar pequenos pedaços de código, executando-os imediatamente. Entretanto, para um número maior de linhas de comando, você deve salvar seu código em um arquivo na forma de script para executá-lo e modificá-lo no futuro.

 >>> print 'Bom dia!'
 Bom dia!

Este é o exemplo de um comando de impressão na tela. Aspas simples (') ou duplas (") indicam o início e o fim do texto a ser exibido e não aparecem no resultado. Procure acompanhar os exemplos aqui descritos experimentando-os enquanto lê o texto. Procure também experimentar novas funcionalidades e introduza erros propositalmente. Este tipo de experiência lhe ajudará a lembrar dos comandos e também a familiarizar-se com os tipos de mensagem de erros. Aprender a lidar com erros de programação é um treinamento importante, pois estes fazem parte do dia-a-dia mais do que desejamos. Além disso ao errar de propósito e conscientemente agora é preferível a cometer erros imperceptíveis depois.


Tipos de variáveis

editar
  • Números:

Números são o primeiro tipo de variável que vem em mente e em Python temos basicamente 2 tipos de números, os inteiros (integer) e os números de ponto flutuante (float). A diferença é que as operações que utilizam exclusivamente números inteiros necessariamente retornarão números inteiros. Já as operações com, pelo menos 1 dos números float retornam float como resposta. Na pratica, temos:

Para uma dada variável a igual a 3 :

 >>> a = 3

Podemos verificar o tipo de uma variável qualquer utilizando a função type :

 >>> type(a)
 <type 'int'>

Como dito anteriormente, operações com números inteiros devem retornar valores inteiros. Então, se usarmos o operador /, que significa divisão, temos:

 >>> a/3
 1

Para definirmos um float podemos, ou colocar um ponto após o número atribuído >>> a = 3. ou multiplicarmos o número inteiro por um float neutro, como se >>> a = 3, redefinirmos >>> a = a*1.. Desta forma:

 >>> type(a)
 <type 'float'>
 >>> a/3
 1.5

  • Texto, formatando textos com (%s, %d, %i, %f):

Textos, ou strings, representam caracteres em geral, ou seja, números, letras ou outros símbolos. Strings podem ser definidas quando colocamos caracteres entre aspas (") ou apóstrofes ('). Para uma dada variável str:

 >>> str = "caract3r3s_\""
 >>> print str
 >>> "caract3r3s_""

Veja que, como apóstrofes representam os limites de uma string, para utilizar os caracteres ' ou " dentro de uma string é preciso utilizar o caractere \, ou seja, \' ou \". Como você pode prever, para utilizar o caractere \ dentro de uma string, utilizamos este caractere em par, ou seja, \\.

Existem algumas operações matemáticas que podem ser realizadas por textos. A mais simples de todas é a de soma e esta só pode ser realizada entre duas strings:

 >>> 'Python is better than '+'Matlab'
 'Python is better than Matlab'

Como viste, a soma de duas strings retorna a justaposição entre estas. A outra operação básica é a multiplicação (*). Esta só pode ser realizada entre uma string e um número inteiro (integer). Para um dado número inteiro N e um texto str1 temos que N*str1 retornará N justaposição de str1:

 >>> N = 3
 >>> 'Python is better than Matlab '*N
 'Python is better than Matlab Python is better than Matlab Python is better than Matlab '

Você pode criar uma string a partir de um número basicamente por duas formas.

Utilizando a função str():

 >>> a = str(4)
 >>> print a
 '4'

Utilizando o símbolo %:

 >>> numero = 3.145
 >>> string = '%i' %(numero)
 >>> string
 '3'
 >>> string = '%d' %(numero)
 >>> string
 '3'
 >>> string = '%s' %(numero)
 >>> string
 '3.145'
 >>> string = '%f' %(numero)
 >>> string
 '3.145'

As opções %d e %i retornam a mesma string porque significam a mesma coisa, ou seja, retornar a string referente a forma integer do número dado. A opção %s e a opção %f retornaram a mesma string, mas a primeira conta os caracteres a partir do 3, interpretando o . também como um caractere e a segunda forma conta os caracteres a partir do primeiro valor após o .. Na prática temos como determinar quantos caracteres devem ser usados utilizando um . e um número depois do símbolo %:


 >>> numero = 3.145
 >>> string = '%.3i' %(numero)
 >>> string
 '003'
 >>> string = '%.3d' %(numero)
 >>> string
 '003'
 >>> string = '%.3s' %(numero)
 >>> string
 '3.1'
 >>> string = '%.3f' %(numero)
 >>> string
 '3.145'

O mesmo pode ser feito usando a função .format() :

 >>> colocacao = 3
 >>> total = 10
 >>> print 'Na corrida, fui o {:0>3d} colocado de {:0>3d} competidores'.format(colocacao,total)
 Na corrida, fui o 003 colocado de 010 competidores

Desta forma, adiciona-se chaves {} no meio do texto com as especificações começando por :, no caso, especificamos que queremos que o número seja representado por um integer (d) de 3 caracteres alinhado no lado direito (>) e que os caracteres que sobrarem sejam substituídos por 0.

Ficou com dúvida ainda? Visite a Documentação de Python para Strings.

  • Listas

Listas são variáveis que possuem mais de uma informação, seja ela números ou textos. A forma mais simples de definir uma lista é utilizando [] colchetes. Diferente de outras linguagens, Python é uma linguagem dinâmica, então não é necessário definir o tamanho da lista antes de criá-la.

 >>> minha_lista = [2,4,1,5,'textoqualquer']

A indexação inicia do número zero. Isto significa que se queres o primeiro valor, utiliza-se [0] depois do nome da variável do tipo lista:

 >>> minha_lista[0]
 2

Em Python, cada variável é um objeto com suas propriedades. Você pode verificar a lista de propriedades de um determinado objeto usando a função dir():

 >>> dir(minha_lista)
 ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', 
 '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__',
 '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__',
 '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index',
 'insert', 'pop', 'remove', 'reverse', 'sort']

Em geral, as propriedades que começam e terminam com "__" são informações sobre os objetos que não modificam nem calculam nada, como a __doc__ que informa o tipo de variável e como criá-la. As outras propriedades são, em geral, funções que ou retornam alguma propriedade calculada, ou modificam a lista. Você acessa uma propriedade usando o formato objeto.propriedade quando esta é uma função utiliza-se objeto.propriedade(input) em que este input pode não ser necessário. Na prática, vamos utilizar como exemplo a função append(). Podemos descobrir o que esta função faz acessando seu __doc__

 >>> minha_lista.append.__doc__
 'L.append(object) -- append object to end'

Então ela adiciona um novo objeto ao fim da lista. Para usá-la adicionaremos um novo objeto e verificaremos o que ocorre com a lista:

 >>> print minha_lista
 [2, 4, 1, 5, 'textoqualquer']
 >>> minha_lista.append('teste')
 >>> print minha_lista
 [2, 4, 1, 5, 'textoqualquer', 'teste']

Você pode usar a indexação para alterar um objeto qualquer. Assim como dito anteriormente, lembre que a indexação inicia do zero, mas saiba também que você pode contar do último para o primeiro, sendo a última posição igual a -1, a penúltima -2 e assim por diante:

 >>> print minha_lista
 [2, 4, 1, 5, 'textoqualquer', 'teste']
 >>> minha_lista[-1] = 'QualquerCoisa'
 >>> print minha_lista
 [2, 4, 1, 5, 'textoqualquer', 'QualquerCoisa']


  • Tuplos

Tuplos são muito semelhante a listas e, a primeira vista, a única diferença é que ao invés de [] colchetes utilizam () parênteses, mas a maior diferença é que os objetos dos tuplos não podem ser modificados. Estes podem ser utilizados para lista de constantes que você utilizará em seu trabalho, pois assim você se assegurará de que estas não serão modificadas:

 >>> constantes = (9.82,3.14,'textoqualquer')
 >>> type(constantes)
 <type 'tuple'>
 >>> constantes[1] = 666
 Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
 TypeError: 'tuple' object does not support item assignment


  • Dicionários

Dicionários são como um tipo especial de lista em que cada objeto tem seu próprio nome. Desta forma, a forma que se tem de indexar, ou chamar algum objeto é informando seu nome e não sua posição. Ao invés de [] colchetes, dicionários são definidos com {} chaves:

 >>> filho = {'nome':'Fulano','sobrenome':'Sicrano da Silva','idade':34,'filhos':[]}
 >>> filho2 = {'nome':'Fulaninha','sobrenome':'Sicraninha da Silva','idade':43,'filhos':[]}
 >>> pai = {'nome':'Fulanão','sobrenome':'Sicrano da Silva','idade':75,'filhos':[filho,filho2]}

Desta forma podemos mostrar que dentro de um dicionário os objetos podem ser de quaisquer tipos, como texto, no caso nos nomes, número, no caso das idades, lista, no caso dos filhos, ou até mesmo um outro dicionário.

 >>> pai['nome'] # nome do pai
 >>> 'Fulanão'

Se aparecer 'Fulan\xc3\xa3o' não se preocupe estamos usando caracteres em utf-8, mais na frente será explicado

 >>> pai['filhos'][0] # primeiro filho da lista de filhos
 {'idade': 34, 'filhos': [], 'sobrenome': 'Sicrano da Silva', 'nome': 'Fulano'}
 >>> pai['filhos'][1]['nome'] # nome do segundo filho da lista de filhos de pai
 Fulaninha


  • array

Algoritmos

editar

De forma simples, algoritmo é uma sequência de ações que devem ser executadas para um determinado fim. Um exemplo claro de um algoritmo é uma receita de bolo: se as instruções não forem executadas na ordem necessária, não terás como resultado a finalidade desejada que é o bolo com determinada textura e sabor.

A sua relação com a programação é total, já que, programas nada mais são do que algoritmos escritos em uma determinada linguagem de programação. Como exemplo podemos utilizar o algoritmo que aprendemos no colegial para cálculo da hipotenusa de um triângulo retângulo:

 # O jogo da velha, ou sharp, representa uma linha de comentário em Python
 # Isso significa que tudo que está após o símbolo não será interpretado
 # Isto serve para que você explique o que quis fazer em uma determinada parte
 # do código ou para dar instruções para quem for ler seu programa
 
 # Vamos começar escrevendo o algoritmo em português:
 # Primeiro temos que definir os nomes e valores de cada cateto
 # Depois calculamos a soma de seus quadrados
 # E então a hipotenusa será igual a raiz quadrada desta soma
 
 # Em Python:
 cateto1 = 3
 cateto2 = 4
 
 soma = cateto1**2 + cateto2**2
 
 hipotenusa = soma**(1/2.)
 print hipotenusa

Isto deve retornar:

 5

Meu primeiro script

editar

O exemplo a seguir calculará o produto fatorial de um número para ilustrar cada um dos cinco tipos de instruções. Enquanto você digita cada linha de código, tente identificar a qual grupo de instruções ela pertence.

 >>> # Calculo do produto fatorial n!
 ... n = input 'n = '
 >>> n = input('n = ')
 n = 3
 >>> if n == int(n):
 ...     N = 1
 ...     for i in range(n):
 ...         N *= (i + 1)
 ...     print 'n! = %d' % (N)
 ...
 n! = 6

Testando seu código

editar

A programação é propensa a erros. Existem três tipos de erros que podem ocorrer em um programa:

  1. Erros sintáticos. Programas podem apenas ser executados se a sintaxe estiver correta. Por sintaxe entende-se a estrutura de um programa e as regras que regem tal estrutura. Tomando como exemplo n = 1 / (2 * (3 + 4), ocorrerá um erro de sintaxe devido à ausência de um parenteses fechando a expressão.
  2. Erros de execução. São erros que surgem apenas durante a execução do programa. Eles também são chamados de exceções e indicam a ocorrência de algo excepcionalmente ruim.
  3. Erros semânticos. Estes estão dentre os erros mais difíceis de serem detectados. Eles ocorrem quando o código possui um erro de lógica de programação e acaba não gerando nenhuma mensagem de erro, tanto de sintaxe quanto de exceção. Por exemplo, se quisermos descobrir o quanto é duas vezes o valor da soma 3 + 4 e escrevermos a expressão a = 2 * 3 + 4, o resultado não será \lstinline{14}. Neste caso temos um erro no significado do programa (na semântica) e o interpretador não identificará este erro pois o problema foi mau formulado.

Remover erros em programas, ou depurar, é uma das habilidades mais importantes na programação. É, ao mesmo tempo, um trabalho de detetive e de cientista experimental. Principalmente quando há erros erros semânticos, procura-se pela causa desconhecida através de testes de hipótese.

Para minimizar os erros durante a programação, Beck (2003) sugere a adoção de uma técnica de desenvolvimento regida por testes (TDD — test-driven development). TDD parte do princípio de que antes de se solucionar cada uma das pequenas partes que compõem um programa, deve-se formular testes específicos e apenas avançar para o próximo estágio quando todos os testes anteriores passarem.

Exercícios

editar

Exercício 1. Inicialize o interpretador do Python e digite help() para abrir o utilitário de ajuda. Se este comando não funcionar, você deve procurar instalar a documentação adicional do Python ou configurar uma variável de ambiente local, dependendo de seu sistema operacional. Outra forma de exibir a documentação de um comando específico, como por exemplo o comando print, é digitar help(print).

Exercício 2. Utilize um navegador Internet para acessar a página python.org. Esta página possui informações sobre a linguagem Python, atalhos para páginas relacionadas a Python e também possibilita a busca em sua documentação. Faça uma busca e discuta o resultado do comando

 >>> print '%d * %s = %.2f' % (2, 'pi', 2 * 3.1415926535897931)
 2 * pi = 6.28

Exercício 2. Utilize o interpretador do Python como uma calculadora. Seja dado o seguinte conjunto de valores: [1, 10, 8, 6, 5, 3, 2, 5, 5, 3]. Determine a soma, os valores mínimo e máximo e a média da série. Lembre que os operadores matemáticos no Python possuem notação semelhante à que estamos acostumados nas aulas de matemática, ou seja, +, -, * e / denotam respectivamente adição, subtração, multiplicação e divisão.

Referências

Beck, Kent. Thest-driven development: By example. Addison-Wesley, 2003. 220 p.

Downey, Allen. Think Python: How to think like a computer scientist. Green Tea Press, 2008. 214 p.