How to count the number of string characters in Kotlin? - android

#SuppressLint("SetTextI18n")
private fun countName(x: String) {
val textView: TextView = findViewById(R.id.result)
for (i in 0 until x.length) {
textView.text = i.toString()
}
}
This is what I have so far. It works somewhat but for some reason it is lagging behind 1 number. For example, if I type James, the number it will output would be 4.

How to get the number of characters in a string (usually what you want):
str.length
How to get the number of Unicode code points in a string (because sometimes a code point is encoded as multiple characters):
str.codePointCount(0, str.length)
See this Java answer for more details on the difference between these two options.

There are many simple ways to get the number of characters in a string. but if you want to know the mistake in your code you should have started to count from 1 instead of 0.
for (i in 1 until x.length) {
textView.text = i.toString()
}

Related

Starts comparing from the first number, not the whole number in kotlin

Hello I need to compare 2 numbers and I used >, => but it doesn't compare whole number, it looks for the leftest(left) number and compare
for example the number is 92,236 and i want to compare it with 100,000, it says 92236 is bigger than 100,000 and it is because of the first number which is 9 and the first number of second number that is 1 so it says 100,000 is not bigger than 9236
here what I had done
class IncreaseMoneyFragment : Fragment() {
var decide = ""
val increaseEditText = mIncreaseMoneyBinding.increaseEdt.text.toString() (get value of edit text)
val currentPayment = it.payment (get loanPayment from database)
if (increaseEditText > currentPayment) {
Toast.makeText(activity, "more", Toast.LENGTH_SHORT).show()
val more = "بیشتر"
decide = more
} else {
Toast.makeText(activity, "less", Toast.LENGTH_SHORT).show()
val less = "کمتر"
decide = less
}
builder.setTitle(" مبلغ مورد نظر از مبلغ قسط وام $decide است. ادامه میدهید؟")
THANKS FOR HELPING ME :)
You are most likely comparing strings (text) and not numbers here. That's why it's using the alphabetical order instead of the integer order:
println("92236" > "100000") // true
println(92236 > 100000) // false
You probably want to convert your strings into integers instead:
if (increaseEditText.toInt() > currentPayment.toInt()) {
// ...
}
Note that toInt will crash if the strings are not actual numbers (for instance empty).
You can use toIntOrNull if you want more safety. It returns null if the string is not a number, so you can simply check for null and deal with this problem separately before comparing.

String.format with English local but numbers are arabic

I am calculating priceAfterDsicount then place value in EditText(so user can modify it after App calculation)
Value retured from format is arabic numbers
this is code
private fun handleDiscount() {
val price = edPackagePrice.text.toString().toDoubleOrNull()
val discount = discount_percentage_edit_text.text.toString().toIntOrNull()
"handleDiscount before price$price discount$discount".log(mTag)
price?.let {
discount?.let {
val finalValue = String.format("%.1f", ValuesHelper.getPercentage(price, discount),Locale.US)
price_after_discount_edit_text.setText(finalValue)
"handleDiscount ook price$price discount$discount, final $finalValue".log(mTag)
}
}
if (discount == null) {
"handleDiscount $price , ${edPackagePrice.text}".log(mTag)
price_after_discount_edit_text.setText("")
price?.let { price_after_discount_edit_text.setText(price.toString()) }
}
"handleDiscount after price_after_discount_edit_text${price_after_discount_edit_text.text.toString()} ".log(mTag)
}
Output at Run
so what is problem?
NOTE
App language is arabic(user can change it from app).
I found other way to convert arabic number to english
Use Java.math.BigDecimal ,it will automatically construct English numeric equivalent to Arabic numeric equivalent , After you have English numeric equivalent do your calculation and when you want to update the UI after calculation use the device locale to show the end result to user in Arabic , BigDecimal only work with digits i.e. 0123. For special characters like , you have to do exception handling , we have .isDigit() method of Character class that you can leverage to iterate over whole input string and remove , before doing calculation,hope this helps.

How can I print while loop results in textView in Kotlin

I have a "for-loop" in Kotlin which is going to run my code 6 times.
I also have a textView on the app and want to see these 6 results shown there.
I can easily println() the results.
However, If I set the text of textView to these results, it only gets the last result.
What I like to do printing out all 5 results in textView (suggestedNums ) as each result is a separate line.
Is it even possible?
Any help appreciated.
Thanks.
for (i in 1..6) {
val s: MutableSet<Int> = mutableSetOf()
//create 5 numbers from numbers
while (s.size < 5) {
val rnd = (numbers).random()
s.add(rnd)
}
// remove all 5 random numbers from numbers list.
numbers.removeAll(s)
// sort 5 random numbers and println
println(s.sorted())
// set suggestedNums text to "s"
suggestedNums.text = s.sorted().toString()
}
You can do it in 2 ways
replace
suggestedNums.text = s.sorted().toString()
with
suggestedNums.text = suggestedNums.text.toString() + "\n" + s.sorted().toString()
Create a string and append the results with "\n" and set the text outside the for loop

Kotlin check for words in string

I have a NSFW class that scans texts like item names and descriptions against a list of known NSFW-words.
That would be the best approach to test a list of strings like
let nsfw = listof(
"badword",
"curseword",
"ass",
... 200+ more
)
against a string like:
This is the text that contains a badword // returns true
Please note that i need to check for full words. not parts of words.
so the sentence:
The grass is grean // returns false
Because grass is not a bad word.
Ive tried something like this but it doesnt check for full words.
val result = nsfw.filter { it in sentence.toLowerCase() }
You may build a regex like
\b(?:word1|word2|word3...)\b
See the regex demo. Then, use it with the Regex.containsMatchIn method:
val nsfw = listOf(
"badword",
"curseword",
"ass"
)
val s1 = "This is the text that contains a badword"
val s2 = "The grass is grean"
val rx = Regex("\\b(?:${nsfw.joinToString(separator="|")})\\b")
println(rx.containsMatchIn(s1)) // => true
println(rx.containsMatchIn(s2)) // => false
See this Kotlin demo.
Here, nsfw.joinToString(separator="|") joins the words with a pipe (the alternation operator) and the "\\b(?:${nsfw.joinToString(separator="|")})\\b" creates the correct regex.
If your words may contain special regex metacharacters, like +, ?, (, ), etc., you need to "preprocess" the nsfw values with the Regex.escape method:
val rx = Regex("\\b(?:${nsfw.map{Regex.escape(it)}.joinToString("|")})\\b")
^^^^^^^^^^^^^^^^^^^^^^
See the Kotlin demo.
AND one more thing: if the keywords may start/end with chars other than letters, digits and underscores, you cannot rely on \b word boundaries. You may
Use whitespace boundaries: val rx = Regex("(?<!\\S)(?:${nsfw.map{Regex.escape(it)}.joinToString("|")})(?!\\S)")
Use unambiguous word boundaries: val rx = Regex("(?<!\\w)(?:${nsfw.map{Regex.escape(it)}.joinToString("|")})(?!\\w)")
You can use split() on the string that you want to check, with space as a delimiter, so you create a list of its words, although this does not always guarantee that all words will be extracted successfully, since there could exist other word separators like dots or commas etc. If that suits you, do this:
val nsfw = listOf(
"badword",
"curseword",
"ass"
)
val str = "This is the text that contains a badword"
val words = str.toLowerCase().split("\\s+".toRegex())
val containsBadWords = words.firstOrNull { it in nsfw } != null
println(containsBadWords)
will print
true
If you want a list of the "bad words":
val badWords = words.filter { it in nsfw }

Kotlin: SumbyDouble returning additional decimals

I am summing double value from arraylist its giving additional decimals as 99999, how to fix this, please guide
ex
class ExDet{var expName:String ="",var expAmount:Double = 0.0}
val arrayList = ArrayList<ExDet>()
arrayList.add(ExDet("Abc 1",45.66))
arrayList.add(ExDet("DEF 1",10.0))
arrayList.add(ExDet("Lee 1",600.89))
arrayList.add(ExDet("Ifr 1",200.9))
var amt = arrayList.sumByDouble{ it.expAmount }
Expected Value of Amount is :
Amt = 857.45
But it returns
Amt = 857.4499999
Sample Code to Test
data class ExDet(var expName:String ="" ,var expAmount:Double=0.0)
fun main(args: Array<String>) {
val arrayList = ArrayList<ExDet>()
arrayList.add(ExDet("Abc 1",45.66))
arrayList.add(ExDet("DEF 1",10.0))
arrayList.add(ExDet("Lee 1",600.89))
arrayList.add(ExDet("Ifr 1",200.9))
var amt = arrayList.sumByDouble{ it.expAmount }
println("Amount is : $amt")
}
The issue you are confronted with is that floating point numbers are build on top of base 2, not base 10.
Think how you can easily represent a third as a fraction (1/3), but when you convert to decimal you get a repeating (recurring) number after the radix point (i.e. 0.33...). Some decimal numbers are recurring when represented in base-2, e.g. x.9. The computer has a finite number of bits, so the (base-2) number is truncated. All the truncation errors can add up.
You need to round to the required precision (e.g. round(x * 100) / 100).
If you are only interested in how it is displayed then you can use the format function with something like "%.2f".
String.format("%.2f", value)

Categories

Resources