{"data":{"mdx":{"code":{"body":"function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nreturn class MDXContent extends React.Component {\n  constructor(props) {\n    super(props);\n    this.layout = null;\n  }\n\n  render() {\n    const _this$props = this.props,\n          {\n      components\n    } = _this$props,\n          props = _objectWithoutProperties(_this$props, [\"components\"]);\n\n    return React.createElement(MDXTag, {\n      name: \"wrapper\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"h1\",\n      components: components\n    }, `🐍 Python`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `I have been writing Python code professionally at `, React.createElement(Link, {\n      to: \"/xp/2014-uniregistry\"\n    }, `Uniregistry`), ` for over five years now. It has also been my primary language for projects and algorithm challenges since early in University (2008).`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `At Uniregistry, we use a custom web framework based on `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Pyramid`), ` and `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `SQLAlchemy`), `. It doesn't come with `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Django`), `'s vast package/app ecosystem, but SQLAlchemy is a very powerful ORM, and I enjoy the query syntax & fine-grained control we have over relationship loading.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `I've also recently created a small `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Django REST Framework`), ` service using `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Python`), ` 3.7 and am loving the improvements. (Type annotations are excellent inline documentation, and I was happy to discover that dictionaries and sets now maintain the order of insertion.)`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `I first started using `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Python`), ` in my `, React.createElement(Link, {\n      to: \"/xp/2007-uct\"\n    }, `second year`), ` of university when I taught myself `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Python`), ` & `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Django`), ` for a team project. I chose `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Django`), ` for the excellent documentation, and it taught me a lot about building complete server-side web stacks. `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Django`), `'s source code is also an excellent introduction to Web Application Security / `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"p\",\n      props: {\n        \"href\": \"https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project\"\n      }\n    }, `OWASP Top Ten`), `.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `I also used `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Django`), ` in 2010 when I worked for a startup. I replaced much PHP with simpler `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Python`), ` code and used `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Django`), ` to spin up a pretty admin interface with more custom functionality than phpMyAdmin.`), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `Podcasts`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `I pick up a lot of new tools/ideas from the following podcasts.`), React.createElement(MDXTag, {\n      name: \"ul\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"li\",\n      props: {\n        \"href\": \"https://pythonbytes.fm/\"\n      }\n    }, `Python Bytes`)), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"li\",\n      props: {\n        \"href\": \"https://talkpython.fm/\"\n      }\n    }, `Talk Python To Me`)), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"li\",\n      props: {\n        \"href\": \"https://changelog.com/podcasts\"\n      }\n    }, `The Changelog`), ` `, `—`, ` not Python-specific`)), React.createElement(MDXTag, {\n      name: \"h2\",\n      components: components\n    }, `Tools & libraries`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `The following are my favourite tools I've been collecting over the last couple of years. These bullet points might turn into blog posts someday.`), React.createElement(MDXTag, {\n      name: \"ul\",\n      components: components\n    }, React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `IPython`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `I've been using `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `IPython`), ` for a while to test things in a REPL quickly. It's excellent at autocompleting everything on the `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `PYTHONPATH`), ` and a fantastic way to explore docs.`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `I've also customised our `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Pyramid`), ` shell to provide shortcuts to our `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"p\",\n      props: {\n        \"href\": \"https://en.wikipedia.org/wiki/Data_access_object\"\n      }\n    }, `DAOs`), ` and all commonly used backend tasks/manager objects, making it an incredibly powerful production OPS shell. (Careful here: \"with great power, etc.\" 😉)`)), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `sentry`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `We host a private instance of `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"p\",\n      props: {\n        \"href\": \"https://sentry.io\"\n      }\n    }, `https://sentry.io`), `'s error monitoring system, and I've written the code to annotate exceptions/errors with user information and additional information about the originating web route/backend task. It saves us all hours of debugging work every week.`)), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Jupyter`), ` notebooks`), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `I've used `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Jupyter`), ` notebooks when they were still `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `IPython`), ` notebooks to document some parts of our code base for myself at work. Recently I've used them even more heavily when I took the `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"p\",\n      props: {\n        \"href\": \"/xp/2018-deeplearning\"\n      }\n    }, `deeplearning.ai`), ` course. I'm still learning the ins and outs of `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `pandas`), ` and `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Matplotlib`), `, but I'm a big fan of their notebook integration.`)), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `devpi-server`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `If you install many packages or need to experiment with many different virtualenvs running `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `devpi-server`), ` on `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `localhost`), ` saves incredible amounts of time and data. (Looking at you `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `pipenv lock`), ` 😒)`)), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `pytest`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `Our test suite currently contains ~8000 unit/integration tests, which massively increases our confidence in each deployment. Tips:`), React.createElement(MDXTag, {\n      name: \"ul\",\n      components: components,\n      parentName: \"li\"\n    }, React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"li\"\n    }, `pytest --durations`), ` discovers the slowest tests. Sometimes you can massively speed up everyone's test runs by fixing a couple of outliers.`), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"li\"\n    }, `pytest-testmon`), ` is incredible if you can get it to work reliably. It reverses test coverage to find all tests that could be influenced by changed code and runs only the relevant subset of the suite.`), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, `You need a zero-tolerance policy for `, React.createElement(MDXTag, {\n      name: \"a\",\n      components: components,\n      parentName: \"li\",\n      props: {\n        \"href\": \"https://samsaffron.com/archive/2019/05/15/tests-that-sometimes-fail\"\n      }\n    }, `flakey tests`), `.`))), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `pipsi`), ` or `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `pipx`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, `Python finally has an `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `npx`), ` equivalent to simplify installing Python tools in separate virtualenvs (to avoid conflicting dependencies).`)), React.createElement(MDXTag, {\n      name: \"li\",\n      components: components,\n      parentName: \"ul\"\n    }, React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `asdf`)), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components,\n      parentName: \"li\"\n    }, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `asdf`), ` acts as a universal \"tool version manager\", much like `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `pyenv`), `/`, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `nvm`), `/countless others. I first used it to switch `, React.createElement(MDXTag, {\n      name: \"inlineCode\",\n      components: components,\n      parentName: \"p\"\n    }, `Elixir`), ` versions; now it's also my primary tool to manage Python versions.`))), React.createElement(MDXTag, {\n      name: \"p\",\n      components: components\n    }, `I'd love to learn about more Tips & Tricks in Python-land. If you feel like I'm missing something super obvious or just want to chat Python, please feel free to contact me.`));\n  }\n\n}"},"frontmatter":{"type":null,"dates":null,"org":null,"detail":null,"tech":null,"role":null}}},"pageContext":{"id":"92b62b20-4486-5d7c-b587-b96df2b9f110","slug":"/tech/python"}}