レポート採点

課題1

合格者リスト

21ec026, 21ec062 (2名)

20ec032, 20ec064, 21ec008, 21ec039, 21ec043, 21ec075, 21ec090, 21ec093, 21ec102, 21ec116(+10名)

21ec004, 21ec069, 21ec070, 21ec082, 21nc003(+5名)

20ec096, 21ec022, 21ec052, 21ec060, 21ec061, 21ec068, 21ec081, 21ec083, 21ec103 (+9名)

採点基準

以下のいずれも満たしているレポートを合格とした。

  1. 学籍番号と氏名が記載されている
  2. プログラムが白黒またはそれに準ずる可読性の高い配色で記載されて いること(特に白地に黄色字などは認めない)。 また、説明のためにプログラムの一部を本文に置くのは構わないが、プ ログラム全体を付録として必ず示し、入力すれば動作可能であるように すること。
  3. プログラムがクラスやメソッドごとに日本語で説明されてい ること。 説明文中に全てのメソッド名が一回以上出てくること。
  4. 計算原理が正しく説明されていること
  5. 状態遷移図
  6. フローチャート
  7. 不正な入力の典型的な例とその復帰について、 (数を入れずに演算キー、小数点の2度押し、異なる演算キーの連続入力、 ゼロ除算など) 入力例と動作を示すとともに、プログラムにおける検知の仕方を記述する
  8. デザインを説明する場合、読んでいる側が画面の様子を記述できるように、 図を入れるか、画面に配置されるもの(10キー、演算キー、表示欄ほか)をす べて説明する必要がある。
  9. 考察に課題の解決に関して考えたことがが書かれている。 なお、課題に関係のない機能を追加する話は考察と認めない。 考察に本文の続きのプログラムの説明やアルゴリズムを書かないこと。

また、プログラムのコメントや、外部へのリンクは一切採点対象としない。

不合格になった場合、新たに次の条件を追加します。 上記の条件に加えてこの条件を満たすようにレポートを修正して再提出し てください。

追加条件

なお、再提出をする場合は、学籍番号-2.pdf というファイル名で 課題1のレポートボックス に アップロードすること 12/6 までに提出すれば再評価をします。

なお、再再提出をする場合は、学籍番号-3.pdf というファイル名で 課題1の レポートボックス に アップロードすること 12/16 までに提出すれば再評価をします。

なお、再再再提出をする場合は、学籍番号-4.pdf というファイル名で 課題1の レポートボックス に アップロードすること 12/22までに提出すれば再評価をします。

さらに、提出をする場合は、学籍番号-5.pdf のファイル名で 課題1の レポートボックス に アップロードすること。 今回で最終評価となりますので、単独の評価結果はお知らせせず、成績に反映 します。 課題1が不合格だと、課題2が合格でも成績としては不合格になります。

コメント 12/27

採点が一日遅れてすみません。 不合格者へは全員コメントをメールで送りました。

コメント 12/19

現在不合格となっている人のパターンは次のどれかです。

  1. 足し算とか掛け算がどのように行われているかについて、「計算原理」 という章での説明がない。
  2. 画面デザインの説明で「何を」「どこに」配置したという説明がな い
  3. フローチャートあるいは状態遷移図が理解できていなくて、図が完全に間 違っている。

コメント 12/12

再提出レポートから名前や学籍番号を消してしまうと、絶対に不合格になり ます。

eval やそれに類する「文字列で書かれている式を解釈する関数」を自分で 書かずに使用している場合は永遠に合格できません。

フローチャートにおいて

  1. ひし形は条件分岐です。ひし形の中には論理式を書きます。実行文や入力文は書 けません
  2. 実行文は長方形の要素に書きます
  3. 入力はキーボード型の台形に書きます
  4. 計算結果を表示したあとに最初に戻っていないフローチャートは、繰り返 し計算が実現できていませんので不合格です。個々の関数では繰り返しが 無くても良いです
  5. ひし形でループを作る場合、実行文であるひし形の要素でひし形内の論理 式の論理変数が更新されない場合は無限ループになってしまうので、必ず間 違いです。
  6. 関数のフローチャートでは開始要素に関数名を入れると良いです

説明とは内容を記述することです。図を説明する場合は、図に何が書いてあ るかを文章で書く必要があります。「図をいかに示す」は図の説明ではあり ません。「図のような〇〇が表示される」は〇〇の説明ではありません。 BNFで書かれた文脈自由文法を説明する場合は、左辺と右辺に何が書いてあ るかを日本語で書く必要があります。「文脈自由文法を以下に示す」は説明 ではありません。

計算例で指定した値と異なった値が出ている場合は、プログラムが間違って いる場合があります。途中まで合っているからと言って正解ではないですの で、合理的な理由が無い限り、途中までで正解とはしないでください。

レポートを途中で打ち切って、考察って書いてからレポートの本文の続きを 書くのは不合格にしてあります。

画面のデザインについて、授業テキストから持ってきているとしても、構成 について説明する必要があります。

図の説明の例

図を説明する場合、図の中身を日本語で書く必要があります。何があるだ けでなく、どのようにあるかも書く必要があります

×
以下に図を示す
×
図にすると以下のようになった
×
ソフトを使用して以下に図を示した
×
おひさまとチューリップについて図に示した
図のように左上におひさま、中央下にチューリップが書かれてい る

コメント 11/28

マジックボタンアンチパターン

有名なアンチパターン(だめなプログラムの定石)である「マジックボタン アンチパターン」を使ってプログラムを作っている人がいます。 これは、ボタンの中に計算機能を埋め込んでしまうものです。 今回のレポート課題では不合格にはしませんが、非常に保守性の悪いプログ ラムになります。 マジックボタンアンチパターンのプログラムは、 一つのボタンについて長大なプログラムが書かれ、似たようなボタンについて プログラムのコピーが貼り付けられ、全体で共有するグローバル変数のよう な仕組みでデータが共有されるものです。

COBOLの時代から、プログラミングの定石として、入力、処理、出力を分離 するということが行われていました。これにより、入力、処理、出力に関す る変更や保守などで、すべてのプログラムを読まなくても対応できるように なりますし、プログラムも読みやすくなります。 オブジェクト指向プログラミングにおいては、MVC(Model, View, Control) とかトライアングルと呼ばれているデザインパターン(オブジェクト指向プ ログラミングの定石)が定石とされています。 電卓で言えば、ボタンや表示部がシンプルに独立していて、計算する部分は 別に記述されている必要があります。 これにより、ボタンを一つ増やしても長大なプログラムをコピーする必要が なくなります。

ゼロ除算

ゼロで割り算を行うことは数学では避けることにしてあります。 通常のプログラミング言語や電卓では単純にエラーとして取り扱っています。 これを「無限大」として取り扱って良いのでしょうか? 実は 0 で割る際、0の符号が問題になります。 要するに 1/0 と (0-1)/0 が同じものになるのか、異なるものになるのか考 えて下さい。 その上で、「エラー」として取り扱うのが良いのか、「無限大」という概念 を導入するのがいいのか考えてみて下さい。

再提出レポートについて

電卓のプログラムはインターネットを探せばいくらでもダウンロードできる という前提なので、 プログラムを載せるだけでは合格になりません。 必ず、クラス、メソッドをすべて日本語または英語で説明してください。 プログラム自体はプログラムの説明ではありません。

また、説明において「Mainは上のようになる」など、プログラムの中身の説 明が「ように」以外無いのは説明と見なしません。 「ように」を禁止するわけではありませんが、図、プログラムなどが無くても、文章 として意味が通じるようにすること、つまり、「ように」は説明を補足する 図表などを指し示す意味しかないことに注意して下さい。

状態遷移図の矢印に文字や記号以外が現れてはいけません。 特に「2回目」が現れてはいけません。 かならず、矢印は文字だけ付けてください。 有限回の計数は状態 を増やせば状態遷移図で数えられます。 さらに、状態に名前をつけるのには問題はありませんが、プログラムの動作を つけてはいけません。 例えば、「=」キーが押された場合に計算が実行される場合には、「=」が付 与された矢印が「計算」という名前のついた状態に入るのではなく、 「=/計算」のように、「文字/動作」というラベルを矢印に付けて下さい。 本課題では動作を明示するのは義務ではありません。

状態遷移図が正しくかけているかをチェックするには、 1.1-200/3.3+4.5=や、.1-200./3+0=など がきちんと辿れるようになっていなければなりません。

だめな例
良い例

不正入力のテストは、一つ以上入力例を示し、その時の画面も示すこと。

プログラムの説明の例

以下のようなプログラムについて、クラスやメソッドごとの日本語の説明の 見本を示します。

例1

class MyFrame extends JFrame {
    public void setCloseActionListener(ActionListener a){
	closeActionList.add(a);
    }
    private final LinkedList<ActionListener> closeActionList
	= new LinkedList<ActionListener>();
    class MyWindowListener extends WindowAdapter {
        @Override
	public void windowClosed(WindowEvent e){
	    for(ActionListener listener : closeActionList){
		listener.actionPerformed(
                   new ActionEvent(
                     this,ActionEvent.ACTION_PERFORMED,"close"));
	    }
	}
    }
    public MyFrame(){
        super();    
	setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
	addWindowListener(new MyWindowListener());
	setSize(FrameConstant.WIDTH,FrameConstant.HEIGHT);
	setTitle(FrameConstant.TITLE);
    }
}

MyFrameクラスはJFrameクラスを継承したクラスであり、 コンストラクタの他は、 setCloseActionListenerメソッ ドを含んでいる。 また、インナークラスとして、WindowAdapter クラスを継承した MyWindowListener クラスを定義した。また、ActionListener のLinkedList として closeActionList フィールドも定義した。

setCloseActionListerメソッドはActionListener のオブジェクト を引数とし、closeActionList フィールドに受け取ったActionListener を 追加する。

MyWindowListerインナークラスでは、 windowClosedメソッドをオーバライドする。 このメソッドは、closedActionList に含まれるすべてのActionListener に対して、 close を示すActionEvent を与えて actionPerformed メソッドを呼び出す。

コンストラクタでは Window のClose ボタンを押されたときのデフォルトの動作をウィンドウ破棄 (DISPOSE_ON_CLOSE)に設定し、 WindowListener として、インナークラスの MyWindowListener のオブジェク トを与える。 そして、幅と高さを設定し、タイトルを設定する。

例2

import tkinter
import tkinter.ttk

class TenkeyBoard(tkinter.ttk.Frame):
    def __init__(self, master=None,  label=None, command=None, **kwargs):
        super().__init__(master, **kwargs)
        self.label = label
        self.command = command
        self.input_string = ""
        for i in map(str, range(10)):
            tkinter.ttk.Button(self, text=i,
                               command=lambda s=i: self.click_button(s)
                               ).pack()
        tkinter.ttk.Button(self, text="+",
                           command=lambda s="+": self.click_button(s)
                           ).pack()
        tkinter.ttk.Button(self, text="=",
                           command=self.enter
                           ).pack()

    def enter(self):
        self.command(self.input_string)
        self.input_string = ""

    def click_button(self, char):
        self.input_string += char
        self.label.config(text=self.input_string)    

TenkeyBoardクラスは tkinter.ttk.Frameクラスを継承したクラスであり、 コンストラクタの他は、 enterメソッドと click_buttonメソッドを含んでいる。

コンストラクタでは 親クラスのコンストラクタに可変長の引数を渡すために **kwargs という特殊 な記法を用いているが、それ以外の引数として master, label, command を指定できるようにしている。 これらのうち、 master と ++kwargs については親クラスのコンストラクタ の引数として、コンストラクタ呼び出しを行った。 label, command に関してはインスタンス変数として保存する。 インスタンス変数として input_string を用意し、空の文字列として初期化 する。 そして、ボタンを配置する。 0から9までのボタンについては、ボタンのテキストをその数とし、コマンド として、数を入力とする click_button メソッドを呼び出す。 さらに、+ボタンに関しても同様にテキストを + として、+ を入力とする click_button メソッドを呼び出す。 =ボタンでは、 enter メソッドを呼び出す。 なお、すべてのボタンのレイアウトには pack を使用した。

enterメソッドでは、input_string 変数を引数として、コンスト ラクタで与えられた command を呼び出す(入力文字列に対して計算の呼び 出し)。 その後、 input_string を初期化する。。

click_buttonメソッドでは、 引数の文字をinput_string 変数に保存している文字列の最後に追加し、 さらに、コンストラクタで与えられた label の config メソッドに対して、 text 引数を input_string に指定して呼び出します。


坂本直志 <sakamoto@c.dendai.ac.jp>
東京電機大学工学部情報通信工学科