checkdigit
Advanced tools
@@ -21,5 +21,5 @@ # /usr/bin/env python | ||
| For more information, please look at the GitHub page for this library: | ||
| For more information, please look at the wiki page for this library: | ||
| https://checkdigit.rtfd.io/ | ||
| """ |
@@ -28,6 +28,11 @@ # /usr/bin/env python | ||
| def convert(digit: int, barcode: str = "isbn") -> str: | ||
| """Converts digits to strings and replaces 10.""" | ||
| def convert(digit: int, isbn: bool = True) -> str: | ||
| """Converts digits to strings and replaces 10 and 11. | ||
| Args: | ||
| digit: The code to be modified. | ||
| isbn: Whether the code is ISBN or not. | ||
| """ | ||
| if digit == 10: | ||
| return "X" if barcode == "isbn" else "0" | ||
| return "X" if isbn else "0" | ||
| return "0" if digit == 11 else str(digit) |
@@ -29,5 +29,3 @@ # /usr/bin/env python | ||
| # WARNING: Data beginning with 0 must be as a string due to PEP 3127 | ||
| def calculate(data: str, polynomial: str, pad: str = "0") -> str: | ||
@@ -34,0 +32,0 @@ """Adds a parity part onto the end of a block of data. |
+36
-13
@@ -16,4 +16,18 @@ # /usr/bin/env python | ||
| """GS1 Validation Functions.""" | ||
| """GS1 Standards. | ||
| This includes support for the following: | ||
| - GSIN | ||
| - GLN | ||
| - GRAI | ||
| - GTIN-8/12/13/14 | ||
| - EAN-8 | ||
| - EAN-13 | ||
| - UPC-A | ||
| - UPC-E | ||
| - SSCC | ||
| - etc. (all fixed length numeric GS1 data structures with a check digit) | ||
| """ | ||
| import math | ||
@@ -23,5 +37,3 @@ | ||
| # WARNING: Data beginning with 0 must be as a string due to PEP 3127 | ||
| def calculate(data: str) -> str: | ||
@@ -38,14 +50,19 @@ """Calculates GS1 Check Digit. | ||
| str: The check digit that was missing | ||
| Examples: | ||
| >>> from checkdigit import gs1 | ||
| >>> gs1.calculate("00199999980000110") | ||
| '7' | ||
| >>> gs1.calculate("67368623738347505") | ||
| '1' | ||
| """ | ||
| data = cleanse(data) | ||
| data = data[::-1] # Reverse the barcode, as last digit is always multiplied by 3 | ||
| total_sum = 0 | ||
| for index, value in enumerate(data): | ||
| if index % 2 == 0: | ||
| total_sum += int(value) * 3 | ||
| else: | ||
| total_sum += int(value) | ||
| next_multiple_of_ten = int(math.ceil(total_sum / 10.0)) * 10 | ||
| check_digit = next_multiple_of_ten - total_sum | ||
| return convert(check_digit, "gs1") | ||
| # Follows order 3, 1, 3, etc. | ||
| # Use ceil to ensure all digits of data are matched with a weight (round up division) | ||
| weights = (3, 1) * math.ceil(len(data) / 2) | ||
| # Multiply each digit by its weight | ||
| total_sum = sum(int(digit) * weight for digit, weight in zip(data, weights)) | ||
| # Return final check digit and type of barcode | ||
| return convert(10 - (total_sum % 10), False) | ||
@@ -66,4 +83,10 @@ | ||
| Examples: | ||
| >>> from checkdigit import gs1 | ||
| >>> gs1.validate("224245438987081447") | ||
| False | ||
| >>> gs1.validate("961552634342856982") | ||
| True | ||
| """ | ||
| data = cleanse(data) | ||
| # Data is cleansed by the calculate function | ||
| return calculate(data[:-1]) == data[-1] | ||
@@ -70,0 +93,0 @@ |
+44
-86
@@ -16,8 +16,7 @@ # /usr/bin/env python | ||
| """ISBN Validation Functions. | ||
| """International Standard Book Number. | ||
| ISBN codes are product identifiers used predominantly for books. | ||
| Support is provided for both ISBN-10 and ISBN-13. | ||
| Note that the ISBN-13 functions can also be used for EAN-13 and Bookland codes. | ||
| """ | ||
@@ -27,10 +26,8 @@ | ||
| # WARNING: Data beginning with 0 must be as a string due to PEP 3127 | ||
| def calculate(data: str) -> str: | ||
| """Calculates ISBN Check Digits. | ||
| def calculate10(data: str) -> str: | ||
| """Calculates ISBN-10 Check Digit. | ||
| Args: | ||
| data: A string of 9 characters | ||
| data: A string of characters representing an ISBN code without the check digit | ||
@@ -42,88 +39,54 @@ Returns: | ||
| >>> from checkdigit import isbn | ||
| >>> isbn.calculate10("006196436") | ||
| '0' | ||
| >>> isbn.calculate10("043942089") | ||
| >>> # ISBN-10 | ||
| >>> isbn.calculate("043942089") | ||
| 'X' | ||
| >>> # ISBN-13 | ||
| >>> isbn.calculate("978-1-86197-876") | ||
| '9' | ||
| """ | ||
| data = cleanse(data) | ||
| # Multiply first digit by 10, second by 9, ... and take the sum | ||
| total_sum = sum( | ||
| int(digit) * weight for digit, weight in zip(data, range(10, 0, -1)) | ||
| ) | ||
| return convert(11 - (total_sum % 11)) | ||
| if len(data) == 9: | ||
| # ISBN 10 (without the check digit) | ||
| # Multiply first digit by 10, second by 9, ... and take the sum | ||
| total_sum = sum( | ||
| int(digit) * weight for digit, weight in zip(data, range(10, 0, -1)) | ||
| ) | ||
| return convert(11 - (total_sum % 11)) | ||
| # elif not required since return above (and makes pylint happy) | ||
| if len(data) == 12: | ||
| # ISBN weights is 1 for odd positions and 3 for even | ||
| # Since there are 12 digits, multiply weights by 6 | ||
| weights = (1, 3) * 6 | ||
| # Multiply each digit by its weight | ||
| total_sum = sum(int(digit) * weight for digit, weight in zip(data, weights)) | ||
| # Return final check digit and type of barcode | ||
| return convert(10 - (total_sum % 10)) | ||
| return "Invalid" | ||
| def validate10(data: str) -> bool: | ||
| """Validates ISBN-10. | ||
| def validate(data: str) -> bool: | ||
| """Validates ISBN check digits. | ||
| Args: | ||
| data: A string of characters representing a full ISBN-10 code | ||
| data: A string of characters representing a fall ISBN code | ||
| Returns: | ||
| bool: A boolean representing whether the | ||
| check digit validates the data or not | ||
| check digit validates the data or non | ||
| Examples: | ||
| >>> from checkdigit import isbn | ||
| >>> isbn.validate10("1-56619-909-3") | ||
| >>> # ISBN-10 | ||
| >>> isbn.validate("0198526636") | ||
| True | ||
| >>> isbn.validate10("0198526636") | ||
| >>> # ISBN-13 | ||
| >>> isbn.validate("978-1-56619-909-4") | ||
| True | ||
| >>> isbn.validate10("423423") | ||
| False | ||
| """ | ||
| data = cleanse(data) | ||
| return calculate10(data[:-1]) == data[-1] | ||
| # The calculate method already cleanses the data. | ||
| # If the return result is 'Invalid', it won't match the check digit (hence false). | ||
| return calculate(data[:-1]) == data[-1] | ||
| def calculate13(data: str, barcode: str = "isbn") -> str: | ||
| """Calculates ISBN-13 Check Digit. | ||
| Args: | ||
| data: A string of 12 characters | ||
| barcode: The type of code (either isbn or upc) | ||
| Returns: | ||
| str: The check digit that was missing | ||
| Examples: | ||
| >>> from checkdigit import isbn | ||
| >>> isbn.calculate13("978-1-86197-876") | ||
| '9' | ||
| >>> isbn.calculate13("012345678912") | ||
| '8' | ||
| """ | ||
| data = cleanse(data) | ||
| # ISBN weights is 1 for odd positions and 3 for even | ||
| # The opposite is true for upc | ||
| weights = (1, 3) * 6 if barcode == "isbn" else (3, 1) * 6 | ||
| # Multiply each digit by its weight | ||
| total_sum = sum(int(digit) * weight for digit, weight in zip(data, weights)) | ||
| # Return final check digit and type of barcode | ||
| return convert(10 - (total_sum % 10), barcode) | ||
| def validate13(data: str) -> bool: | ||
| """Validates ISBN-13. | ||
| Args: | ||
| data: A string of characters representing a full ISBN-13 code | ||
| Returns: | ||
| bool: A boolean representing whether the check digit validates the data | ||
| Examples: | ||
| >>> from checkdigit import isbn | ||
| >>> isbn.validate13("978-1-56619-909-4") | ||
| True | ||
| >>> isbn.validate13("0123456789128") | ||
| True | ||
| >>> isbn.validate13("1234") | ||
| False | ||
| """ | ||
| data = cleanse(data) | ||
| return calculate13(data[:-1]) == data[-1] | ||
| def missing(data: str) -> str: | ||
@@ -141,4 +104,6 @@ """Calculates a missing digit in an ISBN Code represented by a question mark. | ||
| >>> from checkdigit import isbn | ||
| >>> # ISBN-10 | ||
| >>> isbn.missing("15688?111X") | ||
| '1' | ||
| >>> # ISBN-13 | ||
| >>> isbn.missing("978186197876?") | ||
@@ -149,8 +114,6 @@ '9' | ||
| """ | ||
| data = cleanse(data) | ||
| data_length = len(data) # ISBN-10 or 13 | ||
| # We already have an efficient method for the checkdigit | ||
| # We already have an efficient method for the check digit | ||
| if data[-1] == "?": | ||
| # Remove question mark check digit | ||
| return calculate10(data[:-1]) if data_length == 10 else calculate13(data[:-1]) | ||
| return calculate(data[:-1]) | ||
@@ -161,10 +124,5 @@ # We've dealt with the check digit, so X can't be an option | ||
| # Validate the new option | ||
| if ( | ||
| data_length == 10 | ||
| and validate10(option) | ||
| or data_length == 13 | ||
| and validate13(option) | ||
| ): | ||
| if validate(option): | ||
| # Replace question mark with new value | ||
| return option[data.index("?")] | ||
| return "Invalid" |
@@ -25,5 +25,3 @@ # /usr/bin/env python | ||
| # WARNING: Data beginning with 0 must be as a string due to PEP 3127 | ||
| def calculate(data: str) -> str: | ||
@@ -30,0 +28,0 @@ """Calculates the luhn check digit. |
@@ -24,5 +24,3 @@ # /usr/bin/env python | ||
| # WARNING: Data beginning with 0 must be as a string due to PEP 3127 | ||
| def calculate(data: str, even: bool = True) -> str: | ||
@@ -29,0 +27,0 @@ """Adds a parity bit onto the end of a block of data. |
+29
-123
| Metadata-Version: 2.1 | ||
| Name: checkdigit | ||
| Version: 0.2.0 | ||
| Version: 0.3.0 | ||
| Summary: A check digit library for data validation | ||
| Home-page: https://checkdigit.readthedocs.io | ||
| Home-page: https://checkdigit.rtfd.io | ||
| License: GPL-3.0-or-later | ||
| Keywords: Check Digits,Validation,ISBN | ||
| Keywords: Check Digits,Validation,ISBN,GS1,Luhn | ||
| Author: harens | ||
@@ -23,3 +23,3 @@ Author-email: harensdeveloper@gmail.com | ||
| Project-URL: Bug Tracker, https://github.com/harens/checkdigit/issues | ||
| Project-URL: Documentation, https://checkdigit.readthedocs.io | ||
| Project-URL: Documentation, https://checkdigit.rtfd.io | ||
| Project-URL: Repository, https://github.com/harens/checkdigit | ||
@@ -30,2 +30,3 @@ Description-Content-Type: text/x-rst | ||
| :alt: checkdigit logo | ||
| :target: https://github.com/harens/checkdigit | ||
| :align: center | ||
@@ -37,20 +38,26 @@ | ||
| :alt: GitHub Tests status | ||
| :target: https://github.com/harens/checkdigit/actions | ||
| .. image:: https://img.shields.io/codecov/c/github/harens/checkdigit?logo=codecov&style=flat-square | ||
| :alt: Codecov | ||
| :target: https://app.codecov.io/gh/harens/checkdigit | ||
| .. image:: https://img.shields.io/pypi/dm/checkdigit?logo=python&logoColor=white&style=flat-square | ||
| :alt: PyPi - Downloads | ||
| :target: https://pepy.tech/project/checkdigit | ||
| .. image:: https://img.shields.io/codefactor/grade/github/harens/checkdigit?logo=codefactor&style=flat-square | ||
| :alt: CodeFactor Grade | ||
| :target: https://www.codefactor.io/repository/github/harens/checkdigit/ | ||
| .. image:: https://img.shields.io/lgtm/grade/python/github/harens/checkdigit?logo=lgtm&style=flat-square | ||
| :alt: LGTM Grade | ||
| :target: https://lgtm.com/projects/g/harens/checkdigit/ | ||
| | | ||
| ========= | ||
| .. image:: https://raw.githubusercontent.com/harens/checkdigit/master/art/demo.gif | ||
| :alt: checkdigit example gif | ||
| :align: center | ||
| .. image:: https://repology.org/badge/vertical-allrepos/python:checkdigit.svg | ||
| :alt: checkdigit repology | ||
| :target: https://repology.org/project/python:checkdigit/versions | ||
| :align: right | ||
@@ -90,11 +97,14 @@ **checkdigit** is a pure Python library built for identification numbers. | ||
| * Even and odd binary parity | ||
| * Bookland | ||
| * CRC (credit to `@sapieninja <https://github.com/sapieninja>`_) | ||
| * EAN-13 | ||
| * GS1 (credit to `@OtherBarry <https://github.com/OtherBarry>`_) | ||
| * ISBN-10 | ||
| * ISBN-13 | ||
| * Luhn | ||
| * UPC-A | ||
| * `Even/Odd binary parity <https://checkdigit.readthedocs.io/en/latest/_autosummary/checkdigit.parity.html#module-checkdigit.parity>`_ | ||
| * `CRC <https://checkdigit.readthedocs.io/en/latest/_autosummary/checkdigit.crc.html#module-checkdigit.crc>`_ | ||
| (credit to `@sapieninja <https://github.com/sapieninja>`_) | ||
| * `GS1 Standards <https://checkdigit.readthedocs.io/en/latest/_autosummary/checkdigit.gs1.html#module-checkdigit.gs1>`_ (credit to `@OtherBarry <https://github.com/OtherBarry>`_) | ||
| * EAN-8/13 | ||
| * GDTI | ||
| * GLN | ||
| * SSCC | ||
| * UPC-A/E | ||
| * etc. *(all fixed length numeric GS1 data structures with a check digit)* | ||
| * `ISBN-10/13 <https://checkdigit.readthedocs.io/en/latest/_autosummary/checkdigit.isbn.html#module-checkdigit.isbn>`_ | ||
| * `Luhn <https://checkdigit.readthedocs.io/en/latest/_autosummary/checkdigit.luhn.html#module-checkdigit.luhn>`_ | ||
@@ -109,2 +119,3 @@ For each of these formats, we provide functions to validate them and calculate missing digits. | ||
| - Contributing Page: `<https://checkdigit.rtfd.io/en/latest/contributing.html>`_ | ||
| - Issue Tracker: `<https://github.com/harens/checkdigit/issues>`_ | ||
@@ -117,109 +128,4 @@ - Source Code: `<https://github.com/harens/checkdigit>`_ | ||
| š Setup | ||
| ********* | ||
| To find out more, please read our `contributing page <https://checkdigit.readthedocs.io/en/latest/contributing.html>`_. Thank you! | ||
| First, fork the project to your account. Then, run the following with your GitHub handle in place of | ||
| :code:`INSERT_GITHUB_NAME`: | ||
| .. code-block:: console | ||
| git clone https://github.com/INSERT_GITHUB_NAME/checkdigit | ||
| poetry install && poetry shell | ||
| pre-commit install | ||
| š Project structure | ||
| ******************** | ||
| .. | ||
| Credit for file structure: https://stackoverflow.com/a/38819161 | ||
| :: | ||
| checkdigit | ||
| āāā scripts | ||
| ā āāā format.sh | ||
| ā āāā tests.sh | ||
| āāā checkdigit | ||
| ā āāā gs1.py | ||
| ā āāā isbn.py | ||
| ā āāā luhn.py | ||
| ā āāā etc. | ||
| āāā tests | ||
| Each new format goes into a separate file which is named accordingly. Similar formats (e.g. ISBN-10 and ISBN-13) | ||
| should go in the same file. | ||
| Before submitting any new changes, please run the :code:`format.sh` and :code:`tests.sh` scripts beforehand. Thank you :) | ||
| š Building the Docs | ||
| ********************* | ||
| The documentation can be found in :code:`docs/source`. | ||
| We can use `sphinx-autobuild <https://github.com/executablebooks/sphinx-autobuild>`_ to continuously rebuild the docs when changes are made. | ||
| .. code-block:: console | ||
| sphinx-autobuild docs/source docs/_build/html | ||
| šŖ File structure | ||
| ***************** | ||
| Each of the Python files follow the same general format: | ||
| .. code-block:: python | ||
| # License + File docstring | ||
| from checkdigit._data import cleanse, convert | ||
| def calculate(data: str) -> str: | ||
| """Determines check digit. | ||
| Args: | ||
| data: A string of data missing a check digit | ||
| Returns: | ||
| str: The single missing check digit (not the whole block of data) | ||
| """ | ||
| # This helps to deal with user formatting inconsistencies | ||
| # e.g. spaces, hyphens, etc. | ||
| data = cleanse(data) | ||
| # Deals with 10 or 11 being the possible check digit | ||
| return convert(...) | ||
| def validate(data: str) -> bool: | ||
| """Validates a block of data from the check digit. | ||
| Args: | ||
| data: A string representing a full block of data | ||
| Returns: | ||
| bool: A boolean representing whether the data is valid or not | ||
| """ | ||
| data = cleanse(data) | ||
| # Remove the check digit and see if it matches | ||
| return calculate(data[:-1]) == data[-1] | ||
| def missing(data: str) -> str: | ||
| """Returns the missing digit from a block of data. | ||
| Args: | ||
| data: A string with a question mark in the place of a missing digit. | ||
| Returns: | ||
| A string representing the missing digit (not the whole block of data) | ||
| """ | ||
| data = cleanse(data) | ||
| return ... | ||
| For similar data formats, the names can be adjusted accordingly (e.g. :code:`validate10` for ISBN-10 and :code:`validate13` for ISBN-13). | ||
| š License | ||
@@ -226,0 +132,0 @@ ----------- |
+25
-119
| .. image:: https://raw.githubusercontent.com/harens/checkdigit/master/art/logo.png | ||
| :alt: checkdigit logo | ||
| :target: https://github.com/harens/checkdigit | ||
| :align: center | ||
@@ -9,20 +10,26 @@ | ||
| :alt: GitHub Tests status | ||
| :target: https://github.com/harens/checkdigit/actions | ||
| .. image:: https://img.shields.io/codecov/c/github/harens/checkdigit?logo=codecov&style=flat-square | ||
| :alt: Codecov | ||
| :target: https://app.codecov.io/gh/harens/checkdigit | ||
| .. image:: https://img.shields.io/pypi/dm/checkdigit?logo=python&logoColor=white&style=flat-square | ||
| :alt: PyPi - Downloads | ||
| :target: https://pepy.tech/project/checkdigit | ||
| .. image:: https://img.shields.io/codefactor/grade/github/harens/checkdigit?logo=codefactor&style=flat-square | ||
| :alt: CodeFactor Grade | ||
| :target: https://www.codefactor.io/repository/github/harens/checkdigit/ | ||
| .. image:: https://img.shields.io/lgtm/grade/python/github/harens/checkdigit?logo=lgtm&style=flat-square | ||
| :alt: LGTM Grade | ||
| :target: https://lgtm.com/projects/g/harens/checkdigit/ | ||
| | | ||
| ========= | ||
| .. image:: https://raw.githubusercontent.com/harens/checkdigit/master/art/demo.gif | ||
| :alt: checkdigit example gif | ||
| :align: center | ||
| .. image:: https://repology.org/badge/vertical-allrepos/python:checkdigit.svg | ||
| :alt: checkdigit repology | ||
| :target: https://repology.org/project/python:checkdigit/versions | ||
| :align: right | ||
@@ -62,11 +69,14 @@ **checkdigit** is a pure Python library built for identification numbers. | ||
| * Even and odd binary parity | ||
| * Bookland | ||
| * CRC (credit to `@sapieninja <https://github.com/sapieninja>`_) | ||
| * EAN-13 | ||
| * GS1 (credit to `@OtherBarry <https://github.com/OtherBarry>`_) | ||
| * ISBN-10 | ||
| * ISBN-13 | ||
| * Luhn | ||
| * UPC-A | ||
| * `Even/Odd binary parity <https://checkdigit.readthedocs.io/en/latest/_autosummary/checkdigit.parity.html#module-checkdigit.parity>`_ | ||
| * `CRC <https://checkdigit.readthedocs.io/en/latest/_autosummary/checkdigit.crc.html#module-checkdigit.crc>`_ | ||
| (credit to `@sapieninja <https://github.com/sapieninja>`_) | ||
| * `GS1 Standards <https://checkdigit.readthedocs.io/en/latest/_autosummary/checkdigit.gs1.html#module-checkdigit.gs1>`_ (credit to `@OtherBarry <https://github.com/OtherBarry>`_) | ||
| * EAN-8/13 | ||
| * GDTI | ||
| * GLN | ||
| * SSCC | ||
| * UPC-A/E | ||
| * etc. *(all fixed length numeric GS1 data structures with a check digit)* | ||
| * `ISBN-10/13 <https://checkdigit.readthedocs.io/en/latest/_autosummary/checkdigit.isbn.html#module-checkdigit.isbn>`_ | ||
| * `Luhn <https://checkdigit.readthedocs.io/en/latest/_autosummary/checkdigit.luhn.html#module-checkdigit.luhn>`_ | ||
@@ -81,2 +91,3 @@ For each of these formats, we provide functions to validate them and calculate missing digits. | ||
| - Contributing Page: `<https://checkdigit.rtfd.io/en/latest/contributing.html>`_ | ||
| - Issue Tracker: `<https://github.com/harens/checkdigit/issues>`_ | ||
@@ -89,109 +100,4 @@ - Source Code: `<https://github.com/harens/checkdigit>`_ | ||
| š Setup | ||
| ********* | ||
| To find out more, please read our `contributing page <https://checkdigit.readthedocs.io/en/latest/contributing.html>`_. Thank you! | ||
| First, fork the project to your account. Then, run the following with your GitHub handle in place of | ||
| :code:`INSERT_GITHUB_NAME`: | ||
| .. code-block:: console | ||
| git clone https://github.com/INSERT_GITHUB_NAME/checkdigit | ||
| poetry install && poetry shell | ||
| pre-commit install | ||
| š Project structure | ||
| ******************** | ||
| .. | ||
| Credit for file structure: https://stackoverflow.com/a/38819161 | ||
| :: | ||
| checkdigit | ||
| āāā scripts | ||
| ā āāā format.sh | ||
| ā āāā tests.sh | ||
| āāā checkdigit | ||
| ā āāā gs1.py | ||
| ā āāā isbn.py | ||
| ā āāā luhn.py | ||
| ā āāā etc. | ||
| āāā tests | ||
| Each new format goes into a separate file which is named accordingly. Similar formats (e.g. ISBN-10 and ISBN-13) | ||
| should go in the same file. | ||
| Before submitting any new changes, please run the :code:`format.sh` and :code:`tests.sh` scripts beforehand. Thank you :) | ||
| š Building the Docs | ||
| ********************* | ||
| The documentation can be found in :code:`docs/source`. | ||
| We can use `sphinx-autobuild <https://github.com/executablebooks/sphinx-autobuild>`_ to continuously rebuild the docs when changes are made. | ||
| .. code-block:: console | ||
| sphinx-autobuild docs/source docs/_build/html | ||
| šŖ File structure | ||
| ***************** | ||
| Each of the Python files follow the same general format: | ||
| .. code-block:: python | ||
| # License + File docstring | ||
| from checkdigit._data import cleanse, convert | ||
| def calculate(data: str) -> str: | ||
| """Determines check digit. | ||
| Args: | ||
| data: A string of data missing a check digit | ||
| Returns: | ||
| str: The single missing check digit (not the whole block of data) | ||
| """ | ||
| # This helps to deal with user formatting inconsistencies | ||
| # e.g. spaces, hyphens, etc. | ||
| data = cleanse(data) | ||
| # Deals with 10 or 11 being the possible check digit | ||
| return convert(...) | ||
| def validate(data: str) -> bool: | ||
| """Validates a block of data from the check digit. | ||
| Args: | ||
| data: A string representing a full block of data | ||
| Returns: | ||
| bool: A boolean representing whether the data is valid or not | ||
| """ | ||
| data = cleanse(data) | ||
| # Remove the check digit and see if it matches | ||
| return calculate(data[:-1]) == data[-1] | ||
| def missing(data: str) -> str: | ||
| """Returns the missing digit from a block of data. | ||
| Args: | ||
| data: A string with a question mark in the place of a missing digit. | ||
| Returns: | ||
| A string representing the missing digit (not the whole block of data) | ||
| """ | ||
| data = cleanse(data) | ||
| return ... | ||
| For similar data formats, the names can be adjusted accordingly (e.g. :code:`validate10` for ISBN-10 and :code:`validate13` for ISBN-13). | ||
| š License | ||
@@ -198,0 +104,0 @@ ----------- |
+10
-10
| [tool.poetry] | ||
| name = "checkdigit" | ||
| version = "0.2.0" | ||
| version = "0.3.0" | ||
| description = "A check digit library for data validation" | ||
@@ -10,3 +10,3 @@ authors = ["harens <harensdeveloper@gmail.com>"] | ||
| include = ["checkdigit/py.typed"] | ||
| keywords = ["Check Digits", "Validation", "ISBN"] | ||
| keywords = ["Check Digits", "Validation", "ISBN", "GS1", "Luhn"] | ||
| classifiers = [ | ||
@@ -19,5 +19,5 @@ "Natural Language :: English", | ||
| homepage = "https://checkdigit.readthedocs.io" | ||
| homepage = "https://checkdigit.rtfd.io" | ||
| repository = "https://github.com/harens/checkdigit" | ||
| documentation = "https://checkdigit.readthedocs.io" | ||
| documentation = "https://checkdigit.rtfd.io" | ||
@@ -32,4 +32,4 @@ [tool.poetry.urls] | ||
| error404 = "^1.1.8a0" | ||
| pylint = "^2.8.2" | ||
| mypy = "^0.812" | ||
| pylint = "^2.8.3" | ||
| mypy = "^0.902" | ||
| black = "^20.8b1" | ||
@@ -39,8 +39,8 @@ isort = "^5.8.0" | ||
| coverage = "^5.5" | ||
| pre-commit = "^2.12.1" | ||
| pyupgrade = "^2.17.0" | ||
| Sphinx = "^4.0.1" | ||
| pre-commit = "^2.13.0" | ||
| pyupgrade = "^2.19.4" | ||
| Sphinx = "^4.0.2" | ||
| sphinx-autobuild = "^2021.3.14" | ||
| pytest = "^6.2.4" | ||
| pytest-cov = "^2.12.0" | ||
| pytest-cov = "^2.12.1" | ||
| readme-renderer = "^29.0" | ||
@@ -47,0 +47,0 @@ |
+3
-3
@@ -12,5 +12,5 @@ # -*- coding: utf-8 -*- | ||
| 'name': 'checkdigit', | ||
| 'version': '0.2.0', | ||
| 'version': '0.3.0', | ||
| 'description': 'A check digit library for data validation', | ||
| 'long_description': '.. image:: https://raw.githubusercontent.com/harens/checkdigit/master/art/logo.png\n :alt: checkdigit logo\n :align: center\n\n|\n\n.. image:: https://img.shields.io/github/workflow/status/harens/checkdigit/Tests?logo=github&style=flat-square\n :alt: GitHub Tests status\n\n.. image:: https://img.shields.io/codecov/c/github/harens/checkdigit?logo=codecov&style=flat-square\n :alt: Codecov\n\n.. image:: https://img.shields.io/pypi/dm/checkdigit?logo=python&logoColor=white&style=flat-square\n :alt: PyPi - Downloads\n\n.. image:: https://img.shields.io/codefactor/grade/github/harens/checkdigit?logo=codefactor&style=flat-square\n :alt: CodeFactor Grade\n\n.. image:: https://img.shields.io/lgtm/grade/python/github/harens/checkdigit?logo=lgtm&style=flat-square\n :alt: LGTM Grade\n\n|\n\n.. image:: https://raw.githubusercontent.com/harens/checkdigit/master/art/demo.gif\n :alt: checkdigit example gif\n :align: center\n\n**checkdigit** is a pure Python library built for identification numbers.\nYou want to validate a credit card number, or maybe even calculate a missing digit on an ISBN code?\nWe\'ve got you covered š.\n\nWant to know more? Check out the `API Reference and documentation <https://checkdigit.readthedocs.io/en/latest/reference.html>`_!\n\nInstallation\n------------\n\n`MacPorts <https://ports.macports.org/port/py-checkdigit/summary>`_ š\n*************************************************************************\n\n.. code-block::\n\n sudo port install py-checkdigit\n\n`PyPi <https://pypi.org/project/checkdigit/>`_ š\n**************************************************\n\n.. code-block::\n\n pip install checkdigit\n\n⨠Features\n------------\n\n* `PEP 561 compatible <https://www.python.org/dev/peps/pep-0561>`_, with built in support for type checking.\n* Capable of calculating missing digits or validating a block of data.\n* Extensive in-code comments and docstrings to explain how it works behind the scenes. \U0001fa84\n\nā Supported Formats\n---------------------\n\n* Even and odd binary parity\n* Bookland\n* CRC (credit to `@sapieninja <https://github.com/sapieninja>`_)\n* EAN-13\n* GS1 (credit to `@OtherBarry <https://github.com/OtherBarry>`_)\n* ISBN-10\n* ISBN-13\n* Luhn\n* UPC-A\n\nFor each of these formats, we provide functions to validate them and calculate missing digits.\n\nDo you have any formats that you\'d like to see supported? š¤ Feel free to raise an issue,\nor even to send a pull request!\n\nšØ Contributing\n---------------\n\n- Issue Tracker: `<https://github.com/harens/checkdigit/issues>`_\n- Source Code: `<https://github.com/harens/checkdigit>`_\n\nAny change, big or small, that you think can help improve this project is more than welcome š.\n\nAs well as this, feel free to open an issue with any new suggestions or bug reports. Every contribution is appreciated.\n\nš Setup\n*********\n\nFirst, fork the project to your account. Then, run the following with your GitHub handle in place of\n:code:`INSERT_GITHUB_NAME`:\n\n.. code-block:: console\n\n git clone https://github.com/INSERT_GITHUB_NAME/checkdigit\n poetry install && poetry shell\n pre-commit install\n \n\nš Project structure\n********************\n\n..\n Credit for file structure: https://stackoverflow.com/a/38819161\n\n::\n\n checkdigit\n āāā scripts\n ā āāā format.sh\n ā āāā tests.sh\n āāā checkdigit\n ā āāā gs1.py\n ā āāā isbn.py\n ā āāā luhn.py\n ā āāā etc.\n āāā tests\n\nEach new format goes into a separate file which is named accordingly. Similar formats (e.g. ISBN-10 and ISBN-13)\nshould go in the same file.\n\nBefore submitting any new changes, please run the :code:`format.sh` and :code:`tests.sh` scripts beforehand. Thank you :)\n\nš Building the Docs\n*********************\n\nThe documentation can be found in :code:`docs/source`.\n\nWe can use `sphinx-autobuild <https://github.com/executablebooks/sphinx-autobuild>`_ to continuously rebuild the docs when changes are made.\n\n.. code-block:: console\n\n sphinx-autobuild docs/source docs/_build/html\n\nšŖ File structure\n*****************\n\nEach of the Python files follow the same general format:\n\n.. code-block:: python\n\n # License + File docstring\n\n from checkdigit._data import cleanse, convert\n\n\n def calculate(data: str) -> str:\n """Determines check digit.\n\n Args:\n data: A string of data missing a check digit\n\n Returns:\n str: The single missing check digit (not the whole block of data)\n """\n # This helps to deal with user formatting inconsistencies\n # e.g. spaces, hyphens, etc.\n data = cleanse(data)\n\n # Deals with 10 or 11 being the possible check digit\n return convert(...)\n\n\n def validate(data: str) -> bool:\n """Validates a block of data from the check digit.\n\n Args:\n data: A string representing a full block of data\n\n Returns:\n bool: A boolean representing whether the data is valid or not\n """\n data = cleanse(data)\n\n # Remove the check digit and see if it matches\n return calculate(data[:-1]) == data[-1]\n\n\n def missing(data: str) -> str:\n """Returns the missing digit from a block of data.\n\n Args:\n data: A string with a question mark in the place of a missing digit.\n\n Returns:\n A string representing the missing digit (not the whole block of data)\n """\n data = cleanse(data)\n\n return ...\n\nFor similar data formats, the names can be adjusted accordingly (e.g. :code:`validate10` for ISBN-10 and :code:`validate13` for ISBN-13).\n\nš License\n-----------\n\nThis project is licensed under `GPL-3.0-or-later <https://github.com/harens/checkdigit/blob/master/LICENSE>`_.\n', | ||
| 'long_description': ".. image:: https://raw.githubusercontent.com/harens/checkdigit/master/art/logo.png\n :alt: checkdigit logo\n :target: https://github.com/harens/checkdigit\n :align: center\n\n|\n\n.. image:: https://img.shields.io/github/workflow/status/harens/checkdigit/Tests?logo=github&style=flat-square\n :alt: GitHub Tests status\n :target: https://github.com/harens/checkdigit/actions\n\n.. image:: https://img.shields.io/codecov/c/github/harens/checkdigit?logo=codecov&style=flat-square\n :alt: Codecov\n :target: https://app.codecov.io/gh/harens/checkdigit\n\n.. image:: https://img.shields.io/pypi/dm/checkdigit?logo=python&logoColor=white&style=flat-square\n :alt: PyPi - Downloads\n :target: https://pepy.tech/project/checkdigit\n\n.. image:: https://img.shields.io/codefactor/grade/github/harens/checkdigit?logo=codefactor&style=flat-square\n :alt: CodeFactor Grade\n :target: https://www.codefactor.io/repository/github/harens/checkdigit/\n\n.. image:: https://img.shields.io/lgtm/grade/python/github/harens/checkdigit?logo=lgtm&style=flat-square\n :alt: LGTM Grade\n :target: https://lgtm.com/projects/g/harens/checkdigit/\n\n=========\n\n.. image:: https://repology.org/badge/vertical-allrepos/python:checkdigit.svg\n :alt: checkdigit repology\n :target: https://repology.org/project/python:checkdigit/versions\n :align: right\n\n**checkdigit** is a pure Python library built for identification numbers.\nYou want to validate a credit card number, or maybe even calculate a missing digit on an ISBN code?\nWe've got you covered š.\n\nWant to know more? Check out the `API Reference and documentation <https://checkdigit.readthedocs.io/en/latest/reference.html>`_!\n\nInstallation\n------------\n\n`MacPorts <https://ports.macports.org/port/py-checkdigit/summary>`_ š\n*************************************************************************\n\n.. code-block::\n\n sudo port install py-checkdigit\n\n`PyPi <https://pypi.org/project/checkdigit/>`_ š\n**************************************************\n\n.. code-block::\n\n pip install checkdigit\n\n⨠Features\n------------\n\n* `PEP 561 compatible <https://www.python.org/dev/peps/pep-0561>`_, with built in support for type checking.\n* Capable of calculating missing digits or validating a block of data.\n* Extensive in-code comments and docstrings to explain how it works behind the scenes. \U0001fa84\n\nā Supported Formats\n---------------------\n\n* `Even/Odd binary parity <https://checkdigit.readthedocs.io/en/latest/_autosummary/checkdigit.parity.html#module-checkdigit.parity>`_\n* `CRC <https://checkdigit.readthedocs.io/en/latest/_autosummary/checkdigit.crc.html#module-checkdigit.crc>`_\n (credit to `@sapieninja <https://github.com/sapieninja>`_)\n* `GS1 Standards <https://checkdigit.readthedocs.io/en/latest/_autosummary/checkdigit.gs1.html#module-checkdigit.gs1>`_ (credit to `@OtherBarry <https://github.com/OtherBarry>`_)\n * EAN-8/13\n * GDTI\n * GLN\n * SSCC\n * UPC-A/E\n * etc. *(all fixed length numeric GS1 data structures with a check digit)*\n* `ISBN-10/13 <https://checkdigit.readthedocs.io/en/latest/_autosummary/checkdigit.isbn.html#module-checkdigit.isbn>`_\n* `Luhn <https://checkdigit.readthedocs.io/en/latest/_autosummary/checkdigit.luhn.html#module-checkdigit.luhn>`_\n\nFor each of these formats, we provide functions to validate them and calculate missing digits.\n\nDo you have any formats that you'd like to see supported? š¤ Feel free to raise an issue,\nor even to send a pull request!\n\nšØ Contributing\n---------------\n\n- Contributing Page: `<https://checkdigit.rtfd.io/en/latest/contributing.html>`_\n- Issue Tracker: `<https://github.com/harens/checkdigit/issues>`_\n- Source Code: `<https://github.com/harens/checkdigit>`_\n\nAny change, big or small, that you think can help improve this project is more than welcome š.\n\nAs well as this, feel free to open an issue with any new suggestions or bug reports. Every contribution is appreciated.\n\nTo find out more, please read our `contributing page <https://checkdigit.readthedocs.io/en/latest/contributing.html>`_. Thank you!\n\nš License\n-----------\n\nThis project is licensed under `GPL-3.0-or-later <https://github.com/harens/checkdigit/blob/master/LICENSE>`_.\n", | ||
| 'author': 'harens', | ||
@@ -20,3 +20,3 @@ 'author_email': 'harensdeveloper@gmail.com', | ||
| 'maintainer_email': 'harensdeveloper@gmail.com', | ||
| 'url': 'https://checkdigit.readthedocs.io', | ||
| 'url': 'https://checkdigit.rtfd.io', | ||
| 'packages': packages, | ||
@@ -23,0 +23,0 @@ 'package_data': package_data, |
| # /usr/bin/env python | ||
| # This file is part of checkdigit. | ||
| # checkdigit is free software: you can redistribute it and/or modify | ||
| # it under the terms of the GNU General Public License as published by | ||
| # the Free Software Foundation, either version 3 of the License, or | ||
| # (at your option) any later version. | ||
| # checkdigit 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 General Public License for more details. | ||
| # You should have received a copy of the GNU General Public License | ||
| # along with checkdigit. If not, see <http://www.gnu.org/licenses/>. | ||
| """UPC Validation Functions. | ||
| UPC-A codes are the main variant of Universal Product Codes. | ||
| They contain 12 digits and are mainly used for product identification. | ||
| """ | ||
| from checkdigit import isbn | ||
| # WARNING: Data beginning with 0 must be as a string due to PEP 3127 | ||
| # ISBN calculations are very similar to that of UPC | ||
| # The only major difference is that the ODD instead of even placed digits are multiplied by 3 | ||
| # Spaces and hyphens do not need to be removed | ||
| # This is since it's removed by the ISBN-13 Function | ||
| def calculate(data: str) -> str: | ||
| """Calculates UPC Check Digits. | ||
| Args: | ||
| data: A string of UPC digits | ||
| Returns: | ||
| str: The missing check digit | ||
| Examples: | ||
| >>> from checkdigit import upc | ||
| >>> upc.calculate("17593487596") | ||
| '0' | ||
| >>> upc.calculate("73799324006") | ||
| '8' | ||
| """ | ||
| return isbn.calculate13(data, "upc") | ||
| def validate(data: str) -> bool: | ||
| """Determines if the calculated check digit of the data is the last digit given. | ||
| Args: | ||
| data: A string of characters representing a full UPC code | ||
| Returns: | ||
| bool: A boolean representing whether the check digit validates the data or not | ||
| Examples: | ||
| >>> from checkdigit import upc | ||
| >>> upc.validate("672792398018") | ||
| True | ||
| >>> upc.validate("672792398017") | ||
| False | ||
| """ | ||
| return calculate(data[:-1]) == data[-1] |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
71621
-9.34%13
-7.14%546
-10.2%