やわらかテック

興味のあること。業務を通して得られた発見。個人的に試してみたことをアウトプットしています🍵

VSCode使って初学者とコードレビュー兼ペアプロしてみた感想

やってもらった課題

未経験者にプログラミングを教えて得られた知見と反省点と登場したA君に
やってもらっていた課題が完成しましたとの報告が届いた

ちなみにどんな課題をやってもらっていたかというと

name score subject
Kennith Kling 18 math
Oliver O'Connell 36 math
Nicole Gutkowski 6 math
Blanche Deckow 19 math

こんな感じの.csvファイルがあって
このファイルをpythonで読み込んでscore(点数)を合計してprintするというもの
pandasやらは使わずにwith open使って集計してほしいなと淡い期待を抱いて課題を作った

sum_ = 18 + 36 + 6 + 19
print(sum_) 

変数から関数の実装程度までは以前、触ってもらっていたのであまりハマるポイントはないかなと思う
かろうじて、ハマるかなと思っていたのはcsvのheaderを読み飛ばす部分
まぁググれば出るし大丈夫でしょ(適当
あとは合計用の変数を上手く扱ってくれるかどうか(scope問題->毎回0になってる)

完成したとの報告が

課題を出して2日ぐらいで「とりあえず完成しました」との報告があった
ただ平日で面会できる時間も取れないのでどうしたものかと思ったが
そういえばVSCodeペアプロが出来るようになったことを思い出し、急いで調べてペアプロ環境を用意した

VSCode拡張機能の検索欄で「Live Share」と検索してインストール
そうするとVSCodeの下部にLive Shareという項目が追加されるのでこいつをクリック
f:id:takamizawa46:20190519163514p:plain:w450

クリックするとリンクがコピーされるのでペアプロをしたい相手にこのリンクを教えてあげる
あとはこのリンクをクリックしてもらうだけで相手がやってくる
f:id:takamizawa46:20190519170347p:plain:w550
嬉しさのあまりSkype繋いでいるのに画面上でチャットを始める

まずは彼が作成してくれたコードを原文のままにご紹介する

import csv


read_file = "score.csv"

with open(read_file, newline='') as csvfile:
    reader = csv.reader(csvfile, delimiter=',', quotechar='|')

    header = next(reader)
    scores = 0
    for data in reader:
        scores = scores + int(data[1])

うん、とりあえず懸念していた点は全てクリアしてきてくれた!!
これはアカンなって気になる点は特にはないがこのままだと使い勝手が少々悪いので
まずは関数化してもらうことにした

関数化する理由を納得させることが出来ない

しかし、どうやらまだ関数化という考え方に若干ピンと来ていないようで
どういう時に関数化にするんですか?とよく聞かれる
完全な関数化条件は無いものの、「使い回したい時、その可能性がある時」と答えている

ペルソナを考えてみると分かりやすいのかな
彼が作成したこのコードを数学のテスト結果がまとめられた.csvファイルにのみ実行させていたが
他教科の採点もしたくなったとすると
このままだとコードを直接編集して書き直す必要がある

#read_file = "score.csv"  
read_file = "score2.csv"

これは面倒なので少なくともargment parserは使わないとして
関数に引数渡しで対象のファイルを変更できるようにはしておきたいという発想になる

これは面倒なコード編集をした過去があるからそう思うのかもしれない
それを伝えたいのだが中々、言葉足らずになってしまう

まぁとりえあず文法覚える意味も込めてやってもらうことにした

関数を作成する際のレシピ

いつもどういう事を思って関数を作ってるのかということを聞かれたので
自分なりのレシピを書き出して説明してみた(受け売りですが

## 関数を作る時のレシピ
### 何がしたいのか
### 何の値を受け取るのか(引数は何)
### 何の値を返すのか
### 関数の名前(意外と重要)

これを上から埋めてもらった。今回作りたいファイル名を受け取って合計点を算出するというプログラムではこんな感じに落ち着いた

## 関数を作る時のレシピ
### 何がしたいのか,何ができるのか 
--> csvファイルを開いて点数を合計する
### 何の値を受け取るのか(引数は何) 
--> テスト結果ファイル
### 何の値を返すのか
 --> 合計した点数
### 関数の名前(意外と重要)
 --> goukei

このレシピを元に関数を作ってもらった
文法でつまずく(indentやらreturn)部分はあったが本人も納得して関数を作ってくれた
VSCodeで同時編集しながら彼がどういう過程でコードを書いていくかという事を見ることが出来るため
自分の盲点になっている点が多く説明が良く無かったなと非常に勉強になる
あと自分が本質的に理解出来ていなかった部分が浮き彫りになったりする(print関数はどこに実装されてるのか(前回参照))

逆に自分がどのような過程でコードを生成しているかを見せられるので速習になるのではないかと勝手に思っている

def goukei(file):
    with open(file, newline='') as csvfile:
        reader = csv.reader(csvfile, delimiter=',', quotechar='|')
        header = next(reader) #headerを読み飛ばす
        scores = 0
        for data in reader:
            scores = scores + int(data[1])
    return scores

そしていかにファイルの変更が楽に行えるかを説明する

read_file = "score2.csv"

with open(read_file, newline='') as csvfile:
    reader = csv.reader(csvfile, delimiter=',', quotechar='|')

    header = next(reader)
    scores = 0
    for data in reader:
        scores = scores + int(data[1])

print(scores)

#--------------------------

read_file = "score2.csv"
: #省略
:
print(scores)

#関数なら?
res1 = goukei("score2.csv")
res2 = goukei("score.csv")

その場でついでにもう1つ課題を与える

時間があったので関数化のレシピを使いつつ、もう1つ課題をこなしてもらった

こういうデータがある

data = [
    ["A", "B", "A", "AB", "O", "O"],
    ["B", "B", "AB", "A", "B", "O"],
    ["O", "B", "A", "B", "A", "O"],
    ["A", "A", "A", "AB", "O", "A"],
    ["A", "O", "A", "AB", "O", "O"],
    ["B", "B", "A", "O", "O", "O"],
]

このデータ(2次元のリスト)から指定の血液型がいくつ含まれているかをカウントしたい

print(bloody_count("A")) #n
print(bloody_count("O")) #m

説明する事も特になく、すんなりと実装してくれた
ついに配列に用意された.count関数を使い始めた。言語の関数を使って簡略化することは非常に良い事

def bloody_count (blood_type):
    all = 0
    for bl_count in data:
        all += bl_count.count(blood_type)
    return all

print(bloody_count("A")) #12
print(bloody_count("AB")) #4
print(bloody_count("O")) #12
print(bloody_count("B")) #8

VSCodeで作成する過程を見ていると先ほどと手を動かす速さが違うことに気づく
何をすればいいかということが頭の中で理解できている状態であれば実装ってのは割とすんなり出来るんだなと実感
やっぱりペアプロっていいね。誰が教えてください

おまけのコーナー

なんでデータいじくる系の課題ばかりをやらせているの

これは完全にElixirの思想に染まっているからかもしれない
プログラミングでやることってのは大概がデータ処理
Aを変換してBにするという連鎖であって1つ1つは大したことはしていない

まずはデータをいじくる過程を体感してもらうことを大切にしている
個人的には、いきなりDjangoとかRailsとかをやらせるのには反対

データの動きで見えない部分が多すぎるからです
かといって文法だけをひたすら覚えさせるのも良くない
どういうデータ処理を行う場合に使えるのかを合わせて覚える必要がある
そのためにもこういう課題を用意している

教える際に気をつけている事

とりあえずは実装してもらうことを優先している
あきらかにその使い方はないでしょと思っても言わずに、その方法で解決できるように導くようにしている
その後で「実はこういうやり方があってね?」と自分の中でより楽に済む方法を紹介して「確かに」と思ってもらうようにしている
前が見えずにコードを書いている人に、それはダメといきなり言っても理解してもらえずモチベーションを奪うだけなので