Use Effort Calculator variables in a Forward Path scenario

Aug 14, 2017

This topic provides an introduction to the use of the Effort Calculator variables in your Forward Path scenario. This topic uses an example to introduce the use of these features.

About the Effort Calculator variables

Effort Calculator estimates the cost and effort involved in remediating your application portfolio for a target platform (represented by one of the AppDNA reports). The calculation uses two main types of variables:

  • User-defined variables – These store values such as how much a tester, remediator, and project manager cost per day, the number of hours in a typical working day, how long it takes on average to remediate applications of different complexities (simple, normal, and complex), taking into account the difficulty of the remediation action (easy, medium, or hard). You can set these variables separately for each AppDNA report in the Effort Calculator screen.
  • Application-level variables – These are derived from the AppDNA analysis and include the complexity of the application (this is based on the number of files and registry entries the application has), and the difficulty (or complexity) of the actions that need to be taken to remediate the application for the selected report.

Using this information Effort Calculator estimates the expected cost of migrating the entire application portfolio to the new platform. You can now use these variables in your Forward Path scenario – for example, to estimate the cost of remediating each application. This topic provides a relatively simple example of how to do this. One of the sample scenarios that comes with AppDNA provides a more complex and sophisticated example.

For detailed information about the Effort Calculator variables and how they are used, see Effort Calculator.

Retrieving the user-defined Effort Calculator variables

You can access the user-defined Effort Calculator variables through the EffortCalculatorSettings object, which you retrieve through the Host object. The Host object is implicitly available to the entire scenario script. Here is a snippet that retrieves the EffortCalculatorSettings object for the Windows 7 report:

``` pre codeblock Private Dim vars As EffortCalculatorSettings

’ Get the Windows 7 Effort Calculator settings object. vars = Host.GetEffortCalculatorSettings(“Win7Module”)


Notice that we have used the Windows 7 internal report identifier to retrieve the Effort Calculator variables for Windows 7. For a list of the report identifiers, see [Create links to remediation report views](/en-us/dna/7-15/configure/forward-path/dna-forward-path-remediation-links.html).

You can see all of the properties of the EffortCalculatorSettings object in the Property Explorer on the right side of the [Forward Path Logic Editor screen](/en-us/dna/7-15/configure/forward-path/dna-forward-path-logic-editor.html). The names of the properties closely relate to the text shown for the variables in the Effort Calculator screen. For example, the AppStagingHours property corresponds to the Staging time variable in the Staffing variables section of the Effort Calculator screen. We will use this variable in the example that follows.

It is possible to set the values of these variables in your scenario for use in that scenario, like this:

``` pre codeblock
vars.TesterStagerCostPerDay = 23

Note: This does not change or overwrite the variables that Effort Calculator uses.

About the example

To illustrate how to use the two types of Effort Calculator variables to calculate the estimated costs of remediating applications in your Forward Path scenario, we will walk through an example scenario. We will build it up in stages, in an attempt to make it easy to understand.

Here is a screenshot of the output the example creates:

Note: The examples in this topic use the underscore (_) notation to break long lines into two or more lines. This is so that the example code snippets render correctly when included in a PDF. See the MSDN Library for more on this notation.

Initialize the variables

AppDNA includes a Forward Path scenario function called Initialize(). If present in the scenario, AppDNA automatically calls this at the start of the processing. We will use this to initialize variables that we will use later in the scenario. For more information about the Initialize() function, see Grouped Forward Path reports.

Before the Initialize() function, we declare some variables that we will use throughout the script.

``` pre codeblock ‘ Declare variables for use throughout the script. Private Dim vars As EffortCalculatorSettings Private Dim testingPerHour As Decimal = 0 Private Dim remediationPerHour As Decimal = 0


Here is the Initialize() function:

``` pre codeblock
Public Overrides Sub Initialize()

   ' Get the Windows 7 Effort Calculator settings object.
   vars = Host.GetEffortCalculatorSettings("Win7Module")

   ' Calculate the testing and remediation cost per hour.
   testingPerHour = vars.TesterStagerCostPerDay / _
      vars.NormalAppTestingHours
   remediationPerHour = vars.RemediatorCostPerDay / _
      vars.NormalAppTestingHours

   ' Sort the report in descending order of cost.
   Settings.ApplicationSortBy = "Cost"
   Settings.ApplicationSortDescending = true
End Sub

Notice that we are calculating the hourly testing and remediation costs. We do this by dividing the values stored in the variables that represent the tester or remediator cost per day by the value stored in the normal number of working hours in a day variable.

At the end of the Initialize() function, we set the sort order to be in descending order of the values in the Cost column. In this column we will display the calculated cost of remediating the application and staging it for UAT.

The main function

Here is the main ForwardPath() function. AppDNA automatically calls this once for every application that is selected when you run the report. Explanatory notes follow the example.

``` pre codeblock Public Function ForwardPath(ByVal currentApplication _ As Application) As Output

Dim result As New Output()

’ We will use three custom columns. result.CustomField1.Name = “Application Complexity” result.CustomField2.Name = “Action RAG” result.CustomField2.Value = _ currentApplication.Modules.Windows7.ActionRAG result.CustomField3.Name = “Action Complexity”

’ Set the culture on the Cost column to US English, ‘ so that the US dollar currency symbol is used. result.Display.Cost.Culture = “en-US”

’ Test the application’s main RAG status, because ‘ the remediation depends on this. Select Case currentApplication.Modules.Windows7.RAG

  Case Rag.Green

     ' The RAG is green, so no remediation is necessary
     ' and the application can be staged for UAT.
     result.Outcome = "Stage UAT"
     result.RAG = RAG.Green

     ' No remediation is required, so the cost is of
     ' the staging only.
     result.Cost = testingPerHour * vars.AppStagingHours
     result.CustomField3.Value = "--"

     ' Convert the unfriendly application complexity
     ' "RAG" to a text.
     Select Case currentApplication.Complexity
        Case RAG.Red
           result.CustomField1.Value = "Complex"
        Case RAG.Amber
           result.CustomField1.Value = "Medium"
        Case RAG.Green
           result.CustomField1.Value = "Simple"
     End Select

  Case Rag.Amber

     ' The RAG is amber, so the application needs
     ' remediation.
     result.RAG = RAG.Amber
     result.Outcome = "Remediate"

     ' The cost calculation is more complicated,
     ' so we will do it in a separate "GetCost()"
     ' function.
     result.Cost = GetCost(currentApplication, result)

  Case Rag.Red

     ' The RAG is red - we need to check the action
     ' RAG to see if remdiation is possible.
     result.RAG = RAG.Red

     ' If the action RAG is red, the application
     ' cannot be remediated.
     If (currentApplication.Modules.Windows7.ActionRAG = _
        RAG.Red) Then

        result.Outcome = "Redevelop"
        result.CustomField3.Value = "Hard"

        ' Convert the unfriendly application complexity
        ' "RAG" to a text and set an arbitrary
        ' replacement/redevelopment cost.
        Select Case currentApplication.Complexity
           Case RAG.Red
              result.CustomField1.Value = "Complex"
              result.Cost = 3000
           Case RAG.Amber
              result.CustomField1.Value = "Medium"
              result.Cost = 2000
           Case RAG.Green
              result.CustomField1.Value = "Simple"
              result.Cost = 1000
        End Select

     ' The action RAG is not red, so remediation is
     ' possible.
     Else
        result.Outcome = "Remediate"
        result.Cost = GetCost(currentApplication, result)
     End If

  Case Else

     ' Catch all for applications that have not been
     ' analyzed or that are locked.
     result.Outcome = "Unknown"
     result.RAG = RAG.Unknown
     result.CustomField1.Value = "--"
     result.CustomField3.Value = "--"
     result.Cost = 0

End Select

result.Display.SourcePath.Visible = false

ForwardPath = result

End Function


Notice that this function starts by setting up three custom columns (called CustomFieldn) – these are the three right-most columns in the screenshot of the output above. We use these as follows:

| Column       | Displays                                                                                                                                                   |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| CustomField1 | The application complexity. Forward Path stores this as a red/amber/green "RAG". We translate these values into Complex/Medium/Simple texts in the script. |
| CustomField2 | The application's action RAG. We get the value using the Application.Modules.Windows7.ActionRAG property.                                                  |
| CustomField3 | The complexity/difficulty of the application's remediation action. We will retrieve the value for this column later in the script.                         |

The Cost column is automatically displayed in currency format. By default, Forward Path uses the currency symbol for the regional settings on the user's computer. In an international environment, this means that the currency symbol may vary depending on the settings on the device of the person viewing the report. (For example, it might display the euro sign for a user in France, the UK pound sign for a user in England, and the US dollar sign for a user in the United States.) In this example, we will therefore specify the US dollar symbol so that this will always be displayed regardless of the user's regional settings. To do this, we set the Culture property on the Cost column to "en-US", which indicates the United States.

The main body of the function consists of a Select Case statement that tests the application's Windows 7 RAG status and provides different processing depending on that status. Let's look at how we handle each value:

-  **Green RAG** – The application can go straight to UAC. So we calculate the cost of staging the application by multiplying the cost of testing per hour (which we calculated in Initialize()) by the Effort Calculator variable that stores the number of hours it takes to stage an application for testing. We set the action complexity to "--" because remediation is not necessary, and we use another Select Case statement to test the application's complexity and convert the unfriendly "RAG" value into a text.
-  **Amber RAG** – The application needs remediation. We call the GetCost() function to calculate the remediation cost. We will look at this shortly.
-  **Red RAG** – We first test the action RAG. If it is red, it means that the application cannot be remediated and needs to be redeveloped or replaced. We then use a Select Case statement to test the application complexity like we did for the green RAG. However, this time we set an arbitrary replacement cost based on the complexity of the application. For applications that can be remediated (that is, their action RAG is green or amber), we call the GetCost() function to calculate the remediation cost.
-  **Other RAG values** – We handle all other RAG values by using a Case Else statement. This will handle applications that have not been analyzed and those that are locked (unlicensed).

## Calculate the remediation cost

Here is the GetCost() function, which we called in the main function to calculate the remediation costs of amber applications and red ones that can be remediated. Explanatory notes follow the example.

``` pre codeblock
Private Function GetCost(app As Application, _
   cols As Output) As Decimal

   Dim remediationCost As Decimal = 0
   Dim testingCost As Decimal = 0

   ' 1. Using the triggered algorithms, get the
   ' algorithm with the hardest action. We will use this
   ' in our calculations.
   Dim maxAlgorithm As TriggeredRule = _
      (From r in app.TriggeredRules _
      Where r.ModuleIdentifier = "Win7Module" _
      Where r.Action.Complexity = ActionComplexity.Hard Or _
      r.Action.Complexity = ActionComplexity.Medium Or _
      r.Action.Complexity = ActionComplexity.Easy _
      Order By r.Action.Complexity Descending _
      Select r).FirstOrDefault()

   ' 2. Display the algorithm's action complexity.
   cols.CustomField3.Value = maxAlgorithm.Action.Complexity

   ' 3. The remediation cost depends on the application
   ' complexity.
   Select Case app.Complexity

      ' A complex application.
      Case RAG.Red

         cols.CustomField1.Value = "Complex"

         ' The remediation cost also depends on
         ' the complexity of the action. So we will
         ' calculate the time based on the number of
         ' hours held in the Effort Calculator matrix.
         Select Case maxAlgorithm.Action.Complexity
            Case ActionComplexity.Easy
               remediationCost = remediationPerHour * _
                  vars.ComplexAppEasyRemediationHours
            Case ActionComplexity.Medium
               remediationCost = remediationPerHour * _
                  vars.ComplexAppMediumRemediationHours
            Case ActionComplexity.Hard
               remediationCost = remediationPerHour * _
                  vars.ComplexAppHardRemediationHours
            Case Else
               remediationCost = remediationPerHour * _
                  vars.ComplexAppMediumRemediationHours
         End Select

         If app.Modules.Windows7.ActionRAG = RAG.Amber Then

            ' Add the additional post-remediation testing
            ' because the application has an amber action RAG.
            testingCost = testingPerHour * _
               vars.ComplexAppTestingHours

         End If

      ' A medium-complexity application.
      Case RAG.Amber

         cols.CustomField1.Value = "Medium"

         Select Case maxAlgorithm.Action.Complexity
            Case ActionComplexity.Easy
               remediationCost = remediationPerHour * _
                  vars.NormalAppEasyRemediationHours
            Case ActionComplexity.Medium
               remediationCost = remediationPerHour * _
                  vars.NormalAppMediumRemediationHours
            Case ActionComplexity.Hard
               remediationCost = remediationPerHour * _
                  vars.NormalAppHardRemediationHours
            Case Else
               remediationCost = remediationPerHour * _
                  vars.NormalAppMediumRemediationHours
         End Select

         If app.Modules.Windows7.ActionRAG = RAG.Amber Then

            ' Add the additional post-remediation testing
            ' because the application has an amber action RAG.
            testingCost = testingPerHour * _
               vars.NormalAppTestingHours

         End If

      ' A simple application.
      Case RAG.Green

         cols.CustomField1.Value = "Simple"

         Select Case maxAlgorithm.Action.Complexity
            Case ActionComplexity.Easy
               remediationCost = remediationPerHour * _
                  vars.SimpleAppEasyRemediationHours
            Case ActionComplexity.Medium
               remediationCost = remediationPerHour * _
                  vars.SimpleAppMediumRemediationHours
            Case ActionComplexity.Hard
               remediationCost = remediationPerHour * _
                  vars.SimpleAppHardRemediationHours
            Case Else
               remediationCost = remediationPerHour * _
                  vars.SimpleAppMediumRemediationHours
         End Select

         If app.Modules.Windows7.ActionRAG = RAG.Amber Then

            ' Add the additional post-remediation testing
            ' because the application has an amber action RAG.
            testingCost = testingPerHour * _
               vars.SimpleAppTestingHours

         End If

   End Select

   ' 4. Add the remediation and testing costs,
   ' and the cost of staging for UAT.
   GetCost = remediationCost + testingCost + _
      (testingPerHour * vars.AppStagingHours)

End Function

The following notes relate to the numbers in the comments in the above example:

1. We use the current application’s Windows 7 TriggeredRules property. This property is a collection of TriggeredRule objects, which represent all of the algorithms that the application triggered during analysis for Windows 7. From this collection, we get the algorithm that has the hardest remediation action. We will use this to calculate the cost of remediating the application.

2. We display the complexity (difficulty) of the algorithm’s remediation action in CustomField3.

3. We then use a Select Case statement again to test the application’s complexity. We will provide different processing for each complexity. Let’s look at how we handle a complex application:

  • First we use another Select Case statement to test the complexity (difficulty) of the action associated with the algorithm we retrieved in step 1. Then for each of the possible action complexities, we calculate the remediation cost by multiplying the remediation cost per hour (calculated in Initialize()) by the Effort Calculator variable that represents the time it takes to remediate a complex application of the corresponding action complexity.
  • We then check whether the action RAG is amber – because this means that the application needs additional testing after the remediation has been implemented. If the action RAG is amber, we calculate the testing cost by multiplying the testing cost per hour (calculated in Initialize()) by the Effort Calculator variable that represents the time it takes to test a complex application.

The code for medium-complexity and simple applications mirrors the code for the complex application, but each time we select the Effort Calculator variables for medium and simple applications, respectively.

4. Finally, we add the remediation and testing costs we calculated to the cost of staging the application for UAT and set this into the return value.

For an example that calculates the remediation costs by taking into account the actions associated with all of the algorithms triggered by the application, see the sample scenario that comes with AppDNA.