Setting up Home Assistant Supervised w/ WiFi on DietPi 64 bit running on Raspberry Pi 4

Start by downloading DietPi. First navigate to the website, navigate to the download section, and select the 64 bit version for Raspberry Pi.

Burn it to your micro SD card with your software of choice (I use Balena etcher on Windows). Once burned, unplug the SD card and re-insert it into your computer so you can edit your config and setup your Wifi. Use the following steps from the DietPi website:

  1. Open the file named dietpi.txt. Find AUTO_SETUP_NET_WIFI_ENABLED and set to value 1.
  2. Open the file dietpi-wifi.txt and set aWIFI_SSID[0] to the name of your WiFi network.
  3. In the same file dietpi-wifi.txt, set aWIFI_KEY[0] to the password of your WiFi network.
  4. Save and close the files

Once completed you can eject your SD, insert it into your pi and boot up! SSH into your Pi (default user: root | password: dietpi) and complete the setup. Go ahead and install Docker using dietpi-software. Now you’ll install a few dependencies:

apt install -y software-properties-common apparmor-utils apt-transport-https ca-certificates curl dbus jq network-manager

For the next step you’ll need to have your Pi plugged into either ethernet or a screen w/ keyboard. Because Home Assistant requires network-manager to function, while DietPi uses ifupdown, you’re about to run into some issues. In order to get Wifi working you’ll want to go and edit: /etc/network/interfaces. Use nano or your editor of choice and remove all of the lines associated with the WiFi configuration. Now you’re going to install Home Assistant:

cd /tmp/
curl -Lo
chmod +x
bash --machine raspberrypi4-64

Running the above commands will get the automated installer started, and you’ll quickly be presented with a prompt to overwrite your network manager settings. NOTE: If you’re on Wifi, and say either Yes or No at this step you will be disconnected!! Select Y, and the installer will proceed to install home assistant. Now, to reconnect to WiFi, the easiest approach will be to run the network-manager GUI via: nmtui. Run the command, select “Activate a connection” and enter in your WiFi details. Now you should be all set, enjoy your new Home Assistant setup!

Hotkeyboard – Part 1

I spend a large proportion of my day at a keyboard, both as a computer nerd (writing code, designing hardware, etc) and as an intern in internal medicine. I’ve come to appreciate a good keyboard when I use one, and I have definitely gotten some keyboard envy when I spy some of the fancier models bounding around the internet.

It seems like a sort of maker rite-of-passage to design and build your own keyboard, so inspired by some of the other builds I’ve seen on places like Hackaday and Thingiverse, I decided it was finally time to tackle my own.

Behold, my first attempt! Using OpenSCAD, I wrote the code to create a customizable hot-key keyboard (ie: not meant to cover the entire alphabet, more for quickly running a commonly used command or macro), which uses the common Cherry-MX switches and all of their click-y goodness. You can enter any arbitrary number of keys per row/column and it’ll spit out an STL to be used on your fav 3d printer. Wiring is easy, and using a Raspberry Pico as the brains makes it simple to start writing the script required to execute your hotkey commands/macros (more on that in another post). Now all I have to do is finish writing the script, and design some nice key-caps to match each key’s function. That and more coming up soon… to be continued!

Designing a 4th Axis for Engraving Rings on the CNC 2418/3018

Bill of Materials:

  • NEMA 17 Stepper Motor
  • 6x M5-16mm screws for securing to CNC build plate
  • 6x M5 nuts
  • 1x M3-35mm screw for driving wedge into mandrel
  • 1x M3-12mm screw for securing mandrel to stepper motor shaft
  • 4x M3-16mm screws for securing stepper motor to mount
  • 2x M3-20mm screw for axles on steady rest

It wasn’t too long ago that I impulse bought myself a mini lathe, inspired by the likes of This Old Tony among other youtube makers. I’ve relied on a scattered hodgepoge of information across the internet in order to get started actually using the thing. Safety came first, but after learning how to spin a chunk of metal at high speed and do so in a way that didn’t make me fear for my life, I turned toward learning how to actually incorporate this awesome new tool into my projects.

I came across the stellar introductory metal lathe tutorials by Blondihacks, and I am incredibly appreciative of Quinn’s ability to present the complex information surrounding proper lathe usage in such a straightforward and thoughtful manner! I would highly recommend checking them out if you’re just getting started with your first metal lathe!

I finally started gaining my footing, and by the time I reached “Metal Lathe Tutorial 16: Your First Project!” I was excited to put my newfound knowledge to good use. While there are many good options for a first project, Blondihacks kept it simple: we would make a ring (in other words, a simple bushing in disguise). I loved the idea, particularly as I had gotten my hands on some beautiful, shiny brass to start turning, I envisioned it would make a lovely ornamental piece.

I took the dimensions of my finger, drew out my schematic and organized my order of operations before setting out: facing, turning, center drilling, drilling, parting, filing, deburring, and finally polishing! Before I knew it, I’d turned a rod of solid brass into a shiny ring which slid perfectly onto my finger.

This was very satisfying, and I liked the look of the finished product, but I wanted to take this simple first project to the next level. I wanted to add some decorative elements, to up the wow factor. I also wanted to make another ring as a gift for my girlfriend, and I wanted to give it a bit more of my personal touch, add more of my craftsmanship and love to the final piece.


With this in mind, I started searching for solutions which would allow me to use my CNC machine to etchy whatever kind of ornate pattern I desired into the surface of the ring. I envisioned a simple fourth axis using a stepper motor to turn some sort of mandrel which would hold the ring in place during carving. I turned to thingiverse, thinking surely someone else had designed one already. Much to my surpise no such design existed! Determined to make it happen, I booted up Freecad and started designing my own.

Dark Grey = Stepper | Light Grey = Stepper Mount | Orange = Mandrel | Blue = Wedge | Yellow = Steady Rest

Above you can see the latest version of the FreeCAD model as of the time I am writing this post (v3, although some work still remains to perfect the design). Both the original design files and the STLs can be found on Thingiverse:


I want to share the steps that I took in order to actually put the above design into action, with the hope that one day it might help someone else looking to do something similar.

I started by finding an SVG of my design. For my first run, I used the staff of asclepius, a symbol of medicine and physicians. I pulled this into FreeCAD using the “Draft” workbench. I then convert to a sketch before switching to the part design workbench to fit it into my body of choice. See the video below for a quick rundown on my methodology.

Once I’ve got my model all setup I head over to the path workbench and create my toolpath. In the current version of freecad the engraver tool does not seem to work for pocketing so I create an endmill tool with a diameter of 0.1mm, which approximates the diameter of the tip of my V-engraver bit. I create a pocket operation with a 0.2mm final depth and 0.1mm stepdown (this is likely very conservative, but better safe than sorry). I use a 1mm/sec feedrate and set my spindle to max RPM.

The final step before starting your operation on the CNC mill is VERY IMPORTANT! With this new rotary 4th axis, you must tell your CNC machine how many steps it takes to move 1mm on the surface of your ring. In my case, I am using GRBL to run my CNC mill; additionally my control board does not have a free stepper port to control the 4th axis so I swapped out the y-axis stepper for the 4th axis stepper. Given I am using the Y-axis I went ahead and changed the value of $101= 38, which tells the control board that there are 38 steps required to travel 1 mm on this axis. (note, always a good idea to write down your default value, so you can reset back to it once your done using the 4th axis). I arrived at the number 38 using some simple math. My stepper drivers are set to 1/8th stepping, thus there are 360 * 8 steps per full revolution. I know that the outer circumference of my ring is equal to pi * diamter (in my case pi * 24 ~= 75). Thus I simply calculate (360 * 8) / (pi * 24) ~= 38.

With that final step, we were off to the races. It was smooth sailing from there, with one exception. It seems that there is some imperfection in the leveling of my setup (something I tried to avoid with the steady rest, with mixed results. Thus the bottom half of my design did not engrave as deeply as the top half. The fix was easy in this case, I simply re-engraved this section of the design after dropping my starting Z by 0.1mm. On my next run I hope to avoid this issue altogether by using my CNC’s Z-probe function to map out the height of the ring surface (it’s conductive so it should be fairly straightforward) prior to engraving. I’ll be sure share the results in my next blog post. Until then, stay happy and healthy, and may you have success in all your DIY endeavors!

COVID-19 Mask Search 2.0

Around two weeks ago, I posted about a bit of software I wrote in Python. The goal of this project was to quickly create spreadsheets of businesses in a given area, such that they could be imported into a shared Google Sheet and used in order to organize volunteers at my medical school in their efforts to call businesses and ask for donations of personal protective equipmment (PPE; namely N95s/masks) for our frontline healthcare workers. Word quickly spread and I was soon flooded with requests from students at other schools around the country to help them with fetching their own PPE data.

I wanted to publish this update both to share the good this little bit of code has helped make happen (see the map above), but more importantly to share the latest version. This new release of the software contains essential updates: not only is it cleaner and easier to understand (I hope), but new functionality has been added in to further automate the fetches of data. Now, instead of generating one CSV file per locale+industry, the software accepts a list of industries/business types and a locale and then searches for each industry in the given locale, ultimately generating an excel spreadsheet with multiple pages: one for each industry with hundres of rows of businesses and their info such as name, phone #, address, and some other added metadata for volunteers to use for organization. After that, all you need to do is upload this excel spreadsheet to Google sheets and convert it to the Google Sheets format (File -> Save as Google Sheet). Share it with a group of volunteers and let the phone calls and PPE donations start building up. This work can really make a difference for those on the frontline desperate for the PPE they need to protect themselves from infection!

Example of a spreadsheet of business data uploaded to Google Sheets.

Yelp Mask Search: Collect Business Contact Info For COVID-19 PPE Donations

See the latest updates to this project in part 2!

With the outbreak of COVID-19 in NYC, our healthcare system has demonstrated that it is poorly equipped to respond to the needs of its clinicians and other frontline healthcare workers. Most obvious is the lack of effective personal protective equipment (PPE; namely N95 respirators and other masks) which our doctors, nurses, respiratory therapists, and others need in order to protect themselves against infection with the virus. It’s glaringly obvious that if you fail to protect your healthcare workers from falling ill, your system is going to fail — and fast too. Nonetheless, we are barely at the outset of the outbreak and our hospitals are already strictly rationing PPE, causing deeply concerning comprimises in patient and provider safety.

Residents from multiple NYC hospitals reach out to our volunteers to acquire proper PPE.

The problem has gotten so bad that residents and medical students have begun scouring the community for businesses (closing down by law) with extra respirators that they are willing to donate. I was brought on to a medical student team that was calling construction businesses, nail salons, dry cleaners, hardware stores, and tattoo parlors. The volunteers had been manually entering businesses into a massive spreadsheet: organizing the info on what business had been or needed to be called, who had donations to give, and more.

Example PPE donation spreadsheet. Business info (veterinarians, construction, painters, dry cleaners, etc) retrieved from online searches manually.

I was asked to write some code to scrape the web for a list of businesses and their contact info. I went to the Yelp API, and got to work. What resulted was a simple python notebook that I am now hoping to share with voluteers at other hospitals or med schools. The code simply takes a Yelp API key, location, and search terms and generates a CSV spreadsheet of the first 1000 businesses to match the search along with their phone numbers, addresses, and Yelp pages.

You can get started using this simple data scraper by opening the Python notebook below for free using Google Colab (look for button at the top of the code). Once open, simply change the settings for your location, search terms, and API key and you can start generating your own lists of businesses to call for donations! Our group has had success with copy/pasting each industry into its own page in a Google spreadsheet. With this system, multiple volunteers can collaborate and work on calling businesses in parallel.

Repairing a Kitchenaid Mixer

I was walking down the streets of Manhattan when my I spotted it. A cobalt-blue KitchenAid stand mixer, sitting abandoned and alone on the sidewalk. I knew that it was not likely to be in working order, but I also know that many people throw away broken technology that can easily be revived with a quick repair job in the right set of hands. I picked it up and carried it over a mile back to my apartment. Let the games begin!

I was not surprised to find that, despite being in otherwise great condition, the mixer was not fully working. Luckily, when I plugged it in and turned it on, I was greeted by the sound of a happy and healthy electric motor, however there was no movement out of the mixer itself. I fetched my tools, and prepared my operating room before diving into the insides of this hefty machine.

Opening the mixer was a bit of a trial, requiring a set of security screwdriver bits, but I was not going to be deterred so easily. For $11 on Amazon, I had the requisite bits shipped to my doorstep in two short days. I pressed onward, opening the contraption’s heavy cast-iron shell to reveal its inner workings. I scraped away the heap of food-safe grease which encased the drive train and the problem because obvious fairly quickly: the worm gear which coupled the motor to the mixer’s output had been completely destroyed.

The white gear seen at center of the image was completely chewed up, no wonder it wasn’t moving.

It turns out that this is a common issue that befalls the owners of KitchenAid mixers. In fact, this failure was an outcome of an intentional design decision by the KitchenAid engineers. In the event that the mixer is overloaded, this gear is destroyed, rather than the other metal gears in the drive train or the motor itself. A replacement can easily be purchased online for a mere $8-10, but I had another idea of how I wanted to fix this thing up.

A quick perusal of the internet revealed that I could easily print out a replacement gear, and so I put my Anycubic Kossel Linear Plus 3D printer to work! In less than a half hour, I had a replacement gear made out of PLA. I wanted the new part to be strong, so I went ahead and heated up my toaster oven to 170 C, turned it off, and then popped the newly printed gear in. As the toaster cooled, it heated the gear to its glass-transition temperature, allowing the molecular structure of the plastic to rearrange, thus reducing any stress that had been present in the structure as a result of the 3D printing process (this process is known as annealing, and has been demonstrated to significantly increase 3D printed part strength!).

Newly printed gear after annealing!

Now came the scary part. I extracted the old gear from its gearbox and used a jeweler’s saw to remove the old plastic gear from its metal core. I then used a blowtorch to heat the metal core to approximately 200 C and carefully pressed the new gear on (using oven mitts to avoid burning my hands). It wasn’t perfect, but afterwards I had a fully functional replacement gear that fit snugly into it’s new home!

New PLA gear fitted onto the metal core, alongside the old gear it was replacing.

I finished reassembling the mixer, and was overjoyed when I turned it on and I saw everything moving as it should. It works perfectly, and so far seems to be more than strong enough to do its job! Next up is trying to build/buy a pasta maker so I can get some more fresh noodles in my life, wish me luck!

Hacky Headphone Mixer

Every once and a while I come across a problem which has a fairly expensive solution where a much simpler and cheaper one will do. In this post I’m going to try to give a quick summary of one such problem, the project I undertook to solve it, and how I saved around $30 while learning a thing or two about circuitry and product design along the way. I also hope that anyone trying to build a similar project will be able to find this post and gain some info to help them along their way.

What did I need?

In my apartment I have one speaker system and two devices which I use for audio playback: my desktop computer and my Echo Dot. When I wanted to switch between the two devices I’d need to move the speaker input jack manually from one device to another. This practically negated the convenience of controlling my music (which I have constantly playing when I’m home) through Alexa. After some time, I got fed up and decided to begin looking for a solution.

After a quick search, I determined I could solve this problem with an audio mixer which accepts input from two or more 3.5mm headphone jacks and outputs audio through another 3.5mm jack. A quick search of online retailers revealed that I’d have to pay at least around $35 for such a device. All of the devices had features which I did not need (like balance and gain, which I can adjust on my input devices), and many of them used 1/8” jacks rather than 3.5mm, making adapters necessary.

I’m pretty familiar with electronics and circuitry work, but audio signal circuits were something which I was quite unfamiliar with. However, given that audio is transmitted by analog signal over 3.5mm connections I intuitively figured I should just be able to merge the two signals together.

I started doing some research, and quickly came across a number of projects which use amplifier circuits and ICs in order to perform signal mixing (largely for the purpose of controlling the gain of each channel), but remember, the name of the game here is cheap. I wanted to try and get this done with as simple a circuit as possible. So I narrowed my search to include only circuits using passive components. I came across a very helpful Instructable (here) and several posts on the subject (here and here) which all suggested that the passive mixer circuit I envisioned would work just fine, so long as there were resistors on each audio channel going into the mix.

The major drawback of this setup is that as we increase resistance in the circuit we will reduce the output gain (volume) of the mix. Because I am feeding my audio signal into a speaker system with its own built-in amplification circuits, however, this was not at all a problem.

The build

I settled on building a mixer with two 3.5 mm inputs and one 3.5 mm output (just enough for what I needed). I used the following parts and tools for this build:

  • Parts
    • 3 x 3.5mm jacks ($3 for 20 on ebay)
      These come in many different shapes and sizes, so you may need to adjust the case model
    • 4 x 1k Ohm resistors
    • 1 x Screw
    • Wire
    • Solder
    • PLA Filament
  • Tools
    • Soldering Iron
    • 3D Printer

After I received the 3.5mm jacks in the mail, I was able to get to work designing a 3D printed enclosure to encase the circuit and protect it from damage. I constructed a case in two parts: a base which has slots for each of the headphone jacks and a lid which holds the headphone jacks in place (secured using a screw) with a space for the wiring to run. You can find the STL files for the print here.

After the print was finished it was time for the wiring, by far the most difficult part of this project. Each 3.5mm headphone jack needs 3 terminals (though extra pins may be included on the jack): the left + right audio channels, and a common ground.

Image from CircuitBasics

The goal was to pass the signal of each audio channel (left or right from each input jack) through a 1KΩ resistor into a common line to the respective pin on the output audio jack. The ground lines are simply connected by a wire. This is not too difficult to diagram, but soldering it together proved a bit more challenging.

The trick with constructing the circuit is connecting all of the resistors, wires, and pins together without allowing them to contact one another and short out. I quickly began to wish I had left myself a bit more room to work with when designing my case, as it got rather cramped in there. In the end I used a combination of heat shrink tubing and hot glue to insulate the solder joints and strengthen the internal structure against drops or vibration (which the device might encounter while in daily use).

My final circuit looks a bit unruly, but it’s completely functional, and I love it! I screwed the lid on and gave it a test drive…

Concluding Notes

I was a bit worried when first testing the device (remember, I’ve never worked with audio circuitry before), but it worked fantastically on the first try. Additionally, the audio quality is excellent, I have observed no noticeable difference with and without the device.

It’s been 3-4 months now since I first built this prototype, and I still use the mixer daily. It sits on my desk and serves as a really nice reminder that, when I get creative and inspired, I can express myself and build some nifty (and occasionally useful) projects. As I move forward into my Clerkship year of medical school and beyond, I hope to keep making the time to get creative and build something. It’s an outlet of mine that never ceases to satisfy.

Creative Half-Year in Brief Review

It feels like the past 6 months of school have flown by. I’ve dedicated innumerable hours to my studies, and learned such an incredible breadth and depth of medical knowledge in my lectures. I feel empowered to start my work on the wards in the new year. That said, and despite the weight of all of my academic responsibilities, I’ve made sure to take the time to
get creative, express myself, and build some cool stuff.

In a series of posts to come, I hope to tackle my back-log of projects without write-ups. I’ll try to explain a bit about my process and how my work can be replicated.

Highlight: 3D Printing + Hardware Design

On a rainy evening this past summer I found a 3D printer discarded in the trash on a street in NYC. Seeing that it was structurally intact, and being the ambitious maker that I am, I took it back to my apartment, slowly repairing it to good working order. In the subsequent months I’ve learned so much about everything 3D printer related: the design of 3D parts using tools like Fusion360, OpenSCAD, and FreeCAD; slicing parts effectively for
FDM printing; finishing 3D printed parts; repairing printers; and driving stepper motors.

3D printing has allowed me to design some room-automation hardware that I’ve wanted to build for a very long time. It allowed me to build cases for some of my existing projects, and even produce some more whimsical objects like self-watering plant pots, skull cacti, and marble machines!

I’d previously written a blog using a Ruby framework called Jekyll, hosting for free on Github Pages, but I’ve found the process cumbersome and time consuming. I’ve got so many projects in my back-log to write up, and I’ve learned a lot about docker for web application hosting, so I’m switching over to using this dockerized WordPress instance running on my personal server. I hope it’ll facilitate my writing process (and thus help me more readily express myself).

Thanks for reading, and stay tuned for more posts!

Modeling Epidemics – First Steps with Agent-Based Modeling Pt. 2

We spent the last post discussing principles of agent based modeling, and the basic layout of the model I have initially created. Now it’s time to see some results! All of the code used to generate this model can be found here.

First off, I want to talk a bit about the approaches which I have taken towards the visualization of my model, as well as the inadequacies of these approaches. In the previous post, I discussed the fact that my model is based upon the usage of networks (graphs) for the mapping of social interactions. My first approach to visualization (particularly during the development process) was plotting these networks, as this allowed me to see how the disease was spreading in my model, and debug. This worked well during the testing phase, when my model population was rather small; however, when I scaled up the model, this technique did not work as well.

Example Small World Graph

Two example small world networks generated and drawn by the networkx library in Python. As the number of nodes increases, ease of interpretation decreases dramatically. The graph on the right is often referred to as a hairball.

Nonetheless, I have yet to find any better way of displaying the change in the nodes of my network over time. There are other software out there which are better suited to the display of graphs (and allow for greater interactivity), but I have yet to spend much time exploring them. I am particularly interested in two softwares: Gephi, which is a Java based software built for the purpose of both analyzing and visualizing graphs; and sigma.js, a browser-based Javascript library built for the purpose of visualization.

Network Animated GIFs

For now, I have harnessed a technique I have leveraged in a previous project in which I analyzed of US Senate data. I utilize the ImageMagick “convert” command-line tool in order to combine a series of static images into an animated gif (example here). For my network, I animate the nodes as they change color to indicate their infection state. The vizualization is a bit chaotic, but I think it looks real neat.

Animated Network Graph

Animation displaying the spread of the disease through the network (# nodes = 1000). Each node (or individual) can have one of four states for a given pathogen: susceptible (blue), infected (yellow/orange), recovered (green), or dead (red). Here we show a single pathogen system.

Graphing Disease Progression

Though the animated network looks pretty cool, it doesn’t tell us much about the quantitative dynamics of the disease. As such, I have the model create a graph of the SIRD dynamics for each pathogen present in the system (so far I’ve only tested single pathogen systems).

Animated Network Graph

A graph depicting the dynamics for a theoretical pathogen – I’ve taken to calling it the 1918 flu due to it’s rapid spread and high mortality rate. This graph represents the same epidemic displayed in the above animated network.

Expected vs. Actual Results

The fact that my model works at all is already pretty exciting, it was not an easy process to work out all the bugs, but what was more interesting was how closely the model mirrored the dynamics which I derived from my mathematical models. This indicates to me that my agent based model has some degree of predictive validity!

Epidemic Dynamics Comparison

Comparison of results from my agent based model (ABM) on the left and mathematical model on the right. Click to enlarge.

Next Steps

Now that I feel I’ve got a hang of the basics of ABM, I’ve got some real thinking to do. The value of these models is lies in their predictive potential, however I’m not sure exactly which questions I should be asking and trying to predict the answers to. My first impulse has been to explore the internet for epidemic datasets, which I can use as the basis for a predictive model. It’s good to have some sort of empirical data behind any given model, both as a point of comparison, as well as a guide for modeling a real-world system.

I think the biggest thing that my current model lacks is the incorporation of spatial data: clearly the real world is not a flat plane, and there are a number of geographical features which can greatly impact disease transmission. My current thoughts on approaching this issue involve the use of real-world GIS data, as a means of determining population density and movement. In a model of human interactions, it may also be important to incorporate physical objects with which hosts can interact. Inanimate objects (known as fomites) are quite capable of transmitting pathogens, and this sort of interaction may be completely unrelated to social networks.

Ultimately the direction I will take in continuing this research will depend on the questions I am attempting to answer. If you have any ideas of how I can continue this work, feel free to drop them in the comments section. If you’re interested in collaborating with me on this research, please feel free to get in contact. Thanks for reading!

Modeling Epidemics – First Steps with Agent-Based Modeling Pt. 1

For those who have been reading along with my past couple of blog posts, you’ve seen me explore different means of utilizing computational modeling to explore epidemic dynamics. In my last two posts (here and here), I developed a basic set of scripts (in R and Python) which apply a series of simple formulae to model aggregate/bulk infection dynamics in a population. In this case, the model is considered deterministic: meaning that my outcome will be the same every time I run the model.

Now, these mathematical/deterministic models can be useful for approximating the general outcomes of an outbreak, however they can fail to capture the nuances which might be present in a more complicated model. There is less flexibility in this kind of model to alter population or disease behaviours without completely redefining our equations. This is not to say that such models cannot be created, simply that I do not have the expertise or know-how to do so.

Instead, since the beginning of this project, my intention has been to utilize agent based modeling (ABM) as a tool for exploring epidemic dynamics. Just to restate what I discussed in this post, an agent based model does not utilize formulas to model epidemics; instead, the modeler must design agents (objects in an artificial/simulated world), define how these agents interacts, and when they interact. The simulation is then run, and the outcome determined at the end. Typically, these simulations incorporate some degree of randomness, so no two simulations will have exactly the same results (provided the random number generator seed is different).

Jordan’s First ABM

I decided to start simple for my first attempt at designing an ABM, though I did not want the model to be so simple that it would no longer be meaningful. There are three major components to any agent based model, and I will try to describe how I implemented each part in my model. I define each of the components of my model as a Python class for ease of use, and efficiency of code:

  1. Environment: In order for an ABM to exist, there must first be a space in which our agents can exist and interact. In my model, I call this the “World” class, and take this world to be a spatially homogenous region in which social beings can interact. Though the world I use is simplistic (possessing no geographic traits or barriers), it will serve well for this initial model. In future models, I hope to simulate a more realistic world, perhaps using GIS data from a major city (like my current home, Houston), in order to account for spatial factors in disease transmission.
  2. Agents: In this case, there are two major types of agents, hosts and pathogens. I’ve defined my hosts under the “Person” class, though really they are too simplistic to accurately represent people (they just interact with one another, not the environment); instead it may be helpful to think of them more like any other social organism. The pathogens, on the other hand, are defined by the “Disease” class; they are simply capable of infecting hosts, adding an “Infection” class to be stored in for a given host (this class contains the logic for recovery and death of the host).
  3. Relationships: In order for anything to happen in the simulaton, relationships must be defined in order to dictate how the various agents interact with one another. I’ve used my limited knowledge of graph theory to define a network of social interactions between various members of the “Person” class. I use the networkx Python library to generate this graph. Each of the nodes in the graph represent a person, and the edges represent a social connection (the two nodes/hosts know one another and regularly interact). I utilize a randomly generated, small world network topology to simulate a semi-realistic social network. If all this graph theory, mumbo-jumbo doesn’t make a lot of sense to you, read on, I’ll try and explain it more in the next section.

A Quick Primer on Graph Theory

The name “graph theory” is actually a bit deceptive, because it does not refer to the kind of graphs that we typically think of: those with an X and Y axis which depict the relationship between different variables. Instead, graph theory describes the relationships between different entities. These graphs look like spider-webs or clouds of points connected together by various lines. There are two parts to any graph: nodes, the points on a graph which represent the interconnected entities; and edges, the lines which connect nodes on the graph.

Example Graph

An example graph, depicting the relationships between various members of a university karate club. Generated by networkx, using karate_club_graph()

Small World Networks

Previously, I mentioned that I am utilizing a small world network in my model. This term may seem a bit daunting, but describes a familiar concept. I can frame it best in terms of the idea of six degrees of separation, which suggests that in real-world human social networks, any one typical individual is socially connected to any other by a chain of relationships between no more than 6 people. Human society is large (there are a lot of people, and a lot of space) and complex, so this idea may initially seem difficult to believe, but it makes sense in light of a simple principle. There are certain individuals who are able to span long-distances in a given population; these are the individuals who are capable of connecting far-off individuals to one another. For instance, you may live in New York, but have a cousin in California who is able to connect you to any number of people on the opposite side of the country (maybe even a Hollywood celeb).

A small world network mirrors this simple idea. While many nodes (individuals) are connected only to those close by, there are some nodes which have connections that can span great distances to reach far away parts of the network. In this way, most of the nodes are fairly well connected to one another. One counterintuitive aspect of graph visualizations (like the one above) is the fact that the position of each node does not matter for the determination of distance between two nodes; in fact, the nodes are initially placed randomly on an x/y plane for visualization purposes. Instead, distance in graphs is measured by the minimum number of edges (the lines between nodes), needed to travel from one node to another. Small world networks minimize this distance for any two given points.

Creating a Small World Network

While the algorithms for generating a small world network may seem complicated, they can be boiled down to a simple approach. First, we generate a regular network (one in which nodes are only connected to those close by to them). We then randomly select nodes and “rewire” them, connecting them to a distant node. This process can be visualized below in a plot from a 1998 Nature publication on the subject by Watts and Strogatz.

Small World

Concluding Thoughts

This article has gotten a bit longer than I originally expected. I’m gonna end it here, and pick up next time with a review of the results from my first ABM simulation. Thanks for reading!