Archived
stable version
This commit is contained in:
@@ -20,3 +20,5 @@ main_yaml_groups/*
|
||||
Новая таблица - 2 курс весна 2025 copy.csv
|
||||
Новая таблица - 2 курс весна 2025.csv
|
||||
schedule copy.sql
|
||||
tmp/
|
||||
credentials.json
|
||||
Binary file not shown.
Binary file not shown.
@@ -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<b>{}</b>\
|
||||
\n<i>{}</i>".format(
|
||||
start,
|
||||
end,
|
||||
lesson["room"],
|
||||
lesson["course"],
|
||||
lesson["lector"],
|
||||
)
|
||||
if lesson["lector"]:
|
||||
if "/" not in lesson["lector"]:
|
||||
text = "{}-{} | {}\
|
||||
\n<b>{}</b>\
|
||||
\n<i>{}</i>".format(
|
||||
start,
|
||||
end,
|
||||
lesson["room"],
|
||||
lesson["course"],
|
||||
lesson["lector"],
|
||||
)
|
||||
else:
|
||||
lectors = lesson["lector"].split("/")
|
||||
text = "{}-{} | {}\
|
||||
\n<b>{}</b>\
|
||||
\n<i>{}</i> / <i>{}</i>".format(
|
||||
start,
|
||||
end,
|
||||
lesson["room"].replace("/", ", "),
|
||||
lesson["course"],
|
||||
lectors[0],
|
||||
lectors[1],
|
||||
)
|
||||
else:
|
||||
text = "{}-{}\
|
||||
\n<b>{}</b>".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"Такой группы нет в базе. Проверь в <a href='https://docs.google.com/spreadsheets/d/{os.environ.get('TABLE_ID')}/edit?usp=sharing'>таблице</a> существование расписания для твоей группы"
|
||||
|
||||
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)
|
||||
|
||||
+3
-2
@@ -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
|
||||
done
|
||||
|
||||
|
||||
+20
-12
@@ -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<a href='https://docs.google.com/spreadsheets/d/{os.environ.get('TABLE_ID')}/edit?usp=sharing'>Расписание</a>"
|
||||
|
||||
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Проверьте расписание своей группы в <a href='https://docs.google.com/spreadsheets/d/{os.environ.get('TABLE_ID')}/edit?usp=sharing'>этой таблице</a>",
|
||||
)
|
||||
|
||||
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"Пожалуйста, проверь расписание для своей группы в <a href='https://docs.google.com/spreadsheets/d/{os.environ.get('TABLE_ID')}/edit?usp=sharing'>этой таблице</a>",
|
||||
# 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
|
||||
|
||||
@@ -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()
|
||||
|
||||
+5
-5
@@ -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)
|
||||
);
|
||||
+6
-1
@@ -1,6 +1,11 @@
|
||||
pytelegrambotapi
|
||||
python-telegram-bot
|
||||
coloredlogs
|
||||
psycopg2-binary
|
||||
sshtunnel
|
||||
python-dotenv
|
||||
schedule
|
||||
schedule
|
||||
google-api-python-client
|
||||
oauth2client
|
||||
gspread
|
||||
pandas
|
||||
-104
@@ -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 '),
|
||||
Reference in New Issue
Block a user