Currency will not show second decimal in Kotlin [duplicate] - kotlin

I am facing an issue where I need to do some calculations with a number like for example 5000,00 multiplied it by (1,025^3).
So in this case 5000,00 * (1,025^3) = 5385,45
So my question is, how can I format the number 5385,45 to be like 5.385,45 using decimal format maybe?
I tried by myself and I did this piece of code that outputs 5385,45 in the app but not 5.385,45
var interestValue = (5000,00*(Math.pow(1.025,yearValue)))
val number = java.lang.Double.valueOf(interestValue)
val dec = DecimalFormat("#,00")
val credits = dec.format(number)
vValueInterest.text = credits

This is the format you need:
val dec = DecimalFormat("#,###.##")
will print:
5.384,45
if you need always exactly 2 digits after the decimal point:
val dec = DecimalFormat("#,###.00")

val num = 1.34567
val df = DecimalFormat("#.##")
df.roundingMode = RoundingMode.CEILING
println(df.format(num))
When you run the program, the output will be:
1.34
Check:
https://www.programiz.com/kotlin-programming/examples/round-number-decimal

The "most Kotlin-esque" way I found to do this sort of formatting is:
"%,.2f".format(Locale.GERMAN, 1234.5678) // => "1.234,57"
"%,.2f".format(Locale.ENGLISH, 1234.5678) // => "1,234.57"
"%,.2f".format(1234.5678) // => "1,234.57" for me, in en_AU
Note though that even though this is Kotlin's own extension method on String, it still only works on the JVM.
For those looking for a multiplatform implementation (as I was), mp_stools is one option.

Used:
%.numberf
fun main(args: Array<String>) {
var A: Double
A = readLine()!!.toDouble()
var bla = A*A
var calculator = 3.14159 * bla
println("A=%.4f".format(calculator))
}

Try val dec = DecimalFormat("#.###,00"). For examples of DecimalFormat check this link.

Related

How to use Lucene's DistinctValuesCollector?

My objective is to collect distinct values of select fields to provided them as filter options for the frontend. DistinctValuesCollector seems to be the tool for this, however since I haven't found code sample and documentation except for the Javadocs I can't currently correctly construct this collector. Can anyone provide an example?
This is my attempt which doesn't deliver the desired distinct values of the field PROJEKTSTATUS.name.
val groupSelector = TermGroupSelector(PROJEKTSTATUS.name)
val searchGroup = SearchGroup<BytesRef>()
val valueSelector = TermGroupSelector(PROJEKTSTATUS.name)
val groups = mutableListOf(searchGroup)
val distinctValuesCollector = DistinctValuesCollector(groupSelector, groups, valueSelector)
That field is indexed as follows:
document.add(TextField(PROJEKTSTATUS.name, aggregat.projektstatus, YES))
document.add(SortedDocValuesField(PROJEKTSTATUS.name, BytesRef(aggregat.projektstatus)))
Thanks to #andrewJames's hint to a test class I could figure it out:
fun IndexSearcher.collectFilterOptions(query: Query, field: String, topNGroups: Int = 128, mapper: Function<String?, String?> = Function { it }): Set<String?> {
val firstPassGroupingCollector = FirstPassGroupingCollector(TermGroupSelector(field), Sort(), topNGroups)
search(query, firstPassGroupingCollector)
val topGroups = firstPassGroupingCollector.getTopGroups(0)
val groupSelector = firstPassGroupingCollector.groupSelector
val distinctValuesCollector = DistinctValuesCollector(groupSelector, topGroups, groupSelector)
search(query, distinctValuesCollector)
return distinctValuesCollector.groups.map { mapper.apply(it.groupValue.utf8ToString()) }.toSet()
}

Why am I geting a blank when I run this string funtion in Kotlin?

So I was solving a problem that required me to put unique characters in a string without using a data structure.
fun main(){
val s1 = "fhfnfnfjuw"
val s2 = "Osayuki"
val s3 = "Raymond"
val s4 = "Aseosa"
uniqueChar(s1)
}
fun uniqueChar(s: String){
val updatedString = ""
s.forEach {c ->
if (!updatedString.contains(c)){
updatedString.plus(c)
}
}
println(updatedString)
}
And getting this error
I'm not sure what's going on and why I'm getting a blank. I'm sure it's an easy fix, but I can't see it. Any help is appreciated.
updatedString.plus(c) does not change updatedString. It creates a new string, including the character c. Since you don't do anything with that, the new string goes...nowhere.
Instead, you probably wanted updatedString = updatedString.plus(c) -- or something better with StringBuilder, but that's the closest version to your code.

CharBuffer to string?

How to get the string "hi" from the CharBuffer? toString() does not seem to work.
val a = CharBuffer.allocate(10);
a.put('h');
a.put('i');
val b = a.toString();
Variable states after running the code above:
CharBuffer is pretty low-level and really meant for I/O stuff, so it may seem illogical at first. In your example it actually returned a string containing remaining 8 bytes that you didn't set. To make it return your data you need to invoke flip() like this:
val a = CharBuffer.allocate(10);
a.put('h');
a.put('i');
a.flip()
val b = a.toString();
You can find more in the docs of the Buffer
For more typical use cases it is much easier to use StringBuilder:
val a = StringBuilder()
a.append('h')
a.append('i')
val b = a.toString()
Or even use a Kotlin util that wraps StringBuilder:
val b = buildString {
append('h')
append('i')
}

Decimal format in kotlin

Is it possible to use a method or something else rather “%.6f”.format(value) in order to achieve the same thing?
this is my code :
println("%.6f".format(value))
I'll want to make it more dynamic and readable
You can always use
String.format("%.6f", value)
But you can extract the format in a variable
val FORMAT_FLOAT = "%.6f"
println(String.format(FORMAT_FLOAT, value))
It depends on your preferences. Good luck!
You can make it an Extension Function for your project, which is a very powerful feature of Kotlin, the function is like this:
fun Double.roundDecimal(digit: Int) = "%.${digit}f".format(this)
Just put it in a Kotlin file But Outside The Class, then you can access it everywhere in your project:
fun main() {
val number = 0.49555
println(number.roundDecimal(2))
println(number.roundDecimal(3))
}
Output:
0.50
0.496
you can use DecimalFormat class to round a given number. More info
i.e.
val num = 1.345672
val df = DecimalFormat("#.######")
df.roundingMode = RoundingMode.CEILING
println(df.format(num))

Removing unncecessary parts from String

I'm consuming a client that I cannot change and it sends me data that looks like that:
"BOOKING - PAID (price.amount=70, price.currency=EUR)"
and I would like to retrieve from that only 70 EUR
What is the best way to do such thing in kotlin? I didn't find any removeAll("", "", ...) functions for String, only replace but would have to chain them to remove both price.amount and price.currency.
EDIT:
Need to get BOOKING - PAID (70 EUR) actually, forgot about that part.
Thinking about it and as you updated your question to really remove only a part from the string, here are some approaches for removing several strings from a given string:
Using regex:
input.replace("""(price\.(amount|currency)=|,)""".toRegex(), "")
Using a list of strings to remove:
sequenceOf(input, "price.amount=", ",", "price.currency=")
.reduce { acc, rm -> acc.replace(rm, "") }
// alternatively using var:
var input = TODO()
sequenceOf("price.amount=", ",", "price.currency=")
.forEach { input = input.replace(it, "") }
Still: most of the time I would rather take the other route: extracting the information you require and just print that, as also Baptiste has shown in his answer. Otherwise you may start to expose answers of that service you didn't want to expose in the first place.
This sounds like a job for regular expressions!
fun main(args: Array<String>) {
val str = "BOOKING - PAID (price.amount=70, price.currency=EUR)"
// The expressions between parentheses will map to groups[1], groups[2] and groups[3] respectively
val reg = Regex("""(.*) \(price\.amount=([0-9]+), price\.currency=([A-Z]+)\)""")
// Apply the regular expression on the string
val results = reg.find(str)
results?.groupValues?.let { groups ->
// If results and groupValues aren't null, we've got our values!
val type = groups[1]
val price = groups[2]
val currency = groups[3]
println("$type ($price $currency)") // BOOKING - PAID (70 EUR)
}
// Or as suggested by #Roland:
results?.destructured?.let { (type, price, currency) ->
println("$type ($price $currency)") // BOOKING - PAID (70 EUR)
}
}
Regular expressions allow you to take a string as entry, and find a pattern in it. They're quite used in all languages, you can find more info about them all over the place.
EDIT: edited for the updated question. I chose to treat "BOOKING - PAID" as a single string, but there's an infinite number of ways to do it, depending on your granularity needs; and honestly, at that point a regex might be a bit overkill. :)
Without regex by string manipulation and assuming that this is the pattern:
fun main(args: Array <String> ) {
val str = "BOOKING - PAID (price.amount=70, price.currency=EUR)"
val type = str.substringBefore("(").trim()
val price = str.substringBeforeLast(",").substringAfter("=")
val currency = str.substringAfterLast("=").substringBefore(")")
val result = "$type ($price $currency)"
println(result)
}
will print
BOOKING - PAID (70 EUR)
Edit: I use str.substringBeforeLast(",") to get the price, in case , could be used as a delimeter for decimal part in the number