Rosetta Code/Rank languages by number of users: Difference between revisions
Rosetta Code/Rank languages by number of users (view source)
Revision as of 17:26, 3 February 2024
, 4 months ago→{{header|Wren}}: Minor tidy
m (→{{header|Wren}}: Minor tidy) |
|||
(12 intermediate revisions by 6 users not shown) | |||
Line 43:
=={{header|Go}}==
<
import (
Line 109:
fmt.Printf(" %-2d%s %3d %s\n", rank, eq, result.users, result.lang)
}
}</
{{out}}
Line 161:
44= 25 AutoHotkey
44= 25 REXX
</pre>
=={{header|Julia}}==
<syntaxhighlight lang="julia">""" Rank languages on Rosetta Code's site by number of users."""
using Dates
using HTTP
using JSON3
const URL = "https://rosettacode.org/w/api.php?"
const PARAMS = ["action" => "query", "format" => "json", "formatversion" => "2", "generator" => "categorymembers",
"gcmtitle" => "Category:Language%20users", "gcmlimit" => "500", "rawcontinue" => "", "prop" => "categoryinfo"]
const resp = HTTP.get(URL * join(map(p -> p[1] * (p[2] == "" ? "" : ("=" * p[2])), PARAMS), "&"))
const counts = Pair{Int, String}[]
for p in JSON3.read(String(resp.body)).query.pages
contains(p.title, "Category") && push!(counts, p.categoryinfo.size => p.title)
end
println("Date: ", now(), "\nLanguage Users\n----------------------")
for p in sort!(filter(p -> p[1] >= 100, counts), rev = true)
println(rpad(replace(p[2], r"Category:(.+) User" => s"\1"), 16), lpad(p[1], 4))
end
</syntaxhighlight>{{out}}
<pre>
Date: 2022-09-03T21:17:29.428
Language Users
----------------------
C 441
Java 321
Python 319
C++ 314
JavaScript 291
PHP 190
Perl 186
SQL 167
UNIX Shell 151
Pascal 133
C sharp 132
BASIC 132
Haskell 115
Ruby 107
</pre>
=={{header|Nim}}==
<
const
Line 175 ⟶ 218:
Prop = "prop=categoryinfo"
Page = "http://rosettacode.org/
[Action, Format, Formatversion, Generator, GcmTitle, GcmLimit, Prop].join("&")
Line 217 ⟶ 260:
rank = i + 1
lastCount = count
echo &"{rank:3} {count:4} - {lang}"</
{{out}}
<pre> 1
2
3
4
5
6
7
8
9
10
12
13
14
15
16
17
19
21
22
23
24
26 47 - Assembly
28
29
30
30
34
38
41
42
42
44
45
45
47
47
47
53
53
53
53
59
60
60
60
60
64
64
64
74
74
87 11 - Eiffel
87 11 - Elixir
87 11 - Groovy
87 11 - Korn Shell
87 11 - MIPS Assembly
87 11 - Octave
87 11 - PARI/GP
87 11 - TypeScript
87 11 - UnixPipes
...
394 0 - Vorpal
394 0 - Vox
394 0 - Wrapl
394 0 - Zonnon</pre>
=={{header|Perl}}==
<
use warnings;
use JSON;
Line 360 ⟶ 412:
for my $k (sort { $table{$b} <=> $table{$a} } keys %table) {
printf "%4d %s\n", $table{$k}, $k if $table{$k} > $minimum;
}</
{{out}}
<pre> 397 C
Line 400 ⟶ 452:
19: 59 - Common Lisp
20: 58 - AWK
</pre>
=={{header|Python}}==
{{libheader|requests}}
<syntaxhighlight lang="python">"""Rank languages by number of users. Requires Python >=3.5"""
import requests
# MediaWiki API URL.
URL = "http://rosettacode.org/mw/api.php"
# Query string parameters
PARAMS = {
"action": "query",
"format": "json",
"formatversion": 2,
"generator": "categorymembers",
"gcmtitle": "Category:Language users",
"gcmlimit": 500,
"prop": "categoryinfo",
}
def fetch_data():
counts = {}
continue_ = {"continue": ""}
# Keep making HTTP requests to the MediaWiki API if more records are
# available.
while continue_:
resp = requests.get(URL, params={**PARAMS, **continue_})
resp.raise_for_status()
data = resp.json()
# Grab the title (language) and size (count) only.
counts.update(
{
p["title"]: p.get("categoryinfo", {}).get("size", 0)
for p in data["query"]["pages"]
}
)
continue_ = data.get("continue", {})
return counts
if __name__ == "__main__":
# Request data from the MediaWiki API.
counts = fetch_data()
# Filter out languages that have less than 100 users.
at_least_100 = [(lang, count) for lang, count in counts.items() if count >= 100]
# Sort languages by number of users
top_languages = sorted(at_least_100, key=lambda x: x[1], reverse=True)
# Pretty print
for i, lang in enumerate(top_languages):
print(f"{i+1:<5}{lang[0][9:][:-5]:<20}{lang[1]}")
</syntaxhighlight>
{{out}}
<pre>
1 C 423
2 Java 308
3 C++ 301
4 Python 301
5 JavaScript 279
6 PHP 182
7 Perl 181
8 SQL 158
9 UNIX Shell 149
10 Pascal 130
11 C sharp 130
12 BASIC 129
13 Haskell 111
14 Ruby 102
</pre>
Line 406 ⟶ 538:
Note: the implementation is very similar to [[Rosetta_Code/Rank_languages_by_popularity#Racket|Rank languages by popularity]].
<
(require racket/hash
Line 448 ⟶ 580:
(~a (format "(~a ~a)" size entries) #:align 'right #:min-width 14)
(replacer cat))
(values size this-rank))</
{{out}}
Line 525 ⟶ 657:
This is all done in a single pass; ties are not detected until a language has the same count as a previous one, so ties are marked by a '''T''' next to the count indicating that '''this''' language has the same count as the '''previous'''.
<syntaxhighlight lang="raku"
use URI::Escape;
use JSON::Fast;
Line 531 ⟶ 663:
my $client = HTTP::UserAgent.new;
my $url = '
my $start-time = now;
Line 556 ⟶ 688:
lang => .<title>.subst(/^'Category:' (.+) ' User'/, ->$/ {$0}) ) })
.sort( { -.<count>, .<syntaxhighlight lang="text"> } )
.map( { last if .<count> < $minimum; display(.<count>, .<syntaxhighlight lang="text">) } );
say "========= elapsed: {(now - $start-time).round(.01)} seconds =========";
Line 582 ⟶ 714:
sub uri-query-string (*%fields) {
join '&', %fields.map: { "{.key}={uri-escape .value}" }
}</
{{out}}
<pre>========= Generated:
# 1 Rank: 1 with
# 2 Rank: 2 with
# 3 Rank: 3 with
# 4 Rank: 4 with
# 5 Rank: 5 with
# 6 Rank: 6 with
# 7 Rank: 7 with
# 8 Rank: 8 with
# 9 Rank: 9 with
# 10 Rank: 10 with
# 11 Rank: 11 with
# 12 Rank:
# 13 Rank: 13 with
# 14 Rank: 14 with
# 15 Rank: 15 with
# 16 Rank: 16 with
# 17 Rank: 17 with
# 18 Rank: 18 with
# 19 Rank: 19 with
# 20 Rank:
# 21 Rank: 21 with
# 22 Rank: 22 with
# 23 Rank: 23 with
# 24 Rank: 24 with
# 25 Rank: 25 with
# 26 Rank:
# 27 Rank: 27 with
# 28 Rank:
# 29 Rank: 29 with
# 30 Rank: 30 with
# 31 Rank:
# 32 Rank:
# 33 Rank:
# 34 Rank: 34 with
# 35 Rank: 34 T with
# 36 Rank:
# 37 Rank:
# 38 Rank:
# 39 Rank: 39 with
# 40 Rank: 40 with
# 41 Rank:
# 42 Rank: 42 with
# 43 Rank: 43 with
# 44 Rank:
# 45 Rank: 45 with
# 46 Rank: 46 with 27 users: AutoHotkey
# 47 Rank: 46 T with 27 users: Emacs Lisp
# 48 Rank: 46 T with 27 users: PostScript
# 49 Rank: 46 T with 27 users: REXX
# 50 Rank: 50 with 26 users: Perl 6
# 51 Rank: 50 T with 26 users: Sed
# 52 Rank: 52 with 25 users: CSS
# 53 Rank: 52 T with 25 users: Scala
# 54 Rank: 52 T with 25 users: VBScript
========= elapsed: 1.48 seconds =========
========= elapsed: 1.45 seconds =========</pre>
Line 662 ⟶ 805:
Note that this REXX example properly ranks tied languages.
<
parse arg catFID lanFID outFID . /*obtain optional arguments from the CL*/
call init /*initialize some REXX variables. */
Line 776 ⟶ 919:
if #.j==#.jp then do; tR= pR; !tR.j= pR; end
else pR= r
end /*j*/; return</
{{out|output|text= when using the default inputs:}}
<pre style="height:165ex">
Line 1,755 ⟶ 1,898:
=={{header|Stata}}==
<
import delimited categ.html, delim("@") enc("utf-8") clear
keep if ustrpos(v1,"/wiki/Category:") & ustrpos(v1,"_User")
Line 1,786 ⟶ 1,929:
leftalign
list in f/50
save rc_users, replace</
'''Output''' (2019-02-18)
Line 1,853 ⟶ 1,996:
50. | Sed 23 |
+----------------------------+</pre>
=={{header|Wren}}==
{{libheader|libcurl}}
{{libheader|Wren-pattern}}
{{libheader|Wren-fmt}}
An embedded program so we can use the libcurl library.
We can in fact get all the information needed for this task just by parsing the 'Special:Categories' page. Note however that the HTML for this page contains some invisible Unicode right-to-left and left-to-right characters - a well known security risk but apparently harmless here - which need to be allowed for when extracting the number of users.
<syntaxhighlight lang="wren">/* Rosetta_Code_Rank_languages_by_number_of_users.wren */
import "./pattern" for Pattern
import "./fmt" for Fmt
var CURLOPT_URL = 10002
var CURLOPT_FOLLOWLOCATION = 52
var CURLOPT_WRITEFUNCTION = 20011
var CURLOPT_WRITEDATA = 10001
foreign class Buffer {
construct new() {} // C will allocate buffer of a suitable size
foreign value // returns buffer contents as a string
}
foreign class Curl {
construct easyInit() {}
foreign easySetOpt(opt, param)
foreign easyPerform()
foreign easyCleanup()
}
var curl = Curl.easyInit()
var getContent = Fn.new { |url|
var buffer = Buffer.new()
curl.easySetOpt(CURLOPT_URL, url)
curl.easySetOpt(CURLOPT_FOLLOWLOCATION, 1)
curl.easySetOpt(CURLOPT_WRITEFUNCTION, 0) // write function to be supplied by C
curl.easySetOpt(CURLOPT_WRITEDATA, buffer)
curl.easyPerform()
return buffer.value
}
var p = Pattern.new(" User\">[+1^<]<//a>\u200f\u200e ([#13/d] member~s)")
var url = "https://rosettacode.org/w/index.php?title=Special:Categories&limit=5000"
var content = getContent.call(url)
var matches = p.findAll(content)
var over100s = []
for (m in matches) {
var numUsers = Num.fromString(m.capsText[1])
if (numUsers >= 100) {
var language = m.capsText[0][0..-6]
over100s.add([language, numUsers])
}
}
over100s.sort { |a, b| a[1] > b[1] }
System.print("Languages with at least 100 users as at 3 February, 2024:")
var rank = 0
var lastScore = 0
var lastRank = 0
for (i in 0...over100s.count) {
var pair = over100s[i]
var eq = " "
rank = i + 1
if (lastScore == pair[1]) {
eq = "="
rank = lastRank
} else {
lastScore = pair[1]
lastRank = rank
}
Fmt.print("$-2d$s $-11s $d", rank, eq, pair[0], pair[1])
}</syntaxhighlight>
<br>
We now embed this script in the following C program, build and run.
<syntaxhighlight lang="c">/* gcc Rosetta_Code_Rank_languages_by_number_of_users.c -o Rosetta_Code_Rank_languages_by_number_of_users -lcurl -lwren -lm */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include "wren.h"
struct MemoryStruct {
char *memory;
size_t size;
};
/* C <=> Wren interface functions */
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) {
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
char *ptr = realloc(mem->memory, mem->size + realsize + 1);
if(!ptr) {
/* out of memory! */
printf("not enough memory (realloc returned NULL)\n");
return 0;
}
mem->memory = ptr;
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
void C_bufferAllocate(WrenVM* vm) {
struct MemoryStruct *ms = (struct MemoryStruct *)wrenSetSlotNewForeign(vm, 0, 0, sizeof(struct MemoryStruct));
ms->memory = malloc(1);
ms->size = 0;
}
void C_bufferFinalize(void* data) {
struct MemoryStruct *ms = (struct MemoryStruct *)data;
free(ms->memory);
}
void C_curlAllocate(WrenVM* vm) {
CURL** pcurl = (CURL**)wrenSetSlotNewForeign(vm, 0, 0, sizeof(CURL*));
*pcurl = curl_easy_init();
}
void C_value(WrenVM* vm) {
struct MemoryStruct *ms = (struct MemoryStruct *)wrenGetSlotForeign(vm, 0);
wrenSetSlotString(vm, 0, ms->memory);
}
void C_easyPerform(WrenVM* vm) {
CURL* curl = *(CURL**)wrenGetSlotForeign(vm, 0);
curl_easy_perform(curl);
}
void C_easyCleanup(WrenVM* vm) {
CURL* curl = *(CURL**)wrenGetSlotForeign(vm, 0);
curl_easy_cleanup(curl);
}
void C_easySetOpt(WrenVM* vm) {
CURL* curl = *(CURL**)wrenGetSlotForeign(vm, 0);
CURLoption opt = (CURLoption)wrenGetSlotDouble(vm, 1);
if (opt < 10000) {
long lparam = (long)wrenGetSlotDouble(vm, 2);
curl_easy_setopt(curl, opt, lparam);
} else if (opt < 20000) {
if (opt == CURLOPT_WRITEDATA) {
struct MemoryStruct *ms = (struct MemoryStruct *)wrenGetSlotForeign(vm, 2);
curl_easy_setopt(curl, opt, (void *)ms);
} else if (opt == CURLOPT_URL) {
const char *url = wrenGetSlotString(vm, 2);
curl_easy_setopt(curl, opt, url);
}
} else if (opt < 30000) {
if (opt == CURLOPT_WRITEFUNCTION) {
curl_easy_setopt(curl, opt, &WriteMemoryCallback);
}
}
}
WrenForeignClassMethods bindForeignClass(WrenVM* vm, const char* module, const char* className) {
WrenForeignClassMethods methods;
methods.allocate = NULL;
methods.finalize = NULL;
if (strcmp(module, "main") == 0) {
if (strcmp(className, "Buffer") == 0) {
methods.allocate = C_bufferAllocate;
methods.finalize = C_bufferFinalize;
} else if (strcmp(className, "Curl") == 0) {
methods.allocate = C_curlAllocate;
}
}
return methods;
}
WrenForeignMethodFn bindForeignMethod(
WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature) {
if (strcmp(module, "main") == 0) {
if (strcmp(className, "Buffer") == 0) {
if (!isStatic && strcmp(signature, "value") == 0) return C_value;
} else if (strcmp(className, "Curl") == 0) {
if (!isStatic && strcmp(signature, "easySetOpt(_,_)") == 0) return C_easySetOpt;
if (!isStatic && strcmp(signature, "easyPerform()") == 0) return C_easyPerform;
if (!isStatic && strcmp(signature, "easyCleanup()") == 0) return C_easyCleanup;
}
}
return NULL;
}
static void writeFn(WrenVM* vm, const char* text) {
printf("%s", text);
}
void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
switch (errorType) {
case WREN_ERROR_COMPILE:
printf("[%s line %d] [Error] %s\n", module, line, msg);
break;
case WREN_ERROR_STACK_TRACE:
printf("[%s line %d] in %s\n", module, line, msg);
break;
case WREN_ERROR_RUNTIME:
printf("[Runtime Error] %s\n", msg);
break;
}
}
char *readFile(const char *fileName) {
FILE *f = fopen(fileName, "r");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *script = malloc(fsize + 1);
fread(script, 1, fsize, f);
fclose(f);
script[fsize] = 0;
return script;
}
static void loadModuleComplete(WrenVM* vm, const char* module, WrenLoadModuleResult result) {
if( result.source) free((void*)result.source);
}
WrenLoadModuleResult loadModule(WrenVM* vm, const char* name) {
WrenLoadModuleResult result = {0};
if (strcmp(name, "random") != 0 && strcmp(name, "meta") != 0) {
result.onComplete = loadModuleComplete;
char fullName[strlen(name) + 6];
strcpy(fullName, name);
strcat(fullName, ".wren");
result.source = readFile(fullName);
}
return result;
}
int main(int argc, char **argv) {
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.errorFn = &errorFn;
config.bindForeignClassFn = &bindForeignClass;
config.bindForeignMethodFn = &bindForeignMethod;
config.loadModuleFn = &loadModule;
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "Rosetta_Code_Rank_languages_by_number_of_users.wren";
char *script = readFile(fileName);
WrenInterpretResult result = wrenInterpret(vm, module, script);
switch (result) {
case WREN_RESULT_COMPILE_ERROR:
printf("Compile Error!\n");
break;
case WREN_RESULT_RUNTIME_ERROR:
printf("Runtime Error!\n");
break;
case WREN_RESULT_SUCCESS:
break;
}
wrenFreeVM(vm);
free(script);
return 0;
}</syntaxhighlight>
{{out}}
<pre>
Languages with at least 100 users as at 3 February, 2024:
1 C 434
2 Java 326
3 Python 323
4 C++ 306
5 JavaScript 287
6 PHP 188
7 Perl 181
8 SQL 166
9 UNIX Shell 146
10 Pascal 128
10= BASIC 128
12 C sharp 124
13 Haskell 107
14 Ruby 101
</pre>
=={{header|zkl}}==
Uses libraries cURL and YAJL (yet another json library)
<
var [const] CURL=Import("zklCurl"), YAJL=Import("zklYAJL")[0];
Line 1,889 ⟶ 2,320:
println("========== ",Time.Date.prettyDay()," ==========");
foreach n,pgnm in ([1..].zip(allLangs))
{ println("#%3d with %4s users: %s".fmt(n,pgnm.xplode())) }</
{{out}}
<pre>
|