<?xml version="1.0" encoding="UTF-8"?>
<feed
  xmlns="http://www.w3.org/2005/Atom"
  xmlns:thr="http://purl.org/syndication/thread/1.0"
  xml:lang="en"
   >
  <title type="text">Code Kills</title>
  <subtitle type="text"></subtitle>

  <updated>2012-01-22T21:05:58Z</updated>
  <generator uri="http://blogofile.com/">Blogofile</generator>

  <link rel="alternate" type="text/html" href="http://blog.codekills.net" />
  <id>http://blog.codekills.net/feed/atom/</id>
  <link rel="self" type="application/atom+xml" href="http://blog.codekills.net/feed/atom/" />
  <entry>
    <author>
      <name></name>
      <uri>http://blog.codekills.net</uri>
    </author>
    <title type="html">Fun Little Threading Problem</title>
    <link rel="alternate" type="text/html" href="http://blog.codekills.net/2011/08/26/fun-little-threading-problem" />
    <id>http://blog.codekills.net/2011/08/26/fun-little-threading-problem</id>
    <updated>2011-08-26T20:06:40Z</updated>
    <published>2011-08-26T20:06:40Z</published>
    <category scheme="http://blog.codekills.net" term="Play" />
    <summary type="html">Fun Little Threading Problem</summary>
    <content type="html" xml:base="http://blog.codekills.net/2011/08/26/fun-little-threading-problem">&lt;div class=&#34;document&#34;&gt;
&lt;p&gt;A fun little threading problem I ran into today: imagine a Thermometer which
can issue notifications if the temperature reaches a certain threshold:&lt;/p&gt;
&lt;pre class=&#34;literal-block&#34;&gt;
class Thermometer(object):
    def set_temperature(self, value):
        self.temperature = value

    def wait_for_temperature(self, target):
        # ... wait for `self.temperature` to be at least `target` ...
        return self.temperature
&lt;/pre&gt;
&lt;p&gt;Using only &lt;a class=&#34;reference external&#34; href=&#34;http://www.gevent.org/gevent.event.html#gevent.event.AsyncResult&#34;&gt;AsyncResult&lt;/a&gt;, how can
the &lt;tt class=&#34;docutils literal&#34;&gt;set_temperature&lt;/tt&gt; and &lt;tt class=&#34;docutils literal&#34;&gt;wait_for_temperature&lt;/tt&gt; methods be implemented to
guarantee that multiple threads can &lt;tt class=&#34;docutils literal&#34;&gt;wait_for_temperature&lt;/tt&gt; without missing a
temperature change (only one thread will be call &lt;tt class=&#34;docutils literal&#34;&gt;set_temperature&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;My solution:&lt;/p&gt;
&lt;pre class=&#34;literal-block&#34;&gt;
class Thermometer(object):
    def __init__(self):
        self.temperature_changed = AsyncResult()

    def set_temperature(self, value):
        self.temperature = value
        next_change = AsyncResult()
        self.temperature_changed.set((next_change, value))
        self.temperature_changed = next_change

    def wait_for_temperature(self, target):
        changed = self.temperature_changed
        temperature = self.temperature
        while temperature &amp;lt; target:
            changed, temperature = changed.get()
        return temperature
&lt;/pre&gt;
&lt;p&gt;I originally encountered this problem working on a component at work, but I
enjoyed the solution so I thought I would adapt it and post it here.&lt;/p&gt;
&lt;/div&gt;
</content>
  </entry>
  <entry>
    <author>
      <name>David Wolever</name>
      <uri>http://blog.codekills.net</uri>
    </author>
    <title type="html">Making Settlers of Catan less painful with pity points</title>
    <link rel="alternate" type="text/html" href="http://blog.codekills.net/2011/02/27/making-settlers-of-catan-less-painful-with-pity-points" />
    <id>http://blog.codekills.net/2011/02/27/making-settlers-of-catan-less-painful-with-pity-points</id>
    <updated>2011-02-27T23:02:00Z</updated>
    <published>2011-02-27T23:02:00Z</published>
    <category scheme="http://blog.codekills.net" term="Play" />
    <summary type="html">Making Settlers of Catan less painful with pity points</summary>
    <content type="html" xml:base="http://blog.codekills.net/2011/02/27/making-settlers-of-catan-less-painful-with-pity-points">

&lt;p&gt;If you&#39;ve played Settlers, you know that missing a couple of early-game rolls can be the difference between a win and a painful, boring loss. Pity points[0] help fix that.&lt;/p&gt;
&lt;p&gt;The rules are simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Any time a player doesn&#39;t get any resources from a normal (ie, start-of-the-turn) dice roll, they get one pity point.&lt;/li&gt;
&lt;li&gt;At any time, a player may exchange pity points equal to their number of victory points for one resource.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example: on Alice&#39;s turn, she rolls a 3. Neither Alice nor Bob have a settlement adjacent to a 3, so they both get one pity point. Also on Alice&#39;s turn, Bob trades three pity points (because Bob has three victory points) for one sheep, and trades that sheep to Alice.&lt;/p&gt;
&lt;p&gt;[0]: introduced to me by &lt;a href=&#34;http://www.fraserharris.com/&#34;&gt;Fraser Harris&lt;/a&gt; — thanks!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <author>
      <name>David Wolever</name>
      <uri>http://blog.codekills.net</uri>
    </author>
    <title type="html">Lightroom: Export a List of Pictures in a Catalog</title>
    <link rel="alternate" type="text/html" href="http://blog.codekills.net/2010/09/12/lightroom--export-a-list-of-pictures-in-a-catalog" />
    <id>http://blog.codekills.net/2010/09/12/lightroom--export-a-list-of-pictures-in-a-catalog</id>
    <updated>2010-09-12T16:52:00Z</updated>
    <published>2010-09-12T16:52:00Z</published>
    <category scheme="http://blog.codekills.net" term="Play" />
    <summary type="html">Lightroom: Export a List of Pictures in a Catalog</summary>
    <content type="html" xml:base="http://blog.codekills.net/2010/09/12/lightroom--export-a-list-of-pictures-in-a-catalog">

&lt;p&gt;I recently had to export all the names of images in a Lightroom catalog. There was no obvious way of doing this through the Lightroom interface, so I threw together a little Python script that directly reads Lightroom&#39;s SQLite database.  There are a few caveats, noted in the file (below)… But it worked pretty well for me, and hopefully other people will find it useful too.&lt;/p&gt;

&lt;!-- EXTENDED BODY --&gt;
&lt;a id=&#34;extended&#34;&gt;&lt;/a&gt;&lt;script src=&#34;http://gist.github.com/576234.js?file=lr_export_catalog&#34;&gt;&lt;/script&gt;
</content>
  </entry>
  <entry>
    <author>
      <name>David Wolever</name>
      <uri>http://blog.codekills.net</uri>
    </author>
    <title type="html">How to Beat SimTower</title>
    <link rel="alternate" type="text/html" href="http://blog.codekills.net/2009/03/15/how-to-beat-simtower" />
    <id>http://blog.codekills.net/2009/03/15/how-to-beat-simtower</id>
    <updated>2009-03-15T20:32:00Z</updated>
    <published>2009-03-15T20:32:00Z</published>
    <category scheme="http://blog.codekills.net" term="Play" />
    <summary type="html">How to Beat SimTower</summary>
    <content type="html" xml:base="http://blog.codekills.net/2009/03/15/how-to-beat-simtower">

&lt;p&gt;SimTower -- we&#39;ve all played it, many of us have loved it, none of us have beat
it.&lt;/p&gt;
&lt;p&gt;Until now.&lt;/p&gt;
&lt;p&gt;So, here we go: the definitive guide to beating Sim Tower!&lt;/p&gt;
&lt;h3&gt;0: Get the Game&lt;/h3&gt;
&lt;p&gt;It&#39;s hard to beat a game you can&#39;t play, so getting a copy of the game is a good
place to start.  I got mine at &lt;a href=&#34;http://abandonia.com/en/games/341/Sim%20Tower.html&#34;&gt;Abandonia&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A note here: the game will run under &lt;a href=&#34;http://www.kronenberg.org/darwine/&#34;&gt;Darwine&lt;/a&gt; on Intel-based Macs...
Just don&#39;t try and save -- that doesn&#39;t work.&lt;/p&gt;
&lt;h3&gt;1: Starting your Tower: hitting two stars&lt;/h3&gt;
&lt;p&gt;After the game is installed and started, begin your tower by using the
build-a-lobby-in-the-bottom-left-corner-of-the-screen trick to double your
money, then build a lobby that is the entire width of the screen.&lt;/p&gt;
&lt;p&gt;After you have built the mega-lobby, start building offices.  Lots of offices.
Three floors worth of offices.  In addition to offices, build stairs.  I build
them approximately half a screens width from the right side of the screen, then
every screens width after that.  It doesn&#39;t really matter, though -- all that
matters is that you&#39;ve got three floors of solid offices and stairs going to all
of them.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://blog.codekills.net/uploads/SimTowerOffices.png&#34; style=&#34;display: inline&#34; /&gt;&lt;/p&gt;
&lt;p&gt;By the time this is done, you should have two stars (300 population).&lt;/p&gt;
&lt;h3&gt;2: Fast food: three stars&lt;/h3&gt;
&lt;p&gt;Great -- you&#39;ve got two stars.  Only three more to go.  And how will we get
there?  Fast food.&lt;/p&gt;
&lt;p&gt;Why fast food?  Well, the hardest part of the star requirements is the
population, and fast food restaurants have the highest population to space
ratio.  Also, no one seems to notice if the only thing in your tower is fast
food and office space.&lt;/p&gt;
&lt;p&gt;So, time to start building!&lt;/p&gt;
&lt;p&gt;Your first order of business is to build two security offices.  It doesn&#39;t
really matter where you put them, all that matters is that you have them -- they
are the only requirement for three stars.  Stick them under ground, at the
beginning of a floor -- where ever.&lt;/p&gt;
&lt;p&gt;Now that that&#39;s out of the way, it&#39;s time to start building fast food.&lt;/p&gt;
&lt;p&gt;Your goal is to build eleven (yes, 11) floors of fast food.&lt;/p&gt;
&lt;p&gt;To do this, you will also need elevators.  Lots of elevators.  You will need
about six, distributed across the length of your building.  I like to build them
in pairs:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://blog.codekills.net/uploads/SimTowerElevators.png&#34; style=&#34;display: inline&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Additionally, you will need to make sure that the lazy sims working in the
offices &lt;em&gt;don&#39;t&lt;/em&gt; use these elevators.  Use the inspector tool to look at each
elevator, then click the floor numbers to disable floors 2,3,4.  Also, I&#39;ve
found it helpful to have one elevator which goes to odd-numbered floors and
another which goes to even-numbered floors.  Try that too.&lt;/p&gt;
&lt;p&gt;Oh, yea, and make sure that all the elevators have eight cars in them.&lt;/p&gt;
&lt;p&gt;At some point in the process of building this unholy pile of fast food, you&#39;ll
get a population of 1000 and hit three stars.  Cool!  On to the next step.&lt;/p&gt;
&lt;h3&gt;3: Cinemas: A (brief) change from fast food (four stars)&lt;/h3&gt;
&lt;p&gt;Once you&#39;ve hit three stars you&#39;ll get the option to build even more exciting
things like restaurants, shops and party halls.&lt;/p&gt;
&lt;p&gt;But just go ahead and ignore those.&lt;/p&gt;
&lt;p&gt;The only things you should be concerned with are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Building more fast food.&lt;/li&gt;
&lt;li&gt;Add a liberal sprinkling of cinemas - I have no evidence for this, but I
  think they bring more people into your building.&lt;/li&gt;
&lt;li&gt;Build a few parking spots.  Make sure you build enough that there are
  always a few empty.  You will need them for the VIP and five stars.&lt;/li&gt;
&lt;li&gt;Build one hotel suite, along with housekeeping right beside an elevator.
  This is also for the VIP.&lt;/li&gt;
&lt;li&gt;Your sims will whine about wanting medical and recycling centers. Give
  them one medical center, and as many recycling centers as they need to be
  happy (2 or 3?  Just don&#39;t over-do it -- recycling centers have a steep
  annual fee).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Alright, and once you&#39;ve done that, just go back to building more fast food.&lt;/p&gt;
&lt;p&gt;At some point here, you will hit a population of 5,000, the VIP will come and
you will get four stars.  Good job.&lt;/p&gt;
&lt;p&gt;And if you get to 14 floors and still don&#39;t have four stars, just skip down to
the next section anyway.&lt;/p&gt;
&lt;p&gt;Oh, your building will catch on fire too.  Just pay to have it put out.&lt;/p&gt;
&lt;h3&gt;4: Metro station, express elevators and more fast food (five stars)&lt;/h3&gt;
&lt;p&gt;Ah, four stars.  You think you&#39;re almost there, don&#39;t you? Ha!&lt;/p&gt;
&lt;p&gt;By now, you should be up to about 14 floors.  You will finally get a break from
the tedium of building fast food as you get to build a sky lobby and revamp your
elevator system.&lt;/p&gt;
&lt;p&gt;So here&#39;s what to do:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Build a sky lobby on the 15th floor.&lt;/li&gt;
&lt;li&gt;Build express elevators from the 1st floor to the 15th.  I have six, also
 in pairs.&lt;/li&gt;
&lt;li&gt;Extend two of the express elevators all the way down, as low as they will
 go, then build a metro station there.&lt;/li&gt;
&lt;li&gt;Move the existing elevators down so they go only to the 10th floor.&lt;/li&gt;
&lt;li&gt;Build escalators from the sky lobby down to the 11th floor.&lt;/li&gt;
&lt;li&gt;Build four more floors of fast food (from floor 16 to 20), and use
 escalators to connect all of those to the lobby.&lt;/li&gt;
&lt;li&gt;Build more elevators on the 15th floor, directly over top of the elevators
 which go from floor 1 to 10.  These elevators will be used to get people to
 floor 21 and above, so make sure they don&#39;t stop at floors 16 through 20).&lt;/li&gt;
&lt;li&gt;As you build more floors of fast food, use these new elevators to connect
 them to the sky lobby.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;And there you have it -- do this up to floor 23 or 24, and eventually you&#39;ll hit
a population of 10,000 and five stars.  Huzza!&lt;/p&gt;
&lt;h3&gt;5: One last thing...&lt;/h3&gt;
&lt;p&gt;Phew, you&#39;re at five stars and you&#39;ve probably got a population of close to
15,000.  Your first order of business is to get your population up and over
15,000 (the requirement for a &#34;Tower&#34; ranking).  Keep building fast food until
you&#39;ve got that &lt;img src=&#34;/templates/default/img/emoticons/smile.png&#34; alt=&#34;:-)&#34; style=&#34;display: inline; vertical-align: bottom;&#34; class=&#34;emoticon&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Once you&#39;re over 15,000 population, you&#39;ve only got to do one more thing: build
a cathedral.  To do this, pick two express elevators which are at least the
width of a cathedral apart, then extend them up all the way to the 100th floor.
Build a small lobby on the 90th floor, place the cathedral on the 100th floor,
then build an elevator to connect them.&lt;/p&gt;
&lt;p&gt;Now you&#39;ve just got to wait for someone to get married, and your tower will be
awarded the rank of &#34;Tower&#34;! (just don&#39;t forget to turn off fast mode so you can
enjoy the wedding).&lt;/p&gt;
&lt;p&gt;And that&#39;s it! You&#39;re done &lt;img src=&#34;/templates/default/img/emoticons/smile.png&#34; alt=&#34;:-)&#34; style=&#34;display: inline; vertical-align: bottom;&#34; class=&#34;emoticon&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://blog.codekills.net/uploads/SimTowerWin.png&#34; style=&#34;display: inline&#34; /&gt;&lt;/p&gt;
&lt;h3&gt;Resources&lt;/h3&gt;
&lt;p&gt;A couple of useful resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/uploads/DAVID.TDT&#34;&gt;My save game&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.n3mra.com/simtowerstars.html&#34;&gt;SimTower Star Rating&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.gamespot.com/pc/strategy/simtower/show_msgs.php?topic_id=m-1-36608222&amp;amp;pid=565191&amp;amp;page=0&#34;&gt;A series of posts talking about the Sim&#39;s behavior, population density, income and other things&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  <entry>
    <author>
      <name>David Wolever</name>
      <uri>http://blog.codekills.net</uri>
    </author>
    <title type="html">Python Brain-Teaser</title>
    <link rel="alternate" type="text/html" href="http://blog.codekills.net/2008/05/29/python-brain-teaser" />
    <id>http://blog.codekills.net/2008/05/29/python-brain-teaser</id>
    <updated>2008-05-29T15:14:00Z</updated>
    <published>2008-05-29T15:14:00Z</published>
    <category scheme="http://blog.codekills.net" term="Python" />
    <category scheme="http://blog.codekills.net" term="Play" />
    <summary type="html">Python Brain-Teaser</summary>
    <content type="html" xml:base="http://blog.codekills.net/2008/05/29/python-brain-teaser">

&lt;p&gt;I&#39;m working on pulling some functionality out of one object and putting it in another, and I came across this interesting problem:&lt;/p&gt;
&lt;p&gt;&lt;style type=&#34;text/css&#34;&gt;
/**
 * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann
 * (http://qbnz.com/highlighter/ and http://geshi.org/)
 */
.python .de1, .python .de2 {color: #000060; font-weight: normal;}
.python  {white-space: nowrap;border: 1px dotted #a0a0a0; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 110%; background-color: #f0f0f0; margin: 0; line-height: 110%; padding: 0;color: #000099;}
.python a:link {color: #006;}
.python a:hover {background-color: #d6d6e6;}
.python .head {font-family: Verdana, Arial, sans-serif; color: #808080; font-size: 70%; font-weight: bold; background-color: #f0f0ff; border-bottom: 1px solid #d0d0d0; padding: 2px;}
.python .foot {font-family: Verdana, Arial, sans-serif; color: #808080; font-size: 70%; font-weight: bold; background-color: #f0f0ff; border-top: 1px solid #d0d0d0; padding: 2px;}
.python .imp {font-weight: bold; color: red;}
.python li, .python li.li1 {font-family: &#39;Courier New&#39;, Courier, monospace; color: #000060; background-color: #e0e0e0; padding-bottom: 2px;}
.python .kw1 {color: #ff7700;font-weight:bold;}
.python .kw2 {color: #008000;}
.python .kw3 {color: #dc143c;}
.python .kw4 {color: #0000cd;}
.python .co1 {color: #808080; font-style: italic;}
.python .coMULTI {color: #808080; font-style: italic;}
.python .es0 {color: #000099; font-weight: bold;font-weight: normal;}
.python .br0 {color: black;}
.python .sy0 {color: #66cc66;}
.python .st0 {color: #483d8b;}
.python .nu0 {color: #ff4500;}
.python .me1 {color: black;}
.python .me {1}
&lt;/style&gt;&lt;/p&gt;
&lt;div class=&#34;python&#34;&gt;
&lt;div class=&#34;de1&#34;&gt;&lt;span class=&#34;kw1&#34;&gt;class&lt;/span&gt; Foo:&lt;/div&gt;
&lt;div class=&#34;de1&#34;&gt;&amp;nbsp; &amp;nbsp; me = &lt;span class=&#34;st0&#34;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&#34;de1&#34;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&#34;de1&#34;&gt;&lt;span class=&#34;kw1&#34;&gt;class&lt;/span&gt; Bar:&lt;/div&gt;
&lt;div class=&#34;de1&#34;&gt;&amp;nbsp; &amp;nbsp; me = &lt;span class=&#34;st0&#34;&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&#34;de1&#34;&gt;&amp;nbsp; &amp;nbsp; &lt;span class=&#34;kw1&#34;&gt;def&lt;/span&gt; get_me&lt;span class=&#34;br0&#34;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&#34;kw2&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;br0&#34;&gt;&amp;#41;&lt;/span&gt;:&lt;/div&gt;
&lt;div class=&#34;de1&#34;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span class=&#34;kw1&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kw2&#34;&gt;self&lt;/span&gt;.&lt;span class=&#34;me1&#34;&gt;me&lt;/span&gt;&lt;/div&gt;
&lt;div class=&#34;de1&#34;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&#34;de1&#34;&gt;Foo.&lt;span class=&#34;me1&#34;&gt;get_me&lt;/span&gt; = Bar.&lt;span class=&#34;me1&#34;&gt;get_me&lt;/span&gt;&lt;/div&gt;
&lt;div class=&#34;de1&#34;&gt;x = Foo&lt;span class=&#34;br0&#34;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&#34;br0&#34;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&#34;de1&#34;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&#34;de1&#34;&gt;&lt;span class=&#34;kw1&#34;&gt;print&lt;/span&gt; x.&lt;span class=&#34;me1&#34;&gt;get_me&lt;/span&gt;&lt;span class=&#34;br0&#34;&gt;&amp;#40;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;What does this print?&lt;/p&gt;
&lt;p&gt;And, next question, why is that?&lt;/p&gt;
&lt;p&gt;After lunch I&#39;ll post my thoughts &lt;img src=&#34;/templates/default/img/emoticons/smile.png&#34; alt=&#34;:-)&#34; style=&#34;display: inline; vertical-align: bottom;&#34; class=&#34;emoticon&#34; /&gt;&lt;/p&gt;
&lt;hr /&gt;

&lt;!-- EXTENDED BODY --&gt;
&lt;a id=&#34;extended&#34;&gt;&lt;/a&gt;&lt;p&gt;Until now, I had assumed that the semi-magic &lt;code&gt;self&lt;/code&gt; variable was set on method calls (ie, when &lt;code&gt;x.get_me()&lt;/code&gt; is called)... But apparently it&#39;s set when the object is instantiated (which makes perfect sense, otherwise &lt;code&gt;getattr(Bar(), &#39;get_me&#39;)()&lt;/code&gt; would not work).&lt;/p&gt;
&lt;p&gt;So I can only presume that something equivalent to this happens when an object is instantiated:&lt;/p&gt;
&lt;div class=&#34;python&#34; style=&#34;white-space: nowrap;border: 1px dotted #a0a0a0; font-family: &#39;Courier New&#39;, Courier, monospace; font-size: 110%; background-color: #f0f0f0; margin: 0; line-height: 110%; padding: 0;color: #000099;&#34;&gt;
&lt;div class=&#34;de1&#34;&gt;&lt;span class=&#34;kw1&#34;&gt;from&lt;/span&gt; &lt;a href=&#34;http://docs.python.org/lib/module-functools.html&#34;&gt;functools&lt;/a&gt; &lt;span class=&#34;kw1&#34;&gt;import&lt;/span&gt; partial&lt;/div&gt;
&lt;div class=&#34;de1&#34;&gt;new_obj = Class&lt;span class=&#34;br0&#34;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&#34;br0&#34;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&#34;de1&#34;&gt;&lt;span class=&#34;kw1&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;br0&#34;&gt;&amp;#40;&lt;/span&gt;key, val&lt;span class=&#34;br0&#34;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&#34;kw1&#34;&gt;in&lt;/span&gt; new_obj.&lt;span class=&#34;kw4&#34;&gt;__dict__&lt;/span&gt;.&lt;span class=&#34;me1&#34;&gt;items&lt;/span&gt;&lt;span class=&#34;br0&#34;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&#34;br0&#34;&gt;&amp;#41;&lt;/span&gt;:&lt;/div&gt;
&lt;div class=&#34;de1&#34;&gt;&amp;nbsp; &amp;nbsp; &lt;span class=&#34;kw1&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;kw1&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;kw2&#34;&gt;callable&lt;/span&gt;&lt;span class=&#34;br0&#34;&gt;&amp;#40;&lt;/span&gt;val&lt;span class=&#34;br0&#34;&gt;&amp;#41;&lt;/span&gt;: &lt;span class=&#34;kw1&#34;&gt;continue&lt;/span&gt;&lt;/div&gt;
&lt;div class=&#34;de1&#34;&gt;&amp;nbsp; &amp;nbsp; &lt;span class=&#34;kw2&#34;&gt;setattr&lt;/span&gt;&lt;span class=&#34;br0&#34;&gt;&amp;#40;&lt;/span&gt;new_obj, key, partial&lt;span class=&#34;br0&#34;&gt;&amp;#40;&lt;/span&gt;val, new_obj&lt;span class=&#34;br0&#34;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&#34;br0&#34;&gt;&amp;#41;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;
</content>
  </entry>
  <entry>
    <author>
      <name>David Wolever</name>
      <uri>http://blog.codekills.net</uri>
    </author>
    <title type="html">SSH Connection Sharing</title>
    <link rel="alternate" type="text/html" href="http://blog.codekills.net/2008/05/17/ssh-connection-sharing" />
    <id>http://blog.codekills.net/2008/05/17/ssh-connection-sharing</id>
    <updated>2008-05-17T13:35:00Z</updated>
    <published>2008-05-17T13:35:00Z</published>
    <category scheme="http://blog.codekills.net" term="Play" />
    <summary type="html">SSH Connection Sharing</summary>
    <content type="html" xml:base="http://blog.codekills.net/2008/05/17/ssh-connection-sharing">

&lt;p&gt;This tip was originally posted to the &lt;a href=&#34;http://mail.python.org/pipermail/python-dev/2008-May/079499.html&#34;&gt;python-dev&lt;/a&gt; mailing list, so I can&#39;t take one scrap of credit for it.&lt;/p&gt;
&lt;p&gt;Basically, since OpenSSH4, there has been an option to share connections -- that is, once you&#39;ve opened one connection to a host, every subsequent connection is tunneled through the same channel, completely removing the overhead of authentication!&lt;/p&gt;
&lt;p&gt;It&#39;s quite simple, just add this to &lt;code&gt;~/.ssh/config&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ControlMaster auto
ControlPath ~/.ssh/.%r@%h:%p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There can be problems if your machine crashes and that file is left lying around...  So adding this to your crontab will fix that:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@reboot rm -f .ssh/controls/*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next time: tab completion with scp!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <author>
      <name>David Wolever</name>
      <uri>http://blog.codekills.net</uri>
    </author>
    <title type="html">SSH and HTTPS on the same port?!</title>
    <link rel="alternate" type="text/html" href="http://blog.codekills.net/2008/04/11/ssh-and-https-on-the-same-port-!" />
    <id>http://blog.codekills.net/2008/04/11/ssh-and-https-on-the-same-port-!</id>
    <updated>2008-04-11T21:38:00Z</updated>
    <published>2008-04-11T21:38:00Z</published>
    <category scheme="http://blog.codekills.net" term="Python" />
    <category scheme="http://blog.codekills.net" term="Play" />
    <summary type="html">SSH and HTTPS on the same port?!</summary>
    <content type="html" xml:base="http://blog.codekills.net/2008/04/11/ssh-and-https-on-the-same-port-!">

&lt;p&gt;A friend of mine was over the other night, and we were talking about how much we like running SSH on port 443.  It gets you around all but the most insane firewalls, and to anyone but the keenest of observers it just looks like HTTPS traffic.&lt;/p&gt;
&lt;p&gt;But running SSH over port 443 makes it particularly difficult to run a secure web server as well.&lt;/p&gt;
&lt;p&gt;So what can be done?&lt;/p&gt;
&lt;p&gt;Well, it turns out that when an SSH client initiates a connection, it waits for the server to send a banner (&lt;code&gt;SSH-1.99-OpenSSH_4.7&lt;/code&gt;, for example) before beginning the secure negotiation.  Browsers, on the other hand, just go right ahead and begin the secure negotiation.&lt;/p&gt;
&lt;p&gt;Knowing this, it didn&#39;t take long to formulate a plan: write a little program which will listen on 443.  When it gets a connection, it figures out if the remote end is trying to speak SSH or HTTPS, makes the appropriate connection on the local end, the passes the data between the two.&lt;/p&gt;
&lt;p&gt;It only took a couple of hours to write a &lt;a href=&#34;http://wolever.net/~wolever/sstp/sstp.py&#34;&gt;small proof-of-concept&lt;/a&gt;... And, believe it or not, it even works! &lt;small&gt;Disclaimer: this particular implementation is not quite suitable for any real use.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;Anyway, this may not be the most efficient way of doing things... But that&#39;s no matter.  It&#39;s still neat &lt;img src=&#34;/templates/default/img/emoticons/smile.png&#34; alt=&#34;:-)&#34; style=&#34;display: inline; vertical-align: bottom;&#34; class=&#34;emoticon&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Code: &lt;a href=&#34;http://wolever.net/~wolever/sstp/sstp.py&#34;&gt;sstp.py&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <author>
      <name>David Wolever</name>
      <uri>http://blog.codekills.net</uri>
    </author>
    <title type="html">Problem E - Enhancing IPSC Rules: Rock Paper Scissors with PNGs</title>
    <link rel="alternate" type="text/html" href="http://blog.codekills.net/2007/07/21/problem-e---enhancing-ipsc-rules--rock-paper-scissors-with-pngs" />
    <id>http://blog.codekills.net/2007/07/21/problem-e---enhancing-ipsc-rules--rock-paper-scissors-with-pngs</id>
    <updated>2007-07-22T03:33:00Z</updated>
    <published>2007-07-22T03:33:00Z</published>
    <category scheme="http://blog.codekills.net" term="Play" />
    <summary type="html">Problem E - Enhancing IPSC Rules: Rock Paper Scissors with PNGs</summary>
    <content type="html" xml:base="http://blog.codekills.net/2007/07/21/problem-e---enhancing-ipsc-rules--rock-paper-scissors-with-pngs">

&lt;table border=&#34;1&#34; align=&#34;right&#34; cellpadding=&#34;5&#34; cellspacing=&#34;0&#34; style=&#34;background: white;&#34;&gt;
&lt;tr&gt;
&lt;td align=&#34;center&#34; valign=&#34;top&#34;&gt;
&lt;img src=&#34;http://images.wolever.net/blog/e0.png&#34; alt=&#34;Rock paper scissors in PNG form&#34; /&gt;&lt;br /&gt;
Rock paper scissors in PNG form&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;At this point, it seems like the Facebook problems have started to go down hill. Even when Ted and I combine our attention spans, we just can&#39;t quite make it through the descriptions. To make matters worse, the only short problem left, &lt;a href=&#34;http://www.facebook.com/jobs_puzzles/?puzzle_id=6&#34;&gt;Easy Puzzle Mountain&lt;/a&gt;, isn&#39;t actually all that easy...&lt;/p&gt;
&lt;p&gt;So what ever will we do on a lovely Saturday night?  Well, why not revisit an older problem.  This time, it is courtesy of the &lt;a href=&#34;http://ipsc.ksp.sk/&#34;&gt;IPSC&lt;/a&gt;&lt;sup&gt;1&lt;/sup&gt;: &lt;a href=&#34;http://ipsc.ksp.sk/contests/ipsc2007/real/problems/e.php&#34;&gt;Problem E - Enhancing IPSC Rules&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The problem is simple: the input is a JPEG with many pairs of rocks, papers and scissors. Each pair represents one round of &lt;a href=&#34;http://en.wikipedia.org/wiki/Rock,_Paper,_Scissors&#34;&gt;Rock Paper Scissors&lt;/a&gt;.  You must figure out who won each round (and ultimately the game).&lt;/p&gt;
&lt;p&gt;As normal for the IPSC, it was possible to solve the simple data set by hand -- each image had about 10 rounds each.  The hard data set, on the other hand... Well, you can see for yourself.&lt;/p&gt;
&lt;table border=&#34;1&#34; width=&#34;20&#34; align=&#34;right&#34; cellpadding=&#34;5&#34; cellspacing=&#34;0&#34; style=&#34;background: white;&#34;&gt;
&lt;tr&gt;
&lt;td align=&#34;center&#34; valign=&#34;top&#34;&gt;
10% of one hard dataset.  There are 22 sets in total.&lt;br /&gt;
&lt;img src=&#34;http://images.wolever.net/blog/e2.jpg&#34; alt=&#34;&#34; /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;We quickly decided that it would be silly to try and examine the shape of each object, so we decided to focus on the color.&lt;/p&gt;
&lt;p&gt;Looking at the color, it&#39;s easy to tell the difference between the rocks and everything else: they are really dark, everything else is really bright.  We called this the luminosity&lt;sup&gt;2&lt;/sup&gt;, and it is simple to obtain: simply add the red, green and blue channels of each pixel&lt;sup&gt;3&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;The next problem we had was telling the difference between paper and scissors.  Their &#34;luminosity&#34; is similar, and probably not enough to make a sure match.  Fortunately, the paper was fairly bland and the scissors were fairly colorful.  We came up with a metric called &#34;color delta&#34; to measure this.  The formula we used simple: &lt;code&gt;color_delta = abs(red - green) + abs(red - blue) + abs(blue - green)&lt;/code&gt; (where &lt;code&gt;abs(x)&lt;/code&gt; is the absolute value of &lt;code&gt;x&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Alright, great.  So now we have a method of distinguishing between rocks, papers and scissors... But how do I read the file? I have never worked with graphics before.  The Python graphics libraries seemed intimidating, and I&#39;ll be darned if I&#39;m also going to decode the PNGs.&lt;/p&gt;
&lt;p&gt;Fortunately, I had the presence of mind to remember the &lt;a href=&#34;http://en.wikipedia.org/wiki/Portable_pixmap&#34;&gt;PNM&lt;/a&gt; format.  The Wikipedia page has more information, but all that&#39;s important for now is that the P stands for Portable, and this portability is due to the fact that it uses flat ASCII to describe an image.  Nothing could be easier to parse.&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;bash&#34; style=&#34;text-align: left&#34;&gt;&lt;br /&gt;&lt;span style=&#34;color: #b1b100;&#34;&gt;for&lt;/span&gt; FILE &lt;span style=&#34;color: #b1b100;&#34;&gt;in&lt;/span&gt; *.png&lt;br /&gt;&lt;span style=&#34;color: #b1b100;&#34;&gt;do&lt;/span&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; convert &lt;span style=&#34;color: #0000ff;&#34;&gt;$FILE&lt;/span&gt;&lt;span style=&#34;color: #66cc66;&#34;&gt;&amp;#123;&lt;/span&gt;,.pnm&lt;span style=&#34;color: #66cc66;&#34;&gt;&amp;#125;&lt;/span&gt;&lt;br /&gt;&lt;span style=&#34;color: #b1b100;&#34;&gt;done&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;After this, the code came surprisingly quickly...  And, short of an incredibly stupid bug (I used something along the lines of &lt;code&gt;side = count / width % 2&lt;/code&gt; to figure out which side of the image was being processed),  it even worked!  I was able to plot the output (which was the luminosity, color delta pairs) in gnuplot and see a strong correlation.&lt;/p&gt;
&lt;p&gt;To figure out what each point was, I simply opened up one of the files in Photoshop and cut out all the items but the scissors, then all the items but papers.  After adding these to the plot, it was simple to tell which group was which.&lt;/p&gt;
&lt;table border=&#34;1&#34; cellpadding=&#34;5&#34; cellspacing=&#34;0&#34; style=&#34;background: white&#34;&gt;
&lt;tr&gt;
&lt;td align=&#34;center&#34; valign=&#34;top&#34;&gt;
&lt;img src=&#34;http://images.wolever.net/blog/plot.png&#34; alt=&#34;The final plot&#34; /&gt;&lt;br /&gt;
The final plot. Red points are data points, green points are papers from the training set and blue points are scissors from the training set.&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;And that is it &lt;img src=&#34;/templates/default/img/emoticons/smile.png&#34; alt=&#34;:-)&#34; style=&#34;display: inline; vertical-align: bottom;&#34; class=&#34;emoticon&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Code and sample data can be found at &lt;a href=&#34;/code/e/&#34;&gt;/code/e/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;1: On a side note, the IPSC is a great programming/problem solving contest.  I have written it for the past three of four years, and every time it&#39;s a lot of fun.&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;2: Yes, I realize that this is completely incorrect. Brightness would be much more appropriate.&lt;/p&gt;
&lt;p&gt;3: In actuality, I ended up using &lt;code&gt;(255*3)-(r+g+b)&lt;/code&gt; so that white (empty) pixels would have a value of 0.
&lt;/p&gt;
</content>
  </entry>
  <entry>
    <author>
      <name>David Wolever</name>
      <uri>http://blog.codekills.net</uri>
    </author>
    <title type="html">Solving Gridflip</title>
    <link rel="alternate" type="text/html" href="http://blog.codekills.net/2007/07/05/solving-gridflip" />
    <id>http://blog.codekills.net/2007/07/05/solving-gridflip</id>
    <updated>2007-07-05T21:45:00Z</updated>
    <published>2007-07-05T21:45:00Z</published>
    <category scheme="http://blog.codekills.net" term="Play" />
    <category scheme="http://blog.codekills.net" term="Facebook" />
    <summary type="html">Solving Gridflip</summary>
    <content type="html" xml:base="http://blog.codekills.net/2007/07/05/solving-gridflip">

&lt;p&gt;Ted and I had so much fun solving &lt;a href=&#34;/archives/14-Optimal-Movie-Seating-Puzzle.html&#34;&gt;the last Facebook problem&lt;/a&gt; that we decided to do another this weekend: &lt;a href=&#34;http://www.facebook.com/jobs_puzzles/?puzzle_id=9&#34;&gt;gridflip&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The problem is simple: you are given a grid of numbers, some positive and some negative.  The goal is to minimize the sum of the grid, while keeping the sums of the individual rows and columns positive.  The only operation that can be performed is flipping the sign of the individual rows of columns.  For instance, given the grid:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; [  2  -3 ] -1
 [ -3   5 ]  2
   -1   2    2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A flip to the first row and the first column would result in the grid:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; [ -2   3 ]  1
 [ -3   5 ]  2 # After flipping the first row
   -5   8    6

 [  2   3 ]  5
 [  3   5 ]  8 # After flipping the first column
    5   8   26
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the best solution for this grid, because it is the only solution where the sums of all the rows and columns are positive.&lt;/p&gt;
&lt;p&gt;The solution we came up with for this problem was almost as simple: for every possible combination of flipped/not flipped columns&lt;sup&gt;1&lt;/sup&gt;, make sure that every row is positive.  If, after making the sum of every row positive, the sum of every column is positive, the grid is a contender for the smallest sum.&lt;/p&gt;
&lt;p&gt;Now, there is one small problem: rows which have a sum of zero.  If a row&#39;s sum is zero, a flip won&#39;t change the value of the row, but it will change the value of the columns.  The obvious solution is simply to keep track of which rows have a sum of zero, then try flipping them... And that&#39;s exactly what we did.&lt;/p&gt;
&lt;p&gt;Now, the biggest downside to this algorithm is that it runs in &lt;code&gt;O(2&lt;/code&gt;&lt;sup&gt;&lt;code&gt;n&lt;/code&gt;&lt;/sup&gt;&lt;code&gt;)&lt;/code&gt; where &lt;code&gt;n&lt;/code&gt; is the shortest side of the grid... But in practice, even my &lt;a href=&#34;/code/facebook/gridflip/gridflip.py&#34;&gt;less-than-optimal Python code&lt;/a&gt; could solve the &#34;large&#34; data set in less than three seconds (&lt;a href=&#34;/code/facebook/gridflip/gridflip.cs&#34;&gt;Ted&#39;s C# code&lt;/a&gt; was almost instant).&lt;/p&gt;
&lt;p&gt;It makes me wonder, though, is there any way to speed this up?&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;/code/facebook/gridflip&#34;&gt;/code/facebook/gridflip/&lt;/a&gt; for source code and test grids.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;1: Columns for simplicity -- the actual code makes sure there are fewer columns than rows by transposing the grid.&lt;/small&gt;&lt;/p&gt;

&lt;!-- EXTENDED BODY --&gt;
&lt;a id=&#34;extended&#34;&gt;&lt;/a&gt;&lt;p&gt;&lt;em&gt;Edit:&lt;/em&gt; So, it appears that I can&#39;t add.  I&#39;ve fixed up the example grids so that they actually make sense.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Edit by Ted:&lt;/em&gt;  I&#39;d like to try to clarify our algorithm a little since the explanation  is crappy. 
Let&#39;s say we have a 10 x 20 grid.  First we chose the smallest dimension which in this example is 10.  Then we enumerate all possible ways of the 10 rows which is 2^10 = 1024 ways.  For each of those 1024 ways, we look at the 20 columns and update their sums.  If any sum is &amp;lt; 0 we flip the column and now its sum is positive.  This allows us to directly solve the pattern the columns need to be flipped in that can give a valid solution.&lt;br /&gt;
The only issue though is when the sum is zero.  In this case we don&#39;t know whether to flip or not.  Maybe out of the 20 columns, 3 will sum to zero (very few sum to zero and it does vary based on permutations but stays quite low) so that is 2^3 which is 8 possibilities. 
In the end the sign of the sums is checked and it is determined if we are the max sum.  Only a few thousand possibilities and the operations during the iteration are quite simple (adding a few numbers and so if-else&#39;s). This results in a very fast runtime.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <author>
      <name>David Wolever</name>
      <uri>http://blog.codekills.net</uri>
    </author>
    <title type="html">Sorting out Sorting</title>
    <link rel="alternate" type="text/html" href="http://blog.codekills.net/2007/06/20/sorting-out-sorting" />
    <id>http://blog.codekills.net/2007/06/20/sorting-out-sorting</id>
    <updated>2007-06-20T14:34:00Z</updated>
    <published>2007-06-20T14:34:00Z</published>
    <category scheme="http://blog.codekills.net" term="Play" />
    <summary type="html">Sorting out Sorting</summary>
    <content type="html" xml:base="http://blog.codekills.net/2007/06/20/sorting-out-sorting">

&lt;p&gt;Back in grade 10, my high school computer science teacher showed us a video called Sorting out Sorting.  Produced at U of T in 1981&lt;sup&gt;1&lt;/sup&gt;, it shows how different sorting algorithms work and compares their runtime.&lt;/p&gt;
&lt;p&gt;It was very exciting to see it again this morning!  Check out &lt;a href=&#34;http://www.youtube.com/watch?v=F3oKjPT5Khg&#34;&gt;Sorting out Sorting on YouTube&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;1: &lt;a href=&#34;http://www.cs.princeton.edu/~ah/alg_anim/animation/bibliography3_8.html#SOS&#34;&gt;http://www.cs.princeton.edu/~ah/alg_anim/animation/bibliography3_8.html#SOS&lt;/a&gt;
&lt;/small&gt;&lt;/p&gt;
</content>
  </entry>
</feed>

