How do I correctly implement a bubble sort algorithm in python tkinter?
The biggest problem is that inside sort_two
you have if
if y2 > y1: canvas.move(pos_0, x_10-x_00, 0) canvas.move(pos_1, x_01-x_11, 0)
which replaces elements only if y2 > y1
but after sort_two()
you use barList
sort_two(pos_1, pos_2)barList[rd1], barList[rd2] = barList[rd2], barList[rd1]
which always replaces elements on list.
And this way you have wrong results on screen.
You could return True/False
from sort_two()
to control when to change elements on barList
if y2 > y1: canvas.move(pos_0, x_10-x_00, 0) canvas.move(pos_1, x_01-x_11, 0) return Trueelse: return False
and
if sort_two(pos_1, pos_2): barList[rd1], barList[rd2] = barList[rd2], barList[rd1]
Here finall code
I use simple calculation for replacing elements on canvas
x1, _, _, _ = canvas.coords(pos_0)x2, _, _, _ = canvas.coords(pos_1)diff = x1 - x2canvas.move(pos_0, -diff, 0)canvas.move(pos_1, +diff, 0)
I also removed
else: break
which stop animation after every replace and it needs to click button sort
again and again - and I use
window.update() time.sleep(0.1)
so it displays animation (slowly) to the end of sorting and I don't have to click button sort
import tkinter as tkimport randomimport timedef swap_two_pos(pos_0, pos_1): """This does the graphical swapping of the rectangles on the canvas by moving one rectangle to the location of the other, and vice versa """ x1, _, _, _ = canvas.coords(pos_0) x2, _, _, _ = canvas.coords(pos_1) diff = x1 - x2 canvas.move(pos_0, -diff, 0) canvas.move(pos_1, +diff, 0)def sort_two(pos_0, pos_1): x1, y1, _, _ = canvas.coords(pos_0) x2, y2, _, _ = canvas.coords(pos_1) diff = x1 - x2 # moves each rectangle to the x position of the other; y remains unchanged if y2 > y1: canvas.move(pos_0, -diff, 0) canvas.move(pos_1, +diff, 0) return True else: return Falsedef rand_sort(): for i in range(50000): rd1 = random.randint(0, 58) rd2 = random.randint(0, 58) pos_1 = barList[rd1] pos_2 = barList[rd2] if sort_two(pos_1, pos_2): barList[rd1], barList[rd2] = barList[rd2], barList[rd1]def sort (): n = len(barList) # Traverse through all array elements for i in range(n): # Last i elements are already in place for j in range(0, n-i-1): if sort_two(barList[j], barList[j+1]): barList[j], barList[j+1] = barList[j+1], barList[j] window.update() time.sleep(0.1) def random_swap(): """Not a sort yet, but you have the bare bones operations so the swap is executed """ for i in range(500): rd1 = random.randint(0, 58) rd2 = random.randint(0, 58) pos_0 = barList[rd1] pos_1 = barList[rd2] swap_two_pos(pos_0, pos_1) # it is necessary to swap the values in the list too barList[rd1], barList[rd2] = barList[rd2], barList[rd1]window = tk.Tk()window.title('Sorting')window.geometry('600x400')# button to command the swaptk.Button(window, text='swap', command=random_swap).pack()tk.Button(window, text='sort', command=sort).pack()xstart = 5xend = 15canvas = tk.Canvas(window, width='900', height='900')canvas.pack()barList = []lengthList = []Y = 5for x in range(1,60): bar = canvas.create_rectangle(xstart, Y, xend, 395, fill='red') barList.append(bar) xstart += 10 xend += 10 Y += 5for bar in barList: x = canvas.coords(bar) length = x[3]-x[1] lengthList.append(length)window.mainloop()