OmniAICreator/Qiita-1.07M huggingface dataset:
windowsでatomが起動しなくなった時

# 現象
ある日会社に行くとatomをクリックしてもウンともスンとも言わない。

# 対処方法
コマンドプロンプトから起動
コマンドプロンプトでatomと入力してEnterすると普通に起動しました。
とりあえず使えるのでこのまま行きます。

# その他確認・試したこと
- プラグインのupdate→解決せず
- atomのupdate→解決せず
- コマンドプロンプトで atom --safeでセーフモードで起動 → 普通に起動する（プラグインは読み込まない)
- プラグインを1つずつアンインストールして起動→解決せず
    - コマンドプロンプトで以下の流れでアンインストール
        1. apm ls --installed --bare →インストールしたパッケージ確認 --bareをつけるとコピーしやすい感じで表示されます。
        2. apm uninstall {パッケージ名} →パッケージのアンインストール
        3. atom起動するか確認
        4. 1から3を繰り返す
        5. apm install {パッケージ名} →全部試してダメだったのでインストールしなおし
            - 1の内容をコピーしておいてまとめてインストールすると楽チン
- PC再起動→解決せず
- タスクマネージャーにatomのプロセスがあるか確認→なし
ちょっとずつ読むドメイン駆動設計 第一部 ドメインモデルを機能させる 第三章 モデルと実装を結びつける3

# 手続き型からモデル駆動へ

> オブジェクト指向プログラミングが強力なのは、あるモデリングパラダイムに基いていて、モデルを構成する概念に実装を提供するからだ。(第一部 第三章より)

言うまでもなく、エヴァンス本中の例はjavaだし、オブジェクト指向を前提として書かれています。

よく、Rubyでは、、、PHPでは、、、Scalaでは、、、と聞かれますが、答えはいつもやってみたらいいですよ。と、答えています。

なんならVBSで軽くですが、やったことがあります。

オブジェクト指向をサポートする言語なら、程度の差はあれどできると思います。

ただ、普段、手続き型で書いている場合、最初はうまくいかないかもしれません。

当然、手続き型で書いていてはうまくいかないはずです。

> モデル駆動設計も、Cなどの言語を使った場合には、限定的にしか適用できないが、これは純粋な手続き型言語と対応するモデリングパラダイムがないからだ。(第一部 第三章より)

プリント基板の例では、手続き型で書かれたスクリプトをモデル駆動で書き直す例が示されています。

一度、手続き型で書かれたソースコードをモデル駆動でリファクタリングしてみるのは大変お勧めです。
時間をかけて、全部書き直すということではなく、重用なドメインのコアの部分を抜き出して、または、抜き出しやすい箇所を選んで、一部を書き直してみるのです。

モデル駆動にしてからの変更のしやすさ、ルール、機能の追加のしやすさ、テストのし易さを感じることができるかと思います。

自分はこれを1万行を超えるVBSのファイルでやってみたことがあります。。。(かなり微妙だけど一応クラスが使える言語です。。。)

> 忘れないで欲しいのだが、こうしたモデルに基づく設計は一度に現れるものではない。(第一部 第三章より)

何度も本書でこれまでも述べられていましたが、反復を重ねて深いモデルになっていくのを忘れないということですね。
Kibana 5.6 をとりあえず動かしてみた


DL：https://www.elastic.co/downloads/kibana 
　Version:5.6.0
　Release date:September 11, 2017
　
※KibanaとElasticsearchは同じバージョン推奨(ドキュメントより)

---

## ■Kibana

リポジトリ追加

    rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
    
    cat << EOF > /etc/yum.repos.d/kibana5.repo
    [kibana-5.x]
    name=Kibana repository for 5.x packages
    baseurl=https://artifacts.elastic.co/packages/5.x/yum
    gpgcheck=1
    gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
    enabled=1
    autorefresh=1
    type=rpm-md
    EOF
    
インストール

    yum install kibana-5.6.0-1
    chkconfig --add kibana
    
設定
https://www.elastic.co/guide/en/kibana/current/settings.html 参照
デフォルトから変えたところ(明示的にコメント外したところも含む)

    server.port: 5601
    server.host: "tomi-test-agg01.hoge-internal.jp"
    elasticsearch.url: "http://tomi-test-elastic01.hoge
    internal.jp:9200"

起動

    service kibana start
    

接続方法
https://www.elastic.co/guide/en/kibana/current/access.html 参照

    http://tomi-test-agg01.hoge-internal.jp:5601
money_formatの小数点処理が謎だった

今日仕事で触ったコードを改修しててハマったこと。

### money_formatとは

```php
string money_format ( string $format , float $number )
```
> money_format() は、number をフォーマットして返します。この関数は C のライブラリ関数 strfmon() をラップしたものですが、一度に 変換できる数値がひとつだけであるという点が異なります。

http://php.net/manual/ja/function.money-format.php
との事。

金額を表示するような箇所で使われてて個人的には初めて見た。
ほえーこんな関数あったんだーと思ってたらなんか小数点の処理が不可解だった。

### 例

```php
setlocale(LC_MONETARY, 'ja_JP');
echo money_format("%n", 1000.4)."\n";
echo money_format("%n", 2500.6)."\n";
echo money_format("%n", 5000.5)."\n";
```

↓

```
¥1,000
¥2,501
¥5,000
```

まぁ普通に分かる。
`round()` したあと `number_format()` 掛けて先頭に`¥`付けるイメージなのかなーなんて最初は思ってた。

### ハマったのはここから

```php
setlocale(LC_MONETARY, 'ja_JP');
echo money_format("%n", 5001.5)."\n";
echo money_format("%n", 5002.5)."\n";
```

↓

```
¥5,002
¥5,002
```

ファッ！？

### 更に確認してみた

```php
setlocale(LC_MONETARY, 'ja_JP');
for ($i=0.5; $i<10; $i++) {
    echo "orig:".$i." / round:".round($i)." / money_format:".money_format("%n", $i)."\n";
}
```

↓

```
orig:0.5 / round:1 / money_format:¥0
orig:1.5 / round:2 / money_format:¥2
orig:2.5 / round:3 / money_format:¥2
orig:3.5 / round:4 / money_format:¥4
orig:4.5 / round:5 / money_format:¥4
orig:5.5 / round:6 / money_format:¥6
orig:6.5 / round:7 / money_format:¥6
orig:7.5 / round:8 / money_format:¥8
orig:8.5 / round:9 / money_format:¥8
orig:9.5 / round:10 / money_format:¥10
```


うーむ。。。？？？

金額の為の関数なんだろうけどちょっと挙動が謎過ぎてお金みたいなキッチリ処理して出さないと怒られちゃう系の表示にはあまり使いたくないなーなんて思っちゃった。


### 追記

コメントにて@hnwさんから教えて頂きました。

> これは偶数丸めという奴で、むしろお金の計算に使う丸め方式ですね。
> https://ja.wikipedia.org/wiki/%E7%AB%AF%E6%95%B0%E5%87%A6%E7%90%86#.E5.81.B6.E6.95.B0.E3.81.B8.E3.81.AE.E4.B8.B8.E3.82.81.EF.BC.88round_to_even.EF.BC.89

>> 端数が0.5より小さいなら切り捨て、端数が0.5より大きいならは切り上げ、端数がちょうど0.5なら切り捨てと切り上げのうち結果が偶数となる方へ丸める。

端数処理ってそんな種類いっぱいあったのね…
[Java] JVMのオプションで言語、ロケールを英語に変更する

IntelliJ等の組み込みコンソールで出力の言語が日本語だとどうしても文字化けする場合に、英語に設定したい。
その場合はJVMで以下のオプションを設定すればよかった。

```java:英語に設定
-Duser.language=en -Duser.country=US
```

もし日本語に設定したい場合は以下のようにする。

```java:日本語に設定
-Duser.language=ja -Duser.country=JP
```
composerをインストールする

[Macにhomebrewでphpを入れる](http://qiita.com/takehiro_t59/items/bf595c33afca05992da9)でphpを入れたので、composerをインストールする

#composerインストール
```bash
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('SHA384', 'composer-setup.php') === '55d6ead61b29c7bdee5cccfb50076874187bd9f21f65d8991d46ec5cc90518f447387fb9f76ebae1fbbacf329e583e30') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
```

#composerコマンドとして実行できるようにする
```bash
mv composer.phar /usr/local/bin/composer
```
Macにhomebrewでphpを入れる

Macを初期化して、再度環境構築でphpを入れることになったので、メモ。

ターミナルで入れることを想定。

#php7.1を入れる場合
```bash
brew tap homebrew/php
brew install php71
```
ターミナルを再起動。

```bash
brew services start homebrew/php/php71
php -v
```

#php7.2を入れる場合
```bash
brew tap homebrew/php
brew install php72
```
ターミナルを再起動。

```bash
brew services start homebrew/php/php72
php -v
```

#php7.1から7.2にする場合
```bash
brew unlink php71
brew install php72
```
ターミナルを再起動。

```bash
brew services start homebrew/php/php72
php -v
```
RでMendeleyからOAuth認証後、自分のライブラリ情報を抜き出す

# Mendeley で自分のライブラリの操作を行う
前回([RでMendeleyのAPIを叩いてみる](http://qiita.com/kyusque/items/2df08ea4ab49b4f07ce1))はアノニマスな認証でMendeleyのAPIを触ってみました。
今回はOAuth認証で自分のライブラリにアクセス権限を持つトークンを作成後APIを叩いてみたいと思います。
[Authorization code flow](http://dev.mendeley.com/reference/topics/authorization_auth_code.html)

# コード
## 各種情報の入力

```r
username <- "MendeleyのID(E-mail addres)"
password <- "Mendeleyのパスワード"

client_id <- "アプリケーションID"
client_secret <- "アプリケーションSecret"
redirect_uri <- "アプリケーションに登録したURL"

state <- "213653957730.97845" #CSRF対策用のコード、何でもよい

```

## 利用するAPIの設定
利用するMendeley APIを適宜設定してください。
http://dev.mendeley.com/ から選べます。

```r
api <- "https://api.mendeley.com/documents?limit=100"

```
## ライブラリと文字列操作用の二項演算子の設定
```r
require(httr)
require(rjson)
require(RCurl)
require(dplyr)

'%+%' <- paste0
```
## Mendeleyのユーザー認証URLにユーザー情報入力をしてアプリケーション側で利用するコードを得る
```r
basic_auth_credentials <- RCurl::base64(paste(client_id, client_secret, sep = ":"))

auth <-
  POST(
    "https://api.mendeley.com/oauth/authorize?client_id=" %+%
      client_id %+%
      "&redirect_uri=" %+%
      redirect_uri %+%
      "&response_type=code&scope=all&state=" %+%
      state
    ,
    add_headers(
      'Content-Type' = 'application/x-www-form-urlencoded'
    ),
    body = "&username=" %+% username %+% "&password=" %+% password
  )

code <- auth$url %>%
  {function(x) strsplit(x, split="\\?")[[1]][2]}() %>%
  {function(x) strsplit(x, split="\\&")[[1]][1]}() %>% 
  {function(x) strsplit(x, split="\\=")[[1]][2]}()
```

## 得られたコードからアクセストークンを得る

```r
access_token_rsp <-
  POST(
    'https://api.mendeley.com/oauth/token',
    add_headers(
      'Authorization' = paste("Basic", basic_auth_credentials),
      'Content-Type' = 'application/x-www-form-urlencoded'
    ),
    body = "grant_type=authorization_code&code=" %+%
      code %+% "&redirect_uri=" %+% redirect_uri
  )


access_token <- content(access_token_rsp)$access_token

```

## APIを叩いて、欲しい情報を得たり、やりたい操作を行う

```r

doc_rsp <- GET(api,
               add_headers(
                 'Authorization' = paste("Bearer", access_token),
                 'Content-Type' = 'application/vnd.mendeley-document.1+json' #APIを変える場合、ここも適宜変える必要あり
               )
)

docs <- doc_rsp %>% content %>% rawToChar %>% fromJSON
docs %>% lapply(function(x) x$title)
```
[Swift] iPhoneの写真をAPIにPOSTする際の、上下反転問題とファイルサイズ制限への対策

# 概要

iPhoneで撮影した写真を画像解析のWeb APIにPOSTするケースで、以下のような課題に直面しました。

**課題1**
iPhoneで撮影した写真は、iPhoneやMac上で見ると正常に見えますが、他の環境で見ると上下反転していることがあります。
APIの解析処理が正常動作しないため、上下反転を補正してからPOSTする必要が生じました。

**課題2**
APIの仕様上、「POSTする画像は○MB以下」というようなファイルサイズ制限がありました。
ファイルサイズを判定し、制限以下に圧縮する必要が生じました。

以下のようなExtensionを作って、これらの課題をクリアしました。

# 環境

| Item | Version |
|:--|:--|
| Xcode | 8.3 |
| Swift | 3.1 |

# UIImage Extension

```swift:Swift

extension UIImage {
    
    /// 上下逆になった画像を反転する
    func fixedOrientation() -> UIImage? {
        if self.imageOrientation == UIImageOrientation.up {
            return self
        }
        UIGraphicsBeginImageContextWithOptions(self.size, false, scale)
        self.draw(in: CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height))
        guard let newImage = UIGraphicsGetImageFromCurrentImageContext() else {
            return nil
        }
        UIGraphicsEndImageContext()
        return newImage
    }
    
    /// イメージ縮小
    func resizeImage(maxSize: Int) -> UIImage? {
        
        guard let jpg = UIImageJPEGRepresentation(self, 1) as NSData? else {
            return nil
        }
        if isLessThanMaxByte(data: jpg, maxDataByte: maxSize) {
            return self
        }
        // 80%に圧縮
        let _size: CGSize = CGSize(width: (self.size.width * 0.8), height: (self.size.height * 0.8))
        UIGraphicsBeginImageContext(_size)
        self.draw(in: CGRect(x: 0, y: 0, width: _size.width, height: _size.height))
        guard let newImage = UIGraphicsGetImageFromCurrentImageContext() else {
            return nil
        }
        UIGraphicsEndImageContext()
        // 再帰処理
        return newImage.resizeImage(maxSize: maxSize)
    }
    
    /// 最大容量チェック
    func isLessThanMaxByte(data: NSData?, maxDataByte: Int) -> Bool {
        
        if maxDataByte <= 0 {
            // 最大容量の指定が無い場合はOK扱い
            return true
        }
        guard let data = data else {
            fatalError("Data unwrap error")
        }
        if data.length < maxDataByte {
            // 最大容量未満：OK　※以下でも良いがバッファを取ることにした
            return true
        }
        // 最大容量以上：NG
        return false
    }
}

```

# Usage

```swift:Swift

let image = UIImage(named: "Donald_Trump.jpg")
// 上下反転を補正しつつ4MB未満にする
let arrangedImage = image?.fixedOrientation()?.resizeImage(maxSize: 4194304)

```

# 参考リンク

[iPhoneで撮影した画像の上下左右バラバラ問題](http://blog.morizotter.com/2015/06/20/uiimage-orientation-problem/)
[最大容量／最大サイズを指定してUIImageをNSDataに変換する](http://seeku.hateblo.jp/entry/2016/03/06/193628)
/proc/fs/cifs/SecurityFlagsの値

SambaというかCIFSが使うプロトコルにはいくつかのバージョンがありますが、具体的にどのプロトコルを使用できるのかは /proc/fs/cifs/SecurityFlags を見ることで確認できます。
たとえば Ubuntu 16.04.2 LTS では以下の結果になります。

```shell-session
$ cat /proc/fs/cifs/SecurityFlags
0x85
```
この値はビットフィールドになっているので、各ビットがどのような意味なのかが分からないと内容が読み取れません。が、mount.cifs(8)には書いてないですし、ググっても0x80だけは出てこない……

仕方がないのでソースコードを参照します。

https://github.com/torvalds/linux/blob/master/fs/cifs/cifsglob.h#L1521

```c:cifsglob.h
/* Security Flags: indicate type of session setup needed */
#define   CIFSSEC_MAY_SIGN	0x00001
#define   CIFSSEC_MAY_NTLM	0x00002
#define   CIFSSEC_MAY_NTLMV2	0x00004
#define   CIFSSEC_MAY_KRB5	0x00008
#ifdef CONFIG_CIFS_WEAK_PW_HASH
#define   CIFSSEC_MAY_LANMAN	0x00010
#define   CIFSSEC_MAY_PLNTXT	0x00020
#else
#define   CIFSSEC_MAY_LANMAN    0
#define   CIFSSEC_MAY_PLNTXT    0
#endif /* weak passwords */
#define   CIFSSEC_MAY_SEAL	0x00040 /* not supported yet */
#define   CIFSSEC_MAY_NTLMSSP	0x00080 /* raw ntlmssp with ntlmv2 */
```

ということで以下の値が設定されていることが分かりました。

- CIFSSEC_MAY_SIGN
- CIFSSEC_MAY_NTLMV2
- CIFSSEC_MAY_NTLMSSP
err.stackに含まれるコードの位置情報をsource mapで元に戻す

webpackやBabel、uglifyjsなどを使ってソースコードを変換している場合、err.stackに含まれるコードの位置に関する情報が変換後のコードの位置になっており、デバッグが難しい。err.stackに含まれる位置の情報をsource mapを使って、元のコードの位置に変換する方法をちょっとだけ調べた。

調べると色々なnpmパッケージが見つかるが、[source-map-support](https://github.com/evanw/node-source-map-support)が有名っぽい。

```console
# 検証用ディレクトリ作成
$ mkdir source-map-support-playground
$ cd source-map-support-playground

# 依存関係のインストール
$ yarn add babel-cli babel-preset-flow source-map-support -D
```

`src.js`に無理やりFlowtypeのコードを書き、`source-map-support/register`を読み込む。

```js
// src.js
// @flow
require('source-map-support/register');

function throwsError(message: string) {
  throw new Error(`ERR: ${message}`);
}

throwsError('hoge');
```

Babelで変換し、変換後のファイルを実行してみる。

```console
# source mapをつけて変換
$ babel --presets flow src.js --source-maps > lib.js

# 実行
$ node lib.js

/Users/xxxx/xxxx/src.js:5
  throw new Error(`ERR: ${message}`);
        ^
Error: ERR: hoge
    at throwsError (/Users/xxxx/xxxx/src.js:5:9)
    at Object.<anonymous> (/Users/xxxx/xxxx/src.js:8:1)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Function.Module.runMain (module.js:605:10)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:575:3
```

変換後の`lib.js`ではなく、`src.js`の位置で出力されていますね。

<br/>

実装を見てみると、souce mapから元の位置を取得するのにmozillaの[source-map](https://github.com/mozilla/source-map)を利用して、err.stackの書き換えはv8の[Stack Trace API](https://github.com/v8/v8/wiki/Stack-Trace-API)を使っているみたいです（Stack Trace APIについて、以前触れた[記事](http://qiita.com/pirosikick/items/04e099476d46c6389a1b)があるので、よかったらどうぞ）。

今回はNode.jsで動かしましたが、Chromeでも動く（v8だから）ようです。Chrome以外ではerr.stackの書き換えはできなそうなので、mozillaの[source-map](https://github.com/mozilla/source-map)を使ってerr.stack取得後に変換すればいけそうです。試していないので、負荷がどれくらいかかるかはわかりませんが。

Node.jsの場合だと、requireを書くだけなので、簡単でよいですね。
sympyで「比例配分計算」をやってみた

(参考)エクセルで「比例配分計算」をやってみた
http://qiita.com/mrrclb48z/items/47df222b99207c5d7a3e
(参考)Pythonのテキスト作りました
連立方程式の求解
http://www.k-techlabo.org/www_python/python_modules.pdf#page=58
辞書型
http://www.k-techlabo.org/www_python/python_main.pdf#page=25
代入（記号の置換）
http://www.k-techlabo.org/www_python/python_modules.pdf#page=54


```python
from sympy import *
var('y a x b x1 y1 x2 y2 ')
dic= solve(simplify('[y1-a*x1 -b, y2-a*x2 -b]'),simplify('[a,b]'))
ｙ=dic[a]*x+dic[b]
print(y.subs({x1:0,y1:0, x2:10, y2:10, x:5}))
# 5
```
iPhone X Human Interface  Guidelinesの要点

iPhone Xが登場したことで新たに注意すべき点をHuman Interface Guidelinesからまとめました。

## 最低限知っておくべきこと
* レイアウトは画面エリアの全てを使って表示される
* 画面の四隅が丸くなっているので端が切れてしまう可能性がある
* 受話口まわり（上部中央）とホーム画面に戻るためのジェスチャ用の目安表示（下部）にUI要素が被ってしまい見えなくなる可能性がある
* 横幅はiPhone8までのサイズと同じだが、縦が長い（1125px × 2436px (375pt × 812pt ＠3x)）
* SafeAreaという新しい概念がある（Storyboardに追加。プログラム側からも扱える。）
* ステータスバーの高さは従来の画面の高さより高くなるため、決め打ちしていた場合は注意
* 従来はステータスバー上に通話中等のバックグラウンドタスク表示がされると高さが変わったが、iPhone Xでは高さは変わらない
* 画面のアスペクト比が大きく異なるので、全画面の画像素材を従来の画面と使いまわす場合は注意
* 画面の下端でのスワイプジェスチャをホームボタンの代わりに利用するため、そのエリアでのカスタムジェスチャは無効化される

## 対策について
* 標準のUIパーツを使っている場合はほぼ問題なし（NavigationBar, TableView, CollectionView, TabBarなど）
* カスタムパーツを使っている場合でも対応は比較的簡単（特にAutoLayoutを使っていて、Storyboard上でSafeAreaとMarginのレイアウトガイドを使っている場合は簡単に対応できる。）
* 端末を持っていなくてもSimulatorからレイアウトを確認可能

<img width="777" alt="スクリーンショット 2017-09-14 20.29.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/24765/49ce6eab-3bf8-b4e0-112d-4240fb7f5ac3.png">
出典: [iPhone X Human Interface  Guidelines](https://developer.apple.com/ios/human-interface-guidelines/overview/iphone-x/)

## 知っておくと良い
* iPhone Xの画面は従来の画面よりもカラースペースが広い（Wide color）ので画像の見え方が異なる可能性がある
* iPhone Xではカスタムキーボードを使っていてもキーボードの下に入力方法切り替えボタン・音声入力ボタンが表示される

* 角丸になっている四隅のエリア、受話口エリア、ホームに戻るジェスチャ用のインディケーター（画面下部）に対処するために黒いViewを上下に配置して詰めたり、枠の画像で埋めたりしてはいけない（SafeAreaの外も連続的に繋がっているように見せろということだと思います。）
* また、これらのエリアにユーザに指示するようなテキストを表示して注意を惹かせない
* Auto-hiding機能（ホームに戻るジェスチャ用のインディケーターを隠す。ユーザーが画面をタッチすると表示される。）を頻繁に使わない。この機能はビデオ再生中やスライドショー表示中などでのみ使うべき。
* iPhone XではTouch IDではなくFace IDを使うため、アプリ内に表示する文言等でTouch IDについて触れている場合は変更する必要がある

---

間違い、追加等ありましたら編集リクエストいただけると助かります。

参考
https://developer.apple.com/ios/human-interface-guidelines/overview/iphone-x/
Ruby受け取った値を分割する

受け取った文字列を一文字ずつに分割して、配列へ格納する方法。

```
a = "Tohoku"  
moji = a.chars
```

これで`["T","o","h","o","k","u"]`の形で追加される。

2行目で文字列要素を分解し配列に代入している。
Square APIにおけるOAuthのscopeの種類

OAuthでは付きもののスコープ、もちろんSquareのOAuthにも存在します。デフォルトのスコープは以下になります。

- **MERCHANT_PROFILE_READ**  
ビジネスプロフィール情報の閲覧。氏名、プロフィール画像、Eメールアドレスが含まれます。
- **PAYMENTS_READ**  
振込履歴の閲覧。すべての振込情報が含まれます。
- **SETTLEMENTS_READ**  
銀行口座情報のサマリーの閲覧。口座種類、支店番号、および口座番号の末尾が含まれます。
- **BANK_ACCOUNTS_READ**  
支払履歴の閲覧。すべての取引および払戻情報が含まれます。

<img width="578" alt="Screenshot_ 2017-09-14 17.52.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/197026/980a0afe-b988-4eeb-8c22-c757b0d03cdb.png">

デフォルトは読み込み系ですが、書き込み系のスコープも用意されています。

## PAYMENTS_WRITE

![PAYMENTS_WRITE.png](https://qiita-image-store.s3.amazonaws.com/0/197026/56fcae97-ebad-ca4e-864b-95e53678a66e.png)


支払および払戻の作成。EコマースAPIを使う場合には必須のスコープです。

## CUSTOMERS_READ

![CUSTOMERS_READ.png](https://qiita-image-store.s3.amazonaws.com/0/197026/bba20f5e-03e1-b853-8089-5c43b9173cbd.png)


顧客連絡先情報の読み取り。

## CUSTOMERS_WRITE

![CUSTOMERS_WRITE.png](https://qiita-image-store.s3.amazonaws.com/0/197026/cb49b63d-43bc-84bc-0152-f43cef512185.png)


顧客連絡先情報の書き込み、編集、削除。ファイル上に保存されたクレジットカード情報も含まれます。

## ITEMS_READ

![ITEMS_READ.png](https://qiita-image-store.s3.amazonaws.com/0/197026/9564aa05-c5d1-fbf6-5981-5b379fc16f1d.png)

商品ライブラリの閲覧。

## ITEMS_WRITE

![ITEMS_WRITE.png](https://qiita-image-store.s3.amazonaws.com/0/197026/1c369a7f-5619-18a6-08dd-a2208d05ec0c.png)

商品、販売価格、ディスカウントの追加と編集が可能になります。

## ORDERS_READ

![ORDERS_READ.png](https://qiita-image-store.s3.amazonaws.com/0/197026/59eedefa-3aaf-7d18-5adb-d73472219463.png)


注文履歴の閲覧。

## ORDERS_WRITE

![ORDERS_WRITE.png](https://qiita-image-store.s3.amazonaws.com/0/197026/171f7040-08bd-a6a3-8dad-e2677a8decaf.png)


注文の作成と完了、キャンセル、払い戻しといった操作ができます。

## EMPLOYEES_READ

![EMPLOYEES_READ.png](https://qiita-image-store.s3.amazonaws.com/0/197026/d6e510a0-c856-711b-b3e2-1f075db4ba8f.png)


従業員情報の閲覧。

## EMPLOYEES_WRITE

![EMPLOYEES_WRITE.png](https://qiita-image-store.s3.amazonaws.com/0/197026/913133bb-08f6-2054-61bc-e635dcde1f00.png)


従業員情報の編集。氏名、役職、アクセス権限の追加または変更ができます。

## TIMECARDS_READ

![TIMECARDS_READ.png](https://qiita-image-store.s3.amazonaws.com/0/197026/30d14e8d-ae0b-c606-145f-33d34f330593.png)


従業員のタイムカード情報の閲覧。

## TIMECARDS_WRITE

![TIMECARDS_WRITE.png](https://qiita-image-store.s3.amazonaws.com/0/197026/a2413ce5-c05f-3d42-6b60-e12d56387587.png)


タイムカードの追加または変更を許可します。

----

このようなスコープが用意されていますので、アプリに必要な権限をそれぞれ求めるようにしてください。店舗ID（location.id）はほぼすべてのAPIで必要になるでしょう。またEコマース系であればPAYMENT_WRITE権限は必須になるでしょう。

[Square Connect API Documentation](https://docs.connect.squareup.com/api/oauth/#permissionscope)
Google Apps Scriptでうるう秒は問題になるか

Google Apps Scriptでn日後の日付の計算をするとき、ネットを探してみると以下のようなコードに出会いました。

```javascript
// n日後の日付を取得
function dateAfterDayNum(dateBase, dayNum) {
  var msecOfADay = 86400000;
  var t1 = dateBase.getTime();
  var msec = dayNum * msecOfADay;
  var t2 = t1 + msec;
  return new Date(t2);
}
```

1日が `86400秒` (=60秒*60分*24時間)と固定されていますが、うるう秒(閏秒)を含む日は1日 `86401秒` です。最近では2016年年末にうるう秒の挿入があったので、その日は86401秒でした。

つまり、2016年12月31日の1日後の計算

```javascript
dateAfterDayNum(new Date(Date.UTC(2016, 11, 31)), 1)
```

の結果が期待通り
`2017年1月1日0時0分0秒`
にならずに
`2016年12月31日23時59分60秒`
となる心配はないかと思ったのです。

### Google Apps Scriptでテスト

いざGoogle Apps Scriptで試してみると、、、
`2017年1月1日0時0分0秒`
になりました。はい、取り越し苦労でした。
上のコードでも問題なくn日後の日付の計算ができるというわけです。

言い換えると、Google Apps Scriptでうるう秒の計算はできない、23時59分60秒は表現、計算できないということでしょう。

まあGoogle Apps Scriptを使うようなほとんどのケースで問題ないとおもいます。

### n日後の日付の計算

なお、n日後の計算には

```javascript
new Date(d.getFullYear(), d.getMonth(), d.getDate() + dayNum);
```

のコードを使いました。

### JavaScriptでうるう秒

JavaScriptの仕様的にも、うるう秒は扱わないようです。

*ECMAScript® Language Specification*
http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.1
> In time values leap seconds are ignored. It is assumed that there are exactly 86,400,000 milliseconds per day.


### Googleのうるう秒対応

Googleではうるう秒を **ぼかして消す方法** で対応しています。

*うるう秒がやって来る！〜 6 月 30 日の ” 1 秒”に備えよう〜*
https://cloudplatform-jp.googleblog.com/2015/05/6-30-1.html

うるう秒前後の20時間の間、1秒をわずかに伸ばして (`約1.000014秒`に伸ばして) 扱うことにより、うるう秒が無かったかのようにシステムが動きます。
これはGoogle Apps Scriptでうるう秒を扱わないことと整合していると思います。

### 関連記事

[Ruby等でのうるう秒とtimezone環境変数TZとの関係](http://qiita.com/iizuka/items/98c06d6a82e45c71bff6)
DataPumpのexpdp を停止→再開

途中でインポート停止して、再開したい場合の手順を残します。
※注意：もし、実行する際は自己責任でお願いいたします。

いや~以前、impdpでインポート中に表領域が足りなくなって、途中停止せざる追えなくて、焦ったので今後のために手順記載します。


--１，ジョブ名確認
set linesize 200
col owner_name for a10
col job_name for a20
col operation for a10
col job_mode for a10
col state for a12
col degree for 999
col attached_sessions for 999
col datapump_sessions for 999

SQL>select * from dba_datapump_jobs;


--２，ジョブ停止する場合
$impdp system/xxxx attach=SYS_IMPORT_TABLE_01


--３，ジョブを完全停止
impdp system/xxxx attach=SYS_IMPORT_TABLE_01 
Import> kill_job


以上、
Raspberry Pi3でキオスク端末(自動ログイン＋ブラウザ起動)を作る。


# はじめに
　余っているモニターと、持て余しているRaspberry Piを使って情報端末：キオスク端末を作ろうと思ったので、その作業メモ。


## 今回使用したもの
- Raspberry Pi 3 model B
- micro SDカード 8GB
- USBキーボード & USBマウス
- RASPBIAN STRETCH WITH DESKTOP 
    - ダウンロードは公式サイトから。[Download Raspbian for Raspberry Pi](https://www.raspberrypi.org/downloads/raspbian/)
    - Version:September 2017
    - Release date:2017-09-07


# 作業
## Raspberry Pi のセットアップ
1. RaspberryPi用イメージをダウンロード。
    - 30分くらいかかるので事前にダウンロードしておくほうが良い。
1. ダウンロードしたイメージをmicro SDカードに書き込む。
    - Windowsなら[Win32 disk Imager](https://sourceforge.net/projects/win32diskimager/)などを使うと便利。
    - 10MB/sで書き込む場合、10分くらいかかります。
1. Raspberr Piの電源を入れる
2. Terminalを開いて、インストール済みパッケージのアップデートをおこなう。
    - `sudo apt-get update`
    - `sudo apt-get upgrade`

## ブラウザの自動起動
1. Performancesメニューの中にある、Raspberry Pi Configurationで自動ログイン設定する
    - Systemの変更＆確認する場所は下記
        - Hostname を変更する
        - Boot が "To Desktop"である
        - Auto Login のチェックボックス「As current user」がONになっている
![image.png](https://qiita-image-store.s3.amazonaws.com/0/38845/a79536d0-3c69-4cf1-b1d6-beae38b3a157.png)

1. 起動時に`~/.config/chromium/Singleton*`を削除するようにcrontabに追記
    - `@reboot  rm -rf ~/.config/chromium/Singleton*`
    - `~/.config/chromium/Singleton*`、正常に終了できなかった場合に残る。   
    残っていると起動時にメッセージが表示されてしまう。

1. マウスがしばらく動いていないと、マウスカーソルの表示を消すツール`unclutter`を入れる
    - `sudo apt-get install unclutter`
1. `~/.config/lxsession/LXDE-pi/autostart`を編集する

```diff:~/.config/lxsession/LXDE-pi/autostart
@lxpanel --profile LXDE-pi
@pcmanfm --desktop --profile LXDE-pi
@xscreensaver -no-splash
-@point-rpi

+@xset s off
+@xset -dpms
+@xset s noblank
+@unclutter
+@chromium-browser --noerrdialogs --kiosk --incognito http://localhost/
```
`@chromium-browser`の`http://localhost/`を表示させたいURLに書き換える

- その他のオプションについて
    - --noerrdialogs : エラーを表示させない
    - --kiosk : 全画面モードで表示させる
    - --incognito : シークレットモードで起動させる


## サービスを自動起動させる

```ini:/etc/systemd/system/myprogram.service
[Unit
Description= My maked program
After=syslog.target

[Service]
Type=simple
WorkingDirectory = /home/pi/myprogram
ExecStart = home/pi/myprogram/programrun
Restart = always
TimeoutStopSec=5

[Install]
WantedBy = multi-user.target
```

1. 上記ファイルを`/etc/systemd/system/`に作る。
2. あとはsystemctlを使って操作してみる
    - 実行する `sudo systemctl start myprogram`
    - 停止する `sudo systemctl stop myprogram`
    - 起動時に実行させる `sudo systemctl enable myprogram` 
    - 起動時に実行させない `sudo systemctl disable myprogram`

## 完了後の確認事項

- 再起動時、期待通りに自動起動するか確認。
- 実際に再起動してみる
- USB電源を強制切断してみる
- 外部に公開する前に、ログインするユーザー(pi)のパスワードを変更すること。

# 最後に
　簡単にやりたいことができるのがRaspberry Piのいいところですよね。これからも、いろいろ作っていきたい。

## 参考
- [Raspberry Piでプログラムを自動起動する5種類の方法を比較・解説](http://hendigi.karaage.xyz/2016/11/auto-boot/)
Atomでplant-viewerが動かないから、代わりにplantuml-previewを使う(mac)

# なぜ導入に至ったか
1. UMLを描いてみよう
2. どうせならコード管理できる方がいい！GitHubにもあげやすい！PlantUML使おう！
3. LIVEプレビューできるらしい！atomにplant-viewer入れよう！
4. 動かねぇぇぇぇ。

# 対象者
・plant-viewerを使いたかったけど、動かなくて使えなかった人

# 動作環境
Mac 10.12.6
java 1.6.0_65(64bit版)
Atom

# やり方

### 1: 前提環境の構築
graphviz、plantuml、javaのダウンロード
http://qiita.com/kohashi/items/1d2c6e859eeac72ed926

### 2: plantuml-previewを入れる
Atomからplantuml-previewをインストールします。

### 3: 設定をいじる

![スクリーンショット 2017-09-14 20.26.44.png](https://qiita-image-store.s3.amazonaws.com/0/114709/c40d56d1-fcdf-4c07-bef4-c2333c138ed7.png)

### その１
1: でダウンロードしたgraphvizに含まれる「dot」の実行ファイルのパスを入力する
(graphvizはdot言語で書かれた画像ファイルへの出力ツールらしい)
わからなければコマンドラインで

```
which dot
```

とすればパスを確認できる

### その２
ダウンロードした(もしくはされている)plantuml.jarファイルのパスを調べる。
任意にダウンロードした場合はそのパスを入れれば良い。

brewを使ってインストールした場合は

```
command + shift + G
```

を押して出てきたポップアップに
「/usr/local/Cellar/plantuml」と入力して検索すると
![スクリーンショット 2017-09-14 20.38.14.png](https://qiita-image-store.s3.amazonaws.com/0/114709/130f48f8-a008-a214-cd06-65b5e82de068.png)
このようなフォルダ構成になっているので、libexec直下のplantuml.jarのパスを調べて設定に入力する。

#メリット
[ ] Use Temp Dir
というチェックボックスを外しておくと
![スクリーンショット 2017-09-14 20.41.22.png](https://qiita-image-store.s3.amazonaws.com/0/114709/8534c548-c358-de92-ba05-30b85da4735c.png)
このように、対象ファイルと同じディレクトリにsvg/png画像が生成される。

LIVEプレビューではないが、ATOMでのファイル変更保存時(command + s)にUMLを更新して表示してくれる。

#デメリット
LIVEプレビューではないので、「ctrl + option + P」を毎回押して確認する必要がある。
iOS11 xcode9でビルドすると、デフォルトアイコンになってしまう。または申請時に Missing required icon file. と怒られる場合

- xcode9でビルドしたアプリはなぜかデフォルトの、白背景に幾何学模様のアイコンになってしまう

- 申請しようとすると Missing required icon file. と怒られた

**これらの現象に遭遇した場合は cocoapods が怪しい**

# 対応策

- cocoapods本家でプルリクも出ていますが
https://github.com/CocoaPods/CocoaPods/pull/7020


```
post_install do |installer|
    copy_pods_resources_path = "Pods/Target Support Files/Pods-（アプリのTARGET名）/Pods-（アプリのTARGET名）-resources.sh"
    string_to_replace = '--compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"'
    assets_compile_with_app_icon_arguments = '--compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${BUILD_DIR}/assetcatalog_generated_info.plist"'
    text = File.read(copy_pods_resources_path)
    new_contents = text.gsub(string_to_replace, assets_compile_with_app_icon_arguments)
    File.open(copy_pods_resources_path, "w") {|file| file.puts new_contents }
end
```

これを Podfile に追加して、

```
pod install
```
を再実行。

以上で解決します
WPFで読み込むDLLたちを別フォルダにまとめる


ライブラリをいくつか利用したりするとちょっとしたツールでもDLLが大量になってしまう。
PrismとReactivePropertyを使ってMVVMで軽く組もうとでも思うと、
大したことない労力のEXE1つに対してDLLが実に20個近く追加されてしまう。

こうなるとDLLに埋もれてEXEを探すのが大変・・・となってしまうので解決策を探してみました。


App.configのassemblyBindingタグ内にprobingタグを追加すればできるみたいです。

下記例はexeと同階層のbinフォルダにDLLを集約するイメージ

```xml:App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="bin" />
    </assemblyBinding>
  </runtime>
</configuration>
 ```

注意点としては「exe名 + .exe.config」のファイルは必ずEXEと同階層にいないと動かないので注意
（このConfigを見て、設定したフォルダ内のDLLを見に行くので当たり前に必要ですね）

勉強がてらにちょっとしたツールに大層なライブラリを突っ込むことをよくするので、これでスッキリEXEを叩くことができ、かつ気兼ねなく勉強もできます。

#参考元
[DLLの配置場所を変更する(probing, codebase, developmentMode)](http://d.hatena.ne.jp/tekk/20110403/1301829578)

#こういうのもアリ
[実行ファイルとDLLを一つにまとめる](https://qiita.com/krsak/items/75a257cc0866a7e8e4aa
)
Node.jsのMochaのテストコードをChromeの開発ツールでデバッグする

v6.3.0以降のNode.jsでは `--inspect` を指定することでChromeの開発ツールでデバッグできるようになっています[^1]。`--inspect-brk` を指定するとプログラムの先頭にブレークポイントが設定されます。ですが、Mochaのテストコードを開発ツールでデバッグしようとするとMochaのスタートアップルーチンで停止してしまうので、まだテストコードもテスト対象のプログラムもロードされておらず、デバッグしたい箇所にブレークポイントを設定することができません[^2]。
このような場合、以下の操作でブレークポイントが設定できます。

### REPLでテスト対象のプログラムにブレークポイントを設定する
1. コマンドラインから `node --inspect` でREPLを起動し、開発ツールから参照します。([→手順](http://qiita.com/kobalab/items/57f6a8513d40f7c2d569))
2. 開発ツールの Console から `require()` でテスト対象のプログラムをロードします。
3. 開発ツールの Sources からテスト対象のプログラムを選択し、適当な場所(コンストラクタが最適と思われる)にブレークポイントを設定します。
4. 開発ツールを閉じ、コマンドラインから起動したREPLも終了させます。

### テストプログラムを開発ツール内で走行させブレークポイントで停止させる
1. `npm test -- --inspect-brk テストプログラム名` でテストプログラムを走行させ、開発ツールから参照します。
2. Mochaのスタートアップルーチンで停止している状態なので、開発ツールのデバッガの再開ボタンを押下し、プログラムの走行を再開させます。
3. テスト対象のプログラムの先ほど設定したブレークポイントでプログラムが停止するはずです。開発ツールがセッションをまたがってブレークポイントを覚えていてくれるのがミソです。

### テストコードにブレークポイントを張る
1. ここまでくれば、すでにテストコードもロードされた状態になっているはずなので、開発ツールの Sources からテストプログラムを選択し(かなりの数のプログラムがロードされるので探すのがちょっと面倒です)、デバッグしたい箇所にブレークポイントを設定すればOKです。

[^1]: https://nodejs.org/en/docs/inspector/#command-line-options
[^2]: そもそもテストの失敗理由はアサーションで知るべきであり、テストコードをデバッガで参照するなど邪道なのですが、それでもデバッガで追いたくなる場合もあるものです。
iOS11でUIVisualEffectViewに直接addSubviewすると落ちる

開発中のアプリが何故か原因不明のエラーで落ちるので原因を調査した内容のまとめです。

## 検証コード

```
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
effectView.frame = self.view.bounds
self.view.addSubview(effectView)
		
let label = UILabel(frame: self.view.bounds.insetBy(dx: 100, dy: 100))
label.backgroundColor = UIColor.blue
label.text = "Hello iOS11"
effectView.addSubview(label)
```

## 修正方法

検証コードだけで実行した場合は正しくエラーと修正方法が提示されたので解決しました。

``Do not add subviews directly to the visual effect view itself, instead add them to the -contentView.'``


```
effectView.addSubview(label)
↓
effectView.contentView.addSubview(label)
```
ラズパイ + Python + OpenGL メモ

# 環境
- Raspberry Pi 3 Model B
- python3.5.2 (pyenv)
- [LCD モニタ](http://amzn.asia/65JJadx)

# セットアップ
```
sudo apt-get install python-opengl
pip install pyopengl
```

もし画像を表示したいなどで Pillow を入れたい場合

```
sudo apt-get install libjpeg-dev
pip install Pillow
```
もしておく

# 動作確認
http://tomosoft.jp/design/?p=9152 のコードを動かしてみる

```py3
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import sys
 
def display():
    glClear(GL_COLOR_BUFFER_BIT)
    glFlush()
 
 
def main():
    glutInit(sys.argv)
    glutInitWindowSize(300, 300)
    glutInitDisplayMode(GLUT_RGBA)
    glutCreateWindow(b"OpenGL")
 
    glutDisplayFunc(display)
    glClearColor(0.0, 0.0, 0.0, 1.0)
    glutMainLoop()
 
    return 0
 
 
if __name__ == "__main__":
    main()
```
ウィンドウが立ち上がれば OK

# ハマったところ
```
pip install pyopengl
```
のみだと、上記サンプル実行時に以下のようなエラーが起こる

```py3
Traceback (most recent call last):
  File "gltest.py", line 25, in <module>
    main()
  File "gltest.py", line 12, in main
    glutInit(sys.argv)
  File "/usr/local/lib/python2.7/dist-packages/PyOpenGL-3.1.1a1-py2.7.egg/OpenGL/GLUT/special.py", line 333, in glutInit
    _base_glutInit( ctypes.byref(count), holder )
  File "/usr/local/lib/python2.7/dist-packages/PyOpenGL-3.1.1a1-py2.7.egg/OpenGL/platform/baseplatform.py", line 407, in __call__
    self.__name__, self.__name__,
OpenGL.error.NullFunctionError: Attempt to call an undefined function glutInit, check for bool(glutInit) before calling
```

ラズパイに元々入っている OpenGL は OpenGL ES2 だという話しがあり、 OpenGL ES2 は GLUT を使えないのでこのようなことになっているのではないかと想像している。
`セットアップ` のように python-opengl を apt-get で入れて解決。
Vue.js資料色々

# Vue.js色々

## インストール必須

[vue-devtools](https://github.com/vuejs/vue-devtools)

## チートシート

* [Vue.js](https://vuejs-tips.github.io/cheatsheet/)
* [Vuex](https://vuejs-tips.github.io/vuex-cheatsheet/)
* [Vue.js(日本語)](https://nak1114.github.io/cheatsheet/)

## 参考資料

* [Vue.jsガイド](https://jp.vuejs.org/v2/guide/)
* [Vuexガイド](https://vuex.vuejs.org/ja/)
* [Smart and Dumb Components in React](https://jaketrent.com/post/smart-dumb-components-react/)
* [Vue.js コンポーネントスタイルガイド](https://pablohpsilva.github.io/vuejs-component-style-guide/#/japanese)
* [Storybook](https://storybook.js.org/)
* [Awesome Vue](https://github.com/vuejs/awesome-vue)
* [Vue + Vuex — Getting started](https://medium.com/wdstack/vue-vuex-getting-started-f78c03d9f65)


## JsFiddle

https://jsfiddle.net/reoring/estpvq46/526/
githubのファイルページでrawgit urlを作成するブックマークレット

コメントで教えていただいたのですが、**rawgitは終了**します。

> https://rawgit.com/


取得済みのrawgitは2019.10まで使用できるようです。
[chrome拡張機能](https://chrome.google.com/webstore/detail/sushi/kiifdpngeokjhkanhcbefmeflpchafop)も出しちゃっていたので地味に困る……。

***

githubのファイルページで**rawgit url**を作成するブックマークレットをつくりました。

>過度のトラフィックは抑制され、ブラックリストに載せられます。
過剰なトラフィックが続くと、RawGitはあなたの注意を引くためにあなたのウェブサイトに目立ったエラーメッセージを表示します。

ということなので、テスト用などに使用を制限しましょう。

- [GitHub上のファイルをCDNとして参照する
](http://qiita.com/takanorig/items/89db46120d2ec171e3d8)
- [GitHubなどに公開されているコードをscriptタグで読み込む方法](http://kuroeveryday.blogspot.jp/2016/01/rawgit.html)

普通にjsで書いて、[http://chriszarate.github.io/bookmarkleter/](http://chriszarate.github.io/bookmarkleter/)で変換かけました。 

```js:source
-function() {
    if (location.hostname == "github.com") {
        var rawgit_format = "//rawgit.com" + location.pathname.replace(/\/blob/, "");
        prompt("rawgit url", rawgit_format);
    } else {
        alert("not github page");
    }
}();

// 即時関数はなんでも良い
// -function(){}();
// !function(){}();
// (function(){})();
// etc...
```

uglify処理をしてくれた1行コードに変換されるのでブックマークするだけです。

```js:bookmarklet
javascript:-function(){if(%22github.com%22==location.hostname){var%20t=%22//rawgit.com%22+location.pathname.replace(/\/blob/,%22%22);prompt(%22rawgit%20url%22,t)}else%20alert(%22not%20github%20page%22)}();
```
iPhone X・iPhone 8・iPhone 7の違いを徹底比較！どっち買うべき？

# iPhone X・iPhone 8・iPhone 7の違いを徹底比較！どっち買うべき？
iPhone X とiPhone 8がようやく正式に発表されました。アップルファンたちはどう思いますか？iPhone XとiPhone 8は同時に発表されるので、どっちが買うべきかな悩んでいるでしょう。そして、iPhone XとiPhone 8が発売すると、iPhone ７の価格は安くなります。なので[iPhone 7](https://www.imobie.jp/support/should-i-buy-iphone-7.htm)を買いたい人もいます。では、iPhone X・iPhone 8・iPhone 7、いったいどっち買いなのか？ここでiPhone X・iPhone 8・iPhone 7の違いを徹底的に比較します。iPhone X/8/7どっちか迷ったら、ぜひ見逃さないでください。
## iPhone X・iPhone 8・iPhone 7の基本情報
![1.png](https://qiita-image-store.s3.amazonaws.com/0/197388/516fb91a-db8a-17d6-1104-1097d6daf5e0.png)
## iPhone X・iPhone 8・iPhone 7違いの比較
**デザイン**
iPhone Xは全画面ディスプレイが採用されています。iPhone 8はガラスから生まれたまったく新しいデザインを持っています。iPhone 7は伝統的なデザインのままです。
**ホームボタン**
iPhone Xは物理的なホームボタンを廃止し、指紋認証の代わりに、Face ID（顔認証）を使っています。顔がパスワードとして、認証、ロック解除、支払いを安全にできます。
**カメラ**
iPhone 7とiPhone 8はほぼ同じで、1200万画素、光学式手ブレ補正が搭載されて、美しい画像が撮影できますが、iPhone Xは2つのバックカメラ、両方とも光学式手ぶれ補正と高速なレンズを搭載しています、夜景でも鮮明な写真が撮れます。撮った写真は現実の世界をいきいきと再現されます。
**電源とバッテリー**
![2.png](https://qiita-image-store.s3.amazonaws.com/0/197388/0a19cd13-39a7-c447-df48-8a020cb81887.png)
**チープ**
iPhone Xと8はA11を搭載して、iOS 11の新機能を体験できるだけでなく、システム＆処理性能の高くなります。
**アニ文字**
私は一番面白いものだと思います。顔の動きを分析して、表情を12種類のアニ文字に反映させます。
**ワイヤレス充電**
世界中のホテル、カフェ、空港などにあるワイヤレス充電ステーションやマットで充電できます。
**発売日と価格**
iPhone 7はもう発売しました。
価格は：32GB - 7万2800円；128GB - 8万3800円;256GB - 9万4800円。(税別)
iPhone 8：9月15日午後4時1分予約開始、9月22日発売。(税別)
価格は：64GB - 7万8800円；256GB - 9万5800円。
iPhone X：10月27日午後4時1分予約開始、11月3日発売。
価格は：64GB - 11万2800円；256GB - 12万9800円。(税別)
[詳しいのはこちら＞＞](https://www.imobie.jp/support/which-iphone-is-best-for-you.htm)
## 最後に
**iPhone Xの入手をおすすめする人：**
iPhoneの10周年の記念版を入手したい
新しいモデルが欲しい
バッテリーの持続時間が長くなりたい
**iPhone 8の入手をおすすめする人：**
iPhone 8の新機能に満足している
指紋認証機能「Touch ID」を続けて使用したい
急いで機種変更する必要がある
小さいiPhone（4.7インチ）を使い続けたい
**iPhone 7の入手をおすすめする人：**
iPhone X/8に興味ない
iPhone X/8の価格が高いと思う
iPhone 7の性能に満足している
小さいiPhone（4.7インチ）を使い続けたい
経済的に余裕がない
slimでカスタムデータ属性を設定してみた

#今回起きたこと
今回railsプロジェクトに携わり、javascriptやreactなど触る機会が増えた。
そこでjavascript側にカスタムデータ属性を渡すことになったのだが、
調べても全くわからず時間を無駄にしてしまった。。。。
slimのlink_toなどにdata属性を設定する方法はたくさん出てくるのに、
divやspanなどに設定する方法があまり乗っていなかった。

##結論
divやspanなどにカスタムデータを設定するには
めちゃくちゃ簡単だった。。。

```slim
.className data-test=""
```

とやるだけだった。
こんな簡単なことで30分ほど時間を無駄にしてしまった。

##おまけ
link_toに付ける場合は

```slim
= link_to '', class: 'className', data: { name: '' }
```

これで設定できる見たい。。
Drupal8のカスタムモジュール作成メモ

作ってしまえば単純だが、やっぱり苦労したので必要最低限の手順をメモ。

# 最低限のモジュール作成
_最低限のモジュール_ とは、drupal8にモジュールとして認識させるレベル。特に目的の動作はない。

# カスタムディレクトリの用意
まずは、モジュールのディレクトリを作成します。ディレクトリ名はスネークケース _(単語の区切りを"\_"で区切る)_ を用いる。

例えば _First Module_ というモジュールを作成する場合には、 _first\_module_ と言うようなディレクトリを作成する。

```shell-session
first_module/
├
```

# MODULE.info.ymlを作成
最低限ディレクトリと _MODULE.info.yml_ が必要です。
_MODULE_ の部分は、ディレクトリ名とあわせておけば良い。今回は、 _first\_module.info.yml_ とし、 _first\_module_ ディレクトリに格納する。

```shell-session
first_module/
├first_module.info.yml
```

## first_module.info.ymlの中身

```yml:first_module.info.yml
name: First Module　                          #モジュールの名前
type: module                                  #モジュールを作成する時はmoduleでよい。
description: 'My first custom module.'        #モジュールの説明
core: 8.x                                     #対象のDrupalのバージョン
package: My Custom Module                     #パッケージ名（任意？）
```

# モジュールをインストールする
作成したモジュールは、Drupal本体に含まれる _modules_ ディレクトリに設置する。ただし、提供されているモジュールと区別するため _modules_ ディレクトリの下に _custom_ ディレクトリを作成し、その中にモジュールを設置する。


```shell-session
DRUPAL/
├modules/
│├custom/
││├first_module/
│││├first_module.info.yml
```

上記のようにモジュールを設置すると、Drupalの管理画面より「機能拡張(_/admin/modules_)」に _First Module_ が表示されるので、画面に従ってインストールを実施すれば良い。
[ACM] SSL証明書発行時のドメイン認証メールをSESで受け取ってみた のTerraform

元ネタ：[[ACM] SSL証明書発行時のドメイン認証メールをSESで受け取ってみた](http://dev.classmethod.jp/cloud/aws/acm-verifydomain-ses/)

意外と設定項目多いしメンドかったので書いとく

- providerは適当に定義
- `example.com`になってるところを適当に良い感じに設定

```hcl
resource "aws_ses_domain_identity" "mail" {
  domain = "example.com"

  provider = "aws.oregon"
}

resource "aws_route53_record" "mail_amazonses_verification_record" {
  zone_id = "zone_id of example.com"
  name    = "_amazonses.example.com"
  type    = "TXT"
  ttl     = "600"
  records = ["${aws_ses_domain_identity.mail.verification_token}"]
}

resource "aws_route53_record" "mail_amazonses_inbound_mx" {
  zone_id = "zone_if of example.com"
  name    = "example.com"
  type    = "MX"
  ttl     = "600"
  # リージョンごとに設定するエンドポイントは↓を参照(例はオレゴン)
  # http://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/regions.html
  records = ["10 inbound-smtp.us-west-2.amazonaws.com"]
}

resource "aws_s3_bucket" "mailbox" {
  bucket = "mailbox"
}

resource "aws_s3_bucket_policy" "mailbox" {
  bucket = "${aws_s3_bucket.mailbox.id}"
  policy = "${data.aws_iam_policy_document.mailbox.json}"
}

data "aws_iam_policy_document" "mailbox" {
  statement {
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["ses.amazonaws.com"]
    }

    actions = [
      "s3:PutObject",
    ]

    resources = ["${aws_s3_bucket.mailbox.arn}/*"]
  }
}

resource "aws_ses_active_receipt_rule_set" "mail" {
  rule_set_name = "${aws_ses_receipt_rule_set.mail.rule_set_name}"

  provider = "aws.oregon"
}

resource "aws_ses_receipt_rule_set" "mail" {
  rule_set_name = "primary-rules"

  provider = "aws.oregon"
}

resource "aws_ses_receipt_rule" "store" {
  name          = "store-s3"
  rule_set_name = "${aws_ses_receipt_rule_set.mail.rule_set_name}"
  recipients    = ["example.com"]
  enabled       = true
  scan_enabled  = true

  s3_action {
    bucket_name = "${aws_s3_bucket.mailbox.id}"
    position    = 1
  }

  provider = "aws.oregon"
}
```
[自分用メモ]変更しておきたいカーネルパラメータ

```
/proc/sys/kernel/hung_task_timeout_secs
# デフォルトでは120秒
# hung check timer のタイムアウト時間を指定する
```
> 特定のプロセスが「 CPU 時間を占有し続けた場合」に出力される softlockup 特定のプロセスが「割り込み（による中断が）不可能なスリープ状態にあり続けた場合」に出力される
参考 http://www.intellilink.co.jp/article/column/oss08.html

```
/proc/sys/fs/inotify/max_user_instances
# デフォルトでは128
# 1 つの実ユーザ ID に対して生成できる inotify インスタンスの数の上限を指定する。
```
> 参考　http://wadap.hatenablog.com/entry/20100123/1264211202

```
/proc/sys/fs/aio-max-nr
# デフォルトでは？？？(忘れた)
```
> Linux の libaio による非同期I/Oでは aio コンテキスト数は /proc/sys/fs/aio-nr で確認でき、/proc/sys/fs/aio-max-nr に達すると、io_setup システムコールの戻り値に EAGAIN が返される。
参考 http://d.hatena.ne.jp/yohei-a/20140407/1396893637

```
echo fs.inotify.max_user_instances = 256 >> /etc/sysctl.conf
```
などとして再起動しても戻らないよう設定しておく。
Go で実行ファイルのパスを取得

実行ファイルと同じディレクトリにファイルを置きたい場合とか
実行ファイルのパスで、プログラム実行時のカレントディレクトリではない

https://golang.org/pkg/os/#Executable

`exe, err := os.Executable()`

ファイル名までのフルパスが exe に格納される

ディレクトリ名(dirname コマンドイメージ) が欲しければ以下
path/filepath の import を忘れずに

`filepath.Dir(exe)`
[TIPS] Ruby & Rails 初心者が最初にいろいろやったこと

## 概要
もっぱら言語ではJava、最近ではAndroidアプリ開発をメインにやってきた人間が、久しぶりにサーバーサイドプログラミングをやったというお話。
しかも未経験のRuby & Railsでしたので、何をやったかまとめときます。

## やったこと
1. まずは[公式Webドキュメント](https://www.ruby-lang.org/ja/documentation/)を読んでみる  
公式Webサイトでは[他言語からのRuby入門](https://www.ruby-lang.org/ja/documentation/ruby-from-other-languages/)という素敵なコンテンツがあります。  
僕はその中の[JavaからRubyへ](https://www.ruby-lang.org/ja/documentation/ruby-from-other-languages/to-ruby-from-java/)を読みました。  
1. とりあえず [Ruby on Rails チュートリアル](https://railstutorial.jp/) をやる  
僕の場合はRails5.0(第4版)をやりました。
2. [クックパッド開発者ブログ](http://techlife.cookpad.com/)を読む  
今の会社はCTOがクックパッド出身ということもあり、多くの技術がクックパッド由来です。  
全部読んでも仕方ないので、[rails](http://techlife.cookpad.com/search?q=rails)と[docker](http://techlife.cookpad.com/search?q=docker)に関連するところを読みました。  
あとクックパッドの[rubyコーディング規約](https://github.com/cookpad/styleguide/blob/master/ruby.ja.md)なんかも眺めてみました。  
3. 本を読む  
ちょっと古いですが、[パーフェクト Ruby on Rails](http://amzn.asia/43cFvqj)あたりが手頃でした。  
Rails5対応でいい本あったら教えてください。

## これからやること
- Railsのエコシステムにもうちょっと詳しくなる
- RSpec よく分からない
- Dockerよく分からない
- [Ruby on Rails ガイド](https://railsguides.jp/) を読んでみる
Realm を使っている Android アプリの差分ビルド時間の改善

# TL;DR
* Realm プラグインの実行時間を改善
* Realm のモデル定義をライブラリモジュールに切り出して、`apply plugin: 'realm-android'` を設定
* app モジュールの `apply plugin: 'realm-android'` を外す
*  ***差分ビルドにかかる時間を 50% 程度削減できた***

# 前提
* Realm (0.88 以降)を使っている Android アプリ
* app モジュールに `apply plugin: 'realm-android'` している
* ビルド時間を改善したい

# 背景
* 仕事で関わっている Android アプリの差分ビルドがとにかく遅い
* Activiy の Java ファイルを1行変更しただけでも、3分程度掛かっている
    * うち、 `:app:transformClassesWithRealmTransformerForXX` が 50% 程度を占めている!
    * ↓ `./gradlew assembleXX --profile` の結果
     ![BeforeProfile.png](https://qiita-image-store.s3.amazonaws.com/0/9695/b3fae8ce-d1ab-7759-6f64-ea5197cb6d5a.png)

* 計測環境
    * Android Studio 3.0 Beta 4
    * Gradle Plugin 3.0.0-beta4
    * Realm 3.3.1
    * MacBook Pro (15-inch, 2016)
        * プロセッサ　2.9 GHz Intel Core i7
        * メモリ　16 GB 2133 MHz LPDDR3

# Realm プラグインは何をしている？
* [JavaでBytecode Weaving by zaki50](https://speakerdeck.com/zaki50/javadebytecode-weaving) 参照
* Realm を使うためのバイトコード書き換え
    * モジュール内の RealmObject のフィールドアクセスを関数呼び出しに置き換えている
    * ***RealmObject クラス内だけじゃなく、モジュール内全てのコードが対象***
        * setter / getter 経由でなく、直接 public フィールドにアクセスできるようになったため。（そりゃ時間が掛かる…）
    *  例）
    *  <img width="697" alt="スクリーンショット 2017-09-09 16.48.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/9695/24f7baa6-30db-7598-3d4d-09c3577fe3e4.png">
    *  ↑https://speakerdeck.com/zaki50/javadebytecode-weaving?slide=27 より

# ビルド時間の改善のために、モジュールを分割
* Realm のモデル定義をライブラリモジュールに切り出す
    * 目的：Realm のバイトコード書き換えを行う対象を RealmObject クラス（のあるモジュール）のみに絞る
    * （app モジュールとの依存性排除が若干大変だった…）
    * ライブラリモジュールに `apply plugin: 'realm-android'` を設定
* ***app モジュールの `apply plugin: 'realm-android'` を外す***
* [https://github.com/tatsuhama/RealmModelLib/](https://github.com/tatsuhama/RealmModelLib/) にモジュール分割の手順を行ったサンプルコードを置いています。

# 注意事項
* app モジュールに Realm のバイトコード書き換えが行われない事になるので、***app モジュールからは RealmObject のフィールドに直接アクセスしてはいけない！***
* ***→ RealmObject の定義を Kotlin にすれば安心***
* （public な var でも setter / getter 経由でのアクセスになるため）

# 効果測定
* Realm プラグインの実行時間がごっそりなくなり、 ***差分ビルド時間が 50% 以上改善！***
* （5回の平均が、 `3:26` → `1:24`）
![AfterProfile.png](https://qiita-image-store.s3.amazonaws.com/0/9695/494d0d9c-1264-275d-ffba-0b57b76ef838.png)
* 各回の計測値も載せておきます（青：分割前、オレンジ：分割後）
* <img width="838" alt="スクリーンショット 2017-09-09 21.44.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/9695/96f0018b-9470-1f0a-a316-04657d86e9c1.png">

* モジュールを分けたことによって、並列でビルドされてますね！
<img width="305" alt="スクリーンショット 2017-09-09 17.41.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/9695/6a003ad0-df3c-afca-31e5-12cc4e9c056f.png">

# 感想
* ***ビルド時間の大幅改善ができて、開発作業が快適に！***
* RealmObject と app モジュールの依存性を排除する良い機会になった
    * JsonNode から RealmObject を生成する関数（JSONライブラリに依存）
    * Date フィールドを表示用文字列に変換するために Context や string リソースを使っている関数
* まだ検証だけでプロダクトのテストまでは通していないので、見えていない問題があるかも…？
GoogleAppsScriptのトリガや承認周りの仕様メモ

# 対象
Google Apps Scriptでスプレッドシート、フォーム送信等の参照を行っていたり、メール機能を利用している場合
## サンプル
```
// メール
MailApp.sendEmail(...)

// フォーム
function onFormSubmit(e) {
    ...
}

// スプレッドシート
sheet = SpreadsheetApp.getActiveSpreadsheet();
```

# Google Apps Scriptのざっくばらんな仕様
- スクリプト内でスプレッドシートの参照やメールの送信などをGoogle Apps経由で行おうとする場合に必ず承認が求められる
- スクリプトそのものにオーナーという概念は存在せず、帰属するスプレッドシートやフォームの編集権限があれば誰でも閲覧、編集可
- トリガーは設定したアカウントでしか閲覧、編集ができない
- トリガー実行時の承認情報はトリガーを設定したアカウントの承認情報が用いられる

# 問題点
- トリガー設定したアカウントが消えた時に承認情報がなくなりトリガー実行が（たぶん）失敗する
- トリガー失敗時のエラー通知も基本的にそのアカウントのメールへ届くため誰もそのスクリプトが死んだことに気付けない（と思う）

# 移行手順
1. 別のアカウントにてスクリプトエディタを開き、該当のスクリプトが書かれている関数を実行する
1. その際に「承認する？」ってダイアログがでるので承認して該当機能を実行できる状態にする
1. 日時指定でトリガー設定を行い正常にトリガが実行されることを確認する
1. 元のトリガ設定に戻す

# 分からんところ
特にトリガー設定や承認を解除しなかったままアカウントが消えた時の挙動
Macのクリップボードに見知らぬ文章がコピーされていた((((；ﾟДﾟ))))

# ハッキング？！
と思ったら隣のMacでコピーされた文章であることが判明。

#オチ
macOS Sierraで追加された[ユニバーサルクリップボード](https://applech2.com/archives/20160626-how-to-work-universal-clipboard.html)という「別のMacとクリップボードの内容を共有する」機能が原因であることが判明。
画面共有やリモートしている時ならまだしも、普通に作業しているだけでクリップボードが共有されていたので驚いた。

- 別々のMacで同じiCloudアカウントを使いまわしている
- 今更Sierraにアップデートした

などの条件が重なると発生する模様。

#解決策
設定画面的なものが見当たらなかった＆他の共有機能が有効になってるかもしれなくて気持ち悪かった
ので、iCloudをサインアウトし、別のアカウントを作り直した。
Elasticsearch 5.6 をとりあえず動かしてみた



DL：https://www.elastic.co/jp/downloads/elasticsearch )
　Version:5.6.0
　Release date:September 11, 2017

3台クラスタが動くまで。

---

## ■Elaticsearch

ドキュメント ( 
https://www.elastic.co/guide/en/elasticsearch/reference/5.6/release-notes-5.6.0.html )

---
### OS設定 (CentOS6系)
/etc/security/limits.d/90-nproc.conf

    #*          soft    nproc     1024
    root       soft    nproc     unlimited

### Java 1.8.0_131以降 インストール
    # yum install java-1.8.0-openjdk.x86_64
    # java -version
    openjdk version "1.8.0_141"
    OpenJDK Runtime Environment (build 1.8.0_141-b16)
    OpenJDK 64-Bit Server VM (build 25.141-b16, mixed mode)

---

### Elasticsearch インストール
    # rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
    # cat << EOF > /etc/yum.repo.d/elasaticsearch5.repo
    [elasticsearch-5.x]
    name=Elasticsearch repository for 5.x packages
    baseurl=https://artifacts.elastic.co/packages/5.x/yum
    gpgcheck=1
    gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
    enabled=1
    autorefresh=1
    type=rpm-md
    EOF
    
    # yum install elasticsearch-5.6.0
    # chkconfig --add elasticsearch
    # mkdir -p /tomi/elasticsearch/{data,logs}
    # chown -R elasticsearch. /tomi/elasticsearch
---

#### ※rpm (yum) で入れたElasticsearchのdefaultディレクトリ構成
https://www.elastic.co/guide/en/elasticsearch/reference/5.6/rpm.html#rpm-layout

---
    
### Elasticsearch 設定

環境変数：/etc/sysconfig/elasticsearch
設定ファイル：/etc/elasticsearch/elasticsearch.yml

#### ※defautから変更したところ
elasticsearch.yml

    cluster.name: tomi-test-elastic
    node.name: ${HOSTNAME}
    path.data: /tomi/elasticsearch/data
    path.logs: /tomi/elasticsearch/logs
    bootstrap.system_call_filter: false
    bootstrap.seccomp: false
    network.host: 0.0.0.0
    http.port: 9200
    discovery.zen.ping.unicast.hosts: ["tomi-test-elastic01.hoge-internal.jp", "tomi-test-elastic02.hoge-internal.jp", "tomi-test-elastic03.hoge-internal.jp"]
    discovery.zen.minimum_master_nodes: 2
    
---

### Elasticsearch起動
    # service elasticsearch start

---

### クラスタの状態確認
    # curl -X GET http://localhost:9200/_cat/health?v
    epoch      timestamp cluster           status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
    1505374173 16:29:33  tomi-test-elastic green           3         3      0   0    0    0        0             0                  -                100.0%
※cat, clusetr など各種APIが提供されている。ドキュメント参照。

---

### 便利プラグイン例 elasticsearch-head

https://github.com/mobz/elasticsearch-head#running-with-built-in-server

    mkdir /usr/lcoal/src
    git clone https://github.com/mobz/elasticsearch-head.git
    cd elasticsearch-head
    npm install
    npm run start

    http://tomi-test-elastic01.hoge-internal.jp:9100/

※クラスタ情報が表示されない場合はElasticsearch URLをlocalhostではなくIPアドレス指定にしてみる？