Color Audit

import re
from Spotfire.Dxp.Application.Visuals import *
search_for_expression = "<[Actual Sequence of Treatment]>"
replace_with_expression = "<${DSEbyGrp}>"
def setColoringExpression(visual, visualTypeId):
    try:
        vc = visual.As[VisualContent]()
        if vc is not None and hasattr(vc, "ColorAxis") and vc.ColorAxis is not None:
            color_axis_name = "Color By"
            expr_before = vc.ColorAxis.Expression
            expr_after = expr_before
            if expr_before and re.search(re.escape(search_for_expression), expr_before, re.IGNORECASE):
                expr_after = re.sub(re.escape(search_for_expression), replace_with_expression, expr_before, flags=re.IGNORECASE)
                vc.ColorAxis.Expression = expr_after
                expr_after = vc.ColorAxis.Expression
            return color_axis_name, expr_before if expr_before else "None", expr_after if expr_after else "None"   
        return "N/A", "Color By not supported", "Color By not supported"
    except Exception as ex:
        return "Error", "Exception: {}".format(str(ex)), "Exception: {}".format(str(ex))
captured_data = []
headers = [
    "Page", 
    "Visualization Name", 
    "Visualization TypeID", 
    "Color Axis Name", 
    "Color Axis Expression (Before)", 
    "Color Axis Expression (After)"
]
for page in Document.Pages:
    for visual in page.Visuals:
        color_axis_name, expr_before, expr_after = setColoringExpression(visual, visual.TypeId)
        captured_data.append((
            page.Title,
            visual.Title,
            visual.TypeId.Name,
            color_axis_name,
            expr_before,
            expr_after
        ))
print("{}\t{}\t{}\t{}\t{}\t{}".format(*headers))
for row in captured_data:
    p_name = row[0]
    v_name = row[1]
    t_name = row[2].split(".")[-1]
    c_name = row[3]
    c_before = row[4]
    c_after = row[5]
    print("{}\t{}\t{}\t{}\t{}\t{}".format(p_name, v_name, t_name, c_name, c_before, c_after))