Question
Instructions: Please complete board.py, a3.py and a3_test.py board.py import csv import itertools class Board(): ########################################## #### Constructor ########################################## def __init__(self, filename): #initialize all of the
Instructions:
Please complete board.py, a3.py and a3_test.py
board.py
import csv import itertools
class Board():
########################################## #### Constructor ########################################## def __init__(self, filename):
#initialize all of the variables self.n2 = 0 self.n = 0 self.spaces = 0 self.board = None self.valsInRows = None self.valsInCols = None self.valsInBoxes = None self.unSolved = None
#load the file and initialize the in-memory board with the data self.loadSudoku(filename)
#loads the sudoku board from the given file def loadSudoku(self, filename):
with open(filename) as csvFile: self.n = -1 reader = csv.reader(csvFile) for row in reader:
#Assign the n value and construct the approriately sized dependent data if self.n == -1: self.n = int(len(row) ** (1/2)) if not self.n ** 2 == len(row): raise Exception('Each row must have n^2 values! (See row 0)') else: self.n2 = len(row) self.spaces = self.n ** 4 self.board = {} self.valsInRows = [set() for _ in range(self.n2)] self.valsInCols = [set() for _ in range(self.n2)] self.valsInBoxes = [set() for _ in range(self.n2)] self.unSolved = set(itertools.product(range(self.n2), range(self.n2)))
#check if each row has the correct number of values else: if len(row) != self.n2: raise Exception('Each row mus\t have the same number of values. (See row ' + str(reader.line_num - 1) + ')')
#add each value to the correct place in the board; record that the row, col, and box contains value for index, item in enumerate(row): if not item == '': self.board[(reader.line_num-1, index)] = int(item) self.valsInRows[reader.line_num-1].add(int(item)) self.valsInCols[index].add(int(item)) self.valsInBoxes[self.rcToBox(reader.line_num-1, index)].add(int(item)) self.unSolved.remove((reader.line_num-1, index))
########################################## #### Move Functions - YOUR IMPLEMENTATIONS GO HERE ##########################################
#gets the unsolved space with the most current constraints def getMostConstrainedUnsolvedSpace(self): pass
#returns True if the move is not blocked by any constraints def isValidMove(self,space,val): pass
#makes a move, records that its in the row, col, and box, and removes the space from unSolved def makeMove(self, space, val): pass
#removes the move, its record in its row, col, and box, and adds the space back to unSolved def removeMove(self, space, val): pass
########################################## #### Utility Functions ##########################################
#converts a given row and column to its inner box number def rcToBox(self, row, col): return self.n * (row // self.n) + col // self.n
#prints out a command line representation of the board def print(self): for r in range(self.n2): #add row divider if r % self.n == 0 and not r == 0: print(" " + "---" * self.n2)
row = ""
for c in range(self.n2):
if (r,c) in self.board: val = self.board[(r,c)] else: val = None
#add column divider if c % self.n == 0 and not c == 0: row += " | " else: row += " "
#add value placeholder if val is None: row += "_" else: row += str(val) print(row)
a3.py
from board import Board
class Solver:
########################################## #### Constructor ########################################## def __init__(self,filename): self.board = Board(filename) self.solve()
########################################## #### Solver ##########################################
#recursively selects the most constrained unsolved space and attempts #to assign a value to it # #upon completion, it will leave the board in the solved state (or original #state if a solution does not exist) def solve(self): pass
if __name__ == "__main__":
#change this to the input file that you'd like to test s = Solver('testBoard_dastardly.csv')
Please create at least one additional test for each section below.
a3_test.py
import unittest
def TestFactory(module):
class TestA3(unittest.TestCase):
def __init__(self, test): super(TestA3,self).__init__(test)
#bind module functions to tester class self.Board = module.Board self.Solver = module.Solver
################################# # Board.makeMove #################################
def test_makeMove(self):
b = self.Board("testBoard_singletonsOnly.csv")
b.makeMove((0,0), 3) self.assertSequenceEqual({3,7,4,8,1,9}, b.valsInCols[0]) self.assertSequenceEqual({3, 4, 5}, b.valsInRows[0]) self.assertSequenceEqual({2,3,4,5,7,8,9}, b.valsInBoxes[0]) self.assertNotIn((0,0), b.unSolved) self.assertEqual(b.board[(0,0)], 3)
b.makeMove((8, 8), 1) self.assertSequenceEqual({1,2,3,4,6,7}, b.valsInCols[8]) self.assertSequenceEqual({1,6,9}, b.valsInRows[8]) self.assertSequenceEqual({1,2,3,4,5,6,9}, b.valsInBoxes[8]) self.assertNotIn((8, 8), b.unSolved) self.assertEqual(b.board[(8, 8)], 1)
b.makeMove((4, 4), 5) self.assertSequenceEqual({1, 4, 5}, b.valsInCols[4]) self.assertSequenceEqual({2,3,4,5,6,7,8}, b.valsInRows[4]) self.assertSequenceEqual({8,1,4,5,6}, b.valsInBoxes[4]) self.assertNotIn((4,4), b.unSolved) self.assertEqual(b.board[(4,4)], 5)
################################# # Board.removeMove #################################
def test_removeMove(self):
b = self.Board("testBoard_med.csv")
b.removeMove((0, 0), 5) self.assertSequenceEqual({8,3}, b.valsInCols[0]) self.assertSequenceEqual({9,2,4,7}, b.valsInRows[0]) self.assertSequenceEqual({8,7}, b.valsInBoxes[0]) self.assertIn((0, 0), b.unSolved) self.assertNotIn((0,0), b.board)
b.removeMove((5, 3), 8) self.assertSequenceEqual({2,4,6}, b.valsInCols[3]) self.assertSequenceEqual({9, 3,4}, b.valsInRows[5]) self.assertSequenceEqual({5}, b.valsInBoxes[4]) self.assertIn((5, 3), b.unSolved) self.assertNotIn((5, 3), b.board)
b.removeMove((8, 8), 2) self.assertSequenceEqual({6,7}, b.valsInCols[8]) self.assertSequenceEqual({8,3,6,7}, b.valsInRows[8]) self.assertSequenceEqual({8,6}, b.valsInBoxes[8]) self.assertIn((8, 8), b.unSolved) self.assertNotIn((8, 8), b.board)
################################# # Board.isValidMove ################################# def test_isValidMove(self): b = self.Board("testBoard_med.csv")
self.assertFalse(b.isValidMove((1, 2), 5)) self.assertFalse(b.isValidMove((1, 2), 8)) self.assertFalse(b.isValidMove((1, 2), 9)) self.assertFalse(b.isValidMove((4, 3), 5)) self.assertFalse(b.isValidMove((8, 4), 5)) self.assertFalse(b.isValidMove((6, 4), 4)) self.assertFalse(b.isValidMove((8, 8), 8))
self.assertTrue(b.isValidMove((0, 8), 1)) self.assertTrue(b.isValidMove((4, 1), 5)) self.assertTrue(b.isValidMove((4, 8), 5)) self.assertTrue(b.isValidMove((6, 8), 1)) self.assertTrue(b.isValidMove((6, 8), 3))
################################# # Board.getMostConstrainedUnsolvedSpace ################################# def test_getMostConstrainedUnsolvedSpace(self):
a = self.Board("testBoard_singletonsOnly.csv") a_space = a.getMostConstrainedUnsolvedSpace() self.assertIn(a_space, [(4,8), (6,6), (4,0), (2,2)])
b = self.Board("testBoard_med.csv") b_space = b.getMostConstrainedUnsolvedSpace() self.assertIn(b_space, [(8,2), (0,6)])
c = self.Board("testBoard_hard.csv") c_space = c.getMostConstrainedUnsolvedSpace() self.assertIn(c_space, [(5, 6), (3, 2)])
d = self.Board("testBoard_dastardly.csv") d_space = d.getMostConstrainedUnsolvedSpace() self.assertIn(d_space, [(7, 8), (1, 0), (6,4), (1,5), (2,4), (7,3)])
################################# # Solver.solve ################################# def test_solve_easy(self):
a = self.Solver("testBoard_singletonsOnly.csv") a_solved = self.Board("testBoard_singletonsOnly_solution.csv") self.assertDictEqual(a.board.board, a_solved.board)
def test_solve_med(self): b = self.Solver("testBoard_med.csv") b_solved = self.Board("testBoard_med_solution.csv") self.assertDictEqual(b.board.board, b_solved.board)
def test_solve_hard(self): c = self.Solver("testBoard_hard.csv") c_solved = self.Board("testBoard_hard_solution.csv") self.assertDictEqual(c.board.board, c_solved.board)
def test_solve_dastardly(self): d = self.Solver("testBoard_dastardly.csv") d_solved = self.Board("testBoard_dastardly_solution.csv") self.assertDictEqual(d.board.board, d_solved.board)
return TestA3
if __name__ == "__main__":
#CHANGE THE IMPORT TO BE THE MAIN FILE NAME (i.e., a1) mod = __import__("a3")
unittest.TextTestRunner(verbosity=0).run( unittest.TestLoader() .loadTestsFromTestCase(testCaseClass=TestFactory(mod)))
4.2.1 Board.makeMove This function should take a space tuple (r, c) where r and c are a row and column index respectively and a valid value assignment for the space. It should: 1. Save the value in board at the appropriate location 2. Record that the value is in now in the appropriate row, column, and box 3. Remove the space from unSolved 4.2.2 Board.removeMove This function should take a space tuple (r, c) where r and c are a row and column index respectively and a valid value assignment for the space. It should: 1. Remove the value from board at the appropriate location 2. Record that the value is no longer in the appropriate row, column, and box 3. Add the space to unSolved 4.2.3 Board.isValidMove This function should take a space tuple (r, c) where r and c are a row and column index respectively and a valid value assignment for the space. It should return True iff placing the value in the indicated space does not conflict with any of the constraints of Sudoku. 4.2.1 Board.makeMove This function should take a space tuple (r, c) where r and c are a row and column index respectively and a valid value assignment for the space. It should: 1. Save the value in board at the appropriate location 2. Record that the value is in now in the appropriate row, column, and box 3. Remove the space from unSolved 4.2.2 Board.removeMove This function should take a space tuple (r, c) where r and c are a row and column index respectively and a valid value assignment for the space. It should: 1. Remove the value from board at the appropriate location 2. Record that the value is no longer in the appropriate row, column, and box 3. Add the space to unSolved 4.2.3 Board.isValidMove This function should take a space tuple (r, c) where r and c are a row and column index respectively and a valid value assignment for the space. It should return True iff placing the value in the indicated space does not conflict with any of the constraints of SudokuStep by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started