Solucionado (ver solução)

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!

Solucionado
(ver solução)
2
respostas

[Desafio] Hora da prática (6-9)

Esses exercícios foram ótimos para treinar contadores, acumuladores e condições de parada. Deixo abaixo as minhas soluções em Python para quem quiser comparar lógicas ou usar como base para os próprios estudos. Sintam-se à vontade para pontuar melhorias!

  1. Tabuada com o laço for

Para gerar a tabuada de 1 a 10, o laço for junto com a função range() é a ferramenta perfeita, pois já sabemos exatamente quantas vezes o código precisa se repetir.

numero = int(input("Digite um número inteiro para ver sua tabuada: "))

print(f"\nTabuada do {numero}:")
for i in range(1, 11):
    resultado = numero * i
    print(f"{numero} x {i} = {resultado}")

  1. Verificador de Números Primos

A lógica aqui foi assumir inicialmente que o número é primo e tentar provar o contrário. Usei um laço for para testar se ele possui algum divisor além de 1 e dele mesmo. Assim que o programa encontra um divisor, ele muda a variável eh_primo para False e o break interrompe o laço, economizando processamento.

numero = int(input("Digite um número inteiro: "))
eh_primo = True

# Números menores ou iguais a 1 não são primos
if numero <= 1:
    eh_primo = False
else:
    # Testa divisores de 2 até o número anterior a ele
    for i in range(2, numero):
        if numero % i == 0:
            eh_primo = False
            break

if eh_primo:
    print(f"\nO número {numero} é primo.")
else:
    print(f"\nO número {numero} não é primo.")

  1. Distribuição de Idades de Pensionistas

Como a quantidade de clientes não era informada previamente, o while True é ideal. Ele cria um loop infinito que só é quebrado (usando break) quando a condição de encerramento é atingida, neste caso, a digitação de uma idade negativa.

grupo_0_25 = 0
grupo_26_50 = 0
grupo_51_75 = 0
grupo_76_100 = 0

print("Digite as idades dos pensionistas.")
print("Para encerrar a leitura, digite um número negativo.\n")

while True:
    idade = int(input("Idade: "))
    
    if idade < 0:
        break
    
    if 0 <= idade <= 25:
        grupo_0_25 += 1
    elif 26 <= idade <= 50:
        grupo_26_50 += 1
    elif 51 <= idade <= 75:
        grupo_51_75 += 1
    elif 76 <= idade <= 100:
        grupo_76_100 += 1
    else:
        print("Aviso: Idade fora dos intervalos mapeados (> 100 anos).")

print("\n--- Distribuição de Idades ---")
print(f"[0-25]: {grupo_0_25} pessoa(s)")
print(f"[26-50]: {grupo_26_50} pessoa(s)")
print(f"[51-75]: {grupo_51_75} pessoa(s)")
print(f"[76-100]: {grupo_76_100} pessoa(s)")

  1. Urna Eletrônica Corporativa

Aqui nós sabemos exatamente a quantidade de eleitores (20 pessoas). Portanto, usei o for para repetir a coleta de votos exatamente 20 vezes. Fui somando cada voto em sua respectiva variável e, no final, calculei as porcentagens.

votos_candidato1 = 0
votos_candidato2 = 0
votos_candidato3 = 0
votos_candidato4 = 0
votos_nulos = 0
votos_brancos = 0
total_eleitores = 20

print("--- Eleição para Gerência ---")
print("Opções de voto:")
print("1 a 4 - Candidatos")
print("5 - Voto Nulo")
print("6 - Voto em Branco\n")

for i in range(total_eleitores):
    voto = int(input(f"Voto do colaborador {i+1}: "))
    
    if voto == 1:
        votos_candidato1 += 1
    elif voto == 2:
        votos_candidato2 += 1
    elif voto == 3:
        votos_candidato3 += 1
    elif voto == 4:
        votos_candidato4 += 1
    elif voto == 5:
        votos_nulos += 1
    elif voto == 6:
        votos_brancos += 1
    else:
        print("Voto inválido! Será contabilizado como nulo.")
        votos_nulos += 1

# Cálculo das porcentagens
percentual_nulos = (votos_nulos / total_eleitores) * 100
percentual_brancos = (votos_brancos / total_eleitores) * 100

print("\n--- Resultado Final da Eleição ---")
print(f"Candidato 1: {votos_candidato1} voto(s)")
print(f"Candidato 2: {votos_candidato2} voto(s)")
print(f"Candidato 3: {votos_candidato3} voto(s)")
print(f"Candidato 4: {votos_candidato4} voto(s)")
print(f"Votos Nulos: {votos_nulos} voto(s)")
print(f"Votos em Branco: {votos_brancos} voto(s)")
print("-" * 30)
print(f"Porcentagem de Nulos: {percentual_nulos:.2f}%")
print(f"Porcentagem de Brancos: {percentual_brancos:.2f}%")

Espero que esse material ajude a clarear as ideias de quem está travado em algum ponto. Bom avanço nos estudos para todos!

2 respostas
solução!

Olá, Weriton. Como vai?

Parabéns pelo excelente material e pela iniciativa de compartilhar suas resoluções com a comunidade! Seus códigos estão extremamente limpos, muito bem estruturados e as justificativas que você escreveu antes de cada bloco demonstram que você compreendeu com muita clareza a diferença prática e conceitual de quando utilizar o laço for e o laço while.

Você aplicou conceitos fundamentais de lógica e boas práticas de programação, como o uso do break para otimizar o algoritmo de números primos, o uso do while True para fluxos de dados indefinidos e a formatação de strings (f-strings) com casas decimais fixas (:.2f).

Para enriquecer ainda mais o seu post e trazer algumas sugestões de melhoria para os seus estudos, vamos analisar dois pontos específicos onde podemos otimizar o processamento e a escalabilidade dos seus códigos:

1. Otimização no Verificador de Números Primos (Matemática Computacional)

A sua lógica atual está correta, mas imagine se o usuário digitar o número 99.999.999. O seu laço for testará milhões de divisores desnecessariamente.

Existe uma propriedade matemática muito importante para a computação: se um número possui um divisor composto, esse divisor sempre será menor ou igual à raiz quadrada desse número. Portanto, você não precisa testar até numero - 1, basta testar até a parte inteira da raiz quadrada dele!

Veja como o seu código pode economizar toneladas de processamento computacional com essa alteração simples:

import math

numero = int(input("Digite um número inteiro: "))
eh_primo = True

if numero <= 1:
    eh_primo = False
else:
    # Testamos apenas até a raiz quadrada do número (+1 para incluir o limite no range)
    limite = int(math.sqrt(numero)) + 1
    for i in range(2, limite):
        if numero % i == 0:
            eh_primo = False
            break

Para números gigantescos, essa mudança faz o código rodar instantaneamente em vez de travar o console.

2. Escalabilidade na Urna Eletrônica (Uso de Dicionários)

O seu código da urna funciona perfeitamente para o escopo do exercício. Porém, repare que você precisou criar muitas variáveis individuais (votos_candidato1, votos_candidato2, etc.) e uma grande sequência de if/elif. Se o cenário mudasse para uma eleição de condomínio com 15 candidatos, seu código ficaria gigante.

Uma excelente prática de engenharia de dados é substituir múltiplas variáveis semelhantes por uma única estrutura de dados, como um dicionário. Veja como a contagem de votos pode ser enxugada e se tornar dinâmica:

# Mapeamos as opções válidas diretamente em um dicionário
votos = {1: 0, 2: 0, 3: 0, 4: 0, "nulos": 0, "brancos": 0}
total_eleitores = 20

for i in range(total_eleitores):
    voto = int(input(f"Voto do colaborador {i+1}: "))
    
    # Se o voto estiver entre as chaves 1 e 4, incrementamos direto
    if voto in [1, 2, 3, 4]:
        votos[voto] += 1
    elif voto == 5:
        votos["nulos"] += 1
    elif voto == 6:
        votos["brancos"] += 1
    else:
        print("Voto inválido! Será contabilizado como nulo.")
        votos["nulos"] += 1

# No final, para exibir, basta acessar as chaves do dicionário:
# Ex: votos[1], votos["nulos"], etc.

Utilizar dicionários reduz a quantidade de linhas de código, evita erros de digitação de variáveis e deixa o seu programa pronto para crescer se o número de opções de votos aumentar no futuro.

Continue com essa excelente dedicação e compartilhando seus conhecimentos no fórum, isso ajuda imensamente outros alunos que estão começando!

Espero que possa ter lhe ajudado!

Salve Evandro! As duas sugestões de otimização que você trouxe são sensacionais e agregam um valor gigantesco ao post:

A sacada da raiz quadrada (math.sqrt()) no verificador de primos: Sensacional! Faz todo o sentido matemático e computacional. É o tipo de pensamento focado em performance (evitar milhões de iterações desnecessárias) que faz toda a diferença em aplicações reais. Já vou atualizar meu repositório pessoal com essa melhoria.

O uso de dicionários na Urna Eletrônica: Essa refatoração abriu muito a minha cabeça para a questão da escalabilidade. Realmente, ficar criando dezenas de variáveis isoladas e um bloco enorme de if/elif seria insustentável em um cenário maior. Mapear as opções direto nas chaves do dicionário deixou a lógica absurdamente mais elegante, dinâmica e limpa.

Vou com certeza absorver essas duas abordagens e levar esse raciocínio para os meus próximos projetos. Agradeço demais por elevar o nível técnico da discussão aqui no fórum!

Um grande abraço e seguimos nos estudos!