VSCode + DockerでAtCoderのテスト・提出ができる環境構築【Python,PyPy】

# はじめに
私は2022年9月からAtCoderを始めて、今までサイト内にあるコードテストを使ってPython・PyPy3で問題を解いていました。
しかし、サンプルのテスト・提出をするのに毎度コピー＆ペーストするのが煩わしくコマンド一つで完結させたいのと、ローカル環境下に色々インストールすると今後依存関係等で大変になるかと思い、VSCode + Dockerを使って簡単にテスト・提出ができる環境構築を行いました。
環境はWindows10を使用しています。

# 準備
以下のものがインストールされていない場合は事前に準備をしておきます。
細かいインストール手順等は今回のメインではないため割愛させていただきます。

### VSCode
今回はエディターにVSCodeを使用するのでインストールをします。
VSCodeからDockerのコンテナ内に入って作業行うので、`拡張機能「Remote-Containers」`をインストールします。

### Docker
私はWindows10環境なのでDocker Desktop for Windowをインストールしました。

### git
リポジトリをクローンしますので、gitをインストールします。

# 環境構築
1. コマンドプロンプトの任意のディレクトリにて次のコマンドを実行。
   ```
    $git clone https://github.com/gomatofu/atcoder_python.git
    $code atcoder_python
   ```
2. VSCodeで`Remote-Containers: Reopen in Container`を選択。

すると以下のディレクトリ構成となります。 
　　
   ```
   atcoder_python/
        └ .devcontainer/
                ├ Dockerfile
                ├ devcontainer.json
                ├ docker-compose.yml
                └ requirements.txt
        └ contest/
   ```






　
* .devcontainer
  - .devcontainer内ではPython、PyPy、online-judge-tools、atcoder-cli等のインストールの設定を記述しています。
* contest
  - contest内では実際にAtCoderの問題を解いたり、テストしたりする場所として用意しています。

# 設定
ここからはVSCodeのターミナルで操作となります。

1. ディレクトリ：/atcoder_pythonにて次のコマンドを実行。atcoder-cli使用のためAtCoderログイン作業。

   ```
    $acc login
   ```

2. AtCoderのusername、passwordが聞かれるため、入力し実行。初回のみ必要となる。
1. ディレクトリ：/atcoder_pythonにて次のコマンドを実行。online-judge-tools使用のためAtCoderログイン作業。

   ```
    $oj login https://beta.atcoder.jp/
   ```

2. 再びAtCoderのusername、passwordが聞かれるため、入力し実行。初回のみ必要となる。警告が出るが問題ない。
2. ディレクトリ：/atcoder_pythonにて次のコマンドを実行。問題インストール時にデフォルトは１問ずつしかインストールされないが全問インストールされるように変更。

   ```
    $acc config default-task-choice all
   ```

1. テンプレートファイルの設定をPythonに変更するためatcoder-cliの設定フォルダへ移動。

   ```
    $cd `acc config-dir`
   ```

1. Pythonディレクトリを作成し、main.pyとtemplate.jsonの作成を行う。

   ```
    $mkdir python
    $cd python
    $touch template.json
    $touch main.py
    $code template.json
   ```

1. template.jsonの設定を行う。

   ```code:template.json
    {
    "task":{
      "program": ["main.py"],
      "submit": "main.py"
        }
    }
   ```

9. デフォルトのテンプレートをpythonに変更。

   ```
    $acc config default-template python
   ```

ここまででPython、PyPyで問題を解くための設定は終わりました。

---

ここからはテスト・提出のコマンドが長いので、コマンドを簡単にするためエイリアス設定を行っていきます。
あくまで私がわかりやすいようにコマンド名を決めているのでお好みで変更してください。


1. .bashrcを作成します。

   ```
    $cd ~
    $touch .bashrc
    $code .bashrc
   ```

2. .bashrcにエイリアス設定をしていきます。
   ```code:.bashrc
    # PyPy3でのテスト実施
    alias test='oj t -c "pypy3 main.py" -d ./tests/'
    # Pythonでのテスト実施
    alias test2='oj t -c "python3 main.py" -d ./tests/'

    # PyPy3での解答提出
    alias sb='acc s main.py -- --guess-python-interpreter pypy'
    # Pythonでの解答提出
    alias sb2='acc s main.py'

    # コンテストフォルダへ移動
    alias c='cd contest'

    # main.pyを開く
    alias o='code main.py'

    # 出力確認用
    alias d='python main.py'
   ```

これでコマンドの設定は終わりました。

# 使い方
ここから実際に問題を解いていきましょう。

## 問題作成
contestフォルダへ移動し、`acc new [ContestName]`を実行すると、以下のディレクトリが作成される。
[ContestName]： は解答したいコンテストの名前を入力。(例:abc248、abc255等)
   ```
    $ acc new abc248

    contest/
        └ abc248
            ├── a
            │   ├── main.py
            │   └── tests
            │       ├── sample-1.in
            │       ├── sample-1.out
            ...
            │       ├── sample-3.in
            │       └── sample-3.out
            ├── b
            │   ├── main.py
            │   └── tests
            │       ├── sample-1.in
            │       ├── sample-1.out
            ...
            │       ├── sample-3.in
            │       └── sample-3.out
            ├── c
            │   ├── main.py
            │   └── tests
            │       ├── sample-1.in
            │       ├── sample-1.out
            ...
            │       ├── sample-3.in
            │       └── sample-3.out
            ...
            └─ contest.acc.json
   ```

## 解答
解答したい問題のディレクトリに移動し、main.pyを開き解答を行っていきます。
   ```
    $cd abc248	　　　# 解答したいコンテスト
    $cd a		　　　# 解答したい問題
    $o		　　　    # main.pyを開く
   ```

## テスト
問題が解き終わったらサンプルのテストケースをもとにテストを行っていきます。
   ```
    $test	　　　    # PyPy3でテストしたい場合
    $test2	　　　    # Pythonでテストしたい場合
   ```

ターミナル内に結果が返ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731307/694b0968-ebed-a867-0ee7-980f7ddab602.png)


## 提出
問題が解き終わり提出を行っていきます。
   ```
    $sb	　　　    # PyPy3で提出する場合
    $sb2	　　　    # Pythonで提出する場合
   ```

提出の最終確認としてコマンドの入力を求められるので入力します。
今回は"abca"と書かれているので同じものを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731307/9127fd87-c3b7-d980-d5ba-624e558ae22b.png)

すると提出が成功となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731307/e629dcf0-ce9c-ac98-1095-3f46cc0effe6.png)

AtCoderのサイト内でも確認してみると、ちゃんと提出できています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2731307/2b2d9010-ff1c-6a79-b77e-f231d58fa397.png)

# 最後に
Dockerの設定等を一から行ったのは初めてなので間違っている点もあるかもしれませんが、実際に手を動かしながら行っていくと頭の中でぼんやりしていたものがはっきりとして理解が進んだかと思います。
間違っている点を見つけましたらご指摘いただけると助かります。
環境構築に満足してしまった点はありますが、本来の目的であるAtCoderの問題を解き進め、精進していきたいと思います。

**Githubのレポジトリ ↓**
https://github.com/gomatofu/atcoder_python

# 参考文献
* [Github - atcoder-cli](https://github.com/Tatamo/atcoder-cli)
   *  [コマンドラインツールatcoder-cliを公開しました](http://tatamo.81.la/blog/2018/12/07/atcoder-cli/)
* [GitHub - online-judge-tools](https://github.com/online-judge-tools/oj)
* [AtCoderの提出自動化をする（Python）](https://qiita.com/Orangeat/items/7c44994d33b3ca83a6ea#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB)
* [VS CodeでDocker開発コンテナを便利に使おう](https://qiita.com/Yuki_Oshima/items/d3b52c553387685460b0)