![]() |
zunbe |
![]() |
|
| [<<先頭] [<前へ] [ 1 2 3 4 5 6 ] [次へ>] [最後>>] | ||
2005/09/28
|
このエピソードの続き。
処理しているデータは観測機器から取得した観測データであり、当然のことながら、データ中には「欠測」という状況が発生しうる。
今回のプログラムでは、データが欠測であった場合に、値として NULL を投入するように指示してあった。
社員が書いたプログラムは、通常の値については指示通り NULL が設定されていたが、日平均値の計算は以下の様なプログラムになっていた。
-----
if (有効観測数 > 0)
{
日平均値 = 日積算値 / 有効観測数;
}
else
{
日平均値 = 0;
}
-----
有効観測数が「0」の時、日平均値が「0」だと?
ぜんぜんダメである。
なんで、有効な観測値が1レコードもないのに、その平均値が「0」なんだ?
有効な観測値が1レコードもなければ、平均値も有効にはならないのであるから、当然 NULL を設定するべきだろう。
このデータの中身は、気象情報(風速、降水量、日射量など)なのだが、「風速=0」と「風速=わからない(NULL)」はまったく意味が違う。
このプログラムでは、風速が1回も観測できていない状況でも、「平均風速 0.0m」と記録されてしまう。
要するに、社員は、「NULL」という値の意味が理解できていないのである。
ちなみに、このエピソードは、以下のエピソードにも通ずるものがある。
若いモンは、もっともっと勉強するべきだ。
このエピソードはいかがでしたか? ![]() ![]() | ![]() |
投稿者 zunbe : 2005/09/28 02:36:09 | コメント (0) | トラックバック (0)
2005/09/27
|
CSVデータからデータベースに投入するプログラムを作らせた。
仕様はこうだ。
(1).観測局が10地点あり、1時間毎の観測値(1時間値)がCSVファイルに記録されている。
CSVのフォーマットは以下の通り。
-----
観測局コード,観測年月日,観測時刻,観測値
-----
(2).CSVファイルを読み込みデータベースに投入する。
テーブル構造は以下の通り。
-----
観測局コード PKEY
観測年月日+時刻 PKEY
観測値種別 PKEY
観測値
-----
このうち、PKEY と記載されている列がプライマリ・キーである。
「観測値種別」には、「1時間値」と「日平均値」がある。
(3).投入は以下の通り行う。
(a).1時間値は、CSVデータに格納されている値をそのまま投入する。
(b).日平均値は、当該観測年月日の平均値を求めて投入する。
その際、時刻には「00:00:00」を設定する。
社員は、この仕様において、日平均値の計算で以下の様な処理を書いた。
・同じ「観測年月日」のデータをすべて(全観測局分)積算して、平均値を求めて投入。
たとえば、以下の様なデータの場合…
----- CSVファイル -----
1,20050927,00,100
1,20050927,01,110
1,20050927,02,120
2,20050927,00,200
2,20050927,01,210
2,20050927,02,220
-----
日平均値は 160。
データベースには以下の様に投入される。
----- データベース -----
1,2005-09-27 00:00:00,1時間値,100
1,2005-09-27 00:01:00,1時間値,110
1,2005-09-27 00:02:00,1時間値,120
1,2005-09-27 00:00:00,日平均値,160
2,2005-09-27 00:00:00,1時間値,200
2,2005-09-27 00:01:00,1時間値,210
2,2005-09-27 00:02:00,1時間値,220
2,2005-09-27 00:00:00,日平均値,160
-----
ぜんぜんダメである。
どうして、すべて観測局の値から平均値を求めるという発想になるのだろうか。
データベースのプライマリ・キーは、「観測局コード」「観測年月日+時刻」「観測値種別」だ。
すなわち、「観測局コード」「観測年月日+時刻」「観測値種別」を基準に集計されなければならない事を意味している。
どう考えても、すべての観測局のデータを積算して平均値を求めるのはおかしい。
確かにずんべは、「平均値を求めよ」としか指示していない。
しかし、この程度の事は、いちいち指示されなくとも、適切に実装できるべきである。
このエピソードはいかがでしたか? ![]() ![]() | ![]() |
投稿者 zunbe : 2005/09/27 03:59:41 | コメント (6) | トラックバック (0)
2005/09/26
|
メールをPOPで受信して、処理を行うプログラムを作らせた。
POPする事自体は、既存のモジュールを使用して簡単にできるので、そう難しいプログラムではない。
できあがったプログラムの動作について、できるだけ多くのメール・サーバから受信を行って、動作確認を行う様に指示をした。
社内にあるサーバ環境では、どうやっても限界があるので、自分が持っているメールアドレスを使って、受信ができるか確認する事になる。
社員がテストが完了したと言ってきた。
どのメールサーバを利用して動作確認を行ったのか聞いたところ、以下の回答が返ってきた。
excite
goo
意味がわからない。
excite や goo のサービスで POP ができるという話は、聞いた事がない。
どうして、これらのサービスを使用して、POP のプログラムの動作確認ができるのだろうか。
社員は、こうやって動作確認をしているのである。
excite、goo のアドレスから、会社のアドレスに転送設定
ぜんぜんダメである。
これでは、アクセスするメール・サーバは、会社のメール・サーバ「だけ」ではないか。
要するに、社員は「できるだけ多くのメール・サーバから受信して動作確認を行う」という事の意味が理解できていないのである。
メールサーバには、vpopmail、qpopper など、様々なサーバが存在し、それぞれ微妙に挙動が異なる。
単に接続するだけなら、プロトコルだけの問題であるから、どの様なメール・サーバであろうと、接続できるだろう。
しかし、ヘッダの保存のされ方などは、メール・サーバ特有の動作がかなりある。
たとえば、ヘッダ情報が2行に渡るとき、2行目以降の先頭行は空白か、タブか。
プロトコル上入ってはならないヘッダ情報が投入された場合に、それが削除されるか、されないか。
などである。
ひとつのメール・サーバにアクセスしただけでは、動作確認を行った事にはならない。
動作確認において、何を確認するべきか、きっちりと理解して作業するべきである。
このエピソードはいかがでしたか? ![]() ![]() | ![]() |
投稿者 zunbe : 2005/09/26 13:04:06 | コメント (2) | トラックバック (0)
2005/09/22
|
今日も、こんな事があった。
社員に、RSSデータを出力するプログラムを書かせた。
タイトルや本文を出力する際に、改行やダグが入っているので、「CDATA」を使用して、元データをそのまま出力するように指示をした。
たとえば、以下のデータである。
-- タイトル --
ずんべ
の日記
--
このデータで、社員が作成したプログラムから生成したRSSデータはこうだ(かなり省略)。
この XML は、元のデータがそのまま出力されていない。
どこがそのまま出力されていないかというと、タイトルと本文の前後である。
XMLのソースを見てほしい。なぜか、タイトルの改行が挿入されている。
つまり、この様にデータが加工されているのである。
-- タイトル --
(改行)
ずんべ
の日記
(改行)
--
明らかにオリジナルのデータと異なる。
社員に、なぜデータの前後に改行を挿入したのかと聞くと、こうのたまう。
「ブラウザ(IE)で見ると改行されていますので、挿入しました。」
いったいぜんたい何を言っているのだろうか。
ブラウザで見た結果が改行されているからといって、なぜ、ソースも改行されていると考えるのだろうか。
ブラウザはビューワであり、我々が見たときにわかり易い様に加工して出力するツールである。当然、ソースコードのイメージのまま出力されているわけではない。
ちなみに、正解のRSSデータはこうである。
ただ開いただけでは、差はわからない。ブラウザで見る限り、見た目は同じに見える。
しかし、それぞれのソースを覗いてみればわかる。前者のRSSデータは、明らかに余計な加工がされている。
テキストエディタで見る事と、ビューワで見る事の違いぐらい、わからんものなのだろうか。
このエピソードはいかがでしたか? ![]() ![]() | ![]() |
投稿者 zunbe : 2005/09/22 13:41:02 | コメント (0)
2005/09/12
|
今日も、こんな事があった。
社員に、XMLを解析するプログラムを書かせた。
たとえば、こんなXMLの解析だ。
-----
<data1>
<title>アイウエオ</title>
<crdate>2005/09/12 01:02:03</crdate>
<item>あ</item>
<item>い</item>
<item>う</item>
<item>え</item>
<item>お</item>
</data1>
-----
データ中にはタイトル(title)と作成日付(crdate)があり、残り(item)は関連情報。関連情報の数は決まっておらず、いくつでも登録される。
このXMLを解析するのに、社員が書いたコードはこうだ(必要部分以外省略)。
-----
%data1 = ();
$item = 0;
foreach $line (XMLデータ)
{
# タグを解析
# $name = タグの名称
# $val = タグの値
# 要素は item に達した?
if ($name eq 'item')
{
$item = 1;
}
if ($item == 0)
{
# ヘッダ
$data1{$name} = $val;
}
else
{
# データ本体
push(@{$data1{$name}}, $val);
}
}
-----
これではダメである。
何がダメなのか、わかるだろうか。
このコードは、行を順に処理していくが、タグ「item」が現れるまでをヘッダとして処理し、タグ「item」が現れたらそれ以降が関連情報だと決めてかかっている。
つまり、このコードでは、「ヘッダとデータ本体を、ある特定の行で分離する」と考えており、この時点で、XMLにおけるデータ構造の生成の意味を失っている。
単に上から順番に走査してデータを投入するなら、XMLである必要はない。CSVで十分だ。
データの記述順序に依存するイレギュラーなケースもないとは言えないが、常識的な考え方として、要素の順番がどのような順番であっても、処理できるようになっているべきである。
データの解析とは、ただ書式を分解すればよいというものではない。
そのデータのデータ構造が、「どのような考え方で」構成されているものであるのか理解してコードを書かなければ、そのデータを正しく解析しているとは言えないのである。
このエピソードはいかがでしたか? ![]() ![]() | ![]() |
投稿者 zunbe : 2005/09/12 00:39:25 | コメント (0)
| [<<先頭] [<前へ] [ 1 2 3 4 5 6 ] [次へ>] [最後>>] | ||