8 min read

Coding cheatsheet

Table of Contents

Here’s a load of quick snippets of easy-to-forget but often used commands, tricks and tips. It’s got useful info about git, Vim, Python and Perl.

#

Git

#

First commands

These are the things you need to do when using git on a new computer:

Terminal window
1
# Change username associated with commits
2
git config --global user.name "<USER>"
3
4
# Change email associated with commits
5
git config --global user.email <EMAIL>
6
7
# Cache uname and passwd for convenience (only on git >= 1.7.9)
8
git config --global credential.helper cache
9
10
# Push to current branch only by default
11
git config --global push.default current
12
13
# Tell git to use vim as text editor
14
git config --global core.editor vim
15
16
# Tell git to colour its output
17
git config --global color.ui true
#

Adding remote

Add remote repository:

Terminal window
1
git remote add origin https://github.com/username/repository.git

Then subsequently set local branch to track remote branch:

Terminal window
1
git branch --set-upstream master origin/<branch>
#

Setting up git submodules

Adding submodules in a git repository is as simple as editing the file .gitmodules in the root of the repository, with the following syntax:

{% comment %} I’m not sure what highlighter to use for this. If anyone knows a better one, do let me know. {% endcomment %}

1
[submodule "libfoo"]
2
path = include/foo
3
url = git://github.com/foo/libfoo.git
4
5
[submodule "libbar"]
6
path = include/bar
7
url = git://github.com/bar/libbar.git

Then a quick:

Terminal window
1
git submodule init
2
git submodule update
#

Updating git submodules

You might be tempted to think that updating all your submodules from their respective remotes is as simple as running git submodule update. But no, what that does is update the submodules to the version checked out in the remote of the root repo. What you need is to update the version of the submodules that is checked out by the root repo. Here’s how to do it, assuming your submodule is called subm:

Terminal window
1
# Change into your submodule directory
2
cd subm
3
4
# Pull from the submodule remote
5
git pull origin master # Or whatever remote/branch you're updating from
6
7
# Go back into the root repo directory
8
cd ..
9
10
# Check out the updated submodule
11
git commit -am "Update subm"

And you’re done! It can be a bit annoying for updating loads of subdirectories, so I’m working on a short script to do it all for you. I’ll update here once I finish it.

#

Git subsubmodules

If you’ve got nested submodules (i.e. a submodule within another submodule), then you need to do alter this slightly to update the nested submodules. As well as having each submodule within your submodule containing a [submodule "foobar"] within both your root .gitmodules and your submodule .gitmodules, you need to do the following from within the root repository to update all submodules and subsubmodules:

Terminal window
1
git submodule update --init --recursive
#

Vim

#

Vim functions

Here’s the syntax for declaring vim script functions:

1
functions MyFunction ()
2
do first thing
3
do second thing
4
endfunction

And you then call it in Vim with:

1
:call MyFunction()
#

Recognise custom filetypes

I’ve got moo.vim files in my ~/.vim/after/syntax and ~/.vim/after/ftplugin, for all moo files with extension .moo. To get Vim to recognise these .moo files and apply the Vim scripts associated therewith, I need to create a file called moo.vim in ~/.vim/ftdetect/, which contains the following:

1
au BufRead,BufNewFile *.moo set filetype=moo

Note: You may have to wipe your ~/.vim/view before Vim recognises old files as this new filetype.

#

Editing over scp

Vim comes with the ability to edit files remotely over scp. This can be achieved via:

1
vim scp://user@servername//path/to/file

However, trying to save gives the error:

1
E382: Cannot write, 'buftype' option is set

In fact, running set buftype? reveals that buftype is set to nofile, meaning the buffer cannot be saved to file. This can be bypassed by using :Nwrite from the netrw.vim that comes bundled with Vim 7.0:

1
:Nwrite
#

sshfs

To allow other non-root users to access a filesystem mounted over ssh, use:

Terminal window
1
sshfs -o allow_other user@servername:/path/to/content /path/to/local/mountpoint
#

Photoshop

Whilst I don’t generally like expensive proprietary software, particularly photoshop, given the importance of this small technique to my current project (on which I will write a full post soon), I felt it important to include how to mask parts of photos in Photoshop, ready to be imported into programs like PhotoScan (another piece of incredibly expensive proprietary software).

  1. Firstly, select the region you want to mask (or keep unmasked, whichever is easier). The w key switches between the Quick Selection and Magic Wand tools, both useful in their own rights.
  2. Next, in the “Channels” group, click “New channel” at the bottom of the group box. The image should now turn black.
  3. If you want to mask the selection, press <CMD><SHIFT>I to invert the selection and press <SHIFT><F5>; select “White” and press <CR>. If you want to mask everything apart from the selection, then simply press <SHIFT><F5>, select “White” and press <CR>
  4. Save the file as a format supporting alpha channels by pressing <CMD><SHIFT>S. For PhotoScan imports, TIFF is recommended. Tick the box called “Alpha Channels” and press <CR> twice to save.
  5. (optional) In PhotoScan, after loading the photos into the workspace with Workflow>Add photos/Add folder, click Tools>Import>Import masks…. Make sure that “Method” is set to “From Alpha” and click okay. The masked areas will then be darkened to indicate they are masked.

Bonus Tip: To import masks from one photo into another, simpler drag the channel onto the new photo.

Note that this is based on the ancient CS3 that’s installed on the Mac I’m currently using, and may not apply to newer versions.

#

Python

#

argparse

Skeleton argparse template:

1
# Import the library
2
import argparse
3
4
# Description of the program
5
parser = argparse.ArgumentParser(description="Short description of the Python program.")
6
7
# A compulsory positional argument
8
parser.add_argument("compulsory", help="Description of argument, what it does and what the options are.")
9
10
# A required normal argument
11
parser.add_argument("-o", "--option", required=True, help="Short description")
12
13
# An optional true/false argument
14
parser.add_argument("-v", "--verbose", action="store_true", help="Short description")
15
16
# Specifying the type
17
parser.add_argument("-f", "--float", type=float, help="Short description")
18
19
# Specifying the default value
20
parser.add_argument("-n", "--name", default="drew", help="Short description")
21
22
# Parse the arguments
23
args = parser.parse_args()
24
25
# Accessing the values of the arguments
26
myArgument = args.compulsory
27
myName = args.name
#

Replace ~ with home directory

This is just a fun little script that replaces ~ in a string with the path to the user directory, e.g. /home/drew. Useful for taking input and output filenames from input, and want people to be able to use their familiar tilde.

1
import re
2
import os
3
4
# Replace '~' in fname with path to user dir
5
fname = re.sub("~", os.environ['HOME'], fname)
#

Increase size of pyplot legend

Sometimes, the legend in matplotlib isn’t quite big enough. Increase it with:

1
plt.legend(loc="upper left", shadow=True, borderpad=1)
#

Fix spacing in pyplot multiplots

Every time I do a subplot in pyplot, I get annoyed at the spacing, and every time I forget that all you need to do is put the following in your script and it will automagically sort the spacing out for you:

1
plt.tight_layout()

Why is this not a standard part of matplotlib? I don’t know.

#

Change x or y ticks on pyplot plot

You can use either np.arange or specify the ticks yourself:

1
# Automatically generate ticks for x axis
2
plt.xticks(np.arange(min(x), max(x)+1, step))
3
4
# Manually specify ticks for y axis
5
plt.yticks([-1, 5.2, 9.0, 43, 109])
#

Set custom limits on pyplot plot

Here you can both retrieve and set the x and y limits with plt.xlim and plt.ylim:

1
plt.xlim() # Returns the current x axis limits
2
plt.ylim() # Returns the current y axis limits
3
4
plt.xlim(0, 127) # Sets the x axis limits
5
plt.ylim(159, 4) # Sets the y axis limits
#

Find the properties of an object

To find the properties of an object, you can do the following:

1
object.__dict__ # Works in some cases
2
dir(object) # Should work in all cases
3
4
# For example...
5
dir(__builtins__)
6
> ['ArithmeticError', 'AssertionError',
7
...
8
'upgrade', 'vars', 'xrange', 'zip']
9
10
__builtins__.__dict__
11
> {'bytearray': <type 'bytearray'>, 'IndexError': <type 'exceptions.IndexError'>,
12
> ...,
13
> 'OverflowError': <type 'exceptions.OverFlowError'>}
#

Perl

#

Pie

Probably the most useful thing that perl can do is perl -pi -e, often lovingly called Perl Pie. The syntax is:

Terminal window
1
perl -pi -e "s/string to find/string to replace/g" filenames

This replaces string to find with string to replace in filenames. This is fully regex compatible. For instance, if I wanted to replace mispelt with misspelt in all files ending in .txt, I would run:

Terminal window
1
perl -pi -e "s/mispelt/misspelt/g" *.txt