Jump to content

Recommended Posts

I have an application which pulls in data (questions) via XML and randomizes them. Right now if there is 50 questions in the XML file, 50 questions are displayed and randomized in the application. I am trying to figure out how to limit the randomizing and chooses from a larger pool so that only 35 questions display(even when the XML file has 50 questions) or something like that. My current code which brings in the file and randomizes is below.

 

package  exam {
    import flash.net.* //to create URLRequest and load XML  file
    import flash.events.* //for Load events
    //import  flash.display.* //for testing purposes - remove when testing complete
     
    //This class downloads the XML document, and then inserts info  into arrays and variables.
    //Also provides text of questions and  correct answers when requested.
    internal class XaMLDiplomat  extends EventDispatcher {
        //VARIABLES:
        //for  loaded XML doc
        private var myXML:XML;
        //for  loading in XML
        private var examLoader:URLLoader;
         private var numQstns:Number; //count of total questions in a section
         private var sectStart:Number;
        //contains exam questions -  ALL ARRAYS ARE ZERO RELATIVE -> actual question numbers = array index  + 1
        private var questions:Array;
        //contain  associated answer choices
        private var choiceA:Array;
         private var choiceB:Array;
        private var choiceC:Array;
         private var choiceD:Array;
        private var choiceE:Array;
         private var choiceF:Array;
        //array of the correct answers
         private var answers:Array;
        //use custom Mixer class to  randomize order
        private var myMixer:Mixer;
        
         //CONSTRUCTOR
        public function XaMLDiplomat () { //NEED TO  ADD ARGUMENTS (docLocation)
            //create URLRequest from  argument
            var examSite:URLRequest = new  URLRequest("protected/Questions.xml");
            //create a loader  for the XML
            examLoader = new URLLoader();
             //add listener for load completion
             examLoader.addEventListener(Event.COMPLETE, fullyLoaded);
             examLoader.load(examSite);
            //var ugly:Mixer = new  Mixer(25);
        }
        
        //Load listener - creates  XML object, and checks it for multiple sections. If multiple, it asks  users 
        //which section they want - FIRST it needs to check  database for any completed sections. 
        //If single, it goes  ahead and starts array creation for first (& only) section
         private function fullyLoaded (e:Event):void {
            myXML =  new XML(examLoader.data);
            //myXML.prettyPrinting = false;
             //still need to pull out SYSTEM data and pass it along...
             var system:XMLList = myXML..SYSTEM;
            var sysObj:Object =  new Object();
            sysObj.examTitle = system.TITLE.toString();
             sysObj.totalMin = system.MINUTES.toString();
             sysObj.retakePW = system.RETAKEPW.toString();
            var  numSections:Number = myXML..SECTION.length();
            if  (numSections == 1) {
                generateArrays(1);
             }
            dispatchEvent(new  MultiSectEvent(MultiSectEvent.SECTIONS, numSections, sysObj));
         }
        
        //Assigns arrays to instance variables for the  selected section
        internal function generateArrays  (sectn:Number):void {
            var whichSection:XMLList =  myXML..SECTION.(@id == String(sectn));
            var  probList:XMLList = whichSection.PROBLEM;
            numQstns =  probList.length();
            sectStart = Number(probList[0].@id);
             
            questions = new Array();
            choiceA = new  Array();
            choiceB = new Array();
            choiceC =  new Array();
            choiceD = new Array();
             choiceE = new Array();
            choiceF = new Array();
             answers = new Array();
            for (var i:Number=0;  i<numQstns; i++) {
                var curProb:XMLList =  probList.(@id == String(i+1));
                if  (curProb.QUESTION.hasSimpleContent()) {
                     questions[i] = curProb.QUESTION.toString();
                }else {
                     //trace(curProb.QUESTION.toXMLString());
                     questions[i] = dropTags(curProb.QUESTION[0]);
                }
                 choiceA[i] = curProb.CHOICE.(@letter == "a").toString();
                 choiceB[i] = curProb.CHOICE.(@letter == "b").toString();
                 choiceC[i] = curProb.CHOICE.(@letter == "c").toString();
                 choiceD[i] = curProb.CHOICE.(@letter == "d").toString();
                 choiceE[i] = curProb.CHOICE.(@letter == "e").toString();
                 choiceF[i] = curProb.CHOICE.(@letter == "f").toString();
                 answers[i] = curProb.CHOICE.(hasOwnProperty("@correct") &&  @correct == "true").@letter.toString();
            }
             myMixer = new Mixer(numQstns);//mixer commented out
            /*
             trace("Question: "+questions[3]);
            trace("a:  "+choiceA[3]);
            trace("b: "+choiceB[3]);
             trace("c: "+choiceC[3]);
            trace("d: "+choiceD[3]);
             trace("\r\n answer: "+answers[3]); */
        }
        
         //method for external classes to acquire text of current exam question
         internal function getQuestion (qnum:Number):Object {
            var  returnObj:Object = new Object();
            var randomQ:Number =  myMixer.getRandomNumber(qnum-1);
            returnObj.q =  questions[randomQ];
            returnObj.ca = choiceA[randomQ];
             returnObj.cb = choiceB[randomQ];
            returnObj.cc =  choiceC[randomQ];
            returnObj.cd = choiceD[randomQ];
             returnObj.ce = choiceE[randomQ];
            returnObj.cf =  choiceF[randomQ];
            returnObj.num = qnum;
             //trace(randomQ);
            return returnObj;
        }
         
        private function dropTags (txt:XML):String {
             
            var txtString:String = "";
            for each (var  child:XML in txt.*) {
                if (child.nodeKind == "text") {
                     txtString += child.toString();
                }else {
                     txtString += " " + child.toXMLString();
                }
             }
            //trace(txtString);
            return txtString;
         }
        /*
        private function dropTags  (txt:String):String {
            var sliceStart:Number =  txt.indexOf(">");
            var sliceStop:Number =  txt.lastIndexOf("<");
            return txt.slice((sliceStart+1),  sliceStop);
        }*/
        
        internal function  getAnswer (num:Number):String {
            return answers[num];
         }
        
        internal function getQCount ():Number {
             return numQstns;
        }
        
        internal function  getSectStart():Number {
            return sectStart;
        }
         
        internal function getRealNum (num:Number):Number {
             return myMixer.getRandomNumber(num-1);
        }
    }
}

 

package exam {
    
    //This is a very simple object that creates the random order in which exam questions are presented
    internal class Mixer {
        
        //retains the array that is consulted for random question numbers
        private var randomizedOrder:Array;
        
        //CONSTRUCTOR - passed total number of questions in section
        public function Mixer (questnsTotal:Number) {
            randomizedOrder = new Array();
            randomizedOrder[0] = Math.floor(Math.random()*questnsTotal);
            
            for (var i:Number=1; i<questnsTotal; i++) {
                randomizedOrder[i] = newNumber(questnsTotal, i);
            }
            /*
            for (var k:Number=0; k<questnsTotal; k++) {
                trace(""+k+": "+randomizedOrder[k]);
            }*/
        }
        
        //recursive function that creates a new number until it creates one that isn't already in use
        private function newNumber (qTotal:Number, curNum:Number):Number {
            var newNum:Number = Math.floor(Math.random()*qTotal);
            
            for (var j:Number=0; j<curNum; j++) {
                if (randomizedOrder[j] == newNum) {
                    return newNumber(qTotal, curNum);
                }
            }
            return newNum;
        }
        
        //This is how external classes acquire a random number from this class's array
        //(programNum = the question the program wants to ask next, based on sequential order, or user selection)
        internal function getRandomNumber(programNum:Number):Number {
            return randomizedOrder[programNum];
        }
    }
}

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.