\n\n## Installing\nInstall from PyPI:\n````sh\n$ pip install unit_parser\n````\n\n## Usage\nThis library is primarily for parsing strings representing physical\nquantities, like \"5 feet\" or \"88 miles_per_hour\". It can also be used\nfor converting between compatible units and doing basic arithmetic\noperations.\n\nThe parsing function does double duty as a method for converting\nbetween units and is thus called \"convert\".\n```sh\n >>> from unit_parser import unit_parser\n >>> up = unit_parser()\n >>> up.convert(\"3 gallons\", \"liters\")\n 11.356235352\n```\nIt may seem a little strange to have the number as part of the string,\nbut keep in mind this function is used in the context of converting\ntext inputs. For convenience, the---perhaps more intuitive---syntax\nworks as well:\n```sh\n >>> up.convert(3, \"gallons\", \"liters\")\n 11.356235352\n```\nNote the unit parser must be initialized before being used by calling\nthe unit_parser() function without any arguments. That uses the\nbuilt-in unit specification file to define the units recognized by\nthis library. If a unit is not supported, you can create your own unit\nspecification file and provide the file name to this function.\n\nThe next thing we see is that physical quantities and units are\nrepresented by strings. I find this to be the most intuitive way of\ninteracting with physical quantities. (Aside, something like \"3\ngallons\" is a physical quantity, while \"liters\" is a unit.)\n\nSince we represent physical quantities by strings, it is trivial to\nuse the convert function to parse an input in unknown units, but\nensure it is in the appropriate units for the needs of the program.\nFor example, suppose we have a program that does calculations on\nvolumes of water. Suppose there is an input (e.g. from a JSON file)\nrepresenting how much volume of water is to be used. The user is free\nto specify the input in whatever units are most convenient, e.g. \"2\ngallons\". The code that is parsing this input might call:\n\n```sh\n >>> import json\n >>> from unit_parser import unit_parser\n >>> up = unit_parser()\n >>> config = json.load(open('example.json', 'r'))\n >>> water_volume = config['water_volume']\n >>> water_volume_liters = up.convert(water_volume, \"liters\")\n```\n\nIn this way, no assumptions need to be made about what units the input\nis in. The code requires the water volume to be expressed in liters,\nbut it doesn't need to know or care how it was specified.\n\nAlthough the above example seems trivial, perhaps the most interesting\nfeature is the flexible unit specification parsing. Units may be\nspecified by a definition file (built-in, or provide your own!), or by\ncombinations of units defined in that file.\n\nFor example, if 'second', 'meter', and 'kilogram' are defined by the\nfile, the specification 'kilogram_meter_per_second_squared' is valid\nand parsed as expected. These compound specifications consist of\ntokens separated by underscores. Tokens include previously defined\nunits like 'kilogram' as well as the special keywords 'per',\n'squared', and 'cubed'.\n\nThe keyword 'per' may be used at most once per specification and\ndirects that all subsequent tokens belong in the denominator of the\nunit.\n\nThe keywords 'squared' and 'cubed' indicate that the preceding token\nshould be repeated once or twice more, respectively. They cannot be\ndaisy chained, for example: 'meters_squared_squared' is not permitted,\nbut 'meters_squared_meters_squared' or 'meters_cubed_meters' would\nbe. They also only apply to the preceding token, so\n'second_second_meter_meter' is equivalent to\n'second_squared_meter_squared' but not 'second_meter_squared'.\n\nFinally, 'second', 'seconds', and 'sec' are not automatically\ntreated as equivalent units, but the unit definition file can and\ndoes create these as if they were aliases. For example, 'seconds'\nis defined as '1 second'.\n\nWe also permit simple arithmetic operations on units. There are\nfunctions \"add\", \"subtract\", \"multiply\", and \"divide\". Each function\ntakes three arguments: two physical quantities, and the desired units\nof the answer.\n\n```sh\n >>> from unit_parser import unit_parser\n >>> up = unit_parser()\n >>> up.add(\"5 meters\", \"2 feet\", \"yards\")\n 6.13473315836\n >>> up.subtract(\"5 meters\", \"2 feet\", \"yards\")\n 4.80139982502\n >>> up.multiply(\"5 meters_per_sec_squared\", \"2 kg\", \"pounds\")\n 2.248089431\n >>> up.divide(\"5 meters\", \"2 sec\", \"mph\")\n 5.59234073014\n```\n\nAs mentioned above, this library ships with a unit specification\nfile. It contains many of the most common units, but you may find some\nglaring omissions. For your particular use case, you may prefer to\ncreate your own unit specification file and include that with your\napplication. The unit specification file syntax is simple, if not\nintuitive. The file is plain-text, with key-value pairs separated by a\ncolon. Comments may be included and begin with a pound symbol\n(#). Units are either specified as primitives, or in terms of other\nunits. A primitive definition consists of specifying the signature of\nthe unit, which is represented as a vector of non-negative\nintegers. For example:\n````sh\nsecond: [1 0 0]\n````\nThe entries of this vector correspond to the exponents of units in an\narbitrary order that nonetheless needs to be consistent throughout the\napplication. We might arbitrarily decide that time units go first,\nthen length, then mass. Then since force has dimension mass times\nlength divided by time squared, all units of force have signature [-2\n1 1]. The way we define the second really just tells the program which\nindex (the first) corresponds to a particular primitive. A more\ncomplete specification might look like this:\n````sh\nsecond: [1 0 0]\nmeter: [0 1 0]\nkilogram: [0 0 1]\nminute: 60 second\nhour: 60 minute\n# We can define a newton either like this:\nnewton: 1 kilogram_meter_per_second_squared\n# or like this:\n# newton: [-2 1 1]\n# (first way preferred).\n````\nOnce we have defined the \"primitive\" units, it is simple and intuitive\nto define other units recursively in terms of previously specified\nunits. For example, the newton could have been defined in terms of its\nsignature, but it is better to define it in terms of kilograms,\nmeters, and seconds. A pound (of force) could *not* have been defined\nin terms of its signature, because although it has the same signature,\nit has a different quantity. Meaning, a pound is *not* equal to one\nkilogram meter per second squared, and defining units in terms of\nsignatures implicitly assumes the quantity is one.\n\nThe included unit specification file uses MKS (meters, kilograms,\nseconds) as the base, but as long as the internal specification is\nconsistent, that is transparent to the user of such a file. A unit\nspecification file using imperial units as the base would be just as\nvalid, and the end user would never even notice.\n\nIf you are the sort of person that enjoys reading esoteric Wikipedia\npages, the flexible syntax gives the fun opportunity to look up the\nofficial definitions of units, and using that in the file. For\nexample, it turns out the slug, which is a unit of mass in the\nimperial system, is actually defined as one pound of force times one\nsecond squared per foot. So this unit of mass is actually defined in\nterms of a unit of force, even though conceptually mass seems like the\nmore primitive notion! The included unit file tries to be faithful to\nthese definitions. The reader may quite reasonably ask if it makes any\ndifference. The answer is no, except perhaps for the fun of it. (If\nyou are *not* the sort of person who enjoys reading esoteric Wikipedia\narticles, this whole paragraph makes me sound like a weirdo.)\n\nFinally, this library ships with a command line utility called\n\"convert\". This can be run from the command line like so:\n````sh\n$ convert 5 feet to meters\n1.524\n````\n(The \"to\" is optional, but I find it more intuitive to include it.)\n",
"description_content_type": null,
"docs_url": null,
"download_url": "",
"downloads": {
"last_day": -1,
"last_month": -1,
"last_week": -1
},
"home_page": "https://github.com/rwilson4/unit_parser",
"keywords": "unit",
"license": "Apache 2.0",
"maintainer": "",
"maintainer_email": "",
"name": "unit_parser",
"package_url": "https://pypi.org/project/unit_parser/",
"platform": "",
"project_url": "https://pypi.org/project/unit_parser/",
"project_urls": {
"Homepage": "https://github.com/rwilson4/unit_parser"
},
"release_url": "https://pypi.org/project/unit_parser/0.2/",
"requires_dist": null,
"requires_python": "",
"summary": "Unit Parser and Conversions",
"version": "0.2"
},
"last_serial": 3615534,
"releases": {
"0.1": [
{
"comment_text": "",
"digests": {
"md5": "d4c5508a3c6473c25a27c699613e8caa",
"sha256": "ea1aaca75d882314044cbded7bc6bc40cf1e0556986aab15c83f93f0772c32fb"
},
"downloads": -1,
"filename": "unit_parser-0.1.tar.gz",
"has_sig": false,
"md5_digest": "d4c5508a3c6473c25a27c699613e8caa",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 16482,
"upload_time": "2017-12-11T01:34:51",
"url": "https://files.pythonhosted.org/packages/6a/80/c627876b618e5e1c89451f3b81c06833ddc72808231594b5787d9fb4ebda/unit_parser-0.1.tar.gz"
}
],
"0.2": [
{
"comment_text": "",
"digests": {
"md5": "85584d66ec7527f9b87c74e999e9476f",
"sha256": "f0e2de99315b1ab1592d647c7cabd6971693b04ea318c05768df6bf413a73cb5"
},
"downloads": -1,
"filename": "unit_parser-0.2.tar.gz",
"has_sig": false,
"md5_digest": "85584d66ec7527f9b87c74e999e9476f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 17071,
"upload_time": "2018-02-25T23:57:58",
"url": "https://files.pythonhosted.org/packages/6f/3e/8a562019a046fc69b0427c298dafd8b480dd0a6af5b64d2ec71406f1a540/unit_parser-0.2.tar.gz"
}
]
},
"urls": [
{
"comment_text": "",
"digests": {
"md5": "85584d66ec7527f9b87c74e999e9476f",
"sha256": "f0e2de99315b1ab1592d647c7cabd6971693b04ea318c05768df6bf413a73cb5"
},
"downloads": -1,
"filename": "unit_parser-0.2.tar.gz",
"has_sig": false,
"md5_digest": "85584d66ec7527f9b87c74e999e9476f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 17071,
"upload_time": "2018-02-25T23:57:58",
"url": "https://files.pythonhosted.org/packages/6f/3e/8a562019a046fc69b0427c298dafd8b480dd0a6af5b64d2ec71406f1a540/unit_parser-0.2.tar.gz"
}
]
}