summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2024-12-18 14:58:25 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2024-12-18 14:58:25 +0330
commit9313767a800f16e01a05c577183b5e6399c3f76d (patch)
tree8bca2a5c5e409c73e59c56880f23f6e3c32efb55
parent5a670d6cae41d77280a98936f2baddf31f069656 (diff)
great appreciations to https://github.com/hadibolty/ for reporting bugs, a lot of bugs got fixed
-rw-r--r--app/build.gradle.kts4
-rw-r--r--app/release/app-release.apkbin692395 -> 694150 bytes
-rw-r--r--app/release/baselineProfiles/0/app-release.dmbin3521 -> 3531 bytes
-rw-r--r--app/release/baselineProfiles/1/app-release.dmbin3475 -> 3474 bytes
-rw-r--r--app/release/output-metadata.json4
-rw-r--r--app/src/main/AndroidManifest.xml1
-rw-r--r--app/src/main/java/com/a404m/calculator/ContextHelper.kt19
-rw-r--r--app/src/main/java/com/a404m/calculator/model/CalcButtonModel.kt138
-rw-r--r--app/src/main/java/com/a404m/calculator/ui/page/Home.kt2
-rw-r--r--app/src/main/java/com/a404m/calculator/ui/util/Toast.kt12
-rw-r--r--app/src/main/java/com/a404m/calculator/util/MathHelper.kt90
11 files changed, 228 insertions, 42 deletions
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 7fc29a3..8503827 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -12,8 +12,8 @@ android {
applicationId = "com.a404m.calculator"
minSdk = 21
targetSdk = 35
- versionCode = 3
- versionName = "0.1.1"
+ versionCode = 4
+ versionName = "0.1.2"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
diff --git a/app/release/app-release.apk b/app/release/app-release.apk
index 4763c61..ec63e14 100644
--- a/app/release/app-release.apk
+++ b/app/release/app-release.apk
Binary files differ
diff --git a/app/release/baselineProfiles/0/app-release.dm b/app/release/baselineProfiles/0/app-release.dm
index 2df2b65..c34e6d1 100644
--- a/app/release/baselineProfiles/0/app-release.dm
+++ b/app/release/baselineProfiles/0/app-release.dm
Binary files differ
diff --git a/app/release/baselineProfiles/1/app-release.dm b/app/release/baselineProfiles/1/app-release.dm
index 829ee1a..10d60b7 100644
--- a/app/release/baselineProfiles/1/app-release.dm
+++ b/app/release/baselineProfiles/1/app-release.dm
Binary files differ
diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json
index 4b3565e..37c4baa 100644
--- a/app/release/output-metadata.json
+++ b/app/release/output-metadata.json
@@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
- "versionCode": 2,
- "versionName": "0.1.0",
+ "versionCode": 4,
+ "versionName": "0.1.2",
"outputFile": "app-release.apk"
}
],
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8d7bca4..74b91e0 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools">
<application
+ android:name="com.a404m.calculator.ContextHelper"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
diff --git a/app/src/main/java/com/a404m/calculator/ContextHelper.kt b/app/src/main/java/com/a404m/calculator/ContextHelper.kt
new file mode 100644
index 0000000..4e5e3fc
--- /dev/null
+++ b/app/src/main/java/com/a404m/calculator/ContextHelper.kt
@@ -0,0 +1,19 @@
+package com.a404m.calculator
+
+import android.app.Application
+import android.content.Context
+
+class ContextHelper : Application() {
+ companion object {
+ var context: Context? = null
+
+ fun getAppContext(): Context? {
+ return context
+ }
+ }
+
+ override fun onCreate() {
+ super.onCreate()
+ context = applicationContext
+ }
+} \ No newline at end of file
diff --git a/app/src/main/java/com/a404m/calculator/model/CalcButtonModel.kt b/app/src/main/java/com/a404m/calculator/model/CalcButtonModel.kt
index c6a10da..4384448 100644
--- a/app/src/main/java/com/a404m/calculator/model/CalcButtonModel.kt
+++ b/app/src/main/java/com/a404m/calculator/model/CalcButtonModel.kt
@@ -4,98 +4,148 @@ import com.a404m.calculator.util.MathHelper
data class CalcButtonModel(
val text: String,
- val weight:Float = 1F,
+ val weight: Float = 1F,
val op: (expression: String) -> String,
) {
companion object {
val K_0 = CalcButtonModel(
text = "0",
op = {
- it + '0'
+ addNumber(
+ it,
+ '0'
+ )
}
)
val K_1 = CalcButtonModel(
text = "1",
op = {
- it + '1'
+ addNumber(
+ it,
+ '1'
+ )
}
)
val K_2 = CalcButtonModel(
text = "2",
op = {
- it + '2'
+ addNumber(
+ it,
+ '2'
+ )
}
)
val K_3 = CalcButtonModel(
text = "3",
op = {
- it + '3'
+ addNumber(
+ it,
+ '3'
+ )
}
)
val K_4 = CalcButtonModel(
text = "4",
op = {
- it + '4'
+ addNumber(
+ it,
+ '4'
+ )
}
)
val K_5 = CalcButtonModel(
text = "5",
op = {
- it + '5'
+ addNumber(
+ it,
+ '5'
+ )
}
)
val K_6 = CalcButtonModel(
text = "6",
op = {
- it + '6'
+ addNumber(
+ it,
+ '6'
+ )
}
)
val K_7 = CalcButtonModel(
text = "7",
op = {
- it + '7'
+ addNumber(
+ it,
+ '7'
+ )
}
)
val K_8 = CalcButtonModel(
text = "8",
op = {
- it + '8'
+ addNumber(
+ it,
+ '8'
+ )
}
)
val K_9 = CalcButtonModel(
text = "9",
op = {
- it + '9'
+ addNumber(
+ it,
+ '9'
+ )
}
)
val K_PLUS = CalcButtonModel(
text = "+",
op = {
- it + '+'
+ addOperator(
+ it,
+ '+',
+ true
+ )
}
)
val K_MINUS = CalcButtonModel(
text = "-",
op = {
- it + '-'
+ addOperator(
+ it,
+ '-',
+ true
+ )
}
)
val K_MULTIPLY = CalcButtonModel(
text = "×",
op = {
- it + '×'
+ addOperator(
+ it,
+ '×',
+ false
+ )
}
)
val K_DIVISION = CalcButtonModel(
text = "÷",
op = {
- it + '÷'
+ addOperator(
+ it,
+ '÷',
+ false
+ )
}
)
val K_REMINDER = CalcButtonModel(
text = "%",
op = {
- it + '%'
+ addOperator(
+ it,
+ '%',
+ false
+ )
}
)
val K_EQUAL = CalcButtonModel(
@@ -107,20 +157,25 @@ data class CalcButtonModel(
val K_DOT = CalcButtonModel(
text = ".",
op = {
- it + '.'
+ when (MathHelper.getInWriting(it)) {
+ MathHelper.InWriting.NONE -> "0."
+ MathHelper.InWriting.NUMBER_INT -> "$it."
+ MathHelper.InWriting.NUMBER_FLOAT -> it
+ MathHelper.InWriting.OPERATOR -> "${it}0."
+ }
}
)
val K_C = CalcButtonModel(
text = "C",
op = {
- ""
+ "0"
}
)
val K_BACKSPACE = CalcButtonModel(
text = "⌫",
op = {
if (it.length <= 1) {
- ""
+ "0"
} else {
it.substring(
0,
@@ -135,5 +190,50 @@ data class CalcButtonModel(
it
}
)
+
+ private fun addOperator(
+ expression: String,
+ operator: Char,
+ canBePrefix: Boolean
+ ): String {
+ return if (expression == "0") {
+ if (canBePrefix) operator.toString()
+ else expression + operator
+ } else {
+ when (MathHelper.getInWriting(expression)) {
+ MathHelper.InWriting.NONE ->
+ if (canBePrefix) operator.toString()
+ else ""
+
+ MathHelper.InWriting.NUMBER_INT ->
+ expression + operator
+
+ MathHelper.InWriting.NUMBER_FLOAT ->
+ if (expression.last() == '.') "${expression}0$operator"
+ else expression + operator
+
+ MathHelper.InWriting.OPERATOR -> expression.substring(
+ 0,
+ expression.length - 1
+ ) + operator
+ }
+ }
+ }
+
+ private fun addNumber(
+ expression: String,
+ number: Char
+ ): String {
+ val value = MathHelper.getLastNumber(expression)
+
+ return if (value == "0") {
+ expression.substring(
+ 0,
+ expression.length - 1
+ ) + number
+ } else {
+ expression + number
+ }
+ }
}
}
diff --git a/app/src/main/java/com/a404m/calculator/ui/page/Home.kt b/app/src/main/java/com/a404m/calculator/ui/page/Home.kt
index ba9a21e..a2c4846 100644
--- a/app/src/main/java/com/a404m/calculator/ui/page/Home.kt
+++ b/app/src/main/java/com/a404m/calculator/ui/page/Home.kt
@@ -34,7 +34,7 @@ import com.a404m.calculator.ui.util.CalcGrid
@Composable
fun HomePage(modifier: Modifier = Modifier) {
var expression by rememberSaveable {
- mutableStateOf("")
+ mutableStateOf("0")
}
Scaffold(
modifier = modifier,
diff --git a/app/src/main/java/com/a404m/calculator/ui/util/Toast.kt b/app/src/main/java/com/a404m/calculator/ui/util/Toast.kt
new file mode 100644
index 0000000..5041472
--- /dev/null
+++ b/app/src/main/java/com/a404m/calculator/ui/util/Toast.kt
@@ -0,0 +1,12 @@
+package com.a404m.calculator.ui.util
+
+import android.widget.Toast
+import com.a404m.calculator.ContextHelper
+
+fun showToast(text:String){
+ Toast.makeText(
+ ContextHelper.context,
+ text,
+ Toast.LENGTH_SHORT
+ ).show()
+} \ No newline at end of file
diff --git a/app/src/main/java/com/a404m/calculator/util/MathHelper.kt b/app/src/main/java/com/a404m/calculator/util/MathHelper.kt
index d0c3ee3..77244b0 100644
--- a/app/src/main/java/com/a404m/calculator/util/MathHelper.kt
+++ b/app/src/main/java/com/a404m/calculator/util/MathHelper.kt
@@ -1,9 +1,13 @@
package com.a404m.calculator.util
import android.util.Log
+import com.a404m.calculator.ui.util.showToast
import com.a404m.calculator.util.MathHelper.Operator.Kind
+import java.math.BigDecimal
import java.nio.charset.UnsupportedCharsetException
+typealias MathNumberType = BigDecimal
+
object MathHelper {
private val operatorStrings = arrayOf(
'+',
@@ -44,35 +48,35 @@ object MathHelper {
'+',
Kind.INFIX,
{
- Operand(it.first().value+it.last().value)
+ Operand(it.first().value + it.last().value)
}
)
private val sub = Operator(
'-',
Kind.INFIX,
{
- Operand(it.first().value-it.last().value)
+ Operand(it.first().value - it.last().value)
}
)
private val mul = Operator(
'×',
Kind.INFIX,
{
- Operand(it.first().value*it.last().value)
+ Operand(it.first().value * it.last().value)
}
)
private val div = Operator(
'÷',
Kind.INFIX,
{
- Operand(it.first().value/it.last().value)
+ Operand(it.first().value / it.last().value)
}
)
private val rem = Operator(
'%',
Kind.INFIX,
{
- Operand(it.first().value%it.last().value)
+ Operand(it.first().value % it.last().value)
}
)
private val operatorOrders = arrayOf(
@@ -104,7 +108,8 @@ object MathHelper {
return try {
parse(lex(expression)).eval().toString()
} catch (e: Exception) {
- e.message ?: "Exception"
+ showToast(e.message ?: "Exception")
+ expression
}
}
@@ -114,7 +119,7 @@ object MathHelper {
break
}
var i = -1
- while(++i < lexed.size) {
+ while (++i < lexed.size) {
val item = lexed[i]
if (item is BasicOperator) {
var op = item.toOperator(
@@ -175,7 +180,7 @@ object MathHelper {
value = expression.substring(
start,
i
- ).toDouble()
+ ).toBigDecimal()
)
)
--i
@@ -198,7 +203,7 @@ object MathHelper {
private class Operator(
val operator: Char,
val kind: Kind,
- val operate: (operands:List<Operand>)-> Operand,
+ val operate: (operands: List<Operand>) -> Operand,
val operands: ArrayList<Any> = arrayListOf(),
) {
fun cloneWithoutOperands(): Operator {
@@ -223,14 +228,14 @@ object MathHelper {
"A404M",
"eval: $operator $operands"
)
- if(operandSize() != operands.size){
+ if (operandSize() != operands.size) {
throw UnsupportedOperationException("Not enough operands")
}
val evaledOperands = operands.map {
- if(it is Operator){
+ if (it is Operator) {
it.eval()
- }else{
+ } else {
it as Operand
}
}
@@ -277,7 +282,7 @@ object MathHelper {
)
val right = rightItem is Operand || rightItem is Operator
- val k:Kind
+ val k: Kind
if (left) {
if (right) {
@@ -302,13 +307,62 @@ object MathHelper {
}
private class Operand(
- val value: Double,
- ){
+ val value: MathNumberType,
+ ) {
override fun toString(): String {
- if(value % 1 == 0.0){
- return "%.0f".format(value)
+ var str = value.toString()
+ if(str.contains('.')){
+ while (str.last() == '0'){
+ str = str.removeRange(str.length-1,str.length)
+ }
+ if(str.last() == '.'){
+ str = str.removeRange(str.length-1,str.length)
+ }
+ }
+ return str
+ }
+ }
+
+ enum class InWriting {
+ NONE,
+ NUMBER_INT,
+ NUMBER_FLOAT,
+ OPERATOR,
+ }
+
+ fun getInWriting(expression: String): InWriting {
+ return when (expression.lastOrNull()) {
+ in operatorStrings -> InWriting.OPERATOR
+ in numberStrings -> {
+ var i = expression.length
+ var hasDot = false
+ while (--i >= 0 && expression[i] in numberStrings) {
+ if (expression[i] == '.') {
+ hasDot = true
+ }
+ }
+
+ if (hasDot) InWriting.NUMBER_FLOAT
+ else InWriting.NUMBER_INT
}
- return value.toString()
+
+ else -> InWriting.NONE
+ }
+ }
+
+ fun getLastNumber(expression: String): String? {
+ return when (expression.lastOrNull()) {
+ in numberStrings -> {
+ var i = expression.length
+ var number = ""
+ while (--i >= 0 && expression[i] in numberStrings) {
+ number = "${expression[i]}$number"
+ }
+
+ number
+ }
+
+ else -> null
}
}
} \ No newline at end of file