C, PHP, VB, .NET

Дневникът на Филип Петров


* Изходен код от упражнение 9, 2015

Публикувано на 20 ноември 2015 в раздел ПИК3 Java.

В това упражнение се разглеждат структури от данни. Използват се ArrayList, LinkedList и HashMap.

(решена) Задача 1. Реализирайте enum Diagnosis по следния начин:

enum Diagnosis{
    NOTSICK(10.0), LITTLESICK(20.0), SICK(50.0), VERYSICK(200.0);
    final double cureCost;
    Diagnosis(double cureCost){
        this.cureCost = cureCost;
    }
}

Така след като сте създали например обект “Diagnosis sickness = Diagnosis.SICK;” ще можете да видите колко струва лечението ѝ чрез достъпване на променливата sickness.cureCost;

Задача 2. Реализирайте клас „Пациент” (Patient) със следните характеристики: name (String), egn (String), paycheck (double – колко пари има човека) и sicknesses (ArrayList с елементи от изброим тип Diagnosis – какви заболявания има човека). Направете само конструктор с подадени параметри. Не правете get и set методи – нека всички са с модификатор за достъп default.

Реализирайте метод “private double payBill(double amount)”, който намалява paycheck с amount и:

  • Ако paycheck все още е положителен, връща 0 (човека е платил и не сължи нищо);
  • Ако paycheck е станал отрицателен, трябва да направи paycheck 0 (човека е платил каквото има), а да върне като резултат колко пари дължи (с колко amount е бил по-голям от paycheck).

Реализирайте метод:
double cureSickness(Diagnosis sickness) throws OutOfMoneyException,NoSuchSicknessException”
в който правите следното:

  • Ако човекът вече няма пари (paycheck е станал <=0 след последното лечение или не е имал пари по принцип), хвърля OutOfMoneyException;
  • Ако подаденото заболяване не съществува в списъка от болести на човека (той не е болен от него), хвърля NoSuchSicknessException;
  • Ако има такава болест и има позитивен баланс, прави return this.payBill(sickness.cureCost);

Решение:

class Patient{
  String name;
  String egn;
  double paycheck;
  ArrayList<Diagnosis> sicknesses;
  Patient(String name, String egn, double paycheck, ArrayList<Diagnosis> sicknesses){
    this.name = name;
    this.egn = egn;
    this.paycheck = paycheck;
    this.sicknesses = sicknesses;
  }
  private double payBill(double amount){
    this.paycheck -= amount;
    if(this.paycheck >= 0) return 0;
    else{
      double debt = -this.paycheck;
      return debt;
    }
  }
  double cureSickness(Diagnosis sickness)
  throws OutOfMoneyException,NoSuchSicknessException{
    if(this.paycheck<=0) throw new OutOfMoneyException(sickness.cureCost);
    Iterator<Diagnosis> it = this.sicknesses.iterator();
    while(it.hasNext()){
      if(it.next().equals(sickness)){
        double result = this.payBill(sickness.cureCost);
        it.remove();
        return result;
      }
    }
    throw new NoSuchSicknessException(sickness);
  }
  public int hashCode(){
     int result = 17;
     result = result*37 + this.name==null?0:this.name.hashCode();
     result = result*37 + this.egn==null?0:this.egn.hashCode();
     // Всеки List, в случая ArrayList, също има hashCode, който е:
     // int hashCode = 1;
     // for(E e: list) hashCode = hashCode*31 + (e==null?0:e.hashCode());
     // return hashCode;
     result = result*37 + (this.sicknesses==null?0:this.sicknesses.hashCode());
     return result;
     // Забелязахте ли, че не добавихме payCheck във формулата за result?
     // Ще считаме ли два записа за пациент с едно и също име, ЕГН и
     // едни и същи заболявания, но с различни портфейли за различни хора?
     // Разбира се, че не - това е един и същи човек, който просто се е
     // прибрал, взел си е портфейла и се е върнал. Това ще отразим и в equals
  }
  public boolean equals(Object o){
     if(!(o instanceof Patient)) return false;
     Patient p = (Patient)o;
     if(this.name == p.name
          &&
        this.egn == p.egn
          &&
        this.sicknesses.equals(p.sicknesses)
     ) return true;
     else return false;
  }
}

Задача 3. Реализирайте изключенията OutOfMoneyException,NoSuchSicknessException

Решение:

class OutOfMoneyException extends Exception{
  OutOfMoneyException(){
    super("Пациентът няма достатъчно пари");
  }
  OutOfMoneyException(double cureCost){
    super("Пациентът няма достатъчно пари. Трябва да плати: "+cureCost);
  } 
}
class NoSuchSicknessException extends Exception{
  NoSuchSicknessException(){
    super("Пациентът нe е болен от тази болест");
  }
  NoSuchSicknessException(Diagnosis sickness){
    super("Пациентът нe е болен от тази болест: "+sickness.toString());
  }
}

Задача 4. Направете клас с main метод, който съдържа:

  • Статична член променлива
    static HashMap<Patient, Double> debtors = new HashMap<Patient, Double>();
    в която в структура от данни тип „речник“ ще записваме длъжниците – хора, които сме лекували, но не са си платили.
  • Main метод, в който:
    • Създавате няколко примерни обекта от тип Patient и ги нареждате в LinkedList;
    • За всеки елемент на свързания списък правите по няколко различни лечения;
    • Тези хора, които са били лекувани, но не са успяли да платят, записвате в речника debtors
    • Накрая извеждате имената и сумите, които дължат, за всички длъжници в речника.

Решение:

import java.util.*;
public class Upr9{
  static HashMap<Patient, Double> debtors = new HashMap<Patient, Double>();

  public static void main(String[] args){
    ArrayList<Diagnosis> combination1 = new ArrayList<>();
    combination1.add(Diagnosis.LITTLESICK);
    combination1.add(Diagnosis.SICK);
    ArrayList<Diagnosis> combination2 = new ArrayList<>();
    combination2.add(Diagnosis.VERYSICK);
    combination2.add(Diagnosis.SICK);
    ArrayList<Diagnosis> combination3 = new ArrayList<>();
    combination3.add(Diagnosis.NOTSICK);

    Patient p1 = new Patient("Ivan", "1234", 50.0, combination1);
    Patient p2 = new Patient("Petar", "5678", 150.0, combination2);
    Patient p3 = new Patient("Maria", "9012", 100.0, combination3);

    LinkedList<Patient> patients = new LinkedList<Patient>();
    patients.add(p1);
    patients.add(p2);
    patients.add(p3);

    for(Diagnosis sickness: Diagnosis.values()){
      Iterator<Patient> it = patients.iterator();
      while(it.hasNext()){
        Patient tmp = it.next();
        try{
          double debt = tmp.cureSickness(sickness);
          System.out.println(tmp.name+" was cured from "+sickness.toString());
          if(debt>0){
            Upr9.debtors.put(tmp, new Double(debt));
            System.out.println(tmp.name+" was put in the list of debtors with debt "+debt);
          }
        }
        catch(OutOfMoneyException oe){
          System.out.println(tmp.name+" has no money to pay for "+sickness.toString());
        }
        catch(NoSuchSicknessException nse){
          //System.out.println(tmp.name+" is not sick from "+sickness.toString());
        }
      }
    }

    System.out.println("\nLIST OF OUR DEBTORS:");
    for (Map.Entry<Patient, Double> entry : Upr9.debtors.entrySet()){
      Patient patient = entry.getKey();
      Double debt = entry.getValue();
      System.out.println(patient.name+" has debt "+debt.toString());
    }
  }
}

Допълнителна задача 1: Подходящо ли сме подбрали структурите от данни? Помислете за потенциални проблеми в съществуващата постановка на задачата, които биха възникнали в практиката.

Допълнителна задача 2: Правилно ли сме дефинирали (от чисто практическа гледна точка) методите equals и hashCode на клас Patient? Отново помислете за потенциални проблеми, които биха възникнали в практиката.

 



Добави коментар

Адресът на електронната поща няма да се публикува


*