OmniAICreator/Qiita-1.07M huggingface dataset:
amp対応htmlを作成する際、amp-imgの画像サイズ・比率をCSSでなんとかする

ちょうどamp対応する案件があったので参考までにメモとして残します。

amp対応する場合、画像は```<img>```ではなく```<amp-img>```にする必要があります。

しかし```<amp-img>```は通常のimgタグとは違い、widthとheightが必須です。
なので「記事などでどんな縦横比の画像が入るかわからない」というような場合には困ってしまいます。

# amp-imgの設定方法

## 基本

設定の仕方はこんな感じです。

```html
<amp-img src="500x800.jpg"
  width="500"
  height="800">
</amp-img>
```
ただこれでは完全に画像比率が固定されてしまいます。

## レスポンシブにする

ampはモバイルで閲覧されることになりますので、色々なスマートフォンサイズを想定してレスポンシブにしておくのがベストかと思います。

レイアウト属性```layout="responsive```を付ければ、入れた縦横の数字の比率で自動的に幅100%で伸縮するようになります。
cssの指定は必要ありません。

```html
<amp-img src="500x800.jpg"
  width="500"
  height="800"
  layout="responsive">
</amp-img>
```
ただし比率は属性値に入力したサイズで固定されるので、どんな比率の画像がくるかわからない！という場合は強制的に伸ばされて表示されてしまいます。
なので、このhtmlにした上でcssを使って調整します。

### レスポンシブの比率をcssで調整する

amp-imgのwidthとheightで固定された比率をcssで正しい比率に調整します。

```css
img{
    height: auto;
}
.i-amphtml-fill-content{
    /* amp.cssを打ち消す */
    max-height: auto;
    min-height: auto;
}
```
一応、これで画像の比率は戻ります。

またimgにmax-widthをつければ最大幅が指定できるので画像を大きくしたくないという方にはオススメです。が、そうすると左に寄ってしまい、サクッと中央に寄せることが出来ませんでした…
（ちゃんと検証してないので何か方法があるかもしれません）

この方法の欠点ですが、```<amp-img>```のwidthとheightで指定した数値の比率の枠は残ってしまいます。
なので画像の比率によっては上下左右に余白が空いてしまう（background:contain;みたいな感じ）ので、完璧な対応とまではいきません。

※amp-imgには色々な属性が用意されていますので良かったらこちらも合わせてご確認ください。
[Layout & media queries](https://www.ampproject.org/docs/guides/responsive/control_layout)


## サーバーサイドで画像サイズを計算してもらう

結局これが一番完璧です。
この方法がどうしても出来ない場合にのみcssでの調整をとりあえずの手段として検討してみてください！
エラートラッキングサービスの比較 (as of 2017/09/20)

| サービス名  | プラン名  | 価格(月額) | ユーザ数上限 | プロジェクト数上限 | データ保持期間 | エラー数ウィンドウ | 分間最大エラー数 | 月間最大エラー数 |
|-------------|-----------|------------|--------------|--------------------|----------------|--------------------|------------------|------------------|
| [Sentry](https://sentry.io/pricing/)      | small     | $26        | unlimited    | unlimited          | 90日           | 月間               | 2.314814815      | 100,000          |
| [airbrake](https://airbrake.io/pricing)    | startup   | $99        | 15           | 15                 | 90日           | 分間               | 75               | 3,240,000        |
| [airbrake](https://airbrake.io/pricing)    | growth    | $249       | 25           | unlimited          | 180日              | 分間               | 200              | 8,640,000        |
| [honeybadger](https://www.honeybadger.io/plans/) | micro     | $29        | unlimited    | unlimited          | 30日           | 月間               | 2.314814815      | 100,000          |
| [rollbar](https://rollbar.com/pricing/)     | bootstrap | $49        | unlimited    | unlimited          | 180日          | 月間               | 2.314814815      | 100,000          |
Rubyでリトライしたい時の知見

やりたいことは、もうエラーだ！ってなるまでにリトライできてsleepの秒数を1, 4, 16的な感じで増やして行きたい。

箇条書きすると

- urlアクセスする。
- 偶然にもネットワークが不調でエラー
- sleep 1秒挟んでリトライ
- 偶然にもネットワークが不調でエラー(もしくは取得できてうれしい！！)
- sleep 4秒挟んでリトライ
- 偶然にもネットワークが不調でエラー
- もうエラーだ！

# なぜリトライしたいか

- 通信は失敗するものなので!
- 失敗しない前提で作ったシステムは死ぬ

# sleepの秒数をなぜ増やしていくか

下記に則るため。

- [Exponential_backoff](https://en.wikipedia.org/wiki/Exponential_backoff)

ざっくりいうと、失敗回数が増えるに連れて再送信するまでの待ち時間を指数関数的に増やす仕組み

AWSとかGCPとかでもリトライはこの方法を使うべきと書いている(仕様が微妙にことなるみたい)。

- http://cloud-spiral.enpit.jp/wp-content/uploads/Slides_Koji.pdf (p11, p12参照)

```
Exponential Backoff
• リトライの間隔を指数関数的に増加させる
 例：１秒後、２秒後、４秒後、８秒後、、、
• 長期障害発生時にシステムへの不必要な負担を軽減
 大規模分散システム内での常に部分障害（特に一時的）が発生している
• 障害発生時にいちいちシステムを止めていては高可用性を実現できない
リトライにより後に成功する可能性が高い
```


|HTTP Status Code  | リトライ|
|:---|:---|
|200 (OK) | N/A|
|400 (Client Error) | 非推奨（回復の見込みなし）|
|500 (Server Internal Error) | 推奨
|503 (Server Unavailable) | 推奨|

- https://developers.google.com/drive/v3/web/handle-errors#exponential-backoff

# どう実装するのか

[retryable](https://github.com/nfedyashev/retryable)って言う便利gemがあるので使う

## 使い方の例

OpenURI::HTTPErrorが出たときのみリトライ
(400エラーの非推奨も合わせて実行してしまうがopen-uriの例外がこれしかない←コメントで教えてもらいました！コード修正しました)
リトライ回数は3回
リトライするまでの待ち時間を[1, 4, 16, ...]にする場合
(厳密には待ち時間に乱数をつけるべきだが省く)

```ruby
retry_setting = {
  on: OpenURI::HTTPError,
  tries: 3,
  sleep: ->(n) { 4**n }
}
Retryable.retryable(retry_setting) do |retries, exception|
  break if retries > 0 && exception.io.status[0] == "400"
  open('https://www.example.com/')
end
```

# 最後に

自前でbegin書いちゃってたんですが、Gemを使うことによってリトライ処理の書き忘れなどなくなって幸せです。
HTTP ERROR 500（wordpress）

###エラー
HTTP ERROR 500

###対処したこと
wp-config.phpのファイル所有者をapacheに設定したら直った。

###現象
ブラウザでアクセスした時に上記のエラーメッセージが出る。
sshからはアクセス可能。
apacheなども正常起動。

###原因
結果的にwp-config.phpの所有者が原因だった。
さらにその原因としては自分でshellスクリプトを組んで
DB設定をデプロイ時に書き換えており、適切に所有者の設定をしていなかった。
jsdoでカルマンフィルター

#概要
jsdoでカルマンフィルターやってみた。

#写真

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/c/v/M/cvM3.jpg?t=1505892396)

#成果物
http://jsdo.it/ohisama1/cvM3
WPFで自前のスタックトレース作った(MVVMパターン使用)

# きっかけ
WPFアプリの起動中に【アプリの画面】⇔【Visual Studioの出力画面】の行き来が面倒.
というわけで自前でWPFにそれっぽい形スタックトレースを実装してみました.
![stacktrace.gif](https://qiita-image-store.s3.amazonaws.com/0/139940/39329c62-7446-af3f-4009-37f6df56e61f.gif)


## ソース
ソースは<a href="https://github.com/nossey/StackTrace">こちら</a>
VS2017とC#6.0～が必要です.

## 使い方
↓のようなコードで「情報出力」「警告」「エラー」を表示します

```csharp:Sample.cs
using static namespace TracelogTest.Model.Command;

// Show information
Info("Information");

// Show warning
Warning("Warning");

// Show error
Error("Error");
```

右クリックから各種コピーが可能
![thumbnail2.png](https://qiita-image-store.s3.amazonaws.com/0/139940/382cdc09-4d73-7fb6-feb4-46c008899147.png)


スタックトレースをコピーするとこんな感じ
![thumbnail3.png](https://qiita-image-store.s3.amazonaws.com/0/139940/05efeae7-1a46-0697-f8df-5a0a2740d566.png)


## 実装方法
MVVMパターンで組みました. 使用インフラは<a href="http://ugaya40.hateblo.jp/entry/livet">Livet</a>です.
xamlを手探りで組んだので, Viewは色々と汚いです(苦笑)

## 感想
まともにxamlを組んだことが無かったので, 良い勉強になりました.
別エントリに得られた知見をまとめるかも知れません.

今後自分の作るWPFアプリにAvalondockでこのStack traceをくっつければ, なかなか良さそうな感じです.
Cakephp3でbootstrapを使う

#cakephpでbootstrapを使う

bootstrapをダウンロードするだけでは、cakephpで使うことが割と面倒なので、
cakephpで簡単にbootstrapを使うために

手順1
[bootstrapをダウンロード](https://getbootstrap.com/docs/3.3/getting-started/)して読み込んで下さい。

手順2
bootstrapUIのダウンロード
```composer require friendsofcake/bootstrap-ui```

```php:core/bootstrap.php
\Cake\Core\Plugin::load('BootstrapUI');
```

```php:src/View/AppView.php

namespace App\View;

use Cake\View\View;
use BootstrapUI\View\UIView;

class AppView extends UIView
{
    public function initialize()
    {
        //ここが忘れやすいので注意
        parent::initialize();
    }
}
```
これでBootstrapUIの読み込みもできてるはず

BootstrapUIの読み込み完了後、formhelper等でテストしてみて下さい。
Bootstrapに合わせたフォームが作成されているかと思います。
これでCakephpでBootstrapを使うための操作が完了です。

##おまけ
bakeする段階で下記コードでbakeするとbootstrap仕様にbakeしてくれるそう
まだ使ったことはない
```bin/cake bake template Table_name -t BootstrapUI```

やったことある方コメントくださると助かります。
Numeral.jsで序数を得る


順位表示などの国際化対応をする時に、日本語の場合だと`n位`のように`位`をつけるだけで問題ありません。
しかし英語の場合は1位は`1st`,2位は`2nd`のように序数を使用する必要があります。

このような場合には、数値のフォーマットや操作を行う[Numeral.js](http://numeraljs.com/)を使用するのが便利です。

例で上げたような序数を得るためのコードは次の通り。

```js
var string = numeral(1).format('0o');
// '1st'
```

任意の数字の序数のサフィックスだけ欲しい場合は次のように書ける。

```js
var ordinal = numeral.locales.en.ordinal(2)
// 'nd'
```
Amazon SNSを利用したSMSの一斉送信

[AmazonSNS](https://aws.amazon.com/jp/sns/?sc_channel=PS&sc_campaign=acquisition_JP&sc_publisher=google&sc_medium=sns_b&sc_content=sns_e&sc_detail=amazon%20sns&sc_category=sns&sc_segment=79839654145&sc_matchtype=e&sc_country=JP&sc_brand=brand&ef_id=WVCOiQAAAHtFSn_X:20170920052920:s)を利用して社員専用のWebサイトから社用携帯に一斉にSMS送信する機能を実装してみた。

#なぜAmazonSNS(SMS)
社内に居ない社員に対してメールのチェック等を促す手段として社用携帯への一斉Push機能を実装する事になった。
専用のスマホアプリを作成すれば[GoogleGCM](https://developers.google.com/cloud-messaging/?hl=ja)、[AppleAPNｓ](https://developer.apple.com/jp/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html)等での通知を検討するのだが一旦はそこまでの工数は掛けない方針となったのでSMSでの通知をすることになった。
ただ今後の拡張性等(GoogleGCM、AppleAPNｓ等を使うようになるかもしれない)を考えてGoogleGCM、AppleAPNｓ、SMSでの通知をSNS topicという形(後述する電話帳のようなもの)に抽象化して呼び出し元からは意識しないで実装出来るAmazonSNSでのSMS送信を選択した。

#Topicの作成
Topicと言われる一斉通知先の集合体（電話帳のようなもの）をまず作成する。

1. [SNSdashbord](https://console.aws.amazon.com/sns/home)にログイン
2. 「CreateTopic」を選択し新規作成する
    - Display NameがメールやSMSの送信元として表示される
3. Topic画面から「Create subscription」ボタンを選択することにより個別の送信先を追加する
    - 電話番号が08012345678の場合は+818012345678のように指定する
    - ここにSMS以外の通知方法を混在させることが出来る
    - Topic ARNは後で使うのでメモしておく

#送信上限値の変更
デフォルトでは**１ドル分以上のSMSが送れない**設定になっている。
これに気が付かずに途中から送れなくなりしばらくハマった。
上限引き上げの申請は[サポートに連絡](http://docs.aws.amazon.com/ja_jp/general/latest/gr/aws_service_limits.html#limits_sns)することで可能である。申請が通るには一週間位要する。

1. 申請が通ったら改めて[SNSdashbord](https://console.aws.amazon.com/sns/home)にログイン
2. 「Text messaging (SMS)」->「Manage text messaging preferences」を選択
3. 「Account spend limit」を申請した上限値に引き上げる
4. ついでに「Default message type」をTransactionalに変更すると[送信料金](https://aws.amazon.com/jp/sns/sms-pricing/)が多少上がるが到達率も上がるらしい。
    - 試してた限りではPromotionalでも問題は無さそうではあったが

#AWSアクセスキーの作成
APIを叩くときのキーを作成する

1. AWSコンソール右上の「アカウント」->「セキュリティ認証情報」を選択
2. 「アクセスキー」から「新しいアクセスキーの作成」ボタンを押下してアクセスキーを作成する
    - アクセスキーIDとシークレットアクセスキーは後で使うのでメモしておく

#aws-sdk-railsを導入
社員用WebサイトはRubyOnRailsで構築されているのでaws-sdk-railsを導入する

1. $ gem install aws-sdk　を実行
2. gem 'aws-sdk-rails'　をGemfileに追記
3. $ bundle install　を実行

#環境変数の設定
aws-sdk-railsはシークレットキー等は環境変数を参照してくれるので、それらを実行環境に設定しておく。
設定すべき環境変数は下記。

| Key                    | 説明                  |
|:-----------------------|:---------------------|
| AWS_ACCESS_KEY_ID      | アクセスキーID         |
| AWS_SECRET_ACCESS_KEY  | シークレットアクセスキー |
| AWS_REGION             | AWSのリージョン        |

#コーディング
引数msgに渡されてきた文字列を一斉送信するサンプル
リファレンスは[こちら](http://docs.aws.amazon.com/sdkforruby/api/Aws/SNS/Client.html)

```ruby:sample.rb
def send_sms(msg)
  sns = Aws::SNS::Client.new()
  arn = 'arn:aws:sns:ap-xxxxxxxxxxxxxxxxxxxx'   # Topicで作成したARN
  res = sns.publish({
    topic_arn: arn,
    message: msg
  })
end
```
無線LANアダプタを接続したダイキンエアコンをHomekitで操作する

iOS 10ではHomebridgeプラグインを作ってもHeaterCoolerサービスをHomeアプリが認識できず操作できなかったのですが、iOS 11にアップデートしたところ認識されるようになっていたので、早速プラグインを書いて見ました。

ちなみにダイキン純正アプリでは室外機のセンサで取得した屋外の気温も表示でき、これが意外と便利なのでこれも表示できるようにしたいと思います。

お約束ですが、メーカーが保証しない方法でエアコンの操作を行うためご利用の際は自己責任でお願いいたします。ここに記載された情報を試してみてエアコンが火を噴いたり白熊しか住めないような部屋になってしまったりしても一切責任は取れません。

## プロトコル

我が家ではAN80TRPにBRP072A41を接続して利用しているのですが、これの通信プロトコルは公開されていません。どうせHTTPだろうということで、mitmproxyで覗き見してみます。

mitmproxyを立ち上げてプロキシの設定をし、純正アプリを起動してみます。

![スクリーンショット 2017-09-20 15.03.16.png](https://qiita-image-store.s3.amazonaws.com/0/5827/15ce27f0-3c7b-32ce-eb37-90cf9c6b8e4c.png)

はい、バッチリ取れました。

リクエストはすべてGETで行われているようで、レスポンスはキーと値を=で繋いだコンマ区切りです。

| パス | 内容 |
|:-------------------------|:--|
| /common/basic_info       | 基本的な情報。IDやパスワードまで返ってくる（！）ので取扱注意。 |
| /aircon/get_sensor_info  | センサの情報。気温とか湿度とか。  |
| /aircon/get_control_info | 設定情報。運転モードとか。  |
| /aircon/set_control_info | 設定情報の変更 |
| /common/get_datetime     | 現在日時。 |
| /aircon/get_scdltimer_body?target=c | タイマーの情報？詳しくみてないので分かりません。 |

だいたいこんな感じです。キーは「pow」や「htemp」といったように省略形で表現されています。

とりあえず状態表示はget_sensor_infoとget_control_infoを使えばいけそうです。

## それでは実装

値の取得については上記の通りなので、エアコンの状態を変更してはリクエストを投げて値の変化を確認、という地味な作業を繰り返せば簡単に実装できました。

問題はset_control_infoでの状態の変更、電源のオンオフなどですがパラメーターが省略形なのでいまいち分かりません。特にdt1〜7、dh1〜7などは見当すらつかないので何を設定すればいいのか分かりません。

ただ、パラメーターはほぼget_control_infoと同じようなので、取得した値の,を&に置換してpowの値だけ変えてクエリ文字列として投げてみたところバッチリ電源状態が変更できたので、今回はこのまま手抜き実装で行くことにしました。

今回はエアコンなのでHeaterCoolerサービスを実装します。このサービスは以下のCharacteristicを必須としています。

* Active
* CurrentHeaterCoolerState
* TargetHeaterCoolerState
* CurrentTemperature

それから、オプションですが冷暖房の設定温度も取得できた方が便利なので以下も実装しました。

* CoolingThresholdTemperature
* HeatingThresholdTemperature

あとは、湿度も5%刻みで取得できるのでHumiditySensorサービスも追加します。湿度の設定までする場合はHumidifierDehumidifierサービスの方が良さそうですが、なんか色々面倒臭そうなのと設定まではいらねーなと思ったので今回は値の取得のみでいきます。

### 温度センサー

ところで、冒頭にも書いた通りこのエアコンでは室外機のセンサー温度も取得できます。HeaterCoolerサービスでは1つの温度しか取得できませんが、TemperatureSensorサービスも追加すれば温度表示を増やせます。

…なのですが、アクセサリは1つの部屋に属するため、同じアクセサリとして実装すると、「LDK 27℃。LDK 23℃。」みたいな何を言ってるのか分からない表示になってしまうので、別々のアクセサリとして実装した方が良いです。

## というわけで成果物

* 室内機用：https://github.com/haneco/homebridge-daikin-aircon
* 室外機用：https://github.com/haneco/homebridge-daikin-aircon-outdoor

npmモジュールも公開したので、興味のある方はどうぞ。
C++ Builder XE4, 10.2 Tokyo | Indy > TIdStackの使用 > IdComponent.hppをincludeする

```txt:動作環境
C++ Builder XE4
   Indy 10.6.0.4975

RAD Studio 10.2 Tokyo Update 2 (追記: 2018/01/05)
   Indy 10.6.2.5366
```

[C++ Builder / Indy > 自分のIPアドレスを取得する実装](https://qiita.com/7of9/items/d9a96eaaeeca22312589)
にて実装した自IPアドレスを取得しようとした。

`TIdStack::IncUsage();`
にてエラーが出た。

> [bcc32 エラー] XXX.cpp(76): E2090 型限定子 'TIdStack' がクラス名または名前空間名ではない

対象のフォームはIndyのコンポーネントを一つも持っていない。

以下を追加することで、`TIdStack`が使えるようになった。

`#include <IdComponent.hpp>`

### 補足

TIdUdpClientを追加した時、includeされたhppファイルの中から上記を見つけた。
Python 3 で16進数とバイト列の相互変換



## 概要

文字列のテストデータを動的に生成する場合、16進数とバイト列の相互変換が必要になります。整数とバイト列、16進数とバイト列の変換だけでなく表示方法にもさまざまな選択肢があります。文字列とバイト列の相互変換について調べた記事は[こちら](https://qiita.com/masakielastic/items/2a04aee632c62536f82c#%E6%96%87%E5%AD%97%E3%83%90%E3%82%A4%E3%83%88%E5%8D%98%E4%BD%8D%E3%81%AE%E5%B1%95%E9%96%8B)の記事に分割しました。



## 整数と16進数文字列の相互変換

ビルトインの `format` 関数や `hex` を使うことができます。Python 2 系との互換性を保つのであれば、`%` を使います。

```python
>>> format(0xabcd, 'x')
'abcd'
>>> hex(0xabcd)
'0xabcd'
>>> '%02x' % 0xabcd
'abcd'
```

str.format も使うことができます。

```python
>>> '{:02x}'.format(0xabcd)
'abcd'
```

16進数文字列を整数に変換するには `int` を使います。

```python
>>> int('0xabcd', 16)
43981
>>> int('abcd', 16)
43981
```

## 16進数文字列とバイト列の相互変換

### bytes.fromhex と bytes.hex

`bytes.fromhex` と `bytes.hex` は組み込みのメソッドです。`bytes.hex` は Python 3.5 で追加されました。

```python
>>> bytes.fromhex('abcd')
b'\xab\xcd'
>>> b'\xab\xcd'.hex()
'abcd'
```

### binascii.unhexlify と binascii.hexlify

`binascii` モジュールをインポートする必要があります。

```python
>>> import binascii
>>> binascii.unhexlify('abcd')
b'\xab\xcd'
>>> str(binascii.hexlify(b'\xab\xcd'), 'utf-8')
'abcd'
```

エイリアスも用意されています。

```python
>>> binascii.a2b_hex('abcd')
b'\xab\xcd'
>>> str(binascii.b2a_hex(b'\xab\xcd'), 'utf-8')
'abcd'
```

### codecs.decode と codecs.encode

`binascii.a2b_hex()` と `binascii.b2a_hex()` と同じとマニュアルに明記されています。

```python
>>> import codecs
>>> codecs.decode('abcd', 'hex')
b'\xab\xcd'
>>> codecs.encode(b'\xab\xcd', 'hex')
b'abcd'
>>> str(b'abcd', 'utf-8')
'abcd'
```

`codecs.getdecoder` と `codecs.getencoder` はタプルを返します。

```python
>>> codecs.getdecoder('hex')('abcd')
(b'\xab\xcd', 4)
>>> codecs.getencoder('hex')(b'\xab\xcd')
(b'abcd', 2)
>>> str(b'abcd', 'utf-8')
'abcd'
```

## 整数とバイト列の相互変換
### int.to_bytes と int.from_bytes

Python 3.2 から利用できます。

```python
>>> """ https://stackoverflow.com/a/30375198/531320 """
>>> x = 0xabcd
>>> x.to_bytes((x.bit_length() + 7) // 8, byteorder='big')
b'\xab\xcd'
>>> format(int.from_bytes(b'\xab\xcd', byteorder='big'), 'x')
'abcd'
```

### struct.pack と struct.unpack

`struct.pack`、`struct.unpack` で使えるフォーマットの記号の意味はほかのプログラミング言語と異なります。

```python
>>> struct.pack('BB', 0xab, 0xcd)
b'\xab\xcd'
```

リストをパックして渡すことができます。

```python
>>> x = [0xab, 0xcd]
>>> struct.pack('B'* len(x), *x)
b'\xab\xcd'
```

`struct.unpack` はタプルを返します。

```python
>>> x = b'\xab\xcd'
>>> struct.unpack('B' * len(x), x)
(171, 205)
```

### 16進数文字列経由

整数を16進数文字列に変換してから文字列に変換する方法もあります。メリットは整数の桁数を指定しなくてよいことです。

```python
>>> bytes.fromhex(format(0xabcd, 'x'))
b'\xab\xcd'
>>> b'\xab\xcd'.hex()
'abcd'
>>> int(b'\xab\xcd'.hex(), 16)
43981
>>> 0xabcd
43981
```
Eloquentモデルを継承したときに、親モデルのクエリを発行したい

## 問題となるケース
* Illuminate\Database\Eloquent\Modelを継承したParentModelがある
* ChildModelはParentModelと共通な部分が多いので、ParentModelを継承して実装したい
* ChildModelのnameが空だったらParentModelのnameを返すgetNameAttribute()を実装したい
* ChildModel内のメソッドで、ParentModel::where()を使ったのに、ChildModelが返ってきた←！？

環境はPHP7.0、Laravel 5.1（5.5にアップデートしなきゃ）

``` php:ChildModel.php
class ChildModel extends ParentModel
{
    public function getNameAttribute()
    {
        if ($this->name) {
            return $this->name;
        }

        if ($parent = ParentModel::where('id', $this->id)->first()) {
            // $parentにChildModelが入ってきてしまう
            return $parent->name;
        }

        return '';
    }
}
```

## 原因の調査
Model.phpのソースを読んでみたところ、そもそもwhere()はstatic functionとして定義されていなかった。
ではどうやって動いているのか調べていくと、\_\_call()や\_\_callStatic()といったマジックメソッドにフェイルオーバーされるらしい。
http://php.net/manual/ja/language.oop5.overloading.php#object.callstatic


``` php:Illuminate/Database/Eloquent/Model.php
    /**
     * Handle dynamic method calls into the model.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        if (in_array($method, ['increment', 'decrement'])) {
            return call_user_func_array([$this, $method], $parameters);
        }

        $query = $this->newQuery();

        return call_user_func_array([$query, $method], $parameters);
    }

    /**
     * Handle dynamic static method calls into the method.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     */
    public static function __callStatic($method, $parameters)
    {
        $instance = new static;

        return call_user_func_array([$instance, $method], $parameters);
    }
```

ChildModel内でParentModel::where()を呼び出すと、where()自体はParentModelのものが呼ばれるのだが、new static（遅延静的束縛）でChildModelが生成されてしまうのだと思う。

## 解決方法
\_\_callStatic()を見ると、結局のところインスタンスを生成してcall\_user\_func\_array()に渡しているので、先にインスタンスを生成してしまって\_\_call()が呼ばれるようにすればいい。

``` php:ChildModel.php
class ChildModel extends ParentModel
{
    public function getNameAttribute()
    {
        if ($this->name) {
            return $this->name;
        }

        if ($parent = (new ParentModel())->where('id', $this->id)->first()) {
            return $parent->name;
        }

        return '';
    }
}
```

考えてみると、今回の場合はrelationを定義したほうが分かりやすかったので、結局そうした。

``` php:ChildModel.php
class ChildModel extends ParentModel
{
    public function parent()
    {
        return $this->belongsTo('App\ParentModel', 'id', 'id');
    }

    public function getNameAttribute()
    {
        if ($this->name) {
            return $this->name;
        }

        if ($parent) {
            return $parent->name;
        }

        return '';
    }
}
```

## まとめ
確かに、遅延静的束縛でstaticをどこに束縛したいかはケースによって変わってくるので、この仕様は仕方ないのかもしれない。
あまりしっかりと考えて使ったことがないので、もっといい解決法があればコメント頂けると幸いです。

それにしても、PHPのstaticキーワードは使われ方によって全く違う意味になってくるので紛らわしい...
Laravelで掲示板作成

## 目的
インフラ基礎, Web開発の基礎を身につけるためにWeb掲示板を作る

 <br><br><br>

## 仕様
・構成はトップページ, 新規投稿画面, コメント返信画面
・掲示板の各書き込みには返信可能
・返信があった書き込みを昇順で表示

 <br><br><br>
## 環境
|　|バージョン等|
|:--:|:--:|
|開発環境|docker|
|仮想マシン|centOS7|
|言語|php7.0.22,     html5|
|フレームワーク|Laravel Framework 5.4.30|
|データベース|mysql 14.14|

 <br><br><br>

## 大まかな手順

参考サイトを全て覚えているわけではないので、コマンド等間違っている箇所があるかもしれないです

<br>

### 1.Dockerの中にcentOSの仮想マシンを構築
http://qiita.com/zwirky/items/991f61a231f4e198a320

<br>

http://tech.pjin.jp/blog/2015/11/13/docker%E3%81%A7%E3%81%82%E3%81%9D%E3%81%B6%EF%BC%88%EF%BC%92%EF%BC%89centos7%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B/

<br>

### 2.作ったマシンにssh公開鍵認証でログインできるようにする

<br><br>

### 3.仮想マシンの中にphp, apache, larval, mysqlをインストール
#### php
```
yum -y install php
```
<br>
#### ApacheのOfficialイメージをダウンロード
```
docker pull httpd:latest
```
<br>
#### laravel
Conposerを用意

```
curl -sS https://getcomposer.org/installer | php
```
```
mv composer.phar ~/bin/
``` 

laravelをインストール

```
composer global require "laravel/installer"
```

<br>

#### mysql

```
docker pull mysql
```

 <br><br><br>

## テーブル定義
新規投稿画面

<img width="458" alt="スクリーンショット 2017-09-05 11.26.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/203246/037fcf05-b6bb-d12e-02e3-2c5a734d6505.png">



<br>

コメント返信画面
<img width="461" alt="スクリーンショット 2017-09-05 11.26.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/203246/d272ae92-89df-ae61-b2be-326c44379d3a.png">




 <br><br><br>




 <br><br><br>

## よく使用したコマンド
```
//コンテナを起動
docker exec -it コンテナ名 bash


//mysqlにログイン
mysql -uroot -pパスワード



//サーバーを起動
php artisan serve --host 0.0.0.0


//mysql
select comment comments\G;

select * from comments;

//更新されたログを順次出力
tail -f laravel.log

//seederを流す
php artisan db:seed --class=シーダー名


//マイグレーションのロールバック
php artisan migrate:rollback

//マイグレーションの実行
php artisan migrate

```

<br><br><br>

## スクリーンショット
トップページ


<img width="960" alt="スクリーンショット 2017-09-20 15.32.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/203246/73c4cea9-4b28-3381-3200-8176d07bb07a.png">


<br>




新規投稿画面


<img width="960" alt="post.png" src="https://qiita-image-store.s3.amazonaws.com/0/203246/8365f9a1-badb-9702-5467-dbe8cfade991.png">

<br>

コメント返信画面

<img width="960" alt="スクリーンショット 2017-09-20 15.32.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/203246/3274c3ec-a216-4945-e3bd-81e9b78edd5f.png">



<br>

モーダルで確認表示


<img width="960" alt="modal.png" src="https://qiita-image-store.s3.amazonaws.com/0/203246/e04cc1f7-4eb5-6a13-8408-5da9d5fd2003.png">



 <br><br><br>



 <br><br><br>
MVCという概念

# 目的
laravelで掲示板を作成する際のMVCという概念についての理解を深める

<br/>

## MVCとは
> MVC（Model View Controller モデル・ビュー・コントローラ）は、ユーザーインタフェースをもつアプリケーションソフトウェアを実装するためのデザインパターンである。
アプリケーションソフトウェアの内部データを、ユーザーが直接参照・編集する情報から分離する。そのためにアプリケーションソフトウェアを以下の3つの部分に分割する。
参照：https://ja.wikipedia.org/wiki/Model_View_Controller

<br/>

MVC相関図

![500px-MVC-Process.svg.png](https://qiita-image-store.s3.amazonaws.com/0/203246/0f19cd49-fbd6-f831-116d-e4a1d8fa1bdb.png)


<br/>
<br/>

## Model
Model（モデル）は、一般的にビジネスロジックと呼ばれる部分。アプリケーションデータやビジネスルール、関数、データベースへのアクセス、データ管理などを担当。ビジネスロジックそのものを担当するため、UIの変更などの影響を受けにくいという利点がある。

> swiftで例えるとサーバ通信をするクラス。データを扱う。

今回はPost.php, Comments.phpがModelにあたり、モデルと関連しているテーブル, 使用するコネクション名実装した



<br/>


## View
View（ビュー）は、レイアウト部分。UIを表示するコンポーネントであり、データ入力フォームやグラフ、図などデザインやレイアウトに関わるアプリケーションのフロントエンドを担当。

> swiftで例えるとxib。テンプレート。

laravelでいう◯◯.blade.php
今回はindex.blade.php, post.blade.php, comment.blade.phpがViewにあたり、各ページに表示する内容をviewで実装した



<br/>

## Controller
Controller（コントロール）は、ModelとViewの仲介役。Viewから受けたデータをModelに渡して、Modelでの処理結果をViewに戻す役割。

> swiftで例えるとVCL。制御。

laravelでいう◯◯Controller.php
今回はPostsController.php, CommentsController.phpがControllerにあたり、index( ), store( )メソッドをcontrollerで実装した

<br/>

## MVCモデルのメリット
MVCモデルを採用する事で機能ごとの分離が明確になり、独立性が確保される。分業して開発が行いやすく、自分の得意分野に集中して実装することが可能。デザイナーがViewを担当している間に、プログラマーがModelを修正するなどと分業することが可能。また、コンポーネント間の依存性が抑えられることにより、ほかの部分を変更しても、その影響を受けにくいメリットがある。

<br>


参照:https://furien.jp/columns/262/
CognitoUserPoolのトークン整理

# 概要

サインインを必要とするサービスを作る時に、Cognitoは非常に便利ですよね。
Cognito自体の概要やサインイン・サインアップは他記事にお任せして、今回はCognitoUserPool(以降UserPool)でサインイン後(認証後)にUserPoolから返される、各種トークンについて整理しました。

[Cognito公式](http://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html)

# トークンの種類

UserPoolは認証後、以下のトークンをクライアントに返します。

* IDトークン
* アクセストークン
* 更新トークン

上記3つのトークンはそれぞれ使い方や性質が違います。

## IDトークン

* JSONWebToken(JWT)
* 認証したユーザーIDに関するクレームが含まれる。
* リソースサーバーまたはサーバーアプリケーションに対するユーザーの認証に使用できる。
* WebAPIに対してアプリケーション外で使用する場合、IDトークン内でクレームを信頼する前に、IDトークンの署名を確認する必要がある。
* IDトークンは、ユーザーが認証した1時間後に有効期限切れになる。

## アクセストークン

* JSONWebToken(JWT)
* UserPoolのユーザーのコンテキストを操作する。
* 対象のCognitoIDに対してアクセストークンを使用して、ユーザー属性を更新、削除が可能。
* アクセストークンは、ユーザーが認証した1時間後に有効期限切れになる。

## 更新トークン

* 新しいIDトークンまたはアクセストークンを取得するためCognitoに対してのみ使用する。
* デフォルトでは、ユーザーが認証した30日後に有効期限切れになります。(1日～3650日で指定可能)
* 更新トークンを使用して新しいトークンを取得するには、AdminInitiateAuthAPを使用する。
    * 更新トークンが正しければ、Cognitoサーバーでトークン更新プロセスが開始され、新しいIDトークンとアクセストークンが返される。

# 終わり

JWTの概念がかなり多様されています。
次回はJWTの概要と実際にCognitoを利用したサインアップ・サインインフローについてまとめようと思います。
Reactで動的に行を追加するFormの書き方

これは、[初心者歓迎！Reactとvte.cxでWebアプリケーションを作成する#2<動作確認〜ソース解説>](https://vtecx.connpass.com/event/65163/)の説明に使う予定の資料です。

[Reactで扱うFormとEntityの管理について](https://qiita.com/stakezaki/items/cbbfbf23e107b60859c9)の関連で、動的に入力フォームを追加するにはどうすればいいかについて説明します。以下のような入力行を追加するようなやつです。

![develop.gif](https://qiita-image-store.s3.amazonaws.com/0/17472/628a6793-35c8-557f-8139-d01a9c062455.gif)

###ソース解説

趣味の入力行は、HobbyFormコンポーネントとして定義され、以下のように``this.state.feed.entry[0].hobby[]``配列の件数分、this.HobbyForm()が呼ばれるようになっています。keyは、Reactでtableを表示する際に必要なものでユニークな番号を与えます。(これはお決まりだと覚えてください）

```html
<ControlLabel>趣味</ControlLabel>
<table className="table">
	<thead>
		<tr>
			<th>タイプ</th>
			<th>名前</th>
		</tr>
	</thead>
	{this.state.feed.entry&&
     this.state.feed.entry[0].hobby&&
     this.state.feed.entry[0].hobby.map((row, key) => this.HobbyForm(key))}
</table>
```

HobbyFormでは、FormControlで指定しているhobby_typeやhobby_nameに注目してください。
これらは冒頭において、'hobby_type'+keyのように番号のついた名前が定義されます。
これによって、複数行の名前の衝突を防ぐようになっています。``<tbody key={key.toString()}>``も忘れないように記述してください。これはReactのお決まりだと覚えてください。

```html
	HobbyForm(key:number) {
		const hobby_type = 'hobby_type'+key
		const hobby_name = 'hobby_name'+key
		return(
			<tbody key={key.toString()}>
				<td>
					<Col sm={8}>              
						<FormGroup controlId={hobby_type}>
							<FormControl componentClass="select" placeholder="select" value={this.state[hobby_type]} name={hobby_type} onChange={(e)=>this.handleChange(e)}>
								<option value="屋内">屋内</option>
								<option value="屋外">屋外</option>
								<option value="その他">その他</option>
							</FormControl>
						</FormGroup>
					</Col>
				</td>              
				<td>
					<Col sm={8}>              
						<FormGroup controlId={hobby_name}>
							<FormControl type="text" placeholder="hobby" value={this.state[hobby_name]} name={hobby_name} onChange={(e)=>this.handleChange(e)} />
						</FormGroup>
					</Col>
				</td>
			</tbody>
		)
	}
```

最後に、行が追加されたときに呼ばれるメソッドについてです。

```javascript
	addRow() {
		this.setState((prevState) => ({
			feed: ((prevState) => { 
				if (!prevState.feed.entry[0].hobby) {
					prevState.feed.entry[0].hobby = []
				}
				prevState.feed.entry[0].hobby.push({ type: '', name: '' })
				return prevState.feed				
			})(prevState)
		}))			
	}
```

stateに``feed.entry[0].hobby[]``を保持していますが、子要素であるhobby配列に値を追加しても再描画は実行されません。stateの再描画が反応するためにはfeed自体を更新する必要があり、その子要素であるhobby配列に追加した関数の実行結果であるfeedをsetStateに渡す必要があります。

また、上記JSXの例では、stateを使って、``value={this.state[hobby_type]}``のように値を確保していますが、実はstateの外に定義した統一的なエンティティで管理すれば無駄もなくきれいな形になります。

詳しくは、[Reactで扱うFormとEntityの管理について](https://qiita.com/stakezaki/items/cbbfbf23e107b60859c9)を参照してください。
dockerの既存コンテナをベースに新規コンテナを作成する

## 目的
dockerの既存コンテナをベースに新規コンテナを作成する

<br>

## 問題
コンテナを作成ごとに種々をインストールして設定するのが大変 

<br>

## 解決策
一度設定したコンテナを使い回す

<br>

## 方法
exportしたいコンテナをストップ

```
docker stop コンテナID
```

exportする

```
docker export コンテナID > 名前.tar
```

importする

```
docker import 名前.tar 名前:タグ名
```

importできたか確認

```
docker images
```


importしたものを土台にしてコンテナを作成

```
docker run --privileged -it -d -p 8888:8000 -p 12345:22 --name コンテナ名 イメージID /sbin/init
```
<br>

## オプション

--privileged
起動するコンテナに権限を与えることができる。

-i
標準入力(STDIN)を開いたままにする

-t
擬似ttyに接続する。ディスプレイ(STDOUT)をつなぐイメージ

-d
停止しても自動的に削除されない

--name
コンテナ名を指定することができる

よく使うDockerコマンド
http://qiita.com/noralife/items/18301143c20cc5172c56

<br>

## ポート番号
ポート番号
http : 80
https : 443
ssh : 22

<br>

TCPやUDPにおけるポート番号の一覧
https://ja.wikipedia.org/wiki/TCP%E3%82%84UDP%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7%E3%81%AE%E4%B8%80%E8%A6%A7
MySQL/MariaDBのCLIコンソールのプロンプトを変更する

いまさら感はありますが、、複数台のDBサーバを管理していると、どこに接続しているのかわからなくなるため。。

## それぞれのログインで以下をコピペ

```bash
cat << '_EOT_' > ~/.my.cnf
[mysql]
prompt='\\u@\\h [\\d] >\\_'
_EOT_
```

## ログインするとこんな感じになります

```
$ mysql -uuser -p -Dmy_database -hdb01.localhost.com

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

user@db01.localhost.com [my_database] >
```

[参考] というか、そのまんまですが、すごくわかりやく書いてます。私はいままでこれを、my.cnfに書いていましたが、.my.cnfなんですね（汗）

http://nippondanji.blogspot.jp/2009/03/mysql.html
create-react-appを使ったCordovaアプリケーション開発の流れ

## 事前準備

この記事はWindows環境で検証しています。以下のソフトウェアは入っている前提です。

- Windows版node.js　[6.10.3]
- Windows版Oracle JDK　[1.8.0]

Apache Cordovaのインストール

```
> npm install -g cordova
```

create-react-appのインストール

```
> npm install -g create-react-app
```

## アプリケーションの作成

普通にCordovaアプリケーションを作成し、その中にUI開発用にReactアプリケーションを作成します。

```
> cordova create myapp com.hoge.myapp MyApp
> cd myapp
> cordova platform add browser --save
> cordova build
（その後の処理のためにまずビルドします）
```

```
> create-rect-app reactsrc
（時間がかかります）
> cd reactsrc
```

create-react-srcで生成されたpackage.jsonを編集します。

```json:package.json
{
  "name":"reactsrc",
  "version":"0.1.0",
  "private":true,
  "homepage":".",  //この行を追加（注1）
  ※中略
  "scripts": {
    ※以下の行を編集（注2）
    "build": "react-scripts build && ((robocopy .\\build ..\\www /MIR) & exit 0)",
    ※以下略
  }
}
```

注1. Reactでビルドする時に、index.htmlが正しいフォルダ（build）に配置する（多分）

注2. Reactでビルドした結果を、Cordovaのソースフォルダ（www）にコピーする

## アプリケーションの開発

Reactでビルドすると、Cordovaのwwwが上書きされる。念のため、www_orgなど適当な名前にコピーしてバックアップしておきます。

create-react-appで生成したReactの初期ページ（public/index.html）は、Cordova向きではないため、Cordova側のindex.htmlを参考にindex.htmlを作成します。

```html:reactsrc/public/index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src *; connect-src *;style-src *; media-src *; img-src 'self' data: content:;">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<!-- その他、フォントやCSSを必要に応じて追加します -->
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="cordova.js"></script>
</body>
</html>
```

Cordovaアプリケーションの場合、デバイス関連プラグインの準備完了をあらわすdevicereadyイベントでUIのレンダリングを行う必要があります。Reactの初期スクリプト（index.js）を以下のように修正します。

```js:reactsrc/src/index.js
const startApp = () => {
  ReactDOM.render(
    <App />, document.getElementById('root')
  )
}
if (!window.cordova) {
  startApp()
} else {
  document.addEventListener('deviceready', startApp, false)
}
```

## 開発ルーチン

1. React側でコーディング（reactsrc/srcフォルダ）
  - Cordovaイベント（deviceready、pauseなど）はindex.jsに書く
  - アプリケーションのロジックはApp.jsやその他コンポーネントに書く
2. Reactのビルド `npm run build`
3. Cordovaのビルド `cordova build`

## ToDo
Cordovaプラグインの機能を使うコードがあると、Reactのビルドで失敗します。グローバルスコープにCordovaプラグインのオブジェクトがあるかどうかを確かめてから実行するようにして回避できましが、このやり方でよいのか微妙なところです。（そのうち記載）
hubのアンインストールで手こずった話

## 事故紹介
とある会社で、 GitHub Enterprise に日報を上げてる @amooon だよ
プルリクとか自動化させたいなーと思い、やらかしたことをメモする

## hub っていうの便利そ〜
コマンドでプルリクを出すことができるらしい hub というのを見つけ、インストール＆設定
当方、 zsh を使用

```console:console
$ brew install hub
$ echo 'function git(){hub "$@"}' >> ~/.zshrc
$ source ~/.zshrc
```

「わーい、これでいろいろ自動にできるぞ〜！」

## アンインストールしよう
便利だなーと一瞬思っていたところ、 GitHub **Enterprise** だと、いろいろややこしいことが判明したので、
後日やろうと思い、 hub を一旦アンインストールすることにした

```console:console
$ brew uninstall hub
$ vim ~/.zshrc
$ # 'function git(){hub "$@"}' を消す
$ source ~/.zshrc
```

さーて戻った戻った
ところがどっこい

```console:console
$ git
git: command not found: hub
```

git コマンドが使えなくなったでござる
あれれ〜？となった

```console:console
$ which git
git () {
	hub "$@"
}
```

消したはずのものが、何故か残っていた
このあといろいろしても治らず

## 解決方法(?)
`.zshrc` に書いたものが、どこかしらに反映されてしまうのであれば、
上書きしてしまえばいいと思い、試した

```console:console
$ echo 'function git(){git "$@"}' >> ~/.zshrc
$ source ~/.zshrc

$ vim ~/.zshrc
$ # 'function git(){git "$@"}' を消す
$ source ~/.zshrc

$ brew install git
```

これで治った。逆にこの手順じゃないと治らない
この手順をしなければいけない理由が全く分からないまま、解決した
どこにも情報がないように思えたので 初Qiita
【Swift3】要求バージョンの指定

swiftではバージョンに依存する構文があるのでコードにより判定し, バージョンに見合った処理を書くことが推奨されている

<br>

# 判定方法
## コード内で判定する

```swift

if #available(引数) {
  /*コード*/
}else{
  /*コード*/
}
```

```swift:example.swift
// iOS 10以降を要求
if #available(iOS 10, *) { 
  /*コード*/
}else{
  /*コード*/
}
```

<br>


## Attributeで指定する
```swift
@available(引数) 
func f() {
     
}
```
```swift:example.swift
// iOS 10以降を要求
@available(iOS 10, *) 
func f() {
     
}
```
<br>

## 引数内の記載について
最初の引数はプラットフォーム名


#### プラットフォーム名
・iOS
・iOSApplicationExtension
・OSX
・OSXApplicationExtension
・watchOS
・watchOSApplicationExtension
・tvOS
・tvOSApplicationExtension
・* (全プラットホーム)

### その他
・利用不可 : unavailable
・導入 : introduced=version number
・非推奨 : deprecated=version number
・廃止 : obsoleted=version number
・メッセージ : message=""
・名称変更 : renamed="新しい名前"


などもある

<br>
<br>

### 参考
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Attributes.html
何時だって悩んでいる自分へ

# 何時だって悩んでいる自分へ
仕事上、孤独で、悩んではグルグルしだす自分を励ます的な感じで書いとく。
## 気にしすぎてはいけないこと
### 自分が書いたコードを疑いすぎるな！
見直しは当然必要だが、なんでもかんでも他にもっといい書き方があるんじゃないかと思うな！きれいに書けてる時はだいたい大丈夫だ！
### 命名にこだわりすぎるな！
言語基準に沿うのは当然だし、その命名がおかしくないか考えるのはいいが、テスト済やリリース済のコードまで見直すな！ちゃんとその時に悩んだはずだろう！
### さっき見た書き方に惑わされるな！
調べ物してパッと見た書き方をすぐに模倣しようとするな！それが正しいとは限らないし、自分にあっているとも限らない！
### 粒度の細かいリファクタリングに凝りすぎるな！
少しくらいの重複コードは受け入れろ！切り出すと細かな差異を埋める方法を考えなきゃいけなくなるパターンがほとんどだろ！読めば分かるコードが読んでも分からんコードになるぞ！
### 異なるプロジェクトのライブラリのマイナーバージョンの差異を気にしすぎるな！
プロジェクト間のライブラリのバージョンを揃えたい病を我慢しろ！連携・依存がないんだったら気にするな！
### クロスプラット？
社内にあるのはWindowsとiPadだけだ！
## やってはいけないこと
### ブランチを切り忘れるな！
基本！
### 先を見過ぎて機能を広げすぎるな！
将来、○○する可能性が…ってキリが無いことを考えすぎるな！今必要な仕様でスコープを一旦切れ！よっぽど変な構築してなきゃどうにかなるようにしているはずだ！
### DBや構造の破壊的変更に手を染めるな！
最初に良く考えて決めたはず！ちょっと気にくわない位で破壊的変更をするな！本当に必要な時まで我慢しろ！
### 他の言語で同じもの書いてみようかなぁとか思うな！
それは暇な時にしろ！そして書いてたものを途中で放置して忘れるな！
## こうでありたい
### 各言語の仕様、特徴、新機能をきちんと把握できている
最近使ってない言語でもちゃんと理解しておきたいよね！
### その言語の使い方に自信を持つ
上記とちょっと被るけど、自信を持って書きたいよね！
### 流行、廃りに流されすぎない
情報が無い、情報が無いって毎度繰り返さない人間になりたい！世の中で継続して使われているものを馬鹿にしてはいけない！
## まとめ
何かだんだん泣き言になっていきそうだけど、思いついたら追記しよう。
【Swift3】indexPathについて

## indexPathの記法がSwift3で変更されている

### swift2まで

```
NSIndexPath(forRow: Int, inSection: Int)
```

<br>

### swift3

```
IndexPath(row: Int, section: Int)
```

<br><br>

自動変換では対応してくれないので注意

https://stackoverflow.com/questions/38382481/how-has-the-nsindexpath-initialization-changed-in-swift3
【Swift3】Rxswiftの記法変更に伴って

## RxSwiftの記法がSwift3で変更されている

### swift2まで

```swift
.subscribeNext( { } )
```


```swift
rx_response
```

```swift
switch observedEvent {
        case .Next(let value):
            ()
            
        case .Error(let error):
            ()
            
        case .Completed:
            ()
        }
```

<br>

### swift3

```swift
.subscribe(onNext: { } )
```

```swift
rx.response
```

```swift
switch observedEvent {
        case .next(let value):
            ()
            
        case .error(let error):
            ()
            
        case .completed:
            ()
        }
```

<br>
<nr>

自動変換では対応してくれないので注意

http://qiita.com/touyoubuntu/items/d40d2603aa066d48887e
Xcodeでのオブジェクトの上下配置について

# 目的
xibファイルを作る際にオブジェクトが重なってしまい上手く配置できなかったのでメモ

## １．storyboardの「Arrange」を使用する
storyboard画面で位置関係を決めたいオブジェクトを選択→「Editor」→「Arrange」
> 「Send to Front」（最前面へ）
> 「Send to Front」（最背面へ）
> 「Send Forward」（一つ前面へ）
> 「Send Backward」（一つ背面へ）  



## ２．storyboardの「●●Scene」を使用する
storyboard画面で部品構成の「●●Scene」を開く
ここに●●（ViewController名）に含まれるオブジェクトが全て表示されているので,  ドラッグアンドドロップで上下に移動することで前面背面設定ができる。 **下のほうが前面方向である**  
## まとめ
・他にもコードで移動処理を行うことができるが上記の二つが簡単
・xibを作成していく上で位置関係の構成を2の方法で考慮しつつ作ると良いかもしれない
CocoaPodsの環境構築について

## CocoaPodsの環境構築
( https://github.com/wantedly/swift-rss-sample )をswift3で作り変える際にcocoapodsの設定と更新が更新が必要だったので記述

<br>

CocoaPodsのインストール

```
sudo gem install cocoapods
```

<br>
インストール後

```
pod setup
```

<br>

#### CocoaPodsを使っているプロジェクト側ですること
1.プロジェクトのディレクトリに移動する  
2.Podsディレクトリを削除 
 
```
sudo rm -fr Pods/
```
3.Podsを更新 
 
```
pod update
```
MacBookProでTouchBarのスクリーンショットを撮る

`Command（⌘）+ Shift（⇧）+ 6`
でTouchBarのスクリーンショットを撮ることができる。

ちなみにSafariはこんな感じでTouchBarに対応してます。
![Touch Barショット 2017-09-20 15.06.59.png](https://qiita-image-store.s3.amazonaws.com/0/29971/fb1b762f-7010-e379-8598-7bc79e46f88a.png "Touch Barショット 2017-09-20 15.06.59.png")
ClangのPython bindingを使ったC++の関数定義部の特定

# モチベーションと結果
gitリポジトリを解析して、リビジョンAからリビジョンBの間でC++のどの関数が修正されたか特定したかったので、そもそも関数定義はどこの行で行われているかを特定するための方法を調査した。
ClangのPython bindingを使うことで、xxxという関数が何行目から何行目までで定義されているというような情報が取得できることが分かった。

元々がコンパイラなだけのことはあり、関数定義部だけでなく、変数定義部や二項演算子部やRETURN箇所等いろいろ取れるので、node.kind.nameの部分を適当に変えればいろいろできるだろう。

# セットアップ
## clangのpython bindingのインストール
Macな人は以下で良さそう。
http://asdm.hatenablog.com/entry/2015/01/08/170707

Ubuntuな人は、python bindingを使うためにはソースコードからビルドが必要のようだ。以下を参考にビルドする。
https://clang.llvm.org/get_started.html
https://blog.fenrir-inc.com/jp/2011/07/clang_syntax_analysis_interface_with_python.html

# 解析対象
[ここ](http://d.hatena.ne.jp/osyo-manga/20140116/1389882856)のtest.cppを対象にさせてもった。

```cpp:test.cpp
struct X{
    int value;

    void
    func(){}
};

int
plus(int a, int b){
    return a + b;
}

namespace hoge{
    int
    minus(int a, int b){
        return a - b;
    }
}

int
main(){
    plus(1, 2);
    hoge::minus(3, 5);
    return 0;
}
```

# 解析コード
```py:analyze.py
import clang.cindex
from clang.cindex import Index
from clang.cindex import Config

def print_method_area(node):
    if (node.kind.name == 'FUNCTION_DECL'):
        print "file : %s" % node.extent.start.file
        print "function : %s" % node.displayname
        print " from line:%s column:%s" % (node.extent.start.line, node.extent.start.column)
        print " to   line:%s column:%s" % (node.extent.end.line, node.extent.end.column)
    for child in node.get_children():
        print_method_area(child)

index = Index.create()
tu = index.parse("test.cpp")
print_method_area(tu.cursor)
```

# 出力
```shell-session
$ python analyze.py

file : test.cpp
function : plus(int, int)
 from line:8 column:1
 to   line:11 column:2
file : test.cpp
function : minus(int, int)
 from line:14 column:5
 to   line:17 column:6
file : test.cpp
function : main()
 from line:20 column:1
 to   line:25 column:2
```

# 補足
include文なんかが入っていると、include先のファイルまで解析が実施される。include先を除去するには、node.extent.start.fileをチェックして解析対象ファイル以外はprintしないようにしてやれば良い。
そもそもの解析を止める方法もありそうだが。
【Swift3】xibについて

## xib
Interface Builderを使ってカスタムパーツを作ることにより各所に使い回すことができる



#### xibを使用したカスタムビューの作成方法
- https://terakoya.site/ios-dic/ios-dic-customview/

#### UITableViewCellをXIBファイルでカスタムセルにする
- http://programming-beginner-memo.com/?p=110

<br>
<br>



#### △注意すること△
> xibで作ったcustomCellをtableViewCellに適用させた場合, セルタップからのイベントサイクルが変わるためStoryboardに設定しているSegueが無効になってしまう. それによりカスタムセルを設定すると画面遷移しなくなる.

<br>

## 解決策
didSelectRowAtを使い, cellがタップされた時にsegueを発生させる必要がある

```swift

//cellがタップされた時
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        //xibカスタムセル設定によりsegueが無効になっているためsegueを発生させる
        self.performSegue(withIdentifier: "segue名", sender: self.tableView)
        
    }
```

<br>


参照
- https://www.slideshare.net/satoshianai/xib
- http://qiita.com/yoshikyoto/items/5414546cc2da8be1325e
Macの/usr/includeディレクトリを作成する方法

## 目的
CommonCryptoをインポートする際にusr/includeディレクトリがなくパスが通らなかったため

### 解決策
ターミナルで以下のコマンドを叩く

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

<br>

参考
https://superuser.com/questions/995360/missing-usr-include-in-os-x-el-capitan
ファイルが変更されたら自動的にPHPUnitを実行する

pywatchを使ってファイル変更を検出してphpunitを実行します。

## pywatchのインストール

### RedHat系(CentOS)

```
sudo yum install python pip
sudo pip install --upgrade pip
sudo pip install pywatch
```

### Debian系

```
sudo apt-get install python-pip
sudo pip install --upgrade pip 
sudo pip install pywatch
```

## 実行

```
pywatch ./vendor/bin/phpunit test_dir
```

これでいちいちコマンドを実行しなくてもテストを変更したりテスト対象のコードを変更すると自動的にテストを実行してくれます。べんり。

pywatchくんはphpunitだけではなくて、どんなコマンドでも実行できるのでファイル変更検出してなにかしたいときには使えるやつです。いいこ。
Apache-JMeterでRestなAPIの同時接続テストをやってみる

## 実行環境
- Windows10
- Javaインストール済み

## 参考
URL:http://artoftesting.com/performanceTesting/restAPIJMeter.html

## 手順
- Javaがインストールされていない人は以下よりインストール
https://www.java.com/ja/download/

- Apache-JMeterをインストール
http://jmeter.apache.org/download_jmeter.cgi
※インストールするOSに合ったファイルを選択してください
※今回はWindowsなのでzip選択
![13.png](https://qiita-image-store.s3.amazonaws.com/0/187892/56ee6429-5a30-6801-0e03-57064510aa65.png)


インストールしたApache-JMeterの/bin/Jmeter.batをダブルクリックで起動
コンソールが立ち上がったあとにJmeterのウィンドウが立ち上がる
![1.png](https://qiita-image-store.s3.amazonaws.com/0/187892/81ea2fc5-d5e1-8400-a67f-b82907c3e1fe.png)





- 左のツリーより「テスト計画」を右クリック>追加>Threads(Users)>スレッドグループをクリック
![2.png](https://qiita-image-store.s3.amazonaws.com/0/187892/9fb94546-5b0f-acec-099f-f910c12a9f7f.png)

スレッドグループのスレッド数(同時接続数)を変更
![4.png](https://qiita-image-store.s3.amazonaws.com/0/187892/6d09d924-ff3e-3d37-e607-e6c672e2a627.png)


- 左のツリーより「スレッドグループ」を右クリック>追加>サンプラー>HTTPリクエストをクリック
![5.png](https://qiita-image-store.s3.amazonaws.com/0/187892/568fe160-eb31-8e4e-e63c-a12010d1d0db.png)


ここでAPIのURLやパラメーターなどを設定する
![11.png](https://qiita-image-store.s3.amazonaws.com/0/187892/984095f3-d26b-a868-f9fe-38be30bfe167.png)


ベーシック認証などの設定をする場合は左のツリーより「HTTPリクエスト」を右クリック>追加>設定エレメント>HTTP認証マネージャをクリック
![6.png](https://qiita-image-store.s3.amazonaws.com/0/187892/fa08f3f6-02ab-0e70-08d3-d71610ae76c7.png)


ベーシック認証がかかっているAPIならばここで設定
![9.png](https://qiita-image-store.s3.amazonaws.com/0/187892/91f2b288-3865-a803-928b-e7d045e39e22.png)


Content-Typeなどの設定はのツリーより「 HTTPリクエスト」を右クリック>追加>設定エレメント>HTTPヘッダーマネージャをクリック
名前と値を設定
![7.png](https://qiita-image-store.s3.amazonaws.com/0/187892/34caa477-7840-1754-8d66-cb10ab615e79.png)


Content-Typeなどを設定
![10.png](https://qiita-image-store.s3.amazonaws.com/0/187892/1d156dce-a157-01e2-6090-f61f708b58a7.png)


結果を表示するには「スレッドグループ」を右クリック>追加>リスナー>結果をツリーで表示をクリック
![8.png](https://qiita-image-store.s3.amazonaws.com/0/187892/6ea52ede-eaf7-555d-2ecf-b2f5c5241005.png)


## 実行
上のバーにある実行ボタンをクリックすると設定したスレッドの数だけ同時にAPIアクセス処理が実行されます
※今回はダミー情報で実行したので実行結果はすべてこけています

実行結果のツリーにある「HTTPリクエスト」をクリックするとSample Resultに実行結果が表示されます
![12.png](https://qiita-image-store.s3.amazonaws.com/0/187892/c05a077e-da31-42db-e86e-76d1b811f0bb.png)


速度の計測は「スレッドグループ」を右クリック>追加>リスナー>Summary Reportなどから表示することができます。

## CSVのデータを使用し動的な値でテスト


- csvを作成し、任意のディレクトリに保存する。※例) C:\Apache-JMeter\config\parameter.csvと作成
- 左のツリーより「HTTPリクエスト」を右クリック>追加>設定エレメント>Csv Data Set Configをクリック
- Csv Data Set Configにて下記情報を入力
Filenameにcsvのパス(例) C:\C:\Apache-JMeter\config\parameter.csv)
Variable Namesにcsvのデーターを使用するパラメーター名を入力（例) id, pass）
Sharing ModeはALL Threadを選択

- HTTPリクエストの設定画面にてパラメーターを設定
ほかの方はParametersタブから設定しているようでしたが、うまく動かなかったのでBody Dataタブを使用しました。
例) {  "id": ${id}, 
"pass": ${pass}  }
- 実行
【FileMaker】タブコントロールで指定したタブを表示する

FileMakerのタブコントロールでのタブ切り替え、狭いレイアウトに配置するときは便利ですよね。
でも、複数あるタブのどこかで、スクリプトが終わった後、デフォルトタブに戻されてしまうのがもどかしい。。。

例えば、aボタンを押したらaタブに。
<img width="1020" alt="filemaker_tabcontrol1.png" src="https://qiita-image-store.s3.amazonaws.com/0/60538/4704e5f5-14d5-ae51-197a-53aed78ddd42.png">

bボタンを押したらbタブに。
<img width="1024" alt="filemaker_tabcontrol2.png" src="https://qiita-image-store.s3.amazonaws.com/0/60538/c1adeda7-35b4-451e-4531-bf00b20ddc00.png">

cボタンを押したらcタブに。
<img width="1020" alt="filemaker_tabcontrol3.png" src="https://qiita-image-store.s3.amazonaws.com/0/60538/58366d96-06da-2cfd-fe59-d7b992d645b4.png">

こんな感じで実装するには、ちょっとした設定と一行スクリプトで済みます。

まずは、タブコントロールに配置したタブに、オブジェクト名をつけます。
<img width="1016" alt="filemaker_tabcontrol4.png" src="https://qiita-image-store.s3.amazonaws.com/0/60538/3389ac2e-2e87-69e7-07ca-ae78349ae768.png">

そして、一行スクリプト。
<img width="983" alt="filemaker_tabcontrol5.png" src="https://qiita-image-store.s3.amazonaws.com/0/60538/8fd4ead5-b7ac-bed1-ee6a-3a434d612e4a.png">
オブジェクトへ移動するだけです。

タブをオブジェクトと言えば、確かにそうなんですが、いまいち結びつかないので、
・オブジェクトに名前つけ
・オブジェクト移動
と覚えておく感じでしょうか

今回は、ボタンでコントロールしていますが、何かしらのスクリプトにも組み込めますので、ぜひご活用を。
ABC04CとD問題

問題はhttp://abc004.contest.atcoder.jp/ から

#C問題
##解答の方針
入れ替えに周期性がある。
30回操作を行うと初期化するため、
N%30を利用する。

以下のような二つの処理があると考える。
1.先頭の数字が最後に移動する
2.隣の数字と入れ替わる

1の処理は、N%30//5回行われ、
2の処理はn%5回行われる。

##コード
```python:abc04c.py
N = int(input())
num = ["1","2","3","4","5","6"]
n = N%30
m = n//5
s = n%5

for i in range(m):
    a = num.pop(0)
    num.append(a)

for i in range(s):
    k = num[i]
    p = num[i+1]
    num[i] = p
    num[i+1] = k

print("".join(num))
```
#D問題部分点
##解答の方針
R,G,Lともに、どのように広げても重なることはないのである程度適当に考えてもできそう。

中心からの距離が大きくなるにつれて、重みづけをする。
R-1//2回繰り返し処理をし、重みの和を求める
R-1が奇数なら、広げた先で左右どちらかが空くので、条件文を書き加える

##コード
```python:abc04d.py
R,G,B = list(map(int,input().split()))
 
r = R-1
g = G-1
b = B-1
ans = 0
 
for i in [r,g,b]:
    n = 0
    
    for j in range(1,i//2+1):
        ans += 2*j
        n = j
    if i%2 == 1:
        ans += n+1
 
print(ans)
```

#D問題満点
PWAに決済を入れてみた

PWA内でカード決済を行うと既存のApple PayやAndroid
Payなどを通さないで決済できるので、アプリ内課金をしてもAppleに30%手数料を支払うことなく、決済会社への手数料だけで決済を行うことができるようになります。

PWAから決済できる方法をいくつか紹介します。

**Payment Request API**
Googleが開発しているPayment Request
APIを使うことでPWA内でもスムーズに決済を行うことが可能です。

[Googleの詳細記事]
(https://developers.google.com/web/updates/2016/07/payment-request?hl=ja)

Payment Request APIはAndroid 向けChromeだけでしか利用することができなく、iOSのPWAではまだ対応していません。

**Stripeを使った決済デモ**
[Stripe](https://stripe.com/ie)はエレガントに実装できる決済サービスです。これまでさまざまな実績があります。

Stripe決済のデモをPWAで作ってみました。
[https://payment-demo-b9f1a.firebaseapp.com/](https://payment-demo-b9f1a.firebaseapp.com/)

![1-gZlyQI2oGMUd3d1Q0hGDVQ.jpeg](https://qiita-image-store.s3.amazonaws.com/0/201713/9be6c09c-b471-8cb2-71f8-d055a084fa33.jpeg)

これはStripeのテスト環境を使って実装されていますので、動作確認はできますが実際の決済は行われません。

このURLのHome画面から以下を入力してみてください。

カード番号：4242424242424242 (4242を4回)<br> 有効年月：クリックして年月を選ぶ (なんでもいい)<br> CVC: 333
(3桁の数字であればなんでもいい)

この後「カード登録」をクリックすると以下の様なアラートが表示されます。

「カード登録完了」の下にあるtok_で始まる値はStripeのtokenでこれを内部的に保存しておけばカード番号無しで決済を行う事ができます。

あと「番号決済」ページは番号で決済できる機能のデモです。

「決済番号」の所に1234とか適当に数字入れて「これで決済」をクリックすると決済を進めることができます。

この様なフローで決済が可能になることが分かりました。

1.  お店が注文に紐付いた決済番号をお店用PWAで発行
1.  決済番号を購入者に渡す。メールで送ってもいいし、アプリその場で見せてもいい。
1.  購入者は決済番号を決済用PWA内に入力して決済内容を確認して決済完了

決済番号で決済をすることで一度アプリにカードを登録しておけば、決済の際は特にカードを持参していなくても決済が可能になります。

また登録したカードに定期購読をくっつけれるので、毎月980円を自動的に決済みたいな事をすることも可能です。

こうやってPWAでも気軽に決済はできますので、これからのいろんな応用シーンが楽しみですね。

[Mediumの元の記事](https://medium.com/@takeshiamano/pwa%E3%81%AB%E6%B1%BA%E6%B8%88%E3%82%92%E5%85%A5%E3%82%8C%E3%81%A6%E3%81%BF%E3%81%9F-71d9461ad4a3)
IPhoneXでのヘッダ・フッタ追従挙動をテストしてみた

# IPhoneX Safariのoffsetどうなってんだろか
sticky header って結構やるじゃないですか、いわゆる追従ヘッダー。
最近だとcssでposition: sticky;にすれば勝手に上下に余白取ってくれるから楽になりましたね。

最近出てきたスマホってフル液晶(っていうのかな？フルディスプレイ？)で
表示領域とイベント領域がちがってフロントエンドは検証大変です。

とりあえずiphoneXだとbottomの位置どうなってんねんとおもって検証してみました。

## いきなりgithub
githubにまるっとアップしてあるので
iosSimulatorある方はcloneして見たほうが早いです。

https://github.com/task-k/ios11oniPhoneX

## document.bodyのgetBoundingClientRect()を表示してます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/51031/c39aac3a-3279-d566-750b-0db1e6f8e1a1.png" width="auto" height="400px">

### 詳しい検証をしたらtipsをアップデートします
よく利用するワンライナーメモ＜随時更新＞

[株式会社オズビジョン](http://www.oz-vision.co.jp/)の@terra_yuccoです。

サーバ作業の中には、いちいちやるには面倒すぎる＆そもそも不可能なものがいくつかあったりします。そんな時に使っているワンライナーのメモを追加していこうと思います。
だんだん増えていく予定。

## ディレクトリ内ファイルを1つずつgzipでアーカイブ
```bash
$ ls -1 | while read line; do gzip ${line}; done
```
Kotlin覚書 - when?

# はじめに
今回久しぶりにコードを書いていて、Kotlinのwhenに出会ったので覚えがきしておきます。

KotlinのコードからJavaのコードを見たくなることは、JavaでAndroidをやってた人にとってはありそうなので、そんなときの方法はリンクつけておきます。

[Kotlin覚書 - KotlinからJavaにデコードする方法](http://qiita.com/ke__kyukyun1828/items/384972110df2152bf530)

# Kotlinで出てきたwhenさん
普通にActivity生成しただけですが、いきなり「when」を使われても正直スッと頭に入ってこなかったので確認してみました。

### whenの入ったコード
コードです。

```:kotlin
    private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
        when (item.itemId) {
            R.id.navigation_home -> {
                message.setText(R.string.title_home)
                return@OnNavigationItemSelectedListener true
            }
            R.id.navigation_dashboard -> {
                message.setText(R.string.title_dashboard)
                return@OnNavigationItemSelectedListener true
            }
            R.id.navigation_notifications -> {
                message.setText(R.string.title_notifications)
                return@OnNavigationItemSelectedListener true
            }
        }
        false
    }
```
見た感じで雰囲気はわかります。

なので、BottomNavigationViewを選択したときのコールバックに対して処理が書かれてます。
Viewが3つ用意されているので、その3つのViewのリソースID毎に処理わけをしているようです。

つまり、Javaでいうところのswitch文みたいですね。
ではデコンパイルしてみてJavaのコードを覗いてみましょう。

```:java
   private final OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = (OnNavigationItemSelectedListener)(new OnNavigationItemSelectedListener() {
      public final boolean onNavigationItemSelected(@NotNull MenuItem item) {
         Intrinsics.checkParameterIsNotNull(item, "item");
         switch(item.getItemId()) {
         case 2131230821:
            ((TextView)TopActivity.this._$_findCachedViewById(id.message)).setText(2131558459);
            return true;
         case 2131230822:
         default:
            return false;
         case 2131230823:
            ((TextView)TopActivity.this._$_findCachedViewById(id.message)).setText(2131558460);
            return true;
         case 2131230824:
            ((TextView)TopActivity.this._$_findCachedViewById(id.message)).setText(2131558461);
            return true;
         }
      }
   });
```
やはりでしたね。

MenuItemの変数itemからgetItemIdをして、id毎の処理になってました。

# whenの使い方
AndroidStudioでデコンパイルしただけだとswitchで書くのと変わらんやーん！
ってなったので、以下のサイトも参考にさせていただきました。ありがとうございました！

[【Kotlin】whenでif-else](http://qiita.com/AAkira@github/items/3d5b694d488fe029d7b9)

どうやらStringもいけるみたいですね。

自分で検証してみたいところですが、今回時間がなくてまだ検証コードがかけてないので、
それはまた後日アップしたいと思います！！