mirror of
https://github.com/ada-dmitry/lab6.git
synced 2026-09-24 01:10:15 +00:00
add nekit project
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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))
|
||||
@@ -0,0 +1,6 @@
|
||||
# Базовые параметры настройки конфигурации проекта
|
||||
dbname: Test # В классе менять не надо
|
||||
user: postgres # Замените на свой логин от БД в классе
|
||||
password: Qwerty # Замените на свой пароль от БД в классе
|
||||
host: localhost # Замените на 192.168.0.48 в классе
|
||||
dbtableprefix: "public." # Замените на свой логин от БД
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
Binary file not shown.
Binary file not shown.
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
print(len("\t"))
|
||||
@@ -0,0 +1,29 @@
|
||||
show_main_menu_txt = """Привутствуем в меню, выберите действие:
|
||||
1 - просмотр категорий;
|
||||
2 - сброс и инициализация БД;
|
||||
9 - выход;"""
|
||||
show_cath_1txt = """Просмотр списка категорий!
|
||||
№\tНазвание\n-------------------------------------------------------------------------------------------"""
|
||||
|
||||
show_cath_2txt = """-------------------------------------------------------------------------------------------\nДальнейшие операции:
|
||||
0 - возврат в главное меню;
|
||||
3 - добавление новой категории;
|
||||
4 - удаление категории;
|
||||
5 - просмотр блюд в категории;
|
||||
8 - обновить категорию;
|
||||
9 - выход."""
|
||||
|
||||
show_dish_in_cath_txt = """-------------------------------------------------------------------------------------------\nДальнейшие операции:
|
||||
0 - возврат в главное меню;
|
||||
1 - возврат в просмотр категорий;
|
||||
6 - добавление нового блюда;
|
||||
7 - удаление блюда;
|
||||
88 - для обновления блюда;
|
||||
9 - выход."""
|
||||
|
||||
text_choice_update = """-------------------------------------------------------------------------------------------\n
|
||||
Что вы хотите обновить?
|
||||
1 - Категорию
|
||||
2 - Блюдо
|
||||
Введите необходимую цифру для выбора:
|
||||
"""
|
||||
Generated
+3
@@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
Generated
+12
@@ -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>
|
||||
Generated
+4
@@ -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>
|
||||
Generated
+8
@@ -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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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()
|
||||
@@ -0,0 +1,6 @@
|
||||
# Базовые параметры настройки конфигурации проекта
|
||||
dbname: Test # В классе менять не надо
|
||||
user: postgres # Замените на свой логин от БД в классе
|
||||
password: Qwerty # Замените на свой пароль от БД в классе
|
||||
host: localhost # Замените на 192.168.0.48 в классе
|
||||
dbtableprefix: "public." # Замените на свой логин от БД
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user