OmniAICreator/Qiita-1.07M huggingface dataset:
Python Pyramidのトラバーサルについて

今更ながらPythonのWebフレームワークPyramidを触ってみた。
この記事は、「インストールしてみたｗｗｗ」的な初歩の初歩は省き、「じゃあ実際に実装するときどうするの」とか、引っかかりそうなところに焦点を当てた備忘録である。


# トラバーサル(Traversal)
Pyramidには、おなじみURLディスパッチの他にTraversal（トラバーサル）というURLマッピング方法がある。

トラバーサルについては、本家英語サイトの説明では概念的なことしか記載していないし、広大なネット上を調べてみても、数件の記載はあるがそれぞれどうやら解釈（？）が違うようで実装方法が違う。

しかし、アクセスコントロールを実装するためには、本家サイトの例にもあるようにトラバーサル使わないといけないという仕様らしく、PyramidでWebサイトを作る以上、ここを避けては通れない。

### トラバーサルの概念とPythonの辞書
本家にトラバーサルの概念については記載があるため詳しい説明は省くが、簡単に言うと、URLの各要素を入れ子になったPythonの辞書のキー値に見立て、最後に残ったキーをビュー名、最後にヒットした要素をコンテキスト（操作対象）とするURLマッピングの方法である。

たとえば、あるサイトのアカウント'testuser'のユーザ情報なんかを編集するためのURLが"http://example.com/account/testuser/edit" となっていた場合、トラバーサルでは

- ``` Root['account']['testuser'] ```で得られる要素がリソース
- ```edit```がビュー名

となる。
上のRootとは便宜上記述したものであるが、実際にはトラバーサルの開始要素で、ユーザーからのリクエストがあるたびに生成されるリソースである。誤謬があるが、http://example.com がこのサイトのrootリソースと言っても良い。

適当に要約すると上記のように書いてあるが、すぐ壁にぶち当たる。

### トラバーサルを使ったユーザアカウントの実装
上述した内容は、既に本家サイトに（英文だが）記載がある。
本家サイトを鵜呑みにすると、ユーザアカウント関係のリソースの実装としては以下の様になるだろう。

```python
def site_root_factory(request):
    root = dict()
    root['account'] = dict()
    root['account']['testuser'] = request.dbsession.Query(User).filter(name = 'testuser').first()
```

アタリマエのことだが、こんなもんで実装だと言えるわけがない。
固定的なサイトならまだしも、ユーザアカウントは、’登録’/'削除'ができることが当然で、１つとは限らない、例えば'foouser'が追加された場合はどうするのだろうか？

つまり、トラバーサルで動的なWebサイトを作成しようとするなら、リソースを単なるPythonの辞書とその要素として実装するだけでは実現できないのである。

### リソースクラスによる実装方法
リソースとは単なる'辞書```dict()'```ではなく、```__getitem__``` メソッドを実装したクラス/オブジェクトのことである。このことが書いてないと初心者には厳しい。
```__getitem__```ってなに？ という人はPython本家のドキュメントを読んでいない証拠なので、今すぐ読んだほうが良い。

上述した例を用いると、キー'account'で得られる要素は```__getitem__```を実装した以下のような ```AccountFactory```クラスとして実装することができる。

```python
class AccountResource(object):
    def __init__(self, parent, request, model):
         self.request = request
         self.model = model
         self.parent = parent

    @property
    def __name__(self):
         return self.model.name

    @property
    def __parent__(self):
         return self.parent


class AccountFactory(object):
    def __init__(self, parent, request):
         self.request = request
         self.parent  = parent

    @property
    def __name__(self):
         return 'account'

    @property
    def __parent__(self):
         return self.parent

    def __getitem__(self, key):
         m = self.request.dbsession.Query(User).filter(name = key).first()
         if m: 
             reurn m
         else: 
             raise KeyError(key)


def site_root_factory(request):
    root = dict()
    root['account'] = AccountFactory(root, request)
```

これで、```root['account']['testuser']```が呼び出されたときには、```AccountFactory```の```__getitem__```メソッドが```key='testuser'```で呼び出され、```User```モデルが最終的なコンテキストとして呼び出されるようになる。

このコンテキスト(Userモデル)を操作するeditビューを定義するには、たとえば以下のようになるだろう。

```python
@view_config(name='edit', context='User', renderer='editview.jinja2')
def edit(context, request)
    # contextはトラバーサルの結果得られたUserモデルである
    # 以下にUserモデルを操作する処理を記載する
```

何故か、上記例のようにDBアクセスが発生する際のトラバーサルの例がなかったため、ここに記載しておく。

# 状況
日本語の文献は殆ど無い。お察しである。

あってもお決まりのPyramidのインストールと「起動しました！」の記事。
pipでスパッとインストールできる時代にココらへんのことしかないってのはどうなんだろう。
思うんだけど、本家サイトに書いてあるようなインストールの方法記事にしてどうするんだろう。
実績として残す。

金額を入力すると税込みの金額を教えてくれるプログラム。

```tax.py
def zeikomi():
    number = int(input("計算したい金額を入力してください"))
    tax = 0.08
    sum = int(round((number * tax)+number))
    print("税込み金額は"+str(sum)+"円です")
    return sum
    
zeikomi()

while True:
    x = int(input("計算する場合は１,終わる場合は2をおしてください"))
    if x == 1:
        zeikomi()
    elif x == 2:
        break
    else:
        print("入力が不正です")
        continue
```

少し前に簡単なもの何でもいいからつくれないかな？とおもって作ったやつ。
ループ処理が上手くいかなかったりで、いろいろ試行錯誤してやっと機能するようになったので。
(結果としてwhile使えばいいだけでしたｗ←)

もし、この記事見てくれてて、**ここはこうした方が良いよ**等があれば教えてくださると助かります。

一応自分のPCにもファイルは残してあるのですが、まだこれくらいのしか作れないけど**実績としてどこまでできるのか**って目安になればいいなとおもい公開しました！
PowerShell| Start-Job の InitializationScript へ引数を複数渡す


今回の問題のソースは下記です。

# 期待通りに動作しないソース
```ps1
$functions = {
  function Output-Message {
    param (
      [string]$message,
      [string]$name
    )
    sleep 5
    echo "$message : $name"
  }
}

$job = Start-Job -InitializationScript $functions -ScriptBlock {
  param (
  	[string]$m,
  	[string]$n
  )
  Output-Message $m, $n
} -ArgumentList "Hello World", "kirishima"

# 待機後に結果出力
Wait-Job $job
Write-Host (Receive-Job -Job $job)
Remove-Job $job
```

`Start-Job`はグローバルスコープでも変数を渡せません。ですので、`-ArgumentList` で引数を渡します。

上記のスクリプトは`Hello World : kirishima`と出力されてほしいのですが、`Hello World kirishima :`と出力されます。~~どうやら、第1引数へ空白区切りで値が代入されているようです。第2引数へ渡す方法は調べた限りありませんでした。~~
(2017/3/28 追記)ありました、と言うか初心者がつまずく初歩的なミスでした。

# 解決編
引数を1つしか渡せないので、Hashtable として渡せば今回は問題を解決できそうです。修正版が下記になります。

```ps1
$functions = {
  function Output-Message {
    param (
      [hashtable]$data                                 # 変更点1
    )
    sleep 5
    $output = $data["message"] + " : " + $data["name"] # 変更点2
    echo $output                                       # 変更点3
  }
}

$job = Start-Job -InitializationScript $functions -ScriptBlock {
  param (
  	[string]$m,
  	[string]$n
  )
  Output-Message @{message = $m; name = $n} # 変更点4
} -ArgumentList "Hello World", "kirishima"

# 待機後に結果出力
Wait-Job $job
Write-Host (Receive-Job -Job $job)
Remove-Job $job
```

後から気付きましたが、`split` で分割する方法もあります。ただ、HashTableで渡したほうが、変数的でわかりやすいので :o: です。

# そもそもこちらが正解(2017/3/28 追加)
原因は、`Output-Message`を呼び出す際にカンマ区切りで指定していたことでした。Shellであることを忘れてどこぞの言語と勘違いしてました:cry:

```ps1
$functions = {
  function Output-Message {
    param (
      [string]$message,
      [string]$name
    )
    sleep 5
    echo "$message : $name"
  }
}

$job = Start-Job -InitializationScript $functions -ScriptBlock {
  param (
    [string]$m,
    [string]$n
  )
  Output-Message $m $n # 変更点
} -ArgumentList "Hello World", "kirishima"

# 待機後に結果出力
Wait-Job $job
Write-Host (Receive-Job -Job $job)
Remove-Job $job
```

# 参考
- [[PowerShell]Start-Jobで共通の関数を使う](http://qiita.com/Kamo123/items/940910502671d1c195da)
- [PowerShell 実践 ジョブ 2](http://www.sakutyuu.com/technology/?p=188)
- [PowerShell連想配列(ハッシュ)](http://capm-network.com/?tag=PowerShell%E9%80%A3%E6%83%B3%E9%85%8D%E5%88%97(%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5))
iOS Safari の Preload Top Hit 機能

## Preload Top Hit 機能とは
iOS Safari は `Preload Top Hit` という機能がデフォルトで有効になっています。
トップヒットと言うのは、URL入力欄に文字を入力している時、以前アクセスしたことのあるウェブサイトから候補を挙げてくれる機能です。
`Preload Top Hit` 機能が有効になっていると、このトップヒットがサジェストされた瞬間に、該当のウェブサイトにGETリクエストが発生します。
これからアクセスするであろうウェブサイトを予測し、ロードしておくことでユーザー体験を向上しようということでしょう。

## 利用者にとっては一長一短
しかしこの `Preload Top Hit` 機能は、ご丁寧に(恐らく全ての)リソースのダウンロードを発生させます。
ユーザーは体感的にブラウジング速度が向上しているように感じるかもしれませんが、あくまで予測なので無駄な通信が発生しかねないとも言えます。
もし通信量が気になっている、あるいはSafariが重いと感じている方は、設定をOFFにしたほうがいいかもしれません。

## 具体的な挙動例
一文字入力するごとに履歴から候補が選ばれ、通信が発生します。

- `http://` まで入力
  - `http://www.google.com/` に通信が発生
- `http://www.y` まで入力
  - `http://www.yahoo.co.jp/` に通信が発生
- `http://www.yo` まで入力
  - `http://www.youtube.com/` に通信が発生
- `http://www.yod` まで入力
  - `http://www.yodobashi.com/` に通信が発生
- ...

## JavaScript が実行される
なんとこの機能、JavaScript の実行まで行っているようです。
即時実行で XHR 通信する JavaScript を配置した所、サーバーへリクエストが発生しました。
さらにトップヒット候補が変化すると `pagehide` イベントが発火しました。
こちらも `pagehide` のイベントハンドラでXHR通信するコードを配置した所、サーバーへリクエストが発生しました。
(ちなみに `window.alert()` を配置してみましたが、こちらは実行されませんでした。)

## 何が問題となるか
実際にはユーザーはページを見ていないにも関わらず、サーバーへは普通のリクエストが発生します。
利用者にとっては上述のように意図しない通信が生じる点が問題になりえますが、どちらかと言うとサイト管理者にデメリットが有り、ページのアクセス解析を行っていたり、広告のインプレッション数などを計測している場合、ノイズになっている可能性が考えられます。
通信を見た限りでは、このプリロードは通常のアクセスと識別することが出来なさそうなので、判定は諦めるしかなさそうです。（強いて頑張るならばスクロールやタップ操作のイベント監視などすれば不可能ではなさそうですが・・・）
URLを手動入力するという機会は、お気に入りやリンクによってブラウジングする回数よりは恐らく少ないでしょうから大問題にはならないかと思いますが、こういったノイズが発生しうるという点は留意しておいたほうが良さそうです。
Apache 2.4 on Ubuntu 16.04でSSL

久しぶりにApacheをインストールしました。設定ファイルがディレクトリ毎に色々と分かれていたり、設定用のコマンドがあったりして、ちょっと戸惑いましたが、Let's Encryptの証明書でSSL化するまでの手順です。

# インストール

```
# apt-get install apache2
# a2enmod ssl
# vi /etc/apache2/sites-available/default-ssl.conf
        ServerAdmin xxx@yyy.zzz <- 変更
        ServerName xxx.yyy.zzz <- 追加
        DocumentRoot /var/www/html
# a2ensite default-ssl
# service apache2 reload
```

これだけで、sslモジュールが有効になり、とりあえずSSLでアクセスできるようにはなる。あとは、ルータの設定をして、外からhttps\://xxx.yyy.zzzに接続できるようにしておく。

# Let's EncryptでSSL証明書を取得

Let's EncryptでSSL証明書を発行するためには、Certbotクライアントが必要。Apache用のプラグインもインストールする。

```
# apt-get install letsencrypt python-letsencrypt-apache
# letsencrypt run --apache
```
Ubuntu用のaptパッケージ名は、certbotではなく、まだ古い名前のletsencryptのまま。このコマンドを使うと、一発でApacheの設定まで可能。
ただ、Please choose whether HTTPS access is required or optional.でSecureを選ぶとRedirectの設定がエラーになってしまった（たぶん最新版のcertbotでは[直っている] (https://github.com/certbot/certbot/issues/1243)）ので、Easyを選んで、Redirectの設定はあとで手動で行う。

```
# vi /etc/apache2/sites-available/000-default.conf
        Redirect "/" "https://xxx.yyy.zzz/" <- 追加
</VirtualHost>
# service apache2 reload
```

これで終了。ブラウザからアクセスして証明書のエラーが出なくなればOK。

## 証明書の更新

証明書の有効期限が近づいてきたというメールが来ましたので、更新しました。コマンド一発。

```
# letsencrypt renew
```

Let's Encryptの証明書は有効期間は90日間なので、3ヶ月一度更新する必要があります。
小ネタ)すべてのSalesforceオブジェクトにName項目はない

# 概要

　不特定多数のオブジェクトを対象としたアプリケーションを開発する際に、すべてのオブジェクトにName項目があると思って、ソースコードにNameをベタ書きするとNGです。残念ながらすべてのオブジェクトに**Name項目はない**です！
なので、DescribeからName項目ないオブジェクトリストを作成して、それと突き合わせることが安全策です

# Name項目がない代表的なオブジェクト

契約やケースといったよく使うオブジェクトにもName項目はないんです

| オブジェクト名      |        |
|:-----------------|------------------:|
| 契約             |          Contract |
| ケース           |              Case |
| ソリューション    |          Solution |
| ToDo             |              Task |
| 行動             |             Event |
| アイデア          |             Idea |

## 確認方法

DescribeからName項目の有無を確認する

※下記のサンプルコードでクエリ可能か、アクセス可能かなどの条件を追加していますが、必要に応じて変更して実行してください

```
Map<String, Schema.SObjectType> gs = Schema.getGlobalDescribe();
for(String objectName : gs.keySet()) {
    Schema.DescribeSObjectResult schemaSobj = gs.get(objectName).getDescribe();
    if(schemaSobj.isQueryable() &&
       schemaSobj.isAccessible() &&
       schemaSobj.isUpdateable() &&
       (schemaSobj.isSearchable() || schemaSobj.isCustom()) &&
       !schemaSobj.isDeprecatedAndHidden() &&
       !schemaSobj.isCustomSetting()) {
        Map<String, Schema.SObjectField> gf = gs.get(objectName).getDescribe().fields.getMap();
           if(!gf.containsKey('Name')) {
               // Name項目を待たないオブジェクト名が表示されます
               system.debug(objectName);               
           }

       }
}
```
1DAYゲームジャムでの時間配分

#最近流行りの1DAYゲームジャム

1DAYゲームジャム
良いところ：参加しやすい
悪いところ：時間が無い

とにかく時間が足りないのです。
何度か失敗を重ねて、なにより時間配分が重要な気がしてきました。

#セイシュン☆ゲームジャム

昨日は、「[セイシュン☆ゲームジャム](https://t.co/T6odDioAjX)」という1DAYゲームジャムに参加してきました。
すごい面白い「世にはでなさそうな」ゲームがいくつも誕生していました。
発表時の動画（1:36〜）：
https://youtu.be/474aZb2ltDc?t=5765

３人のチームになった。
プログラマ、デザイナ、サウンド（自分）。

「RPGとSTGと学園モノ卒業編」
というタイトルのゲームで
いろいろ盛り込みまくり。
（ゲームジャムではアカンタイプ。でも初めての人たちなので期待もしつつ静観してたのだったが・・・）
## ゲーム画面はないですが音楽だけでも
[RPGとSTGの学園モノ卒業編](https://soundcloud.com/tatmos/rpgstg)

##デザイナ、サウンドの時間配分

設計、作業、提出に時間配分を考える。

全体で10時間で作ると決めたら、
素材を出す側のデザイナやサウンドは、ゲームに組み込まれる時間を想定して、
少し短めに提出期限を設ける。

当初は、サウンドは16:00、17:00くらいにできていれば。という見積もり。

#サウンドの時間配分
自分の場合、まず、プロトタイプとして、
ジャンルにもよりますが、とりあえず、リズムループでもなんでもいいので、
長さ、テンポのわかるものをとりあえず用意します。

名前と、演出のどの場面で使われるかを想像し、
おおまかに、BGM、SE、ジングルとわけて素材を用意します。
今回はwav波形で、ファイル名でわかるようにしていました。

![image](https://qiita-image-store.s3.amazonaws.com/0/96808/a3439513-1300-a6c3-cdec-07e14a3ba6d7.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/96808/f7a5f0c8-7ed5-1ae3-1117-5bbd0d55e060.png)


仮でもいいので、プログラムに音を鳴らす部分を入れてもらうほうが心配が少なくてすみます。

プログラムも呼び出す部分だけとりあえず作ってもらえば、鳴り方が変とかに早めに気がつきやすくなります。
（例：BGMが重なってしまうとか、場面展開の時間と音の尺があってないとか）

#プログラマの時間配分

プログラマにとっての提出は、リリースのタイミングと考えてしまいがちです。

1人で開発しているプログラマなら、ギリギリまで調整してしまう。

#プログラマにかかる負担

![image](https://qiita-image-store.s3.amazonaws.com/0/96808/cf15091e-d9be-a62d-9ea1-cee69909ecf7.png)

- つづけてプログラムし続ける疲労が重なる。

- いくら糖分をとっても眠気が襲う。

- 何をしているのかわからなくなる。


プログラマは自分のコードと戦い、さらに素材をマージしていくという。

このうえさらに新しい演出の要求を迫るといった
ゲームジャムではプログラマが陥りがちな状況になった。

なんとか助けてあげたい気持ちになった。

今回はサウンドやデザイナは素材作成後、応援するしかった。
手伝えることはない。

#うっとりモード
ゲームでもサウンドでも絵でもモデルでもなんでも「もの」を作る。

今回のゲームジャムはみんな「もの」が作れる人が集まっていた。

一人で「もの」を作っていると、そのうちに自分と対話しはじめる。

いわゆる「うっとりモード」

「もの」作る人ってサボっているように見える時があるけど、
作業時間に「自分との対話時間」があって、さぼっているわけではない。
本当にさぼっていたら、作ったものとの対話時間が足りなくなる。
（なので、暇そうだからと仕事を割り当てるとクオリティが下がります）

うっとりすることで、何をするべきかが明確になる。
脳が次の作業を把握でき、効率がよくなる。

これも開発時間に組み込むと良いのでは。

![image](https://qiita-image-store.s3.amazonaws.com/0/96808/5d57ef63-990c-f54a-040b-f70c6cb03683.png)

つまりは、30分くらいは途中で作業止めて、遊ぶ。

# チームならではの開発

せっかくチームでやっているので、チームの意見を反映させる回数は多い方が良い。

最初に決めてあとは黙々と作業
は効率良いですが、チーム作業とは言えない。

ので、何回も繰り返すと良い。
あと、1DAYなので休憩とるタイミングは結構限られている。
気合で乗り切ってしまうこともあるが、まぁ、あまり良い結果にならない。

意識的にとる方向で。

#結論

例えば、1０時間あるなら

![image](https://qiita-image-store.s3.amazonaws.com/0/96808/e9b53ad6-2d69-942b-d905-84d68fd38170.png)


|時間|作業|プログラマ|デザイナ|サウンド|
|----|----|----|----|----|
|10:00|自己紹介、スキル紹介、ゲーム内容決め|
|10:30|α版（ゲームのコア）作成|α版の作成|α版の素材作成|α版の素材作成|
|12:00|α版、食事休憩と意見交換|
|13:00|　 |α版素材を組み込む|α版の素材修正、追加素材作成|α版の素材修正、追加素材作成|
|14:00|α版の素材組み込み版完成、休憩とβ版の意見交換|
|15:00| |β版の部分作成|β版の素材作成|β版の素材作成|
|16:00|β版、意見交換|
|16:30|　 |β版素材を組み込む|β版の素材修正、追加素材作成|β版の素材修正、追加素材作成|
|18:00|β版の素材組み込み版完成、休憩、リリース版の意見交換|
|19:00|　|
|20:00|リリース版完成|

積極的に休憩と意見交換の時間を用意し、方向性を確認しつつ、遊びながら作る。
作成過程に遊ぶための時間も用意しておく。


このスケジュール表を参考にしながら次回の1DAYゲームジャムに参加しようかと思う。
RxSwift 3.3 でダブルタップを正確に検知

記事の内容はこちらを参照してください。
https://mishimay.github.io/6e91912b40866e5c6bcb/
<!--


# やりたいこと
RxSwiftで「x秒間なにもイベントがなかったらそれまでの値をまとめて受け取りたい」という状況はよくあると思います。

例えばダブルタップだと「0.25秒間なにもイベントがなかったとき、それまでのタップ数が2回だったらダブルタップである」という判定ができます。

# 他言語では

RxJSなどではこのような要件は `buffer` と `debounce` (`throttle`) を組み合わせると簡単に実現できます。

`buffer` の引数にどのタイミングでイベントをまとめるかの条件を渡せるので、`debounce` を使って「x秒間なにもなかったら」という条件を指定できます [^1]。

```JavaScript
clickStream.buffer(clickStream.debounce(250))
```

# RxSwiftでは
現在 `buffer` が条件を受け取れる作りになっていません。
なので自前でなにかしら以下のようなものを作ってやる必要があります [^2]。

```Swift
extension ObservableType {
    func debouncedBuffer(_ dueTime: RxTimeInterval, scheduler: SchedulerType) -> Observable<[E]> {
        var buffer: [E] = []
        return self.do(onNext: { value in
            buffer.append(value)
        }).debounce(dueTime, scheduler: scheduler).flatMap { value -> Observable<[E]> in
            defer { buffer.removeAll() }
            return Observable<[E]>.just(buffer)
        }
    }
}
```

そうするとこのように書けます。

```Swift
        button.rx.tap
            .debouncedBuffer(0.25, scheduler: MainScheduler.instance)
            .filter { $0.count == 2 }
            .subscribe(onNext: { _ in
                print("double tap")
            })
            .disposed(by: disposeBag)
```

# 参考

[^1]: [【翻訳】あなたが求めていたリアクティブプログラミング入門 \- ninjinkun's diary](http://ninjinkun.hatenablog.com/entry/introrxja)
[^2]: [swift \- Implementing a debounced buffer with RxSwift, is this correct? \- Stack Overflow](http://stackoverflow.com/questions/39928928/implementing-a-debounced-buffer-with-rxswift-is-this-correct) <br> コードはこのStackOverflowのページを参考にしました :bow: <br> `buffer` に `Observable` を渡せるようなサンプルコードも載っているので興味ある方は見てみてください。






-->
Homebrew のインストール


##1. rubyからcurlを実行してインストール

```
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

↑上記コマンドは、Homebrewの公式サイトにある。URL変わる場合もあるので確認すること。
https://brew.sh/index_ja.html

##2. インストールできたか確認

```
brew doctor
```

で確認する。
「Your system is ready to brew.」と出ればOK


###↓なんかwarning出た。。。

```
$ brew doctor
Please note that these warnings are just used to help the Homebrew maintainers
with debugging if you file an issue. If everything you use Homebrew for is
working fine: please don't worry and just ignore them. Thanks!

Warning: Python is installed at /Library/Frameworks/Python.framework               *1

Homebrew only supports building against the System-provided Python or a
brewed Python. In particular, Pythons installed to /Library can interfere
with other software installs.

Warning: /usr/bin occurs before /usr/local/bin
This means that system-provided programs will be used instead of those
provided by Homebrew. The following tools exist at both paths:
  2to3

Consider setting your PATH so that /usr/local/bin
occurs before /usr/bin. Here is a one-liner:
  echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile
```

(*1) 事前に、独自にPython3.xをインストーラで入れていたため、警告が出た。

###↓なのでPythonいったん消す

####参考URL
http://nwpct1.hatenablog.com/entry/2014/03/20/173740
↓からの
https://nsplat.wordpress.com/2013/06/09/python%E5%86%8D%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%9F%E3%81%A3%E3%81%9F/
↓からの
http://blog.fkoji.com/2012/10022035.html

####Python消す手順
①アプリケーションフォルダにある PythonX.X を削除

②/Library/Frameworks/Python.framework を削除

③/usr/local/bin にある /Library/Frameworks/Python.framework へのシンボリックリンクを削除

シンボリックリンクは以下のコマンドで確認できる。

```
ls /usr/local/bin | grep -i python
```

以下で削除できる。

```
cd /usr/local/bin
ls /usr/local/bin | grep -i python | xargs rm -f
brew prune
```
Dockerコンテナを起動/削除できないときのトラブルシュートのメモ

Dockerを普通に使う分には問題ないのだけれど、例えばDockerホストがダウンしたあととか、普通に `docker run` したり `docker rm` したりするとエラーになる。そんなときに対応したときのメモです。

# docker run時にエラー

## ネットワークのエンドポイントを削除する

`docker run` 実行時に以下のメッセージが出てエラーとなる場合

```bash
docker: Error response from daemon: service endpoint with name <container name> already exists.
```

古いコンテナが残っているのかなと思って`docker ps -a` とかを実行しても出てこない。メッセージの通り、古いコンテナのNetworkのEndpointが残っています。

所属するであろうnetowrk名を調べます。

```bash
docker network inspect <network name>
```

```json
(略)
            "dd73bf98b2299a631581f16c9a159602e125b5f588a0a64a5bc64587cf08334f": {
                "Name": "<container name>",
                "EndpointID": "57f4826689a57238f0630b648d81abd20b7e01371bbcd9884dc6d96200bc7091",
                "MacAddress": "02:42:ac:12:00:07",
                "IPv4Address": "172.18.0.7/16",
                "IPv6Address": ""
            },
```

これが残っているせいで新しい同名のコンテナを作ることができません。以下のコマンドで削除することができます。

```bash
docker network disconnect -f <network name> <container name>
```

後はコンテナを作り直せるはず。

# docker rm 時にエラー

## ボリュームをアンマウントする

`docker rm -f` などでコンテナを削除しようとしても、やたらと時間がかかり(タイムアウトまで待っている)、結果的にコンテナが削除できていないとき。
syslogに以下のようなメッセージが出ている場合です。

```
Mar 22 01:55:16 host dockerd[32048]: time="2017-03-22T01:55:16.803688411+09:00" level=info msg="Container dd73bf98b229 failed to exit within 10 seconds of kill - trying direct SIGKILL"
Mar 22 01:55:16 host dockerd[32048]: time="2017-03-22T01:55:16.832892540+09:00" level=error msg="Handler for DELETE /v1.25/containers/<container name> returned error: Unable to remove filesystem for dd73bf98b2299a631581f16c9a159602e125b5f588a0a64a5bc64587cf08334f: remove /var/lib/docker/containers/dd73bf98b2299a631581f16c9a159602e125b5f588a0a64a5bc64587cf08334f/shm: device or resource busy"
```

デバイスがbusyでアンマウントできていません。普通に `mount` コマンドを実行するとマウントが見えているので、 `umount`します。

```bash
umount /var/lib/docker/containers/dd73bf98b2299a631581f16c9a159602e125b5f588a0a64a5bc64587cf08334f/shm
```

後はコンテナを消せるはず。

多分他にもいろいろハマりどころがあるんだろうなぁ…。
iptablesでポートフォワーディングとフィルタを組み合わせる設定

sshdが22番ポートをlistenしているときに、下記の要件を実現するiptables設定をまとめてみました。

1. 192.0.2.0/24 からsshdに22番ポート経由でアクセス可能
1. 198.51.100.0/24 からsshdに10022番ポート経由でアクセス可能
1. 他の組み合わせではアクセス不可

この場合、下記のようにすると一番見通しが良さそうです。REDIRECTされたかどうかの判断にmarkを利用しています。

```
# iptables -t mangle -A PREROUTING -p tcp --dport 10022 -j MARK --set-mark 10022
# iptables -t nat -A PREROUTING -p tcp --dport 10022 -j REDIRECT --to-port 22
# iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# iptables -A INPUT -s 198.51.100.0/24 -p tcp --dport 22 -m mark --mark 10022 -j ACCEPT
# iptables -A INPUT -m mark --mark 10022 -j DROP
# iptables -A INPUT -s 192.0.2.0/24 -p tcp -m tcp --dport 22 -j ACCEPT
# iptables -A INPUT -j DROP
```

別解として、REDIRECTの対象となるIPアドレスを絞ってしまう設定も考えられます。ただ、これだとIPアドレスの記述がnatテーブルとfilterテーブルとに分散してしまうのがイマイチかもしれません。

```
# iptables -t mangle -A PREROUTING -p tcp --dport 10022 -j MARK --set-mark 10022
# iptables -t nat -A PREROUTING -s 198.51.100.0/24 -p tcp --dport 10022 -j REDIRECT --to-port 22
# iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# iptables -A INPUT -p tcp --dport 22 -m mark --mark 10022 -j ACCEPT
# iptables -A INPUT -s 192.0.2.0/24 -p tcp -m tcp --dport 22 -j ACCEPT
# iptables -A INPUT -j DROP
```

# 参考URL

- [iptables でローカルの上位ポートに転送しているときにそのポートへの直接アクセスを禁止する - Qiita](http://qiita.com/ngyuki/items/1576d62ab9123dd20a4a)
- [コピペから脱出！iptablesの仕組みを理解して環境に合わせた設定をしよう | OXY NOTES](http://oxynotes.com/?p=6361#5)
    - テーブル/チェインの組み合わせと処理順の図がわかりやすい。
Blend for Visual Studio 2017 を試用してみた！

#はじめに
Visual Studio 2017 にひっそり寄り添うように Blend for Visual Studio 2017 が添付されています。
Blend と言えば、最初は有料のツールで主に Silverlight の画面設計のためのデザイナー向けツールという位置づけだったかと思います。
その後、Silverlight が終了してしまい、現在はどうなっているのか試用してみました。


#Blend 2017 を開いてみる
スタートメニューから次のアイコンを探してクリックします。（Windows 10 なら Bグループにあります)

![BlendIcon.png](https://qiita-image-store.s3.amazonaws.com/0/62802/a0686737-c525-54cb-e920-82a16b4c5c3f.png)

起動すると、下のような画面が開きます。Visual Studio そっくりですが、微妙に違ってます。
![Blend2017.png](https://qiita-image-store.s3.amazonaws.com/0/62802/245a19a9-e9e7-47b4-65bc-c11ba7ef0628.png)

ファイルメニューの「新規プロジェクト」から「新しいプロジェクト」ダイアログを開きます。テンプレートは実にシンプルです。 

![NewProject.png](https://qiita-image-store.s3.amazonaws.com/0/62802/9c97000e-587e-e58f-82b0-4937e6ef3330.png)

「WPF アプリ」を選んでOKボタンをクリックすると、WPF アプリにデザイン画面が開きます。

![Blend2017-p.png](https://qiita-image-store.s3.amazonaws.com/0/62802/1a3026a7-d21f-59c8-968d-9b79029a2425.png)

#画面をデザインしてみる
画面のデザインは Visual Studio 同様、部品を貼り付けていく方式です。部品はデザイン画面の左隣に縦に並んでいます。 

![DesignWindow.png](https://qiita-image-store.s3.amazonaws.com/0/62802/7575156d-8057-f206-7e12-578d09ff61ee.png)

これだけじゃ足りないと思いそうですが、一番下の >> ボタンをクリックすると隠れていた部品がずらりと出てきます。あまり数が多いのでどこに何があるのか覚えるのも大変そうです。

![ToolBox.png](https://qiita-image-store.s3.amazonaws.com/0/62802/8aa61bd5-13eb-e488-0a63-d49803a22938.png)

部品を貼り付けて適当に作った画面が下のイメージです。この画面では、「閉じる」ボタンをクリックしたとき、ウィンドウが閉じるだけですが、部品の色を変えたりアニメーションを行ったりいろいろできるようです。

![DesignWindow2.png](https://qiita-image-store.s3.amazonaws.com/0/62802/cc49f1ec-71d4-b248-5706-f46c1d20f142.png)

#イベントハンドラを追加してみる
イベントハンドラを追加すればいろいろできそうですが、ここはお試しということで、ボタンをクリックしたらウィンドウを閉じるイベントハンドラを追加します。まず、ボタンの名前を付けなくてはなりませんが、プロパティウィンドウの一番上に「名前」があるので、そこにボタンの名前（ここでは btnClose)を入力します。 

さらに「名前」横のカミナリマークをクリックすると、イベントハンドラ一覧が表示されるので、Click のところに btnClose_Click と入力します。 

![Property.png](https://qiita-image-store.s3.amazonaws.com/0/62802/80835dba-2241-d14d-802c-af1a72067fb2.png)

「表示」メニューでコードを選ぶと、コード画面に切り替わります。コードを見ると、イベントハンドラが追加されているはずなので、処理として "Close();" を入力します。 

```c#:
private void btnClose_Click(object sender, RoutedEventArgs e)
{
    Close();
}
```

#実行してみる
実行してみると、下のイメージのように何やら見慣れない黒いボタンが表示されますが、これはビジュアル的ないろいろな確認に使うツールのようです。 

![RunApp1.png](https://qiita-image-store.s3.amazonaws.com/0/62802/a9c85eca-2f5c-8401-d48b-5d0c32839c78.png)

このツールの下の方をクリックすると、下のイメージのように隠すことができます。 

![RunApp2.png](https://qiita-image-store.s3.amazonaws.com/0/62802/667bcde5-5e83-d385-c05a-ccdaa9c18dc4.png)

#使い道
業務系アプリケーションでは、地味な画面で十分なので通常 WPF は不要です。

Blend を使えば、デザインの労力はたいしたことがないので、強力な PowerPoint として使えます。もし、マクロを使うような PowerPoint プレゼンテーションを作るなら Blend を使うのも選択肢かもしれません。

電子看板などにも使えますね。きれいな画面と複雑なアニメーションを表現できます。

HTTP クライアント機能を組み込めば、単なる看板でなく対話型のアプリを作れます。ブラウザで複雑な JavaScript のプログラムを組むより C# や VB.NET のほうが開発効率も高いし、WPF の表現力も高いです。WPF は Direct-X ベースなのでスピードも速いはずです。
[リンク集]HTMLもWeb構築もわからない素人がPython+FlaskでWebサービスを作ってみる

これは、エンジニア未経験のど素人が、週末エンジニアとして
PythonとFlaskでWebアプリを作成するためのメモ記事へのリンク集です。

Flask / Docker / Web開発 についてメモしていきます。
それぞれについて詳しくは、
下記のリンクを参照してくださいl。

[ランディングページ] このページ
[Flask](http://qiita.com/yuusei/items/15f38a6abd431d093d2e)
-> [flaskr起動&test編](http://qiita.com/yuusei/items/73eef67fa692090086c0)
[Docker] (http://qiita.com/yuusei/items/51b3917f1ce3f2fbb5e6)
-> [Dockerコマンド](http://qiita.com/yuusei/items/640c85da1a1bf43fe72f)
[Web開発](http://qiita.com/yuusei/items/cf738b0849fc932a64e6)

##環境
MacBook Pro OS: Sierra 10.12.2 
Python Version: Python 3.5.2 :: Anaconda 4.2.0 (x86_64)
Webフレームワーク [Flask](https://flask-docs-ja.readthedocs.io/en/latest/)
仮想環境構築:[Docker](https://www.docker.com)

##動機
動機：
・仕事はRメインで構築しているが、RNNなどDeepLearning系も一旦扱えると面白そう(計算がBlackBox化している点が好きではないのですが・・・)。
・DeepLearningと言えば[Chainer](http://chainer.org)や[TensolFlow](https://www.tensorflow.org)がメジャー。これらはPythonが必須
・Pythonはプログラミング言語だから、他にも応用が利きそうだ。書けて損はないだろう。
・PythonではWebScrapingもできるのか！マナーを守れば欲しいデータ取り放題だぞ！
・しまった・・・Webの事が全くわからない・・・
・よし、勉強がてら簡単なWebサービスを一つ作ってしまおう！

以上です。が・・・自分ながら雑な理由ですね。。。時間かかりそう。。。

##フレームワーク選定理由:
PythonでWebサービス開発をするにあたり、
何がいいかを調べたところ、

[侍エンジニアリング:2017年大注目のPython！WEBフレームワーク3つを徹底比較](http://www.sejuku.net/blog/3713)

こんな記事がありましたよと。

どうも、PythonのWebフレームワークにおいては、
[Dijango](https://www.djangoproject.com)
[Flask](http://flask.pocoo.org)
が二強(と言うかDijangoが王者でFlaskが挑戦者)であり、
他のフレームワークは蚊帳の外っぽいので、この二つのうちのどちらかを選ぶことにしました。

最大の理由は「Flaskの方がDijangoよりもプログラミングっぽく開発ができるらしい」と言う事です。
「プログラミング」ここ大事。何をやっているかわからないまま「サービスできました！」は嬉しくない。

なので、Flaskを選んだのですが、
そもそもWeb開発どころかexe系のアプリ開発さえした事のないプログラミング素人としては・・・いやはや・・・難儀しております。

そんなわけで、今後 Python / Flask / Docker / Web開発 の４つに分けてだらだら上の方のリンク先にまとめて行くので、
よろしければご笑覧のほど。コメントとかアドバイスいただけると飛び跳ねて喜びます。
Ubuntu16.04にてDNSエラー

引っ越して自宅のネットワーク環境が新しくなったら手持ちのUbuntuにてDNSエラーが起きるようになった
#状況
ブラウザではサイトにつながったり、つながらなかったりといったことが確認されていた。
コンソールからwgetを使用すると、「ホストアドレスを解決できませんでした」と言われる始末。

#解決方法
1.IPv6のサポート解除
2.DNSネームサーバの指定

1.
「/etc/sysctl.conf」に以下の１行追加
net.ipv6.conf.all.disable_ipv6 = 1

2.
「/etc/resolvconf/resolv.conf.d/base」に以下の1行を追加
nameserver 8.8.8.8
tmuxで快適にpane移動

2017/03/30 追記
@f440 さんに `display-panes` だけでいけると指摘を受けて修正しました。
標準の機能だけでいけたのか。 `display-panes` なら標準で `C-q` にbindされてるみたいですね。


# tmuxでpane移動

tmuxで作業しているとき、時々いろんな事情で、ウィンドウをたくさんのpaneに分けているとき・・・こういう場合。

<img width="1271" alt="スクリーンショット 2017-03-26 11.23.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/34692/9862bbc7-5ac0-74a3-2c82-19922feaa7c9.png">

標準でbindされているキーだと、

- １つ前のpane
- １つ上、下、左、右

などは、用意されてるんですが、斜めや、２つ以上離れた上下左右のpaneには一発で移動出来ません。
例えば、上記の画像のpane番号でいうと

- `0` から `5` へ移動
- `5` から `1` へ移動
- `1` から `3` へ移動

などはなかなか面倒です。で、なにか方法無いかなーと探していたのですが、stackoverflowで

http://stackoverflow.com/questions/18644359/select-pane-with-c-number-in-tmux/21741563#21741563

というのがありまして、まさにこれがやりたかったことだということで設定してみたら、かなり捗りました。

~/.tmux.confに下記のように設定（ここではprefix　key + `C-g`)しておくと、

```~/.tmux.conf
# 2017/3/30 display-panes だけに修正
bind-key C-g display-panes
```

------------------------------------
**2017/3/30**
実はこれ display-panesだけで大丈夫で、しかも標準で `C-q` にバインドされているようです。。　ほぼこの記事の存在意義が無くなる。。

1点追記時にしらべたところだと、このpane番号が表示されている時間が短いなーとおもっていたのですが、

```~/.tmux.conf
set display-panes-time 10000
```

しておくと、表示されている時間が長くなって選択しやすくなるようでした。

------------------------------------

画面にpane番号を表示しつつ、そのpane番号を入力するとそこに移動するようになります。

例えば、上記の例でいうと、
最初に左上の0番のpaneにいる状態から、

- `0` から `5` へ移動
- `5` から `1` へ移動
- `1` から `3` へ移動

へ移動すると、下記のようになります。
(僕はtmuxのプレフィックスを `C-t` にしているので、 実際には `C-t C-g` になります。)

![output.gif](https://qiita-image-store.s3.amazonaws.com/0/34692/d7d88e90-125a-3423-bc8c-8671c78d6267.gif)

あんまりpaneが多すぎても作業しにくいですが、例えば、小さいpaneで別の端末にsshしておきたい、とか、コンテナの中のシェルを1行分だけ表示しときたいとか、自分の場合はたまにあるので、めっちゃ快適になりました。
ruby 2.4.1 をインストールしました。

私の環境がMax OSですので、Homebrewでのruby 2.4.1の
インストールした方法を記載します。
途中でインストールが失敗しましたが、インストール完了まで記載します。
  
1.まずはHomebrewをアップデートします。

```
brew update
```

2.ruby-buildをアップグレードします。

```
brew upgrade ruby-build
```

3.インストール可能なrubyのリストに 2.4.1 が表示されます。

```
rbenv install --list
  ・
　　　　・
  2.4.0
  2.4.1
  2.5.0-dev
```

4.ruby 2.4.1 をインストールします。

```
rbenv install 2.4.1
ruby-build: use openssl from homebrew
Downloading ruby-2.4.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.1.tar.bz2
Installing ruby-2.4.1...
ruby-build: use readline from homebrew

BUILD FAILED (OS X 10.11.6 using ruby-build 20170201)

Inspect or clean up the working tree at /var/folders/vq/g9m8djz92rd6v0mhdgbl9c6h0000gn/T/ruby-build.20170326103701.37481
Results logged to /var/folders/vq/g9m8djz92rd6v0mhdgbl9c6h0000gn/T/ruby-build.20170326103701.37481.log

Last 10 log lines:
  Referenced from: /private/var/folders/vq/g9m8djz92rd6v0mhdgbl9c6h0000gn/T/ruby-build.20170326103701.37481/ruby-2.4.1/./miniruby (which was built for Mac OS X 10.12)
  Expected in: /usr/lib/libSystem.B.dylib

dyld: Symbol not found: _clock_gettime
  Referenced from: /private/var/folders/vq/g9m8djz92rd6v0mhdgbl9c6h0000gn/T/ruby-build.20170326103701.37481/ruby-2.4.1/./miniruby (which was built for Mac OS X 10.12)
  Expected in: /usr/lib/libSystem.B.dylib

make: *** [encdb.h] Trace/BPT trap: 5
make: *** Waiting for unfinished jobs....
make: *** [.rbconfig.time] Trace/BPT trap: 5
```
BUILD FAILEDで怒られてしまいました。

調べてみるとxcode-selectのバージョンが古いみたいです。
確かにここ最近XCODEを起動してなかったので全く気がつきませんでした。

xcode-selectを更新します。

```
xcode-select --install
```

4.再度、ruby 2.4.1 をインストールします。

```
~ % rbenv install 2.4.1
ruby-build: use openssl from homebrew
Downloading ruby-2.4.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.1.tar.bz2
Installing ruby-2.4.1...
ruby-build: use readline from homebrew
Installed ruby-2.4.1 to /Users/xxxxx/.rbenv/versions/2.4.1
```
今度こそ無事ruby 2.4.1 をインストール出来ました。

5.rubyのバージョンを2.4.1に切り替えます。

```
rbenv global 2.4.1
rbenv versions
  system
  2.0.0-p353
  2.3.0
* 2.4.1 (set by /Users/xxxxx/.rbenv/version)
```
```
ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin15]
```

少し躓きましたが、なんとかruby 2.4.1 をインストール出来て何よりです。
mysqldump結果をvimで読めるように改行挿入

改行のない長大なINSERT文はvimで開きにくい。
改行を挟めば読みやすくなる。

以下はSQLとしてパースしてないから、データが改ざんされるかもしれないけど、これでも十分なケースが多いと思う。

## PHPでやる場合

```bash
$ cat hoge.sql |
php -R 'echo strtr($argn, ["),"=>"),\n","VALUES ("=>"VALUES\n("]),PHP_EOL;'
> hoge_prettyprint.sql
```
docker-composeでmysql+redis+sidekiqなrails環境を作る

- RAILS_ROOT/Gemfile

```ruby
# これ追加
gem 'sidekiq'
gem 'sinatra', require: false
gem 'redis'
gem 'redis-namespace'
``` 

- RAILS_ROOT/config/routes.rb

```ruby
Rails.application.routes.draw do
  # 2行追加
  require 'sidekiq/web'
  mount Sidekiq::Web => '/sidekiq'

  ...
end
```

- RAILS_ROOT/config/initializers/sidekiq.rb

```ruby
Sidekiq.configure_server do |config|
  config.redis = { url: 'redis://redis:6379', namespace: "sidekiq" }
end

Sidekiq.configure_client do |config|
  config.redis = { url: 'redis://redis:6379', namespace: "sidekiq" }
end
```

- RAILS_ROOT/config/database.yml
 
```yaml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password: password # ここ修正
  host: db # ここ修正
```

- RAILS_ROOT/Dockerfile
 
```
FROM ruby:2.3.1
ENV LANG C.UTF-8
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN gem install bundler
ENV app /app
RUN mkdir $app
WORKDIR $app
ADD Gemfile* $app/
ENV BUNDLE_GEMFILE=$app/Gemfile \
  BUNDLE_JOBS=2 \
  BUNDLE_PATH=/bundle
ADD . $app
```

- RAILS_ROOT/docekr-compose.yml
 
```yaml
version: '2'
services:
  db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
    volumes:
      - db-data:/var/lib/mysql
    ports:
      - "3306:3306"
  redis:
    image: redis
  app:
    build: .
    volumes:
      - bundle:/bundle
  web:
    extends:
      service: app
    command: /bin/sh -c "rm -f /app/tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    links:
      - db
      - redis
  worker:
    extends:
      service: app
    command: bundle exec sidekiq
    volumes:
      - .:/app
    links:
      - db
      - redis
volumes:
  db-data:
    driver: local
  bundle:
    driver: local
```

:octocat: https://github.com/t-taira/docker-compose-rails
PHP 7.0でnullableな型宣言を使いたい場合の裏技

これも小ネタ。

PHP7.0の重用な新機能として、タイプヒンティングにプリミティブ型（int, string, float, booleanなど）が指定できるようになりました。（[スカラー型宣言](http://php.net/manual/ja/migration70.new-features.php)）

関数・メソッドの引数の型チェックすることは防衛的プログラミングの基本ですから、せっかくPHP 7を使うのであれば積極的に活用していきたいところですね。

しかし、一つ困ったことが。それは`null`を許容できないことです。

```php:PHP7.0でのスカラー型宣言
declare(strict_types=1);    // 自動型変換を無効（このファイルのみ）

function test(int $n) // $n は intでなければならない。
{
}

test(1);             // OK

test('1');           // NG  PHP Fatal error:  Uncaught TypeError: Argument 1 passed to test() must be of the type integer, string given
                     // declare(strict_types=1); の指定がないと暗黙の型変換によって1に変換されてチェックが通ってしまうことに注意。

test(null);          // NG  Fatal error: Uncaught TypeError: Argument 1 passed to test() must be of the type integer, null given
```

PHP 7.1であれば[nullable な型](http://php.net/manual/ja/migration71.new-features.php)がサポートされているので、型名の前に`?`を追加すればOKです。（ちなみにnullableはプリミティブだけではなく、クラス名指定の場合にも付与可能。）

```php:PHP7.1ならnullable可
declare(strict_types=1);

function test(?int $n) // $n は int か null でなければならない。
{
}

test(1);             // OK

test('1');           // NG  PHP Fatal error:  Uncaught TypeError: Argument 1 passed to test() must be of the type integer, string given

test(null);          // OK
```

さて、PHP 7.0で同じことするにはどうしたら良いでしょうか？ 実は引数のデフォルト値として`=null`を指定すると`null`が許容されるようになります。

```php:PHP7.0でなんちゃってnullable
declare(strict_types=1);

function test(int $n = null) // なんちゃってnullableで、$n は int か null でなければならないようにする。
{
}

test(1);             // OK

test('1');           // NG  PHP Fatal error:  Uncaught TypeError: Argument 1 passed to test() must be of the type integer, string given

test(null);          // OK
test();              // OK
```

PHP 5系のタイプヒンティングでも同様の方法でnullableを指定できてましたので、その流れでしょう。正式な構文なのか、単純にバグなのかちょっと理解に迷うところではあります。

ちなみに、デフォルト引数を使えばint型を宣言していても文字列を指定できるのか？　というと…。

```php:デフォルト引数に文字列を渡してみる。
function test(int $n = 'abc')   // PHP Fatal error:  Default value for parameters with a integer type can only be integer or NULL
{
}
```

怒られちゃいました（PHP 7.0/7.1両方とも）。良くわかりませんね。
DISKのメタデータ (zfs, GPT)を削除

## 現象

* debian8 で zfs を昔使っていた。
* その後zfsを使わずext4で使っていた。
* debian9 をクリーンインストールした後、`blkid`でUUIDが表示されないことに気がついた。
* `dd if=/dev/zero of=/dev/sda bs=1M count=1000` とかしても消えなかったので調査したところ、`wipefs`コマンドで消せることにたどり着いた。

* [HDD mount problem (bad FSTYPE) / System Administration / Arch Linux Forums](https://bbs.archlinux.org/viewtopic.php?id=202587)

## 確認

```rb
# wipefs /dev/sda1
offset               type
----------------------------------------------------------------
0x7470abfc00         zfs_member   [filesystem]
                     LABEL: tank500
                     UUID:  7915798765570182767

0x438                ext4   [filesystem]
                     UUID:  d307f4b7-0862-4a5a-bcd3-fbdc3b842c12
```

## 消去

```rb
# wipefs -a /dev/sda1
/dev/sda1: 2 bytes were erased at offset 0x00000438 (ext4): 53 ef
/dev/sda1: 8 bytes were erased at offset 0x7470abfc00 (zfs_member): 0c b1 ba 00 00 00 00 00
/dev/sda1: 8 bytes were erased at offset 0x7470abf800 (zfs_member): 0c b1 ba 00 00 00 00 00
/dev/sda1: 8 bytes were erased at offset 0x7470abf400 (zfs_member): 0c b1 ba 00 00 00 00 00
/dev/sda1: 8 bytes were erased at offset 0x7470abf000 (zfs_member): 0c b1 ba 00 00 00 00 00
/dev/sda1: 8 bytes were erased at offset 0x7470abec00 (zfs_member): 0c b1 ba 00 00 00 00 00
/dev/sda1: 8 bytes were erased at offset 0x7470abe800 (zfs_member): 0c b1 ba 00 00 00 00 00
/dev/sda1: 8 bytes were erased at offset 0x7470abe400 (zfs_member): 0c b1 ba 00 00 00 00 00
/dev/sda1: 8 bytes were erased at offset 0x7470abe000 (zfs_member): 0c b1 ba 00 00 00 00 00
/dev/sda1: 8 bytes were erased at offset 0x7470abdc00 (zfs_member): 0c b1 ba 00 00 00 00 00
/dev/sda1: 8 bytes were erased at offset 0x7470abd800 (zfs_member): 0c b1 ba 00 00 00 00 00
/dev/sda1: 8 bytes were erased at offset 0x7470abd400 (zfs_member): 0c b1 ba 00 00 00 00 00
/dev/sda1: 8 bytes were erased at offset 0x7470abd000 (zfs_member): 0c b1 ba 00 00 00 00 00
...
```

## 確認、再フォーマット

```rb
wipefs /dev/sda1
mkfs.ext4 /dev/sda1
blkid
```

blkid で UUID 値が表示されることを確認。
ページ内リンクをスムーズにスクロールする方法

# 実装シチュエーション

* 「テキストリンク」や「ボタン」を押したときにページ下部のコンテンツへ移動させるとき
* ページ上部に戻るボタンを押して最上部に移動させるとき

# 利用できる範囲

* ページ内リンクを下記のように、#から始まるように設定したとき

```html:qiita.rb
<a href="#sample">サンプルページ</a>
```

# ソースコード

```js:qiita.rb
$(function(){
   // #で始まるアンカーをクリックした場合に処理
   $('a[href^=#]').click(function() {
      // スクロールの速度
      var speed = 400; // ミリ秒
      // アンカーの値取得
      var href= $(this).attr("href");
      // 移動先を取得
      var target = $(href == "#" || href == "" ? 'html' : href);
      // 移動先を数値で取得
      var position = target.offset().top;
      // スムーススクロール
      $('body,html').animate({scrollTop:position}, speed, 'swing');
      return false;
   });
});
```
import-js で JavaScript の import を自動入力する


# import-js で JavaScript の import を自動入力する

React 等、新しい ES 環境で import を多用する開発を行ってると、クラスや関数を使う度、import に毎回追加、というのが面倒じゃないですか？私はめっちゃ面倒くさかったです。

そんなとき、import-js を使うと、足りない import 文を入力してくれて大変便利です。

- https://github.com/Galooshi/import-js

![](https://camo.githubusercontent.com/4278173836c2791fa09cac61f48300ec93564459/68747470733a2f2f7261772e6769746875622e636f6d2f67616c6f6f7368692f696d706f72742d6a732f6d61737465722f696d706f72742d6a732d64656d6f2e676966)

fix import で足りない import 文を勝手にプロジェクトのルートや node_modules から探していい感じに入れてくれます。また同じ名前のモジュールが複数ある場合、ダイアログを出してくれます。

また JSX や flow にも対応しているため、`<ComponentName />` みたいな JSX タグも import 文に追加してくれます。

エディタも、Atom, Emacs, Sublime, Vim 用のプラグインが用意されてますし、CUI 経由で実行することも出来ます。

JS の構文解析に内部では [babylon](https://www.npmjs.com/package/babylon) を用いていて、 クラス定義などにもある程度うまくジャンプしてくれる機能もあるため、ライブラリへ飛んでソースコード読むときにも活用できます。

また .importjs.js の設定ファイルを作りカスタマイズすることで、細かく追加する import 文を制御することも出来ます。

この import-js 、個人的には React を用いた JS 開発には無くてはならない物となってるんですが、イマイチ知名度が無いため紹介しました。便利！！！１
ADB Connection Error

AndroidStudioでAndroidMonitorを開くとInitialize表示になってしばらくProgress表示になったあとにこのエラーダイアログが表示される。

adbプロセスをKillしてみたりいろいろやっても解決せず
ホームディレクトリにある .android を削除すると解決した

.android ディレクトリの中の何かのファイルが関係しているようだがこれ以上の調査はしていない。
XOR交換アルゴリズムって面白い

# はじめに
サンプルコードは[wandobox](https://wandbox.org/)様で一応動作確認していますが誤っていたらすいません。
数学科とか出てないので間違ってたらすいません。

#XOR演算
**2値が一致している**か**2値が相違している**かどうかで結果が変わる演算です。
特に難しいことはないと思いますが、同期の丸暗記おじさんに教えたら「なるほどー」と言われました。
もし、丸暗記が辛かったらこんな風に法則で覚えると良いですよ
※XOR演算がそういう目的のモノなのかは知らないので覚え方だけですよ！

|A|B|演算結果|
|:-:|:-:|:-:|
|0|0|0|
|0|1|1|
|1|0|1|
|1|1|0|

#交換アルゴリズム

2値の交換って普通に考えると下記のようなコードになると思います。

```py3:wandbox_sample
print('---------- RAW DATA ----------')
obj1 = 10
obj2 = 20
print("obj1: ", obj1)
print("obj2: ", obj2)

print('---------- SWAPED DATA ----------')
tmp_obj = obj1
obj1 = obj2
obj2 = tmp_obj
print("obj1: ", obj1)
print("obj2: ", obj2)
```

これって```tmp_obj```なんて一時変数をわざわざ用意する必要があります。
別に用意してもいいんですけど、

- 一時変数って何の役割の変数か後で見たときに分からない
- メモリがキツキツの環境だとそういうのも削減したい

とかある訳ですよ。知らないけど。

そんな悩みを解決できる奴がいたんです。
その名も……

#XOR交換アルゴリズム

```py3:wandbox_sample
print('---------- RAW DATA ----------')
obj1 = 7
obj2 = 12
print("obj1: ", obj1)
print("obj2: ", obj2)

print('---------- SWAPED DATA ----------')
obj1 = obj1 ^ obj2
obj2 = obj1 ^ obj2
obj1 = obj1 ^ obj2
print("obj1: ", obj1)
print("obj2: ", obj2)
```

ホントに一時変数がなくなった……

## 確かめてみる

コードの概要はこれでした。

```py3:wandbox_sample
A = 7
B = 12
A = A ^ B
B = A ^ B
A = A ^ B
```

```math
\begin{align}
A = 0111\\
B = 1100\\
A &= A \ xor \ B \\
&=0111 \ xor \ 1100\\
&=1011\\
B &= A \ xor \ B \\
&= 1011 \ xor \ 1100\\
&= 0111\\ 
A &= A \ xor \ B\\
&= 1011 \ xor \ 0111\\
&= 1100\\
A = 1100\\
B = 0111
\end{align}
```

確かに入れ替わった！！

#XORの法則
前提として下の法則があります。

##1. 交換法則
xor演算子の左辺・右辺は交換ができる。

```math
A \ xor \ B = B \ xor \ A\\
```
具体例

```math
A = 0111とする\\
B = 1100とする\\
A \ xor \ B = 1011\\
B \ xor \ A = 1011
```

##2. 結合法則
計算の優先を変化させても結果は変わらない。

```math
(A \ xor \ B) \ xor \ C = A \ xor \ (B \ xor \ C)
```
具体例

```math
A=0111とする\\
B=1100とする\\
C=1001とする\\
\begin{align}
(A \ xor \ B) \ xor \ C &= 1011 \ xor \ 1001\\
&= 0010\\
A \ xor \ (B \ xor \ C) &= 0111 \ xor \ 0101\\
&= 0010\\
\end{align}
```

##3. 単位元
Z=0という値があり任意のAとxorするとAが求まる。
計算しても変化しない奴もいますよってこと
具体例

```math
A = 0111とする\\
Z = 0000とする\\
A \ xor \ Z = 0111 (=A)
```

##4. 逆元（インバース？）
任意のAとxorすると0になる値A^-1を持つ。
なんか逆行列みたいな関係のやつ

```math
A = 0111とする\\
A \ xor \ A^{-1} = 0と仮定すると、\\
\begin{align}
A^{-1} &= 0111\\
&= A
\end{align}
```
あれ？自身が逆元だ。おもしろい。

#証明？

```math
\begin{align}
A &= A \ xor \ B\\
B &= A \ xor \ B\\
&= (A \ xor \ B) \ xor \ B（結合法則で変形すると…）\\
&= A \ xor \ (B \ xor \ B)（逆元の存在で計算すると…）\\
&= A \ xor \ 0（単位元の存在で計算すると…）\\
&= A（入れ替わったー！）\\
A &= A \ xor \ B\\
&= (A \ xor \ B) \ xor \ A（交換法則で変形すると…）\\
&= (B \ xor \ A) \ xor \ A（結合法則で変形すると…）\\
&= B \ xor \ (A \ xor \ A)（逆元の存在で計算すると…）\\
&= B \ xor \ 0（単位元の存在で計算すると…）\\
&= B（入れ替わったー！）\\
\end{align}
```

なるほどー(´･_･`) （計算式上成り立つのは分かったけど、ピンと来てない顔
これはスゴイな！！

#追記
これはアルゴリズムのお話なんで、こんなの書きましたけど、
実際に書くときは標準ライブラリに入ってるであろうswap関数を使った方がいいですよ
特にC/C++辺りの独自実装は危険な香りしかしないので、標準ライブラリ頼みな自分です。

Pythonはswap関数がないので、こういう書き方をしますね。

```py3:wandbox_sample
obj1 = 10
obj2 = 20
obj1, obj2 = obj2, obj1
```
plasma-desktopをビルドする

plasma-desktopをビルドしようとして、いろいろ苦労した後で簡単な方法に気がついたので書いておく。

まず、https://neon.kde.org/ からneonのstableなdeveditionをダウンロードしてきてVirtualBoxにでもインストールする。
それから
> sudo apt-get install git dialog

あとgccとmakeもGuestAdditionのために入れた。
そして
> sudo apt-get build-dep plasma-desktop

~/.gitconfig を弄って
> [url "git://anongit.kde.org/"]
   insteadOf = kde:
[url "ssh://git@git.kde.org/"]
   pushInsteadOf = kde:

ディレクトリ掘って
> mkdir -p ~/kde/src
> cd ~/kde/src

cloneして
> git clone kde:kdesrc-build
> cd kdesrc-build

./kdesrc-build-setup を呼ぶ。
commit accessは、たぶん持ってないから＜いいえ＞
HTTP proxy、普通は使わないから＜いいえ＞
それ以外は放っておいてよいと思う。

インストール時に権限が要るので~/.kdesrc-buildrcのglobalの中に
>    make-install-prefix sudo

と書いておく必要がある。
visudoもやっておいた方がよい。
あと
>    kdedir /opt/kde/install

にしておくと実行するとき楽かも。

そして
> ./kdesrc-build plasma-desktop

細工は流々あとは仕上げを御覧じろ。

実行は https://community.kde.org/Guidelines_and_HOWTOs/Build_from_source/Test_plasma が参考になった。
wordpressで記事のプレビューが表示されない場合の対処法


wordpressで公開前の記事がプレビューできない場合がある。
（公開後はきちんと表示される）

その場合、だいたい下記の３つのどれかが原因なので試してほしい。

**1.WordPress アドレス (URL)とサイトアドレス (URL)が異なっている**

これはそのままで、ここが異なっていると表示されない場合がある。
２つのアドレスの違いは
https://www.nishi2002.com/4207.html
を参照。

**2.認証用ユニークキーが原因**

1.と似たような感じですが、最初にサイト構築した後にURLの変更や独自ドメインの取得などを行なった場合、上記が原因で表示されなくなる場合がある。

その場合は「wp-config.php」内の

```
/**#@+
 * 認証用ユニークキー
 *
 * それぞれを異なるユニーク (一意) な文字列に変更してください。
 * {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org の秘密鍵サービス} で自動生成することもできます。
 * 後でいつでも変更して、既存のすべての cookie を無効にできます。これにより、すべてのユーザーを強制的に再ログインさせることになります。
 *
 * @since 2.6.0
 */
```

の部分のちょっと下になる認証キーを上記のURLへ飛んで自動生成し直して上書きする。
URLというのは
https://api.wordpress.org/secret-key/1.1/salt/
の部分のことね

**3.例外処理を入れず「pre_get_posts」を使って記事の並び替え処理などを入れてしまった場合**

下記のfunction.phpなどに、記事のソートや絞り込みなどをカスタマイズの処理として自分で追加した場合、ちゃんと例外処理書いてやらないと表示されなくなる場合がある


![Kobito.ggip1C.png](https://qiita-image-store.s3.amazonaws.com/0/41877/edeb43ff-b238-c0d0-e125-9d1e4d2a23c9.png "Kobito.ggip1C.png")


その場合、その関数の最初に下記の処理を追加する。
そうすると、ソートなどの処理がプレビューに適用されなくなるので無事表示される
```php
 if( is_admin() || ! $query->is_main_query() || is_preview(){
     return;
 }
```
iOSのビルド高速化 7つの方法

# 1.並列ビルド
ターミナルで、`defaults write com.apple.dt.Xcode IDEBuildOperationMaxNumberOfConcurrentCompileTasks 4` を実行。
これはよく出てくる対策です。

# 2.Build Active Architecture Only
Xcodeの`Target→Build Setting→Build Active Architecture Only`で`Debug`だけ`YES`にしましょう。
これをすると、ビルドしたい端末に最適なアーキテクチャでのみビルドしてくれます。
NOにすると、すべてのアーキテクチャでビルドして全最適化を行われます。
不要なアーキテクチャのビルド分時間がかかるということです。
※Releaseでは必ずNOにしましょう。

# 3.Find Implicit Dependencies
ビルドしたいターゲットの`Edit Scheme → Build`で設定できます。
これのチェックを外しましょう。
チェックがあると、自動的に依存ライブラリとしてビルドされるようになるので、自分で`Link with Libraries`にライブラリを追加したりしなくて済みます。
ただ、一度Podsなどの依存ライブラリをビルドしてしまえば、依存ライブラリとして認識されてるので、毎回ビルドする意味はありませんので、チェックを外します。

※pod install/update後は、必ず一回チェックもどしてからビルドするようにしましょう。

# 4.Embedded Framework
Utility系や、独自に編集したライブラリなどをEmbbed Frameworkで切り出しましょう。
差分コンパイルが効きやすくなり、コンパイル時間が短縮されます。

`ld: warning: object file () was built for newer iOS version (9.3) than being linked (8.0)` 
上記のようなwarningは、作成したフレームワークの`Deployment Target`が、アプリのターゲットと、Podfileに記述してるPlatformと一致してないために出るものです。
一致させればwarningが出なくなります。

# 5.Run Script Phaseをスキップ
Run Scriptでは、ビルド時にCocoaPodsやCarthageで導入したフレームワークを毎回コピーしています。使ってるフレームワークが多ければ多いほど、Run Scriptの時間が増え、ビルド時間がどんどん増えていくわけです。
一度これを行えば、`Derived Data`にコピーされてるので、毎回実行しなくていいのです。

`Target→Build Phase`にあるそれぞれの`Run Script Phase`の設定で、`Run script only when installing`というのがあります。
これのチェックを入れると、最初のインストール時のみに実行されるようになります。

ただし、PodsやCarthageでライブラリを追加・更新などを行うと、それをコピーしないとビルドに失敗するため、毎回このチェックを外し直さないといけなくなります。

Podsを更新したときに、`Run script only when installing`にチェックを外し、一度ビルドするとチェックを入れるようにすると便利そうです。

以下のサイトを参考にしました。
https://medium.com/@r.izumita/speed-up-building-on-xcode-by-stopping-run-script-phases-361579a8ba8d#.tjmvql7go

やることは、

1.`Run script only when installing`のチェックを入れたり、外したりするスクリプトを作成
2. Podfileに、上記のスクリプトを使ってチェックを外すようにする
3. 上記のスクリプトを使ってチェックを入れなおすスクリプトを、ビルド後に実行させる

2について、私は以下のようなコードを、Podfileの一番最後に追記しました。

```ruby
require 'open3'
Open3.capture3("ruby update_run_script_setting.rb --no-only --project=プロジェクト.xcodeproj --target=ターゲット --phases='[CP] Embed Pods Frameworks','[CP] Copy Pods Resources','Copy Carthage Framework'")
```

3については、`Edit Scheme → Build → Post Actions`に以下のコードを追加しました。

```
cd $SRCROOT;
ruby update_run_script_setting.rb --only --project=プロジェクト.xcodeproj --target=ターゲット --phases='[CP] Embed Pods Frameworks','[CP] Copy Pods Resources','Copy Carthage Framework'
```

# 6.Podsをやめて、Carthageにする
Carthageにすると、ライブラリを事前にビルドしておくため、その分早くなります。

参考: [Carthageを使ってビルド時間を短縮しよう](http://qiita.com/yutat93/items/97fe9bc2bf2e97da7ec1)

# 7.コードを見直す
`Target -> Build Settings -> Other Swift Flag` ni `-Xfrontend`と`-warn-long-function-bodies=閾値`を追加します。
例えば、閾値のところを100とすると、100ms時間がかかってるコードにwarningが表示されて、どこに処理に時間がかかってるのかがわかるようになります。

参考: [コンパイルに時間がかかるSwiftのコードへWarningを発生させる](http://qiita.com/kazuhiro4949/items/62cedebd08ed87b02333)

また、warningが出るのも遅い原因になるため、地道にwarningを直していきましょう。

型推論も遅い原因になります。
ArrayやDictionaryで型を指定しないと、その分コンパイラが型を推測する必要があるため遅くなるようです。
私もswiftでArrayとDictionaryを多用していたクラスファイルがあったのですが、型を指定してあげると、そのファイルでかかってるコンパイル時間が短くなりました。

参考: [激遅Swiftのコンパイル時間が75%ほど短縮したお話](http://cocopon.me/blog/?p=5447)

追記： [6/23に投稿されたCyberAgentさんの記事もおもしろい](https://developers.cyberagent.co.jp/blog/archives/7815/#measure)
Validated thesis "Twitter mood predicts the stock market" and succeeded 60% accuracy up-down prediction

# Target
"Twitter mood predicts the stock market"
https://arxiv.org/pdf/1010.3003.pdf

Its conclusion can be roughly summarized below.

- Calmness on twitter correlates with Dow Jones Index Average and it enables us to predict up-down of DJI index on 87.6% accuracy

# Validation steps
1. Extract calmness score from Twitter dataset of 2009
 - https://archive.org/details/twitter_cikm_2010
 - Method is almost same with the thesis. But I can't get questionaries called "Profile of Mood States"(POMS). So I selected words express calmness with my original method
2. Predict up-down of DJI Index from calmness score with Xgboost library
 - Data&Prediction code: https://gist.github.com/ryogrid/e5274ac31a5b9ac02e8a9fe33b8ac921
 - Data format: date, daily calmness score, daily DJI Index
 - Early half part of data for learning. Latter half for prediction
 - Input data are 3 days calmness score and stock price diff (price[t]-price[t-1]) 

Plotted calmness score
![calmness.jpg](https://qiita-image-store.s3.amazonaws.com/0/12325/0adde047-a0bc-1fea-13e1-41643ab14a68.jpeg)

DJI Index of 2009
![dji.jpg](https://qiita-image-store.s3.amazonaws.com/0/12325/c3313a62-4027-145a-e061-b193a09581fd.jpeg)

# Result
I successfully predicted up-down on 59.5% accuracy.

If you doubt of this result, please try prediction with my data or analyze it on statistical view.

- https://gist.github.com/ryogrid/e5274ac31a5b9ac02e8a9fe33b8ac921

If you have any question.
Please mail to ryo.contact [at] gmail.com
Laravelインストール付随作業（ローカル開発環境）

# Laravelインストール付随作業（ローカル開発環境）

## composer インストール・パス通し
```
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer
```

## 環境移行後初回に実行
```
composer install
composer update
```

## .envファイル複製
`cp .env.example .env`

## .envファイル作成後にキー生成
`php artisan key:generate`

## .htaccessの下層オーバーライドを許可
`vi /etc/httpd/conf/httpd.conf`
```
<Directory "/var/www/html/public">
-    AllowOverride None
+    AllowOverride All
</Directory>
```

## IDEヘルパーファイル生成（barryvdh/laravel-ide-helperのインストールが必要）
`php artisan ide-helper:generate`

## オートロードファイル更新  
`composer dump-autoload`

## パーミッション変更(-Rでディレクトリ内も再起処理)  
`chmod -R 777 /var/www/html/storage/logs`

## Artisan コマンド チートシート
  -  コンフィグキャッシュファイルクリア・再キャッシュ  
`php artisan config:cache`

  - ルーティングリスト確認  
`php artisan route:list`

  - ルーティングキャッシュファイルクリア・再キャッシュ  
`php artisan route:cache`

  - ビューファイルクリア  
`php artisan view:clear`

  - クラスファイル最適化  
`php artisan optimize`

  - 各生成コマンド
    + サービスプロバイダ登録  
`php artisan make:provider TestServiceProvider`  

    + イベント  
`php artisan event:generate TestEventServiceProvider`


  - マイグレーション

    + マイグレーションテーブル作成  
`php artisan migrate:install`

    + マイグレーションテーブル削除  
`php artisan migrate:reset`

    + マイグレーション実行  
`php artisan migrate`

    + ロールバック  
`php artisan migrate:rollback`

    + リフレッシュ（ロールバック + 再マイグレート）  
`php artisan migrate:refresh`

    + リフレッシュ（シードも実行）  
`php artisan migrate:refresh --seed`

    + 指定のマイグレーション実行  
`php artisan migrate --class=CreateTestsTable`

    + 指定のシーダー実行  
`php artisan db:seed --class=SampleSeeder`

    + テストテーブル作成（テーブル作成例）  
`php artisan make:migration create_tests_table --create=tests`

    + 記事テーブルに公開日カラム追加（スキーマ変更例）  
`php artisan make:migration add_published_at_to_articles_table --table=articles`

    + 強制マイグレート実行（production環境での -y と同等）
`php artisan migrate --force`
ローカルポート食いつぶし時

/etc/sysctl.confの末尾に以下を追加。

```
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 10
```

その後、
```
sysctl -p
```
で反映。

これでローカルポートを1024-65000使える設定に。