Can you call a method from an array element? - excel

I have the following code:
my $workbook = Excel::Writer::XLSX->new( 'a_simple.xlsx' );
my $worksheet = $workbook->add_worksheet();
my #chart_performance1 = $workbook->add_chart( type => 'column', embedded => 1 );
my $no_of_titles = 3;
for ( my $no_of = 0; $no_of < $no_of_titles; $no_of++ ) {
$chart_performance1[ $no_of ]->add_series(
name => $chart_heading[ 0 ],
categories => [ 'Sheet1', $array_game_titles[ $no_of ] , $row_range_max , 0, 0 ],
values => [ 'Sheet1', $array_game_titles[ $no_of ] , $row_range_max , 1, 1 ],
);
}
When I run it, I get the error:
Can't call method "add_series" on an undefined value
Why?

This line
my #chart_performance1 = $workbook->add_chart( type => 'column', embedded => 1 );
looks wrong. The add_chart method returns a single Excel::Writer::XLSX::Chart object, so the result is normally assigned to a scalar, not an array. It's unclear what you're asking, but if you are trying to create one chart that plots three series of data, then you want something more like:
my $chart = $workbook->add_chart( type => 'column', embedded => 1 );
...
for ( my $no_of = 0; $no_of < $no_of_titles; $no_of++ ) {
$chart->add_series( ... );
}

Got my Answer, Need to only declare the array instead of declaring and defining the array "chart_performance" with add_chart method at the same instance. As the add_chart method returns a single object i was getting the error. Thanks for the help BTW.
my $workbook = Excel::Writer::XLSX->new( 'a_simple.xlsx' );
my $worksheet = $workbook->add_worksheet();
my #chart_performance;
my $no_of_titles = 3;
for ( my $no_of = 0; $no_of < $no_of_titles; $no_of++ ) {
$chart_performance[ $no_of ] = $workbook->add_chart( type => 'column', embedded => 1);
$chart_performance[ $no_of ]->add_series(
name => $chart_heading[ 0 ],
categories => [ 'Sheet1', $array_row[ $no_of ], $array_col[ $no_of ], 0, 0 ],
values => [ 'Sheet1', $array_row[ $no_of ], $array_col[ $no_of ], 1, 1 ],
);
}

Related

Grok patterns to match log with multiple special characters

I want to catch my exception with ELK but my exception is full of ( { [ . , \ / , " ' character. How can I index them in grok?
My log file:
Exception in *** CoreLevel*** occured.
Date&Time: 2018-01-21 09:52:20.744092
Root:
( ['MQROOT' : 0x7f0a902b2d80]
(0x01000000:Name ):Properties = ( ['MQPROPERTYPARSER' : 0x7f0a902bffa0]
(0x03000000:NameValue):MessageFormat = 'jms_text' (CHARACTER) )
(0x03000000:NameValue):MsgId = X'5059414d313339363131303234383030303238' (BLOB))
(0x01000000:Name ):usr = (
(0x03000000:NameValue):MessageName = 'SampleMessageName' (CHARACTER)
(0x03000000:NameValue):MsgVersion = 'V1' (CHARACTER)
)
)
)
*****************************************************************************************
*****************************************************************************************
ExceptionList:
( ['MQROOT' : 0x7f0a9072b350]
(0x01000000:Name):RecoverableException = (
(0x03000000:NameValue):File = '/build/slot1/S800_P/src/DataFlowEngine/PluginInterface/ImbJniNode.cpp' (CHARACTER)
(0x03000000:NameValue):Line = 1260 (INTEGER)
(0x03000000:NameValue):Text = 'Caught exception and rethrowing' (CHARACTER)
(0x01000000:Name ):Insert = (
(0x03000000:NameValue):Type = 14 (INTEGER)
)
(0x03000000:NameValue):Label = '' (CHARACTER)
(0x03000000:NameValue):Catalog = "BIPmsgs" (CHARACTER)
(0x03000000:NameValue):Severity = 3 (INTEGER)
(0x03000000:NameValue):Number = 4395 (INTEGER)
)
)
)
and I except to get this pattern into kibana
Exception in: CoreLevel,
Date&Time: 2018-01-21 09:52:20.744092
message:{
Root:".....",
ExceptionList:"......"
}
and this is my grok block that doesn't work
grok {
patterns_dir => "/etc/logstash/patterns/"
break_on_match => false
keep_empty_captures => true
match => {"message" => ["Exception in (?<msg_f> occured..) Date&Time: %{SYSLOGTIMESTAMP:timestamp}"]}
}
mutate {
gsub => ["message", "\n", ""]
}
I'd really appreciate if anyone could help me.
The date in your log is in ISO8601 format so it can be matched with TIMESTAMP_ISO8601 predefined pattern.
For lines after date & time, you can use (?m) to match multiline in your log with GREEDYDATA.
Following pattern will work,
Exception in \*\*\* %{WORD:Exception_in}.*\s*Date&Time: %{TIMESTAMP_ISO8601}(?m)%{GREEDYDATA}
It will output,
{
"Exception_in": [
[
"CoreLevel"
]
],
"TIMESTAMP_ISO8601": [
[
"2018-01-21 09:52:20.744092"
]
],
"YEAR": [
[
"2018"
]
],
"MONTHNUM": [
[
"01"
]
],
"MONTHDAY": [
[
"21"
]
],
"HOUR": [
[
"09",
null
]
],
"MINUTE": [
[
"52",
null
]
],
"SECOND": [
[
"20.744092"
]
],
"ISO8601_TIMEZONE": [
[
null
]
],
"GREEDYDATA": [
[
" \nRoot: \n ( ['MQROOT' : 0x7f0a902b2d80]\n (0x01000000:Name ):Properties = ( ['MQPROPERTYPARSER' : 0x7f0a902bffa0]\n (0x03000000:NameValue):MessageFormat = 'jms_text' (CHARACTER) )\n (0x03000000:NameValue):MsgId = X'5059414d313339363131303234383030303238' (BLOB))\n (0x01000000:Name ):usr = (\n (0x03000000:NameValue):MessageName = 'SampleMessageName' (CHARACTER)\n (0x03000000:NameValue):MsgVersion = 'V1' (CHARACTER)\n )\n )\n) \n***************************************************************************************** \n***************************************************************************************** \nExceptionList: \n( ['MQROOT' : 0x7f0a9072b350]\n (0x01000000:Name):RecoverableException = (\n (0x03000000:NameValue):File = '/build/slot1/S800_P/src/DataFlowEngine/PluginInterface/ImbJniNode.cpp' (CHARACTER)\n (0x03000000:NameValue):Line = 1260 (INTEGER)\n (0x03000000:NameValue):Text = 'Caught exception and rethrowing' (CHARACTER)\n (0x01000000:Name ):Insert = (\n (0x03000000:NameValue):Type = 14 (INTEGER)\n )\n (0x03000000:NameValue):Label = '' (CHARACTER)\n (0x03000000:NameValue):Catalog = "BIPmsgs" (CHARACTER)\n (0x03000000:NameValue):Severity = 3 (INTEGER)\n (0x03000000:NameValue):Number = 4395 (INTEGER)\n )\n )\n)"
]
]
}
You can test it here

Is there a standard functional name for this function?

I'm sure this function is likely common ( or possibly achievable other ways ) but I'm not sure of what it'd be called. I'm thinking of a sliding window of a certain size :-
let slidingMap = (arr,size, f) => {
r = []
arr.reduce((acc, n) => {
let b = acc.concat(n);
if(b.length > size) {
b.shift();
}
if(b.length == size) {
r.push(f(b))
}
return b;
},[])
return r;
}
so given slidingMap([1,2,3,4,5,6], 2, b => b)
you'd get [ [ 1, 2 ], [ 2, 3 ], [ 3, 4 ], [ 4, 5 ], [ 5, 6 ] ]
and slidingMap([1,2,3,4,5,6], 3, b => b)
you'd get [ [ 1, 2, 3 ], [ 2, 3, 4 ], [ 3, 4, 5 ], [ 4, 5, 6 ] ]
or for calculating differences :-
slidingMap([1,2,3,7,5,6],2, b => b.reduceRight((a, n) => a? a-n : n))
you'd get [ 1, 1, 4, -2, 1 ]
or moving average :-
slidingMap([1,2,3,7,5,6],3, b => b.reduce((a, n) => a+n,0)/b.length)
you'd get [ 2, 4, 5, 6 ]
so, is there a commonly implemented function(s) that achieves this?
Update
Probablly better implemented as
let sliding = (arr,size) => {
r = []
arr.reduce((acc, n) => {
let b = acc.concat(n);
if(b.length > size) {
b.shift();
}
if(b.length == size) {
r.push(b)
}
return b;
},[])
return r;
}
then just use map
sliding([1,2,3,4,5],2).map(somefunc);
Or perhaps using zip and skip ( using lodash in this case )
let sliding = (arr, size) =>
_.zip(..._.range(size).map(i => arr.slice(i)))
.filter(a => !a.some(v => v == undefined))
only trick here is the zip will insert undefined when it has no match so they need to be filtered out.

node_redis get zrange withscores

Does anybody know how can I get members with scores by node redis?
I tried something like this:
client.ZRANGE(key, 0, -1, withscores, function(err, replies) {
});
Thanks.
This code looks good. Check out the following link for retrieving what you want :
http://ricochen.wordpress.com/2012/02/28/example-sorted-set-functions-with-node-js-redis/
Added the code here from that link example in case it is ever removed.
var rc=require('redis').createClient();
var _=require('underscore');
rc.zincrby('myset', 1, 'usera');
rc.zincrby('myset', 5, 'userb');
rc.zincrby('myset', 3, 'userc');
rc.zrevrange('myset', 0, -1, 'withscores', function(err, members) {
// the resulting members would be something like
// ['userb', '5', 'userc', '3', 'usera', '1']
// use the following trick to convert to
// [ [ 'userb', '5' ], [ 'userc', '3' ], [ 'usera', '1' ] ]
// learned the trick from
// http://stackoverflow.com/questions/8566667/split-javascript-array-in-chunks-using-underscore-js
var lists=_.groupBy(members, function(a,b) {
return Math.floor(b/2);
});
console.log( _.toArray(lists) );
});
rc.quit();
Seems your code is right. The following is the syntax to get zrange.
without score:
redisClient.zrange(keyName,start,stop,function(err,result){
//result is array
// every index will give you member name
})
Ex :
redisClient.zrange("mySortedset",-1,-1,function(err,result){
//result is array
// every index will give you member name
})
with score:
redisClient.zrange(keyName,start,stop,'withscores',function(err,result){
//result is array
// here even index will hold member
// odd index will hold its score
})
Ex :
redisClient.zrange("mySortedset",-1,-1,'withscores',function(err,result){
//result is array
// here even index will hold member
// odd index will hold its score
})
I tried with the prior accepted answers but i could not get the result i want and later i tried with the following code and got appropriate result,
Original output:
[ 'player:522',
'19685',
'player:164',
'19594',
'player:807',
'19171',
'player:694',
'19165',
'player:905',
'19108',
'player:859',
'19087',
'player:432',
'18973',
'player:515',
'18831',
'player:163',
'18750',
'player:4',
'18552' ]
Expected output:
{
"player:522": "19685",
"player:164": "19594",
"player:807": "19171",
"player:694": "19165",
"player:905": "19108",
"player:859": "19087",
"player:432": "18973",
"player:515": "18831",
"player:163": "18750",
"player:4": "18552"
}
Solution:
redisClient.ZREVRANGE('daily', 1, 10, 'WITHSCORES', function(err, result) {
result = _.fromPairs(_.chunk(result, 2));
return res.status(200).json(result);
});
The right approach for versions ^2.0,
var args = [ key,to, from ];
redisClient.zrevrangebyscore(args,function(err,data){
Vanilla JS Solution
Redis call:
redisClient.zrange(keyName, start, stop, 'withscores', function(err, result) {
// result.reduce ... (See below)
}
Here is a Vanilla-JS solution that I came up with pretty quickly.
For me, personally, it does not make sense to import underscore or any other library to perform such an easy task:
result.reduce(function (a, c, i) {
var idx = i / 2 | 0;
if (i % 2) {
a[idx].score = c;
} else {
a[idx] = { id: c };
}
return a;
}, []);
Assuming this input:
['player1', 13, 'player2', 11, 'player4', 7, 'player3', 3, 'player5', 0]
This function yields:
[
{ id: 'player1', score: 13 },
{ id: 'player2', score: 11 },
{ id: 'player4', score: 7 },
{ id: 'player3', score: 3 },
{ id: 'player5', score: 0 }
]
Here is another one to transform the result into a two-dimensional array:
result.reduce(function (a, c, i) {
var idx = i / 2 | 0;
if (i % 2) {
a[idx].push(c);
} else {
a[idx] = [c];
}
return a;
}, []);
which produces the following array:
[
[ 'player1', 13 ],
[ 'player2', 11 ],
[ 'player4', 7 ],
[ 'player3', 3 ],
[ 'player5', 0 ]
]
One line lambda version:
result.reduce((a, c, i) => i % 2 ? (a[i / 2 | 0].data = c, a) : (a[i / 2 | 0] = { id: c }, a), []);
Vanilla JS reduce works well here.
const result = [
'player:522',
'19685',
'player:164',
'19594',
'player:807',
'19171',
'player:694',
'19165',
'player:905',
'19108',
'player:859',
'19087',
'player:432',
'18973',
'player:515',
'18831',
'player:163',
'18750',
'player:4',
'18552'
]
const map = result.reduce((map, k, i, res) => {
if (i % 2 !== 0) {
map[res[i - 1]] = Number(k);
}
return map;
}, {})
map is now:
{
'player:522': 19685,
'player:164': 19594,
'player:807': 19171,
'player:694': 19165,
'player:905': 19108,
'player:859': 19087,
'player:432': 18973,
'player:515': 18831,
'player:163': 18750.65468,
'player:4': 18552
}
var data = []
results.map((result, index) => {
if (index % 2 == 0) {
data.push(results[index] = { player: results[index], score: results[index+1] })
}
})
console.log(data)

Groovy code to convert json to CSV file

Does anyone have any sample Groovy code to convert a JSON document to CSV file? I have tried to search on Google but to no avail.
Example input (from comment):
[ company_id: '1',
web_address: 'vodafone.com/',
phone: '+44 11111',
fax: '',
email: '',
addresses: [
[ type: "office",
street_address: "Vodafone House, The Connection",
zip_code: "RG14 2FN",
geo: [ lat: 51.4145, lng: 1.318385 ] ]
],
number_of_employees: 91272,
naics: [
primary: [
"517210": "Wireless Telecommunications Carriers (except Satellite)" ],
secondary: [
"517110": "Wired Telecommunications Carriers",
"517919": "Internet Service Providers",
"518210": "Web Hosting"
]
]
More info from an edit:
def export(){
def exportCsv = [ [ id:'1', color:'red', planet:'mars', description:'Mars, the "red" planet'],
[ id:'2', color:'green', planet:'neptune', description:'Neptune, the "green" planet'],
[ id:'3', color:'blue', planet:'earth', description:'Earth, the "blue" planet'],
]
def out = new File('/home/mandeep/groovy/workspace/FirstGroovyProject/src/test.csv')
exportCsv.each {
def row = [it.id, it.color, it.planet,it.description]
out.append row.join(',')
out.append '\n'
}
return out
}
Ok, how's this:
import groovy.json.*
// Added extra fields and types for testing
def js = '''{"infile": [{"field1": 11,"field2": 12, "field3": 13},
{"field1": 21, "field4": "dave","field3": 23},
{"field1": 31,"field2": 32, "field3": 33}]}'''
def data = new JsonSlurper().parseText( js )
def columns = data.infile*.keySet().flatten().unique()
// Wrap strings in double quotes, and remove nulls
def encode = { e -> e == null ? '' : e instanceof String ? /"$e"/ : "$e" }
// Print all the column names
println columns.collect { c -> encode( c ) }.join( ',' )
// Then create all the rows
println data.infile.collect { row ->
// A row at a time
columns.collect { colName -> encode( row[ colName ] ) }.join( ',' )
}.join( '\n' )
That prints:
"field3","field2","field1","field4"
13,12,11,
23,,21,"dave"
33,32,31,
Which looks correct to me

How can I find the connected components of a graph in Perl?

I have the following collection of nodes and edges. What I want to do is to find all the distinct graph from it.
my %connections=(36=>[31],10=>[3,4],31=>[30,22],30=>[20],22=>[20,8],20=>[1],8=>[5],5=>[2],2=>[1,20], 3=>[7]);
In this example it will yield:
my %all_graph = {
graph1 => {36=>[31],31=>[30,22],30=>[20],22=>[20,8],20=>[1],8=>[5],5=>[2],2=>[1,20]}.
graph2 => {10=>[3,4], 3=>[7]}
};
Is there any existing algorithms that does that?
Use the Graph module:
#!/usr/bin/perl
use strict; use warnings;
use Graph;
my %connections = (
36 => [ 31 ],
10 => [ 3, 4],
31 => [ 30, 22],
30 => [ 20 ],
22 => [ 20, 8],
20 => [ 1 ],
8 => [ 5 ],
5 => [ 2 ],
2 => [ 1, 20 ],
3 => [ 7 ]
);
my $g = Graph->new( undirected => 1 );
for my $src ( keys %connections ) {
for my $tgt ( #{ $connections{$src} } ) {
$g->add_edge($src, $tgt);
}
}
my #subgraphs = $g->connected_components;
my #allgraphs;
for my $subgraph ( #subgraphs ) {
push #allgraphs, {};
for my $node ( #$subgraph ) {
if ( exists $connections{ $node } ) {
$allgraphs[-1]{$node} = [ #{ $connections{$node} } ];
}
}
}
use YAML; print Dump \#allgraphs;
Output:
[sinan#archardy SO]$ ./g
---
- 2:
- 1
- 20
20:
- 1
22:
- 20
- 8
30:
- 20
31:
- 30
- 22
36:
- 31
5:
- 2
8:
- 5
- 10:
- 3
- 4
3:
- 7
To find the connected components of an undirected graph you just do a BFS or DFS (Breadth/Depth first search).
Here some sample BFS code
my %connections=(36=>[31],10=>[3,4],31=>[30,22],30=>[20],22=>[20,8]
,20=>[1],8=>[5],5=>[2],2=>[1,20], 3=>[7]);
my $full_connections = {}; # Build a REAL graph with full 2-way edge lists
foreach my $node (keys %connections) {
foreach my $node2 (#{ $connections{$node} }) {
print "$node, $node2\n";
$full_connections->{$node}->{$node2} = 1;
$full_connections->{$node2}->{$node} = 1;
}
}
my %all_graph = ();
my $current_graph = 0;
my %visited = ();
my #to_visit = ();
foreach my $node (keys %$full_connections) {
next if exists $visited{$node};
# start the next segment
$current_graph++;
#to_visit=($node);
while (#to_visit) {
$node_to_visit = shift #to_visit;
#next if $visited{$node_to_visit};
$visited{$node_to_visit} = $current_graph;
push #to_visit, grep { !exists $visited{$_} }
keys %{ $full_connections->{$node_to_visit} };
}
}
# Now reconstruct %all_graph from %visited - left as exercise for the reader
print Data::Dumper->Dump([\%visited]);
I'd suggest the following algorithm:
1.) Move all nodes into a working set N.
2.) Starting with an arbitrary node perform a graph search (depth-first or breadth-first). Add all visited nodes and edges to the first subgraph, remove visited nodes from N
3.) If N is non-empty, select the next starting node and go to step 2.) for the next subgraph.

Resources