Python Forum
project kudoSudoku follows SUDO project
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
project kudoSudoku follows SUDO project
#21
Quote:So in this project you cannot find "kudoSudoku" nor "sudoku". So in the solver.py
Error:
File "kudoSudoku\solver.py", line 5, in <module> from kudoSudoku import sudoku ImportError: cannot import name 'sudoku'
You cannot import a module that doesn't exist.
If you are trying to import sudoku from kudoSudoku, there must be a corresponding kudoSudoku.py file
Reply
#22
It seems very strange. When I run solver.py alone, it runs very well( no mention of kudosudoku or sudoku). But problem arises when I import solver in copy_class.py; there it cannot, nomore find sudoku. What difference when I run solver.py alone, and when it runs on the project ? For running project I type on Command Prompt: python SUDO.
Reply
#23
Do you use this/have it installed?
https://github.com/Varshneyabhushan/kudoSudoku
or on PyPI: https://pypi.org/project/kudosudoku/
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
#24
I installed my project using your second reference: https://pypi.org/project/kudosudoku/
Reply
#25
Hi all. I should like to load a file from a library and then put this file in my project. The name of this file is: kudoSudoku
Reply
#26
import kudoSudoko
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
#27
THE REAL END. At last the non-stop version.Number of files:6.__main__.py, copy_class.py, init.py, solver.py, SudokuSolver_solver.py, and tkcallasync.py
Here the new files:
__main__.py
# __main__.py

from multiprocessing import freeze_support

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

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


    main()
copy_class.py
#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)

And the solver.py Don't forget to replace "Sylvain" by your first name.
#solver.py
import init
import os
import csv
from init 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)

In solver.py you can comment "import init"
Reply
#28
regarding sudoko, - what if i wanna build a sudoko program which has, say, 999 lines and columns - is there a way of creating the array without actually writing it 999 times ?
Reply


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