I have to write an exercise, of a credit card number validator, in which in one of the instances it must be verified if there are 3 consecutive equal numbers and return false
in that case. The code so far goes like this:
num = input("Ingrese el numero de la tarjeta: ")
def validador():
if tiene19() == True and empiezacon456() == True and gruposde4() == True and consecutivos() == True:
return True
def tiene19():
if len(num) == 19:
return True
def empiezacon456():
if num.startswith ("4" or "5" or "6"):
return True
def gruposde4(*args):
numsep = num.replace("-", " ")
numsplit = numsep.split()
if len(numsplit) == 4:
return True
def consecutivos(*args):
for digit in num:
and there I stayed. The other validations do not matter if they are correct or not, I will correct it little by little, but I cannot find one (or some) string methods that allow me to verify if there are 3 equal consecutive numbers.
Your code can be greatly simplified by starting with the first condition:
Remember that since there is no comparison sign, python by default will evaluate if the condition is true, so we can write:
Also if we do a comparison it
True==algo
will return the boolean result of the comparison, using this concept we can further shorten the following 2 functions.Now moving on to your real problem, what you are looking for is not anything complicated or out of this world, it is simply to go through a chain and verify its next 3 positions. For this case I've used a loop
while
to iterate through the string and then just check the next 3 positions, that's it.In the first part of the validation
f"{n*3}"
we only use a property of the strings, that when it comes to operating with a multiplication the string is repeated n times, so when we do itn*3
we are repeating the string 3 times, which by the way could be left in alonen*3
(no need to put it in an f-string). The second part we only access the next 3 positions and with the help of the f-strings we join each of the results, it's like doingstr(num[i+1])+str(num[i+2])+str(num[i+3])
. But sincenum
it is a string we can easily concatenate it without the need for f-strings, leaving it like thisnum[i+1]+num[i+2]+num[i+3]
. But... we can still do better, we can use slicing whose syntax iscadena[inicio:fin:paso]
, which allows us to donum[i: i+3]
what translates to that of the variablenum
just grab what is in positioni
to positioni+3
. With all this, the code would look like this:By the way, I would recommend that all functions receive
num
as an argument, so you avoid some problems and the code becomes easier to read and debug.You can make use of regular expressions. The only thing you need is a string in which you capture a character and check that it is repeated two more times, that is:
(\d)\1{2}
This regex looks for a digit
\d
, saves it in a reference by putting the parentheses, and looks for that same digit next (the reference\1
) repeated exactly 2 times{2}
If you want to remove the cases where there are more than 3 repetitions you can do it with
(\d)\1{3}
With all this you can build a function that returns True when the first regex is found but not the second:
A simple alternative, without regular expressions or anything complicated:
It simply loops through the number comparing each digit to the previous two. If they are equal, return immediately with
True
show
produces:
A regex option:
[!] I think with a bit of research you could put the entire card validation into a regex . However, another person below mentions that a regex should not be used to validate the entire card. But if it can be used to validate in parts, just like your question.