-
Jul 5, 2017
painting clouds with clojure
Over the 4th of July weekend I made this little program to generate images of clouds

(ns clouds.core (:gen-class) (:import [java.awt.image BufferedImage] [java.io File] [javax.imageio ImageIO] [javax.swing JPanel JFrame SwingUtilities] [java.awt Graphics Color Dimension RenderingHints])) (def width 500) (def height 500) (def num-particles 1000000) (def color-cache (atom {})) (def output-image? true) (defn- rand-between [min max] (+ (rand-int (- max min)) min)) (defn- make-gray-color [color-val alpha] (let [color-key (keyword (str color-val "-" alpha)) cached-color (color-key @color-cache)] (if cached-color cached-color (let [^Color new-color (Color. color-val color-val color-val alpha)] (swap! color-cache assoc color-key new-color) new-color)))) (defn- paint-clouds [^Graphics graphics] (loop [n 0 last-x (rand-int width) last-y (rand-int height)] (let [rand-op (if (< (rand) 0.5) inc dec) rand-axis (if (< (rand) 0.5) :vert :horiz) new-x (if (= rand-axis :horiz) (rand-op last-x) last-x) new-y (if (= rand-axis :vert) (rand-op last-y) last-y) rand-gray (rand-between 250 255) rand-alpha (rand-int 75) neighbor-alpha-modifier 0.11 particle-color (make-gray-color rand-gray rand-alpha) neighbor-color (make-gray-color rand-gray (int (* rand-alpha neighbor-alpha-modifier)))] (doall (for [x-offset (range -1 2) y-offset (range -1 2) :let [x (+ new-x x-offset) y (+ new-y y-offset)] :when (and (<= 0 x width) (<= 0 y height) (or (= x-offset y-offset 0) (not= x-offset y-offset)))] (let [^Color color (if (= x-offset y-offset 0) particle-color neighbor-color)] (doto graphics (.setColor color) (.drawLine x y x y))))) (when (< n num-particles) (recur (inc n) new-x new-y))))) (defn- painter [] (proxy [JPanel] [] (paint [^Graphics graphics] (let [^int width (proxy-super getWidth) ^int height (proxy-super getHeight)] (doto graphics (.setRenderingHint RenderingHints/KEY_ANTIALIASING RenderingHints/VALUE_ANTIALIAS_ON) (.setRenderingHint RenderingHints/KEY_INTERPOLATION RenderingHints/VALUE_INTERPOLATION_BICUBIC) (.setColor (Color. 135 206 250)) (.fillRect 0 0 width height)) (paint-clouds graphics))))) (defn- gen [] (let [^JPanel painting-panel (painter) ^Dimension dim (Dimension. width height)] (doto painting-panel (.setSize dim) (.setPreferredSize dim)) (if output-image? (let [^BufferedImage bi (BufferedImage. width height BufferedImage/TYPE_INT_ARGB) ^Graphics graphics (.createGraphics bi)] (.paint painting-panel graphics) (ImageIO/write bi "png" (File. (str "output/" (System/currentTimeMillis) ".png")))) (let [^JFrame frame (JFrame. "clouds")] (.add (.getContentPane frame) painting-panel) (doto frame (.pack) (.setVisible true)))))) (defn -main [& args] (gen)) -
Apr 18, 2017
Getting average motorcycle price across all Craigslist cities
Today I’m going to look at a motorcycle that’s for sale on Craigslist. The asking price for the bike seems fair, but I wanted to get a sense for what other people were asking for the same model and year.
First I did a local search for the motorcycle I was interested in using the year, make and model search filters. The resultant URL was
https://philadelphia.craigslist.org/search/mcy?srchType=T&auto_make_model=suzuki+TU250X&min_auto_year=2012&max_auto_year=2012This returned all the listings in Philadelphia for a 2012 Suzuki TU250X. The srchType=T parameter filters to only include results that have a match in the listing title.
Using pup, a command-line tool for parsing HTML, I extracted the asking price of the motorcycle in the search result listing.
curl -s "https://philadelphia.craigslist.org/search/mcy?srchType=T&auto_make_model=suzuki+TU250X&min_auto_year=2012&max_auto_year=2012" | \ pup 'ul.rows li.result-row p.result-info span.result-meta span.result-price text{}'There is a CL page that lists every Craigslist site in the US. I parsed that for each location’s specific URL.
curl -s "https://geo.craigslist.org/iso/us" | \ pup 'div.geo-site-list-container a attr{href}'I combined these
curl -s "https://geo.craigslist.org/iso/us" | \ pup 'div.geo-site-list-container a attr{href}' | \ while read location; do curl -s "$location/search/mcy?srchType=T&auto_make_model=suzuki+TU250X&min_auto_year=2012&max_auto_year=2012" | \ pup 'ul.rows li.result-row p.result-info span.result-meta span.result-price text{}'; donewhich outputs the asking prices…
$3800 $2750 $2800 $2950 $3800 $3750 $2800 $2400 $2750 $2950 $2750 $3800 $3750 $2700 $2400 ...I was then able to see how the price of the motorcycle in which I was interested compared to similar bikes throughout the US.
-
Jan 2, 2017
Resume
I just updated my resume – the latest version of it should be viewable here.
For this iteration of resume-writing I decided to try out the open-source JSON Resume schema and tooling. So far it’s OK. My only complaints are:
- No markdown export support, despite the docs mentioning it
- PDF exports are pretty gross
- Can’t export using a local theme, though there’s an open issue about this
To get a PDF version of my resume I ended up just writing it in markdown and then using pandoc to generate a PDF from that. I’m wondering if just using markdown and pandoc would be a better option in the long term, but we’ll see. It’s nice having a resume under vcs though :)
-
Nov 8, 2016
How to set SQL modes for MySQL in a CircleCI container
In
circle.ymlyou can add comma-separatedsql-modes to/etc/mysql/my.cnfand then restart themysqlservice, e.g.:database: pre: - echo "[mysqld]" | sudo tee -a /etc/mysql/my.cnf - echo 'sql-mode="ALLOW_INVALID_DATES"' | sudo tee -a /etc/mysql/my.cnf - sudo service mysql restart -
Aug 29, 2016
OS X Setup Guide
Recently I got a new work laptop. Today I configured it and documented the process. If I make any changes to these instructions I’ll update them in this Gist.
Update: I recently had to set up a new computer, so I took the opportunity to automate a lot of this stuff: https://github.com/bi1yeu/new-macos
Here are the programs and tweaks I first made on a fresh install of OS X 10.11:
Homebrew / Cask
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" $ brew tap caskroom/cask $ brew tap caskroom/versions $ brew tap caskroom/fonts $ brew tap tldr-pages/tldrRearrage PATHs
This is so that Homebrew-installed tools load instead of built-in ones. git, emacs, etc.
$ sudo vi /etc/pathsPut
/usr/local/binabove/usr/binin the list. Save file and restart terminal.Install with Cask
$ brew cask install alfred # https://www.alfredapp.com/ $ brew cask install flux # https://justgetflux.com/ $ brew cask install font-source-code-pro # https://github.com/adobe-fonts/source-code-pro $ brew cask install google-chrome # https://www.google.com/chrome/browser/desktop/ $ brew cask install iterm2-nightly # http://iterm2.com/ $ brew cask install java # https://java.com/en/download/ $ brew cask install keepingyouawake # https://github.com/newmarcel/KeepingYouAwake $ brew cask install lunchy # https://github.com/eddiezane/lunchy $ brew cask install middleclick # http://rouge41.com/labs/ $ brew cask install osxfuse # https://osxfuse.github.io/ $ brew cask install spectacle # https://www.spectacleapp.com/Install with Homebrew
$ brew install aspell # http://aspell.net/ $ brew install git # https://git-scm.com/ $ brew install gnupg2 # https://www.gnupg.org/ $ brew install homebrew/fuse/sshfs # https://github.com/libfuse/sshfs $ brew install httpie # https://github.com/jkbrzt/httpie $ brew install jq # https://stedolan.github.io/jq/ $ brew install leiningen # http://leiningen.org/ $ brew install markdown # http://daringfireball.net/projects/markdown/ $ brew install pandoc # http://pandoc.org/ $ brew install task # http://taskwarrior.org/ $ brew install the_platinum_searcher # https://github.com/monochromegane/the_platinum_searcher $ brew install tldr # http://tldr-pages.github.io/launchctl / lunchy
build
locatedatabase:$ lunchy install /System/Library/LaunchDaemons/com.apple.locate.plist $ lunchy start com.apple.locate.plistCreate plist to periodically run
brew update(replace<username>below):<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.<username>.brew-update</string> <key>ProgramArguments</key> <array> <string>/usr/local/bin/brew</string> <string>update</string> </array> <key>StartCalendarInterval</key> <dict> <key>Hour</key> <integer>2</integer> <key>Minute</key> <integer>0</integer> </dict> <key>RunAtLoad</key> <true /> </dict> </plist>And start it:
$ lunchy start ~/Library/LaunchAgents/com.<username>.brew-update.plistGit configuration
$ git config --global user.name '<your-proper-name>' $ git config --global user.email <email-address> $ git config --global core.editor 'vim'Spacemacs
http://spacemacs.org/
$ brew install --with-cocoa emacs $ ln -s /usr/local/Cellar/emacs/24.5/Emacs.app /Applications $ git clone https://github.com/syl20bnr/spacemacs ~/.emacs.d $ git clone https://github.com/bi1yeu/dotfiles $ cd ~/dotfiles/ && ./link-dotfiles.sh $ emacs --daemon && emacsclient -c &Bash prompt
$ brew install bash-git-promptAdd to
.bash_profile:if [ -f "$(brew --prefix)/opt/bash-git-prompt/share/gitprompt.sh" ]; then source "$(brew --prefix)/opt/bash-git-prompt/share/gitprompt.sh" fi GIT_PROMPT_ONLY_IN_REPO=1Link Google Account to iCal
Prefs
- Map Caps Lock key to Control modifier in Keyboard prefs
- Adjust key repeat in Keyboard prefs
- Enable Remote Login in Sharing prefs
- Prevent computer from sleeping automatically when the display is off in Energy Saver prefs
- Put display to sleep in Mission Control > Hot Corners prefs
Generate SSH key and add it to
ssh-agent$ ssh-keygen -t rsa -b 4096 -C "<email-address>" $ chmod 700 ~/.ssh && chmod 600 ~/.ssh/* $ eval "$(ssh-agent -s)" $ ssh-add ~/.ssh/id_rsaEdit iTerm2 settings to bind alt+arrow keys to move forward/backward
https://coderwall.com/p/h6yfda/use-and-to-jump-forwards-backwards-words-in-iterm-2-on-os-x