Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
[feature] Toggle between semi-/fully random subtasklet compilation.
Browse files Browse the repository at this point in the history
The random seed is configurable (system settings). When a fixed random
seed gets configured, all students get the same questions/answers, but
not necessarily in the same order.
  • Loading branch information
smee committed Oct 22, 2010
1 parent efebc51 commit 1ea6675
Show file tree
Hide file tree
Showing 20 changed files with 442 additions and 359 deletions.
Expand Up @@ -29,6 +29,7 @@
import org.apache.struts.action.ActionMapping;

import de.thorstenberger.examServer.model.User;
import de.thorstenberger.examServer.service.ConfigManager;
import de.thorstenberger.examServer.service.UserManager;
import de.thorstenberger.examServer.util.DateUtil;
import de.thorstenberger.examServer.webapp.vo.ComplexTaskInfoVO;
Expand Down Expand Up @@ -122,7 +123,8 @@ public ActionForward execute(
TaskModelViewDelegateObject delegateObject = new TaskModelViewDelegateObjectImpl( taskId,
tm,
login, user.getFirstName() + " " + user.getLastName(),
response.encodeURL(createReturnUrl(request, taskId)));
response.encodeURL(createReturnUrl(request, taskId)),
((ConfigManager) getBean("configManager")).getRandomSeed());



Expand All @@ -140,7 +142,7 @@ public ActionForward execute(

/**
* Create an absolute url that should be used as return url.
*
*
* @param request
* @param taskId
* @return
Expand Down
Expand Up @@ -46,11 +46,11 @@
import de.thorstenberger.taskmodel.complex.complextaskdef.Block;
import de.thorstenberger.taskmodel.complex.complextaskdef.ComplexTaskDefRoot;
import de.thorstenberger.taskmodel.complex.complextaskhandling.CorrectionSubmitData;
import de.thorstenberger.taskmodel.complex.complextaskhandling.subtasklets.impl.AbstractAddonSubTasklet;
import de.thorstenberger.taskmodel.complex.complextaskhandling.SubmitData;
import de.thorstenberger.taskmodel.complex.complextaskhandling.subtasklets.impl.AbstractAddonSubTasklet;
import de.thorstenberger.taskmodel.complex.jaxb.AddonSubTaskDef;
import de.thorstenberger.taskmodel.complex.jaxb.SubTaskDefType;
import de.thorstenberger.taskmodel.complex.jaxb.ComplexTaskHandlingType.TryType.PageType.AddonSubTask;
import de.thorstenberger.taskmodel.complex.jaxb.SubTaskDefType;

/**
* @author Steffen Dienst
Expand Down Expand Up @@ -172,20 +172,23 @@ public SubTasklet_AutotoolImpl( ComplexTaskDefRoot root, Block block, SubTaskDef
this.autotoolSubTask = new AutotoolSubTaskDummy(atSubTask);
}

public String getProblem(){
@Override
public String getProblem(){
return autotoolSubTask.getProblem();
}

public String getAnswer(){
String answer=autotoolSubTask.getAnswer();
if(answer==null)
answer=autotoolSubTask.getDefaultAnswer();
if(answer==null) {
answer=autotoolSubTask.getDefaultAnswer();
}
return answer;
}
public String getLastCorrectedAnswer(){
String answer=autotoolSubTask.getLastCorrectedAnswer();
if(answer==null)
answer=getAnswer();
if(answer==null) {
answer=getAnswer();
}
return answer;
}

Expand All @@ -198,7 +201,7 @@ public void doAutoCorrection(){
try {
AutotoolTaskInstance ati=new AutotoolTaskInstance.AutotoolTaskInstanceVO(autotoolTaskConfig.getTaskType(),(Map) deserialize(autotoolSubTask.getAutotoolInstanceBlob()));
AutotoolGrade grade=getAutotoolServices().gradeTaskInstance(ati,getAnswer());
setCorrection((float) (grade.isSolved()?block.getPointsPerSubTask():0), grade.getGradeDocumentation(), true);//TODO autotools laenge der loesung speichern?
setCorrection((grade.isSolved()?block.getPointsPerSubTask():0), grade.getGradeDocumentation(), true);//TODO autotools laenge der loesung speichern?
autotoolSubTask.setAutotoolScore(grade.getPoints());
autotoolSubTask.setLastCorrectedAnswer(getAnswer());
} catch (Exception e) {//TODO bloed
Expand All @@ -213,10 +216,12 @@ public void doManualCorrection( CorrectionSubmitData csd ){
}

protected void setCorrection( float points, String doc, boolean auto ){
if(auto)
super.setAutoCorrection(points);
else
;//TODO
if(auto) {
super.setAutoCorrection(points);
}
else {
;//TODO
}
autotoolSubTask.setAutotoolDoc(doc);
}

Expand All @@ -231,10 +236,10 @@ public boolean isProcessed(){
* (non-Javadoc)
* @see de.thorstenberger.taskmodel.complex.complextaskhandling.SubTasklet#build()
*/
public void build() throws TaskApiException {
public void build(long randomSeed) throws TaskApiException {
SignedAutotoolTaskConfig satc=new SignedAutotoolTaskConfig.SignedAutotoolTaskConfigVO(this.autotoolTaskConfig.getTaskType(),autotoolTaskConfig.getConfigString(),"",autotoolTaskConfig.getSignature());
try {
AutotoolTaskInstance task=getAutotoolServices().getTaskInstance(satc,RandomUtil.getInt(1000000));
AutotoolTaskInstance task = getAutotoolServices().getTaskInstance(satc, new RandomUtil(randomSeed).getInt(1000000));
autotoolSubTask.setProblem(task.getProblem());
autotoolSubTask.setDefaultAnswer(task.getDefaultAnswer());
autotoolSubTask.setAnswerDoc(task.getAnswerDoc());
Expand Down Expand Up @@ -273,8 +278,9 @@ private Object deserialize(byte[] arr) {
}

private AutotoolServices getAutotoolServices() throws IOException {
if(ats == null)
ats=new AutotoolServices(new URL(autotoolTaskConfig.getAutotoolServerUrl()));
if(ats == null) {
ats=new AutotoolServices(new URL(autotoolTaskConfig.getAutotoolServerUrl()));
}
return ats;
}

Expand All @@ -299,8 +305,9 @@ public int getHash(){
private Element getElement(Element memento, String string) {
Element e=null;
NodeList nl=memento.getElementsByTagName(string);
if(nl.getLength()>0)
e=(Element) nl.item(0);
if(nl.getLength()>0) {
e=(Element) nl.item(0);
}
return e;
}

Expand Down Expand Up @@ -344,7 +351,8 @@ public String getAddOnType() {
return ((AddonSubTaskDef)this.jaxbSubTaskDef).getTaskType();
}

public boolean isInteractiveFeedback() {
@Override
public boolean isInteractiveFeedback() {
return this.autotoolTaskConfig.isInteractive();
}

Expand Down
Expand Up @@ -36,9 +36,9 @@
import de.thorstenberger.taskmodel.complex.complextaskhandling.SubmitData;
import de.thorstenberger.taskmodel.complex.complextaskhandling.subtasklets.impl.AbstractAddonSubTasklet;
import de.thorstenberger.taskmodel.complex.jaxb.AddonSubTaskDef;
import de.thorstenberger.taskmodel.complex.jaxb.ComplexTaskHandlingType.TryType.PageType.AddonSubTask;
import de.thorstenberger.taskmodel.complex.jaxb.SubTaskDefType;
import de.thorstenberger.taskmodel.complex.jaxb.SubTaskType;
import de.thorstenberger.taskmodel.complex.jaxb.ComplexTaskHandlingType.TryType.PageType.AddonSubTask;

public class JUnitSubTaskletImpl extends AbstractAddonSubTasklet implements SubTasklet_JUnit{
private class JUnitSubtaskDummy{
Expand Down Expand Up @@ -125,16 +125,20 @@ public void doSave(SubmitData submitData) throws IllegalStateException {

public void doAutoCorrection() {
JUnitTestResult result=taskCorrector.runUnitTest( justdd.getInterfaceClassDef(), this.getClassDef(), justdd.getTestClassDef(), justdd.getTimeout() );
if(result != null)
setCorrection(result.isCorrect()?block.getPointsPerSubTask():0,result.getResult(),true);
else
;//TODO needs manual correction
if(result != null) {
setCorrection(result.isCorrect()?block.getPointsPerSubTask():0,result.getResult(),true);
}
else {
;//TODO needs manual correction
}
}
protected void setCorrection( float points, String result, boolean auto ){
if(auto)
super.setAutoCorrection(points);
else
;//TODO
if(auto) {
super.setAutoCorrection(points);
}
else {
;//TODO
}
justd.setTestResult(result);
}

Expand All @@ -156,10 +160,11 @@ public boolean isProcessed() {
return justd.getClassDef()!=null && justd.getClassDef().length()>0 && !justd.getClassDef().equals(justdd.getDefaultClassDef());
}

public void build() throws TaskApiException {
public void build(long randomSeed) throws TaskApiException {
//TODO
}
public String getProblem() {
@Override
public String getProblem() {
return justdd.getProblem();
}
public String getAddOnType() {
Expand All @@ -168,12 +173,14 @@ public String getAddOnType() {

public String getClassDef() {
String cd=justd.getClassDef();
if(cd==null)
cd=justdd.getDefaultClassDef();
if(cd==null) {
cd=justdd.getDefaultClassDef();
}
return cd;
}

public boolean isInteractiveFeedback() {
@Override
public boolean isInteractiveFeedback() {
return justdd.isInteractiveFeedback();
}

Expand All @@ -182,8 +189,9 @@ public boolean isInteractiveFeedback() {
private Element getElement(Element memento, String string) {
Element e=null;
NodeList nl=memento.getElementsByTagName(string);
if(nl.getLength()>0)
e=(Element) nl.item(0);
if(nl.getLength()>0) {
e=(Element) nl.item(0);
}
return e;
}

Expand Down
Expand Up @@ -17,26 +17,28 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
*
*
*/
package de.thorstenberger.taskmodel;


/**
*
*
* This interface has the intent of delegating information about the execution of a task
* to the view.
*
*
* @author Thorsten Berger
*
*/
public interface TaskModelViewDelegateObject extends DelegateObject {

public String getLogin();

public String getUserName();

public Tasklet getTasklet() throws TaskApiException;


public long getRandomSeed();


}
Expand Up @@ -41,7 +41,14 @@ public interface ComplexTasklet extends Tasklet {

public boolean canStartNewTry();

public void startNewTry( int tryNo ) throws IllegalStateException;
/**
* Generate a new try. Uses randomSeed to ensure repeatability of the generation process if needed.
*
* @param tryNo
* @param randomSeed
* @throws IllegalStateException
*/
public void startNewTry(int tryNo, long randomSeed) throws IllegalStateException;

public boolean canContinueTry();

Expand All @@ -53,7 +60,7 @@ public interface ComplexTasklet extends Tasklet {
* @param pageNo
* @param submitData
* @param hashcode
* @throws IllegalStateException if the hashcode doesn't match of the
* @throws IllegalStateException if the hashcode doesn't match of the
*/
public void savePage( int pageNo, List<SubmitData> submitData, long hashcode ) throws IllegalStateException;

Expand All @@ -75,7 +82,7 @@ public interface ComplexTasklet extends Tasklet {
public Try getActiveTry() throws IllegalStateException;

/**
* Gibt den letzten (nicht unbedingt aktiven) Versuch zur Korrektur und Einsichtnahme zurück.
* Gibt den letzten (nicht unbedingt aktiven) Versuch zur Korrektur und Einsichtnahme zur�ck.
* TODO: rename method, the term "solution" is misleading in this case
* @return
*/
Expand Down
Expand Up @@ -126,19 +126,21 @@ public interface SubTasklet {
*/
public String getCorrectionHint();

/**
* Called when the SubTasklet is initially created.
* SubTasklet should e.g. create random answers, assignments, texts etc
*
*/
public void build() throws TaskApiException;
/**
* Called when the SubTasklet is initially created. SubTasklet should e.g. create random answers, assignments, texts
* etc
*
* @param randomSeed
* seed to use for any randomly generated values
*/
public void build(long randomSeed) throws TaskApiException;

/**
* Called on SubTasklet creation, but should initialize it for previewing purposes only, i.e.
* to preview the SubTasklet in the editor. Usually, this should just forward to {@link #build()}.
* In the case of a SubTasklet_MC, it'd make sense to append all answers in order to preview the
* whole SubTasklet.
*
*
* @throws TaskApiException
*/
public void buildPreview() throws TaskApiException;
Expand Down
Expand Up @@ -135,7 +135,7 @@ public ActionForward execute(final ActionMapping mapping, final ActionForm form,

if ("new".equals(todo)) { // new try
int tryNo = Integer.parseInt(request.getParameter("try"));
ct.startNewTry(tryNo);
ct.startNewTry(tryNo, delegateObject.getRandomSeed());

log.info("Student starts new try.");
} else if ("continue".equals(todo)) { // continue try
Expand Down
Expand Up @@ -17,12 +17,10 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
*
*
*/
package de.thorstenberger.taskmodel.complex;

import java.util.List;

import de.thorstenberger.taskmodel.complex.complextaskdef.Block;
import de.thorstenberger.taskmodel.complex.complextaskdef.Category;
import de.thorstenberger.taskmodel.complex.complextaskdef.ComplexTaskDefRoot;
Expand All @@ -36,24 +34,25 @@
*
*/
public interface ComplexTaskBuilder {

public ComplexTaskFactory getComplexTaskFactory();

public List<SubTasklet> buildSubTaskletsFromCategory( Category category, ComplexTaskDefRoot complexTaskDefRoot );

/**
* Selection algorithm
*
* @param block
* @return
*/
public List<SubTasklet> buildSubTaskletsFromBlock( Block block, ComplexTaskDefRoot complexTaskDefRoot, String categoryId );
// public List<SubTasklet> buildSubTaskletsFromCategory( Category category, ComplexTaskDefRoot complexTaskDefRoot );

// /**
// * Selection algorithm
// *
// * @param block
// * @return
// */
// public List<SubTasklet> buildSubTaskletsFromBlock( Block block, ComplexTaskDefRoot complexTaskDefRoot, String
// categoryId );

/**
* Generates a complete new Try by using appropriate selection algorithms
* @param complexTaskDefRoot
* @return
*/
public Try generateTry( ComplexTaskDefRoot complexTaskDefRoot, long startTime );
public Try generateTry(ComplexTaskDefRoot complexTaskDefRoot, long startTime, long randomSeed);

}

0 comments on commit 1ea6675

Please sign in to comment.