How to Validate a Regex PIN Code in Python

The challenge

ATM machines allow 4 or 6 digit PIN codes and PIN codes cannot contain anything but exactly 4 digits or exactly 6 digits.

If the function is passed a valid PIN string, return true, else return false.

Examples

"1234" --> true "12345" --> false "a234" --> false
Code language: JavaScript (javascript)

The solution in Python code

Option 1:

def validate_pin(pin): return len(pin) in (4, 6) and pin.isdigit()
Code language: Python (python)

Option 2:

import re def validate_pin(pin): return bool(re.fullmatch("\d{4}|\d{6}", pin))
Code language: Python (python)

Option 3:

def validate_pin(pin): import re if len(pin) == 4 or len(pin) == 6: #not 4 or 6 digits if re.search('[^0-9]', pin) == None : #contains non-digit chars return True return False
Code language: Python (python)

Test cases to validate our solution

import test from solution import validate_pin @test.describe("Fixed Tests") def fixed_tests(): @test.it("should return False for pins with length other than 4 or 6") def basic_test_cases(): test.assert_equals(validate_pin("1"),False, "Wrong output for '1'") test.assert_equals(validate_pin("12"),False, "Wrong output for '12'") test.assert_equals(validate_pin("123"),False, "Wrong output for '123'") test.assert_equals(validate_pin("12345"),False, "Wrong output for '12345'") test.assert_equals(validate_pin("1234567"),False, "Wrong output for '1234567'") test.assert_equals(validate_pin("-1234"),False, "Wrong output for '-1234'") test.assert_equals(validate_pin("-12345"),False, "Wrong output for '-12345'") test.assert_equals(validate_pin("1.234"),False, "Wrong output for '1.234'") test.assert_equals(validate_pin("00000000"),False, "Wrong output for '00000000'") @test.it("should return False for pins which contain characters other than digits") def _(): test.assert_equals(validate_pin("a234"),False, "Wrong output for 'a234'") test.assert_equals(validate_pin(".234"),False, "Wrong output for '.234'") @test.it("should return True for valid pins") def _(): test.assert_equals(validate_pin("1234"),True, "Wrong output for '1234'") test.assert_equals(validate_pin("0000"),True, "Wrong output for '0000'") test.assert_equals(validate_pin("1111"),True, "Wrong output for '1111'") test.assert_equals(validate_pin("123456"),True, "Wrong output for '123456'") test.assert_equals(validate_pin("098765"),True, "Wrong output for '098765'") test.assert_equals(validate_pin("000000"),True, "Wrong output for '000000'") test.assert_equals(validate_pin("123456"),True, "Wrong output for '123456'") test.assert_equals(validate_pin("090909"),True, "Wrong output for '090909'") @test.it("should handle edge cases") def _(): tests = [ '', '123', '12345', '1234567', '1234567890', '1234x', '123456x', '12.0', '1234.0', '123456.0', '123\n', '1234\n', '09876\n', '098765\n', '-111', '111-', '-44444', '44444-', '+111', '+88888', '+1111', '-2018', '+234567', '-234567', '123/', '456:', '\xbe', # "three quarters" in Python 3, just some byte in Python 2 ] for s in tests: test.assert_equals(validate_pin(s), False, "Wrong output for '{}'".format(s)) @test.describe("should work with random input") def random_tests(): from random import randint, choice from string import ascii_letters, punctuation, digits all_chars = ascii_letters + punctuation + digits def solution(pin): return len(pin) in (4, 6) and pin.isdigit() def rand_valid_pin(): length = 4 if randint(0, 1) else 6 return "".join(choice(digits) for _ in range(length)) def rand_pin(): return "".join(choice(all_chars) for _ in range(randint(0, 10))) for _ in range(40): pin = rand_pin() if randint(0, 1) else rand_valid_pin() @test.it(f"testing for validate_pin({pin})") def test_case(): test.assert_equals(validate_pin(pin),solution(pin))
Code language: Python (python)
Tags:
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments