How to get common words from two different sentences by using ENTRY function in progress4gl? - progress-4gl

How to get common words from two different sentences by using ENTRY function in progress4gl?
define variable a1 as character no-undo initial "hi dude do".
define variable a2 as character no-undo initial "hi man it".
define variable cnta as character.
define variable cntb as character.
define variable cntc as character.
define variable i as integer.
define variable j as integer.
do i = 1 to 3:
entry (i,a1,"").
do j = 1 to 3:
entry (j,a2,"").
end.
end.
/* assign cntc = cnta matches cntb . */

define variable a1 as character no-undo initial "hi dude do".
define variable a2 as character no-undo initial "hi man it".
define variable common as character no-undo.
define variable cc as integer no-undo.
define variable ii as integer no-undo.
define variable jj as integer no-undo.
define variable n1 as integer no-undo.
define variable n2 as integer no-undo.
n1 = num-entries( a1 ).
n2 = num-entries( a2 ).
do ii = 1 to n1:
do jj = 1 to n2:
if entry ( ii, a1, " ") = entry( jj, a2, " " ) then
do:
cc = cc + 1.
common = common + " " + entry( ii, a1, " " ).
end.
end.
end.
display trim( cc ) common.
Notes:
The TRIM() function is just to clean up the "common" string so it doesn't have an extra space.
For performance reasons it is good to get in the habit of obtaining NUM-ENTRIES() outside the loop rather than with every iteration of the loop. It doesn't make much difference for small strings but for large strings it can have quite an impact.

1./*if i need to get the n number of words in two sentences from the user at the run time , how to compare and the get the common words.
the following code compares and displays only first letter of the two sentence.
*/
define variable a1 as character no-undo.
define variable a2 as character no-undo.
define variable common as character no-undo.
define variable a1 as character FORMAT "x(64)" no-undo /* initial "hi d do" */.
define variable a2 as character FORMAT "x(64)" no-undo /* initial "hi d it" */.
define variable common as character FORMAT "x(64)" no-undo.
define variable c1 as character FORMAT "x(64)" no-undo.
define variable x as character FORMAT "x(64)" no-undo.
define variable y as character FORMAT "x(64)" no-undo.
define variable cc as integer no-undo initial 0.
define variable ii as integer no-undo.
define variable jj as integer no-undo.
define variable n1 as integer no-undo.
define variable n2 as integer no-undo.
set a1.
n1 = num-entries( a1,"" ).
set a2.
n2 = num-entries( a2,"" ).
do ii = 1 to n1:
do jj = 1 to n2:
if entry ( ii,a1, " ") matches entry( jj,a2, " " ) then
do:
common = entry( ii, a1, " " ).
display common .
end.
end.
end.

Related

Length of Array in progress?

Given two arrays, ( for example 1,2,3,4,5 and 2,3,1,0). Find which number of first array is not present in the second array. How can i get Length of Arrays in progress 4gl ?
If the object in question is an ARRAY, rather than a LIST, you use the EXTENT() function to determine the number of elements. Using arrays:
define variable a1 as integer no-undo extent 5 initial [ 1, 2, 3, 4, 5 ].
define variable a2 as integer no-undo extent 4 initial [ 2, 3, 1, 0 ].
define variable i as integer no-undo.
define variable j as integer no-undo.
define variable ok as logical no-undo.
do i = 1 to extent( a1 ):
ok = no.
do j = 1 to extent( a2 ):
if a1[i] = a2[j] then ok = yes.
end.
if ok = no then message a1[i] "is not in a2".
end.
To have the length of a list (number of items of the list), you can use NUM-ENTRIES() function.
To know if an item is present in a list, you can use LOOKUP() function.
So for your example, you can do something like this:
DEFINE VARIABLE wclist1 AS CHARACTER NO-UNDO INITIAL "1,2,3,4,5".
DEFINE VARIABLE wclist2 AS CHARACTER NO-UNDO INITIAL "2,3,1,0".
DEFINE VARIABLE wc-list-no-present AS CHARACTER NO-UNDO.
DEFINE VARIABLE wi-cpt AS INTEGER NO-UNDO.
/* For each items of list1 */
DO wi-cpt = 1 TO NUM-ENTRIES(wclist1, ","):
/* Test if the item is in list 2 */
IF LOOKUP(ENTRY(wi-cpt, wclist1, ","), wclist2, ",") = 0
THEN
wc-list-no-present = wc-list-no-present + "," + ENTRY(wi-cpt, wclist1, ",").
END.
/* TRIM is to remove the first "," */
DISPLAY TRIM(wc-list-no-present, ",").
def var a as int extent 5 initial [1,2,3,4,5] no-undo.
def var b as int extent 4 initial [2,3,1,0] no-undo.
def var i as int no-undo.
def var j as int no-undo.
loop:
repeat i = 1 to extent(a):
repeat j = 1 to extent(b):
if a[i] = b[j]
then next loop.
end.
Display a[i] "not in b array" format "x(20)".
end.

OpenEdge: how to remove HTML tags from a string?

I have tried doing this:
REPLACE(string, "<*>", "").
but it doesn't seem to work.
REPLACE doesn't work like that. There's no wildcard matching in it.
I've included a simple way of doing this below. However, there's lots of cases that this wont work in - non well formed html etc. But perhaps you can start here and move forward by yourself.
What I do is look for < and > in the text and replace everything between it with a pipe (|) (you could select any character - preferably something not present in the text. When that's done all pipes are removed.
Again, this is a quick and dirty solution and not safe for production...
PROCEDURE cleanHtml:
DEFINE INPUT PARAMETER pcString AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER pcCleaned AS CHARACTER NO-UNDO.
DEFINE VARIABLE iHtmlTagBegins AS INTEGER NO-UNDO.
DEFINE VARIABLE iHtmlTagEnds AS INTEGER NO-UNDO.
DEFINE VARIABLE lHtmlTagActive AS LOGICAL NO-UNDO.
DEFINE VARIABLE i AS INTEGER NO-UNDO.
DO i = 1 TO LENGTH(pcString):
IF lHtmlTagActive = FALSE AND SUBSTRING(pcString, i, 1) = "<" THEN DO:
iHtmlTagBegins = i.
lHtmlTagActive = TRUE.
END.
IF lHtmlTagActive AND SUBSTRING(pcString, i, 1) = ">" THEN DO:
iHtmlTagEnds = i.
lHtmlTagActive = FALSE.
SUBSTRING(pcString, iHtmlTagBegins, iHtmlTagEnds - iHtmlTagBegins + 1) = FILL("|", iHtmlTagEnds - iHtmlTagBegins).
END.
END.
pcCleaned = REPLACE(pcString, "|", "").
END PROCEDURE.
DEFINE VARIABLE c AS CHARACTER NO-UNDO.
RUN cleanHtml("This is a <b>text</b> with a <i>little</i> bit of <strong>html</strong> in it!", OUTPUT c).
MESSAGE c VIEW-AS ALERT-BOX.

How to test if string is numeric using Progress 4GL

Does Progress 4GL have a function for testing whether a string is numeric, like PHP's is_numeric($foo) function?
I've seen the function example at http://knowledgebase.progress.com/articles/Article/P148549 to test if a character in a string is numeric. Looks like it has a typo, btw.
But I would think the language would be a built-in function for this.
I was looking at this myself recently. The approved answer given to this doesn't work in 100% situations.
If the user enters any of the following special string characters: ? * - or + the answer won't work.
A single plus or minus(dash) is converted to 0 which you may not want.
A single question mark character is valid value which progress recognises as unknown value at which again you may not want.
A single or group asterisks on their own also get converted to 0.
If you run the following code you'll see what I mean.
DISP DECIMAL("*")
DECIMAL("**")
DECIMAL("?")
DECIMAL("+")
DECIMAL("-").
The following additional code maybe useful to get around this
DEFINE VARIABLE iZeroCode AS INTEGER NO-UNDO.
DEFINE VARIABLE iNineCode AS INTEGER NO-UNDO.
DEFINE VARIABLE chChar AS CHARACTER NO-UNDO.
ASSIGN iZeroCode = ASC("0")
iNineCode = ASC("9")
chChar = SUBSTRING(cNumber,1,1).
IF NOT(ASC(chChar) >= iZeroCode AND ASC(chChar) <= iNineCode) THEN DO:
MESSAGE "Invalid Number..." VIEW-AS ALERT-BOX.
END.
Do not need a function can jsut do a straight conversion.
ASSIGN dNumber = DECIMAL(cNumber) NO-ERROR.
IF ERROR-STATUS:ERROR THEN
DO:
{Handle issues}
END.
or if it is always whole numbers can use INTEGER instead of DECIMAL.
The language does not have a built-in "isNum()" type of function.
An alternative to the kbase method would be:
function isNum returns logical ( input s as character ):
define variable n as decimal no-undo.
assign
n = decimal( s )
no-error
.
return ( error-status:num-messages = 0 ).
end.
display isNum( "123" ) isNum( "xyz" ).
This code handles any numeric strings - even if the used Character is longer than the max Decimal length etc.
FUNCTION isNumeric RETURNS LOGICAL (textvalue AS CHAR):
DEF VAR i AS INT NO-UNDO.
IF textvalue = ? THEN RETURN TRUE.
DO i = 1 TO (LENGTH(textvalue) - 1):
INT(SUBSTRING(textvalue, i, (i + 1))) NO-ERROR.
IF ERROR-STATUS:ERROR THEN RETURN FALSE.
END.
RETURN TRUE.
END FUNCTION.
Works 100% of the time
FUNCTION is-num RETURNS LOGICAL
(INPUT cString AS CHARACTER):
DEFINE VARIABLE iZeroCode AS INTEGER NO-UNDO.
DEFINE VARIABLE iNineCode AS INTEGER NO-UNDO.
DEFINE VARIABLE cChar AS CHARACTER NO-UNDO.
DEFINE VARIABLE iCount AS INTEGER NO-UNDO.
DO iCount = 1 TO LENGTH(cString):
ASSIGN iZeroCode = ASC("0")
iNineCode = ASC("9")
cChar = SUBSTRING(cString,iCount,1).
IF NOT(ASC(cChar) >= iZeroCode AND ASC(cChar) <= iNineCode) THEN DO:
RETURN FALSE.
END.
END.
RETURN TRUE.
END.

Reference a table through a string representation of the name

I'm trying to write a modular procedure, where I pass in a string representation of a table name, and query/update that table.
What I tried was something to this affect:
PROCEDURE foo:
DEFINE INPUT PARAMETER chTableName AS CHARACTER NO-UNDO.
FIND FIRST VALUE(chTableName) NO-LOCK
WHERE blahblahblah NO-ERROR.
IF AVAIL VALUE(chTableName) THEN
ASSIGN
VALUE(chTableName).value = foo.
END PROCEDURE.
This obviously does not work, but hopefully this will get the point across of what I'm trying to accomplish.
Any help or info in this matter would be appreciated. Thanks.
Hopefully you are running version 9 or better where dynamic queries are available.
procedure x:
define input parameter tbl as character no-undo.
define input parameter fld as character no-undo.
define input parameter xyz as character no-undo.
define variable qh as handle no-undo.
define variable bh as handle no-undo.
define variable fh as handle no-undo.
create buffer bh for table tbl.
create query qh.
qh:set-buffers( bh ).
qh:query-prepare( "for each " + tbl ).
qh:query-open.
do transaction:
qh:get-first( exclusive-lock ).
fh = bh:buffer-field( fld ).
display fh:buffer-value.
fh:buffer-value = xyz.
end.
delete object bh.
delete object qh.
return.
end.
run x ( "customer", "name", "fred" ).
find first customer no-lock.
display name.
This can get you started:
DEFINE TEMP-TABLE tt NO-UNDO
FIELD a AS INTEGER.
PROCEDURE foo:
DEFINE INPUT PARAMETER pcTable AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER pcWhere AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER pcField AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER piValue AS INTEGER NO-UNDO.
DEFINE VARIABLE hBuffer AS HANDLE NO-UNDO.
DEFINE VARIABLE hQuery AS HANDLE NO-UNDO.
CREATE BUFFER hBuffer FOR TABLE pcTable.
CREATE QUERY hQuery.
hQuery:SET-BUFFERS(hBuffer).
hQuery:QUERY-PREPARE("FOR EACH " + pcTable + " WHERE " + pcWhere).
hQuery:QUERY-OPEN().
hQuery:GET-FIRST().
IF hBuffer:AVAILABLE THEN DO:
ASSIGN
hBuffer:BUFFER-FIELD(pcField):BUFFER-VALUE = piValue NO-ERROR.
IF ERROR-STATUS:ERROR THEN DO:
MESSAGE "Failed" VIEW-AS ALERT-BOX ERROR.
END.
END.
DELETE OBJECT hBuffer.
DELETE OBJECT hQuery.
END PROCEDURE.
CREATE tt.
ASSIGN tt.a = 1.
RUN foo( INPUT "tt"
, INPUT "tt.a = 1"
, INPUT "a"
, INPUT 2).
DISPLAY tt.

Copy character values from character array variable to character (string) variable

this is my issue
define varibale MyArray as character extent 40 no-undo.
define variable Mychara as character no-undo.
Mychara = "hai this is checking how to copy values"
Now i want to copy this string to my "MyArray". So that it should be as follows
MyArray[1]=h ,MyArray[2]=a ,MyArray[3]=i ,MyArray[4]="" ,MyArray[5]=t ,MyArray[6]=h
and so on...
So how to do it?
Given your code-example, this should do the trick:
define variable MyArr as character EXTENT 40 no-undo.
define variable Mychara as character no-undo.
Mychara = "hai this is checking how to copy values".
DEF VAR i AS INT NO-UNDO.
DO i = 1 TO 40:
MyArr[i] = SUBSTRING(MyChara,i,1).
END.
A caveat though: this means that you have to know the (maximum) size of your String beforehand, to define the array size appropriately.
little bit dynamically ;)
define variable MyArr as character EXTENT no-undo.
define variable Mychara as character no-undo.
DEF VAR i AS INT NO-UNDO.
Mychara = "hai this is checking how to copy values".
EXTENT (MyArr) = LENGTH (Mychara).
DO i = 1 TO EXTENT (MyArr):
MyArr[i] = SUBSTRING(MyChara,i,1).
END.
define var l_mychara as integer no-undo.
define variable MyArray as character format "x(5)" extent 40 no-undo.
define variable Mychara as character format "x(5)" no-undo.
def var i as int init 1.
Mychara = "hai this is checking how to copy values".
assign l_mychara = length(Mychara).
do while i <= l_mychara.
assign myarray[i] = substring(mychara,i,1).
if myarray[i] = "" then assign myarray[i] = "blank".
i = i + 1.
end.
disp Myarray .