monaco registerSignatureHelpProvider() causes error: Cannot read property 'signatures' of undefined - undefined

I'm using Monaco 0.22.2 trying to bring up suggestions for function parameters. I've defined a simple example like so:
monaco.languages.registerSignatureHelpProvider('myCustomLang', {
signatureHelpTriggerCharacters: ['(', ','],
provideSignatureHelp: (model, position, token) => {
return {
activeParameter: 0,
activeSignautre: 0,
signatures: [{
label:'string of_string(string $string, int $start)',
parameters: [
{
label: 'string $string',
documentation: 'The input string'
},
{
label: 'int $start',
documentation: "if $start is non-negative...",
}
]
}]
};
}
});
However as soon as I type in "(" or "," to trigger this code, I get the error:
Cannot read property 'signatures' of undefined
TypeError: Cannot read property 'signatures' of undefined
at ParameterHintsModel.eval (parameterHintsModel.js:166)
at Generator.next (<anonymous>)
at fulfilled (parameterHintsModel.js:19)
at eval (errors.js:24)
What am I doing wrong? My regular simple suggestions show up, but I can't get potential function parameter suggestions to show up.

The response should be structured this way:
monaco.languages.registerSignatureHelpProvider("myCustomLang", {
signatureHelpTriggerCharacters: ["(", ","],
provideSignatureHelp: (model, position, token) => {
return {
dispose: () => {},
value: {
activeParameter: 0,
activeSignature: 0,
signatures: [
{
label:
"string substr(string $string, int $start [, int $length])",
parameters: [
{
label: "string $string",
documentation:
"The input string. Must be one character or longer.",
},
{
label: "int $start",
documentation:
"If $start is non-negative, the returned string will start at the $start'th position in string, counting from zero. For instance, in the string 'abcdef', the character at position 0 is 'a', the character at position 2 is 'c', and so forth.\r\nIf $start is negative, the returned string will start at the $start'th character from the end of string. If $string is less than $start characters long, FALSE will be returned.",
},
{
label: "int $length",
documentation:
"If $length is given and is positive, the string returned will contain at most $length characters beginning from $start (depending on the length of $string) If $length is given and is negative, then that many characters will be omitted from the end of $string (after the start position has been calculated when a start is negative). If $start denotes the position of this truncation or beyond, FALSE will be returned. If $length is given and is 0, FALSE or NULL, an empty string will be returned. If $length is omitted, the substring starting from $start until the end of the string will be returned.",
},
],
},
],
},
};
},
});
The response type is SignatureHelpResult, it should have a value and dispose method. The value should be SignatureHelp with activeParameter activeSignature and signatures

Related

Why can't a select values not in double quotes from a json file in python programming

import json
f = open(r'C:\Users\Arun\Documents\Input.json',)
data = json.load(f)
json.dumps(data, separators=(",", ":"))
for i in data["notificationChannels"]:
if i["enabled"] == "true":
print(i)
But I can get the values if I use if i["type"] == "BEAN": , Why can't I pull values which are not in double quotes
Sample Json File Content:
{
"notificationChannels": [
{
"type": "BEAN",
"enabled": true,
I believe that the "json" library was build to read the value of true (without double quotes) as boolean True, so that the comparison to string "true" is wrong in the first place.
My suggestion to try:
...
if i["enabled"] == True:
...

perl: Finding mean and variance of large numbers without overflow

I am using a subroutine (stats) to calculate statistics for a list of numbers.
These numbers may be big enough to lose precision if stored as normal perl numbers.
I recieve such numbers as JSON formatted strings.
To decode these strings without losing precision,
I use a JSON::PP object with allow_nonref and allow_bignum activated.
I send the list of such decoded numbers to stats subroutine
(see in code shown below).
This routine calculates some statistics.
These statistics are then encoded to JSON and saved to file.
Most of the time the process seems to work correctly, but
for some inputs (see code for examples) the calculated value of mean and variance statistics
are either clearly wrong, or are encoded as JSON strings by the encoder, or both.
I suspect this is due to interaction of Math::BigInt and Math::BigFloat objects created by JSON decode, and List::Util::sum0.
I am trying to figure out what causes this and a way to avoid/fix this,
preferably without resorting to big non core modules.
I am willing to accept imprecise calculation of mean and variance,
but not entirely inaccurate results
or numerical results encoded as string in JSON.
A script (stats.pl) to demonstrate the problem:
use strict;
use warnings;
use Data::Dumper;
$Data::Dumper::Varname = "DUMPED_RAWDATA";
use JSON::PP;
use List::Util;
my $JSON = JSON::PP->new->allow_bignum->utf8->pretty->canonical;
sub stats {
#TODO fix bug about negative variance. AVOID OVERFLOW
#TODO use GMP, XS?
# #_ has decoded numbers (called RAWDATA here)
my $n = scalar #_;
my $sum = List::Util::sum0(#_);
my $mean = $sum / $n;
my $var = List::Util::sum0( map { $_**2 } #_ ) / $n - $mean**2;
my $s = {
n => $n,
sum => $sum,
max => List::Util::max(#_),
min => List::Util::min(#_),
mean => $mean,
variance => $var
};
# DUMP STATE IF SOME ERROR OCCURS
print Dumper( \#_ ),
$JSON->encode( { json_encoded_stats => $s, json_encoded_rawdata => \#_ } )
if ( '"' eq substr( $JSON->encode($var), 0, 1 ) #MEAN ENCODED AS STRING
or '"' eq substr( $JSON->encode($mean), 0, 1 ) #VARIANCE ENCODED AS STRING
or $var < 0 ); #VARIANCE IS NEGATIVE!
$s;
}
my #test = (
[
qw( 919300112739897344 919305709216464896 919305709216464896 985592115567603712 959299136196456448)
],
[qw(479655558 429035600 3281034608 3281034608 2606592908 3490045576)],
[ qw(914426431563644928) x 3142 ]
);
for (#test) {
print "---\n";
stats( map { $JSON->decode($_) } #$_ );
}
Below is the curtailed output of perl stats.pl with problems indicated as <---.
---
$DUMPED_RAWDATA1 = [
'919300112739897344',
'919305709216464896',
'919305709216464896',
'985592115567603712',
'959299136196456448'
];
{
"json_encoded_rawdata" : [
919300112739897344,
919305709216464896,
919305709216464896,
985592115567603712,
959299136196456448
],
"json_encoded_stats" : {
"max" : 985592115567603712,
"mean" : "9.40560556587377e+17", <--- ENCODED AS STRING
"min" : 919300112739897344,
"n" : 5,
"sum" : 4702802782936887296,
"variance" : 7.46903843214008e+32
}
}
---
$DUMPED_RAWDATA1 = [
479655558,
429035600,
3281034608,
3281034608,
2606592908,
3490045576
];
{
"json_encoded_rawdata" : [
479655558,
429035600,
3281034608,
3281034608,
2606592908,
3490045576
],
"json_encoded_stats" : {
"max" : 3490045576,
"mean" : 2261233143,
"min" : 429035600,
"n" : 6,
"sum" : 13567398858,
"variance" : "-1.36775568782523e+18" <--- NEGATIVE VARIANCE, STRING ENCODED
}
}
---
$DUMPED_RAWDATA1 = [
'914426431563644928',
.
.
.
<snip 3140 identical lines>
'914426431563644928'
];
{
"json_encoded_rawdata" : [
914426431563644928,
.
.
.
<snip 3140 identical lines>
914426431563644928
],
"json_encoded_stats" : {
"max" : 914426431563644928,
"mean" : "9.14426431563676e+17", <--- STRING ENCODED
"min" : 914426431563644928,
"n" : 3142,
"sum" : 2.87312784797307e+21,
"variance" : -9.75463826617761e+22 <--- NEGATIVE VARIANCE
}
}
None of your inputs are big enough to require JSON::PP to create Math::BigInt objects on a system with 64-bit ints, so it doesn't.
You could do something like the following at the start of your sub.
#_ = map { Math::BigInt->new($_) } #_; # Or ::BigFloat?
Alternatively,
my $zero_B = Math::BigInt->new(0);
sub stats {
my $n = #_;
my $sum_B = sum($zero_B, #_);
my $mean_B = $sum_B / $n;
my $var_B = sum( map { Math::BigInt->new($_) ** 2 } #_ ) / $n - $mean_B ** 2;
my ($min, $max) = minmax(#_);
return {
n => $n,
sum => $sum_B,
max => $max,
min => $min,
mean => $mean_B,
variance => $var_B,
};
}
All together:
use strict;
use warnings;
use Data::Dumper qw( Dumper );
use JSON::PP qw( );
use List::MoreUtils qw( minmax );
use List::Util qw( sum );
use Math::BigInt qw( );
my $zero_B = Math::BigInt->new(0);
my $JSON = JSON::PP->new->allow_bignum->utf8->pretty->canonical;
sub stats {
my $n = #_;
my $sum_B = sum($zero_B, #_);
my $mean_B = $sum_B / $n;
my $var_B = sum( map { Math::BigInt->new($_) ** 2 } #_ ) / $n - $mean_B ** 2;
my ($min, $max) = minmax(#_);
return {
n => $n,
sum => $sum_B,
max => $max,
min => $min,
mean => $mean_B,
variance => $var_B,
};
}
my #test = (
[qw( 919300112739897344 919305709216464896 919305709216464896 985592115567603712 959299136196456448 )],
[qw( 479655558 429035600 3281034608 3281034608 2606592908 3490045576 )],
[ qw( 914426431563644928 ) x 3142 ]
);
for (#test) {
print "---\n";
my $s = stats( map { $JSON->decode($_) } #$_ );
if (
$JSON->encode($s->{variance}) =~ /"/ # MEAN ENCODED AS STRING
|| $JSON->encode($s->{mean}) =~ /"/ # VARIANCE ENCODED AS STRING
|| $s->{variance} < 0 # VARIANCE IS NEGATIVE!
) {
local $Data::Dumper::Varname = "DUMPED_RAWDATA";
print Dumper($_);
print $JSON->encode({
json_encoded_rawdata => $_,
json_encoded_stats => $s,
});
} else {
print "ok\n";
}
}
Notes:
Both approaches will work even if the objects are already Math::* objects.
I identified the vars are guaranteed to contain a Math:Big* object using _B for clarity.
I moved the testing code to the test harness.
I used minmax because it's more efficient than calling min and max separately.
I imported the subs from the modules to avoid having to use use their full name.
No need to force something in scalar context into scalar context.
#ikegami's answer works correctly
but it is too slow for me as this subroutine
is called a lot of times in my program's inner loop.
I think that is the cost of ensuring that
all numbers are converted to arbitrary precision ones.
I ended up using the following implementation
which avoids converting all numbers to arbitrary
precision type.
sub stats {
my $n = scalar #_;
my $sum = List::Util::sum0(#_);
my $mean = $sum / $n;
my $var = List::Util::sum0( map { ( $_ - $mean )**2 } #_ ) / $n;
$mean += 0;
$var += 0; # TO ENSURE THAT THEY ARE ENCODED AS NUMBERS IN JSON
{
n => $n,
sum => $sum,
max => List::Util::max(#_),
min => List::Util::min(#_),
mean => $mean,
variance => $var,
};
}
I changed the method of calculating variance
to ensure that negative results are avoided
(as suggested by #Robert).
It may sacrifice precision in $sum
(and everything that depends on $sum)
due to floating point addition of large integers.
It completes the job in an acceptable execution time though.
The unintended JSON encoding of numbers as strings
is explained in https://metacpan.org/pod/JSON::PP#simple-scalars.
This problem is solved by using the method
suggested there to force encoding as numbers.
JSON::PP will encode undefined scalars as JSON null values, scalars
that have last been used in a string context before encoding as JSON
strings, and anything else as number value
You can force the type to be a JSON number by numifying it:
my $x = "3"; # some variable containing a string
$x += 0; # numify it, ensuring it will be dumped as a number
$x *= 1; # same thing, the choice is yours. in to force

How to fetch an attribute value from a variable, having the content of a JSON response

I'm using the Robot Framework API automation. Here, storing the JSON response in a variable [POSTResp.content]. I.e., "POSTResp.content" has the whole response, as given below. Please help me to get an attribute's value (for ex, value of referenceId) from the stored content.
Example of JSON response:
{
"serviceResponseHeader": {
"responseContext": {
"responseCode": "MS19",
"responseDescription": "Success",
"serviceResponseTimeInGMT": "18 Sep 2018 16:12:43 GMT"
},
"requesterContext": {
"applicationCode": null,
"applicationSubCode": null,
"countryCode": null,
"requesterReferenceNumber": null,
"requestTimeInGMT": "30 Jun 2015 11:54:49 GMT",
"requesterUserIdentity": "23483",
"requesterGroupIdentity": "1620",
"requesterIpAddress": "",
"sessionIdentity": "2536kjhfdashfkhfsab",
"ssoSessionIdentity": "2536kjhfdashfkhfsab",
"requesterAbbreviatedGroupName": "NEWCOMP"
},
"serviceContext": {
"serviceVersionNumber": "1.0",
"serviceCode": "30"
}
},
"getProxyDetailResponseBody": {
"proxyDetails": {
"proxyType": "",
"proxyValue": "20140005K",
"referenceId": "PR18090000847597",
"transactionId": "18091801657466"
}
}
}
I've tried the below ways,
1) ${json} To JSON ${POSTResp.content} true
log to console \n the Proxy ID is ${json["proxyValue"]}
Result: Resolving variable '${json["proxyValue"]}' failed: TypeError: string indices must be integers, not str
2) ${json} Evaluate json.loads(${POSTResp.content}} json
log to console \n the Proxy ID is ${json["proxyValue"]}
Result: failed: SyntaxError: unexpected EOF while parsing (, line 1)
Issues with your two approaches:
1) the library keyword call passes a true argument (well, truth-like) to the pretty_print parameter:
${json} To JSON ${POSTResp.content} true
Looking at the library's source, in that case the keyword does not return a dict object - but a string, a beatified version of the source json. That coincides with the error your received.
Remove the "true" argument and it must return a dict.
2) In the Evaluate surround the variable with triple quotes (python's literal string):
${json} Evaluate json.loads('''${POSTResp.content}'''}
json
Without it, the framework just dumped the variable's value, which raised a python syntax error.
By the way, try not to make your variables with language keywords/library names - like ${json} up there.

Convert nested CSV data file to JSON

I am trying to create a Perl function which converts CSV with a special format to JSON.
I have a CSV file where every line has the following format
child_number,parent_number,status
The root parent (without a parent) has parent_number = NA.
My goal is to convert into JSON format like this
{
number:
status:
children: [
{
number:
status:
children: [
{
number:
status:
}
]
},
number:
status:
children: [
{
number:
status:
}
]
]
}
I inserted the contents of the CSV file into an array and found the line with no parent
foreach my $line ( #csv_arr ) {
($child, $perent, $status) = split(/,/,$line);
last if ( $perent eq "NA" );
}
return 0 unless($perent eq "NA");
I would like to get the children for each $perent and insert them into the data structure. I could use the following
push #{ $json_struct->{usage} }, {
number => $perent,
children => getChildren(),
};
...
my #json_arr = JSON::PP->new->encode($json_struct);
In order to explain myself better, please consider the following example
> cat ./csv_file
7,5,0
5,NA,0
3,5,1
> cat ./json_file
{
number: NA
status: 0
children: [
{
number: 5
status: 0
children: [
{
number: 3
status: 1
},
{
number: 7
status: 0
}
]
}
]
}
These are the contents of the CSV file after a real run
7696,44641,0
44654,44641,0
44646,44641,0
44644,44641,0
44651,44649,0
7700,44641,0
7691,44641,0
44657,44641,0
7699,7698,0
7692,44641,0
44650,44649,0
44661,44660,0
44656,44654,1
44659,44641,0
44648,44646,0
7695,7694,0
44662,44660,0
44641,NA,0
7701,7700,0
7698,44641,0
44653,44651,1
44645,44644,0
44647,44646,0
44649,44641,0
44660,44641,0
7697,7696,0
7689,7688,0
7694,44641,0
44658,44657,1
7693,44641,0
7688,44641,0
What is the proper way to implement this method in Perl?
Here's one way to do it:
use strict;
use warnings;
use JSON::PP ();
my %nodes;
$nodes{NA} = { number => 'NA', status => 0 };
while (my $line = readline DATA) {
chomp $line;
my ($id, $parent_id, $status) = split /,/, $line;
my $node = $nodes{$id} //= {};
$node->{number} = 0 + $id;
$node->{status} = 0 + $status;
push #{ $nodes{$parent_id}{children} }, $node;
}
my $jsonpp = JSON::PP->new->pretty->canonical;
print $jsonpp->encode($nodes{NA});
__DATA__
7,5,0
5,NA,0
3,5,1
Output:
{
"children" : [
{
"children" : [
{
"number" : 7,
"status" : 0
},
{
"number" : 3,
"status" : 1
}
],
"number" : 5,
"status" : 0
}
],
"number" : "NA",
"status" : 0
}
The only reason
$nodes{NA} = { number => 'NA', status => 0 };
is there is to give the root node a number and status field. It doesn't otherwise exist in your CSV input, so without that line you'd get a root object containing only a children field.
For every CSV record we extract its id, the corresponding parent id, and the status.
If we've already created a node for this id (this happens if another node has already specified this node as its parent), we just use the existing node; otherwise we create a new empty node and store it in %nodes.
%nodes is our universe of nodes indexed by their id.
We always set the number and status fields. The 0 + part is to explicitly convert the values to numbers (otherwise they'd be quoted in the JSON output).
We add our current node to the list of children of its parent (which is found in $nodes{$parent_id}{children}).
At the end we simply pretty-print the tree under $nodes{NA}, including its children, their children-children, and so on.

Replace and access values in nested hash/json by path in Ruby

Asking for a advice what would be in your opinion best and simple solution to replace and access values in nested hash or json by path ir variable using ruby?
For example imagine I have json or hash with this kind of structure:
{
"name":"John",
"address":{
"street":"street 1",
"country":"country1"
},
"phone_numbers":[
{
"type":"mobile",
"number":"234234"
},
{
"type":"fixed",
"number":"2342323423"
}
]
}
And I would like to access or change fixed mobile number by path which could be specified in variable like this: "phone_numbers/1/number" (separator does not matter in this case)
This solution is necessary to retrieve values from json/hash and sometimes replace variables by specifying path to it. Found some solutions which can find value by key, but this solution wouldn't work as there is some hashes/json where key name is same in multiple places.
I saw this one: https://github.com/chengguangnan/vine , but it does not work when payload is like this as it is not kinda hash in this case:
[
{
"value":"test1"
},
{
"value":"test2"
}
]
Hope you have some great ideas how to solve this problem.
Thank you!
EDIT:
So I tried code below with this data:
x = JSON.parse('[
{
"value":"test1"
},
{
"value":"test2"
}
]')
y = JSON.parse('{
"name":"John",
"address":{
"street":"street 1",
"country":"country1"
},
"phone_numbers":[
{
"type":"mobile",
"number":"234234"
},
{
"type":"fixed",
"number":"2342323423"
}
]
}')
p x
p y.to_h
p x.get_at_path("0/value")
p y.get_at_path("name")
And got this:
[{"value"=>"test1"}, {"value"=>"test2"}]
{"name"=>"John", "address"=>{"street"=>"street 1", "country"=>"country1"}, "phone_numbers"=>[{"type"=>"mobile", "number"=>"234234"}, {"type"=>"fixed", "number"=>"2342323423"}]}
hash_new.rb:91:in `<main>': undefined method `get_at_path' for [{"value"=>"test1"}, {"value"=>"test2"}]:Array (NoMethodError)
For y.get_at_path("name") got nil
You can make use of Hash.dig to get the sub-values, it'll keep calling dig on the result of each step until it reaches the end, and Array has dig as well, so when you reach that array things will keep working:
# you said the separator wasn't important, so it can be changed up here
SEPERATOR = '/'.freeze
class Hash
def get_at_path(path)
dig(*steps_from(path))
end
def replace_at_path(path, new_value)
*steps, leaf = steps_from path
# steps is empty in the "name" example, in that case, we are operating on
# the root (self) hash, not a subhash
hash = steps.empty? ? self : dig(*steps)
# note that `hash` here doesn't _have_ to be a Hash, but it needs to
# respond to `[]=`
hash[leaf] = new_value
end
private
# the example hash uses symbols as the keys, so we'll convert each step in
# the path to symbols. If a step doesn't contain a non-digit character,
# we'll convert it to an integer to be treated as the index into an array
def steps_from path
path.split(SEPERATOR).map do |step|
if step.match?(/\D/)
step.to_sym
else
step.to_i
end
end
end
end
and then it can be used as such (hash contains your sample input):
p hash.get_at_path("phone_numbers/1/number") # => "2342323423"
p hash.get_at_path("phone_numbers/0/type") # => "mobile"
p hash.get_at_path("name") # => "John"
p hash.get_at_path("address/street") # => "street 1"
hash.replace_at_path("phone_numbers/1/number", "123-123-1234")
hash.replace_at_path("phone_numbers/0/type", "cell phone")
hash.replace_at_path("name", "John Doe")
hash.replace_at_path("address/street", "123 Street 1")
p hash.get_at_path("phone_numbers/1/number") # => "123-123-1234"
p hash.get_at_path("phone_numbers/0/type") # => "cell phone"
p hash.get_at_path("name") # => "John Doe"
p hash.get_at_path("address/street") # => "123 Street 1"
p hash
# => {:name=>"John Doe",
# :address=>{:street=>"123 Street 1", :country=>"country1"},
# :phone_numbers=>[{:type=>"cell phone", :number=>"234234"},
# {:type=>"fixed", :number=>"123-123-1234"}]}