Bmi calculator kotlin - kotlin

I'm in the process of learning android studio and kotlin. I have no experience with java so while learning kotlin I'm only drawing on experience I have from C# programming. I am trying to make a simple script which takes the input from the text field of height and weight take them and put them into a formula that gives the BMI score which is then printed everything works when I tested the script by simply multiply or adding height and weight together to test so I know the general code works. How can I fix my problem atm the output Is always 0 I've messed around using values much larger and it appears to not be multiplying by 10,000 at the end any fixes guys? thanks.
package com.example.test
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val btnChangeText = findViewById(R.id.btn_change_text) as Button
val tvBMI = findViewById(R.id.output_BMI) as TextView
val weight = findViewById(R.id.input_weight) as EditText
val height = findViewById(R.id.input_height) as EditText
btnChangeText.setOnClickListener {
val bmiWeight = weight.text.toString().toInt()
val bmiHeight = height.text.toString().toInt()
val bmiCalc = bmiWeight / bmiHeight / bmiHeight * 10000
tvBMI.text = bmiCalc.toString()
}
}
}

Looks like bmiWeight and bmiHeight are integers. Integer division results in a chopping off of the remainder or simply 0 if the denominator is larger.
Try:
bmiWeight.toDouble() / bmiHeight / bmiHeight * 10000
or get bmiHeight and bmiWeight as a double to begin with
val bmiWeight = weight.text.toString().toDouble()

Related

Bigdecimal operation

why does decrement result -0.8?
What is the logic?
import java.math.BigDecimal
fun main(){
var first = BigDecimal("0.2")
val decrement = --first
println(decrement) //-0.8
}
The -- operator is added by Kotlin onto BigDecimal: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/java.math.-big-decimal/dec.html
For completeness -- means reduce the value by 1, which is why 0.2 - 1 = -0.8. -- is normally used with integers, but it seems Kotlin has extended it for BigDecimal too.

Kotlin - Random numbers without repeating

I have a question, how to prevent random numbers from being repeated.
By the way, can someone explain to me how to sort these random numbers?
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val textView = findViewById<TextView>(R.id.textView)
val button = findViewById<Button>(R.id.buttom)
button.setOnClickListener {
var liczba = List(6){Random.nextInt(1,69)}
textView.text = liczba.toString()
}
}
There are three basic methods to avoid repeating 'random' numbers. If they don't repeat then they are not really random of course.
with a small range of numbers, randomly shuffle the numbers and pick them in order after the shuffle.
with a medium size range of numbers, record the numbers you have picked, and reject any repeats. This will get slow if you pick a large percentage of the numbers available.
with a very large range of numbers you need something like an encryption: a one-to-one mapping which maps 0, 1, 2, 3 ... to the numbers in the (large) range. For example a 128 bit encryption will give an apparently random ordering of non-repeating 128-bit numbers.
Sequences are a great way to generate streams of data and limit or filter the results.
import kotlin.random.Random
import kotlin.random.nextInt
val randomInts = generateSequence {
// this lambda is the source of the sequence's values
Random.nextInt(1..69)
}
// make the values distinct, so there's no repeated ints
.distinct()
// only fetch 6 values
// Note: It's very important that the source lambda can provide
// this many distinct values! If not, the stream will
// hang, endlessly waiting for more unique values.
.take(6)
// sort the values
.sorted()
// and collect them into a Set
.toSet()
run in Kotlin Playground
To make sure this works, here's a property-based-test using Kotest.
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.collections.shouldBeMonotonicallyIncreasing
import io.kotest.matchers.collections.shouldBeUnique
import io.kotest.matchers.collections.shouldHaveSize
import io.kotest.property.Arb
import io.kotest.property.arbitrary.positiveInts
import io.kotest.property.checkAll
import kotlin.random.Random
import kotlin.random.nextInt
class RandomImageLogicTest : FunSpec({
test("expect sequence of random ints is distinct, sorted, and the correct size") {
checkAll(Arb.positiveInts(30)) { limit ->
val randomInts = generateSequence { Random.nextInt(1..69) }
.distinct()
.take(limit)
.sorted()
.toSet()
randomInts.shouldBeMonotonicallyIncreasing()
randomInts.shouldBeUnique()
randomInts.shouldHaveSize(limit)
}
}
})
The test passes!
Test Duration Result
expect sequence of random ints is di... 0.163s passed
val size = 6
val s = HashSet<Int>(size)
while (s.size < size) {
s += Random.nextInt(1,69)
}
I create simple class, in constructor you enter "from" number (minimal possible number) and "to" (maximal posible number), class create list of numbers.
"nextInt()" return random item from collection and remove it.
class RandomUnrepeated(from: Int, to: Int) {
private val numbers = (from..to).toMutableList()
fun nextInt(): Int {
val index = kotlin.random.Random.nextInt(numbers.size)
val number = numbers[index]
numbers.removeAt(index)
return number
}
}
usage:
val r = RandomUnrepeated(0,100)
r.nextInt()
Similar to #IR42's answer, you can do something like this
import kotlin.random.Random
fun getUniqueRandoms() = sequence {
val seen = mutableSetOf<Int>()
while(true) {
val next = Random.nextInt()
// add returns true if it wasn't already in the set - i.e. it's not a duplicate
if (seen.add(next)) yield(next)
}
}
fun main() {
getUniqueRandoms().take(6).sorted().forEach(::println)
}
So getUniqueRandoms creates an independent sequence, and holds its own internal state of which numbers it's produced. For the caller, it's just a basic sequence that produces unique values, and you can consume those however you like.
Like #rossum says, this really depends on how many you're going to produce - if you're generating a lot, or this sequence is really long-lived, that set of seen numbers will get very large over time. Plus it will start to slow down as you get more and more collisions, and have to keep trying to find one that hasn't been seen yet.
But for most situations, this kind of thing is just fine - you'd probably want to benchmark it if you're producing, say, millions of numbers, but for something like 6 it's not even worth worrying about!
You can use Set and MutableSet instead of List:
val mySet = mutableSetOf<Int>()
while (mySet.size < 6)
mySet.add(Random.nextInt(1, 69))

How can I get the value of a T-student distribution?

I have been reviewing the documentation of apache commons math and I find that it also calculates distributions, but I can not understand how it works.
I have two values
degrees of freedom = 13
confidence interval = 0.95
My problem is that it does not yield the value I need,
The objective is:
result = 1.771
import org.apache.commons.math3.distribution.TDistribution
fun calculo(a:Double, b:Double): Double {
val distf = TDistribution(a,b)
return distf.getNumericalMean()
}
fun main(args: Array<String>) {
val ko = calculo(13,0.95)
println(ko)
}
```
You can use the following:
new org.apache.commons.math3.distribution.TDistribution(deg_freedom).
inverseCumulativeProbability(probability)
Where deg_freedom=13, and probability=0.95.

Kotlin Long to Float difference

I am trying to convert Long value to Float in Kotlin. However I am seeing it is changing the value by a small fraction.
Here's a simple test run:
import java.text.DecimalFormat
fun main(args: Array<String>) {
val l = 1513741500
val f:Float = l.toFloat()
val df = DecimalFormat("0")
println(df.format(f))
}
Output:
1513741440
As can be seen there is a slight difference between the values. How can I ensure the same value is returned on conversion?
l: Int = 1513741500
f: Float = 1.51374144E9
d: Double = 1.5137415E9
So if you plan to use large numbers, rather use Double than Float.

How to convert toFixed(2) in Kotlin

What should I write in the place of area.toFixed(2)
fun main(args: Array<String>) {
val a = 20
val h = 30
val area = a * h / 2
println("Triangle area = ${area.toFixed(2)}")
}
I think you really meet a problem that how to convert Javascript code to Kotlin code. You need to ask the question clearly at next time, :). you can use String#format instead, for example:
println("%.2f".format(1.0)) // print "1.00"
println("%.2f".format(1.253)) // print "1.25"
println("%.2f".format(1.255)) // print "1.26"
AND the area is an Int which means it will truncates the precision, Kotlin doesn't like as Javascript use the numeric by default, so you should let a*h divide by a Double, then your code is like as below:
// v--- use a `Double` instead
val area = a * h / 2.0
println("Triangle area = ${"%.2f".format(area)}")