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)
1
resposta

[Sugestão] Validando um CPF

# Criado por: MLS ***.235.***-53
import sys
import re

SEPARADOR = "=" * 40


def validar_cpf(cpf):
    """
    Valida um CPF usando o algoritmo de verificação de dígitos.
    
    Args:
        cpf (str): CPF em formato string (com ou sem formatação).
        
    Returns:
        bool: True se CPF é válido, False caso contrário.
    """
    cpf = re.sub(r'\D', '', cpf)
    
    if len(cpf) != 11 or cpf == cpf[0] * 11:
        return False
    
    def calcular_digito(sequencia):
        soma = sum(int(d) * (len(sequencia) + 1 - i) for i, d in enumerate(sequencia))
        resto = soma % 11
        return 0 if resto < 2 else 11 - resto
    
    primeiro_digito = calcular_digito(cpf[:9])
    segundo_digito = calcular_digito(cpf[:10])
    
    return int(cpf[9]) == primeiro_digito and int(cpf[10]) == segundo_digito


def formatar_cpf(cpf):
    """Formata CPF para o padrão XXX.XXX.XXX-XX."""
    cpf = re.sub(r'\D', '', cpf)
    return f"{cpf[:3]}.{cpf[3:6]}.{cpf[6:9]}-{cpf[9:]}"


def obter_cpf(tentativas_max=3):
    """
    Solicita e valida CPF com tentativas limitadas.
    
    Args:
        tentativas_max (int): Número máximo de tentativas.
        
    Returns:
        str: CPF validado (apenas números).
    """
    tentativas = tentativas_max
    
    while tentativas > 0:
        try:
            cpf = input("Digite o CPF (ex: 123.456.789-00): ").strip()
            
            if validar_cpf(cpf):
                return re.sub(r'\D', '', cpf)
            
            print("CPF inválido.")
        except Exception as e:
            print(f"Erro: {str(e)}")
        
        tentativas -= 1
        if tentativas > 0:
            print(f"Você tem {tentativas} tentativas restantes.\n")
        else:
            print("Número de tentativas esgotado. Encerrando o programa.")
            sys.exit(1)


def exibir_resultado(cpf_numeros):
    """Exibe o resultado da validação."""
    cpf_formatado = formatar_cpf(cpf_numeros)
    print(f"\n{SEPARADOR}")
    print(f"CPF Válido: {cpf_formatado}")
    print(f"{SEPARADOR}\n")


def iniciar_sistema():
    """Executa o validador de CPF."""
    print(SEPARADOR)
    print("Validador de CPF")
    print(f"{SEPARADOR}\n")
    
    cpf = obter_cpf()
    exibir_resultado(cpf)


if __name__ == "__main__":
    iniciar_sistema()
1 resposta
solução!

Oi, como vai?

O seu projeto de validação de CPF ficou excelente e muito bem organizado. Dá para perceber o cuidado que você teve tanto com a estrutura do código quanto com a experiência do usuário. A separação em funções deixou o programa limpo, reutilizável e fácil de manter, além de demonstrar uma ótima compreensão sobre modularização em Python.

O uso da biblioteca re para remover caracteres não numéricos foi uma ótima escolha, assim como a implementação do algoritmo de cálculo dos dígitos verificadores utilizando sum() e enumerate(). Outro ponto muito interessante foi o tratamento de CPFs inválidos com todos os números iguais, algo que muitos esquecem de validar. Além disso, limitar o número de tentativas e utilizar sys.exit() trouxe mais controle e profissionalismo para a aplicação.

Também gostei bastante da preocupação com a legibilidade do código através das docstrings e constantes, como o SEPARADOR, pois isso aproxima bastante o projeto de boas práticas utilizadas no mercado.

Pensando na excelente estrutura que você desenvolveu, uma possibilidade interessante de aprimoramento seria transformar o projeto em um pequeno sistema de validação de documentos brasileiros, permitindo também validar CNPJ ou até aplicar máscaras automaticamente durante a digitação. Isso deixaria a aplicação ainda mais completa e ampliaria bastante as possibilidades do seu código.

Parabéns pelo excelente trabalho e por compartilhar uma solução tão completa e bem estruturada com a comunidade. Seu código demonstra muito capricho, preocupação com boas práticas e domínio crescente da linguagem Python. Continue participando do fórum e evoluindo cada vez mais nos seus projetos!