-
Notifications
You must be signed in to change notification settings - Fork 24
/
school.py
115 lines (94 loc) · 3.5 KB
/
school.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import api
import math
import util
class School:
__all_school_list__ = []
__school_name_map__ = {}
__schools_by_pc__ = {}
def __init__(self, idx, name, province, city, aliases):
self.id = idx
self.name = name
self.province = province
self.city = city
self.aliases = aliases
self.score = util.D(0)
@staticmethod
def create(name, province, city, aliases):
"""新建学校。
name: 正式名称。
province: 省份。
city: 城市(或区)。
aliases: 别名列表(可以为空)。
"""
idx = School.count_all()
school = School(idx, name, province, city, aliases)
School.__all_school_list__.append(school)
School.__school_name_map__[name] = school
for alias in aliases:
School.__school_name_map__[alias] = school
pc_key = (province, city)
if pc_key not in School.__schools_by_pc__:
School.__schools_by_pc__[pc_key] = []
School.__schools_by_pc__[pc_key].append(school)
return school
@staticmethod
def by_name(name):
"""根据名称返回学校。
name: 学校名称。
"""
if name in School.__school_name_map__:
return School.__school_name_map__[name]
raise ValueError(f"未知的学校名:\x1b[32m'{name}'\x1b[0m")
@staticmethod
def find_candidate(name, province):
"""根据名称返回已有学校中最有可能者。
name: 学校名称。
province: 省份。
"""
if name in School.__school_name_map__:
return School.__school_name_map__[name]
# 检测是否为 名称/机构 的形式(湖南的报名信息采用此形式)
if "/" in name:
name, _ = name.split("/", 1)
if name in School.__school_name_map__:
return School.__school_name_map__[name]
redirect = api.get_redirect(name)
if redirect is not None and redirect in School.__school_name_map__:
return "b", School.__school_name_map__[redirect]
ret = api.get_location(name, province)
x, y = api.get_longlat(name)
city = "未分区" if ret is None else ret[1]
li = [
(util.lcs(school.name, name), school)
for school in School.__schools_by_pc__.get((province, city), [])
]
li.sort(key=lambda pair: -pair[0])
li = li[:3]
for _, school in li:
if not hasattr(school, "baike_cache"):
school.baike_cache = api.get_redirect(school.name)
school.x, school.y = api.get_longlat(school.name)
if redirect is not None:
if school.baike_cache == redirect:
if redirect == name:
return "f", school
else:
return "fs", school, redirect
for _, school in li:
dist = math.hypot(x - school.x, y - school.y)
if dist <= 0.00108: # 120 米
return "b", school
return "c", city
@staticmethod
def count_all():
"获取当前学校总数。"
return len(School.__all_school_list__)
@staticmethod
def get_all():
"获取当前所有学校的列表。"
return School.__all_school_list__
def location(self):
"获取位置,格式为 province,city。"
return self.province + "," + self.city