How do I rectify this switch case error in Ada? - ada

with Ada.Text_IO; use Ada.Text_IO;
procedure factor is
rate: Integer;
begin
Put("Enter rate: ");
Get(rate);
case rate is
when 1 | 2 =>
Put("Factor =", factor = 2 * rate - 1);
when 3 | 5 =>
Put("Factor =", factor = 3 * rate + 1);
when 4 =>
Put("Factor =", factor = 4 * rate - 1);
when 6 | 7 | 8 =>
Put("Factor =", factor = rate - 2);
when others =>
Put("Factor =", rate);
end case;
end factor;
I am new to ada and im not able to resolve this error. please help me with this code
this is a simple switch case in ada.. this should return factor and rate is the input from user

Here is a comparison of your program and one that compiles and works correctly:
---------------------------------------------------------------
-- Original program:
--
-- with Ada.Text_IO; use Ada.Text_IO;
-- procedure factor is
-- rate: Integer;
-- begin
-- Put("Enter rate: ");
-- Get(rate);
-- case rate is
-- when 1 | 2 =>
-- Put("Factor =", factor = 2 * rate - 1);
-- when 3 | 5 =>
-- Put("Factor =", factor = 3 * rate + 1);
-- when 4 =>
-- Put("Factor =", factor = 4 * rate - 1);
-- when 6 | 7 | 8 =>
-- Put("Factor =", factor = rate - 2);
-- when others =>
-- Put("Factor =", rate);
-- end case;
-- end factor;
------------------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Main is
rate : Integer;
factor : Integer;
begin
Put ("Enter rate: ");
Get (rate);
case rate is
when 1 | 2 =>
factor := 2 * rate - 1;
when 3 | 5 =>
factor := 3 * rate + 1;
when 4 =>
factor := 4 * rate - 1;
when 6 | 7 | 8 =>
factor := rate - 2;
when others =>
factor := rate;
end case;
Put_Line ("Factor =" & factor'Image);
end Main;
In Ada I/O procedures and functions are tied to the types being read or written. Therefore, reading an Integer requires an instance of Ada.TextIO.Integer_IO. The predefined package Ada.Integer_Text_IO is just such a package. The Get procedure from that package is used to input the value for the rate variable.
In Ada variables must be declared before they are used and they are only declared in the declarative part of a procedure or function; that is, the part of the procedure or function before the reserved word begin. The variable named factor is declared in the declarative part of the procedure main.
The case statement calculates the value of factor based upon the rate input. After the end of the case statement the variable factor has been assigned a value according to the logic in the case statement. It is then output with a trailing newline character using the Put_Line procedure.
The Put_Line procedure requires a single string for its argument. That string is created by concatenating a literal string "Factor =", with the string representation of the value in factor. The 'Image attribute converts the integer value in factor to its corresponding string representation. That string value is concatenated with the literal string forming a single string argument for the Put_Line procedure.

First of all, you did not mention the error you got.
I think you got this first
factor.adb:8:05: no candidate interpretations match the actuals:
factor.adb:8:05: missing argument for parameter "Item" in call to "get" declared at a-textio.ads:239
factor.adb:8:05: missing argument for parameter "Item" in call to "get" declared at a-textio.ads:205
factor.adb:8:09: expected type "Standard.String"
factor.adb:8:09: found type "Standard.Integer"
If you carefully read, you'll see that the compiler complains about the types. It expected Standard.String and got Standard.Integer.
In fact, you used Ada.Text_io which is for text only (cf. ARM).
As you want to get an integer, you must use the integer version for IO i.e. Integer_IO.
For displaying, there are several ways but you can use Integer'Image(my_int)
to convert your integer to a string.
Then check where the variable factor is declared. In fact, you never declared it but don't even have to do so.
Finally check how you can concatenate two strings, you will be able to join the "Factor =" with the integer converted to string.

When you like to get rate from the user it is good to know what rate is.
From the case statement it looks like a rate type could be declared as -
1) type Rate_Type is 1 .. 8;
2) type Rate_Type is new Integer range 1 .. 8;
3) subtype Rate_Type is Integer range 1 .. 8;
Rate : Rate_Type;
In this case (new to Ada) option 3 would be the best option. So now Rate is an Integer in the range from (including) 1 to (including) 8.
To get Rate from the user
package Rate_IO is new Ada.Text_IO.Integer_IO (Rate_Type);
The package Rate_IO is like Ada.Integer_Text_IO but for Rate_Type instead of Integer and Rate is input from the user
Rate_IO.Get (Rate);
The advantage of Rate_IO is that if the user enters a value not in the range of Rate_Type an exception (Data_Error) is raised.
This will cause the program to stop with some message.
It is often a better choice to stop the program than to let it run with a value out of range. At least it makes the program much simpler.
So now that Rate is in range, the case statement looks like
case rate is
when 1 | 2 => factor := 2 * rate - 1;
when 3 | 5 => factor := 3 * rate + 1;
when 4 => factor := 4 * rate - 1;
when 6 | 7 | 8 => factor := 1 * rate - 2;
end case;
Below is a program with an exception handler. And uncommented is an example with a default value for rate.
with ada.text_io; use ada.text_io;
with ada.integer_text_io;
procedure program_2 is
subtype rate_t is integer range 1 .. 8;
package rate_io is new ada.text_io.integer_io (rate_t);
rate : rate_t;
factor : integer;
begin
-- Input
put ("Enter rate: ");
rate_io.get (rate); -- May raise data_error exception
-- Calculate
case rate is
when 1 | 2 => factor := 2 * rate - 1;
when 3 | 5 => factor := 3 * rate + 1;
when 6 | 7 | 8 => factor := 1 * rate - 2;
when 4 => factor := 1 * rate + 0;
end case;
-- Output
put ("factor =");
ada.integer_text_io.put (factor);
new_line;
-- Error handling
exception when data_error =>
put_line ("rate out of range");
end program_2;
-- Put begin/exception/end block around rate_io.get to
-- provide ie a default value:
--
-- begin
-- rate_io.get (rate);
-- exception when data_error =>
-- rate := rate_t'first; -- A default value
-- end;

Related

Get output from array in Ada

I want to print array data user input.
But it give me error. I need to get input from user and store in the array. After this i want to print it also count each duplicate word.
with Ada.Text_IO;
use Ada.Text_IO;
procedure Main is
type String_Val is array (1 .. 100) of Character;
type Int_Val is array (1 .. 100) of Integer;
Data : String_Val;
begin
Put_Line ("Please enter values (use space as seperator)");
for I in 1..String_Val'Length loop
Data(I) := Character'Value(Get_Line);
end loop;
for I in String_Val'Range loop
Put (String_Val (Data));
end loop;
end Main;
The following program reads a string as input, tallies the occurrences of characters in the string and outputs both the input string and the occurrences of each character in the input string.
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
type Character_Counts is array (Character) of Natural;
Input : String (1 .. 100); -- String is an array of Character;
Counts : Character_Counts := (Others => 0);
Length : Natural;
begin
Put_Line("Enter a string:");
Get_Line(Item => Input,
Last => Length);
Put_Line ("You entered:");
-- output the data entered by the user
Put_Line(Input(1..Length));
-- Count character occurrences in the string
for I in 1 .. Length loop
Counts(Input(I)) := Counts(Input(I)) + 1;
end loop;
-- output counts of characters in the string
for C in Counts'Range loop
if Counts(C) > 0 then
Put_Line(Character'Image(C) & " : " & Counts(C)'Image);
end if;
end loop;
end Main;
Type Character_Counts is an array of Natural indexed by all the values of type Character. Natural is a pre-defined subtype of integer with a minimum value of 0. The variable Counts is an instance of Character_Counts with all its elements initialized to 0.
The Get_Line procedure returns the string you passed in, filled with characters up to the length of the string or the number of characters entered. The variable Length contains the number of characters entered by the user.
When counting the occurrences of the characters in the string the each character of the string is used as an index into the variable Counts, and the corresponding element in Counts is incremented.
A sample execution of this program is:
Enter a string:
This is a test.
You entered:
This is a test.
' ' : 3
'.' : 1
'T' : 1
'a' : 1
'e' : 1
'h' : 1
'i' : 2
's' : 3
't' : 2

Draw a ruler by writing a recursive program (Ada)

By using recursion, I need to write a program that allows the user to write how many sections and how long each section of the ruler should be. And then, based on that information, the program should be able to display the ruler that the user wants. In my code, I have managed to display the size of the ruler. However, I have some difficulty, writing a recursion that displays the length of each section. It seems like my second function (function Count) is somehow invisible because it does not affect the code, whether it exists or not.
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
Procedure Ruler is
section, length,Y: Positive;
function Factorial(value, value1: Natural) return Natural is --length of
begin --the ruler
Put("|");
if value > 1 then
return Factorial((value * value1)-1,1);
end if;
end Factorial;
function Count(value,value1: Natural) return natural is --Length of each
Calc: Natural; --section
begin
Calc:= (value*value1)/value;
Set_Col(Positive_Count(Calc));
Put("|");
return Count(1, calc+value1);
end Count;
begin
Put("The number of sections and the length of each section: ");
Get(section); Get(length);
Y:= Factorial(section, length);
Y:= Count(section, length);
end Ruler;
Here is a picture of a ruler with 4 sections and each section is 10 cm long:
So, I'm not sure why recursion is required, but below is an example that does the job. I must admit that it's not the most simple piece of code. The recursion is only a small portion of the code (see the Put_Rec function).
rulers.ads
package Rulers is
procedure Put_Ruler (Length, Minor_Tick, Major_Tick : Positive);
-- Draws a ruler of a given length.
end Rulers;
rulers.adb
with Ada.Strings.Fixed;
with Ada.Text_IO;
with Ada.Integer_Text_IO;
package body Rulers is
type On_Step_Fcn is access procedure (Buffer : out String;
Count : Natural);
--------------------
-- Put_Ruler_Part --
--------------------
procedure Put_Ruler_Part
(Step : Integer;
Last : Integer;
On_First : String;
On_Step : On_Step_Fcn;
On_Last : String)
is
use Ada.Text_IO;
procedure Put_Rec (Count : Natural) is
Buffer : String (1 .. Step);
begin
if Count <= Last then -- Check continuation predicate.
On_Step (Buffer, Count);
Put (Buffer);
Put_Rec (Count + Step); -- Recurse.
end if;
end Put_Rec;
begin
Put (On_First);
Put_Rec (Step); -- Initiate recursion.
Put (On_Last);
New_Line;
end Put_Ruler_Part;
---------------------
-- Step functions --
---------------------
-- Functions that will be called on each recursion. The size of the
-- buffer is dictated by the (step-size known by the) calling function.
use Ada.Strings;
use Ada.Strings.Fixed;
procedure Image_Minor_Tick (Buffer : out String; Count : Natural) is
pragma Unreferenced (Count);
begin
Move ("|", Buffer, Justify => Right);
end Image_Minor_Tick;
procedure Image_Major_Tick (Buffer : out String; Count : Natural) is
pragma Unreferenced (Count);
begin
Move ("|", Buffer, Justify => Right);
end Image_Major_Tick;
procedure Image_Number (Buffer : out String; Count : Natural) is
begin
Move (Count'Image, Buffer, Justify => Right, Drop => Left);
end Image_Number;
---------------
-- Put_Ruler --
---------------
procedure Put_Ruler (Length, Minor_Tick, Major_Tick : Positive) is
begin
-- Minor scale.
Put_Ruler_Part
(Step => Minor_Tick,
Last => Length,
On_First => "|",
On_Step => Image_Minor_Tick'Access,
On_Last => "");
-- Major scale.
Put_Ruler_Part
(Step => Major_Tick,
Last => Length,
On_First => "|",
On_Step => Image_Major_Tick'Access,
On_Last => "");
-- Numbers.
Put_Ruler_Part
(Step => Major_Tick,
Last => Length,
On_First => "0",
On_Step => Image_Number'Access,
On_Last => " cm");
end Put_Ruler;
end Rulers;
main.adb
with Ada.Text_IO; use Ada.Text_IO;
with Rulers; use Rulers;
procedure Main is
begin
Rulers.Put_Ruler
(Length => 40,
Minor_Tick => 1,
Major_Tick => 10);
New_Line;
Rulers.Put_Ruler
(Length => 40,
Minor_Tick => 2,
Major_Tick => 5);
New_Line;
Rulers.Put_Ruler
(Length => 40,
Minor_Tick => 1,
Major_Tick => 1);
New_Line;
end Main;
output
|||||||||||||||||||||||||||||||||||||||||
| | | | |
0 10 20 30 40 cm
| | | | | | | | | | | | | | | | | | | | |
| | | | | | | | |
0 5 10 15 20 25 30 35 40 cm
|||||||||||||||||||||||||||||||||||||||||
|||||||||||||||||||||||||||||||||||||||||
01234567890123456789012345678901234567890 cm

Count Female And Male Student using function in pl/sql

I would like to create a function in PL/SQL that returns the number of males and females in the database. I created a function which returns the number of either males or females in the database, but not both. This is the code I used.
This is the the code I used to create the function:
create or replace function totalstudent
return number is
total_male number(2):=0;
begin
select count(*) into total_male from New_Student where gender='Male';
return total_male;
end;
The code I used to call it:
declare
c number(2);
begin
c:=totalstudent();
dbms_output.put_line('Total Number of Male is'||c);
end;
/
Here is the
result produced
Briefly, I want a function which will do what that function does but also display the number of Female entries... Both Female and Male entries are in the Database.
I'm not sure what your requirements are. I suggest using an input parameter:
-- These are the codes I used to create the function
CREATE OR REPLACE FUNCTION totalstudent (v_gender IN VARCHAR2)
RETURN NUMBER
IS
total_gender NUMBER (2) := 0;
BEGIN
SELECT COUNT (*)
INTO total_gender
FROM New_Student
WHERE gender = v_gender;
RETURN total_gender;
END;
-- The code I used to call it
DECLARE
c NUMBER (2);
BEGIN
c := totalstudent ('Male');
DBMS_OUTPUT.put_line ('Total Number of Male is' || c);
c := totalstudent ('Female');
DBMS_OUTPUT.put_line ('Total Number of Female is' || c);
END;
Regards

Describing a String type in Ada

I have a type similar to:
type ID is new String (1 .. 7);
-- Example: 123-456
How can I specify that format in code, either with Ada or SPARK?
I was thinking about Static_Predicate, but the condition that the string must start with 3 positive integers followed by a dash followed by another set of 3 positive integers can't be described with a Static_Predicate expression.
You have to use a Dynamic_Predicate for this:
type ID is new String (1 .. 7)
with Dynamic_Predicate => (for all I in ID'Range =>
(case I is
when 1 .. 3 | 5 .. 7 => ID (I) in '0' .. '9',
when 4 => ID (I) in '-'));
I'm using this quite a bit myself, but I mostly make the types subtypes of String instead of actual new types.

Why this PL/SQL doesn't work?

Im trying to learn PL/SQL. I am struck with this code. Please notify me where im going wrong. I use Oracle 10g in a command line .
declare
grade char(1):='&v_grade';
app varchar(15);
begin
app:=case v_grade
when 'a' then
dbms_output.put_line('Excellent');
when 'b' then
dbms_output.put_line('Good');
else
dbms_output.put_line('Bad');
end case;
dbms_output.put_line('Grade'||grade||' Appraisal:'||app);
end;
/
It shows
Enter value for v_grade: a
old 2: grade char(1):='&v_grade';
new 2: grade char(1):='a';
dbms_output.put_line('Excellent');
*
ERROR at line 7:
ORA-06550: line 7, column 34:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
. ( * % & = - + < / > at else end in is mod remainder not rem
when <an exponent (**)> <> or != or ~= >= <= <> and or like
LIKE2_ LIKE4_ LIKEC_ between || multiset member SUBMULTISET_
The symbol ";" was ignored.
ORA-06550: line 9, column 29:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
. ( * % & = - + < / > at else end in is mod remainder not rem
when <an exponent (**)> <> or != or ~= >= <= <> and or like
LIKE2_ LIKE4_ LIKEC_ between ||
ORA-06550: line 11, column 28:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
. ( * % & = - + < / > at end in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like LIKE2_
LIKE4_ LIKEC_ between || multiset
please notify me where i am going wrong.
T.J. Crowder is sort of right, you shouldn't have a semicolon within a case statement in SQL, but this is the PL/SQL version so it's slightly different.
You are currently trying to assign the (non-existent) return from the dbms_output.put_line procedure (not function) call to your app variable.
For the assignment to work you need the case to evaluate to a string, so you can just use text literals; but the assignment needs to be in each branch:
declare
grade char(1):='&v_grade';
app varchar(15);
begin
case grade
when 'a' then app:= 'Excellent';
when 'b' then app:= 'Good';
else app := 'Bad';
end case;
dbms_output.put_line('Grade '||grade||' Appraisal: '||app);
end;
/
Which when run gets:
Enter value for v_grade: a
Grade b Appraisal: Excellent
PL/SQL procedure successfully completed.
Or use a query to do the assignment, though this is not quite as efficient:
declare
grade char(1):='&v_grade';
app varchar(15);
begin
select case grade
when 'a' then 'Excellent'
when 'b' then 'Good'
else 'Bad'
end case
into app
from dual;
dbms_output.put_line('Grade '||grade||' Appraisal: '||app);
end;
/
Enter value for v_grade: b
Grade b Appraisal: Good
PL/SQL procedure successfully completed.
Or you can do the output directly in each branch:
declare
grade char(1):='&v_grade';
begin
dbms_output.put('Grade '||grade||' Appraisal: ');
case grade
when 'a' then
dbms_output.put_line('Excellent');
when 'b' then
dbms_output.put_line('Good');
else
dbms_output.put_line('Bad');
end case;
end;
/
Enter value for v_grade: c
Grade c Appraisal: Bad
PL/SQL procedure successfully completed.
The first part of your output is before the case now.
You're basically mixing up the different approaches.
You might want to change the first line to:
grade char(1):= upper('&v_grade');
... and then make the case look for A,B,C instead of a,b,c - then it won't matter what case the input is in.
You can read more about the PL/SQL case statemnt here and here.

Resources