# 自宅研修について
まずは配属おめでとうございます。
研修お疲れさまでした。
皆様方の毎日の取り組みは、日報で興味深く拝見しています。
研修を通じてプログラミングとシステムについて様々な気付きを得ましたね。引き続き定着に向けて取り組んでいきましょう。
今年はコロナ対応のため、ご自宅で待機していただく日が半数ほどあります。これを逆にチャンスととらえて、プログラムを書く訓練を存分にしていきましょう。目指すは思考の道具としてプログラミングを使いこなすことです。
皆さまの配属先ではJava以外にも複数の言語を使います。演習では同じ課題を複数の言語で提出することにも取り組んでもらいます。最初は混乱するでしょうが、より本質的にそれぞれの言語を理解することにつながりますので、悲嘆せず前向きに取り組んでください。
## 狙い
- 単純な練習問題を反復的に解きプログラム技能を定着させる
- 新しい問題を読み解きプログラムに落とし込む設計力を鍛える
- 自分のミスを発見する=バグ修正能力、テスト力を鍛える
- 基本的なWEBシステムを調査する力を向上させる
## 課題
- プログラミング研修 Java/c#/javascript/Python/ruby
- WEBシステム調査研修
- バッチ研修
- WEBシステム構築研修
# 1. プログラミング研修
プログラミング研修については`AtCoder`というプログラミングコンテストのサイトの過去問題を利用します。問題提出・添削のため、以下の設定をあらかじめお願いします。
- AtCoderへのユーザー登録
https://atcoder.jp/register
- 練習問題の提出
https://atcoder.jp/contests/abs/tasks/practice_1
- githubへのユーザー登録
- AtCoderProblemsへのログイン
https://note.com/akihanari/n/naa256e8cf133
- Virtual Contestへの参加(join)
https://kenkoooo.com/atcoder/#/contest/show/ec4b5aff-acc3-4703-98e2-c801d885a9f2
練習問題は、見本をコピーして、提出欄に張り付けて提出ボタンを押せば大丈夫です。練習問題を提出したら結果確認のページのリンクをメールで送付してください。
https://atcoder.jp/contests/abs/submissions/12957078
折り返し、質問・添削用チャット(slack)の招待リンクを送りますので参加してください。毎日の問題集のリンクなどチャットで送りますので、毎日参照するようにしてください。
## 1.1 プログラムの実行環境について
自宅PCにeclipseがあるなど自身で環境を構築済であればそちらを利用してください。もし環境が無い、間に合わない場合、以下のpaiza.ioを利用しましょう。
https://paiza.io/ja
- コードを作成してみる(無料)をクリック
- 左上の緑のプルダウンメニューから使用する言語を選ぶ
- 中央の黒い部分にプログラムを記載
- 画面下の入力タブに入力データを記載
- 緑の実行ボタンを押す
- 出力結果を確認
※環境構築は楽しいですが、構築に時間を取られて問題を解く時間をなくしてはダメです。1日にかならず10問は解ききるようにしましょう。最終的には1問10分で解けるスピード感を目指します。
## 1.2 進捗報告
問題セットと同じ名称のタグをつけたチャンネルをslackに準備します。
開始時、および1時間ごとに状況を発信しましょう。
何問目まで解けたのか、今何に取り組み・悩んでいるのか。
## 1.3 質問・添削
疑問があったり確認したいことができたら、質問・添削用チャットで発言してください。自分の書いたソースコードに関する質問(「なぜ動かないのか」「どこが悪いのか」)は提出結果のリンクをチャットに張り付けてください。
これ以外の方法ではソースコードが他人には見えませんのでご注意ください。
各問題について、必ず講師が回答例を投稿してあります。また、早めに取り組みを始めた同期の回答例も確認できます。どうしても問題の解き方がわからなければ、コードを引き写して回答してください。
ただし、コードの丸写しは学習効果を著しく低下させます。写す場合でも一つ一つの意味を理解しながら行うようにしましょう。
また、工夫して上手に書けたので評価してほしい(スタティックメソッドの活用とか、独自クラスの実装とか)とか、講師の書いたプログラムへの疑問や改善提案なども成長につながりますので歓迎します。
# 2. WEBシステム調査研修
配属先ではWEBシステムをたくさん取り扱うことになりますが、不具合が発生したときに原因を調査することも我々の重要な業務です。調査に必要な知識は、「Web技術入門」や「ServletJSPプログラミング」などの研修で身に着けてきましたが、調査に必要な技術を定着させるため、手を動かした研修を行います。
- 調査対象WEBページへのアクセス
https://lqheqh2cf2.execute-api.us-east-1.amazonaws.com/dev
上記ページは研修用に準備したものですが、10個のフラッグという秘密情報が隠されています。フラッグを獲得するには、実際のWEBシステムの調査と同じ方法を調べて実践する必要があります。
10個のフラッグをすべて見つけましょう。
## 2.1 報告
slackのctf001チャンネルに、見つけたフラッグ番号を報告しましょう
## 2.2 すべてのフラッグを見つけたら
10個のフラッグを全て見つけたら、研修用サーバのプログラムコードがすべて入手できます。サーバの機能を改造したり、問題を追加したり、「MVC演習」で得た知識を活用してみましょう。
# 3.バッチ研修
プログラム研修で提出したプログラムの採点結果は、jsonというデータフォーマットで一括で取得することができます。これを集計するバッチプログラムを作成してみましょう。
## 3.1 jsonデータの取得
以下のURLを表示させてみましょう。
`{user_id}`の部分は自分のAtCoderのIDに置き換えます。
```
https://kenkoooo.com/atcoder/atcoder-api/results?user={user_id}
```
次のようなデータが表示されます。拡張子.jsonを付けて保存しましょう。`json`フォーマットについては、検索エンジン等を使って調べましょう。
`
[{"id":10324140,"epoch_second":1582530416,"problem_id":"caddi2018_a","contest_id":"caddi2018","user_id":"tamura2004","language":"Ruby (2.3.3)","point":300.0,"length":152,"result":"AC","execution_time":52},{"id":10324121,"epoch_second":1582530358,"problem_id":"caddi2018_a","contest_id":"caddi2018","user_id":"tamura2004","language":"Ruby (2.3.3)","point":0.0,"length":151,"result":"WA","execution_time":52}]
`
ここで各キー項目の意味は以下の通りです
|キー名称|説明|
|:--|:--|
|id|各提出に付与された一意の番号|
|epoch_second|エポック秒|
|problem_id|問題識別名|
|contest_id|コンテスト識別名|
|user_id|ユーザーID|
|language|使用言語|
|point|問題の配点|
|length|提出プログラムのバイト数|
|result|AC,WA,TLE,REなどの結果|
|execution_time|実行時間ミリ秒|
## 3.2 データの分析
以下のような観点で、データを集計・分析してみましょう。
1. 総提出件数
2. 総AC数、WA数、TLE数、RE数。
3. 提出プログラムの合計行数。ただし、1行=30バイトと仮定する
4. 上記3のうち、ACのみカウントする
5. 上記4のうち、同一問題は最も長いものをカウントする
6. 上記4のうち、同一問題は提出時間が最も早いものをカウントする
7. 上記2を配点が同じグループごとに集計。
8. 上記2,3を、日本時間で同じ日ごとに集計。
9. 上記8を、最初と最後の問題の初回AC時刻の差分、最初の問題の問題ID名で出力(最速タイム)
10. 上記9に、AC以外の結果1件毎に5分のペナルティを付与
11. 上記10のうち、AC出来なかった問題はペナルティを付与しない
最後の11番の集計が、本番のコンテストの集計に近いものになります。
### 例1
2番のプログラム例です。言語でrubyを選択するとどう支えて確認することができます。`java json`などで検索してみると、javaでの方法を調べることもできると思います。
```ruby
require "json"
class Problem
attr_accessor :a
def initialize
@a = JSON.parse(gets)
end
def solve
a.each_with_object(Hash.new(0)) do |record, ans|
ans[record["result"]] += 1
end
end
def show(ans)
ans.each do |key,value|
puts "#{key}: #{value}"
end
end
end
Problem.new.instance_eval do
show(solve)
end
```
誤答率24%でした。
```
AC: 1650
WA: 334
RE: 87
TLE: 83
CE: 18
MLE: 3
```
### 例2
`jq`というツールで加工を行ってからプログラムで処理することも出来ます。
https://qiita.com/amemolee/items/ec1f1f2eab1c4c25a2f9
以下の様なコマンドでCSVに変換できます。
```
$ cat input.json | jq -r '.[] | [.problem_id, .result] | @csv'
```
出力結果
```
"m_solutions2020_a","AC"
"m_solutions2020_e","WA"
"m_solutions2020_c","AC"
"abc161_c","AC"
"abc167_c","AC"
"m_solutions2020_d","RE"
"abc170_c","WA"
"abc104_a","AC"
"abc077_a","AC"
```
### 3.3 報告
slackの「バッチ研修」チャンネルに、問題番号と合わせて結果を貼り付けましょう。
プログラムコードについては、harigami.jpなどのサービスを利用させていただき、リンクを貼り付けましょう。
https://harigami.jp/cd?hsh=1125727f-85bc-4d1c-8d0a-32ee8e0e0c2d
https://harigami.jp/
> 注意!atcodr-apiもharigamiも善意で運営されているサイトです。高い負荷をかけてしまわないように気を付けましょう。手動でデータを取得する分には問題ありませんが、プログラムから自動で取得する仕組み(スクレイピング)を行い、秒間何十回ものアクセスをしてしまうと、高い負荷によりサービスをダウンさせてしまったり大変迷惑をかける恐れがあります。スクレイピングを行う場合は、適宜waitを入れるなど注意しましょう。
### 3.4 発展
学習効果や成長を図るにはどんな分析をしたら良いでしょうか。
分析の方針を立てて、それを検証する集計方法についてプログラミングしてみましょう。
例えば・・・
- 成長しているなら間違いを修正する速度が早くなっているに違いない。
- 各問題の初回WAから初回ACまでの時間と、それまでにACした問題数の相関を調べてみよう
- きっと強い正の相関があるはずだ