カテゴリー
読みやすいコード

最後の例/A Final Example

この章の最後の例では、今まで説明した多くの原則を示す例を示したいと思います。
次のように配置された多数の入力テキストフィールドを持つWebページがあるとします。

<input type="text" id="input1" value="Dustin"> 
<input type="text" id="input2" value="Trevor"> 
<input type="text" id="input3" value="">
<input type="text" id="input4" value="Melissa"> 
...

ご覧のように、IDはinput1から始まり、そこからインクリメントします。
あなたの仕事は、文字列を受け取りページの最初の空の(この例では "input3")に置くsetFirstEmptyInput()という関数を書くことです。 この関数は、更新されたDOM要素を返す必要があります(空の入力が残っていない場合はnull)。 これを行うためのコードは、この章の原則を適用しないものです:

var setFirstEmptyInput = function (new_value) {
    var found = false;
    var i = 1;
    var elem = document.getElementById('input' + i);
    while (elem !== null) {
        if (elem.value === '') {
            found = true;
            break;
        }
        i++;
        elem = document.getElementById('input' + i);
    }
    if (found) elem.value = new_value;
    return elem;
};

このコードは仕事を終わらせるが、それほど美しいものではない。 何が問題なのですか?それをどのように改善しますか?
このコードを改善する方法はたくさんありますが、使用する変数の観点から検討します。

・var found
・var i
・var elem

これら3つの変数はすべて関数全体に存在し、複数回書き込まれます。 それぞれの使い方を改善しようとしましょう。
この章の前半で説明したように、発見されたような中間変数は、しばしば早期に返すことで排除することができます。 ここにその改善があります:

var setFirstEmptyInput = function (new_value) {
    var i = 1;
    var elem = document.getElementById('input' + i);
    while (elem !== null) {
        if (elem.value === '') {
            elem.value = new_value;
            return elem;
        }
        i++;
        elem = document.getElementById('input' + i);
    }
return null;
};

次に、elemを見てみましょう。 コード全体で複数回使用されていますが、その値を把握するのが難しい非常に「偽の」方法です。 コードは、elemが私たちが反復処理している値であるかのように見せます。 ですから、whileループをforループに再構成しましょう。

var setFirstEmptyInput = function (new_value) {
    for (var i = 1; true; i++) {
        var elem = document.getElementById('input' + i);
        if (elem === null)
            return null;  // Search Failed. No empty input found.
        if (elem.value === '') {
            elem.value = new_value;
            return elem;
        }
    }
};

特に、elemがどのように寿命がループ内に含まれる追記型変数として機能するかに注目してください。 true for aループ条件の使用は普通ではありませんが、代わりに、私は1行でiの定義と修正を見ることができます。 (伝統的な(真実)も合理的です。)

参考文献:

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code (English Edition)

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code Kindle (English Edition)

カテゴリー
読みやすいコード

変数は一度だけ書き込む/Prefer Write-Once Variables

変数は一度だけ書き込む

これまでのところ、多くの変数がある「プログラム」を理解することが難しいことについて、この章では話し合いました。まあ、絶えず変化している変数について考えることはさらに困難です。 それらの値を追跡することは、さらに困難を生じさせます。
この問題に対処するために、少し奇妙に思えるかもしれない提案があります:追記型変数を好む。
「永続的なフィクスチャ」である変数は、考えるのが簡単です。 確かに、定数のような:

static const int NUM_THREADS = 10;

読者の側で多くのことを考える必要はありません。 同様の理由から、C ++でのconstの使用(およびJavaでのfinal)は非常に奨励されています。
実際、多くの言語(PythonやJavaを含む)では、文字列のような組込み型は不変です。 James Gosling(Javaの作成者)は、「[Immutables]は、より多くの場合、問題を起こさない傾向がある」と述べています。
しかし、変数を一度ライトワンスにすることはできませんが、変数が少ない場所で変更された場合でも役立ちます。

キー・アイデア
変数が操作される場所が多いほど、現在の値を推論するのが難しくなります。
それではどうしますか? どのように変数を追記型に変更することができますか? さて、多くの場合、次の例のように、コードを少し再構成する必要があります。

参考文献:

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code (English Edition)

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code Kindle (English Edition)

カテゴリー
読みやすいコード

変数のスコープを縮める/Shrink the Scope of Your Variables

"グローバル変数を避ける"というアドバイスを聞いたことがあります。これは良いアドバイスです。グローバル変数がどこでどのように使用されているかを把握するのは難しいからです。 そして、 "名前空間を汚染する"(あなたのローカル変数と衝突する可能性のある名前の束を置く)ことによって、コードは、ローカル変数を使用しようとしているときにグローバル変数を誤って変更する可能性があります。
実際、グローバル変数だけでなく、すべての変数の「範囲を縮小する」ことは良い考えです。

多くのプログラミング言語は、モジュール、クラス、関数、ブロックスコープなど、複数のスコープ/アクセスレベルを提供します。 より制限されたアクセスを使用することは、コードの行数を減らして変数を「見える」ことができるという意味で一般的に優れています。
なぜこれを行うのですか? なぜなら、読者が同時に考えなければならない変数の数を効果的に減らすからです。 すべての変数の範囲を2倍に縮小した場合、平均して一度に範囲の半分の変数が存在します。
たとえば、次のように2つのメソッドだけで使用されるメンバ変数を使用して、非常に大きなクラスがあるとします。

class LargeClass { 
    string str_;
    void Method1() { 
        str_ = ...;
        Method2(); 
    }
    void Method2() { 
        // Uses str_
    }
    // Lots of other methods that don't use str_ ... 
};

ある意味では、クラスメンバ変数は、クラスの領域内の「ミニグローバル」のようなものです。 大規模なクラスの場合、特に、すべてのメンバー変数を追跡するのは難しく、どのメソッドがそれぞれを変更するのかが難しいです。 ミニグローバルの数が少ないほど良い。
この場合、str_をローカル変数に「降格」することは意味があります:

class LargeClass {
    void Method1() {
        string str = ...;
        Method2(str); 
    }
    void Method2(string str) { 
        // Uses str
    }
    // Now other methods can't see str. 
};

クラスメンバーへのアクセスを制限する別の方法は、可能な限り多くのメソッドを静的にすることです。 静的メソッドは、読者に「これらのコード行がこれらの変数から分離されている」ことを知らせるのに最適な方法です。
あるいは、大きなクラスを小さなクラスに分割する方法もあります。 このアプローチは、より小さいクラスが実際には互いに分離されている場合にのみ役立ちます。 お互いのメンバーにアクセスする2つのクラスを作成する場合、あなたは本当に何も達成していません。
大きなファイルを小さいファイルに分割するか、大きな関数を小さな関数に分割する場合も同じです。 そのための大きな動機は、データ(すなわち、変数)を分離することである。
しかし、異なる言語は、スコープを正確に構成するためのルールが異なります。 変数の範囲に関するもっと興味深い規則のほんのいくつかを指摘したいと思います。

ifステートメントスコープをC ++で、次のC ++コードがあるとします。

PaymentInfo* info = database.ReadPaymentInfo(); 
if (info) {
    cout << "User paid: " << info->amount() << endl; 
}
// Many more lines of code below ...

変数infoは残りの関数のスコープ内にとどまるので、これを読んでいる人
コードが情報を念頭に置いて、それが再び使用されるかどうかを疑問に思うかもしれません。
しかし、この場合、infoはif文の内部でのみ使用されます。 C ++では、実際には
条件式の情報:

if (PaymentInfo* info = database.ReadPaymentInfo()) { 
    cout << "User paid: " << info->amount() << endl;
}

今では、読者は情報が範囲外になった後、情報を簡単に忘れることができます。

JavaScriptでの「プライベート」変数の作成

1つの関数だけで使用される永続変数があるとします。

submitted = false; // Note: global variable
var submit_form = function (form_name) { 
    if (submitted) {
            return;  // don't double-submit the form
    }
    ...
    submitted = true;
};

提出されたようなグローバル変数は、このコードを読んでいる人に大きな心配を引き起こす可能性があります。 それはsubmit_form()がサブミットを使用する唯一の機能だとは思われますが、あなたは確かにそれを知ることができません。 実際、別のJavaScriptファイルでは、別の目的のためにsubmitという名前のグローバル変数を使用している可能性があります。
クロージャ内で送信されたラッピングによって、この問題を防ぐことができます。

var submit_form = (function () {
    var submitted = false; // Note: can only be accessed by the function below
    return function (form_name) { 
        if (submitted) {
            return;  // don't double-submit the form
        }
        ...
        submitted = true; 
    };
}());

最後の行のかっこに注意してください。匿名の外部関数はすぐに実行されますが、
内部関数を返します。
以前この技術を見たことがないなら、最初は奇妙に見えるかもしれません。 内部関数だけがアクセスできる「プライベート」スコープを作成するという効果があります。 今読者はどこに提出されたのか不思議に思う必要はありませんか? 同じ名前の他のグローバルと競合することを心配する必要があります。 (JavaScript:Douglas CrockfordのGood Parts [O'Reilly、2008]を参照してください)。

JavaScriptのグローバルスコープ

JavaScriptでは、変数定義(var x = 1ではなくx = 1など)からキーワードvarを省略すると、変数はグローバルスコープに配置され、すべてのJavaScriptファイルとブロックがグローバルスコープにアクセスできます。 次に例を示します。

 <script>
     var f = function () {
         // DANGER: 'i' is not declared with 'var'!
         for (i = 0; i < 10; i += 1) ... 
     };
     f();
 </script>

このコードは私を不注意にグローバルスコープに入れます。したがって、後のブロックでもそれを見ることができます:

<script>
    alert(i); // Alerts '10'. 'i' is a global variable!
</script>

多くのプログラマーはこのスコープルールを認識しておらず、この驚くべき動作は奇妙なバグを引き起こす可能性があります。 このバグは、2つの関数が同じ名前のローカル変数を作成しても、varを使うのを忘れたときによく見られます。 これらの機能は無意識のうちに「クロストーク」し、貧しいプログラマは自分のコンピュータが所有しているとか、RAMが悪いと結論づけることがあります。
JavaScriptの一般的なベストプラクティスは、varキーワード(var x = 1など)を使用して常に変数を定義することです。 この方法は、変数のスコープを、定義されている(最も内側の)関数に制限します。

PythonとJavaScriptでネストされたスコープはありません

C ++やJavaなどの言語では、if、for、tryなどの構造体内で定義された変数がそのブロックのネストされたスコープに限定されるブロックスコープがあります。

if (...) {
    int x = 1;
}
x++; // Compile-error! 'x' is undefined.

しかし、PythonやJavaScriptでは、ブロック内で定義された変数が関数全体に「流出」します。 たとえば、この完全に有効なPythonコードでexample_valueを使用していることに注意してください。

# No use of example_value up to this point.
if request:
    for value in request.values:
        if value > 0:
            example_value = value 
            break
for logger in debug.loggers: 
    logger.log("Example:", example_value)

このスコープルールは多くのプログラマーにとって驚くべきことですが、このようなコードは読みにくいです。 他の言語では、example_valueが最初に定義された場所を見つける方が簡単です。内部にある関数の「左端」に沿って見てください。
前の例もバグです。コードの最初の部分にexample_valueが設定されていない場合、2番目の部分で例外が発生します。 "NameError: 'example_value'が定義されていません。 これを修正し、コードをより読みやすくするために、 "最も近い共通の祖先"(入れ子にして)でexample_valueを使用する場所に定義します。

example_value = None
    
if request:
    for value in request.values:
        if value > 0: 
            example_value = value 
            break
if example_value:
    for logger in debug.loggers:
        logger.log("Example:", example_value)

ただし、これはexample_valueを完全に削除できる場合です。 example_valueは中間結果を保持しているだけで、「中級者を排除する」
95ページの「結果」を参照してください。これらの変数は、「できるだけ早くタスクを完了させる」ことで、しばしば排除できます。
新しいコードは次のようになります:

def LogExample(value):
    for logger in debug.loggers:
        logger.log("Example:", value)
if request:
    for value in request.values:
        if value > 0:
            LogExample(value)  # deal with 'value' immediately
            break

定義を下に移動する

元のCプログラミング言語では、すべての変数定義を関数またはブロックの先頭に置く必要がありました。 多くの変数を持つ長い関数では、あまり時間がかからずにすぐに使用されなくても、読者はこれらの変数についてすぐに考えるようになったため、この要件は残念でした。 (C99とC ++はこの要件を削除しました)。
次の例では、すべての変数が関数の先頭に無意味に定義されています。

def ViewFilteredReplies(original_id):
    filtered_replies = []
    root_message = Messages.objects.get(original_id) 
    all_replies = Messages.objects.select(root_id=original_id)
    root_message.view_count += 1
    root_message.last_view_time = datetime.datetime.now()
    root_message.save()
    for reply in all_replies:
        if reply.spam_votes <= MAX_SPAM_VOTES:
            filtered_replies.append(reply)
    return filtered_replies

このサンプルコードの問題点は、読者が3つの変数を一度に考え、それらの間でギアを切り替えることです。
読者は後でそれを知る必要はないので、最初の使用の直前に各定義を移動するのは簡単です。

ef ViewFilteredReplies(original_id):
   root_message = Messages.objects.get(original_id)
   root_message.view_count += 1
   root_message.last_view_time = datetime.datetime.now()
   root_message.save()
   all_replies = Messages.objects.select(root_id=original_id
   filtered_replies = []
   for reply in all_replies:
       if reply.spam_votes <= MAX_SPAM_VOTES:
           filtered_replies.append(reply)
   return filtered_replies

all_repliesが必要な変数であるのか、それとも排除できるのか不思議に思うかもしれません
行うことによって:

for reply in Messages.objects.select(root_id=original_id): 
...

この場合、all_repliesはかなり説明変数なので、私たちはそれを保つことに決めました。

参考文献:

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code (English Edition)

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code Kindle (English Edition)

カテゴリー
読みやすいコード

変数を削除する/Eliminating Variables

役に立たない一時変数

次のPythonコードのスニペットで、now変数を考えてみましょう:

now = datetime.datetime.now()
root_message.last_view_time = now

今は変える価値のある変数ですか? いいえ。理由は次のとおりです。
•複雑な表現を分解しているわけではありません。
•明示的な追加は行われません。式datetime.datetime.now()は十分明確です。
•一度だけ使用されるため、冗長コードは圧縮されません。

これまでになくても、コードはわかりやすくなりました。

root_message.last_view_time = datetime.datetime.now()

現在のような変数は、通常、コードが編集された後に残る「残り物」です。 変数は、元々複数の場所で使用されていた可能性があります。 あるいは、コーダーが複数回使用することを予期していたかもしれませんが、実際にはそれを必要としませんでした。

中間結果の削除

次に、配列から値を削除するJavaScript関数の例を示します。

var remove_one = function (array, value_to_remove) { 
    var index_to_remove = null;
    for (var i = 0; i < array.length; i += 1) {
        if (array[i] === value_to_remove) { 
            index_to_remove = i;
            break;
        } 
    }
    if (index_to_remove !== null) { 
        array.splice(index_to_remove, 1);
    }
};

変数index_to_removeは、中間結果を保持するために使用されます。 このような変数は、取得するとすぐに結果を処理することで、時には排除することができます。

var remove_one = function (array, value_to_remove) {
    for (var i = 0; i < array.length; i += 1) {
        if (array[i] === value_to_remove) {
            array.splice(i, 1);
            return;
        }
    }
};

コードを早期に返すことで、index_to_removeを完全になくして単純化しました
コードはかなりです。
一般的に、できるだけ早くタスクを完了することは良い戦略です。

制御フロー変数の削除

場合によっては、このコードパターンがループ内に表示されることがあります。

boolean done = false;
while (/* condition */ && !done) {
    ...
    if (...) {
        done = true;
        continue;
    }
}

完了した変数は、ループ全体の複数の場所でtrueに設定される場合もあります。
このようなコードは、しばしば、ループの途中から脱却すべきではない、暗黙のルールを満たすようにしています。 そのようなルールはありません!
doneのような変数は、「制御フロー変数」と呼ばれるものです。その唯一の目的はプログラムの実行を操作することです。実際のプログラムデータは含まれていません。 我々の経験では、構造化プログラミングをより有効に活用することで、制御フロー変数を削除することができます。

while (/* condition */) {
    ...
    if (...) {
        break;
    }
}

このケースはかなり簡単に修正できましたが、単純なブレークでは十分ではない複数のネストされたループがある場合はどうなりますか? このようなより複雑なケースでは、ソリューションはしばしば、コードを新しい関数(ループ内のコード、またはループ全体のコード)に移動する必要があります。

参考文献:

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code (English Edition)

The Art of Readable Code: Simple and Practical Techniques for Writing Better Code Kindle (English Edition)

カテゴリー
Python

変数、名前、オブジェクト

Pythonでは、すべて(ブール値、整数、文字列、浮動小数点、関数、プログラム等)がオブジェクトで実装されている

ミュータブル

データの値を変更できる

イミュータブル

データの値を変更できない

Pythonは、強く型付けされている。つまり、値がミュータブルでも。オブジェクトの型は変わらない。

変数は、値はコピーされない。値の参照である。データを入れているオブジェクトにポストイットのように名前を貼っているだけ。

Type()

変数やリテラルなどの型を調べる

pythonではクラスと型はまったく同じ意味になる

python2では、intは32ビット、longは64ビット

python3ではlongはない。intは任意のサイズ

浮動小数点 float

pythonの文字列はイミュータブル

カテゴリー
HTML/CSS

Bootstrapのブレークポイント

確認環境:

Bootstrap v4.6

Bootstrapとは

レスポンシブ対応のCSSのフレームワーク

モバイルファーストをコンセプトとしている

レスポンシブWebデザインとは

PCとかスマホとか画面サイズの違うデバイスでアクセスされたときでも対応できるようデザインしたサイト

Bootstrapのブレークポイント

ブレークポイントクラス識別子サイズ
X-Smallなし<576px
小さいsm≧576px
md≧768px
lg≧992px
特大xl≧1200px
特大特大xxl≧1400px

Bootstrapで2カラムサイトを作る

まず、以下の公式ページの通り、Bootstrapを使えるようにします。

Bootstrap イントロダクション

その後、以下のようにHTMLを記載します。

<div class="container">
    <div class="row">
        <section class="side col-md-4">
            <h2>サイドコンテンツ</h2> 
            <p>サイドコンテンツの内容</p>
            <h2>サイドリスト</h2>
            <ul>
                <li>メニュー</li>
                <li>メニュー</li>
                <li>メニュー</li>
                <li>メニュー</li>
            </ul>
        </section>
        <section class="main col-md-8">
            <h1>メインコンテンツ</h1>
            <div class="archive">
                <div>
                    <img src="no-image.gif" alt="no-img">
                    <p>見出しや文章</p>
                </div>
                <div>
                    <img src="no-image.gif" alt="no-img">
                    <p>見出しや文章</p>
                </div>
                <div>
                    <img src="no-image.gif" alt="no-img">
                    <p>見出しや文章</p>
                </div>
                <div>
                    <img src="no-image.gif" alt="no-img">
                    <p>見出しや文章</p>
                </div>
            </div>
        </section>
    </div>
</div>

こんな感じに2カラムで表示されます。

この例では、「col-md-8」でブレークポイントを設定しているので、

画面の幅が768pxより小さい場合以下のようにブレークされて表示されます。

まとめ

Bootstrapを使えば、2カラムサイトが簡単に作れます。

Bootstrapを使わないと、cssのdisplayとか、potisionプロパティとかいろいろ設定をしないといけないので手間がかかります。

参考サイト

Bootstrap Document(公式サイト)

Bootstrap Breakpoint

Bootstrap イントロダクション

カテゴリー
Laravel

Laravel ログ出力

確認環境:

Windows10、Laravel 7.30.4、PHP 7.2.33、MySQL 5.7.30

Laravelのログ出力の設定ファイル

config\logging.php

ログ出力レベル

8つのレベルがある。上のものほど重要度が高い。

Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);

参考サイト

Laravel 7.x ログ

RFC 5424規約

カテゴリー
Laravel

LaravelでGmail認証をする

確認環境:

Windows10、Laravel 7.30.4、PHP 7.2.33、MySQL 5.7.30、Gmail

多くのWebアプリケーションは、利用開始時にユーザーのメールアドレスを確認する必要がありますが、Laravelで、とても簡単にメール認証の機能が実装できます。

1) Loginページを作る

上記ページの手順でLoginページを作っておきます。

2) UserモデルにMustVerifyEmailインターフェースを追加する

app\User.php

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable;
    // ...
}

class User extends Authenticatable

の後ろに implements MustVerifyEmail
を追加する。

3)web.phpにルートパラメータを追加する

routes\web.php

Auth::routes(['verify' => true]);
  1. Loginページを作る でAuth::routes は自動で作られるので、引数に ['verify' => true] を追加する。

4) .envファイルにGmail用の設定をする。

MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=任意のGmailアドレス
MAIL_PASSWORD=下記参照
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=任意のGmailアドレス(MAIL_USERNAMEと同じアドレス)
MAIL_FROM_NAME="${APP_NAME}"

自分のGoogleアカウントのセキュリティでアプリパスワードを取得します。

注意点は、2段階認証を選択しておくことです。

取得したアプリパスワードを.envファイルの「MAIL_PASSWORD」に設定します。

5) サイトにアクセスし、新規にユーザー登録する。

ユーザー登録した後、登録時に指定したメールアドレス(Gmail)を確認します。

以下の認証メールが届いていることを確認します。

Verify Email Address ボタンを押すと、認証処理が行われ

/home画面にリダイレクトします。

これだけで、メール認証機能が作れます。すごいシンプルです。

参考サイト

Laravel 7.x 認証

Laravel 7.x メール確認

カテゴリー
Laravel

Laravel Bladeファイルの書き方

ベースのbladeファイル

app.blade.php

<!-- resources/views/layouts/app.blade.phpとして保存 -->

<html>
    <head>
        <title>アプリ名 - @yield('title')</title>
    </head>
    <body>
        @section('sidebar')
            ここがメインのサイドバー
        @show

        <div class="container">
            @yield('content')
        </div>
    </body>
</html>

子のbladeファイル

child.blade.php

<!-- resources/views/child.blade.phpとして保存 -->

@extends('layouts.app')

@section('title', 'Page Title')

@section('sidebar')
    @@parent

    <p>ここはメインのサイドバーに追加される</p>
@endsection

@section('content')
    <p>ここが本文のコンテンツ</p>
@endsection

参考サイト

Laravel 7.x Bladeテンプレート

カテゴリー
プログラミング

クラスとは

クラスとは

オブジェクト指向の中核となる概念

ほとんどのプログラミング言語でクラスを実装できる

クラスとインスタンス

お菓子のクッキーで例えると、クラスはクッキーの金型でインスタンスは金型を使って作った、クッキー

星型、ハート型、動物型のクラス(金型)を定義しておいて、

実際に使うときにはnewしてインスタンスを作る。

言語によってはインスタンスをオブジェクトとも言ったりする。

クラスはプロパティとメソッドを持つ

プロパティ(属性、データ)とも言う

メソッド(関数)とも言う

カプセル化(隠蔽化)

private、public

継承

オーバーロード

クラス変数、クラスメソッド

インスタンス変数、インスタンスメソッド

オーバーライド

インターフェイス(implements)、抽象クラス