001 /* PAVLOV -- Multiple Choice Study System 002 * Copyright (C) 2000 - 2004 T.J. Willis 003 * 004 * This program is free software; you can redistribute it and/or 005 * modify it under the terms of the GNU General Public License 006 * as published by the Free Software Foundation; either version 2 007 * of the License, or (at your option) any later version. 008 * 009 * This program is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 * GNU General Public License for more details. 013 * 014 * You should have received a copy of the GNU General Public License 015 * along with this program; if not, write to the Free Software 016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. 017 * 018 * $Header: /cvsroot/pavlov/net/sourceforge/pavlov/user/ChapterStatistics.java,v 1.5 2004/06/03 03:18:23 tj_willis Exp $ 019 */ 020 package net.sourceforge.pavlov.user; 021 022 import java.io.*; 023 import org.apache.log4j.*; 024 025 /** 026 * Statistics which describle all quizzes a user has taken in a given 027 * chapter. 028 * 029 * @author <a href="mailto:tj_willis@users.sourceforge.net"> T.J. Willis </a> 030 * @version 1.0 031 */ 032 public class ChapterStatistics 033 implements Serializable 034 { 035 // unit coverage in TestQuiz.java 036 /** 037 * Number of questions in the chapter. 038 * 039 */ 040 public int nQuestions; // # questions 041 /** 042 * Number of questions in the chapter that have been answered. 043 * 044 */ 045 public int nAnswered; // #questions answered at least once 046 /** 047 * Number of questions answered correctly at least once. 048 * 049 */ 050 public int nOnceRights; // #questions answered right at least once 051 /** 052 * Number of questions answered only wrong. 053 * 054 */ 055 public int nOnlyWrongs; // #questions answered, but never right 056 /** 057 * Total number of answers. 058 * 059 */ 060 public int totAnswers; // sum of each questions nrights+nwrongs 061 /** 062 * Total number of right answers. 063 * 064 */ 065 public int totRights; // sum of each question's nrights 066 067 /** 068 * Percentage of questions answered right at least once divided by number of questions in chapter. 069 * 070 */ 071 public double rightsVersusNumberOfQuestions; 072 /** 073 * Percentage of questions answered at least once, but with no correct answers divided by number of questions in the chapter. 074 * 075 */ 076 public double onlyWrongsVersusNumberOfQuestions; 077 /** 078 * Percentage of right answers. 079 * 080 */ 081 public double rightsVersusNumberOfAnswers; 082 /** 083 * Percentage of questions that have been answered. 084 * 085 */ 086 public double frequency; // nanswered vs. nquestions 087 088 //public long duration; time in mS from first question answered to now 089 /** 090 * Creates a new <code>ChapterStatistics</code> instance. 091 * 092 */ 093 public ChapterStatistics() { 094 nQuestions = 0; 095 nAnswered = 0; 096 097 nOnceRights = 0; 098 nOnlyWrongs = 0; 099 100 totRights = 0; 101 102 rightsVersusNumberOfQuestions = 0.0; 103 rightsVersusNumberOfAnswers = 0.0; 104 105 frequency = 0.0; 106 } 107 /** 108 * Creates a new <code>ChapterStatistics</code> instance. 109 * 110 * @param nQs Number of questions. 111 * @param totAs Total number of answers. 112 * @param nAns Number of questions answered at least once. 113 * @param c Number of questions answered correctly at least once. 114 * @param d Total number of correct answers. 115 * @param e Number of questions answered only incorrectly. 116 */ 117 public ChapterStatistics(int nQs, int totAs, int nAns, int c, int d, int e) { 118 nQuestions = nQs; // # questions 119 totAnswers = totAs; 120 nAnswered = nAns; 121 nOnceRights = c; //# of questions answered right at least onc 122 totRights = d; // sum of each question's nrights 123 nOnlyWrongs = e; 124 recalc(); 125 } 126 127 /** 128 * Number of right answers as percentage of number of total answers. 129 * 130 * @return a <code>double</code> value 131 */ 132 public double getPercentageOfRightAnswers() { 133 return (1.0 * totRights) / (1.0 * totAnswers); 134 } 135 136 /** 137 * Number of wrong answers as percentage of number of total answers. 138 * 139 * @return a <code>double</code> value 140 */ 141 public double getPercentageOfWrongAnswers() { 142 return (1.0 * (totAnswers - totRights)) / (1.0 * totAnswers); 143 } 144 145 /** 146 * Percentage of questions in the chapter that have been answered at least once. 147 * 148 * @return a <code>double</code> value 149 */ 150 public double getPercentOfQuestionsAnsweredAtLeastOnce() { 151 return (1.0 * nAnswered) / (1.0 * nQuestions); 152 } 153 154 /** 155 * Number of wrong answers over all quizzes for this user on this chapter. 156 * 157 * @return an <code>int</code> value 158 */ 159 public int getTotalNumberOfWrongAnswers() { 160 return totAnswers - totRights; 161 } 162 163 /** 164 * Percentage of questions that have been answered correctly at least once. 165 * 166 * @return a <code>double</code> value 167 */ 168 public double getPercentOfQuestionsAnsweredRightAtLeastOnce() { 169 return ((1.0 * nOnceRights) / (1.0 * nQuestions)); 170 } 171 172 /** 173 * Percentage of questions that have been answered at least once, but never correctly. 174 * 175 * @return a <code>double</code> value 176 */ 177 public double getPercentOfQuestionsOnlyAnsweredWrong() { 178 return ((1.0 * nOnlyWrongs) / (1.0 * nQuestions)); 179 } 180 181 /** 182 * Number of questions in the chapter that the user has never answered. 183 * 184 * @return an <code>int</code> value 185 */ 186 public int getNumberNeverAnswered() { 187 return nQuestions - nOnceRights - nOnlyWrongs; 188 } 189 190 /** 191 * Percentage of questions in the chapter that the user has never answered. 192 * 193 * @return a <code>double</code> value 194 */ 195 public double getPercentNeverAnswered() { 196 return (1.0 * getNumberNeverAnswered()) / (1.0 * nQuestions); 197 } 198 199 200 /** 201 * Recalculares derived statistics from basic statistics. 202 * 203 */ 204 public void recalc() { 205 frequency = (1.0) * nAnswered / (1.0) * nQuestions; 206 rightsVersusNumberOfAnswers = (1.0) * totRights / (1.0) * nAnswered; 207 rightsVersusNumberOfQuestions = (1.0) * nOnceRights / (1.0) * nQuestions; 208 onlyWrongsVersusNumberOfQuestions = (1.0) * nOnlyWrongs / (1.0) * nQuestions; 209 } 210 211 /** 212 * Uses a nifty trick from "Design Patterns in Java" to make a 213 * completely independent copy of this chapter. Useful in chapter 214 * editors. 215 * 216 * @return a <code>ChapterStatistics</code> value 217 */ 218 public ChapterStatistics deepCopy() 219 { 220 try { 221 ByteArrayOutputStream b = new ByteArrayOutputStream(); 222 ObjectOutputStream out = new ObjectOutputStream(b); 223 out.writeObject(this); 224 ByteArrayInputStream bIn = new ByteArrayInputStream(b.toByteArray()); 225 ObjectInputStream oi = new ObjectInputStream(bIn); 226 return ( (ChapterStatistics)oi.readObject()); 227 } catch (IOException e) { 228 System.out.println("exception: " + e); 229 return null; 230 } catch (ClassNotFoundException e1){ 231 System.out.println("exception: " + e1); 232 return null; 233 } 234 } 235 236 237 /** 238 * Call when the question has been answered correctly. 239 * 240 * @param q a <code>QuestionData</code> value 241 */ 242 public void addRight(QuestionData q) { 243 totAnswers++; // 4 dec 02 244 if (q.getRight() + q.getWrong() == 1) 245 nAnswered++; 246 247 if (q.getRight() == 1) { 248 nOnceRights++; 249 if(q.getWrong()>0) nOnlyWrongs--; // 26 jan 04 250 } 251 totRights++; 252 recalc(); 253 } 254 255 /** 256 * Call when the question has been answered incorrectly. 257 * 258 * @param q a <code>QuestionData</code> value 259 */ 260 public void addWrong(QuestionData q) { 261 totAnswers++; // 4 dec 02 262 if (q.getRight() + q.getWrong() == 1) 263 nAnswered++; 264 if ( (q.getRight() < 1) && (q.getWrong() ==1) ) { 265 nOnlyWrongs++; 266 } 267 recalc(); 268 } 269 270 // will break if you add qd for the same question multiple times 271 /** 272 * Add a question to the ChapterStatistics. Only add a question once! 273 * 274 * @param qd a <code>QuestionData</code> value 275 */ 276 public void addQuestionData(QuestionData qd) { 277 nQuestions++; 278 if (qd.getRight() + qd.getWrong() > 0)nAnswered++; 279 if (qd.getRight() > 0) nOnceRights++; 280 else if (qd.getWrong() > 0)nOnlyWrongs++; 281 totAnswers += qd.getRight() + qd.getWrong(); 282 totRights += qd.getRight(); 283 } 284 285 }