I need to compare property values in StringTemplate - stringtemplate

I have a list of tuples that I need to emit a C-like boolean expression from:
ranges = [('a','z'),('0','9'),('_','_')]
my template:
"$ranges:{'$it.0$'<=c&&c<='$it.1$'}; separator='||'$"
this outputs:
'a'<=c&&c<='z'||'0'<=c&&c<='9'||'_'<=c&&c<='_'
I would like to check if $it.0$ is the same as $it.1$ and output c==='$it.0$' in this case (in my example this would generate c==='_' for the last tuple). Is this possible?

You can't have any computation in the template (see Stringtemplate compare strings does not work).
A possible way of getting around this would be to use a custom Range class, and store the functionality inside that. Then you could call a method on the range object that returned whether or not the from and to values are equal.
$ranges:{ range | $if(range.fromToEqual)$c === '$range.from$'$else$'$range.from$' <= c && c <= '$range.to$'$endif$}; separator=" || "$
where the method in the Range class is as follows:
public boolean getFromToEqual() { // note the 'get' prefix
return from == to;
}
output:
'a' <= c && c <= 'b'||'1' <= c && c <= '9'|| c === '_'

Related

Why is my Kotlin comparable not makign correct equality comparisons?

I am currently trying to make a comparable object and working on the compareTo() function, for which I wrote the following code
class InfoAcad(e: String, m: String, c: Int): Comparable<InfoAcad> {
override operator fun compareTo(other: InfoAcad): Int {
if (this.e < other.e) return -1
if (this.e > other.e) return 1
if (this.e == other.e && this.m < other.m) return -1
if (this.e == other.e && this.m > other.m) return 1
return 0
}
}
The idea is that e is an ID number inputted as a string, which always follows the format XX-XXX where every X character is an integer between 0 and 9, and m is a course code following the format LL-XXX where each L character is a capital letter between A and Z and the X characters are integers between 0 and 9 like in the ID numbers. The objects are first compared by their ID number, and if the ID numbers are equal they are then compared by the course code, if both values are the same then the objects are equal, the c parameter is not taken into account in the comparison. I found out yesterday that I could compare strings directly in Kotlin in < and > relations, so I decided to try using that to make the task of comparing the InfoAcad objects a bit easier on myself, however when I make a main function to test the comparisons, the equality always returns a false value independently of what is in the string values of the InfoAcad objects. Here's said main function:
fun main() {
var A = InfoAcad("18-10125", "CI-2526", 3)
var B = InfoAcad("18-10125", "CI-2526", 5)
println("A = B: " + (A == B).toString()) //true
println("A < B: " + (A < B).toString()) //false
ptintln("A > B: " + (A > B).toString()) //false
}
When I change characters in the ID and course code values the inequality relations work just as intended, so what could be causing the equality relation to always return false? I appreciate and thank any responses in advance.
Note: I have also tried giving A and B the same c value, the equality part still returned false.
Override the equals function as well, or use a data class.
compareTo is only used for the < and > operators. The == operator is implemented by the separate equals function.
You can find the available operators, and the functions you need to override for each, in the Operator overloading section of the Kotlin docs.
If you don't override the equals function, the default behaviour is for it to use object identity. That means that two different objects, even if they contain the same fields, will never be considered equal.
There is however a nice shortcut for what you want to do! Kotlin will automatically generate an equals function for you if you make your class a data class. It's a good fit for classes like yours, whose main purpose is to hold data.
Because == and != translates to a call to equals(other: Any?): Boolean method, from kotlinlang
Expression Translated to
a == b a?.equals(b) ?: (b === null)
a != b !(a?.equals(b) ?: (b === null))
These operators only work with the function equals(other: Any?): Boolean, which can be overridden to provide custom equality check
implementation. Any other function with the same name (like
equals(other: Foo)) will not be called.

how do i correctly use >= and <= in code?

I have tried many thing involving this, >=, >==, =>, ==>.i can not find one that works. hey all return either primary expression needed or expected initializer before '>'. I am creating a IR receiver latch switch and thus have to create parameters for the code because the receiver is not constant in all conditions. Full code below. Any suggestions to fix the code please reply and don't DM me. Thank you.
code:
int LEDState = 0;
int LEDPin = 8;
int dt = 100;
int recieverOld ==> 500 and recieverOld ==< 2000;
int recieverNew;
int recieverPin = 12;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(LEDPin, OUTPUT);
pinMode(recieverPin, INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
recieverNew = digitalRead(recieverPin);
if((recieverOld >== 0 && recieverOld <== 10) && (recieverNew >== 500 && recieverNew <== 2000) {
if(LEDState == 0) {
digitalWrite(LEDPin, HIGH);
LEDState = 1;
}
}
recieverOld = recieverNew;
delay(dt);
}
error:
expected initializer before '==' token
if one = used line 4 and related, return error expected primary-expression before '>' token
if > before = line 4 and related, return error expected initializer before '>=' token
Any solutions or suggestions welcome.
TL;DR
Operators that do no exist, and that you should NOT use:
==>, ==<, >==, <==
Operators that works and you can use them:
>= - MORE THAN OR EQUAL, compare operator, for example X >= 5
<= - LESS THAN OR EQUAL, compare operator, for example X <= 5
> - MORE THAN, compare operator, for example X > 5
< - LESS THAN, compare operator, for example X < 5
== - compare operator, when you want to compare values of the variables if they have the same value, for example X == 5, Y == X, 10 == 7
=== - equality operator, similar to compare operator ==, but aditionally checks the type of a variable. for example X === Y, '10' === 10
= - assign operator, when you want to assign something to the variable, for example X = 5
<> OR != - NOT EQUAL, compare operator, for example X != 5, Y <> 10
!== - similar to != or <>, but also checks the type of a value. For example 10 !== '10', and will return opposite result of the equality operator ===

Using in operator to compare string with range of strings

I am using in operator to check whether a value is in range. But I am not able to understand exactly how the comparison with range of strings is done. Below are the few arguments and their output which I have tried:
println("KOTLIN" in "J".."K")
false
println("KOTLIN" in "Java".."Scala")
true
println("KOTLIN" in "Java".."Bhuv")
false
in is compiled down to the following function (defined in kotlin.ranges.Range.kt):
public operator fun contains(value: T): Boolean = value >= start && value <= endInclusive
So "KOTLIN" in "J".."K" results in:
("J".."K").contains("KOTLIN")
The comparison in this case relies on normal String comparisons since >= and <= are compiled down to variations of compareTo. The implementation looks as follows:
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
So, "KOTLIN" in "Java".."Scala" is equal to the following:
"KOTLIN".compareTo("Java") >=0 && "KOTLIN".compareTo("Scala") <= 0
Based on your question, I think you are confused about this result:
println("KOTLIN" in "J".."K") is false
Basically, if you were to sort these using Java's String comparison implementation, you would see this:
Bhuv
J
Java
K
KOTLIN
KZ
Since K is lexicographically before KOTLIN, the result you are seeing makes total sense.
Lexicographic Order aka Dictionary Order, e.g.. when scrolling down the words in a dictionary, the order of the words will be
1.Java
2.Kotlin
3.Scala
Hence,
(Kotlin in Java..Scala) will return true.
In normal english, the code above is stating that by using the Dictionary Order, the word Kotlin is found in between the word Java and Scala.

How to define a single byte variable in go lang

I am a newbie to golang and want to find a way to define a single byte variable.
It's a demo program in Effective Go reference.
package main
import (
"fmt"
)
func unhex(c byte) byte{
switch {
case '0' <= c && c <= '9':
return c - '0'
case 'a' <= c && c <= 'f':
return c - 'a' + 10
case 'A' <= c && c <= 'F':
return c - 'A' + 10
}
return 0
}
func main(){
// It works fine here, as I wrap things with array.
c := []byte{'A'}
fmt.Println(unhex(c[0]))
//c := byte{'A'} **Error** invalid type for composite literal: byte
//fmt.Println(unhex(c))
}
As you see I can wrap a byte with array, things goes fine, but How can I define a single byte without using array? thanks.
In your example, this would work, using the conversion syntax T(x):
c := byte('A')
Conversions are expressions of the form T(x) where T is a type and x is an expression that can be converted to type T.
See this playground example.
cb := byte('A')
fmt.Println(unhex(cb))
Output:
10
If you don't want to use the := syntax, you can still use a var statement, which lets you explicitly specify the type. e.g:
var c byte = 'A'

Objective c - Letter & Points Model

I'm developing a word game and basically I want to assign an integer value to each character of the alphabet.
Currently, I have a helper to return the value for each char but I'm wondering how I should construct the initial data structure.
At the moment it is a dictionary containing each of the letters of the alphabet as the key and I want the points to be the object for that key. What is the best practise to set the points object?
I want to avoid things like this:
if (_letter == 'a' || _letter == 'A') _points = 1;
else if (_letter == 'b' || _letter == 'B') _points = 4;
else if (_letter == 'c' || _letter == 'C') _points = 3;
Many Thanks
You could use a 26-element C array of integers, where each integer is the point value of that letter, with the 0th element being A, the 1st element being B, etc. You then just lowercase the letter before subtracting 'a' from it and use that as the index into the array. At this point, the only thing left is to prevent non-ASCII-alphabetic characters from being considered, which can be done with a simple range check after lowercasing (if (c >= 'a' && c <= 'z')).
You can take advantage of the fact that chars are integers in C (and therefore Objective-C as well), and simply have an array of ints, keyed off the lowercase version of the char - 'a', like so:
int *letterValues[] = {1,4,3}; // a = 1, b=4, etc...
char thisChar = 'B';
int thisCharVal = letterValues[tolower(thisChar) - 'a'];
Note that this uses tolower, which is declared in (std library), and that subtracting 'a' from a lowercase alpha char is essentially deducing it's "index" in the alphabet: 'a' - 'a' = 0, the "first" item, 'b'-'a' = 1, etc. Therefore, your array initializer ({1,4,3}), is simply the values you want to assign to the chars in order (or use designated initializers if you wish, and you can use chars there as well:
int *letterValues[] = {1,4,3, 'z'=4};
If it's just teh standard latin alphabet, with no umlauts or other special characters, the easiest way is to just make an array of 26 ints for the "point" values:
int LookupPoints(char c)
{
static const unsigned char Points[26]={1,4,3, ... };
c=c|0x20; /* all lower case */
assert(c>='a' && c<='z');
return Points[c-'a'];
}
If you want to include other characters you could check for them specifically, or make an alphabetically sorted array of structs (with the character and the value) to search with bsearch.
EDIT: of course, a dictionary will work too. Just use whatever feels like the easiest solution for your specific case.