OmniAICreator/Qiita-1.07M huggingface dataset:
GCDを使った終了処理

# はじめに

GCDを使用したマルチスレッドで複数の処理が終了してから終了処理を実行したい！ので調べて書いてみました。
GCDの基本的な概要はこちらの記事が詳しく書いてありました。
http://qiita.com/ShoichiKuraoka/items/bb2a280688d29de3ff18

# Dispatch Group

Dispatch Groupを使って終了処理を実装する方法
`Global Dispatch Queue(並列)に 処理Blockを追加し実行がすべて終了したらMain Dispatch Queue(メインスレッド:直列)を実行する`

サンプルコード

``` objc
 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, queue, ^{ NSLog(@"Block0"); });
    dispatch_group_async(group, queue, ^{ NSLog(@"Block1"); });
    dispatch_group_async(group, queue, ^{ NSLog(@"Block2"); });
    dispatch_group_async(group, queue, ^{ NSLog(@"Block3"); });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"Done!!");
    });
``` 

## 解説

## dispatch_queue_t
- dispatch_get_global_queue関数を使って`Global Dispatch Queue`を生成しqueue変数に格納

```objc
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
```

## dispatch_group_t
- dispatch_group_create関数を使って`Dispatch Group`を生成しgroup変数に格納

```objc
dispatch_group_t group = dispatch_group_create();
```

## 処理Blockを追加
- dispatch_group_async関数を使って処理を追加します
- 第一引数には追加する` Dispatch Group` を指定し、第二引数には実行する `Queue` を指定し最後に第三引数には実行したい処理を追加します。

```objc
    dispatch_group_async(group, queue, ^{ NSLog(@"Block0"); });
    dispatch_group_async(group, queue, ^{ NSLog(@"Block1"); });
    dispatch_group_async(group, queue, ^{ NSLog(@"Block2"); });
    dispatch_group_async(group, queue, ^{ NSLog(@"Block3"); });
```

# 終了処理を追加
- dispatch_group_notify関数を使って` Dispatch Group`に追加された処理が全て実行されたら実行する終了処理を追加します。
- 第一引数には対象にする`Dispatch Group`を指定、第二引数には実行したい `Queue` を指定し、最後に第三引数に終了時に実行したい処理を追加

```objc
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"Done!!");
    });
```

# 実行結果

Blockの実行が並列なのでバラバラに実行されています。
Done. :champagne: 

``` objc
2017-01-24 10:32:32.599 [85966:2707092] Block0
2017-01-24 10:32:32.599 [85966:2707090] Block1
2017-01-24 10:32:32.599 [85966:2707105] Block2
2017-01-24 10:32:32.599 [85966:2707314] Block3
2017-01-24 10:32:32.605 [85966:2706860] Done!!
```
《Git》すでにインデックスされているファイルを監視対象から外す

### すでにインデックスされているファイルを監視対象から外す

すでにインデックスされているファイルをローカルに残したいけどレポジトリからは削除したいとき。インデックスされているファイルを監視対象から外す。

まず.gitignoreに除外したいファイルやディレクトリを記述します。

[.gitignoreの仕様詳解](http://qiita.com/anqooqie/items/110957797b3d5280c44f)

#### .gitignore

```
your_directory
your.html
```

ターミナルでコマンドを入力します。

#### terminal

```
git rm -r --cached your_directory/
```

または

```
git rm -r --cached your.html
```

上記コマンドのあと、コミットしてプッシュする。
nginx php installation with chocolatey

### better solution ... sigh ...
```
https://www.getwnmp.org/
```

>
The Username and Password for MariaDB is:
 user: root password: password (I recommend changing the password)

>
You should change $cfg['blowfish_secret'] in config.inc.php in the phpmyadmin folder for added security.

>
The SSL Certificate is now generated by Wnmp using VigorTLS. (Now Secure!)


### chocolatey installation

```
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%systemdrive%\chocolatey\bin
```

```
choco install php -version 5.6.17 
```

```
composer config -g -- disable-tls true
```

```
>choco install nginx
Chocolatey v0.10.3
Installing the following packages:
nginx
By installing you accept licenses for the packages.

nginx v1.10.2 [Approved]
nginx package files install completed. Performing other installation steps.
The package nginx wants to run 'chocolateyInstall.ps1'.
Note: If you don't run this script, the installation will fail.
Note: To confirm automatically next time, use '-y' or consider setting
 'allowGlobalConfirmation'. Run 'choco feature -h' for more details.
Do you want to run the script?([Y]es/[N]o/[P]rint): Y

Downloading nginx
  from 'https://www.nginx.org/download/nginx-1.10.2.zip'
Progress: 100% - Completed download of C:\Users\Dell\AppData\Local\Temp\chocolat
ey\nginx\1.10.2\nginx-1.10.2.zip (1.3 MB).
Download of nginx-1.10.2.zip (1.3 MB) completed.
Hashes match.
Extracting C:\Users\Dell\AppData\Local\Temp\chocolatey\nginx\1.10.2\nginx-1.10.2
.zip to C:\ProgramData\chocolatey\lib\nginx\tools...
C:\ProgramData\chocolatey\lib\nginx\tools
 ShimGen has successfully created a shim for nginx.exe
 The install of nginx was successful.
  Software installed to 'C:\ProgramData\chocolatey\lib\nginx\tools'

Chocolatey installed 1/1 packages. 0 packages failed.
 See the log for details (C:\ProgramData\chocolatey\logs\chocolatey.log).
```
Jenkinsへログインできなくなった時の対応方法



* jenkins2.xにてハマったのでメモ。

## 原因
* インストール直後にブラウザからアクセスすると、UIで初期設定を行うことになる。
* 初期状態で「ログイン認証が必要」に設定されているようだが、上記の初期設定中にアカウント設定をしないまま初期設定を中断した。
* 見事ログインできなくなった＼(^o^)／

## 対応
* /var/lib/jenkins/config.xmlを編集する。
	
	```console
	$  diff -u config.xml.org config.xml
	--- config.xml.org	2016-06-12 16:12:14.273858969 +0900
	+++ config.xml	2016-06-12 16:12:26.617858604 +0900
	@@ -4,7 +4,7 @@
	   <version>1.0</version>
	   <numExecutors>2</numExecutors>
	   <mode>NORMAL</mode>
	-  <useSecurity>true</useSecurity>
	+  <useSecurity>false</useSecurity>
	   <authorizationStrategy class="hudson.security.FullControlOnceLoggedInAuthorizationStrategy">
	     <denyAnonymousReadAccess>true</denyAnonymousReadAccess>
	   </authorizationStrategy>
	@@ -38,4 +38,4 @@
	   </crumbIssuer>
	   <nodeProperties/>
	   <globalNodeProperties/>
	-</hudson>
	\ ファイル末尾に改行がありません
	+</hudson>
	```
	
* jenkins再起動
	
	```console
	$ /etc/rc.d/init.d/jenkins restart
	```
dots.の絞り込み検索でタグを使えるようにするextensionを作ってみた

dots.のタグ一覧ページでタグを選んで検索した後、他の条件で絞り込む。そうすると、何故か検索結果に選んだタグに関係のない勉強会が出てくる。
皆さん、こんな経験はありませんか。
どうやら、dots.のUIでは**タグと他の条件で同時に絞り込むことはできないようです**。
例えば、「JavaScript」「東京」「2/1〜2/15」のような絞り込みはできません。

お問い合わせから要望も出したのですが、待ってもいられないので簡単なChrome Extensionを作ってみました。
使い方は簡単、
https://chrome.google.com/webstore/detail/dots-with-tags/noeddbmjgnmkpinbeijfleajcclbldoi
でインストールするだけです。

インストールした後に https://eventdots.jp/event/search にアクセスすると
以下のように 「絞り込み」の下にタグ一覧が出てきます。
![](https://i.gyazo.com/4747f0e2682f9200c748104488eee805.png)

あとは、ここで興味のあるタグにチェックを入れて通常通り検索するだけで、タグを使った絞り込みが可能です。
Extensionの実装自体はかなり手抜きですが、何気に便利だと思うので是非使ってみてください。
Photoshopあれこれ


## ショートカット
#### 等倍に戻す
~~~
command + 1
~~~

#### 選択範囲解除
~~~
command + d
~~~

#### レイヤーの複製
~~~
command + j
~~~

#### レイヤーのグループ化
~~~
command + g
~~~

#### レイヤースタイルのコピー
~~~
// ショートカットなし
// `fx`マークを'alt(option)'を押しながらドラッグ
~~~

#### タブ移動
~~~
control + tab
control + tab + shift
~~~

#### ツール切り替え
`shift`と押しながらで同系ツールへの切り替え

~~~
移動 - v
選択 - m
クイック選択 - w
テキスト - t
長方形 - u
~~~

#### カンバスサイズ画面を開く
~~~
command + alt + c
~~~


## 編集
#### ■だんだん透明にする
1. レイヤーパネルで該当のレイヤーを選択する
1. レイヤーパネルの[ベクトルマスクを追加]
1. ツールバーの[グラデーション]でえいっとやる

##### 複数方向に透明にする
1. ↑でグラデーションをかけたレイヤーを選択し`control + g`(グループ化)
2. フォルダができるので、そのフォルダにベクトルマスクを追加する
3. その繰り返し

#### ■文字にグラデーション
1. レイヤーパネルから[レイヤースタイルを追加(fx)]の[グラデーションオーバーレイ]

#### ■ロゴ：袋文字
1. 文字を書く
1. レイヤーパネルから[レイヤースタイルを追加(fx)]の[境界線]

##### レイヤースタイルを独立させる
1. 作成したレイヤーの`fx`を右クリックして[レイヤーを作成]

##### 中抜き
1. 文字レイヤーで文字を選択する
2. そのまま独立させた境界線レイヤーをアクティブにする
3. `delete`ボタンを押す

#### ■キラキラさせる
##### ブラシ編
http://forty-n-five.boy.jp/blog/2014/08/photoshop_30.php
install ruby 1.8.7 with rbenv on OS X

# install lib
```
  brew install openssl libyaml libffi
```

# install ruby
```
CONFIGURE_OPTS="--with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl`" RUBY_CONFIGURE_OPTS="--with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl`" rbenv install 1.8.7-p371
```
Expressでgzipファイルを送信する（Rewrite）

###前提
・記載例の対象はjsファイルのみ
・gzipファイルはあらかじめ用意しておく

###1. gzipファイルを用意する

ここのやり方は任意です。
参考程度ですが、
・gulpを使う場合 -> gulp-gzip
・webpackを使う場合 -> compression-webpack-plugin
というライブラリを使うと簡単にできました。

gulp-gzip

```gulpfile.babel.js
gulp.task('gzip:js', () => {
  return gulp.src(`<inputのパス>/+(foo|bar|baz)*.js`)
  .pipe(gzip())
  .pipe(gulp.dest(<outputのパス>);
});
```

compression-webpack-plugin

```webpack.config.babel.js
new CompressionPlugin({
  asset: '[path].gz[query]',
  algorithm: 'gzip',
  test: /\.js$/,
  threshold: 10240,
  minRatio: 0.8
})
```

###2. Expressでリクエストをハンドリングする

```app.js
// jsファイルのリクエストをハンドリング
app.get(/(foo|bar|baz).*\.(js)$/, (req, res, next) => {
  req.url = `${req.url}.gz`;
  res.set('Content-Encoding', 'gzip');
  next();
});
```

ハンドリング自体はこれでできるのですが、
このままだと、

> MIME タイプの不一致により “foo.js” からのリソースがブロックされました (X-Content-Type-Options: nosniff)。

というエラーになってしまいます（上記はFirefoxのコンソール）。

'Content-Type'が'application/octet-stream'になっているので、
明示的に'application/javascript'を指定してあげると上記のエラーは出なくなります。

```app.js
app.get(/(foo|bar|baz).*\.(js)$/, (req, res, next) => {
  req.url = `${req.url}.gz`;
  res.set('Content-Type', 'application/javascript'); <- この行を追加
  res.set('Content-Encoding', 'gzip');
  next();
});
```

###3. 動作確認

throttlingをRegular 4Gにした場合だと、手元ではこのくらい変わりました。
圧縮前
![before.png](https://qiita-image-store.s3.amazonaws.com/0/37319/b810f849-58ba-a733-9a9a-ae4980c720c7.png)

圧縮後
![after.png](https://qiita-image-store.s3.amazonaws.com/0/37319/2ddfb33f-dd95-42a8-6709-d34136961147.png)
docker コンテナ上で Hubot スクリプトを開発しはじめるときの自分のやり方

久しぶりに docker コンテナ上で Hubot スクリプトを開発してるんだけど、docker の使い方に慣れてきたのか、前よりもいい感じに環境構築できたのでメモしておく。

## 準備

まず、`Dockerfile.dev` と `docker-dev.sh` という 2 つのファイルを用意する。

**Dockerfile.dev**

```
FROM node
RUN apt-get update && apt-get install -y vim
RUN npm install -g hubot coffee-script
WORKDIR /usr/local/hubot
```

**docker-dev.sh**

```
docker build -f Dockerfile.dev -t tily/hubot-example:dev .
docker run -ti --rm -v $(pwd):/usr/local/hubot tily/hubot-example:dev bash
```

## 開発しはじめる

`docker-dev.sh` を実行すると `Dockerfile.dev` を元にイメージがビルドされたあと、bash でログインした状態になる。(初回のみ時間がかかり、次回以降は一瞬でログインできる。)

```
$ ./docker-dev.sh 
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM node
 ---> b554dc4860d7
Step 2 : RUN apt-get update && apt-get install -y vim
 ---> Using cache
 ---> e05afe17e1a0
Step 3 : RUN npm install -g hubot coffee-script
 ---> Using cache
 ---> 30f07011bb7c
Step 4 : WORKDIR /usr/local/hubot
 ---> Using cache
 ---> 5938ef13430e
Successfully built 5938ef13430e
root@cc998ad261a9:/usr/local/hubot#
```

`npm init` して `package.json` を生成する。

```
root@cc998ad261a9:/usr/local/hubot# npm init
(略)
root@cc998ad261a9:/usr/local/hubot# cat package.json 
{
  "name": "hubot-example",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
```

`index.js` ファイルで Hubot スクリプトを開発していく。

```
root@cc998ad261a9:/usr/local/hubot# vim index.js
root@cc998ad261a9:/usr/local/hubot# cat index.js 
module.exports = (robot)=> {
  robot.respond(/hello/, (message)=> { message.reply("world"); });
};
```

`hubot -r .` で動作確認する。(`-r` はスクリプトを読み込むディレクトリのパスを指定するオプション。)

```
root@cc998ad261a9:/usr/local/hubot# hubot -r .
Hubot> Hubot hello
Hubot> Shell: world
```

## 開発終了

開発が終わったら、`exit` してコンテナを破棄する。`docker run` 時にカレントディレクトリを `/usr/local/hubot` へマウントしていたので、ファイルの変更はホスト側にも反映されている。

```
root@cc998ad261a9:/usr/local/hubot# exit
exit
$ cat index.js 
module.exports = (robot)=> {
  robot.respond(/hello/, (message)=> { message.reply("world"); });
};
```

## まとめ

docker が使える環境なら、2 ファイル用意すれば素早くいい感じに Hubot スクリプトの開発をはじめられるようになった。

hubot-brain 用に redis を立ち上げたいこととかありそうなので、`docker-compose.yml` にしたほうがいいのかもしれないけど、とりあえず最小限はこんな感じかな。
LaTeXでタイトル部分のページ番号を消し，タイトル以降からページ番号が始まるようにする方法

この記事は表紙のカスタマイズを行っている場合に起こるものです．

```tex:
\maketitle
```
を使ってタイトルを作成している人には関係のない話ですのでご了承ください．

表紙のカスタマイズをする場合，以下のような感じで自分で幅などを調節しながら表紙を作ります．

```tex:
\begin{center}
  \huge 論文の種類 \par
  \vspace{15mm}
  \LARGE タイトル \par
  \vspace{100mm}
  \Large ...日付 \par
  \vspace{15mm}
  \Large ...研究室 \par
  \vspace{10mm}
  \Large ..学籍番号.. 名前
  \vspace{10mm}
\end{center}
```
こんな感じのが出来上がります．

<img width="300" alt="Screenshot 2017-01-24 07.08.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/78590/f22c1421-b200-9744-d322-cdec93c0289f.png">

普通であればカスタマイズした表紙にはページ番号が入ってしまいます．

そのため自身の秘伝のタレを持ってる方は表紙の最後の部分に以下のコードを追加すると，表紙以降からページ番号が始まるようになるはずです．

```tex:
\thispagestyle{empty}
\clearpage
\addtocounter{page}{-1}
```



以下は自分がテンプレートとして使っているコードになります．
参考になれば幸いです．

```tex:main.tex
% latex uft-8
\documentclass[a4paper,11pt,oneside,openany]{jsbook}
%
\usepackage[dvipdfmx]{graphicx}
\usepackage{amsmath,amssymb}
\usepackage{bm}
\usepackage{graphicx}
\usepackage{ascmac}
%
\setlength{\textwidth}{\fullwidth}
\setlength{\textheight}{40\baselineskip}
\addtolength{\textheight}{\topskip}
\setlength{\voffset}{-0.55in}
%
\begin{document}
% START DOCUMENT
%
% COVER
\begin{center}
  \huge 平成..年度 ....\par
  \vspace{15mm}
  \huge 論文の種類 \par
  \vspace{15mm}
  \LARGE タイトル \par
  \vspace{100mm}
  \Large ...日付 \par
  \vspace{15mm}
  \Large ...研究室 \par
  \vspace{10mm}
  \Large ..学籍番号..　　　指導教員 ...\par
  \vspace{10mm}
\end{center}
\thispagestyle{empty}
\clearpage
\addtocounter{page}{-1}
\newpage
\setcounter{tocdepth}{3}
%
\tableofcontents
%
\chapter{はじめに}
%
\chapter{研究タイトル}
\section{研究背景と目的}
\section{}
\section{まとめと今後の課題}
\newpage
%
\chapter{おわりに}
\newpage
%
\section*{謝辞}
\addcontentsline{toc}{chapter}{謝辞}
%
\begin{thebibliography}{99}
  \bibitem{1}
\end{thebibliography}
%
% END DOCUMENT
\end{document}
%
```

以上になります．
では良いLaTeXライフを！

##参考サイト
TeXテンプレート - [物理のかぎしっぽ]
http://hooktail.org/computer/index.php?TeX%A5%C6%A5%F3%A5%D7%A5%EC%A1%BC%A5%C8
チートシート

最低限頭に入れておくべきコマンドのメモ（永遠に作成中）

#Linux
|コマンド|説明|
|:--|:--|
|ls|ディレクトリの内容を表示する|
|-l|詳細表示する　（パーミッション、所有ユーザ、所有グループ、ファイルサイズ、タイムスタンプ、ファイル名）|
|-a|隠しファイルを表示する|
|find||
|find ~/ -name "*ほにゃらら*"||
|~/|ホームディレクトリ|
|cp -r ディレクトリ||
|rmdir||
|rm -rf xxx|ディレクトリ名　配下のディレクトリ、ファイルを全て削除|
|sudo -s|rootにスイッチ|
|.|カレントディレクトリ|
|..|一つ上のディレクトリ|
|.profile|ログインした時に読み込まれる設定ファイル|
|.sh||
|less -N|行番号をつけてファイルを表示¥|
|/xxx|less中の下方検索|
|?xxx|less中の上方検索|
|n|less中の検索次へ|
|N|less中の検索前へ|
|wget||
|ifconfig -a||
|netstat -lantop||
|ps -a||
|./コマンド|カレントディレクトリのコマンドを実行|
|/dev/null|標準出力を捨てる|
|<< EOS ほにゃらら EOS|ヒアドキュメント|
|tee|標準入力を標準出力とファイルに出力する|
|ln -s パス|シンボリックリンク作成|
|grep xxx ./*||
|grep xxx ./||
|awk||
|which|コマンドのフルパスを確認|
|chmod +r -R ディレクトリ名|全部に読み取り権限をつける|
|#!/bin/bash -x|シェルスクリプト内で実行されたコマンドを表示する|
|netstat -anp|ポートの確認|

##Bash Shortcut Key
|コマンド|説明|
|:--|:--|
|Ctrl+A|行頭へ移動|
|Ctrl+E|行末へ移動|
|Ctrl+U|行頭まで削除|
|Ctrl+K|行末まで削除|
|ESC+F|１単語進む|
|ESC+B|１単語戻る|

#Virtualbox
|コマンド|説明|
|:--|:--|
|VBoxManage list vms||
|VBoxManage unregister vm vm名||
|||
|||

#Vagrant
|コマンド|説明|
|:--|:--|
|vagrant box list||
|vagrant up||
|vagrant up --provision||
|vagrant halt||
|vagrant box remove box名||
|||
|||

#Docker
|コマンド|説明|
|:--|:--|
|docker --version|バージョンの表示|
|docker ps|起動中のコンテナの表示|
|docker ps -a|すべてのコンテナを表示|
|docker images|イメージの一覧表示|
|docker run ほにゃらら|新しいコンテナの起動|
|docker stop コンテナ名|コンテナの停止|
|docker start コンテナ名|コンテナの再起動|
|docker rm -f コンテナ名|コンテナの削除|
|docker rmi イメージ名|イメージの削除|
|docker-compose up|コンテナの起動|
|docker-compose up -d|バックグラウンドでのコンテナの起動。設定変更後に実施すると、コンテナの停止・再起動を行う（volumeはそのまま保持）|
|docker-compose up -d --force-recreate|強制的に全てのコンテナを停止・再作成|
|docker-compose down|コンテナの停止(コンテナ上の変更は消える)|
|docker-compose kill|コンテナ停止（コンテナ上の変更が残る）|
|docker exec -it コンテナ名　/bin/bash|コンテナに入る|
|docker logs コンテナ名|コンテナのログを表示|
|docker inspect -f "{{.NetworkSettings.IPAddress}}" CONTAINER|IPアドレスを調べる|

#Git
|コマンド|説明|
|:--|:--|
|git clone||
|git branch||
|git branch -r|リモートブランチ一覧|
|git checkout ブランチ名||
|git pull origin master|最新を取る|
|git tag -l|タグの一覧|
|git checkout refs/tags/v1.6|タグに切り替え|

#MAC OS
|コマンド|説明|
|:--|:--|
|chmod 600 ~/.ssh/xxxx.pem|秘密鍵のパーミッション変更|
sudo ssh -i "/Users/ユーザー名/.ssh/xxxx.pem" ec2-user@IPアドレス|MacのterminalでEC2のAmazon Linuxにキーペアを使ってssh接続|
|sudo scp -i /Users/ユーザー名/.ssh/xxx.pem index.html ec2-user@IPアドレス:~/|- MacのterminalでSCP（公開鍵認証）|

- Macのスクリーンロック

> Ctrl + Shift + 電源ボタン

- MacのFinderでパスをコピー

> 右クリック+optionキーでパスをコピー

- ThinkpadのFnキーの切り替え方

> Fn + ESC

- BoxとVMの消し方
    - VirtualBox VMsを消す
    - VBoxManage unregister vm vm名
    - vagrant box remove box名

- Amazon Linuxの初期ユーザー/パス
    - ec2-user/パスなし
[Swift3] plistから多次元配列を読み込み、TableViewで表示する。

#はじめに

plistを使って、tableViewを作成する機会があったので、備忘録として載せます。

##plistの作成方法
xcodeの上部タブメニューより、 File>new>file.. >ios > resource　の中に、Property List　とあるので、クリック。



#plistの構成確認

`PropertyList.plist　`　という名で、下記構造のplistを作成しました。

![2017-01-24 7.40.14.png](https://qiita-image-store.s3.amazonaws.com/0/150745/4b69205b-22db-7bd5-da94-74d788faccfb.png)




#plistの読み込み



```
    //多次元配列の初期化
    var plistArr = [Dictionary<String, String>]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
　　　　　　　　　　　　　　　　　//plistを参照
        let path = Bundle.main.path(forResource: "PropertyList", ofType: "plist")

        //参照したplistを、初期化した配列に納入
        plistArr = NSArray(contentsOfFile: path!) as! [Dictionary<String, String>]
        
        
    }

 ```



#tableViewで表示


 ```


    //行数指定
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return mathArr.count
    }
    
    
    //表示内容
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "[任意]cell", for: indexPath) as![任意]cell

        cell.textLabel?.text = plistArr[indexPath.row]["title"]
        return cell
    }
    
    //タップ時の処理（例：任意のURLをWebViewControllerで表示）
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        tappedCellUrl = plistArr[indexPath.row]["url"]!
        performSegue(withIdentifier: "toWebViewController", sender: nil)
 
    }



 ```
TypeScriptのstrictNullChecksをtrueにして1ヶ月経って分かったこと

ここ一ヶ月ほどTypeScriptのNullチェック機能をONにした状態でコーディングを行っていて、気づいた点をまとめました。

# strictNullChecksの抜け道

strictNullChecksの機能を有効化することで、undefined、null、それ以外がコンパイラによって区別され、
Null参照エラーによるバグやNull判定文を減らすことが出来ます。

ただし、全てのエラーが静的チェックできるわけではなく、以下のケースではundefinedが入力出来てしまいます。

## 初期化されていないインスタンス変数

```js

class Hoge {
  a: string;
}
const b: string = new Hoge().a; // コンパイルOK

const len = b.length // 実行時エラー

```

## 初期化されていないエンクロージャスコープ内の変数

```js

let c: string; // コンパイルOK

let hoge = () => {
  return c.length; // 実行時エラー
};
hoge();


```

## 配列(Array)の範囲外

```js

const a: number[] = [];
const b: number = a[1]; // コンパイルOK

b.toFixed(0); // 実行時エラー


```

## Objectの定義されてないキー

```js

const a: {[key: string]: string}} = {};
const b: string = a["test1"]; // コンパイルOK　

b.length; // 実行時エラー

```

## importする型定義ファイルがstrictNullChecksに対応していない場合

importするライブラリの定義ファイルがstrictNullChecksに対応していない場合は、当然すり抜けてしまいます。
ちなみに、DefinitelyTypedに登録してある定義ファイルは、私の知る限り現時点では対応されていないようです。


# 抜け道対策

上記の様なケースを考慮する為に、Null判定のif文を増やしてしまってはstrictNullChecksの効果が半減するので、
ある程度のコーディング規約を決めて置く必要があります。


## ローカル変数は定義時に初期化

特別な理由がない限り、ローカル変数は定義時に初期化出来るはずです。

```js

let c: string = "hoge";

```

## インスタンス変数はコンストラクタで全て初期化

コンストラクタでの変数初期化は性能にも寄与します。

```js

class Hoge {

  a: string;
  b: number;

  constructor(){
    this.a = "hoge";
    this.b = 0;
  }
}

```

## Map,Setを利用する。

Array、Objectはそれぞれ専用のラッパーを通してアクセスすることで、undefinedチェックの責務を
集中させることが効果的です。（性能を考慮すると、全ての場面で有効ではないですが。）

また、ES6の Map、Setのメソッドを通したアクセスは静的チェックが効くので利用可能な場合は積極的に利用するのが良いと思います。

```js

const map = new Map<string, string>();
map.get("hoge").length; // コンパイルエラー

```

# まとめ

DefinitelyTypedなどの公開定義ファイルは、後方互換を考えると定義ファイルを２重で用意する必要があるので、
strictNullChecksへのハードは高く結合部分はどうしてもNull判定文を入れる必要が出てきます。

それでも、疎結合を意識してコーディングすればstrictNullChecks現状でも十分強力に働くので、今後も積極的に利用していきたいと思います。
第61回 WordBench大阪「Webデザイナーとディレクターのためのマーケティング入門」に参加してきた

2017/01/21に開催された[Webデザイナーとディレクターのためのマーケティング入門](https://wbosaka.connpass.com/event/48078)に参加してきました

#勉強会ノート

##Webサイトの形
パンフレット型

* 社名を検索したとき「**とにかくちゃんとしていること**」が大事
* Webでの集客

ブランディング型

* 社名、製品、サービスが既に世間に認知されている
* 予算が多い、メディアミックス展開している
* 大企業

新規顧客獲得型

* webでの集客を期待したもの
* 広告予算が少ない企業

→Webマーケティングの戦略が重要

##Webサイトを構築したけれど、問い合わせが来ない、成果に繋がらないのはなぜ？
問い合わせ数はこうして決まる
問い合わせ数=アクセス数✕コンバージョン率
アクセス数：打席数
コンバージョン率：打率
みたいなもの
打率が高くても打席に立たなければヒットは打てない
打率が低ければなおさら
限られた資源の中でやっていくには「**戦略=マーケティング**」が必要

##アクセス数
どれくらい必要？
具体的な目標を設定してみて仮説を立てる
例：毎月10件の問い合わせがあって3件くらい成約したい
例えば「サイトを通じて問い合わせ」ということを目標としたとき一般的には1%弱のコンバージョン率のようだ
ということは最低でも1,000件のユニークユーザーのWebサイトのアクセスが必要
もちろん成果として考えた場合、来た問い合わせを確実にクロージングに持っていける営業力も大事

##アクセス数を上げるには
* お金を掛ける
* 手間を掛ける

###お金を掛ける
リスティング広告

* キーワードにマッチした時に表示される広告=すぐ成約に繋がる客の獲得に効果的
* どんなキーワードにするかが大事=検索されないキーワードに広告を設定しても無駄
* 料金は入札形式
* 掲載順位は「入札価格」×「広告品質」
* 予算規模：3万円/月くらいから
* 初期ブーストには効果的
* 出稿を止めると成果ガタ落ちかも
* 永遠に出稿し続けないといけない無限地獄かも(売上を広告費として注ぎ込み続けてしまう)
* 広告に頼らずに売れるしくみの構築を意識する

##手間を掛ける
ブログを書く
書いた記事はWebサイトの資産になる→資産になる記事を書く
記事を書くポイント

* 需要がある記事
* 1,000文字程度→大人が1分間に読める文章量は少ない人で500文字、特別に読むのが早い人では1,500字程度
* 網羅性→そのキーワードで検索している人が知りたいであろうことをすべて書く
* 独自性→他の記事にはないオリジナリティ

忘れてはいけないのが「**地道に書き続けないと効果がでない**」ということ

* 即効性がない
* 長期戦になるので結局手間もお金(人件費的に)もかかる

##コンバージョン率
サイト全体の訪問者の内「Webサイトで設定した目標」が達成された確率
Webサイトで設定した目標の例：

* 資料請求される
* 問い合わせがあった
* 商品が売れた

###コンバージョン率が高いサイト
顧客(潜在顧客)の

* 悩みごと、困りごとの解決(のヒント)
* 答えがズバリ
* 内容が共感できる、納得できる

要は顧客(潜在顧客)の**欲求**が何らかの形で満たされる→問い合わせ、購入などの**具体的な行動**に繋がる

ということは自社のWebサイトに

* 悩みごと、困りごとの解決(のヒント)
* 答えがズバリ
* 内容が共感できる、納得できる

のコンテンツを盛り込こんでいくことで、コンバージョン率を向上させられるんじゃないか？

###コンテンツを提供する側(Webサイトを運営している側)は本当に顧客の気持ちがわかっているのか？
独りよがりになっていないか？
顧客が知りたいコトとコンテンツを提供する側が伝えたいコトのミスマッチ
顧客がわからないコト、知りたいコトがわかっていない
業界にいる期間が長ければ長いほど「その業界のプロ」になってしまって、業界の外の人のわからないコト、知りたいコトが見えなくなっていないか
業界の常識は世間の非常識
前提条件、専門用語
自分で「自分のスゴさ」はわかっていないことが実は多い
自分が当たり前にやっていることを、みんなができるとは限らない

###顧客の気持ちを知る

* アンケートを取ってみる
* 顧客へ取材をしてみる
* 成功事例を集める
* Webサイトのアクセス分析
* リアルやネットで調べてみる

####アンケートを取ってみる
「A4 1枚アンケート」で検索
「A4」1枚販促アンケート広告作成アドバイザー協会ってところがあるレベル
取り入れない手はない
集めた結果の使い方を間違えない=ネガティブな意見を気にしない
ネガティブな部分を消すより、「他より強いところ」を見つけることにフォーカスする
なにを目的としたアンケートなのかを見失わない

####顧客へ取材をしてみる
アンケートではなく顧客に足を運ぶ
データ分析などのデジタルではわからないアナログな情報
取材内容を「お客様の声」として使う→これは大きい成果(コンテンツ)になる
不安要素も聞いてくる→業務改善に繋げられる(かも)
そもそも数をこなせないため、少数意見に引っ張られない

####成功事例を集める
成功事例は「他社と比較して選ばれた」事例
事例の中にこそオリジナリティが現れる
一番多かったパターンに「自社の強み」がある

####Webサイトのアクセス分析
成果に繋がったアクセスと繋がらなかったアクセスを比較する
どのキーワードで流入したアクセスがコンバージョンしているか
そもそもWebサイトのアクセス解析がされていない場合は為す術なし
→今すぐ設定
アクセス数が少ないサイトは有意な結果が出ない
→まずアクセス数を増やすアプローチ

####リアルやネットで調べてみる
類似なものの顧客について調べてみる
身近な人に居たら聞いてみる
ネットで体験談、口コミを検索してみる
「製品名(カテゴリ名) 事例」、「製品名(カテゴリ名) よくある御質問」、「製品名(カテゴリ名) お客様の声」

##Webサイトに繋げる
シナリオを書く
どういうキーワードで流入してきてどういうコンテンツを見て最終的にどういうアクションを取るのかというシナリオを書く
→サイトマップに落とし込めば用意すべきコンテンツが見えてくる
anaconda導入

*gitに必要なライブラリを導入*

~~~
$ yum -y install curl-devel expat-devel gettext-devel openssl-devel zlib-devel
~~~

*gitのインストール*

~~~
$ yum install git
~~~

*pyenvのインストール*

~~~
$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
~~~

*pyenvのパス通す*

~~~
$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
$ source ~/.bashrc
~~~

*anacondaをインストールする*

~~~
# 最新版を確認。anaconda3-4.0.0
# minicondaがいい人はminicondaを入れてください。
$ pyenv install -l | grep ana
$ pyenv install anaconda3-4.0.0
$ pyenv rehash
# anacondaをメインのpythonに設定。
$ pyenv global anaconda3-4.0.0

$ echo 'export PATH="$PYENV_ROOT/versions/anaconda3-4.0.0/bin/:$PATH"' >> ~/.bashrc
# activateがpyenvとanacondaでバッティングするので、pathに明示しておく。
$ source ~/.bashrc
#念のためconda自体をアップデートしておく。
$ conda update conda
~~~


>同一システム上でPython複数環境の構築
>http://qiita.com/yuichy/items/8cd43a667fb4659d89e9
>Python数値計算環境Anacondaの導入
>http://morimori2008.web.fc2.com/contents/PCprograming/python/pythonAnaconda.html
>Pythonで機械学習アプリケーションの開発環境を構築する
http://qiita.com/icoxfog417/items/950b8af9100b64c0d8f9
>データサイエンティストを目指す人のpython環境構築 2016
>http://qiita.com/y__sama/items/5b62d31cb7e6ed50f02c
>CentOSにpyenvを利用してAnacondaをインストール
>http://pppurple.hatenablog.com/entry/2016/05/07/211558
ファイル名を一括変換するコマンド一覧

# for文を使う
正直これが一番わかりやすくて楽。

### ファイル名を一括変換するコマンド

```
% for f in `ls`; do mv $f ${f/変えたい部分/変える部分}; done
```

### ファイル名の一部を一括削除するコマンド
```
% for f in `ls` ; do mv "$f" "${f#消したい部分}" ; done
```

# findを使う
これはややこしかった。
for文の方がおすすめ


### ●ファイル名の先頭にキーワードを付け加える

```
% find /作業するPATH -type f -print0 | awk -F/ '{print $NF}' | xargs -I% mv 作業するPATH/% 作業するPATH/付与したい単語%
```

### ●ファイル名の末尾にキーワードを付け加える

```
% find /作業するPATH -type f -print0 | xargs -0 -I% mv % %付与したい単語
```

### ●ファイル名の先頭にあるキーワードを削除する

```
% find /作業するPATH -type f -print0 -name "削除したい*" | perl -pe 's/削除したい単語//g' | xargs -0 -I% mv 削除したい単語% %
```

### ●ファイル名の末尾にあるキーワードを削除する

```
% find /作業するPATH -type f -print0 -name "*削除したい単語" | perl -pe 's/削除したい単語//g'
```

 　
***
　　
renameという便利なやつがあるらしいけどMacOSXでは使えなかったので割愛

## スペースが含まれるファイル名の場合

（追記）

```
% for f in `ls`;...
```

この書き方では、スペース（環境変数$IFS）が含まれるファイル名を正しく取り扱えないらしい。
なので、globを使って下のように書きます。

```
% for f in *;...
```

これならドットファイル以外の全てのファイル名を取り出せます。
技術英語 > you'd know that flattery will get you nowhere. / here, there, and everywhere

@ Star Trek Voyager > TUVIX

TUVIXとの会話でJanewayが

> you'd know that flattery **<font color=red>will get you nowhere</font>**.

意訳「おだてたってなにもならないですよ」

<hr>
関連して思い出したのは

> here, there, and everywhere

https://www.merriam-webster.com/dictionary/here,%20there,%20and%20everywhere

> :  in an arbitrary location
CraftCMS をインストールする

## Craft CMS
https://craftcms.com/

[Craft CMS Advent Calendar 2016 - Adventar](http://www.adventar.org/calendars/1400)

## システム要件
https://craftcms.com/docs/requirements
#### サーバー要件
* PHP 5.3.0 以上
* MySQL 5.1.0 以上 (InnoDB ストレージエンジン)
* Web サーバー (Apache, Nginx, IIS)
* 32MB以上の PHP へのメモリ割り当て
* 20MB以上の空き容量
* 1MB以上のデータベース容量

#### 必須 PHP エクステンション
* Reflection Extension
* PCRE Extension
* SPL Extension
* PDO Extension
* PDO MySQL Extension
* Mcrypt Extension
* GD Extension with FreeType Support (unless ImageMagick Extension is installed)
* OpenSSL Extension
* Multibyte String Extension
* JSON Extension
* cURL
* crypt() with BLOWFISH_CRYPT enabled

## 構成例
* CentOS 7.3.1611 (minimal)
* Apache 2.4.6 (base)
* PHP 5.4.16 (base)
* MariaDB 5.5.52 (base)

## インストール
```
yum -y install epel-release
yum install httpd php php-{gd,mbstring,mcrypt,mysql,xml} mariadb-server unzip
curl -LO https://download.craftcdn.com/craft/2.6/2.6.2989/Craft-2.6.2989.zip
unzip Craft-2.6.2958.zip -d /var/www
mv /var/www/public/{index.php,robots.txt} /var/www/html
mv /var/www/public/htaccess /var/www/html/.htaccess
cat << "_EOF_" > /etc/httpd/conf.d/craft.conf
<Directory "/var/www/html">
    AllowOverride All
</Directory>
_EOF_
systemctl start httpd mariadb && systemctl enable httpd mariadb
firewall-cmd --permanent --add-service=http && firewall-cmd --reload
chmod -R 744 /var/www/craft/{app,config,storage}
setenforce 0
cat << "_EOQ_" | mysql -u root -p
CREATE DATABASE `craft` CHARACTER SET 'utf8';
CREATE USER 'craft'@'localhost' IDENTIFIED BY 'craft';
GRANT ALL ON craft.* TO 'craft'@'localhost';
_EOQ_
sed -i.org "/'database'/s/''/'craft'/" /var/www/craft/config/db.php
```
http://192.168.56.101/admin にアクセス

![craft1.png](https://qiita-image-store.s3.amazonaws.com/0/15175/4e7b0476-2fae-97a6-fc46-e579ab86fc6d.png)

![craft2.png](https://qiita-image-store.s3.amazonaws.com/0/15175/e38467e2-e12a-36e1-5475-88d649667c11.png)

![craft3.png](https://qiita-image-store.s3.amazonaws.com/0/15175/4a49019c-6966-69d7-da19-ad086b251abd.png)

![craft4.png](https://qiita-image-store.s3.amazonaws.com/0/15175/33cb1f1b-f448-0c93-2c9c-8fa83d102dda.png)

## 管理画面
### ダッシュボード
![craft5.png](https://qiita-image-store.s3.amazonaws.com/0/15175/d4afb33e-d2fa-b5d8-e925-f8136306187b.png)
### エントリ一覧
![craft6.png](https://qiita-image-store.s3.amazonaws.com/0/15175/e2f9f39a-c080-6cbf-da31-434ec1589af7.png)
### 編集画面
![craft7.png](https://qiita-image-store.s3.amazonaws.com/0/15175/0d038f48-c594-f999-a728-5df357327328.png)
### ライブプレビュー
![craft8.png](https://qiita-image-store.s3.amazonaws.com/0/15175/559c12a8-0084-f434-9942-8259a3655e45.png)
### 設定画面
![craft9.png](https://qiita-image-store.s3.amazonaws.com/0/15175/f3508bd9-f6b8-25c8-8a4a-42aed3f57889.png)
bashの組み込みコマンドをつくる

　概要です。

- [bash の組込みコマンド自作によるスクリプトの高速化 - Qiita](http://qiita.com/satoru_takeuchi/items/7d424fa5ef1e33ace4df)

共有ライブラリをつくれば良いことがわかったのでやっていきます。

## 実装する

　型などを定義します。スレッドローカルではない値を定義するために `Sync` をつけているんですけど、これが何を意味しているのかは謎です。俺たちは雰囲気で Rust をやっている。

```rust
const EXECUTION_SUCCESS: c_int = 0;
const BUILTIN_ENABLED: c_int = 0x01;

#[repr(C)]
pub struct WORD_DESC {
  word: *mut c_char,
  dollar_present: c_int,
  quoted: c_int,
  assignment: c_int,
}

#[repr(C)]
pub struct WORD_LIST {
  next: *mut WORD_LIST,
  word: *mut WORD_DESC,
}

pub type sh_builtin_func_t = extern fn (*mut WORD_LIST) -> c_int;

#[repr(C)]
pub struct builtin {
  name: *mut c_char,
  function: sh_builtin_func_t,
  flags: c_int,
  long_doc: *mut *const c_char,
  short_doc: *mut c_char,
  handle: *mut c_char,
}

unsafe impl Sync for builtin {}
```

コマンドを実装します。文字列の定義がとにかく厳しくて、null 終端の byte string を二回キャストしてポインタを取るみたいなことをしています。

```rust
pub extern fn hello_world(_list: *mut WORD_LIST) -> c_int {
  println!("Hello, World!");
  EXECUTION_SUCCESS
} 
  
const LONG_DOC: &'static [*const c_char] = &[
  b"Show a greeting message.\0" as *const _ as *const _,
  b"\0" as *const _ as *const _,
  b"It's far faster than launching executable file\0" as *const _ as *const _,
  b"because it't not necessary to call exec() and fork().\0" as *const _ as *const _,
  0 as *const _,
];

#[no_mangle]
pub static mut hello_world_struct: builtin = builtin {
  name: b"hello_world\0" as *const _ as *mut _,
  function: hello_world,
  flags: BUILTIN_ENABLED,
  long_doc: LONG_DOC as *const _ as *mut _,
  short_doc: b"hello_world\0" as *const _ as *mut _,
  handle: 0 as *mut _,
};
```

共有ライブラリとしてビルドします。`cdylib` と書くべきところを `dylib` と書いて少しハマりました。具体的には、リリースビルドをしたときに文字列のあたりがおかしくなります。

```toml:Cargo.toml
[package]
name = "hello_world"
version = "0.1.0"
authors = []

[lib]
name = "hello_world"
path = "./lib.rs"
crate-type = ["cdylib"]
```

```shell-session
$ cargo build --release
   Compiling hello_world v0.1.0 (file:///Users/woxtu/Workspace/hello_world)
    Finished release [optimized] target(s) in 0.29 secs
```

以上です。

## 呼び出す

　先につくった共有ライブラリを組み込みます。

```shell-session
$ enable -f target/release/libhello_world.dylib hello_world
$ enable | grep hello_world
enable hello_world
```

コマンドを呼び出します。

```shell-session
$ hello_world
Hello, World!
```

```shell-session
$ help hello_world
hello_world: hello_world
    Show a greeting message.
    
    It's far faster than launching executable file
    because it't not necessary to call exec() and fork().
```

やりました。以上です。

## 終わりに

　組み込みコマンドはともかく、共有ライブラリがつくれるということは他言語との連携も取りやすいということなので、仲良くしていくと良いんじゃないかと思います。各位、仲良く。

　コードは Gist に上げてあります。

- https://gist.github.com/woxtu/57697a2f1c51b4e59e87a4b7f9f92047

## 参考

- [Foreign Function Interface - The Rust Programming Language](https://doc.rust-lang.org/stable/book/ffi.html)
- [Alternative representations - The Rustonomicon](https://doc.rust-lang.org/nomicon/other-reprs.html)
- [rustc: Add a new crate type, cdylib - rust-lang/rust - GitHub](https://github.com/rust-lang/rust/pull/33553)
.htaccessによる条件分岐(mod_rewrite) プログラマらしく書くには

#はじめに
こんにちは、chrです。
みなさん、mod_rewrite書いてますか？
リダイレクトの時に使う方や、FWと連携させるのに使う方もいると思います。

サイトのリニューアルを行っていると、定義の量が増えると行数も多く、同じことを何度も書いているなぁと感じてました。

そこで、自分なりにmod_rewriteの書き方のベストプラクティスと感じた方法を共有します。

#結論
* 環境変数を使おう
* 環境変数使えば、何度も同じことを書かなくて良い
* プログラマっぽい考え方でmod_rewriteを書ける
* ただ、mod_rewriteへ求める要件が多くないと、コード量が増えるだけになるかも

#環境変数の定義方法
* RewriteRuleのoptionの値で定義します

```apache:.htaccess
RewriteRule ^lp/(.*)$ index.php?path=$1 [L,E=LP_REQUEST:On]
```
* E=が環境変数の定義開始記号、LP_REQUESTが環境変数名、Onが値です
* 環境変数を取得する場合は、以下のように書く事で取得できます

```apache:.htaccess
##環境変数で分岐
RewriteCond %{ENV:LP_REQUEST} ^On$
##環境変数をRewriteRuleの値内で使用(lp/hoge/へアクセスがあるとOnへrewriteされる
RewriteRule ^lp/hoge/$ %{ENV:LP_REQUEST} [L]
```
* これらを組み合わせることで、複雑な条件でも可読性を高めることができます


#改善したい例
* スマホで/sp/以外のURLへアクセスがあったら、/sp/配下の同一パスへリダイレクト
* スマホで/sp/配下のURLへアクセスがあったら、/の同一パスへリダイレクト
* デバイス：PC
    * http://example.com/ -> リダイレクトしない
    * http://example.com/hoge -> リダイレクトしない
    * http://example.com/sp/ -> http://example.com/ へリダイレクト
    * http://example.com/sp/hoge -> http://example.com/hoge へリダイレクト
* デバイス：スマートフォン
    * http://example.com/ -> http://example.com/sp/ へリダイレクト
    * http://example.com/hoge -> http://example.com/sp/hoge へリダイレクト
    * http://example.com/sp/ -> リダイレクトしない
    * http://example.com/sp/hoge -> リダイレクトしない
    
##良くある書き方でmod_rewriteを書いてみる
```apache:.htaccess
RewriteEngine On
##スマホデバイスの場合はリダイレクト
RewriteCond %{REQUEST_URI} !/sp/
RewriteCond %{HTTP_USER_AGENT} (iPod|iPhone|iPad|Android|Windows\ Phone)
RewriteRule ^(.*)$ http://example.com/sp/$1 [QSA,L,R=302]

##スマホデバイス以外の場合はリダイレクト
RewriteCond %{REQUEST_URI} /sp/
RewriteCond %{HTTP_USER_AGENT} !(iPod|iPhone|iPad|Android|Windows\ Phone)
RewriteRule ^sp/(.*)$ http://example.com/$1 [QSA,L,R=302]
```
##変更した例
```apache:.htaccess
#全てのデバイスをPCとして変数定義、デバイスの違いによるリダイレクトは常に有効とする
RewriteRule .* - [E=DEVICE:PC]
#スマートフォンからのリクエストの場合は、デバイスをSPとする
RewriteCond %{HTTP_USER_AGENT} (iPod|iPhone|iPad|Android|Windows\ Phone)
RewriteRule .* - [E=DEVICE:SP]
#スマートフォン用のURL定義
RewriteRule .* - [E=URL_SP:/sp/]

#リダイレクトの適応 PCで/sp/へアクセス
RewriteCond %{ENV:DEVICE} ^PC$
RewriteCond %{REQUES_URI} ^%{ENV:URL_SP}
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [QSA,L,R=302]
#リダイレクトの適応 SPで/sp/以外へアクセス
RewriteCond %{ENV:DEVICE} ^SP$
RewriteCond %{REQUEST_URI} !^%{ENV:URL_SP}
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{ENV:URL_SP}$1 [QSA,L,R=302]

##RewriteRuleの値で入力している「-」は「置換しない」です
```
* これだけ見ると、コード量が増えて、複雑化しているように見えます
* ですが、スマートフォンと判別するデバイスが増えた場合の変更箇所数はどうでしょうか
* URLにフラグがついていたらリダイレクトさせないといった処理や
* 本番環境のみ全ページSSLページへリダイレクトさせるといった処理が追加されたり
* ホスト名統一したいが、テスト環境ではホスト名がtestだったりと環境による違いがあったり。。。
* mod_rewriteへ求める要件が複雑化してきたら、導入をおすすめします
複数ログファイルをgrepしてマッチした行数を出力するシェルスクリプト

この記事は移行しました！[最新の内容はこちら](https://naoqoo2.github.io/blog/%E8%A4%87%E6%95%B0%E3%83%AD%E3%82%B0%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92grep%E3%81%97%E3%81%A6%E3%83%9E%E3%83%83%E3%83%81%E3%81%97%E3%81%9F%E8%A1%8C%E6%95%B0%E3%82%92%E5%87%BA%E5%8A%9B%E3%81%99%E3%82%8B%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88/)をご覧ください😀

下記のようなことをしたいとき、ありますよねー。

- エラーログから特定のエラーが何回発生したか知りたい
- アクセスログから特定のページへのアクセス数を知りたい


複数ファイルをgrepしてマッチした行数をファイル毎に出力するシェルスクリプトです。
※ログなど圧縮済ファイルを想定してるのでzgrep。


```bash:複数ログファイルをgrepしてマッチした行数を出力

# 検索したい文字列
grep_words=()
grep_words[0]="Warning"
grep_words[1]="Notice"

# grep対象のファイル名を宣言
target_files=()
target_files[0]="error_log-20170101.gz"
target_files[1]="error_log-20170102.gz"
target_files[2]="error_log-20170103.gz"

# 検索文字列でループ
for grep_word in ${grep_words[@]}; do
    # 出力ファイルを空に（2回実行した場合に追記しないように）
    echo -n > tmp/grep_${grep_word}.txt
    # grep対象のファイル名でループ
    for target_file in ${target_files[@]}; do
        # 実行コマンドをコンソールに出力したうえで実行。ログに追記。
        echo "zgrep -c \"${grep_word}\" ${target_file}"
        hit_count=`zgrep -c "${grep_word}" ${target_file}`
        echo "${grep_word} ${target_file} ${hit_count}" >> tmp/grep_${grep_word}.txt
    done
done

```

出力結果はこんな感じ。

```text:tmp/grep_Warning.txt
Warning error_log-20170101.gz 24
Warning error_log-20170102.gz 35
Warning error_log-20170103.gz 103
```

```text:tmp/grep_Notice.txt
Notice error_log-20170101.gz 235
Notice error_log-20170102.gz 321
Notice error_log-20170103.gz 513
```



適宜書き換えてもらえればいろいろ使えるかと。
WrapBootstrapを使ったRailsアプリ作成

## はじめに
この記事では、WrapBootstrapというデザインテンプレートを使用したRailsアプリを起動する手順を書きます。
WrapBootstrapを使用することで、WEBアプリ開発におけるデザイン工程を大幅に効率化することができます。

## 手順
- WrapBootstrapのサイト( https://wrapbootstrap.com/ )からテンプレートを購入します。大体、4~20$くらいで購入できます。今回は、「Angle - Bootstrap Admin Template」というテンプレートを使用します。

- 購入したテンプレートをダウンロードして解凍し、「backend-rails」ディレクトリ配下のRailsルートディレクトリに移動します。

    ```
    cd backend-rails/Angle
    ```
- gemをインストール

    ```
    bundle install --path vendor/bundle
    ```

- Bowerをインストール ※既にインストール済みの場合は不要

    ```
    brew install node.js
    node -v
    npm install bower -g
    bower -v
    ```

- ライブラリをダウンロード

    ```
    bundle exec rake bower:install
    ```

- Railsを起動

    ```
    bundle exec rails s -d
    ```

- http://localhost:3000 にアクセスすると無事、画面が表示されました。
<img width="1435" alt="スクリーンショット 2017-01-24 1.46.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/161201/6abba1a0-d8ae-545e-e3e8-524348111307.png">

## 参考資料
http://blog.jnito.com/entry/2017/01/05/071101
http://blog.mah-lab.com/2014/04/14/bower-rails/
Raspbinan JessieLite にnginx 1.10をソースビルドインストールする

過去記事：[nginxの出力先をカスタマイズする](http://qiita.com/KurokoSin/items/81d29ad8892cc18ea6ac)

# 概要
Raspberry Piにphpサーバを立てたくて、まずWebサーバとしてNginxをインストールします。
自分が前に書いたことを思い出しながら、やってます。

# 環境

| | |バージョン|
|:--:|:--:|:--:|
|OS |Raspbian |Jessie Lite |
|Webサーバ |Nginx |1.10.2 |

## 目指す構成
実行本体とドキュメントを分離して、一時的なものは全てtemp配下で細かく分ける様にします。

```
${NGINX_ROOT}
  　＋－－－1.10.2
      　＋－－sbin
      　＋－－conf
    ＋－－－running
        ＋－－logs
        ＋－－html
        ＋－－temp
           ＋－client_body_temp
           ＋－proxy_temp
           ＋－fastcgi_temp
           ＋－uwsgi_temp
           ＋－scgi_temp
（デフォルトでは～_tempのディレクトリがlogsとかと一緒の場所に作成されてしまい、
　htmlとかlogsの存在が埋もれてしまいそうになる。）
```

# インストール
## アカウント作成
```
$ sudo bash
$ mkdir /opt/nginx
$ groupadd -r web
$ useradd -r -g web -d /opt/nginx -s /usr/sbin/nologin nginx
$ chown -R nginx:web /opt/nginx
$ exit
```
## PCREのインストール
```
$ wget https://ftp.pcre.org/pub/pcre/pcre-8.39.tar.gz
$ tar zxf pcre-8.39.tar.gz
$ ./configure
$ make
$ sudo porg -lD make install
```
コンパイル時に必要となるライブラリを入れておきます

## ソースダウンロード&解凍
```
$ wget https://nginx.org/download/nginx-1.10.2.tar.gz
$ tar xzf nginx-1.10.2.tar.gz
```

## コンパイル＆インストール
```
$ cd ./nginx-1.10.2/
$ ./configure --user=nginx --group=web \
    --with-http_ssl_module \
    --with-http_random_index_module \
    --with-http_dav_module \
    --without-select_module \
    --with-pcre=/home/pi/pcre-8.39 \
    --prefix=/opt/nginx/running \
    --sbin-path=/opt/nginx/1.10.2/sbin/nginx \
    --conf-path=/opt/nginx/1.10.2/conf/nginx.conf \
    --pid-path=/var/run/nginx.pid \
    --lock-path=/var/lock/subsys/nginx \
    --http-client-body-temp-path=temp/client_body_temp \
    --http-proxy-temp-path=temp/proxy_temp \
    --http-fastcgi-temp-path=temp/fastcgi_temp \
    --http-uwsgi-temp-path=temp/uwsgi_temp \
    --http-scgi-temp-path=temp/scgi_temp
```
設定項目は以下の通りです。

|オプション|意味　|
|:-------|:-------|
|--with-http_ssl_module |SSLを使用する |
|--with-http_random_index_module |ページ内の一部をランダムに差し替えるモジュールの使用 |
|--with-http_dav_module |WebDAV機能を使用する |
|--with-http_fastcgi_module |fastcgiを使用する(PHPで使う) |
|--with-pcre=DIR |PCREライブラリーの**ソース**ディレクトリ(ライブラリ本体ではありません） |
|--prefix　以降|ディレクトリの設定 |


```
$ make
$ porg -lD make install
```
最後に`make install`のところですが、ソースビルドしながらパッケージ管理風にしていくため、`porg`をかぶせています。

## ディレクトリ作成
```
$ mkdir /opt/nginx/running/temp
$ sudo chown -R nginx:web /opt/nginx/
```

## 動作確認
```
$ /opt/nginx/1.10.2/sbin/nginx -v
```

pcreのソースディレクトリ設定を抜いて`./configure`したとき、
以下のエラーが発生しました。

```
nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory
```
対処方法として、後からシンボリックリンクを追加する方法もありますが、
なんとなく気持ち悪いので、./configureの時にオプションの指定で対処しましました。
（上記の`./configure`はやり直した結果のコマンドです。）
GitLab 8.16 リリース

# GitLab 8.16 リリース
毎月恒例の [GitLab 8.16 がリリース](https://about.gitlab.com/2017/01/22/gitlab-8-16-released/)されました。

8.16 になったからというわけではないとは思うのですが、フルセットの GitLab を Google Computing Engine にデプロイするデモが上がっていました。

[![Google Computing Engine demo](http://img.youtube.com/vi/3A8mdJl_icM/0.jpg)](http://www.youtube.com/watch?v=3A8mdJl_icM)

GitLab はもちろんですが、以下のものも同時にセットアップされます。

* auto-scaling CI
* auto deploy to your own Kubernetes cluster
* GitLab Mattermost
* your private Docker registry
* set up certificates using Let's Encrypt


## 変更点
[8.16 での変更点](https://about.gitlab.com/2017/01/22/gitlab-8-16-released/)の中から、個人的に気になるものをピックアップします。


### Monitoring GitLab with Prometheus
[Prometheus](https://prometheus.io/)での[モニタリングができるようになった](https://docs.gitlab.com/ce/administration/monitoring/performance/prometheus.html)ようです。不勉強であまり知らないのですが、オープンソースの運用監視ツールです。

しかも、Omnibus Package には最初から含まれているようで、`prometheus['enable'] = true` を `/etc/gitlab/gitlab.rb` に追加し、`gitlab-ctl reconfigure` を実行するだけで、`http://gitlab.example.com:9090` にアクセスするだけで Prometheus での監視ができるようになります。

![prometheus.png](https://qiita-image-store.s3.amazonaws.com/0/103982/67c9b600-2dfb-372e-9ebc-d29c81c970db.png)


将来的には、GitLab CE の監視だけでなく、デプロイ先の環境の監視もできるようになるようです。

### Time Tracking in CE and API
GitLab EE に 8.14 で導入された [Time Tracking](https://docs.gitlab.com/ce/workflow/time_tracking.html) が GitLab CE にも導入されました!

Issue や Merge Request に作業時間の見積もりと実績時間の入力ができます。GitLab CE は会社内で使われることも多いため、この機能を待ち望んでいた人も多いのではないでしょうか?

[API も整備されました](https://docs.gitlab.com/ce/api/issues.html#set-a-time-estimate-for-an-issue)ので、様々なことに使えそうですね!


### GitLab Pages in 8.17
待望の GitLab CE への GitLab Pages の導入は、残念ながら来月の 8.17 からになるようです。来月まで首を長くして待つことにします。


### Deploy keys with write access
GitLab では、CI などで使うためのデプロイキーを発行することができました。ですが、こちら、リードオンリーだったので、CI でビルドした成果物をプッシュすることができませんでした。

8.16 から、書き込み可能なデプロイキーを発行できるようになりました。


### Add support for PlantUML diagrams in Asciidoc
個人的に 8.16 イチオシの機能がこれです。Asciidoc 限定ですが、[PlantUML を使って UML を書けるように](https://docs.gitlab.com/ce/administration/integration/plantuml.html)なりました!

[PlantUML](http://plantuml.com/) とは、テキストで UML 図が書けちゃうすぐれものです。こんなの感じで書けます。

```
class Hoge {
  + subscribe()
}
```

![クラス図](http://www.plantuml.com/plantuml/png/Iyv9B2vMyCXFJrMevb9Gq2ukJIfEBifCIjNGvAe50000)

別途 PlantUML Web Server を用意しなければいけませんが、GitLab のヘルプにビルド方法まで含めて書いてありましたので、簡単に構築することができました。

ついでですので、[Plant Web Server の Docker Image](https://gitlab.com/GrayBullet/plantuml-server) を作りました! これだけで起動できます。

```
$ docker run -d -p 8080:8080 registry.gitlab.com/graybullet/plantuml-server
```

GitLab CE の管理者の設定画面で PlantUML の URL を設定できます。`http://{plantuml server address}:8080/plantuml` を設定してください。

あとは、適当なプロジェクトの Asciidoc にこういう感じで書きます。

```
[plantuml]
--
class Hoge {
  + subscribe()
}
--
```

こんな感じで表示されます!

![plantuml.png](https://qiita-image-store.s3.amazonaws.com/0/103982/5c270b87-7b1e-5f6f-9e37-960b2457526e.png)

* 残念ながら、GitLab.com では有効化されていないようです
* PlantUML の公式サイトで配られている plantuml.war ファイルではうまくいきませんでした
* Markdown もそのうち使えるようになるようです ([#4048](https://gitlab.com/gitlab-org/gitlab-ce/issues/4048))


## 最後に
GitLab Pages が来月に持ち越されたのは少し残念ですが、Time Tracking がついたり、PlantUML が使えるようになったりで、個人的にはとてもうれしいです。

毎月、すごいと思わせる GitLab の開発速度はすごいですね。
Spring MVC 4　開発環境構築メモ

社内での情報共有等を目的に、開発環境の構築についてメモ。
参考になれば嬉しいです。

# 開発環境
## JDK 1.8
とにかく最新版のJDKを入れておけば良いって考え。
## NetBeans 8.2
　現時点の最新版。
　Eclipseで開発していたら謎のビルドエラー等が頻発したのでNetBeansに切り替えました。
　インストールも簡単で比較的動きが軽いので、入門には良いんじゃないかと思っています。
　（会社のPCメモリ４GBだし……）
## Tomcat 8
　現時点の最新版。
　日本語ドキュメントが多いなどの理由で社内標準に内定していました。
　GlassFishの雲行きも怪しいのでTomcatで良いかなって思っています。

# 環境構築
## JDKとNetBeansのインストール
JDKもNetBeansもOracleのサイトからダウンロードできるようですが、今回は別でインストールします。

Java SE Downloads
[http://www.oracle.com/technetwork/java/javase/downloads/index.html](http://www.oracle.com/technetwork/java/javase/downloads/index.html)

NetBeans IDE ダウンロード
[https://netbeans.org/downloads/](https://netbeans.org/downloads/)

NetBeansはJavaEE版をダウンロードしましょう。
Windowsを使っている人は、NetBeansのインストーラでTomcatを選択すると幸せになれます。
![スクリーンショット 2017-01-24 0.54.41.png](https://qiita-image-store.s3.amazonaws.com/0/160615/785ef0f8-01f9-e032-22e4-57345dd75d8f.png)

インストールが終わったらNetBeansを起動してみましょう。

## NetBeansにTomcatを追加する
Macの人はNetBeans導入時にTomcatをインストールできないので、
TomcatをダウンロードしてNetBeansに登録しましょう。
※NetBeansのインストーラでTomcatを選択した人は飛ばしてOKです。（Windowsのみ）

### Tomcatのダウンロード
とりあえず現時点の最新版(8.5.11)をダウンロード。

Tomcat 8 Downloads 
 [https://tomcat.apache.org/download-80.cgi](https://tomcat.apache.org/download-80.cgi)
![スクリーンショット 2017-01-23 23.38.06.png](https://qiita-image-store.s3.amazonaws.com/0/160615/d8489ec0-f173-e2b9-594e-ddbae43a4614.png)

### Tomcatの展開
GlassFishと同じ、NetBeansのインストール先にunzipする。
※正直どこでもいいっちゃどこでもいい。

```Terminal.
$ cd Downloads
$ sudo unzip apache-tomcat-8.5.11.zip -d /Applications/NetBeans
```

### NetBeansにTomcatサーバを登録
1. NetBeansを起動
[画面上部メニュー]-[ツール(T)]-[サーバー(S)]を選択。
    <img width="229" alt="スクリーンショット 2017-01-23 23.30.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/160615/102708fd-1387-db5e-ebec-28689d547b3b.png">

2. [サーバーの追加(A)...]を選択
　　　　![スクリーンショット 2017-01-23 23.30.23.png](https://qiita-image-store.s3.amazonaws.com/0/160615/6ef2cc8c-49cc-4b30-e55b-8bc452239526.png)

3. [Apache TomcatまたはTomEE]を選択して[次>]
　　　　![スクリーンショット 2017-01-23 23.30.37.png](https://qiita-image-store.s3.amazonaws.com/0/160615/d0c28ee9-2fc4-9e7a-2789-0ced0c0271b6.png)

4. [参照(R)...]を選択して[サーバーの場所(S)]を入力。
[ユーザー名(U)]と[パスワード(P)]も入力して[終了(F)]を選択
　　　　![スクリーンショット 2017-01-23 23.33.02.png](https://qiita-image-store.s3.amazonaws.com/0/160615/3d0da8d5-a702-18e5-5562-96b04cae016c.png)

5. サーバーが追加されました。
ローカルにOracle Database XEを導入したりする場合は
[サーバー・ポート(V)]を任意のポート番号に変更しておくと良いかもしれません。
　　　　![スクリーンショット 2017-01-23 23.33.24.png](https://qiita-image-store.s3.amazonaws.com/0/160615/48794742-15f4-5c03-19ce-41049bdc8cad.png)

## NetBeansのデフォルト文字コードの変更
NetBeansのデフォルトの文字コードをUTF-8に変更しておきます。
別にやってもやらなくても良い設定。
Windowsでのやり方は「NetBeans　UTF-8」とかでググってやってみてください。


# 変更履歴
[2017.01.24] 初版作成
Python 3 で Application Insights を使う(bottleも含む)

# TL;DR
Azure 版 New Relic とも言える Application Insights ですがあまり情報が無いので書いてみます。

# GitHub
Microsoft/ApplicationInsights-Python: Application Insights SDK for Python
https://github.com/Microsoft/ApplicationInsights-Python

使い方はGitHubを読めばわかります。
。。。というだけでは寂しいので以下簡単に使い方。

# インストール方法
インストールは `pip` だけでいけます。
`$ pip install applicationinsights`

# 使い方
GitHub の READMEでは、クライアントテレメトリーとサーバー側処理が一緒くたになっていて、分かりにくいのですが、クライアントからリクエストを送る時のモニタリングと、リクエストを受けるサーバー側のモニタリングの2つの分類でのモニタリングが可能です。

## INSTRUMENTATION KEY
どの様な使い方にせよ、INSTRUMENTATION KEY がいります。
INSTRUMENTATION KEY は、Azure の Application Insights のブレードの中のプロパティにあります。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/132347/6876b19b-89da-cf77-e8d1-91afaf8c5a96.png)

## サーバー側として
### とりあえずリクエスト
基本的にWSGIなアプリケーションであれば簡単に組み込めます。
Python の軽量フレームワーク bottle + uWSG な環境でももちろん出来ました。

```
from applicationinsights.requests import WSGIApplication
from bottle import route, run, default_app, get, post, request, static_file
～略～
if __name__ == '__main__':
    # コマンドから"python index.py"で起動した場合
    run(host='0.0.0.0', port=8080, debug=True)
else:
    # uWSGIから起動した場合
    application = WSGIApplication('<INSTRUMENTATION KEY>', default_app())
```

こんな感じで表示されます。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/132347/f0394038-feaa-b27a-5a55-73784691f93e.png)

※ブラウザ表示時のJavaScriptとしても組み込んでいるのでその表示も含まれてます。

### ロギング
これからやってみる

### 例外
これからやってみる

## クライアント側として
これからやってみる
Template Method みたいなのが作りたかった

# 経緯

golang には継承がないので、親クラスでメソッドのフローを記述して、子クラスでインターフェースメソッドの実装。みたいなことをしたい場合にどうするのがいいのかな？という疑問があった。

# コード

```go
package main

import (
	"fmt"
)

// インターフェース
type PrinterInterface interface {
	Print(string)
}

// 実装1 (TestA)
type TestA struct {
}

func (t *TestA) Print(str string) {
	fmt.Print("<", str, ">\n")
}

// 実装2 (TestB)
type TestB struct {
}

func (t *TestB) Print(str string) {
	fmt.Print("[[", str, "]]\n")
}

// 初期化
func GetStruct(str string) (PrinterInterface, error) {
	switch str {
	case "a":
		u := TestA{}
		return &u, nil
	case "b":
		u := TestB{}
		return &u, nil
	}
	return nil, fmt.Errorf("%s is not support string", str)
}

func main() {
	u1, err := GetStruct("a")
	if err != nil {
		fmt.Println(err)
		return
	}
	u1.Print("Hello") // <Hello>

	u2, err := GetStruct("b")
	if err != nil {
		fmt.Println(err)
		return
	}
	u2.Print("Hello") // [[Hello]]
}
```

# まとめ

~~`GetStruct()` で `PrinterInterface` を返せないので、一度別の構造体に保持してからその構造体経由でインターフェースの関数を呼び出してる。なんか回りくどいなぁと思うので、もっといい方法があるに違いないと思っている。~~


~~`GetStruct()` で `interface{}` を返すようにしたらもう少し簡単になるのかもしれないんだけど、それだとなんでもありになってしまってちょっと違う気がするなぁとも思っている。~~

~~良い方法があったら教えてください。という感じです。~~

`PrinterInterface` を返せないと思っていたんですが、返し方が悪かっただけのようです。ということで上記が最適解なのかなぁと思っている。