Place only the correct message print once

1

I'm doing this program:

  

Develop a program that asks you to enter a CPF number   in the format xxx.xxx.xxx-xx and indicate if it is a valid or invalid number through   verification 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 run the output it is this:

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?

    
asked by anonymous 28.06.2018 / 12:56

4 answers

2

You do not need to loop there. Since you are already checking the . and - characters using the string positions (ie cpf[3] != "" ), the loop 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")
    
28.06.2018 / 13:05
1

You are traversing each character of the CPF and displaying the message for each. If the CPF is 14 characters, the message will appear 14 times. This does not even make sense. In addition, the validation of the CPF goes far beyond just verifying the formatting. The last two digits are verifiers 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 validate function will validate the verification 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 at Repl.it | Ideone

    
28.06.2018 / 13:56
0

In your code, for each correct character, it does print, so the program should print only when the entire CPF has been validated, 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.
    
28.06.2018 / 13:18
-1

Dude, I would do the following (I'm a beginner too, I do not 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")
    
28.06.2018 / 13:04