いきなりですが課題です.
昨日の記事の続きです.「サンプルプログラム」の掲載はしませんが,授業は打ち込んでもらい(写経),実行すると,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要素で記述していたのでした.