Jump to content
Macro Express Forums
UAMike

Output a grammatically correct string

Recommended Posts

I am trying to create a macro that takes a string of digits (1-9) input by the user and outputs it as a list in a grammatically correct format (using an Oxford comma if applicable).

 

For example, the user inputs "12345" and the output is is "1, 2, 3, 4, and 5"

"45" => "4 and 5"

"7" => "7"

"389" => "3, 8, and 9"

 

Let's assume that the user only inputs a digit a maximum of one time (ie: no "1123") and would only enter the digits in numerical order (ie: "123", not "321")

 

This is a macro I've wanted to make for a long time and I'm trying to determine what the best approach for creating it would be. Any thoughts/ideas would be appreciated.

Share this post


Link to post
Share on other sites

What if they need a 2 digit number? I think they would need to have some delimiter between each value in that case. It makes a difference on how I would approach it.

Share this post


Link to post
Share on other sites

A space would work as a delimiter, E.G. "1 2 3 6 9 13 15".

Share this post


Link to post
Share on other sites
19 minutes ago, Cory said:

What if they need a 2 digit number? I think they would need to have some delimiter between each value in that case. It makes a difference on how I would approach it.

I was trying to keep it simple for myself by only have 1 digit numbers, as this would work for my purposes 99% of the time. 

 

My plan was to use statements like: If Variable %string% contains "1" and I realized that this would get misinterpreted if I used two digit numbers. But it sounds like you're suggesting I use a space delimiter... can you give me an example of how this would work?

Share this post


Link to post
Share on other sites

Sorry, I don't have time to write the macro for you now. And I think it's better for you to try yourself and learn. 

I would use space delimiters since they're easy to type. Like my example. I would split the string based on the delimiter into an array. Then I would loop the number of times as there are items in the array. I would then create an output variable and in each iteration add that value with a comma and space or  value "and, ". The condition for which would be based on whether we're at the penultimate item in the array. Say there are 7 items in the array. The condition would be "if count - 1"". Oh, and another condition for the last one which would only do the value of course. 

Share this post


Link to post
Share on other sites

Play around with this.  I think it does what you want, or close to it.
This is written in Macro Express 3; if you have the PRO version you can
name the text and integer variables instead of using the standard "T" and "N" names.  

 

// Set input string for testing
Variable Set String %T1% "123"
// Clear output string to null
Variable Set String %T99% ""
// set integer with length of input string
Variable Set Integer %N1% from Length of Variable %T1%
// Append input characters one at a time to output string, with comma and blank after each (except last)
Variable Set Integer %N99% to 1
Repeat Until %N99% > %N1%
  Variable Modify String: Copy Part of %T1% to %T89%
  If Variable %N99% = variable %N1%
    Variable Modify String: Append "AND " to %T99%
  End If
  Variable Modify String: Append %T89% to %T99%
  If Variable %N99% < variable %N1%
    Variable Modify String: Append ", " to %T99%
  End If
  // ....    bump pointer to next input digit
  Variable Modify Integer: Inc (%N99%)
Repeat End
//  
// If input string only two digits, get rid of the comma before the AND
If Variable %N1% = 2
  Replace ", AND" with " AND" in %T99%
End If
// If input string only one digit, get rid of the AND as well
If Variable %N1% = 1
  Replace "AND " with "" in %T99%
End If
//  
// Display result
Text Box Display: Output string
Macro Return
// 

Share this post


Link to post
Share on other sites
1 hour ago, rberq said:

Play around with this.  I think it does what you want, or close to it.
This is written in Macro Express 3; if you have the PRO version you can
name the text and integer variables instead of using the standard "T" and "N" names.  

 

// Set input string for testing
Variable Set String %T1% "123"
// Clear output string to null
Variable Set String %T99% ""
// set integer with length of input string
Variable Set Integer %N1% from Length of Variable %T1%
// Append input characters one at a time to output string, with comma and blank after each (except last)
Variable Set Integer %N99% to 1
Repeat Until %N99% > %N1%
  Variable Modify String: Copy Part of %T1% to %T89%
  If Variable %N99% = variable %N1%
    Variable Modify String: Append "AND " to %T99%
  End If
  Variable Modify String: Append %T89% to %T99%
  If Variable %N99% < variable %N1%
    Variable Modify String: Append ", " to %T99%
  End If
  // ....    bump pointer to next input digit
  Variable Modify Integer: Inc (%N99%)
Repeat End
//  
// If input string only two digits, get rid of the comma before the AND
If Variable %N1% = 2
  Replace ", AND" with " AND" in %T99%
End If
// If input string only one digit, get rid of the AND as well
If Variable %N1% = 1
  Replace "AND " with "" in %T99%
End If
//  
// Display result
Text Box Display: Output string
Macro Return
// 

 

This works really nicely! In order to bump the pointer to the next digit, I modified the command: Variable Modify String: Copy Part of %T1% starting at %N99% and 1 characters long to %T89%. 

 

This only works using 1 digit numbers, but it will work for my purposes. Thank you!

Share this post


Link to post
Share on other sites
7 hours ago, UAMike said:

This works really nicely! In order to bump the pointer to the next digit, I modified the command: Variable Modify String: Copy Part of %T1% starting at %N99% and 1 characters long to %T89%. 

 

This only works using 1 digit numbers, but it will work for my purposes. Thank you!

That's exactly right for the Variable Modify String command -- the details didn't show up when I copied the command text, but I thought it would be good for you to figure it out.  🙂

You could probably modify the macro to handle multi-digit strings,  but of course you would have to use some kind of delimiter between strings like Cory said.

Share this post


Link to post
Share on other sites

This was a fun assignment! Here's my version:

 

 

Variable Set String %Results% to ""
 
Variable Set String %Input%: Prompt
 
Variable Set Integer %Length% to the length of variable %Input%
 
Switch( %Length% )
Case: 0
  Text Box Display: Nothing to do!
End Case
 
Case: 1 // Simple case: just output the input!
  Variable Set String %Results% to "%Input%"
End Case
 
Case: 2 // Change "XY" to "X and Y"
  Variable Modify String: Copy part of text in %Input% starting at 1 and 1 characters long to %Char%
  Variable Modify String %Results%: Append Text (%Char% and )
  Variable Modify String: Copy part of text in %Input% starting at 2 and 1 characters long to %Char%
  Variable Modify String %Results%: Append Text (%Char%)
End Case
 
Default Case // Change "ABC...XYZ" into "A, B, C, ... X, Y, and Z"
  Repeat Until %Length% Equals "2"
    Variable Modify String: Copy part of text in %Input% starting at 1 and 1 characters long to %Char%
    Variable Modify String %Results%: Append Text (%Char%, )
    Variable Modify String: Delete part of text from %Input% starting at 1 and 1 characters long
    Variable Set Integer %Length% to the length of variable %Input%
  End Repeat
  Variable Modify String: Copy part of text in %Input% starting at 1 and 1 characters long to %Char% // Handle penultimate character
  Variable Modify String %Results%: Append Text (%Char%, and )
  Variable Modify String: Copy part of text in %Input% starting at 2 and 1 characters long to %Char% // Handle final character
  Variable Modify String %Results%: Append Text (%Char%)
End Case
End Switch
 
Text Box Display: %Results%
<VARIABLE SET STRING Option="\x00" Destination="%Results%" NoEmbeddedVars="FALSE"/>
<COMMENT/>
<VARIABLE SET STRING Option="\x01" Destination="%Input%" Prompt="Enter characters to output with grammaticalcommas and an \"and\"" Mask="FALSE" OnTop="TRUE" Left="Center" Top="Center" Monitor="0"/>
<VARIABLE SET STRING Option="\x00" Destination="%Input%" Value="1" NoEmbeddedVars="FALSE" _ENABLED="FALSE" _COMMENT="The three lines speed up testng of this script"/>
<VARIABLE SET STRING Option="\x00" Destination="%Input%" Value="12" NoEmbeddedVars="FALSE" _ENABLED="FALSE"/>
<VARIABLE SET STRING Option="\x00" Destination="%Input%" Value="12345" NoEmbeddedVars="FALSE" _ENABLED="FALSE"/>
<COMMENT/>
<VARIABLE SET INTEGER Option="\x0D" Destination="%Length%" Text_Variable="%Input%"/>
<COMMENT/>
<SWITCH Variable="%Length%"/>
<CASE Value="0"/>
<TEXT BOX DISPLAY Title="Nothing to do!" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 \r\n\\par }\r\n" Left="Center" Top="Center" Width="278" Height="200" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0"/>
<END CASE/>
<COMMENT/>
<CASE Value="1" _COMMENT="Simple case: just output the input!"/>
<VARIABLE SET STRING Option="\x00" Destination="%Results%" Value="%Input%" NoEmbeddedVars="FALSE"/>
<END CASE/>
<COMMENT/>
<CASE Value="2" _COMMENT="Change \"XY\" to \"X and Y\""/>
<VARIABLE MODIFY STRING Option="\x09" Destination="%Char%" Variable="%Input%" Start="1" Count="1" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x06" Destination="%Results%" Value="%Char% and " NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x09" Destination="%Char%" Variable="%Input%" Start="2" Count="1" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x06" Destination="%Results%" Value="%Char%" NoEmbeddedVars="FALSE"/>
<END CASE/>
<COMMENT/>
<DEFAULT CASE _COMMENT="Change \"ABC...XYZ\" into \"A, B, C, ... X, Y, and Z\""/>
<REPEAT UNTIL Variable="%Length%" Condition="\x00" Value="2"/>
<VARIABLE MODIFY STRING Option="\x09" Destination="%Char%" Variable="%Input%" Start="1" Count="1" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x06" Destination="%Results%" Value="%Char%, " NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x0A" Destination="%Input%" Start="1" Count="1"/>
<VARIABLE SET INTEGER Option="\x0D" Destination="%Length%" Text_Variable="%Input%"/>
<END REPEAT/>
<VARIABLE MODIFY STRING Option="\x09" Destination="%Char%" Variable="%Input%" Start="1" Count="1" NoEmbeddedVars="FALSE" _COMMENT="Handle penultimate character"/>
<VARIABLE MODIFY STRING Option="\x06" Destination="%Results%" Value="%Char%, and " NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x09" Destination="%Char%" Variable="%Input%" Start="2" Count="1" NoEmbeddedVars="FALSE" _COMMENT="Handle final character"/>
<VARIABLE MODIFY STRING Option="\x06" Destination="%Results%" Value="%Char%" NoEmbeddedVars="FALSE"/>
<END CASE/>
<END SWITCH/>
<COMMENT/>
<TEXT BOX DISPLAY Title="%Results%" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 \r\n\\par }\r\n" Left="Center" Top="Center" Width="278" Height="200" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0"/>

 

Share this post


Link to post
Share on other sites

Hi Alan,

 

Minor point: I'd place %Results% in the body of the display, not the header, which will only accommodate a small number of digits.

 

<TEXT BOX DISPLAY Title="RESULTS" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 %tResults%\r\n\\par }\r\n" Left="Center" Top="Center" Width="278" Height="200" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0"/>

 

Share this post


Link to post
Share on other sites

This version accepts a set of numbers, each of any length (well, under a billion!) separated by single spaces.

 

I've just used a small test set, so add whatever input method suits, such as a prompt or imported text file etc.

 

If you have difficulty understanding what's going on, sprinkle with Text Box Displays to show the changing values of key variables.

 

It would be a mere three lines of script without that final 'and'!
 

Variable Set String %tRawInput% to "1 23 456 7 8 999" // Test input
Variable Modify String: Replace " " in %tRawInput% with ", "
Variable Set Integer %nLenRaw% to the length of variable %tRawInput%
Repeat Until %tChar% Contains ","
  Variable Modify String: Copy part of text in %tRawInput% starting at %nLenRaw% and 1 characters long to %tChar%
  Variable Modify Integer %nLenRaw%: Decrement
End Repeat
Variable Modify Integer: %nLenRaw% = %nLenRaw% + 2
Variable Modify String: Copy part of text in %tRawInput% starting at %nLenRaw% and 10 characters long to %tEnd%
Variable Modify String: Delete part of text from %tRawInput% starting at %nLenRaw% and 10 characters long
Variable Modify String %tRawInput%: Append Text ( and)
Variable Modify String %tRawInput%: Append Text String Variable (%tEnd%)


Text Box Display: RESULT

<VARIABLE SET STRING Option="\x00" Destination="%tRawInput%" Value="1 23 456 7 8 999" NoEmbeddedVars="FALSE" _COMMENT="Test input"/>
<VARIABLE MODIFY STRING Option="\x0F" Destination="%tRawInput%" ToReplace=" " ReplaceWith=", " All="TRUE" IgnoreCase="FALSE" NoEmbeddedVars="FALSE"/>
<VARIABLE SET INTEGER Option="\x0D" Destination="%nLenRaw%" Text_Variable="%tRawInput%"/>
<REPEAT UNTIL Variable="%tChar%" Condition="\x06" Value=","/>
<VARIABLE MODIFY STRING Option="\x09" Destination="%tChar%" Variable="%tRawInput%" Start="%nLenRaw%" Count="1" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY INTEGER Option="\x08" Destination="%nLenRaw%"/>
<END REPEAT/>
<VARIABLE MODIFY INTEGER Option="\x00" Destination="%nLenRaw%" Value1="%nLenRaw%" Value2="2"/>
<VARIABLE MODIFY STRING Option="\x09" Destination="%tEnd%" Variable="%tRawInput%" Start="%nLenRaw%" Count="10" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x0A" Destination="%tRawInput%" Start="%nLenRaw%" Count="10"/>
<VARIABLE MODIFY STRING Option="\x06" Destination="%tRawInput%" Value=" and" NoEmbeddedVars="FALSE"/>
<VARIABLE MODIFY STRING Option="\x07" Destination="%tRawInput%" Variable="%tEnd%" NoEmbeddedVars="FALSE"/>
<TEXT BOX DISPLAY Title="RESULT" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs20 %tRawInput%\r\n\\par }\r\n" Left="Center" Top="Center" Width="278" Height="200" Monitor="0" OnTop="TRUE" Keep_Focus="TRUE" Mode="\x00" Delay="0"/>

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...