From: Shane Jaroch Date: Sat, 8 Apr 2023 14:25:54 +0000 (-0400) Subject: small fixes (#20) X-Git-Tag: v0.2.7~1 X-Git-Url: https://git.nutra.tk/v2?a=commitdiff_plain;h=refs%2Fpull%2F20%2Fhead;p=nutratech%2Fcli.git small fixes (#20) no windows /Scripts in envrc readme and require direnv in init add note in old requirements, see TODO in setup.py fix python3.4 sorting issue, add todos shift error message over one column update casey butt coefficients only need 3.4 on windows, linux covers 3.10 skip 3.5 and 3.8, because 3.4 is already tested --- diff --git a/.envrc b/.envrc index b694c19..1c21d04 100644 --- a/.envrc +++ b/.envrc @@ -1,2 +1,2 @@ -source .venv/bin/activate || source .venv/Scripts/activate +source .venv/bin/activate unset PS1 diff --git a/.github/workflows/install-linux.yml b/.github/workflows/install-linux.yml index ca22d1c..de6fa69 100644 --- a/.github/workflows/install-linux.yml +++ b/.github/workflows/install-linux.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: - python-version: ["3.5", "3.8", "3.10"] + python-version: ["3.10"] steps: - name: Checkout @@ -23,7 +23,7 @@ jobs: with: submodules: recursive - - name: Set up Python ${{ matrix.python-version }} & Restore Cache + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} diff --git a/.github/workflows/install-win32.yml b/.github/workflows/install-win32.yml index 9323928..59b0a6a 100644 --- a/.github/workflows/install-win32.yml +++ b/.github/workflows/install-win32.yml @@ -8,25 +8,37 @@ name: install-win32 - "**" jobs: - windows-latest: + python: runs-on: [windows-latest] + strategy: + matrix: + python-version: ["3.4"] + steps: - name: Checkout uses: actions/checkout@v3 with: submodules: recursive + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + # update-environment: false + - name: Reload Cache / pip uses: actions/cache@v3 with: path: ~\AppData\Local\pip\Cache # NOTE: only cares about base requirements.txt - key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} + # yamllint disable rule:line-length + key: ${{ runner.os }}-${{ matrix.python-version }}-pip-${{ hashFiles('**/requirements.txt') }} + # yamllint enable rule:line-length restore-keys: | - ${{ runner.os }}-pip- + ${{ runner.os }}-${{ matrix.python-version }}-pip- - - name: Install + - name: Install CLI run: make install - name: Basic Tests / CLI / Integration diff --git a/Makefile b/Makefile index 8d94520..9d93218 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ init: ## Set up a Python virtual environment rm -rf .venv ${PY_SYS_INTERPRETER} -m venv .venv - if [ -z "${CI}" ]; then ${PY_SYS_INTERPRETER} -m venv --upgrade-deps .venv; fi - - direnv allow + direnv allow # include .env SKIP_VENV ?= diff --git a/README.rst b/README.rst index 50699c0..84d70e6 100644 --- a/README.rst +++ b/README.rst @@ -9,8 +9,8 @@ and mapping rules built on top. **Requires:** -- Python 3.4.0 or later (``lzma``, ``ssl`` & ``sqlite3`` modules) - [Win XP / Ubuntu 14.04]. +- Python 3.4.3 or later (``lzma``, ``ssl`` & ``sqlite3`` modules) + [WinXP, Ubuntu14.04, or later]. - Packages: see ``setup.py``, and ``requirements.txt`` files. - Internet connection, to download food database & package dependencies. @@ -19,6 +19,7 @@ See ``nt`` database: https://github.com/nutratech/nt-sqlite See ``usda`` database: https://github.com/nutratech/usda-sqlite + Details ####################################################### @@ -69,52 +70,41 @@ Details - + Linux / macOS requirements (for development) ####################################################### -You will need to install ``make`` and ``gcc`` to build the ``Levenshtein`` -extension. - -:: - - sudo apt install \ - make gcc \ - python3-dev python3-venv \ - direnv - +You will need ``make`` and ``gcc`` to build the ``Levenshtein`` extension. -You can add the ``direnv`` hook, ``direnv hook bash >>~/.bashrc``. -Only run this once. +.. code-block:: bash + sudo apt install make gcc direnv python3-dev python3-venv -Plugin Development -####################################################### + # on macOS + brew install make gcc direnv python@3.10 -You can develop plugins (or data modifications sets) that -are imported and built on the base (or core) installation. -These currently can take the form of custom recipes, foods, and RDA injection. +Using ``direnv`` +~~~~~~~~~~~~~~~~ +Install with, -Supporting Old Versions of Python -####################################################### +.. code-block:: bash -The old requirements can still be tested on modern interpreters. -Simply install them with this (inside your ``venv`` environment). + sudo apt install direnv || brew install direnv -:: + # Need to add hook, too + # See: https://direnv.net/docs/hook.html + DEFAULT_SHELL=$(basename $SHELL) + SHELL_RC_FILE=~/.${DEFAULT_SHELL}rc + HOOK='eval "$(direnv hook '$DEFAULT_SHELL')"' - pip install -r requirements-old.txt + # Install the hook, if not already + grep "$HOOK" $SHELL_RC_FILE || echo "$HOOK" >>$SHELL_RC_FILE + source $SHELL_RC_FILE -This won't guarantee compatibility for every version, but it will help. -We provide a wide range. The oldest version of ``tabulate`` is from 2013. +This is what the ``.envrc`` file is for. It automatically activates ``venv``. -There is automated testing on GitHub, but to use an old interpreter -(Python 3.4 does not have the ``typing`` module! Only ``collections.abc``), -you may need to use a virtual machine or install old SSL libraries or enter a -similar messy state. -My preference is for VirtualBox images, where I manually test *Windows XP* -& *Ubuntu 14.04*. Notes @@ -124,24 +114,22 @@ On Windows you should check the box during the Python installer to include ``Scripts`` directory in your ``%PATH%``. This can be done manually after installation too. -Windows users may also have differing results if they install for all users -(as an administrator) vs. installing just for themselves. It may change the -location of installed scripts, and affect the ``$PATH`` variable being -correctly populated for prior installs. +Main program works 100% on older OSes, but ``test`` and ``lint`` may break. + -Install the Levenshtein speedup with this. If it fails remove the ``[extras]``. +Levenshtein speedup [extras] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Install the Levenshtein speedup with this. .. code-block:: bash pip install nutra[extras] -Linux may need to install ``python-dev`` package to build -``python-Levenshtein``. +Linux may need to install ``python-dev`` package as well as ``gcc``. -Windows users may not be able to install ``python-Levenshtein``. +Windows may fail if missing the ``Visual Studio`` build tools are missing. -Main program works 100%, but ``test`` and ``lint`` may break on older operating -systems (*Ubuntu 14.04*, *Windows XP*). Install PyPi release (from pip) @@ -154,6 +142,7 @@ Install PyPi release (from pip) (**Specify:** flag ``-U`` to upgrade, or ``--pre`` for development releases) + Using the source code directly ####################################################### @@ -163,8 +152,7 @@ Clone down, initialize ``nt-sqlite`` submodule, and install requirements: git clone https://github.com/nutratech/cli.git cd cli - make init - # source .venv/bin/activate # uncomment if NOT using direnv + make init || source .venv/bin/activate make deps ./nutra -h @@ -188,16 +176,17 @@ with ``python -m ntclient``. You may need to set the ``PY_SYS_INTERPRETER`` value for the ``Makefile`` if trying to install other than with ``/usr/bin/python3``. + Building the PyPi release (sdist) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: bash - # source .venv/bin/activate # uncomment if NOT using direnv make build # python3 setup.py --quiet sdist twine upload dist/nutra-X.X.X.tar.gz + Linting & Tests ####################################################### @@ -209,6 +198,7 @@ Install the dependencies (``make deps``). Now you can lint & test. make format lint test + ArgComplete (tab completion / autocomplete) ####################################################### @@ -253,9 +243,11 @@ And my ``~/.bashrc`` file looks like this. source ~/.bash_completion.d/python-argcomplete fi +On older versions it may be ``python-argcomplete.sh`` instead. **NOTE:** Standard autocomplete is fully functional, we are adding customized -completions +completions. + Currently Supported Data @@ -270,6 +262,7 @@ Currently Supported Data - Flavonoid, Isoflavonoids, and Proanthocyanidins **[1352 foods]** + Usage ####################################################### diff --git a/ntclient/__init__.py b/ntclient/__init__.py index eb03714..f03cc38 100644 --- a/ntclient/__init__.py +++ b/ntclient/__init__.py @@ -16,7 +16,7 @@ from ntclient.ntsqlite.sql import NT_DB_NAME # Package info __title__ = "nutra" -__version__ = "0.2.7.dev3" +__version__ = "0.2.7.dev4" __author__ = "Shane Jaroch" __email__ = "chown_tee@proton.me" __license__ = "GPL v3" diff --git a/ntclient/argparser/__init__.py b/ntclient/argparser/__init__.py index 86a5f67..b2f8741 100644 --- a/ntclient/argparser/__init__.py +++ b/ntclient/argparser/__init__.py @@ -308,7 +308,7 @@ def build_calc_subcommand(subparsers: argparse._SubParsersAction) -> None: "desired_bf", type=float, nargs="?", - help="e.g. 0.12 -[eric_helms & casey_butt]", + help="e.g. 0.12 [eric_helms & casey_butt]", ) calc_lbl_parser.add_argument( "wrist", type=float, nargs="?", help="wrist (cm) [casey_butt]" diff --git a/ntclient/argparser/funcs.py b/ntclient/argparser/funcs.py index f295730..aa177de 100644 --- a/ntclient/argparser/funcs.py +++ b/ntclient/argparser/funcs.py @@ -316,15 +316,14 @@ def calc_lbm_limits(args: argparse.Namespace) -> tuple: "calf", ] rows = [] - for _calc, _result in result.items(): - _values = list(_result.values()) + for _calc in ["berkhan", "helms", "casey"]: row = [_calc] - row.extend(_values) + row.extend(result[_calc]) while len(row) < len(headers): row.append(str()) rows.append(row) - _table = tabulate(rows, headers=headers, tablefmt="pretty") + _table = tabulate(rows, headers=headers, tablefmt="simple") print(_table) return 0, result diff --git a/ntclient/services/calculate.py b/ntclient/services/calculate.py index ff4e428..8fc9322 100644 --- a/ntclient/services/calculate.py +++ b/ntclient/services/calculate.py @@ -403,7 +403,7 @@ def bf_7site(gender: Gender, args: argparse.Namespace) -> float: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Lean body limits (young men) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -def lbl_berkhan(height: float) -> dict: +def lbl_berkhan(height: float) -> tuple: """ Calculate Martin Berkhan's lean body limit for young men. @@ -415,10 +415,15 @@ def lbl_berkhan(height: float) -> dict: _min = round((height - 102) * 2.205, 1) _max = round((height - 98) * 2.205, 1) - return {"condition": "Contest shape (5-6%)", "weight": "%s ~ %s lbs" % (_min, _max)} + return ( + # condition + "Contest shape (5-6%)", + # weight + "%s ~ %s lbs" % (_min, _max), + ) -def lbl_eric_helms(height: float, args: argparse.Namespace) -> dict: +def lbl_eric_helms(height: float, args: argparse.Namespace) -> tuple: """ Calculate Eric Helm's lean body limit for young men. @@ -432,17 +437,26 @@ def lbl_eric_helms(height: float, args: argparse.Namespace) -> dict: try: desired_bf = float(args.desired_bf) * 100 except (KeyError, TypeError): # pragma: no cover - return {"errMsg": "Eric Helms failed, requires: height, desired_bf."} + # FIXME: define a `warning()` method with bold yellow text. Omit empty columns? + print("WARN: Eric Helms failed, requires: height, desired_bf.") + return ( + # condition (blank) + str(), + # failure message (goes in "weight" column) + "Eric Helms failed!", + ) _min = round(4851.00 * height * 0.01 * height * 0.01 / (100.0 - desired_bf), 1) _max = round(5402.25 * height * 0.01 * height * 0.01 / (100.0 - desired_bf), 1) - return { - "condition": "%s%% body fat" % desired_bf, - "weight": "%s ~ %s lbs" % (_min, _max), - } + return ( + # condition + "%s%% body fat" % desired_bf, + # weight + "%s ~ %s lbs" % (_min, _max), + ) -def lbl_casey_butt(height: float, args: argparse.Namespace) -> dict: +def lbl_casey_butt(height: float, args: argparse.Namespace) -> tuple: """ Calculate Casey Butt's lean body limit for young men. Includes muscle measurements. Some may find these controversial. @@ -461,9 +475,13 @@ def lbl_casey_butt(height: float, args: argparse.Namespace) -> dict: wrist = float(args.wrist) / 2.54 # convert cm --> inches ankle = float(args.ankle) / 2.54 # convert cm --> inches except (KeyError, TypeError): # pragma: no cover - return { - "errMsg": "Casey Butt failed, requires: height, desired_bf, wrist, & ankle." - } + print("WARN: Casey Butt failed, requires: height, desired_bf, wrist, & ankle.") + return ( + # condition (blank) + str(), + # failure message (goes in "weight" column) + "Casey Butt failed!", + ) lbm = round( height ** (3 / 2) @@ -473,14 +491,23 @@ def lbl_casey_butt(height: float, args: argparse.Namespace) -> dict: ) weight = round(lbm / (1 - desired_bf), 1) - return { - "condition": "%s%% body fat" % (desired_bf * 100), - "weight": "%s lbs" % weight, - "lbm": "%s lbs" % lbm, - "chest": round(1.6817 * wrist + 1.3759 * ankle + 0.3314 * height, 2), - "arm": round(1.2033 * wrist + 0.1236 * height, 2), - "forearm": round(0.9626 * wrist + 0.0989 * height, 2), - "neck": round(1.1424 * wrist + 0.1236 * height, 2), - "thigh": round(1.3868 * ankle + 0.1805 * height, 2), - "calf": round(0.9298 * ankle + 0.1210 * height, 2), - } + return ( + # condition + "%s%% body fat" % (desired_bf * 100), + # weight + "%s lbs" % weight, + # lbm + "%s lbs" % lbm, + # chest + round(1.625 * wrist + 1.3682 * ankle + 0.3562 * height, 2), + # arm + round(1.1709 * wrist + 0.1350 * height, 2), + # forearm + round(0.950 * wrist + 0.1041 * height, 2), + # neck + round(1.1875 * wrist + 0.1301 * height, 2), + # thigh + round(1.4737 * ankle + 0.1918 * height, 2), + # calf + round(0.9812 * ankle + 0.1250 * height, 2), + ) diff --git a/requirements-old.txt b/requirements-old.txt index 8885001..34d0733 100644 --- a/requirements-old.txt +++ b/requirements-old.txt @@ -1,4 +1,8 @@ argcomplete<=1.8.2 colorama<=0.3.6 +# NOTE: seems to require 0.18.0 on ubuntu 14.04 fuzzywuzzy==0.3.0 tabulate<=0.4.3 +# NOTE: testing stuff +#future-fstrings +#typing diff --git a/tests/test_cli.py b/tests/test_cli.py index 6623e0e..42d8c7e 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -276,25 +276,19 @@ class TestCli(unittest.TestCase): args = arg_parser.parse_args(args="calc lbl 179 0.1 17.2 21.5".split()) code, result = args.func(args) assert code == 0 - assert result["berkhan"] == { - "condition": "Contest shape (5-6%)", - "weight": "169.8 ~ 178.6 lbs", - } - assert result["helms"] == { - "condition": "10.0% body fat", - "weight": "172.7 ~ 192.3 lbs", - } - assert result["casey"] == { - "condition": "10.0% body fat", - "weight": "196.3 lbs", - "lbm": "176.7 lbs", - "chest": 46.39, - "arm": 16.86, - "forearm": 13.49, - "neck": 16.45, - "thigh": 24.46, - "calf": 16.4, - } + assert result["berkhan"] == ("Contest shape (5-6%)", "169.8 ~ 178.6 lbs") + assert result["helms"] == ("10.0% body fat", "172.7 ~ 192.3 lbs") + assert result["casey"] == ( + "10.0% body fat", + "196.3 lbs", + "176.7 lbs", + 47.69, + 17.44, + 13.77, + 17.21, + 25.99, + 17.11, + ) def test_415_invalid_path_day_throws_error(self): """Ensures invalid path throws exception in `day` subcommand"""