diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index f1a40ee..bcdb6fd 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.10", "3.11"] + python-version: ["3.8","3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v3 diff --git a/.gitignore b/.gitignore index 68bc17f..76e8d2f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,160 +1,166 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -cover/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -.pybuilder/ -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock - -# pdm -# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. -#pdm.lock -# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it -# in version control. -# https://pdm.fming.dev/#use-with-ide -.pdm.toml - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# pytype static type analyzer -.pytype/ - -# Cython debug symbols -cython_debug/ - -# PyCharm -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# vscode +.vscode + +# +/*.dcm \ No newline at end of file diff --git a/README.MD b/README.MD index 866d120..cbf116f 100644 --- a/README.MD +++ b/README.MD @@ -2,6 +2,13 @@ Parser for DCM files [Data Conversion Format](https://www.etas.com/download-center-files/products_ASCET_Software_Products/TechNote_DCM_File_Formats.pdf ). The package has two main classes `DCMParser` and `DCMObject`, which provide a toolkit to deal with DCM files used in automotive software development. While the `DCMParser` is designed to read and interpret DCM files, the `DCMObject` allows for structured representation and manipulation of the parsed data. +## Install + +```python +pip install dcmfile_parser +``` + + ## DCMParser ### Features @@ -13,12 +20,13 @@ Parser for DCM files [Data Conversion Format](https://www.etas.com/download-cent 1. **Parsing the DCM file**: ```python - dcm_parser = DCMParser("path/to/dcm/file") + from dcmfile_parser import DCMParser , DCMObject + dcmfile_parser = DCMParser("path/to/dcm/file") ``` 2. **Creating a DCM object**: ```python - dcm_obj = dcm_parser.create_dcm_object() + dcm_obj = dcmfile_parser.create_dcm_object() ``` ## DCMObject @@ -38,11 +46,11 @@ Parser for DCM files [Data Conversion Format](https://www.etas.com/download-cent ``` 2. **Update Parameters from Another DCMObject**: ```python - updated_names, missing_names = dcm_obj.update_from(other_dcm) + updated_names, missing_names = dcm_obj.update_from(other_dcm_obj) ``` 3. **Add New Parameters from Another DCMObject**: ```python - dcm_obj.add_new_parameters_from(other_dcm) + dcm_obj.add_new_parameters_from(other_dcm_obj) ``` 4. **Remove a Parameter**: @@ -56,5 +64,5 @@ Parser for DCM files [Data Conversion Format](https://www.etas.com/download-cent ``` ### Dependencies -Specifeid in requirements.txt +Specified in requirements.txt diff --git a/dcm_parser/__init__.py b/dcm_parser/__init__.py deleted file mode 100644 index 4fe06ab..0000000 --- a/dcm_parser/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from dcm_parser.parse_dcm import DCMParser -from dcm_parser.dcm_object import DCMObject -from dcm_parser.attribute_classes import * \ No newline at end of file diff --git a/dcm_parser/__main__.py b/dcm_parser/__main__.py deleted file mode 100644 index 2f95793..0000000 --- a/dcm_parser/__main__.py +++ /dev/null @@ -1,23 +0,0 @@ -# dcm_parser/__main__.py -import argparse -from .parse_dcm import DCMParser - - -def main(): - parser = argparse.ArgumentParser(description="dcm parser") - # Add an argument - parser.add_argument('-dcm', '--dcmfile', type=str, help='Input dcm file name') - - args = parser.parse_args() - - if args.dcmfile: - parser = DCMParser(args.dcmfile) - dcm_obj = DCMParser.parse_dcm() - ## extned to your needs. - # print (dcm_obj) - - else: - print ('argument not valid') - -if __name__ == '__main__': - main() diff --git a/dcmfile_parser/__init__.py b/dcmfile_parser/__init__.py new file mode 100644 index 0000000..dc85eb0 --- /dev/null +++ b/dcmfile_parser/__init__.py @@ -0,0 +1,3 @@ +from dcmfile_parser.parse_dcm import DCMParser +from dcmfile_parser.dcm_object import DCMObject +from dcmfile_parser.attribute_classes import * \ No newline at end of file diff --git a/dcm_parser/attribute_classes.py b/dcmfile_parser/attribute_classes.py similarity index 100% rename from dcm_parser/attribute_classes.py rename to dcmfile_parser/attribute_classes.py diff --git a/dcm_parser/dcm_object.py b/dcmfile_parser/dcm_object.py similarity index 100% rename from dcm_parser/dcm_object.py rename to dcmfile_parser/dcm_object.py diff --git a/dcm_parser/parse_dcm.py b/dcmfile_parser/parse_dcm.py similarity index 100% rename from dcm_parser/parse_dcm.py rename to dcmfile_parser/parse_dcm.py diff --git a/dcm_parser/templates/FESTWERT.jinja2 b/dcmfile_parser/templates/FESTWERT.jinja2 similarity index 100% rename from dcm_parser/templates/FESTWERT.jinja2 rename to dcmfile_parser/templates/FESTWERT.jinja2 diff --git a/dcm_parser/templates/FESTWERTEBLOCK.jinja2 b/dcmfile_parser/templates/FESTWERTEBLOCK.jinja2 similarity index 100% rename from dcm_parser/templates/FESTWERTEBLOCK.jinja2 rename to dcmfile_parser/templates/FESTWERTEBLOCK.jinja2 diff --git a/dcm_parser/templates/KENNFELD.jinja2 b/dcmfile_parser/templates/KENNFELD.jinja2 similarity index 100% rename from dcm_parser/templates/KENNFELD.jinja2 rename to dcmfile_parser/templates/KENNFELD.jinja2 diff --git a/dcm_parser/templates/KENNLINIE.jinja2 b/dcmfile_parser/templates/KENNLINIE.jinja2 similarity index 100% rename from dcm_parser/templates/KENNLINIE.jinja2 rename to dcmfile_parser/templates/KENNLINIE.jinja2 diff --git a/dcm_parser/templates/STUETZSTELLENVERTEILUNG.jinja2 b/dcmfile_parser/templates/STUETZSTELLENVERTEILUNG.jinja2 similarity index 100% rename from dcm_parser/templates/STUETZSTELLENVERTEILUNG.jinja2 rename to dcmfile_parser/templates/STUETZSTELLENVERTEILUNG.jinja2 diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..642e8f1 --- /dev/null +++ b/setup.py @@ -0,0 +1,27 @@ +from setuptools import find_packages, setup + +with open("README.md", "r") as f: + long_description = f.read() + +setup( + name="dcmfile-parser", + version="0.0.1", + description="parser for dcm files", + packages=find_packages(where="app"), + long_description=long_description, + long_description_content_type="text/markdown", + url="https://github.com/y-menace/dcmfile-parser", + author="MohitYadav", + author_email="mohit.yadav.id.code.repos@gmail.com", + license="MIT", + classifiers=[ + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3.10", + "Operating System :: OS Independent", + ], + install_requires=["jinja2"], + extras_require={ + "dev": ["pytest", "twine"], + }, + python_requires=">=3.8", +) \ No newline at end of file diff --git a/tests/sample1.dcm b/tests/sample1.dcm index 1348caa..0202d2b 100644 --- a/tests/sample1.dcm +++ b/tests/sample1.dcm @@ -14,7 +14,7 @@ FUNKTIONEN FKT AllocationFunction "5.1" "Function for allocation functions" END -FESTWERT numericalParameter +FESTWERT parameter LANGNAME "Revised numerical parameter" FUNKTION "AdvancedParameterFunction" DISPLAYNAME NumericalDisplayname @@ -23,7 +23,7 @@ FESTWERT numericalParameter VAR VariantB=32.5 END -FESTWERT stringParameter +FESTWERT parameterText LANGNAME "Revised string parameter" FUNKTION "AdvancedParameterFunction" DISPLAYNAME StringDisplayname @@ -32,7 +32,7 @@ FESTWERT stringParameter VAR VariantB="ParameterD" END -FESTWERTEBLOCK arrayParameter1D 4 +FESTWERTEBLOCK matrix 4 LANGNAME "Revised array parameters" FUNKTION "ArrayParameterFunction" DISPLAYNAME ArrayParameterDisplayname @@ -40,7 +40,7 @@ FESTWERTEBLOCK arrayParameter1D 4 WERT 1.0 0.0 0.5 2.0 END -KENNLINIE revisedCurve 8 +KENNLINIE line_curve 8 LANGNAME "Revised curve" FUNKTION "CurveFunction" DISPLAYNAME CurveDisplayname @@ -52,7 +52,7 @@ KENNLINIE revisedCurve 8 WERT 225.0 265.0 305.0 345.0 END -FESTKENNLINIE staticCurve 6 +FESTKENNLINIE fixed_line_curve 6 LANGNAME "Revised static curve" FUNKTION "StaticCurveFunction" DISPLAYNAME StaticCurveDisplayname @@ -64,7 +64,7 @@ FESTKENNLINIE staticCurve 6 WERT 185.0 230.0 275.0 END -GRUPPENKENNLINIE collectiveCurve 3 +GRUPPENKENNLINIE group_line_curve 3 LANGNAME "Revised collective curve" FUNKTION "CollectiveCurveFunction" DISPLAYNAME CollectiveCurveDisplayname @@ -75,7 +75,7 @@ GRUPPENKENNLINIE collectiveCurve 3 WERT -50.0 -95.0 -140.0 END -KENNFELD revisedMap 6 2 +KENNFELD map 6 2 LANGNAME "Revised map" FUNKTION "MapFunction" DISPLAYNAME MapDisplayname @@ -89,7 +89,7 @@ KENNFELD revisedMap 6 2 WERT 1.5 2.5 3.5 2.5 3.5 4.5 END -FESTKENNFELD staticMap 6 2 +FESTKENNFELD static_map 6 2 LANGNAME "Revised static map" FUNKTION "StaticMapFunction" DISPLAYNAME StaticMapDisplayname @@ -103,7 +103,7 @@ FESTKENNFELD staticMap 6 2 WERT 1.5 2.5 3.5 2.5 3.5 4.5 END -GRUPPENKENNFELD collectiveMap 6 3 +GRUPPENKENNFELD group_map 6 3 LANGNAME "Revised collective map" FUNKTION "CollectiveMapFunction" DISPLAYNAME CollectiveMapDisplayname diff --git a/tests/test.py b/tests/test.py deleted file mode 100644 index dfb177f..0000000 --- a/tests/test.py +++ /dev/null @@ -1,14 +0,0 @@ -import os -import sys - -testdir = os.path.dirname(__file__) -srcdir = "../" -sys.path.insert(0, os.path.abspath(os.path.join(testdir, srcdir))) - -from dcm_parser import DCMParser , DCMObject - -parser_object = DCMParser('tests/sample1.dcm') -dcm_object = parser_object.create_dcm_object() - -print(dcm_object) -dcm_object.write('test.dcm') \ No newline at end of file diff --git a/tests/test_dcmfile_parser.py b/tests/test_dcmfile_parser.py new file mode 100644 index 0000000..ac3d489 --- /dev/null +++ b/tests/test_dcmfile_parser.py @@ -0,0 +1,59 @@ +import os +import sys +testdir = os.path.dirname(__file__) +module_dir = "../" +sys.path.insert(0, os.path.abspath(os.path.join(testdir, module_dir))) + + +import pytest +from dcmfile_parser import DCMParser, DCMObject + + +# Assuming the parse_dcm function is available and can parse a DCM file to produce instances of the provided attribute classes. + +@pytest.fixture +def sample_dcm_file(tmp_path): + dcmfile_parser = DCMParser('tests/sample1.dcm') + dcm_obj = dcmfile_parser.create_dcm_object() + return dcm_obj + +@pytest.mark.parametrize("export_file", ["test.dcm"]) +def test_export(sample_dcm_file, export_file): + dcm_obj = sample_dcm_file + dcm_obj.write(export_file) + + +@pytest.mark.parametrize("attribute_type,attribute_name,expected_wert", [ + # For FESTWERT + ("FESTWERT", "parameter", [30.0]), + + # For FESTWERTEBLOCK + ("FESTWERTEBLOCK", "matrix", [1.0, 0.0, 0.5, 2.0]), + + # For KENNLINIE + ("KENNLINIE", "line_curve", [5.0, 85.0, 125.0, 185.0, 225.0, 265.0, 305.0, 345.0]), + + # For FESTKENNLINIE + ("FESTKENNLINIE", "fixed_line_curve", [50.0 ,95.0, 140.0 ,185.0, 230.0, 275.0]), + + # For FESTKENNLINIE + ("GRUPPENKENNLINIE", "group_line_curve", [-50.0, -95.0, -140.0]), + + # For FESTKENNLINIE + ("KENNFELD", "map", [0.5, 0.9, 0.7 ,1.5 ,1.9, 2.3, 1.5, 2.5, 3.5 ,2.5, 3.5, 4.5 ]), + + # For FESTKENNLINIE + ("FESTKENNFELD", "static_map", [0.5, 0.9, 0.7, 1.5, 1.9, 2.3, 1.5, 2.5, 3.5, 2.5, 3.5, 4.5]), + + # For FESTKENNLINIE + ("GRUPPENKENNFELD", "group_map", [1.5 ,2.5 ,3.5 ,2.5 ,3.5 ,4.5 ,2.5 ,4.5 ,6.5 ,3.5 ,4.5 ,5.5 ,3.5 ,6.5 ,9.5 ,7.5 ,8.5 ,9.5]), + + # ... and so on for each attribute type and its values +]) +def test_attribute_wert_read(sample_dcm_file, attribute_type, attribute_name, expected_wert): + dcm_obj = sample_dcm_file + attribute_object, type_of = dcm_obj._param_name_dict[attribute_name] + + # Depending on attribute_type, access the relevant WERT value or values + assert attribute_object.wert == expected_wert +