Invalid operands 'Dictionary' and 'Array' in operator '+'.Godot3.5 - godot

I am using v3.5.stable.official [991bb6ac7] Godot Engine I was also using version 3.4, that is also the reason I have decided to update, since I can't get passed by that error.
Invalid operands 'Dictionary' and 'Array' in operator '+'
extends Area2D
onready var timer = $Timer
onready var plant = $Sprite
var stage = 0
var PlantNum
func _ready():
PlantNum = Game.Plot.size()
Game.Plot += [{
"Seed": "Corn",
"TimeLeft": timer.time_left,
"Stage": stage,
}]
Utils.save_game()
timer.start()
plant.frame = 1
This piece of code is for my game project that I am trying to make. The code serves for the save and load, so that the plants stage will stay the same as when I join again.
The global script which is connected to the upper one.
extends Node
var Plot = [
{
"Seed":"",
"TimeLeft":0,
"Stage":0,
},
]
Expected output
[{Seed:, Stage:0, TimeLeft:0}, {Seed:Corn ,Stage:0, TimeLeft:0}]
Any help would be much appreciated.

I don't know why you are getting that particular error. My first guess is that somewhere along the line the type was lost… Either somewhere you set a Dictionary to Plot (after all, it is Variant), or we are looking at a bug in Godot.
Either way, you can declare Plot as an Array (so it is not Variant). Either implicitly:
var Plot := [
{
"Seed":"",
"TimeLeft":0,
"Stage":0,
},
]
Or explicitly
var Plot:Array = [
{
"Seed":"",
"TimeLeft":0,
"Stage":0,
},
]
On the other hand, using using append_array is better than += (it does not allocate a new Array), so I would prefer that:
Game.Plot.apppend_array([{
"Seed": "Corn",
"TimeLeft": timer.time_left,
"Stage": stage,
}])
Furthermore, you are just adding one element, thus you can use append:
Game.Plot.apppend({
"Seed": "Corn",
"TimeLeft": timer.time_left,
"Stage": stage,
})

Thanks for the post.
I have done this
func _ready():
PlantNum = Game.Plot.size()
Game.Plot.append({
"Seed": "Corn",
"TimeLeft": timer.time_left,
"Stage": stage,
})
And this,
var Plot := [
{
"Seed":"",
"TimeLeft":0,
"Stage":0,
}]
I got a new error by doing so,
Parser Error: The assigned value's type (Dictionary) doesn't match the variable's type (Array).
func _ready():
var date = OS.get_datetime()
Game.Plot = OS.get_datetime() # Error is in this line.
self.text = "Time: " + str(date["hour"]) + " : " + str(date["minute"])

Related

Remove trailing spaces in string in google apps script

I am grouping by "Id" and get the sum of "Total_Weight" in google apps script. This is the result of that computation.
res_1 output:
[ { Id: '400 ', Total_Weight: 484308 },
{ Id: '500W', Total_Weight: 13232 } ]
After this, I have a if-else clause that loops over the "Id" in above array and does some computation.
res_1.forEach((r2,i2)=>{
if (r2['Id']=="400") {
var cost = (r2['Total_Weight']/1000)*cost
NewArray.push([r2['Id'], cost]);
}
else if (r2['Id']=="400W") {
var cost = (r2['Total_Weight']/1000)*cost
NewArray.push([r2['Id'], cost ]);
}
}
My challenge is in "res_1" the first Id is "400 " (400 followed by a space). Hence, when it comes to the for loop, it does not go into the first if clause. I tried with replacing spaces but that doesnt work as well.
Are there any ways that this could be resolved? Any leads would be great.
Try using the .replace call on the res_1 output like so:
var res_1_trim = res_1.replace(/\s/g, "")
res_1_trim.forEach((r2,i2)=>{
if (r2['Id']=="400") {
var cost = (r2['Total_Weight']/1000)*cost
NewArray.push([r2['Id'], cost]);
}
else if (r2['Id']=="400W") {
var cost = (r2['Total_Weight']/1000)*cost
NewArray.push([r2['Id'], cost ]);
}
}
\s is a solution to find whitespace and the 'g' provides a match for instances of whitespace.(.replace documentation)

GDScript modularization

Is it possible to modularize in GDScript?
What I have in mind is that I have a player class with variable input, of type IInput, like this:
Player.gd:
extends KinematicBody
var input = load("res://Scripts/Inputs/PlayerInput.gd").new()
func _physics_process(delta):
if input.is_down("left_trigger"): speed = sprintSpeed
else: speed = runSpeed
Where "res://Scripts/Inputs/PlayerInput.gd" would look like this
extends "res://Scripts/Inputs/IInput.gd"
class_name PlayerInput
var controlTranslatinos = {"left_stick_up" : "move_up",
"left_stick_down" : "move_down",
"left_stick_left" : "move_left",
"left_stick_right" : "move_right",
"right_stick_up" : "rotate_up",
"right_stick_down" : "rotate_down",
"right_stick_left" : "rotate_left",
"right_stick_right" : "rotate_right",
"x" : "attack",
"left_trigger" : "defend",
"a" : "jump",
"right_trigger" : "sprint"}
func pressure(controlName):
var translatedControl = controlTranslatinos[controlName]
var preasure = Input.get_action_strength(translatedControl)
return preasure
func is_down(controlName):
return Input.is_action_pressed(controlTranslatinos[controlName])
and where "res://Scripts/Inputs/IInput.gd" would look like this:
extends Node
class_name IInput
const controls = [ "move_up", "move_down", "move_left", "move_right",
"rotate_up", "rotate_down", "rotate_left", "rotate_right",
"attack", "defend", "jump", "sprint" ]
func pressure(controlName):
return 0
func is_down(controlName):
return false
Goal is to change actor's input to AIInput class and back to PlayerInput on demand. This would also be good for other stuff.
Is it possible to implement this in some other way?
Error at `PlayerInput.gd`
There's an error at first line of PlayerInput, saying:
`Script not fully loaded (cyclic preload?): "res://Scripts/Inputs/IInput.gd"
I get what cyclic preload would mean, but I don't get how cyclic loading is happening at this instance. Can you explain how/why this is happening? How can I overcome it?
If this error wouldn't show up I think the modularization would work (the way I imagine it works).

Adding data to JSON object with data from variables

So my goal is to have an object variable that will be empty at the start but as the code starts running it would get filled up with data from other varibales. When it gets filled up it should look like this:
var fruits = [banana, apple, ...];
var colors = [yellow, green, ...];
var calories = [300, 250, ...]
//the JSON object
{
banana :
{
"color" : "yellow",
"calories" : 300
},
apple :
{
"color" : "green",
"calories" : 250
},
...
}
As you can see all of the data is supposed to be pulled from other variables and this is where I bump into problems. I've tried the following:
var object.fruits[0] = {colors : calories};
//also tried this
var object.fruits[0] = "{""'" + (colors[0]) + "'":+calories[0]+"}";
//and tried many other things...
I've been failing to counter this for at least an hour now and what makes it worse is that some data is supposed to come from other JSON objects. Any idea how to make it work? Also note that having them in an object array is not a option as the list will be HUGE and therefore the time efficiency will be very poor.
Maybe try something like this
res = {}
fruits.map((key, index) => {
res[key] = {
'color': colors[index],
'calories': calories[index]
}
})
You can do like this but yeah put validations to make sure all three arrays are of equal length.
Whenever you want to add a property to an Object where the property value is a value of another variable it is better to use the bracket notation to add the properties to the object [] as used below.
One more thing better use let and const in place of var.
Finally you can use JSON.stringify() to convert into JSON String from the Javascript Object.
'use strict';
const fruits = ['banana', 'apple'];
const colors = ['yellow', 'green'];
const calories = [300, 250];
const fruits_object = {};
for (let i = 0; i < fruits.length; i++) {
fruits_object[fruits[i]] = {};
fruits_object[fruits[i]]['color'] = colors[i];
fruits_object[fruits[i]]['calories'] = calories[i];
}
console.log(JSON.stringify(fruits_object));
Just do it normally like so:
color: colors[0]
and then call JSON.stringify on the entire object like so
JSON.stringify({color: colors[0]})

Need to get the values of the objects (JSON) which have been created dynamically

How to get the top object value in PentahoDI? I have got the other elements like Category, Subcategory, section from the following example of Json file. However, I need to capture the first root object which is x#chapter#e50de0196d77495d9b50fc05567b4a4b and x#e50de0196d77495d9b50fc05567b4a4b
{
"x#chapter#e50de0196d77495d9b50fc05567b4a4b": {
"Category": "chapter",
"SubCategory": [
"x#4eb9072cf36f4d6fa1e98717e6bb54f7",
"x#d85849fbde324690b6067f3b18c4258d",
"x#3edff1a1864f41fe8b212df2bc96bf13"
],
"Section": {
"display_name": "Week 1 Section"
}
},
"x#e50de0196d77495d9b50fc05567b4a4b": {
"category": "course",
"Subcategory": [
"x#e50de0196d77495d9b50fc05567b4a4b"
],
"Section": {
"advanced_modules": [
"google-document"
],
}
}
}
In the Fields tab of the Json Input step I have given the Names and Paths as: Category --> $..Category, Subcategory --> $..Subcategory, Section --> $..Section.
However, I am unable to get the root element as it is crucial information for us to work on it. ex (x#chapter#e50de0196d77495d9b50fc05567b4a4b and x#e50de0196d77495d9b50fc05567b4a4b)
I have used the following code to get the values of the dynamic objects but it didnt work. The following is the code I used it.
var obj = JSON.parse (JBlock) //Jblock is the one which holds the entire string.
var keys = Object.name( obj);
JSONPath is not able to get the keys of a JSON structure. This is one of my main issues with JSONPath, and I wish Pentaho had included other JSON parsing engines.
This JavaScript to be used in Modified Java Script Value works for me. Add a value in the fields editor like this:
And then a script like this:
var obj = JSON.parse(JBlock);
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
    var row = createRowCopy(getOutputRowMeta().size());
    var idx = getInputRowMeta().size();
row[idx++] = keys[i];
putRow(row);
}
trans_Status = SKIP_TRANSFORMATION;

Elastic Search: How to write multi statement scripts?

I have values stored on a document in an Elasticsearch index.
I need to do some date manipulation on the values and return a boolean value to be used in a filter.
The script covers several lines, and I can't get it to run.
I've written other single scripts that work fine, however I know less than nothing about Groovy and very little about Elastic search.
Each and every sample I can find with a script has one line and only one line.
So basically how would I take this perfectly valid script
"script": {
"script": "doc['state'].value == 'completed' && doc['lastStateUpdate'].value < doc['dueDate'].value"
}
And turn it into some thing like
"script": {
"script": "def isCompleted = doc['state'].value == 'completed'
def preSLA = doc['lastStateUpdate'].value < doc['dueDate'].value
return isCompleted && preSLA"
}
I'm not mad about the idea of creating a write-only one liner that expresses the logic, I can see more of these coming down the line and while this one is relatively straight-forward, a "one liner" isn't going to cut it.
The alternative here is to do some preprocessing on the document before it's indexed, and add extra data to it. However this has drawbacks in that it's rather inflexible and we'd need to reindex all the data to change these aggregations, which we'd rather not do.
You simply need to separate each statement with a semicolon:
"script": {
"script": "isCompleted = doc['state'].value == 'completed'; preSLA = doc['lastStateUpdate'].value < doc['dueDate'].value; return isCompleted && preSLA;"
}
Make sure to not add line breaks inside your script string, though, as it would not be valid JSON.
If you want to break your script into multiple lines you have to surrond your script with """ docs
`"query": {
"function_score": {
"script_score": {
"script": {
"lang": "painless",
"source": """
int total = 0;
for (int i = 0; i < doc['goals'].length; ++i) {
total += doc['goals'][i];
}
return total;
"""
}
}
}
}
}`
Update: For some versions of Elasticsearch source should be replaced with inline docs

Resources