OmniAICreator/Qiita-1.07M huggingface dataset:
MacBook Air歴7年のぼくがProを買ってみて思ったこと

このたび愛用していたMacBook Air 11in 2011モデルが[オブソリート認定](https://support.apple.com/ja-jp/HT201624)されたため、  
新しいパソコンとしてMacBook Pro 13in 2017モデルを購入しました。

## 本当はMacBook Proは嫌だった
ノートパソコンは常に持ち運ぶべきと考えているため、処理速度より持ち運びを重視しました。

1. 分厚く重い
	- 「邪魔だし持って行きたくない」とか負けた気がする
1. 13インチ以上しかない
   - バッグに入らないのでは？という疑念があった
1. ぶっちゃけ高い
   - 「壊すのが怖いから置いていこう」とか考えたくない

これにより`持ち運ばない → 何もできない`を避け、
`とりあえず持ち運ぶ → 何かしらできる`状況を作りました。  


## どのマシンを買うべきか
2017年にはAirの11インチが廃止されました。  
軽量・薄型部門はAirの13インチ、もしくはMacBook無印。  
ここで2017年モデルのMacBookとMacBook Pro、そして2015年モデルのMacBook Air 11インチの中古が選択肢に挙がりました。

当初、ポリシーに沿いMacBook Air 2015年モデルの購入を検討していましたが、開発者としてMacBook Proも興味がありました。

MacBook Air 2015モデルは2年前のモデルであり、オブソリート化も2年間早まります。  
今回の再購入の理由がサポート切れである以上、これは大きなデメリットでした。  

また、「MacBookは処理が遅く、開発に向いていない」という意見もあります。  
外部メディアもUSB-Cとなり、MacBookは1個、MacBook Proは2個以上です。こちらもMacBook Proで悩む種でした。  

そこで検討内容を図でまとめることにしました。  

||MacBook Air 2015(11in)|MacBook 2017(12in)|MacBook Pro 2017(13in)||MacBook Air 2011(11in)|
|:--|:--:|:--:|:--:|:--:|:--:|
|高さ（cm）|1.7|1.31|1.49||1.7|
|幅（cm）|30|28.05|30.41||30|
|奥行き（cm）|19.2|19.65|21.24||19.2|
|重量（kg）|1.08|0.92|1.37||1.08|
|値段（最安値）|9万円〜|12万円 〜|15.5万円 〜||-|
|USB|USB-A（2個）|USB-C（1個）|USB-C（2個以上）||USB-A（2個）|
|オブソリートまで|最長あと5年|最長あと7年|最長あと7年||オブソリート|

MacBookとMacBook Airの値段が3万円しか差がないことから、MacBook Airは中古のマシン & サポート期間が短いという特徴より、早々に優先度が低くなりました。  

2017年モデルのMacBook Proは最安価15万円台から購入可能です。  
MacBookは12万円と差額は3万円ですが、他のスペックを加味した場合、値段の差で決める必要はないなと感じました。  

幅・奥行きはほぼ同じなため、誤差の内です。  
タッパがProの方がやや大きく、普段使っていた持ち歩きケースに入るか不安でしたが、結果的には大丈夫でした。  

やはり重量問題が避けて通れず、ここが最後まで悩むポイントとなりました。  
MacBookに比べMacBook Proは4キロほど重くなります。これは「重いから持ち運びたくない」に該当するかもしれないと懸念がありました。  

MacBookの持ち運びを優先すべきか、重量を犠牲にし開発者としてのMacBook Proを買うべきか。  
1ヶ月ほど実機に触れたりレビューを調査したりと検討したところ、Proのメリットが目立つように感じ、結果的にProを購入しました。

## 案外MacBook Proでも大丈夫だった
1. 分厚く重い  
  → 細さはAir並みなので大丈夫。ただ重さはAirと比べ、やはり重く感じる。
1. 13インチ以上しかない  
   → 横幅は同じ。縦幅は少し伸びたけど割と大丈夫だった。むしろウィンドウが上下に配置できて嬉しい
1. ぶっちゃけ高い  
   → 値段で扱いは変わらなかった。というかAirも十分高い。

総評すると、MacBook Proを買っておいてよかったなと感じました。

重量感が以前に比べ大きくましたため、「持ち運びたくない」という気持ちが出てきてしまいました。
こちらが慣れの問題であるかどうかは今後の使用具合に左右されると思います。  
それ以外の問題は特に感じていません。十分に使用に耐えるマシンを手に入れたと思います。

## みんなもMacBook Proを買おう
今回MacBook Proの購入を"高速な処理速度のマシン"ではなく"持ち運びやすいマシンの中でそれなりの処理速度"というアプローチで検討しました。  
これはMacBook Proユーザからすればかなり異端な部類に入ると理解しています。  

ですが、もしかしたら少数ながら、私と同じような悩みでマシン選びをしている人がいるかも分かりません。  
そのような方がいらっしゃいましたら、ぜひ当記事を見ていただき、MacBook Proを検討してみて欲しいと思います。  

最後になりますが、MacBook Proはハードウェア・ソフトウェア共にとても良い出来のマシンです。ぜひ体験して見てください。
Raspberrypi 3でUART通信する際の課題と解決方法

#Raspberrypi 3でUART通信する際の課題

Raspberrypi 2以前では使用できていたUARTがそのままでは使えない．

#UARTが使えない原因

pi3のUARTはminiUARTという機能を使って実現されているが，
**miniUARTのクロックはVPUとリンクしており，VPUのクロックが変わるとボーレートも変化してしまうことが原因**．
https://www.raspberrypi.org/documentation/configuration/uart.md

>The baud rate of the mini UART is linked to the core frequency of the VPU on the VC4 GPU. This means that as the VPU frequency governor varies the core frequency, the baud rate of the UART also changes. This makes the UART of limited use in the default state. Also, when the linux console uses the mini UART (Raspberry Pi 3, Raspberry Pi Zero W), as a consequence of the UART being disabled, the console is also disabled.

※2以前ではPL011(ARMプロセッサのUART機能)を使ってUARTを実現していたが，3では新規追加されたBluetoothにPL011を割り当てており，UARTはminiUARTと呼ばれる機能を使用するようになった，らしい．

#UARTを使うには

解決方法は2つあるようだ．

**1. クロックを固定する**
/boot/config.txtに以下の記述を追加する．
`enable_uart=1`
この記述によってコアクロックが250MHzに固定される（Tubo時は400MHzに自動でセットされる）．
https://www.raspberrypi.org/documentation/configuration/uart.md
>The Linux console can be re-enabled by adding enable_uart=1 to config.txt. This also fixes the core_freq to 250Mhz (unless force_turbo is set, when it will fixed to 400Mhz), which means that the UART baud rate stays consistent.

**2. Bluetoothに割り当てていたPL011をUARTに割り当てる**
先に書いておくが，この方法ではBluetoothが使えなくなる．

/boot/config.txtに以下の記述を追加する．
`dtoverlay=pi3-miniuart-bt`

#注意点
いずれの場合においても /dev/serial0を通してUART通信することに注意．
https://www.raspberrypi.org/documentation/configuration/uart.md
>The primary UART is that assigned to the Linux console, which depends on the Raspberry Pi model as described above, and can be accessed via /dev/serial0.
Python > 実装の変更による処理時間の比較 > .sum()の使用 > 84us to 24us

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.1.0
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
```

### 概要

TensorFlowで学習したネットワークのweightとbiasを使った計算に関して、実装の違いで処理時間の比較をしている。

関連: http://qiita.com/7of9/items/f267e59790526e49a7fd

### 比較対象

```py
    # weight
    for idx1 in range(wgt[0]):
        for idx2 in range(wgt[1]):
            conv[idx2] = conv[idx2] + src[idx1] * weight[idx1, idx2]
```
と

```py
    # weight
    for idx2 in range(wgt[1]):
        tmp_vec = weight[:,idx2] * src[:]
        conv[idx2] = tmp_vec.sum()
```

参考: https://stackoverflow.com/questions/32316978/numpy-array-multiplication-slower-than-for-loop-with-vector-multiplication


### 全コード

Jupyter code.

```py:profile_calc_conv_170722.ipynb
%%timeit

import numpy as np
import math
import sys


def calc_conv1(src, weight, bias, applyActFnc):
    wgt = weight.shape
    conv = [0.0] * bias.size

    # weight
    for idx1 in range(wgt[0]):
        for idx2 in range(wgt[1]):
            conv[idx2] = conv[idx2] + src[idx1] * weight[idx1, idx2]
    # bias
    for idx2 in range(wgt[1]):
        conv[idx2] = conv[idx2] + bias[idx2]
    # activation function
    if applyActFnc:
        for idx2 in range(wgt[1]):
            conv[idx2] = calc_sigmoid(conv[idx2])
    return conv  # return list


def calc_conv3(src, weight, bias, applyActFnc):
    wgt = weight.shape
    conv = [0.0] * bias.size

    # weight
    for idx2 in range(wgt[1]):
        tmp_vec = weight[:,idx2] * src[:]
        conv[idx2] = tmp_vec.sum()
    
    # bias
    for idx2 in range(wgt[1]):
        conv[idx2] = conv[idx2] + bias[idx2]
    # activation function
    if applyActFnc:
        for idx2 in range(wgt[1]):
            conv[idx2] = calc_sigmoid(conv[idx2])
    return conv  # return list


INP_NODE = 100
weight = np.random.randn(INP_NODE,2)
src = np.random.randn(INP_NODE)
bias = np.random.randn(100)
res1 = calc_conv1(src, weight, bias, applyActFnc=False)
#res3 = calc_conv3(src, weight, bias, applyActFnc=False)
#for elem in zip(res1, res3):
#    #if (elem[0] > 0.0):
#        print(elem)
```

### 結果

- calc_conv1
    - 84.5 µs ± 120 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
- calc_conv3
    - 24.1 µs ± 502 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

速くなった。

答えは一応同じはず。
Qiitaにアップする画面動画をgifアニメで簡単に作ろう

簡単２ステップ

## QuickTime Player

画面の動画を撮影します。

<img width="397" alt="quicktime.png" src="https://qiita-image-store.s3.amazonaws.com/0/32215/485002e6-546a-78f6-5ce5-72bd79db613f.png">


## Video to GIF converter

使える。便利。

[Video to animated GIF converter](https://ezgif.com/video-to-gif)

撮影した動画をアップして、コンバートするパラメータを設定して、コンバート！

<img width="600" alt="Video to animated GIF converter.png" src="https://qiita-image-store.s3.amazonaws.com/0/32215/35ec45c8-9ada-f1e3-6a6d-e798bcbfc628.png">

ダウンロード

<img width="600" alt="Video to animated GIF converter-1.png" src="https://qiita-image-store.s3.amazonaws.com/0/32215/31de6afb-73fe-c0c0-af3a-cfdfdfe75c19.png">

ダウンロードしたgifを、Qiitaにドラッグ＆ドロップで終了。
インストルメンテーションテストアプリにMultidexを適用する

Multidex 1.0.2でインストルメンテーションテストアプリに対するmultidexingがサポートされました。
https://developer.android.com/topic/libraries/support-library/revisions.html#25-4-0

例えば以下のライブラリを併用すると、64K制限にひっかかります。

```groovy:app/build.gradle
androidTestCompile 'org.mockito:mockito-android:2.8.47'
androidTestCompile 'com.squareup.assertj:assertj-android-appcompat-v7:1.1.1', {
    exclude group: 'com.android.support'
}
androidTestCompile 'com.squareup.okhttp3:mockwebserver:3.8.1'
androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.2.2', {
    exclude group: 'com.android.support'
}
```

Multidexはこのような場合に有効な手段なのですが、残念なことに現在ドキュメントがないようですので、以下に導入方法を示します。

> 2017/07/29追記
> ドキュメントの不備について指摘したところ、[gradleプラグイン側の対応が未完了](https://issuetracker.google.com/issues/63945424#comment2)との回答を頂いたので、以下の内容を試す場合は自己責任でお願いします。

まず、build.gradleの`repositories`に`maven { url 'https://maven.google.com' }`を追加します。

```groovy:build.gradle
allprojects {
    repositories {
        // Gradle 4.0以上を使用している場合は、`google()`でも可
        maven { url 'https://maven.google.com' }
    }
}
```

次に、app/build.gradleにて、Multidexを有効にします。

```groovy:app/build.gradle
android {
    defaultConfig {
        multiDexEnabled true
    }
}

configurations {
    all {
        // 強制的に1.0.2を適用します
        resolutionStrategy.force 'com.android.support:multidex:1.0.2'
    }
}

dependencies {
    compile 'com.android.support:multidex:1.0.2'
}
```

AndroidJUnitRunnerを継承したJUnitRunnerを用意し、以下のように`MultiDex#installInstrumentation(Context, Context)`を呼び出します。

```java:app/src/androidTest/java/com/example/myapplication/JUnitRunner.java
// パッケージ名は適宜読みかえて下さい
package com.example.myapplication;

import android.os.Bundle;
import android.support.multidex.MultiDex;
import android.support.test.runner.AndroidJUnitRunner;

public class JUnitRunner extends AndroidJUnitRunner {
    @Override
    public void onCreate(Bundle arguments) {
        MultiDex.installInstrumentation(getContext(), getTargetContext());
        super.onCreate(arguments);
    }
}
```

最後に、app/build.gradleの`testInstrumentationRunner`に、作成したJUnitRunnerを指定します。

```groovy:app/build.gradle
android {
    defaultConfig {
        testInstrumentationRunner 'com.example.myapplication.JUnitRunner'
    }
}
```

以上です。
【Android】adbコマンドによる端末の動画キャプチャとPCへのダウンロード

adbコマンドによるAndroid端末の動画キャプチャの手順

次の手順を順に行う

1.USBケーブルでPCとスマホを接続する

2.動画キャプチャを開始するために、次のコマンドを実行する。

```
adb shell screenrecord --bit-rate 500000 --size 720×1280 /sdcard/cap.mp4
```

3.動画のキャプチャを停止する

```
Ctrl + c
```

4.スマホに保存された動画ファイルをPCにダウンロードするために、次のコマンドを実行する

```
adb pull /sdcard/cap.mp4 ~/Desktop
```
MacbookProでアナログデータを取得する

#アナログデータを取りたい時、どうしますか？
AD変換器？　買うの？　お金ないのに？　それに、適当なデータで構わないのに？

そうだ、あなたの手元には__Mac__があるじゃないですか！
#目的
AD変換器を買わずに電圧で出力されてくるデータを取得する方法として、パソコンについている場合の多いマイク端子からデータを入れ、それを録音する方法があります。

macOSの入った四極フォーンプラグのみを音声入出力に使うパソコンしか持っていない私が、その方法が使えるようにメモして、また使えるようにしておくことがこの記事の目的です。
#環境

* MacbookPro mid2012 (macOS Sierra 10.12.5)
* 3.5mm三極フォーンプラグが出力となっているマイク（以下、マイクプラグ）
* 信号を伝えてくる3.5mm三極フォーンプラグ（かジャック）（以下、信号プラグ）
* 取ってきた情報を聞くための3.5mm三極ヘッドホン（以下、ヘッドホンプラグ）
* 3.5mm端子（マイク端子及びイアホン端子）を3.5mm四極ジャックに変える変換器（以下、変換器）

<details><summary>機器の制約</summary>
MacbookProである必要もmid2012である必要もないと思われます。
また、変換器をいろいろくっつければ3.5mmフォーンプラグである必要もないと思います。
この手法は、音声入出力の端子として、__四極フォーンプラグのみ__を持つパソコンうち、特に__macOS__が入っているものに関して有効な手法と考えられます。Bootcampについては知りません。あくまで、筆者の環境が上記のようになっていますよ、というお話です。</details>
#接続手順
1. 変換器にヘッドホンプラグとマイクプラグを接続
2. 変換器をPCに接続
3. 外部マイク認識後、マイクプラグ排除
4. 信号プラグを変換器に接続

以上です。これだけかと言われればこれだけですけれども、Macは_賢い_ので信号プラグを初めから変換器に繋いで変換器をPCに接続すると、外部マイクを認識せず、意外とハマります。私はハマりました。
上記の接続手順さえ問題なければ、あとは例えば、iSpectrumを起動すると、マイクからの入力をヘッドホンに垂れ流してくれますし、例えばAudacityを起動しておくと送られてきたデータをwavとして記録できます。これで、
デジタルデータ　を　てにいれた。

#解決しそうにない問題点
macOSは四極フォーンプラグから送られてくる操作信号を勝手に受け付けます。特に問題になるのが、音楽の再生停止、Siriの起動です。「ぷつっ」といった信号が入ってくると、もれなく音楽の再生が始まります。そして、この機能を停止させる方法は見つかりませんでした。
よって、取得したいデータの種類によっては、この方法を諦めるのが無難かと思われます。

# 『たった一つじゃない冴えたやり方』
この問題は、初めっからマイク端子のあるパソコンを買っていれば解決します。
ほかには、わざわざパソコンのマイク端子を使って物事を行おうとしない力をもつ。USBかなんかで繋がる機器を買う。それらでもいいんじゃないでしょうか。
Progressive Web Apps: PWA を調べたのでメモ

PWAが何なのか分からなかったのでメモ。


# PWAの特徴

PWAはネイティブアプリのようなUXをウェブで実現する。とは具体的にどういうことか？

https://developers.google.com/web/fundamentals/getting-started/codelabs/your-first-pwapp/?hl=ja

こちらの最初の箇条書にある。
つまり普通のアプリっぽいウェブサイトのこと。なるほどわからん。

厳密な定義ではない？アジャイルみたいな感じ？
まだぼんやりしていて分かりにくいのでチェックリストを見る。


# PWAのチェックリスト

https://developers.google.com/web/progressive-web-apps/checklist

* 基本事項
    * HTTPSを使っている
    * タブレットやモバイルでレスポンシブである
    * 少なくともStart URL（？）はオフラインの間に読み込み（レスポンス200）できる
    * （スマホなどの）ホームに追加するためのメタデータがある
    * 3G回線でも速い
    * クロスブラウザ対応
    * 画面遷移時にネットワークでブロックされているように感じさせない
    * どの画面でもURLがある
* 模範事項
    * インデックスとソーシャル連携
        * コンテンツはGoogleにインデックスされる
        * Schema.org メタデータが適切に設定されている
        * ソーシャル用メタデータが適切に設定されている
        * 必要な場合はCanonical URLが設定されている
        * SPAの場合、フラグメントを使わずにHistory APIを使う
    * UX
        * ページ読み込み時にコンテンツがジャンプしない
        * 「戻る」でスクロールが保持されている
        * タップ時に、スクリーンキーボードによって入力が不明瞭にならない
        * アプリモードでも共有ボタンが利用できる
        * スマホ、タブレット、デスクトップでレスポンシブである
        * アプリインストールバナーを過度にせず、インストールされたら消す
    * パフォーマンス
        * 初回読み込みが3Gでも高速
    * キャッシュ
        * 可能ならキャッシュをまず見るようにする（3Gよりオフラインの方が速いのはおかしい）
        * オフラインになったときに適切に通知する
    * プッシュ通知（模範的なPWAの要件ではない）
        * 通知を使用する状況を詳しく提供する
        * プッシュ通知を有効にするUIを過度にしない
        * 権限要求の表示時に他の全てのコンテンツを暗くする
        * プッシュ通知は、適切な時間、正確、ユーザーに関連性があるものでなければならない
        * 通知の有効または無効にするコントロールを提供する
    * その他の機能
        * [Credential Management API](https://credential-management-sample.appspot.com/) によるシームレスなログイン
        * Payment Request API によるネイティブUI連携


# つまり・・・？

ちょっと見えてきた。巷では「PWA＝プッシュ通知」みたいな記事も見かけるけど、キモはオフライン対応なんじゃないだろうか。「PWA＝オフライン対応」と言ってもいいくらい。
技術的に言うならば、`Service Worker`の`Cache API`だ。古い技術も入れるなら、それに加えて`IndexedDB`。

レスポンシブとかHTTPSとかはWeb開発をしている人なら普段から扱うし、プッシュ通知はサンプルを見ながら書いたらすぐ使えそうだ。

しかしオフライン対応はね…。昔`Application Cache`と`IndexedDB`と`LocalStorage`のオフライン機能で盛り上がって、そのまま誰もちゃんと使えず終わっていったよね。
これはGoogleによるリベンジなのか？

その頃PC版Chromeでデスクトップアプリを登録できるようになってたけども、そのレスポンシブ版と考えていいのかも。


PWAとAMP（Accelerated Mobile Pages）を合わせて、PWAMPと言ったりもするらしい。
http://qiita.com/edwardkenfox/items/4c0b9550ffa48c1f0445
http://qiita.com/radiocat/items/231dad496cd44b61e96d
https://www.suzukikenichi.com/blog/pwamp-is-combination-of-pwa-and-amp/
なんでセットで考えるのか分からないけど。マーケティング用語な雰囲気がある。事例紹介記事と技術記事の乖離がひどい。

https://www.suzukikenichi.com/blog/from-amp-to-pwa-progressive-web-amps/
この事例とか。
見てみると、確かにAMPの表示のときにWorkerが動いて、キャッシュを取得している。
ただ、そのキャッシュファイルが共通JavaScriptやCSSのファイルだけなんだけど…。これでPWAの事例って言っちゃうのか。

もっとさ、Google MapでAjaxがすごい！ってなった時のように、関連レシピの情報や画像まで先にDLして本当にオフラインアプリの速度みたいで凄い！っていうようなサンプルは無いのだろうか。
まずGoogleがGmailとかでやるべきだよねえ…。
Python > 実装の変更による処理時間の比較 > forと内包表記 > 57us to 77us

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.1.0
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
```

[TensorFlow / ADDA > reproduce_170429.py > v0.1 > 学習したネットワークをもとに、入力データを与えてpredictionに相当するものを出力](http://qiita.com/7of9/items/f267e59790526e49a7fd)
で実装したcalc_conv()が遅い。

TensorFlowで学習した結果の図示だけですでに20分は経過している。

処理を少しいじってみる。

参考: [Jupyter Notebook > %timeit range(100) > 処理時間の計測 > %%timeit > 複数文の処理時間の計測](http://qiita.com/7of9/items/72df5443bde6bd3c4b0f)


### 比較内容

- forでまわす処理 (calc_conv1)
- 内包表記に変えた処理 (calc_conv2)

### code

```py:profile_calc_conv_170722.ipynb%%timeit

import numpy as np
import math
import sys


def calc_conv1(src, weight, bias, applyActFnc):
    wgt = weight.shape
#   print wgt # debug
    #conv = list(range(bias.size))
    conv = [0.0] * bias.size

    # weight
    for idx1 in range(wgt[0]):
        for idx2 in range(wgt[1]):
            conv[idx2] = conv[idx2] + src[idx1] * weight[idx1, idx2]
    # bias
    for idx2 in range(wgt[1]):
        conv[idx2] = conv[idx2] + bias[idx2]
    # activation function
    if applyActFnc:
        for idx2 in range(wgt[1]):
            conv[idx2] = calc_sigmoid(conv[idx2])
    return conv  # return list


def calc_conv2(src, weight, bias, applyActFnc):
    wgt = weight.shape
#   print wgt # debug
    #conv = list(range(bias.size))
    conv = [0.0] * bias.size

    # weight
    for idx1 in range(wgt[0]):
        conv = [conv[idx2] + src[idx1] * weight[idx1, idx2] for idx2 in range(wgt[1])]
        
    # bias
    for idx2 in range(wgt[1]):
        conv[idx2] = conv[idx2] + bias[idx2]
    # activation function
    if applyActFnc:
        for idx2 in range(wgt[1]):
            conv[idx2] = calc_sigmoid(conv[idx2])
    return conv  # return list


INP_NODE = 100
weight = np.random.randn(INP_NODE,1)
src = np.random.randn(INP_NODE)
bias = np.random.randn(100)
#res1 = calc_conv1(src, weight, bias, applyActFnc=False)
res2 = calc_conv2(src, weight, bias, applyActFnc=False)
#for elem in zip(res1, res2):
#    print(elem)
```

### 結果

- forでまわす処理 (calc_conv1)
    - 57.4 µs ± 625 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
- 内包表記に変えた処理 (calc_conv2)
    - 77.8 µs ± 929 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

内包表記の方が遅くなった。
Java SE8 Silverに合格しました

Java SE8 Silverに合格しましたので、これまでの勉強方法を記しておこうと思います。今後試験を受けようと思っている人の参考になれば幸いです。

**試験結果**
正答率：92%

# 受験前のJavaの理解度
* 新人(2017/07/22現在)なので実務経験はほぼ無し
* Javaは大学の講義で勉強し、一通りの知識はある
* jspとServletを使って簡単なWebページを作ることが出来る

# 使用したテキスト
定番の問題集である[黒本](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5-Java-Silver-%E5%95%8F%E9%A1%8C%E9%9B%86-1Z0-808/dp/4844339931)を購入して使いました。これ一冊のみです。1章から9章まで単元ごとに例題が用意されており、10章と11章に模擬試験が載っています。
もう一つの問題集である[白本](https://www.amazon.co.jp/%E3%82%AA%E3%83%A9%E3%82%AF%E3%83%AB%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E6%95%99%E7%A7%91%E6%9B%B8-Java%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E-Silver-SE-%E3%82%B9%E3%83%94%E3%83%BC%E3%83%89%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E5%95%8F%E9%A1%8C%E9%9B%86/dp/4798142743/ref=pd_lpo_sbs_14_img_2?_encoding=UTF8&psc=1&refRID=WZ81PWY6YWTR9Y6RGM1C)やテキストと問題集が一緒になった[紫本](https://www.amazon.co.jp/%E3%82%AA%E3%83%A9%E3%82%AF%E3%83%AB%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E6%95%99%E7%A7%91%E6%9B%B8-Java%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E-Silver-SE-8/dp/4798142735/ref=pd_bxgy_14_img_2?_encoding=UTF8&psc=1&refRID=HVJAJET0SX9RF0173R9B)は購入しませんでした。
ある程度を知識を持っていて、ソースコードを読めるのであれば紫本は必要ないと感じました。

# 勉強方法
家で勉強していました。乗り物酔いがひどいので通勤中には勉強しませんでしたし、そもそも問題集が重くて持ち歩きたくありませんでした。
平日は仕事があるので多くの時間が取れませんでしたが、休日に一気に勉強しています。

### 例題(1週目)
ひとまず問題を解いて、分からなかったところや答えがそれになる理由が分からなかったところにチェックを付け、弱点を把握。チェックが付いた問題については解説を参考にし、自分なりに別の用紙にまとめて**アウトプット**していました。解説を読むだけでなく、自分の言葉で書くことによってより理解を深めました。

### 模擬試験(1回目)
10章が55%、11章が67%という悲惨な結果。まだまだ理解度が足りていないと知らされました。例題と同様にチェック付けた問題は自分なりの言葉でまとめて理解を深めます。

### 模擬試験(2回目)
10章が88%、11章が92%に上がり、自身が付き始めました。2回目でも間違えた問題は徹底的に分析し、自分の言葉でまとめました。

# 実際の試験
上記の通り勉強して、いよいよ試験当日。勉強の甲斐があったのか意外とサクサク進めることが出来ました。回答時間は150分もあるのですが、90分ほど経過したところで回答・見直しが終わり、試験を終了して退室しました。

# 受験しての感想
eclipseという便利なIDEが自動でエラーを直してくれることもあり、それに頼っていた身としてはJava本来の性質を知るいい機会になりました。SE8からはラムダ式やLocalDateやlocalTimeなどのAPIも出題範囲となっていますが、問題数は1問しかありませんでした...ｱﾝﾅﾆﾍﾞﾝｷｮｳｼﾀﾉﾆ

# 今後の目標
Silverと取ったので、次はGold目指したいと思います。ただ焦らずにもう少し実務経験や知識を積んでから挑もうと思っています。
Goldの前に何か他の資格試験も受けるかもしれません。
HerokuからgolangでBigQueryにつなぐ方法

結構ハマって調べたので、まとめました。2017-07-22 時点の情報です。
作業しながら見つけたので、少し間違っている可能性はあります。

# 対象読者

* BigQueryを用意したがAPIとして呼びたい
* Go(golang)を使いたい
* Herokuなど、Webアプリケーションから動かしたい

# 手順

ざっと以下の手順。

1. GCP上でサービスアカウントを登録
2. Herokuで環境変数の設定
3. Goから呼べるようにする

※Herokuの使い方やBigQueryの作成、細かい用語の説明などは別の方のドキュメントを参考にしてください。

## GCP上でサービスアカウントの登録

### 対象のプロジェクトでGCPの「IAMと管理」を開く

![1.png](https://qiita-image-store.s3.amazonaws.com/0/29764/69a11fa1-b39d-b304-72a0-7cda92737dfd.png)

### サービスアカウントを追加
役割は以下。役割を間違えると、`403 Access Denied`となります。 

* BigQuery データ閲覧者
* BigQuery ユーザー

![2.png](https://qiita-image-store.s3.amazonaws.com/0/29764/54592524-4733-a225-8728-adcbd2537cb8.png)

### Json形式で鍵をダウンロード

手順に従えばダウンロードは問題なくできます。

## Herokuで環境変数の設定をする

Herokuの以下画面で環境変数を設定する。
KEYを「GOOGLE_APPLICATION_CREDENTIALS」、VALUEを上記ダウンロードしたJSONファイルをコピー&ペースト

![3.png](https://qiita-image-store.s3.amazonaws.com/0/29764/c5d55ff8-3166-ce2c-d7f4-61e7d9067f92.png)

※コマンドから設定も可能です。

### Goから呼べるようにする
サンプルコードは以下です。一応ローカル（1.8.1）では動きました。
実際にはAPIとしてHerokuにデプロイしているので、このコードをデプロイしたわけではありません。

*注意*
プロジェクトIDも環境変数に入れいています。ローカル環境では以下のようにして設定しました。

```bash
# xxxにはプロジェクトIDとダウンロードしたjsonファイルです。
export PROJECT_ID=xxxxx
export GOOGLE_APPLICATION_CREDENTIALS="$(cat xxxxxx.json)"
```

goのソースコードは以下です。[gist](https://gist.github.com/pyohei/114b5ea93ec429b1684ce0277a3de7e7)にも似たのは置いています。

```go
package main

import (
	"cloud.google.com/go/bigquery"
	"fmt"
	"golang.org/x/net/context"
	"golang.org/x/oauth2/google"
	bq "google.golang.org/api/bigquery/v2"
	"google.golang.org/api/iterator"
	"google.golang.org/api/option"
	"os"
)

func main() {
	json := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS")
	ctx := context.Background()
        // project ID も環境変数に入れています。
	projectID := os.Getenv("PROJECT_ID")
	jwtConfig, err := google.JWTConfigFromJSON([]byte(json), bq.BigqueryScope)
	if err != nil {
		fmt.Printf("Json load error: %v\n", err)
	}
	ts := jwtConfig.TokenSource(ctx)
	client, err := bigquery.NewClient(ctx, projectID, option.WithTokenSource(ts))
	if err != nil {
		fmt.Printf("Client create error: %v\n", err)
	}

　　　　　　　　　　　　　　　　// SQL
	bqSql := " select * from [zip.zip] order by zip limit 10"
	fmt.Println(bqSql)

	q := client.Query(bqSql)
	it, err := q.Read(ctx)
	if err != nil {
		fmt.Printf("Error2: %v\n", err)
	}
	for {
		var values []bigquery.Value
		err := it.Next(&values)
		if err == iterator.Done {
			break
		}
		if err != nil {
			fmt.Printf("Error3: %v\n", err)
		}
		fmt.Printf(values[0].(string))
		fmt.Printf(values[1].(string))
	}
}
```

# 関連リンク

* [Google Vision APIをHerokuで使う](http://qiita.com/hasokon/items/f6ed020ef91276e3e34a)
* [package bigquery](https://godoc.org/google.golang.org/api/bigquery/v2)
* [GolangでBigQueryにデータを追加する](http://christina04.hatenablog.com/entry/2017/06/22/010755)
* [pyohei/accessBigquery.go](https://gist.github.com/pyohei/114b5ea93ec429b1684ce0277a3de7e7)
Echo Showの表示を試してみる

Echo Showの登場により、今まではシンプルなカードしか表示できなかったのが、より多くの情報を表示できるようになったので、調べてみた。

[Display Interface Reference](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/display-interface-reference)

<font color="red">元のドキュメントが色々typoが多くて間違えがあるかもしれないので注意</font>

Showではテンプレートと呼ばれる特定のレイアウトを利用して情報を表示します。
実際にディスプレイ用に情報を返すSkillを作成したので、そちらをセットアップすれば実際に確認することが出来ます。
https://github.com/sparkgene/echo-show-display-test

## テンプレートの種類

- BodyTemplate1
- BodyTemplate2
- BodyTemplate3
- BodyTemplate6
- ListTemplate1
- ListTemplate2

### BodyTemplate1

<img width="807" alt="スクリーンショット 2017-08-12 15.17.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/36184/4c4f3ff5-c1a7-11d6-bc5f-cd633f10107c.png">


主な機能

- 背景画像
- タイトル
- primary テキスト
- secondary テキスト
- tertiary テキスト
- スクロール可能

### BodyTemplate2

<img width="804" alt="スクリーンショット 2017-08-12 16.45.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/36184/5c817532-88f4-1215-9afa-1cc4bd7388fc.png">

主な機能

- 背景画像
- タイトル
- 画像が右側に表示できる
- primary テキスト
- secondary テキスト
- tertiary テキスト
- ヒントの表示

### BodyTemplate3

<img width="804" alt="スクリーンショット 2017-08-12 13.57.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/36184/fe8d46c6-4f69-16c1-652b-f262428969bc.png">

主な機能

- 背景画像
- タイトル
- 画像が左側に表示できる
- primary テキスト
- secondary テキスト
- tertiary テキスト
- スクロール可能
- ヒントの表示

### BodyTemplate6

<img width="809" alt="スクリーンショット 2017-08-12 17.00.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/36184/3f2e6de1-f6b9-e1b1-81cb-d2be44d856c1.png">

主な機能

- 背景画像
- 画面全体にテキストが表示される
- primary テキスト
- secondary テキスト
- tertiary テキスト

### ListTemplate1

<img width="810" alt="スクリーンショット 2017-08-12 17.30.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/36184/0212ba17-096f-e79f-5df6-25ecd842e8dd.png">

主な機能

- 背景画像
- リスト表示（縦）
- サムネイルの表示
- primary テキスト
- secondary テキスト
- tertiary テキスト
- スクロール可能（音声で操作可能）
- はみ出る文字は切られる

### ListTemplate2

<img width="809" alt="スクリーンショット 2017-08-12 17.31.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/36184/14613482-de9e-0b27-03b2-3dc2889706e3.png">


主な機能

- 背景画像
- リスト表示（横）
- サムネイルの表示
- primary テキスト
- secondary テキスト
- tertiary テキスト
- スクロール可能（音声で操作可能）
- はみ出る文字は切られる

## ビデオ

[VideoApp Interface Reference](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/videoapp-interface-reference)

Echo Showでは動画の再生もサポートしています。
ただし、動画の再生は実機じゃないとサポートしていないようで、サンプル書いてけど動作確認は出来ていません。
試したらヒントしか表示されない

<img width="809" alt="VideoApp.png" src="https://qiita-image-store.s3.amazonaws.com/0/36184/5eef1548-83d2-ebea-f6bc-c99e4ca2d5bd.png">

## まとめ

今までのカードと比べるとかなりリッチになりましたね。
音声だけでは足りない場合は、Showのように大きなディスプレイを持つデバイスがあると便利そうですね。商品探す時は、実際に複数件出てくるだろうし、一覧形式で見れるのは便利だと思う。

早く日本に来ないかな〜。
Kotlinには三項演算子（条件演算子）がない

# Kotlinと三項演算子（条件演算子）
GoogleがAndroidの開発言語としてKotlinを公式にサポートしたことで、最近何かと話題のKotlinですが、Kotlinには三項演算子がありません。

```kotlin
val max = a > b ? a : b // NG
```

そのかわり、Kotlinでは[ifが式として扱われる](https://kotlinlang.org/docs/reference/control-flow.html#if-expression)ので、以下のように書くことができます。

```kotlin
val max = if (a > b) a else b
```

だけど、Javaには三項演算子があるのに、Kotlinにはないなんて、なんか不便じゃないですか？ :thinking_face:
なので今回は、三項演算子っぽいものを無理矢理作ってみたいと思います :muscle:

# 三項演算子を定義する
Kotlinには`?`や`:`という演算子はないので、[Operator overloading](https://kotlinlang.org/docs/reference/operator-overloading.html)は使えません。

しかし、`infix`を使うと、独自の演算子（のように見えるもの）が定義できます。
https://kotlinlang.org/docs/reference/functions.html#infix-notation

今回は、以下のようにクラスとinfix関数を定義します。

```kotlin
data class TernaryOperation<out T>(val condition: Boolean, val value: T)

infix fun <T> Boolean.`?`(other: T) = TernaryOperation<T>(this, other)
infix fun <T> TernaryOperation<T>.`：`(other: T) = if (this.condition) this.value else other
```

`?`や`:`は関数名として使えないため、バッククォートで囲っています。
ただ、`` `?` ``は使えても、`` `:` ``はなぜか使えなかったので、`` `：` ``（全角）にしました。
また、KotlinでもJavaと同様に、関数名に日本語を使うことができますが、`？`や`：`は使えません。

上記で定義した関数を使うときはこんな感じです。

```kotlin
val max = (a > b) `?` a `：` b
```

なんかそれっぽい感じになりました :sweat_smile:

# Javaの三項演算子との違い
## 演算子の優先度
Kotlinのinfix関数は、比較演算子よりも優先度が高いです。
https://kotlinlang.org/docs/reference/grammar.html#precedence

一方で、Javaの三項演算子は、比較演算子よりも優先度が低いです。
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

そのため、今回作った三項演算子もどきで比較演算子などを使う場合は、条件式をカッコでくくる必要があります。

```java:Java
int max = a > b ? a : b; // OK
```

```kotlin:Kotlin
val max = a > b `?` a `：` b // NG

val max = (a > b) `?` a `：` b // OK
val max = (a > b) `?` a + 3 `：` b - 5 // OK
```

## 式の評価
saka1029さんのコメントで気が付きました。ありがとうございます :bow:

今回作った三項演算子もどきは、値を渡しているため、条件の真偽にかかわらず両方の値が評価されてしまいます。

```java:Java
int value = array.length > 0 ? array[0] : -1; // OK
```

```kotlin:Kotlin
val value = array.isNotEmpty() `?` array[0] `：` -1 // arrayが空のときArrayIndexOutOfBoundsException
```

これを回避するとなると、`T`型ではなく`() -> T`型にしないといけないですが、もはやif式との違いがなくなってしまいますね :sweat_smile:

```kotlin
data class TernaryOperation<out T>(val condition: Boolean, val value: () -> T)

infix fun <T> Boolean.`?`(other: () -> T) = TernaryOperation<T>(this, other)
infix fun <T> TernaryOperation<T>.`：`(other: () -> T) = if (this.condition) this.value() else other()

val value = array.isNotEmpty() `?` { array[0] } `：` { -1 } // OK
```

# エルビス演算子を使うパターン
以下のようなinfix関数を定義します。

```kotlin
infix fun <T> Boolean.then(other: T) = if (this) other else null
```

エルビス演算子を使うと、以下のように三項演算子っぽく書けます。

```kotlin
val max = (a > b) then a ?: b
```

ただし、`true`の時の値に`null`を使うと、（当然ですが）常に`false`の時の値になってしまいます :cry:

```kotlin
val body = response.isError() then null ?: response.body // always response.body
```

また、先ほどと同じように、優先度の問題と、式の評価の問題があります。

# まとめ
ネタで作ってみましたが、やっぱり不便ですね :sweat:
自分はPythonもよく使うので、Kotlinの三項演算子の書き方はまだ慣れないです :sob:

何か感想や意見がありましたらコメントお願いします :bow:
numpy > 線形代数の数値演算ライブラリの表示 > np.__config__.show()

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.1.0
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
```

@ 科学技術計算のためのPython入門: 開発基礎、必須ライブラリ、高速化 by 中久喜 健司さん

numpyの線形代数の環境の表示の仕方。

```py
python
>>> import numpy as np;np.__config__.show()
openblas_lapack_info:
    define_macros = [('HAVE_CBLAS', None)]
    language = c
    library_dirs = ['/usr/local/lib']
    libraries = ['openblas', 'openblas']
lapack_mkl_info:
  NOT AVAILABLE
openblas_info:
    define_macros = [('HAVE_CBLAS', None)]
    language = c
    library_dirs = ['/usr/local/lib']
    libraries = ['openblas', 'openblas']
blas_opt_info:
    define_macros = [('HAVE_CBLAS', None)]
    language = c
    library_dirs = ['/usr/local/lib']
    libraries = ['openblas', 'openblas']
lapack_opt_info:
    define_macros = [('HAVE_CBLAS', None)]
    language = c
    library_dirs = ['/usr/local/lib']
    libraries = ['openblas', 'openblas']
blis_info:
  NOT AVAILABLE
blas_mkl_info:
  NOT AVAILABLE
```

IntelMKL入っていない。
Debian 9.0 (stretch) で AMD Radeon HD 6450 を使う

[玄人志向 RH6450-LE1GB](http://www.kuroutoshikou.com/product/graphics_bord/amd/rh6450-le1gb/) ([AMD Radeon HD 6450](http://www.amd.com/en-us/products/graphics/desktop/6000/6450) 搭載) を積んだマシンに [Debian 9.0 (stretch)](https://www.debian.org/releases/stretch/) を入れたんだが解像度が 1280x1024 までしか上がらない。せっかくディスプレイは 1920x1080 なのに。

「[VirtualBoxに入れたLinuxの解像度をワイドに変更](http://qiita.com/ll_kuma_ll/items/ab9907d1dcab6bdd6aad)」を参考にこんなんやってみたけどエラーが出て解像度が変わらない。

```shell-session
$ xrandr
xrandr: Failed to get size of gamma for output default
Screen 0: minimum 640 x 400, current 1280 x 1024, maximum 1280 x 1024
default connected primary 1280x1024+0+0 0mm x 0mm
   1280x1024      0.00*
   1152x864       0.00
   1024x768       0.00
   800x600        0.00
   640x480        0.00
   720x400        0.00
$ cvt 1920 1080
# 1920x1080 59.96 Hz (CVT 2.07M9) hsync: 67.16 kHz; pclk: 173.00 MHz
Modeline "1920x1080_60.00"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync
$ xrandr --newmode "1920x1080_60.00"  173.00  1920 2048 2248 2576  10880 1083 1088 1120 -hsync +vsync
xrandr: Failed to get size of gamma for output default
$ 
```

よく見たら起動画面にこんなエラーが出ていた。

```
[   13.151113] [drm:radeon_pci_probe [radeon]] *ERROR* radeon kernel modesetting for R600 or later requires firmware-amd-graphics.
```

`/etc/apt/sources.list` に `non-free` を追加してこれで解決。

```shell-session
# apt update
# apt install firmware-amd-graphics
# systemctl reboot
```

リブート後は無事に解像度を自動認識して 1920x1080 になってくれた。

参考: [AtiHowTo - Debian Wiki](https://wiki.debian.org/AtiHowTo)
DBからlimitで件数を絞ったデータをkaminariでページネーションする

## TL;DR

`limit` で絞ったデータを `kaminari` で取り扱う場合は
一旦、Arrayに置き換えてから `Kaminari.paginate_array` を使って表現する


## 問題点と回避策

### 問題点

`kaminari` は Modelで検索したデータに
`.page` や `.per` してあげるだけで
簡単にページネーションできるgemですが
`ActiveModel` の `limit` は無視されてしまいます。[^1]

例えば『直近で更新したユーザ100人のデータを1ページ5件ずつに表示させたい』
といったようなデータを抜き出すときに

```rb:直感的に書いた場合のコード
list_data = User.order(updated_at: :desc).limit(100).page(1).per(5)
```

と書けばできそうな雰囲気がありますが `.limit(100)` の内容は無視されてしまうので
Userのデータが１００件以上あれば２０ページ目以降(100 ÷ 5 = 20)も取れてしまう

```rb:コード
list_data = User.order(updated_at: :desc).limit(100).page(25).per(5)         
```
```mysql:実際に走るクエリ
SELECT  `users`.* FROM `users` ORDER BY `users`.`updated_at` DESC LIMIT 5 OFFSET 120
#　kaminari側でlimitを設定しているので .limit(100) は無視される
```

### 回避策

ページネーションするときにDBの検索がかかるため
先にデータの抽出が終わった状態のものに
ページネーション処理を行えば別の処理として扱えます。

なので、一旦Arrayにしてから
そのArrayオブジェクトに対してページネーション処理をすれば
求めていた結果を得ることができます。

先程の例に対して適応すると以下のようになります。

```rb:arrayに置き換え後、Kaminari.paginate_arrayでページネーション
user_result = User.order(updated_at: :desc).limit(100)
user_array = user_result.each_with_object [] do |user, result|
  result << user
end

list_data = Kaminari.paginate_array(user_array).page(1).per(5)
```

ただし、これは部分的に抽出してくれるkaminariの利点を削っているので
大量のデータを絞り込んで使う場合はいらぬ負荷をかけてしまう懸念があるので
ご注意ください。

## 参考ページ
* [kaminariを使って配列に対してのページャーを作成する \- Qiita](http://qiita.com/Konboi@github/items/ef62a511ea35270b71be)
* [bootstrapでKaminariを使ってpaginateする \- Qiita](http://qiita.com/miyakou1982/items/bec13691cb6533329394)

[^1]: Githubにある、[kaminariのReadme](https://github.com/kaminari/kaminari#the-per-scope)に『Keep in mind that per internally utilizes `limit` and so it will override any limit that was set previously. 』 とある
AndroidでViewを「くり抜く」方法

AndroidのAPIlevel1から提供されている[canvas](https://developer.android.com/reference/android/graphics/Canvas.html)を使う事によって、様々なViewの形を実現することができます。
一般的な使い方は、円や長方形などのViewの生成や、Bitmapの切り取りなどではないでしょうか？
そこで今回はViewを**くり抜く**方法について紹介したいと思います。

# まずはViewを描画する方法

```java
public class CanvasView extends View {

    private Paint paint = new Paint();

    public CanvasView(Context context) {
        super(context);
    }

    public CanvasView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public CanvasView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(getRootView().getWidth() / 2, getRootView().getHeight() / 2, 50, paint);
    }
}

```

<img src="https://qiita-image-store.s3.amazonaws.com/0/93589/c3248cf5-88ce-43d9-60c4-31bea0f850f6.png" width="300">

## Viewをくり抜く方法

```java
public class CanvasView extends View {

    private Paint backgroundPaint = new Paint();
    private Paint paint = new Paint();

    public CanvasView(Context context) {
        super(context);
    }

    public CanvasView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public CanvasView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        setLayerType(View.LAYER_TYPE_HARDWARE, null);

        //全体を描画する
        backgroundPaint.setColor(ContextCompat.getColor(getContext(), android.R.color.background_dark));
        canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), backgroundPaint);

        //全体の背景から円をくり抜く
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, 250, paint);
    }
}
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/93589/22ccfaf5-f2a9-5cc5-fc10-5444a0a20281.png" width="300">

## 最後に
こちらで紹介した方法を使ってライブラリを作成しました。いいねと思った方はぜひスターをつけていただけるとうれしいです。

https://github.com/TakuSemba/Spotlight


![customTarget.gif](https://qiita-image-store.s3.amazonaws.com/0/93589/612958c0-a946-f25f-c3fc-641dc13cf697.gif)
【メモ】Xcode9ビルドでCarthage経由で導入したライブラリに関してswift version errorが発生

##はじめに
xcode9でビルドを行おうとしたところ、carthageで導入しているライブラリに関して以下のエラーがでました。

```
Module compiled with Swift 3.0.1 cannot be imported in Swift 3.2
```

解消までに少々ハマったので、備忘録がてら原因と解決方法を記載いたします。

##検証環境
以下の環境を使用しています。

* macOS Sierra Version 10.12.5
* Xcode Version 9.0.0 β3
* Xcode Version 8.3.2 （異なるversionのxcodeを入れています）
* iPhone7 iOS11.0.0 β3

##原因
carthageでライブラリを導入する際に使用する以下のコマンドでxcode buildが内部的に行われますが、ここで使用されているXcodeがXcode8.3.2であることが原因でした。

```
carthage update --platform iOS
```

##解決方法
以下の手順で解決しました。

1. Xcode build で使用しているXcodeのpath確認
    *  `xcode-select -p`
    *  出力例 `/Applications/Xcode.app/Contents/Developer`  
                     
2. 使用するXcodeのパス変更
    * `sudo xcode-select -s /Applications/Xcode-beta.app/Contents/Developer`
    * root権限が必要とされるので、sudoで実行しています。
3. 再度、Xcode build で使用しているXcodeのpath確認
    * xcode-select -pで指定したものに変わっていればOK
    * `/Applications/Xcode-beta.app/Contents/Developer`
4. ライブラリ再ビルド前の準備
    * projectのderived dataを削除
    * 削除したderived dataをゴミ箱から削除
5. carthageでライブラリをビルド
    * `carthage update --platform iOS --no-use-binaries`
6. projectのビルドを実施

上記手順で、carthageでライブラリをビルドする際のxcodeとしてXcode-betaが使用されますので、Xcode9で対象プロジェクトのビルドができるようになります。
※ Xcode-betaとしているところはご自身で使用されているXcodeの名前と合わせてください。
備忘録_homebrewもろもろ


##パッケージのインストール先

homebrewのパッケージは/usr/local/Cellar/にインストールされる。
インストール時にbinにリンクされる。

- /usr/local/Cellar　コマンド実体
- /usr/local/bin　　　コマンドのエイリアス

##brewの基本的な使い方

###インストール / アンインストール

```
// インストール
$ brew install <パッケージ名>
// アンインストール
$ brew uninstall <パッケージ名>
```

###アップデート / アップグレード

```
// アップデート
$ brew update
// アップグレード
$ brew upgrade
```

`brew update`はbrew自体も最新にアップデートし、フォーミュラ(パッケージ)も最新にする
`brew upgrade`はフォーミュラ(パッケージ)のみ最新にする※特定のフォーミュラを指定してupgradeも可能

###リスト

```
// リスト表示
$ brew list
```

`brew list`はインストール済みのフォーミュラを一覧表示する

###ドクター

```
// インストールの問題を確認
$ brew doctor
```

###clean up

```
// clean up
$ brew cleanup
```

`brew cleanup`を実施するろインストールしたすべて、もしくは特定のformulaeの古いバージョンをcellarから削除する

##brew tapに関して

`brew tap`とは公式以外のリポジトリをフォーミュラとしてHomebrewに追加することができる。

```
// インストール
$ brew tap <user/repo>
// アンインストール
$ brew untap <user/repo>
```

##brew-cask

バイナリ形式で配布されているMacアプリケーションをインストールするための拡張

```
// パッケージを検索
$ brew cask search google

// パッケージの情報表示
$ brew cask info google-chrome

// インストール
$  brew cask install google-chrome

// アンインストール
$ brew cask uninstall google-chrome

// インストール済みのものを表示
$ brew cask list

// 不要なダウンロード済みファイルを削除
$ brew cask cleanup

```

※`brew update`でbrew-caskはアプデされるけど、アプリケーションまでは監視しないので下記のコマンドでアプデする

```
//アップデート
$ brew cask install --force $(brew cask list)
```
「モグラたたき開発を卒業しよう　対策編」に大幅に書き加えました。

[「モグラたたき開発を卒業しよう　対策編」](http://qiita.com/nonbiri15/items/015494c7c624748a5974)に大幅に書き加えました。

テスト不十分な状況での実機動作は機器を破壊することなど、
ハードウェアが関係している状況でのことを追加しました。

この記事が、不幸な状況からの脱出に役に立ちますように。
sqlite3のexample

ちょっとsqlite3をWindowsAPIアプリで使ってみる場合の自分用覚書です。

###**オープン**
```
// sqlite3* db;
bool dbopen(char* filename)
{
  int ret;

  ret=sqlite3_open_v2(filename, &db, SQLITE_OPEN_READWRITE| SQLITE_OPEN_CREATE| SQLITE_OPEN_FULLMUTEX, NULL);
  if(ret!=SQLITE_OK){
    dbclose();
    return false;
  }

  ret=sqlite3_exec(db,
                   "CREATE TABLE IF NOT EXISTS datatable("
                   "id INTEGER primary key,"
                   "updatetime INTEGER,"
                   "name TEXT(64),"
                   "value1 REAL,"
                   "value2 INTEGER);",
                   NULL, NULL, NULL); // callback_function, callback_argument, err_message
  if(ret!=SQLITE_OK){
    dbclose();
    return false;
  }
  return true;
}
```

###**クローズ**
```
// sqlite3* db;
void dbclose()
{
  if(db!=NULL){
    sqlite3_close(db);
    db=NULL;
  }
}
```

###**アップサート**
```
// sqlite3* db;
bool dbupsert(DATASTRUCT* ci)
{
  if(db==NULL) return false;
  if(ci->id==0) return false;
  
  int ret;
  sqlite3_stmt *stmt=NULL;
  bool store_data=false;
      
  ret=sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL);
  {
    ret=sqlite3_prepare_v2(db,
                           "REPLACE INTO datatable("
                           "id, updatetime, name, value1, value2) "
                           "VALUES("
                           "?, ?, ?, ?, ?");",
                           -1, &stmt, NULL);

    if((ret==SQLITE_OK)&&(stmt!=NULL)){
      sqlite3_reset(stmt);

      // bind is 1base
      sqlite3_clear_bindings(stmt);
      sqlite3_bind_int64    (stmt,  1, ci->id); 
      sqlite3_bind_int      (stmt,  2, ci->updatetime);
      sqlite3_bind_text     (stmt,  3, ci->name, (int)strlen(ci->name), SQLITE_TRANSIENT);
      sqlite3_bind_double   (stmt,  4, ci->value1);
      sqlite3_bind_int      (stmt,  5, ci->value2);
      
      int iret=sqlite3_step(stmt);
      if(iret==SQLITE_DONE) store_data=true;

      sqlite3_finalize(stmt);
    }
  }
  sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);

  return store_data;
}
```

###**セレクト**
```
// sqlite3* db;
bool dbselect(DATASTRUCT* ci)
{
  if(db==NULL) return false;
  if(ci->id==0) return false;
  
  int ret;
  sqlite3_stmt *stmt=NULL;
  bool aquire_data=false;

  char sqltxt[256];
  sprintf(sqltxt,
          "SELECT "
          "updatetime,"
          "value2 "
          "FROM datatable "
          "WHERE id=%llu;", ci->id);

  ret=sqlite3_prepare_v2(db, sqltxt, -1, &stmt, NULL);

  if((ret==SQLITE_OK)&&(stmt!=NULL)){
    sqlite3_reset(stmt);

    int iret=sqlite3_step(stmt);
    if(iret==SQLITE_ROW){

    // column is 0base
      ci->updatetime=sqlite3_column_int(stmt, 0);
      ci->value2=sqlite3_column_int(stmt, 1);
      aquire_data=true;
    }

    sqlite3_finalize(stmt);
  }

  return aquire_data;
}
```
[Salesforce DX]Salesforce CLIを使ってJWTべアラートークンフローを試してみる

Salesforce DXでは開発の際に継続的統合および継続的デリバリー(CI/CD)を
行いやすくすることを目的の一つとして開発されています。
CI/CDを行うためにはSalesforce環境にブラウザを介さずに自動でログインする必要があります。
今回、Salesforce CLIでサポートされている「JWT べアラートークンフロー」を
利用してログインしてみようと思います。
これは開発におけるCI/CD以外にもスクリプトを使って
Salesforce環境から情報を抽出する際や、
逆にSalesforceに情報を挿入・更新する際にも役立つと思います。

詳細は下記にまとめております。
http://dev.classmethod.jp/cloud/salesforce-cli-jwt-token/
kotlinのreified関数はjavaからは呼べない。

# Reified type parameters
kotlinには`reified`という修飾詞があります。公式ページは[こちら](https://kotlinlang.org/docs/reference/inline-functions.html#reified-type-parameters)

reifiedはgenerics`T`に対して付与することができ、実際の型クラスとして扱得るようになるため、`T`でcastしたり、if文で`T`のインスタンスチェックなどをすることができます。

例えば以下のように定義することができます。

```kotlin
// ListExt.kt

inline fun <reified T> List<T>.filterInstance(): List<T> {
    val destination = mutableListOf<T>()
    this.forEach {
        if (it is T) destination.add(it)
    }
    return destination
}

```

これをkotlinから呼ぶと

```kotlin

val nums = listOf(1, 2f, 3, 4f)
val ints = nums.filterIsInstance<Int>() // [1, 3]

```

しかし、これをjavaから呼ぼうとすると、

```java

List nums = Arrays.asList(1, 2f, 3, 4f);
List ints = ListExtKt.filterIsInstance(nums); // error: filterIsInstance has private access in ListExtKt

```

kotlinにおける`reified`はinline関数に対してのみ付与することができ、inline展開されることによって実際の型クラスにアクセスできるようになります。
javaからkotlinのinline関数を呼んだ際には、inline関数を直接呼ぶため、inline展開されませません。その為、javaからreifiedのついた関数を呼ぼうとするとエラーになるようです。
virtualmin環境にzf-exをインストールする



##zf-exとは

zend framework1を基盤として用意された、ユーザログイン機能、MVCフォルダ構成、デザインテンプレート（CSS）が用意されたまま、PHPアプリ開発ができるようになっているもの（筆者談）

詳しくは作成者のサイトを参照下さい。
http://php-zfex.jp/

##インストール


環境
centos6.8
PHP 5.3.3
webmin 1.831
virtualmin 5.06

###virtualminで仮想サーバを追加する。

zf-ex.localというドメイン名でサイト作成したのを前提で以降は説明します。
virualminで作成すると、zf-exというユーザ名とディレクトリが用意されます。
ただし、データベース名はハイフンは使われなく、zf_exになります。
![createvirualserver.JPG](https://qiita-image-store.s3.amazonaws.com/0/104563/10ff2fce-2984-b7aa-8880-6f0b72382d60.jpeg)

作成完了すると以下のように表示されます。
![createvirualserverdon.JPG](https://qiita-image-store.s3.amazonaws.com/0/104563/f76f0a2d-c8b1-ba73-9ace-0297443ff543.jpeg)


###

仮想サーバを作成した時に用意されたアカウントでSSH接続する。


homesディレクトリを作業場とするためカレントディレクトリを移動して、zf-exをダウンロードする
```
cd /home/zf-ex/homes/
wget http://www.php-zfex.jp/downloads/zfex_0_3_2
```

ダウンロードしたzipファイルを解凍する
```
unzip zfex_0_3_2
```

動作に必要なディレクトリを/home/zf-ex/に移動させる
```
mv ./application ./library ./sql ./tests ./tmp /home/zf-ex/
```

publicディレクトリの内容を/home/zf-ex/public_html/に移動させる
shopt -s dotglobのコマンドを行ったあとワイルドカードで移動元を指定すると隠しファイル.htaccessも含まれるようになります。
shopt -u dotglobのコマンドでこれまで通り隠しファイルはワイルドカードを使っても含まれないようになります。
```
shopt -s dotglob
mv /home/zf-ex/homes/public/* /home/zf-ex/public_html/
shopt -u dotglob
```


###ブラウザ画面でインストールする

http://zf-ex.local/install/にアクセスする

特別DNSなど用意してない場合は、サイトを参照するクライアントのhostsに書く必要がある。
windows10であればC:\Windows\System32\drivers\etcに以下の要領で追記する。IPアドレスはサーバのIPにすること
192.168.0.10	zf-ex.local


ウィザードをすすめる。
![zf-exinstall1.JPG](https://qiita-image-store.s3.amazonaws.com/0/104563/7f6aafd4-7445-0b9f-e599-088e9b83e61e.jpeg)

![zf-exinstall2.JPG](https://qiita-image-store.s3.amazonaws.com/0/104563/e2f2f33d-26d6-2179-cd12-8fb3a56dbe80.jpeg)

![zf-exinstall3.JPG](https://qiita-image-store.s3.amazonaws.com/0/104563/d19b1941-d3fc-5db2-db98-badab52a7460.jpeg)

![zf-exinstall4.JPG](https://qiita-image-store.s3.amazonaws.com/0/104563/decb1d04-e3dd-9d0c-180f-cb62bd59fd9f.jpeg)

![zf-exinstall5.JPG](https://qiita-image-store.s3.amazonaws.com/0/104563/5742e4b2-cc45-465c-6601-ed7fb351cd12.jpeg)

![zf-exinstall6.JPG](https://qiita-image-store.s3.amazonaws.com/0/104563/8d78a2c5-3a25-5e7a-ef07-e655ff029580.jpeg)

![zf-exinstall7.JPG](https://qiita-image-store.s3.amazonaws.com/0/104563/d6a8fa2b-bac7-c57f-8e1d-157c0964d9c9.jpeg)


###zf-ex管理画面にログインする。
![zf-exadmin1.JPG](https://qiita-image-store.s3.amazonaws.com/0/104563/b3f10b7f-bf1f-f4ba-c23b-490c2246bdff.jpeg)

![zf-exadmin2.JPG](https://qiita-image-store.s3.amazonaws.com/0/104563/ff886880-30f6-c2f1-2515-191eb9059c62.jpeg)


###subversionに登録する

作成途中


###エクリプスでsubversionで更新できるようにする。

作成途中
doorkeeper gemでCallback URLにワイルドカードを利用できるようにする


RFC 6749で定義されているOAuth 2.0の仕様ではワイルドカードを用いてはいけないことになっている。

> The redirection endpoint URI MUST be an absolute URI as defined by [RFC3986] Section 4.3.  The endpoint URI MAY include an "application/x-www-form-urlencoded" formatted (per Appendix B) query component ([RFC3986] Section 3.4), which MUST be retained when adding additional query parameters.  The endpoint URI MUST NOT include a fragment component.
>https://tools.ietf.org/html/rfc6749#section-3.1.2

導入は自己責任で。

## TL;DR
initializerでdoorkeeper gemにモンキーパッチを当てる。

```ruby:config/initializers/monkey_patches/doorkeeper.rb
module URICheckerExtension
  def matches?(url, client_url)
    return true if wildcard_matches?(url, client_url)
    super
  end

  def wildcard?(url)
    !/^\*\./.match(url.host).nil?
  end

  def wildcard_matches?(url, client_url)
    url = as_uri(url)
    client_url = as_uri(client_url)
    url.query = nil

    return false unless wildcard?(client_url)
    url.host.sub(/^.+?\./, '') == client_url.host.sub(/^\*\./, '') && url.path == client_url.path
  end
end

module Doorkeeper::OAuth::Helpers::URIChecker
  class << self
    prepend URICheckerExtension
  end
end
```

Callback URLに `https://*.example.com` を指定した場合、これにマッチするURLはValidationが通るようになる。

## Motivation
社内PaaSなどでOAuthを利用するアプリケーションがポコポコ立ち上がる環境を想定したとき、一々作成されたURLを認可サーバに登録するのは面倒くさいし生産性が下がる。

アプリケーションごとにある程度のルールを設けつつこれを解消したかったので、Redirect URLにワイルドカードを利用できるようにした。

もちろんセキュリティの問題もあるので、表向きには出さずにQA環境のみ有効にするといったアプローチを取るのが無難。
【Android】adbコマンドによる端末の画面キャプチャと画像リサイズまでの流れ

Android端末の画面の静止画をキャプチャする手順

USBケーブルでPCとスマホ端末をつなぎ、
次のコマンドを順に実行

1．画面をキャプチャ

```
adb shell screencap -p /sdcard/screen.png
```

2.キャプチャ画像を端末からPCにダウンロード

```
adb pull /sdcard/screen.png
```

3.キャプチャ画像をリサイズ（例では高さを375にして横を自動で設定している）

```
sips --resampleHeight 375 screen.png --out screen.png
```
最後に実行したコマンドの引数を呼び出す便利なショートカット

知っている人は知っているんだろうけど、自分はつい最近知ったコマンドラインでのショートカットテクニックを紹介。

※ 検証環境

- MacOS 10.12.6
- Iterm2（Build 3.1.beta.4）
- bash 3.2.57


`Esc + .`を入力することで最後に実行したコマンドの（最後の）引数を呼び出すことができる。
以下のgifは、 `echo` コマンドの引数として入力した `foobarbaz`を次のプロンプトで呼び出している。

![04e8c04402a36f117c25dd443a43beff.gif](https://qiita-image-store.s3.amazonaws.com/0/2813/cea44e6b-d7a8-03f7-923f-2ac8c62d6ec0.gif)

実務なんかでは、例えば「`cp`コマンドの実行で長いパスを入力した後に、コピー先のファイルを開きたい」というようなケースで便利になると思う。

```shell-session
$ cp /tmp/sample.conf /etc/nginx/conf.d/sample.conf

// ここで less に続けて Esc + .
$ less /etc/nginx/conf.d/sample.conf
```
AudioKitを使う

## AudioKit cloneしてビルド

[AudioKit/AudioKit: Swift audio synthesis, processing, & analysis platform for iOS, macOS and tvOS](https://github.com/AudioKit/AudioKit)

```
git clone https://github.com/AudioKit/AudioKit.git

cd Frameworks
./build_frameworks.sh
```

ビルドが完了すると、iOS,macOS,tvOS毎に「AudioKit.framework」ができます。


<img width="600" alt="AudioKit_Frameworks at master · AudioKit_AudioKit.png" src="https://qiita-image-store.s3.amazonaws.com/0/32215/cfc9c98a-bc5b-fa67-9eb6-c67695c731dc.png">

## AudioKitをプロジェクトにバンドルする

Generalタブの、Embedded Binaries セクションに「AudioKit.framework」をバンドルします。

<img width="600" alt="BowingVision.xcodeproj-1.png" src="https://qiita-image-store.s3.amazonaws.com/0/32215/c4c3bda2-eec5-7d6f-a695-56ce8dbca392.png">


## AudioKitテスト

メトロノームを動かしてみる

```swift

import UIKit
import AudioKit

class ViewController: UIViewController {

    let metronome = AKMetronome()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        metronome.callback = {
            print("call back")
        }
        metronome.tempo = 60.0
        metronome.subdivision = 3
        metronome.frequency1 = 2000
        metronome.frequency2 = 1000
        AudioKit.output = metronome
        AudioKit.start()
        metronome.start()
    }
    
    
    @IBAction func start(_ sender: Any) {
        metronome.reset()
        metronome.restart()
        
    }
    
    @IBAction func stop(_ sender: Any) {
        metronome.stop()
        metronome.reset()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}


```