lists.arthurdejong.org
RSS feed

python-stdnum branch master updated. 1.1-21-g36217ac

[Date Prev][Date Next] [Thread Prev][Thread Next]

python-stdnum branch master updated. 1.1-21-g36217ac



This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "python-stdnum".

The branch, master has been updated
       via  36217ac8d09f0de594b1ba9b17b435329c16548c (commit)
       via  a0cb61f7b1718b93e583e749c1483f0c6a5bdc3a (commit)
      from  5ab8d24c44924de2a3d4e61469f2cefa98378cdf (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://arthurdejong.org/git/python-stdnum/commit/?id=36217ac8d09f0de594b1ba9b17b435329c16548c

commit 36217ac8d09f0de594b1ba9b17b435329c16548c
Author: Dariusz Choruzy <darobial@gmail.com>
Date:   Mon Sep 7 00:53:57 2015 +0200

    Add Polish REGON number

diff --git a/stdnum/pl/regon.py b/stdnum/pl/regon.py
new file mode 100644
index 0000000..5099b55
--- /dev/null
+++ b/stdnum/pl/regon.py
@@ -0,0 +1,95 @@
+# pesel.py - functions for handling REGON numbers
+# coding: utf-8
+#
+# Copyright (C) 2015 Dariusz Choruzy
+# Copyright (C) 2015 Arthur de Jong
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 USA
+
+"""REGON (Rejestr Gospodarki Narodowej, Polish register of economic units).
+
+The REGON (Rejestr Gospodarki Narodowej) is a statistical identification
+number for businesses. National entities are assigned a 9-digit number, while
+local units append 5 digits to form a 14-digit number.
+
+More information can be found at:
+  http://bip.stat.gov.pl/en/regon/
+  http://www.stat.gov.pl/bip/regon_ENG_HTML.htm
+  https://wyszukiwarkaregon.stat.gov.pl/appBIR/index.aspx
+
+>>> validate('192598184')
+'192598184'
+>>> validate('123456785')
+'123456785'
+>>> validate('192598183')
+Traceback (most recent call last):
+    ...
+InvalidChecksum: ...
+>>> validate('12345678512347')
+'12345678512347'
+>>> validate('12345678612342')  # first check digit invalid
+Traceback (most recent call last):
+    ...
+InvalidChecksum: ...
+>>> validate('12345678512348')  # last check digit invalid
+Traceback (most recent call last):
+    ...
+InvalidChecksum: ...
+"""
+
+from stdnum.exceptions import *
+from stdnum.util import clean
+
+
+def compact(number):
+    """Convert the number to the minimal representation. This strips the
+    number of any valid separators and removes surrounding whitespace."""
+    return clean(number, ' -').upper().strip()
+
+
+def calc_check_digit(number):
+    """Calculate the check digit for organisations. The number passed
+    should not have the check digit included."""
+    if len(number) == 8:
+        weights = (8, 9, 2, 3, 4, 5, 6, 7)
+    else:
+        weights = (2, 4, 8, 5, 0, 9, 7, 3, 6, 1, 2, 4, 8)
+    check = sum(weights[i] * int(n) for i, n in enumerate(number))
+    return str(check % 11 % 10)
+
+
+def validate(number):
+    """Checks to see if the number provided is a valid REGON number. This
+    checks the length, formatting and check digit."""
+    number = compact(number)
+    if not number.isdigit():
+        raise InvalidFormat()
+    if len(number) not in (9, 14):
+        raise InvalidLength()
+    if number[-1] != calc_check_digit(number[:-1]):
+        raise InvalidChecksum()
+    if len(number) == 14 and number[8] != calc_check_digit(number[:8]):
+        raise InvalidChecksum()
+    return number
+
+
+def is_valid(number):
+    """Checks to see if the number provided is a valid REGON number. This
+    checks the length, formatting and check digit."""
+    try:
+        return bool(validate(number))
+    except ValidationError:
+        return False
diff --git a/tests/test_pl_regon.doctest b/tests/test_pl_regon.doctest
new file mode 100644
index 0000000..ecd4f69
--- /dev/null
+++ b/tests/test_pl_regon.doctest
@@ -0,0 +1,104 @@
+test_pl_regon.doctest - more detailed doctests for the stdnum.pl.regon module
+
+Copyright (C) 2015 Arthur de Jong
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA
+
+
+This file contains more detailed doctests for the stdnum.pl.regon module. It
+tries to validate a number of numbers that have been found online.
+
+>>> from stdnum.pl import regon
+>>> from stdnum.exceptions import *
+
+
+These have been found online and should all be valid numbers.
+
+>>> numbers = '''
+...
+... 000144992
+... 000262289
+... 000569734
+... 001123710
+... 001130740
+... 001130762
+... 001130785
+... 004611261
+... 010925233
+... 011370116
+... 015615046
+... 015831301
+... 017282442
+... 021425170
+... 021493503
+... 061245300
+... 080121017
+... 101286521
+... 101624716
+... 101702037
+... 120444729
+... 120812966
+... 122903064
+... 122989806
+... 140006787
+... 140124720
+... 140567178
+... 140906290
+... 141215688
+... 147244188
+... 160178314
+... 180405830
+... 180562050
+... 190248215
+... 190384415
+... 191305139
+... 192976380
+... 200197338
+... 220218697
+... 221997249
+... 241675487
+... 271747631
+... 276273209
+... 280002520
+... 292449593
+... 300613124
+... 302406613
+... 357126121
+... 360935507
+... 362392991
+... 362501144
+... 362509447
+... 362509460
+... 362509476
+... 362523660
+... 370418951
+... 370452988
+... 432740426
+... 570007868
+... 570135170
+... 570271370
+... 570860528
+... 572134252
+... 630679076
+... 632154969
+... 634389910
+... 670141210
+... 810033277
+... 812663628
+...
+... '''
+>>> [x for x in numbers.splitlines() if x and not regon.is_valid(x)]
+[]

http://arthurdejong.org/git/python-stdnum/commit/?id=a0cb61f7b1718b93e583e749c1483f0c6a5bdc3a

commit a0cb61f7b1718b93e583e749c1483f0c6a5bdc3a
Author: Dariusz Choruzy <darobial@gmail.com>
Date:   Sun Sep 6 04:57:36 2015 +0200

    Add Polish PESEL number

diff --git a/stdnum/pl/pesel.py b/stdnum/pl/pesel.py
new file mode 100644
index 0000000..4fcb490
--- /dev/null
+++ b/stdnum/pl/pesel.py
@@ -0,0 +1,121 @@
+# pesel.py - functions for handling Polish national identification numbers
+# coding: utf-8
+#
+# Copyright (C) 2015 Dariusz Choruzy
+# Copyright (C) 2015 Arthur de Jong
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 USA
+
+"""PESEL (Polish national identification number).
+
+The Powszechny Elektroniczny System Ewidencji LudnoĊ›ci (PESEL, Universal
+Electronic System for Registration of the Population) is a 11-digit Polish
+national identification number. The number consists of the date of birth,
+a serial number, the person's gender and a check digit.
+
+
+>>> validate('44051401359')
+'44051401359'
+>>> validate('44051401358')  # incorrect check digit
+Traceback (most recent call last):
+    ...
+InvalidChecksum: ...
+>>> validate('02381307589')  # invalid birth date
+Traceback (most recent call last):
+    ...
+InvalidComponent: ...
+>>> get_birth_date('02122401358')
+datetime.date(1902, 12, 24)
+>>> get_gender('02122401358')
+'M'
+>>> get_birth_date('02211307589')
+datetime.date(2002, 1, 13)
+>>> get_gender('02211307589')
+'F'
+"""
+
+import datetime
+
+from stdnum.exceptions import *
+from stdnum.util import clean
+
+
+def compact(number):
+    """Convert the number to the minimal representation. This strips the
+    number of any valid separators and removes surrounding whitespace."""
+    return clean(number, ' -').upper().strip()
+
+
+def get_birth_date(number):
+    """Split the date parts from the number and return the birth date."""
+    number = compact(number)
+    year = int(number[0:2])
+    month = int(number[2:4])
+    day = int(number[4:6])
+    year += {
+        0: 1900,
+        1: 2000,
+        2: 2100,
+        3: 2200,
+        4: 1800,
+    }[month // 20]
+    month = month % 20
+    try:
+        return datetime.date(year, month, day)
+    except ValueError:
+        raise InvalidComponent()
+
+
+def get_gender(number):
+    """Get the person's birth gender ('M' or 'F')."""
+    number = compact(number)
+    if number[9] in '02468':  # even
+        return 'F'
+    else:  # odd: 13579
+        return 'M'
+
+
+def calc_check_digit(number):
+    """Calculate the check digit for organisations. The number passed
+    should not have the check digit included."""
+    weights = (1, 3, 7, 9, 1, 3, 7, 9, 1, 3)
+    check = sum(weights[i] * int(n) for i, n in enumerate(number))
+    return str((10 - check) % 10)
+
+
+def validate(number):
+    """Checks to see if the number provided is a valid
+    national identification number. This checks the length,
+    formatting and check digit."""
+    number = compact(number)
+    if not number.isdigit():
+        raise InvalidFormat()
+    if len(number) != 11:
+        raise InvalidLength()
+    if number[-1] != calc_check_digit(number[:-1]):
+        raise InvalidChecksum()
+    get_birth_date(number)
+    return number
+
+
+def is_valid(number):
+    """Checks to see if the number provided is a valid
+    national identification number. This checks the length,
+    formatting and check digit."""
+    try:
+        return bool(validate(number))
+    except ValidationError:
+        return False

-----------------------------------------------------------------------

Summary of changes:
 stdnum/{ee/ik.py => pl/pesel.py} |   96 +++++++++++++++++++----------------
 stdnum/pl/regon.py               |   95 ++++++++++++++++++++++++++++++++++
 tests/test_pl_regon.doctest      |  104 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 251 insertions(+), 44 deletions(-)
 copy stdnum/{ee/ik.py => pl/pesel.py} (51%)
 create mode 100644 stdnum/pl/regon.py
 create mode 100644 tests/test_pl_regon.doctest


hooks/post-receive
-- 
python-stdnum
-- 
To unsubscribe send an email to
python-stdnum-commits-unsubscribe@lists.arthurdejong.org or see
http://lists.arthurdejong.org/python-stdnum-commits/