0
\$\begingroup\$

There are quite a lot of Python Sudoku solvers on this site, but my question is more about style , structure, design and (if I can coin a phrase) Pythonicity (ie is it Pythonic) rather than specifically how I can improve the Sudoku solver. The code just happens to be for that. (They're good first projects..). I'm trying to get into good habbits early.

My questions are:

  • Am I going over the top in my comments ?

  • Am I going about things in a Pythonic manner or can some of what I'm trying to do be done more Pythonically ? (I come from a C++ background)

  • Should I be doing file-handling in the constructor ?

  • Possibly exception handling round the file handling I haven't tested for exceptions..

  • Any design flaws as yet (it's only the constructor, but hey disasters can start early)

There is a comment that starts DON'T THINK I CAN USE THIS and it's concerning whether I can do file handling with 'with', I don't think I can in this situation.

Finally: Is the code clear enough to communicate what I'm trying to achieve without any further info ?


    class a_square:
        '''
        A single Sudoku square, answers will be a list containing a range
        1 to and including 9 as possible answers. When the list gets down
        to 1 element, then that'll be that square solved. And as possible
        answers are whittled away, thus answers elements will be deleted.
        '''
        def __init__(self,  answers, row, col):
            self.answers = answers
            self.row = row
            self.col = col
    
    class Board:
        '''
        The main class containing all 81 squares and will contain other
        methods such as Solve() etc. Probably some more 'private' methods
        too
        '''
        SQUARES_PER_SIDE = 9
        all_squares = []
    
        def __init__(self):
            '''
            Constructor reads in 9 user strings, each character/number being
            the number in that column. Each string being nine characters and
            thus nine squares. Input a string nine times and there's the 81
            squares in a sudoku board. Any character can be used to signify an
            unknown or empty square. Eg:
                   "12---4---"
                   "--5--6-8-"
                   "----6579-"
                   "---------"
                   "--1-----2"
                   "---------"
                   "6---8-23-"
                   "---------"
                   "---------"
            '''
    # Can't load and save at the same time
            flag = None
            pre_saved = input("Load a pre-saved board (y/n): ")
            if pre_saved is "y":
                flag = "r"
    
            else:
                choice = input("Do you want to save this board for later (y/n): ")
                if choice is "y":
                    flag = "w"
    
            self.__recieve_rows_of_squares(flag)
    
        def __recieve_rows_of_squares(self, flag):
            '''
            Each row of squares is represented by a string, each character being
            the value of the square. 'Row Strings' can be either loaded from pre-
            existing file or saved to a file or just inputed with no file handling:
            flag will be passed to open() and be "w"/"r"/None.
            Files are in directory 'boards/' and have file ext '.sod'
            '''
            if flag is not None:
                stateStr = "LOADED"
                if flag == "w":
                    stateStr = "saved"
                boardname = input("Please input board name to be " + stateStr + ": ")
                boardname = "./boards/" + boardname + ".sod"
                board_file = open(boardname, flag)
    
    # DON'T THINK I CAN USE THIS open('output.txt', flag) as board_file:
    
    # Reading input strings and adding squares to the list of all_squares
            row_count = 0
            while(row_count < self.SQUARES_PER_SIDE):
    
                if flag is "r":
                    digitsStr = board_file.readline().rstrip()
    
                else:
                    digitsStr = input(("Digits for row {} ".format(row_count+1)))
    
                if len(digitsStr) != self.SQUARES_PER_SIDE:
                    print("input for row should be 9 digits long")
                else:
                    if flag is "w":
                        board_file.writelines((digitsStr + "\n"))
                    self.__turn_string_into_squares(row_count, digitsStr)
                    row_count += 1
    
            if flag is not None:
                board_file.close()
    
        def __turn_string_into_squares(self, a_row, a_string):
    
    # You can have any char as a space eg 1..2--0%5 will => 100200005
                column = 0
                for a_numStr in a_string:
                    temp = a_square([range(1, 10)], a_row, column)
                    if a_numStr.isdigit():
                        if a_numStr is not "0": # Zeros can be blank squares too
                            temp = a_square([int(a_numStr)], a_row, column)
                    self.all_squares.append(temp)
                    column += 1
    
    
    a_board = Board()
    print("finished") # This line is just for debugging purposes

a_board will contain 81 squares of either an answer or a list of 1 to 9 possible answers depending on 9 input strings of nine characters long from the user. Each string will contain numbers, or any other character to denote an unsolved square.

\$\endgroup\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.