Astrolábio · Tutorial de Python

Apoio · para quem está a começar

Tutorial de Python

Os programas deste livro usam trinta e duas coisas diferentes do Python, e nenhuma delas se aprende por adivinhação. Esta página explica-as uma a uma, do princípio: o que é, um exemplo que se pode correr aqui mesmo, o que aparece no ecrã, e o erro que se comete de facto.

Não é preciso ler de fio a pavio. Cada janela de código do livro tem um botão que abre esta página nos assuntos que aquele programa usa.

32 assuntos 8 secções 42 exemplos para correr
T1

Escrever, guardar, contar

Um programa é uma lista de ordens, cumpridas de cima para baixo, uma de cada vez. Não é preciso saber mais nada para escrever o primeiro.

Como usar esta página

Cada assunto tem um programa pequeno que podes correr sem mudar nada. Carrega em «Correr no compilador», vê o que aparece, e só depois lê a explicação — dá muito mais jeito nessa ordem. Se chegaste aqui pelo botão de um programa do livro, os assuntos desse programa estão marcados no índice, à esquerda.

Escrever no ecrã · print()

O print é a ordem «mostra isto». O que se quer mostrar vai entre parênteses. É a primeira coisa que se aprende porque, sem ela, um programa corre e não se vê nada — e não saber se funcionou é pior do que não funcionar.

print("Ola!")
print(2 + 3)
print("2 + 3 dá", 2 + 3)

No ecrã:

Ola!
5
2 + 3 dá 5

Três coisas se veem aqui. A primeira: o que está entre aspas aparece tal e qual — o print não faz perguntas, escreve o que lá está. A segunda: o que não está entre aspas é calculado primeiro, e só depois escrito; por isso a segunda linha dá 5 e não 2 + 3. A terceira: dentro dos parênteses podem ir várias coisas separadas por vírgulas, e o Python põe um espaço entre elas.

O erro típico: esquecer as aspas. print(Ola) não escreve Ola — o Python procura uma variável chamada Ola, não a encontra, e pára com NameError: name 'Ola' is not defined. Com aspas é texto; sem aspas é um nome.

Variáveis: dar um nome a um valor

Uma variável é um nome colado a um valor. Escreve-se o nome, um sinal de igual, e o valor. A partir daí, onde se escrever o nome está lá o valor.

preco = 12
quantidade = 3
total = preco * quantidade
print("Total:", total)

No ecrã:

Total: 36

O sinal = aqui não é o igual da matemática. Em matemática, x = x + 1 não tem solução. Em Python, x = x + 1 lê-se «calcula x + 1 e guarda o resultado outra vez em x» — e faz-se a toda a hora:

x = 10
x = x + 1
print(x)

No ecrã: 11. A ordem é sempre a mesma: primeiro calcula-se o que está à direita, depois guarda-se no nome que está à esquerda.

Os nomes podem ter letras, números e o traço de baixo, mas não podem começar por número nem ter espaços. total_2 serve; 2total e total geral não. E há maiúsculas a contar: Total e total são dois nomes diferentes.

O erro típico: usar um nome antes de lhe dar valor. Se escreveres print(iva) sem nunca teres escrito iva = …, o Python pára com NameError. A ordem das linhas conta.

Números e as quatro operações

O Python faz contas com os símbolos do costume: +, -, * para multiplicar e / para dividir. Os parênteses funcionam como na matemática, e a precedência também: primeiro * e /, depois + e -.

print(2 + 3 * 4)
print((2 + 3) * 4)
print(7 / 2)
print(3 * 0.1)

No ecrã:

14
20
3.5
0.30000000000000004

As duas primeiras não surpreendem. A terceira mostra uma coisa importante: o / dá sempre um número com casas decimais, mesmo quando a divisão é exacta — 4 / 22.0 e não 2. A quarta é a que assusta, e não é um erro do Python: é o computador a guardar 0{,}1 em base dois, onde essa dízima é infinita, exactamente como \frac{1}{3} é infinita em base dez. Todos os computadores fazem isto.

Duas famílias de números

Um número sem ponto decimal é um inteiro (int); com ponto é um decimal (float). O separador decimal em Python é o ponto, não a vírgula: escreve-se 2.5. Uma vírgula ali significa outra coisa — separa valores —, e print(2,5) escreve 2 5, não 2,5.

O erro típico: comparar decimais com ==. 3 * 0.1 == 0.3falso, pela razão acima. Quando é preciso comparar decimais, compara-se a diferença: abs(a - b) < 1e-9.

Texto: cadeias, aspas e juntar com números

Texto, em programação, chama-se cadeia (em inglês, string) e escreve-se entre aspas. Tanto faz "assim" como 'assim', desde que a aspa que abre seja igual à que fecha.

nome = "Ana"
print("Bom dia, " + nome + "!")
print("Bom dia,", nome)

No ecrã:

Bom dia, Ana!
Bom dia, Ana

Há duas maneiras de juntar. Com + as cadeias colam-se, sem espaço nenhum pelo meio — repara que o espaço a seguir à vírgula está escrito dentro das aspas. Com a vírgula do print, o Python põe um espaço sozinho. Para escrever uma frase certinha, o + dá mais controlo; para despachar, a vírgula chega.

O erro típico: somar texto com número. "idade: " + 17 pára com TypeError: can only concatenate str to str — o + entre texto e número não sabe o que fazer. Ou se usa a vírgula do print, que aceita tudo, ou se converte o número em texto com str(17).

T2

As contas que a escola não escreve assim

Duas operações que em Python têm símbolo próprio e na aula não têm: a divisão que só quer a parte inteira, e a potência.

Divisão inteira e resto · // e %

Há perguntas em que a parte decimal não serve para nada. «Com 17 alunos e mesas de 4, quantas mesas ficam cheias?» — a resposta é 4, não 4,25. Para isso existem duas operações:

  • // é a divisão inteira: deita fora a parte decimal;
  • % é o resto dessa divisão.
alunos = 17
print(alunos // 4)
print(alunos % 4)
print(573 // 2 + 1)

No ecrã:

4
1
287

Quatro mesas cheias e um aluno de fora. A terceira linha é o programa da maioria absoluta que está na Cidadania: metade de 573 é 286,5, e o mínimo para ter mais de metade é 287. Com / em vez de // a conta daria 287.5, que não é um número de votos.

Onde o resto é a ferramenta certa

O % responde a «é múltiplo de?» — n % 2 == 0 é a maneira de perguntar se n é par — e a «em que posição de um ciclo estou?». O programa das potências de i, nos Números Complexos, usa n % 4 exactamente por isso: as potências repetem-se de quatro em quatro.

O erro típico: confundir % com percentagem. Em Python o % entre dois números é o resto. Vinte por cento de 50 escreve-se 0.20 * 50.

Potências e raízes · **

Elevar a uma potência faz-se com dois asteriscos. Não há símbolo de raiz — mas não faz falta, porque a raiz quadrada é a potência de expoente \frac{1}{2}.

print(2 ** 10)
print(9 ** 0.5)
print(1.03 ** 40)
print(8 ** (1/3))

No ecrã:

1024
3.0
3.2620377918235
2.0

A terceira linha é a conta dos juros compostos da Cidadania: mil euros a 3% ao ano, ao fim de quarenta anos, multiplicam-se por 3,26. A quarta é a raiz cúbica de 8 — repara nos parênteses à volta de 1/3: sem eles, 8 ** 1/3 lê-se «8 elevado a 1, a dividir por 3», que dá 2,666… O ** tem precedência sobre o /.

O erro típico: escrever 2^10. O ^ existe em Python mas faz outra coisa completamente diferente (uma operação bit a bit), e 2^108 sem dar erro nenhum. É o pior tipo de engano: o programa corre e a resposta está errada.

T3

Perguntar a quem está a usar

Um programa que só sabe fazer uma conta com números fixos serve para pouco. Com duas linhas passa a servir para todos os casos.

Ler o que o utilizador escreve · input()

O input pára o programa, mostra uma pergunta, e espera que se escreva alguma coisa e se carregue em Enter. O que foi escrito fica guardado onde se mandar.

nome = input("Como te chamas? ")
print("Ola,", nome)

Repara no espaço antes das aspas que fecham a pergunta: sem ele, o que se escreve fica colado aos dois pontos. É um pormenor, mas é a diferença entre parecer feito e parecer inacabado.

O que o input devolve é sempre texto

Mesmo que se escreva 25, o que fica guardado é a cadeia "25" e não o número 25. É a fonte do erro mais comum de todos, e o assunto seguinte trata dela.

De texto para número · int() e float()

Como o input devolve texto, uma conta feita logo a seguir corre mal. Vê o que acontece:

a = input("Um número: ")
print(a + 1)

No ecrã (escrevendo 5):

TypeError: can only concatenate str (not "int") to str

O Python queixa-se de que não sabe somar texto com número. A solução é converter: int() transforma em inteiro, float() transforma em decimal.

a = int(input("Um número inteiro: "))
b = float(input("Um número com casas decimais: "))
print(a + 1)
print(b * 2)

A escrita int(input(...)) lê-se de dentro para fora: primeiro corre o input, e o que ele devolver é entregue ao int. É a forma que aparece em quase todos os programas do livro que fazem perguntas.

O erro típico: usar int() onde o número tem casas decimais. Se o utilizador escrever 2.5, o int("2.5") pára com ValueError — o int não arredonda texto, recusa-o. Para preços, medidas e taxas usa-se float; o int fica para contagens.

T4

Decidir

Até aqui o programa fazia sempre o mesmo. A partir daqui pode fazer uma coisa ou outra, conforme os valores.

Comparar · ==, !=, <, >

Comparar duas coisas dá sempre uma de duas respostas: True (verdadeiro) ou False (falso). São os seis símbolos do costume, com duas diferenças de escrita:

em Pythonquer dizer
==é igual a
!=é diferente de
<  >menor, maior
<=  >=menor ou igual, maior ou igual
print(3 > 2)
print(3 == 2)
print(3 != 2)
idade = 17
print(idade >= 18)

No ecrã:

True
False
True
False

O erro típico, e o mais comum de todos: escrever = onde se queria ==. Um sinal é guardar, dois é comparar. if x = 5: dá erro de sintaxe — o que, neste caso, é uma sorte, porque o erro aparece logo.

Decidir · if

O if corre um pedaço de programa só se uma condição for verdadeira. Escreve-se if, a condição, dois pontos — e o que fica dependente vai indentado, quatro espaços para dentro.

nota = 14
if nota >= 10:
    print("Aprovado")
print("Fim")

No ecrã:

Aprovado
Fim

Muda o 14 para 8 e corre outra vez: desaparece o Aprovado e fica só o Fim. A razão está na indentação — o print("Aprovado") está para dentro, e por isso pertence ao if; o print("Fim") está encostado à margem, e por isso corre sempre.

A indentação não é enfeite

Na maior parte das linguagens, os espaços à esquerda servem só para o programa se ler melhor. Em Python decidem o que pertence a quê, e por isso não são negociáveis. A regra prática: quatro espaços por cada nível, sempre espaços e não tabulações, e todas as linhas do mesmo bloco alinhadas exactamente.

O erro típico: esquecer os dois pontos no fim da linha do if. O Python pára com SyntaxError: expected ':'. Acontece a toda a gente, e a mensagem diz mesmo o que falta.

Os outros caminhos · elif e else

O else é «e se não for». O elif é «senão, se» — serve para encadear vários casos sem encaixar uns dentro dos outros.

nota = 8
if nota >= 18:
    print("Muito bom")
elif nota >= 14:
    print("Bom")
elif nota >= 10:
    print("Suficiente")
else:
    print("Insuficiente")

No ecrã: aparece Insuficiente, e mais nada.

O Python testa de cima para baixo e pára no primeiro que for verdadeiro. É por isso que não é preciso escrever elif nota >= 14 and nota < 18: se a linha do 18 falhou, já se sabe que a nota é menor do que 18. E é também por isso que a ordem conta — com o nota >= 10 em primeiro lugar, uma nota de 19 dava «Suficiente».

O erro típico: usar vários if seguidos em vez de elif. Com if repetido, o Python testa todos, e uma nota de 19 escreveria as três primeiras mensagens.

Juntar condições · and, or, not

Quando uma decisão depende de duas coisas ao mesmo tempo, juntam-se as condições com palavras em vez de símbolos:

  • and — verdadeiro só se as duas forem verdadeiras;
  • or — verdadeiro se pelo menos uma for;
  • not — troca verdadeiro por falso.
x = 3
y = -2
if x > 0 and y > 0:
    print("1.º quadrante")
elif x < 0 and y > 0:
    print("2.º quadrante")
elif x < 0 and y < 0:
    print("3.º quadrante")
elif x > 0 and y < 0:
    print("4.º quadrante")

No ecrã: 4.º quadrante. É o programa dos Números Complexos que descobre onde fica o afixo.

Um atalho que Python tem e a matemática também

Para dizer «x está entre 0 e 10» pode escrever-se 0 < x and x < 10, mas o Python aceita a forma da matemática: 0 < x < 10. Poucas linguagens deixam.

O erro típico: escrever if x == 1 or 2: a pensar «se x for 1 ou 2». O Python lê isso como «(x == 1) ou (2)», e um 2 sozinho conta como verdadeiro — a condição fica sempre verdadeira. A forma certa é if x == 1 or x == 2:.

T5

Repetir

A razão pela qual vale a pena mandar um computador fazer contas: ele repete dez mil vezes sem se queixar e sem se enganar.

Repetir um número de vezes · for e range()

O for repete um bloco uma vez para cada valor de uma sequência. A sequência mais simples faz-se com range, que conta números.

for i in range(5):
    print(i, i * i)

No ecrã:

0 0
1 1
2 4
3 9
4 16

Duas coisas a reter. A primeira: range(5) conta de 0 a 4 — começa no zero e não inclui o cinco. Parece estranho ao princípio e passa a fazer sentido depressa, porque assim range(n) dá sempre exactamente n valores. A segunda: o i é uma variável que o for vai enchendo sozinho, uma volta de cada vez.

As três formas do range

range(5) → 0, 1, 2, 3, 4.
range(1, 6) → 1, 2, 3, 4, 5 (começa noutro sítio).
range(0, 10, 2) → 0, 2, 4, 6, 8 (de dois em dois).
O último número nunca entra, nas três.

O erro típico: querer contar de 1 a 10 e escrever range(1, 10), que pára no 9. Para incluir o 10 escreve-se range(1, 11). Vale a pena dizer o número em voz alta: «até onze, exclusive».

Repetir até uma condição · while

O for serve quando se sabe quantas voltas são. Quando não se sabe — «até passar dos 5000 euros», «até a diferença ser menor do que um milésimo» — usa-se o while, que repete enquanto uma condição for verdadeira.

capital = 4000
anos = 0
while capital < 5000:
    capital = capital * 1.03
    anos = anos + 1
print("Passou os 5000 ao fim de", anos, "anos:", round(capital, 2))

No ecrã:

Passou os 5000 ao fim de 8 anos: 5067.25

É o exercício do tempo mínimo de capitalização, da Cidadania, resolvido sem logaritmos: em vez de resolver a equação, o programa vai somando anos até lá chegar.

O erro típico, e o único que trava o computador: esquecer de mudar, dentro do ciclo, a variável que está na condição. Se a linha capital = capital * 1.03 faltasse, o capital ficava sempre em 4000, a condição nunca deixava de ser verdadeira, e o programa corria para sempre. Chama-se ciclo infinito. Antes de correr um while, vale a pena olhar para a condição e perguntar: «o que é que, aqui dentro, a vai tornar falsa?»

Sair a meio · break e continue

O break abandona o ciclo imediatamente. O continue salta o resto desta volta e passa à seguinte.

for n in range(2, 100):
    if 100 % n == 0:
        print("O primeiro divisor de 100 acima de 1 é", n)
        break

No ecrã: aparece O primeiro divisor de 100 acima de 1 é 2, e o ciclo pára.

Sem o break, o ciclo continuava a testar até ao 99 e escrevia todos os divisores. Com ele, pára assim que encontra o que procurava — é o padrão de procurar até achar, e é o que a Geometria Sintética usa para varrer mil triângulos à procura de uma excepção.

O erro típico: pôr o break no sítio errado da indentação. Encostado à margem do for em vez de dentro do if, sai sempre na primeira volta — e o programa parece funcionar, porque escreve alguma coisa.

Um ciclo dentro de outro

Um for pode estar dentro de outro. O de dentro corre por inteiro em cada volta do de fora.

for i in range(1, 4):
    for j in range(1, 4):
        print(i, "x", j, "=", i * j)
    print("---")

No ecrã:

1 x 1 = 1
1 x 2 = 2
1 x 3 = 3
---
2 x 1 = 2
... e assim por diante

Repara na linha do ---: está indentada ao nível do for de dentro, não do print, e por isso corre uma vez por cada volta do ciclo de fora. Mover essa linha quatro espaços muda o programa por completo. É o momento em que a indentação deixa de ser arrumação e passa a ser a lógica.

O erro típico: usar o mesmo nome nos dois ciclos. Com for i dentro de for i, o de dentro estraga o contador do de fora e o resultado não faz sentido nenhum. Nomes diferentes, sempre.

T6

Guardar muitos valores

Uma variável guarda um valor. Para guardar as notas de uma turma ou os votos de todas as listas é preciso outra coisa.

Listas: guardar muitos valores

Uma lista é uma sequência de valores, entre parênteses rectos, separados por vírgulas. Podem ser números, texto, ou uma mistura.

votos = [17220, 16125, 15458]
print(votos)
votos.append(834)
print(votos)
print(len(votos))

No ecrã:

[17220, 16125, 15458]
[17220, 16125, 15458, 834]
4

O .append(...) acrescenta um valor ao fim. Repara na escrita: o nome da lista, um ponto, e a operação. Chama-se um método — é uma função que pertence àquele objecto. O len(...), ao contrário, escreve-se à frente e diz quantos elementos há.

Começar do vazio

O padrão mais usado do livro é começar com uma lista vazia e ir enchendo dentro de um ciclo:

quadrados = []
for n in range(1, 6):
    quadrados.append(n * n)
print(quadrados)

No ecrã: [1, 4, 9, 16, 25]

O erro típico: escrever votos = votos.append(834). O append muda a lista e não devolve nada, por isso o votos fica a valer None e tudo o que vem a seguir rebenta. Escreve-se só votos.append(834).

Índices e fatias · lista[0], lista[1:3]

Cada posição de uma lista tem um número, e a contagem começa no zero.

nomes = ["Ana", "Bruno", "Carla", "Diogo"]
print(nomes[0])
print(nomes[2])
print(nomes[-1])
print(nomes[1:3])

No ecrã:

Ana
Carla
Diogo
['Bruno', 'Carla']

O [-1] é o último — e [-2] o penúltimo, o que poupa a conta de saber o comprimento. O [1:3] é uma fatia: do 1 até ao 3, sem o 3, exactamente como no range. A mesma regra em toda a linguagem.

O erro típico: nomes[4] numa lista de quatro elementos. As posições vão de 0 a 3, e o Python pára com IndexError: list index out of range. Numa lista de n elementos, o último índice é sempre n - 1.

Percorrer uma lista · for x in lista

Para passar por todos os valores de uma lista não é preciso contar posições: o for percorre-a directamente.

votos = [17220, 16125, 15458]
total = 0
for v in votos:
    total = total + v
print("Total:", total)

No ecrã: Total: 48803

Em cada volta, o v passa a valer o elemento seguinte. Compara com a alternativa, que também funciona mas se lê muito pior: for i in range(len(votos)): e depois votos[i]. Quando só se querem os valores, a primeira forma é a certa; a segunda fica para quando a posição faz falta.

O erro típico: acrescentar ou apagar elementos da lista enquanto se está a percorrê-la. O ciclo perde-se, e o Python não avisa. Se for preciso, constrói-se uma lista nova.

As funções que já lá estão · len, sum, max

Algumas contas são tão frequentes que já vêm feitas. Não é preciso importar nada.

notas = [12, 15, 9, 18, 14]
print(len(notas))
print(sum(notas))
print(sum(notas) / len(notas))
print(max(notas), min(notas))
print(sorted(notas))
print(round(3.14159, 2), abs(-7))

No ecrã:

5
68
13.6
18 9
[9, 12, 14, 15, 18]
3.14 7

A terceira linha é a média, e é assim que se escreve. O sorted devolve uma lista nova ordenada e deixa a original em paz; para ordenar de maior para menor usa-se sorted(notas, reverse=True), que é o que o programa do método de Hondt faz com os quocientes.

O erro típico: confundir sorted(lista) com lista.sort(). O primeiro devolve uma lista nova; o segundo ordena a que lá está e não devolve nada. x = notas.sort() deixa o x a valer None.

Dicionários: uma chave para cada valor

Numa lista, os valores encontram-se pela posição. Num dicionário, encontram-se por um nome — a chave. Escreve-se entre chavetas, com chave: valor.

votos = {"Chega": 17220, "PS": 16125, "AD": 15458}
print(votos["PS"])
votos["BE"] = 1500
for lista in votos:
    print(lista, "->", votos[lista])

No ecrã:

16125
Chega -> 17220
PS -> 16125
AD -> 15458
BE -> 1500

É a estrutura certa quando os dados têm nome: votos por partido, notas por aluno, preços por artigo. O for sobre um dicionário percorre as chaves; para ter os dois ao mesmo tempo há for k, v in votos.items():.

O erro típico: pedir uma chave que não existe. votos["PSD"] pára com KeyError. Para não arriscar, usa-se votos.get("PSD", 0), que devolve 0 em vez de rebentar.

Devolver mais do que um valor · tuplos

Um tuplo é como uma lista, mas escreve-se com parênteses curvos e não se pode mudar depois de feito. Serve para agrupar coisas que andam juntas — um ponto, um par de coordenadas, dois resultados de uma conta.

P = (3, -2)
print(P[0], P[1])

x, y = P
print("x =", x, " y =", y)

No ecrã:

3 -2
x = 3  y = -2

A linha x, y = P chama-se desempacotamento, e é uma das escritas mais úteis da linguagem: reparte de uma vez os valores de um tuplo por várias variáveis. É assim que uma função devolve dois resultados — rho, theta = cmath.polar(z), nos Números Complexos, arruma o módulo e o argumento em duas variáveis numa linha só.

Serve também para trocar dois valores sem variável auxiliar:

a, b = 1, 2
a, b = b, a
print(a, b)

No ecrã: 2 1

O erro típico: tentar mudar um tuplo. P[0] = 5 pára com TypeError: 'tuple' object does not support item assignment. Se for preciso mudar, usa-se uma lista.

T7

Dar nome ao que se faz

Quando o mesmo pedaço de programa aparece três vezes, é altura de lhe dar um nome.

Escrever a própria função · def e return

Uma função é um pedaço de programa com nome, que recebe valores e devolve um resultado. Define-se com def e devolve-se com return.

def area_triangulo(base, altura):
    return base * altura / 2

print(area_triangulo(6, 4))
print(area_triangulo(10, 3))

No ecrã:

12.0
15.0

Os nomes entre parênteses na definição — base e altura — chamam-se parâmetros, e são caixas vazias que só se enchem quando alguém chama a função. O return faz duas coisas ao mesmo tempo: devolve o valor e termina a função ali mesmo; o que estivesse escrito por baixo não corria.

Definir não é correr

As linhas do def não fazem nada quando o Python passa por elas — apenas ficam guardadas. Só correm quando a função é chamada, com o nome e parênteses. Por isso a definição tem de vir antes da primeira chamada.

O erro típico: escrever print em vez de return. Uma função que faz print(base * altura / 2) mostra o valor mas não o devolve, e por isso 2 * area_triangulo(6, 4) rebenta. Regra prática: uma função que serve para calcular devolve; quem decide se escreve no ecrã é quem a chamou.

Compreensões de lista · [f(x) for x in …]

Construir uma lista a partir de outra é tão comum que a linguagem tem uma escrita curta para isso. As duas formas seguintes fazem exactamente o mesmo:

quadrados = []
for n in range(1, 6):
    quadrados.append(n * n)
print(quadrados)

quadrados = [n * n for n in range(1, 6)]
print(quadrados)

No ecrã: [1, 4, 9, 16, 25], duas vezes.

Lê-se da direita para a esquerda: «para cada n de 1 a 5, mete n * n». Pode levar uma condição no fim, e aí só entram os que a cumprem:

notas = [12, 15, 9, 18, 14]
positivas = [x for x in notas if x >= 10]
print(positivas)

No ecrã: [12, 15, 18, 14]

O erro típico: escrever compreensões muito longas. Se não cabe confortavelmente numa linha, o ciclo for escrito por extenso lê-se melhor — e ler melhor vale mais do que ser curto.

Duas ajudas para percorrer · enumerate e zip

Duas ferramentas para percorrer listas em casos que aparecem a toda a hora.

O enumeratea posição e o valor ao mesmo tempo — para quando faz falta saber em que número se vai:

nomes = ["Ana", "Bruno", "Carla"]
for i, nome in enumerate(nomes):
    print(i, nome)

No ecrã:

0 Ana
1 Bruno
2 Carla

O zip percorre duas listas ao mesmo tempo, elemento a elemento:

listas = ["Chega", "PS", "AD"]
votos = [17220, 16125, 15458]
for nome, v in zip(listas, votos):
    print(nome, v)

No ecrã:

Chega 17220
PS 16125
AD 15458

O erro típico: dar ao zip listas de tamanhos diferentes. Ele não se queixa — pára na mais curta e o resto perde-se em silêncio. Se os tamanhos deviam ser iguais, vale a pena confirmá-lo antes.

Funções sem nome · lambda

Um lambda é uma função de uma linha, escrita no sítio onde é precisa e sem lhe dar nome. Estas duas definições são equivalentes:

def dobro(x):
    return 2 * x

dobro = lambda x: 2 * x
print(dobro(5))

No ecrã: 10

Escrito assim não ganha nada — se a função vai ter nome, o def lê-se melhor. O lambda ganha quando se quer entregar uma função a outra função, e o caso mais comum é dizer ao max ou ao sorted por que critério devem comparar:

pontos = {"A": 220, "B": 325, "C": 265}
print(max(pontos, key=lambda o: pontos[o]))

No ecrã: B — a opção com mais pontos de Borda. Sem o key, o max compararia as letras e responderia C.

O erro típico: pôr um return dentro do lambda. Não leva: o resultado é a própria expressão. lambda x: return 2 * x é erro de sintaxe.

T8

Ferramentas que vêm de fora

O Python traz consigo bibliotecas prontas. Para as usar é preciso pedi-las — e é só isso.

Arredondar e alinhar o que se escreve

Um resultado de 1165.7999999999997 está certo e lê-se mal. Há duas maneiras de o arrumar.

A primeira é o round, que arredonda o número:

liquido = 1450 * 0.804
print(liquido)
print(round(liquido, 2))

No ecrã:

1165.8000000000002
1165.8

A segunda são as f-strings: um f antes das aspas deixa meter contas dentro do texto, entre chavetas, e dizer quantas casas se querem com :.2f.

nome = "Ana"
liquido = 1165.8
print(f"{nome} recebe {liquido:.2f} euros")
print(f"{liquido:10.2f}|")

No ecrã:

Ana recebe 1165.80 euros
   1165.80|

Repara na diferença entre as duas: o round1165.8, com uma casa, porque o zero final não é um algarismo significativo para um número. O :.2f1165.80, com duas, porque aí já é texto — e é isso que se quer num valor em euros. O 10 antes do ponto reserva dez espaços, o que serve para alinhar colunas.

O erro típico: esquecer o f antes das aspas. print("{nome} recebe") escreve mesmo {nome} recebe, com as chavetas e tudo, sem dar erro.

Trazer ferramentas de fora · import

Nem tudo vem carregado à partida — seria pesado de mais. As ferramentas extra estão arrumadas em bibliotecas, e pedem-se com import, normalmente na primeira linha do programa.

Há duas escritas, e a diferença é só de comodidade:

import math
print(math.sqrt(16))
print(math.pi)

from math import sqrt, pi
print(sqrt(16))
print(pi)

No ecrã: 4.0, 3.141592653589793, e outra vez o mesmo.

Com import math traz-se a biblioteca inteira e escreve-se sempre math. à frente. Com from math import sqrt traz-se só o que se nomeia, e escreve-se sem prefixo. A primeira é mais clara — vê-se de onde veio cada coisa; a segunda é mais curta. O livro usa as duas.

O erro típico: usar sqrt(16) depois de import math. Dá NameError — com essa forma, o nome é math.sqrt. A mensagem de erro é clara, mas custa a ver na primeira vez.

A biblioteca math · raízes, logaritmos, π

É a biblioteca das funções matemáticas. As que aparecem no livro:

escreve-seé
math.sqrt(x)raiz quadrada
math.log(x)logaritmo natural; math.log(x, 10) é o de base 10
math.exp(x)a exponencial e^x
math.sin, cos, tantrigonometria, em radianos
math.radians(g), math.degrees(r)converter graus ↔ radianos
math.pi, math.eas duas constantes
math.factorial(n)o factorial n!
math.floor(x), math.ceil(x)arredondar para baixo e para cima
import math
print(math.sqrt(2))
print(math.sin(math.pi / 2))
print(math.sin(math.radians(90)))

No ecrã:

1.4142135623730951
1.0
1.0

O erro típico, e custa a apanhar: dar graus às funções trigonométricas. math.sin(90) não dá 1 — dá 0.8939…, porque 90 radianos é outro ângulo. O programa corre, não dá erro, e a resposta está errada. Ou se converte com math.radians, ou se trabalha em radianos de princípio ao fim.

Sortear · a biblioteca random

Serve para simular o acaso — lançar um dado dez mil vezes, tirar uma amostra, ver uma frequência relativa a estabilizar.

import random
print(random.randint(1, 6))
print(random.random())
print(random.choice(["cara", "coroa"]))

randint(1, 6) dá um inteiro entre 1 e 6 — e aqui, ao contrário do range, o 6 entra. O random() dá um decimal entre 0 e 1. O choice tira um elemento de uma lista.

import random
saidas = 0
for i in range(10000):
    if random.randint(1, 6) == 6:
        saidas = saidas + 1
print("Frequência relativa do 6:", saidas / 10000)

No ecrã: um número perto de 0.1667, diferente em cada corrida. É o programa das Probabilidades que mostra a frequência a aproximar-se de \frac{1}{6}.

O que confunde: correr duas vezes e obter resultados diferentes não é um erro — é o objectivo. Se, para testar, se quiser sempre o mesmo, põe-se random.seed(42) no princípio.

Números complexos · complex e cmath

O Python trabalha com números complexos sem ser preciso instalar nada. A unidade imaginária escreve-se j e não i — é a convenção da engenharia electrotécnica —, e cola-se ao número: 3j, não 3 * j.

z = 2 - 3j
print(z)
print(z.real, z.imag)
print(z.conjugate())
print(abs(z))

No ecrã:

(2-3j)
2.0 -3.0
(2+3j)
3.605551275463989

O abs de um complexo é o módulo. Para a forma trigonométrica há a biblioteca cmath, que é a math dos complexos:

import cmath
z = complex(-3 ** 0.5, -1)
rho, theta = cmath.polar(z)
print(rho, theta)
print(cmath.rect(rho, theta))

O polar devolve dois valores de uma vez — módulo e argumento —, e o desempacotamento da T6 arruma-os em duas variáveis. O rect faz o caminho contrário.

O erro típico: escrever 2 - 3i. Em Python é j, e sem espaço nem sinal de multiplicação. E atenção: sqrt(-1) da math dá erro; a dos complexos é cmath.sqrt(-1), que dá 1j.

Quando corre mal · try e except

Algumas contas falham por razões previsíveis: dividir por zero, tirar o logaritmo de um número negativo, converter em número um texto que não é um número. Em vez de deixar o programa abaixo, pode-se apanhar a falha.

for x in [2, 0, -1]:
    try:
        print(x, "->", 10 / x)
    except ZeroDivisionError:
        print(x, "-> não se divide por zero")

No ecrã:

2 -> 5.0
0 -> não se divide por zero
-1 -> -10.0

O que está no try corre normalmente; se falhar com o erro nomeado no except, corre esse bloco em vez de parar tudo. Repara em que o ciclo continua — sem o try, o programa morria no zero e nunca chegava ao -1.

O erro típico: escrever except: sozinho, que apanha tudo — incluindo enganos de escrita no próprio programa, que passam despercebidos. Nomeia-se sempre o erro que se está à espera: ZeroDivisionError, ValueError, KeyError.

Consola de Python

corre no navegadorprograma inserido no editor — carrega em Run Code

Como usar

  1. Num bloco de código desta página, carrega em ▶ Correr no compilador — a consola abre-se com o programa já escrito.
  2. Carrega em Run Code e lê a saída.
  3. Muda os valores e volta a correr — é assim que se explora.
já vem carregado
from math import * · log, exp, e
numpy · malhas e vetores
sympy · contas exatas
matplotlib · gráficos

Corre tudo dentro do teu navegador: nada sai do computador, e funciona sem ligação à Internet.

A máquina confirma resultados; nos itens de construção o exame exige a resolução analítica justificada.