著者アーカイブ 杉浦

著者:杉浦

SQLを試すwebサービスSQL Fiddle

 SQL Fiddleは様々なSQLを簡単に試せるオンラインサービスです。下図の様な画面で、任意のSQL環境を選び、テーブルを定義し、SQLを実行する、といったものです。
 
 左の赤丸は実行環境、右の赤丸はテキストからData Definition Languageへの変換機能です。下図の様に、ヘッダ、データを用意するとテーブル作成とそのテーブルにデータを入れる構文が出力されます。
 
 この図では半角スペースで区切っていますが、様々な区切り方に対応しています。詳しくはDDLBuilder/fixture.html at master · jakefeasel/DDLBuilder · GitHubを参照です。入力したデータはBrowserボタンから開くと見やすいです。
 データを入力したら、任意のSQLを右側に入れて実行、下側に出力される結果を見るだけです。

著者:杉浦

簡単な置換を簡単に書く

 置換と言えば正規表現ですが、正規表現の処理は複雑です。複雑さ同様、正規表現による置換は往々にして純粋な文字列のみの置換より重くなりがちです。PHP: str_replace – Manual にも

(正規表現のような) 技巧的な置換ルールを必要としない場合、 preg_replace() の代わりにこの関数を常用するべきです。

とあります。
 この技巧的な置換ルールを必要としない置換でよく行いたい置換は、AをB,CをDに置き換える、といった1対1の置換です。複数の置換の記述例は次の通りです。

$str = '置換対象';
$arr = [
	'置換' => 'ちかん',
	'対象' => 'taisyou'
];
$str_replaced = str_replace( array_keys($arr), array_values($arr), $str);

 上の書き方で$str中の’置換’を’ちかん’、対象を’taisyou’に置き換えた$str_replacedができあがります。
 str_replace,preg_replaceは引数の置き換え対象のパターン、置き換え後の語に配列を指定できます。またarray_keysは引数の配列のキーを格納した配列を、array_valuesは引数の配列の値を、配列にして返します。これらを組み合わせることで、置換対象と置換後の文字列を一つの配列内に格納できます。延々と同じ変数を対象にreplaceを繰り返すよりすっきりします。
 実行速度もこちらの書き方の方が高速です。私の環境では、aをaaに置換するという動作を’a’に対して100000回繰り返す動作にかかる実行時間はstr_replaceの重ね書きがおおよそ1*1e-3秒、上記の書き方が7*1e-6秒でした。雑な計り方ですが、ここまで極端な差があるので高速と言っていいでしょう。
 余談な上、勘ですがこの速度差はおそらく関数呼び出しによるオーバーヘッドです。計算コストの異なりそうな違いはstr_replaceの呼び出し回数、文字列変数をどこに保存するかの扱い、あたりにあります。

著者:杉浦

タスク管理ツールtrelloとその拡張

 trelloは視覚的なタスク管理ツールです。画面の様にボード、リスト、カードを増やし、タスクが完了したら画面からどかす、という動作を繰り返すのが基本の使い方になります。
増やす、どかすはマウスのドラッグや簡単なキーボード操作ででき、扱いやすいです。

 このままでも便利なのですが、多くのカードを扱おうとするとデフォルトの設定では問題があります。上の画像はリストが折り返されていますが、デフォルトでは折り返されておらず、リストを増やすと延々と横に伸びていきます。List Layouts for Trelloは上の画像の様な折り返しを追加するChrome拡張ツールです。主にflex、flex-wrap、overflowあたりのStyleを自動で弄ってくれます。
 また、なにかからデータを移行する際には視覚的にわかりやすいことよりも簡単に入力できる事が優先されます。ここでいう移行はcsvからexcelシートに移すぐらいの気楽な移行です。Trello DevelopersにはTrelloのAPIに関する情報が詰まっています。もちろんこのAPIからカードの作成もできます。
 APIの使い方はリファレンスが非常に親切です。
 前準備としてhttps://trello.com/1/appKey/generateでキー、https://trello.com/1/authorize?key=<前述のキー>&name=&expiration=never&response_type=token&scope=read,writeでトークンを取得します。
 GETにkey=<取得したKey>&token=<取得したToken>を追加してリファレンスの通り使うだけです。このリファレンスは次の画像の様にパラメータを入れた場合、投げるべきコードを自動で生成してくれます。数行で済むAPIならではですがとても使いやすいです。

 このリファレンスを参考に文字列生成、パラメータあてはめ、送信の繰り返し処理を書くだけで簡単にデータの移行が出来ました。

著者:杉浦

国土地理院のハザードマップ

重ねるハザードマップ | 国土交通省
 ページのtitleは国土交通省ですし、国土地理院のトップページのみならず国土交通省のトップページからも簡単に遷移できますがが、ドメインとしては国土地理院のページです。国土地理院は国土交通省の一部ですのでおそらくその辺りでしょう。
 主な使い方は簡単です。左上の災害種別で災害毎の影響範囲のまとめを地図上に写して見る、右上の危険虫眼鏡で調べたい場所をクリックしてその場所のリスクを見る、これだけです。
 
 詳しくどういう情報から知りたい時はレイヤー情報の解説ボタンから詳しい解説が開きます。また作図、保存、印刷機能も備えており、メモ書き等含めて目的に合わせた地図を柔軟に作れます。

著者:杉浦

assertで想定外の動作のみを検知する

 デバッグを行う際、プログラム中の変数、式を追うことになります。この変数や式を全て画面に出力すると読む対象が多すぎてとても分かりにくいです。また徐々に異常な結果を辿って、変数や式をその都度画面に出力する場合、実行回数がかさみ時間がかかってしまいます。assert文は異常を発見した時にのみ知りたい変数や式を出力させるための文です。またこのassert文はユーザに見せる本番環境の際には消えている必要があります。assert文の実行は実行速度の低下であり、assert文の出力は脆弱性の発見のきっかけにもなります。
 大体のassert文はassert(条件文,出力定義の色々)という呼び出され方をします。条件文の評価結果がtrueの場合、出力はされず、falseの場合、出力がされます。assert(想定の動作の際の条件文, Errorの際に知ると役に立つであろう値)と書くと想定外の動作を整った情報と共に検出し、早く修正できます。かくあるべし、と意味を書く際のコメントの代わりにもなります。
Console.assert() – Web API インターフェイス | MDN
 javascriptのassetは次の様に使えます。

console.assert(条件式,出力したいものA,出力したいものB,出力したいものC,...)

 出力は次の画像のconsole.log(出力したいもの)と同じ様に表示されます。  javascritptでは外部でどうにかすることでassertを見せないようにします。一つは力技の様な気がしますが

Object.keys(console).forEach(key => {console[key] = () => {}})

の実行です。これによってブラウザの持つconsoleオブジェクトの持つ要素を全て空の関数で埋めます。これならば結果は表示せず、実行速度の面でもconsoleなしより少々遅いぐらいで済みます。ただしユーザはconsoleを使うためにconsoleの再定義が必要になり、また再定義された場合、consoleの中身が表示されてしまいます。もう一つはbabel-plugin-transform-remove-console – npmをつけたbabelのようなconsoleを除去するコンパイラを通すことによってコード内からassert文を消すことです。javascriptの実行コードはユーザがダウンロードするファイルです。そのため高速化を目的にソースコードを結合、圧縮します。その時にまとめてassertの除去を実行することで手間を意識せずassertを消せます。

PHP: assert – Manual
 PHPのassertは7前後で異なっています。PHP7では次のように簡単に書けます。

<?php
$a = 2;
$b = 1;
// assertionを作成
assert($a < $b);
assert($b < $a, '$b is less than $a.$a:'.$a.' $b:'.$b);
assert($a < $b, '$a is less than $b.$a:'.$a.' $b:'.$b);

実行結果

<br />
<b>Warning</b>:  assert(): assert($a &lt; $b) failed in <b>[...][...]</b> on line <b>5</b><br />
<br />
<b>Warning</b>:  assert(): $a is less than $b.$a:2 $b:1 failed in <b>[...][...]</b> on line <b>7</b><br />

 assert(条件式,出力文字列)とするだけです。出力文字列とassert文を記述した行数を出力してくれます。出力文字列を指定しない場合はfalseを出力した条件文を出力します。
 PHP7より前のバージョンではコールバックの指定が必要であり少々面倒です。

<?php
// assertを有効にし、出力を抑制する
assert_options(ASSERT_ACTIVE, 1);//assert()による評価を有効にする。0でassert()を読み飛ばす。
assert_options(ASSERT_WARNING, 0);
assert_options(ASSERT_QUIET_EVAL, 1);

// ハンドラ関数を作成する
function my_assert_handler($file, $line, $code, $desc = null)
{
    echo "Assertion failed at $file:$line: $code";
    if ($desc) {
        echo ": $desc";
    }
    echo "\n";
}

// コールバックを設定する
assert_options(ASSERT_CALLBACK, 'my_assert_handler');

// 失敗するassertionを作成
assert('2 < 1');
assert('2 < 1', 'Two is less than one');

実行結果

Assertion failed at [...][...]:21: 2 < 1
Assertion failed at [...][...]:22: 2 < 1: Two is less than one

 PHP7より前では必ず評価を行った状態を引数にしたコールバックを呼び出します。これが手間で昔のassert文はあまり使われなかったらしいです。PHP7はコールバック呼び出しも可能なまま、容易に使えるasset文になりました。
 PHPはオプションで宣言することによってassert文を読み飛ばします。PHP7ではphp.ini中にzend.assertions=-1とすることでassert文を読み飛ばせます。PHP7より前ではassert_options(ASSERT_ACTIVE, 0);とすることでassertによる評価を無効にします。

著者:杉浦

高速化のために一度の小さな問い合わせで済むSQL文を作る

 プログラムを扱っているとDB(データベース)に接続する必要のある場面がいくつもあります。DBへのアクセスにかかる時間、実行にかかる時間は無視出来ず、実行速度のボトルネックになることがあります。DBの内部をチューニングする事でも速度の向上はできますが、問い合わせの回数、DBから引っ張ってくるデータの大きさといった部分を問い合わせ文の工夫によって少なく、小さくすることによっても高速化はできます。
 よくある場面は、必要なデータが複数のテーブルに分散している、あるテーブル中に格納されたデータを基にした条件に合致するデータのみを取得したい、といったものです。こういった時、それぞれのテーブルをそのまま扱うようなことをすると次の様なコードが生まれます。

$arr = query('SELECT * FROM master_table');
foreach($arr as $v){
	$hoge_addr = query("SELECT * FROM hoge_table WHERE addr = '${arr['addr']}'");
	...
	...
}

 こういった何度も問い合わせをDBに送る様なコードは実行にかかる時間が長くなりがちです。DBへの問い合わせは少ない回数で少ないデータをとれるようにした方がプログラムは高速になります。必要最小限のデータの取得は*を使わずに細かく指定することでできます。問い合わせを少ない回数で行うためにはAS、JOIN、入れ子内部のSELECTが便利です。

SELECT * FROM(
	SELECT
		master_table.id,
		master_table.name,
		hoge_addr.name AS name1,
		hoge_addr2.name AS name2,
		fuga_table.name
	FROM
		master_table
		INNER JOIN
			hoge_table AS hoge_addr
		ON  master_table.addr = hoge_addr.addr
		INNER JOIN
			hoge_table AS hoge_addr2
		ON  master_table.addr2 = hoge_addr.addr
		INNER JOIN
			fuga_table
		ON  master_table.branch = fuga_table.id
) AS tmptable
WHERE
	name1 = 'hogehoge'

 SELECTの結果はそのままテーブルとして扱うことが出来ます。ここではそうまとめの様に扱っていますがWHERE句中に使うこともできます。

WHERE id IN (SELECT hoge_id FROM hoge_table WHERE hogehoge = 'fugafuga')

とすればINにより()内の結果であるhoge_idのいずれかと一致するIDという条件を作れます。
 JOINは表の結合です。オプションは様々でINNER以外も多く使われます。ASはそのままA as BでAをBとして扱うという句です。JOINとASを組み合わせることで同じ表から違う条件で汲み上げた結果を一つの表にまとめられます。

master_table
INNER JOIN
	hoge_table AS hoge_addr
ON  master_table.addr = hoge_addr.addr
INNER JOIN
	hoge_table AS hoge_addr2
ON  master_table.addr2 = hoge_addr.addr
著者:杉浦

開発環境に応じたgitignoreのプリセットをくれるgitignore.ioの紹介

gitignore.io – Create Useful .gitignore Files For Your Project
 gitignore.ioはソースコード等のバージョン管理ツールであるgitの設定ファイルである.gitignoreファイルのプリセットを作成できるサービスです。.gitignoreは.gitignore内に記述された条件に適合するファイルをgitの追跡対象い登録しない設定を行うファイルです。他人のエディタの設定がgitに紛れ込むと無駄なデータ増えます。もし、同じエディタで異なる設定を使っていた場合、しっちゃかめっちゃかです。
 gitignore.ioでは下の画像の様に自分の開発環境、フレームワーク等を指定してCreateボタンを押すことで.gitignoreの中身が作られます。

 Createボタンを押すと下の画像の様に各環境の設定ファイル等を羅列したテキストが出力されます。この中身をコピペした.gitignoreを作成することで.gitignoreに記述するべき大部分を楽に書けます。

著者:杉浦

オーバーヘッドと高速化

 プログラミングの世界においてオーバーヘッドは大体、何かをしようとした時に引っ付いてくる負荷のことを言います。例えば、プロセスにはプロセス自体の処理のみならず起動終了処理が必要です。この場合、起動終了処理がオーバーヘッドと呼ばれます。
 何かを繰り返し実行することで目的を実現する場合、繰り返し実行されるもののオーバーヘッドが大きい場合、オーバーヘッドの積み重なりにより全体の実行完了までの時間は長くなります。このような時、オーバーヘッドを必要としない手法を考える事で高速化を実現することがあります。
 例えば、多数の小さなプログラムによって大きな目的を達成しようとする時です。このような時、多数のプログラムを起動すること、終了することがオーバーヘッドになり、オーバーヘッドの積み重なりによって実行完了までの時間が長くなります。高速化は多数のプログラムを動作させるのではなく、大きな一つのプログラムにまとめることによって実現できます。
 他にはwebページの生成処理や通信の必要な処理です。ブラウザはウィンドウのルートのDOMの要素が変更されるたびに描画処理を実行します。webページの生成の際にはDOMの操作を抑えるか、一斉に行うことによって描画処理の実行を抑えることによって実行時間を短縮します。通信はデータが行って帰ってくるだけで通信資源を食べます。宛先等の情報を組み込んだヘッダの生成、やり取りが大きなオーバーヘッドです。何度も通信するのでなく、一度の通信で大きくやり取りを行うと実行完了までの時間が短くなります。

著者:杉浦

m個の文字列の内、n個以上の別々の文字列を含む行を検索する正規表現

 例えばmagickかconvertかcropかrtkを3つ以上含む行を検索する正規表現は次になります。

^.*(magick|convert|crop|rtk)(?!.*\1).*(magick|convert|crop|rtk)(?!.*(?:\1|\2)).*(magick|convert|crop|rtk).*


 後方参照によって既に選ばれた文字列を除外する、というのがこの正規表現の考えです。.*(magick|convert|crop|rtk)でキーワードが出るまで読み、(?!.*\1)で既に読んだキーワードを弾く、というのを繰り返します。ワンパターンの繰り返しですので、この構文をつくるプログラムを作ったりなんかすると楽です。次はjavascriptのサンプルです。


p = '(magick|convert|crop|rtk)'
r = '^'
for(i = 1; i < 3; i++){
    r = r + '.*'+ p + '(?!.*(?:\\1'
    for(j = 2; j <= i; j++){
        r = r + '|' + '\\' + j
    }
    r = r + '))'
}
r = r + '.*'
著者:杉浦

php用パッケージマネージャcomposer

   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/

 ComposerはPHPのパッケージ管理ツールです。必要なライブラリやフレームワークをまとめます。またphp向けのアプリケーションを管理する事もしてくれます。使っていてphp版npmみたいに思っていましたが、製作者はnpmに強い影響を受けたとあります。納得。
 パッケージのリポジトリはPackagistです。ここと雑多な記事のおすすめで目的に合ったもの、欲しいものを探します。
 フレームワークならLaravel、テスト用環境ならphpunitあたりが高評価なようです。