CodeRetreat2012

CodeRetreat2012 was a blast! I really enjoyed it. This was my first CodeRetreat.

CodeRetreat is a hackathon made of sessions, in every session programmers are pairing and trying to solve Conway’s Game of Life. In every session there is a restriction about the development method.

In this note I’ll try to sum my thoughts about CodeRetreat2012 day that took part in Tel-Aviv-Jaffa in the office of EBay-Israel (Who host this event second year) and by the generous and wonderful hosting of Yonatan Bergman and Aviv Ben-Yosef.

There where six sessions in this day, I used python on most of them. Here are my notes:

Session – 0 – Warm up
Paired with: None
Restrictions: None
I woke up late 😛

Session – 1
Paired with: Uri Sivan
Restrictions: A function must not receive primitives.
This session result in a code larger then needed with 3 classes (Life, Grid, Coord). However, those extra classes caused every method to work exactly in its own domain. Coord had a method yielding neighbor coordinates. Grid wrapped the matrix and had a method that yields all coordinates. Life implemented only methods regarding the game of life. Our code distribution was very ‘sane’ and made a lot of sense, way more then expected.
A trick Uri came up with was to use a larger matrix then needed in order to handle offset overflows.

Session – 2
Paired with: Roy Rothenberg.
Restrictions: Ping-Pong Test-Driven-Development and no function larger then 4 lines of code.
This was my first time using TDD methodology so I can’t say I fully grasped the gist of it. For the most part we just focused on not exceeding the 4 lines limit, and boy did that escalated quickly… It turned into a 1-liner contest. every line of code was merged into a 1 liner, and when bugs occurred it was hell to find where exactly.
A trick Roy came up with was the Pythonic trinary operator(aka ?:) form: a = (4 == 5) and "yes" or "God damn!"

Session – 3 – The evil mute programmer.
Paired with: Elad Mallal.
Restrictions: TDD when one is the tester and the other is the developer. The developer should pass all tests without creating any real useful code (hence the Evil) and NO COMMUNICATION BETWEEN THEM IS ALLOWED.
Elad was the tester and I was the programmer. Even though it was fun it was not very productive. Seeing Elad’s tests I think I finally understood the idea behind TDD and it power. Elad’s simple tests forced me into a strict design he had planned.

Session – 4 – The best session!
Paired with: Igal Kreichman
Restrictions: No return statements allowed.
The no return statement restriction caused us to save the return values as class members – in fact it redefined the domain of every class. The final code was, by my opinion, the best code I worked on during the whole day and I bring it here after a minor bugfix 🙂

import random

"""
@date: December 8th 2012
"""
class Cell():
	def __init__(self, x, y, maxx, maxy):
		self.x = x
		self.y = y
		self.maxx = maxx
		self.maxy = maxy
		self.neighbours = 0
		
	def calc_neighbours(self, old_state):
		self.neighbours = 0
		for i in xrange(max(0, self.x -1), min (self.maxx, self.x+2)):
			for j in xrange(max(0, self.y -1), min(self.maxy, self.y+2)):
				if i == self.x and j == self.y:
					continue
				if isinstance(old_state[i][j], LiveCell):
					self.neighbours += 1
		
	def calc_new_state(self):
		pass

	def next_gen(self, old_state, new_state):
		self.calc_neighbours(old_state)
		self.calc_new_state()
		new_state[self.x][self.y] = self.new_state

class DeadCell(Cell):
	def __init__(self, x, y, maxx, maxy):
		Cell.__init__(self, x, y, maxx, maxy)

	def calc_new_state(self):
		self.new_state = (self.neighbours == 3) and LiveCell(self.x, self.y, self.maxx, self.maxy) or DeadCell(self.x, self.y, self.maxx, self.maxy)

class LiveCell(Cell):
	def __init__(self, x, y, maxx, maxy):
		Cell.__init__(self, x, y, maxx, maxy)
	
	def calc_new_state(self):
		self.new_state = (self.neighbours in [2,3]) and LiveCell(self.x, self.y, self.maxx, self.maxy) or DeadCell(self.x, self.y, self.maxx, self.maxy)


class Board():
	def __init__(self, dim, lives = []):
		self.dim = dim
		self.grid = [[DeadCell(i, j, dim, dim) for j in xrange(dim)] for i in xrange(dim)]
	
		density = len(lives)
		for i in xrange(dim):
			for j in xrange(dim):
				if random.choice(xrange(density)) == 0:
					self.grid[i][j] = LiveCell(i,j,dim,dim) 
		"""
		for l in lives:
			self.grid[l[0]][l[1]] = LiveCell(l[0],l[1],dim,dim)
		"""	

	def print_it(self):
		printval = ""
		for i in xrange(self.dim):
			printval += "\n"
			for j in xrange(self.dim):
				printval += "." if isinstance(self.grid[i][j], DeadCell) else "X"

		print printval
		print "---" * 5

	def step(self):
		
		new_grid = [[DeadCell(i, j, self.dim, self.dim) for i in xrange(self.dim)] for j in xrange(self.dim)]

		for i in xrange(self.dim):
			for j in xrange(self.dim):
				self.grid[i][j].next_gen(self.grid, new_grid)

		self.grid = new_grid


def main():
	b = Board(6, [(2,2),(2,3),(2,4),(2,5)])
	b.print_it()
	b.step()
	b.print_it()

main()

Session – 5 – Freestyle
Paired with: Anton Kucherov
Restriction: None
Extras: Matrices are not allowed and unlimited board.
Each of those extra’s we took upon ourselves may sounds hard but it’s quite the opposite. Unlimited boards does not need an overflow-safety code and without using matrices all one needs is to save a list (or a dictionary) of the ‘alive’ cells. It took us 17 minutes to finish this code and another 10 to improve it. It’s not very beautiful, but it was fun nonetheless. So here is our implementation for Conway’s Game of Life with no matrices:

def produce_deadlist(lives):
	dead_dict = {} 
	for l in lives.keys():
		count = 0
		for xx in [-1,0,1]:
			for yy in [-1,0,1]:
				(x,y) = (l[0] + xx, l[1] + yy)
				p = (x,y)
				if xx == 0 and yy == 0:
					continue
				if p in lives.keys():
					lives[p] += 1
				else:
					if not p in dead_dict.keys():
						dead_dict[p] = 1
					else:
						dead_dict[p] += 1
	return dead_dict

def main():

	lives = [(-1,1),(-1,2),(-1,3)]
	
	for i in range(10):
		lives = step(lives)
		print lives


def step(lives):
	lives_dict = {}
	for live in lives:
		lives_dict[live] = 0
	
	dead_dict = produce_deadlist(lives_dict)
	new_lives = []
	for l in lives:
		if lives_dict[l] in [2,3]:
			new_lives.append(l)

	for d in dead_dict.keys():
		if dead_dict[d] in [3]:
			new_lives.append(d)

	return new_lives

main()

Here are a couple of recommendations for people going to a CodeRetreat event:
* Leave the esoteric editor configurations at home or at least bring another ‘clean’ editor
* Don’t be shy – try to develop in a language you are not familiar with.
* Don’t use Visual Studio unless you have an i7 and SSD drive.

See ya next year!

! Photos are taken from Aviv Ben-Yosef and Yonatan Bergman‘s instagram accounts and I do not hold any rights of those photos.

About accessomat

technical blog about things i do and working on
This entry was posted in Uncategorized and tagged , , , , , , , . Bookmark the permalink.

Leave a comment