5
respostas

Separar CPF e CNH

Boa tarde galera, beleza?

Gente, to procurando algumas ideias aqui... se puderem me ajudar, fico muito agradecido. Conforme o código abaixo, estou fazendo um gerador de CPF e CNPJ no Pycharm, porém, ao tentar fazer uma classe de gerar CNH dá pau pois esta e o CPF possuem a mesma quantidade de caracteres.

Já tentei uma porrada de coisas e nada deu certo. Alguém aí teria alguma ideia de como resolver isso?

Muito obrigado!

from validate_docbr import CPF, CNPJ, CNH

class Documento:

@staticmethod
def cria_documento(documento):
    if len(documento) == 11:
        return DocCpf(documento)
    elif len(documento) == 12:
        return DocCnh(documento)
    elif len(documento) == 14:
        return DocCnpj(documento)
    else:
        raise ValueError("Quantidade de dígitos é inválida")

class DocCpf:

def __init__(self, documento):
    if self.valida(documento):
        self.cpf = documento
    else:
        raise ValueError("CPF inválido")

def __str__(self):
    return self.format()

def valida(self, documento):
    validador = CPF()
    return validador.validate(documento)

def format(self):
    mascara = CPF()
    return mascara.mask(self.cpf)

class DocCnpj:

def __init__(self, documento):
    if self.valida(documento):
        self.cnpj = documento
    else:
        raise ValueError("CNPJ inválido")

def __str__(self):
    return self.format()

def valida(self, documento):
    validador = CNPJ()
    return validador.validate(documento)

def format(self):
    mascara = CNPJ()
    return mascara.mask(self.cnpj)

class DocCnh:

def __init__(self, documento):
    if self.valida(documento):
        self.cnh = documento
    else:
        ValueError("CNH inválida")

def __str__(self):
    return self.format()

def valida(self, documento):
    validador = CNH()
    return validador.validate(documento)

def format(self):
    mascara = CNH()
    return mascara.mask(self.cnh)
5 respostas

Boa Tarde Felipe,

Tenho duas opções, uma delas é passar um argumento na função com o tipo de documento, isso evitaria qualquer outra forma de validação.

Outra opção que consegui pensar seria mudar um pouco o formato das suas classes e validar os documentos antes de criar algo do tipo:

def cria_documento(documento):

    validador = CPF()
    if validador.validate(documento):
        return DocCpf(documento)

    validador =CNH()
    if validador.validate(documento):
        return DocCnh(documento)

    validador = CNPJ()
    if validador.validate(documento):
        return DocCnpj(documento)

    else:
        raise ValueError("Documento não é válido")

Dividi em dois posts para não ficar muito grande. Mas outra coisa que talvez te ajudaria é utilizar uma classe abstrata de Documento e fazendo com que os outros documentos criados herdassem dessa classe principal. Você poderia fazer isso da seguinte forma:

class Documento:

    def __str__(self):
        return self.format()

    def valida(self, documento):
        if self.tipo_doc.validate(documento):
            print('ok')
            self.documento = documento
        else:
            ValueError("CNH inválida")


    def format(self):
        return self.tipo_doc.mask(self.cnh)
class docCNH(Documento):

    def __init__(self, documento, tipo):
        self.tipo_doc = tipo()
        self.valida(documento)

class docCNPJ(Documento):

    def __init__(self, documento, tipo):
        self.tipo_doc = tipo()
        self.valida(documento)

class docCPF(Documento):

    def __init__(self, documento, tipo):
        self.tipo_doc = tipo()
        self.valida(documento)

O argumento tipo seria a classe do tipo de documento que você está passando, no seu caso você passaria CNH, CPF e CNPJ.

Com esse novo formato o que você precisaria fazer pra criar um documento seria:

cnh = docCNH(1111, CNH)

E ela herda todos os métodos de Documento, então sempre que você quiser mudar adicionar um método a todos os documentos você adiciona nessa classe e se quiser adicionar métodos específicos para uma classe adicionaria direto nela.

Além disso, dessa forma você tem mais facilidade se quiser criar um novo tipo de documento no futuro.

Não sei se ficou muito claro, porém se tiver qualquer dúvida estou mais que disposto a seguir.

Opa Gabriel, beleza?

Muito obrigado pelas respostas.

Eu achei bem interessante e simples a primeira resposta.

Só não entendi muito bem a segunda parte...

class Documento:

def __str__(self):
    return self.format()

def valida(self, documento):
    if self.tipo_doc.validate(documento):
        print('ok')
        self.documento = documento
    else:
        ValueError("CNH inválida")


def format(self):
    return self.tipo_doc.mask(self.cnh)

Por que na classe Documento eu colocaria apenas 'CNH inválida'? Não deveria colocar métodos para o CPF e CNPJ também?

Opa Felipe perdão, esqueci desse CNH invalida, mas na verdade voce nao precisa adicionar todo um metodo pra dizer qual tipo de classe que avaliou erro, voce poderia ver literalmente type(self) e ele te retorna algo do tipo<class 'main.docCNH'> ou qualquer das classes de documento que tiver.

Ai se voce quiser poderia criar um if pra mandar um erro mais legivel. Ou tambem poderia simplesmente mandar o Value error como Documento Invalido.

Outra coisa que pensei agora, mas tecnicamente se voce usar o def cria_documento que eu passei ele nunca vai passar um documento invalido para a classe, porque o Documento foi validado antes mesmo de ter sido criado, e se foi criado é porque esta valido. Entao voce nao precisaria nem verificar isso nos inits das classes.