Introdução à programação e aos algoritmos
4.7 Tente Outra Vez
Até mesmo nesses casos, pense se a constante global é realmente necessária ou
se poderia ser declarada como variável local dentro de uma função.
Porém, que atento: Python não fornece suporte a constantes. Crie apenas a
variável e não a altere. O uso dos caracteres maiúsculos serve para car evidente que
esta variável não deve ser modi cada.
Como toda variável declarada fora de funções é global, uma
solução para não ter nenhuma variável global é declarar tudo que iria na parte principal como uma função e chamá-la logo no início da execução do programa. Por exemplo, o Programa 4.16 poderia ficar sem variáveis globais com uma pequena modificação.
O nome da função que vai conter tudo que iria no fluxo principal
pode ser o que você quiser. A escolha do nome main() ajuda, pois é um nome usado normalmente por várias linguagens como a primeira função a ser executada.
25 def main():
26 num = int(input(‘Quantos pontos devem ser sor
teados? ‘))
27 pi, erro = calcula_pi(num)
28 print(‘Com’, num, ‘pontos, o valor de pi é’,
pi, ‘com erro’, erro)
29
30 main()
■ Programa 4.23: Programa que calcula pi sem variável global.
EXERCÍCIO 4.15
Identi que as variáveis globais e locais do Programa 4.16.
4.7 TENTE OUTRA VEZ
O Programa 4.23 tem ainda um pequeno problema. Veja esta execução:
Quantos pontos devem ser sorteados? 12.3 Traceback (most recent call last):
File “calcula_pi.py”, line 25, in <module>
num = int(input(‘Quantos pontos devem ser sortea
dos? ‘))
ValueError: invalid literal for int() with base 10: ‘12.3’
O que acontece é que se o usuário não digitar um número inteiro, o programa vai terminar com uma mensagem de erro. A mensagem diz exatamente em que linha ocorreu o erro e qual foi esse erro.
No caso, o erro está na última linha: ValueError, que significa que a função int() recebeu um argumento literal inválido. Esperava uma string que pudesse ser convertida para um número inteiro, porém recebeu uma string com um número em ponto flutuante. O mesmo aconteceria se você digitasse letras em vez de números.
Como resolver isso?
Seria possível não entregar diretamente o que foi lido por input() a int(), fazer testes antes de passar o parâmetro. Mas Python tem uma solução melhor e mais geral.
Veja o Programa 4.24.
25 def main():
26 while True:
27 try:
28 num = int(
29 input(
30 ‘Quantos pontos devem ser sor teados? ‘))
31 break
32 except ValueError:
33 print(‘Erro: Somente números são acei tos.’)
34 pi, erro = calcula_pi(num)
35 print(‘Com’, num, ‘pontos, o valor de pi é’,
pi,
36 ‘com erro’, erro)
37
38 main()
■ Programa 4.24: Programa que calcula pi com teste de
entrada de dados.
O trecho do programa que lê a entrada de dados ficou mais
longo, porém, agora assegura que os dados estarão corretos. A parte relevante está entre as linhas 26 e 33.
A ideia é a seguinte: começamos com um laço sem fim. A
expressão while True: determina um laço sem condição de fim, pois True sempre será verdade. Em seguida temos o conjunto try ... except.... O que estiver dentro do bloco do try vai ser tentado. Se este trecho de código gerar uma “exceção”, assim que for gerada, o bloco do except será executado. No caso da linha 29 gerar a exceção, a linha 31 não será executada e o fluxo passa imediatamente para a linha 32.
Se a leitura do valor for correta, o comando break “quebra” o
laço while, isto é, o laço while, que era infinito, vai ser interrompido e o fluxo do programa continua na linha seguinte ao bloco do while. Desse modo, se a leitura do inteiro for correta, o programa continua executando e ignora o bloco do except.
A estratégia do bloco try...except é deixar o erro acontecer e
depois tratá-lo. No Programa 4.24, enquanto o usuário não digitar um número inteiro, ele vai continuar pedindo um número.
Podemos dizer que Python tem dois tipos de erros: os de
sintaxe, que aparecem porque escrevemos algum código em desacordo com a sintaxe da linguagem, e os erros de execução, aqueles que são provocados por uma condição que surge causada por alguma situação não prevista pelo código. Esses erros são chamados de exceções. Nesse caso, o programa não previa que o usuário pudesse digitar algo diferente de um número inteiro.
Quando ocorre uma exceção, Python emite uma mensagem de erro, mas você pode “capturar” a exceção. Capturar uma exceção, no jargão da Computação, quer dizer tratar um erro em tempo de execução. Python informa o tipo de erro que ocorreu e é possível fazer algo para corrigi-lo, no caso, pedir novamente ao usuário para digitar um número inteiro, ou fechar o programa de forma elegante. Não é nada agradável executar um programa e vê-lo terminar abruptamente com uma mensagem enigmática.
Python gera vários tipos de exceções além da ValueError. Alguns exemplos são:
ZeroDivisionError uma tentativa de divisão por zero.
IOError quando há erro na tentativa de ler um arquivo.
KeyboardInterrupt quando o usuário interrompe o programa (digitando control-c, por exemplo).
Há muitas outras exceções. Vale a pena ler o manual de Python para saber que tipo de exceção pode ser gerada.
Por exemplo, para capturar a exceção de divisão por zero, podemos fazer:
1 def divide(x, y):
2 “””Divide x por y.”””
3 try:
4 z = x / y
5 print(z)
6 except ZeroDivisionError:
7 print(‘Tentativa de divisão por zero’) 8
9 divide(1, 2)
10 divide(1, 0)
■ Programa 4.25: Capturando exceção de divisão por zero.
Quando executado, o Programa 4.25 produz:
0.5
Tentativa de divisão por zero
Lembre-se de informar a respeito de qual exceção está se
tratando, por isso é importante consultar a documentação de Python para saber quais são as possibilidades. Você também pode capturar diversas exceções.
1 def divide():
2 “””Divide x por y.”””
3 try:
4 x = int(input(‘Digite um numerador:’’))
5 y = int(input(‘Digite um denominador:’))
6 print(‘A divisão de’, x, ‘por’, y, ‘é igu
al a’, x/y)
7 except ZeroDivisionError:
8 print(‘Tentativa de divisão por zero.’)
9 except ValueError:
10 print(‘Número inválido.’)
11
12 divide()
■ Programa 4.26: Capturando duas exceções.
Se você não colocar o tipo de exceção, o programa vai pegar
todas as exceções, mas isto não é recomendado. Imagine que você peça um número ao usuário que termina a execução do programa digitando CONTROL-C. Esse erro é previsto, mas você pensou que o único erro seria um número inválido. Apesar de ter sido interrompido por um comando do usuário, a mensagem de erro seria de número inválido, o que está longe da realidade.
A sintaxe do comando try permite ainda outras opções, como
else e finally, mas o que foi apresentado aqui resolve a maioria das situações práticas.
EXERCÍCIO 4.16