前几天我想知道StackOverflow是否有我可以从Mathematica访问的API,显然它确实如此:"Saving plot annotations"
将StackOverflow中的数据导入Mathematica的最佳方法是什么? Sjoerd利用这些信息制作了一个情节。我有兴趣将SO相关的通知添加到我保存在笔记本中的停靠单元格中,因此我可以在不离开Mathematica的情况下判断何时有更新或响应。
答案 0 :(得分:26)
根据大众需求,使用annotations生成前10个SO回复者的代码(SO API除外)(这是一个非常整洁和完整的API;很多好东西。很容易 - 看我的代码)。
更新:添加App-key以确保代码与SO-API(每日通话上限更高)更好地合作。请仅在此应用中使用它。
2011年4月
2011年8月
MMA 8版! MMA7版本进一步向下
getRepChanges[userID_Integer] :=
Module[{totalChanges},
totalChanges =
"total" /.
Import["http://api.stackoverflow.com/1.1/users/" <>
ToString[userID] <> "/reputation?key=NgVJ4Y6vFkuF-oqI-eOvOw&fromdate=0&pagesize=1&page=1",
"JSON"
];
Join @@
Table[
"rep_changes" /.
Import["http://api.stackoverflow.com/1.1/users/" <>
ToString[userID] <>
"/reputation?key=NgVJ4Y6vFkuF-oqI-eOvOw&fromdate=0&pagesize=100&page="
<> ToString[page],
"JSON"
],
{page, 1, Ceiling[totalChanges/100]}
]
]
topAnswerers =
({"display_name","user_id", "email_hash"} /. #) & /@
("user" /.
("top_users" /.
Import[
"http://api.stackoverflow.com/1.1/tags/mathematica/top-answerers/all-time",
"JSON"
]
)
)
topAnswerers = {#, #2,
Import["http://www.gravatar.com/avatar/" <> #3 <> ".jpg?s=36&d=identicon&d=identicon"]
} & @@@ topAnswerers
repChangesTopUsers =
Table[
repChange =
ReleaseHold[
(
Hold[
{
DateList["on_date" + AbsoluteTime["January 1, 1970"]],
"positive_rep" - "negative_rep"
}
] /. #
) & /@ getRepChanges[userID]
] // Sort;
accRepChange = {repChange[[All, 1]],Accumulate[repChange[[All, 2]]]}\[Transpose],
{userID, topAnswerers[[All, 2]]}
];
pl = DateListLogPlot[
Tooltip @@@
Take[({repChangesTopUsers, Row /@ topAnswerers[[All, {3, 1}]]}\[Transpose]),
10], Joined -> True, Mesh -> None, ImageSize -> 1000,
PlotRange -> {All, {10, All}},
BaseStyle -> {FontFamily -> "Arial-Bold", FontSize -> 16},
DateTicksFormat -> {"MonthNameShort", " ", "Year"},
GridLines -> {True, None},
FrameLabel -> (Style[#, FontSize -> 18] & /@ {"Date", "Reputation",
"Top-10 answerers", ""})]
修改强>
请注意,您可以通过更改Take功能中的值来绘制最多20个并包括前20个。很快就会很忙。
试图在某种程度上提高标记代码的可读性。我担心这会在复制时产生一些假的空间。
修改强>
页面大小返回100个元素/页面==&gt;更少的API调用
请注意,首次调用API是为了确定用户拥有的帖子数量。无论页面大小如何,都存在该数据,因此优选地选择较小(大约10个,可能是1个,不检查)。然后在连续页面中获取数据,直到到达最后一页。您可以使用最大页面大小(100)。请注意调整循环计数中的最大页数。
编辑:更好的MMA 7代码(4月22日星期五)
MMA 7不进行JSON导入,因此我执行文本导入,然后进行简单的JSON转换。我现在已经多次测试过这个版本(在MMA 8中),它似乎没有我昨天得到的错误。
getRepChanges[userID_Integer] :=
Module[{totalChanges},
totalChanges =
"total" /.
ImportString[
StringReplace[(Import[
"http://api.stackoverflow.com/1.1/users/" <>
ToString[userID] <>
"/reputation?key=NgVJ4Y6vFkuF-oqI-eOvOw&fromdate=0&pagesize=1&page=1", "Text"]), {":" ->
"->", "[" -> "{", "]" -> "}"}], "NB"];
Join @@
Table["rep_changes" /.
ImportString[
StringReplace[
Import["http://api.stackoverflow.com/1.1/users/" <>
ToString[userID] <>
"/reputation?key=NgVJ4Y6vFkuF-oqI-eOvOw&fromdate=0&pagesize=100&page=" <> ToString[page],
"Text"], {":" -> "->", "[" -> "{", "]" -> "}"}],
"NB"], {page, 1, Ceiling[totalChanges/100]}]]
topAnswerers = ({"display_name", "user_id",
"email_hash"} /. #) & /@ ("user" /. ("top_users" /.
ImportString[
StringReplace[
" " <> Import[
"http://api.stackoverflow.com/1.1/tags/mathematica/top-answerers/all-time", "Text"], {":" -> "->", "[" -> "{", "]" -> "}"}],
"NB"]))
topAnswerers = {#, #2,
Import["http://www.gravatar.com/avatar/" <> #3 <>
".jpg?s=36&d=identicon&d=identicon"]} & @@@ topAnswerers
repChangesTopUsers =
Table[repChange =
ReleaseHold[(Hold[{DateList[
"on_date" + AbsoluteTime["January 1, 1970"]],
"positive_rep" - "negative_rep"}] /. #) & /@
getRepChanges[userID]] // Sort;
accRepChange = {repChange[[All, 1]],
Accumulate[repChange[[All, 2]]]}\[Transpose], {userID,
topAnswerers[[All, 2]]}];
DateListLogPlot[
Tooltip @@@
Take[({repChangesTopUsers,
Row /@ topAnswerers[[All, {3, 1}]]}\[Transpose]), 10],
Joined -> True, Mesh -> None, ImageSize -> 1000,
PlotRange -> {All, {10, All}},
BaseStyle -> {FontFamily -> "Arial-Bold", FontSize -> 16},
DateTicksFormat -> {"MonthNameShort", " ", "Year"},
GridLines -> {True, None},
FrameLabel -> (Style[#, FontSize -> 18] & /@ {"Date", "Reputation",
"Top-10 answerers", ""})]
编辑:过滤帖子标签的辅助功能
这些函数可用于过滤信誉增益,以便仅查找某些标记的增益。
tagLookup
获取post_ID整数作为输入,并生成特定帖子的标签。 getQuestionIDs
和getAnswerIDsFrom...
走另一条路。给定标记后,他们会找到所有问题和答案ID,以便可以使用MemberQ
测试给定的post_ID是否属于此标记。 tagLookup和getAnswerID都很慢,因为许多API调用都是必需的。我无法测试最后两个函数,因为API访问已关闭或我的IP已被限制。
tagLookup[postID_Integer] :=
Module[{im},
im = Import["http://api.stackoverflow.com/1.1/questions/" <> ToString[postID],"JSON"];
If[("questions" /. im) != {},
First[("tags" /. ("questions" /. im))],
im = Import["http://api.stackoverflow.com/1.1/answers/" <> ToString[postID],"JSON"];
First[("tags" /. ("questions" /. Import["http://api.stackoverflow.com/1.1/questions/" <>
ToString[First["question_id" /. ("answers" /. im)]], "JSON"]))]
]
]
getQuestionIDs[tagName_String] := Module[{total},
total =
"total" /.
Import["http://api.stackoverflow.com/1.1/questions?tagged=" <>
tagName <> "&pagesize=1", "JSON"];
Join @@
Table[("question_id" /. ("questions" /.
Import["http://api.stackoverflow.com/1.1/questions?key=NgVJ4Y6vFkuF-oqI-eOvOw&tagged=" <>
tagName <> "&pagesize=100&page=" <> ToString[i],
"JSON"])), {i, 1, Ceiling[total/100]}]
]
getAnswerIDsFromQuestionID[questionID_Integer] :=
Module[{total},
total =
Import["http://api.stackoverflow.com/1.1/questions/" <>
ToString[questionID] <> "/answers?key=NgVJ4Y6vFkuF-oqI-eOvOw&pagesize=1", "JSON"];
If[total === $Failed, Return[$Failed], total = "total" /. total];
Join @@ Table[
"answer_id" /. ("answers" /.
Import["http://api.stackoverflow.com/1.1/questions/" <>
ToString[questionID] <> "/answers?key=NgVJ4Y6vFkuF-oqI-eOvOw&pagesize=100&page=" <>
ToString[i], "JSON"]), {i, 1, Ceiling[total/100]}]
]
getAnswerIDsFromTag[tagName_String] :=
Module[{},
Join @@ (getAnswerIDsFromQuestionID /@
Cases[getQuestionIDs[tagName], Except[$Failed]])
]
答案 1 :(得分:12)
Brett,与SO API无关,但您可以使用RSS提要来获取最新的Mathematica标记问题。这是我的天真实施:
QuestionHyperlink[data_] :=
Function[{name, title, link},
Hyperlink[Tooltip[title, name], link]] @@ Join[
Cases[data,
XMLElement[
"author", _, {___, XMLElement["name", {}, {name_}], ___}] :>
name],
Cases[data, XMLElement["title", _, {title_}] :> title],
Cases[data, XMLElement["link", rules_, {}] :> ("href" /. rules)]]
Cases[Import[
"http://stackoverflow.com/feeds/tag?tagnames=mathematica&sort=\
newest", "XML"],
XMLElement["entry", attrs_, data_] :>
QuestionHyperlink[data], Infinity]