Capítulo 4: Controle de Fluxo e Números Aleatórios#

Seis trilhas emaranhadas de barras e traços, cada uma de uma cor, seguindo a direção de cada passo sorteado Seis trilhas emaranhadas de barras e traços, cada uma de uma cor, seguindo a direção de cada passo sorteado

Estruturas de Decisão Aninhadas#

🎙️ Ouça a explicação sobre condicionais (if-elif-else):

As estruturas condicionais permitem que o programador controle o fluxo do programa, executando diferentes blocos de código de acordo com condições específicas. Vamos revisar as estruturas mais utilizadas:

  • if: Avalia uma condição e executa um bloco de código se a condição for verdadeira.

  • elif: Avalia uma condição e executa um bloco de código se a condição for verdadeira, mas somente se a condição anterior for falsa.

  • else: Executa um bloco de código se todas as condições anteriores forem falsas.

Cadeias de Comparação:

Python permite cadeias de comparação, que são uma maneira concisa de expressar múltiplas comparações. Por exemplo, if a < b < c: é equivalente a if a < b and b < c:.

Aninhamento de Estruturas Condicionais:

O poder real das estruturas condicionais reside na capacidade de aninhá-las, criando lógica complexa para lidar com diferentes cenários.

Exemplo: Verificação de Maioridade e Sexo

idade = 25
sexo = "Feminino"

if idade >= 18:
    print("Você é maior de idade.")
    if sexo == "Feminino":
        print("E também do sexo feminino.")
else:
    print("Você é menor de idade.")

Saída do Código:

Você é maior de idade.
E também do sexo feminino.

Neste exemplo, verificamos a idade e o sexo da pessoa. Se a pessoa for maior de idade, verificamos o sexo e imprimimos uma mensagem adicional se for feminino.

Exemplo: Classificação de Notas com Cadeias de Comparação

nota = 75

if 90 <= nota < 100:
    print("Parabéns! Você obteve uma nota A.")
elif 80 <= nota < 90:
    print("Ótimo! Sua nota é B.")
elif 70 <= nota < 80:
    print("Bom trabalho! Sua nota é C.")
else:
    print("Infelizmente, você não atingiu a nota mínima. Sua nota é D.")

Saída do Código:

Bom trabalho! Sua nota é C.

Neste exemplo, a nota do aluno é comparada em intervalos usando cadeias de comparação. O código verifica a qual faixa de notas a nota pertence e imprime uma mensagem correspondente. Como a nota é 75, a condição 70 <= nota < 80 é satisfeita, e o programa imprime que o aluno obteve uma nota C.

Estrutura de Repetição for#

O loop for é amplamente utilizado em Python para realizar iterações sobre coleções de dados como listas, tuplas, dicionários e até strings.

Mas antes de explorarmos a estrutura do for, é importante entender dois conceitos fundamentais: a função range() e o operador in.

A Função range()#

A função range() é utilizada para gerar sequências numéricas. Ela pode ser configurada para definir o início, o fim e o intervalo entre os números da sequência, utilizando a seguinte sintaxe:

  • range(início, fim, passo), onde:

  • início: O primeiro número da sequência (inclusivo). O valor padrão é 0.

  • fim: O último número da sequência (exclusivo).

  • passo: A diferença entre os números consecutivos. O valor padrão é 1.

Por exemplo:

# Gera uma lista com os números de 0 a 4
lista_numeros = list(range(5))
print(lista_numeros)

Saída do Código:

[0, 1, 2, 3, 4]

Neste exemplo, a função range(5) gera uma sequência de números de 0 a 4, e usamos list() para transformar essa sequência em uma lista visível.

Outro exemplo com incremento de 2:

# Gera uma lista com números pares de 0 a 10
pares = list(range(0, 11, 2))
print(pares)

Saída do Código:

[0, 2, 4, 6, 8, 10]

Aqui, range(0, 11, 2) gera uma sequência de números pares de 0 a 10 com incrementos de 2.

O Operador in#

O operador in é usado para verificar se um valor está presente em uma sequência, e no contexto do loop for, ele indica que o loop deve iterar sobre cada elemento dessa sequência.

Por exemplo:

if 3 in [1, 2, 3, 4, 5]:
    print("3 está presente na lista")

Saída do Código:

3 está presente na lista

Aqui, o operador in verifica se o número 3 está dentro da lista. Ele retorna True se o valor estiver presente e False caso contrário.

O Loop for#

Agora que entendemos range() e o operador in, podemos introduzir o loop for. Ele permite iterar sobre cada elemento de uma sequência (lista, string, tupla, etc.) e executar um bloco de código para cada elemento:

for variavel in sequencia:
    # Bloco de código a ser repetido

A variável assume, em cada iteração, o valor de um elemento da sequência, e o bloco de código é executado para cada um desses valores.

A animação a seguir executa, passo a passo, o exemplo da string "Python" que aparece mais adiante nesta seção. A cada volta, o for verifica se ainda há elemento na sequência. Se há, a variável recebe o próximo e o bloco é executado. Quando os elementos acabam, o laço termina, e a variável fica com o último valor.

Animação em quatorze quadros do código palavra igual a Python, for letra in palavra, print de letra. Em cada quadro a linha que está rodando aparece marcada, e um fluxograma com Início, a pergunta ainda há elemento, o passo letra recebe o próximo, o print e o Fim acende o passo da vez. Ao lado, as seis letras de Python em casas, com uma seta sob a letra da vez, o valor atual de letra e a saída, que ganha uma letra por volta. Depois do n a pergunta responde Não, a seta cai na casa vazia depois da sequência e o laço termina no Fim, com letra ainda valendo n Animação em quatorze quadros do código palavra igual a Python, for letra in palavra, print de letra. Em cada quadro a linha que está rodando aparece marcada, e um fluxograma com Início, a pergunta ainda há elemento, o passo letra recebe o próximo, o print e o Fim acende o passo da vez. Ao lado, as seis letras de Python em casas, com uma seta sob a letra da vez, o valor atual de letra e a saída, que ganha uma letra por volta. Depois do n a pergunta responde Não, a seta cai na casa vazia depois da sequência e o laço termina no Fim, com letra ainda valendo n

Exemplo Prático: Iterando Sobre uma Sequência Numérica#

Com base no que aprendemos sobre range(), podemos agora utilizar um loop for para iterar sobre a sequência de números:

for i in range(5):
    print(i)

Saída do Código:

0
1
2
3
4

Aqui, o loop for itera sobre a sequência gerada por range(5), imprimindo os números de 0 a 4.

Iterando Sobre uma String#

Podemos usar o loop for para iterar sobre os caracteres de uma string:

palavra = "Python"
for letra in palavra:
    print(letra)

Saída do Código:

P
y
t
h
o
n

Nesse caso, o loop for percorre cada letra da string "Python" e as imprime individualmente.

Iterando Sobre uma Lista de Números#

Podemos também usar o loop for para percorrer uma lista de números e realizar cálculos:

numeros = [10, 20, 30, 40, 50]
for num in numeros:
    print(f"O dobro de {num} é {2 * num}.")

Saída do Código:

O dobro de 10 é 20.
O dobro de 20 é 40.
O dobro de 30 é 60.
O dobro de 40 é 80.
O dobro de 50 é 100.

Nesse exemplo, iteramos sobre cada número na lista numeros e imprimimos o seu dobro.

Executando um Número Específico de Vezes#

Se quisermos executar um bloco de código um número fixo de vezes, podemos usar o for com range():

for _ in range(3):
    print("Olá, mundo!")

Saída do Código:

Olá, mundo!
Olá, mundo!
Olá, mundo!

O uso de _ como variável (também chamado de placeholder) indica que não estamos interessados no valor da variável durante a iteração, apenas no número de vezes que o loop será executado.

Iterando Sobre um Dicionário#

Podemos usar o loop for para percorrer as chaves e valores de um dicionário:

aluno_notas = {"João": 8.5, "Maria": 9.0, "Pedro": 7.8}
for nome, nota in aluno_notas.items():
    print(f"{nome} obteve nota {nota}.")

Saída do Código:

João obteve nota 8.5.
Maria obteve nota 9.0.
Pedro obteve nota 7.8.

Aqui, o método .items() permite iterar tanto pelas chaves quanto pelos valores do dicionário, imprimindo o nome do aluno e sua respectiva nota.

Entendendo o for Aninhado#

Em alguns casos, pode ser necessário usar loops aninhados, ou seja, um loop for dentro de outro. Um exemplo prático seria iterar sobre uma matriz (ou tabela) de números:

matriz = [
    [1, 2, 3], # Primeira linha
    [4, 5, 6], # Segunda linha
    [7, 8, 9]  # Terceira linha
]

for linha in matriz:
    for numero in linha:
        print(numero, end=' ') # Mantém os números da mesma linha juntos
    print() # Pula para a próxima linha

Saída do Código:

1 2 3 
4 5 6 
7 8 9 

Aqui, usamos um loop externo para percorrer cada linha da matriz, e um loop interno para percorrer cada número dentro da linha. A combinação de loops permite navegar em estruturas mais complexas como essa.

Outro Exemplo de for Aninhado#

Vamos usar um for aninhado para gerar todas as combinações possíveis entre dois grupos de elementos. Imagine que você tem duas listas, uma de cores e outra de tamanhos, e quer combinar cada cor com cada tamanho.

cores = ["vermelho", "azul", "verde"]
tamanhos = ["P", "M", "G"]

for cor in cores:
    for tamanho in tamanhos:
        print(f"{cor} - {tamanho}")

Saída do Código:

vermelho - P
vermelho - M
vermelho - G
azul - P
azul - M
azul - G
verde - P
verde - M
verde - G

Nesse exemplo, o loop externo itera sobre cada cor e o loop interno itera sobre cada tamanho, gerando todas as combinações possíveis de cor e tamanho. Este é um exemplo clássico de como o for aninhado pode ser útil para resolver problemas envolvendo múltiplos conjuntos de dados.

Estrutura de Repetição while#

O loop while é Utilizado para repetir um bloco de código enquanto uma condição especificada for verdadeira, proporcionando controle preciso sobre o fluxo de execução.

A estrutura do loop while é composta por duas partes. Sua sintaxe básica é:

while condicao:
    # Bloco de código a ser repetido
  • Condição: Uma expressão booleana que determina se o loop deve continuar ou parar.

  • Bloco de Código: As instruções que serão executadas enquanto a condição for verdadeira.

Exemplo de um contador simples para contar até 5 usando o loop while:

contador = 1
while contador <= 5:
    print(contador)
    contador += 1

Saída do Código:

1
2
3
4
5

Explicando o código:

  • contador é inicializado com 1.

  • A condição contador <= 5 é avaliada. Se for True, o bloco de código é executado.

  • print(contador) imprime o valor atual de contador.

  • contador += 1 incrementa contador em 1.

  • O loop repete enquanto a condição for True, até que contador seja maior que 5.

A animação a seguir executa esse código passo a passo. A cada volta, a condição é avaliada de novo com o valor atual de contador. É o incremento no fim do bloco que muda esse valor: quando contador chega a 6, a condição dá False e o laço termina.

Animação em dezessete quadros do código contador igual a 1, while contador menor ou igual a 5, print de contador, contador mais igual 1. Em cada quadro a linha que está rodando aparece marcada, e um fluxograma com Início, a condição, o print, o incremento e o Fim acende o passo da vez. Ao lado aparecem o valor atual de contador, a condição escrita com esse valor, que a cada volta dá True, e a saída, que ganha um número por volta. Quando contador chega a 6 a condição dá False e o laço termina no Fim Animação em dezessete quadros do código contador igual a 1, while contador menor ou igual a 5, print de contador, contador mais igual 1. Em cada quadro a linha que está rodando aparece marcada, e um fluxograma com Início, a condição, o print, o incremento e o Fim acende o passo da vez. Ao lado aparecem o valor atual de contador, a condição escrita com esse valor, que a cada volta dá True, e a saída, que ganha um número por volta. Quando contador chega a 6 a condição dá False e o laço termina no Fim

Imprimindo os Números Pares de 1 a 10:

numero = 1
while numero <= 10:
    if numero % 2 == 0:
        print(numero)
    numero += 1

Saída do Código:

2
4
6
8
10
  • O loop itera de 1 a 10.

  • A condição numero % 2 == 0 verifica se numero é par.

  • Se for par, print(numero) imprime o número.

  • numero += 1 incrementa numero em 1.

Usando o while not#

Durante o while not, o loop continua enquanto a condição, por exemplo, da variável flag for False.

flag = False
while not flag:
    resposta = input("Você deseja sair? (sim/não): ")
    if resposta.lower() == 'sim':
        flag = True
print("Você saiu do loop.")

Explicando o código:

  • flag é inicializada como False.

  • O loop while not continua enquanto flag for False.

  • O usuário é solicitado a responder se deseja sair.

  • Se o usuário digitar “sim”, flag se torna True.

  • Quando flag é True, o loop termina e imprime “Você saiu do loop.”

While dentro de outro while: Exemplo de aninhamento de loops while.

x = 0
while x < 3:
    y = 0
    while y < 2:
        print(f"Valor de x: {x}, Valor de y: {y}")
        y += 1
    x += 1

Saída do Código:

Valor de x: 0, Valor de y: 0
Valor de x: 0, Valor de y: 1
Valor de x: 1, Valor de y: 0
Valor de x: 1, Valor de y: 1
Valor de x: 2, Valor de y: 0
Valor de x: 2, Valor de y: 1

Aqui, x varia de 0 a 2 e y de 0 a 1. Para tornar o exemplo mais interessante, podemos adicionar uma condição para destacar quando x e y são iguais:

x = 0
while x < 3:
    y = 0
    while y < 2:
        if x == y:
            print(f"X e Y são iguais e valem: {x}!")
        else:
            print(f"Valor de x: {x}, Valor de y: {y}")
        y += 1
    x += 1

Saída do Código:

X e Y são iguais e valem: 0!
Valor de x: 0, Valor de y: 1
Valor de x: 1, Valor de y: 0
X e Y são iguais e valem: 1!
Valor de x: 2, Valor de y: 0
Valor de x: 2, Valor de y: 1

For dentro de um while#

Também é possível aninhar estruturas diferentes, como um loop for dentro de um loop while.

x = 0
while x < 3:
    for i in range(3):
        print(f"Valor de x: {x}, Valor de i: {i}")
    x += 1

Saída do Código:

Valor de x: 0, Valor de i: 0
Valor de x: 0, Valor de i: 1
Valor de x: 0, Valor de i: 2
Valor de x: 1, Valor de i: 0
Valor de x: 1, Valor de i: 1
Valor de x: 1, Valor de i: 2
Valor de x: 2, Valor de i: 0
Valor de x: 2, Valor de i: 1
Valor de x: 2, Valor de i: 2

No último exemplo, x é incrementado após cada ciclo do loop for, até que atinja o valor 3 e o loop while seja interrompido.

Compreensões de Listas (List Comprehensions)#

Uma das características mais poderosas do Python é a capacidade de simplificar operações complexas em poucas linhas de código, e as compreensões de listas são um exemplo perfeito disso.

As compreensões de listas fornecem uma maneira concisa de criar listas. Aplicações comuns incluem gerar novas listas em que cada elemento é o resultado de alguma operação aplicada a cada membro de outra sequência ou iterável, ou criar uma subsequência de elementos que atendem a uma determinada condição.

Sintaxe Básica#

A sintaxe básica de uma compreensão de lista é:

[expressão for item in iterável if condição]
  • expressão: A operação que será realizada em cada item, como uma operação matemática ou chamada de função.

  • item: Representa cada elemento da sequência ou coleção que está sendo percorrida.

  • iterável: Uma sequência (lista, tupla, etc.) ou coleção (conjunto, dicionário, etc.) sobre a qual você deseja iterar.

  • condição (opcional): Um filtro que inclui apenas os elementos onde a condição for verdadeira.

Exemplo: Elevando Números ao Quadrado#

Suponha que você queira elevar ao quadrado cada número em uma lista. Veja como isso pode ser feito usando uma compreensão de lista:

numeros = [1, 2, 3, 4, 5]
quadrados = [x ** 2 for x in numeros]
print(quadrados) 

Saída do Código:

[1, 4, 9, 16, 25]

Exemplo: Filtrando e Elevando ao Quadrado Apenas Números Pares#

Agora, suponha que você queira elevar ao quadrado apenas os números pares de uma lista. Para isso, você pode adicionar uma condição if na compreensão de lista. Veja o exemplo:

numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
quadrados_pares = [x ** 2 for x in numeros if x % 2 == 0]
print(quadrados_pares)

Saída do Código:

[4, 16, 36, 64, 100]

Nesse exemplo, a lista resultante contém apenas os quadrados dos números pares, pois o if x % 2 == 0 filtra os elementos da lista original, garantindo que apenas os pares sejam elevados ao quadrado.

A animação a seguir executa essa compreensão, um elemento por vez. Os números 1, 2 e 3 marcam a ordem em que as partes agem: o for entrega o próximo x, o if o testa, e só então a expressão x ** 2 é calculada, embora venha escrita primeiro. Os ímpares não passam no filtro e são descartados antes de a expressão ser calculada, por isso a lista resultante fica com 5 dos 10 elementos.

Animação em dezessete quadros da compreensão quadrados_pares igual a x ao quadrado for x in numeros if x módulo 2 igual a zero, sobre os números de 1 a 10. No alto, as três partes da compreensão aparecem numeradas pela ordem em que agem, o 1 sobre o for, no meio, o 2 sobre o if, à direita, e o 3 sobre a expressão, à esquerda, e a parte da vez acende. Embaixo, os dez números em casas, com uma seta sob o x da vez, o teste com esse valor e o cálculo. Os ímpares dão False e são descartados sem que a expressão seja calculada, e os pares dão True, são elevados ao quadrado e entram numa das cinco casas do resultado, que termina com 4, 16, 36, 64 e 100, cinco de dez Animação em dezessete quadros da compreensão quadrados_pares igual a x ao quadrado for x in numeros if x módulo 2 igual a zero, sobre os números de 1 a 10. No alto, as três partes da compreensão aparecem numeradas pela ordem em que agem, o 1 sobre o for, no meio, o 2 sobre o if, à direita, e o 3 sobre a expressão, à esquerda, e a parte da vez acende. Embaixo, os dez números em casas, com uma seta sob o x da vez, o teste com esse valor e o cálculo. Os ímpares dão False e são descartados sem que a expressão seja calculada, e os pares dão True, são elevados ao quadrado e entram numa das cinco casas do resultado, que termina com 4, 16, 36, 64 e 100, cinco de dez

Exemplo: Transformando Pares e Ímpares com if/else (Expressão Ternária)#

E se, em vez de filtrar os números, você quisesse transformar todos eles de forma diferente — por exemplo, elevar os pares ao quadrado e deixar os ímpares como estão? Nesse caso, usamos a expressão ternária (vista no Capítulo 3) dentro da compreensão, com o if/else antes do for:

numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
resultado = [x ** 2 if x % 2 == 0 else x for x in numeros]
print(resultado)

Saída do Código:

[1, 4, 3, 16, 5, 36, 7, 64, 9, 100]

Aqui, pares viram quadrado e ímpares ficam como estão. Note que, diferente do exemplo anterior (com if no final), nenhum elemento é descartado: a lista resultante tem o mesmo tamanho da original.

Dica - if no final vs. if/else no começo

  • if no final funciona como um filtro: só entram na lista os elementos que passam na condição, então a lista resultante pode ter menos elementos. Exemplo: [x**2 for x in numeros if x % 2 == 0].

  • if/else no começo é uma expressão ternária: todos os elementos entram, mas o valor produzido depende da condição, então a lista mantém o mesmo tamanho. Exemplo: [x**2 if x % 2 == 0 else x for x in numeros].

Trocar uma forma pela outra é um erro comum. Lembre: filtro fica perto do for, ternário fica perto da expressão.

Compreensão de Lista vs. Estrutura Convencional#

Para ver o quanto as compreensões de listas podem simplificar o código, compare a filtragem de números pares e a elevação ao quadrado com e sem o uso de compreensão de listas.

Sem Compreensão de Lista (Modo Convencional)

numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
quadrados_pares = []

for x in numeros:
    if x % 2 == 0:
        quadrados_pares.append(x ** 2)

print(quadrados_pares)

Nesse caso, o código exige várias linhas para definir a lista resultante, iterar sobre a lista original, aplicar a condição e adicionar os resultados.

Com Compreensão de Lista

numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
quadrados_pares = [x ** 2 for x in numeros if x % 2 == 0]
print(quadrados_pares)

Aqui, a compreensão de lista condensa a lógica em uma única linha, mantendo o código mais direto e legível.

Ao usar compreensões de listas, você pode reduzir significativamente o número de linhas de código, facilitando a leitura e a manutenção. Isso torna o código mais “Pythonic” e é especialmente útil para operações que envolvem filtragem e mapeamento de dados, como no exemplo acima, onde o código foi reduzido de cinco linhas para apenas uma.

Controle de Fluxo com break, continue e pass#

Python oferece diversas maneiras de controlar o fluxo de execução em um programa. Entre elas, destacam-se break, continue e pass, que permitem encerrar a execução de loops, pular iterações ou até mesmo deixar blocos de código propositalmente vazios.

Cada um responde a uma pergunta diferente: e se eu quiser sair do loop antes de terminar (break)? pular esta iteração e continuar (continue)? marcar um bloco como ainda não implementado (pass)?

Saindo do Loop Atual com break#

O comando break é usado para interromper apenas o loop atual, permitindo que o restante do código continue sendo executado após o loop.

Exemplo de uso do break em um loop for#

frutas = ["maçã", "uva", "morango", "banana", "abacaxi"]
for fruta in frutas:
    if fruta == "banana":
        print("Encontrei uma banana! Saindo do loop.")
        break
    print(f"Estou processando a fruta {fruta}.")
print("Estou fora do loop.")

Saída:

Estou processando a fruta maçã.
Estou processando a fruta uva.
Estou processando a fruta morango.
Encontrei uma banana! Saindo do loop.
Estou fora do loop.

Aqui, o break encerra apenas o loop for. O programa segue normalmente após o loop.

Exemplo de uso do break em um loop while#

while True:
    opcao = input("Digite uma opção (a/b/c/sair): ")
    if opcao == "sair":
        print("Saindo do programa.")
        break
    elif opcao == "a":
        print("Executando ação relacionada à opção 'a'")
    elif opcao == "b":
        print("Executando ação relacionada à opção 'b'")
    else:
        print("Opção inválida. Tente novamente.")

Neste caso, o loop while se repete indefinidamente até que o usuário digite “sair”. Nesse momento, o break interrompe o loop e o programa continua sua execução normalmente.

Atenção: em loops aninhados, break interrompe apenas o loop mais interno — o externo continua normalmente. Para sair de uma estrutura aninhada inteira, é comum extrair o trecho para uma função e usar return, ou guardar uma flag e verificá-la no loop externo.

Pulando para a Próxima Iteração com continue#

O comando continue é utilizado quando você deseja pular o restante do código dentro do loop atual e voltar imediatamente ao início da próxima iteração.

Exemplo de uso do continue em um loop for#

frutas = ["maçã", "uva", "morango", "banana", "abacaxi"]
for fruta in frutas:
    if fruta == "banana":
        print("Ignorando a banana.")
        continue
    print(f"Estou processando a fruta {fruta}.")
print("Estou fora do loop.")

Saída:

Estou processando a fruta maçã.
Estou processando a fruta uva.
Estou processando a fruta morango.
Ignorando a banana.
Estou processando a fruta abacaxi.
Estou fora do loop.

Quando o loop encontra “banana”, o continue faz com que o restante do código dentro do loop seja ignorado e a próxima iteração seja iniciada.

Criando Blocos Vazios com pass#

O comando pass é usado como um espaço reservado (placeholder) em blocos de código que ainda não foram implementados. Ele não faz nada — serve apenas para manter a estrutura sintaticamente válida.

Exemplo de uso do pass#

frutas = ["maçã", "uva", "morango", "banana", "abacaxi"]

for fruta in frutas:
    if fruta == "banana":
        pass # Futuramente, adicionarei algo aqui
    else:
        print(f"Estou processando a fruta {fruta}.")

Saída:

Estou processando a fruta maçã.
Estou processando a fruta uva.
Estou processando a fruta morango.
Estou processando a fruta abacaxi.

Neste exemplo, o pass é usado como um marcador para indicar que, no caso de “banana”, nada deve acontecer (por enquanto). É útil durante o desenvolvimento, quando você ainda está planejando a lógica do código.

Outro uso comum do pass é deixar classes e funções vazias enquanto se planeja o esqueleto do programa — você define os nomes agora e implementa o corpo depois, sem que o Python reclame de bloco vazio:

def calcular_imposto(valor):
    pass # implementar depois

class Carrinho:
    pass # esqueleto da classe

Esse padrão aparece com frequência ao esboçar a estrutura de um programa antes de descer para os detalhes de cada parte.

Bônus: o bloco else em loops#

Python tem um detalhe pouco conhecido: tanto for quanto while aceitam um bloco else, que executa apenas se o loop terminar sem break. É um atalho útil em padrões de busca, em que você quer responder “achei” ou “não achei” sem precisar de uma flag auxiliar:

frutas = ["maçã", "uva", "morango", "abacaxi"]
alvo = "banana"

for fruta in frutas:
    if fruta == alvo:
        print(f"Encontrei {alvo}!")
        break
else:
    print(f"{alvo} não está na lista.")

Saída:

banana não está na lista.

Se o break for acionado (a busca encontra a fruta), o else é pulado. Esse é um caso em que a leitura intuitiva do else (“caso contrário”) atrapalha — tente lembrar dele como “executou tudo até o fim, sem interromper”.

Resumo das Diferenças#

Comando

Ação

Escopo de Efeito

Observação

break

Interrompe apenas o loop atual

Local (loop)

Continua o código após o loop

continue

Pula para a próxima iteração do loop

Local (loop)

Ignora o restante da iteração atual

pass

Não faz nada (placeholder)

Local

Mantém a sintaxe válida sem ação executada

Números Aleatórios#

O módulo random em Python facilita a geração de números aleatórios, fornecendo uma interface simples e direta. Este módulo implementa geradores de números pseudoaleatórios, que produzem sequências de números que aproximam a aleatoriedade verdadeira para diversas distribuições estatísticas.

Curiosidade: números verdadeiramente aleatórios podem ser gerados a partir de fenômenos físicos — como ruído atmosférico — em serviços como o random.org.

Módulos em Python#

Módulos em Python são arquivos contendo definições e instruções que podem ser reutilizadas em outros programas. Para utilizá-los, é preciso importá-los com a instrução import, seguida pelo nome do módulo.

Por exemplo, para importar o módulo random (responsável pela geração de números aleatórios):

import random

Depois de importado, suas funções e classes podem ser acessadas usando a notação de ponto, como random.random(), random.randint() e random.choice().

Métodos Comuns do Módulo random#

Na tabela, a coluna da esquerda traz só o nome do método. No código, ele vem sempre depois de random., como no exemplo de cada linha.

Método

O que faz

random()

Sorteia um float de 0 até 1, sem incluir o 1.
random.random() ➞ 0.45

randint(a, b)

Sorteia um inteiro de a a b, incluindo os dois.
random.randint(1, 10) ➞ 7

choice(seq)

Sorteia um elemento de seq.
random.choice([10, 20, 30]) ➞ 20

choices(seq, k=n)

Sorteia n elementos de seq, podendo repetir.
random.choices([0, 1], k=3) ➞ [1, 1, 0]

sample(seq, k)

Sorteia k elementos de seq, sem repetir.
random.sample([1, 2, 3, 4], 2) ➞ [4, 1]

shuffle(seq)

Embaralha a própria lista e devolve None.
[1, 2, 3] vira [3, 1, 2]

Exemplos de Uso#

Para ver cada método em uso, imagine um professor que faz os sorteios da aula com o Python. A turma tem cinco alunos, e cada exemplo abaixo resolve um sorteio diferente, um método por vez.

Um número da chamada, com randint. O randint(1, 5) sorteia um inteiro de 1 a 5, incluindo as duas pontas:

import random

numero = random.randint(1, 5)
print(f"Número da chamada: {numero}")

Saída do código (exemplo):

Número da chamada: 3

Um nome da lista, com choice. Em vez do número, o choice sorteia direto um elemento da lista:

import random

turma = ['Ada', 'Alan', 'Grace', 'Guido', 'Linus']
aluno = random.choice(turma)
print(f"Quem responde: {aluno}")

Saída do código (exemplo):

Quem responde: Guido

Vários sorteios que podem repetir, com choices. O professor tem quatro perguntas e sorteia quem responde cada uma. O mesmo aluno pode sair mais de uma vez, como num dado lançado quatro vezes:

import random

turma = ['Ada', 'Alan', 'Grace', 'Guido', 'Linus']
respondem = random.choices(turma, k=4)
print(f"Quem responde as 4 perguntas: {respondem}")

Saída do código (exemplo):

Quem responde as 4 perguntas: ['Grace', 'Guido', 'Guido', 'Ada']

Vários sorteios sem repetir, com sample. Para o seminário, são três alunos diferentes. O sample nunca sorteia o mesmo elemento duas vezes:

import random

turma = ['Ada', 'Alan', 'Grace', 'Guido', 'Linus']
seminario = random.sample(turma, 3)
print(f"Apresentam o seminário: {seminario}")

Saída do código (exemplo):

Apresentam o seminário: ['Linus', 'Grace', 'Guido']

Uma ordem para todos, com shuffle. Para a ordem das apresentações, o shuffle embaralha a própria lista. Ele não cria uma lista nova (devolve None), por isso o print vem depois e mostra a própria turma:

import random

turma = ['Ada', 'Alan', 'Grace', 'Guido', 'Linus']
random.shuffle(turma)
print(f"Ordem das apresentações: {turma}")

Saída do código (exemplo):

Ordem das apresentações: ['Ada', 'Grace', 'Guido', 'Linus', 'Alan']

Uma chance, com random. O professor decidiu que cada aula tem 30% de chance de quiz surpresa. O random() sorteia um número de 0 até 1, e esse número fica abaixo de 0,3 em 30% das vezes:

import random

sorteio = random.random()
print(f"Número sorteado: {sorteio}")

if sorteio < 0.3:
    print("Hoje tem quiz surpresa!")
else:
    print("Hoje não tem quiz.")

Saída do código (exemplo):

Número sorteado: 0.23796462709189137
Hoje tem quiz surpresa!

Definindo uma Semente#

Definir uma semente pode ser útil quando você precisa reproduzir resultados específicos em execuções diferentes do mesmo programa. Ao definir uma semente com random.seed(valor), a sequência de números gerada será sempre a mesma.

import random

# Define uma semente para reprodutibilidade
random.seed(123)

for i in range(3):
    print(f"Número aleatório {i+1}: {random.randint(1, 100)}")

Saída:

Número aleatório 1: 7
Número aleatório 2: 35
Número aleatório 3: 12

A animação a seguir roda esse programa três vezes. Nas duas primeiras a semente é 123, e os números sorteados se repetem, um a um. Na terceira a semente passa a ser 42, e a sequência muda. É isso que pseudoaleatório quer dizer: os números parecem sorteados, mas saem de um cálculo que, a partir da mesma semente, produz sempre a mesma sequência.

Animação em quatorze quadros do programa do capítulo, que importa random, define a semente com random.seed de 123 e sorteia três inteiros de 1 a 100 com randint. No alto, o código, com uma seta na linha que está rodando. Embaixo, três linhas de casas, uma por execução do programa. A 1ª execução, com seed 123, sorteia 7, 35 e 12. A 2ª, de novo com seed 123, sorteia os mesmos 7, 35 e 12, casa por casa, e termina com a frase igual à 1ª execução. A 3ª, com a semente trocada para 42, sorteia 82, 15 e 4 e termina com a frase diferente da 1ª Animação em quatorze quadros do programa do capítulo, que importa random, define a semente com random.seed de 123 e sorteia três inteiros de 1 a 100 com randint. No alto, o código, com uma seta na linha que está rodando. Embaixo, três linhas de casas, uma por execução do programa. A 1ª execução, com seed 123, sorteia 7, 35 e 12. A 2ª, de novo com seed 123, sorteia os mesmos 7, 35 e 12, casa por casa, e termina com a frase igual à 1ª execução. A 3ª, com a semente trocada para 42, sorteia 82, 15 e 4 e termina com a frase diferente da 1ª

A semente também torna um sorteio verificável. Se o professor anuncia a semente antes do sorteio, qualquer aluno pode rodar o mesmo programa e conferir que a ordem das apresentações saiu dela, e não de uma escolha do professor:

import random

turma = ['Ada', 'Alan', 'Grace', 'Guido', 'Linus']

# a semente anunciada antes do sorteio
random.seed(2026)
random.shuffle(turma)
print(f"Ordem das apresentações: {turma}")

Saída:

Ordem das apresentações: ['Alan', 'Linus', 'Guido', 'Grace', 'Ada']

Com a semente 2026, a ordem é sempre essa, em qualquer execução. Troque a semente, e a ordem muda.

Nota: O Python, por padrão, já inicializa a semente automaticamente com base em fontes de entropia do sistema, garantindo resultados aleatórios diferentes a cada execução. Você só precisa usar random.seed() quando desejar controlar a geração de números aleatórios (por exemplo, em testes ou simulações reproduzíveis).

Atenção - o módulo random não serve para senhas

Quem conhece a semente reproduz toda a sequência do random, e essa sequência também pode ser reconstruída a partir de números já sorteados. Por isso o random serve para jogos, sorteios e simulações, mas não para senhas, códigos de verificação ou chaves de acesso. Para esses casos, o Python tem o módulo secrets, que tira a aleatoriedade do sistema operacional e não aceita semente.

Exemplo: Simulando um Jogo de Dados#

Vamos criar um exemplo simples com dois jogadores, que jogam 10 rodadas. Em cada rodada, os dois lançam um dado ao mesmo tempo: quem tirar 6 vence a rodada; se os dois tirarem 6, a rodada empata; e, se nenhum tirar 6, ninguém vence.

import random

# Simulação do jogo
jogador1_vitorias = 0
jogador2_vitorias = 0

for i in range(1, 11): # Simular 10 rodadas
    jogador1_resultado = random.randint(1, 6)
    jogador2_resultado = random.randint(1, 6)

    print(f"Rodada {i}: Jogador 1 tirou {jogador1_resultado}, Jogador 2 tirou {jogador2_resultado}")

    if jogador1_resultado == 6 and jogador2_resultado == 6:
        print("Empate nesta rodada!")
    elif jogador1_resultado == 6:
        jogador1_vitorias += 1
        print("Jogador 1 ganhou esta rodada!")
    elif jogador2_resultado == 6:
        jogador2_vitorias += 1
        print("Jogador 2 ganhou esta rodada!")
    else:
        print("Nenhum jogador ganhou esta rodada.")
    print()

# Vence o jogo quem ganhou mais rodadas
if jogador1_vitorias > jogador2_vitorias:
    print("Jogador 1 venceu o jogo!")
elif jogador2_vitorias > jogador1_vitorias:
    print("Jogador 2 venceu o jogo!")
else:
    print("Empate no total de rodadas!")

print(f"\nRodadas vencidas pelo Jogador 1: {jogador1_vitorias}")
print(f"Rodadas vencidas pelo Jogador 2: {jogador2_vitorias}")

Saída do código (exemplo):

Rodada 1: Jogador 1 tirou 1, Jogador 2 tirou 5
Nenhum jogador ganhou esta rodada.

Rodada 2: Jogador 1 tirou 6, Jogador 2 tirou 2
Jogador 1 ganhou esta rodada!

Rodada 3: Jogador 1 tirou 3, Jogador 2 tirou 6
Jogador 2 ganhou esta rodada!

...

Jogador 1 venceu o jogo!

Rodadas vencidas pelo Jogador 1: 3
Rodadas vencidas pelo Jogador 2: 2

Exemplo: A Soma de Dois Dados#

Cada face de um dado tem a mesma chance de sair, mas a soma de dois dados não. O programa abaixo lança dois dados 3600 vezes, conta quantas vezes saiu cada soma e desenha a contagem com asteriscos. Com a semente fixa, a saída é sempre a mesma, inclusive quando você roda o código na página.

import random

random.seed(42)

# 13 zeros, nas posições de 0 a 12: a posição s guarda
# quantas vezes a soma s saiu (0 e 1 ficam sem uso)
contagem = []
for i in range(13):
    contagem.append(0)

# lança dois dados 3600 vezes e conta cada soma
for i in range(3600):
    soma = random.randint(1, 6) + random.randint(1, 6)
    contagem[soma] += 1

# desenha uma barra para cada soma, de 2 a 12
for soma in range(2, 13):
    # '*' * n repete o asterisco n vezes:
    # um asterisco a cada 20 lançamentos
    barra = '*' * (contagem[soma] // 20)
    # o :2 reserva duas casas para o número,
    # e alinha o 2 com o 12
    print(f"{soma:2}: {barra} {contagem[soma]}")

Saída:

 2: **** 96
 3: ********* 199
 4: ************* 275
 5: ******************* 394
 6: *********************** 475
 7: ****************************** 610
 8: ************************ 487
 9: ********************* 427
10: *************** 309
11: ********** 204
12: ****** 124

O 7 é a soma que mais sai, e o 2 e o 12 são as mais raras. A explicação está nas combinações: dois dados têm 36 resultados possíveis, e seis deles somam 7 (1 + 6, 2 + 5, 3 + 4, 4 + 3, 5 + 2 e 6 + 1), enquanto só um soma 2 (1 + 1). Em 3600 lançamentos, o esperado para o 7 é 3600 × 6/36 = 600, e saíram 610. Quanto mais lançamentos, mais a proporção de cada soma se aproxima dessa conta.

Exemplo: Sorteio de Amigo Secreto#

No amigo secreto, cada participante tira o nome de outro, e ninguém pode tirar o próprio nome. O programa embaralha uma cópia da lista de participantes e confere cada posição: se alguém ficou com o próprio nome, embaralha de novo, até o sorteio valer. Os participantes são cinco nomes da história da computação: Ada Lovelace, Alan Turing, Grace Hopper, Guido van Rossum (o criador do Python) e Linus Torvalds.

import random

participantes = ['Ada', 'Alan', 'Grace', 'Guido', 'Linus']

# O shuffle embaralha a própria lista.
# A cópia mantém a original na ordem.
sorteados = participantes.copy()

tentativas = 0
valido = False
# sorteia de novo até ninguém tirar o próprio nome
while not valido:
    random.shuffle(sorteados)
    tentativas += 1
    valido = True
    # confere cada pessoa contra o nome que ela tirou
    for i in range(len(participantes)):
        if participantes[i] == sorteados[i]:
            valido = False  # tirou o próprio nome

# mostra quem tirou quem
for i in range(len(participantes)):
    print(f"{participantes[i]} tirou {sorteados[i]}")
print(f"Sorteio válido na tentativa {tentativas}.")

Saída do código (exemplo):

Ada tirou Grace
Alan tirou Guido
Grace tirou Ada
Guido tirou Linus
Linus tirou Alan
Sorteio válido na tentativa 3.

Aqui não há semente, porque um sorteio de verdade não pode ser previsível. Com cinco pessoas, só 44 das 120 ordens possíveis deixam todo mundo com o nome de outro, cerca de 37%. Por isso o programa precisa, em média, de quase três tentativas (120 ÷ 44 ≈ 2,7).

Com o módulo random, você pode criar simulações, jogos e testes que dependem de comportamento imprevisível. E, quando precisar reproduzir um resultado específico, basta definir uma semente com random.seed().

Exercícios#

Antes de começar os exercícios, vamos aprender mais um pouco sobre a leitura dos dados de entrada. Desta vez sobre a função map(), que é usada para aplicar uma função específica a todos os elementos de uma sequência (como listas ou tuplas), retornando um iterador com os resultados. Ela recebe dois argumentos: a função a ser aplicada e a sequência de entrada.

Por exemplo, quando queremos converter a entrada do usuário em números de ponto flutuante, usamos map() juntamente com a função float():

nota1, nota2, nota3 = map(float, input().split())
print(nota1, nota2, nota3)

Neste código, o input() recebe três notas separadas por espaços. O método .split() divide a entrada em uma lista de strings. Em seguida, map(float, ...) aplica a função float() a cada elemento da lista, convertendo as strings em números de ponto flutuante. Finalmente, os valores convertidos são atribuídos às variáveis nota1, nota2 e nota3. O print no fim mostra o resultado: ao testar o código, digite 6 8 9.1 no campo que aparece, e ele imprime 6.0 8.0 9.1, com o 6 e o 8 já convertidos em float.

Outro exemplo é quando queremos converter a entrada do usuário em uma lista de números de ponto flutuante. Podemos fazer isso da seguinte maneira:

notas = list(map(float, input().split()))
print(notas)

Neste caso, o input() recebe várias notas separadas por espaços. O método .split() divide a entrada em uma lista de strings. Em seguida, map(float, ...) aplica a função float() a cada elemento da lista, convertendo as strings em números de ponto flutuante. Finalmente, a função list() transforma o objeto map em uma lista de números de ponto flutuante, que é atribuída à variável notas. Digitando 7 8.5 10 6, o print mostra [7.0, 8.5, 10.0, 6.0]. Agora sim, vamos aos Exercícios.

  1. Classificação Etária: Desenvolva um programa que recebe várias idades de usuários na entrada, todas separadas por espaços. Para cada idade, o programa deve imprimir a categoria correspondente de acordo com a seguinte escala:

Categoria

Faixa Etária

Menor de idade

Menos de 13 anos

Adolescente

De 13 a 17 anos

Maior de idade

De 18 a 59 anos

Idoso

60 anos ou mais

# Teste
Entrada: 12 15 20 16 21 60 22 14 23 65
Saída: 
Menor de idade
Adolescente
Maior de idade
Adolescente
Maior de idade
Idoso
Maior de idade
Adolescente
Maior de idade
Idoso
  1. Verificação de Palíndromo: Faça um programa que receba uma lista de palavras e verifique se cada palavra é um palíndromo. Um palíndromo é uma palavra que permanece a mesma quando lida de trás para frente. O programa deve imprimir “Sim” para palíndromos e “Não” para não palíndromos. Utilize end=' ' no comando print para que os resultados sejam exibidos na mesma linha, separados por espaços.

# Teste
Entrada: arara python reviver código osso casa radar programa mussum piloto
Saída: Sim Não Sim Não Sim Não Sim Não Sim Não
  1. Contagem Regressiva: Escreva uma contagem regressiva de 10 a 1, com um intervalo de 1 segundo entre cada número. Para isso, pesquise e utilize o módulo time para pausar a execução do programa por 1 segundo antes de imprimir cada número.

Lembre-se de importar o módulo time e usar a função time.sleep(1) para criar o atraso desejado. Você pode encontrar mais informações sobre o módulo time na documentação oficial do Python.

# Teste
Entrada: Sem entrada
Saída: 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
  1. Análise de Desempenho de uma Turma com até 100 Alunos: Analise o desempenho de uma turma com até 100 alunos em uma disciplina de linguagem de programação. Seu programa deve receber como entrada uma lista de até 100 números entre 0 e 10, representando as notas finais de cada aluno.

Para cada nota na lista, o programa deve:

  • Adicionar a nota à uma soma total (para posterior cálculo da média da turma).

  • Verificar se a nota é maior ou igual a 5. Se for, incrementar o contador de alunos aprovados.

  • Se a nota for menor que 5, incrementar o contador de alunos reprovados.

Após processar todas as notas, o programa deve calcular e imprimir as seguintes informações: Número de Alunos Aprovados, Número de Alunos Reprovados e Média da Turma.

Obs: Considere utilizar essa sintaxe para o armazenamento das notas em uma lista: list(map(float, input().split(',')))

# Teste 1
Entrada: 1.3, 2.8, 8.1, 5.6, 8.1, 6.9, 9.7, 0.7, 0.7, 1.1, 10.0, 1.7, 8.5, 3.3, 2.4, 6.9, 2.5, 0.3, 8.8, 3.1, 8.1, 9.2, 1.4, 4.6, 4.6, 0.6, 10.0, 1.4, 4.3, 7.9, 3.9, 2.4, 5.4, 5.6, 4.4, 3.5, 0.5, 7.4, 2.7, 2.1, 3.5, 6.3, 3.6, 0.0, 7.7, 0.8, 7.7, 9.7, 1.6, 0.3, 6.5, 4.2, 1.2, 4.3, 4.5, 8.9, 5.8, 7.5, 9.7, 8.2, 1.5, 9.2, 6.1, 9.7, 6.7, 0.5, 7.1, 3.4, 7.8, 8.1, 4.5, 4.1, 5.8, 3.4, 0.3, 10.0, 7.7, 0.2, 9.9, 2.3, 7.8, 5.6, 3.6, 1.3, 9.5, 1.2, 6.4, 3.2, 9.1, 8.6, 6.2, 7.9, 4.9, 7.3, 1.2, 5.1, 9.2, 7.6, 0.3, 7.4
Saída:
Número de Alunos Aprovados: 50
Número de Alunos Reprovados: 50
Média da Turma: 5.06

# Teste 2
Entrada: 7.0, 8.5, 9.0, 4.5, 6.0, 3.0, 2.5, 8.0, 9.5, 5.0
Saída:
Número de Alunos Aprovados: 7
Número de Alunos Reprovados: 3
Média da Turma: 6.30

# Teste 3
Entrada: 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0
Saída:
Número de Alunos Aprovados: 10
Número de Alunos Reprovados: 0
Média da Turma: 10.00

# Teste 4
Entrada: 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
Saída:
Número de Alunos Aprovados: 0
Número de Alunos Reprovados: 10
Média da Turma: 0.00
  1. Cálculo do Fatorial: Escreva um programa que receba uma lista de números inteiros, e obedecendo alguns critérios, calcule e imprima o fatorial de cada um deles. O fatorial de um número é o produto de todos os números inteiros de 1 até o próprio número.

Aqui estão as etapas e critérios para implementar seu programa:

  • Receba e armazene uma lista de números inteiros.

  • Verifique se cada número é válido (ou seja, maior ou igual a zero e menor do que 15).

  • Calcule o fatorial de cada número usando um loop for ou while.

  • Exiba o resultado do fatorial para cada um dos números. Se não for possível calcular o fatorial (por exemplo, para números não válidos), escreva um X.

  • Mostre a quantidade de números para os quais não foi possível calcular o fatorial.

# Teste 1
Entrada: 7, 6, -1, 14, 1, 12, 0, 18, 15, 12, 5, 9, 10, 0, 12, 17, 2, 15, 12, 2, 16, 19, 5, 4, 10
Saída: 5040, 720, X, 87178291200, 1, 479001600, 1, X, X, 479001600, 120, 362880, 3628800, 1, 479001600, X, 2, X, 479001600, 2, X, X, 120, 24, 3628800
Quantidade de números inválidos: 7

# Teste 2
Entrada: 3, 9, 12, 15, 12, 0, 8, 15, 12, 5, 9, 10, 0, 12, 17, 2, 15, 12, 2, 16, 19, 5, 4, 10, 3, 13
Saída: 6, 362880, 479001600, X, 479001600, 1, 40320, X, 479001600, 120, 362880, 3628800, 1, 479001600, X, 2, X, 479001600, 2, X, X, 120, 24, 3628800, 6, 6227020800
Quantidade de números inválidos: 6

Lembre-se de tratar casos especiais. Zero possui fatorial 1 e um número negativo não possui fatorial.

6. Jogo da Adivinhação (Jogador vs Computador): O objetivo é desenvolver um jogo interativo de adivinhação de números no qual o jogador compete contra o computador. O jogo deve seguir as seguintes regras:

  • No início do jogo, o programa deve gerar um número aleatório secreto entre 1 e 100. Este será o número que o jogador e o computador tentarão adivinhar.

  • Tanto o jogador quanto o computador têm um número limitado de tentativas para adivinhar o número. Por exemplo, pode-se limitar a 20 tentativas.

  • Em cada rodada, o jogador e o computador fazem um palpite. O programa deve então fornecer uma dica para ambos, indicando se o número secreto é maior ou menor que os palpites.

  • Se o jogador ou o computador adivinhar o número corretamente, o programa deve parabenizá-lo e informar o número de tentativas que foram necessárias para adivinhar o número. Se ambos adivinharem o número na mesma rodada, o jogo termina em empate.

  • Se o jogador e o computador esgotarem todas as suas tentativas sem adivinhar o número, o programa deve informar que o jogo terminou e revelar o número secreto.

7. Exercício de Padrão de Asteriscos: Escreva um programa em Python que imprima um triângulo de asteriscos. O programa deve receber na entrada o número de linhas do triângulo e o tipo de triângulo a ser impresso (tipo1 ou tipo2). Em seguida, o programa deve imprimir o triângulo de asteriscos com o número de linhas especificado e no formato escolhido.

  • Tipo 1: Cada linha começa com um asterisco e aumenta o número de asteriscos à medida que descemos.

  • Tipo 2: O número máximo de asteriscos aparece na primeira linha e à medida que avançamos para a direita, este número vai diminuindo.

# Teste 1
Entrada: tipo1, 3
Saída:
*
**
***

# Teste 2
Entrada: tipo1, 5
Saída:
*
**
***
****
*****

# Teste 3
Entrada: tipo2, 4
Saída:
****
***
**
*

8. Identificação de Números Primos em uma Lista: Desenvolva um programa que identifique todos os números primos presentes em uma lista fornecida na entrada. Um número primo é um número maior que 1 que não possui divisores positivos além de 1 e si próprio. Siga as Instruções a seguir:

  • Leia uma lista de números inteiros.

  • Para cada número na lista, verifique se ele é um número primo.

  • Se o número for primo, adicione-o a uma nova lista.

  • Após verificar todos os números na lista original, exiba a nova lista contendo apenas os números primos.

# Teste 1
Entrada: -23, 15, -7, 49, -35, 21, -2, 30, -14, 8, -50, 44, -29, 17, -3, 34, -9, 25, -40, 12, 5, -28, 37, -16, 10, -4, 42, -33, 18, -6, 27, -13, 39, -22, 11, -1, 31, -19, 20, -36, 14, -8, 26, -45, 9, -24, 32, -10, 23, -5
Saída: 17, 5, 37, 11, 31, 23

# Teste 2
Entrada: -18, 33, -12, 27, -6, 42, -30, 21, -3, 39, -24, 15, -9, 36, -15, 12, -1, 45, -27, 18, -7, 30, -21, 9, -33, 24, -13, 6, -42, 36, -19, 3, -39, 30, -10, 0, 48, -25, 16, -4, 41, -28, 22, -5, 38
Saída: 3, 41

9. Loteria de 5 números: Desenvolva um programa que simule uma loteria onde são sorteados 5 números distintos entre 1 e 50. O programa deve gerar aleatoriamente jogos de 5 números até que um jogo corresponda exatamente à combinação sorteada. O objetivo é determinar quantos jogos são necessários até que haja um ganhador. Siga as instruções a seguir:

  • Receba na entrada um inteiro correspondente à semente para geração pseudoaleatória de números.

  • Gere uma combinação vencedora de 5 números únicos entre 1 e 50 usando random.sample.

  • Converta a combinação vencedora em um conjunto (set) para facilitar a comparação.

  • Crie um loop que simule jogos de 5 números únicos entre 1 e 50, também usando random.sample.

  • Após cada jogo, converta a combinação de números gerada em um conjunto (set) e verifique se ela corresponde à combinação vencedora.

  • Conte o número de jogos realizados até que um jogo corresponda exatamente à combinação vencedora.

  • Exiba o número total de jogos necessários para encontrar um ganhador.

# Teste 1
Entrada: 1
Saída: Número de jogos necessários: 24836

# Teste 2
Entrada: 2
Saída: Número de jogos necessários: 622164

# Teste 3
Entrada: 11
Saída: Número de jogos necessários: 807045

10. O “Velho” Fibonacci: A sequência de Fibonacci é uma série infinita de números inteiros em que cada número é a soma dos dois anteriores. Ela começa com os números 1 e 1:

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, …

Para calcular o próximo número na sequência, somamos os dois números anteriores. Por exemplo:

  • O terceiro número é 1 + 1 = 2.

  • O quarto número é 1 + 2 = 3.

  • O quinto número é 2 + 3 = 5.

E assim por diante.

Veja a imagem ilustrativa a seguir:

fib

Agora, vamos criar um programa que gere a sequência de Fibonacci até o n-ésimo termo. O usuário fornecerá o valor de n.

  • Inicializamos as variáveis ultimo e penultimo com os valores 1, pois os dois primeiros termos da sequência são 1.

  • Usamos um laço de repetição (como um for ou while) para calcular os próximos termos. Salvando os valores em uma lista.

  • A cada iteração, somamos ultimo e penultimo para obter o próximo termo.

  • Atualizamos as variáveis ultimo e penultimo para os valores corretos.

  • Repetimos o processo até chegarmos ao n-ésimo termo.

  • Por fim, todos os números da sequência, armazenados em uma lista, devem ser impressos.

# Teste 1
Entrada: 10
Saída: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55

# Teste 2
Entrada: 19
Saída: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181

# Teste 3
Entrada: 23
Saída: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657 

11. Gerador de Senhas Aleatórias

Você foi contratado para desenvolver um sistema simples que gere senhas de teste para usuários. Cada senha deve conter letras maiúsculas, letras minúsculas e números. Para facilitar a criação de várias senhas, o sistema deve gerar um conjunto de senhas automaticamente.

Importante: a semente deve ser definida com random.seed(42) antes de qualquer chamada a funções como random.choices() ou random.shuffle(). Isso garante que todos os alunos gerem exatamente as mesmas senhas. Pelo mesmo motivo, essas senhas são previsíveis: servem para praticar, e não para uso real (veja o aviso sobre o módulo secrets na seção Números Aleatórios).

Requisitos:

  • Cada senha deve conter:

  • 3 letras maiúsculas

  • 3 letras minúsculas

  • 3 dígitos

  • A senha deve ter 9 caracteres no total, dispostos em ordem aleatória.

  • Utilize um laço de repetição para gerar a quantidade (qtd) de senhas desejada.

  • Use o módulo random e defina a semente com random.seed(42) antes de gerar qualquer senha.

Dicas:

  • import string pode ser útil

  • Use string.ascii_uppercase, string.ascii_lowercase e string.digits para acessar letras e números.

  • Use random.choices(..., k=3) para sortear 3 caracteres de uma lista.

  • Por fim, use random.shuffle(lista) para embaralhar a ordem dos caracteres da senha.

# Teste 1
Entrada: 3
Saída: rfH4t80AQ wl74S1SKh Gl0I9J2bd

# Teste 2
Entrada: 5
Saída: rfH4t80AQ wl74S1SKh Gl0I9J2bd W6l37evJW ft8R8YHi0

# Teste 3
Entrada: 8
Saída: rfH4t80AQ wl74S1SKh Gl0I9J2bd W6l37evJW ft8R8YHi0 5LKgg8Xo2 pDrE45kW2 19gC5LLyw

12. Batalha de Números Primos

Dois jogadores entraram em uma batalha matemática! Cada um receberá 15 números aleatórios entre 1 e 1000. O objetivo é simples: quem tiver mais números primos vence a partida.

Para garantir que os testes possam ser reproduzidos de forma idêntica, o programa deve receber duas sementes de números aleatórios — uma para cada jogador.

Requisitos

  • Receba dois números inteiros como entrada: eles serão usados como sementes (random.seed()) — uma para cada jogador.

  • Após definir a semente, sorteie 15 números entre 1 e 1000 para cada jogador, com random.randint(1, 1000).

  • Verifique quais desses números são primos.

  • Mostre:

  • Os 15 números sorteados para cada jogador

  • Quantos números primos cada jogador recebeu

  • Declare o vencedor com base em quem teve mais primos: “Vencedor: Jogador 1” ou “Vencedor: Jogador 2”. Em caso de empate, informe: “Vencedor: Empate”

# Teste 1
Entrada: 123 456
Saída:
JOGADOR 1
[54, 275, 90, 788, 418, 273, 111, 859, 923, 896, 40, 389, 550, 576, 341]
Número de Primos: 2

JOGADOR 2
[767, 461, 990, 478, 446, 400, 814, 911, 664, 42, 633, 749, 843, 921, 809]
Número de Primos: 3

Vencedor: Jogador 2

# Teste 2
Entrada: 111 222
Saída:
JOGADOR 1
[848, 972, 218, 944, 966, 324, 506, 199, 408, 427, 632, 832, 174, 645, 199]
Número de Primos: 2

JOGADOR 2
[798, 111, 241, 291, 314, 33, 30, 494, 229, 456, 758, 738, 452, 464, 77]
Número de Primos: 2

Vencedor: Empate

# Teste 3
Entrada: 42 99
Saída:
JOGADOR 1
[655, 115, 26, 760, 282, 251, 229, 143, 755, 105, 693, 759, 914, 559, 90]
Número de Primos: 2

JOGADOR 2
[414, 390, 205, 614, 184, 236, 255, 137, 779, 89, 258, 747, 393, 544, 701]
Número de Primos: 3

Vencedor: Jogador 2