#! /usr/bin/python3 # Last edited on 2026-02-10 06:51:25 by stolfi # To be included in python progs. from sys import stderr as err, stdout as out from math import inf, sqrt, nan, isnan, isfinite def compute_stats(vals, nact = None): # Compute average and deviation of the list of numbers {vals}. If # {nact} is provided, uses {nact} as the number of entries instead of # {len(vals)}. # Returns # # {vnum} number of entries used in the averages ({nact} if given, else {len(vals)}). # {vtot} sum of all entries. # {vmin} smallest of all entries. # {vsin} second-smallest of all entries. # {vmax} largest of all entries. # {vsax} second-largest of all entries. # {vavg} average of all entries ({vtot/vnum}). # {vdev} standard deviation of all entries. # # Some of these values may be {nan}. vnum = len(vals) if nact == None else nact vmin = nan; vmax = nan; vavg = nan; vdev = nan vsin = nan; vsax = nan if vnum >= 1 and len(vals) >= 1: vtot = 0; vmin = +inf; vsin = +inf vmax = -inf; vsax = -inf for v in vals: if v < vmin: vsin = vmin; vmin = v if v > vmax: vsax = vmax; vmax = v vtot += v vavg = vtot/vnum if vnum >= 2 and len(vals) >= 2: sum_ds2 = 0; for v in vals: ds = v - vavg sum_ds2 += ds*ds vdev = sqrt(sum_ds2/(vnum-1)) return vnum, vtot, vmin, vsin, vmax, vsax, vavg, vdev # ---------------------------------------------------------------------- def print_stats(title, vnum, vtot, vmin, vsin, vmax, vsax, vavg, vdev): # Prints the given stats to {stderr}. # Ignores any that are {nan} or {None}. err.write("::: statistics of %s :::\n" % title) err.write(f"{vnum:7.2f} values assumed\n") if vtot != None and isfinite(vtot): err.write(f"{vtot:7d} total\n") if vmin != None and isfinite(vmin): err.write(f"{vmin:7d} smallest\n") if vsin != None and isfinite(vsin): err.write(f"{vsin:7d} second smallest\n") if vmax != None and isfinite(vmax): err.write(f"{vmax:7d} largest\n") if vsax != None and isfinite(vsax): err.write(f"{vsax:7d} second largest\n") if vavg != None and isfinite(vavg): err.write(f"{vavg:7.2f} average\n") if vdev != None and isfinite(vdev): err.write(f"{vdev:7.2f} deviation\n") err.write(":::::::::::::::::::::::::::::::::::::::::::\n") return # ---------------------------------------------------------------------- def compute_and_print_stats(title, vals, nact = None): # Same as {compute_stats}, but prints the stats to {stderr} # before returning them. vnum, vtot, vmin, vsin, vmax, vsax, vavg, vdev = compute_stats(vals, nact) print_stats(title, vnum, vtot, vmin, vsin, vmax, vsax, vavg, vdev) return vnum, vtot, vmin, vsin, vmax, vsax, vavg, vdev # ----------------------------------------------------------------------