1

i have an array that holds student answers for given questions.

if a student gives an answer, it gets inserted into the array at the current index like answers[questionindex] = answer

later, i can read the array and map the entries to the given question-array

this case:

[
"answer",
undefined, // student has not given answer
"answer2",
]

works. (looping over the array, simply outputting "no answer given" if (answers[questionindex] === undefined)

but it doesn't work when the LAST answers were undefined (1 or more) they just don't exist (of course).

how can i set those fields to undefined (like, after a timer reaches zero), to show that there was no answer given?

right now, the average-calculation shows 100% correct for 3 given (correctly), then 2 not given at all

code

var testResults = {

    addRoom: function(Id, teacher) {  // room pseudoconstructor

        this[Id] = {


            created: moment(),

            runningProblem: false,

            time: 0, // holds the countdown for the current problem

            getTime: function() { // returns the countdown-counter
                return this.time;
            },

            Id: Id,

            teacher: teacher,

            getCurrentSolution: function() {
                return math.eval(this.testProblems[this.getCurrentProblemIndex()].problem);
            },

            getTimeTaken: function() {
                return this.getCurrentProblemTimeLimit() - this.time;
            },

            getCurrentProblemTimeLimit: function() {
                return this.testProblems[this.getCurrentProblemIndex()].timeLimit;
            },

            getCurrentProblemIndex: function() {
                return this.testProblems.length - 1;
            },

            addTestProblem: function(problem, timeLimit) {
                var solution = math.eval(problem);

                this.testProblems.push({problem: problem, timeLimit: timeLimit, solution: solution});
                console.dir(this.testProblems);
            },

            testProblems: [],

            updatePercentages: function(name) {

                function round(num) {
                    return +(Math.round(num + "e+2")  + "e-2");
                }

                console.log('updating percentages');
                console.log('answers length ' + this.students[name].givenAnswers.length);
                var timeSum = 0;
                for(var i = 0; i < this.students[name].givenAnswers.length; i++ ) {
                    timeSum += this.students[name].givenAnswers[i].takenTime;
                }
                var timeAvg = timeSum / this.students[name].givenAnswers.length;

                console.log('timeAvg for ' + name + ' ' + timeAvg);
                this.students[name].avgTime = round(timeAvg);

                var correctSum = 0;
                for(var j = 0; j < this.students[name].givenAnswers.length; j++ ) {
                    if (this.students[name].givenAnswers[j].correct) {
                        correctSum++;
                    }
                }
                var correctAvg = correctSum / this.students[name].givenAnswers.length;


                console.log('correctAvg for ' + name + ' ' + correctAvg);
                this.students[name].avgCorrect = round(correctAvg) * 100;
            },

            addGivenStudentAnswer: function(name, answer, takenTime, index) {

                console.log('adding answer ' + name + ' ' +answer+ ' ' + takenTime);

                var correct = this.getCurrentSolution() == answer;

                if (typeof this.students[name].givenAnswers[index] === 'undefined') {
                    this.students[name].givenAnswers[index] = ({
                        answer: answer,
                        takenTime: takenTime,
                        correct: correct
                    });
                    this.updatePercentages(name);
                    //console.dir(this.students[name].givenAnswers);
                    return true;

                } else {
                    console.log('attempt at double answer. not saved');
                    return false;
                }
            },

            addStudent: function(name) {
                if (!(this.students[name])) {
                    this.students[name] = {
                        studentName : name,
                        avgTime: 0,
                        avgCorrect: 0,
                        givenAnswers: []
                    }
                }
                console.dir(this);
            },
            students: {}
        };

        console.dir(this);

    },

    deleteRoom: function(Id) {
        delete this[Id];
        console.log('room deleted from testResults');
    }
};

// after test

var name = socket.userName;
        var room = socket.room;
        var created = testResults[room].created;
        var students = testResults[room].students;
        var problems = testResults[room].testProblems;

var test = new tests({
                roomId      : room,
                created     : created,
                teacher     : name,
                students    : students,
                problems    : problems
            });

            test.save(function(err, result) {
                if (err) {console.log(err);}
                else {
                    console.log('test saved to DB');
                    socket.emit('testSaved');
                    // delete from roomList
                    testRooms.deleteRoom(room, name);
                    // delete from resultObject
                    testResults.deleteRoom(room);
                    // answer
                    io.in(room).emit('room Closed');
                }
            });

route for reading a test from DB afterwars

router.get('/showtests/:roomId', function(req, res) {
    if (req.user && req.user.role === 'teacher') {
        tests.findOne({roomId: req.params.roomId}, {}, function(err, result) {
            if (err) {console.log(err);}
            res.render('showSingleTest', {user: req.user, testData: JSON.parse(JSON.stringify(result))});
        })
    } else {
        res.render('customerror', { title: "Error", errMsg1: "error.error", errMsg2: "error.notLoggedIn" });
    }
});

aaaaaand the jade

h2(data-i18n="markup.studentsAnswers")
each student in testData.students
    .testViewSingleStudentAnswers.col-md-6
        h3 #{student.studentName}

        ol.answers
            each answer in student.givenAnswers
                if (answer)
                    if (answer.correct == true)
                        li.correct
                            span #{answer.answer}
                            | &nbsp;&nbsp;&nbsp;
                            span.floatRight (#{answer.takenTime}s)
                    else
                        li.wrong
                            span #{answer.answer}
                            | &nbsp;&nbsp;&nbsp;
                            span.floatRight (#{answer.takenTime}s)
                else
                    li.noAnswer(data-i18n="markup.noAnswerGiven")
        .testTotals
            | #{student.avgCorrect}
            span(data-i18n="markup.percentCorrect")
            | ,&nbsp;
            | #{student.avgTime}
            span(data-i18n="markup.avgTime")
7
  • Don't you know the total amount of questions? Couldn't you simply fill out answers initially with all NULL values? Commented Feb 4, 2016 at 15:00
  • 1
    Please provide your code here. Commented Feb 4, 2016 at 15:01
  • use a dictionary and just iterate over the keys Commented Feb 4, 2016 at 15:01
  • no, it's totally dynamic. the teacher can add any number of questions, one at a atime Commented Feb 4, 2016 at 15:01
  • You need to provide more code about everything you're doing with these answers and questions. You know on a given page how many questions there are beforehand, correct? There's just too many "architecture" questions to give you a proper answer. Most likely there are several things you're doing that can be done better. Commented Feb 4, 2016 at 15:04

3 Answers 3

2

You can do like so:

function push_answer(answer){
answer = answer || "undefined"
array_of_answers.push(answer)
}

Now, the value is not undefined, but it's defined by the literal. You can replace it with some unicode character in case some answer can be "undefined".

Have a nice day!

Sign up to request clarification or add additional context in comments.

Comments

0

Seems to be working without issue for me.

HTML:

<div id="content">

</div>   

JS:

var answers = ["answer1","answer2",undefined,"answer3",undefined];

for(i=0;i<answers.length;i++) {
  if(!answers[i]){
    answers[i]="no answer";
  }
}
document.getElementById('content').innerHTML = answers;

jsFiddle

1 Comment

would this work? pastebin.com/skbUpKFv webstorm shows an error that "testProblems" is unresolved, even though it definitely exists. how can i access it? (all previous uses seem to work, only the innermost call gets underlined)
0

My personal recomendation: "Never leave things to chance"

if the student doesn't choose an answer, you should fill that blank space with a '', because undefined is really annoying to handle, so in order to fill the gaps:

This will check if answer is "undefined" and fill the gap with a '' (blank), then, when you check that answer, is going to be more simple to evaluate...

if(answer)
   answers[questionindex] = answer;
else
   answers[questionindex] = '';

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.