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
Hi all ! I replaced blanks by zeros; tkinter figure always appears. When I type numbers on the figure(clicking "init" first) I should like the puzzle been created. So with that puzzle I run init.py(previous __init__.py) and i have the solution on command prompt.
1. Without tkinter the files are: __main__.py and init.py
2. With tkinter the files are : __main__.py, copy_class.py, SudokuSolver_solver.py, and (the fourth) tkcallasync.py.
Please call the folder: kudoSudoku
Here are the 5 files:
__main__.py
"""
#SUDOKU WITHOUT TKINTER TO USE WITH init.py
from kudoSudoku import sudoku
#puzzle = [[0,2,4,0],[1,0,0,3],[4,0,0,2],[0,1,3,0]]
puzzle=[[0,0,9,0,0,0,5,6,2],[0,0,0,9,0,0,0,0,0],[2,0,0,0,0,3,1,7,0],[0,0,0,1,9,0,7,8,0],[0,7,5,0,0,0,0,0,0],[0,0,0,2,5,0,6,3,0],
[4,0,0,0,0,8,2,9,0],[0,0,0,7,0,0,0,0,0],[0,0,8,0,0,0,3,5,7]]
table = sudoku(puzzle)
result = table.solve()
print(result)

"""
# __main__.py
from multiprocessing import freeze_support#origin

if __name__ == '__main__':#origin
    freeze_support()#origin
    #import SudokuSolver_class as SudokuSolver#origin
    import copy_class as SudokuSolver
    from tkinter import Tk#origin

    def main():#origin
        root = Tk()#origin
        app = SudokuSolver.SudokuSolver(root)#origin
        root.mainloop()#origin

    main()#origin
2. init.py
                                                                               #init.py
from copy import deepcopy
from time import clock

class sudoku:
    def __init__(self,vals):
        self.__n = len(vals)
        self.__rows = []
        self.__cols = []
        self.__eles = []
        self.blocks = []
        self.isChanged = False
        self.solved = 0
        self.expired = False
        self.Iterations = 0
        self.guesses = 0

        for i in range(self.__n):
            x = subTable(self.__n,self)
            y = subTable(self.__n,self)
            z = subTable(self.__n,self)
            self.__rows.append(x)
            self.__cols.append(y)
            self.blocks.append(z)

        for i in range(self.__n):
            for j in range(self.__n):
                k = int((self.__n)**(1/2.0))
                b = k*(i//k) + (j//k)
                e = element(self,self.__rows[i],self.__cols[j],self.blocks[b])
                if(vals[i][j] != 0):
                    e.setVal(vals[i][j])
                self.__rows[i].setVal(j,e)
                self.__cols[j].setVal(i,e)
                self.blocks[b].setVal( k*(i%k) + j%k,e)
                self.__eles.append(e)

        for i in self.__eles:
            for n in range(self.__n):
                if(i.getVal() == 0):
                    if not (i.myRow().contains(n+1) or i.myCol().contains(n+1) or i.myBlock().contains(n+1)):
                        i.markPoss(n+1)

    def __markOut(self):
        for i in self.__rows:
            i.reposs()

        for i in self.__cols:
            i.reposs()

        for i in self.blocks:
            i.reposs()

    def solve(self):
        clock()
        self.Iterations += 1
        self.isChanged = False
        self.__markOut()
        if(self.isChanged):
            return self.solve()
        else:
            if self.expired: #wrong puzzle
                return {
                    'done' : False,
                    'iterations' : self.Iterations,
                    'guesses' : self.guesses,
                    'timeTaken' : clock(),
                    'solution' : None}
            elif(self.solved == self.__n**2): #solved
                return {
                    'done' : True ,
                    'iterations' : self.Iterations,
                    'guesses' : self.guesses,
                    'timeTaken' : clock(),
                    'solution' : self.__myTable() }
            else: #unsolved
                return self.__guessOne()

    def __myTable(self):
        table = []
        for i in self.__rows:
            row = []
            for ele in i.myeles():
                if(ele.getVal() == 0):
                    row.append(" ")
                else:
                    row.append(ele.getVal())
            table.append(row)
        return table

    def __guessOne(self):
        self.guesses += 1
        selected = 0
        itrs = []
        for i in range(len(self.__eles)):
            posses = self.__eles[i].getPoss()
            if(len(posses) != 0):
                selected = i
                itrs = posses
                break

        for i in itrs:
            newTab = deepcopy(self)
            newTab.__eles[selected].setVal(i)
            ss = newTab.solve()
            if(ss['done']):
                return ss


class subTable:

    def __init__(self,n,table):
        self.__n = n
        self.__eles = [None for i in range(n)]
        self.__vals = []
        self.__table = table

    def setVal(self,i,val):
        self.__eles[i] = val
        if(val.getVal() != 0):
            self.__vals.append(val.getVal())

    def myeles(self):
        return self.__eles

    def contains(self,val):
        return val in self.__vals

    def addVal(self,val):
        if not val in self.__vals:
            self.__vals.append(val)

        for e in self.__eles:
            if(e != None):
                e.removePoss(val)

    def reposs(self):
        poss = []
        for i in self.__eles:
            if(i.getVal() == 0):
                poss.append(i.getPoss())
            else:
                poss.append([i.getVal()])
        vals = self.solveCons(poss)['val']
        for i in range(len(vals)):
            poss = vals[i]
            if(len(poss) == 1):
                if(poss[0] != self.__eles[i].getVal() and self.__eles[i].getVal() != 0):
                    print(self.__eles[i].getVal(),"Errorrr",poss[0])
                    self.__table.isChanged = True
                elif(poss[0] != self.__eles[i].getVal() and self.__eles[i].getVal() == 0):
                    self.__eles[i].setVal(poss[0])
                    self.__table.isChanged = True
            else:
                posses = self.__eles[i].getPoss()
                for poss in posses:
                    if not poss in vals[i]:
                        self.__eles[i].removePoss(poss)
                        self.__table.isChanged = True

    def solveCons(self,row):
        if(len(row) == 1):
            return { "exists" : True , "val" : row}
        else:
            head = row[0]
            tail = row[1:]
            headfinal = []
            tailfinal = [[] for k in range(len(tail))]
            for ele in head:
                reformed_tail = list(map(lambda x : [e for e in x if e != ele],tail))
                tail_val = self.solveCons(reformed_tail)
                if(tail_val['exists'] and (not ([] in tail_val['val']))):
                    headfinal.append(ele)
                    tailfinal = concatAll(tailfinal,tail_val['val'])
            if(len(head) ==0):
                return {'exists' : False , 'val' : None}
            else:
                return {'exists' : True , 'val' : [headfinal] + tailfinal}


class element:
    def __init__(self,table,row,col,block):
        self.__val = 0
        self.__poss = []
        self.__row = row
        self.__col = col
        self.__block = block
        self.__table = table

    def setVal(self,val):
        if(self.__row.contains(val) or self.__col.contains(val) or self.__block.contains(val)):
            self.__table.expired = True
        self.__val = val
        self.__table.solved += 1
        self.clearPoss()
        self.__block.addVal(val)
        self.__col.addVal(val)
        self.__row.addVal(val)

    def myRow(self):
        return self.__row

    def myCol(self):
        return self.__col

    def myBlock(self):
        return self.__block

    def markPoss(self,val):
        if not val in self.__poss:
            self.__poss.append(val)

    def clearPoss(self):
        self.__poss = []

    def getVal(self):
        return self.__val

    def getPoss(self):
        return self.__poss

    def removePoss(self,val):
        if val in self.__poss:
            self.__poss.remove(val)
            if(len(self.__poss) == 1 and self.__val == 0):
                self.setVal(self.__poss[0])



def concatAll(lists1,lists2):
    lists0 = []
    for i in range(len(lists1)):
        resulting_list = list(lists1[i])
        resulting_list.extend([x for x in lists2[i] if x not in lists1[i]])
        lists0.append(resulting_list)
    return lists0
3. copy_class.py
                                                                         #copy_class.py

import os
import SudokuSolver_solver as Solver
from random import randint
from tkinter import ttk
from tkinter import *
from tkcallasync import tk_call_async, MULTIPROCESSING #origin
#import tkcallasync


class SudokuSolver(Frame):

    sudoku = [[0 for col in range(9)] for row in range(9)]
    solution = [[0 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]]
    print(sudoku)
    print(solution)
    print(exampleSudoku)

    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] = ' '
                self.solution[row][col] = ' '
                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):
        for row in range(9):
            print("|-----------------------------------|")
            for col in range(9):
                print("| " + matrix[row][col] + " ",end='')
            print("|")
        print("|-----------------------------------|")

    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]
        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)
4.SudokuSolver_solver.py
                                                                #SudokuSolver_solver.py

BACKTRACK_COUNTER = 0

def do_solve(sudoku):
    status = wsolve(sudoku)
    return status, sudoku, BACKTRACK_COUNTER

def consistent(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


class SolutionFound(Exception):
    pass

def wsolve(sudoku):
    try:
        solve(sudoku, 0)
    except SolutionFound:
        return True
    except StopSolving:
        return False
    return False

def solve(sudoku, num):
    global BACKTRACK_COUNTER
    BACKTRACK_COUNTER += 1
    if num==81:
        raise SolutionFound
        return True
    else:
        row = int(num / 9)
        col = num % 9
        if sudoku[row][col]!=' ':
            solve(sudoku, num+1)
        else:
            for value in range(1,10):
                if consistent(sudoku, row, col, str(value)):
                    sudoku[row][col] = str(value)
                    if solve(sudoku, num+1): return True
                sudoku[row][col]=' '
            return False

if __name__ == '__main__':
    printSUDOKU(sudoku)
    solve(sudoku, 0)
5. tkcallasync.py
#tkcallasync.py
# Author: Miguel Martinez Lopez
#
# Uncomment the next line to see my email
# print("Author's email: %s"%"61706c69636163696f6e616d656469646140676d61696c2e636f6d".decode("hex"))


"""
I provide in this module the function "tk_call_async".

"tk_call_async" executes the function "computation" asyncronously with the provided "args" and "kwargs" without blocking the tkinter event loop.
If "callback" is provided, it will be called with the result when the computation is finnished.
If an exception is raised during computation, instead errback will be called.
"Polling" will be the frequency to poll to check for results.
There is two methods to execute the task: using multiprocessing or using threads.
"""

import traceback
import threading

# Python 3 support
try:
    from Queue import Queue
except ImportError:
    from queue import Queue

MULTIPROCESSING = 0
THREADS = 1

def tk_call_async(window, computation, args=(), kwargs={}, callback=None, errback=None, polling=500, method=MULTIPROCESSING):
    if method == MULTIPROCESSING:
        # I use threads because on windows creating a new python process freezes a little the event loop.
        future_result= Queue()

        worker = threading.Thread(target=_request_result_using_multiprocessing, args=(computation, args, kwargs, future_result))
        worker.daemon = True
        worker.start()
    elif method == THREADS:
        future_result = _request_result_using_threads(computation, args=args, kwargs=kwargs)
    else:
        raise ValueError("Not valid method")


    if callback is not None or errback is not None:
        _after_completion(window, future_result, callback, errback, polling)

    return future_result

def _request_result_using_multiprocessing(func, args, kwargs, future_result):
    import multiprocessing

    queue= multiprocessing.Queue()

    worker = multiprocessing.Process(target=_compute_result, args=(func, args, kwargs, queue))
    worker.daemon = True
    worker.start()

    return future_result.put(queue.get())

def _request_result_using_threads(func, args, kwargs):
    future_result= Queue()

    worker = threading.Thread(target=_compute_result, args=(func, args, kwargs, future_result))
    worker.daemon = True
    worker.start()

    return future_result


def _after_completion(window, future_result, callback, errback, polling):
    def check():
        try:
            result = future_result.get(block=False)
        except:
            window.after(polling, check)
        else:
            if isinstance(result, Exception):
                if errback is not None:
                    errback(result)
            else:
                if callback is not None:
                    callback(result)

    window.after(0, check)

def _compute_result(func, func_args, func_kwargs, future_result):
    try:
        _result = func(*func_args, **func_kwargs)
    except Exception as errmsg:
        _result = Exception(traceback.format_exc())

    future_result.put(_result)


# Multiprocessing uses pickle on windows.
# A pickable function should be in top module or imported from another module.
# This is requirement is not mandatory on Linux because python uses behind the scenes the fork operating system call.
# But on Windows it uses named pipes and pickle.


def _example_calculation(n):
    if n == 0: return 0
    elif n == 1: return 1
    else: return _example_calculation(n-1)+_example_calculation(n-2)

if __name__ == "__main__":
    try:
        from Tkinter import Tk, Frame, Entry, Label, Button, IntVar, StringVar, LEFT
        import tkMessageBox as messagebox
    except ImportError:
        from tkinter import Tk, Frame, Entry, Label, Button, IntVar, StringVar, LEFT
        from tkinter import messagebox

    disabled = False

    def calculate_fibonacci():
        global disabled
        if disabled:
            messagebox.showinfo("warning", "It's still calculating...")
            return

        def callback(result):
            global disabled
            disabled = False
            result_var.set(result)

        disabled = True
        tk_call_async(root, _example_calculation, args=(n.get(),), callback=callback, method =MULTIPROCESSING)

    root = Tk()

    n = IntVar(value=35)
    row = Frame(root)
    row.pack()
    Entry(row, textvariable=n).pack(side=LEFT)
    Button(row, text="Calculate fibonnaci", command =calculate_fibonacci).pack(side=LEFT)
    Button(row, text="It's responsive", command= lambda: messagebox.showinfo("info", "it's responsive")).pack(side=LEFT)

    result_var = StringVar()
    Label(root, textvariable=result_var).pack()
I modified "copy_class.py". Now it prints the puzzle I entered. But not the solution.
If I could get somewhere the matrix of the puzzle, I should be able to run "init.py"(the professionnal), and so have a nice solution on the control prompt. I imported "pprint" which prints nice matrixes. Here below the new "copy_class.py"

#copy_class.py

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
#import tkcallasync


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']]
    pprint(sudoku)
    pprint(solution)
    pprint(exampleSudoku)

    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):
        for row in range(9):
            print("|-----------------------------------|")
            for col in range(9):
                print("| " + matrix[row][col] + " ",end='')
            print("|")
        print("|-----------------------------------|")

    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]
        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)
When I have the figure of tkinter, I first click on 'init", then I enter the values, then I click on "solve", then I click on "print". On the command prompt the "sudoku" appears with the values I entered(using blanks and not zeros). The "solution" matrix contains only blanks.
Now I am very near to the end. I want some help. When I enter a matrix, at first it writes correctly, but then, it replaces the matrix, by a matrix plenty of zeros.
Here are my 2 new files:
#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()
        input("Hit ENTER to continue")

    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)
And now the new __main__.py :
# __main__.py
"""
On the tkinter image:
1. type numbers, 2. click on "solve"  3. click on "print"
"""
import copy_class
import csv
from pprint import pprint
from kudoSudoku import sudoku
from multiprocessing import freeze_support#origin
if __name__ == '__main__':#origin
    freeze_support()#origin
    #import SudokuSolver_class as SudokuSolver#origin
    import copy_class as SudokuSolver
    from tkinter import Tk#origin
    def main():#origin
        root = Tk()#origin
        app = SudokuSolver.SudokuSolver(root)#origin
        root.mainloop()#origin

        def puzzle():
            pass

        def matrix():
            pass

        with open('numbers.csv', newline='') as csvfile:
            puzzle=csv.reader(csvfile, delimiter=' ', quotechar='|')
            for row in puzzle:#origin
                print(', '.join(row))#originr
                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)

    main()
At last the end. I just added, in __main__.py, line 39: import init
I must add a very important thing. When you see on the prompt command " Hit ENTER to continue": remove tkinter figure clicking on its cross(corner up and right). So, I will rather modify "Hit ENTER to continue" to "Remove first tkinter figure and then click ENTER to continue(on the Command Prompt)"
 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)

        input("Hit ENTER to continue")

    def printALL(self):
        print('Sudoku:')
I think this project can be improved, because there are people much stronger than me on python language.
I change my program, because with the last project, once it works once it does not work. Now, instead of "input("hit ENTER to continue")" I put exit(), and then I must run a new file named "solver.py". Here is its code:
#solver.py
import init
import csv
from kudoSudoku import sudoku
from pprint import pprint

with open('numbers.csv', newline='') as csvfile:
    puzzle=csv.reader(csvfile, delimiter=' ', quotechar='|')
    for row in puzzle:#origin
        print(', '.join(row))#originr
        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)
So this version is not simple as the preceeding, but problems disappeared.

__main__.py now is:
# __main__.py
"""
On the tkinter image:
1. type numbers, 2. click on "solve"  3. click on "print"
"""

from multiprocessing import freeze_support

if __name__ == '__main__':
    freeze_support()
    import SudokuSolver_class as SudokuSolver
    from tkinter import Tk

    def main():
        root = Tk()
        app = SudokuSolver.SudokuSolver(root)
        root.mainloop()

    main()
One thing is sure. You must put "exit()" instead of "input("hit ENTER ect..." in copy_class.py. But there is a very strange thing: I enter a sudoku. Then I go to numbers.csv . I make a type. I find my last sudoku. Nothing else. OK for that. But the big surprise is that when I run "solver.py" it gives me the solution of another sudoku. So there must be an error in "solver.py".
There were 2 numbers.csv. One inside the project and another outside. That's why I got always the bad solution. After Larz60 help I have a new solver.py. Also, add please a __init__.py file in the project. It is an empty file. Now here is the new solver.py which works very well. So the project is now well finished.
#solver.py
import init
#import numbers
import os
import csv
from kudoSudoku import sudoku
from pprint import pprint
filename = os.path.abspath('C:/Users/Sylvain/numbers.csv')
def matrix():
    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)
When I run the project with "python kudoSudoku" I should like to have a non-stop project. With exit() in cop_class.py, I go out of the project, and then I run solver.py. But if I put "import solver" instead of "exit()" I cannot nomore import name 'sudoku'. Remember, at the top of solver.py there is: from kudoSudoku import sudoku.
Why with running solver.py alone there is no problem, but with my non-stop project , problem appears. I recognize I am lost with so many imports that exist. May be someone experienced in imports , finds a solution.
Pages: 1 2 3