岐阜だからさElixir

試していることなど...需要がないかもしれないけど細々とアウトプットしてます

未経験者にプログラミングを教えて得られた知見と反省点

ちょっと前にプログラミングを勧めた

地元の後輩が何をしていいか分からず悩んでいるとのことで
「とりあえず損することはないからプログラミングをやっといたら?」
と責任があるのか無責任なのか分からない一言を発する

プログラミングを勧めている理由は
自身も情報学科ではなかったが独学でプログラミングを学習して世界変わったなと思っているため

これが約3ヶ月前のこと
入門しやすい

あたりをやればいいんじゃないかな?と細々と伝えたつもりが
なぜかJavaを選択(同期の友人が情報学科でJavaを勧められたそう)
組み込みとかやりたいなら、まぁいっかとは思いつつも
大学で授業受けたりするわけでもなく独学でのファースト言語がJavaだとつまずきそうだなぁ~と思ってた
(別にJavaをディスってるいるわけではないのでご了承ください)

1ヶ月ぐらいは適度に連絡を取り、状況報告を受けていた
基礎の文法が終わって今からポートフォリオ(自作のRPGだそう)を作り出すというところですという連絡が最終連絡だった
それから音沙汰なし。こちらから連絡するも返事は無かった

しかし、2ヶ月ぐらい経った頃、再び彼と会う機会があったので現状の確認がてら話を聞いてみた(Aとしとく)

僕「最近の学習の調子はどうなのよ?」
A「いや、正直飽きてしまいました」
(やっぱりな〜)
僕「何が面白くなかった?」
A「あっちをいじるとこっちがダメになって訳の分からないエラーが出ての繰り返しで...」
A「あと完成見えなくてモチベーションが保てません」

だいたい以下のどれかにつらみを感じて継続不可になる
いい感じに初学者あるあるにハマってるなと

  • 入門言語の難易度の問題(学習コスト)
  • 学び方の問題
  • モチベーションの保ち方(進め方)の問題

Aの場合は
=> 入門言語の難易度の問題 から モチベーションの保ち方(進め方)の問題 へのリレーだった

そんなこんな話を聞いて一度、Pythonを教えてみることになった
以下、Pythonの入門記事ではないのでさらっと流してください

何を教えたのか

プログラミング言語のレクチャーで何に触れたのかをざっくりとまとめる
完全な初心者ではないものの、一度0からやりたいとのことだった

hello world
最も基本的な値の表示

print("hello world!")

値の型について
値には種類があるんやで〜という話

num = 3 #integer
text_val = "hello world" #string
f_num = 3.14 #float
is_match = True #bool

演算子
基本的なものだけ

5+6 #11
3.14 * 2 #6.28
"hello" + " world" #hello world
5 > 4 #True
5 < 4 #False
"hello" == "hello" #True
"hello" != "hello" #False

ifの文法

num = 10
if num > 5:
  print("over")
else:
  print("lower")

num = 5
if num > 5:
  print("over")
elif num == 5:
  print("equal")
else:
  print("lower")

この時点で一度、FizzBuzzを解かせてみる
ifの判定順(3かつ5の倍数=15の倍数か)に悩むものの、割とすんなり解いてくれた
%演算については事前に教えた

num = 15

if num % 15 == 0:
  print("FizzBuzz") #FizzBuzz
elif num % 3 == 0:
  print("Fizz")
elif num % 5 == 0:
  print("Buzz")
else:
  print(num)

配列について
まず、こういうのやめようなって話をした
なぜ配列が必要なのかを伝えたかった

score1 = 98
score2 = 40
score3 = 89
score4 = 100
score5 = 32
:
:
score100 = 54

配列使おうぜ

nums = [1,2,3,4,5]
fruits = ["apple", "banana", "peach", "orange"]
any = [True, None, 1, "banana", 3.14]

#値の取得(indexは0から始まる)
nums[0] #1
nums[4] #5
nums[5] #error!

思った通り、配列から値を全部取り出すにはどうすればええですか?と質問が来る
forってのがあると自然な流れでループ処理に行けた

forの文法について
ざっくりと

nums = [1,2,3,4,5]

for num in nums:
  print(num)

# 1
# 2
# 3
# 4
# 5

for i in range(0, 4):
  print(i)

# 0
# 1
# 2
# 3

for i in range(4):
  print(i)


# 0
# 1
# 2
# 3

さっきのFizzBuzzをfor組み合わせて書かせたくなったので
range(101)でFizzBuzzをやってもらった
また後で詳細は記述するがこの時点で割とつまっていた
20分ぐらいして上手く動く

for num in range(101):
  if num % 15 == 0:
    print("FizzBuzz") #FizzBuzz
  elif num % 3 == 0:
    print("Fizz")
  elif num % 5 == 0:
    print("Buzz")
  else:
    print(num)

# FizzBuzz
# 1
# 2
# Fizz
# 4
# Buzz
# Fizz

関数について&文法
時間も差し迫っていたので最後に関数について触れた
まずは関数が何なのかという説明をする(厳密な定義ではない)

#関数って何? => 値をもらったらその値を変化/変換するやつ

def add_10(x):
  return x + 10
  
#もらった値に+10変化(変換)している
print(add_10(10))

def greet(user):
  res = "hello " + user
  return res
  
#user名にhelloを付与
print(greet("okb"))

総まとめ

最後にFizzBuzzのfor内の処理を関数化してもらった
この部分でもかなりつまった

def fizzbuzz_func(num):
  if num % 15 == 0:
    return "FizzBuzz"
  elif num % 3 == 0:
    return "Fizz"
  elif num % 5 == 0:
    return "Buzz"
  else:
    return num

for num in range(0, 101):
  print(fizzbuzz_func(num))

#結果省略

1日で行なったことをまとめると

  • 値の出力
  • 変数と型について
  • 演算子
  • ifの文法
  • FizzBuzz
  • 配列
  • forの文法
  • 関数についてと文法
  • FizzBuzzの関数化
  • 他、いくつか例題

と割と盛りだくさんだった
この学習を通して何度かプログラミングを教える難しさを感じたので
前振りが長くなったが共有をしていく

print関数とかlen関数ってどこから呼ばれてるの? どこに書かれているの?

自分で関数を実装するようになって何度か聞かれた
どこにもprint()やらlen()を記述していないのになぜこれらのメゾットが使えるのかが分からないと言われた

def add_10(x):
  return x + 10

#どこにある?
#def print(val):
#:
#:
#:

print(add_10(5)) #15
#このprintはどこから呼ばれてるの!?

自分の中では「そういうもの、用意されているもの」という認識だったが
これが腑に落ちないらしい

この言語にはこういうメゾットがあって...という説明をすることで分かってもらえた
車を運転するのに内部構造を100%理解している必要はないのと同じことだが
低レイヤーの知識も説明できる程度に必要だと反省

書いた関数が実行されない

関数を遊びで作っている時に言われた

def greet(name):
  print("hello " + name)
  return True

「今、実装した関数が動かないんですが...」と言われコードを見てみると
関数の呼び出しが見つからなかった
これが書いてるだけで

def greet(name):
  print("hello " + name)
  return True
greet("okb")

という記述がない
これは関数は呼び出して初めて実行されるという認識が無かったために起きた

関数に取り組むまで単純なコードしか書いておらず
コードは上から下に順番に実行されるものだと(半分正解)思わせてしまった
関数は呼び出して初めて実行されるということをきちんと説明するべきだった

配列や関数の使い所がイメージできない

配列やら関数の文法を一通り、教えた後に例題に取り組んでいる時に発生した
書き方を知ったところで使い方が全くイメージできないとのこと

「配列や関数が便利なのは分かるが、じゃあ使うべきっていう境界線はどこにあるの?」

確かに。明確に言語化しようとするとかなり難しい
そもそも僕はプログラミングの記述に推奨はあっても100&の正解はないと思っている
同じ命題に対しても記述されたコードは余程のことがない限りは一致しない

完全パターンなんてものは存在しないため、「やってる内に分かってくるよ」としか言えなかった
自分の頭の中には「〜この時に使うべき」というべきレシピパターンがあるが言語化は出来ない

過去に自分が書いたコードを見せて、こういうところで使ったでと実物を見せてあげねばと反省
しかし、複雑すぎるものや可読性の悪いものを用意すると混乱を招くので要注意

総評

まぁ分かるけどピンとこない

今思えば、車を作るために各パーツの勉強をするのと
車を作ることを知らずに各パーツの勉強をするのとでは圧倒的に気持ちに差がでるなと思った

プログラミング教育では文法やお作法について最初に取り組むことが多いが
その前に、これからやることをマスターすることで最終的にこういったことが出来るようになります
ということを提示してあげられればと思った

理想形は先に作成物が決まっていて、文法を覚えながら作成物完成までのステップを辿っていくような
ディアゴスティーニのような形

これも個人によって好き嫌いが分かれるので用意するのは難しい

個人的所感をまとめておくと

  • 文法のゴリ押しはNG
  • 知ってる前提で話さない

またAにPythonを教える機会がありそうなので適宜、レポートをまとめたいと思う