how to convert an integer number to decimal kotlin? - string

I am trying to convert cm to ft. I get cm in my convertion function and translate cm to ft. like this
val ftHeight = _height * 0.032808399
it works properly but ftHeight contains ft and inc together. I have to seperate ft and inc values because I show different textfields them.
I seperate ftHeight like this
val inc = ftHeight.toString().substringAfter(".")
val ft = ftHeight.toString().substringBefore(".")
but there is a problem for example I assume that ftHeight is equal 3.289812
so that
ft : 3
inc : 289812
when I try to calculate ft to cm I need to ft and inc values but the value of inc should not be like this
it should be like this for my calculatin
0.289812
How can I solve that issue? can you help me ?
hear is my calculation function
fun onCmToFtChange(_height: Int) {
val ftHeight = _height * 0.032808399
val inc = ftHeight.toString().substringAfter(".")
val ft = ftHeight.toString().substringBefore(".")
_viewState.update {
it.copy(
ft = ft,
inc = "${inc[0]}",
_ft = ft.toInt(),
_inc = "0.{$inc}".toInt(). // this is incorrect code I just tryed something for this issue but it didnt work
)
}
}

you can change the way you calculate inc,
Instead of
val inc = ftHeight.toString().substringAfter(".")
val ft = ftHeight.toString().substringBefore(".")
You can use:
val ft = ftHeight.toString().substringBefore(".")
val inc = ftHeight - ft.toInt()
If you want to stick to your previous approach and convert string to Double, you can use:
val inc = ftHeight.toString().substringAfter(".")
val ft = ftHeight.toString().substringBefore(".")
val _inc = "0.$inc".toDouble()

You could do
val ft= ftHeight.toInt()
val inc = ((ftHeight % 1) * 12).toInt()
To get the feet and inches. Note I already did the conversion to take into account that a foot is 12 inches

Related

how to extract an integer range from a string

I have a string that contains different ranges and I need to find their value
var str = "some text x = 1..14, y = 2..4 some text"
I used the substringBefore() and substringAfter() methodes to get the x and y but I can't find a way to get the values because the numbers could be one or two digits or even negative numbers.
One approach is to use a regex, e.g.:
val str = "some text x = 1..14, y = 2..4 some text"
val match = Regex("x = (-?\\d+[.][.]-?\\d+).* y = (-?\\d+[.][.]-?\\d+)")
.find(str)
if (match != null)
println("x=${match.groupValues[1]}, y=${match.groupValues[2]}")
// prints: x=1..14, y=2..4
\\d matches a single digit, so \\d+ matches one or more digits; -? matches an optional minus sign; [.] matches a dot; and (…) marks a group that you can then retrieve from the groupValues property. (groupValues[0] is the whole match, so the individual values start from index 1.)
You could easily add extra parens to pull out each number separately, instead of whole ranges.
(You may or may not find this as readable or maintainable as string-manipulation approaches…)
Is this solution fit for you?
val str = "some text x = 1..14, y = 2..4 some text"
val result = str.replace(",", "").split(" ")
var x = ""; var y = ""
for (i in 0..result.count()-1) {
if (result[i] == "x") {
x = result[i+2]
} else if (result[i] == "y") {
y = result[i+2]
}
}
println(x)
println(y)
Using KotlinSpirit library
val rangeParser = object : Grammar<IntRange>() {
private var first: Int = -1
private var last: Int = -1
override val result: IntRange
get() = first..last
override fun defineRule(): Rule<*> {
return int {
first = it
} + ".." + int {
last = it
}
}
}.toRule().compile()
val str = "some text x = 1..14, y = 2..4 some text"
val ranges = rangeParser.findAll(str)
https://github.com/tiksem/KotlinSpirit

Problem with Double, String and Integer conversion

Why is the value 4.49504794 ? It should be usdRate:String * sas * ddx:EditText.
I want it to be 0.00000001 * input from edittext (from user) * usdRate:String (1 BTC in USD)
It should be 0.00000001/44950 * x (user_input = x) = (0,00002224694105)
I'm also wanting to limit usdRate:String to only 5 digits total, or somehow remove the last four symbols in the string.
var usdRate:String = (JSONObject(json).getJSONObject("bpi").getJSONObject("USD")["rate"] as String)
val text = usdRate.replace(",", "")
val text2 = text.replace(".", "")
val satosh: Int = text2.toInt()
val sas: Double = 0.00000001
val sas2: Double = sas.toDouble() * satosh.toDouble()
val ddx:EditText = findViewById(R.id.editTextNumber2)
val sasEnty: Double = (ddx.text.toString().toDouble() * sas2)
//1 satoshi value in USD
usdView.text = sasEnty.toString()
//Problem end
Picture of output in application
Output
This code gave me the output I was looking for. When a user input 3 as a value, will it return 0.0013994405520000002
//ex 45,000.01234
var usdRate: String = (JSONObject(json).getJSONObject("bpi").getJSONObject("USD")["rate"] as String).toString()
val usdRateN1: String = usdRate.replace(",", "")
val sastoshi: Double = 0.00000001
var antalSatoshi = sastoshi * ddx.text.toString().toDouble()
var FinalUsdCount = (usdRateN1.toDouble() * antalSatoshi )
Math.round(FinalUsdCount)

treeAggregate use case explanation

I am trying to understand treeAggregate but there isn't enough examples online.
So does the following code merges the elements of partition then calls makeSummary and in parallel do the same for each partition (sums the result and summarizes it again) then with depth set to (lets say) 5, is this repeated 5 times?
The result I want to get from these is to summarize the arrays until I get one of them.
val summary = input.transform(rdd=>{
rdd.treeAggregate(initialSet)(addToSet,mergePartitionSets,5)
// this returns Array[Double] not rdd but still
})
val initialSet = Array.empty[Double]
def addToSet = (s: Array[Double], v: (Int,Array[Double])) => {
val p=s ++ v._2
val ret = makeSummary(p,10000)
ret
}
val mergePartitionSets = (p1: Array[Double], p2: Array[Double]) => {
val p = p1 ++ p2
val ret = makeSummary(p,10000)
ret
}
//makeSummary selects half of the points of p randomly

Accessing rows outside of window while aggregating in Spark dataframe

In short, in the example below I want to pin 'b to be the value in the row that the result will appear in.
Given:
a,b
1,2
4,6
3,7 ==> 'special would be: (1-7 + 4-7 + 3-7) == -13 in this row
val baseWin = Window.partitionBy("something_I_forgot").orderBy("whatever")
val sumWin = baseWin.rowsBetween(-2, 0)
frame.withColumn("special",sum( 'a - 'b ).over(win) )
Or another way to think of it is I want to close over the row when I calculate the sum so that I can pass in the value of 'b (in this case 7)
* Update *
Here is what I want to accomplish as an UDF. In short, I used a foldLeft.
def mad(field : Column, numPeriods : Integer) : Column = {
val baseWin = Window.partitionBy("exchange","symbol").orderBy("datetime")
val win = baseWin.rowsBetween(numPeriods + 1, 0)
val subFunc: (Seq[Double],Int) => Double = { (input: Seq[Double], numPeriods : Int) => {
val agg = grizzled.math.stats.mean(input: _*)
val fooBar = (1.0 / -numPeriods)*input.foldLeft(0.0)( (a,b) => a + Math.abs((b-agg)) )
fooBar
} }
val myUdf = udf( subFunc )
myUdf(collect_list(field.cast(DoubleType)).over(win),lit(numPeriods))
}
If I understood correctly what you're trying to do, I think you can refactor your logic a bit to achieve it. The way you have it right now, you're probably getting "-7" instead of -13.
For the "special" column, (1-7 + 4-7 + 3-7), you can calculate it like (sum(a) - count(*) * b):
dfA.withColumn("special",sum('a).over(win) - count("*").over(win) * 'b)

Count how many times a string repeats itself SCALA

Hi I´m trying to get the number of times an artist name repeats in some years for this I have this
var artists=Array.ofDim[String](994,2)//artist,year
var artists2=Array.ofDim[String](250)//artist name
var artists3 = Array.ofDim[Int](250)//number of times
And the user has to enter ano1 and ano2 that are the years margin we want
val loop = new Breaks;
for(i <- 0 to 993){//copiamos
loop.breakable{
for(j<- 0 to 249){
if(artists2(j).contentEquals("NULL") && artists(i)(1).toInt>=ano1 && artists(i)(1).toInt<=ano2){
artists2(j)=artists(i)(0)
artists3(j)= 1
loop.break;
}else if(artists(i)(0).contentEquals(artists2(j)) && artists(i)(1).toInt>=ano1 && artists(i)(1).toInt<=ano2){
artists3(j)= artists3(j)+1
loop.break;
}
}
}
}
println(artists2.mkString("\n"))
println(artists3.mkString(","))
For some reason my if doesnt work or j add itself 1 after entering in the if because every time is creating a new element in artists2 instead of adding it to artists3
The output I get is artists3 filled with 1 because for some reason it never checks the other part of the if
I'm sorry if this sounds a bit harsh, but there are so many things wrong with your code it's hard to know where to begin.
The main problems are 1) your code isn't very scala-like, and 2) you're using data structures and variable names designed to make things as difficult as possible to understand.
Here's a brief attempt to redesign things. It may not meet all your requirements but perhaps it will start you in a better direction.
val mockdata = List( ("Tom", 2001)
, ("Sue", 2002)
, ("Joe", 2002)
, ("Sue", 2005)
, ("Sue", 2004)
, ("Jil", 2001)
, ("Tom", 2005)
, ("Sue", 2002)
, ("Jil", 2012)
)
def countArtists( dataSet: List[(String,Int)]
, anoStart: Int , anoEnd: Int): Map[String,Int] = {
val artists = for {
(artist, year) <- dataSet
if year >= anoStart && year <= anoEnd
} yield artist
artists.distinct.map(name => name -> artists.count(_ == name)).toMap
}
val count2002to2011 = countArtists(mockdata, 2002, 2011)
At this point you can use the result to get interesting information.
scala> count2002to2011.keys // all artists within the time period
res0: Iterable[String] = Set(Sue, Joe, Tom)
scala> count2002to2011.values.sum // total count within the time period
res1: Int = 6
scala> count2002to2011("Sue") // count for just this artist
res2: Int = 4
your implementation seems a little bit confused, if i understood what you needed, i would like if i may, share how i would have implemented your research, in a more functionnal/scala and clear way.
case class Artist(name: String, year: Int)
case class ArtistNames(name: String)
case class ArtistResult(name: String, nbOccurence: Int)
val anno1 = 1950
val anno2 = 1960
def checkArtist(artists: Seq[Artist], artistNames: Seq[ArtistNames]): Seq[ArtistResult] = {
artists.map{ artist =>
def countOccurence(artist: Artist, artistNames: Seq[ArtistNames], occurence: Int): Int = {
artistNames match {
case Nil => occurence
case head :: tail =>
if (head.name == artist.name && artist.year >= anno1 && artist.year <= anno2) countOccurence(artist, tail, occurence + 1)
else countOccurence(artist, tail, occurence)
}
}
val occurrence = countOccurence(artist, artistNames, 0)
ArtistResult(artist.name, occurrence)
}
}
val artistResultList: Seq[ArtistResult] = checkArtist(/* insert your data here */)
i hope i answered a little bit your question.

Resources