10 月20日

杨家兴發表於2024-10-20

週一Java課上留的課後習題程式碼:
import javax.swing.;
import java.awt.
;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

abstract class ProblemGenerator {
protected int maxOperands;
protected int numberRange;
protected boolean allowMultiplicationAndDivision;
protected boolean includeParentheses;
protected Random random;

public ProblemGenerator(int maxOperands, int numberRange, boolean allowMultiplicationAndDivision, boolean includeParentheses) {
    this.maxOperands = maxOperands;
    this.numberRange = numberRange;
    this.allowMultiplicationAndDivision = allowMultiplicationAndDivision;
    this.includeParentheses = includeParentheses;
    this.random = new Random();
}

public abstract String generateProblem();

protected double getRandomNumber() {
    return random.nextInt(numberRange) + 1;
}

protected char getRandomOperation() {
    char[] operations = {'+', '-', '*', '/'};
    char op = operations[random.nextInt(operations.length)];
    if (!allowMultiplicationAndDivision && (op == '*' || op == '/')) {
        return '+';
    }
    return op;
}

}

class SecondGradeProblemGenerator extends ProblemGenerator {
public SecondGradeProblemGenerator() {
super(2, 100, true, false);
}

@Override
public String generateProblem() {
    int num1 = (int) getRandomNumber();
    int num2 = (int) getRandomNumber();
    char operation = getRandomOperation();
    if (operation == '/') {
        while (num2 == 0 || num1 % num2 != 0) {
            num1 = (int) getRandomNumber();
            num2 = (int) getRandomNumber();
        }
    }
    return String.format("%d %c %d", num1, operation, num2);
}

}

class ThirdGradeProblemGenerator extends SecondGradeProblemGenerator {
public ThirdGradeProblemGenerator() {
super();
this.maxOperands = 4;
this.numberRange = 1000;
}

@Override
public String generateProblem() {
    StringBuilder problem = new StringBuilder();
    int operands = random.nextInt(maxOperands - 1) + 2;
    for (int i = 0; i < operands; i++) {
        problem.append((int) getRandomNumber());
        if (i < operands - 1) {
            problem.append(" ").append(getRandomOperation()).append(" ");
        }
    }
    return problem.toString();
}

}

class FourthGradeProblemGenerator extends ThirdGradeProblemGenerator {
public FourthGradeProblemGenerator() {
super();
this.maxOperands = 5;
this.includeParentheses = true;
}

@Override
public String generateProblem() {
    StringBuilder problem = new StringBuilder();
    int operands = random.nextInt(maxOperands - 1) + 2;
    for (int i = 0; i < operands; i++) {
        if (includeParentheses && random.nextBoolean()) {
            problem.append("(");
        }
        problem.append((int) getRandomNumber());
        if (includeParentheses && random.nextBoolean()) {
            problem.append(")");
        }
        if (i < operands - 1) {
            problem.append(" ").append(getRandomOperation()).append(" ");
        }
    }
    return problem.toString();
}

}

public class MathQuizAppGUI {
private JFrame frame;
private JTextArea questionArea;
private JTextField answerField;
private JTextArea resultArea;
private JComboBox gradeSelector;
private ProblemGenerator problemGenerator;
private List mistakes = new ArrayList<>();
private List problems = new ArrayList<>();
private int correctCount = 0;
private int totalCount = 0;

public MathQuizAppGUI() {
    initComponents();
}

private void initComponents() {
    frame = new JFrame("Math Quiz");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(800, 600);
    frame.setLayout(new BorderLayout());

    JPanel topPanel = new JPanel();
    topPanel.setLayout(new GridLayout(2, 1));
    JLabel titleLabel = new JLabel("Math Quiz", JLabel.CENTER);
    titleLabel.setFont(new Font("Arial", Font.BOLD, 32));
    topPanel.add(titleLabel);

    String[] grades = {"Select Grade", "Second Grade", "Third Grade", "Fourth Grade"};
    gradeSelector = new JComboBox<>(grades);
    gradeSelector.setFont(new Font("Arial", Font.PLAIN, 24));
    gradeSelector.addActionListener(e -> gradeChanged());
    topPanel.add(gradeSelector);

    frame.add(topPanel, BorderLayout.NORTH);

    questionArea = new JTextArea(10, 20);
    questionArea.setEditable(false);
    questionArea.setFont(new Font("Arial", Font.PLAIN, 24));
    frame.add(new JScrollPane(questionArea), BorderLayout.CENTER);

    answerField = new JTextField();
    answerField.setFont(new Font("Arial", Font.PLAIN, 24));
    frame.add(answerField, BorderLayout.SOUTH);

    JPanel buttonPanel = new JPanel();
    JButton submitButton = new JButton("Submit Answer");
    submitButton.setFont(new Font("Arial", Font.PLAIN, 18));
    submitButton.addActionListener(new SubmitActionListener());
    buttonPanel.add(submitButton);

    JButton nextProblemButton = new JButton("Next Problem Set");
    nextProblemButton.setFont(new Font("Arial", Font.PLAIN, 18));
    nextProblemButton.addActionListener(e -> generateNewProblemSet(10));
    buttonPanel.add(nextProblemButton);

    frame.add(buttonPanel, BorderLayout.EAST);

    resultArea = new JTextArea(10, 20);
    resultArea.setEditable(false);
    frame.add(new JScrollPane(resultArea), BorderLayout.WEST);

    frame.setVisible(true);
}

private void gradeChanged() {
    String selectedGrade = (String) gradeSelector.getSelectedItem();
    switch (selectedGrade) {
        case "Second Grade":
            problemGenerator = new SecondGradeProblemGenerator();
            break;
        case "Third Grade":
            problemGenerator = new ThirdGradeProblemGenerator();
            break;
        case "Fourth Grade":
            problemGenerator = new FourthGradeProblemGenerator();
            break;
        default:
            problemGenerator = null;
            return;
    }
    generateNewProblemSet(10);
}

private void generateNewProblemSet(int count) {
    if (problemGenerator == null) {
        JOptionPane.showMessageDialog(frame, "Please select a grade level first.", "Error", JOptionPane.ERROR_MESSAGE);
        return;
    }

    problems.clear();
    for (int i = 0; i < count; i++) {
        problems.add(problemGenerator.generateProblem());
    }
    displayProblems();
}

private void displayProblems() {
    StringBuilder displayText = new StringBuilder();
    for (int i = 0; i < problems.size(); i++) {
        displayText.append((i + 1)).append(". ").append(problems.get(i)).append("\n");
        if ((i + 1) % 3 == 0) {
            displayText.append("\n");
        }
    }
    questionArea.setText(displayText.toString());
}

private class SubmitActionListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        String userAnswers = answerField.getText();
        String[] answers = userAnswers.split("\\s+");
        if (answers.length != problems.size()) {
            JOptionPane.showMessageDialog(frame, "Please answer all questions!", "Error", JOptionPane.ERROR_MESSAGE);
            return;
        }

        resultArea.setText("");
        correctCount = 0;
        totalCount = problems.size();
        StringBuilder results = new StringBuilder();

        for (int i = 0; i < problems.size(); i++) {
            double correctAnswer = evaluateExpression(problems.get(i));
            try {
                double userAnswer = Double.parseDouble(answers[i]);
                if (Math.abs(userAnswer - correctAnswer) < 1e-9) {
                    correctCount++;
                    results.append("Correct: ").append(problems.get(i)).append(" = ").append(userAnswer).append("\n");
                } else {
                    mistakes.add(problems.get(i));
                    results.append("Wrong: ").append(problems.get(i)).append(" = ").append(correctAnswer).append("\n");
                }
            } catch (NumberFormatException ex) {
                mistakes.add(problems.get(i));
                results.append("Invalid input for ").append(problems.get(i)).append("\n");
            }
        }

        resultArea.setText(results.toString());
        double accuracy = ((double) correctCount / totalCount) * 100;
        JOptionPane.showMessageDialog(frame, "You got " + correctCount + " out of " + totalCount + " correct!\nAccuracy: " + accuracy + "%", "Results", JOptionPane.INFORMATION_MESSAGE);

        saveProblemsToFile();
    }
}

private void saveProblemsToFile() {
    try (BufferedWriter writer = new BufferedWriter(new FileWriter("problems.txt"))) {
        for (String problem : problems) {
            writer.write(problem + "\n");
        }
        JOptionPane.showMessageDialog(frame, "Problems saved to problems.txt", "Saved", JOptionPane.INFORMATION_MESSAGE);
    } catch (IOException e) {
        e.printStackTrace();
        JOptionPane.showMessageDialog(frame, "Failed to save problems", "Error", JOptionPane.ERROR_MESSAGE);
    }
}

private double evaluateExpression(String expr) {
    String[] tokens = expr.split(" ");
    double result = Double.parseDouble(tokens[0]);
    int index = 1;
    while (index < tokens.length) {
        String operator = tokens[index++];
        double nextNum = Double.parseDouble(tokens[index++]);
        switch (operator) {
            case "+":
                result += nextNum;
                break;
            case "-":
                result -= nextNum;
                break;
            case "*":
                result *= nextNum;
                break;
            case "/":
                result /= nextNum;
                break;
        }
    }
    return result;
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(MathQuizAppGUI::new);
}

}