diff --git a/Lab_1/initial_calculations.py b/Lab_1/initial_calculations.py new file mode 100644 index 0000000..3010f1f --- /dev/null +++ b/Lab_1/initial_calculations.py @@ -0,0 +1,11 @@ +def initial_calculations(input_sets, u_set): + results = [] + results.append(input_sets[1] & (u_set - input_sets[2])) + results.append((u_set - input_sets[0]) & input_sets[2]) + results.append(input_sets[0] & input_sets[1]) + results.append(results[1] | results[2]) + results.append(results[0] | results[3]) + results.append((u_set - input_sets[2]) | results[4]) + results.append(input_sets[1] | results[5]) + results.append((u_set - input_sets[0]) | results[6]) + return results diff --git a/Lab_1/main.py b/Lab_1/main.py new file mode 100644 index 0000000..a2c1d13 --- /dev/null +++ b/Lab_1/main.py @@ -0,0 +1,251 @@ +import window_1, window_2, window_3, window_4, window_5 +from tkinter import * +from tkinter import messagebox +import random +import initial_calculations, simplified_calculations, z_calculations +import shelve + +class Screen_Handler(): + def get_universal_set(self): + u_boundaries = [window_1.lowest_entry.get(), window_1.highest_entry.get()] + + if (not all([item.strip("-").isdigit() for item in u_boundaries])): + messagebox.showerror("Помилка", "Межі універсальної множини мають бути цілими числами.") + return 0 + + u_boundaries = list(map(int, u_boundaries)) + + if (u_boundaries[0] >= u_boundaries[1]): + messagebox.showerror("Помилка", "Нижня межа універсальної множини має бути введена раніше першої.") + else: + self.u_boundaries = u_boundaries + self.set_universal_set() + self.universal_set = set(range(u_boundaries[0], u_boundaries[1]+1)) + + def get_manual_sets(self): + if (not self.check_universal()): + return 0 + + set_getters_list = [i.get for i in window_1.manual_entries] + sets_abc = [i() for i in set_getters_list] + sets_abc = [set(i().split()) for i in set_getters_list] + + if (not all([all([item.strip("-").isdigit() for item in arr]) for arr in sets_abc])): + messagebox.showerror("Помилка", "Множини мають складатися з чисел або бути пустими.") + return 0 + + sets_abc = [set(map(int, curr_set)) for curr_set in sets_abc] + + if (all(map(self.check_manual_sets, sets_abc))): + list(map(self.set_abc_set, sets_abc, window_1.set_labels)) + list(map(self.set_abc_set, sets_abc, window_2.set_labels)) + list(map(self.set_abc_set, sets_abc, window_3.set_labels)) + list(map(self.set_abc_set, sets_abc, window_4.set_labels)) + + self.sets_abc = sets_abc + + def get_generated_sets(self): + if (not self.check_universal()): + return 0 + + cardinalities = [item.get() for item in window_1.cardinality_entries] + + if (not all([item.isdigit() for item in cardinalities])): + messagebox.showerror("Помилка", "Потужності мають бути числами.") + return 0 + cardinalities = list(map(int, cardinalities)) + + if (max(cardinalities) > len(self.universal_set)): + messagebox.showerror("Помилка", "Потужності не можуть перевищувати кількість елементів в універсальній множині.") + return 0 + + sets_abc = [set(random.sample(range(min(self.universal_set), max(self.universal_set)+1), i)) for i in cardinalities] + + list(map(self.set_abc_set, sets_abc, window_1.set_labels)) + list(map(self.set_abc_set, sets_abc, window_2.set_labels)) + list(map(self.set_abc_set, sets_abc, window_3.set_labels)) + list(map(self.set_abc_set, sets_abc, window_4.set_labels)) + + self.sets_abc = sets_abc + + def check_manual_sets(self, curr_set): + if curr_set: + if (max(curr_set) > max(self.universal_set) or min(curr_set) < min(self.universal_set)): + messagebox.showerror("Помилка", "Вихід за межі універсальної множини.") + return False + else: + return True + else: + return True + + def initial_calculation_sets(self): + results = initial_calculations.initial_calculations(self.sets_abc, self.universal_set) + + result_labels = window_2.calculation_result_labels + + for i in range(len(results)): + results_text = set(map(str, results[i])) + + results_text = f"{{ {'; '.join(results_text)} }}" + + result_labels[i].configure(text=results_text) + + window_2.elements_D_label.configure(text=results_text) + + self.initial_D = results[-1] + + def simple_calculation_sets(self): + results = simplified_calculations.simplified_calculations(self.sets_abc, self.universal_set) + + result_labels = window_3.calculation_result_labels + + for i in range(len(results)): + results_text = set(map(str, results[i])) + + results_text = f"{{ {'; '.join(results_text)} }}" + + result_labels[i].configure(text=results_text) + + window_3.elements_D_label.configure(text=results_text) + + self.simple_D = results[-1] + + def z_calculations(self): + custom_results = z_calculations.z_calculations(self.sets_abc, self.universal_set) + + result_labels = window_4.step_results + + for i in range(len(custom_results)): + results_text = set(map(str, custom_results[i])) + + results_text = f"{{ {'; '.join(results_text)} }}" + + result_labels[i].configure(text=results_text) + + window_4.elements_Z_label.configure(text = results_text) + + self.custom_Z = custom_results[-1] + self.default_Z = z_calculations.z_calculations_in(self.sets_abc, self.universal_set) + + def set_universal_set(self): + lower_boundary, upper_boundary = map(str, self.u_boundaries) + universal_text = f"{{ {lower_boundary}; ...; {upper_boundary} }}" + window_1.elements_U_label.configure(text = universal_text) + + def set_abc_set(self, curr_set, curr_label): + curr_set = set(map(str, curr_set)) + curr_text = f"{{ {'; '.join(curr_set)} }}" + curr_label.configure(text = curr_text) + + def check_universal(self): + if (not hasattr(self, "universal_set")): + messagebox.showerror("Помилка", "Універсальна множина не задана.") + return False + else: + return True + + def save_initial_D(self): + if (not hasattr(self, "initial_D")): + messagebox.showerror("Помилка", "Множина D не знайдена.") + return 0 + + with shelve.open("save.db") as sh: + sh["initial_D"] = self.initial_D + + def save_simple_D(self): + if (not hasattr(self, "simple_D")): + messagebox.showerror("Помилка", "Множина D не знайдена.") + return 0 + + with shelve.open("save.db") as sh: + sh["simple_D"] = self.simple_D + + def save_Z(self): + if (not (hasattr(self, "custom_Z") or hasattr(self, "default_Z"))): + messagebox.showerror("Помилка", "Множина Z не знайдена.") + return 0 + + with shelve.open("save.db") as sh: + sh["custom_Z"] = self.custom_Z + sh["default_Z"] = self.default_Z + + def read_initial_D(self): + with shelve.open("save.db") as sh: + if ("initial_D" in sh.keys()): + initial_D = set(map(str, sh["initial_D"])) + initial_D = f"{{ {'; '.join(initial_D)} }}" + window_5.initial_D_elements.configure(text=initial_D) + else: + messagebox.showerror("Помилка", "Множина D не збережена.") + + def read_simple_D(self): + with shelve.open("save.db") as sh: + if ("simple_D" in sh.keys()): + simple_D = set(map(str, sh["simple_D"])) + simple_D = f"{{ {'; '.join(simple_D)} }}" + window_5.simplified_D_elements.configure(text=simple_D) + else: + messagebox.showerror("Помилка", "Множина D не збережена.") + + def read_default_Z(self): + with shelve.open("save.db") as sh: + if ("default_Z" in sh.keys()): + default_Z = set(map(str, sh["default_Z"])) + default_Z = f"{{ {'; '.join(default_Z)} }}" + window_5.python_Z_elements.configure(text=default_Z) + else: + messagebox.showerror("Помилка", "Множина Z не збережена.") + + def read_custom_Z(self): + with shelve.open("save.db") as sh: + if ("custom_Z" in sh.keys()): + custom_Z = set(map(str, sh["custom_Z"])) + custom_Z = f"{{ {'; '.join(custom_Z)} }}" + window_5.custom_Z_elements.configure(text=custom_Z) + else: + messagebox.showerror("Помилка", "Множина Z не збережена.") + + def compare_D(self): + with shelve.open("save.db") as sh: + if (sh["initial_D"] == sh["simple_D"]): + messagebox.showinfo("Порівняння D", "Множини D збігаються.") + else: + messagebox.showinfo("Порівняння D", "Множини D не збігаються.") + + def compare_Z(self): + with shelve.open("save.db") as sh: + if (sh["default_Z"] == sh["custom_Z"]): + messagebox.showinfo("Порівняння Z", "Множини Z збігаються") + else: + messagebox.showinfo("Порівняння Z", "Множини Z не збігаються.") + + def clear_saves(self): + sh = shelve.open("save.db", flag="n") + sh.close() + + def configure_buttons(self): + window_1.set_U_button.configure(command=self.get_universal_set) + window_1.set_manual_button.configure(command=self.get_manual_sets) + window_1.set_generation_button.configure(command=self.get_generated_sets) + + window_2.start_calculations_button.configure(command=self.initial_calculation_sets) + window_2.save_D_button.configure(command=self.save_initial_D) + + window_3.start_calculations_button.configure(command=self.simple_calculation_sets) + window_3.save_D_button.configure(command=self.save_simple_D) + + window_4.start_calculations_button.configure(command=self.z_calculations) + window_4.save_Z_button.configure(command=self.save_Z) + + window_5.clear_save_button.configure(command=self.clear_saves) + window_5.read_initial_D_button.configure(command=self.read_initial_D) + window_5.read_simplified_D_button.configure(command=self.read_simple_D) + window_5.read_default_Z_button.configure(command=self.read_default_Z) + window_5.read_custom_Z_button.configure(command=self.read_custom_Z) + window_5.compare_D_button.configure(command=self.compare_D) + window_5.compare_Z_button.configure(command=self.compare_Z) + +screens = Screen_Handler() +screens.configure_buttons() + +window_1.root.mainloop() diff --git a/Lab_1/save.db b/Lab_1/save.db new file mode 100644 index 0000000..8eedda1 Binary files /dev/null and b/Lab_1/save.db differ diff --git a/Lab_1/simplified_calculations.py b/Lab_1/simplified_calculations.py new file mode 100644 index 0000000..bd6896b --- /dev/null +++ b/Lab_1/simplified_calculations.py @@ -0,0 +1,6 @@ +def simplified_calculations(input_sets, u_set): + results = [] + results.append(u_set - input_sets[0]) + results.append(results[0] | input_sets[1]) + results.append(results[1] | (u_set - input_sets[2])) + return results diff --git a/Lab_1/window_1.py b/Lab_1/window_1.py new file mode 100644 index 0000000..dffed9f --- /dev/null +++ b/Lab_1/window_1.py @@ -0,0 +1,174 @@ +from tkinter import * + +root = Tk() +root.title("Головний екран") + +# Віджети ідентифікації студента +id_frame = Frame(root, bd=5) + +id_label = Label(id_frame, text="Ідентифікація") + +surname_label = Label(id_frame, text="Прізвище:") +surname_entry = Label(id_frame, text="Швед") + +name_label = Label(id_frame, text="Ім'я:") +name_entry = Label(id_frame, text="Андрій") + +parental_label = Label(id_frame, text="По-батькові:") +parental_entry = Label(id_frame, text="Дмитрович") + +group_number_name = Label(id_frame, text="Номер групи:") +group_number_entry = Label(id_frame, text="23") + +student_number_name = Label(id_frame, text="Номер у списку:") +student_number_entry = Label(id_frame, text="30") + +variant_label = Label(id_frame, text="Варіант:") +variant_result_label = Label(id_frame, text="24") + +# Пакувальники ідентифікації студента +id_frame.grid(row=0, column=0) + +id_label.grid(row=0, column=0, columnspan=2) + +surname_label.grid(row=1, column=0, sticky=E) +surname_entry.grid(row=1, column=1, sticky=W) + +name_label.grid(row=2, column=0, sticky=E) +name_entry.grid(row=2, column=1, sticky=W) + +parental_label.grid(row=3, column=0, sticky=E) +parental_entry.grid(row=3, column=1, sticky=W) + +group_number_name.grid(row=4, column=0, sticky=E) +group_number_entry.grid(row=4, column=1, sticky=W) + +student_number_name.grid(row=5, column=0, sticky=E) +student_number_entry.grid(row=5, column=1, sticky=W) + +variant_label.grid(row=6, column=0, sticky=E) +variant_result_label.grid(row=6, column=1, sticky=W) + +# Віджети універсальної множини +universal_set_frame = Frame(root, bd=5) + +universal_set_label = Label(universal_set_frame, text="Межі універсальної множини") + +lowest_label = Label(universal_set_frame, text="Від:") +highest_label = Label(universal_set_frame, text="До:") + +lowest_entry = Entry(universal_set_frame, width=20) +highest_entry = Entry(universal_set_frame, width=20) + +set_U_button = Button(universal_set_frame, text="Задати універсальну множину") + +set_U_label = Label(universal_set_frame, text="Множина U:") +elements_U_label = Label(universal_set_frame) + +# Пакувальники універсальної множини +universal_set_frame.grid(row=1, column=0) + +universal_set_label.grid(row=0, column=0, columnspan=4) + +lowest_label.grid(row=1, column=0) +lowest_entry.grid(row=1, column=1) + +highest_label.grid(row=1, column=2) +highest_entry.grid(row=1, column=3) + +set_U_button.grid(row=2, column=0, columnspan=4) + +set_U_label.grid(row=3, column=0, columnspan=2, sticky=E) +elements_U_label.grid(row=3, column=2, columnspan=2, sticky=W) + +# Віджети задання множин +set_declaration_frame = Frame(root, bd=5) + +set_declaration_label = Label(set_declaration_frame, text="Задання множин", bd=5) + +set_generation_label = Label(set_declaration_frame, text="Випадкова генерація", bd=5) + +cardinality_A_label = Label(set_declaration_frame, text="Потужність A:") +cardinality_A_entry = Entry(set_declaration_frame, width=20) + +cardinality_B_label = Label(set_declaration_frame, text="Потужність B:") +cardinality_B_entry = Entry(set_declaration_frame, width=20) + +cardinality_C_label = Label(set_declaration_frame, text="Потужність C:") +cardinality_C_entry = Entry(set_declaration_frame, width=20) + +cardinality_entries = [cardinality_A_entry, cardinality_B_entry, cardinality_C_entry] + +set_generation_button = Button(set_declaration_frame, text="Згенерувати множини") + +set_manual_label = Label(set_declaration_frame, text="Ручний ввід", bd=5) + +manual_A_label = Label(set_declaration_frame, text="Введіть множину A:") +manual_A_entry = Entry(set_declaration_frame, width=40) + +manual_B_label = Label(set_declaration_frame, text="Введіть множину B:") +manual_B_entry = Entry(set_declaration_frame, width=40) + +manual_C_label = Label(set_declaration_frame, text="Введіть множину C:") +manual_C_entry = Entry(set_declaration_frame, width=40) + +set_manual_button = Button(set_declaration_frame, text="Задати введені множини") + +manual_entries = [manual_A_entry, manual_B_entry, manual_C_entry] + +# Пакувальники задання множин +set_declaration_frame.grid(row=2, column=0) + +set_declaration_label.grid(row=0, column=0, columnspan=4) + +set_generation_label.grid(row=1, column=0, columnspan=2) + +cardinality_A_label.grid(row=2, column=0, sticky=E) +cardinality_A_entry.grid(row=2, column=1) + +cardinality_B_label.grid(row=3, column=0, sticky=E) +cardinality_B_entry.grid(row=3, column=1) + +cardinality_C_label.grid(row=4, column=0, sticky=E) +cardinality_C_entry.grid(row=4, column=1) + +set_generation_button.grid(row=5, column=0, columnspan=2) + +set_manual_label.grid(row=1, column=2, columnspan=2) + +manual_A_label.grid(row=2, column=2, sticky=E) +manual_A_entry.grid(row=2, column=3) + +manual_B_label.grid(row=3, column=2, sticky=E) +manual_B_entry.grid(row=3, column=3) + +manual_C_label.grid(row=4, column=2, sticky=E) +manual_C_entry.grid(row=4, column=3) + +set_manual_button.grid(row=5, column=2, columnspan=2) + +# Віджети множин +sets_frame = Frame(root, bd=5) + +set_A_label = Label(sets_frame, text="Множина A:") +elements_A_label = Label(sets_frame) + +set_B_label = Label(sets_frame, text="Множина B:") +elements_B_label = Label(sets_frame) + +set_C_label = Label(sets_frame, text="Множина C:") +elements_C_label = Label(sets_frame) + +set_labels = [elements_A_label, elements_B_label, elements_C_label] + +# Пакувальники множин +sets_frame.grid(row=3, column=0) + +set_A_label.grid(row=0, column=0, sticky=E) +elements_A_label.grid(row=0, column=1, sticky=W) + +set_B_label.grid(row=1, column=0, sticky=E) +elements_B_label.grid(row=1, column=1, sticky=W) + +set_C_label.grid(row=2, column=0, sticky=E) +elements_C_label.grid(row=2, column=1, sticky=W) diff --git a/Lab_1/window_2.py b/Lab_1/window_2.py new file mode 100644 index 0000000..82a556d --- /dev/null +++ b/Lab_1/window_2.py @@ -0,0 +1,104 @@ +from tkinter import * + +root = Tk() +root.title("Розрахунки початкового виразу") + +# Віджети введених множин +sets_frame = Frame(root, bd=5) + +set_A_label = Label(sets_frame, text="Множина A:", bd=5) +elements_A_label = Label(sets_frame) + +set_B_label = Label(sets_frame, text="Множина B:", bd=5) +elements_B_label = Label(sets_frame) + +set_C_label = Label(sets_frame, text="Множина C:", bd=5) +elements_C_label = Label(sets_frame) + +set_labels = [elements_A_label, elements_B_label, elements_C_label] + +# Пакувальники введених множин +sets_frame.grid(row=0, column=0) + +set_A_label.grid(row=0, column=0, sticky=E) +elements_A_label.grid(row=0, column=1, sticky=W) + +set_B_label.grid(row=1, column=0, sticky=E) +elements_B_label.grid(row=1, column=1, sticky=W) + +set_C_label.grid(row=2, column=0, sticky=E) +elements_C_label.grid(row=2, column=1, sticky=W) + +# Кнопка початку розрахунків +start_calculations_button = Button(root, text="Почати розрахунки") +start_calculations_button.grid(row=1, column=0) + +# Віджети покрокового розв'язання +calculations_frame = Frame(root, bd=5) + +expression_label = Label(calculations_frame, text="Вираз: D = ¬A ∪ B ∪ ¬C ∪ (B ∩ ¬C) ∪ (¬A ∩ C) ∪ (A ∩ B)", bd=5) + +first_step_label = Label(calculations_frame, text="(B ∩ ¬C) = ", bd=5) +first_step_result = Label(calculations_frame) + +second_step_label = Label(calculations_frame, text="(¬A ∩ C) = ", bd=5) +second_step_result = Label(calculations_frame) + +third_step_label = Label(calculations_frame, text="(A ∩ B) = ", bd=5) +third_step_result = Label(calculations_frame) + +fourth_step_label = Label(calculations_frame, text="(¬A ∩ C) ∪ (A ∩ B) = ", bd=5) +fourth_step_result = Label(calculations_frame) + +fifth_step_label = Label(calculations_frame, text="(B ∩ ¬C) ∪ (¬A ∩ C) ∪ (A ∩ B) = ", bd=5) +fifth_step_result = Label(calculations_frame) + +sixth_step_label = Label(calculations_frame, text="¬C ∪ (B ∩ ¬C) ∪ (¬A ∩ C) ∪ (A ∩ B) = ", bd=5) +sixth_step_result = Label(calculations_frame) + +seventh_step_label = Label(calculations_frame, text="B ∪ ¬C ∪ (B ∩ ¬C) ∪ (¬A ∩ C) ∪ (A ∩ B) = ", bd=5) +seventh_step_result = Label(calculations_frame) + +eighth_step_label = Label(calculations_frame, text="¬A ∪ B ∪ ¬C ∪ (B ∩ ¬C) ∪ (¬A ∩ C) ∪ (A ∩ B) = ", bd=5) +eighth_step_result = Label(calculations_frame) + +calculation_result_labels = [first_step_result, second_step_result, third_step_result, fourth_step_result, fifth_step_result, sixth_step_result, seventh_step_result, eighth_step_result] + +# Пакувальники покрокового розв'язання +calculations_frame.grid(row=2, column=0) + +expression_label.grid(row=0, column=0, columnspan=2) + +first_step_label.grid(row=1, column=0, sticky=E) +second_step_label.grid(row=2, column=0, sticky=E) +third_step_label.grid(row=3, column=0, sticky=E) +fourth_step_label.grid(row=4, column=0, sticky=E) +fifth_step_label.grid(row=5, column=0, sticky=E) +sixth_step_label.grid(row=6, column=0, sticky=E) +seventh_step_label.grid(row=7, column=0, sticky=E) +eighth_step_label.grid(row=8, column=0, sticky=E) + +first_step_result.grid(row=1, column=1, sticky=W) +second_step_result.grid(row=2, column=1, sticky=W) +third_step_result.grid(row=3, column=1, sticky=W) +fourth_step_result.grid(row=4, column=1, sticky=W) +fifth_step_result.grid(row=5, column=1, sticky=W) +sixth_step_result.grid(row=6, column=1, sticky=W) +seventh_step_result.grid(row=7, column=1, sticky=W) +eighth_step_result.grid(row=8, column=1, sticky=W) + +# Віджети множини D +d_frame = Frame(root, bd=5) + +set_D_label = Label(d_frame, text="Множина D:", bd=5) +elements_D_label = Label(d_frame) + +save_D_button = Button(d_frame, text="Зберегти D") + +# Пакувальники множини D +d_frame.grid(row=3, column=0) + +set_D_label.grid(row=0, column=0, sticky=E) +elements_D_label.grid(row=0, column=1, sticky=W) + +save_D_button.grid(row=1, column=0, columnspan=2) diff --git a/Lab_1/window_3.py b/Lab_1/window_3.py new file mode 100644 index 0000000..54e57b8 --- /dev/null +++ b/Lab_1/window_3.py @@ -0,0 +1,79 @@ +from tkinter import * + +root = Tk() +root.title("Розрахунки спрощеного виразу") + +# Віджети введених множин +sets_frame = Frame(root, bd=5) + +set_A_label = Label(sets_frame, text="Множина A:", bd=5) +elements_A_label = Label(sets_frame) + +set_B_label = Label(sets_frame, text="Множина B:", bd=5) +elements_B_label = Label(sets_frame) + +set_C_label = Label(sets_frame, text="Множина C:", bd=5) +elements_C_label = Label(sets_frame) + +# Пакувальники введених множин +sets_frame.grid(row=0, column=0) + +set_A_label.grid(row=0, column=0, sticky=E) +elements_A_label.grid(row=0, column=1, sticky=W) + +set_B_label.grid(row=1, column=0, sticky=E) +elements_B_label.grid(row=1, column=1, sticky=W) + +set_C_label.grid(row=2, column=0, sticky=E) +elements_C_label.grid(row=2, column=1, sticky=W) + +set_labels = [elements_A_label, elements_B_label, elements_C_label] + +# Кнопка початку розрахунків +start_calculations_button = Button(root, text="Почати розрахунки") +start_calculations_button.grid(row=1, column=0) + +# Віджети покрокового розв'язання +calculations_frame = Frame(root, bd=5) + +expression_label = Label(calculations_frame, text="Вираз: D = ¬A ∪ B ∪ ¬C", bd=5) + +first_step_label = Label(calculations_frame, text="¬A = ", bd=5) +first_step_result = Label(calculations_frame) + +second_step_label = Label(calculations_frame, text="¬A ∪ B = ", bd=5) +second_step_result = Label(calculations_frame) + +third_step_label = Label(calculations_frame, text="¬A ∪ B ∪ ¬C = ", bd=5) +third_step_result = Label(calculations_frame) + +calculation_result_labels = [first_step_result, second_step_result, third_step_result] + +# Пакувальники покрокового розв'язання +calculations_frame.grid(row=2, column=0) + +expression_label.grid(row=0, column=0, columnspan=2) + +first_step_label.grid(row=1, column=0, sticky=E) +second_step_label.grid(row=2, column=0, sticky=E) +third_step_label.grid(row=3, column=0, sticky=E) + +first_step_result.grid(row=1, column=1, sticky=W) +second_step_result.grid(row=2, column=1, sticky=W) +third_step_result.grid(row=3, column=1, sticky=W) + +# Віджети множини D +d_frame = Frame(root, bd=5) + +set_D_label = Label(d_frame, text="Множина D:", bd=5) +elements_D_label = Label(d_frame) + +save_D_button = Button(d_frame, text="Зберегти D") + +# Пакувальники множини D +d_frame.grid(row=3, column=0) + +set_D_label.grid(row=0, column=0) +elements_D_label.grid(row=0, column=1) + +save_D_button.grid(row=1, column=0, columnspan=2) diff --git a/Lab_1/window_4.py b/Lab_1/window_4.py new file mode 100644 index 0000000..174b3a5 --- /dev/null +++ b/Lab_1/window_4.py @@ -0,0 +1,79 @@ +from tkinter import * + +root = Tk() +root.title("Обчислення Z") + +# Віджети введених множин +sets_frame = Frame(root, bd=5) + +set_A_label = Label(sets_frame, text="Множина A:", bd=5) +elements_A_label = Label(sets_frame) + +set_B_label = Label(sets_frame, text="Множина B:", bd=5) +elements_B_label = Label(sets_frame) + +set_C_label = Label(sets_frame, text="Множина C:", bd=5) +elements_C_label = Label(sets_frame) + +# Пакувальники введених множин +sets_frame.grid(row=0, column=0) + +set_A_label.grid(row=0, column=0, sticky=E) +elements_A_label.grid(row=0, column=1, sticky=W) + +set_B_label.grid(row=1, column=0, sticky=E) +elements_B_label.grid(row=1, column=1, sticky=W) + +set_C_label.grid(row=2, column=0, sticky=E) +elements_C_label.grid(row=2, column=1, sticky=W) + +set_labels = [elements_A_label, elements_B_label, elements_C_label] + +# Кнопка початку розрахунків +start_calculations_button = Button(root, text="Почати розрахунки") +start_calculations_button.grid(row=1, column=0) + +# Віджети покрокового розв'язання +calculations_frame = Frame(root, bd=5) + +expression_label = Label(calculations_frame, text="Вираз: Z = X ∆ Y", bd=5) + +first_step_label = Label(calculations_frame, text="X = ¬B = ", bd=5) +first_step_result = Label(calculations_frame) + +second_step_label = Label(calculations_frame, text="Y = ¬A = ", bd=5) +second_step_result = Label(calculations_frame) + +third_step_label = Label(calculations_frame, text="Z = ", bd=5) +third_step_result = Label(calculations_frame) + +step_results = [first_step_result, second_step_result, third_step_result] + +# Пакувальники покрокового розв'язання +calculations_frame.grid(row=2, column=0, sticky=W) + +expression_label.grid(row=0, column=0, columnspan=2) + +first_step_label.grid(row=1, column=0, sticky=E) +second_step_label.grid(row=2, column=0, sticky=E) +third_step_label.grid(row=3, column=0, sticky=E) + +first_step_result.grid(row=1, column=1, sticky=W) +second_step_result.grid(row=2, column=1, sticky=W) +third_step_result.grid(row=3, column=1, sticky=W) + +# Віджети множини Z +z_frame = Frame(root, bd=5) + +set_Z_label = Label(z_frame, text="Множина Z:", bd=5) +elements_Z_label = Label(z_frame) + +save_Z_button = Button(z_frame, text="Зберегти Z") + +# Пакувальники множини Z +z_frame.grid(row=3, column=0) + +set_Z_label.grid(row=0, column=0) +elements_Z_label.grid(row=0, column=1) + +save_Z_button.grid(row=1, column=0, columnspan=2) diff --git a/Lab_1/window_5.py b/Lab_1/window_5.py new file mode 100644 index 0000000..07c22cf --- /dev/null +++ b/Lab_1/window_5.py @@ -0,0 +1,89 @@ +from tkinter import * + +root = Tk() +root.title("Збереження і відображення") + +# Віджети початкового виразу +read_initial_frame = Frame(root, bd=5) + +read_initial_D_button = Button(read_initial_frame, text="Зчитати результати\nобчислення початкового виразу") +initial_D_label = Label(read_initial_frame, text="D = ", bd=5) +initial_D_elements = Label(read_initial_frame) + +# Пакувальники початкового виразу +read_initial_frame.grid(row=0, column=0) + +read_initial_D_button.grid(row=0, column=0, columnspan=2) +initial_D_label.grid(row=1, column=0, sticky=E) +initial_D_elements.grid(row=1, column=1, sticky=W) + +# Віджети спрощеного виразу +read_simplified_frame = Frame(root, bd=5) + +read_simplified_D_button = Button(read_simplified_frame, text="Зчитати результати\nобчислення спрощеного виразу") +simplified_D_label = Label(read_simplified_frame, text="D = ", bd=5) +simplified_D_elements = Label(read_simplified_frame) + +# Пакувальники спрощеного виразу +read_simplified_frame.grid(row=0, column=1) + +read_simplified_D_button.grid(row=0, column=0, columnspan=2) +simplified_D_label.grid(row=1, column=0, sticky=E) +simplified_D_elements.grid(row=1, column=1, sticky=W) + +# Віджети Z вбудованої +read_python_z_frame = Frame(root, bd=5) + +read_default_Z_button = Button(read_python_z_frame, text="Зчитати Z обчислену\nвбудованими функціями") +python_Z_label = Label(read_python_z_frame, text="Z = ", bd=5) +python_Z_elements = Label(read_python_z_frame) + +# Пакувальники Z вбудованої +read_python_z_frame.grid(row=1, column=0) + +read_default_Z_button.grid(row=0, column=0, columnspan=2) +python_Z_label.grid(row=1, column=0, sticky=E) +python_Z_elements.grid(row=1, column=1, sticky=W) + +# Віджети Z написаної +read_custom_z_frame = Frame(root, bd=5) + +read_custom_Z_button = Button(read_custom_z_frame, text="Зчитати Z обчислену\nнаписаною функцією") +custom_Z_label = Label(read_custom_z_frame, text="Z = ", bd=5) +custom_Z_elements = Label(read_custom_z_frame) + +# Пакувальники Z написаної +read_custom_z_frame.grid(row=1, column=1) + +read_custom_Z_button.grid(row=0, column=0, columnspan=2) +custom_Z_label.grid(row=1, column=0, sticky=E) +custom_Z_elements.grid(row=1, column=1, sticky=W) + +# Віджети порівняння D +compare_D_frame = Frame(root, bd=5) + +compare_D_button = Button(compare_D_frame, text="Порівняти D") + +# Пакувальники порівняння D +compare_D_frame.grid(row=2, column=0) + +compare_D_button.grid(row=0, column=0) + +# Віджети порівняння Z +compare_Z_frame = Frame(root, bd=5) + +compare_Z_button = Button(compare_Z_frame, text="Порівняти Z") + +# Пакувальники порівняння Z +compare_Z_frame.grid(row=2, column=1) + +compare_Z_button.grid(row=0, column=0) + +# Очищення файлів +clear_save_frame = Frame(root, bd=5) + +clear_save_button = Button(clear_save_frame, text="Очистити збережені множини") + +clear_save_frame.grid(row=3, column=0, columnspan=2) + +clear_save_button.grid(row=0, column=0) diff --git a/Lab_1/z_calculations.py b/Lab_1/z_calculations.py new file mode 100644 index 0000000..dbbcbdd --- /dev/null +++ b/Lab_1/z_calculations.py @@ -0,0 +1,21 @@ +def z_calculations(input_sets, u_set): + x = u_set - input_sets[1] + y = u_set - input_sets[0] + results = set() + for curr_elem in x: + if (curr_elem not in y): + results.add(curr_elem) + + for curr_elem in y: + if (curr_elem not in x): + results.add(curr_elem) + + return [x, y, results] + +def z_calculations_in(input_sets, u_set): + x = u_set - input_sets[1] + y = u_set - input_sets[0] + + results = x ^ y + + return results diff --git a/Lab_2/dat/saved_sets b/Lab_2/dat/saved_sets new file mode 100644 index 0000000..d38d3c3 Binary files /dev/null and b/Lab_2/dat/saved_sets differ diff --git a/Lab_2/main.py b/Lab_2/main.py new file mode 100644 index 0000000..75adc70 --- /dev/null +++ b/Lab_2/main.py @@ -0,0 +1,18 @@ +import window_1 as w_1 +import sys +from PyQt5 import QtWidgets + +female_names = ["Діана", "Оксана", "Катерина", "Карина", "Антоніна"] +male_names = ["Андрій", "Сергій", "Микола", "Євгеній", "Олександр"] + +app = QtWidgets.QApplication(sys.argv) + +app.setStyleSheet(open("style.css").read()) + +window_1 = w_1.Window() + +window_1.window_2.set_sets(female_names, male_names) + +window_1.show() + +sys.exit(app.exec_()) diff --git a/Lab_2/style.css b/Lab_2/style.css new file mode 100644 index 0000000..89ed7b6 --- /dev/null +++ b/Lab_2/style.css @@ -0,0 +1,26 @@ +QWidget{ + border-radius: 10px; + padding: 4px; + margin: 2px; + font-family: "Liberation Mono"; + font-size: 14pt; +} +QPushButton{ + background-color: blueviolet; + color: white; +} +QPushButton:hover{ + background-color: #6f20b3; +} +QPushButton:pressed{ + background-color: #8f58c9; +} +QListView{ + border: 3px solid blueviolet; +} +QLabel{ + border: 3px solid blueviolet; +} +QRadioButton{ + border: 3px solid blueviolet; +} \ No newline at end of file diff --git a/Lab_2/window_1.py b/Lab_2/window_1.py new file mode 100644 index 0000000..ec0a2ec --- /dev/null +++ b/Lab_2/window_1.py @@ -0,0 +1,116 @@ +from PyQt5 import QtCore, QtWidgets +from sys import exit +import window_2 as w_2, window_3 as w_3, window_4 as w_4 + + +def open_window(window): + window.show() + + +class Window(QtWidgets.QMainWindow): + + def __init__(self): + + super(QtWidgets.QMainWindow, self).__init__() + + self.window_2 = w_2.Window() + self.window_3 = w_3.Window() + self.window_4 = w_4.Window() + + self.setWindowTitle("Вікно 1") + + self.centralwidget = QtWidgets.QWidget(self) + + self.gridLayout = QtWidgets.QGridLayout(self.centralwidget) + + self.full_name = QtWidgets.QLabel(self.centralwidget) + self.full_name.setText("П. І. Б:") + self.full_name.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.gridLayout.addWidget(self.full_name, 0, 0, 1, 1) + + self.full_name_answer = QtWidgets.QLabel(self.centralwidget) + self.full_name_answer.setText("Швед Андрій Дмитрович") + self.gridLayout.addWidget(self.full_name_answer, 0, 1, 1, 1) + + self.group = QtWidgets.QLabel(self.centralwidget) + self.group.setText("Група:") + self.group.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.gridLayout.addWidget(self.group, 1, 0, 1, 1) + + self.group_answer = QtWidgets.QLabel(self.centralwidget) + self.group_answer.setText("ІО-23") + self.gridLayout.addWidget(self.group_answer, 1, 1, 1, 1) + + self.list_number = QtWidgets.QLabel(self.centralwidget) + self.list_number.setText("Номер в списку:") + self.list_number.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.gridLayout.addWidget(self.list_number, 2, 0, 1, 1) + + self.list_number_answer = QtWidgets.QLabel(self.centralwidget) + self.list_number_answer.setText("30") + self.gridLayout.addWidget(self.list_number_answer, 2, 1, 1, 1) + + self.task_number = QtWidgets.QLabel(self.centralwidget) + self.task_number.setText("Номер завдання:") + self.task_number.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.gridLayout.addWidget(self.task_number, 3, 0, 1, 1) + + self.task_number_answer = QtWidgets.QLabel(self.centralwidget) + self.task_number_answer.setText("24") + self.gridLayout.addWidget(self.task_number_answer, 3, 1, 1, 1) + + self.setCentralWidget(self.centralwidget) + + self.menubar = QtWidgets.QMenuBar(self) + self.menubar.setGeometry(QtCore.QRect(0, 0, 362, 22)) + + self.menubar.setDefaultUp(False) + + self.menu_Windows = QtWidgets.QMenu(self.menubar) + self.menu_Windows.setTitle("Вікна") + self.setMenuBar(self.menubar) + + self.window_2_action = QtWidgets.QAction(self) + self.window_2_action.setText("Вікно 2") + self.menu_Windows.addAction(self.window_2_action) + + self.window_3_action = QtWidgets.QAction(self) + self.window_3_action.setText("Вікно 3") + self.menu_Windows.addAction(self.window_3_action) + + self.window_4_action = QtWidgets.QAction(self) + self.window_4_action.setText("Вікно 4") + self.menu_Windows.addAction(self.window_4_action) + + self.menu_Windows.addSeparator() + + self.exit_action = QtWidgets.QAction(self) + self.exit_action.setText("Вихід") + self.menu_Windows.addAction(self.exit_action) + + self.menubar.addAction(self.menu_Windows.menuAction()) + + self.set_menu() + + QtCore.QMetaObject.connectSlotsByName(self) + + self.female_names = ["Діана", "Оксана", "Катерина", "Карина", "Антоніна"] + self.male_names = ["Андрій", "Сергій", "Микола", "Євгеній", "Олександр"] + + def set_menu(self): + self.window_2_action.triggered.connect(lambda: open_window(self.window_2)) + self.window_3_action.triggered.connect(lambda: self.open_window_3()) + self.window_4_action.triggered.connect(lambda: self.open_window_4()) + self.exit_action.triggered.connect(lambda: exit()) + + def open_window_3(self): + self.window_3.set_sets(self.window_2.get_set_A(), self.window_2.get_set_B(), self.female_names, self.male_names) + self.window_3.form_relations() + open_window(self.window_3) + + def open_window_4(self): + self.window_4.set_sets( + self.window_3.get_granddaughter(), self.window_3.get_godmother(), + self.window_2.get_set_A(), self.window_2.get_set_B() + ) + open_window(self.window_4) diff --git a/Lab_2/window_2.py b/Lab_2/window_2.py new file mode 100644 index 0000000..f8f258e --- /dev/null +++ b/Lab_2/window_2.py @@ -0,0 +1,132 @@ +from PyQt5 import QtCore, QtWidgets + + +def save_set(set_to_save, set_name): + import shelve + with shelve.open("dat/saved_sets") as f: + try: + f[set_name] = set_to_save + except: + pass + + +class Window(QtWidgets.QWidget): + + def __init__(self): + + super(QtWidgets.QWidget, self).__init__() + + self.setWindowTitle("Вікно 2") + + self.gridLayout_2 = QtWidgets.QGridLayout(self) + + self.A = QtWidgets.QRadioButton(self) + self.A.setText("A") + self.A.setChecked(True) + self.gridLayout_2.addWidget(self.A, 0, 0, 1, 1) + + self.B = QtWidgets.QRadioButton(self) + self.B.setText("B") + self.gridLayout_2.addWidget(self.B, 0, 1, 1, 1) + + self.label_female = QtWidgets.QLabel(self) + self.label_female.setText("Жінки") + self.label_female.setAlignment(QtCore.Qt.AlignCenter) + self.gridLayout_2.addWidget(self.label_female, 1, 0, 1, 1) + + self.label_male = QtWidgets.QLabel(self) + self.label_male.setText("Чоловіки") + self.label_male.setAlignment(QtCore.Qt.AlignCenter) + self.gridLayout_2.addWidget(self.label_male, 1, 1, 1, 1) + + self.list_female = QtWidgets.QListWidget(self) + self.gridLayout_2.addWidget(self.list_female, 2, 0, 1, 1) + + self.list_male = QtWidgets.QListWidget(self) + self.gridLayout_2.addWidget(self.list_male, 2, 1, 1, 1) + + self.sets_label = QtWidgets.QLabel(self) + self.sets_label.setText("A: \nB: ") + self.gridLayout_2.addWidget(self.sets_label, 4, 0, 1, 2) + + self.clear_A = QtWidgets.QPushButton(self) + self.clear_A.setText("Очистити А") + self.gridLayout_2.addWidget(self.clear_A, 5, 0, 1, 1) + + self.clear_B = QtWidgets.QPushButton(self) + self.clear_B.setText("Очистити B") + self.gridLayout_2.addWidget(self.clear_B, 5, 1, 1, 1) + + self.save_A = QtWidgets.QPushButton(self) + self.save_A.setText("Зберегти А") + self.gridLayout_2.addWidget(self.save_A, 8, 0, 1, 1) + + self.save_B = QtWidgets.QPushButton(self) + self.save_B.setText("Зберегти B") + self.gridLayout_2.addWidget(self.save_B, 8, 1, 1, 1) + + self.read_grid = QtWidgets.QGridLayout() + + self.read_A = QtWidgets.QPushButton(self) + self.read_A.setText("Читати А") + self.read_grid.addWidget(self.read_A, 1, 0, 1, 1) + + self.read_B = QtWidgets.QPushButton(self) + self.read_B.setText("Читати B") + self.read_grid.addWidget(self.read_B, 2, 0, 1, 1) + + self.gridLayout_2.addLayout(self.read_grid, 12, 0, 1, 2) + + QtCore.QMetaObject.connectSlotsByName(self) + + self.set_functions() + + self.set_A = set() + self.set_B = set() + + + def set_functions(self): + self.list_female.itemClicked.connect(self.add_to_set) + self.list_male.itemClicked.connect(self.add_to_set) + + self.clear_A.clicked.connect(lambda: self.clear_set(self.set_A)) + self.clear_B.clicked.connect(lambda: self.clear_set(self.set_B)) + + self.save_A.clicked.connect(lambda: save_set(self.set_A, "Set_A")) + self.save_B.clicked.connect(lambda: save_set(self.set_B, "Set_B")) + + self.read_A.clicked.connect(lambda: self.read_set(self.set_A, "Set_A")) + self.read_B.clicked.connect(lambda: self.read_set(self.set_B, "Set_B")) + + def add_to_set(self, item): + if self.A.isChecked(): + self.set_A.add(item.text()) + elif self.B.isChecked(): + self.set_B.add(item.text()) + self.set_set_label_text() + + def set_set_label_text(self): + self.sets_label.setText(f"A: {self.set_A}\nB: {self.set_B}".replace("set()", "")) + + def set_sets(self, names_f, names_m): + self.list_female.addItems(names_f) + self.list_male.addItems(names_m) + + def clear_set(self, set_to_clear): + set_to_clear.clear() + self.set_set_label_text() + + def read_set(self, set_to_read, set_name): + import shelve + with shelve.open("dat/saved_sets") as f: + try: + set_to_read.update(f[set_name]) + except: + pass + self.set_set_label_text() + + def get_set_A(self): + return self.set_A + + def get_set_B(self): + return self.set_B diff --git a/Lab_2/window_3.py b/Lab_2/window_3.py new file mode 100644 index 0000000..9917f4a --- /dev/null +++ b/Lab_2/window_3.py @@ -0,0 +1,124 @@ +from PyQt5 import QtCore, QtWidgets + + +def form_table(relation, label): + from prettytable import PrettyTable + + table = PrettyTable() + + a = [i[0] for i in relation] + b = [i[1] for i in relation] + + # print(f"A: {a}\nB: {b}") + + matrix = [[0 for j in range(len(b))] for i in range(len(a))] + for i in relation: + m = a.index(i[0]) + n = b.index(i[1]) + matrix[m][n] = 1 + + table.field_names = [" "] + a + + for i in range(len(matrix)): + table.add_row([b[i]] + matrix[i]) + + label.setText(table.get_string()) + + +class Window(QtWidgets.QWidget): + + def __init__(self): + super(QtWidgets.QWidget, self).__init__() + + self.setWindowTitle("Вікно 3") + + self.gridLayout = QtWidgets.QGridLayout(self) + + self.label_A = QtWidgets.QLabel(self) + self.label_A.setText("A") + self.label_A.setAlignment(QtCore.Qt.AlignCenter) + self.gridLayout.addWidget(self.label_A, 0, 0, 1, 1) + + self.label_B = QtWidgets.QLabel(self) + self.label_B.setText("B") + self.label_B.setAlignment(QtCore.Qt.AlignCenter) + self.gridLayout.addWidget(self.label_B, 0, 1, 1, 1) + + self.list_A = QtWidgets.QLabel(self) + self.gridLayout.addWidget(self.list_A, 1, 0, 1, 1) + + self.list_B = QtWidgets.QLabel(self) + self.gridLayout.addWidget(self.list_B, 1, 1, 1, 1) + + self.label_grand_daughter = QtWidgets.QLabel(self) + self.label_grand_daughter.setText("Внучка") + self.label_grand_daughter.setAlignment(QtCore.Qt.AlignCenter) + self.gridLayout.addWidget(self.label_grand_daughter, 2, 0, 1, 2) + + self.table_grand_daughter = QtWidgets.QLabel(self) + self.table_grand_daughter.setAlignment(QtCore.Qt.AlignCenter) + self.gridLayout.addWidget(self.table_grand_daughter, 3, 0, 1, 2) + + self.label_godmother = QtWidgets.QLabel(self) + self.label_godmother.setText("Хрещена мати") + self.label_godmother.setAlignment(QtCore.Qt.AlignCenter) + self.gridLayout.addWidget(self.label_godmother, 4, 0, 1, 2) + + self.table_godmother = QtWidgets.QLabel(self) + self.table_godmother.setAlignment(QtCore.Qt.AlignCenter) + self.gridLayout.addWidget(self.table_godmother, 5, 0, 1, 2) + + QtCore.QMetaObject.connectSlotsByName(self) + + self.set_A = set() + self.set_B = set() + self.female_names = set() + self.male_names = set() + + self.grandparent_granddaughter_relation = set() + self.godmother_godchild_relation = set() + + def set_sets(self, set_A, set_B, female_names, male_names): + self.set_A = set_A + self.set_B = set_B + self.female_names = female_names + self.male_names = male_names + + self.list_A.setText("\n".join(set_A)) + self.list_B.setText("\n".join(set_B)) + + def form_relations(self): + for grandparent in self.set_A: + for granddaughter in self.set_B: + if ( + grandparent != granddaughter + and granddaughter in self.female_names + and (granddaughter, grandparent) not in self.grandparent_granddaughter_relation + and (grandparent, granddaughter) not in self.grandparent_granddaughter_relation + and not any(grandparent == i[0] for i in self.grandparent_granddaughter_relation) + and not any(granddaughter == i[1] for i in self.grandparent_granddaughter_relation) + ): + self.grandparent_granddaughter_relation.add((grandparent, granddaughter)) + + for godmother in self.set_A: + for godchild in self.set_B: + if ( + godmother in self.female_names + and godmother != godchild + and (godmother, godchild) not in self.grandparent_granddaughter_relation + and (godchild, godmother) not in self.grandparent_granddaughter_relation + and (godchild, godmother) not in self.godmother_godchild_relation + and (godmother, godchild) not in self.godmother_godchild_relation + and not any(godchild == i[1] for i in self.godmother_godchild_relation) + and not any(godmother == i[0] for i in self.godmother_godchild_relation) + ): + self.godmother_godchild_relation.add((godmother, godchild)) + + form_table(self.grandparent_granddaughter_relation, self.table_grand_daughter) + form_table(self.godmother_godchild_relation, self.table_godmother) + + def get_granddaughter(self): + return self.grandparent_granddaughter_relation + + def get_godmother(self): + return self.godmother_godchild_relation diff --git a/Lab_2/window_4.py b/Lab_2/window_4.py new file mode 100644 index 0000000..b54317a --- /dev/null +++ b/Lab_2/window_4.py @@ -0,0 +1,141 @@ +from PyQt5 import QtCore, QtWidgets + + +def unite(*a): + b = [] + + for i in a: + for j in i: + if j not in b: + b.append(j) + + return b + + +def intersect(*a): + b = [] + + for i in a: + for j in i: + if all([j in k for k in a]): + b.append(j) + + +def difference(a, b): + c = [] + + for i in a: + if i not in b: + c.append(i) + + return c + + +def universal_set(set_X, set_Y): + universal = [] + for x in set_X: + for y in set_Y: + universal.append((x, y)) + return universal + + +def reverse(relation): + res = [] + for i in relation: + res.append(i[::-1]) + return res + + +def form_table(relation, label): + from prettytable import PrettyTable + + table = PrettyTable() + + if relation: + a = [i[0] for i in relation] + b = [i[1] for i in relation] + + matrix = [[0 for j in range(len(a))] for i in range(len(a))] + for i in relation: + m = a.index(i[0]) + n = b.index(i[1]) + matrix[m][n] = 1 + + if len(set([" "] + a)) < len([" "] + a): + table.field_names = [i for i in range(len(matrix) + 1)] + table.add_row([" "] + a) + else: + table.field_names = [" "] + a + + for i in range(len(matrix)): + table.add_row([b[i]] + matrix[i]) + else: + table.field_names = [" "] + + label.setText(table.get_string()) + + +class Window(QtWidgets.QWidget): + + def __init__(self): + super(QtWidgets.QWidget, self).__init__() + + self.setWindowTitle("Вікно 4") + + self.gridLayout = QtWidgets.QGridLayout(self) + + self.label = QtWidgets.QLabel(self) + self.label.setText("Оберіть операцію") + self.label.setAlignment(QtCore.Qt.AlignCenter) + self.gridLayout.addWidget(self.label, 0, 0, 1, 2) + + self.button_union = QtWidgets.QPushButton(self) + self.button_union.setText("R ∪ S") + self.gridLayout.addWidget(self.button_union, 1, 0, 1, 1) + + self.button_intersection = QtWidgets.QPushButton(self) + self.button_intersection.setText("R ∩ S") + self.gridLayout.addWidget(self.button_intersection, 2, 0, 1, 1) + + self.button_difference = QtWidgets.QPushButton(self) + self.button_difference.setText("R \\ S") + self.gridLayout.addWidget(self.button_difference, 3, 0, 1, 1) + + self.button_universal_difference = QtWidgets.QPushButton(self) + self.button_universal_difference.setText("U \\ R") + self.gridLayout.addWidget(self.button_universal_difference, 4, 0, 1, 1) + + self.button_reverse = QtWidgets.QPushButton(self) + self.button_reverse.setText("S⁻¹") + self.gridLayout.addWidget(self.button_reverse, 5, 0, 1, 1) + + self.tableView_relation = QtWidgets.QLabel(self) + self.tableView_relation.setAlignment(QtCore.Qt.AlignCenter) + self.gridLayout.addWidget(self.tableView_relation, 1, 1, 5, 1) + + QtCore.QMetaObject.connectSlotsByName(self) + + self.set_functions() + + self.set_R = set() + self.set_S = set() + self.set_A = set() + self.set_B = set() + + def set_functions(self): + self.button_union.clicked.connect(lambda: form_table(unite(self.set_R, self.set_S), self.tableView_relation)) + self.button_intersection.clicked.connect(lambda: form_table(intersect(self.set_R, self.set_S), + self.tableView_relation)) + self.button_difference.clicked.connect(lambda: form_table(difference(self.set_R, self.set_S), + self.tableView_relation)) + self.button_universal_difference.clicked.connect(lambda: form_table( + difference(universal_set(self.set_A, self.set_B), self.set_R), self.tableView_relation) + ) + self.button_reverse.clicked.connect(lambda: form_table(reverse(self.set_S), self.tableView_relation)) + + def set_sets(self, granddaughter, godmother, set_A, set_B): + self.set_R = granddaughter + self.set_S = godmother + self.set_A = set_A + self.set_B = set_B + diff --git a/Lab_3/main.py b/Lab_3/main.py new file mode 100644 index 0000000..622fb1b --- /dev/null +++ b/Lab_3/main.py @@ -0,0 +1,95 @@ +from PyQt5 import QtCore, QtWidgets +import sys +import window_2 + + +class Window(QtWidgets.QMainWindow): + + def __init__(self): + super(QtWidgets.QMainWindow, self).__init__() + + self.window_2 = window_2.Window() + + self.setWindowTitle("Вікно 1") + + centralwidget = QtWidgets.QWidget(self) + + self.grid_layout = QtWidgets.QGridLayout(centralwidget) + + self.full_name = QtWidgets.QLabel(centralwidget) + self.full_name.setText("П. І. Б:") + self.full_name.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.grid_layout.addWidget(self.full_name, 0, 0, 1, 1) + + self.full_name_answer = QtWidgets.QLabel(centralwidget) + self.full_name_answer.setText("Швед Андрій Дмитрович") + self.grid_layout.addWidget(self.full_name_answer, 0, 1, 1, 1) + + self.group = QtWidgets.QLabel(centralwidget) + self.group.setText("Група:") + self.group.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.grid_layout.addWidget(self.group, 1, 0, 1, 1) + + self.group_answer = QtWidgets.QLabel(centralwidget) + self.group_answer.setText("ІО-23") + self.grid_layout.addWidget(self.group_answer, 1, 1, 1, 1) + + self.list_number = QtWidgets.QLabel(centralwidget) + self.list_number.setText("Номер в списку:") + self.list_number.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.grid_layout.addWidget(self.list_number, 2, 0, 1, 1) + + self.list_number_answer = QtWidgets.QLabel(centralwidget) + self.list_number_answer.setText("30") + self.grid_layout.addWidget(self.list_number_answer, 2, 1, 1, 1) + + self.task_number = QtWidgets.QLabel(centralwidget) + self.task_number.setText("Номер завдання:") + self.task_number.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.grid_layout.addWidget(self.task_number, 3, 0, 1, 1) + + self.task_number_answer = QtWidgets.QLabel(centralwidget) + self.task_number_answer.setText("1") + self.grid_layout.addWidget(self.task_number_answer, 3, 1, 1, 1) + + self.setCentralWidget(centralwidget) + + self.menubar = QtWidgets.QMenuBar(self) + self.menubar.setGeometry(QtCore.QRect(0, 0, 362, 22)) + + self.menubar.setDefaultUp(False) + + self.menu_Windows = QtWidgets.QMenu(self.menubar) + self.menu_Windows.setTitle("Вікна") + self.setMenuBar(self.menubar) + + self.window_2_action = QtWidgets.QAction(self) + self.window_2_action.setText("Вікно 2") + self.menu_Windows.addAction(self.window_2_action) + + self.menu_Windows.addSeparator() + + self.exit_action = QtWidgets.QAction(self) + self.exit_action.setText("Вихід") + self.menu_Windows.addAction(self.exit_action) + + self.menubar.addAction(self.menu_Windows.menuAction()) + + self.set_menu() + + QtCore.QMetaObject.connectSlotsByName(self) + + def set_menu(self): + self.exit_action.triggered.connect(lambda: sys.exit()) + self.window_2_action.triggered.connect(lambda: self.window_2.show()) + + +app = QtWidgets.QApplication(sys.argv) + +app.setStyleSheet(open("style.css").read()) + +window = Window() + +window.show() + +sys.exit(app.exec_()) \ No newline at end of file diff --git a/Lab_3/style.css b/Lab_3/style.css new file mode 100644 index 0000000..0eecc52 --- /dev/null +++ b/Lab_3/style.css @@ -0,0 +1,23 @@ +QWidget{ + border-radius: 10px; + padding: 4px; + margin: 2px; + font-family: "Liberation Mono"; + font-size: 14pt; +} +QPushButton{ + background-color: blueviolet; + color: white; +} +QPushButton:hover{ + background-color: #6f20b3; +} +QPushButton:pressed{ + background-color: #8f58c9; +} +QLabel{ + border: 3px solid blueviolet; +} +QTextEdit{ + border: 3px solid blueviolet; +} \ No newline at end of file diff --git a/Lab_3/table.txt b/Lab_3/table.txt new file mode 100644 index 0000000..b2a073a --- /dev/null +++ b/Lab_3/table.txt @@ -0,0 +1,4 @@ +1 0 0 1 +1 0 1 0 +0 0 1 0 +0 1 0 1 \ No newline at end of file diff --git a/Lab_3/window_2.py b/Lab_3/window_2.py new file mode 100644 index 0000000..1af6a28 --- /dev/null +++ b/Lab_3/window_2.py @@ -0,0 +1,227 @@ +from PyQt5 import QtCore, QtWidgets +import networkx as nx +import matplotlib.pyplot as plt +import numpy as np +import random +from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas +from prettytable import PrettyTable + + +def is_square(matrix): + return all(len(row) == len(matrix) for row in matrix) + + +def validate_values(matrix): + return all(all(("1" == element) or ("0" == element) for element in row) for row in matrix) + + +class Window(QtWidgets.QWidget): + + def __init__(self): + + super(QtWidgets.QWidget, self).__init__() + + self.setWindowTitle("Вікно 2") + + self.grid_layout = QtWidgets.QGridLayout(self) + + self.adjacency_input_label = QtWidgets.QLabel(self) + self.adjacency_input_label.setText("Введіть матрицю суміжності графа") + self.grid_layout.addWidget(self.adjacency_input_label, 0, 0, 1, 1) + + self.adjacency_input = QtWidgets.QTextEdit(self) + self.grid_layout.addWidget(self.adjacency_input, 1, 0, 2, 1) + + self.adjacency_output_label = QtWidgets.QLabel(self) + self.adjacency_output_label.setText("Матриця суміжності") + self.grid_layout.addWidget(self.adjacency_output_label, 0, 1, 1, 1) + + self.adjacency_output = QtWidgets.QLabel(self) + self.grid_layout.addWidget(self.adjacency_output, 1, 1, 1, 1) + + self.incidence_output_label = QtWidgets.QLabel(self) + self.incidence_output_label.setText("Матриця інцидентності") + self.grid_layout.addWidget(self.incidence_output_label, 0, 2, 1, 1) + + self.incidence_output = QtWidgets.QLabel(self) + self.grid_layout.addWidget(self.incidence_output, 1, 2, 1, 1) + + self.edges_dictionary_output_label = QtWidgets.QLabel(self) + self.edges_dictionary_output_label.setText("Словник граней") + self.grid_layout.addWidget(self.edges_dictionary_output_label, 0, 3, 1, 1) + + self.edges_dictionary_output = QtWidgets.QLabel(self) + self.grid_layout.addWidget(self.edges_dictionary_output, 1, 3, 1, 1) + + self.canvas_grid = QtWidgets.QGridLayout() + + self.figure = plt.figure() + self.canvas = FigureCanvas(self.figure) + self.canvas_grid.addWidget(self.canvas, 0, 0, 1, 1) + + self.grid_layout.addLayout(self.canvas_grid, 2, 1, 1, 3) + + self.build_graph_button = QtWidgets.QPushButton(self) + self.build_graph_button.setText("Побудувати граф") + self.grid_layout.addWidget(self.build_graph_button, 3, 0, 1, 2) + + self.open_file_button = QtWidgets.QPushButton(self) + self.open_file_button.setText("Відкрити файл") + self.grid_layout.addWidget(self.open_file_button, 3, 2, 1, 2) + + QtCore.QMetaObject.connectSlotsByName(self) + + self.set_functions() + + def parse_matrix(self) -> (np.ndarray | None, str | None): + text_matrix = list(map(lambda x: x.split(" "), self.adjacency_input.toPlainText().splitlines())) + + if not is_square(text_matrix): + return None, "square_error" + elif not validate_values(text_matrix): + return None, "value_error" + else: + return np.array(list([list(map(int, row)) for row in text_matrix])), None + + def build_graphs(self): + adjacency_matrix, error = self.parse_matrix() + + if adjacency_matrix is None and error == "square_error": + self.show_error( + "Матриця суміжності має бути квадратною. Перевірте чи кожен елемент рядка відділений пробілом і чи " + "дорівнює кількість рядків кількості стовпців." + ) + elif adjacency_matrix is None and error == "value_error": + self.show_error( + "Матриця суміжності мусить складатись лише з нулів і одиниць розділених пробілом. Перевірте ваш ввід." + ) + else: + adjacency_graph = self.create_adjacency_graph(adjacency_matrix) + self.display_adjacency_matrix(adjacency_graph, self.adjacency_output) + incidence_nodes, incidence_edges, incidence_matrix = self.create_incidence_matrix(adjacency_graph) + self.display_incidence_matrix(incidence_nodes, incidence_edges, incidence_matrix, self.incidence_output) + incidence_graph = self.create_incidence_graph(incidence_nodes, incidence_edges) + self.draw_graph(adjacency_graph, incidence_graph) + self.display_edge_dictionary(adjacency_graph, self.edges_dictionary_output) + + @staticmethod + def show_error(error_text: str): + error_message = QtWidgets.QMessageBox() + error_message.setIcon(QtWidgets.QMessageBox.Critical) + error_message.setText("Помилка вводу") + error_message.setInformativeText(error_text) + error_message.setWindowTitle("Помилка") + error_message.exec_() + + @staticmethod + def create_adjacency_graph(adjacency_matrix: np.ndarray) -> nx.DiGraph: + graph = nx.DiGraph() + + nodes = [f"X{i}" for i in range(len(adjacency_matrix))] + edge_indices = np.argwhere(adjacency_matrix) + edges = [(nodes[edge_index[0]], nodes[edge_index[1]]) for edge_index in edge_indices] + graph.add_nodes_from(nodes) + graph.add_edges_from(edges) + + return graph + + @staticmethod + def create_incidence_graph(nodes: list, edges: list) -> nx.DiGraph: + graph = nx.DiGraph() + + graph.add_nodes_from(nodes) + graph.add_edges_from(edges) + + return graph + + def draw_graph(self, adjacency_graph: nx.DiGraph, incidence_graph: nx.DiGraph): + random.seed(0) + np.random.seed(0) + + self.figure.clf() + + pos = nx.planar_layout(adjacency_graph, scale=0.5) + + nx.draw( + adjacency_graph, pos=pos, with_labels=True, node_color="blueviolet", node_size=700, font_color="white", + font_size=14, font_family="Liberation Mono", font_weight="bold", width=2 + ) + + pos = nx.planar_layout(incidence_graph, scale=0.5) + + for i in pos: + pos[i][0] += 2 + + nx.draw( + adjacency_graph, pos=pos, with_labels=True, node_color="blueviolet", node_size=700, font_color="white", + font_size=14, font_family="Liberation Mono", font_weight="bold", width=2 + ) + + self.canvas.draw_idle() + + @staticmethod + def display_adjacency_matrix(graph: nx.DiGraph, label: QtWidgets.QLabel): + matrix = nx.adjacency_matrix(graph).todense().tolist() + + table = PrettyTable() + + nodes = [f"X{i}" for i in range(len(matrix))] + + table.field_names = [" "] + nodes + + for i in range(len(matrix)): + table.add_row([nodes[i]] + matrix[i]) + + label.setText(table.get_string()) + + @staticmethod + def display_incidence_matrix(nodes: list, edges: list, incidence_matrix: list, label: QtWidgets.QLabel): + table = PrettyTable() + + edge_names = [f"E{i}" for i in range(len(edges))] + + table.field_names = [" "] + edge_names + + for i in range(len(incidence_matrix)): + table.add_row([nodes[i]] + incidence_matrix[i]) + + label.setText(table.get_string()) + + @staticmethod + def create_incidence_matrix(graph: nx.DiGraph) -> (list, list, list): + nodes = list(graph.nodes) + edges = list(graph.edges) + + edge_names = [f"E{i}" for i in range(len(edges))] + + matrix = [["0" for j in range(len(edges))] for i in range(len(nodes))] + matrix = [ + ["1" if nodes[i] == edges[j][0] else matrix[i][j] for j in range(len(matrix[i]))] + for i in range(len(matrix))] + matrix = [ + ["-1" if nodes[i] == edges[j][1] else matrix[i][j] for j in range(len(matrix[i]))] + for i in range(len(matrix))] + matrix = [ + ["±1" if (nodes[i] == edges[j][0] and nodes[i] == edges[j][1]) + else matrix[i][j] for j in range(len(matrix[i]))] + for i in range(len(matrix))] + + return nodes, edges, matrix + + @staticmethod + def display_edge_dictionary(graph: nx.DiGraph, label: QtWidgets.QLabel): + edge_dictionary = "" + edges = list(graph.edges) + for i, edge in enumerate(edges): + edge_dictionary += f"E{i} = ({edge[0]} -> {edge[1]})\n" + label.setText(edge_dictionary) + + def browse_files(self): + file_name = QtWidgets.QFileDialog.getOpenFileName(self, "Відкрити файл", "~/", "Текстові файли (*.txt)") + with open(file_name[0]) as f: + text_read = f.read() + self.adjacency_input.setText(text_read) + + def set_functions(self): + self.build_graph_button.clicked.connect(lambda: self.build_graphs()) + self.open_file_button.clicked.connect(lambda: self.browse_files()) diff --git a/Lab_4/main.py b/Lab_4/main.py new file mode 100644 index 0000000..a20d3ac --- /dev/null +++ b/Lab_4/main.py @@ -0,0 +1,11 @@ +from PyQt5 import QtWidgets +from window import Window +import sys + +app = QtWidgets.QApplication(sys.argv) +app.setStyleSheet(open("style.css").read()) + +main_window = Window() +main_window.show() + +sys.exit(app.exec()) diff --git a/Lab_4/style.css b/Lab_4/style.css new file mode 100644 index 0000000..a99a233 --- /dev/null +++ b/Lab_4/style.css @@ -0,0 +1,23 @@ +QWidget{ + border-radius: 10px; + padding: 4px; + margin: 2px; + font-family: "JetBrains Mono"; + font-size: 12pt; +} +QPushButton{ + background-color: blueviolet; + color: white; +} +QPushButton:hover{ + background-color: #6f20b3; +} +QPushButton:pressed{ + background-color: #8f58c9; +} +QLabel{ + border: 3px solid blueviolet; +} +QTextEdit{ + border: 3px solid blueviolet; +} \ No newline at end of file diff --git a/Lab_4/table.txt b/Lab_4/table.txt new file mode 100644 index 0000000..4b5d06a --- /dev/null +++ b/Lab_4/table.txt @@ -0,0 +1,10 @@ +0 0 1 0 0 1 1 0 0 0 +0 0 1 0 0 0 1 1 0 0 +1 1 0 1 0 0 0 0 1 0 +0 0 1 0 1 0 0 0 1 0 +0 0 0 1 0 0 0 0 1 1 +1 0 0 0 0 0 1 0 0 0 +1 1 0 0 0 1 0 1 0 0 +0 1 0 0 0 0 1 0 1 0 +0 0 1 1 1 0 0 1 0 1 +0 0 0 0 1 0 0 0 1 0 \ No newline at end of file diff --git a/Lab_4/window.py b/Lab_4/window.py new file mode 100644 index 0000000..0dfc4ec --- /dev/null +++ b/Lab_4/window.py @@ -0,0 +1,228 @@ +from PyQt5 import QtCore, QtWidgets +import sys +import networkx as nx +import matplotlib.pyplot as plt +import matplotlib.colors as mcolours +import numpy as np +from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas + + +class Window(QtWidgets.QMainWindow): + + def __init__(self): + super().__init__() + + self.setWindowTitle("Вікно 1") + + central_widget = QtWidgets.QWidget(self) + + self.grid_layout = QtWidgets.QGridLayout(central_widget) + + self.id_grid_layout = QtWidgets.QGridLayout() + + self.full_name = QtWidgets.QLabel(central_widget) + self.full_name.setText("П. І. Б:") + self.full_name.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.id_grid_layout.addWidget(self.full_name, 0, 0, 1, 1) + + self.full_name_answer = QtWidgets.QLabel(central_widget) + self.full_name_answer.setText("Швед Андрій Дмитрович") + self.id_grid_layout.addWidget(self.full_name_answer, 0, 1, 1, 1) + + self.group = QtWidgets.QLabel(central_widget) + self.group.setText("Група:") + self.group.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.id_grid_layout.addWidget(self.group, 1, 0, 1, 1) + + self.group_answer = QtWidgets.QLabel(central_widget) + self.group_answer.setText("ІО-23") + self.id_grid_layout.addWidget(self.group_answer, 1, 1, 1, 1) + + self.list_number = QtWidgets.QLabel(central_widget) + self.list_number.setText("Номер в списку:") + self.list_number.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.id_grid_layout.addWidget(self.list_number, 2, 0, 1, 1) + + self.list_number_answer = QtWidgets.QLabel(central_widget) + self.list_number_answer.setText("30") + self.id_grid_layout.addWidget(self.list_number_answer, 2, 1, 1, 1) + + self.task_number = QtWidgets.QLabel(central_widget) + self.task_number.setText("Номер завдання:") + self.task_number.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter) + self.id_grid_layout.addWidget(self.task_number, 3, 0, 1, 1) + + self.task_number_answer = QtWidgets.QLabel(central_widget) + self.task_number_answer.setText("1") + self.id_grid_layout.addWidget(self.task_number_answer, 3, 1, 1, 1) + + self.grid_layout.addLayout(self.id_grid_layout, 0, 0, 1, 1) + + self.graph_grid_layout = QtWidgets.QGridLayout() + + self.adjacency_input_label = QtWidgets.QLabel(self) + self.adjacency_input_label.setText("Введіть матрицю суміжності графа") + self.graph_grid_layout.addWidget(self.adjacency_input_label, 0, 0, 1, 1) + + self.adjacency_input = QtWidgets.QTextEdit(self) + self.graph_grid_layout.addWidget(self.adjacency_input, 1, 0, 2, 1) + + self.graph_label = QtWidgets.QLabel(self) + self.graph_label.setText("Розфарбований граф") + self.graph_grid_layout.addWidget(self.graph_label, 0, 1, 1, 1) + + self.figure = plt.figure() + self.canvas = FigureCanvas(self.figure) + self.graph_grid_layout.addWidget(self.canvas, 1, 1, 1, 1) + + self.grid_layout.addLayout(self.graph_grid_layout, 1, 0, 1, 1) + + self.buttons_grid_layout = QtWidgets.QGridLayout() + + self.build_graph_button = QtWidgets.QPushButton(self) + self.build_graph_button.setText("Побудувати граф") + self.buttons_grid_layout.addWidget(self.build_graph_button, 0, 0, 1, 1) + + self.open_file_button = QtWidgets.QPushButton(self) + self.open_file_button.setText("Відкрити файл") + self.buttons_grid_layout.addWidget(self.open_file_button, 0, 1, 1, 1) + + self.grid_layout.addLayout(self.buttons_grid_layout, 2, 0, 1, 1) + + self.setCentralWidget(central_widget) + + self.menubar = QtWidgets.QMenuBar(self) + self.menubar.setGeometry(QtCore.QRect(0, 0, 362, 22)) + + self.menubar.setDefaultUp(False) + + self.menu_Windows = QtWidgets.QMenu(self.menubar) + self.menu_Windows.setTitle("Вікна") + self.setMenuBar(self.menubar) + + self.exit_action = QtWidgets.QAction(self) + self.exit_action.setText("Вихід") + self.menu_Windows.addAction(self.exit_action) + + self.menubar.addAction(self.menu_Windows.menuAction()) + + self.set_menu() + self.set_functions() + + QtCore.QMetaObject.connectSlotsByName(self) + + def set_menu(self): + self.exit_action.triggered.connect(lambda: sys.exit()) + + @staticmethod + def is_square(matrix: list) -> bool: + return all(len(row) == len(matrix) for row in matrix) + + @staticmethod + def validate_values(matrix: list) -> bool: + return all(all(("1" == element) or ("0" == element) for element in row) for row in matrix) + + def parse_matrix(self) -> (np.ndarray | None, str | None): + text_matrix = list(map(lambda x: x.split(" "), self.adjacency_input.toPlainText().splitlines())) + + if not self.is_square(text_matrix): + return None, "square_error" + elif not self.validate_values(text_matrix): + return None, "value_error" + elif not text_matrix: + return None, "empty_matrix" + else: + return np.array(list([list(map(int, row)) for row in text_matrix])), None + + def build_graphs(self): + adjacency_matrix, error = self.parse_matrix() + + if adjacency_matrix is None and error == "square_error": + self.show_error( + "Матриця суміжності має бути квадратною. Перевірте чи кожен елемент рядка відділений пробілом і чи " + "дорівнює кількість рядків кількості стовпців." + ) + elif adjacency_matrix is None and error == "value_error": + self.show_error( + "Матриця суміжності мусить складатись лише з нулів і одиниць розділених пробілом. Перевірте ваш ввід." + ) + elif adjacency_matrix is None and error == "empty_matrix": + self.show_error( + "Матриця суміжності не може бути пустою." + ) + elif type(adjacency_matrix) is np.ndarray and error is None: + adjacency_graph = self.create_adjacency_graph(adjacency_matrix) + colours = self.brute_force_colour(adjacency_graph) + self.draw_graph(adjacency_graph, colours) + + @staticmethod + def show_error(error_text: str): + error_message = QtWidgets.QMessageBox() + error_message.setIcon(QtWidgets.QMessageBox.Critical) + error_message.setText("Помилка вводу") + error_message.setInformativeText(error_text) + error_message.setWindowTitle("Помилка") + error_message.exec_() + + @staticmethod + def create_adjacency_graph(adjacency_matrix: np.ndarray) -> nx.Graph: + graph = nx.Graph() + + nodes = [f"{i}" for i in range(len(adjacency_matrix))] + edge_indices = np.argwhere(adjacency_matrix) + edges = [(nodes[edge_index[0]], nodes[edge_index[1]]) for edge_index in edge_indices] + graph.add_nodes_from(nodes) + graph.add_edges_from(edges) + + return graph + + def draw_graph(self, graph: nx.Graph, colour_map: list): + + self.figure.clf() + + nx.draw( + graph, with_labels=True, node_size=700, font_size=14, font_family="Ubuntu Mono", node_color=colour_map, + edgecolors="black", font_weight="bold", width=2 + ) + + plt.margins(0.2) + + self.canvas.draw_idle() + + @staticmethod + def previous_neighbors(graph: nx.Graph, node: str): + neighbours = list(graph.neighbors(node)) + + nodes = list(graph.nodes) + previous = nodes[:nodes.index(node)] + + res = [n for n in previous if n in neighbours] + + return res + + def brute_force_colour(self, graph: nx.Graph) -> list: + coloured_nodes = dict() + i = 0 + for node in graph: + previous_colours = [coloured_nodes[f'{n}'] for n in self.previous_neighbors(graph, node)] + nodes_difference = sorted(list(set(coloured_nodes.values()) - set(previous_colours))) + + if (not coloured_nodes) or (not nodes_difference): + coloured_nodes[f"{node}"] = i + i += 1 + else: + coloured_nodes[f"{node}"] = nodes_difference[0] + + colour_map = [list(mcolours.CSS4_COLORS.keys())[i] for i in coloured_nodes.values()] + + return colour_map + + def open_file(self): + file_name = QtWidgets.QFileDialog.getOpenFileName(self, "Відкрити файл", "~/", "Текстові файли (*.txt)") + with open(file_name[0]) as f: + text_read = f.read() + self.adjacency_input.setText(text_read) + + def set_functions(self): + self.build_graph_button.clicked.connect(lambda: self.build_graphs()) + self.open_file_button.clicked.connect(lambda: self.open_file())