Only put the correct message print once

Asked

Viewed 685 times

0

I’m doing this show:

Develop a program that requires typing of a CPF number in format xxx.xxx.xxx-xx and indicate if it is a valid or invalid number via validation of check digits and formatting characters.

The code is this:

pf = input("CPF(xxx.xxx.xxx-xx) :") #3 7 11

for letra in cpf:
    if(cpf[3] !=".") or (cpf[7] !=".") or (cpf[11] !="-"):
        cpf = input("O 'CPF' pricisa estar no formato (xxx.xxx.xxx-xx) :")
    else:
        print("O 'CPF' está no formato correto")

But when I say run, this is the way out:

O 'CPF' está no formato correto
O 'CPF' está no formato correto
O 'CPF' está no formato correto
O 'CPF' está no formato correto
O 'CPF' está no formato correto
O 'CPF' está no formato correto
O 'CPF' está no formato correto
O 'CPF' está no formato correto
O 'CPF' está no formato correto
O 'CPF' está no formato correto
O 'CPF' está no formato correto
O 'CPF' está no formato correto
O 'CPF' está no formato correto
O 'CPF' está no formato correto

How can I just go out once?

4 answers

1

No need to loop ai. As you are already checking the characters . and - using the positions of the string (e. g cpf[3] != ""), the cycle seems unnecessary.

cpf = input("CPF(xxx.xxx.xxx-xx) :") #3 7 11

if(cpf[3] !=".") or (cpf[7] !=".") or (cpf[11] !="-"):
    cpf = input("O 'CPF' pricisa estar no formato (xxx.xxx.xxx-xx) :")
else:
    print("O 'CPF' está no formato correto")
  • That way, the system would request the CPF again only once, try to exchange the if for while

  • 1

    Actually the CPF check goes beyond that. The last two digits are the check digits and it is necessary to validate them.

  • @Nathanschroeder I understand, yes, it makes more sense then to be a while until validation passes. @Andersoncarloswoss I am not familiar with CPF, but I understand the validation that is required. I just used the original code example.

  • In fact, for your solution the input ...........-.. would be a valid CPF: https://ideone.com/JktKch

  • True! I didn’t even confirm that the code was validating correctly, I just noticed that the cause of the repetition was the cycle for each letter, but then it wasn’t even used correctly. Despite everything, I voted for the answer with the most appropriate solution, this one I don’t know why has an upvote.

1

You are scrolling through each character of the CPF and displaying the message to each one. If the CPF has 14 characters, the message will appear 14 times. It doesn’t even make sense to do so. In addition, the CPF validation goes far beyond just checking the formatting. The last two digits are checkers and you need to validate them. See:

So what you need to do is something like:

try:
    cpf = input('Informe o CPF: ')
    assert validate(cpf), 'O CPF informado não é válido'
    print('CPF válido')
except AssertionError as error:
    print(error)

Where the function validate validate the check digits:

def validate(cpf: str) -> bool:

    """ Efetua a validação do CPF, tanto formatação quanto dígitos verificadores.

    Parâmetros:
        cpf (str): CPF a ser validado

    Retorno:
        bool:
            - Falso, quando o CPF não possuir o formato 999.999.999-99;
            - Falso, quando o CPF não possuir 11 caracteres numéricos;
            - Falso, quando os dígitos verificadores forem inválidos;
            - Verdadeiro, caso contrário.

    Exemplos:

    >>> validate('529.982.247-25')
    True
    >>> validate('52998224725')
    False
    >>> validate('111.111.111-11')
    False
    """

    # Verifica a formatação do CPF
    if not re.match(r'\d{3}\.\d{3}\.\d{3}-\d{2}', cpf):
        return False

    # Obtém apenas os números do CPF, ignorando pontuações
    numbers = [int(digit) for digit in cpf if digit.isdigit()]

    # Verifica se o CPF possui 11 números:
    if len(numbers) != 11:
        return False

    # Validação do primeiro dígito verificador:
    sum_of_products = sum(a*b for a, b in zip(numbers[0:9], range(10, 1, -1)))
    expected_digit = (sum_of_products * 10 % 11) % 10
    if numbers[9] != expected_digit:
        return False

    # Validação do segundo dígito verificador:
    sum_of_products = sum(a*b for a, b in zip(numbers[0:10], range(11, 1, -1)))
    expected_digit = (sum_of_products * 10 % 11) % 10
    if numbers[10] != expected_digit:
        return False

    return True

See working on Repl.it | Ideone

-1

Man, I’d do this (I’m a beginner too, I don’t know if it’s the best way):

cpf = input("CPF(xxx.xxx.xxx-xx) :") #3 7 11

correto = False

for letra in cpf:
    if(cpf[3] !=".") or (cpf[7] !=".") or (cpf[11] !="-"):
        cpf = input("O 'CPF' pricisa estar no formato (xxx.xxx.xxx-xx) :")
    else:
        correto = True

if correto == True:
     print("O 'CPF' está no formato correto")
  • Correct, this code works, just need to add a checker to the numbers of the CPF, to validate if they are not letters, because then the program would accept a response like: foo.bar.abc-de

  • Actually the CPF check goes beyond that. The last two digits are the check digits and it is necessary to validate them.

  • Thank you so much for the information @Andersoncarloswoss , was not aware

  • @It doesn’t make sense for you to go through every digit of the number, so this loop is unnecessary. An indicative of this is that you have not even used the object letra within the loop.

-1

In its code, for each correct character, it prints, for this reason, the program must print only when the entire CPF has been validated, follows an example below:

def verificarNumeros(cpf): #FUNÇÃO QUE IRÁ VERIFICAR SE TODOS OS CARACTERES DO CPF, QUE NÃO SÃO "." NEM "-" SÃO NÚMEROS
    for posicao,caractere in enumerate(cpf): #PARA CADA ELEMENTO DENTRO DE cpf E SUA POSIÇÃO NA STRING
        if posicao!=3 and posicao!=7 and posicao!=11 and not caractere.isdigit(): #VERIFICANDO SE O CARÁCTER NÃO É UM NÚMERO
            return True #SE UM CARÁCTER NÃO FOR UM NÚMERO, ESSA FUNÇÃO IRÁ PARAR E RETORNAR UM VALOR "True" PARA O while DE VERIFICAÇÃO
    return False #CASO NÃO ENCONTRE NENHUM ERRO, IRÁ RETORNAR "False" PARA O while

cpf = input("CPF(xxx.xxx.xxx-xx) :") #3 7 11

while verificarNumeros(cpf) or cpf[3] !="." or cpf[7] !="." or cpf[11] !="-": #ENQUANTO O CPF NÃO FOR VÁLIDO, ELE IRÁ PERGUNTAR NOVAMENTE, POIS DO MODO QUE VOCÊ ESTAVA FAZENDO, ELE IRIA PERGUNTAR APENAS 13 VEZES, QUE É A QUANTIDADE DE ELEMENTOS DENTRO DE cpf, OU SEJA, SE O USUÁRIO INSISTISSE 14 VEZES NO ERRO, O PROGRAMA IRIA ACEITAR
    cpf = input("O 'CPF' pricisa estar no formato (xxx.xxx.xxx-xx) :")

print("O 'CPF' está no formato correto") #O PROGRAMA SÓ IRÁ CAIR AQUI QUANDO TODAS AS CONDIÇÕES DO WHILE FOREM FALSAS.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.