<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>six degrees of separation</title>
	<atom:link href="http://sixdegrees.hu/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://sixdegrees.hu/blog</link>
	<description>Random musings on complex networks, machine learning, game theory and stuff</description>
	<lastBuildDate>Tue, 16 Nov 2010 15:21:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>igraph 0.6 ported to Python 3.x</title>
		<link>http://sixdegrees.hu/blog/2010/11/igraph-0-6-ported-to-python-3-x/</link>
		<comments>http://sixdegrees.hu/blog/2010/11/igraph-0-6-ported-to-python-3-x/#comments</comments>
		<pubDate>Tue, 16 Nov 2010 15:19:03 +0000</pubDate>
		<dc:creator>Tamás</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://sixdegrees.hu/?p=185</guid>
		<description><![CDATA[Recently I've committed quite a few patches to the igraph trunk that adapts igraph's Python interface for the API-incompatible changes introduced between Python 2.x and Python 3. Currently, all the 222 test cases pass both in Python 2.6 and Python 3.1, although there might be a few edge cases (especially around UTF-8 encoding issues and [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I've committed quite a few patches to the <a href="https://code.launchpad.net/igraph/trunk">igraph trunk</a> that adapts igraph's Python interface for the API-incompatible changes introduced between Python 2.x and Python 3. Currently, all the 222 test cases pass both in Python 2.6 and Python 3.1, although there might be a few edge cases (especially around UTF-8 encoding issues and GraphML support) that may require further work.</p>

<pre>$ python3.1 -m igraph.test.__init__
................................................................
................................................................
................................................................
..............................
----------------------------------------------------------------
Ran 222 tests in 1.802s

OK</pre>

<p>Therefore, I'm happy to announce that <a href="http://pypi.python.org/pypi/python-igraph">python-igraph</a> will officially support Python 3 starting from the next major release; that is, 0.6. If you can't wait till the next release and would like to take it for a test drive, you can grab the <a href="http://code.google.com/p/igraph">nightly builds</a> from Google Code and compile them for yourself.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixdegrees.hu/blog/2010/11/igraph-0-6-ported-to-python-3-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Git-aware shell prompt</title>
		<link>http://sixdegrees.hu/blog/2010/09/git-aware-shell-prompt/</link>
		<comments>http://sixdegrees.hu/blog/2010/09/git-aware-shell-prompt/#comments</comments>
		<pubDate>Thu, 16 Sep 2010 13:52:58 +0000</pubDate>
		<dc:creator>Tamás</dc:creator>
				<category><![CDATA[Asides]]></category>
		<category><![CDATA[English]]></category>

		<guid isPermaLink="false">http://sixdegrees.hu/?p=178</guid>
		<description><![CDATA[Just learned today that there's a neat function called __git_ps1 in the official bash completion file for Git (usually named as git-completion.bash), which enables one to display the current Git branch in the shell prompt if the current directory is a Git repository. Just put the following somewhere in your bash prompt: $&#40;__git_ps1 &#34;(%s)&#34;&#41; Make [...]]]></description>
			<content:encoded><![CDATA[<p>Just learned today that there's a neat function called <code>__git_ps1</code> in the official bash completion file for Git (usually named as <a href="http://git.kernel.org/?p=git/git.git;a=blob;f=contrib/completion/git-completion.bash;h=67569901e71e5062199e48304afc424f15b57ba1;hb=master"><code>git-completion.bash</code></a>), which enables one to display the current Git branch in the shell prompt if the current directory is a Git repository. Just put the following somewhere in your bash prompt:</p>

<pre class="bash">$<span style="color: #7a0874; font-weight: bold;">&#40;</span>__git_ps1 <span style="color: #ff0000;">&quot;(%s)&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre>

<p>Make sure that you use single quotes when you set the bash prompt (e.g., <code>export PS1='...'</code> instead of <code>export PS1="..."</code>) to ensure that the command is executed every time the prompt is displayed.</p>

<p>You may also use specific environment variables to tweak the behaviour of <code>__git_ps1</code>:</p>

<pre class="bash"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">GIT_PS1_SHOWDIRTYSTATE=</span>true
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">GIT_PS1_SHOWUNTRACKEDFILES=</span>true
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">GIT_PS1_SHOWSTASHSTATE=</span>true</pre>
]]></content:encoded>
			<wfw:commentRss>http://sixdegrees.hu/blog/2010/09/git-aware-shell-prompt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating animations in igraph</title>
		<link>http://sixdegrees.hu/blog/2010/09/creating-animations-in-igraph/</link>
		<comments>http://sixdegrees.hu/blog/2010/09/creating-animations-in-igraph/#comments</comments>
		<pubDate>Mon, 13 Sep 2010 11:16:25 +0000</pubDate>
		<dc:creator>Tamás</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://sixdegrees.hu/?p=162</guid>
		<description><![CDATA[This entry presents an add-on to the Python package of igraph that enables one to create nifty animations featuring igraph graphs with ease. At the moment, the add-on requires MEncoder to encode consecutive frames to an AVI video file, but it is easy to add support for other video encoders like FFMpeg or even to [...]]]></description>
			<content:encoded><![CDATA[<p>This entry presents an add-on to the <a href="http://pypi.python.org/pypi/igraph">Python package of igraph</a> that enables one to create nifty animations featuring igraph graphs with ease. At the moment, the add-on requires <a href="http://www.mplayerhq.hu">MEncoder</a> to encode consecutive frames to an AVI video file, but it is easy to add support for other video encoders like <a href="http://www.ffmpeg.org">FFMpeg</a> or even to use <a href="http://pymedia.org">PyMedia</a> to encode the video stream directly without saving the individual frames to disk first. I will also show two usage examples, one for the visualisation of the GraphOpt layout algorithm and the other for the simulation of a simple SIR (susceptible-infected-recovered) epidemic model.</p>

<p><span id="more-162"></span></p>

<h2>Requirements</h2>

<p>If you want to <a href="http://gist.github.com/577159">try this add-on</a>, you will need the following:</p>

<ul>
<li><p><a href="http://www.python.org">Python 2.5</a> or later. To tell the truth, I've only tested the module in
Python 2.6, but it should work in Python 2.5 as well - if not, let me know!
Python 3 is not supported yet as igraph itself does not support Python 3.</p></li>
<li><p><a href="http://igraph.sourceforge.net">igraph</a> 0.5.3 or later and its <a href="http://pypi.python.org/pypi/igraph">Python bindings</a>.</p></li>
<li><p>A working <code>mencoder</code> executable somewhere in your path. If you have it but
you don't want to add it to your path, that's fine, just remember to pass
the full path of the executable to the <code>MEncoderVideoEncoder</code> constructor
in the examples.</p></li>
</ul>

<p>Of course you will also need <a href="http://gist.github.com/577159">the add-on itself</a>.</p>

<h2>Where to get it from</h2>

<p>The add-on is currently hosted on GitHub; <a href="http://gist.github.com/577159">click here to download it</a>. Place the file somewhere on your Python path so Python can find it, then type <code>from video import MEncoderVideoEncoder</code>.</p>

<h2>The basic API</h2>

<p>The essence of the add-on is an abstract class called <code>VideoEncoder</code>, and its derived subclasses. Well, that's an overstatement, since currently the only subclass of <code>VideoEncoder</code> is <code>MEncoderVideoEncoder</code>, which teaches igraph how to handle <a href="http://www.mplayerhq.hu">MEncoder</a> in order to encode a series of images into an AVI file. So, the first step is always to construct an instance of an appropriate <code>VideoEncoder</code> subclass; e.g.:</p>

<pre class="python">encoder = MEncoderVideoEncoder<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>

<p>At construction time, you may also specify the bounding box (i.e. the width and height) of the video and the number of frames per second (FPS). The default FPS value is 25. This is how to override the bounding box and the FPS:</p>

<pre class="python">encoder = MEncoderVideoEncoder<span style="color: black;">&#40;</span>bbox=<span style="color: black;">&#40;</span><span style="color: #ff4500;">400</span>, <span style="color: #ff4500;">300</span><span style="color: black;">&#41;</span>, fps=<span style="color: #ff4500;">12</span><span style="color: black;">&#41;</span></pre>

<p>You can also override the bounding box and the FPS later by assigning new values to the corresponding instance attributes:</p>

<pre class="python">encoder.<span style="color: black;">bbox</span> = <span style="color: black;">&#40;</span><span style="color: #ff4500;">500</span>, <span style="color: #ff4500;">400</span><span style="color: black;">&#41;</span>
encoder.<span style="color: black;">fps</span> = <span style="color: #ff4500;">24</span></pre>

<p>Besides these attributes, you will only need the <code>add()</code> and <code>save()</code> methods of the encoder instance. <code>add()</code> adds the next frame to the animation, while <code>save()</code> saves the whole animation to an AVI file. <code>add()</code> accepts names of image files, igraph's <code>Plot</code> objects, or any plottable igraph object (such as <code>Graph</code>); in the latter case, a corresponding <code>Plot</code> object will be created automatically and added to the video sequence. For example:</p>

<pre class="python">encoder.<span style="color: black;">add</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;my_title_page.png&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
p = igraph.<span style="color: black;">Plot</span><span style="color: black;">&#40;</span>bbox=<span style="color: black;">&#40;</span><span style="color: #ff4500;">500</span>, <span style="color: #ff4500;">400</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
p.<span style="color: black;">add</span><span style="color: black;">&#40;</span>graph, vertex_color=<span style="color: #483d8b;">&quot;green&quot;</span><span style="color: black;">&#41;</span>
encoder.<span style="color: black;">add</span><span style="color: black;">&#40;</span>p<span style="color: black;">&#41;</span>
&nbsp;
encoder.<span style="color: black;">add</span><span style="color: black;">&#40;</span>graph, layout=<span style="color: #483d8b;">&quot;kamada_kawai&quot;</span><span style="color: black;">&#41;</span></pre>

<p>The supported image formats depend solely on the video encoding backend; in case of <a href="http://www.mplayerhq.hu">MEncoder</a>, you can safely use either PNG or JPG files. Finally, when you have added all the frames in the right order, you have to call <code>save()</code> to start encoding the video:</p>

<pre class="python">encoder.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;my_video.avi&quot;</span><span style="color: black;">&#41;</span></pre>

<p>There is also an alternative syntax using Python's <code>with</code> keyword:</p>

<pre class="python">encoder = MEncoderVideoEncoder<span style="color: black;">&#40;</span>bbox=<span style="color: black;">&#40;</span><span style="color: #ff4500;">400</span>, <span style="color: #ff4500;">300</span><span style="color: black;">&#41;</span>, fps=<span style="color: #ff4500;">12</span><span style="color: black;">&#41;</span>
with encoder.<span style="color: black;">encode_to</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;my_video.avi&quot;</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;"># Here you can add your frames by calling encoder.add()</span></pre>

<p>The video encoding will then start automatically as soon as Python leaves the indented <code>with</code> block -- no need to call <code>save()</code> at all.</p>

<h2>Behind the scenes</h2>

<p><code>MEncoderVideoEncoder</code> manages a temporary directory in the background. Frames you have added to the video stream are stored in this temporary directory (unless they were already saved as image files on the hard drive). This means that when you <code>add()</code> a <code>Plot</code> instance or a plottable igraph object, it is rendered immediately to a file in the temporary directory. You can keep on modifying the object you have plotted without affecting the frame. The temporary directory is removed either when the video encoder object is garbage collected or deleted with the <code>del</code> operator, or when the <code>save()</code> function returns successfully. This means that you do not have to worry about the temporary directory (in fact, you do not even have to know that it exists), everything will be cleaned up properly, even if an exception happens while you are constructing the frames.</p>

<p>You may have also noticed that I have not mentioned how to specify the codec used during encoding. The default codec is <code>msmpeg4v2</code>, as it seems to be the only codec that is installed on a vanilla Windows XP. If you need a better codec (well, it's not too hard to be better than <code>msmpeg4v2</code> anyway), you can modify the <code>lavcopts</code> attribute of the <code>MEncoderVideoEncoder</code> instance -- this tweaks the value of the <code>-lavcopts</code> command line switch of <code>mencoder</code>. Please refer to the relevant chapter of the <a href="http://www.mplayerhq.hu/DOCS/HTML/en/menc-feat-enc-libavcodec.html">MEncoder documentation</a> for more information. The <code>lavcopts</code> instance variable accepts both strings and dictionaries; e.g., the following two calls are equivalent:</p>

<pre class="python">encoder.<span style="color: black;">lavcopts</span> = <span style="color: #483d8b;">&quot;vcodec=mpeg4:mbd=2:vbitrate=1600:trell:keyint=50&quot;</span>
encoder.<span style="color: black;">lavcopts</span> = <span style="color: black;">&#123;</span>
    <span style="color: #483d8b;">&quot;vcodec&quot;</span>: <span style="color: #483d8b;">&quot;mpeg4&quot;</span>,
    <span style="color: #483d8b;">&quot;mbd&quot;</span>: <span style="color: #ff4500;">2</span>,
    <span style="color: #483d8b;">&quot;vbitrate&quot;</span>: <span style="color: #ff4500;">1600</span>,
    <span style="color: #483d8b;">&quot;trell&quot;</span>: <span style="color: #008000;">True</span>,
    <span style="color: #483d8b;">&quot;keyint&quot;</span>: <span style="color: #ff4500;">50</span>
<span style="color: black;">&#125;</span></pre>

<p>Setting <code>lavcopts</code> to <code>None</code> resets it to the default value, which is <code>vcodec=msmpeg4v2</code>.</p>

<p><code>MEncoderVideoEncoder</code> also has an instance variable named <code>verbose</code>. If <code>verbose</code> is <code>True</code>, the output of MEncoder will be piped back to the standard output of the invoking Python process, so you can directly see the progress messages from MEncoder. IF <code>verbose</code> is <code>False</code>, only error messages will be printed. The encoder is in quiet mode by default.</p>

<h2>Example #1: Layout visualisation</h2>

<p>This section presents a short code snippet that demonstrates how the GraphOpt layout algorithm works in igraph. The GraphOpt algorithm uses basic principles of physics to determine an optimal graph layout iteratively. Each node in the graph is given a mass and an electric charge, and each edge represents a spring. The layout is then calculated by simulating the actual physical system for a given number of steps.</p>

<p>In our example, we will visualise the GraphOpt algorithm by running it one step at a time and then adding the current layout to the video stream. We will make use of the fact that passing a keyword argument <code>seed=...</code> to the GraphOpt layout function will specify the initial layout the algorithm is started from. We will also calculate a clustering of the graph using the <a href="http://www.arxiv.org/abs/cond-mat/0402349">spinglass clustering algorithm</a> and show how the nodes in the clusters are pulled close to each other by the layout algorithm. For the latter part, we will make use of a recent addition in igraph 0.6 which enables one to plot a <code>VertexClustering</code> object directly. The code is as follows (assuming that you have imported <code>Graph</code> from the igraph module and <code>MEncoderVideoEncoder</code> from the add-on):</p>

<pre class="python"><span style="color: #808080; font-style: italic;"># Generate graph and find the communities</span>
graph = Graph.<span style="color: black;">GRG</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">100</span>, <span style="color: #ff4500;">0.2</span><span style="color: black;">&#41;</span>
clusters = graph.<span style="color: black;">community_spinglass</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Specify initial layout</span>
layout = <span style="color: #008000;">None</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Set up the video encoder</span>
encoder = MEncoderVideoEncoder<span style="color: black;">&#40;</span>bbox=<span style="color: black;">&#40;</span><span style="color: #ff4500;">600</span>, <span style="color: #ff4500;">600</span><span style="color: black;">&#41;</span>, fps=<span style="color: #ff4500;">30</span><span style="color: black;">&#41;</span>
encoder.<span style="color: black;">lavcopts</span> = <span style="color: #483d8b;">&quot;vcodec=mpeg4:mbd=2:vbitrate=1600:trell:keyint=30&quot;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Generate frames in the animation one by one</span>
with encoder.<span style="color: black;">encode_to</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;demo_layout.avi&quot;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">500</span><span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;"># Run one step of the layout algorithm</span>
        layout = graph.<span style="color: black;">layout</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;graphopt&quot;</span>, niter=<span style="color: #ff4500;">1</span>, seed=layout<span style="color: black;">&#41;</span>
        <span style="color: #808080; font-style: italic;"># Add the clustering to the encoder</span>
        encoder.<span style="color: black;">add</span><span style="color: black;">&#40;</span>clusters, layout=layout, mark_groups=<span style="color: #008000;">True</span>, margin=<span style="color: #ff4500;">20</span><span style="color: black;">&#41;</span></pre>

<p>And this is how the result looks like:</p>

<div align="center"><object width="400" height="400"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=14922587&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=14922587&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="400"></embed></object><br /></div>

<h2>Example #2: Epidemic spreading on networks</h2>

<p>This example illustrates a simple epidemic spreading model called the SIR model on a geometric random graph. In the SIR model, each node can be in one of three states: <strong>S</strong> is <em>susceptible</em> (i.e. not infected, but prone to infections), <strong>I</strong> is <em>infected</em> and <strong>R</strong> is <em>recovered</em> (i.e. it was infected at some point, but it will not be infected again). Nodes start in the <strong>S</strong> state and move to the <strong>I</strong> state if they get infected. Once infected, a node will try to infect its neighbors in each time step with a spreading probability <em>&beta;</em>. Infected nodes may recover from the infection in every time step with probability <em>&gamma;</em>; after recovery, such nodes move to the <strong>R</strong> state and stay there forever.</p>

<p>When implementing the SIR model in Python using igraph, we attach an attribute named <code>state</code> to the vertices, denoting which state the vertex is in. We will also need a dictionary that maps vertex states to colors in the visualisation (red = infected, green = recovered, white = susceptible). The whole setup procedure is then as follows:</p>

<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> igraph <span style="color: #ff7700;font-weight:bold;">import</span> Graph, Layout
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">random</span> <span style="color: #ff7700;font-weight:bold;">import</span> sample, <span style="color: #dc143c;">random</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Specify the simulation parameters</span>
initial_outbreak_size = <span style="color: #ff4500;">3</span>
beta = <span style="color: #ff4500;">0.05</span>
gamma = <span style="color: #ff4500;">0.1</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Set up the mapping from vertex states to colors</span>
colormap=<span style="color: #008000;">dict</span><span style="color: black;">&#40;</span>S=<span style="color: #483d8b;">&quot;white&quot;</span>, I=<span style="color: #483d8b;">&quot;red&quot;</span>, R=<span style="color: #483d8b;">&quot;green&quot;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Generate the graph and the layout</span>
graph, xs, ys = Graph.<span style="color: black;">GRG</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">100</span>, <span style="color: #ff4500;">0.2</span>, return_coordinates=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
layout = Layout<span style="color: black;">&#40;</span><span style="color: #008000;">zip</span><span style="color: black;">&#40;</span>xs, ys<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Set up the initial state of the individuals</span>
graph.<span style="color: black;">vs</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;state&quot;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;S&quot;</span><span style="color: black;">&#93;</span> * graph.<span style="color: black;">vcount</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> vertex <span style="color: #ff7700;font-weight:bold;">in</span> sample<span style="color: black;">&#40;</span>graph.<span style="color: black;">vs</span>, initial_outbreak_size<span style="color: black;">&#41;</span>:
    graph.<span style="color: black;">vs</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;state&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;I&quot;</span></pre>

<p>The above code generates a geometric random graph with 100 vertices, lays them out on the 2D plane according to the original coordinates used in the generation process, then puts all the individuals into the susceptible (S) state save a few who will be infected already (I). Now we can move on to setting up the encoder and rendering the animation:</p>

<pre class="python">encoder = MEncoderVideoEncoder<span style="color: black;">&#40;</span>bbox=<span style="color: black;">&#40;</span><span style="color: #ff4500;">600</span>, <span style="color: #ff4500;">600</span><span style="color: black;">&#41;</span>, fps=<span style="color: #ff4500;">5</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
    <span style="color: #808080; font-style: italic;"># Create a plot of the current state and add it to the encoder</span>
    colors = <span style="color: black;">&#91;</span>colormap<span style="color: black;">&#91;</span>state<span style="color: black;">&#93;</span> <span style="color: #ff7700;font-weight:bold;">for</span> state <span style="color: #ff7700;font-weight:bold;">in</span> graph.<span style="color: black;">vs</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;state&quot;</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span>
    encoder.<span style="color: black;">add</span><span style="color: black;">&#40;</span>graph, layout=layout, vertex_color=colors,
                vertex_label=graph.<span style="color: black;">vs</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;state&quot;</span><span style="color: black;">&#93;</span>, margin=<span style="color: #ff4500;">20</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># First, the infected individuals try to infect their neighbors        </span>
    infected = graph.<span style="color: black;">vs</span>.<span style="color: #dc143c;">select</span><span style="color: black;">&#40;</span>state=<span style="color: #483d8b;">&quot;I&quot;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> vertex <span style="color: #ff7700;font-weight:bold;">in</span> infected:
        <span style="color: #ff7700;font-weight:bold;">for</span> idx <span style="color: #ff7700;font-weight:bold;">in</span> graph.<span style="color: black;">neighbors</span><span style="color: black;">&#40;</span>vertex.<span style="color: black;">index</span><span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">if</span> graph.<span style="color: black;">vs</span><span style="color: black;">&#91;</span>idx<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;state&quot;</span><span style="color: black;">&#93;</span> == <span style="color: #483d8b;">&quot;S&quot;</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #dc143c;">random</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> &lt; beta:
                graph.<span style="color: black;">vs</span><span style="color: black;">&#91;</span>idx<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;state&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;I&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Second, the infected individuals try to recover</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> vertex <span style="color: #ff7700;font-weight:bold;">in</span> infected:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">random</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> &lt; gamma:
            vertex<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;state&quot;</span><span style="color: black;">&#93;</span> = <span style="color: #483d8b;">&quot;R&quot;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;"># Okay, are there any infected people left?</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> infected:
        <span style="color: #ff7700;font-weight:bold;">break</span>
encoder.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;demo_epidemic.avi&quot;</span><span style="color: black;">&#41;</span></pre>

<p>Note that it takes a relatively short time until the infection spreads to almost the whole network, and how it takes much longer for the last infected nodes to recover, even though the spreading probability is smaller than the recovery probability. This is because a node almost always has multiple chances to infect in a single time step (since it tries all its susceptible neighbors), while it has only one chance to recover. See the full result here:</p>

<div align="center"><object width="400" height="400"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=14923361&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=14923361&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="400"></embed></object><br /></div>

<h2>Concluding remarks</h2>

<p>The whole video encoder API is unstable yet. It might eventually get included in the Python interface of igraph, but I'd love to hear your comments first. Can it be made any simpler than this? Shall I add support for <a href="http://www.ffmpeg.org">FFMpeg</a> or <a href="http://pymedia.org">PyMedia</a>? Are there some features missing? Would you like to see it as part of the Python interface, or shall I leave it separate? Feel free to comment or send me an email.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixdegrees.hu/blog/2010/09/creating-animations-in-igraph/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Plotting igraph graphs in matplotlib</title>
		<link>http://sixdegrees.hu/blog/2010/07/plotting-igraph-graphs-in-matplotlib/</link>
		<comments>http://sixdegrees.hu/blog/2010/07/plotting-igraph-graphs-in-matplotlib/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 20:10:12 +0000</pubDate>
		<dc:creator>Tamás</dc:creator>
				<category><![CDATA[English]]></category>

		<guid isPermaLink="false">http://sixdegrees.hu/?p=144</guid>
		<description><![CDATA[An interesting question popped up on the igraph-help mailing list the other day: someone asked whether it is possible to plot an igraph graph on top of a Matplotlib plot. Matplotlib is definitely the de facto 2D plotting library in Python, so I thought it would be nice if there would be a way to [...]]]></description>
			<content:encoded><![CDATA[<p>An interesting question popped up on the <a href="http://lists.nongnu.org/mailman/listinfo/igraph-help">igraph-help</a> mailing list the other day: someone asked whether it is possible to plot an <a href="http://igraph.sourceforge.net">igraph</a> graph on top of a <a href="http://matplotlib.sourceforge.net">Matplotlib</a> plot. Matplotlib is definitely the <em>de facto</em> 2D plotting library in Python, so I thought it would be nice if there would be a way to wire them together somehow.</p>

<p><a href="http://igraph.sourceforge.net">igraph</a> uses <a href="http://www.cairographics.org">Cairo</a> as a plotting backend. If you dive into the plotting internals of <a href="http://igraph.sourceforge.net">igraph</a>, you will see that every plottable object has a method called <code>__plot__</code>, which is called when the object has to be plotted on a Cairo surface. (The plotting code has undergone major refactoring in the last few weeks, therefore things are likely to change in igraph 0.6, but the <code>__plot__</code> method will be kept for sake of compatibility anyway). For instance, <code>Graph.__plot__</code> is called with a Cairo context <code>ctx</code>, a bounding box <code>bbox</code> in which the graph has to be drawn, and a <code>palette</code> that is used occasionally to resolve numeric color indices to RGB triplets. This means that I would only have to extract the Cairo context that Matplotlib uses to draw the figures and pass it on to <code>Graph.__plot__</code> somehow.</p>

<p><span id="more-144"></span></p>

<p>Matplotlib, on the other hand, can work not only on Cairo contexts but all sorts of different backends (e.g., it can render plots on a GTK surface using Agg, or on the surface of a Qt window and so on). The difference between backends is abstracted away by the concept of <em>renderers</em>, which offer a common interface to high-level Matplotlib entities (<em>artists</em> in Matplotlib lingo). When a curve is plotted in <a href="http://matplotlib.sourceforge.net">matplotlib</a>, the curve object itself does not talk to the backend, it talks to the renderer instead. If we want to hijack the plotting process of Matplotlib, we have to implement our own artist that draws <a href="http://igraph.sourceforge.net">igraph</a> graphs and inject it into a Matplotlib figure.</p>

<p>Matplotlib artists are abstract classes that require subclasses to implement a method called <code>draw</code>, which expects a renderer and takes care of drawing the artist itself using the renderer. When we put all this together, it turns out that it is remarkably simple to implement an artist for <a href="http://igraph.sourceforge.net">igraph</a> graphs:</p>

<pre class="python"><span style="color: #ff7700;font-weight:bold;">from</span> matplotlib.<span style="color: black;">artist</span> <span style="color: #ff7700;font-weight:bold;">import</span> Artist
<span style="color: #ff7700;font-weight:bold;">from</span> igraph <span style="color: #ff7700;font-weight:bold;">import</span> BoundingBox, Graph, palettes
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> GraphArtist<span style="color: black;">&#40;</span>Artist<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, graph, bbox, palette=<span style="color: #008000;">None</span>, *args, **kwds<span style="color: black;">&#41;</span>:
        <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;Constructs a graph artist that draws the given graph
        within the given bounding box.&quot;</span><span style="color: #483d8b;">&quot;&quot;</span>
        Artist.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">graph</span> = graph
        <span style="color: #008000;">self</span>.<span style="color: black;">palette</span> = palette <span style="color: #ff7700;font-weight:bold;">or</span> palettes<span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;gray&quot;</span><span style="color: black;">&#93;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">bbox</span> = BoundingBox<span style="color: black;">&#40;</span>bbox<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">args</span>, <span style="color: #008000;">self</span>.<span style="color: black;">kwds</span> = args, kwds
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> draw<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, renderer<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">from</span> matplotlib.<span style="color: black;">backends</span>.<span style="color: black;">backend_cairo</span> <span style="color: #ff7700;font-weight:bold;">import</span> RendererCairo
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>renderer, RendererCairo<span style="color: black;">&#41;</span>:
            <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">TypeError</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;backend not supported&quot;</span><span style="color: black;">&#41;</span>
        ctx = renderer.<span style="color: #dc143c;">gc</span>.<span style="color: black;">ctx</span> <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">hasattr</span><span style="color: black;">&#40;</span>renderer, <span style="color: #483d8b;">&quot;gc&quot;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">else</span> renderer.<span style="color: black;">ctx</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">graph</span>.__plot__<span style="color: black;">&#40;</span>ctx, <span style="color: #008000;">self</span>.<span style="color: black;">bbox</span>, <span style="color: #008000;">self</span>.<span style="color: black;">palette</span>, *<span style="color: #008000;">self</span>.<span style="color: black;">args</span>, **<span style="color: #008000;">self</span>.<span style="color: black;">kwds</span><span style="color: black;">&#41;</span></pre>

<p>The usage of <code>GraphArtist</code> is pretty simple. First, we have to make sure that Matplotlib uses the Cairo plotting backend (as this is the only one supported by <code>GraphArtist</code>):</p>

<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> matplotlib
matplotlib.<span style="color: black;">use</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;cairo.pdf&quot;</span><span style="color: black;">&#41;</span></pre>

<p>After that, we can move on to creating a figure with a 2D plot:</p>

<pre class="python"><span style="color: #ff7700;font-weight:bold;">import</span> matplotlib.<span style="color: black;">pyplot</span> as pyplot
figure = pyplot.<span style="color: black;">figure</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
axes = figure.<span style="color: black;">add_subplot</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">111</span><span style="color: black;">&#41;</span>
xs = <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">200</span><span style="color: black;">&#41;</span>
ys = <span style="color: black;">&#91;</span><span style="color: #dc143c;">math</span>.<span style="color: black;">sin</span><span style="color: black;">&#40;</span>x/<span style="color: #ff4500;">10</span>.<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> xs<span style="color: black;">&#93;</span>
axes.<span style="color: black;">plot</span><span style="color: black;">&#40;</span>xs, ys<span style="color: black;">&#41;</span></pre>

<p>Now, we have to construct a <code>GraphArtist</code> for our graph to be plotted (say, <code>graph</code>) and add it to the figure. The trick here is that we have to add the artist to the <em>axes</em> and not the <em>figure</em>, since the axes of a Matplotlib figure are always drawn on top of any other artist added to the figure, and we want to ensure that our graph appears on top of the plot itself:</p>

<pre class="python">graph_artist = GraphArtist<span style="color: black;">&#40;</span>graph, <span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span>, <span style="color: #ff4500;">10</span>, <span style="color: #ff4500;">150</span>, <span style="color: #ff4500;">150</span><span style="color: black;">&#41;</span>, layout=<span style="color: #483d8b;">&quot;kk&quot;</span><span style="color: black;">&#41;</span>
graph_artist.<span style="color: black;">set_zorder</span><span style="color: black;">&#40;</span><span style="color: #008000;">float</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'inf'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
axes.<span style="color: black;">artists</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>graph_artist<span style="color: black;">&#41;</span>
fig.<span style="color: black;">savefig</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;test.pdf&quot;</span><span style="color: black;">&#41;</span></pre>

<p>The first line constructs the artist itself, using a bounding box spanning from (10, 10) to (150, 150). The remaining positional and keyword arguments (such as <code>layout="kk"</code>) will be passed on intact to <code>Graph.__plot__</code>. The second line sets the Z-order of the artist to infinity to ensure that it is drawn on top of any curves that were added to the axes before. Finally, the artist is appended to the list of artists managed by <code>axes</code> and the figure is saved to the given PDF file.</p>

<p><a href="/files/code/2010-07/igraph_mpl.py">Click here</a> to download the source code.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixdegrees.hu/blog/2010/07/plotting-igraph-graphs-in-matplotlib/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speeding up maximal clique search in igraph</title>
		<link>http://sixdegrees.hu/blog/2010/03/speeding-up-maximal-clique-search-in-igraph/</link>
		<comments>http://sixdegrees.hu/blog/2010/03/speeding-up-maximal-clique-search-in-igraph/#comments</comments>
		<pubDate>Sun, 28 Mar 2010 19:20:25 +0000</pubDate>
		<dc:creator>Tamás</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://sixdegrees.hu/?p=121</guid>
		<description><![CDATA[Maximal clique finding has been part of igraph for quite a long time (the first commit of this algorithm was well back in 2007 IIRC), but out of sheer laziness I simply implemented it as a search for maximal independent vertex sets on the complementary graph. As Drew Conway pointed it out in one of [...]]]></description>
			<content:encoded><![CDATA[<p>Maximal clique finding has been part of <a href="http://igraph.sourceforge.net">igraph</a> for quite a long time (the first commit of this algorithm was well back in 2007 IIRC), but out of sheer laziness I simply implemented it as a search for maximal independent vertex sets on the complementary graph. As <a href="http://www.drewconway.com">Drew Conway</a> pointed it out in <a href="http://www.drewconway.com/zia/?p=1221">one of his SNA talks</a>, this is a terribly slow approach for sparse graphs as it takes ages to build the complementary graph. The implementation of the <a href="http://en.wikipedia.org/wiki/Bron–Kerbosch_algorithm">Bron-Kerbosch algorithm</a> in last September (see <a href="http://bazaar.launchpad.net/%7Eigraph/igraph/0.6-main/revision/1653">this commit</a> in Launchpad) speeded up things big time, and at that point I thought this is pretty much as good as it gets - but I was wrong. There was still plenty of space for improvement.
<span id="more-121"></span>
Inside the Bron-Kerbosch algorithm, intersections between sorted sets are calculated all the time. igraph used the naïve set intersection algorithm in this case, which is O(<i>n</i>+<i>m</i>) where <i>n</i> and <i>m</i> are the sizes of the larger and smaller sets, respectively. Linear complexity is not bad, but there are better solutions, such as the set intersection algorithm of <a href="http://www.dcc.uchile.cl/~rbaeza/">Ricardo Baeza-Yates</a>, which attains log-log complexity at the expense of requiring random access to the set elements. This does not pose a limitation as the sets in question in igraph are randomly accessible, so I thought I'll give it a try. Basically, the set intersection algorithm of Baeza-Yates goes as follows:</p>

<ol>
<li>Pick the median element A of the smaller set.</li>
<li>Search for the insertion point B of this element in the larger set.</li>
<li>If A equals B, add A to the result set.</li>
<li>Repeat the previous three steps for non-empty subsets to the left and right of A and B.</li>
</ol>

<p>A big kudos goes to <a href="http://fawx.com/2009/10/26/an-ode-to-set-intersection-part-1/">Erik Frey</a> for drawing my attention to the above procedure. According to his measurements, the algorithm works even better if one uses interpolation search instead of binary search, but it did not yield performance improvements compared to the binary search case in igraph, so I decided to go with binary search only. Some quick measurements on geometric random graphs with an increasing number of vertices (while keeping the density constant) show that indeed the improvements in the set intersection algorithm speeded up the maximal clique search significantly (red line shows the old Bron-Kerbosch implementation with linear set intersection, blue line shows the new one):</p>

<p><img src="http://chart.apis.google.com/chart?chtt=Calculation+time+(seconds)&chts=000000,18&chs=600x400&chf=bg,s,ffffff|c,lg,90,ffffff,1,eeeeee,0&chxt=x,y,x&chxl=0:|0.00|50,000|100,000|1:|0.00|6.18|12.35|18.53|24.71|2:|Number+of+vertices&cht=lxy&chd=t:1.00,5.00,10.00,20.00,50.00,100.00|0.04,0.44,1.41,4.66,25.90,100.00|0.00,5.00,10.00,20.00,30.00,40.00,50.00,75.00,100.00|0.00,0.32,0.75,1.89,3.50,5.47,7.44,14.80,23.83&chdl=Old+|New&chco=ff0000,0000ff&chm=d,ff0000,0,0.0,10|d,ff0000,0,1.0,10|d,ff0000,0,2.0,10|d,ff0000,0,3.0,10|d,ff0000,0,4.0,10|d,ff0000,0,5.0,10|d,0000ff,1,0.0,10|d,0000ff,1,1.0,10|d,0000ff,1,2.0,10|d,0000ff,1,3.0,10|d,0000ff,1,4.0,10|d,0000ff,1,5.0,10|d,0000ff,1,6.0,10|d,0000ff,1,7.0,10|d,0000ff,1,8.0,10&chxp=2,50" alt="Chart showing calculation times" width="600" height="400" /></p>

<p>This will be included in the next major release of <a href="http://igraph.sourceforge.net">igraph</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixdegrees.hu/blog/2010/03/speeding-up-maximal-clique-search-in-igraph/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>64-bit issues on Snow Leopard</title>
		<link>http://sixdegrees.hu/blog/2009/09/64-bit-issues-on-snow-leopard/</link>
		<comments>http://sixdegrees.hu/blog/2009/09/64-bit-issues-on-snow-leopard/#comments</comments>
		<pubDate>Mon, 28 Sep 2009 19:12:04 +0000</pubDate>
		<dc:creator>Tamás</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://sixdegrees.hu/?p=117</guid>
		<description><![CDATA[It looks like the change from 32-bit OS X Leopard to 64-bit OS X Snow Leopard won't be as smooth as I had originally expected. Although I have to admit that the OS X developers did a very good job in making the change as smooth as possible for ordinary users (insert the DVD, start [...]]]></description>
			<content:encoded><![CDATA[<p>It looks like the change from 32-bit OS X Leopard to 64-bit OS X Snow Leopard won't be as smooth as I had originally expected. Although I have to admit that the OS X developers did a very good job in making the change as smooth as possible for ordinary users (insert the DVD, start the installer, grab a coffee, wait, reboot, rejoice), but from the developers' point of view, there are a few unexpected glitches.</p>

<p>The first is that Python was upgraded to a 64-bit version of the 2.6.1 release. This means that all the Python extensions I used that have parts written in C have to be recompiled from scratch for the 64-bit version. Not a big deal - as long as you don't use any extensions that depend on 32-bit third party libraries. One example is Syck, a <a href="http://www.yaml.org">YAML</a> parser written in C. I used to install Syck from <a href="http://www.finkproject.org">Fink</a>, but Fink only supplies a 32-bit version, not a 64-bit one, so for the time being I am stuck with a 32-bit version... which means that I have to run Python in 32-bit mode. Luckily, there are at least two ways to switch back to the 32-bit implementation. One is to change the corresponding setting permanently:</p>

<pre>
$ defaults write com.apple.versioner.python Prefer-32-Bit -bool yes
</pre>

<p>The other possibility is an environment variable called <code>VERSIONER_PYTHON_PREFER_32_BIT</code> which should be set to either <code>yes</code> or <code>no</code>.</p>

<p>Another catch lies in <code>gcc</code> which also produces 64-bit code by default. This means that it won't be able to link to a static or dynamic library compiled earlier with Leopard in 32-bit mode; either the library has to be recompiled or <code>gcc</code> should be instructed to produce 32-bit code:</p>

<pre>
$ gcc -arch i386 <i>...the rest is the same</i>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://sixdegrees.hu/blog/2009/09/64-bit-issues-on-snow-leopard/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Coloured grep output</title>
		<link>http://sixdegrees.hu/blog/2009/08/coloured-grep-output/</link>
		<comments>http://sixdegrees.hu/blog/2009/08/coloured-grep-output/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 11:24:32 +0000</pubDate>
		<dc:creator>Tamás</dc:creator>
				<category><![CDATA[Asides]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[grep]]></category>
		<category><![CDATA[os x]]></category>

		<guid isPermaLink="false">http://sixdegrees.hu/2009/08/coloured-grep-output/</guid>
		<description><![CDATA[$ export GREP_OPTIONS='--color=auto' The best thing since sliced bread. (Put it into your .profile of course). The highlight colour can also be adjusted by tweaking GREP_COLOR using standard SGR ANSI codes - my personal choice is export GREP_COLOR='30;43' which gives an appearance resembling a yellow highlighter pen.]]></description>
			<content:encoded><![CDATA[<p><code>$ export GREP_OPTIONS='--color=auto'</code>
The best thing since sliced bread. (Put it into your <code>.profile</code> of course).
The highlight colour can also be adjusted by tweaking <code>GREP_COLOR</code> using standard SGR ANSI codes - my personal choice is <code>export GREP_COLOR='30;43'</code> which gives an appearance resembling a yellow highlighter pen.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixdegrees.hu/blog/2009/08/coloured-grep-output/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PithHelmet with Safari 3.1 and later</title>
		<link>http://sixdegrees.hu/blog/2008/04/pithhelmet-with-safari-31-and-later/</link>
		<comments>http://sixdegrees.hu/blog/2008/04/pithhelmet-with-safari-31-and-later/#comments</comments>
		<pubDate>Fri, 18 Apr 2008 13:30:18 +0000</pubDate>
		<dc:creator>Tamás</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[pithhelmet]]></category>
		<category><![CDATA[safari]]></category>

		<guid isPermaLink="false">http://sixdegrees.hu/index.php/archives/2008/04/18/pithhelmet-with-safari-31-and-later</guid>
		<description><![CDATA[PithHelmet is a great software for those who are at least as annoyed by advertisements and silly moving Flash banners and such as me. However, it does not work with Safari 3.1 and above at the time I write this: Safari claims that this plugin is untested and refuses to load it. The good thing [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.culater.net/software/PithHelmet/PithHelmet.php">PithHelmet</a> is a great software for those who are at least as annoyed by advertisements and silly moving Flash banners and such as me. However, it does not work with Safari 3.1 and above at the time I write this: Safari claims that this plugin is untested and refuses to load it. The good thing is that changing a single byte in the appropriate config file is enough to deceive Safari and make it load PithHelmet again. The steps to salvation are as follows:
<span id="more-79"></span>
<ol>
<li>Launch Safari and checks its "About" box in the "Safari" menu. Look for the bundle number in parentheses after the version number (mine reads 5525.18 now).</li>
<li>Close Safari.</li>
<li>Open <code>/Library/Application Support/SIMBL/Plugins/PithHelmet.bundle/Contents/Info.plist</code> in the Property List Editor and search for <code>/Root/SIMBLTargetApplications/0/MaxBundleVersion</code>. Set its value to the bundle number of your Safari (the part before the dot, so it is 5525 in my case).</li>
<li>Relauch Safari and everything should work as expected.</li>
</ol>

</p><p>Note that this is a really ugly hack, and it works only as long as there are no incompatible changes between different versions of Safari that would prevent PithHelmet from operating properly. It looks like it works with Safari 3.1, but there is no warranty that it will work with later versions as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixdegrees.hu/blog/2008/04/pithhelmet-with-safari-31-and-later/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Leopard wtf #1 megoldva</title>
		<link>http://sixdegrees.hu/blog/2008/02/leopard-wtf-1-megoldva/</link>
		<comments>http://sixdegrees.hu/blog/2008/02/leopard-wtf-1-megoldva/#comments</comments>
		<pubDate>Fri, 01 Feb 2008 13:55:17 +0000</pubDate>
		<dc:creator>Tamás</dc:creator>
				<category><![CDATA[Hungarian]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[ukelele]]></category>
		<category><![CDATA[word]]></category>

		<guid isPermaLink="false">http://sixdegrees.hu/index.php/archives/2008/02/01/leopard-wtf-1-megoldva</guid>
		<description><![CDATA[Amint már írtam régebben, van az OS X Leopardnak és az Office 2008-nak egy kis lerendeznivaló vitája egymással. Nevezetesen: magyar kiosztást használva a Word 2008 kurzora nemes egyszerűséggel felfelé mozog, ha leütöm a hosszú ó betűt, elég nehézkessé téve így bármiféle magyar dokumentum írását (hosszú ó betű clipboardra TextEdit-ből, majd paste-elés Wordben, feltéve, ha közben [...]]]></description>
			<content:encoded><![CDATA[<p>Amint már <a href="http://sixdegrees.hu/index.php/archives/2007/11/27/leopard-wtf-1">írtam régebben</a>, van az OS X Leopardnak és az Office 2008-nak egy kis lerendeznivaló vitája egymással. Nevezetesen: magyar kiosztást használva a Word 2008 kurzora nemes egyszerűséggel felfelé mozog, ha leütöm a hosszú ó betűt, elég nehézkessé téve így bármiféle magyar dokumentum írását (hosszú ó betű clipboardra TextEdit-ből, majd paste-elés Wordben, feltéve, ha közben másra nem használtam a clipboardot). A jó hír az, hogy <a href="http://gaba.lenard.hu/2008/01/02/hungarian-prg-billentyuzetkiosztas-mac-os-x-ala/">Gaba Hungarian-PRG kiosztása</a> segítségével a probléma orvosolható. Az egyetlen zavaró tényező az maradt, hogy Gaba kiosztása visszarendezi az Y-t és a Z-t az angol billentyűzeten megszokott helyére, értelmetlenné téve ezzel a magyar billentyűzet megszokásával töltött hosszú éveket ;) Így hát fogtam a kiosztást, <a href="http://www.macupdate.com/info.php/id/14495">Ukelele</a> segítségével megcseréltem ismét a fentebb említett két billentyűt, és csodák csodája, működik Word-ben is rendesen a hosszú ó. Öröm és boldogság.</p>

<div class="download"><a href="http://sixdegrees.hu/wp-content/plugins/DownloadCounter/download.php?id=8">Hungarian-PRG QWERTZ kiosztás letöltése</a></div>

<p><span id="more-78"></span></p>

<p>Mellesleg van még egy alternatíva, a <a href="http://members.chello.hu/kozak.oliver/hungarianpro/index.html">Hungarian Pro</a> kiosztás. Ezzel annyi a probléma, hogy a Caps Lock gombot "elhasználja" az Unicode és a Central European karakterkódolás közötti váltásra. Mivel én szinte kizárólag Unicode-ban dolgozom, viszont a Caps Lock-ra szükségem van, ez a megoldás jobbnak látszott (arról nem is beszélve, hogy a PRG kiosztást Gaba eleve programozóknak szánta).</p>

<h3>Telepítési instrukciók</h3>

<ol>
<li>Töltsd le a fenti .dmg fájlt és nyisd meg Finder-ben</li>
<li>A .dmg-ben lévő két fájlt másold be a <code>/Library/Keyboard Layouts</code> könyvtárba. Ha csak a saját felhasználód számára szeretnéd elérhetővé tenni, akkor elég, ha a home-odon belül lévő <code>Library/Keyboard Layouts</code> könyvtárba másolod.</li>
<li><b>Jelentkezz ki és jelentkezz be újra!</b> Ez a lépés fontos, enélkül a lépés nélkül nálam a billentyűzetkiosztás kiválasztásakor semmilyen billentyűleütésre nem reagált az OS X, viszont gyönyörűen elkezdett strandlabdázni az az alkalmazás, amelyben gépeltem.</li>
<li>A System Preferences-ben az International / Input Menu alatt keresd meg a kiosztást és válaszd ki.</li>
</ol>

<p>Hibajelzéseket és hasonlóakat kommentekben szívesen fogadok.</p>

<h3>Köszönetnyilvánítás</h3>

<p>Nagy köszönet <a href="http://gaba.lenard.hu">Gabának</a>, amiért közzétette a Hungarian-PRG kiosztást, enélkül valószínűleg soha nem jutott volna eszembe, hogy itt keressem a hibát.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixdegrees.hu/blog/2008/02/leopard-wtf-1-megoldva/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Add Samba printers in OS X Leopard</title>
		<link>http://sixdegrees.hu/blog/2008/02/add-samba-printers-in-os-x-leopard/</link>
		<comments>http://sixdegrees.hu/blog/2008/02/add-samba-printers-in-os-x-leopard/#comments</comments>
		<pubDate>Fri, 01 Feb 2008 12:54:30 +0000</pubDate>
		<dc:creator>Tamás</dc:creator>
				<category><![CDATA[Asides]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[cups]]></category>
		<category><![CDATA[os x]]></category>
		<category><![CDATA[printing]]></category>
		<category><![CDATA[samba]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://sixdegrees.hu/index.php/archives/2008/02/01/add-samba-printers-in-os-x-leopard</guid>
		<description><![CDATA[By removing/hiding the Advanced Options panel of the Add Printer dialog, Apple posed me a challenge when I tried to install a shared Windows printer used in my department. Basically, the damn thing (or more precisely its server) did not show up among the shares in my workgroup. Luckily, there's a full-fledged CUPS (Common Unix [...]]]></description>
			<content:encoded><![CDATA[<p>By removing/hiding the Advanced Options panel of the Add Printer dialog, Apple posed me a challenge when I tried to install a shared Windows printer used in my department. Basically, the damn thing (or more precisely its server) did not show up among the shares in my workgroup. Luckily, there's a full-fledged CUPS (Common Unix Printing System) deep beneath, so I succeeded by typing <code>localhost:631</code> in Safari to reach the CUPS admin area where I was able to add it manually. Another possibility is right-clicking on the toolbar of the Add Printer dialog box and add the Advanced button - it takes a while until it initializes, but after that, it provides almost the same functionality as the CUPS admin area.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixdegrees.hu/blog/2008/02/add-samba-printers-in-os-x-leopard/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

