
本文介绍如何将独立的星形图案生成函数改造为可复用模块,并通过主循环接收用户输入,逐字渲染5×5 ascii星图,支持多字母组合显示及优雅退出机制。
本文介绍如何将独立的星形图案生成函数改造为可复用模块,并通过主循环接收用户输入,逐字渲染5×5 ascii星图,支持多字母组合显示及优雅退出机制。
在构建字符艺术类程序时,关键在于职责分离与参数化设计:原始代码中 pattern() 函数直接依赖全局变量 name 和 list2,导致难以复用;而输入验证逻辑(如 information_gathering_phase)与图案渲染逻辑混杂,破坏了模块内聚性。下面我们将重构整个流程,使其符合专业 Python 教程推荐的实践标准。
✅ 核心重构原则
- 函数应接收输入,返回输出:pattern(name) 接收字符串,返回由多个 5×5 字符矩阵组成的列表;
- 避免全局状态:所有中间变量(如 list2)应在函数内部声明;
- 输入验证与业务逻辑解耦:验证由专用函数完成,渲染由 pattern() 独立承担;
- 横向排版渲染需按行优先遍历:即先固定第 i 行(0–4),再对每个字母取该行字符,最后统一打印一行。
? 完整可运行代码
def pattern(name):
"""根据输入字符串生成对应字母的5x5星形图案列表(每个字母为5x5二维字符列表)"""
list2 = []
for char in name.upper(): # 统一转大写,增强鲁棒性
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 0 < col <= 4):
grid[row][col] = "*"
list2.append(grid)
else:
print(f"Warning: '{char}' is not supported. Skipping.")
continue # 跳过非法字符,不中断整个流程
return list2
def information_gathering_phase():
"""获取用户输入单词,仅接受 'B', 'A', 'L'(大小写不敏感),输入 'stop' 退出"""
while True:
word = input("Enter a word from the letters 'B', 'A' and/or 'L' (or type 'stop' to stop): ").strip()
if word.lower() == "stop":
return None
if all(c.upper() in "BAL" for c in word):
return word
print("Invalid word! Only 'B', 'A', 'L' (case-insensitive) are allowed.")
def main():
print("? Letter Pattern Generator (B / A / L only)")
print("Type 'stop' at any time to exit.\n")
while True:
word = information_gathering_phase()
if word is None:
print("Thanks for trying my program... Bye for now!")
break
# 生成所有字母的图案矩阵
letter_grids = pattern(word)
if not letter_grids: # 若全部跳过,无有效图案
print("No valid letters to display.\n")
continue
# 按行渲染:第 i 行 → 所有字母的第 i 行 → 合并为一行输出
for row_idx in range(5):
line_parts = []
for grid in letter_grids:
line_parts.append("".join(grid[row_idx])) # 拼接单个字母的第 row_idx 行
print(" ".join(line_parts)) # 字母间用空格分隔
print() # 字母组之间空一行
if __name__ == "__main__":
main()⚠️ 注意事项与扩展建议
- 可维护性提升:当前 pattern() 中的字母逻辑仍较冗长。后续可将每个字母定义为独立函数(如 get_A(), get_B())或使用预定义字典(如 CHAR_MAP = {'A': [...], 'B': [...]}),大幅提升可读性与可扩展性。
- 错误处理优化:原逻辑遇到非法字符会打印 "INVALID" 并终止整个 pattern()。我们改为 print Warning + continue,确保合法字符仍能正常输出。
- 渲染清晰度:示例中改用 " ".join(...) 替代嵌套三重循环 print(..., end=" "),语义更清晰、性能略优,且避免末尾多余空格问题。
- 未来扩展:添加完整 26 字母支持时,只需向 pattern() 的 if/elif 链中追加分支,或采用字典映射 + getattr() 动态调用,即可平滑演进。
通过本次重构,你不仅解决了“函数与循环整合”的具体问题,更掌握了命令行工具开发中至关重要的关注点分离与函数接口设计思想——这是构建可测试、可维护、可扩展 Python 应用的基石。










