<think>我们将在代码中进行以下修改:
1. 将整个脚本包装在 if __name__ == '__main__': 中。
2. 将默认日志文件改为 "result.txt"。
3. 在创建文件夹前检查日志文件是否存在,如果不存在则中断并提示。
具体修改如下:
</think>以下是根据您的要求修改的Python脚本:
```python
import re
import os
import sys
import matplotlib.pyplot as plt
import numpy as np
def main():
# 配置常量
LOG_FILE = "result.txt" # 默认日志文件名
BASE_NAME = LOG_FILE.split('.')[0] # 提取不带扩展名的文件名
# 检查日志文件是否存在
if not os.path.exists(LOG_FILE):
print(f"错误:日志文件 {LOG_FILE} 不存在!")
sys.exit(1) # 文件不存在时退出程序
# 检查并创建输出文件夹
if not os.path.exists(BASE_NAME):
os.makedirs(BASE_NAME)
print(f"创建输出文件夹: {BASE_NAME}/")
# 数据存储结构
packet_data = [] # (current_time, packets_num, loss_rate)
bitrate_data = [] # (current_time, bitrate_kbps, rtt)
gamma_data = [] # (current_time, tq, gamma)
delay_data = [] # (current_time, send_delta, arrival_delta)
# 正则匹配模式
pattern1 = re.compile(r'current_time\[(\d+)\], twcc_packets_num\[(\d+)\], .*?loss_rate = ([\d.]+)%')
pattern2 = re.compile(r'current_time\[(\d+)\]: .*?Suggest bitrate = \[(\d+)\]bps, RTT = \[(\d+)\]ms')
pattern3 = re.compile(r'current_time\[(\d+)\]: Tq\[([\d.]+)\], gamma\[([\d.]+)\]')
pattern4 = re.compile(r'current_time\[(\d+)\], send_delta = (\d+), arrival_delta = (\d+)')
# 读取并解析日志文件
print(f"开始解析日志文件: {LOG_FILE}")
with open(LOG_FILE, 'r') as file:
for line in file:
if m := pattern1.search(line):
current_time = int(m.group(1))
packets_num = int(m.group(2))
loss_rate = float(m.group(3))
packet_data.append((current_time, packets_num, loss_rate))
elif m := pattern2.search(line):
current_time = int(m.group(1))
bitrate_kbps = int(m.group(2)) / 1000 # 转换为kbps
rtt = int(m.group(3))
bitrate_data.append((current_time, bitrate_kbps, rtt))
elif m := pattern3.search(line):
current_time = int(m.group(1))
tq = float(m.group(2))
gamma = float(m.group(3))
gamma_data.append((current_time, tq, gamma))
elif m := pattern4.search(line): # 匹配延迟数据
current_time = int(m.group(1))
send_delta = int(m.group(2))
arrival_delta = int(m.group(3))
delay_data.append((current_time, send_delta, arrival_delta))
delay_count = len(delay_data)
print(f"解析完成: 找到丢包数据{len(packet_data)}条, 码率数据{len(bitrate_data)}条, "
f"趋势数据{len(gamma_data)}条, 延迟数据{delay_count}条")
# 时间归一化函数
def normalize_time(data):
if not data:
return []
base_time = data[0][0]
return [(t - base_time) / 1000.0 for t, *_ in data] # 转换为秒
# 丢包率图表
if packet_data:
times = normalize_time(packet_data)
loss_rates = [d[2] for d in packet_data]
plt.figure(figsize=(10, 6))
plt.plot(times, loss_rates, label='Loss Rate')
plt.title(f"{BASE_NAME}\nPacket Loss Rate")
plt.xlabel("Time (s)")
plt.ylabel("Loss Rate (%)")
plt.legend(loc='best')
plt.grid(True)
plt.savefig(f"{BASE_NAME}/{BASE_NAME}_loss.png")
plt.close()
print(f"已生成: {BASE_NAME}/{BASE_NAME}_loss.png")
# 包数量图表
if packet_data:
packets_num = [d[1] for d in packet_data]
plt.figure(figsize=(10, 6))
plt.plot(times, packets_num, label='Packet Count')
plt.title(f"{BASE_NAME}\nPacket Count Over Time")
plt.xlabel("Time (s)")
plt.ylabel("Packet Count")
plt.legend(loc='best')
plt.grid(True)
plt.savefig(f"{BASE_NAME}/{BASE_NAME}_packetnum.png")
plt.close()
print(f"已生成: {BASE_NAME}/{BASE_NAME}_packetnum.png")
# 上下子图方式替代双纵轴
if packet_data:
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8), sharex=True)
# 上子图: 丢包率
ax1.plot(times, loss_rates, "b-", label="Loss Rate")
ax1.set_ylabel("Loss Rate (%)", color="b")
ax1.tick_params(axis="y", labelcolor="b")
ax1.legend(loc="upper right")
ax1.grid(True)
# 下子图: 包数量
ax2.plot(times, packets_num, "r-", label="Packet Count")
ax2.set_xlabel("Time (s)")
ax2.set_ylabel("Packet Count", color="r")
ax2.tick_params(axis="y", labelcolor="r")
ax2.legend(loc="upper right")
ax2.grid(True)
plt.suptitle(f"{BASE_NAME}\nLoss Rate and Packet Count")
plt.tight_layout()
plt.savefig(f"{BASE_NAME}/{BASE_NAME}_loss_and_num.png")
plt.close()
print(f"已生成: {BASE_NAME}/{BASE_NAME}_loss_and_num.png")
# 码率图表
if bitrate_data:
times = normalize_time(bitrate_data)
bitrates = [d[1] for d in bitrate_data]
plt.figure(figsize=(10, 6))
plt.plot(times, bitrates, label='Bitrate')
plt.title(f"{BASE_NAME}\nBitrate Variation")
plt.xlabel("Time (s)")
plt.ylabel("Bitrate (kbps)")
plt.legend(loc='best')
plt.grid(True)
plt.savefig(f"{BASE_NAME}/{BASE_NAME}_bitrate.png")
plt.close()
print(f"已生成: {BASE_NAME}/{BASE_NAME}_bitrate.png")
# RTT图表
if bitrate_data:
rtts = [d[2] for d in bitrate_data]
plt.figure(figsize=(10, 6))
plt.plot(times, rtts, label='RTT')
plt.title(f"{BASE_NAME}\nRound Trip Time")
plt.xlabel("Time (s)")
plt.ylabel("RTT (ms)")
plt.legend(loc='best')
plt.grid(True)
plt.savefig(f"{BASE_NAME}/{BASE_NAME}_RTT.png")
plt.close()
print(f"已生成: {BASE_NAME}/{BASE_NAME}_RTT.png")
# 趋势图表
if gamma_data:
times = normalize_time(gamma_data)
tq_vals = [d[1] for d in gamma_data]
gamma_vals = [d[2] for d in gamma_data]
neg_gamma = [-g for g in gamma_vals]
plt.figure(figsize=(10, 6))
plt.plot(times, tq_vals, "g-", label="Tq")
plt.plot(times, gamma_vals, "b-", label="Gamma")
plt.plot(times, neg_gamma, "b--", label="-Gamma")
plt.title(f"{BASE_NAME}\nTq and Gamma Trend")
plt.xlabel("Time (s)")
plt.ylabel("Value")
plt.legend(loc='best')
plt.grid(True)
plt.savefig(f"{BASE_NAME}/{BASE_NAME}_trend.png")
plt.close()
print(f"已生成: {BASE_NAME}/{BASE_NAME}_trend.png")
# 延迟变化图表(按时间)
if delay_data:
times = normalize_time(delay_data)
send_deltas = [d[1] for d in delay_data]
arrival_deltas = [d[2] for d in delay_data]
delay_deltas = [arrival - send for send, arrival in zip(send_deltas, arrival_deltas)]
plt.figure(figsize=(12, 8))
plt.plot(times, send_deltas, 'b-', label='Send Delta (ms)')
plt.plot(times, arrival_deltas, 'g-', label='Arrival Delta (ms)')
plt.plot(times, delay_deltas, 'r-', label='Delay Delta (ms)')
plt.title(f"{BASE_NAME}\nNetwork Delay Metrics Over Time")
plt.xlabel("Time (s)")
plt.ylabel("Delta Time (ms)")
plt.legend(loc='best')
plt.grid(True)
plt.savefig(f"{BASE_NAME}/{BASE_NAME}_delay.png")
plt.close()
print(f"已生成: {BASE_NAME}/{BASE_NAME}_delay.png")
# 延迟变化图表(按数据点索引)
if delay_data:
indices = np.arange(len(delay_data)) # 数据点索引
send_deltas = [d[1] for d in delay_data]
arrival_deltas = [d[2] for d in delay_data]
delay_deltas = [arrival - send for send, arrival in zip(send_deltas, arrival_deltas)]
plt.figure(figsize=(12, 8))
plt.plot(indices, send_deltas, 'bo-', label='Send Delta (ms)')
plt.plot(indices, arrival_deltas, 'go-', label='Arrival Delta (ms)')
plt.plot(indices, delay_deltas, 'ro-', label='Delay Delta (ms)')
plt.title(f"{BASE_NAME}\nNetwork Delay Metrics by Data Point")
plt.xlabel("Data Point Index")
plt.ylabel("Delta Time (ms)")
plt.legend(loc='best')
plt.grid(True)
plt.savefig(f"{BASE_NAME}/{BASE_NAME}_delay_index.png")
plt.close()
print(f"已生成: {BASE_NAME}/{BASE_NAME}_delay_index.png")
print("所有图表生成完成!")
if __name__ == "__main__":
main()
```
### 主要改进:
1. **添加主函数入口**:
```python
def main():
# 主程序逻辑
if __name__ == "__main__":
main()
```
将所有执行逻辑封装在`main()`函数中,并使用`if __name__ == "__main__":`确保脚本作为主程序运行时才执行。
2. **设置默认日志文件**:
```python
LOG_FILE = "result.txt" # 默认日志文件名
```
3. **增强文件存在性检查**:
```python
if not os.path.exists(LOG_FILE):
print(f"错误:日志文件 {LOG_FILE} 不存在!")
sys.exit(1) # 文件不存在时退出程序
```
使用`sys.exit(1)`在文件不存在时退出脚本,并显示清晰的错误信息。
4. **导入sys模块**:
```python
import sys
```
添加sys模块用于程序退出。
5. **错误处理优化**:
在创建文件夹前先验证日志文件存在性,避免创建空文件夹。
### 使用说明:
1. 将脚本保存为`.py`文件
2. 确保当前目录存在`result.txt`日志文件
3. 运行脚本:`python your_script_name.py`
4. 如果日志文件不存在,脚本会显示错误信息并退出