Merge pull request #1 from ada-dmitry/output_of_pages

Output of pages
This commit is contained in:
Dmitry
2024-05-23 17:55:26 +03:00
committed by GitHub
52 changed files with 1896 additions and 401 deletions
Binary file not shown.
Binary file not shown.
+58 -20
View File
@@ -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Введите время приготовления сначала в часах, потом в минутах')
Args:
input_str (str): входная строка для проверки
while True:
ins_time = validate_input(f'Введите кол-во часов [0 <= x <= 23] (-1 - для отмены): ',\
0, 23)
if(ins_time==''):
return -1
else:
time.append(ins_time)
break
Returns:
bool: Булевое значение, которое характеризует валидность вводимых строк
"""
# Регулярное выражение для проверки формата
pattern = r'^(\d+\s*hours?\s*)?(\d+\s*minutes?)$'
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
# Проверка соответствия регулярному выражению
match = re.match(pattern, input_str)
# def validate_time_format(input_str):
if match:
return True
# """
# Функция проверки подходящего формата для ввода времени в interval
# Если формат некорректный, возвращаем False
return False
# Args:
# input_str (str): входная строка для проверки
# Returns:
# bool: Булевое значение, которое характеризует валидность вводимых строк
# """
# # Регулярное выражение для проверки формата
# pattern = re.compile(r"""^(-)?(?:(?P<hour>d+):)?(?P<minute>d+):(?P<second>d+(.d+)?)$""")
# # Проверка соответствия регулярному выражению
# match = re.match(pattern, input_str)
# if match:
# return True
# # Если формат некорректный, возвращаем False
# return False
def validate_input(prompt, min_value, max_value):
"""Проверка ввода для выбора номера строки
@@ -34,12 +70,12 @@ 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}")
@@ -47,6 +83,8 @@ def validate_input(prompt, min_value, max_value):
print("Введенное значение должно быть числом.")
# test1 = 'erhwogngonwro'
# test2 = '1 minute'
# test3 = '2 hours 3 minutes'
@@ -71,6 +109,6 @@ def add_zero_before(old_index: str, max_len: str) -> str:
def cls():
# Закомментировать строку нижу, если нужно выключить очистку терминала
os.system('cls')
# Закомментировать строку ниже, если нужно выключить очистку терминала
# os.system('cls')
return
+3 -14
View File
@@ -98,22 +98,11 @@ 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):
+164 -138
View File
@@ -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,111 +96,118 @@ class Main:
else:
return next_step
def show_page_cath(self):
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)
menu = """Просмотр списка категорий!
\tНазвание\n-------------------------------------------------------------------------------------------"""
cath_page = 1
lst = CathTable().get_cath_page(cath_page)
action = '>'
max_page = math.ceil(self.max_cath_index/10)
max_page = math.ceil(self.max_cath_index/10) + ((self.max_cath_index/10)== 0)
while True:
self.cath_arr = []
for i in lst:
self.cath_arr.append(str(i[0]))
cath_arr = CathTable().get_cath_page(cath_page)
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])
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Кол-во записей на странице: 10\n\
Для переключения между страницами используйте "<" и ">"\n\
Для выхода в меню действий нажмите любую другую клавишу\n=> ')
if(action=='>'):
if(self.cath_page==max_page):
self.cath_page = 1
if(cath_page==max_page):
cath_page = 1
else:
self.cath_page += 1
lst = CathTable().get_page(self.cath_page)
cath_page += 1
lst = CathTable().get_cath_page(cath_page)
elif(action=='<'):
if(self.cath_page==1):
self.cath_page = max_page
if(cath_page==1):
cath_page = max_page
else:
self.cath_page -= 1
lst = CathTable().get_page(self.cath_page)
cath_page -= 1
lst = CathTable().get_cath_page(cath_page)
else:
break
menu = texts.show_cath_2txt
def show_cath(self):
self.cath_id = -1
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
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])
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:
print("Сначала выберите категорию")
return "1"
next_step = "5"
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:
print("Сначала выберите категорию")
return "1"
@@ -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()
+61 -35
View File
@@ -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)
@@ -65,26 +61,56 @@ class CathTable(DbTable):
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
+183 -169
View File
@@ -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,23 +38,68 @@ 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 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, val):
sql = "DELETE FROM dish"
sql += " WHERE dish_name"
sql += "=" + "'" + val + "';"
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}'"
cur = self.dbconn.conn.cursor()
@@ -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", "Веганский пад-тай", "Пад-тай с использованием растительных ингредиентов."])
# 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
+38 -5
View File
@@ -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}"
import os
# # print(a)
# # import psycopg2
# # from psycopg2.extras import Interval
print('До очистки')
# Для Windows
os.system('cls')
# # def check_interval(value):
# # try:
# # # Попытка преобразования значения в объект Interval
# # interval_obj = Interval(value)
# # # Если преобразование успешно, значение относится к типу Interval
# # return isinstance(interval_obj, Interval)
# # except (ValueError, TypeError):
# # # Если преобразование не удалось, значение не относится к типу Interval
# # return False
print('после очистки')
# # user_input = input("Введите интервал: ")
# # if check_interval(user_input):
# # print("Введенное значение относится к типу Interval")
# # else:
# # print("Введенное значение не относится к типу Interval")
# import psycopg2
# from psycopg2.extras import DateTimeTZRange
# 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
import this
+11
View File
@@ -0,0 +1,11 @@
{
"folders": [
{
"path": "."
},
{
"path": "../sun_project"
}
],
"settings": {}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+53
View File
@@ -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))
+6
View File
@@ -0,0 +1,6 @@
# Базовые параметры настройки конфигурации проекта
dbname: Test # В классе менять не надо
user: postgres # Замените на свой логин от БД в классе
password: Qwerty # Замените на свой пароль от БД в классе
host: localhost # Замените на 192.168.0.48 в классе
dbtableprefix: "public." # Замените на свой логин от БД
+34
View File
@@ -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)
+124
View File
@@ -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
+228
View File
@@ -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()
+21
View File
@@ -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)
+90
View File
@@ -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
+202
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
print(len("\t"))
+3
View File
@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
</module>
@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9" project-jdk-type="Python SDK" />
</project>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Right.iml" filepath="$PROJECT_DIR$/.idea/Right.iml" />
</modules>
</component>
</project>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+45
View File
@@ -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()
+6
View File
@@ -0,0 +1,6 @@
# Базовые параметры настройки конфигурации проекта
dbname: Test # В классе менять не надо
user: postgres # Замените на свой логин от БД в классе
password: Qwerty # Замените на свой пароль от БД в классе
host: localhost # Замените на 192.168.0.48 в классе
dbtableprefix: "public." # Замените на свой логин от БД
+34
View File
@@ -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)
+103
View File
@@ -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()
+53
View File
@@ -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()
+304
View File
@@ -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()
+21
View File
@@ -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)