Проблема с использованием ключевого слова yield для визуализации быстрой сортировки с помощью tkinter? - PullRequest
0 голосов
/ 30 октября 2019

Для моего проекта класса я должен реализовать быструю сортировку и визуализировать ее, используя графический интерфейс с tkinter.

Но у меня проблема с ключевым словом yield, необходимым для анимации бирж. Когда я нажимаю кнопку быстрой сортировки для вызова функции сортировки,

появляется сообщение об ошибке:

TypeError: unsupported operand type (s) for -: 'generator' and 'int'

Но когда я удаляю yield, программа работаетотлично за исключением того, что анимация не закончена.

Не могли бы вы мне помочь?

import tkinter as tk
import random

#QUICK SORT
def partition(low, high):
    i = (low - 1)  # index of smaller element
    pivot = longueur_liste[high]  # pivot

    for j in range(low, high):

        # If current element is smaller than or
        # equal to pivot
        if longueur_liste[j] <= pivot:
            # increment index of smaller element
            i = i + 1

            longueur_liste[i], longueur_liste[j] = longueur_liste[j], longueur_liste[i]
            barre_liste[i], barre_liste[j ] = barre_liste[j ], barre_liste[i]
            echange_position(barre_liste[i], barre_liste[j ])  # Met à jour l'affichage
            yield
    longueur_liste[i + 1], longueur_liste[high] = longueur_liste[high], longueur_liste[i + 1]
    barre_liste[i+1], barre_liste[high] = barre_liste[high], barre_liste[i+1]
    echange_position(barre_liste[i+1], barre_liste[high])  # Met à jour l'affichage
    yield
    return i + 1


# The main function that implements QuickSort
# arr[] --> Array to be sorted,
# low  --> Starting index,
# high  --> Ending index

# Function to do Quick sort
def quickSort(low, high):
    if low < high:
        # pi is partitioning index, arr[p] is now
        # at right place

        pi = partition(low, high)


        # Separately sort elements before
        # partition and after partition
        quickSort(low, pi - 1)
        quickSort(pi + 1, high)




def _quickSort():     # Command start sorting and animation
    global utilisateur
    utilisateur = quickSort(0, 78)
    animate()

# ECHANGE POSITION
def echange_position(pos_0, pos_1):
    Bar_1_1, _, Bar_1_2, _ = canvas.coords(pos_0)
    Bar_2_1, _, Bar_2_2, _ = canvas.coords(pos_1)
    canvas.move(pos_0, Bar_2_1 - Bar_1_1, 0)
    canvas.move(pos_1, Bar_1_2 - Bar_2_2, 0)

# ANIMATION
def animate():
    global utilisateur
    if utilisateur is not None:
        try:
            next(utilisateur)
            window.after(10, animate)    # Repeat until sorting is complete
        except StopIteration:            # Repeat until sorting is complete
            utilisateur = None
        finally:
            window.after_cancel(animate) # Stop reminders

# GENERATION OF RANDOM VALUES BETWEEN 1 AND 390
def generer():
    global barre_liste
    global longueur_liste
    canvas.delete('all')
    x_start = 5
    x_end = 15
    barre_liste = []
    longueur_liste = []

    for x in range(1, 80):
        random_Y = random.randint(1, 400)
        x = canvas.create_rectangle(x_start, random_Y, x_end, 450, fill='red')
        barre_liste.append(x)
        x_start += 10
        x_end += 10

    for barre in barre_liste:
        x = canvas.coords(barre)
        length = x[3] - x[1]
        longueur_liste.append(length)

    for i in range(len(longueur_liste) - 1):
        if longueur_liste[i] == min(longueur_liste):
            canvas.itemconfig(barre_liste[i], fill='blue')
        elif longueur_liste[i] == max(longueur_liste):
            canvas.itemconfig(barre_liste[i], fill='yellow')


window = tk.Tk()
window.title('Algorithmes de tri')
window.geometry('820x485')
canvas = tk.Canvas(window, width='820', height='450')
canvas.grid(column=0,row=0, columnspan = 50)
gen = tk.Button(window, text='generate', command=generer)
quick = tk.Button(window, text='Quicksort', command=_quickSort)
gen.grid(column=0, row=1)
quick.grid(column=1, row=1)
generer()
window.mainloop()

Вот еще одна сортировка, анимация работает отлично.

import tkinter as tk
import random

# SHELL SORT
def shellSort():
    n = len(longueur_liste)
    gap = n // 2
    while gap > 0:

        for i in range(gap, n):
            temp = longueur_liste[i]
            j = i
            while j >= gap and longueur_liste[j - gap] > temp:
                longueur_liste[j] = longueur_liste[j - gap]
                longueur_liste[j] = longueur_liste[j - gap]
                barre_liste[j], barre_liste[j - gap] = barre_liste[j - gap], barre_liste[j]
                echange_position(barre_liste[j], barre_liste[j - gap])  # Update the display
                yield
                j -= gap
            longueur_liste[j] = temp
        gap //= 2


utilisateur = None


def _shell():     #Starts both the sort and the animation
    global utilisateur
    utilisateur = shellSort()
    animate()

# ANIMATION
def animate():
    global utilisateur
    if utilisateur is not None:
        try:
            next(utilisateur)
            window.after(10, animate)    # Repeat until the sort is complete
        except StopIteration:            # When the generator is full
            utilisateur = None
        finally:
            window.after_cancel(animate) # Stop les rappels

# Generate 80 random values between 1 and 400
def generer():
    global barre_liste
    global longueur_liste
    canvas.delete('all')
    x_start = 5
    x_end = 15
    barre_liste = []
    longueur_liste = []

    for x in range(1, 80):
        random_Y = random.randint(1, 400)
        x = canvas.create_rectangle(x_start, random_Y, x_end, 450, fill='red')
        barre_liste.append(x)
        x_start += 10
        x_end += 10

    for barre in barre_liste:
        x = canvas.coords(barre)
        length = x[3] - x[1]
        longueur_liste.append(length)

    for i in range(len(longueur_liste) - 1):
        if longueur_liste[i] == min(longueur_liste):
            canvas.itemconfig(barre_liste[i], fill='blue')
        elif longueur_liste[i] == max(longueur_liste):
            canvas.itemconfig(barre_liste[i], fill='yellow')

# EXHANGE POSITION
def echange_position(pos_0, pos_1):
    Bar_1_1, _, Bar_1_2, _ = canvas.coords(pos_0)
    Bar_2_1, _, Bar_2_2, _ = canvas.coords(pos_1)
    canvas.move(pos_0, Bar_2_1 - Bar_1_1, 0)
    canvas.move(pos_1, Bar_1_2 - Bar_2_2, 0)

window = tk.Tk()
window.title('Algorithmes de tri')
window.geometry('820x485')
canvas = tk.Canvas(window, width='820', height='450')
canvas.grid(column=0, row=0, columnspan=50)

gen = tk.Button(window, text='Générer', command=generer)
shell = tk.Button(window, text='Shell', command=_shell)
shell.grid(column=2, row=1)
gen.grid(column=1, row=1)

generer()
window.mainloop()

1 Ответ

0 голосов
/ 30 октября 2019

Я не совсем понимаю, что yield делает в этом конкретном примере, но я вполне уверен, что вы можете решить эту проблему, понимая, что вообще такое yield. Для этого я настоятельно рекомендую прочитать this - и у вас нет оправданий не делать этого, это по-французски: p

...