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 :)
If it won't be simple, it simply won't be. [Hire me, source code] by Miki Tebeka, CEO, 353Solutions
Thursday, June 26, 2014
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).
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.
Oh, and there's also a Go version.
$ 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:
Look at the chart above, we divide tasks to four categories on the urgent/important dimensions. Let's look at each category:
- 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 ...
- JFDI. However if you find that most of your time is spent there - you're doing something wrong.
- Don't bother.
- This is the big time sucker. Try to avoid at all cost.
Note: "If everything is important, then nothing is." - Patrick Lencioni
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.
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:
I added DavMail to my "Login Items" so it starts when I login.
I have a cron job to run getmail every 3 minutes
*/3 * * * * /usr/local/bin/getmail -n -q
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
- Sup as email client
- DavMail for POP3/SMTP
- getmail for fetching email
- Homebrew for unix-ish environment (yup, that's OSX for you)
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_passwdAfter 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".
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.
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.
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).
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.
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 ;)
I wrote a little utility to do just that (still waiting for pinboard support to get back to me ;)
Thursday, October 03, 2013
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 ;)
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
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.
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:
Here's a small example usage:
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)
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.
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.
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.
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
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).
(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:
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:
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
Thursday, April 11, 2013
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).
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:
[](https://www.gittip.com/Miki%20Tebeka/)
ReStructuedText:
.. image:: http://i.imgur.com/lg9rx9w.png
:alt: gittip
:target: https://www.gittip.com/Miki%20Tebeka/
Notes:
One option I found that works it to add a clickable image to your README.md or README.rst.
See example here.
Markdown:
[](https://www.gittip.com/Miki%20Tebeka/)
ReStructuedText:
.. image:: http://i.imgur.com/lg9rx9w.png
:alt: gittip
:target: https://www.gittip.com/Miki%20Tebeka/
Notes:
- You'll probably want to change gittip user id :)
- There's a discussion on gittip bug tracker on the right way to do this.
- 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).
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.
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:
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.
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
fastavro got snappy support
fastavro 0.7.1 introduces snappy support! (also 3.3 egg)
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.
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).
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"
}
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:
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
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.
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:
We are lucky to have Ben Kim now with us at Adconion, and he posted the following:
Mac OS X Lion Software Installs
- Install compilers
- Install XCode 4.x from the App Store
- Install Command Line Tools in Preferences/Download
- Install gcc, g++, and gfortran compilers
- Download tar file
- Extract to /
- tar -xvf abc.tar -C /
- Reference http://sites.google.
com/site/dwhipp/tutorials/mac_ compilers
- Install XCode 4.x from the App Store
- Install Homebrew
- Run the install command using ruby
ruby <(curl -fsSkL raw.github.com/mxcl/homebrew/go)
- brew doctor
- chown /usr/local folders listed
- Place /usr/local/bin before /usr/bin in path
- Reference https://github.com/
mxcl/homebrew/wiki/ installation
- Run the install command using ruby
- Install python using brew
- brew install readline sqlite gdbm pkg-config
- brew install python
- Note: Mac OS X Lion comes with old version 2.7.1 of python (python --version)
- Set PATH in .bash_profile
- vim ~/.bash_profile
- export PATH=/usr/local/share/python:/
usr/local/bin:$PATH
- export PATH=/usr/local/share/python:/
- vim ~/.bash_profile
- Create symlinks
- Within /(System/)?Library/Frameworks/
Python.framework/Versions, sudo rm Current - Within the above directories, ln -s /usr/local/Cellar/python/2.7.3 Current
- Within /(System/)?Library/Frameworks/
- Install pip, if necessary, using easy_install
- sudo easy_install pip
- Using pip (sudo pip install [--upgrade] abc)
- Install nose
- Install numpy
- Install scipy with environmental variables settings
- sudo CC=clang CXX=clang FFLAGS=-
ff2c pip install [--upgrade] scipy
- sudo CC=clang CXX=clang FFLAGS=-
- Install scikit-learn
- Install pandas
- Install matplotlib
- Download source from repo: https://github.com/matplotlib/
matplotlib - cd ~Downloads/matplotlib-*
- python setup.py build
- python setup.py install
- Download source from repo: https://github.com/matplotlib/
- Install VW (Vowpal Wabbit)
- Install boost
- Download tar file
- mv boost extracted folder to /usr/local
- export BOOST_ROOT environmental variable
- cd to boost directory
- make and install
- sudo ./bootstrap
- sudo ./bjam install
- Download bjam
- mv to directory in PATH
- mv bjam /usr/local/bin
- Set bjam toolset to darwin
- bjam toolset=darwin stage
- Reference http://www.boost.
org/doc/libs/1_41_0/more/ getting_started/unix-variants. html#expected-build-output
- cd to VW directory
- make and test
- make
- make test
- make and test
- Install boost
Tuesday, August 21, 2012
Monday, July 23, 2012
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:
Then "bootstrap" it with the following command:
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
(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.
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?
The right answer is:
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]
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.
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).
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.
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:
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.

Tuesday, December 27, 2011
How To Use A Chat To Amplify Your Team
A chat room is a great tool for any team. I've worked both in distributed and
"local" team and in both cases a central chat room was one of the most
effective tools we used. The chat room is the central location for updates,
conversations, shared knowledge and more. It's also highly effective in many open source projects.Starting is super easy, you can either set an internal server in your company with one of many open IRC/Jabber servers or try an external service (like Campfire, or HipChat).
The success of the chat room depends on the signal/noise ratio in the main room. Try to have every new conversation start in the main room, and only if it becomes to noisy move it to another room. 1/1 conversations are hiding information from the team and should be used only for personal communication.
Don't forget add services to the chat room. It's easy to add build notification, source commits, reminders and other smart bots. We use (Jenkins Jabber plugin) to get build notification. However be careful not to generate too much noise and tweak all these bots.
Logging and searching is another critical feature. Some services (like Campfire) provide it out of the box. If your chat server does not provide logging, it's pretty easy to add it with one of the many logging bots out there, and hooking search on top of the logs is pretty easy as well. (That's what we did with selenium.saucelabs.com which is a combination of Supybot and Omega).
Another issue is presence, people need to make it clear when they are "in" or "out" of the room. In some cases when the server logs it's as easy as login/logout. In other cases just notify the team your are away (we use the IRC /me lunching a lot). Stating that it's acceptable to be "out" of the room allows people to close the chat when they need to be in the zone.
So go ahead, set a chat for you team. Soon you'll wonder how you managed before.
Thursday, December 15, 2011
Decimals Class Decorator
A friend at work had a problem where he wanted to make sure some attributes are always Decimal.
We considered using the excellent traits library, but it's an overkill and we didn't want to introduce another dependency. For me this looked like a job for properties but we wanted some way to generate the properties automatically. Lucky for us we now have class decorators (in the old days I'd probably use a metaclass).
We considered using the excellent traits library, but it's an overkill and we didn't want to introduce another dependency. For me this looked like a job for properties but we wanted some way to generate the properties automatically. Lucky for us we now have class decorators (in the old days I'd probably use a metaclass).
Friday, December 02, 2011
branches
At work, our workflow involves JIRA and feature branches.
We name the feature branches in the name of the issue they are solving.
However when doing hg branches it's hard to know what branch you want.
Below is a small script that annotates the output of hg branches with the issue description from JIRA (and also added the branch parent).
However when doing hg branches it's hard to know what branch you want.
Below is a small script that annotates the output of hg branches with the issue description from JIRA (and also added the branch parent).
Friday, November 11, 2011
VirtualBox and USB
A little something I found out, writing it here in hope someone else will find it useful.
I'm on a Ubunbu system (11.10), and needed to connect to a USB device from an XP VM (wanted to sync and upgrade iPod touch, there is no iTunes for Linux). I couldn't connect the XP VM to any USB port (the USB menu was empty). The solution is to add yourself to the vboxusers group.
Open Users and Group, click on Manage Groups and double click on vboxusers and make sure your name is checked. After that logout and login, you should see the USB devices in the USB menu now.
I'm on a Ubunbu system (11.10), and needed to connect to a USB device from an XP VM (wanted to sync and upgrade iPod touch, there is no iTunes for Linux). I couldn't connect the XP VM to any USB port (the USB menu was empty). The solution is to add yourself to the vboxusers group.
Open Users and Group, click on Manage Groups and double click on vboxusers and make sure your name is checked. After that logout and login, you should see the USB devices in the USB menu now.
Tuesday, November 01, 2011
Summarize tuples
Raymond asked "Group the list of tuples on a given field and sum or count selected other fields.", here's my solution using sqlite3.
(original answer here).
Friday, October 28, 2011
Using dbus To Control Pidgin
I using Pidgin as my IM client, however after work I'd like to disconnect from our jabber server. Being the command like geek I am, I wrote the following. (Earlier version was written in bash using purple-remote
.)
You can learn more about Pidgin dbus interface here.
Saturday, October 15, 2011
Finding Module Version
A friend at work asked me how can he find which version of Python module is currently installed. The quick answer is to use pip:
pip freeze | grep <module>
pip freeze | grep <module>
Friday, September 30, 2011
Old Berlios Projects
Seems like Berlios is closing down. I've placed a backup of my old projects here. Let me know if you like to take ownership on one/several of them.
Using Generators in nose Tests
Sometimes you have many tests that do exactly the same thing but with different data. nose provides an easy way to do that with tests that return generators.
Saturday, September 24, 2011
Feynman On The Importance Of Playing
I'm reading "Surely You're Joking, Mr. Feynman" (very good read).
What he says about burnout, playing and doing the things you love is priceless:
Go out and play, I'm sure you'll make wonderful things.
EDIT: Thanks for HN for proof reading this. Also found a more complete excerpt here.
What he says about burnout, playing and doing the things you love is priceless:
But when it came time to do some research. I couldn't get to work. I was a little tired; I was not interested; I couldn't do research! ...
And then I thought to myself, "You know, what they think of you is so fantastic, it's impossible to live up to it. You have no responsibility to live up to it!"...
Then I had another thought; Physics disgusts me a little bit now, but I used to enjoy doing physics.
Why did I enjoy it? I used to play with it. I used to do whatever I felt like doing - it didn't have to do with whether it was important for the development of nuclear physics...
So I get this new attitude ... I'm going to play with physics, whenever I want to, without worrying about any importance whatsoever.
Within a week I was in the cafeteria and some guy, fooling around, throws a
plate in the air. ...
I had nothing to do, so I start to figure out the motion of the rotating plate...
And before I knew it (it was a very short time) I was "playing" - working, really - with the same old problem that I loved so much, that I had stopped working on when I went to Los Alamos; my thesis-type problems; all those old-fashioned wonderful things.
It was effortless. It was easy to play with these things. It was like uncorking
a bottle: Everything flowed out effortlessly. ...
There was no importance to what I was doing, but ultimately there was. The diagrams and the whole business that I got the Nobel Prize for came from that piddling around with the wobbling plate.
EDIT: Thanks for HN for proof reading this. Also found a more complete excerpt here.
Thursday, September 08, 2011
istail and ipeek
Prompted by a question in comp.lang.python:
Monday, August 29, 2011
"Top X" UI
Doing some experiments with data at work, one of the common tasks was "show top X items". However X was changing all the time. Finally I came out with a web based UI where you can set the top yourself. Hopefully someone else will find it useful.
Key points:
As usual, the code is in bitbucket.
Key points:
- Using jQuery, jQuery UI and flot
- Site is static, no backend needed
- Data is generated to a .js file
As usual, the code is in bitbucket.
Thursday, August 18, 2011
Crucible Command Line Client
At work, we use Crucible (which I mostly like). However we do reviews post commit (using feature branches). And creating a review from a patch is too much clicks to my taste. Hence crucible command line client. You can install it with easy_install crucible and then run it.
crucible has many options, but you can save many defaults in ~/.cruciblerc (see example at top of the crucible script).
crucible has many options, but you can save many defaults in ~/.cruciblerc (see example at top of the crucible script).
Wednesday, July 13, 2011
logio
The logging module is nice, one think I find myself missing here and there is the ability to treat logs as file objects. This help them "play nice" with many modules.
Here is a quick hack to do that, at the bottom there's an example on how to create CSV log files (and then we can use TimedRotatingFileHandler to rotate the logs).
Here is a quick hack to do that, at the bottom there's an example on how to create CSV log files (and then we can use TimedRotatingFileHandler to rotate the logs).
Thursday, July 07, 2011
PDB - The Movie
I did it again, this time showing how to work with PDB (the Python debugger).
Could it be the proximity to Hollywood that causes me to do these movies?
Could it be the proximity to Hollywood that causes me to do these movies?
Saturday, June 25, 2011
ingress
One of the many cool features in Twisted is "manhole". It lets you connect to any running server and get a shell (over ssh or telnet) in the server environment. This is very helpful when debugging.
It's very easy to implement this using SocketServer which is in the standard library, this way even if you're not running under Twised, you can still have this feature. I've created ingress just for this (easy_install ingress), using it is super easy:
The code itself is not that complicated. (Could have been simpler if there was a way to override writing to stdout in code.InteractiveConsole).
It's very easy to implement this using SocketServer which is in the standard library, this way even if you're not running under Twised, you can still have this feature. I've created ingress just for this (easy_install ingress), using it is super easy:
import ingress ingress.install()
The code itself is not that complicated. (Could have been simpler if there was a way to override writing to stdout in code.InteractiveConsole).
Thursday, June 09, 2011
3 IDLE Tips - The Movie
I've managed to make a screencast, giving tips on how to use IDLE.
(Yeah, I know - it sucks, but that's how I learn ... ;)
(Yeah, I know - it sucks, but that's how I learn ... ;)
Sunday, May 29, 2011
avrocat
After playing a bit with simpleavro, I've decided it'll be better done in the Unix tradition of "doing one thing well" and using pipes. Hence avrocat was born, a "cat" like utility for avro files.
EDIT: Seems like avrocat is finding itself into the "avro" package.
usage: avrocat [-h] [-n COUNT] [-s SKIP] [-f {json,csv}] [--header]
[--filter FILTER] [--schema]
filename
`cat` for Avro files
positional arguments:
filename avro file (- for stdin)
optional arguments:
-h, --help show this help message and exit
-n COUNT, --count COUNT
number of records to print
-s SKIP, --skip SKIP number of records to skip
-f {json,csv}, --format {json,csv}
record format
--header print CSV header
--filter FILTER filter records (e.g. r['age']>1)
--schema print schemaEDIT: Seems like avrocat is finding itself into the "avro" package.
Saturday, May 28, 2011
Wednesday, May 18, 2011
Delicous Monkey
Sadly, the official Delicious Firefox addon does not support Firefox 4.
I couldn't find any other addon online the gives me keyboard shortcut for saving the current page in Delicious.
Lucky for me, there is GreaseMonkey. Below is a short script to have CTRL-M save the current page in Delicious.
I couldn't find any other addon online the gives me keyboard shortcut for saving the current page in Delicious.
Lucky for me, there is GreaseMonkey. Below is a short script to have CTRL-M save the current page in Delicious.
Saturday, May 07, 2011
Convert PDF to JPEG
The wife needed a quick and dirty solution to convert PDF files to JPEG. Below is a quick UI (using Tkinter) about ImageMagic's "convert" utility.
Subscribe to:
Posts (Atom)







