Skip to content

Commit a2bec87

Browse files
committed
added benchmarks and more documentation
1 parent 23b0520 commit a2bec87

File tree

15 files changed

+266
-648
lines changed

15 files changed

+266
-648
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Changelog
22

3+
## v0.3.0 (2024-02-19)
4+
5+
[GitHub release](https://github.com/davidpeckham/vin/releases/tag/v0.3.0)
6+
7+
### New Features
8+
9+
* Decode the make, model, series, and trim
10+
* Supports passenger cars, multipurpose vehicles, and light trucks manufactured since 1980
11+
* Performance benchmarks
12+
13+
### Fixes
14+
15+
* Correctly determines the model year for older vehicles
16+
317
## v0.2.0 (2024-02-03)
418

519
[GitHub release](https://github.com/davidpeckham/vin/releases/tag/v0.2.0)

README.md

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,52 @@
77

88
-----
99

10-
**Contents**
11-
12-
- [Why use VIN?](#why-use-vin)
13-
- [Vehicle Identification Number](#vehicle-identification-number)
14-
- [Vehicle Data](#vehicle-data)
15-
- [Installation](#installation)
16-
- [License](#license)
17-
18-
VIN validates Vehicle Identification Numbers and decodes the vehicle's manufacturer, make, model, and model year.
10+
``VIN`` validates Vehicle Identification Numbers and decodes the vehicle's manufacturer, make, model, series, trim, and model year.
1911

2012
>>> from vin import VIN
2113

14+
>>> VIN('KNDCE3LG2L5073161').description
15+
'2020 Kia Niro EX Premium'
16+
2217
>>> vin("5FNYF5H59HB011946").manufacturer
2318
Honda
2419

20+
>>> vin("5FNYF5H59HB011946").model_year
21+
2017
22+
2523
>>> vin("YT9NN1U14KA007175").manufacturer
2624
Koenigsegg
2725

28-
>>> vin("5FNYF5H59HB011946").model_year
29-
2017
26+
``VIN`` supports passenger vehicles manufactured since 1980:
27+
28+
* Passenger Cars
29+
* Multipurpose Passenger Vehicle (MPV)
30+
* Light Trucks
31+
32+
``VIN`` does not currently support:
33+
34+
* Buses
35+
* Heavy Trucks
36+
* Incomplete Vehicles
37+
* Low Speed Vehicles (LSV)
38+
* Motorcycles
39+
* Off Road Vehicles
40+
* Trailers
3041

3142
## Why use VIN?
3243

33-
- **Accurate** — Vehicle information is provided by the National Highway Traffic Safety Administration.
34-
- **Fast** — Vehicle data is included and periodically updated, so validation and decoding are fast.
44+
- **Accurate** — Uses U.S. National Highway Traffic Safety Administration vehicle data.
45+
- **Fast** — Validate and decode 1,500 VINs per second.
46+
47+
## Installation
48+
49+
Use ``pip`` to install the library:
50+
51+
$ pip install vin
3552

3653
## Vehicle Identification Number
3754

38-
A ``VIN`` is a unique 17-character Vehicle Identification Number.
55+
A ```VIN``` is a unique 17-character Vehicle Identification Number.
3956

4057
* Uniquely identifies vehicles manufactured for sale or use in the United States since 1980
4158
* Assigned by vehicle manufacturers
@@ -65,17 +82,10 @@ plant where the vehicle was made, and the vehicle's serial number.
6582

6683
For more information, see the [VIN specification](https://www.ecfr.gov/current/title-49/subtitle-B/chapter-V/part-565).
6784

68-
Installation
69-
------------
70-
71-
Use ``pip`` to install the library:
72-
73-
$ pip install vin
74-
7585
## Vehicle Data
7686

7787
Vehicle data is provided by the U.S. National Highway Traffic Safety Administration (NHTSA) [Product Information Catalog and Vehicle Listing (vPIC)](https://vpic.nhtsa.dot.gov).
7888

7989
## License
8090

81-
`VIN` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
91+
``VIN`` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.

docs/hooks.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import shutil
22

33

4-
def copy_history(*args, **kwargs):
4+
def copy_docs(*args, **kwargs):
55
shutil.copy("CHANGELOG.md", "docs/changelog.md")
6+
shutil.copy("README.md", "docs/index.md")

docs/index.md

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,55 @@
77

88
-----
99

10-
VIN validates Vehicle Identification Numbers and decodes the vehicle's manufacturer, make, model, and model year.
10+
``VIN`` validates Vehicle Identification Numbers and decodes the vehicle's manufacturer, make, model, series, trim, and model year.
1111

1212
>>> from vin import VIN
1313

14+
>>> VIN('KNDCE3LG2L5073161').description
15+
'2020 Kia Niro EX Premium'
16+
1417
>>> vin("5FNYF5H59HB011946").manufacturer
1518
Honda
1619

20+
>>> vin("5FNYF5H59HB011946").model_year
21+
2017
22+
1723
>>> vin("YT9NN1U14KA007175").manufacturer
1824
Koenigsegg
1925

20-
>>> vin("5FNYF5H59HB011946").model_year
21-
2017
26+
``VIN`` supports passenger vehicles manufactured since 1980:
27+
28+
* Passenger Cars
29+
* Multipurpose Passenger Vehicle (MPV)
30+
* Light Trucks
31+
32+
``VIN`` does not currently support:
33+
34+
* Buses
35+
* Heavy Trucks
36+
* Incomplete Vehicles
37+
* Low Speed Vehicles (LSV)
38+
* Motorcycles
39+
* Off Road Vehicles
40+
* Trailers
2241

2342
## Why use VIN?
2443

25-
- **Accurate** — Vehicle information is provided by the National Highway Traffic Safety Administration.
26-
- **Fast** — Vehicle data is included and periodically updated, so validation and decoding are fast.
44+
- **Accurate** — Uses U.S. National Highway Traffic Safety Administration vehicle data.
45+
- **Fast** — Validate and decode 1,500 VINs per second.
46+
47+
## Installation
48+
49+
Use ``pip`` to install the library:
50+
51+
$ pip install vin
2752

2853
## Vehicle Identification Number
2954

30-
A ``VIN`` is a unique 17-character Vehicle Identification Number.
55+
A ```VIN``` is a unique 17-character Vehicle Identification Number.
3156

32-
* Assigned by vehicle manufacturers
3357
* Uniquely identifies vehicles manufactured for sale or use in the United States since 1980
58+
* Assigned by vehicle manufacturers
3459
* Governed by the U.S. National Highway Traffic Safety Administration (NHTSA)
3560

3661
The structure of the VIN is:
@@ -57,18 +82,10 @@ plant where the vehicle was made, and the vehicle's serial number.
5782

5883
For more information, see the [VIN specification](https://www.ecfr.gov/current/title-49/subtitle-B/chapter-V/part-565).
5984

60-
Installation
61-
------------
62-
63-
Use ``pip`` to install the library:
64-
65-
$ pip install vin
66-
6785
## Vehicle Data
6886

6987
Vehicle data is provided by the U.S. National Highway Traffic Safety Administration (NHTSA) [Product Information Catalog and Vehicle Listing (vPIC)](https://vpic.nhtsa.dot.gov).
7088

7189
## License
7290

73-
VIN is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
74-
91+
``VIN`` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.

hatch.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
dependencies = [
33
"freezegun==1.2.*",
44
"pytest-cov==4.1.*",
5+
"pytest-benchmark==4.0.*",
56
"pytest==7.3.*",
67
"parametrize_from_file"
78
]
89

910
[envs.default.scripts]
10-
test = "pytest {args:.}"
11+
test = "pytest {args:.} --benchmark-autosave"
1112
cov-test = "pytest --cov {args:vin} --cov-report=term-missing --cov-report=xml"
1213

1314
[envs.lint]
@@ -49,6 +50,7 @@ dependencies = [
4950
# Validation
5051
# https://github.com/linkchecker/linkchecker/pull/669#issuecomment-1267236287
5152
"linkchecker @ git+https://github.com/linkchecker/linkchecker.git@d9265bb71c2054bf57b8c5734a4825d62505c779",
53+
"black"
5254
]
5355
[envs.docs.scripts]
5456
build = "mkdocs build --clean --strict"

mkdocs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ plugins:
6767
merge_init_into_class: true
6868
mkdocs-simple-hooks:
6969
hooks:
70-
on_pre_build: 'docs.hooks:copy_history'
70+
on_pre_build: 'docs.hooks:copy_docs'
7171

7272
markdown_extensions:
7373
- admonition

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ path = "src/vin/__about__.py"
3535
[tool.hatch.envs.default]
3636
dependencies = [
3737
"coverage[toml]>=6.5",
38-
"pytest",
38+
"pytest"
3939
]
4040
[tool.hatch.envs.default.scripts]
4141
test = "pytest {args:tests}"

src/vin/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# SPDX-FileCopyrightText: 2024-present David Peckham <dave.peckham@icloud.com>
22
#
33
# SPDX-License-Identifier: MIT
4-
__version__ = "0.2.0"
4+
__version__ = "0.3.0"

src/vin/__init__.py

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@
99
# ruff: noqa: TRY003, EM101, EM102
1010

1111
from datetime import date
12-
from importlib.resources import files
13-
from typing import Final
1412

13+
from vin.constants import CARS_AND_LIGHT_TRUCKS
1514
from vin.constants import VIN_CHARACTER_VALUES
1615
from vin.constants import VIN_CHARACTERS
1716
from vin.constants import VIN_CHECK_DIGIT_CHARACTERS
@@ -74,13 +73,8 @@ class VIN:
7473
7574
"""
7675

77-
CARS_AND_LIGHT_TRUCKS: Final[list[str]] = (
78-
files("vin").joinpath("cars-and-light-trucks.csv").read_text().splitlines()
79-
)
80-
"""WMI that make cars and light trucks (used to determine model year)"""
81-
82-
def __init__(self, vin: str, decode=True, fix_check_digit=False) -> None:
83-
"""Initialize a VIN.
76+
def __init__(self, vin: str, decode: bool = True, fix_check_digit: bool = False) -> None:
77+
"""Validates the VIN and decodes vehicle information.
8478
8579
Args:
8680
vin: The 17-digit Vehicle Identification Number.
@@ -160,11 +154,9 @@ def calculate_check_digit(cls, vin: str) -> str:
160154
161155
"""
162156
total = 0
163-
for n in range(VIN_LENGTH):
164-
if n == VIN_CHECK_DIGIT_POSITION:
165-
continue
166-
letter = vin[n]
167-
total = total + VIN_CHARACTER_VALUES[letter] * VIN_POSITION_WEIGHTS[n]
157+
for position, letter in enumerate(vin):
158+
if position != VIN_CHECK_DIGIT_POSITION:
159+
total += VIN_CHARACTER_VALUES[letter] * VIN_POSITION_WEIGHTS[position]
168160
return VIN_CHECK_DIGIT_CHARACTERS[total % 11]
169161

170162
@property
@@ -371,18 +363,10 @@ def descriptor(self) -> str:
371363
"""The part of the VIN used to lookup make, model, and other
372364
vehicle attributes in NHTSA vPIC.
373365
374-
The descriptor is 11 characters for a mass-market manufacturer.
375-
For specialized manufacturers, the descriptor is 14 characters so
376-
that it includes the second half of the WMI.
377-
378366
Returns:
379-
str: the 11- or 14-character descriptor for this VIN
367+
str: the 14-character descriptor for this VIN
380368
"""
381369
return f"{self._vin[3:8]}|{self._vin[9:]}"
382-
# if self._vin[2] == "9":
383-
# return descriptor[:14]
384-
# else:
385-
# return descriptor[:11]
386370

387371
def _decode_model_year(self) -> int:
388372
"""The model year as encoded in the VIN.
@@ -394,11 +378,11 @@ def _decode_model_year(self) -> int:
394378
uses information from NHTSA vPIC to determine the actual model year.
395379
396380
Returns:
397-
The vehicle model year. May be negative if the VIN alone isn't
398-
sufficient to determine the model year. When this happens, the
399-
actual model year is likely the absolute value of this model year,
400-
or 30 years earlier. To find the actual model year, look up the VIN
401-
VIN details first with the later model year and then the earlier
381+
The vehicle model year. May be negative if the VIN alone isn't \
382+
sufficient to determine the model year. When this happens, the \
383+
actual model year is likely the absolute value of this model year, \
384+
or 30 years earlier. To find the actual model year, look up the VIN \
385+
VIN details first with the later model year and then the earlier \
402386
model year -- only one of these is likely to return a result.
403387
404388
Examples:
@@ -428,7 +412,7 @@ def _decode_model_year(self) -> int:
428412

429413
assert model_year > 0
430414

431-
if self.wmi in self.CARS_AND_LIGHT_TRUCKS:
415+
if self.wmi in CARS_AND_LIGHT_TRUCKS:
432416
if self._vin[6].isdigit():
433417
# cars and light trucks manufactured on or before April 30, 2009 (1980 to 2009)
434418
model_year -= 30

0 commit comments

Comments
 (0)