the OOP project is needed to be coded in netbeans and store a information in fil
ID: 3855924 • Letter: T
Question
the OOP project is needed to be coded in netbeans and store a information in file on local machine it could be stored with xml tags since its easier.
OOP Project Description
Requirements:
You are to design and build software media rental system. The software will track each user’s account with its rentals. A user can rent multiple media of different type/genre and all that user’s rentals are managed under their account (single account per user). A user will be assigned a unique account id by the system and his first name, last name, and email address will also be stored at account creation. There will be ability to update the user’s name and email address but not the account id.
The software needs to be able to track different accounts, but the software should only load and actively manage one account at a time. There should be the ability to save account information to a file, re-open it later (one account per file using XML format), and delete the account (delete file with account information). The account id will be used as part of the filename to save, lookup to open, and delete account. There can be an account without any media rented.
There are 3 types of media that can be rented: Movie DVD, Music CD, and Audio Book CD. The company only rents certain genre of each media, shown in the table below. All media have following characteristics: media id (integer), title (String), year published (integer), file size in megabytes (double), rental end date (Calendar), and rental fee (Double). Audio book also has number of chapters (integer) and Music CD the length in minutes.
Media Type
Genre
Movie DVD
Romance
Drama
Documentary
Music CD
Country
Classical
Audio Book on CD
Memoir
SciFi
Romance
So for example, a user would rent a specific media such as a movie DVD of genre Romance with title “Love”, media id 100005, etc. Rental fee needs to be calculated at the time the rental is added to the account and the calculated fee should be stored in the rented media’s attribute.
Every media has a price to rent based on a 2 week rental. The following rules show how to determine the rental price.
Movie DVD rental has a flat fee of $3.50 for movie published within current year and otherwise a flat fee of $2.00. So for example if the DVD was published this year, it would cost $3.50 to rent for two weeks but if published last year, it would cost $2.00. However, Drama and Romance media has an additional fee of $0.25 added to the price so for documentary the above example would be $3.75 and $2.25 respectively.
Audio Book rentals are a little more complex.The rental price is calculated by multiplying the number of chapters * 0.10 and adding a $1 if the Audio Book was published this year. So if the Audio Book was published this year and the size is 20 chapters, the rental would cost $3.00 (20 * 0.10 + 1) and if it was published 2 years ago, it would be $2.00 to rent.
Music CDs are even more complicated because they depend of the type of music being rented. So classical rentals are calculated based on the file size * 0.015 and additional fee of 1.00 if published this year.Country music rental are calculated based on the file size * 0.02 and additional fee of 1.00 if published this year. So a classical music rental of size 114 MB published this year would cost $2.71 (114 *0.015 +1) and country music rental of 114 MB published this year would cost $2.28 (114 *0.02).
There also needs to be ability to add a media to the account, and delete media from the account. When a rental expires, it can be renewed for another two weeks.
Here is a scenario how this system should work in a real business:
Imagine there are media boxes on the shelf in some rental place. So a customer comes in and gets some boxes of the rentals they want to get. They go up to the cashier and if it is their first time, an account will be created for them in the system. They will need to provide their first name, last name and email address that will be inputted by the cashier into the new account being created. The system will generate an account id for this user and cashier will give that information to the customer.
Then the cashier will scan each box for the media information, which will create the media object in the system. That object will be added to the account. The cashier will repeat for each media box to be rented. The rental end date will be set by the system, 2 weeks from the current date. The system will calculate the rental fee for each media being rented. All that information will be displayed on the screen: each media with its information and the rental fee for each (the actual displaying will be done by user interface which is not part of the system you are creating). Customer will pay and get receipt but that is outside of the scope of the system we are creating.
Then the customer may come in to return the media. He will provide his account number and the cashier will bring his account up. The cashier will select return choice in the user interface and scan each media to remove from his account. Let’s say he had 3 media rented but he is returning two of them. So those 2 rentals are removed from his account. For the one he still has he decides to renew it so cashier selects renew option in the user interface, scans the media and that media gets renewed for next two weeks. Again the fee is calculated and all the new information in the account is displayed by the user interface.
Then he notices on the screen that his name is spelled incorrectly or his email is not right. The cashier will be able to change that information in the account.
Next time when customer comes in, he may return the media he has but he may not want to rent at this time. His account will be still there but without any media until next time when he rents again.
The system you are designing will have the functionality needed to satisfy the above requirements as illustrated by the scenario. You will not be implementing the actual user interface (you will still design them though in assignment 7) but you need the classes, attributes, and methods to receive and provide the information that the user interface will need. You can assume that for a complete solution there would be some other class that implements user interface with main() method and the scanning module and that it will call your classes. You will write such a class with main() in assignment 8 as your test class.
Media Type
Genre
Movie DVD
Romance
Drama
Documentary
Music CD
Country
Classical
Audio Book on CD
Memoir
SciFi
Romance
Explanation / Answer
package string;
/**
* Class for special mathematical calculations.<br/>
* ATTENTION:<br/>Should depend only on standard Java libraries!
*
* @since 2013-09-05
* @version 2014-10-14
*/
10 public class MathsUtils {
11
12 // CONSTANTS
13 // ------------------------------------------
14
15 /** The exponent sign in a scientific number, or the capital letter E. */
16 public static final char EXPONENT = 'E';
17
18 /** Value after which the language switches from scientific to double */
19 private static final double E_TO_DOUBLE = 1E-3;
20
21 /** The zero string constant used at several places. */
22 public static final String ZERO = "0";
23
24 /** The string of zeros */
25 private static final String ZEROS = "000000000000000000000000000000000";
26
27 // METHODS
28 // ------------------------------------------
29
30 /**
31 * Determines, if the number uses a scientific representation.
32 *
33 * @param number the number
34 * @return true, if it is a scientific number, false otherwise
35 */
36 private static boolean isScientific(final double number) {
37 return ((new Double(number)).toString().indexOf(EXPONENT) > 0);
38 }
39
40 /**
41 * Determines how many zeros are to be appended after the decimal digits.
42 *
43 * @param significantsAfter Requested significant digits after decimal
44 * @param separator Language-specific decimal separator
45 * @param number Rounded number
46 * @return Requested value
47 */
48 private static byte calculateMissingSignificantZeros(
49 final byte significantsAfter,
50 final char separator,
51 final double number) {
52
53 final byte after = findSignificantsAfterDecimal(separator, number);
54
55 final byte zeros =
56 (byte) (significantsAfter - ((after == 0) ? 1 : after));
57
58 return ((zeros >= 0) ? zeros : 0);
59 }
60
61 /**
62 * Finds the insignificant zeros after the decimal separator.
63 *
64 * @param separator Language-specific decimal separator
65 * @param number the number
66 * @return the byte
67 */
68 private static byte findInsignificantZerosAfterDecimal(
69 final char separator,
70 final double number) {
71
72 if ((Math.abs(number) >= 1) || isScientific(number)) {
73 return 0;
74 } else {
75 final StringBuilder string = new StringBuilder();
76
77 string.append(number);
78 string.delete(0,
79 string.indexOf(new Character(separator).toString()) + 1);
80
81 // Determine what to match:
82 final String regularExpression = "[1-9]";
83
84 final String[] split = string.toString().split(regularExpression);
85
86 return (split.length > 0) ? (byte) split[0].length() : 0;
87 }
88 }
89
90 /**
91 * Calculates the number of all significant digits (without the sign and
92 * the decimal separator).
93 *
94 * @param significantsAfter Requested significant digits after decimal
95 * @param separator Language-specific decimal separator
96 * @param number Value where the digits are to be counted
97 * @return Number of significant digits
98 */
99 private static byte findSignificantDigits(final byte significantsAfter,
100 final char separator,
101 final double number) {
102
103 if (number == 0) { return 0; }
104 else {
105 String mantissa =
106 findMantissa(separator, new Double(number).toString());
107
108 if (number == (long)number) {
109 mantissa = mantissa.substring(0, mantissa.length() - 1);
110 }
111
112 mantissa = retrieveDigits(separator, mantissa);
113 // Find the position of the first non-zero digit:
114 short nonZeroAt = 0;
115
116 for (; (nonZeroAt < mantissa.length())
117 && (mantissa.charAt(nonZeroAt) == '0'); nonZeroAt++) ;
118
119 return (byte)mantissa.substring(nonZeroAt).length();
120 }
121 }
122
123 /**
124 * Determines the number of significant digits after the decimal separator
125 * knowing the total number of significant digits and the number before the
126 * decimal separator.
127 *
128 * @param significantsBefore Number of significant digits before separator
129 * @param significantDigits Number of all significant digits
130 * @return Number of significant decimals after the separator
131 */
132 private static byte findSignificantsAfterDecimal(
133 final byte significantsBefore,
134 final byte significantDigits) {
135
136 final byte afterDecimal =
137 (byte) (significantDigits - significantsBefore);
138
139 return (byte) ((afterDecimal > 0) ? afterDecimal : 0);
140 }
141
142 /**
143 * Determines the number of digits before the decimal point.
144 *
145 * @param separator Language-specific decimal separator
146 * @param number Value to be scrutinised
147 * @return Number of digits before the decimal separator
148 */
149 private static byte findSignificantsBeforeDecimal(final char separator,
150 final double number) {
151
152 final String value = new Double(number).toString();
153
154 // Return immediately, if result is clear: Special handling at
155 // crossroads of floating point and exponential numbers:
156 if ((number == 0) || (Math.abs(number) >= E_TO_DOUBLE)
157 && (Math.abs(number) < 1)) {
158
159 return 0;
160 } else if ((Math.abs(number) > 0) && (Math.abs(number) < E_TO_DOUBLE)) {
161 return 1;
162 } else {
163 byte significants = 0;
164 // Significant digits to the right of decimal separator:
165 for (byte b = 0; b < value.length(); b++) {
166 if (value.charAt(b) == separator) {
167 break;
168 } else if (value.charAt(b) != StringUtils.DASH) {
169 significants++;
170 }
171 }
172
173 return significants;
174 }
175 }
176
177 /**
178 * Returns the exponent part of the double number.
179 *
180 * @param number Value of which the exponent is of interest
181 * @return Exponent of the number or zero.
182 */
183 private static short findExponent(final double number) {
184 return new Short(findExponent((new Double(number)).toString()));
185 }
186
187 /**
188 * Finds the exponent of a number.
189 *
190 * @param value Value where an exponent is to be searched
191 * @return Exponent, if it exists, or "0".
192 */
193 private static String findExponent(final String value) {
194 final short exponentAt = (short) value.indexOf(EXPONENT);
195
196 if (exponentAt < 0) { return ZERO; }
197 else {
198 return value.substring(exponentAt + 1);
199 }
200 }
201
202 /**
203 * Finds the mantissa of a number.
204 *
205 * @param separator Language-specific decimal separator
206 * @param value Value where the mantissa is to be found
207 * @return Mantissa of the number
208 */
209 private static String findMantissa(final char separator,
210 final String value) {
211
212 String strValue = value;
213
214 final short exponentAt = (short) strValue.indexOf(EXPONENT);
215
216 if (exponentAt > -1) {
217 strValue = strValue.substring(0, exponentAt);
218 }
219 return strValue;
220 }
221
222 /**
223 * Retrieves the digits of the value without decimal separator or sign.
224 *
225 * @param separator
226 * @param number Mantissa to be scrutinised
227 * @return The digits only
228 */
229 private static String retrieveDigits(final char separator, String number) {
230 // Strip off exponent part, if it exists:
231 short eAt = (short)number.indexOf(EXPONENT);
232
233 if (eAt > -1) {
234 number = number.substring(0, eAt);
235 }
236
237 return number.replace((new Character(StringUtils.DASH)).toString(), "").
238 replace((new Character(separator)).toString(), "");
239 }
240
241
242 // ---- Public methods ----------------------
243
244 /**
245 * Returns the number of digits in the long value.
246 *
247 * @param value the value
248 * @return the byte
249 */
250 public static byte digits(final long value) {
251 return (byte) StringUtils.filter(Long.toString(value), ".,").length();
252 }
253
254 /**
255 * Finds the significant digits after the decimal separator of a mantissa.
256 *
257 * @param separator Language-specific decimal separator
258 * @param number Value to be scrutinised
259 * @return Number of significant zeros after decimal separator.
260 */
261 public static byte findSignificantsAfterDecimal(final char separator,
262 final double number) {
263
264 if (number == 0) { return 1; }
265 else {
266 String value = (new Double(number)).toString();
267
268 final short separatorAt = (short) value.indexOf(separator);
269
270 if (separatorAt > -1) {
271 value = value.substring(separatorAt + 1);
272 }
273
274 final short exponentAt = (short) value.indexOf(EXPONENT);
275
276 if (exponentAt > 0) {
277 value = value.substring(0, exponentAt);
278 }
279
280 final Long longValue = new Long(value).longValue();
281
282 if (Math.abs(number) < 1) {
283 return (byte) longValue.toString().length();
284 } else if (longValue == 0) {
285 return 0;
286 } else {
287 return (byte) (("0." + value).length() - 2);
288 }
289 }
290 }
291
292 /**
293 * Calculates the power of the base to the exponent without changing the
294 * least-significant digits of a number.
295 *
296 * @param basis
297 * @param exponent
298 * @return basis to power of exponent
299 */
300 public static double power(final int basis, final short exponent) {
301 return power((short) basis, exponent);
302 }
303
304 /**
305 * Calculates the power of the base to the exponent without changing the
306 * least-significant digits of a number.
307 *
308 * @param basis the basis
309 * @param exponent the exponent
310 * @return basis to power of exponent
311 */
312 public static double power(final short basis, final short exponent) {
313 if (basis == 0) {
314 return (exponent != 0) ? 1 : 0;
315 } else {
316 if (exponent == 0) {
317 return 1;
318 } else {
319 // The Math method power does change the least significant
320 // digits after the decimal separator and is therefore useless.
321 double result = 1;
322 short s = 0;
323
324 if (exponent > 0) {
325 for (; s < exponent; s++) {
326 result *= basis;
327 }
328 } else if (exponent < 0) {
329 for (s = exponent; s < 0; s++) {
330 result /= basis;
331 }
332 }
333
334 return result;
335 }
336 }
337 }
338
339 /**
340 * Rounds a number to the decimal places.
341 *
342 * @param significantsAfter Requested significant digits after decimal
343 * @param separator Language-specific decimal separator
344 * @param number Number to be rounded
345 * @return Rounded number to the requested decimal places
346 */
347 public static double round(final byte significantsAfter,
348 final char separator,
349 final double number) {
350
351 if (number == 0) { return 0; }
352 else {
353 final double constant = power(10, (short)
354 (findInsignificantZerosAfterDecimal(separator, number)
355 + significantsAfter));
356 final short dExponent = findExponent(number);
357
358 short exponent = dExponent;
359
360 double value = number*constant*Math.pow(10, -exponent);
361 final String exponentSign =
362 (exponent < 0) ? String.valueOf(StringUtils.DASH) : "";
363
364 if (exponent != 0) {
365 exponent = (short) Math.abs(exponent);
366
367 value = round(value);
368 } else {
369 value = round(value)/constant;
370 }
371
372 // Power method cannot be used, as the exponentiated number may
373 // exceed the maximal long value.
374 exponent -= Math.signum(dExponent)*(findSignificantDigits
375 (significantsAfter, separator, value) - 1);
376
377 if (dExponent != 0) {
378 String strValue = Double.toString(value);
379
380 strValue = strValue.substring(0, strValue.indexOf(separator))
381 + EXPONENT + exponentSign + Short.toString(exponent);
382
383 value = new Double(strValue);
384 }
385
386 return value;
387 }
388 }
389
390 /**
391 * Rounds a number according to mathematical rules.
392 *
393 * @param value the value
394 * @return the double
395 */
396 public static double round(final double value) {
397 return (long) (value + .5);
398 }
399
400 /**
401 * Rounds to a fixed number of significant digits.
402 *
403 * @param significantDigits Requested number of significant digits
404 * @param separator Language-specific decimal separator
405 * @param dNumber Number to be rounded
406 * @return Rounded number
407 */
408 public static String roundToString(final byte significantDigits,
409 final char separator,
410 double dNumber) {
411
412 // Number of significants that *are* before the decimal separator:
413 final byte significantsBefore =
414 findSignificantsBeforeDecimal(separator, dNumber);
415 // Number of decimals that *should* be after the decimal separator:
416 final byte significantsAfter = findSignificantsAfterDecimal(
417 significantsBefore, significantDigits);
418 // Round to the specified number of digits after decimal separator:
419 final double rounded = MathsUtils.round(significantsAfter, separator, dNumber);
420
421 final String exponent = findExponent((new Double(rounded)).toString());
422 final String mantissa = findMantissa(separator,
423 (new Double(rounded)).toString());
424
425 final double dMantissa = new Double(mantissa).doubleValue();
426 final StringBuilder result = new StringBuilder(mantissa);
427 // Determine the significant digits in this number:
428 final byte significants = findSignificantDigits(significantsAfter,
429 separator, dMantissa);
430 // Add lagging zeros, if necessary:
431 if (significants <= significantDigits) {
432 if (significantsAfter != 0) {
433 result.append(ZEROS.substring(0,
434 calculateMissingSignificantZeros(significantsAfter,
435 separator, dMantissa)));
436 } else {
437 // Cut off the decimal separator & after decimal digits:
438 final short decimal = (short) result.indexOf(
439 new Character(separator).toString());
440
441 if (decimal > -1) {
442 result.setLength(decimal);
443 }
444 }
445 } else if (significantsBefore > significantDigits) {
446 dNumber /= power(10, (short) (significantsBefore - significantDigits));
447
448 dNumber = round(dNumber);
449
450 final short digits =
451 (short) (significantDigits + ((dNumber < 0) ? 1 : 0));
452
453 final String strDouble = (new Double(dNumber)).toString().substring(0, digits);
454
455 result.setLength(0);
456 result.append(strDouble + ZEROS.substring(0,
457 significantsBefore - significantDigits));
458 }
459
460 if (new Short(exponent) != 0) {
461 result.append(EXPONENT + exponent);
462 }
463
464 return result.toString();
465 } // public static String roundToString(…)
466
467 /**
468 * Rounds to a fixed number of significant digits.
469 *
470 * @param separator Language-specific decimal separator
471 * @param significantDigits Requested number of significant digits
472 * @param value Number to be rounded
473 * @return Rounded number
474 */
475 public static String roundToString(final char separator,
476 final int significantDigits,
477 float value) {
478
479 return roundToString((byte)significantDigits, separator,
480 (double)value);
481 }
482 } // class MathsUtils
The code is tested with the following JUnit test:
Computer code Code listing 3.22: MathsUtilsTest.java
1 package string;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertFalse;
5 import static org.junit.Assert.assertTrue;
6
7 import java.util.Vector;
8
9 import org.junit.Test;
10
11 /**
12 * The JUnit test for the <code>MathsUtils</code> class.
13 *
14 * @since 2013-03-26
15 * @version 2014-10-14
16 */
17 public class MathsUtilsTest {
18
19 /**
20 * Method that adds a negative and a positive value to values.
21 *
22 * @param d the double value
23 * @param values the values
24 */
25 private static void addValue(final double d, Vector<Double> values) {
26 values.add(-d);
27 values.add(d);
28 }
29
30 // Public methods ------
31
32 /**
33 * Tests the round method with a double parameter.
34 */
35 @Test
36 public void testRoundToStringDoubleByteCharDouble() {
37 // Test rounding
38 final Vector<Double> values = new Vector<Double>();
39 final Vector<String> strValues = new Vector<String>();
40
41 values.add(0.0);
42 strValues.add("0.00000");
43 addValue(1.4012984643248202e-45, values);
44 strValues.add("-1.4012E-45");
45 strValues.add("1.4013E-45");
46 addValue(1.999999757e-5, values);
47 strValues.add("-1.9999E-5");
48 strValues.add("2.0000E-5");
49 addValue(1.999999757e-4, values);
50 strValues.add("-1.9999E-4");
51 strValues.add("2.0000E-4");
52 addValue(1.999999757e-3, values);
53 strValues.add("-0.0019999");
54 strValues.add("0.0020000");
55 addValue(0.000640589, values);
56 strValues.add("-6.4058E-4");
57 strValues.add("6.4059E-4");
58 addValue(0.3396899998188019, values);
59 strValues.add("-0.33968");
60 strValues.add("0.33969");
61 addValue(0.34, values);
62 strValues.add("-0.33999");
63 strValues.add("0.34000");
64 addValue(7.07, values);
65 strValues.add("-7.0699");
66 strValues.add("7.0700");
67 addValue(118.188, values);
68 strValues.add("-118.18");
69 strValues.add("118.19");
70 addValue(118.2, values);
71 strValues.add("-118.19");
72 strValues.add("118.20");
73 addValue(123.405009, values);
74 strValues.add("-123.40");
75 strValues.add("123.41");
76 addValue(30.76994323730469, values);
77 strValues.add("-30.769");
78 strValues.add("30.770");
79 addValue(130.76994323730469, values);
80 strValues.add("-130.76");
81 strValues.add("130.77");
82 addValue(540, values);
83 strValues.add("-539.99");
84 strValues.add("540.00");
85 addValue(12345, values);
86 strValues.add("-12344");
87 strValues.add("12345");
88 addValue(123456, values);
89 strValues.add("-123450");
90 strValues.add("123460");
91 addValue(540911, values);
92 strValues.add("-540900");
93 strValues.add("540910");
94 addValue(9.223372036854776e56, values);
95 strValues.add("-9.2233E56");
96 strValues.add("9.2234E56");
97
98 byte i = 0;
99 final byte significants = 5;
100
101 for (final double element : values) {
102 final String strValue;
103
104 try {
105 strValue = MathsUtils.roundToString(significants, StringUtils.PERIOD, element);
106
107 System.out.println(" MathsUtils.round(" + significants + ", '"
108 + StringUtils.PERIOD + "', " + element + ") ==> "
109 + strValue + " = " + strValues.get(i));
110 assertEquals("Testing roundToString", strValue, strValues.get(i++));
111 } catch (final Exception e) {
112 // TODO Auto-generated catch block
113 e.printStackTrace();
114 }
115 }
116 }
117
118 } // class MathsUtilsTest
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.