Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

randomizing questions via XML

Explorer ,
Apr 13, 2010 Apr 13, 2010

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 pool so that only 35 questions display 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 = curProb.QUESTION.toString();
                }else {
                    //trace(curProb.QUESTION.toXMLString());
                    questions = dropTags(curProb.QUESTION[0]);
                }
                choiceA = curProb.CHOICE.(@letter == "a").toString();
                choiceB = curProb.CHOICE.(@letter == "b").toString();
                choiceC = curProb.CHOICE.(@letter == "c").toString();
                choiceD = curProb.CHOICE.(@letter == "d").toString();
                choiceE = curProb.CHOICE.(@letter == "e").toString();
                choiceF = curProb.CHOICE.(@letter == "f").toString();
                answers = 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);
        }
    }
}

TOPICS
ActionScript
2.6K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 13, 2010 Apr 13, 2010

call getQuestion() 35 times.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 13, 2010 Apr 13, 2010

would it be here?

internal function getQCount (35):Number {
            return numQstns;
        }

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 13, 2010 Apr 13, 2010

no.  it would be the bold function 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 = curProb.QUESTION.toString();
                }else {
                    //trace(curProb.QUESTION.toXMLString());
                    questions = dropTags(curProb.QUESTION[0]);
                }
                choiceA = curProb.CHOICE.(@letter == "a").toString();
                choiceB = curProb.CHOICE.(@letter == "b").toString();
                choiceC = curProb.CHOICE.(@letter == "c").toString();
                choiceD = curProb.CHOICE.(@letter == "d").toString();
                choiceE = curProb.CHOICE.(@letter == "e").toString();
                choiceF = curProb.CHOICE.(@letter == "f").toString();
                answers = 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);
        }
    }
}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 13, 2010 Apr 13, 2010

would I just need to add this to that function?

[as]

call getQuestion(35);

[/as]

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 13, 2010 Apr 13, 2010

you wouldn't add that code to the function.  you would add that code where you need to retrieve a question.  (thought it's not clear

myMixer.getRandomNumber() is randomizing without repeats.)

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 13, 2010 Apr 13, 2010

I don't want any repeats, just to randomly pick a number of questions out of the XML, so if there are fifty questions in the XML, display 35, but a different 35 each time(random). Would I still use Call?

is this where I need to change?

var randomQ:Number = myMixer.getRandomNumber(qnum-1);

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 13, 2010 Apr 13, 2010

i don't know if it's randomizing without repeats or not.  that part of the code isn't shown.

but, i suspect it's not.  to randomize without repeats the questions array should be randomized or "shuffled".  i've posted a shuffle function numerous times in these forums over the years.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 13, 2010 Apr 13, 2010

your right, the mixer code was in a different package. Here is that code.

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 = newNumber(questnsTotal, i);
            }
            /*
            for (var k:Number=0; k<questnsTotal; k++) {
                trace(""+k+": "+randomizedOrder);
            }*/
        }
       
        //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 == 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];
        }
    }
}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 13, 2010 Apr 13, 2010

that's poor coding but it's close to randomizing the questions without repeats IF it were called once.  but it's called repeatedly which isn't correct.

actually, the whole setup is a mess but you can continue to work with that using:


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;
   private var questionNum:Array=[];
       
        //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 = curProb.QUESTION.toString();
                }else {
                    //trace(curProb.QUESTION.toXMLString());
                    questions = dropTags(curProb.QUESTION[0]);
                }

questionNum.push(i);

                choiceA = curProb.CHOICE.(@letter == "a").toString();
                choiceB = curProb.CHOICE.(@letter == "b").toString();
                choiceC = curProb.CHOICE.(@letter == "c").toString();
                choiceD = curProb.CHOICE.(@letter == "d").toString();
                choiceE = curProb.CHOICE.(@letter == "e").toString();
                choiceF = curProb.CHOICE.(@letter == "f").toString();
                answers = curProb.CHOICE.(hasOwnProperty("@correct") && @correct == "true").@letter.toString();
            }

            questionNum=shuffle(questionNum)

        }

       

        //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 = questionNum(qnum);

            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 shuffle(a:Array) {
    var p:int;
    var t:*;
    var ivar:int;
    for (ivar = a.length-1; ivar>=0; ivar--) {
        p=Math.floor((ivar+1)*Math.random());
        t = a[ivar];
        a[ivar] = a

;
        a

= t;
    }
}       
        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);
        }
    }
}


Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 13, 2010 Apr 13, 2010

thanks, I will try ot out, and yes, the current code is a mess. So with the code you provided, do I still need to add the call to limit the display?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 13, 2010 Apr 13, 2010

you just call getQuestion() and pass the current question number (starting with 0,...,34) each time you want to retrieve a new question, choices and correct answer.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 13, 2010 Apr 13, 2010

other than what I have posted , this package brings in the question and answer display.

package exam {
   
    import flash.display.*;
    import flash.events.*;
    import flash.text.*;
   
    //This class displays the current question, and contains the Choices for the question
    public class QMachine extends Sprite {
        //VARIABLES
        private var QObject:Object; //object from XaMLDiplomat, containing necessary text
        private var limit:Number;
        private var QNumTxt:TextField;
        private var QTxt:TextField;
        private var sub:TextField;
        private var txtStyle:StyleSheet;
        private var choiceA:Choice;
        private var choiceB:Choice;
        private var choiceC:Choice;
        private var choiceD:Choice;
        private var choiceE:Choice;
        private var choiceF:Choice;
       
        //CONSTRUCTOR
        public function QMachine (hite:Number) {
            limit = hite;
            var style:Object = new Object();
            style.fontFamily = "Arial";
            //style.fontWeight = "bold";
            style.fontSize = "16";
            style.color = "#333333";
            txtStyle = new StyleSheet();
            txtStyle.setStyle("p",style);
           
           
            QNumTxt = new TextField();
            QNumTxt.styleSheet = txtStyle;
            //QNumTxt.embedFonts = true;
            QNumTxt.htmlText = "<p>1) </p>";
            QNumTxt.autoSize = TextFieldAutoSize.RIGHT;
            QNumTxt.x = 10;
           
            QNumTxt.mouseEnabled = false;
           
               
           
           
            QTxt = new TextField();
            QTxt.styleSheet = txtStyle;
            //QTxt.embedFonts = true;
            QTxt.width = 300;
            QTxt.multiline = true;
            QTxt.wordWrap = true;
            QTxt.autoSize = TextFieldAutoSize.LEFT;
            QTxt.htmlText = "<p>Question 1</p>";
            QTxt.x = 35;
           
            QTxt.mouseEnabled = false;
           
            addChild(QNumTxt);
            addChild(QTxt);
           
            choiceA = new Choice("a");
            choiceA.x = 350;
            addChild(choiceA);
           
            choiceB = new Choice("b");
            choiceB.x = 350;
            addChild(choiceB);
           
            choiceC = new Choice("c");
            choiceC.x = 350;
            addChild(choiceC);
           
            choiceD = new Choice("d");
            choiceD.x = 350;
            addChild(choiceD);
           
            choiceE = new Choice("e");
            choiceE.x = 350;
            addChild(choiceE);
           
            choiceF = new Choice("f");
            choiceF.x = 350;
            addChild(choiceF);
           
            addEventListener(MouseEvent.MOUSE_UP, selectResponse, true);
        }
       
        internal function newQuestion (obj:Object, prior:String = ""):void {
            //trace(obj.num);
            QNumTxt.htmlText = "<p>"+ obj.num + ".</p>";
            QTxt.htmlText = "<p>"+ obj.q + "</p>";
            choiceA.deselect();
            choiceB.deselect();
            choiceC.deselect();
            choiceD.deselect();
            choiceE.deselect();
            choiceF.deselect();
            choiceA.resetSize();
            choiceB.resetSize();
            choiceC.resetSize();
            choiceD.resetSize();
            choiceE.resetSize();
            choiceF.resetSize();
            choiceA.changeTxt(obj.ca);
            choiceB.changeTxt(obj.cb);
            choiceB.y = choiceA.height + 5;
            if (obj.cc == undefined || String(obj.cc) == "") {
                choiceC.visible = false;
            }else {
                choiceC.changeTxt(obj.cc);
                choiceC.y = choiceB.y + choiceB.height + 5;
                choiceC.visible = true;
            }
            if (obj.cd == undefined || String(obj.cd) == "") {
                choiceD.visible = false;
            }else {
                choiceD.changeTxt(obj.cd);
                choiceD.y = choiceC.y + choiceC.height + 5;
                choiceD.visible = true;
            }
            if (obj.ce == undefined || String(obj.ce) == "") {
                choiceE.visible = false;
            }else {
                choiceE.changeTxt(obj.ce);
                choiceE.y = choiceD.y + choiceD.height + 5;
                choiceE.visible = true;
            }
            if (obj.cf == undefined || String(obj.cf) == "") {
                choiceF.visible = false;
            }else {
                choiceF.changeTxt(obj.cf);
                choiceF.y = choiceE.y + choiceE.height + 5;
                choiceF.visible = true;
            }
           
            var curHite:Number;
            if (choiceF.visible) {
                curHite = choiceF.y + choiceF.height + 5;
            }else if (choiceE.visible) {
                curHite = choiceE.y + choiceE.height + 5;
            }else if (choiceD.visible) {
                curHite = choiceD.y + choiceD.height + 5;
            }else {
                curHite = choiceC.y + choiceC.height + 5;
            }
            if (curHite > (limit-150)) {
                shrinkText();
            }
           
            if (prior != "") {
                if (prior == "a") {
                    choiceA.nowSelected();
                }else if (prior == "b") {
                    choiceB.nowSelected();
                }else if (prior == "c") {
                    choiceC.nowSelected();
                }else if (prior == "d") {
                    choiceD.nowSelected();
                }else if (prior == "e") {
                    choiceE.nowSelected();
                }else if (prior == "f") {
                    choiceF.nowSelected();
                }
            }
        }
       
        private function shrinkText() {
            choiceA.dropSize();
            choiceB.dropSize();
            choiceC.dropSize();
            choiceD.dropSize();
            choiceE.dropSize();
            choiceF.dropSize();
           
            choiceB.y = choiceA.y + choiceA.height + 5;
            choiceC.y = choiceB.y + choiceB.height + 5;
            choiceD.y = choiceC.y + choiceC.height + 5;
            choiceE.y = choiceD.y + choiceD.height + 5;
            choiceF.y = choiceE.y + choiceE.height + 5;
           
            var curHite:Number = 0;
            if (choiceF.visible) {
                curHite = choiceF.y + choiceF.height + 5;
            }else if (choiceE.visible) {
                curHite = choiceE.y + choiceE.height + 5;
            }else if (choiceD.visible) {
                curHite = choiceD.y + choiceD.height + 5;
            }else {
                curHite = choiceC.y + choiceC.height + 5;
            }
            if (curHite > (limit-150)) {
                shrinkText();
            }
        }
       
        private function selectResponse (e:MouseEvent):void {
            choiceA.deselect();
            choiceB.deselect();
            choiceC.deselect();
            choiceD.deselect();
            choiceE.deselect();
            choiceF.deselect();
            var letter:String = e.target.parent.getLetter();
            dispatchEvent(new ResponseEvent(ResponseEvent.SELECTION, letter));
        }
       
        internal function setPriorResponse() {
            choiceA.deselect();
            choiceB.deselect();
            choiceC.deselect();
            choiceD.deselect();
            choiceE.deselect();
            choiceF.deselect();
        }
    }
}

is it within I need to call getQuestion()? Or within the package that displays the XML data?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 13, 2010 Apr 13, 2010

that's beyond my limit of lines of code to go through trying to figure out what you're doing.  you should be able to focus my attention on a handful of lines and direct a question about those lines.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 13, 2010 Apr 13, 2010

well this code is mostly formatting, hilighting and selecting text, I know that. I don't think this is where I need to place the code you mentioned, but still confused as to where that would be. This line is pulling in the text.

  private var QObject:Object; //object from XaMLDiplomat, containing  necessary text

and this part is choosing the questions to display.

internal function newQuestion (obj:Object, prior:String = ""):void {
             //trace(obj.num);
            QNumTxt.htmlText = "<p>"+  obj.num + ".</p>";
            QTxt.htmlText = "<p>"+  obj.q + "</p>";

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 13, 2010 Apr 13, 2010

there's some place where you decide it's time to present the first question and the choices.  then you evaluate the answer given by a user and sometime after that you present the next question.   when you want to present a question, you call getQuestion().  that returns the question and choices and correct answer.  where are you using all that?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 14, 2010 Apr 14, 2010

isn't that being done here?

//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 = questionNum(qnum);

            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;

        }

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 14, 2010 Apr 14, 2010

no.

it appears you don't understand that application, at all.   you'll need someone to download your file and make the changes you need.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 14, 2010 Apr 14, 2010

then it's right here. This is where the first question is being pulled in.

currentQ = 1;
                checkForDisable();
                myQMachine = new QMachine(mySkipper.y);
                myQMachine.newQuestion(myDiplomat.getQuestion(1));
                myQMachine.x = 11;
                myQMachine.y = 150;

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 14, 2010 Apr 14, 2010

myDiplomat is a class instance (of some class).   that class has a getQuestion() method.  presumably that's related to the getQuestion() method we've been discussing but it's not clear it's related, at all.  you'll have to check that class' method to see.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 14, 2010 Apr 14, 2010

the method for accessing the exam and beggining the process

if bringing in questions is here:

private function accessExam (e:UserEvent) {
            if(e.userID != 0 && e.logID != 0) {
               //put code here to have ResultsHandler pull from Shared Obj and send
               myRecords = new ResultsHandler(e.userID, e.logID);
               myRecords.findAndSend(e.userID, e.logID);
            }else {
                login.removeEventListener(UserEvent.LOGIN, accessExam);
                removeChild(login);
                removeChild(curtain);
               
                myDiplomat = new XaMLDiplomat();
                //must wait for XML to load and parse, then can create Mixer
                myDiplomat.addEventListener(MultiSectEvent.SECTIONS, sectionListener);

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
May 03, 2010 May 03, 2010
LATEST

Hi, I am still trying to get this working. Right now with the code I have, I am getting an error "1061: Call to a possibly undefined method questionNum through a reference with static type Function.".

the error is occurring here.

internal function getRealNum (num:Number):Number {
            return shuffle.questionNum(num-1);
        }

can anyone explain this error to me?

My full code is here:

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;
        private var questionNum: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/exam.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 = curProb.QUESTION.toString();
                }else {
                    //trace(curProb.QUESTION.toXMLString());
                    questions = dropTags(curProb.QUESTION[0]);
                }
                choiceA = curProb.CHOICE.(@letter == "a").toString();
                choiceB = curProb.CHOICE.(@letter == "b").toString();
                choiceC = curProb.CHOICE.(@letter == "c").toString();
                choiceD = curProb.CHOICE.(@letter == "d").toString();
                choiceE = curProb.CHOICE.(@letter == "e").toString();
                choiceF = curProb.CHOICE.(@letter == "f").toString();
                answers = curProb.CHOICE.(hasOwnProperty("@correct") && @correct == "true").@letter.toString();
            }
             questionNum=shuffle(questionNum)
        }
       
     
           
            //var questionslimit:Array = shuffle(questions,35);
       
        //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 = questionNum[qnum];
           
            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 = 35;
            //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 shuffle(a:Array) {
        var p:int;
        var t:*;
        var ivar:int;
        for (ivar = a.length-1; ivar>=0; ivar--) {
        p=Math.floor((ivar+1)*Math.random());
        t = a[ivar];
        a[ivar] = a

;
        a

= t;
    }

        /*
        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;
           
           
            //trace (numQstns);
        }
       
        internal function getSectStart():Number {
            return sectStart;
        }
       
        internal function getRealNum (num:Number):Number {
            return shuffle.questionNum(num-1);
        }
    }
}

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines