import math

def ratio(processing_seconds,audio_seconds):
    if not all(math.isfinite(x) and x>0 for x in (processing_seconds,audio_seconds)):
        raise ValueError("Both durations must be finite and positive")
    return {"rtf":processing_seconds/audio_seconds,"rtfx":audio_seconds/processing_seconds}

def pooled(records):
    for processing,audio in records:ratio(processing,audio)
    return ratio(sum(x[0] for x in records),sum(x[1] for x in records))

if __name__ == "__main__":
    rows=[(2.0,10.0),(90.0,100.0)]
    print("sample",ratio(30,120))
    print("pooled",pooled(rows))
    print("mean_file_rtf",sum(ratio(p,a)["rtf"] for p,a in rows)/len(rows))
    assert ratio(30,120)=={"rtf":0.25,"rtfx":4.0}
    assert abs(pooled(rows)["rtf"]-92/110)<1e-12
    for bad in (0,-1,float("nan"),float("inf")):
        try:ratio(bad,10)
        except ValueError:pass
        else:raise AssertionError("Bad duration accepted")
