Extract list of features from element

Hi Sensmetry team,

I’m currently using evaluate_feature to compute values on a model element, for example:

santa_sleigh = find_element_by_name(model, "SantaSleigh")
reindeer_count = evaluate_feature(santa_sleigh["reindeerCount"], santa_sleigh)
total_power = evaluate_feature(santa_sleigh["totalPower"], santa_sleigh)
average_power = evaluate_feature(santa_sleigh["averagePower"], santa_sleigh)

This works, but it requires hardcoding feature names. I’d like to make this more dynamic by iterating over all available features on the element instead of explicitly referencing "reindeerCount", "totalPower", etc.

From the documentation, I see references to things like features, ownedFeatures, and similar properties, but I’m not sure which of these corresponds to what is accessible via:

santa_sleigh["reindeerCount"]

Specifically:

  • Which collection (e.g., features, ownedFeatures, or something else) contains the features that can be accessed via element["featureName"]?

  • What is the recommended way to iterate over all such features programmatically and pass them into evaluate_feature?

  • Is there a way to filter only evaluable features (e.g., value properties or computed features) versus other feature types?

An example of iterating over features and evaluating them would be very helpful.

Thanks,
Dat

Which collection (e.g., features, ownedFeatures, or something else) contains the features that can be accessed via element["featureName"]?

Subscript operator only retrieves owned members. Type.owned_features will be the most similar property, otherwise Type.features includes also inherited features.

What is the recommended way to iterate over all such features programmatically and pass them into evaluate_feature?

Use .collect() to iterate over lazy accessors, e.g. for feature in type.owned_features.collect(): ....

Is there a way to filter only evaluable features (e.g., value properties or computed features) versus other feature types?

You probably want to just check if a feature has a feature value using Feature.feature_value_expression:

for feature in type.owned_features.collect():
  if expr := feature.feature_value_expression:
     # do something with expr, e.g.
     value = compiler.evaluate(expr, scope=type, stdlib=Environment.get_default().lib)

If you are evaluating owned features, there is no reason to use Compiler.evaluate_feature, Compiler.evaluate will be equivalent without an additional feature lookup required. evaluate_feature is only required for evaluating features in scopes other than their owning_types.