
Я нашел отличный код, чтобы получить n случайных вопросов отbankA.tex
Создать экзамен из банка вопросов?
Но мне нужно получить только n-ный вопрос в bankA? например: \getquestionsfrombank{bankA.tex}{6}
, тогда мы получим только 6-й вопрос (Question 6) в bankA.tex. Можете ли вы мне помочь?
\documentclass{article}
\usepackage{multicol}% Just for this example
\usepackage{filecontents}
\begin{filecontents*}{bankA.tex}
\begin{questionblock}
Question 1
\end{questionblock}
\begin{questionblock}
Question 2
\end{questionblock}
\begin{questionblock}
Question 3
\end{questionblock}
\begin{questionblock}
Question 4
\end{questionblock}
\begin{questionblock}
Question 5
\end{questionblock}
\begin{questionblock}
Question 6
\end{questionblock}
\begin{questionblock}
Question 7
\end{questionblock}
\begin{questionblock}
Question 8
\end{questionblock}
\begin{questionblock}
Question 9
\end{questionblock}
\begin{questionblock}
Question 10
\end{questionblock}
\end{filecontents*}
\usepackage{catchfile,environ,tikz}
\makeatletter% Taken from https://tex.stackexchange.com/q/109619/5764
\def\declarenumlist#1#2#3{%
\expandafter\edef\csname pgfmath@randomlist@#1\endcsname{#3}%
\count@\@ne
\loop
\expandafter\edef
\csname pgfmath@randomlist@#1@\the\count@\endcsname
{\the\count@}
\ifnum\count@<#3\relax
\advance\count@\@ne
\repeat}
\def\prunelist#1{%
\expandafter\xdef\csname pgfmath@randomlist@#1\endcsname
{\the\numexpr\csname pgfmath@randomlist@#1\endcsname-1\relax}
\count@\pgfmath@randomtemp
\loop
\expandafter\global\expandafter\let
\csname pgfmath@randomlist@#1@\the\count@\expandafter\endcsname
\csname pgfmath@randomlist@#1@\the\numexpr\count@+1\relax\endcsname
\ifnum\count@<\csname pgfmath@randomlist@#1\endcsname\relax
\advance\count@\@ne
\repeat}
\makeatother
% Define how each questionblock should be handled
\newcounter{questionblock}
\newcounter{totalquestions}
\NewEnviron{questionblock}{}%
\newcommand{\randomquestionsfrombank}[2]{%
\CatchFileDef{\bank}{#1}{}% Read the entire bank of questions into \bank
\setcounter{totalquestions}{0}% Reset total questions counters ***
\RenewEnviron{questionblock}{\stepcounter{totalquestions}}% Count every question ***
\bank% Process file ***
\declarenumlist{uniquequestionlist}{1}{\thetotalquestions}% list from 1 to totalquestions inclusive.
\setcounter{totalquestions}{#2}% Start the count-down
\RenewEnviron{questionblock}{%
\stepcounter{questionblock}% Next question
\ifnum\value{questionblock}=\randomquestion
\par% Start new paragraph
\BODY% Print question
\fi
}%
\foreach \uNiQueQ in {1,...,#2} {% Extract #2 random questions
\setcounter{questionblock}{0}% Start fresh with question block counter
\pgfmathrandomitem\randomquestion{uniquequestionlist}% Grab random question from list
\xdef\randomquestion{\randomquestion}% Make random question available globally
\prunelist{uniquequestionlist}% Remove picked item from list
\bank% Process file
}}
\begin{document}
\begin{multicols}{3}
\foreach \x in {1,...,6} {
\bigskip
\randomquestionsfrombank{bankA.tex}{6}
}
\end{multicols}
\end{document}
решение1
Обновлено
Использование:
% parse all questions from "bankA.tex"
\storequestionsfrombank{bankA.tex}
\begin{multicols}{3}
% print questions 1, 3, 5, and 7 in order
\foreach \x in {1,3,5,7} {
\pickquestionfrombank{\x}
}
\end{multicols}
Определение:
% read file #1, store quesion <num> in \question@body@<num>
\newcommand{\storequestionsfrombank}[1]{%
\CatchFileDef{\bank}{#1}{}% Read the entire bank of questions into \bank
\RenewEnviron{questionblock}{%
\stepcounter{totalquestions}%
\expandafter\global\expandafter\let
\csname question@body@\the\value{totalquestions}\endcsname\BODY
}%
\setcounter{totalquestions}{0}%
\bank}
% print question #1 in constant time
\newcommand\pickquestionfrombank[1]{%
\par
\@nameuse{question@body@#1}%
}
Оригинальный ответ
С этой новой командой
% print question #2 from bank #1 in linear time
\newcommand{\pickquestionsfrombank}[2]{%
\CatchFileDef{\bank}{#1}{}% Read the entire bank of questions into \bank
\setcounter{totalquestions}{0}% Reset total questions counters ***
\RenewEnviron{questionblock}{%
\stepcounter{totalquestions}% Next question
\ifnum\value{totalquestions}=#2
\par% Start new paragraph
\BODY% Print question
\fi
}%
\setcounter{totalquestions}{0}%
\bank}
вход
\pickquestionsfrombank{bankA.tex}{<number>}
распечатает содержание вопроса <number>
.
Полный пример:
\begin{filecontents}[force]{bankA.tex}
\begin{questionblock}
Question 1
\end{questionblock}
\begin{questionblock}
Question 2
\end{questionblock}
\begin{questionblock}
Question 3
\end{questionblock}
\begin{questionblock}
Question 4
\end{questionblock}
\begin{questionblock}
Question 5
\end{questionblock}
\begin{questionblock}
Question 6
\end{questionblock}
\begin{questionblock}
Question 7
\end{questionblock}
\begin{questionblock}
Question 8
\end{questionblock}
\begin{questionblock}
Question 9
\end{questionblock}
\begin{questionblock}
Question 10
\end{questionblock}
\end{filecontents}
\documentclass{article}
\usepackage{multicol}% Just for this example
\usepackage{catchfile,environ,tikz}
\makeatletter% Taken from https://tex.stackexchange.com/q/109619/5764
\def\declarenumlist#1#2#3{%
\expandafter\edef\csname pgfmath@randomlist@#1\endcsname{#3}%
\count@\@ne
\loop
\expandafter\edef
\csname pgfmath@randomlist@#1@\the\count@\endcsname
{\the\count@}
\ifnum\count@<#3\relax
\advance\count@\@ne
\repeat}
\def\prunelist#1{%
\expandafter\xdef\csname pgfmath@randomlist@#1\endcsname
{\the\numexpr\csname pgfmath@randomlist@#1\endcsname-1\relax}
\count@\pgfmath@randomtemp
\loop
\expandafter\global\expandafter\let
\csname pgfmath@randomlist@#1@\the\count@\expandafter\endcsname
\csname pgfmath@randomlist@#1@\the\numexpr\count@+1\relax\endcsname
\ifnum\count@<\csname pgfmath@randomlist@#1\endcsname\relax
\advance\count@\@ne
\repeat}
\makeatother
% Define how each questionblock should be handled
\newcounter{questionblock}
\newcounter{totalquestions}
\NewEnviron{questionblock}{}%
\newcommand{\randomquestionsfrombank}[2]{%
\CatchFileDef{\bank}{#1}{}% Read the entire bank of questions into \bank
\setcounter{totalquestions}{0}% Reset total questions counters ***
\RenewEnviron{questionblock}{\stepcounter{totalquestions}}% Count every question ***
\bank% Process file ***
\declarenumlist{uniquequestionlist}{1}{\thetotalquestions}% list from 1 to totalquestions inclusive.
\setcounter{totalquestions}{#2}% Start the count-down
\RenewEnviron{questionblock}{%
\stepcounter{questionblock}% Next question
\ifnum\value{questionblock}=\randomquestion
\par% Start new paragraph
\BODY% Print question
\fi
}%
\foreach \uNiQueQ in {1,...,#2} {% Extract #2 random questions
\setcounter{questionblock}{0}% Start fresh with question block counter
\pgfmathrandomitem\randomquestion{uniquequestionlist}% Grab random question from list
\xdef\randomquestion{\randomquestion}% Make random question available globally
\prunelist{uniquequestionlist}% Remove picked item from list
\bank% Process file
}}
\newcommand{\pickquestionsfrombank}[2]{%
\CatchFileDef{\bank}{#1}{}% Read the entire bank of questions into \bank
\RenewEnviron{questionblock}{%
\stepcounter{totalquestions}% Next question
\ifnum\value{totalquestions}=#2
\par% Start new paragraph
\BODY% Print question
\fi
}%
\setcounter{totalquestions}{0}%
\bank}
\begin{document}
\begin{multicols}{3}
\foreach \x in {1,3,5,7} {
\pickquestionsfrombank{bankA.tex}{\x}
}
% this prints questions 1, 3, 5, and 7 in order
\end{multicols}
\end{document}
Обратите внимание, что с 2019-10-01 latex2e пакет filecontents
устарел, а его утилита объединена с latex2e. Поэтому я заменяю environment filecontents*
на \begin{filecontents}[force]{bankA.tex}
.