
本文详解如何重构星形图案生成函数,使其接收用户输入的单词作为参数,并嵌入循环交互流程,支持连续输入、校验与即时渲染,为后续扩展完整字母表奠定模块化基础。
本文详解如何重构星形图案生成函数,使其接收用户输入的单词作为参数,并嵌入循环交互流程,支持连续输入、校验与即时渲染,为后续扩展完整字母表奠定模块化基础。
在构建字符艺术(ASCII Art)类程序时,核心挑战之一是解耦逻辑与交互:图案生成应专注“如何画”,而输入控制应负责“何时画、画什么”。原始代码将 name 和 list2 设为全局变量,导致函数无法复用、难以测试,且与主流程强耦合。下面我们将通过三步完成专业级重构——参数化、局部化、流程化。
✅ 第一步:使 pattern() 成为纯函数
原函数隐式依赖全局 name 和 list2,需改为显式接收字符串参数,并在函数内部初始化结果容器:
def pattern(name):
list2 = [] # ✅ 局部变量,避免副作用
for char in name: # ✅ 使用更清晰的变量名替代 i
if char == "B":
grid = [[" " for _ in range(5)] for _ in range(5)]
for row in range(5):
for col in range(5):
if (col == 0) or \
(col == 4 and row not in {0, 2, 4}) or \
((row in {0, 2, 4}) and 0 < col < 4):
grid[row][col] = "*"
list2.append(grid)
elif char == "A":
grid = [[" " for _ in range(5)] for _ in range(5)]
for row in range(5):
for col in range(5):
if (row == 0 and 1 < col < 3) or \
((row == 1) and (0 < col < 2 or 2 < col < 4)) or \
(row == 2) or \
((row in {3, 4}) and (col == 0 or col == 4)):
grid[row][col] = "*"
list2.append(grid)
elif char == "L":
grid = [[" " for _ in range(5)] for _ in range(5)]
for row in range(5):
for col in range(5):
if col == 0 or (row == 4 and col > 0):
grid[row][col] = "*"
list2.append(grid)
else:
print(f"Warning: '{char}' is not supported. Skipping.")
continue # ✅ 跳过非法字符,不中断整个流程
return list2? 关键改进说明:
- 所有 print_X 变量统一为 grid,语义更通用;
- 条件表达式使用反斜杠 \ 换行 + 逻辑分组,大幅提升可读性;
- continue 替代 print("INVALID") 避免因单个字符失败而终止整个单词渲染;
- 移除冗余括号与模糊索引(如 0<=col<1 → col == 0),增强健壮性。
✅ 第二步:整合输入验证与主循环
information_gathering_phase() 已具备良好的输入过滤能力(仅允许 'B', 'A', 'L'),我们只需在 main() 中将其输出直接传入 pattern(),并复用其返回的二维字符网格列表进行逐行横向拼接打印:
def main():
print("? Letter Pattern Generator (B / A / L only)")
print("Type 'stop' to exit.\n")
while True:
word = information_gathering_phase()
if word is None:
print("Thanks for trying my program... Bye for now!")
break
# ✅ 调用纯函数,获取每个字母的5×5网格列表
grids = pattern(word)
# ✅ 按行渲染:对每一行(0~4),遍历所有字母网格的该行,横向拼接
for row_idx in range(5):
line = ""
for grid in grids:
# 将当前行的5个字符转为字符串,后加空格分隔
line += "".join(grid[row_idx]) + " "
print(line.rstrip()) # ✅ rstrip() 清除末尾多余空格
print() # ✅ 字母组间空行,提升可读性✅ 第三步:注意事项与扩展建议
- 性能提示:当前实现对每个字符重建 5×5 网格。若追求更高效率,可预先定义 CHAR_MAP = {'A': [...], 'B': [...], ...},实现 O(1) 查表;
- 可维护性:每个字母的绘制逻辑可进一步封装为独立函数(如 draw_A()),便于单元测试与协作开发;
- 健壮性增强:建议在 pattern() 开头添加 if not isinstance(name, str): raise TypeError("Input must be a string");
- 扩展准备:当添加新字母(如 'C', 'D')时,仅需在 if/elif 链中追加分支,无需修改主流程或打印逻辑。
最终,该结构清晰分离了「数据输入」、「模式生成」和「结果输出」三层职责,符合单一职责原则(SRP),为后续支持大小写兼容、自定义尺寸、文件导出等功能提供了坚实基础。










