Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

6
respostas

Desafio: hora da prática

Aquecimento

1. Faça um programa que solicite à pessoa usuária digitar dois números float e calcular a divisão entre esses números. O código deve conter um tratamento de erro, indicando o tipo de erro que foi gerado caso a divisão não seja possível de realizar. Teste o programa com o segundo valor numérico do input igual a 0. Também teste utilizando caracteres textuais no input para checar os tipos de erro que ocorrem.

def main():
    while True:  
        try:
            numero_1 = float(input("Digite o primeiro número: "))
            numero_2 = float(input("Digite o segundo número: "))

            resultado = numero_1 / numero_2
            print(f'O resultado da divisão é: {resultado}')
            break 

        except Exception as e:
            print("Não foi possível realizar a divisão.")
            print(f'Tipo de erro: {type(e).__name__}')
            print(f'Descrição do erro: {e}')
            print(f'Tente novamente...')

if __name__ == "__main__":
    main()

Digite o primeiro número: 15
Digite o segundo número: 0
Não foi possível realizar a divisão.
Tipo de erro: ZeroDivisionError
Descrição do erro: float division by zero
Tente novamente...
Digite o primeiro número: 15
Digite o segundo número: três
Não foi possível realizar a divisão.
Tipo de erro: ValueError
Descrição do erro: could not convert string to float: 'três'
Tente novamente...
Digite o primeiro número: 15
Digite o segundo número: 3
O resultado da divisão é: 5.0

2. Faça um programa que solicite à pessoa usuária digitar um texto que será uma chave a ser pesquisada no seguinte dicionário: idades = {'Júlia': 16, 'Carol': 23, 'Alberto': 19, 'Roberta': 17}, armazenando o resultado do valor em uma variável. O código deve conter um tratamento de erro KeyError, imprimindo a informação 'Nome não encontrado', caso ocorra o erro; e imprimir o valor caso não ocorra nenhum. Teste o programa com um nome presente em uma das chaves do dicionário e com um que não esteja no dicionário para verificar a mensagem de erro.

idades = {'Júlia': 16, 'Carol': 23, 'Alberto': 19, 'Roberta': 17}

while True:
    chave = input("Digite o nome que deseja pesquisar: ")

    try:
        valor = idades[chave]
        print(f'Idade encontrada: {valor}')
        break  
    except KeyError:
        print("Nome não encontrado. Tente novamente.")

Digite o nome que deseja pesquisar: Leonor
Nome não encontrado. Tente novamente.
Digite o nome que deseja pesquisar: Roberta
Idade encontrada: 17

3. Crie uma função que recebe uma lista como parâmetro e converta todos os valores da lista para float. A função deve conter um tratamento de erro indicando o tipo de erro gerado e retornar a lista caso não tenha ocorrido nenhum erro. Por fim, deve ter a cláusula finally para imprimir o texto: 'Fim da execução da função'.

def converter_para_float(lista):
    try:
        lista_convertida = [float(item) for item in lista]
        return lista_convertida
    except Exception as e:
        print(f'Ocorreu um erro: {type(e).__name__} - {e}')
    finally:
        print("Fim da execução da função")

valores = []
print("Digite os números da lista (digite 'sair' para terminar):")

while True:
    entrada = input("Digite um número: ")
    if entrada.lower() == "sair":
        break
    try:
        numero = float(entrada)
        valores.append(numero)
    except ValueError:
        print("Valor inválido! Tente novamente.")

resultado = converter_para_float(valores)

if resultado:
    print("Lista convertida:", resultado)

Digite os números da lista (digite 'sair' para terminar):
Digite um número: 8
Digite um número: 15
Digite um número: dezenove
Valor inválido! Tente novamente.
Digite um número: 19
Digite um número: 28
Digite um número: sair
Fim da execução da função
Lista convertida: [8.0, 15.0, 19.0, 28.0]

Continua...

6 respostas

Ei! Tudo bem, Andressa?

Que ótima entrega! No desenvolvimento em Python voltado para Data Science, dominar o tratamento de exceções é fundamental para garantir que nossos scripts de automação e pipelines de dados não quebrem por conta de entradas inesperadas.

O seu código ficou excelente e demonstra um ótimo domínio da lógica de programação. Gostei que a sua função que utiliza list comprehension para a conversão ficou super limpa e elegante. A cláusula foi aplicada certinho, garantindo a exibição da mensagem independentemente do sucesso ou erro na conversão. O seu script de captura de dados para alimentar a lista também ficou impecável!

Meus parabéns pela dedicação e organização nas respostas!

Como você se sentiu construindo essas estruturas de repetição integradas com os blocos de exceção?

Conteúdo para complementar seus estudos
Esse conteúdo pode estar em inglês, para traduzi-lo utilize o tradutor automático do navegador ou clique com o botão direito do mouse sobre a página e selecione a opção Traduzir para o português.
Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!

Continuação:

4. Crie uma função que recebe duas listas como parâmetros e agrupe os elementos um a um das listas, formando uma lista de tuplas de 3 elementos, no qual o primeiro e segundo elemento da tupla são os valores na posição i das listas e o terceiro elemento é a soma dos valores na posição i das listas. A função deve conter um tratamento de erro indicando o tipo de erro gerado e retornar como resultado a lista de tuplas. Caso as listas enviadas como parâmetro tenham tamanhos diferentes, a função deve retornar um IndexError com a frase: 'A quantidade de elementos em cada lista é diferente.' Dados para testar a função:

  • Valores sem erro:
lista1 = [4,6,7,9,10]
lista2 = [-4,6,8,7,9]
  • Listas com tamanhos diferentes:
lista1 = [4,6,7,9,10,4]
lista2 = [-4,6,8,7,9]
  • Listas com valores incoerentes:
lista1 = [4,6,7,9,'A']
lista2 = [-4,'E',8,7,9]
def agrupar_listas(lista1, lista2):
    try:
        if len(lista1) != len(lista2):
            raise IndexError('A quantidade de elementos em cada lista é diferente.')
        
        resultado = []
        for i in range(len(lista1)):
            if not isinstance(lista1[i], (int, float)) or not isinstance(lista2[i], (int, float)):
                raise TypeError(f'Valores incoerentes encontrados nas listas: {lista1[i]} e {lista2[i]}')
            
            soma = lista1[i] + lista2[i]
            resultado.append((lista1[i], lista2[i], soma))
        
        return resultado
    
    except Exception as e:
        print(f"Erro: {type(e).__name__} - {e}")
        return None


def criar_lista_manual():
    lista = []
    qtd = int(input("Quantos elementos deseja inserir na lista? "))
    for i in range(qtd):
        valor = input(f"Digite o {i+1}º valor: ")
        try:
            valor = float(valor) if "." in valor else int(valor)
        except ValueError:
            pass
        lista.append(valor)
    return lista

while True:
    print("Criação da primeira lista:")
    lista1 = criar_lista_manual()

    print("\nCriação da segunda lista:")
    lista2 = criar_lista_manual()

    print("Resultado:")
    resultado = agrupar_listas(lista1, lista2)

    if resultado is not None:
        print(resultado)
        break 
    else:
        print("Vamos tentar novamente...")


Criação da primeira lista:
Quantos elementos deseja inserir na lista? 4
Digite o 1º valor: 1
Digite o 2º valor: 11
Digite o 3º valor: 22
Digite o 4º valor: 33

Criação da segunda lista:
Quantos elementos deseja inserir na lista? 5
Digite o 1º valor: 2
Digite o 2º valor: 4
Digite o 3º valor: 6
Digite o 4º valor: 8
Digite o 5º valor: 10
Resultado:
Erro: IndexError - A quantidade de elementos em cada lista é diferente.
Vamos tentar novamente...
Criação da primeira lista:
Quantos elementos deseja inserir na lista? 3
Digite o 1º valor: 1
Digite o 2º valor: A
Digite o 3º valor: 0

Criação da segunda lista:
Quantos elementos deseja inserir na lista? 3
Digite o 1º valor: 2
Digite o 2º valor: B
Digite o 3º valor: 3
Resultado:
Erro: TypeError - Valores incoerentes encontrados nas listas: A e B
Vamos tentar novamente...
Criação da primeira lista:
Quantos elementos deseja inserir na lista? 4
Digite o 1º valor: 1
Digite o 2º valor: 10
Digite o 3º valor: 100
Digite o 4º valor: 1000

Criação da segunda lista:
Quantos elementos deseja inserir na lista? 4
Digite o 1º valor: 2
Digite o 2º valor: 20
Digite o 3º valor: 40
Digite o 4º valor: 80
Resultado:
[(1, 2, 3), (10, 20, 30), (100, 40, 140), (1000, 80, 1080)]

Continua...

Continuação:

Aplicando a projetos:

5. Como desafio, você recebeu a tarefa de desenvolver um código que contabiliza as pontuações de estudantes de uma instituição de ensino de acordo com suas respostas num teste. Este código deve ser testado para um exemplo de 3 estudantes com uma lista de listas em que cada lista possui as respostas de 5 questões objetivas de cada estudante. Cada questão vale um ponto e as alternativas possíveis são A, B, C ou D.

gabarito = ["A", "C", "B", "D", "A"]

estudantes = []

for i in range(3):
    while True:
        matricula = input(f'Digite a matrícula do estudante {i+1} (4 dígitos): ')
        if matricula.isdigit() and len(matricula) == 4:
            break
        else:
            print("Matrícula inválida! Digite exatamente 4 dígitos numéricos.")
    
    respostas = []
    print(f'Digite as respostas do estudante {matricula}:')
    for j in range(5):
        while True:  
            resposta = input(f'Questão {j+1} (A/B/C/D): ').upper()
            if resposta in {"A", "B", "C", "D"}:
                respostas.append(resposta)
                break
            else:
                print(f'A alternativa {resposta} não é uma opção válida. Digite novamente.')
    estudantes.append({"matricula": matricula, "respostas": respostas})

def calcular_pontuacoes(estudantes, gabarito):
    resultados = []
    for estudante in estudantes:
        pontos = sum(1 for r, g in zip(estudante["respostas"], gabarito) if r == g)
        resultados.append({"matricula": estudante["matricula"], "pontuacao": pontos})
    return resultados

pontuacoes = calcular_pontuacoes(estudantes, gabarito)

print("Resultados finais:")
for resultado in pontuacoes:
    print(f'Matrícula {resultado['matricula']}: {resultado['pontuacao']} pontos')

Digite a matrícula do estudante 1 (4 dígitos): Hugo
Matrícula inválida! Digite exatamente 4 dígitos numéricos.
Digite a matrícula do estudante 1 (4 dígitos): 1051
Digite as respostas do estudante 1051:
Questão 1 (A/B/C/D): e
A alternativa E não é uma opção válida. Digite novamente.
Questão 1 (A/B/C/D): D
Questão 2 (A/B/C/D): A
Questão 3 (A/B/C/D): B
Questão 4 (A/B/C/D): C
Questão 5 (A/B/C/D): A
Digite a matrícula do estudante 2 (4 dígitos): 1052
Digite as respostas do estudante 1052:
Questão 1 (A/B/C/D): A
Questão 2 (A/B/C/D): C
Questão 3 (A/B/C/D): B
Questão 4 (A/B/C/D): D
Questão 5 (A/B/C/D): A
Digite a matrícula do estudante 3 (4 dígitos): 10534
Matrícula inválida! Digite exatamente 4 dígitos numéricos.
Digite a matrícula do estudante 3 (4 dígitos): 1053
Digite as respostas do estudante 1053:
Questão 1 (A/B/C/D): 1
A alternativa 1 não é uma opção válida. Digite novamente.
Questão 1 (A/B/C/D): A
Questão 2 (A/B/C/D): B
Questão 3 (A/B/C/D): C
Questão 4 (A/B/C/D): D
Questão 5 (A/B/C/D): A
Resultados finais:
Matrícula 1051: 2 pontos
Matrícula 1052: 5 pontos
Matrícula 1053: 3 pontos

Continua...

Continuação:

6. Você está trabalhando com processamento de linguagem natural (NLP) e, dessa vez, sua líder requisitou que você criasse um trecho de código que recebe uma lista com as palavras separadas de uma frase gerada pelo ChatGPT. Você precisa criar uma função que avalia cada palavra desse texto e verificar se o tratamento para retirar os símbolos de pontuação (',' '.', '!' e '?') foi realizado. Caso contrário, será lançada uma exceção do tipo ValueError apontando o 1º caso em que foi detectado o uso de uma pontuação por meio da frase "O texto apresenta pontuações na palavra "[palavra]".". Essa demanda é voltada para a análise do padrão de frases geradas pela inteligência artificial.

  • Os dados para o teste do código são:
lista_tratada = ['Python', 'é', 'uma', 'linguagem', 'de', 'programação', 'poderosa', 'versátil',

                  'e', 'fácil', 'de', 'aprender', 'utilizada', 'em', 'diversos', 'campos', 'desde',

                  'análise', 'de', 'dados', 'até', 'inteligência', 'artificial']
lista_nao_tratada = ['Python', 'é', 'uma', 'linguagem', 'de', 'programação', 'poderosa,', 'versátil',

                  'e', 'fácil,', 'de', 'aprender', 'utilizada', 'em', 'diversos', 'campos,', 'desde',

                  'análise', 'de', 'dados', 'até', 'inteligência', 'artificial!']
def avalia_texto(texto: list):
    palavras_com_pontuacao = []
    
    for palavra in texto:
        if ',' in palavra or '.' in palavra or '!' in palavra or '?' in palavra:
            palavras_com_pontuacao.append(palavra)
    
    if palavras_com_pontuacao:
        raise ValueError(f'O texto apresenta pontuações nas palavras: {", ".join(palavras_com_pontuacao)}.')
    
    return "Texto já tratado!"

while True:
    frase_usuario = input("Digite uma frase: ")
    lista_palavras = frase_usuario.split()
    
    try:
        resultado = avalia_texto(lista_palavras)
        print(resultado)
        break  
    except ValueError as e:
        print(e)
        print("Por favor, tente novamente sem pontuações.")

Digite uma frase: Python é uma linguagem de programação poderosa, versátil e fácil de aprender, utilizada em diversos campos, desde análise de dados até inteligência artificial! 
O texto apresenta pontuações nas palavras: poderosa,, aprender,, campos,, artificial!.
Por favor, tente novamente sem pontuações.
Digite uma frase: Python é uma linguagem de programação poderosa versátil e fácil de aprender utilizada em diversos campos desde análise de dados até inteligência artificial
Texto já tratado!

Continua...

Continuação...

7. Você foi contratado(a) como uma pessoa cientista de dados para auxiliar um laboratório que faz experimentos sobre o comportamento de uma cultura de fungos. O laboratório precisa avaliar constantemente a razão (divisão) entre os dados de pressão e temperatura do ambiente controlado recolhidos durante a experimentação para definir a melhor condição para os testes.

Para cumprir com a demanda, você precisa criar uma função divide_colunas que recebe os dados das colunas de pressão e temperatura (que vem no formato de listas) e gerar uma nova coluna com o resultado da divisão. Os parâmetros da função são as duas listas e você deve tratar dentro dela ao menos 2 tipos de exceções:

  • Verificar se as listas têm o mesmo tamanho (ValueError)
  • Verificar se existe alguma divisão por zero (ZeroDivisionError)
  • Para testar a função, vamos realizar a divisão entre duas listas de dados coletados no experimento, com os valores de pressão e temperatura do ambiente controlado.
def divide_colunas(pressoes, temperaturas):
    try:
        if len(pressoes) != len(temperaturas):
            raise ValueError("As listas não têm o mesmo tamanho.")

        resultados = []
        for p, t in zip(pressoes, temperaturas):
            if t == 0:
                raise ZeroDivisionError("Divisão por zero encontrada.")
            resultados.append(p / t)

        return resultados

    except ValueError as ve:
        print(f'Erro: {ve}')
    except ZeroDivisionError as zde:
        print(f'Erro: {zde}')

# Teste 1: 
pressoes = [100, 120, 140, 160, 180]
temperaturas = [20, 25, 30, 35, 40]
print("Teste 1 (sem exceção):", divide_colunas(pressoes, temperaturas))

# Teste 2: 
pressoes = [60, 120, 140, 160, 180]
temperaturas = [0, 25, 30, 35, 40]
print("Teste 2 (ZeroDivisionError):", divide_colunas(pressoes, temperaturas))

# Teste 3: 
pressoes = [100, 120, 140, 160]
temperaturas = [20, 25, 30, 35, 40]
print("Teste 3 (ValueError):", divide_colunas(pressoes, temperaturas))

Teste 1 (sem exceção): [5.0, 4.8, 4.666666666666667, 4.571428571428571, 4.5]
Erro: Divisão por zero encontrada.
Teste 2 (ZeroDivisionError): None
Erro: As listas não têm o mesmo tamanho.
Teste 3 (ValueError): None

Ei! Tudo bem, Andressa?

Uau, parabéns pelo trabalho na prática! Suas soluções demonstram um ótimo domínio sobre estruturas de dados, loops, funções e o fluxo de tratamento de exceções. Você foi além e construiu estruturas interativas com e inputs manuais, o que deixa a validação dos dados muito mais rica.

Gostaria de destacar dois pontos super positivos e uma pequena recomendação técnica de boas práticas:

  • Uso correto do zip no exercício 7: essa função é perfeita para iterar em paralelo pelas listas de pressão e temperatura, mantendo o código elegante.
  • A validação da matrícula e dos inputs das questões usando conjuntos ficou limpa, eficiente e impede respostas inválidas antes mesmo do processamento.

O seu raciocínio lógico está afiadíssimo e pronto para os próximos desafios de análise e manipulação de grandes volumes de dados.

Como você se sentiu construindo essas lógicas de tratamento de erros? Teve alguma parte que achou mais complexa de estruturar?

Bons estudos e até mais!