Working with one of
my clients (who is hiring BTW), we decided to use Docker as deployment platform. Since many Linux systems
now use Python for many utilities, it''s advisable to install your own Python
next to the system one and use it.
Installing CPython from source requires some system packages, libraries, headers
and some knowledge. The much easier path it to use MiniConda (from the wonderful people at Continuum). Not only the Python installation is super simple,
but also the conda package
manger will get you a lot of packages pre-compiled so you don''t have to install
gcc and header files for C extensions. And if you can''t find the package you
need with conda, pip is also available.
Here''s a little project to demonstrate how to do this. The application is an image server with has two entry points /edge for edge detection
and /resize for image resizing. We''ll be using scikit-image and Pillow for image manipulation and Flask as web server. All of them can be conda installed.
Here''s the Dockerfile for the project. Build with docker build -tag imgsrv,
Run with docker run -p 8080:8080 imgsrv (see Makefile).
If it won't be simple, it simply won't be. [Hire me, source code] by Miki Tebeka, CEO, 353Solutions
Tuesday, April 07, 2015
Tuesday, February 24, 2015
Adding Server SSL Certificate on Linux
Here''s a small script to add a server SSL certificate on Linux. You can
export the certificate from your browser. Inspired by this stackoverflow
post.
Tuesday, February 03, 2015
Logging from Celery to logstash and a structured log (JSON)
I love Celery, and we''re
using it at one of my customers. One thing
we wanted to have is centralized logging, since you can have multiple workers
on multiple machines. We looked at several solutions and the winner came out to
be logstash + kibana
(AKA ELK stack).
Here''s some code to log to logstash with Celery current task information (if available) and also to a structured log (every line is a JSON object) for backup in case of network issues.
Here''s some code to log to logstash with Celery current task information (if available) and also to a structured log (every line is a JSON object) for backup in case of network issues.
Tuesday, January 27, 2015
Using supervisord to Manage You Daemons
Say you have some daemons running. You''d like to restart them automatically
if they fail, grab logs from them and in general manage them - supervisord
will do it all for you.
One of my (super cool) clients needed also to start/stop daemons when configuration changes. The solution was to have a script that updates supervisord.conf every time we have a configuration change and then selectively start/stop on the daemons that have change (by default if your run supervisorctl update, it will restart all the daemons).
For this example, I''ll assume that the daemon processes are python -m SimpleHTTPServer and I have a list of port I''d like to listen on. This list of ports might change.
One of my (super cool) clients needed also to start/stop daemons when configuration changes. The solution was to have a script that updates supervisord.conf every time we have a configuration change and then selectively start/stop on the daemons that have change (by default if your run supervisorctl update, it will restart all the daemons).
For this example, I''ll assume that the daemon processes are python -m SimpleHTTPServer and I have a list of port I''d like to listen on. This list of ports might change.
Example Usage
$ ./updated.py 8000 8001 8002
$ supervisorctl status
httpd-8000 RUNNING pid 31768, uptime 0:00:04
httpd-8001 RUNNING pid 31767, uptime 0:00:04
httpd-8002 RUNNING pid 31766, uptime 0:00:04
$ ./updated.py 8000 8004 8002 # Remove 8001, add 8004
httpd-8001: disappeared
httpd-8004: available
httpd-8001: stopped
httpd-8001: removed process group
httpd-8004: added process group
$ supervisorctl status
httpd-8000 RUNNING pid 31768, uptime 0:00:12
httpd-8002 RUNNING pid 31766, uptime 0:00:12
httpd-8004 RUNNING pid 31785, uptime 0:00:02
$
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.
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
}
]
$ 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:
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:
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.'
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.
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
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:
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
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.
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.
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:
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.
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 :).
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.
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 :)
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).
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.
Subscribe to:
Posts (Atom)







