Search code examples
hashmaprecordadadata-containers

ADA - Records in a hashmap. Problems with printing the hash map


I'm new to programming and this is my first attempt at a data container with records. I'm having difficulty with printing the hashmap between line 65-70. I'm guessing I need to break down the record and print each of its attributes individually but I'm not sure on the best way to do that. The error state 'no candidates match the actuals: missing argument for parameter.

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Text_IO.Unbounded_IO; use Ada.Text_IO.Unbounded_IO;
with Ada.Strings.Hash;
with Ada.Containers.Hashed_Maps;
with Ada.Characters.Handling;

procedure Hashmap_Records is


   type Guest is record
      Name : Unbounded_String := Null_Unbounded_String;
      Attending : Boolean := False;
      Vegitarian : Boolean := False;
      Kids : Natural := 0;
   end record;

   function Equivalent_Keys(Left : Unbounded_String;
                            Right : Unbounded_String)
                            return Boolean is
   begin
      return Left = Right;
      end Equivalent_Keys;

   function U_To_L(Key : in Unbounded_String)
                   return Unbounded_String is
   begin
      return To_Unbounded_String(Ada.Characters.Handling.To_Lower(To_String(Key)));
   end U_To_L;

   function Hash_Func(Key : in Unbounded_String)
                      return Ada.Containers.Hash_Type is
   begin
      return Ada.Strings.Hash(To_String(Key));
   end Hash_Func;


   package Guest_Tracker is new Ada.Containers.Hashed_Maps(Key_Type => Unbounded_String,
                                                           Element_Type => Guest,
                                                           Hash => Hash_Func,
                                                           Equivalent_Keys => Equivalent_Keys);
   Tracked_Guests : Guest_Tracker.Map;

   User_Input : Natural := 0;

   Name_Input : Unbounded_String := Null_Unbounded_String;
   Name : Unbounded_String := Null_Unbounded_String;
   Attendance_Input : Unbounded_String := Null_Unbounded_String;
   Vegitarian_Input : Unbounded_String := Null_Unbounded_String;
   Kids_Input : Natural := 0;
   Temp_Attendance : Boolean := False;
   Temp_Vegi : Boolean := False;


   Procedure Populate_Hash_Map is
   begin
      Tracked_Guests.Insert(Key => To_Unbounded_String("John Smith"),
                            New_Item => (To_Unbounded_String("John"), True, False, 1));
      Tracked_Guests.Insert(Key => To_Unbounded_String("Robert Johnson"),
                           New_Item => (To_Unbounded_String("Rob"), True, True, 2));

   end Populate_Hash_Map;

   procedure Print_Hash_Map(Position : Guest_Tracker.Cursor) is                ---
   begin
      Put_Line("The key: " & To_String(Guest_Tracker.Key(Position)) &
                 " the data item: ");
      Put(Guest_Tracker.Element(Position));                                    ----THIS IS WHERE ERRORS OCCUR
   end Print_Hash_Map;                                                          ----


begin
   Populate_Hash_Map;
   loop
      Put_Line(" - Menu - ");
      Put_Line(" - 1 - Enter new value.");
      Put_Line(" - 2 - Delete Existing Value.");
      Put_Line(" - 3 - Print entire hashmap.");
      Put_Line(" - 4 - Exit Application.");
      New_Line;
      Put(" - > ");

      declare
      begin
         Get(User_Input);
      exception
         when Data_Error =>
            Put_Line("ERROR : The entered value is not an integer, please try again!");
            User_Input := 0;
         when others =>
            Put_Line("ERROR: An unknown error has occured!");
      end;

      Skip_Line;
      New_Line;

      if User_Input = 1 then
         Put_Line("Enter a new value.");
         Put(" Name - > ");
         Name_Input := Get_Line;
         Name := Name_Input;
         New_Line;

         Put(" Attending? (yes/y/no/n) - > ");
         Attendance_Input := Get_Line;
         New_Line;

         Put(" Vegitarian? (yes/y/no/n) - > ");
         Vegitarian_Input := Get_Line;
         New_Line;

         Put("How many children attending? - > ");
         Get(Kids_Input);
         New_Line;

         if (U_To_L(Attendance_Input) = To_Unbounded_String("no"))
           or (U_To_L(Attendance_Input) = To_Unbounded_String("n")) then
            Temp_Attendance := False;

         elsif (U_To_L(Attendance_Input) = To_Unbounded_String("y"))
           or (U_To_L(Attendance_Input) = To_Unbounded_String("yes")) then
            Temp_attendance := True;

         else
            Put_Line("WARNING: The confirmation that you entered is not recognized.");
         end if;

         if (U_To_L(Vegitarian_Input) = To_Unbounded_String("no"))
           or (U_To_L(Vegitarian_Input) = To_Unbounded_String("n")) then
            Temp_Vegi := False;

         elsif (U_To_L(Vegitarian_Input) = To_Unbounded_String("y"))
           or (U_To_L(Vegitarian_Input) = To_Unbounded_String("yes")) then
            Temp_Vegi := True;

         else
            Put_Line("WARNING: The confirmation that you entered is not recognized.");
         end if;

         Guest_Tracker.Insert(Container => Tracked_Guests,
                                 Key => Name_Input,
                                 New_item => (Name, Temp_Attendance, Temp_Vegi, Kids_Input));



      elsif User_Input = 2 then
         Put("Delete a value - > ");
         Name_Input := Get_Line;
         New_Line;

         declare
         begin
            Guest_Tracker.Delete(Container => Tracked_Guests,
                                      Key => Name_Input);
         exception
            when Constraint_Error =>
               Put_Line("The name: '" & To_String(Name_Input) & "' is not found.");
            when others =>
               Put_Line("ERROR: Another error has been discovered!");
         end;
      elsif User_Input = 3 then
         Tracked_Guests.Iterate(Print_Hash_Map'access);
         New_Line;
      elsif User_Input = 4 then
         exit;
      end if;
   end loop;

   end Hashmap_Records;

Solution

  • This has nothing to do with the hash map. You are assuming that there is a Put procedure that outputs your record type Guest but there is none. You only have the Put subroutines from Ada.Text_IO, Ada.Integer_Text_IO and Ada.Text_IO.Unbounded_IO available, none of which take a value of type Guest as parameter.

    Ada does not automatically generate a subroutine to pretty-print a record value when you define the record type. You have to do it yourself, e.g.

    procedure Put (Value : Guest) is
    begin
       Put ("Guest(Name: ");       --  supplied by Ada.Text_IO
       Put (Value.Name);           --  supplied by Ada.Text_IO.Unbounded_IO
       Put (", Attending: ");
       Put (Value.Attending'Img);  --  'Img is GNAT-specific; standard is
                                   --  Boolean'Image (Value.Attending)
       Put (", Vegitarian: ");
       Put (Value.Vegitarian'Img);
       Put (", Kids: ");
       Put (Value.Kids);           --  supplied by Ada.Integer_Text_IO
       Put (")");
    end Put;