AOJ向けPythonライブラリ&コマンドラインツールセットaojtoolsを公開しました

PyPIaojtoolsというパッケージを登録しました。
aojtoolsはAizu Online Judge Systemが提供するAPIのラッパーとsubmit用モジュール、それからコマンドラインプログラムからなります。

aojtoolsを使うとAPIに透過的にアクセスできたり、プログラムを素早く提出できます。

インストール

easy_installを使うのが手軽です。

  • $ easy_install aojtools
  • PyPIのページからソースを落としてソースからインストール
  • $ git clone git@github.com:yatt/aojtools.git でソースを落としてソースからインストール

モジュールの使い方

API ReferenceにあるAPIを使いたい

aojtools.api以下がAPIのラッパーです。現時点の全てのAPIに対応しています。
それぞれのAPIが関数に1対1対応しており、User Search APIならaojtools.api.userなどといった感じです。APIへのパラメータは関数の引数にキーワード引数で与えてください。レスポンスはそれっぽいものが戻ります。dictオブジェクトっぽいもの。

API 関数名
User Search API user
Problem Search API problem
Problem List Search API problemlist
All User List (Rank List) Search API alluserlist
Solved Record Search API solvedrecord
Status Log Search API statuslog
Problem Category Search API problemcategory

例)User Search APIを使う

>>> from aojtools import api
>>> u = api.user(id='yatt')
>>> u
<user keys=status,name,lastsubmitdate,registerdate_str,affiliation,registerdate,id,lastsubmitdate_str,solved_list>
>>> u.registerdate_str
'2010/10/19 16:12:25'
>>> u.status
<status keys=submission,memorylimit,runtimeerror,wronganswer,solved,timelimit,compileerror,accepted,outputlimit>
>>> u.status.submission
109
プログラムをsubmitしたい

aojtools.submitにユーザ名やソースコードの情報を渡してください。接続のタイムアウトや最大試行回数を設定することもできます。
戻り値は対応するsubmitステータスです。

>>> from aojtools import submit
>>> info = {
>>>     'user_id': '(user id)',
>>>     'password': '(password)',
>>>     'code': '(source code)', # sjis
>>>     'problem_id': 0,
>>>     'lang': 'C',
>>> }
>>> r = submit(info)
>>> r.status
Accept
>> info['code'] = open('wrong.c').read() # sjis
>>> r = submit(info)
>>> r.status
Wrong Answer

コマンドラインプログラムの使い方

aojtoolsをインストールするとパスの通った場所にいくつかのスクリプトがインストールされます。

aojsubmit sutmitツール

aojsubmitは問題をサーバに提出するツールです。
ユーザ名やパスワード等を指定してプログラムファイルを渡すと結果を返します。

$ aojsubmit -u userid -p password -l cpp -i 0 problem.cpp # 問題0000にsubmit

なお、問題番号はプログラムファイルの1行目のコメントに" AOJ 0000"などと、正規表現'AOJ\D?(\d+).*'(大文字小文字無視)にマッチする文字列がある場合はキャプチャしてそれを問題番号として提出します。また、プログラム言語はファイル名に拡張子がある場合自動で判別します。
加えて、ホームディレクトリの.aojsubmitrcというファイルにユーザ名とパスワードがスペース区切りで保存されていると自動で読み込みます。
前述の拡張子の判別と問題番号のコメント記述、それから.aojsubmitrcファイルを全て使うと、プログラムの引数にファイルパスを指定するだけでsubmitできるようになります。

$ cat > ~/.aojsubmitrc
userid password
$ chmod 600 ~/.aojsubmitrc
$ cat aoj0000.cpp
// AOJ 0000
#include<cstdio>
int main()
{
    for (int i = 1; i < 10; i++)
        for (int j = 1; j < 10; j++)
            printf("%dx%d=%d\n", i, j, i*j);
    return 0;
}
$ aojsubmit aoj0000.cpp
Accepted
$ cat wrong.cpp
// AOJ 0000
#include<cstdio>
int main()
{
    printf("wrong\n");
        return 0;
}
$ aojsubmit wrong.cpp
Wrong Answer
$ cat aoj0012.c
/* aoj 0012 A Point in a Triangle */
#include<stdio.h>
float cross(float a, float b, float c, float d)
{
    return a * d - b * c;
}
(略)
$ submit aoj0012.c
Accepted
aojwhois ユーザの情報を表示
$ aojwhois yatt
+ status       
  - submission          109
  - memorylimit         0
  - runtimeerror        8
  - wronganswer         34
  - solved              48
  - timelimit           2
  - compileerror        9
  - accepted            56
  - outputlimit         0
- name                  brainfs
- lastsubmitdate        2010/12/17 14:36:01
- registerdate_str      2010/10/19 16:12:25
- affiliation           -
- registerdate          2010/10/19 16:12:25
- id                    yatt
- lastsubmitdate_str            2010/12/17 14:36:01
- solved_list:
   0000 0001 0002 0003 0005 0006 0007 0008 0009 0011 0014 0017 0019 0020 0023 
   0025 0028 0030 0044 0046 0049 0052 0055 0073 0075 0077 0093 0123 0124 0136 
   0149 0150 0158 0167 0173 0175 0184 0188 0195 0197 0206 0510 0511 0543 1000 
   1041 1200 2006 
aojwhatis 問題に関する情報を表示
$ aojwhatis 2
+ status 
  - submission      1780
  - memorylimit      0
  - runtimeerror      197
  - wronganswer      704
  - timelimit      118
  - accepted      761
  - outputlimit      0
- problemmemorylimit      32768
- solved_list:
   tomoyuki   NightSky   grassbigboy nkkwe      kikusumk3  
   tfrkd      ychemchemy te2        daiki02peach seotos     
  ...(591 users)
- problemtimelimit      1
- id      2
- name      Digit Number
aojcategories 問題の分類別にスコアを表示

APIで得られた分類情報を表示します。次にどの問題を解こうか迷ったらこれを目安にするといいかも。

$ aojcategories 
datamanipu      35
string          31
probability     7
geometry        80
graph           64
straight        70
number          35
numeric         19
simulation      56
combinatorial   56
parsing         11
puzzle          59
$ aojcategories probability
0504 3.250000
1020 2.000000
1056 3.000000
1058 3.500000
1213 3.000000
1277 1.500000
1286 2.000000
2019 1.000000

初めてモジュールをPyPIに上げました。公開するのってこんなに簡単だったのかーて感じです。setup.pyの記述はエキスパートPythonとネット上の記事を参考にしました。ネット上の日本語の情報は情報量が少なかったりわかりにくかったりでアレな感じなのでモジュール公開するならこの本立ち読みでもしましょう。あとで備忘録もかねてわかりやすい公開手順を書きたい。

エキスパートPythonプログラミング

エキスパートPythonプログラミング