Arvutiteaduse instituut
  1. Kursused
  2. 2019/20 kevad
  3. Objektorienteeritud programmeerimine (Narva Kolledž) (LTAT.NR.003)
EN
Logi sisse

Objektorienteeritud programmeerimine (Narva Kolledž) 2019/20 kevad

  • Home
  • Materials
  • Grading
  • Java Glossary
  • Cheat sheet (S1-S6)
  • Source Example
  • Links

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;ordinaryjob25.03.2020 12:34
 Ordi;urgentjob;monitor12.04.2020 10:12

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.
  • Arvutiteaduse instituut
  • Loodus- ja täppisteaduste valdkond
  • Tartu Ülikool
Tehniliste probleemide või küsimuste korral kirjuta:

Kursuse sisu ja korralduslike küsimustega pöörduge kursuse korraldajate poole.
Õppematerjalide varalised autoriõigused kuuluvad Tartu Ülikoolile. Õppematerjalide kasutamine on lubatud autoriõiguse seaduses ettenähtud teose vaba kasutamise eesmärkidel ja tingimustel. Õppematerjalide kasutamisel on kasutaja kohustatud viitama õppematerjalide autorile.
Õppematerjalide kasutamine muudel eesmärkidel on lubatud ainult Tartu Ülikooli eelneval kirjalikul nõusolekul.
Courses’i keskkonna kasutustingimused