mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-23 21:11:08 +00:00
feat: Polish ID (PESEL) checker added (#10618)
* feat: Polish ID (PESEL) checker added * refactor: 'sum' variable renamed to 'subtotal' * style: typos * Apply suggestions from code review * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: Christian Clauss <cclauss@me.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
09c2b2d006
commit
9de1c49fe1
92
strings/is_polish_national_id.py
Normal file
92
strings/is_polish_national_id.py
Normal file
|
@ -0,0 +1,92 @@
|
|||
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 <class 'int'>
|
||||
|
||||
>>> 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 not 10100000 <= input_int <= 99923199999:
|
||||
return False
|
||||
|
||||
# check month correctness
|
||||
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 correctness
|
||||
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]
|
||||
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 multipliers.
|
||||
# In case of a double-digit result, add only the last digit.
|
||||
subtotal += (int(digit) * multipliers[index]) % 10
|
||||
|
||||
checksum = 10 - subtotal % 10
|
||||
|
||||
return checksum == input_int % 10
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from doctest import testmod
|
||||
|
||||
testmod()
|
Loading…
Reference in New Issue
Block a user