PL/SQL annoymous procedure + cursor problems - plsql

I am trying to write an anonymous block as follows, but it always give me error messages as
Encountered the symbol "=" when expecting one of the following. ( ) , * # % & - + / at mod remainder rem and or || multiset.
I don't know what it means.

You're missing a : in front of the =in several places, e.g. here:
get_sectno='1031';
The assignment operator in PL/SQL is :=- = is (just like in plain SQL) comparison for equality.
You're also missing the ; at the end of every call to
lowest_average (get_term, get_sectno, get_ctitle, get_sid, get_sname, get_average)

Related

Counting nr of elements in a file

I am trying to count the number of Harbour elements in an XML file. However, i keep getting the following error:
item expected, sequence found: (element harbour {...}, ...)
The code snippet is the following:
for $harbour in distinct-values(/VOC/voyage/leftpage/harbour)
let $count := count(/VOC/voyage/leftpage/harbour eq $harbour)
return concat($harbour, " ", $count)
Input XML:
<voyage>
<number>4411</number>
<leftpage>
<harbour>Rammekens</harbour>
</leftpage>
</voyage>
<voyage>
<number>4412</number>
<leftpage>
<harbour>Texel</harbour>
</leftpage>
</voyage>
Can someone help me out? How do I iterate over the number of harbours in the XML file instead of trying to use /VOC/voyage/leftpage/harbour?
eq is a value comparison, i.e. used to compare individual items. That is why the errors messages tells you that it is expecting a (single) item, but instead found all the harbour elements. You have to use the general comparison operator =. Also, when you would compare it like that
/VOC/voyage/leftpage/harbour = $harbour
it would always be 1 as it will compare the existence. instead, you want to filter out all harbour items which have an equal text element as child. You can do so using []. All together it will be
for $harbour in distinct-values(/VOC/voyage/leftpage/harbour)
let $count := count(/VOC/voyage/leftpage/harbour[. = $harbour])
return concat($harbour, " ", $count)
Also, if your XQuery processor supports XQuery 3.0 you can also use a group by operator, which in my opinion is nicer to read (and could be faster, but this depends on the implementation):
for $voyage in /VOC/voyage
let $harbour := $voyage/leftpage/harbour
let $harbour-name := $harbour/string()
group by $harbour-name
return $harbour-name || " " || count($harbour)

To lower case recursive algorithm

I have this code for returning a string in all lower case, using recursion:
function min(ch:string):string;
begin
if ( ch = '' ) then
min:= ''
else
if (ch[1] in ['A'..'Z']) then
begin
ch[1]:=chr(ord(ch[1])+32);
min:= ch[1] + min(copy(ch,2,length(ch)-1));
end;
end;
But it doesn't work:
When I run it with the example min('AbC') the output is a only not abc.
Where is the problem here?
The problem is that you do not always call the recursive function. As soon as you find a letter that is already lower case, you don't look any more at the characters that follow it. And so the return value is truncated up to that character.
You should also call it when the character being looked at is not a capital letter. So move the recursive call out of that if, and it will work:
function min(ch:string):string;
begin
if ( ch = '' ) then
min:= ''
else
begin
if (ch[1] in ['A'..'Z']) then
ch[1]:=chr(ord(ch[1])+32);
min:= ch[1] + min(copy(ch,2,length(ch)-1));
end;
end;
See it run on ideone.com.

printing string and calling recursive function

I am currently learning sml but I have one question that I can not find an answer for. I have googled but still have not found anything.
This is my code:
fun diamond(n) =
if(n=1) then (
print("*")
) else (
print("*")
diamond(n-1)
)
diamond(5);
That does not work. I want the code to show as many * as number n is and I want to do that with recursion, but I don't understand how to do that.
I get an error when I try to run that code. This is the error:
Standard ML of New Jersey v110.78 [built: Thu Aug 20 19:23:18 2015]
[opening a4_p2.sml] a4_p2.sml:8.5-9.17 Error: operator is not a
function [tycon mismatch] operator: unit in expression:
(print "*") diamond /usr/local/bin/sml: Fatal error -- Uncaught exception Error with 0 raised at
../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
Thank you
You can do side effects in ML by using ';'
It will evaluate whatever is before the ';' and discard its result.
fun diamond(n) =
if(n=1)
then (print "*"; 1)
else (print "*"; diamond(n-1));
diamond(5);
The reason for the error is because ML is a strongly typed language that although you don't need to specify types explicitly, it will infer them based on environmental factors at compile time. For this reason, every evaluation of functions, statements like if else need to evaluate to an unambiguous singular type.
If you were allowed to do the following:
if(n=1)
then 1
else print "*";
then the compiler will get a different typing for the then and else branch respectively.
For the then branch the type would be int -> int whereas the type for the else branch would be int -> unit
Such a dichotomy is not allowed under a strongly typed language.
As you need to evaluate to a singular type, you will understand that ML does not support the execution of a block of instructions as we commonly see in other paradigms which transposed to ML naively would render something like this:
....
if(n=1)
then (print "1"
print "2"
)
else (print "3"
diamond(n-1)
)
...
because what type would the then branch evaluate to? int -> unit? Then what about the other print statement? A statement has to return a singular result(even it be a compound) so that would not make sense. What about int -> unit * unit? No problem with that except that syntactically speaking, you failed to communicate a tuple to the compiler.
For this reason, the following WOULD work:
fun diamond(n) =
if(n=1)
then (print "a", 1) /* A tuple of the type unit * int */
else diamond(n-1);
diamond(5);
As in this case you have a function of type int -> unit * int.
So in order to satisfy the requirement of the paradigm of strongly typed functional programming where we strive for building mechanisms that evaluate to one result-type, we thus need to communicate to the compiler that certain statements are to be executed as instructions and are not to be incorporated under the typing of the function under consideration.
For this reason, you use ';' to communicate to the compiler to simply evaluate that statement and discard its result from being incorporated under the type evaluation of the function.
As far as your actual objective is concerned, following is a better way of writing the function, diamond as type int -> string:
fun diamond(n) =
if(n=1)
then "*"
else "*" ^ diamond(n-1);
print( diamond(5) );
The above way is more for debugging purposes.

Defining tables - strange bug

I got a strange kind of issue. When I define this table:
function test()
a = Float32[0.3010299957,0.3010299957,-0.3010299957,0.3010299957,0.3010299957]
return a[1]*a[3]
end
It's fine. After call test() i got correct output. But when I define this one, there is an error ErrorException("−3 not defined"):
function test()
a = Float32[2.718281828, −3.141592654 , 1.414213562 , 0.5772156649 , 0.3010299957]
return a[1]*a[2]
end
You're using two different dashes: - (HYPHEN-MINUS) in the first, and − (MINUS SIGN) in the second. Issues like these often happen when you copy text from a formatted source (web page, document, etc.) You want to use HYPHEN-MINUS:
julia> -1 # hyphen-minus
-1
julia> −1 # minus sign
ERROR: syntax: invalid character "−"

Ada String Concatenation

I have a function that returns a string for a particular item, and I need to call that function numerous times and combine those strings into one. The combined string is bounded. I've made sure to fill it when space characters when it initializes but I keep getting "length check failed" errors. Is there something basic I'm doing wrong here?
FOR I IN 1..Collection.Size LOOP
Combined_String := combined_string & Tostring(Collection.Book(I));
END LOOP;
Unbounded_String is probably the easiest way to go:
with Ada.Strings.Unbounded;
use Ada.Strings.unbounded;
...
Temp_Unbounded_String : Unbounded_String; -- Is empty by default.
...
for I in 1 .. Collection.Size loop
Append(Temp_Unbounded_String, ToString(Collection.Book(I));
end loop;
If you then need to have the result placed in your fixed length standard string:
declare
Temp_String : constant String := To_String(Temp_Unbounded_String);
begin
-- Beware! If the length of the Temp_String is greater than that of the
-- fixed-length string, a Constraint_Error will be raised. Some verification
-- of source and target string lengths must be performed!
Combined_String(Temp_String'Range) := Temp_String;
end;
Alternatively, you can use the Ada.Strings.Fixed Move() procedure to bring the Unbounded_String into the target fixed-length string:
Ada.Strings.Fixed.Move(To_String(Temp_Unbounded_String), Combined_String);
In this case, if the source string is "too long", by default a Length_Error exception is raised. There are other parameters to Move() that can modify the behavior in that situation, see the provided link on Move for more detail.
In order to assign Combined_String, you must assign the full correct length at once. You can't "build up" a string and assign it that way in Ada.
Without seeing the rest of your code, I think Ada.Strings.Unbounded is probably what you should be using.
I know this is an ancient question, but now that Ada 2012 is out I thought I'd share an idiom I've been finding myself using...
declare
function Concatenate(i: Collection'index)
is
(tostring(Collection(i) &
if (i = Collection'last) then
("")
else
(Concatenate(i+1))
);
s: string := Concatenate(Collection'first);
begin
Put_Line(s);
end;
Typed off the top of my head, so it'll be full of typos; and if you want it to work on empty collections you'll need to tweak the logic (should be obvious).
Ada 2012's expression functions are awesome!
Ada works best when you can use perfectly-sized arrays and strings. This works wonderfully for 99% of string uses, but causes problems any time you need to progressively build a string from something else.
Given that, I'd really like to know why you need that combined string.
If you really need it like that, there are two good ways I know of to do it. The first is to use "unbounded" (dynamically-sized) strings from Ada.Strings.Unbounded, as Dave and Marc C suggested.
The other is to use a bit of functional programming (in this case, recursion) to create your fixed string. Eg:
function Combined_String (String_Collection : in String_Collection_Type) return String is
begin
if String_Collection'length = 1 then
return String_Collection(String_Collection'first);
end if;
return String_Collection(String_Collection'first) &
Combined_String (String_Collection'first + 1 .. String_Collection'last);
end Combined_String;
I don't know what type you used for Collection, so I'm making some guesses. In particular, I'm assuming its an unconstrained array of fixed strings. If it's not, you will need to replace some of the above code with whatever your container uses to return its bounds, access elements, and perform slicing.
From AdaPower.com:
function Next_Line(File : in Ada.Text_IO.File_Type :=
Ada.Text_Io.Standard_Input) return String is
Answer : String(1..256);
Last : Natural;
begin
Ada.Text_IO.Get_Line(File => File,
Item => Answer,
Last => Last);
if Last = Answer'Last then
return Answer & Next_Line(File);
else
return Answer(1..Last);
end if;
end Next_Line;
As you can see, this method builds a string (using Get_Line) of unlimited* length from the file it's reading from. So what you'll need to do, in order to keep what you have is something on the order of:
function Combined_String (String_Collection : in String_Collection_Type)
Return String is
begin
if String_Collection'length = 1 then
Return String_Collection(String_Collection'First).All;
end if;
Recursion:
Declare
Data : String:= String_Collection(String_Collection'First).All;
SubType Constraint is Positive Range
Positive'Succ(String_Collection'First)..String_Collection'Last;
Begin
Return Data & Combined_String( String_Collection(Constraint'Range) );
End Recursion;
end Combined_String;
Assuming that String_Collection is defined as:
Type String_Collection is Array (Positive Range <>) of Access String;
*Actually limited by Integer'Range, IIRC

Resources