Is there any proper example for explaining call-by-result ? (not pseudocode)
I have learned that ALGOL 68, Ada could use this way,
but I cannot find any clear example of Call-by-Result.
I just made by myself.
pseudocode
begin
integer n;
procedure p(k: integer);
begin
n := n+1;
k := k+4;
print(n);
end;
n := 0;
p(n);
print(n);
end;
Implement using Ada Language
call.adb
with Gnat.Io; use Gnat.Io;
procedure call is
x : Integer;
Procedure NonSense (A: in out integer) is
begin
x := x + 1;
A := A + 4;
Put(x);
end NonSense;
begin
x := 0;
NonSense (x);
Put(" ");
Put(x);
New_Line;
end call;
Since Ada uses call-by-result way, result should be 1 4. (It could be checked by entering this code into online-Ada-compiler "http://www.tutorialspoint.com/compile_ada_online.php")
And, other result applied different passing parameter types should be...
call by value: 1 1
call by reference: 5 5
(compare > call by value-result: 1 4)
Related
i have a problem developing this function, i have this text..
Testing Function
ok
US.Cool
rwgehtrhjyw54 US_Cool
fhknehq is ryhetjuy6u24
gflekhtrhissfhejyw54i
my function :
function TForm5.FindWordInString(sWordToFind, sTheString : String): Integer;
var
i : Integer; x:String;
begin
Result := 0;
for i:= 1 to Length(sTheString) do
begin
x := Copy(sTheString,i,Length(sWordToFind));
if X = sWordToFind then
begin
if X.Length > sWordToFind.Length then
begin
Result := 100;
break;
end else
begin
Result := i;
break;
end;
end;
end;
end;
now, i want X to be US.Cool, but here its always = US, because i want to check the length of sWordToFind and X.
After clarification, this question is about getting length of a word searched by its starting substring within a string. For example when having string like this:
fhknehq is ryhetjuy6u24
When you execute a desired function for the above string with the following substrings, you should get results like:
hknehq → 0 → substring is not at the beginning of a word
fhknehq → 7 → length of the word because substring is at the beginning of a word
yhetjuy6u24 → 0 → substring is not at the beginning of a word
ryhetjuy6u24 → 12 → length of the word because substring is at the beginning of a word
If that is so, I would do this:
function GetFoundWordLength(const Text, Word: string): Integer;
const
Separators: TSysCharSet = [' '];
var
RetPos: PChar;
begin
Result := 0;
{ get the pointer to the char where the Word was found in Text }
RetPos := StrPos(PChar(Text), PChar(Word));
{ if the Word was found in Text, and it was at the beginning of Text, or the preceding
char is a defined word separator, we're at the beginning of the word; so let's count
this word's length by iterating chars till the end of Text or until we reach defined
separator }
if Assigned(RetPos) and ((RetPos = PChar(Text)) or CharInSet((RetPos - 1)^, Separators)) then
while not CharInSet(RetPos^, [#0] + Separators) do
begin
Inc(Result);
Inc(RetPos);
end;
end;
I spend a few times on your idea, so i wrote below codes, but it is not a good way for develop a Start With search. with some research you can find builtin functions, that provide better performance. you can try StrUtils.SearchBuf Function it will provide a full function string search.
anyway this code are working with SPACE separator, I hope it will be useful for you:
function TForm5.FindWordInString(sWordToFind, sTheString : String): Integer;
var
i : Integer; x:String;
flag : Boolean;
begin
Result := 0;
i := 1;
flag := False;
while True do
begin
if i > Length(sTheString) then Break;
if not flag then
x := Copy(sTheString,i,Length(sWordToFind))
else
begin
if sTheString[i] = ' ' then Break;
x := x + sTheString[i];
end;
if (X = sWordToFind) then
begin
flag := True;
if (X.Length >= sWordToFind.Length) and
(sTheString[i + Length(sWordToFind)] = ' ') then
break
else
i := i + Length(sWordToFind) -1;
end;
i := i + 1;
end;
Result := Length(x);
end;
How do i display all customers who have purchased an item on a certain day, my code doesn't seem to work, ive tried implementing the code within the displayByDayPurchased procedure. Sorry if this is a simple question, i'm still new to programming.
type
Tday = (monday, tuesday);
Tcustomer = record
itemPurchased:string;
dayPurchased: Tday;
end;
Tcustomers = array of Tcustomer;
function readDay(prompt:string): Tday;
var
selection:Integer;
begin
writeln('1. Monday');
writeln('2. Tuesday');
selection := ReadIntegerRange('Select day purcased (1 - 3): ', 1, 3);
result := Tday(selection-1);
end;
function readCustomers(prompt:string):TCustomers;
var
numOfCustomers:integer;
i:integer;
begin
numOfCustomers := ReadInteger('Enter number of customers: ');
setLength(result, numOfCustomers);
for i := 0 to high(result) do
begin
writeln(i);
result[i].itemPurchased := ReadString('Item Purchased: ');
result[i].dayPurchased := readDay(prompt);
end;
end;
procedure displayByDayPurchased(customers:TCustomers);
var
specific_day:integer;
begin
specific_day := ReadInteger('Enter day to see items purchased');
if (specific_day = customers.dayPurchased[specific_day])then
begin
end;
end;
procedure Main();
var
customer: Tcustomers;
begin
customer := readCustomers('Read in customers');
end;
begin
Main();
end.
my code doesn't seem to work, ive tried implementing the code within the displayByDayPurchased procedure.
Well, in the code you've posted, your displayByDayPurchased doesn't actually implement anything which would result in matching records being displayed, all you have is an empty begin ... end block:
if (specific_day = customers.dayPurchased[specific_day])then
begin
end;
and a) that doesn't correctly specify the match condition anyway and b) it will not compile because a Tcustomers array does not have a dayPurchased field ( a Tcustomer record does, but not the array).
Your code depends of quite a lot of things whose definitions you have not provide (ReadString, ReadInteger, ReadIntegerRange, etc) so it is difficult to give you a tested solution.
However an implementation of your displayByDayPurchased should probably look something like this:
procedure displayByDayPurchased(customers:TCustomers);
var
specific_day:integer;
i : integer;
ADay : Tday;
begin
specific_day := ReadInteger('Enter day to see items purchased');
ADay := Tday(specific_day); // converts integer to TDay value
for i := Low(customers) to High(Customers) do begin
if customers[i].dayPurchased = ADay then begin
writenln(customers[i].itemPurchased);
end;
end;
end;
I assume your Tcustomer record actually includes the customer's name, andx your code needs modifying to handle that.
Btw, your function readDay(prompt:string): Tday is wrong; Because of your definition of Tday, the allowed values in readDay should be 0 and 1, because the lowest value of the Tday enumeration actually corresponds to zero, not 1.
Also, you did not say which Pascal compiler you are using, but most modern versions allow a call like Tday(integerValue) to convert an integer to an instance value of the enumeration.
I'm migrating the database engine an application from MySql to SAP HANA.
I found a little trouble. I have a query like this:
Select SUBSTRING_INDEX(id, "-", -2) as prod_ref From products;
I don't know how to "translate" the function substring_index, because the initial part of the id has a variable length.
Thanks.
This can be done using a regex:
select substr_regexpr( '.*-([^-]*-[^-]*)$' in 'varia-ble---part-part1-part2' group 1) from dummy;
select substr_regexpr( '.*-([^-]*-[^-]*)$' in 'variable-part-part1-part2' group 1) from dummy;
According to the HANA 2.0 SP0 doc you could use locate with a negative offset (and then using right()), but this does not work on my system ("...feature isn't supported...")
If you execute such queries on a regular basis on lots of records I would recommend extracting the part you are interested in during ETL into a separate field. Or, alternatively fill a separate field using " GENERATED ALWAYS AS...".
I have seen it more than once, that people calculate a field like this in complex SQL queries or complex CalcViews, and then wonder why performance is bad when selecting 100 million records and filtering on the calculated field etc... Performance is usually no problem when you have aggregated your intermediate result set to a reasonable size and then apply "expensive" functions.
I don't think there is any direct function like SUBSTRING_INDEX in SAP HANA. But you have a work around alternative by creating a function to pass the input string and delimiter.
And I am assuming that -2 in SUBSTRING_INDEX and providing the solution
Reverse the string and get the position of the second delimiter, '-' in your case, into "obtainedPosition"
Now subtract that "obtainedPosition" from the length of the string.
obtainedPosition = LENGTH(id) - obtainedPosition
Using that value in the inbuilt substring function you can get the required string and return it from the function.
SELECT SCHEMA.FN_SUBSTRING_INDEX(id,obtainedPosition) INTO ReturnValue FROM DUMMY;
CREATE FUNCTION FN_SUBSTRING_INDEX
(
id VARCHAR(500),
delim VARCHAR(2)
)
RETURNS SplitString VARCHAR(500)
LANGUAGE SQLSCRIPT AS
BEGIN
DECLARE reversedString VARCHAR(500);
DECLARE charString VARCHAR(2);
DECLARE i INT := LENGTH(:id);
DECLARE len INT := LENGTH(:id);
DECLARE obtainedPosition INT := 0;
DECLARE flag INT := 0;
reversedString := '';
--loop to reverse the inputstring
WHILE :i > 0
DO
reversedString = CONCAT(:reversedString, SUBSTRING(:id,:i,1));
i := :i - 1;
END WHILE;
--loop to get the second delimiter position
i := 1;
WHILE :i <= :leng
DO
charString := '';
charString := SUBSTRING(:reversedString,i,1);
IF((:charString = :delim ) AND (:flag < 2)) THEN
BEGIN
obtainedPosition := :i;
flag := :flag + 1;
END;
END IF;
i := :i + 1;
END WHILE;
--IF condition to check if at least 2 delimiters are available, else print complete string
IF(flag = 2) THEN
obtainedPosition := :len - :obtainedPosition + 2; --2 is added to avoid the character at that position and '-' from printing
ELSE
obtainedPosition := 1;
END IF;
--SplitString contains the string's splitted return value
SELECT SUBSTRING(:id,:obtainedPosition) INTO SplitString FROM DUMMY;
END;
The above function is modified from http://www.kodyaz.com/sap-abap/sqlscript-reverse-string-function-in-sap-hana.aspx
For string functions in SAP HANA refer to this: http://www.sapstudent.com/hana/sql-string-functions-in-sap-hana/3
You can use anonymous block in SAP HANA to call and check the function
DO
BEGIN
DECLARE id VARCHAR(500) := 'Test-sam-ple-func';
DECLARE delim VARCHAR(2) := '-';
SELECT SCHEMA.FN_SUBSTRING_INDEX(id,delim) AS "SplitStringIndex" FROM DUMMY;
END;
I would be glad to know reason for a downvote. :)
can anybody help me with my sorting function - seriously I don't know how can I make it work as supposed to. :( Database is in MariaDB in Xampp. I use phpMyAdmin to execute the query.
DELIMITER $$
DROP FUNCTION IF EXISTS convRomanNumeral$$
CREATE FUNCTION convRomanNumeral (numeral CHAR(4))
RETURNS INT
BEGIN
DECLARE intnum INT;
CASE numeral
WHEN "I" THEN intnum = 1;
WHEN "II" THEN intnum = 2;
END CASE;
RETURN intnum;
END;
$$
SET #iteration = -1;
UPDATE `st0gk_docman_documents`
SET created_on = DATE('2016-06-14') + INTERVAL(#iteration := #iteration + 1) SECOND
WHERE `docman_category_id` = 141 ORDER BY convRomanNumeral(SUBSTRING(SUBSTRING_INDEX(title,'/',1),' ',-2) ASC, SUBSTRING_INDEX(title,'/',-2)+0 ASC;
So what I want to achieve is to sort documents by title. Example titles are:
Document Nr I/36/2006
Document Nr II/36/2006
Document Nr I/32/2006
Document Nr II/19/2006
After sorting them by first Roman number and then by second Arabic number I want to update the date. Code below for updating by only second Arabic number works properly:
SET #iteration = -1;
UPDATE `st0gk_docman_documents`
SET created_on = DATE('2016-06-14') + INTERVAL(#iteration := #iteration + 1) SECOND
WHERE `docman_category_id` = 141 ORDER BY SUBSTRING_INDEX(title,'/',-2)+0 ASC;
I would like to use CASE to return proper variable for Roman values. I know it's not perfect but I can't even make the CASE and FUNCTION work. What I am doing wrong? All suggestions are welcome.
The best way to do this is to add another column that has a sortable equivalent of that string. And use non-SQL code to do the parsing and building of that column before inserting into the table.
First mistake that I was making it was trying to execute the whole query at once... After taking the first lodge out of the way the debugging seemed way simpler. :D
So I created my case function to convert Roman numerals:
DELIMITER $$
DROP FUNCTION IF EXISTS convRomanNumeralSubFunction$$
CREATE FUNCTION convRomanNumeralSubFunction (numeral CHAR(1))
RETURNS INT
BEGIN
DECLARE intnum INT;
CASE numeral
WHEN "I" THEN SELECT 1 INTO intnum;
WHEN "X" THEN SELECT 10 INTO intnum;
WHEN "C" THEN SELECT 100 INTO intnum;
WHEN "M" THEN SELECT 1000 INTO intnum;
WHEN "V" THEN SELECT 5 INTO intnum;
WHEN "L" THEN SELECT 50 INTO intnum;
WHEN "D" THEN SELECT 500 INTO intnum;
END CASE;
RETURN intnum;
END;
$$
After that I declared the second function needed for conversion. I don't know if You can declare function inside function... and I didn't want to waste more time on this. For sure You can declare Function inside Procedure. Anyhow. WARNING: This function is not proof of BAD numerals like IIX. Numerals like that or will be badly counted. Also AXI will not count.
DELIMITER $$
DROP FUNCTION IF EXISTS convRomanNumeral$$
CREATE FUNCTION convRomanNumeral (numeral CHAR(10))
RETURNS INT
BEGIN
DECLARE currentintnum, previntnum, intnum, counter, numerallength INT;
SET numerallength = LENGTH(numeral);
SET counter = numerallength;
SET intnum = 0;
SET previntnum = 0;
WHILE counter > 0 DO
SET currentintnum = CAST(convRomanNumeralSubFunction(SUBSTRING(numeral,counter, 1)) as integer);
IF currentintnum < previntnum THEN
SET intnum = intnum - currentintnum;
ELSE
SET intnum = intnum + currentintnum;
END IF;
SET previntnum = currentintnum;
SET counter = counter - 1;
END WHILE;
RETURN intnum;
END;
$$
So that's it. Now You can convert all kind of Roman numerals and sort them up.
Use this to test the conversion:
SELECT convRomanNumeral("XIX");
This is example sorting code that I in the end used:
SET #iteration = -1;
UPDATE `st0gk_docman_documents`
SET created_on = DATE('2016-06-07') + INTERVAL(#iteration := #iteration + 1) SECOND
WHERE `docman_category_id` = 67 ORDER BY convRomanNumeralBreak(SUBSTRING_INDEX(SUBSTRING_INDEX(title,'/',1),' ',-1)) ASC, SUBSTRING_INDEX(title,'/',-2)+0 ASC;
Also one more thing - if You'll try to excecute this on mySQL then You have to fix this line:
SET currentintnum = CAST(convRomanNumeralSubFunction(SUBSTRING(numeral,counter, 1)) as integer);
into this:
SET currentintnum = CAST(convRomanNumeralSubFunction(SUBSTRING(numeral,counter, 1)) as SIGNED);
This code could be improved but as the #Rick James stated this should be done differently - not in as db update but in different table structure and sorting mechanism.
So I have this piece of Pascal code:
program P;
var a: array [1..2] of Integer;
var i :Integer;
var k :Integer;
procedure update(x,y,z: Integer);
begin
x := x+1;
y := x*2;
x := y;
k := x;
end
begin
a[1] := 5; a[2] := 10;
k := 3;
for i:=1 to 2 do
begin
update(a[i],a[2],k);
print(a);
print(k)
end
end.
(assume that 'print' prints elements of array separated by spaces, and then prints a new line and also for an integer it just prints it)
And i'm trying to understand how different the output would be if the function call was by value-result or by reference.
obviously, if it was just by-value, it's easy to tell that the procedure wouldn't make any difference to the actual parameter, i.e the output (in by value) should be: 5 10 3 5 10 3.
I think that if it was be value-result it would have been, at least the first iteration: 12 12 12.
at the case of by reference I got confused.
What would it be?
You haven't declared any variable parameters. The variable K will be changed, but that doesn't count in this context and is generally considered bad practice.
PROGRAM ParamTest;
VAR
A, B : Integer;
PROCEDURE TestProc(X : Integer; VAR Y : Integer; CONST Z : Integer);
BEGIN
X := X + Z;
Y := Y + Z;
END;
BEGIN
A := 10;
B := 10;
TestProc(A, B, 5);
WriteLn(A, ' ', B);
END.
X : Call by value
Y : Call by reference
Z : Call by constant
The output of this program should be 10 15.
With declaring Zas constant parameter you promise to the compiler that you don't change that value. The following procedure variant should give an error while compiling.
PROCEDURE TestProc(X : Integer; VAR Y : Integer; CONST Z : Integer);
BEGIN
X := X + Z;
Y := Y + Z;
Z := Z + 1;
END;