{"id":1797,"date":"2014-10-29T10:49:38","date_gmt":"2014-10-29T16:49:38","guid":{"rendered":"http:\/\/www.mooreds.com\/wordpress\/?p=1797"},"modified":"2014-10-10T14:03:53","modified_gmt":"2014-10-10T20:03:53","slug":"python-problem","status":"publish","type":"post","link":"https:\/\/www.mooreds.com\/wordpress\/archives\/1797","title":{"rendered":"Python Minesweeper Programming Problem"},"content":{"rendered":"<p>At an interview, I was asked to build a python program, using TDD, which would output the results of a <a href=\"http:\/\/minesweeperonline.com\/#\">minesweeper game<\/a>.\u00a0 Not a fully functional game, just a small program that would take an array of bomb locations and print out a map of the board with all values exposed.<\/p>\n<p>So, if you have a 3&#215;3 board, and there is a bomb in each corner, it would print out something like this:<\/p>\n<pre>x 2 x\r\n2 4 2\r\nx 2 x\r\n<\/pre>\n<p>Or if you have a 3&#215;3 board and there is only a bomb in the upper left corner, it would print out something like this:<\/p>\n<pre>x 1 0\r\n1 1 0\r\n0 0 0\r\n<\/pre>\n<p>I did not complete the task in the allotted time, but it was a fun programming exercise and I hope illuminating to the interviewers. I actually took it home and finished it up. Here&#8217;s the full text of the program:<\/p>\n<pre>\r\nclass Board:\r\n        def __init__(self, size = 1, bomblocations = []):\r\n\t\tself._size = size\r\n\t\tself._bomblocations = bomblocations\r\n    \t\r\n\tdef size(self):\r\n\t\treturn self._size\r\n    \t\r\n\tdef _bombLocation(self,location):\r\n                for onebomblocation in self._bomblocations:\r\n                \tif onebomblocation == location:\r\n\t\t\t\treturn 'x'\r\n\r\n\tdef _isOnBoard(self,location):\r\n\t\tif location[0] =self._size:\r\n\t\t    \treturn False\r\n\t\tif location[1] &gt;=self._size:\r\n\t\t    \treturn False\r\n\t\treturn True\r\n\r\n\tdef whatsAt(self,location):\r\n\t\tif self._bombLocation(location) == 'x':\r\n\t\t\treturn 'x'\r\n\t\tif not self._isOnBoard(location):\r\n\t\t\treturn None\r\n\t\treturn self._numberOfBombsAdjacent(location)\r\n\r\n\tdef _numberOfBombsAdjacent(self,location):\r\n\t\tbombcount = 0\r\n\t\t# change x, then y\r\n\t\tcurrx = location[0] \r\n\t\tcurry = location[1] \r\n\t\tfor xincrement in [-1,0,1]:\r\n\t\t\txtotest = currx + xincrement\r\n\t\t\tfor yincrement in [-1,0,1]:\r\n\t\t\t\tytotest = curry + yincrement\r\n\t\t\t\t#print 'testing: '+ str(xtotest) + ', '+str(ytotest)+ ', '+str(bombcount)\r\n\t\t\t\tif not self._isOnBoard([xtotest,ytotest]):\r\n\t\t\t\t\tcontinue\t\r\n\t\t\t\tif self._bombLocation([xtotest,ytotest]) == 'x':\r\n\t\t\t\t\tbombcount += 1\r\n\t\treturn bombcount\r\n\r\n\tdef printBoard(self):\r\n\t\tx = 0\r\n\t\twhile x &lt; self._size:\r\n\t\t\ty = 0\r\n\t\t\twhile y &lt; self._size:\r\n\t\t\t\tprint self.whatsAt([x,y]),\r\n\t\t\t\ty += 1\r\n\t\t\tx += 1\r\n\t\t\tprint\r\n\t\t\t\t\r\ndef main():\r\n\tboard = Board(15,[[0,1],[1,2],[2,4],[2,5],[3,5],[5,5]])\r\n\tboard.printBoard()\r\n\r\nif __name__ == \"__main__\": \r\n\tmain()\r\n<\/pre>\n<p>And the tests:<\/p>\n<pre>import unittest\r\nimport app\r\n\r\nclass TestApp(unittest.TestCase):\r\n\r\n    def setUp(self):\r\n    \tpass\r\n\r\n    def test_board_creation(self):\r\n\r\n        newboard = app.Board()\r\n        self.assertIsNotNone(newboard)\r\n\r\n    def test_default_board_size(self):\r\n     \tnewboard = app.Board()\r\n        self.assertEqual(1, newboard.size())\t\r\n\r\n    def test_constructor_board_size(self):\r\n     \tnewboard = app.Board(3)\r\n        self.assertEqual(3, newboard.size())\t\r\n\r\n    def test_board_with_bomb(self):\r\n     \tnewboard = app.Board(3,[[0,0]])\r\n        self.assertEqual('x', newboard.whatsAt([0,0]))\t\r\n\r\n    def test_board_with_n_bombs(self):\r\n     \tnewboard = app.Board(4,[[0,0],[3,3]])\r\n        self.assertEqual('x', newboard.whatsAt([0,0]))\t\r\n        self.assertEqual('x', newboard.whatsAt([3,3]))\t\r\n\r\n    def test_board_with_bomb_check_other_spaces_separated_bombs(self):\r\n     \tnewboard = app.Board(4,[[0,0],[3,3]])\r\n        self.assertEqual(1, newboard.whatsAt([0,1]))\t\r\n        self.assertEqual(1, newboard.whatsAt([1,0]))\t\r\n        self.assertEqual(1, newboard.whatsAt([1,1]))\t\r\n        self.assertEqual(0, newboard.whatsAt([1,2]))\t\r\n        self.assertEqual(0, newboard.whatsAt([2,1]))\t\r\n        self.assertEqual(1, newboard.whatsAt([3,2]))\t\r\n        self.assertEqual(1, newboard.whatsAt([2,3]))\t\r\n        self.assertEqual(1, newboard.whatsAt([2,2]))\t\r\n\r\n    def test_check_other_spaces_contiguous_bombs(self):\r\n     \tnewboard = app.Board(4,[[0,1],[0,0]])\r\n        self.assertEqual(1, newboard.whatsAt([0,2]))\t\r\n        self.assertEqual(2, newboard.whatsAt([1,0]))\t\r\n        self.assertEqual(0, newboard.whatsAt([2,1]))\t\r\n\r\n    def test_off_the_board(self):\r\n     \tnewboard = app.Board(3,[[0,0],[1,2]])\r\n        self.assertEqual(None, newboard.whatsAt([3,3]))\t\r\n<\/pre>\n<p>This was written in python 2.7, and reminded me of the pleasure of small, from the ground up software (as opposed to gluing together libraries to achieve business objectives, which is what I do a lot of nowadays).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>At an interview, I was asked to build a python program, using TDD, which would output the results of a minesweeper game.\u00a0 Not a fully functional game, just a small [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,58],"tags":[],"class_list":["post-1797","post","type-post","status-publish","format-standard","hentry","category-dynamic-languages","category-testing"],"_links":{"self":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/1797","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/comments?post=1797"}],"version-history":[{"count":2,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/1797\/revisions"}],"predecessor-version":[{"id":1799,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/posts\/1797\/revisions\/1799"}],"wp:attachment":[{"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/media?parent=1797"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/categories?post=1797"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mooreds.com\/wordpress\/wp-json\/wp\/v2\/tags?post=1797"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}