OmniAICreator/Qiita-1.07M huggingface dataset:
Active Recordの色々なメソッドの返り値

Active Recordでよく使われる`find`や`where`などのメソッドの返り値について調べたらこうなった.

※ `Comment`の部分は, `Comment`という名前のモデルを意味しています. 検索条件に該当したレコードのインスタンスが返ってきていることを意味します.
![image.png](https://qiita-image-store.s3.amazonaws.com/0/80357/fe2d08c2-6af0-2f34-1dac-01663281c982.png)



ちなみに以下のようにして調べた.

```
Comment.all.class
=> Comment::ActiveRecord_Relation

Comment.find(10401).class
=> Comment(id: integer, body: text, commentable_id: integer, user_id: integer, likes_count: integer, created_at: datetime, updated_at: datetime, commentable_type: string)

Comment.find(10401, 10402).class
=> Array

Comment.find_by_id(10401).class
=> Comment(id: integer, body: text, commentable_id: integer, user_id: integer, likes_count: integer, created_at: datetime, updated_at: datetime, commentable_type: string)

Comment.find_by({id:10401}).class
=> Comment(id: integer, body: text, commentable_id: integer, user_id: integer, likes_count: integer, created_at: datetime, updated_at: datetime, commentable_type: string)

Comment.where({id:10401}).class
=> Comment::ActiveRecord_Relation

Comment.all.page(10).class
=> Comment::ActiveRecord_Relation

Comment.all.first.class
=> Comment(id: integer, body: text, commentable_id: integer, user_id: integer, likes_count: integer, created_at: datetime, updated_at: datetime, commentable_type: string)

Comment.all.last.class
=> Comment(id: integer, body: text, commentable_id: integer, user_id: integer, likes_count: integer, created_at: datetime, updated_at: datetime, commentable_type: string)

Comment.includes(:user).class
=> Comment::ActiveRecord_Relation

Comment.order('created_at DESC').class
=> Comment::ActiveRecord_Relation
```


### ・ ActiveRecord_Relation ってなんぞ

`ActiveRecord_Relation`が返ってきた時点ではまだSQLは発行されていない. 描画に必要になったときに初めてSQLが発行される仕組み成っている. また, メソッドチェーンで`where`や`order`などを続けて書くことができる, という便利な機能.
Cognosの導入がうまくいかないパターン④ - LinuxやAIXでulimitのnofilesの設定変更

#LinuxやAIXで、Cognosが正常に起動できない
Cognos Analyticsで最近発生しましたが、Cognos BIでもLinuxやAIXで実装する時に、Cognosサービスの起動ユーザーのulimit -a で、nofilesが1024とか、デフォルトのままの小さい値になっている場合に、Cognosの起動が正常に完了しないという事象が発生します。
ちょいちょい問題を起こすnofilesは、Cognosセットアップ問題のあるあるなので投稿しておきます。

#事象と対応
Cognos起動時に、cogserver.logに以下のメッセージが表示され、Product Ready to Useのメッセージは出力され、プロセスとしても起動するのですが、Cognos接続するとつながりませんでした。

```html
cogserver.log ---------------------------------- 
CM-SYS-5001 A Content Manager internal error occurred. Cause: Could not 
read class 'com.ibm.db2.jcc.am.h' as resource 
'com/ibm/db2/jcc/am/h.class'  Stack trace: java.lang.ClassFormatError: 
Could not read class 'com.ibm.db2.jcc.am.h' as esource 
'com/ibm/db2/jcc/am/h.class' 
------------------------------------------------------- 
```

対応は、ulimitのnofilesを8192に変更しました。
unlimitedでも良いと思います。

nofilesの値の変更は、ここら辺のリンクを参考にして下さい。
https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/REDHAT%E3%81%AE%E3%83%A1%E3%83%A2%E5%B8%B3/page/ulimit%20%E3%81%AE%E5%A4%89%E6%9B%B4

転ばぬ先の杖で、とりあえずLinuxやAIXでCognosをセットアップ時は、nofilesを大きくしておくことは習慣にしましょう。
awkを使ってCSVのカラム数をチェック

# awkを使ってcsvのカラム数チェック
CSVの形をパパッとシェルスクリプトから確認したいときに、行数は`wc -l`で簡単にできるけど、列数はどうするんだろうと思って調べたので、そのメモです。

## シェルコマンドで列数をチェックする方法
例えば下のようなcsvファイルの列数をチェックしたいとします。

```
1,apple,120
2,orange,230
3,kiwi
4,banana,200
5,melon,1000
```

各行のカラム数のチェックはawkで下のようにします。

```
$ cat sample.csv | awk -F ',' '{print NF}'
3
3
2
3
3
```

`-F ','`は区切り文字を指定するためのオプションで`--field-separator`でも指定できるようです。
Autolayoutを使って、UIViewをAspectFitで配置する

特定の UIView のアスペクト比を維持したまま、所定の範囲内に収める方法です。
UIImageView の Aspect fit を UIView でやる感じ。

##とりあえず適当に UIView を配置
UIView を2つ配置します。
黒い UIView が親、オレンジ色の UIView が子になります。
子のアスペクト比を維持したまま、親の中に収まるようにリサイズされることになります。

##親の Autolayout を設定
今回は適当に、上下左右に16ポイントのスペースを開けて、画面いっぱいになるように設定します。
![](https://qiita-image-store.s3.amazonaws.com/0/165132/81edf663-59c4-5523-ded8-fcfe2754280e.png)

設定後、シミュレーターで実行してみた結果です。
上下左右に16ポイント分のスペースが開いて、画面いっぱいにリサイズされました。
![](https://qiita-image-store.s3.amazonaws.com/0/165132/cfe1783d-b0ca-3cd8-40ca-89be631bf720.png)

##子の Autolayout 設定
子にアスペクト比の制約をつけます。
今回はアスペクト比を16:9にします。
![](https://qiita-image-store.s3.amazonaws.com/0/165132/8a9a9825-3a1a-322d-a17b-2fd1c02213da.png)

子に、Equal Widths と Equal Heights をつけます。
※しばらく Autolayout でエラーみたいに出ますが、気にせず進めてください。
![](https://qiita-image-store.s3.amazonaws.com/0/165132/426cf973-3602-aab2-b909-1af9451bdce2.png)

指定した Equal Widths の制約を、less than or equal に変更します。
![](https://qiita-image-store.s3.amazonaws.com/0/165132/64fef910-48e5-ab23-8575-5d70a7ff6020.png)
Equal Heights の制約も同様に、less than or equal に変更します。
![](https://qiita-image-store.s3.amazonaws.com/0/165132/245b924c-5072-3205-27cb-3623a66b38e7.png)

もう一度、子に Equal Widths と Equal Heights つけます。
![](https://qiita-image-store.s3.amazonaws.com/0/165132/2b2105d7-ee81-ff21-9f6f-bf316fbc8f5f.png)

今回指定した Equal Widths の制約を、優先度750に変更します。
![](https://qiita-image-store.s3.amazonaws.com/0/165132/6e187755-439f-04d4-9673-fae4d9ecb11a.png)
Equal Heights の制約も同様に、優先度750に変更します。
![](https://qiita-image-store.s3.amazonaws.com/0/165132/35df0bf8-2849-e29f-7803-53d5b879eb29.png)

子を親の中央に表示するよう制約をつけます。
![](https://qiita-image-store.s3.amazonaws.com/0/165132/02872c50-4b86-190a-5c49-f850748ec370.png)

Autolayout の設定はこれで終了です。
![](https://qiita-image-store.s3.amazonaws.com/0/165132/77b6eaaa-81d6-5e1e-5e74-8c6a861daf84.png)

シミュレーターで確認してみると、画面の回転に合わせて、アスペクト比を維持したまま、親のビューの中にピッタリ収まるように、子のビューがリサイズされます。
![](https://qiita-image-store.s3.amazonaws.com/0/165132/cab88405-0c90-0702-69f6-f776631e06a6.png)
![](https://qiita-image-store.s3.amazonaws.com/0/165132/fb53683d-adb2-0133-130f-b4d6955ec3ed.png)
iPhone Safari モーダル内で明示的な電話をかけるaタグでも電話番号として認識されない（1回タップで電話かけられない）場合の対処法

iPhone Safariでは電話番号があれば自動的に電話をかけられるaタグが挿入される仕様のようですが、外部HTMLの場合はそうじゃない。


###対処法
aタグに target="_parent"を記述する。


    <a href="tel:xxxxxxxxx"  target="_parent">hoge</a>

参考　スタックオーバーフロー
https://translate.googleusercontent.com/translate_c?act=url&depth=1&hl=ja&ie=UTF8&prev=_t&rurl=translate.google.co.jp&sl=en&sp=nmt4&tl=ja&u=https://stackoverflow.com/questions/35516354/mobile-links-in-an-iframe-and-ios&usg=ALkJrhgeBhiOwN5TMDTjZoUzIYvigcfEvg
VisualStudioでクラスのアイコンが変で、開こうとするとデザイナエラーになる

大昔に作られたクラスだが、ソリューションエクスプローラー上で見ると何だかアイコンが赤くて変な奴がいた（ActiveReportのデザインクラスと同じ）
なんだと思ってクリックして開こうとするとデザイナエラー・・・・

F7を押してコード側に行けば問題なく開発は進められたが、毎度やるのは微妙にめんどくさい・・・

というわけで調べたら下記の記事にて解決。

[[VisualStudio]Componentを継承した.csクラスファイルを開くとデザイナで開こうとしてエラーになる](http://oita.oika.me/2014/10/23/vs-opens-component-with-designer/)


どうやらBackgroundWorkerを継承したクラスだったことが原因。
クラスにDesignerCategory("Code")の属性を付ければ解決しました。


```C#:Hoge.cs

[System.ComponentModel.DesignerCategory("Code")]
public class Hoge : BackgroundWorker
{

}

```


↓ 記事内にあるけど、これだけ超注意ですね。 ↓

>上記の回答者も書いてくれているんだけど、謎なことに
属性の「System.ComponentModel」をusingに入れて省略して書いてしまうと
解決しない。
VisualStudioはusing無視しますよ、だそうだ。まじか。
iframe　クロスドメイン　高さ調整は諦めた話

##iframeに異なるドメイン（クロスドメイン）のコンテンツを読み込んで高さを自動調節しようと思ったら出来なかった

高さを調節する方法は検索すると出てくるのだが異なるドメイン先のiframeにもスクリプトを仕込む必要があるのでASP側ファイルを触れない案件なので諦めた。
※JavaScriptでiframeの高さを取得してみたいなことは同一ドメイン同士であれば可能のようだ。

###PCブラウザの場合
スクロールバーを出したくないので
heightを与え、iframeタグにscrolling="no"を記述した。

###スマホの場合
スクロールバーを出したくない場合は高さの可変に対応する必要がでてしまうのだが、
前述のように出来ないため、iframeのエリアをスクロールで対応する。

iPhone safariでスクロール可能とするためにiframeの親要素に下記CSSを与える

      height: 60vh;
      overflow: auto;
      -webkit-overflow-scrolling: touch;
GmailのIMAPサーバーのSSL証明書を取得する

#IMAPサーバーのSSL証明書
JavaMailを用いてGmailのIMAPサーバーに接続しようとしたのですが、SSLの証明書をキーストアに読み込む必要がありました。ブラウザを使わずにSSL証明書を取得する方法がわからずに少し苦労したのでメモしておきます。

##OpenSSLのダウンロード
OpenSSLを用いることで、証明書の内容を表示できます。[こちら](http://www.atmarkit.co.jp/ait/articles/1601/29/news043.html)の内容を参考にしてインストールを行い、パスを通しました。

##imap.gmail.comへの接続
s_clientコマンドを使用してimapサーバーに接続します。
以下のように証明書の情報が表示されます(一部省略)。

```s_client
OpenSSL> s_client -connect imap.gmail.com:993
CONNECTED(00000138)
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
---
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=imap.gmail.com
   i:/C=US/O=Google Inc/CN=Google Internet Authority G2
 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEgDCCA2igAwIBAgIIJeQIYDQR0i8wDQYJKoZIhvcNAQELBQAwSTELMAkGA1UE
BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl
cm5ldCBBdXRob3JpdHkgRzIwHhcNMTcwOTA3MTEwNjE0WhcNMTcxMTMwMTA1NDAw
WjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN
TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UEAwwOaW1h
cC5nbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTj3n4
asDt602O14Q2n3XoinQkFnfAdkrezhFTioyuwKVf8bD4xND8H/rxfFUqF5g14p5v
/240s1ww4WftaqrRHXJ2eGyEehcIA1l6DX9UffK9jh+s08nFycZY3iPPmcmRt2kP
msOa9sBF6Eb0sjju7B5j5+ZfpinzhB8Y2PW6xI58glQUh7xkEVwuGLNG+E+AtVi8
Zxf4Mh22cNz2HZoxDxj1x6N4O9lIjx7UMxBMhnDaPiBsfOClOLBTVmxKbUNVTWGM
R/NhGjCBGLdrXIH34JAxXws6RhdAk3hFhnkFUShaL823nVQmLZdvFezxM5KK4HRN
mHF0FTrEtZgF2DVNAgMBAAGjggFLMIIBRzAdBgNVHSUEFjAUBggrBgEFBQcDAQYI
KwYBBQUHAwIwGQYDVR0RBBIwEIIOaW1hcC5nbWFpbC5jb20waAYIKwYBBQUHAQEE
XDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3J0
MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9vY3NwMB0G
A1UdDgQWBBSqFXiwdGEThuRgwhzNgmtXtWlAHTAMBgNVHRMBAf8EAjAAMB8GA1Ud
IwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMCEGA1UdIAQaMBgwDAYKKwYBBAHW
eQIFATAIBgZngQwBAgIwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL3BraS5nb29n
bGUuY29tL0dJQUcyLmNybDANBgkqhkiG9w0BAQsFAAOCAQEAKCZwCCZ4SxjeJhja
oGMnbqux1lSi3uFFpLN0b0FTvWvPWKMJ+YFb5T88OvSTKyhiElFxq8NshaIFYiHf
MBy8IlR78QtftTJsHEhX+E1ozK1WJKjKmmp+DGVR60cPZASzZ9/EZyCdOIi8uHg7
NeDjChxVYN3w9TqT4Gm5S7tRIDCrId7lvbBrAviqtRBdnJ0MlwaOyemc4fqQ9tC7
NRxLyjmfWT8hW1qdc00AWABRJbiCqoz1zwCS//7p1poTYmCuFUHDYwjHeBwwTk22
73R2QCnfN7sPctq48I+vrWF2rwC20J4jDBV69XGTd/HgYwdw15hoSsAx9eDg+Jos
NGyLvw==
-----END CERTIFICATE-----
```
##証明書の作成
表示された結果の、
-----BEGIN CERTIFICATE-----
から
-----END CERTIFICATE-----
までをメモ帳等にコピーし、適当な名前(例：gmailimap.crt)で保存します。これでOKです。
-----BEGIN CERTIFICATE-----と-----END CERTIFICATE-----を含める形で保存する点に注意してください。

##おまけ：証明書のインポート
keystoreにインポートする際のコマンドはこちらです。

```
keytool -import -alias gmail -file gmailimap.crt -keystore key.jks
```
rbenv でとりあえず全部のRubyをインストールするワンライナー

普通は最新版だけ使えばよいのですが、たまに古いRubyで動いているコードに当たる時もあり、そんなときに `rbenv install` の完了を待つのは退屈なので、あらかじめビルドしておきます。


`rbenv install -l` でバージョン一覧が取れるので、適当に grep し・・・

```
$ rbenv install -l | cut -b 3- | grep '^2\.[234]\.[0-9]\+$' # 2.2.x 〜 2.4.x 一覧表示
```

`rbenv install` を実行すればOK。`-s` をつけるとすでにインストール済みの場合はスキップしてくれます。

```
$ rbenv install -l | cut -b 3- | grep '^2\.[234]\.[0-9]\+$' | xargs -n 1 rbenv install -s
```
Heroku CLI を ubuntuに入れる


PaaS 環境 Heroku を使用する準備として、Heroku CLIをインストールします。

# 前提
* Herokuアカウント作成済みであること

# インストール
[Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli "Heroku CLI") を見に行くと、環境ごとのインストール方法が記載されています。

今回はUbuntuに入れるので、以下をこぴぺ。

```bash
wget -qO- https://cli-assets.heroku.com/install-ubuntu.sh | sh
```

インストールが終わったら、以下のコマンドでバージョンの確認ができます。

```bash
heroku --version
```

#ログイン
インストールが終わったら実際にログインしてみましょう。
プロキシ経由する場合は、事前に環境変数を設定しておく必要があります。
コマンドは「heroku login」

```bash
$ export HTTP_PROXY=http://proxy.example.com:8080
$ export HTTPS_PROXY=http://proxy.example.com:8080
$ heroku login
Enter your Heroku credentials:
Email: hogehoge@example.com
Password: **********
Logged in as hogehoge@example.com
```

ここまでで、herokuを使う準備が出来ました。
Drupal8のカスタムモジュールをcronに対応させるメモ

自作モジュールをcronに対応させて、定期的な処理を実行する手順をメモする。
モジュール名は _First Module_ とし、記述を進める。

```
DRUPAL/modules/custom/
├first_module/
│├first_module.info.yml
```

## cronに対応させる2段階のステップ
カスタムモジュールをcronに対応させるには2つのステップが必要となる。

1. **Drupalでcronが実行された際にキューに処理を登録する処理**。
1. **生成されたキューを実行する処理**。

これらの手順を意識すれば、カスタムモジュールのcron対応は案外簡単に実装出来る。ただし、一つ整理しておかなければならないことがある。それは、上記のステップのうち定期実行によって処理されるのは後者であるということ。前者はcronとは関係ない。要するにcron実行時に限らず、キューへの処理登録は随時行えば良い。cron実行時には登録されているキューを随時処理していくという流れになる。

# キューにデータを登録
cron実行時に処理されるキューを登録する。記述は意外と単純。

```php
  $queue = \Drupal::queue('first_module_queue');
  $data = [ 'value' => 'test'];
  $queue->createItem($data);
```

で良い。この処理をカスタムモジュールのいずれかのタイミングで実行することでキューが登録される。

ここで、1行目で指定している _first\_module\_queue_ はQueueIDと言うもので、どのキューにデータを登録するかの識別子となる。

混乱しかねないのでイメージだけ共有しておきたい。そもそもキューとは、 **高速道路における料金所の各ゲート** だと考える。そしてデータは、 **各ゲートに並んだ車** ということになる。どのキューにデータを登録するのかは、キューの識別子であるQueueIDを用いることになる。キューに登録されたデータは、 **登録された順** でキューによって処理される。

上記3行の記述はは次のように解釈できる。
1行目でどのキューを利用するのか指定した。続いて登録する処理に必要なデータを用意する（2行目）。データをキューに登録する（3行目）という流れになる。

# キューの処理
QueueIDによって選択されたキューにデータを登録することで、cron実行時に登録済みのデータが処理される。
ここではQueueIDと対応するキューの作成を行う。前節の例で言うならば、料金所におけるゲートと通過する際の処理を定義することになる。

ソースコードは _FirstModuleQueueWorker.php_ とし、 _src/Plugin/QueueWorker_ に配置する。

```
DRUPAL/modules/custom/
├first_module/
│├first_module.info.yml
│├src/
││├Plugin/
│││├QueueWorker/
││││├FirstModuleQueueWorker.php
```

## FirstModuleQueueWorker.php
FirstModuleQueueWorker.phpはキューとその処理を定義する。

* src/Plugin/QueueWorker/ に配置する。
* `\Drupal\Core\Queue\QueueWorkerBase` を継承したクラスにする。
* QueueIDを持つ。
* キューの処理は、 `public function processItem($data){}` として定義する。
 
```php:FirstModuleQueueWorker.php
<?php

namespace Drupal\first_module\Plugin\QueueWorker;
use Drupal\Core\Queue\QueueWorkerBase;

/**
 * Processes for First Module Queue.
 *
 * @QueueWorker(
 *   id = "first_module_queue",
 *   title = @Translation("FirstModuleQueueWorker"),
 *   cron = {"time" = 60}
 * )
 */
 
class FirstModuleQueueWorker extends QueueWorkerBase {

  /**
   * {@inheritdoc}
   */
  public function processItem($data) {
    // Process $data here.
    \Drupal::logger('first_module')->notice('run processItem@FirstModuleQueueWorker');

  }
}
```

キューにデータが登録されていると、cronが呼び出された際に`processItem($data)`が呼び出される。引数の`$data`は、前節のプログラムにあった`$queue->createItem($data);`によって登録された`$data`となる。

上記のプログラムでは`$data`は特に利用せず、キューが処理を実施した場合にメッセージをログに残すだけのプログラムとなっている。
MySQL起動できなくなった　The server quit without updating PID file

プログラミング初心者のエラー対処メモ

DBにMySQLを使ったRailsアプリを起動させるのにMySQLを起動させようとしたところエラーが発生

```
$ sudo mysql.server start
Password:
Starting MySQL
.. ERROR! The server quit without updating PID file (/usr/local/var/mysql/****.local.pid).
```
ググってこちらの質問のベストアンサーを参考にやってみた
<a　href="https://teratail.com/questions/19778"=target_blank>MySQLを起動する際にエラーが発生します。</a>

PIDファイルのエラーの件は、/usr/local/var/mysql/マック名.local.errの権限の問題らしいのですが、

```
$ chown [mysqlの動作ユーザ名] /usr/local/var/mysql/***.local.err 
```

でもエラー

usr/local/var/mysql/mysql　にいって再起動してみる

```
$ usr/local/var/mysql/mysql > sudo mysql.server restart
Password:
 ERROR! MySQL server PID file could not be found!
Starting MySQL
.. ERROR! The server quit without updating PID file (/usr/local/var/mysql/.local.pid).
```

PID fileが見つからないとのエラーだったのでファイルの生成をしてみる

```
$ /usr/local/var/mysql/mysql > touch /usr/local/var/mysql/****.local.pid
```

再起動

```
$ /usr/local/var/mysql/mysql > sudo mysql.server restart
 ERROR! MySQL server PID file could not be found!
Starting MySQL
. SUCCESS!
```

起動した！
ESP8266 > 検討 > APPTVRepeater > 英語リスニング補助ツール (定数時間の巻き戻し機能)

WIP: Work in progress

```txt:動作確認
- ESP-WROOM-02
- ユニーバサル基板実装
```

### やりたいこと

Apple TVにてNetflix上でStar Trek: Deep Space 9を見ている。リスニングの練習として数秒戻るために以下の操作を行う。

1. 左カーソルを選択
2. 適当な時間で再生ボタンを選択

Apple TVで見ている限り、上記を一つの機能として実行できるUIは用意されていないようだ。

上記を行うツールを用意するにはどうするか。

## 方法案

### ESP8266でIR送信プログラムを作成

- [ ] IRコマンドの解析 (Apple Remote: silver)
    - 左カーソル押下時
    - 再生ボタン押下時
    - 解析用の基板作成
    - 解析用のプログラム(ESP8266)作成
- [ ] 補助ツールプログラム実装

### UnityでAndroidアプリを作る

ESP8266の場合と比べて、基板実装の手間は減る。

### ESP8266でApple Remoteのボタンを押す

- IRコマンド解析が不要
- リレーなり、モーターでたたくなりが必要
    - [raspberry piでSG-90サーボモータを動かす](http://qiita.com/anzaitetsu/items/a66213c97fdb04d9baa7)

### 他

どこかにApple Remote送信パターンの情報があるかもしれない。
それを使えば、上記のIRコマンド解析作業が不要になる。

## 見つけたもの

### Infrared remote library for ESP8266

https://github.com/markszabo/IRremoteESP8266

examples/を見たところ、エアコンの操作用のライブラリの感じがする。

### Remote control @ Wikipedia

https://en.wikipedia.org/wiki/Remote_control
> A 940 nm wavelength LED is typical. 

- [電子工作 > INFRA-RED EMITTING DIODE > L-53F3BT > datasheet](http://qiita.com/7of9/items/8d7c6e5407ca31ed6080)で使ったL-53F3BTは在庫があっただろうか。
    - [Inventory / unity > code v0.6 > Row:Next/Prev, Column:Next/Prev実装](http://qiita.com/7of9/items/57fae488744a75f03597#_reference-c17d1b8ba3e3a02f6bd7)で見つからないので、在庫なし
    - [φ5mm高輝度赤外線LED 940nm 15°
OSI5LA5111A @ 共立エレショップ](http://eleshop.jp/shop/g/gG5G313/)
        - ネコポス可能

### squeed/AppleRemoteSender

https://github.com/squeed/AppleRemoteSender

ヘッダーファイルにパターンのようなものがある。

### macsbugさんの情報
(追記 2017/09/16)

[赤外線LEDリモコンの制作](https://macsbug.wordpress.com/2015/11/29/%E8%B5%A4%E5%A4%96%E7%B7%9Aled%E3%83%AA%E3%83%A2%E3%82%B3%E3%83%B3%E3%81%AE%E5%88%B6%E4%BD%9C/)

ESP8266のGPIOの電流は10mA程度。そのままでは赤外LEDを使用できないとのこと。

過去に調べたのを忘れていた。
[ESP8266 > Link > GPIO > 12mA / 20mA for source current / sink current](http://qiita.com/7of9/items/15589cfb7d25a7cd4d42)。

macsbugさんの回路を参考にVcc=3.3V版に変更したらいいのかもしれない。

### 東京お気楽カメラさんの情報
(追記 2017/09/17)

macsbugさんの使用されているICの情報を元に、以下を見つけた。

[WROOM02を使った赤外線リモコン その1](http://okiraku-camera.tokyo/blog/?p=4800)

こちらも色々参考になります。
[Tmux] セッションを自動保存・リストア

セッションを自動で保存し、macを再起動しても自動でtmuxを起動し、セッションをリストアできるようにします。
**手順**
1. tpmを導入
2. 自動保存・リストアのプラグインを導入

## [tpm (Tmux Plugin Manager)](https://github.com/tmux-plugins/tpm)を導入
tmuxのためのプラグイン管理ツールです。
まずtpmをダウンロードします。

```bash
$ git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
```
次の設定を.tmux.confに追加します。

```~/.tmux.conf
#===================================
# tpm - Tmux Plugin Manager
#===================================

# Plugins
set -g @plugin 'tmux-plugins/tpm'

# Initialize TMUX plugin manager 
# (keep this line at the very bottom of tmux.conf)
run '~/.tmux/plugins/tpm/tpm'
```
起動中のtmuxから設定を反映します。

```bash
$ tmux source ~/.tmux.conf
```



## 自動保存・リストアのプラグインを導入

インストールはtpmを通して行います。次のプラグインを導入します。

- [tmux-resurrect](https://github.com/tmux-plugins/tmux-resurrect)
- [tmux-continuum](https://github.com/tmux-plugins/tmux-continuum)

tmux-resurrectはtmuxを保存・リストアするプラグイン。tmux-continuumは保存・リストアを自動化するプラグインです。（tmux-resurrect-autoはtmux-continuumの旧名です。）
先ほどの設定ファイルに、次を追記します。

```~/.tmux.conf
# Plugins
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
```
追記したら、`prefix + I`でプラグインをtpmによりインストールします。

インストールが完了したら、tmux起動時に自動で保存されたセッションをリストアするように設定します。
この際、tmux-continuumの機能として、terminalの自動起動も利用してみます。
以下を.tmux.confに追加します。

```~/.tmux.conf
#===================================
# Auto start tmux and restore
#===================================

# auto start terminal
set -g @continuum-boot 'on'
set -g @continuum-boot-options 'iterm'

# auto restore tmux
set -g @continuum-restore 'on'

```

---
以上で完了です。再起動すると自動でリストアされるはずです。
Reduxのアプリケーション作成の際のメモ


## 概要
基本的なことは、公式ドキュメント及びそれらの解説ブログ等を参考にした。
ゼロからではなく、サンプルを流用

- [公式のサンプル](https://github.com/reactjs/redux/tree/master/examples/counter)

## 目的

- Reduxの機能を一通り覚える
- Reduxでの実装の勘所を押さえる
- サンプルの修正から始めることで、機能追加・変更が起きた際にどこを修正すれば良いかを理解する

## 作ったもの
アンケートアプリ
https://github.com/sugiii8/react-redux-enquete-app

- 問題に回答して、回答に応じた結果を表示するというもの
- 以前に作ったことがあるので設計は把握している

## ハマったところ
- Container Component(以降Container)/Presentation Component(以降Component)の分け方
	- Container: Componentに渡すデータ・関数を定義・設定する。dispatchを行う。
	- Component: Containerから渡されたデータを表示する。イベントハンドラで、Containerから渡された関数を呼ぶ。		- Componentはただ渡されたものを表示・実行するだけ。中身については関知しない。
	- ※ `render()` はComponentでやるべきと思っていたが、他サンプル見てるとContainerでやってるのもあるのでそうでもないみたい。

- 非同期処理
	- redux-thunkをMiddlewareとして適用する
	- ※ Middlewareについてはふわっとした理解になっているので後で改めて調べる
- ビジネスロジックはどこに
	- modelを追加してそこに集約する
		- 実体はimmutable.jsのRecord()
	- reducerはmodelのメソッドを呼ぶだけにする
- `document.ready()` 的なことがしたい
	- `componentDidMount()`
		- 今回はこのタイミングでリモートのjsonを取りに行った
- ループ内でComponentを呼ぶ
	- key属性に一意になる値を設定しないと警告が出る
	- React側でどのComponentの特定ができなくなるから(?要調査)

## やってわかったこと
- 役割が分割されることのメリットは大規模アプリケーションで威力を発揮しそう
	- ロジックの見通し、action/reducer(model)を見れば、何が行われるかがひと目で分かること
- Containerの`mapDispatchToProps()` で必要な関数のみに絞ることで、子の何でもあり状態を制限することができる
	- バグの温床を作りづらい
- ただやはりメリットは大規模開発時の時に享受できるもので、今回の規模だた、手間のほうがかかるという感じもした。
	- もちろん今回は学習のためなので、そうなるだろうと予測はしていた。
- reduxに限らず何か作る際は、完成されたものを弄くりながら進めたほうが理解も完成も早いということを実感した。
UIButtonの画像をラベルにはさみたい

自分用メモ

# 概要
こんなボタンがデザインで上がってきました。

<img width="200" alt="スクリーンショット 2017-09-15 12.24.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/61792/9df7801b-0202-8b4a-8e91-7d3d176ab2ee.png">

UIButtonのLabelの両脇に画像を配置しています。
普通にUIViewでボタンの中のレイアウトを組んでの上にUIButtonのせればいいんじゃないの？って思ったんですが、ボタンを押した時にハイライトにならずにイマイチだったのでUIButtonだけで頑張ってみました。

# 実装
これで↑のボタンができました。

```swift
// Buttonの装飾部分は割愛

let string = NSMutableAttributedString(string: "10000")
let leftImage = #imageLiteral(resourceName: "money")
let rightImage = #imageLiteral(resourceName: "disclosure")
        
let leftAttachment = NSTextAttachment()
let leftImageString = NSAttributedString(attachment: leftAttachment)
leftAttachment.image = leftImage
// デフォルトの位置だと中央ぞろえが厳しいので調整
leftAttachment.bounds = CGRect(x: 0, y: -3, width: leftImage.size.width, height: leftImage.size.height)
        
let rightAttachment = NSTextAttachment()
let rightImageString = NSAttributedString(attachment: rightAttachment)
rightAttachment.image = rightImage
// デフォルトの位置だと中央ぞろえが厳しいので調整
rightAttachment.bounds = CGRect(x: 0, y: -3, width: rightImage.size.width, height: rightImage.size.height)
        
string.insert(leftImageString, at: 0)
string.append(rightImageString)
button.setAttributedTitle(string, for: .normal)

```

# 懸念
画像の位置がちょっとずれているのでコードで調整する必要があり、ボタンのバリエーションが増えると使い勝手が悪くなるかもしれません。

# 参考
[UILabelに画像を表示する](http://qiita.com/nagisawks/items/ff8232e92a2e9525ab0b)
Promiseでfinallyっぽいことをする

# 概要
Promiseでfinallyっぽいことをしたい。

でも、Promiseは、finallyと異なり、データやエラーが渡されるので、前の処理から渡された結果を、どうするのか、次の処理に何を渡すのか、エラーをどうするのかによって、finallyっぽいものの実装方法が何種類も考えられます。

さて、何らかのリソースをクローズしたり一時ファイルを削除するような処理の場合、クローズの結果そのものは、次の処理に渡す必要はなく、クローズの前のデータを次の処理に渡したいことが多いと思います。つまり、「前の処理の内容を、透過的に次の処理に渡す」、データの流れ的には一切手を付けず、finallyっぽい処理をすれば、使い勝手が良さそうです。

そこで、こんなコードを書いてみました。

# コード

```js
Promise.prototype.finally = function (promisable) {
    return this.then(
        function (originalResult) {
            return Promise.resolve(promisable())
                .then(function(result) {
                    return originalResult;
                })
        },
        function (originalReason) {
            return Promise.resolve(promisable())
                .then(
                    function (result) {
                        return Promise.reject(originalReason);
                    },
                    function (reason) {
                        reason.parent = originalReason;
                        return Promise.reject(reason);
                    }                
                )
        }
    )
}
```

# 使用例

```js
doSomething(file)
  .finally(()=>{
     fs.unlink(file);
  })
　.then((result)=>{
      // finallyは無視して、doSomethingの結果を受け取る
  })
　.catch((cause)=>{
　　　 // finallyを含めた、すべてのエラーを受け取る。二重にエラーだった場合は、parentに前のエラーを保持。
  })

```

# 補足

やっぱり、originalReason（「処理」の結果）を受け取りたいと考える人もいるかもしれませんが、その場合は、エラーとの分岐が必要で、それなら、普通にthenを書いて、受け取った結果を次に渡せば良いわけです。分岐が必要ないからこそ、一つの処理として書きたい。なので、ほとんどの場合、この実装で問題ないのではないかと思います。


# 問題

そもそも、Promiseの実装が多数あって、特定のライブラリが返すpromiseが、グローバルのPromiseのインスタンスではないことが多々あります。で、そういう場合には、Promise.resolve()してやらないといけない。これは、あまりエレガントではありません。

ついでに言うと、標準でもなんでもない拡張を、Promiseに加えるのは、品質管理的にあまり良くありません。ですので、これはあくまで実験的な機能として、頭の隅に置いておいてもらえればと思います。
ScotchboxのPHPでMailCatcherを使う

（2019-01-21 追記）
ScotchBox3.5になって、MailHogがインストールされました。
普通にVM起ち上げたら、8025ポートでアクセスするだけです。
http://IPアドレス:8025/
こっちの方が簡単なので、バージョン3.5以降の場合はこれでOKになりました。


# ScotchBox3.0でMailCatcherを動かす

MailCatcherは、擬似的なSMTPサーバで、プログラムから送信されたメールをキャッチしてローカルで閲覧できる便利な開発用ツールです。
VagrantのScotchbox3.0で試そうとしたら、php.iniの設定がうまくいかなくてハマったのでメモ。

## 起動
```
$ vagrant ssh
```
SSHログインしたら、そのまま

```
$ mailcatcher --http-ip=0.0.0.0
```
で、起動します。
ここまでは、ScotchBoxのマニュアル通り。

PHPで使うには、php.iniの設定が必要

## php.iniの設定

### catchmailのパスを調べる

さきにパスを調べておきます。

```
$ which catchmail
/home/vagrant/.rbenv/shims/catchmail
```
MailCatcherのパスを調べる。そして覚えておく。
私の環境では
/home/vagrant/.rbenv/shims/catchmail
でした。

## php.iniの設定

php.iniの設定を行います。（php.iniは、/etc/php/7.0/apache2/php.iniにありました）

```
$ sudo vi /etc/php/7.0/apache2/php.ini
```

```php.ini
SMTP = 0.0.0.0
smtp_port = 1025
sendmail_path = /home/vagrant/.rbenv/shims/catchmail --ip 0.0.0.0
```
で、apache再起動

```
$ sudo service apache2 restart
```

これで、使えるようになりました。
使い方とかは、いろいろなところで紹介されているので検索してください。

## 参考資料
https://box.scotch.io/
https://github.com/scotch-io/scotch-box/issues/194
https://gist.github.com/mppatterson/1737348341a501268530
URLのクエリ文字列をJavaScriptで指定して削除する


# URLのクエリ文字列をJavaScriptで指定して削除する
特に用途は思いつきませんが、作ったのでメモとして残します。

## HTML
``` HTML:index.html
<html>
    <head>
        <title>ReplaceURL</title>
 <script type="text/javascript" src="./replaceurl.js"></script>
    </head>
    <body></body>
</html>
```

## JavaScript
```JavaScript:replaceurl.js
    // delete  query string        
    // クエリストリング取得
    var urlQueryString = document.location.search;
    var replaceQueryString = "";
    if (urlQueryString !== "") {
    
        // クエリストリング毎に分割
        var params = urlQueryString.slice(1).split("&");
        
        // クエリストリング確認用
        for (var i = 0; i < params.length; i++) {
            var param = params[i].split("=");
            var key = param[0];
            var value = param[1];

            // 該当するクエリストリングは無視
            if (key === "delquery") continue;

            // 新たにクエリストリングを作成
            if (replaceQueryString !== "") {
                replaceQueryString += "&";
            } else {
                replaceQueryString += "?";
            }

            replaceQueryString += key + "=" + value;
        }
    }
    
    // URLに新しいクエリストリングを付与
    history.pushState(null,null,replaceQueryString);
```

## 結果
JavaScriptの実行前後で、以下のように、query文字列が変更されます。
http://～/index.html?delquery=del&hoge=hoge
↓
http://～/index.html?hoge=hoge
C#のメモ帳　動的に配列の要素数を増やす

```csharp:動的に配列の要素数を増やすぞ！
string[] 顧客 = new string[0];   //空の配列を作る。

 for(int i= 0; i < 9; i++)
{
	Array.Resize(ref 顧客, i + 1);  //配列のリサイズ。既存値はそのまま。リサイズ直後の値はNull(のようだ)。
	顧客[i] = i;
	Console.WriteLine(顧客[i]);
}

Console.WriteLine("要素数: "+ 顧客.length);
```
Emacs でメッセージを表示せずにファイルを保存する方法を調べた

※オチがあります

# 問題

Emacs のもっとも基本的なファイル出力関数である `write-region` は、保存時に `Wrote <filename>.` というメッセージを表示してしまうので、 Emacs アプリやスクリプト内部でファイル出力を扱う場合にはうるさくなってしまうことがあります。

```lisp
(write-region (point-min) (point-max) "file")
```

他のファイル保存関数も、内部で　`write-region` を利用しているので同様です。

# だめだったアイデア
## 1. with-temp-message

ミニバッファの表示を固定しながらフォームを評価する、 `with-temp-message` というマクロがあるので、基本的にはこれで足ります。

```lisp
(with-temp-message ""
  (let ((message-log-max nil))
    (write-region (point-min) (point-max) "file")))
```

ただこれはたんに表示を固定するだけで、メッセージを表示するルーチン自体は呼ばれているので、たとえば `emacs --script` や `emacs --batch` でターミナルから Emacs が実行されている場合は、普通に stderr に `Wrote <filename>.` が出力されてしまいます。

## 2. message 関数を再定義

`write-region` が内部で `message` 関数を呼んでいるなら、 `message` 関数を一時的に再定義してしまえばメッセージを表示させなくすることができそうです

```lisp
(flet ((message (&rest _) nil))
  (write-region (point-min) (point-max) "file"))
```

`flet` が obsolete な最近のバージョンでは

```lisp
(let ((orig-message-fn (symbol-function 'message)))
  (unwind-protect
      (progn (fset 'message (lambda (&rest _) nil))
             (write-region (point-min) (point-max) "file"))
    (fset 'message orig-message-fn)))
```

結果は、だめでした。なぜなら、 `write-region` は C のコアレベルで定義されている関数なので、そもそも Emacs Lisp の世界の `message` を呼んでいないからです。

----

余談：

関数再定義で挙動を変えられるのは動的束縛の強みです。個人的に Emacs Lisp は動的束縛であり続けて欲しいですし、 `flet` を削除するのは賛成できないです。

## 3. シェルコマンドを呼ぶ

emacs には、指定した範囲の文字列を標準入力としてシェルコマンドを呼び出す `shell-command-on-region` という関数があります。これを使ってファイルを保存すれば Emacs のメッセージは表示されません。

```lisp
(shell-command-on-region (point-min) (point-max) (format "cat > file"))
```

Unix の場合これでうまくいくのですが、この方法だとバッファの coding-system が反映されないので、 windows や mac を使っているとたとえば CRLF で保存されてしまったりします。

# うまくいった方法

どうにもうまくいかなかったので、 Emacs のソースを見てみました。

ファイル IO 関連の関数は `src/fileio.c` にあります。 `write_region` の実装を読んでみると、一番下にメッセージを表示している箇所が見つかります。

```c
Lisp_Object
write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
	      Lisp_Object append, Lisp_Object visit, Lisp_Object lockname,
	      Lisp_Object mustbenew, int desc)
{

  ...

  ...

  ...

  if (!auto_saving && !noninteractive)
    message_with_string ((NUMBERP (append)
			  ? "Updated %s"
			  : ! NILP (append)
			  ? "Added to %s"
			  : "Wrote %s"),
			 visit_file, 1);

  return Qnil;
}
```

よく見てみると、メッセージを表示する条件に `if (!auto_saving && !noninteractive)` とあります。その手があった！

というわけで、 `auto-save` 機構を悪用してファイルを保存するこのコードに行き着きました。これはうまくいきます。

```lisp
(let ((buffer-auto-save-file-name "file"))
  (do-auto-save t t))
```

自動保存ファイルの向き先を一時的に目当てのパスに `let` で上書きして、 `do-auto-save` で自動保存をトリガーします。 `do-auto-save` の第二引数に non-`nil` な値を渡すとカレントバッファだけが対象になるので、それを利用すれば任意のバッファを任意のパスに、「自動保存機構を経由して」保存できます。

# 追記

`write-region` の第５引数に `nil` でも `t` でもない値を明示するとメッセージ出ないらしい。がびーん。

```lisp
(write-region (point-min) (point-max) "file" nil 'nomsg)
```
JetBrains IDE の設定をリポジトリ管理する

WebStorm や RubyMine を入れ直すたびに，設定を export して転送して import みたいなことをしていたが，リポジトリ管理に切り替えてみた．


# 既存設定をリポジトリ管理下にいれる

## リポジトリ作成

管理用のリポジトリを新規作成し，clone URL をコピー
`git@github.com:tanakaworld/WebStorm.git` 

## IDE で設定

`File > Settings Repository`

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31862/dd54289a-aec5-dd37-4690-a950d61ec5c8.png)

`Upstream Repository` にリポジトリのURLを入力．
初回作成の場合は， `Overwrite Remote` を選択すると，リポジトリにアップロードされる．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31862/6ff5425f-c856-34c8-3ca7-c0f14760a87a.png)

#　他のIDEに設定を反映

* `File > Settings Repository` でリポジトリのURLを入力．
* `Overwrite Local` を選択．
* 再起動

これだけで，設定が反映される．
Visual Studio CodeでGitHubのログインダイアログがしつこい

Visual Studio Codeが使いやすくて最近気に入ってます。
ただ、1点、GitHubのログインダイアログが頻繁に表示されるのが煩わしいので、何とかならないものかなと思っていました。

求めていたものとは少し違ったのですが、頻繁に表示される状態は改善できたのでメモ。

ユーザー設定に次の項目を加えるだけでした。
（[VS Code incessantly invokes an OpenSSH dialog · Issue #7821 · Microsoft/vscode](https://github.com/Microsoft/vscode/issues/7821)より）

```json:
{
  "git.autofetch": false
}
```

自動でfetchしていたせいで頻繁にダイアログが出てきていたということみたいです。
ssh agentをパスフレーズ省略に応用する方法まとめ

どうも、ラズパイエンジニアのかちおです。

シェルスクなどでsshする時にパスフレーズがかかっているとうまく動かないのですが、それを解決するためにssh-agentを使う必要があります。で、まったくわからなかったので調べて実際に動かした結果などを共有していきます。

# そもそもssh-agentとは

sshをした先のサーバーで、ホストにある鍵を使いたかったりするときのためのもので、リモートにホストと繋がるソケットを置いて、そこに問い合わせるとssh秘密鍵が帰ってくるというセキュアな鍵送信方法、らしいです。

# パスフレーズ省略への応用

自分のマシン自体でssh-agentを走らせておくと、秘密鍵を返してくれるソケットが出来上がります。でも`~/.ssh/`に鍵あるんだからそれを使えばいいんじゃ？という話ですが、ここで出てくるのがパスフレーズの問題です。
ssh秘密鍵にパスフレーズを登録していた場合、sshやgit使用時に毎回シェルで入力する必要があります。
しかし、ssh-agentに鍵を登録する時にパスフレーズを入力すれば、電源が落ちるまでssh-agentが復号化された秘密鍵を持って置いてくれます。
なので、ローカルでssh-agentを起動して、そいつに`~/.ssh/id_rsa`とかをパスフレーズ解除して登録すればいいことになります！

# 手順

## 1. ssh鍵ペアを作る

`ssh-keygen`を使って鍵を作りましょう。すでに鍵がある場合はそれを流用してください。

## 2. ssh agentに秘密鍵を登録する

```
$ ssh-add ~/.ssh/id_rsa
```

鍵の名前は各自変えてください。そして、このコマンド実行時にパスフレーズを聞かれるので入力してください。

### 永続化(※MacOSのみ)
このssh-agentに登録した複合化済みの秘密鍵は、再起動するたびに消えてくれるので安心です。が、ももし毎回ssh-addするのがめんどくさい方は、MacOSのみ方法があります。
-Kオプションをつければいだけです。こうすると、Macのキーチェーンにパスフレーズが登録され、次回起動時も勝手にssh-addされた状態になります。

```
$ ssh-add -K ~/.ssh/id_rsa
```

さらに、これもめんどくさい人は、以下の内容を~/.ssh/configに登録すればいいです。

```
Host *
    AddKeysToAgent yes
    UseKeychain yes
```

AddKeysToAgentをyesにすることで、-Kオプションをつけなくてもssh-addの時やsshの時に強制的にパスフレーズがMacOSに保存されます。-Kをつけるのがめんどくさい方はぜひ。
また、UseKeychainをつけることで、ssh-agentを利用していなくても、MacOSに保存されたパスフレーズで自動的に~/.ssh/id_rsaなどを複合化してくれるようです。

ちなみにセキュリティ上はあまりよろしくないので、僕は書いていません。毎回-Kしてます。

## 3. ssh agentに追加された鍵を確認する

```
$ ssh-add -l
2048 SHA256:************************************** /Users/*******/.ssh/id_rsa (RSA)
```

先ほど登録した鍵が表示されてればOKです。

## 4. 試してみる

`ssh git@github.com` とか試して見てください。
ちなみにgithubのsshはパスワードではなく公開鍵暗号方式なので、以前ログインしたパスワードが残っているかどうか心配する必要はないです。
パスフレーズ聞かれなかったら成功です。

# まとめ

これで一度入力すれば以降パスフレーズなしでsshやgit cloneできるようななりました！
シェルスクでgitやsshを使う方はぜひ試して見てください！
【Unity拡張】シーンファイルを開くウィンドウを作ったら便利だった

# はじめに
Unityを使っていると、シーンファイル(.unity)を開くという作業が数えきれないほど発生するかと思います。

プロジェクトに存在するファイルが少ないうちはシーンファイルを直接クリックして開くだけでも特に困ることはないのですが、ファイルが増えてくると目的のシーンファイルを探すのに手間がかかるようになってきます。

そこで、プロジェクト内に存在するシーンファイルを**ウィンドウ上から直接開く**ウィンドウを作ってみました。

# 環境
Unity5.6.1f3
Windows 10

# 作ったものについて
![image.png](https://qiita-image-store.s3.amazonaws.com/0/44288/6fa62c4e-21b4-a2a5-7351-5c86bc05dbd5.png)

ウィンドウ上にシーンの一覧がボタンで表示されるようなものを作ってみました。
ボタンをクリックすると対応するシーンを開くことができます。

# ソースコード
Unityプロジェクト内にEditorフォルダを作成して、以下のスクリプトを入れるとこのツールが使えるようになります。

```SceneLaunchWindow.cs
﻿namespace SceneLauncher
{
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEditor;
    using UnityEditor.Callbacks;
    using UnityEditor.SceneManagement;
    using System.Linq;

    public class SceneLaunchWindow : EditorWindow
    {
        private SceneAsset[] sceneArray;
        private Vector2 scrollPos = Vector2.zero;

        [MenuItem("Tools/Scene Launcher")]
        static void Open()
        {
            GetWindow<SceneLaunchWindow>("SceneLauncher");
        }

        void OnFocus()
        {
            this.ReloadScenes();
        }

        void OnGUI()
        {
            if (this.sceneArray == null) { this.ReloadScenes(); }

            if (this.sceneArray.Length == 0)
            {
                EditorGUILayout.LabelField("シーンファイル(.unity)が存在しません");
                return;
            }

            EditorGUI.BeginDisabledGroup(EditorApplication.isPlaying);
            this.scrollPos = EditorGUILayout.BeginScrollView(this.scrollPos);
            foreach (var scene in this.sceneArray)
            {
                var path = AssetDatabase.GetAssetPath(scene);
                if (GUILayout.Button(path))
                {
                    EditorSceneManager.OpenScene(path);
                }
            }
            EditorGUILayout.EndScrollView();
            EditorGUI.EndDisabledGroup();
        }

        /// <summary>
        /// シーン一覧の再読み込み
        /// </summary>
        void ReloadScenes()
        {
            this.sceneArray = GetAllSceneAssets().ToArray();
        }

        /// <summary>
        /// プロジェクト内に存在するすべてのシーンファイルを取得する
        /// </summary>
        static IEnumerable<SceneAsset> GetAllSceneAssets()
        {
            return AssetDatabase.FindAssets("t:SceneAsset")
           .Select(guid => AssetDatabase.GUIDToAssetPath(guid))
           .Select(path => AssetDatabase.LoadAssetAtPath(path, typeof(SceneAsset)))
           .Where(obj => obj != null)
           .Select(obj => (SceneAsset)obj);
        }
    }
}
```

# ツールを使う
画面上部のメニューから　**Tools/Scene Launcher** を選択するとウィンドウが開きます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/44288/7a9d5bd7-6520-badb-0859-41a3e0528dfd.png)

ウィンドウ上に表示されたボタンをクリックするとシーンファイルを開くことができます.
![image.png](https://qiita-image-store.s3.amazonaws.com/0/44288/6fa62c4e-21b4-a2a5-7351-5c86bc05dbd5.png)

シーンを編集しているときにこのツールを使ってシーンを開いてしまうと現在の**編集状態が破棄**されてしまうので注意してください
[javascript]モーダルを作成してみた

#やったこと
フロントエンドエンジニアとして働いてはいるものの、あまりjsに触ってこなかった自分が
最近jsを触ってやったことを紹介したいと思います。
今回はモーダルを作成したのでこちらを紹介させて頂きます。

## コード
class名など結構、適当に書いたので書くときはちゃんと考えて書いた方がいいかもしれません。

```html
    <div class="main">
      <button type="button" id="main_button">ボタンです</button>
      <div class="content1">
        <p>テキストテキストテキストテキストテキストテキスト</p>
      </div>
      <div class="content2">
        <p>テキストテキストテキストテキストテキストテキスト</p>
      </div>
      <div class="content3">
        <p>テキストテキストテキストテキストテキストテキスト</p>
      </div>
      <div class="content4">
        <p>テキストテキストテキストテキストテキストテキスト</p>
      </div>
      <div class="content5">
        <p>テキストテキストテキストテキストテキストテキスト</p>
      </div>
    </div>

    <div class="modal">
      <div class="modal_wrapper"></div>
      <div class="modal_content">
        <p>テキスト</p>
      </div>
    </div>
```
```css
      .main {
        height: 3000px;
        background-color: #ff0000;
        text-align: center;
      }
      .content1, .content2, .content3, .content4, .content5 {
        width: 600px;
        height: 400px;
        background-color: #0000ff;
        margin: 30px auto;
        color: #ffffff;
      }

      .modal {
        display: none;
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
      }
      .modal_wrapper {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.5);
      }
      .modal_content {
          position: fixed;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          color: #ffffff;
          font-size: 30px;
          display: flex;
          justify-content: center;
          align-items: center;
      }
```
```js
window.addEventListener('load', function() {
  const $button = document.getElementById('main_button');
  const $modal = document.getElementsByClassName('modal');

  $button.addEventListener('click', function() {
    $modal[0].style.display="block";
  });

  $modal[0].addEventListener('click', function() {
    $modal[0].style.display="none";
  });

  const windowHeight = window.innerHeight;
  $modal[0].style.height = windowHeight + 'px';

});

```

とりあえずこれだけでいけました。
これはhtmlの方に適当なボタンを設置して押したらモーダルで文言が出るような仕組みにしてます。
WebdriverIOメモ

# WebdriverIOを使うときのメモ

業務でWEBテストをする必要があったので、その時のメモ
[本家サイト](http://webdriver.io/)の[APIDOC](http://webdriver.io/api.html)が充実しているので、英語に免疫のある人はそっち見たほうが良い。

## 作業環境
| ツール | バージョン |
| --- | --- |
| WebdriverIO | 4.8.0 |
| node.js | 6.10.3 |
| npm | 3.10.10 |
| selenium-server-standalone | 3.5.3 |
実際の構築は別の誰かに任せます。

## Tips

#### URLへアクセス
```js:sample.js
browser.url(weburl);
```

#### いろいろ取得
```js:sample.js
// ブラウザのタイトル
browser.getTitle()
// 指定したセレクタ内のテキスト
browser.getText(selector);
// 指定したセレクタのAttribute
browser.getAttribute(selector,attributeName);
```

#### 動作させる
```js:sample.js
// クリック
browser.click(selector);
// input:type=text要素に値を設定
browser.setValue(selector,text);
// セレクトボックスの操作
$(selector).selectByIndex(number)
```

#### フレーム間の移動
```js:sample.js
// フレームへ移動
browser.waitForExist(selector);
browser.frame($(selector).value);
// 親フレームへ戻る
browser.frameParent();
```

#### スクリーンショットの取得
```js:sample.js
// 指定したファイル名の個所（カレントからの相対）に保存される
browser.saveScreenshot('ファイル名');

// こうするとスクリーンショットをBASE64で取得できる
const screenshot = browser.screenshot();
```
Visual Studio Emulator for Androidの使い方2点(apkインストールとプロキシ設定)

Visual Studio Emulator for Android、速くて使いやすいですよね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/fedcca1b-d362-de2a-7986-c072d783d2fb.png)

今回は、これの使い方について2点調査したので共有します。

# 1) apkをインストールする方法

Visual Studioと連携していれば通常個別にインストールすることはありませんが、他で作成したapkをインストールすることも(もちろん)可能です。

(何と、)エクスプローラからドラッグ＆ドロップするだけでインストールできました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/9b9a9492-9de8-4739-23d5-518c2ae3a3d8.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/151c2e1b-9f09-976b-001b-97ca2f6d6920.png)

adb install 的なコマンドはどこにあるのか・・・と探してしまいましたが簡単にできました。

# 2) プロキシ設定

AVDでは"Access Point Names"のあたりで設定しますが、Visual Studio Emulator for AndroidではWi-Fiのオプションで設定します。

設定から
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/f70f3661-fdfa-504c-434a-667aa8217be5.png)

Wi-Fiを選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/5a778b5c-b001-1180-18d3-06f277c0b461.png)

Wi-Fiを <b><font color="red">長押し</font></b> して
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/db80c09f-aee6-167b-b0b2-cb5ff794ae5c.png)

"Modify Network"を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/c5abb476-6961-04a4-0bee-f365d94f460d.png)

あとは"Show advanced options"にチェックを入れて、プロキシサーバの情報を設定すれば完了です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/36328ca5-cd5e-4629-babb-1c529ebb9171.png)

ブラウザでInternet接続できるようになったことを確認してください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/87db3b13-23ec-3a40-fa79-f143148bca2a.png)

# 参考

- [Visual Studio Emulator: install .apk files](https://www.youtube.com/watch?v=Dq7fIEPoi98)
- [Use proxy in Visual Studio Emulator for Android](https://stackoverflow.com/questions/29224560/use-proxy-in-visual-studio-emulator-for-android)
AWS(Amazon Web Services)社のロゴが変わりました


9月12日(火)にAWSさんのロゴが変わりました。

ちょうど当日はAWS社にてパートナー向けの勉強会に参加していました。

勉強会の途中の15時頃にAWS社の方から、
「突然ですが、緊急のお知らせがあります。」
と案内があり、何事かと思っていると。。。

「本日突然ですが、AWS社のロゴが変わりました。
グローバルでのロゴ変更で、突然のことなので、
ガイドライン等はまだ更新されていませんが別途ご案内します」
とのこと

左側が古いロゴで、右側が新しいロゴがになります。
![aws_old_logo.png](https://qiita-image-store.s3.amazonaws.com/0/62038/341af727-2564-a931-c91e-f78dfecd47d1.png)![aws_new_logo.png](https://qiita-image-store.s3.amazonaws.com/0/62038/22cc4759-2302-fb6b-b895-11b2a1c544bc.png)

新しいロゴは小文字の「aws」の下に
Amazon.comでおなじみの矢印が付いています。
やわらかくて優しいイメージですね。

個人的な意見としては、昔から左側のロゴに慣れているので
新しいロゴには少し違和感を感じます。
CKEditorをガラケー向けにカスタマイズする


本ページで記載しているCKEditorのバージョンは
4.6.2
になります。

#WYSIWYGエディタのCKEditorをガラケー向けにカスタマイズ

担当したシステムで
ガラケー向けのHTMLを記載する機能にWYSIWYGエディタを導入しているんですが
運用チームからあまりに不便すぎるので何とかしてほしいとの要望があり早速調査を開始。

既存のWYSIWYGエディタ（一応名前は伏せます）の情報サイトが少なすぎて
ソースを一から追いかけるしかなく・・・
しかたなく中身を見たんですが**汚すぎて吐きそうに**・・・

これはもともと汚いのか・・・
前任者がカスタムした結果こうなってしまったのか・・・
はたまたその両方か・・・

function化されておらず、同じようなロジックがクソほどありました。
何日か頑張ったけど断念。

「無理でした」とも言えないので勝手に新しく作りなおして「改修は無理だったので作り直しました」
と報告することに方針変更。
外見ほぼ一緒なら運用チームも文句言わないだろうし。

どのWYSIWYGエディタを使うかいろいろググった結果、いくつかの候補からCKEditorをチョイス。
選定の決め手は情報量。
カスタム前提なのでカスタムした報告をしている情報サイトの多いやつということで選びました。

##要件

どうせ作り直すし
あとからアレコレ欲しいと言われるのも嫌なので
追加要望もコミで再度要件を聞き直してみる。

改めて必要なボタン、今ある不要なボタンを聞き出してみる。
その結果、出てきたのを以下にまとめてみた。

**欲しい機能リスト**
>[ソース]ボタン・・・HTML表示とタグ表示の切り替え
>[プレビュー]ボタン・・・別WINDOWでHTML表示する
>[貼り付け]ボタン・・・クリップボードの内容を貼り付け
>[元に戻す/やり直す]ボタン・・・操作を戻したり
>[左寄せ/中央寄せ/右寄せ]ボタン※・・・文字位置
>[文字サイズ]ボタン※・・・標準/大/特大の３パターンから文字サイズを選択
>[太字]ボタン・・・太字にする
>[アンダーライン]ボタン・・・アンダーラインをひく
>[文字色]ボタン※・・・文字色を変える
>[リンク]ボタン・・・リンク挿入
>[リンク解除]ボタン・・・リンク挿入の解除
>[水平線]ボタン・・・水平線をひく(hrタグ)
>[画像]ボタン・・・画像挿入
>[行背景色]ボタン※・・・文字背景色を設定
>[テキストエリア内の改行]・・・brタグにしたい※


##方針

対ガラケー向けということでstyleが一切使えないため、上記要件の※部分はカスタムが必要となってきます。他の機能は既存にあるのでボタンを配置するだけで完了。

カスタムが必要な機能を以下のようにしていく。

<br/>**[左寄せ/中央寄せ/右寄せ]ボタン**
デフォルトはスタイルで位置指定される

```
style="text-align:right"
style="text-align:center"
```

これ↑をこう↓変更

```
[左寄せ]
<div align="left">テキスト</div>

[右寄せ]
<div align="right">テキスト</div>

[中央寄せ]
<center>テキスト</center>
```

<br/>**[文字サイズ]ボタン**
デフォルトはスタイルでサイズ指定される

```
<span style="font-size:14px">テキスト</span>
```

これ↑をこう↓変更

```
<font size="5">テキスト</font>
```

<br/>**[文字色]ボタン**
デフォルトはスタイルで色指定される

```
<span style="color:#ff0000">テキスト</span>
```

これ↑をこう↓変更

```
<font color="#ff0000">テキスト</font>
```

<br/>**[行背景色]ボタン**
もともとないので新規作成。
こんな感じ↓

```
<table bgcolor="#ff0000" width="100%">
<tbody><tr><td>テキスト</td></tr></tbody>
</table>
```

<br/>**[テキストエリア内の改行]**
もともとはpタグ

```
<p>テキスト</p>
```

これ↑をこう↓変更

```
テキスト<br/>
```

##実装（定義ファイル）
まずは簡単なところから。
>[テキストエリア内の改行]

これは config.js に定義を書くだけ。

```js:config.js
CKEDITOR.editorConfig = function( config ) {
  config.language = 'ja';

  config.enterMode = 2;
  config.shiftEnterMode = 1;
  ～略～
};
```

enterMode だけ書けばいいんですが
一応shift+Enterの挙動も書いてみました。
1 が br改行で 2がpタグ改行です。
他にblockタグ（divタグ）で囲う改行もできます。

リテラルで書いてますが、CKEDITOR.ENTER_BR など定数が切られているのでそちらを使うのをお勧めします…
<br/>続いて
>[文字色]ボタン

これも定義だけです。

```js:config.js
CKEDITOR.editorConfig = function( config ) {
  ～略～
  config.colorButton_foreStyle.element = 'font';
  config.colorButton_foreStyle.attributes = {'color':'#(color)'};
  config.colorButton_foreStyle.styles = '';
  ～略～
};
```

こんな感じです。
<br/>続いて
>[文字文字サイズ]ボタン

これも定義だけです。

```js:config.js
CKEDITOR.editorConfig = function( config ) {
  ～略～
  config.fontSize_sizes='標準/3;大/4;特大/5;';
  config.fontSize_style = {
    element: 'font',
    attributes: { 'size': '#(size)' },
    overrides: [ {
      element: 'font', attributes: { 'size': null }
    } ]
  };
  ～略～
};
```

こんな感じです。

のこりの
>[左寄せ/中央寄せ/右寄せ]ボタン

は styles.js をいじることで対応。

>[行背景色]ボタン

はpluginを作成することで対応しました。

ちょっと長くなったのでこれらは
[別ページ](http://qiita.com/n_a/items/f401e8548126a3a31b81)
に書きますね。
LINE Messaging APIのDatetime picker actionをPHPで使う


<img width="320" alt="IMG_8493.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/164153/1dd43122-8f6b-a1dc-d2c1-08319f86f11a.png">


**公式SDKアップデートされたのでもうこの処理は不要になりました！一応残しておきますが。**
https://github.com/line/line-bot-sdk-php

---

Datetime picker action。
https://devdocs.line.me/ja/?shell#template-message

今日使いそうなので載せておきます。

```php:index.php
<?php

require_once __DIR__ . '/vendor/autoload.php';

$httpClient = new \LINE\LINEBot\HTTPClient\CurlHTTPClient(getenv('CHANNEL_ACCESS_TOKEN'));
$bot = new \LINE\LINEBot($httpClient, ['channelSecret' => getenv('CHANNEL_SECRET')]);
$signature = $_SERVER["HTTP_" . \LINE\LINEBot\Constant\HTTPHeader::LINE_SIGNATURE];

$events = $bot->parseEventRequest(file_get_contents('php://input'), $signature);
foreach ($events as $event) {
  if ($event instanceof \LINE\LINEBot\Event\PostbackEvent) {
    error_log('postback : ' . file_get_contents('php://input')); // date data in postback field
  }

  if ($event instanceof \LINE\LINEBot\Event\MessageEvent) {
    if ($event instanceof \LINE\LINEBot\Event\MessageEvent\TextMessage) {
      $json = array(
        "replyToken" => $event->getReplyToken(),
        "messages" => [
          array(
            "type" => "template",
            "altText" => "this is a confirm template",
            "template" => array(
                "type" => "confirm",
                "text" => "Are you sure?",
                "actions" => [
                    array(
                      "type" => "datetimepicker",
                      "data" => "datestring", // will be included in postback action
                      "label" => "Please Choose",
                      "mode" => "date", // date | time | datetime
                      //"initial": "", // 2017-06-18 | 00:00 | 2017-06-18T00:00
                      //"max": "", // 2017-06-18 | 00:00 | 2017-06-18T00:00
                      //"min": "", // 2017-06-18 | 00:00 | 2017-06-18T00:00
                    ),
                    array(
                      "type" => "message",
                      "label" => "No",
                      "text" => "no"
                    )
                ]
            )
          )
        ]
      );

      $curl = curl_init() ;
      curl_setopt($curl, CURLOPT_URL, "https://api.line.me/v2/bot/message/reply") ;
      curl_setopt($curl, CURLOPT_HEADER, true);
      curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
      curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: application/json", "Authorization: Bearer " . getenv('CHANNEL_ACCESS_TOKEN')));
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
      curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($json));
      curl_exec($curl);
    }
    continue;
  }
}

 ?>
```