<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>blog on Mister Muffin Blog</title>
    <link>http://blog.mister-muffin.de/tags/blog/</link>
    <description>Recent content in blog on Mister Muffin Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 31 Mar 2025 22:40:45 +0000</lastBuildDate><atom:link href="http://blog.mister-muffin.de/tags/blog/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>NASA has pride across most of the universe</title>
      <link>http://blog.mister-muffin.de/2025/03/31/nasa-has-pride-across-most-of-the-universe/</link>
      <pubDate>Mon, 31 Mar 2025 22:40:45 +0000</pubDate>
      
      <guid>http://blog.mister-muffin.de/2025/03/31/nasa-has-pride-across-most-of-the-universe/</guid>
      <description>&lt;p&gt;In July 2024, NASA posted an article titled &amp;ldquo;NASA Has Pride Across the
Universe&amp;rdquo; featuring a pride flag by Rachel Lense where each color band is made
up of images from across NASA. Today is the annual &lt;a href=&#34;https://en.wikipedia.org/wiki/International_Transgender_Day_of_Visibility&#34;&gt;International Transgender
Day of
Visibility&lt;/a&gt;.
The &lt;a href=&#34;https://svs.gsfc.nasa.gov/14627&#34;&gt;original NASA article&lt;/a&gt; from last year has
since been taken offline. But the heroes from archive.org still carry a copy
which I now &lt;a href=&#34;https://mister-muffin.de/nasapride/&#34;&gt;archived myself&lt;/a&gt; together
with the other source images. Here is NASA&amp;rsquo;s pride flag in all its glory:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://mister-muffin.de/nasapride/NASA_Pride_Flag_high_res.png&#34;&gt;&lt;img width=&#34;100%&#34; alt=&#34;NASA pride flag by Rachel Lense&#34; src=&#34;https://mister-muffin.de/nasapride/NASA_Pride_Flag_high_res_print.jpg&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Southern Fried Science has an &lt;a href=&#34;https://www.southernfriedscience.com/the-story-of-the-pride-flag-made-from-nasa-imagery-blueskys-most-liked-image/&#34;&gt;article about the
flag&lt;/a&gt;.
The original 4000x2547 TIFF image was stored not by archive.org but the PNG
version in the same resolution can be downloaded
&lt;a href=&#34;https://mister-muffin.de/nasapride/NASA_Pride_Flag_high_res.png&#34;&gt;here&lt;/a&gt; or by
clicking on the image.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Looking for self-hosted filesharing software</title>
      <link>http://blog.mister-muffin.de/2016/12/18/looking-for-self-hosted-filesharing-software/</link>
      <pubDate>Sun, 18 Dec 2016 10:18:00 +0000</pubDate>
      
      <guid>http://blog.mister-muffin.de/2016/12/18/looking-for-self-hosted-filesharing-software/</guid>
      <description>&lt;p&gt;The owncloud package was &lt;a href=&#34;https://tracker.debian.org/news/764369&#34;&gt;removed&lt;/a&gt; from
Debian unstable and testing. I am thus now looking for an alternative.
Unfortunately, finding such replacement seems to be harder than I initially
thought, even though I only use a very small subset of what owncloud provides.
What I require is some software which allows me to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;upload a directory of files of any type to my server (no &amp;ldquo;distributed&amp;rdquo; filesharing where I have to stay online with my laptop)&lt;/li&gt;
&lt;li&gt;share the content of that directory via HTTP (no requirement to install any additional software other than a web browser)&lt;/li&gt;
&lt;li&gt;let the share-links be private (no possibility to infer the location of other shares)&lt;/li&gt;
&lt;li&gt;allow users to browse that directory (image thumbnails or a photo gallery would be nice)&lt;/li&gt;
&lt;li&gt;allow me to allow anonymous users to upload their own content into that directory (also only requiring their web browser)&lt;/li&gt;
&lt;li&gt;already in Debian or easy to package and maintain due to low complexity (I don&amp;rsquo;t have enough time to become the next &amp;ldquo;owncloud maintainer&amp;rdquo;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I thought this was a pretty simple task to solve but I am unable to find any
software that fits above criteria.&lt;/p&gt;
&lt;p&gt;The below table shows the result of my research of what&amp;rsquo;s currently available.
The columns mark whether the respective software fulfills one of the six
criteria from above.&lt;/p&gt;
&lt;table border=1&gt;
&lt;tr&gt;&lt;th&gt;Software&lt;/th&gt;           &lt;th&gt;1&lt;/th&gt;&lt;th&gt;2&lt;/th&gt;&lt;th&gt;3&lt;/th&gt;&lt;th&gt;4&lt;/th&gt;&lt;th&gt;5&lt;/th&gt;&lt;th&gt;6&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;owncloud&lt;/td&gt;           &lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;sparkleshare&lt;/td&gt;       &lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;dvcs-autosync&lt;/td&gt;      &lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;git annex assistant&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;syncthing&lt;/td&gt;          &lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;pydio&lt;/td&gt;              &lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;seafile&lt;/td&gt;            &lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;sandstorm.io&lt;/td&gt;       &lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;ipfs&lt;/td&gt;               &lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;bozon&lt;/td&gt;              &lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;droppy&lt;/td&gt;             &lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✘&lt;/td&gt;&lt;td&gt;✔&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;Pydio, seafile and sandstorm.io look promising but they seem to be beasts
similar in complexity to owncloud as they bring features like version tracking,
office integration, wikis, synchronization across multiple devices or online
editing of files which are features that I do not need.&lt;/p&gt;
&lt;p&gt;I would already be very happy if there was a script which would make it easy to
create a hard-to-guess symlink to a directory with data tracked by git annex
under my www-root and then generate some static HTML to provide a thumbnails
view or a photo gallery. Unfortunately, even that solution would not be
sufficient as it would still disallow public upload by anybody whom I would
give the link to&amp;hellip;&lt;/p&gt;
&lt;p&gt;If you know some software that meets my criteria or would like to submit
corrections to above table, please shoot an email to &lt;a href=&#34;mailto:josch@debian.org&#34;&gt;josch@debian.org&lt;/a&gt;. Thanks!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>I became a Debian Developer</title>
      <link>http://blog.mister-muffin.de/2015/02/04/i-became-a-debian-developer/</link>
      <pubDate>Wed, 04 Feb 2015 18:00:00 +0000</pubDate>
      
      <guid>http://blog.mister-muffin.de/2015/02/04/i-became-a-debian-developer/</guid>
      <description>&lt;img width=&#34;75%&#34; src=&#34;http://blog.mister-muffin.de/images/josch_dd.jpg&#34; /&gt;
&lt;p&gt;Thanks to akira for the confetti to celebrate the occasion!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>port bootstrap build-ordering tool report 4</title>
      <link>http://blog.mister-muffin.de/2012/07/30/port-bootstrap-build-ordering-tool-report-4/</link>
      <pubDate>Mon, 30 Jul 2012 10:30:00 +0000</pubDate>
      
      <guid>http://blog.mister-muffin.de/2012/07/30/port-bootstrap-build-ordering-tool-report-4/</guid>
      <description>&lt;p&gt;A copy of this post is sent to
&lt;a href=&#34;http://lists.alioth.debian.org/pipermail/soc-coordination/2012-July/001322.html&#34;&gt;soc-coordination@lists.alioth.debian.org&lt;/a&gt;
as well as to
&lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-July/000315.html&#34;&gt;debian-bootstrap@lists.mister-muffin.de&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;diary&#34;&gt;Diary&lt;/h1&gt;
&lt;h2 id=&#34;july-2&#34;&gt;July 2&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;playing around with syntactic dependency graphs and how to use them to flatten dependencies&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;july-4&#34;&gt;July 4&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;make work with dose 3.0.2&lt;/li&gt;
&lt;li&gt;add linux-amd64 to source architectures&lt;/li&gt;
&lt;li&gt;remove printing in build_compile_rounds&lt;/li&gt;
&lt;li&gt;catch Not_found exception and print warning&lt;/li&gt;
&lt;li&gt;use the whole installation set in crosseverything.ml instead of flattened dependencies&lt;/li&gt;
&lt;li&gt;detect infinite loop and quit in crosseverything.ml&lt;/li&gt;
&lt;li&gt;use globbing in _tags file&lt;/li&gt;
&lt;li&gt;use wildcards and patsubst in makefile&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;july-5&#34;&gt;July 5&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;throw a warning if there exist binary packages without source packages&lt;/li&gt;
&lt;li&gt;add string_of_list and string_of_pkglist and adapt print_pkg_list and print_pkg_list_full to use them&lt;/li&gt;
&lt;li&gt;fix and extend flatten_deps - now also tested with Debian Sid&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;july-6&#34;&gt;July 6&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;do not exclude the crosscompiled packages from being compiled in crosseverything.ml&lt;/li&gt;
&lt;li&gt;clean up basebuildsystem.ml, remove old code, use BootstrapCommon code&lt;/li&gt;
&lt;li&gt;clean up basenocycles.ml, remove unused code and commented out code&lt;/li&gt;
&lt;li&gt;add option to print statistics about the generated dependency graph&lt;/li&gt;
&lt;li&gt;implement most_needed_fast_wrong as well as most_needed_slow_correct and make both available through the menu&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;july-7&#34;&gt;July 7&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;allow to investigate all scc, not only the full graph and the scc containing the investigated package&lt;/li&gt;
&lt;li&gt;handle Not_found in src_list_from_bin_list with warning message&lt;/li&gt;
&lt;li&gt;handle the event of the whole archive actually being buildable&lt;/li&gt;
&lt;li&gt;replace raise Failure with failwith&lt;/li&gt;
&lt;li&gt;handle incorrectly typed package names&lt;/li&gt;
&lt;li&gt;add first version of reduced_dist.ml to create a self-contained mini distribution out of a big one&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;july-8&#34;&gt;July 8&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;add script to quickly check for binary packages without source package&lt;/li&gt;
&lt;li&gt;make Debian Sid default in makefile&lt;/li&gt;
&lt;li&gt;add *.d.byte files to .gitignore&lt;/li&gt;
&lt;li&gt;README is helpful now&lt;/li&gt;
&lt;li&gt;more pattern matching and recursiveness everywhere&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;july-9&#34;&gt;July 9&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;fix termination condition of reduced_dist.ml&lt;/li&gt;
&lt;li&gt;have precise as default ubuntu distribution&lt;/li&gt;
&lt;li&gt;do not allow to investigate an already installable package&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;july-10&#34;&gt;July 10&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;milestone: show all cycles in a graph&lt;/li&gt;
&lt;li&gt;add copyright info (LGPL3+)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;july-11&#34;&gt;July 11&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;advice to use dose tools in README&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;july-16&#34;&gt;July 16&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;write apt_pkg based python filter script replacing grep-dctrl&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;july-17&#34;&gt;July 17&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;use Depsolver.listcheck more often&lt;/li&gt;
&lt;li&gt;add dist_graph.ml&lt;/li&gt;
&lt;li&gt;refactor dependency graph code into its own module&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;july-18&#34;&gt;July 18&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;improve package selection for reduced_dist.ml&lt;/li&gt;
&lt;li&gt;improve performance of cycle enumeration code&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;july-20&#34;&gt;July 20&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;implement buildprofile support into dose3&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;july-22&#34;&gt;July 22&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;let dist_graph.ml use commandline arguments&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;july-23&#34;&gt;July 23&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;allow dose3 to generate source package lists without Build-{Depends|Conflicts}-Indep&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;july-29&#34;&gt;July 29&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;implement crosscompile support into dose3&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;results&#34;&gt;Results&lt;/h1&gt;
&lt;h2 id=&#34;readme&#34;&gt;Readme&lt;/h2&gt;
&lt;p&gt;There is not yet a writeup on how everything works and how all the pieces of
the code work together but the current README file provides a short
introduction on how to use the tools.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;build and runtime dependencies&lt;/li&gt;
&lt;li&gt;compile instructions&lt;/li&gt;
&lt;li&gt;execution examples for each program&lt;/li&gt;
&lt;li&gt;step by step guide how to analyze the dependency situation&lt;/li&gt;
&lt;li&gt;explanation of general commandline options&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A detailed writeup about the inner workings of everything will be part of a
final documentation stage.&lt;/p&gt;
&lt;h2 id=&#34;license&#34;&gt;License&lt;/h2&gt;
&lt;p&gt;All my code is now released under the terms of the LGPL either version 3, or
(at your option) any later version. A special linking exception is made to the
license which can be read at the top of the provided COPYING file. The
exception is necessary because Ocaml links statically, which means that without
that exception, the conditions of distribution would basically equal GPL3+.&lt;/p&gt;
&lt;h2 id=&#34;reduced_distml&#34;&gt;reduced_dist.ml&lt;/h2&gt;
&lt;p&gt;Especially the Debian archive is huge and one might want to work on a reduced
selection of packages first. Having a smaller selection of the archive would be
significantly faster and would also not add thousands of packages that are not
important for an extended base system.&lt;/p&gt;
&lt;p&gt;I call a reduced distribution a set of source packages A and a set of binary
packages B which fulfill the following three properties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;all source packages A must be buildable with only binary packages B being
available&lt;/li&gt;
&lt;li&gt;all binary packages B except for architecture:all packages must be buildable
from source packages A&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The set of binary packages B and source packages A can be retrieved using the
reduced_dist program. It allows to either build the most minimal reduced
distribution or one that includes a certain package selection.&lt;/p&gt;
&lt;p&gt;To filter out the package control stanzas for a reduced distribution from a
full distribution, I originally used a call to grep-dctrl but later replaced
that by a custom python script called filter-packages.py. This script uses
python-apt to filter Packages and Sources files for a certain package
selection.&lt;/p&gt;
&lt;h2 id=&#34;dist_graphml&#34;&gt;dist_graph.ml&lt;/h2&gt;
&lt;p&gt;It soon became obvious that there were not many independent dependency cycle
situation but just one big scc that would contain 96% of the packages that are
involved in build dependency cycles. Therefor it made sense to write a program
that does not iteratively build the dependency graph starting from a single
package, but which builds a dependency graph for a whole archive.&lt;/p&gt;
&lt;h2 id=&#34;cycles&#34;&gt;Cycles&lt;/h2&gt;
&lt;p&gt;I can now enumerate all cycles in the dependency graph. I covered the
theoretical part in another &lt;a href=&#34;http://blog.mister-muffin.de/2012/07/04/enumerating-elementary-circuits-of-a-directed_graph/&#34;&gt;blog post&lt;/a&gt; and wrote &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-July/000257.html&#34;&gt;an email&lt;/a&gt; about the
achievement to the list. Both resources contain more links to the respective
sourcecode.&lt;/p&gt;
&lt;p&gt;The dependency graph generated for Debian Sid has 39486 vertices. It has only
one central scc with 1027 vertices and only eight other scc with 2 to 7
vertices.  All the other source and binary packages in the dependency graph for
the archive are degenerate components of length one.&lt;/p&gt;
&lt;p&gt;Obtaining the attached result took 4 hours on my machine (Core i5 @ 2.53GHz).
1.5 h of that were needed to build the dependency graph, the other 2.5 hours
were needed to run johnson&amp;rsquo;s algorithm on the result. Memory consumption of the
program was at about 700 MB.&lt;/p&gt;
&lt;p&gt;It is to my joy that apparently the runtime of the cycle finding algorithm for
a whole Debian Sid repository as well as the memory requirements are within
orders of magnitude that are justifiable when being run on off-the-shelf
hardware. It must also be noted that nothing is optimized for performance yet.&lt;/p&gt;
&lt;p&gt;A list of all cycles in Debian Sid up to length 4 can be retrieved from &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-July/000257.html&#34;&gt;this
email&lt;/a&gt;. This cycle analysis assumes that only essential packages,
build-essential and dependencies and debhelper are available. Debhelper is not
an essential or build-essential package but 79% of the archive build-depends on
it.&lt;/p&gt;
&lt;p&gt;The most interesting cycles are probably those of length 2 that need packages
that they build themselves. Noticeable examples for these situations are vala,
python, mlton, fpc, sbcl and ghc. Languages seem love to need themselves to be
built.&lt;/p&gt;
&lt;h2 id=&#34;buildprofiles&#34;&gt;Buildprofiles&lt;/h2&gt;
&lt;p&gt;There is a &lt;a href=&#34;http://bugs.debian.org/661538&#34;&gt;long discussion&lt;/a&gt; of how to encode staged build dependency
information in source packages. While the initial idea was to use
Build-Depends-StageN fields, this solution would duplicate large parts of the
Build-Depends field, which leads to bitrot as well as it is inflexible to
possible other build &amp;ldquo;profiles&amp;rdquo;. To remedy the situation it was proposed to use
field names like Build-Depends[stage1 embedded] but this would also duplicate
information and would break with the rfc822 format of package description
files. &lt;a href=&#34;http://www.hadrons.org/~guillem/debian/docs/embedded.proposal&#34;&gt;A document&lt;/a&gt; maintained by Guillem Jover gives even more ideas and
details.&lt;/p&gt;
&lt;p&gt;Internally, Patrick and me decided for another idea of Guillem Jover to
annotate staged build dependencies. The format reads like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Build-Depends: huge (&amp;gt;= 1.0) [i386 arm] &amp;lt;!embedded !bootstrap&amp;gt;, tiny
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So each build profile would follow a dependency in &amp;lt;&amp;gt; &amp;ldquo;brackets&amp;rdquo; an have a
similar format as architecture options.&lt;/p&gt;
&lt;p&gt;Patrick has a patch for dpkg that implements this functionality while I
&lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-July/000306.html&#34;&gt;patched dose3&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;dropping-build-depends-indep-and-build-conflicts-indep&#34;&gt;Dropping Build-Depends-Indep and Build-Conflicts-Indep&lt;/h2&gt;
&lt;p&gt;When representing the dependencies of a source package, dose3 concatenates its
Build-Depends and Build-Depends-Indep dependency information.&lt;/p&gt;
&lt;p&gt;So up to now, a source package could only be compiled, if it manages to compile
all of its binary packages including architecture:all packages.&lt;/p&gt;
&lt;p&gt;But when bootstrapping a new architecture, it should be sufficient to only
build the architecture dependent packages and therefor to only build the
build-arch target in debian/rules and not the build-indep target.&lt;/p&gt;
&lt;p&gt;Only considering the Build-Depends field and dismissing the Build-Depends-Indep
field, reduced the main scc from 1027 vertices to 979 vertices.  The amount of
cycles up to length four reduced from 276 to 206. Especially the cycles
containing gtk-doc-tools, doxygen, debiandoc-sgml and texlive-latex-base got
much less.&lt;/p&gt;
&lt;p&gt;Patrick managed to add a Build-Depends-Indep field to four packages so far
which reduced the scc further by 14 vertices down to 965 vertices.&lt;/p&gt;
&lt;p&gt;So besides staged build dependencies and cross building there is now a third
method that can be applied to break dependency cycles: add Build-Depends-Indep
information to them or update existing information.&lt;/p&gt;
&lt;p&gt;I submitted &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-July/000297.html&#34;&gt;a list of packages&lt;/a&gt; that have a binary-indep and/or a
build-indep target in their debian/rules to the list.&lt;/p&gt;
&lt;p&gt;I also submitted &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-July/000307.html&#34;&gt;a patch&lt;/a&gt; for dose3 to be able to specify to ignore
Build-Depends-Indep and Build-Conflicts-Indep information.&lt;/p&gt;
&lt;h2 id=&#34;dose3-crossbuilding&#34;&gt;Dose3 crossbuilding&lt;/h2&gt;
&lt;p&gt;So far I only looked at dependency situations in the native case. While the
native case contains a huge scc of about 1000 packages, the dependency
situation will be much nicer when cross building. But dose3 was so far not able
to simulate cross building of source packages. I wrote &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-July/000310.html&#34;&gt;a patch&lt;/a&gt; that
implements this functionality and will allow me to write programs that help
analyze the cross-situation as well.&lt;/p&gt;
&lt;h2 id=&#34;debconf-presentation&#34;&gt;Debconf Presentation&lt;/h2&gt;
&lt;p&gt;Wookey was giving &lt;a href=&#34;http://penta.debconf.org/dc12_schedule/events/874.en.html&#34;&gt;a talk&lt;/a&gt; at debconf12 for which I was supplying him with
slides. The slides in their final version can be downloaded &lt;a href=&#34;http://blog.mister-muffin.de/files/bootstrap_debconf12.pdf&#34;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;future&#34;&gt;Future&lt;/h1&gt;
&lt;p&gt;Patrick maintains &lt;a href=&#34;http://bootstrap.pehjota.net/staged/notes/weak-build-deps.txt&#34;&gt;a list&lt;/a&gt; of &amp;ldquo;weak&amp;rdquo; build dependencies. Those are
dependencies that are very likely to be droppable in either a staged build or
using Build-Depends-Indep. I must make use of this list to make it easier to
find packages that can easily be removed of their dependencies.&lt;/p&gt;
&lt;p&gt;I will have to implement support for resolving the main scc using staged build
dependencies. Since it is unlikely that Patrick will be fast enough in
supplying me with modified packages, I will need to create myself a database of
dummy packages.&lt;/p&gt;
&lt;p&gt;Another open task is to allow to analyze the crossbuilding dependency
situation.&lt;/p&gt;
&lt;p&gt;What I&amp;rsquo;m currently more or less waiting on is the inclusion of my patches into
dose3 as well as a decision on the buildprofile format. More people need to
discuss about it until it can be included into tools as well as policy.&lt;/p&gt;
&lt;p&gt;Every maintainer of a package can help making bootstrapping easier by making
sure that as many dependencies as possible are part of the Build-Depends-Indep
field.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>port bootstrap build-ordering tool report 3</title>
      <link>http://blog.mister-muffin.de/2012/07/02/port-bootstrap-build-ordering-tool-report-3/</link>
      <pubDate>Mon, 02 Jul 2012 10:58:00 +0000</pubDate>
      
      <guid>http://blog.mister-muffin.de/2012/07/02/port-bootstrap-build-ordering-tool-report-3/</guid>
      <description>&lt;p&gt;A copy of this post is sent to
&lt;a href=&#34;http://lists.alioth.debian.org/pipermail/soc-coordination/2012-July/001297.html&#34;&gt;soc-coordination@lists.alioth.debian.org&lt;/a&gt;
as well as to
&lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-July/000253.html&#34;&gt;debian-bootstrap@lists.mister-muffin.de&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;diary&#34;&gt;Diary&lt;/h1&gt;
&lt;h2 id=&#34;june-18&#34;&gt;June 18&lt;/h2&gt;
&lt;p&gt;Pietro suggests a faster way to generate installation sets for a list of
packages. In my case, I need an installation set for every source package in
the archive to find out how often a binary package is needed to build a source
package. As a result, the speed is doubled in contrast to the original
approach.&lt;/p&gt;
&lt;h2 id=&#34;june-19&#34;&gt;June 19&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;adapt code to work with new dose release 3.0&lt;/li&gt;
&lt;li&gt;remove unneeded parts of code&lt;/li&gt;
&lt;li&gt;add different possibilities to find amount of source packages that need a binary package&lt;/li&gt;
&lt;li&gt;add code to get multiple installation sets using Depsolver_int.solve&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;june-20&#34;&gt;June 20&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;add ~global_constraints:false to Depsolver.listcheck, Depsolver.trim and Depsolver.edos_install calls&lt;/li&gt;
&lt;li&gt;adapt output graph to limited xdot capabilities&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;june-21&#34;&gt;June 21&lt;/h2&gt;
&lt;p&gt;I formulate an &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000204.html&#34;&gt;email&lt;/a&gt; to the list, reporting of dependency graphs of
debhelper, cdbs, pkg-config and libgtk2.0-dev. My current technique gets an
installation set for a source package, removes all those that are already
installable and adds the others as a dependency of that source package. This
dependency will include an installation set of that binary as well minus all
packages that are already available. The problem with that approach are
dependency cycles created by long dependency chains. Example: src:A needs B
needs C needs A. B and C would both be added as a dependency of src:A. B as
well as C would also include their installation set which in both cases
includes A. So now there are two cycles: src:A-&amp;gt;B-&amp;gt;A and src:A-&amp;gt;C-&amp;gt;A. For a
real life example, look at the following situation of cdbs and src:sqlite3.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.mister-muffin.de/images/cdbs-old.dot.png&#34;&gt;&lt;img src=&#34;http://blog.mister-muffin.de/thumbs/cdbs-old.dot.png&#34; alt=&#34;cdbs old situation&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It is created because src:sqlite3 needs cdbs needs python-scour needs python
needs python2.7 needs libsqlite3-0. Therfor libsqlite3-0 is in the installation
set of cdbs, python-scour, python and python2.7. This creates five cycles in
the graph even though there is only one. It would be better to reduce the
dependencies added to src:sqlite3 to its direct dependency which is cdbs.&lt;/p&gt;
&lt;p&gt;Package dependencies are disjunctions from which the solver chooses one or the
other to build an installation set. To solve the problem above I would need to
know which disjunction the solver chose and then only add the direct dependency
of a package to the dependency graph.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;improve build_compile_rounds performance&lt;/li&gt;
&lt;li&gt;big overhaul of menu structure&lt;/li&gt;
&lt;li&gt;fix subgraph extraction code&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;june-22&#34;&gt;June 22&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;do not create a universe if not needed - use hashtables instead&lt;/li&gt;
&lt;li&gt;for sorting packages, generating difference of package sets and otherwise
comparing packages, always use CudfAdd.compare&lt;/li&gt;
&lt;li&gt;as a custom list membership function, use List.exists instead of trying
List.find&lt;/li&gt;
&lt;li&gt;more speedup for build_compile_rounds&lt;/li&gt;
&lt;li&gt;the number of source packages that can be built does NOT include the cross built packages&lt;/li&gt;
&lt;li&gt;print closure members in graph&lt;/li&gt;
&lt;li&gt;refactor code and move common functions to bootstrapCommon.ml&lt;/li&gt;
&lt;li&gt;add breakcycles.ml for future code to break cycles using staged build dependencies&lt;/li&gt;
&lt;li&gt;use more extlib functionality&lt;/li&gt;
&lt;li&gt;extended package list input format&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;june-23&#34;&gt;June 23&lt;/h2&gt;
&lt;p&gt;After several emails with Pietro I learn about syntactic dependency graphs. To
document my progress and prove my efforts I committed the code as commit
6684c13. But this code was soon found out to be unecessary so it will be
removed later and just serves as documentation.&lt;/p&gt;
&lt;h2 id=&#34;june-24&#34;&gt;June 24&lt;/h2&gt;
&lt;p&gt;I came up with another (better?) solution to get the chosen disjunctions. It
simply uses the calculated installation set to decide for each disjunction
which one was taken by the solver. I reported that important step and the open
questions involved with it in an &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000223.html&#34;&gt;email&lt;/a&gt; to the list. The problem always
was, that an installation set can easily contain more than one package of a
disjunction. In this case it is not clear which branch was chosen by the
solver. I found, that in Ubuntu Natty there are only 6 such packages and for
each of them the situation can be solved. It can be solved because in all of
those cases it is that either one package of a disjunction provides the other
or that both packages depend upon each other, which means that both have to be
included.&lt;/p&gt;
&lt;h2 id=&#34;june-27&#34;&gt;June 27&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;use installation set to flatten build dependencies of source packages&lt;/li&gt;
&lt;li&gt;refactor code and move common functions to bootstrapCommon.ml&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;june-25&#34;&gt;June 25&lt;/h2&gt;
&lt;p&gt;I have to have an algorithm that finds all circuits in a given graph. This is
necessary so that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;cycles can be enumerated for huge dependency graphs where cycles are hard to see&lt;/li&gt;
&lt;li&gt;cycles can be enumerated to find a cycle that can be broken using staged build dependencies&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It seems that &lt;a href=&#34;http://dutta.csc.ncsu.edu/csc791_spring07/wrap/circuits_johnson.pdf&#34;&gt;Johnson&amp;rsquo;s algorithm&lt;/a&gt; is the best way to do this complexity
wise and Pietro already &lt;a href=&#34;http://mancoosi.org/~abate/finding-all-elementary-circuits-directed-graph&#34;&gt;blogged about the problem&lt;/a&gt; together with an
implementation of the algorithm in ocaml. Unfortunately it turns out that his
code doesnt implement the algorithm correctly and hence &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000227.html&#34;&gt;misses out on some
cycles&lt;/a&gt;. The fix seems not to be too trivial so I&amp;rsquo;m still investigating it.&lt;/p&gt;
&lt;h2 id=&#34;june-28&#34;&gt;June 28&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;add crosseverything.ml to obtain a list of source packages that, if cross compiled, would make the whole archive available&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;results&#34;&gt;Results&lt;/h1&gt;
&lt;p&gt;While the first week was productive as usual, I had to work some time on a
University project during the second week as well as attend a family meeting. I
will catch up with the lost time over the course of the next week.&lt;/p&gt;
&lt;h2 id=&#34;dose3&#34;&gt;dose3&lt;/h2&gt;
&lt;p&gt;Using dose 3.0 (which fixes a bug about essential packages) the output of the
algorithms is now likely less wrong then before.&lt;/p&gt;
&lt;h2 id=&#34;performance&#34;&gt;performance&lt;/h2&gt;
&lt;p&gt;Performance was improved in the generation of installation sets as well as in
the code that tries out how many packages can be built in multiple rounds. This
was achieved by more caching, less unnecessary operations in looping
constructs, replacing lists with hashtables, not creating universes where not
necessary.&lt;/p&gt;
&lt;h2 id=&#34;user-interface&#34;&gt;user interface&lt;/h2&gt;
&lt;p&gt;The main program, basenocycles.ml now has a much better menu structure.&lt;/p&gt;
&lt;h2 id=&#34;input-format&#34;&gt;input format&lt;/h2&gt;
&lt;p&gt;The programs take two package file inputs. The list of source packages that has
to be cross built for a minimal build system and the list of source packages
that was chosen to be cross compiled in addition to that. Both files list one
source package per line and now allow comments.&lt;/p&gt;
&lt;h2 id=&#34;refactoring&#34;&gt;refactoring&lt;/h2&gt;
&lt;p&gt;As more and more scripts are added, more and more functionality is moved to
bootstrapCommon.ml which makes each script much cleaner.&lt;/p&gt;
&lt;h2 id=&#34;what-to-test-for-cross-building&#34;&gt;what to test for cross building&lt;/h2&gt;
&lt;p&gt;As discussed in the &amp;ldquo;Future&amp;rdquo; section of the last report, I now automated the
process of finding out which packages, if they were cross compiled, would make
the whole archive available because they break all cycles and allow native
compilation of the rest. The outcome: to build 3333 out of 3339 packages in
natty natively, at most 186 source packages must be cross compiled. The other
six cannot be compiled because of version mismatches in the Natty Sources.bz2
and Packages.bz2. The code can be run from crosseverything.ml.&lt;/p&gt;
&lt;h2 id=&#34;limit-source-dependencies-to-direct-dependencies&#34;&gt;limit source dependencies to direct dependencies&lt;/h2&gt;
&lt;p&gt;Reducing the dependencies of source packages from their full installation set
to their direct dependencies by finding out which disjunction of their
dependency list were taken, greatly simplifies the dependency graphs. The
dependency graph created for libgtk2.0-dev could be reduced from 491 to 247
vertices for a depth of three.&lt;/p&gt;
&lt;p&gt;For cdbs it is now clearly visible that cdbs depends on libsqlite3-0 which
builds from src:sqlite3 which depends on cdbs.&lt;/p&gt;
&lt;p&gt;Before:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.mister-muffin.de/images/cdbs-old.dot.png&#34;&gt;&lt;img src=&#34;http://blog.mister-muffin.de/thumbs/cdbs-old.dot.png&#34; alt=&#34;cdbs old situation&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.mister-muffin.de/images/cdbs-new.dot.png&#34;&gt;&lt;img src=&#34;http://blog.mister-muffin.de/thumbs/cdbs-new.dot.png&#34; alt=&#34;cdbs new situation&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For pkg-config the graph also has been reduced to the one single cycle that
matters: src:pkg-config needs libglib2.0-dev which depends on pkg-config which
builds from src:pkg-config.&lt;/p&gt;
&lt;p&gt;Before:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.mister-muffin.de/images/pkg-config-old.dot.png&#34;&gt;&lt;img src=&#34;http://blog.mister-muffin.de/thumbs/pkg-config-old.dot.png&#34; alt=&#34;pkg-config old situation&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After:&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.mister-muffin.de/images/pkg-config-new.dot.png&#34;&gt;&lt;img src=&#34;http://blog.mister-muffin.de/thumbs/pkg-config-new.dot.png&#34; alt=&#34;pkg-config old situation&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;future&#34;&gt;Future&lt;/h1&gt;
&lt;p&gt;I will prepare content for wookey&amp;rsquo;s debconf talk on crossbuilding and
bootstrapping. As this will include directions how to use the current code, I
will kill two birds with one stone and write some proper documentation for my
current source.&lt;/p&gt;
&lt;p&gt;The following two lists will be displayed after a dependency graph is
calculated and reduced to its scc:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;those source packages that have the least build dependencies not fulfilled.
Those might be candidates for easy staged build dependencies. Since the
source package is part of the scc, it will definitely be involved in some cycle
somewhere.&lt;/li&gt;
&lt;li&gt;those binary packages that most source packages depend upon. Those could be
candidates for cross compilation as it might be easier to cross compile the
source package than using staged build dependencies.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Patrick managed to cross build packages with sbuild now. So the list of
packages that crosseverything.ml produces can now be checked efficiently for
cross buildability. With this list, potentially more cycles can be broken out
of the box. A feature will be added that allows the user to remove all packages
from a dependency graph that can be cross compiled without any additional
effort.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-July/000249.html&#34;&gt;Version mismatches&lt;/a&gt; between source and binary packages in Sources.bz2 and
Packages.bz2 respectively in Ubuntu make the scripts fail and/or produce wrong
results. Debian (even Sid) doesnt have this problem so I should find out where
to report this problem to Ubuntu.&lt;/p&gt;
&lt;p&gt;I need to write a working version of Johnson&amp;rsquo;s algorithm because much
functionality depends upon it. I have the option to improve Pietro&amp;rsquo;s version or
write one from scratch. Writing one from scratch might be easier as I have
Pietro&amp;rsquo;s code as template as well as a Java implementation of Johnson&amp;rsquo;s
algorithm which seems to work.&lt;/p&gt;
&lt;p&gt;The following functionalities need working cycle enumeration:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;given source packages with staged build dependencies, an enumeration of
cycles is needed to find out which cycles can be broken by building packages
staged. It makes less sense to blindly build a package stage and then check if
this makes more packages available.&lt;/li&gt;
&lt;li&gt;display cycles of a dependency graph to the user. After obtaining all cycles
in the graph it makes sense to sort them by their length. The user would
then investigate the situation of the smallest cycles first. This makes sense
because breaking small cycles can potentially break bigger cycles.  Since in
the end, all cycles have to be eliminated anyway, it makes sense for the user
to first tackle the small ones.&lt;/li&gt;
&lt;li&gt;display the feedback arc set to the user. The packages in the feedback arc
set might be very good candidates for reduced build dependencies or cross
compilation.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>port bootstrap build-ordering tool report 2</title>
      <link>http://blog.mister-muffin.de/2012/06/17/port-bootstrap-build-ordering-tool-report-2/</link>
      <pubDate>Sun, 17 Jun 2012 19:35:00 +0000</pubDate>
      
      <guid>http://blog.mister-muffin.de/2012/06/17/port-bootstrap-build-ordering-tool-report-2/</guid>
      <description>&lt;p&gt;A copy of this post is sent to
&lt;a href=&#34;http://lists.alioth.debian.org/pipermail/soc-coordination/2012-June/001269.html&#34;&gt;soc-coordination@lists.alioth.debian.org&lt;/a&gt;
as well as to
&lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000194.html&#34;&gt;debian-bootstrap@lists.mister-muffin.de&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;diary&#34;&gt;Diary&lt;/h1&gt;
&lt;h2 id=&#34;june-4&#34;&gt;June 4&lt;/h2&gt;
&lt;p&gt;I added the first version of basenocycles.ml to git. Given an initial set of
cross built packages, it tries to compile as much as possible on the resulting
system in multiple rounds.&lt;/p&gt;
&lt;h2 id=&#34;june-5&#34;&gt;June 5&lt;/h2&gt;
&lt;p&gt;During June 3, I discovered and error in my program that would only come up
when using the Debian Sid package lists as the input:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Fatal error: exception Assert_failure(&amp;quot;common/edosSolver.ml&amp;quot;, 610, 11)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On this day, June 5, I wrote a &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000146.html&#34;&gt;minimal test case&lt;/a&gt; for this problem.&lt;/p&gt;
&lt;p&gt;The same day, Pietro &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000147.html&#34;&gt;figured out&lt;/a&gt; that this is a bug in dose which will be
fixed in the next release.&lt;/p&gt;
&lt;p&gt;Begin writing code to figure out how important a binary package is for the
further build process.&lt;/p&gt;
&lt;p&gt;Try to use Depsolver.edos_install to find out what packages are needed to make
debhelper available.&lt;/p&gt;
&lt;p&gt;Restructure basenocycles.ml, exclude source packages that already have been
built, still trouble with already existing binary packages and
Cudf.mem_installed, comment stuff better.&lt;/p&gt;
&lt;h2 id=&#34;june-6&#34;&gt;June 6&lt;/h2&gt;
&lt;p&gt;I wrote some crude code (only estimate, not correct, fixed later) that would
give a rough overview of how often a given binary package is directly required
as a build dependency.&lt;/p&gt;
&lt;p&gt;Debhelper came out as the most needed package. It is architecture:all, so it
does not have to be built but it has unfulfilled runtime dependencies. To make
those packages available, 13 (actually 11, fixed later) packages have to be
compiled on Ubuntu Natty. But those packages all (except gettext) require
debhelper itself to be built. The first dependency cycle.&lt;/p&gt;
&lt;p&gt;This dependency cycle (actually, the 12 cycles) can be broken by either cross
compiling those source packages or by making them build without debhelper. One
goal of the program is to help decide what the easier option is, but this is
not yet implemented.&lt;/p&gt;
&lt;p&gt;To play around a bit, I created the possibility to specify a list of packages
that are additionally to the minimal set of cross compiled packages also cross
compiled. I added the 13 packages found above to the list, thus making the
binary packages they build available. This made debhelper available in the
system.&lt;/p&gt;
&lt;p&gt;As a result, 1625 out of 3339 source packages can be built with just a minimal
build system (priority:essential packages plus build-essential) and debhelper
available.&lt;/p&gt;
&lt;p&gt;The next package that blocks the most other source packages from being built is
cdbs. The next nine packages in that list also require cdbs so it seems to be
the next important package to be available.&lt;/p&gt;
&lt;p&gt;Pietro&amp;rsquo;s suggestions make me:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; - do not open BootstrapCommon but ExtLib, Common, Algo, Debian
 - do proper option parsing and logging
 - use Debcudf.ignore_essential = true
 - do Debcudf.init_tables (binlist@srclist)
 - use @ with shorter list first
 - use more List.rev_append instead of @
 - use CudfAdd.who_provides to find if a package is available
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;june-7&#34;&gt;June 7&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000150.html&#34;&gt;Pietro&lt;/a&gt; and &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000155.html&#34;&gt;Patrick&lt;/a&gt; suggest that for solving the debhelper cycles, one
could provide a minimal debhelper version so that the above list of 12 packages
can be built without debhelper.&lt;/p&gt;
&lt;p&gt;I try to figure out how to get a list of packages that are missing to make a
package installable/buildable. This functionality should be provided in dose
but I fail to find it.&lt;/p&gt;
&lt;h2 id=&#34;june-8&#34;&gt;June 8&lt;/h2&gt;
&lt;p&gt;Lacking a solution of the problem of June 7, I write &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000159.html&#34;&gt;a mail&lt;/a&gt; to Pietro.&lt;/p&gt;
&lt;p&gt;I start my first graphs in ocaml using the ocamlgraph library.&lt;/p&gt;
&lt;p&gt;The graph I generate, starts off at a binary package. For each binary package
it connects new vertices as its runtime dependencies. If a binary package is
not arch:all and also not yet otherwise compiled, its source package is also
added.&lt;/p&gt;
&lt;p&gt;The result is a graph in which set of source packages in it will make the
initial package available, if those source packages would be cross compiled.&lt;/p&gt;
&lt;p&gt;The graph is extended further than the source packages.&lt;/p&gt;
&lt;h2 id=&#34;june-9&#34;&gt;June 9&lt;/h2&gt;
&lt;p&gt;I refine a couple of functions, make univ_get_pkg_by_name return the package
with the highest version number.&lt;/p&gt;
&lt;p&gt;I wrote a rather lengthy (1027 words) &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000160.html&#34;&gt;email&lt;/a&gt; to the list that explains my
status as of this day.&lt;/p&gt;
&lt;p&gt;I can create graphviz dot files with ocaml, can create node and edge types and
create the graph by an imperative pattern that I saw a lot in Pietro&amp;rsquo;s code.&lt;/p&gt;
&lt;p&gt;Disjunctions are not yet handled correctly (see mail from June 8).&lt;/p&gt;
&lt;p&gt;The graphs generated look like the following:
&lt;a href=&#34;http://mister-muffin.de/p/8nyc.png&#34;&gt;http://mister-muffin.de/p/8nyc.png&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;june-11&#34;&gt;June 11&lt;/h2&gt;
&lt;p&gt;I write a &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000165.html&#34;&gt;test case&lt;/a&gt; which shows how CudfAdd.who_provides doesnt find
virtual packages.&lt;/p&gt;
&lt;p&gt;Automate the process of finding the packages that, if cross compiled, would
make another package available.&lt;/p&gt;
&lt;p&gt;Add more predicates (identifying source packages) and improve input file
reading code.&lt;/p&gt;
&lt;p&gt;Move build_compile_rounds which compiles as many source packages as it can in
multiple rounds on a given minimal system a toplevel function and thereby
abstract it more.&lt;/p&gt;
&lt;p&gt;Create a rudimentary text based menu to choose different actions to take for an
analysis.&lt;/p&gt;
&lt;p&gt;Start writing an extended version of simple_dependency_graph for deeper
analysis.&lt;/p&gt;
&lt;p&gt;Use xdot to show graphs from the text menu. Allow saving those graphs to a
file.&lt;/p&gt;
&lt;h2 id=&#34;june-12&#34;&gt;June 12&lt;/h2&gt;
&lt;p&gt;Move functionality from the extended version of simple_dependency_graph over to
the normal version and delete the extended version.&lt;/p&gt;
&lt;p&gt;Add the new Closure vertex type.&lt;/p&gt;
&lt;p&gt;Create extended_dependency_graph which is supposed to not contain single binary
package vertices but handle a package and its installation set as one vertex.&lt;/p&gt;
&lt;p&gt;The output of extended_dependency_graph is optionally reduced to the biggest
(non degenerate) strongly connected component.&lt;/p&gt;
&lt;p&gt;User gets the option of choosing the exploration depth.&lt;/p&gt;
&lt;h2 id=&#34;june-13&#34;&gt;June 13&lt;/h2&gt;
&lt;p&gt;Pietro &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000169.html&#34;&gt;replies&lt;/a&gt; to my mail from June 8 but apparently I failed to express
myself well enough in my last mail, so I &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000172.html&#34;&gt;rephrase my question&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pietro &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000167.html&#34;&gt;replies&lt;/a&gt; to my email from June 11 and explains how the effect I see
is due to &amp;ldquo;a nuisance of the debian to cudf encoding&amp;rdquo;. As a result I change my
code accordingly.&lt;/p&gt;
&lt;h2 id=&#34;june-14&#34;&gt;June 14&lt;/h2&gt;
&lt;p&gt;Another lengthy (1130 words) &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000173.html&#34;&gt;email&lt;/a&gt; to the list. I explain what was done
in the past days, what parts work and how they work. I list some rationales on
why I did things the way I did them.&lt;/p&gt;
&lt;p&gt;The most important observation is, that after improving my code again and
again, I ended up representing the dependency cycle problem in the same (very
similar) way that Pietro suggested in the beginning. This is probably a good
discovery.&lt;/p&gt;
&lt;p&gt;Lots of data of that email is now of only little use as of June 16, I make lots
of improvements in correctness.&lt;/p&gt;
&lt;p&gt;As I dont have an answer to my other email to Pietro from June 13, I implement
a very crude way to get an answer to the question of what packages are missing
for a package to be available/compileable. I called it
flatten_vpkgformula_best_effort and it suffers from many faults including
disjunctions and package conflicts.&lt;/p&gt;
&lt;p&gt;Patrick spots a problem. As a result, I make sure that at no point, the source
package of an arch:all package can be listed.&lt;/p&gt;
&lt;h2 id=&#34;june-15&#34;&gt;June 15&lt;/h2&gt;
&lt;p&gt;As a reply to my mail from June 13, Pietro creates a new branch in the git and
adds the code I needed to get a proper installation set.&lt;/p&gt;
&lt;h2 id=&#34;june-16&#34;&gt;June 16&lt;/h2&gt;
&lt;p&gt;As a result of Pietro&amp;rsquo;s efforts from June 15, I make &lt;a href=&#34;http://lists.mister-muffin.de/pipermail/debian-bootstrap/2012-June/000191.html&#34;&gt;great advancements&lt;/a&gt;
on all fronts.&lt;/p&gt;
&lt;p&gt;Details of the current status follow in the next section.&lt;/p&gt;
&lt;h1 id=&#34;results&#34;&gt;Results&lt;/h1&gt;
&lt;p&gt;A big leap was made on June 16 due to Pietro&amp;rsquo;s great help on making me
understand how Depsolver.listcheck can be used for my purposes. My difficulties
in finding the solution myself are rooted in many parts of the dose framework
being poorly commented but Pietro did already a couple of documentation commits
whenever things were unclear for me.&lt;/p&gt;
&lt;p&gt;Using Depsolver.listcheck makes it possible to be more distribution agnostic
and I dont have to handle vpkgs, virtual packages and constraints myself
anymore. The code also doesnt suffer anymore by wrongly analyzed dependencies
and conflicts. The only thing that is not yet taken care of, is that
Depsolver.listcheck only chooses one out of several possible installation set.
A final version should be able to take into account that a different
installation set could provide a better solution.&lt;/p&gt;
&lt;p&gt;Overall, in comparison to two weeks ago, I can now properly build, traverse and
analyze graphs, can choose an installation set properly, understand more about
dependencies, closures, dose and ocaml in general.&lt;/p&gt;
&lt;h2 id=&#34;finding-the-importance-of-binary-packages-for-building&#34;&gt;Finding the importance of binary packages for building&lt;/h2&gt;
&lt;p&gt;When calculating how many source packages are depending on the
availability of a binary package I originally flattened the
pkg.Cudf.depends list twice for a rough overview. This is of course
wrong due to disjunctions and conflicts and also doesnt provide a deep
dependency inspection. The new method is to calculate an installation
set that is necessary to compile a source package for every source
package. The resulting list of binary packages is then used to find out
how often a binary package appears in an installation set.&lt;/p&gt;
&lt;p&gt;I see three drawbacks though:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;calculating an installation set for each source package in the
archive is very slow&lt;/li&gt;
&lt;li&gt;if X packages build depend on A then also X packages will build
depend on the installation set of A, resulting in lots of duplication&lt;/li&gt;
&lt;li&gt;only one installation set is selected though there are many&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;removing-simple-graph&#34;&gt;Removing simple graph&lt;/h2&gt;
&lt;p&gt;The simple graph which contained single binary and source packages was
removed. I realized it doesnt really serve any purpose to look at it. As
a result, Bin vertices and InstallDep edges are also not part of the
graph anymore. Since it was responsible for generating the list of
source packages that have to be cross built to make a package available,
I created a new function get_cross_source_packages which uses an
installation to serve the same purpose.&lt;/p&gt;
&lt;h2 id=&#34;fix-extended_dependency_graph&#34;&gt;Fix extended_dependency_graph&lt;/h2&gt;
&lt;p&gt;extended_dependency_graph now uses installation sets for generating the
list of packages that is needed to compile a source package or install a
binary package. The list of build dependencies does not include packages
that are already installable. The list of runtime dependencies does not
include packages that are otherwise available (cross built,
arch:all&amp;hellip;). Instead of checking for list membership all the time, I
created hash tables for the list of installable as well as for the list
of available binary packages.&lt;/p&gt;
&lt;h1 id=&#34;future&#34;&gt;Future&lt;/h1&gt;
&lt;p&gt;There are two big tasks for the next two weeks:&lt;/p&gt;
&lt;p&gt;Task one is to find a way to give hints on which packages to best
consider for having reduced build dependencies. This would then probably
finally make use of Pietro&amp;rsquo;s cycle algorithms.&lt;/p&gt;
&lt;p&gt;Task two is to find a way to break cycles and create a build-DAG from a
list of packages that already have staged build dependency information.&lt;/p&gt;
&lt;p&gt;Patrick is currently working on patching dpkg with Build-Depends-StageN
dependencies as making perl cross compilable.  If he doesnt need the ability to
decide which packages to modify to have staged build dependencies in the near
future, then task one is probably less urgent and therefor of less importance
right now?&lt;/p&gt;
&lt;p&gt;On the other hand, I can easily generate fake reduced build dependencies so
that doing task two right now would not be a problem. Also, having the solution
for task two will make it possible to show the user what effect it would have
to add reduced build dependencies to a package.&lt;/p&gt;
&lt;p&gt;For the reasons above (it&amp;rsquo;s not urgent, task one profits from task two being
solved) I will go and implement task two first (if there are no objections from
my mentors).&lt;/p&gt;
&lt;p&gt;Another idea, that I discussed with wookey and Patrick yesterday, was that due
to multiarch being used for more and more packages, there should exist a set of
packages that is cross compilable without any change to the package.&lt;/p&gt;
&lt;p&gt;We agreed that I make a list of packages that, if cross compiled, would break
dependency cycles and make other packages available. I created such a list of
about 160 packages for Ubuntu Natty that, if cross compiled, made it possible
to have 87% of Natty available (those numbers have to be treated with caution
as I did not yet use the proper way of installation sets when generating that
list, but the order of magnitude should be correct). Wookey can then try to
cross compile those packages.  If some packages of those &amp;ldquo;crucial&amp;rdquo; source
packages are found to be cross compilable, then they should be cross compiled
because it means that no work has to be done to break some cycles.  Cross
compiling all packages that are cross compilable out of the box is no solution,
as only natively compiled packages can go into the archive.  This is why the
list of potentially additionally cross compiled source packages has to be kept
as small as possible.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>sisyphus wins ICRA 2012 VMAC</title>
      <link>http://blog.mister-muffin.de/2012/05/21/sisyphus-wins-icra-2012-vmac/</link>
      <pubDate>Mon, 21 May 2012 09:48:00 +0000</pubDate>
      
      <guid>http://blog.mister-muffin.de/2012/05/21/sisyphus-wins-icra-2012-vmac/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/josch/sisyphus&#34;&gt;Sisyphus&lt;/a&gt; is a piece of software that I
wrote as a member of a team from Jacobs University led by Prof. Dr. Andreas
Nüchter. It managed to place our team first in this year&amp;rsquo;s &lt;a href=&#34;http://www.icra2012.org/&#34;&gt;IEEE ICRA
2012&lt;/a&gt; &lt;a href=&#34;http://www.vma-competition.com/&#34;&gt;Virtual Manufacturing Automation
Competition&lt;/a&gt; in all three rounds.&lt;/p&gt;
&lt;p&gt;The goal was, to stack a given set of boxes of different length, height and
width on a pallet in a way that achieved optimal volume utilization, center of
mass and interlock of the boxes. Besides the cartesian placement of a box on
the pallet, the only other degree of freedom was a 90° rotation of the box
around a vertical axis.&lt;/p&gt;
&lt;p&gt;Since the arrangement of boxes into a three dimensional container is NP hard
(three dimensional orthogonal knapsack), I decided for a heuristic for an
approximate solution.&lt;/p&gt;
&lt;p&gt;The premise is, that there are many boxes of equal height which was the case in
the &lt;a href=&#34;http://www.vma-competition.com/?q=node/13&#34;&gt;test cases&lt;/a&gt; that were available
from the 2011 VMAC.&lt;/p&gt;
&lt;p&gt;Given this premise, my heuristic was, to arrange the boxes into layers of equal
height and then stack these layers on top of each other. A set of boxes that
would be left over or too little from the start to form its own full layer,
would then be stacked on the top of the completed layers.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://youtu.be/FSqjGiVt50I&#34;&gt;There is a video of how this looked like.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My code is now &lt;a href=&#34;https://github.com/josch/sisyphus&#34;&gt;online on github&lt;/a&gt; and it
even documented for everybody who is not me (or a potential future me of
course).&lt;/p&gt;
&lt;p&gt;&lt;i&gt;This blog post is about the &amp;ldquo;interesting&amp;rdquo; parts of sisyphus. You can read about
the overall workings of it in the project&amp;rsquo;s README.&lt;/i&gt;&lt;/p&gt;
&lt;h2 id=&#34;python-dict-to-xml-and-xml-to-python-dict&#34;&gt;Python dict to XML and XML to Python dict&lt;/h2&gt;
&lt;p&gt;The evaluation program for the challenge is reading XML files and the pallet
size and the list of articles with their sizes are also given in XML format. So
I had to have a way to easily read article information from XML and to easily
dump my data into XML format.&lt;/p&gt;
&lt;p&gt;Luckily, all the XML involved was not making use of XML attributes at all, so
the only children a node had, where other nodes. Thus, the whole XML file could
be represented as an XML dictionary with keys being tagnames and the values
being other dictionaries or lists or strings or integers.&lt;/p&gt;
&lt;p&gt;The code doing that uses &lt;code&gt;xml.etree.ElementTree&lt;/code&gt; and turns out to be very
simple:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; xml.etree &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; ElementTree
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;xmltodict&lt;/span&gt;(element):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;xmltodict_handler&lt;/span&gt;(parent_element):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        result &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; dict()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; element &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; parent_element:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; len(element):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                obj &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; xmltodict_handler(element)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                obj &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; element&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;text
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; result&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;get(element&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;tag):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; hasattr(result[element&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;tag], &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;append&amp;#34;&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    result[element&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;tag]&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(obj)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    result[element&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;tag] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [result[element&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;tag], obj]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                result[element&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;tag] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; obj
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; result
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; {element&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;tag: xmltodict_handler(element)}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;dicttoxml&lt;/span&gt;(element):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;dicttoxml_handler&lt;/span&gt;(result, key, value):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; isinstance(value, list):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; e &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; value:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                dicttoxml_handler(result, key, e)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;elif&lt;/span&gt; isinstance(value, basestring):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            elem &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ElementTree&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Element(key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            elem&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;text &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; value
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            result&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(elem)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;elif&lt;/span&gt; isinstance(value, int) &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; isinstance(value, float):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            elem &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ElementTree&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Element(key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            elem&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;text &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; str(value)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            result&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(elem)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;elif&lt;/span&gt; value &lt;span style=&#34;color:#f92672&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            result&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(ElementTree&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Element(key))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            res &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ElementTree&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Element(key)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; k, v &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; value&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;items():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                dicttoxml_handler(res, k, v)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            result&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;append(res)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    result &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; ElementTree&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;Element(element&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;keys()[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; key, value &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; element[element&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;keys()[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]]&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;items():
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        dicttoxml_handler(result, key, value)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; result
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;xmlfiletodict&lt;/span&gt;(filename):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; xmltodict(ElementTree&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;parse(filename)&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;getroot())
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;dicttoxmlfile&lt;/span&gt;(element, filename):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ElementTree&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;ElementTree(dicttoxml(element))&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;write(filename)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;xmlstringtodict&lt;/span&gt;(xmlstring):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; xmltodict(ElementTree&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;fromstring(xmlstring))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;dicttoxmlstring&lt;/span&gt;(element):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; ElementTree&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;tostring(dicttoxml(element))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Lets try this out:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; from util import xmlstringtodict, dicttoxmlstring
&amp;gt;&amp;gt;&amp;gt; xmlstring = &amp;quot;&amp;lt;foo&amp;gt;&amp;lt;bar&amp;gt;foobar&amp;lt;/bar&amp;gt;&amp;lt;baz&amp;gt;&amp;lt;a&amp;gt;1&amp;lt;/a&amp;gt;&amp;lt;a&amp;gt;2&amp;lt;/a&amp;gt;&amp;lt;/baz&amp;gt;&amp;lt;/foo&amp;gt;&amp;quot;
&amp;gt;&amp;gt;&amp;gt; xmldict = xmlstringtodict(xmlstring)
&amp;gt;&amp;gt;&amp;gt; print xmldict
{&#39;foo&#39;: {&#39;baz&#39;: {&#39;a&#39;: [&#39;1&#39;, &#39;2&#39;]}, &#39;bar&#39;: &#39;foobar&#39;}}
&amp;gt;&amp;gt;&amp;gt; dicttoxmlstring(xmldict)
&#39;&amp;lt;foo&amp;gt;&amp;lt;baz&amp;gt;&amp;lt;a&amp;gt;1&amp;lt;/a&amp;gt;&amp;lt;a&amp;gt;2&amp;lt;/a&amp;gt;&amp;lt;/baz&amp;gt;&amp;lt;bar&amp;gt;foobar&amp;lt;/bar&amp;gt;&amp;lt;/foo&amp;gt;&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The dict container doesnt preserve order, but as XML doesnt require that, this
is also not an issue.&lt;/p&gt;
&lt;h2 id=&#34;arranging-items-in-layers&#34;&gt;Arranging items in layers&lt;/h2&gt;
&lt;p&gt;When it was decided, that I wanted to take the layered approach, it boiled down
the 3D knapsack problem to a 2D knapsack problem. The problem statement now
was: how to best fit small rectangles into a big rectangle?&lt;/p&gt;
&lt;p&gt;I decided for a simple and fast approach as it is explained in Jake Gordon&amp;rsquo;s
&lt;a href=&#34;http://codeincomplete.com/posts/2011/5/7/bin_packing/&#34;&gt;blog article&lt;/a&gt;. There is
&lt;a href=&#34;http://codeincomplete.com/posts/2011/5/7/bin_packing/example/&#34;&gt;a demo&lt;/a&gt; of his
code and should the site vanish from the net, the code is &lt;a href=&#34;https://github.com/jakesgordon/bin-packing/&#34;&gt;on
github&lt;/a&gt;. This solution seemed to
generate results that were &amp;ldquo;good enough&amp;rdquo; while simple to implement and fast to
execute. If you look very hard, you can still see some design similarities
between my &lt;code&gt;arrange_spread.py&lt;/code&gt; and his &lt;code&gt;packer.js&lt;/code&gt; code.&lt;/p&gt;
&lt;p&gt;Jake Gordon got his idea from Jim Scott who wrote an
&lt;a href=&#34;http://www.blackpawn.com/texts/lightmaps/default.html&#34;&gt;article&lt;/a&gt; of arranging
randomly sized lightmaps into a bigger texture.&lt;/p&gt;
&lt;p&gt;There is also an ActiveState Code
&lt;a href=&#34;http://code.activestate.com/recipes/442299/&#34;&gt;recipe&lt;/a&gt; from 2005 which looks
very similar to the code by Jake Gordon.&lt;/p&gt;
&lt;p&gt;The posts of Jake Gordon and Jim Scott explain the solution well, so that I
dont have to repeat it. Should the above resources go offline, I made backups
of them
&lt;a href=&#34;http://mister-muffin.de/website_backup/codeincomplete.com/posts/2011/5/7/bin_packing/&#34;&gt;here&lt;/a&gt;
and
&lt;a href=&#34;http://mister-muffin.de/website_backup/www.blackpawn.com/texts/lightmaps/default.html&#34;&gt;here&lt;/a&gt;.
There is also a backup of the ActiveState piece
&lt;a href=&#34;http://mister-muffin.de/website_backup/code.activestate.com/recipes/442299/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;spreading-items-out&#34;&gt;Spreading items out&lt;/h2&gt;
&lt;p&gt;The algorithm above would cram all rectangles into a top-left position. As a
result, there would mostly be space at the bottom and left edge of the
available pallet surface. This is bad for two reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the mass is distributed unequally&lt;/li&gt;
&lt;li&gt;articles on the layer above at the bottom or left edge, are prone to overhang too much so that they tumble down&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Instead all articles should be spread over the available pallet area, creating
small gaps between them instead big spaces at the pallet borders.&lt;/p&gt;
&lt;p&gt;Since articles were of different size, it was not clear to me from the start
what &amp;ldquo;equal distribution&amp;rdquo; would even mean because it was obvious that it was
not as simple as making the space between all rectangles equal. The spacing had
to be different between them to accommodate for differently sized boxes.&lt;/p&gt;
&lt;p&gt;The solution I came up with, made use of the tree structure, that was built by
the algorithm that arranged the rectangles in the first place. The idea is, to
spread articles vertically first, recursively starting with the deepest nodes
and spreading them out in their parent rectangle. And then spreading them
horizontally, spreading the upper nodes first, recursively resizing and
spreading child nodes.&lt;/p&gt;
&lt;p&gt;The whole recursion idea created problems of its own. One of the nicest
recursive beauty is the following function:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;get_max_horiz_nodes&lt;/span&gt;(node):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; node &lt;span style=&#34;color:#f92672&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;or&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; node[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;article&amp;#39;&lt;/span&gt;]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; [], []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;elif&lt;/span&gt; node[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;down&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;and&lt;/span&gt; node[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;down&amp;#39;&lt;/span&gt;][&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;article&amp;#39;&lt;/span&gt;]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        rightbranch, sr &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; get_max_horiz_nodes(node[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;right&amp;#39;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        rightbranch &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [node] &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; rightbranch
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        downbranch, sd &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; get_max_horiz_nodes(node[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;down&amp;#39;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ar &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; rightbranch[len(rightbranch)&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;][&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;article&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ad &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; downbranch[len(downbranch)&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;][&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;article&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; ar[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;x&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;ar[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;width&amp;#39;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; ad[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;x&amp;#39;&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;ad[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;width&amp;#39;&lt;/span&gt;]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; rightbranch, sr&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;[downbranch[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; downbranch, sd&lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt;[rightbranch[&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        rightbranch, short &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; get_max_horiz_nodes(node[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;right&amp;#39;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; [node] &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; rightbranch, short
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;get_max_horiz_nodes()&lt;/code&gt; traverses all branches of the tree that &lt;code&gt;node&lt;/code&gt; has
below itself and returns a tuple containing the list of nodes that form the
branch that stretches out widest plus the list of nodes that are in the other
branches (which are shorter than the widest).&lt;/p&gt;
&lt;p&gt;Another interesting problem was, how to decide on the gap between articles.
This was interesting because the number resulting of the subtraction of the
available length (or width) and the sum of the articles lengths (or widths),
was mostly not divisible by the amount of gaps without leaving a rest. So there
had to be an algorithm that gives me a list of integers, neither of them
differing by more than one to any other, that when summed up, would give me the
total amount of empty space. Or in other words: how to divide a number m into n
integer pieces such that each of those integers doesnt differ more than 1 from
any other.&lt;/p&gt;
&lt;p&gt;Surprisingly, generating this list doesnt contain any complex loop constructs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; m = 108 # total amount
&amp;gt;&amp;gt;&amp;gt; n = 7 # number of pieces
&amp;gt;&amp;gt;&amp;gt; d,e = divmod(m, n)
&amp;gt;&amp;gt;&amp;gt; pieces = (e)*[(d+1)]+(n-e)*[d]
&amp;gt;&amp;gt;&amp;gt; print pieces
[16, 16, 16, 15, 15, 15, 15]
&amp;gt;&amp;gt;&amp;gt; sum(pieces) == m
True
&amp;gt;&amp;gt;&amp;gt; len(pieces) == n
True
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can test out the algorithms that arrange rectangles and spread them out by
cloning &lt;a href=&#34;https://github.com/josch/sisyphus&#34;&gt;the git&lt;/a&gt; and then running:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PYTHONPATH=. python legacy/arrange_spread.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The results will be svg files test1.svg and test2.svg, the latter showing the
spread-out result.&lt;/p&gt;
&lt;p&gt;Here is an example how the output looks like (without the red border which is
drawn to mark the pallet border):&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;http://blog.mister-muffin.de/images/pallet1.png&#34;&gt;&lt;img src=&#34;http://blog.mister-muffin.de/thumbs/pallet1.png&#34; /&gt;&lt;/a&gt; &lt;a
href=&#34;http://blog.mister-muffin.de/images/pallet2.png&#34;&gt;&lt;img src=&#34;http://blog.mister-muffin.de/thumbs/pallet2.png&#34; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;arrange_spread2.py&lt;/code&gt; contains an adaption of arrange_spread.py for the actual
problem.&lt;/p&gt;
&lt;h2 id=&#34;permutations-without-known-length&#34;&gt;Permutations without known length&lt;/h2&gt;
&lt;p&gt;When creating a layer out of articles of same height, then there are four
strategies that I can choose from. It is four because there are two methods
that I can either use or not. I can rotate the article by 90° per default or
not and I can rotate the pallet or not.&lt;/p&gt;
&lt;p&gt;So every time that I build a new layer, there are those four options. Depending
on which strategy I choose, there is a different amount of possible leftover
articles that did not fit into any layer. The amount is different because each
strategy is more or less efficient.&lt;/p&gt;
&lt;p&gt;To try out all combinations of possible layer arrangements, I have to walk
through a tree where at each node I branch four times for each individual
strategy. Individual neighboring nodes might be the same but this outcome is
unlikely due to the path leading to those neighboring nodes being different.&lt;/p&gt;
&lt;p&gt;To simplify, lets name the four possible strategies for each layers 0, 1, 2 and
3. I now want an algorithm that enumerates through all possible permutations of
those four numbers for &amp;ldquo;some&amp;rdquo; length. This is similar to counting. And the
itertools module comes with the &lt;code&gt;product()&lt;/code&gt; method that nearly does what I
want. For example, should I know that my tree does not become deeper than 8
(read: no more than eight layers will be built), then I can just run:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; for i in itertools.product([0,1,2,3], repeat=8):
...     print i
...
(0,0,0,0,0,0,0,0)
(0,0,0,0,0,0,0,1)
(0,0,0,0,0,0,0,2)
(0,0,0,0,0,0,0,3)
(0,0,0,0,0,0,1,0)
(0,0,0,0,0,0,1,1)
(0,0,0,0,0,0,1,2)
(0,0,0,0,0,0,1,3)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This would work if the number of layers created with each strategy was the
same. But as each strategy behaves differently depending on the input, it
cannot be known before actually trying out a sequence of strategies, how many
layers it will yield.&lt;/p&gt;
&lt;p&gt;The strategy (0,0,0,0,0,0,0,0) might create 7 layers, resulting in
(0,0,0,0,0,0,0,1), (0,0,0,0,0,0,0,2) and (0,0,0,0,0,0,0,3) yielding the same
output as only the first 7 strategies count. This would create duplicates which
I should not waste cpu cycles on later.&lt;/p&gt;
&lt;p&gt;It might also be that (0,0,0,0,0,0,1,0) turns out to be a combination of
strategies that creates more than 8 layers in which case the whole thing fails.&lt;/p&gt;
&lt;p&gt;So what I need is a generator, that gives me a new strategy depending on how
often it is asked for one. It should dynamically extend the tree of possible
permutations to accommodate for any size.&lt;/p&gt;
&lt;p&gt;Since the tree will become humongous (4^11 = 4194304), already traversed nodes
should automatically be cleaned so that only the nodes that make the current
list of strategies stays in memory at any point in time.&lt;/p&gt;
&lt;p&gt;This sounded all complicated which made me even more surprised by how simple
the solution was in the end.&lt;/p&gt;
&lt;p&gt;Here a version of the algorithm that could easily be ported to C:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Tree&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; __init__(self, branch_factor):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;branch_factor &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; branch_factor
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;root &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;children&amp;#34;&lt;/span&gt;: []}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;current &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;next&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;children&amp;#34;&lt;/span&gt;]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;children&amp;#34;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;:val, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;:self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;current, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;children&amp;#34;&lt;/span&gt;:[]} &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; val &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;branch_factor)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;current &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;children&amp;#34;&lt;/span&gt;][&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;reset&lt;/span&gt;(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;][&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;children&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;pop(&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;][&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;children&amp;#34;&lt;/span&gt;]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;current &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;current &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;reset()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; __str__(self):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; str(self&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;root)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It would be used like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; tree = Tree(4)
&amp;gt;&amp;gt;&amp;gt; print tree.next(), tree.next(), tree.next()
&amp;gt;&amp;gt;&amp;gt; while tree.reset():
...     print tree.next(), tree.next(), tree.next()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which would be equivalent to calling &lt;code&gt;itertools.product([1,2,3,4], 3)&lt;/code&gt;. The
special part is, that in each iteration of the loop I can call &lt;code&gt;tree.next()&lt;/code&gt; an
arbitrary amount of times, just how much it is needed. Whenever I cannot
generate an additional layer anymore, I can call &lt;code&gt;tree.reset()&lt;/code&gt; to start a new
permutation.&lt;/p&gt;
&lt;p&gt;For my code I used a python specific version which is a generator:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;product_varlength&lt;/span&gt;(branch_factor):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    root &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; {&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;None&lt;/span&gt;, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;children&amp;#34;&lt;/span&gt;: []}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    current &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;not&lt;/span&gt; current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;children&amp;#34;&lt;/span&gt;]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;children&amp;#34;&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; [{&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;:val, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;:current, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;children&amp;#34;&lt;/span&gt;:[]} &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; val &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(branch_factor)]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        current &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;children&amp;#34;&lt;/span&gt;][&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;yield&lt;/span&gt; current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;value&amp;#34;&lt;/span&gt;]):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;True&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;][&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;children&amp;#34;&lt;/span&gt;]&lt;span style=&#34;color:#f92672&#34;&gt;.&lt;/span&gt;pop(&lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;][&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;children&amp;#34;&lt;/span&gt;]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    current &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; root
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#66d9ef&#34;&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    current &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; current[&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It is used like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;it = product_varlength(4)
print it.next(), it.send(False), it.send(False)
while True:
	print it.send(True), it.send(False), it.send(False)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again, the expression in the loop can have any number of &lt;code&gt;it.send(False)&lt;/code&gt;. The
first &lt;code&gt;it.send(True)&lt;/code&gt; tells the generator to do a reset.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>adblocking with a hosts file</title>
      <link>http://blog.mister-muffin.de/2011/11/14/adblocking-with-a-hosts-file/</link>
      <pubDate>Mon, 14 Nov 2011 10:49:00 +0000</pubDate>
      
      <guid>http://blog.mister-muffin.de/2011/11/14/adblocking-with-a-hosts-file/</guid>
      <description>&lt;p&gt;Naturally adblock plus is a must-have extension for firefox but other programs
displaying websites might not offer such a facility.&lt;/p&gt;
&lt;p&gt;To block ads on any application accessing the internet, the use of a hosts file
which redirects requests to certain hostnames to 127.0.0.1 (which will refuse
incoming connections) provides a universal method to get rid of advertisements.&lt;/p&gt;
&lt;p&gt;The question is how to obtain a list of malicious hosts.&lt;/p&gt;
&lt;p&gt;Searching around revealed three lists that seemed to be well-maintained:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://winhelp2002.mvps.org/hosts.htm&#34;&gt;http://winhelp2002.mvps.org/hosts.htm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://pgl.yoyo.org/adservers/&#34;&gt;http://pgl.yoyo.org/adservers/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://someonewhocares.org/hosts/&#34;&gt;http://someonewhocares.org/hosts/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The according hosts-file entries can be found under these urls respectively:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;http://winhelp2002.mvps.org/hosts.txt&#34;&gt;http://winhelp2002.mvps.org/hosts.txt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&amp;amp;mimetype=plaintext&#34;&gt;http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&amp;amp;mimetype=plaintext&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://someonewhocares.org/hosts/hosts&#34;&gt;http://someonewhocares.org/hosts/hosts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also looked into the adblock plus filter rules but they mostly contain
expressions for the path, query and fragment part of URIs and not so much
hostnames. This makes sense because using its syntax adblock plus is able to
block with much more accuracy than just blocking whole domains.&lt;/p&gt;
&lt;p&gt;Now I wanted a combined list of them without duplicates so I cleaned them up
using the following sed expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sed &#39;s/\([^#]*\)#.*/\1/;s/[ \t]*$//;s/^[ \t]*//;s/[ \t]\+/ /g&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It removes comments, whitespace at the beginning and end of the line and
reduces any additional whitespace (between ip and hostname) to only one space.
I would then run the output through sort and uniq and append the result to my
/etc/hosts.&lt;/p&gt;
&lt;p&gt;What is still problematic about this approach is, that if one doesnt have a
service bound to 127.0.0.1:80 then every application trying to establish a TCP
connection to it will meaninglessly wait for localhost to respond until timeout
is reached. To avoid this and immediately send a tcp RST when the browser is
redirected to 127.0.0.1 when it tries to retrieve an advertisement, I use the
following iptables rule:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;iptables -A INPUT -i lo -p tcp -m tcp --dport 80 -j REJECT --reject-with tcp-reset
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some hosts that you might also want to add to your /etc/hosts because they are
there to track users are:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;127.0.0.1 www.google-analytics.com
127.0.0.1 auto.search.msn.com
127.0.0.1 ad.doubleclick.net
127.0.0.1 google-analytics.com
127.0.0.1 stat.livejournal.com
127.0.0.1 stats.surfaid.ihost.com
127.0.0.1 ads.imeem.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are not included by default in the lists above because it might break some
websites if they were.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;EDIT (2012-05-21)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I forgot to include port 443 for https in the iptables rule above. For example
google uses https for googleadservices.com and others might too, so dont forget
to also reset connections to port 443 with the rule given above.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>gnuplot live update</title>
      <link>http://blog.mister-muffin.de/2011/11/13/gnuplot-live-update/</link>
      <pubDate>Sun, 13 Nov 2011 13:44:00 +0000</pubDate>
      
      <guid>http://blog.mister-muffin.de/2011/11/13/gnuplot-live-update/</guid>
      <description>&lt;p&gt;When you have data that is not instantly generated but trickles in one by one
(either because calculation is difficult or because the data source produces
new datapoints over time) but you still want to visualize it with gnuplot the
easiest option is to hit the refresh button in the wx interface everytime you
want to refresh the data.&lt;/p&gt;
&lt;p&gt;A more cool way, is to make gnuplot &amp;ldquo;autoupdate&amp;rdquo; the data it displays whenever
new data is available automagically.&lt;/p&gt;
&lt;p&gt;Lets simulate a data source by the output of this python script that will just
output coordinates on a circle with radius one around the coordinate center and
wait for 0.5 seconds after every step.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; math &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; pi, sin, cos
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;from&lt;/span&gt; time &lt;span style=&#34;color:#f92672&#34;&gt;import&lt;/span&gt; sleep
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; alpha &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; [&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;pi&lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;i&lt;span style=&#34;color:#f92672&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;16.0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; i &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;16&lt;/span&gt;)]:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    print sin(alpha), cos(alpha)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    sleep(&lt;span style=&#34;color:#ae81ff&#34;&gt;0.5&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The magic will be done by this shell script which does nothing else than
reading lines from stdin, appending them to a buffer and printing the buffer
with gnuplot syntax around it every time new input is received.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;while&lt;/span&gt; read line; &lt;span style=&#34;color:#66d9ef&#34;&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        lines&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;$lines$line&lt;span style=&#34;color:#e6db74&#34;&gt;\n&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;plot \&amp;#34;-\&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        echo -n $lines
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;e&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These two scripts can now be used like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python -u circle.py | sh live-gnuplot.sh | gnuplot -p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The -u option has to be passed to python to enable unbuffered output. The -p
option for gnuplot makes the plot window remain even after the main gnuplot
exited.&lt;/p&gt;
&lt;p&gt;Since you with this setup gnuplot would auto-scale the coordinate axes
according to the current input, a more beatiful output with a fixed size
coordinate frame would be produced by:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{ echo &amp;quot;set xrange [-2:2]&amp;quot;; echo &amp;quot;set yrange [-2:2]&amp;quot;; python -u circle.py | sh live-gnuplot.sh } | gnuplot -p
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This way you can also pass more options like title, style, terminal or others.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>persistent NAT setup</title>
      <link>http://blog.mister-muffin.de/2011/11/06/persistent-nat-setup/</link>
      <pubDate>Sun, 06 Nov 2011 15:18:00 +0000</pubDate>
      
      <guid>http://blog.mister-muffin.de/2011/11/06/persistent-nat-setup/</guid>
      <description>&lt;p&gt;Often having some tablet or smartphone running linux connected to my usb port
and I always have to look up how to enable NAT-ing on my laptop so that those
devices can access the internet via usb-ethernet connection. So here is how to
do it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sysctl net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -j MASQUERADE
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But I will not need this reminder anymore because this is how to make the
setup persistant between reboots:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ echo net.ipv4.ip_forward = 1 &amp;gt; /etc/sysctl.d/ip_forward.conf
$ cat /etc/iptables/rules.v4
*nat
-A POSTROUTING -j MASQUERADE
COMMIT
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The content in /etc/iptables/rules.v4 is normally generated via iptables-save
so there might be some extra work needed to combine this with possible existing
content. The initscript required to run iptables-restore with this file as input
is provided as the iptables-persistent package.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
