初心者のためのC#プログラミング本格入門84 - 油断せずに行こう
以前述べたように、テストプログラムは徐々に難しくしていきます。その考えに従って、CalculateMultiExpressionテストをちょっと難しくします。
class MultiAnalyzerTest : Test
{
//複数の式の計算処理をチェック
public void CalculateMultiExpression()
{
string[] expressions = new string[]
{
"( + 1 2 ) + 3", "( + 1 2 ) * 3",
"( + 1 2 ) - 3", "( + 1 2 ) / 3"
};
double[] rightValues = new double[]
{
6, 9, 0, 1
};
for ( int i = 0; i < expressions.Length; ++i )
{
CalculateMultiExpression(
expressions[ i ], rightValues[ i ] );
}
}
private void CalculateMultiExpression(
string expression, double rightValue )
{
++this.testCount;
this.target = new MultiAnalyzer();
this.target.AnalyzeExpression( expression );
double result = this.target.Calculation();
if ( result != rightValue )
{
++errorCount;
System.Console.WriteLine(
expression +
" の計算処理が正しくありません。 " +
"正しい値:{0}, 処理結果;{1}",
rightValue, result );
}
}
}
前回の復習のために多重定義を使っています。今まで解説してきた文法を使っているのでプログラムの内容は分かると思います。デバッグ実行(F5)して下さい。今回は珍しくエラーがありません。インドリにしては珍しいと思った人は鋭いです。テストはちょっと意地悪になるぐらいが丁度いいです。テストデータを増やしましょう。
//複数の式の計算処理をチェック
public void CalculateMultiExpression()
{
string[] expressions = new string[]
{
"( + 1 2 ) + 3", "( + 1 2 ) * 3",
"( + 1 2 ) - 3", "( + 1 2 ) / 3",
"( + 3 4 ) + 3", "( + 3 4 ) * 3",
"( + 3 4 ) - 3", "( * 3 4 ) / 3"
};
double[] rightValues = new double[]
{
6, 9, 0, 1,
10, 21, 4, 4
};
for ( int i = 0; i < expressions.Length; ++i )
{
CalculateMultiExpression(
expressions[ i ], rightValues[ i ] );
}
}
デバッグ実行(F5)して下さい。案の定?エラーが表示されます。「やっぱりバグを仕込んでいたか!」と怒らないで、エラー文に注目して下さい。「 ( 3 + 4 ) - 4 」の答えが4ではなく-4になっています。どうやったら-4になるのでしょうか?Calculationメソッドのプログラムをよく見て下さい。そうすると、1つの式を計算して、次の式へ値を追加している事が分かります。やってみましょう。
4 + 3 = 7
3 - 7 = -4
一致しています。正しくは「 7 - 4 」にしたいのですから、値の並びが逆になっています。念のために割り算の方も計算してみましょう。
4 * 3 = 12
3 / 12 = 0.25
やはり逆順になっています。ということは、値を逆に記録して計算すれば解決します。早速修正してみましょう。どこを修正するべきなのかは問題です。答えを見る前に考えて下さい。
答えを発表します。答えは・・・AnalyzerオブジェクトのAddValuesメソッドです。このメソッド内のプログラムを修正すればこのエラーの原因となっているバグをなくせます。
class Analyzer
{
//値を直接追加
public void AddValues( double value )
{
this.values.Insert( 0, value );
}
}
Insertメソッドを使えば、任意の位置に追加できます。デバッグ実行(F5)して下さい。今度はエラーが表示されません。今回は復習をしました。プログラミングは何度も繰り返さないと上手くなりません。初心者用のプログラミング本を買っても、プログラミングが分からない人がいるのはそれが原因だと思います。特に計算された過ちをしないという点が大きいと思います。本という媒体上、計算された過ちをできないのでしょう。また、インターネット上でも正しい答えを羅列しているものしか見た事がありません。これは著者のプライドかなと思います。※趣味目的のものは除いています
しかし、正しい答えを見るだけなんて学習になりません。人に物を教える為ならば教える側は間違う勇気が必要です。下手なプライドは要りません。もしかしたら、教える為ならば自分が恥を書いてもいいというのが、私のプライドなのかもしれません。私は自己顕示欲のためにブログを書いているのではなく、誰かにプログラミングを伝えるためにブログを書いています。ですから、自分の技術力を見せびらかす記事を書いた事がありません。常に想定する読者に合わせて書いています。長年システム屋をしているので、お客様に合わせて自分を出さないのが普通になっています。プロというものは常に誰かのために考えるものです。自分を誇示する必要なんてありません。これからも読者目線の記事を書くので楽しみにして下さい。