diff --git a/.gitignore b/.gitignore
index 57f7cd3..5de7aa3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,5 @@ main_yaml_groups/*
Новая таблица - 2 курс весна 2025 copy.csv
Новая таблица - 2 курс весна 2025.csv
schedule copy.sql
+tmp/
+credentials.json
\ No newline at end of file
diff --git a/1_kurs_vesna_2025_0.pdf b/1_kurs_vesna_2025_0.pdf
deleted file mode 100644
index 82fc568..0000000
Binary files a/1_kurs_vesna_2025_0.pdf and /dev/null differ
diff --git a/2_kurs_vesna_2025_0.pdf b/2_kurs_vesna_2025_0.pdf
deleted file mode 100644
index 6890f6a..0000000
Binary files a/2_kurs_vesna_2025_0.pdf and /dev/null differ
diff --git a/app/db.py b/app/db.py
index 8f7d130..6bf992f 100644
--- a/app/db.py
+++ b/app/db.py
@@ -55,10 +55,18 @@ def into_list(rows: list[tuple], column_name: list[tuple]) -> list[dict]:
def save_user(infos):
+ # infos = [
+ # call.from_user.id,
+ # call.from_user.first_name,
+ # call.from_user.last_name,
+ # call.from_user.username,
+ # call.data,
+ # ]
+
conn = db.getconn()
cursor = conn.cursor()
cursor.execute(
- "INSERT INTO users (id, username, first_name, last_name, group) VALUES (%s, %s, %s, %s, %s)",
+ 'INSERT INTO users (id, first_name, last_name, username, "group") VALUES (%s, %s, %s, %s, %s) ON CONFLICT (id) DO UPDATE SET first_name = EXCLUDED.first_name, last_name = EXCLUDED.last_name, username = EXCLUDED.username, "group" = EXCLUDED."group"',
infos,
)
@@ -96,15 +104,36 @@ def parse_lesson(lesson: dict[str, str]) -> str:
if lesson["parity"] == 1:
lesson["course"] += " (нечёт.)"
- text = "{}-{} | {}\
- \n{}\
- \n{}".format(
- start,
- end,
- lesson["room"],
- lesson["course"],
- lesson["lector"],
- )
+ if lesson["lector"]:
+ if "/" not in lesson["lector"]:
+ text = "{}-{} | {}\
+ \n{}\
+ \n{}".format(
+ start,
+ end,
+ lesson["room"],
+ lesson["course"],
+ lesson["lector"],
+ )
+ else:
+ lectors = lesson["lector"].split("/")
+ text = "{}-{} | {}\
+ \n{}\
+ \n{} / {}".format(
+ start,
+ end,
+ lesson["room"].replace("/", ", "),
+ lesson["course"],
+ lectors[0],
+ lectors[1],
+ )
+ else:
+ text = "{}-{}\
+ \n{}".format(
+ start,
+ end,
+ lesson["course"],
+ )
return text
@@ -132,8 +161,10 @@ def create_schedule_tasks(manual=False):
if group == "other":
continue
- cursor.execute("SELECT * FROM schedule WHERE group = %s", (group,))
+ cursor.execute('SELECT * FROM schedule WHERE "group" = %s', (group,))
data = cursor.fetchall()
+ if not data:
+ continue
schdl = into_list(data, cursor.description)
for lesson in schdl:
@@ -191,7 +222,7 @@ def create_schedule_tasks(manual=False):
def groups_in_json() -> list[str]:
conn = db.getconn()
cursor = conn.cursor()
- cursor.execute("SELECT DISTINCT group FROM schedule ORDER BY group")
+ cursor.execute('SELECT DISTINCT "group" FROM schedule ORDER BY "group"')
data = cursor.fetchall()
groups = [row[0] for row in data]
db.putconn(conn)
@@ -204,7 +235,7 @@ def students_in_group(group) -> list[str]:
conn = db.getconn()
cursor = conn.cursor()
- cursor.execute("SELECT * FROM users WHERE group = %s", (group,))
+ cursor.execute('SELECT * FROM users WHERE "group" = %s', (group,))
data = cursor.fetchall()
students = [row[0] for row in data]
db.putconn(conn)
@@ -251,7 +282,7 @@ def get_schedule(id: str, day: str) -> str:
conn = db.getconn()
cursor = conn.cursor()
- cursor.execute("SELECT group FROM users WHERE id = %s", (id,))
+ cursor.execute('SELECT "group" FROM users WHERE id = %s', (id,))
data = cursor.fetchone()
group = data[0]
db.putconn(conn)
@@ -259,9 +290,12 @@ def get_schedule(id: str, day: str) -> str:
if group == "other":
return "У тебя не выбрана группа для рассылки сообщений"
+ if group not in groups_in_json():
+ return f"Такой группы нет в базе. Проверь в таблице существование расписания для твоей группы"
+
conn = db.getconn()
cursor = conn.cursor()
- cursor.execute("SELECT * FROM schedule WHERE group = %s", (group,))
+ cursor.execute('SELECT * FROM schedule WHERE "group" = %s', (group,))
data = cursor.fetchall()
schdl = into_list(data, cursor.description)
db.putconn(conn)
diff --git a/app/install.sh b/app/install.sh
index 397ab76..846c9ad 100644
--- a/app/install.sh
+++ b/app/install.sh
@@ -1,7 +1,7 @@
#!/bin/bash
# List of environment variables to check
-env_vars=("TG_ADMIN_ID" "TG_API_TOKEN" "DB_HOST" "DB_PORT" "DB_USER" "DB_PASSWORD" "DB_NAME")
+env_vars=("TG_ADMIN_ID" "TG_API_TOKEN" "DB_HOST" "DB_PORT" "DB_USER" "DB_PASSWORD" "DB_NAME" "TABLE_ID")
for var in "${env_vars[@]}"; do
if [ -z "${!var}" ]; then
@@ -10,4 +10,5 @@ for var in "${env_vars[@]}"; do
# else
# echo "Environment variable $var is set to '${!var}'."
fi
-done
\ No newline at end of file
+done
+
diff --git a/app/schedules.py b/app/schedules.py
index 7b12365..ffec3e0 100644
--- a/app/schedules.py
+++ b/app/schedules.py
@@ -10,7 +10,7 @@ from dotenv import load_dotenv
load_dotenv()
-bot = telebot.TeleBot(os.environ.get("TG_TEST_TOKEN"))
+bot = telebot.TeleBot(os.environ.get("TG_TEST_TOKEN"), parse_mode=ParseMode.HTML)
PARITY_FIRST = 0
@@ -31,6 +31,11 @@ def help(message):
send_message(message.chat.id, help_msg)
+ help_msg2 = f"Бот берёт расписание из таблицы, которую можно посмотреть по ссылке:\
+ \nРасписание"
+
+ send_message(message.chat.id, help_msg2)
+
if is_admin(message):
admin_help_msg = "И команды только для админа:\
\n/restart - перезапуск бота.\
@@ -262,16 +267,16 @@ def start(message):
else:
send_message(
message.chat.id,
- "Похоже, что расписания для этой группы ещё не существует. \
- \nРазработчик уже пинается, но можете дополнительно написать ему: @Kr0sH_512",
+ f"Похоже, что расписания для этой группы ещё не существует. \
+ \nПроверьте расписание своей группы в этой таблице",
)
- send_admin_message(
- "В группе {} был запрос на {} группу.\
- \nid: {}".format(
- message.chat.title, temp, message.chat.id
- )
- )
+ # send_admin_message(
+ # "В группе {} был запрос на {} группу.\
+ # \nid: {}".format(
+ # message.chat.title, temp, message.chat.id
+ # )
+ # )
temp = "other"
db.save_user(infos)
else:
@@ -290,6 +295,8 @@ def start(message):
# markup.add(types.InlineKeyboardButton(text=i, callback_data=i))
markup.add(types.InlineKeyboardButton(text="1 курс", callback_data="1course"))
markup.add(types.InlineKeyboardButton(text="2 курс", callback_data="2course"))
+ markup.add(types.InlineKeyboardButton(text="3 курс", callback_data="2course"))
+ markup.add(types.InlineKeyboardButton(text="4 курс", callback_data="2course"))
bot.send_message(
message.chat.id,
@@ -346,8 +353,9 @@ def callback_inline(call):
bot.edit_message_text(
chat_id=call.message.chat.id,
message_id=call.message.message_id,
- text="Используй команду /request и напиши номер группы, которую хочешь добавить\
- \nПосле создания расписания для твоей группы, я пришлю тебе сообщение",
+ text=f"Пожалуйста, проверь расписание для своей группы в этой таблице",
+ # text="Используй команду /request и напиши номер группы, которую хочешь добавить\
+ # \nПосле создания расписания для твоей группы, я пришлю тебе сообщение",
parse_mode=ParseMode.HTML,
)
else:
@@ -605,7 +613,7 @@ def send_message(id, text, thread_id="General", parity=None):
if thread_id == "General":
thread_id = None
- if parity != None:
+ if parity and parity != "-":
parity = int(parity)
count_of_weeks = (datetime.now() - datetime(2024, 2, 5)).days // 7
is_odd = (count_of_weeks + 1) % 2 == PARITY_FIRST
diff --git a/app/upload_sql.py b/app/upload_sql.py
index e69de29..8da1562 100644
--- a/app/upload_sql.py
+++ b/app/upload_sql.py
@@ -0,0 +1,164 @@
+#!/usr/bin/python3.3
+import gspread, os, telebot
+import pandas as pd
+from dotenv import load_dotenv
+from google.oauth2 import service_account
+from sshtunnel import SSHTunnelForwarder
+from psycopg2 import pool
+
+load_dotenv()
+
+
+"""
+CREATE TABLE IF NOT EXISTS schedule(
+ id BIGSERIAL PRIMARY KEY,
+ day_of_week VARCHAR(255),
+ begin_time VARCHAR(20),
+ end_time VARCHAR(20),
+ course VARCHAR(255),
+ lector VARCHAR(255),
+ is_lecture BOOLEAN DEFAULT FALSE,
+ room VARCHAR(20),
+ group VARCHAR(10),
+ parity VARCHAR(10),
+);
+"""
+
+"""
+День недели Время начала Название Чётность пары Лекция? Преподаватель Кабинет 2-ой преподаватель Прочие кабинеты Остальная информация
+Понедельник 8:45 Английский язык - FALSE Бим Мария Моисеевна 735 Шубина Юлия Витальевна 790
+Понедельник 10:30 Практикум на ЭВМ - FALSE Тюляева Вера Викторовна МЗ-4
+Понедельник 12:15 Действительный и комплексный анализ - TRUE Крицков Леонид Владимирович П-12
+Понедельник 15:00 Физическая культура - FALSE
+Понедельник 16:20 FALSE
+Вторник 8:45 Теория вероятностей и математическая статистика - TRUE Королёв Виктор Юрьевич П-13
+Вторник 10:30 Обыкновенные дифференциальные уравнения - FALSE Дмитриева Ирина Владимировна 607
+Вторник 12:15 Действительный и комплексный анализ - FALSE Сычугов Дмитрий Юрьевич 613
+Вторник 14:35 Электродинамика - FALSE Аксенов Владимир Николаевич 659
+Вторник 16:20 - FALSE
+Среда 8:45 Практикум на ЭВМ - FALSE Тюляева Вера Викторовна 505
+Среда 10:30 Теория вероятностей и математическая статистика - FALSE Ирина Геннадьевна Шевцова 645
+Среда 12:15 Обыкновенные дифференциальные уравнения - TRUE Денисов Александр Михайлович П-13
+Среда 15:00 FALSE
+Среда 16:20 FALSE
+Четверг 9:00 FALSE
+Четверг 10:30 FALSE
+Четверг 12:15 FALSE
+Четверг 15:00 FALSE
+Четверг 16:20 FALSE
+Пятница 9:00 FALSE
+Пятница 10:30 FALSE
+Пятница 12:15 FALSE
+Пятница 15:00 FALSE
+Пятница 16:20 FALSE
+Суббота 9:00 FALSE
+Суббота 10:30 FALSE
+Суббота 12:15 FALSE
+Суббота 15:00 FALSE
+Суббота 16:20 FALSE
+ FALSE
+ FALSE
+ FALSE
+ FALSE
+ FALSE
+ FALSE
+ FALSE
+ FALSE
+ FALSE
+"""
+
+SERVICE_ACCOUNT_FILE = "app/credentials.json"
+
+credentials = service_account.Credentials.from_service_account_file(
+ SERVICE_ACCOUNT_FILE,
+ scopes=[
+ "https://www.googleapis.com/auth/drive",
+ "https://www.googleapis.com/auth/documents",
+ ],
+)
+
+gc = gspread.authorize(credentials)
+
+table = gc.open_by_key(os.environ.get("TABLE_ID"))
+
+ws = table.worksheets()
+
+bot = telebot.TeleBot(os.environ.get("TG_TEST_TOKEN"))
+
+if os.environ.get("ENV") == "dev":
+ print("DEV: Connecting to local database")
+ server = SSHTunnelForwarder(
+ (os.environ.get("SSH_HOST"), 22),
+ ssh_private_key=os.environ.get("SSH_KEY"),
+ ssh_username=os.environ.get("SSH_USER"),
+ ssh_password=(
+ os.environ.get("SSH_PASSWORD") if os.environ.get("SSH_PASSWORD") else None
+ ),
+ remote_bind_address=("localhost", int(os.environ.get("DB_PORT"))),
+ )
+ server.start()
+
+db = pool.SimpleConnectionPool(
+ 1,
+ 20,
+ user=os.environ.get("DB_USER"),
+ password=os.environ.get("DB_PASSWORD"),
+ host="localhost" if os.environ.get("ENV") == "dev" else os.environ.get("DB_HOST"),
+ port=(
+ server.local_bind_port
+ if os.environ.get("ENV") == "dev"
+ else os.environ.get("DB_PORT")
+ ),
+ database=os.environ.get("DB_NAME"),
+)
+
+
+for i in ws:
+ print(i.title)
+
+ if not (i.title == "Пример" or i.title == "main") and i.title.isdigit():
+ df = pd.DataFrame(i.get_all_records())
+ if not df.empty:
+ with db.getconn() as conn:
+ with conn.cursor() as cursor:
+ cursor.execute(
+ 'DELETE FROM schedule WHERE "group" = %s', (str(i.title),)
+ )
+ conn.commit()
+ for index, row in df.iterrows():
+ day_of_week_map = {
+ "Понедельник": "mon",
+ "Вторник": "tue",
+ "Среда": "wed",
+ "Четверг": "thu",
+ "Пятница": "fri",
+ "Суббота": "sat",
+ "Воскресенье": "sun",
+ }
+ row["День недели"] = day_of_week_map.get(
+ row["День недели"], row["День недели"]
+ )
+ if row["Название"] == "":
+ continue
+ end_time = (
+ pd.to_datetime(row["Время начала"], format="%H:%M")
+ + pd.Timedelta(hours=1, minutes=35)
+ ).strftime("%H:%M")
+ cursor.execute(
+ """
+ INSERT INTO schedule (day_of_week, begin_time, end_time, course, lector, is_lecture, room, "group", parity)
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
+ """,
+ (
+ row["День недели"],
+ row["Время начала"],
+ end_time,
+ row["Название"],
+ f'{row["Преподаватель"]}{"/" + str(row["2-ой преподаватель"]) if row["2-ой преподаватель"] else ""}',
+ row["Лекция?"],
+ f'{row["Кабинет"]}{"/" + str(row["Прочие кабинеты"]) if row["Прочие кабинеты"] else ""}',
+ i.title,
+ row["Чётность пары"],
+ ),
+ )
+ conn.commit()
diff --git a/database.sql b/database.sql
index 723e044..17a0c16 100644
--- a/database.sql
+++ b/database.sql
@@ -1,11 +1,11 @@
-CREATE DATABASE IF NOT EXISTS tg_schedule;
+CREATE DATABASE tg_schedule;
CREATE TABLE IF NOT EXISTS users (
id BIGINT PRIMARY KEY,
username VARCHAR(255),
- first_name VARCHAR(255) NOT NULL,
+ first_name VARCHAR(255),
last_name VARCHAR(255),
- group VARCHAR(255) DEFAULT 'other',
+ "group" VARCHAR(255) DEFAULT 'other',
timeout INT DEFAULT 10,
allow_message BOOLEAN DEFAULT TRUE,
thread VARCHAR(255) DEFAULT 'General',
@@ -21,6 +21,6 @@ CREATE TABLE IF NOT EXISTS schedule(
lector VARCHAR(255),
is_lecture BOOLEAN DEFAULT FALSE,
room VARCHAR(20),
- group VARCHAR(10),
- parity VARCHAR(10),
+ "group" VARCHAR(10),
+ parity VARCHAR(10)
);
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index f688902..e2e308b 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,11 @@
pytelegrambotapi
+python-telegram-bot
coloredlogs
psycopg2-binary
sshtunnel
python-dotenv
-schedule
\ No newline at end of file
+schedule
+google-api-python-client
+oauth2client
+gspread
+pandas
\ No newline at end of file
diff --git a/schedule.sql b/schedule.sql
deleted file mode 100644
index cc15518..0000000
--- a/schedule.sql
+++ /dev/null
@@ -1,104 +0,0 @@
-CREATE TABLE IF NOT EXISTS schedule(
- id BIGSERIAL PRIMARY KEY,
- day_of_week VARCHAR(255),
- begin_time VARCHAR(20),
- end_time VARCHAR(20),
- course VARCHAR(255),
- lector VARCHAR(255),
- is_lecture BOOLEAN DEFAULT FALSE,
- room VARCHAR(20),
- group VARCHAR(10),
- parity INT,
-);
-
--- ('mon', '101', '08:45', '10:20', '', '', ''),
--- ('mon', '101', '10:30', '12:05', '', '', ''),
--- ('mon', '101', '12:50', '14:25', '', '', ''),
--- ('mon', '101', '14:35', '16:10', '', '', ''),
--- ('mon', '101', '16:50', '18:20', '', '', ''),
-
-INSERT INTO schedule(day_of_week, group, begin_time, end_time, course, lector, room) VALUES
-('mon', '101', '10:30', '12:05', 'Практикум на ЭВМ', 'Кузьменкова Е.А.', '731'),
-('mon', '101', '10:30', '12:05', 'Практикум на ЭВМ', 'Малышев Н.Е.', '778'),
-('mon', '101', '12:50', '14:25', 'Английский язык', 'Бим М.М.', '735'),
-('mon', '101', '12:50', '14:25', 'Английский язык', 'Шубина Ю.В.', '790'),
-('mon', '101', '14:35', '16:10', 'Русский язык и культура речи', 'Рождественская Ольга Юрьевна', 'П-6'),
-('mon', '102', '14:35', '16:10', 'Русский язык и культура речи', 'Рождественская Ольга Юрьевна', 'П-6'),
-('mon', '103', '14:35', '16:10', 'Русский язык и культура речи', 'Рождественская Ольга Юрьевна', 'П-6'),
-('mon', '104', '14:35', '16:10', 'Русский язык и культура речи', 'Рождественская Ольга Юрьевна', 'П-6'),
-('mon', '105', '14:35', '16:10', 'Русский язык и культура речи', 'Рождественская Ольга Юрьевна', 'П-6'),
-('mon', '106', '14:35', '16:10', 'Русский язык и культура речи', 'Рождественская Ольга Юрьевна', 'П-6'),
-('mon', '107', '14:35', '16:10', 'Русский язык и культура речи', 'Рождественская Ольга Юрьевна', 'П-6'),
-('mon', '101', '16:50', '18:20', 'Физическая культура', '', ''),
-('mon', '102', '16:50', '18:20', 'Физическая культура', '', ''),
-('mon', '103', '16:50', '18:20', 'Физическая культура', '', ''),
-('mon', '104', '16:50', '18:20', 'Физическая культура', '', ''),
-('mon', '105', '16:50', '18:20', 'Физическая культура', '', ''),
-('mon', '106', '16:50', '18:20', 'Физическая культура', '', ''),
-('mon', '107', '16:50', '18:20', 'Физическая культура', '', ''),
-
-('mon', '102', '10:30', '12:05', 'Английский язык', 'Бим М.М.', '735'),
-('mon', '102', '10:30', '12:05', 'Английский язык', 'Шубина Ю.В.', '790'),
-('mon', '102', '12:50', '14:25', 'Математический анализ', 'Лапонин В.С.', '682'),
-
-('mon', '103', '08:45', '10:20', 'Английский язык', 'Лаптинова А.И.', '73'),
-('mon', '103', '08:45', '10:20', 'Английский язык', 'Каришева П.В.', '72'),
-('mon', '103', '10:30', '12:05', 'Математический анализ', 'Зайцева Н.В.', '71'),
-('mon', '103', '12:50', '14:25', 'Практикум на ЭВМ', 'Кузьменкова Е.А.', '731'),
-('mon', '103', '12:50', '14:25', 'Практикум на ЭВМ', 'Малышев Н.Е.', '778'),
-
-('mon', '104', '10:30', '12:05', 'Математический анализ', 'Лапонин В.С.', '682'),
-('mon', '104', '12:50', '14:25', 'Английский язык', 'Каришева П.В.', '72'),
-
-('mon', '105', '10:30', '12:05', 'Математический анализ', 'Никитин А.А.', '72'),
-('mon', '105', '12:50', '14:25', 'Алгебра и геометрия', 'Лебедева О.С.', '503'),
-
-('mon', '106', '10:30', '12:05', 'Практикум на ЭВМ', 'Корухова Л.С.', '779'),
-('mon', '106', '10:30', '12:05', 'Практикум на ЭВМ', 'Соловьев М.А.', '780'),
-('mon', '106', '12:15', '13:50', 'Алгебра и геометрия', 'Есикова Н.Б.', '504'),
-
-('mon', '107', '08:45', '10:20', 'Математический анализ', 'Зайцева Н.В.', '71'),
-('mon', '107', '10:30', '12:05', 'Алгебра и геометрия', 'Есикова Н.Б.', '504'),
-('mon', '107', '12:50', '14:25', 'Практикум на ЭВМ', 'Журихин Д.М.', 'МЗ-3'),
-('mon', '107', '12:50', '14:25', 'Практикум на ЭВМ', 'Гуляев Д.А.', 'МЗ-2'),
-
-
-
-
-
-
-
-
-
-('tue', '101', '8:45', '10:20', 'Алгебра и геометрия', 'Матвеев С.А.', '713'),
-('tue', '101', '10:30', '12:05', 'Алгебра и геометрия', 'академик РАН Тыртышников Евгений Евгеньевич', 'П-6'),
-('tue', '101', '12:50', '14:25', 'Математический анализ', 'профессор Садовничая Инна Викторовна', 'П-6'),
-('tue', '101', '14:35', '16:10', 'Математический анализ', 'Хорошилова Е.В.', '605'),
-('tue', '101', '16:20', '17:55', 'Английский язык', 'Бим М.М.', '790'),
-
-('tue', '102', '8:45', '10:20', 'Английский язык', 'Шубина Ю.В.', '72'),
-('tue', '102', '10:30', '12:05', 'Алгебра и геометрия', 'академик РАН Тыртышников Евгений Евгеньевич', 'П-6'),
-('tue', '102', '12:50', '14:25', 'Математический анализ', 'профессор Садовничая Инна Викторовна', 'П-6'),
-('tue', '102', '14:35', '16:10', 'Алгебра и геометрия', 'Руднев С.Г.', '607'),
-('tue', '102', '16:20', '17:55', 'Практикум на ЭВМ', 'Цыбров Е.Г.', 'МЗ-1'),
-('tue', '102', '16:20', '17:55', 'Практикум на ЭВМ', 'Гуляев Д.А.', 'МЗ-1'),
-
-('tue', '103', '8:45', '10:20', 'Конс. Алгебра и геометрия', 'Будак А.Б.', '612'),
-('tue', '103', '10:30', '12:05', 'Алгебра и геометрия', 'академик РАН Тыртышников Евгений Евгеньевич', 'П-6'),
-('tue', '103', '12:50', '14:25', 'Математический анализ', 'профессор Садовничая Инна Викторовна', 'П-6'),
-('tue', '103', '14:35', '16:10', 'Алгебра и геометрия', 'Будак А.Б.', '613'),
-('tue', '103', '16:20', '17:55', 'Английский язык', 'Лаптинова А.И.', '72'),
-('tue', '103', '16:20', '17:55', 'Английский язык', 'Каришева П.В.', '582-а'),
-
-('tue', '104', '8:45', '10:20', 'Конс. Алгебра и геометрия', 'Будак А.Б.', '612'),
-('tue', '104', '10:30', '12:05', 'Алгебра и геометрия', 'академик РАН Тыртышников Евгений Евгеньевич', 'П-6'),
-('tue', '104', '12:50', '14:25', 'Математический анализ', 'профессор Садовничая Инна Викторовна', 'П-6'),
-('tue', '104', '14:35', '16:10', 'Практикум на ЭВМ', 'Цыбров Е.Г.', 'МЗ-1'),
-('tue', '104', '14:35', '16:10', 'Практикум на ЭВМ', 'Гуляев Д.А.', 'МЗ-1'),
-('tue', '104', '16:20', '17:55', 'Алгебра и геометрия', 'Будак А.Б.', '613'),
-
-('tue', '105', '8:45', '10:20', 'Алгебра и геометрия', 'Лебедева О.С.', '503'),
-('tue', '105', '10:30', '12:05', 'Алгебра и геометрия', 'академик РАН Тыртышников Евгений Евгеньевич', 'П-6'),
-('tue', '105', '12:50', '14:25', 'Математический анализ', 'профессор Садовничая Инна Викторовна', 'П-6'),
-('tue', '104', '14:35', '16:10', 'Практикум на ЭВМ', 'Русол А.В.', '574 '),
-('tue', '104', '14:35', '16:10', 'Практикум на ЭВМ', 'Гуляев А.В.', '574 '),