I recently got the request of converting a Python result a user had created to an extension.
Why would you want to do that? Well, simply to more easily share your work with your colleagues. The Python Result can be used to create a prototype of a specific post-processing, but might be harder to share, especially if you have details properties associated to it.
Below I'm showing you how to go from one to the other, with the necessary pieces of code. In this example, the Python Result has two properties: a float input to get the display time and a dropdown with a list of named selections to choose from. It will then display the deformation on the selection at the specified time - nothing complex, but that's not the purpose of this discussion. Also, the Python Result has two additional properties to provide the mean and maximum value of the result being displayed.

Let's start with the Python Results' property provider where you define the properties to be shown in the details view. This is the code you would put under the "Property Provider" tab of your Python Result.
def reload_props():
this.PropertyProvider = None
# comment the following return to allow the rest of the function definition to be executed and add properties
# return
"""
Some sample code is provided below that shows how to:
1. Create an instance of the Provider. The Provider class is used to add custom properties to the details.
2. Use the Provider instance to add custom properties.
3. Configure those custom properties.
"""
# Create the property instance
provider = Provider()
# Create a group named Group 1.
group = provider.AddGroup("My Properties")
# Create a property with control type Expression and a property with control type Double, and add it to the Group 1
# Property for seleciton of a time value
time_prop = group.AddProperty("Display Time", Control.Double)
# DropDown to select a named selection
selection_prop = group.AddProperty("Named selection", Control.Options)
# Retrieve all named selections
# Fill the dropdown with the list of named selections
all_named_sel=DataModel.GetObjectsByType(DataModelObjectCategory.NamedSelection)
ns_list={}
idx=1
for ns in all_named_sel:
ns_list[idx]=ns.Name
idx+=1
selection_prop.Options = ns_list
# Second group for some results
group2 = provider.AddGroup("My Results")
# Mean value
mean_prop = group2.AddProperty("Mean value", Control.Double)
mean_prop.ParameterType = ParameterType.Output
# Maximum value
max_prop = group2.AddProperty("Maximum value", Control.Double)
max_prop.ParameterType = ParameterType.Output
# Connects the provider instance back to the object by setting the PropertyProvider member on this, 'this' being the
# current instance of the Python Code object.
this.PropertyProvider = provider
And here's the script part of the Python Result:
def post_started(sender, analysis):# Do not edit this line
define_dpf_workflow(analysis)
# Uncomment this function to enable retrieving results from the table/chart
# def table_retrieve_result(value):# Do not edit this line
# import mech_dpf
# import Ans.DataProcessing as dpf
# wf = dpf.Workflow(this.WorkflowId)
# wf.Connect('contour_selector', value)
# this.Evaluate()
def define_dpf_workflow(analysis):
import mech_dpf
import Ans.DataProcessing as dpf
mech_dpf.setExtAPI(ExtAPI)
dataSource = dpf.DataSources(analysis.ResultFileName)
u = dpf.operators.result.displacement()
nrm = dpf.operators.math.norm_fc(u)
# Get properties
time=float(this.GetCustomPropertyByPath("My Properties/Display Time").Value)
selection_name=this.GetCustomPropertyByPath("My Properties/Named selection").ValueString
# Get selection corresponding to user choice
if selection_name!='':
scoping_op=dpf.operators.scoping.on_named_selection(data_sources=dataSource,named_selection_name=selection_name.ToUpper())
scoping=scoping_op.outputs.getmesh_scoping()
u.inputs.mesh_scoping.Connect(scoping)
u.inputs.data_sources.Connect(dataSource)
u.inputs.time_scoping.Connect(time)
# Set output results
max=dpf.operators.min_max.min_max(nrm)
maxval=max.outputs.getfield_max().Data[0]
nrmdata=nrm.outputs.getfields_container()[0].Data
mean=sum(list(nrmdata))/len(nrmdata)
this.GetCustomPropertyByPath("My Results/Mean value").Value=mean
this.GetCustomPropertyByPath("My Results/Maximum value").Value=maxval
dpf_workflow = dpf.Workflow()
dpf_workflow.Add(u)
dpf_workflow.Add(nrm)
# dpf_workflow.SetInputName(u, 0, 'time')
# dpf_workflow.Connect('time', timeScop)
dpf_workflow.SetOutputContour(nrm)
dpf_workflow.Record('wf_id', False)
this.WorkflowId = dpf_workflow.GetRecordedId()
Now read the next comment to see how this is transformed into an ACT extension.