-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Sorting Animation With Python [GUI & UI] 🤍
- Loading branch information
1 parent
ff515c9
commit dec62b5
Showing
12 changed files
with
313 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# SortingAlgorithms | ||
|
||
## BubbleSort | ||
|
||
<p align="center"> | ||
<img src="imgs/BubbleSort.png" width="752" height="656"> | ||
</p> | ||
|
||
|
||
## InsertionSort | ||
|
||
<p align="center"> | ||
<img src="imgs/InsertionSort.png" width="752" height="656"> | ||
</p> | ||
|
||
|
||
## MergeSort | ||
|
||
<p align="center"> | ||
<img src="imgs/MergeSort.png" width="752" height="656"> | ||
</p> | ||
|
||
## QuickSort | ||
|
||
<p align="center"> | ||
<img src="imgs/QuickSort.png" width="752" height="656"> | ||
</p> | ||
|
||
## SelectionSort | ||
|
||
<p align="center"> | ||
<img src="imgs/SelectionSort.png" width="752" height="656"> | ||
</p> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import matplotlib.animation as animation | ||
import matplotlib.pyplot as plt | ||
from tkinter import messagebox | ||
from sort import Algorithms | ||
import tkinter as tk | ||
import random | ||
import time | ||
|
||
|
||
class Window(tk.Tk): | ||
def __init__(self): | ||
super().__init__() | ||
self.title("Sorting Algorithms - Clever Code") | ||
# self.resizable(False, False) | ||
|
||
self.frame = tk.Frame() | ||
self.frame.pack() | ||
self.n_label = tk.Label(self.frame, text="n:", font=("Cascadia Code", "15")) | ||
self.n_label.grid(row=0, column=0, padx=10, pady=10) | ||
self.n_entry = tk.Entry(self.frame, justify="center", font=("Cascadia Code", "15")) | ||
self.n_entry.grid(row=0, column=1, padx=10, sticky="E") | ||
|
||
self.sort_frame = tk.Frame() | ||
self.sort_frame.pack() | ||
self.radio_value = tk.IntVar() | ||
self.radio_value.set(-1) | ||
self.bubble_sort = tk.Radiobutton(self.sort_frame, text="BubbleSort", variable=self.radio_value, value=0) | ||
self.bubble_sort.grid(row=0, column=0, padx=10, sticky="W") | ||
self.insertion_sort = tk.Radiobutton(self.sort_frame, text="InsertionSort", variable=self.radio_value, value=1) | ||
self.insertion_sort.grid(row=0, column=1, padx=10, sticky="W") | ||
self.merge_sort = tk.Radiobutton(self.sort_frame, text="MergeSort", variable=self.radio_value, value=2) | ||
self.merge_sort.grid(row=1, column=0, padx=10, sticky="W") | ||
self.quick_sort = tk.Radiobutton(self.sort_frame, text="QuickSort", variable=self.radio_value, value=3) | ||
self.quick_sort.grid(row=1, column=1, padx=10, sticky="W") | ||
self.selection_sort = tk.Radiobutton(self.sort_frame, text="SelectionSort", variable=self.radio_value, value=4) | ||
self.selection_sort.grid(row=2, columnspan=2, padx=10) | ||
|
||
self.button_frame = tk.Frame() | ||
self.button_frame.pack() | ||
self.reset_button = tk.Button(self.button_frame, text="Reset", font=("Cascadia Code", "15"), command=self.resetWindow) | ||
self.reset_button.grid(row=0, column=0, padx=10, pady=10, sticky="WE") | ||
self.start_button = tk.Button(self.button_frame, text="Start", font=("Cascadia Code", "15"), command=self.setAlgorithm) | ||
self.start_button.grid(row=0, column=1, padx=10, pady=10, sticky="WE") | ||
|
||
def resetWindow(self): | ||
self.n_entry.delete(0, tk.END) | ||
self.radio_value.set(-1) | ||
|
||
def __checkAll(self): | ||
try: | ||
if self.radio_value.get() in [i for i in range(0, 5)] and int(self.n_entry.get()): | ||
return True | ||
except ValueError: | ||
return False | ||
|
||
def setAlgorithm(self): | ||
if self.__checkAll(): | ||
N = int(self.n_entry.get()) | ||
A = [x + 1 for x in range(N)] | ||
random.seed(time.time()) | ||
random.shuffle(A) | ||
|
||
algo = Algorithms() | ||
if self.radio_value.get() == 0: | ||
self.title = "BubbleSort" | ||
self.generator = algo.bubblesort(A) | ||
elif self.radio_value.get() == 1: | ||
self.title = "InsertionSort" | ||
self.generator = algo.insertionsort(A) | ||
elif self.radio_value.get() == 2: | ||
self.title = "MergeSort" | ||
self.generator = algo.mergesort(A, 0, N - 1) | ||
elif self.radio_value.get() == 3: | ||
self.title = "QuickSort" | ||
self.generator = algo.quicksort(A, 0, N - 1) | ||
else: | ||
self.title = "SelectionSort" | ||
self.generator = algo.selectionsort(A) | ||
|
||
self.showFigure(A, N) | ||
else: | ||
messagebox.showerror("Si è verificato un errore", "Valori Inseriti Non Validi!") | ||
|
||
def updateFigure(self, A, rects, iteration): | ||
for rect, val in zip(rects, A): | ||
rect.set_height(val) | ||
iteration[0] += 1 | ||
self.text.set_text("# of Operations: {}".format(iteration[0])) | ||
|
||
def showFigure(self, A, N): | ||
fig, ax = plt.subplots() | ||
ax.set_title(self.title) | ||
bar_rects = ax.bar(range(len(A)), A, align="edge") | ||
ax.set_xlim(0, N) | ||
ax.set_ylim(0, int(1.07 * N)) | ||
self.text = ax.text(0.02, 0.95, "", transform=ax.transAxes) | ||
|
||
iteration = [0] | ||
anim = animation.FuncAnimation(fig, func=self.updateFigure, fargs=(bar_rects, iteration), frames=self.generator, interval=1, repeat=False) | ||
plt.show() | ||
|
||
if __name__ == "__main__": | ||
window = Window() | ||
window.mainloop() |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
matplotlib==3.5.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
class Algorithms: | ||
def swap(self, A, i, j): | ||
if i != j: | ||
A[i], A[j] = A[j], A[i] | ||
|
||
def bubblesort(self, A): | ||
if len(A) == 1: | ||
return | ||
|
||
swapped = True | ||
for i in range(len(A) - 1): | ||
if not swapped: | ||
break | ||
swapped = False | ||
for j in range(len(A) - 1 - i): | ||
if A[j] > A[j + 1]: | ||
self.swap(A, j, j + 1) | ||
swapped = True | ||
yield A | ||
|
||
def insertionsort(self, A): | ||
for i in range(1, len(A)): | ||
j = i | ||
while j > 0 and A[j] < A[j - 1]: | ||
self.swap(A, j, j - 1) | ||
j -= 1 | ||
yield A | ||
|
||
def mergesort(self, A, start, end): | ||
if end <= start: | ||
return | ||
|
||
mid = start + ((end - start + 1) // 2) - 1 | ||
yield from self.mergesort(A, start, mid) | ||
yield from self.mergesort(A, mid + 1, end) | ||
yield from self.merge(A, start, mid, end) | ||
yield A | ||
|
||
def merge(self, A, start, mid, end): | ||
merged = [] | ||
leftIdx = start | ||
rightIdx = mid + 1 | ||
|
||
while leftIdx <= mid and rightIdx <= end: | ||
if A[leftIdx] < A[rightIdx]: | ||
merged.append(A[leftIdx]) | ||
leftIdx += 1 | ||
else: | ||
merged.append(A[rightIdx]) | ||
rightIdx += 1 | ||
|
||
while leftIdx <= mid: | ||
merged.append(A[leftIdx]) | ||
leftIdx += 1 | ||
|
||
while rightIdx <= end: | ||
merged.append(A[rightIdx]) | ||
rightIdx += 1 | ||
|
||
for i, sorted_val in enumerate(merged): | ||
A[start + i] = sorted_val | ||
yield A | ||
|
||
def quicksort(self, A, start, end): | ||
if start >= end: | ||
return | ||
|
||
pivot = A[end] | ||
pivotIdx = start | ||
|
||
for i in range(start, end): | ||
if A[i] < pivot: | ||
self.swap(A, i, pivotIdx) | ||
pivotIdx += 1 | ||
yield A | ||
self.swap(A, end, pivotIdx) | ||
yield A | ||
|
||
yield from self.quicksort(A, start, pivotIdx - 1) | ||
yield from self.quicksort(A, pivotIdx + 1, end) | ||
|
||
|
||
def selectionsort(self, A): | ||
if len(A) == 1: | ||
return | ||
|
||
for i in range(len(A)): | ||
# Find minimum unsorted value. | ||
minVal = A[i] | ||
minIdx = i | ||
for j in range(i, len(A)): | ||
if A[j] < minVal: | ||
minVal = A[j] | ||
minIdx = j | ||
yield A | ||
self.swap(A, i, minIdx) | ||
yield A |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import matplotlib.animation as animation | ||
import matplotlib.pyplot as plt | ||
from sort import Algorithms | ||
import random | ||
import time | ||
|
||
|
||
def main(): | ||
while True: | ||
N = int(input("Enter number of integers: ")) | ||
if N > 0: | ||
while True: | ||
try: | ||
method = int(input("Enter sorting method:\n(1) BubbleSort\n(2) InsertionSort\n(3) MergeSort\n(4) QuickSort\n(5) SelectionSort\n(0) Exit\n> ")) | ||
if method in [i for i in range(0, 6)]: | ||
|
||
# init random list A | ||
A = [x + 1 for x in range(N)] | ||
random.seed(time.time()) | ||
random.shuffle(A) | ||
|
||
algo = Algorithms() | ||
if method == 0: | ||
print("Bye.") | ||
exit() | ||
elif method == 1: | ||
title = "BubbleSort" | ||
generator = algo.bubblesort(A) | ||
elif method == 2: | ||
title = "InsertionSort" | ||
generator = algo.insertionsort(A) | ||
elif method == 3: | ||
title = "MergeSort" | ||
generator = algo.mergesort(A, 0, N - 1) | ||
elif method == 4: | ||
title = "QuickSort" | ||
generator = algo.quicksort(A, 0, N - 1) | ||
elif method == 5: | ||
title = "SelectionSort" | ||
generator = algo.selectionsort(A) | ||
|
||
print(f"You selected {title}") | ||
output(A, N, title, generator) | ||
print("Bye.") | ||
exit() | ||
else: | ||
print("You must enter a number between 0 and 5... Try Again!") | ||
except Exception as e: | ||
print(f"Error: {e}... Try Again!") | ||
else: | ||
print("You must enter a number > 0... Try again!") | ||
|
||
|
||
def update_fig(A, rects, iteration, text): | ||
for rect, val in zip(rects, A): | ||
rect.set_height(val) | ||
iteration[0] += 1 | ||
text.set_text("# of Operations: {}".format(iteration[0])) | ||
|
||
def output(A, N, title, generator): | ||
fig, ax = plt.subplots() | ||
ax.set_title(title) | ||
|
||
bar_rects = ax.bar(range(len(A)), A, align="edge") | ||
ax.set_xlim(0, N) | ||
ax.set_ylim(0, int(1.07 * N)) | ||
|
||
text = ax.text(0.02, 0.95, "", transform=ax.transAxes) | ||
|
||
iteration = [0] | ||
anim = animation.FuncAnimation(fig, func=update_fig, | ||
fargs=(bar_rects, iteration, text), frames=generator, interval=1, | ||
repeat=False) | ||
plt.show() | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |