Say I have 3 conditions, and I want to perform some action if 2 of these conditions are fulfilled. With a few number of combinations, like 3, the solution could be something like:
c1=...
c2=...
c3=...
if (c1==true and c2==true) then
elseif (c1==true and c3==true) then
elseif (c2==true and c3==true) then
This is not very practical with, say, 100 conditions of which 90 should be fulfilled.
Is there a more compact way to implement this in PineScript?
If you represent the boolean true/false of your condition as 1/0 ints, you could count them to see how many are true.
The shortest way I can think of, is putting them in an array, and calculate the sum of that array.
//#version=5
indicator("My Script")
var int c0 = 1
var int c1 = 0
var int c2 = 1
var int c3 = 1
var int c4 = 1
var int c5 = 0
var int c6 = 0
var int c7 = 1
var int c8 = 1
var int c9 = 1
var int[] a = array.from(c0,c1,c2,c3,c4,c5,c6,c7,c8,c9)
mySum = array.sum(a)
plot(mySum)
Related
For every group I'd like to find the max observation for VarB and subtract the first value in each group of Var A. Max(VarB for group1) - FirstObs(VarA group1). Hopefully this makes sense. Below is the desired results in table form and my attempt at the code
VarA VarB Group Result Index
10 11 1 (10-11=-1) 1
11 4 1 (10-11=-1) 2
...
12 7 1 (10-11=-1) 5
9 11 2 (9-11=-2) 6
13 4 2 (9-11=-2) 7
...
11 7 2 (9-11=-2) 11
Maxdiff =
VAR CurrGroup = Table1[Group]
VAR MaxVal = CALCULATE(MAX(Table1[VarB]), ALL(Table1), Table1[Group] = CurrGroup)
VAR MinIndex = CALCULATE(MIN(Table1[Index]), ALL(Table1), Table1[Group] = CurrGroup)
RETURN LOOKUPVALUE(Table1[VarB], Table1[Group], MaxVal) -
LOOKUPVALUE(Table1[VarA], Table1[Index], MinIndex)
I get the error "a table of multiple values was supplied where a single value was expected"
The problem is that you are trying to look up the VarB value for a Group that matches your MaxVal. This doesn't make sense since you probably don't want to match a Group number to a VarB value. It returns multiple values since each group has multiple VarB values associated with it.
I think the following is what you are after:
MaxDiff =
VAR CurrGroup = Table1[Group]
VAR MaxVal = CALCULATE(MAX(Table1[VarB]), ALL(Table1), Table1[Group] = CurrGroup)
VAR MinIndex = CALCULATE(MIN(Table1[Index]), ALL(Table1), Table1[Group] = CurrGroup)
RETURN MaxVal - LOOKUPVALUE(Table1[VarA], Table1[Index], MinIndex)
This returns 1 and 2 for [Group] = 1 and 2.
(Your subtraction looks backward in your question.)
I would like to use something like (code below), but I think that there must be a nicer solution with usage lastOrNull() instead of using isEmpty and last()
data class Entry(val x: Float, val y: Float)
var entries: MutableList<Entry> = ArrayList()
if(some) {
entries.add(Entry(100f, 200f)
}
val foo = (if (entries.isEmpty()) 0f else entries.last().y) + 100f
Is there some better way like entries.lastOrNull()?.y if null 0f?
you can using Kotlin elvis operator ?:, for example:
// if the expression `entries.lastOrNull()?.y` is null then return `0f`
// v
val lastY = entries.lastOrNull()?.y ?: 0f
for the expression in your code above, you can using safe-call ?.let/?.run to make your code more clearly, for example:
//val foo = if (entries.isEmpty()) 0f else entries.last().y + 100f else 100f
// if no Entry in List return `0F` ---v
val foo = entries.lastOrNull()?.run { y + 100 } ?: 0F
// ^--- otherwise make the last.y + 100
If I've managed to understand you correctly, this will do the job:
val foo = if (entries.isEmpty()) 0f else entries.lastOrNull()?.y ?: 0f + 100f
I'm trying to calculate the checksum in an NMEA sentence, but i can't get the correct value. Here is my test code.
import UIKit
//$GPGLL,5300.97914,N,00259.98174,E,125926,A*28
let str = "GPGLL,5300.97914,N,00259.98174,E,125926,A"
var xor: UInt8 = 0
for i in 0..<str.characters.count {
xor = xor ^ Array(str.utf8)[i]
}
print(xor)
This returns a checksum of 40, not the 28 i'd expected.
What am i doing wrong?
The checksum is simple, just an XOR of all the bytes between the $ and
the * (not including the delimiters themselves), and written in
hexadecimal.
let str = "$GPGLL,5300.97914,N,00259.98174,E,125926,A*"
var xor: UInt8 = 0
for i in 1..<(str.characters.count - 1){
xor = xor ^ Array(str.utf8)[i]
}
extension UnsignedInteger {
var hex: String {
var str = String(self, radix: 16, uppercase: true)
while str.characters.count < 2 * MemoryLayout<Self>.size {
str.insert("0", at: str.startIndex)
}
return str
}
}
let strWithCheckSum = str + xor.hex
print(strWithCheckSum) // GPGLL,5300.97914,N,00259.98174,E,125926,A*28
Is this a RegEx problem?
To note: there will always be only four items, each starts with a capital letter, each will be in order (color,color,shape,color):
"BlackWhiteTriangleGreen" etc.
So,
a="BlackWhiteTriangleGreen"
yields:
c1 = "Black"
c2 = "White"
S = "Triangle"
c3 = "Green"
EDIT: referencing the post suggested by Alex K., an AS3 solution as follows works:
private function UpperCaseArray(input:String):void {
var result:String = input.replace(/([A-Z]+)/g, ",$1").replace(/^,/, "");
var b:Array=result.split(",");
c1 = b[0];
c2 = b[1];
S = b[2];
c3 = b[3];
}
referencing the post suggested by Alex K., an AS3 solution as follows works:
private function UpperCaseArray(input:String):void {
var result:String = input.replace(/([A-Z]+)/g, ",$1").replace(/^,/, "");
var b:Array=result.split(",");
c1 = b[0];
c2 = b[1];
S = b[2];
c3 = b[3];
}
For example I have: 1|2|3,4|5|6,7|8|10;
How can I output it like this:
A: 1 2 3
B: 4 5 6
C: 7 8 10
And how can I do this:
Array A = {1,2,3}
Array B = {4,5,6}
Array C = {7,8,10}
var reg = /(\d+)\|(\d+)\|(\d+)[,;]/g;
var str = "1|2|3,4|5|6,7|8|10;";
var index = 0;
str.replace(reg,function myfun(g,g1,g2,g3){
var ch = String.fromCharCode(65 + (index++));
return ch+": "+g1+" "+g2+" "+g3+"\n";
});
the second case should update myfun return string:
"Array "+ch+" = {"+g1+","+g2+","+g3+"}\n";