fixes 3 pairs подряд, etc

This commit is contained in:
2025-09-12 20:07:04 +03:00
parent 6920d24a98
commit ed65e5b483
8 changed files with 239 additions and 78 deletions

100
parser.py
View File

@@ -1,7 +1,11 @@
# Copyright Stanislav Mironov
PAIR_NUMS = [
"1-2", "3-4", "5-6", "7-8", "9-10", "11-12", "13-14", "15-16"
]
import json
import xlrd
import uuid
import aigenerated
from coord import Coord, Merged
from translations import ExcelSheetReader
@@ -13,13 +17,13 @@ def pprint(*args, **kwargs):
if LOGGING:
print(*args, **kwargs)
class Parser:
def __init__(self, reader: ExcelSheetReader):
self.reader = reader
self.groups = {}
self.teachers = set()
self.places = set()
self.parser_error = None
pprint("Parser created for '{0}'".format(reader.info()))
def parse(self):
@@ -27,6 +31,7 @@ class Parser:
if monday is None:
print(" -- Failed parse! -- ")
print("ПОНЕДЕЛЬНИК НЕ НАЙДЕН!")
self.parser_error = "'ПОНЕДЕЛЬНИК' не найден в таблице."
return
head_rx = monday.row - 1 # выше первого понидельника
@@ -59,7 +64,7 @@ class Parser:
# location
location = merged.high.shift(down=1).cell(self.reader).value
return {"loc": str(location), "leader": str(speaker), "name": str(merged.cell(self.reader).value)}
return {"loc": str(location).strip(), "leader": str(speaker).strip(), "name": str(merged.cell(self.reader).value).strip()}
def process_group(self, group, monday):
"""
@@ -71,13 +76,13 @@ class Parser:
pprint(group_name)
row = group['position'][0] + 1 # counter for while, +1 for shift down; также номер строки в таблице (вроде с нуля)
weeknum = 1 # номер недели, щёлкнет +1 при каком-то условии.
previous_pair = None
while row < self.reader.get_row_count(): # maybe условие чтобы не уйти ниже чем есть строк
pos = Coord(row, group['position'][1]) # текущая позиция, верхний левый угол (=low)
pos_right = pos.shift(right=3)
pair_pos = pos.replace(col=5)
weekday_pos = pos.replace(col=4)
merged = self.reader.get_merged_coord(pos)
right_cell = pos_right.cell(self.reader)
merged_cell = merged.cell(self.reader)
cv = merged_cell.value
# В конце (12 пара:>) название группы, можно использовать как якорь
@@ -89,6 +94,16 @@ class Parser:
weekday = utils.unspace(weekday_mr.cell(self.reader).value)
pair_mr = self.reader.get_merged_coord(pair_pos)
pair = utils.unspace(pair_mr.cell(self.reader).value)
fuck_empty_pair_in_excel = pair == ""
previous_dump = previous_pair
if fuck_empty_pair_in_excel:
if previous_pair is None or previous_pair == "":
pair = f"EMPTY_IN_EXCEL_{uuid.uuid4()}"
else:
pair = utils.next_element(PAIR_NUMS, previous_pair)
if pair != "":
previous_pair = pair
skip = 0
if weekday == "":
@@ -99,26 +114,25 @@ class Parser:
row += 1
else:
break
if not skip:
next = 3 # на сколько пыгнуть для следующего шага?
is_empty_lesson = right_cell.is_empty() and merged_cell.is_empty()
dispname = ""
is_empty_lesson = len(utils.parse_all_dirt(self.reader, pos, 4, 3)) == 0 # если в поле не найдено ничего..
parsed_discipline_name = None
parsed_location = None
parsed_leader = None
is_2pair = False
pairs = 1
is_solid = pos_right in merged
parsed_uncotigorized = []
is_wide_maybe_potokoviy = merged.width() > 4 # потоковая ли лекция (занимает несколько групп.)
if is_empty_lesson:
dispname = "<no lesson>"
if not is_empty_lesson:
may_prepod = merged.low.shift(down=2)
if utils.has_no_bottom_border(self.reader, may_prepod):
next = 6
is_2pair = True
cur = merged.low.shift(down=2)
while utils.has_no_bottom_border(self.reader, cur):
next += 3
pairs += 1
cur = cur.shift(down=3)
if is_wide_maybe_potokoviy:
ret = self.parse_potokoviy(merged)
@@ -127,45 +141,37 @@ class Parser:
parsed_discipline_name = ret['name']
parsed_uncotigorized = list(utils.parse_all_dirt(self.reader, merged.low, merged.width(), next))
else:
if (is_solid):
parsed_discipline_name = cv
dispname = cv
dispname += (" SOLD" if is_solid else " SPLIT")
dispname += (" [ДВУПАРНЫЙ]" if is_2pair else "")
parsed_uncotigorized = list(utils.parse_all_dirt(self.reader, merged.low, 4, next))
if parsed_leader: dispname += f" [{parsed_leader}]"
if parsed_location: dispname += f" [{parsed_location}]"
dispname = dispname.replace("\n", "\\n")
pprint(f"[{group_name}] row={row}; {pos} {pos_right} {pair} {weekday}: {'[ПОТОКОВЫЙ] ' if is_wide_maybe_potokoviy else ''}{dispname} {parsed_uncotigorized}")
# пытаемся из некотегорезированных данных выцепить место и лидера (препода)
prepods = set()
if parsed_leader is not None: prepods.add(aigenerated.extract_last_name(parsed_leader))
if parsed_leader is not None: prepods.add(parsed_leader.strip())
locations = set()
if parsed_location is not None: locations.add(parsed_location.replace(" ", "").replace("-", ""))
if parsed_location is not None: locations.add(parsed_location.strip().replace(" ", ""))
for x in list(parsed_uncotigorized):
if aigenerated.is_surname_string(x):
prepods.add(aigenerated.extract_last_name(x))
prepods.add(x.strip())
if aigenerated.is_room_number(x):
locations.add(x.replace(" ", "").replace("-", "") if x is not None else None)
locations.add(x.strip().replace(" ", "") if x is not None else None)
# оставшееся в дисциплину (костыль)
# попытка починить пустую дисциплину
if parsed_discipline_name is None:
parsed_discipline_name = " ".join(parsed_uncotigorized)
l = utils.remove_from_list(list(parsed_uncotigorized), [parsed_leader, parsed_location])
parsed_discipline_name = " ".join(l)
prepods.discard(None)
prepods.discard("")
locations.discard(None)
locations.discard("")
# чистим сеты от мусора
utils.discards_list(prepods, nones=True, emptystrings=True)
utils.discards_list(locations, nones=True, emptystrings=True)
utils.discards_list(parsed_uncotigorized, nones=True, emptystrings=True)
# если не пустой предмет то записываем его
if not is_empty_lesson:
slots = group['slots']
w = weekday + ("_1" if weeknum == 1 else "_2")
@@ -174,22 +180,30 @@ class Parser:
today = slots[w]
today[pair] = {
"pos": str(pos),
"discipline": parsed_discipline_name,
"excel_pos": str(pos),
"discipline_name": parsed_discipline_name.strip(),
"locations": list(locations),
"leads": list(prepods),
"is_solid": is_solid,
"is_2pair": is_2pair,
"time_coeff": pairs,
"is_flow": is_wide_maybe_potokoviy,
"lefttopmerged": {
"width": merged.width(),
"height": merged.height(),
"excel_range": utils.merged_humanize(merged.as_numbers())
},
"raw": parsed_uncotigorized,
"weeday": utils.weekday_to_num(weekday),
"weekday": utils.weekday_to_num(weekday),
"weeknum": weeknum
}
if fuck_empty_pair_in_excel:
today[pair]['pair_num_empty'] = {
"prev": previous_dump,
"restoted": pair != "",
"pair": pair
}
self.teachers.add(aigenerated.extract_last_name(parsed_leader))
# INCREMENT на next и конец цикла.
row += next