OmniAICreator/Qiita-1.07M huggingface dataset:
VMware 12 Player上のCentOSの環境を設定

## 前提
仮想マシンにCentOSインストールできていること
## 環境
- ホスト Windows10 1703
- VMware Workstation 12 Player 12.5.8 build-8097237
- CentOS release 6.6 (Final)

## 設定
### キーボード
インストール後にUS配置キーボードとして認識されている場合に設定を変更する。
確認

```
[root@localhost ~]# cat /etc/sysconfig/keyboard
KEYTABLE="us"
MODEL="pc105+inet"
LAYOUT="us"
KEYBOARDTYPE="pc"
```
変更

```
[root@localhost ~]# vi /etc/sysconfig/keyboard
```
下記のように変更

```diff
- KEYTABLE="us"
- MODEL="pc105+inet"
- LAYOUT="us"
+ KEYTABLE="jp106"
+ MODEL="jp106"
+ LAYOUT="jp"
KEYBOARDTYPE="pc"
```
反映させるために再起動する。

### IPアドレス固定
固定のほうが検証しやすいと思うので固定設定する。
確認

```
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0 
DEVICE="eth0"
BOOTPROTO="dhcp"
HWADDR="xx:xx:xx:xx:xx:xx"
IPV6INIT="yes"
NM_CONTROLLED="yes"
ONBOOT="yes"
TYPE="Ethernet"
UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
```

変更
```
[root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0
```
下記のように変更

- 「IPV6INIT」を「yes」→「no」
-  「IPADDR」を追

```diff
DEVICE="eth0"
BOOTPROTO="dhcp"
HWADDR="xx:xx:xx:xx:xx:xx"
- IPV6INIT="yes"
+ IPV6INIT="no"
+ IPADDR=192.168.234.128
NM_CONTROLLED="yes"
ONBOOT="yes"
TYPE="Ethernet"
UUID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
```

反映させるために再起動する。
Rspecで悲観的ロックをテストする

悲観的ロックのテストを書くことがあって調べたら、[それっぽい記事](http://tech.actindi.net/3656032930)を発見したが、ペーペーは読んで？？だったから、自分用に噛み砕いたものをメモ。

記事の例として挙げられている、銀行口座のように、同一のデータに対して、複数のユーザーから更新処理が実行される場合に、どちらかの処理をブロックしてデータの競合を避ける必要がある。

- 複数のユーザーがログインしている状態を実現するために、usersをmapしてuser毎に作成したThreadの配列を生成。
- Threadの配列をeachして、Thread#joinで処理が終了するのを待ち、終わったらThreadをdeadにするようにする。
- Mutex#syncronizeでマルチスレッド時の処理を同期実行するようにしたけど、これだとテストできてないのか? ><
- ロックが効いてて、データが更新されていないことを確認する。

```rb

describe 'Transaction Lock' do
  # ロールバックせずに保存するようにする
  self.use_transactional_fixtures = false

  mutex = Mutex.new

  describe '悲観ロックのテスト' do
    it 'お金消えたり増えたりしてないよね' do
      users.map { |user|
        Thread.new {
          # マルチスレッドで複数の処理が競合しないようにMutex#syncronizeで処理をブロックする。
          # mutex使っちゃったらマルチスレッドの意味無くなるのかな。。。分かる方教えてください m__m
          mutex.synchronize do
            # スレッド毎にDB接続
            ActiveRecord::Base.connection_pool.with_connection do
              # 悲観的ロック
            end
          end
        }
      }.each(&:join)

      # お金消えたり増えたりしてないことを確認
      expect(...).to eq(...)
    end
  end
end

```

参考
[RubyのThread](http://www.atmarkit.co.jp/ait/articles/1412/12/news037.html)
[Thread#join](https://docs.ruby-lang.org/en/2.4.0/Thread.html#method-i-join)
[Rubyで基礎的なマルチスレッドプログラミングをするためのサンプル](http://blog.codebook-10000.com/entry/20130804/1375631808)
[RubyのThread、Fiber、Kernel、forkで並列処理やプロセスの深淵へ](http://www.atmarkit.co.jp/ait/articles/1412/12/news037.html)
[RubyのThreadを利用したWebサーバーを作る](http://jangajan.com/blog/2014/09/07/unix-thread-socket-server-in-ruby/)
[RubyでThreadを使う](http://yuji-shimoda.hatenablog.com/entry/2013/05/13/234504)
[irbから学ぶRubyの並列処理 ~ forkからWebSocketまで](http://melborne.github.io/2011/09/29/irb-Ruby-fork-WebSocket/)
[bukuroswift] BUKURO.swiftのススメ

<p>BUKURO.swiftは、月に一度、平日の夜に池袋のコワーキングスペースOpenOffice FORESTで開催される、macOS/iOS/watchOS/tvOSプログラマのための勉強会です。<br />
参加費は無料で、各自コワーキングスペースの利用費を払っていただきます。</p>

<p>様々な方が参加者されていまして、業務でアプリケーションを開発されている方、異なるIT分野の方、趣味でプログラミングをされている方などです。<br />
ただ、共通しているのはプログラミングを学びたいということです。<br />
勉強会に参加するということは、広大なプログラミングの学びの領域を手分けして勉強し、得られた知識を共有するということでもありますし、学んだことを他人に教えることによって、理解を深めるということではないかと思っています。</p>

<p>荀子の言葉に、「聞いたことは忘れ、見たことは覚え、行ったことは理解できる。」がありますが、自分もアプリケーション開発をマスターしたいと試行錯誤してきたのですが、うまくいきませんでした。試験がある学生時代と異なり、社会人となった自分にとって、講義形式での勉強は身に入らず、揃えられた材料を使って手を動かしても実は理解できていなかったりと、このことは実感しました。<br />
そんな自分にとって勉強会の発表の場は、自分で自分のケツを叩く良い勉強のの場となりました。<br />
もし、アプリケーション開発をマスターしたいと考えられている方がいらっしゃいましたら、お待ちしております！</p>

<p>勉強会で発表するということを大げさに考えなくてもと思っていまして、ある分野を勉強し理解できたので発表するだけでなく、今取り組んでいることから課題となっていることを説明し、発表者から参加者に質問をするというのもありで、実際、自分をこれによって何度か助けられました。<br />
ですので、もし、敷居が高そうという理由で参加を躊躇されている方がいらっしゃるのでしたら、全然、大丈夫ですよ！と伝えたいです。</p>

<p>勉強会の名前にSwiftがついているので、Swiftでプログラミングしていないと関係ないや！とお考えの方、こちらも大丈夫です。AppleScript関連しか発表されない方もいらっしゃいます！</p>

<p>平日の夜、開催ということで、終了後、帰宅を急ぐ方が多く、懇親会は開催していません。ですが、年末の勉強会では、終了後、有志でささやかな忘年会のようなことをやろうと思っていますので、お声がけを。希望者がいらっしゃらない場合は中止ですが・・・</p>

<p>自分はプログラマがアプリケーションをプログラミングしてリリースするという行為は表現活動という一面があると思っています。<br />
プログラマがプログラミングすることによって喜ぶ方々がいらっしゃるとすれば素晴らしいじゃないですか。</p>

<p>ほぼ毎月、池袋の片隅でBUKURO.swiftの扉を叩いて入ってこられる方をお待ちしています。いつでも大歓迎ですので、ちょっと、ブクロでお茶する感じの軽いノリで、時間があったらで構いませんので、是非！</p>

関連情報
<a href="https://cocoa-kanto.connpass.com">Cocoa勉強会 BUKURO.swift (connpass)</a><br />
<a href="https://atnd.org/groups/cocoa-study">Cocoa勉強会 BUKURO.swift (ATND)</a><br />
<a href="http://cocoa-study.peatix.com">Cocoa勉強会 BUKURO.swift (Peatix)</a><br />

【Cocoa練習帳】
<a href="http://www.bitz.co.jp/weblog/">http://www.bitz.co.jp/weblog/</a><br />
<a href="http://ameblo.jp/bitz/">http://ameblo.jp/bitz/</a>（ミラー・サイト）<br />
<a href="https://t.co/6P3h2jtbRk>note</a><br />
<a href="https://qiita.com/m_yukio>Qiita</a><br />
ディレクトリを複数階層一発で作成してみる(mkdir -p ちょっと応用)

# mkdir -p時にブレース展開する
現場でTipsを毎日書く習慣があって、mkdirを使用して複数階層のディレクトリを作れっていうのがあった。てことで備忘録としてこれやってみる。(といってもただのワンライナーだが…)

```
$ mkdir -p /tmp/hoge/{a1/a2,b1/b2/b3}
$ tree /tmp/hoge/                            
/tmp/hoge/                                                             
├ ─ ─  a1                                                              
│    └ ─ ─  a2                                                         
└ ─ ─  b1                                                              
    └ ─ ─  b2                                                          
        └ ─ ─  b3                                                      
                                                                       
5 directories, 0 files         
```
GoogleHomeからBacklogのタスクを更新する

# GoogleHomeからBacklogのタスクを更新する

最近購入したGoogleHomeを試していて、
業務になんとか活かせないものかと思い、試しにBacklogのタスクを更新(ステータスを終了)、タスクを追加できるようにしてみた。

今回、プログラミングはせずに行なっており、
セキュリティに関しても考慮していない点は要注意。

## 前提
Backlogのアカウントを持っていて、なんとなくBacklog APIの使用方法がわかっている。


## 試した結果
GoogleAssistantで数字を使用したい場合、日本語だとあまりうまく認識しないように思う。
そのため、タスクIDや何かの管理番号を使って更新したい場合は、あまり向かないかも。

タスクの追加に関しては、思いついた時のメモくらいなら使用できるかなぁ。

ただ、メモならBacklogである必要はないというか、、別のもののほうがいいかもしれないですね

## やったこと
GoogleAssistant経由で以下を実行できるようにした。

* Backlogのタスクのステータスを完了に更新
 ※[Ok,Google タスク完了 {タスク番号}]

* Backlogにタスクを追加
 ※[Ok,Google タスク追加 {タスク名}]

## 設定方法

1） IFTTTのアカウントを作成する。
   https://ifttt.com/
   この時にGoogleHomeで使用しているGoogleアカウントと紐づける。

2) My Appletsから[New Applet]をクリック

3) [+ this]をクリック

4) Search Servicesに[google assistant]と入力し、GoogleAssistantをクリック

5) タスク追加の場合は[Say a phrase with a text ingredient]をクリック
　 タスク完了の場合は、[Say a phrase with a number]

* タスクの追加

| 項目       |       値 |    備考    |
|:-----------------|------------------:|:------------------:|
| What do you want to say?|タスク追加 $|音声コマンド|
| What's another way to say it?(optional)||別の音声コマンド|
| And another way? (optional)|||
| What do you want the Assistant to say in response?|タスクを追加しました|音声コマンドを受け付けた時の返答|
| Language|Japanese||

* タスクのステータス完了

| 項目       |       値 |    備考    |
|:-----------------|------------------:|:------------------:|
| What do you want to say?|タスク完了 #|音声コマンド|
| What's another way to say it?(optional)||別の音声コマンド|
| And another way? (optional)|||
| What do you want the Assistant to say in response?|タスクを完了しました|音声コマンドを受け付けた時の返答|
| Language|Japanese||

6) Create Triggerをクリック

7) + thatをクリック

8) Search Servicesに[webhook]と入力し、webhooksをクリック

9) [Make a web request]をクリック

10) 下記の情報を入力

* タスク追加の場合

| 項目       |       値 |    備考    |
|:-----------------|------------------:|:------------------:|
|URL|https://xxxx.backlog.jp/api/v2/issues?apiKey={backlogのAPIキー}|xxxxは使用しているbacklogのスペース|
|Method|POST||
|Content Type |application/x-www-form-urlencoded||
|Body|projectId=[プロジェクトID]&issueTypeId=[課題種別ID]&priorityId=3&summary={{TextField}}||

* タスク更新の場合

| 項目       |       値 |    備考    |
|:-----------------|------------------:|:------------------:|
|URL|https://xxxx.backlog.jp/api/v2/issues/[プロジェクトキー]-{{NumberField}}?apiKey={backlogのAPIキー}|xxxxは使用しているbacklogのスペース|
|Method|POST||
|Content Type |application/x-www-form-urlencoded||
|Body|statusId=4||

プロジェクトIDやIsuueTypeIDが不明な場合は、
Backlogに一つ課題を追加し、その課題のキーを使用して以下のURLで確認できる。

https://xxx.backlog.jp/api/v2/issues/[課題キー]?apiKey=[backlogのAPIキー]

11) [Create Action]をクリック

12) [Finish]をクリック

13) ここで実行できるが、反映まで多少時間がかかるので、コマンドが認識されない場合は少し時間をおいてから試す。


## IFTTTの実行ログ
IFTTTの[activity]で実行ログを参照できる。
ただし、Webhookでエラーが発生してもどのような内容でエラーとなっているかは確認できない点は試していて不便だった。

## タスク追加の場合のIFTTTのConfigureのキャプチャ
![タスク追加.png](https://qiita-image-store.s3.amazonaws.com/0/213799/33b32f58-b220-048a-c416-ad7e7ed1b6e4.png "タスク追加.png")
AVContentProposalは本当に便利なのか


# AVContentProposalとは
tvOS10から登場した、次のエピソードの訴求をクールかつシンプルに実装することができるAVKitのAPIです。
![avcontentproposal001.gif](https://qiita-image-store.s3.amazonaws.com/0/35008/7ecdea76-609f-4e74-46b2-ab2b653eba2c.gif "avcontentproposal001.gif")


# 問題
以前[こういう記事](http://toshi0383.hatenablog.com/entry/2016/09/24/191628)を書きまして、AVContentProposalちゃんと動かないじゃん！という問題提起をしました。transitionアニメーション中にMENUを押して戻ると表示がおかしくなります。シミュレータではオートレイアウトのエラーが出てクラッシュします。

![avcontentproposal002.gif](https://qiita-image-store.s3.amazonaws.com/0/35008/47a532a5-8cff-1688-8269-2e48f36ca796.gif "avcontentproposal002.gif")

tvOS11で試したところ、依然として問題が継続していました。

> 2017-11-18 21:53:54.683980+0900 TVOSTest[11885:456841] *** Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with anchors <NSLayoutXAxisAnchor:0x600000673400 "AVFocusProxyView:0x7faeb5e47ad0.left"> and <NSLayoutXAxisAnchor:0x600000673700 "AVPlayerLayerView:0x7faeb5e1ee50.left"> because they have no common ancestor.  Does the constraint or its anchors reference items in different view hierarchies?  That's illegal.'


ワークアラウンドを実装できましたので共有します。

# ワークアラウンド
原因はAVPlayerViewControllerがすでにプレイヤーがいなくなっていることにContentProposalViewControllerが気づかないのが原因なので、

- 気づかせてあげる
- 状況がハッキリするまではボタンなどUIを表示しない

の2点が解決方法です。要するに、地道にフラグ管理するということになります。

```swift
class ContentProposalViewController: AVContentProposalViewController {
    var shouldDismiss: Bool = false {
        didSet { dismissIfNeeded() }
    }
    @IBOutlet private var button: UIButton! {
        didSet { button.alpha = 0.0 }
    }
    @IBOutlet private var textView: UITextView! {
        didSet { textView.alpha = 0.0 }
    }
    override var preferredFocusEnvironments: [UIFocusEnvironment] {
        return [button]
    }
    override var preferredPlayerViewFrame: CGRect {
        return CGRect(x: 432, y: 20, width: 1056, height: 594)
    }
    @IBAction private func button(sender: UIButton!) {
        dismissContentProposal(for: .accept, animated: true, completion: nil)
    }
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        if !shouldDismiss {
            UIView.animate(withDuration: 0.2) {
                self.button.alpha = 1.0
                self.textView.alpha = 1.0
            }
        } else {
            dismissIfNeeded()
        }
    }
    private func dismissIfNeeded() {
        if shouldDismiss {
            DispatchQueue.main.async { [weak self] in
                self?.button?.alpha = 0.0
                self?.textView?.alpha = 0.0
                self?.dismissContentProposal(for: .reject, animated: false, completion: nil)
            }
        }
    }
    deinit {
        print(#function)
    }
}
```

これで、MENU押して戻った時に見た目がおかしくなることはなくなりました。シミュレータでもクラッシュしません🎉

![avcontentproposal003.gif](https://qiita-image-store.s3.amazonaws.com/0/35008/ab1986a8-bb2a-6e3a-e7a8-eef7d64262a4.gif "avcontentproposal003.gif")


# まとめ

「AVContentProposalは本当に便利なのか？」

上記のようなワークアラウンドをすれば、とっても便利です！

以前作った以下のサンプルアプリを更新しておきましたのでご興味ある方はご覧ください。
https://github.com/toshi0383/tvOS-10-Sampler
ansibleでシンプルにAWS EC2でGo言語をインストールして再起動する

# 前提条件
- Cloud9でansibleを動かしたい。
- すでにEC2インスタンスを作成してある。
    - IPアドレス割り当て済み
    - キーペアが設定済み
- ansible 2.4.1.0

# やりたいこと
- ansibleのPlaybookをシンプルに書きたい。(→2ファイルになりました)
- 次のコマンドをAWS EC2 インスタンスにssh接続して、下記のコマンドを実行したい。

```shell-session
$ sudo yum update
$ sudo yum groupinstall -y "Development Tools"
$ sudo yum groupinstall -y "Development Libraries"
$ sudo yum install golang
$ sudo shutdown -r now
```

# 作成したもの

## inventry file
EC2の割り当て済みのIPアドレスと、キーペアに指定したキーファイル(.pem)をインベントリファイルに記述する。

```ini:hosts
[ec2servers]
54.249.xxx.xxx   ansible_ssh_private_key_file=~/.ssh/aws-ssh.pem
```

## Playbook
```yaml:ec2setup.yml
---
- hosts: ec2servers
  name: ec2 first setup
  user: ec2-user
  sudo: yes
  gather_facts: true

  tasks:
    - name: yum update 
      yum:
        name: '*'
        state: latest

    - name: yum groupinstall "Development Tools"
      yum:
        name: "@Development tools"
        state: latest

    - name: yum groupinstall "Development Libraries"
      yum:
        name: "@Development Libraries"
        state: latest

    - name: yum install golang 
      yum:
        name: 'golang'
        state: latest

    - name: reboot
      command: shutdown -r now

    - name: wait connection
      wait_for_connection:
        delay: 10
        timeout: 180
```
## 実行
```shell-session
$ ansible-playbook -i hosts ec2setup.yml
```

# ハマったところの解説

## ansibleでsshで鍵認証(キーファイル)を指定する方法
インベントリファイルに接続先ホストと同じ行に`ansible_ssh_private_key_file`とキーファイルを記述する。AWS EC2へのssh接続に限らず、`~/.ssh/config`に接続情報を登録したりせずに、ホストごとにキーファイルを指定したい場合に使える。

```ini
[ec2servers]
54.249.xxx.xxx   ansible_ssh_private_key_file=~/.ssh/aws-ssh.pem
```

## ssh接続するときのユーザー名
Playbookにログオンしたいユーザー名を指定する。

```yaml
user: ec2-user
```

## 都度sudoでコマンド実行したい
Playbookに`sudo`を記載する

```yaml
sudo: yes
```

## なんでansibleの`ec2_*`モジュールを使わないの？

### (1) 今回実行したホスト側の環境がCloud9
- どこからでもブラウザ開いて、コードをかける
- shell実行ができる

これは、ansible向き！ってことで試してみた。

### (2) Cloud9にansible2.4をインストール

```shell-session
$ sudo apt install software-properties-common
$ sudo apt-add-repository ppa:ansible/ansible
$ sudo apt update
$ sudo apt install ansible
```
- ※ ansibleリポジトリを追加しないで、`sudo apt update`して`sudo apt install ansible`するとansible 1.5.4が追加される上に各種ライブラリの更新がかかってCloud9のdisk容量を600MBくらい消費するので、ちょっとツライ。

### (3) Cloud9からansibleで`ec2_*`を使ってみた……

1. Cloud9はユーザーにコンテナっぽい感じで、開発環境を提供
2. 外部にSSH/http接続するときNATを経由
3. ansibleで`ec2_*`を使うときは、`localhost`にssh接続してawscliを実行される
4. Cloud9は外部からssh接続できない
5. ansibleで`ec2_*`を実行するとき、`localhost`にssh接続できないので実行が失敗する
6. ＼(^o^)／

- もしかして、Cloud9にsshdをインストールして～とやれば`localhost`にssh接続できるようになるのかもしれないけど、試せてません。
- ansibleからec2インスタンスを作成や削除の作業をしなければ、`ec2_*`モジュールを使わずにもどうにかなる。

### cloud9から外部接続したときの接続元(Cloud9側)のIPアドレスを調べる方法
接続元IPアドレスをセキュリティグループのインバウンドに登録しないとssh接続できないので、あらかじめ調べておく。

```shell-session
$ curl ifconfig.co
104.155.xxx.xx
```
参考：[自分のIPアドレスを知る方法](https://qiita.com/sharow/items/66d89136180884a2f7b7)
Amazon Echo リセット方法まとめ

4,5年 Amazon Prime 会員を続けていた甲斐があってか、発売直前くらいに招待依頼をしましたが、無事 11/16 に発送され、11/17 に Amazon Echo が届きました。
初期設定などをしている中で、うまくいかない点があり、サポートにチャット対応をしていただいたところ、Amazon Echo のリセット方法を複数教えていただいたのでそのまとめです。

# Amazon Echo リセット方法
環境
- Amazon Echo (第2世代) 
- Amazon Alexa iOS アプリ

今回は iOS デバイスに Echo 端末を登録しましたが、以下のリセット手順は Android でもほぼ共通だと思います。

## Echo のリフレッシュ・再起動
1. Echo の電源ケーブルを取り外す
2. そのまま３分ほど放置
※電気的なトラブルの場合、放電が必要なため実施
3. 電源を接続する

その後自動で起動します。
iOS アプリとの連携などの設定は残ったままです。


# Echo と Alexa アプリの登録解除・再登録
1. Alexa アプリを開く
2. メニューから「設定」を開く
3. 「デバイス」項目のEcho端末を選択
4. 下部「その他」にあるデバイスの登録先右側にある「登録解除」をタップしてEcho端末の登録を解除
5. メニューを開き、最下部にある「サインアウト」をタップ
6. Alexaアプリをアンインストールし、再インストール
7. Alexaアプリを開き、サインインして再度 Echo 端末を登録


# Echo の初期化
1. マイクオフボタンと音量を下げるボタンを、ライトリングがオレンジ色に変わるまで（約20秒間）同時に長押し。 ライトリングが青色に変わります。  
※体感ではボタンの長押しは5秒程度でした。また、Echo以外のDotなどの端末ではリセット方法は異なるかも知れません。
2. 初期化後起動が完了すると、ライトリングがオレンジ色に変わり、Echo端末がセットアップモードになるのでしばらく待ちます。
3. Alexaアプリを開き、再度セットアップします。
SwiftでGoogle Maps Elevation APIを利用して地点の標高を取得する

# 概要

Google Maps Elevation APIにリクエストして標高の情報を取得する実装のメモです。

## Elevation APIについて
```
Google Maps Elevation API のシンプルなインターフェースを使用すると、
地球上の任意の地点における標高データを問い合わせることができます。
さらに、任意のルート上で標高データをサンプリングするようリクエストして、
そのルートに沿った標高の変化を計算することもできます。
```
こういったことができます。
公式のデベロッパーガイドは[こちら](
APIのドキュメントは[こちら](https://developers.google.com/maps/documentation/elevation/intro?hl=ja))です。

## 実装してみる

### 準備：APIキーの取得

APIのリクエストにはAPIキーが必要です。
[このページを開いて](https://developers.google.com/maps/documentation/elevation/get-api-key?hl=ja)、「キーを取得する」ボタンから取得します。

<img src="https://qiita-image-store.s3.amazonaws.com/0/10057/ef6a03c9-9cf2-e9bd-b39e-be3f084a4479.png" width="400">


### 実装

簡単な例として、ViewControllerが表示されたタイミングでAPIリクエストを行うように実装しました。

```swift
import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        request()
    }

    private func request() {
        let configuration = URLSessionConfiguration.default
        let session = URLSession(configuration: configuration)

        let apiKey = "<YOUR_API_KEY>"
        let url = "https://maps.googleapis.com/maps/api/elevation/json?key=\(apiKey)&locations=35.360556,138.727778"
        let task = session.dataTask(with: URL(string: url)!) { (data, response, error) in
            if let error = error {
                print(error)
            } else {
                let json = try! JSONSerialization.jsonObject(with: data!, options: []) as! [String: Any]
                if let results = json["results"] as? [[String: Any]] {
                    for result in results {
                        if let location = result["location"] as? [String: Double] {
                            print(location["lat"])
                            print(location["lng"])
                        }
                        print(result["elevation"] as? Double)
                    }
                }
            }
        }
        task.resume()
    }
}
```

<YOUR_API_KEY> の部分を事前準備で取得した自分のAPIキーに置き換えればAPIリクエストが成功すると思います。
`locations`には標高を取得したい地点の緯度・経度を指定してください。
上記の例では富士山が指定されています（緯度:35.360556, 経度:138.727778）

### 複数の位置情報をリクエストする

複数の地点の標高を取得したい場合は、リクエストパラメータのlocationsに複数の緯度経度を渡します。

* `locations=40.714728,-73.998672|-34.397,150.644`

地点と地点は`|`（パイプ）で接続します。

### APIのレスポンス

```
{
   "results" : [
      {
         "elevation" : 1608.637939453125,
         "location" : {
            "lat" : 39.73915360,
            "lng" : -104.98470340
         },
         "resolution" : 4.771975994110107
      }
   ],
   "status" : "OK"
}
```
ドキュメント通りですが、こういう感じで返ってきます。


以上、Google Maps Elevation APIを使って標高情報を取得する実装のメモでした。
SideeXでマッチングアプリTinderの右スワイプ自動化

みなさんTinder知ってますか？
かなり流行してるマッチングアプリで無料で利用できます
元々tinderはiPhoneとかandroidのアプリでデスクトップ版が最近リリースされました

tinderをやっているとプロフィールを確認せずにとにかく右スワイプしたいって人は多いと思いますので今日はこれを自動化してみようと思います

とは言ってもプログラミング不要なことはプログラミングせずに済ませたい

なので今回はSelenium IDEの後継SideeXを使います
sideexはchromeかfirefoxのエクステンション(アドオン)なんですが、chrome版は今回きちんと動かなかったのでfirefoxのアドオンで行います
要するにめっちゃ簡単だし誰でもできるということです!

↓映像が重くてqiita上では再生できないみたいなのでtwitterに飛んで再生を推奨


<blockquote class="twitter-tweet" data-lang="en"><p lang="und" dir="ltr"><a href="https://t.co/t9IfarH6j6">pic.twitter.com/t9IfarH6j6</a></p>&mdash; supertinder (@supertinder) <a href="https://twitter.com/supertinder/status/931858473922396160?ref_src=twsrc%5Etfw">November 18, 2017</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



わざわざ文章で説明もダルいのでquicktime playerの画面収録を利用しました
qiitaの人たちも記事をわざわざ文章なんてダルいフォーマット使わずにどんどん映像をキャプチャしてアップロードしてほしい。ちなみにquicktime playerだと拡張子が.qtだからffmpegでmp4に変換が必要

あとはtinderの画像をキャプチャして機械学習に利用したりしたら色々面白そう
年齢と住んでいる場所で絞れるから画像から年齢を判定したり住んでいる地域を判定したりできる。かもしれない。とは言っても画像のサンプル数が足りなさそうではあるし、facebookクロールしたほうがうまくいくかもしれない

参考にした記事
https://qiita.com/gluelan2013/items/c21b1a186bc5e56523ee
https://qiita.com/mriho/items/a16b3c618c378efeb58f
https://qiita.com/akameco/items/6ff78b0918e96f871f57
not null制約がついたカラムにunique key 制約つけるとnot null制約がはずれる

```
mysql> create table a(col1 int);
mysql> alter table a modify col1 not null;
mysql> desc a;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| col1  | int(11) | NO   |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.01 sec)

mysql> alter table a modify col1 int unique;
mysql> desc a;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| col1  | int(11) | YES  | UNI | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.01 sec)
```

uniqueキーを貼るときは上記を踏まえた上で、nullを許容しないのであればnot null制約も同時につけること。

```
mysql> create table a (col1 int);
mysql> alter table a modify col1 int not null;
mysql> show columns from a;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| col1  | int(11) | NO   |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.04 sec)

alter table a modify col1 int not null unique;
mysql> desc a;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| col1  | int(11) | NO   | PRI | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.06 sec)
```
WindowsでSpatiaLiteを動かしてみる

SpatiaLiteとはSQLite上でGISを扱えるようにする拡張モジュールです。
PostgreSQLに対するPostGISのような位置づけです。

SpatiaLite本家のサイトはこちら：http://www.gaia-gis.it/gaia-sins/
サイトの下部に "MS Windows binaries" とあるので、そこから64bit版をダウンロードして動作確認をしてみます。
ファイル名はmod_spatialite-4.3.0a-win-amd64.7z。

解凍するとSQLiteのコンソールアプリケーションsqlite3.exeと、SpatiaLiteモジュールであるmod_spatialite.dllが同じディレクトリにありますので、以下のように実行してみます。

# 起動と初期化

まずsqlite.exeを起動します。引数なしで起動すると、インメモリの一時データベースを自動生成します。

```
D:\spatialite\mod_spatialite-4.3.0a-win-amd64>sqlite3.exe
SQLite version 3.8.11.1 2015-07-29 20:00:57
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
```
まず、`load_extension` 関数を使ってSpatiaLiteモジュールを読み込みます。

```
SELECT load_extension('mod_spatialite');
```

次に、`InitSpatialMetaData`関数を実行してSpatiaLiteが利用するメタデータテーブルを作成します。これを実行しておかないと地理情報系の関数が正しく動作しません。

```sql
SELECT InitSpatialMetaData(1);
```

# ジオメトリ型のカラムを持つテーブルの作成

３次元の座標を持つ点を格納できるテーブルを作ってみましょう。SpatiaLiteでは、以下の流れとなります。

* まず、ジオメトリ型以外のカラムを持つテーブルを作る
* そのテーブルにジオメトリ型のカラムを追加する

SQLで書くと以下のようになります。

```sql
CREATE TABLE t(id INTEGER, name TEXT);
SELECT AddGeometryColumn(
    't',                 -- テーブル名
    'point',             -- カラム名
    0,                   -- SRID
    'POINTZ',            -- ジオメトリ型
    'XYZ',               -- ジオメトリの次元
    1                    -- 1ならNOT NULL制約あり
);
```

PostGISのように、ジオメトリ型のカラムを持つテーブルを`CREATE TABLE`一発で作ることはできないので注意してください。

# データの挿入と取り出し

これで、`t`テーブルの`point`カラムに三次元点を格納できます。(1, 2, 3)を格納してみましょう。`ST_GeomFromText()` という関数を使います。点は `'POINTZ(1.0 2.0 3.0)'`で表します。

```
INSERT INTO t VALUES(1, 'some', ST_GeomFromText('POINTZ(1.0 2.0 3.0)'));
```

このとき、点(1,2,3)は内部表現でDBに格納されます。人間が読める形で取り出すときには、格納したカラムを引数として`ST_AsText()`関数を使います。

```
SELECT id, name, ST_AsText(point) AS pt FROM t;

-- 1|some|POINT Z(1 2 3)
```

入れたとおりの値が取り出せました。
ASK（AlexaSkillsKit）のリクエストタイプ（インテント）について

# 標準のリクエストタイプ（インテント）
基本的なリクエストタイプ（インテント）。ちなみにこれ以外もあるみたいなので、随時更新していきたい。


## LaunchRequest
特に指示もしないで、スキルを呼び出したときに発動されるインテント
例えば、「天気予報をひらいて」（スキル名だけで、どこの都市だとかの指定をしていない。）
このレスポンスとしては、だいたいそのスキルの説明を発現させる。

## IntentRequest
開発者側で定義したインテント

## SessionEndedRequest
Alexaがセッションが終了したことを伝えるインテント。このインテントが送信される理由として、

1. ユーザーが終了といったとき
2. ユーザーが何も言わない、または開発側で定義したインテントに一致しない言葉を発した時。
3. エラーが発生した場合。

スキルはこのインテントの後に応答をかえすことができない。
特定の拡張子のファイルをリストアップ

拡張子が.xls .xlsm .xlsx のファイルだけリストする
Get-ChildItem | where{$_\_.mode -match "a" -and $__.name -match ".\*\\.x.*"}

Mode                LastWriteTime     Length Name
-a---        2017/11/11     18:47       8813 recult.xlsx
-a---        2017/11/06     20:32      14359 シート.xlsm
-a---        2017/11/05     20:08      15829 ファイル.xlsm
[メモ]ラズパイzero w事始め(物理電源スイッチの取り付け）

#概要

ラズパイマガジン2017年、６月号の特集2「ラズパイ工作　トラブル解決12」より、P51の「動かない1　電源用USB端子の接触が悪くなった」を参考に、電源用ピンヘッダとトグルスイッチを接続して、物理電源スイッチを追加しました。
※今回は設定ファイルの編集など一切ないので完全に作業メモです。

##物理電源スイッチの追加

![完成系](https://lh3.googleusercontent.com/Nhz69GFWVP7ZVcnf6L8m6NDnucEmBG1LIpa4DrB09ucX71wL9rvscIeZtkYkFtqxTC-cEIAnxS7gc75D_f2csYfkCtSCAJIIZ7ZOhkpgU3XHDB1L8LKg9Sc9bLPRgJa9H0kDtNp3Ls3JBUuiy4ucW3VphGvZFOanSAEO1qnzCBqCE942D2aVgUFYiZ1D3HW-tYuMj9RLxKoH-IOzzwyQHlsiBKVgDA9OreOXcIi3l9Uol6N2kBFD2BVbfphOvkM46sRYjRhjGBDsCCA679NdU0EBHYx57dL_8hLSV1m5PIlQYtv7niZCBlFJkTNjx1Zez7iFxnZn9SUUh0YhQmrFi6gICEUfEJr4A3-7ZWYH72hrgPit02iAieHX7rBvOLy0bgDPsSf507MSlvLNirdvqsNTV7o7oe5UUZwPypjBnyC7ON994Hg7wiprI3B6mKS9wVUWi_F8GsMS8B5eSj1w9oNN31x453jsJj816hBnCOO-FTbZkJyc6k97eyTDB6oFlv5OYG6wz2iUa-R_rugQiIkYWn52umxrGAwjCpG99NI_IQuYeWGoSq9BpMu3CkG3qgZRqFxr4mCj3mhSEfEOAWBGRNyFldko46r6WhM8lQ=w1092-h819-no)

作業前の写真を撮り忘れたので、いきなり完成系ですがラズパイ基板上の「RUN端子」にピンヘッダを半田付けして、余っているジャンパーケーブルとトグルスイッチを接続します。
写真手前側のトグルスイッチON/OFFで電源が落ちることを確認しました。

ついでに半田があったまっていたので、GPIOのピンヘッダーの取り付けも行いました。
Android Studioの過去バージョンの置き場

既出っぽいですが、自分の備忘録も兼ねて掲載。
# リンク
[https://developer.android.com/studio/archive.html](https://developer.android.com/studio/archive.html)
# 掲載理由
以前見た時は過去バージョンのアーカイブは消されていたのですが、10月頃？に復活したようです。
仕事の都合でどうしても過去バージョンを使う必要がある場合、
これでアップデートを恐れる心配がなくなりましたね！:ok_hand:
(そんなプロジェクトあるのかな。。)
Railsで使用するbasic認証

# 概要
開発環境でRailsアプリを作成している時に、簡単なセキュリティ対策のため、basic認証を行えないか調査しました。その結果を記載します。

# 詳細
## 実装

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :basic
  
  private
  def basic
    authenticate_or_request_with_http_basic do |name, password|
      name == "test" && password == "123456"
    end
  end
end
```

# 解説
**application_controller.rb**
共通のコントローラーの処理を記載するファイル。  
  
```ruby:
before_action :<アクション名>
```

全てのアクションが実行される前に行う処理を記載する。
また、引数として渡すアクション名はシンボルとして渡す。

```ruby:
  private
  def アクション名
    authenticate_or_request_with_http_basic do |name, password|
      name == "test" && password == "123456"
    end
  end

```
nameにログインユーザ名、passwordにパスワードを記載する。
impressionist gemを使ってrailsでページビューのランキングを作る

## はじめに

impressionist gemを使ってページビューやユニークユーザー数が取得できるんだけど、それをソートしてランキング化したいという要望があると思う。

調べてみると、まずimpressionsテーブルからimpressionable_idを取り出して、今度はそれを対象のテーブルに対してwhereで条件として適用している記事があった。

「impressionist Gemでランキングを作る」
https://tagamidaiki.com/create-ranking-with-impressionist-gem/

けれどこのようなやり方は、あまりいい方法じゃないなという話です。

## なぜいい方法じゃないのか

記事ではimpressionの対象はArticleなのでそれを前提として、何が困るのかというと

- MySQLじゃないとFIELD関数がないので困る
- impressionsのcreated_atに条件を指定しても、それは参照された際にimpressionがcreateされた日時なので困る
    - おそらく「昨日書かれた記事の中でのランキング」が欲しいと思うんだけど、記事では「impressionがあった日からのランキング」になっている
        - つまりArticleのcreated_atによって抽出しないと、過去の記事がランキングに出てくる
- 上と似ている話で、impressionsテーブルからデータを取得する際にArticlesを条件にしたいのでjoinすることになる

## 解決策

これはimpressionist のwikiに書いてある
https://github.com/charlotte-ruby/impressionist/wiki/How-to-order-records-by-impressionist_count.

これを読めば分かるってなもんだけど、impressionistを知っている状態で、もっと分かりやすくまとめとくと

- 対象とするテーブルに `impressions_count` なカラム作ってintegerにしておく
- 対象となるモデルクラスに `:counter_cache` オプション追加
- あとは `impressions_count` に対してorderを使う

### 対象とするテーブルに `impressions_count` なカラムを作ってintegerにしておく

```ruby
class AddCounterCacheToArticle < ActiveRecord::Migration[5.1]
  def change
    add_column :articles, :impressions_count, :integer, default: 0
  end
end
```

このカラムはimpressionsテーブルがcreateされるとき、その対象のテーブルのimpressions_countがupdateされるようにしておく。

### 対象となるモデルクラスに `:counter_cache` オプション追加

```ruby
class Article < ActiveRecord::Base
  is_impressionable counter_cache: true
end
```

これで下記のようなSQLが発行され、結果を集計しそれを加算して`impressions_count` が増える。

```sql
INSERT INTO "impressions" ("impressionable_type", "impressionable_id", "user_id", "controller_name", "action_name", "request_hash", "ip_address", "session_hash", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING "id" （省略）
SELECT COUNT(*) FROM "impressions" WHERE "impressions"."impressionable_id" = $1 AND "impressions"."impressionable_type" = $2  [["impressionable_id", 1], ["impressionable_type", "Article"]]
UPDATE "articles" SET "impressions_count" = COALESCE("impressions_count", 0) + 6 WHERE "articles"."id" = $1  [["id", 1]]
```

（コードを読んでもどこで計算しているのか分からなかったので次のリストはメモ程度）

- 厳密に言うと、元のimpressions_countに対して集計結果との差分を足し合わせている
  - 例1: article.impressions_countは0（またはnull）のデータだが集計した結果6なら `+ 6`
  - 例2: article.impressions_countは1のデータだが集計した結果6なら差分の `+ 5`

これの何が嬉しいかというと、運営していく中でこのカラムを追加しても集計した値が格納されること。

### あとは impressions_count に対してorderを使う 

```ruby
@most_viewed = Article.order('impressions_count DESC').take(10)
```

これで先に述べたように条件を直接Articleに指定すれば良いだけになる。
最初に引用した記事のように日付で条件をつけたいなら次のようになるだろう。

（読みやすさのために改行した）

```ruby
@most_viewed = Article.order('impressions_count DESC')
                  .where("? <= created_at", Time.now.yesterday)
                  .where("created_at <= ?", Time.now).take(10)
```

## その他

`impressions_count` のカラム名を変えたい場合なども [README](https://github.com/charlotte-ruby/impressionist)に書いてある。

## 参考

- impressionistの導入については、[impressionist gemを使ってrailsでページビューをトラッキングする](https://qiita.com/yimajo/items/995584ede90be1a873ce)に書いた
ＥＳＰ３２でＧＡＭＥエミュレーターを動かす(ＳＭＳ編)

# 概要
ESP31で(かなり著名な)家庭用ＧＡＭＥエミュレーターを動かしているサイトを見つけたので、追試を試みる。
[esp31-smsemu ]　https://github.com/espressif/esp31-smsemu
これがうまくいったらシリーズ化出来ないかと夢想する。

nesemuは半年放置の状態のプロジェクトに手を加えたら、一週間後に本家で正式更新され、努力(?)が無駄になりすこしがっかり。
smsemuは２年間放置状態ですが、さて今度はどうなることやら。
#やること、やった事
ハードは
[ＥＳＰ３２でＧＡＭＥエミュレーターを動かす]https://qiita.com/hi631/items/a0dfb6ee91b90c028445
を見てください。ピンの配置も全く一緒です。

ソフトは今回は変更が多いのでGitHubに上げました。
[esp32-smsemu]https://github.com/hi631/esp32-smsemu
ダウンロードして、COMポートと通信速度をボードに合わせてコンパイルすれば動くはずです。

smsファイルのフラッシュへの書き込みは下記のコマンドで行います。
esptool.py --chip esp32 --port "/dev/ttyxx" --baud $((921600)) write_flash -fs 4MB 0x140000 xxxx.sms
"/dev/ttyxx"、xxxx.smsは自分の環境に合わせましょう。
アドレスがnesemuとは変わっていますので注意の事。いやならpartitions.csvを弄ってください。

make flash して、Resetすれば動くと思います。
smsファイルの書き込みに失敗している場合、LCD画面は青枠の中に黒い画面が(さびしく)見えるはずです。

#今回苦労した所
今回はsmsemuをnesemuのI/Oに接ぎ木して動かしています。
一応、ちゃんと画面も音も出てコントローラーで遊ぶことができます。
デバッグ画面には、60FPSと表示されますが眉唾のような気がします。
元ネタとは開発環境がだいぶ変わっているようで、最初は山のようなエラーがドバー。なにが何だか判りませんでした。
力技で適当につなぎ合わせたら動きました。smsemuをnesemuは同じ人(チーム)で作られていると思われます。

#その他

　上記記載のハード、ソフトは無保証であり、各自の責任においてご利用願います。
　中身がよく判らないのに、動けばＯＫという勢いで改変していますので、何か傷を抱えているかもしれません。
　また蛇足ですが、世の中にはフリーでないプログラムも存在しますので、注意の上で遊ばれることをお勧めします。
SlackのMacアプリで送信ボタンが表示されない

# 問題点

WEBのSlackで表示される**送信**ボタンがMacアプリMacアプリで表示されない。

WEB
![slack-send03.png](https://qiita-image-store.s3.amazonaws.com/0/141934/375f612a-d976-3551-201e-5aa3c1addd03.png)

Macアプリ
![slack-send01.png](https://qiita-image-store.s3.amazonaws.com/0/141934/3a5ae55b-12e0-d4a8-12a3-08cabfdc6e8f.png)

# 原因
Macアプリ起動中にWEBでSlackの表示言語を日本語に変更した。

> 補足：Macアプリ起動中にWEBでSlackの表示言語を日本語に変更すると自動でMacアプリの表示言語も日本語に切り替わるけど、送信ボタンの表示設定がMacアプリには反映されなかったようです。

# 解決方法

Macアプリを再起動すれば**送信**ボタンが表示されるようになった。

![slack-send02.png](https://qiita-image-store.s3.amazonaws.com/0/141934/6882a0bb-9661-e6ac-7310-e92901d6b0b6.png)
kuromojiとicuを使って漢字、ひらがな、ローマ字変換する

elasticsearchとかsolrでお世話になるkuromojiですがこんな使い方もできました。

```scala
import com.atilika.kuromoji.ipadic.Token
import com.atilika.kuromoji.ipadic.Tokenizer
import scala.collection.JavaConversions._

val tokenizer: Tokenizer = new Tokenizer()
tokenizer.tokenize("今日の晩ご飯はお豆腐").map(_.getReading()).mkString
```

実行結果
```
res: String = キョウノバンゴハンハオトウフ
```

ただ変な（？）日本語入れるとToken#getReading()が*を返します。

```scala
tokenizer.tokenize("イエに帰る").map(_.getReading()).mkString
```

実行結果

```
res: String = *ニカエル
```

なので*の場合はToken#getSurface使うようにしてみました。

```scala
tokenizer.tokenize("イエに帰る").map { token => if (token.getReading == "*")  token.getSurface else token.getReading }.mkString
```
せっかくカタカナにできたのでひらがなに変換してみます。
icu使うと簡単です。

```scala
import com.ibm.icu.text._

val kataToHira = Transliterator.getInstance("Katakana-Hiragana")
kataToHira.transliterate("キョウノバンゴハンハオトウフ")
```

実行結果
```
res: String = きょうのばんごはんはおとうふ
```

ですが長音ある場合はちょっと困った動作になります。。。
```scala
kataToHira.transliterate("スーパーマーケット")
```

実行結果```
res: String = すうぱあまあけっと
```

これが望む答えの場合もあるんでしょうが、、個人的に長音はそのままそっとしておいてほしいのでこんなことをしました。

```scla
"スーパーマーケット".split("ー").map { kataToHira.transliterate }.mkString("ー")
```

実行結果

```
res: String = すーぱーまーけっと
```

最後にひらがなをローマ字にしてみます。

```scala
val hiraToLatin = Transliterator.getInstance("Hiragana-Latin")
hiraToLatin.transliterate("きょうのごはんはおとうふ")
```

実行結果

```
res: String = kyounogohanhaotoufu
```

まとめたものは[こちら]
(https://github.com/tky/japanese-tokenizer)
[メモ]ラズパイzero w事始め(プリインストールアプリの削除で軽量化)

#概要

ラズパイマガジン２０１７年６月号を参考にOSの軽量化を実施。

##軽量化の内容

- 仮想コンソール（tty）を減らす。
- 未使用のアプリケーションを削除(バックアップでの消費ディスクを減らしたい)。

##実施手順

まずは、仮想コンソール用の設定ファイルをユーザ独自設定用のディレクトリ、「/etc/systemd/system/」ディレクトリにコピー

```bash
sudo cp /lib/systemd/system/getty-static.service /etc/systemd/system/
```

コピーした設定ファイルを編集。パラメータ「ExecStart」は起動時に立ち上げる仮想コンソールなので、必要数だけ残して、残りは削除。私の場合はgetty@tty2.service getty@tty3.serviceを残しました。

```bash
ExecStart=/bin/systemctl --no-block start getty@tty2.service getty@tty3.service
```

続いて、不要なアプリケーションの削除

```bash
sudo apt-get purge wolfram-engine # Wolfram Alphaはウルフラム・リサーチが開発した質問応答システム 683 MB
sudo apt-get purge libreoffice* # OSSのオフィススイーツ。245MB
```

合計　928MBの不要なアプリケーションを削除しました。
vscodeのkeybindins.jsonメモ

随時追加

## ctrl+shift+dで現在行を複製
Contextual DuplicateなどのDuplicate拡張をインストールしたあと、

```json
 { "key": "ctrl+shift+d", "command": "lafe.duplicateCode" },
```
## 選択した範囲にマッチする次の範囲に移動
eclipseのctrl+k と同じ挙動

```json
  { "key": "alt+n", "command": "editor.action.moveSelectionToNextFindMatch" },
```

## Dash
Dash拡張を入れた後に

```json
  {
    "key": "ctrl+shift+r",
    "command": "extension.dash.specific",
    "when": "editorTextFocus"
  },
```
Railsでユーザーをコンソールから作成する方法

# はじめに
チーム開発に途中から参加して、少し困ったのでメモ
ローカル環境において、ユーザーを作成しようとした
しかし、deviseのSignupページがなく（管理者のみがユーザーを作るため）どうやって管理者画面にログインすればいいか詰まった


# 解決方法
`$ rails console`を利用してモデルからインスタンスを作成

コンソールを起動して
`[1] pry(main)> User.create!(name: 'hoge', email: 'admin@example.com', password: 'password')`
それぞれのUserモデルに指定されたカラムに値を入れて実行
nameカラムは標準では存在しないのでemailとpasswordで十分
IE11、Edgeで要素のscale値を変更するとガタつく場合

IE11、Edgeで要素のscale値を変更するとガタつく場合、
変形させる要素にrotate(0.001deg)を追加するとガタつきがなくなった。

　
下記のように変形させる要素に下記を記述する。

```
transform: rotate(0.001deg);
```

 
 
TweenMaxで変形させる場合は、下記のように記述するとガタつきがなくなった。

```
TweenMax.fromTo(element, 0.5, {
	scale: 1.3,
	rotation: 0.001
}, {
	scale: 1
});
```
Pythonista3に絵本を読ませよう

#はじめに
Google Cloud Vision APIの無料トライアルに登録しました。
色々あるみたいだけど、文字認識なんか結構使えそう。
じゃあ、Pythonista3でiPadに絵本読ませて、子育て支援しちゃおう!

#用意するもの
iPad(Pythonista3インストール済み)
絵本

#作る 
作るものはiPad(iPhone)内蔵のカメラで絵本を写したら読み上げてくれるソフトです。
##やり方
1.カメラから絵本画像を取得する。
2.Google Cloud Vision APIに画像を送信し、文字を認識させる。
3.認識した文字を読み上げる

ソースコード全体は[github](https://github.com/mitazet/python_code/blob/master/read_picture_book.py)に置いてあります。
##Google Cloud Vision APIを使う
Google Cloud Vision APIのAPIキーの取得までは[Syncer](https://syncer.jp/cloud-vision-api)で分かりやすく説明されていました。
これを参考にAPIキーを取得します。
また、PythonでCloud Vision APIの使い方は[Google Cloud Vision API sample for python](https://qiita.com/bluemooninc/items/075a658f0d2c7ac62efc)を参考にしました。
ここでは文字認識なので`'type': 'TEXT_DETECTION'`を指定します。
以下が、実際のコードです。

```py3
GOOGLE_CLOUD_VISION_API_URL = 'https://vision.googleapis.com/v1/images:annotate?key='
API_KEY = 'SET_YOUR_API_KEY'
def goog_cloud_vison (image_content):
	api_url = GOOGLE_CLOUD_VISION_API_URL + API_KEY
	req_body = json.dumps({
		'requests': [{
			'image': {
				'content': image_content
			},
			'features': [{
				'type': 'TEXT_DETECTION',
				'maxResults': 10,
			}]
		}]
	})
	res = requests.post(api_url, data=req_body)
	return res.json()
```
JSON形式で、認識結果が返ってきます。
##文字を取得する
JSONからTEXT部分を取り出しているだけです。

```py3
def get_text_from_return(res_json):
	text = res_json['responses'][0]['fullTextAnnotation']['text']
	return text
```

##カメラから絵本を写して読み上げる
Pythonista3の`photos.capture_image()`で「カメラ起動→撮影写真の使用」ができるので、それを利用します。
いちいち保存しなくて済むように、少し工夫をしています。
読み上げは`speech`を使用して簡単にできます。

```py3
console.alert("ページを写して", "", "Ok")
pil_img=photos.capture_image()

size = (int(pil_img.size[0]*0.2), int(pil_img.size[1]*0.2))
pil_img = pil_img.resize(size)

#空のインスタンスに保存し、バイナリデータを取得する
img = io.BytesIO()
pil_img.save(img,"JPEG")
img_byte = img.getvalue()

img_str = str(base64.b64encode(img_byte),"utf-8")

#Cloud Vision APIで文字を認識させてTEXTデータを取得する
res_json = goog_cloud_vison(img_str)
text_json = get_text_from_return(res_json)

##内容の確認と読み上げ
print(text_json)
speech.say(text_json)
```
#テスト
スクリプトを実行します。
![EB042A4D-9AD8-48BE-A4A3-E3CDE5C5E67D.jpeg](https://qiita-image-store.s3.amazonaws.com/0/140055/ced66379-349a-f303-3b05-6a71fed1dfc0.jpeg)

カメラが起動するので撮影します。

![21A0473C-1AD4-468F-AD45-279B38F49B61.png](https://qiita-image-store.s3.amazonaws.com/0/140055/91b5861c-c845-f6d6-87f0-3f9d85740dcc.png)

そして、認識。
そして、読み上げ成功!!

![F81B8ADA-A349-4247-BDC1-C2FAA560D495.jpeg](https://qiita-image-store.s3.amazonaws.com/0/140055/1f0a362e-5ea4-ad28-e1b8-80a02483a570.jpeg)
__実際には音声が流れています。__

#最後に
もうちょっと工夫すれば、本当に子育て支援できるかもしれません。
難しい書籍だと認識精度&読み上げ精度がイマイチだったので、絵本にしたことがばれませんように。
[#TouchDesigner] マルチパスGLSL

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3132373430322f33313137333465332d343535372d363932342d373965382d3536616338333738346661622e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/127402/bc09fa66-6974-cf2d-8204-18782e0426fc.png)

# はじめに
1つのGLSL TOPから複数の画像をレンダリングする、「Multiple Render Target」を行う方法について解説します。
取るに足りない感じの記事なので雑に書きます。
![2017-11-18_183050.png](https://qiita-image-store.s3.amazonaws.com/0/127402/8ea1639f-1367-93c5-f60d-c82864093f2d.png)


# GLSL TOP の設定
**\# of Color Buffers** を、用意するレンダーターゲット数分確保します。
![2017-11-18_182713.png](https://qiita-image-store.s3.amazonaws.com/0/127402/94489b7a-d53c-ee4c-1ece-824fee71f592.png)

# GLSLコード
![2017-11-18_182549.png](https://qiita-image-store.s3.amazonaws.com/0/127402/956c25fc-022b-db76-19b2-8f3527b73b69.png)

```c:glsl_pixel
layout (location=?) out hoge
```
で、レンダーターゲットのインデックスと、値を格納する変数名(hoge)を指定することができます。
後は普段のGLSLコードと同様それぞれの変数にピクセル色を格納します。


# レンダーターゲットの取り出し
レンダリングした結果(レンダーターゲット)の画像の取得は、
以下のようにRender Select TOP内のTOPパラメータにGLSL TOPをアサインし、
Color Buffer IndexをGLSLコード内で指定したインデックスに変更することで行えます。

![2017-11-18_182636.png](https://qiita-image-store.s3.amazonaws.com/0/127402/fe95d31c-1653-db2f-04fe-628df319650a.png)

![2017-11-18_182652.png](https://qiita-image-store.s3.amazonaws.com/0/127402/aa990450-033c-2e5a-a4f2-9c502f870e49.png)

# 終わりに
この方法とFeedback TOPとを組み合わせることで、マルチパスレンダリング(ReactionDiffusionなど)が行えるみたいですが、
まだそこまでの検証ができていないので、でき次第記事をあげようと思います。
タスク・アイデアを思いついた瞬間Trelloカードに入れる(GoogleHome)

# 背景
我が家では日々のタスク管理やアイデアのストックにTrelloを使用しています。
ただ、タスクやアイデアを思いつくのは、ふとした瞬間で。
食事をしていたり、テレビを見ていたり…
「後でTrelloに入れよう」と思って、そのまま放置してしまうことがありました。
そこで、GoogleHomeに話しかけたらTrelloのカードに入れてくれるような仕組みをつくりました。

# 実現したいこと
 + GoogleHomeに「Trelloに～追加して」と言ったらTrelloのカードが生成される
 + カードは「今週やること」ボードの「今週todo」リストに追加される

# 方法
**IFTTT**を使用して、GoogleAssitantとTrelloを連携しました。
手順は以下の通りです。

## thisを設定する
1. IFTTTの**this**でGoogleAssistantを選択する

1. 「Say a phrase with a text ingredient」を選択する
![IFTTT_01.png](https://qiita-image-store.s3.amazonaws.com/0/213964/2281e37f-4637-7612-8e54-fa16f7610ccb.png)

1. トリガーとなる言葉を決めて入力する
「$」には追加したいカードの名前が入ります  
![IFTTT_02_01.png](https://qiita-image-store.s3.amazonaws.com/0/213964/8628189d-d73b-80f8-f386-0a67dafec2bc.png)
    
1. GoogleAssistantが認識したら返す言葉を決めて入力する
![IFTTT_03.png](https://qiita-image-store.s3.amazonaws.com/0/213964/127e511c-e8ff-929b-ff69-c180c1195d64.png)

1.  言語を決定する

1. 「Create trigger」で完成

## thatを設定する

1. IFTTTの**that**でTrelloを選択する  
最初は自分のアカウントと連携させる必要があります
1. 「Create a card」を選択する
1. カードを追加したいボードとリスト、リストに追加する際の位置を入力・選択する
![IFTTT_04.png](https://qiita-image-store.s3.amazonaws.com/0/213964/1eef7668-ff7e-a50f-8969-49193a9b5378.png)

1. タイトルでAdd ingredientを選択して、`TextField`を選択する
![IFTTT_05.png](https://qiita-image-store.s3.amazonaws.com/0/213964/7b41a19d-ab2d-9d30-da36-24ed85bbbfd1.png)

1. それ以降はお好みで設定する
1. 「Create action」で完成

# 結果
+ 「ねえ、グーグル。トレロ、年賀状を書く。」と話しかけると、「ほう、それがお望みか」と言って、トレロにカードを追加してくれるようになりました
+ たまに「トレロ」という言葉を認識してくれませんが、めげずに話しかけると認識してくれます

# 気づき事項
+ トリガーに「トレロに $ と追加して」という言葉を入れてみましたが、設定してしばらく経つと「と追加して」だったか「って追加して」だったか忘れてしまうため言い切る形にしました（人間側の問題ですね…）
+ トリガーに「トレロ」と「トレロに追加して」を併用すると、「トレロ」の段階でGoogleHomeが反応して「に追加して」という謎のカードができてしまうことがありました…「トレロに追加して」ではなく「やること追加して」にしてみました
Azure App Service で C# を使う場合に Git デプロイでアセンブリできない現象を回避する

Web App や Function App で C# を使う場合、デフォルトの設定だとアセンブリファイルがロックされるようになっている。  
デプロイオプションによって各種 Git と連携すると更新されない問題が発生するため、以下の設定を入れてこの挙動を回避する。

アプリケーション設定
`MSDEPLOY_RENAME_LOCKED_FILES=1`

参考
https://github.com/projectkudu/kudu/wiki/Configurable-settings
ビルド対象のモジュールを環境ごとに分ける

# What want?

- environmentごとにビルド対象のモジュールを分ける
- webpack.config.jsは触らない。angular-cli.jsonも触らない。nodeやgulpのビルドスクリプトも用意しない。
- environment.tsをプレーンな設定ファイルにする。Angularオブジェクト（guardやcomponent）を持ち込まない。

# How to do?

- routing定義でLazyLoadingModuleへの参照パスをenvironmentによって切り替えることでビルド対象を切り替える

# Example

```ts:app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { environment } from '../environments'

// 通常のルート定義
const routes: Routes = [
  {
    path: '',
    component: TopComponent,
  },
  {
    path: 'user',
    loadChildren: './users/users.module#UsersModule'
  },
];

//　環境ごとの追加ルート
const additionalRoutes: Routes = !environment.production ? [
  {
    path: 'develop',
    loadChildren: './develop/develop.module#DevelopModule'
  },
] : [
  {
    path: 'analyze',
    loadChildren: './analyze/analyze.module#AnalyzeModule'
  },
];

@NgModule({
  imports: [RouterModule.forRoot(
    // ルートを結合する
    [...routes, ...additionalRoutes]
  )],
  exports: [RouterModule]
})
export class AppRoutingModule { }
```

以上で、`ng build`つまりdev環境ならdevelop.moduleがビルドされ、`ng build --prod`つまりproduction環境ならanalyze.moduleがビルドされる。

webpackのloader段階で参照関係を解決できていないと失敗するため、additionalRoutesの持ち方はArray.pushの引数などにせず上記のように変数で持つと良い。

# Conclusion

- LazyLoadingModuleを利用することで、ビルド設定を変えずenvironmentファイルもプレーンに保ち、angularアプリ内で環境毎のビルド対象をコントロールすることができる。
Twitter で、oauth2 を使って フォローワーを取得

python3 の oauth2 を使って、フォロワーを取得する方法です。


```py:followers_oauth2.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#   followers_oauth2.py
#
#					   Apr/25/2019
# --------------------------------------------------------------------
import sys
import os
import json
from dotenv import load_dotenv
import oauth2 as oauth
# --------------------------------------------------------------------
def get_info_proc(client,id):
	url = "https://api.twitter.com/1.1/users/show.json?user_id="
	url += str(id)
	response, data = client.request(url)
	if response.status == 200:
		dict_aa = json.loads(data)
		str_out = str(id) + "\t" + dict_aa['screen_name'] + "\t"
		str_out += dict_aa['name']
		print(str_out)
	else:
		sys.stderr.write("Error: %d\n" % response.status)
#
# --------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")

dotenv_path = '.env'
load_dotenv(dotenv_path)
CONSUMER_KEY = os.environ.get("CONSUMER_KEY")
CONSUMER_SECRET = os.environ.get("CONSUMER_SECRET")
ACCESS_TOKEN = os.environ.get("ACCESS_TOKEN")
ACCESS_TOKEN_SECRET = os.environ.get("ACCESS_TOKEN_SECRET")

nnx = 20
url = "https://api.twitter.com/1.1/followers/ids.json"
params = {'screen_name': "ekzemplaro",
	'count': nnx}

consumer = oauth.Consumer(key=CONSUMER_KEY, secret=CONSUMER_SECRET)
access_token = oauth.Token(key=ACCESS_TOKEN, secret=ACCESS_TOKEN_SECRET)
client = oauth.Client(consumer, access_token)
#
url= "https://api.twitter.com/1.1/followers/ids.json?screen_name="
url += params['screen_name'] + "&count=" + str(nnx)

response, data = client.request(url)
print(response.status)
if response.status == 200:
	print ("OK")
	json_str = data
	dict_aa = json.loads(json_str)
	results = []
	icount = 0
	for id in dict_aa['ids']:
		print(icount,id)
		get_info_proc(client,id)
		icount += 1
else:
	sys.stderr.write("Error: %d\n" % response.status)
#
sys.stderr.write("*** 終了 ***\n")
# --------------------------------------------------------------------
```

CONSUMER_KEY
CONSUMER_SECRET
ACCESS_TOKEN
ACCESS_TOKEN_SECRET
は、自分のものと置き換えて下さい。

```text:.env
CONSUMER_KEY = '******'
CONSUMER_SECRET = '******'
ACCESS_TOKEN = '******'
ACCESS_TOKEN_SECRET = '******'
```

次のバージョンで確認しました。

```text
$ python --version
Python 3.7.3
```
DockerでPHP7、MySQL5.7、PHPixie3の開発環境を構築する

# はじめに
Dockerで、[PHPixie](https://phpixie.com/)フレームワークの環境を構築する方法がweb上でなかなか見つからなかったのでここに投稿します。

# 目次

- はじめに
- 概要
- 動作環境 
- 手順
- おわりに


# 概要
以下の環境の開発環境を構築することがゴールです。PHPixieの初期画面が表示されることが期待値です。

![スクリーンショット 2017-11-18 13.28.03.png](https://qiita-image-store.s3.amazonaws.com/0/84126/71164da1-00fa-72a3-d1d3-d06755538a55.png)

- CentOS 7
- PHP7
- MySQL 5.7
- PHPixie 3
- Apache 2.2

# 動作環境
- macOS Sierra 10.12.6
- Docker for Mac

# 手順

## PHPixieをcomposerでダウンロードする
```
$ composer create-project phpixie/project phpixie
```


## Docker Containerの作成
今回、Docker環境を構築するにあたりDockerイメージを作成したので、そちらを利用します。

```bash
$ docker pull econoics0it0bem0116/php7-phpixie
$ docker run -d --privileged -p 8080:80 -v {現在のディレクトリまでの絶対パス}/phpixie:/var/www/html --name php7-phpixie econoics0it0bem0116/php7-phpixie /sbin/init -DFOREGROUND
```

### Apache初期セットアップ
Apacheを起動いたします。

```
$ docker container exec -it php7-phpixie sh

(container内)
# systemctl start httpd
```

### MySQL初期セットアップ
MySQLの初期パスワードを取得して、パスワードリセットします。

```
(container内)
# cat /var/log/mysqld.log | grep password
2017-11-18T08:09:36.277776Z 1 [Note] A temporary password is generated for root@localhost: {初期パスワード}

# mysql_secure_installation ##パスワードを更新する
```

### database接続設定

- assets/config/database.phpを修正する

```php
<?php

return array(
 	'default' => array(
        'database' => 'phpixie',
        'user'     => 'root',
        'password' => 'P@ssw0rd',
        'adapter'  => 'mysql', // one of: mysql, pgsql, sqlite
        'driver'   => 'pdo'
    )
);
```

- 接続動作確認


```
# ./console framework:database drop
Database succesfully dropped or does not exist
# ./console framework:database create
Database succesfully created or already exists
```

### 動作確認
http://localhost:8080　
にアクセスすると、以下の画面が見えればここまで成功です。

![スクリーンショット 2017-11-18 13.28.03.png](https://qiita-image-store.s3.amazonaws.com/0/84126/71164da1-00fa-72a3-d1d3-d06755538a55.png)

以上で終了です。

# おわりに
PHPixie自体のセットアップは、composerでダウンロードして、database接続設定を変更するのみなので、非常に簡単に使い始めることができます。

# 備忘
今回の環境構築方法では、Apache・MySQL・config設定は手動で行いましたが、これもDockerの動作内でできるようにする予定です。
完了したら、こちらの記事も更新しようと思います。
【Go】開発環境を作るまで(Mac + SublimeText)

# Goの開発環境を作るまで(Mac + SublimeText)
## 今回のゴール
GoをMac(Mac OS Sierra 10.12.6) にインストールして、開発ができる環境を整えること。
## 書いた理由
Macを買い直した時とか、1からインストールし直すと色々忘れてるためその備忘録
## やること
- Goのインストール
- SublimeTextの設定
    - format
    - lint
    - imports
    - シンタックスハイライト
- Hello World

## Goのインストール
流れは以下
1. Homebrewインストール
2. Homebrewを使ってGoをインストール
3. GOPATHを設定

### 1. brewのインストール
以下コマンドで、インストール
xcodeのライセンスとかあるので、読んでagreeと打つ。

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

### 2. Goのインストール

```
brew install go
```

### 3. GOPATHの設定
ターミナル起動時に読み込まれるように設定。今回は「~/playground/go」をGOPATHにする。

```shell-session:~/.bash_profile
if [ -f ~/.bashrc ] ; then
. ~/.bashrc
fi
```

```shell-session:~/.bashrc
export GOPATH=$HOME/playground/go
export PATH=$GOPATH/bin:$PATH
alias ll='ls -lsa'
```

```
$ go version
go version go1.9.2 darwin/amd64
```

これでGoがインストールされました。簡単だけどよく忘れてググる。

## Sublime Textの設定

### エディタの設定
1. SublimeのパッケージンストーラでGoSublimeをインストール
 1. 「command+shift+p」で入力バーを開く
 2. 「Package Control:Install Package」を選択
 3. 「GoSublime」を選択
2. goのライブラリをインストール

```shell-session:command
go get golang.org/x/tools/cmd/goimports
go get github.com/golang/lint/golint
```
3． Sublimeの設定を変更(focus_viewをfalseにしておかないと、saveするたび別枠へ移動するので注意)

```:GoSublime.sublime-settings
{
  "env": {"GOPATH":"$HOME/playground/go"},

  "fmt_cmd": ["goimports"],
  "comp_lint_enabled": false,
  "on_save": [
    {
      "cmd": "gs9o_open",
      "args": {
        "run": ["sh", "go vet && golint"],
        "focus_view": false
      }
    }]
}
```

4 SublimeTextを再起動

これでそれなりのGo開発環境ができます。

## Hello World
以下のようなファイルを用意して実行するとhello worldを拝めます。

```go:main.go
package main

import "fmt"

func main() {
	fmt.Println("hello world")
}
```
```
go run main.go
hello world
```

まあこれだけじゃ味気ないので以下のようにファイルを修正して「http://localhost:8080/
」アクセスするとブラウザからhello worldを拝めます。

```go:main.go
package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "hello world") }) // ハンドラを登録する。hello worldにあるまじきまさかの無名関数w
	http.ListenAndServe(":8080", nil)
}
```

週刊Goとして記事を毎週書いて行きたいところです。
以上。


 参考文献
[Homebrew macOS 用パッケージマネージャー](https://brew.sh/index_ja.html)
[Sublime Textで快適なgolangの開発環境](https://qiita.com/69guitar1015/items/f69d004976de4272b65f)
[ターミナル起動時に.bashrcを読み込むようにする](http://blog.ruedap.com/2010/09/13/mac-bash-bashrc)
[API Reference – Sublime Text 3 Documentation](https://www.sublimetext.com/docs/3/api_reference.html)