2013/01/20
苦労と値段
メルマガ本文を読まずにここだけに反応するのはまずいかも知れないけど:
Life is beautiful: 今週の週刊 Life is Beautiful:1月22日号
「オープンソース」というムーブメントには、Microsoft 時代から注目して来ました。「なぜ苦労して作ったソフトウェアを無料で公開するのか」という部分に関して、かなり理解できるようになったとは言え、未だに抵抗があります...
なぜ「なぜ苦労して作ったソフトウェアを無料で公開するのか」という疑問が出るのだろう。正確に言えば、なぜ苦労と価格をリンクさせるんだろう。
価格は需要と供給で決まるんで、「どれだけ苦労して作ったか」は本質的に価格を決めるパラメータじゃないし、リンクさせる必要もないよね。ビジネス的には「なるべく少ない苦労で高く売れる」のがいいわけだし。
もちろん喰ってくためにソフトを作っているという前提なら、投入する労力が利益に見合わないと持続できないので、「苦労に見合う価格」が供給側の価格の下限になる。そして供給側に複数の競争相手がいる買い手市場なら市場価格はその下限まで下がるので、結果的に労力の量と価格が釣り合うことになるわけだけれど。それはいくつもの前提のもとでの結果にすぎないし、たとえこの前提のもとだって、「これだけ苦労したからこの値段で」は理屈が逆で、「この値段で売れるからここまで労力をかけられる」という話になるはずだ。「こんだけ苦労したんだからこの値段で」っていうのは、価格が常に原価で決まるという思い込みに通じる気がする。
現実には上の前提が成り立たない場面っていくらでもあるわけで。喰ってく手段が別にあるなら、たとえ見返りを求めるにせよそれが金銭である必要は全くないわけだ。自分のまわりを見回しても、全然金にならないことに膨大な労力を注いでる人はたくさんいる。むしろ「なぜ有料にするのか」=「なぜ見返りが金銭でなくてはいけないのか」に自覚的であるべきじゃないかなあ。(有料にしたらダメとか無料が偉いとか言ってるわけじゃないよ。金を取るのは「喰ってゆくため」とか「買い手にそれだけの価値を提供するから」とか「サポートに対応するためのリソースが必要」とか「金という形で評価を得たい」とかいろいろあるはずで、自覚的であれば価格の説得力も増すはず。「苦労したから金を取って当然」っていうのは短絡的なんじゃないかな、って話)。
(追記2013/01/24 10:39:40 UTC): 立場によって受け取り方がいろいろあるようだけど、プログラミングの仕事と役者の仕事を両方やってる身からすれば、広い意味で労力と報酬は結びついてないってのは経験的真実ですな。例えば報酬が一般的に「CM > 映画 > 舞台」なのに費やされる時間は「舞台 > 映画 > CM」だったりするし。まあ個々のケースはいろいろだけど。 なんつうか、確かにお金というのは為される仕事の指標なんだけど、あんまりきちきちに結びつけちゃうと世知辛いと思うんだよね。お金は、あるところから頂けばよい というユルさが多少ある社会の方がうまく回るんじゃないかな。「あるところから取らなければならない=金持ち許すまじ」となってしまうとそれはそれでまた硬直するんだけど。
2013/01/19
プログラマとGnuCashと複式簿記
@higeponがオフラインの家計簿ソフトを探していたので、独立してから10年来使ってる GnuCashをおすすめしといた。 GnuCashは実用的なSchemeアプリケーションでもあるので(結構な部分がGuileで書かれている) こういう機会のたびにサジェストしてるんだけど、最初のハードルがちょい高いみたい。 考えてみたら自分も初めは何が何やらわからなかったので、 最初の頃に戸惑ったポイントについて書いてみる。
なお自分はそれまで複式簿記を学んだことがなく、入門書を読んだり会計士さんに 相談したりしながらなんちゃって帳簿でやってきたので、 おかしなところがあれば突っ込んでほしい。あと、GnuCashでしか複式帳簿をつけたことがないので、 複式簿記一般の話とGnuCash特有の話が混ざってると思う (ひとつの言語で プログラミングを学んだ人と同じ状態)。
(私は簿記を学ぶにあたって英語の本を使ったのでわかりやすいようにアカウント名も英語のまま使っているけれど、GnuCashは日本語化されているので日本語でも使える)
複式簿記
それまで複式で帳簿をつけたことが無ければ、GnuCashの一番のハードルは その概念を理解することだと思う。ただ、GnuCashはアカウントごとにわかりやすい 表示をしてくれる ("Debit"/"Credit"のかわりに、例えば銀行口座のアカウントなら "Deposit"/"Withdrawal" とか) ので素人にも使いやすい。
で、簿記の本を読むと色々書いてあるんだけど、会計の世界の言葉は 普段自分がいるプログラミングの世界と離れすぎてていまいちイメージが掴みにくかった。 自分なりに咀嚼した理解は、
複式簿記は制約システムだ。
というもの。
小遣い帳みたいな単式の世界では、「自分の持っているオカネの残高」という状態を 持つオブジェクトが中心にあって、外の世界から収入があるとそれが残高の増加をもたらし、 外の世界への支出があるとそれが残高の減少をもたらす。 オカネを使うことや得ることは、個々のメッセージに不可分に結びつけられている。
複式の世界では、何が収入で何が支出かというのは実はシステム自体と関係がない。 システムは複数のアカウントから構成されて、アカウントの間で形式的に 数値のやりとりが行われるだけである。 そのやりとりのメッセージそのものに「収入/支出」といった意味はない。 使う側で、「このアカウントはこの仕事の報酬」 「このアカウントはこの項目の出費」といった意味づけをしてやるのだ。
プログラマ的には、形式システムと、その意味づけとの関係に似ていると思える。 一旦、現実世界のもろもろを「アカウント」に対応づけてしまえば、 後はその意味を忘れて形式的な操作だけをしていればよい。
さて、「アカウント」には5つの種類がある。Assets, Liability, Equity, Income, Expenseだ。そしていかなる時でも、次の等式が成り立つ。
Assets + Expense = Liability + Equity + Income
この制約が満たされるように、アカウント間で数値のやりとりが行われる。
assetsは銀行の口座とか、固定資産など。liabilityはクレジットカードの 残高など借りてるもの。equityは資本。incomeとexpenseはそのまんま。
例えば、ある仕事をして報酬$1000を得たとする。 これを記述するには、incomeアカウントの数値を$1000増やせばよい。
ところがincomeが$1000増えるということは上の式の右辺が$1000増えるので、 左辺も同じだけ増えないとまずい。普通は報酬はすぐに銀行に預けるので、 Assetsの中にある銀行口座のアカウントが$1000増えてバランスすることになる。
何かを買って$500使ったとしたら、それはexpenseのアカウントが$500増えたということ。 手元にあるお金 (assets) から支出した場合は、assetsが$500減って等式が保たれる。 でも借金して買った場合 (クレジットカードで買う場合がそうだ) なら、 expenseが$500増えた分は、liabilityが$500増えてバランスされることになる。 (その$500のクレジットカードの残高を後で支払う時に、assetsとliabilityがともに$500減る)。
「収入=残高を増やす」/「支出=残高を減らす」という考えを、「収入も支出も それに対応するアカウントの数値の増加であり、それとバランスするように他の アカウントの数値が増減する」というふうな考えに転換するのが、 自分にとっては理解のポイントだった。
GnuCashのセットアップ
GnuCashを最初に立ち上げるとウィザードでいくつかアカウント構成のテンプレートが 選べるけど、家計簿として使うなら会計的な基準を色々気にする必要はないので、 最初はごく単純なアカウント構成から始めて、慣れてきたら細かくすれば良いと思う。
ウィザードでは 通貨を選んだ後に "Choose accounts to create" で最初に作るアカウントを 選ぶようになってる。デフォルトの "Common Accounts" は色々入ってるけど、 シンプルにスタートするなら一旦clear allして "A Simple Checkbook" で 始めればいい。
そのままウィザードをすすめるとこうなる。
クレジットカードを持ってる場合はLiabilityの項目が必要なので作る。 File > New > New Account でダイアログを開いて、Account Nameを "Liability", Parent Account で "New Toplevel Account" を選んで、 Account Type は "Liability"。
後は適当に各カテゴリのアカウントを増やしとく。toplevel以外のアカウントについては、 親になるアカウントを選んだ状態で File > New > New Accountすれば Account Typeが適切に選択されているので、名前をタイプするだけでよい。 まあ例えばこんな感じ。
自分は、会社の方のExpenseはかなり細かく分けてるけど、 家計の方のExpenseはGeneralという項目に分類がめんどくさいものを全部 放り込んでいる。医療費は税金控除が受けられる場合があるので分けとくといい。 あと、仕事に関連しそうな本の購入、セミナー参加費なども経費にできるので 分けとく。自分はEducationの下にBooksとかConferenceとか作ってる。 IT関係の仕事ならPC関連の支出も分けとくと良いかも (私用で使う場合でも、 仕事で何割使ってる、という具合に按分できる可能性がある)。 細かくやりたいなら車のガソリン代、携帯電話の料金なども分けてもいいけど、 まあ、申告の前に会計士さんと相談しながらレシートを仕分けして、 それを後から反映したっていいので、最初はあまり複雑にしなくてもいいんじゃないかな。
さてセットアップの最終段階は初期残高、Opening Balancesの設定。全部ゼロからの 出発ってことは滅多にないだろうから。
EquityのOpening Balancesのアカウントを開いて、残高を設定したいアカウントを "Transfer" に選び、金額を記入する。自分の資本が増える方向の要素 (銀行残高や 手持ちのキャッシュは自分の資本になる) は "Increase" に、 自分の資本が減るような要素 (クレジットカードの残高とか) は "Decrease" に記入。
これでAccountsタブに戻るとこんな感じ。 Assets + Expense = Liability + Equity + Income の等式が 成り立っているのを確認してほしい。
日々の操作
自分は小額のキャッシュの出入りとかいちいちつけないので (仕事関係はほぼ全て チェックかクレジットカードだし)、日々記入する機会はチェックを切る時と 預ける時くらい。
チェックを切る時はChecking Accountを開いて日付と"Num"にチェック番号を記入、 "Transfer" にはそのお金の行き先 (何かを買う支払いならExpenseのアカウント、 クレジットカードの支払いならLiabilityのアカウント) を選択。 そしてお金を引き出すので "Withdrawal" のカラムに金額を記入。
チェックを預ける時は、Checking Accountからやっても Incomeからやってもいいんだけど、 自分はIncomeのアカウントを開いて"Transfer"にCheckingアカウントを指定し、 "Income" のカラムに金額を入れてる。
まれに、ATMで下ろせるより多額の現金が必要な時に自分でチェックを書いて 直接現金化することがある。その場合は Checking Account の "Transfer" の 先に "Cash" を指定すれば、Checking Accountの残高が減った分 Cashの 残高が増える。
毎月の操作
月一で銀行やクレジットカードのステートメントが送られてくるので、 それをまとめて記入。
銀行のサイトからデータをダウンロードできるのでそれをインポートしても いいんだけど、自分は確認のために未だにステートメントを見ながら 打ち込んでる。そのうち面倒になるかもしれないけど。
ステートメントを入力するかインポートしたら、 Reconcilation をしとくといい。 これは残高の再確認みたいなもの。 Action > Reconclie (アイコンもある) を選び、ステートメントにある 最終残高を記入すると、今までReconcileをしてないトランザクションが ずらっと出てくるので、ステートメントを見ながらチェックを入れてゆく。 残高が合えば完了。何かトランザクションを入れ忘れていたり 金額を間違えていたら合わないので再確認できる。
なお、自分はキャッシュの出入りについてもこの時にまとめてやっちゃう。 ATMで引き出した金額をChecking AccountからCashへと移して、 そこから適当に "Cash expense" として "Expense:General" へ移してる。 (まあ、レシートとか見て分かる範囲で細目を記入してもいいんだけど)。
毎年の操作
年が開けて2月中旬くらいまでには各種書類が揃うので、前年度の帳簿をまとめる。 自分はこんな手順でやっている。
- まず、EquityにIncome Summary > 2012 といったサブアカウントを作る
- 全てのIncome, Expenseアカウントについて、12/31付けで残高を全て Income summaryのサブアカウントに移動する。Descriptionは "Closing entries"。 これを済ませると、Income, Expenseは0になり、Income summary > 年度 の アカウントにはその年の収支総計が出てくる。
- Income summeryの全額を12/31づけでEquity:Retained Earningsアカウントに 移動。このアカウントが、累計での資本の増加(減少)を表すことになる。
年度の収支のまとめは Reports > Income & Expense > Income Statement、 バランスシートは Reports > Assets & Liabilities > Balance Sheet で作れる。 (GnuCashへの不満は、このレポートのフォーマットがいまいちなことなんだけど、 会計士さんのところへ持ってゆくぶんには用は足りる)。
税金の申告を作った時点で、追加の払込が必要だとわかれば ExpenseにTaxというアカウントを作る。戻ってくる場合はIncomeにTax Refundとかを 作ればいい。最近は直接銀行口座に振り込んでもらえる。
その他
会社のお金を建て替えたのを記録しておきたい場合は、Assetsに A/Receivable (Accounts Receivable) という階層を作って、"Company expense" などの アカウントを作っておく。 例えばキャッシュで$400建て替えたら、CashからTrasferにA/Receivableのアカウントを 指定して$400減らす (A/Receivableの方は$400増える)。
その後会社から$400のチェックをもらったら、 "Company expense" のアカウントで "Reimbursement" として TransferをChecking Accountに指定し "Payment" に$400を記入。すると A/Receivableが$400減ってChecking Accountが$400増える。
401kみたいな貯蓄はAssetの中にアカウントを作る。ここで、給料の一部が Checkingに行って一部が401k口座にゆく、みたいな場合は、 "Income" に記入するときに "Split" のアイコンをクリックすれば、 ひとつのトランザクションで複数のTransfer先を指定できる。
まとめ
子供の頃、小遣い帳をつけるように言われたのだけれどいつも残高と手元のお金が 合わなくなってすぐ諦めてた。複式だと (無理すれば矛盾を入れることもできるけど) 素直にソフトに従っていると帳尻が合うのがとても新鮮だった。学校で習いたかったよ。
まあ、紙の帳簿でつける場合は制約の伝搬を手でやらなくちゃならないんで面倒だと 思うけど、ソフトウェアならどっか一ヶ所で入れれば残りを計算してくれるので めっちゃ楽。
なお、素人の理解では帳簿の技術には
- 制約形式システムとしての複式簿記
- 現実のお金の出入りをどのアカウントに振り分けるかというルールやノウハウ
- 帳簿から得られたデータを使った分析
という要素があるように思える。プログラマにとって1.の部分は仕組みさえ 見えればとてもわかりやすく、そこさえわかってれば 家計簿はつけられるので、もはや単式の帳簿を使う意味は無いと思う。
2.は現実社会のルールや運用実態 (どこまで経費として認められるか、 みたいなノウハウを含めて) を色々知らないとならなくて、そこはプログラマ的には あまり興味を持てないかもしれないけど、必要ならプロの会計士さんにアウトソースすればいいし。
3.も奥が深そうな話ではあるのだけど良く知らない。誰か知ってる人が語ってくれるとうれしいな。
2013/01/18
メッセージキューの設計
タスクキューのイベントのやりとりにパイプを使ってたけど、イベント生成のペースがイベント消費のペースより速かったので特定の条件でハングしちゃった、というバグ話。
似たような話に自分も昔はまったことがあるんだけど具体例を忘れてしまった。ただ、その時の経験から、書き込み側タイムアウト(キューがいっぱいである状態が一定時間続いたら書き込みがエラーを返す)の手段を用意していないキューのAPIはなんか信用できない。
とはいえタイムアウトしたことがわかってもどうしようもないって場合もよくあるんで、それがベストなAPIなのかどうかはわからない。色々例外的なケースを考えていると、例えば緊急事態には既にキューにあるメッセージをすっ飛ばして特殊メッセージを送りたいとかいろいろ出てきて複雑化しちゃうし。ベストの実装というものはケースバイケースにならざるを得ないんだろうか。
以前、他の人が書いた、複数のスレッドがメッセージをやりとりしながら動くプログラムでハングの問題が発生して追っかけたことがある。キューも全部手作りなのでコードを読んでいたのだが、キューがいっぱいになった時の動作がどこにも書いていない。リングバッファだけど書き込み側が追い越したら古いメッセージはどんどん上書きされるように見える。何度見直してもそうなので、どうやらそういう設計なのだと気づいた。メッセージのほとんどは現在の状態を送るものなので新しい情報で上書きしても構わないし、そうでないイベントでも落ちたら(起きるべきことが起きなければ)ユーザが気づいてまたアクションを取るだろう、と割り切っていたのだ。なるほど設計は単純になる。(ハングの問題はというと、アルゴリズムの一部にO(n^2)なところがあって、nが大きくなると処理時間が延びて止まっているように見えていたのだった。)
Tag: Programming
2013/01/17
ピアノレッスン78回目
- Bach: Well-tempered Clavier Book I No. 3 (C♯ major)
- Prelude MM=80。good。
- Fugue 八分音符=104。とても忙しい曲なのでテーマをよく浮き上がらせないと聴く方がついていけない。注意せよ。
- Debussy: Pour le piano
- Prelude - pでの左の旋律、もっと歌ってよい。
- Sarabande - good
- Toccata - あやふやになるところを重点的に練習。クライマックスに向かうところでの左に出てくる新たな動機を浮き上がらせる。
Tag: Piano
2013/01/11
小学校の英語
らむ太は学校では第一言語として英語を学んでいるわけだが、 見ていると自分が外国語として学んだ過程とはだいぶ違う。まあ当然だけど。 動詞の活用や名詞の複数形など、理屈で「こうだからsをつけるんだ」じゃなくて 用例にたくさん触れることで覚えてゆく感じ。
新鮮だったのは、関係代名詞とか完了形とかが早いうちから 何の説明も無しに出てくることで、まあそりゃ日常的に使うものだから むしろ出さないことが不自然なわけで、こういうのも規則以前に例で身につけて行くんだろう。
一応文法については、こういう図形と色を使ったので勉強してはいるようだ。
あとは語彙を増やすことと、すらすら読めるようになることが重視されてる感じかな。 後者については「一目で読めるべき単語」のリストがあって、それを順に練習してゆく。
語彙については、外国語として学ぶ場合は母国語との対応づけで覚えられるけど、 第一言語だとそういうわけにはいかないので、読書や会話で覚えたり、 韻を踏む単語、対義語、類義語を上げるゲームとかで増強してゆくことになる。 (こういうゲームは英語が非母語な親にとっても案外難しかったりする。 「1年生にもわかる単語」とそうでない単語の順序づけが頭に入ってないので、 探索範囲を絞り込めないのだ)。
で、そうやって既知の語彙の集合との関連でもって新たな語彙を増やしてゆく場合、 知っている語彙が十分に小さければ、単位時間に新たに学べる語彙 dV/dt は それまでに知っている語彙 V および関連づけに費やす時間割合 T (1日のうちどのくらい、既知の語彙に結びつける形で新たな言葉に触れているか)に 比例することになる。
バイリンガル環境だと普通にしてたら各言語あたりの T は半分になり、 語彙の増加速度 dV/dt が減って V が増えず、それによってさらに dV/dt が鈍るという 悪循環が。
らむ太との会話で、日本語の未知語が出てきて「××ってなに?」って聞き返されることは、 一日に10回や20回じゃ済まないけれど、それによって日本語の語彙が増やせても、 学校でそれを応用して定着させる機会がない。逆もまた真で、 学校で耳にした英語語彙について家で使ってみたり尋ねてみたりという機会がそれほど無い (独り言はほぼ英語だけど。) これはなかなか大変なことである。 日本語の言葉を教える時に英語も一緒に教えてみようとも したけれどちょっと情報量が多すぎて処理しきれないみたいだった。
「子供は頭が柔軟だから言葉は自然に覚えるよ」なんて言う人がいるけど 眉につばつけた方がいい。自然に任せておいて何とかなるのは、そういう素質がある 限られた子供だけだと思う。 学習の効率と負担を考えたら、ひとつの言語で十分な語彙のネットワークを構築した上で 新たな言語に取り組む方が圧倒的に良いはず。
「アメリカでは幼稚園児も英語を話せる」などと言って 英語の早期教育を推してる人もいるけれど、 これまでと同じだけ日本語の下地を作りつつ、 さらにアメリカの幼稚園児が英語に触れているのと同じだけの時間、 英語に触れさせるのはまず無理なわけで、 早期教育は異文化に触れさせる程度に止めといて (「英語を使えるようになること」は期待しない)、 ちゃんとした学習は中学校からでもいいんじゃないかな。
Comments (0)