これだけは知っておきたい。Web開発に必要な周辺技術って何ですか?

Twitterで昔こんな会話をしていたので、

Web開発に必要な技術を、自分の経験とともにまとめてみたいと思います。

Web開発って、コーディングができれば良いってもんじゃ無いんですよ。

Web自体がいろんな技術の組み合わせで成り立っているので、それを知らないと、万が一のトラブルの時に対応出来ないのですよ。

その当たりのサポートもできれば、一人前のWeb開発者です。

Linux

WebサーバのほとんどがLinux系OSで動作しています。

その理由は、コスト。

Linuxはオープンソースで開発されたOSなので、OSそのものにお金がかかりません。

その代わりメンテナンスも自分でやらないといけませんがね。

通信プロトコル(http等)

ブラウザのWebサーバの間はHTTPという通信プロトコルを使用しています。

Ajaxを使用した場合もその都度HTTPを使用することになりますので、その当たりの知識も勿論必要になります。

Webサーバ(Apache or Nginx)

サーバにソースファイルを置いただけでは機能しません。

HTTPを処理してくれるWebサーバがあって初めてWebページが機能します。

Apacheはリソースを多く使用しますが、プラグインで機能追加できるので、扱いやすいです。

Nginxは非常に軽量で動作できるWebサーバです。

玄人からすれば、Nginxの方が好まれるようです。

データベース

Webシステムでは大量のデータを扱いますので、データベースを理解することは非常に重要です。

自分も今は慣れましたが、情報処理の資格を取るのにSQLを覚えるのが大変でした。

データベースの種類は沢山ありますが、基本的なSQL文は共通しているので、基本的なところを押さえれば問題無いでしょう。

このほかにも、使用するフレームワークやライブラリなどが挙げられますが、挙げれば切りが無いので、必要なときにその都度勉強する必要があります。

もう勉強することが多くてたいへんよぉ

でも知識はあればあるだけその分自分に有利に働きますので、学ぶことは大事。

ITエンジニアは日々勉強です。

【Laravel】【ホテル予約管理】レスポンシブ対応を行う

前回までの状況はこちら

最新ソースはこちら(gitHub)

https://github.com/takishita2nd/hotel-mng

さて、残る作業はレスポンシブ対応ですが、

そもそも、レスポンシブ対応とは何かというと、

PCだけでなく、スマホやタブレットでも、そのデバイスに対応した表示に切り替えることができる対応、ということです。

PCでは正しく表示できても、スマホだと表示が崩れて使用できない、というのはレスポンシブ対応とは言えません。

その確認のために重宝するのが、Google Chromeのレスポンシブモード。

擬似的にスマホやタブレットでの表示に切り替えてくれる機能です。

使い方は、Google Chromeの画面でF12を押し、

このボタンをクリックして青色(絵の状態)にします。

表示エリア上部にこんな感じのバーが表示されますので、ここをクリックすることで、画面の表示解像度を切り替えることができます。

こうやってレスポンシブ対応できているかを確認するのですね。

実機を使うと、それだけ実物のデバイスを用意しなければなりませんので、これはかなり有効な確認方法です。

ためしに、作成中のいろんなページを表示させてみましょう。

こんな感じで文字が2行になるのはまだ読めるのでセーフです。

こんな感じで表示が枠からはみ出てしまったらアウトですね。

修正する必要があります。

こういうのは、たいていテンプレートやスタイルの問題です。

こんな感じでどうでしょうか。

いい感じに仕上がったと思います。

実は、Laravelには、標準でBootstrapというJSライブラリが組み込まれていて、このライブラリでブラウザ差分を吸収したり、基本的なレスポンシブ対応を行えるようにしてくれています。

今作成している機能はBootstrapをバリバリ活用した作りになっていません。そもそもそんな表示をするところが無いためです。

もしかしたら、画像のサムネイルなどをたくさん表示させたり、表を二列に表示させる場合などに活用することになるかもしれませんね。

まぁ、これで最終チェックして提出しようと思います。

【C#】【数独】解析ロジック(ラインチェック)を追加する

前回までの状況はこちら。

最新ソースはこちら(gitHub)

https://github.com/takishita2nd/sudoku

さて、前回のアルゴリズムで、いくつか問題を解いてみたのですが、

こんな問題の時、解析が完了しませんでした。

この状態のまます、解析が進まなかったんですね。

この状態、手で解いた場合、

この2箇所に「3」が入ります。

この時の解析ロジックを組み込まなければなりません。

では、どうやって解析すればいいのか。

この場合、3という数字に注目すると、

この部分、および、すでに確定されているマスに「3」が入ることができません。

赤いところの9マスは一箇所しか空いていないため、そこの空いているマスには「3」が入ることが確定されます。

これをプログラミングで行います。

考え方は、9×9の二次元配列を用意し、各数字について、入れることができないマスを埋めていき、9エリアに一箇所だけ空きがあれば、その値が確定する、とします。

        private void searchNumber()
        {
            for(int number = 1; number <= 9; number++)
            {
                bool[,] tempTable = new bool[9, 9];
                // 初期化
                for (int i = 0; i < 9; i++)
                {
                    for (int j = 0; j < 9; j++)
                    {
                        tempTable[i, j] = false;
                    }
                }

                // 数字が入らないところをtrueにする
                for (int i = 0; i < 9; i++)
                {
                    for(int j = 0; j < 9; j++)
                    {
                        if(tempTable[i,j] == false)
                        {
                            tempTable[i, j] = _square[i, j].isConfirmed();
                            if(_square[i,j].GetValue() == number)
                            {
                                for(int row = 0; row < 9; row++)
                                {
                                    tempTable[row, j] = true;
                                }
                                for(int col = 0; col < 9; col++)
                                {
                                    tempTable[i, col] = true;
                                }

                                int rowStart;
                                int colStart;
                                getRowCol9Area(i, j, out rowStart, out colStart);
                                for (int r = rowStart; r < rowStart + 3; r++)
                                {
                                    for (int c = colStart; c < colStart + 3; c++)
                                    {
                                        tempTable[r, c] = true;
                                    }
                                }
                            }
                        }
                    }
                }

                // debug
                FileAccess.Output(tempTable);

                // 結果を確認する
                for(int i = 0; i < 9; i++)
                {
                    for(int j = 0; j < 9; j++)
                    {
                        if(tempTable[i,j] == false)
                        {
                            int rowStart;
                            int colStart;
                            getRowCol9Area(i, j, out rowStart, out colStart);

                            int count = 0;
                            for (int r = rowStart; r < rowStart + 3; r++)
                            {
                                for (int c = colStart; c < colStart + 3; c++)
                                {
                                    if(tempTable[r,c] == false)
                                    {
                                        count++;
                                    }
                                }
                            }
                            if(count == 1)
                            {
                                _square[i, j].SetValue(number);
                            }
                        }
                    }
                }
            }
        }

        private void getRowCol9Area(int row, int col, out int rowStart, out int colStart)
        {
            if (row >= 0 && row <= 2)
            {
                rowStart = 0;
            }
            else if (row >= 3 && row <= 5)
            {
                rowStart = 3;
            }
            else
            {
                rowStart = 6;
            }

            if (col >= 0 && col <= 2)
            {
                colStart = 0;
            }
            else if (col >= 3 && col <= 5)
            {
                colStart = 3;
            }
            else
            {
                colStart = 6;
            }
        }

一応、色塗りした処理結果もデバッグ用に出力させました。

3の時の色塗り結果を見てみると、9マスで一か所だけ空きがあることが分かります。

目論見通り、3が確定されました。

全部埋まりました。

ロジックがうまく働いたようです。

【バンドリ】【ガルパ】1/21のハロハピ放送局で公開された情報まとめ

新情報まとめました。

新カバー楽曲

ドレミファロンド

ボカロ曲です。

カバーバンドはハロハピ

予想レベル24。

フル楽曲情報

予想通りFIRE BIRDでした。

予想レベル28。

公開と同時にMVも追加されます。

公開日は23日です。

ガールズバンド総選挙情報

イラストと楽曲が公開されました。

曲の一部が後悔されていましたが、かなり難しそうです。

予想レベル27。

ログインボーナス

ログインボーナス忘れずに貰いましょう。

【レビュー】とにかく目を労りたい。アイマッサージャー

本当にね、もう年だからね、長時間PC作業していると目が疲れるのよ。

なので、思い切って買ってみました。

アイマッサージャー。

USBで充電するタイプで、3~4時間の充電で、30~45分使用可能になります。

スイッチをONにすると動き出します。

目に当てる部分が暖かくなり、空気圧と振動でマッサージしてくれます。

やはり、目元を暖めてくれるのは本当に嬉しくて、

今までは蒸しタオルを使っていたのですが、その効果は長くても1分。

でもこれは1回で15分間暖めてくれます。

この機能だけで良い。

もう、マッサージ機能とかは無くても良いです。

振動機能なんて意味わからん。

目を温めて、繰り返し利用できるだけでも買えて満足です。


【ぼっち】【釣り】ワカサギ釣り体験

じゃらんを調べてみると、札幌でワカサギ釣り体験ができるというものがありましたので、行ってみました。

車で行く場合は、駐車料金が必要になります。

車が無い場合は、札幌バスターミナル、麻生駅、栄町駅からあいの里4条1行きのバスに乗れば最寄りのバス停まで行けます。

自分でテントを立ててワカサギを釣ることもできるみたいです。

もちろん、釣り具をレンタルすることもできます。

テントに番号が付けられていて、受付を済ませると、指定されたテントの中で釣ることになります。

テントの中はこんな感じ。

穴が空いているので、ここに糸を垂らして釣ります。

エサもレンタルに含まれます。(※観覧注意)

13時から15時までやってみましたが、釣れませんでした。

15時近くになると日が落ちて寒くなってきて、帰りのバスの時間も近くなってきたので、断念しました。

いろいろ調べてみると、エサは針に取り付けた後、はさみで二つに切る、という手間が必要らしいです。

というのは、エサを切断した断面からエサの体液が水の中に広がり、ワカサギをおびき寄せる、らしいです。

レンタルにはさみは付いてきません。

余ったエサは同じテントでワカサギを釣りまくってた方にあげてきました。

その人の話を聞くと、釣り具は1500円で購入できる、とのことです。

まぁ、いろいろ足りないところもわかってきたので、また次回(たぶん来年)挑戦したいと思います。

冷えた体に冷たいビール。

【Laravel】【ホテル予約管理】バリデーション処理を実装しなおす。

前回までの状況はこちら。

最新ソースはこちら(gitHub)

https://github.com/takishita2nd/hotel-mng

Vue.jsを使用する前はRequestにバリデーション処理を行っていましたが、Vue.jsを使用してからは、一切使用されていませんでした。

当然、このままではよろしくないので、パラメータをチェックするバリデーション処理を追加します。

やることは単純で、パラメータに値が入っているかどうかだけを確認します。

            validate: function(){
                var ret = true;
                this.errors = [];
                if(this.contents.id == 0) {
                    this.errors.push("ユーザーが選択されていません");
                    ret = false;
                }
                if(this.contents.num == 0) {
                    this.errors.push("人数が選択されていません");
                    ret = false;
                }
                if(this.contents.roomid == 0) {
                    this.errors.push("部屋が選択されていません");
                    ret = false;
                }
                if(this.contents.days == 0) {
                    this.errors.push("宿泊日数が入力されていません");
                    ret = false;
                }
                if(this.contents.start_day == "") {
                    this.errors.push("宿泊日が入力されていません");
                    ret = false;
                }
                if(this.contents.checkout == "") {
                    this.errors.push("チェックアウト時刻が入力されていません");
                    ret = false;
                }
                return ret;
            },
            regist: function() {
                if(this.validate() == false){
                    this.error_flg = true;
                    return;
                }
                var self = this;
                this.param.contents = this.contents;
                axios.post('/api/add', this.param).then(function(response){
                    document.location = "/management";
                }).catch(function(error){
                    self.error_flg = true;
                    self.error_message = error.response.data.errors;
                    console.log("失敗しました");
                });
            },
        <p v-if="error_flg == true" class="error">
            <ul>
                <li v-for="error in errors">{{ error }}</li>
            </ul>
        </p>

チェックに引っかかった項目をすべてerrorsにpushして、error_flg=trueとすることで、その内容をリストで表示します。

おなじ処理を編集画面にも実装します。

うまく動きました。

スマートバンドはfitbitを選ぶべき理由

Amazonを見ていると、他にもそれなりの性能で安いスマートバンドあるじゃん!って思いますが。

オイラも一時期、安いスマートバンド使ってました。

これを使用していたときは、とにかく、装着部分がめちゃくちゃかぶれてました。

ところがですよ。

これをfitbitに代えてからかぶれなくなったのです。

これには、調べてみると理由がありまして。

fitbitって、実は過去に皮膚のかぶれでクレームが入り、リコールを行っているのです。

https://www.gizmodo.jp/2015/02/post_16614.html

原因は、バンドの素材にアレルギーを引き起こす可能性があるものが含まれていたらしく、それ以降、アレルギー物質を含まない素材にした、ということらしいです。

実際、オイラが安物スマートバンドを使っていたときは、一日中装着していると、肌がかぶれていましたが、

fitbitに代えてからは一切かぶれていないのです。

お風呂以外、ほぼ同じ場所につけっぱなしにも関わらず!

確かにfitbitは他のスマートバンドより割高ですが、高いものには高い理由があった。

今はfitbitに代えて大満足です。

安物スマートバンドで肌荒れに困っている人は、今すぐfitbitに切り替えよう!

【C#】【数独】終了判定を実装する

前回までの状況はこちら

最新ソースはこちら(gitHub)

https://github.com/takishita2nd/sudoku

さて、最後に解析終了処理を実装していきます。

解析終了条件は、9×9=81マス全ての数字が確定した場合、になります。

逆に言えば、81マスの中で、一つでも確定していないマスがあれば、終了しない、と言うことになります。

と言うわけで、コードはこうなりました。

        private bool checkEnd()
        {
            for (int i = 0; i < 9; i++)
            {
                for(int j = 0; j < 9; j++)
                {
                    if(_square[i, j].isConfirmed() == false)
                    {
                        return false;
                    }
                }
            }
            return true;
        }

解析終了ならばtrueを、そうでないならばfalseを返します。

これを周回処理に組み込みます。

        public void run()
        {
            bool roop = true;
            while (roop)
            {
                for(int row = 0; row < 9; row++)
                {
                    for(int col = 0; col < 9; col++)
                    {
                        if(_square[row,col].isConfirmed() == false)
                        {
                            Candidate candidate = new Candidate();
                            searchRowLine(row, candidate);
                            searchColLine(col, candidate);
                            search9Area(row, col, candidate);
                            _square[row, col].checkCandidate(candidate);
                        }
                    }
                }

                roop = !checkEnd();
                FileAccess.Output(_square);
            }
        }

ループ条件と判定結果が反転しているので、!演算子で反転させています。

実行結果はこちら。

ちゃんと全部埋まった時点で終了しました。

【Laravel】【ホテル予約管理】忘れていた機能を追加する

前回までの状況はこちら。

最新ソースはこちら(gitHub)

https://github.com/takishita2nd/hotel-mng

さて、ここである重大な欠陥を見つけてしまいました。

それは、Vue.jsで実装を行った際、管理者が予約をチェックする処理の実装を忘れていました。

いかんいかん、完全にミスったわ。

というわけで、ここを実装します。

修正するのは予約一覧から予約をクリックして表示される予約詳細画面です。

管理者がこの画面を表示させた場合、チェックボタンを追加し、チェック処理を行います。

Vue.jsのテンプレートと処理を追加します。

            <p>
                <button @click="closeModal">close</button>
                <button v-if="edit_flg == false" @click="onClickEdit">編集</button>
                <button v-else @click="onClickSave">保存</button>
                <button v-if="edit_flg == false" @click="onClickDelete">削除</button>
                <button v-if="role == true && edit_flg == false" @click="onClickCheck">チェック</button>
            </p>
        data() {
            return {
                role: false,
                error_message: "",
                error_flg:false,
                errors: {},
        created: function() {
            this.getRole();
            this.getRooms();
            this.getTimeList();
        },
        methods: {
            getRole: function() {
                var self = this;
                axios.post('/api/role').then(function(response){
                    self.role = response.data.role;
                }).catch(function(error){
                    console.log("失敗しました");
                });
            },

データにroleフラグを追加し、画面表示時にroleの取得を行います。

trueが返れば管理者であるということなので(ここは前回実装の動きに合わせる)、role=trueならば、チェックボタンを表示させます。

また、編集中はチェックボタンを表示させないようにします。

では、API部分の実装。

    public function check(Request $request)
    {
        $this->registerManagement->lodging($request->id);
        return response()->json(['registerLists' => $this->registerManagement->getListByMonth(
            $request->year,
            $request->month,
            $request->room,
            Auth::user()
        )]);
    }

チェックの実行を行った直後に、予約一覧を返すことで、チェック後の予約一覧を素早く表示させることができます。

最後Routeを追加。

Route::post('/api/check', 'ApiController@check');

これで機能するようになりました。

ふぅ。(汗

自分、ぼっちですが何か?