0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonで商談メモ4版から最新版を選び、変更1か所を表示

0
Posted at

架空の商談メモ4版を並べたら、v10より後ろにv9が来た。この順で「最新版」を選ぶ処理は危ない。

僕なら版番号を整数に直します。v9とv10を選び、回答期限の変更1か所を取り出せました。

Pythonで版番号を取り出す

sorted()で名前を並べると、共通部分の次の文字で順序が決まります。v10の数字は1から始まるので、v2やv9より前。版の順番には使えません。

名前は商談メモ_v1.txtの形式。番号は1以上、先頭のゼロは禁止。欠番があれば、残った中で番号が大きい2版を選びます。

「最終」「最終修正」は、どちらが後か名前だけでは決まりません。

4版から直前との差分を出す

CPython 3.14.6で実行済み。下をmemo_diff.pyに保存し、python3 memo_diff.pyで動きます。見本はメモリ内に置きます。

import re
from difflib import unified_diff

def version(name):
    m = re.fullmatch(r"商談メモ_v([1-9][0-9]*)\.txt", name)
    if m is None:
        raise ValueError(f"版番号を読めません: {name}")
    return int(m[1])

def compare(files):
    names = sorted(files, key=version)
    if len(names) < 2:
        raise ValueError("比較には2版以上必要です")
    old, new = names[-2:]
    diff = list(unified_diff(
        files[old].splitlines(), files[new].splitlines(),
        fromfile=old, tofile=new, n=0, lineterm="",
    ))
    return names, diff

files = {
    "商談メモ_v1.txt": "回答期限: 未定\n担当: 佐藤\n",
    "商談メモ_v2.txt": "回答期限: 9月25日\n担当: 佐藤\n",
    "商談メモ_v9.txt": "回答期限: 9月25日\n担当: 田中\n",
    "商談メモ_v10.txt": "回答期限: 9月28日\n担当: 田中\n",
}
names, diff = compare(files)
assert sorted(files)[-1] == "商談メモ_v9.txt"
assert [version(n) for n in names] == [1, 2, 9, 10]
assert diff == [
    "--- 商談メモ_v9.txt", "+++ 商談メモ_v10.txt",
    "@@ -1 +1 @@", "-回答期限: 9月25日", "+回答期限: 9月28日",
]
print("\n".join(diff))

出力は5行。3つのassertも通りました。

--- 商談メモ_v9.txt
+++ 商談メモ_v10.txt
@@ -1 +1 @@
-回答期限: 9月25日
+回答期限: 9月28日

---と+++は版の名前、@@ -1 +1 @@は両方の1行目を示します。-が変更前、+が変更後。2行で1か所の書き換えです。

担当者はv2からv9で変わっています。今回比べたv9とv10では同じなので出ません。直前からの変更だけを読むなら、この切り分けが助かります。

商談メモの版番号を整数として並べ、v9とv10の回答期限の変更だけを表示する流れ

行を整えすぎると変更が消える

n=0で周辺の同じ行を省きます。splitlines()で行末を外したため、差分の見出しにも改行を足さないlineterm=""を指定。CPython同梱のdifflib.unified_diffのdocstringと実装で確認しました。

LFとCRLF、末尾改行の有無は区別しません。空白の削除や本文の並べ替えはせず、字下げや行順の変更は残します。短いテキストメモ向けで、WordやPDFは直接読めません。

実ファイルでは、上のfiles = {以降を次に置き換えます。作業フォルダ内のmemosに、同じ商談のUTF-8テキストを2版以上入れます。

from pathlib import Path

files = {
    p.name: p.read_text(encoding="utf-8-sig")
    for p in Path("memos").glob("商談メモ_*") if p.is_file()
}
names, diff = compare(files)
print(f"比較: {names[-2]} → {names[-1]}")
print("\n".join(diff) if diff else "本文の差分なし")

商談メモ_最終.txtはValueErrorで止まります。黙って除外すると比較対象の抜けに気づけません。v01やバックアップ名の拒否も確認済みです。

桁が増えてもこの手順を使えます。ただし、最大の版が承認済みかは別に確認が必要です。送付前に直前との差分を出し、変更を読むところまで使う。参考になればストックで教えてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?