Primeiros programas
Algoritmos, valores, tipos, atribuição, operadores, entrada e saída em Python.
Instruções e valores
Em print("Olá"), o texto entre aspas é uma string e print mostra-o no ecrã:
print("Olá")
A saída é Olá; o programa executa uma instrução que só apresenta texto. O exemplo seguinte converte uma duração: recebe um número inteiro de segundos e calcula horas, minutos e segundos, pelo que a entrada 3661 deve produzir 1 1 1.
Decompor o problema
Um algoritmo descreve passos precisos para resolver uma classe de problemas. Uma hora tem 3600 segundos, por isso em 3661 cabe uma hora completa e sobram 61 segundos. Nesse resto cabe um minuto completo e sobra um segundo. A mesma divisão com resto funciona para qualquer duração inteira não negativa, incluindo zero.
Decompor é separar o problema em partes, e aqui cada contagem usa a mesma divisão com resto; abstrair é conservar só os dados que interessam ao cálculo, por isso para converter a duração não precisas de saber quem a mediu.
Valores, tipos e variáveis
Uma expressão calcula um valor. 3661 // 3600 calcula o número de horas completas. Os dois operandos são inteiros, do tipo int; o resultado também é inteiro. O tipo determina as operações que um valor suporta.
| Tipo | Valores | Operação típica |
|---|---|---|
int | 0, 12, -3 | Contar unidades inteiras |
float | 2.5, -0.25 | Calcular uma aproximação numérica |
str | "FEUP", "12" | Manipular texto |
bool | True, False | Representar uma condição |
12 e "12" têm tipos diferentes. 12 + 3 vale 15; "12" + "3" vale "123", porque + concatena texto. type(valor) permite inspecionar o tipo. None representa a ausência de um resultado útil; não é o número zero nem a string vazia.
A atribuição total = 3661 associa o nome total ao objeto inteiro 3661. Python calcula primeiro o lado direito e só depois altera a associação do lado esquerdo. Em total = total + 1, lê o valor antigo, soma 1 e guarda 3662, o que não é uma equação matemática, pois = atribui enquanto == compara.
Os nomes distinguem maiúsculas de minúsculas. total e Total são nomes diferentes. True, False e None têm maiúscula inicial. true pode ser um nome, mas lê-lo sem definição causa NameError.
Operadores e precedência
| Expressão | Resultado | Significado |
|---|---|---|
7 / 2 | 3.5 | Divisão |
7 // 2 | 3 | Quociente arredondado para baixo |
7 % 2 | 1 | Resto |
2 ** 3 | 8 | Potência |
"FP" * 2 | "FPFP" | Repetição de texto |
Para inteiros e divisor não nulo, a == (a // b) * b + a % b. Com negativos, arredondar para baixo não é cortar as casas decimais: -7 // 2 vale -4 e -7 % 2 vale 1.
A potência precede multiplicação e divisão, que precedem adição e subtração. Usa parênteses para exprimir a intenção: (2 + 3) * 4 vale 20, enquanto 2 + 3 * 4 vale 14.
Ver pormenores de potência e negativos
Há pormenores que a regra escolar não cobre: -2 ** 2 vale -4, mas (-2) ** 2 vale 4; 2 ** 3 ** 2 vale 512, porque a potência associa à direita.
Números float são aproximações binárias, por isso 0.1 + 0.2 produz 0.30000000000000004 e 0.1 + 0.2 == 0.3 dá False: estas frações decimais não têm representação binária finita.
Para resultados de medição, decide a tolerância ou o arredondamento pedido. Mostrar o resultado com duas casas decimais produz 0.30, mas não altera o valor calculado. A lição de ficheiros e testes apresenta math.isclose para comparar aproximações.
Entrada e saída
input() lê uma linha e devolve uma string, sem a mudança de linha final. int(input()) converte essa string num inteiro. float("3.5") usa ponto decimal; float("3,5") falha. Por agora, o programa seguinte assume entrada válida.
Os parênteses fazem uma chamada: pedem a uma função que execute uma operação. Em int(input()), a chamada interior lê primeiro o texto; a exterior converte esse resultado.
Uma instrução por linha permite seguir a ordem do programa de cima para baixo. O texto depois de # é um comentário, que Python ignora.
print(a, b) escreve dois valores separados por um espaço. Uma f-string começa com f antes das aspas e coloca expressões entre chavetas. Se media = 12.5, f"{media:.2f}" produz "12.50", com duas casas decimais. A saída pedida por um exercício faz parte do contrato, por isso não acrescentes mensagens a um programa que só deve escrever números.
Segundos em horas, minutos e segundos
total = int(input())
horas = total // 3600
resto = total % 3600
minutos = resto // 60
segundos = resto % 60
print(horas, minutos, segundos)Executa o código para ver a saída e os gráficos.
O contrato exige segundos inteiros não negativos. As horas podem ultrapassar 23, pois medimos uma duração, não a hora do dia. Os minutos e segundos ficam entre 0 e 59. Com 3661, o programa calcula por passos:
| Passo | Cálculo | Resultado |
|---|---|---|
| Horas completas | 3661 // 3600 | 1 |
| Resto após horas | 3661 % 3600 | 61 |
| Minutos completos | 61 // 60 | 1 |
| Segundos | 61 % 60 | 1 |
A saída é 1 1 1, o que confirmas no sentido inverso com . Para 59, esperas 0 0 59; para 3600, 1 0 0; para 0, 0 0 0. Reserva a comparação global com a entrada para depois de cada passo bater certo num caso pequeno.
Sintaxe, execução e lógica
Três falhas pedem respostas diferentes:
- Um erro de sintaxe impede o interpretador de compreender o programa, como esquecer os dois pontos depois de
if. - Um erro de execução surge ao executar uma operação, como converter
"Ana"comint. - Um erro de lógica produz um resultado diferente do pedido, como usar
/no cálculo de horas completas.
Lê a última linha da mensagem de erro para identificar o tipo, depois a linha indicada. Para um resultado errado, acompanha os valores das variáveis após cada instrução. Escolhe um caso pequeno com resultado conhecido antes de tentar uma entrada grande.
Exercícios
Definir o problema
Um programa converte minutos em dias, horas e minutos. Define o domínio da entrada, os limites dos campos de saída e uma verificação do resultado.
Pista
Mais uma pista
Solução
Confere a tua resposta:
- Indiquei que a entrada é inteira e não negativa.
- Permiti qualquer número inteiro não negativo de dias.
- Defini horas de 0 a 23 e minutos de 0 a 59.
- Reconstruí a entrada com 1440d + 60h + m.
Erros frequentes
Prever uma expressão
Quanto vale -2 ** 2 + 3 * 4?
Pista
Mais uma pista
Solução
Erros frequentes
Quociente com negativos
Quais são os valores de -7 // 2 e -7 % 2, nesta ordem?
Pista
Mais uma pista
Solução
- -4 e -1. Não satisfaz a identidade: 2 × (-4) - 1 = -9.
- -4 e 1. Arredondar -3.5 para baixo dá -4; o resto é 1.
- -3 e -1. Isto corresponderia a truncar para zero, não à divisão // em Python.
Erros frequentes
Converter minutos
Escreve um programa que lê uma linha com minutos inteiros não negativos e escreve dias, horas e minutos, separados por espaços. As horas vão de 0 a 23 e os minutos de 0 a 59. Não precisas de definir funções.
total = int(input())
print(0, 0, 0)Verifica o código para comparar o resultado com os testes.
Testes
Zero
Entrada0
Esperado:0 0 0
Menos de uma hora
Entrada59
Esperado:0 0 59
Uma hora
Entrada60
Esperado:0 1 0
Fim de um dia
Entrada1439
Esperado:0 23 59
Um dia completo
Entrada1440
Esperado:1 0 0
Dias, horas e minutos
Entrada2941
Esperado:2 1 1
0
0 0 0
59
0 0 59
60
0 1 0
1439
0 23 59
1440
1 0 0
2941
2 1 1
Pista
Usa // e % para retirar unidades completas e conservar o resto.
Mais uma pista
Depois de total // 1440, usa total % 1440 para calcular horas e minutos.
Solução
Cada dia retira 1440 minutos. As horas são calculadas sobre o resto, não sobre o total. Para 2941, 2 × 1440 + 1 × 60 + 1 = 2941.
total = int(input())
dias = total // 1440
resto = total % 1440
horas = resto // 60
minutos = resto % 60
print(dias, horas, minutos)Erros frequentes
Usar / para unidades completas, deixar as horas ultrapassar 23 ou acrescentar mensagens à saída.
Diagnosticar o tipo da entrada
Um programa recebe a linha 4 e guarda texto = input(). Prevê o valor e o
tipo de texto * 2. Depois explica por que texto + 2 falha e corrige essa
expressão para somar dois ao número recebido. O que obterias com
int(texto * 2)? Compara com int(texto) * 2.
Solução
input devolve a string "4". Multiplicá-la por 2 repete o texto e produz
"44", do tipo str. Somar uma string a um inteiro causa TypeError;
int(texto) + 2 converte primeiro e produz o inteiro 6.
int(texto * 2) converte o texto já repetido e dá 44. int(texto) * 2
converte o 4 e calcula o dobro, 8. As duas expressões são válidas, mas resolvem
problemas diferentes. Se a linha fosse "quatro", a conversão com int
lançaria ValueError; mudar o tipo exige uma representação numérica válida.
Confere a tua resposta:
- Previ "44" e TypeError nas duas versões.
- Distingui conversão de repetição de texto.
- Corrigi a conversão antes da operação numérica.