Won't go inside if statemente even when statemente is true. Kotlin - kotlin

I'm trying to make a simple calculator but the equals button doesn't perform as expected, it doesn't do any of the operations even though the if statement is true. This is the code
var value1: Float = 0f
var value2: Float = 0f
var operator: String = "n"
val input = expression.text.toString().trim()
//this is the adding button the subtracting, multiplying, and dividing are basically the exact code
plus.setOnClickListener {
if (input.isNullOrBlank()) {
expression.text = ""
} else {
operator = "sum"
value1 = expression.text.toString().toFloat()
expression.text = ""
}
}
//equals button
equals.setOnClickListener {
val input2 = expression.text.toString().trim()
if (!input2.isNullOrBlank()) {
value2 = expression.text.toString().toFloat()
// this is the textView and it always shows up as n
expression.text = operator
//it never goes in any of these, I don't know if I'm setting it up wrong in the action buttons (add, sub, multi, div)
if (operator == "sum") {
var s = value1 + value2
expression.text = s.toString()
operator = "n"
}
if (operator == "sub") {
var r = value1 - value2
expression.text = r.toString()
operator = "n"
}
if (operator == "div") {
var d = value1 / value2
expression.text = d.toString()
operator = "n"
}
if (operator == "multi") {
var m = value1 * value2
expression.text = m.toString()
operator = "n"
}
}
}
Why is this happening? I don't know if I'm setting up the operator String wrong or if it's something else I'm doing wrong.
I wanted to have it so that if the values aren't imputed than the operator or equals button won't work like on the phone calculator

val input = expression.text.toString().trim()
Here you capture the content of that edittext at view setup phase. It's likely empty at this point.
Then, in the click listener you have conditional code for that value:
plus.setOnClickListener {
if (input.isNullOrBlank()) {
expression.text = ""
} else {
operator = "sum"
value1 = expression.text.toString().toFloat()
expression.text = ""
}
}
and the input.isNullOrBlank() condition is always true so the else branch never gets executed.
You likely should read the input (val input = expression.text.toString().trim()) inside the click listener.

This is what I came up with
//operator buttons
plus.setOnClickListener {
if (expression.text.toString().trim().isNullOrBlank()) {
expression.text = ""
} else {
value1 = expression.text.toString().toFloat()
operador = "suma"
expression.text = ""
}
}
the equals button stays the same

Related

Kotlin - The caracter literal does not conform expect type Int

I'm struggling with types with my program, I've been asked to do it in JS first and it worked fine but now I can't achieve the result.
Do you think I should make another 'algorithm' ? In advance, thank you for your time.
fun main(){
// the idea is to put numbers in a box
// that cant be larger than 10
val data = "12493419133"
var result = data[0]
var currentBox = Character.getNumericValue(data[0])
var i = 1
while(i < data.length){
val currentArticle = Character.getNumericValue(data[i])
currentBox += currentArticle
println(currentBox)
if(currentBox <= 10){
result += Character.getNumericValue(currentArticle)
}else{
result += '/'
//var resultChar = result.toChar()
// result += '/'
currentBox = Character.getNumericValue(currentArticle)
result += currentArticle
}
i++
}
print(result) //should print 124/9/341/91/33
}
The result is actually of a Char type, and the overload operator function + only accepts Int to increment ASCII value to get new Char.
public operator fun plus(other: Int): Char
In idomatic Kotlin way, you can solve your problem:
fun main() {
val data = "12493419133"
var counter = 0
val result = data.asSequence()
.map(Character::getNumericValue)
.map { c ->
counter += c
if (counter <= 10) c.toString() else "/$c".also{ counter = c }
}
.joinToString("") // terminal operation, will trigger the map functions
println(result)
}
Edit: If the data is too large, you may want to use StringBuilder because it doesn't create string every single time the character is iterated, and instead of using a counter of yourself you can use list.fold()
fun main() {
val data = "12493419133"
val sb = StringBuilder()
data.fold(0) { acc, c ->
val num = Character.getNumericValue(c)
val count = num + acc
val ret = if (count > 10) num.also { sb.append('/') } else count
ret.also { sb.append(c) } // `ret` returned to ^fold, next time will be passed as acc
}
println(sb.toString())
}
If you want a result in List<Char> type:
val data = "12493419133"
val result = mutableListOf<Char>()
var sum = 0
data.asSequence().forEach {
val v = Character.getNumericValue(it)
sum += v
if (sum > 10) {
result.add('/')
sum = v
}
result.add(it)
}
println(result.joinToString(""))

Adding, subtracting, dividing and multiplying two numbers. Kotlin

I'm trying to take a simple calculator in Java and convert the code to Kotlin as an example, I've never used Kotlin before and I'm lost. I'm trying to take a number from a editText and convert it to a float to do the actual conversions and then do the operations on these for the result
var value1: Float? = null
var value2: Float? = null
var suma: Boolean = false
var resta: Boolean = false
var multi: Boolean = false
var div: Boolean = false
plus.setOnClickListener {
if (expression == null) {
expression.text = ""
} else {
value1 = expression.text.toString().toFloat()
suma = true
expression.text = ""
}
}
mul.setOnClickListener {
if (expression == null) {
expression.text = ""
} else {
value1 = expression.text.toString().toFloat()
multi = true
expression.text = ""
}
}
minus.setOnClickListener {
if (expression == null) {
expression.text = ""
} else {
value1 = expression.text.toString().toFloat()
resta = true
expression.text = ""
}
}
divide.setOnClickListener {
if (expression == null) {
expression.text = ""
} else {
value1 = expression.text.toString().toFloat()
div = true
expression.text = ""
}
}
dot.setOnClickListener {
expression.text = expression.text.toString() + "."
}
clear.setOnClickListener {
expression.text = ""
value1 = null
value2 = null
}
equal.setOnClickListener {
value2 = expression.text.toString().toFloat()
if (suma) {
var s = value1 + value2
expression.text = s.toString()
}
if (resta) {
var r = value1 - value2
expression.text = r.toString()
}
if (div) {
var d = value1 / value2
expression.text = d.toString()
}
if (multi) {
var m = value1 * value2
expression.text = m.toString()
}
}
When I try to do the adding, subtracting, multiplying or dividing the code is underlined in red after the operator and the value2 as well, the suggestion is to do this value1.plus(value2) but if I do that it also is in red and says only save or non-null asserted calls are allowed on a nullable reciever of type Float? If I follow all the suggestions it gives me it still doesn't stop being underlined in red.
This is how I'm starting the values
var value1: Float? = null
var value2: Float? = null
Don't make your values nullable. It's rarely necessary to need nullable primitive properties. The error you're getting is because you're trying to use values that might be null.
Instantiate them like this.
var value1: Float = 0f
var value2: Float = 0f
And in your clear() function, set them back to 0f rather than null.
If you really have to keep them null, you could do something like this where you only add them after checking they are both non-null, and then show an error message if either value is null:
if (suma) {
val s = value1?.let { value2?.plus(it) }
expression.text = s?.toString() ?: "Invalid input value(s)"
}
//...
Edit in response to your comment:
A typical calculator just resets the operator when you press = before anything else, so I would rewrite the equal button's listener like this (with a when statement for simplicity). I'm removing the value2 member property because it's unnecessary and using a local property instead.
equal.setOnClickListener {
val value2 = expression.text.toString().toFloatOrNull()
if (value2 != null) {
val result = when {
suma -> value1 + value2
resta -> value1 - value2
div -> value1 / value2
multi -> value1 * value2
else -> value1 // Shouldn't happen but can default to not changing number
}
expression.text = result.toString()
}
// reset for next operation
suma = false
resta = false
div = false
multi = false
}

Kotlin decomposing numbers into powers of 2

Hi I am writing an app in kotlin and need to decompose a number into powers of 2.
I have already done this in c#, PHP and swift but kotlin works differently somehow.
having researched this I believe it is something to do with the numbers in my code going negative somewhere and that the solution lies in declaring one or more of the variable as "Long" to prevent this from happening but i have not been able to figure out how to do this.
here is my code:
var salads = StringBuilder()
var value = 127
var j=0
while (j < 256) {
var mask = 1 shl j
if(value != 0 && mask != 0) {
salads.append(mask)
salads.append(",")
}
j += 1
}
// salads = (salads.dropLast()) // removes the final ","
println("Salads = $salads")
This shoud output the following:
1,2,4,8,16,32,64
What I actually get is:
1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,33554432,67108864,134217728,268435456,536870912,1073741824,-2147483648,
Any ideas?
This works for the one input that you specified, at the very least:
fun powersOfTwo(value :Long): String {
val result = ArrayList<String>()
var i = 0
var lastMask = 0
while (lastMask < value) {
val mask = 1 shl i
if (value != 0.toLong() && mask < value) {
result.add(mask.toString())
}
lastMask = mask
i += 1
}
return result.joinToString(",")
}
Ran it in a unit test:
#Test
fun addition_isCorrect() {
val result = powersOfTwo(127)
assertEquals("1,2,4,8,16,32,64", result)
}
Test passed.
You can get a list of all powers of two that fit in Int and test each of them for whether the value contains it with the infix function and:
val value = 126
val powersOfTwo = (0 until Int.SIZE_BITS).map { n -> 1 shl n }
println(powersOfTwo.filter { p -> value and p != 0}.joinToString(","))
// prints: 2,4,8,16,32,64
See the entire code in Kotlin playground: https://pl.kotl.in/f4CZtmCyI
Hi I finally managed to get this working properly:
fun decomposeByTwo(value :Int): String {
val result = ArrayList<String>()
var value = value
var j = 0
while (j < 256) {
var mask = 1 shl j
if ((value and mask) != 0) {
value -= mask
result.add(mask.toString())
}
j += 1
}
return result.toString()
}
I hope this helps someone trying to get a handle on bitwise options!
Somehow you want to do the "bitwise AND" of "value" and "mask" to determine if the j-th bit of "value" is set. I think you just forgot that test in your kotlin implementation.

Use/select enumeration values in DXL DOORS

I tried to use somekind of condition of another attribute object to set the attribute with pre-set enumeration values {"", "1","2","3"}, something like:
if ( o."attr1" = "AA" ) {
o."enumeratedAttr" = "1"
} else if (o."attr1" = "BB" ) {
o."enumeratedAttr" = "1"
} else {
o."enumeratedAttr" = "" //no change as default
}
However, as enumeration attribute return its element as DBE. My script above won't work. So How can I set/select one of enumeration values at each condition. Thanks.
Okay, I'm going to take a crack at this, and I hope it is helpful.
if ( o."attr1" = "AA" ) {
o."enumeratedAttr" = "1"
} else if (o."attr1" = "BB" ) {
o."enumeratedAttr" = "1"
} else {
o."enumeratedAttr" = "" //no change as default }
This won't pull the enum as the type that you want. If you want to compare the Enum to a string, you'll need something like this:
if ( o."attr1" "" == "AA" ) {
o."enumeratedAttr" = "1"
} else if (o."attr1" "" == "BB" ) {
o."enumeratedAttr" = "1"
} else {
o."enumeratedAttr" = "" //no change as default }
You will need to make sure that you don't assign o."enumeratedAttr" to a value that isn't valid for the enum type - this will cause a DXL error.
Adding the quotes ( "" ) after the object / attribute call ensures that DOORS is doing a string to string comparison.

ActionScript 2.0 Random Boolean Function not working

I have the below code which show be randomly true and randomly false. But in my case its always being false. Any help is appreciated. Thanks.
In the below code tail and heads are the tow buttons.
on(release)
{
var guess:Boolean = Boolean(Math.round(Math.random()));
var input:Boolean;
if (event.target.name == "tail"){
input = true;
}
else if (event.target.name == "heads"){
input = false;
}
if (guess == input){
var newresult = Number(income.text) + Number(amount.text);
income.text = Number(newresult);
}
else{
var newresult = Number(income.text) - Number(amount.text);
income.text = Number(newresult);
}
}
This will also work:
on(release)
{
var guess:Boolean = Boolean(Math.floor(Math.random()*2));
if (guess){
result.text = "Your Guess is corrent";
var newresult = Number(income.text) + Number(amount.text);
income.text = Number(newresult);
}
else{
result.text = "Your Guess is wrong";
var newresult = Number(income.text) - Number(amount.text);
income.text = Number(newresult);
}
}
You dont need the event.target.name because the function is within the event handler of each button. So you can just use a random boolean. Event.target.name also doesnt work in AS2.0