[![Read my blog](https://img.shields.io/badge/-Blog%20etc-888888?style=flat&labelColor=eeeeee&logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAADgAAAA4CAMAAACfWMssAAABpFBMVEX%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8AAAD%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F8AAAAAAACwsLABAQEBAQEBAQGlpaUCAgICAgIXFxdycnKAgIBVVVSZmZgDAwMQEBANDQ0JCQgCAgIAAAAWFhYAAAAYGBgXFxcVFRUEBAQ5OTkZGRlTU1NqampmZmaAgHxfX198fHyKioqQkJCurqoMDAwFBQQAAAAgIB0QEBARERAjIyMaGhoXFxcVFRUAAAAVFRUXFxcVFRUBAQEnJyc9PT0uLi4tLS0lJSUzMzMtLS1ISEhFRUVERERhYV5XV1cPDw9GRkZWVlY%2FPz5aWlpjY19hYWFaWlojIyNjY2NLS0srKytnZ2c2NjZzc3IKCgqFhYUrKyuNjYDa2toFBQUaGhoXFxcKCgoUFBQcHBwKCgoKCgoAAAAICAEWFhYnJyMAAAAKCgoMDAwAAAAAAAAjIyM2NjYAAAARERExMSkKCgpRUU4bGxtHR0cAAAA%2BPj4oKCdOTkhZWVkFBQVPT086OjpNTUk5OTkBAQFLS0teXlZKSkpQUFBvb241NTUAAABvb294eHgAAACBIqjAAAAAi3RSTlMBBgMHCAACBQT9%2Bw%2F18eoT7efLNCQeF%2Fny8u%2Fk29nW08%2B3eHZYOi8rKCMgGxkH%2BvXz7Ofk4t%2Fc1cfFwLy2spiUjoqFd2VjXVlTUVBMR0ZCPz8%2BOzs3NjEtLB0aCwr%2B9Orq6OXi09LMxr%2B%2Fu7qro5qSj46HhIOAf317dXBtamlhVVBHRDYxKSckHhcWCkdRuAAAArhJREFUSMeV1mdX2zAUBuDrCNlJWIEQ9ipQNi0tpYWyZwuljEILBbr33nvv8f7pxkoT2fg6TvRFOdf3OTrOa9kiYVphU0hBycmQBWSEQgapyaICKcywRcKe7KbdticzCZFqIocT5HSGxxXuA1DVUkCWfdXhpL%2BzUk6NZ8pRXq6pYqEaeKGacnYjSdcjxUYtMJPspRxd6XGgOenIWi8GWskgH0deV96b6l3tR2Q%2BRBlnOZ003G446SrTmX0tQskO6b%2FV4cjtKm8BGNxWzr76BljKyZWrGBq20%2Ff0GWijAEcZB1z%2Fk3LfY4hsZuJwupDT9TYjPW6W2u5HGTBNlHYy2AFDpWR01QGTZBCzXsjheprgHHcKE%2FXAo2QTcU7Hf%2F4Y3ONuIzCudgcTP%2Bv0GDdVUzbX3cC4iVQT5esm073%2BruIo46bSvZSfe5rpJV83yLjnupfUtvA%2Bbp1HGPdSuzC5nczmXjuz5h%2FvjgEvi7S67olYdzi7U1PIuy3aGXfhrdtJYtwVZr13e5wgz3aKX2LcB09mnm0RP8S4WW%2FWtKf0jXHROS5rt9tfy7h5LmsKdAdOsFmTy9X4OCYzcrhVxlWd5J0gXVqp5h3%2F6tTrLV%2F0uqJT3BdeuOJYOsg7%2FhWo41jn3GnfV5mOY8zriv2djiMR9bplf6fjeIXivW7F3%2Bk4%2BgaqOxtdLnYmi9NxLOKh7K53uJKsTscxii1hdl3T7mzgyUCVfkeH7N%2B%2FrmoX%2BIVXcUxjTpW2LitXFg92Ko7duthOqnQuZrv27E7HsYDH%2F0uJMaBuUzvu8dZxyFF8TK33IIr694XsAVY7HcfPCIrWhFwcAYY%2FJUtZ19NxSGMKQE1LI6L3N4TM%2BcBMRl8J7NE%2F0UXaBcUfNslsUwm0%2FLXMQOeO4zZwY7ZPlfJwkjoi974IM28naC3uKOXh%2FgEMt7c2Kju6aAAAAABJRU5ErkJggg%3D%3D&logoColor=white "Read my blog")](https://nedbatchelder.com) [![Follow @nedbat on Mastodon](https://img.shields.io/badge/%40nedbat-3.9k-96a3b0?style=flat&labelColor=450657&logo=mastodon&logoColor=white "Follow @nedbat on Mastodon")](https://hachyderm.io/@nedbat) [![Follow nedbat.com on Bluesky](https://img.shields.io/badge/Bluesky-4.3k-96a3b0?style=flat&labelColor=3686f7&logo=icloud&logoColor=white "Follow nedbat.com on Bluesky")](https://bsky.app/profile/nedbat.com) [![Join us at Boston Python](https://img.shields.io/badge/-Boston%20Python-4d7954?style=flat&labelColor=eeeeee&logo=meetup&logoColor=red "Join us at Boston Python")](https://about.bostonpython.com) [![Python Discord](https://img.shields.io/badge/-Discord-ffe97c?style=flat&labelColor=7289da&logo=discord&logoColor=white "Python Discord")](https://discord.gg/python) [![Sponsor me on GitHub](https://img.shields.io/badge/%E2%9D%A4-Sponsor%20me-brightgreen?style=flat&logo=GitHub "Sponsor me on GitHub")](https://github.com/sponsors/nedbat) [![Stack Overflow reputation](https://img.shields.io/badge/-378k%20%F0%9F%9F%A1%E2%80%8977%20%E2%9A%AA%E2%80%89583%20%F0%9F%9F%A4%E2%80%89675-e6873e?style=flat&labelColor=333333&logo=stackoverflow "Stack Overflow reputation")](https://stackoverflow.com/users/14343/ned-batchelder) [![My PyPI packages](https://img.shields.io/badge/-PyPI-4B8BBE?style=flat&labelColor=306998&logo=python&logoColor=FFE873 "My PyPI packages")](https://pypi.org/user/nedbatchelder) [](https://nokings.org)      [](https://nedbatchelder.com/blog/202411/my_politics.html)      [](https://stand-with-ukraine.pp.ua/#support-ukraine)      [](https://nedbatchelder.com/blog/201207/my_mom_got_married.html)      [](https://nedbatchelder.com/blog/202006/black_lives_matter.html) I'm **Ned Batchelder**, a Python software developer and community organizer. - My personal site is [nedbatchelder.com][nedbat]. - I'm an organizer of [Boston Python][bp]. - I'm a member of the [Python Docs Editorial Board][pdeb]. You can **find me** at: - Mastodon: [@nedbat@nedbat.com][mastodon]. - Bluesky: [nedbat.com](https://bsky.app/profile/nedbat.com). - Libera IRC: nedbat in [#python][libera]. - Discord: nedbat in the [Python Discord][discord]. My latest **[blog][blog]** posts: - **[No more .html](https://nedbatchelder.com/blog/202601/no_more_html)**, 2 Jan
My site used to have URLs ending with .html. Not anymore. *([read..](https://nedbatchelder.com/blog/202601/no_more_html))* - **[Generating data shapes with Hypothesis](https://nedbatchelder.com/blog/202512/generating_data_shapes_with_hypothesis)**, 21 Dec
I used Hypothesis to generate random data structure schemas, and then generate random data using them. I learned a lot along the way. *([read..](https://nedbatchelder.com/blog/202512/generating_data_shapes_with_hypothesis))* - **[A testing conundrum](https://nedbatchelder.com/blog/202512/a_testing_conundrum)**, 18 Dec
A useful class that is hard to test thoroughly, and my failed attempt to use Hypothesis to do it. *([read..](https://nedbatchelder.com/blog/202512/a_testing_conundrum))* - **[Autism Adulthood, 3rd edition](https://nedbatchelder.com/blog/202511/autism_adulthood_3rd_edition)**, 18 Nov
My wife’s book is out today, you should buy it. *([read..](https://nedbatchelder.com/blog/202511/autism_adulthood_3rd_edition))* - and [many more][blog].. I maintain a few [**Python packages**][ned_pypi], including: - [**Coverage.py**](https://github.com/nedbat/coveragepy): The code coverage tool for Python
[![PyPI](https://img.shields.io/pypi/v/coverage?style=flat?style=flat "The coverage PyPI page")](https://pypi.org/project/coverage) [![GitHub last commit](https://img.shields.io/github/last-commit/nedbat/coveragepy?logo=github&style=flat?style=flat "Recent coverage.py commits")](https://github.com/nedbat/coveragepy/commits) [![PyPI - Downloads](https://img.shields.io/pypi/dm/coverage?style=flat?style=flat "Download stats for coverage")](https://pypistats.org/packages/coverage) [![Follow @coveragepy on Mastodon](https://img.shields.io/badge/%40coveragepy-290-96a3b0?style=flat&labelColor=450657&logo=mastodon&logoColor=white "Follow @coveragepy on Mastodon")](https://hachyderm.io/@coveragepy) - [**Cog**](https://github.com/nedbat/cog): Small bits of Python computation for static files
[![PyPI](https://img.shields.io/pypi/v/cogapp?style=flat?style=flat "The cogapp PyPI page")](https://pypi.org/project/cogapp) [![GitHub last commit](https://img.shields.io/github/last-commit/nedbat/cog?logo=github&style=flat?style=flat "Recent cog commits")](https://github.com/nedbat/cog/commits) [![PyPI - Downloads](https://img.shields.io/pypi/dm/cogapp?style=flat?style=flat "Download stats for cogapp")](https://pypistats.org/packages/cogapp) - [**Scriv**](https://github.com/nedbat/scriv): Changelog management tool
[![PyPI](https://img.shields.io/pypi/v/scriv?style=flat?style=flat "The scriv PyPI page")](https://pypi.org/project/scriv) [![GitHub last commit](https://img.shields.io/github/last-commit/nedbat/scriv?logo=github&style=flat?style=flat "Recent scriv commits")](https://github.com/nedbat/scriv/commits) [![PyPI - Downloads](https://img.shields.io/pypi/dm/scriv?style=flat?style=flat "Download stats for scriv")](https://pypistats.org/packages/scriv) - [**Dinghy**](https://github.com/nedbat/dinghy): A GitHub activity digest tool
[![PyPI](https://img.shields.io/pypi/v/dinghy?style=flat?style=flat "The dinghy PyPI page")](https://pypi.org/project/dinghy) [![GitHub last commit](https://img.shields.io/github/last-commit/nedbat/dinghy?logo=github&style=flat?style=flat "Recent dinghy commits")](https://github.com/nedbat/dinghy/commits) [![PyPI - Downloads](https://img.shields.io/pypi/dm/dinghy?style=flat?style=flat "Download stats for dinghy")](https://pypistats.org/packages/dinghy) - [**WatchGHA**](https://github.com/nedbat/watchgha): Live display of current GitHub action runs
[![PyPI](https://img.shields.io/pypi/v/watchgha?style=flat?style=flat "The watchgha PyPI page")](https://pypi.org/project/watchgha) [![GitHub last commit](https://img.shields.io/github/last-commit/nedbat/watchgha?logo=github&style=flat?style=flat "Recent watchgha commits")](https://github.com/nedbat/watchgha/commits) [![PyPI - Downloads](https://img.shields.io/pypi/dm/watchgha?style=flat?style=flat "Download stats for watchgha")](https://pypistats.org/packages/watchgha) I've also made a few informal projects, some mathy art, and some small utilities: - [pkgsample](https://github.com/nedbat/pkgsample), an simple example of how to package a Python project. - [Truchet images](https://github.com/nedbat/truchet) explores Truchet tiles and rendering images with them. [Blog post](https://nedbatchelder.com/blog/202208/truchet_images.html). - [Flourish](https://github.com/nedbat/flourish) is a harmonograph explorer. [Blog post](https://nedbatchelder.com/blog/202101/flourish.html) and [live site](https://flourish.nedbat.com/). - [Stilted](https://github.com/nedbat/stilted) is a toy PostScript implementation. [Blog post](https://nedbatchelder.com/blog/202208/stilted.html). - [Gefilte Fish](https://github.com/nedbat/gefilte) is a Python-based DSL for writing Gmail filters. [Blog post](https://nedbatchelder.com/blog/202103/gefilte_fish_gmail_filter_creation.html). - [Pydoctor](https://github.com/nedbat/pydoctor) shows details of your Python environment for troubleshooting. - [Aptus](https://nedbatchelder.com/code/aptus/v3.html) is a Mandelbrot toy.

This is a [Markdown page with embedded Python code][readme.md] rendered with [cog][cog]. See my blog post **[Cogged GitHub profile][blog_post]** for details. *Updated at 2026-01-03 14:40 UTC* [nedbat]: https://nedbatchelder.com "My site with blog, talks, etc" [blog]: https://nedbatchelder.com/blog "My blog" [mastodon]: https://hachyderm.io/@nedbat [discord]: https://pythondiscord.com [libera]: https://libera.chat [bp]: https://bostonpython.com "The Boston Python home page" [pdeb]: https://python.github.io/editorial-board/ [ned_pypi]: https://pypi.org/user/nedbatchelder "The list of all my packages on PyPI" [cog]: https://github.com/nedbat/cog "The cog repo on GitHub" [readme.md]: https://github.com/nedbat/nedbat/blob/main/README.md?plain=1 "The raw source for this GitHub profile" [blog_post]: https://nedbatchelder.com/blog/202409/cogged_github_profile.html "Discussion of how this page is constructed"