<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Michel Albert</title><link href="https://michel.albert.lu/" rel="alternate"/><link href="https://michel.albert.lu/feeds/all.atom.xml" rel="self"/><id>https://michel.albert.lu/</id><updated>2026-10-29T18:00:00+01:00</updated><entry><title>Tidying Up My Python Libraries</title><link href="https://michel.albert.lu/tidying-up-my-python-libraries.html" rel="alternate"/><published>2026-10-29T18:00:00+01:00</published><updated>2026-10-29T18:00:00+01:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2026-10-29:/tidying-up-my-python-libraries.html</id><summary type="html">&lt;p class="first last"&gt;Final releases for t61codec and config_resolver, a 2.0 for
x690 and a refresh of gouge.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Last week I spent some time on my older Python libraries. t61codec,
x690, gouge and config_resolver all got a new release, and their docs
have moved to GitHub Pages.&lt;/p&gt;
&lt;div class="section" id="t61codec-3-0-0"&gt;
&lt;h2&gt;t61codec 3.0.0&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/exhuma/t61codec"&gt;t61codec&lt;/a&gt; is a Python codec for T.61 strings. You still run into those
in ASN.1 data, where they are called &lt;tt class="docutils literal"&gt;TeletexString&lt;/tt&gt;. Version 3.0.0
follows the 1988 version of the ITU-T spec to the letter. Accented
letters decode to precomposed characters, invalid input raises an error
instead of being guessed, and the incremental decoder copes with
sequences that are split across chunks.&lt;/p&gt;
&lt;p&gt;The expected test data was written from the spec, &lt;em&gt;not&lt;/em&gt; from the code.
I also compared the output with glibc's &lt;tt class="docutils literal"&gt;iconv&lt;/tt&gt; over 1696 inputs. All
168 differences are intended and documented.&lt;/p&gt;
&lt;p&gt;This is the last feature release. From now on it only gets fixes.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="x690-2-0-0"&gt;
&lt;h2&gt;x690 2.0.0&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/exhuma/x690"&gt;x690&lt;/a&gt; is the BER encoder and decoder behind &lt;a class="reference external" href="https://github.com/exhuma/puresnmp"&gt;puresnmp&lt;/a&gt;. 2.0.0 is a
breaking release:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;It uses t61codec 3, so T.61 decoding is strict now.&lt;/li&gt;
&lt;li&gt;Context tags are registered per type instead of globally.&lt;/li&gt;
&lt;li&gt;More types decode to proper Python values (&lt;tt class="docutils literal"&gt;str&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;datetime&lt;/tt&gt;,
&lt;tt class="docutils literal"&gt;float&lt;/tt&gt;).&lt;/li&gt;
&lt;li&gt;A decoded value can let go of the input it came from.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;puresnmp and NXP's spsdk both pin &lt;tt class="docutils literal"&gt;x690 &amp;lt;2&lt;/tt&gt;, so they keep working
as before until they move to it.&lt;/p&gt;
&lt;p&gt;It also got a lot faster. Reading items of a decoded sequence by index
was quadratic: 200 items took 40,200 header reads. Now it's at most
600. Decoding a file of 80 MB (on a Ryzen 5 5600X):&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="47%" /&gt;
&lt;col width="28%" /&gt;
&lt;col width="25%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head"&gt;Workload&lt;/th&gt;
&lt;th class="head"&gt;Before&lt;/th&gt;
&lt;th class="head"&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;Full document&lt;/td&gt;
&lt;td&gt;14.4 s / 232 MB&lt;/td&gt;
&lt;td&gt;10.0 s / 8 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Last record only&lt;/td&gt;
&lt;td&gt;2.2 s / 233 MB&lt;/td&gt;
&lt;td&gt;0.71 s / 8 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10,000 records by index&lt;/td&gt;
&lt;td&gt;167 s&lt;/td&gt;
&lt;td&gt;10.5 s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For whole documents, x690 is now the fastest of the five libraries I
benchmarked. pyasn1 needs 146 s and 9.5 GB for the same file. For
streaming, asn1crypto is still faster.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="config-resolver-5-2-0"&gt;
&lt;h2&gt;config_resolver 5.2.0&lt;/h2&gt;
&lt;p&gt;5.2.0 is the last release of &lt;a class="reference external" href="https://github.com/exhuma/config_resolver"&gt;config_resolver&lt;/a&gt;. With the alternatives
around today, I don't see much value in keeping it.&lt;/p&gt;
&lt;p&gt;It now emits a deprecation warning, and the docs have a migration page
with tested replacements: pydantic-settings for services,
&lt;tt class="docutils literal"&gt;ConfigParser&lt;/tt&gt; for existing INI files, and &lt;tt class="docutils literal"&gt;platformdirs&lt;/tt&gt; with
&lt;tt class="docutils literal"&gt;tomllib&lt;/tt&gt; for CLI tools. The repository is archived.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="gouge-2-3-0"&gt;
&lt;h2&gt;gouge 2.3.0&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/exhuma/gouge"&gt;gouge&lt;/a&gt; fixes coloured tracebacks (some viewers lost the colour after
the first line) and adds JSON output and an option to show extra record
attributes, like a trace ID. The default output is byte-identical to
2.2.5, so existing setups don't change.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="docs-and-python-support"&gt;
&lt;h2&gt;Docs and Python Support&lt;/h2&gt;
&lt;p&gt;The docs are now on GitHub Pages:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://exhuma.github.io/t61codec/"&gt;https://exhuma.github.io/t61codec/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://exhuma.github.io/x690/"&gt;https://exhuma.github.io/x690/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://exhuma.github.io/gouge/"&gt;https://exhuma.github.io/gouge/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://exhuma.github.io/config_resolver/"&gt;https://exhuma.github.io/config_resolver/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All four are tested against every supported CPython version, and
releases go out through PyPI's Trusted Publishing.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;puresnmp still pins &lt;tt class="docutils literal"&gt;x690 &amp;lt;2&lt;/tt&gt;, so it doesn't use the new x690 yet.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="programming"/><category term="python"/><category term="opensource"/><category term="x690"/><category term="t61codec"/><category term="gouge"/></entry><entry><title>Nine Years of Quiet Building</title><link href="https://michel.albert.lu/nine-years-of-quiet-building.html" rel="alternate"/><published>2026-03-09T12:00:00+01:00</published><updated>2026-03-09T12:00:00+01:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2026-03-09:/nine-years-of-quiet-building.html</id><summary type="html">&lt;p&gt;The blog went quiet in 2017. The keyboard didn't.&lt;/p&gt;
&lt;p&gt;Here's what happened in the intervening nine years — a quick tour through the
projects that got built, shipped, and occasionally finished.&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;div class="section" id="the-snmp-ecosystem"&gt;
&lt;h2&gt;The SNMP Ecosystem&lt;/h2&gt;
&lt;p&gt;The most sustained body of work, and the one I'm most proud of.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/exhuma/puresnmp"&gt;puresnmp&lt;/a&gt; is a pure …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;The blog went quiet in 2017. The keyboard didn't.&lt;/p&gt;
&lt;p&gt;Here's what happened in the intervening nine years — a quick tour through the
projects that got built, shipped, and occasionally finished.&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;div class="section" id="the-snmp-ecosystem"&gt;
&lt;h2&gt;The SNMP Ecosystem&lt;/h2&gt;
&lt;p&gt;The most sustained body of work, and the one I'm most proud of.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/exhuma/puresnmp"&gt;puresnmp&lt;/a&gt; is a pure Python SNMPv2
library — no C extensions, no compiled dependencies, just Python. The goal was
simple: make SNMP accessible without fighting a build system first. It quietly
grew from a weekend experiment into something with actual users, reaching
&lt;strong&gt;v2.0.1 in July 2024&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Along the way it spawned two companion libraries:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/exhuma/x690"&gt;x690&lt;/a&gt; — X.690 / BER encoding, extracted
into its own package (v1.0.0 in 2022) so other tools could use it
independently.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/exhuma/puresnmp-crypto"&gt;puresnmp-crypto&lt;/a&gt; — DES and AES
encryption support as an optional add-on, keeping the core dependency-free.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The biggest design lesson: carving out a focused, composable library from a
monolith is worth the effort. &lt;tt class="docutils literal"&gt;x690&lt;/tt&gt; being separate means it can evolve
independently. More things should work like this.&lt;/p&gt;
&lt;/div&gt;
&lt;hr class="docutils" /&gt;
&lt;div class="section" id="infrastructure-ops-tooling"&gt;
&lt;h2&gt;Infrastructure &amp;amp; Ops Tooling&lt;/h2&gt;
&lt;p&gt;A few small tools that scratched real itches.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/exhuma/pgflux"&gt;pgflux&lt;/a&gt; ships PostgreSQL monitoring
metrics to InfluxDB. It's one of those tools that does one thing and stays out
of the way — v1.0.0 shipped in 2021 and it hasn't needed much attention since.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/exhuma/weathermonitor"&gt;weathermonitor&lt;/a&gt; captures sensor
data from Zigbee/Phoscon devices and stores it for later. Dockerised in 2023,
which made it actually usable on a home server without ceremony.&lt;/p&gt;
&lt;p&gt;Three smaller utilities that get regular use:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/exhuma/gouge"&gt;gouge&lt;/a&gt; — a small collection of Python
logging configurations, because the stdlib defaults are ugly.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/exhuma/clproc"&gt;clproc&lt;/a&gt; — a changelog processor.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/exhuma/strec"&gt;strec&lt;/a&gt; — a stream coloriser for
stdout/stderr output.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None of these are glamorous. They're the kind of thing you build because the
alternative is doing it by hand every time.&lt;/p&gt;
&lt;/div&gt;
&lt;hr class="docutils" /&gt;
&lt;div class="section" id="web-frontend-work"&gt;
&lt;h2&gt;Web &amp;amp; Frontend Work&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/exhuma/schmackhaft"&gt;schmackhaft&lt;/a&gt; is a self-hosted
bookmark manager inspired by the old del.icio.us. Six releases from v0.5 to
v1.2.3 shipped across 2022. The short answer to &amp;quot;why build your own bookmark
manager in 2022&amp;quot; is: the hosted options are either dead, privacy-hostile, or
both.&lt;/p&gt;
&lt;p&gt;On the component side:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/exhuma/editable-text"&gt;editable-text&lt;/a&gt; — a web component
that makes any text element inline-editable.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/exhuma/copy-able"&gt;copy-able&lt;/a&gt; — a web component for
one-click clipboard copy on any element with a &lt;tt class="docutils literal"&gt;.value&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/exhuma/vue-components"&gt;vue-components&lt;/a&gt; — reusable
VueJS components, started in 2025.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Small, focused, no framework dependencies. The kind of thing that should exist
as a package but rarely does.&lt;/p&gt;
&lt;/div&gt;
&lt;hr class="docutils" /&gt;
&lt;div class="section" id="hardware-iot"&gt;
&lt;h2&gt;Hardware &amp;amp; IoT&lt;/h2&gt;
&lt;p&gt;In 2025 the work moved off the screen entirely.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/exhuma/noise-goblin"&gt;noise-goblin&lt;/a&gt; is a physical button —
ESP32-based, WiFi-connected — that fetches a random sound from an API and plays
it. Originally on a basic ESP32-DevC, it grew an OLED memory display and
eventually moved to the XIAO ESP32S3 module. The commit history from September
2025 tells the story: memory footprint battles, event loop trade-offs, buffer
tuning. Hardware is humbling in ways software rarely is.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/exhuma/spriglet"&gt;spriglet&lt;/a&gt; is a more ambitious project:
a collaborative tabletop device ecosystem for games and activities that need
shared counting or tracking. Still early — the design document landed in
September 2025 — but it's the most interesting hardware direction to date.&lt;/p&gt;
&lt;p&gt;The honest reflection on moving into hardware: everything you know about
debugging becomes unreliable. You can't &lt;tt class="docutils literal"&gt;print()&lt;/tt&gt; your way out of a stack
overflow when there's no stack trace. It's frustrating and completely
absorbing.&lt;/p&gt;
&lt;/div&gt;
&lt;hr class="docutils" /&gt;
&lt;div class="section" id="developer-workflow"&gt;
&lt;h2&gt;Developer Workflow&lt;/h2&gt;
&lt;p&gt;Two recent additions to the toolbox:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/exhuma/taskfiles"&gt;taskfiles&lt;/a&gt; — a collection of reusable
&lt;a class="reference external" href="https://taskfile.dev"&gt;Taskfile&lt;/a&gt; tasks for common project operations. Started
in January 2026 as a way to stop copying the same boilerplate across repos.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/exhuma/timerz"&gt;timerz&lt;/a&gt; — a chess clock implementation,
first commit February 2026. Simple scope, well-contained problem, useful result.&lt;/p&gt;
&lt;/div&gt;
&lt;hr class="docutils" /&gt;
&lt;div class="section" id="what-s-next"&gt;
&lt;h2&gt;What's Next&lt;/h2&gt;
&lt;p&gt;A few things on the horizon:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;JS modernisation&lt;/strong&gt; — &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;closure-easing&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;galeshapley-js&lt;/span&gt;&lt;/tt&gt;, and others
were written for Google Closure Library circa 2012. Time to bring them to
ES6 modules and npm. &lt;a class="reference external" href="https://github.com/exhuma/closure-easing/issues/2"&gt;Issue filed&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;npm publishing&lt;/strong&gt; — several of the web components are useful enough to
publish properly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Profile cleanup&lt;/strong&gt; — archiving old forks and playgrounds that have been
cluttering the profile.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nine years is a long time to go without a post. Hopefully the next one won't
take as long.&lt;/p&gt;
&lt;/div&gt;
</content><category term="programming"/><category term="python"/><category term="javascript"/><category term="hardware"/><category term="retrospective"/><category term="open-source"/></entry><entry><title>Colorize Flask Logging</title><link href="https://michel.albert.lu/colorize-flask-logging.html" rel="alternate"/><published>2017-05-29T10:49:02+02:00</published><updated>2017-05-29T10:49:02+02:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2017-05-29:/colorize-flask-logging.html</id><summary type="html">&lt;p&gt;Here's a simple drop-in colorizer for Werkzeug (and thus also Flask) logs. It
won't make much sense in production, but makes development a bit more cheerful.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;a class="reference external image-reference" href="https://michel.albert.lu/images/colorize_werkzeug.png"&gt;
&lt;img alt="Screenshot" src="https://michel.albert.lu/images/colorize_werkzeug.png" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;Adding &lt;a class="reference external" href="https://pypi.python.org/pypi/gouge"&gt;gouge.colourcli&lt;/a&gt; to the mix,
makes it even more colourful:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;a class="reference external image-reference" href="https://michel.albert.lu/images/colorize_werkzeug2.png"&gt;
&lt;img alt="Screenshot using gouge.colourcli" src="https://michel.albert.lu/images/colorize_werkzeug2.png" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;To use it, simply put it in a utility module somewhere, import it …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Here's a simple drop-in colorizer for Werkzeug (and thus also Flask) logs. It
won't make much sense in production, but makes development a bit more cheerful.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;a class="reference external image-reference" href="https://michel.albert.lu/images/colorize_werkzeug.png"&gt;
&lt;img alt="Screenshot" src="https://michel.albert.lu/images/colorize_werkzeug.png" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;Adding &lt;a class="reference external" href="https://pypi.python.org/pypi/gouge"&gt;gouge.colourcli&lt;/a&gt; to the mix,
makes it even more colourful:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;a class="reference external image-reference" href="https://michel.albert.lu/images/colorize_werkzeug2.png"&gt;
&lt;img alt="Screenshot using gouge.colourcli" src="https://michel.albert.lu/images/colorize_werkzeug2.png" /&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;To use it, simply put it in a utility module somewhere, import it and call
&lt;tt class="docutils literal"&gt;colorize_wekzeug&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;You will need &lt;tt class="docutils literal"&gt;blessings&lt;/tt&gt;. If that's not available, the function will not do
any colorizing.&lt;/p&gt;
&lt;p&gt;The code is hosted as a gist on GitHub:&lt;/p&gt;
&lt;div class="gist"&gt;
    &lt;script src='https://gist.github.com/81515c19eca1d4afaa57051a894b5c5d.js?file=colorize.py'&gt;&lt;/script&gt;
    &lt;noscript&gt;
        &lt;pre&gt;&lt;code&gt;import logging
import re


P_REQUEST_LOG = re.compile(r'^(.*?) - - \[(.*?)\] "(.*?)" (\d+) (\d+|-)$')

LOG = logging.getLogger('werkzeug')


def colorize_werkzeug():
    """
    Fetches the werkzeug logger and adds a color filter.

    This is based on "blessings". If it's not available, this is a no-op!
    """

    try:
        from blessings import Terminal
    except ImportError:
        return

    term = Terminal()
    method_colors = {
        'GET': term.bold_green,
        'POST': term.bold_yellow,
        'PUT': term.bold_blue,
        'DELETE': term.bold_red,
    }

    class WerkzeugColorFilter:

        def filter(self, record):
            match = P_REQUEST_LOG.match(record.msg)
            if match:
                try:
                    ip, date, request_line, status_code, size = match.groups()
                    method = request_line.split(' ')[0]  # key 0 always exists
                    fmt = method_colors.get(method.upper(), term.white)
                    request_line = fmt(request_line)
                    ip = term.blue(ip)
                    date = term.yellow(date)
                    try:
                        status_code_value = int(status_code)
                        if status_code_value &gt;= 500:
                            status_code = term.yellow_on_red(status_code)
                        elif status_code_value &gt;= 400:
                            status_code = term.red(status_code)
                        elif status_code_value &gt;= 300:
                            status_code = term.black_on_yellow(status_code)
                        elif status_code_value &gt;= 200:
                            status_code = term.green(status_code)
                        else:
                            status_code = term.bold_white(status_code)
                    except ValueError:
                        pass
                    record.msg = '%s - - [%s] "%s" %s %s' % (
                        ip, date, request_line, status_code, size
                    )
                except ValueError:
                    pass
            return record

    logging.getLogger('werkzeug').addFilter(WerkzeugColorFilter())&lt;/code&gt;&lt;/pre&gt;
    &lt;/noscript&gt;
&lt;/div&gt;
</content><category term="programming"/><category term="python"/><category term="development"/></entry><entry><title>Testing the Untestable</title><link href="https://michel.albert.lu/testing-the-untestable.html" rel="alternate"/><published>2017-04-13T07:52:20+02:00</published><updated>2017-04-13T07:52:20+02:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2017-04-13:/testing-the-untestable.html</id><summary type="html">&lt;div class="topic"&gt;
&lt;p class="topic-title"&gt;Abstract&lt;/p&gt;
&lt;p&gt;Sometimes you come across a code-base which has no unit-tests. This makes
contributing to the project risky. If an application has not been written
with unit-tests in mind from the beginning, it is often very difficult to
add them later on. This article takes one such project and uses …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="topic"&gt;
&lt;p class="topic-title"&gt;Abstract&lt;/p&gt;
&lt;p&gt;Sometimes you come across a code-base which has no unit-tests. This makes
contributing to the project risky. If an application has not been written
with unit-tests in mind from the beginning, it is often very difficult to
add them later on. This article takes one such project and uses the
fantastic &lt;tt class="docutils literal"&gt;unittest.mock&lt;/tt&gt; Python module to add tests without modifying
the code.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="preface"&gt;
&lt;h2&gt;Preface&lt;/h2&gt;
&lt;p&gt;From personal experience with old code-base maintainance, projects become hard
to unit-test for four main reasons:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Violations of Demeter's Law.&lt;/li&gt;
&lt;li&gt;Fuzzy borders between the main application code and external I/O (like
&lt;tt class="docutils literal"&gt;stdout&lt;/tt&gt;, databases, network services, ...).&lt;/li&gt;
&lt;li&gt;Hidden global state.&lt;/li&gt;
&lt;li&gt;Function-call side-effects / non-pure functions.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are other reasons, but these are by far the ones I've ran across the
most.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;The following article mentions the open-source project &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;munin-influxdb&lt;/span&gt;&lt;/tt&gt;.
It is &lt;em&gt;only&lt;/em&gt; taken as illustrative example and I do not intend to paint
this in a bad light.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;As a starting point, we'll look at commit &lt;a class="reference external" href="https://github.com/mvonthron/munin-influxdb/tree/8b6b4efcac22707c9c00675529e12e8d540e249a"&gt;8b6b4efca of munin-influxdb&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;THe project confronts us with several challenges:&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="challenge-1-no-clear-entry-point"&gt;
&lt;h2&gt;Challenge 1 - No Clear  Entry-Point&lt;/h2&gt;
&lt;p&gt;The project contains a &lt;a class="reference external" href="https://github.com/mvonthron/munin-influxdb/blob/8b6b4efcac22707c9c00675529e12e8d540e249a/muninflux"&gt;shell-script&lt;/a&gt; and separate modules in the &lt;tt class="docutils literal"&gt;bin&lt;/tt&gt; subfolder.
Additionally, the &lt;tt class="docutils literal"&gt;setup.py&lt;/tt&gt; module does not define any &lt;tt class="docutils literal"&gt;entry_points&lt;/tt&gt;&lt;/p&gt;
&lt;div class="section" id="issues"&gt;
&lt;h3&gt;Issues&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;As nothing is packaged probably it becomes non-trivial to install. Neither in
an isolated virtual environment, nor on the system.&lt;/li&gt;
&lt;li&gt;Testing the main entry-point becomes more difficult as it is a bash script.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="solution"&gt;
&lt;h3&gt;Solution&lt;/h3&gt;
&lt;p&gt;Move the scripts from the &lt;tt class="docutils literal"&gt;bin&lt;/tt&gt; folder into the project itself, and remove
the &lt;tt class="docutils literal"&gt;muninflux&lt;/tt&gt; shell script. Use the &lt;a class="reference external" href="http://foo"&gt;argparse&lt;/a&gt; module to provide a
well-known &amp;quot;UI&amp;quot; to the end user. This has been achieved between commit
&lt;a class="reference external" href="https://github.com/exhuma/munin-influxdb/commit/8b6b4efcac22707c9c00675529e12e8d540e249a"&gt;8b6b4efca&lt;/a&gt; and &lt;a class="reference external" href="https://github.com/exhuma/munin-influxdb/commit/acea4515fbee97cb95a400e0fa8b5e1239299871"&gt;acea4515f&lt;/a&gt;.&lt;/p&gt;
&lt;!-- XXX TODO --&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="challenge-2-global-state"&gt;
&lt;h2&gt;Challenge 2 - Global State&lt;/h2&gt;
&lt;p&gt;In order to add unit-tests it is important that one can look at a piece (a
&amp;quot;unit&amp;quot;) of code and can say what it's doing without looking through other parts
of the code. The project makes this difficult in it's current state. It makes
use of a &lt;tt class="docutils literal"&gt;Settings&lt;/tt&gt; class containing key/value pairs which are populated at
run-time by various methods, and are not known in advance. If there's a
function taking a &lt;tt class="docutils literal"&gt;Settings&lt;/tt&gt; instance as argument it's not trivial to &amp;quot;guess&amp;quot;
the structure of that instance to be able to run the function.&lt;/p&gt;
&lt;/div&gt;
</content><category term="programming"/><category term="python"/><category term="unittesting"/><category term="mocking"/><category term="opensource"/></entry><entry><title>Getting Flask-Social working</title><link href="https://michel.albert.lu/getting-flask-social-working.html" rel="alternate"/><published>2016-03-04T21:17:42+01:00</published><updated>2016-03-04T21:17:42+01:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2016-03-04:/getting-flask-social-working.html</id><summary type="html">&lt;p&gt;A couple of weeks ago I decided to add social login buttons to a small
web-page. I am usually wary of &amp;quot;frameworks&amp;quot; and &amp;quot;plugins&amp;quot;, and usually only use
them sparingly. I &lt;em&gt;do&lt;/em&gt; use Flask for web-development though.&lt;/p&gt;
&lt;p&gt;For a change I decided to give &lt;a class="reference external" href="https://pythonhosted.org/Flask-Social"&gt;flask-social&lt;/a&gt; a chance. Turns out that …&lt;/p&gt;</summary><content type="html">&lt;p&gt;A couple of weeks ago I decided to add social login buttons to a small
web-page. I am usually wary of &amp;quot;frameworks&amp;quot; and &amp;quot;plugins&amp;quot;, and usually only use
them sparingly. I &lt;em&gt;do&lt;/em&gt; use Flask for web-development though.&lt;/p&gt;
&lt;p&gt;For a change I decided to give &lt;a class="reference external" href="https://pythonhosted.org/Flask-Social"&gt;flask-social&lt;/a&gt; a chance. Turns out that one is
based on &lt;a class="reference external" href="https://pythonhosted.org/Flask-Security/"&gt;flask-security&lt;/a&gt; so I had to ditch &lt;a class="reference external" href="https://flask-login.readthedocs.org/en/latest/"&gt;flask-login&lt;/a&gt; and that's where the
fun started.&lt;/p&gt;
&lt;div class="section" id="flask-security"&gt;
&lt;h2&gt;Flask Security&lt;/h2&gt;
&lt;p&gt;First, flask-security &lt;em&gt;enforces&lt;/em&gt; that &lt;tt class="docutils literal"&gt;user&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;group&lt;/tt&gt; DB table have an
&lt;tt class="docutils literal"&gt;id&lt;/tt&gt; column. Historically, the PK in my DB is the email address though. Even
&amp;quot;simulating&amp;quot; an &lt;tt class="docutils literal"&gt;id&lt;/tt&gt; column using a &lt;tt class="docutils literal"&gt;property&lt;/tt&gt; did not work. Took me a
while to figure out the problem as all errors are silent.&lt;/p&gt;
&lt;p&gt;Eventually gave up and added an auto-incrementing &lt;tt class="docutils literal"&gt;id&lt;/tt&gt; for both tables
anyway. That made it work. So yay...&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="flask-social"&gt;
&lt;h2&gt;Flask Social&lt;/h2&gt;
&lt;p&gt;This was the worst minefield. For the most part because the documentation is
wrong. Starting off from their &amp;quot;getting started&amp;quot; section of version 1.6.2 won't
get you working social logins. There are several issues:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Not all mentioned modules are Python 3 compatible (flask-social being one of
them).&lt;/li&gt;
&lt;li&gt;The installation of the social &amp;quot;providers&amp;quot; is not completely doable via pip.
Not all packages are available on pypi.&lt;/li&gt;
&lt;li&gt;The profile route breaks as some connections may become &lt;tt class="docutils literal"&gt;None&lt;/tt&gt;. This is
easily fixed by some conditionals.&lt;/li&gt;
&lt;li&gt;Removing a social connection does not work as the associated route does not
allow the &lt;tt class="docutils literal"&gt;DELETE&lt;/tt&gt; method. The only workaraound I found was an XhrIO call.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All in all, the solution is simple. But getting there was not trivial. For two
reasons: One, beaker signals make it hard to follow the flow of the
applications, and two, flask-social uses &lt;tt class="docutils literal"&gt;*args&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;**kwargs&lt;/tt&gt; exessively.
The latter makes it really hard to reason which parameters get passed on to
which function.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="my-current-solution"&gt;
&lt;h2&gt;My (current) solution&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;This document should be read as a companion to the current Flask-Social
docs in case you want to get it to work on Python 3. The official docs are
here:&lt;/p&gt;
&lt;p class="last"&gt;&lt;a class="reference external" href="http://pythonhosted.org/Flask-Social/#getting-started"&gt;http://pythonhosted.org/Flask-Social/#getting-started&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;After much fiddling around, I came up with the following solution. It still
requires a lot of cleanup, but at least, this is a working solution.&lt;/p&gt;
&lt;p&gt;Assuming you have flask-security properly configured, these are the steps to
follow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;For Python 3, install flask-social from my github branch (You may want to
check first if the pypi version has since been updated):&lt;/p&gt;
&lt;pre class="literal-block"&gt;
pip install https://github.com/exhuma/flask-social/tarball/python3-support
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Again for Facebook login with Python 3, install the Facebook API from github
(and check pypi first of course):&lt;/p&gt;
&lt;pre class="literal-block"&gt;
pip install http://github.com/pythonforfacebook/facebook-sdk/tarball/master
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;... the same goes for python-twitter:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
pip install git+https://github.com/bear/python-twitter
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;The google provider seems to be fine.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This should get you set up for Python 3. On to the next step...&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="application-setup"&gt;
&lt;h2&gt;Application Setup&lt;/h2&gt;
&lt;div class="section" id="configuration"&gt;
&lt;h3&gt;Configuration&lt;/h3&gt;
&lt;p&gt;Something not well documented:&lt;/p&gt;
&lt;p&gt;In case you need to pass on different OAuth scopes (f.ex.: getting e-mail
addresses from Google accounts), you need to set the &lt;tt class="docutils literal"&gt;'request_token_params&lt;/tt&gt;
key for your social provider:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;SOCIAL_GOOGLE&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;&amp;#39;consumer_key&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;...&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;&amp;#39;consumer_secret&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;...&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;&amp;#39;request_token_params&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;&amp;#39;scope&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;https://www.googleapis.com/auth/userinfo.profile &amp;#39;&lt;/span&gt;
                  &lt;span class="s1"&gt;&amp;#39;https://www.googleapis.com/auth/plus.me &amp;#39;&lt;/span&gt;
                  &lt;span class="s1"&gt;&amp;#39;https://www.googleapis.com/auth/userinfo.email&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="data-model"&gt;
&lt;h3&gt;Data Model&lt;/h3&gt;
&lt;p&gt;As mentioned earlier, flask-social uses &lt;tt class="docutils literal"&gt;**kwargs&lt;/tt&gt; in places. This causes
problems with the &lt;tt class="docutils literal"&gt;rank&lt;/tt&gt; argument. To fix this without modifying the
flask-social code, you can just override the &lt;tt class="docutils literal"&gt;__init__&lt;/tt&gt; method of your
&lt;tt class="docutils literal"&gt;Connection&lt;/tt&gt; class to accept &lt;tt class="docutils literal"&gt;**kwargs&lt;/tt&gt; as well. You then of course need to
set the values as needed. You also need to add a relationship to your &lt;tt class="docutils literal"&gt;User&lt;/tt&gt;
class:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;relationship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;User&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;user_id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provider_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;provider_id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;provider_user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;provider_user_id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;access_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;access_token&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;secret&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;display_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;display_name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;profile_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;profile_url&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;image_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;image_url&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;rank&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="passing-connections-to-your-template"&gt;
&lt;h3&gt;Passing connections to your template&lt;/h3&gt;
&lt;p&gt;This is tivial. Some connections may be &lt;tt class="docutils literal"&gt;None&lt;/tt&gt;. As such, you need to check
those before calling &lt;tt class="docutils literal"&gt;get_connection&lt;/tt&gt; on them. Additionally, you need to
allow the &lt;tt class="docutils literal"&gt;DELETE&lt;/tt&gt; method so you can remove connections. This &lt;em&gt;seems&lt;/em&gt; to be
caused by a redirect which is used internally in flask-social. This redirect
happens &lt;em&gt;after&lt;/em&gt; the connection has been deleted. So you will land on this
endpoint, still using the &lt;tt class="docutils literal"&gt;DELETE&lt;/tt&gt; method. I simply accept it here, and don't
treat it in a special manner. This is not fully HTTP compliant, but at least it
works:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nd"&gt;@app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/profile&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;GET&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;DELETE&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nd"&gt;@login_required&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s1"&gt;&amp;#39;profile.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Profile Page&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;twitter_conn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;social&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;twitter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_connection&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;social&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;twitter&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;facebook_conn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;social&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;facebook&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_connection&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;social&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;facebook&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;google_conn&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;social&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;google&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_connection&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;social&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;google&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Talking about disconnecting. The flask-social docs use a &lt;tt class="docutils literal"&gt;FORM&lt;/tt&gt; element with
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;action=&amp;quot;DELETE&amp;quot;&lt;/span&gt;&lt;/tt&gt;. This did not work for me and had to replace it with an
XhrIO call (even though this uses closure, the gist should be understandable):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;disconnectButtons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementsByClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;social-disconnect-button&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;disconnectButtons&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EventType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CLICK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAncestorByTagNameAndClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;span&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;providerId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;data-provider-id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;data-user-id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;connectionURL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/connect/&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;providerId&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;net&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;XhrIo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connectionURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isSuccess&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;alertDialog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Dialog&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;alertDialog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Verbindungstrennung fehlgeschlagen.&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;alertDialog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Fehler&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;alertDialog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setButtonSet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Dialog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ButtonSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nx"&gt;alertDialog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;DELETE&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In order to get a consistend look &amp;amp; feel, I used the same way for the login
button and to create connections. This may seem hacky, but it's consisten in
both source-code and UI. I had to use form submits in this case to get around
the same-origin policy:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;loginButtons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementsByClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;login-button&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loginButtons&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EventType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CLICK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAncestorByTagNameAndClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;form&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;connectButtons&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementsByClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;social-connect-button&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connectButtons&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EventType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CLICK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;goog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAncestorByTagNameAndClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;evt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;form&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="programming"/><category term="flask"/><category term="python"/></entry><entry><title>Remapping Keys in Windows</title><link href="https://michel.albert.lu/remapping-keys-in-windows.html" rel="alternate"/><published>2016-01-19T09:10:43+01:00</published><updated>2016-01-19T09:10:43+01:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2016-01-19:/remapping-keys-in-windows.html</id><summary type="html">&lt;p&gt;After having been using Linux for over 20 years now, one of the few things I
really miss in Windows, is the &amp;quot;&lt;a class="reference external" href="https://en.wikipedia.org/wiki/Compose_key"&gt;Compose Key&lt;/a&gt;&amp;quot;. It does exist, but until
today, I was never happy with the mapping. For ages I have this mapped on the
Caps Lock key. But under …&lt;/p&gt;</summary><content type="html">&lt;p&gt;After having been using Linux for over 20 years now, one of the few things I
really miss in Windows, is the &amp;quot;&lt;a class="reference external" href="https://en.wikipedia.org/wiki/Compose_key"&gt;Compose Key&lt;/a&gt;&amp;quot;. It does exist, but until
today, I was never happy with the mapping. For ages I have this mapped on the
Caps Lock key. But under Windows this sometimes leads to a &amp;quot;stuck&amp;quot; caps lock.
I've tried different Compose Key applications on Windows, and they all had the
same problem.&lt;/p&gt;
&lt;p&gt;I was looking for something like &lt;tt class="docutils literal"&gt;.Xmodmap&lt;/tt&gt; on Windows, and today I found it.
You can rebind scan codes using the Windows Registry.&lt;/p&gt;
&lt;p&gt;An example entry might be the following:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
&amp;quot;Scancode Map&amp;quot;=hex:00,00,00,00,00,00,00,00,02,00,00,00,5c,e0,3a,00,00,00,00,00
&lt;/pre&gt;
&lt;p&gt;This maps scan code &lt;tt class="docutils literal"&gt;3a 00&lt;/tt&gt; (usually sent by the caps-lock key) to &lt;tt class="docutils literal"&gt;5c e0&lt;/tt&gt;
(usually sent by the right Windows button). So now pressing caps-lock is
interpreted as the right windows key by the OS. This one can be safely bound as
compose key as it's not a &amp;quot;sticky&amp;quot; key like caps-lock.&lt;/p&gt;
&lt;p&gt;Refernces:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.howtogeek.com/howto/windows-vista/disable-caps-lock-key-in-windows-vista/"&gt;Disabling Caps Lock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://msdn.microsoft.com/en-us/library/aa299374(v=vs.60).aspx"&gt;Scan Codes (official MS site)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html"&gt;Scan Codes (unofficial listing)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content><category term="desktop"/><category term="windows"/></entry><entry><title>Alternative PostgreSQL plugin for munin — Part 4</title><link href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-4.html" rel="alternate"/><published>2015-11-27T13:41:03+01:00</published><updated>2015-11-27T13:41:03+01:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2015-11-27:/alternative-postgresql-plugin-for-munin-part-4.html</id><summary type="html">&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related Posts&lt;/h2&gt;
&lt;p&gt;This post in part in a series:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin.html"&gt;Part 1&lt;/a&gt; — &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-2.html"&gt;Part 2&lt;/a&gt; — &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-3.html"&gt;Part 3&lt;/a&gt; — Part 4 (this post)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="no-longer-alpha"&gt;
&lt;h2&gt;No longer &amp;quot;alpha&amp;quot;&lt;/h2&gt;
&lt;p&gt;After running the graphs for some time, I am happy with the result, and they
have replaced most of the old Postgres graphs at work.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="changes-since-v1-0-0a2"&gt;
&lt;h2&gt;Changes since v1 …&lt;/h2&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related Posts&lt;/h2&gt;
&lt;p&gt;This post in part in a series:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin.html"&gt;Part 1&lt;/a&gt; — &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-2.html"&gt;Part 2&lt;/a&gt; — &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-3.html"&gt;Part 3&lt;/a&gt; — Part 4 (this post)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="no-longer-alpha"&gt;
&lt;h2&gt;No longer &amp;quot;alpha&amp;quot;&lt;/h2&gt;
&lt;p&gt;After running the graphs for some time, I am happy with the result, and they
have replaced most of the old Postgres graphs at work.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="changes-since-v1-0-0a2"&gt;
&lt;h2&gt;Changes since v1.0.0a2&lt;/h2&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;Added &amp;quot;transaction age&amp;quot; to query ages.&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;This value was simply missing.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Disabled value scaling&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;This affects how values are displayed and causes less fractional values.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Added POD-Style documentation&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;Munin graphs require POD documentation. It is readable with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;munin-doc&lt;/span&gt;&lt;/tt&gt;.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Graph Labels/Info&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;Improved the labels and info fields of graphs.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;autoconf&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;The graph is not auto-detectable with autoconf.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Moved to postgresql category&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;The former category was used for testing to keep the graphs better apart.
Now that they are production-ready, this is no longer needed.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Transaction Stats&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;Added graph of committed/rolled-back transactions.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Fixed counters for query-ages&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;The value sometimes came out as NaN. This is now properly reported as &lt;tt class="docutils literal"&gt;0&lt;/tt&gt;.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Added a breakdown of DB sizes&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p class="first"&gt;Opening the DB-Sizes graphs will now show a more detailed view, containing
separate sizes for &amp;quot;main data&amp;quot;, &amp;quot;indexes&amp;quot;, &amp;quot;free-space-map&amp;quot;, &amp;quot;visibility
map&amp;quot; and &amp;quot;TOAST tables&amp;quot;.&lt;/p&gt;
&lt;p class="last"&gt;The values here usually sum up to &lt;em&gt;less&lt;/em&gt; than the raw DB-size value. The
DB-size value counts the on-disk size of the database folder. This may
contain other/temporary files. In extreme cases (catastrophic server
failure), the temporary files may not get cleaned up. This should become
visible in this graph.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Row Access is now stacked&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;This should make the graph more readable.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Added default warning/crtitical values for QueryAges&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;The default warning is 1 hour, the critical limit is set to 12 hours.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;Removed IDLE connections from query ages&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;This blew up the graph in case an application kept an open connection
without active work.&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
</content><category term="sysadmin"/><category term="munin"/><category term="postgresql"/><category term="python"/></entry><entry><title>Alternative PostgreSQL plugin for munin — Part 3</title><link href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-3.html" rel="alternate"/><published>2015-11-11T08:08:21+01:00</published><updated>2015-11-27T14:02:07+01:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2015-11-11:/alternative-postgresql-plugin-for-munin-part-3.html</id><summary type="html">&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related Posts&lt;/h2&gt;
&lt;p&gt;This post in part in a series:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin.html"&gt;Part 1&lt;/a&gt; — &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-2.html"&gt;Part 2&lt;/a&gt; — Part 3 (this post) — &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-4.html"&gt;Part 4&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="comparison-with-the-official-plugins"&gt;
&lt;h2&gt;Comparison with the Official Plugins&lt;/h2&gt;
&lt;p&gt;The most obvious difference you see at first is that it's only one single file
instead of multiple. At this time I'm still pondering to break …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related Posts&lt;/h2&gt;
&lt;p&gt;This post in part in a series:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin.html"&gt;Part 1&lt;/a&gt; — &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-2.html"&gt;Part 2&lt;/a&gt; — Part 3 (this post) — &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-4.html"&gt;Part 4&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="comparison-with-the-official-plugins"&gt;
&lt;h2&gt;Comparison with the Official Plugins&lt;/h2&gt;
&lt;p&gt;The most obvious difference you see at first is that it's only one single file
instead of multiple. At this time I'm still pondering to break it apart, but I
have a strong tendency to leave it as it is.&lt;/p&gt;
&lt;p&gt;If you want to only enable some of the graphs, this can be done using the
&lt;tt class="docutils literal"&gt;PG_MULTIGRAPHS&lt;/tt&gt; environment variable. See &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-2.html"&gt;Part 2&lt;/a&gt; for details on this.&lt;/p&gt;
&lt;p&gt;The main aim of the work was to aggregate those plugins which generated too
many graphs. While they show aggregated values on the default munin overview,
these new graphs  will show a breakdown page once clicking on them.&lt;/p&gt;
&lt;p&gt;Quick overview:&lt;/p&gt;
&lt;blockquote&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="49%" /&gt;
&lt;col width="51%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head"&gt;Official Plugin&lt;/th&gt;
&lt;th class="head"&gt;Name for new plugin&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;postgres_bgwriter&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;Not ported (good enough).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;postgres_checkpoints&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;Not ported (good enough).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;postgres_xlog&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;Not ported (good enough).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;postgres_transactions_&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;Not ported (no use-case).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;postgres_cache_&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;&lt;p class="first"&gt;Replaced with:&lt;/p&gt;
&lt;ul class="last simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;indexio&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;sequenceio&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;tableio&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;postgres_connections_&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;&lt;tt class="docutils literal"&gt;connections&lt;/tt&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;postgres_connections_db&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;Merged with &lt;tt class="docutils literal"&gt;connections&lt;/tt&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;postgres_users&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;Merged with &lt;tt class="docutils literal"&gt;connections&lt;/tt&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;postgres_locks_&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;&lt;tt class="docutils literal"&gt;locks&lt;/tt&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;postgres_querylength_&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;&lt;tt class="docutils literal"&gt;query_ages&lt;/tt&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;postgres_scans_&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;&lt;tt class="docutils literal"&gt;scan_types&lt;/tt&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;postgres_size_&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;&lt;tt class="docutils literal"&gt;sizes&lt;/tt&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;postgres_tuples_&lt;/tt&gt;&lt;/td&gt;
&lt;td&gt;&lt;tt class="docutils literal"&gt;row_access&lt;/tt&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="design-decisions"&gt;
&lt;h2&gt;Design Decisions&lt;/h2&gt;
&lt;div class="section" id="general"&gt;
&lt;h3&gt;General&lt;/h3&gt;
&lt;p&gt;Most graph aggregations use stacked areas to display values. The idea behind
this is that you are usually interested in the total value. Using stacks gives
you a much better view of this. Overlapping lines are more useful to see
correlations between values.&lt;/p&gt;
&lt;p&gt;Most aggregations show the sum of all the agregates. In the case of the query
ages, it shows the maximum of all the aggregates.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="replacing-postgres-cache-with-3-new-i-o-plugins"&gt;
&lt;h3&gt;Replacing &lt;tt class="docutils literal"&gt;postgres_cache_&lt;/tt&gt; with 3 new I/O Plugins&lt;/h3&gt;
&lt;p&gt;While investigating, I discovered the following stats tables:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.postgresql.org/docs/9.2/static/monitoring-stats.html#PG-STATIO-ALL-TABLES-VIEW"&gt;pg_statio_user_tables&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.postgresql.org/docs/9.2/static/monitoring-stats.html#PG-STATIO-ALL-SEQUENCES-VIEW"&gt;pg_statio_user_sequences&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.postgresql.org/docs/9.2/static/monitoring-stats.html#PG-STATIO-ALL-INDEXES-VIEW"&gt;pg_statio_user_indexes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;They give a more fine-grained view on buffer I/O than &lt;a class="reference external" href="http://www.postgresql.org/docs/9.2/static/monitoring-stats.html#PG-STAT-DATABASE-VIEW"&gt;pg_stat_database&lt;/a&gt; and
decided to split that one up.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="connections-to-the-db"&gt;
&lt;h3&gt;Connections to the DB&lt;/h3&gt;
&lt;p&gt;This currently shows connections by user. It does &lt;em&gt;not&lt;/em&gt; show connections per DB
(yet?). I currently have no pressing plans to include connections per DB. So I
will leave it as-is for the time being.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="locks"&gt;
&lt;h3&gt;Locks&lt;/h3&gt;
&lt;p&gt;The official plugin combines both locks which are granted with locks which
aren't (somewhere someone's waiting for the release). Personally, I find it
more important to watch for waiting locks than for granted locks. For this
reason, this plugin now splits both lock types up, showing granted locks on one
side of the X-axis, and waiting locks on the other.&lt;/p&gt;
&lt;p&gt;This still keeps all the information from the old graphs, but adds an
additional element to it.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="query-ages"&gt;
&lt;h3&gt;Query Ages&lt;/h3&gt;
&lt;p&gt;I decided to use &amp;quot;age&amp;quot; instead of &amp;quot;length&amp;quot; as, in the context of a graph, this
makes more sense. Maybe I was a bit too nitpicky here.&lt;/p&gt;
&lt;p&gt;The official graph shows both query and transaction start. The transaction
start is currently not yet implemented in the new graph, but I will do so once
this blog-post is done.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="scan-types"&gt;
&lt;h3&gt;Scan Types&lt;/h3&gt;
&lt;p&gt;Nothing of importance to say here.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="sizes"&gt;
&lt;h3&gt;Sizes&lt;/h3&gt;
&lt;p&gt;Nothing of importance to say here.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="row-access"&gt;
&lt;h3&gt;Row Access&lt;/h3&gt;
&lt;p&gt;Named &lt;em&gt;Tuple Access&lt;/em&gt; in the official plugins. I renamed it as the statistics
table in PG also talks about &amp;quot;row access&amp;quot;. So do the docs.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="sysadmin"/><category term="munin"/><category term="postgresql"/><category term="python"/></entry><entry><title>Alternative PostgreSQL plugin for munin — Part 2</title><link href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-2.html" rel="alternate"/><published>2015-11-10T08:00:49+01:00</published><updated>2015-11-27T14:01:34+01:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2015-11-10:/alternative-postgresql-plugin-for-munin-part-2.html</id><summary type="html">&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related Posts&lt;/h2&gt;
&lt;p&gt;This post in part in a series:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin.html"&gt;Part 1&lt;/a&gt; — Part 2 (this post) — &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-3.html"&gt;Part 3&lt;/a&gt; — &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-4.html"&gt;Part 4&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="first-alpha-releases"&gt;
&lt;h2&gt;First Alpha Releases&lt;/h2&gt;
&lt;p&gt;I have finished porting all &amp;quot;virtual&amp;quot; graphs from the official plugins. The
source of this release can be found &lt;a class="reference external" href="https://github.com/exhuma/munin-plugins/tree/postgres-multigraph/v1.0.0a2"&gt;on github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is currently a very rough cut …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related Posts&lt;/h2&gt;
&lt;p&gt;This post in part in a series:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin.html"&gt;Part 1&lt;/a&gt; — Part 2 (this post) — &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-3.html"&gt;Part 3&lt;/a&gt; — &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-4.html"&gt;Part 4&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="first-alpha-releases"&gt;
&lt;h2&gt;First Alpha Releases&lt;/h2&gt;
&lt;p&gt;I have finished porting all &amp;quot;virtual&amp;quot; graphs from the official plugins. The
source of this release can be found &lt;a class="reference external" href="https://github.com/exhuma/munin-plugins/tree/postgres-multigraph/v1.0.0a2"&gt;on github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is currently a very rough cut release. Keep in mind:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;There is barely any documentation&lt;/li&gt;
&lt;li&gt;The plugin does not support &lt;tt class="docutils literal"&gt;autoconfig&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;It is likely that some major refactoring will go on once the docs are
written.&lt;/li&gt;
&lt;li&gt;Maybe things will change. Maybe not.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="trying-it-out"&gt;
&lt;h2&gt;Trying it out&lt;/h2&gt;
&lt;div class="section" id="installation"&gt;
&lt;h3&gt;Installation&lt;/h3&gt;
&lt;p&gt;Installing the plugin is fairly easy:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p class="first"&gt;Clone the &lt;a class="reference external" href="https://github.com/exhuma/munin-plugins.git"&gt;github repository&lt;/a&gt; somewhere and switch to the alpha tag:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
git clone https://github.com/exhuma/munin-plugins.git /opt/exhuma/munin-plugins
cd /opt/exhuma/munin-plugins
git checkout postgres-multigraph/v1.0.0a2
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Install &lt;tt class="docutils literal"&gt;psycopg2&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
apt-get install python-psycopg2
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Symlink the plugin into your munin-node:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
ln -s /opt/exhuma/munin-plugins/pg_multigraph /etc/munin/plugins/pg_multigraph
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="configuration"&gt;
&lt;h3&gt;Configuration&lt;/h3&gt;
&lt;p&gt;The plugin reads the following environment variables:&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;PG_DBNAME (&lt;em&gt;default='template1'&lt;/em&gt;)&lt;/dt&gt;
&lt;dd&gt;The database name to connect to.&lt;/dd&gt;
&lt;dt&gt;PG_USER (&lt;em&gt;default='postgres'&lt;/em&gt;)&lt;/dt&gt;
&lt;dd&gt;The username used to connect.&lt;/dd&gt;
&lt;dt&gt;PG_PASSWORD (&lt;em&gt;default=''&lt;/em&gt;)&lt;/dt&gt;
&lt;dd&gt;The password used to connect. If empty, perform a passwordless login.&lt;/dd&gt;
&lt;dt&gt;PG_HOST (&lt;em&gt;default=''&lt;/em&gt;)&lt;/dt&gt;
&lt;dd&gt;The DB host. If empty, connect using the unix domain socket.&lt;/dd&gt;
&lt;dt&gt;PG_PORT (&lt;em&gt;default=0&lt;/em&gt;)&lt;/dt&gt;
&lt;dd&gt;The port which is used to connect. If &lt;tt class="docutils literal"&gt;0&lt;/tt&gt;, connect using the unix domain socket.&lt;/dd&gt;
&lt;dt&gt;PG_MULTIGRAPHS (&lt;em&gt;default='__all__'&lt;/em&gt;)&lt;/dt&gt;
&lt;dd&gt;&lt;p class="first"&gt;A comma-separated list of which graphs to create. At the time of this
writing the following names are accepted:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;__all__&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;connections&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;locks&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;query_ages&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;row_access&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;scantypes&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;sizes&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;indexio&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;sequenceio&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;tableio&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p class="last"&gt;The special name &lt;tt class="docutils literal"&gt;__all__&lt;/tt&gt; causes all graphs to be generated.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="what-s-different"&gt;
&lt;h2&gt;What's different?&lt;/h2&gt;
&lt;p&gt;Compared to the plugins bundled with munin, there are a couple of differences
in the generated graphs:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Locks show both &amp;quot;granted&amp;quot; and &amp;quot;waiting&amp;quot; locks. The official plugin did not
differentiate between both.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;postgres_transactions_&lt;/tt&gt; has not been ported. I have not use-case for that
one.&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;index scan&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;sequential scan&lt;/tt&gt; is removed from &lt;tt class="docutils literal"&gt;tuple access&lt;/tt&gt;. It
is now also related to &lt;tt class="docutils literal"&gt;row access&lt;/tt&gt;. Both scan fetches are more related to
indices and pollute that graph.&lt;/li&gt;
&lt;li&gt;Buffer Cache has been removed and replaced by sepearate I/O plugins for
Tables, Sequences and Indices.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="screenshots"&gt;
&lt;h2&gt;Screenshots?&lt;/h2&gt;
&lt;p&gt;I have currently no screenshots at hand which are really representative. All I
have is some &amp;quot;work in progress&amp;quot; stuff from my laptop. They don't represent the
graphs very well.&lt;/p&gt;
&lt;/div&gt;
</content><category term="sysadmin"/><category term="munin"/><category term="postgresql"/><category term="python"/></entry><entry><title>Alternative PostgreSQL plugin for munin</title><link href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin.html" rel="alternate"/><published>2015-11-08T10:22:49+01:00</published><updated>2015-11-27T14:00:34+01:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2015-11-08:/alternative-postgresql-plugin-for-munin.html</id><summary type="html">&lt;div class="section" id="abstract"&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;p&gt;I've been using the PostgreSQL graphs which come bundled with munin for quite
some time. But recently I've come annoyed with the amount of graphs those
plugins generate. I've decided to fix this in the existing plugins, but ran
into a design dilemma. It prompted me to re-write the …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="abstract"&gt;
&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;p&gt;I've been using the PostgreSQL graphs which come bundled with munin for quite
some time. But recently I've come annoyed with the amount of graphs those
plugins generate. I've decided to fix this in the existing plugins, but ran
into a design dilemma. It prompted me to re-write the plugins. During this I
discovered a couple of interesting facts about both PostgreSQL stats, and the
existing graphs. This blog-post (which is the first in a series) will give some
context to the ongoing development and put my thoughs &amp;quot;on paper&amp;quot;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related Posts&lt;/h2&gt;
&lt;p&gt;Part 1 (this post) — &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-2.html"&gt;Part 2&lt;/a&gt; — &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-3.html"&gt;Part 3&lt;/a&gt; — &lt;a class="reference external" href="https://michel.albert.lu/alternative-postgresql-plugin-for-munin-part-4.html"&gt;Part 4&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="stipulations"&gt;
&lt;h2&gt;Stipulations&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;First&lt;/strong&gt;, the new plugins should work like the &lt;tt class="docutils literal"&gt;snmp__if_multi&lt;/tt&gt; plugin.
Meaning, the main dashboard should show an aggregated graph. Upon clicking on
it it should show a more readable breakdown before going to the yearly
overview. &lt;strong&gt;Second&lt;/strong&gt;, the graphs should avoid an excessive number of
overlapping values on one graph, utilising negative axis where possible.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="why-modify-the-existing-graphs"&gt;
&lt;h2&gt;Why modify the existing graphs?&lt;/h2&gt;
&lt;p&gt;The current plugins have a couple of &amp;quot;pain-points&amp;quot;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;New symlinks have to be created each time a database is created/deleted. If
you forget it, the DB will not be graphed.&lt;/li&gt;
&lt;li&gt;There are (currently) 17 &lt;a class="reference external" href="https://github.com/munin-monitoring/munin/tree/b163c3f94688277bf8b075c6bb116e45065bb6e8/plugins/node.d"&gt;official postgres plugins&lt;/a&gt;. Of these 17 plugins,
11 are &amp;quot;virtual&amp;quot; plugins which have to be symlinked for each database. This
means that a system multiple databases will generate 6 + 11 * &amp;lt;num databases&amp;gt;
graphs. That is a &lt;em&gt;lot&lt;/em&gt; of graphs.&lt;/li&gt;
&lt;li&gt;Some graphs (f. ex. &amp;quot;Connections by User&amp;quot;) are a bit hard to read as they can
generate a lot of overlapping lines.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="why-a-re-write-the-design-dilemma"&gt;
&lt;h2&gt;Why a re-write? (The &amp;quot;design dilemma&amp;quot;)&lt;/h2&gt;
&lt;p&gt;My first reflex was to grab the sources of the existing plugins. I ran into one
major issue:&lt;/p&gt;
&lt;p&gt;The plugins rely on &lt;a class="reference external" href="https://github.com/munin-monitoring/munin/blob/b163c3f94688277bf8b075c6bb116e45065bb6e8/lib/Munin/Plugin/Pgsql.pm"&gt;a perl module bundled with munin&lt;/a&gt;. This module is
non-trivial, forces the plugin-author to write SQL queries which return a
schema as required by the plugin. This makes some queries more complex than
necessary. It also makes contributions more difficult as the module tightly
couples the plugin with munin itself.&lt;/p&gt;
&lt;p&gt;While the library generalises many of the aspects of plugin authoring, it
&lt;em&gt;overgeneralises&lt;/em&gt; (in my own , personal opinion) which renders the plugins a
lot harder to read and modify. Some graphs may warrant top be displayed
differently than others. By using the same library for all, this customisation
gets lost. And supporting the customisation, is counter-productive to the
generalisation.&lt;/p&gt;
&lt;p&gt;A re-write allows me to decouple the plugins from the library and make them
standalone executables. This makes them easier to debug and more approachable
by potential contributors.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="design-decisions"&gt;
&lt;h2&gt;Design Decisions&lt;/h2&gt;
&lt;div class="section" id="code-structure"&gt;
&lt;h3&gt;Code Structure&lt;/h3&gt;
&lt;p&gt;I like munin plugins to be nicely self-contained executables. However, in this
case, the plugins &lt;em&gt;have&lt;/em&gt; some common properties. In its minimal form, those are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The DB connection parameters&lt;/li&gt;
&lt;li&gt;The graph category&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Especially considering the connection parameters, one could argue that this
part of the code should be shared amongst the plugins. But I don't want to
extract a library. There's no good place to put it if the plugins should remain
self-contained.&lt;/p&gt;
&lt;p&gt;There are two solutions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;One huge script generating the graphs using the &lt;tt class="docutils literal"&gt;multigraph&lt;/tt&gt; statement.&lt;/li&gt;
&lt;li&gt;Don't share the code.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In a first iteration, I have opted to writing a multigraph plugin. Currently,
the amount of shared code is fairly small. I am considering ripping them apart
and &lt;em&gt;not&lt;/em&gt; share any code.&lt;/p&gt;
&lt;p&gt;I did however not yet fully walk through the code and examine shareable parts.
I will investigate this further in the future.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="graph-visualisation"&gt;
&lt;h3&gt;Graph Visualisation&lt;/h3&gt;
&lt;p&gt;Most graphs can be designed such that they have an intermediary &amp;quot;breakdown&amp;quot;
graph. A good example is the databse size. It can be written such that it shows
all sizes on one stacked graph on the munin overwiew. Then, when clicking on
it, you will be sent to a page listing daily/weekly graphs for each database.
Clicking on those will send you to the dayly/weekly/monthly/yearly graph of
that DB.&lt;/p&gt;
&lt;p&gt;Using that method will keep the main munin overview much cleaner than the
original graphs while not losing any information.&lt;/p&gt;
&lt;p&gt;Another way to improve visualisation is using the negative axis. A good example
here are locks and disk/buffer I/O. For locks, granted locks can be drawn on
the positive axis, while the waiting locks of the same type can be shown on the
negative axis. Fo I/O graphs, buffer hits can be shown as positive values, and
disk reads of the same time can be drawn as negative values.&lt;/p&gt;
&lt;p&gt;Using both positive and negative values cuts down the number of colors used on
a graph by a factor of 2. And thus make it easier to read again.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Example Table I/O using both positive and negative axis." src="https://michel.albert.lu/images/munin/tableio.png" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="current-state"&gt;
&lt;h2&gt;Current State&lt;/h2&gt;
&lt;p&gt;I am currently writing a minimal viable product to replace the existing
plugins. As of today, I have working graphs for:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Connections (breakdown by user)&lt;/li&gt;
&lt;li&gt;Sizes&lt;/li&gt;
&lt;li&gt;Locks&lt;/li&gt;
&lt;li&gt;QueryAges&lt;/li&gt;
&lt;li&gt;TableDiskIO (former buffer-cache)&lt;/li&gt;
&lt;li&gt;IndexDiskIO (former buffer-cache)&lt;/li&gt;
&lt;li&gt;SequencesDiskIO (former buffer-cache)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The current source can be found &lt;a class="reference external" href="https://github.com/exhuma/munin-plugins/blob/postgres-multigraphs/pg_multigraph"&gt;on github&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</content><category term="sysadmin"/><category term="munin"/><category term="postgresql"/><category term="python"/></entry><entry><title>How to write "nested" graphs for Munin</title><link href="https://michel.albert.lu/how-to-write-nested-graphs-for-munin.html" rel="alternate"/><published>2015-10-11T10:58:21+02:00</published><updated>2015-10-11T10:58:21+02:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2015-10-11:/how-to-write-nested-graphs-for-munin.html</id><summary type="html">&lt;div class="section" id="preface"&gt;
&lt;h2&gt;Preface&lt;/h2&gt;
&lt;p&gt;To make this tutorial useful to an as wide audience as possible, I will begin
to explain the basics of Munin plugins first. If you are only interested in
nested graphs, feel free to directly jump to either the &lt;a class="reference internal" href="#multigraphs"&gt;Multigraphs&lt;/a&gt; or
&lt;a class="reference internal" href="#nested-graphs"&gt;Nested Graphs&lt;/a&gt; section.&lt;/p&gt;
&lt;div class="section" id="terms-used"&gt;
&lt;h3&gt;Terms Used&lt;/h3&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;dashboard&lt;/dt&gt;
&lt;dd&gt;The default …&lt;/dd&gt;&lt;/dl&gt;&lt;/div&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="preface"&gt;
&lt;h2&gt;Preface&lt;/h2&gt;
&lt;p&gt;To make this tutorial useful to an as wide audience as possible, I will begin
to explain the basics of Munin plugins first. If you are only interested in
nested graphs, feel free to directly jump to either the &lt;a class="reference internal" href="#multigraphs"&gt;Multigraphs&lt;/a&gt; or
&lt;a class="reference internal" href="#nested-graphs"&gt;Nested Graphs&lt;/a&gt; section.&lt;/p&gt;
&lt;div class="section" id="terms-used"&gt;
&lt;h3&gt;Terms Used&lt;/h3&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;dashboard&lt;/dt&gt;
&lt;dd&gt;The default view when opening the Munin web-interface. It shows daily and
weekly graphs for each plugin.&lt;/dd&gt;
&lt;dt&gt;year-view&lt;/dt&gt;
&lt;dd&gt;The view when clicking on a traditional graph. It shows daily, weekly,
monthly and yearly graphs for the selected plugin.&lt;/dd&gt;
&lt;dt&gt;breakdown&lt;/dt&gt;
&lt;dd&gt;The view when clicking on a &lt;em&gt;nested&lt;/em&gt; graph. It shows daily and weekly
graphs for each subgraph in the selected plugin.&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="basics"&gt;
&lt;h2&gt;Basics&lt;/h2&gt;
&lt;p&gt;I will try to show a comprehensive minimal example starting from a simple
plugin, but if you have not yet read &lt;a class="reference external" href="http://munin-monitoring.org/wiki/HowToWritePlugins"&gt;the tutorial on how to write plugins&lt;/a&gt; &lt;a class="footnote-reference" href="#footnote-1" id="footnote-reference-1"&gt;[1]&lt;/a&gt;,
you should.&lt;/p&gt;
&lt;p&gt;I will &lt;em&gt;not&lt;/em&gt; show any plugin source-code. But rather focus on the output that
Munin needs to see on stdout!&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="footnote-1" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#footnote-reference-1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;At the time of this writing, the Munin documentation is undergoing a
transition, but the plugin authoring document is still at it's old location!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="walkthrough"&gt;
&lt;h2&gt;Walkthrough&lt;/h2&gt;
&lt;div class="section" id="essentials"&gt;
&lt;h3&gt;Essentials&lt;/h3&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;You can skip this if you already know how to write simple plugins.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Let's start with a simple, basic plugin. At the very least you need to handle
two cases:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;The plugin is called without arguments, and&lt;/li&gt;
&lt;li&gt;The plugin is called with the argument &lt;tt class="docutils literal"&gt;config&lt;/tt&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Munin runs the plugin with the &lt;tt class="docutils literal"&gt;config&lt;/tt&gt; argument to figure out what values to expect
and how to graph them (lines, areas, stacks, colours, labels, …).&lt;/p&gt;
&lt;p&gt;The absolute minimum looks like this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ /path/to/plugin config
graph_title Really simple, static graph
graph_vlabel Static value
myvar.label Static value
&lt;/pre&gt;
&lt;p&gt;This will create a graph named &lt;tt class="docutils literal"&gt;Really simple, static graph&lt;/tt&gt; in the category
&lt;tt class="docutils literal"&gt;other&lt;/tt&gt; (the default). It will expect values for a variable named &lt;tt class="docutils literal"&gt;myvar&lt;/tt&gt;.
You can of course name it however you like.  For more configuration options,
look up &lt;a class="reference external" href="http://munin-monitoring.org/wiki/HowToWritePlugins"&gt;the official Munin documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next, now that Munin knows what variables to expect, it will get them by
calling the plugin without any arguments. It expects a line for each variable
with its value. In our case:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ /path/to/plugin
myvar.value 10
&lt;/pre&gt;
&lt;p&gt;This is all you need for a basic plugin. There is much more to know about
plugins. This is out of the scope of this tutorial. See the official
documentation for that.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="using-the-same-code-for-multiple-graphs-essentials-2"&gt;
&lt;h3&gt;Using the same code for multiple graphs (essentials #2)&lt;/h3&gt;
&lt;p&gt;Sometimes you can run the same core code for multiple graphs while only
changing one variable. A good example is the graph for network interface
statistics.  Traditionally, this is achieved by creating one core plugin, then
symlinking that with other names. This lets you use the basename of the
executable to determine the variable. Example:&lt;/p&gt;
&lt;dl class="docutils"&gt;
&lt;dt&gt;&lt;strong&gt;if_&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;This plugin on its own does nothing.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;if_eth0&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;Symlink to &lt;tt class="docutils literal"&gt;if_&lt;/tt&gt;. Accessing the basename and cutting off &lt;tt class="docutils literal"&gt;if_&lt;/tt&gt; lets you
determine that the stats are supposed to run for &lt;tt class="docutils literal"&gt;eth0&lt;/tt&gt;.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Now you can run the same code-base for multiple graphs.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="multigraphs"&gt;
&lt;h3&gt;Multigraphs&lt;/h3&gt;
&lt;p&gt;The above method to run multiple graphs has a few downsides:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The whole plugin has to be executed for each variable. Even if it could
technically share some data between executions. This can be wasteful if it's
an expensive process.&lt;/li&gt;
&lt;li&gt;For each new created link, the munin-node needs to be restarted. It cannot be
dynamically add/remove graphs.&lt;/li&gt;
&lt;li&gt;It potentially create a &lt;em&gt;lot&lt;/em&gt; of graphs on the &amp;quot;dashboard&amp;quot;. A good culprit
for this are the PostgreSQL plugins. This easily creates more than 5 graphs
per database, and can be painful to scroll through on a system with many DBs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Multigraphs tackle these problems one way or another. The latter one is solved
by using &amp;quot;nested&amp;quot; graphs which we'll get to shortly.&lt;/p&gt;
&lt;p&gt;The Munin documentation claims that multigraphs tend to be complex. While that
may be true for some cases, I personally find that they are still very easy to
write for basic needs.&lt;/p&gt;
&lt;p&gt;To write a multigraph, the only thing you need, is preface each graph with the
&lt;tt class="docutils literal"&gt;multigraph&lt;/tt&gt; statement. Here's an example defining two graphs in one
&lt;tt class="docutils literal"&gt;config&lt;/tt&gt; command:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ /path/to/plugin config
multigraph myfirstgraph
graph_title Really simple, static graph
graph_vlabel Static value
myvar.label Static value

multigraph mysecondgraph
graph_title Another , static graph
graph_vlabel Static value
myvar.label Static value
&lt;/pre&gt;
&lt;p&gt;This will generate two graphs named &lt;tt class="docutils literal"&gt;myfirstgraph&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;mysecondgraph&lt;/tt&gt;.
They are both &lt;em&gt;completely independent&lt;/em&gt;! The big difference to classical plugins
is that they are generated by the same process. And can thus share expensive
resources.&lt;/p&gt;
&lt;p&gt;Additionally, if the process generates more &lt;tt class="docutils literal"&gt;multigraph&lt;/tt&gt; sections on
subsequent runs, new graphs will dynamically appear. Conversely, if existing
&lt;tt class="docutils literal"&gt;multigraph&lt;/tt&gt; section &lt;em&gt;disappears&lt;/em&gt;, the corresponding graph(s) will disappear
as well!&lt;/p&gt;
&lt;div class="admonition warning"&gt;
&lt;p class="first admonition-title"&gt;Warning&lt;/p&gt;
&lt;p class="last"&gt;At the time of this writing, RRD files of graphs are &lt;em&gt;not&lt;/em&gt; removed when a
multigraph section disappears! So be careful not to fill up the disk with
&amp;quot;temporary&amp;quot; graphs!&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This is extremely useful for situations where graphs can appear/disappear
during the life-time of the monitored node. A good example is the
aforementioned PostgreSQL situation. With the classic plugins, you need to
create a new symlink and reload the node each time a new DB is created.&lt;/p&gt;
&lt;p&gt;But how about the values? They are generated in the same way as the config:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ /path/to/plugin
multigraph myfirstgraph
myvar.value 10

multigraph mysecondgraph
myvar.value 20
&lt;/pre&gt;
&lt;p&gt;Note that the variable names and values are &lt;em&gt;local&lt;/em&gt; to the corresponding
&lt;tt class="docutils literal"&gt;multigraph&lt;/tt&gt; section of the config! In this example both &lt;tt class="docutils literal"&gt;myvar&lt;/tt&gt; variables
are completely independent!&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="nested-graphs"&gt;
&lt;h2&gt;Nested Graphs&lt;/h2&gt;
&lt;div class="section" id="what-are-nested-graphs"&gt;
&lt;h3&gt;What are &amp;quot;nested&amp;quot; graphs?&lt;/h3&gt;
&lt;p&gt;The default Munin view (the &amp;quot;dashboard&amp;quot;) shows you the day and week view of
each graph.&lt;/p&gt;
&lt;p&gt;When clicking on one of those graphs, you will see an overview of the selected
plugin including the month and year. The &amp;quot;year-view&amp;quot;.&lt;/p&gt;
&lt;p&gt;A &amp;quot;nested&amp;quot; graph adds one additional &amp;quot;breakdown&amp;quot; step between the default and
&amp;quot;year-view&amp;quot; to this.&lt;/p&gt;
&lt;p&gt;So instead of going:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
dashboard → year-view
&lt;/pre&gt;
&lt;p&gt;You will go:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
dashboard → breakdown → year view
&lt;/pre&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;The values you report for the dashboard do not necessarily have to be
related to the breakdown! While this might not seem to make sense at first
sight, there may be some intersting applications for this. Just keep in
mind that &lt;strong&gt;you can report completely different values with a different
config on the &amp;quot;dashboard&amp;quot; as on the &amp;quot;breakdown&amp;quot;!&lt;/strong&gt; An interesting exmple
might be a dashboard graph reporting an arbitrry &amp;quot;I/O health&amp;quot; score based
on inode usage, disk IOs and IOstat. Then on the breakdown, report each
individual graph.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="writing-nested-graphs"&gt;
&lt;h3&gt;Writing Nested Graphs&lt;/h3&gt;
&lt;p&gt;Writing nested graphs is extremely easy, and build on &lt;a class="reference internal" href="#multigraphs"&gt;Multigraphs&lt;/a&gt; and simply
uses names separated by dots. For example, if you have one &amp;quot;dashboard&amp;quot; graph
named &lt;tt class="docutils literal"&gt;summaryscore&lt;/tt&gt; and two &amp;quot;breakdown&amp;quot; charts called &lt;tt class="docutils literal"&gt;diskscore&lt;/tt&gt; and
&lt;tt class="docutils literal"&gt;cpuscore&lt;/tt&gt;, the names shown in the multigraph config are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;summaryscore&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;summaryscore.diskscore&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;summaryscore.cpuscore&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The config would look like this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ /path/to/plugin config
multigraph summaryscore
graph_title Summery Health Score
graph_vlabel Score (higher = better)
health_summary.label Health Summary

multigraph summaryscore.diskscore
graph_title Disk score
graph_vlabel Disk score (higher = better)
temperature_score.label Temperature
iowait_score.label IO Wait
mtbf_score.label MTBF
mtbf_score.info Days until MTBF

multigraph summaryscore.cpuscore
graph_title CPU score
graph_vlabel CPU score (higher = better)
temperature_score.label Temperature
age_score.label Age
age.info Age of the CPU
&lt;/pre&gt;
&lt;p&gt;The corresponding values would look like this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ /path/to/plugin
multigraph summaryscore
health_summary.value 98

multigraph summaryscore.diskscore
temperature_score.label 99
iowait_score.label 99
mtbf_score.label 65

multigraph summaryscore.cpuscore
temperature_score.label 87
age_score.label 99
&lt;/pre&gt;
&lt;p&gt;This would create only one graph (&amp;quot;Summary Health Score&amp;quot;) on the dashboard. And
once you would click on it you would see the week-view of the two sub-graphs
&amp;quot;Disk Score&amp;quot; and &amp;quot;CPU Score&amp;quot;.&lt;/p&gt;
&lt;p&gt;How the values are determined is entirely up to you.&lt;/p&gt;
&lt;p&gt;Now, the above example is extremely contrived, and I have no real-world
example. But it should get the point across.&lt;/p&gt;
&lt;p&gt;Hope this helped and made writing Munin plugins easier.&lt;/p&gt;
&lt;p&gt;Happy coding!&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="sysadmin"/><category term="munin"/><category term="monitoring"/></entry><entry><title>Controlling Raspberry-Pi LEDs the Hard Way</title><link href="https://michel.albert.lu/controlling-raspberry-pi-leds-the-hard-way.html" rel="alternate"/><published>2015-07-16T20:39:07+02:00</published><updated>2015-07-16T20:39:07+02:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2015-07-16:/controlling-raspberry-pi-leds-the-hard-way.html</id><summary type="html">&lt;p&gt;Yesterday I finally got my hands on a multimeter and could read out resistor
values. As a colourblind person, I was unaware that this would bite me.&lt;/p&gt;
&lt;p&gt;I decided to go ahead and play around with a simple schematic. The goal: Make
the LED light up as long as the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Yesterday I finally got my hands on a multimeter and could read out resistor
values. As a colourblind person, I was unaware that this would bite me.&lt;/p&gt;
&lt;p&gt;I decided to go ahead and play around with a simple schematic. The goal: Make
the LED light up as long as the button is pressed.&lt;/p&gt;
&lt;p&gt;I decided to do all with a multiprocessed Python application. You know... for
funsies. But also because I am more of a software than a hardware guy.&lt;/p&gt;
&lt;p&gt;To access the GPIOs, I'm using the excellent &lt;a class="reference external" href="http://abyz.co.uk/rpi/pigpio/python.html"&gt;pigpio&lt;/a&gt; library.&lt;/p&gt;
&lt;div class="section" id="the-challenge"&gt;
&lt;h2&gt;The Challenge&lt;/h2&gt;
&lt;p&gt;Write a Python application which uses multiple processes to react to external
stimuli.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="starting-point"&gt;
&lt;h2&gt;Starting Point&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Button connected to GPIO 7 (&lt;tt class="docutils literal"&gt;CE1&lt;/tt&gt; on the Ext. Board).&lt;/li&gt;
&lt;li&gt;LED connected to GPIO 8 (&lt;tt class="docutils literal"&gt;CE0&lt;/tt&gt; on the Ext. Board).&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="plan-of-action"&gt;
&lt;h2&gt;Plan of Action&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Write three sub-processes (in addition to the main process):&lt;ul&gt;
&lt;li&gt;One process, the &amp;quot;Button Monitor&amp;quot;, which reacts to button presses by
converting them into &amp;quot;Button State Change Events&amp;quot;.&lt;/li&gt;
&lt;li&gt;One process, the &amp;quot;LED Controller&amp;quot;, which reacts to &amp;quot;LED State Change&amp;quot;
events by converting them to GPIO signals.&lt;/li&gt;
&lt;li&gt;One &amp;quot;Event Dispatch Process&amp;quot;. This one combines all message queues and
knows which events should be sent to which process.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="material-used"&gt;
&lt;h2&gt;Material Used&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;SunFounder Raspberry-Pi-GPIO Extension Board V2.2&lt;/li&gt;
&lt;li&gt;1 kΏ Resistor&lt;/li&gt;
&lt;li&gt;1 LED&lt;/li&gt;
&lt;li&gt;1 Button&lt;/li&gt;
&lt;li&gt;3 Jumper Wires&lt;/li&gt;
&lt;li&gt;1 Bread Board&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="wiring"&gt;
&lt;h2&gt;Wiring&lt;/h2&gt;
&lt;p&gt;I don't have anything to draw schematics yet... so a crappy potato photo will
have to do:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Wiring" src="https://michel.albert.lu/images/rpi/2015-07-16-ledcontrol.jpg" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="code"&gt;
&lt;h2&gt;Code&lt;/h2&gt;
&lt;p&gt;Now this is the amusing part. And too big to post here. The resulting code can
be found in my GitHub &lt;a class="reference external" href="https://github.com/exhuma/electro-sandbox/tree/master/mpledcontrol"&gt;repository&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;It works. And the code of the individual processes is fairly simple.&lt;/p&gt;
&lt;p&gt;But...&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;I have two processes wach having a connection to the &lt;tt class="docutils literal"&gt;pigpiod&lt;/tt&gt; daemon. It
irks me. I'd prefer having only one connection. But it's good enough for now.&lt;/li&gt;
&lt;li&gt;It's not possible to attach event-handlers. The handling is completely
hard-coded in the dispatcher process. Again, good enough for a
quick-and-dirty script.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="programming"/><category term="rpi"/><category term="python"/></entry><entry><title>Executing snmpwalk on multiple devices simultaneously</title><link href="https://michel.albert.lu/executing-snmpwalk-on-multiple-devices-simultaneously.html" rel="alternate"/><published>2015-02-24T16:22:45+01:00</published><updated>2015-02-24T16:22:45+01:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2015-02-24:/executing-snmpwalk-on-multiple-devices-simultaneously.html</id><summary type="html">&lt;p&gt;I tend to run the same SNMP probes on multiple devices quite often. The devices
are always the same, the OIDs change. To simplify this I created a small Python
script running the commands in a &lt;tt class="docutils literal"&gt;tmux&lt;/tt&gt; session.&lt;/p&gt;
&lt;p&gt;However, there seems to be a small bug/annoyance in tmux which …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I tend to run the same SNMP probes on multiple devices quite often. The devices
are always the same, the OIDs change. To simplify this I created a small Python
script running the commands in a &lt;tt class="docutils literal"&gt;tmux&lt;/tt&gt; session.&lt;/p&gt;
&lt;p&gt;However, there seems to be a small bug/annoyance in tmux which makes it nearly
impossible to run a command with special characters in it's parameters directly
via tmux. Instead, &amp;quot;injecting&amp;quot; the keystrokes into the running session works
fine.&lt;/p&gt;
&lt;p&gt;I started off writing this in &lt;tt class="docutils literal"&gt;bash&lt;/tt&gt;, but due to the issue mentioned above, I
ended up writing it in Pythong, making the code a lot cleaner. Albeit
unnecessary:&lt;/p&gt;
&lt;pre class="code python highlight literal-block"&gt;
&lt;span class="ch"&gt;#!/usr/bin/python3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="sd"&gt;'''
Run &amp;quot;snmpwalk&amp;quot; on multiple devices simultaneously in separate tmux tabs.
'''&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;collections&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;namedtuple&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;subprocess&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;check_call&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'TERM'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'xterm-256color'&lt;/span&gt;  &lt;span class="c1"&gt;# Hint for tmux to enable 256 colours.&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;Connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;namedtuple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Connection'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ip, community, name'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="n"&gt;TMUX_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'snmpt-probe'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;TARGET_DEVICES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'1.2.3.4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'helloworld'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Device 1'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'1.2.3.5'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'helloworld'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Device 2'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'1.2.3.6'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'helloworld'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Device 3'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'1.2.3.7'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'helloworld'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Device 4'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;exec_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;oid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;community&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="sd"&gt;'''
    Run a command using ``tmux send-keys``.

    This is a workaround. Executing the command directly does not work if a
    parameter contains special characters.
    '''&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'tmux'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'send'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-t'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TMUX_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' snmpwalk -v2c -c &amp;quot;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'tmux'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'send'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-t'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TMUX_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;community&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'tmux'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'send'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-t'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TMUX_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&amp;quot; &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt; | less'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;oid&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'tmux'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'send'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-t'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TMUX_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ENTER'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;    &lt;span class="c1"&gt;# Ask the user to enter the OID&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;oid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'OID: '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;oid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'OID cannot be empty!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;    &lt;span class="c1"&gt;# Create a new, empty tmux session&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'tmux'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'new'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-s'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TMUX_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-d'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;    &lt;span class="c1"&gt;# give the first window it's proper name&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'tmux'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'rename-window'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-t'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TARGET_DEVICES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;    &lt;span class="c1"&gt;# create the remaining tabs with appropriate names&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;TARGET_DEVICES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:]:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'tmux'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'new-window'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-n'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;    &lt;span class="c1"&gt;# run the snmpwalk commands&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;community&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;TARGET_DEVICES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'tmux'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'select-window'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-t'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="n"&gt;exec_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;oid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;community&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;    &lt;span class="c1"&gt;# Attach the tmux session&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'tmux'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'attach'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-t'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TMUX_NAME&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'__main__'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/pre&gt;
</content><category term="programming"/><category term="tmux"/></entry><entry><title>Maximising xterm and gvim in KDE</title><link href="https://michel.albert.lu/maximising-xterm-and-gvim-in-kde.html" rel="alternate"/><published>2015-02-23T10:52:15+01:00</published><updated>2015-02-23T10:52:15+01:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2015-02-23:/maximising-xterm-and-gvim-in-kde.html</id><summary type="html">&lt;div class="section" id="the-problem"&gt;
&lt;h2&gt;The Problem&lt;/h2&gt;
&lt;p&gt;For ages, I was annoyed that neither &lt;tt class="docutils literal"&gt;gvim&lt;/tt&gt; nor &lt;tt class="docutils literal"&gt;xterm&lt;/tt&gt; maximised properly
in some desktop environment (KDE being one of them). They both have a small
&amp;quot;gap&amp;quot; around the outermost screen edges. It is not only visually annoying, but
I am also used to &amp;quot;throw&amp;quot; the mouse to …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="the-problem"&gt;
&lt;h2&gt;The Problem&lt;/h2&gt;
&lt;p&gt;For ages, I was annoyed that neither &lt;tt class="docutils literal"&gt;gvim&lt;/tt&gt; nor &lt;tt class="docutils literal"&gt;xterm&lt;/tt&gt; maximised properly
in some desktop environment (KDE being one of them). They both have a small
&amp;quot;gap&amp;quot; around the outermost screen edges. It is not only visually annoying, but
I am also used to &amp;quot;throw&amp;quot; the mouse to the top corner to grab the title-bar.
But because this small gap exists, I always end up clicking anything which lies
behind that window.&lt;/p&gt;
&lt;div class="figure align-left" style="width: 300px"&gt;
&lt;a class="reference external image-reference" href="https://michel.albert.lu/images/x11-fullscreen/fullscreen-1-2.png"&gt;
&lt;img alt="Visual gap between the screen edges and the application window." src="https://michel.albert.lu/images/x11-fullscreen/fullscreen-1-2.png" /&gt;
&lt;/a&gt;
&lt;p class="caption"&gt;Note the visual gap between the application and the window on it's left.
gvim (or xterm) is maximised, and the other window is sitting on a second
monitor. The gap is clearly visible.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The reason this happens, is because the applications give the window
manager resizing hints. And because both applications are resized based on
characters, and &lt;em&gt;not&lt;/em&gt; based on pixels, the WM tries it's best to fill as much
screen as possible. But only changing the size by the increments given by the
application. This depends on font and font-size. It is unlikely that the width
and height of the characters can perfectly fill the screen.&lt;/p&gt;
&lt;br clear="both" /&gt;&lt;/div&gt;
&lt;div class="section" id="solution"&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;KDE offers you a way to ignore those hints.&lt;/p&gt;
&lt;div class="figure align-left" style="width: 300px"&gt;
&lt;a class="reference external image-reference" href="https://michel.albert.lu/images/x11-fullscreen/fullscreen-3.png"&gt;
&lt;img alt="Context menu for the application." src="https://michel.albert.lu/images/x11-fullscreen/fullscreen-3.png" /&gt;
&lt;/a&gt;
&lt;p class="caption"&gt;The context menu for special application settings.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;When the application is open, right-click on the title bar, select &amp;quot;&lt;em&gt;More
Actions&lt;/em&gt;&amp;quot;, and &amp;quot;&lt;em&gt;Special Application Settings&lt;/em&gt;&amp;quot;. This will open up a dialog for
&lt;em&gt;this application&lt;/em&gt;&amp;quot;.&lt;/p&gt;
&lt;div class="figure align-left" style="width: 300px"&gt;
&lt;a class="reference external image-reference" href="https://michel.albert.lu/images/x11-fullscreen/fullscreen-4.png"&gt;
&lt;img alt="Configuration Dialog" src="https://michel.albert.lu/images/x11-fullscreen/fullscreen-4.png" /&gt;
&lt;/a&gt;
&lt;p class="caption"&gt;The &amp;quot;Special Application Settings&amp;quot; dialog.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The &amp;quot;&lt;em&gt;Size &amp;amp; Position&lt;/em&gt;&amp;quot; tab contains the option we are looking for: &amp;quot;&lt;em&gt;Obey geometry restrictions&lt;/em&gt;&amp;quot;.&lt;/p&gt;
&lt;p&gt;Override the WM default by ticking the checkbox and selecting &amp;quot;&lt;em&gt;Force&lt;/em&gt;&amp;quot; in the drop-down menu and setting the value to &amp;quot;&lt;em&gt;No&lt;/em&gt;&amp;quot;.&lt;/p&gt;
&lt;div class="figure align-left" style="width: 300px"&gt;
&lt;a class="reference external image-reference" href="https://michel.albert.lu/images/x11-fullscreen/fullscreen-5.png"&gt;
&lt;img alt="The geometry restriction option." src="https://michel.albert.lu/images/x11-fullscreen/fullscreen-5.png" /&gt;
&lt;/a&gt;
&lt;p class="caption"&gt;Close-up on the value that you need to set.&lt;/p&gt;
&lt;/div&gt;
&lt;br clear="both" /&gt;&lt;/div&gt;
&lt;div class="section" id="end-result"&gt;
&lt;h2&gt;End-Result&lt;/h2&gt;
&lt;div class="figure align-left" style="width: 300px"&gt;
&lt;a class="reference external image-reference" href="https://michel.albert.lu/images/x11-fullscreen/fullscreen-6.png"&gt;
&lt;img alt="Screenshot after changing the option." src="https://michel.albert.lu/images/x11-fullscreen/fullscreen-6.png" /&gt;
&lt;/a&gt;
&lt;p class="caption"&gt;In this screenshot, you can see that the gap between both windows has
disappeared.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;After changing these values you can try to maximise the window (or restore,
then maximise again). It should now fill the screen up to the last pixel,
closuing up the gap.&lt;/p&gt;
&lt;p&gt;This fix is applicable to all applications which force size increments on your
window. For me, this was both &lt;em&gt;gvim&lt;/em&gt; and &lt;em&gt;xterm&lt;/em&gt;, but it will surely also fix
issues with &lt;em&gt;emacs&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This fix is also not exclusive to KDE. For example &amp;quot;&lt;em&gt;awesome&lt;/em&gt;&amp;quot; allows you to do
the same &lt;a class="reference external" href="http://superuser.com/questions/751075/emacs-maximized-but-leaves-few-pixels-in-awesome-wm"&gt;via config files&lt;/a&gt;, and I am sure other WMs let you override this as
well.&lt;/p&gt;
&lt;/div&gt;
</content><category term="desktop"/><category term="kde"/><category term="linux"/><category term="desktop"/></entry><entry><title>Linux LVM and RAID recovery</title><link href="https://michel.albert.lu/linux-lvm-and-raid-recovery.html" rel="alternate"/><published>2014-12-17T15:16:47+01:00</published><updated>2014-12-17T15:16:47+01:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2014-12-17:/linux-lvm-and-raid-recovery.html</id><summary type="html">&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#creating-the-software-raid-array" id="toc-entry-1"&gt;Creating the Software RAID Array&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#required-packages" id="toc-entry-2"&gt;Required packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#creating-files-for-testing" id="toc-entry-3"&gt;Creating files for testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#create-devices-for-these-files" id="toc-entry-4"&gt;Create devices for these files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#create-the-raid-array" id="toc-entry-5"&gt;Create the RAID array&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#verify-integrity" id="toc-entry-6"&gt;Verify integrity&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#creating-logical-volumes" id="toc-entry-7"&gt;Creating Logical Volumes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#cleanup" id="toc-entry-8"&gt;Cleanup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#recovery" id="toc-entry-9"&gt;Recovery&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#raid" id="toc-entry-10"&gt;RAID&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#lvm" id="toc-entry-11"&gt;LVM&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#restarting-the-array-with-all-devices" id="toc-entry-12"&gt;Restarting the array with all devices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;This little tutorial will first create a RAID array, and one LVM volume using …&lt;/p&gt;</summary><content type="html">&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#creating-the-software-raid-array" id="toc-entry-1"&gt;Creating the Software RAID Array&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#required-packages" id="toc-entry-2"&gt;Required packages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#creating-files-for-testing" id="toc-entry-3"&gt;Creating files for testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#create-devices-for-these-files" id="toc-entry-4"&gt;Create devices for these files&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#create-the-raid-array" id="toc-entry-5"&gt;Create the RAID array&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#verify-integrity" id="toc-entry-6"&gt;Verify integrity&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#creating-logical-volumes" id="toc-entry-7"&gt;Creating Logical Volumes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#cleanup" id="toc-entry-8"&gt;Cleanup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#recovery" id="toc-entry-9"&gt;Recovery&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#raid" id="toc-entry-10"&gt;RAID&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#lvm" id="toc-entry-11"&gt;LVM&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#restarting-the-array-with-all-devices" id="toc-entry-12"&gt;Restarting the array with all devices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;This little tutorial will first create a RAID array, and one LVM volume using
dummy files. Next it will simulate the case where you would like to recover
from just one device, and finally reassemble the complete array again.&lt;/p&gt;
&lt;div class="section" id="creating-the-software-raid-array"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;Creating the Software RAID Array&lt;/a&gt;&lt;/h2&gt;
&lt;div class="section" id="required-packages"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#contents"&gt;Required packages&lt;/a&gt;&lt;/h3&gt;
&lt;pre class="literal-block"&gt;
sudo aptitude install \
    lvm2 \
    mdadm
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="creating-files-for-testing"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#contents"&gt;Creating files for testing&lt;/a&gt;&lt;/h3&gt;
&lt;pre class="literal-block"&gt;
dd if=/dev/zero of=disk1 bs=1M count=30
dd if=/dev/zero of=disk2 bs=1M count=30
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="create-devices-for-these-files"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#contents"&gt;Create devices for these files&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;mdadm&lt;/tt&gt; only accepts valid block devices for raid members. We use the
loopback device for this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo losetup /dev/loop0 disk1
sudo losetup /dev/loop1 disk2
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="create-the-raid-array"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#contents"&gt;Create the RAID array&lt;/a&gt;&lt;/h3&gt;
&lt;pre class="literal-block"&gt;
sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/loop0 /dev/loop1
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="verify-integrity"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#contents"&gt;Verify integrity&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Running &lt;tt class="docutils literal"&gt;cat /proc/mdstat&lt;/tt&gt; should show you the following now:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Personalities : [raid1]
md0 : active raid1 loop1[1] loop0[0]
      30656 blocks super 1.2 [2/2] [UU]

unused devices: &amp;lt;none&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;[UU]&lt;/tt&gt; shows us that both devices are up.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="creating-logical-volumes"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;Creating Logical Volumes&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As the devices have never been used in LVM, we need to create everything first:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo pvcreate /dev/md0
&lt;/pre&gt;
&lt;p&gt;This flags the devices as member in a &lt;em&gt;volume group&lt;/em&gt;. Now we can craete a
&lt;em&gt;volume group&lt;/em&gt; with this raid array as member:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo vgcreate foobar /dev/md0
&lt;/pre&gt;
&lt;p&gt;To see that it worked, run the following:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo vgs
&lt;/pre&gt;
&lt;p&gt;You should see the following:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
VG     #PV #LV #SN Attr   VSize  VFree
foobar   1   0   0 wz--n- 28.00m 28.00m
&lt;/pre&gt;
&lt;p&gt;This shows us that we have one &lt;em&gt;volume group&lt;/em&gt; (you can imagine this as a
virtual hard-disk) with a bit less than 30MB of free space (we created 30M
files in the very first step).&lt;/p&gt;
&lt;p&gt;Finally, we can create our &lt;em&gt;logical volumes&lt;/em&gt; (virtual partitions). Let's create
two 10M partitions:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo lvcreate -L10M -n part1 foobar
sudo lvcreate -L10M -n part2 foobar
&lt;/pre&gt;
&lt;p&gt;This will create two volums with the names &lt;em&gt;part1&lt;/em&gt; and &lt;em&gt;part2&lt;/em&gt;. They should now
be available in &lt;tt class="docutils literal"&gt;/dev/foobar&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;/dev/mapper&lt;/tt&gt; and can be used like regular
disks. To see a quick status, you can run the commands &lt;tt class="docutils literal"&gt;pvs&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;vgs&lt;/tt&gt; and
&lt;tt class="docutils literal"&gt;lvs&lt;/tt&gt; for quick reports about &lt;em&gt;physical volumes&lt;/em&gt;, &lt;em&gt;volume groups&lt;/em&gt; and
&lt;em&gt;logical volumes&lt;/em&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="cleanup"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;Cleanup&lt;/a&gt;&lt;/h2&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;This is &lt;strong&gt;only&lt;/strong&gt; necessary if you followed the above steps to simulate real
devices using regular files. We need to free up all references before we can
remove the loopback devices.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;To simulate the physical connection, you can run the following commands to
clean up everything from the previous step:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo vgchange -a n foobar  # This deactivates the volume group from LVM
sudo mdadm --stop /dev/md0  # This removes the /dev/md0 device and frees up the loopback devices /dev/loop[01]
sudo losetup -d /dev/loop0  # Finally, this removes the loopback devices
sudo losetup -d /dev/loop1
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="recovery"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;Recovery&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Let's assume that you have only one disk, and you need to recover data from
this disk. This section shows how to reassemble everything.&lt;/p&gt;
&lt;p&gt;As both the software raid and LVM store metadata in the devices (superblocks),
the reassembly is much easier than creation.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;If you are using the dummy files as created above, we will set only one of
the two files as block device. This is equivalent to physically connecting
only one device:&lt;/p&gt;
&lt;pre class="last literal-block"&gt;
sudo losetup /dev/loop0 disk1
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="raid"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#contents"&gt;RAID&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;First we scan for RAID devices:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo mdadm --assemble --scan
&lt;/pre&gt;
&lt;p&gt;You should see the following:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
mdadm: /dev/md/0 has been started with 1 drive (out of 2).
&lt;/pre&gt;
&lt;p&gt;And a quick look at &lt;tt class="docutils literal"&gt;/proc/mdstat&lt;/tt&gt; shows the following:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md0 : active raid1 loop0[0]
      30656 blocks super 1.2 [2/1] [U_]

unused devices: &amp;lt;none&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Seeing &lt;tt class="docutils literal"&gt;[U_]&lt;/tt&gt; shows us that one device is up, and the other one missing.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="lvm"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#contents"&gt;LVM&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Now that the raid device &lt;tt class="docutils literal"&gt;/dev/md0&lt;/tt&gt; is up and running, we can scan for LVM
metadata:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo vgscan
&lt;/pre&gt;
&lt;p&gt;This should show up with the following message:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Reading all physical volumes.  This may take a while...
Found volume group &amp;quot;foobar&amp;quot; using metadata type lvm2
&lt;/pre&gt;
&lt;p&gt;Now, running the command &lt;tt class="docutils literal"&gt;pvs&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;vgs&lt;/tt&gt; and/or &lt;tt class="docutils literal"&gt;lvs&lt;/tt&gt; should show the
previously created devices.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="restarting-the-array-with-all-devices"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;Restarting the array with all devices&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After recovery, you can reassemble the array with all devices in the exact same
way as in the previous &amp;quot;recovery&amp;quot; step. But in this case, you should see both
devices as &amp;quot;up&amp;quot; in &lt;tt class="docutils literal"&gt;/proc/mdstat&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
</content><category term="sysadmin"/><category term="linux"/><category term="raid"/><category term="lvm"/></entry><entry><title>Automatically Sync Files on WIFI Connect</title><link href="https://michel.albert.lu/automatically-sync-files-on-wifi-connect.html" rel="alternate"/><published>2014-10-06T19:56:49+02:00</published><updated>2014-10-06T19:56:49+02:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2014-10-06:/automatically-sync-files-on-wifi-connect.html</id><summary type="html">&lt;p&gt;I recently discovered &lt;a class="reference external" href="http://wicd.sourceforge.net/"&gt;wicd&lt;/a&gt; (thanks to &lt;a class="reference external" href="https://gefoo.org/"&gt;Gefoo&lt;/a&gt;). It is a really nifty network
manager. And it supports running scripts on each connection stage for a
network. This immediately gave me an idea:&lt;/p&gt;
&lt;p&gt;I like taking photos, and sometimes I unload them from my camera to my laptop
for immediate housekeeping …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I recently discovered &lt;a class="reference external" href="http://wicd.sourceforge.net/"&gt;wicd&lt;/a&gt; (thanks to &lt;a class="reference external" href="https://gefoo.org/"&gt;Gefoo&lt;/a&gt;). It is a really nifty network
manager. And it supports running scripts on each connection stage for a
network. This immediately gave me an idea:&lt;/p&gt;
&lt;p&gt;I like taking photos, and sometimes I unload them from my camera to my laptop
for immediate housekeeping. I keep them on an in-house NAS for safe-keeping.
Being able to run scripts once the laptop connects, lets me sync the files
automagically to my NAS. This is awesome, and this article summarises how I've
implemented it.&lt;/p&gt;
&lt;p&gt;It is actually quite straight-forward. The wicd documentation mentions that you
should modify one the following settings (depending on what you need):&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;afterscript&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;postdisconnectscript&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;beforescript&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;predisconnectscript&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, this did not work for me. After editing the file, the values reverted
to their original value (&lt;tt class="docutils literal"&gt;None&lt;/tt&gt;). I assume that you need to stop the wicd
service before editing it. I did not do that, and I assume that the file is
written when wicd ends. This would explain this issue. But there is also
another way, which I followed fo the rest of this.&lt;/p&gt;
&lt;p&gt;As an alternative, you can just drop executable scripts into one of the
&lt;tt class="docutils literal"&gt;/etc/wicd/scripts&lt;/tt&gt; subfolders. For my task, I chose &lt;tt class="docutils literal"&gt;postconnect&lt;/tt&gt;. I use
this script as an &amp;quot;orchestration&amp;quot; script which launches other scripts as
needed. For now it only contains one script, and looks like this:&lt;/p&gt;
&lt;pre class="code bash highlight literal-block"&gt;
&lt;span class="ch"&gt;#!/bin/bash
&lt;/span&gt;&lt;span class="nv"&gt;conntype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;essid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;bssid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$3&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$conntype&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;wireless&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$essid&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;MichTik&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;then&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;/opt/wicd/scripts/filedrop&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;This says, that as soon as a wireless connection is established on the SSID
&amp;quot;MichTik&amp;quot;, the script &lt;tt class="docutils literal"&gt;/opt/wicd/scripts/filedrop&lt;/tt&gt; should be executed.&lt;/p&gt;
&lt;p&gt;That script in turn looks like this:&lt;/p&gt;
&lt;pre class="code bash highlight literal-block"&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#!/bin/bash
&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;LOGFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/var/log/filedropper.log&lt;span class="w"&gt;

 &lt;/span&gt;&lt;span class="c1"&gt;# SSH Private Key for fully unattended operation. This key must be
&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# passwordless, so the containing directory should have the proper access
&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# rights.
&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;IDENTITY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/opt/wicd/scripts/sshkeys/filedrop&lt;span class="w"&gt;

 &lt;/span&gt;&lt;span class="c1"&gt;# Any file created by this script (the logfile) should be secured.
&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;umask&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0077&lt;/span&gt;&lt;span class="w"&gt;

 &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;date&lt;span class="w"&gt; &lt;/span&gt;+&lt;span class="s2"&gt;&amp;quot;%F %T&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; dropping new files...&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$LOGFILE&lt;/span&gt;&lt;span class="w"&gt;

 &lt;/span&gt;&lt;span class="c1"&gt;##
&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# drop(src, dest)
&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#
&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# Moved files from &amp;quot;src&amp;quot; to &amp;quot;dest&amp;quot;.
&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#
&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# WARNING
&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# This uses rsync with --remove-source-files, so you should make sure that
&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# files are not modified *while* this is running! Read the according
&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# section of the rsync man-page for details!
&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;##
&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;drop&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nv"&gt;dst&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;rsync&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;--partial&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;--remove-source-files&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;ssh -l exhuma -i &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;IDENTITY&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;dst&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LOGFILE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

 &lt;/span&gt;drop&lt;span class="w"&gt; &lt;/span&gt;/home/exhuma/photos&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\
&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="m"&gt;192&lt;/span&gt;.168.1.1:/mnt/media/incoming/filedrop/&lt;span class="w"&gt;

 &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;date&lt;span class="w"&gt; &lt;/span&gt;+&lt;span class="s2"&gt;&amp;quot;%F %T&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; DONE.&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$LOGFILE&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;And that's it!&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;Security of this could be improved. For example, I am using my own user on
the filedrop target. Which means that if my laptop is compromised, and
someone would get their hands on this passwordless key, that person could
wreak all kinds of havoc. After I finish this article, I will set up a
dedicated user on the NAS for this purpose. And you should do so too :P&lt;/p&gt;
&lt;/div&gt;
</content><category term="automation"/><category term="linux"/><category term="lifheack"/></entry><entry><title>Better Testdata for HClustering</title><link href="https://michel.albert.lu/better-testdata-for-hclustering.html" rel="alternate"/><published>2014-09-12T22:00:00+02:00</published><updated>2014-09-14T12:01:54+02:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2014-09-12:/better-testdata-for-hclustering.html</id><summary type="html">&lt;p&gt;While I first intended to create the matrices manually, it
turned out to take too much time if I wanted to reproduce the exact same error
as happened in the unit-tests.&lt;/p&gt;
&lt;p&gt;So in order to create the matrices used in the earlier blog-posts, I used the
script at the end …&lt;/p&gt;</summary><content type="html">&lt;p&gt;While I first intended to create the matrices manually, it
turned out to take too much time if I wanted to reproduce the exact same error
as happened in the unit-tests.&lt;/p&gt;
&lt;p&gt;So in order to create the matrices used in the earlier blog-posts, I used the
script at the end of this article. I took care to double-check the results
however. There are times, where there's a choice of more than one cluster to
pick. And as the order is not important, this choice becomes dependent on the
concrete implementation, and thus non-deterministic in the unit-tests. This
caused a discrepancy in the matrices generated by the script below, and the
current implementation of the algorithm in library. If that was the case, I
validated the results manually, and they checked out.&lt;/p&gt;
&lt;p&gt;Unfortunately though, the data in the existing unit-test do not provoke a
difference between &lt;em&gt;UCLUS&lt;/em&gt; and &lt;em&gt;average&lt;/em&gt; linkage (there are no real
&lt;em&gt;outliers&lt;/em&gt;).  Which is unfortunate. I will (for now) &lt;em&gt;not&lt;/em&gt; create a new
data-set to verify the difference between &lt;em&gt;UCLUS&lt;/em&gt; and &lt;em&gt;average&lt;/em&gt;. I trust the
current implementation enough to say that it will do the right thing...&lt;/p&gt;
&lt;p&gt;Finally, here's the script used to create the test-data:&lt;/p&gt;
&lt;pre class="code python literal-block"&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;__future__&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;print_function&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;difflib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SequenceMatcher&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;
    Returns the arithmetic mean of a numeric list.
    see: http://mail.python.org/pipermail/python-list/2004-December/294990.html
    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;median&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;
    Return the median of the list of numbers.
    see: http://mail.python.org/pipermail/python-list/2004-December/294990.html
    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;    &lt;span class="c1"&gt;# Sort the list and take the middle element.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;copy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# There is an odd number of elements&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;textsim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;sm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SequenceMatcher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;. -&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;sm&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;simplesim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="c1"&gt;# sim = textsim&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;sim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;simplesim&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;single&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;sim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ey&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;sim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ey&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;uclus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;median&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;sim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ey&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;average&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;sim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ey&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="n"&gt;linkage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;average&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="s1"&gt;'Lorem'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'ipsum'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'dolor'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'sit'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'amet'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'consectetuer'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'adipiscing'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'elit'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'Ut'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'elit'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'Phasellus'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'consequat'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'ultricies'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'mi'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'Sed'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'congue'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'leo'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'at'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'neque'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'Nullam'&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;791&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;956&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;676&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;124&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;564&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;84&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;594&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;940&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;398&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;971&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;                      &lt;span class="mi"&gt;131&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;542&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;336&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;518&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;835&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;134&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;391&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cell&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;            &lt;span class="n"&gt;minsim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;linkage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cell&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minsim&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="n"&gt;sorted_matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="n"&gt;closest_items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sorted_matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;closest_items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="n"&gt;new_element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print_matrix2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;iteration&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="n"&gt;simdata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;linkage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;simdata&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="n"&gt;smallest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.. csv-table:: Matrix #&lt;/span&gt;&lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iteration&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'    :header-rows: 1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'    :stub-columns: 1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'    :delim: :&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'    :'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;': '&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;', '&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="n"&gt;simdata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;linkage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="n"&gt;strsimdata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'**&lt;/span&gt;&lt;span class="si"&gt;{:.3f}&lt;/span&gt;&lt;span class="s1"&gt;**'&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;                      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;smallest&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{:.3f}&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;                      &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;simdata&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;','&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;': '&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strsimdata&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'    '&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sep&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;': '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;


&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;print_matrix2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;print_matrix2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;
</content><category term="programming"/><category term="algorithms"/><category term="github"/><category term="python"/></entry><entry><title>Validating the test-case for clustering string values</title><link href="https://michel.albert.lu/validating-the-test-case-for-clustering-string-values.html" rel="alternate"/><published>2014-09-10T12:43:40+02:00</published><updated>2014-09-10T12:43:40+02:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2014-09-10:/validating-the-test-case-for-clustering-string-values.html</id><summary type="html">&lt;p&gt;Here we go again...&lt;/p&gt;
&lt;p&gt;After further analysis (the trial &amp;amp; error kind), I found out that the error of
modified values only occurs in unsorted data. Which makes perfect sense as
Python's &lt;tt class="docutils literal"&gt;list.remove&lt;/tt&gt; picks the &lt;em&gt;first matching item&lt;/em&gt;. So the ordering of
data plays a role.&lt;/p&gt;
&lt;p&gt;As a quick fix …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Here we go again...&lt;/p&gt;
&lt;p&gt;After further analysis (the trial &amp;amp; error kind), I found out that the error of
modified values only occurs in unsorted data. Which makes perfect sense as
Python's &lt;tt class="docutils literal"&gt;list.remove&lt;/tt&gt; picks the &lt;em&gt;first matching item&lt;/em&gt;. So the ordering of
data plays a role.&lt;/p&gt;
&lt;p&gt;As a quick fix, sorted data is now enforced when using the hierarchical
clustering algorithm. Now, the only remaining test failure is the one comparing
string values. And this time, I'll prepare a &lt;em&gt;real&lt;/em&gt; test-case!&lt;/p&gt;
&lt;p&gt;Which means manually calculating the matrix and clusters. So here we go!&lt;/p&gt;
&lt;p&gt;The input data (lorem-ipsum split on white-space):&lt;/p&gt;
&lt;pre class="literal-block"&gt;
['Lorem', 'ipsum', 'dolor', 'sit', 'amet,', 'consectetuer', 'adipiscing',
 'elit.', 'Ut', 'elit.', 'Phasellus', 'consequat', 'ultricies', 'mi.',
 'Sed', 'congue', 'leo', 'at', 'neque.', 'Nullam.']
&lt;/pre&gt;
&lt;p&gt;As distance function, we'll use Python's &lt;a class="reference external" href="https://docs.python.org/3/library/difflib.html#difflib.SequenceMatcher.ratio"&gt;SequenceMatcher&lt;/a&gt;.&lt;/p&gt;
&lt;div class="section" id="h30m-later"&gt;
&lt;h2&gt;2h30m later&lt;/h2&gt;
&lt;p&gt;Funnily enough, the matrices are now generated using another quick-and-dirty
script. With this input data, doing it manually was a bit too much after all.
However, this time, the resulting values look actually correct!&lt;/p&gt;
&lt;p&gt;This new algorithm is completely written from scratch, and could possibly
replace the existing algorithm in the library.  But I have other ideas for that
one, so I'll leave it for now...&lt;/p&gt;
&lt;p&gt;And indeed, fixing the above mentioned &amp;quot;sorting&amp;quot; issue fixes the problem.
Running the tests with the new test-data, against the old code checks out.&lt;/p&gt;
&lt;p&gt;There was one discrepancy though: On the final iteration of the test (going
from matrix #10 to matrix #11) there are several candidates with a distance of
&lt;tt class="docutils literal"&gt;0.600&lt;/tt&gt;. And the code which generated the test matrices below picked &lt;tt class="docutils literal"&gt;(leo,
dolor), Lorem&lt;/tt&gt; where the original algorithm picked &lt;tt class="docutils literal"&gt;adipiscing, ipsum&lt;/tt&gt;. Both
values are correct, so the result of the test is indeed valid!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="matrices"&gt;
&lt;h2&gt;Matrices&lt;/h2&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Matrix #1&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;Lorem&lt;/th&gt;
&lt;th class="head"&gt;ipsum&lt;/th&gt;
&lt;th class="head"&gt;dolor&lt;/th&gt;
&lt;th class="head"&gt;sit&lt;/th&gt;
&lt;th class="head"&gt;amet&lt;/th&gt;
&lt;th class="head"&gt;consectetuer&lt;/th&gt;
&lt;th class="head"&gt;adipiscing&lt;/th&gt;
&lt;th class="head"&gt;elit&lt;/th&gt;
&lt;th class="head"&gt;Ut&lt;/th&gt;
&lt;th class="head"&gt;elit&lt;/th&gt;
&lt;th class="head"&gt;Phasellus&lt;/th&gt;
&lt;th class="head"&gt;consequat&lt;/th&gt;
&lt;th class="head"&gt;ultricies&lt;/th&gt;
&lt;th class="head"&gt;mi&lt;/th&gt;
&lt;th class="head"&gt;Sed&lt;/th&gt;
&lt;th class="head"&gt;congue&lt;/th&gt;
&lt;th class="head"&gt;leo&lt;/th&gt;
&lt;th class="head"&gt;at&lt;/th&gt;
&lt;th class="head"&gt;neque&lt;/th&gt;
&lt;th class="head"&gt;Nullam&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Lorem&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ipsum&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;dolor&lt;/th&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;sit&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;amet&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;consectetuer&lt;/th&gt;
&lt;td&gt;0.765&lt;/td&gt;
&lt;td&gt;0.765&lt;/td&gt;
&lt;td&gt;0.765&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;adipiscing&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;elit&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.429&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Ut&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;elit&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.429&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.000&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Phasellus&lt;/th&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;consequat&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.429&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ultricies&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;0.810&lt;/td&gt;
&lt;td&gt;0.684&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;mi&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Sed&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;congue&lt;/th&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.444&lt;/td&gt;
&lt;td&gt;0.625&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.467&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;leo&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;at&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.333&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;neque&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.529&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.429&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.455&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Nullam&lt;/th&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.889&lt;/td&gt;
&lt;td&gt;0.875&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Matrix #2&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;Lorem&lt;/th&gt;
&lt;th class="head"&gt;ipsum&lt;/th&gt;
&lt;th class="head"&gt;dolor&lt;/th&gt;
&lt;th class="head"&gt;sit&lt;/th&gt;
&lt;th class="head"&gt;amet&lt;/th&gt;
&lt;th class="head"&gt;consectetuer&lt;/th&gt;
&lt;th class="head"&gt;adipiscing&lt;/th&gt;
&lt;th class="head"&gt;Ut&lt;/th&gt;
&lt;th class="head"&gt;Phasellus&lt;/th&gt;
&lt;th class="head"&gt;consequat&lt;/th&gt;
&lt;th class="head"&gt;ultricies&lt;/th&gt;
&lt;th class="head"&gt;mi&lt;/th&gt;
&lt;th class="head"&gt;Sed&lt;/th&gt;
&lt;th class="head"&gt;congue&lt;/th&gt;
&lt;th class="head"&gt;leo&lt;/th&gt;
&lt;th class="head"&gt;at&lt;/th&gt;
&lt;th class="head"&gt;neque&lt;/th&gt;
&lt;th class="head"&gt;Nullam&lt;/th&gt;
&lt;th class="head"&gt;elit, elit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Lorem&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ipsum&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;dolor&lt;/th&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;sit&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;amet&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;consectetuer&lt;/th&gt;
&lt;td&gt;0.765&lt;/td&gt;
&lt;td&gt;0.765&lt;/td&gt;
&lt;td&gt;0.765&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;adipiscing&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Ut&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Phasellus&lt;/th&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;consequat&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.429&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ultricies&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;0.810&lt;/td&gt;
&lt;td&gt;0.684&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;mi&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Sed&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;congue&lt;/th&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.444&lt;/td&gt;
&lt;td&gt;0.625&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.467&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;leo&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;at&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.333&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;neque&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.529&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.429&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.455&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Nullam&lt;/th&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.889&lt;/td&gt;
&lt;td&gt;0.875&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;elit,elit&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.429&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Matrix #3&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;col width="5%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;Lorem&lt;/th&gt;
&lt;th class="head"&gt;ipsum&lt;/th&gt;
&lt;th class="head"&gt;dolor&lt;/th&gt;
&lt;th class="head"&gt;sit&lt;/th&gt;
&lt;th class="head"&gt;consectetuer&lt;/th&gt;
&lt;th class="head"&gt;adipiscing&lt;/th&gt;
&lt;th class="head"&gt;Ut&lt;/th&gt;
&lt;th class="head"&gt;Phasellus&lt;/th&gt;
&lt;th class="head"&gt;consequat&lt;/th&gt;
&lt;th class="head"&gt;ultricies&lt;/th&gt;
&lt;th class="head"&gt;mi&lt;/th&gt;
&lt;th class="head"&gt;Sed&lt;/th&gt;
&lt;th class="head"&gt;congue&lt;/th&gt;
&lt;th class="head"&gt;leo&lt;/th&gt;
&lt;th class="head"&gt;neque&lt;/th&gt;
&lt;th class="head"&gt;Nullam&lt;/th&gt;
&lt;th class="head"&gt;elit, elit&lt;/th&gt;
&lt;th class="head"&gt;at, amet&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Lorem&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ipsum&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;dolor&lt;/th&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;sit&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;consectetuer&lt;/th&gt;
&lt;td&gt;0.765&lt;/td&gt;
&lt;td&gt;0.765&lt;/td&gt;
&lt;td&gt;0.765&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;adipiscing&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Ut&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Phasellus&lt;/th&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;consequat&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.429&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ultricies&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.810&lt;/td&gt;
&lt;td&gt;0.684&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;mi&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Sed&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;congue&lt;/th&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.444&lt;/td&gt;
&lt;td&gt;0.625&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.467&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;leo&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;neque&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.529&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.429&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.455&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Nullam&lt;/th&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.889&lt;/td&gt;
&lt;td&gt;0.875&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;elit,elit&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.429&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;at,amet&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Matrix #4&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;Lorem&lt;/th&gt;
&lt;th class="head"&gt;ipsum&lt;/th&gt;
&lt;th class="head"&gt;dolor&lt;/th&gt;
&lt;th class="head"&gt;sit&lt;/th&gt;
&lt;th class="head"&gt;adipiscing&lt;/th&gt;
&lt;th class="head"&gt;Ut&lt;/th&gt;
&lt;th class="head"&gt;Phasellus&lt;/th&gt;
&lt;th class="head"&gt;ultricies&lt;/th&gt;
&lt;th class="head"&gt;mi&lt;/th&gt;
&lt;th class="head"&gt;Sed&lt;/th&gt;
&lt;th class="head"&gt;congue&lt;/th&gt;
&lt;th class="head"&gt;leo&lt;/th&gt;
&lt;th class="head"&gt;neque&lt;/th&gt;
&lt;th class="head"&gt;Nullam&lt;/th&gt;
&lt;th class="head"&gt;elit, elit&lt;/th&gt;
&lt;th class="head"&gt;at, amet&lt;/th&gt;
&lt;th class="head"&gt;consequat, consectetuer&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Lorem&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ipsum&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;dolor&lt;/th&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;sit&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;adipiscing&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Ut&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Phasellus&lt;/th&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ultricies&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.684&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;mi&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Sed&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;congue&lt;/th&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.625&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;leo&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;neque&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.455&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Nullam&lt;/th&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.875&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;elit,elit&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.429&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;at,amet&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;consequat,consectetuer&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.765&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.444&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.429&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Matrix #5&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;Lorem&lt;/th&gt;
&lt;th class="head"&gt;ipsum&lt;/th&gt;
&lt;th class="head"&gt;dolor&lt;/th&gt;
&lt;th class="head"&gt;adipiscing&lt;/th&gt;
&lt;th class="head"&gt;Ut&lt;/th&gt;
&lt;th class="head"&gt;Phasellus&lt;/th&gt;
&lt;th class="head"&gt;ultricies&lt;/th&gt;
&lt;th class="head"&gt;mi&lt;/th&gt;
&lt;th class="head"&gt;Sed&lt;/th&gt;
&lt;th class="head"&gt;congue&lt;/th&gt;
&lt;th class="head"&gt;leo&lt;/th&gt;
&lt;th class="head"&gt;neque&lt;/th&gt;
&lt;th class="head"&gt;Nullam&lt;/th&gt;
&lt;th class="head"&gt;at, amet&lt;/th&gt;
&lt;th class="head"&gt;consequat, consectetuer&lt;/th&gt;
&lt;th class="head"&gt;elit, elit, sit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Lorem&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ipsum&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;dolor&lt;/th&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;adipiscing&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Ut&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Phasellus&lt;/th&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ultricies&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.684&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;mi&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Sed&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;congue&lt;/th&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.625&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;leo&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;neque&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.455&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Nullam&lt;/th&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.875&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;at,amet&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;consequat,consectetuer&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.765&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.444&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.429&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;elit,elit,sit&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Matrix #6&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;col width="6%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;Lorem&lt;/th&gt;
&lt;th class="head"&gt;ipsum&lt;/th&gt;
&lt;th class="head"&gt;dolor&lt;/th&gt;
&lt;th class="head"&gt;adipiscing&lt;/th&gt;
&lt;th class="head"&gt;Ut&lt;/th&gt;
&lt;th class="head"&gt;Phasellus&lt;/th&gt;
&lt;th class="head"&gt;ultricies&lt;/th&gt;
&lt;th class="head"&gt;mi&lt;/th&gt;
&lt;th class="head"&gt;Sed&lt;/th&gt;
&lt;th class="head"&gt;congue&lt;/th&gt;
&lt;th class="head"&gt;leo&lt;/th&gt;
&lt;th class="head"&gt;Nullam&lt;/th&gt;
&lt;th class="head"&gt;at, amet&lt;/th&gt;
&lt;th class="head"&gt;elit, elit, sit&lt;/th&gt;
&lt;th class="head"&gt;consequat, consectetuer, neque&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Lorem&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ipsum&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;dolor&lt;/th&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;adipiscing&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Ut&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Phasellus&lt;/th&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ultricies&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.684&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;mi&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Sed&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;congue&lt;/th&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.625&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;leo&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Nullam&lt;/th&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.875&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;at,amet&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;elit,elit,sit&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;consequat,consectetuer,neque&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.765&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.444&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Matrix #7&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;Lorem&lt;/th&gt;
&lt;th class="head"&gt;ipsum&lt;/th&gt;
&lt;th class="head"&gt;dolor&lt;/th&gt;
&lt;th class="head"&gt;adipiscing&lt;/th&gt;
&lt;th class="head"&gt;Ut&lt;/th&gt;
&lt;th class="head"&gt;Phasellus&lt;/th&gt;
&lt;th class="head"&gt;ultricies&lt;/th&gt;
&lt;th class="head"&gt;mi&lt;/th&gt;
&lt;th class="head"&gt;Sed&lt;/th&gt;
&lt;th class="head"&gt;leo&lt;/th&gt;
&lt;th class="head"&gt;Nullam&lt;/th&gt;
&lt;th class="head"&gt;at, amet&lt;/th&gt;
&lt;th class="head"&gt;elit, elit, sit&lt;/th&gt;
&lt;th class="head"&gt;consequat, consectetuer, neque, congue&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Lorem&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ipsum&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;dolor&lt;/th&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;adipiscing&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Ut&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Phasellus&lt;/th&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ultricies&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.684&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;mi&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Sed&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;leo&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Nullam&lt;/th&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.875&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;at,amet&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;elit,elit,sit&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;consequat,consectetuer,neque,congue&lt;/th&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.765&lt;/td&gt;
&lt;td&gt;0.625&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Matrix #8&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;col width="7%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;Lorem&lt;/th&gt;
&lt;th class="head"&gt;ipsum&lt;/th&gt;
&lt;th class="head"&gt;adipiscing&lt;/th&gt;
&lt;th class="head"&gt;Ut&lt;/th&gt;
&lt;th class="head"&gt;Phasellus&lt;/th&gt;
&lt;th class="head"&gt;ultricies&lt;/th&gt;
&lt;th class="head"&gt;mi&lt;/th&gt;
&lt;th class="head"&gt;Sed&lt;/th&gt;
&lt;th class="head"&gt;Nullam&lt;/th&gt;
&lt;th class="head"&gt;at, amet&lt;/th&gt;
&lt;th class="head"&gt;elit, elit, sit&lt;/th&gt;
&lt;th class="head"&gt;consequat, consectetuer, neque, congue&lt;/th&gt;
&lt;th class="head"&gt;leo, dolor&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Lorem&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ipsum&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;adipiscing&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Ut&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Phasellus&lt;/th&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ultricies&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.684&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;mi&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Sed&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Nullam&lt;/th&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.875&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;at,amet&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;elit,elit,sit&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;consequat,consectetuer,neque,congue&lt;/th&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.625&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;leo,dolor&lt;/th&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Matrix #9&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;Lorem&lt;/th&gt;
&lt;th class="head"&gt;ipsum&lt;/th&gt;
&lt;th class="head"&gt;adipiscing&lt;/th&gt;
&lt;th class="head"&gt;Phasellus&lt;/th&gt;
&lt;th class="head"&gt;ultricies&lt;/th&gt;
&lt;th class="head"&gt;mi&lt;/th&gt;
&lt;th class="head"&gt;Sed&lt;/th&gt;
&lt;th class="head"&gt;Nullam&lt;/th&gt;
&lt;th class="head"&gt;elit, elit, sit&lt;/th&gt;
&lt;th class="head"&gt;consequat, consectetuer, neque, congue&lt;/th&gt;
&lt;th class="head"&gt;leo, dolor&lt;/th&gt;
&lt;th class="head"&gt;at, amet, Ut&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Lorem&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ipsum&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;adipiscing&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Phasellus&lt;/th&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ultricies&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.684&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;mi&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Sed&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Nullam&lt;/th&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.875&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;elit,elit,sit&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;consequat,consectetuer,neque,congue&lt;/th&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.625&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;leo,dolor&lt;/th&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;at,amet,Ut&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Matrix #10&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;col width="8%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;Lorem&lt;/th&gt;
&lt;th class="head"&gt;ipsum&lt;/th&gt;
&lt;th class="head"&gt;adipiscing&lt;/th&gt;
&lt;th class="head"&gt;Phasellus&lt;/th&gt;
&lt;th class="head"&gt;ultricies&lt;/th&gt;
&lt;th class="head"&gt;mi&lt;/th&gt;
&lt;th class="head"&gt;Sed&lt;/th&gt;
&lt;th class="head"&gt;Nullam&lt;/th&gt;
&lt;th class="head"&gt;consequat, consectetuer, neque, congue&lt;/th&gt;
&lt;th class="head"&gt;leo, dolor&lt;/th&gt;
&lt;th class="head"&gt;at, amet, Ut, elit, elit, sit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Lorem&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ipsum&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;adipiscing&lt;/th&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Phasellus&lt;/th&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.789&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ultricies&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;0.684&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;mi&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Sed&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Nullam&lt;/th&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.875&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;consequat,consectetuer,neque,congue&lt;/th&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.625&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;leo,dolor&lt;/th&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;at,amet,Ut,elit,elit,sit&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Matrix #11&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="9%" /&gt;
&lt;col width="9%" /&gt;
&lt;col width="9%" /&gt;
&lt;col width="9%" /&gt;
&lt;col width="9%" /&gt;
&lt;col width="9%" /&gt;
&lt;col width="9%" /&gt;
&lt;col width="9%" /&gt;
&lt;col width="9%" /&gt;
&lt;col width="9%" /&gt;
&lt;col width="9%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;Lorem&lt;/th&gt;
&lt;th class="head"&gt;Phasellus&lt;/th&gt;
&lt;th class="head"&gt;ultricies&lt;/th&gt;
&lt;th class="head"&gt;mi&lt;/th&gt;
&lt;th class="head"&gt;Sed&lt;/th&gt;
&lt;th class="head"&gt;Nullam&lt;/th&gt;
&lt;th class="head"&gt;consequat, consectetuer, neque, congue&lt;/th&gt;
&lt;th class="head"&gt;leo, dolor&lt;/th&gt;
&lt;th class="head"&gt;at, amet, Ut, elit, elit, sit&lt;/th&gt;
&lt;th class="head"&gt;adipiscing, ipsum&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Lorem&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Phasellus&lt;/th&gt;
&lt;td&gt;0.857&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;ultricies&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;mi&lt;/th&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Sed&lt;/th&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;Nullam&lt;/th&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;consequat,consectetuer,neque,congue&lt;/th&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;0.733&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;leo,dolor&lt;/th&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.833&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;1.000&lt;/td&gt;
&lt;td&gt;0.667&lt;/td&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;at,amet,Ut,elit,elit,sit&lt;/th&gt;
&lt;td&gt;0.778&lt;/td&gt;
&lt;td&gt;0.692&lt;/td&gt;
&lt;td&gt;0.818&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.600&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;adipiscing,ipsum&lt;/th&gt;
&lt;td&gt;0.800&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.684&lt;/td&gt;
&lt;td&gt;0.714&lt;/td&gt;
&lt;td&gt;0.846&lt;/td&gt;
&lt;td&gt;0.636&lt;/td&gt;
&lt;td&gt;0.625&lt;/td&gt;
&lt;td&gt;0.867&lt;/td&gt;
&lt;td&gt;0.750&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The remaining matrices have been left out, as this last one is the one we want for our unit-test!&lt;/p&gt;
&lt;/div&gt;
</content><category term="programming"/><category term="algorithms"/><category term="github"/><category term="python"/></entry><entry><title>Stepping through the failing data</title><link href="https://michel.albert.lu/stepping-through-the-failing-data.html" rel="alternate"/><published>2014-09-09T14:04:53+02:00</published><updated>2014-09-09T14:04:53+02:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2014-09-09:/stepping-through-the-failing-data.html</id><summary type="html">&lt;div class="figure align-left" style="width: 300px"&gt;
&lt;a class="reference external image-reference" href="https://michel.albert.lu/images/failing-example.svg"&gt;
&lt;img alt="Steps through the failing data." src="https://michel.albert.lu/images/failing-example.png" style="width: 300px;" /&gt;
&lt;/a&gt;
&lt;p class="caption"&gt;This is a thumbnail of a visualisation of the separate clustering steps.
Open &lt;a class="reference external" href="https://michel.albert.lu/images/failing-example.svg"&gt;original SVG file&lt;/a&gt; for
better readability.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The linked image shows the individual steps through the existing clustering
algorithm. Each &amp;quot;horizontal line&amp;quot; (the Y-Axis) represents one step of the
algorithm. The distance between each &amp;quot;line&amp;quot; represents the level …&lt;/p&gt;</summary><content type="html">&lt;div class="figure align-left" style="width: 300px"&gt;
&lt;a class="reference external image-reference" href="https://michel.albert.lu/images/failing-example.svg"&gt;
&lt;img alt="Steps through the failing data." src="https://michel.albert.lu/images/failing-example.png" style="width: 300px;" /&gt;
&lt;/a&gt;
&lt;p class="caption"&gt;This is a thumbnail of a visualisation of the separate clustering steps.
Open &lt;a class="reference external" href="https://michel.albert.lu/images/failing-example.svg"&gt;original SVG file&lt;/a&gt; for
better readability.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The linked image shows the individual steps through the existing clustering
algorithm. Each &amp;quot;horizontal line&amp;quot; (the Y-Axis) represents one step of the
algorithm. The distance between each &amp;quot;line&amp;quot; represents the level of the created
cluster. The first line represents the input data (the black dots).&lt;/p&gt;
&lt;p&gt;The X-Axis represents the input values (which ranged roughly between 0 and 1000).&lt;/p&gt;
&lt;p&gt;On each iteration, the last generated cluster is marked as a red circle, where
previous datums are shown as gray circles. As mentioned, the black dots on the
first line are the input values.&lt;/p&gt;
&lt;p&gt;Stepping through the code like this has revealed, that the error is not where I
think it is. The values here are all straight out of debugging data from a
test-run. In this execution, all values were present. Nothing went missing. I
will have to continue my search...&lt;/p&gt;
</content><category term="programming"/><category term="algorithms"/><category term="github"/><category term="python"/></entry><entry><title>So the Test isn't Failing</title><link href="https://michel.albert.lu/so-the-test-isnt-failing.html" rel="alternate"/><published>2014-09-08T18:33:11+02:00</published><updated>2014-09-08T18:33:11+02:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2014-09-08:/so-the-test-isnt-failing.html</id><summary type="html">&lt;p&gt;It turns out, the test I prepared earlier passes. So the reported issue needs a
bit more work. I wanted to avoid the data-set which reproduces the failure
because I'm lazy.&lt;/p&gt;
&lt;p&gt;I should have known better.&lt;/p&gt;
&lt;p&gt;So I will now do a similar manual step through the data-set as I …&lt;/p&gt;</summary><content type="html">&lt;p&gt;It turns out, the test I prepared earlier passes. So the reported issue needs a
bit more work. I wanted to avoid the data-set which reproduces the failure
because I'm lazy.&lt;/p&gt;
&lt;p&gt;I should have known better.&lt;/p&gt;
&lt;p&gt;So I will now do a similar manual step through the data-set as I did earlier...
This time, as the data is one-dimensional, I will need to find anotehr way to
visualise it. And I also think I will do that by manually writing an SVG file.
Clicking all that together with a mouse would be painful. Let's see where this
gets me...&lt;/p&gt;
</content><category term="programming"/><category term="algorithms"/><category term="github"/><category term="python"/></entry><entry><title>Blogging in reStructured Text</title><link href="https://michel.albert.lu/blogging-in-restructured-text.html" rel="alternate"/><published>2014-09-04T18:22:57+02:00</published><updated>2014-09-04T18:22:57+02:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2014-09-04:/blogging-in-restructured-text.html</id><summary type="html">&lt;p&gt;I have always been quite a big fan of &lt;a class="reference external" href="http://docutils.sourceforge.net/rst.html"&gt;reStructured Text&lt;/a&gt; Text as markup
format. It's easy to write and supports a lot of different text roles. It's not
a lot more difficult than &lt;a class="reference external" href="http://daringfireball.net/projects/markdown/"&gt;Markdown&lt;/a&gt; but can do a lot more. I always thought it
was a great blogging &amp;quot;platform …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I have always been quite a big fan of &lt;a class="reference external" href="http://docutils.sourceforge.net/rst.html"&gt;reStructured Text&lt;/a&gt; Text as markup
format. It's easy to write and supports a lot of different text roles. It's not
a lot more difficult than &lt;a class="reference external" href="http://daringfireball.net/projects/markdown/"&gt;Markdown&lt;/a&gt; but can do a lot more. I always thought it
was a great blogging &amp;quot;platform&amp;quot;. So I went searching, and found &lt;a class="reference external" href="http://docs.getpelican.com"&gt;Pelican&lt;/a&gt; as
static site generator. I have been playing around with it now for two days and
am impressed so far!&lt;/p&gt;
&lt;p&gt;To me the two biggest highlights are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Publishing from the shell and&lt;/li&gt;
&lt;li&gt;Tracking articles &lt;a class="reference external" href="https://github.com/exhuma/blog"&gt;via git&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As &lt;tt class="docutils literal"&gt;git&lt;/tt&gt; is a very viable option, publishing via hooks becomes a very nead
possibility as well. For now, I'm handling it with &lt;a class="reference external" href="http://fabfile.org"&gt;fabric&lt;/a&gt;, and I don't see the
immediate need to publish via hooks.&lt;/p&gt;
</content><category term="web"/><category term="publishing"/><category term="rst"/><category term="blogging"/></entry><entry><title>A Lesson in Unit Testing</title><link href="https://michel.albert.lu/a-lesson-in-unit-testing.html" rel="alternate"/><published>2014-09-04T09:00:00+02:00</published><updated>2014-09-07T12:11:46+02:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2014-09-04:/a-lesson-in-unit-testing.html</id><summary type="html">&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#hierarchical-clustering" id="toc-entry-1"&gt;Hierarchical Clustering&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#initial-step" id="toc-entry-2"&gt;Initial Step&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#single-linkage" id="toc-entry-3"&gt;Single Linkage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#complete-linkage" id="toc-entry-4"&gt;Complete Linkage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#uclus" id="toc-entry-5"&gt;Uclus&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;Quite some time back, I wrote a Python library for simple clustering tasks.
Back in the day, I only needed &lt;em&gt;K-Means&lt;/em&gt; clustering. But I decided I would add
&lt;em&gt;hierarchical clustering&lt;/em&gt; as well as it could come in handy later on …&lt;/p&gt;</summary><content type="html">&lt;div class="contents topic" id="contents"&gt;
&lt;p class="topic-title"&gt;&lt;a class="reference internal" href="#top"&gt;Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference internal" href="#hierarchical-clustering" id="toc-entry-1"&gt;Hierarchical Clustering&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference internal" href="#initial-step" id="toc-entry-2"&gt;Initial Step&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#single-linkage" id="toc-entry-3"&gt;Single Linkage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#complete-linkage" id="toc-entry-4"&gt;Complete Linkage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference internal" href="#uclus" id="toc-entry-5"&gt;Uclus&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;Quite some time back, I wrote a Python library for simple clustering tasks.
Back in the day, I only needed &lt;em&gt;K-Means&lt;/em&gt; clustering. But I decided I would add
&lt;em&gt;hierarchical clustering&lt;/em&gt; as well as it could come in handy later on.&lt;/p&gt;
&lt;p&gt;Turns out I &lt;strong&gt;messed up&lt;/strong&gt; the unit tests, &lt;em&gt;and&lt;/em&gt; the hierarchical clustering
algorithm. But the error went unnoticed as the unit-tests were not testing one
obvious fact:&lt;/p&gt;
&lt;blockquote&gt;
Are all the elements from the input present in the output? And &lt;em&gt;only&lt;/em&gt; those
from the input?&lt;/blockquote&gt;
&lt;p&gt;The main cause of this error is because the way I obtained the &lt;em&gt;expected&lt;/em&gt;
values was complete heresy! I ran the test run on random values, and simply
copy/pasted the results into the expected values. Of course now the test
passed, with the important fact that the tests were &lt;strong&gt;testing against the wrong
values!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In order to fix address this, I first need some proper test values. So now I do
what I should have done in the first place: &lt;strong&gt;Manually step through the
algorithm.&lt;/strong&gt; This article contains my scribbles which I will use as a &amp;quot;mental
strut&amp;quot;.&lt;/p&gt;
&lt;div class="section" id="hierarchical-clustering"&gt;
&lt;h2&gt;&lt;a class="toc-backref" href="#contents"&gt;Hierarchical Clustering&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;We will start of with a sample of non primitive data types. In this case points
on a two-dimensional plane. As distance function we will use the euclidian
distance. And, for the first step through, we will use single linkage between
clusters. The same scenario will be played through with complete- and
uclus-linkage later on. As overall method, we will use a bottom-up approach.&lt;/p&gt;
&lt;p&gt;The three aproaches will result in the following dendograms:&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Final Dendograms" src="https://michel.albert.lu/images/dendograms.png" /&gt;
&lt;/div&gt;
&lt;div class="section" id="initial-step"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#contents"&gt;Initial Step&lt;/a&gt;&lt;/h3&gt;
&lt;div class="figure"&gt;
&lt;img alt="Graph of initial data" src="https://michel.albert.lu/images/01-initial.png" /&gt;
&lt;/div&gt;
&lt;p&gt;So we have the following points:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
a (1, 1)
b (9, 1)
c (2, 2)
d (3, 2)
e (9, 2)
f (3, 4)
&lt;/pre&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p class="last"&gt;To keep the matrix table more readable, individual points are written in
lower-case, while clusters are written in upper-case!&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This results in the following initial distance matrix. We will mark the
diagonal with an &lt;tt class="docutils literal"&gt;x&lt;/tt&gt; as we're not interested in comparing a point with
itself.  Equally, we are only interested in the absolute distance. So we only
need the values for pairs on ons side of the diagonal.&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Distance Matrix&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;a&lt;/th&gt;
&lt;th class="head"&gt;b&lt;/th&gt;
&lt;th class="head"&gt;c&lt;/th&gt;
&lt;th class="head"&gt;d&lt;/th&gt;
&lt;th class="head"&gt;e&lt;/th&gt;
&lt;th class="head"&gt;f&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;a&lt;/th&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;8.00&lt;/td&gt;
&lt;td&gt;1.41&lt;/td&gt;
&lt;td&gt;2.24&lt;/td&gt;
&lt;td&gt;8.06&lt;/td&gt;
&lt;td&gt;3.61&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;b&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;7.07&lt;/td&gt;
&lt;td&gt;6.08&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;6.71&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;c&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;7.00&lt;/td&gt;
&lt;td&gt;2.24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;d&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;6.00&lt;/td&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;e&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;6.32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;f&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="single-linkage"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#contents"&gt;Single Linkage&lt;/a&gt;&lt;/h3&gt;
&lt;div class="section" id="first-step"&gt;
&lt;h4&gt;First Step&lt;/h4&gt;
&lt;div class="figure"&gt;
&lt;img alt="Graph showing the fist clustering step" src="https://michel.albert.lu/images/eb.png" /&gt;
&lt;/div&gt;
&lt;p&gt;With this matrix, we see that the first candidates are &lt;tt class="docutils literal"&gt;[b, e]&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;[c,
d]&lt;/tt&gt;. We'll pick &lt;tt class="docutils literal"&gt;[b, e]&lt;/tt&gt; as firt cluster (&lt;tt class="docutils literal"&gt;A&lt;/tt&gt;):&lt;/p&gt;
&lt;pre class="literal-block"&gt;
a (1, 1)
A (9, 1), (9, 2) level=1.00
c (2, 2)
d (3, 2)
f (3, 4)
&lt;/pre&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Distance Matrix&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="17%" /&gt;
&lt;col width="17%" /&gt;
&lt;col width="17%" /&gt;
&lt;col width="17%" /&gt;
&lt;col width="17%" /&gt;
&lt;col width="17%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;a&lt;/th&gt;
&lt;th class="head"&gt;A&lt;/th&gt;
&lt;th class="head"&gt;c&lt;/th&gt;
&lt;th class="head"&gt;d&lt;/th&gt;
&lt;th class="head"&gt;f&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;a&lt;/th&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;8.00&lt;/td&gt;
&lt;td&gt;1.41&lt;/td&gt;
&lt;td&gt;2.24&lt;/td&gt;
&lt;td&gt;3.61&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;A&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;7.00&lt;/td&gt;
&lt;td&gt;6.00&lt;/td&gt;
&lt;td&gt;6.32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;c&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;2.24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;d&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;f&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="second-step"&gt;
&lt;h4&gt;Second Step&lt;/h4&gt;
&lt;div class="figure"&gt;
&lt;img alt="Graph showing the second clustering step." src="https://michel.albert.lu/images/cd-eb.png" /&gt;
&lt;/div&gt;
&lt;p&gt;The next candidate is &lt;tt class="docutils literal"&gt;[c, d]&lt;/tt&gt; as &lt;tt class="docutils literal"&gt;B&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
a (1, 1)
A (9, 1), (9, 2) level=1.00
B (2, 2), (3, 2) level=1.00
f (3, 4)
&lt;/pre&gt;
&lt;p&gt;Giving us:&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Distance Matrix&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="20%" /&gt;
&lt;col width="20%" /&gt;
&lt;col width="20%" /&gt;
&lt;col width="20%" /&gt;
&lt;col width="20%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;a&lt;/th&gt;
&lt;th class="head"&gt;A&lt;/th&gt;
&lt;th class="head"&gt;B&lt;/th&gt;
&lt;th class="head"&gt;f&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;a&lt;/th&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;8.00&lt;/td&gt;
&lt;td&gt;1.41&lt;/td&gt;
&lt;td&gt;3.61&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;A&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;6.00&lt;/td&gt;
&lt;td&gt;6.32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;B&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;f&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="third-step"&gt;
&lt;h4&gt;Third Step&lt;/h4&gt;
&lt;div class="figure"&gt;
&lt;img alt="Graph showing the third clustering step." src="https://michel.albert.lu/images/cdf-eb.png" /&gt;
&lt;/div&gt;
&lt;p&gt;Then &lt;tt class="docutils literal"&gt;[f, B]&lt;/tt&gt; as &lt;tt class="docutils literal"&gt;C&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
a (1, 1)
A (9, 1), (9, 2) level=1.00
C (3, 4), ((2, 2), (3, 2) level=1.00) level=2.00
&lt;/pre&gt;
&lt;p&gt;Resulting in:&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Distance Matrix&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="25%" /&gt;
&lt;col width="25%" /&gt;
&lt;col width="25%" /&gt;
&lt;col width="25%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;a&lt;/th&gt;
&lt;th class="head"&gt;A&lt;/th&gt;
&lt;th class="head"&gt;C&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;a&lt;/th&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;8.00&lt;/td&gt;
&lt;td&gt;1.41&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;A&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;6.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;C&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="fourth-step"&gt;
&lt;h4&gt;Fourth Step&lt;/h4&gt;
&lt;div class="figure"&gt;
&lt;img alt="Graph showing the fourth clustering step." src="https://michel.albert.lu/images/acdf-eb-1.png" /&gt;
&lt;/div&gt;
&lt;p&gt;Then &lt;tt class="docutils literal"&gt;[a, C]&lt;/tt&gt; as &lt;tt class="docutils literal"&gt;D&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
A (9, 1), (9, 2) level=1.00
D (1, 1), ((3, 4), ((2, 2), (3, 2) level=1.00) level=2.00) level=1.41
&lt;/pre&gt;
&lt;p&gt;Resulting in:&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Distance Matrix&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="33%" /&gt;
&lt;col width="33%" /&gt;
&lt;col width="33%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;A&lt;/th&gt;
&lt;th class="head"&gt;D&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;A&lt;/th&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;6.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;D&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Which gives us the final cluster &lt;tt class="docutils literal"&gt;E&lt;/tt&gt; with a level of &lt;tt class="docutils literal"&gt;6.00&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;The end-result is the following dendogram:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
               E
               |
   +-----------+-----------+
   |                       |
   |                       D
   |                       |
   |                 +-----+-----+
   |                 |           |
   |                 C           |
   |                 |           |
   |            +----+----+      |
   |            |         |      |
   A            B         |      |
   |            |         |      |
+--+--+      +--+--+      |      |
|     |      |     |      |      |
e     b      c     d      f      a
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="complete-linkage"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#contents"&gt;Complete Linkage&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Initial distance matrix for reference:&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Distance Matrix&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;a&lt;/th&gt;
&lt;th class="head"&gt;b&lt;/th&gt;
&lt;th class="head"&gt;c&lt;/th&gt;
&lt;th class="head"&gt;d&lt;/th&gt;
&lt;th class="head"&gt;e&lt;/th&gt;
&lt;th class="head"&gt;f&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;a&lt;/th&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;8.00&lt;/td&gt;
&lt;td&gt;1.41&lt;/td&gt;
&lt;td&gt;2.24&lt;/td&gt;
&lt;td&gt;8.06&lt;/td&gt;
&lt;td&gt;3.61&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;b&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;7.07&lt;/td&gt;
&lt;td&gt;6.08&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;6.71&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;c&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;7.00&lt;/td&gt;
&lt;td&gt;2.24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;d&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;6.00&lt;/td&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;e&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;6.32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;f&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="section" id="first-step-1"&gt;
&lt;h4&gt;First Step&lt;/h4&gt;
&lt;p&gt;First iteration is identical, but distance matrix has different values. The
subsequent steps will be displayed without aditional explanation, the idea is
the same as above, simply using a different linkage function.&lt;/p&gt;
&lt;div class="figure"&gt;
&lt;img alt="Graph showing the first clustering step." src="https://michel.albert.lu/images/eb.png" /&gt;
&lt;/div&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Distance Matrix&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="17%" /&gt;
&lt;col width="17%" /&gt;
&lt;col width="17%" /&gt;
&lt;col width="17%" /&gt;
&lt;col width="17%" /&gt;
&lt;col width="17%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;a&lt;/th&gt;
&lt;th class="head"&gt;A&lt;/th&gt;
&lt;th class="head"&gt;c&lt;/th&gt;
&lt;th class="head"&gt;d&lt;/th&gt;
&lt;th class="head"&gt;f&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;a&lt;/th&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;8.06&lt;/td&gt;
&lt;td&gt;1.41&lt;/td&gt;
&lt;td&gt;2.24&lt;/td&gt;
&lt;td&gt;3.61&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;A&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;7.07&lt;/td&gt;
&lt;td&gt;6.08&lt;/td&gt;
&lt;td&gt;6.71&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;c&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;2.24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;d&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;f&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="second-step-1"&gt;
&lt;h4&gt;Second Step&lt;/h4&gt;
&lt;div class="figure"&gt;
&lt;img alt="Graph showing the second clustering step." src="https://michel.albert.lu/images/cd-eb.png" /&gt;
&lt;/div&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Distance Matrix&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="20%" /&gt;
&lt;col width="20%" /&gt;
&lt;col width="20%" /&gt;
&lt;col width="20%" /&gt;
&lt;col width="20%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;a&lt;/th&gt;
&lt;th class="head"&gt;A&lt;/th&gt;
&lt;th class="head"&gt;B&lt;/th&gt;
&lt;th class="head"&gt;f&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;a&lt;/th&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;8.06&lt;/td&gt;
&lt;td&gt;2.24&lt;/td&gt;
&lt;td&gt;3.61&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;A&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;7.07&lt;/td&gt;
&lt;td&gt;6.71&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;B&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;2.24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;f&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="third-step-1"&gt;
&lt;h4&gt;Third Step&lt;/h4&gt;
&lt;div class="admonition note"&gt;
&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;We now have to make a choice. I have not yet decided on how to handle this
situation to have a detereministic behaviour. My current train of thought
is using python &lt;tt class="docutils literal"&gt;sets&lt;/tt&gt; as data-structure which is unordered. So the
algorithm could return either one here.&lt;/p&gt;
&lt;p class="last"&gt;For a demonstration, we'll pick &lt;tt class="docutils literal"&gt;[Ba]&lt;/tt&gt; as to have a different result from
sinle linkage...&lt;/p&gt;
&lt;/div&gt;
&lt;div class="figure"&gt;
&lt;img alt="Graph showing the third clustering step." src="https://michel.albert.lu/images/acd-eb.png" /&gt;
&lt;/div&gt;
&lt;p&gt;This will give us:&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Distance Matrix&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="25%" /&gt;
&lt;col width="25%" /&gt;
&lt;col width="25%" /&gt;
&lt;col width="25%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;C&lt;/th&gt;
&lt;th class="head"&gt;A&lt;/th&gt;
&lt;th class="head"&gt;f&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;C&lt;/th&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;8.06&lt;/td&gt;
&lt;td&gt;3.61&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;A&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;6.71&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;f&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="section" id="fourth-step-1"&gt;
&lt;h4&gt;Fourth Step&lt;/h4&gt;
&lt;div class="figure"&gt;
&lt;img alt="Graph showing the fourth clustering step." src="https://michel.albert.lu/images/acdf-eb-2.png" /&gt;
&lt;/div&gt;
&lt;p&gt;And finally&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Distance Matrix&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="33%" /&gt;
&lt;col width="33%" /&gt;
&lt;col width="33%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;D&lt;/th&gt;
&lt;th class="head"&gt;A&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;D&lt;/th&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;8.06&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;A&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The end-result is the following dendogram:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
               E
               |
   +-----------+-----------+
   |                       |
   |                       D
   |                       |
   |                 +-----+-----+
   |                 |           |
   |                 C           |
   |                 |           |
   |            +----+----+      |
   |            |         |      |
   A            B         |      |
   |            |         |      |
+--+--+      +--+--+      |      |
|     |      |     |      |      |
e     b      c     d      a      f
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="uclus"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#contents"&gt;Uclus&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Initial distance matrix for reference:&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Distance Matrix&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;col width="14%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;a&lt;/th&gt;
&lt;th class="head"&gt;b&lt;/th&gt;
&lt;th class="head"&gt;c&lt;/th&gt;
&lt;th class="head"&gt;d&lt;/th&gt;
&lt;th class="head"&gt;e&lt;/th&gt;
&lt;th class="head"&gt;f&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;a&lt;/th&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;8.00&lt;/td&gt;
&lt;td&gt;1.41&lt;/td&gt;
&lt;td&gt;2.24&lt;/td&gt;
&lt;td&gt;8.06&lt;/td&gt;
&lt;td&gt;3.61&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;b&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;7.07&lt;/td&gt;
&lt;td&gt;6.08&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;6.71&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;c&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;7.00&lt;/td&gt;
&lt;td&gt;2.24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;d&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;6.00&lt;/td&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;e&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;6.32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;f&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;As in complete linkage, the first iteration is identical, but distance matrix
has different values. So we will not go into too much detail and will skip the
visualisations.&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Distance Matrix&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="17%" /&gt;
&lt;col width="17%" /&gt;
&lt;col width="17%" /&gt;
&lt;col width="17%" /&gt;
&lt;col width="17%" /&gt;
&lt;col width="17%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;a&lt;/th&gt;
&lt;th class="head"&gt;A&lt;/th&gt;
&lt;th class="head"&gt;c&lt;/th&gt;
&lt;th class="head"&gt;d&lt;/th&gt;
&lt;th class="head"&gt;f&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;a&lt;/th&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;8.03&lt;/td&gt;
&lt;td&gt;1.41&lt;/td&gt;
&lt;td&gt;2.24&lt;/td&gt;
&lt;td&gt;3.61&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;A&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;7.04&lt;/td&gt;
&lt;td&gt;6.04&lt;/td&gt;
&lt;td&gt;6.52&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;c&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;1.00&lt;/td&gt;
&lt;td&gt;2.24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;d&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;f&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Distance Matrix&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="20%" /&gt;
&lt;col width="20%" /&gt;
&lt;col width="20%" /&gt;
&lt;col width="20%" /&gt;
&lt;col width="20%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;a&lt;/th&gt;
&lt;th class="head"&gt;A&lt;/th&gt;
&lt;th class="head"&gt;B&lt;/th&gt;
&lt;th class="head"&gt;f&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;a&lt;/th&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;8.03&lt;/td&gt;
&lt;td&gt;1.83&lt;/td&gt;
&lt;td&gt;3.61&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;A&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;6.54&lt;/td&gt;
&lt;td&gt;6.52&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;B&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;2.12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;f&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Distance Matrix&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="25%" /&gt;
&lt;col width="25%" /&gt;
&lt;col width="25%" /&gt;
&lt;col width="25%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;C&lt;/th&gt;
&lt;th class="head"&gt;A&lt;/th&gt;
&lt;th class="head"&gt;f&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;C&lt;/th&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;7.04&lt;/td&gt;
&lt;td&gt;2.24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;A&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;6.52&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;f&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;And finally&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;caption&gt;Distance Matrix&lt;/caption&gt;
&lt;colgroup&gt;
&lt;col width="33%" /&gt;
&lt;col width="33%" /&gt;
&lt;col width="33%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head stub"&gt;&amp;nbsp;&lt;/th&gt;
&lt;th class="head"&gt;D&lt;/th&gt;
&lt;th class="head"&gt;A&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;th class="stub"&gt;D&lt;/th&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;td&gt;6.86&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;th class="stub"&gt;A&lt;/th&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The end-result is the following dendogram:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
               E
               |
   +-----------+-----------+
   |                       |
   |                       D
   |                       |
   |                 +-----+-----+
   |                 |           |
   |                 C           |
   |                 |           |
   |            +----+----+      |
   |            |         |      |
   A            B         |      |
   |            |         |      |
+--+--+      +--+--+      |      |
|     |      |     |      |      |
e     b      c     d      a      f
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="programming"/><category term="algorithms"/><category term="github"/><category term="python"/></entry><entry><title>Add creation and modification timestamps to an Excel worksheet</title><link href="https://michel.albert.lu/add-creation-and-modification-timestamps-to-an-excel-worksheet.html" rel="alternate"/><published>2002-02-19T09:00:00+01:00</published><updated>2002-02-19T09:00:00+01:00</updated><author><name>Michel Albert</name></author><id>tag:michel.albert.lu,2002-02-19:/add-creation-and-modification-timestamps-to-an-excel-worksheet.html</id><summary type="html">&lt;p&gt;Please, for the love of $deity do not hit me….. This is going to be a post
about excel!&lt;/p&gt;
&lt;p&gt;Excel is a horrid solution for data entry, and even worse for data archival.
And yet, it’s one of the most commonly used solutions. One of the most useful
information …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Please, for the love of $deity do not hit me….. This is going to be a post
about excel!&lt;/p&gt;
&lt;p&gt;Excel is a horrid solution for data entry, and even worse for data archival.
And yet, it’s one of the most commonly used solutions. One of the most useful
information in any given data-set is the information about when the information
was created and when it was last modified. This is something that any decent
developer in charge of a data collection (let’s just call it that for now) will
add to each data record.&lt;/p&gt;
&lt;p&gt;Alas, a lot of non-IT people manage and store their data in excel worksheets.
And that is OK with me as long as they pay attention to data archival. In it’s
most simple form, data archival can be achieved by storing the data as a CSV
file and including the following metadata:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Which column represents which value (the name of the variable)&lt;/li&gt;
&lt;li&gt;The data type (f.ex.: number, text, date, …) of each column&lt;/li&gt;
&lt;li&gt;If a column is “coded”, please also include the meaning of each code.
For example a “Yes”, “No”, “Maybe” column might be stored as “1”, “2” and
“3”. Which means in it’s most basic nature it’s a numeric variable, but the
different values have a meaning attached to them. So: Add this list in your
metadata description.&lt;/li&gt;
&lt;li&gt;If any computations or checks are performed on the values, please add them to
the metadata document as well!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Even if the timestamp values might seem superflous at first, it will be of
great help to anyone tracing errors in the data. Imagine that you would at some
point need to fix some values that were entered/modified during a specific time
period for whatever reason. Without this most basic bit of information you will
be up for a treat. However, if it’s been rigurously implemented since the
beginning, you’ll have the problem solved in no time.&lt;/p&gt;
&lt;p&gt;Now, each halfway serious database system will offer you this kind of
functionality out-of-the-box. But Excel is no database system (I intentionally
left out the word “management” as this issue is a bit more general!). So it
does not offer you a straight-forward way to solve this. But even if it’s not
straight-forward, it’s simple enough for about anyone using Excel do add this
bit of information.&lt;/p&gt;
&lt;p&gt;Assuming that you use the first two columns (numbered 1 and 2 in excel) of your
worksheet to add creation- and modification timestamps simply open up the
Visual Basic editor (found in Tools-&amp;gt;Macro or somesuch), next, in your project
tree (in the top left of the screen) select your workbook (the .xls file), and
in it’s sub-tree double-click the Worksheet that should have the timestamps set
automatically.&lt;/p&gt;
&lt;p&gt;Then copy/paste the following text into the just opened code editor and you’re
done. I hope the comments will give some insight as to what happens. Note that
in this case I will ignore the first row of the sheet, and obviously, the first
two columns. If that does not suit your needs, feel free to change this script
to your liking.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c"&gt;&amp;#39;&lt;/span&gt;
&lt;span class="c"&gt;&amp;#39; Callback which is called when a cell in a workbook changes&lt;/span&gt;
&lt;span class="c"&gt;&amp;#39; @param Target: The cell that changed it&amp;#39;s value&lt;/span&gt;
&lt;span class="c"&gt;&amp;#39;&lt;/span&gt;
&lt;span class="k"&gt;Private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Sub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Worksheet_Change&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ByVal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;As&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c"&gt;&amp;#39; We will ignore any changes in the first row, as it contains header&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c"&gt;&amp;#39; labels&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;If&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Row&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Then&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Sub&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&amp;#39;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c"&gt;&amp;#39; As we set the values of column 1 and 2 we won&amp;#39;t need to capture&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c"&gt;&amp;#39; changes in these either&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;If&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;Or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Then&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Exit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Sub&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;&amp;#39;&amp;#39;&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c"&gt;&amp;#39; We will update the timestamp in column 2 *always* (last changed time)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;Cells&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c"&gt;&amp;#39; We will update the timestamp in column 1 only if it is empty (creation&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c"&gt;&amp;#39; time)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;If&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IsEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Cells&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Then&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;Cells&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="k"&gt;End&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;If&lt;/span&gt;
&lt;span class="k"&gt;End&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;Sub&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
</content><category term="programming"/><category term="data quality"/><category term="excel"/><category term="vba"/></entry></feed>