2014年3月27日木曜日

基礎からのPython

最も基本的なプログラムで脳トレとpythonの基礎を復習してみる。
今日のお題は以下の2つ。


1. 任意の入力を受けて、その数値以下の素数をすべてダンプしてみよう

今回は、シンプルに「素数とはなにか」に忠実に実装するだけです。
「素数とは、1 と自分自身以外に正の約数を持たない自然数で、1 でない数のことである。」
プログラムしやすい形に言い換えると、2以上からその数より小さい自然数で割り切れない場合は素数であるって感じかな。

def isPrime(n):
    for i in range(2,n-1):
        if( n%i == 0 ):
            return False
    return True

2. 任意の入力を受けて、その項数分フィボナッチ数列をダンプしてみよう

数式で書くとこんなかんじか。
 f(n) = f(n-2) + f(n-1)    ( ただし、 f(1)=f(2)=1, n<=3 )

この式をそのまま書いちゃえばいいんです。

def fibonacci(n):
    # f(n) = f(n-2) + f(n-1), 3<=n, f(1) = 1, f(2) = 1
    if n <= 2:
        return 1
    
    return fibonacci(n-2) + fibonacci(n-1)
以上!寝る。

2014年3月20日木曜日

リーダブルコードを読んだら恥ずかしくなってきた話

リーダブルコード読んでみました。
元Googleの方が書いた本ということもありいろいろとお勉強になることが多いと思いまして。
結論から言うと、「めっちゃ勉強になって、自分の書いてきたコードが恥ずかしくて人に見せられなくなった」
という感じですかね。
プログラマとしてキレる人の目線を少し感じられました。
わかりやすい話で、ベテランエンジニアからすると当然って思うことばかりかもしれませんが、
少なくとも会社に入りたての新人や、駆け出しプログラマは読むといいんじゃないでしょうか。
読んで自分に参考になった点を箇条書きでまとめます。



名前に情報を詰め込む


* 明確な単語を選ぶ
  send ⇒ deliver, dispatch, announce, etc...
  find ⇒ search, extract, locate
  start ⇒ launch, create, begin, open


* 汎用的な名前は避ける
  tmp, retvalみたいなものは避け、エンティティの値や目的を表現した名前を選
  スコープが小さければ例外的に使ってもOK
  単語補完機能があるから、長い名前を入力するのは問題じゃない

* 値の属性を追加する
  単位: **_ms, **_mb, **_kbps, etc
  その他: **_utf8, **_urlenc

* 名前のフォーマットで情報を伝える
  クラス名はCamelCase
  変数名はlower_separated
  定数はkConstantName
  クラスのメンバ変数は member_

コメントすべきことを知る

  自分の考えを記録する
  既知の不具合や試行錯誤の結果、挙動に関する評価をコメントする
  コードの欠陥にコメントを付ける
  プログラマがよく使う記法

  記法 典型的な意味
  - TODO   :  あとで手を付ける
  - FIXME   : 既知の不具合があるコード
  - HACK    : あまりきれいじゃない解決策
  - XXX       : 危険。大きな問題がある

* 定数にコメントをつける
  定数が何をするのか、なぜその値を持っているのかという背景を説明する

* 要約コメント
  関数内部の大きな塊に対して、全体像に関するコメントをしておく。

制御フローを読みやすくする

  do/whileループは避ける
  if, while, forと異なり、条件が下にくるので少し不自然
  
* ネストを浅くする
  ネストの深いコードは理解しにくい
  早めに返すことでネストを削除orコードをクリーンにできる
  失敗ケースは早めにreturnし、タスクを出来るだけ早く完了させる
  continueでループ内部のネストを削除

* 巨大な式を分割する
  説明変数を導入する
  式を変数に代入しておき、簡潔な名前で式を説明することでコードを文書化する
  主要な概念を読み手が認識しやすくなる
  ド・モルガンの法則を使う
  論理式を簡潔に

変数と読みやすさ
  変数のスコープを縮める
  if文内部のスコープ
  グローバル変数は読む人を不安にさせる
  定義の位置を下げる(C99, C++には先頭で定義する制約が無い)
  constやfinalは使えるときは使う

2014年3月18日火曜日

nasneとiPad miniで快適なテレビライフが保証される件について


世間一般の人は、テレビを見るためにアクオス、ビエラ、ブラビア、その他のいわゆる「テレビ」と呼ばれるものを使っていることでしょう。
家電量販店ではスマートテレビがすごいぞー!多機能だぞー!って宣伝されてるので、
勢いで買った人も多いんじゃないですか?

勢いで買えちゃうようなお金持ちの方は、
これ以降の話を読んでも面白く無いしためにならないと思うので、
貴重な時間をムダにしないためにも他のページに行って下さい、さようなら。

お金持ちで、広い家に住んでいるわけではない、
一人暮らしの男で、ものぐさだしスペースを取る機材はできるだけ置きたくない、
スマートに、複数の機能を兼ねた電化製品で、なんでもコンパクトにしちゃいたい、
そんな同士のために参考になるお話をしたいと思います!!



世間で言ういわゆるあのテレビ。

デカイですねー、4K?画質がすごいんですか、そうですか。
人間の目の解像度とどっちがすごいんですかねぇ(某)

とりあえず、ネットとテレビが同時に出来る「テレビ」っていうのが不要なんです。
私の考えでは、ネットとテレビが同時にできる「パソコン」が欲しいんです。
今の時代、主役は確実にネットなんです。

テレビを快適に動作させるために設計されたテレビよりも、
ネットを快適に動作させるために設計されたものでテレビを見たいんです。

結論から言います。
タイトルにあるように、nasneとiPad mini を買いましょう。
nasneはソニーさんが出してるもので、
TVチューナーになる大容量ハードディスクです。
iPadは説明要らずの幸せデバイスです。

2章に分けてnasneの素晴らしさを説きます。


【 1. TVチューナー機能 】

まぁざっくり言ってテレビとほぼ同等の機能が発揮できます。
テレビ要らね、ってなります。

# ちなみに dボタンだなんだっていうクソみたいな細かい機能は使えません。

================== しばし脱線 ==================

ぶっちゃけdボタンで投票(?)的な機能は、使い勝手が悪すぎて、
将来的に淘汰されると思ってます。
# 既にオワコン?
ユースケースとして、テレビってリビングに置かれてみんなでテレビ見るわけじゃないですか。
dボタンで投票って誰がやるんですか?
一家の大黒柱のお父さんですか?
使う側からすれば、みんながdボタンの機能使えるわけじゃないから楽しくない。
提供する側からすれば、誰がその機能使ってるかわからないから、番組に使う情報としてもあまり有益ではない。投票者の属性値が見えてこないので、テレビ局がスポンサー様側に提示する情報
としても不十分。
高負荷の通信を捌く技術はネット系の方が圧倒的に優れている。
結局ネットに流れるんですって。(完全に私の妄想ですが。)
===============================================

nasneは明示的にはソニー系デバイス(Xperia, PS3, PS Vita, ソニーのタブレット)でしか使えないとあります。
でもiPadに特定のアプリをインストールすれば、
ソニー系のタブレット買わなくてもテレビが見られます。
ライブチューナー機能も使えるし、
CHAN_TORU経由で家の外からテレビ番組をリモート予約だってできちゃいます。
録画したテレビ番組はnasneに保存されて、iPadに持ち出しだってできちゃいます!
あー幸せ。
私はiPadにDiXiM Digital TV for iOSをインストールして幸せを享受しております。



【 2. ネットワークストレージとして、自宅内のネットワーク・サーバーとして使うも良し! 】

エンジニアの方々、経営者の方々。
nasneをシェアサーバーにしちゃいなよ。
nasne内にリモートレポジトリ作って、社内LANについないでチェックアウト、コミットして、
ソフトウェア開発しちゃいなよ。
ハッキーなことはいっくらでもできます。
私はnexus5にnasne accessとかいうAndroidの神アプリをインストールして、
携帯で撮った画像をnasneに同期してニヤニヤしてます。



つかれたので終わり。
【完】

2014年3月6日木曜日

持つべきものはデータ構造とアルゴリズム力


適切なデータ構造とアルゴリズムを選択し簡素な実装ができる力の重要性を、
実務を通して理解することができた。

私は普段デバイスドライバを書く仕事をしている。
デバドラのレイヤでは複雑な事はせずに、軽く、賢くバイナリ列をパースしたり、
アプリが使いやすいAPIを提供する責務がある。
デバドラを書くことにおいて「いい仕事」とは、

1. 処理が軽いこと
2. 使いやすいAPIが最小限に揃っていること
3. 適切な抽象化がなされ、拡張性に富んでいること

に集約されると考えている。


1. 処理が軽いこと

当然のことであるが、冗長な処理や、不要な条件分岐等はやめる。

例えば、USBやBluetooth, WiFiなどの通信関連のデバドラでは、
えてしてパース処理が発生する。
TCP/IPに関連するデバイスではヘッダのどこぞのビットがIPアドレスでー、
これが宛先MACアドレスでー、。。。うんぬんかんぬんな処理がどこかに入るはず。
基本的なことではあるが、とにかく不要な処理はスキップしよう。
いちいちループを書いて探索処理をすることは、
場合にも依るがデバドラ実装においては負けだと思おう。

データ構造を工夫することで繰り返し処理を減らす。
ときに組込系のシステムでは使用可能なメモリ容量が限られているケースが見られるが、
無条件にループを描いて降伏するのではなく抗おう。
今まで割り当てていた使用していないビットに意味を持たせて、
どうにかしてフラグ管理するなどしてメモリの節約を考えよう。

if(  A && B && ...) と書くときは重い処理を右に持って行こう。
短絡評価を有効活用するわけです。
とにかく重い処理からは逃げることを考えよう。

データ構造の設計はひとたび間違えると糞コードのオンパレードになる。
データ構造とアルゴリズムはほぼ同義といっていいくらい関連性が深い。
ここで最適な戦略を取れるかどうかは、
日頃の学習と、業務における経験で培うところだろう。
糞コードをたくさん産んでは捨てることでスキルをのばそう。

タイトルに記載したとおり、私は本当にアルゴリズムとデータ構造の選定スキルの重要性を感じている。
デバドラ開発において、アルゴリズム力はオペレーティングシステムで、プログラミング言語を扱う能力はアプリケーションのようなイメージ。
アプリがいっぱい揃っていてもOSが残念であれば全体の評価は糞だ。
プログラミング言語が多数扱えること以上に、
思考のOSを鍛えることこそがITエンジニアとして大成するカギになると考えている。

参考になった書籍を以下に掲載する。
いいプログラマはたいてい読んでいるという書籍だ。
目から鱗が落ちた回数分、自分が未熟であることを感じることができた良書である。





2. 使いやすいAPIが最小限に揃っていること

デバドラはなんのためにあるのか?
アプリ屋さんに使ってもらうためである。
シンプルで使いやすいAPIを用意すれば、
ミドルウェア開発者やらアプリ開発者やらから来る注文や質問を事前にシャットアウトでき、
不要な仕事を発生させずに済むのである。
また、「最小限に」と記述したことには意味がある。
APIを不要にたくさん用意すると、APIを提供するデバドラ屋のサポートコストが上がる。
更に、APIを一度公開してしまえば、後方互換性を考慮する手間が発生する。
結果、無駄な仕事を増やす結果になってしまう。
それだけではない。
後方互換性のために自分の知的創造物であるデバイスドライバの神聖な領域を汚すような後方互換性を担保するための糞コードを書かなければならないのである。
これはエンジニアからすると死んでもやりたくない行為である。


3. 適切な抽象化がなされ、拡張性に富んでいること

例えば、あるプラットフォームで使える多種多様なデバイスに対して、
別々に構造体を定義した場合はどうなるだろう。
アプリ屋さんからするといちいち構造体を使い分けなきゃいけなくなるし、
実装コードは汚くなりバグを生み出しがちになる。
加えて、彼らの学習コストも増大する。
デバドラ提供者側は、人間が解釈できるレベルの粒度でオブジェクトという抽象的なカタマリを作っていこう。

抽象的なカタマリという面でいえば、デバドラというものはアプリにstaticにリンクされるべきものではない。
ほぼ確実に動的にロードされて使われるべきだ。

静的リンクを行う戦略をとった場合、後方互換性の観点からするとガン細胞になりがちだ。
大昔に出たアプリが動かない可能性だって出てくる。
staticにリンクされたものの場合、修正することは困難になる。
多種多様なアプリが乗っかるデバドラの場合は、後方互換性や拡張性の観点から、
ほぼ確実に動的ライブラリの形で提供すべきだろう。