Introdução 1 - Python & Spyder

Modelação Numérica 2016/17

Mestrado Integrado em Engenharia da Energia e do Ambiente
Licenciatura em Meteorologia, Oceanografia e Geofísica
Licenciatura em Engenharia Geoespacial

DEGGE-FCUL
Departamento de Engenharia Geográfica, Geofísica e Energia
Faculdade de Ciências da Universidade de Lisboa

Introdução ao Python

Adaptado de IRIS: https://nbviewer.jupyter.org/github/obspy/docs/blob/master/workshops/2015-08-03_iris/01_Python_Crash_Course.ipynb

Esta aula é dedicada a explorar alguns comandos básicos de Python e a conhecer o ambiente Spyder. Segue os comandos passo a passo. Assegura-te de que percebes como funcionam todas as linhas de comando e funções.

NumPy para utilizadores de Matlab

Se estás habituado a utilizar Matlab, aqui ficam alguns links úteis:

Spyder

Explora o que podes fazer no Spyder:

  • Vê quais as funções disponíveis no Menú (File, Edit, Search, Source, Run, Debug, etc...).
  • Vê como funcionam as várias janelas do Spyder e o que podes fazer em cada uma delas.
  • Aprende a utilizar teclas de atalho para poderes trabalhar mais rapidamente.
  • Utiliza "#%%" para separar diferentes blocos de código.
In [1]:
x = "Hello World!"
In [2]:
x.
  File "<ipython-input-2-64a09567da13>", line 1
    x.
      ^
SyntaxError: invalid syntax

Ajuda

  • Usa o ponto de interrogação para pedir ajuda sobre funções ou métodos.
In [3]:
x.lower?

Importação de módulos

In [4]:
# Importa a função 'print' do Python 3, com a seguinte utilização: print("Hello")
from __future__ import print_function

# Importar NumPy - módulo de funções numéricas
import numpy as np

# Importar MatplotLib - módulo de gráficos
import matplotlib.pyplot as plt

# Parâmetros dos gráficos
plt.style.use('ggplot')
plt.rcParams['figure.figsize'] = 12, 8

1. Números

Em Python as variáveis são definidas de forma dinâmica com base na sua sintaxe, sem ser necessário definir o tipo.

In [5]:
# Três tipos básicos de números
a = 1             # Inteiros
b = 2.0           # Reais (floating point)
c = 3.0 + 4j      # Complexos

# Verificar o tipo das variáveis
type(a)

# A aritmética funciona como esperado...
d = a + b         # (int + float = float)
e = c ** 2        # c ao quadrado

2. Variáveis boleanas

In [6]:
estado1 = True
estado2 = not estado1

print(estado1)
print(estado2)

print(b)
print(b > 100)
True
False
2.0
False

3. Frases (strings)

In [7]:
# Podem-se usar plicas (') ou aspas () para criar frases
local = "Faculdade de Ciencias"

# As frases/palavras podem ser concatenadas com +
onde_estou_eu = "Eu estou na " + local

# Print things with the print() function.
print(local)
print(onde_estou_eu)

# Em python tudo são objectos..
# As frases (strings) têm muitos métodos anexados para manipulações comuns.
print(local.upper())

# Acede-se a letras ou conjuntos de letras com parêntesis rectos.
print(local[0], local[:5], local[3:9])

# Utilizam-se índices negativos para aceder a posições opr ordem inversa (a começar do fim).
print(local[-1], local[-9:])
Faculdade de Ciencias
Eu estou na Faculdade de Ciencias
FACULDADE DE CIENCIAS
F Facul uldade
s  Ciencias

4. Listas

In [8]:
# As listas são escritas com parêntesis rectos e são simples colecções ordenadas de items (de tipo arbitrário)
TudoJunto = [a, c, local, 1, 2, 3, "hello"]
print(TudoJunto)

# Acede-se aos elementos das listas utilizando a mesma síntaxe que para as frases
# Importante: Em Python os índices começam em zero!
print(TudoJunto[0])
print(TudoJunto[:3])
print(TudoJunto[2:-2])
print(TudoJunto[-3:])

# Podem-se juntar mais elementos à lista utilizando o método 'append'
# (Existem também outros métodos auxiliares para listas)
TudoJunto.append("tu")
print(TudoJunto)
[1, (3+4j), 'Faculdade de Ciencias', 1, 2, 3, 'hello']
1
[1, (3+4j), 'Faculdade de Ciencias']
['Faculdade de Ciencias', 1, 2]
[2, 3, 'hello']
[1, (3+4j), 'Faculdade de Ciencias', 1, 2, 3, 'hello', 'tu']

5. Dicionários

In [9]:
# Os dicionários têm campos reconhecidos pelos seus nomes, sem ordem inerente.
# Tal como as listas, podem conter items de qualquer tipo
info = {
    "nome": "Sara",
    "apelido": "Silva",
    "idade": 48,
    "filhos": ["Ana", "Miguel"]
}

# Acede-se aos items chamando o campo dentro de parêntesis rectos.
print(info["filhos"])

# Adicionam-se novos items, explicitado o campo.
print(info)
info["musica"] = "jazz"
print(info)
['Ana', 'Miguel']
{'idade': 48, 'filhos': ['Ana', 'Miguel'], 'apelido': 'Silva', 'nome': 'Sara'}
{'idade': 48, 'filhos': ['Ana', 'Miguel'], 'musica': 'jazz', 'apelido': 'Silva', 'nome': 'Sara'}

6. Funções

In [10]:
# As funções são definidas com a palavra-chave "def".
# O corpo da função é o bloco identado que aparece depois da sintaxe 
# de definição da função e normalmente e normalmente termina com um comando de "return"

def vezes(a, b):
    return a * b

# Para se chamar uma função utilizam-se parêntesis curvos.
print(vezes(2, 3))
6
In [11]:
# Os argumentos das funções podem ter valores pré-definidos.
def tempo(distancia, velocidade=80.0):
    return distancia / velocidade

# Se não for definido um valor diferente, o valor pré-definido é utilizado.
print(tempo(1000))
print(tempo(1000,100))
12.5
10

7. Importar

Para importar funções e objectos que não fazem parte do espaço pré-definido, é necessário importá-las.

In [12]:
# Importar o módulo math, e chamar os seus métodos utilizando o ponto '.'

import math

a = math.cos(4 * math.pi)

# Também se podem importar funções específicas de cada módulo.
from math import pi

b = 2.0 * pi

# E até lhes podemos dar novos nomes se não gostarmos dos nomes pré-definidos.
from math import cos as coseno
c = coseno(b)
print(c)
1.0

8. Ciclos e condições

Os ciclos e condições são indispensáveis para qualquer operação não trivial. É importante notar que os espaços em branco contam no Python. Tudo o que tem a mesma identação é interpretado como fazendo parte do mesmo bloco!

In [13]:
temp = ["a", "b", "c"]

# Um ciclo clássico é o para-cada (for), ex:
for item in temp:
    print(item)
a
b
c
In [14]:
# A função 'range()' é útil.
for i in range(5):
    print(i)
0
1
2
3
4
In [15]:
# As condições se-então (if/else) funcionam como esperado.
idade = 77
#idade = -1.

if idade >= 0 and idade < 10:
    print("Menos de 10 anos.")
elif idade >= 10:
    print("Mais do que 10 anos.")
else:
    print("O quê???")
Mais do que 10 anos.
In [16]:
# As listas compreensivas são uma forma simpática de escrever ciclos de forma compacta.

a = list(range(10))
print(a)
b = [i ** 2 for i in a]
print(b)

# Ciclo 'for' equivalente para gerar b.
b = []
for i in a:
    b.append(i ** 2)
print(b)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
In [17]:
# Os ciclos 'enquanto' (while) são executados repetidamente, enquanto as condições são verdadeiras ("True").

feliz = False
doces = 0
print(doces)

while not feliz:
    doces += 1
    print('doces = ' + str(doces))
    if doces >= 20:
        feliz = True
        print('20 doces... Mmm...')

print('doces = '+ str(doces))
0
doces = 1
doces = 2
doces = 3
doces = 4
doces = 5
doces = 6
doces = 7
doces = 8
doces = 9
doces = 10
doces = 11
doces = 12
doces = 13
doces = 14
doces = 15
doces = 16
doces = 17
doces = 18
doces = 19
doces = 20
20 doces... Mmm...
doces = 20

9. Excepções

No processamento automático de scripts, por veses acontecem coisas inesperadas que fazem com que o Python pare a execução do código e levante uma Exception (podemos pensar nisto como um erro). Às vezes, mesmo assim, gostaríamos que o código continuasse a correr...

In [18]:
while True:
    try:
        x = int(raw_input("Escreve um numero: "))
        break
    except ValueError:
        print("Oh-oh! Isso não é um número válido. Tenta outra vez...")        
Escreve um numero: 
Oh-oh! Isso não é um número válido. Tenta outra vez...
Escreve um numero: 1

Mas cuidado, continuar sempre em caso de Excepções pode mascarar erros nos códigos.

In [19]:
# Outro exemplo:

def isto_falha():
    x = 1/0

try:
    isto_falha()
except ZeroDivisionError as detail:
    print('Temos um problema: ' + str(detail))
Temos um problema: integer division or modulo by zero

10. NumPy

O NumPy é um dos módulos mais utilizados pela comunidade científica. No centro do Numpy estão as variáveis de tipo "ndarray" (matrizes n-dimensionais). As operações com matrizes NumPy são económicas em memória utilizada e computacionalmente rápidas (as computações internas são feitas em C). É boa ideia trabalhar com as arrays e funções do NumPy sempre que possível.

In [20]:
import numpy as np

# Criar uma matriz com um milhão de amostras, igualmente espaçadas, entre 1 e 100.
x = np.linspace(0, 100, 1E6)

# A maioria das operações é aplicada elemento a elemento.
y = x ** 2

# Recorre a C e Fortran para fazer os cálculos mais rapidamente.
print(y.sum())
3333335000.0

11. Fazer gráficos

Os gráficos são frequentemente feitos com o módulo matplotlib. A interface do matplotlib é semelhante à do matlab.

In [21]:
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi, 2000)
y = np.sin(x)

plt.plot(x, y, color="green", label="sine wave")
plt.legend()
plt.ylim(-1.1, 1.1)
plt.grid()
#plt.show()

# gravar a imagem num ficheiro
# para gravar noutros formatos de imagem basta mudar a extensão
plt.savefig('myplot1.pdf')          
plt.savefig('myplot1.jpg')          

12. Limpar variáveis

In [22]:
# Apagar uma ou mais variáveis.
a=1
b=2
del a, b

# Apagar todos os objectos, incluindo os módulos importados.
# Na linha de comando:
# %reset
# %reset -f

# Apagar gráficos

plt.close()

# Listar todos os objectos
dir()

# Função útil que apaga todas as variáveis, mas não apaga os objectos relacionados com os módulos importados nem funções globais.
# Pode-se inserir no início dos scripts e chamar com 'clear_all()'.
def clear_all():
    """Clears all the variables from the workspace of the spyder application."""
    gl = globals().copy()
    for var in gl:
        if var[0] == '_': continue
        if 'func' in str(globals()[var]): continue
        if 'module' in str(globals()[var]): continue

        del globals()[var]
if __name__ == "__main__":
    clear_all()

Exercícios

Funções, NumPy, and Matplotlib

1. Funções, NumPy e Matplotlib

a) Escreve uma função que pega num vector NumPy x e em três números reais a, b e c como argumentos e calcula:

$$ f(x) = a x^2 + b x + c $$

b) Faz o gráfico da função para valores arbitrários de a, b e c e para valores de x entre -3 e +3.

2. 99 Garrafas de cerveja

(tirado de http://www.ling.gu.se/~lager/python_exercises.html)

"99 Bottles of Beer" é uma canção tradicional dos EUA e Canadá. É típico cantá-la em viagens longas, porque é repetitiva, fácil de memorizar e pode-se cantá-la durante muito tempo. A letra da canção é a seguinte:

99 bottles of beer on the wall, 99 bottles of beer.
Take one down, pass it around, 98 bottles of beer on the wall.

O mesmo verso é repetido, cada vez com uma garrafa a menos. A canção termina quando se chega às zero garrafas.

Escreve um script Python capaz de gerar todos os versos da canção.

3. A cifra de César

(tirado de http://www.ling.gu.se/~lager/python_exercises.html)

Em criptografia, o código de César é uma técnica de encriptação muito simples, na qual cada letra do texto é substituida por uma letra que fica um número de posições fixas mais à frente no alfabeto. Por exemplo, com um passo de 3, a letra A seria substituída por D, B por E, e assim consecutivamente. O método tem o nome de Júlio César, que o utilizou para comunicar com os seus generais.
ROT-13 ("rotação com passo de 13") é um exemplo da cifra de César em que o passo é 13. Em Python, a chave do ROT-13 pode-se representar com o seguinte dicionário:

chave = {'a':'n', 'b':'o', 'c':'p', 'd':'q', 'e':'r', 'f':'s', 'g':'t', 'h':'u', 
       'i':'v', 'j':'w', 'k':'x', 'l':'y', 'm':'z', 'n':'a', 'o':'b', 'p':'c', 
       'q':'d', 'r':'e', 's':'f', 't':'g', 'u':'h', 'v':'i', 'w':'j', 'x':'k',
       'y':'l', 'z':'m', 'A':'N', 'B':'O', 'C':'P', 'D':'Q', 'E':'R', 'F':'S', 
       'G':'T', 'H':'U', 'I':'V', 'J':'W', 'K':'X', 'L':'Y', 'M':'Z', 'N':'A', 
       'O':'B', 'P':'C', 'Q':'D', 'R':'E', 'S':'F', 'T':'G', 'U':'H', 'V':'I', 
       'W':'J', 'X':'K', 'Y':'L', 'Z':'M'}

Implementa uma descodificação do ROT-13. Quando terminares, conseguirás descodificar as seguintes mensagens secretas:

Nir Prfne!
Cbe Ghgngvf, rfgrf Ebznabf fnb ybhpbf!

Bónus: Escreve um codificador!