Monday, March 28, 2011

Driven by the pursuit of proficiency

velocity

I am looking for a job, and as this is only the third time in my life job hunting, I have sought advice anywhere I can get it. Like most universities, Virginia Tech has a Career Services office, so I consulted their website to help get things rolling. They suggest beginning with a self-assessment, and the very first item of this self assessment bluntly asks, "What do you want to achieve in your work?" While this question is frustratingly broad, it is fair game; one could expect such a question in an interview, and one certainly must have an answer ready.

I have never felt guided by some vision of how my life should be. I mean, sure, when I was 8, I wanted to fly an F-14 Tomcat and shoot down commie MiGs because that made you a hero, and when I was 13, I wanted to be a Marine Biologist because of National Geographic and NOVA PBS shows, and when I was 18 I wanted to be a physician because that's what all biology majors intend to be. Each one of those were fantasies—spurious projections of the possible me, based on the immature and incomplete value system I held at the moment. When I gave up on the gauntlet of medical school my junior year at UGA, I also gave up pretending I could calculate long term career trajectories. Despite blowing off this central tenant of many a cookie-cutter career book and commencement address, I've thus far avoided becoming a complete and utter catastrophe of a human being, so I continue to make without.

Now I'm a grad student in computational biology—the result of a few simple ingredients: 1) I've enjoyed computer programming since high school, and 2) I've found biology fascinating since the days of reading Zoobooks at the dinner table. I have also loved video games since grade school, but I didn't take the career path of a video game programmer because I didn't feel like I would make a substantial contribution to humankind. In contrast, I quit trying to become a physician—a career in which I would have had a direct and tangible impact on other people's lives—because I saw the competition was better than I was at jumping through the med school application hoops. (I also love playing guitar, but let's be realistic—although I've re-evaluated that option and there are worse things.)

According to motivational speaker Dan Pink, motivation boils down to three needs: mastery, autonomy, and purpose (video below if you are unfamiliar with Pink's theory). From that standpoint, I didn't feel a sense of mastery in my quest to become a physician, and I didn't feel a sense of purpose in my pursuit of game programming, but with a decent grasp of biology and a propensity for programming, computational biology seemed a good fit. Now the question stands, has it been?

From the standpoint of fulfilling the need for purposeful work, I have to say I have certainly experienced a boost in motivation after switching research groups, due in large part to shifting the biological subject from bacteria to in vitro liver tissue culture systems, which has more immediate implications for human health—a subject which still motivates me.

Considering proficiency, though, I feel very uncertain about my path in research. My RSS feeds continue to fill up with table-of-contents from journals faster than I can screen them for interesting abstracts. Also, although I don't reading through literature in the field as much as before, I still just dislike doing it. I think this indicates a major obstacle to a career in research because it breaks the virtuous cycle of positive feedback: what we like, we do more of, so we get better at it, which makes us like it more and do more of it, which makes us better at it, and so on.

It's not clear I've grown much as a presenter, either, though it's not for lack of opportunities. I've given at least one presentation a month, sometimes several, mostly to my two research groups, but with some conference and departmental talks, as well. While I've gotten better at recognizing the work pattern that goes into preparing a presentation, I don't feel I've been able to reduce the time it takes to prepare them, and while I feel I've improved in delivery technique, I feel disappointed at how little I've improved given the amount of time I've invested. This said, I have discovered I enjoy delivering a presentation for which I've prepared adequately, which I attribute to the performance aspect.

If we take a look at the most important currency in academia, publications, I'm far from flush, with one co-authorship on a book chapter, one second-authorship on a collaboration paper, and one first-authorship on an original research article (Open Access, yay!). I'm working on another paper currently, and should begin another one prior to defending in June. It's not a sparse record, but it's unremarkable. If I have learned anything from The Dip, it's that I want to do remarkable work.

I really want to become proficient, but after nine years of working in academic research from undergrad, to research tech, to grad student, I feel it's escaping me in this pursuit. My research experience feels like long periods of slogging, largely devoid of any feedback, let alone positive feedback (which is rare and fleeting). I want a research experience that breaks that mold, but I'm willing to accept I might not find one, and I'm becoming more enthusiastic about switching tracks to a career where I can make a genuine success of myself. I want that virtuous cycle of positive feedback. I want to get excited and make things!

So, to the future interviewer who asks, "What do you want to achieve in your work?" I answer this: "I want to achieve remarkable proficiency." Why settle for less? Life is short; let's find a way to become awesome while we still can.

Friday, January 7, 2011

Common Good: Adding a Creative Commons License button to your Blogspot (Blogger) blog

2500 Creative Commons Licenses

I have intended to place the contents of this blog under a Creative Commons (CC) license for a long while, especially given that all the attractive photos I love to use in these blog entries come from Creative Commons-licensed content on Flickr. For those unfamiliar with Creative Commons licenses, they explicitly permit re-use of creative works a priori. Provided you follow the criteria of the particular CC license of the work (usually simply attributing the original creator), you may simply use, or even modify the work, without the need to contact the original creator for direct permission to do so. Read the Creative Commons' website for more detail.

I had let this task linger far too long, so, spurred on by a recent email exchange with Mark Hahnel of Science 3.0, I finally felt the inspiration to get this done. Unfortunately, I didn't find the top-ranked pages in Google searches for placing a CC license button on Blogger/Blogspot blogs very helpful, so I decided to just figure it out. It turned out to be a simple process, so I documented it and present it here, in step-by-step format (all under the CC-BY license, of course):

  1. Go to the Creative Commons website and choose a license
  2. Copy the HTML that CC presents you after you've selected your license
  3. Go to your blog's page, and click the "Design" link in the navigation bar at the top. Alternatively, go to your Blogger author page and click the appropriate "Design" link for your blog there.
  4. Click the "Add a Gadget" link in the design editor (should be one at the bottom of the area).
  5. Click the link to add an "HTML/JavaScript" gadget.
  6. Add a title, like "CC License", paste the HTML of your license button that you copied from the CC website into the contents box, and click "Save".
  7. Optional: You'll be back at the design editor; double-click the new CC License gadget and move it below your Blog Posts gadget (or some other fitting area).

That's it! Your shiny new CC license button should appear where you placed it.

Tuesday, August 17, 2010

Cell on Wheels: Famous Scientist Roller Derby Names

Valtron 3000

This past Sunday I had an exciting first Roller Derby experience when I went out to support the NRV Rollergirls in their bout of against the Mason Dixon Roller Vixens. For those unfamiliar with modern roller derby, it is a contact, point-based sport in which the players of two teams skate in a circuit, trying to help their point-scorer, designated a "jammer", pass the other team, whilst simultaneously using any blunt part of their bodies above the knees to prevent the other team's jammer from passing them. The rest of the details you can pick up as you watch.

Today, roller derby is largely an all-women's sport, where men play supporting roles as coaches and referees, which is sort of an interesting role-reversal. My favorite part of the roller derby culture is that all participants don noms de guerre, which usually involve clever (or even tacky) wordplay, including the use of homophones, oronyms, and portmanteaus, to spin references to pop culture, history, or anything otherwise generally familiar, with a violent, aggressive bent. For example, my favorites for the NRV Rollergirls are Huck Finish Her and Eleanor Blows B. Dealt, but other good examples include Baby Ruthless and Bloody Holly from the enjoyable film "Whip It", or Hyper Lynx, Auntie Christ, Beyonsláy, and Nina Millimeter who have been appeared in various articles in the New York Times.

As I lay awake Monday, unable to sleep with anxieties about upcoming presentations, needing to develop an entirely different computational approaches for research, and general insecurities about my place in life, I started thinking about how amusing derby names are, and then tried inventing some of my own. Then I had a revelation that it would be hilarious if there were derby names based off of (relatively) famous scientists. Once I got a few, I started jotting them down. Here's a list of ones I've come up with, so far:

I would like to point out the obvious that these are all plays ot men's names, which is ironic given that roller derby is played predominantly by women. This is disheartening for three reasons:

  1. I could only come up with four "famous" female scientists offhand: Marie Curie, Jane Goodall, Rosalind Franklin, and Lynn Margulis.
  2. I couldn't come up with a clever spin on any of them.
  3. Did I mention I could come up with only four famous scientists who are women? This reflects poorly on me, but I think also on the inequality that exists in scientific education and scientific research, both of yesteryear but also today. This is another issue for another blog post.

If you have any suggestions for scientists I've missed (particularly famous women who are or were scientists), or better suggestions for the ones I've attempted to spin, I encourage you to post them in the comments, or put them in your own blog and post the link below.

Update 2011-05-17: Randall Munroe published a relevant comic on the final points on female scientists:

Thursday, January 21, 2010

Interactive sandboxes: using IPython with virtualenv

sandbox baby

A very helpful blog post on IPython and virtualenv by Pedro Algarvio inspired this one. The advice found there takes you 90% to where you want. I'll recap on that 90% but explain and give the extra 10%. I am indebted to Pedro for laying down all the hard work.

First of all, if you are unfamiliar with Ian Bicking's virtualenv package, you should know two things about it:

  1. virtualenv allows you to develop in sane, aseptic, "sandbox" development environments, switch between them seamlessly, and maintain harmonious order in your Python universe.
  2. virtualenv is certifiably awesome. Proceed directly to installing it (especially in combination with pip)! Do not pass Go! Do not collect $200!

Arthur Koziel already wrote a really good tutorial on using virtualenv, and, in fact, you'll probably find working with Doug Hellman's excellent virtualenvwrapper more convenient; in this case, Doug already wrote an excellent virtualenvwrapper tutorial, too. I've mentioned IPython in a previous blog post, so I won't cover that here, either. Instead, let's cut to the chase and get IPython and virtualenv playing well together.

Ordinarily, IPython, commonly installed system-wide by your preferred package management system, remains oblivious of an activated virtualenv environment, and will just mill about importing packages and modules from the system, rather than the sandbox. This gives two obvious solutions: either 1) configure the system installation of IPython to work with virtualenv, or 2) install IPython in each virtualenv environment. Doug Hellman wrote a nice tutorial on doing the latter approach; here, we'll focus on the former, which I prefer, since it means having to only install IPython once.

IPython (being a Python program) can read and execute Python scripts during launch; we'll use this mechanism to modify IPython's launch to hook into the virtualenv environment we're currently in. First, we'll tell IPython that we want to execute some code in a at startup. If we go to the $HOME/.ipython/ directory, we'll find a file called ipy_user_conf.py. Open the file in your editor of choice, locate the function main(), and at the within that function (I suggest at the end), insert the following line:

execf('~/.ipython/virtualenv.py')

Next, we need to create this file. Still in the $HOME/.ipython/ directory, create a new file called virtualenv.py and open it with your editor. Next, add these contents to this file:

import site
from os import environ
from os.path import join
import sys

if 'VIRTUAL_ENV' in environ:
    virtual_env = join(environ.get('VIRTUAL_ENV'),
                       'lib',
                       'python%d.%d' % sys.version_info[:2],
                       'site-packages')

    # Remember original sys.path.
    prev_sys_path = list(sys.path)
    site.addsitedir(virtual_env)

    # Reorder sys.path so new directories at the front.
    new_sys_path = []
    for item in list(sys.path):
        if item not in prev_sys_path:
            new_sys_path.append(item)
            sys.path.remove(item)
    sys.path[1:1] = new_sys_path

    print 'VIRTUAL_ENV ->', virtual_env
    del virtual_env

del site, environ, join, sys

If you took a look at Pedro's version of virtualenv.py, you'll recognize most of his code here. The important difference lies in the trickery we play with sys.path in lines 12 through 22. These lines were inspired by a solution to a problem presented by using site.addsitedir(), which adds new paths only to the end of sys.path.

Adding paths to the end of sys.path has, for our purposes, the undesirable side-effect of allowing system-wide packages and modules to preempt locally installed ones, since Python searches through sys.path for modules and packages in first-to-last order. I have filed a feature request for site.addsitedir() to allow inserting new paths at the beginning of sys.path; in the meantime, we'll use this hack inspired by the modwsgi programmers, which keeps track of the paths before and after the call to site.addsitedir(), then swaps the position of the new paths from the end, to just after the first element, '', which represents the current working directory (which should preempt every other path).

IPython will have access to the contents of the virtualenv sandbox in which you're currently working. For example, if I activate my networkx virtual environment, which has the latest development version of the NetworkX graph library, then fire up IPython, I get the following result (note the line that begins with VIRTUALENV indicating I'm accessing the virtualenv sandbox):

(networkx)$ ipython
VIRTUAL_ENV -> /home/lasher/.virtualenvs/networkx/lib/python2.6/site-packages
Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) 
Type "copyright", "credits" or "license" for more information.

IPython 0.9.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object'. ?object also works, ?? prints more.

In [1]: import networkx

In [2]: networkx.__version__
Out[2]: '1.1.dev1518'

When I leave the sandbox (e.g., by using virtualenvwapper's deactivate command), I return to accessing the system-wide default install of NetworkX:

$ ipython
/var/lib/python-support/python2.6/IPython/Magic.py:38: DeprecationWarning: the sets module is deprecated
  from sets import Set
Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) 
Type "copyright", "credits" or "license" for more information.

IPython 0.9.1 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object'. ?object also works, ?? prints more.

In [1]: import networkx

In [2]: networkx.__version__
Out[2]: '0.36'

So there you have it: one IPython to rule all your virtualenv sandboxes!

Friday, November 13, 2009

Time out: deterring brute force SSH attacks with iptables

Brute Force

These are some simple iptables rules I keep around on my firewall to deter brute force SSH attacks. The original idea came from Dominik Borkowski, a sysadmin at VBI.

If the attacker attempts more than 4 connections within a minute, these rules temporarily blacklist them for the next minute—or as I like to say, "put them in time-out". Their packets will be dropped; to them, it will seem that the machine simply disappeared from the intarwebs. The rules will also log such violators to your syslog. I've found them very effective. Most scripts that these crackers run will drop off after one iteration and look for lower hanging fruit.

Of course, if you forget your password, or have a habit of making a couple of simultaneous connections to your computer, the door will shut on you, too, but the good news is that you'll only be blocked for a minute. More draconian methods that append to actual blacklists have a habit of locking their owners out. (Not that I'm speaking from personal experience at all.) The rules escape this pitfall but will prove just as effective.

## Below includes very successful deterrents for SSH brute force
## that allows a maximum of 4 connection attempts within a minute.
iptables -A INPUT -p tcp -m state --state NEW --dport 22 -m recent --name sshattack --set
iptables -A INPUT -m recent --name sshattack --rcheck --seconds 60 --hitcount 4 -m limit --limit 4/minute -j LOG --log-prefix 'SSH attack: '
iptables -A INPUT -m recent --name sshattack --rcheck --seconds 60 --hitcount 4 -j DROP
iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT

I keep this in a firewall (shell) script that controls iptables rules and executes on bootup. If there's sufficient demand, I can make the entire script available.