AtCoderに提出されたプログラムの言語の割合を可視化するアプリを作ってみました

# はじめに
アローラ!! Inazuma110と申します…。
これは[Competitive Programming (1) Advent Calendar 2020](https://adventar.org/calendars/4969)の3日目の記事です。

# [AtCoder Language Visualizer](https://inazuma110.github.io/atcoder_language_visualizer)
AtCoderに提出された、プログラムの言語の割合を問題ごとに可視化するWebアプリを作りました。(ACしたコードのみを集計しています。)
ソースコードは[こちら](https://github.com/Inazuma110/atcoder_language_visualizer)です。
<a href="https://github.com/inazuma110/atcoder_language_visualizer"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/inazuma110/atcoder_language_visualizer.png" width="460px"></a> 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227269/a46f5a09-9912-c72d-44ff-96eb50605208.png)

## 使い方
1. コンテスト名や問題名で可視化したい問題を検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227269/4dd75919-2799-bcc1-8ade-726cdabce31f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227269/b090a331-3051-04f0-5651-89cc864d902c.png)

1. 表示したい問題のRadio Boxにチェックを入れ、Displayボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227269/73daf1a3-1005-c5a3-ddab-379c66ab11ff.png)

この時、Only submissions in contestにチェックを入れてDisplayボタンを押すと、コンテスト中に提出されたプログラムだけで集計し可視化します。

# 技術的な話など
Webアプリを作るにあたって、 ~~僕はケチなので~~ お金がかかるものは嫌でした。なのでサーバーを必要とせず、フロントだけで完結する構成を考えました。以下が構成になります。(こういう図を作るのは初めてなので見にくかったり間違いがあったりするかもです…)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227269/000bc2fc-98ce-24b4-1bcb-4ac0c2c44eb7.png)

基本的には、[AtCoder ProblemsのAPI](https://github.com/kenkoooo/AtCoderProblems/blob/master/doc/api.md)を用いてJSONを取得し、色を付けていくだけです。
しかし、AtCoder Problemsには、各問題に提出されたプログラムの情報を取得するAPIはありません。代わりに提出されたすべてプログラムの情報を保持するデータセットがあるので、それをいい感じに使うことにしました。

## 工夫
上述したデータセットはgz形式に圧縮されたcsv形式のファイルです。展開後のデータ総量は1.2GBもあるので、直接Webページで持つには少し無理があります。
ところで、このデータセットは各提出について以下の情報を持っていました。

- 提出時間
- 問題ID
- コンテストID
- User ID
- プログラミング言語
- プログラムの長さ
- 結果
- 実行時間

本アプリにおいて、これだけ多くの情報を持つ必要はありません。使うのはせいぜい「提出時間、問題ID、コンテストID、プログラミング言語、結果」あたりでしょう。更に、あらかじめ「コンテスト内に提出されたか」を計算し、非ACコードは情報を持たないことでデータ量を圧縮できそうです。
また、本Webアプリにとって、1提出ごとに情報を持つよりコンテストごとに情報を保持しておいたほうが扱いやすいです。また、問題ごとに情報を持つ場合、「ある言語でACしたコードがいくつあるか」のみを保持すれば良いので更にデータの圧縮を行えます。
[main.py](https://github.com/Inazuma110/atcoder_language_visualizer/blob/main/main.py)で圧縮を行ったところ、336KBまで圧縮できたので、無事リポジトリにおけるサイズとなった。

また、この圧縮したデータをGitHubのリポジトリに置くことで、これらのデータをローカルファイルのように扱うことができ、自分で用意したサーバーなどでデータを保持する必要がなくなります。

## 改善点・反省
- Vue.jsのコンポーネントをどこまで細かくするべきなのかわからなかった。
- コンポーネント間のデータのやり取りがよくわからなかったので、問題の検索から可視化まですべて1つのコンポーネントにまとめてしまっている。
- データセットは1週間に1度更新されるので、リポジトリに置くデータを手動で更新しなければならない。
- ローカルのソースコードをデバッグする時、ファイルのデータにアクセスできない。CORSの設定を適切にすれば良いみたいだが、どこで設定すれば良いのかよくわからなかったので頻繁にデプロイしてGitHub pagesを見てデバッグする必要があった。
- Chart.jsによる円グラフの表示がスマホだと小さくなりすぎて見にくい。どうにかしたい。
- Fuzzy検索で表示する問題の閾値をもう少しゆるくしてもいいかも?

## 知見
- Bootstrapをはじめとした、各種ライブラリをCDNを用いて簡単に利用できるはめちゃくちゃ便利

# 可視化結果を見て得た知見
ぼんやり結果を見てわかった知見です。ちゃんと分析するなら、言語の割合の推移などを可視化する必要があると思います。

## 昔
- 昔のコンテストではRubyの提出がかなり多い。1位C系言語、2位Java or Pythonだと思っていたのでかなりびっくり
- HaskellやPerlなんかも上位に
- (当然だが)提出数は今と比べてかなり少ない

## 最近
- やっぱりC++が多い
- pypyと合わせてPythonも増えてる
- Rustが増えてる

## マラソン
- アルゴ系のコンテストでは全く見なかった「Text」がいくつかあった。

# まとめ
作る前に思い描いていたものが無事作れたので嬉しいです。このWebアプリが無事に完成したのはひとえに[AtCoder problems](https://kenkoooo.com/atcoder/#/table//)のおかげです。ありがとうございます。

他に改善点などありましたら、コメントやIssue、PRなどでお願いします。
リポジトリ→https://github.com/Inazuma110/atcoder_language_visualizer
<a href="https://github.com/inazuma110/atcoder_language_visualizer"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/inazuma110/atcoder_language_visualizer.png" width="460px"></a>