Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > Delphi > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail


Донат для форума - использовать для поднятия настроения себе и модераторам

А ещё здесь можно купить рекламу за 15 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru

Ответ
 
Опции темы
Старый 25.05.2019, 19:38   #1
EverMan32
Новичок
 
Регистрация: 28.03.2019
Сообщений: 2
Репутация: 10
По умолчанию Рандомный вывод вопросов с исключением повторений

Здравствуйте, необходимо сделать рандомный вывод вопросов на форму, у меня в программе реализована последовательная загрузка одного за другим, при этом необходимо исключить повторения. Внизу идёт подсчёт правильных ответов.Пробовал делать в процедуре WriteVopros Num:=random(n); но при этом нарушается нумерация на форме Вопрос№1 и идёт не по порядку, а по номеру теста, который появился, а также сбивается подсчёт результатов.
Код:
unit Test;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls, Book_Test, Prepod, Student, jpeg;

type
  TForm5 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Image1: TImage;
    RadioGroup1: TRadioGroup;
    BitBtn1: TBitBtn;
    Label3: TLabel;
    BitBtn2: TBitBtn;
    procedure BitBtn2Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure WriteVopros(k:integer);
    procedure BitBtn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form5: TForm5;
  Tst:array[1..50] of Vopros;
  n,Sum,Num:integer;
  res:string;

implementation

{$R *.dfm}

procedure TForm5.WriteVopros(k:integer);
var i:integer;
begin
  //Вывод вопроса № k на форму:
  //Номер вопроса:
  Label1.Caption:='Вопрос №'+IntToStr(k)+':';
  //Текст вопроса:
  Label2.Caption:=Tst[k].Text;
  //Рисунок к вопросу:
try
  if Tst[k].FileRis<>'' then
    Image1.Picture.LoadFromFile('Test/'+Tst[k].FileRis)
  else
    Image1.Visible:=false;
except
  //Image1.Picture.LoadFromFile('Test/AN00790_.WMF');
  showmessage('Не найден файл указанного рисунка к вопросу!');
end;
  //Варианты ответов:
  RadioGroup1.Items.Clear;
  for i:=1 to 4 do
    RadioGroup1.Items.Add(Tst[k].Variant[i]);
  for i:=0 to 3 do
    RadioGroup1.Buttons[i].WordWrap:=true;
  RadioGroup1.ItemIndex:=-1;
  //Текуший результат:
  res:='Результат. Правильных ответов: '+IntToStr(Sum)+' из '+IntToStr(k-1);
  if k>1 then
    res:=res+' ('+IntToStr(Sum*100 div (k-1))+'%).';
  Label3.Caption:=res;
end;

procedure TForm5.FormShow(Sender: TObject);
begin
  //Открытие формы
  //Открыть файл теста, прочитать вопросы теста из файла в массив:
  //s - имя файла с выбранным тестом
 Caption:=Caption+' '+SpisStud[NumStud].FIO;
 try
  AssignFile(ftest,s);
  Reset(ftest);
  n:=0;
  while not eof(ftest) do begin
    inc(n);
    read(ftest,Tst[n]);
  end;
  CloseFile(ftest);
  BitBtn2.Enabled:=False;
  BitBtn1.Enabled:=True;
  //Вывод 1-го вопроса:
  Num:=1;
  Sum:=0;
  WriteVopros(Num);
 except
   showmessage('Не найден файл теста!');
   close;
 end;
end;

procedure TForm5.BitBtn1Click(Sender: TObject);
var rec:boolean;
begin
  //Нажатие на кнопку "Далее"
  //Проверка правильности ответа на текущий вопрос:
  if RadioGroup1.ItemIndex+1=Tst[Num].NumVern then inc(Sum)
  else showmessage(Tst[Num].Help);
  //Вывод следуещего вопроса:
  inc(Num);
  if Num<=n then WriteVopros(Num)
  else begin //Тест закончен
     BitBtn2.Enabled:=True;
     BitBtn1.Enabled:=False;
     res:='Результат. Правильных ответов: '+IntToStr(Sum)+' из '+IntToStr(n);
     res:=res+' ('+IntToStr(Sum*100 div n)+'%). ';
     //Запись результата тестирования в файл:
     Repeat
     rec:=True;
     try
       AssignFile(frestest,'Data/ResTest.dat');
       Reset(frestest);
       Seek(frestest,FileSize(frestest));
       restest.Group:=SpisStud[NumStud].Group;
       restest.FIO:=SpisStud[NumStud].FIO;
       restest.DateTest:=Date;
       restest.NumTest:=Form4.ListBox1.ItemIndex+1;
       restest.ResProcent:=Sum*100 div n;
       write(frestest,restest);
       CloseFile(frestest);
     except
       Rewrite(frestest);
       rec:=False;
     end;
     Until rec;
     res:=res+'Тестирование закончено.';
     Label3.Caption:=res;
  end;
end;

procedure TForm5.BitBtn2Click(Sender: TObject);
begin
  //Выход. Закрыть форму "Тестирование":
  Close;
end;

end.
EverMan32 вне форума   Ответить с цитированием
Старый 25.05.2019, 22:56   #2
Serge_Bliznykov
МегаМодератор
СуперМодератор
 
Регистрация: 09.01.2008
Сообщений: 25,450
Репутация: 5596
По умолчанию

Вы предоставили неполную информацию.
Нет описания структуры вопроса (Vopros). Неизвестно где описан ftest и т.д.

но, если я правильно Вас понял, вашу проблему можно решить и достаточно просто.
Нужно просто перемешать вопросы в массиве после их чтения:
Код:
procedure TForm5.FormShow(Sender: TObject);
var 
  i,k:integer;
  buf : Vopros;
begin
  //Открытие формы
  //Открыть файл теста, прочитать вопросы теста из файла в массив:
  //s - имя файла с выбранным тестом
 Caption:=Caption+' '+SpisStud[NumStud].FIO;
 try

  AssignFile(ftest,s);
  Reset(ftest);
  n:=0;
  while not eof(ftest) do begin
    inc(n);
    read(ftest,Tst[n]);
  end;
  CloseFile(ftest);

  Randomize;

  //----------перемешать-------------
  for i:=1 to n-1 do
  begin
   k:= Random(n-i+1)+i;
   if k<>i then begin
     buf:=Tst[i];
     Tst[i]:=Tst[k];
     Tst[k]:=buf;
   end;
  end;

  BitBtn2.Enabled:=False;
  BitBtn1.Enabled:=True;
  //Вывод 1-го вопроса:
  Num:=1;
  Sum:=0;
  WriteVopros(Num);
 except
   showmessage('Не найден файл теста!');
   close;
 end;
end;
Serge_Bliznykov вне форума   Ответить с цитированием
Старый 25.05.2019, 23:10   #3
EverMan32
Новичок
 
Регистрация: 28.03.2019
Сообщений: 2
Репутация: 10
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
Вы предоставили неполную информацию.
Нет описания структуры вопроса (Vopros). Неизвестно где описан ftest и т.д.

но, если я правильно Вас понял, вашу проблему можно решить и достаточно просто.
Нужно просто перемешать вопросы в массиве после их чтения:
Код:
procedure TForm5.FormShow(Sender: TObject);
var 
  i,k:integer;
  buf : Vopros;
begin
  //Открытие формы
  //Открыть файл теста, прочитать вопросы теста из файла в массив:
  //s - имя файла с выбранным тестом
 Caption:=Caption+' '+SpisStud[NumStud].FIO;
 try

  AssignFile(ftest,s);
  Reset(ftest);
  n:=0;
  while not eof(ftest) do begin
    inc(n);
    read(ftest,Tst[n]);
  end;
  CloseFile(ftest);

  Randomize;

  //----------перемешать-------------
  for i:=1 to n-1 do
  begin
   k:= Random(n-i+1)+i;
   if k<>i then begin
     buf:=Tst[i];
     Tst[i]:=Tst[k];
     Tst[k]:=buf;
   end;
  end;

  BitBtn2.Enabled:=False;
  BitBtn1.Enabled:=True;
  //Вывод 1-го вопроса:
  Num:=1;
  Sum:=0;
  WriteVopros(Num);
 except
   showmessage('Не найден файл теста!');
   close;
 end;
end;
Спасибо, работает, а я начинал всё усложнять, присваивая Num:=random(n), при этом вопросы иногда повторялись, да и плохо считались результаты, а вы так грамотно сделали.
EverMan32 вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
VBS как написать цикл Do While... Loop с исключением повторений Alex_Dom Microsoft Office Excel 5 15.02.2019 11:59
Рандомный вывод GRFed PHP 5 19.07.2017 10:15
Рандомный вывод вопросов в тесте Алексей_2012 Общие вопросы Delphi 12 25.05.2016 20:28
Создать рандомный массив без повторений элементов KYZ Помощь студентам 8 09.10.2014 11:54
Рандомный вывод Forrest Gamp Общие вопросы C/C++ 6 10.02.2008 16:03


20:25.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.

Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru