Requirement Volatility - how to get it?

I have been asked to find a way to measure the volatility of requirements for the program. This volatility would be based upon the following:

Requirement Volatility = Total number of requirements changed after review closure



Total number of requirements changed before review
I wonder if anyone knows a way to accomplishment this?

thanks for your help!
DOORSUser - Mon Jan 25 16:20:12 EST 2010

Re: Requirement Volatility - how to get it?
llandale - Mon Jan 25 17:22:06 EST 2010

I think this says:

ReqVolatility = (#Reqs Changed After Review)/(#Reqs changed before Review).


Are you really wanting to know the number of changes to requirements: if you change a single requirement 5 times, is that "5" (# changes) or just "1" (# changed requirements)? Are you really wanting to divide by the total number of requirements?

Is a 'change' something that changes the meaning of the requirement? Any change to the text of the requirement? Any change to any of a list of important requirements, such as 'IsReq' or 'Test Method'?

Anyway, it gets tricky to plow through History for an Object. You want to ignore non-Requirement objects like Headings and Captions. You probably want to look for Object Delete and Undeletes and History that modifies the Object Text. Ignore History older than some threshold date. If the Threshold is older than the current Baseline, open up relevant Baselines.

Generally, your DXL scripts will report the current state of the Requirements; and you take such output and do manual Excel magic to come up with trends over time.

 

 

  • Louie

 

 

Re: Requirement Volatility - how to get it?
faisal.zahidi@boeing.com - Mon Jan 25 21:19:15 EST 2010

pragma runLim,0

string inFile = "c:/temp/input.txt"
string outFile = "c:/temp/output.txt"

string strModuleName
string strStartDate
string strEndDate

Module m
int totCnt=0 // initialize counters
int newCnt=0
int modCnt=0
int delCnt=0
Object o
Date cd, ld, ed, sd // create, last modified, end, start
Regexp Findshall = regexp "shall" // regular expression to find "shall" in text

Stream input = read inFile
input >> strModuleName
input >> strStartDate
input >> strEndDate

close input

if (exists module strModuleName) {
m = read(strModuleName,false)
showDeletedObjects(true)
ed = strEndDate
sd = strStartDate
Stream out = write outFile

for o in m do {
string text = o."Object Text"
if (Findshall text){ // if "shall" is in the object text
cd = o."Created On"""
ld = o."Last Modified On"
string on = number o ""
if ((on0:0 == "3") && (cd<=ed)) { // if section 3 and created before end date
totCnt++
if (isDeleted(o)) { // if deleted
delCnt++
} else {
if (cd>=sd) newCnt++ // if created after start date
if ((ld>=sd) && (cd<sd)) modCnt++ // if modified, but not created, after start date
}
}
}
}

close m

out << "Total Requirements=" totCnt "\n"
out << "Requirements Changed:Modified=" modCnt "\n"
out << "Requirements Changed:Added=" newCnt "\n"
out << "Requirements Changed:Deleted=" delCnt "\n"
close out
} else {
ack "Module '" strModuleName "' doesn't exist!"
}

Re: Requirement Volatility - how to get it?
SystemAdmin - Tue Jan 26 07:30:02 EST 2010

I developped a script to calculate what we call the "Requirement stability index".
I forster through history and I count (addition+deletions+modifications)/TotalNumberOfObjects per WEEK.
Whenever the same object is changed 20 time in one week, it is counted as one modification. Goal of this time-box is to eleminate "editorial changes" like three history-records just to write a sentence to its end.
I do also differentiate "Requirements only" and "all object" ; you need a convention for that (we have an attribute "Object Type" which can be Req, Info, Heading).
Another important thing is to consider only "official changes", I mean to ignore changes like editing the comment column. I do this by looknig at the attribute property "affects change date" and ignores them if it is not set.

I would be VERY interested to knwow what do you going to do with your "Volatility number", once you have calculated it ?

Re: Requirement Volatility - how to get it?
DOORSUser - Tue Jan 26 14:37:58 EST 2010

Thanks for your replies!

I haven't thought about the situation that one requirement was changed multiple times just for editing purpose. I would have to think about it when implementing the solution.

I will report my progress...

Thanks again!!!

Re: Requirement Volatility - how to get it?
llandale - Tue Jan 26 15:01:21 EST 2010

SystemAdmin - Tue Jan 26 07:30:02 EST 2010
I developped a script to calculate what we call the "Requirement stability index".
I forster through history and I count (addition+deletions+modifications)/TotalNumberOfObjects per WEEK.
Whenever the same object is changed 20 time in one week, it is counted as one modification. Goal of this time-box is to eleminate "editorial changes" like three history-records just to write a sentence to its end.
I do also differentiate "Requirements only" and "all object" ; you need a convention for that (we have an attribute "Object Type" which can be Req, Info, Heading).
Another important thing is to consider only "official changes", I mean to ignore changes like editing the comment column. I do this by looknig at the attribute property "affects change date" and ignores them if it is not set.

I would be VERY interested to knwow what do you going to do with your "Volatility number", once you have calculated it ?

Perhaps ... you could get the Session number from the History, and ignore all history in a session for an object, other than the first one. So if a user edits a module and makes 5 edits to text of an object and closes, then edits the module and makes 3 changes to that same object; it counts as '2'.

  • Louie

Re: Requirement Volatility - how to get it?
ChrisAnnal - Mon Jun 13 16:14:11 EDT 2011

I was wondering if anyone came up with a solution here? The suggested script doesn't actually work, even when a module name is provided and the "input.txt" and "output.txt" files are placed on the C drive. It falls through to the ...ack "Module '"strModuleName"' doesn't exist!" line. This would be great to have, since requirements volatility is a hot topic nowadays.

Chris Annal
SW Test Engineer / DOORS Database Administrator
Sensis Corporation, East Syracuse, New York
chrisa@sensis.com

Re: Requirement Volatility - how to get it?
ChrisAnnal - Mon Jun 13 16:31:21 EDT 2011

ChrisAnnal - Mon Jun 13 16:14:11 EDT 2011
I was wondering if anyone came up with a solution here? The suggested script doesn't actually work, even when a module name is provided and the "input.txt" and "output.txt" files are placed on the C drive. It falls through to the ...ack "Module '"strModuleName"' doesn't exist!" line. This would be great to have, since requirements volatility is a hot topic nowadays.

Chris Annal
SW Test Engineer / DOORS Database Administrator
Sensis Corporation, East Syracuse, New York
chrisa@sensis.com

Never mind. I forgot my input file provides the needed information. For instance:

MyModule
2011, 06 jun
2011, 13 jun

Thanks!!

Chris Annal
SW Test Engineer / DOORS Database Administrator
Sensis Corporation, East Syracuse, New York
chrisa@sensis.com

Re: Requirement Volatility - how to get it?
ChrisAnnal - Fri Jun 17 14:34:49 EDT 2011

ChrisAnnal - Mon Jun 13 16:31:21 EDT 2011
Never mind. I forgot my input file provides the needed information. For instance:

MyModule
2011, 06 jun
2011, 13 jun

Thanks!!

Chris Annal
SW Test Engineer / DOORS Database Administrator
Sensis Corporation, East Syracuse, New York
chrisa@sensis.com

OK. For what it's worth, I put together a script that goes through a module looking for "shall" and counts the objects (Req_Total), then looks for objects that were modified, added, or deleted between two dates (selected by the user in a dialog box).
The script requires the user to have an Excel template file C:\\Temp\\Requirement_Volatility_Metrics.xlt
The reason for the Excel template is just so the user can format and apply headings to the output data as they wish. The data is output to the template at the 2nd row to allow for this.

// Exports Volatility Metrics to the Requirement_Volatility_Metrics.xls file
 
/*
    Volatility Metrics are calculated and then exported to the Requirement_Volatility_Metrics.xls File
        This requires that the Requirement_Volatility_Metrics.xls template file exists so that the export
        can locate it. (Create an empty Excel file for starters).

*/
 
pragma runLim,0
#include <utils/ole.inc>
checkPlatform "Microsoft Excel"
 
const string cMethodOpen                = "Open"
const string columnTitles[] = {"Date","Total_Reqs","Num_Added","Num_Deleted","Num_Modified","Total_Changes"}
const int NumOfTitles = 6
 
 
int Total_Reqs = 0          //Total Requirements = (Object Text CONTAINS 'shall') AND (NOT(Object Text CONTAINS 'DELETE'))) 
int Num_Added = 0                   //Num of added reqs =(((Object Text CONTAINS 'shall') AND (NOT(Object Text CONTAINS 'DELETE'))) AND (Created On > xx/xx/xx) AND (NOT(Allocation is empty)
int Num_Deleted = 0         //Num of deleted reqs = (Object Text CONTAINS "shall") AND (Object Text CONTAINS "DELETE") AND (Last Modified On >= xx/xx/xx)
int Num_Modified = 0        //Num of Changed Reqs = ((Object Text CONTAINS 'shall') AND (NOT(Object Text CONTAINS 'DELETE'))) AND (Last Modified On >= xx/xx/xx) AND (Clarity includes Modified)
int Total_Changes = 0       //Total Number of changes Made within this period
real Volatility = 0.00      //Will be calculated as Total_Changes / Total_Reqs
string dataSheetName = "Sheet1"               //Has the name of the worksheet that will hold the data.
Date DateToTest = "03/04/2005"        //This will be changed when the user inputs the actual date. This is just used as a "default" date.
Date startDate = "02/03/2004"         //This will be changed when the user inputs the actual date. This is just used as a "default" date.
 
//--------------------------------------------------------------
 
OleAutoObj objExcel = null
OleAutoObj objWorkbooks = null
OleAutoObj objWorkbook = null
OleAutoObj objWorksheets = null
OleAutoObj objSheet = null
OleAutoObj objCell = null
OleAutoArgs args   = create
 
//--------------------------------------------------------------
 
Module ThisModule = current
 
//initialize the OLE Application (Excel)
bool excelInit() 
{
        string ExcelFileName = "C:\\Temp\\Requirement_Volatility_Metrics.xlt"
//      print ExcelFileName 
 
        objExcel = connectToApp(cObjExcelApplication, "Excel")
        if (null objExcel) return false
 
        makeVisible objExcel
 
        // get workbooks collection
        checkRes(oleGet(objExcel,cPropertyWorkbooks,objWorkbooks))
        if (null objWorkbooks) 
        {
                ack "Unable to get workbooks collection"
                return false
        }
 
      // Open existing Excel file
      clear( args )
      put( args, cParamFileName, ExcelFileName )
      checkRes( oleMethod( objWorkbooks, cMethodOpen, args ) )
 
        // get active workbook
        checkRes(oleGet(objExcel,cPropertyActiveWorkbook,objWorkbook))
        if (null objWorkbook) 
        {
                ack "Unable to get active workbook"
                return false
        }
        
        //get the worksheets
        checkRes(oleGet(objWorkbook, "Worksheets", objWorksheets))
        if (null objWorksheets) 
        {
                ack "Unable to get worksheets"
                return false
        }
 
        clear(args )
        put(args, dataSheetName)
        checkRes( oleGet(objWorksheets,"Item", args , objSheet) )
        if (null objSheet)
        {
                ack "Unable to get Sheet"
                return false
        }
        
        // Activate selected sheet 
        checkRes( oleMethod(objSheet, "Activate") )
 
        return true    
}
 
 
//for creating the Excel Columns
string intToCol(int i) {
    int p
    if (i < 26) {
        char a = `A'
        p = intOf a
        p = p + (i-1)
        a = charOf p
        return a ""
    } else {
        ack "Too many columns"
        halt
    }
}
 
void setCell(int row, int col, string s) {
    closeIfNonNull objCell
    clear(args)
    put(args, (intToCol col) row "")
    checkRes(oleGet(objSheet, cMethodRange,args, objCell))
 
    if (null objCell) {
        ack "Unable to get cell object"
        halt
    }
 
    checkRes(olePut(objCell, cPropertyValue, s))
}
 
void doExcel() 
{
        Object o
        Column c
        string s = ""
        int row = 1
        int col = 0
        if (!excelInit) 
        {
                return
        }
row++
 
        col=0
        s = startDate ""
        col++
        setCell(row, col, s)
        
        s = DateToTest ""
        col++
        setCell(row, col, s)
 
        s = Total_Reqs ""
        col++
        setCell(row, col, s)
 
        s = Num_Added ""
        col++
        setCell(row, col, s)
 
        s = Num_Deleted ""
        col++
        setCell(row, col, s)
 
        s = Num_Modified ""
        col++
        setCell(row, col, s)
 
        s = Total_Changes ""
        col++
        setCell(row, col, s)
 
        s = Volatility ""
        col++
        setCell(row, col, s)
        disconnectFromApp objExcel
}
 
 
 
 
// Dialog box variables
DB dbDates = null    // this is the dialog box definition
DBE dbeStartDate = null
DBE dbeEndDate = null //holds the string to search for
startDate = null
Date endDate = null
bool datesAreValid = false
 
Buffer outBuf = create
outBuf = ""
 
void GenerateMetrics (DB db)
{//GenerateMetrics
 
string ThisString
Object ThisObject 
int offset,len
 
Link OutLink 
 
 
Date ThisObjLastModDate //Last Date this was modified on.
Date ThisObjDateCreated //Date this Object was created
Date TestDate = getDate(dbeEndDate)             //Get the Date to Test for from the user, for some reason this can't be assigned to a global
DateToTest = TestDate
startDate = getDate(dbeStartDate)
 
Date LastMetricDate = getDate(dbeStartDate)
if (DateToTest <= LastMetricDate)
{
   ack "Metric Date must be after last Metric Date"
   halt
}
 
//Get Total_Reqs
for ThisObject in ThisModule do //loop through entire module
{
   ThisString = ThisObject."Object Text"
   ThisObjLastModDate= ThisObject."Last Modified On"
   ThisObjDateCreated= ThisObject."Created On"
 
   //Get Total_Reqs
   if (findRichText(ThisString , "shall", offset, len, false)) 
        {
                Total_Reqs++
 
                                //Get the number of shalls that were added since the last metric update
                if (ThisObjDateCreated > LastMetricDate) Num_Added++
 
                //Get the number of shalls that were modified (not including those that were deleted) since the last metric update
                if ( (ThisObjLastModDate > LastMetricDate) && (!isDeleted(ThisObject)) ) Num_Modified++
                
                //Get the number of shalls deleted since the last metric update
                if (isDeleted(ThisObject)) Num_Deleted++
 
//      else            //shall wasn't added, modified or deleted between selected dates
//      {
                //Get the number of shalls deleted since the last metric update
//              if (isDeleted(ThisObject)) Num_Deleted++
//      } // end else
   } // end Get Total Req
} //end for ThisObject in ThisModule
 
//Get Total Changes
Total_Changes = Num_Added + Num_Deleted + Num_Modified
 
//Get Volatility
//DXL doesn't allow good casting so had to use "real" variables to convert ints to reals before calculating
real TR = Total_Reqs
real TC = Total_Changes
Volatility = TC/TR
 
//Build an Information Box to display results to user, clicking OK will export to Excel
string MessageString = ""
 
MessageString = MessageString "Start Date = " startDate "\n"
MessageString = MessageString "End Date = " DateToTest "\n"
MessageString = MessageString "Total_Reqs = " TR ", "
MessageString = MessageString "Num_Added = " Num_Added ", "
MessageString = MessageString "Num_Deleted = " Num_Deleted ", "
MessageString = MessageString "Num_Modified = " Num_Modified ","
MessageString = MessageString "Total_Changes = " TC "\n"
MessageString = MessageString "Volatility = " Volatility "\n"
 
// notify the user that the script is complete
infoBox MessageString 
doExcel
 
}//GenerateMetrics
 
void getKey() {
   dbDates = centered "Requirement Volatility"
   label(dbDates, "!!! NOTE YOU MUST BE IN STANDARD VIEW UNFILTERED !!!")
   label(dbDates, "Enter the start and end dates that you want the metrics from.")
        dbeStartDate = date(dbDates, 20, today, true)
        dbeEndDate = date(dbDates, 20, today, true)
   ok(dbDates, "Generate Volatility Metrics", GenerateMetrics )
   show dbDates
} // getKey
 
load view "ShowDeletions"
getKey

 


Hope you can read this. I'm trying to make the script read with colorization.

Chris Annal
SW Test Engineer / DOORS Database Administrator
Sensis Corporation,
East Syracuse, New York
chrisa@sensis.com

 

Re: Requirement Volatility - how to get it?
llandale - Fri Jun 17 16:53:46 EDT 2011

ChrisAnnal - Fri Jun 17 14:34:49 EDT 2011

OK. For what it's worth, I put together a script that goes through a module looking for "shall" and counts the objects (Req_Total), then looks for objects that were modified, added, or deleted between two dates (selected by the user in a dialog box).
The script requires the user to have an Excel template file C:\\Temp\\Requirement_Volatility_Metrics.xlt
The reason for the Excel template is just so the user can format and apply headings to the output data as they wish. The data is output to the template at the 2nd row to allow for this.

// Exports Volatility Metrics to the Requirement_Volatility_Metrics.xls file
 
/*
    Volatility Metrics are calculated and then exported to the Requirement_Volatility_Metrics.xls File
        This requires that the Requirement_Volatility_Metrics.xls template file exists so that the export
        can locate it. (Create an empty Excel file for starters).

*/
 
pragma runLim,0
#include <utils/ole.inc>
checkPlatform "Microsoft Excel"
 
const string cMethodOpen                = "Open"
const string columnTitles[] = {"Date","Total_Reqs","Num_Added","Num_Deleted","Num_Modified","Total_Changes"}
const int NumOfTitles = 6
 
 
int Total_Reqs = 0          //Total Requirements = (Object Text CONTAINS 'shall') AND (NOT(Object Text CONTAINS 'DELETE'))) 
int Num_Added = 0                   //Num of added reqs =(((Object Text CONTAINS 'shall') AND (NOT(Object Text CONTAINS 'DELETE'))) AND (Created On > xx/xx/xx) AND (NOT(Allocation is empty)
int Num_Deleted = 0         //Num of deleted reqs = (Object Text CONTAINS "shall") AND (Object Text CONTAINS "DELETE") AND (Last Modified On >= xx/xx/xx)
int Num_Modified = 0        //Num of Changed Reqs = ((Object Text CONTAINS 'shall') AND (NOT(Object Text CONTAINS 'DELETE'))) AND (Last Modified On >= xx/xx/xx) AND (Clarity includes Modified)
int Total_Changes = 0       //Total Number of changes Made within this period
real Volatility = 0.00      //Will be calculated as Total_Changes / Total_Reqs
string dataSheetName = "Sheet1"               //Has the name of the worksheet that will hold the data.
Date DateToTest = "03/04/2005"        //This will be changed when the user inputs the actual date. This is just used as a "default" date.
Date startDate = "02/03/2004"         //This will be changed when the user inputs the actual date. This is just used as a "default" date.
 
//--------------------------------------------------------------
 
OleAutoObj objExcel = null
OleAutoObj objWorkbooks = null
OleAutoObj objWorkbook = null
OleAutoObj objWorksheets = null
OleAutoObj objSheet = null
OleAutoObj objCell = null
OleAutoArgs args   = create
 
//--------------------------------------------------------------
 
Module ThisModule = current
 
//initialize the OLE Application (Excel)
bool excelInit() 
{
        string ExcelFileName = "C:\\Temp\\Requirement_Volatility_Metrics.xlt"
//      print ExcelFileName 
 
        objExcel = connectToApp(cObjExcelApplication, "Excel")
        if (null objExcel) return false
 
        makeVisible objExcel
 
        // get workbooks collection
        checkRes(oleGet(objExcel,cPropertyWorkbooks,objWorkbooks))
        if (null objWorkbooks) 
        {
                ack "Unable to get workbooks collection"
                return false
        }
 
      // Open existing Excel file
      clear( args )
      put( args, cParamFileName, ExcelFileName )
      checkRes( oleMethod( objWorkbooks, cMethodOpen, args ) )
 
        // get active workbook
        checkRes(oleGet(objExcel,cPropertyActiveWorkbook,objWorkbook))
        if (null objWorkbook) 
        {
                ack "Unable to get active workbook"
                return false
        }
        
        //get the worksheets
        checkRes(oleGet(objWorkbook, "Worksheets", objWorksheets))
        if (null objWorksheets) 
        {
                ack "Unable to get worksheets"
                return false
        }
 
        clear(args )
        put(args, dataSheetName)
        checkRes( oleGet(objWorksheets,"Item", args , objSheet) )
        if (null objSheet)
        {
                ack "Unable to get Sheet"
                return false
        }
        
        // Activate selected sheet 
        checkRes( oleMethod(objSheet, "Activate") )
 
        return true    
}
 
 
//for creating the Excel Columns
string intToCol(int i) {
    int p
    if (i < 26) {
        char a = `A'
        p = intOf a
        p = p + (i-1)
        a = charOf p
        return a ""
    } else {
        ack "Too many columns"
        halt
    }
}
 
void setCell(int row, int col, string s) {
    closeIfNonNull objCell
    clear(args)
    put(args, (intToCol col) row "")
    checkRes(oleGet(objSheet, cMethodRange,args, objCell))
 
    if (null objCell) {
        ack "Unable to get cell object"
        halt
    }
 
    checkRes(olePut(objCell, cPropertyValue, s))
}
 
void doExcel() 
{
        Object o
        Column c
        string s = ""
        int row = 1
        int col = 0
        if (!excelInit) 
        {
                return
        }
row++
 
        col=0
        s = startDate ""
        col++
        setCell(row, col, s)
        
        s = DateToTest ""
        col++
        setCell(row, col, s)
 
        s = Total_Reqs ""
        col++
        setCell(row, col, s)
 
        s = Num_Added ""
        col++
        setCell(row, col, s)
 
        s = Num_Deleted ""
        col++
        setCell(row, col, s)
 
        s = Num_Modified ""
        col++
        setCell(row, col, s)
 
        s = Total_Changes ""
        col++
        setCell(row, col, s)
 
        s = Volatility ""
        col++
        setCell(row, col, s)
        disconnectFromApp objExcel
}
 
 
 
 
// Dialog box variables
DB dbDates = null    // this is the dialog box definition
DBE dbeStartDate = null
DBE dbeEndDate = null //holds the string to search for
startDate = null
Date endDate = null
bool datesAreValid = false
 
Buffer outBuf = create
outBuf = ""
 
void GenerateMetrics (DB db)
{//GenerateMetrics
 
string ThisString
Object ThisObject 
int offset,len
 
Link OutLink 
 
 
Date ThisObjLastModDate //Last Date this was modified on.
Date ThisObjDateCreated //Date this Object was created
Date TestDate = getDate(dbeEndDate)             //Get the Date to Test for from the user, for some reason this can't be assigned to a global
DateToTest = TestDate
startDate = getDate(dbeStartDate)
 
Date LastMetricDate = getDate(dbeStartDate)
if (DateToTest <= LastMetricDate)
{
   ack "Metric Date must be after last Metric Date"
   halt
}
 
//Get Total_Reqs
for ThisObject in ThisModule do //loop through entire module
{
   ThisString = ThisObject."Object Text"
   ThisObjLastModDate= ThisObject."Last Modified On"
   ThisObjDateCreated= ThisObject."Created On"
 
   //Get Total_Reqs
   if (findRichText(ThisString , "shall", offset, len, false)) 
        {
                Total_Reqs++
 
                                //Get the number of shalls that were added since the last metric update
                if (ThisObjDateCreated > LastMetricDate) Num_Added++
 
                //Get the number of shalls that were modified (not including those that were deleted) since the last metric update
                if ( (ThisObjLastModDate > LastMetricDate) && (!isDeleted(ThisObject)) ) Num_Modified++
                
                //Get the number of shalls deleted since the last metric update
                if (isDeleted(ThisObject)) Num_Deleted++
 
//      else            //shall wasn't added, modified or deleted between selected dates
//      {
                //Get the number of shalls deleted since the last metric update
//              if (isDeleted(ThisObject)) Num_Deleted++
//      } // end else
   } // end Get Total Req
} //end for ThisObject in ThisModule
 
//Get Total Changes
Total_Changes = Num_Added + Num_Deleted + Num_Modified
 
//Get Volatility
//DXL doesn't allow good casting so had to use "real" variables to convert ints to reals before calculating
real TR = Total_Reqs
real TC = Total_Changes
Volatility = TC/TR
 
//Build an Information Box to display results to user, clicking OK will export to Excel
string MessageString = ""
 
MessageString = MessageString "Start Date = " startDate "\n"
MessageString = MessageString "End Date = " DateToTest "\n"
MessageString = MessageString "Total_Reqs = " TR ", "
MessageString = MessageString "Num_Added = " Num_Added ", "
MessageString = MessageString "Num_Deleted = " Num_Deleted ", "
MessageString = MessageString "Num_Modified = " Num_Modified ","
MessageString = MessageString "Total_Changes = " TC "\n"
MessageString = MessageString "Volatility = " Volatility "\n"
 
// notify the user that the script is complete
infoBox MessageString 
doExcel
 
}//GenerateMetrics
 
void getKey() {
   dbDates = centered "Requirement Volatility"
   label(dbDates, "!!! NOTE YOU MUST BE IN STANDARD VIEW UNFILTERED !!!")
   label(dbDates, "Enter the start and end dates that you want the metrics from.")
        dbeStartDate = date(dbDates, 20, today, true)
        dbeEndDate = date(dbDates, 20, today, true)
   ok(dbDates, "Generate Volatility Metrics", GenerateMetrics )
   show dbDates
} // getKey
 
load view "ShowDeletions"
getKey

 


Hope you can read this. I'm trying to make the script read with colorization.

Chris Annal
SW Test Engineer / DOORS Database Administrator
Sensis Corporation,
East Syracuse, New York
chrisa@sensis.com

 

Got some bad news. You don't want to hit an Object Text that says "Following are the shallow water requirements."

You may need to do a regexp search looking for "shall" surrounded by non-alpha characters. Don't recall the exact syntax, byut you want to put it in your main code, not in a function; since the "regexp2" command is particularly slow.

Something perhaps like this; ... which hopefully someone else here will debug for us.

Regexp = re_HasShall = regexp2("[^A-Za-z][sS][hH][aA][lL][lL][^A-Za-z]")
 
bool HasShall(Object obj)
{  string Text = obj."Object Text"
   return(re_HasShall text)
}

 

  • Louie

 

Re: Requirement Volatility - how to get it?
jsarkic - Mon Jun 20 09:09:21 EDT 2011

I find the best metric for requirements volatility is to determine what requirements have changed between baselines. A requirement may have changed multiple times between baselines, but should be recorded as a single change. In addition, a new requirement that may have undergone multiple editorial changes should be treated as a new requirement, until a new baseline is struck. Measuring volatility this way will identify the volatility of existing requirements, the number of new requirements; and you can easily determine the number of deleted requirements between baselines. These measures does depend on the Programs striking baselines during key milestones.

Re: Requirement Volatility - how to get it?
ChrisAnnal - Mon Jun 20 11:06:19 EDT 2011

llandale - Fri Jun 17 16:53:46 EDT 2011

Got some bad news. You don't want to hit an Object Text that says "Following are the shallow water requirements."

You may need to do a regexp search looking for "shall" surrounded by non-alpha characters. Don't recall the exact syntax, byut you want to put it in your main code, not in a function; since the "regexp2" command is particularly slow.

Something perhaps like this; ... which hopefully someone else here will debug for us.

Regexp = re_HasShall = regexp2("[^A-Za-z][sS][hH][aA][lL][lL][^A-Za-z]")
 
bool HasShall(Object obj)
{  string Text = obj."Object Text"
   return(re_HasShall text)
}

 

  • Louie

 

You're right, Louie. This script only works if "shall" appears in the text. so it would count an object as a requirement if it contained "shallow" in the text. There may be some better options than what I had used in the original script, for instance the user might want to "filter" the module and create a specific view that only contained those requirement objects, prior to running the rest of the script. Something like this...
 

/*
NOTE - This script assumes the module has been filtered for only displaying objects that contain the word "shall" in the text. Using Tools-->Filter-->Define, from the top menu in an open module, then selecting "Any string or text attribute...contains...shall" and unchecking the boxes for "Match Case" and "Regular Expression" as needed. Save the resulting filtered view as Only_Shalls.
*/
 
//Prior to any scripts used for calculations, user would apply a view as described above
 
View v = view("Only_Shalls")

 


Another approach would be to use the Regular Expression, and I think the one Louie has suggested would work. I had some older scripts that used one or the other of the following:

Regexp re = regexp "(Sshall)"
//the above may find "Shall" or "shall"
Regexp re = regexp "(^A-Za-zSshallA-Za-z)|(Sshall^A-Za-z)" //This may find "SHALL", "Shall" or "shall", at least...

I also found a couple of minor nits in my script. For instance, the following line...

 

 

 

ack "Metric Date must be after last Metric Date"
//should read...
ack "End Date must be after Start Date"

 


Lastly, I would remove everything in the following comments from the "equal sign" to the end of the comment. The module I was working in was somewhat special in that the user had marked his text with "DELETE" and I was originally addressing that. This was unnecessary, so the comments are a bit misleading.

 

 

 

 

 

 

 

 

int Total_Reqs = 0        //Total Requirements = (Object Text CONTAINS 'shall') AND (NOT(Object Text CONTAINS 'DELETE'))) 
int Num_Added = 0                   //Num of added reqs =(((Object Text CONTAINS 'shall') AND (NOT(Object Text CONTAINS 'DELETE'))) AND (Created On > xx/xx/xx) AND (NOT(Allocation is empty)
int Num_Deleted = 0         //Num of deleted reqs = (Object Text CONTAINS "shall") AND (Object Text CONTAINS "DELETE") AND (Last Modified On >= xx/xx/xx)
int Num_Modified = 0        //Num of Changed Reqs = ((Object Text CONTAINS 'shall') AND (NOT(Object Text CONTAINS 'DELETE'))) AND (Last Modified On >= xx/xx/xx) AND (Clarity includes Modified)
 
//should be.....
 
int Total_Reqs = 0          //Total Requirements 
int Num_Added = 0           //Num of added reqs
int Num_Deleted = 0         //Num of deleted reqs
int Num_Modified = 0        //Num of Changed Reqs

 


jsarkic - I think this script will do what you suggest. What requirements changed between baselines can use the "start" and "end" dates per whatever dates those baselines were performed. Since it uses "Date ThisObjDateCreated" and compares that to the selected "start" date - it should only capture a new object once per report. In regard to multiple changes to the same requirement it only cares about the objects that were modified (not including those that were deleted) since the start date and doesn't care if it was modified several times. ..."if ( (ThisObjLastModDate > LastMetricDate) && (!isDeleted(ThisObject)) ) Num_Modified++". (It counts deletions separately for this reason, too).

All in all, this script isn't perfect, but it can be a good starting point for anyone hoping to develop metrics for their requirements. I think the Regular Expression for "shall" is a great suggestion for improvement (or using a special view). I think the metrics work as defined, but can perhaps be more refined. This is my best stab at it. Good Luck!
Thanks,
:)

Chris Annal
SW Test Engineer / DOORS Database Administrator
Sensis Corporation, East Syracuse, New York
chrisa@sensis.com

 

 

 

 

 

 

Re: Requirement Volatility - how to get it?
ChrisAnnal - Mon Jun 20 11:41:07 EDT 2011

jsarkic - Mon Jun 20 09:09:21 EDT 2011
I find the best metric for requirements volatility is to determine what requirements have changed between baselines. A requirement may have changed multiple times between baselines, but should be recorded as a single change. In addition, a new requirement that may have undergone multiple editorial changes should be treated as a new requirement, until a new baseline is struck. Measuring volatility this way will identify the volatility of existing requirements, the number of new requirements; and you can easily determine the number of deleted requirements between baselines. These measures does depend on the Programs striking baselines during key milestones.

Here are a couple of bugs with the existing script that others may be able to tackle, or possibly could be addressed as part of a requirements refinement process prior to running the script...

{code}
/* This script looks for "Shall" or "shall" in the object text and increments the count integer for each one it finds,
whether the shall is in plain or boldfaced font.
WARNING! If the Object Text attribute contains text with a "shall" AND
an OLE object, this script will ignore the "shall".

Developed in DOORS 7.1 p12
Chris Annal
SW Test Engineer / DOORS Database Administrator
Sensis Corporation, East Syracuse, New York
chrisa@sensis.com

Re: Requirement Volatility - how to get it?
ChrisAnnal - Mon Jun 20 11:45:37 EDT 2011

ChrisAnnal - Mon Jun 20 11:41:07 EDT 2011
Here are a couple of bugs with the existing script that others may be able to tackle, or possibly could be addressed as part of a requirements refinement process prior to running the script...

{code}
/* This script looks for "Shall" or "shall" in the object text and increments the count integer for each one it finds,
whether the shall is in plain or boldfaced font.
WARNING! If the Object Text attribute contains text with a "shall" AND
an OLE object, this script will ignore the "shall".

Developed in DOORS 7.1 p12
Chris Annal
SW Test Engineer / DOORS Database Administrator
Sensis Corporation, East Syracuse, New York
chrisa@sensis.com

(Sorry, hit the "tab" and "spacebar" while typing and it "posted" the above)
Here's the bugs again...

/* This script looks for "shall" in the object text and increments the count integer for each one it finds,
   whether the shall is in plain or boldfaced font.
   

   WARNING! If the Object Text attribute contains text with a "shall" AND
   an OLE object, this script will ignore the "shall". 

   WARNING! If the Object Text attribute contains text with more than one "shall" it will only count the 1st "shall" and move
   on to the next object.

   Developed in DOORS 9.3 p1
   Chris Annal
*/

 


Chris Annal
SW Test Engineer / DOORS Database Administrator
Sensis Corporation, East Syracuse, New York
chrisa@sensis.com