Implementação de Referência

Esta é uma implementação de referência das interfaces IEnquirer e IResponder que serão usadas no trabalho.

Ela também está montada sobre a lógica de componentes de software apresentada no notebook que está no diretório s04components.

Nessa implementação é criado um componente paciente Patient que sorteia uma das doenças e um componente doutor CrazyDoctor que tentará descobrir a doença.

Como o doutor é louco, ele apenas sorteia uma das doenças também. Apesar de fazer perguntas ao paciente, ele ignora as respostas e tenta advinhar a doença. Na maioria das vezes ele erra. Mas, lembre-se, essa não é a solução para o problema, é apenas uma implementação mostrando como se usa as interfaces e a lógica de componentes.

Interfaces relacionadas ao componente DataSet


In [1]:
public interface IDataSource {
  public String getDataSource();
  public void setDataSource(String dataSource);
}

public interface ITableProducer {
  String[] requestAttributes();
  String[][] requestInstances();
}

public interface ITableProducerReceptacle {
  public void connect(ITableProducer producer);
}

Componente DataSet


In [2]:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

public interface IDataSet extends IDataSource, ITableProducer {
}

public class DataSetComponent implements IDataSet {
  private String dataSource = null;
  private String[] attributes = null;
  private String[][] instances = null;
  
  public DataSetComponent() {
    /* nothing */
  }

  public String getDataSource() {
    return dataSource;
  }

  public void setDataSource(String dataSource) {
    this.dataSource = dataSource;
    if (dataSource == null) {
      attributes = null;
      instances = null;
    } else
      readDS();
  }
  
  public String[] requestAttributes() {
    return attributes;
  }
  
  public String[][] requestInstances() {
    return instances;
  }
  
  private void readDS() {
    ArrayList<String[]> instArray = new ArrayList<String[]>();
    try {
      BufferedReader file = new BufferedReader(new FileReader(dataSource));
        
      String line = file.readLine();
      if (line != null) {
        attributes = line.split(",");
        line = file.readLine();
        while (line != null) {
          String[] instLine = line.split(",");
          instArray.add(instLine);
          line = file.readLine();
        }
        instances = instArray.toArray(new String[0][]);
      }
        
      file.close();
    } catch (IOException erro) {
      erro.printStackTrace();
    }
  }
  
}

Interfaces de Referência

Estas são as três interfaces de referência IResponder, IResponderReceptacle e IEnquirer, que deverão ser usadas na sua solução. Elas não podem ser modificadas para a Parte 1 do trabalho.


In [3]:
public interface IResponder {
    public String ask(String question);
    public boolean finalAnswer(String answer);
}

public interface IResponderReceptacle {
    public void connect(IResponder responder);
}

public interface IEnquirer {
    public void startInterview();
}

Componente Patient

Implementação de referência de um componente Patient que é ligado ao componente DataSet (pela interface ITableProducerReceptacle) e implementa a interface IResponder. A interface IPatient foi criada para juntar a interface provida (IResponder) e a interface requerida (ITableProducerReceptacle).


In [4]:
import java.util.Random;

// combinando duas interfaces para IPatient
public interface IPatient extends IResponder, ITableProducerReceptacle {
}

public class Patient implements IPatient {
    private int patientN = 0;
    
    private ITableProducer producer;
    
    private String attributes[];
    private String patientInstance[];
    
    public void connect(ITableProducer producer) {
        this.producer = producer;

        attributes = producer.requestAttributes();
        String instances[][] = producer.requestInstances();

        patientN = (int)(Math.random() * instances.length);
        patientInstance = instances[patientN];
        
        System.out.println("Patient selected: " + patientN);
        System.out.println("Patient's disease: " + patientInstance[attributes.length - 1]);
    }
    
    public String ask(String question) {
        String result = "unknown";
        
        for (int a = 0; a < attributes.length - 1; a++)
            if (question.equalsIgnoreCase(attributes[a]))
                result = (patientInstance[a].equals("t")) ? "yes" : "no";
        
        return result;
    }

    public boolean finalAnswer(String answer) {
        boolean result = false;
        if (answer.equalsIgnoreCase(patientInstance[attributes.length - 1]))
            result = true;
        return result;
    }
}

Componente CrazyDoctor

Implementação de um médico louco. Este médico não faz o diagnóstico correto na maioria das vezes, mas usa as interfaces corretamente. Ele serve como referência para o uso das interfaces e componentes.

O componente CrazyDoctor que é ligado ao componente DataSet (pela interface ITableProducerReceptacle), é ligado ao componente Patient (pela interface IResponderReceptacle) e implementa a interface IEnquirer. A interface IDoctor foi criada para juntar a interface provida (IEnquirer) e as interfaces requeridas (IResponderReceptacle e ITableProducerReceptacle).


In [5]:
import java.util.Random;

// combinando duas interfaces para IPatient
public interface IDoctor extends IEnquirer, IResponderReceptacle, ITableProducerReceptacle {
}

public class CrazyDoctor implements IDoctor {
    private int patientN = 0;

    private ITableProducer producer;
    private IResponder responder;
  
    public void connect(ITableProducer producer) {
        this.producer = producer;
    }
    
    public void connect(IResponder responder) {
        this.responder = responder;
    }
        
    public void startInterview() {
        String attributes[] = producer.requestAttributes();
        String instances[][] = producer.requestInstances();

        patientN = (int)(Math.random() * instances.length);
        
        System.out.println("Doctor guess: " + patientN);
        
        for (int a = 0; a < attributes.length - 1; a++)
            System.out.println("Question: " + responder.ask(attributes[a]));

        System.out.println("Disease guess: " + instances[patientN][attributes.length - 1]);
        boolean result = responder.finalAnswer(instances[patientN][attributes.length - 1]);
        System.out.println("Result: " + ((result) ? "I am right =)" : "I am wrong =("));
    }
    
}

In [6]:
// instanciando o componente DataSet
IDataSet dataset = new DataSetComponent();
dataset.setDataSource("../../../db/zombie/zombie-health-spreadsheet-ml-training.csv");

// instanciando o componente paciente
IPatient aPatient = new Patient();

// conectando-o no componente DataSet
aPatient.connect(dataset);

// instanciando o componente doutor louco
IDoctor cDoctor = new CrazyDoctor();

// conectando-o ao componente DataSet
cDoctor.connect(dataset);

// conectando-o ao componente paciente
cDoctor.connect(aPatient);

// executando a entrevista
cDoctor.startInterview();


Patient selected: 5
Patient's disease: fights
Doctor guess: 4
Question: no
Question: no
Question: yes
Question: no
Question: no
Question: yes
Question: no
Disease guess: viral_infection
Result: I am wrong =(