Spaces:
Sleeping
Sleeping
File size: 4,667 Bytes
76684fa |
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 116 117 118 |
import random
from typing import List, Tuple
from data_structures import SlideContent
from logger import LOG
# 定义 content_type 对应的权重
CONTENT_TYPE_WEIGHTS = {
'Title': 1,
'Content': 2,
'Picture': 4
}
def calculate_layout_encoding(layout_name: str) -> int:
"""
根据 layout_name 计算其编码值。
移除编号部分,只对类型进行编码,顺序无关。
"""
# 移除 layout_name 中的编号部分,并按 ',' 分割
parts = layout_name.split(', ')
base_name = ' '.join(part.split()[0] for part in parts) # 只保留类型部分,移除编号
# 计算权重和
weight_sum = sum(CONTENT_TYPE_WEIGHTS.get(part, 0) for part in base_name.split())
return weight_sum
def calculate_content_encoding(slide_content: SlideContent) -> int:
"""
根据 SlideContent 的成员情况计算其编码值。
如果有 title、bullet_points 和 image_path,则根据这些成员生成编码。
"""
encoding = 0
if slide_content.title:
encoding += CONTENT_TYPE_WEIGHTS['Title']
if slide_content.bullet_points:
encoding += CONTENT_TYPE_WEIGHTS['Content']
if slide_content.image_path:
encoding += CONTENT_TYPE_WEIGHTS['Picture']
return encoding
# 通用的布局策略类,使用参数化的方式实现不同布局策略的功能。
class LayoutStrategy:
"""
通用布局策略类,通过参数化方式来选择适合的布局组。
`get_layout` 方法根据 SlideContent 内容和布局映射来返回合适的布局ID和名称。
"""
def __init__(self, layout_group: List[Tuple[int, str]]):
self.layout_group = layout_group # 布局组成员,存储可选布局
def get_layout(self, slide_content: SlideContent) -> Tuple[int, str]:
"""
根据 SlideContent 内容随机选择一个合适的布局。
"""
return random.choice(self.layout_group) # 随机选择布局
# 布局管理器类,负责根据 SlideContent 自动选择合适的布局策略。
class LayoutManager:
"""
布局管理器根据 SlideContent 的内容(如标题、要点和图片)自动选择合适的布局策略,并随机选择一个布局。
"""
def __init__(self, layout_mapping: dict):
self.layout_mapping = layout_mapping # 布局映射配置
# 初始化布局策略,提前为所有布局创建策略并存储在字典中
self.strategies = {
1: self._create_strategy(1), # 仅 Title
3: self._create_strategy(3), # Title + Content
5: self._create_strategy(5), # Title + Picture
7: self._create_strategy(7) # Title + Content + Picture
}
# 打印调试信息
LOG.debug(f"LayoutManager 初始化完成:\n {self}")
def __str__(self):
"""
打印 LayoutManager 的调试信息,包括所有布局策略及其对应的布局组。
"""
output = []
output.append("LayoutManager 状态:")
for encoding, strategy in self.strategies.items():
layout_group = strategy.layout_group
output.append(f" 编码 {encoding}: {len(layout_group)} 个布局")
for layout_id, layout_name in layout_group:
output.append(f" - Layout ID: {layout_id}, Layout Name: {layout_name}")
return "\n".join(output)
def assign_layout(self, slide_content: SlideContent) -> Tuple[int, str]:
"""
根据 SlideContent 的成员情况计算编码,并选择对应的布局策略。
"""
# 计算 SlideContent 的编码
encoding = calculate_content_encoding(slide_content)
# 根据编码获取对应的布局策略
strategy = self.strategies.get(encoding)
if not strategy:
raise ValueError(f"没有找到对应的布局策略,编码: {encoding}")
# 使用对应的策略获取合适的布局
return strategy.get_layout(slide_content)
def _create_strategy(self, layout_type: int) -> LayoutStrategy:
"""
根据布局类型创建通用的布局策略,并生成布局组,记录布局组的 debug 信息。
"""
layout_group = [
(layout_id, layout_name) for layout_name, layout_id in self.layout_mapping.items()
if calculate_layout_encoding(layout_name) == layout_type
]
# Debug 级别日志输出,查看各个布局组的详细情况
# LOG.debug(f"创建 {layout_type} 编码对应的布局组,共 {len(layout_group)} 个布局: {layout_group}")
return LayoutStrategy(layout_group) |