Images and EXIF

  • Apparently, when you snap a picture with an iPhone in portrait mode, pixel data is saved as landscape and its orientation added in its EXIF. This means you gonna get hurt real bad (like me) if you’re not careful when preparing data for training a model.
  • Fortunately, pillow has a great module for transposing images:
import os, glob
from PIL import Image, ImageOps

count = 0

def mylistdir(directory):
  """A specialized version of os.listdir() that ignores files that
  start with a leading period."""
  filelist = os.listdir(directory)
  return [x for x in filelist
          if not (x.startswith('.'))]

for dirName in mylistdir(os.getcwd() + '/img'):
  dirPath = os.getcwd() + '/img/' + dirName + '/*.jpg'
  for infile in glob.glob(dirPath):
    img =
    rotated_img = ImageOps.exif_transpose(img)

    count += 1

print('Transposed %d images' % count)

Google Cloud SDK

  • gsutil rsync will sync OS-related files and symlinks if you don’t supply it with the necessary flags. This one worked particularly well for me:
gsutil -m rsync -r -d -e -x '\..*|.*/\.[^/]*$|.*/\..*/.*$|_.*' [YOUR_DIRECTORY] gs://[YOUR_BUCKET]

UniFi Controller

If you’re using a UniFi setup in your home network, Java 8 is no longer bundled with the software from 5.11.47 onwards. Other than failing to startup the network controller, you might also run into database issues because of how permissions are set during installation. The steps to remedy this for 5.12.35 are to:

brew tap adoptopenjdk/openjdk
brew cask install adoptopenjdk8
  • Use a script to startup the network controller UI
cd "/Applications/"
exec $(/usr/libexec/java_home -v 1.8)/bin/java -jar /Applications/ ui
  • I’ve had to update my controller to 5.12.66 and it’s basically just installing over the existing default location. Running the same script will launch it the same way.

Game development

  • Finally understood what Delta time means. It’s the time difference between the previously rendered frame and the current frame. Multiplying vx * dt will move a sprite the same distance in the same amount of real world time regardless of frame rates!
  • Also, gafferongames is like the bible for game networking.


  • So I plugged in my long-abandoned ATH-M50x headphones today and everything sounded great except the vocals. Almost binned the thing but it turns out that the 6.35mm jack was just dirty. Wiped it down with isopropyl alcohol and all is well.