From 86dedf0460677e469594528f1d31ee06e6999169 Mon Sep 17 00:00:00 2001 From: Terence Tuhinanshu Date: Thu, 23 Sep 2021 17:48:14 -0400 Subject: [PATCH 1/7] Remove incorrectly committed artifacts And update .gitignore correspondingly --- .gitignore | 7 +++++++ tr55.egg-info/PKG-INFO | 18 ------------------ tr55.egg-info/SOURCES.txt | 25 ------------------------- tr55.egg-info/dependency_links.txt | 1 - tr55.egg-info/requires.txt | 5 ----- tr55.egg-info/top_level.txt | 1 - 6 files changed, 7 insertions(+), 50 deletions(-) delete mode 100644 tr55.egg-info/PKG-INFO delete mode 100644 tr55.egg-info/SOURCES.txt delete mode 100644 tr55.egg-info/dependency_links.txt delete mode 100644 tr55.egg-info/requires.txt delete mode 100644 tr55.egg-info/top_level.txt diff --git a/.gitignore b/.gitignore index d24a863..195720e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,10 @@ env/ tr55/wintab32dll.txt tr55/Results_*.csv *.bak + +*.egg-info/ +*.egg +.eggs + +build/ +dist/ diff --git a/tr55.egg-info/PKG-INFO b/tr55.egg-info/PKG-INFO deleted file mode 100644 index 3a96742..0000000 --- a/tr55.egg-info/PKG-INFO +++ /dev/null @@ -1,18 +0,0 @@ -Metadata-Version: 1.1 -Name: tr55 -Version: 1.1.3 -Summary: A Python implementation of TR-55. -Home-page: https://github.com/azavea/tr-55 -Author: Azavea Inc. -Author-email: UNKNOWN -License: Apache License 2.0 -Description: A Python implementation of TR-55. - -Keywords: tr-55 watershed hydrology -Platform: UNKNOWN -Classifier: Development Status :: 1 - Planning -Classifier: Intended Audience :: Developers -Classifier: Intended Audience :: Education -Classifier: License :: OSI Approved :: Apache Software License -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 3 diff --git a/tr55.egg-info/SOURCES.txt b/tr55.egg-info/SOURCES.txt deleted file mode 100644 index 89e9217..0000000 --- a/tr55.egg-info/SOURCES.txt +++ /dev/null @@ -1,25 +0,0 @@ -DESCRIPTION.rst -MANIFEST.in -setup.cfg -setup.py -test/test_model.py -test/test_model.pyc -test/test_operations.py -test/test_operations.pyc -test/test_tablelookup.py -test/test_tablelookup.pyc -test/test_water_quality.py -test/test_water_quality.pyc -tr55/__init__.py -tr55/compareMiniAppTables.py -tr55/makeMiniAppTable.py -tr55/model.py -tr55/operations.py -tr55/tablelookup.py -tr55/tables.py -tr55/water_quality.py -tr55.egg-info/PKG-INFO -tr55.egg-info/SOURCES.txt -tr55.egg-info/dependency_links.txt -tr55.egg-info/requires.txt -tr55.egg-info/top_level.txt \ No newline at end of file diff --git a/tr55.egg-info/dependency_links.txt b/tr55.egg-info/dependency_links.txt deleted file mode 100644 index 8b13789..0000000 --- a/tr55.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/tr55.egg-info/requires.txt b/tr55.egg-info/requires.txt deleted file mode 100644 index 57283b9..0000000 --- a/tr55.egg-info/requires.txt +++ /dev/null @@ -1,5 +0,0 @@ - -[dev] - -[test] -nose >= 1.3.4 diff --git a/tr55.egg-info/top_level.txt b/tr55.egg-info/top_level.txt deleted file mode 100644 index a66c865..0000000 --- a/tr55.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -tr55 From ee391785a37416c27bdaa0f968f9e62556e74b84 Mon Sep 17 00:00:00 2001 From: Terence Tuhinanshu Date: Thu, 23 Sep 2021 17:48:51 -0400 Subject: [PATCH 2/7] Use pipenv for development --- Pipfile | 15 +++ Pipfile.lock | 260 +++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 13 ++- 3 files changed, 286 insertions(+), 2 deletions(-) create mode 100644 Pipfile create mode 100644 Pipfile.lock diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..1167607 --- /dev/null +++ b/Pipfile @@ -0,0 +1,15 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +nose = ">=1.3.7" +numpy = ">=1.20.3" + +[dev-packages] +build = "*" +twine = "*" + +[requires] +python_version = "3.9" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..112d4c4 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,260 @@ +{ + "_meta": { + "hash": { + "sha256": "8fd298c704c8b2eb235730cbf4a1e9a2641c65a9d798b60a094d59838b35dc25" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.9" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "nose": { + "hashes": [ + "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac", + "sha256:dadcddc0aefbf99eea214e0f1232b94f2fa9bd98fa8353711dacb112bfcbbb2a", + "sha256:f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" + ], + "index": "pypi", + "version": "==1.3.7" + }, + "numpy": { + "hashes": [ + "sha256:09858463db6dd9f78b2a1a05c93f3b33d4f65975771e90d2cf7aadb7c2f66edf", + "sha256:209666ce9d4a817e8a4597cd475b71b4878a85fa4b8db41d79fdb4fdee01dde2", + "sha256:298156f4d3d46815eaf0fcf0a03f9625fc7631692bd1ad851517ab93c3168fc6", + "sha256:30fc68307c0155d2a75ad19844224be0f2c6f06572d958db4e2053f816b859ad", + "sha256:423216d8afc5923b15df86037c6053bf030d15cc9e3224206ef868c2d63dd6dc", + "sha256:426a00b68b0d21f2deb2ace3c6d677e611ad5a612d2c76494e24a562a930c254", + "sha256:466e682264b14982012887e90346d33435c984b7fead7b85e634903795c8fdb0", + "sha256:51a7b9db0a2941434cd930dacaafe0fc9da8f3d6157f9d12f761bbde93f46218", + "sha256:52a664323273c08f3b473548bf87c8145b7513afd63e4ebba8496ecd3853df13", + "sha256:550564024dc5ceee9421a86fc0fb378aa9d222d4d0f858f6669eff7410c89bef", + "sha256:5de64950137f3a50b76ce93556db392e8f1f954c2d8207f78a92d1f79aa9f737", + "sha256:640c1ccfd56724f2955c237b6ccce2e5b8607c3bc1cc51d3933b8c48d1da3723", + "sha256:7fdc7689daf3b845934d67cb221ba8d250fdca20ac0334fea32f7091b93f00d3", + "sha256:805459ad8baaf815883d0d6f86e45b3b0b67d823a8f3fa39b1ed9c45eaf5edf1", + "sha256:92a0ab128b07799dd5b9077a9af075a63467d03ebac6f8a93e6440abfea4120d", + "sha256:9f2dc79c093f6c5113718d3d90c283f11463d77daa4e83aeeac088ec6a0bda52", + "sha256:a5109345f5ce7ddb3840f5970de71c34a0ff7fceb133c9441283bb8250f532a3", + "sha256:a55e4d81c4260386f71d22294795c87609164e22b28ba0d435850fbdf82fc0c5", + "sha256:a9da45b748caad72ea4a4ed57e9cd382089f33c5ec330a804eb420a496fa760f", + "sha256:b160b9a99ecc6559d9e6d461b95c8eec21461b332f80267ad2c10394b9503496", + "sha256:b342064e647d099ca765f19672696ad50c953cac95b566af1492fd142283580f", + "sha256:b5e8590b9245803c849e09bae070a8e1ff444f45e3f0bed558dd722119eea724", + "sha256:bf75d5825ef47aa51d669b03ce635ecb84d69311e05eccea083f31c7570c9931", + "sha256:c01b59b33c7c3ba90744f2c695be571a3bd40ab2ba7f3d169ffa6db3cfba614f", + "sha256:d96a6a7d74af56feb11e9a443150216578ea07b7450f7c05df40eec90af7f4a7", + "sha256:dd0e3651d210068d13e18503d75aaa45656eef51ef0b261f891788589db2cc38", + "sha256:e167b9805de54367dcb2043519382be541117503ce99e3291cc9b41ca0a83557", + "sha256:e42029e184008a5fd3d819323345e25e2337b0ac7f5c135b7623308530209d57", + "sha256:f545c082eeb09ae678dd451a1b1dbf17babd8a0d7adea02897a76e639afca310", + "sha256:fde50062d67d805bc96f1a9ecc0d37bfc2a8f02b937d2c50824d186aa91f2419" + ], + "index": "pypi", + "version": "==1.21.2" + } + }, + "develop": { + "bleach": { + "hashes": [ + "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da", + "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994" + ], + "markers": "python_version >= '3.6'", + "version": "==4.1.0" + }, + "build": { + "hashes": [ + "sha256:1aaadcd69338252ade4f7ec1265e1a19184bf916d84c9b7df095f423948cb89f", + "sha256:21b7ebbd1b22499c4dac536abc7606696ea4d909fd755e00f09f3c0f2c05e3c8" + ], + "index": "pypi", + "version": "==0.7.0" + }, + "certifi": { + "hashes": [ + "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee", + "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8" + ], + "version": "==2021.5.30" + }, + "charset-normalizer": { + "hashes": [ + "sha256:5d209c0a931f215cee683b6445e2d77677e7e75e159f78def0db09d68fafcaa6", + "sha256:5ec46d183433dcbd0ab716f2d7f29d8dee50505b3fdb40c6b985c7c4f5a3591f" + ], + "markers": "python_version >= '3'", + "version": "==2.0.6" + }, + "colorama": { + "hashes": [ + "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", + "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.4.4" + }, + "docutils": { + "hashes": [ + "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125", + "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", + "version": "==0.17.1" + }, + "idna": { + "hashes": [ + "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a", + "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3" + ], + "markers": "python_version >= '3'", + "version": "==3.2" + }, + "importlib-metadata": { + "hashes": [ + "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15", + "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1" + ], + "markers": "python_version >= '3.6'", + "version": "==4.8.1" + }, + "keyring": { + "hashes": [ + "sha256:6334aee6073db2fb1f30892697b1730105b5e9a77ce7e61fca6b435225493efe", + "sha256:bd2145a237ed70c8ce72978b497619ddfcae640b6dcf494402d5143e37755c6e" + ], + "markers": "python_version >= '3.6'", + "version": "==23.2.1" + }, + "packaging": { + "hashes": [ + "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7", + "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14" + ], + "markers": "python_version >= '3.6'", + "version": "==21.0" + }, + "pep517": { + "hashes": [ + "sha256:3fa6b85b9def7ba4de99fb7f96fe3f02e2d630df8aa2720a5cf3b183f087a738", + "sha256:e1ba5dffa3a131387979a68ff3e391ac7d645be409216b961bc2efe6468ab0b2" + ], + "version": "==0.11.0" + }, + "pkginfo": { + "hashes": [ + "sha256:37ecd857b47e5f55949c41ed061eb51a0bee97a87c969219d144c0e023982779", + "sha256:e7432f81d08adec7297633191bbf0bd47faf13cd8724c3a13250e51d542635bd" + ], + "version": "==1.7.1" + }, + "pygments": { + "hashes": [ + "sha256:b8e67fe6af78f492b3c4b3e2970c0624cbf08beb1e493b2c99b9fa1b67a20380", + "sha256:f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6" + ], + "markers": "python_version >= '3.5'", + "version": "==2.10.0" + }, + "pyparsing": { + "hashes": [ + "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1", + "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", + "version": "==2.4.7" + }, + "readme-renderer": { + "hashes": [ + "sha256:63b4075c6698fcfa78e584930f07f39e05d46f3ec97f65006e430b595ca6348c", + "sha256:92fd5ac2bf8677f310f3303aa4bce5b9d5f9f2094ab98c29f13791d7b805a3db" + ], + "version": "==29.0" + }, + "requests": { + "hashes": [ + "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24", + "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==2.26.0" + }, + "requests-toolbelt": { + "hashes": [ + "sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f", + "sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0" + ], + "version": "==0.9.1" + }, + "rfc3986": { + "hashes": [ + "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835", + "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97" + ], + "version": "==1.5.0" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "version": "==1.16.0" + }, + "tomli": { + "hashes": [ + "sha256:8dd0e9524d6f386271a36b41dbf6c57d8e32fd96fd22b6584679dc569d20899f", + "sha256:a5b75cb6f3968abb47af1b40c1819dc519ea82bcc065776a866e8d74c5ca9442" + ], + "markers": "python_version >= '3.6'", + "version": "==1.2.1" + }, + "tqdm": { + "hashes": [ + "sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c", + "sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==4.62.3" + }, + "twine": { + "hashes": [ + "sha256:087328e9bb405e7ce18527a2dca4042a84c7918658f951110b38bc135acab218", + "sha256:4caec0f1ed78dc4c9b83ad537e453d03ce485725f2aea57f1bb3fdde78dae936" + ], + "index": "pypi", + "version": "==3.4.2" + }, + "urllib3": { + "hashes": [ + "sha256:4987c65554f7a2dbf30c18fd48778ef124af6fab771a377103da0585e2336ece", + "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", + "version": "==1.26.7" + }, + "webencodings": { + "hashes": [ + "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", + "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" + ], + "version": "==0.5.1" + }, + "zipp": { + "hashes": [ + "sha256:957cfda87797e389580cb8b9e3870841ca991e2125350677b2ca83a0e99390a3", + "sha256:f5812b1e007e48cff63449a5e9f4e7ebea716b4111f9c4f9a645f91d579bf0c4" + ], + "markers": "python_version >= '3.6'", + "version": "==3.5.0" + } + } +} diff --git a/README.md b/README.md index 693e508..7499a36 100644 --- a/README.md +++ b/README.md @@ -206,10 +206,19 @@ u'unmodified': {u'bod': 43.11309178874012, The output shown is a tree-like dictionary, akin to the one in the discussion of the first parameter of the `simulate_water_quality` function, except with additional keys and values attached to each node in the tree. The additional keys, `runoff`, `tss`, and so on, have associated values which are the water volumes and pollutant loads that have been calculated. The volumes and loads at the leaves of the tree are those returned by the `fn` function (the second parameter of the `simulate_modifications` function), while those of internal nodes are the sums of the amounts found in their child nodes. -## Testing +## Development + +Development uses [pipenv](https://pipenv.pypa.io/en/latest/). After cloning this repository, setup your local development environment with: + +```console +$ pipenv install --dev +``` -Run `python setup.py test` from within the project directory. +## Testing +```console +$ pipenv run nosetests --verbosity=2 +``` ## Deployments From 7fd3e1bbd4901ea43587edcf67b6c54d44edab8a Mon Sep 17 00:00:00 2001 From: Terence Tuhinanshu Date: Thu, 23 Sep 2021 17:49:36 -0400 Subject: [PATCH 3/7] Update dependencies --- requirements.txt | 4 ++-- setup.py | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index 508c462..6ebd3ff 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -nose==1.3.4 -numpy==1.11.0 \ No newline at end of file +nose==1.3.7 +numpy==1.20.3 diff --git a/setup.py b/setup.py index f7c2a95..197c36e 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ 'DESCRIPTION.rst'), encoding='utf-8') as f: long_description = f.read() -tests_require = ['nose >= 1.3.4'] +tests_require = ['nose >= 1.3.7'] setup( name='tr55', @@ -31,7 +31,9 @@ ], keywords='tr-55 watershed hydrology', packages=find_packages(exclude=['tests']), - install_requires=[], + install_requires=[ + 'numpy >= 1.20.3', + ], extras_require={ 'dev': [], 'test': tests_require, From c82f08d441297345957bfc9e49df2a5948aeb32f Mon Sep 17 00:00:00 2001 From: Terence Tuhinanshu Date: Thu, 23 Sep 2021 17:50:11 -0400 Subject: [PATCH 4/7] Add pyproject.toml for modern building --- README.md | 58 ++++++++++++++++++++++++++++++++++++++------------ pyproject.toml | 6 ++++++ setup.py | 3 ++- 3 files changed, 52 insertions(+), 15 deletions(-) create mode 100644 pyproject.toml diff --git a/README.md b/README.md index 7499a36..00a0a92 100644 --- a/README.md +++ b/README.md @@ -222,26 +222,56 @@ $ pipenv run nosetests --verbosity=2 ## Deployments -Deployments to PyPi are handled through [Travis-CI](https://travis-ci.org/WikiWatershed/tr-55). The following git flow commands approximate a release using Travis: +Create a new release using git flow: -``` bash -$ git flow release start 0.1.0 +```console +$ git flow release start 2.0.0 $ vim CHANGELOG.md $ vim setup.py -$ git commit -m "0.1.0" -$ git flow release publish 0.1.0 -$ git flow release finish 0.1.0 +$ git add CHANGELOG.md setup.py +$ git commit -m "2.0.0" +$ git flow release publish 2.0.0 ``` -After you've completed the `git flow` steps, you'll need to push the changes from your local `master` and `develop` branches back to the main repository. +Then create a wheel to publish to PyPI using [build](https://github.com/pypa/build): -```bash -$ git checkout develop -$ git push origin develop -$ git checkout master -$ git push origin master -# Trigger PyPi deployment -$ git push --tags +```console +$ pipenv run python -m build +``` + +This should create two files under `dist/`: + +```console +$ ls -1 dist/ +tr55-2.0.0.tar.gz +tr55-2.0.0-py2.py3-none-any.whl +``` + +Then publish the wheel to PyPI using [twine](https://github.com/pypa/twine/) and credentials from LastPass: + +```console +$ python -m twine check dist/* +Checking dist/tr55-2.0.0-py2.py3-none-any.whl: PASSED +Checking dist/tr55-2.0.0.tar.gz: PASSED +``` +```console +$ python -m twine upload dist/* +Uploading distributions to https://upload.pypi.org/legacy/ +Enter your username: azavea +Enter your password: +Uploading tr55-2.0.0-py2.py3-none-any.whl +100%| +Uploading tr55-2.0.0.tar.gz +100%| + +View at: +https://pypi.org/project/tr-55/2.0.0/ +``` + +Finally, finish the release: + +```console +$ git flow release finish -p 2.0.0 ``` ## License diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e7bfd67 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,6 @@ +[build-system] +requires = [ + "setuptools>=42", + "wheel>=0.31", + "twine>=1.11", +] diff --git a/setup.py b/setup.py index 197c36e..1a3ad01 100644 --- a/setup.py +++ b/setup.py @@ -16,6 +16,7 @@ version='1.3.0', description='A Python implementation of TR-55.', long_description=long_description, + long_description_content_type='text/x-rst', url='https://github.com/azavea/tr-55', author='Azavea Inc.', license='Apache License 2.0', @@ -30,7 +31,7 @@ 'Programming Language :: Python :: 3', ], keywords='tr-55 watershed hydrology', - packages=find_packages(exclude=['tests']), + packages=find_packages(exclude=['test']), install_requires=[ 'numpy >= 1.20.3', ], From dd12fe2bd3be76c5744410293f2b0230471eb665 Mon Sep 17 00:00:00 2001 From: Terence Tuhinanshu Date: Thu, 23 Sep 2021 17:57:36 -0400 Subject: [PATCH 5/7] Drop Python 2 support --- README.md | 3 --- setup.py | 4 +--- test/test_model.py | 3 --- test/test_operations.py | 3 --- test/test_tablelookup.py | 3 --- test/test_water_quality.py | 3 --- tr55/model.py | 3 --- tr55/operations.py | 3 --- tr55/tablelookup.py | 3 --- tr55/tables.py | 3 --- tr55/water_quality.py | 3 --- 11 files changed, 1 insertion(+), 33 deletions(-) diff --git a/README.md b/README.md index 00a0a92..3ef8eca 100644 --- a/README.md +++ b/README.md @@ -131,9 +131,6 @@ The following land use values are implemented and correspond to the keys listed: The output of the following program: ```Python # -*- coding: utf-8 -*- -from __future__ import print_function -from __future__ import unicode_literals -from __future__ import division import pprint diff --git a/setup.py b/setup.py index 1a3ad01..b377798 100644 --- a/setup.py +++ b/setup.py @@ -20,18 +20,16 @@ url='https://github.com/azavea/tr-55', author='Azavea Inc.', license='Apache License 2.0', - # TODO Determine Python version support - # See also: https://github.com/azavea/tr-55/issues/16 classifiers=[ 'Development Status :: 1 - Planning', 'Intended Audience :: Developers', 'Intended Audience :: Education', 'License :: OSI Approved :: Apache Software License', - 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 3', ], keywords='tr-55 watershed hydrology', packages=find_packages(exclude=['test']), + python_requires=">=3.7", install_requires=[ 'numpy >= 1.20.3', ], diff --git a/test/test_model.py b/test/test_model.py index 8637c3d..39aa658 100644 --- a/test/test_model.py +++ b/test/test_model.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import print_function -from __future__ import unicode_literals -from __future__ import division """ Model test set diff --git a/test/test_operations.py b/test/test_operations.py index 841e464..4933a9e 100644 --- a/test/test_operations.py +++ b/test/test_operations.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import print_function -from __future__ import unicode_literals -from __future__ import division """ Operation tests. diff --git a/test/test_tablelookup.py b/test/test_tablelookup.py index 9657b0c..f6e9211 100644 --- a/test/test_tablelookup.py +++ b/test/test_tablelookup.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import print_function -from __future__ import unicode_literals -from __future__ import division """ Table Lookup test set. diff --git a/test/test_water_quality.py b/test/test_water_quality.py index 375c0fd..e77e1c1 100644 --- a/test/test_water_quality.py +++ b/test/test_water_quality.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import print_function -from __future__ import unicode_literals -from __future__ import division import unittest from tr55.water_quality import get_volume_of_runoff, get_pollutant_load diff --git a/tr55/model.py b/tr55/model.py index 5dbf6dd..dc73a23 100644 --- a/tr55/model.py +++ b/tr55/model.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import print_function -from __future__ import unicode_literals -from __future__ import division """ TR-55 Model Implementation diff --git a/tr55/operations.py b/tr55/operations.py index f8fce4d..f43ed0d 100644 --- a/tr55/operations.py +++ b/tr55/operations.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import print_function -from __future__ import unicode_literals -from __future__ import division import sys diff --git a/tr55/tablelookup.py b/tr55/tablelookup.py index 23745a4..3233d61 100644 --- a/tr55/tablelookup.py +++ b/tr55/tablelookup.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import print_function -from __future__ import unicode_literals -from __future__ import division """ Various routines to do table lookups. diff --git a/tr55/tables.py b/tr55/tables.py index 056598d..b718673 100644 --- a/tr55/tables.py +++ b/tr55/tables.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import print_function -from __future__ import unicode_literals -from __future__ import division """ TR-55 tables diff --git a/tr55/water_quality.py b/tr55/water_quality.py index b7297fd..c2e43d5 100644 --- a/tr55/water_quality.py +++ b/tr55/water_quality.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import print_function -from __future__ import unicode_literals -from __future__ import division from tr55.tablelookup import lookup_load, lookup_nlcd From c2dcfde476cdc57eca588ceb4502139ff4a6dc90 Mon Sep 17 00:00:00 2001 From: Terence Tuhinanshu Date: Thu, 23 Sep 2021 17:58:24 -0400 Subject: [PATCH 6/7] Use almostEqual testing where needed Some of these long floating point results are not stable, so we check them up to 7 digits of precision to ensure that they work. --- test/test_model.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/test/test_model.py b/test/test_model.py index 39aa658..991de55 100644 --- a/test/test_model.py +++ b/test/test_model.py @@ -450,6 +450,23 @@ class TestModel(unittest.TestCase): """ Model test set. """ + # Test for Almost Equal, for unstable floating point results + # via https://stackoverflow.com/a/53081544/6995854 + def assertDictAlmostEqual(self, d1, d2, msg=None, places=7): + # check if both inputs are dicts + self.assertIsInstance(d1, dict, 'First argument is not a dictionary') + self.assertIsInstance(d2, dict, 'Second argument is not a dictionary') + + # check if both inputs have the same keys + self.assertEqual(d1.keys(), d2.keys()) + + # check each key + for key, value in d1.items(): + if isinstance(value, dict): + self.assertDictAlmostEqual(d1[key], d2[key], msg=msg) + else: + self.assertAlmostEqual(d1[key], d2[key], places=places, msg=msg) + def test_nrcs(self): """ Test the implementation of the runoff equation. @@ -797,7 +814,7 @@ def test_day_1(self): precip = 2 actual = simulate_day(CENSUS_1, precip) expected = DAY_OUTPUT_1 - self.assertEqual(actual, expected) + self.assertDictAlmostEqual(actual, expected) def test_day_2(self): """ @@ -807,7 +824,7 @@ def test_day_2(self): precip = 2 actual = simulate_day(CENSUS_2, precip) expected = DAY_OUTPUT_2 - self.assertEqual(actual, expected) + self.assertDictAlmostEqual(actual, expected) def test_day_with_invalid_census(self): """ From e0247d46f7d12a0a655d8fa1b94b2f9353eca97c Mon Sep 17 00:00:00 2001 From: Terence Tuhinanshu Date: Thu, 23 Sep 2021 18:00:17 -0400 Subject: [PATCH 7/7] Update test to match Python 3 rounding The round() function was reimplemented in Python 3 to round to the nearest even number, instead of the higher one, in case of half-way points. Apparently this produces more accurate results over large data points, which would otherwise skew higher than expected. For more details, see: - https://docs.python.org/3/whatsnew/3.0.html#builtins - https://stackoverflow.com/q/10825926/6995854 --- test/test_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_model.py b/test/test_model.py index 991de55..47c1bff 100644 --- a/test/test_model.py +++ b/test/test_model.py @@ -20,7 +20,7 @@ PS = [1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0] # noqa CN55 = [0.000, 0.000, 0.000, 0.000, 0.000, 0.020, 0.080, 0.190, 0.350, 0.530, 0.740, 0.980, 1.520, 2.120, 2.780, 3.490, 4.230, 5.000, 5.790, 6.610, 7.440, 8.290] # noqa CN70 = [0.000, 0.030, 0.060, 0.110, 0.170, 0.240, 0.460, 0.710, 1.010, 1.330, 1.670, 2.040, 2.810, 3.620, 4.460, 5.330, 6.220, 7.130, 8.050, 8.980, 9.910, 10.85] # noqa -CN80 = [0.080, 0.150, 0.240, 0.340, 0.440, 0.560, 0.890, 1.250, 1.640, 2.040, 2.460, 2.890, 3.780, 4.690, 5.630, 6.570, 7.520, 8.480, 9.450, 10.42, 11.39, 12.37] # noqa +CN80 = [0.080, 0.150, 0.240, 0.340, 0.440, 0.560, 0.890, 1.250, 1.640, 2.040, 2.460, 2.890, 3.780, 4.690, 5.620, 6.570, 7.520, 8.480, 9.450, 10.42, 11.39, 12.37] # noqa CN90 = [0.320, 0.460, 0.610, 0.760, 0.930, 1.090, 1.530, 1.980, 2.450, 2.920, 3.400, 3.880, 4.850, 5.820, 6.810, 7.790, 8.780, 9.770, 10.76, 11.76, 12.75, 13.74] # noqa CN95 = [0.560, 0.740, 0.920, 1.110, 1.290, 1.480, 1.960, 2.450, 2.940, 3.430, 3.920, 4.420, 5.410, 6.410, 7.400, 8.400, 9.400, 10.39, 11.39, 12.39, 13.39, 14.39] # noqa # These are runoffs calculated by Sara Damiano.