
Я написал почти все, кроме синтаксического анализа 3rds-строк в событии (строка местоположения) потому что там могут быть сложные закономерности, вообще здесь может быть практически всё, что приходит к человеку, который составляет расклад, но я собрал набор того, что было в раскладе.
Может быть, и вы есть идеи, как это реализовать? Подойдут и приближенные подходы, с использованием ml и т.п. Прикрепляю скрипт для тестирования:
from datetime import date, datetime, time
from functools import partial
from unittest import TestCase
import pytest
ydate = partial(date, year=datetime.today().year)
cases = [
# Simple
("303", dict(location="303")),
("room 107", dict(location="107")),
("room #107", dict(location="107")),
("ROOM #107", dict(location="107")),
("ONLINE", dict(location="ONLINE")),
("online", dict(location="ONLINE")),
("106/313/314/316/318/320/421", dict(location="106/313/314/316/318/320/421")),
("105/ (ONLINE)", dict(location="105/ONLINE")),
# starts_from modifier
("STARTS ON 2/10", dict(starts_from=ydate(day=2, month=10))),
("STARTS FROM 21/09", dict(starts_from=ydate(day=21, month=9))),
("304 Starts from 19/09", dict(location="304", starts_from=ydate(day=19, month=9))),
("313 (STARTS FROM 21/09)", dict(location="313", starts_from=ydate(day=21, month=9))),
# starts_at modifier
("STARTS AT 16.10", dict(starts_at=time(hour=16, minute=10))),
("107 (STARTS AT 10.50)", dict(location="107", starts_at=time(hour=10, minute=50))),
# week modifiers
("105 (WEEK 2-3 ONLY)", dict(location="105", on_weeks=[2, 3])),
("105 (WEEK 2, 4 ONLY)", dict(location="105", on_weeks=[2, 4])),
("105 (WEEK 2 ONLY)", dict(location="105", on_weeks=[2])),
("105 (WEEK 2)", dict(location="105", on_weeks=[2])),
# on modifier
("ONLINE ON 13/09", dict(location="ONLINE", on=ydate(day=13, month=9))),
(
"107 (ONLY ON 8/09, 29/09, 27/10, 17/11)",
dict(
location="107",
on=[ydate(day=8, month=9), ydate(day=29, month=9), ydate(day=27, month=10), ydate(day=17, month=11)],
),
),
(
"107 (ON 8/09, 29/09, 27/10, 17/11)",
dict(
location="107",
on=[ydate(day=8, month=9), ydate(day=29, month=9), ydate(day=27, month=10), ydate(day=17, month=11)],
),
),
(
"ONLINE (only on 31/08 and 14/09)",
dict(location="ONLINE", on=[ydate(day=31, month=8), ydate(day=14, month=9)]),
),
# NEST
(
"105 (room #107 on 28/08)",
dict(location="105", NEST=dict(location="107", on=ydate(day=28, month=8))),
),
(
"313 (WEEK 1-3) / ONLINE",
dict(location="ONLINE", NEST=dict(location="107", on_weeks=[0, 1, 2])),
),
(
"ONLINE ON 13/09, 108 ON 01/11 (STARTS AT 9:00)",
dict(
starts_at=time(hour=9, minute=0),
NEST=[
dict(location="ONLINE", on=ydate(day=13, month=9)),
dict(location="108", on=ydate(day=1, month=11)),
],
),
),
(
"314 (312 ON 12/09,19/09,26/09) 301 ON 03/10",
dict(
location="314",
NEST=[
dict(
location="312",
on=[
ydate(day=12, month=9),
ydate(day=19, month=9),
ydate(day=26, month=9),
],
),
dict(location="301", on=ydate(day=3, month=10)),
],
),
),
]
def f(input_: str) -> dict:
pass
@pytest.mark.parametrize("input_, desired", cases, ids=[x for x, _ in cases])
def test_location_parser(input_: str, desired: dict):
result = f(input_)
TestCase().assertDictEqual(result, desired)
Подробнее здесь: https://stackoverflow.com/questions/789 ... scheduling