わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

創意工夫のソースコードを採点する

 いきなりですが課題です.

 サンプルプログラムをもとに,面白いSVG画像を生成するプログラムを作成し,C言語のソースファイルを提出しなさい。

 昨日の記事の続きです.「サンプルプログラム」の掲載はしませんが,授業は打ち込んでもらい(写経),実行すると,SVG画像となるコードを生成します.そのソースコードの構成はおおむね次のとおりです.まずstdio.hとmath.h(sin,cos,sqrtなどの使用のため)のインクルード,次に「svgの開始タグ」「背景色のrectタグ」「svgの終了タグ」を出力する自作関数,そのあとmain関数です.main関数は,画像の幅・高さ・線の太さ・円の半径(正多角形や星型を描画するとき,中心からの最遠点をこの円周上にする)などを変数宣言しておき,あとのタグ生成の処理でそれらの変数名を参照します.
 「面白い」については,とくに規定をせず,各学生に委ねることにしました.課題の掲示(と提出)はMoodleを使用しており,「採点時に面白い答案があれば,生成したSVG画像を他の受講者も閲覧できるようにする」というのも書いていました.
 締切が来たので,答案を回収して…
 今回は,ソースコードを順に見て採点,というわけにいきません.コンパイルして,SVG画像を生成する必要があります.そして(Windows 10のエクスプローラーでは),SVG画像はアイコン表示となります.一覧表示できるようにすること,またSVGファイルの書式が適切かを機械的に確認する方法として,ImageMagickのconvertコマンドを使用してPNGファイルに変換することにしました.
 一つのディレクトリに,各学生のソースファイルがあるようにしてから,別の課題のシェルスクリプトファイルを書き換えました.

#!/bin/zsh
set -x
for f in *.c
do
    gcc $f -o a.out -lm >& ${f%.c}.log
    [ -f a.out ] && ./a.out > ${f%.c}.svg
    [ -f ${f%.c}.svg ] && convert ${f%.c}.svg ${f%.c}.png >& ${f%.c}.convert.log
    [ -f a.out ] && rm a.out
done
set +x

 doとdoneの間に,4つのコマンドを実行します.順に「コンパイル(Cからa.out)」「プログラム実行(a.outからSVG)」「画像変換(SVGからPNG)」「a.outの除去」です.コンパイルと画像変換では,「>& ファイル名」により,標準出力と標準エラー出力に書き出されるものをすべて(それぞれの実行で異なる)ファイルに保存させました.なお,2行目の「set -x」は実行するコマンドを出力するもの,最終行の「set +x」はその出力をしないようにするものです.
 実行して…
 最初の答案の,プログラム実行で,止まってしまいました.
 無限ループが入っていたら,こうなってしまうよな,無限にコード出力してたらストレージの無駄遣いになってしまう…と気づき,数秒でCtrl+Cを押して停止しました.
 最初の答案の,ソースコードを,Emacsで開いて見ました.無限ループになる処理はなかったのですが,かわりにscanfで,画像の幅と高さを獲得する処理を入れていました.無限ループではなく,入力待ちだったのです.
 すべてのCのファイルに対して,scanfの使用をgrepコマンドで調べたところ,使用していたのは,最初の答案だけでした.あとで個別採点するよう,別のディレクトリに移動させました.
 100件近くの答案(ソースコード提出)に対し,PNGファイルの生成に至らなかったのがいくつかありました.一つ一つチェックし,以下のとおり取りまとめました.箇条書きは,上のものほど減点幅が小さくなります.

  • 生成されたSVGファイルの書式に誤りを含む:6名
  • ソースコードに全角空白が入っていた:5名
  • その他のソースコードの不備:1名
  • scanfを使用していた:1名
  • SVGファイルを提出した:1名
  • 他の課題のソースコードを提出した:1名

 「SVGファイルの書式に誤りを含む」コードを一つだけ,紹介します.「x="0" y="0"」ではなく「x="θ" y="θ"」です.「θ」というのは,基本データ型と基本インタフェース – SVG 1.1 (第2版)を読んだ限りでは,認められません.

<rect x="θ" y="θ" width="400" height="400" fill="cyan"/>

 全角文字使用・ソースコード不備・scanf使用については,待避したディレクトリ上で修整を行ったあと,前述のスクリプトファイルを実行し,いずれもPNG生成に至りました.
 次は「展示」の選定です.数十のPNG画像を順に見ていくと,画像は3種類に大別できることに気づきました.一つは,正五角形や星型の発展版,二番目は,提供した課題にとらわれない自由描画,最後に線画です.線画というのは,表示領域に太さ1の縦線・横線を引いて合同な長方形で分割するという課題の発展形です.
 正五角形タイプと自由描画タイプには,見比べて面白いものがいくつかあったので,3つずつ選び,SVGや,Cのファイルも見て内容確認をしたのち,SVGファイルの名前を変えて,課題ページにアップロード(展示)しました.
 自由描画タイプで最も面白かったのは,パックマンをあしらった画像です.参考にしたURLもソースコードに書かれていました.
 画像を見て,あれっと思いました.パックマンの外形は,扇形です.それを「閉じた図形」にするには,SVGではpath要素と,円弧を描く命令などが必要です.授業で扱ったのはrext,polygon,lineの各要素のみですので,学生は調査したのかな,すごいな…
 と思いながらSVGファイルをEmacsで開くと,こちらの予想を超えていました.パックマンも,食べられるドットも,polygon要素で記述していたのでした.