How to check if a TypedPipe or a ValuePipe are empty in Scalding? - scalding

In Scalding, suppose you have a TypedPipe[Long] or ValuePipe[Long]. How would you go about checking whether they are empty in the most elegant/efficient way?
Currently testing the following:
val isTPEmpty: Boolean = typePipe.equals(TypedPipe.empty)
val isVPEmpty: Boolean = valuePipe.equals(EmptyValue)
Or, to make it more generic:
def isTypedPipeEmpty[A](typedPipe: TypedPipe[A]): Boolean = {
val emptyTP: TypedPipe[A] = TypedPipe.empty
typedPipe.equals(emptyTP)
}
UPDATE: this doesn't work (will return false for an empty TypedPipe). Appreciate any inputs.

After speaking to several people on this, there is no straight solution simply because a TypedPipe is distributed, and checking whether it is empty is "expensive", therefore one should avoid this as much as possible.
If you absolutely have no choice, what worked for me was something "ugly" as creating a temporary empty TypedPipe, then calling mapWithValue on my ValuePipe, and if it is empty do X, otherwise do Y. Something like:
TypedPipe.from(List()).mapWithValue(valuePipe) { case (temp, valuePipe) => if (valuePipe.isEmpty) doX else doY }
But again, cumbersome.

Related

how to set multiple kotlin variables in one line

I want to fill two variables in the same line, but I don't know the best way to do it at kotlin
var a:String? = null
var b:String? = null
a, b = "Text"
Not possible in Kotlin (unless you are ready to resort to some contrived constructs with repetition as described in other answers and comments). You cannot even write
a = b = "Text"
because weirdly enough, assignments are not expressions in Kotlin (as opposed to almost everything else like if, return, throw, swicth, etc., which are expressions in Kotlin, but not in Java, for example).
So, if you want to assign exactly the same value without repetition (of the assigned value), you'll have to write
a = "Text"
b = a
Note, that there is also an also function (pun intended), so technically you can write the following if you really want to stay on one line
a = "Text".also { b = it }
but I doubt it is really worth it.
var a: String? = null; var b: String? = null
or
var (a: String?, b: String?) = null to null
But please don't ever do so
Simply create an inline array, iterate through and assign values.
arrayListOf(a, b, c, d).forEach { it = "Text" }

Why is kotlin stream evaluating an .all predicate to true where the first Iterable is empty

I have a List of objects.
importerResponse.applications is empty (size=0)
This is my code:
val isDeployed = importerResponse.applications
.flatMap(Application::instances)
.map(Instance::state)
.all { state -> DEPLOYED == state }
isDeployed is true in this case. How can this be? I want it to resolve into false if applications is empty.
Why would you want that? All the elements in the collection satisfy your predicate.
You can check the documentation:
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.sequences/all.html
If you want you can explicitly check for the collection being empty.
This should give you what you want:
val isDeployed = importerResponse.applications
.flatMap(Application::instances)
.map(Instance::state)
.count { state -> DEPLOYED == state } > 0```
The all method might be looking for any element that doesn't meet the condition, since you don't have any, it defaults to true.
You can achieve what you want by doing something similar to this:
val isDeployed = importerResponse.applications
.flatMap(Application::instances)
.map(Instance::state)
.let { it.size() > 0 && it.all { state -> DEPLOYED == state } }
Note that let allows you to reuse the same expression without recalculating it twice.
It can be a little bit confusing, why "any" returns "false" on empty collections, but "all" return true, because "all" seems to be more limiting than "any" (based on human language).
But if you ask as one example "if all persons in a room are male", than that's still true, if the room is empty. 0 out of 0 persons are ALL.

Getting the name of the variable as a string in GD Script

I have been looking for a solution everywhere on the internet but nowhere I can see a single script which lets me read the name of a variable as a string in Godot 3.1
What I want to do:
Save path names as variables.
Compare the name of the path variable as a string to the value of another string and print the path value.
Eg -
var Apple = "mypath/folder/apple.png"
var myArray = ["Apple", "Pear"]
Function that compares the Variable name as String to the String -
if (myArray[myposition] == **the required function that outputs variable name as String**(Apple) :
print (Apple) #this prints out the path.
Thanks in advance!
I think your approach here might be a little oversimplified for what you're trying to accomplish. It basically seems to work out to if (array[apple]) == apple then apple, which doesn't really solve a programmatic problem. More complexity seems required.
First, you might have a function to return all of your icon names, something like this.
func get_avatar_names():
var avatar_names = []
var folder_path = "res://my/path"
var avatar_dir = Directory.new()
avatar_dir.open(folder_path)
avatar_dir.list_dir_begin(true, true)
while true:
var avatar_file = avatar_dir.get_next()
if avatar_file == "":
break
else:
var avatar_name = avatar_file.trim_suffix(".png")
avatar_names.append(avatar_name)
return avatar_names
Then something like this back in the main function, where you have your list of names you care about at the moment, and for each name, check the list of avatar names, and if you have a match, reconstruct the path and do other work:
var some_names = ["Jim","Apple","Sally"]
var avatar_names = get_avatar_names()
for name in some_names:
if avatar_names.has(name):
var img_path = "res://my/path/" + name + ".png"
# load images, additional work, etc...
That's the approach I would take here, hope this makes sense and helps.
I think the current answer is best for the approach you desire, but the performance is pretty bad with string comparisons.
I would suggest adding an enumeration for efficient comparisons. unfortunately Godot does enums differently then this, it seems like your position is an int so we can define a dictionary like this to search for the index and print it out with the int value.
var fruits = {0:"Apple",1:"Pear"}
func myfunc():
var myposition = 0
if fruits.has(myposition):
print(fruits[myposition])
output: Apple
If your position was string based then an enum could be used with slightly less typing and different considerations.
reference: https://docs.godotengine.org/en/latest/tutorials/scripting/gdscript/gdscript_basics.html#enums
Can't you just use the str() function to convert any data type to stirng?
var = str(var)

How to properly sanitize a list of items received from server using RX | filter{} map{}

I have the following code which I am trying to use for two purposes:
1) Call an API and get result as a POJO
2) Sanitize this object (POJO) before I display it in the UI
private fun getWinbackDataItems(rewardPurpose: String) /*Single<WinbackBaseItem>*/ {
val x = repository.getRewardsList(rewardPurpose)
.filter {
it.result?.rewards != null
}.map { winback ->
winback.result?.rewards?.asSequence()?.filter { rewardsItem ->
rewardsItem?.id != null && rewardsItem.title != null
}?.toList()?.take(3)?.map {
WinbackListItem(it?.id, it?.title!!, false)
}?.toList()
}
}
The point of contention for me is the line below:
itemListSanitized.add(WinbackListItem(it.id, it.title, false))
At this point I assume the filter has removed all nulls from the original list but to my amazement I find that I have to null check on it and all its content while adding them to the new list.
What do I miss here, pardon my naivety as I have just begun reactive
I take it that you are working not against executing code but against your IDE's warning messages or just the ability for this code to compile. What you're probably running up against is that earlier checks for null won't necessarily allow the compiler to assume non-null values later on, because in the meantime, other code in a different thread could have run and changed the values.
So when you create a WinbackListItem, you can safely assume that certain items are not null, and yet the compiler can't be sure of this, because it can't know what else is going on in your process space. So the compiler requires that you tell it not to worry about null values (!!) or that you check the values again. This is just the way Kotlin works. It's often a PITA, but it's just how it is.
I played with the posted code just to be sure I knew what I was talking about. Here is code that I was able to run:
private fun getWinbackDataItems(rewardPurpose: String) /*Single<WinbackBaseItem>*/ {
val x = repository.getRewardsList(rewardPurpose)
.filter {
it.result?.rewards != null
}.map { winback ->
winback.result?.rewards?.asSequence().filter { rewardsItem ->
rewardsItem.id != null && rewardsItem.title != null
}.toList().take(3).map {
println(it.id)
println(it.title)
WinbackListItem(it.id!!, it.title!!, false)
}.toList()
}.count()
}
I created some very simple classes and objects to satisfy this code and let it run. Note that I took out some unnecessary '?' null checks. I played with input values until I was convinced that it.id and it.title can never be null when the WinbackListItem constructor is called. And yet, the two !! on its parameters, or something else making sure they are not null, are required given this definition of WinbackListItem that won't accept null parameter values:
class WinbackListItem(val id: Int, val title: String, val huh: Boolean)

Why does R.all with R.both does not equal R.allPass with the same arguments?

I'm just learning while doing ramda.js. Well, there are many ways to reach a goal with ramda, but there is on thing I do not understand.
I would like to check the input for an array of strings that all match one regular expression. I thought I could do it R.all(R.both(isString, isRegExp)), but it seems to deliver a true when the input is a number.
As expected R.allPass([isString, isRegExp]) gives a false with a number input.
But can anyone please explain me why R.all is returning a true? Or what and where is mistake (in thinking)?
Complete code:
var isString = R.is(String),
isMyRegExp = R.test(/^[a-z]+$/),
isMyRegExpString = R.both(isString, isMyRegExp),
isArrayOfMyRegExpStrings = R.all(isMyRegExpString),
isArrayOfMyRegExpStringsPass = R.allPass([isString, isMyRegExp]),
result = {
'all': isArrayOfMyRegExpStrings(9),
'allPass': isArrayOfMyRegExpStringsPass(9)
};
console.log(result);
// {
// all: true,
// allPass: false
// }
https://codepen.io/Eisenhardt/pen/PKLZqj
PS:
I know that I could shorten conditions with just the regexp, but there could be other situations where I need both conditions to be true. eg. isArrayOfNumber and sumOfNumbersOver50.
The second argument to R.all is expecting a list of values to test. Due to the way the function is implemented it is treating the 9 in your example as an empty list, resulting in a vacuous truth and evaluating to true.