{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Practical tips" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Numerics" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A [double-precision floiting point number](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) is stored in a total of 64 bits (1 sign bit, 11-bit exponent, 52-bit mantissa). This corresponds to about 15 decimal digits of precision. Any calculation resulting in a higher precision is subject to rounding errors. An upper bound of the relative error due to rounding can be obtain in python like this:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2.220446049250313e-16" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import sys\n", "sys.float_info.epsilon" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Comparing floating point numbers" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "0.3**2 == 0.09" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "0.2**2 == 0.04" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "np.isclose((0.2)**2, 0.04)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Range of floating point numbers" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.2250738585072014e-308 1.7976931348623157e+308\n" ] } ], "source": [ "print(sys.float_info.min, sys.float_info.max)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In numpy, results that are larger than the maximum range a set to `inf` or `-inf`, respectively." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "inf\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ ":1: RuntimeWarning: overflow encountered in exp\n", " a = np.exp(1000)\n" ] } ], "source": [ "a = np.exp(1000)\n", "print(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Undefined operations result in the floating point value [`nan`](https://en.wikipedia.org/wiki/NaN)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "nan nan nan\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ ":1: RuntimeWarning: invalid value encountered in sqrt\n", " print(np.sqrt(-1), np.log(-1), np.arcsin(1.1))\n", ":1: RuntimeWarning: invalid value encountered in log\n", " print(np.sqrt(-1), np.log(-1), np.arcsin(1.1))\n", ":1: RuntimeWarning: invalid value encountered in arcsin\n", " print(np.sqrt(-1), np.log(-1), np.arcsin(1.1))\n" ] } ], "source": [ "print(np.sqrt(-1), np.log(-1), np.arcsin(1.1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Clean code" ] }, { "attachments": { "b51d942c-f39b-416f-aa39-c53ca8f64bb2.png": { "image/png": "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" } }, "cell_type": "markdown", "metadata": {}, "source": [ "See [https://xkcd.com/844/](https://xkcd.com/844/)\n", "\n", "![good_code.png](attachment:b51d942c-f39b-416f-aa39-c53ca8f64bb2.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A key issue in large software project is to manage complexity. The total cost have of having a mess can be large in terms of wasted time and money. From Robert C. Martin books [Clean code](https://www.amazon.de/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=sr_1_1?__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91&dchild=1&keywords=clean+code&qid=1612906152&sr=8-1): \"As the mess builds, the productivity of the team continues to decrease, asymptotically approaching zero\". \n", "\n", "A few simple rule might help. The text below was adapted from\n", "* [Jamie Bullock, Clean Code: 5 Essential Takeaways](https://medium.com/better-programming/clean-code-5-essential-takeaways-2a0b17ccd05c)\n", "* [Esteban Solorzano, Clean Code in Python](https://medium.com/dev-genius/clean-code-in-python-8251eea292fa)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Keep it short\n", "* Function bodies should be short — hardly ever longer than 20 lines and mostly less than 10 lines\n", "* Functions should take as few arguments as possible" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### The DRY Principle: Don't repeat yourself" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "DRY principle as defined in the book *The Pragmatic Programmer*:\n", "\n", "\"*Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.*\"\n", "\n", "When the [DRY principle](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) is applied successfully, a modification of any single element of a system does not require a change in other logically unrelated elements. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Make Code Self-Documenting\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"Clear and expressive code with few comments is far superior to cluttered and complex code with lots of comments. — Robert C. Martin\n", "\n", "Not so clear:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " // Check to see if the employee is eligible for full benefits\n", " if ((employee.flags & HOURLY_FLAG) &&\n", " (employee.age > 65))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Better:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " if (employee.isEligibleForFullBenefits())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Use meaningful and intention-revealing names\n", "* Example: `int elapsedTimeInDay` is better than `int days`\n", "* Function names should say what they do" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Unit tests\n", "\"Unit tests are typically automated tests written and run by software developers to ensure that a section of an application (known as the \"unit\") meets its design and behaves as intended.\" (from the wikipedia article on [unit testing](https://en.wikipedia.org/wiki/Unit_testing))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### From the Zen of Python\n", "* Beautiful is better than ugly.\n", "* Simple is better than complex.\n", "* Readability counts.\n", "\n", "(Try `import this`)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The Zen of Python, by Tim Peters\n", "\n", "Beautiful is better than ugly.\n", "Explicit is better than implicit.\n", "Simple is better than complex.\n", "Complex is better than complicated.\n", "Flat is better than nested.\n", "Sparse is better than dense.\n", "Readability counts.\n", "Special cases aren't special enough to break the rules.\n", "Although practicality beats purity.\n", "Errors should never pass silently.\n", "Unless explicitly silenced.\n", "In the face of ambiguity, refuse the temptation to guess.\n", "There should be one-- and preferably only one --obvious way to do it.\n", "Although that way may not be obvious at first unless you're Dutch.\n", "Now is better than never.\n", "Although never is often better than *right* now.\n", "If the implementation is hard to explain, it's a bad idea.\n", "If the implementation is easy to explain, it may be a good idea.\n", "Namespaces are one honking great idea -- let's do more of those!\n" ] } ], "source": [ "import this" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.5" } }, "nbformat": 4, "nbformat_minor": 4 }