はじめに
AtCoderなどの競技プログラミングやPaizaスキルチェックなどプログラミング問題といった入力に対して特定の出力を導く問題には、たいてい時間制限がついていますよね。
ちょっとした動作確認に時間を割いている余裕はないのです。
以前、この問題を解決するべく以下の記事を書きました。
Paizaのスキルチェックの例題のデバッグをJupyterとかのローカル環境でやるときの入力の手間を省きたい【Python】
しかし、これでもまだ微妙に使い方がスッキリしていないですし、しばらく使わないと使い方を忘れてしまいそうです。
そこで今回は、
折角のJupyter。マジックコマンドを使わない手はない!
という方針で解決してみることにしました。
マジックコマンドとは?
Jupyterにおけるマジックコマンドとは、%
や%%
から始まる特殊機能の呼び出しのことを指します。
%time
や%%timeit
、%matplotlib notebook
などのコマンドは馴染み深い方も多いのではないでしょうか?
これ、実は自分で作れます。
詳しい?方法は以下で紹介していますのでよろしければ見ていってください。
【Python・Jupyter】ライブラリを自動インポートする方法・マジックコマンドの作り方
作ったもの
以下をセルに入れて実行するか、C:\Users\%USERNAME%\.ipython\profile_default\startup
(Windows) 下に置くことで(上記リンク参照)マジックコマンドが使えるようになります。
from IPython.core.magic import Magics, magics_class, cell_magic, line_magic
@magics_class
class MyMagics(Magics):
lines = ""
@cell_magic
def input_magic(self, line, cell):
global input
assert line in ('input', 'test'), "Please specify the command after the magic command: 'input' or 'test'."
if line == 'input':
self.lines = cell.strip('\n').splitlines()
self.stdin = self.__stdin()
else:
input = self.input
self.shell.run_cell(cell)
input = __builtins__.input
@line_magic
def reload_input(self, line=None):
self.stdin = self.__stdin()
def input(self, arg=""):
if arg:
print(arg, end=" ")
return next(self.stdin)
def __stdin(self):
assert self.lines, "Input lines are not defined."
for line in self.lines:
yield line
else:
raise EOFError("EOF when reading a line")
get_ipython().register_magics(MyMagics)
使い方
%%input_magic
に続いて、「input
」で入力の設定、
「test
」で実行ができます。
AtCoder Beginner Contest 219 : H - Candlesより
%%input_magic input
5
0 1000000000
0 1000000000
1 1000000000
2 1000000000
3 1000000000
%%input_magic test
hogehoge
4999999994
また、実行時は毎回%%input_magic input ~
のセルを実行する必要がありますが、おまけとして入力をリセットするコマンドも用意していますので、
%reload_input
コマンドを挟んでおけば、その行の時点で入力を始めからにすることができます。
%%input_magic test
%reload_input
fugafuga
さいごに
環境によってはasyncio
周りのエラーが出ることがあります。原因はよく判りません。
Colabや、Dockerで作った仮想環境では正常に動きました。