LoginSignup
3
3

More than 5 years have passed since last update.

paizaスキルチェック問題をローカルで自動テストできる環境のすゝめ(vim, python3使い向け)

Last updated at Posted at 2018-02-24

【修正1. 02-24-2018(Sat)】parse.pyのform関数

TL;DR

以下基本の3ステップでスキルチェック問題への迅速な解答手段を提案する.

  1. make dl url=https://paiza.jp/path/to/problem # download problem
  2. vim solve.py # type code here ...
  3. 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

使い方(例)

  1. chromeのcookie.txt exportでcookie情報を取得し,.system/cookie.txtに上書きする.
  2. vimを起動し,ビルドコマンドからmake dl url=https://paiza.jp/path/to/problemを実行する.
  3. make dl後にsolve.pyを開いてコードを記述し,make testでACを確認する.
  4. 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スキルチェック問題を通したプログラミング学習の一助になれば幸いです.アドバイスやツッコミ,別なアプローチなど御座いましたらフィードバックよろしくお願いします.

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3