我不是产品经理,但我涉足。在工作中,我们最近开始了一项计划,该计划确实需要一些适当的用户故事映射(以我的卑鄙看法)。我们是一个完全分布式的团队,我们对这种事情的贡献是Miro.
由于这个项目的性质,我有很多文档可以梳理和大量的用户故事卡来创建和组织。问题是,我太不耐烦了,无法直接在Miro 中创建它们,所有这些指向和单击和重写。
我知道可以将Google表格复制到Miro板上,并且数据将作为粘笔注入。我也知道Google表可以上传为CSV文件。
这是一个想法:用于快速输入用户故事的脚本并将这些用户故事导出为可以上传到Google表的CSV文件的脚本。我有理由花更多的时间在Python上,所以这就是我要写此脚本的内容。
我将逐步构建此脚本。
收集输入
让我们从收集输入开始。
role = input("As a(n): ")
function = input("I want to: ")
outcome = input("So that: ")
print(f"As a(n) {role} I want to {function} so that {outcome}")
很容易。 python为我们提供了input()
方法,这些用于字符串插值的f-strings
。
运行脚本,您可以输入信息,但是脚本将在您输入第一个故事后立即终止。这是不好的,因为我想输入许多故事。因此,完成一个故事后,我希望它再次提示我。我会添加一段循环:
while True:
role = input("As a(n): ")
function = input("I want to: ")
outcome = input("So that: ")
print(f"As a(n) {role} I want to {function} so that {outcome}\n\n")
现在我们将永远循环(或直到按CTRL-C)为止。我还在最后一行的结尾添加了两个线路休息,因此故事之间有一些空间。唯一的问题是格式有点时髦。我希望每个故事之后都可以清理屏幕,以免游戏机拥挤:
import os
os.system("clear")
while True:
role = input("As a(n): ")
function = input("I want to: ")
outcome = input("So that: ")
os.system("clear")
print(f"As a(n) {role} I want to {function} so that {outcome}\n\n")
我们导入os
模块,然后在输入每个故事后将clear
命令发送到控制台。
将故事写入CSV文件
那么我们如何写入Python中的文件?
import os
os.system("clear")
file = open("stories.csv", "w")
try:
while True:
role = input("As a(n): ")
function = input("I want to: ")
outcome = input("So that: ")
os.system("clear")
file.write(f"As a(n) {role} I want to {function} so that {outcome}\n")
except KeyboardInterrupt:
file.close()
os.system("clear")
print("g'bye")
python为我们提供了open()
函数,该功能采用要写入的文件的名称以及与使用文件打开文件的模式。 (在这种情况下,写入“ W”。)我们需要确保在完成文件后关闭文件,以便添加了一个尝试/除外。通过在除块中捕获KeyboardInterrupt
函数,我可以在按下ctrl-c时关闭文件。
测试和松散的末端
我只是进行了一个简单的手动测试:运行脚本,将结果的CSV文件上传到Google表格,然后将细胞从该表格复制到Miro。它像魅力一样工作。
我要做的最后一件事是清理硬编码的文件名,以便用户可以如果需要:
可以更改它:
import os
os.system("clear")
file_path = input("Path to stories csv (./stories.csv): ")
file_path = "stories.csv" if file_path == "" else file_path
print(f"Writing stories to {file_path}\n\n")
file = open(file_path, "w")
try:
while True:
role = input("As a(n): ")
function = input("I want to: ")
outcome = input("So that: ")
os.system("clear")
file.write(f"As a(n) {role} I want to {function} so that {outcome}\n")
except KeyboardInterrupt:
file.close()
os.system("clear")
print("g'bye")
我已经提示用户获取文件名并提供了默认值。
由于我们正在接受文件名的用户输入,因此用户可以给我们一个不良的文件名,这会导致脚本输出可怕的错误。由于我是该脚本的唯一用户,因此我通常不太介意太多。但是,由于我也对Python感到满意,让我们变得更好。
要这样做,如果我们提供了一个不良文件名,我需要弄清楚python会给我什么错误。尝试给它一个文件名,例如“〜/blah blah%$#@ no”,看看会发生什么。我们得到一个FileNotFoundError
。
当我们遇到此错误时,我们想做什么?我们可以强制默认文件名,或者我们可以用友好的消息结束脚本。我喜欢最后一个选项,所以我不会意外地写一个也许我想待在的文件。
#!/usr/bin/env python3
import os
os.system("clear")
file_path = input("Path to stories csv (./stories.csv): ")
file_path = "stories.csv" if file_path == "" else file_path
try:
file = open(file_path, "w")
print(f"Writing stories to {file_path}\n\n")
while True:
role = input("As a(n): ")
function = input("I want to: ")
outcome = input("So that: ")
os.system("clear")
file.write(f"As a(n) {role} I want to {function} so that {outcome}\n")
except KeyboardInterrupt:
file.close()
os.system('clear')
print("g'bye")
except FileNotFoundError:
print(f"{file_path} is not a valid filename.")
我添加了一个新的except
块,并打印了一条友好的消息。我还在脚本的开头添加了一个Shebang,因此我可以将其放入Bin文件夹中并从任何地方运行。现在,这生活在my dotfiles repo,直到我决定摆脱它为止。
在这里没什么可见的
快速而肮脏的工具是我关于编码的一些最喜欢的东西,而Python是一种创建它们的好语言。