E-Book Python Básico
E-Book Python Básico
Formação Inicial e
Continuada
+ IFMG
Campus Bambuí
Marcos Roberto Ribeiro
Python Básico
1ª Edição
Belo Horizonte
Instituto Federal de Minas Gerais
2022
© 2022 by Instituto Federal de Minas Gerais
Todos os direitos autorais reservados. Nenhuma parte desta publicação poderá ser
reproduzida ou transmitida de qualquer modo ou por qualquer outro meio, eletrônico
ou mecânico. Incluindo fotocópia, gravação ou qualquer outro tipo de sistema de
armazenamento e transmissão de informação, sem prévia autorização por escrito do
Instituto Federal de Minas Gerais.
FICHA CATALOGRÁFICA
Dados Internacionais de Catalogação na Publicação (CIP)
R484p Ribeiro, Marcos Roberto.
Python básico [recurso eletrônico] / Marcos Roberto Ribeiro. –
Belo Horizonte : Instituto Federal de Minas Gerais, 2022.
CDD 005.13
2022
Direitos exclusivos cedidos ao
Instituto Federal de Minas Gerais
Avenida Mário Werneck, 2590,
CEP: 30575-180, Buritis, Belo Horizonte – MG,
Telefone: (31) 2513-5157
Sobre o material
Formulário de
Sugestões
Bons estudos!
Marcos Roberto Ribeiro
Apresentação do curso
Este curso está dividido em quatro semanas, cujos objetivos de cada uma são
apresentados, sucintamente, a seguir.
Semana 1 - Introdução....................................................................................15
1.1 Introdução..................................................................................................15
1.1.1 Lógica de programação..........................................................................15
1.1.2 A ferramenta Spyder..............................................................................17
1.2 Tipos de dados..........................................................................................18
1.3 Variáveis....................................................................................................18
1.4 Depuração de código................................................................................19
1.5 Legibilidade...............................................................................................20
1.6 Entrada e saída de dados.........................................................................21
1.7 Operadores................................................................................................21
1.7.1 Operadores aritméticos..........................................................................22
1.7.2 Operadores relacionais..........................................................................23
1.7.3 Operadores lógicos................................................................................24
1.8 Utilizando funções.....................................................................................25
1.8.1 Manipulação de dados textuais..............................................................26
1.8.2 Funções matemáticas............................................................................27
1.9 Exercícios..................................................................................................28
1.10 Respostas dos exercícios........................................................................29
1.11 Revisão....................................................................................................30
Semana 2 - Controle de fluxo..........................................................................33
2.1 Introdução..................................................................................................33
2.2 Estruturas de decisão................................................................................33
2.2.1 Estrutura de decisão simples.................................................................33
2.2.2 Estrutura de decisão composta..............................................................34
2.2.3 Estruturas de decisão aninhadas...........................................................34
2.2.4 Resolvendo problemas com estruturas de decisão................................35
2.2.1 Exercícios...............................................................................................38
2.2.2 Respostas dos exercícios.......................................................................39
2.3 Estruturas de repetição.............................................................................40
2.3.1 Laço de repetição while..........................................................................40
2.3.2 Laço de repetição for..............................................................................40
2.3.3 Interrupção e continuação de laços de repetição...................................41
2.3.4 Resolvendo problemas com estruturas de repetição.............................42
2.3.1 Exercícios...............................................................................................45
2.3.2 Respostas dos exercícios.......................................................................46
2.4 Revisão......................................................................................................48
Semana 3 - Modularização e tratamento de exceções...................................49
3.1 Introdução..................................................................................................49
3.2 Tratamento de exceções...........................................................................49
3.3 Modularização...........................................................................................51
3.3.1 Funções..................................................................................................51
3.3.2 Passagem de parâmetros e retorno de resultado..................................52
3.3.3 Nomes de parâmetros e parâmetros opcionais......................................53
3.3.4 Recursão................................................................................................54
3.3.5 Módulos e bibliotecas.............................................................................54
3.4 Decomposição de problemas....................................................................55
3.5 Exercícios..................................................................................................59
3.6 Respostas dos exercícios..........................................................................60
3.7 Revisão......................................................................................................63
Semana 4 - Coleções de dados......................................................................65
4.1 Introdução..................................................................................................65
4.2 Listas.........................................................................................................66
4.2.1 Resolvendo o problema dos preços acima da média com listas............66
4.2.2 Matrizes..................................................................................................68
4.2.3 Inicialização e seleção de elementos.....................................................70
4.2.4 Implementando o jogo da forca com listas.............................................71
4.3 Tuplas........................................................................................................74
4.4 Conjuntos..................................................................................................75
4.5 Dicionários.................................................................................................79
4.6 Exercícios..................................................................................................84
4.7 Respostas dos exercícios..........................................................................85
4.8 Revisão......................................................................................................88
Finalizando o curso.........................................................................................91
Atividade final..................................................................................................91
Referências.....................................................................................................93
Currículo do autor............................................................................................94
Semana 1 - Introdução
Objetivos
- Conhecer os tipos básicos de dados e funcionamento de
variáveis;
- Desenvolver códigos com entrada e saída de dados;
- Entender o funcionamento de expressões aritméticas,
relacionais, lógicas e suas combinações.
1.1 Introdução
Símbolo Significado
Terminador (início e fim do algoritmo)
N1
N2
M ← (N1 + N2)/2
SIM NÃO
M ≥ 60?
Aprovado Reprovado
Fim
Tipo Descrição
int Números inteiros
float Números fracionários
bool Valores lógicos como True (verdadeiro) ou False (falso)
str Valores textuais
Figura 5 – Tipos básicos de dados em Python
Fonte: Elaborado pelo Autor.
1.3 Variáveis
Para que não ocorram erros no código, o nome de uma variável devem obedecer às
seguintes regras:
• Deve obrigatoriamente começar com uma letra;
• Não deve possuir espaços em branco;
• Não pode conter símbolos especiais, exceto o sublinhado (_);
• Não deve ser uma palavra reservada (uma palavra da já existente na linguagem,
como print, por exemplo).
1.5 Legibilidade
Quando um algoritmo recebe dados do usuário, dizemos que ocorre uma entrada de
dados. De forma análoga, quando o algoritmo exibe mensagens para o usuário, acontece
uma saída de dados. Em Python, a entrada de dados é efetuada com a instrução input().
Dentro dos parênteses colocamos um texto para ser mostrado ao usuário antes da entrada
dos dados. Normalmente, usamos uma variável para receber a resposta digitada. A função
input() sempre retorna um valor textual digitado pelo usuário. Se precisarmos de outro tipo
de dado, temos que realizar uma conversão3.
No caso da saída de dados, temos a instrução print(). Essa instrução recebe as
informações a serem mostradas para o usuário separadas por vírgula. Se usarmos uma
variável, será mostrado o valor dessa variável. Em diversas situações é importante compor
mensagens adequadas para o usuário combinando literais e variáveis. A Figura 9 exibe um
código usando as funções input() e print(). Na linha 5, usamos a instrução int() para
converter texto retornado pelo input() para um número inteiro.
1 print('Bem vindo!')
2 # Nome do usuário
3 nome = input('Informe seu nome: ')
4 # Idade convertida para inteiro
5 idade = int(input('Informe sua idade: '))
6 print() # Escreve uma linha em branco
7 # Escreve mensagem usando as variáveis
8 print('Olá,', nome, 'sua idade é', idade)
9 print('Até mais!')
Figura 9 – Código usando input() e print()
Fonte: Elaborado pelo Autor.
1.7 Operadores
Operador Descrição
+ Adição
- Subtração
* Multiplicação
/ Divisão
// Divisão inteira
% Resto de divisão
** Potenciação
Figura 10 – Operadores aritméticos do Python
Fonte: Elaborado pelo Autor.
1 ni = 10 // 3
2 print('10 // 3 =', ni)
3 ni = 10 % 3
4 print('10 % 3 =', ni)
5 nr = 2.34 * 3.58
6 print('2.34 * 3.58 =', nr)
7 nr = 2.99 / 4.1
8 print('2.99 / 4.1 =', nr)
9 nr = (10.5 - 7.8) * (3.2 + 200.43)
10 print('(10.5 - 7.8) * (3.2 + 200.43) =', nr)
Figura 11 – Código usando operadores aritméticos
Fonte: Elaborado pelo Autor.
Com o conteúdo visto até o momento, podemos fazer um código para simular uma
calculadora simples. A ideia é obter dois números com o usuário e mostrar os resultados
das possíveis operações aritméticas entre esses números. A Figura 12 mostra uma
possível solução.
O operador + pode ser usado também para concatenar variáveis e literais textuais.
No entanto, não é possível concatenar diretamente um elemento textual e um elemento
numérico. Nesse caso, é necessário converter o valor numérico para textual antes da
concatenação. O código da Figura 13 demonstra como isso pode ser feito.
1 print('Informe os dados')
2 nome = input('Nome: ')
3 sobrenome = input('Sobrenome: ')
4 idade = int(input('Idade: '))
5 mensagem = nome + ' ' + sobrenome + ', ' + str(idade)
6 print(mensagem)
Figura 13 – Código para simular calculadora simples
Fonte: Elaborado pelo Autor.
Operador Descrição
== Igual
!= Diferente
< Menor
<= Menor ou igual
> Maior
>= Maior ou igual
Figura 15 – Operadores relacionais
Fonte: Elaborado pelo Autor.
Expressão Resultado
not True False
not False True
Figura 17 – Operador lógico not
Fonte: Elaborado pelo Autor.
Expressão Resultado
True or True True
True or False True
False or True True
False or False False
Figura 19 – Operador lógico or
Fonte: Elaborado pelo Autor.
O Python possui uma biblioteca padrão com funções que podem ser usadas
diretamente no código. Além disso, podemos importar diversas outras bibliotecas que
podem ser utilizadas para as mais variadas tarefas (BORGES, 2010). A Figura 21 exibe
algumas funções da biblioteca padrão. Além da biblioteca padrão, abordaremos funções
relacionadas ao tipo textual e também a biblioteca de funções matemáticas.
Na linguagem Python, o tipo de dado textual (str) possui funções relacionadas que
auxiliam na manipulação de dados desse tipo (DOWNEY, 2015). Por serem funções
associadas ao tipo str, é preciso usá-las com o dado desse tipo. Por exemplo, se tempos
uma variável x do tipo str, podem chamar uma função lower() com a instrução x.lower().
A Figura 23 contém alguns exemplos de funções de manipulação de texto. O código da
Figura 26 demostra a utilização de algumas dessas funções.
Função Funcionamento
s.find(subtexto, ini, fim) Procura subtexto em s, começando
da posição ini até a posição fim.
Retorna −1, se o subtexto não for
encontrado.
s.format(x1 , ..., xn) Retorna s com os parâmetros x1, ...,
xn incorporados e formatados.
s.lower() Retorna o s com todas as letras
minúsculas.
s.replace(antigo, novo, n) Retorna o s substituindo antigo por
novo, nas n primeiras ocorrências.
Figura 22 – Algumas funções associadas ao tipo str
Fonte: Elaborado pelo Autor.
Função Funcionamento
ceil(x) Retorna o teto de x
floor(x) Retorna o piso de x
trunc(x) Retorna a parte inteira de x
exp(x) Retorna ex
log(x, b) Retorna o logaritmo de x em uma base b. Se a base
não for especificada, retorna o logaritmo natural de x
sqrt(x) Retorna a raiz quadrada de x
pi Retorna o valor de π
Figura 24 – Algumas funções da biblioteca math
Fonte: Elaborado pelo Autor.
1 import math
2
3 n = float(input('Informe um número: '))
4 x = n * math.pi
5 print('x = n * pi = ', n)
6 print('Teto de x =', math.ceil(x))
7 print('Piso de x =', math.floor(x))
8 print('Log de x na base 10 =', math.log(x, 10))
9 print('Raiz de x =', math.sqrt(x))
Figura 25 – Código com funções matemáticas
Fonte: Elaborado pelo Autor.
1.9 Exercícios
Objetivos
- Entender o funcionamento do fluxo de execução do código,
das estruturas de decisão e das estruturas de repetição;
- Combinar estruturas de decisão e de repetição para
resolver problemas;
- Desenvolver códigos com estruturas de decisão e de
repetição.
2.1 Introdução
A estrutura de decisão mais simples utiliza uma única instrução if, seguida por uma
expressão lógica e pelo bloco de instruções a ser executado se o valor da expressão lógica for
verdadeiro (CEDER, 2018). Considere, por exemplo, o problema de verificar se um aluno foi
aprovado. Isso é feito testando se a nota do aluno é maior ou igual a 60. A Figura 26 mostra o
código para resolver esse problema.
A endentação deve ser feita corretamente para especificar quais instruções estão dentro da
estrutura condicional. Utilizamos quatro espaços para endentar um bloco de instruções. Observe
que, depois da expressão lógica seguida por dois pontos (:), começa o bloco de instruções do if.
Esse bloco deve ser obrigatoriamente endentado. No código, a mensagem “Aprovado” é escrita na
Observe que, no código da Figura 28, tivemos que endentar mais o if mais interno. Caso
tenhamos muitas estruturas de decisão aninhadas, a legibilidade pode ficar prejudicada. Assim,
outra maneira de usar as estruturas de decisão aninhadas é de forma consecutiva, como mostrado
na Figura 29. A instrução elif funciona como uma junção do else com o if. Essa instrução é
especialmente útil quando temos muitos testes consecutivos a serem feitos.
Como as estruturas de decisão são muito usadas, vamos resolver alguns problemas
utilizando essas estruturas antes de avançarmos para o próximo conteúdo.
Ano bissexto
Como primeiro problema, criaremos um código para verificar se um ano é bissexto ou não.
Um ano é bissexto se é múltiplo de 400, ou então se é múltiplo de quatro, mas não é múltiplo de
100. Por exemplo, 2012 (múltiplo de 4, mas não múltiplo de 100) é bissexto, 1900 (múltiplo de
quatro e de 100) não é bissexto, 2000 (múltiplo de 400 é bissexto). A Figura 30 mostra o código
para resolver esse problema.
Observe que temos um teste que combina expressões relacionais com operadores lógicos
na linha 2. As expressões relacionais são usadas para testar se a variável ano é ou não múltipla de
2.2.1 Exercícios
1 atual = 0
2 n = int(input('Informe um número: '))
3 while atual < n:
4 print(atual)
5 atual += 2
Figura 33 – Listagem de números pares
Fonte: Elaborado pelo Autor.
A estrutura de repetição while possui uma condição que é testada antes mesmo de
executar a primeira repetição. Enquanto essa condição for verdadeira, as repetições continuam
acontecendo. Se o usuário informar zero, por exemplo, não acontece nenhuma repetição. Dentro do
laço, somamos mais dois ao número atual para chegarmos ao próximo número par.
O laço de repetição for é indicado quando se sabe o número de repetições a serem feitas.
Basicamente, o laço for percorre de forma automática os elementos de uma estrutura de lista. A
maneira mais comum de utilizar o laço for é com a função range(). Essa função recebe um número
inteiro n e gera um intervalo de números de 0 até n – 1 (CORRÊA, 2020).
Para exemplificar o uso do laço for, vamos considerar o problema de somar 10 números
informados pelo usuário. A Figura 34 mostra o código para resolver esse problema. Observe que,
no laço, for usamos a função range(10) e a variável cont para percorrer os números do intervalo
gerado pela função range(). Assim, na primeira repetição, a variável cont vale 0, na segunda, vale
1, e assim por diante até assumir o valor 9.
É possível notar, no código para soma dos 10 números, que a única função da variável cont
é controlar as repetições do laço for. Quando temos uma variável que não é usada em nenhuma
outra parte do código, podemos substituir essa variável pela variável anônima _ (sublinhado).
Outro detalhe importante é a função range(). Além do fim do intervalo, podemos definir o
início e a periodicidade dos números. Se usarmos, por exemplo, a instrução range(2, 6), será
retornado o intervalo de números “2, 3, 4, 5”, ou seja, o primeiro número é o início e o segundo
número é o fim do intervalo. Lembrando que o número do fim não é incluído no intervalo. Quando
incluímos um terceiro número, definimos a periodicidade dos números. Como exemplo, se usarmos
a instrução range(3, 19, 4) teremos a sequência “3, 7, 11, 15”. A sequência começa em 3, e os
demais números são obtidos somando 4 ao número atual, até atingir o fim do intervalo. Além disso,
no lugar dos números, podemos usar qualquer variável ou expressão que retorne um número
inteiro. Também podemos obter intervalos em ordem decrescente, por exemplo, a instrução
range(5,0,-1) retorna a sequência “5, 4, 3, 2, 1”.
O laço de repetição while precisa testar a condição de parada antes mesmo da primeira
repetição. Entretanto, em diversos momentos, precisamos executar a primeira repetição antes de
testar a condição de parada. Nesse caso, podemos criar um laço com a instrução while True e
utilizar a instrução break para finalizar o laço de repetição.
Como exemplo, vamos considerar a soma de uma quantidade indeterminada de números
informados pelo usuário. Devemos parar de somar apenas quando o usuário informar o número 0
(zero). A Figura 35 apresenta o código para resolver esse problema. É importante tomar um certo
cuidado com laços while True, temos que garantir que a instrução break será executada em algum
momento e o laço não fique repetido indefinidamente.
1 soma = 0
2 while True:
3 n = float(input('Informe um número: '))
4 if n == 0:
5 break
6 soma = soma + n
7 print('Soma dos números:', soma)
Figura 35 – Soma indefinida de números
Fonte: Elaborado pelo Autor.
Vamos considerar agora uma modificação no problema de somar números. Além do que já
foi mencionado, suponha que os números negativos não devam ser somados. Diante disso,
podemos usar a instrução continue para ignorar os números negativos e pular para a próxima
repetição do laço (CEDER, 2018). O código da Figura 36 mostra a solução para a modificação do
1 soma = 0
2 while True:
3 n = float(input('Informe um número: '))
4 if n < 0:
5 continue
6 if n == 0:
7 break
8 soma = soma + n
9 print('Soma dos números:', soma)
Figura 36 – Soma indefinida de números (exceto negativos)
Fonte: Elaborado pelo Autor.
Combinações de elementos
Agora, vamos considerar o problema de gerar as combinações de dois elementos a partir de
um conjunto de números naturais com n elementos, ou seja, um conjunto A = {1, 2, 3, ..., n}. Antes
de gerar as combinações, o código deve perguntar o número de elementos do conjunto ao usuário.
A Figura 38 mostra o código para resolver o problema descrito.
Após pegar o número de elementos informado pelo usuário (linha 1), escrevemos todos os
elementos do conjunto na tela (linhas 3 a 5). No laço de repetição usamos a instrução range(1, n+1)
para termos a sequência de elemento de 1 até n. Repare também que usamos o parâmetro end= '
', na função print() para evitar a quebra de linha e os elementos ficarem um após o outro.
Nas linhas 7 a 10, escrevemos as combinações dos elementos. Usamos dois laços de
repetição aninhados para que cada elemento seja combinado com os demais (inclusive, com ele
mesmo). O primeiro elemento é a variável cont e o segundo elemento é a variável cont2. A função
print() dentro do laço mais interno escreve cada uma das combinações. Foram usados os
2.3.1 Exercícios
1 while True:
2 print('Calculadora (+, -, /, *)')
3 print('s: sair')
4 resp = input('Informe a operação desejada (s para sair): ')
5 if resp == 's':
6 break
7 print('Informe dois números:')
8 n1 = float(input('N1: '))
9 n2 = float(input('N1: '))
10 if resp == '+':
11 r = n1 + n2
12 elif resp == '-':
13 r = n1 - n2
14 elif resp == '*':
15 r = n1 * n2
16 elif resp == '/':
17 r = n1 / n2
18 else:
19 print('Operação inválida!')
20 continue
21 print(n1, resp, n2, '=', r)
Objetivos
- Entender o funcionamento da tratamento de exceções;
- Conhecer o conceito de modularização e decomposição de
problemas;
- Construir códigos modularizados e com tratamento de
exceção.
3.1 Introdução
Mesmo os códigos escritos corretamente podem se deparar com erros durante a execução.
Além disso, dependendo do problema a ser resolvido, podemos ter códigos muito extensos que
precisam ser organizados adequadamente para facilitar o entendimento e a manutenção. Nas
próximas seções, vamos abordar tanto o tratamento de exceções para lidar com erros inesperados,
quanto com a modularização para organizar melhor os códigos.
1 try:
2 print('Informe dois números')
3 n1 = float(input('n1: '))
4 n2 = float(input('n2: '))
5 r = n1 / n2
6 print(n1, '/', n2, '=', r)
7 except:
8 print('Ocorreu um erro.')
Figura 40 – Tratamento simples de exceção
Fonte: Elaborado pelo Autor.
No código anterior, se ocorrer um erro, a execução será finalizada na linha 8. Assim, caso o
usuário quiser tentar novamente, será preciso executar o código novamente. Uma solução para
esse problema é colocar o tratamento de exceção dentro de um laço de repetição. Dessa maneira,
se ocorrer um erro, o usuário poderá tentar novamente sem ter que executar todo o código mais
uma vez. Essa solução é mostrada na Figura 41. Como foi usado um laço while True, temos que
1 import math
2 while True:
3 try:
4 print('Informe dois números')
5 n1 = float(input('n1: '))
6 n2 = float(input('n2: '))
7 r = n1 / n2
8 break
9 except:
10 print('Ocorreu um erro! Tente novamente.')
11 print(n1, '/', n2, '=', r)
Figura 41 – Tratamento de exceção com repetição
Fonte: Elaborado pelo Autor.
Em nosso código, além do erro de digitação pelo usuário, pode acontecer o erro de divisão
por zero na linha 7. A instrução except da linha 9 captura todos os tipos de erros. Se for necessário
tratar erros diferentes, temos que colocar uma cláusula except para cada tipo de erro. Para
descobrir as classes dos erros, podemos usar a função type() como mostrado no código da Figura
42.
1 while True:
2 try:
3 print('Informe dois números')
4 n1 = float(input('n1: '))
5 n2 = float(input('n2: '))
6 r = n1 / n2
7 break
8 except Exception as e:
9 print('Ocorreu o seguinte erro:', type(e))
10 print(n1, '/', n2, '=', r)
Figura 42 – Descobrindo classes de erros
Fonte: Elaborado pelo Autor.
A instrução try possui também as cláusulas else e finally. A cláusula else pode ser usada
para realizar alguma ação quando não ocorrer erros. Já a cláusula finally é executa
incondicionalmente, ocorrendo erros ou não. A cláusula finally é útil para executar ações de limpeza
como fechamento de arquivos.
3.3 Modularização
3.3.1 Funções
Funções são trechos de código que executam determinada tarefa ao serem chamados e
depois retornam o controle para o ponto em que foram chamadas (CEDER, 2018). Apesar de ainda
não termos criados nossas próprias funções, já escrevemos diversos códigos utilizando funções
prontas como input() e print(). Quando chamamos uma função devemos informar os parâmetros
1 def saudacao():
2 print('*****************************')
3 print('* BEM VINDO *')
4 print('*****************************')
5
6 saudacao()
Figura 44 – Função saudacao()
Fonte: Elaborado pelo Autor.
No código da Figura 44 criamos apenas uma função. Porém, para a grande maioria dos
problemas precisar escrever códigos com várias funções. Além disso, podemos criar uma função
pode chamar outras funções. Uma função pode declarar variáveis para serem utilizadas apenas
internamente. Estas variáveis, assim como os parâmetros da função, são chamadas de variáveis
locais enquanto as variáveis de fora da função são as variáveis globais. É importante que as
variáveis sejam locais sempre que possível.
No código anterior, podemos ver que a função saudacao() não recebe nenhum parâmetro e
nem dados do usuário. Isso faz com que essa função sempre realize as mesmas ações. Na maioria
das vezes, precisamos criar funções parametrizáveis que realizam ações específicas conforme os
parâmetros recebidos. Na prática, os parâmetros são como variáveis já inicializadas recebidas pelas
funções.
A Figura 45 mostra um código com a função cubo(). A função recebe como parâmetro o
número num e calcula o cubo do mesmo. Contudo, essa função ainda pode ser melhorada.
Observe que não foi usada a instrução return para retornar o resultado do cálculo. A função está
simplesmente escrevendo na tela. Assim, se modificarmos a função para retornar o resultado,
1 def calcula_cubo(num):
2 cubo = num * num * num
3 print(num, 'ao cubo é', cubo)
4
5 n = float(input('Informe um número: '))
6 calcula_cubo(n)
Figura 45 – Função cubo() sem retorno
Fonte: Elaborado pelo Autor.
1 def cubo(num):
2 return num * num * num
3
4 n = float(input('Informe um número: '))
5 print(n, 'ao cubo é', cubo(n))
6 print(n, 'elevado a nona é', cubo(cubo(n)))
Figura 46 – Função cubo() com retorno
Fonte: Elaborado pelo Autor.
A Figura 46 mostra a modificação da função cubo() com o retorno do resultado. Repare que
podemos usar diretamente a função dentro do print(). Além disso, podemos usar o resultado da
função em qualquer expressão numérica, como na instrução cubo(cubo(n)) da linha 6.
3.3.4 Recursão
A recursão ocorre quando uma função chama a si mesma. Na prática, é possível usar laços
de repetição para substituir recursões. Contudo, em muitas situações, funções recursivas podem
ser mais intuitivas do que laços de repetição. Uma observação importante é que precisamos ter
cuidado com a condição de parada, assim como fazemos nos laços de repetição. Caso contrário,
podemos cair em uma recursão infinita que a função faz chamadas a ela mesma indefinidamente.
1 def fat(num):
2 if num <= 1:
3 return 1
4 return num * fat(num - 1)
5
6 n = int(input('Informe um número: '))
7 print('O fatorial de', n, 'é', fat(n))
Figura 48 – Função recursiva fat()
Fonte: Elaborado pelo Autor.
O código da Figura 48 mostra apresenta a função recursiva fat(). O if da linha 2 faz o teste
da condição de parada. Quando o parâmetro de entrada for menor ou igual a um, seu fatorial será
um. Na linha 5, ocorre a chamada recursiva, usando a equivalência n! = n * (n-1)!.
Dependendo da quantidade de código, pode ser interessante a criar módulos para agrupar
as funções correlacionadas. Normalmente, os módulos possuem apenas definições de funções ou
outras estruturas e o código principal controla o fluxo de execução do código importando os
módulos e chamando suas funções.
Para exemplificar a criação de módulos, consideraremos o problema de calcular o cubo e o
fatorial de um número. A Figura 49 mostra o módulo com as funções que realizam esses cálculos.
1 def cubo(num):
2 return num * num * num
3
4 def fat(num):
5 if num <= 1:
6 return 1
7 return num * fat(num - 1)
Figura 49 – Módulo mat.py
Fonte: Elaborado pelo Autor.
Na Figura 50 temos o código do módulo principal que controla o fluxo de execução e efetua
as chamadas as funções do módulo mat.py. É importante que ambos módulos sejam salvos na
mesma pasta ou diretório. No código, especificamos quais funções deveriam ser importados
A linguagem Python é uma linguagem interpretada, ou seja, não é preciso compilar o código-
fonte para gerar arquivos executáveis. No caso do Linux, podemos criar scripts executáveis usando
o comentário especial #!/usr/bin/env python3 na primeira linha do módulo principal. Além disso,
temos que dar permissão de execução ao arquivo. No caso do Windows, podemos associar a
abertura de arquivos .py ao programa pythonw.exe disponível na pasta de instalação do Spyder.
Assim, os scripts podem ser executados diretamente através do gerenciador de arquivos ou linha
de comando. A Figura 51 mostra um script executável juntando os dois módulos do exemplo
anterior.
1 #!/usr/bin/env python3
2
3 # -*- coding: utf-8 -*-
4
5 def cubo(num):
6 return num * num * num
7
8 n = int(input('Informe um número: '))
9 print(n, 'ao cubo é', cubo(n))
Figura 51 – Exemplo de script executável
Fonte: Elaborado pelo Autor.
1 def calcula(expr):
2 try:
3 return eval(expr)
4 except:
5 print('Expressão inválida!')
6 return None
Figura 52 – Função calcula() da calculadora de expressões
Fonte: Elaborado pelo Autor.
A Figura 52 exibe o código da função calcula(). Usamos a instrução try para fazer o
tratamento de exceção. No caso de algum erro, mostramos a mensagem de expressão inválida e
retornamos o valor None. Esse valor é um valor nulo que podemos testar ao receber o resultado da
função.
Agora criaremos uma função para atualizar o histórico da calculadora. Seu código é
mostrado na Figura 53. A instrução global HIST da linha 2 é usada para podermos alterar a variável
global HIST. Tal variável será declarada posteriormente para armazenar o histórico. Nesse
problema estamos adotando maiúsculas para variáveis globais e minúsculas para variáveis locais. A
função historico() recebe os parâmetros expr (texto da expressão calculada) e res (resultado do
cálculo). Na linha 3, fazemos um teste para verificar se a expressão é válida. O teste res is not
None é usado para verificar se o resultado da expressão (res) é diferente de None. Dentro do if
apenas adicionamos a expressão e seu resultado ao histórico. Utilizamos o '\n' para separar as
linhas do histórico.
Depois de construirmos as duas funções auxiliares, vamos escrever a função principal da
calculadora que deverá gerenciar o fluxo de execução e chamar as funções auxiliares quando
necessário. A Figura 54 mostra o código dessa função.
Temos um laço de repetição para que o usuário possa digitar quantas expressões desejar.
Na linha 6, testamos se o usuário informou o comando s e interrompemos o laço de repetição. No
caso do comando h, o teste é feito na linha 8. A linha 9 apenas mostra o histórico de cálculos
guardado na variável HIST. Repare que não precisamos da instrução global HIST nessa função
porque estamos apenas lendo o conteúdo da variável global.
Se o usuário não informar os comandos s ou h, partimos para o cálculo da expressão na
linha 11. O resultado da expressão é guardado na variável res. Em seguida, na linha 12, chamamos
a função de atualizar o histórico. Por fim, na linha 13, mostramos o resultado do cálculo da
expressão.
As funções desenvolvidas até agora não são suficientes para que a calculadora funcione.
Temos que declarar a variável global HIST e chamar a função principal(). A Figura 55 exibe o
código completo da calculadora de expressões. Os comentários das linhas 1 e 2 permitem que o
código seja executado na forma de script. A variável global HIST é inicializada com um texto vazio
na linha 4. O if da linha 33 utiliza a variável especial __name__ do Python para verificar se o
módulo foi executado como um script. Quando isso acontece o conteúdo dessa variável é
'__main__'.
3.5 Exercícios
1 def input_int(mensagem):
2 while True:
3 try:
4 return int(input(mensagem))
5 except:
6 print('Número inválido! Tente novamente.')
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3
4 def ano_bissexto(ano):
5 if (ano % 400 == 0):
6 return True
7 elif (ano % 4 == 0) and not (ano % 100 == 0):
8 return True
9 else:
10 return False
11
12 def dias_mes(ano, mes):
13 if mes == 1 or mes == 3 or mes == 5 or mes == 7:
14 return 31
15 elif mes == 8 or mes == 10 or mes == 12:
16 return 31
17 elif mes == 4 or mes == 6 or mes == 9 or mes == 11:
18 return 30
19 elif mes == 2:
20 if ano_bissexto(ano):
21 return 29
22 else:
23 return 28
24 else:
25 return -1
26
27 def principal():
28 print('Informe a data')
29 ano = int(input('Ano: '))
30 mes = int(input('Mês: '))
31
32 print('Ano bissexto:', ano_bissexto(ano))
33 print('Dias do mês:', dias_mes(ano, mes))
34
if __name__ == '__main__':
principal()
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3
4 def mdc(n1, n2):
5 while True:
6 resto = n1 % n2
7 if resto == 0:
8 return n2
9 n1 = n2
10 n2 = resto
11
12 def mmc(n1, n2):
13 return n1 * n2 // mdc(n1, n2)
14
15 def principal():
16 print('Informe dois números inteiros:')
17 n1 = int(input())
18 n2 = int(input())
19 print('MDC:', mdc(n1, n2))
20 print('MMC:', mmc(n1, n2))
21
22 if __name__ == '__main__':
23 principal()
Objetivos
- Conhecer os diferentes tipos de coleções de dados da
linguagem Python;
- Empregar as coleções de dados mais adequadas na
resolução de problemas;
- Escrever códigos usado coleções de dados.
4.1 Introdução
1 soma = 0
2 print('Informe o preço dos produtos')
3 for cont in range(10):
4 mensagem = 'Produto ' + str(cont+1) + ': '
5 preco = float(input(mensagem))
6 soma += preco
7 media = soma / 10
8 print('O preço médio é', media)
Figura 56 – Cálculo do preço médio de produtos
Fonte: Elaborado pelo Autor.
O problema das preços acima da média é que usamos os preços dos produtos para calcular
a média e depois precisamos novamente desses preços. Uma solução seria declarar 10 variáveis
uma para cada produto. Porém, imagine uma lista de 50 produtos ou mais, a declaração de
variáveis individuais não é viável na prática.
Outra solução seria pedir para o usuário para informar os preços, realizar o cálculo da média
e solicitar os preços novamente. Essa solução também não é eficiente, pois o usuário precisa digitar
a lista de preços duas vezes. Além da sobrecarga do usuário, pode ocorrer uma digitação errada na
segunda vez. A melhor solução para o problema é a utilizar uma coleção de dados para guardar os
preços de todos os produtos e, depois do cálculo da média, revisitar a coleção para buscar aqueles
produtos com preço acima da média.
40 35 61 89 10 52
0 1 2 3 4 5
Figura 57 – Representação de lista de números
Fonte: Elaborado pelo Autor.
Função Funcionamento
l.append(x) Adiciona o elemento x no final da lista l
l.insert(p, x) Insere o elemento x na posição p da lista l
l.pop(p) Remove e retorna o elemento da posição p de l (se p não for
informado, a última posição é considerada)
l.clear() Remove todos os elementos da lista l
Figura 58 – Algumas funções de listas
Fonte: Elaborado pelo Autor.
O código da Figura 59 mostra uma possível solução para o problema dos produtos
com preço acima da média utilizando listas. Na linha 2, criamos uma lista vazia para
guardar os preços dos produtos. Dentro do primeiro laço de repetição, na linha 8, os
preços são adicionados no final da lista com a função append(). O Segundo laço de
repetição percorre os preços da lista e mostra apenas aqueles acima da média.
O código anterior mostra apenas os preços acima da média, mas não exibe os produtos
com esses preços. Para resolver essa questão, no segundo laço, temos que percorrer as posições
da lista usando o range. Essa solução é apresentada na Figura 60. Como estamos varrendo a lista
pelos índices, usamos lista_precos[cont] para acessar o preço na posição cont. O código usa a
função range() para gerar o intervalo de índices da lista. Uma alternativa é usar a função
enumerate() que numera os elementos da lista e os retorna junto com seus índices. Essa solução
alternativa é mostrada na Figura 61.
1 soma = 0
2 lista_precos = []
3 print('Informe o preço dos produtos')
4 for cont in range(10):
5 mensagem = 'Produto ' + str(cont+1) + ': '
6 preco = float(input(mensagem))
7 soma += preco
8 lista_precos.append(preco)
9 media = soma / 10
10 print('O preço médio é', media)
11 print('Os produtos com preço acima da média são:')
12 for cont in range(10):
13 if lista_precos[cont] > media:
14 print('Produto', cont+1)
15 print('Preço: ', lista_precos[cont])
Figura 60 – Solução mostrando os produtos com preços acima da média
Fonte: Elaborado pelo Autor.
4.2.2 Matrizes
1 soma = 0
2 lista_precos = []
3 print('Informe o preço do produto de cada fornecedor')
4 for cont in range(5):
5 mensagem = 'Fornecedor ' + str(cont+1) + ': '
6 preco = float(input(mensagem))
7 soma = soma + preco
8 lista_precos.append(preco)
9 media = soma / 5
10 print('O preço médio é', media)
11 print('Os fornecedores com preço abaixo da média são:')
12 for cont in range(5):
13 if lista_precos[cont] < media:
14 print('Fornecedor', cont, ', preço: ', lista_precos[cont])
Figura 62 – Solução mostrando os produtos com preços acima da média
Fonte: Elaborado pelo Autor.
Uma matriz é uma estrutura de dados com múltiplas dimensões. As matrizes mais simples
são as matrizes bidimensionais que podem ser vistas como tabelas e seus elementos podem ser
referenciados através de uma linha e uma coluna. Como exemplo, uma matriz 3x4 (3 linhas por 4
colunas) é representada na Figura 63. Nessa matriz, a posição [0,1] (linha 0, coluna 1) possui o
elemento 89. Em Python, podemos implementar matrizes na forma de listas de listas.
1 30 23 17 28
2 65 72 81 58
Figura 63 – Representação de matriz bidimensional
Fonte: Elaborado pelo Autor.
1 NUM_PRODUTOS = 5
2 NUM_FORNECEDORES = 3
3
4 mat_precos = []
5 for cont_prod in range(NUM_PRODUTOS):
6 print('Produto ' + str(cont_prod+1))
7 print('Informe o preço de cada fornecedor')
8 linha = []
9 for cont_forn in range(NUM_FORNECEDORES):
10 mensagem = 'Fornecedor ' + str(cont_forn+1) + ': '
11 preco = float(input(mensagem))
12 linha.append(preco)
13 mat_precos.append(linha)
14
15 print('\nPreço médio dos produtos')
16 for cont_prod, linha in enumerate(mat_precos):
17 soma = 0
18 for preco in linha:
19 soma = soma + preco
20 media = soma / NUM_FORNECEDORES
21 print('Produto', cont_prod+1, ':', media)
22
23 print('\nPreço médio dos fornecedores')
24 for cont_forn in range(NUM_FORNECEDORES):
25 soma = 0
26 for cont_prod in range(NUM_PRODUTOS):
27 soma = soma + mat_precos[cont_prod][cont_forn]
28 media = soma / NUM_PRODUTOS
29 print('Fornecedor', cont_forn+1, ':', media)
Figura 64 – Preço médio de produtos e de fornecedores
Fonte: Elaborado pelo Autor.
Além da seleção de um único elemento pelo seu índice, as listas permitem diversos outros
tipos de seleções. A utilização de índices negativos faz a seleção dos elementos a partir do final da
lista. O índice -1 representa o último elemento, -2 é o penúltimo elemento, e assim por diante.
Também podemos selecionar sub-listas, ou seja, pedaços da lista. No caso das sub-listas usamos a
notação de colchetes após a lista indicando a posição inicial e final da sub-lista. A Figura 67 mostra
alguns exemplos de sub-listas a partir de uma lista l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].
Para praticarmos o conteúdo sobre listas, vamos implementar o jogo da forca em Python. O
jogo será de dois jogadores. Um jogador informa a palavra e o outro tenta descobrir. O jogo deve
permitir apenas palavras sem espaços e sem caracteres especiais. Assim, vamos começar criando
a função valida_palavra() para verificar se a palavra informada é válida. O Código da função é
mostrado na Figura 68. A função percorre todas as letras da palavra e verifica se as mesmas são
caracteres de 'A' a 'Z'. Se alguma letra inválida for encontrada, e função retorna False. Se a palavra
for válida a função retorna True.
1 def valida_palavra(palavra):
2 for letra in palavra:
3 if letra < 'A' or letra > 'Z':
4 return False
5 return True
Figura 68 – Função valida_palavra() para o jogo da forca
Fonte: Elaborado pelo Autor.
Vamos criar também a função novo_jogo() para pedir a palavra ao jogador. A Figura 69
apresenta o código dessa função. Usamos um laço de repetição para garantir que o jogador digite
uma palavra correta. Enquanto a palavra não for válida, a função pede para o jogador digitar
novamente. Na linha 5 recebemos a palavra digitada pelo usuário e fazemos alguns tratamentos no
texto. A função upper() é usada para converter o texto para maiúsculo e a função strip() remove
possíveis espaços em branco no início e final do texto.
1 def novo_jogo():
2 while True:
3 print('Informe a palavra para seu adversário')
4 print('Não use espaços ou caracteres especiais')
5 palavra = input().upper().strip()
6 if valida_palavra(palavra):
7 return palavra
8 else:
9 print('Palavra inválida! Tente novamente.')
Figura 69 – Função novo_jogo() para o jogo da forca
Fonte: Elaborado pelo Autor.
Assim como validamos a palavra digitada no início do jogo, temos que validar as letras
digitadas pelo jogador adversário durante o jogo. A Figura 72 mostra o código contendo a função
valida_letra() para realizar essa tarefa. A função retorna True se a letra válida e False em caso
Instituto Federal de Minas Gerais
Pró-Reitoria de Extensão 72
negativo. Na linha 2, testamos se o jogador digitou uma única letra. Na linha 4, verificamos se a letra
é válida (de 'A' a 'Z') e se já foi digitada.
1 def principal():
2 palavra = novo_jogo()
3 letras_tela = ['_'] * len(palavra)
4 erros = 0
5 digitadas = ''
6 while True:
7 mostra_jogo(letras_tela, digitadas, erros)
8 letra = input('Informe uma letra: ').upper().strip()
9 if not valida_letra(letra, digitadas):
10 continue
11 digitadas += letra
12 if not tem_letra(palavra, letra, letras_tela):
13 erros += 1
14 if erros == 5:
15 print('Você perdeu!')
16 break
17 if '_' not in letras_tela:
18 print('Você acertou!')
19 break
20
22 if __name__ == '__main__':
23 principal()
Figura 73 – Função principal() para o jogo da forca
Fonte: Elaborado pelo Autor.
Por fim, apresentamos a função principal() na Figura 73. Na linha 2, pegamos a palavra a
ser descoberta no jogo. A seguir, inicializamos os dados do jogo. A variável letras_tela recebe a lista
de caracteres '_' que serão substituídos a media que o jogador acertar as letras. O número inicial de
erros é zero e a variável digitadas, inicializada com texto vazio, representa as letras já digitadas.
O laço de repetição é usado para que novas letras sejam solicitadas até que o jogador tenha
cinco erros ou acerte a palavra. Dentro do laço, mostrados o estado do jogo com a função
mostra_jogo() e pegamos a letra digitada. Novamente, usamos upper() e strip() para remover
espaços e deixar a letra maiúscula. Em seguida, usamos a função valida_letra() para verificar se a
letra é válida. Em caso negativo, usamos a instrução continue para ignorar as demais instruções
do laço e passar para a próxima repetição. Assim, o usuário terá que digitar a letra novamente.
Se a letra for válida, adicionamos a mesma na variável digitadas (na linha 11) e fazemos
mais dois testes. O teste da linha 12 verifica se a letra não está na palavra do jogo. Nessa situação,
adicionamos um erro para o jogador (na linha 13) e verificamos se o limite de erros foi atingido (na
linha 14). Quando o número de erros chegar a cinco, o jogador perde, o break da linha 16 finaliza o
laço e o jogo termina.
O if da linha 17 verifica se o jogador já acertou todas as letras. Isso acontece quando não
temos mais o caractere '_' na lista letras_tela. Assim, o jogador vence e o jogo termina.
As tuplas são estruturas usadas para agrupar uma quantidade fixa de elementos. A
especificação de tuplas é feita escrevendo seus elementos separados por vírgula. Se a
tupla tiver um único elemento, é preciso incluir uma vírgula após esse elemento.
Normalmente, por uma questão de legibilidade, colocamos essa lista de elementos entre
parênteses. As tuplas são recomendadas para agrupar quantidades fixas e pequenas de
elementos.
Uma aplicação interessante para tuplas é o agrupamento de dia, mês e ano em uma
data. A Figura 74 ilustra essa aplicação. Observe que as tuplas de data são criadas com ano, mês
e dia, nessa ordem. Isso possibilita comparar as tuplas diretamente como foi feito na linha 13. A
comparação é feita considerando o primeiro elemento, depois o segundo e assim por diante.
1 print('Informe as datas')
2 print('Primeira data')
3 dia = int(input('Dia: '))
4 mes = int(input('Mês: '))
5 ano = int(input('Ano: '))
6 data1 = (ano, mes, dia)
7 print('Segunda data')
8 dia = int(input('Dia: '))
9 mes = int(input('Mês: '))
10 ano = int(input('Ano: '))
11 data2 = (ano, mes, dia)
12 recente = data1
13 if data2 > data1:
14 recente = data2
15 print('Data mais recente:', recente)
Figura 74 – Utilização de tuplas para representar datas
Fonte: Elaborado pelo Autor.
Cada elemento de uma tupla possui um índice, começando pelo zero (DOWNEY,
2015). Assim, podemos usar a instrução t[n] para acessar o elemento da tupla t na
posição n-1. Os índices dos elementos das tuplas representando datas podem vistos na
Figura 75. No entanto, é importante frisar que as tuplas são tipos imutáveis. Assim,
podemos ler seus elementos, mas não podemos alterá-los.
0 1 2
ano mes dia
Figura 75 – Índices dos elementos de uma tupla representando data
Fonte: Elaborado pelo Autor.
1 soma = 0
2 lista_produtos = []
3 print('Informe o dados dos produtos')
4 for cont in range(10):
5 print('\nProduto ' , cont+1)
6 nome = input('Nome: ')
7 preco = float(input('Preço: '))
8 produto = (nome, preco)
9 soma += preco
10 lista_produtos.append(produto)
11 media = soma / 10
12 print('O preço médio é', media)
13 print('Os produtos com preço acima da média são:')
14 for produto in lista_produtos:
15 nome, preco = produto
16 if preco > media:
17 print('Produto:', nome)
18 print('Preço:', preco)
Figura 76 – Produtos acima da média usando tuplas
Fonte: Elaborado pelo Autor.
4.4 Conjuntos
Os conjuntos são coleções não ordenadas de elementos (CORRÊA, 2020). Eles devem ser
utilizados quando a existência de um elemento na coleção é mais importante do que a ordem do
elemento ou do que a quantidade de vezes que o elemento aparece. Na verdade, os conjuntos em
Python, assim como na matemática, não possuem elementos repetidos.
Podemos criar um conjunto com elementos separados por vírgula entre parênteses ou usar
o construtor set() (TAGLIAFERRI, 2018). No caso do construtor, temos que passar uma coleção de
elementos, como uma lista, por exemplo. Conjuntos vazios devem ser criados com o construtor
set() sem sem nenhum parâmetro. Para exemplificar as operações sobre conjuntos, vamos
considerar os conjuntos s1 = {1, 2, 3, 4}, s2 = {4, 5, 6} e s3 = {4, 5}. A Figura 77 mostra algumas
operações sobre esses conjuntos na linguagem Python e a notação matemática correspondente.
Observe que as operações mostradas podem ser feitas com operadores ou funções.
Além das operações entre conjuntos podemos verificar se um elemento existe no conjunto
como operador in. Também podemos adicionar e remover elementos com as operações add() e
remove(), respectivamente.
Para fixar os conteúdos já apresentados, vamos agora desenvolver um jogo de bingo.
Inicialmente, vamos importar função shuffle() da biblioteca random e declarar o total de números
como mostrado na Figura 78. Se você preferir, pode usar uma quantidade diferente de números
para o jogo. Em seguida, criamos uma função que gera uma lista embaralhada de números. O
código dessa função é mostrado na Figura 79. Na linha 2, criamos a lista com os números de 1 a 80
e, na linha 3, usamos a função shuffle() para embaralhar essa lista.
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3
4 from random import shuffle
5
6 TOTAL_NUM = 80
Figura 78 – Código inicial do jogo de bingo
Fonte: Elaborado pelo Autor.
1 def gera_numeros():
2 lista_num = list(range(1, TOTAL_NUM-1))
3 shuffle(lista_num)
4 return lista_num
Figura 79 – Função gera_numeros() do jogo de bingo
Fonte: Elaborado pelo Autor.
Cada jogador deverá possuir uma cartela com os seus números. O código da Figura 80
demostra como gerar uma cartela de um jogador. Nós usamos a função gera_numeros() para
gerar os números embaralhados e tomar 30% desses números para compor a cartela. Observe
que, na linha 4, a cartela é gerada na forma de conjunto porque a ordem dos números não importa
mais.
1 def gera_cartela():
2 lista_num = gera_numeros()
3 cartela_num = int(TOTAL_NUM*0.3)
4 cartela_set = set(lista_num[:cartela_num])
5 return cartela_set
Figura 80 – Função gera_cartela() do jogo de bingo
Fonte: Elaborado pelo Autor.
1 def gera_jogadores(num_jogadores):
2 lista_jogadores = []
3 for cont in range(num_jogadores):
4 print('\n\nJogador', cont+1)
5 nome = input('Nome do jogador: ')
6 cartela = gera_cartela()
7 jogador = (nome, cartela)
8 lista_jogadores.append(jogador)
9 return lista_jogadores
Figura 81 – Função gera_jogadores() do jogo de bingo
Fonte: Elaborado pelo Autor.
Durante o jogo, vamos sortear os números e removê-los das cartelas dos jogadores. Assim,
o jogador que ficar sem números será o vencedor. O código da Figura 82 apresenta a função para
remover o número sorteado das cartelas dos jogadores. Basicamente, percorremos a lista de
jogadores, e removemos o número de suas cartelas. Como a lista de jogadores é uma lista de
tuplas, podemos fazer com que o laço pegue os dois elementos da tupla ao mesmo tempo. Usamos
a variável anônima (_) para descartar o nome do jogador, pois esse dado não será necessário. O if
da linha 3 verifica se a cartela realmente possui o número antes de removê-lo.
Para mostrar os números sorteados aos jogadores, vamos manter uma lista com os
mesmos. Além disso, a cada número sorteado, temos que mostrar o estado atual do jogo. A Figura
83 mostra o código responsável por essa tarefa. A função mostra os números já sorteados e os
números de cada jogador.
Outra tarefa importante é verificar se algum jogador já venceu o jogo. Como mencionamos,
quando os jogadores que ficarem sem números serão os vencedores. O código da Figura 84
mostra a função que verifica se já temos jogadores vencedores. Na linha 2, a função cria um
1 def busca_vencedores(lista_jogadores):
2 vencedores = set()
3 for nome, cartela in lista_jogadores:
4 if len(cartela) == 0:
5 vencedores.add(nome)
6 return vencedores
Figura 84 – Função busca_vencedores() do jogo de bingo
Fonte: Elaborado pelo Autor.
1 def principal():
2 print('Iniciando o bingo')
3 num_jog = int(input('Informe o número de jogadores: '))
4 lista_jogadores = gera_jogadores(num_jog)
5 lista_numeros = gera_numeros()
6 sorteados = set()
7 while True:
8 mostra_jogo(sorteados, lista_jogadores)
9 print('Pressione ENTER para sortear um número')
10 input()
11 num = lista_numeros.pop()
12 sorteados.add(num)
13 remove_numero(lista_jogadores, num)
14 vencedores = busca_vencedores(lista_jogadores)
15 if len(vencedores) > 0:
16 mostra_jogo(sorteados, lista_jogadores)
17 print('\nBingo!')
18 print('Vencedor(res):', vencedores)
19 break
20
21 if __name__ == '__main__':
22 principal()
Figura 85 – Função principal() do jogo de bingo
Fonte: Elaborado pelo Autor.
Por fim, a Figura 85 mostra a função principal do jogo. Primeiro, criamos a lista de jogadores,
geramos a lista com todos os números embaralhados e inicializamos o conjunto de números
sorteados. Na linha 7, começamos o laço que se repete a cada número sorteado.
Dentro do laço, mostramos o estado atual do jogo e sorteamos um número na lina 11. Como
a lista de números já está embaralhada, podemos simplesmente retirar o último elemento da lista.
Em seguida, adicionamos o número sorteado ao conjunto sorteados e chamamos a função
remove_numero() para remover o número sorteado da cartela dos jogadores.
Na linha 14, chamamos a função busca_vencedores para e, na linha 15, verificamos se já
existe algum vencedor. Quando existir algum vencedor, exibimos o estado do jogo mais uma vez ,
mostramos os vencedores e interrompemos o laço de repetição.
1 dic_vazio = {}
2 dic_letras = {1:'A', 2:'B', 3:'C'}
3 dic_letras[4] = 'E'
4 dic_letras[4] = 'D'
5 print(dic_vazio, dic_letras)
6 for cont in range(1, 5):
7 print(cont, ':', dic_letras[cont])
Figura 86 – Exemplo simples com dicionários
Fonte: Elaborado pelo Autor.
Função Funcionamento
d.clear() Remove todos os elementos do dicionário d
d.copy() Retorna uma cópia de d
d.items() Retorna as chaves-valores de d no formato de tuplas
d.keys() Retorna uma lista com as chaves de d
d.popitem() Retorna uma tupla (chave, valor) qualquer(se d estiver vazio,
ocorre um erro)
d.update(d2) Atualiza os elementos de d utilizando os elementos de d2
d.values() Retorna uma lista com os valores de d
Figura 87 – Algumas funções de dicionários
Fonte: Elaborado pelo Autor.
A primeira função que criaremos será usada para cadastrar novos produtos ou atualizar
produtos existentes. Vamos armazenar cada produto como um dicionário contendo chaves para sua
descrição, estoque e preço. Vamos usar também um dicionário de produto onde a chave de cada
produto será seu código. Dessa forma, teremos um dicionário de dicionários.
1 def cad_produto(dic_produtos):
2 print('Cadastrar/atualizar produto')
3 codigo = int(input('Código do produto: '))
4 if codigo in dic_produtos:
5 produto = dic_produtos[codigo]
6 print('\nProduto existente:\n', produto)
7 else:
8 print('\nProduto não encontrado')
9 descricao = input('Informe a descrição: ')
10 produto = {DESCRICAO: descricao}
11 dic_produtos[codigo] = produto
12 produto[ESTOQUE] = float(input('Estoque: '))
13 produto[PRECO] = float(input('Preço: '))
Figura 89 – Função cad_produto() do caixa de supermercado
Fonte: Elaborado pelo Autor.
Com os produtos cadastrados, o sistema deverá permitir a venda dos mesmos. A Figura 91
exibe o código da função venda() que realiza essa tarefa. A função recebe como parâmetros o
dicionário de produtos e a lista de vendas. A lista de vendas é usada para salvar as vendas
efetivadas. A função começa solicitado o código do produto a ser vendido. Na linha 4, a função
verificar se o código é inválido (produto inexistente) e, nesse caso, finaliza sem realizar a venda
(linha 6).
Se o código do produto for válido, a função busca esse produto no dicionário dic_produtos
e solicita a quantidade a ser vendida ao usuário. Em seguida, na linha 10, a função verifica se a
quantidade é maior do que o estoque do produto. Em caso afirmativo, a venda não é efetivada. Por
fim, se o código do produto e a quantidade vendida forem válidos, função prossegue mostrando as
informações da venda e atualizando o dados. A atualização dos dados consiste em fazer a retirada
do estoque (linha 15) e adicionar a venda à lista de vendas.
Nosso caixa de supermercado vai precisar também de um relatório de vendas para listar
todas as vendas já realizadas. A Figura 92 apresenta o código para emitir tal relatório. Primeiro, a
função informa que nenhuma venda foi encontrada, se a lista_vendas estiver vazia (linha 2). Por
outro lado, se houverem vendas, a função inicializa a variável total_geral e percorre todas as
vendas da lista.
Para cada venda a função, exibe as informações do produto, quantidade vendida, preço e
total. Além disso, o total da venda é somado ao total geral que, por sua vez, é exibido no final do
relatório.
Para utilizar todas essas funções, teremos que mostrar um menu de opções para o usuário
e pegar a opção escolhida. A função da Figura 93 escreve o menu descrito na tela e captura a
escolha do usuário.
1 def menu():
2 print('\n*****************************')
3 print('* CAIXA *')
4 print('*****************************')
5 print('(C)adastrar/atualizar produto')
6 print('(L)istar produtos ')
7 print('(V)ender produto ')
8 print('(R)elatório de vendas ')
9 print('(S)air ')
10 print('*****************************')
11 escolha = input('Informe sua opção: ').upper()
12 return escolha
Figura 93 – Função menu() do caixa de supermercado
Fonte: Elaborado pelo Autor.
4.6 Exercícios
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3
4 import math
5
6 def raizes_equacao(a, b, c):
7 delta = b**2 - 4 * a * c
8 if a == 0 or delta < 0:
9 return ()
10 elif (delta == 0):
11 x1 = b * (-1) / 2 * a
12 return (x1,)
13 else:
14 raiz_delta = math.sqrt(delta)
15 x1 = (b * (-1) + raiz_delta)/ 2 * a
16 x2 = (b * (-1) - raiz_delta)/ 2 * a
17 return (x1, x2)
18
19 def principal():
20 print('Informe os termos da equação Ax² + Bx + C')
21 a = float(input('A: '))
22 b = float(input('B: '))
23 c = float(input('C: '))
24 raizes = raizes_equacao(a, b, c)
25 if len(raizes) == 0:
26 print('\nA equação não é uma equação de segundo grau')
27 elif len(raizes) == 1:
28 print('\nA raiz da equação é x =', raizes[0])
29 else:
30 print('\nAs raizes da equação são ', end='')
31 print('x1 =', raizes[0], ' e x2 =', raizes[1])
32
33 if __name__ == '__main__':
34 principal()
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3
4 num_trechos = int(input('Informe o número de trechos: '))
5
6 lista_trechos = []
7 soma_dist = 0
8 soma_veloc_dist = 0
9 for cont in range(num_trechos):
10 print('------------------------------')
11 print('Trecho ', cont+1)
12 dist = float(input('Distância: '))
13 soma_dist += dist
14 veloc = float(input('Velocidade: '))
15 trecho = (dist, veloc)
16 lista_trechos.append(trecho)
17 soma_veloc_dist += veloc*dist
18
19 veloc_med = soma_veloc_dist/soma_dist
20 print('\nVelocidade média:', veloc_med)
21
22 print('\nTrechos com velocidade acima da média:')
23 for cont in range(num_trechos):
24 dist, veloc = lista_trechos[cont]
25 if veloc > veloc_med:
26 print('Trecho ', cont+1 , ', distância =', dist,
27 ', velocidade =', veloc)
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3
4 lista_num = []
5 while True:
6 n = int(input('Informe um número (0 para parar):'))
7 if n == 0:
8 break
9 lista_num.append(n)
10
11 dic_num = {}
12 for n in lista_num:
13 if n in dic_num:
14 dic_num[n] += 1
15 else:
16 dic_num[n] = 1
17
18 print('\nInformações sobre os números')
19 for n, quant in dic_num.items():
20 print('Número', n, ':', quant)
Bons estudos!
Atividade final
Mídia digital
Revisão da quarta
semana