Rosetta Code/Find unimplemented tasks: Difference between revisions
No edit summary |
m (→{{header|Tcl}}) |
||
Line 176: | Line 176: | ||
set base_url http://www.rosettacode.org/w/api.php |
set base_url http://www.rosettacode.org/w/api.php |
||
set query {action query list categorymembers cmtitle Category:%s format json cmlimit 500} |
set query {action query list categorymembers cmtitle Category:%s format json cmlimit 500} |
||
set this_query [dict create {*}[format $query $category]] |
set this_query [dict create {*}[split [format $query $category]]] |
||
set tasks [list] |
set tasks [list] |
||
Revision as of 12:54, 17 April 2009
You are encouraged to solve this task according to the task description, using any language you may know.
Given the name of a language on Rosetta Code, find all tasks which are not implemented in that language.
E
Using JSON.
<lang>
- !/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 [<language>]
- 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) ) -> { # Compute difference and report def notDoneTasks := allTasks &! doneTasks println() println("\n".rjoin(notDoneTasks.getElements().sort()))
} catch p {
# Whoops, something went wrong stderr.println(`$p${p.eStack()}`)
} </lang>
Perl
Using JSON, though we don't bother actually parsing it.
<lang perl>use LWP::Simple 'get';
my $fmt = 'http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:%s&cmlimit=500&format=json'; my $lang = shift
or die "No language given.\n";
sub urlencode
{join , map {sprintf '%%%02x', ord} split //, shift}
sub tasks
{my $category = urlencode shift; my @tasks; my $json = get sprintf $fmt, $category; for (;;) {push @tasks, $json =~ /"title":"(.+?)"}/g; $json =~ /"cmcontinue":"(.+?)"}/ or last; $json = get sprintf $fmt . '&cmcontinue=%s', $category, urlencode $1;} return @tasks;}
my @all = tasks 'Programming_Tasks'; my %lang = map {$_, 1} tasks $lang
or die "No such category.\n";
$lang{$_} or print "$_\n"
foreach @all;</lang>
Python
Using XML.
<lang python>import xml.dom.minidom import urllib, sys
def do(category):
x = urllib.urlopen("http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:%s&cmlimit=500&format=xml" % urllib.quote(category)).read() x = xml.dom.minidom.parseString(x) x = [i.getAttribute("title") for i in x.getElementsByTagName("cm")] return x
alltasks = do("Programming_Tasks") lang = do(sys.argv[1])
for i in [i for i in alltasks if i not in lang]:
print i</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.
This uses the json
and struct::set
packages from tcllib
<lang tcl>package require Tcl 8.5
package require http
package require json
package require struct::set
fconfigure stdout -buffering none
proc get_tasks {category} {
set start [clock milliseconds] puts -nonewline "getting $category members..." set base_url http://www.rosettacode.org/w/api.php set query {action query list categorymembers cmtitle Category:%s format json cmlimit 500} set this_query [dict create {*}[split [format $query $category]]] set tasks [list]
while {1} { set url [join [list $base_url [http::formatQuery {*}$this_query]] ?] set response [http::geturl $url] if {[set s [http::status $response]] ne "ok" || [http::ncode $response] != 200} { error "Oops: url=$url\nstatus=$s\nhttp code=[http::code $response]" } 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] != 0} { # no more continuations, we're done break } dict set this_query cmcontinue $continue_task } puts " found [llength $tasks] tasks in [expr {[clock milliseconds] - $start}] milliseconds" return $tasks
}
proc get_unimplemented {lang} {
set unimplemented [struct::set difference [get_tasks Programming_Tasks] [get_tasks $lang]] puts "\n$lang has [llength $unimplemented] unimplemented programming tasks:" puts [join [lsort $unimplemented] \n]
}
get_unimplemented Tcl</lang>