【修正1. 02-24-2018(Sat)】parse.pyのform関数
TL;DR
以下基本の3ステップでスキルチェック問題への迅速な解答手段を提案する.
- make dl url=https://paiza.jp/path/to/problem # download problem
- vim solve.py # type code here ...
- make test # run all test cases
動機
- いちいち入力例をコピーしてinputに投げ込むのが面倒だった.
- web上でのコード作成とIO機能が搭載されたonlineツールの使い勝手が如何せん悪かった.
- vim中毒ゆえの決断ry
方針
- 解答までの時間を可能な限り短縮できる方法を実装すること.
- スキルチェック問題で提示されている全ての入出力例をテストできること.
TODO
- cookie情報を自動で取得しcookie.txtを作成する => chromeのcookie.txt exportで代用.
-
自動テスト環境
- problem.html(スキルチェック問題)をcurl(cookie利用)する.
- problem.htmlをparseし,問題タイトル及び入出力例を取得する.
- 取得した情報からsolve.py, test/sample-N.{in,out}を作成する.
- 自動テスト用のtest.shを作成.
- make testの出力結果の色付け.
- ユーザ定義のテストケースの追加.
導入
プロジェクト構成
├── .system/
│ ├── cookie.txt
│ ├── parse.py
│ └── test.sh
├── Makefile
├── solve.py
└── test/
├── sample-0.ans
├── sample-0.in
├── sample-0.out
├── sample-1.ans
├── sample-1.in
├── sample-1.out
├── ...
必須ツール&モジュール
brew install curl python3
pip3 install beautifulsoup4 lxml
使い方(例)
- chromeのcookie.txt exportでcookie情報を取得し,.system/cookie.txtに上書きする.
- vimを起動し,ビルドコマンドから**make dl url=https://paiza.jp/path/to/problem**を実行する.
- make dl後にsolve.pyを開いてコードを記述し,make testでACを確認する.
- solve.pyの内容をpaizaスキルチェックの解答欄にコピー&ペーストしてコードを提出する.
主要コード
Makefile
.PHONY: test
test:
sh .system/test.sh
diff:
diff --side-by-side test/sample-$(N).ans test/sample-$(N).out
dl:
curl -b ./.system/cookie.txt -o ./problem.html $(url) -s
rm -f ./solve.py ./test/*
python3 .system/parse.py
rm -f ./problem.html
test.sh
#!/bin/sh
echo "\n-- * -- TEST -- * --\n"
for f in test/*.in
do
cat $f | python3 solve.py 1>${f%.in}.ans 2>/dev/null
if diff -q ${f%.in}.ans ${f%.in}.out >/dev/null; then
echo "${f%.in}: Success"
else
echo "${f%.in}: Failure"
fi
done
echo "\n-- * -- TEST -- * --\n"
parse.py
from bs4 import BeautifulSoup
def save(filename, body):
with open(filename, 'w') as f:
f.write(body)
def form(text):
rn = map(lambda s: s.replace('\n', '').strip(), text.strings)
fn = list(filter(lambda s: s != '', rn))[1:]
return '\n'.join(fn) + '\n'
def get_soup(filename, parser):
with open(filename, 'r') as f:
soup = BeautifulSoup(f, parser)
return soup
def parse(soup):
# Problem Title
prob_title = soup.h1.span.text
# Test Cases
box1 = soup.find_all("dl", class_="txt2")
inputs = [b for b in box1 if "入力例" in b.text]
outputs = [b for b in box1 if "出力例" in b.text]
# solve.py
save('solve.py', "# " + prob_title + "\n")
# test/*.{in,out}
path2t = 'test/sample-{}.{}'
for n, [i, o] in enumerate(zip(inputs, outputs)):
save(path2t.format(n, 'in'), form(i))
save(path2t.format(n, 'out'), form(o))
return soup
readfile = 'problem.html'
prob_soup = parse(get_soup(readfile, 'lxml'))
所感
動機の煩わしい問題を解決できたため,一応満足している.
その他の痒いところに手が届かない問題を少しずつ解決していこうと思った.
おわりに
タイトルではvim, python3使い向けと銘打っていますが,その他の方にとってもpaizaスキルチェック問題を通したプログラミング学習の一助になれば幸いです.アドバイスやツッコミ,別なアプローチなど御座いましたらフィードバックよろしくお願いします.