<?xml version='1.0' encoding='utf-8' ?>
<!--  If you are running a bot please visit this policy page outlining rules you must respect. http://www.livejournal.com/bots/  -->
<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/' xmlns:media='http://search.yahoo.com/mrss/' xmlns:atom10='http://www.w3.org/2005/Atom'>
<channel>
  <title>C. Scott Ananian</title>
  <link>http://cananian.livejournal.com/</link>
  <description>C. Scott Ananian - LiveJournal.com</description>
  <lastBuildDate>Sat, 07 Feb 2009 08:33:01 GMT</lastBuildDate>
  <generator>LiveJournal / LiveJournal.com</generator>
  <lj:journal>cananian</lj:journal>
  <lj:journalid>123187</lj:journalid>
  <lj:journaltype>personal</lj:journaltype>
  <atom10:link rel='hub' href='http://pubsubhubbub.appspot.com/' />
  <image>
    <url>http://l-userpic.livejournal.com/11312513/123187</url>
    <title>C. Scott Ananian</title>
    <link>http://cananian.livejournal.com/</link>
    <width>100</width>
    <height>100</height>
  </image>

<item>
  <guid isPermaLink='true'>http://cananian.livejournal.com/54572.html</guid>
  <pubDate>Sat, 07 Feb 2009 08:33:01 GMT</pubDate>
  <title>JDoctest!</title>
  <link>http://cananian.livejournal.com/54572.html</link>
  <description>&lt;p&gt;The Python &lt;a href=&quot;http://docs.python.org/lib/module-doctest.html&quot;&gt;doctest&lt;/a&gt; module is really great: it makes it easy to simultaneously write test suites and demonstrate the usage for your modules.  Python&apos;s interactive interpreter is key to its coolness: it&apos;s really easy to load the code you&apos;re working on, type some examples at the prompt, and turn the session into documentation and a test case.&lt;/p&gt;
&lt;p&gt;I&apos;ve been dusting off my &lt;a href=&quot;http://cscott.net/Projects/SDR/&quot;&gt;Square Dance Revolution&lt;/a&gt; project, written in Java, and I thought: gee, it would be nice to use doctests here.  A bit of inspiration from &lt;a href=&quot;http://code.google.com/p/doctestj/&quot;&gt;doctestj&lt;/a&gt; and &lt;a href=&quot;http://blog.norrisboyd.com/2008/03/doctest-in-rhino.html&quot;&gt;Rhino&lt;/a&gt;, and a bit of elbow grease and: voila!  &lt;a href=&quot;http://cscott.net/Projects/JDoctest/&quot;&gt;JDoctest is born!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://cscott.net/Projects/JDoctest/&quot;&gt;JDoctest&lt;/a&gt; is a Javadoc plugin which implements doctests by calling out to the Rhino javascript interpreter.  Rhino&apos;s interactive javascript session makes Java as fun to program in / debug / test as Python is.  (Rhino makes it &lt;a href=&quot;http://www.mozilla.org/rhino/ScriptingJava.html&quot;&gt;easy to call between Javascript and Java&lt;/a&gt;.) Copy and paste those examples into javadoc comments, add a &lt;code&gt;@doc.test&lt;/code&gt; tag, and you&apos;ve got a test / use case example.  I&apos;ve added hooks to &lt;a href=&quot;http://code.google.com/p/google-code-prettify/&quot;&gt;google-code-prettify&lt;/a&gt; to make the output beautiful, too.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://cscott.net/Projects/JDoctest/jdoctest-latest/api/net/cscott/jdoctest/JDoctest.html&quot;&gt;Here&apos;s a simple example&lt;/a&gt; using JDoctest, and the SDR sources are now filled with more complex examples (for &lt;a href=&quot;http://cscott.net/Projects/SDR/sdr-latest/doc/net/cscott/sdr/calls/package-summary.html#package_description&quot;&gt;example&lt;/a&gt;). (New SDR release soon, I promise.)  Enjoy!&lt;/p&gt;</description>
  <comments>http://cananian.livejournal.com/54572.html</comments>
  <category>sdr</category>
  <category>jdoctest</category>
  <category>java</category>
  <category>doctest</category>
  <category>python</category>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://cananian.livejournal.com/52847.html</guid>
  <pubDate>Sat, 03 Jan 2009 05:09:46 GMT</pubDate>
  <title>xkcd and shut-the-box</title>
  <link>http://cananian.livejournal.com/52847.html</link>
  <description>&lt;p&gt;An xkcd comic from a while ago mentioned a &quot;&lt;a href=&quot;http://xkcd.com/c287.html&quot;&gt;knapsack problem&lt;/a&gt;,&quot; and one reader (dhogarty) &lt;a href=&quot;http://www.flyingsymbols.com/2007/11/06/recursive-generators-multisets-and-randall-munroe/&quot;&gt;wrote some set enumeration code&lt;/a&gt; to tackle it.&lt;/p&gt;

&lt;p&gt;Before I go further, I should mention that &lt;a href=&quot;http://www-cs-staff.stanford.edu/~uno/taocp.html&quot;&gt;Knuth&lt;/a&gt; is the definitive reference here (as in most things), in particular Volume 4 which is now available only in fascicle form.  If you haven&apos;t been reading the pre-fascicles just as soon as they&apos;re posted on the TAOCP web page, you&apos;re a sad sorry person who doesn&apos;t deserve to be called a computer scientist.  (If you&apos;re not a computer scientist, read at least fascicle 4&apos;s chapter on &lt;a href=&quot;http://www-cs-staff.stanford.edu/~uno/fasc4b.ps.gz&quot;&gt;the history of combinatorics&lt;/a&gt;; you can buy a hardcopy from &lt;a href=&quot;http://www.amazon.com/exec/obidos/ISBN=0321335708/cscottananianA/&quot;&gt;amazon&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;The xkcd problem is called a &quot;knapsack problem&quot;, but it&apos;s not, really; see Knuth&apos;s commentary around Algorithm F of 7.2.1.3 (vol 4 fascicle 3a).  We&apos;re generating multicombinations of n items taken from the m appetizers (repetition permitted).  It&apos;s always worthwhile generating your options in strict lexicographic order to get a handle on duplicates; consult the history of combinatorics cited above for cautionary tales.&lt;p&gt;

&lt;p&gt;A compact way to generate multicombinations without duplicates is simply to require the output to be in lexicographic (sorted) order.  For example, tweaking dhogarty&apos;s code only slightly:&lt;/p&gt;
&lt;pre&gt;
def all_seqs(size, alphabet):
   for n,c in zip(xrange(len(alphabet)), alphabet):
     for s in all_seqs(size-1, alphabet[n:]) if size&amp;gt;1 else [[]]:
       yield [c]+s

&lt;/pre&gt;
&lt;p&gt;You can wrap this in an iteration of sizes from 0 to infinity to generate multicombinations of all possible cardinalities.&lt;/p&gt;

&lt;p&gt;A more elegant solution only generates multicombinations which sum properly (this is similar to Knuth&apos;s Algorithm F):&lt;/p&gt;

&lt;pre&gt;
def ways_to_sum(total, menu):
    if total &amp;lt; 0: return
    if total == 0: yield []
    for (item,price),n in zip(menu, xrange(len(menu))):
        for tail in ways_to_sum(total-price, menu[n:]):
            yield [ item ] + tail

menu = [(&apos;Fruit&apos;, 215), (&apos;Fries&apos;, 275),
        (&apos;Salad&apos;, 335), (&apos;Wings&apos;, 355),
        (&apos;Sticks&apos;, 420), (&apos;Sampler&apos;, 580)]

for solution in ways_to_sum(1505, menu):
    print solution

&lt;/pre&gt;

&lt;p&gt;It&apos;s regrettable that the solution isn&apos;t unique.  Bad Randall.&lt;/p&gt;

&lt;p&gt;I&apos;ve found lots of opportunities to generate &quot;all possible solutions&quot; in various contexts, and Python&apos;s generators have generally been an elegant means to express solutions.  For example, I&apos;ve been discussing &lt;a href=&quot;http://cananian.livejournal.com/tag/shut+the+box&quot;&gt;&quot;Shut the Box&quot;&lt;/a&gt;; here&apos;s some code fragments to generate all possible plays for some board state:&lt;/p&gt;

&lt;pre&gt;
def ways_to_sum(total, min_digit=1, max_digit=9):
    &quot;&quot;&quot;Generate all the ways to sum to the given total using the digits
    `min` through `max` without repetitions.
    By default min and max are 1 and 9, respectively.

    &amp;gt;&amp;gt;&amp;gt; list(ways_to_sum(1))
    [[1]]
    &amp;gt;&amp;gt;&amp;gt; list(ways_to_sum(2))
    [[2]]
    &amp;gt;&amp;gt;&amp;gt; list(ways_to_sum(3))
    [[1, 2], [3]]
    &amp;gt;&amp;gt;&amp;gt; list(ways_to_sum(12))
    [[1, 2, 3, 6], [1, 2, 4, 5], [1, 2, 9], [1, 3, 8], [1, 4, 7], [1, 5, 6], [2, 3, 7], [2, 4, 6], [3, 4, 5], [3, 9], [4, 8], [5, 7]]
    &quot;&quot;&quot;
    for first in xrange(min_digit, min(max_digit+1, total)):
        for tail in ways_to_sum(total-first, min_digit=first+1, max_digit=max_digit):
            yield [ first ] + tail
    if min_digit &amp;lt;= total and total &amp;lt;= max_digit:
        yield [ total ]

def all_states(min_digit=1):
    &quot;&quot;&quot;Generate all possible shut-the-box states.&quot;&quot;&quot;
    if min_digit &amp;lt;= 9:
        for x in all_states(min_digit=min_digit+1):
            yield x
            yield [min_digit] + x
    else:
        yield []

&lt;/pre&gt;

&lt;p&gt;The all_states() function generates the states in lexicographic order based on the set&apos;s binary representation (a9 a8 a7 ... a2 a1, to use Knuth&apos;s notation).&lt;/p&gt;

&lt;p&gt;
[This was originally going to be a comment on &lt;a href=&quot;http://www.flyingsymbols.com/2007/11/06/recursive-generators-multisets-and-randall-munroe/&quot;&gt;dhogarty&apos;s post&lt;/a&gt;, but after writing it I discovered that dhogarty had broken his wordpress installation sometime after 12 Sep 2008.  I reverse-engineered the &lt;a href=&quot;http://wordpresssupplies.com/wordpress-plugins/captcha-free/&quot;&gt;&quot;Captcha-free&quot;&lt;/a&gt; spam protection and fixed the Ajax URL in his page, but no dice.  Querying the &quot;Captcha-free&quot; implementation with a python one-liner and performing a manual submission still loses.  Maybe trackback will work.] &lt;/p&gt;</description>
  <comments>http://cananian.livejournal.com/52847.html</comments>
  <category>knuth</category>
  <category>shut the box</category>
  <category>xkcd</category>
  <category>python</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://cananian.livejournal.com/52530.html</guid>
  <pubDate>Tue, 09 Dec 2008 23:24:00 GMT</pubDate>
  <title>Pippy.  And Winnie-the-Pooh.</title>
  <link>http://cananian.livejournal.com/52530.html</link>
  <description>&lt;p&gt;In October, &lt;a href=&quot;http://blogs.law.harvard.edu/sj/&quot;&gt;SJ&lt;/a&gt; and I travelled to Peru for &lt;a href=&quot;http://blog.laptop.org/&quot;&gt;OLPC&lt;/a&gt;.  (Ob. Plug: buy a &lt;a href=&quot;http://laptop.org/xo&quot;&gt;G1G1&lt;/a&gt; machine this holiday season!  It helps get laptops to needy kids &lt;i&gt;and&lt;/i&gt; helps fund us to develop more and better software for those kids.)&lt;/p&gt;

&lt;p&gt;Anyway, my favorite story from our time in Peru was when SJ stood up in front of a classroom of &lt;a href=&quot;http://www.usmp.edu.pe/&quot;&gt;university&lt;/a&gt; kids and announced, in Spanish, &quot;Now we are going to make drawings with pee-pee.&quot;  He actually was talking about &lt;a href=&quot;http://wiki.laptop.org/go/Pippy&quot;&gt;Pippy&lt;/a&gt;, the python-programming-for-kids activity written by &lt;a href=&quot;http://blog.printf.net/&quot;&gt;Chris Ball&lt;/a&gt; (with patches from yours truely and others) -- but there&apos;s a reason why Pippy is translated &quot;Peppy&quot; in Spanish =).&lt;/p&gt;

&lt;p&gt;But I&apos;ve found another contender for that crown: a &lt;a href=&quot;http://www.ironicsans.com/2007/10/best_book_title_ever.html&quot;&gt;cookbook&lt;/a&gt;.  Best book title ever.  (David Friedman not only found that book, he made it an &lt;a href=&quot;http://www.ironicsans.com/2007/12/bookstore_befuddlement.html&quot;&gt;&quot;employee pick&quot;&lt;/a&gt; when working at a &quot;large chain bookstore&quot;.)&lt;/p&gt;

&lt;p&gt;So.  Pippy and Winnie-the-Pooh.  Closing a scatological circle.&lt;/p&gt;

&lt;p&gt;(While I&apos;m in the neighborhood, I have to plug David Friedman&apos;s &lt;a href=&quot;http://www.ironicsans.com/2008/11/murder_in_the_hundred_acre_woo.html&quot;&gt;Murder in the Hundred Acre Wood&lt;/a&gt; as well.  And &lt;a href=&quot;http://www.ironicsans.com/2008/09/10_lessons_from_the_movies.html&quot;&gt;10 Lessons from the Movies&lt;/a&gt;.  Ok, go resume your productive lives now.)&lt;/p&gt;</description>
  <comments>http://cananian.livejournal.com/52530.html</comments>
  <category>winnie-the-pooh</category>
  <category>olpc</category>
  <category>david friedman</category>
  <category>pippy</category>
  <category>python</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://cananian.livejournal.com/51991.html</guid>
  <pubDate>Tue, 09 Dec 2008 19:25:14 GMT</pubDate>
  <title>Monkeys!</title>
  <link>http://cananian.livejournal.com/51991.html</link>
  <description>Dilinger pointed me at an amusing &lt;a href=&quot;http://www.b-list.org/weblog/2008/dec/05/python-3000/&quot;&gt;anecdote about monkeys&lt;/a&gt; leading off an essay about Python 3.0 (you can skip the Python parts if you&apos;re not interested in that stuff).  I wonder to what degree some of OLPC&apos;s long-running software gun battles are over monkey-and-the-fire-hose sort of stuff.  Since I imagine myself on the &quot;good guys&quot; side most of the time (part of having healthy self respect, etc) I like to think of some of the objections I hear to proposed refactorings as being &quot;attacked by the old monkeys&quot; -- but, to be honest, I&apos;m sure there are large parts of Sugar which I like which are just &quot;how it&apos;s always been done&quot;, and I&apos;m probably as guilty of being an &quot;old monkey&quot; as others.</description>
  <comments>http://cananian.livejournal.com/51991.html</comments>
  <category>olpc</category>
  <category>monkeys</category>
  <category>python</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>http://cananian.livejournal.com/48301.html</guid>
  <pubDate>Wed, 05 Nov 2008 17:45:31 GMT</pubDate>
  <title>Binding python to v8</title>
  <link>http://cananian.livejournal.com/48301.html</link>
  <description>Google&apos;s v8 virtual machine (part of Chrome) is really great, from a virtual-machine-implementer&apos;s perspective.  It would be a fantastic backend for Python, because of the way that object mutation and method dispatch is handled.  I thought of hacking together a proof-of-concept, but decided that my work at OLPC wasn&apos;t really benefited by my going off to spend a year writing a fast Python runtime.&lt;br /&gt;&lt;br /&gt;Luckily, I don&apos;t have to: &lt;a href=&quot;http://www.advogato.org/article/985.html&quot;&gt;pyv8&lt;/a&gt; is a proof-of-concept implementation of just such a thing!  And it&apos;s ten times faster than standard interpreted Python -- although it should be noted that this is for a strictly toy benchmark.&lt;br /&gt;&lt;br /&gt;What&apos;s missing is bypassing pyjamas and working directly from python bytecode, and a better attempt at providing python standard library support.  Hopefully other bright minds are hard at work on this!</description>
  <comments>http://cananian.livejournal.com/48301.html</comments>
  <category>olpc</category>
  <category>v8</category>
  <category>python</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
</channel>
</rss>
