This calculator code was written by ChatGPT.
The external design turned out fine.
The extension is also normally assembled by the Rush program.
But with the calculations, I was not able to get a positive result.
Let's take a simple example of 1+3 , the calculator gives the answer 13.0.
And so on, all simple calculations, with errors.
Do you have any idea how to fix this in this code?
@SimpleFunction(description = "1. The `Calculator` function is the entry point for invoking the calculator. It calls the `CalculatorText` function, passing an `identify` parameter.\n" +
"\n" +
"2. The `CalculatorText` function initializes the layout components and creates the calculator UI. It sets up the `AlertDialog.Builder`, creates a vertical `LinearLayout` as the main container for the calculator UI, and initializes the `expressionTextView` and `resultTextView` for displaying the expression and result.\n" +
"\n" +
"3. The `valuesHex` array stores the labels for the calculator buttons, including numbers, operators (+, -, *, /), and special buttons like \"DEL\" and \"=\".\n" +
"\n" +
"4. The function sets up the button layout using nested `LinearLayouts`. It iterates over the `valuesHex` array and creates `Button` objects for each label. It also dynamically adjusts the layout parameters based on the button label. Buttons with labels \"+\", \"=\", and \"DEL\" have a width of 2 units, while others have a width of 1 unit. This ensures that these buttons appear wider in the layout.\n" +
"\n" +
"5. Each button click is handled by an `OnClickListener`. When a button is clicked, the corresponding button label is retrieved. If the button label is \"=\", the expression is evaluated using the `evaluateExpression` function, and the result is displayed in the `resultTextView`. The expression and expression display are cleared for the next calculation. If the button label is \"DEL\", the last character of the expression is deleted. For other buttons, the corresponding label is appended to the expression, and the expression display is updated.\n" +
"\n" +
"6. The `evaluateExpression` function takes the expression as input, removes any non-digit characters except the decimal point, and then evaluates the expression using stacks for operators and operands. It splits the expression into numbers and operators, performs the necessary calculations, and returns the final result.\n" +
"\n" +
"7. The `hasPrecedence` function checks the precedence of two operators based on their order of evaluation.\n" +
"\n" +
"8. The `evaluateTopOperator` function performs the evaluation of the top operator in the stack and updates the operand stack accordingly.\n" +
"\n" +
"Overall, this code creates a calculator UI with dynamically sized buttons and handles button clicks to build and evaluate mathematical expressions. The expression and result are displayed in the respective text views.")
public void Calculator(final int identify) {
CalculatorText(identify);
}
private void CalculatorText(final int identify) {
// Define the buttons and their labels
String[] valuesHex = {"7", "8", "9", "/", "4", "5", "6", "*", "1", "2", "3", "-", ".", "0", "+", "+", "DEL", "="};
// Create a StringBuilder to store the input expression
StringBuilder expressionBuilder = new StringBuilder();
// Create the layout components
AlertDialog.Builder alert = new AlertDialog.Builder(this.activity);
LinearLayout layout = new LinearLayout(activity);
layout.setOrientation(LinearLayout.VERTICAL);
int screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;
int commonBlockWidth = (int) (screenWidth * 0.8); // Adjust the width as needed (e.g., 80% of the screen width)
LinearLayout.LayoutParams linear_fill_wrap = new LinearLayout.LayoutParams(
commonBlockWidth,
LinearLayout.LayoutParams.WRAP_CONTENT
);
// Create the TextView to display the expression and result
TextView expressionTextView = new TextView(activity);
expressionTextView.setLayoutParams(linear_fill_wrap);
expressionTextView.setGravity(Gravity.CENTER);
expressionTextView.setTextSize(24);
expressionTextView.setPadding(10, 6, 10, 22);
expressionTextView.setText(""); // Initially, no expression
layout.addView(expressionTextView);
TextView resultTextView = new TextView(activity);
resultTextView.setLayoutParams(linear_fill_wrap);
resultTextView.setGravity(Gravity.CENTER);
resultTextView.setTextSize(24);
resultTextView.setPadding(10, 6, 10, 22);
resultTextView.setText(""); // Initially, no result
layout.addView(resultTextView);
// Create the button layout
LinearLayout horizontalLayout = null;
int buttonCount = 0;
final int numberOfButtons = 4; // Number of buttons per row
for (int i = 0; i < valuesHex.length; i++) {
if (buttonCount % numberOfButtons == 0) {
horizontalLayout = new LinearLayout(activity);
horizontalLayout.setOrientation(LinearLayout.HORIZONTAL);
horizontalLayout.setWeightSum(numberOfButtons);
layout.addView(horizontalLayout, linear_fill_wrap);
}
Button button = new Button(activity);
button.setText(valuesHex[i]);
LinearLayout.LayoutParams buttonParams = new LinearLayout.LayoutParams(
0,
LinearLayout.LayoutParams.WRAP_CONTENT,
valuesHex[i].equals("+") || valuesHex[i].equals("=") || valuesHex[i].equals("DEL") ? 2 : 1
);
button.setLayoutParams(buttonParams);
int finalI = i;
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String buttonText = valuesHex[finalI];
if (buttonText.equals("=")) {
// Evaluate the expression and display the result
double result = evaluateExpression(expressionBuilder.toString());
resultTextView.setText(String.valueOf(result));
expressionBuilder.setLength(0); // Clear the expression
expressionTextView.setText(""); // Clear the expression display
} else if (buttonText.equals("DEL")) {
// Delete the last character from the expression
if (expressionBuilder.length() > 0) {
expressionBuilder.deleteCharAt(expressionBuilder.length() - 1);
expressionTextView.setText(expressionBuilder.toString());
}
} else {
expressionBuilder.append(buttonText);
expressionTextView.setText(expressionBuilder.toString());
}
}
});
horizontalLayout.addView(button);
buttonCount++;
}
alert.setMessage("Calculator");
alert.setView(layout);
alert.show();
}
private double evaluateExpression(String expression) {
// Remove any non-digit characters except for the decimal point
expression = expression.replaceAll("[^\\d.]", "");
// Create stacks for operators and operands
Stack<String> operatorStack = new Stack<>();
Stack<Double> operandStack = new Stack<>();
// Split the expression into numbers and operators
String[] tokens = expression.split("(?<=\\d)(?=\\D)|(?<=\\D)(?=\\d)");
for (String token : tokens) {
if (token.matches("[+\\-*/]")) {
// Operator
while (!operatorStack.empty() && hasPrecedence(token, operatorStack.peek())) {
evaluateTopOperator(operatorStack, operandStack);
}
operatorStack.push(token);
} else {
// Operand
operandStack.push(Double.parseDouble(token));
}
}
// Evaluate any remaining operators
while (!operatorStack.empty()) {
evaluateTopOperator(operatorStack, operandStack);
}
// The final result will be at the top of the operand stack
return operandStack.pop();
}
private boolean hasPrecedence(String op1, String op2) {
// Check operator precedence
return (op2.equals("*") || op2.equals("/")) && (op1.equals("+") || op1.equals("-"));
}
private void evaluateTopOperator(Stack<String> operatorStack, Stack<Double> operandStack) {
String operator = operatorStack.pop();
double operand2 = operandStack.pop();
double operand1 = operandStack.pop();
switch (operator) {
case "+":
operandStack.push(operand1 + operand2);
break;
case "-":
operandStack.push(operand1 - operand2);
break;
case "*":
operandStack.push(operand1 * operand2);
break;
case "/":
operandStack.push(operand1 / operand2);
break;
}
}