diff --git a/0.8_indev/__pycache__/add_func.cpython-311.pyc b/0.8_indev/__pycache__/add_func.cpython-311.pyc index d188ea8..47b975d 100644 Binary files a/0.8_indev/__pycache__/add_func.cpython-311.pyc and b/0.8_indev/__pycache__/add_func.cpython-311.pyc differ diff --git a/0.8_indev/__pycache__/dbtable.cpython-311.pyc b/0.8_indev/__pycache__/dbtable.cpython-311.pyc index cf5d63c..873cecf 100644 Binary files a/0.8_indev/__pycache__/dbtable.cpython-311.pyc and b/0.8_indev/__pycache__/dbtable.cpython-311.pyc differ diff --git a/0.8_indev/add_func.py b/0.8_indev/add_func.py index f75f7a7..24f815c 100644 --- a/0.8_indev/add_func.py +++ b/0.8_indev/add_func.py @@ -1,26 +1,62 @@ import re import os -def validate_time_format(input_str): - """Функция проверки подходящего формата для ввода времени в interval +def input_time_format(name): + time = [] + output = '' + print(f'Процесс добавления блюда: {name}\nВведите время приготовления сначала в часах, потом в минутах') + + while True: + ins_time = validate_input(f'Введите кол-во часов [0 <= x <= 23] (-1 - для отмены): ',\ + 0, 23) + if(ins_time==''): + return -1 + else: + time.append(ins_time) + break + + while True: + ins_time = validate_input(f'Введите кол-во минут [0 <= x <= 59] (-1 - для отмены): ',\ + 0, 59) + if(ins_time==''): + return -1 + else: + time.append(ins_time) + break + if(time[0]==1): + output += f"1 hour " + elif(time[0]>1): + output += f"{time[0]} hours " + else: + pass + if(time[1]==1): + output += f"1 minute" + elif(time[1]>1): + output += f"{time[0]} minutes" + else: + pass + return output - Args: - input_str (str): входная строка для проверки +# def validate_time_format(input_str): + +# """ +# Функция проверки подходящего формата для ввода времени в interval - Returns: - bool: Булевое значение, которое характеризует валидность вводимых строк - """ - # Регулярное выражение для проверки формата - pattern = r'^(\d+\s*hours?\s*)?(\d+\s*minutes?)$' +# Args: +# input_str (str): входная строка для проверки + +# Returns: +# bool: Булевое значение, которое характеризует валидность вводимых строк +# """ +# # Регулярное выражение для проверки формата +# pattern = re.compile(r"""^(-)?(?:(?Pd+):)?(?Pd+):(?Pd+(.d+)?)$""") +# # Проверка соответствия регулярному выражению +# match = re.match(pattern, input_str) - # Проверка соответствия регулярному выражению - match = re.match(pattern, input_str) - - if match: - return True - - # Если формат некорректный, возвращаем False - return False +# if match: +# return True +# # Если формат некорректный, возвращаем False +# return False def validate_input(prompt, min_value, max_value): """Проверка ввода для выбора номера строки @@ -34,17 +70,19 @@ def validate_input(prompt, min_value, max_value): int: Либо число, введенное пользователем, либо -1 для выхода """ while True: - user_input = input(prompt) + user_input = input(prompt).strip() try: value = int(user_input) - if min_value <= value <= max_value and value != 0: + if min_value <= value <= max_value and value != -1: return value - elif value == 0: + elif value == -1: return -1 else: print(f"Введенное значение должно быть в диапазоне от {min_value} до {max_value}") except ValueError: print("Введенное значение должно быть числом.") + + # test1 = 'erhwogngonwro' @@ -71,6 +109,6 @@ def add_zero_before(old_index: str, max_len: str) -> str: def cls(): - # Закомментировать строку нижу, если нужно выключить очистку терминала - os.system('cls') + # Закомментировать строку ниже, если нужно выключить очистку терминала + # os.system('cls') return \ No newline at end of file diff --git a/0.8_indev/dbtable.py b/0.8_indev/dbtable.py index 37f4355..dc28016 100644 --- a/0.8_indev/dbtable.py +++ b/0.8_indev/dbtable.py @@ -98,23 +98,12 @@ class DbTable: cur.execute(sql) return cur.fetchall() - def get_page(self, page_num): - """Функция для получения "страницы" из БД по её номеру. - В программе заменяет .all() для вывода информации. - - Args: - page_num (int): номер страницы, определяется пользователем. - - Returns: - lst (list): Список, содержащий в себе все строки для этой страницы. - """ - ROW_PER_PAGE = 10 + def count(self): + sql = f"""SELECT COUNT(*) FROM {self.table_name()};""" cur = self.dbconn.conn.cursor() - offset = (page_num - 1) * ROW_PER_PAGE - sql = (f"SELECT * FROM {self.table_name()} LIMIT {ROW_PER_PAGE} OFFSET {offset}") cur.execute(sql) - return cur.fetchall() - + return int(cur.fetchone()[0]) + def select_one(self, **kwargs): conditions = [] diff --git a/0.8_indev/main.py b/0.8_indev/main.py index c52f2f6..5c0619d 100644 --- a/0.8_indev/main.py +++ b/0.8_indev/main.py @@ -1,5 +1,4 @@ import sys -import texts import math # import time @@ -21,14 +20,28 @@ TODO: 6) Доделать ограничение на выбор категории - done 7) UPDATE для блюд - done 0.7 8) Постраничный вывод - indev 0.8 - реализация через offset. -9) Реализовать отдельный просмотр(offset) +9) Реализовать отдельный просмотр(offset) - done for cath 10) И отдельный вывод(offset) +1) detele category - done +2) update category - done +3) add category - done + FIXME: 1) Откомментировать os.cls 2) Исправить вылет при неверном вводе в самое начало(сделать выход на предыдущую менюшку) 3) При вводе текста пропуск сделать с помощью пустой строки. +4) Ввод времени + +TEST: +1) Удаление категории + ввод неизвестных символов и отмена +2) Обновление категории + ввод неизвестных символов и отмена +3) Добавление категории + ввод неизвестных символов и отмена +4) Обновление блюда +5) Добавление блюда +6) Удаление блюда + ''' @@ -60,7 +73,11 @@ class Main: cth.drop() return def show_main_menu(self): - menu = texts.show_main_menu_txt + menu = """Привутствуем в меню, выберите действие: + 1 - просмотр категорий; + 2 - сброс и инициализация БД; + 9 - выход;""" + print(menu) return def read_next_step(self): @@ -79,112 +96,119 @@ class Main: else: return next_step + def show_page_cath(self): + + menu = """Просмотр списка категорий! +№\tНазвание\n-------------------------------------------------------------------------------------------""" + + cath_page = 1 + lst = CathTable().get_cath_page(cath_page) + action = '>' + max_page = math.ceil(self.max_cath_index/10) + ((self.max_cath_index/10)== 0) + while True: + cath_arr = CathTable().get_cath_page(cath_page) + add_func.cls() + + print(menu) + for i in range(len(cath_arr)): + print(add_func.add_zero_before(cath_arr[i][0],\ + len(str(self.max_cath_index))) + "\t" + cath_arr[i][1]) + + action = input('-------------------------------------------------------------------------------------------\n\ +Для переключения между страницами используйте "<" и ">"\n\ +Для выхода в меню действий нажмите любую другую клавишу\n=> ') + + if(action=='>'): + if(cath_page==max_page): + cath_page = 1 + else: + cath_page += 1 + lst = CathTable().get_cath_page(cath_page) + elif(action=='<'): + if(cath_page==1): + cath_page = max_page + else: + cath_page -= 1 + lst = CathTable().get_cath_page(cath_page) + else: + break + + def show_cath(self): self.cath_id = -1 - menu = texts.show_cath_1txt - print(menu) - self.max_cath_index = len(CathTable().all()) - self.cath_page = 1 - lst = CathTable().get_page(self.cath_page) - action = '>' - max_page = math.ceil(self.max_cath_index/10) - while True: - - self.cath_arr = [] - - for i in lst: - self.cath_arr.append(str(i[0])) - add_func.cls() - for i in range(len(self.cath_arr)): - print(add_func.add_zero_before(str((i+1)+(10*(self.cath_page-1))), len(str(self.max_cath_index))) + "\t" + self.cath_arr[i]) - action = input('-------------------------------------------------------------------------------------------\n\ -Для переключения между страницами используйте "<" и ">"\nКол-во записей на странице: 10\n\ -Для выхода в меню действий нажмите любую другую клавишу\n=> ') - if(action=='>'): - if(self.cath_page==max_page): - self.cath_page = 1 - else: - self.cath_page += 1 - lst = CathTable().get_page(self.cath_page) - elif(action=='<'): - if(self.cath_page==1): - self.cath_page = max_page - else: - self.cath_page -= 1 - lst = CathTable().get_page(self.cath_page) - else: - break - - menu = texts.show_cath_2txt + self.max_cath_index = CathTable().count() + self.show_page_cath() + menu = """-------------------------------------------------------------------------------------------\nДальнейшие операции: + 0 - возврат в главное меню; + 3 - добавление новой категории; + 4 - удаление категории; + 5 - просмотр блюд в категории; + 8 - обновить категорию; + 9 - выход.""" print(menu) return + def after_show_cath(self, next_step): """Выбор действий после вывода категорий - """ + """ while True: if next_step == "4": # Удаление категории - if(self.cath_page<(self.max_cath_index//10)): - left = ((self.cath_page-1)*10)+1 - right = left+9 - print(left) - - else: - left = 1+((self.cath_page-1)*10) - right = self.max_cath_index - x = add_func.validate_input('Введите номер удаляемой категории (0 - для отмены): ', left, right) + left = 1 + right = self.max_cath_index + x = add_func.validate_input('Введите номер удаляемой категории (-1 - отмена): ', left, right) if(x!=-1): - CathTable().delete(self.cath_arr[(int(x)-1)-((self.cath_page-1)*10)]) + CathTable().delete(CathTable().get_cath_from_page(x).get("id")) return "1" elif next_step == "6": #Добавление блюда в категорию - DishTable().insert_dishone(self.cath_id) - next_step = "5" + if(self.cath_id != -1): + DishTable().insert_dishone(self.cath_id) + next_step = "5" + else: + print("Сначала выберите категорию") + return "1" elif next_step == "7":#Удаление блюда из категории - if(self.dish_page<(self.max_index//10)): - left = ((self.dish_page-1)*10)+(self.dish_page==1) - right = left+9 - + if(self.cath_id != -1): + left = 1 + right = self.max_dish_index + x = add_func.validate_input('Введите номер удаляемого блюда (-1 - отмена): ', left, right) + if(x!=-1): + DishTable().delete(DishTable().get_dish_from_page(self.cath_id, x).get("id")) + return "1" + else: + next_step = "5" + return "1" else: - left = 1+((self.dish_page-1)*10)+(self.dish_page!=1) - right = self.max_index - x = add_func.validate_input('Введите номер удаляемого блюда (0 - для отмены): ', left, right) - if(x!=-1): - DishTable().delete(self.dish_arr[(int(x)-1)-((self.dish_page-1)*10)][0]) - else: - return "1" - next_step = "5" + print("Сначала выберите категорию") + return "1" elif next_step == "5": next_step = self.show_dish_in_cath() elif next_step == "8": # Обновление названия категории - if(self.cath_page<(self.max_cath_index//10)): - left = 1+((self.cath_page-1)*10) - right = left+9 - - else: - left = 1+((self.cath_page-1)*10) - right = self.max_cath_index - x = add_func.validate_input('Введите номер обновляемой категории (0 - для отмены): ', left, right) + left = 1 + right = self.max_cath_index + x = add_func.validate_input('Введите номер обновляемой категории (-1 - отмена): ', left, right) if(x!=-1): - CathTable().cath_update(self.cath_arr[(int(x)-1)-((self.cath_page-1)*10)]) + CathTable().cath_update(CathTable().get_cath_from_page(x).get("cath_name")) return "1" - elif next_step == "88": - if(self.dish_page<(self.max_index//10)): - left = 1+((self.dish_page-1)*10) - right = left+9 - + + elif next_step == "88": # Обновление блюда + if(self.cath_id != -1): + left = 1 + right = self.max_dish_index + x = add_func.validate_input('Введите номер обновляемого блюда (-1 - отмена): ', left, right) + if(x!=-1): + DishTable().update_dish(DishTable().get_dish_from_page(self.cath_id, x)) + return "1" + else: + return "1" else: - left = 0+((self.dish_page-1)*10) - right = self.max_index - x = add_func.validate_input('Введите номер обновляемого блюда (0 - для отмены): ', left, right) - if(x!=-1): - DishTable().update_dish(self.dish_arr[(int(x)-1)-((self.cath_page-1)*10)][0]) - else: - return "1" + print("Сначала выберите категорию") + return "1" elif next_step != "0" and next_step != "9" and next_step != "3": @@ -197,88 +221,90 @@ class Main: """ Добавление новой категории в таблицу """ - data = [] - data.append(input("Введите название (1 - отмена): ").strip()) - if data[0] == "1": - return - while((len(data[0].strip()) == 0)or(len(data[0].strip()) > 32)): - if (len(data[0].strip()) > 32): - data[0] = input("Название слишком длинное! Введите название заново (1 - отмена):").strip() - if data[0] == "1": - return + data = input("Введите название (enter - отмена): ").strip() + while((len(data) == 0)or(len(data) > 32)or(CathTable().check_by_name(data))): + if (len(data) > 32): + data = input("Название слишком длинное! Введите название заново (enter - отмена): ").strip() + elif(CathTable().check_by_name(data)): + data = input("Такое название уже существует! Введите название заново (enter - отмена): ").strip() else: - data[0] = input("Название не может быть пустым! Введите название заново (1 - отмена):").strip() - if data[0] == "1": - return - CathTable().insert_one(data) + return + CathTable().insert_one([data]) return + + def show_dish_page(self): + print("Блюда:") + dish_page = 1 + lst = DishTable().get_dish_page(self.cath_id, dish_page) + self.max_len_name = 0 + self.max_dish_index = DishTable().count(self.cath_id) + action = '>' + max_page = math.ceil(self.max_dish_index/10) + ((self.max_dish_index/10) == 0) + + lst = DishTable().get_dish_page(self.cath_id, dish_page) + + while True: + dish_arr = [] + + for i in lst: + dish_arr.append([str(i[2]), str(i[4]), str(i[5])]) + self.max_len_name = max(self.max_len_name, len(i[2])) + add_func.cls() + print("№" + " "*(len(str(self.max_dish_index)) + 1)+ "Название" + " " + " "*(self.max_len_name - 4)\ + +"Время приготовления Краткая инструкция\ + \n-------------------------------------------------------------------------------------------") + + for i in range(len(dish_arr)): + txt = add_func.add_zero_before(str((i+1)+(10*(dish_page-1))), \ + len(str(self.max_dish_index))) + " "*(2+len(str(self.max_dish_index))) + txt += dish_arr[i][0] + " "*(4+self.max_len_name - len(dish_arr[i][0])) + txt += dish_arr[i][1] + " "*(5+19-len(dish_arr[i][1])) + txt += dish_arr[i][2] + print(txt) + action = input('-------------------------------------------------------------------------------------------\n\ + Для переключения между страницами используйте "<" и ">"\n\ + Для выхода в меню действий нажмите любую другую клавишу\n=> ') + if(action=='>'): + if(dish_page==max_page): + dish_page = 1 + else: + dish_page += 1 + lst = DishTable().get_dish_page(self.cath_id, dish_page) + elif(action=='<'): + if(dish_page==1): + dish_page = max_page + else: + dish_page -= 1 + lst = DishTable().get_dish_page(self.cath_id, dish_page) + else: + break def show_dish_in_cath(self): """Вывод всех блюд в выбранной пользователем категории """ - if self.cath_id == -1: while True: - if(self.cath_page<(self.max_cath_index//10)): - left = 1+((self.cath_page-1)*10) - right = left+9 - - else: - left = 1+((self.cath_page-1)*10)+(self.cath_page!=1) - right = self.max_cath_index - x = add_func.validate_input('Выберите номер интересуемой категории (0 - отмена): ', left, right) + left = 1 + right = self.max_cath_index + x = add_func.validate_input('Выберите номер интересуемой категории (-1 - отмена): ', left, right) add_func.cls() if(x!=-1): - self.cath_id = CathTable().find_by_name(self.cath_arr[(int(x)-1)-((self.cath_page-1)*10)]) - self.cath_obj = self.cath_arr[(int(x)-1)-((self.cath_page-1)*10)] + self.cath = CathTable().get_cath_from_page(x) + self.cath_obj = self.cath.get("cath_name") + self.cath_id = self.cath.get("id") else: return "1" - print("Выбрана категория: " + self.cath_obj) - print("Блюда:") - self.dish_page = 1 - lst = DishTable().get_page_dish(self.cath_id, self.dish_page) - self.max_len_name = 0 - self.max_index = len(DishTable().all_by_cath_id(self.cath_id)) - action = '>' - max_page = math.ceil(self.max_index/10) - lst = DishTable().get_page_dish(self.cath_id, self.dish_page) + self.show_dish_page() + print(f"Выбрана категория: {self.cath_obj}") - while True: - self.dish_arr = [] - for i in lst: - self.dish_arr.append([i[2], str(i[1]), str(i[4])]) - self.max_len_name = max(self.max_len_name, len(i[2])) - add_func.cls() - print("№" + " "*(len(str(self.max_index)) + 1)+ "Название" + " "*(self.max_len_name - 4)\ - +"Время приготовления Краткая инструкция\ - \n-------------------------------------------------------------------------------------------") - - for i in range(len(self.dish_arr)): - txt = add_func.add_zero_before(str((i+1)+(10*(self.dish_page-1))), len(str(self.max_index))) + " "*(2+len(str(self.max_index))) - txt += self.dish_arr[i][0] + " "*(4+self.max_len_name - len(self.dish_arr[i][0])) - txt += self.dish_arr[i][1] + " "*(5+19-len(self.dish_arr[i][1])) - txt += self.dish_arr[i][2] - print(txt) - action = input('-------------------------------------------------------------------------------------------\n\ - Для переключения между страницами используйте "<" и ">"\nКол-во записей на странице: 10\n\ - Для выхода в меню действий нажмите любую другую клавишу\n=> ') - if(action=='>'): - if(self.dish_page==max_page): - self.dish_page = 1 - else: - self.dish_page += 1 - lst = DishTable().get_page_dish(self.cath_id, self.dish_page) - elif(action=='<'): - if(self.dish_page==1): - self.dish_page = max_page - else: - self.dish_page -= 1 - lst = DishTable().get_page_dish(self.cath_id, self.dish_page) - else: - break - - menu = texts.show_dish_in_cath_txt + menu = """-------------------------------------------------------------------------------------------\nДальнейшие операции: + 0 - возврат в главное меню; + 1 - возврат в просмотр категорий; + 6 - добавление нового блюда; + 7 - удаление блюда; + 88 - для обновления блюда; + 9 - выход.""" print(menu) return self.read_next_step() diff --git a/0.8_indev/tables/__pycache__/cath_table.cpython-311.pyc b/0.8_indev/tables/__pycache__/cath_table.cpython-311.pyc index 6cebb9d..8f5eeb6 100644 Binary files a/0.8_indev/tables/__pycache__/cath_table.cpython-311.pyc and b/0.8_indev/tables/__pycache__/cath_table.cpython-311.pyc differ diff --git a/0.8_indev/tables/__pycache__/dish_table.cpython-311.pyc b/0.8_indev/tables/__pycache__/dish_table.cpython-311.pyc index 7cc03d3..05fe468 100644 Binary files a/0.8_indev/tables/__pycache__/dish_table.cpython-311.pyc and b/0.8_indev/tables/__pycache__/dish_table.cpython-311.pyc differ diff --git a/0.8_indev/tables/cath_table.py b/0.8_indev/tables/cath_table.py index 1d6dcc5..bfb70e7 100644 --- a/0.8_indev/tables/cath_table.py +++ b/0.8_indev/tables/cath_table.py @@ -1,6 +1,9 @@ # Таблица с категориями и действия с ними from dbtable import * +import math + +ROW_PER_PAGE = 10 class CathTable(DbTable): def table_name(self): @@ -13,11 +16,10 @@ class CathTable(DbTable): def table_constraints(self): return ['CONSTRAINT "Name" UNIQUE (cath_name)'] - def delete(self, val): - param_sql = "DELETE FROM cath WHERE cath_name = %s;" + def delete(self, id): + param_sql = f"DELETE FROM cath WHERE id = {id};" cur = self.dbconn.conn.cursor() - value = "".join(val) - cur.execute(param_sql, (value,)) + cur.execute(param_sql) self.dbconn.conn.commit() def find_by_name(self, name): @@ -35,20 +37,14 @@ class CathTable(DbTable): print(f'''Выбрана категория для изменения: {old}''') cur = self.dbconn.conn.cursor() - data = input("Введите название (1 - отмена): ").strip() - if data == "1": - return + data = input("Введите название (enter - отмена): ").strip() while((len(data.strip()) == 0)or(len(data.strip()) > 32)or(self.check_by_name(data.strip()))): if (len(data.strip()) > 32): - data = input("Название слишком длинное! Введите название заново (1 - отмена):").strip() - if data == "1": - return - elif len(data.strip()) == 0: - data = input("Название не может быть пустым! Введите название заново (1 - отмена):").strip() - if data == "1": - return + data = input("Название слишком длинное! Введите название заново (enter - отмена):").strip() + elif(self.check_by_name(data.strip()) == 1): + data = input("Такое название уже существует. Введите новое (enter - отмена):").strip() else: - data = input("Такое название уже существует. Введите новое (1 - отмена):").strip() + return "1" param_sql = f"UPDATE cath SET cath_name = '{data}' WHERE cath_name = '{old}';" cur.execute(param_sql) @@ -64,27 +60,57 @@ class CathTable(DbTable): return True else: return False + + def get_cath_page(self, page_num): + """Функция для получения "страницы" из БД по её номеру. + В программе заменяет .all() для вывода информации. + + Args: + page_num (int): номер страницы, определяется пользователем. + + Returns: + lst (list): Список, содержащий в себе все строки для этой страницы. + """ + final_list = [] + cur = self.dbconn.conn.cursor() + offset = (page_num - 1) * ROW_PER_PAGE + sql = (f"SELECT * FROM {self.table_name()} LIMIT {ROW_PER_PAGE} OFFSET {offset}") + cur.execute(sql) + zero_list = cur.fetchall() + for i in range(len(zero_list)): + final_list.append([str(i+1+(ROW_PER_PAGE*(page_num-1))), str(zero_list[i][0]), zero_list[i][1]]) + return final_list + + def get_cath_from_page(self, row_num): + arr = self.get_cath_page(math.ceil(row_num/ROW_PER_PAGE)) + row = dict() + for i in arr: + if(int(i[0]) == row_num): + row["id"] = str(i[2]) + row["cath_name"] = str(i[1]) + return row + # def change_pages(self, ) def example_insert(self): - self.insert_one(["Завтрак"]) - self.insert_one(["Обед"]) - self.insert_one(["Ужин"]) - self.insert_one(["Перекус"]) - self.insert_one(["Десерт"]) - self.insert_one(["Напиток"]) - self.insert_one(["Закуска"]) - self.insert_one(["Салат"]) - self.insert_one(["Гарнир"]) - self.insert_one(["Выпечка"]) - self.insert_one(["Супы"]) - self.insert_one(["Соусы"]) - self.insert_one(["Паста"]) - self.insert_one(["Мясные блюда"]) - self.insert_one(["Рыбные блюда"]) - self.insert_one(["Веганские блюда"]) - self.insert_one(["Блюда из птицы"]) - self.insert_one(["Морепродукты"]) - self.insert_one(["Национальная кухня"]) - self.insert_one(["Быстрые блюда"]) + # self.insert_one(["Завтрак"]) + # self.insert_one(["Обед"]) + # self.insert_one(["Ужин"]) + # self.insert_one(["Перекус"]) + # self.insert_one(["Десерт"]) + # self.insert_one(["Напиток"]) + # self.insert_one(["Закуска"]) + # self.insert_one(["Салат"]) + # self.insert_one(["Гарнир"]) + # self.insert_one(["Выпечка"]) + # self.insert_one(["Супы"]) + # self.insert_one(["Соусы"]) + # self.insert_one(["Паста"]) + # self.insert_one(["Мясные блюда"]) + # self.insert_one(["Рыбные блюда"]) + # self.insert_one(["Веганские блюда"]) + # self.insert_one(["Блюда из птицы"]) + # self.insert_one(["Морепродукты"]) + # self.insert_one(["Национальная кухня"]) + # self.insert_one(["Быстрые блюда"]) return \ No newline at end of file diff --git a/0.8_indev/tables/dish_table.py b/0.8_indev/tables/dish_table.py index a683180..193233b 100644 --- a/0.8_indev/tables/dish_table.py +++ b/0.8_indev/tables/dish_table.py @@ -2,6 +2,9 @@ from dbtable import * import add_func +import math + +ROW_PER_PAGE = 10 class DishTable(DbTable): def table_name(self): @@ -17,8 +20,6 @@ class DishTable(DbTable): def table_constraints(self): return ['CONSTRAINT "Name Dish" UNIQUE (dish_name)'] - - def find_by_position(self, num): sql = "SELECT * FROM " + self.table_name() sql += " ORDER BY " @@ -37,22 +38,67 @@ class DishTable(DbTable): cur.execute(sql) return cur.fetchall() - def get_page_dish(self, cath_id, page_num): - row_per_page = 10 - offset = (page_num - 1) * row_per_page - sql = f"""SELECT * FROM dish WHERE cath_id = {str(cath_id)}\ - ORDER BY {", ".join(self.primary_key())} LIMIT {row_per_page} OFFSET {offset}""" - cur = self.dbconn.conn.cursor() - cur.execute(sql) - return cur.fetchall() - - def delete(self, val): - sql = "DELETE FROM dish" - sql += " WHERE dish_name" - sql += "=" + "'" + val + "';" +# def get_page_dish(self, cath_id, page_num): +# offset = (page_num - 1) * ROW_PER_PAGE +# sql = f"""SELECT * FROM dish WHERE cath_id = {str(cath_id)}\ +# ORDER BY {", ".join(self.primary_key())} LIMIT {ROW_PER_PAGE} OFFSET {offset}""" +# cur = self.dbconn.conn.cursor() +# cur.execute(sql) +# return cur.fetchall() + + def delete(self, id): + sql = f"""DELETE FROM {self.table_name()} WHERE id = {id};""" cur = self.dbconn.conn.cursor() cur.execute(sql) self.dbconn.conn.commit() + + def count(self, id): + sql = f"""SELECT COUNT(*) FROM {self.table_name()} WHERE cath_id = {id};""" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return int(cur.fetchone()[0]) + + def get_dish_from_page(self, cath_id, row_num): + arr = self.get_dish_page(cath_id, math.ceil(row_num/ROW_PER_PAGE)) + row = dict() + for i in arr: + if(int(i[0]) == row_num): + row["id"] = i[1] + row["dish_name"] = str(i[2]) + row["cath_id"] = i[3] + row["cook_time"] = str(i[4]) + row["manual"] = str(i[5]) + return row + + def get_dish_page(self, cath_id, page_num): + """Функция для получения "страницы" из БД по её номеру. + В программе заменяет .all() для вывода информации. + + Args: + page_num (int): номер страницы, определяется пользователем. + cath_id (int): id категории, из которой необходимо получить блюда + + Returns: + lst (list): Список, содержащий в себе все строки для этой страницы. + + 0 - number + 1 - id + 2 - name + 3 - cath_id + 4 - cook_time + 5 - manual + """ + final_list = [] + cur = self.dbconn.conn.cursor() + offset = (page_num - 1) * ROW_PER_PAGE + sql = (f"SELECT * FROM {self.table_name()} WHERE cath_id = {cath_id} LIMIT {ROW_PER_PAGE} OFFSET {offset}") + cur.execute(sql) + zero_list = cur.fetchall() + for i in range(len(zero_list)): + final_list.append([str(i+1+(ROW_PER_PAGE*(page_num-1))), zero_list[i][3],\ + str(zero_list[i][2]), zero_list[i][0], str(zero_list[i][1]), str(zero_list[i][4])]) + return final_list + def check_by_name(self, value): sql = f"SELECT * FROM {self.table_name()} WHERE dish_name='{value}'" @@ -82,100 +128,67 @@ class DishTable(DbTable): return str(result) def insert_dishone(self, cath_id): - - ins_name = input('Введите название добавляемого блюда (1 - для отмены): ') - - while (ins_name.strip() == '')or(len(ins_name.strip()) > 32)\ - or(DishTable().check_by_name(ins_name)): - - if(ins_name.strip() == ''): - ins_name = input("\nПустая строка. Повторите ввод! Укажите название удаляемого блюда (0 - отмена): ") - if ins_name == "0": - return "1" - - elif(len(ins_name.strip()) > 32): - ins_name = input("\nСлишком длинная строка. Повторите ввод!\ - Укажите название удаляемого блюда (0 - отмена): ") - if ins_name == "0": - return "1" - else: + while True: + ins_name = input('Введите название добавляемого блюда (enter - для отмены): ').strip() + if(len(ins_name) > 32): + print("Слишком длинная строка. Повторите ввод!") + elif(DishTable().check_by_name(ins_name)): print('\nТакое блюдо уже существует') - ins_name = input("Повторите ввод! Укажите название блюда (0 - отмена): ") - if ins_name == "0": - return "1" - - ins_time = input(f'\nПроцесс добавления блюда: {ins_name}\ - \nВведите время приготовления в формате 10 minutes/1 hour 5 minutes (1 - для отмены): ') - while(ins_time==0)or(add_func.validate_time_format(ins_time)==False): - if ins_time == "0": + elif(ins_name == ""): return "1" else: - ins_time = input('Время введено в неверном формате. Повторите попытку.\n\ -Введите время приготовления в формате 10 minutes/1 hour 5 minutes (1 - для отмены): ') - + break + + ins_time = add_func.input_time_format(ins_name) + ins_manual = input(f'\nПроцесс добавления блюда: {ins_name}\ - \nВведите краткую инструкцию приготовления блюда (1 - для отмены): ') - if ins_manual == "0": + \nВведите краткую инструкцию приготовления блюда (enter - для отмены): ').strip() + if ins_manual == "": return "1" - insert = [cath_id, ins_time, ins_name, ins_manual] - self.insert_one(insert) - def update_dish(self, dish): + def update_dish(self, obj: dict): print('После изменения выберите другой пункт для изменения или введите 0 для выхода') - n = dish x = -10000 - obj_id = self.id_by_name(dish)[1] + dish_id = obj.get("id") + dish_name = obj.get("dish_name") + tmp = dish_name while True: - x = add_func.validate_input(f'\nВыбранное блюдо: {n}\nЧто вы хотите изменить в рецепте?\n\ -1 - Название\n2 - Время приготовления\n3 - Инструкция\n0 - для отмены\n=> ', 0, 3) + x = add_func.validate_input(f'\nВыбранное блюдо: {tmp}\nЧто вы хотите изменить в рецепте?\n\ +1 - Название\n2 - Время приготовления\n3 - Инструкция\n-1 - для отмены\n=> ', 1, 3) if(x==1): - new_name = input(f"Текущее название {n}.\nВведите новое название (0 - для отмены): ") + new_name = input(f"Текущее название {tmp}.\nВведите новое название (enter - для отмены): ") while (new_name.strip() == '')or(len(new_name.strip()) > 32)\ - or(DishTable().check_by_name(new_name))or(x=='0'): - - if(new_name.strip() == ''): - new_name = input("Пустая строка. Повторите ввод! Укажите название блюда (0 - отмена): ") - if new_name == "0": - break - - elif(DishTable().check_by_name(new_name)): + or(DishTable().check_by_name(new_name)): + if(DishTable().check_by_name(new_name)): print('Такое блюдо уже существует') - new_name = input("Повторите ввод! Укажите название блюда (0 - отмена): ") - if new_name == "0": - break + new_name = input("Повторите ввод! Укажите название блюда (enter - отмена): ") elif(len(new_name.strip()) > 32): new_name = input("Слишком длинная строка. Повторите ввод!\ - Укажите название блюда (0 - отмена): ") - if new_name == "0": - break + Укажите название блюда (enter - отмена): ") else: break - # dish = new_name - n = new_name + tmp = new_name new_name = "'" + new_name + "'" - self.update('dish_name', new_name, obj_id) + self.update('dish_name', new_name, dish_id) elif(x==2): - new_time = input(f'Введите время приготовления в формате 10 minutes/1 hour 5 minutes (0 - для отмены): ') - while(new_time==0)or(add_func.validate_time_format(new_time)==False): - if new_time == "0": - break - else: - new_time = input('Введите время приготовления в формате 10 minutes/1 hour 5 minutes (0 - для отмены): ') - new_time = "'" + new_time + "'" - self.update('cook_time', new_time, obj_id) + new_time = add_func.input_time_format(tmp) + if(new_time != -1): + self.update('cook_time', new_time, dish_id) + else: + break elif(x==3): - new_manual = input(f'Введите краткую инструкцию приготовления блюда (0 - для отмены): ') - if new_manual == "0": + new_manual = input(f'Введите краткую инструкцию приготовления блюда (enter - для отмены): ') + if new_manual == "": break new_manual = "'" + new_manual + "'" - self.update('manual', new_manual, obj_id) + self.update('manual', new_manual, dish_id) elif(x==-1): break @@ -184,94 +197,95 @@ class DishTable(DbTable): def example_insert(self): - self.insert_one([1, "10 minutes", "Яичница", "Взбить яйца, нарезать помидоры, обжарить их вместе."]) - self.insert_one([1, "20 minutes", "Блины", "Замесить тесто, да пожарить. ©️ Никита Сергеич"]) - self.insert_one([2, "2 hours", "Хлэб", "Почти, как блины, но не совсем."]) - self.insert_one([3, "40 minutes", "Паста", "Почувствуй себя итальянцем"]) - self.insert_one([1, "1 hour", "Пицца", "Раскатать тесто, добавить начинку и запечь в духовке."]) - self.insert_one([2, "30 minutes", "Салат Цезарь", "Нарезать салат, приготовить соус и обжарить куриную грудку."]) - self.insert_one([3, "45 minutes", "Лазанья", "Слои теста с соусом и начинкой, запеченные в духовке."]) - self.insert_one([4, "1 hour 15 minutes", "Жаркое", "Обжарить мясо и овощи, затем потушить в духовке."]) - self.insert_one([5, "20 minutes", "Смузи", "Смешать фрукты, ягоды, йогурт и лед в блендере."]) - self.insert_one([6, "2 hours 30 minutes", "Бефстроганов", "Обжарить говядину, приготовить соус и подать с гарниром."]) - self.insert_one([7, "1 hour", "Чили кон карне", "Обжарить мясо, добавить фасоль, помидоры и специи."]) - self.insert_one([8, "45 minutes", "Фахитас", "Обжарить мясо и овощи, подать с лепешками и соусом."]) - self.insert_one([9, "2 hours", "Пельмени", "Приготовить тесто, начинку и слепить пельмени."]) - self.insert_one([10, "1 hour 30 minutes", "Ризотто", "Обжарить рис, добавить бульон и готовить, постоянно помешивая."]) - self.insert_one([11, "50 minutes", "Тако", "Обжарить начинку, подать с лепешками и соусами."]) - self.insert_one([12, "3 hours", "Бараньи ребрышки", "Замариновать ребрышки и запечь в духовке."]) - self.insert_one([13, "1 hour 15 minutes", "Карри", "Обжарить специи, добавить овощи и курицу, потушить."]) - self.insert_one([14, "30 minutes", "Бургер", "Обжарить котлету, собрать бургер с соусами и овощами."]) - self.insert_one([15, "2 hours 45 minutes", "Утка по-пекински", "Замариновать утку, запечь и подать с лепешками и соусом."]) - self.insert_one([16, "1 hour 30 minutes", "Паэлья", "Обжарить рис с овощами, добавить бульон и морепродукты."]) - self.insert_one([17, "45 minutes", "Рататуй", "Обжарить овощи и запечь в духовке."]) - self.insert_one([18, "2 hours", "Борщ", "Обжарить овощи, добавить бульон и тушить."]) - self.insert_one([19, "1 hour 15 minutes", "Куриные наггетсы", "Замариновать куриное филе, обвалять в панировке и обжарить."]) - self.insert_one([20, "3 hours", "Индейка с начинкой", "Приготовить начинку, фаршировать индейку и запекать в духовке."]) - self.insert_one([1, "50 minutes", "Фрикадельки", "Приготовить фарш, сформировать фрикадельки и обжарить."]) - self.insert_one([2, "2 hours 15 minutes", "Лазанья с мясным соусом", "Приготовить мясной соус, слои теста и запечь в духовке."]) - self.insert_one([3, "1 hour 30 minutes", "Чили", "Обжарить мясо, добавить фасоль, помидоры и специи, потушить."]) - self.insert_one([4, "40 minutes", "Хумус", "Приготовить нутовую пасту, добавить специи и подать с питой."]) - self.insert_one([5, "2 hours 30 minutes", "Утиная ножка по-французски", "Замариновать утиные ножки, обжарить и потушить."]) - self.insert_one([6, "1 hour 45 minutes", "Лапша по-сингапурски", "Обжарить лапшу с овощами, добавить соус и морепродукты."]) - self.insert_one([7, "55 minutes", "Фалафель", "Приготовить фалафельную смесь, сформировать шарики и обжарить."]) - self.insert_one([8, "2 hours 45 minutes", "Жаркое из телятины", "Обжарить мясо, добавить овощи и потушить в духовке."]) - self.insert_one([9, "1 hour 20 minutes", "Том ям", "Приготовить бульон, добавить морепродукты и специи."]) - self.insert_one([10, "3 hours 15 minutes", "Баранина по-гречески", "Замариновать баранину, запечь и подать с рисом."]) - self.insert_one([11, "50 minutes", "Картофельные оладьи", "Приготовить картофельное пюре, сформировать оладьи и обжарить."]) - self.insert_one([1, "30 minutes", "Омлет", "Взбить яйца, добавить ингредиенты по вкусу и запечь в духовке или обжарить на сковороде."]) - self.insert_one([1, "25 minutes", "Гренки", "Нарезать хлеб, обжарить на сковороде с маслом и чесноком."]) - self.insert_one([1, "45 minutes", "Запеканка", "Смешать ингредиенты, выложить в форму и запечь в духовке."]) - self.insert_one([1, "1 hour", "Ризотто", "Обжарить лук и рис, постепенно добавлять бульон и размешивать."]) - self.insert_one([1, "20 minutes", "Тосты", "Нарезать хлеб, обжарить на сковороде или в тостере, добавить начинку."]) - self.insert_one([1, "35 minutes", "Фриттата", "Смесь яиц, овощей и других ингредиентов, запеченная в духовке."]) - self.insert_one([1, "40 minutes", "Киш", "Открытый пирог с начинкой из яиц, сыра и других ингредиентов."]) - self.insert_one([1, "1 hour 10 minutes", "Рагу", "Тушеное блюдо из мяса, овощей и специй."]) - self.insert_one([1, "50 minutes", "Каннеллони", "Трубочки из теста, фаршированные начинкой и запеченные в соусе."]) - self.insert_one([1, "30 minutes", "Крок-месьё", "Тосты с сыром, запеченные в духовке."]) - self.insert_one([1, "1 hour 20 minutes", "Мусака", "Слоеное блюдо из баклажанов, мяса и соуса бешамель."]) - self.insert_one([1, "45 minutes", "Фрикадельки", "Приготовить фарш, сформировать шарики и обжарить или потушить."]) - self.insert_one([1, "35 minutes", "Зразы", "Фаршированные рулетики из мяса или овощей."]) - self.insert_one([1, "1 hour", "Чили кон карне", "Острое блюдо из мяса, бобов и специй."]) - self.insert_one([1, "40 minutes", "Блинчики", "Приготовить тесто, испечь блины и добавить начинку."]) - self.insert_one([1, "50 minutes", "Кесадилья", "Лепешка с начинкой, запеченная с сыром."]) - self.insert_one([1, "1 hour 30 minutes", "Паэлья", "Испанское блюдо из риса, морепродуктов и овощей."]) - self.insert_one([1, "25 minutes", "Сэндвичи", "Хлеб с различными начинками и соусами."]) - self.insert_one([1, "55 minutes", "Лазанья-роллы", "Рулетики из лазаньи с начинкой и соусом."]) - self.insert_one([1, "1 hour 10 minutes", "Тефтели", "Фрикадельки в томатном соусе."]) - self.insert_one([1, "35 minutes", "Вафли", "Приготовить тесто и выпекать в вафельнице."]) - self.insert_one([1, "45 minutes", "Фахитас", "Мексиканские лепешки с начинкой из мяса, овощей и специй."]) - self.insert_one([1, "1 hour 20 minutes", "Чили син карне", "Вегетарианская версия чили кон карне."]) - self.insert_one([1, "30 minutes", "Тартины", "Открытые бутерброды с различными ингредиентами."]) - self.insert_one([1, "55 minutes", "Энчиладас", "Мексиканские лепешки, завернутые с начинкой и запеченные в соусе."]) - self.insert_one([1, "1 hour 15 minutes", "Ризотто с морепродуктами", "Ризотто с добавлением креветок, кальмаров и другими морепродуктами."]) - self.insert_one([1, "40 minutes", "Панини", "Горячие сэндвичи, приготовленные в специальном прессе."]) - self.insert_one([1, "50 minutes", "Тортилья", "Испанский омлет с картофелем и луком."]) - self.insert_one([1, "1 hour 30 minutes", "Тажин", "Марокканское блюдо, приготовленное в глиняном горшочке."]) - self.insert_one([1, "35 minutes", "Брускетта", "Хлеб, обжаренный с чесноком и помидорами."]) - self.insert_one([1, "1 hour", "Рататуй", "Овощное рагу из баклажанов, цуккини, перца и помидоров."]) - self.insert_one([1, "45 minutes", "Начос", "Чипсы с начинкой из фасоли, сыра, гуакамоле и сальсы."]) - self.insert_one([1, "1 hour 20 minutes", "Курица тикка масала", "Индийское блюдо из курицы в пряном соусе."]) - self.insert_one([1, "30 minutes", "Бутерброды", "Хлеб с различными ингредиентами и соусами."]) - self.insert_one([1, "55 minutes", "Фалафель", "Жареные шарики из нута с соусами."]) - self.insert_one([1, "1 hour 15 minutes", "Чана масала", "Индийское блюдо из нута в пряном соусе."]) - self.insert_one([1, "40 minutes", "Кимчи-боул", "Миска с рисом, кимчи и другими ингредиентами."]) - self.insert_one([1, "50 minutes", "Такос", "Мексиканские лепешки с начинкой из мяса, овощей и соусов."]) - self.insert_one([1, "1 hour 30 minutes", "Цуккини-лазанья", "Лазанья с использованием цуккини вместо теста."]) - self.insert_one([1, "35 minutes", "Брускетта с авокадо", "Хлеб с авокадо, помидорами и специями."]) - self.insert_one([1, "1 hour", "Чана масала с цветной капустой", "Индийское блюдо из цветной капусты в пряном соусе."]) - self.insert_one([1, "45 minutes", "Баос", "Мягкие булочки с начинкой из свинины, огурцов и соусов."]) - self.insert_one([1, "1 hour 20 minutes", "Пад-тай", "Тайская лапша с яйцом, креветками и овощами."]) - self.insert_one([1, "30 minutes", "Авокадо-тосты", "Тосты с авокадо, яйцом и другими ингредиентами."]) - self.insert_one([1, "55 minutes", "Кимчи-чигэ", "Острый корейский суп с кимчи и свининой."]) - self.insert_one([1, "1 hour 15 minutes", "Буррито-боул", "Миска с рисом, фасолью, мясом, овощами и соусами."]) - self.insert_one([1, "40 minutes", "Баклажаны по-гречески", "Запеченные баклажаны с томатным соусом и сыром."]) - self.insert_one([1, "50 minutes", "Том-ям", "Острый тайский суп с креветками и грибами."]) - self.insert_one([1, "1 hour 30 minutes", "Веганский пастуший пирог", "Пастуший пирог с растительными ингредиентами."]) - self.insert_one([1, "35 minutes", "Сэндвич с авокадо и яйцом", "Бутерброд с авокадо, яйцом и другими ингредиентами."]) - self.insert_one([1, "1 hour", "Карри с тофу и овощами", "Тайское карри с тофу и смесью овощей."]) - self.insert_one([1, "45 minutes", "Кимчи-фритата", "Фриттата с добавлением кимчи и других ингредиентов."]) - self.insert_one([1, "1 hour 20 minutes", "Паста с песто из авокадо", "Паста с соусом из авокадо, базилика и сыра."]) - self.insert_one([1, "30 minutes", "Яичница с авокадо", "Яичница с добавлением авокадо и других ингредиентов."]) - self.insert_one([1, "55 minutes", "Веганский пад-тай", "Пад-тай с использованием растительных ингредиентов."]) - return \ No newline at end of file + # self.insert_one([1, "10 minutes", "Яичница", "Взбить яйца, нарезать помидоры, обжарить их вместе."]) + # self.insert_one([1, "20 minutes", "Блины", "Замесить тесто, да пожарить. ©️ Никита Сергеич"]) + # self.insert_one([2, "2 hours", "Хлэб", "Почти, как блины, но не совсем."]) + # self.insert_one([3, "40 minutes", "Паста", "Почувствуй себя итальянцем"]) + # self.insert_one([1, "1 hour", "Пицца", "Раскатать тесто, добавить начинку и запечь в духовке."]) + # self.insert_one([2, "30 minutes", "Салат Цезарь", "Нарезать салат, приготовить соус и обжарить куриную грудку."]) + # self.insert_one([3, "45 minutes", "Лазанья", "Слои теста с соусом и начинкой, запеченные в духовке."]) + # self.insert_one([4, "1 hour 15 minutes", "Жаркое", "Обжарить мясо и овощи, затем потушить в духовке."]) + # self.insert_one([5, "20 minutes", "Смузи", "Смешать фрукты, ягоды, йогурт и лед в блендере."]) + # self.insert_one([6, "2 hours 30 minutes", "Бефстроганов", "Обжарить говядину, приготовить соус и подать с гарниром."]) + # self.insert_one([7, "1 hour", "Чили кон карне", "Обжарить мясо, добавить фасоль, помидоры и специи."]) + # self.insert_one([8, "45 minutes", "Фахитас", "Обжарить мясо и овощи, подать с лепешками и соусом."]) + # self.insert_one([9, "2 hours", "Пельмени", "Приготовить тесто, начинку и слепить пельмени."]) + # self.insert_one([10, "1 hour 30 minutes", "Ризотто", "Обжарить рис, добавить бульон и готовить, постоянно помешивая."]) + # self.insert_one([11, "50 minutes", "Тако", "Обжарить начинку, подать с лепешками и соусами."]) + # self.insert_one([12, "3 hours", "Бараньи ребрышки", "Замариновать ребрышки и запечь в духовке."]) + # self.insert_one([13, "1 hour 15 minutes", "Карри", "Обжарить специи, добавить овощи и курицу, потушить."]) + # self.insert_one([14, "30 minutes", "Бургер", "Обжарить котлету, собрать бургер с соусами и овощами."]) + # self.insert_one([15, "2 hours 45 minutes", "Утка по-пекински", "Замариновать утку, запечь и подать с лепешками и соусом."]) + # self.insert_one([16, "1 hour 30 minutes", "Паэлья", "Обжарить рис с овощами, добавить бульон и морепродукты."]) + # self.insert_one([17, "45 minutes", "Рататуй", "Обжарить овощи и запечь в духовке."]) + # self.insert_one([18, "2 hours", "Борщ", "Обжарить овощи, добавить бульон и тушить."]) + # self.insert_one([19, "1 hour 15 minutes", "Куриные наггетсы", "Замариновать куриное филе, обвалять в панировке и обжарить."]) + # self.insert_one([20, "3 hours", "Индейка с начинкой", "Приготовить начинку, фаршировать индейку и запекать в духовке."]) + # self.insert_one([1, "50 minutes", "Фрикадельки", "Приготовить фарш, сформировать фрикадельки и обжарить."]) + # self.insert_one([2, "2 hours 15 minutes", "Лазанья с мясным соусом", "Приготовить мясной соус, слои теста и запечь в духовке."]) + # self.insert_one([3, "1 hour 30 minutes", "Чили", "Обжарить мясо, добавить фасоль, помидоры и специи, потушить."]) + # self.insert_one([4, "40 minutes", "Хумус", "Приготовить нутовую пасту, добавить специи и подать с питой."]) + # self.insert_one([5, "2 hours 30 minutes", "Утиная ножка по-французски", "Замариновать утиные ножки, обжарить и потушить."]) + # self.insert_one([6, "1 hour 45 minutes", "Лапша по-сингапурски", "Обжарить лапшу с овощами, добавить соус и морепродукты."]) + # self.insert_one([7, "55 minutes", "Фалафель", "Приготовить фалафельную смесь, сформировать шарики и обжарить."]) + # self.insert_one([8, "2 hours 45 minutes", "Жаркое из телятины", "Обжарить мясо, добавить овощи и потушить в духовке."]) + # self.insert_one([9, "1 hour 20 minutes", "Том ям", "Приготовить бульон, добавить морепродукты и специи."]) + # self.insert_one([10, "3 hours 15 minutes", "Баранина по-гречески", "Замариновать баранину, запечь и подать с рисом."]) + # self.insert_one([11, "50 minutes", "Картофельные оладьи", "Приготовить картофельное пюре, сформировать оладьи и обжарить."]) + # self.insert_one([1, "30 minutes", "Омлет", "Взбить яйца, добавить ингредиенты по вкусу и запечь в духовке или обжарить на сковороде."]) + # self.insert_one([1, "25 minutes", "Гренки", "Нарезать хлеб, обжарить на сковороде с маслом и чесноком."]) + # self.insert_one([1, "45 minutes", "Запеканка", "Смешать ингредиенты, выложить в форму и запечь в духовке."]) + # self.insert_one([1, "1 hour", "Ризотто", "Обжарить лук и рис, постепенно добавлять бульон и размешивать."]) + # self.insert_one([1, "20 minutes", "Тосты", "Нарезать хлеб, обжарить на сковороде или в тостере, добавить начинку."]) + # self.insert_one([1, "35 minutes", "Фриттата", "Смесь яиц, овощей и других ингредиентов, запеченная в духовке."]) + # self.insert_one([1, "40 minutes", "Киш", "Открытый пирог с начинкой из яиц, сыра и других ингредиентов."]) + # self.insert_one([1, "1 hour 10 minutes", "Рагу", "Тушеное блюдо из мяса, овощей и специй."]) + # self.insert_one([1, "50 minutes", "Каннеллони", "Трубочки из теста, фаршированные начинкой и запеченные в соусе."]) + # self.insert_one([1, "30 minutes", "Крок-месьё", "Тосты с сыром, запеченные в духовке."]) + # self.insert_one([1, "1 hour 20 minutes", "Мусака", "Слоеное блюдо из баклажанов, мяса и соуса бешамель."]) + # self.insert_one([1, "45 minutes", "Фрикадельки", "Приготовить фарш, сформировать шарики и обжарить или потушить."]) + # self.insert_one([1, "35 minutes", "Зразы", "Фаршированные рулетики из мяса или овощей."]) + # self.insert_one([1, "1 hour", "Чили кон карне", "Острое блюдо из мяса, бобов и специй."]) + # self.insert_one([1, "40 minutes", "Блинчики", "Приготовить тесто, испечь блины и добавить начинку."]) + # self.insert_one([1, "50 minutes", "Кесадилья", "Лепешка с начинкой, запеченная с сыром."]) + # self.insert_one([1, "1 hour 30 minutes", "Паэлья", "Испанское блюдо из риса, морепродуктов и овощей."]) + # self.insert_one([1, "25 minutes", "Сэндвичи", "Хлеб с различными начинками и соусами."]) + # self.insert_one([1, "55 minutes", "Лазанья-роллы", "Рулетики из лазаньи с начинкой и соусом."]) + # self.insert_one([1, "1 hour 10 minutes", "Тефтели", "Фрикадельки в томатном соусе."]) + # self.insert_one([1, "35 minutes", "Вафли", "Приготовить тесто и выпекать в вафельнице."]) + # self.insert_one([1, "45 minutes", "Фахитас", "Мексиканские лепешки с начинкой из мяса, овощей и специй."]) + # self.insert_one([1, "1 hour 20 minutes", "Чили син карне", "Вегетарианская версия чили кон карне."]) + # self.insert_one([1, "30 minutes", "Тартины", "Открытые бутерброды с различными ингредиентами."]) + # self.insert_one([1, "55 minutes", "Энчиладас", "Мексиканские лепешки, завернутые с начинкой и запеченные в соусе."]) + # self.insert_one([1, "1 hour 15 minutes", "Ризотто с морепродуктами", "Ризотто с добавлением креветок, кальмаров и другими морепродуктами."]) + # self.insert_one([1, "40 minutes", "Панини", "Горячие сэндвичи, приготовленные в специальном прессе."]) + # self.insert_one([1, "50 minutes", "Тортилья", "Испанский омлет с картофелем и луком."]) + # self.insert_one([1, "1 hour 30 minutes", "Тажин", "Марокканское блюдо, приготовленное в глиняном горшочке."]) + # self.insert_one([1, "35 minutes", "Брускетта", "Хлеб, обжаренный с чесноком и помидорами."]) + # self.insert_one([1, "1 hour", "Рататуй", "Овощное рагу из баклажанов, цуккини, перца и помидоров."]) + # self.insert_one([1, "45 minutes", "Начос", "Чипсы с начинкой из фасоли, сыра, гуакамоле и сальсы."]) + # self.insert_one([1, "1 hour 20 minutes", "Курица тикка масала", "Индийское блюдо из курицы в пряном соусе."]) + # self.insert_one([1, "30 minutes", "Бутерброды", "Хлеб с различными ингредиентами и соусами."]) + # self.insert_one([1, "55 minutes", "Фалафель", "Жареные шарики из нута с соусами."]) + # self.insert_one([1, "1 hour 15 minutes", "Чана масала", "Индийское блюдо из нута в пряном соусе."]) + # self.insert_one([1, "40 minutes", "Кимчи-боул", "Миска с рисом, кимчи и другими ингредиентами."]) + # self.insert_one([1, "50 minutes", "Такос", "Мексиканские лепешки с начинкой из мяса, овощей и соусов."]) + # self.insert_one([1, "1 hour 30 minutes", "Цуккини-лазанья", "Лазанья с использованием цуккини вместо теста."]) + # self.insert_one([1, "35 minutes", "Брускетта с авокадо", "Хлеб с авокадо, помидорами и специями."]) + # self.insert_one([1, "1 hour", "Чана масала с цветной капустой", "Индийское блюдо из цветной капусты в пряном соусе."]) + # self.insert_one([1, "45 minutes", "Баос", "Мягкие булочки с начинкой из свинины, огурцов и соусов."]) + # self.insert_one([1, "1 hour 20 minutes", "Пад-тай", "Тайская лапша с яйцом, креветками и овощами."]) + # self.insert_one([1, "30 minutes", "Авокадо-тосты", "Тосты с авокадо, яйцом и другими ингредиентами."]) + # self.insert_one([1, "55 minutes", "Кимчи-чигэ", "Острый корейский суп с кимчи и свининой."]) + # self.insert_one([1, "1 hour 15 minutes", "Буррито-боул", "Миска с рисом, фасолью, мясом, овощами и соусами."]) + # self.insert_one([1, "40 minutes", "Баклажаны по-гречески", "Запеченные баклажаны с томатным соусом и сыром."]) + # self.insert_one([1, "50 minutes", "Том-ям", "Острый тайский суп с креветками и грибами."]) + # self.insert_one([1, "1 hour 30 minutes", "Веганский пастуший пирог", "Пастуший пирог с растительными ингредиентами."]) + # self.insert_one([1, "35 minutes", "Сэндвич с авокадо и яйцом", "Бутерброд с авокадо, яйцом и другими ингредиентами."]) + # self.insert_one([1, "1 hour", "Карри с тофу и овощами", "Тайское карри с тофу и смесью овощей."]) + # self.insert_one([1, "45 minutes", "Кимчи-фритата", "Фриттата с добавлением кимчи и других ингредиентов."]) + # self.insert_one([1, "1 hour 20 minutes", "Паста с песто из авокадо", "Паста с соусом из авокадо, базилика и сыра."]) + # self.insert_one([1, "30 minutes", "Яичница с авокадо", "Яичница с добавлением авокадо и других ингредиентов."]) + # self.insert_one([1, "55 minutes", "Веганский пад-тай", "Пад-тай с использованием растительных ингредиентов."]) + return + \ No newline at end of file diff --git a/0.8_indev/test.py b/0.8_indev/test.py index 5b1e75e..d18e09e 100644 --- a/0.8_indev/test.py +++ b/0.8_indev/test.py @@ -1,10 +1,43 @@ +# # a = dict() +# # for i in range(1, 41, 2): +# # for j in range(2, 41, 2): +# # a[f"{i}"] = f"{j}" + +# # print(a) + +# # import psycopg2 +# # from psycopg2.extras import Interval -import os +# # def check_interval(value): +# # try: +# # # Попытка преобразования значения в объект Interval +# # interval_obj = Interval(value) +# # # Если преобразование успешно, значение относится к типу Interval +# # return isinstance(interval_obj, Interval) +# # except (ValueError, TypeError): +# # # Если преобразование не удалось, значение не относится к типу Interval +# # return False + +# # user_input = input("Введите интервал: ") +# # if check_interval(user_input): +# # print("Введенное значение относится к типу Interval") +# # else: +# # print("Введенное значение не относится к типу Interval") +# import psycopg2 +# from psycopg2.extras import DateTimeTZRange -print('До очистки') -# Для Windows -os.system('cls') +# def check_interval(input_str): +# try: +# # Создаем объект Interval из входной строки +# interval = DateTimeTZRange(input_str, '[]') +# except (ValueError, psycopg2.DataError): +# return False +# return True +# # Примеры использования +# print(check_interval('1 day')) # True +# print(check_interval('1:60')) # False +# print(check_interval('P1Y2M3DT4H5M6.7S')) # True -print('после очистки') \ No newline at end of file +import this \ No newline at end of file diff --git a/lab6.code-workspace b/lab6.code-workspace new file mode 100644 index 0000000..0870ba8 --- /dev/null +++ b/lab6.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "." + }, + { + "path": "../sun_project" + } + ], + "settings": {} +} \ No newline at end of file diff --git a/other/Nekit/__pycache__/add_func.cpython-311.pyc b/other/Nekit/__pycache__/add_func.cpython-311.pyc new file mode 100644 index 0000000..7e72e6c Binary files /dev/null and b/other/Nekit/__pycache__/add_func.cpython-311.pyc differ diff --git a/other/Nekit/__pycache__/dbconnection.cpython-311.pyc b/other/Nekit/__pycache__/dbconnection.cpython-311.pyc new file mode 100644 index 0000000..f85e242 Binary files /dev/null and b/other/Nekit/__pycache__/dbconnection.cpython-311.pyc differ diff --git a/other/Nekit/__pycache__/dbtable.cpython-311.pyc b/other/Nekit/__pycache__/dbtable.cpython-311.pyc new file mode 100644 index 0000000..4140dca Binary files /dev/null and b/other/Nekit/__pycache__/dbtable.cpython-311.pyc differ diff --git a/other/Nekit/__pycache__/project_config.cpython-311.pyc b/other/Nekit/__pycache__/project_config.cpython-311.pyc new file mode 100644 index 0000000..8815881 Binary files /dev/null and b/other/Nekit/__pycache__/project_config.cpython-311.pyc differ diff --git a/other/Nekit/__pycache__/texts.cpython-311.pyc b/other/Nekit/__pycache__/texts.cpython-311.pyc new file mode 100644 index 0000000..165ae1b Binary files /dev/null and b/other/Nekit/__pycache__/texts.cpython-311.pyc differ diff --git a/other/Nekit/add_func.py b/other/Nekit/add_func.py new file mode 100644 index 0000000..458bbfc --- /dev/null +++ b/other/Nekit/add_func.py @@ -0,0 +1,53 @@ +import re + +def validate_time_format(input_str): + """Функция проверки подходящего формата для ввода времени в interval + + Args: + input_str (str): входная строка для проверки + + Returns: + bool: Булевое значение, которое характеризует валидность вводимых строк + """ + # Регулярное выражение для проверки формата + pattern = r'^(\d?+\s*hours?\s*)?(\d+\s*minutes?)$' + + # Проверка соответствия регулярному выражению + match = re.match(pattern, input_str) + + if match: + return True + + # Если формат некорректный, возвращаем False + return False + +def validate_input(prompt, min_value, max_value): + """Проверка ввода для выбора номера строки + + Args: + prompt (string): "Промт" или запрос пользователю + min_value (int): Нижняя граница, по умолчанию 0 + max_value (int): Верхняя граница + + Returns: + int: Либо число, введенное пользователем, либо -1 для выхода + """ + while True: + user_input = input(prompt) + try: + value = int(user_input) + if min_value <= value <= max_value and value != 0: + return value + elif value == 0: + return -1 + else: + print(f"Введенное значение должно быть в диапазоне от {min_value} до {max_value}") + except ValueError: + print("Введенное значение должно быть числом.") + + +# test1 = 'erhwogngonwro' +# test2 = '1 minute' +# test3 = '2 hours 3 minutes' + +# print(validate_time_format(test1), validate_time_format(test2), validate_time_format(test3)) \ No newline at end of file diff --git a/other/Nekit/config.yaml b/other/Nekit/config.yaml new file mode 100644 index 0000000..be6cac8 --- /dev/null +++ b/other/Nekit/config.yaml @@ -0,0 +1,6 @@ +# Базовые параметры настройки конфигурации проекта +dbname: Test # В классе менять не надо +user: postgres # Замените на свой логин от БД в классе +password: Qwerty # Замените на свой пароль от БД в классе +host: localhost # Замените на 192.168.0.48 в классе +dbtableprefix: "public." # Замените на свой логин от БД \ No newline at end of file diff --git a/other/Nekit/dbconnection.py b/other/Nekit/dbconnection.py new file mode 100644 index 0000000..6fac33c --- /dev/null +++ b/other/Nekit/dbconnection.py @@ -0,0 +1,34 @@ +# Установка соединения с базой данных +# (параметры передаются через класс конфиг). +import psycopg2 + +class DbConnection: + + def __init__(self, config): + self.dbname = config.dbname + self.user = config.user + self.password = config.password + self.host = config.host + self.prefix = config.dbtableprefix + self.conn = psycopg2.connect(dbname = self.dbname, + user = self.user, + password = self.password, + host = self.host) + + def __del__(self): + if self.conn: + self.conn.close() + + def test(self): + cur = self.conn.cursor() + cur.execute("DROP TABLE IF EXISTS test CASCADE") + cur.execute("CREATE TABLE test(test integer)") + cur.execute("INSERT INTO test(test) VALUES(1)") + self.conn.commit() + cur.execute("SELECT * FROM test") + result = cur.fetchall() + cur.execute("DROP TABLE test") + self.conn.commit() + return (result[0][0] == 1) + + diff --git a/other/Nekit/dbtable.py b/other/Nekit/dbtable.py new file mode 100644 index 0000000..a84f108 --- /dev/null +++ b/other/Nekit/dbtable.py @@ -0,0 +1,124 @@ +# Базовые действия с таблицами + +from dbconnection import * + +''' +FIXME: +''' + +class DbTable: + dbconn = None + + def __init__(self): + return + + def table_name(self): + return self.dbconn.prefix + "table" + + def columns(self): + return {"test": ["integer", "PRIMARY KEY"]} + + def column_names(self): + return sorted(self.columns().keys(), key = lambda x: x) + + def primary_key(self): + return ['id'] + + def column_names_without_id(self): + res = sorted(self.columns().keys(), key = lambda x: x) + if 'id' in res: + res.remove('id') + return res + + def table_constraints(self): + return [] + + def create(self): + sql = "CREATE TABLE " + self.table_name() + "(" + arr = [k + " " + " ".join(v) for k, v in sorted(self.columns().items(), key = lambda x: x[0])] + sql += ", ".join(arr + self.table_constraints()) + sql += ")" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + self.dbconn.conn.commit() + return + + def drop(self): + sql = "DROP TABLE IF EXISTS " + self.table_name() + cur = self.dbconn.conn.cursor() + cur.execute(sql) + self.dbconn.conn.commit() + return + + def insert_one(self, vals): + for i in range(len(vals)): + if type(vals[i]) == str: + vals[i] = "'" + vals[i] + "'" + else: + vals[i] = str(vals[i]) + values = ", ".join(vals) + query = f"""INSERT INTO {self.table_name()}({", ".join(self.column_names_without_id())}) VALUES({values})""" + cur = self.dbconn.conn.cursor() + # cur.execute(sql) + try: + cur.execute(query) + self.dbconn.conn.commit() + except psycopg2.errors.UniqueViolation: + self.dbconn.conn.rollback() + print('Такая строка уже существует. Повторите попытку') + return + + def update(self, column, values, wh): + sql = f"UPDATE {self.table_name()} SET {column} = {values} WHERE id = {wh};" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + self.dbconn.conn.commit() + return + + def first(self): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return cur.fetchone() + + def last(self): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join([x + " DESC" for x in self.primary_key()]) + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return cur.fetchone() + + def all(self): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return cur.fetchall() + + def select_one(self, **kwargs): + conditions = [] + values = [] + + sorted_kwargs = sorted(kwargs.items(), key=lambda x: x[0]) + + for key, value in sorted_kwargs(): + conditions.append(f"{key}=%s") + values.append(value) + + sql = f"SELECT * FROM {self.table_name()} WHERE " + " AND ".join(conditions) + cur = self.dbconn.conn.cursor() + cur.execute(sql, tuple(values)) + result = cur.fetchone() + cur.close() + + if result: + return True + else: + return False + + + diff --git a/other/Nekit/main.py b/other/Nekit/main.py new file mode 100644 index 0000000..b76fa77 --- /dev/null +++ b/other/Nekit/main.py @@ -0,0 +1,228 @@ +import sys +import texts +# import time +sys.path.append('tables') + +from project_config import * +from dbconnection import * + +from tables.dish_table import * +from tables.cath_table import * + +''' +TODO: +1) Реализовать ввод порядкового номера - done +2) Удалить проверки на "русскоязычный ввод" - done +3) Устранить SQLi с помощью санации атрибутов - done +4) UPDATE для категорий - done +5) Красивый вывод - done +6) Доделать ограничение на выбор категории - done +7) UPDATE для блюд - done +8) Постраничный вывод - indev + +FIXME: +''' + + +class Main: + + + config = ProjectConfig() + connection = DbConnection(config) + + def __init__(self): + DbTable.dbconn = self.connection + return + + def db_init(self): + cth = CathTable() + d = DishTable() + cth.create() + d.create() + return + + def db_insert_somethings(self): + cth = CathTable() + dsh = DishTable() + + cth.example_insert() + dsh.example_insert() + + def db_drop(self): + cth = CathTable() + d = DishTable() + d.drop() + cth.drop() + return + + def show_main_menu(self): + menu = texts.show_main_menu_txt + print(menu) + return + + def read_next_step(self): + return input("=> ").strip() + + def after_main_menu(self, next_step): + if next_step == "2": + self.db_drop() + self.db_init() + self.db_insert_somethings() + print("Таблицы созданы заново!") + return "0" + elif next_step != "1" and next_step != "9": + print("Выбрано неверное число! Повторите ввод!") + return "0" + else: + return next_step + + def show_cath(self): + self.cath_id = -1 + self.cath_arr = [] + menu = texts.show_cath_1txt + print(menu) + lst = CathTable().all() + self.max_cath_index = (len(lst)) + for i in lst: + self.cath_arr.append(str(i[0])) + + for i in range(len(self.cath_arr)): + print(str(i+1) + "\t" + self.cath_arr[i]) + + menu = texts.show_cath_2txt + print(menu) + return + + def after_show_cath(self, next_step): + """Выбор действий после вывода категорий + """ + while True: + if next_step == "4": # Удаление категории + x = add_func.validate_input('Введите номер удаляемой категории (0 - для отмены): ', 0, self.max_cath_index) + if(x!=-1): + CathTable().delete(self.cath_arr[int(x)-1]) + return "1" + + elif next_step == "6": #Добавление блюда в категорию + DishTable().insert_dishone(self.cath_id) + next_step = "5" + + elif next_step == "7":#Удаление блюда из категории + x = add_func.validate_input('Введите номер удаляемого блюда (0 - для отмены): ', 0, self.max_index) + if(x!=-1): + DishTable().delete(self.dish_arr[int(x)-1][0]) + else: + return "1" + next_step = "5" + + elif next_step == "5": + next_step = self.show_dish_in_cath() + + elif next_step == "8": # Обновление названия категории + x = add_func.validate_input('Введите номер обновляемой категории (0 - для отмены): ', 0, self.max_cath_index) + if(x!=-1): + CathTable().cath_update(self.cath_arr[int(x)-1]) + return "1" + elif next_step == "88": + x = add_func.validate_input('Введите номер изменяемого блюда (0 - для отмены): ', 0, self.max_index) + if(x!=-1): + DishTable().update_dish(self.dish_arr[int(x)-1][0]) + else: + return "1" + + + elif next_step != "0" and next_step != "9" and next_step != "3": + print("Выбрано неверное число! Повторите ввод!") + return "1" + else: + return next_step + + def add_cath(self): + """ + Добавление новой категории в таблицу + """ + data = [] + data.append(input("Введите название (1 - отмена): ").strip()) + if data[0] == "1": + return + while((len(data[0].strip()) == 0)or(len(data[0].strip()) > 32)): + if (len(data[0].strip()) > 32): + data[0] = input("Название слишком длинное! Введите название заново (1 - отмена):").strip() + if data[0] == "1": + return + else: + data[0] = input("Название не может быть пустым! Введите название заново (1 - отмена):").strip() + if data[0] == "1": + return + CathTable().insert_one(data) + return + + def show_dish_in_cath(self): + """Вывод всех блюд в выбранной пользователем категории + """ + self.dish_arr = [] + if self.cath_id == -1: + while True: + x = add_func.validate_input('Выберите номер интересуемой категории (0 - отмена): ', 0, self.max_cath_index) + if(x!=-1): + self.cath_id = CathTable().find_by_name(self.cath_arr[x-1]) + self.cath_obj = self.cath_arr[x-1] + else: + return "1" + + print("Выбрана категория: " + self.cath_obj) + print("Блюда:") + + lst = DishTable().all_by_cath_id(self.cath_id) + self.max_len_name = 0 + self.max_index = len(lst) + for i in lst: + self.dish_arr.append([i[2], str(i[1]), str(i[4])]) + self.max_len_name = max(self.max_len_name, len(i[2])) + print("№" + " "*(self.max_index + 1)+ "Название" + " "*(self.max_len_name - 4)\ + +"Время приготовления Краткая инструкция\ + \n-------------------------------------------------------------------------------------------") + for i in range(len(self.dish_arr)): + txt = str(i+1) + " "*(2+self.max_index-len(str(i))) + txt += self.dish_arr[i][0] + " "*(4+self.max_len_name - len(self.dish_arr[i][0])) + txt += self.dish_arr[i][1] + " "*(5+19-len(self.dish_arr[i][1])) + txt += self.dish_arr[i][2] + print(txt) + menu = texts.show_dish_in_cath_txt + print(menu) + return self.read_next_step() + + def main_cycle(self): + """Основной цикл программы, регулирующий порядок действий + """ + current_menu = "0" + next_step = None + + while(current_menu != "9"): + + if current_menu == "0": + self.show_main_menu() + next_step = self.read_next_step() + current_menu = self.after_main_menu(next_step) + + elif current_menu == "1": + self.show_cath() + next_step = self.read_next_step() + current_menu = self.after_show_cath(next_step) + + elif current_menu == "2": + self.show_main_menu() + + elif current_menu == "3": + self.add_cath() + current_menu = "1" + + print("До свидания!") + return + + def test(self): + DbTable.dbconn.test() + +m = Main() +# m.test() +m.main_cycle() \ No newline at end of file diff --git a/other/Nekit/project_config.py b/other/Nekit/project_config.py new file mode 100644 index 0000000..2b451e5 --- /dev/null +++ b/other/Nekit/project_config.py @@ -0,0 +1,21 @@ +# Загрузка настроек проекта (в данном случае только настроек соединения с БД) +# из файла config.yaml. +import yaml + +class ProjectConfig: + """Класс считывает базовые настройки из файла config.yaml""" + + def __init__(self): + with open('config.yaml') as f: + config = yaml.safe_load(f) + self.dbname = config['dbname'] + self.user = config['user'] + self.password = config['password'] + self.host = config['host'] + self.dbtableprefix = config['dbtableprefix'] + +# Этот метод запускается только, если запускать +# данный файл, а не подключать его. +if __name__ == "__main__": + x = ProjectConfig() + print(x.dbfilepath) diff --git a/other/Nekit/tables/__pycache__/cath_table.cpython-311.pyc b/other/Nekit/tables/__pycache__/cath_table.cpython-311.pyc new file mode 100644 index 0000000..e976e38 Binary files /dev/null and b/other/Nekit/tables/__pycache__/cath_table.cpython-311.pyc differ diff --git a/other/Nekit/tables/__pycache__/dish_table.cpython-311.pyc b/other/Nekit/tables/__pycache__/dish_table.cpython-311.pyc new file mode 100644 index 0000000..e7959f7 Binary files /dev/null and b/other/Nekit/tables/__pycache__/dish_table.cpython-311.pyc differ diff --git a/other/Nekit/tables/cath_table.py b/other/Nekit/tables/cath_table.py new file mode 100644 index 0000000..1d6dcc5 --- /dev/null +++ b/other/Nekit/tables/cath_table.py @@ -0,0 +1,90 @@ +# Таблица с категориями и действия с ними + +from dbtable import * + +class CathTable(DbTable): + def table_name(self): + return self.dbconn.prefix + "cath" + + def columns(self): + return {"id": ["serial", "PRIMARY KEY"], + "cath_name": ["varchar(32)", "NOT NULL"]} + + def table_constraints(self): + return ['CONSTRAINT "Name" UNIQUE (cath_name)'] + + def delete(self, val): + param_sql = "DELETE FROM cath WHERE cath_name = %s;" + cur = self.dbconn.conn.cursor() + value = "".join(val) + cur.execute(param_sql, (value,)) + self.dbconn.conn.commit() + + def find_by_name(self, name): + cur = self.dbconn.conn.cursor() + param_query = "SELECT id FROM cath WHERE cath_name = %s;" + # sql_sel = "SELECT id FROM " + self.table_name() + # sql_sel += " WHERE cath_name = " + "'" + name + "'" + ";" + cur.execute(param_query, (name,)) + ret = list(cur.fetchone())[0] + return ret + + def cath_update(self, old): + """Функция для обновления категории + """ + print(f'''Выбрана категория для изменения: {old}''') + cur = self.dbconn.conn.cursor() + + data = input("Введите название (1 - отмена): ").strip() + if data == "1": + return + while((len(data.strip()) == 0)or(len(data.strip()) > 32)or(self.check_by_name(data.strip()))): + if (len(data.strip()) > 32): + data = input("Название слишком длинное! Введите название заново (1 - отмена):").strip() + if data == "1": + return + elif len(data.strip()) == 0: + data = input("Название не может быть пустым! Введите название заново (1 - отмена):").strip() + if data == "1": + return + else: + data = input("Такое название уже существует. Введите новое (1 - отмена):").strip() + + param_sql = f"UPDATE cath SET cath_name = '{data}' WHERE cath_name = '{old}';" + cur.execute(param_sql) + self.dbconn.conn.commit() + + def check_by_name(self, value): + sql = f"SELECT * FROM {self.table_name()} WHERE cath_name='{value}'" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + result = cur.fetchone() + cur.close() + if result: + return True + else: + return False + + + def example_insert(self): + self.insert_one(["Завтрак"]) + self.insert_one(["Обед"]) + self.insert_one(["Ужин"]) + self.insert_one(["Перекус"]) + self.insert_one(["Десерт"]) + self.insert_one(["Напиток"]) + self.insert_one(["Закуска"]) + self.insert_one(["Салат"]) + self.insert_one(["Гарнир"]) + self.insert_one(["Выпечка"]) + self.insert_one(["Супы"]) + self.insert_one(["Соусы"]) + self.insert_one(["Паста"]) + self.insert_one(["Мясные блюда"]) + self.insert_one(["Рыбные блюда"]) + self.insert_one(["Веганские блюда"]) + self.insert_one(["Блюда из птицы"]) + self.insert_one(["Морепродукты"]) + self.insert_one(["Национальная кухня"]) + self.insert_one(["Быстрые блюда"]) + return \ No newline at end of file diff --git a/other/Nekit/tables/dish_table.py b/other/Nekit/tables/dish_table.py new file mode 100644 index 0000000..4ebb705 --- /dev/null +++ b/other/Nekit/tables/dish_table.py @@ -0,0 +1,202 @@ +# Таблица с блюдами и действия с ними + +from dbtable import * +import add_func + +class DishTable(DbTable): + def table_name(self): + return self.dbconn.prefix + "dish" + + def columns(self): + return {"id": ["serial", "PRIMARY KEY"], + "cath_id": ["integer", "REFERENCES cath(id) ON DELETE CASCADE", "NOT NULL"], + "dish_name": ["varchar(32)", "NOT NULL"], + "cook_time": ["interval"], + "manual": ["text"]} + + def table_constraints(self): + return ['CONSTRAINT "Name Dish" UNIQUE (dish_name)'] + + + + def find_by_position(self, num): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + sql += " LIMIT 1 OFFSET %(offset)s" + cur = self.dbconn.conn.cursor() + cur.execute(sql, {"offset": num - 1}) + return cur.fetchone() + + def all_by_cath_id(self, cath_id): + sql = "SELECT * FROM " + self.table_name() + sql += " WHERE cath_id = " + str(cath_id) + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return cur.fetchall() + + def delete(self, val): + sql = "DELETE FROM dish" + sql += " WHERE dish_name" + sql += "=" + "'" + val + "';" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + self.dbconn.conn.commit() + + def check_by_name(self, value): + sql = f"SELECT * FROM {self.table_name()} WHERE dish_name='{value}'" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + result = cur.fetchone() + cur.close() + if result: + return True + else: + return False + + def name_by_id(self, id): + sql = f'SELECT dish_name FROM dish WHERE id = {id}' + cur = self.dbconn.conn.cursor() + cur.execute(sql) + result = cur.fetchone() + cur.close() + return str(result) + + def id_by_name(self, name): + sql = f"""SELECT id FROM dish WHERE dish_name = '{name}'""" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + result = cur.fetchone() + cur.close() + return str(result) + + def insert_dishone(self, cath_id): + + ins_name = input('Введите название добавляемого блюда (1 - для отмены): ') + + while (ins_name.strip() == '')or(len(ins_name.strip()) > 32)\ + or(DishTable().check_by_name(ins_name)): + + if(ins_name.strip() == ''): + ins_name = input("Пустая строка. Повторите ввод! Укажите название добавляемого блюда (0 - отмена): ") + if ins_name == "0": + return "1" + + elif(len(ins_name.strip()) > 32): + ins_name = input("Слишком длинная строка. Повторите ввод!\ + Укажите название добавляемого блюда (0 - отмена): ") + if ins_name == "0": + return "1" + else: + print('Такое блюдо уже существует') + ins_name = input("Повторите ввод! Укажите название блюда (0 - отмена): ") + if ins_name == "0": + return "1" + + ins_time = input(f'Процесс добавления блюда: {ins_name}\ + \nВведите время приготовления в формате 10 minutes/1 hour 5 minutes (1 - для отмены): ') + while(ins_time==0)or(add_func.validate_time_format(ins_time)==False): + if ins_time == "0": + return "1" + else: + ins_time = input('Время введено в неверном формате. Повторите попытку.\n\ +Введите время приготовления в формате 10 minutes/1 hour 5 minutes (1 - для отмены): ') + + ins_manual = input(f'Процесс добавления блюда: {ins_name}\ + \nВведите краткую инструкцию приготовления блюда (1 - для отмены): ') + if ins_manual == "0": + return "1" + + insert = [cath_id, ins_time, ins_name, ins_manual] + + self.insert_one(insert) + + def update_dish(self, dish): + print('После изменения выберите другой пункт для изменения или введите 0 для выхода') + x = -10000 + obj_id = self.id_by_name(dish)[1] + while(x!=-1): + x = add_func.validate_input('Что вы хотите изменить в рецепте?\n\ +1 - Название\n2 - Время приготовления\n3 - Инструкция\n0 - для отмены\n=> ', 0, 3) + + if(x==1): + new_name = input(f"Текущее название {dish}.\nВведите новое название: ") + while (new_name.strip() == '')or(len(new_name.strip()) > 32)\ + or(DishTable().check_by_name(new_name)): + if(new_name.strip() == ''): + new_name = input("Пустая строка. Повторите ввод! Укажите название блюда (0 - отмена): ") + if new_name == "0": + return "1" + + elif(len(new_name.strip()) > 32): + new_name = input("Слишком длинная строка. Повторите ввод!\ + Укажите название блюда (0 - отмена): ") + if new_name == "0": + return "1" + else: + print('Такое блюдо уже существует') + new_name = input("Повторите ввод! Укажите название блюда (0 - отмена): ") + if new_name == "0": + return "1" + new_name = "'" + new_name + "'" + self.update('dish_name', new_name, obj_id) + + elif(x==2): + new_time = input(f'Введите время приготовления в формате 10 minutes/1 hour 5 minutes (1 - для отмены): ') + while(new_time==0)or(add_func.validate_time_format(new_time)==False): + if new_time == "0": + return "1" + else: + new_time = input('Введите время приготовления в формате 10 minutes/1 hour 5 minutes (1 - для отмены): ') + new_time = "'" + new_time + "'" + self.update('cook_time', new_time, obj_id) + + elif(x==3): + new_manual = input(f'Введите краткую инструкцию приготовления блюда (1 - для отмены): ') + if new_manual == "0": + return "1" + new_manual = "'" + new_manual + "'" + self.update('manual', new_manual, obj_id) + + + + + def example_insert(self): + self.insert_one([1, "10 minutes", "Яичница", "Взбить яйца, нарезать помидоры, обжарить их вместе."]) + self.insert_one([1, "20 minutes", "Блины", "Замесить тесто, да пожарить. ©️ Никита Сергеич"]) + self.insert_one([2, "2 hours", "Хлэб", "Почти, как блины, но не совсем."]) + self.insert_one([3, "40 minutes", "Паста", "Почувствуй себя итальянцем"]) + self.insert_one([1, "1 hour", "Пицца", "Раскатать тесто, добавить начинку и запечь в духовке."]) + self.insert_one([2, "30 minutes", "Салат Цезарь", "Нарезать салат, приготовить соус и обжарить куриную грудку."]) + self.insert_one([3, "45 minutes", "Лазанья", "Слои теста с соусом и начинкой, запеченные в духовке."]) + self.insert_one([4, "1 hour 15 minutes", "Жаркое", "Обжарить мясо и овощи, затем потушить в духовке."]) + self.insert_one([5, "20 minutes", "Смузи", "Смешать фрукты, ягоды, йогурт и лед в блендере."]) + self.insert_one([6, "2 hours 30 minutes", "Бефстроганов", "Обжарить говядину, приготовить соус и подать с гарниром."]) + self.insert_one([7, "1 hour", "Чили кон карне", "Обжарить мясо, добавить фасоль, помидоры и специи."]) + self.insert_one([8, "45 minutes", "Фахитас", "Обжарить мясо и овощи, подать с лепешками и соусом."]) + self.insert_one([9, "2 hours", "Пельмени", "Приготовить тесто, начинку и слепить пельмени."]) + self.insert_one([10, "1 hour 30 minutes", "Ризотто", "Обжарить рис, добавить бульон и готовить, постоянно помешивая."]) + self.insert_one([11, "50 minutes", "Тако", "Обжарить начинку, подать с лепешками и соусами."]) + self.insert_one([12, "3 hours", "Бараньи ребрышки", "Замариновать ребрышки и запечь в духовке."]) + self.insert_one([13, "1 hour 15 minutes", "Карри", "Обжарить специи, добавить овощи и курицу, потушить."]) + self.insert_one([14, "30 minutes", "Бургер", "Обжарить котлету, собрать бургер с соусами и овощами."]) + self.insert_one([15, "2 hours 45 minutes", "Утка по-пекински", "Замариновать утку, запечь и подать с лепешками и соусом."]) + self.insert_one([16, "1 hour 30 minutes", "Паэлья", "Обжарить рис с овощами, добавить бульон и морепродукты."]) + self.insert_one([17, "45 minutes", "Рататуй", "Обжарить овощи и запечь в духовке."]) + self.insert_one([18, "2 hours", "Борщ", "Обжарить овощи, добавить бульон и тушить."]) + self.insert_one([19, "1 hour 15 minutes", "Куриные наггетсы", "Замариновать куриное филе, обвалять в панировке и обжарить."]) + self.insert_one([20, "3 hours", "Индейка с начинкой", "Приготовить начинку, фаршировать индейку и запекать в духовке."]) + self.insert_one([1, "50 minutes", "Фрикадельки", "Приготовить фарш, сформировать фрикадельки и обжарить."]) + self.insert_one([2, "2 hours 15 minutes", "Лазанья с мясным соусом", "Приготовить мясной соус, слои теста и запечь в духовке."]) + self.insert_one([3, "1 hour 30 minutes", "Чили", "Обжарить мясо, добавить фасоль, помидоры и специи, потушить."]) + self.insert_one([4, "40 minutes", "Хумус", "Приготовить нутовую пасту, добавить специи и подать с питой."]) + self.insert_one([5, "2 hours 30 minutes", "Утиная ножка по-французски", "Замариновать утиные ножки, обжарить и потушить."]) + self.insert_one([6, "1 hour 45 minutes", "Лапша по-сингапурски", "Обжарить лапшу с овощами, добавить соус и морепродукты."]) + self.insert_one([7, "55 minutes", "Фалафель", "Приготовить фалафельную смесь, сформировать шарики и обжарить."]) + self.insert_one([8, "2 hours 45 minutes", "Жаркое из телятины", "Обжарить мясо, добавить овощи и потушить в духовке."]) + self.insert_one([9, "1 hour 20 minutes", "Том ям", "Приготовить бульон, добавить морепродукты и специи."]) + self.insert_one([10, "3 hours 15 minutes", "Баранина по-гречески", "Замариновать баранину, запечь и подать с рисом."]) + self.insert_one([11, "50 minutes", "Картофельные оладьи", "Приготовить картофельное пюре, сформировать оладьи и обжарить."]) + return \ No newline at end of file diff --git a/other/Nekit/test.py b/other/Nekit/test.py new file mode 100644 index 0000000..0a318aa --- /dev/null +++ b/other/Nekit/test.py @@ -0,0 +1 @@ +print(len("\t")) \ No newline at end of file diff --git a/0.8_indev/texts.py b/other/Nekit/texts.py similarity index 100% rename from 0.8_indev/texts.py rename to other/Nekit/texts.py diff --git a/other/Right/.idea/.gitignore b/other/Right/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/other/Right/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/other/Right/.idea/Right.iml b/other/Right/.idea/Right.iml new file mode 100644 index 0000000..8b8c395 --- /dev/null +++ b/other/Right/.idea/Right.iml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/other/Right/.idea/inspectionProfiles/profiles_settings.xml b/other/Right/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/other/Right/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/other/Right/.idea/misc.xml b/other/Right/.idea/misc.xml new file mode 100644 index 0000000..d56657a --- /dev/null +++ b/other/Right/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/other/Right/.idea/modules.xml b/other/Right/.idea/modules.xml new file mode 100644 index 0000000..e971c9a --- /dev/null +++ b/other/Right/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/other/Right/__pycache__/cathegory_table.cpython-311.pyc b/other/Right/__pycache__/cathegory_table.cpython-311.pyc new file mode 100644 index 0000000..1eee49f Binary files /dev/null and b/other/Right/__pycache__/cathegory_table.cpython-311.pyc differ diff --git a/other/Right/__pycache__/cathegory_table.cpython-39.pyc b/other/Right/__pycache__/cathegory_table.cpython-39.pyc new file mode 100644 index 0000000..6ed9b4d Binary files /dev/null and b/other/Right/__pycache__/cathegory_table.cpython-39.pyc differ diff --git a/other/Right/__pycache__/dbconnection.cpython-311.pyc b/other/Right/__pycache__/dbconnection.cpython-311.pyc new file mode 100644 index 0000000..e7ca4e6 Binary files /dev/null and b/other/Right/__pycache__/dbconnection.cpython-311.pyc differ diff --git a/other/Right/__pycache__/dbconnection.cpython-39.pyc b/other/Right/__pycache__/dbconnection.cpython-39.pyc new file mode 100644 index 0000000..9534e32 Binary files /dev/null and b/other/Right/__pycache__/dbconnection.cpython-39.pyc differ diff --git a/other/Right/__pycache__/dbtable.cpython-311.pyc b/other/Right/__pycache__/dbtable.cpython-311.pyc new file mode 100644 index 0000000..3dc8aaf Binary files /dev/null and b/other/Right/__pycache__/dbtable.cpython-311.pyc differ diff --git a/other/Right/__pycache__/dbtable.cpython-39.pyc b/other/Right/__pycache__/dbtable.cpython-39.pyc new file mode 100644 index 0000000..9256561 Binary files /dev/null and b/other/Right/__pycache__/dbtable.cpython-39.pyc differ diff --git a/other/Right/__pycache__/dish_table.cpython-311.pyc b/other/Right/__pycache__/dish_table.cpython-311.pyc new file mode 100644 index 0000000..d2da102 Binary files /dev/null and b/other/Right/__pycache__/dish_table.cpython-311.pyc differ diff --git a/other/Right/__pycache__/dish_table.cpython-39.pyc b/other/Right/__pycache__/dish_table.cpython-39.pyc new file mode 100644 index 0000000..3d325c4 Binary files /dev/null and b/other/Right/__pycache__/dish_table.cpython-39.pyc differ diff --git a/other/Right/__pycache__/project_config.cpython-311.pyc b/other/Right/__pycache__/project_config.cpython-311.pyc new file mode 100644 index 0000000..47df0a5 Binary files /dev/null and b/other/Right/__pycache__/project_config.cpython-311.pyc differ diff --git a/other/Right/__pycache__/project_config.cpython-39.pyc b/other/Right/__pycache__/project_config.cpython-39.pyc new file mode 100644 index 0000000..d4e0e91 Binary files /dev/null and b/other/Right/__pycache__/project_config.cpython-39.pyc differ diff --git a/other/Right/cathegory_table.py b/other/Right/cathegory_table.py new file mode 100644 index 0000000..765f3ac --- /dev/null +++ b/other/Right/cathegory_table.py @@ -0,0 +1,45 @@ +# Таблица Телефоны и особые действия с ней. + +from dbtable import * +import re + +class CathegoryTable(DbTable): + def table_name(self): + return self.dbconn.prefix + "Cathegory" + + def columns(self): + return {"cath_id": ["serial", "PRIMARY KEY"], + "cath_name": ["varchar(20)", "NOT NULL"]} + + def primary_key(self): + return ["cath_id"] + + def delete_one(self, data): + if type(data)==int: + sql = f"DELETE FROM {self.table_name()} WHERE cath_id = %(id)s" + cur = self.dbconn.conn.cursor() + cur.execute(sql, {'id': str(data)}) + self.dbconn.conn.commit() + elif type(data)==str: + sql = f"DELETE FROM {self.table_name()} WHERE name = %(name)s" + cur = self.dbconn.conn.cursor() + + cur.execute(sql, {'name': str(data)}) + self.dbconn.conn.commit() + return + + def exist_by_number(self, data): + sql = "SELECT * FROM " + self.table_name() + sql += " WHERE cath_id = %(id)s" + cur = self.dbconn.conn.cursor() + cur.execute(sql, {'id': str(data)}) + return len(cur.fetchall()) > 0 + + + def update(self, cathegory_id, data): + sql = "UPDATE " + self.table_name() + sql += " SET cath_name = '" + re.split(r"'|--|\(|\)", data[0])[0] + "'" + sql += " WHERE cath_id = %(id)s" + cur = self.dbconn.conn.cursor() + cur.execute(sql, {'id': str(cathegory_id)}) + self.dbconn.conn.commit() \ No newline at end of file diff --git a/other/Right/config.yaml b/other/Right/config.yaml new file mode 100644 index 0000000..be6cac8 --- /dev/null +++ b/other/Right/config.yaml @@ -0,0 +1,6 @@ +# Базовые параметры настройки конфигурации проекта +dbname: Test # В классе менять не надо +user: postgres # Замените на свой логин от БД в классе +password: Qwerty # Замените на свой пароль от БД в классе +host: localhost # Замените на 192.168.0.48 в классе +dbtableprefix: "public." # Замените на свой логин от БД \ No newline at end of file diff --git a/other/Right/dbconnection.py b/other/Right/dbconnection.py new file mode 100644 index 0000000..6fac33c --- /dev/null +++ b/other/Right/dbconnection.py @@ -0,0 +1,34 @@ +# Установка соединения с базой данных +# (параметры передаются через класс конфиг). +import psycopg2 + +class DbConnection: + + def __init__(self, config): + self.dbname = config.dbname + self.user = config.user + self.password = config.password + self.host = config.host + self.prefix = config.dbtableprefix + self.conn = psycopg2.connect(dbname = self.dbname, + user = self.user, + password = self.password, + host = self.host) + + def __del__(self): + if self.conn: + self.conn.close() + + def test(self): + cur = self.conn.cursor() + cur.execute("DROP TABLE IF EXISTS test CASCADE") + cur.execute("CREATE TABLE test(test integer)") + cur.execute("INSERT INTO test(test) VALUES(1)") + self.conn.commit() + cur.execute("SELECT * FROM test") + result = cur.fetchall() + cur.execute("DROP TABLE test") + self.conn.commit() + return (result[0][0] == 1) + + diff --git a/other/Right/dbtable.py b/other/Right/dbtable.py new file mode 100644 index 0000000..003586a --- /dev/null +++ b/other/Right/dbtable.py @@ -0,0 +1,103 @@ +# Базовые действия с таблицами +import re + +from dbconnection import * + +class DbTable: + dbconn = None + + def __init__(self): + return + + def table_name(self): + return self.dbconn.prefix + "table" + + def columns(self): + return {"test": ["integer", "PRIMARY KEY"]} + + def column_names(self): + return sorted(self.columns().keys(), key = lambda x: x) + + def primary_key(self): + return ['id'] + + def column_names_without_id(self): + res = list(self.columns().keys()) + for key in self.primary_key(): + if key in res: + res.remove(key) + return res + + def table_constraints(self): + return [] + + def create(self): + sql = "CREATE TABLE " + self.table_name() + "(" + arr = [k + " " + " ".join(v) for k, v in self.columns().items()] + sql += ", ".join(arr + self.table_constraints()) + sql += ")" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + self.dbconn.conn.commit() + return + + def drop(self): + sql = "DROP TABLE IF EXISTS " + self.table_name() + cur = self.dbconn.conn.cursor() + cur.execute(sql) + self.dbconn.conn.commit() + return + + def delete_one(self, data): + if type(data)==int: + sql = f"DELETE FROM {self.table_name()} WHERE id = %(id)s" + cur = self.dbconn.conn.cursor() + cur.execute(sql, {'id': str(data)}) + self.dbconn.conn.commit() + elif type(data)==str: + sql = f"DELETE FROM {self.table_name()} WHERE name = %(name)s" + cur = self.dbconn.conn.cursor() + cur.execute(sql, {'name': str(data)}) + self.dbconn.conn.commit() + return + + def insert_one(self, vals): + for i in range(0, len(vals)): + if type(vals[i]) == str: + vals[i] = re.split(r"'|--|\(|\)", vals[i])[0] + vals[i] = "'" + vals[i] + "'" + else: + vals[i] = str(vals[i]) + # sql = "INSERT INTO " + self.table_name() + "(" + # sql += ", ".join(self.column_names_without_id()) + ") VALUES(" + # sql += ", ".join(vals) + ")" + sql = f"""INSERT INTO {self.table_name()} ({", ".join(self.column_names_without_id())}) VALUES ({", ".join(vals)});""" + cur = self.dbconn.conn.cursor() + cur.execute(sql) + self.dbconn.conn.commit() + return + + def first(self): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return cur.fetchone() + + def last(self): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join([x + " DESC" for x in self.primary_key()]) + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return cur.fetchone() + + def all(self): + sql = "SELECT * FROM " + self.table_name() + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + cur = self.dbconn.conn.cursor() + cur.execute(sql) + return cur.fetchall() + diff --git a/other/Right/dish_table.py b/other/Right/dish_table.py new file mode 100644 index 0000000..8212847 --- /dev/null +++ b/other/Right/dish_table.py @@ -0,0 +1,53 @@ +from dbtable import * + +class DishTable(DbTable): + def table_name(self): + return self.dbconn.prefix + "Dish" + + def exist_by_number(self, dish_id): + sql = f"SELECT COUNT(*) FROM {self.table_name()} WHERE dish_id = %(id)s" + cur = self.dbconn.conn.cursor() + cur.execute(sql, {'id': str(dish_id)}) + return cur.fetchone()[0] > 0 + + def columns(self): + return {"dish_id": ["serial", "PRIMARY KEY"], + "name": ["varchar(64)", "NOT NULL"], + "cook_time": ["integer", "NOT NULL"], + "manual": ["text", "NOT NULL"], + "cath_id": ["integer", "NOT NULL"]} + + def primary_key(self): + return ["dish_id"] + + def get_all_by_cathegory_number(self, cathegory_number): + sql = "SELECT * FROM " + self.table_name() + sql += " WHERE cath_id = %(id)s" + sql += " ORDER BY " + sql += ", ".join(self.primary_key()) + cur = self.dbconn.conn.cursor() + print(str(cathegory_number)) + cur.execute(sql, {'id': str(cathegory_number)}) + return cur.fetchall() + + def delete_one(self, data): + if type(data)==int: + sql = f"DELETE FROM {self.table_name()} WHERE dish_id = %(id)s" + cur = self.dbconn.conn.cursor() + cur.execute(sql, {'id': str(data)}) + self.dbconn.conn.commit() + elif type(data)==str: + sql = f"DELETE FROM {self.table_name()} WHERE name = %(name)s" + cur = self.dbconn.conn.cursor() + cur.execute(sql, {'name': str(data)}) + self.dbconn.conn.commit() + return + + def delete_all_with_cathegory_id(self, cathegory_id): + sql = f"DELETE FROM {self.table_name()} WHERE cath_id = %(id)s" + cur = self.dbconn.conn.cursor() + cur.execute(sql, {'id': str(cathegory_id)}) + self.dbconn.conn.commit() + + + diff --git a/other/Right/mainN.py b/other/Right/mainN.py new file mode 100644 index 0000000..9d4199c --- /dev/null +++ b/other/Right/mainN.py @@ -0,0 +1,304 @@ +import sys + +sys.path.append('tables') + +from project_config import * +from dbconnection import * +from cathegory_table import * +from dish_table import * + + +class Main: + config = ProjectConfig() + connection = DbConnection(config) + + def __init__(self): + DbTable.dbconn = self.connection + return + + def db_init(self): + ct = CathegoryTable() + dt = DishTable() + ct.create() + dt.create() + return + + def db_insert_somethings(self): + ct = CathegoryTable() + dt = DishTable() + ct.insert_one(["Салат"]) + ct.insert_one(["Второе"]) + ct.insert_one(["Суп"]) + dt.insert_one(["Борщ", "120", "Сварить супчик", 3]) + dt.insert_one(["Домашний салат", "15", "Настругать салатик", 1]) + dt.insert_one(["Жаркое", "60", "Нажарить на славу", 2]) + dt.insert_one(["Цезарь", "40", "Настругать салатик с курицей", 1]) + + def db_drop(self): + ct = CathegoryTable() + dt = DishTable() + ct.drop() + dt.drop() + return + + def show_main_menu(self): + menu = """Добро пожаловать! +Основное меню (выберите цифру в соответствии с необходимым действием): + 1 - просмотр всех категорий; + 2 - сброс и инициализация таблиц; + 3 - просмотр всех блюд; + 9 - выход.""" + print(menu) + return + + def read_next_step(self): + return input("=> ").strip() + + def after_main_menu(self, next_step): + if next_step == "2": + self.db_drop() + self.db_init() + self.db_insert_somethings() + print("Таблицы созданы заново!") + return "0" + if not next_step.isdigit(): + print("Неверный тип данных! Введите число!") + return "0" + elif next_step != "1" and next_step != "9" and next_step != "3": + print("Выбрано неверное число! Повторите ввод!") + return "0" + else: + return next_step + + def show_cathegory(self): + menu = """Просмотр категорий! +№\tНазвание""" + print(menu) + allCathegory = CathegoryTable().all() + self.max_cath_index = len(allCathegory) + for i in allCathegory: + print(str(i[0]) + "\t" + str(i[1])) + menu = """Дальнейшие операции: + 0 - возврат в главное меню; + 4 - добавление новой категории; + 5 - удаление категории; + 6 - изменить название категории; + 9 - выход.""" + print(menu) + return + + def show_dish(self): + menu = """Просмотр блюд! +Формат: № ; Название ; Время приготовления ; Мануал ; Номер категории""" + print(menu) + allDish = DishTable().all() + for i in allDish: + print(str(i[0]) + " ; " + str(i[1]) + " ; " + str(i[2]) + " ; " + str(i[3]) + " ; " + str(i[4])) + menu = """Дальнейшие операции: + 0 - возврат в главное меню; + 1 - просмотр блюд по номеру категории; + 2 - удаление блюда; + 3 - добавление блюда; + 9 - выход.""" + print(menu) + return + + def after_show_dish(self, next_step): + while True: + if next_step == "1": + self.all_dish_by_cathegory() + return "0" + elif next_step == "2": + self.del_dish() + return "3" + elif next_step == "3": + self.insert_dish() + return "3" + elif next_step != "0" and next_step != "9": + print("Выбрано неверное число! Повторите ввод!") + next_step = self.read_next_step() + else: + return next_step + + def all_dish_by_cathegory(self): + cathegory_number = input("Введите номер категории(enter - отмена): ").strip() + if cathegory_number == "": + return + try: + cathegory_number = int(cathegory_number) + except ValueError: + print("Неверный тип. Ожидается число") + return + txt = """"Просмотр блюд! +Формат: № ; Название ; Время приготовления ; Мануал ; Номер категории""" + print(txt) + allDish = DishTable().get_all_by_cathegory_number(cathegory_number) + for i in allDish: + print(str(i[0]) + " ; " + str(i[1]) + " ; " + str(i[2]) + " ; " + str(i[3]) + " ; " + str(i[4])) + + + def del_dish(self): + dish_id = input("Введите № блюда для удаления: ").strip() + try: + dish_id = int(dish_id) + if dish_id > 0: + DishTable().delete_one(dish_id) + else: + print("Неверное значение. Ожидается целое положительное число") + return + except ValueError: + print("Неверный тип. Ожидается число") + return + dish_table = DishTable() + if not dish_table.exist_by_number(dish_id): + print("Указанный номер блюда не найден. Попробуйте заново") + return + + dish_table.delete_one(dish_id) + print("Блюдо успешно удалено") + + + def insert_dish(self): + data = [] + + data.append(input("Введите имя блюда(enter - отмена): ").strip()) + while len(data[0].strip()) > 64: + data[0] = input("Неверная длина! Имя должно быть не пустым и не больше 64 символов. Введите имя заново (1 - отмена):").strip() + if data[0] == "": + print("Отмена действия") + return + + data.append(input("Введите время приготовления в минутах(0 - отмена): ").strip()) + flag = True + while flag: + try: + data[1] = int(data[1]) + except ValueError: + data[1] = input("Неверный тип. Ожидается число. Введите число заново (0 - отмена):").strip() + continue + flag = False + if data[1] == 0: + return + if data[1] < 0: + print("Время не может быть отрицательным") + return + + data.append(input("Введите мануал(enter - отмена): ").strip()) + #while len(data[2].strip()) == 0: + # data[2] = input("Неверная длина! Мануал должно быть не пустым. Введите мануал заново (enter - отмена):").strip() + if data[2] == "": + print("Отмена действия") + return + + data.append(input("Введите номер категории(enter - отмена): ").strip()) + if data[3] == "": + return + flag = True + while flag: + try: + data[3] = int(data[3]) + except ValueError: + data[3] = input("Неверный тип. Ожидается число. Введите число заново (enter - отмена):").strip() + if data[3] == "": + return + continue + flag = False + + if not (CathegoryTable().exist_by_number(data[3])): + print("Указанный номер категории не найдем. Попробуйте заново") + return + DishTable().insert_one(data) + + def after_show_cathegory(self, next_step): + while True: + if next_step == "4": + self.insert_cathegory() + return "1" + elif next_step == "5": + self.del_cathegory() + return "1" + elif next_step == "6" : + self.update_cathegory() + return "1" + elif next_step != "0" and next_step != "9": + print("Выбрано неверное число! Повторите ввод!") + next_step = self.read_next_step() + else: + return next_step + + def insert_cathegory(self): + data = [] + data.append(input("Введите имя категории(1 - отмена): ").strip()) + while len(data[0].strip()) == 0 or len(data[0].strip())>20: + data[0] = input("Неверная длина! Имя должно быть не пустым и не больше 20 символов. Введите имя заново (1 - отмена):").strip() + if data[0] == "1": + return + + CathegoryTable().insert_one(data) + + def del_cathegory(self): + while True: + cathegory_id = input("Введите № категории для удаления: ").strip() + try: + cathegory_id = int(cathegory_id) + except ValueError: + print("Неверный тип. Ожидается число") + # return + if (cathegory_id <= 0)or(cathegory_id > self.max_cath_index): + print(f'Число должно лежать в диапазоне от 1 до {self.max_cath_index}.') + elif not (CathegoryTable().exist_by_number(cathegory_id)): + print("Указанный номер категории не найдем. Попробуйте заново") + # return + else: + break + DishTable().delete_all_with_cathegory_id(cathegory_id) + CathegoryTable().delete_one(cathegory_id) + return + + def update_cathegory(self): + data = [] + cathegory_id = input("Введите № категории для изменения: ").strip() + try: + cathegory_id = int(cathegory_id) + except ValueError: + print("Неверный тип. Ожидается число") + return + if not (CathegoryTable().exist_by_number(cathegory_id)): + print("Указанный номер категории не найдем. Попробуйте заново") + return + + data.append(input("Введите имя категории(1 - отмена): ").strip()) + while len(data[0].strip()) == 0 or len(data[0].strip()) > 20: + data[0] = input("Неверная длина! Имя должно быть не пустым и не больше 20 символов. Введите имя заново (1 - отмена):").strip() + if data[0] == "1": + return + CathegoryTable().update(cathegory_id, data) + + def main_cycle(self): + current_menu = "0" + next_step = None + while (current_menu != "9"): + if current_menu == "0": + self.show_main_menu() + next_step = self.read_next_step() + current_menu = self.after_main_menu(next_step) + elif current_menu == "1": + self.show_cathegory() + next_step = self.read_next_step() + current_menu = self.after_show_cathegory(next_step) + elif current_menu == "3": + self.show_dish() + next_step = self.read_next_step() + current_menu = self.after_show_dish(next_step) + print("До свидания!") + return + + def test(self): + DbTable.dbconn.test() + + +m = Main() +# Откоментируйте эту строку и закоментируйте следующую для теста +# соединения с БД +# m.test() +m.main_cycle() diff --git a/other/Right/project_config.py b/other/Right/project_config.py new file mode 100644 index 0000000..2b451e5 --- /dev/null +++ b/other/Right/project_config.py @@ -0,0 +1,21 @@ +# Загрузка настроек проекта (в данном случае только настроек соединения с БД) +# из файла config.yaml. +import yaml + +class ProjectConfig: + """Класс считывает базовые настройки из файла config.yaml""" + + def __init__(self): + with open('config.yaml') as f: + config = yaml.safe_load(f) + self.dbname = config['dbname'] + self.user = config['user'] + self.password = config['password'] + self.host = config['host'] + self.dbtableprefix = config['dbtableprefix'] + +# Этот метод запускается только, если запускать +# данный файл, а не подключать его. +if __name__ == "__main__": + x = ProjectConfig() + print(x.dbfilepath) diff --git a/project/Lib/site-packages/psycopg2/__pycache__/_ipaddress.cpython-311.pyc b/project/Lib/site-packages/psycopg2/__pycache__/_ipaddress.cpython-311.pyc index ca8f30e..f6b6ea8 100644 Binary files a/project/Lib/site-packages/psycopg2/__pycache__/_ipaddress.cpython-311.pyc and b/project/Lib/site-packages/psycopg2/__pycache__/_ipaddress.cpython-311.pyc differ diff --git a/project/Lib/site-packages/psycopg2/__pycache__/extras.cpython-311.pyc b/project/Lib/site-packages/psycopg2/__pycache__/extras.cpython-311.pyc index f6ebf25..5f8a053 100644 Binary files a/project/Lib/site-packages/psycopg2/__pycache__/extras.cpython-311.pyc and b/project/Lib/site-packages/psycopg2/__pycache__/extras.cpython-311.pyc differ