Posts: 148
Threads: 34
Joined: May 2020
Hello,
I've got coding experience but I'm new to python.
I'm trying to generate a sudoku solver in python using tkinter. I found online the code - now I'm trying to link it with tkinter. The code uses the list bo - this list contains the entered values from the entries of tkinter.
How to pass the list "bo" to the solve function when the button "readin" is pressed?
I tried " bo=readin() " (line 91).
Here is the error description:
Traceback (most recent call last):
File "d:/Ordner/Python/testgrid2/testgrid2.py", line 91, in <module>
bo=readin()
File "d:/Ordner/Python/testgrid2/testgrid2.py", line 70, in readin
listrow0.append(Square[i].get())
IndexError: list index out of range
What I am doing wrong?
Thanks for your help!!
Greetings,
flash77
import tkinter as tk
from tkinter import Entry, IntVar, Tk
def solve(bo):
find = find_empty(bo)
if not find:
print("Sudoku solved.")
return True
else:
row, col = find
for i in range(1,10):
if valid(bo, i, (row, col)):
bo[row][col] = i
if solve(bo):
return True
bo[row][col] = 0
return False
def valid(bo, num, pos):
# Check row
for i in range(len(bo[0])):
if bo[pos[0]][i] == num and pos[1] != i:
return False
# Check column
for i in range(len(bo)):
if bo[i][pos[1]] == num and pos[0] != i:
return False
# Check box
box_x = pos[1] // 3
box_y = pos[0] // 3
for i in range(box_y*3, box_y*3 + 3):
for j in range(box_x * 3, box_x*3 + 3):
if bo[i][j] == num and (i,j) != pos:
return False
return True
def find_empty(bo):
for i in range(len(bo)):
for j in range(len(bo[0])):
if bo[i][j] == 0:
return (i, j) # row, col
return None
def quit_frame():
main.destroy()
Square = []
def SquareCreate():
for j in range(0, 9):
for i in range(0,9):
data = IntVar()
t = tk.Entry(main, textvariable=data, justify="center",font=("Arial",16))
t.place(x=i*40+70, y=j*40+80, width=40, height=40)
t.delete(0)
Square.append(data)
def readin():
listrow0 = []; listrow1 = []; listrow2 = []; listrow3 = []; listrow4 = []; listrow5 = []; listrow6 = []
listrow7 = []; listrow8 = []
for i in range(0,9):
listrow0.append(Square[i].get())
for i in range(9,18):
listrow1.append(Square[i].get())
for i in range(18,27):
listrow2.append(Square[i].get())
for i in range(27,36):
listrow3.append(Square[i].get())
for i in range(36,45):
listrow4.append(Square[i].get())
for i in range(45,54):
listrow5.append(Square[i].get())
for i in range(54,63):
listrow6.append(Square[i].get())
for i in range(63,72):
listrow7.append(Square[i].get())
for i in range(72,81):
listrow8.append(Square[i].get())
bo = []
bo = [listrow0,listrow1,listrow2,listrow3,listrow4,listrow5,listrow6,listrow7,listrow8]
return bo
bo=readin()
#mainprogramm
main = tk.Tk()
main.geometry("500x540")
main.resizable(width=0, height=0)
l=tk.Label(main, text="Sudoku Bruteforce Solver")
l["font"]="Arial"
l.place(x=150,y=0)
SquareCreate()
button1=tk.Button(main, text="quit", command = quit_frame)
button1.place(x=50,y=450)
button2=tk.Button(main, text="readin", command = readin)
button2.place(x=150,y=450)
solve(bo)
main.mainloop()
Posts: 6,798
Threads: 20
Joined: Feb 2020
def readin():
"""Assumes solve wants a list"""
puzzle = []
for square in Square:
puzzle.append(square.get())
return puzzle
def readin():
"""Assumes solve wants a list of rows"""
puzzle = []
for r in range(9)
row = []
for c in range(9):
row.append(Square[r*9+c].get()
puzzle.append(row)
return puzzle
Posts: 148
Threads: 34
Joined: May 2020
Hello deanhystad,
thanks for your answer!!
I added in line 12 to 21 some code for spaces between the entries.
I use the acronym "bo" for "board".
Unfortunately there is an error in line 32, for the expression "bo" it is mentioned "invalid syntax".
I tried very long to find the reason for it but I came to no solution...
What could I do?
Thanks again,
Greetings flash77
import tkinter as tk
from tkinter import Entry, IntVar, Tk
def quit_frame():
main.destroy()
def SquareCreate():
for j in range(0, 9):
for i in range(0,9):
data = IntVar()
t = tk.Entry(main, textvariable=data, justify="center",font=("Arial",16))
ixtra=0
jxtra=0
if i > 2:
ixtra=4
if i > 5:
ixtra=8
if j > 2:
jxtra=4
if j > 5:
jxtra=8
t.place(x=i*40+70+ixtra, y=j*40+80+jxtra, width=40, height=40)
t.delete(0)
Square.append(data)
def readin():
bo = []
for r in range(9):
row = []
for c in range(9):
row.append(Square[r*9+c].get()
bo.append(row)
return bo
def solve(bo):
find = find_empty(bo)
if not find:
print("Sudoku solved.")
return True
else:
row, col = find
for i in range(1,10):
if valid(bo, i, (row, col)):
bo[row][col] = i
if solve(bo):
return True
bo[row][col] = 0
return False
def valid(bo, num, pos):
# Check row
for i in range(len(bo[0])):
if bo[pos[0]][i] == num and pos[1] != i:
return False
# Check column
for i in range(len(bo)):
if bo[i][pos[1]] == num and pos[0] != i:
return False
# Check box
box_x = pos[1] // 3
box_y = pos[0] // 3
for i in range(box_y*3, box_y*3 + 3):
for j in range(box_x * 3, box_x*3 + 3):
if bo[i][j] == num and (i,j) != pos:
return False
return True
def find_empty(bo):
for i in range(len(bo)):
for j in range(len(bo[0])):
if bo[i][j] == 0:
return (i, j) # row, col
return None
#mainprogramm
Square = []
main = tk.Tk()
main.geometry("500x540")
main.resizable(width=0, height=0)
l=tk.Label(main, text="Sudoku Bruteforce Solver")
l["font"]="Arial"
l.place(x=150,y=0)
button1=tk.Button(main, text="quit", command = quit_frame)
button1.place(x=50,y=450)
button2=tk.Button(main, text="readin", command = readin)
button2.place(x=150,y=450)
SquareCreate()
bo=readin()
print(bo)
solve(bo)
main.mainloop()
Posts: 6,798
Threads: 20
Joined: Feb 2020
Syntax error is in line 31
Posts: 148
Threads: 34
Joined: May 2020
Dear deanhystad,
thanks for your patience!
The Squarecreate function creates the entries.
The next steps would be:
When the given values are entered in the entries of the frame, the values shall be read in when the button readin is pressed and the function solve shall be run. When the function solve has solved the puzzle the values of the list board have to be written in the entries.
I have coding experience but I'm a beginner to python so I have to ask again and again...
Please would you be so kind and solve these steps?
Then I would have a working code I could orientate myself...
That would be perhpas a better way instead of asking and asking (and perhaps annoying) again?
Greetings
flash77
import tkinter as tk
from tkinter import Entry, IntVar, Tk
def quit_frame():
main.destroy()
def SquareCreate():
sq = []
for j in range(0, 9):
for i in range(0,9):
data = IntVar()
t = tk.Entry(main, textvariable=data, justify="center",font=("Arial",16))
ixtra=0
jxtra=0
if i > 2:
ixtra=4
if i > 5:
ixtra=8
if j > 2:
jxtra=4
if j > 5:
jxtra=8
t.place(x=i*40+70+ixtra, y=j*40+80+jxtra, width=40, height=40)
t.delete(0)
sq.append(data)
return sq
def readin(sq):
bo = []
for r in range(0,9):
row = []
for c in range(0,9):
row.append(sq[r*9+c].get())
bo.append(row)
return bo
def solve(bo):
find = find_empty(bo)
if not find:
print("Sudoku solved.")
return True
else:
row, col = find
for i in range(1,10):
if valid(bo, i, (row, col)):
bo[row][col] = i
if solve(bo):
return True
bo[row][col] = 0
return False
def valid(bo, num, pos):
# Check row
for i in range(len(bo[0])):
if bo[pos[0]][i] == num and pos[1] != i:
return False
# Check column
for i in range(len(bo)):
if bo[i][pos[1]] == num and pos[0] != i:
return False
# Check box
box_x = pos[1] // 3
box_y = pos[0] // 3
for i in range(box_y*3, box_y*3 + 3):
for j in range(box_x * 3, box_x*3 + 3):
if bo[i][j] == num and (i,j) != pos:
return False
return True
def find_empty(bo):
for i in range(len(bo)):
for j in range(len(bo[0])):
if bo[i][j] == 0:
return (i, j) # row, col
return None
#mainprogramm
main = tk.Tk()
main.geometry("500x540")
main.resizable(width=0, height=0)
l=tk.Label(main, text="Sudoku Bruteforce Solver")
l["font"]="Arial"
l.place(x=150,y=0)
button1=tk.Button(main, text="quit", command = quit_frame)
button1.place(x=50,y=450)
button2=tk.Button(main, text="readin", command = readin)
button2.place(x=150,y=450)
SquareCreate()
Square=SquareCreate()
main.mainloop()
Posts: 148
Threads: 34
Joined: May 2020
Hello,
I changed the complexity of the example to concentrate on the basics.
The function SquareCreate() generates the squares.
I'm trying to read in the values of the entries with the function readin().
In line 24 it is mentioned that "list index ist out of range".
What I am doing wrong?
I ask politely for help...
Greetings, flash77
import tkinter as tk
from tkinter import Entry, IntVar, Tk
def quit_frame():
main.destroy()
def SquareCreate():
sq=[]
for j in range(1,4):
for i in range(1,4):
data = IntVar()
t = tk.Entry(main, textvariable=data, justify="center",font=("Arial",16))
t.place(x=i*40, y=j*40, width=40, height=40)
t.delete(0)
sq.append(data)
return sq
def readin():
sq=[]
bo=[]
for r in range(1,4):
row=[]
for c in range(1,4):
row.append(sq[r*9+c].get())
bo.append(row)
return bo
#mainprogramm
main = tk.Tk()
main.geometry("500x540")
main.resizable(width=0, height=0)
l=tk.Label(main, text="Sudoku Bruteforce Solver")
l["font"]="Arial"
l.place(x=150,y=0)
button1=tk.Button(main, text="quit", command = quit_frame)
button1.place(x=50,y=450)
button2=tk.Button(main, text="readin", command = readin)
button2.place(x=150,y=450)
SquareCreate()
main.mainloop()
Posts: 6,798
Threads: 20
Joined: Feb 2020
You don't want to do "sq = []" in readin(). Do you know why that is bad?
Posts: 148
Threads: 34
Joined: May 2020
Hello deanhystad,
thanks for your help again...
I'm not sure how to use "sq" in function "readin()". "sq" is a local variable of "squarecreate()".
My attempt to handover
z=squarecreate() to
readin(z)
doesn't work.
If the handover of "sq" to readin would work then "sq=[]" would overwrite it?
So I have to erase "sq=[]" from readin?
Greetings, flash77
Posts: 6,798
Threads: 20
Joined: Feb 2020
May-28-2020, 02:45 PM
(This post was last modified: May-28-2020, 02:45 PM by deanhystad.)
I think you need to take a Python class. There are some really important concepts I don't think you understand, like how variables work and what scope means and how it affects programs. Until you understand that, this sudoku solver is just going to be frustrating.
Posts: 1
Threads: 0
Joined: Apr 2025
Apr-03-2025, 01:01 PM
(This post was last modified: Apr-03-2025, 01:33 PM by buran.)
(May-22-2020, 04:29 PM)flash77 Wrote: Hello,
I've got coding experience but I'm new to python.
I'm trying to generate a sudoku solver in python using tkinter. I found online the code - now I'm trying to link it with tkinter. The code uses the list bo - this list contains the entered values from the entries of tkinter.
How to pass the list "bo" to the solve function when the button "readin" is pressed?
I tried " bo=readin() " (line 91).
Here is the error description:
Traceback (most recent call last):
File "d:/Ordner/Python/testgrid2/testgrid2.py", line 91, in <module>
bo=readin()
File "d:/Ordner/Python/testgrid2/testgrid2.py", line 70, in readin
listrow0.append(Square[i].get())
IndexError: list index out of range
What I am doing wrong?
Thanks for your help!!
Greetings,
flash77
import tkinter as tk
from tkinter import Entry, IntVar, Tk
def solve(bo):
find = find_empty(bo)
if not find:
print("Sudoku solved.")
return True
else:
row, col = find
for i in range(1,10):
if valid(bo, i, (row, col)):
bo[row][col] = i
if solve(bo):
return True
bo[row][col] = 0
return False
def valid(bo, num, pos):
# Check row
for i in range(len(bo[0])):
if bo[pos[0]][i] == num and pos[1] != i:
return False
# Check column
for i in range(len(bo)):
if bo[i][pos[1]] == num and pos[0] != i:
return False
# Check box
box_x = pos[1] // 3
box_y = pos[0] // 3
for i in range(box_y*3, box_y*3 + 3):
for j in range(box_x * 3, box_x*3 + 3):
if bo[i][j] == num and (i,j) != pos:
return False
return True
def find_empty(bo):
for i in range(len(bo)):
for j in range(len(bo[0])):
if bo[i][j] == 0:
return (i, j) # row, col
return None
def quit_frame():
main.destroy()
Square = []
def SquareCreate():
for j in range(0, 9):
for i in range(0,9):
data = IntVar()
t = tk.Entry(main, textvariable=data, justify="center",font=("Arial",16))
t.place(x=i*40+70, y=j*40+80, width=40, height=40)
t.delete(0)
Square.append(data)
def readin():
listrow0 = []; listrow1 = []; listrow2 = []; listrow3 = []; listrow4 = []; listrow5 = []; listrow6 = []
listrow7 = []; listrow8 = []
for i in range(0,9):
listrow0.append(Square[i].get())
for i in range(9,18):
listrow1.append(Square[i].get())
for i in range(18,27):
listrow2.append(Square[i].get())
for i in range(27,36):
listrow3.append(Square[i].get())
for i in range(36,45):
listrow4.append(Square[i].get())
for i in range(45,54):
listrow5.append(Square[i].get())
for i in range(54,63):
listrow6.append(Square[i].get())
for i in range(63,72):
listrow7.append(Square[i].get())
for i in range(72,81):
listrow8.append(Square[i].get())
bo = []
bo = [listrow0,listrow1,listrow2,listrow3,listrow4,listrow5,listrow6,listrow7,listrow8]
return bo
bo=readin()
#mainprogramm
main = tk.Tk()
main.geometry("500x540")
main.resizable(width=0, height=0)
l=tk.Label(main, text="Sudoku Bruteforce Solver")
l["font"]="Arial"
l.place(x=150,y=0)
SquareCreate()
button1=tk.Button(main, text="quit", command = quit_frame)
button1.place(x=50,y=450)
button2=tk.Button(main, text="readin", command = readin)
button2.place(x=150,y=450)
solve(bo)
main.mainloop()
Hey flash77,
Nice work diving into Python and Tkinter! The issue seems to be that you're calling readin() before the GUI is even created, so Square doesn’t have any values yet—it's still empty when the function runs. Try calling solve(readin()) only after the user has entered numbers and clicked the button. That way the data is actually there when readin() runs.
Good luck with your solver!
buran write Apr-03-2025, 01:33 PM:Spam link removed
|