Python Forum
project kudoSudoku follows SUDO project
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
project kudoSudoku follows SUDO project
#11
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'
Reply
#12
Hi all ! Is it possible to remove previous imports, when I am at the bottom of the file.
Reply
#13
to what end?
Reply
#14
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.
Reply
#15
sylas, you've gotten this feedback before - you need to provide full (though minimal) code that reproduces the problem.
Reply
#16
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'
Reply
#17
  • 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?
Reply
#18
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.
Reply
#19
I merged the two threads as this one and the one with the question of imports are closely related
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#20
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.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Modify project (so that it uses db, QSqlRelationalTableModel etc) panoss 0 1,265 Jan-31-2022, 10:14 PM
Last Post: panoss
Question GUI for simple python project Qwertz 4 112,888 Jan-26-2022, 10:29 AM
Last Post: menator01
  [Tkinter] remove file from current project rwahdan 2 2,287 Jul-25-2021, 09:14 AM
Last Post: Larz60+
  [Tkinter] Finishing GUI calculator project benybeastboy 3 3,117 Feb-26-2021, 04:54 PM
Last Post: kkaur
  python file(.py) not working with my tkinter project DeanAseraf1 9 7,119 Mar-22-2020, 10:58 PM
Last Post: ifigazsi
  Problem In calling a Function from another python file of project vinod2810 7 5,321 Oct-05-2019, 01:09 PM
Last Post: ichabod801
  advice getting started with GUI project loulou 1 1,953 Jun-18-2019, 01:20 PM
Last Post: Denni
  Linear algebra semester project frequency 3 3,073 Dec-02-2018, 07:12 AM
Last Post: buran
  [Tkinter] TkInter Setting Out Project MTom5 1 2,226 Aug-14-2018, 04:08 PM
Last Post: Larz60+
  Continue SUDO project sylas 6 3,973 Apr-29-2018, 04:43 PM
Last Post: sylas

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020