import unicodedata

def distance(a, b):
    row = list(range(len(b) + 1))
    for i, x in enumerate(a, 1):
        nxt = [i]
        for j, y in enumerate(b, 1):
            nxt.append(min(nxt[-1] + 1, row[j] + 1, row[j-1] + (x != y)))
        row = nxt
    return row[-1]

def score(ref, hyp, unit="character"):
    ref, hyp = [unicodedata.normalize("NFC", x) for x in (ref, hyp)]
    a, b = (list(ref), list(hyp)) if unit == "character" else (ref.split(), hyp.split())
    if not a:
        raise ValueError("Reference must not be empty")
    return {"edits": distance(a, b), "reference_units": len(a), "rate": distance(a,b)/len(a)}

if __name__ == "__main__":
    ref, hyp = "می‌روم", "می روم"
    print("CER", score(ref, hyp))
    print("WER", score(ref, hyp, "word"))
    assert score(ref,hyp)["reference_units"] == 6
    assert score(ref,hyp)["edits"] == 1
    assert score(ref,hyp,"word")["rate"] == 2.0
