<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4005848446363811858</id><updated>2012-03-02T13:55:48.882+01:00</updated><category term='fub'/><category term='Python'/><category term='KDE'/><category term='publication'/><category term='network'/><category term='vim'/><category term='shell'/><category term='talk'/><category term='Debian'/><category term='LaTeX'/><category term='C'/><title type='text'>Science, Engineering, Research</title><subtitle type='html'>My personal information dump</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>37</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-4331939000771682629</id><published>2012-03-02T13:53:00.000+01:00</published><updated>2012-03-02T13:55:48.894+01:00</updated><title type='text'>Brute-Force Sudoku Solver</title><content type='html'>This post has a backstory that I do not want to discuss (in short: I am stupid!) but I had to write a Sudoku solver. Here is a backtracking solver that applies a brute-force approach. It does only create a 9x9 Sudoku board as example and can also only solve 9x9 boards but you can easily extend it to arbitrary sizes. This is not very nice code but it works and solves the board in about 2-3 seconds.&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;#!/usr/bin/env python&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;# -*- coding: utf-8 -*-&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import sys&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import pylab&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;import numpy as np&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;from collections import Counter&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;def initialize_board(board):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; '''&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; example board from wikipedia page&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; '''&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[0][0] = 5&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[0][1] = 3&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[1][0] = 6&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[2][1] = 9&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[2][2] = 8&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[0][4] = 7&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[1][3] = 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[1][4] = 9&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[1][5] = 5&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[2][7] = 6&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[3][0] = 8&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[4][0] = 4&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[5][0] = 7&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[3][4] = 6&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[4][3] = 8&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[4][5] = 3&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[5][4] = 2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[3][8] = 3&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[4][8] = 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[5][8] = 6&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[6][1] = 6&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[7][3] = 4&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[7][4] = 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[7][5] = 9&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[8][4] = 8&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[6][6] = 2&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[6][7] = 8&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[7][8] = 5&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[8][7] = 7&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[8][8] = 9&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return board&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;def check_rows_columns(board):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for i in range(board.shape[0]):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; row = data = board[i]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; column = board.transpose()[i]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dups_rows = [1 for key, value in Counter(row).iteritems() if key != 0.0 and value &amp;gt; 1]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dups_columns = [1 for key, value in Counter(column).iteritems() if key != 0.0 and value &amp;gt; 1]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if len(dups_rows) or len(dups_columns):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return False&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return True&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;def check_sub(sub):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dups = [1 for key, value in Counter(pylab.flatten(sub)).iteritems() if key != 0.0 and value &amp;gt; 1]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if len(dups):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return False&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return True&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;def check_subs(board):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for row in xrange(3):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for column in xrange(3):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sub = board[row*3:(row+1)*3, column*3:(column+1)*3]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if not check_sub(sub):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return False&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return True&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;def check_board(board):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return check_rows_columns(board) and check_subs(board)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;def create_board():&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board = np.zeros((9, 9))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board = initialize_board(board)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return board&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;def solve_board(board, pos=0):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if pos &amp;gt;= 9*9:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return True&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if board[pos%9][pos/9] &amp;gt; 0:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return solve_board(board, pos+1)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for i in xrange(1, 10):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[pos%9][pos/9] = i&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if check_board(board) and solve_board(board, pos+1):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return True&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board[pos%9][pos/9] = 0&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return False&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;def main():&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; board = create_board()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if not check_board(board):&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print 'ERROR: initial board violates rules'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sys.exit(1)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; solvable = solve_board(board)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if not solvable:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print 'ERROR: board not solvable'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print board&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;if __name__ == '__main__':&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; main()&lt;/span&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-4331939000771682629?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/4331939000771682629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2012/03/brute-force-sudoku-solver.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/4331939000771682629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/4331939000771682629'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2012/03/brute-force-sudoku-solver.html' title='Brute-Force Sudoku Solver'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-721046790703673298</id><published>2012-03-01T10:13:00.006+01:00</published><updated>2012-03-01T10:13:45.514+01:00</updated><title type='text'>Matplotlib: Draw Ellipses</title><content type='html'>Just a concise example:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;#!/usr/bin/env python&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;# -*- coding: utf-8 -*-&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;from pylab import *&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;from matplotlib.patches import Polygon, Ellipse&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;from matplotlib.collections import PatchCollection&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;# example data&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;data = [(0.1, 0.1, 0.15, 0.07), (0.1, 0.4, 0.5, 0.1), (0.6, 0.5, 0.25, 0.17)]&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;fig = figure()&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ax = gca()&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ellipses = list()&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;for x, y, width, height in data:&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ellipses.append(Ellipse((x, y), width, height, edgecolor='black', facecolor='red', alpha=0.5))&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ax.add_collection(PatchCollection(ellipses, match_original=True))&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;fig.savefig('/tmp/ellipse_example.pdf')&lt;/span&gt;&lt;/blockquote&gt;Ellipses are a nice way to visualize confidence intervals on two axis for your data instead of using error bars for the representation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-721046790703673298?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/721046790703673298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2012/03/matplotlib-draw-ellipses.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/721046790703673298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/721046790703673298'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2012/03/matplotlib-draw-ellipses.html' title='Matplotlib: Draw Ellipses'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-7504777465140006516</id><published>2012-02-26T17:46:00.002+01:00</published><updated>2012-02-26T20:08:42.842+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Starting X11 Applications over SSH AND showing the GUI on the remote host</title><content type='html'>Most people know that you can start an application on a remote computer and have the GUI tunneled/forwarded over an SSH session by connecting as follows:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ssh -X ${USER}@${HOST}&lt;/span&gt;&lt;/blockquote&gt;(Of course you have to set the USER and HOST variables appropriately.) &lt;br /&gt;&lt;br /&gt;But how do you actually start an application after you have logged in over SSH and display the GUI on the remote machine's Xserver? This can be achieved quite simple. You have to set the XAUTHORITY variable to the file that contains the "magic cookie" as follows:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;export XAUTHORITY=/home/$USER/.Xauthority&lt;/span&gt;&lt;/blockquote&gt;&amp;nbsp;Subsequently, set the DISPLAY variable (usually to ":0") as follows:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;export DISPLAY=':0'&lt;/span&gt;&lt;/blockquote&gt;That's it! Keep in mind that if you want to disconnect after starting the application, you should probably use &lt;a href="http://www.gnu.org/software/screen/" target="_blank"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;screen&lt;/span&gt;&lt;/a&gt;, &lt;a href="http://tmux.sourceforge.net/" target="_blank"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;tmux&lt;/span&gt;&lt;/a&gt;, or &lt;a href="http://en.wikipedia.org/wiki/Nohup" target="_blank"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;nohup&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Depending on the application that you have started, you may actually be able to control it on the shell that you logged into over SSH, e.g., you can still control &lt;a href="http://www.mplayerhq.hu/design7/news.html" target="_blank"&gt;mplayer&lt;/a&gt; when started on a remote host.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-7504777465140006516?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/7504777465140006516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2012/02/starting-x11-applications-over-ssh.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/7504777465140006516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/7504777465140006516'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2012/02/starting-x11-applications-over-ssh.html' title='Starting X11 Applications over SSH AND showing the GUI on the remote host'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-6380450106558373625</id><published>2012-02-21T13:06:00.000+01:00</published><updated>2012-02-26T20:09:08.929+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Shell Script Programming in Bash</title><content type='html'>Shell script is an easy way to automate common tasks but shell script certainly has its oddities and pitfalls.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://mywiki.wooledge.org/BashPitfalls" target="_blank"&gt;Greg's Wiki&lt;/a&gt; provides a good overview of common Bash pitfalls.  Freddy Vulto has additionally published a summary of Bash error handling in &lt;a href="http://fvue.nl/wiki/Bash:_Error_handling" target="_blank"&gt;his wiki&lt;/a&gt;. Both sources are excellent reads for any shell script developer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-6380450106558373625?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/6380450106558373625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2012/02/shell-script-programming-in-bash.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/6380450106558373625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/6380450106558373625'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2012/02/shell-script-programming-in-bash.html' title='Shell Script Programming in Bash'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-8686327560249144372</id><published>2012-02-15T22:52:00.000+01:00</published><updated>2012-02-26T20:09:30.279+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><title type='text'>Piercing Holes in NATs</title><content type='html'>In contrast to the 90s when we were still using dial-up connections from a single computer to the Internet over modems, nowadays everyone has a device at home that you may often refer to as router. In fact, this is usually a DSL modem, a cable model, or similar device that is also providing switching and routing functionality.&lt;br /&gt;&lt;br /&gt;By having multiple computers connected to the Internet over a single line, it became necessary to be able to differentiate the connections, e.g., made with browsers from the (internal) computers&amp;nbsp;B&lt;sub&gt;1&lt;/sub&gt;, B&lt;sub&gt;2&lt;/sub&gt;, and B&lt;sub&gt;3&lt;/sub&gt;&amp;nbsp;to the same website (external) A. Thus there are multiple connections that are multiplexed and we need a way to determine if inbound packets from C are destined to B&lt;sub&gt;1&lt;/sub&gt;, B&lt;sub&gt;2&lt;/sub&gt;, or B&lt;sub&gt;3&lt;/sub&gt; that are all addressed by a shared external, routable IP address. The following figure depicts the scenario:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-lYUoa5irgB0/TzWPpGw2-HI/AAAAAAAABG0/ozkVCRt4vok/s1600/nat.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="90" src="http://3.bp.blogspot.com/-lYUoa5irgB0/TzWPpGw2-HI/AAAAAAAABG0/ozkVCRt4vok/s320/nat.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;i&gt;Network Address &amp;nbsp;Translation&lt;/i&gt; (NAT), also sometimes&amp;nbsp;&lt;i&gt;Network Address &amp;nbsp;Port Translation&lt;/i&gt;&amp;nbsp;(NAPT), maps the internal and external tuples for the IP addresses and the port numbers, that we are using for transport layer multiplexing, to each other. Thus your router that incorporates NAT functionality is able to forward the packets if these mappings are learned, e.g., when B&lt;sub&gt;1&lt;/sub&gt; initializes an (outbound) connection to A.&lt;br /&gt;&lt;br /&gt;This approach has an additional benefit: security. If there is not matching mapping because an internal computer has not initialized a connection, inbound packets are simple dropped. Hence NAT devices enable a simple but effective firewall. While this probably has prevented incidents for many non-tech-savvy people, it has a quite&amp;nbsp;unpleasant side effect.&amp;nbsp;Services like VoIP cannot be easily realized, if the two entities that want to communicate are both behind NAT devices. An external entity may act as relay/proxy to enable communication but this way all data has to traverse the relay (security?!?) and a relay has to be known or discovered in the first place.&lt;br /&gt;&lt;br /&gt;The IETF provides an approach to overcome this problem.&amp;nbsp;&lt;i&gt;Session Traversal Utilities for NAT&lt;/i&gt; (STUN) as specified in &lt;a href="https://tools.ietf.org/html/rfc5389" target="_blank"&gt;RFC 5389&lt;/a&gt;&amp;nbsp;is used by the&amp;nbsp;&lt;i&gt;Interactive Connectivity Establishment&lt;/i&gt; (ICE) protocol that itself is defined in &lt;a href="https://tools.ietf.org/html/rfc5245" target="_blank"&gt;RFC 5245&lt;/a&gt;.&amp;nbsp;You find an informative figure that depicts the STUN algorithm which determines the type of NAT that has to be traversed &lt;a href="http://upload.wikimedia.org/wikipedia/commons/6/63/STUN_Algorithm3.svg" target="_blank"&gt;here&lt;/a&gt;. In addition, ICE also supports&amp;nbsp;&lt;i&gt;Traversal Using Relays around NAT&lt;/i&gt; (TURN) as specified in &lt;a href="https://tools.ietf.org/html/rfc5766" target="_blank"&gt;RFC 5766&lt;/a&gt;&amp;nbsp;and &lt;a href="https://tools.ietf.org/html/rfc6156" target="_blank"&gt;RFC 6156&lt;/a&gt; where an external relay is actually used. You can find an ICE implementation in &lt;a href="http://nice.freedesktop.org/wiki/" target="_blank"&gt;libnice&lt;/a&gt;&amp;nbsp;which should be available in most Linux distributions. STUN, TURN, and ICE enable thus communication over NAT devices in a transparent way for most applications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-8686327560249144372?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/8686327560249144372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2012/02/piercing-holes-in-nats.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/8686327560249144372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/8686327560249144372'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2012/02/piercing-holes-in-nats.html' title='Piercing Holes in NATs'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-lYUoa5irgB0/TzWPpGw2-HI/AAAAAAAABG0/ozkVCRt4vok/s72-c/nat.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-1331056041811547630</id><published>2012-02-10T18:25:00.000+01:00</published><updated>2012-02-26T20:09:52.645+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='Debian'/><title type='text'>Data Structures for C Developers</title><content type='html'>Just a brief introduction to a simple solution for a common problem (and also shameless self-advertisement).&lt;br /&gt;&lt;br /&gt;The C standard library offers little to none of the data structures that developers, that are accustomed with higher level programming languages, e.g., Java and C++, will expect when they are faced with C programming. Of course, you find them in the &lt;a href="http://developer.gnome.org/glib/" target="_blank"&gt;GLib&lt;/a&gt; but often you may want to avoid this dependency, especially due to the size of the library.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://uthash.sourceforge.net/" target="_blank"&gt;uthash&lt;/a&gt; has been developed by&amp;nbsp;Troy D. Hanson and offers, despite its name, hash maps, linked lists, arrays, and strings. What makes this solution so interesting is that the data structures are implemented as C preprocessor macros. Thus, you only have to include the provided header files and there are no run-time dependencies. uthash is also available in &lt;a href="http://packages.debian.org/search?lang=de&amp;amp;searchon=names&amp;amp;keywords=uthash" target="_blank"&gt;Debian&lt;/a&gt; and &lt;a href="https://launchpad.net/ubuntu/+source/uthash" target="_blank"&gt;Ubuntu&lt;/a&gt; (and probably other Debian based distributions) as I am the corresponding package maintainer.&lt;br /&gt;&lt;br /&gt;So give the data structures in uthash a chance and don't start to implement them yourself, like many others have. Troy provides a simple but elegant solution that is also adequately documented.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-1331056041811547630?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/1331056041811547630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2012/02/data-structures-for-c-developers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/1331056041811547630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/1331056041811547630'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2012/02/data-structures-for-c-developers.html' title='Data Structures for C Developers'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-7922033936409468583</id><published>2012-02-04T15:00:00.000+01:00</published><updated>2012-02-04T15:00:11.769+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='Debian'/><title type='text'>IEEE 802.1QinQ and VMware</title><content type='html'>The IEEE 802.1Q standard defines virtual LANs, i.e., a way to setup logical/virtual topologies on a physical topology. The frames are extended by an additional VLAN header that is evaluated by the switches. QinQ, Q-in-Q, and double-tagging refer to VLANs that are created within VLANs, i.e., the frames may have multiple VLAN headers (see IEEE 802.1ad).&lt;br /&gt;&lt;br /&gt;I am certainly no expert in VMware's products, but from what I have been told by our technical department, topologies are realized in VMware ESX(i) by VLANs. If you are unlucky as me, when I asked for a bunch of VMs for teaching and experiments, there may not be enough VLAN ids available to create sophisticated network topologies. First of all, the creation of topologies is somehow not easily done in VMware ESX(i) and VLAN ids may be valid for the whole campus/company. As they are limited to 12 bit (some equipment may even support less!) you may have only very few available, if you cannot isolate your experimental network (was off my responsibilities). Thus you may end up with a sufficient number of VMs but that are fully meshed, i.e., each host can reach any other directly.&lt;br /&gt;&lt;br /&gt;QinQ can be a solution for this problem. The VLANs of VMware ESX(i) are transparent for the VMs. We can create virtual interfaces in Linux with &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;vcontrol&lt;/span&gt; that add a specific VLAN header to the frame before it is sent out over another interface. Thus by assigning VLAN ids to specific interfaces on the VMs, you can easily setup any topology you want to&amp;nbsp; study.&lt;br /&gt;&lt;br /&gt;Unfortunately, VMware ESX(i) does not like double-tagged frames and they are quietly dropped by the virtual switches (or somewhere else, does not matter). So how can we enable QinQ despite this miss-behavior? Actually the solution is quite simple. The VLAN header is identified by the ethertype &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;0x&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;8100&lt;/span&gt; in the Ethernet frame. If you change this value, the switches are not able to detect the double-tagged frames anymore as they will not apply any sophisticated detection algorithms if the ethertype is unknown. These algorithms would require too many resources on the switches.&lt;br /&gt;&lt;br /&gt;You can replace the ethertype in several ways but what worked the best for me was actually to replace the value, e.g., in the e1000e NIC's kernel module source code and to rebuild it. You additionally have to disable any VLAN support that may be available in the hardware. If you forget this, the hardware will actually insert the VLAN header with the correct ethertype.&lt;br /&gt;&lt;br /&gt;If you are successful, you will be able to use QinQ depite VMware's "feature". Although this approach violates the corresponding standards, network protocols often have no protection against similar attacks. That is something you always have to consider. An IP datagram may be "disguised" by the ethertype that actually identifies an ARP packet.&lt;br /&gt;&lt;br /&gt;You can basically use most ethertypes to disguise your QinQ frames but I would advise to use 0x885B or 0xx88B6 as they are defined as local experimental ethertypes in IEEE 802: "&lt;i&gt;for public use and vendor-specific protocol development&lt;/i&gt;". This way you should prevent problems due to accidental evaluation of the frames by network hardware that does not know about the proposed solution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-7922033936409468583?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/7922033936409468583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2012/02/ieee-8021qinq-and-vmware.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/7922033936409468583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/7922033936409468583'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2012/02/ieee-8021qinq-and-vmware.html' title='IEEE 802.1QinQ and VMware'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-1234221934171812681</id><published>2012-02-03T11:28:00.001+01:00</published><updated>2012-02-05T13:15:14.916+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='Debian'/><title type='text'>Ethernet Bridging Troubles on VMware</title><content type='html'>Ethernet bridging should be a straight forward task. Usually, computer science students learn about it in the computer networks / telematics lecture and it sounds pretty trivial. Unfortunately this is not always the case. When I tried to extend our &lt;a href="http://www.des-testbed.net/" target="_blank"&gt;testbed&lt;/a&gt; deployment to an external partner by a layer 2 tunnel (Ethernet bridging with OpenVPN), I ran into several problems. Descriptions of these problems can be found on several mailing lists or in forums but I neither found an in detail discussion of the fundamental problem nor a simple solution.&lt;br /&gt;&lt;br /&gt;Lets assume that we have the following network architecture:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-QXmIekOa1vk/TyunNmVzQjI/AAAAAAAABF8/zB536-QjQNk/s1600/architecture.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="128" src="http://2.bp.blogspot.com/-QXmIekOa1vk/TyunNmVzQjI/AAAAAAAABF8/zB536-QjQNk/s320/architecture.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host A&lt;/span&gt; shall be bridged into the LAN where &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host C&lt;/span&gt; resides. &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt; is the tunnel endpoint and connects into the LAN with interface &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;eth&lt;/span&gt;. The OpenVPN server on &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt; reads and writes frames from/to the virtual Ethernet interface &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;tap&lt;/span&gt; which is bridged by &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;br&lt;/span&gt; with &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;eth&lt;/span&gt;. &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;vSwitch&lt;/span&gt; is a virtual switch in VMware ESX(i) and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt; is actually a virtual machine. I omitted a cascade of additional (real) switches that are found between &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;vSwitch&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host C &lt;/span&gt;as they do not matter in this example. Actually, I do not exactly know about the LAN and which VMware solution is applied for the virtualization as this infrastructure is not managed by me. We will thus consider the infrastructure as black box in the following.&lt;br /&gt;&lt;br /&gt;So what problem did I experience? Simply speaking, frames did not arrive from &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host C&lt;/span&gt; at &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host A&lt;/span&gt;:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-o4zcoxsRl3w/TyuqrfzJPRI/AAAAAAAABGM/Qx403bbT0kY/s1600/problem1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="259" src="http://2.bp.blogspot.com/-o4zcoxsRl3w/TyuqrfzJPRI/AAAAAAAABGM/Qx403bbT0kY/s320/problem1.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;As depicted and marked as &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Problem 1&lt;/span&gt;, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ARP Requests&lt;/span&gt; (broadcast frames) did traverse the bridge and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;vSwitch&lt;/span&gt; and were answered by &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ARP Replies &lt;/span&gt;(unicast frames), but the replies did not arrive at &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt;. Further on (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Problem 2&lt;/span&gt;), while &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ARP Requests&lt;/span&gt; from &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host C&lt;/span&gt; arrived at &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt; and where successfully answered,&amp;nbsp; unicast frames (&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ICMP Echo Request&lt;/span&gt; in this example) sent by &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host C&lt;/span&gt; and destined to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host A&lt;/span&gt; did not arrive at &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt;. Both problems are easily explained. &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;vSwitch&lt;/span&gt; is actually a very simple virtual switch and will only deliver frames to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt; that are destined to the MAC address of &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt;'s &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;eth&lt;/span&gt; interface. The switch cannot support multiple MACs per port. Thus there is only one solution: switch on the promiscuous mode for &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;vSwitch&lt;/span&gt; so that all frames that are received by &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;vSwitch&lt;/span&gt; are delivered to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;This was realized thanks to our technical department and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host A&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt; were actually able to communicate in some cases as this configuration introduces a new problem. I observed the following packet flow:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-N7XXiLWdKwM/TyuuQDyhe-I/AAAAAAAABGc/y7bJDoxt5ws/s1600/problem2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="154" src="http://4.bp.blogspot.com/-N7XXiLWdKwM/TyuuQDyhe-I/AAAAAAAABGc/y7bJDoxt5ws/s320/problem2.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;The &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ARP Reply&lt;/span&gt; was received by &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt; but the bridge br forwarded the unicast frame over the wrong port (resp. dropped the frame to prevent a loop): &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;P2&lt;/span&gt; and not &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;P1&lt;/span&gt; where &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host A&lt;/span&gt; is actually reachable. Thus the fundamental question is: why did the bridge use the wrong port? Bridges learn on which ports the stations/hosts/MAC addresses are actually reachable by evaluating the source addresses in the Ethernet frames. Shouldn't &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;br&lt;/span&gt; know that &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host A&lt;/span&gt; is reachable via port &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;P1&lt;/span&gt; because of the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ARP Request&lt;/span&gt;? In fact, I noticed with &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;brctl showmacs&lt;/span&gt; that &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host A&lt;/span&gt;'s MAC was sometimes reachable via &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;P1&lt;/span&gt; but most often via &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;P2&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;This is easily explained. Promiscuous mode has a slightly different meaning than usual. VMware writes in its documentation, that the promiscuous mode in ESX Server &lt;i&gt;"makes a virtual switch port act as a SPAN port or mirror port"&lt;/i&gt;. This somehow results in the following packet flow:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-l4H8gkvSS88/TyuvxNrPv7I/AAAAAAAABGk/_bf6VzRJGEg/s1600/problem3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="122" src="http://3.bp.blogspot.com/-l4H8gkvSS88/TyuvxNrPv7I/AAAAAAAABGk/_bf6VzRJGEg/s320/problem3.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;The virtual switch sends a copy of the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ARP Request&lt;/span&gt; back to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt;. Thus, while br did firstly detect &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host A&lt;/span&gt; as reachable via &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;P1&lt;/span&gt;, the copy arrived later and the bridge overwrote &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;P1&lt;/span&gt; by &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;P2&lt;/span&gt; in the forwarding table. Of course, this is not a fault of the bridge as Host A may have moved. It simply has to learn based on the observed frames. You can actually monitor duplicates of all broadcast frames on &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;eth&lt;/span&gt; on &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt; that are received by &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;vSwitch&lt;/span&gt; - even broadcasts that do not originate from &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt; or are forwarded by it. Thankfully this does not happen with unicast frames.&lt;br /&gt;&lt;br /&gt;So what is the solution to this problem? In fact there are several:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Replace &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;vSwitch&lt;/span&gt; with real hardware (costly)&lt;/li&gt;&lt;li&gt;Replace vSwitch by a Nexus 1000V (untested but certainly costly)&lt;/li&gt;&lt;li&gt;Consider other solutions, e.g., based on ProxyARP (untested, may introduce additional problems)&lt;/li&gt;&lt;li&gt;Disable learning in the bridge: &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;brctl setageing br 0&lt;/span&gt; (quick and easy solution but unicast packets are always flooded)&lt;/li&gt;&lt;li&gt;Filter the copies of the frames on &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;br&lt;/span&gt; resp. &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;eth&lt;/span&gt; on &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;The last options is actually what I evaluated and what I actually used in the end.&amp;nbsp; But why should it be that easy? My first idea was to filter the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ARP Request&lt;/span&gt; copies that we accidentally received from the virtual switch. Unfortunately, I was unable to solve the problem with &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;arptables&lt;/span&gt; as I cannot drop the frames before the bridge learns. &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;arptables&lt;/span&gt; provides only the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;filter&lt;/span&gt; table with the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;INPUT&lt;/span&gt;, &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;FORWARD&lt;/span&gt;, and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;OUTPUT&lt;/span&gt; chains. We can use only the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;FORWARD&lt;/span&gt; chain as the others apply only if the frame is generated on or destined to &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Host B&lt;/span&gt;. Unfortunately, the bridge has already learned/updated the mapping in the forward state. Thus after consulting &lt;a href="https://en.wikipedia.org/wiki/File:Netfilter-packet-flow.svg" target="_blank"&gt;this helpful figure&lt;/a&gt;, I opted for an &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ebtables&lt;/span&gt; rule that is evaluated early enough:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-family: inherit;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ebtables -t broute -A BROUTING --src $EXT_MAC --in-if $IFACE -j DROP&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-family: inherit;"&gt;There is only &lt;/span&gt;one issue with this solution: you need one rule for every external host/MAC address. This is not a problem in our case as we know which wireless mesh routers are located outside of our campus.&lt;br /&gt;&lt;br /&gt;This ends my discussion of this particular problem that kept me busy for some time. I hope that my documentation will help others and save time. Feel free to comment.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-1234221934171812681?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/1234221934171812681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2012/02/ethernet-bridging-troubles-on-vmware.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/1234221934171812681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/1234221934171812681'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2012/02/ethernet-bridging-troubles-on-vmware.html' title='Ethernet Bridging Troubles on VMware'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-QXmIekOa1vk/TyunNmVzQjI/AAAAAAAABF8/zB536-QjQNk/s72-c/architecture.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-5344550272828912107</id><published>2012-01-31T09:37:00.004+01:00</published><updated>2012-01-31T09:37:46.445+01:00</updated><title type='text'>Tales from my Job Hunt</title><content type='html'>There are several facts that I learned in the last weeks when I have been applying for jobs in the IT industry. Some of them are surprising and some are slightly&amp;nbsp;discouraging.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;There are several job advertisements for jobs that do not actually exist. You notice these jobs if your application process is closed, e.g., after exactly 72 hours after submission. Usually you get an email that that states that they selected someone more qualified (but you are nevertheless a "highly qualified applicant") whereas the position is still open and advertised.&amp;nbsp;But why are there advertisements if these companies do not actively seek new employees? While there is little information on the web available from what I found&lt;/li&gt;&lt;ul&gt;&lt;li&gt;these are either permanent advertisements to collect information about the current job market state,&lt;/li&gt;&lt;li&gt;they are only looking for experts that match all requirements&lt;/li&gt;&lt;li&gt;they want to attract professionals from competing companies, or&lt;/li&gt;&lt;li&gt;they&amp;nbsp;are permanent advertisements to get applications if a position is available at short notice&lt;span class="Apple-style-span" style="background-color: white;"&gt;&lt;a href="http://www.dict.cc/englisch-deutsch/notice.html" style="color: black; font-family: arial, helvetica, sans-serif; font-size: 13px; text-decoration: none;"&gt;&lt;/a&gt;.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;If you are asked about the expected salary, provide a reasonable interval. Of course, it is honest to argue that your actual salary depends on many factors, like the work hours per week, bonuses, training courses/certifications, etc. This figure is an important criterion if you are a potential fit for the position or if you are too expensive to begin with. At the same time, it is also important to know what your work is actually worth. It may also be a negative factor if you demand a too low salary as you may not earn much less currently because you are doing a poor job.&amp;nbsp;&lt;/li&gt;&lt;li&gt;The positions &lt;i&gt;Project Manager, Team Manager, IT Manager&lt;/i&gt;, etc can mean anything from managing a small developer team to being responsible for a multi-million Euro project. The &lt;a href="http://www.pmi.org/" target="_blank"&gt;PMI&lt;/a&gt;&amp;nbsp;thus differentiates several classes of companies in their book, depending on the power and responsibilities of the manager, e.g., strong or weak matrix. Unfortunately, this is not always clear from the job advertisements and you may apply for positions that do not fit. There are also similar positions that are prefixed with the terms &lt;i&gt;Functional&lt;/i&gt; or &lt;i&gt;Technical&lt;/i&gt; that usually do not refer to positions where the manager is responsible for everything and is actually working in a team of managers. Some few companies offer &lt;i&gt;Junior&lt;/i&gt; or &lt;i&gt;Trainee&lt;/i&gt; positions that are a good opportunity to continue your career.&lt;/li&gt;&lt;li&gt;Making your profile available at job markets/career websites/social networks like Monster, StepsStone, Xing, LinkedIn has advantages but also several disadvantages. You will get contacted by several headhunters that may offer interesting job opportunities but you are also contacted by a large number of agencies - sometimes even by multiple recruiters of the same company that are responsible for distinct regions or professions. It gets tiring if you have 5 telephone interviews and two on-site interviews per week, especially as you often do not know if these agencies actually have interesting jobs to offer (keep in mind that you still have a job during the job hunt and need to take some days off work for the interviews!). Nevertheless, it is a good training to present yourself and to plan where you want to be in 5-10 years.&lt;/li&gt;&lt;li&gt;You will also get contacted by so called &lt;i&gt;IT service providers&lt;/i&gt; (&lt;i&gt;IT Dienstleister&lt;/i&gt; in German). These companies may offer permanent positions but they are actually sending their employees to their clients to support the on-site teams for a particular project. These projects last from 6 months to 3 and maybe sometimes 5 years. While the IT service providers claim that they will try to get a subsequent project at the same location, they cannot guarantee it. Thus you may be either loosing your job or have to move every year(s). This is certainly not a job I aspire. Yes, you have to be mobile nowadays, but making a career in a single company sounds much better. If you are worrying about your job every year, you cannot focus on your current task.&lt;/li&gt;&lt;li&gt;Include ALL your technical skills in your resume. The human resource employees and even the department manager may not know which common skills you can expect from graduate students nowadays. For example, I am a researcher with focus on computer networks and of course are using relational databases. I expect that this skill is common and nothing special (but I am somehow alone with this&amp;nbsp;opinion).&amp;nbsp;Unfortunately, you are often required to list some specific programs, programming languages, etc in your resume because many companies do not expect that you are able to acquire the necessary knowledge yourself in a few weeks and/or require special training courses (costly!). If you are a computer scientist, you should have a good understanding of most topics in IT and be able to learn - but again, this may not be assumed.&lt;/li&gt;&lt;li&gt;German companies want German applications - sometimes even when the job offer is in English and the offer lists business-fluent English as a mandatory skill: "...we accept English resumes, but our official working language is German and we are a German company...". This applies even for some large, global corporations! This is quite surprising as English is the primary language in the academic research domain and even meetings (and some lectures) are often held in English.&lt;/li&gt;&lt;li&gt;Most companies were basically &lt;i&gt;"offline"&lt;/i&gt; for three weeks over Christmas and New Year's Eve and they took 1-2 weeks to get started again. You should not expect any notification during this time. This really surprised me, especially as we are talking about some large, well known, global corporations that sometimes expect that their employees are available at all times. I got feedback and where asked for interview dates 1.5 months after my submission! Please note that these were usually no job advertisements with a specific submission deadline where you expect a longer time for feedback if you submit early.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Despite these experiences, there are actually some very interesting offers with a reasonable salary and working conditions. Several headhunters told me that the companies currently have problems to find employees that plan to stay for 2+ years and/or to take on responsibilities. Thus the free lance market is currently booming and the companies are skeptical if they should invest in the training of new employees. Maybe this partially explains the job advertisement issue that is discussed?!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-5344550272828912107?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/5344550272828912107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2012/01/tales-from-my-job-hunt.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/5344550272828912107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/5344550272828912107'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2012/01/tales-from-my-job-hunt.html' title='Tales from my Job Hunt'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-4895616480707650696</id><published>2012-01-18T13:37:00.001+01:00</published><updated>2012-01-18T13:37:51.567+01:00</updated><title type='text'>Multi-Hop Routing on Android</title><content type='html'>I have been contacted by multiple people in the last months that are interested in our ongoing research work to enable multi-hop routing on the Android platform. In fact we have a working prototype since over a year.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.des-testbed.net/sites/default/files/installed.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://www.des-testbed.net/sites/default/files/installed.png" width="133" /&gt;&lt;/a&gt;&lt;a href="http://www.des-testbed.net/sites/default/files/dessert-on-android3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://www.des-testbed.net/sites/default/files/dessert-on-android3.png" width="153" /&gt;&lt;/a&gt;&lt;/div&gt;The left image depicts our &lt;a href="http://www.des-testbed.net/DES-SERT/android" target="_blank"&gt;DES-SERT Android app&lt;/a&gt; that enables to download, configure, and monitor routing daemons written for the &lt;a href="http://des-sert.net/" target="_blank"&gt;DES-SERT routing framework&lt;/a&gt;. Unfortunately, we were unable to make it publicly available as it does not yet fulfill our quality requirements. I am busy with my PhD thesis and several student helpers of the team left because projects ended. Thus the DES-SERT on Android sub-project is currently on hold for an indefinite time.&lt;br /&gt;The provisioning of a mature and user friendly solution is actually not an easy task. While I like the Android platform, I think it is kept back by several deficiencies. To name a few:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;A packaging system should be provided. This enables easier software deployment below the Dalvik VM but also enables frequent security updates! (Has this changed in Android &amp;gt;=3 ???)&lt;/li&gt;&lt;li&gt;Scrap the Bionic libc and switch to some common open source alternative to improve the compatibility and to ease software development!&lt;/li&gt;&lt;li&gt;The wireless drivers and their configuration are "weird"&amp;nbsp; and proprietary.&lt;/li&gt;&lt;/ol&gt;My propositions to improve the platform: &lt;br /&gt;&lt;ol&gt;&lt;li&gt;Provide a platform that fully complies to the Linux Standard Base to fulfill your users expectations about the installed standard utilities, the init process, etc (or at least provide a packaging system so that everyone can easily extend and update its installation).&lt;/li&gt;&lt;li&gt;Define Android as the Dalvik VM, the required libraries, and everything running on the VM and leave everything else to the open source community, distributions, etc. The Android Runtime and the Application Framework should be the only dependency to run Android apps on any (Linux based) OS. While this is already partially realized, there is still a long way to go to provide and use Android apps in a pervasive way.&lt;/li&gt;&lt;li&gt;Understand the mobile phone, tablet, etc as a full-fledged mobile computer with multi-user support, under full user control, and with a lifetime longer than 1-2 years. It is a mobile computer that is currently held back by proprietary solutions that provide us only with a subset of the features that we have come to love (printing anyone?).&lt;/li&gt;&lt;/ol&gt;Porting and maintaining the DES-SERT routing framework has taken much more work than it should have been. I assume that many other novel applications are held back at this time because companies care mostly only about the apps (that's were the money is at) and universities do not have the resources for dedicated, long-term projects to develop and support such solutions.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-4895616480707650696?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/4895616480707650696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2012/01/multi-hop-routing-on-android.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/4895616480707650696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/4895616480707650696'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2012/01/multi-hop-routing-on-android.html' title='Multi-Hop Routing on Android'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-4620701810790536065</id><published>2011-12-18T19:34:00.001+01:00</published><updated>2011-12-18T19:40:06.412+01:00</updated><title type='text'>Attack of the Mesh Routers</title><content type='html'>Hey look what I found! An advertisement poster for our then small research group that I created in 2008 with &lt;a href="http://inkscape.org/" target="_blank"&gt;Inkscape&lt;/a&gt;.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-BjCTe3vD2cM/Tu4xSqJZEhI/AAAAAAAABFw/pTf9fPnhUz8/s1600/attack-of-the-mesh-routers.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-BjCTe3vD2cM/Tu4xSqJZEhI/AAAAAAAABFw/pTf9fPnhUz8/s320/attack-of-the-mesh-routers.png" width="226" /&gt;&lt;/a&gt;&lt;/div&gt;The poster depicts a rather aggressive variant of our old mesh router design. You can find more information about the new design on the &lt;a href="http://des-testbed.net/hardware" target="_blank"&gt;DES-Testbed Hardware&lt;/a&gt; page.&lt;br /&gt;I wonder if any student joined our group because of the poster...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-4620701810790536065?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/4620701810790536065/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/12/attack-of-mesh-routers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/4620701810790536065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/4620701810790536065'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/12/attack-of-mesh-routers.html' title='Attack of the Mesh Routers'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-BjCTe3vD2cM/Tu4xSqJZEhI/AAAAAAAABFw/pTf9fPnhUz8/s72-c/attack-of-the-mesh-routers.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-5559017698140949549</id><published>2011-12-18T12:48:00.000+01:00</published><updated>2011-12-18T17:47:56.630+01:00</updated><title type='text'>Positions in the IT Industry</title><content type='html'>As I am currently looking for a new job (after I have finally submitted by PhD thesis and my contract ends), I have noticed that there is no brief overview and description of the positions in the software/IT industry. Interestingly, there are different titles for some positions, while a title may also have a significantly different meaning. You find a brief description of the most common positions in the following. Please feel free to post comments. Of course, most positions are available as &lt;i&gt;new grad&lt;/i&gt;,&amp;nbsp;&lt;i&gt;junior&lt;/i&gt;, and &lt;i&gt;senior&lt;/i&gt; variants whereas the work experience to reach the senior level may vary significantly (often times 5+ years). Several titles can also be prefixed by IT or similar terms.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Software Engineer&lt;/li&gt;&lt;ul&gt;&lt;li&gt;AKA:&amp;nbsp;Programmer, Software Developer, Software Development Engineer&lt;/li&gt;&lt;li&gt;Tasks:&amp;nbsp;Programmer that implements code based on a specification&lt;/li&gt;&lt;li&gt;Note: Some software engineers, e.g., for embedded systems often times have more freedom how they solve a particular problem, as there is no &lt;a href="http://de.wikipedia.org/wiki/Objektorientierte_Analyse_und_Design" target="_blank"&gt;OOAD&lt;/a&gt; involved.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Software Architect&lt;/li&gt;&lt;ul&gt;&lt;li&gt;AKA: IT Architect&lt;/li&gt;&lt;li&gt;Tasks: Models/designs the architecture of the application based on the requirement specification usually in an object oriented way using UML or related description languages&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Requirements Engineer&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Tasks: Applies requirement analysis techniques to specify the requirements of the application based on the customers demands,&amp;nbsp;questionnaires, interviews, etc&lt;/li&gt;&lt;li&gt;Note: May be the same person as the software architect but usually separated in current, larger projects.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Test Engineer&lt;/li&gt;&lt;ul&gt;&lt;li&gt;AKA:&amp;nbsp;Software Engineer in Test, Quality Assurance Engineer, Quality Manager&lt;/li&gt;&lt;li&gt;Tasks: Specifies, automates, and evaluates tests to find bugs in the application&lt;/li&gt;&lt;li&gt;Note: Quality manager may either represent an alternative title for test engineer or be the position of the manager of the test team&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Consultant&lt;/li&gt;&lt;ul&gt;&lt;li&gt;AKA: Business Analyst, Product Analyst, IT Auditor&lt;/li&gt;&lt;li&gt;Tasks:&amp;nbsp;Analyses business processes in a company, usually in a team, and proposes changes for the optimization; can be an internal or external consultant;&amp;nbsp;IT Business Analysts are often internal consultants&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Consultant (alternative)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;AKA: Contingent Worker&lt;/li&gt;&lt;li&gt;Tasks: Depends on the job/project&lt;/li&gt;&lt;li&gt;Note: Blatantly misleading description to fool applications, usually underpaid employment without job security. The worker is employed by a specific IT service company and leased to other companies for a project. He/she may be permanently employed by the client afterwards but there is no guarantee. Acceptable position if you are a highly skilled, well paid specialist. Alternatively, free lance work may be more promising than this position.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Researcher&lt;/li&gt;&lt;ul&gt;&lt;li&gt;AKA: Research and Development Engineer, Research Scientist&lt;/li&gt;&lt;li&gt;Tasks: Specifies a research and development plan for a project, either conducts the research independently or in a team&lt;/li&gt;&lt;li&gt;Note: Somehow a hybrid position of a academic researcher and a software engineer. There may be a hierarchy of research scientists.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Project Manager&lt;/li&gt;&lt;ul&gt;&lt;li&gt;AKA: Team Manager, IT Manager, Application Owner, Product Owner, Product Manager, Technical Program Manager&lt;/li&gt;&lt;li&gt;Tasks: Develops business cases, leads the developer team, reports to the upper management, works on proposals to acquire new projects, coordinates, and communicates with the client&lt;/li&gt;&lt;li&gt;Note: While the listed positions may have different focus, all of them include the responsibility for a particular product/team/application and include (some) human resource management and less software engineering related tasks.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Technical Writer&lt;/li&gt;&lt;ul&gt;&lt;li&gt;AKA: Technical Communicator&lt;/li&gt;&lt;li&gt;Tasks: Writes and maintains documentation about the product for developers, consumers, etc. He/she may also be employed by a publisher and act as an editor for publications.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;System Administrator&lt;/li&gt;&lt;ul&gt;&lt;li&gt;AKA: IT Communication Service Specialist&lt;/li&gt;&lt;li&gt;Tasks: Takes care that the IT infrastructure runs and all other departments can do their job. He/she may also be responsible to setup and maintain the hardware infrastructure.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Solution Designer&lt;/li&gt;&lt;ul&gt;&lt;li&gt;AKA: Solution Engineer, Conceptual Designer, Creative Planer&lt;/li&gt;&lt;li&gt;Tasks: Examine the business requirements and proposes solutions; hybrid position of a system architect and requirements engineer or may alternatively work closely with both of these&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;IT Supporter&lt;/li&gt;&lt;ul&gt;&lt;li&gt;AKA: Technical Supporter, Customer Service&lt;/li&gt;&lt;li&gt;Tasks: Is contacted by consumer, customer, or internal persons because of problems; either provides solutions for known problems or communicates problems to the specific department or person, e.g., some project manager&lt;/li&gt;&lt;li&gt;Note: Depending on the employment this may also be a hybrid position for highly skilled people that includes the tasks of the test engineer to reproduce the reported defect and the tasks of the software engineer and system architect to fix the problem. This may be especially be true in B2B scenarios, e.g., support for a commercial compiler or development environment.&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;div&gt;That is quite a list! Again, please consider that the title may have limited significance. The job description/description of the tasks will be more detailed. Nevertheless, despite the job advertisement you may end up doing something totally different in some companies depending on the current requirements ... but isn't that why we are in this domain? No day is like the other and there are always new problems and challenges :-)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-5559017698140949549?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/5559017698140949549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/12/as-i-am-currently-looking-for-new-job.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/5559017698140949549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/5559017698140949549'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/12/as-i-am-currently-looking-for-new-job.html' title='Positions in the IT Industry'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-2439124693203697637</id><published>2011-12-14T23:22:00.000+01:00</published><updated>2011-12-14T23:22:54.741+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LaTeX'/><title type='text'>Improved description environment</title><content type='html'>The LaTeX description environment is frequently used but has some limits. Consider the following example:&lt;br /&gt;&lt;blockquote class="tr_bq" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;\begin{description}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; \item[Short Label] Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod  tempor incididunt ut labore et dolore magna aliqua.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; \item[Looooooooooooong Label:] Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.&lt;br /&gt;\end{description}&lt;/blockquote&gt;The description labels and the text will not be aligned which just looks unprofessional. Fortunately, the &lt;a href="http://www.ctan.org/pkg/koma-script" target="_blank"&gt;KOMA-Script&lt;/a&gt; classes provide the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;labeling&lt;/span&gt; environment:&lt;br /&gt;&lt;blockquote class="tr_bq" style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;\begin{labeling}[\vspace{2em}]{Looooooooooooong Label:}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  \item[Short Label] Lorem ipsum dolor sit amet, consectetur adipisicing  elit, sed do eiusmod  tempor incididunt ut labore et dolore magna  aliqua.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; \item[Looooooooooooong Label:] Lorem  ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod  tempor incididunt ut labore et dolore magna aliqua.&lt;br /&gt;\end{labeling}&lt;/blockquote&gt;The optional parameter (in square brackets) allows to specify a custom separator for the labels and the text and may be some white space like in this example. The mandatory parameter (in curly brackets) specifies the width of the widest label in the labeling environment. Thus a clean looking alignment can be achieved.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-2439124693203697637?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/2439124693203697637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/12/improved-description-environment.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/2439124693203697637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/2439124693203697637'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/12/improved-description-environment.html' title='Improved description environment'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-1550801442316125675</id><published>2011-12-12T13:14:00.000+01:00</published><updated>2011-12-12T13:16:51.044+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Pseudo-color plot</title><content type='html'>&lt;a href="http://matplotlib.sourceforge.net/" target="_blank"&gt;matplotlib&lt;/a&gt; provides several functions to plot scientific data. Often times, I plot 3-dimensional data in 2-dimensonal formats as the third dimension sometimes obscures particular parts in the plot or such plots are problematic in publications. Pseudo-color plots are a good alternative as they are 2-dimensonal plots (x and y axes) whereas the third dimension is represented by color.&lt;br /&gt;&lt;br /&gt;The normal &lt;a href="http://matplotlib.sourceforge.net/api/axes_api.html?highlight=pcolor#matplotlib.axes.Axes.pcolor" target="_blank"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ax.pcolor()&lt;/span&gt;&lt;/a&gt; function unfortunately draws a grid around the cells that are rather ugly (click on the image to enlarge):&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-a52GzXitDQ8/TuXvRR1b2tI/AAAAAAAABFg/E-_AKFQbU9g/s1600/grid.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="270" src="http://4.bp.blogspot.com/-a52GzXitDQ8/TuXvRR1b2tI/AAAAAAAABFg/E-_AKFQbU9g/s320/grid.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;Although there are the &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;shading&lt;/span&gt; and &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;edgecolor&lt;/span&gt; options, they show not the desired effect. You can use the &lt;a href="http://matplotlib.sourceforge.net/api/axes_api.html?highlight=pcolor#matplotlib.axes.Axes.pcolorfast" target="_blank"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;ax.pcolorfast()&lt;/span&gt;&lt;/a&gt; function that improves the speed of the plotting as it does not draw any lines:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-z0DTWhCaHbc/TuXv9Ir0hmI/AAAAAAAABFo/DWcrrlDOUq4/s1600/nogrid.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="270" src="http://2.bp.blogspot.com/-z0DTWhCaHbc/TuXv9Ir0hmI/AAAAAAAABFo/DWcrrlDOUq4/s320/nogrid.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-1550801442316125675?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/1550801442316125675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/12/pseudo-color-plot.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/1550801442316125675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/1550801442316125675'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/12/pseudo-color-plot.html' title='Pseudo-color plot'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-a52GzXitDQ8/TuXvRR1b2tI/AAAAAAAABFg/E-_AKFQbU9g/s72-c/grid.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-7715384379953334427</id><published>2011-12-09T10:13:00.000+01:00</published><updated>2011-12-14T23:07:50.222+01:00</updated><title type='text'>Random Waypoint Model</title><content type='html'>Most MANET simulations of the last decade use the random waypoint model.&lt;br /&gt;The nodes select a random destination, usually in a square or rectangular area, a random velocity from (0, vmax], and then move towards the destination.&lt;br /&gt;When they arrive, they may either wait for a random time (may be omitted in some simulations) or immediately select a new random destination and velocity.&lt;br /&gt;&lt;br /&gt;The model has particular problems that have already been discussed in literature. For example, a low lower bound of the velocities may&amp;nbsp; result in many nodes that are stuck in their movement, i.e., they selected velocity 0 units/s or they may never arrive during the simulation time. Further on, the node accumulate in the center of the simulation area, as there is a larger probability to travel through the center than along the border.&lt;br /&gt;&lt;br /&gt;You can see an example of the mobility model in the following animation that I implemented in Python in an afternoon.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;iframe width="420" height="315" src="http://www.youtube.com/embed/4ZzaCfrbGb0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;!--&lt;object width="320" height="266" class="BLOG_video_class" id="BLOG_video-dbc8ea2454ccfa56" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="movie" value="http://www.youtube.com/get_player"&gt;&lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;param name="allowfullscreen" value="true"&gt;&lt;param name="flashvars" value="flvurl=http://v21.nonxt8.googlevideo.com/videoplayback?id%3Ddbc8ea2454ccfa56%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1332948276%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D55B2B93127EDDB96C10CAD78457559AA32F7D088.444FAC919BD40D9756599FAB8551F55FC41520D2%26key%3Dck1&amp;amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3Ddbc8ea2454ccfa56%26offsetms%3D5000%26itag%3Dw160%26sigh%3DPwhj1TPA7EOw4FJ6WRJHH_X4D_Y&amp;amp;autoplay=0&amp;amp;ps=blogger"&gt;&lt;embed src="http://www.youtube.com/get_player" type="application/x-shockwave-flash"width="320" height="266" bgcolor="#FFFFFF"flashvars="flvurl=http://v21.nonxt8.googlevideo.com/videoplayback?id%3Ddbc8ea2454ccfa56%26itag%3D5%26app%3Dblogger%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D1332948276%26sparams%3Did,itag,ip,ipbits,expire%26signature%3D55B2B93127EDDB96C10CAD78457559AA32F7D088.444FAC919BD40D9756599FAB8551F55FC41520D2%26key%3Dck1&amp;iurl=http://video.google.com/ThumbnailServer2?app%3Dblogger%26contentid%3Ddbc8ea2454ccfa56%26offsetms%3D5000%26itag%3Dw160%26sigh%3DPwhj1TPA7EOw4FJ6WRJHH_X4D_Y&amp;autoplay=0&amp;ps=blogger"allowFullScreen="true" /&gt;&lt;/object&gt;--&gt;&lt;/div&gt;The edges in the graph represent wireless links that are created when the nodes are within communication range. A very simple free space like model is assumed.&lt;br /&gt;&lt;br /&gt;Simulation are often times fairly abstract and the models are not good representatives for the real world. You should always be critical when using common models and ask yourself if the models are actually applicable in your scenario and if and how the models are affecting your results.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-7715384379953334427?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/7715384379953334427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/12/random-waypoint-model.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/7715384379953334427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/7715384379953334427'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/12/random-waypoint-model.html' title='Random Waypoint Model'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/4ZzaCfrbGb0/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-536075360956860801</id><published>2011-11-27T22:19:00.000+01:00</published><updated>2011-11-27T22:36:45.680+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Random graph with custom node degree distribution</title><content type='html'>Random and regular graphs are often used in simulations but sometimes you need some custom node degree distribution. This may be because the system you are modeling is not following a distribution which is available in common graph generators. &lt;a href="http://networkx.lanl.gov/index.html" target="_blank"&gt;NetworkX&lt;/a&gt; is my Python graph module of choice and actually supports everything to solve this problem:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;code&gt;&lt;br /&gt;import networkx as nx&lt;br /&gt;&lt;br /&gt;G1 = nx.&lt;a href="http://networkx.lanl.gov/reference/generated/networkx.generators.degree_seq.havel_hakimi_graph.html#networkx.generators.degree_seq.havel_hakimi_graph" target="_blank"&gt;havel_hakimi_graph&lt;/a&gt;(range(1,10)*2)&lt;br /&gt;G2 = nx.&lt;a href="http://networkx.lanl.gov/reference/generated/networkx.generators.degree_seq.expected_degree_graph.html#networkx.generators.degree_seq.expected_degree_graph" target="_blank"&gt;expected_degree_graph&lt;/a&gt;(range(1,10), selfloops=False)&lt;br /&gt;&lt;/code&gt;&lt;/blockquote&gt;The nodes in graph &lt;code&gt;G1&lt;/code&gt; will have exactly the given degree sequence, while the node degree distribution in G2 is similar. Of course, you should have a look at the documentation as there may be some specific details to consider. Further on, also consider that the structure of the graph may not be what you expect. The graph generators will often not create graphs that model wireless multi-hop networks very well. Links/edges can exist between far away nodes/vertices - in fact there is no relationship between the positions and the probability to insert an edge. The diameter of the generated graph will thus be much smaller than in geometric graphs with the same parameters.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-536075360956860801?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/536075360956860801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/random-graph-with-custom-node-degree.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/536075360956860801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/536075360956860801'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/random-graph-with-custom-node-degree.html' title='Random graph with custom node degree distribution'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-1376198260778902837</id><published>2011-11-27T11:19:00.000+01:00</published><updated>2011-12-12T13:18:05.008+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='KDE'/><title type='text'>KDE with Gnome/Unity Look</title><content type='html'>I like KDE and since version 4.6 it is finally usable again and feels like the 3.x versions. What I don't like is the default look and the themes that are provided by most distributions. Gnome and Unity have a much nicer design (we are not discussing the usability and customizability!). After some some tinkering around I got the following result.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-yC0odtY4H5o/TtINLKlwZ1I/AAAAAAAABFY/coYMwN7oPb0/s1600/desktop.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="179" src="http://2.bp.blogspot.com/-yC0odtY4H5o/TtINLKlwZ1I/AAAAAAAABFY/coYMwN7oPb0/s320/desktop.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;Looks pretty unlike KDE, doesn't it?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Wallpaper: &lt;a href="http://aaron-kelley.net/tech/ubuntu/ubuntu-wallpapers/" target="_blank"&gt;warty-final-ubuntu&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Icons: &lt;a href="https://launchpad.net/humanity/+download" target="_blank"&gt;Humanity-Dark&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Desktop Theme: &lt;a href="http://kde-look.org/content/show.php?content=136981" target="_blank"&gt;Ambiance&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Window Decoration: &lt;a href="http://kde-look.org/content/show.php?content=122924" target="_blank"&gt;Ambiance Aurorae&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Color Theme: Human (don't know the source anymore)&lt;/li&gt;&lt;li&gt;Style: Oxygen (will probably be changed in the future)&lt;/li&gt;&lt;/ul&gt;&amp;nbsp;The look is not perfect but much nicer than the out-of-the-box Kubuntu style.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-1376198260778902837?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/1376198260778902837/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/kde-with-gnomeunity-look.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/1376198260778902837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/1376198260778902837'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/kde-with-gnomeunity-look.html' title='KDE with Gnome/Unity Look'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-yC0odtY4H5o/TtINLKlwZ1I/AAAAAAAABFY/coYMwN7oPb0/s72-c/desktop.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-5084363756436610315</id><published>2011-11-25T18:12:00.000+01:00</published><updated>2011-12-18T19:42:02.901+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LaTeX'/><title type='text'>Sequential Figure and Table Numbering</title><content type='html'>&lt;code&gt;For some publishers it is mandatory to use a sequential numbering scheme for your floats. Sequential numbering of the figures and tables can be achieved with the help of the &lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;a href="http://www.ctan.org/pkg/caption" target="_blank"&gt;caption&lt;/a&gt;&lt;/span&gt; package:&lt;/code&gt;&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;code&gt;\usepackage{caption}&lt;/code&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote class="tr_bq"&gt;&lt;code&gt;\captionsetup{%&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; figurewithin=none,&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; tablewithin=none&lt;/code&gt;&lt;br /&gt;&lt;code&gt;}&lt;/code&gt;&lt;/blockquote&gt;Although I&amp;nbsp;prefer the format with the Chapter number as prefix, e.g., Table 2.1&amp;nbsp;&amp;nbsp;this scheme makes sense when you have few floats in your document.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-5084363756436610315?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/5084363756436610315/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/sequential-figure-and-table-numbering.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/5084363756436610315'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/5084363756436610315'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/sequential-figure-and-table-numbering.html' title='Sequential Figure and Table Numbering'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-181352532171512256</id><published>2011-11-21T09:21:00.000+01:00</published><updated>2011-11-21T09:21:10.062+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LaTeX'/><title type='text'>Margins in matplotlib Figures</title><content type='html'>&lt;a href="http://matplotlib.sourceforge.net/" target="_blank"&gt;matplotlib&lt;/a&gt; creates figures that may have unnecessarily large margins around the content. You can enforce a tighter format as follows:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;code&gt;&lt;br /&gt;fig.savefig('/tmp/figure.pdf', bbox_inches='tight')&lt;/code&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-181352532171512256?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/181352532171512256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/margins-in-matplotlib-figures.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/181352532171512256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/181352532171512256'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/margins-in-matplotlib-figures.html' title='Margins in matplotlib Figures'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-2732292031064956121</id><published>2011-11-20T17:27:00.000+01:00</published><updated>2011-11-20T17:29:05.100+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Restore Cursor Position in VIM</title><content type='html'>A very handy tip is available in the &lt;a href="http://vim.wikia.com/wiki/Restore_cursor_to_file_position_in_previous_editing_session" target="_blank"&gt;Vim Tips Wiki&lt;/a&gt;. Your cursor will be automatically moved to the last position in the file of your previous session. Just include the following in your &lt;a href="http://vim.wikia.com/wiki/Vimrc" target="_blank"&gt;Vim runtime configuration&lt;/a&gt; file:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;pre&gt;function! ResCur()&lt;br /&gt;  if line("'\"") &amp;lt;= line("$")&lt;br /&gt;    normal! g`"&lt;br /&gt;    return 1&lt;br /&gt;  endif&lt;br /&gt;endfunction&lt;br /&gt;&lt;br /&gt;augroup resCur&lt;br /&gt;  autocmd!&lt;br /&gt;  autocmd BufWinEnter * call ResCur()&lt;br /&gt;augroup END&lt;/pre&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-2732292031064956121?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/2732292031064956121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/restore-cursor-position-in-vim.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/2732292031064956121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/2732292031064956121'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/restore-cursor-position-in-vim.html' title='Restore Cursor Position in VIM'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-863046487389093660</id><published>2011-11-20T16:01:00.000+01:00</published><updated>2011-11-20T17:28:37.947+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Named Tuples in Python</title><content type='html'>As a developer that discovered Python after years of C programming, I sometimes miss the ability to access my tuples by names. In C you often times have a list of structures where you access a particular member in a loop. &lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;&lt;br /&gt;typedef struct _my_struct {&lt;br /&gt;    uint8_t foo;&lt;br /&gt;    uint8_t bar;&lt;br /&gt;    struct _my_struct* next;&lt;br /&gt;} my_struct;&lt;br /&gt;&lt;br /&gt;int main(int argc, char** argp) {&lt;br /&gt;    my_struct* list = NULL;&lt;br /&gt;    my_struct* s1 = (my_struct*) malloc(sizeof(my_struct));&lt;br /&gt;    my_struct* s2 = (my_struct*) malloc(sizeof(my_struct));&lt;br /&gt;    s1-&amp;gt;foo = 5;&lt;br /&gt;    list = s1;&lt;br /&gt;    s1-&amp;gt;next = s2;&lt;br /&gt;    s2-&amp;gt;foo = 8;&lt;br /&gt;    s2-&amp;gt;next = NULL;&lt;br /&gt;    &lt;br /&gt;    my_struct* cur = list;&lt;br /&gt;    uint32_t  accu = 0;&lt;br /&gt;    while(cur != NULL) {&lt;br /&gt;        accu += cur-&amp;gt;foo;&lt;br /&gt;        cur = cur-&amp;gt;next;&lt;br /&gt;    }&lt;br /&gt;    printf("accu = %d\n", accu);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/blockquote&gt;Please, ignore that I am not checking the return value of &lt;code&gt;malloc&lt;/code&gt; as this is just a simple example! The member names enable that you do not have to remember the position inside the structure (respectively the offset). In fact, the compiler may reposition all members.&lt;br /&gt;How can you realize this in Python? Often times you have data in a list of tuples, e.g., tuples like (foo, bar). The sum of the foo member can be calculated as follows:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;code&gt;&lt;br /&gt;tuples = list()&lt;br /&gt;tuples.append((5, 0))&lt;br /&gt;tuples.append((8, 0))&lt;br /&gt;sum_of_foos = sum([t[0] for t in tuples])&lt;br /&gt;&lt;/code&gt;&lt;/blockquote&gt;Although lists and tuples are powerful data structures of Python, the code is rather ugly. Suppose you have 100 values inside a tuple. Will you be able to remember at which position foo resides? Will you be able to remember after some refactoring when the positions changed?&lt;br /&gt;Python provides named tuples in the collections module.&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;code&gt;import collections&lt;br /&gt;&lt;br /&gt;MyTuple = collections.namedtuple('MyTuple', 'foo bar')&lt;br /&gt;&lt;br /&gt;tuples = list()&lt;br /&gt;s1 = MyTuple(foo=8, bar=0)&lt;br /&gt;tuples.append(s1)&lt;br /&gt;s2 = MyTuple(foo=5, bar=0)&lt;br /&gt;tuples.append(s2)&lt;br /&gt;&lt;br /&gt;print sum([s.foo for s in tuples])&lt;br /&gt;&amp;nbsp; &lt;/code&gt;&lt;/blockquote&gt;As you can see, named tuples can make your life easier even though you have to add definitions of all tuple types. Whether the overhead is acceptable, that is up to you and the size of your software project.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-863046487389093660?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/863046487389093660/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/named-tuples-in-python.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/863046487389093660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/863046487389093660'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/named-tuples-in-python.html' title='Named Tuples in Python'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-6855912374739405951</id><published>2011-11-18T09:44:00.000+01:00</published><updated>2011-11-20T16:07:11.794+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='LaTeX'/><title type='text'>LaTeX and matplotlib</title><content type='html'>Although it should be the content that decides the "fate" of submissions to scientific journals or conferences, the presentation is also an important factor. While it has become a rare event that papers contain figures/graphs that have been created in some spreadsheet application, as many people nowadays use gnuplot or matplotlib, the figures may still not completely fit the document. Fonts and font sizes have to be matched. While I have no sound approach for the size, the font can be matched easily - at least with matplotlib and LaTeX.&lt;br /&gt;&lt;br /&gt;LaTeX uses the &lt;a href="http://en.wikipedia.org/wiki/Computer_Modern" target="_blank"&gt;Computer Modern&lt;/a&gt; font from  &lt;a href="http://en.wikipedia.org/wiki/Donald_Knuth" title="Donald Knuth"&gt;Donald Knuth&lt;/a&gt;. matplotlib can be &lt;a href="http://matplotlib.sourceforge.net/users/usetex.html" target="_blank"&gt;configured&lt;/a&gt; to use LaTeX for the typesetting. Either include the following in your &lt;a href="http://matplotlib.sourceforge.net/users/customizing.html" target="_blank"&gt;matplotlib rc file&lt;/a&gt;:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;code&gt;text.usetex: true&lt;/code&gt;&lt;/blockquote&gt;or in your Python code:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;code&gt;matplotlib.rc('text', usetex=True)&lt;/code&gt;&lt;/blockquote&gt;&amp;nbsp;This enables LaTeX processing, so that you may also use mathematical formulas as follows in your strings:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;code&gt;'Something $\delta \frac{foo}{bar}$'&lt;/code&gt;&lt;/blockquote&gt;If you require some particular LaTeX package or other LaTeX specific settings, just include them as follows:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;code&gt;matplotlib.rcParams['text.latex.preamble'] = '\usepackage{euler}'&lt;/code&gt;&lt;/blockquote&gt;If you observe that the font outside of the mathematical environments does not match the LaTeX font, it may be that matplotlib is using a non-serif font but Computer Modern is serif. Configure matplotlib and everything should be fine:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;code&gt;matplotlib.rcParams['font.family'] = 'serif'&lt;br /&gt;matplotlib.rcParams['font.serif'] = 'Computer Modern Roman'&lt;/code&gt;&lt;/blockquote&gt;Computer Modern should be the default serif font but it shouldn't hurt to configure it implicitly.&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-FpdUUkOiGRo/TsYZn2jNpmI/AAAAAAAABFI/cefMkBEqwKA/s1600/example.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="240" src="http://2.bp.blogspot.com/-FpdUUkOiGRo/TsYZn2jNpmI/AAAAAAAABFI/cefMkBEqwKA/s320/example.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;The labels on the axes are not in a mathematical environment while the tick labels are set in the Euler font. The image was created by the following code in the &lt;a href="http://ipython.org/" target="_blank"&gt;IPython&lt;/a&gt; shell started with the &lt;code&gt;-pylab&lt;/code&gt; parameter:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;matplotlib.use('Agg')&lt;br /&gt;matplotlib.rc('text', usetex=True)&lt;br /&gt;matplotlib.rcParams['text.latex.preamble'] = '\usepackage{euler}'&lt;br /&gt;matplotlib.rcParams['lines.linewidth'] = 2&lt;br /&gt;matplotlib.rcParams['font.family'] = 'serif'&lt;br /&gt;matplotlib.rcParams['font.serif'] = 'Computer Modern Roman'&lt;br /&gt;matplotlib.rcParams['font.size'] = '24'&lt;br /&gt;fig = figure()&lt;br /&gt;ax = fig.gca()&lt;br /&gt;ax.plot(pylab.linspace(0, 100, 101))&lt;br /&gt;ax.set_xlabel('x-axis')&lt;br /&gt;ax.set_ylabel('y-axis')&lt;br /&gt;fig.savefig('/tmp/example.png')&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-6855912374739405951?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/6855912374739405951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/latex-and-matplotlib.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/6855912374739405951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/6855912374739405951'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/latex-and-matplotlib.html' title='LaTeX and matplotlib'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-FpdUUkOiGRo/TsYZn2jNpmI/AAAAAAAABFI/cefMkBEqwKA/s72-c/example.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-9132264341495724965</id><published>2011-11-16T14:31:00.000+01:00</published><updated>2011-11-16T14:31:35.229+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='publication'/><title type='text'>What Every Computer Scientist Should Know About Floating-Point Arithmetic</title><content type='html'>David Goldberg published a fundamental paper about the accuracy of floating point arithmetic in 1991. Indeed, every computer scientists should have read it and understood the problem. If haven't, here is the &lt;a href="http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.1.7712" target="_blank"&gt;PDF&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-9132264341495724965?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/9132264341495724965/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/what-every-computer-scientist-should.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/9132264341495724965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/9132264341495724965'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/what-every-computer-scientist-should.html' title='What Every Computer Scientist Should Know About Floating-Point Arithmetic'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-8265769332936006637</id><published>2011-11-15T21:24:00.000+01:00</published><updated>2011-11-15T21:30:33.369+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LaTeX'/><title type='text'>LaTeX Figure Filenames</title><content type='html'>The &lt;a href="http://www.ctan.org/pkg/grffile" target="_blank"&gt;grffile&lt;/a&gt; is a LaTeX package that enables support for some unsupported figure filename patterns. For example the following filename will produce an error due to the multiple dots: &lt;code&gt;data_p=1.0.pdf&lt;/code&gt;. Quite helpful but this feature should have been enabled by default.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-8265769332936006637?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/8265769332936006637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/latex-figure-filenames.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/8265769332936006637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/8265769332936006637'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/latex-figure-filenames.html' title='LaTeX Figure Filenames'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-9043988334545918756</id><published>2011-11-14T09:29:00.000+01:00</published><updated>2011-11-14T09:29:50.475+01:00</updated><title type='text'>Know Your Distributions</title><content type='html'>When I was recently evaluating and fitting some data, I found some nice documents that give an overview to statistical distributions.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://pubs.amstat.org/doi/abs/10.1198/000313008X270448" target="_blank"&gt;Univariate Distribution Relationships&amp;nbsp;                          by Leemis et al.&lt;/a&gt; (PDF can be easily found via Google)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.google.com/url?sa=t&amp;amp;rct=j&amp;amp;q=&amp;amp;esrc=s&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CCQQFjAA&amp;amp;url=http%3A%2F%2Fpeleg.yogiley.org%2Fmath%2Fprobability%2Fprobabilitycs.pdf&amp;amp;ei=cNDATofCJo7KtAbd06i-Aw&amp;amp;usg=AFQjCNF4TCs2dsZOFIyDZFUmR-FeMPB4GQ"&gt;Probability Cheat Sheet&lt;/a&gt; by&amp;nbsp; Peleg Michaeli&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.itl.nist.gov/div898/handbook/," target="_blank"&gt;Engineering Statistics Handbook&lt;/a&gt; by NIST&lt;/li&gt;&lt;/ol&gt;Of course, Wikipedia provides also some concise information.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-9043988334545918756?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/9043988334545918756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/know-your-distributions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/9043988334545918756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/9043988334545918756'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/know-your-distributions.html' title='Know Your Distributions'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-971778233754688181</id><published>2011-11-14T09:01:00.000+01:00</published><updated>2011-11-14T09:01:56.520+01:00</updated><title type='text'>Terminal Emulator</title><content type='html'>Ever had to debug or communicate with an embedded system over the serial line? Are you happy with &lt;a href="http://alioth.debian.org/projects/minicom/" target="_blank"&gt;minicom&lt;/a&gt; or &lt;a href="http://www.chiark.greenend.org.uk/%7Esgtatham/putty/" target="_blank"&gt;putty&lt;/a&gt;? Try &lt;a href="http://www.der-hammer.info/terminal/" target="_blank"&gt;hterm&lt;/a&gt;! It may not be open source but it puts all options in plain view, you can show the output a binary/ascii/hex, and it is available for Linux and Windows thanks to the &lt;a href="http://www.wxwidgets.org/" target="_blank"&gt;wxwidgets&lt;/a&gt; toolkit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-971778233754688181?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/971778233754688181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/terminal-emulator.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/971778233754688181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/971778233754688181'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/terminal-emulator.html' title='Terminal Emulator'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-2817511770323311811</id><published>2011-11-13T23:29:00.000+01:00</published><updated>2011-11-13T23:30:53.047+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LaTeX'/><title type='text'>Forcing Float Positions in LaTeX</title><content type='html'>One of the common annoyances for LaTeX beginners is that you are not  explicitly specifying the position of floating environments, e.g.,  figures and tables. There are some ways to force the positions like the  [h] option but none is really perfect.&lt;br /&gt;The &lt;a href="http://www.ctan.org/pkg/placeins"&gt;placeins&lt;/a&gt; package defines the&lt;code&gt; \FloatBarrier&lt;/code&gt; command, beyond which floats may not pass. In addition, you may also specify that floats are always positioned in the section where they are referenced.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-2817511770323311811?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/2817511770323311811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/forcing-float-positions-in-latex.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/2817511770323311811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/2817511770323311811'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/forcing-float-positions-in-latex.html' title='Forcing Float Positions in LaTeX'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-4980608859217016333</id><published>2011-11-13T23:10:00.000+01:00</published><updated>2011-11-13T23:10:44.443+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LaTeX'/><title type='text'>Protocol Headers in LaTeX</title><content type='html'>Ever had to include a figure with a protocol header in your scientific publication or thesis written in LaTeX? Use the &lt;a href="http://www.ctan.org/tex-archive/macros/latex/contrib/bytefield/" target="_blank"&gt;bytefield&lt;/a&gt; package to produce a professional output and avoid bitmap or vector images created in external programs. As you stay within LaTeX, your fonts will match perfectly. The package may also be abused to typeset other types of figures, e.g., a Gantt chart.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-4980608859217016333?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/4980608859217016333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/protocol-headers-in-latex.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/4980608859217016333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/4980608859217016333'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/protocol-headers-in-latex.html' title='Protocol Headers in LaTeX'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-8892916632668609921</id><published>2011-11-13T23:01:00.000+01:00</published><updated>2011-11-13T23:14:14.215+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Python for Scientifc Research</title><content type='html'>&lt;a href="http://www.python.org/" target="_blank"&gt;Python&lt;/a&gt; certainly has established itself as an all-purpose language with a rich module library. We use Python for mostly everything in the &lt;a href="http://www.des-testbed.net/" target="_blank"&gt;DES-Testbed&lt;/a&gt;: running experiments, evaluating data, and plotting. Unfortunately, some developers still do not know about the most powerful modules and write everything from scratch - reinventing the wheel.&lt;br /&gt;Thus everyone in the research domain should have a look at the following tutorials:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.scipy.org/Tentative_NumPy_Tutorial" target="_blank"&gt;numpy&lt;/a&gt;: arrays, matrices, and histograms&lt;/li&gt;&lt;li&gt;&lt;a href="http://docs.scipy.org/doc/scipy/reference/tutorial/index.html" target="_blank"&gt;scipy&lt;/a&gt;: mathematical algorithms, convenience functions, distributions, fft, image processing, fitting, ...&lt;/li&gt;&lt;li&gt;&lt;a href="http://matplotlib.sourceforge.net/users/index.html" target="_blank"&gt;matplotlib&lt;/a&gt;: 2D plotting library (but also includes some 3D plots)&lt;/li&gt;&lt;/ul&gt;The combination of numpy, scipy, and matplotlib is a good substitute for R and Matlab. There are also several &lt;a href="http://www.gnuplot.info/" target="_blank"&gt;gnuplot&lt;/a&gt; modules but I never found one I liked. Although I have to admit, that gnuplot plots look somehow more professional but this is just a matter of individual taste.&lt;br /&gt;&lt;br /&gt;And do not forget one of the most important rules of scientific publishing:&amp;nbsp; avoid bitmap images, use vector formats!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-8892916632668609921?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/8892916632668609921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/python-for-scientifc-research.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/8892916632668609921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/8892916632668609921'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/python-for-scientifc-research.html' title='Python for Scientifc Research'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-2155158666060779128</id><published>2011-11-13T22:38:00.000+01:00</published><updated>2011-11-13T22:38:17.162+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Essential Unix Tutorials</title><content type='html'>Bruce Barnett has compiled some nice &lt;a href="http://www.grymoire.com/Unix/" target="_blank"&gt;tutorials&lt;/a&gt;, e.g., about sed, awk, and shell quoting. The tutorials are a little bit older but still relevant and every novel shell script developer should read them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-2155158666060779128?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/2155158666060779128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/essential-unix-tutorials.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/2155158666060779128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/2155158666060779128'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/essential-unix-tutorials.html' title='Essential Unix Tutorials'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-8942733277377934736</id><published>2011-11-13T22:34:00.000+01:00</published><updated>2011-11-13T22:35:03.632+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>moreutils</title><content type='html'>The &lt;a href="http://kitenet.net/%7Ejoey/code/moreutils/" target="_blank"&gt;moreutils&lt;/a&gt; package extends the standard tool set of shell script developers by some useful programs.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;combine: combine the lines in two files using boolean operations&lt;/li&gt;&lt;li&gt;ifdata: get network interface info without parsing ifconfig output&lt;/li&gt;&lt;li&gt;ifne: run a program if the standard input is not empty&lt;/li&gt;&lt;li&gt;isutf8: check if a file or standard input is utf-8&lt;/li&gt;&lt;li&gt;lckdo: execute a program with a lock held&lt;/li&gt;&lt;li&gt;mispipe: pipe two commands, returning the exit status of the first&lt;/li&gt;&lt;li&gt;parallel: run multiple jobs at once&lt;/li&gt;&lt;li&gt;pee: tee standard input to pipes&lt;/li&gt;&lt;li&gt;sponge: soak up standard input and write to a file&lt;/li&gt;&lt;li&gt;ts: timestamp standard input&lt;/li&gt;&lt;li&gt;vidir: edit a directory in your text editor&lt;/li&gt;&lt;li&gt;vipe: insert a text editor into a pipe&lt;/li&gt;&lt;li&gt;zrun: automatically uncompress arguments to command&lt;/li&gt;&lt;/ul&gt;I am an avid user of ifdata!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-8942733277377934736?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/8942733277377934736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/morutils.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/8942733277377934736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/8942733277377934736'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/morutils.html' title='moreutils'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-3566094717375249533</id><published>2011-11-13T22:29:00.000+01:00</published><updated>2011-11-13T22:29:24.610+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fub'/><category scheme='http://www.blogger.com/atom/ns#' term='talk'/><title type='text'>Bitcoin Introduction</title><content type='html'>&lt;a href="http://sneak.datavibe.net/" target="_blank"&gt;Jeffrey Paul&lt;/a&gt; is giving a talk at Freie Universität Berlin about &lt;a href="http://bitcoin.org/" target="_blank"&gt;Bitcoin&lt;/a&gt;, the digital Peer-to-Peer currency.&lt;br /&gt;&lt;br /&gt;Wednesday, 23.11.2011, 18:00&lt;br /&gt;Computer Science Lecture Hall&lt;br /&gt;Takustraße 9&lt;br /&gt;14195 Berlin&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-3566094717375249533?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/3566094717375249533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/bitcoin-introduction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/3566094717375249533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/3566094717375249533'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/bitcoin-introduction.html' title='Bitcoin Introduction'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-3678001158053492389</id><published>2011-11-13T22:22:00.000+01:00</published><updated>2011-11-13T22:24:03.033+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Debian'/><title type='text'>/tmp as tmpfs</title><content type='html'>Bastien Roucaries started a very interesting &lt;a href="http://lists.debian.org/debian-devel/2011/11/msg00281.html" target="_blank"&gt;discussion on debian-devel&lt;/a&gt; about the decision to mount a tmpfs as /tmp and the associated problems that arise. Some programs require significantly more memory in /tmp than is available.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-3678001158053492389?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/3678001158053492389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/tmp-as-tmpfs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/3678001158053492389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/3678001158053492389'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/tmp-as-tmpfs.html' title='/tmp as tmpfs'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-2422880012520490887</id><published>2011-11-13T22:16:00.000+01:00</published><updated>2011-11-13T22:17:54.380+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>curses Based File Manager</title><content type='html'>&lt;a href="http://ranger.nongnu.org/" target="_blank"&gt;ranger&lt;/a&gt; is an interesting curses based file manager with a multi-column display (Miller Columns). An interesting alternative for the &lt;a href="https://www.midnight-commander.org/" target="_blank"&gt;Midnight Commander&lt;/a&gt;.&lt;br /&gt;ranger also provides a vim-like console and hotkeys.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-2422880012520490887?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/2422880012520490887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/curses-based-file-manager.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/2422880012520490887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/2422880012520490887'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/curses-based-file-manager.html' title='curses Based File Manager'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-3242969538367934669</id><published>2011-11-13T22:10:00.000+01:00</published><updated>2011-11-13T22:17:25.480+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><title type='text'>Code Obfuscation</title><content type='html'>&lt;a href="http://www.ioccc.org/" target="_blank"&gt;International Obfuscated C Code Contest&lt;/a&gt; is accepting submissions again. Write code that simply looks funny and is unreadable but still has some function. For example, the last contests submissions include tiny operating system and flight simulators.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-3242969538367934669?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/3242969538367934669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/international-obfuscated-c-code-contest.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/3242969538367934669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/3242969538367934669'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/international-obfuscated-c-code-contest.html' title='Code Obfuscation'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-3118495807632178195</id><published>2011-11-13T21:59:00.000+01:00</published><updated>2011-11-13T22:11:17.008+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C'/><title type='text'>Hiding malicious code in innocent programs</title><content type='html'>&lt;a href="http://underhanded.xcott.com/" target="_blank"&gt;The Underhanded C Contest&lt;/a&gt; annual contest where contestant may submit solutions for a given problem. The catch: the code has to look innocent but a specific malicious behavior has to be hidden. The submissions a very nice exercise for code reviewers - although some submissions would not pass QA due to their violation of common coding standards.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-3118495807632178195?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/3118495807632178195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/hiding-malicious-code-in-innocent.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/3118495807632178195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/3118495807632178195'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/hiding-malicious-code-in-innocent.html' title='Hiding malicious code in innocent programs'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4005848446363811858.post-208692725459655962</id><published>2011-11-01T22:50:00.000+01:00</published><updated>2011-12-23T22:54:52.149+01:00</updated><title type='text'>About this Blog</title><content type='html'>What's this Blog about and why does it exit? In the last years I wrote several tutorials and answered hundreds of questions for my students. As I am currently (finally!) finishing my PhD, my time at Freie Universität Berlin slowly comes to an end. I am migrating the information to this blog so that it is not lost in the future if no one is taking care of our Wikis, Mailinglists, etc. In addition, it serves as my personal information dump that may be of use for someone else.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4005848446363811858-208692725459655962?l=blywis.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blywis.blogspot.com/feeds/208692725459655962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blywis.blogspot.com/2011/11/about-this-blog.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/208692725459655962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4005848446363811858/posts/default/208692725459655962'/><link rel='alternate' type='text/html' href='http://blywis.blogspot.com/2011/11/about-this-blog.html' title='About this Blog'/><author><name>Bastian Blywis</name><uri>http://www.blogger.com/profile/15362950235202957858</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
