LoginSignup
474
186

More than 1 year has passed since last update.

生徒の努力を得点じゃなく、「音ゲー」のようなリザルト画面で評しました!

Last updated at Posted at 2022-01-16

フランスの大学院で先生の仕事をしながら、生徒のためにいつも新たな教え方を探しています。僕はプログラミングのレッスンをしているので、課題として生徒は応用問題を解かなければいけません。

会社に仕事、学校の教育でも、先輩からもらった感謝が第一であるって僕は絶対に思います。今回は先生として、先輩になるからこそ、感謝の正しい伝え方を探しました。生徒の努力をちゃんと認めたら、自然に頑張ります。

生徒には得点を伝えなければならないけれど、応用問題がよくできたかどうかも伝えたい。でも結局、それは十分じゃないと思いました。最初は、応用問題に関して生徒の努力をはっきり感謝したい。そうしたら頑張らなかった生徒は悔しくてやる気になって、よく頑張った生徒はもっと頑張ります。


得点のかわりは、何?

勇気付けられる物を考えたら「音ゲー」、すなわちリズムゲームを思いだしました。一曲遊んだ後で、リザルト画面は文字スコアで評価を見せます。

あまりできなかったら「B」スコアになり、普通にクリアしたら「A」スコアがあって、もっと上手にできたら「S」スコアがあって、それに完璧だったら「SSS」スコアがあります。これなら評価はわかりやすいし、なら次回はもっと頑張りたい、と感じるようになります。

これを思い出したとたん、文字スコアの利用をすぐに決めました。

chunithmresult.jpg

「チュウニズム」アケードゲームのリザルト画面(©SEGA)️

上の画像のように、文字スコアは一番大きいテキストですね。その他は、細かいことについてのデータが見れます。リザルト画面は基本的に明るくて、かっこよくて、そして前回からの伸びがわかります。

文字スコアだけじゃなく、応用問題についての細かい説明も表示するのがいいでしょう。例えばソースコードに関して評価をします。そして応用問題の目的がちゃんとできたかどうか、構文規則が悪いかどうか、バグが多いかどうかも表示します。

maimairesult.jpg

「maimai」アケードゲームのリザルト画面(©SEGA)️

その上maimaiの画面では、画面下にプレイした時間と場所が見れます。それでは、応用問題の名前と日付も書きましょうか。


リザルト画面のやり方

まずどこかのファイルに生徒の評価を書かなければなりません。簡単な記入のために、エクセルがいいと思いました。エクセルファイルは後でPythonで読みやすいし、そして余白イメージにデータを印刷するつもりです。


テンプレートのイメージ

さて、印刷されられるイメージを作りましょう。いつも通り僕はAffinity Designerを使いますが、別のソフトでも大丈夫です。

後でPythonでイメージにテキストを印刷するので、空欄が必要です。リズムゲームのような感じにしたいから、カラフルで読みやすいデザインにしました。このファイルはtemplate.pngという名前にしましょう。

template.png

例のために日本語に変えちゃった

テキストを印刷するために、空欄の座標を書いておきましょう。イメージ本体のサイズは2048px*1024pxで、応用問題の名前の空欄の座標は(1296,196)、日付の空欄の座標は(1298,902)、などなど。

そして、使用可能なすべての文字スコアは別のイメージでおいて置きましょう。

letters.png

文字スコアのイメージ


エクセルファイルの用意

評価はあるエクセルファイルにまとめるつもりなので、準備しましょう。1行目には応用問題の名前、日付、レッスンの名前を書いておきます。以降、一行一人、生徒の評価を書いておきます。

excel.png

エクセルファイルの例

Pythonを使うときのため、データがどこにあるかを覚えましょう。応用問題の名前は「B1」セル、日付は「D1」セル、レッスン名は「F1」セルです。そして3行目からは、生徒の評価です。一番目の生徒のランクは「C3」セル、構文規則ランクは「D3」セル、などなど。

このファイルはnotes.xslxとしましょう。


Pythonで読んで印刷

テンプレートイメージとエクセルファイルが完成したら、Pythonで生徒の結果のイメージが印刷できます。

printer.py
import os
import argparse

from PIL import Image, ImageDraw, ImageFont
from openpyxl import load_workbook

#色んなサイズのフォントの準備
font_bold_60 = ImageFont.truetype("MPLUS1p-Bold.ttf", 60)
font_bold_52 = ImageFont.truetype("MPLUS1p-Bold.ttf", 52)
font_bold_28 = ImageFont.truetype("MPLUS1p-Bold.ttf", 28)
font_medium_32 = ImageFont.truetype("MPLUS1p-Medium.ttf", 28)

#argparseのおかげで使いやすくなります
parser = argparse.ArgumentParser(description="ある応用問題の結果を印刷差し上げます。")
parser.add_argument("spreadsheet", help="表計算ファイルの名前")
args = parser.parse_args()

#ファイルを開く
excel = load_workbook(args.spreadsheet)
#一番目の表計算を使う
sheet = excel.active

#データを読んでおきます
exercice_name = sheet["B1"].value
exercice_date = sheet["D1"].value
exercice_lesson = sheet["F1"].value

#3行目から表計算を読んで、10列目まで
for row in sheet.iter_rows(min_row=3, max_col=10, values_only=True):
    #一つ行からデータを引き出す
    lastname, firstname, rank, syntax_rank, syntax_note, objective_rank, objective_note, quality_rank, quality_note, notes = row

    #ランクがない場合は多分、結果の打ち込みがまだ
    if rank is None:
        print(f"空きランク、スキップ...")
        continue

    print(f"--> {lastname} {firstname} ● ランク {rank}")

    #テンプレートのイメージを開く
    with Image.open("template.png") as im:
        draw = ImageDraw.Draw(im)

        # テキストの印刷
        draw.text((92, 80), f"{lastname}\n{firstname}", font=font_bold_52, fill=(0,0,0))
        #anchor="mm"の意味は、中央揃えで書く
        draw.text((1296, 196), exercice_name, font=font_bold_60, anchor="mm", fill=(255,255,255))
        draw.text((1298, 902), exercice_date.strftime("%d/%m/%Y"), font=font_bold_28, fill=(0,0,0))
        draw.text((1610, 902), exercice_lesson, font=font_bold_28, fill=(0,0,0))
        #ここからは複数行テキスト
        draw.multiline_text((500, 384), syntax_note or "", font=font_medium_32, anchor="lm", fill=(0,0,0))
        draw.multiline_text((500, 544), objective_note or "", font=font_medium_32, anchor="lm", fill=(0,0,0))
        draw.multiline_text((500, 704), quality_note or "", font=font_medium_32, anchor="lm", fill=(0,0,0))
        draw.multiline_text((280, 870), notes or "", font=font_medium_32, anchor="lm", fill=(255,255,255))

        #文字ランクのイメージのサイズが違っているので、
        #中央揃えのために、正しいx位置を書いておこう
        ranks_x_position = {
            "B": 1496,
            "A": 1466,
            "S": 1490,
            "SS": 1384,
            "SSS": 1278
        }

        #文字ランクのイメージの印刷
        with Image.open(f"rank_{rank}.png") as im_rank:
            im.paste(im_rank, (ranks_x_position[rank], 486), im_rank)

        #構文規則ランクのイメージの印刷
        with Image.open(f"rank_{syntax_rank}.png") as im_syntax_rank:
            im_syntax_rank.thumbnail((94, 94))
            im.paste(im_syntax_rank, (380 if syntax_rank != "A" else 375, 340), im_syntax_rank)

        #目的ランクのイメージの印刷
        with Image.open(f"rank_{objective_rank}.png") as im_objective_rank:
            im_objective_rank.thumbnail((94, 94))
            im.paste(im_objective_rank, (380 if objective_rank != "A" else 375, 500), im_objective_rank)

        #コード質のイメージの印刷
        with Image.open(f"rank_{quality_rank}.png") as im_quality_rank:
            im_quality_rank.thumbnail((94, 94))
            im.paste(im_quality_rank, (380 if quality_rank != "A" else 375, 660), im_quality_rank)

        #最後はイメージを保存する
        im.save(f"{firstname} {lastname} - {exercice_name}.png")

スクリプトを実行する前に、フォントのファイルをダウンロードしなきゃいけません。たとえばM+1フォントはGoogle Fontsからみつけます。そして、スクリプトはprinter.pynotes.xlsxのエクセルファイルを使いたかったら、ターミナルで実行のはこのようになります。

$ python printer.py notes.xlsx

数秒後、一生徒一枚のイメージが保存されます。

守 田中 - 福岡地下鉄.png

できたイメージはこういうものです。


生徒たちへの影響

多分、一番知りたいことでしょうか。基本的に、生徒が自分の能力をちゃんとわかるように、そして後でどうしたらいいかわかるようにするために、役に立ったと思います。

それなのに、次の応用問題を提出してもらったときに、たまに同じミスや悪いやり方を見つけました。その原因はいろいろだと思います。おそらく僕の説明が明らでなかったとか、締め切りの前に生徒が忙し過ぎたとか。だからこそ責任は生徒だけじゃなく、学校や先生にもあると思います。

とりあえず、結果の新しい伝え方がみつけられてうれしいです。せめて生徒が応用問題の結果をもっと気になって、次の応用問題に役立ててくれればうれしいです。


読んでいただきありがとうございます。このトピックで話したいなら、ツイッターは@komanakun、Wantedlyはこちら、LinkedInプロフはこちらです。

474
186
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
474
186