# Records

## Directions

Goal: create a package that handles directions and geometric angles.

Steps:

1. Implement the `Directions` package.

1. Declare the `Ext_Angle` record.

2. Implement the `Display` procedure.

3. Implement the `To_Ext_Angle` function.

Requirements:

1. Record `Ext_Angle` stores information about the extended angle (see remark about extended angles below).

2. Procedure `Display` displays information about the extended angle.

1. You should use the implementation that has been commented out (see code below) as a starting point.

3. Function `To_Ext_Angle` converts a simple angle value to an extended angle (`Ext_Angle` type).

Remarks:

1. We make use of the algorithm implemented in the `Check_Direction` procedure (chapter on imperative language).

2. For the sake of this exercise, we use the concept of extended angles. This includes the actual geometric angle and the corresponding direction (North, South, Northwest, and so on).

```

package Directions is

type Angle_Mod is mod 360;

type Direction is
(North,
Northeast,
East,
Southeast,
South,
Southwest,
West,
Northwest);

function To_Direction (N: Angle_Mod) return Direction;

--  Include type declaration for Ext_Angle record type:
--
--  NOTE: Use the Angle_Mod and Direction types declared above!
--
--  type Ext_Angle is [...]
--

function To_Ext_Angle (N : Angle_Mod) return Ext_Angle;

procedure Display (N : Ext_Angle);

end Directions;

package body Directions is

procedure Display (N : Ext_Angle) is
begin
--  Uncomment the code below and fill the missing elements
--
--  Put_Line ("Angle: "
--            & Angle_Mod'Image (____)
--            & " => "
--            & Direction'Image (____)
--            & ".");
null;
end Display;

function To_Direction (N : Angle_Mod) return Direction is
begin
case N is
when   0        => return North;
when   1 ..  89 => return Northeast;
when  90        => return East;
when  91 .. 179 => return Southeast;
when 180        => return South;
when 181 .. 269 => return Southwest;
when 270        => return West;
when 271 .. 359 => return Northwest;
end case;
end To_Direction;

function To_Ext_Angle (N : Angle_Mod) return Ext_Angle is
begin
--  Implement the conversion from Angle_Mod to Ext_Angle here!
--
--  Hint: you can use a return statement and an aggregate.
--
null;
end To_Ext_Angle;

end Directions;

with Directions;        use Directions;

procedure Main is
type Test_Case_Index is
(Direction_Chk);

procedure Check (TC : Test_Case_Index) is
begin
case TC is
when Direction_Chk =>
Display (To_Ext_Angle (0));
Display (To_Ext_Angle (30));
Display (To_Ext_Angle (45));
Display (To_Ext_Angle (90));
Display (To_Ext_Angle (91));
Display (To_Ext_Angle (120));
Display (To_Ext_Angle (180));
Display (To_Ext_Angle (250));
Display (To_Ext_Angle (270));
end case;
end Check;

begin
if Argument_Count < 1 then
Put_Line ("ERROR: missing arguments! Exiting...");
return;
elsif Argument_Count > 1 then
end if;

Check (Test_Case_Index'Value (Argument (1)));
end Main;

Enable tabbed editor view for this editor

Use the dark theme

```

## Colors

Goal: create a package to represent HTML colors in RGB format using the hexadecimal form.

Steps:

1. Implement the `Color_Types` package.

1. Declare the `RGB` record.

2. Implement the `To_RGB` function.

3. Implement the `Image` function for the `RGB` type.

Requirements:

1. The following table contains the HTML colors and the corresponding value in hexadecimal form for each color element:

Color

Red

Green

Blue

Salmon

`#FA`

`#80`

`#72`

Firebrick

`#B2`

`#22`

`#22`

Red

`#FF`

`#00`

`#00`

Darkred

`#8B`

`#00`

`#00`

Lime

`#00`

`#FF`

`#00`

Forestgreen

`#22`

`#8B`

`#22`

Green

`#00`

`#80`

`#00`

Darkgreen

`#00`

`#64`

`#00`

Blue

`#00`

`#00`

`#FF`

Mediumblue

`#00`

`#00`

`#CD`

Darkblue

`#00`

`#00`

`#8B`

2. The hexadecimal information of each HTML color can be mapped to three color elements: red, green and blue.

1. Each color element has a value between 0 and 255, or `00` and `FF` in hexadecimal.

2. For example, for the color salmon, the hexadecimal value of the color elements are:

• red = `FA`,

• green = `80`, and

• blue = `72`.

3. Record `RGB` stores information about HTML colors in RGB format, so that we can retrieve the individual color elements.

4. Function `To_RGB` converts from the `HTML_Color` enumeration to the `RGB` type based on the information from the table above.

5. Function `Image` returns a string representation of the `RGB` type in this format:

• `"(Red => 16#..#, Green => 16#...#, Blue => 16#...# )"`

Remarks:

1. We use the exercise on HTML colors from the previous lab on Strongly typed language as a starting point.

```

package Color_Types is

type HTML_Color is
(Salmon,
Firebrick,
Red,
Darkred,
Lime,
Forestgreen,
Green,
Darkgreen,
Blue,
Mediumblue,
Darkblue);

function To_Integer (C : HTML_Color) return Integer;

type Basic_HTML_Color is
(Red,
Green,
Blue);

function To_HTML_Color (C : Basic_HTML_Color) return HTML_Color;

subtype Int_Color is Integer range 0 .. 255;

--  Replace type declaration for RGB record below
--
--  - NOTE: Use the Int_Color type declared above!
--
--  type RGB is [...]
--
type RGB is null record;

function To_RGB (C : HTML_Color) return RGB;

function Image (C : RGB) return String;

end Color_Types;

package body Color_Types is

function To_Integer (C : HTML_Color) return Integer is
begin
case C is
when Salmon      => return 16#FA8072#;
when Firebrick   => return 16#B22222#;
when Red         => return 16#FF0000#;
when Darkred     => return 16#8B0000#;
when Lime        => return 16#00FF00#;
when Forestgreen => return 16#228B22#;
when Green       => return 16#008000#;
when Darkgreen   => return 16#006400#;
when Blue        => return 16#0000FF#;
when Mediumblue  => return 16#0000CD#;
when Darkblue    => return 16#00008B#;
end case;

end To_Integer;

function To_HTML_Color (C : Basic_HTML_Color) return HTML_Color is
begin
case C is
when Red   => return Red;
when Green => return Green;
when Blue  => return Blue;
end case;
end To_HTML_Color;

function To_RGB (C : HTML_Color) return RGB is
begin
--  Implement the conversion from HTML_Color to RGB here!
--
return (null record);
end To_RGB;

function Image (C : RGB) return String is
subtype Str_Range is Integer range 1 .. 10;
SR : String (Str_Range);
SG : String (Str_Range);
SB : String (Str_Range);
begin
--  Replace argument in the calls to Put below
--  with the missing elements (red, green, blue)
--  from the RGB record
--
Item  => 0,    --  REPLACE!
Base  => 16);
Item  => 0,    --  REPLACE!
Base  => 16);
Item  => 0,    --  REPLACE!
Base  => 16);
return ("(Red => " & SR
& ", Green => " & SG
& ", Blue => "  & SB
&")");
end Image;

end Color_Types;

with Color_Types;      use Color_Types;

procedure Main is
type Test_Case_Index is
(HTML_Color_To_RGB);

procedure Check (TC : Test_Case_Index) is
begin
case TC is
when HTML_Color_To_RGB =>
for I in HTML_Color'Range loop
Put_Line (HTML_Color'Image (I) & " => "
& Image (To_RGB (I)) & ".");
end loop;
end case;
end Check;

begin
if Argument_Count < 1 then
Put_Line ("ERROR: missing arguments! Exiting...");
return;
elsif Argument_Count > 1 then
end if;

Check (Test_Case_Index'Value (Argument (1)));
end Main;

Enable tabbed editor view for this editor

Use the dark theme

```

## Inventory

Goal: create a simplified inventory system for a store to enter items and keep track of assets.

Steps:

1. Implement the `Inventory_Pkg` package.

1. Declare the `Item` record.

2. Implement the `Init` function.

3. Implement the `Add` procedure.

Requirements:

1. Record `Item` collects information about products from the store.

1. To keep it simple, this record only contains the name, quantity and price of each item.

2. The record components are:

• `Name` of `Item_Name` type;

• `Quantity` of `Natural` type;

• `Price` of `Float` type.

2. Function `Init` returns an initialized item (of `Item` type).

1. Function `Init` must also display the item name by calling the `To_String` function for the `Item_Name` type.

• This is already implemented in the code below.

3. Procedure `Add` adds an item to the assets.

1. Since we want to keep track of the assets, the implementation must accumulate the total value of each item's inventory, the result of multiplying the item quantity and its price.

```

package Inventory_Pkg is

type Item_Name is
(Ballpoint_Pen, Oil_Based_Pen_Marker, Feather_Quill_Pen);

function To_String (I : Item_Name) return String;

--  Replace type declaration for Item record:
--
type Item is null record;

function Init (Name     : Item_Name;
Quantity : Natural;
Price    : Float) return Item;

procedure Add (Assets : in out Float;
I      : Item);

end Inventory_Pkg;

package body Inventory_Pkg is

function To_String (I : Item_Name) return String is
begin
case I is
when Ballpoint_Pen        => return "Ballpoint Pen";
when Oil_Based_Pen_Marker => return "Oil-based Pen Marker";
when Feather_Quill_Pen    => return "Feather Quill Pen";
end case;
end To_String;

function Init (Name     : Item_Name;
Quantity : Natural;
Price    : Float) return Item is
begin
Put_Line ("Item: " & To_String (Name) & ".");

--  Replace return statement with the actual record initialization!
--
return (null record);
end Init;

procedure Add (Assets : in out Float;
I      : Item) is
begin
--  Implement the function that adds an item to the inventory here!
--
null;

end Inventory_Pkg;

with Inventory_Pkg;     use Inventory_Pkg;

procedure Main is
--  Remark: the following line is not relevant.
F   : array (1 .. 10) of Float := (others => 42.42);

type Test_Case_Index is
(Inventory_Chk);

procedure Display (Assets : Float) is
package F_IO is new Ada.Text_IO.Float_IO (Float);

use F_IO;
begin
Put ("Assets: \$");
Put (Assets, 1, 2, 0);
Put (".");
New_Line;
end Display;

procedure Check (TC : Test_Case_Index) is
I      : Item;
Assets : Float := 0.0;

--  Please ignore the following three lines!
pragma Warnings (Off, "default initialization");
pragma Warnings (On, "default initialization");
begin
case TC is
when Inventory_Chk =>
I := Init (Ballpoint_Pen,        185,  0.15);
Display (Assets);

I := Init (Oil_Based_Pen_Marker, 100,  9.0);
Display (Assets);

I := Init (Feather_Quill_Pen,      2, 40.0);
Display (Assets);
end case;
end Check;

begin
if Argument_Count < 1 then
Put_Line ("ERROR: missing arguments! Exiting...");
return;
elsif Argument_Count > 1 then
end if;

Check (Test_Case_Index'Value (Argument (1)));
end Main;

Enable tabbed editor view for this editor

Use the dark theme

```