Programming Taskbook



User registration   Restore password



1100 training tasks on programming

©  M. E. Abramyan (Southern Federal University, Shenzhen MSU-BIT University), 1998–2024


Examples | PascalABC.NET | PT4 types and procedures


Additional types and procedures

The types and procedures described on this page will be available in the program if the PT4 unit is included with the uses clause.

Task initialization, data input-output

procedure Task(Name: string);

This procedure initializes a task named Name. It must be called at the beginning of the program. If the source code does not contain the Task procedure call then the program output the error message "The Task procedure is not called".

A task name must contain a name of a task group and an order number (for example, 'Begin3'). If the group name is invalid then the program output the error message "Invalid task group". If the task number is invalid then the program output the error message with information about the range of the available task numbers for this group. The symbol "?" placed after the task name (for example, 'Begin3?') means that the program will be run in the demo mode.

Starting from the version 4.8, the Task procedure may be also used for creating and displaying an html-page containing a description of a task or a task group. In this case the name of the required task or the task group ended by the "#" symbol must be used for the Name parameter, for example, 'Begin3#' or 'Begin#'.

Starting from the version 4.13, the Programming Taskbook provides a program testing on several sets of input data during a single running of the program. You should place the sumbol "!" after the task name (for example, 'Begin3!') in order to switch off this new feature.

All subsequent calls of the Task procedure are ignored with the following exception: if several calls are used for creation of an html-page containing a description of various tasks or task groups then all these calls will be taken into account.

Starting from the version 4.12, the Name parameter may include the "_en" or "_ru" suffix that determines the interface language (English or Russian respectively) for Programming Taskbook window and the task itself. The "?", "#", and "!" symbols should be placed before the suffix, for example, 'Begin3#_en'. If several calls of the Task procedure are used (for creation of an html-page) then only the suffix of the first call will be taken into account. If the suffix is absent then the default language is applied (the default language may be changed by means of a pop-up menu of the PT4Load tool; in the PascalABC.NET IDE the default language is determined by the IDE option "Language"—see "Tools | Options" menu command).

function ReadBoolean: boolean; function ReadInteger: integer; function ReadReal: real; function ReadChar: char; function ReadString: string; function ReadNode: Node;

These functions must be used to input initial data values in the program. They must be called after the Task procedure, otherwise the program output the error message "The Task procedure with a task name is not called at the beginning of the program".

Each input function must correspond to the type of data item, otherwise the program output the following message: "Invalid type is used for an input data item" . For example, this message will be output if ReadInteger function will be called for input a string.

In the case of input of more data than the task requires, the program output the error message "An attempt to input superfluous data". In the case of input of less data than the task requires, the program output the error message "Some required data are not input".

It is convenient to call input functions directly when describing variables to be initialized, which allows automatic output of type, for example:

var n := ReadInteger;
var a := ReadReal;

There are variants of these functions, which return tuples of the specified type of source data, consisting of 2, 3 and 4 elements. For example, to input real numbers, you can use not only the ReadReal function, but also the functions ReadReal2, ReadReal3 and ReadReal4:

var (a, b, c) := ReadReal3;

In version 4.19, the set of input methods has been extended with methods which simplify input of linear and two-dimensional data structures. Each group of methods provides reading structures with elements of one of the three basic types T: integer, real and string. Six groups of methods described below are implemented.

Linear structure input methods are presented by ReadArr..., ReadSeq... and ReadList... (for example, ReadArrInteger, ReadSeqReal, ReadListString). They can be called without parameters (in this case, they first read an integer – the size of the structure, and then all its elements are read) or with one parameter of integer type, defining the size of the structure (and in this case only the elements themselves are read). The ReadArr... return a one-dimensional array of T, the ReadSeq... – sequences of T, ReadList... – list based on the array List<T>.

Two-dimensional structure input methods are presented by the ReadMatr..., ReadArrArr... and ReadListList... (for example ReadMatrInteger, ReadArrArrReal, ReadListListString). They can be called without parameters, and, in this case, they first read two integers, that determine the size of the structure by the first index (the number of rows) and by the second index (the number of columns), then they read all the elements by rows. If one integer parameter m is specified, it defines both the number of rows and the number of columns (i.e., the structure corresponds to a square matrix of order m); the method reads only the elements of the structure. If you specify two integer parameters m and n, the first one defines the number of rows, the second one defines the number of columns, in this case, the method reads only elements of the structure. The ReadMatr... return two-dimensional array [,] of T, the ReadArrArr... – array of arrays of T, methods of group ReadListList... – List<List<T>>.

In PascalABC.NET, you can use the standard Write and Print procedures with any number of parameters to output results. Parameters can be scalar data, tuples, linear and binary data structures. Besides, Write and Print methods can be used to output data structures (for example, the a.Print operator can be used to output array a). To output linear structures, there are additional WriteAll and PrintAll methods, which, when called, first output the size of the structure and then its elements.

These procedures must be called after the Task procedure, otherwise the program output the error message "The Task procedure with a task name is not called at the beginning of the program".

The used procedure should correspond to output data item, otherwise the program output the error message "Invalid type is used for an output data item".

In the case of output of more data than the task requires, the program output the error message "An attempt to output superfluous data". In the case of output of less data than the task requires, the program output the error message "Some data are not output".

Dynamic structures processing

type Node = class(IDisposable) public // Constructors: constructor Create; constructor Create(aData: integer); constructor Create(aData: integer; aNext: Node); constructor Create(aData: integer; aNext,aPrev: Node); constructor Create(left,right: Node; data: integer); constructor Create(left,right: Node; data: integer; parent: Node); // Method releasing resources: procedure Dispose; // Properties (available for reading and writing): property Next: Node; property Prev: Node; property Left: Node; property Right: Node; property Parent: Node; property Data: integer; end;

The Node class is used in the ObjDyn, GCDyn and ObjTree, GCTree group tasks. In ObjDyn and GCDyn tasks devoted to stacks and queues (1—28), only the Data and Next properties are used when working with Node classes; in tasks devoted to lists (29—80), the Data, Next, and Prev properties are used. In the majority of tasks for binary trees (ObjTree and GCTree groups), the Data, Left and Right properties are used; in the tasks for doubly linked binary trees (48—56 and 70—71), the Parent field is used additionally.

Dispose method, which releases resources, is required only in ObjDyn and ObjTree groups. In tasks of GCDyn and GCTree groups, resources are supposed to be released automatically by Garbage Collector, so it's not required (although not forbidden) to use Dispose method in them. This feature is indicated by the GC (Garbage Collector) prefix in the group names GCDyn and GCTree.

All input and output objects in tasks are of Node type; they should be input using ReadNode, ReadNode2, ReadNode3, ReadNode4 functions, and output using standard Write/Writeln or Print/Pringln procedures.

The Node class should not be redefined in learning programs.

Output debug info

Procedures described below are intended to output some debug data into the debug panel located below the task panels of the Programming Taskbook window.

Since version 4.22, the debug panel can contain text data with any Unicode characters.

procedure Show(params args: array of object); procedure ShowLine(params args: array of object); procedure HideTask; procedure SetWidth(w: integer); procedure SetPrecision(p: integer);

The Show procedure displays data in the debug panel of the Taskbook window; it can accept any number of parameters of any type. The displayed data are separated from the preceding debugging data (and from each other) by a space. If necessary, they are transferred to the next screen line (the width of the output area in the debugging section is fixed and equal to 80 positions).

Composite data, including nested data (e.g., numeric arrays or tuple arrays), is displayed in a special view, using auxiliary formatting elements. The following notation is used for displaying data sets: tuples are enclosed in parentheses; most types that implement the Enumerable interface (in particular, arrays and lists List) use square brackets; the exceptions are sets (HashSet and SortedSet) and dictionaries (in particular, Dictionary and SortedDictionary), for which curly brackets are used. Dictionary items, like tuples, are enclosed by parentheses, in addition, the keys and values of these items are separated by a colon.

After the output of any Enumerable object, an automatic line break is performed in the debugging panel. If there are several nested Enumerable objects, the level of nesting is defined with additional indentation.

Elements of any data sets are separated by commas (except for elements that implement Enumerable interface, after which no comma is specified because, as it was mentioned above, such elements are separated by line breaks).

The ShowLine procedure is a modification of the Show procedure; it additionally performs an automatic line break after displaying the specified data in the debug panel. If the ShowLine procedure is called without any parameters, it simply performs line break.

The ShowLine procedure performs an additional line break only if the last output data element is not an Enumerable object, because after such objects, the line break is always performed.

Calling the HideTask procedure provides automatic hiding of all panels of the Tasks window, except the debug panel. If the debugging panel is not displayed in the Taskbook window (in particular, if the program is running in demo mode), the HideTask procedure call is ignored. All repeated calls to this procedure are also ignored.

To hide/restore the main panels of the Taskbook window after it is displayed on the screen, you can also use the spacebar or the corresponding command of the context menu of the debug panel.

The SetWidth(w) procedure sets the minimal width w (w >= 0) of the output field for the data elements displayed by the Show and ShowLine procedures; by default, the minimal width is assumed to be 0. This setting is valid for all future calls of the Show and ShowLine procedures. Numeric data are justified to the right, other data are justified to the left.

The SetPrecision(d) procedure sets the number of d fractional digits in real numbers (floating-point format is used if d <= 0; the number of fractional digits in this case is -d or 6 if d is 0); by default, d = 2. The decimal separator is a dot. This setting applies to all subsequent calls of the Show and ShowLine procedures.

Below are examples of using the Show procedure to output various data sets. The program fragment that provides debug output is as follows (the Matrix80 task was used, which gives a real square matrix):

     ShowLine('Matrix of real numbers (width = 5):');
     var a := ReadMatrReal(ReadInteger);
     ShowLine('Dictionary of strings (width = 0):');
     var b1 := new Dictionary<integer, string>();
     b1[1] := 'ABCD';
     b1[3] := '123';
     b1[10] := '!*****!';
     ShowLine('Dictionary of string arrays (width = 3):');
     var b2 := new Dictionary<integer, array of string>();
     b2[1] := new string[] ( 'ab', 'd' );
     b2[2] := new string[] ( '123', '45', '7' );
     b2[22] := new string[] ( '**', '#', '@@@' );
     ShowLine('List of lists containing strings (width = 6):');
     var c1 := new List<List<string>>();
     c1.Add(new List<string>());
     c1[0].Add('ABCD'); c1[0].Add('123'); c1[0].Add('!****!');
     c1.Add(new List<string>());
     c1[1].Add('abcd'); c1[1].Add('56789');
     ShowLine('Array of arrays containing numeric arrays (width = 2):');
     var c2 : array of array of array of integer;
     SetLength(c2, 3);
     SetLength(c2[0], 2);
     c2[0][0] := new integer[] ( 1, 2, 3 );
     c2[0][1] := new integer[] ( 4, 5, 6 );
     SetLength(c2[1], 3);
     c2[1][0] := new integer[] ( 7, 8, 9 );
     c2[1][1] := new integer[] ( 10, 11, 12 );
     c2[1][2] := new integer[] ( 60, 61, 62 );
     SetLength(c2[2], 2);
     c2[2][0] := new integer[] ( 13, 14, 15, 50 );
     c2[2][1] := new integer[] ( 16, 17, 18, 19, 20 );

One should pay attention that, when scalar or tuple elements are output, they are separated by commas, while each element that implements the Enumerable interface (array or List) is followed by a new line. In addition, one should pay attention to the use of indentation when outputting multidimensional lists, as well as to the setting of the output area width with the SetWidth procedure.

  1>  Matrix of real numbers (width = 5):
  2>  [ [  2.07 ,  4.75 ,  4.15 ,  6.20 ,  0.59 ]
  3>    [  4.47 ,  3.12 ,  7.51 ,  7.98 ,  9.45 ]
  4>    [  5.50 ,  8.67 ,  2.51 ,  2.64 ,  5.90 ]
  5>    [  2.45 ,  6.45 ,  4.24 ,  4.35 ,  4.51 ]
  6>    [  2.87 ,  1.46 ,  6.67 ,  5.57 ,  5.00 ]
  7>  ]
  8>  Dictionary of strings (width = 0):
  9>  { ( 1 : ABCD ) , ( 3 : 123 ) , ( 10 : !*****! ) }
 10>  Dictionary of string arrays (width = 3):
 11>  { (   1 : [ ab  , d   ]
 12>  ) (   2 : [ 123 , 45  , 7   ]
 13>  ) (  22 : [ **  , #   , @@@ ]
 14>  ) }
 15>  List of lists containing strings (width = 6):
 16>  [ [ ABCD   , 123    , !****! ]
 17>    [ abcd   , 56789  ]
 18>  ]
 19>  Array of arrays containing numeric arrays (width = 2):
 20>  [ [ [  1 ,  2 ,  3 ]
 21>      [  4 ,  5 ,  6 ]
 22>    ]
 23>    [ [  7 ,  8 ,  9 ]
 24>      [ 10 , 11 , 12 ]
 25>      [ 60 , 61 , 62 ]
 26>    ]
 27>    [ [ 13 , 14 , 15 , 50 ]
 28>      [ 16 , 17 , 18 , 19 , 20 ]
 29>    ]
 30>  ]




Designed by
M. E. Abramyan and V. N. Braguilevsky

Last revised: