Python Forum

Full Version: project kudoSudoku follows SUDO project
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3
I looked in Lutz's book. All examples he gives concern files, not folders. From that file import that name. Here is my error message:
Error:
Exception in Tkinter callback Traceback (most recent call last): File "C:\Python35\lib\tkinter\__init__.py", line 1558, in __call__ return self.func(*args) File "kudoSudoku\copy_class.py", line 152, in printALL self.printSUDOKU(self.sudoku) File "kudoSudoku\copy_class.py", line 148, in printSUDOKU import solver File "kudoSudoku\solver.py", line 5, in <module> from kudoSudoku import sudoku ImportError: cannot import name 'sudoku'
Hi all ! Is it possible to remove previous imports, when I am at the bottom of the file.
to what end?
I don't know what to do in my sudoku project. When I run solver.py alone, it works very well. It says nothing concernining "from kudoSudoku import sudoku". But when I run the whole project with "python kudoSudoku", error appears saying "impossible to import sudoku".
I repeat that in copy_class.py , instead of exit() I put import solver, followed by exit(). In my mind I should like to have a non-stop project.
sylas, you've gotten this feedback before - you need to provide full (though minimal) code that reproduces the problem.
I should appreciate very much some help. Here the codes of solver.py and that of copy_class.py
#solver.py
import init
import os
import csv
from kudoSudoku import sudoku
from pprint import pprint
filename = os.path.abspath('C:/Users/Sylvain/numbers.csv')
def matrix():
    pass

#def sudoku():
#    pass

with open(filename) as csvfile:
    puzzle = csv.reader(csvfile, delimiter=' ', quotechar='|')
    for row in puzzle:
        print(', '.join(row))
        matrix=row

    for i in range(9):
        matrix[i]=eval(matrix[i])


    print('sylvain')
    print(matrix)
    pprint(matrix)

    table = sudoku(matrix)
    result = table.solve()
    pprint(result)
The second:
#copy_class.py
import csv
import os
import SudokuSolver_solver as Solver
from pprint import pprint#ad
from random import randint
from tkinter import ttk
from tkinter import *
from tkcallasync import tk_call_async, MULTIPROCESSING #origin

class SudokuSolver(Frame):

    sudoku = [["0" for col in range(9)] for row in range(9)]
    solution = [[" " for col in range(9)] for row in range(9)]
    exampleSudoku = [['0','0','0','2','1','0','0','0','0'],
                     ['0','0','7','3','0','0','0','0','0'],
                     ['0','5','8','0','0','0','0','0','0'],
                     ['4','3','0','0','0','0','0','0','0'],
                     ['2','0','0','0','0','0','0','0','8'],
                     ['0','0','0','0','0','0','0','7','6'],
                     ['0','0','0','0','0','0','2','5','0'],
                     ['0','0','0','0','0','7','3','0','0'],
                     ['0','0','0','0','9','8','0','0','0']]


    def __init__(self, parent):
        Frame.__init__(self, parent, name='frame')
        self.parent = parent
        self.initUI()
        self.blankSUDOKU()
        self.sudokudir = os.path.join(os.getcwd(), 'sudokus')

    def initUI(self):
        self.message_txt = StringVar()
        self.time_txt = StringVar()
        self.seconds = 0
        self.minutes = 0
        self.time_txt.set('0{}:0{}'.format(self.minutes, self.seconds))
        self.timer_mode = 'stopped'
        self.disabled = False
        self.values = {}

        self.parent.title('Sudoku Solver')
        self.pack(fill=BOTH, expand=True)

        self.message = Label(self, textvariable=self.message_txt)
        self.message.grid(row=10,column=0,columnspan=8, sticky=E+W)

        self.timer = Label(self,textvariable=self.time_txt)
        self.timer.grid(row=10,column=8,sticky=E+W)

        self.solveBtn = Button(self, text="solve",width=6,command=self.execute_solver)
        self.solveBtn.grid(row=0,column=0)

        self.newBtn = Button(self, text="new",width=6,command=self.blankSUDOKU)
        self.newBtn.grid(row=0,column=1)

        self.initBtn = Button(self, text="init",width=6,command=self.initSUDOKU)
        self.initBtn.grid(row=0,column=2)

        self.startBtn = Button(self, text="start",width=6,command=self.start_timer)
        self.startBtn.grid(row=0,column=3)

        self.checkBtn = Button(self, text="check",width=6,command=self.checkSOLUTION)
        self.checkBtn.grid(row=0,column=6)

        self.saveBtn = Button(self, text="save",width=6,command=self.saveSUDOKU)
        self.saveBtn.grid(row=0,column=7)

        self.printBtn = Button(self, text="print",width=6,command=self.printALL)
        self.printBtn.grid(row=0,column=8)

        self.pbar = ttk.Progressbar(self, mode='indeterminate')
        self.pbar.grid(row=11,column=0, columnspan=9, sticky=W+E)

    # --- clear all fields and delete all values in sudoku[][] and solution[][] --- #
    def blankSUDOKU(self):
        self.message_txt.set('')
        self.reset_timer()
        for row in range(9):
            for col in range(9):
                #self.sudoku[row][col] = ' '#origin
                self.sudoku[row][col] = 0
                #self.solution[row][col] = ' '#origin
                self.sudoku[row][col] = 0
                self.numEntry = Entry(self, width=5, justify=CENTER,
                                 font="Helvetica 12 bold")
                self.values[row,col] = self.numEntry
                self.numEntry.grid(row=row+1,column=col, ipady=5)

    # ----- get a random Sudoku from textfiles ----- #
    def initSUDOKU(self):
        self.blankSUDOKU()
        self.message_txt.set('')
        self.reset_timer()
        Files = []
        valid = True
        for filename in os.listdir(self.sudokudir):
            if filename.startswith('sudoku') and filename.endswith('.txt'):
                Files.append(filename)
        L = len(Files)
        if L < 1:
            self.message_txt.set('No Sudokus saved, yet! Try this one')
            self.sudoku = self.copySUDOKU(self.exampleSudoku)
        else:
            # ----- fill sudoku array with values from textfile ----- #
            R = randint(0, L-1)
            sudokuFile = open(os.path.join(self.sudokudir,Files[R]))
            row, col = 0, 0
            for value in sudokuFile.read():
                if value.isdigit() or value==' ':
                    if value=='0': value = ' ' # zeros can also be used as blanks
                    self.sudoku[row][col] = value
                    col += 1
                    if col==9:
                        if row==8: break
                        row += 1
                        col = 0
            sudokuFile.close()
            valid = self.checkSUDOKU(self.sudoku)[0]
        if not valid:
            self.message_txt.set('%s does not contain a valid sudoku' % Files[R])
        else:
        # ----- make values from random sudoku appear in the GUI ----- #
            for row in range(9):
                for col in range(9):
                    value = self.sudoku[row][col]
                    if value!=' ':
                        self.values[row,col].insert(0,value)
        self.reset_message()

    def printSUDOKU(self, matrix):
        pprint(matrix)
        for i in range(9):
            for j in range(9):
                if matrix[i][j]==' ':
                    matrix[i][j]=0
                else:
                    matrix[i][j]=int(matrix[i][j])

        puzzle=matrix
        print("puzzle")
        pprint(puzzle)
        with open('numbers.csv', 'w', newline='') as csvfile:
            numwriter=csv.writer(csvfile, delimiter=' ', quotechar='|', quoting=csv.QUOTE_MINIMAL)
            numwriter.writerow(puzzle)
        #exit()
        import solver
        exit()

    def printALL(self):
        print('Sudoku:')
        self.printSUDOKU(self.sudoku)
        print('Solution:')
        self.printSUDOKU(self.solution)

    def saveSUDOKU(self):
       CHECK = self.checkSUDOKU(self.solution)
       if CHECK[0] and CHECK[1]:    # check if Sudoku is valid and complete
           filecount = 1    # variable for how many sudoku files are already existing
           if not os.path.exists(self.sudokudir): os.makedirs(self.sudokudir)
           while os.path.isfile(self.path_to("sudoku%s.txt" % filecount)):
               filecount += 1
           sudokuFile = open(self.path_to("sudoku%s.txt" % filecount), 'w')
           solutionFile = open(self.path_to("solution%s.txt" % filecount), 'w')
           # ----- create textfiles for sudoku and the solution ----- #
           for row in range(9):
               for col in range(9):
                   sudokuFile.write(self.sudoku[row][col])
                   solutionFile.write(self.solution[row][col])
               sudokuFile.write('\n')
               solutionFile.write('\n')
           sudokuFile.close()
           solutionFile.close()
           self.message_txt.set('Files saved...')
       else:
           self.message_txt.set('Sudoku must be valid and complete!')
       self.reset_message()

    def copySUDOKU(self, matrix):
        matrix_copy = [[" " for col in range(9)] for row in range(9)]
        for row in range(9):
            for col in range(9):
                matrix_copy[row][col] = matrix[row][col]
        #pprint(matrix_copy)#ad
        return matrix_copy

    # ----- check if user input makes sense -----#
    def checkSUDOKU(self, matrix):
        valid, complete, ctr = True, True, 0
        for row in range(9):
            for col in range(9):
                value = matrix[row][col]
                if value!=' ':
                    matrix[row][col]=' '
                    if not self.consistent(matrix, row, col, value):
                        valid, complete = False, True
                        return valid, complete, row, col
                    matrix[row][col] = value
                    ctr += 1
                else: complete = False
        if ctr<17: valid = False        # Sudoku must include at least 17 clues
        return valid, complete

    # ----- check if solution is valid ----- #
    def checkSOLUTION(self):
        self.getinput(self.solution)
        CHECK = self.checkSUDOKU(self.solution)
        if CHECK[0] and CHECK[1]: self.message_txt.set("Solution correct!")
        elif not CHECK[1]: self.message_txt.set("Sudoku is not complete!")
        elif not CHECK[0]: self.message_txt.set("Mistake at row %s, col %s"
                                      % (CHECK[2], CHECK[3]))
        self.reset_message()

    # ----- write user input into values{} ----- #
    def getinput(self, matrix):
        for row in range(9):
            for col in range(9):
                value = self.values[row,col].get()
                if value=='': matrix[row][col] = ' '
                elif len(value)!=1: matrix[row][col] = ' '
                elif not value.isdigit(): matrix[row][col] = ' '
                elif int(value)<1 or int(value)>9: matrix[row][col] = ' '
                else : matrix[row][col] = value

    # ----- check if this input leads to a valid solution ----- #
    def consistent(self, matrix, row, col, value):
        for i in range(9):
            if matrix[row][i]==value: return False
            if matrix[i][col]==value: return False
        rowStart = row - row%3
        colStart = col - col%3
        for m in range(3):
            for k in range(3):
                if matrix[rowStart+k][colStart+m]==value: return False
        return True

    def path_to(self, name):
        return os.path.join(self.sudokudir, name)

    def execute_solver(self):
        self.getinput(self.sudoku) # user input from GUI -> sudoku array
        if not self.checkSUDOKU(self.sudoku)[0]:    # check if user input makes sense
            self.message_txt.set("This sudoku does not have a solution")
            self.reset_message()
        else:
            if self.disabled:
                self.message_txt.set("warning, It's still calculating...")
                self.reset_message()
                return

            def callback(result):
                self.disabled = False
                status, self.solution, N = result
                self.pbar.stop()
                self.printSUDOKU(self.sudoku)
                self.printSUDOKU(self.solution)
                self.message_txt.set('Solution found! %s backtracks needed' % N if status else 'No Solution found!')
                self.fill_solution()
                self.reset_message(10000)

            self.disabled = True
            self.pbar.start(20)
            tk_call_async(self, Solver.do_solve, args=(self.sudoku),
                     callback=callback, method=MULTIPROCESSING)

    def fill_solution(self):
        for row in range(9):
            for col in range(9):
                self.values[row,col].delete(0,END)
                self.values[row,col].insert(0,self.solution[row][col])

    def start_timer(self):
        if self.timer_mode == 'stopped':
            self.startBtn.configure(text='stop')
            self.timer_mode = 'running'
        elif self.timer_mode == 'running':
            self.startBtn.configure(text='start')
            self.timer_mode = 'stopped'

        def timer():
            if self.timer_mode == 'stopped': return
            if self.seconds == 60:
                self.seconds = 0
                self.minutes += 1
            if self.seconds > 9 and self.minutes > 9:
                self.time_txt.set('{}:{}'.format(self.minutes, self.seconds))
            elif self.seconds > 9 and self.minutes <= 9:
                self.time_txt.set('0{}:{}'.format(self.minutes, self.seconds))
            elif self.seconds <= 9 and self.minutes <= 9:
                self.time_txt.set('0{}:0{}'.format(self.minutes, self.seconds))
            elif self.seconds <= 9 and self.minutes > 9:
                self.time_txt.set('{}:0{}'.format(self.minutes, self.seconds))
            self.seconds += 1
            self.after(1000, timer)

        timer()

    def reset_timer(self):
        self.startBtn.configure(text='start')
        self.minutes = 0
        self.seconds = 0
        self.timer_mode = 'stopped'
        self.time_txt.set('0{}:0{}'.format(self.minutes, self.seconds))

    def reset_message(self,DELAY=5000):
        def reset():
            self.message_txt.set('')
        self.after(DELAY, reset)

Here the error message:
Error:
Exception in Tkinter callback Traceback (most recent call last): File "C:\Python35\lib\tkinter\__init__.py", line 1558, in __call__ return self.func(*args) File "kudoSudoku\copy_class.py", line 153, in printALL self.printSUDOKU(self.sudoku) File "kudoSudoku\copy_class.py", line 148, in printSUDOKU import solver File "kudoSudoku\solver.py", line 5, in <module> from kudoSudoku import sudoku ImportError: cannot import name 'sudoku'
  • what are the names of the two modules.
  • What does your directory structure look like
  • Are you using appropriate __init__.py files, with the topmost including the directory structure
  • is the file sudoku.py within this structure, and included in the topmost __init__.py file?
The name of the project is: kudoSudoku. Nowhere I find "sudoku" file or directoty. kudoSudoku is a directory, not a file. As you told me, I added a __init__.py file in the project.
I merged the two threads as this one and the one with the question of imports are closely related
I came back to SUDO project. So in this project you cannot find "kudoSudoku" nor "sudoku". So in the solver.py, "from kudoSudoku import sudoku", I think it refers to some Library. Remember solver.py alone, works very well.
Pages: 1 2 3