user
Task

Sort the most popular computer programming languages based in number of members in Rosetta Code categories.

Sample output on 02 August 2022 at 09:50 +02

```
Rank:  1 (1,565 entries) Phix
Rank:  2 (1,558 entries) Wren
Rank:  3 (1,531 entries) Julia
Rank:  4 (1,507 entries) Raku
Rank:  5 (1,500 entries) Go
Rank:  6 (1,466 entries) Perl
Rank:  7 (1,409 entries) Python
Rank:  8 (1,402 entries) Nim
Rank:  9 (1,254 entries) J
Rank: 10 (1,211 entries) C
...
```

Notes

* Each language typically demonstrates one or two methods of accessing the data:

:   :   :   * with web scraping   (via http://www.rosettacode.org/mw/index.php?title=Special:Categories&limit=5000)
            * with the API method   (examples below for Awk, Perl, Ruby, Tcl, etc).

* The scraping and API solutions can be separate subsections, see the Tcl example.
* Filtering wrong results is optional.   You can check against Special:MostLinkedCategories (if using web scraping)

:   :   If you use the API, and do elect to filter, you may check your results against this complete, accurate, sortable, wikitable listing of all **971** programming languages, updated periodically, *typically weekly*.

* A complete ranked listing of all   **813**   languages (from the REXX example) is included here   ──►   output from the REXX program.
assistant
(formerly Perl 6)

### Raku: Using the API

Note that this counts **only** the tasks. It does not include other non-task categories in the counts yielding more realistic, non-inflated numbers. Raku is Unicode aware and handles non-ASCII names natively. This does not attempt to 'unify' different language names that are the same behind the scenes as a result of Rosettacodes' capitalization peculiarities. (E.G. μC++, UC++ & ΜC++)

```
use HTTP::UserAgent;
use URI::Escape;
use JSON::Fast;
use Sort::Naturally;

my $client = HTTP::UserAgent.new;

my $url = 'https://rosettacode.org/w';

my $tablefile = './RC_Popularity.txt';

my %cat = (
    'Programming_Tasks' => 'Task',
    'Draft_Programming_Tasks' => 'Draft'
);
my %tasks;

for %cat.keys.sort -> $cat {
    mediawiki-query(
        $url, 'pages',
        :generator<categorymembers>,
        :gcmtitle("Category:$cat"),
        :gcmlimit<350>,
        :rawcontinue(),
        :prop<title>
    ).map({ %tasks{%cat{$cat}}++ });
}

my %counts =
    mediawiki-query(
        $url, 'pages',
        :generator<categorymembers>,
        :gcmtitle<Category:Programming Languages>,
        :gcmlimit<350>,
        :rawcontinue(),
        :prop<categoryinfo>
    )
    .map({
        my $title = .<title>.subst(/^'Category:'/, '');
        my $tasks = (.<categoryinfo><pages> || 0);
        my $categories = (.<categoryinfo><subcats> || 0);
        my $total = (.<categoryinfo><size> || 0);
       $title  => [$tasks ,$categories, $total]
   });

my $out = open($tablefile, :w)  or die "$!\n";

# Add table boilerplate and header
$out.say:
    "\{|class=\"wikitable sortable\"\n",
    "|+ As of { Date.today } :: {+%counts} Languages\n",
    '!Rank!!Language!!Task<br>Entries!!Tasks<br>done %!!Non-task<br>Subcate-<br>gories!!Total<br>Categories'
;

my @bg = <#fff; #ccc;>;
my $ff = 0;
my $rank = 1;
my $ties = 0;

# Get sorted unique task counts
for %counts.values»[0].unique.sort: -* -> $count {
    $ff++;
    # Get list of tasks with this count
    my @these = %counts.grep( *.value[0] == $count )».keys.sort: *.&naturally;

    for @these {
        $ties++;
        $out.say:
          "|- style=\"background-color: { @bg[$ff % 2] }\"\n"~
          "|$rank\n"~
          "|[[:Category:$_|]]\n"~
          "|$count\n"~
          "|{(100 * $count/%tasks<Draft Task>.sum).round(.01)} %\n"~
          "|{%counts{$_}[1]}\n"~
          "|{%counts{$_}[2]}"
    }
    $rank += $ties;
    $ties = 0;
}
$out.say( "|}" );
$out.say('=' x 5, " query, download & processing: {(now - INIT now).round(.01)} seconds ", '=' x 5);
$out.close;

sub mediawiki-query ($site, $type, *%query) {
    my $url = "$site/api.php?" ~ uri-query-string(
        :action<query>, :format<json>, :formatversion<2>, |%query);
    my $continue = '';

    gather loop {
        my $response = $client.get("$url&$continue");
        my $data = from-json($response.content);
        take $_ for $data.<query>.{$type}.values;
        $continue = uri-query-string |($data.<query-continue>{*}».hash.hash or last);
    }
}

sub uri-query-string (*%fields) {
    join '&', %fields.map: { "{.key}={uri-escape .value}" }
}

```

Abridged output:

See full output here.

As of 2019-02-10 :: 715 Languages

| Rank | Language | Task Entries | Tasks done % | Non-task Subcate- gories | Total Categories |
| --- | --- | --- | --- | --- | --- |
| 1 | Go | 1100 | 96.15 % | 4 | 1104 |
| 2 | Perl 6 | 1046 | 91.43 % | 4 | 1050 |
| 3 | Kotlin | 1029 | 89.95 % | 1 | 1030 |
| 4 | Python | 1017 | 88.9 % | 17 | 1034 |
| 5 | Phix | 991 | 86.63 % | 3 | 994 |
| 6 | Racket | 986 | 86.19 % | 3 | 989 |
| 7 | Perl | 963 | 84.18 % | 5 | 968 |
| 8 | Julia | 958 | 83.74 % | 3 | 961 |
| 9 | C | 940 | 82.17 % | 3 | 943 |
| 10 | Tcl | 925 | 80.86 % | 4 | 929 |
| 11 | Zkl | 918 | 80.24 % | 1 | 919 |
| 12 | J | 901 | 78.76 % | 3 | 904 |
| 13 | Java | 897 | 78.41 % | 3 | 900 |
| 14 | REXX | 886 | 77.45 % | 4 | 890 |
| 15 | D | 871 | 76.14 % | 3 | 874 |
| 16 | Ruby | 866 | 75.7 % | 3 | 869 |
| 17 | Haskell | 849 | 74.21 % | 3 | 852 |
| 18 | Scala | 789 | 68.97 % | 3 | 792 |
| 19 | Sidef | 787 | 68.79 % | 1 | 788 |
| 20 | PicoLisp | 772 | 67.48 % | 3 | 775 |

### Raku: Using web scraping

Scraping the languages and categories pages. Raku automatically handles Unicode names correctly.

```
my $languages =  qx{wget -O - 'http://rosettacode.org/wiki/Category:Programming_Languages'};
my $categories = qx{wget -O - 'http://www.rosettacode.org/mw/index.php?title=Special:Categories&limit=5000'};
 
my @lines = $languages.lines;
shift @lines until @lines[0] ~~ / '<h2>Subcategories</h2>' /;
my \languages = set gather for @lines {
    last if / '/bodycontent' /;
    take ~$0 if
        / '<li><a href="/wiki/Category:' .*? '" title="Category:' .*? '">' (.*?) '</a></li>' /;
}
 
@lines = $categories.lines;
my @results = sort -*.[0], gather for @lines {
    take [+$1.subst(',', ''), ~$0] if
        / '<li><a href="/wiki/Category:' .*? '" title="Category:' .*? '">'
        (.*?) <?{ ~$0 ∈ languages }>
        '</a>' .*? '(' (<[, 0..9]>+) ' member' /;
}
 
for @results.kv -> $i, @l {
    printf "%d:\t%4d - %s\n", $i+1, |@l;
}

```

Output:

(As of 2018-10-28) Here we show only the top 10.

```
1:	1036 - Go
2:	1029 - Kotlin
3:	1014 - Python
4:	 998 - Perl 6
5:	 980 - Racket
6:	 929 - Tcl
7:	 926 - C
8:	 910 - Perl
9:	 904 - Zkl
10:	 901 - J
```