How to calculate mean twist of a curve?
I figured it out. I made a FloatProperty and put the function I was going to write as the update:

bpy.types.Curve.mean_twist = FloatProperty(name='Mean Twist', step=10.0, default=mean, unit='ROTATION', update=get_twist)


Then I wrote the function which got the average tilt of all the points, subtracted that from the floatproperty to get the difference after the change, and added that to all the tilts: tilt + (floatproperty-averagetilt)

def get_twist(self, context):
    cur = bpy.context.active_object.data
    points = cur.splines.active.bezier_points
    rot = cur.mean_twist
    tilts = [p.tilt for p in points]
    mean = sum(tilts)/len(points)
    new_twist = [t + rot - mean for t in tilts]
    points.foreach_set('tilt', new_twist)


Then I just added the float property to a panel as a slider. It changes the actual mean twist and works in Object mode.