Fox Row

Rowing, computers, astronomy

How to generate Django secret keys

You accidentally committed your secret key to version control, or the server got compromised, or you lost control of the secret key for some reason. Using an online service to generate one is a bad idea - nobody else should ever have your secret key. How do you generate a new secret key? The otherwise-excellent Django docs are silent on this. Here’s how Django generates one when you run startproject:

>>> import random
>>> ''.join(random.SystemRandom().choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)') for i in range(50))

Generate a new one and you’re good to go. - detect duplicate frames in Video, TV, or Film

The Force Awakens has a lot of shots that are callbacks to A New Hope - they evoke very particular scenes and shots, if not outright identical. That got me thinking about recycling shots in films. How could that be quantified?

A common task in image processing is finding sets of similar images. Often you have a picture, and you want to search for identical or near-identical copies from some large set. A few ways to do this are described here - pHash and dHash in particular are quite effective.

We can use this to our advantage. Given a video clip, we should be able to go frame-by-frame and hash each image. We can then count the number of frames that hash to the same value, telling us how many occurred earlier. I wrote up a python tool to do this:

Retread measures how much any given frame is reused in a video clip. It can be a TV show, online video, any video file you can get your hands on. It spits out nice JSON, so you can plot it nicely via d3.

Now, let’s see what some movies look like. First up is Mad Max: Fury Road, a 2015 action blockbuster with many fast cuts and short shots overall.

Often the most common frame ends up being black. This is usually credits, maybe a handful of frames from the beginning of the movie, and any fade-to-blacks in the middle. This shows up as big, solid bars near the beginning and end. The interesting stuff is in the middle. Here we see Max doesn’t have any monster repetitive sections: mad max duplicate frames

On the other hand, Memento, a film with a nonlinear story, has heavier and more spikes. The film is presented in sort of an outside-in fashion - the end comes first, then the beginning, then back to the end, working toward the middle the whole time: memento duplicate frames

Inception somewhat famously wraps multiple stories within one another, with the narrative jumping between all 3 in parallel. Christopher Nolan directed both Memento and Inception. He seems to be a fan of cutting across time and space. This results in a moderately busy graph: inception duplicate frames

Paprika, one of the inspirations for Inception, has even more. Flashbacks occur throughout the film, and it shows. The chart is almost totally full: paprika duplicate frames

See retread here to analyze your own films, TV shows, or clips.

Online stroke watch


How to use: Hit Start/Stop to begin or pause the timer. At either the catch or the finish, hit 'Stroke'. You don't need the stopwatch running to calcuate rate. No downloads or app required!

If this was helpful to you, check out Virtual Cox. It's an online service for rowing video analysis and athlete tracking. I wrote some more about it here.

Introducing Virtual Cox

I’m pleased to announce the launch of a project I have been working on for a while. It’s called Virtual Cox, and it’s an online tool to help rowers and rowing coaches row faster and more efficiently. The homepage can be found at

In a sentence: Virtual Cox lets rowers and rowing coaches analyze video to go faster on the water.

Elevator pitch: Virtual Cox lets rowers and rowing coaches analyze video to go faster on the water. Video can be captured via any device, and data analysis tools enable closer critique of form, technique, and consistency. Sharing tools let coaches provide feedback to athletes for later review.

Even a short amount of footage can make rough edges glaringly obvious, even things the rowers don’t realize they’re doing themselves! Despite being such a rich source of feedback to both athletes and coaches, there are often barriers to using it effectively (or at all). Like photography, the best camera is the one you have with you. My goal is to give crews the tools to take and analyze more video.

Video can be uploaded from any device, so you don’t have to bring along a video camera or mount any equipment on the boat. (Though you certainly can if you want!) Simply using your phone in the launch, GoPro up close, or video camera can take all the footage you need. Erging video works too, for those winter training sessions.

Once you’ve uploaded your video, tools allow you to slow down playback to closely review technique. For more advanced measurements, coaches and rowers can measure ratio, timing, and other metrics.

Coaches can save and easily share video and data with other coaches, coxswains, or athletes via a sharing link.

I’m always looking to hear from you! Send me an email at, I read all of them, and try to get back to everyone. If it’s been a few days and you haven’t heard back from me, send me a quick ping. It’s more likely it slipped off my radar than I took a personal disliking to your email. If you’re a rower or coach looking to get faster on the water, sign up at Virtual Cox, and follow @virtualcox.

Brainfunction - brainfuck with functions

Some time ago, I wrote a brainfuck interpreter. It’s nice and all, but I thought, “you know what would really make this great? More inscrutable instructions!” How to extend it, though? It already has such a great feature set. You may remember it from hits such as:

  • Hilarious-looking source code!
  • Turing completeness!
  • It somehow manages ultra-verbosity in a language with only 8 valid characters.

Despite that saliva-inducing list, one item you can never get enough of in computing is recursion. So let’s add functions! Brainfuck already has an array of data cells, let’s expand that to an array of functions to call as well.

Official brainfunction v0.1 spec (subject to revision):

The official brainfunction repository can be found at

The brain

A brainfunction program runs on the brain, which is an extended version of the brainfuck VM. It supports the eight standard brainfuck symbols, instruction pointer, data tape, and data pointer. In addition to this, it has an array of functions. When a brainfunction program is parsed, each line of text in the source file becomes a function. These constitute the function array, starting with the first line of text in position 0. A function is exactly one line of source code. This implies one cannot break up logical units multiple lines as is done in brainfuck.


Each function has a function pointer, initialized to 0 (the first line in the file). The function pointer is moved by the symbols v and ^, meaning “move the function pointer down” and “move the function pointer up”, respectively. Each function also has a local data pointer, data tape, and instruction pointer.


To call another function, the : symbol is used. When this occurs, the function pointed to by the current function pointer is called. The value in the caller’s current data cell is passed to the callee. This argument is placed in cell 0 of the callee’s data tape.


A function returns when the symbol ; is encountered or the function runs out of instructions. When a function returns, the value in the current data cell is returned. The return value is placed in the caller’s current data cell.


The brain begins execution in the zeroth function in the function array, and continues until an error is encountered or the function runs out of symbols. All symbols except the 12 specified are ignored. When a function calls another, execution blocks in the caller until the callee returns.

The reference implementation is an interpreter written in python, which can be found here.


Example hello world:

>++++++++++[>++++++++++<-]>++++.---.+++++++..+++.                    print hello
>++++++++++++[>++++++++++<-]>-.--------.+++.------.--------.         print world
>++++[>++++++++<-]>.                                                 print space character
>++++[>++++++++<-]>+.                                                print !

When executed, this will print

hello hello world world world!

Example factorial calculator:


When executed, this will prompt the user for input (limited to a single character), calculate the factorial of that number, and print the output:

bf > 5

### Roadmap Future developments may include real error messages, and perhaps a debugger, to make it easy to inspect the state of the brain. Maybe even zanier symbols!

That’s it! Look on my works, ye mighty, and despair! wtf?

Page 1 of 5