# Build better hardware. Write clean, versioned and tested code Joaquin Matres <jmatres@jmatres.com> --- ![](https://i.imgur.com/jYkEHuL.jpg) --- # Outline 1. Git :two_women_holding_hands: 2. Clean code :sparkles: 3. Packaging :package: --- ![code_v2](https://i.imgur.com/1hkk3SU.png) --- ![git flow](https://i.imgur.com/ETQf5Vx.png) --- # Git for collaborative writing - Keep track of history - Develop new features safely - Swap between versions --- # Terminology - Git takes snapshots of all the files in a folder. This folder is called a repository or repo. - Create a commit to take a snapshot of a file or files. - Add information about your changes in a commit message. --- # Git commands - `git init`: new project :small_blue_diamond: - `git clone`: to your computer :arrow_down::cloud: - `git add fileName`: track file :white_check_mark: - `git commit`: commits your changes :camera: - `git push`: changes to remote server :arrow_up::cloud: - `git pull`: changes to your computer :arrow_down::cloud: - `git status`: check status :question: - `git log`: read log :book: --- # plain text :smiley_cat: - python (.py) - markdown (.md) - restructured Text (.rst) # binary :scream_cat: :elephant: :horse: - power point --- # Git Remote services - Github (free for public repos) - Gitlab (free for public repos), you can also self-host it - Bitbucket Atlassian (private repos up to 5 collaborators) --- # Learn Git - type `git help` in a terminal - [Atlassian](https://www.atlassian.com/git/tutorials/setting-up-a-repository) - [github](https://try.github.io/levels/1/challenges/1) - [Software carpentry](http://swcarpentry.github.io/git-novice/01-basics/) - [Git notebooks](https://github.com/computerproductivity/git_notebooks) --- ![git branches](https://i.imgur.com/Aiof0cH.png) --- ![thesis](https://i.imgur.com/K6Z27TC.jpg) [1] --- # Docstrings ![docstrings](https://i.imgur.com/dLto5vs.png) --- # Google style ``` python def func(arg1, arg2): """ Summary Args: arg1 (int): Description of arg1 arg2 (str): Description of arg2 Returns: bool: Description of return value """ return True ``` --- # Numpy style ``` python def func(arg1, arg2): """Summary line. Parameters ---------- arg1 : int Description of arg1 arg2 : str Description of arg2 Returns ------- bool Description of return value """ return True ``` --- # Code readability Code is read many more times than written! In many cases, that person is probably going to be you, six months from now. - [pep8](https://pep8.org/) - black: autoformatter - pylint/pyflakes: syntax checker --- ``` python def GetArea(l, w): return l*w l=3 w=4 A=GetArea(l,w) ``` --- ``` python def area_rectangle(length, width): return length*width length = 3 width = 4 area = area_rectangle(length, width) ``` --- # Style guides - [PEP8](https://www.python.org/dev/peps/pep-0008/) - [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html) Formatting tools: - [black]() - [pep8, flake8](http://flake8.pycqa.org/en/latest/index.html) - [pylint](https://www.pylint.org/) --- # Classes ``` python class SampleClass(object): """Summary of class here. Longer class information.... Attributes: likes_spam: boolean indicates if we like SPAM or not. eggs: An integer count of the eggs we have laid. """ def __init__(self, likes_spam=False): """Inits SampleClass with blah.""" self.likes_spam = likes_spam self.eggs = 0 def public_method(self): """Performs operation blah.""" ``` --- ``` python def rmse(x, y): return np.sqrt(((x-y)**2).mean()) ``` --- ``` python def root_mean_square_error(observed, modelled): error = observed - modelled return np.sqrt((error**2).mean()) ``` --- ``` python def root_mean_square_error(measured, simulated): """ Root Mean Square Error (RMSE) Args: measured: numpy array of measured data simulated: numpy array of simulated data Returns: mean square error numpy array """ error = observed - modelled return np.sqrt((error**2).mean()) ``` --- # PEP8 Indentation - Four spaces (no tab!) - Most editors can be set to convert a tab that you type to four spaces in the file --- # PEP8 Maximum line length - PEP8 recommends 79 characters - We use 88 characters (default for [black autoformatter](https://github.com/ambv/black)) --- # PEP8 Line spacing - Two blank lines around top level functions - Two blank lines around classes - One blank line between functions in a class - One blank line between logical groups in a function (sparingly) --- # No ``` python a_var = 1 def one_function(): return something def other_function(): return something_else result = one_function() ``` --- # Yes ``` python a_var = 1 def one_function(): return something def other_function(): return something_else result = one_function() ``` --- # PEP8 Imports are typically grouped: - standard library imports - related third party imports - local application/library specific imports ``` python import os import sys import numpy as np import pandas as pd import my_module ``` --- | type | Name convention | | -------------------------- | ---------------- | | Packages/Modules/Functions | lower_with_under | | Classes/Exceptions | CapWords | | Global/Class Constants | CAPS_WITH_UNDER | | Global/Class Variables | lower_with_under | | Instance/Local Variables | lower_with_under | | Function/Method Parameters | lower_with_under | --- ``` python from statistics import mean, stdev import numpy as np def MyFunction(ARGUMENT): m=mean(ARGUMENT) s=stdev(ARGUMENT) gt3sd = 0 ls3sd = 0 for m in ARGUMENT: if m > m + (s * 2): gt3sd +=1 elif m < m - (s * 2): ls3sd +=1 return(gt3sd,ls3sd) def AnotherFunction(anumber, anothernumber): l = np.random.randint(anothernumber, size = anumber) return(MyFunction(l)) a,b=AnotherFunction( anumber = 1000, anothernumber = 1000) print('found %d random values greather than 2 * sd and %d less than 2 * sd' % (a, b)) ``` --- ``` python from statistics import mean, stdev import numpy as np def MyFunction(ARGUMENT): m = mean(ARGUMENT) s = stdev(ARGUMENT) gt3sd = 0 ls3sd = 0 for m in ARGUMENT: if m > m + (s * 2): gt3sd += 1 elif m < m - (s * 2): ls3sd += 1 return gt3sd, ls3sd def AnotherFunction(anumber, anothernumber): l = np.random.randint(anothernumber, size=anumber) return MyFunction(l) a, b = AnotherFunction(anumber=1000, anothernumber=1000) print('found %d random values greather than 2STD and %d less than 2STD' % (a, b)) ``` --- ``` python from statistics import mean, stdev import numpy as np def my_function(value): m = mean(value) s = stdev(value) gt3sd = 0 ls3sd = 0 for m in value: if m > m + (s * 2): gt3sd += 1 elif m < m - (s * 2): ls3sd += 1 return gt3sd, ls3sd def another_function(highest, size): l = np.random.randint(highest, size=size) return my_function(l) a, b = AnotherFunction(highest=1000, size=1000) print('found %d random values greather than 2STD and %d less than 2STD' % (a, b)) ``` --- ![packaging leader](https://i.imgur.com/gEomJ8U.png) [1] --- # 3. Python packaging :package: - Setuptools modularizes your projects - Pytest tests your code - Sphinx bulds your documentation --- # Python package - directory with the package's name - `__init__.py` file inside the directory - the actual code --- # How to use this package? - Hack sys.path ``` import sys sys.path.append("/home/user/my_modules") ``` - Make a distributable/installable package - add `setup.py` - `pip install -e .` --- # Pytest ```python def func(x): return x + 1 def test_answer(): assert func(4) == 5 ``` --- ```rst reStructuredText ----------------------------------- Write in **bold**, *italic* or `code` * use * lists Code blocks:: a = 1 .. plot:: :include-source: import matplolib as plt plt.plot([0, 1, 2]) .. image:: images/my_image.png `link websites <http://klayout.de/>`_ ``` --- ```rst Sphinx ----------------------------------- .. autofunction:: my_function .. autoclass:: MyClass .. automodule:: my_module :members: ``` --- # `#` markdown title ## `##`subtitle ![](https://i.imgur.com/UhlgTSz.png) ``` bash ```python def function(var1, var2): return var1 + var2 ``` ``` --- # markdown tables ```bash order | topic ------ | ---- 1 | git 2 | clean code 3 | packaging ``` order | topic ------ | ---- 1 | git 2 | clean code 3 | packaging --- # References 1. [The Art of Readable Code: by Dustin Boswell and Trevor Foucher](http://shop.oreilly.com/product/9780596802301.do) 2. [Software engineering best practices for scientists: Paris Saclay](https://github.com/lightwave-lab/python-workshop.git) 3. [git pro book](https://git-scm.com/book/en/v2) 4. [interesting jupyter notebooks](https://github.com/jupyter/jupyter/wiki/A-gallery-of-interesting-Jupyter-Notebooks) 5. [git cheatsheet](http://cheat.errtheblog.com/s/git) 6. [python notebooks](https://github.com/computerproductivity/python) --- # Bonus tips - Choose editor wisely - vim - sublime - atom - IDEs can be helpful - Spyder - PyCharm - VisualCode - Linux philosophy: - provide small programs that do `one` thing well and - provide mechanisms for joining programs together - ` ls | grep Python` --- # Thank you --- # Summary 1. Git :two_women_holding_hands: 2. Clean code :sparkles: 3. Packaging :package:
{"metaMigratedAt":"2023-06-14T20:20:34.102Z","metaMigratedFrom":"YAML","title":"Build better hardware. Write clean, versioned and tested code","breaks":true,"slideOptions":"{\"theme\":\"white\"}","contributors":"[{\"id\":\"502c9c70-abff-40e6-8f85-3bd77aafd255\",\"add\":15509,\"del\":5557}]"}
    339 views