Skip to content

Commit

Permalink
Add pre-commit hooks and fix errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Iain-S committed Nov 30, 2022
1 parent a2eef09 commit 81bca1b
Show file tree
Hide file tree
Showing 11 changed files with 187 additions and 64 deletions.
3 changes: 3 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[flake8]
max-line-length = 120
ignore = E731,E721,W503
64 changes: 64 additions & 0 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
name: pre-commit action
on:
pull_request:
# Run on merge to main because caches are inherited from parent branches
push:
branches:
- main
env:
# This should be the default but we'll be explicit
PRE_COMMIT_HOME: ~/.caches/pre-commit
jobs:
the_job:
runs-on: ubuntu-latest
strategy:
matrix:
python_version: ['3.10']
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python_version }}
- name: Bootstrap poetry
shell: bash
run: |
python -m ensurepip
python -m pip install --upgrade pip
python -m pip install poetry
- name: Configure poetry
shell: bash
run: |
python -m poetry config virtualenvs.in-project true
- name: Cache Poetry dependencies
uses: actions/cache@v3
id: poetry-cache
with:
path: .venv
key: venv-${{ runner.os }}-${{ matrix.python_version }}-${{ hashFiles('poetry.lock') }}
- name: Install dependencies
shell: bash
if: steps.poetry-cache.outputs.cache-hit != 'true'
run: |
python -m poetry install
- name: Install Pre-Commit
shell: bash
run: |
python -m pip install pre-commit
- name: Cache Pre-Commit Hooks
id: pre-commit-cache
uses: actions/cache@v3
with:
path: ${{ env.PRE_COMMIT_HOME }}
key: hooks-${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }}
- name: Install Pre-Commit Hooks
shell: bash
if: steps.pre-commit-cache.outputs.cache-hit != 'true'
run: |
pre-commit install-hooks
- name: Run Pre-Commit Hooks
shell: bash
run: |
pre-commit run --all-files
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,4 @@ dmypy.json
.pyre/

# Pycharm
.idea/
.idea/
28 changes: 28 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.2.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/markdownlint/markdownlint
rev: v0.11.0
hooks:
- id: markdownlint
args: [--style=mdl_style.rb]
- repo: https://github.com/psf/black
rev: 22.10.0
hooks:
- id: black
- repo: https://github.com/PyCQA/isort
rev: 5.10.1
hooks:
- id: isort
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:
- id: flake8
11 changes: 0 additions & 11 deletions Jenkinsfile

This file was deleted.

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Generate and validate NHS numbers in Python 2.7+ and 3.6+.

Generate five (-n 5) sequential (-d) formatted (-f) nhs numbers:

```
```shell
$ python -m nhs_number_generator.generate_nhs_numbers -n 5 -d -f
400 000 0004
400 000 0012
Expand All @@ -20,7 +20,7 @@ $ python -m nhs_number_generator.generate_nhs_numbers -n 5 -d -f

Use the -h flag for help:

```
```shell
$ python -m nhs_number_generator.generate_nhs_numbers -h
usage: generate_nhs_numbers.py [-h] [-n N] [-d] [-f]

Expand Down
4 changes: 4 additions & 0 deletions mdl_style.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
all
exclude_rule 'MD013'
exclude_rule 'MD026'
rule 'MD029', :style => :one
75 changes: 48 additions & 27 deletions nhs_number_generator/generate_nhs_numbers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,11 @@
"""

from __future__ import unicode_literals
from random import randint, choice

from argparse import ArgumentParser
from random import choice, randint

check_digit_weights = {0: 10,
1: 9,
2: 8,
3: 7,
4: 6,
5: 5,
6: 4,
7: 3,
8: 2}
check_digit_weights = {0: 10, 1: 9, 2: 8, 3: 7, 4: 6, 5: 5, 6: 4, 7: 3, 8: 2}


def calculate_check_digit(nhs_number):
Expand Down Expand Up @@ -63,7 +56,9 @@ def calculate_check_digit(nhs_number):
return eleven_minus_remainder


def deterministic_nhs_number_generator(ranges=[(400000000, 499999999), (600000000, 708800001)]):
def deterministic_nhs_number_generator(
ranges=[(400000000, 499999999), (600000000, 708800001)]
):
"""Returns a generator for a predictable sequence of 10-digit NHS numbers.
The default ranges are the ones currently issued in England, Wales and the Isle of Man. Numbers outside of this
Expand All @@ -76,18 +71,22 @@ def deterministic_nhs_number_generator(ranges=[(400000000, 499999999), (60000000
"""
for _range in ranges:
if _range[1] < _range[0]:
raise ValueError("The high end of the range should not be lower than the low end.")
raise ValueError(
"The high end of the range should not be lower than the low end."
)

if (_range[1] - _range[0]) == 0:
only_possible_check_digit = calculate_check_digit('{:09d}'.format(_range[0]))
only_possible_check_digit = calculate_check_digit(
"{:09d}".format(_range[0])
)
if only_possible_check_digit == 10:
raise ValueError("{:09d} is not a valid NHS number.".format(_range[0]))

for _range in ranges:
i = _range[0]

while i <= _range[1]:
candidate_number = '{:09d}'.format(i)
candidate_number = "{:09d}".format(i)

check_digit = calculate_check_digit(candidate_number)

Expand All @@ -99,7 +98,9 @@ def deterministic_nhs_number_generator(ranges=[(400000000, 499999999), (60000000
return


def random_nhs_number_generator(ranges=[(400000000, 499999999), (600000000, 708800001)]):
def random_nhs_number_generator(
ranges=[(400000000, 499999999), (600000000, 708800001)]
):
"""Returns a generator for an unpredictable sequence of 10-digit NHS numbers.
The default ranges are the ones currently issued in England, Wales and the Isle of Man. Numbers outside of this
Expand All @@ -112,24 +113,28 @@ def random_nhs_number_generator(ranges=[(400000000, 499999999), (600000000, 7088
"""
for _range in ranges:
if _range[1] < _range[0]:
raise ValueError("The high end of the range should not be lower than the low end.")
raise ValueError(
"The high end of the range should not be lower than the low end."
)

if (_range[1] - _range[0]) == 0:
only_possible_check_digit = calculate_check_digit('{:09d}'.format(_range[0]))
only_possible_check_digit = calculate_check_digit(
"{:09d}".format(_range[0])
)
if only_possible_check_digit == 10:
raise ValueError("{:09d} is not a valid NHS number.".format(_range[0]))

while True:
# Pick a tuple (a, b) at random from ranges and get a random int >= a and <= b.
# Note that this weights the ranges equally, no matter their size
candidate_number = '{:09d}'.format(randint(*choice(ranges)))
candidate_number = "{:09d}".format(randint(*choice(ranges)))
check_digit = calculate_check_digit(candidate_number)

if check_digit != 10:
yield candidate_number + str(check_digit)


def add_separators(nhs_number, separator=' '):
def add_separators(nhs_number, separator=" "):
"""Returns the NHS number in 3-3-4 format with a separator in between (a space by default)."""
return nhs_number[0:3] + separator + nhs_number[3:6] + separator + nhs_number[6:10]

Expand All @@ -148,7 +153,11 @@ def is_valid_nhs_number(nhs_number):
NHS numbers in 3-3-4 format should be converted first, i.e. with remove_separators().
"""
if (type(nhs_number) != str and type(nhs_number) != unicode) or len(nhs_number) != 10 or not nhs_number.isnumeric():
if (
(type(nhs_number) != str and type(nhs_number) != type(""))
or len(nhs_number) != 10
or not nhs_number.isnumeric()
):
return False

check_digit = calculate_check_digit(nhs_number)
Expand All @@ -168,13 +177,25 @@ def main():

# Define our command line options with sensible defaults and help messages
parser = ArgumentParser(description="Generate 10-digit NHS numbers.")
parser.add_argument('-n', required=False, type=int, help="the amount to generate", default=10)
parser.add_argument('-d', '--deterministic', action='store_const',
const=True, default=False,
help='whether to generate predictably, starting at 4000000004')
parser.add_argument('-f', '--format', action='store_const',
const=True, default=False,
help='whether to format using spaces e.g. 565 228 3297')
parser.add_argument(
"-n", required=False, type=int, help="the amount to generate", default=10
)
parser.add_argument(
"-d",
"--deterministic",
action="store_const",
const=True,
default=False,
help="whether to generate predictably, starting at 4000000004",
)
parser.add_argument(
"-f",
"--format",
action="store_const",
const=True,
default=False,
help="whether to format using spaces e.g. 565 228 3297",
)

# Get the arguments passed in by the user
arguments = parser.parse_args()
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ packages = [{include = "nhs_number_generator"}]
python = "^2.7 || ^3.6"


[tool.isort]
profile = "black"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Binary file removed tests/.test_generate_nhs_numbers.py.swp
Binary file not shown.
Loading

0 comments on commit 81bca1b

Please sign in to comment.