[三流君] −−>
[プログラマー業務の愚痴] −−>
[バックナンバー一覧]
−−> No.174 同じ外見/動作でも中身の違う配列使用プログラム
同じ外見/動作でも中身の違う配列使用プログラム
本文(発行内容)
<同じ外見/動作でも中身の違う配列使用プログラム>
こんにちは、三流プログラマーのKen3です。
今回は、
配列を使った、
同じ外見/動作でも中身の違うプログラム
そんなプログラム関係のお話です。
まぁ、いつもの独り言だけど、聞いてください。
/*
* 1.今回のキッカケ
*/
仕様書 書く側 と 受取り側(要求仕様書、基本設計書、詳細設計書)
http://www.ken3.org/vba/doc.html
なんて、偉そうに設計してからシステム組みましょうとほざいてました。
次は、
作成時 Ctrl+C Ctrl+Vの前によく考えよう
http://www.ken3.org/vba/vba-copy-pg.html
では、コピー貼り付けの操作が速い自慢にならないよ、
プログラム作成で一工夫しようよ・・・
とここでも語ってましたねぇ(笑)
どちらかと言えば、芸術的プログラムとは無縁の三流プログラマーです。
えっ、そんなのわかってるって?
そんな前フリは置いといて、
今回は、配列を使用したプログラムを書いてみたいと思います。
※変に複雑にやせている女性より、ふっくらした女性がいいと思うけど・・・
えっ、でもCtrl+CとCtrl+Vで着膨れしたセンスないプログラム(女性)はチョット?
う〜ん、いい表現が、、あっ、外見同じでも体脂肪の違いって感じで・・
/*
* 2.仕様書
*/
「先輩、仕様書ください、口頭じゃなくて紙で。でないと組めませんよ」
ちぇ、しょうがねえなぁ、簡単にテキストファイルで書くか。
仕様.TXT
~~~~~~~~
言語はASPで動作するVBScriptで。 (※言語も書いとくか)
関数名は Sub HANTEI(strNO) (※関数名なんて好きでいいんだけど)
受け取りは文字列で"1","2","3"を受け取る
1 グー
2 チョキ
3 パー
(※受け取りパラメータの説明を書いて)
処理
^^^^
入力値の判断、エラーならメッセージを表示させ抜ける
エラーメッセージは
[XXXX]は不正な入力です
(※メッセージなんてそれらしく作ってよ、
えっ、仕様書で指定しないくせに、あとから文句言うなって?)
乱数でコンピュータの手を発生させる
グー・チョキ・パーを乱数で。
結果の判断と勝負手の表示
USER_NAME(←グローバル変数に格納されてます)さんの手は、グーです
コンピュータの手はパーです
引き分けです
アナタの勝ちです
私(コンピュータ)の勝ちです
と、結果を画面に出力する
リターン値は無しで、関数を終了する
関数仕様書作りのポイント
~~~~~~~~~~~~~~~~~~~~
まず重要なのは、入力(INパラメータ)・処理を詳しく・出力(戻り値)
何を受け取って、XXXXと処理をして、XXXと上位関数に結果を返す。
リターン値無しでも私は気にしないけど、
~~~~~~~~~~~~~~
無い場合でも必ず0を返す(0正常)と書かないと気になる君も居ます。
ほかに必要なのは、処理に入れるんだけど、
エラー処理は?どうするか?
と
意外と質問が多いのが、メッセージの文章。
メッセージ適当でいいよとお任せで渡すけど、
プログラムよりメッセージ考えてた/メッセージに悩んでいた(笑)
なんてプログラマーが居るのも事実。
あとは、簡単な仕様書を元に、説明時に詰めていくんだけど。
※ここで、問題点を話し合って、仕様変更。
パラメータは0〜2にしてほしいとか、処理方法とか。
でも仕様書はそのまま。
そんなんで、初期の仕様書のまま納品なんてパターン多いかも。
お客はわからないよ・・なんて思わないで更新しようね仕様書の。
でもそんなことしていると、
プログラマーってより、ワープロ屋って感じ(これホント)
/*
* 3.この仕様書から作られたプログラム
*/
こんな仕様書を書くなら、自分で作ったほうがハヤイな・・・
と
思いつつ、仕様書を渡し作業をお願いする。
自分は、上位ルーチンの作成や次の関数仕様書を作成する
And 3が月前に納品した他のシステムのバグ対応、新規システムの打ち合わせ
と平行して業務を実行する。
作成された(できあがった)サブ関数をもらいました。
Sub HANTEI(strNO) 'ユーザーの手を受取り判断する
Dim nCON 'コンピュータの手1〜3の数値が入る
Dim nPC 'ユーザーさんの手
Dim strTE(3) '(*1)配列変数を宣言
strTE(1) = "グー" '(*2)配列にメッセージを代入
strTE(2) = "チョキ"
strTE(3) = "パー"
'入力値の判断、エラーならメッセージを表示させ抜ける
'If文で1,2,3以外を判断する
If strNO <> "1" And strNO <> "2" And strNO <> "3" Then
Response.Write "[" & strNO & "]は不正な入力です"
Exit Sub '<--Exit Subを使用してここでプログラムを抜ける
End If
'コンピュータの手を決定
Randomize ' 乱数発生ルーチンを初期化します。
nCON = Int((3 * Rnd) + 1) '1 から 3 までの乱数を発生させます。
'結果判断と表示
'ユーザーの手を表示する
nPC = CInt(strNO) 'CInt関数で数値型に変換する
Response.Write USER_NAME & "さんの手は、"
Response.Write strTE(nPC) & "です<br>" '(*3)ここでnPC番目を表示
'(*4)同様にコンピュータの手を表示する
Response.Write "コンピュータの手は" & strTE(nCON) & "です<br>"
'結果の判断
'まず、引き分けを判断
If nPC = nCON Then Response.Write "引き分けです<br>"
'次に自分が勝ちの手を判断 グーvsチョキ,チョキvsパー,パーvsグー
If nPC = 1 And nCON = 2 Then Response.Write "アナタの勝ちです<br>"
If nPC = 2 And nCON = 3 Then Response.Write "アナタの勝ちです<br>"
If nPC = 3 And nCON = 1 Then Response.Write "アナタの勝ちです<br>"
'コンピュータが勝ちか判断 グーvsパー,チョキvsグー,バーvsチョキ
If nPC = 1 And nCON = 3 Then Response.Write "私(コンピュータ)の勝ちです<br>"
If nPC = 2 And nCON = 1 Then Response.Write "私(コンピュータ)の勝ちです<br>"
If nPC = 3 And nCON = 2 Then Response.Write "私(コンピュータ)の勝ちです<br>"
End Sub |
自分の作成した上位関数に組み込みテスト。
http://www.ken3.org/cgi-bin/test/test064-1.asp
でテスト実行できます、遊んでみてください
/*
* 4.同じ固定文字列を嫌う病的プログラマーを目指して
*/
まぁ、関数仕様書の話で終わっても良かったんだけど、
同じ仕様書でも違う中身のプログラムが作成される。
面白いよね And 同じ動作なんだけどプログラマーのレベルって出てくるよ。
※仕様書の内容が粗いほど、イロイロ出てくるって話もあるけど。
処理フローまで書いては渡さないし、入出力設計のみで、
あとは、人任せ(担当プログラマー任せ)かなぁ。
動作は同じ、中身が違うプログラム、そんな話に強引にもって行きます。
同じ固定文字列を嫌う先輩
~~~~~~~~~~~~~~~~~~~~~~~~
世の中には少しのムダも許せない、そんな人も居る
が
無駄遣いが好きな人も居る。
プログラム中のムダっていろいろとあるんだけど、
同じ固定のメッセージなどの文字列を嫌う人は多いです。
'次に自分が勝ちの手を判断 グーvsチョキ,チョキvsパー,パーvsグー
If nPC = 1 And nCON = 2 Then Response.Write "アナタの勝ちです<br>"
If nPC = 2 And nCON = 3 Then Response.Write "アナタの勝ちです<br>"
If nPC = 3 And nCON = 1 Then Response.Write "アナタの勝ちです<br>"
ここ、あきらかにコピープログラムだよね。
上のIf文をコピーして、数値だけ修正してる。
このResponse.Write "アナタの勝ちです<br>"がムダに見えるらしい。
strMSGPC = "アナタの勝ちです<br>" 'ユーザー勝利
strMSGCON = "私(コンピュータ)の勝ちです<br>" 'コンピュータ勝利
'次に自分が勝ちの手を判断 グーvsチョキ,チョキvsパー,パーvsグー
If nPC = 1 And nCON = 2 Then Response.Write strMSGPC
If nPC = 2 And nCON = 3 Then Response.Write strMSGPC
If nPC = 3 And nCON = 1 Then Response.Write strMSGPC
'コンピュータが勝ちか判断 グーvsパー,チョキvsグー,バーvsチョキ
If nPC = 1 And nCON = 3 Then Response.Write strMSGCON
If nPC = 2 And nCON = 1 Then Response.Write strMSGCON
If nPC = 3 And nCON = 2 Then Response.Write strMSGCON
って、すればいいんだろ。
なるほどねぇ、メッセージを変えてくれと言われても、
1箇所で済むんだぁ、へぇ〜すごいすごい(笑)(バカにしたような笑い)
なんか文句あるんですか?ボクのプログラムに対して?
別に動いているから文句無いんだけど、
^^^^^^^^^^^^^^^^^^^^^^^^^^^^(どんな書き方でも動くプログラムじゃないと)
配列の使い方、知ってるようで知らないよね。
どこが?ですか?
まず、上のほうでは、
Dim strTE(3) '(*1)配列変数を宣言
strTE(1) = "グー" '(*2)配列にメッセージを代入
strTE(2) = "チョキ"
strTE(3) = "パー"
と、配列に手の文字列を入れて置き(下準備)
'ユーザーの手を表示する
nPC = CInt(strNO) 'CInt関数で数値型に変換する
Response.Write USER_NAME & "さんの手は、"
Response.Write strTE(nPC) & "です<br>" '(*3)ここでnPC番目を表示
'(*4)同様にコンピュータの手を表示する
Response.Write "コンピュータの手は" & strTE(nCON) & "です<br>"
と、
strTE(nPC), strTE(nCON)
配列の中身を参照して表示してるよね。
下記のコピー君から卒業してて、
If nPC = "1" Then Response.Write "グーです<br>"
If nPC = "2" Then Response.Write "チョキです<br>"
If nPC = "3" Then Response.Write "パーです<br>"
と比べると、配列を使用してメッセージの管理はOKかなぁ。
それと一緒で、
strMSGPC = "アナタの勝ちです<br>" 'ユーザー勝利
strMSGCON = "私(コンピュータ)の勝ちです<br>" 'コンピュータ勝利
の
結果のメッセージも配列で管理してみては?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Dim nMSGNO 'メッセージの番号
Dim strMSG(3) 'メッセージ表示用の配列
strMSG(1) = "アナタの勝ちです<br>" 'メッセージの代入
strMSG(2) = "引き分けです<br>"
strMSG(3) = "私(コンピュータ)の勝ちです<br>"
'結果の判断
'まず、引き分けを判断
If nPC = nCON Then nMSGNO = 2 '引き分け
'次に自分が勝ちの手を判断 グーvsチョキ,チョキvsパー,パーvsグー
If nPC = 1 And nCON = 2 Then nMSGNO = 1 'ユーザーの勝ちをセット
If nPC = 2 And nCON = 3 Then nMSGNO = 1
If nPC = 3 And nCON = 1 Then nMSGNO = 1
'コンピュータが勝ちか判断 グーvsパー,チョキvsグー,バーvsチョキ
If nPC = 1 And nCON = 3 Then nMSGNO = 3 'コンピュータの勝ちをセット
If nPC = 2 And nCON = 1 Then nMSGNO = 3
If nPC = 3 And nCON = 2 Then nMSGNO = 3
'結果のメッセージを表示する(メッセージ番号を使用して)
Response.Write strMSG(nMSGNO)
と、表示メッセージを配列で用意して、
結果の判断では、nMSGNO = X と メッセージの場号を代入。
最後にメッセージを表示する。
そんな感じに変更すると、
strMSGPC = "アナタの勝ちです<br>" 'ユーザー勝利
'次に自分が勝ちの手を判断 グーvsチョキ,チョキvsパー,パーvsグー
If nPC = 1 And nCON = 2 Then Response.Write strMSGPC
If nPC = 2 And nCON = 3 Then Response.Write strMSGPC
If nPC = 3 And nCON = 1 Then Response.Write strMSGPC
処理は似ているけど、メッセージ内容の変更があっても対応可能で、
Response.Write strMSGPC
を3回も書かなくていいしね。
http://www.ken3.org/cgi-bin/test/test065-1.asp
でテスト実行できます、遊んでみてください
※動作は同じなんだけど
/*
* 5.2次元配列で結果を管理する
*/
まぁ、配列を使用して、
If nPC = "1" Then Response.Write "グーです<br>"
If nPC = "2" Then Response.Write "チョキです<br>"
If nPC = "3" Then Response.Write "パーです<br>"
から
Dim strTE(3) '(*1)配列変数を宣言
strTE(1) = "グー" '(*2)配列にメッセージを代入
strTE(2) = "チョキ"
strTE(3) = "パー"
'ユーザーの手を表示する
Response.Write strTE(nPC) & "です<br>" '(*3)ここでnPC番目を表示
と、しました。
これをさらに応用して、
じゃんけんの勝敗を
~~~~~~~~~~~~~~~~~~
'結果の判断
'まず、引き分けを判断
If nPC = nCON Then nMSGNO = 2 '引き分け
'次に自分が勝ちの手を判断 グーvsチョキ,チョキvsパー,パーvsグー
If nPC = 1 And nCON = 2 Then nMSGNO = 1 'ユーザーの勝ちをセット
If nPC = 2 And nCON = 3 Then nMSGNO = 1
If nPC = 3 And nCON = 1 Then nMSGNO = 1
'コンピュータが勝ちか判断 グーvsパー,チョキvsグー,バーvsチョキ
If nPC = 1 And nCON = 3 Then nMSGNO = 3 'コンピュータの勝ちをセット
If nPC = 2 And nCON = 1 Then nMSGNO = 3
If nPC = 3 And nCON = 2 Then nMSGNO = 3
'結果のメッセージを表示する(メッセージ番号を使用して)
Response.Write strMSG(nMSGNO)
と判断しているんだけど、
条件を表にすると、
~~~~~~~~~~~~~~~~~~
グー(1) チョキ(2) パー(3) ←コンピュータの手
グー(1) 引き分け 勝ち 負け
チョキ(2) 負け 引き分け 勝ち
パー(3) 勝ち 負け 引き分け
↑自分の手
ですね。
まぁ、そんなこと言われなくても(表に書かなくても)わかるか。
この表を見て判断じゃないけど、
If nPC = 1 And nCON = 3 Then nMSGNO = 3 'コンピュータの勝ちをセット
と、nPC=1グーとnCON=3パーをみて(1,3)負け(コンピュータの勝ち)を判断してます。
メッセージ番号で結果を判断してます。
strMSG(1) = "アナタの勝ちです<br>" 'メッセージの代入
strMSG(2) = "引き分けです<br>"
strMSG(3) = "私(コンピュータ)の勝ちです<br>"
この、1,2,3を表にすると
~~~~~~~~~~~~~~~~~~~~~~~
グー(1) チョキ(2) パー(3) ←コンピュータの手
グー(1) 2引き分け 1勝ち 3負け
チョキ(2) 3負け 2引き分け 1勝ち
パー(3) 1勝ち 3負け 2引き分け
↑自分の手
ですね。
これをそのまま、2次元配列にして、管理してみます。
'結果の判断
' グー(1) チョキ(2) パー(3) ←コンピュータの手
'グー(1) 2引き分け 1勝ち 3負け
'チョキ(2) 3負け 2引き分け 1勝ち
'パー(3) 1勝ち 3負け 2引き分け
'↑自分の手
'勝負の結果表を作る
Dim strCHK(3, 3) '3x3の結果の表
strCHK(1, 1) = 2 : strCHK(1, 2) = 1 : strCHK(1, 3) = 3
strCHK(2, 1) = 3 : strCHK(2, 2) = 2 : strCHK(2, 3) = 1
strCHK(3, 1) = 1 : strCHK(3, 2) = 3 : strCHK(3, 3) = 2
'結果を代入
nMSGNO = strCHK(nPC, nCON) '結果表の値を代入
'結果のメッセージを表示する(メッセージ番号を使用して)
Response.Write strMSG(nMSGNO)
なんて、2次元配列を使用した書き方ができます。
だいぶ、変わりましたね。
同じ動作なんだけどねぇ・・・
Sub HANTEI(strNO) 'ユーザーの手を受取り判断する
Dim nCON 'コンピュータの手1〜3の数値が入る
Dim nPC 'ユーザーさんの手
Dim strTE(3) '(*1)配列変数を宣言
strTE(1) = "グー" '(*2)配列にメッセージを代入
strTE(2) = "チョキ"
strTE(3) = "パー"
Dim nMSGNO 'メッセージの番号
Dim strMSG(3) 'メッセージ表示用の配列
strMSG(1) = "アナタの勝ちです<br>" 'メッセージの代入
strMSG(2) = "引き分けです<br>"
strMSG(3) = "私(コンピュータ)の勝ちです<br>"
'入力値の判断、エラーならメッセージを表示させ抜ける
'If文で1,2,3以外を判断する
If strNO <> "1" And strNO <> "2" And strNO <> "3" Then
Response.Write "[" & strNO & "]は不正な入力です"
Exit Sub '<--Exit Subを使用してここでプログラムを抜ける
End If
'コンピュータの手を決定
Randomize ' 乱数発生ルーチンを初期化します。
nCON = Int((3 * Rnd) + 1) '1 から 3 までの乱数を発生させます。
'結果判断と表示
'ユーザーの手を表示する
nPC = CInt(strNO) 'CInt関数で数値型に変換する
Response.Write USER_NAME & "さんの手は、"
Response.Write strTE(nPC) & "です<br>" '(*3)ここでnPC番目を表示
'(*4)同様にコンピュータの手を表示する
Response.Write "コンピュータの手は" & strTE(nCON) & "です<br>"
'結果の判断
' グー(1) チョキ(2) パー(3) ←コンピュータの手
'グー(1) 2引き分け 1勝ち 3負け
'チョキ(2) 3負け 2引き分け 1勝ち
'パー(3) 1勝ち 3負け 2引き分け
'↑自分の手
'勝負の結果表を作る
Dim strCHK(3, 3) '3x3の結果の表
strCHK(1, 1) = 2 : strCHK(1, 2) = 1 : strCHK(1, 3) = 3
strCHK(2, 1) = 3 : strCHK(2, 2) = 2 : strCHK(2, 3) = 1
strCHK(3, 1) = 1 : strCHK(3, 2) = 3 : strCHK(3, 3) = 2
'結果を代入
nMSGNO = strCHK(nPC, nCON) '結果表の値を代入
'結果のメッセージを表示する(メッセージ番号を使用して)
Response.Write strMSG(nMSGNO)
End Sub |
http://www.ken3.org/cgi-bin/test/test065-2.asp
でテスト実行できます、遊んでみてください
※動作は同じなんだけど
/*
* 6.終わりの挨拶(次回はアルのか?(爆))
*/
よくわからなかったけど、何が今日は言いたかったの?
えっと、
If文の連続プログラム
と
配列の値を参照したプログラム
って話です。
まぁ、あまり気にしなくてもいいんだけど、
If文を縦に羅列しすぎるプログラムって、
一工夫できますよ程度に思っててください。
あまり気にし過ぎて病的な配列大好きif文は悪だとなられても困るし。
何か読者の心に残れば、うれしいです。
*私の独り言をうまく消化してくださいね。
いつも失敗?のKen3でした。
~~~~~~~(↑オイオイ)
ページフッター
ここまで、読んでいただきどうもです。ここから下は、三流君のホームページの紹介・案内です
目的の情報が見つかったか?少々心配しつつ、、、
リンクや広告など
項目別に本音?それとも建て前?的な記事をまとめました。
Blogとリンク:[三流君の作業日記]/
[愚痴(Bookmark)]/
[広告Blog(Bookmark)]
[三流君(TOP ken3.org へ戻る)]
/ [プログラマー業務の愚痴]
/ [バックナンバー 一覧]