diff --git a/LICENSE b/LICENSE index ab417881..dd8cf868 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 AguaClara +Copyright (c) 2019 AguaClara Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Pipfile b/Pipfile index fe4919b9..bd3a1094 100644 --- a/Pipfile +++ b/Pipfile @@ -8,8 +8,7 @@ pandas = "*" pint = "==0.8.1" scipy = "*" onshape_client = "*" -requests = ">=2.20.0" -matplotlib = "==3.0.3" +matplotlib = "==3.0.3" # Supports Python 3.5 [dev-packages] codecov = "*" @@ -17,12 +16,13 @@ coverage = "*" pytest = "*" pytest-cov = "*" Sphinx = "*" -sphinx_rtd_theme = "==0.4.0" -aguaclara = {editable = true,path = "."} +sphinx_rtd_theme = "*" +aguaclara = {editable = true, path = "."} pytest-runner = "*" requests = ">=2.20.0" rope = "*" pylint = "*" +autopep8 = "*" [requires] python_version = "3.6" diff --git a/Pipfile.lock b/Pipfile.lock index 6e70a850..f32e341d 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "979f696effffec10c0ea2cdc4b10bdec1bd3790501e8709af4571cd8317a6dbf" + "sha256": "7f7fd9e435922f0f617e7080f32a1a3a8fb74aa45a151ad37360b4aaf2e61bc7" }, "pipfile-spec": 6, "requires": { @@ -135,10 +135,10 @@ }, "oauthlib": { "hashes": [ - "sha256:0ce32c5d989a1827e3f1148f98b9085ed2370fc939bf524c9c851d8714797298", - "sha256:3e1e14f6cde7e5475128d30e97edc3bfb4dc857cb884d8714ec161fdbb3b358e" + "sha256:40a63637707e9163eda62d0f5345120c65e001a790480b8256448543c1f78f66", + "sha256:b4d99ae8ccfb7d33ba9591b59355c64eef5241534aa3da2e4c0435346b84bc8e" ], - "version": "==3.0.1" + "version": "==3.0.2" }, "onshape-client": { "hashes": [ @@ -213,7 +213,6 @@ "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" ], - "index": "pypi", "version": "==2.22.0" }, "requests-oauthlib": { @@ -225,26 +224,26 @@ }, "ruamel.yaml": { "hashes": [ - "sha256:17dbf6b7362e7aee8494f7a0f5cffd44902a6331fe89ef0853b855a7930ab845", - "sha256:23731c9efb79f3f5609dedffeb6c5c47a68125fd3d4b157d9fc71b1cd49076a9", - "sha256:2bbdd598ae57bac20968cf9028cc67d37d83bdb7942a94b9478110bc72193148", - "sha256:34586084cdd60845a3e1bece2b58f0a889be25450db8cc0ea143ddf0f40557a2", - "sha256:35957fedbb287b01313bb5c556ffdc70c0277c3500213b5e73dfd8716f748d77", - "sha256:414cb87a40974a575830b406ffab4ab8c6cbd82eeb73abd2a9d1397c1f0223e1", - "sha256:428775be75db68d908b17e4e8dda424c410222f170dc173246aa63e972d094b3", - "sha256:514f670f7d36519bda504d507edfe63e3c20489f86c86d42bc4d9a6dbdf82c7b", - "sha256:5cb962c1ac6887c5da29138fbbe3b4b7705372eb54e599907fa63d4cd743246d", - "sha256:5f6e30282cf70fb7754e1a5f101e27b5240009766376e131b31ab49f14fe81be", - "sha256:86f8e010af6af0b4f42de2d0d9b19cb441e61d3416082186f9dd03c8552d13ad", - "sha256:8d47ed1e557d546bd2dfe54f504d7274274602ff7a0652cde84c258ad6c2d96d", - "sha256:98668876720bce1ac08562d8b93a564a80e3397e442c7ea19cebdcdf73da7f74", - "sha256:9e1f0ddc18d8355dcf5586a5d90417df56074f237812b8682a93b62cca9d2043", - "sha256:a7bc812a72a79d6b7dbb96fa5bee3950464b65ec055d3abc4db6572f2373a95c", - "sha256:b72e13f9f206ee103247b07afd5a39c8b1aa98e8eba80ddba184d030337220ba", - "sha256:bcff8ea9d916789e85e24beed8830c157fb8bc7c313e554733a8151540e66c01", - "sha256:c76e78b3bab652069b8d6f7889b0e72f3455c2b854b2e0a8818393d149ad0a0d" - ], - "version": "==0.15.97" + "sha256:035d1258d1f07c672a55263435a22f3292c50636bf8ed0fa6b90cee0a244e6bd", + "sha256:189437e108ef00104d21ee9aa57b2ae3927f3ab61bef0447a2fd21b82c64e4b2", + "sha256:25bb32cea6ee4bf7da680d80b51ec42081254f30e02d3f58db0653b041ae8185", + "sha256:2852fd6854cd8fb9342ae785d222af3d797e41fa712296f6cf7cd9ae0fee085d", + "sha256:340244ab265943bad541220466e56b0409f5bbcfe3750f417c4c15fabed27a9d", + "sha256:5cdea389d836f6f7386cf32dbe4c29ef82e517559bdf8ba4470ebe9d85ceda4f", + "sha256:6cb78ae9a515936a342adfb114513998a78333441e6599599ab6a7cab90f1999", + "sha256:72a89b03d7e9671340e19ef96ba9cc58b86a079190c0ab89b70ee5458b71748c", + "sha256:86278b7804111b6295069e05266e6faa06a426616ad11597c5c6fed14055b1bb", + "sha256:937908eb1fab3cc997e88960ccce21a44feb31711c2eb00bb2dbdcad645f5e77", + "sha256:95c2f135479957b2d6ca577f8a4bd2d22f78d566250cabf308b75b060100bcd4", + "sha256:9cecfbf214bb6ab93026ea180e429b76e8cc12782f4e531632b0ea0a407be543", + "sha256:a1f78fa84358631025bf393207c0b043b995ae76cb3963ce555be46932792d13", + "sha256:aee248b1583b577cb4dbda1fb24e67baae9af2f25eed849b45d9db077fa62c3b", + "sha256:bb7438aa4f81a0bed286498ec71e68c04f725b153dc52203fa4eed96ee898013", + "sha256:c9685b1788823bc3a34349322cb7268f949a2136d396de2b8044b1cd49cd5370", + "sha256:d3557962da02bbed24157b0de16343f6c264c4b691f6424f3b72dfcecbca592e", + "sha256:e93c86cbaee4c299fff8dbff5df6b22af78846ddd1e9fcb5e238489a4910cf29" + ], + "version": "==0.15.98" }, "scipy": { "hashes": [ @@ -316,6 +315,13 @@ ], "version": "==19.1.0" }, + "autopep8": { + "hashes": [ + "sha256:4d8eec30cc81bc5617dbf1218201d770dc35629363547f17577c61683ccfb3ee" + ], + "index": "pypi", + "version": "==1.4.4" + }, "babel": { "hashes": [ "sha256:af92e6106cb7c55286b25b38ad7695f8b4efb36a90ba483d7f7a6628c46158ab", @@ -345,14 +351,6 @@ "index": "pypi", "version": "==2.0.15" }, - "colorama": { - "hashes": [ - "sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", - "sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48" - ], - "markers": "sys_platform == 'win32'", - "version": "==0.4.1" - }, "coverage": { "hashes": [ "sha256:3684fabf6b87a369017756b551cef29e505cb155ddb892a7a29277b978da88b9", @@ -428,10 +426,10 @@ }, "isort": { "hashes": [ - "sha256:c40744b6bc5162bbb39c1257fe298b7a393861d50978b565f3ccd9cb9de0182a", - "sha256:f57abacd059dc3bd666258d1efb0377510a89777fda3e3274e3c01f7c03ae22d" + "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", + "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd" ], - "version": "==4.3.20" + "version": "==4.3.21" }, "jinja2": { "hashes": [ @@ -557,11 +555,10 @@ }, "more-itertools": { "hashes": [ - "sha256:2112d2ca570bb7c3e53ea1a35cd5df42bb0fd10c45f0fb97178679c3c03d64c7", - "sha256:c3e4748ba1aad8dba30a4886b0b1a2004f9a863837b8654e7059eebf727afa5a" + "sha256:3ad685ff8512bf6dc5a8b82ebf73543999b657eded8c11803d9ba6b648986f4d", + "sha256:8bb43d1f51ecef60d81854af61a3a880555a14643691cc4b64a6ee269c78f09a" ], - "markers": "python_version > '2.7'", - "version": "==7.0.0" + "version": "==7.1.0" }, "numpy": { "hashes": [ @@ -651,6 +648,13 @@ ], "version": "==1.8.0" }, + "pycodestyle": { + "hashes": [ + "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", + "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c" + ], + "version": "==2.5.0" + }, "pygments": { "hashes": [ "sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127", @@ -675,11 +679,11 @@ }, "pytest": { "hashes": [ - "sha256:4a784f1d4f2ef198fe9b7aef793e9fa1a3b2f84e822d9b3a64a181293a572d45", - "sha256:926855726d8ae8371803f7b2e6ec0a69953d9c6311fa7c3b6c1b929ff92d27da" + "sha256:6ef6d06de77ce2961156013e9dff62f1b2688aa04d0dc244299fe7d67e09370d", + "sha256:a736fed91c12681a7b34617c8fcefe39ea04599ca72c608751c31d89579a3f77" ], "index": "pypi", - "version": "==4.6.3" + "version": "==5.0.1" }, "pytest-cov": { "hashes": [ @@ -716,7 +720,6 @@ "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" ], - "index": "pypi", "version": "==2.22.0" }, "rope": { @@ -730,26 +733,26 @@ }, "ruamel.yaml": { "hashes": [ - "sha256:17dbf6b7362e7aee8494f7a0f5cffd44902a6331fe89ef0853b855a7930ab845", - "sha256:23731c9efb79f3f5609dedffeb6c5c47a68125fd3d4b157d9fc71b1cd49076a9", - "sha256:2bbdd598ae57bac20968cf9028cc67d37d83bdb7942a94b9478110bc72193148", - "sha256:34586084cdd60845a3e1bece2b58f0a889be25450db8cc0ea143ddf0f40557a2", - "sha256:35957fedbb287b01313bb5c556ffdc70c0277c3500213b5e73dfd8716f748d77", - "sha256:414cb87a40974a575830b406ffab4ab8c6cbd82eeb73abd2a9d1397c1f0223e1", - "sha256:428775be75db68d908b17e4e8dda424c410222f170dc173246aa63e972d094b3", - "sha256:514f670f7d36519bda504d507edfe63e3c20489f86c86d42bc4d9a6dbdf82c7b", - "sha256:5cb962c1ac6887c5da29138fbbe3b4b7705372eb54e599907fa63d4cd743246d", - "sha256:5f6e30282cf70fb7754e1a5f101e27b5240009766376e131b31ab49f14fe81be", - "sha256:86f8e010af6af0b4f42de2d0d9b19cb441e61d3416082186f9dd03c8552d13ad", - "sha256:8d47ed1e557d546bd2dfe54f504d7274274602ff7a0652cde84c258ad6c2d96d", - "sha256:98668876720bce1ac08562d8b93a564a80e3397e442c7ea19cebdcdf73da7f74", - "sha256:9e1f0ddc18d8355dcf5586a5d90417df56074f237812b8682a93b62cca9d2043", - "sha256:a7bc812a72a79d6b7dbb96fa5bee3950464b65ec055d3abc4db6572f2373a95c", - "sha256:b72e13f9f206ee103247b07afd5a39c8b1aa98e8eba80ddba184d030337220ba", - "sha256:bcff8ea9d916789e85e24beed8830c157fb8bc7c313e554733a8151540e66c01", - "sha256:c76e78b3bab652069b8d6f7889b0e72f3455c2b854b2e0a8818393d149ad0a0d" - ], - "version": "==0.15.97" + "sha256:035d1258d1f07c672a55263435a22f3292c50636bf8ed0fa6b90cee0a244e6bd", + "sha256:189437e108ef00104d21ee9aa57b2ae3927f3ab61bef0447a2fd21b82c64e4b2", + "sha256:25bb32cea6ee4bf7da680d80b51ec42081254f30e02d3f58db0653b041ae8185", + "sha256:2852fd6854cd8fb9342ae785d222af3d797e41fa712296f6cf7cd9ae0fee085d", + "sha256:340244ab265943bad541220466e56b0409f5bbcfe3750f417c4c15fabed27a9d", + "sha256:5cdea389d836f6f7386cf32dbe4c29ef82e517559bdf8ba4470ebe9d85ceda4f", + "sha256:6cb78ae9a515936a342adfb114513998a78333441e6599599ab6a7cab90f1999", + "sha256:72a89b03d7e9671340e19ef96ba9cc58b86a079190c0ab89b70ee5458b71748c", + "sha256:86278b7804111b6295069e05266e6faa06a426616ad11597c5c6fed14055b1bb", + "sha256:937908eb1fab3cc997e88960ccce21a44feb31711c2eb00bb2dbdcad645f5e77", + "sha256:95c2f135479957b2d6ca577f8a4bd2d22f78d566250cabf308b75b060100bcd4", + "sha256:9cecfbf214bb6ab93026ea180e429b76e8cc12782f4e531632b0ea0a407be543", + "sha256:a1f78fa84358631025bf393207c0b043b995ae76cb3963ce555be46932792d13", + "sha256:aee248b1583b577cb4dbda1fb24e67baae9af2f25eed849b45d9db077fa62c3b", + "sha256:bb7438aa4f81a0bed286498ec71e68c04f725b153dc52203fa4eed96ee898013", + "sha256:c9685b1788823bc3a34349322cb7268f949a2136d396de2b8044b1cd49cd5370", + "sha256:d3557962da02bbed24157b0de16343f6c264c4b691f6424f3b72dfcecbca592e", + "sha256:e93c86cbaee4c299fff8dbff5df6b22af78846ddd1e9fcb5e238489a4910cf29" + ], + "version": "==0.15.98" }, "scipy": { "hashes": [ @@ -782,10 +785,9 @@ }, "snowballstemmer": { "hashes": [ - "sha256:919f26a68b2c17a7634da993d91339e288964f93c274f1343e3bbbe2096e1128", - "sha256:9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89" + "sha256:9f3b9ffe0809d174f7047e121431acf99c89a7040f0ca84f94ba53a498e6d0c9" ], - "version": "==1.2.1" + "version": "==1.9.0" }, "sphinx": { "hashes": [ @@ -797,11 +799,11 @@ }, "sphinx-rtd-theme": { "hashes": [ - "sha256:aa3e190392e963551432de7df24b8a5fbe5b71a2f4fcd9d5b75808b52ad999e5", - "sha256:de88d637a60371d4f923e06b79c4ba260490c57d2ab5a8316942ab5d9a6ce1bf" + "sha256:00cf895504a7895ee433807c62094cf1e95f065843bf3acd17037c3e9a2becd4", + "sha256:728607e34d60456d736cc7991fd236afb828b21b82f956c5ea75f94c8414040a" ], "index": "pypi", - "version": "==0.4.0" + "version": "==0.4.3" }, "sphinxcontrib-applehelp": { "hashes": [ @@ -888,10 +890,10 @@ }, "zipp": { "hashes": [ - "sha256:8c1019c6aad13642199fbe458275ad6a84907634cc9f0989877ccc4a2840139d", - "sha256:ca943a7e809cc12257001ccfb99e3563da9af99d52f261725e96dfe0f9275bc3" + "sha256:4970c3758f4e89a7857a973b1e2a5d75bcdc47794442f2e2dd4fe8e0466e809a", + "sha256:8a5712cfd3bb4248015eb3b0b3c54a5f6ee3f2425963ef2a0125b8bc40aafaec" ], - "version": "==0.5.1" + "version": "==0.5.2" } } } diff --git a/aguaclara/core/utility.py b/aguaclara/core/utility.py index 72ae4071..dfbcf180 100644 --- a/aguaclara/core/utility.py +++ b/aguaclara/core/utility.py @@ -1,65 +1,203 @@ -"""This file provides basic utility functions such as significant figures which -can be used throughout the plant design. +"""Utility functions and features +This module provides functions and features for scientific calculations and +complex function inputs. + +Example: + >>> import aguaclara.core.utility as ut + >>> ut.round_sig_figs(1234567, 3) + 1230000 """ from aguaclara.core.units import unit_registry as u - import numpy as np -from math import log10, floor +from math import log10, floor, ceil +import warnings + +def optional_units(arg_positions, keys): + """Wrap a function so that arguments may optionally have units. + + This should be used as a function decorator; it will not do anything + meaningful unless it is appended with a ``@`` before another function. + + Example: + @optional_units([0, 1], ['num', 'step']) + def stepper(num, step=10, func=round): + step = step.to(num.units) + num = func(num / step) * step + return num + + Args: + - ``arg_positions (int list)``: Position indices of positional and + keyword arguments with optional units + - ``keys (str list)``: Names of positional and keyword arguments with + optional units + """ + # func is the function that is being decorated, and *args/**kwargs are the + # arguments being passed to that function. + def decorator(func): + def wrapper(*args, **kwargs): + args = list(args) + for i in range(len(args)): + if i in arg_positions: + args[i] *= u.dimensionless + + for key in list(kwargs.keys()): + if key in keys: + kwargs[key] *= u.dimensionless + + result = func(*args, **kwargs) + + # Convert back to native Python number type, if possible + if result.units == u.dimensionless: + result = result.magnitude + return result + return wrapper + return decorator -def round_sf(number, digits): - """Returns inputted value rounded to number of significant figures desired. +@optional_units([0], ['num']) +def round_sig_figs(num, figs=4): + """Round a number to some amount of significant figures. - :param number: Value to be rounded - :type number: float - :param digits: number of significant digits to be rounded to. - :type digits: int + Args: + - ``num (float)``: Value to be rounded (optional units) + - ``figs (int)``: Number of significant digits to be rounded to + (recommended, defaults to 4) """ - units = None - try: - num = number.magnitude - units = number.units - except AttributeError: - num = number - - try: - if (units != None): - rounded_num = round(num, digits - int(floor(log10(abs(num)))) - 1) * units - else: - rounded_num = round(num, digits - int(floor(log10(abs(num)))) - 1) - return rounded_num - except ValueError: # Prevents an error with log10(0) - if (units != None): - return 0 * units - else: - return 0 + # Prevents undefined log10(0) if num is already 0 + if num.magnitude != 0: + decimals = figs - int(floor(log10(abs(num.magnitude)))) - 1 + num = np.round(num.magnitude, decimals) * num.units + return num + +@optional_units([0, 1], ['num', 'step']) +def _stepper(num, step=10, func=round): + """Round a number to be a multiple of some step. + + Args: + - ``num (float)``: Value to be rounded (optional units) + - ``step (float)``: Factor to which ``num`` will be rounded (defaults + to 10). + - ``func (function)``: Rounding function to use (defaults to round()) + + Note: + ``step`` must have the same dimensionality as ``num``, but not + necessarily the same units (e.g. ``num``: meters and ``step``: + centimeters are acceptable). + """ + step = step.to(num.units) + num = func(num / step) * step + return num + +def round_step(num, step=10): + """Round a number to be a multiple of some step. + + Args: + - ``num (float)``: Value to be rounded (optional units) + - ``step (float)``: Factor to which ``num`` will be rounded (defaults + to 10). + + Note: + ``step`` must have the same dimensionality as ``num``, but not + necessarily the same units (e.g. ``num``: meters and ``step``: + centimeters are acceptable). + """ + return _stepper(num, step = step, func = round) + +def ceil_step(num, step=10): + """Like :func:`round_step`, but ``num`` is always rounded up.""" + return _stepper(num, step = step, func = ceil) + +def floor_step(num, step=10): + """Like :func:`round_step`, but ``num`` is always rounded down.""" + return _stepper(num, step = step, func = floor) def stepceil_with_units(param, step, unit): - """This function returns the smallest multiple of 'step' greater than or - equal to 'param' and outputs the result in Pint units. - This function is unit-aware and functions without requiring translation - so long as 'param' and 'unit' are of the same dimensionality. + """Round a number up to be a multiple of some step. + + Args: + - ``param (float)``: Value to be rounded (optional units) + - ``step (float)``: Factor to which ``param`` will be rounded + - ``unit (Quantity)``: units of ``step`` + + Note: this function will be deprecated after 21 Dec 2019. Use ceil_step + instead. """ + warnings.warn( + 'stepceil_with_units will be deprecated after 21 Dec 2019. Use ' + 'ceil_step instead.', + FutureWarning + ) counter = 0 * unit while counter < param.to(unit): counter += step * unit return counter +def floor_nearest(x, array): + """Get the nearest element of a NumPy array less than or equal to a value. -# Take the values of the array, compare to x, find the index of the first value less than or equal to x -def floor_nearest(x,array): - myindex = np.argmax(array >= x) - 1 - return array[myindex] + Args: + - ``x``: Value to compare + - ``array (numpy.array)``: Array to search + """ + i = np.argmax(array >= x) - 1 + return array[i] + +def ceil_nearest(x, array): + """Get the nearest element of a NumPy array less than or equal to a value. + Args: + - ``x``: Value to compare + - ``array (numpy.array)``: Array to search + """ + i = np.argmax(array >= x) + return array[i] -# Take the values of the array, compare to x, find the index of the first value greater or equal to x -def ceil_nearest(x,array): - myindex = np.argmax(array >= x) - return array[myindex] +def _minmax(*args, func=np.max): + """Get the minuimum/maximum value of some Pint quantities with units. + + Args: + - ``func (function)``: the min/max function being used. + + Note: + - All quantities must have the same dimensionality, but can have + different units. + - The output will have the same units as the first argument. + + Example: + >>> from aguaclara.play import * + >>> ut.max(10 * u.m, 100 * u.cm, 32 * u.cm, 40 * u.inch, 40 * u.km) + + """ + base_quantity = args[0] + lst = [] + + for arg in args: + lst.append((arg / base_quantity)) + + result = func(lst) * base_quantity + return result + +def max(*args): + """Get the maximum value of some Pint quantities with units. + + Note: + - All quantities must have the same dimensionality, but can have + different units. + - The output will have the same units as the first argument. + + Example: + >>> from aguaclara.play import * + >>> ut.max(10 * u.m, 100 * u.cm, 32 * u.cm, 40 * u.inch, 40 * u.km) + + """ + return _minmax(*args, func = np.max) +def min(*args): + """Like :func:`max`, but the minimum of the quantites.""" + return _minmax(*args, func = np.min) def list_handler(HandlerResult="nparray"): """Wraps a function to handle list inputs.""" @@ -204,4 +342,4 @@ def array_qtys_to_strs(lst): - ``lst (numpy.ndarray Quantity)``: a list of values that has a Pint unit attached to it """ - return [str(value) for value in lst] \ No newline at end of file + return [str(value) for value in lst] diff --git a/aguaclara/design/ent.py b/aguaclara/design/ent.py index 78cda443..0525cdf7 100644 --- a/aguaclara/design/ent.py +++ b/aguaclara/design/ent.py @@ -115,7 +115,7 @@ def plate_l(self): np.cos(self.plate_angle.to(u.rad)) ) ) - (self.plate_s * np.tan(self.plate_angle.to(u.rad))).to(u.cm) - plate_l_rounded = ut.stepceil_with_units(plate_l, 1.0, u.cm) + plate_l_rounded = ut.ceil_step(plate_l, 1.0 * u.cm) return plate_l_rounded @property diff --git a/docs/source/conf.py b/docs/source/conf.py index 07e4a677..d2f8268d 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -20,7 +20,7 @@ # -- Project information ----------------------------------------------------- project = u'AguaClara' -copyright = u'2018, AguaClara Cornell' +copyright = u'2019, AguaClara Cornell' author = u'AguaClara Cornell' # The short X.Y version @@ -91,6 +91,12 @@ # # html_theme_options = {} +# The name of an image file (relative to this directory) to use as a favicon of +# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# +html_favicon = 'images/favicon.ico' + # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". diff --git a/docs/source/core/utility.rst b/docs/source/core/utility.rst index fffc4ded..056bd071 100644 --- a/docs/source/core/utility.rst +++ b/docs/source/core/utility.rst @@ -3,3 +3,4 @@ Utility .. automodule:: aguaclara.core.utility :members: + :exclude-members: stepceil_with_units \ No newline at end of file diff --git a/docs/source/images/favicon.ico b/docs/source/images/favicon.ico new file mode 100644 index 00000000..84ec174c Binary files /dev/null and b/docs/source/images/favicon.ico differ diff --git a/docs/source/index.rst b/docs/source/index.rst index c626078e..2ab40ef3 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,5 +1,5 @@ =========================== -``aguaclara`` Documentation +Home =========================== .. image:: images/logo.png diff --git a/meta.yaml b/meta.yaml index 4f53d65b..abe2690b 100644 --- a/meta.yaml +++ b/meta.yaml @@ -36,11 +36,11 @@ test: - aguaclara about: - home: https://github.com/AguaClara/aguaclara_design + home: https://github.com/AguaClara/aguaclara license: MIT license_family: MIT license_file: '' - summary: AguaClara Infrastructure Design Engine + summary: AguaClara Software Package description: '' doc_url: '' dev_url: '' diff --git a/tests/core/test_utility.py b/tests/core/test_utility.py index 09c23bb9..5e46d1d0 100644 --- a/tests/core/test_utility.py +++ b/tests/core/test_utility.py @@ -5,9 +5,18 @@ class UtilityTest(unittest.TestCase): - def test_round_sf(self): - self.assertAlmostEqual(ut.round_sf(123456.789, 8), 123456.79) - self.assertAlmostEqual(ut.round_sf(20.01 * u.L/u.s, 2), 20 * u.L/u.s) - self.assertAlmostEqual(ut.round_sf(-456.789 * u.L/u.s, 4), -456.8 * u.L/u.s) - self.assertAlmostEqual(ut.round_sf(0, 4), 0) - self.assertAlmostEqual(ut.round_sf(0 * u.m, 4), 0 * u.m) + def test_round_sig_figs(self): + self.assertAlmostEqual(ut.round_sig_figs(123456.789, 8), 123456.79) + self.assertAlmostEqual(ut.round_sig_figs(20.01 * u.L/u.s, 2), 20 * u.L/u.s) + self.assertAlmostEqual(ut.round_sig_figs(-456.789 * u.L/u.s, 4), -456.8 * u.L/u.s) + self.assertAlmostEqual(ut.round_sig_figs(0, 4), 0) + self.assertAlmostEqual(ut.round_sig_figs(0 * u.m, 4), 0 * u.m) + def test_max(self): + self.assertEqual(ut.max(2 * u.m, 4 * u.m),4 * u.m) + self.assertEqual(ut.max(3 * u.m, 1 * u.m, 6 * u.m, 10 * u.m, 1.5 * u.m), 10 * u.m) + self.assertEqual(ut.max(2 * u.m),2 * u.m) + + def test_min(self): + self.assertEqual(ut.min(2 * u.m, 4 * u.m), 2 * u.m) + self.assertEqual(ut.min(3 * u.m, 1 * u.m, 6 * u.m, 10 * u.m, 1.5 * u.m), 1 * u.m) + self.assertEqual(ut.min(2 * u.m), 2 * u.m) \ No newline at end of file diff --git a/tests/design/test_ent_floc.py b/tests/design/test_ent_floc.py index 04501b09..dc53b38c 100644 --- a/tests/design/test_ent_floc.py +++ b/tests/design/test_ent_floc.py @@ -1,5 +1,6 @@ from aguaclara.design.ent_floc import EntTankFloc from aguaclara.core.units import unit_registry as u +import aguaclara.core.utility as ut import pytest @@ -8,7 +9,7 @@ @pytest.mark.parametrize('actual, expected', [ (etf_20.ent.l, 37.6732811402825 * u.inch), - (etf_60.ent.l, 59.945577185244304 * u.inch), + (etf_60.ent.l, 59.94557718524431 * u.inch), (etf_20.floc.chan_w, 0.45 * u.m), (etf_60.floc.chan_w, 0.4377982708968249 * u.m)