Skip to content

Commit c388559

Browse files
功能常规性更新
1 parent 5f0b875 commit c388559

File tree

9 files changed

+194
-72
lines changed

9 files changed

+194
-72
lines changed

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "usf"
7-
version = "1.0.0"
7+
version = "0.1.2"
88
description = "A lightweight Universal Schedule Format (USF) parser and generator."
99
authors = [{ name = "USF-org", email = "USF-org@outlook.com" }]
1010
license = { text = "MIT" }
1111
readme = "README.md"
1212
requires-python = ">=3.6"
13-
dependencies = []
13+
dependencies = ["jsonschema"]
1414

1515
[project.urls]
1616
Homepage = "https://github.com/USF-org"

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
setup(
44
name="usf",
5-
version="1.0.0",
5+
version="0.1.2",
66
packages=find_packages(),
77
install_requires=[],
88
python_requires=">=3.6",

tests/test_generator.py

Lines changed: 0 additions & 13 deletions
This file was deleted.

tests/test_parser.py

Lines changed: 0 additions & 11 deletions
This file was deleted.

tests/test_usf.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import json
2+
import unittest
3+
from usf.generator import USFGenerator
4+
from usf.parser import USFParser
5+
from usf.validator import USFValidator
6+
7+
class TestUSF(unittest.TestCase):
8+
def setUp(self):
9+
"""初始化测试用例"""
10+
self.generator = USFGenerator(version=1)
11+
12+
# 添加科目
13+
self.generator.add_subject("Mathematics", simplified_name="Math", teacher="Dr. Smith", room="Room 101")
14+
self.generator.add_subject("Physics", simplified_name="Phys", teacher="Dr. Johnson", room="Room 102")
15+
16+
# 添加时间段(每天适用)
17+
self.generator.add_period("08:00:00", "09:30:00") # 第一节课
18+
self.generator.add_period("10:00:00", "11:30:00") # 第二节课
19+
20+
# 添加课程表(星期一的第一节课为数学,第二节课为物理)
21+
self.generator.add_schedule(1, "all", "Mathematics", 1) # 星期一,第一节,数学
22+
self.generator.add_schedule(1, "all", "Physics", 2) # 星期一,第二节,物理
23+
24+
# 生成 USF 数据
25+
self.usf_data = self.generator.generate_usf_data()
26+
27+
def test_usf_generation(self):
28+
"""测试 USF 生成"""
29+
self.assertIn("version", self.usf_data)
30+
self.assertIn("subjects", self.usf_data)
31+
self.assertIn("periods", self.usf_data)
32+
self.assertIn("timetable", self.usf_data)
33+
34+
self.assertEqual(self.usf_data["version"], 1)
35+
self.assertEqual(len(self.usf_data["subjects"]), 2)
36+
self.assertEqual(len(self.usf_data["periods"]), 2)
37+
self.assertEqual(len(self.usf_data["timetable"]), 2)
38+
39+
def test_usf_parser(self):
40+
"""测试 USF 解析"""
41+
json_data = json.dumps(self.usf_data, indent=2)
42+
parser = USFParser(json_data)
43+
44+
self.assertEqual(len(parser.get_subjects()), 2)
45+
self.assertEqual(len(parser.get_periods()), 2)
46+
self.assertEqual(len(parser.get_timetable()), 2)
47+
48+
# 验证解析出的数据是否正确
49+
subjects = parser.get_subjects()
50+
self.assertEqual(subjects["Mathematics"]["teacher"], "Dr. Smith")
51+
self.assertEqual(subjects["Physics"]["room"], "Room 102")
52+
53+
def test_usf_validation(self):
54+
"""测试 USF 校验"""
55+
validator = USFValidator()
56+
57+
# 校验正确的数据
58+
self.assertTrue(validator.validate(self.usf_data))
59+
60+
# 校验错误的数据(缺少 timetable)
61+
invalid_data = {
62+
"version": 1,
63+
"subjects": self.usf_data["subjects"],
64+
"periods": self.usf_data["periods"]
65+
}
66+
self.assertFalse(validator.validate(invalid_data))
67+
68+
if __name__ == "__main__":
69+
unittest.main()

usf/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from .parser import USFParser
21
from .generator import USFGenerator
2+
from .parser import USFParser
33
from .validator import USFValidator
44

5-
__all__ = ["USFParser", "USFGenerator", "USFValidator"]
5+
__all__ = ["USFGenerator", "USFParser", "USFValidator"]

usf/generator.py

Lines changed: 78 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,84 @@
11
import json
22

33
class USFGenerator:
4-
def __init__(self):
5-
self.data = {"subjects": [], "schedule": []}
6-
7-
def add_subject(self, name, teacher, location):
8-
"""添加课程"""
9-
subject = {"name": name, "teacher": teacher, "location": location}
10-
self.data["subjects"].append(subject)
11-
12-
def add_schedule(self, subject_index, day, time, week_rule="all"):
13-
"""添加课程表项"""
14-
schedule_item = {
15-
"subject_index": subject_index,
16-
"day": day,
17-
"time": time,
18-
"week_rule": week_rule
4+
def __init__(self, version=1):
5+
"""
6+
Initialize USF Generator.
7+
8+
Args:
9+
version (int, optional): USF format version. Defaults to 1.
10+
"""
11+
self.version = version
12+
self.subjects = {}
13+
self.periods = []
14+
self.timetable = []
15+
16+
def add_subject(self, name, simplified_name=None, teacher=None, room=None):
17+
"""
18+
Add a subject to USF.
19+
20+
Args:
21+
name (str): Subject name.
22+
simplified_name (str, optional): Shortened subject name.
23+
teacher (str, optional): Teacher's name.
24+
room (str, optional): Classroom.
25+
"""
26+
self.subjects[name] = {
27+
"simplified_name": simplified_name or name,
28+
"teacher": teacher or "",
29+
"room": room or "",
30+
}
31+
32+
def add_period(self, start_time, end_time):
33+
"""
34+
Add a class period to USF.
35+
36+
Args:
37+
start_time (str): Start time (HH:MM:SS).
38+
end_time (str): End time (HH:MM:SS).
39+
40+
Returns:
41+
int: Index of the added period (1-based).
42+
"""
43+
self.periods.append([start_time, end_time])
44+
return len(self.periods) # Return 1-based index
45+
46+
def add_schedule(self, day, week_type, subject, period_index):
47+
"""
48+
Add a schedule entry.
49+
50+
Args:
51+
day (int): Day of the week (1=Monday, ..., 7=Sunday).
52+
week_type (str): "all", "even", or "odd".
53+
subject (str): Subject name (must exist in subjects).
54+
period_index (int): Index of the period (1-based).
55+
"""
56+
if subject not in self.subjects:
57+
raise ValueError(f"Subject '{subject}' is not defined.")
58+
if period_index < 1 or period_index > len(self.periods):
59+
raise ValueError(f"Invalid period index {period_index}.")
60+
self.timetable.append([day, week_type, subject, period_index])
61+
62+
def generate(self):
63+
"""
64+
Generate USF data as a dictionary.
65+
66+
Returns:
67+
dict: USF formatted data.
68+
"""
69+
return {
70+
"version": self.version,
71+
"subjects": self.subjects,
72+
"periods": self.periods,
73+
"timetable": self.timetable,
1974
}
20-
self.data["schedule"].append(schedule_item)
2175

22-
def save(self, filename):
23-
"""保存USF文件"""
76+
def save_to_file(self, filename):
77+
"""
78+
Save USF data to a JSON file.
79+
80+
Args:
81+
filename (str): Output filename.
82+
"""
2483
with open(filename, "w", encoding="utf-8") as f:
25-
json.dump(self.data, f, ensure_ascii=False, indent=2)
84+
json.dump(self.generate(), f, indent=2, ensure_ascii=False)

usf/parser.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
import json
22

33
class USFParser:
4-
def __init__(self, usf_file):
5-
self.usf_file = usf_file
6-
self.data = None
4+
def __init__(self, filename):
5+
"""
6+
Initialize USF Parser.
77
8-
def load(self):
9-
"""加载USF文件"""
10-
with open(self.usf_file, "r", encoding="utf-8") as f:
8+
Args:
9+
filename (str): Path to USF JSON file.
10+
"""
11+
with open(filename, "r", encoding="utf-8") as f:
1112
self.data = json.load(f)
1213

1314
def get_subjects(self):
14-
"""获取课程列表"""
15-
if self.data is None:
16-
self.load()
17-
return self.data.get("subjects", [])
15+
"""Return the subjects dictionary."""
16+
return self.data.get("subjects", {})
1817

19-
def is_valid(self):
20-
"""检查USF文件是否合法"""
21-
from .validator import USFValidator
22-
validator = USFValidator(self.data)
23-
return validator.validate()
18+
def get_periods(self):
19+
"""Return the list of periods."""
20+
return self.data.get("periods", [])
21+
22+
def get_timetable(self):
23+
"""Return the timetable list."""
24+
return self.data.get("timetable", [])

usf/validator.py

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
1+
import json
2+
import jsonschema
3+
from jsonschema import validate
4+
15
class USFValidator:
2-
def __init__(self, data):
3-
self.data = data
4-
5-
def validate(self):
6-
"""校验USF数据格式"""
7-
if not isinstance(self.data, dict):
8-
return False
9-
if "subjects" not in self.data or "schedule" not in self.data:
10-
return False
6+
def __init__(self, schema_file="schema.json"):
7+
"""
8+
Initialize USF Validator.
9+
10+
Args:
11+
schema_file (str, optional): Path to JSON Schema. Defaults to "schema.json".
12+
"""
13+
with open(schema_file, "r", encoding="utf-8") as f:
14+
self.schema = json.load(f)
15+
16+
def validate(self, data):
17+
"""
18+
Validate USF data.
19+
20+
Args:
21+
data (dict): USF formatted dictionary.
22+
23+
Returns:
24+
bool: True if valid, raises an error if invalid.
25+
"""
26+
validate(instance=data, schema=self.schema)
1127
return True
28+

0 commit comments

Comments
 (0)