C, PHP, VB, .NET

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


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

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

Задачата е за подготовка за контролна работа. Даден е файл с математически задачи, който има следната структура (показано е примерно съдържание):

 Автор: Иван Иванов
 Предмет: Математика
 Клас: 8
 Тема: Квадратни уравнения
 Условие: Решете уравнението x^2+2x-3=0
 Верен отговор: x1=-3, x2=1
 Дистрактор 1: x1=3, x2=1
 Дистрактор 2: x1=3, x2=-1
 Дистрактор 3: x1=-3, x2=-1
 Дистрактор 4: x1=1, x2=1
 .
 Автор: …

Задача 1. Напишете клас “MathProblem”, който отразява структурата на зададения файл. Трябва да съдържа име (name) и фамилия (family_name) на автора, име на учебния предмет (subject), клас (class) от тип int, тема (topic), условие на задачата (description), верен отговор (correct_answer) и 4 дистрактори (distractor1, distractor2, …). Погрижете се класа да е число от 1 до 12. Погрижете се верния отговор и дистракторите да са различни. В случай на некоректен клас или повторения в отговор и/или дистрактори, да се връща изключение MathException. Класът MathProblem трябва да е immutable (веднъж създадена задача, да не може да се променя). Не пишете всички get методи – напишете за първите три член променливи и уточнете, че другите се реализират по аналогия. Направете метод void print(), който отпечатва съдържанието на задача в конзолата.

Задача 2. Напишете клас MathException, който кореспондира с употребата му в задача 1.

Задача 3. Напишете клас MathProblemsUtility, който няма конструктор и член променливи, а съдържа един единствен не-private статичен метод parseFile с входен параметър String – име на файл – и изходен параметър масив от задачи. Методът трябва да извършва следните действия:

  • Отвраря файла и преброява колко задачи има в него. Записва това в променлива int problemsCount;
  • Създава масив MathProblem[] problems с брой елементи problemsCount;
  • Обхожда файла и записва всяка задача в масива. Ако за дадена задача се получи проблем с информацията (нещо във формата на файла не отговаря), задачата да бъде пропусната;
  • Ако не е запълнен целия масив, да се премахнат празните клетки;
  • Връща масива.

Задача 4. Демонстрирайте функционалностите в клас с main метод

Решение: Всички класове се записват във файл Upr8.java:

Клас Upr8

import java.io.*;
import java.util.*;

public class Upr8{
  public static void main(String[] args){
    try{
      MathProblem[] problems = MathProblemsUtility.parseFile("problems.txt");
      for(MathProblem mp: problems) mp.print();
    }
    catch(MathException e){
      System.out.println(e.getMessage());
    }
    catch(IOException e2){
      System.out.println(e2.getMessage());
    }
  }
}

Клас MathProblem

class MathProblem{
  private String name;
  private String familyName;
  private String subject;
  private int klas;
  private String topic;
  private String description;
  private String correct_answer;
  private String distractor1;
  private String distractor2;
  private String distractor3;
  private String distractor4;
  
  MathProblem(String name, String familyName, String subject, int klas, String topic, String description, 
              String correct_answer, String distractor1, String distractor2, String distractor3, 
              String distractor4)  throws MathException{
    this.name=name;
    this.familyName=familyName;
    this.subject=subject;
    this.setKlas(klas);
    this.topic=topic;
    this.description=description;
    this.setAnswers(correct_answer, distractor1, distractor2, distractor3, distractor4);
  }
  
  private void setKlas(int klas) throws MathException{
    if(klas<1 || klas>12) throw new MathException("Класът трябва да е от 1 до 12. Вие въведохте: "+klas);
    this.klas = klas;
  }
  
  private void setAnswers(String...answers) throws MathException{
    if(answers.length!=5) throw new MathException("Непредвиден проблем с дистракторите");
    for(int i=0; i<4; i++){
      for(int j=i+1; j<5; j++){
        if(answers[i].equals(answers[j])) throw new MathException("Еднакви отговори: "+answers[i]);
      }
    }
    this.correct_answer = answers[0];
    this.distractor1 = answers[1];
    this.distractor2 = answers[2];
    this.distractor3 = answers[3];
    this.distractor4 = answers[4];
  }
  
  String getName(){
    return this.name;
  }  
  String familyName(){
    return this.familyName;
  }  
  String getSubject(){
    return this.subject;
  }  
  int getKlas(){
    return this.klas;
  }  
  String getTopic(){
    return this.topic;
  }  
  String getDescription(){
    return this.description;
  }  
  String getCorrect_answer(){
    return this.correct_answer;
  }  
  String getDistractor1(){
    return this.distractor1;
  }  
  String getDistractor2(){
    return this.distractor2;
  }  
  String getDistractor3(){
    return this.distractor3;
  }  
  String getDistractor4(){
    return this.distractor4;
  }
  
  void print(){
    System.out.println("Автор: "+this.name+" "+this.familyName);
    System.out.println("Предмет: "+this.subject);
    System.out.println("Клас: "+this.klas);
    System.out.println("Тема: "+this.topic);
    System.out.println("Условие: "+this.description);
    System.out.println("Верен отговор: "+this.correct_answer);
    System.out.println("Дистрактор 1: "+this.distractor1);
    System.out.println("Дистрактор 2: "+this.distractor2);
    System.out.println("Дистрактор 3: "+this.distractor3);
    System.out.println("Дистрактор 4: "+this.distractor4);
  }
}

Клас MathException

class MathException extends Exception{
    MathException(){
        super("Задачата е с невалиден формат");
    }
    MathException(String msg){
        super(msg);
    }
}

Клас MathProblemsUtility

class MathProblemsUtility{
  static MathProblem[] parseFile(String file) throws MathException,IOException{
    int problemsCount = getProblemsCount(file);
    if(problemsCount==0) throw new IOException("Не открих задачи във файла");
    
    MathProblem[] problems = new MathProblem[problemsCount];
    Scanner sc = new Scanner(new FileReader(file));
    parser: for(int i=0; i<problems.length; i++){
      String name="";
      String familyName="";
      String subject="";
      int klas=0;
      String topic="";
      String description="";
      String correct_answer="";
      String distractor1="";
      String distractor2="";
      String distractor3="";
      String distractor4="";
      String line;
      while(!(line = sc.nextLine()).equals(".")){
        String[] lineSplit = line.split(": ", 2);
        if(lineSplit.length!=2){
          gotoNextProblem(sc);
          continue parser;
        }
        switch(lineSplit[0]){
          case "Автор":
            String[] nameSplit = lineSplit[1].split(" ", 2);
            if(nameSplit.length!=2){
              gotoNextProblem(sc);
              continue parser;
            }
            name = nameSplit[0];
            familyName = nameSplit[1];
            break;
          case "Предмет":
            subject = lineSplit[1];
            break;
          case "Клас":
            try{
              klas = Integer.parseInt(lineSplit[1]);
            }
            catch(NumberFormatException e){
              gotoNextProblem(sc);
              continue parser;
            }
            break;
          case "Тема":
            topic = lineSplit[1];
            break;
          case "Условие":
            description = lineSplit[1];
            break;
          case "Верен отговор":
            correct_answer = lineSplit[1];
            break;
          case "Дистрактор 1":
            distractor1 = lineSplit[1];
            break;
          case "Дистрактор 2":
            distractor2 = lineSplit[1];
            break;
          case "Дистрактор 3":
            distractor3 = lineSplit[1];
            break;
          case "Дистрактор 4":
            distractor4 = lineSplit[1];
            break;
        }
      }
      try{
        problems[i] = new MathProblem(name, familyName, subject, klas, topic, description, 
                                      correct_answer, distractor1, distractor2, distractor3, distractor4);
      }
      catch(MathException e1){}
    }
    
    int validProblems = 0;
    for(MathProblem mp: problems){
      if(mp!=null) validProblems++;
    }
    MathProblem[] result = new MathProblem[validProblems];
    int i=0;
    for(MathProblem mp: problems){
      if(mp!=null){
        result[i] = mp;
        i++;
      }
    }
    return result;
  }
  
  private static int getProblemsCount(String file) throws IOException{
    int problemsCount = 0;
    Scanner sc = new Scanner(new FileReader(file));
    while(sc.hasNext()){
      if(sc.nextLine().equals(".")) problemsCount++;
    }
    sc.close();
    return problemsCount;
  }
  
  private static void gotoNextProblem(Scanner sc){
    String line;
    while(!(line = sc.nextLine()).equals(".")){}
  }
}

Примерен файл problems.txt:

Автор: Иван Иванов
Предмет: Математика
Клас: 8
Тема: Квадратни уравнения
Условие: Решете уравнението x^2+2x-3=0
Верен отговор: x1=-3, x2=1
Дистрактор 1: x1=3, x2=1
Дистрактор 2: x1=3, x2=-1
Дистрактор 3: x1=-3, x2=-1
Дистрактор 4: x1=1, x2=1
.
Автор: Петър Петров
Предмет: Математика
Клас: 8
Тема: Квадратни уравнения
Условие: Решете уравнението x^2+x-2=0
Верен отговор: x1=-2, x2=1
Дистрактор 1: x1=2, x2=1
Дистрактор 2: x1=2, x2=-1
Дистрактор 3: x1=-2, x2=-1
Дистрактор 4: x1=2, x2=2
.
Автор: Тодор Димитров
Предмет: Математика
Клас: 8
Тема: Квадратни уравнения
Условие: Решете уравнението -x^2+2x=0
Верен отговор: x1=0, x2=2
Дистрактор 1: x1=0, x2=-2
Дистрактор 2: x1=1, x2=2
Дистрактор 3: x1=0, x2=1
Дистрактор 4: x1=-1, x2=-2
.

Допълнителна задача: Потърсете начини да „счупите“ парсъра на задачи. Предложете подобрения спрямо намереното.

 



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

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


*