TestTranslator / lib /utils.py
yujuanqin's picture
update scripts
42742c6
import csv
from datetime import datetime
import subprocess
from subprocess import CompletedProcess
from typing import Literal
import re
import time
import difflib
from functools import wraps
from pathlib import Path
import textdistance
import numpy as np
import soundfile as sf
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.perf_counter()
result = func(*args, **kwargs) # 执行原函数
end_time = time.perf_counter()
run_time = end_time - start_time
print(f"函数 {func.__name__!r} 执行耗时: {run_time:.4f} 秒")
return result
return wrapper
class Timer:
def __init__(self, log=""):
self.log = log
def __enter__(self):
self.start = time.perf_counter()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
end = time.perf_counter()
self.duration = end - self.start
print(f"{self.log} cost: {self.duration:.4f} 秒")
def get_time_str(level:Literal["d","s","ms"]="d"):
time = datetime.now()
if level == "d":
return time.strftime("%Y-%m-%d")
if level == "s":
return time.strftime("%H%M%S")
if level == "ms":
return time.strftime("%H%M%S.%f")
def save_csv(file_path, header, rows):
with open(file_path, "w", encoding="utf-8", newline="") as f:
writer = csv.writer(f)
if header:
writer.writerow(header)
writer.writerows(rows)
print(f"write csv to {file_path}")
def cmd(command: str, check=True, capture_output=False) -> CompletedProcess:
print(command)
if capture_output:
ret = subprocess.run(command, shell=True, check=check, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
universal_newlines=True)
else:
ret = subprocess.run(command, shell=True, check=check)
print(ret.stdout)
return ret
import cn2an
def clean_text_for_comparison_zh(text):
"""移除中文标点,并把所有数字都转换成中文的形式"""
symbol_pattern = "[ ,。、!?::‘’-《》!?;,\n]"
to = ""
text = re.sub(symbol_pattern, to, text).lower()
if re.search(r"\d", text):
text = cn2an.transform(text, "an2cn")
return text
def clean_text_for_comparison_en(text):
symbol_pattern = "[,.\n]"
to = ""
return re.sub(symbol_pattern, to, text).lower()
def run_textdistance(text1, text2):
d = textdistance.levenshtein.distance(text1, text2)
nd = d / len(text1)
# print("Levenshtein distance of texts:", d, "normalized distance is:", nd)
return d, nd
def highlight_diff(a, b, spliter=""):
if spliter:
a = a.split(spliter)
b = b.split(spliter)
matcher = difflib.SequenceMatcher(None, a, b)
output = []
for tag, a_start, a_end, b_start, b_end in matcher.get_opcodes():
if tag == 'equal':
output.append(spliter.join(a[a_start:a_end]))
elif tag == 'delete':
deleted = spliter.join(a[a_start:a_end])
output.append(f"[-{deleted}-]")
elif tag == 'insert':
inserted = spliter.join(b[b_start:b_end])
output.append(f"{{+{inserted}+}}")
elif tag == 'replace':
deleted = spliter.join(a[a_start:a_end])
inserted = spliter.join(b[b_start:b_end])
output.append(f"[-{deleted}-]{{+{inserted}+}}")
return spliter.join(output)
def time_to_float(s: str):
if d := s.replace("s", ""):
return float(d)
return 0.0
def read_audio(file:Path)->np.ndarray:
audio, sr = sf.read(file)
if sr != 16000:
raise ValueError(f"只支持 16k 采样率的音频,当前采样率为 {sr}")
return audio.astype(np.float32)
def write_audio(file:Path, audio:np.ndarray, sr=16000):
sf.write(file, audio, sr)
print(f"写入音频文件 {file}")
if __name__ == '__main__':
with Timer() as duration_b:
print("开始操作 B...")
time.sleep(0.4)
print(duration_b.duration)
with Timer("C") as duration_b:
print("开始操作 C...")
time.sleep(0.5)
print(duration_b.duration)