Principles

I define success as a human being as having a set of well-grounded invariants, always doing your best to strive for them, but continuously challenging them. A successful human being will fight to defend their invariants with all the energy they have until the precise moment they are presented with a better alternative. This page has some core tenets, followed by a number of invariants that go into more detail in all aspects of life.

Ambiguity Evaluator

When defining grammars, it is useful to know whether they are ambiguous, ie. whether the same output can be attained by two separate paths through the syntax tree. For example, given the grammar S := aS, aaS, ε, the string “aa” can be obtained either by applying the 1st rule twice or the 2nd rule once. There is no general purpose algorithm to determine whether a grammar is ambiguous or not, and so here is a brute-force approach which enumerates all the words up to a certain depth (say, 5 rule applications) and determines whether the grammar is definitely ambiguous or potentially not.

GSOC18: Reverse Engineering AirPlay for VLC

I discovered Google Summer of Code quite late. Scrambling together my applications made for a hectic weekend. I had a goal in mind but, as a contingency, used up all three proposals. A few days later an email pinged into my inbox from a familiar name and I was welcomed aboard. I was bringing AirPlay support to VLC. The Goal In VLC 3.0 there was a considerable effort made that paved the way for my project.

Infinite Sieve of Eratosthenes

The Sieve of Eratosthenes is a well known algorithm for finding primes. Typically, it is performed on a bounded set of N numbers to yield all primes less than N however with a few compromises, it is possible to make an infinite generator. There is a solution floating around the code-scape using generator expressions which (on top of choking with python’s recursion depth) doesn’t properly follow the algorithm. This is the fake sieve:

Composing Serializers With DRF

Django Rest Framework provides a fast way to build APIs, expressing them as a set of serializers and views. I recently ran into a case where I wanted user-specific data to be included when a user is authenticated, but default to the generic serializer in all other cases. /api/v1/items/2 (anonymous) 1 2 3 4 5 { "name": "Cannonball", "item_id": 2, "store_price": 5 } /api/v1/items/2 (authenticated) 1 2 3 4 5 6 { "name": "Cannonball", "item_id": 2, "store_price": 5, "favorited": true } This lead to two separate but similar serializers, only differing with the inclusion of the favorited field.

Setting up a Headless, WiFi'd Raspberry Pi

Sometimes you just get stuck in situations where you don’t have access to an HDMI port or mouse/keyboard when setting up a raspberry pi. Luckily, there are a good number of solutions at your disposal to install the OS and connect to wifi without any human intervention. This works for any wifi-enabled pi, including ones with wifi over usb. Obtaining an Image The first step is to obtain an operating system image for your new raspberry pi.

Command Line Todolist

In trying to boost my command-line productivity I decided to drop todoist and pick up something that is a little more automation friendly. Todoist hides many of its useful features behind their premium subscription as well as abstracting away the user from the data. I wanted a simple tool that would allow me to take control of my data as well as providing a simple interface for automation. The tool I settled on was todolist, which is a simple but expressive todo app.

Getting Started With ZSH

The following is a small story of my switch to zsh, followed up by my dotfiles management. I decided I needed to upgrade my terminal experience and make it consistent between my main machine and any other machine I regularly use such as the servers at University. To start, I decided to take the full plunge and give my terminal a makeover starting with ripping out bash and replacing it altogether.

Memoize

This simple decorator can significantly speed up recursive functions in python by storing solutions in a dictionary as it runs. The code uses the new typing library introduced in python 3.5 but it isn’t strictly necessary. It supports functions with any number of input parameters. note: that the solution dictionary is tied to the function itself so multiple calls to the same function will reuse cached solutions from any previous calls.