Rosetta Code/Find unimplemented tasks: Difference between revisions
Add Rust implementation |
|||
Line 1,192: | Line 1,192: | ||
</pre> |
</pre> |
||
=={{header|Mathematica}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
Two implementations are considered, the first will use the API to get all the programming tasks, then the ones implemented for a certain language, and take the difference. The other will use the Tasks not implemented page and strip the html. |
Two implementations are considered, the first will use the API to get all the programming tasks, then the ones implemented for a certain language, and take the difference. The other will use the Tasks not implemented page and strip the html. |
||
<lang Mathematica>ClearAll[ImportAll] |
<lang Mathematica>ClearAll[ImportAll] |
Revision as of 10:01, 14 August 2021
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
Given the name of a language on Rosetta Code, find all tasks which are not implemented in that language.
Note: Implementations should allow for fetching more data than can be returned in one request to Rosetta Code.
You'll need to use the Media Wiki API, which you can find out about locally, here, or in Media Wiki's API documentation at, API:Query
Ada
Parsing XML with XMLAda from Adacore <lang Ada>with Aws.Client, Aws.Messages, Aws.Response, Aws.Resources, Aws.Url; with Dom.Readers, Dom.Core, Dom.Core.Documents, Dom.Core.Nodes, Dom.Core.Attrs; with Input_Sources.Strings, Unicode, Unicode.Ces.Utf8; with Ada.Strings.Unbounded, Ada.Text_IO, Ada.Command_Line; with Ada.Containers.Vectors;
use Aws.Client, Aws.Messages, Aws.Response, Aws.Resources, Aws.Url; use Dom.Readers, Dom.Core, Dom.Core.Documents, Dom.Core.Nodes, Dom.Core.Attrs; use Aws, Ada.Strings.Unbounded, Input_Sources.Strings; use Ada.Text_IO, Ada.Command_Line;
procedure Not_Coded is
package Members_Vectors is new Ada.Containers.Vectors ( Index_Type => Positive, Element_Type => Unbounded_String); use Members_Vectors;
All_Tasks, Language_Members : Vector;
procedure Get_Vector (Category : in String; Mbr_Vector : in out Vector) is Reader : Tree_Reader; Doc : Document; List : Node_List; N : Node; A : Attr; Page : Aws.Response.Data; S : Messages.Status_Code;
-- Query has cmlimit value of 100, so we need 5 calls to -- retrieve the complete list of Programming_category Uri_Xml : constant String := "http://rosettacode.org/mw/api.php?action=query&list=categorymembers" & "&format=xml&cmlimit=100&cmtitle=Category:"; Cmcontinue : Unbounded_String := Null_Unbounded_String; begin loop Page := Aws.Client.Get (Uri_Xml & Category & (To_String (Cmcontinue))); S := Response.Status_Code (Page); if S not in Messages.Success then Put_Line ("Unable to retrieve data => Status Code :" & Image (S) & " Reason :" & Reason_Phrase (S)); raise Connection_Error; end if; declare Xml : constant String := Message_Body (Page); Source : String_Input; begin Open (Xml'Unrestricted_Access, Unicode.Ces.Utf8.Utf8_Encoding, Source); Parse (Reader, Source); Close (Source); end; Doc := Get_Tree (Reader); List := Get_Elements_By_Tag_Name (Doc, "cm"); for Index in 1 .. Length (List) loop N := Item (List, Index - 1); A := Get_Named_Item (Attributes (N), "title"); Members_Vectors.Append (Mbr_Vector, To_Unbounded_String (Value (A))); end loop; Free (List); List := Get_Elements_By_Tag_Name (Doc, "query-continue"); if Length (List) = 0 then -- we are done Free (List); Free (Reader); exit; end if; N := First_Child (Item (List, 0)); A := Get_Named_Item (Attributes (N), "cmcontinue"); Cmcontinue := To_Unbounded_String ("&cmcontinue=" & Aws.Url.Encode (Value (A))); Free (List); Free (Reader); end loop; end Get_Vector;
procedure Quick_Diff (From : in out Vector; Substract : in Vector) is Beginning, Position : Extended_Index; begin -- take adavantage that both lists are already sorted Beginning := First_Index (From); for I in First_Index (Substract) .. Last_Index (Substract) loop Position := Find_Index (Container => From, Item => Members_Vectors.Element (Substract, I), Index => Beginning); if not (Position = No_Index) then Delete (From, Position); Beginning := Position; end if; end loop; end Quick_Diff;
begin
if Argument_Count = 0 then Put_Line ("Can't process : No language given!"); return; else Get_Vector (Argument (1), Language_Members); end if;
Get_Vector ("Programming_Tasks", All_Tasks); Quick_Diff (All_Tasks, Language_Members);
for I in First_Index (All_Tasks) .. Last_Index (All_Tasks) loop Put_Line (To_String (Members_Vectors.Element (All_Tasks, I))); end loop; Put_Line ("Numbers of tasks not implemented :=" & Integer'Image (Last_Index ((All_Tasks))));
end Not_Coded;</lang>
AutoHotkey
The GUI overkill version with comments. <lang AutoHotkey>
- NoEnv ; do not resolve environment variables (speed)
- SingleInstance force ; allow only one instance
SetBatchLines, -1 ; set to highest script speed SetControlDelay, 0 ; set delay between control commands to lowest
- additional label, for clarity only
AutoExec:
Gui, Add, DDL, x10 y10 w270 r20 vlngStr ; add drop-down list Gui, Add, Button, x290 y10 gShowLng, Show Unimplemented ; add button Gui, Add, ListView, x10 y36 w400 h300 vcatLst gOnLV, Unimplemented ; add listview Gui, Add, StatusBar, vsbStr, ; add statusbar Gui, Show, , RosettaCode unimplemented list ; show the gui allLng := getList("lng") ; get a list of all available languages selectStr = Select language... ; set selection string for ddl GuiControl, , LngStr, |%selectStr%||%allLng% ; set the ddl to new contents SB_SetIcon("user32.dll", 5) ; change statusbar icon SB_SetText("Done loading languages. Select from menu.") ; change statusbar text
Return ; end of the autoexec section. Script waits for input.
- subroutine for language list in ddl update
ShowLng:
Gui, Submit, NoHide ; refresh all gui variables If (lngStr != selectStr) ; if the current selected language is not the selection string { SB_SetIcon("user32.dll", 2) ; set statusbar icon to exclamation SB_SetText("Loading unimplemented tasks... Please wait.") ; set statusbar text allTsk := getList("tsk") ; get a list of all tasks allThis := getList(lngStr) ; get a list of all done tasks for this language Loop, Parse, allTsk, | ; parse the list of all tasks { If !InStr(allThis,A_LoopField) ; if the current task is not found in the list of all tasks notImpl .= A_LoopField . "|" ; add the current field to the notImpl variable allTskCnt := A_Index ; save the index for final count } StringTrimRight, notImpl, notImpl, 1 ; remove last delimiter LV_Delete() ; emty the listview GuiControl, -Redraw, catLst ; set the listview to not redraw while adding (speed) Loop, Parse, notImpl, | ; parse the list of not implemented tasks { LV_Add("", A_LoopField) ; add them to the listview, field by field notImplCnt := A_Index ; save the index for final count } GuiControl, +Redraw, catLst ; set the listview back to normal SB_SetIcon("user32.dll", 5) ; change statusbar icon to information SB_SetText("There are " . notImplCnt . " of " . allTskCnt . " tasks unimplemented. Double-click task to open in browser.") ; set the statusbar text notImpl = ; empty the notImpl variable notImplCnt = 0 ; set the count back to 0 }
Return
- subroutine for action on listview
OnLV:
If (A_GuiEvent = "DoubleClick") ; if the listview was double-clicked { LV_GetText(rowTxt, A_EventInfo) ; get the text of the clicked row rowTxt := Enc_Uri(rowTxt) ; uri-encode the text StringReplace, rowTxt, rowTxt, `%20, _, All ; replace all space-encodings with underscores Run % "http://rosettacode.org/wiki/" . rowTxt ; run the resulting link in the default browser }
Return
- generic function to gather list
getList(category) {
fileName = temp.xml ; set temp-file name If (category = "lng") ; if the category received is lng { category = Programming_Languages ; set the category fileName = lng.xml ; set temp-file name IfExist, %fileName% ; if the file already exists { FileGetTime, modTime, %fileName% ; get the last modified time EnvSub, modTime, %A_Now%, days ; get the difference between now and last modified time in days If (modTime < 3) ; if the result is less than 3 Goto, GetFileNoDL ; go to function-internal subroutine to parse } SB_SetIcon("user32.dll", 2) ; set statusbar icon SB_SetText("Loading languages... Please wait.") ; set statusbar text } If (category = "tsk") ; if the category received is tsk category = Programming_Tasks ; set the category getFile: ; function-internal subroutine for getting a file and parsing it ; construct the url url := "http://www.rosettacode.org/w/api.php?action=query&list=" . "categorymembers&cmtitle=Category:" . category . "&cmlimit=500&format=xml" . doContinue UrlDownloadToFile, %url%, %fileName% ; download the url getFileNoDL: ; function-internal subroutine for parsing a file FileRead, data, %fileName% ; read file into variable pos = 1 ; set while-loop counter rxp = title="(.*?)" ; set regular expression While (pos := RegExMatch(data, rxp, title, pos)) ; get the contents of the title fields one-by-one { If InStr(title1, "Category:") ; if the contents contain Category: StringTrimLeft, title1, title1, 9 ; remove that from the contents StringReplace, title1, title1, |, `|, All ; escape all containing delimiters title1 := Dec_XML(UTF82Ansi(title1)) ; convert to ansi first and then decode html entities allTitles .= title1 . "|" ; add this title to list pos++ ; increment counter } rxp = cmcontinue="(.*?)" ; set regular expression If RegExMatch(data, rxp, next) ; when found { doContinue = &cmcontinue=%next1% ; set continuation string to add to url Goto getFile ; go to function-internal subroutine to redownload and parse } StringTrimRight, allTitles, allTitles, 1 ; remove last delimiter from result Return allTitles ; return result
}
- function to convert html entities to ansi equivalents
Dec_XML(str) {
Loop If RegexMatch(str, "S)(&#(\d+);)", dec) StringReplace, str, str, %dec1%, % Chr(dec2), All Else If RegexMatch(str, "Si)(&#x([\da-f]+);)", hex) StringReplace, str, str, %hex1%, % Chr("0x" . hex2), All Else Break StringReplace, str, str, , %A_Space%, All StringReplace, str, str, ", ", All StringReplace, str, str, ', ', All StringReplace, str, str, <, <, All StringReplace, str, str, >, >, All StringReplace, str, str, &, &, All return, str
}
- function to uri-encode input string
Enc_Uri(str) {
f = %A_FormatInteger% SetFormat, Integer, Hex If RegExMatch(str, "^\w+:/{0,2}", pr) StringTrimLeft, str, str, StrLen(pr) StringReplace, str, str, `%, `%25, All Loop If RegExMatch(str, "i)[^\w\.~%/:]", char) StringReplace, str, str, %char%, % "%" . SubStr(Asc(char),3), All Else Break SetFormat, Integer, %f% Return, pr . str
}
- function to convert unicode to ansi text
UTF82Ansi(zString) {
Ansi2Unicode(zString, wString, 65001) Unicode2Ansi(wString, sString, 0) Return sString
}
- helper function for unicode to ansi function
Ansi2Unicode(ByRef sString, ByRef wString, CP = 0) {
nSize := DllCall("MultiByteToWideChar", "Uint", CP , "Uint", 0, "Uint", &sString, "int", -1 , "Uint", 0, "int", 0) VarSetCapacity(wString, nSize * 2) DllCall("MultiByteToWideChar" , "Uint", CP, "Uint", 0, "Uint", &sString, "int", -1 , "Uint", &wString, "int", nSize)
}
- helper function for unicode to ansi function
Unicode2Ansi(ByRef wString, ByRef sString, CP = 0) {
nSize := DllCall("WideCharToMultiByte" , "Uint", CP, "Uint", 0, "Uint", &wString, "int", -1 , "Uint", 0, "int", 0, "Uint", 0, "Uint", 0) VarSetCapacity(sString, nSize) DllCall("WideCharToMultiByte" , "Uint", CP, "Uint", 0, "Uint", &wString, "int", -1 , "str", sString, "int", nSize, "Uint", 0, "Uint", 0)
}
- subroutine called when user closes the gui
GuiClose:
ExitApp ; exit the script
Return </lang>
Output
Loads a list of all languages. Pick the language you would like to see the unimplemented tasks of, press the button, double click the selected task to launch in default browser. It will download the languages to file and redownload if older than 3 days (to save unnecessary bandwith).
C#
Using JSON (not parsed, just Regex.)
To help demonstrate paging, the cmlimit parameter has been omitted from the search query so that 10 rows are returned by default
<lang csharp>using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System.Net;
class Program {
static List<string> GetTitlesFromCategory(string category) { string searchQueryFormat = "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:{0}&format=json{1}"; List<string> results = new List<string>(); string cmcontinue = string.Empty;
do { string cmContinueKeyValue;
//append continue variable as needed if (cmcontinue.Length > 0) cmContinueKeyValue = String.Format("&cmcontinue={0}", cmcontinue); else cmContinueKeyValue = String.Empty;
//execute query string query = String.Format(searchQueryFormat, category, cmContinueKeyValue); string content = new WebClient().DownloadString(query);
results.AddRange(new Regex("\"title\":\"(.+?)\"").Matches(content).Cast<Match>().Select(x => x.Groups[1].Value));
//detect if more results are available cmcontinue = Regex.Match(content, @"{""cmcontinue"":""([^""]+)""}", RegexOptions.IgnoreCase).Groups["1"].Value; } while (cmcontinue.Length > 0);
return results; }
static string[] GetUnimplementedTasksFromLanguage(string language) { List<string> alltasks = GetTitlesFromCategory("Programming_Tasks"); List<string> lang = GetTitlesFromCategory(language);
return alltasks.Where(x => !lang.Contains(x)).ToArray(); }
static void Main(string[] args) { string[] unimpl = GetUnimplementedTasksFromLanguage(args[0]);
foreach (string i in unimpl) Console.WriteLine(i); }
}</lang>
Clojure
This uses a couple of core libraries, and a Java method for URL encoding. <lang clojure>(require
'[clojure.xml :as xml] '[clojure.set :as set] '[clojure.string :as string])
(import '[java.net URLEncoder])</lang>
The titles-cont function fetches and parses an XML response, and walks over it extracting titles. It also extracts the cmcontinue value, if present. Returns a pair [titles,cmcontinue]. <lang clojure>(defn titles-cont [url]
(let [docseq (-> url xml/parse xml-seq)] ((juxt #(filter string? %), #(-> (filter map? %) first :cmcontinue)) (for [{:keys [tag attrs content]} docseq :when (#{:cm :query-continue} tag)] (if (= tag :cm) (attrs :title) (-> content first :attrs))))))</lang>
The get-titles function has 1- and 2-argument versions. The former takes the name of a category, composes the appropriate URL query, and calls the 2-argument version. The 2-argument version gets a title list (with possible cmcontinue value), chaining further calls as necessary into the lazy sequence result. <lang clojure>(defn urlencode [s] (URLEncoder/encode s "UTF-8")) (defn param [p v] (str p (urlencode v)))
(defn get-titles
([category] (let [urlbase "http://www.rosettacode.org/w/api.php" params ["action=query" "list=categorymembers" "format=xml" "cmlimit=200" (param "cmtitle=Category:" category)] url (str urlbase "?" (string/join "&" params)] (get-titles url nil))) ([url continue-at] (let [continue-param (if continue-at (param "&cmcontinue=" continue-at)) [titles continue] (titles-cont (str url continue-param))] (if continue (lazy-cat titles (get-titles url continue)) titles))))</lang>
The unimplemented function gets a set of all titles and of language-implemented titles and returns the difference. It uses future in order to do the necessary URL requests in parallel. <lang clojure>(defn unimplemented [lang-name]
(let [title-set #(future (apply sorted-set (get-titles %))) all-titles (title-set "Programming_Tasks") lang-titles (title-set lang-name)] (seq (set/difference @all-titles @lang-titles))))
(let [titles (unimplemented "Clojure")]
(doseq [title titles] (println title)) (println "count: " (count titles)))
(shutdown-agents)</lang>
E
Using JSON.
<lang e>#!/usr/bin/env rune
- NOTE: This program will not work in released E, because TermL is an
- imperfect superset of JSON in that version: it does not accept "\/".
- If you build E from the latest source in SVN then it will work.
- Usage: rosettacode-cat-subtract.e [<lang e>]
- Prints a list of tasks which have not been completed in the language.
- If unspecified, the default language is E.
pragma.syntax("0.9") pragma.enable("accumulator")
def termParser := <import:org.quasiliteral.term.makeTermParser> def jURLEncoder := <unsafe:java.net.makeURLEncoder>
def urlEncode(text) {
return jURLEncoder.encode(text, "UTF-8")
}
/** Convert JSON-as-term-tree to the corresponding natural E data structures. */ def jsonTermToData(term) {
switch (term) {
# JSON object to E map match term`{@assocs*}` { return accum [].asMap() for term`@{key :String}: @valueJson` in assocs { _.with(key, jsonTermToData(valueJson)) } }
# JSON array to E list match term`[@elements*]` { return accum [] for elem in elements { _.with(jsonTermToData(elem)) } } # Literals just need to be coerced match lit :any[String, int, float64] { return lit } # Doesn't support true/false/null, but we don't need that for this application. }
}
def fetchCategoryAccum(name, membersSoFar :Set, extraArgs) {
stderr.println(`Fetching Category:$name $extraArgs...`) def categoryAPIResource := <http>[`//rosettacode.org/w/api.php?` + `action=query&list=categorymembers&cmtitle=Category:${urlEncode(name)}&` + `format=json&cmlimit=500&cmprop=title$extraArgs`] def members := when (def responseJSON := categoryAPIResource <- getTwine()) -> { # stderr.println(`Fetched Category:$name $extraArgs, parsing...`) def response := jsonTermToData(termParser(responseJSON))
# stderr.println(`Parsed Category:$name $extraArgs response, extracting data...`) def [ "query" => ["categorymembers" => records], "query-continue" => continueData := null ] := response def members := accum membersSoFar for record in records { _.with(record["title"]) } switch (continueData) { match ==null { stderr.println(`Got all ${members.size()} for Category:$name.`) members } match ["categorymembers" => ["cmcontinue" => continueParam]] { stderr.println(`Fetched ${members.size()} members for Category:$name...`) fetchCategoryAccum(name, members, `&cmcontinue=` + urlEncode(continueParam)) } } } catch p { throw(p) } return members
}
def fetchCategory(name) {
return fetchCategoryAccum(name, [].asSet(), "")
}
- Interpret program arguments
def lang := switch (interp.getArgs()) {
match [lang] { lang } match [] { "E" }
}
- Fetch categories
when (def allTasks := fetchCategory("Programming_Tasks"),
def doneTasks := fetchCategory(lang), def omitTasks := fetchCategory(lang + "/Omit") ) -> { # Compute difference and report def notDoneTasks := allTasks &! (doneTasks | omitTasks) println() println("\n".rjoin(notDoneTasks.getElements().sort()))
} catch p {
# Whoops, something went wrong stderr.println(`$p${p.eStack()}`)
}</lang>
Erlang
init_http/0 is used by many tasks. rosetta_code_list_of/1 is used by Rosetta_Code/Rank_languages_by_popularity <lang Erlang> -module( find_unimplemented_tasks ). -include_lib( "xmerl/include/xmerl.hrl" ).
-export( [init_http/0, per_language/1, rosetta_code_list_of/1] ).
init_http() -> application:start( inets ).
per_language( Language ) -> ok = init_http(), Tasks = rosetta_code_list_of( "Programming_Tasks" ), Uninplemented = Tasks -- rosetta_code_list_of( Language ), io:fwrite( "Unimplemented total: ~p~n", [erlang:length(Uninplemented)] ), [io:fwrite("~p~n", [X]) || X <- Uninplemented].
rosetta_code_list_of( Category ) -> URL = "http://rosettacode.org/mw/api.php?action=query&list=categorymembers&cmlimit=500&format=xml&cmtitle=Category:" ++ Category, title_contents( URL, "", [] ).
title_contents( URL, Continue, Acc ) -> {ok, {{_HTTP,200,"OK"}, _Headers, Body}} = httpc:request( URL ++ Continue ), {XML, _} = xmerl_scan:string( Body ), News = xml_selection( "title", XML ), New_continue = title_contents_url_continue( xml_selection("cmcontinue", XML) ), title_contents_continue( URL, New_continue, Acc ++ News ).
title_contents_continue( _URL, "", Acc ) -> Acc; title_contents_continue( URL, Continue, Acc ) -> title_contents( URL, Continue, Acc ).
title_contents_url_continue( [] ) -> ""; title_contents_url_continue( [Continue | _] ) -> "&cmcontinue=" ++ Continue.
xml_selection( Selection, XML ) -> [lists:map( fun xml_8211/1, X) || #xmlAttribute{value=X} <- xmerl_xpath:string("//@" ++ Selection, XML)].
xml_8211( 8211 ) -> $-; xml_8211( 924 ) -> $\s; xml_8211( 1050 ) -> $\s; xml_8211( 1052 ) -> $\s; xml_8211( Character ) -> Character. </lang>
- Output:
25> find_unimplemented_tasks:per_language("Erlang"). Unimplemented total: 307 "24 game/Solve" "Abstract type" "Active Directory/Search for a user" "Add a variable to a class instance at runtime" "Address of a variable" . . . "Yahoo! search interface" "Yin and yang" "Zeckendorf arithmetic" "Zeckendorf number representation" "Zhang-Suen thinning algorithm"
Go
XML, stepping through the elements. <lang go>package main
import (
"encoding/xml" "fmt" "io" "net/http" "net/url"
)
const language = "Go"
var baseQuery = "http://rosettacode.org/mw/api.php?action=query" +
"&format=xml&list=categorymembers&cmlimit=100"
func req(u string, foundCm func(string)) string {
resp, err := http.Get(u) if err != nil { fmt.Println(err) // connection or request fail return "" } defer resp.Body.Close() for p := xml.NewDecoder(resp.Body); ; { t, err := p.RawToken() switch s, ok := t.(xml.StartElement); { case err == io.EOF: return "" case err != nil: fmt.Println(err) return "" case !ok: continue case s.Name.Local == "cm": for _, a := range s.Attr { if a.Name.Local == "title" { foundCm(a.Value) } } case s.Name.Local == "categorymembers" && len(s.Attr) > 0 && s.Attr[0].Name.Local == "cmcontinue": return url.QueryEscape(s.Attr[0].Value) } } return ""
}
func main() {
// get language members, store in a map langMap := make(map[string]bool) storeLang := func(cm string) { langMap[cm] = true } languageQuery := baseQuery + "&cmtitle=Category:" + language continueAt := req(languageQuery, storeLang) for continueAt > "" { continueAt = req(languageQuery+"&cmcontinue="+continueAt, storeLang) }
// a quick check to avoid long output if len(langMap) == 0 { fmt.Println("no tasks implemented for", language) return }
// get tasks, print as we go along printUnImp := func(cm string) { if !langMap[cm] { fmt.Println(cm) } } taskQuery := baseQuery + "&cmtitle=Category:Programming_Tasks" continueAt = req(taskQuery, printUnImp) for continueAt > "" { continueAt = req(taskQuery+"&cmcontinue="+continueAt, printUnImp) }
}</lang>
Haskell
from HackageDB
<lang haskell>import Network.Browser import Network.HTTP import Network.URI import Data.List import Data.Maybe import Text.XML.Light import Control.Arrow import Data.Char
getRespons url = do
rsp <- Network.Browser.browse $ do setAllowRedirects True setOutHandler $ const (return ()) -- quiet request $ getRequest url return $ rspBody $ snd rsp
replaceWithSpace c = (\x -> if c==x then ' ' else x)
encl = chr 34
unimpTasks lang = do
allTasks <- getRespons "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml" impl <- getRespons ( "http://rosettacode.org/json/isb/" ++ lang ++ ".json") let langxx = map (map(replaceWithSpace '_')) $ filter (/=",") $ words $ map (replaceWithSpace encl ) $ init $ drop 1 impl xml = onlyElems $ parseXML allTasks allxx = concatMap (map (fromJust.findAttr (unqual "title")). filterElementsName (== unqual "cm")) xml mapM_ putStrLn $ sort $ allxx \\ langxx</lang>
With only standard libraries <lang haskell>import Network.HTTP import Data.Text (splitOn, pack, unpack) import Data.List
getTasks :: String -> IO [String] getTasks url = do
resp <- simpleHTTP (getRequest url) body <- getResponseBody resp return $ tail $ map (unpack . head . splitOn (pack "\"}")) $ splitOn (pack "\"title\":\"") (pack body)
main :: String -> IO () main lang = do
implTasks <- getTasks $ "http://rosettacode.org/mw/api.php?action=query&list=categorymembers&cmtitle=Category:" ++ lang ++ "&format=json&cmlimit=500" allTasks <- getTasks "http://rosettacode.org/mw/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&format=json&cmlimit=500" mapM_ putStrLn $ allTasks \\ implTasks</lang>
Icon and Unicon
The following code only works in Unicon.
<lang unicon>$define RCINDEX "http://rosettacode.org/mw/api.php?format=xml&action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500" $define RCTASK "http://rosettacode.org/mw/index.php?action=raw&title=" $define RCUA "User-Agent: Unicon Rosetta 0.1" $define RCXUA "X-Unicon: http://unicon.org/" $define TASKTOT "* Total Tasks *" $define TOTTOT "* Total Headers*"
link strings link hexcvt
procedure main(A) # simple single threaded read all at once implementation
lang := \A[1] | "Unicon" write("Unimplemented tasks for ",lang," as of ",&date) every task := taskNames() do { if lang == languages(task) then next write(task) }
end
- Generate task names
procedure taskNames()
continue := "" while \(txt := ReadURL(RCINDEX||continue)) do { txt ? { while tab(find("<cm ") & find(s :="title=\"")+*s) do suspend tab(find("\""))\1 if tab(find("cmcontinue=")) then { continue := "&"||tab(upto(' \t')) } else break } }
end
- Generate language headers in a task
procedure languages(task)
static WS initial WS := ' \t' page := ReadURL(RCTASK||CleanURI(task)) page ? while (tab(find("\n==")),tab(many(WS))|"",tab(find("{{"))) do { header := tab(find("==")) header ? { while tab(find("[[:Category:|]] [[Category:]] Titles = {XPath Doc [api query categorymembers cm {Attribute title}]} in case {XPath Doc [api 'query-continue' categorymembers {Attribute cmcontinue}]} of nil then Titles [] [NewCMContinueAtom] then NewCMContinue = {PercentEncode {Atom.toString NewCMContinueAtom}} in {Append Titles {Loop "&cmcontinue="#NewCMContinue}} end end in {Loop nil} end
%% XPath emulation fun {XPath Doc Path} P|Pr = Path in Doc.name = P %% assert {FoldL Pr XPathStep [Doc]} end
Nothing = {NewName} fun {NotNothing X} X \= Nothing end fun {XPathStep Elements P} if {Atom.is P} then {FilteredChildren Elements P} elseif {Procedure.is P} then {Filter {Map Elements P} NotNothing} end end %% A flat list of all Type-children of all Elements. fun {FilteredChildren Elements Type} {Flatten {Map Elements fun {$ E} {Filter E.children fun {$ X} case X of element(name:!Type ...) then true else false end end} end}} end fun {Attribute Attr} fun {$ Element} case {Filter Element.attributes fun {$ A} A.name == Attr end} of [A] then A.value else Nothing end end end
%% GetPage Client = {New HTTPClient.urlGET init(inPrms(toFile:false toStrm:true) _)} fun {GetPage RawUrl} Url = {VirtualString.toString RawUrl} OutParams in {Client getService(Url ?OutParams ?_)} OutParams.sOut end fun {PercentEncode Xs} case Xs of nil then nil [] X|Xr then if {Char.isDigit X} orelse {Member X [&- &_ &. &~]} orelse X >= &a andthen X =< &z orelse X >= &z andthen X =< &Z then X|{PercentEncode Xr} else {Append &%|{ToHex2 X} {PercentEncode Xr}} end end end fun {ToHex2 X} [{ToHex1 X div 16} {ToHex1 X mod 16}] end fun {ToHex1 X} if X >= 0 andthen X =< 9 then &0 + X elseif X >= 10 andthen X =< 15 then &A + X - 10 end end
%% Parse local Parser = {New XMLParser.parser init} in fun {Parse Xs} {Parser parseVS(Xs $)} end end
fun {ListDiff Xs Ys} {FoldL Ys List.subtract Xs} end
in
%% show tasks not implemented in Oz {ForAll {FindUnimplementedTasks "Oz"} System.showInfo}</lang>
Perl
<lang perl>use LWP::UserAgent;
my $ua = LWP::UserAgent->new; $ua->agent();
sub enc { join , map {sprintf '%%%02x', ord} split //, shift } sub get { $ua->request( HTTP::Request->new( GET => shift))->content }
sub tasks {
my($category) = shift; my $fmt = 'http://www.rosettacode.org/mw/api.php?' . 'action=query&generator=categorymembers&gcmtitle=Category:%s&gcmlimit=500&format=json&rawcontinue='; my @tasks; my $json = get(sprintf $fmt, $category); while (1) { push @tasks, $json =~ /"title":"(.+?)"\}/g; $json =~ /"gcmcontinue":"(.+?)"\}/ or last; $json = get(sprintf $fmt . '&gcmcontinue=%s', $category, enc $1); } @tasks;
}
my %language = map {$_, 1} tasks shift || 'perl'; $language{$_} or print "$_\n" foreach tasks('Programming_Tasks'), tasks('Draft_Programming_Tasks');</lang>
See also: User:ImplSearchBot/Code
Phix
Note that Rosetta_Code/Tasks_without_examples#Phix with summary=true and output_html=false does much that same via web scraping, whereas this uses the web api.
<lang Phix>-- demo\rosetta\Find_unimplemented_tasks.exw constant language = "Phix",
base_query = "http://rosettacode.org/mw/api.php?action=query"& "&format=xml&list=categorymembers&cmlimit=100"
include builtins\libcurl.e atom curl = NULL atom pErrorBuffer include builtins\xml.e
function req(string url, integer rid)
if curl=NULL then curl_global_init() curl = curl_easy_init() pErrorBuffer = allocate(CURL_ERROR_SIZE) curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, pErrorBuffer) end if curl_easy_setopt(curl, CURLOPT_URL, url) object res = curl_easy_perform_ex(curl) if integer(res) then string error = sprintf("%d [%s]",{res,peek_string(pErrorBuffer)}) crash("Download error: %s\n",{error}) end if if not string(res) then ?9/0 end if object xml = xml_parse(res)[XML_CONTENTS] res = xml_get_nodes(xml,"continue") res = iff(res=={}?"":xml_get_attribute(res[1],"cmcontinue")) xml = xml_get_nodes(xml,"query")[1] xml = xml_get_nodes(xml,"categorymembers")[1] xml = xml_get_nodes(xml,"cm") for i=1 to length(xml) do call_proc(rid,{xml_get_attribute(xml[i],"title")}) end for return res
end function
sequence languages = {} procedure store_lang(string language)
languages = append(languages,language)
end procedure constant r_store_lang = routine_id("store_lang")
integer unimplemented_count = 0 procedure print_unimplemented(string language)
if not find(language,languages) then printf(1,"%s\n",{language}) unimplemented_count += 1 end if
end procedure constant r_print = routine_id("print_unimplemented")
procedure main()
-- get and store language members string lang_query := base_query & "&cmtitle=Category:" & language, continue_at := req(lang_query, r_store_lang) while continue_at!="" do continue_at = req(lang_query&"&cmcontinue="&continue_at, r_store_lang) end while -- a quick check to avoid long output if length(languages)==0 then printf(1,"no tasks implemented for %s\n", {language}) return end if -- get tasks, print as we go along string task_query := base_query & "&cmtitle=Category:Programming_Tasks" continue_at = req(task_query, r_print) while continue_at!="" do continue_at = req(task_query&"&cmcontinue="&continue_at, r_print) end while printf(1,"%d unimplemented tasks found for %s.\n",{unimplemented_count,language})
end procedure main()</lang>
- Output:
Abstract type Active Directory/Connect Active Directory/Search for a user ... Yahoo! search interface 78 unimplemented tasks found for Phix.
PicoLisp
<lang PicoLisp>(load "@lib/http.l" "@lib/xm.l")
(de rosettaCategory (Cat)
(let (Cont NIL Xml) (make (loop (client "rosettacode.org" 80 (pack "mw/api.php?action=query&list=categorymembers&cmtitle=Category:" Cat "&cmlimit=200&format=xml" Cont ) (while (line)) (setq Xml (and (xml?) (xml))) ) (NIL Xml) (for M (body Xml 'query 'categorymembers) (link (attr M 'title)) ) (NIL (attr Xml 'query-continue' categorymembers 'cmcontinue)) (setq Cont (pack "&cmcontinue=" @)) ) ) ) )
(de unimplemented (Task)
(diff (rosettaCategory "Programming_Tasks") (rosettaCategory Task) ) )</lang>
PowerShell
I don't think this script follows the spirit of the task, but it works. <lang PowerShell> function Find-UnimplementedTask {
[CmdletBinding()] [OutputType([string[]])] Param ( [Parameter(Mandatory=$true, Position=0)] [string] $Language )
$url = "http://rosettacode.org/wiki/Reports:Tasks_not_implemented_in_$Language" $web = Invoke-WebRequest $url $unimplemented = 1
[string[]](($web.AllElements | Where-Object {$_.class -eq "mw-content-ltr"})[$unimplemented].outerText -split "`r`n" | Select-String -Pattern "[^0-9A-Z]$" -CaseSensitive)
} </lang> <lang PowerShell> $tasks = Find-UnimplementedTask -Language PowerShell
$tasks[0..5],".`n.`n.",$tasks[-6..-1] Write-Host "`nTotal unimplemented Tasks: $($tasks.Count)" </lang>
- Output:
15 Puzzle Game 2048 24 game/Solve 4-rings or 4-squares puzzle 9 billion names of God the integer AKS test for primes . . . Xiaolin Wu's line algorithm Yahoo! search interface Yin and yang Zebra puzzle Zeckendorf arithmetic Zhang-Suen thinning algorithm Total unimplemented Tasks: 388
Python
<lang python>""" Given the name of a language on Rosetta Code, finds all tasks which are not implemented in that language. """ from operator import attrgetter from typing import Iterator
import mwclient
URL = 'www.rosettacode.org' API_PATH = '/mw/'
def unimplemented_tasks(language: str,
*, url: str, api_path: str) -> Iterator[str]: """Yields all unimplemented tasks for a specified language""" site = mwclient.Site(url, path=api_path) all_tasks = site.categories['Programming Tasks'] language_tasks = site.categories[language] name = attrgetter('name') all_tasks_names = map(name, all_tasks) language_tasks_names = set(map(name, language_tasks)) for task in all_tasks_names: if task not in language_tasks_names: yield task
if __name__ == '__main__':
tasks = unimplemented_tasks('Python', url=URL, api_path=API_PATH) print(*tasks, sep='\n')
</lang>
<lang python>""" Given the name of a language on Rosetta Code, finds all tasks which are not implemented in that language. """ from functools import partial from operator import itemgetter from typing import (Dict,
Iterator, Union)
import requests
URL = 'http://www.rosettacode.org/mw/api.php' REQUEST_PARAMETERS = dict(action='query',
list='categorymembers', cmlimit=500, rawcontinue=True, format='json')
def unimplemented_tasks(language: str,
*, url: str, request_params: Dict[str, Union[str, int, bool]] ) -> Iterator[str]: """Yields all unimplemented tasks for a specified language""" with requests.Session() as session: tasks = partial(tasks_titles, session=session, url=url, **request_params) all_tasks = tasks(cmtitle='Category:Programming_Tasks') language_tasks = set(tasks(cmtitle=f'Category:{language}')) for task in all_tasks: if task not in language_tasks: yield task
def tasks_titles(*,
session: requests.Session, url: str, **params: Union[str, int, bool]) -> Iterator[str]: """Yields tasks names for a specified category""" while True: request = session.get(url, params=params) data = request.json() yield from map(itemgetter('title'), data['query']['categorymembers']) query_continue = data.get('query-continue') if query_continue is None: return params.update(query_continue['categorymembers'])
if __name__ == '__main__':
tasks = unimplemented_tasks('Python', url=URL, request_params=REQUEST_PARAMETERS) print(*tasks, sep='\n')
</lang>
<lang python>import xml.dom.minidom import urllib, sys
def findrc(category):
name = "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:%s&cmlimit=500&format=xml" % urllib.quote(category) cmcontinue, titles = , [] while True: u = urllib.urlopen(name + cmcontinue) xmldata = u.read() u.close() x = xml.dom.minidom.parseString(xmldata) titles += [i.getAttribute("title") for i in x.getElementsByTagName("cm")] cmcontinue = filter( None, (urllib.quote(i.getAttribute("cmcontinue")) for i in x.getElementsByTagName("categorymembers")) ) if cmcontinue: cmcontinue = '&cmcontinue=' + cmcontinue[0] else: break return titles
alltasks = findrc("Programming_Tasks") lang = findrc(sys.argv[1])
for i in [i for i in alltasks if i not in lang]:
print i</lang>
R
<lang R>library(XML) find.unimplemented.tasks <- function(lang="R"){ PT <- xmlInternalTreeParse( paste("http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml",sep="") ) PT.nodes <- getNodeSet(PT,"//cm") PT.titles = as.character( sapply(PT.nodes, xmlGetAttr, "title") ) language <- xmlInternalTreeParse( paste("http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:", lang, "&cmlimit=500&format=xml",sep="") ) lang.nodes <- getNodeSet(language,"//cm") lang.titles = as.character( sapply(lang.nodes, xmlGetAttr, "title") ) unimplemented <- setdiff(PT.titles, lang.titles) unimplemented }
- Usage
find.unimplemented.tasks(lang="Python") langs <- c("R","python","perl") sapply(langs, find.unimplemented.tasks) # fetching data for multiple languages</lang>
Racket
<lang Racket>
- lang racket
(require net/url net/uri-codec json (only-in racket/dict [dict-ref ref]))
(define (RC-get verb params)
((compose1 get-pure-port string->url format) "http://rosettacode.org/mw/~a.php?~a" verb (alist->form-urlencoded params)))
(define (get-category catname)
(let loop ([c #f]) (define t ((compose1 read-json RC-get) 'api `([action . "query"] [format . "json"] [list . "categorymembers"] [cmtitle . ,(format "Category:~a" catname)] [cmcontinue . ,(and c (ref c 'cmcontinue))] [cmlimit . "500"]))) (define (c-m key) (ref (ref t key '()) 'categorymembers #f)) (append (for/list ([page (c-m 'query)]) (ref page 'title)) (cond [(c-m 'query-continue) => loop] [else '()]))))
- The above is the required "library" code, same as the "Rosetta
- Code/Count" entry
(define (show-unimplemented lang)
(for-each displayln (remove* (get-category lang) (get-category 'Programming_Tasks))))
(show-unimplemented 'Racket) ; see all of the Racket entries </lang>
Raku
(formerly Perl 6)
<lang perl6>use HTTP::UserAgent; use URI::Escape; use JSON::Fast; use Sort::Naturally;
unit sub MAIN( Str :$lang = 'Raku' );
my $client = HTTP::UserAgent.new; my $url = 'http://rosettacode.org/mw';
my @total; my @impl;
@total.append: .&get-cat for 'Programming_Tasks', 'Draft_Programming_Tasks'; @impl = get-cat $lang;
say "Unimplemented tasks in $lang:"; .say for (@total (-) @impl).keys.sort: &naturally;
sub get-cat ($category) {
flat mediawiki-query( $url, 'pages', :generator<categorymembers>, :gcmtitle("Category:$category"), :gcmlimit<350>, :rawcontinue(), :prop<title> ).map({ .<title> });
}
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) { %fields.map({ "{.key}={uri-escape .value}" }).join("&") }</lang>
Ring
<lang ring>
- Project: Rosetta Code/Find unimplemented tasks
load "stdlib.ring" ros= download("http://rosettacode.org/wiki/Category:Programming_Tasks") lang = "Ring" pos = 1 num = 0 totalros = 0 rosname = "" rostitle = "" see "Tasks not implemented in " + lang + " language:" + nl for n = 1 to len(ros)
nr = searchstring(ros,'
",sn) rosname = substr(ros,nr2+2,nr3-nr2-2) return sn func searchtitle(sn) st = searchstring(ros,"title=",sn) rostitle = substr(ros,sn+19,st-sn-21) rostitle = "rosettacode.org/wiki/" + rostitle rostitle = download(rostitle) s = substr(rostitle,lang) if s = 0 num = num + 1 totalros = totalros + 1 see "" + num + ". " + rosname + nl ok return sn func count(cstring,dstring) sum = 0 while substr(cstring,dstring) > 0 sum = sum + 1 cstring = substr(cstring,substr(cstring,dstring)+len(string(sum))) end return sum </lang> Output:
Tasks not implemented in Ring language: 1. 15 puzzle solver 2. 2048 3. 24 game/Solve 4. 9 billion names of God the integer 5. Abstract type 6. Active Directory/Search for a user 7. Address of a variable 8. AKS test for primes 9. Align columns 10. Amb ...... 343. Xiaolin Wu's line algorithm 344. XML/DOM serialization 345. XML/Input 346. XML/Output 347. XML/XPath 348. Y combinator 349. Yahoo! search interface 350. Yin and yang 351. Zeckendorf arithmetic 352. Zhang-Suen thinning algorithm Total: 352 examples.
Ruby
Finds tasks that are either not implemented or omitted. Sorts by task creation time.
Uses the RosettaCode
module from Count programming examples#Ruby
<lang ruby>require 'rosettacode'
require 'time'
module RosettaCode
def self.get_unimplemented(lang) programming_tasks = [] category_members("Programming_Tasks") {|task| programming_tasks << task}
lang_tasks = [] category_members(lang) {|task| lang_tasks << task}
lang_tasks_omit = [] category_members("#{lang}/Omit") {|task| lang_tasks_omit << task}
[programming_tasks - lang_tasks, lang_tasks_omit] end
def self.created_time(title) url = get_api_url({ "action" => "query", "titles" => title, "format" => "xml", "rvlimit" => 500, "prop" => "revisions", "rvprop" => "timestamp" }) doc = REXML::Document.new open(url) REXML::XPath.each(doc, "//rev").collect do |node| Time.parse( node.attribute("timestamp").value ) end.min end
end
puts Time.now lang = ARGV[0] || "Ruby" unimplemented, omitted = RosettaCode.get_unimplemented(lang) unimplemented.collect {|title| [title, RosettaCode.created_time(title)]} .
sort_by {|e| e[1]} . each do |title, date| puts "%s %6s %s" % [ date.strftime("%Y-%m-%d"), omitted.include?(title) ? "[omit]" : "" , title ] end
</lang>
Output for Ruby
2010-04-05 11:08:07 -0500 2007-01-14 Table creation 2007-01-25 [omit] Pointers and references 2007-02-04 SQL-based authentication 2007-02-09 Metered concurrency 2007-02-27 [omit] Address of a variable 2007-02-27 [omit] Variable size/Set 2007-02-27 Variable size/Get 2007-06-08 OpenGL 2007-06-08 HTTPS/Authenticated 2007-11-06 Pattern matching 2007-11-08 [omit] Parametric polymorphism 2007-11-13 Special characters 2007-12-11 Arithmetic evaluation 2007-12-21 [omit] Proof 2007-12-24 Plot coordinate pairs 2007-12-24 Polynomial regression 2007-12-24 Compare sorting algorithms' performance 2008-03-27 Dragon curve 2008-03-28 Formal power series 2008-09-11 RCRPG 2008-11-02 Active object 2008-11-13 Window creation/X11 2008-12-05 [omit] Constrained genericity 2009-02-17 Rendezvous 2009-03-22 Arena storage pool 2009-05-23 Ray-casting algorithm 2009-05-26 [omit] Memory allocation 2009-05-26 Simulate input/Mouse 2009-05-27 Mouse position 2009-05-27 Keyboard macros 2009-05-27 Window management 2009-05-27 Color of a screen pixel 2009-06-01 HTTPS/Client-authenticated 2009-06-02 Simulate input/Keyboard 2009-06-08 [omit] Create an object at a given address 2009-06-10 Events 2009-06-10 Scope modifiers 2009-08-09 Verify distribution uniformity/Chi-squared test 2009-08-11 Call a function from a foreign language 2009-08-12 Safe addition 2009-12-05 Rate counter 2010-01-02 Loading Animated 3D Data 2010-01-06 Catmull–Clark subdivision surface 2010-01-21 Hough transform 2010-01-25 Compile-time calculation 2010-02-14 Knapsack problem/Bounded 2010-02-21 Deconvolution/1D 2010-02-23 Deconvolution/2D+ 2010-02-24 Knapsack problem/Continuous 2010-03-23 Sutherland-Hodgman polygon clipping 2010-03-23 Find Common Directory Path
Run BASIC
Find tasks not implemented. Select Language from DropDown and click [GO] or [Exit]. <lang runbasic>WordWrap$ = "style='white-space: pre-wrap;white-space: -moz-pre-wrap;white-space: -pre-wrap;white-space: -o-pre-wrap;word-wrap: break-word'" a$ = httpGet$("http://rosettacode.org/wiki/Category:Programming_Languages") a$ = word$(a$,2,"mw-subcategories")
a$ = word$(a$,1,"")
i = instr(a$,"/wiki/Category:")
html " Select language from list
"
html "<SELECT name='lang'>"
while i <> 0
j = instr(a$,""" title=""Category:",i) lang$ = mid$(a$,i+15,j-i-15) k = instr(a$,""">",j + 18) langName$ = mid$(a$,j + 18,k-(j+18)) count = count + 1 html "<option value='";lang$;"'>";langName$;"</option>" i = instr(a$,"/wiki/Category:",k)
wend html "</select>"
html "
Number of Languages:";count;"
"
button #go,"GO", [go]
html " "
button #ex, "Exit", [exit]
wait
[go]
cls
lang$ = #request get$("lang")
h$ = "http://rosettacode.org/wiki/Reports:Tasks_not_implemented_in_";lang$
a$ = httpGet$(h$)
a$ = word$(a$,3,"mw-content-ltr")
html "
i = instr(a$,"<a href=""/wiki/",i+7)
wend
html "";mid$(a$,i+7,j-(i+7));" |
"
print "Total unImplemented Tasks:";c [exit] end</lang>
24 game/Solve | Abstract type | Accumulator factory | Active Directory/Connect | Active Directory/Search for a user |
Arena storage pool | Arithmetic/Rational | Arithmetic evaluation | Average loop length | Averages/Mean angle |
Averages/Mean time of day | Bitcoin/address validation | Bitmap/PPM conversion through a pipe | Bitmap/Read an image through a pipe | Break OO privacy |
CRC-32 | CSV to HTML translation | Calendar | Calendar - for "real" programmers | Call a function |
Call an object method | Canny edge detector | Carmichael 3 strong pseudoprimes, or Miller Rabin's nemesis | Catmull–Clark subdivision surface | Chat server |
Check Machin-like formulas | Cholesky decomposition | Colour pinstripe/Printer | Compare sorting algorithms' performance | Constrained genericity |
Continued fraction | Continued fraction arithmetic/Continued fraction r2cf(Rational N) | Continued fraction arithmetic/G(matrix NG, Contined Fraction N) | Continued fraction arithmetic/G(matrix NG, Contined Fraction N1, Contined Fraction N2) | Count the coins |
Zebra puzzle | Zeckendorf number representation |
Total unImplemented Tasks:177
Rust
<lang rust> use std::collections::{BTreeMap, HashSet};
use reqwest::Url; use serde::Deserialize; use serde_json::Value;
/// A Rosetta Code task.
- [derive(Clone, PartialEq, Eq, Hash, Debug, Deserialize)]
pub struct Task {
/// The ID of the page containing the task in the MediaWiki API. #[serde(rename = "pageid")] pub id: u64,
/// The human-readable title of the task. pub title: String,
}
/// Encapsulates errors that might occur during JSON parsing.
- [derive(Debug)]
enum TaskParseError {
/// Something went wrong with the HTTP request to the API. Http(reqwest::Error),
/// There was a problem parsing the API response into JSON. Json(serde_json::Error),
/// The response JSON contained unexpected keys or values. UnexpectedFormat,
}
impl From<serde_json::Error> for TaskParseError {
fn from(err: serde_json::Error) -> Self { TaskParseError::Json(err) }
}
impl From<reqwest::Error> for TaskParseError {
fn from(err: reqwest::Error) -> Self { TaskParseError::Http(err) }
}
/// Represents a category of pages on Rosetta Code, such as "Rust". struct Category {
name: String, continue_params: Option<BTreeMap<String, String>>,
}
impl Category {
fn new(name: &str) -> Category { let mut continue_params = BTreeMap::new(); continue_params.insert("continue".to_owned(), "".to_owned());
Category { name: name.to_owned(), continue_params: Some(continue_params), } }
}
/// Sends a request to Rosetta Code through the MediaWiki API. If successful, returns the response /// as a JSON object. fn query_api(
category_name: &str, continue_params: &BTreeMap<String, String>,
) -> Result<Value, TaskParseError> {
let mut url = Url::parse("http://rosettacode.org/mw/api.php").expect("invalid URL"); url.query_pairs_mut() .append_pair("action", "query") .append_pair("list", "categorymembers") .append_pair("cmtitle", &format!("Category:{}", category_name)) .append_pair("cmlimit", "500") .append_pair("format", "json") .extend_pairs(continue_params);
Ok(reqwest::blocking::get(url)?.json()?)
}
/// Given a JSON object, parses the task information from the MediaWiki API response. fn parse_tasks(json: &Value) -> Result<Vec<Task>, TaskParseError> {
let tasks_json = json .pointer("/query/categorymembers") .and_then(Value::as_array) .ok_or(TaskParseError::UnexpectedFormat)?;
tasks_json .iter() .map(|json| Task::deserialize(json).map_err(From::from)) .collect()
}
impl Iterator for Category {
type Item = Vec<Task>;
fn next(&mut self) -> Option<Self::Item> { self.continue_params.as_ref()?;
query_api(&self.name, self.continue_params.as_ref()?) .and_then(|result| { // If there are more pages of results to request, save them for the next iteration. self.continue_params = result .get("continue") .and_then(Value::as_object) .map(|continue_params| { continue_params .iter() .map(|(key, value)| { (key.to_owned(), value.as_str().unwrap().to_owned()) }) .collect() });
parse_tasks(&result) }) .map_err(|err| println!("Error parsing response: {:?}", err)) .ok() }
}
pub fn all_tasks() -> Vec<Task> {
Category::new("Programming Tasks").flatten().collect()
}
pub fn unimplemented_tasks(lang: &str) -> Vec<Task> {
let all_tasks = all_tasks().iter().cloned().collect::<HashSet<_>>(); let implemented_tasks = Category::new(lang).flatten().collect::<HashSet<_>>(); let mut unimplemented_tasks = all_tasks .difference(&implemented_tasks) .cloned() .collect::<Vec<Task>>(); unimplemented_tasks.sort_by(|a, b| a.title.cmp(&b.title)); unimplemented_tasks
}
fn main() {
for task in find_unimplemented_tasks::unimplemented_tasks("Rust") { println!("{:6} {}", task.id, task.title); }
} </lang>
- Output:
2973 Active Directory/Search for a user 2135 Add a variable to a class instance at runtime 22638 Bioinformatics/Sequence mutation 23073 Biorhythms 3219 Bitmap/Bézier curves/Cubic 3213 Bitmap/Bézier curves/Quadratic 3226 Bitmap/Histogram 3218 Bitmap/Midpoint circle algorithm 3217 Bitmap/PPM conversion through a pipe 3225 Bitmap/Read a PPM file 3246 Bitmap/Read an image through a pipe 10244 Break OO privacy 7508 Bulls and cows/Player 9832 Calendar - for "REAL" programmers 11471 Canny edge detector 5279 Catmull–Clark subdivision surface 12552 Check Machin-like formulas 22349 Chernick's Carmichael numbers 22212 Chowla numbers 23287 Cistercian numerals 4268 Color of a screen pixel 10293 Color quantization 9749 Colour pinstripe/Display 9748 Colour pinstripe/Printer 13300 Combinations and permutations 17481 Commatizing numbers 2438 Compare sorting algorithms' performance 21167 Compiler/AST interpreter 21169 Compiler/code generator 21046 Compiler/lexical analyzer 21137 Compiler/syntax analyzer 21170 Compiler/virtual machine interpreter 22714 Cyclotomic polynomial 22500 De Bruijn sequences 9404 Death Star 6107 Deconvolution/1D 6110 Deconvolution/2D+ 14060 Deming's Funnel 21228 Determine if two triangles overlap 17509 Digital root/Multiplicative digital root 9965 Dinesman's multiple-dwelling problem 22595 Display an outline as a nested table 2102 Distributed programming 21206 Diversity prediction theorem 3273 Doubly-linked list/Definition 4888 Doubly-linked list/Traversal 8974 Draw a cuboid 19095 Draw a rotating cube 4297 Dynamic variable names 21942 EKG sequence convergence 22189 Eban numbers 21218 Eertree 17421 Elementary cellular automaton/Infinite length 22032 Elliptic Curve Digital Signature Algorithm 12635 Elliptic curve arithmetic 9371 Executable library 2843 Execute SNUSP 23157 Exponentiation with infix operators in (or operating on) the base 22649 Faces from a mesh 22098 Factorial base numbers indexing permutations of a collection 22459 Factorions 19860 Faulhaber's formula 21408 Faulhaber's triangle 21786 Feigenbaum constant calculation 12308 Find largest left truncatable prime in a given base 17454 Find palindromic numbers in both binary and ternary bases 9996 First class environments 22334 First perfect square in base n with n unique digits 22699 First power of 2 that has leading decimal digits of 12 1788 Flow-control structures 2783 Formal power series 2420 Forward difference 22506 Fraction reduction 17107 Fractran 21109 French Republican calendar 10768 Function frequency 10110 Function prototype 19505 Functional coverage tree 8058 GUI component interaction 8059 GUI enabling/disabling of controls 8843 GUI/Maximum window dimensions 9552 Galton box animation 3996 Gamma function 22619 Gapful numbers 21753 Gauss-Jordan matrix inversion 4996 Go Fish 22793 Graph colouring 3224 Grayscale image 9751 Greyscale bars/Display 4291 HTTPS/Client-authenticated 10707 Hofstadter Figure-Figure sequences 6245 Hofstadter-Conway $10,000 sequence 7622 Holidays related to Easter 9782 Honeycombs 7588 Horizontal sundial calculations 5346 Hough transform 22492 Humble numbers 17428 Idiomatically determine all the characters that can be used for symbols 3228 Image convolution 8370 Image noise 21308 Imaginary base numbers 17613 Index finite lists of positive integers 22565 Intersecting number wheels 1998 Introspection 9828 Inverted syntax 23001 Isqrt (integer square root) of X 9763 Joystick position 9722 Jump anywhere 9891 Kaprekar numbers 8432 Keyboard input/Flush the keyboard buffer 8434 Keyboard input/Keypress check 4263 Keyboard macros 6046 Knapsack problem/Bounded 3196 Knapsack problem/Unbounded 19210 Knuth's power tree 21302 Kosaraju 22467 Lah numbers 21584 Largest number divisible by its digits 22424 Latin Squares in reduced form 22003 Law of cosines - triples 19103 List rooted trees 2228 Literals/String 22821 Long literals, with continuations 3851 Long multiplication 21733 Loops/Increment loop index within loop body 21990 Loops/With multiple ranges 21994 Loops/Wrong ranges 17325 Lucky and even lucky numbers 22107 Matrix digital rain 3230 Median filter 1991 Memory layout of a data structure 23353 Merge and aggregate datasets 22710 Mertens function 22608 Metallic ratios 10462 Metronome 22215 Mian-Chowla sequence 22664 Minimal steps down to 1 23296 Minkowski question-mark function 23539 Modified random distribution 12952 Modular arithmetic 20014 Monads/List monad 20016 Monads/Maybe monad 20022 Monads/Writer monad 18481 Multi-dimensional array 12576 Multifactorial 4456 Multiple regression 2400 Multiplicative order 9299 Multisplit 13149 Musical scale 4451 Named parameters 9454 Natural sorting 12953 Nautical bell 21855 Nested templated data 2778 Non-continuous subsequences 23075 Non-transitive dice 16746 Nonogram solver 10185 Numeric error propagation 22048 Numerical and alphabetical suffixes 9805 Numerical integration/Gauss-Legendre Quadrature 10147 OLE automation 10773 Odd word problem 18243 One-time pad 11982 OpenWebNet password 12237 Operator precedence 17599 Order disjoint list items 9223 Ordered partitions 23454 P-Adic numbers, basic 23470 P-Adic square roots 21652 P-value correction 23570 Padovan n-step number sequences 23149 Pancake numbers 10974 Paraffins 4878 Parametrized SQL statement 10993 Parsing/RPN to infix conversion 9391 Partial function application 19012 Pascal matrix generation 2770 Pascal's triangle/Puzzle 20044 Pathological floating point problems 22237 Peaceful chess queen armies 22161 Pell's equation 19037 Pentagram 15821 Percolation/Bond percolation 15850 Percolation/Mean cluster density 15846 Percolation/Mean run density 15836 Percolation/Site percolation 22093 Perfect totient numbers 12099 Permutations by swapping 9631 Permutations/Derangements 12454 Permutations/Rank of a permutation 22476 Pierpont primes 12298 Pig the dice game/Player 9745 Pinstripe/Display 9746 Pinstripe/Printer 4366 Play recorded sounds 13455 Playfair cipher 2435 Plot coordinate pairs 1784 Pointers and references 3094 Polymorphic copy 1968 Polymorphism 4397 Polynomial long division 2436 Polynomial regression 20435 Polyspiral 10639 Pragmatic directives 22678 Primality by Wilson's theorem 18777 Primes - allocate descendants to their ancestors 7941 Problem of Apollonius 23045 Pseudo-random numbers/Combined recursive generator MRG32k3a 23039 Pseudo-random numbers/PCG32 23038 Pseudo-random numbers/Xorshift star 10734 Pythagoras tree 9939 QR decomposition 22293 Ramanujan's constant 22365 Random Latin squares 23477 Random sentence from book 17751 Ranking methods 5179 Rate counter 21939 Recaman's sequence 9054 Record sound 21019 Reflection/Get source 21022 Reflection/List methods 21023 Reflection/List properties 3559 Rendezvous 10354 Resistor mesh 4317 Respond to an unknown method call 21365 Retrieve and search chat history 3149 Roots of a quadratic function 3357 Rosetta Code/Find unimplemented tasks 21688 Rosetta Code/Rank languages by number of users 3315 Rosetta Code/Rank languages by popularity 3557 Runtime evaluation 3556 Runtime evaluation/In an environment 1678 SOAP 1912 SQL-based authentication 4723 Safe addition 22006 Safe primes and unsafe primes 19083 Sailors, coconuts and a monkey problem 12228 Same fringe 4362 Scope modifiers 12940 Scope/Function names and labels 23112 Self numbers 10406 Send an unknown method call 4467 Send email 19255 Sequence of primorial primes 22268 Sequence: nth number with exactly n divisors 22259 Sequence: smallest number greater than previous term with exactly n divisors 11690 Set consolidation 10590 Set of real numbers 12906 Set puzzle 4679 Seven-sided dice from five-sided dice 21557 Shoelace formula for polygonal area 12961 Shortest common supersequence 10750 Simple database 2501 Singleton 9801 Sokoban 17663 Solve a Holy Knight's tour 17657 Solve a Hopido puzzle 17656 Solve a Numbrix puzzle 18017 Solve the no connection puzzle 23050 Sort an outline at every level 8099 Sorting algorithms/Bead sort 15995 Sorting algorithms/Patience sort 2853 Sorting algorithms/Permutation sort 9526 Sorting algorithms/Strand sort 4966 Soundex 2227 Special characters 9850 Special variables 9468 Speech synthesis 23564 Square Form Factorization 7892 Stable marriage problem 4197 Stack traces 4924 Stair-climbing puzzle 10077 Start from a main routine 10410 State name puzzle 10159 Statistics/Normal distribution 5219 Stem-and-leaf plot 18358 Stern-Brocot sequence 22465 Stirling numbers of the first kind 22466 Stirling numbers of the second kind 9882 Straddling checkerboard 20956 Stream merge 8644 Strip block comments 9875 Strip control codes and extended characters from a string 22088 Strong and weak primes 19060 Subleq 19649 Substitution cipher 10198 Subtractive generator 22295 Successive prime differences 22055 Suffixation of decimal numbers 19053 Sum and product puzzle 21263 Sum to 100 10366 Summarize and say sequence 21914 Sunflower fractal 19672 Superellipse 18234 Superpermutation minimisation 1676 Table creation/Postal addresses 23375 Tau function 10052 Terminal control/Cursor movement 8413 Terminal control/Cursor positioning 8423 Terminal control/Dimensions 8596 Terminal control/Display an extended character 8595 Terminal control/Hiding the cursor 8597 Terminal control/Inverse video 8418 Terminal control/Positional read 9380 Terminal control/Preserve screen 10505 Terminal control/Unicode output 17719 Test integerness 3104 Text processing/1 3111 Text processing/2 21761 The Name Game 20692 Tonelli-Shanks algorithm 12844 Topic variable 12627 Topswops 12310 Total circles area 22586 Tree datastructures 23450 Tree from nesting levels 12318 Twelve statements 22636 UPC 23467 Untouchable numbers 9733 Update a configuration file 4482 User input/Graphical 9349 Van der Corput sequence 1986 Variable size/Set 8488 Variable-length quantity 4470 Variables 2868 Variadic function 4688 Verify distribution uniformity/Chi-squared test 4680 Verify distribution uniformity/Naive 9889 Video display modes 16103 Vogel's approximation method 22228 Weird numbers 3109 Window creation/X11 4266 Window management 20673 Word search 22991 Word wheel 17721 World Cup group stage 2433 Write float arrays to a text file 1760 XML/DOM serialization 1643 XML/XPath 3998 Xiaolin Wu's line algorithm 4124 Yahoo! search interface 9410 Yin and yang 10989 Zebra puzzle 12489 Zeckendorf arithmetic 12371 Zeckendorf number representation 16497 Zhang-Suen thinning algorithm
Scala
Add to `build.sbt`
libraryDependencies ++= Seq( "org.json4s"%%"json4s-native"%"3.6.0", "com.softwaremill.sttp"%%"core"%"1.5.11", "com.softwaremill.sttp"%%"json4s"%"1.5.11")
<lang scala> import com.softwaremill.sttp.json4s._ import com.softwaremill.sttp.quick._
implicit val serialization = org.json4s.native.Serialization import org.json4s.DefaultFormats implicit val formats = DefaultFormats
case class Task(pageid: Int, title: String) case class Category(categorymembers: List[Task]) case class Query(query: Category)
List("Programming Tasks", "Scala")
.map { title => sttp .get(uri"http://www.rosettacode.org/mw/api.php?action=query&list=categorymembers&cmtitle=Category:${title}&cmlimit=1000&format=json") .header("User-Agent", mozillaUserAgent) .response(asJson[Query]) .send() .body } .map { case Right(r) => r.query.categorymembers.toSet case Left(s) => Set.empty[Task] } .foldRight(Set.empty[Task])((acc: Set[Task], ele: Set[Task]) => acc -- ele)
</lang>
Tcl
First, find all members of the Programming_Tasks category,
then find all members of the $lang
category.
The difference is the list of unimplemented tasks.
<lang tcl>package require Tcl 8.5 package require http package require json package require struct::set
fconfigure stdout -buffering none
- Initialize a cache of lookups
array set cache {} proc log msg {
#puts -nonewline $msg
}
proc get_tasks {category} {
global cache if {[info exists cache($category)]} {
return $cache($category)
} set base_url http://www.rosettacode.org/mw/api.php set query {
action query list categorymembers cmtitle Category:%s format json cmlimit 500
} set query [list {*}$query]; # remove excess whitespace set this_query [dict create {*}[split [format $query $category]]] set tasks [list] while {1} { set url [join [list $base_url [http::formatQuery {*}$this_query]] ?] while 1 { set response [http::geturl $url]
# Process redirects
if {[http::ncode $response] == 301} { set newurl [dict get [http::meta $response] Location] if {[string match http://* $newurl]} { set url $newurl } else { set url [regexp -inline {http://[^/]+} $url] append url $newurl } continue }
# Check for oopsies!
if {
[set s [http::status $response]] ne "ok" || [http::ncode $response] != 200 } then {
error "Oops: url=$url\nstatus=$s\nhttp code=[http::code $response]" } break }
# Get the data out of the message
set data [json::json2dict [http::data $response]] http::cleanup $response # add tasks to list foreach task [dict get $data query categorymembers] { lappend tasks [dict get [dict create {*}$task] title] } if {[catch {
dict get $data query-continue categorymembers cmcontinue } continue_task]} then {
# no more continuations, we're done break } dict set this_query cmcontinue $continue_task } return [set cache($category) $tasks]
}
proc get_unimplemented {lang} {
set tasks [get_tasks Programming_Tasks] set collected [get_tasks Collection_Members] set doneTasks [get_tasks $lang] set omittedTasks [get_tasks $lang/Omit]
# Map generic collection task categories to specific ones set tasks [regsub -all {Category:(\S+)} $tasks "\\1/$lang"]
set collectOfLang [struct::set intersect $collected $doneTasks] set ignorable [struct::set union $doneTasks $omittedTasks $collectOfLang] set unimplemented [struct::set difference $tasks $ignorable]
puts "\n$lang has [llength $unimplemented] unimplemented programming tasks:" if {[llength $unimplemented]} {
puts " [join [lsort $unimplemented] "\n "]"
}
}
catch {console show} catch {wm withdraw .} foreach lang {Perl Python Ruby Tcl} {
get_unimplemented $lang
}</lang>
zkl
Uses shared libraries YAJL and cURL. <lang zkl>var [const] YAJL=Import("zklYAJL")[0], CURL=Import("zklCurl");
fcn getTasks(language){
continueValue,tasks:="",Data(0,String); // "nm\0nm\0...." do{ page:=CURL().get(("http://rosettacode.org/mw/api.php?" "action=query&cmlimit=500"
"&format=json" "&list=categorymembers" "&cmtitle=Category:%s" "&cmcontinue=%s").fmt(language,continueValue));
page=page[0].del(0,page[1]); // get rid of HTML header json:=YAJL().write(page).close(); json["query"]["categorymembers"].pump(tasks,T("get","title")); continueValue=json.find("continue") //continue:-||,cmcontinue:page|954|19) .toList().apply("concat","=").concat("&"); }while(continueValue); tasks
}
allTasks:=getTasks.future("Programming_Tasks"); // thread</lang> <lang zkl>language:="zkl"; tasks:=getTasks(language); langTasks:=Dictionary(); tasks.pump(Void,langTasks.add.fp1(Void)); unimplementedTasks:=allTasks.filter('wrap(nm){ (not langTasks.holds(nm)) }); println("Found %d unimplemented tasks for %s:"
.fmt(unimplementedTasks.len(1),language));
unimplementedTasks.pump(Console.println);</lang>
- Output:
Found 166 unimplemented tasks for zkl: 15 Puzzle Game 2048 Address of a variable Animate a pendulum ... Zeckendorf arithmetic Zhang-Suen thinning algorithm
- Pages using duplicate arguments in template calls
- Programming Tasks
- Rosetta Code related
- Ada
- AWS
- AutoHotkey
- C sharp
- Clojure
- E
- Erlang
- Go
- Haskell
- HTTP XML
- Icon
- Unicon
- Perl
- Phix
- Phix/libcurl
- PicoLisp
- PowerShell
- Python
- Mwclient
- Requests
- Urllib
- R
- XML (R)
- Racket
- Raku
- Ring
- Ruby
- Run BASIC
- Rust
- Scala
- Tcl
- Tcllib
- Zkl
- Batch File/Omit
- Brainf***/Omit
- Lilypond/Omit
- Lotus 123 Macro Scripting/Omit
- Maxima/Omit
- PostScript/Omit
- TI-83 BASIC/Omit
- TI-89 BASIC/Omit
- Yorick/Omit
- ZX Spectrum Basic/Omit