| 1 | package edu.ucsb.cs156.courses.models; | |
| 2 | ||
| 3 | import java.util.ArrayList; | |
| 4 | import java.util.List; | |
| 5 | import java.util.Objects; | |
| 6 | ||
| 7 | /** | |
| 8 | * Represents a UCSB quarter. Allows easy conversion between QYY alphanumeric | |
| 9 | * format (F19, W20, S20, M20) and YYYYQ numerical format (20194, 20201, 20202, | |
| 10 | * 20203) as well as incrementing and decrementing. | |
| 11 | * | |
| 12 | */ | |
| 13 | ||
| 14 | public class Quarter { | |
| 15 | ||
| 16 | private int yyyyq; // YYYYQ where Q = 1, 2, 3 or 4 | |
| 17 | ||
| 18 | public Quarter(int yyyyq) { | |
| 19 |
1
1. <init> : removed call to edu/ucsb/cs156/courses/models/Quarter::setValue → KILLED |
setValue(yyyyq); |
| 20 | } | |
| 21 | ||
| 22 | public int getValue() { | |
| 23 |
1
1. getValue : replaced int return with 0 for edu/ucsb/cs156/courses/models/Quarter::getValue → KILLED |
return this.yyyyq; |
| 24 | } | |
| 25 | ||
| 26 | public void setValue(int yyyyq) { | |
| 27 |
1
1. setValue : negated conditional → KILLED |
if (invalidQtr(yyyyq)) |
| 28 | throw new IllegalArgumentException("Quarter constructor requires a integer ending in 1,2,3 or 4"); | |
| 29 | this.yyyyq = yyyyq; | |
| 30 | } | |
| 31 | ||
| 32 | /** | |
| 33 | * Construct a Quarter object from a string s, either in QYY or YYYYQ format. If | |
| 34 | * s is of length three, QYY format is expected, if 5 then YYYYQ format is | |
| 35 | * expected. Otherwise an IllegalArgumentException is thrown. | |
| 36 | * | |
| 37 | * @param s Quarter either in QYY or YYYYQ format | |
| 38 | */ | |
| 39 | ||
| 40 | public Quarter(String s) { | |
| 41 | ||
| 42 | switch (s | |
| 43 | .length()) { | |
| 44 | case 3: | |
| 45 | this.yyyyq = qyyToyyyyQ(s); | |
| 46 | return; | |
| 47 | case 5: | |
| 48 | this.yyyyq = yyyyqToInt(s); | |
| 49 | return; | |
| 50 | default: | |
| 51 | throw new IllegalArgumentException("Quarter shoudl be in QYY or YYYYQ format"); | |
| 52 | } | |
| 53 | } | |
| 54 | ||
| 55 | public String getYY() { | |
| 56 |
1
1. getYY : replaced return value with "" for edu/ucsb/cs156/courses/models/Quarter::getYY → KILLED |
return getYY(this.yyyyq); |
| 57 | } | |
| 58 | ||
| 59 | public String getYYYY() { | |
| 60 |
1
1. getYYYY : replaced return value with "" for edu/ucsb/cs156/courses/models/Quarter::getYYYY → KILLED |
return getYYYY(this.yyyyq); |
| 61 | } | |
| 62 | ||
| 63 | public String getYYYYQ() { | |
| 64 |
1
1. getYYYYQ : replaced return value with "" for edu/ucsb/cs156/courses/models/Quarter::getYYYYQ → KILLED |
return String.format("%d",this.yyyyq); |
| 65 | } | |
| 66 | ||
| 67 | public String toString() { | |
| 68 |
1
1. toString : replaced return value with "" for edu/ucsb/cs156/courses/models/Quarter::toString → KILLED |
return yyyyqToQyy(this.yyyyq); |
| 69 | } | |
| 70 | ||
| 71 | public String getQ() { | |
| 72 |
1
1. getQ : replaced return value with "" for edu/ucsb/cs156/courses/models/Quarter::getQ → KILLED |
return getQ(this.yyyyq); |
| 73 | } | |
| 74 | ||
| 75 | private static boolean invalidQtr(int value) { | |
| 76 |
1
1. invalidQtr : Replaced integer modulus with multiplication → KILLED |
int index = value % 10; |
| 77 |
5
1. invalidQtr : changed conditional boundary → KILLED 2. invalidQtr : changed conditional boundary → KILLED 3. invalidQtr : negated conditional → KILLED 4. invalidQtr : negated conditional → KILLED 5. invalidQtr : replaced boolean return with true for edu/ucsb/cs156/courses/models/Quarter::invalidQtr → KILLED |
return (index < 1) || (index > 4); |
| 78 | } | |
| 79 | ||
| 80 | /** | |
| 81 | * Advance to the next quarter, and return the value of that quarter as an int. | |
| 82 | * | |
| 83 | * @return the new getValue() for the quarter, i.e. quarter as in in yyyyq | |
| 84 | * format | |
| 85 | */ | |
| 86 | public int increment() { | |
| 87 |
1
1. increment : Replaced integer modulus with multiplication → KILLED |
int q = this.yyyyq % 10; |
| 88 |
1
1. increment : Replaced integer division with multiplication → KILLED |
int yyyy = this.yyyyq / 10; |
| 89 | ||
| 90 |
6
1. increment : Replaced integer addition with subtraction → KILLED 2. increment : Replaced integer multiplication with division → KILLED 3. increment : Replaced integer addition with subtraction → KILLED 4. increment : Replaced integer addition with subtraction → KILLED 5. increment : negated conditional → KILLED 6. increment : removed call to edu/ucsb/cs156/courses/models/Quarter::setValue → KILLED |
setValue((q == 4) ? (((yyyy + 1) * 10) + 1) : (this.yyyyq + 1)); |
| 91 |
1
1. increment : replaced int return with 0 for edu/ucsb/cs156/courses/models/Quarter::increment → KILLED |
return this.yyyyq; |
| 92 | } | |
| 93 | ||
| 94 | /** | |
| 95 | * Subtract one from current quarter, and return the value of that quarter as an | |
| 96 | * int. | |
| 97 | * | |
| 98 | * @return the new getValue() for the quarter, i.e. quarter as in in yyyyq | |
| 99 | * format | |
| 100 | */ | |
| 101 | public int decrement() { | |
| 102 |
1
1. decrement : Replaced integer modulus with multiplication → KILLED |
int q = this.yyyyq % 10; |
| 103 |
1
1. decrement : Replaced integer division with multiplication → KILLED |
int yyyy = this.yyyyq / 10; |
| 104 | ||
| 105 |
6
1. decrement : Replaced integer subtraction with addition → KILLED 2. decrement : Replaced integer multiplication with division → KILLED 3. decrement : Replaced integer addition with subtraction → KILLED 4. decrement : Replaced integer subtraction with addition → KILLED 5. decrement : negated conditional → KILLED 6. decrement : removed call to edu/ucsb/cs156/courses/models/Quarter::setValue → KILLED |
setValue((q == 1) ? (((yyyy - 1) * 10) + 4) : (this.yyyyq - 1)); |
| 106 |
1
1. decrement : replaced int return with 0 for edu/ucsb/cs156/courses/models/Quarter::decrement → KILLED |
return this.yyyyq; |
| 107 | } | |
| 108 | ||
| 109 | /** | |
| 110 | * Convert yyyyq as string to int, throwing exception if format is incorrect | |
| 111 | * | |
| 112 | * @param yyyyq String in yyyyq format (e.g. 20194 for F19 (Fall 2019)) | |
| 113 | * @throws IllegalArgumentException | |
| 114 | * @return int representation of quarter | |
| 115 | */ | |
| 116 | public static int yyyyqToInt(String yyyyq) { | |
| 117 | String errorMsg = "Argument should be a string representation of a five digit integer yyyyq ending in 1,2,3 or 4"; | |
| 118 | int result = 0; | |
| 119 | try { | |
| 120 | result = Integer | |
| 121 | .parseInt(yyyyq); | |
| 122 | } catch (Exception e) { | |
| 123 | throw new IllegalArgumentException(errorMsg); | |
| 124 | } | |
| 125 |
1
1. yyyyqToInt : negated conditional → KILLED |
if (invalidQtr(result)) { |
| 126 | throw new IllegalArgumentException(errorMsg); | |
| 127 | } | |
| 128 |
1
1. yyyyqToInt : replaced int return with 0 for edu/ucsb/cs156/courses/models/Quarter::yyyyqToInt → KILLED |
return result; |
| 129 | } | |
| 130 | ||
| 131 | /** | |
| 132 | * Convert yyyyq int format to Yqq String format throwing exception if format is | |
| 133 | * incorrect | |
| 134 | * | |
| 135 | * @param yyyyq int (e.g. 20194 for Fall 2019 | |
| 136 | * @throws IllegalArgumentException | |
| 137 | * @return Qyy representation (e.g. F19) | |
| 138 | */ | |
| 139 | public static String yyyyqToQyy(int yyyyq) { | |
| 140 |
1
1. yyyyqToQyy : negated conditional → KILLED |
if (invalidQtr(yyyyq)) { |
| 141 | throw new IllegalArgumentException( | |
| 142 | "Argument should be a five digit integer in qqqqy format ending in 1,2,3 or 4"); | |
| 143 | } | |
| 144 |
1
1. yyyyqToQyy : replaced return value with "" for edu/ucsb/cs156/courses/models/Quarter::yyyyqToQyy → KILLED |
return String |
| 145 | .format("%s%s", getQ(yyyyq), getYY(yyyyq)); | |
| 146 | } | |
| 147 | ||
| 148 | /** | |
| 149 | * Take yyyyq int format and return single character for quarter, either "W", | |
| 150 | * "S", "M", or "F" for last digit 1, 2, 3, 4, respectively. Throw illegal | |
| 151 | * argument exception if not in yyyyq format. | |
| 152 | * | |
| 153 | * @param yyyyq int (e.g. 20194 for Fall 2019) | |
| 154 | * @throws IllegalArgumentException | |
| 155 | * @return single char string for quarter (e.g. "F") | |
| 156 | */ | |
| 157 | public static String getQ(int yyyyq) { | |
| 158 |
1
1. getQ : negated conditional → KILLED |
if (invalidQtr(yyyyq)) { |
| 159 | throw new IllegalArgumentException( | |
| 160 | "Argument should be a five digit integer in qqqqy format ending in 1,2,3 or 4"); | |
| 161 | } | |
| 162 | String[] quarters = new String[] { "W", "S", "M", "F" }; | |
| 163 |
1
1. getQ : Replaced integer modulus with multiplication → KILLED |
int index = yyyyq % 10; |
| 164 |
2
1. getQ : Replaced integer subtraction with addition → KILLED 2. getQ : replaced return value with "" for edu/ucsb/cs156/courses/models/Quarter::getQ → KILLED |
return quarters[index - 1]; |
| 165 | } | |
| 166 | ||
| 167 | /** | |
| 168 | * Take yyyyq int format and return two digit year as a String Throw illegal | |
| 169 | * argument exception if not in yyyyq format. | |
| 170 | * | |
| 171 | * @param yyyyq int (e.g. 20194 for Fall 2019) | |
| 172 | * @throws IllegalArgumentException | |
| 173 | * @return two char string for year (e.g. "19") | |
| 174 | */ | |
| 175 | public static String getYY(int yyyyq) { | |
| 176 |
1
1. getYY : negated conditional → KILLED |
if (invalidQtr(yyyyq)) { |
| 177 | throw new IllegalArgumentException( | |
| 178 | "Argument should be a five digit integer in qqqqy format ending in 1,2,3 or 4"); | |
| 179 | } | |
| 180 |
3
1. getYY : Replaced integer division with multiplication → KILLED 2. getYY : Replaced integer modulus with multiplication → KILLED 3. getYY : replaced return value with "" for edu/ucsb/cs156/courses/models/Quarter::getYY → KILLED |
return String |
| 181 | .format("%02d", (yyyyq / 10) % 100); | |
| 182 | } | |
| 183 | ||
| 184 | /** | |
| 185 | * Take yyyyq int format and return four digit year as a String Throw illegal | |
| 186 | * argument exception if not in yyyyq format. | |
| 187 | * | |
| 188 | * @param yyyyq int (e.g. 20194 for Fall 2019) | |
| 189 | * @throws IllegalArgumentException | |
| 190 | * @return four char string for year (e.g. "2019") | |
| 191 | */ | |
| 192 | public static String getYYYY(int yyyyq) { | |
| 193 |
1
1. getYYYY : negated conditional → KILLED |
if (invalidQtr(yyyyq)) { |
| 194 | throw new IllegalArgumentException( | |
| 195 | "Argument should be a five digit integer in qqqqy format ending in 1,2,3 or 4"); | |
| 196 | } | |
| 197 |
2
1. getYYYY : Replaced integer division with multiplication → KILLED 2. getYYYY : replaced return value with "" for edu/ucsb/cs156/courses/models/Quarter::getYYYY → KILLED |
return String |
| 198 | .format("%04d", (yyyyq / 10)); | |
| 199 | } | |
| 200 | ||
| 201 | public static int qyyToyyyyQ(String qyy) { | |
| 202 | if (qyy | |
| 203 |
1
1. qyyToyyyyQ : negated conditional → KILLED |
.length() != 3) |
| 204 | throw new IllegalArgumentException("Argument should be in QYY format"); | |
| 205 | ||
| 206 | char q = qyy | |
| 207 | .charAt(0); | |
| 208 | String yy = qyy | |
| 209 | .substring(1, 3); | |
| 210 | String legalQuarters = "WSMF"; | |
| 211 | int qInt = legalQuarters | |
| 212 |
1
1. qyyToyyyyQ : Replaced integer addition with subtraction → KILLED |
.indexOf(q) + 1; |
| 213 |
1
1. qyyToyyyyQ : negated conditional → KILLED |
if (invalidQtr(qInt)) { |
| 214 | throw new IllegalArgumentException("First char should be one of " + legalQuarters); | |
| 215 | } | |
| 216 | int yyInt = Integer | |
| 217 | .parseInt(yy); | |
| 218 |
2
1. qyyToyyyyQ : changed conditional boundary → KILLED 2. qyyToyyyyQ : negated conditional → KILLED |
int century = (yyInt > 50) ? 1900 : 2000; |
| 219 |
4
1. qyyToyyyyQ : Replaced integer addition with subtraction → KILLED 2. qyyToyyyyQ : Replaced integer multiplication with division → KILLED 3. qyyToyyyyQ : Replaced integer addition with subtraction → KILLED 4. qyyToyyyyQ : replaced int return with 0 for edu/ucsb/cs156/courses/models/Quarter::qyyToyyyyQ → KILLED |
return (century + yyInt) * 10 + qInt; |
| 220 | } | |
| 221 | ||
| 222 | ||
| 223 | @Override | |
| 224 | public boolean equals(Object o) { | |
| 225 |
1
1. equals : negated conditional → KILLED |
if (o == this) |
| 226 |
1
1. equals : replaced boolean return with false for edu/ucsb/cs156/courses/models/Quarter::equals → KILLED |
return true; |
| 227 |
1
1. equals : negated conditional → KILLED |
if (!(o instanceof Quarter)) { |
| 228 |
1
1. equals : replaced boolean return with true for edu/ucsb/cs156/courses/models/Quarter::equals → KILLED |
return false; |
| 229 | } | |
| 230 | Quarter quarter = (Quarter) o; | |
| 231 |
2
1. equals : negated conditional → KILLED 2. equals : replaced boolean return with true for edu/ucsb/cs156/courses/models/Quarter::equals → KILLED |
return yyyyq == quarter.yyyyq; |
| 232 | } | |
| 233 | ||
| 234 | @Override | |
| 235 | public int hashCode() { | |
| 236 |
1
1. hashCode : replaced int return with 0 for edu/ucsb/cs156/courses/models/Quarter::hashCode → KILLED |
return Objects.hashCode(yyyyq); |
| 237 | } | |
| 238 | ||
| 239 | ||
| 240 | ||
| 241 | /** | |
| 242 | * return a list of Quarters starting with the start parameter and ending with the end parameter, inclusive. | |
| 243 | * | |
| 244 | * The result will automatically go in chronological or reverse chronological order, depending | |
| 245 | * on the order of the parameters. | |
| 246 | * @param start | |
| 247 | * @param end | |
| 248 | * @return list of quarters in specified order | |
| 249 | */ | |
| 250 | ||
| 251 | public static List<Quarter> quarterList(String start, String end) { | |
| 252 | List<Quarter> result = new ArrayList<Quarter>(); | |
| 253 | ||
| 254 | int startInt = Quarter.yyyyqToInt(start); | |
| 255 | int endInt = Quarter.yyyyqToInt(end); | |
| 256 | ||
| 257 |
2
1. quarterList : changed conditional boundary → KILLED 2. quarterList : negated conditional → KILLED |
if (startInt < endInt) { |
| 258 |
2
1. quarterList : changed conditional boundary → KILLED 2. quarterList : negated conditional → KILLED |
for (Quarter iter = new Quarter(startInt); iter.getValue() <= endInt; iter.increment()) { |
| 259 | Quarter q = new Quarter(iter.getValue()); | |
| 260 | result.add(q); | |
| 261 | } | |
| 262 | } | |
| 263 |
2
1. quarterList : changed conditional boundary → KILLED 2. quarterList : negated conditional → KILLED |
if (startInt >= endInt) { |
| 264 |
2
1. quarterList : changed conditional boundary → KILLED 2. quarterList : negated conditional → KILLED |
for (Quarter iter = new Quarter(startInt); iter.getValue() >= endInt; iter.decrement()) { |
| 265 | Quarter q = new Quarter(iter.getValue()); | |
| 266 | result.add(q); | |
| 267 | } | |
| 268 | } | |
| 269 |
1
1. quarterList : replaced return value with Collections.emptyList for edu/ucsb/cs156/courses/models/Quarter::quarterList → KILLED |
return result; |
| 270 | } | |
| 271 | } | |
Mutations | ||
| 19 |
1.1 |
|
| 23 |
1.1 |
|
| 27 |
1.1 |
|
| 56 |
1.1 |
|
| 60 |
1.1 |
|
| 64 |
1.1 |
|
| 68 |
1.1 |
|
| 72 |
1.1 |
|
| 76 |
1.1 |
|
| 77 |
1.1 2.2 3.3 4.4 5.5 |
|
| 87 |
1.1 |
|
| 88 |
1.1 |
|
| 90 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
| 91 |
1.1 |
|
| 102 |
1.1 |
|
| 103 |
1.1 |
|
| 105 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
| 106 |
1.1 |
|
| 125 |
1.1 |
|
| 128 |
1.1 |
|
| 140 |
1.1 |
|
| 144 |
1.1 |
|
| 158 |
1.1 |
|
| 163 |
1.1 |
|
| 164 |
1.1 2.2 |
|
| 176 |
1.1 |
|
| 180 |
1.1 2.2 3.3 |
|
| 193 |
1.1 |
|
| 197 |
1.1 2.2 |
|
| 203 |
1.1 |
|
| 212 |
1.1 |
|
| 213 |
1.1 |
|
| 218 |
1.1 2.2 |
|
| 219 |
1.1 2.2 3.3 4.4 |
|
| 225 |
1.1 |
|
| 226 |
1.1 |
|
| 227 |
1.1 |
|
| 228 |
1.1 |
|
| 231 |
1.1 2.2 |
|
| 236 |
1.1 |
|
| 257 |
1.1 2.2 |
|
| 258 |
1.1 2.2 |
|
| 263 |
1.1 2.2 |
|
| 264 |
1.1 2.2 |
|
| 269 |
1.1 |