Second test: sample task
NB! This task will probably take you more time than usual. During the test, there will a similar task, which will be a bit shorter. It is strongly recommended that you to solve this task in order to get experience about all possible topics of the test.
Task description
The task is to write a program for a company which repairs computers.
In the beginning of a working day, the program is launched from the command line with one argument - name of the recource which contains jobs to be completed during the day (a job means a description of one computer to be repaired). The program reads the jobs into an appropriate data structure and proceeds with a loop. On each iteration of the loop, the user is prompted for a task he wants to do next: repair (R
), add a new job (A
) or finish the working day (F
).
You can use the following sample input file for the jobs: test2_file.txt.
Example of program output
Line: Ordi@2020-04-21T14:00:23 Error explanation: The number of fields is incorrect! Do you want to repair (R), add a new job (A) or finish (F) ? R Computer info: Lenovo;urgentjob@2020-04-21T14:22:42 Enter the time in minutes spent on the repair: 142 Enter your name: Jan The job is completed. Invoice: 59.33€ Do you want to repair (R), add a new job (A) or finish (F) ? A Enter the job description: Dell;ordinaryjob;mnitor Invalid input! The value of the third field is not "monitor"! Enter the job description: Dell;ordinaryjob;monitor The job is registered! Do you want to repair (R), add a new job (A) or finish (F) ? R Computer info: ML;urgentjob;monitor@2020-04-21T14:08:09 Enter the time in minutes spent on the repair: 42 Enter your name: Peter The job is completed. Invoice: 36.45€ Do you want to repair (R), add a new job (A) or finish (F) ? R Computer info: Dell;ordinaryjob;monitor@2020-04-20T13:08:30.080 Enter the time in minutes spent on the repair: 75 Enter your name: Peter The job is completed. Invoice: 44.88€ Do you want to repair (R), add a new job (A) or finish (F) ? F Session summary: Earned sum of money: 140.66€ Repaired computers: Lenovo: 1 Dell: 1 ML: 1 There are 2 computer(s) left to be repaired tomorrow.
Main class
The main class has to be named as ComputerRepair
.
Classes Laptop
and Desktop
.
In order to create a list of jobs, create two classes: Laptop
and Desktop
. The Desktop
class has to be a subclass of Laptop
class. Instances of both classes need to use the following user-defined methods to retrieve the data about a computer:
String getBrand()
boolean isUrgent()
java.time.LocalDateTime getRegistrationDateTime()
Also there has to be a method called calculateInvoice
which takes the base price (double
) as its argument and returns the sum to pay (the calculation rules of the sum are given below).
These methods have to be accessible everywhere.
Job list management
Initial job list
The name of the job list is given as a command line argument. The name may be a file name or a web address. You can assume that if the first argument in the command line starts with http://
or https://
, then it is a web address; otherwise, it is a file name. In both resources, the data are in the text format (UTF-8 encoding).
Hint (click after you have tried to solve this subtask)
if (ref.startsWith("http://") || ref.startsWith("https://")) s = new URL(ref).openStream(); else s = new FileInputStream(ref); BufferedReader bf = new BufferedReader(new InputStreamReader(s, "UTF-8"));
In both types of the resource, the content consists of lines; each line contains information about one job. A job description has the following fields (separated by a semicolon): computer's brand name, job type ("urgentjob" or "ordinaryjob"). If the computer is a desktop, then the job type is followed by the keyword ;monitor
. After that there is a symbol @ followed by job registration date and time.
Example:
Lenovo;ordinaryjob Ordi;urgentjob;monitor
Reading the lines of the text file has to be implemented in the main method; processing the line has to be done in a method called newComputer
(see next section). For each line an object of the corresponding class is created and added to the collection of jobs. For all invalid lines, the program outputs a message with an explanation. If an exception occurs when reading the resource e.g. file is not found or reading from the web is failed (the exception is not about data processing), the exception has to be printed out and the program finishes its work.
Method newComputer
In the main class, there has to be a method called newComputer
(this method can be static), which takes a job description as a string argument and returns an instance of the Laptop
or Desktop
type.
If a job description does not contain @ followed by the registration date and time, the object registration field has to be assigned the time when the object is creatad.
If the format of the string does not meet the requirements, the newComputer
method has to throw an exception. Hence, create an exception class called FormatException
. The exception thrown has to contain a description of the exception. A FormatException
has to be thrown in the following cases (you can assume that no other input exceptions occur):
- the number of fields separated by semicolons is smaller that two or larger than three;
- the job type is neither "ordinaryjob" nor "urgentjob";
- there are three fields in the job description, but the value of the third field is not "monitor".
The method newComputer
is a method of the main class; it cannot be accessible from anywhere else.
Hint: LocalDateTime#parse
Hint: LocalDateTime#now
Hint (click after you have tried to solve this subtask)
private static Laptop newComputer(String line) { int at = line.lastIndexOf('@'); LocalDateTime regTime; if (at != -1) { regTime = LocalDateTime.parse(line.substring(at + 1)); line = line.substring(0, at); } else { regTime = LocalDateTime.now(); } String[] parts = line.split(";"); if (parts.length < 2 || parts.length > 3) // add an exception handler if (!parts[1].equals("ordinaryjob") && !parts[1].equals("urgentjob")) // add an exception handler if (parts.length == 3 && !parts[2].equals("monitor")) // add an exception handler boolean isUrgentjob = parts[1].equals("urgentjob"); if (parts.length == 3) return new Desktop(parts[0], isUrgentjob, regTime); return new Laptop(parts[0], isUrgentjob, regTime); }
Registering new job
If the user wants to register a new job, he has to do it by taking into account the format of the job description. Note that the user does not have to enter the registration date, time and symbol @. Once the description of the new job is entered in the appropriate way, the program adds the job of the Laptop
or Desktop
type to the job collection. If the job description entered is invalid, the program prompts the user for the job description again until the user enters the job in an appropriate format. Each time the user enters an invalid job description, the program outputs the error description.
Repairing the computers
If the user wants to repair a computer, he is given one of the urgent jobs. If there are no urgent jobs, the user is given one of the ordinary jobs. The program shows the job description and pauses until the user enters the time spent on the computer repair (whole minutes) and his name. After that the invoice is generated and the job is completed.
Calculating the invoices
The base price of a job is calculated as follows: the time spent on the computer repair times the payment rate per hour for the specialist who repairs the computer. To get the total price of the repair, the base price is added the fixed sum of 2€ for a laptop or 3€ for a desktop. If the job is urgent, an additional fee of 10€ is added to the base price.
Payment rates per hour are stored in the file payment_rates.dat. This is a binary file created using the java.io.DataOutputStream
class. The first entry of the file is the number of specialists (int
) followed by the name of each specialist (String
) together with his payment rate (double
). In other words, the structure of the payment_rates.dat file looks as follows:
- number of specialists
- name of the first specialist
- payment rate of the first specialist
- . . .
- name of the last specialist
- payment rate of the last specialist
Completed and uncompleted jobs
Before the program exits, is saves the completed jobs into the file called completed.dat using the java.io.DataOutputStream
class. The file must have the following structure: the number of the completed jobs (int
) followed by the brand name of each repaired computer (String
), registration time (String
; use the toString
method of LocalDateTime
class) and the sum to be received for the completed jobs (double
). NB! If there already is a file with the same name, the program rewrites it.
All uncompleted jobs have to be saved into a file called queue.txt using the UTF-8 encoding and the initial format.
Summary of jobs
At the end of the session the program has to output the summary of the jobs. The summary has to contain information about the amount of money earned, brand names of repaired computers with the numbers of computers repaired for each brand, and the number of jobs in the queue left for the next session tomowrrow.
Hint (click after you have tried to solve this subtask)
private static void showSummary(double sum, Map<Laptop, Double> completed, int incompleted) { System.out.println("Session summary:"); System.out.println("Earned sum of money: " + Math.round(sum*100.0)/100.0 + "€"); System.out.println("Repaired computers: "); Map<String, Integer> differentComputers = new HashMap<String, Integer>(); for (Laptop computer : completed.keySet()) { String brandName = computer.getBrand(); if (differentComputers.containsKey(brandName)) { int numOfBrand = differentComputers.get(brandName) + 1; differentComputers.put(brandName, numOfBrand); } else differentComputers.put(brandName, 1); } for (String brandName : differentComputers.keySet()) System.out.println(" " + brandName + ": " + differentComputers.get(brandName)); System.out.println("There are " + incompleted + " computer(s) in the queue left to be repaired tomorrow."); }
Data files
It is recommended to create your own data files. Think what inputs would test the program efficiently and help discover bugs in the program.
If it is too difficult to compose the files, use these: computers.zip.
To test reading the data from a webpage, use: computers.txt
Recommendations
- If possible, place subtasks into separate methods.
- If you notice that you copy and paste lines of code, try to place these lines of code into a separate method.
- Check that polymorphism, inheritance and data structures are used appropriately.
- All fields have to be private and non-static.