2008年6月26日木曜日

問題解決について

俺が考えている問題解決の手順。
あくまで、『俺流』であることに注意。
最後にも書いたけど、俺自身この手順を踏まないことも多いしね。

  • 1.問題・状況の明確化
まず、何が起こっているのかを正しく把握する。
「よくわからないけど、動きません。バグってます。おかしいです。」の状況は最悪。
この状態が最悪な理由は、顧客(ユーザ)に対して説明ができないことにある。
上のセリフを客に行ったら、多分キレる。少なくとも俺ならキレる。
どのような際に起こった問題なのか。
期待すべき結果はどうだったのか。
期待すべき結果と比べ、どのような違いがあるのか。
という観点から、起こった事象を論理的に纏める。

  • 2. 原因の推定
上で纏めた事象から、原因と思われる箇所をいくつかピックアップする。
ここでピックアップする箇所は、当然のことながら少ないほうが良いのだが、漏れが怖いため、できる限り多めに選ぶ。
原因と思われる箇所を選ぶ、というよりは、決して原因になりえない箇所を消していくという消去法のほうが良いかもしれない。
また、原因となりうる箇所は一ヶ所とは限らない。
複数の箇所が、相互に作用したうえで問題の原因となっている場合もある。

  • 3. 状況と原因の結びつけ
上記でいくつか絞った原因の候補群と、実際に起こっている現象の結びつけを行う。
「Aという箇所に○○の問題があったため、次処理にて不具合を起こしたと思われる」
「Aという箇所では○○を出力する可能性があるが、Bではそれを想定していないため、結果に不具合が生じたと思われる」

のように段階を踏んだストーリー的に表せるとよい。
ここでの仮定は3段論法にならないよう注意すること。
ここまできてようやく顧客にまともな説明ができるようになる。
また、この後の作業についても顧客からの理解が得やすくなる。
そのため、作業量は多いが、可及的速やかにここまでこなす必要がある。

  • 4.裏取り
上で挙げた仮定を実証する。
ここまで来てようやく実際に手を動かすわけだが、やみくもに原因と思われる箇所に
手を加えることはできるだけ避けること。
問題を解決しなければいけないという逸る気持ちは抑え、上の仮定を実証することに全力を注ぐ。
この際、できればテストシナリオを作成し、それに沿って作業を行うとよい。
「Aという箇所に○○のような修正を加えた場合、仮定1が正しければ結果はBになるし、正しくなければ結果はCになる。」
のようなシナリオをいくつか作成し、実際に作業を行うことでいくつかあった仮定を絞り込んでゆく。
最終的に仮定が1つになれば、それがこの問題の原因であると言えるわけである。
また、ここまでくれば大概は問題に対する解決案もいくつかでてくることと思う。

  • 5. 問題の解決
ここまでで導かれた問題・状況とそれに対するいくつかの解決案を顧客に提示し、実際に行う解決法を選択してもらう。
あとは何も考えず、手を動かせばよい。

  • おまけ
実際問題として、ここまでの手順をきちんと踏まなくてはならないということはない。
事象を聞いた時点で原因が思いつく場合は多々あるし、それが正しいことは日常茶飯事である。
問題解決はスピードが命なので、即解決ができるのであれば、上のような面倒な手順を追うことは時間の無駄とも言える。
ただ、何をしてよいかわからず、ただやみくもに手を動かすよりは一つ一つの手順をおって行ったほうが
解決は早いし、顧客への説明もやりやすくなる。
状況に応じて使い分けることが必要と言える。

2008年6月19日木曜日

plaxoを試してみる。

http://www.plaxo.com/

最近暇なので似たようなサービスをいろいろ登録している。
brightkiteとかFacebookとかplaxoとか。

とはいっても周りで使ってる人があまりいないので
あくまで自己満足のレベル。

ただ、plaxoはかなりいい。
何がいいって。カレンダーの同期機能がうれしい。
google Calenderとicalとoutlookでバッチリ同期をかけてくれるし
インターフェースもかなり分かりやすい。

カレンダー同期サービスと割り切って使うのもアリかもしれない。


2008年6月9日月曜日

ロジカルライティング読了

積ん読消化月間。今日はロジカルライティングを読んだ。
全体の流れとしては、
  • ロジカルシンキング基礎
  • ロジカルシンキングで纏めた内容を文書化
  • モノを書く上でのテクニック
という流れ。
内容としては、今更・・・的なものも多いけれど、ボリュームも少ないので一度読んでおくのはアリかな。

気になったポイントを備忘。


  • 読んだ人に対して、自分のする行動をとってもらえるようなドキュメントをかく。
  • MECEのフレームワーク一例
  •  ・自社の現状をとらえる3C(競合[Conpetitor]・顧客や市場[Customer]・自社[Company]) 
  •  ・マーケティングの4P(サービスの特徴[Product]・価格[Price]・訴求方法[Promotion]・販売チャネル[Plice])
とりあえずこのフレームワークは俺が書くようなドキュメントではちょっと役に立たないかも。
実際にモノをかくうえで自分なりのフレームワーク的なものを考えてみたい感じ。


  • 論理の組み立て「結論から根拠へ」 → 書き手にとって結論が明確であり、根拠もだいたいわかっている場合。
  • 論理の組み立て「根拠から結論へ」 → 多量の情報はあるが、結論と根拠が曖昧
結論が曖昧である場合はテーマの再定義や細分化が必要なのでは?

  • 論理の組み立てを行う際には、各項目の独立性及び項目間のつながりに注意する。
項目を単体で読んだときに理解できること。下位の項目が上位の項目の根拠になっていること。

  • 結論を先に書くか、論拠を先に書くか。
読み手に伝えたい方・読み手が求めている方を先に書く。根拠から結論を導く過程を伝えたい場合は根拠から書く場合もある。

  • 導入部には当該ドキュメントの存在理由を書く。
  • 導入部には読後、読者が起こして欲しいアクションを書く。
  • 記号やスペースなどを利用して視覚化する。
  • 同レベルのセンテンスはMECEの関係に
  • センテンスの上下関係はSo Whatの関係に
  • 付帯条件について、「場合によっては」という曖昧な書き方ではなく、具体的な条件を書く。
  • 曖昧な言葉に注意する。3文字略語や業界用語に注意。
  • 体言止めを使うと単なるキーワードの列挙になりがちで、重要な情報が抜けやすいので注意する。
  • 否定形で終わると抽象的になりやすいので注意する。肯定形で具体的に。
「AはBではない。」→「じゃあAはなに?」

  • 「〜は以下の通り」のような表現には注意する。その後に細かい情報を箇条書きなどで書く場合でも概要をきちんと書いておくべき。
  • 「〜により、」を多用すると一文が長くなり、結果読みにくくなる。
  • 「〜される」のような受動態を使うよりも、能動態にしたほうが主語がはっきりして分かりやすい。


ロジカルじゃないな〜(汗

ロジカル・ライティング (BEST SOLUTION―LOGICAL COMMUNICATION SKILL TRAINING)

2008年5月7日水曜日

マインドマップが使えない

某マンガで取り上げられたり、自己啓発本が結構出たりして、それなりに周知されてきたマインドマップ

俺にはどーにも使えない。

思考をそのまま紙にかくから纏めやすい、と聞くけど、あの放射状な感じが俺の思考とは相いれない感じ。

論理展開って普通左から右に、上から下に流れてくもんじゃないの?放射状じゃなくない?

俺みたいな凡人だからそうなのであって、天才肌にはしっくりくるものなのかもしれないけど、俺にはどうにもある種の窮屈さがかんじられちゃうんだよなぁ。

2008年5月4日日曜日

tumblr

tumblrをちょっと使って見ている。

twitterとおんなじようなもんだろうと思ってたけど、実際に使ってみてコンセプトの違いに気がついた。
twitterもtumblrもミニブログとか言われているけど、
両者の違いは、情報の発生元にあるのかなぁとなんなく思ってる。

twitterはつぶやき、つまり自分からの情報を出力するけど、tumblrはもともとwebに公開されている情報を再出力する感じ。再出力というよりは、新聞の切り抜きにちかいかもしれない。

まぁ何はともあれ実際に使ってみるとなかなか楽しいサービスだった。いまさらだけど。

2008年5月2日金曜日

クロージャとオブジェクト指向とJava

クロージャがイマイチ理解できない。
全く理解できないわけじゃないけど、でっていう感じ。


とりあえず、俺の理解的には、
宣言時の変数(状態?)のスコープを引き継ぐ高階関数
だと思っている。

関数ポインタとの最大の違いはスコープを引き継ぐところだというのはわかるんだけど。

結局、状態をもつ関数ってことなんだから、オブジェクトじゃないの?と思ってしまう。

Java7で導入されるみたいだからそれまでに理解しておきたいんだが・・・。

rubyとかで実際に使ってないと難しいかなぁ。

2008年5月1日木曜日

とりあえず、「ふつうのHaskell」は読み終わった。

サンプルも書いた。
でも、ぶっちゃけよくわからんよ、Haskell。

とりあえず、fizzbuzz問題でも解いてみる。れんしゅう。


** 1から100までの数字を列挙。ただし、3の倍数の時はfizz、5の倍数の時はbuzz、15の倍数の時はfizzbuzz。

普通の言語で組むなら100まで回したループの内部で条件分岐、って考えるのがシンプルだが。
haskellループないし。
1から100までのリストを用意して各要素に対してfizzbuzzな関数を適用して出力。かなぁ。

とりあえず1から100までのリストを出してみる。
>|haskell|
main = putStr [1..100]
||< 怒られた。putStrにリストは渡せないか。じゃあ、リストを展開して出すか。 >|haskell|
main = putStr unlines [1..100]
||< 怒られた。unlinesは文字列のリストじゃないとダメか。 >|haskell|
main = print [1..100]
||< でた。んー。最終的な出力形式をどうするかって問題がありそげだけど、とりあえずこれでいいか。 ふむ。入力はIntのリストだけど、出力にはfizzやらbuzzやらが入るんだから、Stringのリストになるのか。 つーことは、fizzbuzz関数の型は [Int] -> [String] か。
とりあえず、fizzbuzz関数を組み込んでみる。

>|haskell|
main = print $ fizzbuzz [1..100]

fizzbuzz :: [Int] -> [String]
fizzbuzz cs = map show cs
||< 問答無用でshow関数使ってIntをStringに変えちゃってるけど、ここに条件入れればおけかな。 >|haskell|
main = print $ fuzzbizz [1..100]

fuzzbizz :: [Int] -> [String]
fuzzbizz cs = map test cs
where
test c = if c `mod` 15 == 0 then "fizzbuzz" else
if c `mod` 5 == 0 then "buzz" else
if c `mod` 3 == 0 then "fizz" else show c
||< でけた。次。 ** 素数を出す。 Haskellとかすごい得意そうな問題だな。 んー。考え方としては、2以上の数のリストを用意して (1が入ると面倒なので) そのリストから先頭一つをとって、その数で割れるかどうかのフィルタリングをして、ってかんじかなー。 こんな感じ? 2, [ 3, 4, 5, 6, ...] →のリストに対して2で割れないモノだけ抽出するフィルタをかけると 2, [ 3, 5, 7, 9, ...] そしたら、→のリストに同じことを繰り返してく。 2, 3, [ 5, 7, 11, ... ] →のリストがなくなるまで続けて、最後に連結して終わり。 調べればもっと効率的な解法がありそうだけど、とりあえずこれで組んでみる。 >|haskell|
main = print $ prime [2..100]

prime :: [Int] -> [Int]
prime [] = []
prime (x:xs) = x : ( prime $ filter check xs )
where
check c = if c `mod` x /= 0 then True else False
||<>|haskell|
main = print $ prime [2..100]

prime :: [Int] -> [Int]
prime [] = []
prime (x:xs) = x : prime [ c | c <- xs, c `mod` x /= 0 ]
||<

こんなもんかな。

http://d.hatena.ne.jp/masato_spica/20080609