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/QuestionData.java,v 1.6 2004/07/01 09:03:44 tj_willis Exp $
019     */ 
020    package net.sourceforge.pavlov.user;
021    import java.util.*;
022    import org.apache.log4j.*;
023    
024    
025    /**
026     * Encapsulates correct and incorrect responses to a given question.
027     * @author <a href="mailto:tj_willis@users.sourceforge.net"> T.J. Willis </a>
028     * @version 1.0
029     */
030    public final class QuestionData {
031        /** This question's unique identifier */
032        private String id;
033        /** Vector of Dates of correct responses. */
034        private Vector<Date> rights;
035        /** Vector of Dates of incorrect responses. */
036        private Vector<Date> wrongs;
037        /**Total number of responses. */
038        private int total = 0;
039        /**Total number of correct responses. */
040        private  int right = 0;
041        /**Total number of incorrect responses. */
042        private  int wrong = 0;
043        /** Last time this question was asked */
044        private Date last;
045        private static int globalQDs =0;
046        private static final boolean DEBUG = false;
047    
048        /** Creates a QuestionData with id "NOID" */
049        public QuestionData() {
050            this("NOID");
051        }
052    
053        /**
054         * Creates a QuestionData with the given id
055         * @param id a <code>String</code> value
056         */
057        public QuestionData(final String id) {
058            if(DEBUG){
059                globalQDs++;
060                System.out.println("+Global # of question data: " + globalQDs);
061            }
062            this.id = id;
063            init();
064        }
065    
066        private void init(){
067            rights = new Vector<Date>();
068            wrongs = new Vector<Date>();
069            last = new Date(0);
070        }
071    
072        /**
073         * Return's this question's unique identifier
074         * @return a <code>String</code> value
075         */
076        public String getID() {
077            return id;
078        }
079        /**
080         * Sets this question's unique identifier
081         * @param _id a <code>String</code> value
082         */
083        public void setID(final String id) {
084            this.id = id;
085        }
086    
087        /**
088         * Adds a correct response for this question
089         * @param when a <code>Date</code> value
090         */
091        public void addRight(final Date when) {
092            rights.add(when);
093            right++;
094            total++;
095            if (last.before(when)){
096                    last = when;
097            }
098        }
099    
100        /**
101         * Adds an incorrect response for this question
102         * @param when a <code>Date</code> value
103         */
104        public void addWrong(final Date when) {
105            wrongs.add(when);
106            wrong++;
107            total++;
108            if (last.before(when)){
109                    last = when;
110            }
111        }
112    
113        /**
114         * When last asked.
115         * @return a <code>Date</code> value
116         */
117        public Date getLastAsked() {
118            return last;
119        }
120    
121        /** double from 0 to 100.0 of correct response percentage
122         * @deprecated use getPercentage()  instead.
123         */
124        @Deprecated public double percentage() {
125            return getPercentage();
126        }
127    
128    
129        /**
130         * Number of times asked.
131         * @return an <code>int</code> value
132         */
133        public int getNumAsked() {
134            return total;
135        }
136    
137    
138        /**
139         * True if this question has been asked.
140         * @return a <code>boolean</code> value
141         */
142        public boolean hasBeenAsked() {
143            if (total > 0) return true;
144            return false;
145        } 
146    
147        /**
148         * Percentage of correct answers, or -1 if no answers.
149         *
150         * @return a <code>double</code> value
151         */
152        public double getPercentage() {
153            if (total <= 0) return -1;
154            return ((1.0 * right) / (1.0 * total) * 100.0);
155        }
156    
157        /**
158         * Number of correct responses.
159         * @return an <code>int</code> value
160         */
161        public int getRight() {
162            return right;
163        }
164    
165        /**
166         * Number of incorrect responses.
167         * @return an <code>int</code> value
168         */
169        public int getWrong() {
170            return wrong;
171        }
172    
173        /**
174         * Number of total responses.
175         * @return an <code>int</code> value
176         */
177        public int getTotal() {
178            return total;
179        }
180    
181        /**
182         * Dumps this question in XML to the given writer.
183         * @param writer a <code>java.io.Writer</code> value
184         * @exception java.io.IOException if an error occurs
185         */
186        public void toXML(java.io.Writer writer)
187            throws java.io.IOException 
188        {
189            boolean multiline = (rights.size() + wrongs.size() > 0);
190    
191            if (!multiline){
192                return;  // don't output questions with no data
193            } else {
194                writer.write("\t\t\t<QUESTION SN=\"" + getID() + "\">");
195                    //if (multiline) 
196                writer.write("\n");
197                for(Date da : rights) {
198                    writer.write("\t\t\t\t<RIGHT DATE=\"" + da.getTime() + "\"></RIGHT>\n");
199                }
200                for(Date da : wrongs) {
201                    writer.write("\t\t\t\t<WRONG DATE=\"" + da.getTime() + "\"></WRONG>\n");
202                }
203                //if (multiline) 
204                writer.write("\t\t\t");
205                writer.write("</QUESTION>\n");
206            }
207        }
208    
209        protected void finalize() throws Throwable
210        {
211            if(DEBUG){
212                globalQDs--;
213                System.out.println("-Global # of question data: " + globalQDs);
214            }
215            super.finalize();
216        }
217    }
218