Пример окна программы приведен на рис. 1.70.

Рис. 1.70. Окно программы

Вопросы теста должны находиться в текстовом файле, имя которого должно передаваться программе тестирования как параметр командной строки.
Предлагается следующая структура файла теста. Первая строка файла теста — название теста, за которым следуют разделы:

  • заголовка;
  • оценок;
  • вопросов.

Название выводится в заголовке стартового окна программы тестирования.
Раздел заголовка содержит общую информацию о тесте, например, о его назначении. Заголовок может состоять из нескольких строк. Признаком конца раздела заголовка является точка, стоящая в начале строки.
Вот пример заголовка файла теста:

Сейчас Вам будут предложены вопросы о знаменитых памятниках
и архитектурных сооружениях Санкт-Петербурга. Вы должны
из предложенных нескольких вариантов ответа выбрать правильный.

За заголовком следует раздел оценок, в котором приводятся на звания оценочных уровней и количество баллов, необходимое для достижения этих уровней. Название уровня должно располагаться в одной строке. Вот пример раздела оценок:

Отлично
100
Хорошо
85
Удовлетворительно
60
Плохо
50

За разделом оценок следует раздел вопросов теста. Каждый вопрос начинается текстом вопроса, за которым может следовать имя файла иллюстрации, размещаемое на отдельной строке и начинающееся символом \. Имя файла иллюстрации является признаком конца текста вопроса. Если к вопросу нет иллюстрации, то вместо имени файла ставится точка. После, вопроса следуют альтернативные ответы. Текст альтернативного ответа может занимать несколько строк. В строке, следующей за текстом ответа, располагается оценка (количество баллов) за выбор этого ответа. Если альтернативный ответ не является последним для текущего ответа, то перед оценкой ставится запятая, если последний — то точка.
Вот пример вопроса:

Архитектор Исаакиевского' собора:
\isaak.bmp
Домеиико Трезини
,0
Огюст Монферран
,1
Карл Росси
.0

В приведенном вопросе первый и третий варианты ответа помечены как не правильные (оценка за их выбор равна нулю).
Вид формы программы тестирования приведен на рис. 1.71.

I Универсальная программа тестирования.
(с) Культин Н.Б., 2003 )
unit tester_;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, ExtCtrls,
jpeg;
type
TForml = class(TForm)
// вопрос
Label5: TLabel;
// альтернативные ответы
Label1: TLabel;
Рис. 1.71. Форма программы тестирования
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
// переключатели выбора ответа
RadioButtonl: TRadioButton;
RadioButton2: TRadioButton;
RadioButton3: TRadioButton;
RadioButton4: TRadioButton;
Imagel: TImage; // область вывода иллюстрации
Buttonl: TButton;
Panell: TPanel;
RadioButton5: TRadioButton;
procedure FormActivate(Sender: TObject);
procedure ButtonlClick(Sender: TObject);
procedure RadioButtonClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
// Эти объявления вставлены сюда вручную
procedure Info;
procedure VoprosToScr;
procedure ShowPicture; // выводит иллюстрацию
procedure ResetForm; // "очистка" формы перед выводом
// очередного вопроса
procedure Itog; // результат тестирования
private
/' Private declarations }
public
I Public declarations j
end;
var
Forrnl: TForml; // форма
implementation
{$R *.DFM}
const
N_LEV=4; // четыре уровня оценки
N_ANS=4; // четыре варианта ответов
var >
f:TextFile;:
fn:string; // имя файла вопросов
// сумма, соответствующая уровню
level:array[l..N_LEV] of integer;
// сообщение, соответствующее уровню
mes:array[1..N_LEV] of string;
score: array[ 1. .N_ANS] of integer; //' оценка за выбор ответа
suirnia: integer; // набрано очков
vopros:integer; // номер текущего вопроса
otv:integer; // номер выбранного ответа
// вывод информации о тесте
procedure Tforml.Info;
var
s,buf:string;
begin
readln(f,s);
Forml.Caption := s;
buf:='';
repeat
readln(f,s);
if s[l] <>
then buf := buf +s + #13;
until s[1] ='.' ;
Label5.caption:=buf;
end;
// прочитать информацию об оценках за тест
Procedure GetLevel;
var
i:integer;
buf:string;
begin
i:=l;
repeat
readln(f,buf) ;
if buf[1] <> '.' then begin
mes[i]:=buf; // сообщение
readln(f,level[i]); // оценка
i:=i+l;
end;
until buf[1]='.';
end;
// масштабирование иллюстрации
Procedure TForml.ShowPicture;
var
w,h: integer; // максимально возможные размеры картинки
begin
// вычислить допустимые размеры картинки
w:=C.lientWidth-10;
h:=ClientHeight
- Panell.Height -10
- Label5.Top
- Label5.Height - 10;
// вопросы
if Label1.Caption О "
then h:=h-Labell.Height-10;
if Label2.Caption <> "
then h:=h-Label2.Height-10;
if Label3.Caption <> ''
then h:=h-Label3.Height-10;
if Label4.Caption <> ''
then h:=h-Label4.Height-10;
// если размер картинки меньше w на h,
// то она не масштабируется
ImageI.Top:=Forml.Label5.Top+Label5.Height+10;
if Image1.Picture.Bitmap.Height > h
then Imagel.Height:=h
else Imagel.Height:= Imagel.Picture.Height;
if Imagel.Picture.Bitmap.Width > w
then Imagel.Width:=w
else Imagel.Width:=Imagel.Picture.Width;
Imagel.Visible := True;
end;
// вывести вопрос
Procedure TForml.VoprosToScr;
var
i:integer;
s,buf:string;
ifn:string; // файл иллюстрации
begin
vopros:=vopros+l;
caption:='Вопрос ' + IntToStr(vopros);
// прочитать вопрос
buf:='';
repeat
readln(f,s);
if (s[l] о '.') and (s[l] <> 'V)
then buf:=buf+s+' ';
until (s[l] ='.') or (s[l] ='\');
Label5.caption:=buf; // вывести вопрос
I Иллюстрацию прочитаем, но выведем только после
того, как прочитаем альтернативные ответы
и определим максимально возможный размер
области формы, который можно использовать
для ее вывода.}
if s[l] <> 'V
then Imagel.Tag:=0 // к вопросу нет иллюстрации
else // к вопросу есть иллюстрация
begin
Imagel.Tag:=l;
ifn:=copy(s,2,length(s)) ;
try
Imagel.Picture.LoadFromFile(ifn) ;
except
on E:EFOpenError do
Imagel. Tag:=0;
end;
end;
// читаем варианты ответов
i:=l;
repeat
buf:='';
repeat // читаем текст варианта ответа
readln(f,s);
if (s[l]<>' . ' ) and (s[l] <> ', ' )
then buf:=buf+s+' ';
until (s[l] = r, ' )or(s[l] = ' . ') ;
// прочитан альтернативный ответ
scored] := StrToInt (s [2] ) ;
case i of
1: Labell.caption:=buf;
2: Label2.caption:=buf;
3: Label3.caption:=buf;
4: Label4.caption:=buf;
end;
i:=i+l;
until s[l] = ' . ' ;
// здесь прочитана иллюстрация и альтернативные ответы
// текст вопроса уже выведен
if Imagel.Tag =1 // есть иллюстрация к вопросу
then ShowPicture;
// вывод альтернативных ответов
if Forml.Labell.Caption О ''
then begin
if Forml.Imagel.Tag =1
then Labell.Top:=Imagel.Top+Imagel.Height+10
else Labell.Top:=Label5.Top+Label5.Height+10;
RadioButtonl.Top:=Labell.Top;
Labell.visible:=TRUE;
RadioButtonl.visible:=TRUE;
end;
if Forml.Label2.Caption <> "
then begin
Label2.top:=Labell.top+ Labell.height+10;
RadioButton2.top:=Label2.top;
Label2 . visible: =TRUE;
RadioButton2.visible:=TRUE;
end;
if Forml.Label3.Caption о "
then begin
Label3.top:=Label2.top+ Label2.height+10;
RadioButton3.top:=Label3.top;
Label3.visible:=TRUE;
RadioButton3.visible:=TRUE;
end;
if Forml.Label4.Caption О '{•
then begin
Label4.top:=Label3.top+ Label3.height+10;
RadioButton4.top:=Label4.top;
Label4.visible:=TRUE;
RadioButton4.visible:=TRUE;
end;
end;
Procedure TForml.ResetForm;
begin // сделать невидимыми все метки и переключатели
Labell.Visible:=FALSE;
Labell.Caption:='';
Labell.Width:=ClientWidth-Labell.left-5;
RadioButtonl.Visible:=FALSE;
Label2.Visible:=FALSE;
Label2.Caption:='';
Label2.Width:=ClientWidth-Label2.left-5;
RadioButton2.Vis ible:=FALSE;
Label3.Visible:=FALSE;
Label3.Caption:='';
Label3.Width:=ClientWidth-Label3.1eft-S;
RadioButton3.Visible:=FALSE;
Label4.Visible:=FALSE;
Label4.Caption:='';
Labe14.Width:=C1ientWidth-Label4.lett-5;
RadioButton4.Visible:=FALSE;
Label5.Width:=ClientWidth-Label5.left-5;
Imagel.Visible:=FALSE;
end;
// определение достигнутого уровня
procedure TForml.Itog;
var
i:integer;
buf:string;
begin
buf:='';
buf:='Результаты тестирования'+ #13
+'Всего баллов: '+ IntToStr(summa);
i:=l;
while (summa < level[i]) and (i i:=i+l;
buf:=buf+ #13+mes(i];
Label5.Top:=20;
Label5.Caption:=buf;
end;
procedure TForml.FormActivate(Sender: TObject);
begin
ResetForm;
if ParamCount = 0
then begin
Label5.Caption:= 'He задан файл вопросов теста.';
Buttonl.Caption:='Ok';
Buttonl.Tag:=2;
Buttonl.Enabled:=TRUE
end
else begin
fn := ParamStr(l);
assignfile(f,fn);
try
reset(f);
except
on EFOpenError do
begin
ShowMessage{'Файл теста '+fn+' не найден.');
Buttonl.Caption: = 'Ok' ;
Buttonl.Tag:=2;
Buttonl.Enabled:=TRUE;
exit;
end;
end;
Info; // прочитать и вывести информацию о тесте
GetLevel; // прочитать информацию об уровнях оценок
end;
end;
// щелчок на кнопке Buttonl
procedure TForml.ButtonlClick(Sender: TObject);
begin
case Buttonl.tag of
0: begin
Buttonl.caption:='Дальше';
Buttonl.tag:=1;
RadioButton5.Checked:=TRUE;
// вывод первого вопроса
Butt onl.Enabled:=Fa1s e;
ResetForm;
VoprosToScr;
end;
1: begin // вывод остальных вопросов
summa:=surama+score[otv];
RadioButton5.Checked:=TRUE;
Buttonl.Enabled:=False;
ResetForm;
if not eof(f)
then VoprosToScr
else
begin
summa:=summa+score[otv];
closefile(f);
Buttonl.caption:='Ok';
Forml.caption:='Результат1;
Buttonl.tag:=2;
Buttonl.Enabled:=TRUE;
Itog; // вывести результат
end;
end;
2: begin // завершение работы
Forml.Close;
end;
end;
end;
/./ Процедура обработки события Onclick
// для компонентов RadioButtonl-RadioButton4
procedure TForml.RadioButtonClick(Sender: TObject);
begin
if sender = RadioButtonl
then otv:=1
else if sender = RadioButton2
then otv:=2
else if sender = RadioButton3
then otv:=3
else otv:=4;
Buttonl.enabled:=TRUE;
end;
// обеспечивает настройку компонентов
procedure TForml.FormCreate(Sender: TObject);
begin
Imagel.AutoSize := False;
Imagel.Proportional := True;
RadioButtonl.Visible := False;
end;
end.