/timm's /charming /python /tricks

How to be Charming (in Python)

by tim@menzies.us
January'14.

Doco: HTML | Markdown.
Code: Python | with highlighting | zipped.


Good Code is Charming Code

I hate bad Python code- twisted, bloated, contorted, etc, etc. Such code truly resembles a python- a sinister shapes that slithers into my nightmares, sending shivers down my spine.

So how to write good code? I say that good code is charming code; i.e. it is a delightful piece of magic. How can we be charming in Python? The definition of charm tells us that this is really two problems. We must:

This code base, called CHARMING, was written, very quickly, for WVU's spring 2014 AI subject. At the very least, CHARMING illustrates some the Python tricks I've learned over the years. And, at most, CHARMING might become a laboratory which results in some new and interesting optimizers. We'll see.


Write to Delight

Recall the above manta:

So, starting at the very beginning to describe how I made CHARMING delightful.

Easy to Access

CHARMING's code is stored in this repository (and when I get time, I'll jump it to Github).

To download CHARMING:

Easy to Share

Once you get the CHARMING code, you should store it in some on-line source code management system where:

Easy to Install

Once the CHARMING files are unpacked into a directory, check the installation, using

If nothing crashes, you are good to go.

Easy to Read

Ideally, code can be included in two-column documentation and/or as some on-line html format (by the way, for the html-ized version of this code, see here).

So, when writing code:

This convention forces you to divide your code into lots of short, sharp ideas. Here are some tips to work in the above constraints:

One thing is to minimize the use of globals and, what globals you have, are clearly defined in one quick-to-find location.

Another technique to improve readability is to offer lots of examples of your running code. Hence, CHARMING contains many demo functions that show people how to run by code. Those demos are divided into layers (demo0, demo1, demo2,..., demo7) and I recommend that people try to read and understand demoi before reading demoi+1.

For more on that demo system, see the @demo code in demo.py.

Easy to Run

CHARMING includes a quick tool for running specific Python functions from the command-line (and that tool knows to compile number strings to numbers.

For more on that demo system, see the cmd code in demo.py.

Easy to Test

Finally, CHARMING includes a test suite tool. Functions annotated with @test are expected to return a list of (want,got) pairs. The test suite counts how many times want == got, in all the test functions.

For more on that test system, see the @test code in demo.py.


Bring the Magic

So now we can write delightfully CHARMING code, it is time to add the magic.

CHARMING offers support for stochastic optimizers. These are tools that are useful for exploring a space of competing objectives by trying random choices. If this sounds odd to you then you, then please recall that there are two definitions of random:

  1. Random = crazy i.e. having no specific pattern, purpose, or objective;
  2. Random = directed i.e. events biased by some probability distribution.

Note that, in the second case, if we knew the distribution associated with preferred behavior, then we could bias our tries by that distribution (in which case the random tries would actually be the informed choice).

There are many other reason to use random search. For one thing, a little random jiggling can let a search escape from sub-optimal cul de sacs. For another, random search can finds short-cuts that lead to good solutions, faster than complete search.

Classes

In this text, any word in CamelCase typewriter font is a class in the CHARMING system. The CHARMING classes are listed below. For full details, see below, but they are listed them here just to lay some groundwork.

Charmed  : super-class of all
  About  : what we know about columns
    Num  : distributions of numbers with min and max values
    Sym  : distributions of symbols
  Row    : place to store prior random guesses
  Sample : helper, keeps a random sample
  Thing  : helper, a thing with labeled fields
  Table  : holds what we know About the Rows
  Model   : guesses decisions, scores objectives.

Some Details

A Model contains:

(Aside: in this description, anything in the mono font is an actual CHARMING class of method.

Here are some details. To make some decisions, CHARMING needs to know About the space of legal values for each decision. For that, CHARMING used Num and Sym objects to define legal ranges for numerics or discrete variables. These objects can learn distributions by passing them data from some population (using the seen(x) method).

After learning that distribution we can normalized Num values using the norm method. Recall that normalization maps a numerics into some position 0 to 1 from min to max (for the sake of completeness, Sym also respond to norm, but just returns the passed value unmodified). Another thing we can do with Nums is to divide the seen values into some number of equal-sized bins.

Using the learned distribution, we can:

To explore a Model, we generate many candidates and store the observed information in a Table.

CHARMING uses For example, suppose we have made three guesses, then filled in their associated objective scores. Suppose further that the at (in this example) columns 1,2,3 (for decisions) and (4,5) for objectives.

Each position is one column CHARMING holds

About information in Num and Sym objects.

All the About objects have

Model has many decisions (aka independent variables) marked $ numeric (use Num) ? ignore sym (use Sym) many objectives (aka depedent variables) marked < minimize (use Num) > maximize (use Num) = goal (use Sym)
one Table

Table has many columns


This file is part of Timm's charming Python tricks.
© 2014, Tim Menzies: tim.menzies@gmail.com, http://menzies.us.

Timm's charming Python tricks are free software: you can redistribute it and/or modify it under the terms of the GNU Lesser Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Timm's charming Python tricks are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU Lesser Public License along with Foobar. If not, see http://www.gnu.org/licenses.