プロジェクトの工数算出というものに対して非常に疑問に思うことがある。
工数とは、各機能を算出してそれらを足していき、そこにある程度のスパイス(保険)を足して算出する感じだろう。
ここに、スパイスというよくわからないものがあるが、このスパイスが経験でズバッと3倍とか、1.5倍とか…
ここまでいい加減でないにしても、それぞれの機能に複雑度・影響度を加味した係数をかけて、足していき・・・・・
って、これで実際に工数を出してみても、本当にその考え方あってるの?と疑問に思う。
そもそも、
そのプロジェクトはいつまでに完了(納品)しなければいけないのか、とか?
何人投入するのか(できるのか?)
が、関係するんじゃないんかなー。
それらは、工数を出してからというかもしれないが。
だったら、導き出せる工数というのは場合の数だけ複数あるのではないだろうか?
そんな状況を示すのは、こういう会話ではないだろうか?
A:「この機能開発の工数ってどのくらい?」
B:「んー、まあ、ほとんど外部要因を考慮しなければ、作るための工数は12人月くらいかな?」
A:「じゃ、1人月 100万だから、安全をみて1500万くらいでいいかな?」
B:「んー、でも、開発にかけられる期間にもよるかな?」
A:「発注がきてから、3か月くらいまでに完成していればいいと思うよ。」
B:「わー、結構忙しいな、じゃ、人数も増やすから、保険で2倍にして24人月くらいで・・・」
と、ここで、各会社により、人月単価とか、保険の倍率とかはその時それぞれだが、
工数を答えている方も、経験からなんとなく、期間や、投入できる人数を踏まえて「勘」で、答える。
これを聞いたほうは、2倍もとっているんだから安全な数値だなと思うでしょう。
言っているほうは、十分な保険をとっているという感覚はあるが、実際はそのくらいになってしまうという実感。
または、実際にはこれより遅れてしまうなんてことも普通にあるのではないでしょうか?
これでは、予定の2倍も認めているのに終わらないなんて、怠けているにも程がある!!
ということになってしまう。
または、初めから24カ月と伝えるようになる。
根拠はということになると、期間が人数が関係しており、
それらが決まっていない以上、つつじつまが合わず、どう考えても、半分程度で終わるのになーという感覚を持たれてしまう。
そして、本当のことを言わないやつらだ・・・と。
実際、「勘」は、理論より正確ということもあり得るが、できるだけ、「勘」の要素は減らした方が、他人には納得がいくはずだ。
そもそも、プロジェクトを周りに認知してもらうには、実施部隊に意味があろうとなかろうと、根拠が必要になるのだ。
そして、誰もが予定通りいくことを願っているのだ。
では、これらの「勘」は、どんな経験から来ているかと考えると・・・
経験1:「多くの人数で行うよりも、少ない人数で行う方が効率よく終わる(ある時は早く終わったりする)」
経験2:「期間を短くするためには、いろいろと同時進行しなければいけないから、その分人数が多く必要」
経験3:「ある程度独立した機能があったら、同時進行してもリスクは低くなる。」
要するに、ある程度の必要な人数というものもあるが、必要以上に増やしても、余計工数がかかる。
また、機能はサブシステム(ある程度独立)ごとに分けられれば、工数は減らすことができる。
ここでジレンマが発生する。
1と2では、人を増やせば、ある仕事量を早く終わらせることができるが、人を増やせば仕事量が増える。
要するに、人が多くなれば多くなるほど、それぞれの関係が複雑化し、よりやらなければいけないことが増えるのだ。
(もしかしたら、メンバーへの教育かもしれない)
つまり、工数は増えるのだ。では、何人がいいの?
一人より二人のほうが早く終わるのは理解できるし、
二人よりも三人・・・・
・・・・・・・・
でも100人にすると、何だか収集がつかず、余計混乱していく気がする。
では、どのように考えればいいのだろうか?
工数計算の方法を改めて調べてみたものの、どうも、どれだけ人数をかけられて、どれだけの期間の制限があるという前提で・・・
という条件を踏まえると見つからない。
(もしかしたら、勉強不足なだけかもしれないが、私には見つからなかった。)
そこで、自分なりに考えてみることにした。
したがって、何の根拠もありませんが、できるだけ実感にしっくりくるようにしてみました。
(あくまで、私の独断と偏見にみちた計算です。)
そこで、まず考えたのは、
私はここで、人が一人増えると、増える前の工数より10%程工数が増えると仮定してみました。
というのも、人数が増えれば、増えるほどそれぞれの人がネットワークとして関係をもつという事です。
それに、増えれば増えるほど、できない人に合わせていく必要があり、それでできる人の仕事量もより増えてしまうという考え方です。
あまりに、現実に忠実すぎると複雑になるので、複利的に工数が増えてくるという事で表現することにしました。
つまり、ここでは、それらの人同士が増えた分だけ、深く依存しあうという前提です。
ちょっとあいまいですが・・・
(あまり、依存しあわないというケースは後で説明します。)
これで、考えてみると、12人月の工数は一人で行うと12人月だが、2人で行えば、
12 + 12 × 0.1 = 13.2 (人月)
同様に、3人では・・・
13.2 + 13.2 × 0.1 = 14.52
実際にかかる期間はといえば、
13.2 / 2 = 6.6 (か月)
14.52 / 3 = 4.84(か月)
これを数式にしてみる。

純粋工数 :上の例で12人月のこと。つまり、組織や、人が絡むことにより増える工数を除いた工数を示す。
人的複雑計数:上の例で10%工数が増えるということ。10%ということは1.1になる。
期間 :上の例で、実際かかると予測される期間です。
この式に人数を増やしていくと、だんだんと期間も減ってくる。
しかし、10人、11人(2.829537 カ月)を境にむしろ必要な期間が延びてくる。
これで、経験1と経験2がうまく適用できたきがします。
できるだけ早くという前提では、10人以上かけても無駄だということです。
ちなみに、このときの工数はといえば、約29人月ということだ。
また、3か月以内という条件では、8人投入ということになり、「保険で2倍」という24人月とほぼ一致します。
(というか、これ以降します例のためにあえて近い数字なのですが・・・)
5か月以内でという条件では、3人投入で、工数は 15.2か月です。
これで、同じ機能なのに、期間が変わる=作業人数が変わる で、工数が変わってしまうということがある程度根拠になるのではないでしょうか?
ただ、これでは、「2か月以内に納品してほしい」という要望が来たときに、理論的にできません。ということなってしまいます。
実際にはそういうことはないでしょう。
もしくは、もうちょっと工数を減らしてよ。
と、そこで、経験3:「ある程度独立した機能があったら、同時進行してもリスクは低くなる」の登場です。
これで、独立した機能ごとに、グループを割り当て、計算上は、1つのグループの工数を減らすことができるというわけです。
したがって、純粋工数が12人月を2つのグループに分けて、6人月にしようというわけです。
しかし、実際には、グループを分割しても、それぞれをつなげなければなりません。
ガントチャートのエディタ上で、線を2つに分けてスライドさせればOKというわけにはいかないのです。
実際には、サブシステム間の接続ルールを決めなければいけなくなります。
もっと、プログラムチックに言えばAPIを定義するということでしょうか?
しかも、サブシステム間の関係は、人と人の関係よりは、もっと工数リスクが高くなるのが普通という気がします。
でも、工数リスクが上がっても、トータルで工数は減らせるということは、経験的にわかっています。
これは、一体どういうことでしょうか?
仮にまったく工数が同じだけかかる2つのサブシステムに分割できたとしましょう。
そして、それらの2つのサブシステムはまったく同時に依存関係なく、進めることとします。
ただし、最後につなぐ必要があるので、ここでは、その係数が1.2とし、最後にその分だけ掛け算をします。
(つまり、人と人は10%の仕事増加だかが、グループ間は20%の仕事増加ということです。)
ここでは、工数の増減を知りたいので、上の例で、「3か月以内」=「8人の投入」という計算になったので、同様に8人投入できることとします。
つまり、1つのグループには4人です。
純粋工数は1グループにつき6か月です。
これを前の式に当てはめると、実際の工数は・・
6×1.1^(4-1) = 7.986
これが、2つのグループで2倍して、係数1.2をかけると
7.986×2×1.2 = 19.1664
になります。
したがって、工数が約24人月から約19人月まで5カ月ほど工数を減らせたという訳です。
さらに、工数を減らせたということは完成までの期間も減らせたわけです。
19.1664 / 8 = 2.39 (か月)
になりました。
これを数式で表せば、
のようになり、ここで分割数を割って、かけているのでそれらを相殺すれば、
のようになります。
ただし、この式の条件は、前にも書いたように、まったく同じ工数で分割できることであり、また、それぞれの分割後に割り当てる人数も平等という前提です。
実際には、工数が違うグループになり、適用する技術ごとに割り当てる人が違うなど、もっと複雑になるとは思いますが、
ここでは、関係性が表すという目的から、すごく(計算上)理想的にサブシステムが分割できる前提で、数式モデルもわかりやすく作れると思うので、そういう前提にしました。
これで、先の2カ月以内で終わらせるための工数は?
上の式に当てはめて探してみると、工数は約23人月なのです。
しかし、条件がある。そう、同時に投入できる人数です。
その人数は12人必要となる。
これは、機能を2つに分解し、6人のチームとするか、
機能を3つに分解し、4人のチームとするかだ。
たとえば、割り当てられるのは上限6人として計算すれば、残念ながら2カ月では完成しない。
という計算になる。
このように、もとある工数見積もりの200%とかいう話ではなく、
実際にこれらの因果関係を見積もって、間接工数をそれぞれ一定の割合として人数とともに考慮していけば、
12人月が24人月にも膨らむことが示せたのではないでしょうか?
さらに、実際のプロジェクトでは、この計算に入れられない一定の阻害要因が必ずと言っていいほど発生します。
よくあるのが、顧客が要件を決めてくれないなど。
でも、200%の安全をとっているという安心から、それでOKとしてしまい許してしまう事は多々あります。
しかし、計算では、実は最初の12人月の200%は安全ではなく、必要な間接工数だったのです。
したがって、余分な保険はほとんどなく、非常に他の要因に対して甘い見積もりだったというわけです。
ただ、まったく、予想できない問題に対してコストを反映するのは現在のコスト競争の中ではできないことかもしれませんし、
それらが発生した時点で顧客と相談でその分の期間延長は呑んでもらえることも多々です。
だけど、実際にはそれ以上に遅れる。それも信じられないほど。
そこには、もうひとつ大きなポイントが上の式にはあります。
12*2 = 24 と 12 * 1.1^(8-1) = 23.xxxx(ほぼ24)
を見直すと、 「2」と「1.1」はやはり、経験(統計)と勘によるものであることには変わりありません。
この値は非常に、ぶれやすいと言えるでしょう。
たとえば、それぞれ「10%」ほど読みを間違えたとしましょう。
(もしくは10%程度であれば、その違いを工数として幅を持たせることを許しましょう。)
実際には1.1という係数自体も人が増えれば増えるほど、大きくなるぶれる可能性が高くなると思うので、
人数が変われば読み間違いやすいでしょう。
また、期間が延長されれば、もともといた人は外れて、新たに人が入ってくるということもよくあるのです。
これで、人的複雑係数の値は変わってきてしまいます。
では、計算してみましょう。
12*2.2 = 26.4
12*1.21^(8-1)=45.57
とかなり、違いが出てきます。
まあ、顧客も責任あるし、4人月くらいはいいか?と思っていたのに・・・
(これでも、2400万の案件で、400万円の上乗せを顧客になっとくしてもらうには至難の業です。)
でも、下の計算ではほぼ2倍弱に膨れ上がっているのです。
つまり、もし、締め切りも3か月から1年ぐらいまでなら許せる。人数は不定。ただし、上限は8人くらいかな。
という前提で、12人月ほどかかりそうな機能を実装するための工数は
「12人月~46人月」
こんなことを聞いた、営業やお客さんは「はー、意味わかんね。適当なこと言って・・・」
と思うかもしれないが、ITのプロジェクトは、普通に予定の2倍、3倍かかってしまう事がしょっちゅうあるということが、見事に反映されている気がします。
もしくは、無理やり期間で帳尻を合わせようと、仕様をけずれば、12人月の仕様から6人月の仕様になってしまうなどです。
そして、小さな読みの間違いでも、結果は大きくぶれるという事です。
「情マネ流マーフィーの法則その2」
情報システムの開発では、計画時の2倍の費用と2倍の時間がかかり、1/2の機能しか実現しない
も、同じような事を言っているので、それなりに反映できている気もします。
どうでしょうか?この理論。
ただ、この理論はあまりにもモデルを単純化しているので、実際には、ここからこれらの関係をもつ要素の依存関係を考慮していき、
ガントチャートなどを作成しながら、さらに関係を見積もっていくのでしょうが・・・・
前回は、HTMLメールを作成したが、今回は、添付ファイル付メールです。
メールの送信の全体の流れは変わりませんので、今回は添付ファイルのメッセージを作成する部分だけ説明します。
ただし、今回もライブラリを新しくなったので、こちらからもっとも新しいバージョンをダウンロードしてください。
前回、setTextBodyにちょっとバグを埋め込んでしまいましたしたので、こちらも修正しました。(詳細)
さて、添付メールの説明です。
といっても非常に簡単です。
-
var contentType:ContentType = ContentType.MULTIPART_MIXED;
-
var mimeMsg:MimeMessage = new MimeMessage(contentType);
-
:
-
省略
-
:
-
var filePart:MimeBinaryPart = new MimeBinaryPart();
-
filePart.setAttachementFile(File.desktopDirectory.resolvePath("image.jpg"),"添付ファイル.jpg");
-
mimeMsg.addChildPart(filePart);
-
-
sender.send(mimeMsg);
-
sender.close();
で終了です。
ここで、MimeBinaryPartは、自動的にContent-Typeが、application/octet-streamになります。
また、
-
filePart.setAttachementFile(file:File,filename:String):void
で、添付ファイルをつけます。
上の例のように、添付するファイルが画像の場合には以下のようにContent-Typeを変更してもいいかもしれません。
-
var filePart:MimeBinaryPart = new MimeBinaryPart()
-
filePart.contentType.setMainType("image");
-
filePart.contentType.setSubType("jpeg");
または、
-
filePart:MimeImagePart = new MimeImagePart();
とすることで、image/xxxx のようになります。
xxxxの部分は、添付するファイルの拡張子で変わります。
最近、The GOALを読んでからちょっとだけ、TOCを勉強してみようかなと思いかじっているうちに、ITプロジェクトの管理に関しては本格的に勉強する価値があるのではないか?という気がしてきた。つまり、自分で経験的に知っているというレベルから、人に説明するうえで体系的な知識として使えるのでは?という意味です。
現場でITプロジェクト管理をやっていると、まず、政治的関係者は、PMBOKなどの言葉や、また、工学的な理論などよりも、マーケティングやら販売手法やらを考えている人たちの言葉に近いほうを形式的に学んだほうがいいような気がする。
というのも、PMBOKなどをかじる機会があったが、あまりに規模がでかすぎるという気がした。
何々、何々をするべき・・・
ってあるが、ITプロジェクトでは数百万から2,3千万程度の案件では、実際の実働部隊は二人くらいで、それ以外すべて管理者なんてことだってあり得る。ほとんどは、管理者の管理に翻弄され、実動する人たちに何も伝えられないって場合があるのではないだろうか?
で、実際には、実動する二人が勝手につくってしまってある程度できてから、やっとまともな話ができる状態になる。
そんなのが普通というときに、だいそれた「PMBOK」やら高度情報処理試験での「プロジェクトマネージャ」の理屈・知識は本当に通用するのだろうか?
あまりに、正論すぎる気がする。
(知らないより、知っていたほうがいいのはよくわかるし、それに、よく理解していれば使えるのもよくわかる。でも、小さい(予算が少ない)案件ほど、かなりの変則的応用を求められると思うので、小さい案件で基本を学び、徐々におおきくってプロジェクト管理の手法の学習としては無理があるのではないだろうか?関係者の調整力を学んでいくっては有効だが・・・
それに、学問が正論じゃなきゃ意味がないだろ!っていう気もする。)
それよりも、ほとんどうまくいかなく、問題と間違いだらけという前提から始めることができる「制約理論」ってのは、かなり現実にフィットしている気がする。
たとえば、「スケジュールというのを意思として決める」というより、制約として上から落ちてくるってのが普通だと思うし、使う技術・環境なんかも、選択するっていうよりも、今いるメンバーやハードで何が、どこまでできるか?っていう制約って考えるということになる。
たとえば、何かを変更したときに、カッコよく言えば「変更管理」っていうが、要は間違いに気付いただけだったりする。しかし、それを知る手法がわからないとか・・・
それに、たいてい失敗しているプロジェクトをみると、崇高な感じのドキュメントやら、過剰に投資した環境が多々見られる。なんでこんなになってるんだー。ってみると、コンサルタントなどを通して形式的には正しい方法をとっていたり・・・
という意味では、こんな時代に必要なのは、「失敗しないためのプロジェクト管理」ではなく、失敗の中から「成功させる」を生み出す理論のほうが大切なのではないだろうか?
そう考えれば、人は自由な選択と意思から計画的に生み出すものよりも、多々ある制約から生み出すものの方がよりいいものが生まれると思ってしまうのは私だけだろうか?
私も過去、自分がある制約からやりたいことができず、んー「まあ、これで今のところはいいか!?時間があるときにきちんと作りなおそう」と言って割り切って機能を実装したものが、ほかの会社ではその機能をみて、どうやってそれを実装しようかと試行錯誤していたということを聞いた。
それは、まさに制約から偶然生まれた「そういう事」だったのかも知れない。
次回は、「制約理論」と「サーバ管理」の関係を書いてみたと思う。
以前公開していた、ZIP圧縮・解凍ライブラリですが、airxmailと同様にGoogle Codeに移動して公開することにしました。
こちらです。
これに伴い、ライブラリ名をairxzipに変更し、パッケージ名も変更しました。
まだまだ準備不足ですが・・・・
また、これ以外にパスワード付きZIPファイルにも一部対応しました。
ただし、ZipCrypto(PKWare crypto)形式の暗号化のみです。
こちらで説明されている、VII. Traditional PKWARE Encryptio という形式のみです。
この形式はWindowsXPなどで使われている暗号形式ですので、まあ、ふつうの人が一般的に目にするレベルでは使えるようになったと思います。
パスワード付きZIPファイルの使い方は以下のようになります。
作成(圧縮)方法
-
var writer:ZipFileWriter = new ZipFileWriter();
-
// パスワードの指定
-
// パスワードの指定がなければ、通常のZIPファイルが作成されます。
-
writer.setPassword("pass");
-
writer.open(File.desktopDirectory.resolvePath("crypto_airxzip.zip"));
-
-
// Add ByteArrayとして追加する場合
-
// ファイル名は"sample.txt"とする。
-
var data:ByteArray = new ByteArray();
-
data.writeUTFBytes("SAMPLE");
-
writer.addBytes(data,"sample.txt");
-
-
// Add Directory
-
// 空のディレクトリを追加する
-
writer.addDirectory("Foo1");
-
-
// ローカルにあるファイルを指定する場合
-
writer.addFile(File.desktopDirectory.resolvePath("image.jpg"),"Foo1/image.jpg");
-
-
// close()を忘れずに!!
-
writer.close();
解凍方法
-
var reader:ZipFileReader = new ZipFileReader();
-
var file:File = File.desktopDirectory.resolvePath("crypto_airxzip.zip");
-
reader.open(file);
-
reader.setPassword("pass");
-
var list:Array = reader.getEntries();
-
-
for each(var entry:ZipEntry in list){
-
if(!entry.isDirectory()){
-
if(entry.getFilename() == "sample.txt"){
-
try{
-
var bytes:ByteArray = reader.unzip(entry);
-
log.debug("sample.txt : " + bytes);
-
}
-
catch(e:ZipError){
-
log.warn(entry.getFilename() + ":" + e.message);
-
}
-
}
-
}
-
}
最近ノートパソコンを使って作業をすることも多くなり、
自宅にあるデータを外出先からみたいという気持も多々あり、
また、複数あるPCで共有するデータをNASのようなところにおいておきたい。
ダウンロードしたフリーのソフトなどは、たびたびダウンロードするようなこともしたくないし、
なにより、また、探すのが面倒だ。
でも、「新たな機器を増やしたくないなー」と思っていたので、仕方がなくUSBメモリで共有していた。
そこへ、部屋の模様替えに伴い、ブロードバンドルータから線がながーくでてしまうことになり、
また、Wiiとかにも接続したいしと・・・いろいろ調べるよりも新しくしてしまう方が楽かなということで、
思い切って数年ぶりに買い替えることにした。
予算は1万円程度。
さらに、上の用途を満たすために、
「VPN機能(外出先から自宅へのアクセス)」
「NAS機能(ネットワークストレージ機能)」
をみたしているものにした。
いやー、ほんの数年前までこんなことは簡単に、かつ安価にできなかった気がするが、進歩は早いものです。
そして、実際に買ったのはこれです。
BICで9800円のポイント20%付きで買いました。
そして、後で、このポイントを使って8GのUSBメモリを買いました。
さらにこのルータはWOL(Wake On LAN)というLANを通してPCに電源を入れることもできます。
したがって、必要になったら電源を入れるということもできるのです。
このあたりもルータですべてできてしまうのはいいですね。
家庭的にはルータに常に電源がはいっているのは許せますが、
多少なりともPCなどうるさい機器が使わないときに電気が入っているのは嫌ですから・・・・
ただし、IPが動的の場合、DynamicDNSのサービスを使わないと実質的にはできないのでご注意を。




