I have written a change calculator using Ada. when the user inputs an amount of money it returns a list of the coins and bills needed to create that total. It starts off by trying to use the largest money types then tries smaller ones.I am still learning how to use Ada and would like to know how i can make better use of the language features. Am i using the right data types, is there a way to make the change calculation loop more readable?with Ada.Text_IO;with Ada.Float_Text_IO;with Ada.IO_Exceptions;with Ada.Integer_Text_IO;use Ada;procedure Change_Calculator is   type Money is delta 0.01 digits 10;   Input_Amount : Money := 0.0;   package Money_IO is new Text_IO.Decimal_IO(Money);   type Currency_Denomination is record      Name : String(1..10);      Value : Money;   end record;   Currency_Names  : array (1..10) of Currency_Denomination;   Currency_Counts : array (1..10) of Integer := (others=>0);   Currency_Index  : Integer range 1..10;   procedure Get_Money_Prompt(Amount: out Money) is      Response : String(1..20);      Last     : Natural;   begin      loop         declare         begin            Text_IO.Put(amount: );            Text_IO.Flush;            Text_IO.Get_Line(Response, Last);            -- try to convert string input to money type            Amount := Money'Value(Response(1 .. Last));            -- quit the loop if the money converted -- '            exit;         exception            when Constraint_Error =>               Text_IO.Put_Line(ERROR: bad money format);         end;      end loop;   end Get_Money_Prompt;begin   Currency_Names := ((Penny     , 0.01),                      (Nickle    , 0.05),                      (Dime      , 0.10),                      (Quarter   , 0.25),                      (Dollar    , 1.00),                      (5 Dollar  , 5.00),                      (10 Dollar , 10.00),                      (20 Dollar , 20.00),                      (50 Dollar , 50.00),                      (100 Dollar, 100.00));   -- read money amount from the user   Get_Money_Prompt(Input_Amount);   -- calculate needed currency   for I in Currency_Names'Range loop      -- calculate inverse of index to count backwords      Currency_Index := (Currency_Names'Length-I)+1;      while Input_Amount >= Currency_Names(Currency_Index).Value loop         Input_Amount := Input_Amount - Currency_Names(Currency_Index).Value;         -- increment currency useage in array         Currency_Counts(I) := Currency_Counts(I) + 1;      end loop;   end loop;   -- display needed currency   for I in Currency_Counts'Range loop      Currency_Index := (Currency_Names'Length-I)+1;      -- do not display unused currency      if Currency_Counts(Currency_Index) /= 0 then        Text_IO.Put(Currency_Names(I).Name &  );        Integer_Text_IO.Put(Currency_Counts(Currency_Index));        Text_IO.New_Line;      end if;   end loop;end Change_Calculator;
Calculating change in Ada
ada;change making problem
Currency_Names, Currency_Counts and Currency_Index all use the same range,so it is better to declare a ranged type (or a subtype):   type Index is range 1..10;   Currency_Names  : array (Index) of Currency_Denomination;   Currency_Counts : array (Index) of Integer := (others=>0);   Currency_Index  : Index;To loop backwards, it is better to use the reverse keyword:   -- calculate needed currency   for I in reverse Currency_Names'Range loop      while Input_Amount >= Currency_Names(I).Value loop         Input_Amount := Input_Amount - Currency_Names(I).Value;         -- increment currency useage in array         Currency_Counts(I) := Currency_Counts(I) + 1;      end loop;   end loop;   -- display needed currency   for I in Currency_Counts'Range loop      -- do not display unused currency      if Currency_Counts(I) /= 0 then        Text_IO.Put(Currency_Names(I).Name &  );        Integer_Text_IO.Put(Currency_Counts(I));        Text_IO.New_Line;      end if;   end loop;A nice side-effect is that the index of Currency_Counts will now correspond to the index of Currency_Names, no need to calculate the index anymore, and the Currency_Index variable is no longer needed.