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名)
以下のいずれも満たしているレポートを合格とした。
また、プログラムのコメントや、外部へのリンクは一切採点対象としない。
不合格になった場合、新たに次の条件を追加します。 上記の条件に加えてこの条件を満たすようにレポートを修正して再提出し てください。
なお、再提出をする場合は、学籍番号-2.pdf というファイル名で 課題1のレポートボックス に アップロードすること 12/6 までに提出すれば再評価をします。
なお、再再提出をする場合は、学籍番号-3.pdf というファイル名で 課題1の レポートボックス に アップロードすること 12/16 までに提出すれば再評価をします。
なお、再再再提出をする場合は、学籍番号-4.pdf というファイル名で 課題1の レポートボックス に アップロードすること 12/22までに提出すれば再評価をします。
さらに、提出をする場合は、学籍番号-5.pdf のファイル名で 課題1の レポートボックス に アップロードすること。 今回で最終評価となりますので、単独の評価結果はお知らせせず、成績に反映 します。 課題1が不合格だと、課題2が合格でも成績としては不合格になります。
採点が一日遅れてすみません。 不合格者へは全員コメントをメールで送りました。
現在不合格となっている人のパターンは次のどれかです。
再提出レポートから名前や学籍番号を消してしまうと、絶対に不合格になり ます。
eval やそれに類する「文字列で書かれている式を解釈する関数」を自分で 書かずに使用している場合は永遠に合格できません。
フローチャートにおいて
説明とは内容を記述することです。図を説明する場合は、図に何が書いてあ るかを文章で書く必要があります。「図をいかに示す」は図の説明ではあり ません。「図のような〇〇が表示される」は〇〇の説明ではありません。 BNFで書かれた文脈自由文法を説明する場合は、左辺と右辺に何が書いてあ るかを日本語で書く必要があります。「文脈自由文法を以下に示す」は説明 ではありません。
計算例で指定した値と異なった値が出ている場合は、プログラムが間違って いる場合があります。途中まで合っているからと言って正解ではないですの で、合理的な理由が無い限り、途中までで正解とはしないでください。
レポートを途中で打ち切って、考察って書いてからレポートの本文の続きを 書くのは不合格にしてあります。
画面のデザインについて、授業テキストから持ってきているとしても、構成 について説明する必要があります。
図を説明する場合、図の中身を日本語で書く必要があります。何があるだ けでなく、どのようにあるかも書く必要があります
有名なアンチパターン(だめなプログラムの定石)である「マジックボタン アンチパターン」を使ってプログラムを作っている人がいます。 これは、ボタンの中に計算機能を埋め込んでしまうものです。 今回のレポート課題では不合格にはしませんが、非常に保守性の悪いプログ ラムになります。 マジックボタンアンチパターンのプログラムは、 一つのボタンについて長大なプログラムが書かれ、似たようなボタンについて プログラムのコピーが貼り付けられ、全体で共有するグローバル変数のよう な仕組みでデータが共有されるものです。
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=など がきちんと辿れるようになっていなければなりません。
不正入力のテストは、一つ以上入力例を示し、その時の画面も示すこと。
以下のようなプログラムについて、クラスやメソッドごとの日本語の説明の 見本を示します。
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 のオブジェク トを与える。 そして、幅と高さを設定し、タイトルを設定する。
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 に指定して呼び出します。