Download Files (Like PDFs) Open in Safari to the Current Finder Folder

I often click PDF links in Safari, and the PDF will open in that Safari window rather than downloading. This is ok with me. I don't like a bunch of files cluttering my ~/Downloads folder.

But when I do want to download one of these PDFs, there isn't an easy way to do it. There is no "Save As..." in the right click menu, and the HUD buttons at the bottom of the viewer are hard to reliably bring up.

Enter this Automator workflow, which I trigger with LaunchBar. It will download the file (PDF or otherwise) in the frontmost Safari window into the frontmost Finder window's folder, or to the Desktop if no Finder windows are open. Download it here.

List of Ruby's % operators

Compiled from this Stack Overflow answer, here is the list of Ruby’s very useful % operators:

  • %w() creates an array from space-delimited strings (a b c becomes [‘a’, ‘b’, ‘c’])
  • %r() is another way to write a regular expression
  • %q() is for single-quoted strings (so you can do %q(that's right) without escaping the '
  • %Q() is for double-quoted strings so you don't have to escape ", but can do interpolation (%Q(#{1+1}) => "2")
  • %x() is a shell command
  • %i() gives an array of symbols (Ruby >= 2.0.0)
  • %s() turns foo into a symbol (:foo)

How to Strip Photo Metadata in the Terminal with exiftool

If you want to strip metadata from photos (e.g., location data from your phone's GPS), there are a few ways to do it:

  • On iOS, I recommend Metapho.
  • On Mac, you can use the built-in Preview.app, and there are lots of apps in the App Store of dubious quality that do this.

There's another option for Mac if you want to use the Terminal: exiftool

You can get exiftool with brew install exiftool, and then you can use this command to strip all the metadata from a photo:

exiftool -all= /path/to/file.jpg

You can verify that it worked with exiftool -a /path/to/file.jpg | grep GPS. Try running this before and after the previous command, and you can see how the GPS info is removed.

I have added the following to my .zshrc file for quick access to these commands:

alias exifstrip='exiftool -all='

function exifgps(){
    exiftool -a "$1" | grep GPS
}

IPython Notebook Setup Code

I just posted the code I use at the top of every IPython notebook to GitHub: https://github.com/masnick/ipython-setup

It was somewhat difficult to figure out what to import (and the conventions for this) when starting with IPython. This setup file takes care of that.

It also has some additional goodies like my code toggle button and my method to display raw HTML inline in the notebook.

In any case, I recommend standardizing the contents of the first cell in IPython notebooks, saving this out to a file, and then using %load magic to bootstrap the first cell. (This is explained in more detail in the GitHub link above.)

SciPy: Using GridSpec to Display Box Plots Under Histograms

Here's how to get output like this using matplotlib and its GridSpec class:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gs

%matplotlib inline

df = pd.DataFrame([
        np.random.randn(1000),
        np.random.random_integers(1, 2, 1000)
    ]).T
df.columns = ["value", "group"]


fig = plt.figure(figsize=(10, 6))
grid = gs.GridSpec(2, 2, height_ratios=[3, 1]) 
for i, g in enumerate([1, 2]):
    
    subset = df['value'][df['group'] == g]
    
    # Histogram
    ax = plt.subplot(grid[i])
    ax.hist(list(subset), color='k', alpha=0.4)
    ax.set_title("Group %s" % g)
    
    # Box plot
    ax2 = plt.subplot(grid[i+2])
    pd.DataFrame(subset).boxplot(vert=False, return_type='axes')
    ax2.set_yticklabels([''])

fig.tight_layout()
fig.subplots_adjust(top=0.85)
fig.suptitle('Example', fontsize=20)

None # Don't display the last thing -- `%matplotlib inline` will display the graphs no matter what.


It looks like Gist embed is broken here on PostHaven for IPython notebooks, so the embed below may look strange:

Installing Python 3 Alongside Python 2 on OS X (Yosemite)

This was actually pretty easy. Here’s what I did:

  1. Opened a new Terminal window that wasn’t in a virtualenv.
  2. Ran brew update
  3. Ran brew install python3
  4. cd ~/.virtualenvs (the folder where my virtualenvs are)
  5. virtualenv -p `which python3` data3 to create a new virtualenv using Python 3
  6. workon data3 (this is from virtualenvwrapper)
  7. pip install "ipython[all]"

Update: I've been trying out pyenv, which is forked from my much-beloved rbenv. It seems to work fine with virtualenv via pyenv-virtualenv, but I could not get pyenv-virtualenvwrapper to work. I'm using this now to run an updated version of Python 2 without messing with my system Python, and it seems to work fine.

IPython and Jupyter Notebooks: Automatically Export .py and .html

[Updated 2016-03-04 to support Jupyter 4 notebooks – see below.]

IPython notebooks are stored in a format that is not particularly human-readable and doesn’t work well in version control.

One way to solve this problem is to automatically export the code from IPython notebooks into a vanilla Python file after each save.

It’s also useful to automatically generate a HTML file of the notebook on each save. This can be done manually in Jupyter (File > Download as > HTML), but if you always want this, doing it automatically is much easier.

Use the following code to automatically save a .py and a .html file when you save a notebook in Jupyter. These two files will be saved in the same folder as the parent .ipynb file.

First, run ipython locate profile default, which will give you the path to save the following code in.

Save the code below in this folder as ipython_notebook_config.py:

Now, run ipython notebook. You will see an error message in the terminal if there are any syntax or runtime errors with ipython_notebook_config.py. If everything looks good, go to your web browser, open a notebook, and click the Save/Checkpoint button (it’s the floppy disk icon in the Jupyter toolbar). You should see a .py and a .html file appear alongside your .ipynb file.

Update for Jupyter 4 notebooks

After the big split between IPython and Jupyter, and the accompanying update to Jupyter 4.x, the config file above no longer works. Instead, put the following in a file saved at ~/.jupyter/jupyter_notebook_config.py to achieve the same thing:

This code could be DRYer, but it does work.