I'm very new to programming and have just gotten started with Records and boolean in Ada.
I'm trying to make it so that whenever I write 'T' it will say "True" and whenever I write 'F' it will say False, but I´m not sure how to do that. In this assignment I'm not allowed to change T: Boolean:= False; this has to be in the code, but I´m not sure what I have to do to get what I want. I guess I have to do some sort of if statement like
But i´m not sure how to do that.
My code looks like the following:
type Sub_J is
record
Y: Character:= '9';
Q: Character:= 'p';
end record;
type Sub_B is
record
Y: Character:= 'J';
Q: Character:= 'o';
end record;
type Sub_O is
record
T: Boolean:= False;
L: Character:= '5';
end record;
type DS3 is
record
J: Sub_J;
B: Sub_B;
O: Sub_O;
end record;
procedure Get_3(DSThree: out DS3) is
Space: Character;
begin
Put("Mata in datamängd: ");
Get(DSThree.J.Y);
Get(Space);
Get(DSThree.J.Q);
Get(Space);
Get(DSThree.B.Y);
Get(Space);
Get(DSThree.B.Q);
Get(Space);
Get(DSThree.O.T);
Get(Space);
Get(DSThree.O.L);
end Get_3;
procedure Put_3(DSThree: in DS3) is
begin
Put("Inmatad datamängd: ");
Put(DSThree.J.Y);
Put(" ");
Put(DSThree.J.Q);
Put(" ");
Put(DSThree.B.Y);
Put(" ");
Put(DSThree.B.Q);
Put(" ");
Put(DSThree.O.T);
Put(" ");
Put(DSThree.O.L);
end Put_3;
I assume that you’re using Ada.Text_IO.Put (or Put_Line): what you have to do is to print the image of the variable.
In the case of a Character or String, the image is the thing itself. In the case of other simple types, you can apply the attribute Image:
Ada.Text_IO.Put (T’Image);
This will result in TRUE or FALSE.
Your question is unfortunately not very clear. You show a program, but the program is incomplete and not compilable, and you do not say explicitly which part of the program your question concerns -- is it about an input operation (Get), an output operation (Put), or something else?
You say your goal is "whenever I write 'T' it will say "True"", and likewise F for False. But do you mean that you write 'T' into the program's source code, or in response to an input operation (Get) when you run the program? And is it an output operation that you want to "say "True""? Or do you want to make 'T' and 'F' be abbreviations for True and False in the Ada source code?
If you want to be able to enter 'T' in response to a Get operation for a Boolean variable, for example B : Boolean, and have 'T' mean True, one way is to Get a Character value, for example Get(C) where C is a Character variable, and then make a case selection:
case C is
when 'T' => B := True;
when 'F' => B := False;
when others =>
-- Erroneous input.
-- Perhaps tell the user and ask for new input.
...
end case;
Note, however, that Get for a Character really does give the next character, and does not skip blank characters in the way Get for other types does. However it does skip line terminators (and page terminators).
Giving you a good answer would be much easier if you could show a compilable program and explain what you want it do.
I figured it out
procedure Get_3(DSThree: out DS3) is
Space: Character;
True_Or_False: Character;
begin
Put("Mata in datamängd: ");
Get(DSThree.J.Y);
Get(Space);
Get(DSThree.J.Q);
Get(Space);
Get(DSThree.B.Y);
Get(Space);
Get(DSThree.B.Q);
Get(Space);
Get(True_Or_False);
if True_Or_False = 'T' then
DSThree.O.T:= True;
elsif True_Or_False = 'F' then
DSThree.O.T:= False;
end if;
Get(Space);
Get(DSThree.O.L);
end Get_3;
procedure Put_3(DSThree: in DS3) is
begin
Put("Inmatad datamängd: ");
Put(DSThree.J.Y);
Put(" ");
Put(DSThree.J.Q);
Put(" ");
Put(DSThree.B.Y);
Put(" ");
Put(DSThree.B.Q);
Put(" ");
if DSThree.O.T = True then
Put("True");
elsif DSThree.O.T = False then
Put("False");
end if;
Put(" ");
Put(DSThree.O.L);
end Put_3;
Related
im trying to implement my own hash function as a wrapper to Strings.hash
with an upper bound, here is my code:
function hash (k : in tcodigo; b : in positive) return natural is
hash: Ada.Containers.Hash_Type;
begin
hash := Ada.Strings.Hash(String(k));
return integer(hash) mod b;
end hash;
My problem is that i dont know how to cast hash to integer so i can make the mod operation.
According to the Reference Manual (A.18.1) Hash_Type is a modular type. Therefore, a simple Integer(Hash) should work. Actually, I guess you can take directly the mod of the hash by first casting b to Hast_Type and then converting the result to Natural. Remember to add use type Ada.Containers.Hash_Type.
I recommend using the hashing function from the notes; if you don't have it at hand, I'll leave it here:
function hash(k: in string) return natural is
s, p: natural;
begin
s:= 0;
for i in k'range loop
p:= character'pos(k(i)); -- código ASCII
s:= (s+p) mod b;
end loop;
return s;
end hash;
See you on Monday at the exam; good luck and study hard!
I am working my way through Barnes' book 'Programming in Ada 2012'. This is a code sample implementing a stack from section 12.5.
src/stacks.adb: (the main relevant file)
package body Stacks is
procedure Push(S: in out Stack; X: in Integer) is
begin
S := new Cell'(S,X);
end Push;
procedure Pop(S: in out Stack; X: in out Integer) is
begin
X := S.Value;
S := Stack(S.Next);
end Pop;
function "="(S, T: Stack) return Boolean is
SS: access Cell := S;
TT: access Cell := T;
begin
while SS /= null and TT /= null loop
if SS.Value /= TT.Value then
return false;
end if;
SS := SS.Next;
TT := TT.Next;
end loop;
return SS = TT; -- error: implicit conversion of stand-alone anonymous access object not allowed
end "=";
end Stacks;
I have added a comment containing the error that gnat gives me. Why am I not allowed to convert from one anonymous access Cell to another?
I can solve the problem by inverting the condition:
return not (SS /= TT);
It mystifies me as John Barnes states earlier that if you define a "=" operator returning a boolean, then the inverse "/=" is generated automatically for you, meaning the opposite.
Similarly, the loop condition can be inverted, in which case it fails to compile with the same message.
Finally, a side-note: the expected behaviour of the program, which it gives after changing to return not (SS /= TT) is to recurse infinitely and raise a storage_error due to stack overflow. The reason for that is better seen in this other SO question, and is not the subject of this question.
Why is the conversion disallowed by the compiler when I write "="?
Why is it different when I write "/=", which I thought would always be the inverse?
The other files needed in order to compile the example for yourself:
src/stacks.ads:
package Stacks is
type Stack is limited private;
procedure Push(S: in out Stack; X: in Integer);
procedure Pop(S: in out Stack; X: in out Integer);
function "="(S, T: Stack) return Boolean;
private
type Cell is
record
Next: access Cell;
Value: Integer;
end record;
type Stack is access all Cell;
end;
src/main.adb:
with Ada.Text_IO; use Ada.Text_IO;
with Stacks; use Stacks;
procedure Main is
A : Stack;
B : Stack;
begin
Push(A, 1);
Push(B, 1);
Push(A, 2);
Push(B, 2);
Push(A, 1);
Push(B, 1);
Push(A, 8);
Push(B, 8);
declare
Same : Boolean := A = B;
Text : String := (if Same then "They are the same" else "They are not the same");
begin
Put_Line(Text);
end;
end Main;
stacks.gpr:
project stacks is
for Source_Dirs use ("src");
for Object_Dir use "obj";
for Main use ("main.adb");
end stacks;
Makefile:
all:
gprbuild -d -p -g
clean:
rm -rf obj *.o *.ali
Or compile with gcc:
gcc -c src/*.adb
gnatbind main
gnatlink main
It gives the same results.
I have the following if else statement that created by myself in order to link to the if else statement given in second part:
m=4
if m==3
disp(true)
else
disp(false)
Second part ( this code is fix cannot be change):
if (true)
A=Hello World
else
A=Bye
If using the first part code, my output will be
A=Hello World
but my desire output is
A=Bye
Anyone one have idea to edit the first part, because now my return value in first part not able to link to my second part.
If you can't change the second part's code, I'm afraid your desire cannot be fulfilled. Or rather, I'm afraid your code won't run at all, because your perenthesis, quotes, end-statement (and arguably semicolons) are not in place.
if true
A = 'Hello World';
else
A = 'Bye';
end
This code will return A = 'Hello World', no matter what, since true is always true. If-else conditions work like this:
if (*what's in here evealuates to true*)
%do stuff
else (*if what's up there does not evaluate to true*)
%do other stuff
Clearly, true will always evaluate to true. So the above if-else condition will always return A = 'Hello World'.
You don't need two if statements in order to accomplish this task. One is more than enough to perform all what you need:
m = 4;
if (m == 3)
A = 'Hello World';
else
A = 'Bye';
end
disp(A);
A few comments concerning your code:
if statements need to be closed with an end
if (true) will always pass into the statement
the disp function doesn't assign a value, its only goal is to display it in the Command Window
in order to work with text, you have to enclose it within single quotes ' (char array) or double quotes " (string), more info here
If you posted only small excerpts of your code and you need to perform those two checks sequentially, in different parts of your script, then:
m = 4;
if (m == 3)
m_equals_3 = true;
disp('M == 3');
else
m_equals_3 = false;
disp('M ~= 3');
end
% then, somewhere else...
if (m_equals_3)
A = 'Hello World';
else
A = 'Bye';
end
% ...
I guess this is a homework exercise. You should disclose that if it’s the case.
The exercise requieres you to change the workspace such that the second bit of code evaluated the else case. This can be accomplished by changing the meaning of true. In your first bit of code, make it so that
true = flase;
Or equivalently,
true = 0;
Note that this is really bad form, if you ever do something like this outside of a homework exercise that explicitly asks you to do so, you’ll get fired or maybe even shot. You’ve been warned!
By the way, I assume that the missing quote characters around the strings and the missing ends are typos?
with Ada.Text_IO, Ada.Integer_Text_IO, Ada.Characters.Handling;
with Ada.Exceptions; use Ada.Exceptions;
USE Ada, Ada.Text_Io;
WITH connectfour;
PROCEDURE Main IS
PACKAGE board is new connectfour;
USE board;
col : Character;
function checkInput (input : Character) RETURN BOOLEAN is
ins : Character := input;
begin
ins := Ada.Characters.Handling.To_Lower(ins);
if ins = 'a' or ins = 'b' or ins = 'c' or ins = 'd' or
ins = 'e' or ins = 'f' or ins = 'g' or ins = 'h' then
return true;
end if;
return false;
end checkInput;
begin
board.initialize;
board.print;
while (not board.isFull) loop
loop
PUT("Player"&Integer'Image(board.turn)&": ");
Ada.Text_IO.Get(col);
exit when checkInput(col);
end loop;
exit when col = '0';
Text_IO.New_Line;
Text_IO.Put ("");
board.play(col);
end loop;
end Main;
So when I run my program I get:
Player 1: a --> (I entered the character 'a' and clicked enter)
Then I keep getting this error right after, at the line "Ada.Text_IO.Get(col);"
raised ADA.IO_EXCEPTIONS.DATA_ERROR : a-tiinio.adb:86 instantiated at a-inteio.ads:18
What I want to do, is get a single character input from the user and check if it is within the range A .. H, if yes, then exit the loop, otherwise keep asking...
I cannot find out what my issue is...
I allow the user to enter lowercase or uppercase characters, and I convert uppercase to lowercase and perform a check.
Please help...
I am not sure how to read in a single Character....
Okay the exception message could be clearer (and there are ways to get stack traces when one happens but let's work with what we've got...)
locate a-tiinio.adb
/usr/lib/gcc/x86_64-linux-gnu/4.9/rts-native/adainclude/a-tiinio.adb
which is
package body Ada.Text_IO.Integer_IO
and line 86 is an exception raised in
procedure Get
(Item : out Num;
Width : Field := 0)
Details don't matter (yet) but I cannot see any calls to Ada.Text_IO.Integer_IO.Get.
So my suspicion is that the code shown is working
(as well as can be expected : NOTE HOWEVER there is no way to get to exit when col = '0'; with col outside a .. h) and there is another call to Get (this time Integer_IO.Get) buried in board.play. It would be easy to test this by printing col= before calling board.play.
Minor style comment:
function checkInput (input : Character) RETURN BOOLEAN is
ins : Character := input;
begin
ins := Ada.Characters.Handling.To_Lower(ins);
can be simplified
function checkInput (input : Character) RETURN BOOLEAN is
ins : Character := Ada.Characters.Handling.To_Lower(input);
begin
I don't want to use global value it is dangerous for a big program. Code is like this
subroutine has_key(id)
if (true) then
return 1
else
return 0
end if
end subroutine
subroutine main
if(has_key(id))
write(*,*) 'it works!'
end subroutine
how can I do something like this using subroutine. I was thinking of return a flag but I may use a global value. Anyone has idea?
Like this
subroutine test(input, flag)
integer, intent(in) :: input
logical, intent(out) :: flag
flag = input>=0
end subroutine
and
call test(3,myflag)
will set myflag to .true.
Note
that subroutines return values through their argument lists;
the use of the intent clause to tell the compiler what the subroutine can do with its arguments;
my example is very simple and you will probably want to adapt it to your needs.
You could also do it with a function. Say it returns true for even numbers
logical function has_key(id)
integer, intent(in):: id
has_key = mod(id,2) .eq. 0
end function has_key
program main
do ii = 1, 4
if(has_key(ii))
print *, ii, ' has key'
else
print *, ii, ' no key'
end if
end do
end program