Untitled

 avatar
unknown
plain_text
a year ago
8.1 kB
7
Indexable
package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.util.function.Function;

public class MainActivity extends AppCompatActivity {
    private Button[] numberButtons;
    private Button bdot, bpi, bequal, bplus, bminus, bdiv, bmul, bac, bc, bsqrt, bsquare, bfact, bln, bsin, bcos, btan, blog;
    private TextView tvsec, tvmain;
    private static final String PI = "3.14159265";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initializeViews();
        setButtonListeners();
    }

    private void initializeViews() {
        numberButtons = new Button[10];
        for (int i = 0; i < numberButtons.length; i++) {
            String buttonID = "b" + i;
            int resID = getResources().getIdentifier(buttonID, "id", getPackageName());
            numberButtons[i] = findViewById(resID);
        }

        bdot = findViewById(R.id.bdot);
        bpi = findViewById(R.id.bpi);
        bequal = findViewById(R.id.bequal);
        bplus = findViewById(R.id.bplus);
        bminus = findViewById(R.id.bminus);
        bdiv = findViewById(R.id.bdiv);
        bmul = findViewById(R.id.bmul);
        bac = findViewById(R.id.bac);
        bc = findViewById(R.id.bc);
        bsqrt = findViewById(R.id.bsqrt);
        bsquare = findViewById(R.id.bsquare);
        bfact = findViewById(R.id.bfact);
        bln = findViewById(R.id.bln);
        bsin = findViewById(R.id.bsin);
        bcos = findViewById(R.id.bcos);
        btan = findViewById(R.id.btan);
        blog = findViewById(R.id.blog);

        tvmain = findViewById(R.id.tvmain);
        tvsec = findViewById(R.id.tvsec);

        // Ensure text fits in TextView
        tvmain.setSelected(true);
    }

    private void setButtonListeners() {
        for (int i = 0; i < numberButtons.length; i++) {
            final int index = i;
            numberButtons[index].setOnClickListener(v -> appendToMain(String.valueOf(index)));
        }

        bdot.setOnClickListener(v -> appendToMain("."));
        bac.setOnClickListener(v -> clearAll());
        bc.setOnClickListener(v -> backspace());
        bplus.setOnClickListener(v -> appendToMain("+"));
        bminus.setOnClickListener(v -> appendToMain("-"));
        bdiv.setOnClickListener(v -> appendToMain("/"));
        bmul.setOnClickListener(v -> appendToMain("*"));
        bsqrt.setOnClickListener(v -> computeSingleArgumentFunction(Math::sqrt, "√"));
        bfact.setOnClickListener(v -> computeFactorial());
        bsquare.setOnClickListener(v -> computeSingleArgumentFunction(x -> x * x, "²"));
        bpi.setOnClickListener(v -> appendToMain(PI));
        bsin.setOnClickListener(v -> appendToMain("sin("));
        bcos.setOnClickListener(v -> appendToMain("cos("));
        btan.setOnClickListener(v -> appendToMain("tan("));
        bln.setOnClickListener(v -> appendToMain("ln("));
        blog.setOnClickListener(v -> appendToMain("log("));
        bequal.setOnClickListener(v -> evaluateExpression());
    }

    private void appendToMain(String str) {
        tvmain.append(str);
    }

    private void clearAll() {
        tvmain.setText("");
        tvsec.setText("");
    }

    private void backspace() {
        String val = tvmain.getText().toString();
        if (!val.isEmpty()) {
            val = val.substring(0, val.length() - 1);
            tvmain.setText(val);
        }
    }

    private void computeSingleArgumentFunction(Function<Double, Double> function, String symbol) {
        try {
            double val = Double.parseDouble(tvmain.getText().toString());
            double result = function.apply(val);
            tvmain.setText(formatResult(result));
            tvsec.setText(symbol + val);
        } catch (NumberFormatException e) {
            showToast("Invalid input for " + symbol);
        }
    }

    private void computeFactorial() {
        try {
            int val = Integer.parseInt(tvmain.getText().toString());
            int result = factorial(val);
            tvmain.setText(formatResult(result));
            tvsec.setText(val + "!");
        } catch (NumberFormatException e) {
            showToast("Invalid input for factorial");
        }
    }

    private int factorial(int n) {
        if (n < 0) return 0;
        return (n == 0 || n == 1) ? 1 : n * factorial(n - 1);
    }

    private void evaluateExpression() {
        String expression = tvmain.getText().toString();
        try {
            double result = eval(expression);
            tvmain.setText(formatResult(result));
            tvsec.setText(expression);
        } catch (Exception e) {
            showToast("Error in expression");
        }
    }

    private double eval(String str) {
        return new Object() {
            int pos = -1, ch;

            void nextChar() {
                ch = (++pos < str.length()) ? str.charAt(pos) : -1;
            }

            boolean eat(int charToEat) {
                while (ch == ' ') nextChar();
                if (ch == charToEat) {
                    nextChar();
                    return true;
                }
                return false;
            }

            double parse() {
                nextChar();
                double x = parseExpression();
                if (pos < str.length()) throw new RuntimeException("Unexpected: " + (char) ch);
                return x;
            }

            double parseExpression() {
                double x = parseTerm();
                for (;;) {
                    if (eat('+')) x += parseTerm();
                    else if (eat('-')) x -= parseTerm();
                    else return x;
                }
            }

            double parseTerm() {
                double x = parseFactor();
                for (;;) {
                    if (eat('*')) x *= parseFactor();
                    else if (eat('/')) x /= parseFactor();
                    else return x;
                }
            }

            double parseFactor() {
                if (eat('+')) return parseFactor();
                if (eat('-')) return -parseFactor();

                double x;
                int startPos = this.pos;
                if (eat('(')) {
                    x = parseExpression();
                    eat(')');
                } else if ((ch >= '0' && ch <= '9') || ch == '.') {
                    while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
                    x = Double.parseDouble(str.substring(startPos, this.pos));
                } else if ((ch >= 'a' && ch <= 'z')) {
                    while ((ch >= 'a' && ch <= 'z')) nextChar();
                    String func = str.substring(startPos, this.pos);
                    x = parseFactor();
                    if (func.equals("sqrt")) x = Math.sqrt(x);
                    else if (func.equals("sin")) x = Math.sin(Math.toRadians(x));
                    else if (func.equals("cos")) x = Math.cos(Math.toRadians(x));
                    else if (func.equals("tan")) x = Math.tan(Math.toRadians(x));
                    else if (func.equals("log")) x = Math.log10(x);
                    else if (func.equals("ln")) x = Math.log(x);
                    else throw new RuntimeException("Unknown function: " + func);
                } else {
                    throw new RuntimeException("Unexpected: " + (char) ch);
                }

                if (eat('^')) x = Math.pow(x, parseFactor());

                return x;
            }
        }.parse();
    }

    private void showToast(String message) {
        Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
    }

    private String formatResult(double result) {
        // This method limits the result to 10 decimal places to avoid overflow
        return String.format("%s", result);
    }
}
Editor is loading...
Leave a Comment