How to use mapbox case expression within case expression in icon-color - mapbox-gl-js

I am trying to have a case expression within case expression in icon-color. My icon-color depends on a combination of to variables. I tryed the following syntax without any success. What is wrong? Is it possible?
"icon-color": [
"case",
["==",["get","status"],"s1"],
["case", ["==",["get","priority"],"p1"], "#111111", ["==",["get","priority"],"p2"], "#222222", "#DDDDDD"]
["==",["get","status"],"s2"],
["case", ["==",["get","priority"],"p1"], "#333333", ["==",["get","priority"],"p2"], "#444444", "#DDDDDD"]
"#777777"]

Try this:
"icon-color": [
"case",
["all",["==",["get","status"],"s1"],["==",["get","priority"],"p1"]], // is status == s1 AND priority == p1?
"#111111", // result of all on the above line being true
["all",["==",["get","status"],"s1"],["==",["get","priority"],"p2"]], // after failing the first test, is status == s1 AND priority == p2?
"#222222", // result of all on the above line being true
["all",["==",["get","status"],"s2"],["==",["get","priority"],"p1"]], // after failing the second test, is status == s2 AND priority == p1?
"#333333", // result of all on the above line being true
["all",["==",["get","status"],"s2"],["==",["get","priority"],"p2"]], // after failing the third test, is status == s2 AND priority == p2?
"#444444", // result of all on the above line being true
"#777777" // result of all tests failing
]

For starters, you need to put double quotes around your colors ("#111111") and around property names with hyphens ("icon-color").

Related

Return keyword inside the inline function in Scala

I've heard about to not use Return keyword in Scala, because it might change the flow of the program like;
// this will return only 2 because of return keyword
List(1, 2, 3).map(value => return value * 2)
Here is my case; I've recursive case class, and using DFS to do some calculation on it. So, maximum depth could be 5. Here is the model;
case class Line(
lines: Option[Seq[Line]],
balls: Option[Seq[Ball]],
op: Option[String]
)
I'm using DFS approach to search this recursive model. But at some point, if a special value exist in the data, I want to stop iterating over the data left and return the result directly instead. Here is an example;
Line(
lines = Some(Seq(
Line(None, Some(Seq(Ball(1), Ball(3))), Some("s")),
Line(None, Some(Seq(Ball(5), Ball(2))), Some("d")),
Line(None, Some(Seq(Ball(9))), None)
)),
balls = None,
None
)
In this data, I want to return as like "NOT_OKAY" if I run into the Ball(5), which means I do not need to any operation on Ball(2) and Ball(9) anymore. Otherwise, I will apply a calculation to the each Ball(x) with the given operator.
I'm using this sort of DFS method;
def calculate(line: Line) = {
// string here is the actual result that I want, Boolean just keeps if there is a data that I don't want
def dfs(line: Line): (String, Boolean) = {
line.balls.map{_.map { ball =>
val result = someCalculationOnBall(ball)
// return keyword here because i don't want to iterate values left in the balls
if (result == "NOTREQUIRED") return ("NOT_OKAY", true)
("OKAY", false)
}}.getOrElse(
line.lines.map{_.map{ subLine =>
val groupResult = dfs(subLine)
// here is I'm using return because I want to return the result directly instead of iterating the values left in the lines
if (groupResult._2) return ("NOT_OKAY", true)
("OKAY", false)
}}
)
}
.... rest of the thing
}
In this case, I'm using return keyword in the inline functions, and change the behaviour of the inner map functions completely. I've just read somethings about not using return keyword in Scala, but couldn't make sure this will create a problem or not. Because in my case, I don't want to do any calculation if I run into a value that I don't want to see. Also I couldn't find the functional way to get rid of return keyword.
Is there any side effect like stack exception etc. to use return keyword here? I'm always open to the alternative ways. Thank you so much!

Swift 5 isEmoji method returns true for a number?

Like in example below isEmoji method returns true for a number :
let scalars: [Unicode.Scalar] = ["🤓", "+", "1"]
for s in scalars {
print(s, "-->", s.properties.isEmoji)
}
// 🤓 --> true
// + --> false
// 1 --> true... wait what? 😦
But why and how to determine for the last case in my example.
I make a little search after facing this issue and found the answer in Apple's documentation. I am sharing with you so that you do not waste your valuable time in the future:
The final result is true because the ASCII digits have non-default
emoji presentations; some platforms render these with an alternate
appearance.
Because of this behavior, testing isEmoji alone on a
single scalar is insufficient to determine if a unit of text is
rendered as an emoji; a correct test requires inspecting multiple
scalars in a Character. In addition to checking whether the base
scalar has isEmoji == true, you must also check its default
presentation (see isEmojiPresentation) and determine whether it is
followed by a variation selector that would modify the presentation.
This property corresponds to the “Emoji” property in the Unicode
Standard.
SOLUTION
So you can check like the line below:
let scalars: [Unicode.Scalar] = ["🤓", "+", "1"]
for s in scalars {
print(s, "-->", (s.properties.isEmoji && s.properties.isEmojiPresentation))
}
// 🤓 --> true
// + --> false
// 1 --> false

How to use Optional in Netlogo Extensions

I want to create a netlogo primitive that may receive a boolean or may not. Therefore I want make possible to the user that he uses the primitive of these two ways:
1:
ask Walkers [
qlearningextension:learning
]
2:
ask Walkers [
qlearningextension:learning true
]
I tried to do that with OptionalType, but I could not make it. Is it possible to do what I want? If so, how can I do it?
So OptionalType unfortunately only works with CommandBlockType. For a good example of how that works, check out the sample-scala extension (maybe that's where you saw a reference to it in the first pace). OptionalType will not work with BooleanType.
There is a secondary option, that's a little hacky. You can use RepeatableType along with setting defaultOption and minimumOption in your syntax (so NetLogo knows that 0 arguments is okay/expected). Scala code example:
object RepeatableTypeTest extends api.Command {
override def getSyntax =
commandSyntax(
right = List(BooleanType | RepeatableType),
defaultOption = Some(0),
minimumOption = Some(0)
)
def perform(args: Array[api.Argument], context: api.Context) {
println(args.length)
if (args.length > 0) {
val ref = args(0).getBoolean
println(ref)
} else {
println("No argument given!")
}
}
}
Then you just have to wrap calls with the boolean argument in parenthesis, so NetLogo knows you're not starting a new command (it expects the defaultOption without the parens):
to test
sample-scala:rep-bool
(sample-scala:rep-bool true)
(sample-scala:rep-bool false)
(sample-scala:rep-bool false true false true false)
end
The problem with this, as you can see in the example, is if your users want to they can provide extra useless booleans: (sample-scala:rep-bool false true false false true false false). If your code ignores them they won't have an effect, but they could be confusing or weird to extension users.

Fastlane set options auto value

I would like to submit my lane with optional options. So for example the lane:
lane :mylane do |options|
mailgun(
to: "#{options[:mailto]}"
....
)
end
How do I give :mailto a default value? So if I would run fastlane mylane it would automatically set :mailto to mail#example.com.
But if I would runfastlane mylane mailto:"secondmail#example.com" it would use that value
As Lyndsey Ferguson pointed out in a comment on this answer, the following is simplest:
mail_addr = options.fetch(:mailto, 'mail#example.com')
where the first parameter of fetch is the option to fetch, and the second is the default value if the option was not passed in.
I just want to add that this works a lot better than the other suggestion:
options[:mailto] || 'mail#example.com'
when dealing with boolean options.
Fastlane (or maybe Ruby) interprets true, false, yes, and no as boolean values instead of strings (maybe others too, though I tried N, n, NO, and FALSE and they were treated as strings), so if in your lane implementation you had:
options[:my_option] || true
or
(options[:my_option] || 'true') == 'true'
you would get unexpected behaviour.
If you didn't pass in myOption at all, this would default to true as you would expect. If you passed in true this would also return true. But if you passed in false this would turn into true, which you of course wouldn't want.
Using options.fetch(:myOption, true) works great with boolean flags like the ones mentioned above and therefore seems better to use in general.
Here's a very thorough example in case you want to test it yourself:
lane :my_lane do |options|
puts("You passed in #{options[:my_option]}")
my_option = options[:my_option] || true
if my_option
puts('Using options[:my_option], the result is true')
else
puts('Using options[:my_option] the result is false')
end
my_option_fetched = options.fetch(:my_option, true)
if my_option_fetched
puts('Using fetched, the result is true')
else
puts('Using fetched, the result is false')
end
end
Outputs:
fastlane my_lane my_option:true
You passed in true
Using options[:my_option], the result is true
Using fetched, the result is true
fastlane my_lane my_option:false
You passed in false
Using options[:my_option], the result is true
Using fetched, the result is false
fastlane my_lane my_option:no
You passed in false
Using options[:my_option], the result is true
Using fetched, the result is false
Note, e.g. FALSE would default to true as it is not being interpreted as a boolean, which seems reasonable to me.
(Fastlane 1.77.0, Ruby 2.7.2)
EDIT: It's worth noting that if you pass an empty string instead of nothing/null you would not get the default value from the fetch method.
I'm not sure there's a way to make Fastlane pass a default. The processing is pretty simple:
https://github.com/fastlane/fastlane/blob/master/fastlane/lib/fastlane/command_line_handler.rb#L10
But you can easily do this in your Fastfile:
lane :mylane do |options|
mail_addr = options[:mailto] || "mail#example.com"
mailgun(
to: "#{mail_addr}"
....
)
end

why pyang does not throw error in this scenario

the following when condition is referring to a non existing node. I wonder why pyang does not throw error ? It does, if I use a wrong prefix though.
can you review the when conditions (embedded in the module) please.
is it allowed (in when expression) to refer to schema out of the augment itself ?
module mod-w-1 {
namespace "http://example.org/tests/mod-w-1";
prefix m1;
container m1 {
leaf b1 {
type string;
}
}
}
module when-tests {
namespace "http://example.org/tests/when-tests";
prefix wt;
import mod-w-1 {
prefix m1;
}
augment "/m1:m1" {
// when "/m1:m1/b3 = 'abc'";
// there is no b3, so, should be invalid.
// when "/m1:m1/b1 = 'abc'";
// a payload or data situation that has m1/b1 != 'abc' will cause the
// data that fits this augment content will be invalid/rejected.
/* for ex;
<m1>
<b1>fff</b1>
<x>sfsf</x>
<conditional>
<foo>dddd</foo>
</conditional>
</m1>
is invalid, hence, the <x> and <conditional> parts will be
rejected.
*/
leaf x {
type string;
}
container conditional {
leaf foo {
type string;
}
}
}
}
That is because pyang does not validate semantics of XPath expressions at all, only their syntax - and a couple of additional checks, such as function and prefix usage. You will need another YANG compiler to validate those properly.
def v_xpath(ctx, stmt):
try:
toks = xpath.tokens(stmt.arg)
for (tokname, s) in toks:
if tokname == 'name' or tokname == 'prefix-match':
i = s.find(':')
if i != -1:
prefix = s[:i]
prefix_to_module(stmt.i_module, prefix, stmt.pos,
ctx.errors)
elif tokname == 'literal':
# kind of hack to detect qnames, and mark the prefixes
# as being used in order to avoid warnings.
if s[0] == s[-1] and s[0] in ("'", '"'):
s = s[1:-1]
i = s.find(':')
# make sure there is just one : present
if i != -1 and s[i+1:].find(':') == -1:
prefix = s[:i]
# we don't want to report an error; just mark the
# prefix as being used.
my_errors = []
prefix_to_module(stmt.i_module, prefix, stmt.pos,
my_errors)
for (pos, code, arg) in my_errors:
if code == 'PREFIX_NOT_DEFINED':
err_add(ctx.errors, pos,
'WPREFIX_NOT_DEFINED', arg)
elif ctx.lax_xpath_checks == True:
pass
elif tokname == 'variable':
err_add(ctx.errors, stmt.pos, 'XPATH_VARIABLE', s)
elif tokname == 'function':
if not (s in xpath.core_functions or
s in yang_xpath_functions or
(stmt.i_module.i_version != '1' and
s in yang_1_1_xpath_functions) or
s in extra_xpath_functions):
err_add(ctx.errors, stmt.pos, 'XPATH_FUNCTION', s)
except SyntaxError as e:
err_add(ctx.errors, stmt.pos, 'XPATH_SYNTAX_ERROR', e)
Line 1993 of statements.py.
Note that an XPath expression referring to a non-existent node is technically not invalid, not from XPath specification perspective. It just means that an empty node set will be selected by the location path (and that your condition will be false forever).
Yes, you can refer to nodes that are "above" the augment's target node or are its siblings - in fact, you always should when when statement is in play (it should not refer to any node made conditional by it).
Also, you should never attempt to break "module confinement" with a non-prefixed node test (such as b3 and b1). The XPath expression is only able to see names that are defined in imports of the defining module and the defining module itself. For example, even if b3 is later augmented by some unknown third module, your condition would still evaluate to false. It is best to assume that non-prefixed names belong to the defining module's namespace.