Skip to content

Instantly share code, notes, and snippets.

@tmarthal
Created February 23, 2017 02:43
Show Gist options
  • Save tmarthal/1f1eadda7124dc1a285f6cf17616da83 to your computer and use it in GitHub Desktop.
Save tmarthal/1f1eadda7124dc1a285f6cf17616da83 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### About Me\n",
"Polygot programmer, writing multiple languages per day. Currently writing lots of python(notebooks|pyspark|airflow), SQL and our main web-app is Rails/Ruby (so some js/html too).\n",
"\n",
"Really a Fortran ➡️️ Java programmer in disguise. Picked up python to do GIS processing in the late-2000's with 'geodjango' and PostGIS. Been using it to do all of my analysis since then, and have recently been able to sell companies with the idea to use python as the main back-end language.\n",
"\n",
"*Footnote: Idea based on a pyladies seattle talk 'The Joy of Type Hints' given by Joel Grus [https://www.meetup.com/Seattle-PyLadies/events/236706688/]*"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Typing\n",
"\n",
"\n",
"- Previous (2015-16) project used Groovy, a dynamic/untyped language on top of the JVM \n",
" - Lead to a ton of `NotImplementedException` problems when the programs were run\n",
" - it sucked, had to unit test method definitions/signatures to make sure that the program would run properly.\n",
" \n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Python Typing\n",
"\n",
"(**Bad Summary**††) Object instantiation has a 'type' but variables of a type can be re-assigned to another type, i.e. python is a `strongly` typed `dynamic` language.\n",
"\n",
" \n",
"\n",
"††: Programmers can't agree on anything, let alone what typing means. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## PEP-484\n",
"'Type Hints' https://www.python.org/dev/peps/pep-0484/\n",
"\n",
"**This PEP aims to provide a standard syntax for type annotations, opening up Python code to easier static analysis and refactoring, potential runtime type checking, and (perhaps, in some contexts) code generation utilizing type information.**"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Python Type Hinting\n",
"\n",
"Python is automatically compiled (`*.pyc` files), so there is never a 'compilation' step.\n",
"\n",
"Instead use a manual step to check types - `mypy`! \n",
"\n",
"Type hinting is a built-in python3.5 language feature, in the `typing` package (https://docs.python.org/3/library/typing.html). Otherwise, in python2 `mypy` checks comment strings with similar syntax."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# python 2 type hints\n",
"def plus2(num1, num2):\n",
" # type: (int, int) -> int\n",
" return num1 + num2\n",
"plus2(2, 3.0) # converts to float"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# python3 hits, typing next to the arguments\n",
"def plus3(num1: int, num2: int) -> int:\n",
" return num1 + num2\n",
"plus3('2', '3') # will gladly add the strings together"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Type hints _do nothing_, they are hints, and the type checking needs to be done as an outside step, like unit testing or code linting. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# pip install mypy\n",
"!mypy -h"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"Note: Could not figure out how to run `mypy` from this notebook (nor is it even a good idea)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"!cat -n plus2.py"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"!mypy plus2.py"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import typing"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# Most built in types\n",
"[s for s in dir(typing) if not s.startswith('_')]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from typing import Iterable, List\n",
"def f(int_iterable: Iterable[int]) -> List[str]:\n",
" return [str(x) for x in int_iterable]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"f(range(1, 3))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Classes"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# String class type to avoid sym linking issues, e.g. NameError: name 'MyClass' is not defined\n",
"class MyClass(object):\n",
" \n",
" def my_method(self: MyClass, num: int, str1: str) -> str:\n",
" \"\"\" Normal docstring. Repeats `str1` `num` times\"\"\"\n",
" return num * str1\n",
"\n",
" # The __init__ method doesn't return anything, so it gets return\n",
" # type None just like any other method that doesn't return anything.\n",
" def __init__(self: 'MyClass') -> None:\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"x = MyClass()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"x.my_method(4, 'x')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Other (python2) examples and resources at the mypy 'cheat sheet': https://github.com/python/mypy/blob/master/docs/source/cheat_sheet.rst"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"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.0"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment