After upgrading a Django project from Django 1.5 to the current beta of Django 1.7, running the tests triggered a warning:

System check identified some issues:
WARNINGS:
?: (1_6.W001) Some project unittests may not execute as expected.
HINT: Django 1.6 introduced a new default test runner. It looks like this project was generated using Django 1.5 or earlier. You should ensure your tests are all running & behaving as expected. See https://docs.djangoproject.com/en/dev/releases/1.6/#discovery-of-tests-in-any-test-module for more information.

After verifying that all my tests are run, I was left wondering how I can silence the warning after reading (okay, let’s be honest: skimming) the release notes of 1.6. The answer is simple, but I had to look in the source of the system check framework to find it. Apparently you have to explicitly define a test runner starting from Django 1.6. To do so, add the following line to your settings:

Caught VariableDoesNotExist while rendering: Failed lookup for key [request] in...

you are probably using a template tag that requires the request context processor. Simply add ‘django.core.context_processors.request’ to the TEMPLATE_CONTEXT_PROCESSORS tuple in your settings file.

HTTP Status 400 - missing content stream
Status report
message missing content stream
description The request sent by the client was syntactically incorrect (missing content stream).

then you are probably missing the commit parameter i.e. ?commit=true

For Christmas, I got the ThinkFun 36 Cube. It is consists of 36 towers in 6 colors and 6 different sizes and a base plate with 6 by 6 slots to plug in the towers. These slots are of different heights. The goal is to place one towers of every color in each row and column. And the towers must fit to form a level cube.

After some tries, I came to the conclusion that this puzzle is the work of the devil and that I should not waste more brain cycles on solving it. So I wrote a little python script to solve the puzzle for me.

#!/usr/bin/python
COLORS =dict(zip((1 << i for i inrange(6)),('P','Y','O','B','R','G')))
COLORS[False]='X'
used_towers =[0for i inrange(6)]
cube =((1,3,4,5,2,0),(2,5,0,4,1,3),(0,1,3,2,5,4),(5,4,1,3,0,2),(4,2,5,0,3,1),(3,0,2,1,4,5))
solution =[[Falsefor x inrange(6)]for x inrange(6)]
used =tuple(set()for i inrange(6))def test_color(pos, solution, used_towers, color, size):
#check if tower of this size and color has already been usedif color & used_towers[size]:
returnFalse#check if tower has already been used in row or column:for i inrange(6):
if color == solution[pos/6][i]: returnFalseif color == solution[i][pos%6]: returnFalsereturnTruedef print_solution(solution):
for i inrange(6):
printzip((COLORS[c]for c in solution[i]),(6 - s for s in cube[i]))def solve(pos, solution, used_towers, best):
if pos ==36: return best, solution
size = cube[pos/6][pos%6]for i inrange(6):
color =1 << i
if test_color(pos, solution, used_towers, color, size):
used_towers[size]= used_towers[size] | color
solution[pos/6][pos%6]= color
if pos > best:
print"#######", pos + 1,"towers placed"
print_solution(solution)
best = pos
best, solution = solve(pos+1, solution, used_towers, best)if best >=35:
return best, solution
solution[pos/6][pos%6]=False
used_towers[size]= used_towers[size] ^ color
return best, solution
solve(0, solution, used_towers,0)

#!/usr/bin/python
COLORS = dict(zip((1 << i for i in range(6)), ('P','Y','O','B','R','G')))
COLORS[False] = 'X'
used_towers = [0 for i in range(6)]
cube = ((1,3,4,5,2,0),
(2,5,0,4,1,3),
(0,1,3,2,5,4),
(5,4,1,3,0,2),
(4,2,5,0,3,1),
(3,0,2,1,4,5))
solution = [[False for x in range(6)] for x in range(6)]
used = tuple(set() for i in range(6))
def test_color(pos, solution, used_towers, color, size):
#check if tower of this size and color has already been used
if color & used_towers[size]:
return False
#check if tower has already been used in row or column:
for i in range(6):
if color == solution[pos/6][i]: return False
if color == solution[i][pos%6]: return False
return True
def print_solution(solution):
for i in range(6):
print zip((COLORS[c] for c in solution[i]), (6 - s for s in cube[i]))
def solve(pos, solution, used_towers, best):
if pos == 36: return best, solution
size = cube[pos/6][pos%6]
for i in range(6):
color = 1 << i
if test_color(pos, solution, used_towers, color, size):
used_towers[size] = used_towers[size] | color
solution[pos/6][pos%6] = color
if pos > best:
print "#######", pos + 1, "towers placed"
print_solution(solution)
best = pos
best, solution = solve(pos+1, solution, used_towers, best)
if best >= 35:
return best, solution
solution[pos/6][pos%6] = False
used_towers[size] = used_towers[size] ^ color
return best, solution
solve(0, solution, used_towers, 0)

My program quickly came up with a correct placement for 34 towers – but it failed to find the complete solution.

Legend:
P = Purple, Y = Yellow, O = Orange, B = Blue, R = Red, G = Green, X = Empty
The number is the size of the tower.
As you can see, I didn’t waste much time on making the output pretty 🙂

So close and yet so far

After spending lots of time verifying that my program was working correctly, I became impatient and googled for help. I found an answer, but it revealed to much, taking all the fun.

Therefore, I split my solution into multiple hints. If you are stuck, reveal just one of them at a time and try to figure it out by yourself. It is way more rewarding!

Hint #1 (show): Your assumptions are probably wrong.
Now go back and try to solve it. I’m waiting here.

Hint #2 (show): The assumption that all towers of the same size only differ in color is wrong.

Hint #3 (show): There are two towers which do fit on slots where the other towers of the same size do not fit.

Hint #4 (show): The two special towers are the yellow one of heigh 5 and the orange one of height 6.

Hint #5 (show): The yellow tower of height 5 has to go to position (1,2) and the orange tower of height 6 to (3,2) in my coordinate system.

Even if you uncovered all hints, the puzzle is still far from solved. You can still tinker with it forever.

Spoiler alert: Don’t uncover the solution, unless your are really desperate!

After I had found the two culprits, I adjusted my program by changing the array and inserting two special conditions. Within seconds I had a complete solution of the 36 Cube:

#!/usr/bin/python
COLORS =dict(zip((1 << i for i inrange(6)),('P','Y','O','B','R','G')))
COLORS[False]='X'
used_towers =[0for i inrange(6)]# definition with (1,2) and (3,2) switched
cube =((1,3,4,5,2,0),(2,5,1,4,1,3),(0,1,3,2,5,4),(5,4,0,3,0,2),(4,2,5,0,3,1),(3,0,2,1,4,5))
solution =[[Falsefor x inrange(6)]for x inrange(6)]
used =tuple(set()for i inrange(6))def test_color(pos, solution, used_towers, color, size):
#check if tower of this size and color has already been usedif color & used_towers[size]:
returnFalse#check if tower has already been used in row or column:for i inrange(6):
if color == solution[pos/6][i]: returnFalseif color == solution[i][pos%6]: returnFalse# special conditions for the two special towersif(pos/6, pos%6)==(1,2)and color !=2: returnFalseif(pos/6, pos%6)==(3,2)and color !=4: returnFalsereturnTruedef print_solution(solution):
for i inrange(6):
printzip((COLORS[c]for c in solution[i]),(6 - s for s in cube[i]))def solve(pos, solution, used_towers, best):
if pos ==36: return best, solution
size = cube[pos/6][pos%6]for i inrange(6):
color =1 << i
if test_color(pos, solution, used_towers, color, size):
used_towers[size]= used_towers[size] | color
solution[pos/6][pos%6]= color
if pos > best:
print"#######", pos + 1,"towers placed"
print_solution(solution)
best = pos
best, solution = solve(pos+1, solution, used_towers, best)if best >=35:
return best, solution
solution[pos/6][pos%6]=False
used_towers[size]= used_towers[size] ^ color
return best, solution
solve(0, solution, used_towers,0)

#!/usr/bin/python
COLORS = dict(zip((1 << i for i in range(6)), ('P','Y','O','B','R','G')))
COLORS[False] = 'X'
used_towers = [0 for i in range(6)]
# definition with (1,2) and (3,2) switched
cube = ((1,3,4,5,2,0),
(2,5,1,4,1,3),
(0,1,3,2,5,4),
(5,4,0,3,0,2),
(4,2,5,0,3,1),
(3,0,2,1,4,5))
solution = [[False for x in range(6)] for x in range(6)]
used = tuple(set() for i in range(6))
def test_color(pos, solution, used_towers, color, size):
#check if tower of this size and color has already been used
if color & used_towers[size]:
return False
#check if tower has already been used in row or column:
for i in range(6):
if color == solution[pos/6][i]: return False
if color == solution[i][pos%6]: return False
# special conditions for the two special towers
if (pos/6, pos%6) == (1,2) and color != 2: return False
if (pos/6, pos%6) == (3,2) and color != 4: return False
return True
def print_solution(solution):
for i in range(6):
print zip((COLORS[c] for c in solution[i]), (6 - s for s in cube[i]))
def solve(pos, solution, used_towers, best):
if pos == 36: return best, solution
size = cube[pos/6][pos%6]
for i in range(6):
color = 1 << i
if test_color(pos, solution, used_towers, color, size):
used_towers[size] = used_towers[size] | color
solution[pos/6][pos%6] = color
if pos > best:
print "#######", pos + 1, "towers placed"
print_solution(solution)
best = pos
best, solution = solve(pos+1, solution, used_towers, best)
if best >= 35:
return best, solution
solution[pos/6][pos%6] = False
used_towers[size] = used_towers[size] ^ color
return best, solution
solve(0, solution, used_towers, 0)

After upgrading WordPress to the current version, I could no longer automatically update plugins. This is the error message I got:

Downloading update from http://downloads.wordpress.org/plugin/xxx.zip.

Unpacking the update. Warning: unlink(/…/wp-content/upgrade/xxx.zip) [function.unlink]: No such file or directory in /…/wp-admin/includes/class-wp-upgrader.php on line 146

Open the file wp-config.php in the root directory of your WordPress installation and remove the definition of the WP_TEMP_DIR variable, i.e. a line that looks like this

Ubuntu hat inzwischen eine ziemlich gute WLAN-Unterstützung. Lange Zeit konnte DUKATH nur[1] mit einem VPN-Client genutzt werden, inzwischen geht das auch per WPA. Laut Anleitung des Microbit [PDF] soll man ein Skript schreiben um den Zugang zu nutzen. Unter Ubuntu geht es aber auch etwas einfacher:

Auf das Symbol des Netzwerk-Manager-Applet klicken:

Benutzername und Passwort entsprechen denen bei der Verwendung von VPN.

Fertig!

[1] Der Zugang über das DUKATH Web-Interface sollte nur in Notfällen genutzt werden, da die Verbindung nicht verschlüsselt wird und deshalb einfach abgehört werden kann.