Fazer um programa em Python para solicitar ao usuário as informações de quantas senhas ele deseja cadastrar.
Então, verifique se cada senha criada atende aos requisitos:
Mais de 16 caracteres e menos de 20 .
Se houver caracteres especiais, saiba: !@#$%&.
Se contém dia, mês ou ano do aniversário do usuário.

Passo 1

O enunciado pede para fazermos um programa em Python que:
  • Solicite ao usuário quantas senhas ele deseja cadastrar.
  • Para cada senha informada, verifique se ela atende aos requisitos:
    1. Ter comprimento maior que 16 caracteres e menor que 20 caracteres (ou seja, comprimento estritamente entre 16 e 20).
    2. Conter ao menos um dos caracteres especiais da lista: !@#$%&.
    3. Não conter o dia, o mês ou o ano do aniversário do usuário (ou seja, a senha não pode ter como substring o dia, o mês ou o ano da data de nascimento do usuário).
  • O programa deve pedir ao usuário a data de nascimento para poder verificar o item 3.
Informações relevantes dadas:
  • Limite inferior de comprimento: 16 (a senha deve ser maior que isso).
  • Limite superior de comprimento: 20 (a senha deve ser menor que isso).
  • Conjunto de caracteres especiais permitidos: !@#$%&.
  • Precisamos checar presença de dia, mês e ano do aniversário do usuário dentro da senha (substrings).

Passo 2

Plano de ação (em linhas gerais, sem programar ainda):
  1. Perguntar ao usuário quantas senhas serão cadastradas (um inteiro positivo).
  2. Pedir a data de nascimento do usuário em um formato claro (vou usar DD/MM/AAAA) e extrair o dia, mês e ano.
  3. Para cada senha (repetir o número de vezes informado):
    • Ler a senha.
    • Verificar o comprimento: ver se len(senha) satisfaz 16 < \text{len} < 20.
    • Verificar presença de pelo menos um caractere da lista !@#$%&.
    • Verificar se a senha contém o dia, o mês ou o ano do aniversário (considerar dia/mês com e sem zero à esquerda; considerar ano com 4 dígitos e, por segurança, também os 2 últimos dígitos).
    • Informar ao usuário se a senha é aceita ou, se não for, listar o(s) motivo(s).
  4. Repetir até processar todas as senhas solicitadas.

Passo 3

Como verificar o comprimento de uma string em Python (aula curtinha):
  • Em Python usamos a função embutida len() para obter o número de caracteres de uma string.
  • Exemplo: para a senha armazenada em senha, o comprimento é len(senha).
  • A condição pedida é: a senha deve satisfazer 16 < \text{len(senha)} < 20. Em código isso vira:
    if len(senha) > 16 and len(senha) < 20:
        # comprimento aceitável
    else:
        # comprimento inválido
    
  • Nota prática: isso significa que comprimentos válidos são 17, 18 ou 19 caracteres.

Passo 4

Como checar presença de caracteres especiais (método simples e confiável):
  • Definimos uma coleção com os especiais permitidos, por exemplo especiais = set("!@#$%&").
  • Para saber se a senha contém pelo menos um desses caracteres podemos usar any():
    • any(c in especiais for c in senha) retorna True se existir algum caractere c na senha que pertença a especiais.
  • any() funciona assim: recebe um gerador/iterável de valores booleanos e retorna True se qualquer um for True. É eficiente porque para ao encontrar o primeiro True.

Passo 5

Como checar se a senha contém dia, mês ou ano do aniversário:
  • Vamos pedir a data no formato DD/MM/AAAA e dividir usando split("/") para obter strings de dia, mês e ano.
  • Atenção com zeros à esquerda: pessoas podem colocar dia 05 na senha como "05" ou como "5"; então é prudente checar ambas as formas:
    • dia com zero: dia = partes[0].zfill(2) (garante dois dígitos, ex.: "05").
    • dia sem zero: dia_sem_zero = str(int(partes[0])) (converte "05" para "5").
  • Fazer o mesmo para o mês: mes e mes_sem_zero.
  • Para o ano, pegamos ano = partes[2] (ex.: "1998"). Também podemos checar os dois últimos dígitos ano[-2:] por segurança (ex.: "98").
  • Em Python a verificação de substring é simples: if dia in senha: significa que a sequência de caracteres dia aparece em senha.
  • Vamos considerar a senha como sensível a maiúsculas/minúsculas apenas se houvesse letras; como dia/mês/ano são números, não precisamos mudar caixa (case).

Passo 6

Estrutura da função de validação (explicando antes de ver o código final):
  • Criaremos uma função validar_senha(senha, dia, dia_sem_zero, mes, mes_sem_zero, ano, ano2) que:
    1. Inicializa uma lista motivos = [].
    2. Verifica comprimento; se inválido, adiciona motivo apropriado.
    3. Verifica presença de especiais com any(...); se nenhum especial encontrado, adiciona motivo.
    4. Verifica presença de qualquer variante do dia, mês ou ano na senha; se encontrar, adiciona motivo.
    5. Se motivos ficar vazia, a senha é válida; caso contrário, é inválida e retornamos a lista de motivos.
  • No laço principal do programa, para cada senha chamamos essa função e mostramos o resultado ao usuário.

Passo 7

Comportamento do programa na interação com o usuário (detalhes práticos):
  • Primeiro, perguntar quantas senhas cadastrar. Se o usuário digitar algo inválido (não inteiro ou ≤ 0), repetir o pedido até obter um inteiro válido.
  • Em seguida, pedir a data de nascimento no formato DD/MM/AAAA. Se o formato estiver errado (não três partes, ou partes não numéricas, ou dia/mês fora do intervalo razoável), pedir novamente.
  • Depois, para i de 1 até n, pedir a senha i, validar e imprimir:
    • “Senha X: válida.” ou
    • “Senha X: inválida. Motivos:” seguido de cada motivo em uma linha.
  • Ao final, opcionalmente encerrar com uma mensagem resumida (não obrigatório).

Passo 8

Observações pedagógicas e dicas para a prova:
  • Lembre-se: len() conta caracteres, incluindo espaços e símbolos. Senhas podem conter espaços; se não forem desejados, trate isso explicitamente (não foi pedido no enunciado).
  • any() é sua amiga para testar “existe ao menos um” entre várias condições. Há também all() para “todas devem ser verdadeiras”.
  • Para checar substrings, use o operador in: é direto e legível.
  • Sempre trate entradas do usuário com validação para evitar erros de runtime (ex.: dividir por índices inexistentes).
  • Em prova, escreva primeiro o algoritmo (em palavras) e depois traduza para código; isso ajuda a não esquecer passos de validação.

Resposta

def ler_inteiro_positivo(prompt):
    while True:
        s = input(prompt).strip()
        try:
            n = int(s)
            if n > 0:
                return n
            else:
                print("Por favor, digite um número inteiro positivo.")
        except ValueError:
            print("Entrada inválida. Digite um número inteiro.")

def ler_data_nascimento(prompt):
    while True:
        s = input(prompt).strip()
        partes = s.split("/")
        if len(partes) != 3:
            print("Formato inválido. Use DD/MM/AAAA.")
            continue
        dia_s, mes_s, ano_s = partes
        if not (dia_s.isdigit() and mes_s.isdigit() and ano_s.isdigit()):
            print("Dia, mês e ano devem ser numéricos. Use DD/MM/AAAA.")
            continue
        dia_i = int(dia_s)
        mes_i = int(mes_s)
        ano_i = int(ano_s)
        if not (1 <= dia_i <= 31):
            print("Dia inválido. Deve estar entre 1 e 31.")
            continue
        if not (1 <= mes_i <= 12):
            print("Mês inválido. Deve estar entre 1 e 12.")
            continue
        if not (0 <= ano_i <= 9999):
            print("Ano inválido.")
            continue
        # retornar strings úteis: com zero à esquerda e sem
        dia = dia_s.zfill(2)
        dia_sem_zero = str(dia_i)
        mes = mes_s.zfill(2)
        mes_sem_zero = str(mes_i)
        ano = ano_s.zfill(4)
        ano2 = ano[-2:]
        return dia, dia_sem_zero, mes, mes_sem_zero, ano, ano2

def validar_senha(senha, dia, dia_sem_zero, mes, mes_sem_zero, ano, ano2):
    motivos = []
    comprimento = len(senha)
    # regra de comprimento: maior que 16 e menor que 20
    if not (comprimento > 16 and comprimento < 20):
        motivos.append(f"Comprimento inválido ({comprimento} caracteres). Deve ter mais de 16 e menos de 20.")
    # caracteres especiais permitidos
    especiais = set("!@#$%&")
    if not any(c in especiais for c in senha):
        motivos.append("Não contém caracteres especiais permitidos (!@#$%&).")
    # checar presença de dia, mês ou ano (várias formas)
    contem_data = False
    partes_data = {dia, dia_sem_zero, mes, mes_sem_zero, ano, ano2}
    for p in partes_data:
        if p and p in senha:
            contem_data = True
            break
    if contem_data:
        motivos.append("Contém dia, mês ou ano do aniversário do usuário.")
    # resultado
    return motivos

def main():
    print("Cadastro de senhas - validação")
    n = ler_inteiro_positivo("Quantas senhas deseja cadastrar? ")
    print("Digite sua data de nascimento no formato DD/MM/AAAA para que possamos verificar as senhas.")
    dia, dia_sem_zero, mes, mes_sem_zero, ano, ano2 = ler_data_nascimento("Data de nascimento (DD/MM/AAAA): ")
    for i in range(1, n+1):
        senha = input(f"Senha {i}: ")
        motivos = validar_senha(senha, dia, dia_sem_zero, mes, mes_sem_zero, ano, ano2)
        if not motivos:
            print(f"Senha {i}: válida.")
        else:
            print(f"Senha {i}: inválida. Motivos:")
            for m in motivos:
                print("-", m)

if __name__ == "__main__":
    main()

Exercícios relacionados