tail -f findings.out

Tune MySQL like a pro with MySQLTuner

I don’t know why I didn’t know about this before (or why I forgot about it, more likely), but I came across MySQLTuner recently and was most pleasantly surprised. It’s a Perl script that only requires your MySQL user and password to provide detailed and useful checks of a running MySQL instance. First though, check out the awesome URL you download it at:

1
wget mysqltuner.pl

Yeah, that’s the actual URL that works. Pretty sweet.

Anyway, next you make it executable, run it, enter creds:

Get MySQLTuner running

Then the goodies appear:

MySQLTuner Results

Oh, that query_cache_limit is tiny! At this point, no changes have been made to your setup. But at a glance you get helpful stats, validate that changes you’ve decided to make are in place, and get alerted to potential improvements.

If I knew Perl now and refreshed my MySQL tuning knowledge, I’d love to help as a maintainer of this lovely script. Maybe sometime soon…

Tags: , , ,
March 13, 2010 - 6:22 PM No Comments

A better way to search for methods of Python objects

Python’s introspection abilities are quite extensive and useful. They are also well-documented, so I won’t go into the basics here. Check out this article if you need a good overview. N.B.: discussion and code below applies to both methods and attributes. I will simply refer to “methods” for simplicity.

Beyond simply listing the methods of an object, however, I often find that I want to search through them for something in particular. And eyeballing the output of dir(obj) is only efficient in the simplest of cases. hasattr(obj, “method”) won’t get you far either, as you need to match the “method” name exactly. What if you just have a good guess about the name of a method based on what you need to do? What if you want to know everything you can do with directories in the os module or ISO related methods in datetime.date? I haven’t found anything to help with this sort of problem yet. Approaches like writing a loop to do the search every time or perusing the pertinent API docs are too circuitous for such quick questions. So let’s make a tool to do this more easily!

We start with knowing some object and some string containing all or part of the method(s) we’re interested in:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def mf(obj, term):
    """
    Searches through the methods and attributes defined for obj,
    looks for those containing the term passed.
    Returns all matches or a warning if none found.
    """

    meths = dir(obj)
    match_meths = []
    for meth in meths:
        if meth.rfind(term) != -1:
            match_meths.append(meth)
    if match_meths:
        print match_meths
    else:
        print "No matches!"

This simply iterates over the methods and attributes defined for the object passed and looks for the term passed within the name of each. rfind returns the highest index of the substring passed in the string it’s called on and returns -1 if no match is found. Once the matches are collected they are printed out. An example:

1
2
3
4
>>>from method_finder import mf
>>>import os
>>>mf(os, "dir")
['chdir', 'curdir', 'fchdir', 'listdir', 'makedirs', 'mkdir', 'pardir', 'removedirs', 'rmdir']

For convenience let’s make it available on the Python interactive prompt at every load without any extra effort. This is easy enough using a .pythonstartup file. This file can be used to load various useful items like tab completion for interactive Python sessions. If you haven’t used it before, you’ll need to add the following to your .bashrc:

1
export PYTHONSTARTUP="$HOME/.pythonstartup"

Then in your home directory create a .pythonstartup file containing something like the following:

1
2
3
4
5
6
7
8
9
10
11
import os
# Adds mf(obj, "str") allowing search for methods matching 'str' on obj
# as well as obinfo(obj) returning lots of info on obj
util_loc = "/home/shuckins/code/code_homerepo/python-programming/utilities"
if os.path.isdir(util_loc):
    import sys
    sys.path.append(util_loc)
    from utils import mf, obinfo
    sys.path.remove(util_loc)
    del sys
del os

You’ll need to change the path specified to wherever you placed utils.py containing the mf() function of course. You can download mine here if you’d like. The del statements are to clean up any trace of this operation once you get to the interactive interpreter. This way you get the added functions without mucking up your namespace.

This also loads in an obinfo(obj) function that I included in the same utils.py file. This is based on the interrogate() function written by Patrick O’Brien in the introspection article mentioned above. My version just adds a check for objects without docstrings and prints more of the docstring:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def obinfo(obj):
    """
    Print useful information about object.

    From http://www.ibm.com/developerworks/library/l-pyint.html
    """

    if hasattr(obj, '__name__'):
        print "NAME:    ", obj.__name__
    if hasattr(obj, '__class__'):
        print "CLASS:   ", obj.__class__.__name__
    print "ID:      ", id(obj)
    print "TYPE:    ", type(obj)
    print "VALUE:   ", repr(obj)
    print "CALLABLE:",
    if callable(obj):
        print "Yes"
    else:
        print "No"
    if hasattr(obj, '__doc__'):
        doc = getattr(obj, '__doc__')
        doc = doc.strip()
        topfive = doc.split('\n')[0:4]
        print "DOC:     ", "\n".join(topfive)
    else:
        print "No docstring. Yell at the author."

It’s fairly useful:

1
2
3
4
5
6
7
8
>>> obinfo(["some", "list"].count)
NAME:     count
CLASS:    builtin_function_or_method
ID:       139922087930696
TYPE:     <type 'builtin_function_or_method'>
VALUE:    <built-in method count of list object at 0x7f422658ef80>
CALLABLE: Yes
DOC:      L.count(value) -> integer -- return number of occurrences of value
Tags: , ,
November 8, 2009 - 5:08 PM Comments (4)

Rapidly set up a MySQL database for testing

Sometimes you just want a database to run some queries against. Any reasonable set of tables with data pertaining to something not terribly complicated will do. Perhaps you have an urge to tease out the intricacies of correlated subqueries, or you need to test some complicated pattern matching functions. MySQL provides a database dump for such recreation, called “world”. The world database contains global population data from Statistics Finland. The data itself is several years old, but it works fine as general test fodder.

Since I normally only use it on my own machines for testing, I’ve found setting it up to be a fixed process. So I created this alias for such situations:

1
2
3
alias setup_world_db="wget -O /tmp/world.sql.gz http://downloads.mysql.com/docs/world.sql.gz && \
gunzip /tmp/world.sql.gz && mysql -u root -p -e 'create database if not exists world;' && \
mysql -u root -p world < /tmp/world.sql && rm /tmp/world.sql"

This pulls down the world database dump, unzips it, creates a DB to hold it, imports it, then removes the temporary files. You’ll be prompted twice for the password of the root MySQL user. You could also alter it to include the password if you are so inclined. Add the above alias line to ~/.bashrc, reload it, and you can have a test DB up and waiting within seconds anytime you want.

Tags: , ,
September 7, 2009 - 11:52 AM Comments (2)

Light at the end of the carpal tunnel: snippets in vim with snipMate

vim_logoI’ve tried a number of snippet plugins for vim, many claiming more and less feature parity with the beloved TextMate. I started using snipMate today, and it is by far my favorite. If you haven’t seen TextMate-like snippets in action, check out this short video. If you weren’t a fan of snippets before, you should be now. They allow you to type a small piece of text that serves to remind you of the purpose and, once triggered, have it be replaced with blocks of text and code of all sorts.

So why choose snipMate for snippets? The main features:

 
  • Easy to use
  • Well documented
  • Lots of snippets out of the box
  • Simple to define your own snippets
  • Easy to convert current TextMate snippets for snipMate use
  • Marks aren’t added into the buffer, so if you change your mind and escape in the middle of finishing the snippet, you don’t have ugly “{<foo>}” placeholders in your code
  • Variables are updated dynamically, so different parts of a snippet related to what you’re typing change as you type
  • <Shift-Tab> goes backwards in the tabbed fields

Many of the other snippet plugins lack one or many of these characteristics, which are all quite valuable.

Setup

  • Download the latest zip file into your ~/.vim directory and unzip it. This will place the plugin files, snippet files, and help files into the right places.
  • Open a new instance of vim and run “:helptags ~/.vim/doc”. This will load snipMate’s help files for vim to access.
  • The next time you open/restart vim you’ll be ready to go.

Conflicts

There’s one fly in this tabular ointment. <Tab> is a popular fellow, so snipMate’s use of it will likely conflict with other completion plugins. Perhaps your language-based code completion (see this post if you haven’t set this up before). In my case, all was good until I opened a Python file, wherein <Tab> after “class”, for example, brought up the word completion pop-up, not the desired snippet.

To get around this, I changed the trigger for code completion to <CTRL+n>, so both sets of functionality can be used. I find snippets more valuable than language completion, so I’d rather it be closer at hand.

Use and examples

To use a snippet, you simply type the appropriate term representing it and press <Tab>. The snippet is then placed at your current location. In many cases, you need to fill out part of the snippet to make it valid code. In these cases, you can simply tab through the locations you need or might want to edit, typing as you go. Once you tab past the last one, you are done.

.html file example, after typing “doct”, <Tab>, “html”, <Tab>, “head”, <Tab>:

HTML file snippets

Then you just type in the title, the rest is complete and indented already. A .py file example, after typing “cl”, <Tab>:

Python snippet example

Roll your own

What really sold me on snipMate was how easy it was to define custom snippets. In some other snippet plugins I tried, the snippets were in a wretched format:

1
2
exec "Snippet get def get_".st."name".et."(self):<CR>return self._".st."name".et."<CR>".st.et
exec "Snippet set def set_".st."name".et."(self, ".st."value".et."):

Not exactly easy on the eye. snipMate, however, is much more flexible. One place to start adding your own is in ~/.vim/snippets/_.snippets. This file is for snippets to be loaded for all filetypes. Here are a few useful ones I added to illustrate:

1
2
3
4
5
6
7
8
snippet date
    `strftime("%Y-%m-%d")`
snippet datetime
    `strftime("%Y-%m-%d %T %Z")`
# My name and email
snippet myinfo
    Author: `g:BASH_AuthorName`
    Email: `g:BASH_Email`

Tabs and newlines can be used without escaping, and you have full access to vimscript. It gets even better once you need to be able to type in certain parts of the snippet:

1
2
3
4
snippet def
    def ${1:fname}(${2:`indent('.') ? 'self' : ''`}):
        """${3:docstring for $1}"""
        ${4:pass}

Each “${NUM}” represents a tab stop. In this example, typing “def” then <Tab> would bring up the snippet, with the cursor placed right after def, ready to be filled in. And the string after “${NUM:” acts as a reminding placeholder. In addition, “$NUM” can be used to refer to the content of previous entries, which allows dependent parts of a snippet to be updated as you type! After “def” and <Tab>, I only typed the function name once:

Example of variable synchronization

Multiple filetypes

One issue I ran into early on was wanting more than one filetype’s snippets available for a single file. In my case, I was editing a file with a .php extension, but it had a lot of HTML in it as well. Since the filetype is determined from the extension, I only had the snippets for PHP. To fix this, I added a file ~/.vim/ftdetect/php.vim, containing:

1
au BufRead,BufNewFile *.php set filetype=php.html

When a file with an extension matching a filename in ftdetect is opened, its filetype can be changed to whatever is desired via a directive like the one above. The dot separating the filetypes allows for multiple formats to be made available at once.

Useful customizations

I’ve been adding more snippets as I’ve needed them. Additions to ~/.vim/snippets/python.snippets:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
snippet sb
    #!/usr/bin/env python
snippet sba
    #!/usr/bin/env python
    """${1}
    """

snippet docs
    """
    File: `Filename('$1.py', 'foo.py')`
    Author: `g:BASH_AuthorName`
    Date: `strftime("%Y-%m-%d %T %Z")`

    Description: ${1}
    """

# Debugging
snippet pdb
    import pdb; pdb.set_trace()

snippet pudb
    import pudb; pudb.set_trace()

And to ~/.vim/snippets/html.snippets:

1
2
3
4
snippet img
    <img src="${1}" alt="${2:Helpful description}" />${3}
snippet p
    <p>${1}</p>

Aside from this, I also changed the names of several of the trigger words. If a needed snippet’s name isn’t intuitive to you, change it! The longer it takes you to recall the shortcut, the closer you are to typing the full form. To customize the terms, open the file appropriate to the language you are working inside of ~/.vim/snippets. Just search for the old term, replace it, save, and the next time you open vim your new trigger will be in place.

Tags: , ,
July 19, 2009 - 8:39 PM Comments (5)

Improved irb configuration

As applies to most new tools I start to use, the time in which I’ve started to learn Ruby has included a fair amount of time improving my general working environment, to make it more suited to the use of a welcome new tool. Aside from seeking out informative and reliable sources of documentation, new useful modules, and additions to my editor to make it more Ruby-friendly, I’ve also sought a more efficient configuration for irb. I discussed irb and how to setup some basic improved config in this recent post.

Commenter Vorian helpfully mentioned that the same effect can be achieved through an .irbrc file. This file can then be placed in a VCS, and in addition having the configuration in one spot is preferable. While seeking information on the configuration options available, I came across a number of additional customizations that have proved quite useful. I took this page’s suggestions mostly verbatim in formulating mine. This page was also helpful. Here’s my current .irbrc, highlights to follow:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# Interactive Ruby console configuration
IRB_START_TIME = Time.now

# Print to yaml format with "y"
require 'yaml'
# Pretty printing
require 'pp'
# Ability to load rubygem modules
require 'rubygems'
# Tab completion
require 'irb/completion'
# Save irb sessions to history file
require 'irb/ext/save-history'

# Not stdlib
require 'map_by_method'
require 'what_methods'
# For printing time in session
require 'duration'
# For coloration
require 'wirble'

# Include line numbers and indent levels:
IRB.conf[:PROMPT][:SHORT] = {
  :PROMPT_C=>"%03n:%i* ",
  :RETURN=>"%s\n",
  :PROMPT_I=>"%03n:%i> ",
  :PROMPT_N=>"%03n:%i> ",
  :PROMPT_S=>"%03n:%i%l "
}

IRB.conf[:PROMPT_MODE] = :SHORT
# Adds readline functionality
IRB.conf[:USE_READLINE] = true
# Auto indents suites
IRB.conf[:AUTO_INDENT] = true
# Where history is saved
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-save-history"
# How many lines to save
IRB.conf[:SAVE_HISTORY] = 1000

# Turn turn on colorization, off other wirble wierdness
Wirble.init(:skip_prompt => true, :skip_history => true)
Wirble.colorize

# Quick benchmarking facility
# Based on rue's irbrc => http://pastie.org/179534
def quick(repetitions=100, &block)
  require 'benchmark'
  Benchmark.bmbm do |b|
    b.report {repetitions.times &block}
  end
  nil
end

# Return only the methods not present on basic objects
class Object
  def interesting_methods
    (self.methods - Object.new.methods).sort
  end
end

# Prints how long the session has been open upon exit
at_exit { puts Duration.new(Time.now - IRB_START_TIME) }

You’ll need to install the following gems (”sudo gem install FOO”): map_by_method, what_methods, duration, and wirble. Most options should be self-explanatory and there’s plenty of commentary.

With this in place, you’ll get tab completion to assist in remembering method names and automatic indentation to make visualizing your code’s structure simpler. Output will be colorized for quicker understanding. Your activity will be recorded for later review, and when you exit you’ll find out how long you were in the session.

irb

The two methods defined are helpers for benchmarking and viewing the methods on an object that are more interesting:

methods

For more information on irb use, check out this section in Programming Ruby.

Tags: , ,
July 18, 2009 - 9:18 PM Comments (2)

« Older Entries

Twitter links powered by Tweet This v1.6.1, a WordPress plugin for Twitter.