Programs to Complete: Book Collection

The first program to complete enables you to create, read, update and delete records. It also demonstrates nested records. However, it contains no sorting or searching facilities. The procedure FindBooks contains little more than a search menu. You could develop the program as follows:

  • Write a sort procedure for at least one of the fields.
  • Write a search procedure for at least one of the fields.
  • Enable a search on the field selected by the user.
program BookCollection;
{$APPTYPE CONSOLE}
uses
  SysUtils;
type
  TName = record
    Surname : string[15];
    FName : String[10];
  end;
  TBook = record
    SystemID : integer;
    Title : string[30];
    Author : TName;
    Rating : string[1];
    LastRating : TName;
  end;
var
  Books : array [1..1000] of TBook;
  TotalBooks, SysID, FirstName : integer;
  CurrentUser : TName;
  Bookdata : file of TBook;
  FirstOption, InitOption : string;

procedure ResetID; //Resets the value of each
                   // SystemID to record position
var
  Count : integer;
begin
  for Count := 1 to Totalbooks do
    begin
      Books[Count].SystemID := Count;
    end;
end;

procedure RegisterBooks;
var
  strRegQuantity : string;
  iRegQuantity, Count : integer;
begin
  SysID := TotalBooks;
  repeat
    write('How many books do you wish to register? Maximum 9: ');
    readln(strRegQuantity);
  until (strRegQuantity[1] in ['1'..'9']) AND (length(StrRegQuantity) = 1);
  iRegQuantity := Strtoint(strRegQuantity);
  writeln('Enter book details');
  for Count := 1 to iRegQuantity do
    begin
      inc(totalbooks);
      SysID := TotalBooks;
      Books[SysID].SystemID := SysID;
      writeln('ID no.', Books[SysID].SystemID);
      write('Title: ');
      readln(Books[SysID].Title);
      write('Author (surname): ');
      readln(Books[SysID].Author.Surname);
      write(' "  "  (forename): ');
      readln(Books[SysID].Author.FName);
      write('Please rate this book (max 5):');
      readln(Books[SysID].rating);
      Books[SysID].LastRating := CurrentUser;
      writeln('Last Rated by ', Books[SysID].LastRating.FName,
                    ' ', Books[SysID].LastRating.Surname);
      writeln;
    end;
  writeln('You have successfully registered ', strRegQuantity,' books.');
  readln;
end;

procedure FindBooks;
var
  SearchField, Count : integer;
  SearchTerm, CompleteField : string;
begin
  {writeln('What do you wish to search by?   [1] SystemID');
  writeln('                                 [2] Title');
  writeln('                                 [3] Author (Surname)');
  writeln('                                 [4] Author (Firstname)');
  writeln('                                 [5] Rating');
  readln(SearchField);
  writeln('Enter search term');
  readln(SearchTerm);}
end;

procedure ListBooks;
var
  Count : integer;
begin
  for Count := 1 to TotalBooks do
    begin
      writeln('ID No. ', Books[Count].SystemID);
      writeln('Title: ', Books[Count].Title);
      writeln('Author: ', Books[Count].Author.Surname,
              ', ',Books[Count].Author.FName);
      writeln('Rating: ', Books[Count].Rating, ' Star(s)!');
      writeln('Last rated by: ', Books[Count].LastRating.Surname,
               ', ',Books[Count].LastRating.FName);
      writeln(' ');
    end;
end;
procedure TestData;
  //Adds a set of test data to system (3 books)
begin
  writeln('Loading test data');
  Books[1].SystemID := 1;
  Books[1].Title:= 'On Chesil Beach';
  Books[1].Author.Surname:= 'McEwan';
  Books[1].Author.FName:= 'Ian';
  Books[1].Rating:='5';
  Books[1].LastRating.Surname:= 'Horner';
  Books[1].LastRating.FName := 'Jack';
  Books[2].SystemID := 2;
  Books[2].Title:= 'Yellow Dog';
  Books[2].Author.Surname := 'Amis';
  Books[2].Author.FName := 'Martin';
  Books[2].Rating:= '3';
  Books[2].LastRating.Surname:= 'Eccles';
  Books[2].LastRating.FName := 'Jennifer';
  Books[3].SystemID := 3;
  Books[3].Title := 'Malone Dies';
  Books[3].Author.Surname := 'Beckett';
  Books[3].Author.FName := 'Samuel';
  Books[3].Rating := '4';
  Books[3].LastRating.Surname := 'Rigby';
  Books[3].LastRating.Fname := 'Eleanor';
  TotalBooks := TotalBooks + 3;
end;

procedure CountBooks;
//Counts the amount of books registered and runs 'ResetID'
var
  Count : integer;
begin
  TotalBooks := 0;
  for Count := 1 to 1000 do
    begin;
      if Books[Count].SystemID <> 0 then
    begin
      inc(TotalBooks);
    end;
  end;
  ResetID;
  writeln('There are ', TotalBooks,
          ' books registered on the system.');
end;

procedure Update;
var
  RecentRating, UpdateID, iRating : integer;
  UpdateField : string;
  LoopAgain : Boolean;
begin
  LoopAgain := True;
  writeln('What is the ID of the record you wish to update?');
  readln(UpdateID);
  repeat
    writeln('ID No. ', Books[UpdateID].SystemID);
    writeln('Title: ', Books[UpdateID].Title);
    writeln('Author: ', Books[UpdateID].Author.Surname,
            ', ', Books[UpdateID].Author.Fname);
    writeln('Rating: ', Books[UpdateID].Rating, ' Star(s)!');
    writeln('Last rated by: ', Books[UpdateID].LastRating.Surname,
                 ', ', Books[UpdateID].LastRating.FName);
    writeln(' ');
    writeln('What field do you wish to update? [1] Title');
    writeln('                                  [2] Author (Surname)');
    writeln('                                  [3] Author (Forename)');
    writeln('                                  [4] Add your rating');
    writeln('Finished with this record?        [5] Go Back');
    repeat
      writeln('Please make your selection: ');
      readln(UpdateField);
    until (length(UpdateField) = 1) AND (UpdateField[1] in ['1'..'5']);
    case UpdateField[1] of
      '1': begin
             writeln('Please type in a new title: ');
             readln(Books[UpdateID].Title);
           end;
      '2': begin
             writeln('Please type the Author''s surname: ');
             readln(Books[UpdateID].Author.Surname);
           end;
      '3': begin
             writeln('Please type the Author''s forename: ');
             readln(Books[UpdateID].Author.Fname);
           end;
      '4': begin
             writeln('What would you rate this book as?');
             readln(RecentRating);
             Books[UpdateID].LastRating := CurrentUser;
             iRating := ((RecentRating + 
                        (strtoint(Books[UpdateID].Rating))) div 2);
             Books[UpdateID].Rating := inttostr(iRating);
           end;
      '5': LoopAgain := False;
    end; //endcase
  until Loopagain = False;
end; //End Proc

procedure DeleteRecord;
var
  DeleteID, Count : integer;
  FirstSure : char;
begin
  write('What is the ID of the record you wish to delete? ');
  readln(deleteID);
  writeln(Books[DeleteID].Title, ', AUTHOR: ',
          Books[DeleteID].Author.Surname,
              ' ', Books[DeleteID].Author.FName);
  writeln('Are you sure you wish to delete the above record? [Y/N]');
  readln(FirstSure);
  if (FirstSure = 'Y') OR (FirstSure = 'y')  then
    begin
      for Count := DeleteID to TotalBooks do
        begin
          Books[Count]:= Books[Count+1];
        end;
    end
  else
    begin
      writeln('Returning to main menu');
    end;
  CountBooks;
end;

procedure SaveToFile;
var
  Count : integer;
begin
  assignFile(BookData, 'Bookdata.txt');
  rewrite(BookData);
  for Count := 1 to Totalbooks do
    begin
      write(BookData, Books[Count]);
    end;
  closeFile(BookData);
  writeln('Well done, you have saved it.');
end;

procedure LoadFromFile;
var
  LastRecord : integer;
begin
  assignfile(BookData,'Bookdata.txt');
  reset(Bookdata);
  LastRecord := 0;
  while not eof(Bookdata) do
    begin
      inc(LastRecord);
      read(Bookdata, Books[LastRecord]);
    end;
  closeFile(Bookdata);
  CountBooks;
end;

//MAIN PROGRAM:
begin
  write('What is your first name? ');
  readln(CurrentUser.FName);
  write('What is your surname? ');
  readln(CurrentUser.Surname);
  repeat //Makes the menu appear each time
    repeat //This repeat loop checks that the input is valid
      writeln('Do you want to...  [1] Register new books to the system?');
      writeln('                   [2] List all books on system?');
      writeln('                   [3] Load test data?');
      writeln('                   [4] Update records?');
      writeln('                   [5] Save all records?');
      writeln('                   [6] Load data which you have ' +
                                      'previously saved?');
      writeln('                   [7] Delete a record?');
      writeln('                   [8] Search?');
      writeln('                   [9] Exit?');
      readln(FirstOption);
    until (length(FirstOption) = 1) AND (FirstOption[1] in ['1'..'9']);
    case FirstOption[1] of
      '1': RegisterBooks;
      '2': ListBooks;
      '3': TestData;
      '4': Update;
      '5': SaveToFile;
      '6': LoadFromFile;
      '7': DeleteRecord;
      '8': writeln('You need to complete procedure FindBooks.'#13#10);
      '9': halt;
    end;
  until False;
end.

Programming - a skill for life!

Unfinished programs for you to complete