Check If Condition in for loop in kotlin - kotlin

I want to change the btn.text when value is 5, but it's not working. Here's my code:
fun loopFunction(){
for (i in 1 until 5 step 2) {
if (i == 5){
btn.text = "Timer End" //btn is Button
}
println(i)
}
}

The loop will never reach 5 because until excludes the upper value, i.e. it creates an interval that's open on the right, which in this case is [1,5).
If you use rangeTo (or in its operator form, ..), you'll get a range that includes the upper value as well:
fun loopFunction() {
for (i in 1..5 step 2) {
if (i == 5) {
btn.text = "Timer End" //btn is Button
}
println(i)
}
}

Related

tried check valid palindrom string problem solving using kotlin but there is one of the testcase is not passed i tried several times

this is the problem
A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.
Given a string s, return true if it is a palindrome, or false otherwise.
Example 1:
Input: s = "A man, a plan, a canal: Panama"
Output: true
Explanation: "amanaplanacanalpanama" is a palindrome.
Example 2:
Input: s = "race a car"
Output: false
Explanation: "raceacar" is not a palindrome.
myCode
class Solution {
fun isPalindrome(s:String):Boolean {
var s1 = s.toLowerCase()
var myStringBuilder = StringBuilder()
var n = s1.length-1
var n1=myStringBuilder.length
for ( i in 0..n) {
if (Character.isLetterOrDigit(s1[i])) {
myStringBuilder.append(s1[i])
}
}
for( i in 0 .. (n1/2)-1){
if(myStringBuilder[i] != myStringBuilder[n1-i-1]){
return false
}
}
return true
}
}
the first case passed
but this is not passed as per the result Input: s = "race a car result true expected is false
You're initialising n1 too early:
// create an -empty- StringBuilder
var myStringBuilder = StringBuilder()
...
// since it's empty, n1 == 0
var n1=myStringBuilder.length
You're setting it to the length of the StringBuilder contents before you've actually put anything in it. This is a simple value you're setting, it's not a reference to the length getter that will give the current value when you access it. You set it once and that's its value forever.
So your last loop, the one that checks if it's a palindrome or not, never actually runs:
// since n1 is 0, this is for (i in 0..0)
for( i in 0 .. (n1/2)-1){
You can fix it by initialising n1 when you've finished adding your content to the StringBuilder, so you can get its final length:
for ( i in 0..n) {
if (Character.isLetterOrDigit(s1[i])) {
myStringBuilder.append(s1[i])
}
}
// StringBuilder is complete, grab its final length
var n1 = myStringBuilder.length
// now you can use it
for (i in 0..(n1/2)-1) {
Just fyi, there's also an until operator that works like .. except it doesn't include the last value of the range. So you can write
for (i in 0 until (n1/2))
if you want!
You can use this simple solution.
fun isPalindrome(s:String):Boolean {
val str = s.filter { it.isLetterOrDigit() }.lowercase()
for (i in 0..str.length/2 ){
if (str[i]!=str[str.length-i-1])
return false
}
return true
}
Edit:
By the #cactustictacs comment, you can do this in much more simple way.
fun isPalindrome(s:String):Boolean {
val str = s.filter { it.isLetterOrDigit() }.lowercase()
return str == str.reversed()
}

Is there a way to merge filter and map into single operation in Kotlin?

The below code will look for "=" and then split them. If there's no "=", filter them away first
myPairStr.asSequence()
.filter { it.contains("=") }
.map { it.split("=") }
However seeing that we have both
.filter { it.contains("=") }
.map { it.split("=") }
Wonder if there's a single operation that could combine the operation instead of doing it separately?
You can use mapNotNull instead of map.
myPairStr.asSequence().mapNotNull { it.split("=").takeIf { it.size >= 2 } }
The takeIf function will return null if the size of the list returned by split method is 1 i.e. if = is not present in the string. And mapNotNull will take only non null values and put them in the list(which is finally returned).
In your case, this solution will work. In other scenarios, the implementation(to merge filter & map) may be different.
I see your point and under the hood split is also doing an indexOf-check to get the appropriate parts.
I do not know of any such function supporting both operations in a single one, even though such a function would basically just be similar to what we have already for the private fun split-implementation.
So if you really want both in one step (and require that functionality more often), you may want to implement your own splitOrNull-function, basically copying the current (private) split-implementation and adapting mainly 3 parts of it (the return type List<String>?, a condition if indexOf delivers a -1, we just return null; and some default values to make it easily usable (ignoreCase=false, limit=0); marked the changes with // added or // changed):
fun CharSequence.splitOrNull(delimiter: String, ignoreCase: Boolean = false, limit: Int = 0): List<String>? { // changed
require(limit >= 0, { "Limit must be non-negative, but was $limit." })
var currentOffset = 0
var nextIndex = indexOf(delimiter, currentOffset, ignoreCase)
if (nextIndex == -1 || limit == 1) {
if (currentOffset == 0 && nextIndex == -1) // added
return null // added
return listOf(this.toString())
}
val isLimited = limit > 0
val result = ArrayList<String>(if (isLimited) limit.coerceAtMost(10) else 10)
do {
result.add(substring(currentOffset, nextIndex))
currentOffset = nextIndex + delimiter.length
// Do not search for next occurrence if we're reaching limit
if (isLimited && result.size == limit - 1) break
nextIndex = indexOf(delimiter, currentOffset, ignoreCase)
} while (nextIndex != -1)
result.add(substring(currentOffset, length))
return result
}
Having such a function in place you can then summarize both, the contains/indexOf and the split, into one call:
myPairStr.asSequence()
.mapNotNull {
it.splitOrNull("=") // or: it.splitOrNull("=", limit = 2)
}
Otherwise your current approach is already good enough. A variation of it would just be to check the size of the split after splitting it (basically removing the need to write contains('=') and just checking the expected size, e.g.:
myPairStr.asSequence()
.map { it.split('=') }
.filter { it.size > 1 }
If you want to split a $key=$value-formats, where value actually could contain additional =, you may want to use the following instead:
myPairStr.asSequence()
.map { it.split('=', limit = 2) }
.filter { it.size > 1 }
// .associate { (key, value) -> key to value }

How to make keyCode == ENTER update a string?

I have my programme here, where you can see I have a string called "S", and a void Get Temperature. At the bottom where keypresses are processed, it has an else If statement with ENTER. I want it so that when you press enter, it updates the string (s) to whatever you have typed, and then load it into the "SetAddress" field. How would I go about this?
import com.temboo.core.*;
import com.temboo.Library.Yahoo.Weather.*;
import ddf.minim.*;
AudioPlayer player;
Minim minim;
PImage bg;
String myText;
PFont Bold;
PFont Thin;
TembooSession session = new TembooSession("goldsmiths-c", "myFirstApp", "CNgLbwqnqzGdsnk6wHXPfAnQNSmV0Fmr");
String s = "Enter Location";
int prev = frameCount;
//KeyPressed KeyPressed = new KeyPressed();
void setup() {
size(960, 540);
bg = loadImage("mountains.jpg");
minim = new Minim(this);
player = minim.loadFile("song.mp3");
player.play();
player.loop();
runGetTemperatureChoreo();
Bold = createFont ("TTFirsBlackItalic.otf", height);
Thin = createFont ("TTFirsThin.otf", height);
frameRate (30);
}
void draw() {
background(bg);
fill (0);
textFont (Bold);
textSize (48);
fill(255, 255, 255);
text(myText, 10, 390);
fill(255, 255, 255);
textFont (Thin);
textSize (48);
text(s, 10, 500);
print(mouseY);
}
void runGetTemperatureChoreo() {
GetTemperature getTemperatureChoreo = new GetTemperature(session);
getTemperatureChoreo.setAddress(s);
getTemperatureChoreo.setUnits("c");
GetTemperatureResultSet getTemperatureResults = getTemperatureChoreo.run();
myText = (s) + (getTemperatureResults.getTemperature() + ("°c"));
print(getTemperatureResults.getTemperature());
}
void keyPressed()
{
if (keyPressed && prev <= frameCount-10) { //If a key is being pressed, and the security/delay is fine with it
prev = frameCount; //re-Init the clock
if (keyCode == BACKSPACE) { //Delete a char!
if (s.length() > 0) {
s = s.substring(0, s.length()-1);
}
} else if (keyCode == DELETE) {
s = "";
} else if (keyCode == ENTER && s.length() != 0) {
} else if (keyCode != SHIFT && keyCode != CONTROL && keyCode != ALT && s.length() < 20) { //It's an ok char, add it to the String
s += key;
}
}
}
Well, it looks like you're storing what the user types in the s variable. You then have this part of your if statement:
else if (keyCode == ENTER && s.length() != 0) {
}
That else if will be entered whenever the user presses enter after typing something. So you just have to put whatever code you want inside the body of that statement:
else if (keyCode == ENTER && s.length() != 0) {
getTemperatureChoreo.setAddress(s);
}
I might not be fully understanding your code, so this is just an example. But the basic idea is the same: to do something when the user presses enter, just put the code you want to happen inside this else if block.
In the future, please try to post an MCVE instead of your entire sketch. For example, your question has nothing to do with minim, so you can get rid of all of that code. Start over with a blank sketch and only add enough code so we can copy and paste it to run it ourselves to see where you're stuck. Good luck.

I am getting an error (variable y might not have been initialised in the if's in the loop. How to solve that?

import java.util.Scanner;
public class RPS
{
public void show()
{
int i;
System.out.println("1 - Rock 2 - Paper 3 - Scissor");
Scanner in = new Scanner(System.in);
i = in.nextInt();
double x = Math.random();
int y;
if(x<=0.33)
{
y=1;
}
else if(x>0.33 && x<0.67)
{
y=2;
}
else if(x>=0.67)
{
y=3;
}
for(;;)
{
if(i==y)
System.out.println("It's a draw!");
else if(i==1 && y==2)
System.out.println("Computer wins!");
else if(i==1 && y==3)
System.out.println("You win!");
else if(i==2 && y==1)
System.out.println("You win!");
else if(i==2 && y==3)
System.out.println("Computer wins!");
else if(i==3 && y==1)
System.out.println("Computer wins!");
else if(i==3 && y==2)
System.out.println("You win!");
else
System.out.println("Error!");
}
}
}
Whats wrong?
It gives an error that variable y might not have been intialised in the if's in the for loop.
I have assigned a value to y in the previous if-else section.
so why isnt it getting intialised?
javac is not smart enough to realize that the way your conditions are constructed, one of them will always be true.
You can rewrite your if-statements to make javac realize one branch will always be triggered:
int y;
if(x<=0.33)
{
y=1;
}
else if(x>0.33 && x<0.67)
{
y=2;
}
else // This only triggers when x >= 0.67, so no need to check
{
y=3;
}
Now javac sees that if the first two don't trigger, the last will, so y will always have a value.
You can alternatively add an else branch with an error, in case someone breaks the conditions:
int y;
if(x<=0.33)
{
y=1;
}
else if(x>0.33 && x<0.67)
{
y=2;
}
else if(x >= 0.67)
{
y=3;
}
else
{
// This should never happen
throw new IllegalArgumentException("Something's gone terribly wrong for " + x);
}
This also compiles, and if someone later decides to skew the numbers and turns the first condition into x <= 0.2 but forgets to update the other condition, you'll get an exception at runtime.

How to switch cases with ( - ) and ( + ) keys presses?

I am working with AutoHotKey. I know I have tagged C also, I think someone with enough C programming knowledge can also help here.
Code below is working for me.
It will read two keyboard input from user and based on what user pressed it will run code for that case.
1::
Input Key, L1
if Key=1
{
;your code
}
if Key=2
{
;your code
}
2::
Input Key, L1
if Key=1
{
;your code
}
if Key=2
{
;your code
}
I would like to know if I can add a loop or something if user presses + or - key it will go do one case at a time,
for example if user presses + for first time it will do
1 1 if user presses + again it will do
1 2 if user presses - it will do
1 1
and so on.
I am not sure if this is do able or not.
I am new to programming. please help :)
You can use global variables. A global variable can be accessed anywhere in the program, unlike a normal variable which exists only inside the function.
Example:
#NoEnv
#Persistent
SetBatchLines, -1
global myVar = 0
h::
myVar := myVar + 1
execute()
return
g::
myVar := myVar - 1
execute()
return
execute()
{
if(myVar == 1)
{
;do stuff
tooltip, myVar: %myVar%
}
else if (myVar == 2)
{
;do stuff
tooltip, myVar: %myVar%
}
else if (myVar == 3)
{
;do stuff
tooltip, myVar: %myVar%
}
else if (myVar == 4)
{
;do stuff
tooltip, myVar: %myVar%
}
else if (myVar == 5)
{
;do stuff
tooltip, myVar: %myVar%
}
else
{
; nothing
tooltip,
}
return
}
I hope this is what you were asking, i wasn't quite sure from the question.
; Some of this is what's called Pseudo code. (not sure if you're familiar). It gives you needs to be turned into actual code...
; Written for AHK...
CurrentNumber = 1
(plus key)::
CurrentNumber += 1
send %CurrentNumber%
return
(minus key)::
CurrentNumber -= 1
send %CurrentNumber%
return
; Not sure if this is what you were looking for or not.. if you want a loop it will be different.
; either way, good luck to you, i'm out..
+::
keywait, +, u
{
If var =
var = 11
Else
var++
}
Return
-::
keywait, -, u
{
If var =
var = 11
Else
var--
}
Return
"var" should have same name with the variable, which has two or one digit number, in your code.
You may use this too
NumpadAdd::
keywait, NumpadAdd, u
{
If var =
var = 11
Else
var++
}
Return
NumpadSub::
keywait, NumpadSub, u
{
If var =
var = 11
Else
var--
}
Return