Second test: sample task
NB! This task will probably take you more time than usually. During the test, there will a similar task, but a bit shorter. We strongly recommend you to solve this task in order to get invaluable experience and learn from own mistakes.
Task description
The task is to write a program for a company which repairs computers.
At the beginning of a day, the program is launched from the command line with one argument - a reference to the recourse with jobs to be done during the day (a job is a description of one computer to be repaired). The program reads in 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: to repair (P
), to register a new job (R
) or to finish his working day (F
).
You can use the following sample input file for the jobs: Attach:test2_file.txt
An example of the program output
Line: Ordi@2017-04-21T14:00:23 Error explanation: The number of fields is incorrect! Do you want to repair (P), register a new job (R) or finish (F) ? P Computer info: Lenovo;urgentjob@2017-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 (P), register a new job (R) or finish (F) ? R 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 (P), register a new job (R) or finish (F) ? P Computer info: ML;urgentjob;monitor@2017-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 (P), register a new job (R) or finish (F) ? P Computer info: Dell;ordinaryjob;monitor@2017-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 (P), register a new job (R) or finish (F) ? F Session summary: Earned sum of money: 140.66€ Repaired computers: Lenovo: 1pcs Dell: 1pcs ML: 1pcs There are 2 computer(s) to be repaired tomorrow.
Guidelines how to start solving the task
Main class
The main class has to be named as ComputerRepair
and placed into the default package.
Classes Laptop
and Desktop
.
In order to create a list of jobs, create two classes into the default package: Laptop
and Desktop
. The Desktop
class has to be a subclass of Laptop
class. Do not duplicate the fields and methods of the superclass in the subclass. Instances of both classes need to use the following user-defined methods to retrieve data about a computer:
String getBrand()
boolean getIsUrgentJob()
java.time.LocalDateTime getRegistrationDateTime()
Also there has to be a method called calculateInvoice
which takes in an argument for the base price (double
) and returns the sum to pay (the calculation rules of the sum are given further in the task).
NB! These methods have to be accessible everywhere.
Job list management
Initial job list
A reference to the initial job list is given as a command line argument. The reference might be a file name or a webpage. You can assume if the first argument in the command line starts with http://
or https://
, then the reference is a webpage; otherwise, it is a file name. In both resources, the data are in the text format (UTF-8 encoding).
Hint (check 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"));
Note: reading the text lines has to be implemented in the main method; a line processing has to be done in a method called readComputer
(see next section).
In both resources, 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 a computer is a desktop, the job type is followed by the keyword ;monitor
. After that there is a symbol @ followed by the job registration date and time.
Example:
*Lenovo;ordinaryjob
*Ordi;urgentjob;monitor
During data reading from a resource, an object of the corresponding class is created for each line and added to the collection of jobs (check a method readComputer
described in next section). For all invalid lines, the program outputs a message with an explanation. If an exception occurs with reading a 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 has to finish its work.
Method ComputerRepair.readComputer
In the main class, there has to be a method called readComputer
(the method might be static) which takes in 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 a new record has been entered.
If the format of the string does not meet the requirements, readComputer
method has to throw an exception. Hence, create an exception class called FormatException
. The thrown out exception has to contain a description of the exception. FormatException
has to be thrown out 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".
NB! Method readComputer
is a method of the main class; it cannot be accessible from anywhere else.
Hint: LocalDateTime#parse
Hint: LocalDateTime#now
Hint (check after you have tried to solve this subtask)
private static Laptop readComputer(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); }
Register new job
If a user wants to register a new job, he has to do it 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 a description of a 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 entered job description is invalid, the program prompts the user for the job description again until the user enters the job in the appropriate format. Each time the user enters an invalid job description, the program outputs the error description.
Computer repair
If the user wants to repair a computer, he is given one of the urgent jobs. If there are no urgent jobs, the specialist is given one of the ordinary jobs. The program shows the job description and holds on until the user enters the time spent on the computer repair (whole minutes) and his name. After that the invoice has to be generated, and the job is completed.
Calculate job invoice
The base price of a job is calculated as follows: the time spend on the computer repair times specialist's payment rate per hour. 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.
Specialists' payment rate per hour are stored in a file called payment_rate.dat. This is a binary file created with the help of java.io.DataOutputStream
class. On the first line of the file, there is the number of specialists (int
) followed by the name of each specialist (String
) and his payment rate (double
). In other words, the structure of the .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 not completed jobs
Before the program exits, the program saves the completed jobs into a file called completed.dat using 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 is a file with the same name, the program rewrites the content of the file.
The incompleted jobs have to be saved into a file called queue.txt using the UTF-8 encoding and the initial format.
Summary on jobs
The summary of the jobs has to be output at the end of the program execution session. The summary has to contain information about the earned amount of money, the brand name of the repaired computers, the number of the repaired computers of each brand, and the number of the jobs in the queue left for the next time.
Hint (check 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)+"pcs"); System.out.println("There are "+ incompleted +" computer(s) in the queue left to be repaired next time."); }
Data files
It is recommended to create your own data files. Think about the records which 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 data reading from a webpage, use : computers.txt
Strong recommendations
- Reading data with the aid of
Scanner
class has to be well-practised by now. Therefore, try to use other streams for reading from a file. - The code has to be readable (use tabs)!
- If possible, place subtasks into separate methods!
- If you notice that you copy-paste lines of code, try to place these lines of code into a separate method.
- Check if polymorphism, inheritance and data structures are used appropriately!
- All the fields have to be private and non-static!!
A non-compilable program gives 0 points!