fdbw commited on
Commit
6e9babc
·
verified ·
1 Parent(s): 9ee3f9f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +80 -97
app.py CHANGED
@@ -1,27 +1,19 @@
1
  import gradio as gr
2
  import json
3
- import re
4
  from collections import defaultdict
5
 
6
- def safe_extract_year(info_str):
7
- """安全提取出生年份"""
8
- try:
9
- if not info_str:
10
- return 9999
11
- match = re.search(r'(19\d{2}|20\d{2})', str(info_str))
12
- return int(match.group(1)) if match else 9999
13
- except:
14
- return 9999
15
-
16
- def load_full_families():
17
- # 存储所有人物的详细信息,用于反向查找配偶
18
- people = {}
19
- # 存储父子关系:father -> [children]
20
- children_map = defaultdict(list)
21
- # 存储婚姻关系:husband -> wife (尝试从数据中推断)
22
- marriages = {}
23
 
24
- # 第一步:读取所有数据,建立索引
25
  try:
26
  with open('family_data.jsonl', 'r', encoding='utf-8') as f:
27
  for line in f:
@@ -29,103 +21,94 @@ def load_full_families():
29
  if not line:
30
  continue
31
  try:
32
- record = json.loads(line)
33
- name = record.get('n')
34
- if not name:
35
- continue
36
- # 保存人物详情
37
- people[name] = {
38
- 'info': record.get('info', ''),
39
- 'f': record.get('f'), # 父亲
40
- 'm': record.get('m'), # 母亲 (如果有)
41
- }
42
  except:
43
  continue
44
- except:
45
- return {"错误": {"wife": "文件读取失败", "children": []}}
46
 
47
- # 第二步:构建父子关系 & 婚姻关系
48
- # 逻辑:遍历所有有父亲(f)的人,将其加入父亲的子女列表
49
- # 逻辑:通常,女性记录中会包含其丈夫的名字(假设字段为 'spouse' 或 'f' 是夫家,这里需要根据实际数据调整)
50
- # 由于数据结构未知,这里采用一种常见逻辑:如果一个人的 'f' 是某个男性,且这个人是女性(名字在特定列表或通过其他方式判断),则该男性是其丈夫。
51
- # 但为了简化并消除 "待考",我们假设:**数据中存在记录,其 'n' 是母亲,且其 'f' 字段指向其丈夫(即家里的男主人)**
52
-
53
- # 重新遍历,构建关系
54
- for name, details in people.items():
55
- father_name = details['f']
56
-
57
- # 如果这个人有父亲,说明他是子女,加入子女列表
58
- if father_name and father_name != "无":
59
- children_map[father_name].append((name, details['info']))
60
-
61
- # 尝试推断婚姻:如果这个人是女性(简单判断:不在明显的男性列表中,或名字在特定库),且她的 'f' 指向一个男性,则该男性是她的丈夫
62
- # 这是一个复杂的逻辑,这里做一个简单假设:**如果一个人的记录中,其 'f' 是 A,且 A 在数据中存在,那么 A 是她丈夫(即她是A的妻子)**
63
- # 注意:这需要数据格式支持。如果数据中母亲的记录里写着 f: "丈夫名字",则此逻辑成立。
64
- if father_name and father_name in people:
65
- # 假设这是妻子嫁给了 father_name
66
- marriages[father_name] = name # father_name 的妻子是这个人
67
 
68
- # 第三步:整理最终结果
69
- result = {}
70
- # 获取所有可能的父亲(有子女的,或者有妻子的)
71
- all_possible_fathers = set(children_map.keys()) | set(marriages.keys())
72
-
73
- for father in sorted(all_possible_fathers):
74
- # 获取配偶(母亲),如果没有找到,则暂时标记为“请补充”或尝试其他逻辑
75
- mother = marriages.get(father, "数据中未找到配偶记录,请检查数据")
76
-
77
- # 获取子女并去重、排序
78
- children_list = children_map.get(father, [])
79
- # 去重
80
- unique_children = list(set(children_list))
81
- # 按年份排序
82
- unique_children.sort(key=lambda x: safe_extract_year(x[1]))
83
-
84
- result[father] = {
85
- "wife": mother,
 
 
 
 
 
 
 
 
 
 
86
  "children": unique_children
87
  }
 
88
 
89
- return result
90
 
91
- def show_all_families():
92
- families = load_full_families()
93
 
94
- # 如果返回的是错误信息
95
- if "错误" in families:
96
- return families["错误"]
97
-
98
- output_lines = ["# 冯氏家族关系网家网成员表\n"]
99
 
100
  for father in sorted(families.keys()):
101
- family_data = families[father]
102
- mother = family_data["wife"]
103
- children = family_data["children"]
104
-
105
- output_lines.append(f"### {father} 家庭")
106
- output_lines.append(f"* **父亲**:{father}")
107
- output_lines.append(f"* **母亲**:{mother}")
108
- output_lines.append("* **子女**:")
109
 
 
 
 
 
110
  if children:
111
  for name, info in children:
112
- year = safe_extract_year(info)
113
- year_str = f"({year})" if year != 9999 else ""
114
- output_lines.append(f" * {name} {year_str} - {info}")
115
  else:
116
- output_lines.append(" * (暂无子女记录)")
117
-
118
- output_lines.append("") # 空行分隔
119
-
120
- return "\n".join(output_lines)
121
 
122
- # 构建 Gradio 应用
123
  demo = gr.Interface(
124
- fn=show_all_families,
125
  inputs=None,
126
- outputs=gr.Markdown(label="家族成员表"), # 使用 Markdown 更美观
127
  title="冯氏家族关系网家网成员表",
128
- description="点击 **Generate** 查看所有家庭成员(自动关联母亲名字)"
129
  )
130
 
131
  if __name__ == "__main__":
 
1
  import gradio as gr
2
  import json
 
3
  from collections import defaultdict
4
 
5
+ def load_people_and_families():
6
+ """
7
+ 从 family_data.jsonl 加载数据,并自动推断谁是配偶。
8
+ 返回: {father_name: {"spouse": spouse_name_or_None, "children": [(name, info), ...]}}
9
+ """
10
+ # 所有记录
11
+ records = []
12
+ # 统计每个人是否有子女(即是否为人父母)
13
+ is_parent = set()
14
+ # 构建父子关系
15
+ children_of = defaultdict(list)
 
 
 
 
 
 
16
 
 
17
  try:
18
  with open('family_data.jsonl', 'r', encoding='utf-8') as f:
19
  for line in f:
 
21
  if not line:
22
  continue
23
  try:
24
+ rec = json.loads(line)
25
+ name = rec.get('n')
26
+ father = rec.get('f')
27
+ info = rec.get('info', '')
28
+ if name and father and father != "无":
29
+ records.append((name, father, info))
30
+ # 记录父子关系
31
+ children_of[father].append((name, info))
32
+ # 标记此人有父亲,但更重要的是:如果 name 出现在别人 f 字段中,他就是父母
 
33
  except:
34
  continue
35
+ except Exception as e:
36
+ return {"__ERROR__": str(e)}
37
 
38
+ # 第二遍:找出所有“为人父母”的人
39
+ all_fathers = set(children_of.keys())
40
+ for children in children_of.values():
41
+ for child_name, _ in children:
42
+ if child_name in all_fathers:
43
+ is_parent.add(child_name)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
+ # 构建最终家庭结构
46
+ families = {}
47
+ processed_fathers = set()
48
+
49
+ # 所有出现过的男性家长(作为父亲出现过的人)
50
+ for father in all_fathers:
51
+ children_list = children_of[father]
52
+ real_children = []
53
+ spouse_candidate = None
54
+
55
+ for name, info in children_list:
56
+ # 如果这个人自己也是父母,那他大概率不是子女,而是配偶(儿媳/女婿)或同辈
57
+ # 但在夫权家谱中,通常是妻子被记在丈夫名下
58
+ if name in is_parent:
59
+ # 暂定为配偶(取第一个符合条件的)
60
+ if spouse_candidate is None:
61
+ spouse_candidate = name
62
+ # 即使有多个,也只取一个作为配偶,其余可能需人工审核
63
+ else:
64
+ real_children.append((name, info))
65
+
66
+ # 去重子女
67
+ unique_children = list(set(real_children))
68
+ # 简单按名字排序(因无年份无法精确排)
69
+ unique_children.sort(key=lambda x: x[0])
70
+
71
+ families[father] = {
72
+ "spouse": spouse_candidate or "(请补充配偶)",
73
  "children": unique_children
74
  }
75
+ processed_fathers.add(father)
76
 
77
+ return families
78
 
79
+ def format_family_table():
80
+ families = load_people_and_families()
81
 
82
+ if "__ERROR__" in families:
83
+ return f"❌ 数据加载失败:{families['__ERROR__']}"
84
+
85
+ lines = ["# 冯氏家族关系网家网成员表\n"]
 
86
 
87
  for father in sorted(families.keys()):
88
+ data = families[father]
89
+ spouse = data["spouse"]
90
+ children = data["children"]
 
 
 
 
 
91
 
92
+ lines.append(f"### {father} 家庭")
93
+ lines.append(f"- **父亲**:{father}")
94
+ lines.append(f"- **母亲**:{spouse}")
95
+ lines.append("- **子女**:")
96
  if children:
97
  for name, info in children:
98
+ lines.append(f" - {name} — {info}")
 
 
99
  else:
100
+ lines.append(" - (暂无子女记录)")
101
+ lines.append("") # 空行分隔
102
+
103
+ return "\n".join(lines)
 
104
 
105
+ # Gradio 应用
106
  demo = gr.Interface(
107
+ fn=format_family_table,
108
  inputs=None,
109
+ outputs=gr.Markdown(label="家族成员表"),
110
  title="冯氏家族关系网家网成员表",
111
+ description="点击 **Generate** 自动生成全体家庭成员(自动识别配偶与子女)"
112
  )
113
 
114
  if __name__ == "__main__":