让Chatgpt帮我写代码(一)

一、起因

今天在刷牙的时候看了一眼携程app上订的旅游的航班和高铁班次,发现不知什么时候携程把行程同步到日历的功能给下线了…

但对于我这种习惯了用日历或者提醒功能的人,行程没法通过日历主动提醒,就觉得缺了啥东西。 于是上网搜了搜如何把行程同步到日历上。

后来在知乎上看到了一个人把航班信息发给chatgpt,让它给我直接生成ics文件,然后用mac直接打开就能生成日历了。我也试了下,如下

chatgpt将航班信息转化为ICS文件格式

打开日历确实能够实现想要的效果,同样的手机上也正常显示。

日历显示

既然如此,那就可以直接让chatgpt帮我用写个脚本,下次直接填行程就行。 说干就干。

二、Chatgpt上场

2.1 航班信息

我先重复了让它帮我生成ics的操作,然后再说出我的需求

将需求告诉它

然后将代码放入代码编辑器中运行,果不其然报错了

代码报错

直接丢给chatgpt,让它给我优化(我懒)

chatgpt给的排错建议

不出意外的已经把错误打印出来了

ValueError: time data ‘2023/05/041 5:20’ does not match format ‘%Y/%m/%d %H:%M’

这个错误提示表明时间格式不符合预期,可能是时间字符串中有一个多余的字符或者缺少一个字符。

原来是为填写时间时候,出错了,把2023/05/04 15:20 写成 2023/05/041 5:20 了。

最后查看result.ics打开验证是否能被日历功能正常读取。

生成的代码如下:

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
from datetime import datetime, timedelta
import re

def convert_flight_to_ics(flight_info):
regex = r"(\S+)\s+(\S+)\s+出发时间\s+(\S+\s+\S+)\s+(\S+)\s+达到时间\s+(\S+\s+\S+)"
match = re.search(regex, flight_info)
if match is None:
print("Error: failed to match flight information.")
return None
airline, dep_airport, dep_time, arr_airport, arr_time = match.groups()

# 生成ICS字符串
start_time = datetime.strptime(dep_time, '%Y/%m/%d %H:%M')
end_time = datetime.strptime(arr_time, '%Y/%m/%d %H:%M')
uid = f'{airline}-{start_time.date()}'
ics_str = f'BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//ChatGPT//Flight Schedule//EN\nBEGIN:VEVENT\nUID:{uid}\nDTSTAMP:{datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")}\nDTSTART;TZID=Asia/Shanghai:{start_time.strftime("%Y%m%dT%H%M%S")}\nDTEND;TZID=Asia/Shanghai:{end_time.strftime("%Y%m%dT%H%M%S")}\nSUMMARY:航班 {airline}\nLOCATION:{dep_airport}\nDESCRIPTION:{airline} 将于{dep_time}{dep_airport}出发,预计于{arr_time}到达{arr_airport}。\nEND:VEVENT\nEND:VCALENDAR'

return ics_str

# 读取航班信息
with open('Flight.txt', 'r') as f:
flight_info = f.read()

# 转换为ICS字符串
ics_str = convert_flight_to_ics(flight_info)

# 将ICS字符串写入文件
with open('result.ics', 'w') as f:
f.write(ics_str)

print('转换完成!请查看对应目录的result.ics文件')

2.2 高铁信息

现在解决了航班信息,突然想到还有高铁信息也需要,本次目的是chatgpt帮我写代码,所以我将上面的代码发送给他,增加了需求

新增需求

生成的代码:

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
from datetime import datetime, timedelta
import re

def convert_to_ics(travel_info):
regex = r"(\S+)\s+(\S+)\s+出发时间\s+(\S+\s+\S+)\s+(\S+)\s+达到时间\s+(\S+\s+\S+)"
train_regex = r"(\S+)\s+(\S+)\s+出发时间\s+(\S+\s+\S+)\s+(\S+)\s+到达时间\s+(\S+\s+\S+)"
match = re.search(regex, travel_info)
if match is None:
match = re.search(train_regex, travel_info)
if match is None:
print("Error: failed to match travel information.")
return None
travel_type = "高铁/动车"
train_no, dep_station, dep_time, arr_station, arr_time = match.groups()
else:
travel_type = "航班"
airline, dep_airport, dep_time, arr_airport, arr_time = match.groups()

# 生成ICS字符串
start_time = datetime.strptime(dep_time, '%Y/%m/%d %H:%M')
end_time = datetime.strptime(arr_time, '%Y/%m/%d %H:%M')
uid = f'{travel_type}-{start_time.date()}'
if travel_type == "航班":
summary = f'{airline} {uid}'
location = dep_airport
description = f'{airline} 将于{dep_time}{dep_airport}出发,预计于{arr_time}到达{arr_airport}。'
elif travel_type == "高铁/动车":
summary = f'{train_no} {uid}'
location = dep_station
description = f'{train_no} 将于{dep_time}{dep_station}出发,预计于{arr_time}到达{arr_station}。'
else:
raise ValueError("Unknown travel type.")

ics_str = f'BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//ChatGPT//Travel Schedule//EN\nBEGIN:VEVENT\nUID:{uid}\nDTSTAMP:{datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")}\nDTSTART;TZID=Asia/Shanghai:{start_time.strftime("%Y%m%dT%H%M%S")}\nDTEND;TZID=Asia/Shanghai:{end_time.strftime("%Y%m%dT%H%M%S")}\nSUMMARY:{summary}\nLOCATION:{location}\nDESCRIPTION:{description}\nEND:VEVENT\nEND:VCALENDAR'

return ics_str


# 读取行程信息
with open('Flight.txt', 'r') as f:
travel_info = f.read()

# 转换为ICS字符串
ics_str = convert_to_ics(travel_info)

# 将ICS字符串写入文件
with open('result.ics', 'w') as f:
f.write(ics_str)

print('转换完成!请查看对应目录的result.ics文件')

根据代码最后生成的结果出了点小bug

高铁信息最后在rusult.ics中为 UID:航班-2023-05-02,其中应为UID:高铁/动车-2023-05-02

将错误反馈给chatgpt,继续改~

chagpt排错

原来是我Flight.txt中的“到达时间”写成了“达到时间”,我的锅! 错怪了你 chatgpt。

修改后,就能正常生成了。

三、 Claude

3.1 航班信息

顺便试试Claude的代码能力。 告知他的需求

告知需求

最终生成的效果如下,未能识别

未能识别

将问题反馈给Claude

反馈排错

继续跟它对话,可以按照它的操作来,也可以直接告诉它,把修改后的代码发给你

整理代码

使用修改后的代码继续尝试,还是没达到效果,将输出结果发给它,继续调整

继续优化代码

经过比多次调教,最终给出代码

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
import datetime
import logging

ics = "BEGIN:VCALENDAR\n"
ics += "PRODID:flight\n"
ics += "VERSION:2.0\n"
ics += "CALSCALE:GREGORIAN\n"

flight_info = []
event_count = 0

with open('demo.txt', 'r') as f:
content = f.read().strip()
flights = content.split("\n\n")
for flight in flights:
flight_info = flight.split("\n")

# 打印航班信息,确认是否准确
print(f"航班信息: {flight_info}")

name = flight_info[0]
# 打印航班名称
print(f"name: {name}")

if len(flight_info) < 5:
print("航班信息不完整!")
continue

# 解析出机场和时间信息
airport = flight_info[1].split(' ')
print(f"起飞机场: {airport[0]}")
depart_airport = ' '.join(airport[:2])

depart_time = flight_info[2]
depart_time = datetime.datetime.strptime(depart_time, '%Y-%m-%d %H:%M')
print(f"起飞时间: {depart_time}")

airport = flight_info[3].split(' ')
print(f"到达机场: {airport[0]}")
arrive_airport = ' '.join(airport[:2])

arrive_time = flight_info[4]
arrive_time = datetime.datetime.strptime(arrive_time, '%Y-%m-%d %H:%M')
print(f"到达时间: {arrive_time}")

# 生成VEVENT事件
try:
ics += f"BEGIN:VEVENT\n"
ics += f"UID:{name}@{depart_airport}@{arrive_airport}\n"
ics += f"DTSTART;TZID=Asia/Shanghai:{depart_time.strftime('%Y%m%dT%H%M%S')}\n"
ics += f"DTEND;TZID=Asia/Shanghai:{arrive_time.strftime('%Y%m%dT%H%M%S')}\n"
ics += f"SUMMARY:{name}\n"
ics += f"LOCATION:{depart_airport} -> {arrive_airport}\n"
ics += "END:VEVENT\n"

event_count += 1

except Exception as e:
print(f"生成VEVENT失败:{e}")
logging.exception(e)

ics += "END:VCALENDAR"

# 如果成功生成了至少一个事件,就写入文件
if event_count > 0:
with open('result.ics', 'w') as f:
f.write(ics)
else:
print("没有生成任何事件,无法写入到文件")

3.2 高铁信息

告知Claude,需要在原代码基础上添加识别高铁信息的功能。

添加识别高铁信息

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
import datetime
import logging

ics = "BEGIN:VCALENDAR\n"
ics += "PRODID:transport\n" # 修改为transport
ics += "VERSION:2.0\n"
ics += "CALSCALE:GREGORIAN\n"

info = []
event_count = 0

with open('demo.txt', 'r') as f:
content = f.read().strip()
transports = content.split("\n\n") # 修改为transports
for transport in transports:
info = transport.split("\n")

# 判断是航班还是高铁
if '高铁' in info[0] or '动车' in info[0]:
# 高铁信息
name = info[0]
# 起始站
start_station = info[1]
# 出发时间
depart_time = info[2]
depart_time = datetime.datetime.strptime(depart_time, '%Y/%m/%d %H:%M')
# 终点站
end_station = info[3]
# 到达时间
arrive_time = info[4]
arrive_time = datetime.datetime.strptime(arrive_time, '%Y/%m/%d %H:%M')

else:
# 航班信息(代码省略)
...

# 生成VEVENT事件
try:
ics += f"BEGIN:VEVENT\n"
if '高铁' in name or '动车' in name: # 判断是高铁还是航班
ics += f"UID:{name}@{start_station}@{end_station}\n" # 修改机场为站点
else:
ics += f"UID:{name}@{depart_airport}@{arrive_airport}\n"
... # 其他代码不变

event_count += 1
except Exception as e:
... # 日志记录异常代码不变

# 后续代码不变
...

但一眼看出它将原有的 ics += “PRODID:flight\n” 修改为了 ics += “PRODID:transport\n”

明显不符合我的要求,于是重新把我的需求告诉它,现在看上去是理解了我的需求了。

重新说明需求

给出代码后还给出了本次代码修改特点,可谓是很贴心了🤣

修改特点

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
import datetime
import logging

ics = "BEGIN:VCALENDAR\n"
ics += "PRODID:transport\n"
ics += "VERSION:2.0\n"
ics += "CALSCALE:GREGORIAN\n"

info = []
event_count = 0

with open('demo.txt', 'r') as f:
content = f.read().strip()
transports = content.split("\n\n")

for transport in transports:
info = transport.split("\n")

# 先判断是航班还是高铁,然后分别处理
if '高铁' in info[0] or '动车' in info[0]:
# 高铁信息
...
else:
# 航班信息
...

# 生成VEVENT事件
try:
ics += f"BEGIN:VEVENT\n"
if '高铁' in name or '动车' in name:
ics += f"UID:{name}@{start_station}@{end_station}\n"
else:
ics += f"UID:{name}@{depart_airport}@{arrive_airport}\n"
... # 其他代码不变

event_count += 1
except Exception as e:
... # 日志记录异常代码不变

# 后续代码不变
...

运行修正后的代码,成功生产ics文件

Claude生产的ics

四、 效果对比

然后给出与chatgpt生成的ics对比

  • Claude

    Claude效果

Chatgpt效果

4.1 最终代码

贴上Chatgpt和Claude生成的代码

4.1.1 Chatgpt

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
from datetime import datetime, timedelta
import re

def convert_to_ics(travel_info):
regex = r"(\S+)\s+(\S+)\s+出发时间\s+(\S+\s+\S+)\s+(\S+)\s+达到时间\s+(\S+\s+\S+)"
train_regex = r"(\S+)\s+(\S+)\s+出发时间\s+(\S+\s+\S+)\s+(\S+)\s+到达时间\s+(\S+\s+\S+)"
match = re.search(regex, travel_info)
if match is None:
match = re.search(train_regex, travel_info)
if match is None:
print("Error: failed to match travel information.")
return None
travel_type = "高铁/动车"
train_no, dep_station, dep_time, arr_station, arr_time = match.groups()
else:
travel_type = "航班"
airline, dep_airport, dep_time, arr_airport, arr_time = match.groups()

# 生成ICS字符串
start_time = datetime.strptime(dep_time, '%Y/%m/%d %H:%M')
end_time = datetime.strptime(arr_time, '%Y/%m/%d %H:%M')
uid = f'{travel_type}-{start_time.date()}'
if travel_type == "航班":
summary = f'{airline} {uid}'
location = dep_airport
description = f'{airline} 将于{dep_time}{dep_airport}出发,预计于{arr_time}到达{arr_airport}。'
elif travel_type == "高铁/动车":
summary = f'{train_no} {uid}'
location = dep_station
description = f'{train_no} 将于{dep_time}{dep_station}出发,预计于{arr_time}到达{arr_station}。'
else:
raise ValueError("Unknown travel type.")

ics_str = f'BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//ChatGPT//Travel Schedule//EN\nBEGIN:VEVENT\nUID:{uid}\nDTSTAMP:{datetime.utcnow().strftime("%Y%m%dT%H%M%SZ")}\nDTSTART;TZID=Asia/Shanghai:{start_time.strftime("%Y%m%dT%H%M%S")}\nDTEND;TZID=Asia/Shanghai:{end_time.strftime("%Y%m%dT%H%M%S")}\nSUMMARY:{summary}\nLOCATION:{location}\nDESCRIPTION:{description}\nEND:VEVENT\nEND:VCALENDAR'

return ics_str


# 读取行程信息
with open('Flight.txt', 'r') as f:
travel_info = f.read()

# 转换为ICS字符串
ics_str = convert_to_ics(travel_info)

# 将ICS字符串写入文件
with open('result.ics', 'w') as f:
f.write(ics_str)

print('转换完成!请查看对应目录的result.ics文件')

Flight.txt的格式

  • 航班信息
1
2
3
4
5
厦门航空 MF8415
杭州萧山机场T3
出发时间 2023/05/04 15:20
重庆江北机场T3
到达时间 2023/05/04 17:45
  • 高铁信息
1
2
3
4
5
高铁/动车 G158
杭州东站
出发时间 2023/05/04 16:13
上海虹桥站
到达时间 2023/05/04 17:12

4.1.2 Claude

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
import datetime
import logging

ics = "BEGIN:VCALENDAR\n"
ics += "PRODID:transport\n"
ics += "VERSION:2.0\n"
ics += "CALSCALE:GREGORIAN\n"

info = []
event_count = 0

with open('demo.txt', 'r') as f:
content = f.read().strip()
transports = content.split("\n\n")

for transport in transports:
info = transport.split("\n")

# 先判断是航班还是高铁,然后分别处理
if '高铁' in info[0] or '动车' in info[0]:
# 高铁信息
name = info[0]
# 起始站
start_station = info[1]
# 出发时间
depart_time = info[2]
depart_time = datetime.datetime.strptime(depart_time, '%Y/%m/%d %H:%M')
# 终点站
end_station = info[3]
# 到达时间
arrive_time = info[4]
arrive_time = datetime.datetime.strptime(arrive_time, '%Y/%m/%d %H:%M')
else:
# 航班信息
flight_info = transport.split("\n")
name = flight_info[0]
# 解析出机场和时间信息
airport = flight_info[1].split(' ')
depart_airport = ' '.join(airport[:2])

depart_time = flight_info[2]
depart_time = datetime.datetime.strptime(depart_time, '%Y-%m-%d %H:%M')

airport = flight_info[3].split(' ')
arrive_airport = ' '.join(airport[:2])

arrive_time = flight_info[4]
arrive_time = datetime.datetime.strptime(arrive_time, '%Y-%m-%d %H:%M')

# 生成VEVENT事件
try:
ics += f"BEGIN:VEVENT\n"
if '高铁' in name or '动车' in name:
ics += f"UID:{name}@{start_station}@{end_station}\n"
else:
ics += f"UID:{name}@{depart_airport}@{arrive_airport}\n"
ics += f"DTSTART;TZID=Asia/Shanghai:{depart_time.strftime('%Y%m%dT%H%M%S')}\n"
ics += f"DTEND;TZID=Asia/Shanghai:{arrive_time.strftime('%Y%m%dT%H%M%S')}\n"
ics += f"SUMMARY:{name}\n"
if '高铁' in name or '动车' in name:
ics += f"LOCATION:{start_station} -> {end_station}\n"
else:
ics += f"LOCATION:{depart_airport} -> {arrive_airport}\n"
ics += "END:VEVENT\n"
event_count += 1
except Exception as e:
print(f"生成VEVENT失败:{e}")
logging.exception(e)

ics += "END:VCALENDAR"

# 如果成功生成了至少一个事件,就写入文件
if event_count > 0:
with open('result.ics', 'w') as f:
f.write(ics)
else:
print("没有生成任何事件,无法写入到文件")

Demo.txt 格式

  • 航班信息
1
2
3
4
5
厦门航空 MF8415
杭州萧山机场T3
2023-05-04 15:20
重庆江北机场T3
2023-05-04 17:45
  • 高铁信息
1
2
3
4
5
高铁 G158
杭州东站
2023/05/04 16:13
上海虹桥站
2023/05/04 17:12

五 、 最后

整个过程中因为我不想自己去手动调整代码,直接以命令口吻要求Chatgpt和Claude帮我写,如果报错或者输出结果不对,就把结果和错误发送回去,让它继续优化,直到达到自己想要的目的。 因为本人用的gpt3.5 和 Claude,编码能力不及gpt4.0;所以替我写好的代码需要重复调整,在这个上面花费的时间有点多(当然也有我自己写错配置的原因,比如到达写成达到,chatgpt第二次给我指正这个问题时候我才发现🤣)

目前代码需要自己在txt文件中添加航班或者高铁信息,还有优化的空间。

5.1 一些小问题

在使用Keepchatgpt插件的时候,chatgpt发过来的代码还是会出现中断的情况,但是不会出现报错提示了。此时就需要提升chatgpt 代码没发完整,需要重新发。

chatgpt回复出现中断

5.2 代码能力

gpt 4.0 >> gpt 3.5 > Claude

5.3 注意 ⚠️

本次只是一个小脚本,信息就是个人的出行信息。不涉及敏感信息,但还是要强调一点:不要在chatgpt上发送有关企业内部代码和敏感涉密代码。信息安全是重中之重!!!

想吐槽携程啥时候能把这个行程信息同步功能重新上线….😶‍🌫️

六、参考来源

  1. https://chat.openai.com/
  2. https://app.slack.com

让Chatgpt帮我写代码(一)
https://suiyideali.github.io/2023/04/22/让Chatgpt帮我写代码(一)/
作者
m0ch4z
发布于
2023年4月22日
更新于
2023年12月29日
许可协议