Files
VSTU_Schedule_Parser/utils.py

184 lines
5.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Copyright Stanislav Mironov
import time
import xlrd
from coord import Coord, Merged
from translations import ExcelSheetReader
import re
class StepTimeCounter:
def __init__(self):
self.time: float = -1.0
self.createtime = time.time()
self.setnow()
def setnow(self):
self.time = time.time()
def step(self, no_set_now=False):
left = time.time() - self.time
if not no_set_now:
self.setnow()
return left
def from_create(self):
left = time.time() - self.createtime
return left
EMPTY_CTYPES = [xlrd.XL_CELL_EMPTY, xlrd.XL_CELL_BLANK]
def discards_list(trg, nones=True, emptystrings=True):
if nones: remove_from_list(trg, [None])
if emptystrings: remove_from_list(trg, [""])
def has_no_bottom_border(reader: "ExcelSheetReader", coord):
return reader.get_border_style(coord, 'bottom') == 0 and reader.get_border_style(coord.shift(down=1), 'top') == 0
def find_element_index(my_list, element):
if element in my_list:
return my_list.index(element)
else:
return -1
def next_element(arr, el):
index = find_element_index(arr, el)
return arr[index + 1]
def remove_from_list(l: list, todel: list):
for x in todel:
if x in l:
l.remove(x)
return l
def parse_all_dirt(reader: "ExcelSheetReader", min_pos: Coord, right, down):
RET = set()
row = min_pos.row
while row < min_pos.row + down:
col = min_pos.col
while col < min_pos.col + right:
#print(excel_coordinate(row, col))
cv = reader.get_cell_value(row, col)
value = str(cv).strip()
if cv is not None and len(value) > 0:
RET.add(value)
col += 1
row += 1
return RET
# GEMINI GENERATED
def normalize_name(raw_name):
"""
Приводит разнородные записи ФИО к единому структурированному виду.
"""
# Шаг 1: Очистка
name = re.sub(r'\s+', ' ', raw_name).strip()
# Шаг 2: Извлечение звания
known_titles = ['проф.', 'доц.', 'акад.', 'к.т.н.', 'д.м.н.']
title = None
for t in known_titles:
if name.lower().startswith(t):
title = t
# Удаляем звание из строки, убираем лишние пробелы
name = name[len(t):].strip()
break
# Шаг 3 и 4: Разделение и идентификация
parts = name.split(' ')
last_name = None
initials = None
# Простой эвристический анализ
# Ищем инициалы (содержат точку или состоят из 1-2 заглавных букв)
initials_parts = []
name_parts = []
for part in parts:
if '.' in part or (1 <= len(part) <= 2 and part.isupper()):
initials_parts.append(part)
else:
# Считаем все остальное частью фамилии (для двойных фамилий)
name_parts.append(part)
if name_parts:
last_name = " ".join(name_parts)
if initials_parts:
initials = "".join(initials_parts) # Сливаем "А." и "Н." в "А.Н."
# Если фамилия не найдена (например, только инициалы),
# но есть части, считаем первую часть фамилией
if not last_name and name_parts:
last_name = name_parts[0]
return {
"last_name": last_name,
"initials": initials,
"title": title
}
def excel_coordinate(row, col):
"""
Преобразует координаты строки и столбца (начиная с 0) в эквивалент Excel (например, A7, CB34).
Args:
row: Индекс строки (начиная с 0).
col: Индекс столбца (начиная с 0).
Returns:
Строка, представляющая координату ячейки в стиле Excel.
~ Google Gemini, tested
"""
col_str = ''
while col >= 0:
col_str = chr(ord('A') + col % 26) + col_str # Преобразуем в буквы, начиная с A
col = col // 26 - 1 # Уменьшаем номер столбца и учитываем переход к следующему разряду (как в 26-ричной системе)
return col_str + str(row + 1) # Добавляем номер строки (Excel начинается с 1)
def merged_humanize(crange):
"""Получить из 4 цифр границ AA:BB координаты как в Excel"""
row_low, col_low, row_high, col_high = crange # see order!
return excel_coordinate(row_low, col_low) + ":" + excel_coordinate(row_high, col_high)
def unspace(s: str):
"""Убрать пробелы из текста"""
if s is None:
return "!!!Python None!!!"
return s.strip().replace(" ", "").replace("\t", "")
def find(sh, query = None):
for rx in range(sh.nrows):
i = 0
for x in sh.row(rx):
if x.value == query:
return rx, i
i += 1
return None
def weekday_to_num(st: str):
if st.upper().strip() == "ПОНЕДЕЛЬНИК":
return 1
if st.upper().strip() == "ВТОРНИК":
return 2
if st.upper().strip() == "СРЕДА":
return 3
if st.upper().strip() == "ЧЕТВЕРГ":
return 4
if st.upper().strip() == "ПЯТНИЦА":
return 5
if st.upper().strip() == "СУББОТА":
return 6
if st.upper().strip() == "ВОСКРЕСЕНЬЕ":
return 7
return -1