Code030: Q&A式 CGI入門:アクセスカウンターを作ろう!〜今度は画像でカウントだ!〜

この記事は2002年に書かれたものです。


■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
【 Webプログラミング Code Sample 】                          Since2001/11/23

           Code030: Q&A式 CGI入門:アクセスカウンターを作ろう!
                       〜今度は画像でカウントだ!〜

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                                                    Produced by ichikoro.com

           ▼毎週月曜日と金曜日に配信しています。
           ▼等幅フォントでご覧いただくとキレイに見えます。
           ▼登録・解除はこちらから可能です。
               < http://www.ichikoro.com/webp/ >
                  ※バックナンバーへのリンクもあります。
                  ※お友達にもぜひお勧めください(^^)/


─【Contents】───────────────────────────────
    01.Tips ................. Q&A式 CGI入門(Perl編)
    02.News ................. ネット業界の一週間
    03.Answer ............... 前回の回答
    04.From Editor .......... 編集後記


                   【 Webプログラミングは毎週2本立て! 】

             ・月曜日版はWebの実際の活用方法などを特集します。
             ・金曜日版はHTMLやCGIなど一つの分野について最初から
              解説する講座になっています。現在はC言語入門です。


こんにちは、編集者の勝部です。

今回でめでたく30号です。
さらにさらに、前回の配信で何と1900部を突破いたしました!

      (*^^)//。・:*:・°'★,。・:*:♪・°'☆ パチパチ

これもみなさまの応援のおかげです。
ふつつかなメルマガではございますが、これからもよろしくお願いいたします。


ではでは、今週も行ってみましょう!



━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  01.Tips  「ちょっとがんばれば分かる FAQ式CGI入門 Perl編」
──────────────────────────────────────

さぁ、アクセスカウンターを作るお話もいよいよ大詰め!
今週は一段と本物(?)っぽく、画像でカウントできるようになりますよ!

──────────────────────────────────────
■前回のプログラム
──────────────────────────────────────

    前回は、画像を表示するCGIをご紹介しました。
        http://www.ichikoro.com/webp/back_list/?cd=00026

        #!/usr/bin/perl

        #-------------------------------------#
        #        画像ファイルから情報取得     #
        #-------------------------------------#
        open(IMG, "image.gif");
        @buff = <IMG>;
        close(IMG);

        #-------------------------------------#
        #              GIFを表示              #
        #-------------------------------------#
        print "Content-type: image/gif\n\n";
        foreach $i (@buff){
            print $i;
        }

        exit(0);


    今回はここから、画像を使ったカウンターに仕上げてみましょう!
    さて、今回この特集記事はより人間チックに、QとAがお送りします。
    というわけで、彼らの名前募集中です(笑)

        あて先はこちら
            mm-webp@ichikoro.com


──────────────────────────────────────
■数字を解剖だ!
──────────────────────────────────────

    [Q]. 今週もよろしくお願いしまーす。
    [A]. はいはい。では早速、次のCGIを実行してみてください。

            #!/usr/bin/perl

            #-- 数字を代入 --#
            $suuji = 1234567890;

            #-- 数字を“一文字”ずつに分割する --#
            @split_suuji = split("", $suuji);

            #-- 順番に表示する --#
            print "Content-type: text/html\n\n";
            $count = 1;
            foreach $i ( @split_suuji ){
                print "$count : $i<br>\n";

                $count = $count + 1;
            }

            exit(0);


    [Q]. これは前回逃亡する寸前に私が質問したことと関係あるんですか?
    [A]. その通り!詳しくは前回を見ていただくと分かるとおり、カウンター
         は、次のような流れのプログラムになります。

>            (1)前回のカウント値のつまったファイルを開く
>            (2)変数$countに、ファイルの情報を詰め込む
>            (3)ファイルを閉じる
>
>            (4)変数$count にあった画像を作成し、画像の内容を変数$count_imageに格納
>
>            (5)ブラウザにこれからGIFを送ると教える
>            (6)変数$count_imageをブラウザに送る

    [Q]. ふむふむ、それで 1 〜 3 と 5, 6 はもう取り上げたんですよね。
    [A]. 残す所は (4) だけなのです。
         さて、では元のCGIの話に戻りましょう。
         このプログラムは、全て「ある」行を解説するためのものです。

    [Q]. う〜んと、ここかな?

>            #-- 数字を“一文字”ずつに分割する --#
>            @split_suuji = split("", $suuji);

    [A]. そうそう。ここでsplitという命令を使っています。
         これを解説する前に今度は下のようなプログラムを実行してください。

            #!/usr/bin/perl

            #-- ちょっとした英語の文章を代入 --#
            $ai = "Please, make me a real boy";     #陰気であんまり好きじゃないんですが、
                                                    #ラストは思わず泣きましたね(^^;

            #-- スペースで分割 --#
            @split_ai = split(" ", $ai);

            #-- 順番に表示する --#
            print "Content-type: text/html\n\n";
            $count = 1;
            foreach $i ( @split_ai ){
                print "$count : $i<br>\n";

                $count = $count + 1;
            }

            exit(0);

    [Q]. おお、オスメント君の台詞がバラバラに!
    [A]. splitとは呼んで字の如く、バラバラに分割する命令のことです。
         既にお分かりだと思いますが、

             (結果) = split("分割する文字を指定",  分割する対象);

         というような風に記述します。


    [Q]. なるほど。結果は配列になってるんですね?
    [A]. Yes!
         さらに分割する文字を何も指定しないと、一文字ずつバラバラにした
         結果が返ってきます。


    [Q]. で、これが何の関係があるんですか?
    [A]. よくぞ聞いてくれました!


──────────────────────────────────────
■画像を“連結”しよう!
──────────────────────────────────────

    [Q]. タイトルにちょっと期待(笑)
    [A]. これは結構感動しますよ!(^^)/
         今回は、実行するのに必要なものがあります。
         まずは以下のものを用意してください。

            ・gifcat.pl Ver1.60 - GIF画像連結ライブラリ

                [入手先]とほほのCGIソフト集
                  http://tohoho.wakusei.ne.jp/wwwsoft.htm
                    ※一番下にあります。
                     圧縮してありますので解凍してください。

            ・適当なGIFファイル
                ※アニメGIFは不可
                ※同じ高さの物以外は不可
                ※なるべく軽いヤツでお願いします。


    [Q]. これは何ですか?<gifcat.pl
    [A]. こいつが、実際に画像を合体してくれます。
         gifcat.plの中に、合体するためのプログラムが書かれています。

    [Q]. うぉ、クラッとしますね(ーー;)
    [A]. うーん、この中身を理解する必要は全くありません(^^;
         作った方に感謝して使い方だけ覚えましょう〜。
         というわけで、以下のCGIを動かしてみましょう。

            #!/usr/bin/perl

            require "gifcat.pl";                        #gifcat.plの機能を取り込む

            #-- 画像の場所を変数に設定 --#
            $image_1 = "sono_1.gif";
            $image_2 = "sono_2.gif";

            #-- 合体! --#
            $join_image = gifcat::gifcat($image_1, $image_2);

            #-- 表示する --#
            print "Content-type: image/gif\n\n";
            print $join_image;

            exit(0);

    [Q]. スゴイ!スゴイ!
    [A]. ちょっと感動ですよね。


──────────────────────────────────────
■カウンターを作ろう!
──────────────────────────────────────

    [Q]. あ!分かりましたよ。
         splitで数字を分解して、gifcatで合体してやろうということですね!?
    [A]. その通り。
         というわけで、今回ラストのCGIは以下です。
         これまでの総決算ですよ!!

            ▼必要なもの
                (1)gifcat.pl ............ CGIと同じディレクトリにUP
                (2)0 〜 9 のGIF画像 ..... 同じ高さでアニメGIFでない物を。
                                          名前をそれぞれ 0〜9 とし、拡張子(.gif)
                                          もいりません。CGIと同じディレクトリにUP
                (3)count_value.dat ...... 0とだけ記述したファイル。
                                          CGIと同じディレクトリにUP

            ▼ここからがCGIです。

                #!/usr/bin/perl

                require "gifcat.pl";                      #gifcat.plの機能を取り込む

                #-------------------------------------#
                #           前回の値を取得            #
                #-------------------------------------#
                open(DAT, "count_value.dat");
                $count = <DAT>;
                close(DAT);

                #-------------------------------------#
                #        前回の値に+1して保存         #
                #-------------------------------------#
                $count = $count + 1;                      #取得した値に+1する
                open(DAT, ">count_value.dat");
                print DAT $count;
                close(DAT);

                #-------------------------------------#
                #     数字を“一文字”ずつに分割する  #
                #-------------------------------------#
                @split_suuji = split("", $count);

                #-------------------------------------#
                #               合体!                #
                #-------------------------------------#
                $join_image = gifcat::gifcat( @split_suuji ); #配列は自動的に以下の
                                                              #ように展開されます。
                                                              #  $split_suuji[0],
                                                              #  $split_suuji[1],
                                                              #         :
                                                              #         :
                                                              #  $split_suuji[n]

                #-------------------------------------#
                #              画像を表示             #
                #-------------------------------------#
                print "Content-type: image/gif\n\n";
                print $join_image;

                exit(0);


    [Q]. どうやって実行するんですか??
    [A]. そのまま直接CGIを訪れるか、IMGタグで呼び出してみてください。


──────────────────────────────────────
■「使ってはいけない」
──────────────────────────────────────

    [Q]. 思っていたよりも、結構簡単なんですね(^-^)
    [A]. そうですね〜。順序良く勉強していけば、そんなに難しくはないんです。
         ただ、

    [Q]. ただ?
    [A]. 覚えないといけない事が沢山ありすぎるので、だんだんと根気の勝負に
         なってきます(笑)


    [Q]. ところで、この項のタイトルが気になってるんですけど(^^;
    [A]. 実はこのCGI、色々と問題をかかえています。

        (1)桁数がバラバラ
        (2)同時にアクセスされると、ファイルが真っ白になってしまう。

    [Q]. おお!? 2番はかなり致命的ですね!
    [A]. というわけで、次回はこれらを出来る限り解決する方向で(^^ゞ



さらに以下のことにも挑戦しちゃう予定です。

    (1)ログを取ろう!
    (2)キリ番の時には画像を変えよう!

誌面の都合上、次々回になることもあります(^^;
ところで、「合体」って聞くたびに釣りバカ日誌思い出しちゃうのは私だけ?(笑)


---【PR】-------------------------------------------------------------------
                CGIで困った、腕を上げたいならまずはココ
                  『CGIプログラミングメーリングリスト』

                   < http://www.ichikoro.com/cgi/ml/ >
                                                    Produced by ichikoro.com
-------------------------------------------------------------------【PR】---

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  02.News  「今週の気になるニュース
                インターネット業界の一週間」
──────────────────────────────────────

すでにご覧になっている方も多いと思いますが、4月1日は下記のサイトで
フィーバーしてました。

  http://dailynews.yahoo.co.jp/fc/science/april_fools/
    ※まぐまぐは元にもどっちゃってます。

もう、インプレス大好きです(笑)


───────
  4月1日(月)
───────
・TTNet、PHS事業を鷹山に売却
  http://k-tai.impress.co.jp/cda/article/news_toppage/0,,8899,00.html
    初めて契約した携帯(というかPHS)はアステルでした。
    丁度20歳の誕生日に買いに行ったこともあり、こういうニュースを聞くと感慨
    深くなってしまいます。今では解約してDoCoMoを使ってますが、その時アステ
    ルを選んだ理由は、もちろん売り場のお姉ちゃんがかわいかったからです(笑)
        ※そんなんバッカリです(^-^;

・ミッフィーの携帯電話向けコンテンツ「あのね ミッフィー」 
  http://k-tai.impress.co.jp/cda/article/news_toppage/0,,8900,00.html


───────
  4月2日(火)
───────
・W3Cが開設しているメーリングリストの全文検索サービスが開始される
  http://www.watch.impress.co.jp/internet/www/article/2002/0402/w3c.htm

・電通ほか、インターネットキーワードを使ったラジオ広告を展開
  http://www.watch.impress.co.jp/internet/www/article/2002/0402/ik.htm
    うちの会社でも購入してますが、実は月4000円くらいと意外に安かった
    りします。個人サイトだとあんまり意味ないですが、会社の商品名を登
    録しておけば、ホームページへの誘導がしやすいですよね。
    
    日本語ドメインより魅力的じゃないかと思っていますが、このサービス、
    王様のようになっているIEだからこそ成立するビジネスだったりします。

・インターネットで家族の絆は深まるか?
  http://japan.internet.com/research/20020402/1.html
    次は遠距離恋愛での調査をリクエスト。
    何度つらい思いをしたことか(笑)

・韓国、携帯電話加入者が3000万人を突破 
  http://japan.internet.com/webtech/20020402/5.html


───────
  4月3日(水)
───────
・サーチエンジン「Teoma」が正式リリース
  〜情報発見のための新しいツール登場
  http://www.watch.impress.co.jp/internet/www/article/2002/0403/teoma.htm
    Lycosが採用したWiseNutとともに以前から注目されていたTeoma。
    こいつの一番の特徴は、Googleのページランクの概念とともに、「特定の分野」
    の中でランクを振るという物。詳しくは記事を(^-^;

    早く日本語対応版を使ってみたいです。
    (英語だとスゴイかどうかハッキリ分からない(笑))

───────
  4月4日(木)
───────
・米Yahoo!、PDFファイルをディレクトリーに掲載開始
  http://www.watch.impress.co.jp/internet/www/article/2002/0404/yah.htm
    これってロボット式検索エンジンの仕事なのでは...(^-^;
    Googleと提携してるんだから任せとけばいいのに、何でこんなこと
    やるんでしょ??
        ※GoogleはPDF以外にもOffice系のファイルも検索できます。

・昭文社、SVGを利用した法人向け地図サービス「BaseMapサービス」提供へ
  http://www.watch.impress.co.jp/internet/www/article/2002/0404/svgmap.htm


───────
  4月5日(金)
───────
・ほぼすべてのCDをバックアップできる「CloneCD4」 
  http://www.zdnet.co.jp/news/bursts/0204/05/07.html
    イタチごっこですな(^^;



━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  03.Answer  「前回の回答」
──────────────────────────────────────

金曜日版で出題した問題の回答例です。


    Q. 2 〜 1000 までの素数を求めるプログラムを作成せよ

    ■実行例
        C:\>bcc32 sample.c
        Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
        sample.c:
        Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

        C:\>sample
          2   3   5   7  11  13  17  19  23  29  31  37  41  43  47  53  59  61  67  71
         73  79  83  89  97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173
        179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281
        283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409
        419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541
        547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659
        661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809
        811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941
        947 953 967 971 977 983 991 997


    A.1 まずはストレートな回答例です。
        ここでは「フラグ」という考え方を使います。

        #include <stdio.h>

        int main(void)
        {
            int n;
            int i;

            /* 2 〜 1000 を調べる */
            n = 2;
            while( n<=1000 ){
                int flag = 0;

                /* n以下の整数で割り切れるかどうかを計算 */
                i = 2;
                while( i<n ){
                    if( (n%i) == 0 ){        /* 割り切れるかどうかチェック */
                        flag = 1;
                    }

                    i = i + 1;
                }

                /* flagが立っていなければ(一回も割れていなければ)素数 */
                if ( flag == 0 ){
                    printf("%3d ",i);
                }

                n = n + 1;
            }

            return(0);
        }

もちろんこの回答でも問題はありません。ただ、ちょっと無駄が多いようです。
そこで、以下のように変更してみましょう。

    A.2 一行追加することで、無駄な計算を省くことができます。

        #include <stdio.h>

        int main(void)
        {
            int n;
            int i;

            /* 2 〜 1000 を調べる */
            n = 2;
            while( n<=1000 ){
                int flag = 0;

                /* n以下の整数で割り切れるかどうかを計算 */
                i = 2;
                while( i<n ){
                    if( (n%i) == 0 ){       /* 割り切れるかどうかチェック */
                        flag = 1;
                        break;              /* breakはwhileを抜ける命令分です。
                                             * 割り切れた時点で素数ではないと
                                             * 判別できるのでループを抜けてし
                                             * まってOK
                                             */
                    }

                    i = i + 1;
                }

                /* flagが立っていなければ(一回も割れていなければ)素数 */
                if ( flag == 0 ){
                    printf("%3d ",i);
                }

                n = n + 1;
            }

            return(0);
        }

例えば1000をすごく大きい値にし(10億など)、ストップウォッチなどを使い、両方を
比べてみてください。たった一行追加しただけで大幅に実行結果が変わりましたよね?


さて、実はもっと効率の良いやり方があります。
これは「エラトステネスのふるい」と呼ばれる物で、以下のような考え方になります。


    (1) 2 〜 n までの全ての値を「ふるい」に入れる

    while( n回繰り返す ){

        (2) 「ふるい」の中で一番小さい数が素数となる
        (3) (2)で求めた素数の倍数をすべて「ふるい」からハズス

    }

    (4)「ふるい」に残った物が素数のリストとなる


さて、この「エラトステネスのふるい」を解くには「二次元配列」を覚えると、
比較的簡単に解くことができます。金曜日はこの二次元配列を取り上げますので、
それまでしばらくお待ちください(^-^)/


【参考文献】
    ・C言語による はじめてのアルゴリズム入門
        河西 朝雄 (著)/\2,718/技術評論社/ISBN:4-87408-500-8
        http://www.amazon.co.jp/exec/obidos/ASIN/4874085008/stagefan-22
            ※学生時代に随分とコイツで勉強しました。
              お世話になりました(^-^)



━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                           編    集    後    記
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

最近「ドゥ」というスポーツクラブに通い始めました。というのも、社内報の企画で
ダイエットをしているのですが(笑)、半分成り行きで先々週くらいから行っています。
普段から想像していた通り、なかなか不思議な空間なのですが、その場の雰囲気だけ
で結構楽しめます<おい

先週は、エアロビも初めて体験。
「ストレッチ&ベーシック」という初心者向けのヤツなのですが、もともとリズム
感のない私にはとてもついていけませんでした(^^; 皆からワンステップズレルは、
動きが左右逆になるのはもちろん、手と足が一緒に出たりとか、モウ!モウ!モウ!
って感じです(笑)うぐ〜、悔しいぞー。


でも、これが思っていたより全然楽しいのです!
学生の頃はバスケとサッカーに夢中で(見るよりやる方)、元々カラダを動かすのは好
きな方だったりします。そう言っても信じてもらえないのは何故でしょうね(笑)

次回はプールに挑戦する予定です。
よく浮きそうだ(爆)

    ●ドゥ・スポーツプラザ
      http://www.dspnet.co.jp/


ではでは、また金曜日にお会いしましょう(^.^)/~~~



■Information 
 「Webプログラミングからのお知らせ」

    【相互広告募集のお知らせ】
      読者数を増やしたいメルマガ発行者さんを募集しています。お互いに一定期間(1〜
      3回程度)広告を掲載し合いませんか?詳細はご相談ください(無料)

         お問い合わせ: mm-webp@ichikoro.com

    【コラム募集のお知らせ】
      Webプログラミングでは、寄稿していただけるコラムやプログラムなどを募集して
      います。たくさんの読者の方にあなたをアピールする場にもなります。ぜひ有意義
      な情報やご意見をお送りください。

         お問い合わせ: mm-webp@ichikoro.com



■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

                   【 Webプログラミング Code Sample 】

                    発  行 : ichikoro.com
                発行責任者 : 勝部 麻季人
                              < mailto:katsube@ichikoro.com >
                  発行部数 : 1903部(前回)
                 Webサイト : < http://www.ichikoro.com/webp/ >
            お問い合わせ先 : < mailto:mm-webp@ichikoro.com >

                            Powerd by まぐまぐ
    All Right Reserved, CopyRight(C) 2001 Webプログラミング Code Sample
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■


コメント

コメントを入力. Wiki文法が有効です:
V A F​ N U