Last active
June 21, 2018 19:11
-
-
Save brianspiering/6921253524fe0a058d4de8aa0d306c02 to your computer and use it in GitHub Desktop.
Python's Mathematical Gotchas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Python's Mathematical Gotchas\n", | |
"--------\n", | |
"\n", | |
"Python is a nice computer language for the \"maths\". I'm looking at you [`math.tau`](https://www.python.org/dev/peps/pep-0628/) and [SymPy](http://www.sympy.org/) But like all finite machine languages, Python can not flawlessly instantiate the rich world of mathematics.\n", | |
"\n", | |
"tl;dr: Choosing modern, specific tools within Python can assist. Sometimes it is worth being \"fancy\" to be more accurate.\n", | |
"\n", | |
"__Several Rough Edge Cases__:\n", | |
"\n", | |
"1. Mathematical Constants That Change\n", | |
"1. Rational Number Shenanigans\n", | |
"1. Specific Tools > General Tools\n", | |
"\n", | |
"All of these examples have been adapted from [Raymond Hettinger](https://twitter.com/raymondh?lang=en). Follow him and develop as a developer." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Mathematical Constants That Change\n", | |
"------" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 34, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"3.14159265359\n" | |
] | |
} | |
], | |
"source": [ | |
"%%python2\n", | |
"from math import pi\n", | |
"\n", | |
"pi_py2 = pi\n", | |
"print(pi_py2)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 35, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"3.141592653589793\n" | |
] | |
} | |
], | |
"source": [ | |
"%%python3\n", | |
"from math import pi\n", | |
"\n", | |
"pi_py3 = pi\n", | |
"print(pi_py3)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Rational Number Shenanigans\n", | |
"-------" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 36, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"False" | |
] | |
}, | |
"execution_count": 36, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# Should be the same...\n", | |
".1 + .2 == .3 # 😡" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Other languages (e.g., Perl 6) internally represent some numbers as rational numbers, each with numerators and a denominators. \n", | |
"\n", | |
"In Python it would be like..." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 37, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from fractions import Fraction" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 38, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"True" | |
] | |
}, | |
"execution_count": 38, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# Change the representation and they are equivalent\n", | |
"Fraction(1, 10) + Fraction(2, 10) == Fraction(3, 10) # 🙂" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Specfic Tools > General Tools\n", | |
"------\n", | |
"\n", | |
"When given a choice in Python, use specialized tool.\n", | |
"\n", | |
"from this [Raymond tweet](https://twitter.com/raymondh/status/974018651308179456)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 39, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# General log\n", | |
"from math import log" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 40, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"False" | |
] | |
}, | |
"execution_count": 40, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# Should be all be the same\n", | |
"all(log(2**p, 2) == p for p in range(1024)) # 😡" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 41, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Special log base 2\n", | |
"from math import log2" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 42, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"True" | |
] | |
}, | |
"execution_count": 42, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# Now they are all the same\n", | |
"all(log2(2**p) == p for p in range(1024)) # 🙂" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Summary\n", | |
"------\n", | |
"\n", | |
"Python does __not__ always perform the way we expect. \n", | |
"\n", | |
"It is worth knowing about and collecting MathOps (Mathematical Operations) edge cases." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<br>\n", | |
"<br> \n", | |
"<br>\n", | |
"\n", | |
"----" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"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.6.5" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment