From 95e9018472fa8f6cc6e3ff04e634c3b23ca97eba Mon Sep 17 00:00:00 2001 From: Marek Mazij <112333347+Mrk-Mzj@users.noreply.github.com> Date: Mon, 16 Oct 2023 21:50:16 +0200 Subject: [PATCH 1/5] feat: Polish ID (PESEL) checker added --- strings/is_polish_national_id.py | 95 ++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 strings/is_polish_national_id.py diff --git a/strings/is_polish_national_id.py b/strings/is_polish_national_id.py new file mode 100644 index 000000000000..b75812a7677c --- /dev/null +++ b/strings/is_polish_national_id.py @@ -0,0 +1,95 @@ +def is_polish_national_id(input_str: str) -> bool: + """ + Verification of the correctness of the PESEL number. + www-gov-pl.translate.goog/web/gov/czym-jest-numer-pesel?_x_tr_sl=auto&_x_tr_tl=en + + PESEL can start with 0, that's why we take str as input, + but convert it to int for some calculations. + + + >>> is_polish_national_id(123) + Traceback (most recent call last): + ... + ValueError: Expected str as input, found + + >>> is_polish_national_id("abc") + Traceback (most recent call last): + ... + ValueError: Expected number as input + + >>> is_polish_national_id("02070803628") # correct PESEL + True + + >>> is_polish_national_id("02150803629") # wrong month + False + + >>> is_polish_national_id("02075503622") # wrong day + False + + >>> is_polish_national_id("-99012212349") # wrong range + False + + >>> is_polish_national_id("990122123499999") # wrong range + False + + >>> is_polish_national_id("02070803621") # wrong checksum + False + """ + + # check for invalid input type + if not isinstance(input_str, str): + msg = f"Expected str as input, found {type(input_str)}" + raise ValueError(msg) + + # check if input can be converted to int + try: + input_int = int(input_str) + except ValueError: + msg = "Expected number as input" + raise ValueError(msg) + + # check number range + if input_int < 10100000 or input_int > 99923199999: + return False + + # check month corectness + month = int(input_str[2:4]) + + if ( + month not in range(1, 13) # year 1900-1999 + and month not in range(21, 33) # 2000-2099 + and month not in range(41, 53) # 2100-2199 + and month not in range(61, 73) # 2200-2299 + and month not in range(81, 93) # 1800-1899 + ): + return False + + # check day corectness + day = int(input_str[4:6]) + + if day not in range(1, 32): + return False + + # check the checksum + multipliers = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3] + sum = 0 + + digits_to_check = str(input_str)[:-1] # cut off the checksum + + for index, digit in enumerate(digits_to_check): + # Multiply corresponding digits and multipiers. + # In case of a double-digit result, add only the last digit. + sum += (int(digit) * multipliers[index]) % 10 + + checksum = 10 - sum % 10 + + if checksum != input_int % 10: + return False + + return True + + +if __name__ == "__main__": + from doctest import testmod + + testmod() From 3e2fea33d05431117c3fd5f40c6d90b214b25efc Mon Sep 17 00:00:00 2001 From: Marek Mazij <112333347+Mrk-Mzj@users.noreply.github.com> Date: Mon, 16 Oct 2023 22:14:26 +0200 Subject: [PATCH 2/5] refactor: 'sum' variable renamed to 'subtotal' --- strings/is_polish_national_id.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/strings/is_polish_national_id.py b/strings/is_polish_national_id.py index b75812a7677c..40bb5ab0dd11 100644 --- a/strings/is_polish_national_id.py +++ b/strings/is_polish_national_id.py @@ -72,16 +72,16 @@ def is_polish_national_id(input_str: str) -> bool: # check the checksum multipliers = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3] - sum = 0 + subtotal = 0 digits_to_check = str(input_str)[:-1] # cut off the checksum for index, digit in enumerate(digits_to_check): # Multiply corresponding digits and multipiers. # In case of a double-digit result, add only the last digit. - sum += (int(digit) * multipliers[index]) % 10 + subtotal += (int(digit) * multipliers[index]) % 10 - checksum = 10 - sum % 10 + checksum = 10 - subtotal % 10 if checksum != input_int % 10: return False From 9dca50bed36bdd79c453db9039d033bbae4ca660 Mon Sep 17 00:00:00 2001 From: Marek Mazij <112333347+Mrk-Mzj@users.noreply.github.com> Date: Mon, 16 Oct 2023 22:23:02 +0200 Subject: [PATCH 3/5] style: typos --- strings/is_polish_national_id.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/strings/is_polish_national_id.py b/strings/is_polish_national_id.py index 40bb5ab0dd11..caa7808efd90 100644 --- a/strings/is_polish_national_id.py +++ b/strings/is_polish_national_id.py @@ -52,7 +52,7 @@ def is_polish_national_id(input_str: str) -> bool: if input_int < 10100000 or input_int > 99923199999: return False - # check month corectness + # check month correctness month = int(input_str[2:4]) if ( @@ -64,7 +64,7 @@ def is_polish_national_id(input_str: str) -> bool: ): return False - # check day corectness + # check day correctness day = int(input_str[4:6]) if day not in range(1, 32): @@ -77,7 +77,7 @@ def is_polish_national_id(input_str: str) -> bool: digits_to_check = str(input_str)[:-1] # cut off the checksum for index, digit in enumerate(digits_to_check): - # Multiply corresponding digits and multipiers. + # Multiply corresponding digits and multipliers. # In case of a double-digit result, add only the last digit. subtotal += (int(digit) * multipliers[index]) % 10 From ebac50e1fbffdb35123586488211b5ab64086271 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Tue, 17 Oct 2023 20:19:42 +0200 Subject: [PATCH 4/5] Apply suggestions from code review --- strings/is_polish_national_id.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/strings/is_polish_national_id.py b/strings/is_polish_national_id.py index caa7808efd90..888cb0a7b567 100644 --- a/strings/is_polish_national_id.py +++ b/strings/is_polish_national_id.py @@ -49,7 +49,8 @@ def is_polish_national_id(input_str: str) -> bool: raise ValueError(msg) # check number range - if input_int < 10100000 or input_int > 99923199999: + if not 10100000 <= input_int <= 99923199999: + return False # check month correctness @@ -83,10 +84,7 @@ def is_polish_national_id(input_str: str) -> bool: checksum = 10 - subtotal % 10 - if checksum != input_int % 10: - return False - - return True + return checksum == input_int % 10 if __name__ == "__main__": From 5e79f4f4d42778d371fb7b353c9f62126bc7c7db Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 18:20:16 +0000 Subject: [PATCH 5/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- strings/is_polish_national_id.py | 1 - 1 file changed, 1 deletion(-) diff --git a/strings/is_polish_national_id.py b/strings/is_polish_national_id.py index 888cb0a7b567..8b463a24532a 100644 --- a/strings/is_polish_national_id.py +++ b/strings/is_polish_national_id.py @@ -50,7 +50,6 @@ def is_polish_national_id(input_str: str) -> bool: # check number range if not 10100000 <= input_int <= 99923199999: - return False # check month correctness