
No so small as the calculator, but small enough (120 lines of code).
It can do any Python expression as a formula, support cell reference and ranges.
If it won't be simple, it simply won't be. [Hire me, source code] by Miki Tebeka, CEO, 353Solutions

def f():and you run it, nothing is printed.
print "F"
yield 1
if __name__ == "__main__":
f()
from timeit import TimerOn my machine this gives:
def fast_fib(n):
if n < 2:
return 1
a, b = 1, 1
for i in range(n - 1):
a, b = b, a + b
return b
def slow_fib(n):
if n < 2:
return 1
return slow_fib(n - 1) + slow_fib(n - 2)
INDEX = 20
TIMES = 100
fast_timer = Timer("fast_fib(INDEX)", "from __main__ import fast_fib, INDEX")
slow_timer = Timer("slow_fib(INDEX)", "from __main__ import slow_fib, INDEX")
print "slow:", slow_timer.timeit(TIMES) / TIMES
print "fast:", fast_timer.timeit(TIMES) / TIMES
However sometimes you to send your function some more complex data, plus you don't want to add too much timing code into the top level of your module.
fast: 5.11884689331e-06
slow: 0.00996325016022
def benchmark():
benchmark.index = 20
timer = Timer("fast_fib(benchmark.index)",
"from __main__ import fast_fib, benchmark")
num_runs = 100
print timer.timeit(num_runs) / num_runs
def main(argv=None):
if argv is None:
import sys
argv = sys.argv
from optparse import OptionParser
parser = OptionParser("usage: %prog [options] MESSAGE")
parser.add_option("--benchmark", help="run benchmark",
dest="benchmark", action="store_true", default=0)
opts, args = parser.parse_args(argv[1:])
if opts.benchmark:
benchmark()
raise SystemExit()
if len(args) != 1:
parser.error("wrong number of arguments") # Will exit
# Do main program stuff here
try:
print fast_fib(int(args[0]))
except ValueError:
raise SystemExit("error: %s - bad number" % args[0])
if __name__ == "__main__":
main()
===========
Hello World
===========
:Author: Miki Tebeka <miki@mikitebeka.com>
:Date: $Date: 2007-06-05 21:02:04 -0700 (Tue, 05 Jun 2007) $
.. contents::
Chapter 1
=========
In the beginning ...
Sub Chapter 1
-------------
There was LaTex_ [#]_
Chapter 2
=========
And then there was reST_
::
That can have preformatted
text
----
.. _LaTex: http://tug.org
.. _reST: http://docutils.sf.net/rst.html
.. [#] Which is still very good
.. comment: vim: ft=rst spell
%.html: %.txt
rst2html.py --stylesheet style.css $< $@
%.pdf: %.tex
pdflatex $<
%.tex: %.txt
rst2latex.py $< $@
all: hw.html hw.pdf
clean:
rm -f *.aux *.log *.pdf *.html *.out
fresh: clean all
.PHONY: all clean fresh


/*
:Author: Fred L. Drake, Jr.
:date: $Date$
:version: $Revision$
This stylesheet combines some ideas from the two stylesheets
distributed with docutils and enhances them for Zope 3 documentation.
*/
@import url(default.css);
div.document {
margin: 0px 1em 1em 4em;
padding: 0px; }
div.document a {
text-decoration: none; }
div.document a[href] {
text-decoration: underline; }
div.document h1.title {
background-image: url("zope3logo.gif");
background-position: -6px -4px;
background-repeat: no-repeat;
font-size: 150%;
min-height: 50px; }
div.document div.section {
margin: 0px 0px 1.5em 0px; }
div.document div.section h1 {
background-color: rgb(230,230,230);
margin-left: -2em;
padding: 0.2em;
padding-left: 0.35em;
padding-top: 0.35em;
/* This grey underline make this more visually distinctive on LCD
monitors, which often don't have enough contrast. */
border-right: thin solid rgb(180,180,180);
border-bottom: thin solid rgb(180,180,180); }
div.document div.section div.section div.section h3 {
margin-bottom: -0.5em; }
div.document h1 {
font-family: sans-serif;
font-size: 135%; }
div.document h2 {
font-family: sans-serif;
font-size: 120%; }
div.document h3 {
font-family: sans-serif;
font-size: 105%; }
div.document h4 {
font-family: sans-serif;
font-size: 100%; }
div.document h5 {
font-family: sans-serif;
font-size: 100%; }
div.document h6 {
font-family: sans-serif;
font-style: italic;
font-size: 100%; }
div.document hr {
width: 75%; }
div.document .literal .pre {
background-color: white;
font-family: lucidatypewriter, "lucida typewriter", sans-serif; }
div.document .literal-block {
border: thin solid rgb(180,180,180);
font-family: lucidatypewriter, "lucida typewriter", monospace;
font-size: 80%;
padding: 0.5em; }
div.document table.table {
margin-left: 2em;
margin-right: 2em; }
div.document table.table thead {
background-color: rgb(230,230,230); }
/* docutils uses the "option" class with both "col" and "span"
elements, so we have to be explicit here */
div.document .option-list span.option {
font-weight: bold; }
div.document .option-list kbd {
font-family: inherit; }
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date$
:version: $Revision$
:copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
*/
div.document .first {
margin-top: 0 }
div.document .last {
margin-bottom: 0 }
div.document a.toc-backref {
text-decoration: none ;
color: black }
div.document dd {
margin-bottom: 0.5em }
div.document div.abstract {
margin: 2em 5em }
div.document div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.document div.attention,
div.document div.caution,
div.document div.danger,
div.document div.error,
div.document div.hint,
div.document div.important,
div.document div.note,
div.document div.tip,
div.document div.warning,
div.document div.admonition {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.document div.attention p.admonition-title,
div.document div.caution p.admonition-title,
div.document div.danger p.admonition-title,
div.document div.error p.admonition-title,
div.document div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
div.document div.hint p.admonition-title,
div.document div.important p.admonition-title,
div.document div.note p.admonition-title,
div.document div.tip p.admonition-title,
div.document div.admonition p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.document div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.document div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.document div.figure {
margin-left: 2em }
div.document div.footer,
div.document div.header {
font-size: smaller }
div.document div.sidebar {
margin-left: 1em ;
border: medium outset ;
padding: 0em 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.document div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.document div.system-messages {
margin: 5em }
div.document div.system-messages h1 {
color: red }
div.document div.system-message {
border: medium outset ;
padding: 1em }
div.document div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.document div.topic {
margin: 2em }
div.document h1.title {
text-align: center }
div.document h2.subtitle {
text-align: center }
div.document hr {
width: 75% }
div.document ol.simple, ul.simple {
margin-bottom: 1em }
div.document ol.arabic {
list-style: decimal }
div.document ol.loweralpha {
list-style: lower-alpha }
div.document ol.upperalpha {
list-style: upper-alpha }
div.document ol.lowerroman {
list-style: lower-roman }
div.document ol.upperroman {
list-style: upper-roman }
div.document p.attribution {
text-align: right ;
margin-left: 50% }
div.document p.caption {
font-style: italic }
div.document p.credits {
font-style: italic ;
font-size: smaller }
div.document p.label {
white-space: nowrap }
div.document p.rubric {
font-weight: bold ;
font-size: larger ;
color: darkred ;
text-align: center }
div.document p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
div.document p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
div.document p.topic-title {
font-weight: bold }
div.document pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font-family: serif ;
font-size: 100% }
div.document pre.line-block {
font-family: serif ;
font-size: 100% }
div.document pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em ;
background-color: #eeeeee }
div.document span.classifier {
font-family: sans-serif ;
font-style: oblique }
div.document span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
div.document span.interpreted {
font-family: sans-serif }
div.document span.option {
white-space: nowrap }
div.document span.option-argument {
font-style: italic }
div.document span.pre {
white-space: pre }
div.document span.problematic {
color: red }
div.document table {
margin-top: 0.5em ;
margin-bottom: 0.5em }
div.document table.citation {
border-left: solid thin gray ;
padding-left: 0.5ex }
div.document table.docinfo {
margin: 2em 4em }
div.document table.footnote {
border-left: solid thin black ;
padding-left: 0.5ex }
div.document td,
div.document th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
div.document th.docinfo-name,
div.document th.field-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap }
div.document h1 tt,
div.document h2 tt,
div.document h3 tt,
div.document h4 tt,
div.document h5 tt,
div.document h6 tt {
font-size: 100% }
div.document tt {
background-color: #eeeeee }
div.document ul.auto-toc {
list-style-type: none }
def positive_logic(x):
if x > 2:
y = f(x)
if y < 10:
g = f(y)
if g > 0:
do_cool_stuff(g)
def negative_logic(x):
if x <= 2:
return
y = f(x)
if y >= 10:
return
g = f(y)
if g <= 0:
return
do_cool_stuff(g)
def _build():
from os.path import getmtime, isfile, dirname, join
from sys import executable
from os import system
from setup import DYNLIB, SRC_FILE
MODULE_DIR = dirname(__file__)
def _run(cmd):
return system("(cd \"%s\" && %s) > /dev/null 2>&1" % (MODULE_DIR, cmd))
_full_src = join(MODULE_DIR, SRC_FILE)
_full_dynlib = join(MODULE_DIR, DYNLIB)
if (not isfile(_full_dynlib)) or (getmtime(_full_dynlib) < getmtime(_full_src)):
assert _run("%s setup.py build_ext -i" % executable) == 0, "build error"
_build()
del _build
from _greet import *
from distutils.core import Extension, setup
MODULE_NAME = "_greet"
DYNLIB = MODULE_NAME + ".so"
SRC_FILE = MODULE_NAME + ".c"
if __name__ == "__main__":
setup(ext_modules=[Extension(MODULE_NAME, [SRC_FILE])])
#include <python.h>
#include <stdio.h>
static PyObject *
greet_greet(PyObject *self, PyObject *args)
{
char *name;
if (!PyArg_ParseTuple(args, "s", &name)) {
return NULL;
}
printf("Hello %s\n", name);
return Py_BuildValue("");
}
static PyMethodDef GreetMethods[] = {
{ "greet", greet_greet, METH_VARARGS,
"Print a friendly greeting."
},
{NULL, NULL, 0, NULL} /* Sentinel */
};
PyMODINIT_FUNC
init_greet(void)
{
Py_InitModule("_greet", GreetMethods);
}
#!/usr/bin/env python
import re
# 2007-04-01 11:20
find_time = re.compile(
"(?P<year>\d{4})" # 4 digit year
"-"
"(?P<month>\d{2})" # 2 digit month
"-"
"(?P<day>\d{2})" # 2 digit day
"\s+" # white space(s)
"(?P<hour>\d{2})" # 2 digit hour
":"
"(?P<minute>\d{2})" # 2 digit minute
).search
match = find_time("The exact time is 2007-04-01 11:20.")
assert match, "can't find time"
print "MONTH: %s" % match.group("month")
from urllib import urlopen
import re
import webbrowser
W3_URL = "http://www.w3.org/TR/WD-html40-970708/sgml/entities.html"
FILE_NAME = "/tmp/html-entities.html"
find_entity = re.compile("!ENTITY\s+([A-Za-z][A-Za-z0-9]+)").search
fo = open(FILE_NAME, "wt")
print >> fo, "<html><body><table border=\"1\">"
for line in urlopen(W3_URL):
match = find_entity(line)
if match:
entity = match.groups()[0]
print >> fo, "<tr><td>%s</td><td>&%s;</td></tr>" % (entity, entity)
print >> fo, "</table></body></html>"
fo.close()
webbrowser.open(FILE_NAME)
#!/usr/bin/env python
from cgi import FieldStorage
from myapp import do_something_with_data
ERROR = "<html><body>Error: %s</body></html>"
def main():
print "Content-Type: text/html"
print
form = FieldStorage()
data = form.getvalue("data", "")
key = form.getvalue("key", "").strip()
if not (key and data):
raise SystemExit(ERROR % "NO 'key' or 'data'")
try:
do_something_with_data(key, data)
except Exception, e:
raise SystemExit(ERROR % e)
print "<html><body>OK</body></html>"
if __name__ == "__main__":
main()
#!/usr/bin/env python
from urllib import urlopen, urlencode
CGI_URL = "http://localhost:8080/load.cgi"
def push_data(key, data):
query = urlencode([("data", data), ("key", key)])
try:
urlopen(CGI_URL, query).read()
except IOError, e:
pass # FIXME: Handle error
def main(argv=None):
if argv is None:
import sys
argv = sys.argv
from optparse import OptionParser
from os.path import isfile, basename
parser = OptionParser("usage: %prog FILENAME")
opts, args = parser.parse_args(argv[1:])
if len(args) != 1:
parser.error("wrong number of arguments") # Will exit
filename = args[0]
if not isfile(filename):
raise SystemExit("error: can't find %s" % filename)
key = basename(filename)
data = open(filename, "rb").read()
push_data(key, data)
if __name__ == "__main__":
main()
from collections import defaultdictOr, if you want to store the location of the words as well
def histogram(text):
histogram = defaultdict(int) # int() -> 0
for word in text.split():
histogram[word] += 1
return histogram
def histogram(text):
histogram = defaultdict(list) # list() -> []
for location, word in enumerate(text.split()):
histogram[word].append(location)
return histogram

#!/usr/bin/env pythonOur HTML page is very simple, note that:
import simplejson
from random import randint
print "Content-Type: text/plain"
low, high = 0, 100
data = {
"A" : randint(low, high),
"B" : randint(low, high),
}
print simplejson.dumps(data)
<html>What's left is our little script:
<head>
<title>pythonwise - MochiKit Demo
<!-- Load MochiKit -->
<script type="text/javascript" src="/MochiKit/MochiKit.js">
<!-- Load our script -->
<script type="text/javascript" src="/values.js">
</title>
<!-- Have some style -->
<style>
table {
background-color: lightskyblue;
border-style: solid;
border-width: 5px;
width: 20%;
text-align: center;
}
td {
text-align: center;
font-family: Courier, monospace;
font-size: 40px;
}
</style>
</head>
<body>
<center>
<h1>pythonwise - MochiKit Demo
<div class="content">
<!-- Just a simple table with the values we want to show -->
<table>
<tr>
<td>A
<td id="A">???
</tr>
<tr>
<td>B
<td id="B">???
</tr>
</table>
</div>
<hr width="20%" />
A MochiKit demo from
<a href="http://pythonwise.blogspot.com">pythonwise, by
<a href="mailto:miki.tebeka@gmail.com">Miki
</center>
</body>
</html>
function connection_error () {
alert("Connection Error!");
}
function process_values(data) {
/* Even JavaScript has some introspection */
for (key in data) {
var new_value = data[key];
var color = "black"; /* No chage color */
var element = getElement(key);
var last_value = parseInt(element.innerHTML);
if (last_value == NaN) { /* First time */
color = "black";
}
else if (new_value > last_value) {
color = "green";
}
else if (new_value < last_value) {
color = "red";
}
/* Change to new value */
element.innerHTML = new_value;
element.normalize()
element.style["color"] = color;
}
/* Wait 3 seconds and refresh again */
callLater(3, get_updates);
}
function get_updates() {
var data = loadJSONDoc("get_values.cgi");
data.addCallbacks(process_values, connection_error);
}
/* Call get_updates when window is loaded */
connect(window, "onload", get_updates);
# lighhtpd configuration file, see http://trac.lighttpd.net/trac/wiki/Docs for
# more information
server.modules = (
"mod_access",
"mod_cgi",
)
server.document-root = "/home/mtebeka/mochikit-demo"
server.port = 8080
# .html is HTML
mimetype.assign = ( ".html" => "text/html" )
# Look for index.html
index-file.names = ( "index.html" )
# .cgi are not static
static-file.exclude-extensions = ( ".cgi" )
# Use Python to run CGI scripts
cgi.assign = ( ".cgi" => "/usr/local/bin/python" )
That's it, I hope that next time you'll consider AJAX - it's not that hard :)
>>> from functools import partial
>>> import re
>>> remove_prefix = partial(re.compile("prefix: ").sub, "")
>>> remove_prefix("prefix: hello")
'hello'
>>> remove_prefix("hello")
'hello'
>>>
#!/bin/bash
# Get changes from mirrord subversion repository
# Miki Tebeka
case $# in
0 ) up=1; project=`basename $PWD`;;
1 ) up=0; project=$1;;
* ) echo "usage: `basename $0` [PROJECT_NAME]"; exit 1;;
esac
echo "Project is $project"
svk info //$project > /dev/null
if [ $? -ne 0 ]; then
echo "error: bad project - $project"
exit 1
fi
svk sync //$project/mirror
if [ $? -ne 0 ]; then
exit $?
fi
svk smerge --incremental -l //$project/mirror //$project/local
if [ $? -ne 0 ]; then
exit $?
fi
if [ $up == 1 ]; then
svk up
extra=""
else
extra="Don't forget to run 'svk up'"
fi
echo
echo "Done. $extra"
#!/bin/bashNotes:
# Push changes to mirrord subversion repository
# Miki Tebeka
USAGE="usage: `basename $0` [-m comment] [PROJECT]"
COMMENT=""
while getopts "m:h" opt
do
case $opt in
m ) COMMENT=$OPTARG;;
h ) echo $USAGE; exit;;
* ) echo "error: unrecognized option -$opt"; exit 1;;
esac
done
shift $(($OPTIND - 1))
case $# in
0 ) up=1; project=`basename $PWD`;;
1 ) up=0; project=$1;;
* ) echo $USAGE; exit 1;;
esac
echo "Project is $project"
svk info //$project > /dev/null
if [ $? -ne 0 ]; then
echo "error: bad project - $project"
exit 1
fi
svk sync //$project/mirror
if [ $? -ne 0 ]; then
exit $?
fi
if [ "$COMMENT" == "" ]; then
svk smerge //$project/local //$project/mirror
else
svk smerge -m "$COMMENT" //$project/local //$project/mirror
fi
if [ $? -ne 0 ]; then
exit $?
fi
echo
echo "Done."
from os import environIf you're using Python, you can just write from root import ROOT_DIR, however if you're using bash you can write ROOTDIR=`./root.py` and then use $ROOTDIR
from os.path import join
from getpass import getuser
if "DEBUG" in environ:
# Every user has his/her own test root directory
ROOT_DIR = join("/tmp", "testing", getuser())
else:
ROOT_DIR = "/usr/local/cool"
if __name__ == "__main__":
print ROOT_DIR