プログラミング・開発の最近のブログ記事

はてなブックマークをタグでAND検索するGreasemonkeyスクリプトです。色々考えた結果 Greasemonkey で作ってみました。ソースは、まあ・・・ぐちゃぐちゃです。とりあえず、プロトタイプということで。

  1. はてブタグAND検索RSSをAJAXで読み込む版
  2. はてブタグAND検索HTMLを強引に書き換える版 (上の作る前の試験)

1. のFlash動作デモ も作ってみました。 (created with wink)

インストール方法(文字化けするので少し手順を踏む必要があります)

  • 通常の Greasemonkey のとおり、インストールする。
  • 拡張の Greasemonkey メニューから、インストールしたばかりのファイルを開きます(この時点で化けてます)。
  • 正しい内容をWEB上のファイルから貼り付けて、UTF-8 で保存する。
  • 完了。

インストールしたら、http://b.hatena.ne.jp/ でタグをスペース区切りで複数してして検索してみてください。 さらに検索するには、「もっと探す」をクリックします。ぼーっと待っていると、5ページくらい先までキャッシュしにいきます。

処理としては、最初のタグで RSS を引いてくる => そこへ残りのタグでフィルタリングして表示。 という単純なものです。ただ、RSS 引くとちょっともたつくみたいだし、非ブクマ数なども表示されないので、AJAX 版でも HTML をいじってしまうというのもありかもしれません。

参考にしたサイト

それにしても、いままであまり興味のなかった Greasemonkey ですが、かなり面白いです。javascript に慣れないぶん、えらく苦労しましたが・・・。っていうか、Flash と javascript の魔力は恐ろしいです。 こんな時間になってしまいました。(3:10分語る)

本当にまだちょっとだけ。
いじって思ったこと。

Canvas はないんですか?
A. たぶんこんなかんじが近い。

Graphics g = panel1.CreateGrtaphics();
Color fw = Color.FromArgb(0, 255, 0);
Color bk = Color.FromArgb(255, 255, 255);
Pen p = new Pen(fw);
Brush b = new SolidBrush(bk);
g.FillRectangle(b, 0, 0, panel1.Size.Width, panel1.Size.Height);

ActionList がないと生きてゆけません。
A. (たぶん)標準ではついていません。
が、作っている方はいます。http://www.codeproject.com/cs/miscctrl/actionlist.asp

TLabel の FocusControl プロパティは?
A. なさそう。 ただし、フォーカスは Label の次のタブオーダーのコントロールに移る。

TabOrder は自動調整してくれないの?
A. たぶんしてくれない。同じ TabOrder を複数のコントロールが持つ場合、Zオーダーで順番が決まるそうです。

TStringList は?
(ref: http://www.atmarkit.co.jp/fdotnet/special/generics01/generics01_02.html)

List<string> stringList = new List<string>();
stringList.Add("こんにちわ");
stringList.Add("さようなら");

もちっと作ってからリリースしようと思っていましたが、全然 TODO リストが減らないので、ここいらで出しておきます。

今回 HTMLヘルプを付けましたが、どうせ HTML だし完全オンラインマニュアル化するかも。まあ、そのあたりは未定。 wiki もいいかなと思ったり。

プログラミング作法』の中に出てくる、マルコフ連鎖 C バージョンを Delphi で書いてみた。ただし、標準入出力は使わずに、TStringList にテキストを読んでしまってから処理。結果も TStringList に返ってくるようにしてみた。

unit Markov_C;
interface
uses Classes, SysUtils, Windows;
const NPREF = 2; NHASH = 4093; MAXGEN = 10000; NONWORD = #$0A;
type PPrefix = ^TPrefix; TPrefix = array[0..NPREF-1] of PChar; PSuffix = ^TSuffix; PState = ^TState; TState = packed record Pref: TPrefix; Suf: PSuffix; Next: PState; end; TSuffix = packed record Word: PChar; Next: PSuffix; end; var StateTab: array[0..NHASH-1] of PState;
function Hash(S: PPrefix): Cardinal; function Lookup(Prefix: PPrefix; Create: Boolean): PState; procedure Build(Prefix: PPrefix; FileName: string); procedure Add(Prefix: PPrefix; Suffix: PChar); procedure AddSuffix(SP: PState; Suffix: PChar); procedure Generate(nWords: Integer; SL: TStringList);
implementation
function Hash(S: PPrefix): Cardinal; var H: Cardinal; P: PChar; I: Integer; const MULTIPLIER = 31; // set 31 or 37 begin H := 0; for I := 0 to NPREF - 1 do begin P := S[I]; while Ord(P^) <> 0 do begin H := MULTIPLIER * H + Ord(P^); Inc(P); end; end; Result := H mod NHASH; end;
function Lookup(Prefix: PPrefix; Create: Boolean): PState; var I, H: Integer; SP: PState; begin H := Hash(Prefix); SP := StateTab[H]; while SP <> nil do begin for I := 0 to NPREF - 1 do if StrComp(Prefix[I], SP.Pref[I]) <> 0 then Break; if I = NPREF then begin Result := SP; Exit; end; SP := SP.Next; end; if Create then begin GetMem(SP, Sizeof(TState)); for I := 0 to NPREF - 1 do SP.Pref[I] := Prefix[I]; SP.Suf := nil; SP.Next := StateTab[H]; StateTab[H] := SP; end; Result := SP; end;
procedure Build(Prefix: PPrefix; FileName: string); var SL: TStringList; I: Integer; Buf: PChar; begin SL := TStringList.Create; try SL.LoadFromFile(FileName); SL.Text := StringReplace(SL.Text, ' ', #$0D#$0A, [rfReplaceAll]); for I := 0 to SL.Count - 1 do if SL[I] <> '' then begin GetMem(Buf, Length(SL[I]) + 1); StrCopy(Buf, PChar(SL[I])); Add(Prefix, Buf); end; finally SL.Free; end; end;
procedure Add(Prefix: PPrefix; Suffix: PChar); var SP: PState; begin SP := Lookup(Prefix, True); AddSuffix(SP, Suffix); System.Move(Prefix[1], Prefix[0], (NPREF-1)*SizeOf(Prefix[0])); Prefix[NPREF-1] := Suffix; end;
procedure AddSuffix(SP: PState; Suffix: PChar); var Suf: PSuffix; begin GetMem(Suf, SizeOf(TSuffix)); Suf.Word := Suffix; Suf.Next := SP.Suf; SP.Suf := Suf; end;
procedure Generate(nWords: Integer; SL: TStringList); var SP: PState; Suf: PSuffix; Prefix: TPrefix; W: PChar; I, nMatch: Integer; begin for I := 0 to NPREF - 1 do Prefix[I] := NONWORD; Randomize; W := nil; //コンパイラを黙らせる for I := 0 to nWords - 1 do begin SP := Lookup(@Prefix, False); nMatch := 0; Suf := SP.Suf; while Suf <> nil do begin Inc(nMatch); if (Random($7FFF) mod nMatch) = 0 then W := Suf.Word; Suf := Suf.Next; end; if StrComp(W, NONWORD) = 0 then Break; SL.Add(W); System.Move(Prefix[1], Prefix[0], (NPREF-1)*SizeOf(Prefix[0])); Prefix[NPREF-1] := W; end; end;
end.

使うときはこんな感じ

procedure TForm1.btnBuildAndSaveClick(Sender: TObject);
var
  Prefix: TPrefix;
  I: Integer;
  SL: TStringList;
  FileName: string;
begin
  if not OpenDialog1.Execute then Exit;
  FileName := OpenDialog1.FileName;
  for I := 0 to NPREF - 1 do
    Prefix[I] := NONWORD;
  Build(@Prefix, FileName);
  Add(@Prefix, NONWORD);
  SL := TStringList.Create;
  try
    Generate(MAXGEN, SL);
    SL.Text := StringReplace(SL.Text, #$0D#$0A, ' ', [rfReplaceAll]);
    SL.SaveToFile(ChangeFileExt(FileName, '_out.txt'));
  finally
    SL.Free;
  end;
end;

なんか冗長な感じ・・・ツッコミ希望。次は Java, C++ バージョンを Delphi らしく書いてみたい。

レイザーラモンHG

開発中に思わぬエラーが出て、「セイセイセイ」とつぶやいている自分に気づいた。

コンパイル フォーーー!!!

『Delphi 2.0J 32bit パワープログラミング』 (1997.1.1 Charles Calvert著、篠原慶訳 \7500)

delphi 2 unleashed

これ、もう手に入らないと思うけど、今でもたまにお世話になっている。本当に名著だと思う。なにがすばらしいかって、ただのハウツー本ではないところ。この姿勢は筆者の以下の言葉に表れている(ちょっと長いけど引用する)。

1.2.2 本書を有効に利用するには
 本書を読むにあたり理解しておいてほしい重要な点の一つは、本書は、Delphi の実行ファイルを最も迅速かつ簡単な方法で作成するための指南書ではないということである。本書にはその種の例を多く収めてあるが、簡単な方法ではなく難しい方法で実行ファイルを作る例も多数盛り込んである。
 では、なぜ必要以上に難しいことをするのか。
 それは、本書の目的が、表面下を深く掘り下げて、Delphi がどのように動作するのか、そしてときには Windows API がどのように動作するのかを示すことにあるからである。したがって、何かを行うための最も簡単な方法を示す代わりに、場所によっては Delphi の表面を徹底的にはぎとり、この精巧で高度な性能の表面下に隠れている複雑な機構を解明していこうと思う。

あと、VCL のソースは持っていたほうが良いとも書いてある。つまり、(本気で学ぶなら)Delphi 6 Personal では不十分だということ。本気で学ぶなら Delphi 以外を選びなさい、というツッコミは禁止。

ちなみに、原書は『Delphi 2 Unleashed』。『Delphi 4 Unleashed』 まで出ているはずだけど、邦訳されていない。たぶん。

復刊ドットコムで Delphi 本がいくつか復刊希望リストにあがっているけど、この本こそ復刊させるべきだと思う。ちなみに同サイトですでに復刊している、『Delphi オブジェクト指向プログラミング』も読んだのだけど、先にパワープログラミングを読んでしまっていたせいか、物足りなかった。もちろん、初めてな方にはオブジェクト指向?もおすすめ。

では、同書でとりあげられているすばらしいポイントをいくつか。これでもかなり絞った。絞らないと全部になっちゃう^^;。ちなみに、カッコ内はその内容にさかれているページ数

第2章 「Win32 での Delphi の型」 (40ページ)
第4章 「ポインタと PChar」 (30ページ)
第5章 「ポインタ、リンクリスト、メモリ」 (40ページ)
このあたりの基本をきっちりおさえている。ポインタと PChar は必読。

第6章 「例外」 (30ページ)
より安全なプログラムのために。

第9章 ? 第14章 (210ページ)
VCL に依存しない Windows API の解説。WinMain、WinProc、メッセージ、DLL、コールバックなどなど。

第22章 「オブジェクトと継承」 (35ページ)
第23章 「オブジェクト、カプセル化、プロパティ」 (30ページ)
第24章 「多態性」 (45ページ)
オブジェクト指向の基本。Delphi でどう使われているかの例。

第25章コンポーネントの作成 (35ページ)
第26章非ビジュアルコンポーネントの作成 (30ページ)
コンポーネント作成の基本。

第27章 ? 第30章 で OLE と COMの解説 (160ページ)
1997年の時点で、未来の主要な技術らしいので知っておこう、という話。

第31章・第32章 (95ページ)
DirectX を利用したグラフィックスの例。あくまで前章からの COM つながりで。さすがに古いかも?

  1. 窓の杜でレビューされて自己顕示欲を満たす。
  2. (済)Vector でレビューされて自己顕示欲を満たす。
  3. Google 日本語検索でヒット数 1000 を達成して自己顕示欲を満たす。
  4. はてなブックマークで 100 ブックマークされて自己顕示欲を満たす。
  5. オチを思いつかなかったので省略。

これで行くことにした。

towofu.net になってから1年弱。
まだまだ、辞めそうにはないので2年延長してみた。

あと、XTMemo の WEB 版を Ajax で作ってみたいな、なんて妄想してるんだけどperl の知識も javascript の知識もその他もろもろも足りなさ気。

今の世の中にはフリーウェア/シェアウェア/体験版/バンドル版、色々あるけど、もっと作者が自由に選べてもいいじゃあないか。ということで考えてみた。

年収ウェア - 年収の多い人からたくさん頂く、嫉妬型モデル

一億円以上 10000円
5000万円以上 5000円
1000万円以上 1000円
500万円以上 500円
300万円以上 300円
300万円未満 タダ

苗字ウェア - 苗字の人口比率をたくみに利用し、やった俺他よりお得じゃん、という心理を利用する薄利多売モデル(参考: http://www.myj7000.jp-biz.net/)

佐藤さん 100円
豊川さん 500円
城島さん 1000円
白柳さん 2000円
安井さん タダ(駄洒落)

禁煙ウェア - 食べ物屋で副流煙とか気にせず煙草吸っちゃうヤツとか本当ゆるせないんですモデル

愛煙家 1000万円
禁煙家 500円
嫌煙家 タダ

3番目の禁煙ウェアのような社会的に意義のある主張は実用的かもしれない。

「バージョン番号なんて飾りです。
偉い人にはそれが分からんのです。」

そういえば一周年ぽいというのもあって、正式版としてリリースしてみました。

と、言っても上に書いてあるとおり、バージョン番号が変わったからといって急激にパワーアップするわけではありません。

今後も地道に更新していくのでよろしくお願いします。

このアーカイブについて

このページには、過去に書かれたブログ記事のうちプログラミング・開発カテゴリに属しているものが含まれています。

前のカテゴリはゲームです。

次のカテゴリは雑記です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。