Question
· Sep 6, 2023

Efficiently Parsing and Structuring Message Data: A Developer-Friendly Approach

Good morning,

Thank you for taking the time to read, understand, and answer this question.

If you needed to convert a message where questions are separated by "|", and the question text is the portion before the ":" and the response is the portion after the ":"; Which way would be the most readable and understandable for other developers?

Input example:

NAME OF SQUAD 1?:ALPHA|NAME OF SQUAD 2?:BRAVO|NAME OF SQUAD 2?:ANSWER THREE||NAME OF SQUAD 25?:YANKEE|NAME OF SQUAD 26?:ZULU

 

Output structure:

[
    {
        "definition": "question 1",
        "text": "NAME OF SQUAD 1?",
        "answer": [
            {
                "valueString": "ALPHA"
            }
        ]
    },
    {
        "definition": "question 2",
        "text": "NAME OF SQUAD 2?",
        "answer": [
            {
                "valueString": "BRAVO"
            }
        ]
    },
    {
        "definition": "question 3",
        "text": "NAME OF SQUAD 3?",
        "answer": [
            {
                "valueString": "ANSWER CHARLIE"
            }
        ]
    },
    {
        "definition": "question 4",
        "text": "NAME OF SQUAD 25?",
        "answer": [
            {
                "valueString": "YANKEE"
            }
        ]
    },
    {
        "definition": "question 5",
        "text": "NAME OF SQUAD 26?",
        "answer": [
            {
                "valueString": "ZULU"
            }
        ]
    }
]

 

 

 

 

 

 

 

 

 

A way to get the needed output would be:

ClassMethod createResponse(data As %String(MAXLEN="")) As %Library.DynamicArray
{
    ;1.- Questions splitted by "|"
    SET listQuestions 			= $LISTFROMSTRING(data, "|")
    set items 			= []
    set questionNumber 	= 0
    ;2.- Iterate
    FOR i=1:1:$LISTLENGTH(listQuestions) {
        set questionAnswer = $LISTGET(listQuestions, i)
        ;3.- Update variables
        set questionNumber 	= questionNumber + 1
        SET question 		= $PIECE(questionAnswer, ":", 1)
        SET answer 		= $ZSTRIP($PIECE(questionAnswer, ":", 2), "<W") //Get rid of initial whitespace
        ;4.- Generate item
        set item 			= 									
        {
        "definition": ("question "_(questionNumber)),
        "text": (question),
        "answer": 
        [
            {
                "valueString": (answer)
            }
        ]
        }
        do items.%Push(item)
    }	
    quit items
}

 

Is there a more readable and understandable and easier way for anyone reading this code to understand for the first time, to explain to them through the code itself and/or comments what it does? I mean, is there a way to make it more understandable and easy to understand?


📍📌 Thank you for your time reading this question, and for your time to think about it.

All the best.

Product version: HealthShare 2020.1
Discussion (2)1
Log in or sign up to continue

This is a rather subjective based on the skill level of the intended audience.

You could add a comment to the ClassMethod to provide context to what is being done and why. For example:

/// This ClassMethod takes a delimited String from System-X that consists of sets of Questions and Answers. 
/// The Sets are delimited by a pipe "|" and then the questions and answers are delimeted by a colon ":"
/// The response from this ClassMethod is a %Library.DynamicArray object containing the questions and answers
ClassMethod createResponse(data As %String(MAXLEN="")) As %Library.DynamicArray
{
    ;1.- Questions splitted by "|"
    Set listQuestions 			= $LISTFROMSTRING(data, "|")
    Set items 			= []
    Set questionNumber 	= 0
    ;2.- Iterate
    For i=1:1:$LISTLENGTH(listQuestions) {
        Set questionAnswer = $LISTGET(listQuestions, i)
        ;3.- Update variables
        Set questionNumber 	= questionNumber + 1
        Set question 		= $PIECE(questionAnswer, ":", 1)
        Set answer 		    = $ZSTRIP($PIECE(questionAnswer, ":", 2), "<W") //Get rid of initial whitespace
        ;4.- Generate item
        Set item 			= 									
        {
        "definition": ("question "_(questionNumber)),
        "text": (question),
        "answer": 
        [
            {
                "valueString": (answer)
            }
        ]
        }
        Do items.%Push(item)
    }	
    Quit items
}

Or you could go one step further and be more descriptive with your comment at each action within your code. So, instead of:

;2.- Iterate

You could write something like:

;2.- Iterate through the list of Questions and Answers

If your intended audience is not familiar with ObjectScript, then you may want to introduce them to features in stages. For example, you could use $ZSTRIP on both the question and answer in your For loop, but only nest it for the answer and use comments to describe it all. Something like:

// Retrieve the question from the delimited entry
Set tQuestion = $PIECE(questionAnswer, ":", 1)

// Strip any whitespace from the start of the question
Set question = $ZSTRIP(tQuestion, "<W")

// It is also possible to nest functions, so below we will retrieve the answer and remove the whitespace in a single line.
Set answer = $ZSTRIP($PIECE(questionAnswer, ":", 2), "<W")

This is nice. Anyway there are few suggestions

  1. Make sure the commands and string functions are following same format either SET or Set or set 
  2. Use %DynmaicArray instead of literal constructors  [ ]. Because it's instantiate the methods of the object like %push when accessing it. Literal constructors won't do it.
  3. Comments are essential for better understanding the program flow. Anyway if you don't want to appear your comments in INT code then use the syntax #;  instead of ;  ex: #;Test comment
  4. Use $ListNext to get the list values one by one. It rid out the 2 additional string functions $LISTLENGTH and $LISTGET usage in your case. Easy to understand 
  5. You can use $Increment instead of declaring a   questionNumber variable and do addition operation in the code.
  6. Add some conditional checks to skip the if the values in between | is empty

I have attached the code sample below. 


ClassMethod createResponse(data As %String(MAXLEN="")) As %DynamicArray
{
	
	set items = ##class(%DynamicArray).%New()
	
	#;1.- Questions splitted by "|"
	set ptr=0
	set listQuestions = $ListFromString(data, "|")
    
    #;2.- Iterate
    while $ListNext(listQuestions,ptr,questionAnswer) {
	   	#;3.- Update variables
	   	continue:questionAnswer=""
	    set question= $Piece(questionAnswer, ":", 1)
        set answer 	= $ZStrip($PIECE(questionAnswer, ":", 2), "<W") //Get rid of initial whitespace
        #;4.- Generate item
    	set item 	= 									
        	{
        	"definition": ("question "_($Increment(questionNumber))),
        	"text": (question),
        	"answer": 
			        [
			            {
			                "valueString": (answer)
			            }
			        ]
        	}
        do items.%Push(item)
    }	
    return items
}

Hope this helps