diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 27fd920..0000000 --- a/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -language: python -python: - - "2.7" - - "3.3" - - "3.4" - - "3.5" -before_install: - - if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then - wget https://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh; - else - wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh; - fi - - bash miniconda.sh -b -p $HOME/miniconda - - export PATH="$HOME/miniconda/bin:$PATH" - - hash -r - - conda config --set always_yes yes --set changeps1 no - - conda update -q conda - - conda info -a - - conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION setuptools numpy pyyaml sphinx numpydoc nose coverage - - source activate test-environment -install: - - python setup.py install -script: - - nosetests -v --with-coverage --cover-package=yeadon - - cd doc && make html && cd .. - - python setup.py install diff --git a/LICENSE.txt b/LICENSE.txt index 5c36a27..f979d1c 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2011-2017, Christopher Lee Dembia +Copyright (c) 2011-2022, Christopher Lee Dembia All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/README.rst b/README.rst index cfd0fec..a2173a5 100644 --- a/README.rst +++ b/README.rst @@ -2,23 +2,25 @@ yeadon ====== .. image:: https://img.shields.io/pypi/v/yeadon.svg - :target: https://pypi.python.org/pypi/yeadon/ - :alt: Latest PyPI version + :target: https://pypi.python.org/pypi/yeadon/ + :alt: Latest PyPI version .. image:: https://img.shields.io/pypi/dm/yeadon.svg - :target: https://pypi.python.org/pypi/yeadon/ - :alt: Number of PyPI downloads + :target: https://pypi.python.org/pypi/yeadon/ + :alt: Number of PyPI downloads + +.. image:: https://anaconda.org/conda-forge/yeadon/badges/version.svg + :target: https://anaconda.org/conda-forge/yeadon .. image:: https://readthedocs.org/projects/yeadon/badge/?version=latest - :alt: Documentation Status - :scale: 100% - :target: https://yeadon.readthedocs.org/en/latest/?badge=latest + :alt: Documentation Status + :scale: 100% + :target: https://yeadon.readthedocs.org/en/latest/?badge=latest .. image:: https://zenodo.org/badge/doi/10.5281/zenodo.15770.svg - :target: http://dx.doi.org/10.5281/zenodo.15770 + :target: http://dx.doi.org/10.5281/zenodo.15770 -.. image:: https://travis-ci.org/chrisdembia/yeadon.png?branch=master - :target: https://travis-ci.org/chrisdembia/yeadon +.. image:: https://github.com/chrisdembia/yeadon/actions/workflows/runtests.yml/badge.svg This package calculates the masses, center of mass positions, and inertia tensors that correspond to the human inertia model developed by Yeadon in @@ -44,7 +46,7 @@ Directories Installing ========== -This package was developed for Python 2.7 and Python 3.3+. +This package was developed for Python 3.7+. Dependencies ------------ @@ -78,10 +80,10 @@ Option 1: Scientific python distributions ````````````````````````````````````````` Most `scientific python distributions -`_ provide all of these -dependencies and it is often easiest to install one of them to get started. Once -you have a distribution, you simply need to install the yeadon package. This is -the best solution for Windows users. +`_ provide +all of these dependencies and it is often easiest to install one of them to get +started. Once you have a distribution, you can install the yeadon package. This +is the best solution for Windows users. Option 2: Operating system package manager `````````````````````````````````````````` @@ -92,9 +94,8 @@ be able to obtain all of these packages by opening a terminal window and typing:: $ # prepend sudo to each line below if you desire a system install - $ apt-get install python-setuptools python-numpy python-yaml # required - $ apt-get install python-nose python-sphinx mayavi2 # optional packages - $ easy_install numpydoc # this package is not in the Debian repositories + $ apt-get install python3-setuptools python3-numpy python3-yaml # required + $ apt-get install python3-nose python3-sphinx python3-numpydoc mayavi2 # optional packages For other operating systems (e.g. Windows or Mac), visit the websites for the packages for installation instructions. @@ -106,10 +107,9 @@ This option is required if you want to use `yeadon` in a virtualenv. You can build the dependencies from source and then install them by using a tool like `pip`:: - $ easy_install pip - $ pip install numpy PyYAML - $ pip install nose sphinx mayavi - $ pip install numpydoc + $ python -m pip install numpy PyYAML + $ python -m pip install nose sphinx mayavi + $ python -m pip install numpydoc or you can obtain the source code, perhaps from GitHub_, and install the packages manually. @@ -123,7 +123,7 @@ Once you've obtained the dependencies, you can install `yeadon`. The easiest way to download and install the `yeadon` package is by using a tool like `pip` to obtain the package from the Python Package Index (PyPi):: - $ pip install yeadon # sudo if system install + $ python -m pip install yeadon # sudo if system install You can also obtain an archive of the package at the Python Package Index (``_), and then install the package on your @@ -140,9 +140,6 @@ your terminal:: $ cd yeadon-X.X.X.tar.gz $ python setup.py install # sudo if system install -Both of these options assume that the version of your default Python -interpreter is 2.7. - Run the tests with:: $ python setup.py nosetests @@ -222,9 +219,9 @@ Cite us! If you make use of the yeadon software we would welcome a citation in your publications. Please cite this software paper: - Dembia C, Moore JK and Hubbard M. An object oriented implementation of the - Yeadon human inertia model, F1000Research 2014, 3:223 (doi: - 10.12688/f1000research.5292.1) +Dembia C, Moore JK and Hubbard M. An object oriented implementation of the +Yeadon human inertia model, F1000Research 2014, 3:223 (doi: +https://dx.doi.org/10.12688/f1000research.5292.1) Contact ======= diff --git a/doc/conf.py b/doc/conf.py index 13664b4..d3014c9 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -58,7 +58,7 @@ # General information about the project. project = u'yeadon' -copyright = u'2011-2016, Chris Dembia' +copyright = u'2011-2022, Chris Dembia' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/doc/releasenotes.rst b/doc/releasenotes.rst index af0de02..158a4ab 100644 --- a/doc/releasenotes.rst +++ b/doc/releasenotes.rst @@ -5,6 +5,13 @@ Future releases --------------- See issues on github at ``_. +v1.4.0 +------ + +- Dropped support for Python < 3.7 (including 2.7). +- Replaced ``yaml.load`` with ``yaml.safe_load``. +- Fixed pretty printing of results to work with newer NumPy versions. + v1.3.0 ------ diff --git a/requirements.txt b/requirements.txt index d8a9f04..a9efb2b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -numpy -pyyaml -numpydoc +numpy>=1.16.5 +pyyaml>=5.3.1 +numpydoc>=0.7.0 diff --git a/setup.py b/setup.py index 5884508..26c1ac7 100644 --- a/setup.py +++ b/setup.py @@ -15,11 +15,12 @@ keywords="human inertia yeadon sports biomechanics gymnastics", license='LICENSE.txt', packages=find_packages(), - install_requires=['numpy>=1.6.1', - 'pyyaml>=3.10'], - extras_require={'gui': ['mayavi>=4.0'], - 'doc': ['sphinx', 'numpydoc']}, - tests_require=['nose'], + # NOTE : The minimum versions correspond to those in Ubuntu 20.04 LTS. + install_requires=['numpy>=1.16.5', + 'pyyaml>=5.3.1'], + extras_require={'gui': ['mayavi>=4.7.1'], + 'doc': ['sphinx>=1.8.5', 'numpydoc>=0.7.0']}, + tests_require=['nose>=1.3.7'], test_suite='nose.collector', include_package_data=True, scripts=['bin/yeadon'], @@ -27,10 +28,10 @@ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Science/Research', 'Operating System :: OS Independent', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', 'Topic :: Scientific/Engineering :: Physics', ], ) diff --git a/yeadon-dev-env.yml b/yeadon-dev-env.yml index 8bea398..0a11982 100644 --- a/yeadon-dev-env.yml +++ b/yeadon-dev-env.yml @@ -1,11 +1,12 @@ name: yeadon-dev channels: - conda-forge +# NOTE : The minimum versions correspond to those in Ubuntu 20.04 LTS. dependencies: - - coverage - - nose - - numpy >=1.6.1 - - numpydoc - - pyyaml >=3.10 - - setuptools - - sphinx + - coverage >=4.5.2 + - nose >=1.3.7 + - numpy >=1.16.5 + - numpydoc >=0.7.0 + - pyyaml >=5.3.1 + - setuptools >=44.0.0 + - sphinx >=1.8.5 diff --git a/yeadon/human.py b/yeadon/human.py index 61e8fdd..88b01eb 100644 --- a/yeadon/human.py +++ b/yeadon/human.py @@ -4,8 +4,6 @@ """ -# Use Python3 integer division rules. -from __future__ import division import copy import warnings diff --git a/yeadon/inertia.py b/yeadon/inertia.py index 6d6c544..e689688 100644 --- a/yeadon/inertia.py +++ b/yeadon/inertia.py @@ -1,6 +1,3 @@ -# Use Python3 integer division rules. -from __future__ import division - import warnings import numpy as np diff --git a/yeadon/segment.py b/yeadon/segment.py index ec30b03..40f1471 100644 --- a/yeadon/segment.py +++ b/yeadon/segment.py @@ -4,9 +4,6 @@ user does not interact with this module. """ -# Use Python3 integer division rules. -from __future__ import division - # external imports import numpy as np diff --git a/yeadon/solid.py b/yeadon/solid.py index e1139a5..ddedbcc 100644 --- a/yeadon/solid.py +++ b/yeadon/solid.py @@ -5,8 +5,6 @@ class definition for stadium objects, which are used to construct Semiellipsoid classes. """ -# Use Python3 integer division rules. -from __future__ import division import warnings import numpy as np diff --git a/yeadon/tests/test_human.py b/yeadon/tests/test_human.py index d36b742..5139f44 100644 --- a/yeadon/tests/test_human.py +++ b/yeadon/tests/test_human.py @@ -3,10 +3,7 @@ import os import warnings # For redirecting stdout. -if (sys.version_info > (3, 0)): - from io import StringIO -else: - from cStringIO import StringIO +from io import StringIO import unittest import nose diff --git a/yeadon/tests/test_segment.py b/yeadon/tests/test_segment.py index e259c53..31aa0b1 100644 --- a/yeadon/tests/test_segment.py +++ b/yeadon/tests/test_segment.py @@ -2,10 +2,7 @@ import os import warnings # For redirecting stdout. -if (sys.version_info > (3, 0)): - from io import StringIO -else: - from cStringIO import StringIO +from io import StringIO import unittest import numpy as np diff --git a/yeadon/tests/test_solid.py b/yeadon/tests/test_solid.py index 04ccd49..07ba54e 100644 --- a/yeadon/tests/test_solid.py +++ b/yeadon/tests/test_solid.py @@ -1,8 +1,5 @@ #!/usr/bin/env python -# Use Python3 integer division rules. -from __future__ import division - import sys import os import unittest diff --git a/yeadon/ui.py b/yeadon/ui.py index ea6cb31..f2728db 100644 --- a/yeadon/ui.py +++ b/yeadon/ui.py @@ -2,9 +2,6 @@ object. ''' import os -import sys -if sys.version_info >= (3, 0): - raw_input = input import numpy as np @@ -12,6 +9,7 @@ from . import human as hum + def start_ui(): print("Starting YEADON user interface.") @@ -43,7 +41,7 @@ def start_ui(): print("PROVIDE DATA INPUTS: measurements and configuration (joint angles).") print("\nMEASUREMENTS: can be provided as a 95-field dict (units must be " "meters), or a .TXT file") - temp = raw_input("Type the name of the .TXT filename (to use preloaded " + temp = input("Type the name of the .TXT filename (to use preloaded " "measurements just hit enter): ") if temp == '': meas = measPreload @@ -51,7 +49,7 @@ def start_ui(): file_exist_meas = os.path.exists(temp) meas = temp while not file_exist_meas: - temp = raw_input("Please type the correct name of the .TXT filename " + temp = input("Please type the correct name of the .TXT filename " "(or just use preloaded measurements just hit enter): ") file_exist_meas = os.path.exists(temp) @@ -63,7 +61,7 @@ def start_ui(): print("\nCONFIGURATION (joint angles): can be provided as a 21-field dict," " or a .TXT file") - CFG = raw_input("Type the name of the .TXT filename (for all joint angles " + CFG = input("Type the name of the .TXT filename (for all joint angles " "as zero, just hit enter): ") # create the human object. only one is needed for this commandline program print("Creating human object.") @@ -73,7 +71,7 @@ def start_ui(): else: file_exist_CFG = os.path.exists(CFG) while not file_exist_CFG: - CFG = raw_input("Please type the correct name of the .TXT filename " + CFG = input("Please type the correct name of the .TXT filename " "(for all joint angles as zero, just hit enter): ") file_exist_CFG = os.path.exists(CFG) @@ -101,7 +99,7 @@ def start_ui(): " o: options\n", " q: quit") - userIn = raw_input("What would you like to do next? ") + userIn = input("What would you like to do next? ") print("") # MODIFY JOINT ANGLES @@ -111,7 +109,7 @@ def start_ui(): # SAVE CURRENT JOINT ANGLES elif userIn == 'a': - fname = raw_input("The joint angle dictionary CFG will be pickled" \ + fname = input("The joint angle dictionary CFG will be pickled" \ " into a file saved in the current directory." \ " Specify a file name (without quotes or spaces," \ " q to quit): ") @@ -124,7 +122,7 @@ def start_ui(): print("Be careful with this, because there is no error checking" " yet. Make sure that the pickle file is in the same format" " as a pickle output file from this program.") - fname = raw_input("Enter the name of a CFG .TXT file" \ + fname = input("Enter the name of a CFG .TXT file" \ " including its extension" \ " (q to quit):") if fname != 'q': @@ -133,7 +131,7 @@ def start_ui(): # FORMAT INPUT MEASUREMENTS FOR ISEG FORTRAN CODE elif userIn == 's': - fname = raw_input("Enter the file name to which you would like" \ + fname = input("Enter the file name to which you would like" \ " to write the ISEG input: ") if H.write_meas_for_ISEG(fname) == 0: print("Success!") @@ -148,16 +146,16 @@ def start_ui(): "with respect to your new, desired coordinate system. " "We will first rotate about your x-axis, then your " "y-axis, then your z-axis.") - thetx = raw_input("Angle (rad) about your x-axis: ") - thety = raw_input("Angle (rad) about your y-axis: ") - thetz = raw_input("Angle (rad) about your z-axis: ") + thetx = input("Angle (rad) about your x-axis: ") + thety = input("Angle (rad) about your y-axis: ") + thetz = input("Angle (rad) about your z-axis: ") H.rotate_coord_sys(inertia.rotate_space_123(thetx,thety,thetz)) print("Now we'll specify the position of yeadon with respect to " "your coordinate system. You will provide the three " "components, x y and z, in YOUR coordinates.") - posx = raw_input("X-position (m): ") - posy = raw_input("Y-position (m): ") - posz = raw_input("Z-position (m): ") + posx = input("X-position (m): ") + posy = input("Y-position (m): ") + posz = input("Z-position (m): ") H.translate_coord_sys( (posx,posy,posz) ) print("All done!") @@ -190,7 +188,7 @@ def start_ui(): combinectr = 1 objlist = [] while combinedone == False: - objtemp = raw_input('Solid/segment #' + str(combinectr) + ': ') + objtemp = input('Solid/segment #' + str(combinectr) + ': ') if objtemp == 'q': combinedone = True else: @@ -214,7 +212,7 @@ def start_ui(): sym[ int(H.is_symmetric) ],"now)\n", " 2: scale human by mass\n", " q: back to main menu") - optionIn = raw_input("What would you like to do? ") + optionIn = input("What would you like to do? ") if optionIn == '1': if H.is_symmetric == True: H.is_symmetric = False @@ -225,7 +223,7 @@ def start_ui(): H.update() print("Symmetry is now turned", sym[int(H.is_symmetric)], ".") elif optionIn == '2': - measmass = raw_input("Provide a measured mass with which "\ + measmass = input("Provide a measured mass with which "\ "to scale the human (kg): ") H.scale_human_by_mass(float(measmass)) elif optionIn == 'q': @@ -260,21 +258,21 @@ def modify_joint_angles(H): for i in np.arange(len(H.CFGnames)): print(" ",i,":",H.CFGnames[i],"=",CFG[H.CFGnames[i]]/np.pi,"pi-rad") if counter == 1: - idxIn = raw_input("Enter the number next to the joint angle" \ + idxIn = input("Enter the number next to the joint angle" \ " to modify (q to quit): ") else: - idxIn = raw_input("Modify another joint angle (q to quit):") + idxIn = input("Modify another joint angle (q to quit):") if idxIn == 'q': done = 1 else: - valueIn = raw_input("Enter the new value for the joint angle" \ + valueIn = input("Enter the new value for the joint angle" \ " in units of pi-rad (q to quit): ") if valueIn == 'q': done = 1 else: CFG[H.CFGnames[int(idxIn)]] = float(valueIn) * np.pi while H.validate_CFG() == -1: - valueIn = raw_input("Re-enter a value for this joint: ") + valueIn = input("Re-enter a value for this joint: ") CFG[H.CFGnames[int(idxIn)]] = float(valueIn) * np.pi H.CFG = CFG H._update_segments() @@ -295,7 +293,7 @@ def print_segment_properties(H): for seg in H.segments: print(" ",counter,":",seg.label) counter += 1 - printIn = raw_input("Enter a segment index to view the properties" \ + printIn = input("Enter a segment index to view the properties" \ " of (q to quit): ") if printIn == 'q': printdone = 1 @@ -320,7 +318,7 @@ class for more information. for seg in H.segments: print(" ",counter,":",seg.label) counter += 1 - printIn = raw_input("Enter the segment index to view the solid" \ + printIn = input("Enter the segment index to view the solid" \ " properties of (q to quit): ") if printIn == 'q': printdone = 1 @@ -333,7 +331,7 @@ class for more information. for sol in Seg.solids: print(" ",counter,":",sol.label) counter += 1 - printIn = raw_input("Enter the solid index" \ + printIn = input("Enter the solid index" \ " to view parameters of (q to quit): ") if printIn == 'q': soldone = 1 diff --git a/yeadon/version.py b/yeadon/version.py index 801e0da..5011a2b 100644 --- a/yeadon/version.py +++ b/yeadon/version.py @@ -1 +1 @@ -__version__ = '1.4.0dev`' +__version__ = '1.5.0.dev0'