diff --git a/CHANGES.md b/CHANGES.md index e096090..fffc688 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,11 @@ # NGI Python SGF Parser Package +_2025-05-13_ + +Version 0.0.8 + +- Reverted the parsing strategy to go line by line, such that K-codes do not overrule the other data. + _2025-04-11_ Version 0.0.7 diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..763ed18 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,218 @@ +# This file is automatically @generated by Poetry 2.1.2 and should not be changed by hand. + +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[[package]] +name = "pydantic" +version = "2.11.4" +description = "Data validation using Python type hints" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "pydantic-2.11.4-py3-none-any.whl", hash = "sha256:d9615eaa9ac5a063471da949c8fc16376a84afb5024688b3ff885693506764eb"}, + {file = "pydantic-2.11.4.tar.gz", hash = "sha256:32738d19d63a226a52eed76645a98ee07c1f410ee41d93b4afbfa85ed8111c2d"}, +] + +[package.dependencies] +annotated-types = ">=0.6.0" +pydantic-core = "2.33.2" +typing-extensions = ">=4.12.2" +typing-inspection = ">=0.4.0" + +[package.extras] +email = ["email-validator (>=2.0.0)"] +timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows\""] + +[[package]] +name = "pydantic-core" +version = "2.33.2" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8"}, + {file = "pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2"}, + {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a"}, + {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac"}, + {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a"}, + {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b"}, + {file = "pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22"}, + {file = "pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640"}, + {file = "pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7"}, + {file = "pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef"}, + {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e"}, + {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d"}, + {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30"}, + {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf"}, + {file = "pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51"}, + {file = "pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab"}, + {file = "pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65"}, + {file = "pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc"}, + {file = "pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1"}, + {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b"}, + {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1"}, + {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6"}, + {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea"}, + {file = "pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290"}, + {file = "pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2"}, + {file = "pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab"}, + {file = "pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f"}, + {file = "pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d"}, + {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56"}, + {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5"}, + {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e"}, + {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162"}, + {file = "pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849"}, + {file = "pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9"}, + {file = "pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9"}, + {file = "pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac"}, + {file = "pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5"}, + {file = "pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9"}, + {file = "pydantic_core-2.33.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a2b911a5b90e0374d03813674bf0a5fbbb7741570dcd4b4e85a2e48d17def29d"}, + {file = "pydantic_core-2.33.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6fa6dfc3e4d1f734a34710f391ae822e0a8eb8559a85c6979e14e65ee6ba2954"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54c939ee22dc8e2d545da79fc5381f1c020d6d3141d3bd747eab59164dc89fb"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53a57d2ed685940a504248187d5685e49eb5eef0f696853647bf37c418c538f7"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09fb9dd6571aacd023fe6aaca316bd01cf60ab27240d7eb39ebd66a3a15293b4"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e6116757f7959a712db11f3e9c0a99ade00a5bbedae83cb801985aa154f071b"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d55ab81c57b8ff8548c3e4947f119551253f4e3787a7bbc0b6b3ca47498a9d3"}, + {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c20c462aa4434b33a2661701b861604913f912254e441ab8d78d30485736115a"}, + {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44857c3227d3fb5e753d5fe4a3420d6376fa594b07b621e220cd93703fe21782"}, + {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:eb9b459ca4df0e5c87deb59d37377461a538852765293f9e6ee834f0435a93b9"}, + {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9fcd347d2cc5c23b06de6d3b7b8275be558a0c90549495c699e379a80bf8379e"}, + {file = "pydantic_core-2.33.2-cp39-cp39-win32.whl", hash = "sha256:83aa99b1285bc8f038941ddf598501a86f1536789740991d7d8756e34f1e74d9"}, + {file = "pydantic_core-2.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:f481959862f57f29601ccced557cc2e817bce7533ab8e01a797a48b49c9692b3"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c"}, + {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb"}, + {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:87acbfcf8e90ca885206e98359d7dca4bcbb35abdc0ff66672a293e1d7a19101"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f92c15cd1e97d4b12acd1cc9004fa092578acfa57b67ad5e43a197175d01a64"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f26877a748dc4251cfcfda9dfb5f13fcb034f5308388066bcfe9031b63ae7d"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac89aea9af8cd672fa7b510e7b8c33b0bba9a43186680550ccf23020f32d535"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970919794d126ba8645f3837ab6046fb4e72bbc057b3709144066204c19a455d"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3eb3fe62804e8f859c49ed20a8451342de53ed764150cb14ca71357c765dc2a6"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3abcd9392a36025e3bd55f9bd38d908bd17962cc49bc6da8e7e96285336e2bca"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3a1c81334778f9e3af2f8aeb7a960736e5cab1dfebfb26aabca09afd2906c039"}, + {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27"}, + {file = "pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "six" +version = "1.17.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main"] +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20241206" +description = "Typing stubs for python-dateutil" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53"}, + {file = "types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb"}, +] + +[[package]] +name = "typing-extensions" +version = "4.13.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"}, + {file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"}, +] + +[[package]] +name = "typing-inspection" +version = "0.4.0" +description = "Runtime typing introspection tools" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f"}, + {file = "typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122"}, +] + +[package.dependencies] +typing-extensions = ">=4.12.0" + +[metadata] +lock-version = "2.1" +python-versions = ">=3.11,<4" +content-hash = "3fcef7ed2cc8d61da9285b1c2358fb316b8f4c5e67fa7eb29bb2147f86d64892" diff --git a/pyproject.toml b/pyproject.toml index 05b15a0..f3054ad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "sgf-parser" -version = "0.0.7" +version = "0.0.8" description = "Parser for the Swedish Geotechnical Society / Svenska Geotekniska Föreningen (SGF) data format" authors = [{ name = "Jostein Leira", email = "jostein@leira.net" }] requires-python = ">=3.11,<4" diff --git a/src/sgf_parser/models/method.py b/src/sgf_parser/models/method.py index a649c1c..da0cb7e 100644 --- a/src/sgf_parser/models/method.py +++ b/src/sgf_parser/models/method.py @@ -8,7 +8,6 @@ from sgf_parser.datetime_parser import convert_str_to_datetime, convert_str_to_time from sgf_parser.models import MethodType -from sgf_parser.models.types import FlushingVariant, HammeringVariant, RotationVariant class MethodData(BaseModel, abc.ABC): @@ -135,11 +134,8 @@ def __repr__(self): # class Method(BaseModel, abc.ABC): class Method(BaseModel): - _flushing_variant: FlushingVariant | None = None _current_flushing_active_state: bool = False - _hammering_variant: HammeringVariant | None = None _current_hammer_active_state: bool = False - _rotation_variant: RotationVariant | None = None _current_increased_rotation_state: bool = False def __init__(self, **kwargs): @@ -148,31 +144,6 @@ def __init__(self, **kwargs): def post_processing(self): pass - def detect_flushing_rule(self) -> FlushingVariant: - """ - Call this with the method data before parsing the method data. - - The result of calling this method will set the self.detected_flushing_variant to either use the "K" code if any - regulating the flushing are present, the "AR" (flushing on/off) code or the "I" (flushing pressure) code. - """ - if self._flushing_variant: - return self._flushing_variant - - if any( - [ - row.comment_code in (72, 73, 76, 77) - or any(x in (72, 73, 76, 77) for x in self.extract_codes(row.remarks)) - for row in self.method_data - ] - ): - self._flushing_variant = FlushingVariant.CODE_K - elif any([getattr(row, "flushing") is not None for row in self.method_data]): - self._flushing_variant = FlushingVariant.CODE_AR - else: - self._flushing_variant = FlushingVariant.CODE_I - - return self._flushing_variant - @classmethod def extract_codes(cls, remarks: str | None) -> tuple[int, ...]: """ @@ -195,10 +166,10 @@ def is_flushing_active( The following priority should be used to figure out if flushing is active: - 1. Check K (kode) regulating flushing in file, use only K codes - 2. If no K codes present in file, then check if "AR" code is present and has + 1. Check K (kode) regulating flushing in file + 2. If no K code present, then check if "AR" code is present and has a value (0 or 0.0 = off, 1 or 1.0 = on) - 3. If no "AR" code is present in the file, then check if "I" (flushing pressure) > 0.1 + 3. If no "AR" code is present, then check if "I" (flushing pressure) > 0.1 4. Otherwise, return False Codes used: @@ -207,49 +178,28 @@ def is_flushing_active( Kode 76 (hammer and flushing on) Kode 77 (hammer and flushing off) """ - if self._flushing_variant == FlushingVariant.CODE_K: - if data_row.comment_code in (72, 76) or any(x in (72, 76) for x in self.extract_codes(data_row.remarks)): + if data_row.comment_code in (72, 76) or any(x in (72, 76) for x in self.extract_codes(data_row.remarks)): + self._current_flushing_active_state = True + return self._current_flushing_active_state + # TODO: check remark for extra codes + elif data_row.comment_code in (73, 77) or any(x in (73, 77) for x in self.extract_codes(data_row.remarks)): + self._current_flushing_active_state = False + return self._current_flushing_active_state + + if data_row.flushing is not None: + self._current_flushing_active_state = data_row.flushing + return self._current_flushing_active_state + + if data_row.flushing_pressure is not None: + if data_row.flushing_pressure > Decimal("0.1"): self._current_flushing_active_state = True - # TODO: check remark for extra codes - elif data_row.comment_code in (73, 77) or any(x in (73, 77) for x in self.extract_codes(data_row.remarks)): + else: self._current_flushing_active_state = False - elif self._flushing_variant == FlushingVariant.CODE_AR: - if data_row.flushing is not None: - self._current_flushing_active_state = data_row.flushing - - elif self._flushing_variant == FlushingVariant.CODE_I: - if data_row.flushing_pressure is not None: - if data_row.flushing_pressure > Decimal("0.1"): - self._current_flushing_active_state = True - else: - self._current_flushing_active_state = False + return self._current_flushing_active_state return self._current_flushing_active_state - def detect_hammering_rule(self) -> HammeringVariant | None: - """ - Call this with the method data loaded before parsing the hammering in the method data. - - The result of calling this method will set the self._hammering_variant to either use the "K" code if - any regulating the hammering are present, the "AP" (hammering on/off) code. - """ - if self._hammering_variant: - return self._hammering_variant - - if any( - [ - row.comment_code in (74, 75, 76, 77) - or any(x in (74, 75, 76, 77) for x in self.extract_codes(row.remarks)) - for row in self.method_data - ] - ): - self._hammering_variant = HammeringVariant.K - else: - self._hammering_variant = HammeringVariant.AP - - return self._hammering_variant - def is_hammer_active( self, data_row, #: models.MethodCPTData| models.MethodTOTData| models.MethodRPData| models.MethodSRSData, @@ -269,46 +219,18 @@ def is_hammer_active( Kode 76 (hammer and flushing on) Kode 77 (hammer and flushing off) """ - if self._hammering_variant == HammeringVariant.K: - if data_row.comment_code in (74, 76) or any(x in (74, 76) for x in self.extract_codes(data_row.remarks)): - self._current_hammer_active_state = True - return self._current_hammer_active_state - elif data_row.comment_code in (75, 77) or any(x in (75, 77) for x in self.extract_codes(data_row.remarks)): - self._current_hammer_active_state = False - return self._current_hammer_active_state - - elif self._hammering_variant == HammeringVariant.AP: - if data_row.hammering is not None: - self._current_hammer_active_state = data_row.hammering - return self._current_hammer_active_state - - return self._current_hammer_active_state - - def detect_increased_rotation_rule(self) -> RotationVariant | None: - """ - Call this with the method data before updating the increased rotation in the method data. + if data_row.comment_code in (74, 76) or any(x in (74, 76) for x in self.extract_codes(data_row.remarks)): + self._current_hammer_active_state = True + return self._current_hammer_active_state + elif data_row.comment_code in (75, 77) or any(x in (75, 77) for x in self.extract_codes(data_row.remarks)): + self._current_hammer_active_state = False + return self._current_hammer_active_state - The result of calling this method will set the self._increased_rotation_variant to either use the - "K" code if any regulating the increased rotation are present, the "AQ" (increased rotation on/off) code - or the "R" (rotation rate) code. - """ + if data_row.hammering is not None: + self._current_hammer_active_state = data_row.hammering + return self._current_hammer_active_state - if self._rotation_variant: - return self._rotation_variant - - if any( - [ - row.comment_code in (70, 71) or any(x in (70, 71) for x in self.extract_codes(row.remarks)) - for row in self.method_data - ] - ): - self._rotation_variant = RotationVariant.K - elif any([row.increased_rotation_rate is not None for row in self.method_data]): - self._rotation_variant = RotationVariant.AQ - else: - self._rotation_variant = RotationVariant.R - - return self._rotation_variant + return self._current_hammer_active_state def is_increased_rotation_active( self, @@ -328,53 +250,24 @@ def is_increased_rotation_active( Kode 70 (increased rotation speed on) Kode 71 (increased rotation speed off) """ - if self._rotation_variant == RotationVariant.K: - if data_row.comment_code == 70: + if data_row.comment_code == 70: + self._current_increased_rotation_state = True + return self._current_increased_rotation_state + elif data_row.comment_code == 71: + self._current_increased_rotation_state = False + return self._current_increased_rotation_state + if data_row.increased_rotation_rate is not None: + self._current_increased_rotation_state = data_row.increased_rotation_rate + return self._current_increased_rotation_state + if data_row.rotation_rate is not None: + if data_row.rotation_rate > 35: self._current_increased_rotation_state = True - elif data_row.comment_code == 71: + else: self._current_increased_rotation_state = False - elif self._rotation_variant == RotationVariant.AQ: - if data_row.increased_rotation_rate is not None: - self._current_increased_rotation_state = data_row.increased_rotation_rate - else: - if data_row.rotation_rate is not None: - if data_row.rotation_rate > 35: - self._current_increased_rotation_state = True - else: - self._current_increased_rotation_state = False + return self._current_increased_rotation_state return self._current_increased_rotation_state - def flushing_update(self): - """ - Update flushing - - """ - self._flushing_variant = self.detect_flushing_rule() - - for data in self.method_data: - data.flushing = self.is_flushing_active(data) - - def hammering_update(self): - """ - Update hammering - - """ - self._hammering_variant = self.detect_hammering_rule() - - for data in self.method_data: - data.hammering = self.is_hammer_active(data) - - def rotation_update(self): - """ - Update rotation - - """ - self._rotation_variant = self.detect_increased_rotation_rule() - - for data in self.method_data: - data.increased_rotation_rate = self.is_increased_rotation_active(data) - @model_validator(mode="before") @classmethod def guess_date_format(cls, data: Any) -> Any: diff --git a/src/sgf_parser/models/method_rp.py b/src/sgf_parser/models/method_rp.py index 1f97bdc..c54a0f7 100644 --- a/src/sgf_parser/models/method_rp.py +++ b/src/sgf_parser/models/method_rp.py @@ -39,16 +39,3 @@ def __init__(self, **kwargs): method_data_type: type[MethodRPData] = MethodRPData method_data: list[MethodRPData] = [] - - def post_processing(self): - """ - Post-processing - - """ - - if not self.method_data: - return - - # Update flushing and increased rotation - self.flushing_update() - self.rotation_update() diff --git a/src/sgf_parser/models/method_srs.py b/src/sgf_parser/models/method_srs.py index f0fa1c5..91bda55 100644 --- a/src/sgf_parser/models/method_srs.py +++ b/src/sgf_parser/models/method_srs.py @@ -93,20 +93,6 @@ def set_sounding_class(cls, data: Any) -> Any: return data - def post_processing(self): - """ - Post-processing - - """ - - if not self.method_data: - return - - # Update flushing, hammering and increased rotation - self.flushing_update() - self.hammering_update() - self.rotation_update() - @computed_field def depth_in_rock(self) -> Decimal | None: _rock_top_depth = None diff --git a/src/sgf_parser/models/method_tot.py b/src/sgf_parser/models/method_tot.py index 6b74f88..f689480 100644 --- a/src/sgf_parser/models/method_tot.py +++ b/src/sgf_parser/models/method_tot.py @@ -159,17 +159,3 @@ def bedrock_elevation(self) -> Decimal | None: return Decimal(self.point_z) - _depth_in_soil return None - - def post_processing(self): - """ - Post-processing - - """ - - if not self.method_data: - return - - # Update flushing, hammering and increased rotation - self.flushing_update() - self.hammering_update() - self.rotation_update() diff --git a/src/sgf_parser/models/types.py b/src/sgf_parser/models/types.py index 34a4409..5a85356 100644 --- a/src/sgf_parser/models/types.py +++ b/src/sgf_parser/models/types.py @@ -81,35 +81,6 @@ class ParseState(enum.Enum): QUIT = 3 -class FlushingVariant(enum.StrEnum): - """ - Flushing variants - """ - - CODE_K = "K" - CODE_AR = "AR" - CODE_I = "I" - - -class HammeringVariant(enum.StrEnum): - """ - Hammering variants - """ - - K = "K" - AP = "AP" - - -class RotationVariant(enum.StrEnum): - """ - Rotation variants - """ - - K = "K" - AQ = "AQ" - R = "R" - - class SoundingClass(enum.StrEnum): """ Soil-Rock-Sounding (Swedish Jord-bergsondering) classes diff --git a/src/sgf_parser/parser.py b/src/sgf_parser/parser.py index ad999c7..4304178 100644 --- a/src/sgf_parser/parser.py +++ b/src/sgf_parser/parser.py @@ -142,4 +142,10 @@ def parse_header(self, header: dict[str, Any]) -> Method: def parse_data(self, method: Method, row: str) -> MethodData: row_dict = self._convert_str_to_dict(row) method_data = method.method_data_type.model_validate(row_dict) + if hasattr(method_data, "flushing"): + method_data.flushing = method.is_flushing_active(method_data) + if hasattr(method_data, "hammering"): + method_data.hammering = method.is_hammer_active(method_data) + if hasattr(method_data, "increased_rotation_rate"): + method_data.increased_rotation_rate = method.is_increased_rotation_active(method_data) return method_data diff --git a/tests/integration/test_parse.py b/tests/integration/test_parse.py index db9ad3a..79692da 100644 --- a/tests/integration/test_parse.py +++ b/tests/integration/test_parse.py @@ -510,9 +510,9 @@ def test_return_one_method_one_placeholder( datetime(2018, 11, 20, 10, 50,21), { # load=A, hammering=AP, load=W, turning=H, rotation_rate=R - Decimal("3.625"): {"load":Decimal("1.020"), "turning":Decimal("152"), "penetration_rate": Decimal("154.208"), "comment_code": None, "remarks": None, "hammering": None}, - Decimal("3.700"): {"load": Decimal("1.020"), "turning": Decimal("24"), "penetration_rate": Decimal("10.287"), "hammering": None,}, - Decimal("3.775"): {"load": Decimal("5.681"), "turning": Decimal("24"), "penetration_rate": Decimal("1.506"), "hammering": None, "comment_code": 91, "remarks": "Sond kan ej drivas normalt"}, + Decimal("3.625"): {"load":Decimal("1.020"), "turning":Decimal("152"), "penetration_rate": Decimal("154.208"), "comment_code": None, "remarks": None, "hammering": False}, + Decimal("3.700"): {"load": Decimal("1.020"), "turning": Decimal("24"), "penetration_rate": Decimal("10.287"), "hammering": False,}, + Decimal("3.775"): {"load": Decimal("5.681"), "turning": Decimal("24"), "penetration_rate": Decimal("1.506"), "hammering": False, "comment_code": 91, "remarks": "Sond kan ej drivas normalt"}, }, ), ), diff --git a/tests/unit/test_tot_k_codes.py b/tests/unit/test_tot_k_codes.py index 90eab17..fd1e045 100644 --- a/tests/unit/test_tot_k_codes.py +++ b/tests/unit/test_tot_k_codes.py @@ -53,25 +53,25 @@ class TestTotKCodes: ("D", "K_72_F_ON", "D", "K_73_F_OFF", "D", "K_74_H_ON", "K_75_H_OFF", "D", "K_76_H_F_ON", "D", "K_77_H_F_OFF", "D", "K_72_F_ON", "D", "K_77_H_F_OFF", "K_90",), (False, False, False, False, False, True, False, False, True, True, False, False, False, False, False, False), ), -( # Case #4: K codes (overrides AP) +( # Case #4: K codes do not override AP ("D", "AP_ON", "I_ON", "K_74_H_ON", "I_OFF", "D", "I_OFF", "AP_OFF", "AP_ON", "I_ON", "D", "I_OFF", "K_90"), - (False, False, False, True, True, True, True, True, True, True, True, True, True), + (False, True, True, True, True, True, True, False, True, True, True, True, True), ), ( # Case #5: No K codes, AP codes ("AP_ON", "I_OFF", "AP_OFF", "D", "I_ON", "I_OFF", "D", "AP_ON", "D", "AP_OFF"), (True, True, False, False, False, False, False, True, True, False), ), -( # Case #6: Multiple K codes on the same row (overrides AP) +( # Case #6: Multiple K codes on the same row do not overrides AP ("AP_ON", "D", "AP_OFF", "D", "I_ON", "K_MULTI_H_F_ON", "D", "K_MULTI_H_F_ON", "D", "AP_OFF", "K_MULTI_H_F_OFF", "K_MULTI_H_F_ON_REVERSE", "D", "K_MULTI_H_F_OFF_REVERSE", "K_90"), - (False, False, False, False, False, True, True, True, True, True, False, True, True, False, False), + (True, True, False, False, False, True, True, True, True, False, False, True, True, False, False), ), ], ) # fmt: on def test_hammering(self, rows, expected_hammering): """ - K - If K codes regulating flushing, then only look at K codes. - AP - If no K codes present (regulating hammering), then look at the AP code. + K - If K code regulating hammering, then look at K code. + AP - If no K code present (regulating hammering), then look at the AP code. """ # Header @@ -106,25 +106,25 @@ def test_hammering(self, rows, expected_hammering): ("D", "K_72_F_ON", "D", "K_73_F_OFF", "D","K_74_H_ON", "K_75_H_OFF", "D", "K_76_H_F_ON", "D", "K_77_H_F_OFF", "D", "K_72_F_ON", "D", "K_77_H_F_OFF", "K_90",), (False, True, True, False, False, False, False, False, True, True, False, False, True, True, False, False), ), -( # Case #4: K codes (overrides AR and I) +( # Case #4: K codes do not override AR and I ("D", "AR_ON", "I_ON", "K_72_F_ON", "I_OFF", "D", "I_OFF", "D", "D", "I_ON", "D", "I_OFF", "K_90"), - (False, False, False, True, True, True, True, True, True, True, True, True, True), + (False, True, True, True, False, False, False, False, False, True, True, False, False), ), -( # Case #5: No K codes, AR codes (overrides I) +( # Case #5: No K codes, only AR codes and I codes ("AR_ON", "I_OFF", "AR_OFF", "D", "I_ON", "I_OFF", "D", "AR_ON", "D", "AR_OFF"), - (True, True, False, False, False, False, False, True, True, False), + (True, False, False, False, True, False, False, True, True, False), ), -( # Case #6: Multiple K codes on the same row (overrides AR and I) +( # Case #6: Multiple K codes on the same row do not overrides AR and I ("AR_ON", "I_ON", "AR_OFF", "D", "I_ON", "K_MULTI_H_F_ON", "D", "K_MULTI_H_F_ON", "D", "AR_OFF", "K_MULTI_H_F_OFF", "K_MULTI_H_F_ON_REVERSE", "D", "K_MULTI_H_F_OFF_REVERSE", "K_90"), - (False, False, False, False, False, True, True, True, True, True, False, True, True, False, False), + (True, True, False, False, True , True, True, True, True, False, False, True, True, False, False), ), ], ) # fmt: on def test_flushing(self, rows, expected_flushing): """ - K - If K codes regulating flushing, then only look at K codes. - AR - If no K codes present (regulating flushing), then look at AR code. + K - If K code regulating flushing, then look at K code. + AR - If no K code present (regulating flushing), then look at AR code. I - If no K or AR code present (regulating flushing), then look at the I code. If I > 0.1 MPa then flushing is on. """ @@ -160,25 +160,25 @@ def test_flushing(self, rows, expected_flushing): ("D", "K_70_R_ON", "D", "K_71_R_OFF", "D", "K_74_H_ON", "K_75_H_OFF", "D", "K_76_H_F_ON", "D", "K_70_R_ON", "D", "K_72_F_ON", "D", "K_70_R_ON", "K_90",), (False, True, True, False, False, False, False, False, False, False, True, True, True, True, True, True), ), -( # Case #4: K codes (overrides AQ and R) +( # Case #4: K codes do not override AQ and R ("D", "AQ_ON", "R_ON", "K_70_R_ON", "R_OFF", "D", "R_OFF", "I_OFF", "D", "R_ON", "D", "R_OFF", "K_71_R_OFF", "K_90"), - (False, False, False, True, True, True, True, True, True, True, True, True, False, False), + (False, True, True, True, False, False, False, False, False, True, True, False, False, False), ), -( # Case #5: No K codes, AQ codes (overrides R) +( # Case #5: No K codes, AQ codes do not override R ("AQ_ON", "R_OFF", "AQ_OFF", "D", "R_ON", "R_OFF", "D", "AQ_ON", "D", "AQ_OFF"), - (True, True, False, False, False, False, False, True, True, False), + (True, False, False, False, True, False, False, True, True, False), ), -( # Case #6: Multiple K codes on the same row (overrides AQ and R) +( # Case #6: Multiple K codes on the same row, do not override AQ and R ("AQ_ON", "R_ON", "AQ_OFF", "D", "R_ON", "K_MULTI_H_F_R_ON_REVERSE", "D", "K_MULTI_H_F_R_ON_REVERSE", "D", "AQ_OFF", "K_MULTI_H_F_R_OFF_REVERSE", "K_MULTI_H_F_R_ON", "D", "K_MULTI_H_F_R_OFF", "K_90"), - (False, False, False, False, False, True, True, True, True, True, False, True, True, False, False), + (True, True, False, False, True, True, True, True, True, False, False, True, True, False, False), ), ], ) # fmt: on def test_rotation(self, rows, expected_rotation): """ - K - If K codes regulating increased rotation, then only look at K codes. - AQ - If no K codes present (regulating increased rotation), then look at the AQ code. + K - If K code regulating increased rotation, then look at K code. + AQ - If no K code present (regulating increased rotation), then look at the AQ code. R - If no K or AQ code present (regulating increased rotation), then look at the R code. If R > 35 rpm then increased rotation is on. """