I have a file outputted from a TCL script, which has a TCL syntax'ed array, as below.
set data(item1) {
xyz {
a { one two three 1 2 3}
b { three one two 3 2 4}
}
lmn {
z { "something" 1 2 3}
d { "samething" 3 2 4}
}
};
set data(item2) {
xyz {
ss { 100 }
sd { "sdss" 200 300}
}
lmn {
ee { "xdf" 1 "2dsd" 3}
pp { "dd" "fsdf" 3 2 4}
}
};
Now I need to read this file in a Ruby program and build them into a Hash of Hashes, similar to something below, before I start consuming the required data:
data = {
'item1' => {
'xyz' => {
'a' => %w{one two three 1 2 3},
'b' => %w{three one two 3 2 4}
},
'lmn' => {
'z' => %w{something 1 2 3},
'd' => %w{samething 3 2 4}
}
},
'item2' => {
'xyz' => {
'ss' => %w{100 },
'sd' => %w{sdss 200 300}
},
'lmn' => {
'ee' => %w{xdf 1 2dsd 3},
'pp' => %w{dd fsdf 3 2 4}
}
}
}
Is there any Ruby utility or method that I can use for this purpose?
Thanks in advance for your support.
No. You will have to build a parser. Take a look at treetop.
It will help a lot to have some early basic knowledge of compilers like compiling phases (lexical analyzer and syntax analyzer, you don't need semantic analyzer for this project).
Also, some basic understanding of grammars will help, since is pre-requisite for compilers - but most likely you will stumble upon grammars while trying to figure out compilers.
Related
My raku Inline::Python code module unexpectedly prints output even when the rs_str method is disabled.
use Inline::Python;
role Series {
has $args;
has $!py = Inline::Python.new;
has $.po; #each instance has own Python Series obj
method TWEAK {
my $py-str = qq{
class RakuSeries:
def __init__(self):
self.series = pd.Series($args)
#`[
def rs_str(self):
return(str(self.series))
#]
};
$!py.run($py-str);
$!po = $!py.call('__main__', 'RakuSeries');
}
method Str {
$!po.rs_str()
}
}
say ~Series.new( args => "[1, 3, 5, 6, 8]" );
>>>
0 1
1 3
2 5
3 6
4 8
Name: anon, dtype: int64
Is this a special tunnelling mode?
Poisson d'Avril
April Fool
першоквітневий дурень
Aprilscherz
I am making a poker hand analyzer in Elixir. The program takes an input of 52 ints and distributes 5 odd (indexed) cards to player1 and 5 even (indexed) cards to player2, before deciding whose hand is better. I made a function for each player (below). When I try and compile, compiler throws an error: (CompileError) poker.ex:49: undefined function player1/1. I have tried a lot of things, but they all seem to fail, please help!
defmodule Poker do
decks = %{ 1 => "2C", 2 => "3C", 3 => "4C", 4 => "5C", 5 => "6C", 6 => "7C", 7 => "8C",
8=> "9C", 9=> "10C", 10 => "11C", 11 => "12C", 12 => "13C", 13 => "1C", 14 => "2D",
15 => "3D", 16=> "4D", 17 => "5D", 18=> "6D", 19=> "7D", 20=> "8D", 21=> "9D",
22=> "10D", 23=> "11D", 24=> "12D", 25=> "13D", 26=> "1D", 27=> "2H", 28=> "3H",
29=> "4H", 30=> "5H", 31=> "6H", 32=> "7H", 33=> "8H", 34=> "9H", 35=> "10H",
36=> "11H", 37=> "12H", 38=> "13H", 39=> "1H", 40=> "2S", 41=> "3S", 42=> "4S",
43=> "5S", 44=> "6S", 45=> "7S", 46=> "8S", 47=> "9S", 48=> "10S", 49=> "11S",
50=> "12S", 51=> "13S", 52=> "1S"}
defp player1(cards), do: Enum.take(Enum.drop_every(cards, 2), 5)
defp player2(cards) do
Enum.take(
cards -- (Enum.drop_every(cards, 2)) ,5)
end
mapHand = for n <- player1(cards), do: Map.get(decks, n)
end
What am I doing wrong?
There's some problems with your code. And the solution mostly depends on what you want to do. It would help you a great deal to take a look at https://elixir-lang.readthedocs.io/en/latest/technical/scoping.html to get a better understanding of the scoping rules in Elixir.
The most straightforward solution I would suggest in your case, would be to replace all of the matches e.g.mapHand = for n <- ... for functions. Like so:
defmodule Poker do
defp decks do
%{ 1 => "2C", 2 => "3C", 3 => "4C", 4 => "5C", 5 => "6C", 6 => "7C", 7 => "8C",
8=> "9C", 9=> "10C", 10 => "11C", 11 => "12C", 12 => "13C", 13 => "1C", 14 => "2D",
15 => "3D", 16=> "4D", 17 => "5D", 18=> "6D", 19=> "7D", 20=> "8D", 21=> "9D",
22=> "10D", 23=> "11D", 24=> "12D", 25=> "13D", 26=> "1D", 27=> "2H", 28=> "3H",
29=> "4H", 30=> "5H", 31=> "6H", 32=> "7H", 33=> "8H", 34=> "9H", 35=> "10H",
36=> "11H", 37=> "12H", 38=> "13H", 39=> "1H", 40=> "2S", 41=> "3S", 42=> "4S",
43=> "5S", 44=> "6S", 45=> "7S", 46=> "8S", 47=> "9S", 48=> "10S", 49=> "11S",
50=> "12S", 51=> "13S", 52=> "1S"}
end
defp player1(cards), do: Enum.take(Enum.drop_every(cards, 2), 5)
defp player2(cards) do
Enum.take(cards -- (Enum.drop_every(cards, 2)), 5)
end
def map_hand(cards) do
for n <- player1(cards), do: Map.get(decks(), n )
end
end
That way you could then (outside of the module) do something like:
player_1_cards = [1, 2, 3, 4, 5]
Poker.map_hand(player_1_cards)
And get something like:
["3C", "5C"]
PLEASE NEED HELP
This is what I'm doing:
var my_array_W:Array = new Array();
my_array_W.push({cor:Acorrect, tem:AnewTime, tab: "TB_A", nom:Aoseasnnombre});
my_array_W.push({cor:Bcorrect, tem:BnewTime, tab: "TB_B", nom:Boseasnnombre});
my_array_W.push({cor:Ccorrect, tem:CnewTime, tab: "TB_C", nom:Coseasnnombre});
my_array_W.push({cor:Dcorrect, tem:DnewTime, tab: "TB_D", nom:Doseasnnombre});
my_array_W.push({cor:Ecorrect, tem:EnewTime, tab: "TB_E", nom:Eoseasnnombre});
my_array_W.push({cor:Fcorrect, tem:FnewTime, tab: "TB_F", nom:Foseasnnombre});
This Output:
[tab] | [cor] | [tem]
TB_A 3 8.6877651541
TB_B 4 12.9287651344
TB_C 1 6199.334999999999923
TB_D 4 33.6526718521
TB_E 4 31.90468496844
TB_F 1 6.334999999923
So then I sort:
my_array_W.sortOn("tem", Array.NUMERIC);
my_array_W.sortOn("cor", Array.NUMERIC | Array.DESCENDING);
And Geting this T_T :
[tab] | [cor] | [tem]
TB_E 4 31.90468496844
TB_D 4 33.6526718521
TB_B 4 12.9287651344
TB_A 3 8.6877651541
TB_F 1 31.90468496844
TB_C 1 6199.334999999999923
I just wanna sort a Winner Table by Time(the less) and Correct(the high)
So the Winner is the One who make more correct answers in less time.
I really try so hard to get a sort like this:
[tab] | [cor] | [tem]
TB_B 4 12.9287651344
TB_E 4 31.90468496844
TB_D 4 33.6526718521
TB_A 3 8.6877651541
TB_F 1 6.334999999923
TB_C 1 6199.334999999999923
But couldn't achieve it
Your mistake is that you sort it 2 times. The second time does not additionally sort the sorted, it just sorts the whole Array anew. What you need is to use the Array.sort(...) method with a compareFunction argument:
my_array_W.sort(sortItems);
// Should return -1 if A < B, 0 if A == B, or 1 if A > B.
function sortItems(A:Object, B:Object):Number
{
// First, the main criteria.
if (A.cor > B.cor) return -1;
if (A.cor < B.cor) return 1;
// If A.cor == B.cor, then secondary criteria.
if (A.tem < B.tem) return -1;
if (A.tem > B.tem) return 1;
// Items seem to be equal.
return 0;
}
#Organis was so close.
But Finally I do the trick :D
With this line
my_array_W.sortOn(['cor', 'tem'],[ Array.NUMERIC | Array.DESCENDING, Array.NUMERIC ]);
I get the result I was looking for
Thanks
In your case you have to write a costume sorter function. to do that check my example:
Your first data:
var arr:Array = [];
arr.push({cor:4,tem:13});
arr.push({cor:3,tem:12});
arr.push({cor:2,tem:1});
arr.push({cor:3,tem:16});
arr.push({cor:1,tem:11});
The sorting function and sort result for sample one based on tem:
arr.sort(scrollSorter);
function temSorter(a,b):int
{
if(a.tem<b.tem)
return 1 ;//To pass a forward
else(a.tem>b.tem)
return -1;//To pass a backward
return 0;//a and b are same.
}
And the result is:
The result is this:
[
{
"cor": 3,
"tem": 16
},
{
"cor": 4,
"tem": 13
},
{
"cor": 3,
"tem": 12
},
{
"cor": 1,
"tem": 11
},
{
"cor": 2,
"tem": 1
}
]
Now the sample based on something close you need:
arr.sort(scrollSorter);
function userScoreCalculator(a):Number
{
return a.cor/a.tem;
}
function winnerSorter(a,b):int
{
var aScore:Number = userScoreCalculator(a);
var bScore:Number = userScoreCalculator(b);
if(aScore<bScore)
return 1 ;
else(aScore>bScore)
return -1
return 0
}
And the result is:
[
{
"cor": 2,
"tem": 1
},
{
"cor": 4,
"tem": 13
},
{
"cor": 3,
"tem": 12
},
{
"cor": 3,
"tem": 16
},
{
"cor": 1,
"tem": 11
}
]
Than means the person with score of 2 is winner because he made it in only 1 second. but other players are close to gather in tem parameter, so the next winner is the person with highest score. it comes from the userScoreCalculator() output. the higher output of that function is the winner.
Now take your time and change the userScoreCalculator() function to show the winner.
https://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7fa4.html
I want to know how to use Observable.
What I want to do is duplicate deletion. The following sample 1 can be moved, but what I want to do is not this format, but how to cook when preparing an array in advance.
orgLayerDistinct(allList: LabelMasterExt[]) {
// Observable.of( allList ).distinct( );
// [sample 1] このサンプルは動くが好みの形式ではない。
// [sample 1] This sample works, but it's not a form of favorite.
Observable.of<Person>(
{ age: 4, name: 'Foo'},
{ age: 7, name: 'Bar'},
{ age: 5, name: 'Foo'},
{ age: 6, name: 'Foo'})
.distinct((p: Person) => p.name)
.subscribe(x => console.log(x));
// [sample 2 experimental] 配列を用意してある前提で利用したい。
// [sample 2 experimental] I would like to use an array on the assumption that it is prepared.
const persons: Person[] = [];
persons.push({ age: 4, name: 'Foo'});
persons.push({ age: 7, name: 'Bar'});
persons.push({ age: 5, name: 'Foo'});
persons.push({ age: 6, name: 'Foo'});
Observable.of<Person[]>(persons)
.distinct((p: Person) => p.name)
.subscribe(x => console.log(x));
}
[sample 2 experimental]
However, this gives the following error.
The type argument for type parameter 'T' cannot be inferred from the usage.
Consider specifying the type arguments explicitly.
Type argument candidate 'Person[]' is not a valid type argument
because it is not a supertype of candidate 'Person'.
Property 'includes' is missing in type 'Person'.
Is there any good plan?
You can either use Observable.from<Person>(array) or Observable.of<Person>(...array).
The problem your second example has is that Observable.of<Person[]>()s elements are arrays of Person, but the .distinct() is expecting an input of the Person type.
I am trying RxJS.
My use case is to parse a log file and group lines by topic ( i.e.: the beginning of the group is the filename and then after that I have some lines with user, date/time and so on)
I can analyse the lines using regExp. I can determine the beginning of the group.
I use ".scan" to group the lines together, when I've the beginning of new group of line, I create an observer on the lines I've accumulated ... fine.
The issue is the end of the file. I've started a new group, I am accumulating lines but I can not trigger the last sequence as I do not have the information that the end. I would have expect to have the information in the complete (but not)
Here is an example using number. Begin of group can multi of 3 or 5. (remark: I work in typescript)
import * as Rx from "rx";
let r = Rx.Observable
.range(0, 8)
.scan( function(acc: number[], value: number): number[]{
if (( value % 3 === 0) || ( value % 5 === 0)) {
acc.push(value);
let info = acc.join(".");
Rx.Observable
.fromArray(acc)
.subscribe( (value) => {
console.log(info, "=>", value);
});
acc = [];
} else {
acc.push(value);
}
return acc;
}, [])
.subscribe( function (x) {
// console.log(x);
});
This emit:
0 => 0
1.2.3 => 1
1.2.3 => 2
1.2.3 => 3
4.5 => 4
4.5 => 5
6 => 6
I am looking how to emit
0 => 0
1.2.3 => 1
1.2.3 => 2
1.2.3 => 3
4.5 => 4
4.5 => 5
6 => 6
7.8 => 7 last items are missing as I do not know how to detect end
7.8 => 8
Can you help me, grouping items?
Any good idea, even not using scan, is welcome.
Thank in advance
You can use the materialize operator. See the documentation here and the marbles here, and an example of use from SO.
In your case, I would try something like (untested but hopefully you can complete it yourself, note that I don't know a thing about typescript so there might be some syntax errors):
import * as Rx from "rx";
let r = Rx.Observable
.range(0, 8)
.materialize()
.scan( function(acc: number[], materializedNumber: Rx.Notification<number>): number[]{
let rangeValue: number = materializedNumber.value;
if (( rangeValue % 3 === 0) || ( rangeValue % 5 === 0)) {
acc.push(rangeValue);
generateNewObserverOnGroupOf(acc);
acc = [];
} else if ( materializedNumber.kind === "C") {
generateNewObserverOnGroupOf(acc);
acc = [];
} else {
acc.push(rangeValue);
}
return acc;
}, [])
// .dematerialize()
.subscribe( function (x) {
// console.log(x);
});
function generateNewObserverOnGroupOf(acc: number[]) {
let info = acc.join(".");
Rx.Observable
.fromArray(acc)
.subscribe( (value) => {
console.log(info, "=>", value);
});
The idea is that the materialize and dematerialize works with notifications, which encodes whether the message being passed by the stream is one of next, error, completed kinds (respectively 'N', 'E', 'C' values for the kind property). If you have a next notification, then the value passed is in the value field of the notification object. Note that you need to dematerialize to return to the normal behaviour of the stream so it can complete and free resources when finished.