OmniAICreator/Qiita-1.07M huggingface dataset:
Amazon Linux 2を見る

# Amazon Linux 2
```shell-session

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
```

Amazon Linux 2が発表されました。
https://aws.amazon.com/jp/about-aws/whats-new/2017/12/introducing-amazon-linux-2/

# ec2-metadata
```shell-session
[root@ip-10-5-32-70 ~]# ec2-metadata
ami-id: ami-2a34b64c
ami-launch-index: 0
ami-manifest-path: (unknown)
ancestor-ami-ids: not available
block-device-mapping:
         ami: /dev/xvda
         root: /dev/xvda
instance-id: i-071c4a39e70ae745b
instance-type: t2.nano
local-hostname: ip-10-5-32-70.ap-northeast-1.compute.internal
local-ipv4: 10.5.32.70
kernel-id: not available
placement: ap-northeast-1a
product-codes: not available
public-hostname: ec2-13-112-183-81.ap-northeast-1.compute.amazonaws.com
public-ipv4: 13.112.183.81
public-keys:
keyname:galaxy
index:0
format:openssh-key
key:(begins from next line)
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCehg0RkIeCPg94jpFM7hqQXYWD8BdVyewE3836SnSA2lKsiHKmo+dhzZg8u70eDaevOXvQNrumXdJUWN76gemO9JB1IfjNjECZqRXOFc3yHheQMWbimcLAT3W39/MjXja2Amjy539qjfJ5blknQUPi3InnGae0TDutXQN1UX6oU3y5JBZOoi1kQi8Jth34LpoS5qXs/+i7DFlhNA7YXNzAqTnksbXPA6G7Ww0+xFLLTaXUfbhQydM3rkCU7ABGEUlodhU6BKFMmDltXEC9Q7nCghETZdFgF3lVTOOM3Tsb+e890+OcW7Nf3CGR57LABX+FwxvW2jGNarhWP9oR/8T1 galaxy
ramdisk-id: not available
reservation-id: r-0f55ec655c1e51a0b
security-groups: lithium-prod-web
user-data: not available
```

> ami-id: ami-2a34b64c

# uname
```shell-session
[root@ip-10-5-32-70 ~]# uname -a
Linux ip-10-5-32-70.ap-northeast-1.compute.internal 4.9.62-10.57.amzn2.x86_64 #1 SMP Wed Dec 6 00:07:49 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
```

> amzn2

# systemd support
```shell-session
[root@ip-10-5-32-70 ~]# ps u -p 1
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.8  1.0 125280  5256 ?        Ss   04:28   0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 21
```

# Python
記事にはこう書いてあります。

> Additional software packages, including the newer versions of popular software packages such as Python, MariaDB, Node.js, are available for installation using the Amazon Linux Extras repository.

さぞ新しいバージョンが入っていることでしょう。

> the newer versions



```shell-session
[root@ip-10-5-32-70 ~]# python --version
Python 2.7.5
```

これだから…
[MDC]TabBarのindicatorの高さを変更する

[Material Design Components for iOS](https://github.com/material-components/material-components-ios) の[MDCTabBar](https://github.com/material-components/material-components-ios/tree/develop/components/Tabs)を使っていたのですが、タブ下のインジケータがデフォルトで2ptというとても細い線しか描画できず困っていました。
が、[40.1.0](https://github.com/material-components/material-components-ios/releases/tag/v40.1.0)より自由に変更できるようになっていました。

```swift:使い方
let tabBar = MDCTabBar()
tabBar.items = ....
tabBar.selectionIndicatorTemplate = MDCTabBarUnderlineIndicatorTemplate()
```

アンダーラインは[MDCTabBarUnderlineIndicatorTemplate](https://github.com/material-components/material-components-ios/blob/develop/components/Tabs/src/MDCTabBarUnderlineIndicatorTemplate.m)としてデフォルトで用意してありますが、高さが2.0fと固定されているため、高さを変更する場合は独自で用意する必要があります。

```swift:TabIndicator.swift
import Foundation
import MaterialComponents

class TabIndicator: NSObject, MDCTabBarIndicatorTemplate {
    /// タブインジケーター高さ
    private let underlineHeight: CGFloat = 4.0
    func indicatorAttributes(for context: MDCTabBarIndicatorContext) -> MDCTabBarIndicatorAttributes {
        let bounds = context.bounds
        let attributes = MDCTabBarIndicatorAttributes()
        let underlineFrame = CGRect(x: bounds.minX,
                                    y: bounds.maxY - underlineHeight,
                                    width: bounds.width,
                                    height: underlineHeight)
        attributes.path = UIBezierPath(rect: underlineFrame)
        return attributes
    }
}
```
MDCTabBarIndicatorTemplateを継承し、indicatorAttributesを実装してその中で自由にインジケータを描画してあげればOKです。

ただし、注意点としてtabのitemsをsetした後に設定しないと反映されません。
（上の例だと、boundsがzeroになってしまいます）
そのため、私は下記のようにカスタムクラスを用意しています。

```swift:TabBar.swift
import MaterialComponents

class TabBar: MDCTabBar {
    override var items: [UITabBarItem] {
        get {
            return super.items
        }
        set {
            super.items = newValue
            /// itemsがセットされた後でないと反映されません
            selectionIndicatorTemplate = TabIndicator()
        }
    }
}
```

また、underlineだけではなく、色々なインジケータを表現できます。
下記はサンプルから拝借しました。

```swift:SampleIndicatorTemplate.swift
class IndicatorTemplate: NSObject, MDCTabBarIndicatorTemplate {
    func indicatorAttributes(for context: MDCTabBarIndicatorContext) -> MDCTabBarIndicatorAttributes {
      let attributes = MDCTabBarIndicatorAttributes()
      // Outset frame, round corners, and stroke.
      let indicatorFrame = context.contentFrame.insetBy(dx: -8, dy: -4)
      let path = UIBezierPath(roundedRect: indicatorFrame, cornerRadius: 4)
      attributes.path = path.stroked(withWidth: 2)
      return attributes
    }
}

extension UIBezierPath {
  /// Returns a copy of the path, stroked with the given line width.
  func stroked(withWidth width: CGFloat) -> UIBezierPath {
    let strokedPath = cgPath.copy(
      strokingWithWidth: width,
      lineCap: .butt,
      lineJoin: .miter,
      miterLimit: 0)
    return UIBezierPath(cgPath: strokedPath)
  }
}
```
上記例だと下記のようになります。
![sample.png](https://qiita-image-store.s3.amazonaws.com/0/202533/f36a15f8-1a10-8997-30f9-9bfc6cbd3b57.png)

アンダーラインの高さを変えたいだけなのに手間がかかってしまいますが、自由度は高いので色々面白いこともできそうです。
色々よしなにやってくれるコマンド達



# はじめに
<img src="https://i.gyazo.com/e4eb05baf0442a0519d0d0a56c1cffd5.jpg" alt="1" width=50% />

すでにエンジニアでやっている人は当然一回は聞いたことありますよね。
エンジニアにとってterminalはほぼ間違いなく毎日触る箇所であり、プログラミングをやらずとも、使う箇所なので、
今回紹介するコマンドと<a href="https://qiita.com/yogoken/items/cb28b8cac6672a4c158c” target="_blank">ここら辺のアプリ</a>を駆使して、是非快適なパソコンライフを過ごしてください。

## 個人的な便利さと利用動機

```bash
peco                | file/リポジトリ、どこでも一瞬したい
ghq                 | githubのリポジトリ一元管理勝手にしてほしい 
hub                 | githubさっと開きたい
ag                  | クラス継承とか影響範囲を知りたい
------- ちょっとした壁 -------------------------------------------
mycli               | mysqlで打ち間違えない
exa                 | catに色つけたい    
atom                | atomさっと開く     
tldr                | コマンドあったか確認したい 
glances             | ちょっとしたリソースが見たい      
zsh-autosuggestions | 打ち間違いしなくなる                       
```

# コマンド一覧

| コマンド名 | 動作イメージ | rep の URL |
|:-------|:----------|:------------|
| peco     |<img src="https://i.gyazo.com/b228acb2bf418240f4acfc3e4a18a090.png" width=70%/>|https://github.com/peco/peco                        | 
| ghq      |<img src="https://i.gyazo.com/7ba90dcac66e2877de15a1961c908e93.png" width=70%/>|https://github.com/motemen/ghq                      |
| hub      |<img src="https://i.gyazo.com/1e87398417b5e802cdce5e73db18603f.png" width=70%/>|https://github.com/github/hub                       |
| ag       |<img src="https://i.gyazo.com/096d418ed67215813ca14995e28b2ed1.png" width=70%/>|https://github.com/ggreer/the_silver_searcher       |
| mycli    |<img src="https://i.gyazo.com/a423d06a26ade41570e87c7f75928514.gif" width=70%/>|https://github.com/dbcli/mycli                      |
| exa      |<img src="https://i.gyazo.com/0583522753d2fef012bd1ed2aa489276.png" width=70%/>|https://nodejs.org/en/                              |
| atom     |<img src="https://i.gyazo.com/575b6c0b1b5e2ca61f2ce81bb2dae61b.png" width=70%/>|https://qiita.com/kon_yu/items/56cc87be47022a31dda1 | 
| tldr     |<img src="https://i.gyazo.com/9d3672b3105097d329dd65c7aee770e1.png" width=70%/>|https://github.com/tldr-pages/tldr                  |
| glances  |<img src="https://i.gyazo.com/a0282981a05f24ed11697b074f4c4625.png" width=70%/>|https://github.com/nicolargo/glances                |
| zsh-autosuggestions |<img src="https://i.gyazo.com/6a238c7da8c7de8529666cb117665aaa.png" width=70%/>|https://github.com/zsh-users/zsh-autosuggestions    |


### 今後
dotfilesか何かで公開したら下にリンク載せますが、多分問題なく導入できます。
[visual studio] devenv.exe.configの場所 

visual studio でproxy設定をするとき編集するファイル(devenv.exe.config)の場所は

```
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\devenv.exe.config
```

です。(2017は2019かもしれません。CommunityはEnterpriseかもしれません。)




以下には無いです。

```
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE
```

参考: http://cream-worker.blog.jp/archives/1028025704.html


認証proxyの場合は上記は修正せずに、以下のツールでproxyを爆破したほうがいいです。
http://ipponshimeji.cocolog-nifty.com/blog/2017/01/post-0ce6.html
(github https://github.com/ipponshimeji/MAPE/blob/master/Documentation/ja/Index.md)
このツールは実行中のみwindowsのproxy設定を書き換えるので、前述の設定ファイルの修正はいらないのです。
競プロに出てくるPython便利Tipsメモ

# collections.defaultdict
https://docs.python.jp/3.3/library/collections.html#collections.defaultdict

key の初期化を意識せずに済みます。


```py3
from collections import defaultdict
d = defaultdict(int)
for k in "toshino":
    d[k] += 1
print(d.items())
# [('t', 1), ('o', 2), ('s', 1), ('h', 1), ('i', 1), ('n', 1)]
```

この辺を省略できてます。

```diff
for k in "toshino":
-    if k not in d:
-        d[k] = 0
     d[k] += 1
```  


# operator.itemgetter
https://docs.python.jp/3/library/operator.html#operator.itemgetter

面倒な lambda を書かずにすみます。

```py3

from operator import itemgetter

itemgetter(1, 3, 5)('ABCDEFG')
# ('B', 'D', 'F')

a = [["third", 3], ["first", 1], ["second", 2]]
a.sort(key=itemgetter(1))
a
# [['first', 1], ['second', 2], ['third', 3]]
```

```diff
- a.sort(key=lambda x: x[1])
+ a.sort(key=itemgetter(1))
```


# inf
```py3
import math

inf = float('inf')

inf > 10000000000000000000000000000000000000000000000
# True

math.isinf(inf)
# True
math.isinf(11111111111)
# False
```

# 初期化, input 受け取り

```py3
n, m, s = map(int, input().split())
data = [list(map(int, input().split())) for _ in range(n)]
d = [inf] * size
```

追加していきます。
xargsで受け取った複数のファイル名をvimで開く(BSD系以外の場合)

## TL;DR
シェルでfind、grep等をパイプしてxargsで受け取ってvimで開くには、
`find . -type f -name hoge | xargs sh -c 'vim $* < /dev/tty'`
とすれば良い。
これを毎回書くのは面倒なので、
`alias xargsvim='xargs sh -c '\''vim $* < /dev/tty'\'''`
とエイリアスを作っておくと
`find . -type f -name hoge | xargsvim`
と書けて便利。

## 背景
上記以外に言うべきことはほとんど無いのですが、背景を少し。
同じことを実現するために、素直に
`find . -type f -name hoge | xargs vim`
とすると、「Vim: Warning: Input is not from a terminal」という警告が出る上に、以降、ターミナルへの入力がおかしくなります。

仕方ないので
``vim `find . -type f -name hoge` ``
とやっていたのですが、この方法だと途中でパスの補完が効かなかったり不便です。

そんな折に、こちらの記事を見つけました。
[ファイル名をパイプで出力してvimで開く方法](https://qiita.com/suhirotaka/items/27cb38f88b0dc5f7c4f3)
(`xargs vim`でターミナルがおかしくなる理由も書いてありますので、興味のある人はぜひ読んでみてください)

`find . -type f -name hoge | xargs -o vim`
と、`-o`オプションを付けるだけでOKとのこと。
「おー、こういうのが欲しかったんだよ」思ったのですが、これはBSD系固有のオプションのようです。
https://linuxjm.osdn.jp/html/GNU_findutils/man1/xargs.1.html

という訳で、素直に環境に依存しない形式で、`-o`オプション相当のことを実現するエイリアスを作ればいい、という結論になりました。
UIViewPropertyAnimatorのカスタムイージング(模索中)

この記事はQuadアドベントカレンダー14日目の記事です。

iOS10からUIViewPropertyAnimatorという機能が追加されたようですが、カスタム方法がよくわかりませんでした。
最終手段は自作すれば良いのですが、簡単に利用できるならそちらを利用したいところです。

## 達成したかったこと
イージングパターンを簡単に切り替えれるようにしたい。Cubic, Expo, Quadなどのeasingの数式を適用して実装したかった。

## 結果
力技で対応しました。(詳しい人いたら教えてください。。。)

## デフォルトのまま利用
利用方法はQiitaにもたくさんあるのでそちらでご確認ください。だいたい以下のような形になると思います。

```swift
let timing = UICubicTimingParameters(animationCurve: .easeOut)
let animation = UIViewPropertyAnimator(duration: 1.0, timingParameters: timing)
animation.addAnimations { [unowned ball] in
    ball.frame.origin.x = 360
}
animation.startAnimation()
```
## timingParamersをカスタムすることで利用できるのでは？
UITimingCurveProviderプロトコルを実装したインスタンスを渡すようですが、プロトコルの定義を確認すると...

```swift
@available(iOS 10.0, *)
public var timingCurveType: UITimingCurveType { get }

@available(iOS 10.0, *)
public var cubicTimingParameters: UICubicTimingParameters? { get }

@available(iOS 10.0, *)
public var springTimingParameters: UISpringTimingParameters? { get }
```

こちら実装する必要がありそう。そしてCubic縛りのようですね。なるほど「UICubicTimingPrameters」を用意するのですね...
controlPoint1、controlPoint2を設定するしか「UIViewPropertyAnimator」を利用する方法はないのか？！

## ControlPointの数値を設定したクラスを作る

最終的には以下のようなstructを作りやりくりしています。

```swift
struct EasingBuilder {
    
    var easeOutQuad: UICubicTimingParameters {
        let point1 = CGPoint(x: 0.16, y: 0.39)
        let point2 = CGPoint(x: 0.06, y: 0.97)
        let timing = UICustomTimingPrameters(controlPoint1: point1, controlPoint2: point2)
        return timing
    }
}
```

イージングは、[こちらのページでちまちま作ってます。](http://cubic-bezier.com/#.17,.67,.83,.67)
【R】要素数の異なるリストを行列に変換する方法

要素数がすべて同じリストオブジェクトであれば、関数do.callを用いれば行列に変換することができます（リストオブジェクトをLISTとします）。

>do.call(rbind,LIST)

しかし、リストの要素数が異なる場合、これができません。その場合、リストの要素数をそろえる必要があります。例えば、

>lapply(LIST, function(x){c(x,rep(NA, max(sapply(LIST,length)) - length(x)))})

のように、リスト内の要素数の最大値をとってきて、それに合わせるようにNAを補完し、要素数をそろえます。
これで、関数do.callを使用し、行列に変換できます。
CentOS7のminimalインストール後にとりあえずやったこと雑記

勉強用にCentOS7をminimalインストールした後に、
とりあえずやってたことを雑に記述していきます。

#更新
```bash
$ sudo yum update -y
```

#リポジトリ追加
```bash
$ sudo yum install -y epel-release
```
デフォルトだとないものが多い・・。

#viの強化
```bash
$ yum list | grep vim
$ sudo yum install -y vim-enhanced
```
とりあえずvimチュートリアル

```bash
$ vimtutor ja
```
vimの方が便利で高機能。

#vimの設定(~/.vimrc)
基本プラグイン使ってないです。そろそろ使って見ようかなぁ。

```vim
"キーマップ設定----------------------------------------------------------------------
" Escの2回押しでハイライト消去
nnoremap <ESC><ESC> :nohlsearch<CR><ESC>
" 日付入力
inoremap <F2> a<C-R>=strftime("%Y/%m/%d (%a)")<CR>
inoremap <F3> a<C-R>=strftime("%H:%M:%S")<CR>

"インデント設定 ---------------------------------------------------------------
" 新しい行のインデントを現在行と同じにする
"set autoindent
" 新しい行を作ったときに高度な自動インデントを行う
"set smartindent

"タブ設定 ---------------------------------------------------------------------
" タブの代わりに空白文字を挿入する
set expandtab
" ファイル内の <Tab> が対応する空白の数
set tabstop=4
" シフト移動幅
set shiftwidth=4
"キーボードでのタブ文字数
set softtabstop=4 
" 行頭の余白内で Tab を打ち込むと、'shiftwidth' の数だけインデントする。
set smarttab

"行設定 -----------------------------------------------------------------------
"行を折り返さない
set nowrap
"set guioptions+=b
" 行数を表示
set number
" 閉じ括弧が入力されたとき、対応する括弧を表示する
set showmatch

"検索設定 ---------------------------------------------------------------------
" インクリメンタルサーチを行う
set incsearch
"検索結果をハイライトする
set hlsearch
"検索時に文字の大小を区別しない
set ignorecase
" 検索時に大文字を含んでいたら大/小を区別
set smartcase
" 検索をファイルの先頭へループしない
"set nowrapscan
"検索をファイルの先頭へループする
set wrapscan

"その他 -----------------------------------------------------------------------
" タブ文字、行末など不可視文字を表示する
set list
set listchars=tab:^\ 

" カーソル行をハイライト
set cursorline
" アンダーラインを引く(color terminal)
highlight CursorLine cterm=underline ctermfg=NONE ctermbg=NONE
" カーソル列にハイライト
"set cursorcolumn
" アンダーラインを引く(color terminal)
"highlight Cursorcolumn cterm=bold ctermfg=NONE ctermbg=NONE

" n行目に色を付ける
set colorcolumn=100

" ステータス行の表示情報の指定 後で見直す・・・。
"set statusline=%<%f\ %m%r%h%w%{'['.(&fenc!=''?&fenc:&enc).']['.&ff.']'}%=%l,%c%V%8P
```
昔から使ってる設定なので設定方法とコメントがあってるか微妙・・。
というか「後で見直す・・・。」ってあるんですけど(；ﾟДﾟ)

#manの強化
```bash
$ yum list | grep man-page
$ sudo yum install -y man-pages.noarch man-pages-ja.noarch
```
マニュアルページ追加、日本語化

#lsの強化
```bash
$ yum list | grep '^sl'
$ sudo yum install -y sl
```
正直全く役に立たないけれど、こういうのも入れると楽しい。

#管理系インストール
```bash
sudo yum install -y git sysstat psmisc iptraf-ng htop lsof iotop
```
minimalだといろいろ入ってない。
(覚えているものを列挙)

#文字コード変換用
```bash
sudo yum install -y nkf
```
iconvよりこっちが便利な気がする。

#ファイルダウンロード系インストール
```bash
sudo yum install -y wget aria2
```
aria2は複数サーバーから分割ダウンロードも可能なコマンド。めっちゃ早いっぽい。

参考：https://aria2.github.io/index-ja.html

#history設定変更
お好きな設定ファイルに以下の設定追加

```bash
HISTSIZE=50000
HISTTIMEFORMAT='%Y/%m/%d %H:%M:%S '
export HISTCONTROL=ignoredups
```
設定ファイル例
・/etc/profile
・~/.bash_profile
・~/.bashrc
など

自分は全ユーザに適用したかったので/etc/profileに追加してみました。

#ちなみに
環境構築はVagrantを使用しているため
sudoの設定等は除外しています。

思いついたら追加していきます。

# 追記
思いついたので追記。

```bash
$ sudo yum install -y tree
$ sudo yum install -y bind-utils
```

bind-utilsにdigコマンドが含まれている。
developブランチの内容を複数のfeatureブランチにマージするスクリプト

developブランチにDB関連や設定ファイルをコミットしたときなど、すべてのfeatureブランチにdevelopブランチの内容を取り込みたいときがあるとおもいます。

そんなときに使えるスクリプトを作りましたので公開します。

## 機能概要
- ファイルで指定した複数のブランチ、引数で指定したブランチをマージする。
- マージ前にリモートリポジトリから最新をpullする。
- 競合が発生した場合など、マージに失敗した場合はマージ前の状態に戻す。

## スクリプト
### 動作確認環境
Windows10 + Git for Windows + Git Bash

### スクリプト本体
```ruby:auto_merge.sh
#!/bin/bash

# ./auto_merge.sh ./ develop ./branch_list.txt

if [ $# -ne 3 ]
then
  echo "usage : ${0##*/} <repository_path> <merge_commit> <target_branch_list_path>"
  exit 1
else
  REPO=$1
  SHA=$2
  LIST=$3
fi

cd ${REPO}

# 対象ブランチファイル読み込み
while read BRANCH
do
  echo "
  ${BRANCH}"

  git checkout ${BRANCH}
  if [ $? -ne 0 ]
  then
    # 対象ブランチなし
    echo "fail to checkout"
    continue
  fi
  
  git pull
  git merge ${SHA}
  if [ $? -ne 0 ]
  then
    # マージ失敗 元に戻す
    echo "${BRANCH} is fail"
    git merge --abort
  fi
done < ${LIST}
```

### マージ先ブランチリスト
```ruby:branch_list.txt
feature/func1
feature/func2
```
1行につき1ブランチ記述する
改行は``LF``

## 実行方法
```
> auto_merge.sh <repository_path> <merge_commit> <target_branch_list_path>
# <repository_path>:リポジトリのパス
# <merge_commit>:マージ元(branch or commit)
# <target_branch_list_path>:マージ先ブランチリストのパス
```

### 実行例
#### 実行前状態
![実行前状態](https://qiita-image-store.s3.amazonaws.com/0/192172/6c8963c0-3851-2a43-67fb-96e759c902c8.png)

#### 実行

```
$ ./auto_merge.sh . develop branch_list.txt

  feature/func1
Already on 'feature/func1'
fatal: No remote repository specified.  Please, specify either a URL or a
remote name from which new revisions should be fetched.
Merge made by the 'recursive' strategy.
 .gitignore | 1 -
 1 file changed, 1 deletion(-)

  feature/func2
Switched to branch 'feature/func2'
fatal: No remote repository specified.  Please, specify either a URL or a
remote name from which new revisions should be fetched.
Merge made by the 'recursive' strategy.
 .gitignore | 1 -
 1 file changed, 1 deletion(-)
```
リモートリポジトリがない場合はgitのエラーメッセージが出ますがそのままマージします。

#### 実行後状態
![実行後状態](https://qiita-image-store.s3.amazonaws.com/0/192172/9038ee34-4511-be65-7f17-e119f4226d2f.png)
GoogleオプティマイズはGoogleタグマネージャー配信では正しく計測できない


オールアバウトアドベントカレンダー14日目になります。
街ではクリスマスの曲が流れていますね。今年もあと半月、大切に過ごしたいです。
#はじめに
オールアバウトでは、今年の4月からGA360を本格導入いたしました。
現行システムでも、社内集計でアクセスデータを蓄積してきましたが、より多くの社員にデータを活用しやすい環境を整えたいと思い、社内向けのGoogleアナリティクス(GA)の勉強会や個別相談会を定期的に開催し、現在では編集部、営業部はもちろん、広報、人事の各部署でGAのデータを活用する動きが生まれてきています。
そこで、導入から約1年GA360に携わってきていろんなトピックスがありますが、今回は最近悩まされたことをここに記載します。

題して、**「GoogleオプティマイズはGoogleタグマネージャー(GTM)配信では正しく計測できない」**
時系列で記載するので、結論が知りたい方は最後までスクロールしてください。

#設定その1
GTMにて、オプティマイズ用のタグを作成し、発火条件はAll Pageに設定
![1.png](https://qiita-image-store.s3.amazonaws.com/0/57723/255db5bf-ef20-8a57-b8dd-7dc006b78017.png)
#検証結果その1
オプティマイズのターゲット設定の対象を100％としたので、該当ページのGAセッション数とウェブテストセッション数が同数ぐらいを想定していましたが、GAセッション数の3分の1しかウェブテストセッション数が取得できませんでした。。。
#設定その2
次にGTMのオプティマイズタグの発火条件をページビュータグ内で設定するに変更
[詳しくは公式ページ　⇒　ステップ 2: タグマネージャでオプティマイズ タグを設定する](https://support.google.com/360suite/optimize/answer/6314801#recommended)
![2.png](https://qiita-image-store.s3.amazonaws.com/0/57723/3f060426-6d38-a132-b961-e09d97a096c5.png)
![3.png](https://qiita-image-store.s3.amazonaws.com/0/57723/5a505c3c-d7f5-2925-279b-ebc9d5e1392e.png)

#検証結果その2
GAセッション数とウェブテストセッション数の乖離はなくなりました。
しかし、
オプティマイズタグが発火してからGAページビュータグの発火。。。
危険な香りはしていましが、ページビュー数が0.5％～5％減ってしまいました。
対象ページにより差はありますが、ページビュー数が減ってしまうのは致命的です。
#設定その3（これぞ、ベストプラクティス）
GA360の技術担当の方に問い合わせたところ、オプティマイズの発火はGTM経由ではなく、直接コードを書いてくださいとの回答をいただきました。
GTMに統一することにより開発者のリソースを使わないでタグの配信が可能になっていたが、また逆戻り、何とかなりませんかと懇願してみましたが、直近では改善される予定はないとのお話でした。
[詳しくは公式ページ　⇒](https://support.google.com/360suite/optimize/answer/6262084?hl=ja)
![4.png](https://qiita-image-store.s3.amazonaws.com/0/57723/762649c2-a886-8d51-4888-2e6f63f3e857.png)
**GTM-XXXXXX**はオプティマイズのコンテナID
**UA-XXXXXXXX-X**には連携されているGAのプロパティIDを入力

でも、このコードにも気になる箇所が。。。
GA360の道のりはまだまだ続く。
最後まで読んでいただきありがとうございます。
IOSシミュレーターのアニメーションが劇遅になる時の対処

## 原因
* IOSシミュレーターのShow AnimataionsがONになっていることが原因...
* これに気づくのが遅れてPC再起動したりしまくっていた

## 対処法
* IOSシミュレーターの[Debug]>[Slow Animations]をOFFにすればOK

![image.png](https://qiita-image-store.s3.amazonaws.com/0/33823/4422e5b9-0a37-d697-11c1-f3c0a0c9f54a.png)
Ctrl + Q > Visual Studio | PowerPoint | Word

```txt:動作環境
Windows 7 Pro (32bit)
Windows 8.1 Pro (64bit)
など
```

- Visual Studio 2017
    - Window.QuickLaunch
    - https://msdn.microsoft.com/ja-jp/library/da5kh0wa.aspx
- PowerPoint 2013
    - ソフトが終了する
    - [公式](https://support.office.com/ja-jp/article/%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88-%E3%82%AD%E3%83%BC%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%83%97%E3%83%AC%E3%82%BC%E3%83%B3%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B-ebb3d20e-dcd4-444f-a38e-bb5c5ed180f4)には記載なし?
- Word 2013
    - 段落の書式設定解除
    - [公式](https://support.office.com/ja-jp/article/Windows-%E7%89%88-Microsoft-Word-%E3%81%AE%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89-%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88-95ef89dd-7142-4b50-afb2-f762f663ceb2)では記載なし?

[Visual Studio > IDE > ショートカットを忘れたときの確認手順 > Ctrl+Q とキーワード入力](https://qiita.com/7of9/items/7c1187981158f09b5dc4)
と同じ仕組みを様々なソフト使用時に使えればいいと思った。

その場合、１つのショートカット(例:Ctrl + Q)を補足するようにしておくと使いやすいと思うのだが、ソフトを終了するキー割り当てのソフト(PowerPoint)があるのでは使えない。

### 案 > 現在のソフト情報

特定のキー押下時の動作

- フォーカスがあたっているソフトの情報を得る
- そのソフトのショートカットキーを検索できるテキストボックスが表示される
- 検索で探しているショートカットキーを表示する

### 問題点

以下の問題がある。

- 使用OSそれぞれにソフトをセットアップが必要
- データの更新が必要
- 他のソフトのショートカットキー割り当てと衝突する可能性がある

15時間で作れれば実装するが、できないだろう。
pythonでx509証明書のCSRの作成

#はじめに
pythonでx509証明書のパースをしたかったのでその覚書。チュートリアルで最初にCSRを作成したので本ページではそれを纏める。

pythonの標準ライブラリではx509証明書をパース出来ない模様。
そこでadd-on packageのcryptographyをここでは利用する。
https://cryptography.io/

Python 2.7.11で実施。

#cryptographyのインストール
インストールはpipで以下の通り。
```
pip install cryptography
```

#CSRの作成
ソースは以下の通り。

```
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes
from cryptography import x509
from cryptography.x509.oid import NameOID

def gen_rsa_key():
    return rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
        backend=default_backend()
    )

def gen_ec_key():
    return ec.generate_private_key(
        ec.SECP384R1(), default_backend()
    )

def gen_csr(key, c, s, l, o, cn):
    return x509.CertificateSigningRequestBuilder().subject_name(x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, c),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, s),
        x509.NameAttribute(NameOID.LOCALITY_NAME, l),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, o),
        x509.NameAttribute(NameOID.COMMON_NAME, cn),
    ])).sign(key, hashes.SHA256(), default_backend())

def write_key(key, pass_phrase, path):
    with open(path, "wb") as f:
        f.write(key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.BestAvailableEncryption(pass_phrase),
        ))

def write_csr(csr, path):
    with open(path, "wb") as f:
        f.write(csr.public_bytes(serialization.Encoding.PEM))
.
# RSAのkeyを利用したCSR
rsa_key = gen_rsa_key()
rsa_csr = gen_csr(rsa_key, u"JP", u"Tokyo", u"Shibuya", u"Company name", u"example.jp")
write_key(rsa_key, b"password", "/home/hoge/rsa.key")
write_csr(rsa_csr, "/home/hoge/rsa.csr")

# ECのkeyを利用したCSR
ec_key = gen_ec_key()
ec_csr = gen_csr(ec_key, u"JP", u"Tokyo", u"Shibuya", u"Company name", u"example.jp")
write_key(ec_key, b"password", "/home/hoge/ec.key")
write_csr(ec_csr, "/home/hoge/ec.csr")
```

と終わらせるのも何なので、少し解説。
## 1.鍵生成
まず秘密鍵と公開鍵のペアを生成する。

サーバ鍵生成などで用いられるものの主流はRSA 2048bit。ECDH/ECDSA P256, ECDH/ECDSA P384なども使われている。

楕円曲線パラメータはいろいろある。
P256(=SECP256R1), P384(=SECP384R1)あたりが証明書としては多く使われているイメージ。
ちなみにビットコインで利用している暗号形式はSECP256K1。

## 2.CSR生成
ここでは、COUNTRY_NAME, STATE_OR_PROVINCE_NAME, LOCALITY_NAME, 
ORGANIZATION_NAME, COMMON_NAMEを入力。
さらに、先ほど作った公開鍵を秘密鍵とSHA256を使って署名。
サーバ証明書ではこの公開鍵をCAの秘密鍵で署名することになる。

入力する情報としてはORGANIZATIONAL_UNIT_NAME, EMAIL_ADDRESSもよくつかわれる。
Appveyorでgolang/depを使いつつ、各プラットフォーム用のバイナリをビルド

Go言語で書いたソフトウェアで、Linux/Windows, 32bit/64bitのバイナリをAppveyorでビルドしているものがあった

```yaml:BEFORE&nbsp;appveyor.yml
clone_folder: C:\Users\appveyor\md2html
environment:
  GOPATH: C:\gopath
  matrix:
  - GOOS: windows
    GOARCH: 386
  - GOOS: windows
    GOARCH: amd64
  - GOOS: linux
    GOARCH: 386
  - GOOS: linux
    GOARCH: amd64
build_script:
  - go get -u github.com/golang/dep/...
  - set PATH=%PATH%;%GOPATH%\bin
  - dep ensure
  - go build
```
こんな感じで

- HOMEディレクトリ以下にビルド対象のソースをclone
- Linux/Windows, 32bit/64bitのバイナリをAppveyorでビルド

と、していたのだけれど
Go言語のパッケージの依存関係解決ツール`dep`を使おうとしたらなかなか上手く行かなかったのでメモ。

## 回避策

前述のAppveyorの設定だと`dep`を使うにあたり2つ問題があった

- `dep`のインストール時にも`%GOOS%`, `%GOARCH%`の環境変数が反映される  
  - インストール先も`%GOPATH%/bin`じゃなくなるし、GOOS=linuxだとバイナリもELFになったり
- `dep`コマンドは`%GOPATH%`以下で使う必要あり

という事で`appveyor.yml`を次のように修正

```yaml:AFTER&nbsp;appveyor.yml
clone_folder: C:\gopath\src\appveyor\md2html
environment:
  GOPATH: C:\gopath
  matrix:
  - _GOOS: windows
    _GOARCH: 386
  - _GOOS: windows
    _GOARCH: amd64
  - _GOOS: linux
    _GOARCH: 386
  - _GOOS: linux
    _GOARCH: amd64
install:
  - go get -u github.com/golang/dep/...
  - set PATH=%PATH%;%GOPATH%\bin
before_build:
  - set GOOS=%_GOOS%
  - set GOARCH=%_GOARCH%
build_script:
  - dep ensure
  - go build
```

- ソースのclone先を`%GOPATH%`の下にしてしまう
- `%_GOOS%`, `%_GOARCH%`で一旦受けて、build前に`%GOOS%`, `%GOARCH%`に設定する

これで無事`dep`で依存関係を解決しつつ、Appveyorで各プラットフォーム用のバイナリがビルドできました。
テスト設計コンテストに参加してみた

##テスト設計コンテストとは
- 概要
  - テスト設計コンテストとは、NPO法人 ソフトウェアテスト技術振興協会(ASTER)というが主催するイベントです。
  - 参加費は、法人-1チーム 32,400円（税込）/ 個人-1チーム 5,400円（税込）。
  - 参加者は、主催者側から提供された[テストベース](http://aster.or.jp/business/contest/doc/2018-tdc_V2.zip)（あるシステムの要件定義書・用語集・状態遷移図・etc）をベースにテスト設計を行い、コンテスト形式で競います。
       - チームの立場・プロジェクトの状況（第三者検証会社なのか？品質管理部門なのか？など）などは、各自で設定します。
  - まず、北海道・東京・東海/関西の3地域で地域予選が行われ、各地域の優勝チームが決勝戦に進みます。
- スケジュール
  - 2017年07月01日（土）- チュートリアル（東京）
     - テストを設計する上での基礎知識・考え方の解説をしてくださいます。
  - 2017年09月29日（金）- 参加申込締切
  - 2017年10月13日（金）- 成果物提出締切（東京）
     - 審査員はこの成果物を見て、地域予選の発表順などを決定する模様です。
     - 提出した成果物を地域予選までの間に修正することはできません。
  - 2017年10月20日（金）- 地域予選（東京）の発表順・開始終了時間などの通知
  - 2017年10月28日（土）- 地域予選（東京）
     - 各チームが成果物についてのプレゼンを行います。
     - 見学者用に、成果物の印刷物を掲示します。
  - 2018年02月24日（土）- 決勝戦
     - 地域予選の有償チームがプレゼンを行います。
     - 地域予選の成果物を修正することができます。
- 成果物
    1. テスト設計の最終成果物
        - 想定するテスト依頼元への納品物という位置づけのドキュメント
        - 40ページ以内
    2. テスト設計に関わる成果物一式
        - マインドマップやマトリクスなど、上記の成果物をまとめる過程で作成したドキュメント
    3. [アピールシート](http://aster.or.jp/business/contest/doc/appeal_sheet_2018.docx)
    4. プレゼンテーション用資料
    5. 当日フロア掲示用資料
- 詳細
  - [公式サイト](http://aster.or.jp/business/contest.html)

##結果・作業工程
- 結果
    - 地方予選（東京）にて落選。
- 作業工程
    1. 2017年10月05日（成果物提出締切の約1週間前）から作業開始。
        - チームメンバーはそれぞれ日々の業務に追われ、ついつい後回しに・・・。
    2. 目標設定
        - 教科書どおり一連のプロセスを経験してみること。
            - 要求分析 -> テストアーキテクチャ設計 → テスト詳細設計 → テスト仕様書作成
        - 審査員からの客観的な評価を得て、今後の実際の業務での改善に活かすこと。
    3. コンセプト・設定・方針の確定
        - コンセプト
            - 今回の活動を業務に活かせるものにすること。
        - 設定
            - チームの立場
                - 受託開発案件のテスト支援
            - プロジェクトの状況
                - 現在テスト工程
                - 想定以上に不具合が発生し、開発メンバは不具合対応に追われている。
                - テストの進捗に遅延が生じており、顧客から改善策を求められている。
                - ※作業開始から成果物の締切まで正味3人日ほどしか確保できないため、苦肉の策として、設定自体も時間がない前提とした。
        - 方針
            - 短期間でプロダクトの状態を把握するためのテスト設計を行う。
    4. 成果物作成・提出
        - 上記の決定事項に従い成果物を作成し、提出締切の1時間59分前に、22:00になんとか提出！
    5. プレゼン練習
        - 突貫工事で成果物を作成したため、口頭でカバーすべくプレゼンを猛練習。
        - 提出したプレゼン資料を修正できないのがつらいところ。
    6. 地方予選（東京）にてプレゼン
        - なんとか発表を終えるも、審査員からの質問にしっかり答えられずアワアワ・・・。
        - 休憩時間に審査員の方から個別に声をかけられ、不明点を聞きたかっただけでイジメるつもりはなかったと謝罪を受ける始末。
- 審査員評価
    - 予想はしていましたが、以下のような評価を頂きました。
        - 長所
            - 要求分析や観点抽出にマインドマップを用いている点が良かった。
        - 短所
            - 「短期間で品質状況を把握する」という設定だったが、短期間につながるポイントが見えなかった。
            - お手本にあるようなプロセスでテスト設計をしているという点では、完成度の高いプロセスから一定水準の品質が期待できるが、その一方で、独自性・新規性という意味での工夫が見られなかった。

##まとめ
- 通常の業務では、期間などの制約から、お手本通りのプロセスでテスト設計を行う機会がないのですが、今回このような手順を踏むことで、テスト設計の基礎を学ぶことができたと思います。
- 今回は、審査基準の1つである、独自性・新規性については考えず、まずはテスト設計プロセスの基礎を抑えたいという目的があったので、そういう意味では目的は達成できたと思います。
- ただ、何事もそうですが、計画的に進めるべきだと思いました。
- 着手したのが遅すぎたということもありますが、ドキュメントの一貫性を保ちつつ、複数人で役割分担するのは難しいと思いました。
【PlayCanvas】Google Analyticsを組み込んで行動分析

この記事は [PlayCanvas Advent Calendar 2017](https://qiita.com/advent-calendar/2017/playcanvas) の17日目の記事です。
#何
PlayCanvasにGoogle Analyticsを組み込んで行動分析してみます

#用意
Google analyticsで新規プロパティ作成、トラッキングIDを取得します。

#注意
最新のグローバル サイトタグ（gtag.js）を使った方式だと、htmlでのscriptロードが入っているため、PlayCanvasの開発環境では動作しません。
旧式のGoogleAnalyticsObject 'ga'を使った方式をとります

```javascript
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

    ga('create', 'UA-xxxxxxxx-x', 'auto');
    ga('send', 'pageview');
```
※xxx..は自身のトラッキングコードに変更してください。

これを適当なスクリプトのinitializeメソッドに貼り付けます。

#確認
実行すると、analyticsが取得できていることが確認できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/148084/08ae09f2-8a07-a148-2530-470e923af735.png)

#イベント送信
どのボタンがどれだけ押されたのか、どこで敵に倒されたか、等を簡単に取得できるイベント機能を使って行動分析を手軽にできます。

```javascript
                ga('send', 'event', {
                  'eventCategory': "イベントカテゴリー",
                  'eventAction': "イベントアクション",
                  'eventLabel' : "イベントラベル",
                  'eventValue': "値"
                });
```

ga('send','event',{});を呼ぶだけでイベント送信ができます。
送られてきたイベントはanalyticsのレポート>行動>イベントから確認することができます
assertThatでテスト対象がいずれかの値であることをテストする


インポート部分はこんな感じ

``` kotlin
import org.hamcrest.Matchers.*
import org.junit.Test
import org.junit.Assert.*
```

変数`val`が hogeかfugaであることをテストするには、以下のように記述すればよい。

```kotlin
assertThat(val, anyOf(equalTo("hoge"), equalTo("fuga")))
```

assetThatは色々柔軟な書き方が出来そう。
CakePHPでユーザ名とパスワードを変更するシェルを作る

## やりたいこと
既存のユーザのユーザ名とパスワードを変更するShellを作りたい。

とある要望から既存のユーザ名とパスワードを変更する必要が出てきたので、いずれまた同じ要望が出てきて他の人が同じ問題で悩まなくていいように、折角ならShell作っとくか、ということで作りました。

##環境
- CakePHP 2.2.5

##やり方
ポイントは３つです。

### １．AuthComponentを読み込ませる

```php:UpdateUserShell.php
App::uses('AuthComponent', 'Controller/Component'); //AuthComponentを読み込む

class UpdateUserShell extends AppShell {
 .
 .
```
これが居ないとパスワードがうまく保存出来ません。

AuthComponentの本体は

```
lib/Cake/Controller/Component/AuthComponent.php
```

ここにいるので、上記のように記述するとうまくいきました。

**※ただし、Userモデルの中で読み込んでいる場合はシェルで指定する必要はありません**

### ２．Shell からモデルを使えるようにする
```php:UpdateUserShell.php
public $uses = array('User');
```
Shell からUserモデルを使えるようにするために、１文必要です。

### ３．パスワードは平文を指定する

```php:UpdateUserShell.php
$this->User->id = $id;
$this->User->set(array(
	'username' => 'fuga',
	'password' => 'newPassword', //パスワードは平文を指定
));
$this->User->save();
```
平文で指定してやると勝手にハッシュ化してくれます。


##参考
- [シェルの中でモデルの利用（本家）](https://book.cakephp.org/2.0/ja/console-and-shells.html#id3)
- [[CakePHP 2.x] shell(シェル)からComponent(コンポーネント)を呼び出す](https://qiita.com/colorrabbit/items/d302cc0eeec3adc18456)
tarのコマンドの覚え方(´・ω・｀)版

tarのコマンドの覚え方(´・ω・｀)版
==================
(´・ω・｀)は最近やっと使えるようになったので，その喜びを噛みしめるためにも．

tarが苦手な理由って，そのオプションの設定が必須なのによくわからないっていうところだと思う．

それぞれの意味をきちんと抑えると実はそんなに難しくない．

これを期によく使う部分だけ簡単に覚えてしまおう．


tarとはなにか
=====================

`tar`は複数のファイルを一つのファイルにまとめるコマンドだ．

例えば次の３つのファイルがある時，

a.txt b.txt c.txt

`tar`でまとめると，

abc.tar

こんな風に，`tar`という拡張子のファイルにまとめてくれる．

現在では書庫にしてから圧縮するという二段構成が面倒なので，
`tar`のオプションで圧縮までできるようになった．

しかし，慣習として`tar`して`gzip`と言う流れだったから，
拡張子は`tar.gz`という風に二段構成でつけられる．

もうちょっと詳しい`tar`と`gzip`の関係については一番最後に．


総覧
=======================

BNFっぽい記法で書くと大体次を覚えればよい．

オプションに`-`をつけなくても良い珍しいコマンド．
もちろんつけても大丈V．

```bash:
tar {c|x|t}{z|j|J|}{v|}f [出力先] [処理対象]
```

日本語で書くと，それぞれのブラケットは次のような処理に対応している．

```bash:
tar {何をするか}{圧縮のオプション}{処理を表示}f [出力先] [処理対象]
```

必須オプション{何をするか}
----------------
まず，何をしたいのかを教えてあげよう．


アーカイブを新規に作成したい場合は`c`オプション(Create)

```bash:
tar c
```

書庫から取り出したいときは`x`オプション(eXtract)

```bash:
tar x
```

書庫をテストしたい時は`t`オプション(Test)

とりあえずこれだけで十分．

他にも
ファイルを追加したいときはAオプション
後ろにファイルを付け加えたいときはrオプション，
ファイルを消したいときは--deleteオプション

圧縮のオプション
------------------
圧縮したい場合，あるいは圧縮されているものを回答したい場合は`z`もしくは`J`オプションを付ける．

アーカイブだけだと`tar`．

拡張子は`.tar.gz`と言う風に二段構成にすることが多い．

###gzip

gzipであれば（.gzで終わるファイル．）
zオプションをつけよう．


```bash:
tar cz
tar xz
```

###bzip2

bzip2であれば（.bg2）jオプションをつけよう．

```bash:
tar cj
tar xj
```

###xz
xzであれば（.xz）Jオプションをつけよう．

```bash:
tar cJ
tar xJ
```

よく見るのは`tar.gz`か`tar.xz`かな？

扱うファイルによって使い分けるのがよい．


処理内容表示オプション
------------------------
また，vオプションを付けると今何をしているのか表示してくれる．

```bash:
tar czv
tar xzv
```

出力先オプション
--------------------
何も指定しないと，磁気テープ上に保存されてしまう．
名前の指定をしないといけない．

名前指定はfオプションで指定してあげよう．

```bash:
tar czvf [出力先] [処理対象]
tar xzvf [処理対象] [出力]
```


ちなみに出力先に`-`を指定すると，標準出力に流してくれる．

パイプで繋げば色々できちゃうよん．


まとめ
=================
ここまで読めば，次のBNFっぽい記法さえ覚えておけば，tarは怖くないと思えるはずだ．

```bash:
tar {c|x|t}{z|j|J|}{v|}f [出力先] [処理対象]
```


古いtarで圧縮・解凍したい
====================
古い`tar`だと圧縮・解凍機能がついていないことがある．

まあ，`.tar`をつくって`gzip`，あるいは，`gzip`して`tar`としてもいいんだけど，ワンライナーでしたいよね．
そんなときは，さっき紹介した標準出力に流す`-`を使って，

圧縮
------

```bash:
tar cvf - [処理対象] | gzip - > [出力先]
```

解凍
-------------

```bash:
gzip -dc [処理対象] | tar -xvf -
```

gzipについてちょっとだけ
--------------
なんでこんな面倒なことをしないといけないのか．

`gzip`は__一つのファイル__を圧縮するコマンド．

ディレクトリは圧縮できないのね．

ってことで，`tar`してディレクトリをファイルにまとめてから，`gzip`で圧縮．


参考文献
==========
- [gzip対応していないtarでtar.gzをワンライナーで圧縮・解凍する](http://mobamen.info/server-unyo/95)
- [tar](https://ja.wikipedia.org/wiki/Tar)
- [tarコマンド、gzipコマンドの使い方](https://qiita.com/sinpey_g2/items/13819ebe57a46090f064)
- [TAR（ター）とは？](http://gama.e-creators.info/20160224-linux-tar-gz-zip)
gulp周り

なんか
gulpした時に

```
Error in plugin 'gulp-ruby-sass'
```

ってエラーが出ることがある。

nvm

node

npm

sass

のversionを見てみるしかない。


今回はsassのversionあげてこのエラーが出てしまった感じ。


```
$ sass -v
Sass 3.5.3 (Bleeding Edge)

$ sudo gem uninstall sass 
Select gem to uninstall:
 1. sass-3.4.25
 2. sass-3.5.3
 3. All versions
> 2
Successfully uninstalled sass-3.5.3
$ sass -v
Sass 3.4.25 (Selective Steve)

```
MeCabの全解析結果をデータフレームにする


## 形態素解析

形態素解析器であるMeCabに文章を与えると、デフォルトでは以下のような出力が得られます。

```{r}
system("echo 日曜日はロシアに出かけます。 | mecab")
```
```
日曜日	名詞,副詞可能,*,*,*,*,日曜日,ニチヨウビ,ニチヨービ
は	助詞,係助詞,*,*,*,*,は,ハ,ワ
ロシア	名詞,固有名詞,地域,国,*,*,ロシア,ロシア,ロシア
に	助詞,格助詞,一般,*,*,*,に,ニ,ニ
出かけ	動詞,自立,*,*,一段,連用形,出かける,デカケ,デカケ
ます	助動詞,*,*,*,特殊・マス,基本形,ます,マス,マス
。	記号,句点,*,*,*,*,。,。,。
EOS
```


すなわち形態素ごとに *表層形\t品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用形,活用型,原形,読み,発音* が出力されます。

**RMeCab** パッケージでは `RMeCabText()`を除いて、このうち表層形、品詞,品詞細分類1,原形について取り出し、頻度表を作成しています。

ただ、全て品詞情報が必要だという声を耳にすることがありますので、その方法を示します。といっても`RMeCataText()`の出力を*tidyverse* パッケージを使って加工するだけです。

## **tidyverse** と組み合わせる

いわゆるtidyな出力です。

```{r}
library(RMeCab)
x <- RMeCabText("yukiguni.txt")
library(tidyverse)

x %>% map_df(~ data_frame(Term = .x, 
                          POS  = c("表層","品詞","品詞１",
                                   "品詞２","品詞３", "活用１",
                                   "活用２","原形","読み","発音")),.id = "Line")  %>% head(11)
```

```
## # A tibble: 11 x 3
##     Line       Term    POS
##    <chr>      <chr>  <chr>
##  1     1       国境   表層
##  2     1       名詞   品詞
##  3     1       一般 品詞１
##  4     1          * 品詞２
##  5     1          * 品詞３
##  6     1          * 活用１
##  7     1          * 活用２
##  8     1       国境   原形
##  9     1 コッキョウ   読み
## 10     1 コッキョー   発音
## 11     2         の   表層
```


POS情報を列に分けたい、つまり横長のデータフレームにしたい場合は以下のようにします。



```{r}
x <-  RMeCabText("/home/ishida/Dropbox/R/forCheck_utf8/data/yukiguni.txt")
x %>% map_df ( ~ data_frame(Term = .x, 
                             Pos  = c("表層","品詞","品詞１","品詞２","品詞３", 
                                      "活用１","活用２","原形","読み","発音")),
                              .id = "Line") %>% 
                                 spread(key = Pos, value = Term)

```

```
## # A tibble: 28 x 11
##     Line           活用１     活用２  原形       読み       発音  表層
##  * <chr>            <chr>      <chr> <chr>      <chr>      <chr> <chr>
##  1     1                *          *  国境 コッキョウ コッキョー  国境
##  2    10   五段・ラ行アル 連用タ接続  ある       アッ       アッ  あっ
##  3    11         特殊・タ     基本形    た         タ         タ    た
##  4    12                *          *    。         。         。    。
##  5    13                *          *    夜       ヨル       ヨル    夜
##  6    14                *          *    の         ノ         ノ    の
##  7    15                *          *    底       ソコ       ソコ    底
##  8    16                *          *    が         ガ         ガ    が
##  9    17 形容詞・アウオ段 連用テ接続  白い     シロク     シロク  白く
## 10    18       五段・ラ行 連用タ接続  なる       ナッ       ナッ  なっ
## # ... with 18 more rows, and 4 more variables: 品詞 <chr>, 品詞１ <chr>,
## #   品詞２ <chr>, 品詞３ <chr>
```


ファイルを用意したくない場合は、一時ファイルを作成して読み込ませるといいでしょう。


```{r}
tmp <- tempfile()
"国境の長いトンネルを抜けると雪国であった。夜の底が白くなった。信号所に汽車が止まった。"  %>%
   write(file = tmp)
x <- RMeCabText(tmp)
unlink(tmp)
```
Re:AtomとAnaconda ～浮気して乗り換えたの巻～

前回の記事で、ぐちゃぐちゃにしてしまった自分の環境。

いろいろと面倒だからとブショウをしてとりあえず前に進んでみたものの。
やりたいことがちょろっと変わるだけで、いろいろ制限が出てきたので。

# そもそも自分がやりたかったこと。
大嫌いな環境構築を少ない手順で行う。
対象の環境としては、java、Python

## 前回までの状態
Atom　インストール、パッケージインストール
Anaconda　インストール、env作成
これで、Pythonは行けてた。

## 今のやりたいこと。
大嫌いな環境構築を少ない手順で行う。(変わらず)
対象の環境としては、java、Python、node＋Electron(これ増えた)

というわけで。
頭をクリアして、そういえばと思い出したこと。

自分のPCには、「chocolatey」が入っていたのだと。
いったん作業を始める前に整理。
インストールされているもの

```
chocolatey
git(コンソール含む)
```

### まずは、python
git付属のコンソールを管理者権限で開いて。
※ちなみに、以下をファイル名を指定して実行とすると一発です。

```
powershell -command "Start-Process -wait \"C:\Program Files\Git\git-bash.exe\" -Verb runas"
```

choco でよくつかうコマンド

```
choco list -lo
```

#### 3系をインストールする場合

```
cinst python3 -y
```
#### 2系をインストールする場合

```
cinst python2 -y
```
※ cinst python でも可能だけど、環境変数はやってくれない。ギャラリーでもちょろっと書いてあった。

#### バージョン確認

```
python --version
pip --version
```
後は仮想環境をとりあえず。

```
pip install virtualenv
```

### nodeを使えるように

```
cinst nvm -y
```
#### バージョン確認

```
nvm version
```
### nodeのインストール
#### 可能なバージョンの確認

```
nvm ls available
```
一番左のCURRENTをもとに例えば以下。

```
nvm install 9.0.0
```
※ npmが対応してないので、基本使わない？？？
とか

```
nvm install 8.8.1
```
今ローカルに何がインストールされているかは

```
nvm ls
```
どれを使うかは、

```
nvm use 8.8.1
```

現在どのバージョンが選択されているかの確認は

```
node --version
```
削除するのは、

```
nvm uninstall 8.8.1
```

### Electronは以下

```
npm -g install electron
```
### 次にエディタ。
Atomのパッケージ多機能もよかったのですが、VisualStudioのほうが、見分けやすいとのことで、こちらへ浮気。

```
choco install visualstudiocode -y
```
いったんコンソール閉じて。

```
code .
```
で起動確認

git やら ターミナル　やら　言語関連のエクステンションは、お知らせいただけるので、素直に従いましょう。

キーコンフィグでやっておいたほうが良いこと。
コンソールとエディタの移動をしたくなります。
そんな時は、以下をお好みで。

```
[
    {
        "key": "ctrl+【お好み】",            "command": "workbench.action.terminal.focus",
                                    "when": "editorTextFocus"
    },
    {
        "key": "ctrl+【お好み】",            "command": "workbench.action.focusFirstEditorGroup",
                                    "when": "terminalFocus"
    }
]
```

注意点としては、Visual Studio Codeが「USキーボードのキーコードを想定している」様子であること。
【お好み】を「;」にしたとき「:」で動いてます。

後はコーディングが行える状態になるかと。
Windows > curlを使う


Windows環境でcurlを使います。

↓からcurlをダウンロードします。
[curl - Download](https://curl.haxx.se/download.html)

ページ最下部あたりにWindowsがあります。
自分の環境はWindows7 64bitだったのでWin64 ia64 CABを選びました。
![image](https://qiita-image-store.s3.amazonaws.com/0/49910/20f017de-2205-72a7-8a80-54b92c40a7b6.png)

ダウンロードしたファイルを解凍します。

以下のようにフォルダが表示されます。
各々の環境に応じたフォルダを選択します。
![image](https://qiita-image-store.s3.amazonaws.com/0/49910/34253386-43c7-f172-9469-f060eb694a07.png)

64bitWindwsだったのでAMD64のフォルダに入りました。

エクスプローラーのパス部分にcmdと打ち込んでコマンドプロンプトを表示します。
![image](https://qiita-image-store.s3.amazonaws.com/0/49910/b4eec9ee-32cd-40fe-9537-3b7244549fed.png)

`curl --help` 
と打ち込んでヘルプが表示されたらOK

ここで各種curlコマンドが実行できます。


# proxy環境の場合

proxy環境でlocalhostにcurlアクセスする場合、以下のようにでる場合があります。

```
$ curl -XGET http://localhost:9200/
<HTML>
<HEAD><TITLE>Redirection</TITLE></HEAD>
<BODY><H1>Redirect</H1></BODY>
```

その場合にはnoproxyを指定するとproxyを通さずにLocalhostへアクセスできます。

```
curl --noproxy localhost localhost:9200
```
CentOS7の仮想環境上でRails動かしていて Bundle installに失敗する場合

#bundle installに失敗してたのを解決した話


##日付がずれていた
研修環境でMacOSにVirtualBoxをインストールしその上でCentOS7を使っていました。
かれこれ２ヶ月以上その環境で使っていましたが、ほぼ仮想環境もマシンもシャットダウンしていません。
ある朝気がつくと、Rails上で取得している日付が１週間以上ずれていました。

この原因はちゃんと調べていないのですが、仮想環境をシャットダウンせずにマシンをスリープ（画面を閉じる）させるタイミングで少しずつ時間がずれていたようです。


##エラー発生
その日にコマンドライン上で　
bundle install
してみました。

そうすると　SSL　関係のエラーがでました。長々と表示されますが

```
Could not verify the SSL certificate for https://rubygems.org/.
　〜中略〜
         edit your Gemfile sources and change 'https' to 'http'
```

最後にこのように表示されました。

##解決せず
このエラーメッセージをGoogle検索してみると
SSL証明書のエラーだから pem（証明書）ファイルをダウンロードして云々とでてきます。
しかしそれらを実行してみても解決しませんでした。
あちこちのディレクトリの権限がないと表示されます。


##日付を合わせて解決
それで当初の日付がずれていることを思い出し、日付を合わせることにしました。

今回は　chrony　をインストールしました。
chronyについて詳しくは[CentOS7の時刻をChronyを使ってNICTと同期する](https://qiita.com/Kenji_TAJIMA/items/88ec9985a0585e66ef33)を参照させていただきました。


```
sudo yum install chrony

sudo systemctl start chronyd.service
```

最初のyum installでchronyをインストールすると何度か問い合わせがあるので　「y」を選択します。
ひとまず２番目のコマンドでchronydを起動するとそのうちタイムサーバと同期して日付を合わせてくれます。
その後　date　コマンドを実行すると無事日付の同期を確認しました。

同じエラーが出ていた２つの仮想環境で無事　bundle install　成功しました。

ChronyはCentOS7のisoでminimal版以外だと最初から入っているようです。
限られた環境かもしれませんがこんな原因もあるということで。

##追記
bundle install だけでなくgem installでも同じく

```
$ gem install rails
ERROR:  SSL verification error at depth 0: certificate is not yet valid (9)
ERROR:  Certificate /C=US/ST=California/L=San Francisco/O=Fastly, Inc./CN=f2.sha
以下同じようなSSL verificationエラー

```
が発生した場合、日付のズレを直すと無事gemでもinstallが実行できました。
react-native 基本中の基本を勉強します

reactnativeの基本的な所

# reactnativeとは
　iosとandroidが一つの言語でかける
　webのプログラム言語
　JavaScriptの知識が必要

# 準備
 ・Expo
 ・WebStream

# react-native 基本的なプログラム

###< 単純に文字を表示するプログラム>
<font color="Red">App.js</font>

```
import React, { Component } from 'react';
import { Text } from 'react-native';

export default class HelloWorldApp extends Component {
  render() {
    return (
      <Text>Hello world!</Text>
    );
  }
}
```

ここで必要な機能を使うためのライブラリを取得している

```
import React, { Component } from 'react';

import { Text } from 'react-native';
```

実際にプログラムを入力をするところ、テキストを表示している

```
export default class HelloWorldApp extends Component {
   render() {
    return (
      <Text>Hello world!</Text>
    );
  }
}
```

//追記していきます

# つまづいたところ

import Listviewadd from './addListView';

と宣言するとき

Listviewaddをlistviewaddとするとエラーが出る。
そのため、最初の文字は大文字にしなければならない

こんな感じのエラーが出た時の対処法

Google Chrome exited with error: Error: Exited with code 1
17:18:08:     at ChildProcess.<anonymous> (/Users/tatsuya/ReactNativeProject/ListAdd/node_modules/react-native/node_modules/opn/index.js:86:8)
17:18:08:     at Object.onceWrapper (events.js:316:30)
17:18:08:     at emitTwo (events.js:125:13)
17:18:08:     at ChildProcess.emit (events.js:213:7)
17:18:08:     at maybeClose (internal/child_process.js:927:16)
17:18:08:     at Socket.stream.socket.on (internal/child_process.js:348:11)
17:18:08:     at emitOne (events.js:115:13)
17:18:08:     at Socket.emit (events.js:210:7)
17:18:08:     at Pipe._handle.close [as _onclose] (net.js:557:12)

アプリのexpoをシェイクすると出るメニューの上から２番目が「Stop Debug Js Remotely」となっていたら、それをプッシュすると元に戻る
nohup コマンド

# nohup

この記事は [Linux コマンド 全部オレ Advent Calendar 2017](https://adventar.org/calendars/2630) の14日目の記事です。

```
NAME
     nohup -- invoke a utility immune to hangups

SYNOPSIS
     nohup [--] utility [arguments]

DESCRIPTION
     The nohup utility invokes utility with its arguments and at this time sets the signal
     SIGHUP to be ignored.  If the standard output is a terminal, the standard output is
     appended to the file nohup.out in the current directory.  If standard error is a ter-
     minal, it is directed to the same place as the standard output.

     Some shells may provide a builtin nohup command which is similar or identical to this
     utility.  Consult the builtin(1) manual page.
```
意味としては HUP シグナルを無視したいときに使う。

## よく使いそうな使い方

`nohup コマンド &` で、コマンドを実行し仮想端末を閉じたりログアウトしてもコマンドが動き続けるようにする。
一般的には仮想端末を閉じると、HUP シグナルが送られてそのプロセスは終了する（※）が、それを無視することでプロセスを動かせ続けるようにする。

```
[sinsengumi ~]$ nohup sleep 30 &
```

## nohup つけなくても動き続けてるけど？

bash だと `huponexit` がデフォルト OFF になっているから。これが OFF だと exit しても SIGHUP は送られない。

### 参考

- https://www.glamenv-septzen.net/view/854

## nohup とデーモンの違い

デーモンのざっくりした定義としては以下らしい。

1. バックグランドで動作している
1. 制御端末を持たない
1. 他のプロセスグループに属さない
1. 親プロセスが init

3, 4 あたり満たしてないので、デーモンとは言わない感じ。
systemd や supervisord などでサービス化されてるものはデーモンと呼んで良さそう。


### 参考

- http://engineering.otobank.co.jp/entry/2015/03/12/135500
今CSS組版で同人誌を書くとしたら 2017

[技術系同人誌 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/tech-fanbook)の名目上9日目です。
なんかすんごい勢いで枠埋まってるので日をさかのぼって登録してます。

----

何度も頓挫させてるのではっきり言って信用ならない情報なのですが、
仮にこれから私がCSS組版で同人誌を書くとしたら
どんな環境を用意するか、というIFの話をします。
*あと自分は業界人でもなんでもないただの素人だからそこ覚悟して読んでね。*

# 基本ルール
## 「あるものを使う」
なるべく既にあるものを上手いこと使いまわして労力を削減します。
まかりまちがっても組版向けのレイアウトフレームワークを作るとかはやりません。

## 「Webに近しいものを使う」
HTML,CSS,JavaScriptとその親戚を優先して使います。
最終形がここなのでここから遠いものがプロジェクト内に
増えれば増えるほど道のりがしんどくなることが予想されます。

できればプログラム的なものはJSライクにだけ書ければいいようにしたいです。
やっぱアイソモーフィックですよアイソモーフィック。知らんけど。

# HTML
何はともあれ本文用にMarkdown。

Markdownにはデファクトスタンダードがないという点がよく槍玉に上がるけど
合同誌向けでもない限りはオレオレ拡張でガンガン建て増しした方が結果的に良さそう。
なのでパーサがいじりやすいものだと良い。JS製ならmarkdown-itだと思う。

あとはstat blockのためにテンプレートエンジン的なものが欲しい。
PugかReact-JSXかEJSか。動的にやる必要はあまりない。
物によってはテンプレートエンジンがMarkdown読み込み対応してたりする。

最終的に複数のMarkdownやstat blockをレンダリングしたものを
1ファイルのhtmlに組み立てていく段階があり、そこを誰にやらすかでプロジェクトの方向が決まる。
JS書いてDOMを組み立てるか、前述のテンプレートエンジンを利用するか、
PostHTMLとかを使ってそれらのいいとこどりを狙うか。
JSからテンプレートエンジン呼び出して使ったり、
テンプレートエンジンのプラグインでMarkdownがパースできたり、
こいつらの多くは相互に相手を利用する方法を持ってるけど
結局根っこは誰が担当するのかというのを明確にしておく必要がある。

# CSS
PostCSSかなー。
現代のCSSを効率的に書くのではなく未来のCSSを現代の環境に召喚するのが主目的なので
コンセプト的にはCSSNextとかが合致しているように見える。

Markdownは要素にクラスを当てるの超絶苦手なので
BEMやらコンポーネント指向やらのメインストリームの考え方とはものすごく相性が悪い。
あきらめてタイプセレクタまみれのスタイルシートを書くかMarkdownパーサを魔改造するか
他の方法で本文を書く修羅になるかを選ぶ感じだと思う。

# JavaScript
お好きなaltJSをどうぞ。
レガシーブラウザ対応とか考える必要ないからES6をaltJSとして使えばいいと個人的には思う。
そのうち間に処理はさむことなく直で使えるようになるだろうからその時のリターンを見越す感じで。
採用したテンプレートエンジンが特定のaltJS推しならそっちでも。

# ビルドツール/バンドラ
まあgulpかwebpackでいいのでは。シェル芸歴がないのでnpm-scriptsだとかえって手間かかりそう。

あとやってることがほぼほぼ静的サイトジェネレータなので
条件にマッチするものがあれば色々そっちに面倒を見てもらう手もあるか。

小さいプロジェクトなら最近出てきたparcelとかいうのも使えそう。
本を書く目的ならつまるところエントリポイントは本文一個なので相性は良いと思う。

# ヘッドレスブラウザ
CSS組版的には環境を一変させてしまった危ないブツ。
これがあると原稿をpdf化するまでを全部スクリプトでできるようになってしまう。
でもまだ全然いじれてないのでコメントできない。

どうせデザインやる時にchrome dev toolは使うのでヘッドレスブラウザ使うなら同系のpuppeteerになると思う。
もしくははるさめ氏の https://www.npmjs.com/package/viola-savepdf に任せる。

# 字詰め
- Yaku Han JP
- `font-feature-settings: 'palt';`

なんかすごいこだわりがあるのでなければこの二つさえあればどうにかなると思う。

# Chromeのルビでかすぎ問題
https://www.nxworld.net/tips/css-snippets-6.html#anchor03

# stat blockの中身書き
直でjsonいじったりすると手計算部分とかで死にそうなので
基本的にオンラインキャラシーのようなものを用途別に作ってそっちからしこしこ入力したい。
phpでスクライピングをやってみたが・・・・

#始めに
PHPでスクライピングをやってみたときのメモです
ちなみにやりたいことはまだできていません・・・

#やりたいこと
Yahooファイナンスから値上がり率1位の銘柄を取得すること。 
ちなみに、値上がり率1位の銘柄はaタグの属性'data-ylk''が'slk:yoso;pos:1'のもので取得できるようです

#書いてみたソース
```sample.php
<?php

$dom = DOMDocument::load('https://finance.yahoo.co.jp/');
$nodelist= $dom->getElementsByTagName('a');
$target=array_filter($nodelist,function($a){return $a->getAttribute('data-ylk')==='slk:yoso;pos:1';}); 
echo $target->nodeValue;
?>
```

#実行結果(1回目）
```
Warning: DOMDocument::load(): Unable to find the wrapper "https" - did you forget to enable it when you configured PHP? in C:\phpsource\xpath.php on line 3

Warning: DOMDocument::load(): I/O warning : failed to load external entity "https://finance.yahoo.co.jp/" in C:\phpsource\xpath.php on line 3
```

がコンソールに出力された。
[スタックオーバーフロー](https://stackoverflow.com/questions/5444249/unable-to-find-the-wrapper-https-did-you-forget-to-enable-it-when-you-config)を見ると、php.iniに

- extension=php_openssl.dll
- allow_url_include = On

が必要そう
php.iniに上記設定を追加してみる

#実行結果(2回目）
php.iniにopen_sslの設定を追加した後、プログラムを実行したが

```
PHP Fatal error:  Uncaught Error: Call to a member function getElementsByTagName() on boolean in C:\phpsource\xpath.php:4
Stack trace:
#0 {main}
  thrown in C:\phpsource\xpath.php on line 4

Fatal error: Uncaught Error: Call to a member function getElementsByTagName() on boolean in C:\phpsource\xpath.php:4
Stack trace:
#0 {main}
  thrown in C:\phpsource\xpath.php on line 4
```

というエラーが出た
おそらく、phpの実装が間違っていると思わるが、どこで間違っているかは正直よくわかっていません
Eclipse の "The JRE container on the classpath is not perfect match" 

#問題
Eclipse で "The JRE container on the classpath is not perfect match" というWarning?が発生した場合。
<img width="901" alt="スクリーンショット 2017-12-14 11.24.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/9e45d8dc-0614-b550-28c3-ab4518768f2c.png">

#解決方法
<img width="303" alt="スクリーンショット 2017-12-14 11.24.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/4b26a701-5c9b-2226-772a-3aafe78bea5a.png">
プロジェクトの中にあるMANIFEST.MFの設定が間違っているのが原因っぽいので、
<img width="631" alt="スクリーンショット 2017-12-14 11.25.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/70d41ff6-b6ae-c715-9c64-d8e82df83c04.png">

Project ExplorerでJRE System Library が JavaSE-1.8となっているので
MANIFEST.MFのOverView Execution Environmentsからそれに合わせる

<img width="338" alt="スクリーンショット 2017-12-14 11.32.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/4a5772fe-7f8f-586a-6355-9d3cb8df41e1.png">