type hints
play

Type hints CREATIN G ROBUS T P YTH ON W ORK F LOW S Martin - PowerPoint PPT Presentation

Type hints CREATIN G ROBUS T P YTH ON W ORK F LOW S Martin Skarzynski Co-Chair, Foundation for Advanced Education in the Sciences (FAES) Dynamic typing Python def double(n): Infers types when running code return n * 2 Dynamic (duck)


  1. Type hints CREATIN G ROBUS T P YTH ON W ORK F LOW S Martin Skarzynski Co-Chair, Foundation for Advanced Education in the Sciences (FAES)

  2. Dynamic typing Python def double(n): Infers types when running code return n * 2 Dynamic (duck) typing double(2) double('2') 4 '22' CREATING ROBUST PYTHON WORKFLOWS

  3. Type hints for arguments def double(n: int): def double(n: str): return n * 2 return n * 2 double(2) double('2') 4 '22' CREATING ROBUST PYTHON WORKFLOWS

  4. Type hints for return values def double(n: int) -> int: def double(n: str) -> str: return n * 2 return n * 2 double(2) double('2') 4 '22' CREATING ROBUST PYTHON WORKFLOWS

  5. Get type hint information from double import double # The help() function help(double) Help on function double in module double: double(n:int) -> int CREATING ROBUST PYTHON WORKFLOWS

  6. Type checker setup Type checking tool setup: mypy type checker pytest testing framework pytest-mypy pytest plugin $ pip install pytest mypy pytest-mypy CREATING ROBUST PYTHON WORKFLOWS

  7. Type checker setup pytest.ini �le with the following: [pytest] addopts = --doctest-modules --mypy --mypy-ignore-missing-imports CREATING ROBUST PYTHON WORKFLOWS

  8. Mypy to the rescue! $ pytest double.py ========================= test session starts ============================== ... =============================== FAILURES =================================== ____________________________ mypy double.py ________________________________ double.py:4: error: Arg. 1 to "double" has incompatible type "str"; expected "int" ======================= 1 failed in 0.36 seconds =========================== CREATING ROBUST PYTHON WORKFLOWS

  9. List from typing import List def cook_foods(raw_foods: List[str]) -> List[str]: return [food.replace('raw', 'cooked') for food in raw_foods] cook_foods(['raw asparagus', 'raw beans', 'raw corn']) cook_foods('raw corn') ['cooked asparagus', 'cooked beans', 'cooked corn'] ['r', 'a', 'w', ' ', 'c', 'o', 'r', 'n'] CREATING ROBUST PYTHON WORKFLOWS

  10. Pytest cook $ pytest cook.py ========================= test session starts ============================== ... =============================== FAILURES =================================== ____________________________ mypy cook.py __________________________________ cook.py:7: error: Arg. 1 to "cook_foods" has ... type "str"; expect. "List[str]" ======================= 1 failed in 0.25 seconds =========================== CREATING ROBUST PYTHON WORKFLOWS

  11. Optional from typing import Optional def str_or_none(optional_string: Optional[str] = None) -> Optional[str]: return optional_string CREATING ROBUST PYTHON WORKFLOWS

  12. Let's practice type annotating our code! CREATIN G ROBUS T P YTH ON W ORK F LOW S

  13. Docstrings CREATIN G ROBUS T P YTH ON W ORK F LOW S Martin Skarzynski Co-Chair, Foundation for Advanced Education in the Sciences (FAES)

  14. Docstrings Triple quoted strings Include documentation in objects def double(n: float) -> float: """Multiply a number by 2.""" return n * 2 CREATING ROBUST PYTHON WORKFLOWS

  15. Access docstrings help(double) Help on function double in module __main__: double(n: float) -> float Multiply a number by 2. CREATING ROBUST PYTHON WORKFLOWS

  16. Google docstring style """Google style. The Google style tends to result in wider docstrings with fewer lines of code. Section 1: Item 1: Item descriptions don't need line breaks. """ CREATING ROBUST PYTHON WORKFLOWS

  17. Numpy docstring style """Numpy style. The Numpy style tends to results in narrower docstrings with more lines of code. Section 1 --------- Item 1 Item descriptions are indented on a new line. """ CREATING ROBUST PYTHON WORKFLOWS

  18. Docstring types Location determines the type: """MODULE DOCSTRING""" In de�nitions of def double(n: float) -> float: Functions """Multiply a number by 2.""" Classes return n * 2 Methods class DoubleN: """CLASS DOCSTRING""" At the top of .py �les def __init__(self, n: float): Modules """METHOD DOCSTRING""" Scripts self.n_doubled = n * 2 __init__.py CREATING ROBUST PYTHON WORKFLOWS

  19. Package docstrings help() output highlights: import pandas help(pandas) NAME DESCRIPTION (package docstring) Help on package pandas: FILE (path to __init__.py ) NAME pandas DESCRIPTION pandas - a powerful data analysis and manipulation library for Python CREATING ROBUST PYTHON WORKFLOWS

  20. Module docstrings import double class DoubleN(builtins.object) help(double) | DoubleN(n: float) | | CLASS DOCSTRING Help on module double: | | Methods defined here: NAME | double - MODULE DOCSTRING | __init__(self, n: float) | METHOD DOCSTRING CLASSES builtins.object DoubleN CREATING ROBUST PYTHON WORKFLOWS

  21. Class docstrings class DoubleN: """The summary of what the class does. Arguments: n: A float that will be doubled. Attributes: n_doubled: A float that is the result of doubling n. """ def __init__(self, n: float) -> None: self.n_doubled = n * 2 CREATING ROBUST PYTHON WORKFLOWS

  22. Docstring examples Mistake in the docstring example: def double(n: float) -> float: """"Multiply a number by 2. 2 * 2 Arguments: n: The number to be doubled. Returns: 4 The value of n times 2. Examples: 2. * 2 >>> double(2) 4.0 4.0 """ return n * 2 CREATING ROBUST PYTHON WORKFLOWS

  23. Test docstring examples ============== FAILURES =============== $ pytest double.py _______ [doctest] double.double _______ Docstring examples combine 005 Returns: Documentation 006 The value of n times 2. 007 Examples: T ests (via doctest ) 008 >>> double(2) Expected: 4.0 Got: 4 MODULE/square.py:8: DocTestFailure === 1 failed, 1 passed in 0.26 sec. === CREATING ROBUST PYTHON WORKFLOWS

  24. Module docstring examples """Module docstring $ pytest double.py Examples: >>> dn = DoubleN(2) ======== test session starts ========== >>> dn.n_doubled == double(2) ... True """ double.py .. [100%] def double(n: float) -> float: ====== 2 passed in 0.36 seconds ======= return n * 2 class DoubleN: def __init__(self, n: float): self.n_doubled = n * 2 CREATING ROBUST PYTHON WORKFLOWS

  25. Let's practice writing docstrings! CREATIN G ROBUS T P YTH ON W ORK F LOW S

  26. Reports CREATIN G ROBUS T P YTH ON W ORK F LOW S Martin Skarzynski Co-Chair, Foundation for Advanced Education in the Sciences (FAES)

  27. Jupyter notebooks Consist of cells T ext (Markdown format) Code (Python, R, etc.) Have an .ipynb extension Built on IPython Have a structure based on JSON JavaScript Object Notation Similar to a Python dictionary 1 Pérez, F., & Granger, B. E. (2007). IPython: a system for interactive scienti�c computing. CiSE, 9(3). CREATING ROBUST PYTHON WORKFLOWS

  28. Track notebooks changes old.ipynb Empty code cell CREATING ROBUST PYTHON WORKFLOWS

  29. Track notebooks changes new.ipynb Empty code cell Markdown cell that says Hi! CREATING ROBUST PYTHON WORKFLOWS

  30. Diff View changes made to notebooks "source": [] With the diff shell command + }, + { $ diff -c old.ipynb new.ipynb + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Hi!" + ] } CREATING ROBUST PYTHON WORKFLOWS

  31. Nbdiff View changes made to notebooks --- old.ipynb 2020-02-07 20:46:26.4981 With the diff shell command +++ new.ipynb 2020-02-07 20:41:18.5494 ## inserted before /cells/1: $ diff -c old.ipynb new.ipynb + markdown cell: + source: With the nbdime nbdiff command + Hi! $ nbdiff old.ipynb new.ipynb https://nbdime.readthedocs.io CREATING ROBUST PYTHON WORKFLOWS

  32. Notebook work�ow package 1. Use nbformat to create notebooks from: Markdown �les ( .md ) Code �les ( .py ) CREATING ROBUST PYTHON WORKFLOWS

  33. Convert notebooks 1. Use nbformat to create notebooks from: Markdown �les ( .md ) Code �les ( .py ) 2. Use nbconvert to convert notebooks CREATING ROBUST PYTHON WORKFLOWS

  34. Code cells Use nbformat 's v4 module to create: from nbformat.v4 import (new_notebook, Notebook objects new_code_cell) new_notebook() nb = new_notebook() Code cell objects nb.cells.append(new_code_cell('1+1')) new_code_cell() nb.cells Code cell keys execution_count [{'cell_type': 'code', 'metadata': {}, source 'execution_count': None, 'source': '1+1', 'outputs': []}] outputs CREATING ROBUST PYTHON WORKFLOWS

  35. Unexecuted code cells Square brackets ( [ ]: ) on the left Correspond to execution_count key-value pair CREATING ROBUST PYTHON WORKFLOWS

  36. Executed code cells Running notebook code cells Increments the Number in [ ]: (rendered) execution_count value Produces output (e.g. a plot) Below the code cell In the outputs list CREATING ROBUST PYTHON WORKFLOWS

Recommend


More recommend