简体   繁体   中英

I want to make a 2D array with processing

I'm trying to make a simple quiz app by reading data from a txt file. I don't know how to handle the data.

questions.txt

questionA?,2,choicesA-1,achoicesA-2,choicesA-3,choicesA-4
questionB?,3,choicesB-1,choicesB-2,choicesB-3,choicesB-4
questionC?,4,choicesC-1,choicesC-2,choicesC-3,choicesC-4

training.pde

String lin;
int ln;
String lines[];

void setup() {
  size(500, 500);
  background(255);

  ln=0;
  lines = loadStrings("questions.txt");
}

void draw() {
  lin =lines[ln];
  String[] co = split(lin, ',');
   println(co[0]);
   println(co[1]);
  ln++;
  if (ln == lines.length) noLoop();
}

I want to make a 2D array..

   println(co[0][0]); //questionA?
   println(co[0][1]); //2

You can use to load and read lines. Store each line in an Arraylist:

List<String> lines = Collections.emptyList(); 
try {
    lines =  Files.readAllLines(Paths.get(fileName), StandardCharsets.UTF_8); 
} catch (IOException e) {
    // do something
    e.printStackTrace();
} 

Now for each line in Arraylist, You can split them using the delimeter ',' and do whatever you want with the words:

 for (String line: lines) {
     String[] words = Arrays.stream(line.split(",")).map(String :: trim).toArray();
     System.out.println("Question: " + words[0] + ", Choices: " + words[1] + " " + words[2] + " " + words[3] + " " + words[4]);
 }

You can use something like this:

String filename = "path_to_file";
File file = new File(filename);
Scanner data = new Scanner(file);

String line;
List<String[]> questions = new ArrayList<>();
while (data.hasNextLine()) {
     line = data.nextLine();
     questions.add(line.split(","));
}

As you can see, questions is a list of arrays of strings. Every element of that list corresponds to one line of your file and you can access a line with questions.get(index). You can also get a specific element of a line with the standard array notation

eg with the example you provided, questions.get(1)[2] will return choicesB-1

Keep in mind that reading data from plain text (.txt) will always get you a headache. You should use formats like JSON or YAML to store your data, a good parser is already available with those.

The String parsing options Alberto and devReddit suggested are good (+1).

I'd like to propose restructuring the data as a JSON array :

[
    {
      "question":"Question A ?",
      "options": [
        "choicesA-1",
        "choicesA-2",
        "choicesA-3",
        "choicesA-4"
        ],
      "selectedIndex":-1,
      "correctIndex":1
    },
    {
      "question":"Question B ?",
      "options": [
        "choicesB-1",
        "choicesB-2",
        "choicesB-3",
        "choicesB-4"
        ],
      "selectedIndex":-1,
      "correctIndex":2
    },
    {
      "question":"Question C ?",
      "options": [
        "choicesC-1",
        "choicesC-2",
        "choicesC-3",
        "choicesC-4"
        ],
      "selectedIndex":-1,
      "correctIndex":3
    }
  ]

If you save it in a new sketch folder as questionnaire.json you could load it and parse (as well as check) the answers with something like this:

// stores currently loaded questions
JSONArray questions;
// the index of the current question
int currentQuestionIndex = 0;
// the questionnaire data at this index (question, options, correct answer(as index), selected answer(as index)) 
JSONObject currentQuestionData;

void setup() {
  size(400, 400);
  // load data
  try {
    questions = loadJSONArray("questionnaire.json");
  }
  catch(Exception e) {
    println("error loading JSON data");
    e.printStackTrace();
    exit();
  }
}

void draw() {
  // get the current question data
  currentQuestionData = questions.getJSONObject(currentQuestionIndex);
  // access the choices associated with this question
  JSONArray currentQuestionOptions = currentQuestionData.getJSONArray("options");

  background(0);
  // render the question
  text(currentQuestionData.getString("question"), 10, 15);
  // ...and the choices
  for (int i = 0; i < currentQuestionOptions.size(); i++) {
    text(currentQuestionOptions.getString(i), 10, 35 + (20 * i));
  }
  // testing view:
  // render user selected index
  text("selected: " + currentQuestionData.getInt("selectedIndex"), 10, 120);
  // render correct index (and choice text)
  text("correct: " + currentQuestionData.getInt("correctIndex") + " = " + currentQuestionOptions.getString(currentQuestionData.getInt("correctIndex")), 10, 150);
  // render match condition (result) 
  text("match: " + (currentQuestionData.getInt("selectedIndex") == currentQuestionData.getInt("correctIndex")), 10, 180);
}

void keyPressed() {
  // control question with left/right keys
  if (keyCode == LEFT && currentQuestionIndex > 0) currentQuestionIndex--;
  if (keyCode == RIGHT && currentQuestionIndex < questions.size() - 1) currentQuestionIndex++;
  // set user answers on 1,2,3,4 keys
  if (key == '1') currentQuestionData.setInt("selectedIndex", 0);
  if (key == '2') currentQuestionData.setInt("selectedIndex", 1);
  if (key == '3') currentQuestionData.setInt("selectedIndex", 2);
  if (key == '4') currentQuestionData.setInt("selectedIndex", 3);
}

It's quite a bit of code, because on top of showing how to parse and render the question/choices, it also demonstrates how to test go through the questions using left/right keys as well as test arrows with 1,2,3,4 keys. Hopefully the comments illustrate the functionality.

The decision to store the user selected choice index is optional, more of an idea. It might be useful to store quiz results later (which saveJSONArray() can help with).

Another option might be to store the data as a CSV table which Processing can easily parse using loadTable() .

Personally I find the JSON format more flexible, even though it's more verbose: you can use a tree structure / questions with different number of options, etc. where as the CSV table is limited to being a table.

Last remark when loading/saving strings: pay attention to special characters.

Have fun!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM