Week 33: AWK

This week’s post is about a language/tool that I’ve been wanting to learn for some time: AWK. AWK (or awk) is a UNIX command-line tool that comes with its own interpreted language for text manipulation and analysis, and it should be useful in whipping up all kinds of script-fu. Let’s get started, shall we?

According to Wikipedia

awk programs consist of “a series of pattern-action pairs”. In other words, ack programs consist of chained statements of the form

1
condition {action}

When analyzing a file, awk first breaks it up into “records” (lines), and then processes each line sequentially, evaluating each action whose condition is true for the current line. Additionally, the BEGIN and END conditions cause their respective actions to be evaluated before or after the file is analyzed, and pattern1, pattern2 matches every record starting with the one that matches pattern1 up to the one that matches pattern2.

It is worth noting that either the condition or the action can be blank, in which case condition defaults to matching everything, and action defaults to printing the line.

The awk language has a full suite of standard functions, like arithmetic, printing, writing files (using the UNIX > syntax), piping, functions, regexps, and much more. I won’t get into a whole lot of detail here, and instead will point interested parties to some helpful resources.

With that out of the way, it’s time for the main event.

Start the music!

This week’s program is going to be an awk script to read a file and play Morse code based on it’s contents. Lines starting with a “–” or the word “dit” will be dits, lines starting with a “_” or the word “dah” will be dahs, and blank lines will be character breaks. Here we go.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function dit() {
  print "\a"
  system("sleep 0.2")
}

function dah() {
  print "\a"
  system("sleep 0.5")
}

function char_break() {
  system("sleep 0.5")
}

/^(-|dit)/ { dit()        }
/^(_|dah)/ { dah()        }
/^$/       { char_break() }

I’ve fine-tuned the timings to sound right to my inexperienced ear, but forgive me if they are not spot-on.

You can run this program by saving it as morse_parser.awk, saving the morse you want to play in morse.txt, and running awk -f morse_parser.awk morse.txt. Thanks for reading, and I’ll see you next week.

Week 32: C

This week’s language is C. A tab staid, I know, but I’ll do my best to keep it from being too boring.

“How?”, I hear you ask

Funny you should ask that.

<INCEPTION NOISE>

DUHNNNNNNNNNNNNNNNNNNNNN

I could write something like a really fast sort, because this is C, and C is fast. But that brings us to the problem of really fast C code being not that interesting to write about (unless I start getting really passionate about pointers… you never know). To remedy this malady1, I’m going to avoid the problem entirely by writing some code in Ruby.

1
2
3
4
5
6
7
8
9
class NotBoring
    def doSomethingInteresting
        puts "Knock Knock"
        puts "Who's there?"
        puts "Boo"
        puts "Boo who?"
        puts "Don't cry"
    end
end

And now to write the same exact code in C!

Ruby, at its base, is implemented in C and therefore allows you to write extensions in pure C. Here we go (in the file notboring.c):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "ruby.h"

static VALUE not_boring_class; // VALUE is the data type for a ruby object

static void doSomethingInteresting() {
  printf("Knock Knock\n");
  printf("Who's there?\n");
  printf("Boo\n");
  printf("Boo who?\n");
  printf("Don't cry\n");
}

void Init_notboring() {
  not_boring_class = rb_define_class("NotBoring", rb_cObject); // Defines a ruby class that inherits from Object
  rb_define_method(not_boring_class, "doSomethingInteresting", doSomethingInteresting, 0); // Defines a ruby method for the class NotBoring called doSomethingInteresting that will evaluate the given function with 0 arguments
}

The C code needs some supporting ruby to build a Makefile (this goes in extconf.rb)

1
2
require 'mkmf'
create_makefile('notboring')

That’s it! Now just run ruby extconf.rb and make and you’re ready to fire up irb, run require './notboring and play around with the new class, knowing that it’ll be extra speedy due to C’s hefty natural advantage.


  1. Heyoo!

Week 31: SCSS

Hi there. I know there haven’t been any posts in a while, but that’s not because I haven’t been coding. In fact, I have a backlog of languages to write about. Let’s get started.

I don’t need any SASS

First, a little history:

In the beginning, there was HTML, And it was pretty boring.

So some people said, “Let there be CSS”.

And there was CSS, And things were suddenly not so boring.

But some other people said, “This is still kind of boring.” “Let there be variables and loops and things.”

And there were variables and loops and things, And things were even less boring, And it was called SASS.

BUT THEN the first group of people said, “Hold the phone. SASS syntax is not a strict superset of the existing CSS standard!”

And the second group said, “Alright, let there be curly brackets and semicolons.”

And there were curly brackets and semicolons, And it was called SCSS, And things were slightly more boring, But it’s the standard now, so live with it.

How’s that for a creation story?

Variables and Loops and things

My adventure in the land of SCSS comes in the form of a Rails app, using Bourbon Neat with a dash of Bitters as the frontend framework. To decrypt that last bit, Bourbon is a SCSS mixin library that turns your stylesheet’s awesome factor up to 11, Neat is a SCSS grid framework, and Bitters is a scaffold for your stylesheets (all three are maintained by Thoughtbot).

You can see the results at http://corresponder.herokuapp.com/

P.S. Shout out for my new favorite serif font: Bitter (the similarity to the frontend framework is coincidental).

The meat of the code can be seen in letters.css.scss:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$letter-columns: 8;

.wrapper {
  @include outer-container;

  @include pad(0 0 20 0);

  .headings {
      @include span-columns(4);
      @include shift(2);
      @include omega;
  }

  .letters {
    @include span-columns($letter-columns);
    @include shift(2);
    
    $half: $letter-columns / 2;
    .letter {
      @include span-columns($half of $letter-columns);
    }

    .your-letter {
      @include span-columns($half of $letter-columns);
    }
  }
}

Represented here are some of the things that make SCSS awesome.

  • Variables like $letter-columns make your code much more DRY.
  • Mixins like @include span-columns(4) do the same thing by allowing you to give inheritance-like behaviors to your styles.
  • Nesting makes your code more expressive (see below).

Without nesting, your stylesheets might look like this:

1
2
3
4
5
6
7
8
9
10
11
div.main {
    // Some stuff
}

div.main a {
    // Styles for child anchor
}

div.main a:hover {
    // Blah blah blah
}

With nesting, that becomes:

1
2
3
4
5
6
7
8
9
10
11
div.main {
    // Some stuff

    a {
        // Styles for child anchor

        &:hover {
            // Blah blah blah
        }
    }
}

Pretty cool.

That’s it for now. Watch out for the next installment!

Week 30: Smalltalk

Hi all! This week’s going to be short (and I really mean it this time).

tl;dr: Smalltalk

Smalltalk. The link’s right there in case you want to look it up. I’m a little pressed for time, so I’m going to get right to the program.

The Program

Smalltalk’s shtick is the “message” construct. Messages are like methods in that they are sent to receivers, and the receivers can respond with an answer (a return value). As in Objective-C (my first language, one that inherited a lot from Smalltalk), in Smalltalk messages can have keywords interspersed with arguments, which can lead to more readable code. For example, instead of something like Rectangle.new(100, 100) you could write Rectangle width: 100 height: 200.

Well, you know what they say: if it’s worth doing, it’s worth overdoing :P.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Object subclass: Rambler [
  Rambler class [
    so:something walksInto:aPlace andThe:person looksUpAndSays:thePunchline [
      'Let me tell you a joke' printNl.
      ('So, ',something,' walks into ',aPlace) printNl.
      ('And the ',person,' looks up and says, "',thePunchline, '"') printNl.
      '' printNl.
      'Can you believe that?' printNl.
    ]
  ]
]

Rambler so: 'a guy' walksInto: 'a bar' andThe: 'bartender' looksUpAndSays: 'Stop telling these stupid jokes'.
'===================================' printNl.
Rambler so: 'an alien' walksInto: 'a space station' andThe: 'bartender' looksUpAndSays: 'Why is there a bartender on a space station?'.

And one more thing

Before I wrap up this post, I just want to comment on how nice the multiple keyword message syntax makes things look. For example, if x is an array, x at:1 put: 1337 inserts 1337 at index 1 of array x. Isn’t that nice? OK, I’m done now.

KTHXBAI.

P.S. The docs aren’t great. I had to google for a long time just to find a complete example of a GNU Smalltalk class declaration

Week 29: D

Wow. I said before that I was going to catch up, but this time I really mean it. Really.

However, this catching up business means that I’m going to be doing these posts more quickly, trying to get to the actual weekly program a lot sooner. I’m only a week behind schedule, so I should be back up to date soon.

With that in mind, I give you this week’s language:

D

See what I did there? Even the name is short. The amount of time I saved by only having to type D as opposed to something longer like C# or even (heaven forbid) C++ is immense. That’s efficiency for you.

Anyway…

D is a C-like language that draws mainly from C++, but is, as one tutorial puts it like ‘C++ done right’. Not being a C++ programmer, I wouldn’t know. Even so, as a mainly interpreted language type of guy, more at home with Ruby than C, one of D’s main tenets, convenience, is pretty attractive. For instance, even though D is technically a compiled language, it includes a tool (rdmd) that compiles and runs all in one go, which is nice.

As a language, D promises “modern convenience”, “modeling power”, and “native efficiency”, which sounds a little bit too much like trying to be all things to all people. You can also see this in the tutorial I linked to above, in which the author provides introductions for programmers coming from languages from C to Java to Go to Clojure to Node.js, for a total of 9 different categories (one of which if aimed at 5 different languages). Swiss army knives are nice and all, but sometimes you need a dedicated screwdriver.

But lets see what the swiss army knife can do…

Here is what I’ve come up with in D: a binary search algorithm.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import std.stdio;

void main() {
  // One of D's differences from C are built-in dynamic arrays
  // These arrays are bounds checked and you can change their size on the fly
  int[] array;
  array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; // Pre-sorted, as I didn't want to "cheat" by using the built in sort,
                                       // which comes in the same library as the built in search

  // Read in the target
  write("What number are you looking for? ");
  int target;
  readf("%s", &target);

  int i = search(array, target);

  if (i != -1) {
    write("Target found at index: ");
    writeln(i);
  } else {
    writeln("Target not found");
  }
}

int search(int[] a, int target) {
  int i = cast(int)a.length / 2;

  // Base case: if the element does not exist in the array, then the search
  // is over once the array shrinks to length 0
  if (a.length == 0) {
    return -1;
  }

  if (a[i] == target) {
    return i;
  } else if (a[i] > target) {
    int next_i = search(a[0..i], target); // Array slicing

    // If subsequent recursions cannot find the target, return -1
    if (next_i == -1) {
      return -1;
    }

    return next_i;
  } else {
    int next_i = search(a[(i+1)..a.length], target);

    // If subsequent recursions cannot find the target, return -1
    if (next_i == -1) {
      return -1;
    }

    return (i + 1) + next_i;
  }
}

Week 28: Bash

>> for i in $(seq 1 10); do echo "BASH" | say; done;

That’s right. This week’s post is about Bash, and for once started with a project I was actually working on outside of my little endeavor here and thought might make a good post.

Where did I put my hammer?

You all know Bash, or at least you should), so I’ll keep my introduction to the language short and sweet.

There’s only one thing you really need to know about bash (or any other shell language, for that matter), and that is the concept of pipes. Pipes (the ‘|’ character) take the output from one command and “pipe” it as input to the next command. For instance, echo "hello" would normally print “hello” to STDOUT, but you can take that output and pipe it anywhere you want. You can pipe it to something silly like say (as I did at the start of this article) or something a little more practical, like bc (a decimal calculator).

To take full advantage of the UNIX environment, you need to understand how you can take a series of small commands and piece them together to get what you want. For instance, when I start a create post with rake new_post['Title'], octopress generates TIMESTAMP-Title.markdown. To open the new post up in Sublime Text, I can run ls -1 | tail -1 | xargs subl -n, which is 3 commands (technically 4 because of xargs) joined together with the pipe.

  • ls -1 prints the contents of the current directory (the ls command) and formats the output to one file per line (the -1 option).
  • tail -1 takes the last 1 line of input and outputs it by itself. If I didn’t include this, Sublime would open every file and directory provided by ls.
  • xargs is a special command that takes another command as its first argument and passes that command the input it receives from the pipeline. It’s generally used as a wrapper for commands that don’t handle pipes so well, but it has a whole range of more powerful formatting capabilities.
  • subl -n opens the file in Sublime in a new window (the -n option)

That’s the gist of it, and if you want to learn more, well here you go).

tl;dr Use | and people will marvel at your command line ninja skills.

Moving on…

Here’s this week’s program. I was inspired by this guy’s termal setup, especially the battery level indicator, but the python script he had started crying about encodings the minute I fired it up, so I decided to roll my own in pure bash, with pretty decent results. For reference, my current setup is iTerm2 with the LiquidCarbonTransparent color scheme, Inconsolata font, Bashstrap, and this hack, and it looks a little something like this:

And here’s how (also on GitHub):

~/bin/battery.bash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash

# I added this on to the PS1 from bashstrap (https://github.com/barryclark/bashstrap)
# but you can put it wherever you want

# Get the current capacity of your battery
CAPACITY=$(ioreg -n AppleSmartBattery -r |
            awk '/\"CurrentCapacity\" = ([0-9]*)/ { print $3 }')

# Get the maximum capacity of your battery
MAX_CAPACITY=$(ioreg -n AppleSmartBattery -r |
                awk '/\"MaxCapacity\" = ([0-9]*)/ { print $3 }')

# Battery percentage is CAPACITY / MAX_CAPACITY * 100%, but we only need the fraction
# (Hack to do floating point math: delegate out to bc)
# (scale=5 gives 5 decimal places of precision)
BATTERY_FRAC=$(echo "scale=5; $CAPACITY/$MAX_CAPACITY" | bc)
BATTERY_FRAC=$(printf "%.1f" "$BATTERY_FRAC") # Round to nearest 10th

MAX_NUM_BARS=10
BAR_SYM="▮" # Set this to whatever you want. Go nuts

# Construct bar graph
BATTERY_STRING=""
NUM_BARS=$(echo "scale=0; $BATTERY_FRAC*($MAX_NUM_BARS - 1) + 1" | bc) # scale=0 forces integer output
for i in `seq 1 $NUM_BARS`; do
  BATTERY_STRING="$BATTERY_STRING$BAR_SYM" # Concatenate another bar onto the string
done

# Append padding characters to make sure BATTERY_STRING has constant width
PADDING_NEEDED=$(echo "scale=0; $MAX_NUM_BARS - $NUM_BARS" | bc)
for i in `seq 0 $PADDING_NEEDED`; do
  BATTERY_STRING="$BATTERY_STRING "
done

# Save this file to ~/bin/battery.bash and run "chmod 755 ~/bin/battery.bash"
# See ./.bash_profile.example for details on how to build this script into you're prompt.

And here’s an example ~/.bash_profile to go with it (without full bashstrap integration, which is left as an exercise for the reader :D).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Battery bar graph
source ~/bin/battery.bash

# Colorize BATTERY_STRING appropriately
# Under 20% => magenta
# Under 40% => orange
# Under 80% => green
# Otherwise => bright green
if [[ $(echo "$BATTERY_FRAC < 0.20" | bc) = 1 ]]; then
  BATTERY_STRING="$(tput setaf 1)$BATTERY_STRING$(tput sgr0)";
elif [[ $(echo "$BATTERY_FRAC < 0.40" | bc) = 1 ]]; then
  BATTERY_STRING="$(tput setaf 3)$BATTERY_STRING$(tput sgr0)";
elif [[ $(echo "$BATTERY_FRAC < 0.80" | bc) = 1 ]]; then
  BATTERY_STRING="$(tput setaf 2)$BATTERY_STRING$(tput sgr0)";
else
  BATTERY_STRING="$(tput setaf 120)$BATTERY_STRING$(tput sgr0)";
fi

SYMBOL=">>" # Change this to be whatever you want your prompt to be (traditionally $)

PS1=$BATTERY_STRING$SYMBOL

Normally I’d love nothing more than to spend several minutes explaining some dense bash code to you, but it’s late, so I’ll just tell you that the secret sauce comes from ioreg -n AppleSmartBattery -r, which prints out a whole ton of “useful” information about the battery (and presumably other subsystems, hmmmm…). The code is relatively well commented, so I’ll let it speak for itself.

TL;DR To gain ninja-like bash skills, use | and google the fiddly bits in between.

Week 27: APL

It would seem that I have fallen ever so slightly behind schedule. Wolfram tells me that it is already week 28, but yet above THIS VERY POST you can very plainly see the words ‘Week 27’, and for this I am sorry. To remedy this GRIEVOUS ERROR, this weekend I shall dedicate myself to producing not one BUT TWO posts, one on D (to be produced on the morrow) and one on…

APL!

“What is this ‘APL’?”, I hear you ask. “That’s just a meaningless acronym, little more than a pseudo-random sampling of letters!”

You’d be right. According to Wikipedia), “APL” is named after a book remembered by many for its specificity: “A Programming Language”. Notice the lack of a definite article in that title. There is no “the”, as in the apocryphal “The C Programming Language”. Just “a”. They could have just called it “Some Programming Language”, or “This Programming Language”. Anyway…

So What is APL? Besides A Programming Language

Again according to WikipediaCitation needed), APL is a language “typically structured as chains of monadic or dyadic functions and operators acting on arrays”. As this quite honestly speaks for itself, no further explanation is needed here. Let’s move on, shall we?

Wait, what?

OK. So you remember foldl from Haskell? inject from Ruby? map from Python? APL is basically all like that. Operations on arrays (and sometimes matrices, which are just arrays with pretensions).

Also, APL uses a keyboard that looks like this:

Awesome sauce.

So what do squiggly characters and funny acronyms get us?

Quite a lot, actually. The, ahem, squigglyness of APLs commands allow us to be remarkably concise in our statements. In APL, m ← +/ιn (that’s an ‘iota’ before the n there) is equivalent to the following C (not counting boilerplate, which I’m not sure I remember off the top of my head):

1
2
3
4
int m = 0;
for (int i = 0; i < n; i++) {
  m += i;
}

Technically, that C should build an array [1, 2, 3, …, n] and then iterate over that array to find its sum, but I think I’ve made my point. (P.S. if you want to try out some APL for yourself, look here for an online interpreter, replete with on-screen keyboard for typing the aforementioned squiggly characters.)

And that whirlwind introduction brings us to my program for this week (last week, really, but who’s counting?). In honor of APLs lovely squiggles, the only criteria I used for constructing this week’s program is to use the squiggliest operators I can (see here for a complete list of relevant squiggles).

Here goes:

1
2
3
a ← ⍳10 # => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b ← ⍳20 # => [0, 1, 2, 3, ... , 17, 18, 19]
a ∊ b # There's a good squiggle, returns an array with a 1 for every element of b in a

Output: 1 1 1 1 1 1 1 1 1 1

Sorry if that example was a little lackluster, but a) I have a lot to do this weekend and b) I’m too tired to review matix math. See you next time!

Week 26: Io

I’ve been a little busy with work, so these posts seem to be doomed to get gradually smaller and smaller….

Anyway, this week we have Io! I won’t waste any time here, and just jump right into the code (with my commentary in the comments).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
a := "Hello," // ':=' is used for first time assignments
b := "world!"

b = " world!\n" // '=' is used for reassignments

writeln(a, b)

greet := method( // Kind of a javascript-y way to declare functions...
  writeln("What is your name?")
  you := File.standardInput readLine
  writeln 
)

// This next bit is a bit weird...
myObj := Object clone // Creates a new object
myObj name := "Gerald" // Add an instance variable
myObj say_name := method(writeln("Hi, I'm ", self name)) // Add another instance variable that happens to be a method

// This is where it gets wierd
myClass := myObj clone
myInstance1 := myClass clone
myInstance1 name = "Howard" // Why no ':='? You'll see...
myObj say_name // =>"Hi, I'm Howard" (GASP!). This is not a class! This is the same object called by a different name!

myObj name = "Gerald" // Fix this grievous mistake
myClass init := method(self name := "Reginald") // THIS makes myClass into a class
myInstance1 = myClass clone
myInstance1 name = "Howard"
myInstance2 = myClass clone
myInstance2 name = "Cynthia"
myInstance3 = myClass clone

myObj say_name // => "Hi, I'm Gerald"
myInstance1 say_name // => "Hi, I'm Howard"
myInstance2 say_name // => "Hi, I'm Cynthia"
myInstance3 say_name // => "Hi, I'm Reginald"

That class/object stuff is kinda weird, which means that at least it’s interesting. See you next time, and thanks for reading!

Week 25: Perl

Here’s another quick post for you (hopefully some properly original coding should make up for it this week). This week’s language is Perl, but the whole time I was reading through the tutorial, all I could think is, “Wow, this really looks an awful lot like Ruby…”

And it does

Aside from some cool/interesting deviations, which I’ll outline here.

First of all, Perl uses sigils like “$”, “@”, and “%” to prefix the variable names of scalars (numbers, strings, etc.), lists, and hashes respectively. This is kind of cool, as it allows the easy type inference of Ruby while still encouraging some semblance of type safety.

Perl also wins the prize for best way to open a file:

1
open(FILE, "test.txt") or die "AAAAAAAAAAAAAAAH!"

Open that file, or DIE!!!!!! MWAAHAHAHAHAHAHAHA!!

Anyway…

My code

<<WARNING: Minor rant ahead>

One of my pet peeves is when I’m forced to (in every English or History class ever) write my commas and periods inside the quotations. AAAAAARGH! It’s a relic from the age of printing presses, but just like so many other relics (COUGH COUGH IMPERIAL UNITS COUGH COUGH) that the ENTIRE REST OF THE WORLD has stopped using, the U.S. continues to be set in its ways. To remedy this, here is a Perl script that uses the language’s baked-in regex support to move all commas and periods outside the double quotes they so erroneously appear to the left of.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/perl
use strict;
use warnings;

# USAGE: the_right_way.pl INFILE OUTFILE

my $infilename = $ARGV[0];
my $outfilename = $ARGV[1];

open (INFILE, "< $infilename") or die "Could not read input file!";
my $text_to_fix = <INFILE>;
$text_to_fix =~ s/,"/',/g;
$text_to_fix =~ s/\."/"\./g;
my $fixed_text = $text_to_fix; # Don't want our variable names to be misleading
close INFILE;

open (OUTFILE, "> $outfilename") or die "Could not open output file!";
print OUTFILE $fixed_text;
close OUTFILE;

The usage is ./fix_punctuation_inside_quotes.pl INFILE OUTFILE (assuming the file is executable, of course).

Sure enough, when tested with:

1
Some good words are "octothorpe," "fungible," and "effervescent."

The script output:

1
Some good words are "octothorpe', "fungible', and "effervescent".

Thanks for reading! See you next week (hopefully).

Week 24: Python

I have very little time this week, and this is a make-up post for the last week, when I was on a trip, so in the immortal words of xkcd

Here have code

The project (written before the challenge started) is documented on github here, so I’ll just provide the source code here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import sublime, sublime_plugin, random, string

class InstigateCommand(sublime_plugin.TextCommand):

  def run(self, edit):
    print "A shot across the bows! Instigate.py strikes again!"

    # Get tne first selection, and check if a) it exists and b) it's on
    #   at least the 6th line (to give you a head start)
    current_sel = self.view.sel()[0]
    current_rowcol = self.view.rowcol(current_sel.begin())

    if current_rowcol[0] >= 5:
      offset = random.randint(10, current_sel.begin() - 10)
      to_replace_region = sublime.Region(current_sel.begin() - offset, 
        current_sel.begin() - offset + 1)
      new_char = random.choice(string.letters)

      self.view.replace(edit, to_replace_region, new_char)

    # IMPORTANT: whatever key you bind this command to (i.e. enter, '.', ';', etc)
    #   will not actually be entered after this command is run. To remedy this, you
    #   need to type the bound character at the end of the command
    self.view.insert(edit, current_sel.begin(), '\n')


# To be evil, and install this in your friend's Sublime Text, add the following line to
#   Default.sublime-keymap:
#       
#       { "keys": ["enter"], "command": "instigate" }

This week’s post will be up sometime tomorrow.