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
