HDDケースに入れてUSB接続したHDDが認識しなかったときの対処(Windows7)

裸の2.5インチHDDを譲り受けたので,昔のPCのバックアップ用にでもしようと,
USB接続できるHDDケース(LHR-PBGU2を購入)を使ってWin7PCに接続したのですが,
マイコンピュータの画面から認識されず困ったときの記録です.

ドライバが正しく動いていないのかと疑いましたが,そうではない様子.
ネットで調べると,そのままズバリの回答をされている方が.

USB-ATA Bridge でHDD が見えないトラブル : 還暦からの出発

詳細に書かれていて,非常にわかりやすいです.
要は"コンピュータの管理"画面から,HDDにボリューム名を定義してあげないといけない,ということのようです.

最後のフォーマットの部分で,"MBR"と"GPT"のどちらにすべきか聞かれますが,
それはこちらが参考になります.

MBRとGPTの違い(HDDの初期化) : モモンハン日記

私の場合は,容量の小さなディスクで,異なるOSにも接続する可能性があったため,
MBRのほうでフォーマットすることにしました.

というわけで,現在無事に使えています.
非常に助かりました.

数独(Sudoku)ソルバ

Sudoku - Wikipedia, the free encyclopedia
数独といえば知らない人はおそらくいない大人気パズルですが,
そういえばソルバを書いたことがないなと思い立ちまして,Rubyで書いてみました.

いろいろと怪しいところはありますが,自分で考えて書いてみるのは楽しいです.

基本的には,9x9マスの数字列を書いたテキストファイルを入力として,
(0は未確定のマス)

530070000
600195000
098000060
800060003
400803001
700020006
060000280
000419005
000080079

解けた後の9x9マスの数字をコンソールに出力するというものです.

534678912
672195348
198342567
859761423
426853791
713924856
961537284
287419635
345286179

以下,Githubに置いたソースのコピペです.
http://github.com/glass5er/sudoku-solver
solver.rb

#!/usr/bin/env ruby

# -- N for stage size
# -- only N = 3 available currently : 9x9 sudoku
N = 3
STAGE_WH = N ** 2
BLOCK_WH = N

# -- exception classes
class InvalidInputFormatException < Exception; end
class NumNotFoundException        < Exception; end

class Block
  attr_reader :value
  attr_reader :cands
  def initialize(val = 0)
    @value = val
    @cands = (1..STAGE_WH).to_a
    @cands = [val] if val > 0
  end

  def update()
    raise NumNotFoundException if @cands.size <= 0 && @value <= 0

    flag = false
    if @cands.size == 1 then
      @value = @cands[0]
      flag = true
    end

    return @value, flag
  end

  def exclude(n)
    @cands.delete(n)
    #update()
  end

end

class Stage
  def initialize(filename="")
    @rows = STAGE_WH
    @cols = STAGE_WH

    @field = Array.new(@rows)

    @rows.times {|y|
      @field[y] = Array.new(@cols)
    }

    begin
      read(filename)
    rescue InvalidInputFormatException => e
      # -- InvalidInputFormatException : add error message
      raise e, "Input txt file should be #{STAGE_WH}x#{STAGE_WH} matrix format."
      # -- FileNotFoundException : send to default error handler
    end

  end

  def read(filename)
    File.open(filename) {|f|
      y = 0
      while line = f.gets do
        x = 0
        line.chomp.chars { |c|
          @field[y][x] = Block.new(c.to_i)
          x += 1
        }
        raise InvalidInputFormatException if x != STAGE_WH
        y += 1
        break if y >= STAGE_WH
      end
    }
  end

  def solve()
    begin
      updated = false

      @rows.times {|y|
        @cols.times {|x|

          # -- n    = @field[y][x].value
          # -- flag = @field[y][x].updted?
          n, flag = @field[y][x].update()

          if flag then
            # -- exclude n from candidate

            # -- h-line, v-line
            @rows.times {|cy|  @field[cy][x].exclude(n) }
            @cols.times {|cx|  @field[y][cx].exclude(n) }

            # -- square-block
            area_x = x / BLOCK_WH
            area_y = y / BLOCK_WH
            BLOCK_WH.times {|ay|
              BLOCK_WH.times {|ax|
                @field[area_y * BLOCK_WH + ay][area_x * BLOCK_WH + ax].exclude(n)
              }
            }

            updated = true
          else
            puts "(#{y},#{x}) => #{n} : #{@field[y][x].cands}" if $DEBUG
          end

        }
      }
    end while updated
    # -- can finish anyway when impossible questions
    return check()
  end

  def check()
    @rows.times {|y|
      @cols.times {|x|
        # -- simple check (not perfect...)
        return false if @field[y][x].value == 0
      }
    }
    true
  end

  def to_s()
    str = ""
    @rows.times {|y|
      @cols.times {|x|
        str += @field[y][x].value.to_s
      }
      str += "\n"
    }
    str
  end
end

main.rb

#!/usr/bin/env ruby

require "./solver.rb"

def test()
  hoge = Block.new(3)
  p hoge.value
  p hoge.cands
  fuga = Block.new(0)
  p fuga.value
  p fuga.cands
  fuga.setValue(4)
  p fuga.value
  p fuga.cands

  # -- @DEBUG : shoud raise exception
  #fuga.setValue(5)
  #p fuga.value
  #p fuga.cands

  stage = Stage.new("./dataset/question001.txt")
  print stage
end

if __FILE__ == $0
  stage = Stage.new(ARGV[0])
  puts "Question is :" if $DEBUG
  puts stage        if $DEBUG

  solved = stage.solve
  puts (solved ? "Answer is :" : "Not solved ... :") if $DEBUG
  print stage
end

Singletonクラスの継承

仕事で似たようなレジスタ管理クラスを複数作る必要があって,
うまいことSIngletonパターンをのせたベースクラスを継承して
使いたいなと思っていましたが,やり方を知りませんでした.

テンプレート化するとよいんですね.

timlibの作者さんのページを参考に.
C++ の Singleton パターンを Template 化 | TM Life

というわけで,ベースクラスとその継承を書いたサンプルを作りました.
http://gist.github.com/glass5er/5813190

(以下,2013/6/30時点でのサンプルコードのコピペ)

#include <iostream>
#include <string>
 
using namespace std;
 
//----------------
 
template <class U>
class SingletonParent
{
  public:
    static U* getInstance() {
      static U instance;
      return &instance;
    }
 
  protected:
    //--  template func in template class available
    template<typename T> void print2Times(T v);
 
    SingletonParent() {
      base_str = string("BASE");
    }
    virtual ~SingletonParent() {}
    string base_str;
};
 
 
//--  use template succession
class SingletonChild : public SingletonParent<SingletonChild> {
  public:
    SingletonChild() {
      child_value = 0;
    }
    ~SingletonChild() {}
 
    void set(int v) { child_value = v; }
    int  get()      { return child_value; }
 
    void print()    {
      print2Times(base_str);
      print2Times(child_value);
    }
  private:
    int child_value;
};
 
//--  when defining template func in template class,
//--  2 template declaraton required
template<class U> template<typename T>
void
SingletonParent<U>::print2Times(T v)
{
  cout << v << v << endl;
}
 
 
//----------------
 
 
int
main(int argc, char const* argv[])
{
  //--  actually the same instance
  SingletonChild *inst1 = SingletonChild::getInstance();
  SingletonChild *inst2 = SingletonChild::getInstance();
 
  //--  both 0
  cout << inst1->get() << endl;
  cout << inst2->get() << endl;
 
  //--  BASEBASE, 00
  inst1->print();
 
  inst2->set(3);
 
  //--  both 3
  cout << inst1->get() << endl;
  cout << inst2->get() << endl;
 
  //--  BASEBASE, 33
  inst1->print();
  return 0;
}

Homebrewの"Unsupported special dependency"エラー対策

Homebrew関連でつまったのでメモです.

OpenCVをインストールし直そうとしたところ,見慣れないエラーが出ました.

$ brew install opencv
#=> Error : Unsupported special dependency python

"Unsupported special dependency python"とのことなので,pythonまわりを調べてみるも,直し方わからず.
しかし,困ったときのbrew doctorに頼んでみたらあっさり解決しました.


要するに

  • Xcodeが古すぎてformulaの正しいバージョンを捕捉できない
  • Homebrewも古すぎてformulaの(略)

というわけで,App StoreXcodeのアップデートと,brew updateを行った後に再度brew install opencvをトライしたところ,正常にインストール完了しました.

まだ自分の中では"Unsupported special dependency"が出る条件が完全にクリアでないので,もう少し調べた方がよさそうですが,今日はここまで.

herokuのアップデートで動かなくなったWebサービスを直したときの話

前に日記を書いたときに作りはじめたWebサービス,YTJukeに手を加えようと思ったら,"Application Error"と表示されてうまく動作しない状態になっていたので,そこからもとの状態に戻したときの試行錯誤の話です.

直接ハマった所は1箇所だけで,何ともしょうもない話なのですが,

herokuにおけるデータベースのURL変数を,SHARED_DATABASE_URLとしていたのが良くなかった

ということでした.

当初,ログを読むと,こんなのが出ていました.

$ heroku logs 
## 2012-12-26T10:58:24+00:00 app[web.1]: /app/app.js:20
## 2012-12-26T10:58:24+00:00 app[web.1]:   client.query("SELECT tablename from pg_tables where tablename = '" + baseTab
## 2012-12-26T10:58:24+00:00 app[web.1]:          ^
## 2012-12-26T10:58:24+00:00 app[web.1]: TypeError: Cannot call method 'query' of null

データベースへの接続ができていないとのことだったので,もしかして,postgres9.2にバージョンアップしたという件かと思ったのですが,違いました.

Heroku Postgres | Heroku Dev Center
公式によれば,process.env.DATABASE_URLと記述すべきとのことです.
以前は,SHARED_DATABASE_URLも,特に設定しなければこれと同じ値になっていたのでしょう.今は,変数自体が無いようでした.

$ heroku config | grep DATABASE
## DATABASE_URL:                  postgres://chkctcjn(アドレスが書かれていたが,略)


他にも,いくつか細々としたところでハマったので,一応書いておきます.

ローカル環境のnodeのバージョンをあげたので,依存関係がおかしくなっていた

これはpackage.jsonとnpmコマンドでいろいろ調整です.
バージョンが合っていないとこんなのが出るので,どちらかに合わせる.

$ npm install exress
## npm WARN engine express@2.4.7: wanted: {"node":">= 0.4.1 < 0.5.0"} (current: {"node":"v0.8.15","npm":"1.1.66"})

expressを最新版(3.0.5)にしたら仕様がいろいろと変わって動かなくなった

Express - api reference
express3になって,関数名やファイル構成など,仕様があちこち変わったみたいです.
私はlayout.ejsを読み込まない仕様になっていることに気づかずにハマりました.
package.jsonに,express2.5系を指定したら問題なく動作しました.

Heroku Toolbeltを使うようにしたら,tapsでのデータベース転送がうまくいかなくなった

(gem版とtapsの組み合わせは動作するので,移行などしなければハマることもなかったのですが...)
以前は,gem版のherokuを使っていて,tapsでデータベースを転送していました.
tapsを使って開発環境のデータベースをHerokuにインポートする - (゚∀゚)o彡 sasata299's blog
しかし,gem版のherokuをつかっていたら,こんなメッセージが出てきたので,Toolbeltに移行しました.

$ sudo gem install heroku
##   !    The `heroku` gem has been deprecated and replaced with the Heroku Toolbelt.
##   !    Download and install from: https://toolbelt.heroku.com
##   !    For API access, see: https://github.com/heroku/heroku.rb

もう古いからToolbeltに乗り換えなさい,とのことです.
Heroku Toolbelt
で,DLしてインストール後,tapsを使ってみると,うまくいかない.

$ heroku db:push postgres://pgsqladmin:(パスワード)@localhost/ytplaydb --app ytjuke
##    !    Taps Load Error: cannot load such file -- taps/operation
##    !    You may need to install or update the taps gem to use db commands.
##    !    On most systems this will be:
##    !    
##    !    sudo gem install taps

いや,インストールしてますけどもね.関連付けがうまくいっていないようです.
調べてみると,今は別の方法が推奨されているみたいです.
Using `pg:transfer` to Migrate Postgres Databases - Higher Order Heroku
これでやっと,うまくいきました.


本当にやりたかったメンテナンスは,これからです.

sortで文字列の途中からソートする

ファイルの順番を自分好みに並べ替えたいときに.

# (たとえば,2つのフォルダにそれぞれ以下のようなファイルがあるとする)
$ ls ./*/*.ppm | cat
./new/exp001.ppm
./new/exp002.ppm
./new/exp003.ppm
./original/exp001.ppm
./original/exp002.ppm
./original/exp003.ppm
# (上記の並び順ではなくて,ファイル名の部分でソートしたいとき,以下のようにする)
$ ls ./*/*.ppm | sort -t "/" -k 3
./new/exp001.ppm
./original/exp001.ppm
./new/exp002.ppm
./original/exp002.ppm
./new/exp003.ppm
./original/exp003.ppm
# (sortコマンドに,-t で区切り文字を指定して,-k でフィールド番号を指定する)
# (フォルダはスラッシュ区切りなので -t "/" ,今回はファイル名がスラッシュ区切りで3つ目なので -k 3)

2つの方法で作った画像をビューアで比較するときによく使います.

$ ls ./*/*.ppm | sort -t "/" -k 3 | xargs display
# (displayは,ビューアの名前.ImageMagickのツール)

複数のバージョンのプログラムを性能比較するときの方法

Gitを使ってソースコードを管理していて,少し前のアルゴリズムと現在のアルゴリズムを性能比較したくなることがあります.
パラメータファイルの変更くらいなら,そのファイルを2つ作っておくなどでよいですが,複数のソースコードを変更した状態での比較だと面倒.どこかでミスりそう.

Gitは多機能なのでいくつか方法があると思いますが,よく使う2つの方法を記します.

最新コミットと,いくつか前のコミットを比較するとき

# (いま,masterブランチの最新コミットの状態とする.性能評価するスクリプトを実行.)
git checkout -b OLD_COMMIT_NAME HEAD~{n}
# (OLD_COMMIT_NAMEという名前のブランチを作って,n個前のコミットをひっぱってきた.)
# (自動的にOLD_COMMIT_NAMEブランチに移動しているので,性能評価するスクリプトを実行.)
git checkout master
# (もとの最新コミットに戻ってきた.)
# (OLD_COMMIT_NAMEブランチが不要なら,以下のようにして削除しておく.)
git branch -D OLD_COMMIT_NAME

最新のコミットに変更を加えて,変更前と変更後で比較するとき

# (いま,変更を加えた状態とする.性能評価するスクリプトを実行.)
git stash save
# (変更前にもどったので,性能評価するスクリプトを実行.)
git stash pop
# (変更後の状態になる)

後者のほうがお手軽なものの,最新のコミットでの比較にしか使えないという制約と,なんとなく不安だという理由があって(私だけかもしれないが),前者を使うようにしています.
ただし,変更をいきなりmasterにコミットするのは抵抗があるので,devブランチかなにかを作っておいて,そこから前者の方法にもっていくようにしています.