Помощь - Поиск - Пользователи - Календарь
Полная версия: Подправка кода
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Делфи
Vera
Здравствуйте, имеется программа тест с базой данных. Скажите пожалуйста, как сделать, чтобы не только шли рандомно вопросы, но и ответы. А также, чтобы выводились баллы не 1 и 0, а в процентном соотношение.

procedure FillArray(var A: array of Integer);
var
I, S, R: Integer;
begin
for I := 0 to High(A) do
A[I] := I;
for i := High(A) downto 0 do
begin
R := Random(I);
S := A[R];
A[R] := A[I];
A[I] := S;
end;
end;

procedure Ttest.Vopros(nomer:integer);
begin
DataModule2.Vopros.Locate('Номер',mass[nomer],[]);
//варианты ответов
DataModule2.Variant.First;
RadioButton1.Caption:=DataModule2.Variant.FieldValues['Ответ'];
if DataModule2.Variant.FieldValues['Правильный']=true then
RadioButton1.Tag:=1 else RadioButton1.Tag:=0;

DataModule2.Variant.Next;
RadioButton2.Caption:=DataModule2.Variant.FieldValues['Ответ'];
if DataModule2.Variant.FieldValues['Правильный']=true then
RadioButton2.Tag:=1 else RadioButton2.Tag:=0;

DataModule2.Variant.Next;
RadioButton3.Caption:=DataModule2.Variant.FieldValues['Ответ'];
if DataModule2.Variant.FieldValues['Правильный']=true then
RadioButton3.Tag:=1 else RadioButton3.Tag:=0;

DataModule2.Variant.Next;
RadioButton4.Caption:=DataModule2.Variant.FieldValues['Ответ'];
if DataModule2.Variant.FieldValues['Правильный']=true then
RadioButton4.Tag:=1 else RadioButton4.Tag:=0;
Label2.Caption:=inttostr(strtoint(Label2.Caption)+1);
end;

procedure Ttest.Button1Click(Sender: TObject);
var i:integer;
RB:TRadioButton;
cena:string;
begin
if ((RadioButton1.Checked=true) or
(RadioButton2.Checked=true) or
(RadioButton3.Checked=true) or
(RadioButton4.Checked=true) )

then
begin
for i := 0 to GroupBox1.ControlCount-1 do
begin
RB:=TRadioButton(GroupBox1.Controls[i]);
if RB.Checked=true then
Label1.Caption:=inttostr(strtoint(Label1.Caption)+RB.Tag);
end;



if strtoint(Label2.Caption)<16 then
begin
Vopros(strtoint(Label2.Caption));
RadioButton1.Checked:=false;
RadioButton2.Checked:=false;
RadioButton3.Checked:=false;
RadioButton4.Checked:=false;

test.Caption:='Тестирование.Вопрос'+inttostr(strtoint(Label2.Caption)-1)+' из 15';
end else
begin
if strtoint(Label1.Caption)>8 then
ocen:='5' else
if strtoint(Label1.Caption)>6 then
ocen:='4' else
if strtoint(Label1.Caption)>4 then
ocen:='3' else
ocen:='2';

if MessageDlg('Набрано баллов '+Label1.Caption+'.'+#13+
'Ваша оценка: '+ocen+'!'+ 'Правильных: '+IntToStr(i)+,
mtConfirmation, [mbYes], 0)=mrYes then
Form1.Visible:=true;
test.Close;
Label2.Caption:='1';
Label1.Caption:='0';
RadioButton1.Checked:=false;
RadioButton2.Checked:=false;
RadioButton3.Checked:=false;
RadioButton4.Checked:=false;

end;
end else
showmessage('Вы не выбрали вариант ответа!');
end;

procedure Ttesti.Button2Click(Sender: TObject);
var i,kol:integer;
begin
For i:=1 to DataModule2.Vopros.RecordCount do
begin
DataModule2.Vopros.Edit;
DataModule2.Vopros.FieldValues['Номер']:=i;
DataModule2.Vopros.Post;
DataModule2.Vopros.Next;
end;
DataModule2.Vopros.Last;
kol:=DataModule2.Vopros.FieldValues['id'];

Randomize;

SetLength(mass,kol);
FillArray(mass);

Vopros(strtoint(Label2.Caption));
testi.Caption:='Тестирование. Вопрос 1 из 50';

end;



OCTAGRAM
Как я понял, DataModule2.Vopros.Locate делает запрос из БД. Сам этот запрос, наверное, можно изменить так, чтоб был случайный порядок (ORDER BY RANDOM()). Или ORDER BY IFF(id MOD 4 = 0, …, …), где перебираются все возможные остатки id от деления на 4 и в зависимости от этого подставляются номера из случайно сгенеренного масива вроде того, что делает FillArray.

Или запросить всё сразу, а потом переставить:

procedure Ttest.Vopros(nomer:integer);
type TOtvet = record
Text: string;
Verno: Boolean;
end;
var
Perestanovka: array[0 .. 4] of Integer;
Otvet: array[0 .. 4] of TOtvet;
I: Integer;
begin
DataModule2.Vopros.Locate('Номер',mass[nomer],[]);

for I := 0 to 3 do
begin
if I = 0 then
DataModule2.Variant.First;
else
DataModule2.Variant.Next;
Otvet[I].Text := DataModule2.Variant.FieldValues['Ответ'];
Otvet[I].Verno := DataModule2.Variant.FieldValues['Правильный']=True;
end;

FillArray(Perestanovka);

//варианты ответов
RadioButton1.Caption:=Otvet[Perestanovka[0]].Text;
if Otvet[Perestanovka[0]].Verno then
RadioButton1.Tag:=1 else RadioButton1.Tag:=0;

RadioButton2.Caption:=Otvet[Perestanovka[1]].Text;
if Otvet[Perestanovka[1]].Verno then
RadioButton2.Tag:=1 else RadioButton2.Tag:=0;

RadioButton3.Caption:=Otvet[Perestanovka[2]].Text;
if Otvet[Perestanovka[2]].Verno then
RadioButton3.Tag:=1 else RadioButton3.Tag:=0;

RadioButton4.Caption:=Otvet[Perestanovka[3]].Text;
if Otvet[Perestanovka[3]].Verno then
RadioButton4.Tag:=1 else RadioButton4.Tag:=0;
Label2.Caption:=inttostr(strtoint(Label2.Caption)+1);
end;
Vera
Добавлено через 4 мин.
Цитата(OCTAGRAM @ 3.12.2017 17:35) *

Как я понял, DataModule2.Vopros.Locate делает запрос из БД. Сам этот запрос, наверное, можно изменить так, чтоб был случайный порядок (ORDER BY RANDOM()). Или ORDER BY IFF(id MOD 4 = 0, …, …), где перебираются все возможные остатки id от деления на 4 и в зависимости от этого подставляются номера из случайно сгенеренного масива вроде того, что делает FillArray.

Или запросить всё сразу, а потом переставить:

procedure Ttest.Vopros(nomer:integer);
type TOtvet = record
Text: string;
Verno: Boolean;
end;
var
Perestanovka: array[0 .. 4] of Integer;
Otvet: array[0 .. 4] of TOtvet;
I: Integer;
begin
DataModule2.Vopros.Locate('Номер',mass[nomer],[]);

for I := 0 to 3 do
begin
if I = 0 then
DataModule2.Variant.First;
else
DataModule2.Variant.Next;
Otvet[I].Text := DataModule2.Variant.FieldValues['Ответ'];
Otvet[I].Verno := DataModule2.Variant.FieldValues['Правильный']=True;
end;

FillArray(Perestanovka);

//варианты ответов
RadioButton1.Caption:=Otvet[Perestanovka[0]].Text;
if Otvet[Perestanovka[0]].Verno then
RadioButton1.Tag:=1 else RadioButton1.Tag:=0;

RadioButton2.Caption:=Otvet[Perestanovka[1]].Text;
if Otvet[Perestanovka[1]].Verno then
RadioButton2.Tag:=1 else RadioButton2.Tag:=0;

RadioButton3.Caption:=Otvet[Perestanovka[2]].Text;
if Otvet[Perestanovka[2]].Verno then
RadioButton3.Tag:=1 else RadioButton3.Tag:=0;

RadioButton4.Caption:=Otvet[Perestanovka[3]].Text;
if Otvet[Perestanovka[3]].Verno then
RadioButton4.Tag:=1 else RadioButton4.Tag:=0;
Label2.Caption:=inttostr(strtoint(Label2.Caption)+1);
end;



Спасибо большое, изменила код на присланный вами. Варианты ответов стали меняться. Только вот вопросы, в принципе как и раньше, повторяются следуя сразу друг за другом, и с каждым новым прохождением повторение увеличивается.
OCTAGRAM
Есть гипотеза, что в начало Ttesti.Button2Click надо добавить

   DataModule2.Vopros.First;
Vera
Цитата(OCTAGRAM @ 9.12.2017 4:22) *

Есть гипотеза, что в начало Ttesti.Button2Click надо добавить

   DataModule2.Vopros.First;



Спасибо большое, теперь не повторяются. А вы не подскажете еще как написать, чтобы можно было ставить разное количество баллов, а не только 1. Чтобы выводилась сумма баллов и ее % от максимума и правильные ответы на те вопросы, по которым тестируемый дал неверные ответ.
OCTAGRAM
Цитата(Vera @ 10.12.2017 15:24) *
А вы не подскажете еще как написать, чтобы можно было ставить разное количество баллов, а не только 1. Чтобы выводилась сумма баллов


Например, в RadioButton3.Tag ставить не 0 или 1, как сейчас, а 0 или баллы за вопрос. DataModule2.Vopros.FieldValues['Баллы'].AsInteger или что-нибудь вроде того. Сложение уже делается так, что менять сильно не надо.

Цитата(Vera @ 10.12.2017 15:24) *
и ее % от максимума

Можно параллельно реальной сумме баллов вести сумму балов, сколько могло бы быть максимум. Я заметил, вы не используете нормальный механизм для этого, приватные поля, а вместо этого всё держите в метках и гоняете из числа в строку и обратно постоянно. Я не вижу, mass — глобальная переменная или поле, но рядом с ним не мешало бы побольше данных хранить в типизированном виде. Можно, конечно, завести невидимый TLabel под текущий максимум баллов. Или при подведении итогов запрос к базе данных сделать на максимум. В конце умножить реальную сумму на 100 и поделить целочисленно (div) на максимум. Это будут проценты.

Цитата(Vera @ 10.12.2017 15:24) *
и правильные ответы на те вопросы, по которым тестируемый дал неверные ответ.


Для этого можно (если не сильно заботиться о типизации) завести поле типа string и при неправильных ответах дописывать в него информацию о том, какой был правильный и какой правильный:

  FText := FText + #13#10#13#10 + 'Вопрос ' + … + #13#10 + 'Правильный ответ: ' + … + #13#10 + 'Был выбран ответ: ' + …;


А потом при подведении итогов в MessageDlg написать + FText в конце. #13#10 — это спецсимволы CR и LF, перенос строки в Windows.
Vera
Цитата(OCTAGRAM @ 10.12.2017 16:44) *

Цитата(Vera @ 10.12.2017 15:24) *
А вы не подскажете еще как написать, чтобы можно было ставить разное количество баллов, а не только 1. Чтобы выводилась сумма баллов


Например, в RadioButton3.Tag ставить не 0 или 1, как сейчас, а 0 или баллы за вопрос. DataModule2.Vopros.FieldValues['Баллы'].AsInteger или что-нибудь вроде того. Сложение уже делается так, что менять сильно не надо.

Цитата(Vera @ 10.12.2017 15:24) *
и ее % от максимума

Можно параллельно реальной сумме баллов вести сумму балов, сколько могло бы быть максимум. Я заметил, вы не используете нормальный механизм для этого, приватные поля, а вместо этого всё держите в метках и гоняете из числа в строку и обратно постоянно. Я не вижу, mass — глобальная переменная или поле, но рядом с ним не мешало бы побольше данных хранить в типизированном виде. Можно, конечно, завести невидимый TLabel под текущий максимум баллов. Или при подведении итогов запрос к базе данных сделать на максимум. В конце умножить реальную сумму на 100 и поделить целочисленно (div) на максимум. Это будут проценты.

Цитата(Vera @ 10.12.2017 15:24) *
и правильные ответы на те вопросы, по которым тестируемый дал неверные ответ.


Для этого можно (если не сильно заботиться о типизации) завести поле типа string и при неправильных ответах дописывать в него информацию о том, какой был правильный и какой правильный:

  FText := FText + #13#10#13#10 + 'Вопрос ' + … + #13#10 + 'Правильный ответ: ' + … + #13#10 + 'Был выбран ответ: ' + …;


А потом при подведении итогов в MessageDlg написать + FText в конце. #13#10 — это спецсимволы CR и LF, перенос строки в Windows.


С полем FText не получается, про % тоже не понятно, чтобы выводилось в таком виде (if (...<=100) and ...r>=80) then t:=5 и тд). mass глобальная переменная.
OCTAGRAM
Ну проценты посчитать сначала надо, а уже потом сравнивать. «не получается» — это слишком не конкретно
Vera
Цитата(OCTAGRAM @ 10.12.2017 19:04) *

Ну проценты посчитать сначала надо, а уже потом сравнивать. «не получается» — это слишком не конкретно


Что надо подставлять в поле FText + 'Вопрос' + ...
OCTAGRAM
Там расписывать надо, какой вопрос, какой был выбран ответ и какой ответ был правильным.

Эту информацию, как я понимаю, надо вытаскивать из элементов управления. Если не переделывать структуру (не переносить информацию в приватные поля), то это будут развесистые if'ы, сравнения тегов переключателей и т.п.
nishaknapp
Why not settling on games that is fun and at the same time your earning. Well it'll make suspense because the game is well but dude just try it and it gave me hope while pandemic is real rn. DIFFERENT TYPES OF ONLINE SLOT GAMES
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.