If it won't be simple, it simply won't be. [Hire me, source code] by Miki Tebeka, CEO, 353Solutions

Friday, January 09, 2015

python -m

python -m lets you run modules as scripts. If your module is just one .py file it'll be executed (which usually means code under if __name__ == '__main__'). If your module is a directory, Python will look for __main__.py (next to __init__.py) and will run it.

One of Python's mottoes is "batteries included", and this goes for python -m as well. Here are some (all?) of the gems hidden in the standard library. Sadly not all of them have help, but I poked around in the source code to see the usage.

json.tool

This is by far the one I use most, it'll indent nicely an JSON input in the standard output and very helpful in combination with curl.
$ curl -sL http://j.mp/1IuxaLD
[{"x":1,"y":2},{"x":3,"y":4},{"x":5,"y":6}]
$ curl -sL http://j.mp/1IuxaLD | python -m json.tool
[
    {
        "x": 1,
        "y": 2
    },
    {
        "x": 3,
        "y": 4
    },
    {
        "x": 5,
        "y": 6
    }
]

zipfile

zipfile will let you view, extract and create zip files - very much like the zip and unzip. Here's the help:
$ python -m zipfile -h
Usage:
    zipfile.py -l zipfile.zip        # Show listing of a zipfile
    zipfile.py -t zipfile.zip        # Test if a zipfile is valid
    zipfile.py -e zipfile.zip target # Extract zipfile into target dir
    zipfile.py -c zipfile.zip src ... # Create zipfile from sources

gzip

Like zipfile, let's you compress and decompress .gz files, like gzip/gunzip. By default it'll compress a file but with -d will decompress.
python -m gzip wordlist.txt  # Will create wordlist.txt.gz
python -m gzip -d wordlist.txt.gz  # Will extract to wordlist.txt

filecmp

Compare two directories.
$ python -m filecmp /tmp/a /tmp/b
diff /tmp/a /tmp/b
Only in /tmp/a : ['1']
Only in /tmp/b : ['2']
Identical files : ['4']
Differing files : ['3']

Encode/Decode

Several modules lets you encode/decode in various formats:
  • base64
  • uu
  • encodings.rot_13
  • binhex
  • mimify
  • quopri
For example
$ echo 'secertpassword' | python -m encodings.rot_13
frpregcnffjbeq

Servers

There are several servers that you can run, the ones I know are SimpleHTTPServer, CGIHTTPServer and smtpd (mail). If you quickly want to serve some files from a directory on your machine, just run:
python -m SimpleHTTPServer

Clients

Modules that provide simple clients to various protocols are:
  • ftplib
  • poplib
  • nntplib
  • smtplib (on localhost only)
  • telnetlib
For example if you want to view Star Wars in text mode, do
$ python -m telnetlib towel.blinkenlights.nl

System Info

You can use platform to get some platform information (very much line uname -a) and locale to get locale information. Use mimetype to get the mime type of a file:
$ python -m mimetypes doc.html
type: text/html encoding: None

Python Utilties

  • compileall will compile all Python files to .pyc
  • dis will show bytecode for a file
  • pdb will start the Python debugger on a given file (see here)
  • pydoc will show documentation on a module/class/function
  • site will print some site information (sys.path, USER_BASE ...)
  • sysconfig will show many system related information (such as exec_prefix)
  • tabnanny will tell you of you mix tabs and spaces (like starting python with -t or -tt)
  • tokenize will print list of tokens in Python file
I mostly use pdb and pydoc, for example:
$ python -m pydoc os.remove
Help on built-in function remove in os:

os.remove = remove(...)
    remove(path)
    
    Remove a file (same as unlink(path)).

Profiling

There are several profiles and timers you can use from the command line:
  • cProfile - Show profile information
  • profile (use cProfile :)
  • timeit - Time how long things run
  • pstats - Print output of profiles
  • trace - Show tracing information on run
Example:
$ python -m cProfile match.py
         28537 function calls (27503 primitive calls) in 0.057 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.000    0.000 :1()
        1    0.000    0.000    0.000    0.000 :1(ArgInfo)
        1    0.000    0.000    0.000    0.000 :1(ArgSpec)
   ...

$ pyton -m timeit 'import math; math.factorial(100)'
100000 loops, best of 3: 12.9 usec per loop

timeit has good help from the command line.

IDLE

You can start IDLE by running python -m idlelib.idle

ensurepip

Python 2.7.9 and 3.x comes with an easy way to install pip. Run python -m ensurepip and pypi is at your service.


That's about it ... What are you favorite python -m tools? Which ones did I miss?

EDIT: The good folks at comp.lang.python reminded me a few I forgot:

unittest

python -m unittest discover will run unittest in discovery mode. Just drop a new Python file starting with test and it'll be picked up next time you run the tests. You can also specify a specific test to run with python -m unittest test_file.py TestClass.test_method.

calendar

python -m calendar will show calendar of the current year. You can also run python -m calendar YEAR to display a specific year and python -m calendar YEAR MONTH to display a specific month.

Easter Eggs

python -m this will display the Python Zen
python -m antigravity will open XKCD comic web page (which my company is named after).

Saturday, December 20, 2014

Quick View of matplotlib Styles

matploblit 1.4.2 added support for styles. I created a notebook to show how the ones bundled in look, you can view it here.

Wednesday, December 17, 2014

Calculate Distance in .kmz File

Here's a little script that calculates the distance of a path (series of GPS points) in a .kmz file (which I generate with My Tracks). It combines several elements - Zip file, XML (with namespaces), zip, sum and of course a bit of math.

Sunday, December 07, 2014

The Versatile date Command

*nix systems comes with a date command line utility. Many people use it to view the current time, however there''s much more that date can do.

For example we run a daily job to process yesterday data. The job is a Python script that get the date as a paramter in YYYYMMDD format. This translates to one cron line:

@daily /path/to/job.py $(date --date=yesterday +%Y%m%d)

Here are some things you can do with date:


As a bonus, there is also a cal command which displays calender. Note that years are 4 digits so cal 4 14 will diaplay April for the year 14, not 2014.

cal has a handy -w switch that shows the work week as well.'

Wednesday, November 26, 2014

Generate QR Code Using Google Charts API

Here's a small utility to generate QR code image using Google Charts API.

Note the hand crafted Python 2/3 support, for more advanced stuff you might want to have a look at six. However for this script I wanted to stay without external dependencies.

Sunday, November 16, 2014

Common Errors

"Experience is the name every one gives to their mistakes."
    - Oscar Wilde

Students are sometimes amazed by how I can tell the cause of exception without looking at the code. This is the result of making many errors in Python myself and also from observing many students doing mistakes. Here's a short list I've compiled of most likely cause of errors:

NameError

  • You forgot to import a module
  • You made a typo

AttributeError: 'NoneType' object has no attribute ...

  • You forgot a return in your function

AttributeError

  • Typo on dot lookup (obj.foo)
  • Object is different type from what you think (str vs int)
  • Object does not implement a dunder method (e.g. __len__)
There's also the 3'rd party didyoumean module, which might be interesting for beginners. It changes the default stack trace to add a hint about what might be the problem.

Monday, November 03, 2014

A Streaming Chart using Flask and flot

I was teaching a course on "Python Analytics" (pandas, scikit-learn, matplotlib ...) and was asked to provide an example of streaming chart - ones that updates periodically. I''ve showed a couple of examples one by generating image using matplotlib and another with bokeh-server. After a couple of days I remembered another way - using flot to render the chart. Here''s a small example using Flask as the web server (the code works both on Python 2 and 3).


Few comments:

  • Don''t use debug=True in production :)
  • For simplicity everything is in one file. However for larger application you might want to take the HTML template(s) out
  • Data is in memory, a restart will wipe it out. If you need data persistence - pick a database (shelve, sqlite3 ...)
  • A big shoutout to Continuum Analytics - Anaconda (and conda) has made my life so much easier teaching this workshop.

Tuesday, October 28, 2014

Resolve SSH Host Name

~/.ssh/config let''s you give meanigful names to hosts/ips. But sometimes you want the reverse lookup - what''s the ip of web1? Here''s a little Python script that does that.

EDIT: EAFP > LBYL

Friday, October 24, 2014

Archlinux Install Steps (on VirtualBox)

My favorite Linux distro for using under VirtualBox is Archlinux with XFCE window manager. It''s light, fast and has all the latest shiny new toys (just the way I like it :).

I found myself setting up VMs to try things out and wrote down the steps I use, this is a trimmed down version of the Installation part in the Archlinux beginners guide.

Thursday, October 09, 2014

Be a Better Developer by Coding in Four Different Types of Lauguages

I like programming languages and find out that every time I learn a new language it improves my coding in the other ones as well. I learn new ways of doing things, different ways of thinking and it's great.

I usually tell new developers they need to write a (small) project in at least four types of languages - mainstream (procedural/OO), functional, logic based and assembly. Each of these types will give you a different way of solving problems and enrich your programming experience by and order of magnitude.

Here are my recommendations for each category.

Main Stream

By "main stream" I mean procedural/OO languages. There are tons of these and its up to what you're working with currently (though it might be a good excuse to learn a new language). I'm a Python expert, but pick anything - Go, JavaScript, Ruby, C, C++, Java, C# ...

(Yeah - I know they differ a lot. But thinking in most of them is probably the same. The main difference will probably be dynamic vs static typing).

Functional

Many choices here as well. Personally I like the Lisp family of languages, mostly Clojure and Scheme but you can check out a Common Lisp implementation (I think SBCL leads the pack currently), Haskell, ML and others.

Logic Based

If you haven't done logic programming - it'll blow your mind! It's a totally different way of thinking. Prolog is the main language, one free implementation is SWI but there are others as well.

Assembly

Learning assembly will give you a better understanding on how computers work and what are the abstractions other programming languages do for you. I recommend picking one that targets the machine you're working on.

Saturday, October 04, 2014

Add That Trailing Comma

Lets say you wrote this simple code and at first things were going well.

Then after a while a friend came in and did a little fix.

But things started falling apart, after a lot of digging in - you find this.

Python will join two string together in this case, not what you wanted. Always leave a trailing comma.

Couple more things:
  • As Dave Cheney pointed out, using this practice has the nice effect that one line change shows as one line change in the diff since you don''t have to add a comma to the previous line.
    • Go probably learned from Python and made trailing comma mandatory.
  • You can see more Python "gotchas" here.

Monday, September 29, 2014

draft2gist - Publish draftin.com Documents to gist

I've started playing with draftin.com, so far very nice.

draftin.com lets you publish documents to several sites, and if the site you want to publish to is not on the list - there are WebHooks.

I've written a small AppEngine service that is a WebHook for publishing draftin.com documents to gist. Feel free to use it and let me know if you find any errors.

Below is the server code, rest of the files are here.

Monday, September 22, 2014

HTTP Proxy Stripping Headers (go)

At one of my clients, we wanted to write an HTTP proxy that strips some of the headers sent from the target (backend). With the help of golang-nuts mailing list - this turned out to be pretty simple.

Sunday, August 24, 2014

timeat on pypi

timeat is now on pypi. There's some extra code to get current time from NTP server. Should work both on Python 2.x and 3.x

Thursday, July 31, 2014

timeat in Go

Wrote timeat, which shows time at a specific location, in Go as well. (For comparison the Python version is here). To install either go get bitbucket.org/tebeka/timeat or download the executables.

Working in a multi-timezone team, this script comes handy from time to time (as well as worldtimebuddy :).


Wednesday, July 16, 2014

Generating Byte Arrays for Assets in Go using xxd

Go's net/http server is pretty fast, but sometimes you want to get faster. One way to do that is to create a binary array in memory for static files (assets). Here''s how I generate the byte arrays automatically with xxd.

Note that this makes the build go slower as you have more and bigger assets.If this is a problem, take a look at nrsc ;)

Since the go toolchain does not support custom steps currently, I''m using make.

Makefile

httpd.go

Sunday, July 06, 2014

Hook to Update Tag List when Changing git Branch

I use ctags with Vim to move around. At work we use git feature branches, which means code changes when you switch a branch. Here''s a very simple post-checkout hook to update the tag list whenever you switch branches.

Thursday, June 26, 2014

Use dict to Speed Up Your Code

In Python, dictionary access is very fast. You can use that to get some speedup in your code  by replacing if/else with dictionary get.

In [1]: fn1 = lambda x: 1 if x == 't' else 0

In [2]: fn2 = {'t': 1, 'f': 0}.get

In [3]: %timeit fn1('y')  # Check "True" branch
10000000 loops, best of 3: 124 ns per loop

In [4]: %timeit fn2('y')
10000000 loops, best of 3: 79.6 ns per loop

In [5]: %timeit fn1('f')  # Check "False" branch
10000000 loops, best of 3: 125 ns per loop

In [6]: %timeit fn2('f')
10000000 loops, best of 3: 81.3 ns per loop

About 30% speedup - not bad :)

Wednesday, June 04, 2014

HTTPDir - Small OSX Utility to Serve a Directory over HTTP

HTTPDir is a small utility that lets you serve content of a directory over HTTP.

This is handy when you develop static sites that has reference to external resources. It is also aimed to people who are not comfortable with the command line.

HTTPDir is a simple Python script that uses Tkinter. It is packed in a format that OSX recognizes as an application. See the code here (look under HTTPDir.app/Contents/MacOS).

Friday, May 23, 2014

"timeat" updated

timeat updated to use the new(ish) Google Time Zone API.
$ timeat haifa
Haifa, Israel: Fri May 23, 2014 22:16
$ timeat paris
Paris, France: Fri May 23, 2014 21:17
Paris, TX, USA: Fri May 23, 2014 14:17
Paris, TN 38242, USA: Fri May 23, 2014 14:17
Paris, IL 61944, USA: Fri May 23, 2014 14:17
Paris, KY 40361, USA: Fri May 23, 2014 15:17

Oh, and there's also a Go version.

Sunday, April 20, 2014

Important vs Urgent

This was a lesson I learned a long time ago, maybe other people will find it useful as well.

Look at the chart above, we divide tasks to four categories on the urgent/important dimensions. Let's look at each category:
  1. Not urgent and important - this is where you (and most successful companies) should spent your time. This means investing in infrastructure, making your process more efficient ...
  2. JFDI. However if you find that most of your time is spent there - you're doing something wrong.
  3. Don't bother.
  4. This is the big time sucker. Try to avoid at all cost.
Note: "If everything is important, then nothing is." - Patrick Lencioni

See more here, here and here.

Tuesday, April 01, 2014

Easy statsd metrics decorator and context manager

Easy statsd metrics decorator and context manager statsd is very handy with creating metrics. Here's a decorator and context manager that simplify the usage even more.
Note: If you want to easily test your code, you can use this Vagrant VM.

Monday, February 17, 2014

Running commands via HTTP

Ran asked about invoking commands via HTTP interface. Here's a quick answer I came up with (using Flask).

Friday, January 24, 2014

pypi→u


I was trying to see if there's an annoucement list for Celery (which we use at work) - didn't find it. One thing led to another... and I wrote pypi→u, a service that emails you if there's a new version of packages your interested in.

It run on AppEngine (with some bootstrap sprinkeld on). You can view the source here.

Note that pypi→u is very alpha, handle with care. Suggestions, comments and bug reports are welcomed.

Friday, January 03, 2014

Current email setup: osx + homebrew + sup + davmail + getmail

 At work we have an Exchange server for email (no POP3/IMAP) and most people use Outlook. However I prefer not to use outlook, here's what I came with:
  • Sup as email client
  • DavMail for POP3/SMTP
  • getmail for fetching email
  • Homebrew for unix-ish environment (yup, that's OSX for you)
 Setup is a bit complicated, but once you're there - email is a bliss (well, as much as email can be :)

DavMail

Install DavMail from the .dmg. Run it and point it to the exchange server URL and have it expose POP3 and SMTP. See ~/.davmail.properties (though it's easy to configure from the UI as well).

I added DavMail to my "Login Items" so it starts when I login.

Homebrew

See the site for documentation on how to install.

getmail

Install with "brew install getmail". I keep my mail in ~/Mail, see ~/.getmail/getmailrc.

I have a cron job to run getmail every 3 minutes
    */3 * * * * /usr/local/bin/getmail -n -q

sup

sup is based on ruby. I've installed rbenv and ruby 1.9. "gem install sup" should work. (Note that I had trouble linking to ncurses, and had to run "brew link ncurses" before installing sup). See ~/.sup for configuration example.

sendmail

Sending mail is done via the sendmail program that comes with OSX. A bit of configuration is needed though. See /etc/postfix/main.cf and /etc/postfix/sasl_passwd

After the above changes, run the following commands:
    sudo postmap /etc/postfix/sasl_passwd
    sudo postfix reload

That's it, you should be set to go with a decent email client.

I also use iTerm2, which lets me click on a link on sup terminal and open it


Friday, December 13, 2013

Reading Passwords of OSX Keychain

OSX stores passwords in its keychain, which is sometimes useful when you forget a password. The command line security utility lets you access the keychain, however the output is somewhat cryptic.

Below is a little script to get user and password for a given domain.

    find-pass.py signup.netflix.com

Note you might get an image like the image on the right. Click either "Allow" or "Always Allow".





Thursday, November 28, 2013

Dealing with Bad Memory

The family joke is that I was born senile (my joke is that I have 1bit memory). During the years I've developed some methods to help me be be productive with bad memory. Hope they'll help you as well (if you remember them :).

JFDI
That's the most effective method - do it at the moment you remember. It's pretty amazing how many things you can do "right now" without interrupting your flow too much. Once you did it - there's no need to remember.

Make it Impossible to Forget
Yeah, writing things down help - but I forget to look at my lists. However if you make things impossible to forget - then you won't forget. For example if I need to take something to the car, I'll place it at the front door - can't miss it when I go out.

Get Help
May they be electronic or human, get some help. I married a wife with a phenomonal memory, but it's not an option for everyone :) In this digital age you can find a good non human assistent to help you. Hiring a human assitenet doesn't have to be expensive - see Fancy Hands for example. 

Write It Down
We have a saying: "A short pencil is better than a long memory.". Write things down, it'll help you remember when you write then and later you can look them up. I use this blog as an memory of things that worked for me. Other things I use are pinboard, trello, GMail and Google Docs. Everything with a search function in it.
 
Forgive Yourself
You will forget things, learn to live with it. One of the worst things you can do it agonize over the things you forgot. It'll only add stress to your life without helping you to remember.  

Monday, November 25, 2013

Removing "noise" before matplotlib charts in IPython notebooks

By default, IPython notebook prints the value of the last expression. This works fine most of the time but sometimes the result of a chart is a long list of lines which is something you don't want to see - you just want to see the chart. Here are two options to fix this (you can also view the example notebook).

Wednesday, November 06, 2013

Decorators and Context Managers Workshop

I gave a workshop on decorators and context mangers at work.

Both are very powerful and will change the way you code in Python once you grok them. They mostly allow you to focus on application logic and write the "book keeping" code (logging, timing, resource allocation ...) in a separate place.

Here are the IPython notebooks:
And the solutions (but try to solve the exercises first):
 If you want to run locally, the code is here.

Searching and Viewing emoji

We started using emoji at work. We're using Adium with the emoji xtra.

Here's a little script to search and optionally show emojis (requires matplotlib).

Wednesday, October 30, 2013

Making "pip" Faster

We use pip to install packages at work. Mostly in combination with virtualenv and wheel packages. Lately I had to re-install again and again a bunch of virtual environments and looks for a way to speed things up.

The solution was to cache the pip downloads and also to keep in a local directory the bigger .whl packages. All done in ~/.pip/pip.conf. Most of the downloads are done once now and using local .whl means no more compilation (I'm looking at you PyYAML ...). I didn't measure the time difference, but for sure it feels faster.

Friday, October 25, 2013

A Simple Python Based Configuration with Overrides

Here's a simple Python based configuration system that supports overrides. We use a variant of it at work and it proves to be very handy. The fact that you can use all of Python in your configuration is very powerful. We use Puppet to write config_local.py in production/qa environments and keep the default good for development machines.

Wednesday, October 16, 2013

Import Google Bookmarks to Pinboard

I decided to give Pinboard a try. Sadly they lack support for importing Google Bookmarks.

I wrote a little utility to do just that (still waiting for pinboard support to get back to me ;)

Thursday, October 03, 2013

Python Logging Overview

Gave a talk at work about Python Logging.

You can view it here.

Sunday, September 29, 2013

logbot

We have an internal Jabber server at work, which is great for communication. However unlike HipChat/Campfire - it lacks central logging.

A couple of hours with sleekxmpp, Whoosh and flask solved the problem. logbot is out there - use with caution. (And pull requests are more than welcome ;)

Saturday, September 21, 2013

"crashlog" is now on PyPi

FYI: Decided to make crashlog a PyPi package.
LMK if you find any problems.

JSON Handling with datetime Support

While working on some ETL testing code, we needed to load some synthetic data to a database. At first we thought of using YAML for the synthetic data, but it was very slow so we decided to switch to JSON which is still readable but way faster (loading 183 records took 0.68sec with YAML vs 0.008sec in JSON).

However we needed support for serializing datetime objects. Here's dtjson, which support datetime objects in JSON serialization. You can use it almost a drop-in replacement for json: import dtjson as json.

Wednesday, September 18, 2013

Adding ODBC Source on OSX

At work, we're using Netezza as our main data warehouse. It took me a while to figure out how to add the ODBC driver on OSX so that I'll be able to connect with pyodbc.

Here are the steps:
  • Get the OSX Netezza ODBC driver and unpack it
    • Not sure where do get it, we have it internally
  • Extract the archive somewhere (say /opt/NetezzaODBCDriver)
  •  Add  export DYLD_LIBRARY_PATH="${DYLD_LIBRARY_PATH}":/opt/NetezzaODBCDriver/lib/ to your ~/.zshrc (or ~/.bashrc)
  • mkdir -p ~/Library/ODBC
  • cp /opt/NetezzaODBCDriver/ini/*.ini ~/Library/ODBC
  • Edit ~/Library/ODBC/odbcinst.ini to reflect were your driver is (Driver and Setup keys)
    • In our example it'll be Driver = /opt/NetezzaODBCDriver/lib/libnzodbc.so (same for Setup) 
That's it, you can now connect to Netezza from OSX.

Here's a small example usage:

Monday, September 16, 2013

Don't Forget Your Process When Selecting Tools

When selecting tools, there are many things you should consider - prices, value added, integration cost, health ...

However many teams forgot to check how well does the tool integrate with your current development process. A good tool that does not play well with your process will cause many problem and might alter your process a direction you don't want.

For example, we have a process (like many others probably) which involves code reviews. We have a tool with does not play well with code reviews - it has binary projects. The process with this tool is different, much slower and more error prone than the rest of the tools.

Next time you pick a tool to work with, think how well will it play with your current process and take it into consideration.

Note: It might be OK to change the process if the tool is worth it, just make sure it does before you integrate it.

Monday, September 09, 2013

Advice For New Managers

Here's some of the advice I give new managers. I try to talk to them before they start their first management job - let me be the first to ruin their career :)

Disclaimer: I'm not a manager, but I was managed by many and was an officer for many years in the IDF which is very informal kind of army.

Here they are, without any particular order.

Style

Every manager has their own style. From fire-and-forget to micromanagement and everything in the middle. Your style will probably be different from another manager (even from your own), your management style will change over time and from team to team. Play to your strengths - organizational, people skills, ....

Don't be afraid to try until you find a style that both you and your team are comfortable in. As long as you're open about what you're doing, you team will support you. It's hard to measure the effectivenehess of each style, but if you can - do that.

Let Go

You are a manager now, not a developer. I've seen very few managers in my long career that managed to do both effectively. Learn to trust your team and be a manager first and developer last.

Think about the things you liked and disliked in your past managers (and the current one) and figure out what you should do.

Manage Your Time

Management is very different from development, it's much more interruption driven. However you need to allocate time for yourself. I've seen the best officers in the army taking up to 30 minutes to think while all hell breaking loose around them (number 2 was in charge in the meanwhile). If they can do it - I'm sure you can.

Here's a great talk by John Cleese (of the Monty Python fame) about creativity which covers this topic as well.

Know Your Place

In officer training over at IDF, they teach you that an officer should be where he/she's most needed. Same goes for you - think about what you are the most effective at solving the more important things and be there.

Develop A Mantra

Find a sentence which will help you focus, and ask it repeatedly throughout the day. I found out that "Why aren't we deploying?" help our team focus and deliver. However find one that fits your goals/team/company ....

You Team Comes First

If you show your team they come first (mostly by "buffering" them from all the management noise), they will be loyal to you. Loyalty works both ways or it doesn't work.A loyal and jelled team is hard to build but when you get there - they will rock.


That's about it. Don't be nervous and try to enjoy a new position. In the worse case know that management is not for everybody (I personally don't like it). There's no shame in saying "this is not for me" and getting back to to fun stuff. (My brother did just that, he managed for a year and then said to the company - "Either I'm back to development or I'm out". He was back in development).

I hope that you found this useful.


Monday, August 26, 2013

Vi Keybindings in SBCL REPL

I'm (re-)reading "Practical Common Lisp" and going over the exercises/code with SBCL. I found the below script to help me with my Vi addiction :)

Friday, August 23, 2013

Error Handling in Python

I gave a talk at work about error handling in Python.
You can view it here.

What do you think? Did I miss something?

It's worth noting that after a while working with Go and the way it handles errors (if value, err = foo(); err != nil ...). If find my Go programs more verbose but more robust at the same time.

Saturday, August 03, 2013

XFCE and Volume Keys

I'm currently playing around with XFCE. I have PulseAudio and wanted the volume keys to work (I'm a keyboard kinda guy. :). Here's a solution:

  • Open Settings -> Keyboard -> Application Shortcuts
  • Click on "Add"
  • Type pactl set-sink-volume 0 +10% and then OK
  • Hit the "up volume" button on your keyboard
  • Click on "Add" (again)
  • Type pactl set-sink-volume 0 -- -10% and then OK
    • The -- is not a typo
  • Clock on "Add"
Your volume keys sound work now.

Oh, and I find installing they "Greybird" theme [1] (from Ubuntu) makes things much nicer :)


[1] Install with yaourt -S xfce-theme-greybird and then select in Settings -> Appearance

Friday, August 02, 2013

Google Bookmark Command Line Utility

A little utility to save URLs in Google Bookmarks. (This will open a web browser with some fields populated).

Wednesday, July 31, 2013

IPython on OSX (with iTerm2)

Sadly, in the new workplace I have to use OSX (it's either that or Windows, running Linux and connecting to everything is a ... challenge).

Here's a little script I wrote to open IPython with a new iTerm2 window. I call this script ipy and place it at ~/bin. Then hitting APPLE+SPACE launches Spotlight. Writing "ipy" inside and hitting ENTER does the trick.

If you want VIm keybindings, add the following to ~/.inputrc

set editing-mode vi
tab: complete
set completion-ignore-case on
set blink-matching-paren on
Oh, and if you find out how to maximize the window - please share :)

Tuesday, July 30, 2013

Command line front end to Jinja2

Below is a little command line front end to the Jinja2 templating library.
(Very much in the spirit of the mako utility).

Monday, May 20, 2013

Want To Be More Productive? - Improve Your I/O


It always surprise me that people trying to makes themselves more productive overlook their I/O - reading and writing.

I still see many people slowly and inefficiently reading on the input side and pecking their way on the keyboard in the output side.

I guess the reason that people don't invest time in improving their I/O is that it's boring. I'll be the first to agree that learning speed reading or touch typing is boring, however the benefits you'll reap are big - the investment will pay itself every time you interact with your computer.

After getting the basics of speed reading and touch typing out of the way [1], there are many more ways you can improve your I/O. Here are few examples:

  • Learn to efficiently skim through documents
  • Learn to pick what to read
  • Master your IDE
  • Automate everything
  • ...
[1] And you should never stop practicing.

Friday, May 17, 2013

Running "one off" Conversions In PostgreSQL

The other day we needed to runs a one-off job for converting datetime.weekday() values to day names. Here's what we came up with.

Wednesday, May 01, 2013

Getting Good Errors from Python Map/Reduce Jobs

At work, we use some Python map/reduce jobs (using Hadoop streaming).

Debugging can be difficult, since Hadoop does not keep the Python stacktraces and even if it does - it's very hard to find it. We decided to use crashlog, and now we get wonderful emails with detailed description of what went wrong.

Notes:
  • The current mapper input file is in map_input_file environment variable
  • Don't forget to add crashlog.py with -file (see here)
  • You must add "." to PYTHONPATH in order to import
    • import sys; sys.path.append('.') should do the trick
  • Email is not the best solution for distributed logging (you get a lot of email when things go South). I'm going to play with graylog2 in the future.

Saturday, April 20, 2013

Serving Dynamic Images with matplotlib

Here's an example of generating dynamic images using matplotlib in a web server (flask this time).

Thursday, April 11, 2013

Show Location Of Hive Table in HDFS

Here's a script I use to find out where Hive is storing it's data on HDFS (I call it hiveloc).




Tuesday, April 09, 2013

Quickly Plotting Labeled Data

Here's a quick way to view some labeled data you have (taken from An Introduction to scikit-learn). It will reduce the data to two dimensions using PCA and then scatter plot it with different colors for each label.

Script to close a branch in mercurial (hg)

Mercurial (hg) does not let you delete branches (or alter history in any way). But you can close branches so they won't show in hg branches command.

Here's a script I use to close branches (we work with feature branches at work, and close them when work on the feature is done).

Sunday, March 31, 2013

gittip on bitbucket/github

gittip is a cool idea, however currently there's no built-in way to add it to bitbucket/github projects.

One option I found that works it to add a clickable image to your README.md or README.rst.

See example here.

Markdown:

[![gittip](http://i.imgur.com/lg9rx9w.png)](https://www.gittip.com/Miki%20Tebeka/)


ReStructuedText:

.. image:: http://i.imgur.com/lg9rx9w.png
   :alt: gittip
   :target: https://www.gittip.com/Miki%20Tebeka/



Notes:

  1. You'll probably want to change gittip user id :)
  2. There's a discussion on gittip bug tracker on the right way to do this.
  3. Unofficial gittip image generated using cooltext.

Thursday, March 28, 2013

import "C" slides

Last night I gave a talk about using C from Go at the L.A. Gophers meetup.

You can view the slides here. (Note that "run" won't work due to security restrictions, you can download the slides here and run it locally using the present tool).

Wednesday, March 13, 2013

Investigating Hash Distribution

A college asked me for a hash function on strings that return an integer between 0 to N. Before diving in, I decided to take the lazy path and check if Python's hash function is good enough.

Luckily, ipython notebook --pylab=inline makes that a breeze.
Check out the notebook here.

And yes, we decided to stick with this solution. I guess we're at least 1/3 programmers.

Friday, March 08, 2013

zipstream - Zip File InputFormat for Hadoop Streaming

At work, we store logs as a single CSV inside a zip file in HDFS (history, that's why :).

Looking around, I couldn't find a FileInput library that works with Hadoop streaming on CDH4 (the version we're using).

So I wrote one, hope you'll find it useful (you can download the jar directly from here.)

Here's an example how to use it:

Thursday, February 21, 2013

Abusing namedtuple - Yet Another Enum

There's a discussion over at python-ideas about enum. This prompted me to write yet another implementation of enum, this time abusing namedtuple.

Friday, February 15, 2013

try lock

At work, we have several functions that can run only one at a time. We call this "try lock" (or trylock), and had it forever in the Java code.

When we started a Python project, we wanted this functionality. A decorator seems like the right solution. The below try_lock decorator has an optional function that lets you get a finer grained solution on what to lock. It gets the function arguments and returns a key to lock on. If you don't specify keyfn, then there will be just one lock for the function.

Thursday, January 24, 2013

whoops - A WebHDFS Library and Client

Just released whoops 0.1.0 which is a WebHDFS library and a command line client for Python.

Wednesday, December 19, 2012

Timing Your Code

It's a good idea to time portions of your code and have some metric you monitor. This way you can see trends and solve bottlenecks before someone notices (hopefully). Timing functions is easy with decorators, but sometimes you want to time a portion of a function. For this you can use a context manager.

Tuesday, December 11, 2012

Tuesday, November 20, 2012

Last Letter Frequency

I was playing a game with my child where you say a word, then the other person need to say a word which starts with the last letter of the word you said, then you need to say a word with their last letter ...

We noticed that many words end with S and E, which made me curious about the frequency of the last letter in English words. matplotlib makes it super easy to visualize the results.

Friday, November 16, 2012

Python For Data Analysis

Just finished reading Python For Data Analysis, it's a great book with lots of practical examples. Highly recommended.

Thursday, October 25, 2012

Mocking HTTP Servers

Sometimes, httpbin is not enough, and you need your own custom HTTP server for testing.
Here's a small example on how to do that using the built in SimpleHTTPServer (thanks @noahsussman for reminding me).

Monday, October 15, 2012

http://httpbin.org

Sometimes you need to write an HTTP server to debug the client you are writing.

One quick way to avoid this is to use http://httpbin.org/. It supports most of the common HTTP verbs and mostly return the variables you send in.

For example (note the args field in the reply):

$ curl -i 'http://httpbin.org/get?x=1&y=2'
HTTP/1.1 200 OK
Content-Type: application/json
Date: Mon, 15 Oct 2012 21:50:27 GMT
Server: gunicorn/0.13.4
Content-Length: 386
Connection: keep-alive

{
  "url": "http://httpbin.org/get?x=1&y=2",
  "headers": {
    "Content-Length": "",
    "Connection": "keep-alive",
    "Accept": "*/*",
    "User-Agent": "curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3",
    "Host": "httpbin.org",
    "Content-Type": ""
  },
  "args": {
    "y": "2",
    "x": "1"
  },
  "origin": "75.82.8.111"
}

Friday, October 05, 2012

Cleanup After Your Tests - But Be Lazy

It's a nice practice to clean after your tests. It's good for various reasons like disk space, "pure" execution environment and others.

However if you clean up to eagerly it'll make your debugging much harder. The data just won't be there to see what went wrong.

The solution we found is pretty simple:
  • Try to place all your test output in one location
  • Nuke this location when starting the tests
This way all the information is available after an error, and you don't accumulate too much junk (just one test run junk at a time).

Thursday, September 20, 2012

Data Wrangling With Python

I just gave a talk at work called "Data Wrangling With Python" which gives an overview on the scientific Python ecosystem. You can view it here.

Friday, September 14, 2012

Using Hadoop Streaming With Avro

One of the way to use Python with Hadoop is via Hadoop Streaming. However it's geared mostly toward text based format and at work we use mostly Avro.

Took me a while to figure the magic, but here it is. Note that the input to the mapper is one JSON object per line.

Note it's a bit old (Avro is now at 1.7.4), originally from here.

Friday, September 07, 2012

Setting Maching Learning on OSX

Setting up machine learning tools (numpy, scipy, matplotlib, scikit-learn, ...) can be a pain (why can they just use a decent OS? :).

We are lucky to have Ben Kim now with us at Adconion, and he posted the following:


Mac OS X Lion Software Installs
  1. Install compilers
    1. Install XCode 4.x from the App Store
      1. Install Command Line Tools in Preferences/Download
    2. Install gcc, g++, and gfortran compilers
      1. Download tar file
      2. Extract to /
        1. tar -xvf abc.tar -C /
    3. Reference http://sites.google.com/site/dwhipp/tutorials/mac_compilers
  2. Install Homebrew
    1. Run the install command using ruby
      1. ruby <(curl -fsSkL raw.github.com/mxcl/homebrew/go)
    2. brew doctor
      1. chown /usr/local folders listed
      2. Place /usr/local/bin before /usr/bin in path
    3. Reference https://github.com/mxcl/homebrew/wiki/installation
  3. Install python using brew
    1. brew install readline sqlite gdbm pkg-config
    2. brew install python
    3. Note: Mac OS X Lion comes with old version 2.7.1 of python (python --version) 
  4. Set PATH in .bash_profile
    1. vim ~/.bash_profile
      1. export PATH=/usr/local/share/python:/usr/local/bin:$PATH
  5. Create symlinks
    1. Within /(System/)?Library/Frameworks/Python.framework/Versions, sudo rm Current
    2. Within the above directories, ln -s /usr/local/Cellar/python/2.7.3 Current
  6. Install pip, if necessary, using easy_install
    1. sudo easy_install pip
  7. Using pip (sudo pip install [--upgrade] abc)
    1. Install nose
    2. Install numpy
    3. Install scipy with environmental variables settings
      1. sudo CC=clang CXX=clang FFLAGS=-ff2c pip install [--upgrade] scipy
    4. Install scikit-learn
    5. Install pandas
  8. Install matplotlib
    1. Download source from repo: https://github.com/matplotlib/matplotlib
    2. cd ~Downloads/matplotlib-*
    3. python setup.py build
    4. python setup.py install
  9. Install VW (Vowpal Wabbit)
    1. Install boost
      1. Download tar file
      2. mv boost extracted folder to /usr/local
      3. export BOOST_ROOT environmental variable
      4. cd to boost directory
      5. make and install
        1. sudo ./bootstrap
        2. sudo ./bjam install
      6. Download bjam
      7. mv to directory in PATH
        1. mv bjam /usr/local/bin
      8. Set bjam toolset to darwin
        1. bjam toolset=darwin stage
      9. Reference http://www.boost.org/doc/libs/1_41_0/more/getting_started/unix-variants.html#expected-build-output
    2. cd to VW directory
      1. make and test
        1. make
        2. make test

Saturday, July 07, 2012

Show Dependecies of Azkaban Jobs

We're using Azkaban at work to schedule Hadoop jobs. It's hard to view the job dependencies without deploying, so here's a little script that will show you job dependencies as an image. It uses dot (from Graphviz) to produce the image.

Tuesday, June 26, 2012

Python Based Assembler

Got reminded of a project I did while back. It's a Python based assembler. The main idea is that the assembly file is actually a Python file with pre-set functions (assembly instruction). In this manner, I managed to skip lexing, parsing and other things and deliver a working assembler in two days. You can view the presentation I gave on this here.

The Assembler


Example Input

Friday, May 04, 2012

Using travis-ci with bitbucket

travis-ci is a great service. My problem is that it works only with github while I mainly use bitbucket (and please, let's not get into hg/git debate - hg is way better :).

The way I found to make this work is to mirror my bitbucket projects on github using hg-git. Below is an example from fastavro.

First, you need to install hg-git. It's available from PyPI, "pip install hg-git" will do the trick, (or "easy_install hg-git" if you don't have pip).

Then create a repository on github to mirror the one on bitbucket. After that tell travis-ci to watch this repository.

Next step is to enable hg-git in your repository, edit .hg/hgrc and add the following:
[extensions]
hgext.bookmarks =
hggit =

Then "bootstrap" it with the following command:
hg bookmark -r default master

Next step is to create .travis.yml, For fastavro I have both Python 2.7 and 3.2.

Last step, is to make sure every time we push to bitbucket, changes are pushed to github as well. This is done with an outgoing hook in .hg/hgrc
[hooks]
outgoing = hg push git+ssh://git@github.com/tebeka/fastavro.git || true

(The || true is there since hg push will exit with non-zero value sometimes)

That's all. Now fastavro has continuous integration that runs both on Python 2.7 and 3.2.

Monday, April 23, 2012

Twitter Post Frequency

Sometime I see interesting new people on Twitter. However before adding them I'd like to know what is their post frequency so I won't get spammed. Below is a simple script to do that:

Tuesday, March 27, 2012

A lambda Gotcha

Quick, what is the output of the following?

In [1]: callbacks = [lambda: i for i in range(10)]
In [2]: [c() for c in callbacks]

The right answer is:
Out[2]: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9]

This is due to the fact that i is bound to the same variable in all the lambdas, and has the final value of 9.

There are two ways to overcome this. The first is to use the fact the default arguments are evaluated at function creation time (which is another known gotcha).

In [3]: callbacks = [lambda i=i: i for i in range(10)]
In [4]: [c() for c in callbacks]
Out[4]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

The second is to create a function generator function:
In [5]: def make_callback(i):
   ...:     return lambda: i
   ...:
In [6]: callbacks = [make_callback(i) for i in range(10)]
In [7]: [c() for c in callbacks]
Out[7]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Wednesday, March 14, 2012

Reading Avro Files Faster than Java

At work, we use a lot of Avro. One of the problems we faced was that the Python Avro package is very slow comparing to the Java one. The goal then was to write fastavro which is a subset of the avro package and should be at least as fast as Java. In this post I'll show how fastavro became faster than Java and also Python 3 compatible.

Going Fast
The Python avro package uses classes and properties heavily. This might allow for nice design but since function calls in Python are expensive it has a cost. The approach was to strip down most of the code in the avro package to one simple module, eliminating as many function calls as possible along the way and using only built in types. After some tweaking, fastavro was churning through the 10K records benchmark in about 2.6seconds (comparing to 13.9 seconds of the avro package). It was a nice speedup but the goal was to be as fast as Java (which was doing about 1.8sec).


Going Faster
Enter Cython. fastavro compiles the Python code without any specific Cython code. This way on machines that do not have a compiler users can still use fastavro. This complicated the build process a bit since now the C extension is generated using Cython in external Makefile. The code in fastavro first tries to import the C extension and if it fails imports the pure Python one.

This approach gave a 2x speedup (benchmark of 10K records done in 1.5seconds). Again, this is without any Cython specific code.

Python 3 Support
The initial Python 3 support was written on the first day of PyCon. However after hearing Robert Brewer's excellent talk I decided to take his advice and write a small compatibility layer (six was not used for various reasons).

As Robert said, this approach made fastavro better with strings, unicode and other things which were glossed over the 2.X only code. The build system was simplified a lot comparing to the one with the initial Python 3 support.

End Result
The end result is a package that reads Avro faster than Java and supports both Python 2 and Python 3. Using Cython and a little bit of work the was achieved without too much effort.

As usual, the code can be found on bitbucket.

Thursday, February 23, 2012

Super Simple Mocking

There are many mocking libraries for Python out there. Due to the dynamic nature of Python I find them an overkill. Below is a super simple mocking library that works for me.


Note that for some types (such as C extensions, objects with __slots__ ...) this will not work since they do not have a __dict__.

EDIT: Following HackerNews comments , I've changed the interface to mock(obj, **kw).

Sunday, February 05, 2012

Adding Key Navigation to Your Web Site

I don't like using the mouse and thankful for every web site that adds keyboard navigation (like Google Reader). Be nice to your users and add some yourself.

jQuery makes it super easy to add keyboard navigation to your site, below is a simple example adding keyboard navigation. "k/j" for up/down, "o" for opening an item and "?" for toggling help. JavaScript code starts at line 90.


Wednesday, January 11, 2012

fastavro with Cython

Added an optional step of compiling fastavro with Cython. Just doing that, with no Cython specific code reduced the time of processing 10K records from 2.9sec to 1.7sec. Not bad for that little work.

Also added a __main__.py so you can use fastavro to process Avro files:

  • python -m fastavro weather.avro # Dump records in JSON format
  • python -m fastavro --schema weather.avro # Dump schema

Friday, January 06, 2012

fastavro

Just released fastavro to PyPI. It has way less features than the official avro package, but according to my tests it's about 5 times faster.

Blog Archive