Introdução à programação e aos algoritmos

João Araujo Ribeiro · Capítulo 58 de 103

Páginas do PDF

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