I'm new to Android. I'm trying to develop my first calculator. My calculator output is good, but I'm trying to make some changes to it. Please suggest. My output is 2+2=4.0 How can I get 4 if I put 2+2 and 4.0 when I put 2.8+1.2.
Also, please help me out in trying to figure out how can i keep on adding till i press =.
My code that I'm looking at is below:
private View.OnClickListener buttonClickListerner = new
View.OnClickListener() {
float r;
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.clear:
screen.setText("");
operator.setText("");
FirstNum= 0;
showtext.setText("");
break;
case R.id.buttonAdd:
mMath("+");
operator.setText("+");
showtext.setText(String.valueOf(FirstNum));
break;
case R.id.buttonMinus:
mMath("-");
operator.setText("-");
break;
case R.id.buttonMul:
mMath("*");
operator.setText("*");
break;
case R.id.buttonequal:
mResult();
break;
case R.id.buttonDiv:
mMath("/");
operator.setText("/");
break;
case R.id.buttonPercent:
mMath("%");
r = FirstNum / 100;
showtext.setText("[" + String.valueOf(FirstNum) + "%" + "]");
screen.setText(String.valueOf(r));
break;
default:
String num = ((Button) v).getText().toString();
getKeyboard(num);
break;
}
}
};
public void mMath(String str){
FirstNum = Float.parseFloat(screen.getText().toString());
operation = str;
screen.setText("");
}
public void getKeyboard(String str){
String CurrentScreen = screen.getText().toString();
if(CurrentScreen.equals("0"))
CurrentScreen = "";
CurrentScreen = CurrentScreen + str;
screen.setText(CurrentScreen);
String ExScreen = CurrentScreen;
screen.setText(ExScreen);
}
public void mResult(){
float SecondNum = Float.parseFloat(screen.getText().toString());
float ThirdNum = Float.parseFloat(screen.getText().toString());
float result = 0;
//float exresult = result;
if(operation.equals("+")){
result = FirstNum + SecondNum;
// exresult = result + ThirdNum;
}
if(operation.equals("-")){
result = FirstNum - SecondNum;
//exresult = result - ThirdNum;
}
if(operation.equals("*")){
result = FirstNum * SecondNum;
//exresult = result * ThirdNum;
}
if(operation.equals("/")){
result = FirstNum / SecondNum;
//exresult = result / ThirdNum;
}
screen.setText(String.valueOf(result));
//screen.setText(String.valueOf(exresult));
showtext.setText(String.valueOf(FirstNum + operation + SecondNum));
//showtext.setText(String.valueOf(FirstNum + operation + SecondNum +
operation + ThirdNum));
}
}
I guess you should do your calculations as double and then before setting the output to TextView (or whatever you are using), check for the output if int or not and then decide which form of output to set to the TextView.
if ((variable == Math.floor(variable)) && !Double.isInfinite(variable)) {
// integral type
}
See this
Edit:
The idea is to check that fractional part of the number is 0 (i.e.) the number is integer.
You may also Use these conditions [if true then variable is an Integer]
// check if
variable == Math.ceil(variable)
or
// check if
variable == Math.round(variable)
Also Math.round(float f) will return the interger form of the number!
To add multiple item first set up an array with a size of how long the user can input and then loop through each array adding them equivalently... i know this is a vague answer but you can ask me if anything is unclear and also an up vote would be nice. you got the right idea for the cases just try the following code
// array to sum
int[] numbers = new int[]{ 10, 10, 10, 10};
int sum = 0;
for (int i=0; i < numbers.length ; i++) {
sum = sum + numbers[i];
}
System.out.println("Sum value of array elements is : " + sum);
}
Related
So I have a String[] which contains math expressions like "3+6=" or "5+9/8=".
I have a function that gets the array, loops through the array and while looping, it splits the array so that I have one String[] containing the math operations like +,-,*,/ and another int[] containing the numbers in the question.
The function then puts the the answer into a int[] called answers. My question is that why when I output the answers[0], I can only see the first number and not the answer to the first question?
EDIT = I have found out that where the problem is happening. It is happening in my evaluation method. I dont know why:
public int evaluateAnswerTwoOperations(String operation, int numberOne, int numberTwo) {
switch(operation){
case "+":
Log.d("usingsubtraction","plus2nmbers");
return numberOne + numberTwo;
case "-":
Log.d("usingsubtraction","usingsubtraction");
return numberOne - numberTwo;
case "/":
Log.d("usingsubtraction","usingdivision");
return numberOne / numberTwo;
default:
Log.d("usingsubtraction","usingmultiplication");
return numberOne*numberTwo;
}
Something like this:
import android.util.Log;
public class TwoNumberOperation {
private final String PLUS = "+";
private final String MINUS = "-";
private final String MULTIPLY = "*";
private final String DIVIDE = "/";
private final String EQUAL = "=";
private String operation;
private int numberOne;
private int numberTwo;
public TwoNumberOperation(String operation, int numberOne, int numberTwo) {
if (operation.equalsIgnoreCase(PLUS) ||
operation.equalsIgnoreCase(MINUS) ||
operation.equalsIgnoreCase(MULTIPLY) ||
operation.equalsIgnoreCase(DIVIDE)) {
this.operation = operation;
this.numberOne = numberOne;
this.numberTwo = numberTwo;
}
else {
Log.d("error", "error: invalid operation");
this.operation = "";
this.numberOne = 0;
this.numberTwo = 0;
}
}
public int getAnswer() {
switch (operation) {
case PLUS:
Log.d("addition", "addition");
return numberOne + numberTwo;
case MINUS:
Log.d("subtraction", "subtraction");
return numberOne - numberTwo;
case MULTIPLY:
Log.d("multiplication", "multiplication");
return numberOne / numberTwo;
case DIVIDE:
Log.d("division", "division");
return numberOne / numberTwo; // note the returning an int
default:
Log.d("error", "error");
return -999999999;
}
}
#Override
public String toString() {
return numberOne + operation + numberTwo + EQUAL;
}
}
I have this button which calls two methods. See Code; Now i have tried to add a method on my onPictureSubmit(v) method which will print a Toast message (Please Submit Answer) if someone clicked the button without submitting an answer. Problem is it keeps crushing. Any help on how i can detect someone clicked the button without submitting answer will be appreciated.
My Button Code;
#Override
public void onClick(View v) {
switch (pass) {
case 0:
onDefinitionSubmit(v);
break;
case 1:
onPictureSubmit(v);
break;
case 2
break;
}
}
My Code :
private void onPictureSubmit(View v) {
if (v.getId() == R.id.picture_submit) {
final int answerGiven = Integer.parseInt("" + ((EditText) findViewById(R.id.picture_answer)).getText());
final int answerKey = com.madonasystematixnote.mathhelper.lessons.PictureFragment.answer;
final int x = Integer.parseInt("" + ((TextView) findViewById(R.id.picture_x)).getText());
final int y = Integer.parseInt("" + ((TextView) findViewById(R.id.picture_y)).getText());
}
}
If I were you I'd declare the TextView, EditText, Button as a global variable, and then in your onCreate() I'd use the findViewById() to avoid NullPointerException.
Second, I'd check if the answerGiven (I guess is the answer) it's empty, so I'd create a method that returns me if it's empty or not the EditText.
public boolean isEtEmpty(String str){
if(str.isEmpty() || str.length() == 0 || str.equals("") || str == null){
return true;
}
else{
return false;
}
}
Then at the time you call onPictureSubmit() call this method doing this :
if (v.getId() == R.id.picture_submit) {
if (isEtEmpty(picture_answer.getText())){ //picture_answer is the EditText that you want to know if it's empty or not
Toast.makeText(v.getContext(), "Please Submit Answer",Toast.LENGTH_LONG).show();
}
else{
final int answerGiven = Integer.parseInt("" + ((EditText) findViewById(R.id.picture_answer)).getText());
final int answerKey = com.madonasystematixnote.mathhelper.lessons.PictureFragment.answer;
final int x = Integer.parseInt("" + ((TextView) findViewById(R.id.picture_x)).getText());
final int y = Integer.parseInt("" + ((TextView) findViewById(R.id.picture_y)).getText());
}
}
I'm having a hard time getting the childobjects of a listview. So, there are multiple objects in it, visible and not yet visible. When I ask for the size, it returns 5 (those 5 are the visible ones).
I tried to scroll the list view from the bottom item to the top item and store those items but than I face the issue that items from other parts in the listview are recognized. Another method that I tried is to scroll the last item a little bit up, until the new item becomes visible. But here I face the issue that a whole other items text is recognized when the item is scrolled.
The code for the first method:
Within this code, I take the listviews childObjects, iterate through them and store all the textfields. When I do this, some textfields of other items are mixed which makes it unusable.
List AccountList;
ArrayList<String> AccountArray = new ArrayList<String>();
String tempAccountInfo = "";
String AccountType="";
String LastItem = "";
String NewLastItem = "N/A";
List<WebElement> AccountListItems;
AccountList = driver.findElements(getObject("ElementsWithinAccountListView"));
AccountListItems = AccountList.get(AccountList.size() - 1).findElements(By.className("android.widget.TextView"));
while (!NewLastItem.equals(LastItem)) {
for (int i=0; i<AccountList.size();i++){
AccountList = driver.findElements(getObject("ElementsWithinAccountListView"));
AccountListItems = AccountList.get(i).findElements(By.className("android.widget.TextView"));
switch (AccountList.get(i).getAttribute("className")){
case "android.widget.LinearLayout":
if (!AccountListItems.get(0).getText().contains("New ")){
switch(AccountListItems.get(0).getText()){
case "Current accounts":
AccountType = "Current accounts";
break;
case "Savings accounts":
AccountType = "Saving accounts";
break;
case "Investments":
AccountType = "Investments";
break;
case "Credit cards":
AccountType = "Credit cards";
break;
case "Other":
AccountType = "Other";
break;
}
}
break;
case "android.widget.RelativeLayout":
AccountListItems = AccountList.get(i).findElements(By.className("android.widget.TextView"));
if (AccountListItems.size() == 5 || AccountListItems.size() == 4){
tempAccountInfo = AccountType;
for(int j=0; j<AccountListItems.size(); j++){
tempAccountInfo = tempAccountInfo + "|" + AccountListItems.get(j).getText();
LastItem = AccountListItems.get(2).getText();
}
switch(AccountType){
case "Investments":
if (!(AccountListItems.size() == 5)) {
System.out.println(tempAccountInfo);
AccountArray.add(tempAccountInfo);
}
break;
default:
System.out.println(tempAccountInfo);
AccountArray.add(tempAccountInfo);
break;
}
tempAccountInfo = "";
}
break;
}
}
driver.swipe(AccountList.get(AccountList.size()-1).getLocation().x + 70, AccountList.get(AccountList.size()-1).getLocation().y, AccountList.get(1).getLocation().x + 70, AccountList.get(1).getLocation().y, 3000);
Thread.sleep(20000);
AccountListItems = AccountList.get(AccountList.size() - 1).findElements(By.className("android.widget.TextView"));
try {
NewLastItem = AccountListItems.get(2).getText();
} catch (Exception e){
System.out.println("Not at the end of the listview");
NewLastItem = "N/A";
}
System.out.println("LastItem:" + LastItem);
System.out.println("NewLastItem:" + NewLastItem);
}
Objects viewed in Appium
This is the code of the second method that I've tried:
protected void swipeToNextElement(String Element) throws Exception{
List AccountList;
String LastItem;
String NewLastItem;
List<WebElement> AccountListItems;
Boolean loop = true;
AccountList = driver.findElements(getObject(Element));
AccountListItems = AccountList.get(AccountList.size()-1).findElements(By.className("android.widget.TextView"));
LastItem = AccountListItems.get(0).getAttribute("text");
NewLastItem = AccountListItems.get(0).getAttribute("text");
driver.swipe(AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y, AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y - 70, 1000);
while (loop) {
if (NewLastItem.equals(LastItem)){
AccountList = driver.findElements(getObject(Element));
AccountListItems = AccountList.get(AccountList.size()-1).findElements(By.className("android.widget.TextView"));
driver.swipe(AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y, AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y - 70, 1000);
NewLastItem = AccountListItems.get(0).getAttribute("text");
} else {
AccountList = driver.findElements(getObject(Element));
AccountListItems = AccountList.get(AccountList.size()-1).findElements(By.className("android.widget.TextView"));
driver.swipe(AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y, AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y + 70, 1000);
NewLastItem = AccountListItems.get(0).getAttribute("text");
loop = false;
}
}
System.out.println("NewLastItem: " + NewLastItem);
}
Any help is welcome ^^
Thanks in advance!
It's painful when you try to get the items from a long list on Android.
And it's hard to get the complete list if some items are invisible and even harder when some of them are the same to Appium.
So my suggestion is to avoid testing a long list.
Small Android application, which performs addition and other basic operations, and the OnClick() is as follows
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnAdd:
isValidToProcess(1);
break;
......
/*Switch continues for all other operations like Subtraction,etc*/
}
}
and my isValidToProcess() is as follows
private boolean isValidToProcess(int a) {
String num1 = mEdit1.getText().toString();
String num2 = mEdit2.getText().toString();
if (num1.matches("") || num2.matches(""))
{
ValueEmptyWarning();
}
else {
float numa = Float.parseFloat(num1);
float numb = Float.parseFloat(num2);
switch (a) {
case 1:
addition(numa, numb);
break;
......
/*Switch continues for all other operations like Subtraction,etc*/
}
}
My addition() function
public void addition(float numa, float numb) {
answer = numa + numb;
mEdit3.setText(String.valueOf(answer));
Log.v(TAG, "Error at Subtraction");
}
This program is working fine for Float and Integer numbers, But the problem is, for both Integer and Float values the answer will be in fractions, For example Number1=2 and Number2=3 and the answer=5.0
Objective: If User inputs Integer, The decimal point should not be there.
Is this possible to get the type of Value which user has entered on EditText?
first check for Integer.parseInt(numer) and catch for NumberFormatException . if it will parse it correctly then it is an integer else you can go for float.
For more control, try the basic OOP concept of overloading methods like
public float addition(float numa, float numb) {
// will return float
return numa + numb;
}
public int addition(int numa, float numb) {
// explicitly cast to int
return numa + (int) numb;
}
public int addition(float numa, int numb) {
// explicitly cast to int
return (int) numa + numb;
}
public int addition(int numa, int numb) {
// will return int
return numa + numb;
}
To examin your in put, try something like this...
public void examineInput(String input1, String input2) {
// For both are float
if (input1.indexOf(".") != -1 && input2.indexOf(".") != -1) {
float numa = Float.parseFloat(input1);
float numb = Float.parseFloat(input2);
float ans = addition(numa, numb);
Log.i(TAG, String.format("%f + %f = %f", numa, numb, ans));
}
// for first to be int and second to be float
else if (input1.indexOf(".") == -1 && input2.indexOf(".") != -1) {
int numa = Integer.parseInt(input1);
float numb = Float.parseFloat(input2);
int ans = addition(numa, numb);
Log.i(TAG, String.format("%d + %f = %d", numa, numb, ans));
}
// for first to be float and second to be int
else if (input1.indexOf(".") != -1 && input2.indexOf(".") == -1) {
float numa = Float.parseFloat(input1);
int numb = Integer.parseInt(input2);
int ans = addition(numa, numb);
Log.i(TAG, String.format("%f + %d = %d", numa, numb, ans));
}
// for both to be int
else if (input1.indexOf(".") == -1 && input2.indexOf(".") == -1) {
int numa = Integer.parseInt(input1);
int numb = Integer.parseInt(input2);
int ans = addition(numa, numb);
Log.i(TAG, String.format("%d + %d = %d", numa, numb, ans));
}
}
And the is the input to test this code, with output
examineInput("5.2", "6.2"); // 5.200000 + 6.200000 = 11.400000
examineInput("5", "3.6"); // 5 + 3.600000 = 8
examineInput("1.6", "5"); // 1.600000 + 5 = 6
examineInput("5", "5"); // 5 + 5 = 10
Note: you need to verify that examineInput always get valid numbers, not strings of non numaric characters...
Hope this helps to improve OOP concepts as well..:)
I don't think there is an usable api in EditText for developer to get the type of value.You can find another way in JAVA,apache may provider some widget to handle this.
You can use String formatters in this case.
Formatting Numeric Print Output
For your case, you have to use a pattern like this.
DecimalFormat df = new DecimalFormat("0.##");
String finalAnswer = df.format(answer);
You can use the following code in your addition function if your answer is float
answer = numa + numb;
String answerString = String.valueOf(answer);
String decimalString = answerString.substring(answerString.indexOf(".") + 1);
if (Integer.parseInt(decimalString) == 0)
answerString = answerString.substring(0, answerString.indexOf("."));
This will return a float value if your answer has other than 0 after the decimal or else it will return int in String
The user always enters String there is no other type entered using editText however, you need to check if the editText has (.) therefore it is float and then parse it as float otherwise, it is Integer and then parse it as Integer.
The code could look like the following.
if (num1.indexOf(".") != 0) {
float numa = Float.parseFloat(num1);
float numb = Float.parseFloat(num2);
}
else
{
int numa = Integer.parseInt(num1);
int numb = Integer.parseInt(num2);
}
by doing so the output for integers wont be in fraction style
P.S:
You have to make sure that the keyboard only enters number. so your app doesn't crash while parsing.
hope this helps
The type of Value which user has entered on EditText will be always String only. but you can restrict user to enter any perticular type value by android:inputType="" property inside EditText.
I'm coding a method that solve various kind of equation. Now I want that the method receives a String equation that could be in the forms:
ax^2+bx+c=0
or
*ax^2+c=0*
or
bx+c=0
etc. and the order shouldn't matter.
My problem is: How could I parse the equation according the "x" grade?
The eq could contains more values of the same grade for example 2x^2+4x^2+3x+8=2 (max grade x^3).
My method should assign the a value to double a[] if on the left or on the right of a there is x^2, double b[], if on the left or on the right there is x, and double c[] if there isn't any x variable near the value (and should change the value sign if the therms is after the =).
Convert a String number in a double is simple but I don't know how I could disassemble the input String according the x grade as described.
Tested for -2x + 3x^2 - 2 + 3x = 3 - 2x^2
public Double[] parseEquation(String equation)
{
Log.d(TAG, "equation: " + equation);
// Remove all white spaces
equation = equation.replaceAll("[ ]", "");
// Get the left and right sides of =
String[] sides = equation.split("[=]"); // should be of size 2
boolean leftNegative = false;
boolean rightNegative = false;
if (sides.length != 2)
{
// There is no = or more than one = signs.
}
else
{
// if sides i starts with + remove the +
// if - we remove and put it back later
for (int i = 0; i < 2; i++)
{
if (sides[i].charAt(0) == '+')
{
sides[i] = sides[i].substring(1);
}
}
if (sides[0].charAt(0) == '-')
{
leftNegative = true;
sides[0] = sides[0].substring(1);
}
if (sides[1].charAt(0) == '-')
{
rightNegative = true;
sides[1] = sides[1].substring(1);
}
}
Log.d(TAG, "left side:" + sides[0] + " right side: " + sides[1]);
// Terms without signs need to find out later
String[] leftTerms = sides[0].split("[+-]");
String[] rightTerms = sides[1].split("[+-]");
int length = leftTerms[0].length();
if (leftNegative)
{
leftTerms[0] = "-" + leftTerms[0];
}
// put in the minus sign for the rest of the terms
for (int i = 1; i < leftTerms.length; i++)
{
Log.d(TAG, "length = " + length + " " + sides[0].charAt(length));
if (sides[0].charAt(length) == '-')
{
leftTerms[i] = "-" + leftTerms[i];
length += leftTerms[i].length();
}
else
{
length += leftTerms[i].length() + 1;
}
}
length = rightTerms[0].length();
if (rightNegative)
{
rightTerms[0] = "-" + rightTerms[0];
}
for (int i = 1; i < rightTerms.length; i++)
{
Log.d(TAG, "length = " + length + " " + sides[1].charAt(length));
if (sides[1].charAt(length) == '-')
{
rightTerms[i] = "-" + rightTerms[i];
length += rightTerms[i].length();
}
else
{
length += rightTerms[i].length() + 1;
}
}
// Now we put all the factors and powers in a list
List<ContentValues> leftLists = new ArrayList<ContentValues>();
// left side
for (int i = 0; i < leftTerms.length; i++)
{
Log.d(TAG, "leftTerm: " + leftTerms[i]);
ContentValues contentValues = new ContentValues();
int indexOfX = leftTerms[i].indexOf('x');
if (indexOfX == -1)
{
// no x mean a constant term
contentValues.put("factor", leftTerms[i]);
contentValues.put("power", "0");
}
else
{
int indexOfHat = leftTerms[i].indexOf('^');
if (indexOfHat == -1)
{
// no hat mean power = 1
contentValues.put("power", "1");
String factor = leftTerms[i].substring(0, indexOfX).trim();
contentValues.put("factor", factor);
}
else
{
String power = leftTerms[i].substring(indexOfX + 2).trim();
String factor = leftTerms[i].substring(0, indexOfX).trim();
contentValues.put("factor", factor);
contentValues.put("power", power);
}
}
Log.d(TAG, contentValues.toString());
leftLists.add(contentValues);
}
List<ContentValues> rightLists = new ArrayList<ContentValues>();
for (int i = 0; i < rightTerms.length; i++)
{
Log.d(TAG, "rightTerm: " + rightTerms[i]);
ContentValues contentValues = new ContentValues();
int indexOfX = rightTerms[i].indexOf('x');
if (indexOfX == -1)
{
// no hat mean a constant term
contentValues.put("factor", rightTerms[i]);
contentValues.put("power", "0");
}
else
{
int indexOfHat = rightTerms[i].indexOf('^');
if (indexOfHat == -1)
{
// no hat mean power = 1
contentValues.put("power", "1");
String factor = rightTerms[i].substring(0, indexOfX).trim();
contentValues.put("factor", factor);
}
else
{
String power = rightTerms[i].substring(indexOfX + 2).trim();
String factor = rightTerms[i].substring(0, indexOfX).trim();
contentValues.put("factor", factor);
contentValues.put("power", power);
}
}
Log.d(TAG, contentValues.toString());
rightLists.add(contentValues);
}
// Now add the factors with same powers.
// Suppose we solve for cubic here the end result will be
// 4 terms constant, x, x^2 and x^3
// Declare a double array of dim 4 the first will hold constant
// the second the x factor etc...
// You can allow arbitrary power by looping through the lists and get the max power
Double[] result = new Double[]{0.0, 0.0, 0.0, 0.0};
for (ContentValues c : leftLists)
{
switch (c.getAsInteger("power"))
{
case 0:
//Log.d(TAG, "power = 0, factor = " + c.toString());
result[0] += c.getAsDouble("factor");
break;
case 1:
result[1] += c.getAsDouble("factor");
break;
case 2:
result[2] += c.getAsDouble("factor");
break;
case 3:
result[3] += c.getAsDouble("factor");
break;
}
}
for (ContentValues c : rightLists)
{
switch (c.getAsInteger("power"))
{
case 0:
//Log.d(TAG, "power = 0, factor = " + c.toString());
result[0] -= c.getAsDouble("factor");
break;
case 1:
result[1] -= c.getAsDouble("factor");
break;
case 2:
result[2] -= c.getAsDouble("factor");
break;
case 3:
result[3] -= c.getAsDouble("factor");
break;
}
}
Log.d(TAG, "constant term = " + result[0] + ", x^1 = " + result[1]
+ ", x^2 = " + result[2] + ", x^3 = " + result[3]);
return result;
}
If you weren't limited by Android, I'd suggest using a lexer and parser. These are code generators, so they can work anywhere the base language works, but they tend to produce bloated code. Android might not appreciate that.