/timm's /charming /python /tricks
by tim@menzies.us
January'14.
Doco:
HTML |
Markdown.
Code:
Python |
with highlighting |
zipped.
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.
Recall the above manta:
So, starting at the very beginning to describe how I made CHARMING delightful.
CHARMING's code is stored in this repository (and when I get time, I'll jump it to Github).
To download CHARMING:
svn export http://unbox.org/open/trunk/472/14/spring/src
Once you get the CHARMING code, you should store it in some on-line source code management system where:
Once the CHARMING files are unpacked into a directory, check the installation, using
python demo.py demo
. If nothing crashes, you are good to go.
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.
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.
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.
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:
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.
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.
A Model
contains:
valid
predicate that checks if the decisions
are permissable.score
function reports the
objectives achieved by those decisionsscore
(decisions).(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 Num
s is to divide the seen values into some
number of equal-sized bins
.
Using the learned distribution, we can:
sample
method to return a generator for
values from that distribution.centroid
method to return the expected
value of that population. Sym
's centroid is the most common symbol.Num
's centroid is the mean value.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
pos
: some index into the list of decisions and objectives.name
: the name 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.