It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
program date;
uses wincrt;
var
m,ch,ch1,ch2,ch3: string ;
mois,j,a,b: integer ;
begin
write('a');read(a);
write('j');read(j);
write('mois');read(mois);
case mois of
1,3,5,7,8,10: if j<31 then
begin
b:=j+1;
m:=str(b,ch)+'/'+str(mois,ch2)+'/'+str(a,ch3);
else if j=31then
b:=1;
s:=mois+1;
m:=concat(str(b,ch),'/',str(s,ch2),'/',str(a,ch3));
end
else m:='erreur';
4,6,9,11:if j<30 then
begin
b:=j+1;
m:=concat(str(b,ch),'/',str(mois,ch2),'/',str(a,ch3));
end
else j=30 then
begin
b:=1;
s:=mois+1;
m:=concat(str(b,ch),'/',str(mois,ch2),'/',str(a,ch3));
end
else m:='erreur';
2:if j<28 then
begin
b:=j+1;
m:=concat(str(b,ch),'/',str(mois,ch2),'/',str(a,ch3));
end
else if j=28 then
begin
b:=1;
m:=concat(str(b,ch),'/',str(mois,ch2,'/',str(a,ch3));
end
else if((a mod 4=0)AND (a mod 100<>0)) or ((a mod 100=0)and(a mod 400=0)) then
if j<29 then
begin
b:=j+1;
m:=concat(str(b,ch),'/',str(mois,ch2,'/',str(a,ch3));
end
else if j=29 then
begin
b:=1;
m:=concat(str(b,ch),'/',str(mois,ch2,'/',str(a,ch3));
end
else m:='erreur';
12:if j<31 then
begin
b:=j+1;
m:=concat(str(b,ch),'/',str(mois,ch2,'/',str(a,ch3));
end
else if j=31 then
begin
b:=1;
s:=a+1;
m:=concat(str(b,ch),'/',str(mois,ch2,'/',str(s,ch3));
end;
writeln(m);
end.
this is my program i hope you be able to help me
It may be a good idea to indent the code according to the begin/end-blocks. This make it very easy to spot unpaired begin/end statements.
m:=str(b,ch)+'/'+str(mois,ch2)+'/'+str(a,ch3);
It is a long time since i did something with Turbo Pascal, but if i remember correctly, str is a procedure. So it does not return anything.
In order to simplify your program, it may be a good idea, to only calculate the new variables "b", "mois" and "a" inside the case block. And then do the transformation to a string once after the case-block.
str(b, ch);
str(mois, ch2);
str(a, ch3);
m := ch + '/' + ch2 + '/' + ch3;
Related
I'm supposed to make a subprogram that has exactly one parameter of type Integer. And this Integer represents a day of the week where 1 is monday, 2 is tuesday etc...
The subprogram should return how many days there's left until Saturday.
This is my approach (I'm not supposed to use arrays):
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Test3 is
function Week (Days : in Integer) return Integer is
begin
if Days = 1 then
return 5;
elsif Days = 2 then
return 4;
elsif Days = 3 then
return 3;
elsif Days = 4 then
return 2;
elsif Days = 5 then
return 1;
elsif Days = 6 then
return 7;
elsif Days = 7 then
return 6;
end if;
end Week;
Days : Integer;
begin
Put("What day is it: ");
Get(Days);
if Days < 0 or Days > 7 then
Put_Line("Wrong Value");
end if;
Put("It's ");
Put(Week(Days), Width => 1);
Put(" days until Saturday.");
end Test3;
Even though my program works I have two problems. Do you see the amount of "elsifs", can this not be solved in any other way? I don't like how my program looks.
Secondly,
How am I supposed to make an if statement where if Days < 0 or Days > 7 will raise an error. As you can see I have attempted to this in my main program but it won't work since I have
"Get(Days);" before this statement and my subprogram won't recognize my if statement? Should I put my if statement in my subprogram instead?
Any help is appreciated.
With respect to raising error, how about
if Days not in 1 .. 7 then
Put_Line("Wrong Value");
raise Contrain_Error with "Days is out of range, " & Days'Image;
else
-- normal processing
end if;
Regarding the question of what to do with invalid Days, that is for you to decide, and then you code the subprogram accordingly. I think the most natural, for Ada, would be to put the check in the subprogram and raise Constraint_Error if it fails.
As Simon Wright said, you must decide and specify (and describe in comments) how the week-days are numbered. Otherwise no-one can check your code.
Once you have clearly decided and described those things, for yourself and for any reader of the program, you can have a closer look at your if-then-else nest and see how systematically the return value depends on the input value. Maybe there is a simple formula that can handle most cases, or perhaps all cases with valid input? That would let you reduce the number of if-then-elses.
It appears you allow day numbers in 1 .. 7. You can state this directly
subtype Day_Number is Integer range 1 .. 7;
function Days_Till_Saturday (Day : in Day_Number) return Day_Number;
You can then omit the check on the input value; passing an invalid value to the function will raise Constraint_Error, which you can handle to report the error.
Regarding the long chain of elsifs, you can use a case statement:
case Day is
when 1 =>
return 5;
but for this problem it might be clearer to use arithmetic:
Result : constant Integer := 6 - Day;
begin
if Result not in Day_Number then
return Result + Day_Number'Last;
end if;
return Result;
Writing the below code gives me error saying:
PL/SQL: Statement ignored
PLS-00382: expression is of wrong type:
Code:
if ( l_vol = 0 )
then
l_cndtn_string := 'l_wgt > l_wgt_limit';
else
l_cndtn_string := '(l_wgt > l_wgt_limit) and (l_vol > l_vol_limit)';
end if;
if ( l_cndtn_string )
then
l_isis_task := 'PO';
else
l_isis_task := 'TO';
end if;
If statement evaluates a boolean expression. In your example
if ( l_cndtn_string )
l_cndtn_string is not a boolean expression but a character expression and there is no implicit cast between them.
Please help yourself and check Expressions too.
I don't know what is your logic but the following example shows you one way to convert character expression into boolean expression:
if l_cndtn_string is not null -- a boolean expression
then
null;
else
null;
end if;
You want dynamic condition build. In plsql,like other compiled languages, it hard to do.
Try like this:
if ( l_vol = 0 )
then
if(l_wgt > l_wgt_limit) then
l_isis_task := 'PO';
end if;
else
if(l_wgt > l_wgt_limit and l_vol > l_vol_limit) then
l_isis_task := 'TO';
end if;
end if;
After IF boolean expression is expected, not a string - that's why you're getting PLS-00382 error. You can of course try to dynamically evaluate your expression using dynamic sql, but in fact what you want is as simple as:
if ( l_wgt > l_wgt_limit and ( l_vol = 0 or l_vol > l_vol_limit ) )
then
l_isis_task := 'PO';
else
l_isis_task := 'TO';
end if;
Oh, only after reading the other answers I realised what this question was about. I decided to keep also my original answer as the point about character expression in if-statement is still correct.
The other answers are correct that buiding a logic based on string evaluation with dynamic PL/SQL is not a good idea in general. They also present correct solutions, but IMHO even better approach exists.
Usually when I have multiple conditions in PL/SQL I give the conditions a name. Please see the example below that illustrates the technique. The names make the code self-documenting and is a huge improvement in code readability as very often the condition now reads as human language.
declare
v_volume number := 0;
v_weight number := 1;
v_weight_limit constant number := 10;
v_volume_limit constant number := 10;
v_has_volume constant boolean := v_volume > 0;
v_exceed_weight_limit constant boolean := v_weight > v_weight_limit;
v_exceed_volume_limit constant boolean := v_volume > v_volume_limit;
begin
-- no guarantee the logic is the same than in question
-- but just illustrates the coding style
if v_has_volume
and v_exceed_weight_limit
and v_exceed_volume_limit
then
null; -- something
else
null; -- something else
end if;
end;
/
I am trying to get a character input from the user in this format:
Player 1: a
This is my code:
Ada.Text_IO.Put("Player"&Integer'Image(board.turn)&": ");
Ada.Text_IO.Get(Item => move);
Now, when I run my program this is what happens:
a
Player 1:
For some odd reason, the GET is appearing before the PUT... I tried flipping their positions and it still occurs the same way.
I recently upgraded my AdaCore GNAT from 2012 to 2014 and I didn't have this issue in 2012...
Am I missing something?
Please help!
These are my with/use if you need them:
with Ada.Text_IO, Ada.Characters.Handling;
with Ada.Exceptions; use Ada.Exceptions;
USE Ada, Ada.Text_Io;
NEW
Here is more code... Don't worry about the AI stuff...
Full code:
PROCEDURE Main IS
PACKAGE board is new connectfour;
USE board;
begin
PUT(" ********** CONNECT-FOUR *********"); Put_Line("");
AI.start;
while (not board.isFull) loop
if AIwin = true then goto Win; end if;
Put_Line(""); DELAY 0.5;
Put("Player"&Integer'Image(board.turn)&": ");
Get(move);
if move='0' then goto Quit; end if;
Put_Line("");
if board.Move(move) = true then goto Win; end if;
board.print; DELAY 0.5;
AI.print;
end loop;
<<Win>>
Put_Line("");
Put_Line("PLAYER"&Integer'Image(board.turn)&" IS THE WINNER!");
<<Quit>>
AI.stop;
Put_Line("");
if move='0' then
Put_Line("PLAYER"&Integer'Image(board.turn)&" HAS FORFEIT!");
if board.turn = 1 then
Put_Line("PLAYER 2 IS THE WINNER!");
else
Put_Line("PLAYER 1 IS THE WINNER BY DEFAULT!");
end if;
end if;
end Main;
The standard output may be being buffered. Try
Ada.Text_IO.Put("Player"&Integer'Image(board.turn)&": “);
Ada.Text_IO.Flush;
Ada.Text_IO.Get(Item => move);
(later)
Well, that wasn’t the answer. I just tried
with Ada.Text_IO;
procedure Borovez is
Move : Character;
begin
Ada.Text_IO.Put ("Player" & Integer'Image (42) & ": ");
-- Ada.Text_IO.Flush;
Ada.Text_IO.Get (Item => Move);
end Borovez;
on GNAT GPL 2014/Windows 7 and it worked exactly as expected.
You’re going to need to edit your question to include a Minimal, Complete, and Verifiable example.
So here is a piece of my body file. I am getting the error "words.adb:75:42: actual for "S" must be a variable".
procedure Remove_Character(S : in out Ustring; C : in Character; Successful : out Boolean) is
begin
for I in 1..length(S) loop
if Element(S, I) = C then
Delete(S, I, I);
Successful := true;
return;
end if;
end loop;
Successful := false;
end Remove_Character;
function Is_Subset(Subset : Ustring; S : Ustring) return Boolean is
Could_Remove : Boolean;
begin
for I in 1..length(Subset) loop
Remove_Character(S , Element(Subset, I), Could_Remove);
if Could_Remove = false then
return false;
end if;
end loop;
return True;
end Is_Subset;
I understand where my error is coming from. Remove_Character uses S : in out Ustring while function Is_Subset uses S : in Ustring.
My question is how do I change the variable from Remove_Character into only an in Ustring?
Sorry if this is a tad jumbled, I'm fairly new to both programming and the site.
You can't, at least not directly.
I don't know what a UString is, but I presume the Delete procedure modifies it. If you changed the declaration of S in Remove_Character to S: in Ustring, you'd presumably get an error on the call to Delete.
The simplest approach I can think of would be to make a copy of S in Is_Subset:
Copy_Of_S: UString := S;
and then pass the (modifiable) copy to Remove_Character.
By "simplest", I mean it makes the smallest change to your existing code. But you should probably consider reorganizing it. Determining whether one UString is a subset of another by modifying one of the strings doesn't seem like the best approach; I'm sure there's a more efficient way to do it.
A minor and irrelevant point: this:
if Could_Remove = false then
is better written as:
if not Could_Remove then
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Consider the following controller (protected object) in Ada95 to adapt that a Task calls Waiting() this one its not going to be put on waiting if the waiting marker (Marker) corresponds already on the marker of selection (Selecting_Marker) only naturally before it's initialization:
protected type Controller is
entry Waiting(Marker : in Marker_Type);
procedure WakeUp(Marker : in Marker_Type);
private
Tentative_Count : Natural := 0;
Selecting_Marker : Marker_Type;
end Controller;
protected body Controller is
entry Waiting (Marker : in Marker_Type) when Tentative_Count > 0 is
begin
Tentative_Count := Tentative_Count - 1;
if Selecting_Marker /= Marker then
requeue Waiting;
end if;
end Waiting;
procedure WakeUp (Marker : in Marker_Type) is
begin
Selecting_Marker := Marker;
Tentative_Count := Waiting'Count;
end WakeUp;
end Controller;
The object is to alter the behavior of the protected object, likely the following line:
entry Waiting (Marker : in Marker_Type) when Tentative_Count > 0 is
I'm not well-versed in protected objects, so won't offer any more than that except to say you'd probably be better off a) rereading the book's chapter on protected objects; and b) understanding what the objective of the code is and what the teacher/book is asking.
Part b is especially important, as in real life you need to be able to translate specifications into an implementation; and oftentimes the exact-wording is at odds with the examples and/or the example/reasoning.
Additional resources:
Ada 95 Rationale: II.9 Protected Types
Ada 95 Rationale: 9.1 Protected Types