{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Units and Quantities\n", "\n", "## Objectives\n", "\n", "- Use units\n", "- Create functions that accept quantities as arguments\n", "- Create new units" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Basics\n", "\n", "How do we define a Quantity and which parts does it have?" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false, "keep": true }, "outputs": [], "source": [ "from astropy import units as u\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "26.2 m\n" ] } ], "source": [ "# Define a quantity length\n", "length = 26.2 * u.meter\n", "# print it\n", "print(length) # length is a quantity" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "astropy.units.quantity.Quantity" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Type of quantity\n", "type(length)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "astropy.units.core.IrreducibleUnit" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Type of unit\n", "type(u.meter)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$26.2 \\; \\mathrm{m}$" ], "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Quantity\n", "length" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "26.2" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# value\n", "length.value" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$\\mathrm{m}$" ], "text/plain": [ "Unit(\"m\")" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# unit\n", "length.unit" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "dtype = float64\n", "unit = m\n", "class = Quantity\n", "n_bad = 0" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# information\n", "length.info" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Quantities can be converted to other units systems or factors by using `to()`" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.0262 km\n", "2.76934218514e-15 lyr\n" ] } ], "source": [ "# Convert it to: km, lyr\n", "print(length.to(u.km))\n", "print(length.to(u.lightyear))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can do arithmetic operations when the quantities have the compatible units:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "22.99999 km\n" ] } ], "source": [ "# arithmetic with distances\n", "distance_start = 10 * u.mm\n", "distance_end = 23 * u.km\n", "length = distance_end - distance_start\n", "print(length)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Quantities can also be combined, for example to measure speed" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.53333266667 km / min\n" ] } ], "source": [ "# calculate a speed\n", "time = 15 * u.minute\n", "speed = length / time\n", "print(speed)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "25.5555444444 m / s\n", "25.5555444444 m / s\n" ] } ], "source": [ "# decompose it\n", "print(speed.decompose())\n", "print(speed.si)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Challenges

\n", "\n", "
    \n", "
  1. Convert the speed in imperial units (miles/hour) using:
    \n", "\n", " ```from astropy.units import imperial```\n", "
  2. \n", "
  3. Calculate whether a pint is more than half litre
    \n", " \n", " You can compare quantities as comparing variables.
    \n", " Something strange? Check what deffinition of pint astropy is using.\n", "
  4. \n", "
  5. Does units work with areas? calculate the area of a rectangle of 3 km of side and 5 meter of width. Show them in m^2 and convert them to yards^2
  6. \n", "
" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "57.166124831 mi / h\n" ] } ], "source": [ "#1\n", "from astropy.units import imperial\n", "print(speed.to(imperial.mile/u.hour))" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#2\n", "imperial.pint > 0.5 * u.l\n", " # A liquid pint in US is 473 ml; in UK is 568 ml" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "15.0 km m\n", "15000.0 m2\n", "17939.8506945 yd2\n" ] } ], "source": [ "#3\n", "rectangle_area = 3 * u.km * 5 * u.m\n", "print(rectangle_area)\n", "print(rectangle_area.decompose())\n", "print(rectangle_area.to(imperial.yard ** 2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Composed units\n", "\n", "Many units are compositions of others, for example, one could create new combinationes for ease of use:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$2555.5544 \\; \\mathrm{\\frac{cm}{s}}$" ], "text/plain": [ "" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# create a composite unit\n", "cms = u.cm / u.s\n", "speed.to(cms)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$57.166125 \\; \\mathrm{\\frac{mi}{h}}$" ], "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# and in the imperial system\n", "mph = imperial.mile / u.hour\n", "speed.to(mph)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and others are already a composition:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[Unit(\"Hz\"), Unit(\"Bq\"), Unit(\"3.7e+10 Ci\")]" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# what can be converted from s-1?\n", "(u.s ** -1).compose()" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[Unit(\"J\"), Unit(\"1e+07 erg\"), Unit(\"4.58742e+17 Ry\"), Unit(\"6.24151e+18 eV\")]" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# or Jules?\n", "(u.joule).compose()\n" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$0.99999996 \\; \\mathrm{R_{\\infty}}$" ], "text/plain": [ "" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Unity of R\n", "(13.605692 * u.eV).to(u.Ry)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sometime we get *no units* quantitites" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$20 \\; \\mathrm{\\frac{cm}{m}}$" ], "text/plain": [ "" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# no units\n", "nounits = 20. * u.cm / (1. * u.m)\n", "nounits" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What happen if we add a number to this?" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$3.2 \\; \\mathrm{}$" ], "text/plain": [ "" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# arithmetic with no units\n", "nounits + 3" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$0.2 \\; \\mathrm{}$" ], "text/plain": [ "" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# final value of a no unit quantity\n", "nounits.decompose() # It's a unitless quantity\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Equivalencies\n", "\n", "Some conversions are not done by a conversion factor as between miles and kilometers, for example converting between wavelength and frequency." ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "ename": "UnitConversionError", "evalue": "'nm' (length) and 'Hz' (frequency) are not convertible", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mUnitConversionError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m# converting spectral quantities\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[1;33m(\u001b[0m\u001b[1;36m656.281\u001b[0m \u001b[1;33m*\u001b[0m \u001b[0mu\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mnm\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mto\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mu\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mHz\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# Fails because they are not compatible\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;32m/home/dvd/.conda/envs/swc/lib/python2.7/site-packages/astropy/units/quantity.pyc\u001b[0m in \u001b[0;36mto\u001b[1;34m(self, unit, equivalencies)\u001b[0m\n\u001b[0;32m 631\u001b[0m \u001b[0munit\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mUnit\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0munit\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 632\u001b[0m new_val = self.unit.to(unit, self.view(np.ndarray),\n\u001b[1;32m--> 633\u001b[1;33m equivalencies=equivalencies)\n\u001b[0m\u001b[0;32m 634\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_new_view\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnew_val\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0munit\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 635\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;32m/home/dvd/.conda/envs/swc/lib/python2.7/site-packages/astropy/units/core.pyc\u001b[0m in \u001b[0;36mto\u001b[1;34m(self, other, value, equivalencies)\u001b[0m\n\u001b[0;32m 966\u001b[0m \u001b[0mIf\u001b[0m \u001b[0munits\u001b[0m \u001b[0mare\u001b[0m \u001b[0minconsistent\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 967\u001b[0m \"\"\"\n\u001b[1;32m--> 968\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_get_converter\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mother\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mequivalencies\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mequivalencies\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mvalue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 969\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 970\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0min_units\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mother\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mvalue\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m1.0\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mequivalencies\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;32m/home/dvd/.conda/envs/swc/lib/python2.7/site-packages/astropy/units/core.pyc\u001b[0m in \u001b[0;36m_get_converter\u001b[1;34m(self, other, equivalencies)\u001b[0m\n\u001b[0;32m 867\u001b[0m \u001b[1;32mexcept\u001b[0m \u001b[0mUnitsError\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 868\u001b[0m return self._apply_equivalencies(\n\u001b[1;32m--> 869\u001b[1;33m self, other, self._normalize_equivalencies(equivalencies))\n\u001b[0m\u001b[0;32m 870\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[1;32mlambda\u001b[0m \u001b[0mval\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mscale\u001b[0m \u001b[1;33m*\u001b[0m \u001b[0m_condition_arg\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mval\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 871\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;32m/home/dvd/.conda/envs/swc/lib/python2.7/site-packages/astropy/units/core.pyc\u001b[0m in \u001b[0;36m_apply_equivalencies\u001b[1;34m(self, unit, other, equivalencies)\u001b[0m\n\u001b[0;32m 858\u001b[0m raise UnitConversionError(\n\u001b[0;32m 859\u001b[0m \"{0} and {1} are not convertible\".format(\n\u001b[1;32m--> 860\u001b[1;33m unit_str, other_str))\n\u001b[0m\u001b[0;32m 861\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 862\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0m_get_converter\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mother\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mequivalencies\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mUnitConversionError\u001b[0m: 'nm' (length) and 'Hz' (frequency) are not convertible" ] } ], "source": [ "# converting spectral quantities\n", "(656.281 * u.nm).to(u.Hz) # Fails because they are not compatible" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$4.5680502 \\times 10^{14} \\; \\mathrm{Hz}$" ], "text/plain": [ "" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# but doing it right\n", "(656.281 * u.nm).to(u.Hz, equivalencies=u.spectral())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Other built-in equivalencies are: \n", " - `parallax()`\n", " - Doppler (`dopplr_radio`, `doppler_optical`, `doppler_relativistic`)\n", " - spectral flux density\n", " - brigthness temperature\n", " - temperature energy\n", " - and you can [build your own](http://astropy.readthedocs.org/en/stable/units/equivalencies.html#writing-new-equivalencies)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ " Primary name | Unit definition | Aliases \n", "[\n", " Bq | 1 / s | becquerel ,\n", " Ci | 2.7027e-11 / s | curie ,\n", " Hz | 1 / s | Hertz, hertz ,\n", "]" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# finding the equivalencies\n", "u.Hz.find_equivalent_units()" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ " Primary name | Unit definition | Aliases \n", "[\n", " AU | 1.49598e+11 m | au, astronomical_unit ,\n", " Angstrom | 1e-10 m | AA, angstrom ,\n", " Bq | 1 / s | becquerel ,\n", " Ci | 2.7027e-11 / s | curie ,\n", " Hz | 1 / s | Hertz, hertz ,\n", " J | kg m2 / s2 | Joule, joule ,\n", " Ry | 2.17987e-18 kg m2 / s2 | rydberg ,\n", " cm | 0.01 m | centimeter ,\n", " eV | 1.60218e-19 kg m2 / s2 | electronvolt ,\n", " erg | 1e-07 kg m2 / s2 | ,\n", " k | 100 / m | Kayser, kayser ,\n", " lyr | 9.46073e+15 m | lightyear ,\n", " m | irreducible | meter ,\n", " micron | 1e-06 m | ,\n", " pc | 3.08568e+16 m | parsec ,\n", " solRad | 6.95508e+08 m | R_sun, Rsun ,\n", "]" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# but also using other systems\n", "u.Hz.find_equivalent_units(equivalencies=u.spectral())\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Printing the quantities" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.533 km min-1\n", "1.533 $\\mathrm{km\\,min^{-1}}$\n" ] } ], "source": [ "# Printing values with different formats\n", "print(\"{0.value:0.03f} {0.unit:FITS}\".format(speed))\n", "print(\"{0.value:0.03f} {0.unit:latex_inline}\".format(speed))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Arrays\n", "\n", "Quantities can also be applied to arrays" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$1.9130435 \\; \\mathrm{\\frac{m}{s}}$" ], "text/plain": [ "" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# different ways of defining a quantity for a single value\n", "length = 44 * u.m\n", "time = u.Quantity(23, u.s)\n", "speed = length / time\n", "speed" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$[1,~1,~1] \\; \\mathrm{\\frac{m}{s}}$" ], "text/plain": [ "" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# now with lists\n", "length_list = [1, 2, 3] * u.m\n", "\n", "# and arrays\n", "import numpy as np\n", "time_array = np.array([1, 2, 3]) * u.s\n", "\n", "# and its arithmetics\n", "length_list / time_array" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 0. 179.] deg\n", "[ 0. 0.01745241]\n" ] } ], "source": [ "# angles are smart!\n", "angle = u.Quantity(np.arange(180), u.deg)\n", "print(angle[[0, -1]])\n", "print(np.sin(angle[[0, -1]]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plotting quantities\n", "\n", "To work nicely with matplotlib we need to do as follows:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "collapsed": false, "keep": true }, "outputs": [], "source": [ "# allowing for plotting\n", "from astropy.visualization import quantity_support\n", "quantity_support()\n", "\n", "# loading matplotlib\n", "%matplotlib inline\n", "from matplotlib import pyplot as plt\n" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Ploting the previous array\n", "plt.plot(angle, np.sin(angle))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Creating functions with quantities as units\n", "\n", "We want to have functions that contain the information of the untis, and with them we can be sure that we will be always have the *right* result." ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Create a function for the Kinetic energy\n", "@u.quantity_input(mass=u.kg, speed=u.m/u.s)\n", "def kinetic(mass, speed):\n", " return (mass * speed ** 2 / 2.).to(u.joule)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$2.5 \\; \\mathrm{J}$" ], "text/plain": [ "" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# run with and without units\n", "kinetic(5, 10) # Fails! it doesn't specify the units.\n", "kinetic(5 * u.kg, 100 * cms)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Challenges

\n", "\n", "
    \n", "
  1. Create a function that calculates potential energy where *g* defaults to Earth value, \n", " but could be used for different planets. \n", " Test it for any of the *g* values for any other \n", " planet.\n", "
  2. \n", "
\n", "
" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": true }, "outputs": [], "source": [ "#4\n", "@u.quantity_input(mass=u.kg, height=u.m, g=u.m / u.s ** 2)\n", "def potential(mass, height, g=9.8 * u.m / u.s **2):\n", " return (0.5 * mass * g * height).to(u.joule)\n" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$7.35 \\; \\mathrm{J}$" ], "text/plain": [ "" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# run it for some values\n", "potential(5 * u.kg, 30 *u.cm)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/latex": [ "$9.375 \\; \\mathrm{J}$" ], "text/plain": [ "" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# on Mars:\n", "potential(5 * u.kg, 1 * u.m, g=3.75 * u.m/u.s**2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create your own units\n", "\n", "Some times we want to create our own units:" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "240.0 titter\n" ] } ], "source": [ "# Create units for a laugh scale\n", "titter = u.def_unit('titter')\n", "chuckle = u.def_unit('chuckle', 5 * titter)\n", "laugh = u.def_unit('laugh', 4 * chuckle)\n", "guffaw = u.def_unit('guffaw', 3 * laugh)\n", "rofl = u.def_unit('rofl', 4 * guffaw)\n", "death_by_laughing = u.def_unit('death_by_laughing', 10 * rofl)\n", "print((1 * rofl).to(titter))\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Challenges

\n", "\n", "
    \n", "
  1. Convert the area calculated before `rectangle_area` in Hectare\n", " (1 hectare = 100 ares; 1 are = 100 m2).\n", "
  2. \n", "
\n", "
" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.5 hectares\n" ] } ], "source": [ "#5\n", "ares = u.def_unit('ares', (10 * u.m)**2)\n", "hectar = u.def_unit('hectares', 100 * ares)\n", "print(rectangle_area.to(hectar))" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python2", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.11" } }, "nbformat": 4, "nbformat_minor": 0 }