How not to repeat math operations if there is no number in front of it?

Hello I have made a simple calculator in “Kotlin” using android studio
the problem I got and i don’t have a way to fix it is how to no repeat the math operations after type a one number … Perhaps because I am new to the world of Android application development and I do not know the way I should avoid this problem

example for what I mean , He entered addition/subtraction twice

enter image description here
My codes :
Main.kt

  package com.iosmostafa.calculator
    import android.support.v7.app.AppCompatActivity
    import android.os.Bundle
    import android.util.Log
    import com.iosmostafa.calculator.R
    import kotlinx.android.synthetic.main.activity_main.*
    import net.objecthunter.exp4j.ExpressionBuilder
    
    class Main : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            //Numbers
            tvOne.setOnClickListener { appendOnExpresstion("1", true) }
            tvTwo.setOnClickListener { appendOnExpresstion("2", true) }
            tvThree.setOnClickListener { appendOnExpresstion("3", true) }
            tvFour.setOnClickListener { appendOnExpresstion("4", true) }
            tvFive.setOnClickListener { appendOnExpresstion("5", true) }
            tvSix.setOnClickListener { appendOnExpresstion("6", true) }
            tvSeven.setOnClickListener { appendOnExpresstion("7", true) }
            tvEight.setOnClickListener { appendOnExpresstion("8", true) }
            tvNine.setOnClickListener { appendOnExpresstion("9", true) }
            tvZero.setOnClickListener { appendOnExpresstion("0", true) }
            tvDot.setOnClickListener { appendOnExpresstion(".", true) }
    
    
    
            //Operators
            tvPlus.setOnClickListener { appendOnExpresstion("+", false) }
            tvMinus.setOnClickListener { appendOnExpresstion("-", false) }
            tvMul.setOnClickListener { appendOnExpresstion("*", false) }
            tvDivide.setOnClickListener { appendOnExpresstion("/", false) }
            tvOpen.setOnClickListener { appendOnExpresstion("(", false) }
            tvClose.setOnClickListener { appendOnExpresstion(")", false) }
            tvNew1.setOnClickListener{(appendOnExpresstion("%",false))}
    
            tvClear.setOnClickListener {
                tvExpression.text = ""
                tvResult.text = ""
            }
    
            tvBack.setOnClickListener {
                val string = tvExpression.text.toString()
                if(string.isNotEmpty()){
                    tvExpression.text = string.substring(0,string.length-1)
                }
                tvResult.text = ""
            }
    
    
    
            tvEquals.setOnClickListener {
                try {
    
                    val expression = ExpressionBuilder(tvExpression.text.toString()).build()
                    val result = expression.evaluate()
                    val longResult = result.toLong()
                    if(result == longResult.toDouble())
                        tvResult.text = longResult.toString()
                    else
                        tvResult.text = result.toString()
    
                }catch (e:Exception){
                    Log.d("Exception"," message : " + e.message )
                }
            }
    
    
        }
    
        fun appendOnExpresstion(string: String, canClear: Boolean) {
    
            if(tvResult.text.isNotEmpty()){
                tvExpression.text = ""
            }
    
            if (canClear) {
                tvResult.text = ""
                tvExpression.append(string)
            } else {
                tvExpression.append(tvResult.text)
                tvExpression.append(string)
                tvResult.text = ""
            }
        }
    }

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tvExpression"
        android:layout_width="match_parent"
        android:layout_height="80sp"
        android:ellipsize="start"
        android:gravity="end"
        android:singleLine="true"
        android:textColor="@color/numberButton"
        android:textSize="40sp" />

    <TextView
        android:id="@+id/tvResult"
        android:layout_width="match_parent"
        android:layout_height="100sp"
        android:ellipsize="end"
        android:gravity="end"
        android:singleLine="true"
        android:textColor="@color/numberButton"
        android:textSize="30sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tvClear"
                style="@style/ActionButtonStyle"
                android:text="حذف" />

            <TextView
                android:id="@+id/tvOpen"
                style="@style/ActionButtonStyle"
                android:text="(" />

            <TextView
                android:id="@+id/tvClose"
                style="@style/ActionButtonStyle"
                android:text=")" />

            <TextView
                android:id="@+id/tvNew1"
                style="@style/ActionButtonStyle"
                android:text="%" />

            <TextView
                android:id="@+id/tvDivide"
                style="@style/ActionButtonStyle"
                android:text="/" />


        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tvSeven"
                style="@style/NumberButtonStyle"
                android:text="7" />

            <TextView
                android:id="@+id/tvEight"
                style="@style/NumberButtonStyle"
                android:text="8" />

            <TextView
                android:id="@+id/tvNine"
                style="@style/NumberButtonStyle"
                android:text="9" />

            <TextView
                android:id="@+id/tvMul"
                style="@style/ActionButtonStyle"
                android:text="X" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal">


            <TextView
                android:id="@+id/tvFour"
                style="@style/NumberButtonStyle"
                android:text="4" />

            <TextView
                android:id="@+id/tvFive"
                style="@style/NumberButtonStyle"
                android:text="5" />

            <TextView
                android:id="@+id/tvSix"
                style="@style/NumberButtonStyle"
                android:text="6" />

            <TextView
                android:id="@+id/tvMinus"
                style="@style/ActionButtonStyle"
                android:text="-" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal">


            <TextView
                android:id="@+id/tvOne"
                style="@style/NumberButtonStyle"
                android:text="1" />

            <TextView
                android:id="@+id/tvTwo"
                style="@style/NumberButtonStyle"
                android:text="2" />

            <TextView
                android:id="@+id/tvThree"
                style="@style/NumberButtonStyle"
                android:text="3" />

            <TextView
                android:id="@+id/tvPlus"
                style="@style/ActionButtonStyle"
                android:text="+" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/tvDot"
                style="@style/NumberButtonStyle"
                android:text="." />

            <TextView
                android:id="@+id/tvZero"
                style="@style/NumberButtonStyle"
                android:text="0" />

            <ImageView
                android:id="@+id/tvBack"
                style="@style/NumberButtonStyle"
                android:scaleType="center"
                android:src="@drawable/backspace" />

            <TextView
                android:id="@+id/tvEquals"
                style="@style/ActionButtonStyle"
                android:text="=" />

        </LinearLayout>


    </LinearLayout>


</LinearLayout>

Basically, you’ll have to check for the character at tvExpression.text[tvExpression.text.length - 1] and see if it is any of the operators. If it is an operator, then delete that character (by setting the text of the tvExpression to tvExpression.text.substring(0, tvExpression.text.length - 1) and then append the operator as usual

can you do it in the full code please?

The pseudo-code could be:

  1. When appending on the expression*
  2. if the character being appended is an operator then remove it
  3. append the new character to the expression

Considering the first line of our pseudo-code, a good place to implement this might be in the appendOnExpression method since that method is already responsible for knowing how to properly update the expression on new input–the logic for inputting repeated operators naturally fits into this responsibility.

I’d recommend experimenting with strings on Kotlin Playground. The Kotlin Koans and other beginner tutorials should also help with learning string manipulation.


EDIT: From looking at your stackoverflow question and seeing as you’re asking for the full implemented code completed for you, I want to double down on encouraging you to go through some of the basic tutorials. It’ll be a million times faster to learn and understand what your code is doing. The example you’re asking does not require anything complicated or even Android related–it’s beginner string manipulation and we all have to learn it at some point.

It’s possible that within an hour of following a tutorial and experimenting on Kotlin Playground you could answer this question yourself and fully understand why your answer would be correct.

Feel free to ask for learning resources if those tutorials assume too much prior programming experience.

2 Likes