Hello,

If I am trying to create something real with J, it looks terrible, I do not
know why, but writing the same simple script on perl and even K was a much
easier for me.
I think the root cause of it that I do not have necessary amount of
"standart" consctruction and do not know how to apply them in J

Let me give an example of the tool I was trying to create:

Description I am trying to calculate:
http://www.usacycling.org/news/user/story.php?id=580
source data: https://dl.dropboxusercontent.com/u/34917039/2013.txt
J source: https://dl.dropboxusercontent.com/u/34917039/1.j

Description of the file:
it has format: lines starts with -- - it is description of the race
Next lines - decription of the protocol: place number <some info> Last
First names - only place and Last+First name is important for us. Also, it
is possible to have DNS,DNF or x, if there is not place.

*1) In perl I did it very simple:*
process it line by line:
if it /-- -> I put the race in races hash table and update count of racers
where.
if it races -> I put it in racers hash table with the link to the race and
place.

Next step: I count scores for every player for every race: You can find an
example of the table here:
http://www.usacycling.org/news/user/story.php?id=580 It is easy - more
points if more participants.

Now I have players with scores for every race and count of races. And now I
calculate category of the racer:
initial category is 4, if count races >= 2 update cat to 4, previous is ok,
then count scores if >20 cat3 if >30 cat2 if >35 cat1.

I can write it in perl in 15-20 minutes with debug and everithing, but I
like K and J and what I spent 2 days to rewrite it :)

J source: https://dl.dropboxusercontent.com/u/34917039/1.j

Let me put the full listing here:

NB. I created table to calculate scores, I know how to read and cut file :)

points =: (4 10 $ 0),(6 3 $3 2 1),(10 6$7 5 4 3 2 1),(29 7$8 6 5 4 3 2
1),(1 9$10 8 7 6 5 4 3 2 1)
lines =: LF cut freads'2013.txt'
score =: ((-&1@(10&((I.@:([<])) }))@[) { {&points@((-&1@#points)&<.@-&1@]))
re =: rxcomp '^(\d+|DNF|DNS|VK|DQ|OTL|x)([\t \.]+(\d+|x))?([\*\t
\.]+([a-zA-Z]+\d*))?([\t \.]+([^\t \.]+ [^\t \.]+))'
re_d =: rxcomp '\d+'

NB. select lines with races:
races_whe =: (('--' -: 2&{.) S:0) lines

NB. now it was more compilated:
NB. I replace box lines without race description with regexp and extract
place and l+f-names. Ok, looks not bad.
NB. Then I convert place from string to number if it possible, if not let
it be _. *The first thing I do not like here* how I work with boxes and
structures: I imagine that box is table, I cannot update some values easy,
I have to extract every value with {. x{ or }. , unbox it process and then
box again and merge with all values, which were not updated. Ok, this line
is not the worst.
NB. Then I group this array by races and remove race description.

r =: (>@}.) each races_whe <;.1 (((<@(".@('_'&[`]@.(re_d&rxeq)))@>@{.) ,
}.) each ((re;1 7)&(rxmatch rxfrom ]) each lines#~-.races_whe))
(I.-.races_whe) } lines

NB. Problem: I cannot work with boxes very well and I have to rotate
extract fiels, then extract another field, unbox it, process, then box,
etc,etc. For the moment it looks like the main problem for me: The longest
part of all these functions is it to extract and unpack and then pack
necessary value again.
NB. Then I merge lines again, with scores and again rotate and extract then
unbox :( I am not really sure now that I do there, I just see a lot of
rotations and extractions.
NB. And it is just to make box: name; score

rs =: >,each/ (|:@((1&{) ,: (<"0)@(>@(0&{) score #@(0&{)))@|:) each r

NB. this line took too long, but I can describe it very simple in SQL:
SELECT NAME, SUM(SCORE), COUNT(SCORE) FROM T GROUP BY NAME
NB. I was lucky to find </. after it I have to reuse rs several times
inside function, I would not like, but it is easier.
NB. I groupped indexes .......... looks like error here: I have to group
only name, not full box ..... anyway.
NB. I groupped indexes, then extract value with index, then I, get first
index, extract first value, unbox, then rotate, extract second field,
unbox, sum
NB. then the same to count, then box and unbox. Crazy :( so simple and so
many operations. I am sure there a much more simple way to do it, That is
why I created this email.

rss =: >((>@(0&{@{.) ; (+/@:>@(1&{@|:)) ; #)@:{&rs) each (rs) </. (i.#rs)

NB. the next step to calculate categories I failed, because amend } it too
long, and just writes following:
cat4 =: 2<:>2{|:rss
cat3 =: 20<:>1{|:rss
cat2 =: 30<:>1{|:rss
cat1 =: 35<:>1{|:rss

cat =: 5- +/cat1,cat2,cat3,:cat4

NB. next box, rotate, group, rotate, unbox. Fortunately is not so long :)
rss =: |:(|:rss),<"0 cat
NB. and sort by group, I would like to sort by name also, but failed.
[ rss =: rss/:>3{|:rss

NB. fuf

Question: Could you please help with some tricks how to make it more clear?

For example:
('a';1),:'b';2 -> add +1
I have to 1) rotate, extract first row to box with (extract second, unbox,
plus, box) and then rotate.

|: (0&{ ,: <@+&1@>@(1&{)) |:('a';1),:'b';2

Thank you,
-- 
Regards,
  Alexander.
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to