texlive[60481] Master/texmf-dist: mcexam (12sep21)

commits+karl at tug.org commits+karl at tug.org
Sun Sep 12 22:29:14 CEST 2021


Revision: 60481
          http://tug.org/svn/texlive?view=revision&revision=60481
Author:   karl
Date:     2021-09-12 22:29:14 +0200 (Sun, 12 Sep 2021)
Log Message:
-----------
mcexam (12sep21)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/mcexam/README.md
    trunk/Master/texmf-dist/doc/latex/mcexam/mcexam.pdf
    trunk/Master/texmf-dist/doc/latex/mcexam/mcexam.tex
    trunk/Master/texmf-dist/doc/latex/mcexam/mcexam_example.tex
    trunk/Master/texmf-dist/tex/latex/mcexam/mcexam.sty

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/latex/mcexam/mcexam_example_dataset.r

Removed Paths:
-------------
    trunk/Master/texmf-dist/doc/latex/mcexam/mcexam_example.r

Modified: trunk/Master/texmf-dist/doc/latex/mcexam/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/mcexam/README.md	2021-09-12 20:28:41 UTC (rev 60480)
+++ trunk/Master/texmf-dist/doc/latex/mcexam/README.md	2021-09-12 20:29:14 UTC (rev 60481)
@@ -1,9 +1,9 @@
-mcexam package v0.4
+mcexam package v0.5
 
 The mcexam package is a LaTeX package that automatically randomly permutes the order of questions and answer options in different versions of a multiple choice exam/test. Next to the exam versions themselves, the package also allows printing a concept version of the exam, a key table with the correct answers or points, and a document with solutions and explanation per exam version. The package also allows writing an R code which processes the results of the exam and calculates the grades.
 
 ---------------
-Jorre Vannieuwenhuyze 2017
+Jorre Vannieuwenhuyze 2021
 jorre_v[ad]zoho.com
 
 Permission is granted to copy, distribute and/or modify this software under the terms of the LaTeX Project Public License, version 1.3c or later.

Modified: trunk/Master/texmf-dist/doc/latex/mcexam/mcexam.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/mcexam/mcexam.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/mcexam/mcexam.tex	2021-09-12 20:28:41 UTC (rev 60480)
+++ trunk/Master/texmf-dist/doc/latex/mcexam/mcexam.tex	2021-09-12 20:29:14 UTC (rev 60481)
@@ -218,7 +218,7 @@
 
 \subsection{The questions}
 
-The most important parts of the exam are, of course, the questions. Within the body of your script file, you place the questions within the \verb$mcquestions$-environment which works similar to list-environments. Each question is preceded by a \verb$\question$ command similar to the \verb$\item$ command :
+The most important parts of the exam are, of course, the questions. Within the body of your script file, you place the questions within the \verb$mcquestions$-environment which works similar to list-environments. Each question is preceded by a \verb$\question$ command similar to the \verb$\item$ command:
 \begin{code}
 \begin{mcquestions}
 \question This is the first question.
@@ -314,7 +314,7 @@
  \item \verb$permutenone$:
        This option doesn't permute the answers and sorts the answers in each version in the same order as they are given in the script file.
  \item \emph{User specific}:
-       If none of the above options satisfies your needs, you can still enter the possible permutations manually. You achieve this by making a comma separated list of all allowed permutations where each permutation itself is a comma separated list of all answer numbers within two curly braces. For example, if your question contains three answers you can give the option \verb$[{1,2,3},{2,3,1}]$. With this option, the package will either put the answers in the order `answer 1, answer 2, answer 3' or in the order `answer 2, answer 3, answer 1'. The package will throw errors if only one permutation is given, if a permutation does not contain all answer numbers, if a permutations contains answer numbers more than once, or if a permutation contains invalid answer numbers. The package will not throw errors if a permutation is given more than once. For example, \verb$[{1,2,3},{1,2,3},{2,3,1}]$ will not give errors, it just means that the order `1,~2,~3' is twice more likely to appear than the order `2,~3,~1'.
+       If none of the above options satisfies your needs, you can still enter the possible permutations manually. You achieve this by making a comma separated list of all allowed permutations where each permutation itself is a comma separated list of all answer numbers within two curly braces. For example, if your question contains three answers you can give the option \verb$[{1,2,3},{2,3,1}]$. With this option, the package will either put the answers in the order `answer 1, answer 2, answer 3' or in the order `answer 2, answer 3, answer 1'. The package will throw errors if only one permutation is given, if a permutation does not contain all answer numbers, if a permutation contains answer numbers more than once, or if a permutation contains invalid answer numbers. The package will not throw errors if a permutation is given more than once. For example, \verb$[{1,2,3},{1,2,3},{2,3,1}]$ will not give errors, it just means that the order `1,~2,~3' is twice more likely to appear than the order `2,~3,~1'.
 \end{itemize}
 
 Putting all together, in your script file you can write something like this:
@@ -684,18 +684,13 @@
 
 \item[2017/12/26 v0.4:] Added \texttt{pgffor} package to fix bug.
 
+\item[2021/09/12 v0.5:] Fixed bugs with randomization of answers.
+
 \end{description}
 
 
 
-\subsection{Planned modifications}
 
-\begin{itemize}
- \item Add an error message when you only have one question and the option randomizequestions=true. Now, you should change this option explicitly to randomizequestions=false for one question.
- \item Find an alternative for longtable which is now the default for tables in the package. Longtable doesn't work with twocolumn.
- \item Add a function to reproduce the questions in another permutation/version within the same document.
- \item Add the option to continue the question counter over several mcquestions environments. 
-\end{itemize}
 
 
 

Deleted: trunk/Master/texmf-dist/doc/latex/mcexam/mcexam_example.r
===================================================================
--- trunk/Master/texmf-dist/doc/latex/mcexam/mcexam_example.r	2021-09-12 20:28:41 UTC (rev 60480)
+++ trunk/Master/texmf-dist/doc/latex/mcexam/mcexam_example.r	2021-09-12 20:29:14 UTC (rev 60481)
@@ -1,118 +0,0 @@
-mcprocessanswers <- function(ID,versions,answers,path=getwd()) {
- 
-tol <- .Machine$double.eps^0.5 
-if(! is.numeric(answers)) stop("non-numeric value(s) in answers, mcprocessanswers stopped") 
-if(min(answers > tol)==0) stop("non-positive value(s) in answers, mcprocessanswers stopped") 
-if(min(abs(answers - round(answers)) < tol)==0) stop("non-integer value(s) in answers, mcprocessanswers stopped") 
-if(! is.numeric(versions)) stop("non-numeric value(s) in versions, mcprocessanswers stopped") 
-if(min(versions > tol)==0) stop("non-positive value(s) in versions, mcprocessanswers stopped") 
-if(min(abs(versions - round(versions)) < tol)==0) stop("non-integer value(s) in versions, mcprocessanswers stopped") 
-if(min(versions-4< tol)==0) stop("value(s) in versions too large, maximum possible value is 4, mcprocessanswers stopped") 
- 
-questiondictionary=list(c(11,3,14,15,16,17,12,2,6,4,7,8,5,9,10,13,1),c(8,10,3,4,5,15,11,16,2,12,7,6,17,9,1,13,14),c(7,11,8,9,10,3,1,15,4,2,12,17,16,13,14,5,6),c(13,12,3,4,5,9,2,11,16,17,14,15,1,6,7,8,10))
- 
-randomizedanswersdictionary=list(
- list(c(3,1,2,4,5),c(3,4,1,2),c(4,1,2,3),c(1,2,3,4,5),c(2,1,3,4),c(2,1,4,3),c(4,1,3,2),c(4,3,2,1),c(3,4,1,2),c(4,3,2,1),c(4,2,1,3),c(4,3,1,2),c(4,3,2,1),c(4,3,2,1),c(2,4,1,3),c(1,2,3,4),c(1,2))
- ,list(c(4,3,1,2,5),c(3,4,2,1),c(1,2,3,4),c(5,4,3,2,1),c(1,2,3,4),c(3,4,1,2),c(2,1,3,4),c(4,3,2,1),c(2,1,3,4),c(4,3,2,1),c(3,1,2,4),c(4,2,3,1),c(4,2,3,1),c(1,2,3,4),c(3,4,2,1),c(2,1,3,4),c(1,2))
- ,list(c(3,2,1,4,5),c(3,1,2,4),c(3,4,1,2),c(5,4,3,2,1),c(2,1,3,4),c(1,2,3,4),c(4,1,2,3),c(1,2,3,4),c(3,4,1,2),c(2,1,3,4),c(1,4,3,2),c(3,2,4,1),c(1,3,2,4),c(4,3,2,1),c(1,4,3,2),c(2,1,3,4),c(1,2))
- ,list(c(2,4,1,3,5),c(2,3,1,4),c(4,1,2,3),c(1,2,3,4,5),c(2,1,3,4),c(4,3,2,1),c(2,4,3,1),c(1,2,3,4),c(3,2,4,1),c(4,1,2,3),c(1,4,2,3),c(3,2,4,1),c(1,2,3,4),c(1,2,3,4),c(1,4,3,2),c(1,2,3,4),c(1,2))
- )
- 
-correctiondictionary=list(c(1,0,0,0,0),c(0,0,1,0),c(1,0,0,0),c(0,1,0,0,0),c(0,1,0,0),c(0,0,0,1),c(1,0,0,0),c(0,0,1,0),c(1,0,0,0),c(0,1,0,0),c(0,0,1,0),c(1,0,0,0),c(0,0,1,0),c(0,0,0,1),c(0,1,0,0),c(0,1,0,0),c(1,0))
- 
-Nversions=4; 
-Nquestions=17;
-Nanswers=c(5,4,4,5,4,4,4,4,4,4,4,4,4,4,4,4,2);
-Nstudents=nrow(answers);
- 
-Q <- matrix(NA,nrow=Nstudents,ncol=Nquestions); 
-P <- matrix(NA,nrow=Nstudents,ncol=Nquestions); 
-for ( student in 1:Nstudents ){
- for (question in 1:Nquestions){
- R <- randomizedanswersdictionary[[versions[student]]][[question]]; 
- Q[student,question] <- R[answers[student,questiondictionary[[versions[student]]][question]]]; 
- P[student,question] <- correctiondictionary[[question]][Q[student,question]]; 
- P[student,question] <- ifelse(is.na(P[student,question]),0,P[student,question]); 
- }}
-Points=apply(P,1,sum); 
-outputdata <- data.frame(ID=ID,versions=versions,originalQuestion=Q,pointsQuestion=P,total=Points); 
- 
-p <- apply(P,2,mean); 
-p.cor <- apply(P,2,mean) - (1-apply(P,2,mean))/(Nanswers-unlist(lapply(correctiondictionary,sum))); 
-r.cor <- NULL; 
-for (i in 1:Nquestions){
- r.cor[i] <- ifelse(var(P[,i])==0,0,cor(P[,i],apply(P[,-i],1,sum))); 
- }
- 
-Nquestions.cor <- sum(apply(P,2,var)>0); 
-alpha <- (Nquestions.cor/(Nquestions.cor-1))*(1-(sum(apply(P,2,var))/var(Points))); 
- 
-outputfilename=file.path(path,"mcexam_example.ana"); 
-write("\\makeatletter",outputfilename) ; 
- 
-formatnumber <- function(x) {
- y <- gsub("(?<![0-9.])0+","", sprintf("%.3f",x),perl = TRUE) 
- n <- nchar(y) 
- y <- gsub(" ","\\\\phantom{-}",y) 
- y <- paste0(strrep("\\phantom{0}",max(n)-n),y) 
- y 
- }; 
-write(c( 
- "\\gdef\\mc at questionAnalysisTable{", 
- " \\begin{setmcquestionanalysistable}", 
- " \\begin{longtable}{cccc}", 
- " & \\mc at babel@Proportion & \\mc at babel@Corrected & \\mc at babel@Item at rest \\\\", 
- " & \\mc at babel@correct & \\mc at babel@proportion & \\mc at babel@correlation \\\\", 
- " \\hline", 
- " \\mc at babel@Question \\\\", 
- " \\endhead", 
- " \\hline", 
- " \\endfoot", 
- " \\hline", 
- paste0(" \\multicolumn{4}{l}{\\mc at babel@Number at of@students\\ = ",Nstudents,"}\\\\"), 
- paste0(" \\multicolumn{4}{l}{Cronbach's alpha = ",sprintf("%.3f",alpha),"}\\\\"), 
- " \\endlastfoot ", 
- paste0(" \\setcounter{mc at counter}{",1:ncol(answers),"}\\mcquestionlabelfmt{mc at counter}& " 
- ,formatnumber(p)," & ",formatnumber(p.cor)," & ",formatnumber(r.cor)," \\\\"), 
- " \\end{longtable}", 
- " \\end{setmcquestionanalysistable}", 
- " }" 
- ),outputfilename,append=TRUE) ; 
- 
-versions.factor <- factor(versions); 
-levels(versions.factor) <- 1:Nversions; 
-for (i in 1:Nquestions) {
- X <- factor(Q[,i],1:Nanswers[i]); 
- props <- cbind(prop.table(table(X,versions.factor,useNA="ifany"),2),prop.table(table(X,useNA="ifany"))); 
- dims <- dim(props); 
- props <- lapply(props,function(x) ifelse(is.na(x),"N.A.",gsub(" ","\\\\phantom{0}",paste0(sprintf("%5.1f",x*100),"\\%")))); 
- dim(props) <- dims; 
- props <- apply(props, 1, paste, collapse=" & "); 
- labels <- paste0(" \\setcounter{mc at counter}{",1:Nanswers[i],"}\\mcanswerlabelfmt{mc at counter}"); 
- labels <- ifelse(is.na(labels[1:dims[1]])," invalid",labels[1:dims[1]]) 
-write(c( 
- paste0("\\csgdef{mc at answerAnalysisTable",i,"}{"), 
- paste0(" \\begin{tabular}{c",strrep("c",Nversions),"c}"), 
- paste0(" \\multicolumn{1}{r}{\\mc at babel@Version}&" 
- ,paste(paste0("\\setcounter{mc at counter}{",1:Nversions, 
- "}\\mcversionlabelfmt{mc at counter}"),collapse="&") 
- ," & \\mc at babel@total \\\\"), 
- " \\hline", 
- " \\mc at babel@Answer \\\\", 
- paste0(labels," & ",props,"\\\\"), 
- " \\hline", 
- paste0(" \\multicolumn{",Nversions+2,"}{l}{\\mc at babel@Proportion at correct\\ = ", 
- sprintf("%.3f",p[i]),"}\\\\"), 
- paste0(" \\multicolumn{",Nversions+2,"}{l}{\\mc at babel@Corrected at proportion\\ = ", 
- sprintf("%.3f",p.cor[i]),"}\\\\"), 
- paste0(" \\multicolumn{",Nversions+2,"}{l}{\\mc at babel@Item at rest@correlation\\ = ", 
- sprintf("%.3f",r.cor[i]),"}\\\\"), 
- " \\end{tabular}", 
- " }" 
- ),outputfilename,append=TRUE) ; 
- }
- 
-write("\\makeatother",outputfilename,append=TRUE) ; 
- 
-outputdata ; 
- }

Modified: trunk/Master/texmf-dist/doc/latex/mcexam/mcexam_example.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/mcexam/mcexam_example.tex	2021-09-12 20:28:41 UTC (rev 60480)
+++ trunk/Master/texmf-dist/doc/latex/mcexam/mcexam_example.tex	2021-09-12 20:29:14 UTC (rev 60481)
@@ -39,9 +39,26 @@
  
   
 
-  
 
 
+% solution counter starting at 3
+%\newcounter{temp}
+%\setlist[setmcquestions]{
+%label=\protect\setcounter{temp}{\arabic{*}}
+%      \protect\addtocounter{temp}{2}
+%      \arabic{temp}.
+%,ref=\protect\setcounter{temp}{\arabic{*}}
+%     \protect\addtocounter{temp}{2}
+%     \arabic{temp}.
+%,itemsep=2\baselineskip
+%,topsep=2\baselineskip }
+
+
+
+
+
+
+
 \begin{document}
 
 
@@ -77,6 +94,7 @@
  
 
 
+    
 
  
 \begin{mcquestions}

Added: trunk/Master/texmf-dist/doc/latex/mcexam/mcexam_example_dataset.r
===================================================================
--- trunk/Master/texmf-dist/doc/latex/mcexam/mcexam_example_dataset.r	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/mcexam/mcexam_example_dataset.r	2021-09-12 20:29:14 UTC (rev 60481)
@@ -0,0 +1,42 @@
+### mcexam_example_dataset.r
+### This code contains some test data for the example of mcexam. First run 
+### mcexam_example.tex through LaTeX, then process this file with R. Next,
+### you can make an analysis version of the exam in LaTeX. Make sure the 
+### working directory is the folder where mcexam_example.tex resorts. 
+###
+### Copyright (c) 2017 Jorre Vannieuwenhuyze.
+###
+### Permission is granted to copy, distribute and/or modify this
+### software under the terms of the LaTeX Project Public License
+### (LPPL), version 1.3c or any later version.
+###
+### This software is provided 'as is', without warranty of any kind,
+### either expressed or implied, including, but not limited to, the
+### implied warranties of merchantability and fitness for a
+### particular purpose.
+
+rm(list = ls())
+
+ID       <- c(1,2,3,4,5,6,7,8,9,10)
+versions <- c(1,1,1,2,2,2,2,3,3,3)
+answers  <- rbind(c(1,2,1,4,2, 3,4,3,1,1, 2,2,2,5,2, 1,3)   #17
+                 ,c(1,1,2,4,3, 2,2,3,1,2, 2,3,2,5,2, 2,3)   #9
+                 ,c(1,2,1,3,2, 3,4,2,1,1, 2,2,3,5,1, 1,3)   #8
+                 ,c(3,2,5,4,2, 4,1,3,4,1, 2,3,1,1,2, 2,3)   #11
+                 ,c(2,2,5,3,2, 3,1,2,4,2, 2,3,1,1,1, 2,3)   #0 
+                 ,c(3,2,5,4,2, 4,1,3,3,1, 2,2,1,1,2, 1,4)   #7 
+                 ,c(3,2,5,4,2, 3,1,3,4,2, 2,3,2,1,1, 2,1)   #2 
+                 ,c(2,1,4,2,1, 1,3,5,4,1, 1,3,1,4,3, 2,4)   #6
+                 ,c(2,1,3,3,1, 1,3,5,4,1, 1,2,1,4,3, 2,4)   #11
+                 ,c(1,1,3,3,2, 1,2,5,4,3, 2,3,4,3,3, 1,3)   #4   
+                 )
+                 
+source("mcexam_example.r")                                  
+data <- mcprocessanswers(ID,versions,answers)   
+
+
+                 
+                 
+
+ 
+ 
\ No newline at end of file

Modified: trunk/Master/texmf-dist/tex/latex/mcexam/mcexam.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/mcexam/mcexam.sty	2021-09-12 20:28:41 UTC (rev 60480)
+++ trunk/Master/texmf-dist/tex/latex/mcexam/mcexam.sty	2021-09-12 20:29:14 UTC (rev 60481)
@@ -46,7 +46,7 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 \NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{mcexam}[2017/12/26 v0.4 LaTeX package for creating randomized Multiple Choice questions]
+\ProvidesPackage{mcexam}[2021/09/12 v0.5 LaTeX package for creating randomized Multiple Choice questions]
 
 % package option: output
 \newbool{mc at concept}
@@ -1057,10 +1057,11 @@
   \foreach \a in {1,...,\csuse{mc at totalNumberOfAnswersQ\q}}{
      \csxdef{mc at answerTempnum\a}{\a}
      }
+  \numdef\@numberofpermuteanswers{\csuse{mc at totalNumberOfAnswersQ\q}}
   \numdef\@numberofswaps{\csuse{mc at totalNumberOfAnswersQ\q}-1}   
   \foreach \v in {1,...,\mc at totalNumberOfVersions}{  
     \foreach \x in {1,...,\@numberofswaps}{
-      \pgfmathrandominteger{\r}{\x}{\csuse{mc at totalNumberOfAnswersQ\q}}
+      \pgfmathrandominteger{\r}{\x}{\@numberofpermuteanswers}
       \letcs\@temp{mc at answerTempnum\x}   
       \global\csletcs{mc at answerTempnum\x}{mc at answerTempnum\r}
       \global\cslet{mc at answerTempnum\r}{\@temp}
@@ -1137,6 +1138,7 @@
   
 
 \def\mc at randomizeAnswers@userdefined{
+  \numdef\@numberofpermuteanswers{\csuse{mc at totalNumberOfUserPermutationsQ\q}}
   \numdef\@numberofswaps{\csuse{mc at totalNumberOfUserPermutationsQ\q}-1}
   \gdef\mc at cntr{0}  
   \renewcommand*{\do}[1]{
@@ -1147,7 +1149,7 @@
   \foreach \v in {1,...,\mc at totalNumberOfVersions}{
     \ifnumequal{\mc at cntr}{0}{
       \foreach \p in {1,...,\@numberofswaps}{
-        \pgfmathrandominteger{\r}{\p}{\csuse{mc at totalNumberOfUserPermutationsQ\q}}
+        \pgfmathrandominteger{\r}{\p}{\@numberofpermuteanswers}
         \letcs\@temp{mc at userPermutationQ\q P\p}
         \global\csletcs{mc at userPermutationQ\q P\p}{mc at userPermutationQ\q P\r}
         \global\cslet{mc at userPermutationQ\q P\r}{\@temp}



More information about the tex-live-commits mailing list.