OmniAICreator/Qiita-1.07M huggingface dataset:
NSArray内のオブジェクトを検索し、そのindexを取得する(indexOfObjectPassingTest)

地道にfor文でループさせても良いのですけれども。SwiftからCスタイルfor文が無くなることですし、「今更for文を使うのはいかがなものか」と思い、他の方法を調べました。

NSArrayのメソッド indexOfObjectPassingTest を使用します。

    // 例：Userクラスの配列から、userId == 123のユーザーのindexを得る
    NSUInteger index = [userArray indexOfObjectPassingTest:^BOOL(id  _Nonnull obj,
                                                                  NSUInteger idx,
                                                                  BOOL * _Nonnull stop) {
        User* user = (User*)obj;
        return user.userId == 123;
    }];

※条件がヒットしない場合は、NSNotFoundが返ってきます。

### 参考サイト
* [NSArray Class Reference](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/#//apple_ref/occ/instm/NSArray/indexOfObjectPassingTest:)
* [iphone - How to search an NSSet or NSArray for an object which has an specific value for an specific property? - Stack Overflow](http://stackoverflow.com/questions/3076477/how-to-search-an-nsset-or-nsarray-for-an-object-which-has-an-specific-value-for)
/var/log/のログファイルを一括でクリアしたくなったら


お客様のサーバなんかを構築した後に綺麗な状態で納品したくて特定ファイル(今回は/var/log)のファイルを一括消去したくて方法を模索したのでシェアします。

ファイルを**削除**ではなく、ファイルの中身を**消去**を目的をしています。

```shell-session
[centos@root ~]# find /var/log/ -type f -name \* -exec cp -f /dev/null {} \;
```

これで/var/log以下のファイルを探しだし、すべてのファイルに対して/dev/nullでnullを書き込んでいます。

一般的なLinuxサーバであれば利用出来るコマンドなのでお試しアレ。
Groongaで学ぶ全文検索2016-05-20 類似文書検索と精度


今日のお題は類似文書検索とその精度を上げる方法についてでした。


## 類似文書検索の仕組み

いつもの`入力`→`処理`→`出力`で考えると

「入力」はある文書

「出力」は入力した文書に類似した文書

「処理」は類似している文書を検索する処理になるが、中身は下記を行っている。
1.他の文書には無く、その文書に含まれている語を特徴語として抽出する
2. 特徴語をOR検索する
→特徴語を含む文書=入力した文書に類似した文書

## 特徴語の抽出には
* 辞書を使って日本語を良い感じに分ける仕組みの形態素解析を使う。
* 辞書の精度を上げるの大事

例)
新しい言葉を登録するなど


## 精度について

適合率:正解率(数をうつと下がる)

再現率:欲しかったものがどれだけ入っているか（数うてば当たる)
→漏れなく検索できてるかなどはこちらが重要。

* 上記2つはトレードオフの関係なので<BR>
似たような文書を検索するシステムではリリース初期はデータが少ないので再現率を高くしてヒット率を上げ、<BR>
データが増えたら適合率を上げてデータを絞り込むのがユーザーにとって良さそう
* 検索エンジンなどでは再現率を高めつつ、適合率の高い結果
を優先的に上位に表示させることで、<BR>よりユーザーが探したいものを先に表示し、ノイズが入っても影響を少なくしている
* 検索結果が思ったものでは無かったユーザー向けに関連キーワードをページ下部に表示して、ユーザーの次の手を広げるなどのやり方もある

## 特徴語の抽出のカスタマイズ

* 特徴語を増やして再現率を上げたい<BR>
→特徴語を増やすと一般的な語が混ざった場合にノイズが増えるので、文書に紐付いたメタデータを使ってより欲しい文書を表示する必要がある。

例)

* 最近見たもの
* 時間が近いもの
* お気に入りに入れているもの

などのスコアを高くするなどスコアリングに工夫が必要になる

## Mroongaで特徴語をカスタマイズするには

* *SS プラグマを使ってGroongaのすべての検索機能を使えるスクリプト構文を使うhttp://mroonga.org/ja/docs/reference/full_text_search/boolean_mode.html#ss

* 登録はMroonga,検索はGroongaサーバーとHTTPプロトコルで通信するプログラムであるgroonga-httpdを使っても良さそう
http://groonga.org/ja/docs/reference/executables/groonga-httpd.html#groonga-httpd
Wordpress を使ったブログサイトの構築 (次回はまらないため）

### wordpressでハマったところを中心にreviewします

## 構成図



##手順

①ネットワーク作成
→　デフォルトでOK. DNS　hostnameを　yesにして　EC2にインスタンスを割り当てる

②subnetの作成
→　public を2つ、　privateを2つ　作ります. AZ はそれぞれ　ap-northeast-1a,c
public subnetだけに自動でpublicIPをつけるように設定

③internet-gateway
→作成したら、vpcにアタッチする。

④route table
→デフォルト

⑤Security group

wordpress用　→　SSH(22), HTTP(80)
発信元：　SSH→　自分のグローバルIP/32  HTTP→0.0.0.0/0
DB用　→   Mysql(3306)
発信元：wordpress用　security group ID

⑥ DB subnet group

privateA を　ap-northeast-1a のIDに追加
privateC を　ap-northeast-1c のIDに追加

⑦RDSインスタンス

Mysql5.6を使用
SGにはwordpress用のSGを使用　　　port 3306

⑧EC2インスタンス

AMI: Amazon Linux  AMI
type: t2.nano
subnet: PublicSubnetA
SG:wordpress用

⑨ミドルウェアをセットアップ

sshにログインする必要がある

*キーがあるところに　cd しておく
```chmod 0600 キーの名前.pem```
```ssh -i キー.pem ec2-user@public IP```

これでログインできるのでphp,mysql,wordpressをインストール

```sudo yum install php php-mysql php-gd php-mbstring -y```
```sudo yum mysql -y```
これでmysql完了

```wget -O /tmp/wordpress-4.1-ja.tar.gz https:///ja.wordpress.org/wordpress-4.1-ja.tar.gz```

```sudo tar zxf /tmp/wordpress-4.1-ja.tar.gz -C /opt```
```sudo ln -s /opt/wordpress /var/www/html/```
wordpress完了
```sudo chown -R apatche:apache /opt/wordpress```
```sudo chkconfig httpd on```
```sudo service httpd start```
これでapacheを起動

⑩mysqlセットアップ

```mysql -u 名前　-p -h endpoint```
endpointはRDSインスタンスで確認出来る

http://(EC2 public DNS)/wordpress/wp-admin/install.phpにアクセス

詰まったところ

①ブラウザでアクセスできない
→apacheのhomeにアクセスできるか？？
yes....apache の下のディレクトリで動いているかを確認
ls -l  /var/www/html
no→　再インストール

②Can’t connect to MySQL server on ‘******’ (111)が出てくる
→　DBとWordpressが接続されていない可能性
SGに問題がある可能性なので、wordpressのSGでDBのSGをインバウンドで許可する
MayaでOutlinerが行方不明になった場合

# MayaのUI Reset

## 事象
Outlinerを選択しているが表示出来なくなった。

## 原因と思われること
デュアルディスプレイのメインディスプレイを交換したため、Outlinerの表示場所が表示されない位置へと変わってしまった

## 解決方法
公式ドキュメント
https://knowledge.autodesk.com/support/maya/troubleshooting/caas/sfdcarticles/sfdcarticles/Reset-Maya-to-Default.html

prefsフォルダをprefsOldにしてMayaを再起動したら、表示されるようになった。
Windowsなら：
Windows 64 ビット版: 
C:\Users\USERNAME\My Documents\maya\VERSION\prefs
↓
C:\Users\USERNAME\My Documents\maya\VERSION\prefsOld
　　　　　　　　　　
Windows 32 ビット版: 
C:\Users\USERNAME\My Documents\maya\VERSION\prefs
↓
C:\Users\USERNAME\My Documents\maya\VERSION\prefsOld
OSX で git diff を DiffMerge で visual に表示できるように設定する


git diff でターミナル上で差分比較はできるわけですが、
これは行単位に変更点が確認できるだけなので、行のなかのどこが変更されたかはわかりません。

github 上で Diff options を Split で表示することで、
行の中のどこが変更されたかも確認はできます。
しかしながら以下の問題があります。

* git commit & push した後でないと確認できない。
* 変更行数が多すぎると、そもそも確認できなくなる([1500行を超えた場合らしい](https://help.github.com/articles/what-are-the-limits-for-viewing-content-and-diffs-in-my-repository/))。
    * ソースコードで普通は無いことですが、CSV に列を追加した場合などがこれにあたります。

というわけで、OSX 上の GUI で visual な diff を使って差分確認をする必要がでてきます。
これの設定方法です。

# 前提
visual な diff は [DiffMerge](https://sourcegear.com/diffmerge/) を使うこととします。
以下の条件で選びました。

* 日本語 OK。
     * これは [tkdiff](https://sourceforge.net/projects/tkdiff/?source=typ_redirect) もOK。
* ある程度巨大な diff を表示できる。
* 通常の OSX のインストールの手順とターミナルでのコピペで設定できる。


# 手順
1. [DiffMerge](https://sourcegear.com/diffmerge/downloads.php)をダウンロード・インストールする。
2. [DiffMerge を日本語化する](https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=diffmerge%20%E6%97%A5%E6%9C%AC%E8%AA%9E%E5%8C%96)。
     * 但しこれでも日本語化できないケースがあるようです。これは自分は発生していないので解決できません。
3. 以下をコマンドラインで実行する。

```sh
$ git config --global diff.tool diffmerge
$ git config --global difftool.prompt false
$ git config --global difftool.diffmerge.path /Applications/DiffMerge.app/Contents/Resources/diffmerge.sh
```

# 使い方
git diff と打つ代わりに git difftool と打てば OK です。
ファイルごとに DiffMerge が起動するので、確認が終わったら ⌘W で閉じれば、次のファイルの差分表示に進みます。
Swift で NSColor と UIColor、NSImage と UIImage を同じソースで扱う

前回の [Swift で CSS3 の色を名前で参照する方法](http://qiita.com/codelynx/items/be07591511d910a96daa) のおまけとして書いた所を切り出して記事にしたいと思います。



Swift で iOS のコードと OS X のコードを共有した時ってあるかと思います。その際、時々問題になるのが、同様なクラスなのに iOS と OS X でプレフィックスが違うクラスの扱いです。iOS では、「`UIColor`, `UIImage`, `UIView`, `UIViewController`, `UIBezierPath`, `UIResponder`」「`NSColor`, `NSImage`, `NSView`, `NSViewController`, `NSBezierPath`, `NSResponder`」になっていて、以下のように import 先だけ、`#if` で切り分けても

```.swift
#if os (OSX)
import Cocoa
#elseif os(iOS)
import UIKit 
#endif
```

実際に `UIImage` とか `NSImage` とかをいちいち切り分けるのは面倒の極みです。

```.swift
class MyObject {
	#if os (OSX)
	var image: NSImage?
	#elseif os(iOS)
	var image: UIImage?
	#endif
}
```

そこで、まぁ知っていればどうってない事ですが、ちょっとした小技を紹介したいと思います。そのトリックは　import の `#if` の切り分け時の所でこんな具合に書きます。

```.swift
#if os (OSX)
import Cocoa
typealias XColor = NSColor
typealias XImage = NSImage
typealias XView = NSView
typealias XViewController = NSViewViewController
...
#elseif os(iOS)
import UIKit 
typealias XColor = UIColor
typealias XImage = UIImage
typealias XView = UIView
typealias XViewController = UIViewViewController
...
#endif
```

勢い余って「...」までコピペしないでください。これで本体のコードの中でいちいち切り分けなくても大丈夫になり、コードの見渡しが良くなります。

```.swift
class MyObject {
	var color: XColor?
	var image: XImage?
	// snip
}
```

基底クラスとしても使えます。

```.swift
class MyImage: XImage {
	// snip
}
```

ただ、最も元のクラスに違いがある場合は、その違いを直接吸収できるわけではありませんので、工夫する必要があるかと思います。

```.swift
class MyView: XView {
	#if os (OSX)
	func layout() {
		super.layout()
		self._layoutSubviews()
	}
	#elseif os(iOS)
	func layoutSubviews() {
		super.layoutSubviews()
		self._layoutSubviews()
	}
	#endif

	private func _layoutSubviews() {
		// your layout code
	}
}
```

いかがでしたでしょうか。それでは、皆様、Have a nice coding...

［環境］swift のバージョンは以下の通りです。

```.console
Apple Swift version 2.2 (swiftlang-703.0.18.1 clang-703.0.29)
```
select2でjQuery Validation Engineを使う方法

Select2の4.0.2から、特別にオプションを設定しなくてもjQuery Validation Engineを併せて使えるようになった。
selectタグをdisplay:noneするのではなく、最小化して見えなくする方式に変わったため。

---

Validation Engine  2.6.2
Select2  4.0.0-rc.2

select2はselectをフィルタ付きのselectにしてくれるプラグイン。
jQuery Validation Engineはformの各タグにバリデーションを行うことができるプラグイン。

##select2でjQuery Validation Engineを使う方法。

###1.html

```html
<select class="validate[required]" data-promptPosition="inline">
  <option>鎌倉
  <option>横浜
</select>
```

###2.オプションを設定

```js
$('form').validationEngine({
    validateNonVisibleFields: true,
    promptPosition:'inline'
});
```

※promptPositionのinlineはhmtlのdata1属性またはjsのオプションで設定する。

##解説
###1.validateNonVisibleFields: true

select2はselectタグをdisplay:noneで非表示にして、spanタグでフィルタリン付きのselectを表示している。spanタグのフィルタリン付きのselectを変更すると、selectタグに反映される。
validationEngineはデフォルトでは、非表示タグは対象外(false)なのでオプションで対象(true)に変更する。

###2.promptPosition:'inline'
デフォルトのバリデーションメッセージは右上に表示されるが、これはバリデーション対象のタグの位置を計測して表示している。
位置の計測はposition().topを使っているため、display:noneでは正確に計測できない。そのため計測の必要がないinlineを使用している。
groonga勉強会のまとめ(2016年5月20日)

# Groongaの類似検索について

##　疑問（テーマ）
 Mroonga での類似検索を行う場合、特徴の個数を変更することができるのか。
 
##　結論
 Mroonga の特徴であるSQL互換の機能では不可能ただし、SQL互換以外のコマンド（Pragma?）を使用する手もあり。データのCreateとUpdateに関してはSQL側から操作し、検索（index, show）に関してはmroonga httpd を使うという手段がある。

## 詳細な内容
上記結論を得るまでの話の流れについて

###　キーワード
- 形態素
- 類似文書検索

###　類似検索について
　　入力（文書） -> 処理 ->出力　（文書のリスト）　入力の文書から特徴になる形態素を抜き出し、その形態素を使ってor検索を実施するという仕組みになっている。特徴に一般的な語が混ざると入れてしまうとノイズ（無関係な文書）が増えてしまうと。

###　形態素解析について　
　　類似検索では日本語の文章を形態素ごとに分けている。形態素とは、意味が通る、ことばの最小単位である。全文検索では形態素解析を使用しており、インデックスを付加する際などにも使われる。

###　検索の精度について
　　適合率と再現率がある。

- 再現率=見つけてきた正解の数／全ての正解の数
- 適合率=含まれる正解の数／見つけてきたものの数

適合率と再現率はトレードオフであるため、状況によって使い分ける必要がある。πが少ない時は、再現率をあげるよう努め、πが増えるにつれて、適合度をあげるように努める。

###　その他の精度に関して
　　上記二つの指標以外として大事なことが、見せる順番と他の検索のリコメンドである。一つのクエリーで得られる結果を数十ページも見る人はそうそういない。そのため、はじめのページに重要そうなものを表示する必要があり、そのページの終わりに別の検索クエリーを提示するというようなことも重要に成る。google検索などで実際に行われている。いかに精度よく見つけるかと見つからなかったらどうするかということを視野に入れる必要がある。

###　MroongaとGronnga の関係性
　　いわばMroonga は Groongaのラッパーであり、内部的にはGroongaが動いている。Mroongaはそのコンセプト上SQLから大きく外れないということを目指しているため、Groonga機能は網羅的に触れるようになっていない。しかし、SQL的でないコマンド（Pragma?要調査）などを使えば可能である。また、
Mroongaを介さずGroongaを直接　groonga　httpd　などで叩くことでも可能である。
SwiftyBeaverベータ版使ってみたら感動した話

株式会社[Nanameue](http://nanameue.jp/?lang=ja)
iOSエンジニアの[bati](https://www.facebook.com/hiroshi.chiba.54)です

今回は噂のSwiftLoggingツールSwiftyBeaver使ってみたよ！ってはなしです

SwiftBeaverとは、ログをXcodeで確認したり収集するプラットフォームです。HelpScout社が運用するオープンソースプロジェクトです。

ログをHelpScout社が提供するMacアプリで見ることができます。
すなわち、プロダクションにあるアプリのログも見れちゃうすぐれものです！

install stepは

- [SwiftyBeaver](https://github.com/SwiftyBeaver/SwiftyBeaver)からgit clone or pod install or Swift Package Managerを使ってインストールします
- SwiftyBeaver Mac App アプリをダウンロードします。まだリリースされていないため、ベータverに登録した人しかダウンロードできません
- app ID, secret, encryption keyをset

```
public let SBLog = SwiftyBeaver.self

 SBLog.addDestination(ConsoleDestination())
 SBLog.addDestination(FileDestination())
 SBLog.addDestination(SBPlatformDestination(appID: kSBAppId, appSecret: kSBAppSecretId, encryptionKey: kSBAppEncryptionKey))
```

-あとは以下のように使います
```
SBLog.verbose("not so important")  // prio 1, VERBOSE in silver
SBLog.debug("something to debug")  // prio 2, DEBUG in green
SBLog.info("a nice information")   // prio 3, INFO in blue
SBLog.warning("oh no, that won’t be good")  // prio 4, WARNING in yellow
SBLog.error("ouch, an error did occur!")  // prio 5, ERROR in red
```


***エラーメッセージを詳細に見れるのは良い***


```

SBLog.error("\(error.code) \(error.userInfo)")


```

などのように使うと、エラーコードやエラーの詳細メッセージをSwiftyBeaver Mac アプリで見ることができます

こんな感じ

<img width="462" alt="スクリーンショット 2016-05-20 21.13.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/118340/1bea347d-8abc-5d6d-ee8d-422f65252ca6.png">


リリースされたら是非みなさんも使いましょう！！！！！


また、今度TECH_Salon ✖　私コラボイベント
**to do アプリを作ろう開催します！！！**

是非初心者大学生など、Swift勉強したい方お越しください！！！

[to do アプリを作ろう Swift勉強会](http://techsalon.connpass.com/event/31672/)


また最近記事になりました
[「Twitterがキッカケで出会って1分で入社を決意、エンジニアとして猛烈に成長したい」ナナメウエ iOSエンジニア 千葉大志氏はどうスキルを磨いたのか](http://labs.skyland.vc/entry/2016/05/20/093124)
Groonga勉強会 2016-05-20

# 前提知識

## 類似文書検索とは・・・

ある文書を入力として、それに類似している文書を出力する検索を「類似文書検索」といいます。
　　（入力：ある文書）　ー＞　（処理）　ー＞　（出力：類似文書）

実際に検索する際にどのような処理が行われているかと言えば、文書から特徴語を抽出し、候補となる文書の集合に対してOR検索するイメージです。

特徴語を抽出する際によく使われる分け方として2種類あり、形態素とN-gramがあります。
N-gramの方が単純であるため結構使われますが、形態素の方がより言語を意識した分け方をするため、精度が高いです。

形態素に分ける際は、半角全角の違いや動詞の活用を同一単語として取り扱うか、別物として取り扱うか、最近では絵文字を絵文字として取り扱うか、あるいは日本語に変換して取り扱うかで精度が変わってくるようです。

## 精度とは・・・

精度の指標は2種類あり、適合率と再現率があります。

* 適合率
  + 結果の中にどの程度正解が含まれているか。
* 再現率
  + 正解のうち結果にどの程度含まれているか。

# 本題

今回のテーマは、勉強会参加者からの「入力である文書に対して、より多くの結果（類似文書）を出すためにはどうすればいいのか？」についてです。

それには特徴語の抽出処理をどのようにチューニングするかが肝になります。
しかし、これには若干の問題があり、より多くの結果を出す（＝再現率を上げる）ために、ただ出力の量を増やしてしまうと、適合率が下がってしまい、結果的にユーザの利便性が下がり、ユーザが離れてしまいます。

では、どうすればいいのか？

出力である検索結果をどのようにソートするのかや、ユーザの動線を意識した補助機能の組み込みが実は肝だったりします。

誰もが日常的に使っている「Google」を例に考えてみます。

Googleの検索結果は再現率が高いですが、ユーザが離れないような工夫がされています。

1. ソーティング
Googleで検索した人は数万件に及ぶ大量の結果が出たとしても、それを全て見る人は皆無であり、大半の人が最初の数件しか見ません。
そのため、ソーティングの精度を上げて、いかに最初の数件にユーザが望むものを出すかに心血を注いでいます。

2. ユーザ補助機能
それでも、ソーティングの精度が完璧ではないため、ユーザが欲しい情報が最初の数件に出ないこともあります。そのような場合に備えて、ユーザが次の一手を打てるように、おすすめの検索キーワードをレコメンドし、ユーザの次の動作を補助しています。

# まとめ

類似文書検索の適合率や再現率を上げるのも大事ですが、ソーティングの精度を上げたり、ユーザの動線を意識した補助機能を充実させることも大事です。
有孔ボードのフックを自作する

電子工作していると、道具やケーブルの置き場に困ってくるんだけど、最近は有孔ボードを買って、軽い物はに引っかけるようにしている。

![DSC05266.jpg](https://qiita-image-store.s3.amazonaws.com/0/5330/94a0cb17-ec09-f18f-b441-5e7f80fb2e7d.jpeg)

フックを一個一個買うと、ちゃんとした製品のものはしっかりとした堅さなので微調整が難しく、また一個100円弱ぐらいするため、針金から自作する。

# 用意するもの

- 針金
    - 堅さの好みがあったり、素材によって堅さが違うので一概にこれが良いとは言えないが、写真では太さ 16mm のブロンズ色のアルミワイヤーを使ってる
- ニッパ
- ラジオペンチ

![DSC05264.jpg](https://qiita-image-store.s3.amazonaws.com/0/5330/14949791-cae4-2e37-9eb5-4f618808074d.jpeg)


# 手順

## 15cm ぐらいに切る

![DSC05245.jpg](https://qiita-image-store.s3.amazonaws.com/0/5330/ee222239-13d1-8897-abb7-310ba647bcd6.jpeg)


## 真ん中で折る

![DSC05246.jpg](https://qiita-image-store.s3.amazonaws.com/0/5330/5501ab18-eaa2-4aa3-f1e0-42ef21ee4dfe.jpeg)


## J の形を作る

![DSC05247.jpg](https://qiita-image-store.s3.amazonaws.com/0/5330/bdf5446a-fac7-d15f-8611-e558acd633ce.jpeg)


## 2cm ぐらいのところで折る

J とは反対側に2cmぐらい折る

![DSC05248.jpg](https://qiita-image-store.s3.amazonaws.com/0/5330/dc3a8765-08a9-c0f8-a166-018239e1c8c2.jpeg)


## 1cm ぐらいのところで折る

上に向かい 1cm ぐらい折る

![DSC05249.jpg](https://qiita-image-store.s3.amazonaws.com/0/5330/9d5cae49-9eb2-822f-e5ac-91e698341e09.jpeg)


## 5mm ぐらいのところで折る

手前に飛び出す方向に 5mm ぐらいのところで折る

![DSC05250.jpg](https://qiita-image-store.s3.amazonaws.com/0/5330/a5d42591-27c2-34c8-8306-9dba83a48711.jpeg)

# 完成

![DSC05251.jpg](https://qiita-image-store.s3.amazonaws.com/0/5330/8fbc34b1-e078-58c8-7402-aa98acc437e2.jpeg)

これで完成。たくさん作ろう！！

![DSC05258.jpg](https://qiita-image-store.s3.amazonaws.com/0/5330/24825e8b-bbd5-87b8-0cd6-727cb24a7c31.jpeg)

そこそこ柔らかいので、引っかけるものに応じて調整も簡単。ただし耐久重量は低いので、軽いものを。

![DSC05252.jpg](https://qiita-image-store.s3.amazonaws.com/0/5330/4d064506-8918-ce2b-847b-002f996a1f0c.jpeg)

有孔ボード、180cm x 90cm の物が2~3000円ぐらいで買えるので、便利に活用できる。
セッションをメモリに保存する

デフォルトではセッションはファイルに書き出されます。
ディスクI/Oはボトルネックなので、より早いメモリ保存にしてみます。

とりあえずWindows版PHP7には[APCu](http://php.net/manual/ja/book.apcu.php)が入ってないので[PECL](https://pecl.php.net/package/apcu_bc)から拾ってくる。
今回は1.0.3のDLLをダウンロード。
解凍したらextディレクトリにphp_apcu.dllを置いてphp.iniに以下を記載。
Linuxなら適当にpeclコマンドでも使って。

```ini
extension=php_apcu.dll
[APCu]
apc.enabled = 1
apc.entries_hint = 4096
apc.gc_ttl = 3600
apc.ttl = 3600
```

Apacheを再起動したらAPCu関数が使えるようになっているはず。

```php
class MySessionHandler implements SessionHandlerInterface{

	/**
	* コンストラクタ
	* @param string パス
	* @param string session_name()
	* @return bool true
	*/
	public function open($save_path, $name): bool {
		return true;
	}
	
	/**
	* デストラクタ
	* @return bool true
	*/
	public function close(): bool {
		return true;
	}
	
	/**
	* session_destroy()した
	* @param string session_id()
	* @return bool true
	*/
	public function destroy($session_id): bool {
		if(apcu_exists($session_id)){
			return apcu_delete($session_id);
		}
		return true;
	}
	
	/**
	* $_SESSIONを返す。
	* @param string session_id()
	* @return string session_encode($_SESSION)
	*/
	public function read($session_id): string {
		return apcu_fetch($session_id);
	}
	
	/**
	* $_SESSIONを保存する。
	* @param string session_id()
	* @param string session_encode($_SESSION)
	* @return bool true
	*/
	public function write($session_id, $session_data): bool {
		return apcu_store($session_id, $session_data, (int)ini_get('apc.ttl'));
	}
	
	/**
	* ガベージコレクションが動いた。
	* @param int session.gc_maxlifetime
	* @return bool true
	*/
	public function gc($maxlifetime): bool {
		$list = apcu_cache_info();
		$ttl = (int)ini_get('apc.gc_ttl');
		foreach($list['cache_list'] as $v){
			if( ($v['access_time'] + $ttl) < $_SERVER['REQUEST_TIME']){
				apcu_delete($v['info']);
			}
		}
		return true;
	}
}

	// セッションハンドラ変更
	session_set_save_handler(new MySessionHandler(), true);
	
	// 以後セッションはメモリに保存される
	session_start();
	session_regenerate_id();
	$a=session_id();
	$_SESSION['a'] = 'b';
```

session_name()とか実装してないけど誰も使わないからいいよね。

gcは不要になったAPCuを削除しています。
apcu_store()は配列に値を入れるようなもので、ttlを越えると配列の値は取得できなくなりますが、配列のキー自体は残っています。
そのためキー自体を削除する処理が入っています。
APCUIteratorでは何故かオプションAPC_LIST_DELETEDを指定しても取得できませんでした。
しかしここは`apc.ttl`と`apc.gc_ttl`と`session.gc_maxlifetime`どれに従うべきなんだろうか。

さて、せっかく作ったはいいけど、大人数が使うサービスでやるとメモリ不足で死ぬし、少人数しかいないサービスではそもそもディスクアクセスでも十分な速度だから作る必要無いしで、需要がよくわからない。
serverspec for windows


# Why `windows_feature` failed!

## For non-english users
```ruby:
describe windows_feature('Web-Webserver') do
  it{ should be_installed.by("powershell") }
end
```  
https://github.com/serverspec/serverspec.github.io/blob/master/_includes/windows_feature.md

Unfortunately, `should be_installed.by("dsim")` failed 100%.

## For english users (Windows English edition)
Feature-Name have defferent `DISM` and `powershell`.
Default = `it { should be_installed }` via `DISM`

## Route cause
Provider = `dism` is default.

# via SSL - Winrm
http://qiita.com/h-imaoka/items/3c17c38aeca443566d22
チリツモ削減 タブエクスプローラを使用する

# タブエクスプローラを使用する
![20160520_Qiita003.png](https://qiita-image-store.s3.amazonaws.com/0/111261/474a175b-ce26-072c-7121-4c1e70ddecfb.png)

## まっ！いいかぁ。。。がチリツモって時間がいくらあっても足りない
なんとなく仕事をしていると、いつの間にかにウィンドウが増えていく。
どこを操作していたか分からなくなってしまって、同じウィンドウを開いてまた増えていく。
日々あちこち移動して色んなPCを渡り歩いていると

**まっ！いいかぁ。。。**

自分の環境へのこだわりが消えていった

最近、仕事量が増えていくので、今までと同じようにやっていては段々間に合わなくなってしまった。
「まっ！いいかぁ。。。」は「塵も積もれば・・・」コンテンツだ。
日々チリツモコンテンツを減らしていけば少し楽になるんではないだろうか。

今まで無視していた、作業改善をしてみよう

## タブエクスプローラでウィンドウ数削減
まずは仕事をしていて、山ほどあるエクスプローラウィンドウが気になったのでウィンドウ数を減らそうと考えた。
たくさんウィンドウがあったり、よく使うフォルダがすぐ取り出せるようにしたら少しは楽になるのではないだろうか。
タブWebブラウザやタブエディタがあるようにタブエクスプローラも結構昔から存在している。
昔はタブエクスプローラアプリはよく落ちるという印象があったけど、今はどうなんだろうか

## Windows
### 有名そうなタブエクスプローラをインストールしてみた。
今時の有名なタブエクスプローラはプラグインみたいに使うことが出来た。
CloverとQTTabBarの二つをインストールしてみた
自分としてはCloverの方がすぐ使えることもあって、Cloverを使おうことにした

[Clover](http://www.forest.impress.co.jp/library/software/clover/)
- 簡単インストール
- 再起動必要なし
- Chromeを良く使うので親しみやすい
- エクスプローラを表示しようと、エクスプローラのアイコンをクリックするとタブが増えてしまう。 Cloverのアイコンをクリックしなければならない
![20160520_Qiita005.png](https://qiita-image-store.s3.amazonaws.com/0/111261/53073282-bfc3-f852-bb97-93faf61b5e12.png)

[QTTabBar](http://www.forest.impress.co.jp/library/software/qttabbar/)
- インストール後再起動が必要
- いろいろな設定がカスタマイズ出来る
- タブが隠れてしまったりして、タブを表示するまでに時間がかかった
![20160520_Qiita004.png](https://qiita-image-store.s3.amazonaws.com/0/111261/0623ba10-919a-421d-a0f8-19e842303c4f.png)

### ウィンドウの使用方法の方針改善
簡単なところからまず２点改善しようと決めた
- フォルダ構成の見直し
- よく使うフォルダをお気に入り登録

#### フォルダ構成の見直し
長年PCを使っていると重要度の階層がおかしくなっていく。
よく使うフォルダのお気に入りを追加する前に、何が重要で、お気に入り登録するフォルダは同じ階層になるようにしてみた。

（★はお気に入りに追加されているフォルダ）
「改善前」
よく使うフォルダ★
 ＋　次によく使うフォルダ★
 　　　＋　その次に良く使うフォルダ★
 ＋　あんまり使わないフォルダ

「改善後」
よく使うフォルダ★
 ＋　あんまり使わないフォルダ
次によく使うフォルダ★
　＋　その次に良く使うフォルダ

#### よく使うフォルダをお気に入り登録
Cloverではお気に入り登録したいフォルダをタブの下にドラッグするだけで、お気に入り登録できた。
![20160520_Qiita006.png](https://qiita-image-store.s3.amazonaws.com/0/111261/5979c022-9ff8-6a6a-cb24-1750db62dabb.png)

## Mac
### Macは標準のFinderにタブ機能が搭載されている
MacはFinderの標準機能にタブ表示が含まれていた
![スクリーンショット 2016-05-21 10.10.24.png](https://qiita-image-store.s3.amazonaws.com/0/111261/5b87bcf4-aa5d-7db2-9e03-789a4a58ff0b.png)

[表示] -> [タブバーを表示]
![スクリーンショット 2016-05-21 10.11.24.png](https://qiita-image-store.s3.amazonaws.com/0/111261/6ef49333-7a38-8d5d-0e89-db6837e1ccf8.png)

タブバーが表示される
![スクリーンショット 2016-05-21 10.12.08.png](https://qiita-image-store.s3.amazonaws.com/0/111261/bd480846-a168-5c76-f8e0-21b696a4b720.png)

参考になりそうなURL
[OS X Mavericksの新機能「Finderタブ」の使い方まとめ｜Mac](http://weekly.ascii.jp/elem/000/000/181/181236/)

[MacのFinderにタブを追加して複数ウインドウをひとつにまとめて表示可能になる「XtraFinder」](http://gigazine.net/news/20141229-xtrafinder/)
最新のOSだと使えなかった

## あとは使ってみながら考えてみる
すぐに取り出せるように他にも方法がないか考えてみる
jpmobileでwrong number of arguments (given 4, expected 3)と怒られた

<img width="1031" alt="スクリーンショット 2016-05-20 20.36.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/118003/413bb11f-9435-b2d5-a9f5-2c1473377445.png">

こんな感じでした。


jpmobileのバージョンを指定することで回避できました。

```
gem 'jpmobile', '4.2.2'
```
はじめてのSEO対策

*2018/01/19追記*
最初に投稿してから、何度か検索順位が上がらなくて困った時に打った手っ取り早い施策（効果ありそうな順）
- h1タグとtitleタグの中に全く同じ文言（検索されたいワード）を含ませる
- h1タグは絶対１つ
- カノニカルをいれる

---

SEOについて調べてみました。

>「SEO対策」の本質は、”検索エンジン用に自分のサイトを最適化する事” ではありません。”検索ユーザー用に、自分のサイトを最適化する事” が、「SEO対策」の本質なのです。

##コンテンツを充実させる
###Why?
Googleの検索エンジン『クローラー』は *ユーザーにとって価値のあるページ* を優先的に表示させる。
つまり、情報が豊富で便利なサイトを作成し、コンテンツを『わかりやすく』『正確に』ページに記述する必要がある。

###How?
- titleやalt属性の説明をわかりやすく正確に
	- キーワードを積極的に含める 
- わかりやすいページ階層
- h1タグはpcもspもひとつに


##URLの正規化
同一ページへのURLを統一させる

- www.hogehoge.com
- hohoge.com 
- hogehoge.com/index.html
- SPとPCでページを分けている場合
- ECサイトの商品一覧ページ

###Why?
検索エンジンからの評価の分散を防いで被リンク数を増やすため

###How?
- まずは[Webマスターツール](https://www.google.com/webmasters/)に登録
- `canonical`の設定
- WebサーバーのHTTPヘッダーにも`canonical`を指定できる
- spとpcで分かれてる場合、`alternate`を追加

```
<link rel="alternate" media="only screen and (max-width: 640px)" href="http://sp.example.com/" />
<link rel="alternate" media="handheld" href="http://sp.example.com/" />
```

##インデックスを登録
>インデックス
>検索エンジン用語では、「Google（検索エンジン）に、Webサイトのページを登録する事」を指します。

###How?
- 更新頻度を高く
- Ping送信（古め）
- サイトマップを通知
- PubSubHububub
	- リアルタイムにサイトの更新を検索エンジンに通知してくれる
- Fetch as Google（Webマスターツール内）
	- クローニングの要求、通常１日以内、３日〜数週間かかることも
	- インデックス申請は１週間で10件まで


##検索してみる
[Googleの検索方法と検索オプション、テクニックまとめ | 株式会社LIG](http://liginc.co.jp/web/service/google/86222)

##参考サイト
[ウェブマスター向けガイドライン（品質に関するガイドライン） - Search Console ヘルプ](https://support.google.com/webmasters/answer/35769?hl=ja)
[正規化とは？サイトのページURLを正規化する必要性と方法についてまとめてみた](http://viral-community.com/seo/url-normalization-2965/)


##追記
上記の施策を行って待つこと３日、４ページ目→１ページ目に昇格しました:tada:
ESP8266搭載HaLake KitをビジュアルプログラミングアプリRobipと連携させる方法

#ESP8266搭載HaLake Kitとは？
ESP8266搭載HaLake Kit（ハレイクキット）とは、ニャンパス株式会社が開発、販売をしているESP8266Wi-Fiモジュール以外に、加速度センサー、赤外線送信、赤外線受信機、maikuroUSBポートを内蔵した、ボードです。
基本的には、専用のプログラミングアプリ「Robip（ロビップ）」からプログラムを書き込みます。

#ビジュアルプログラミングアプリRobipとは？
HaLake Kit同様、ニャンパス株式会社が開発した、ビジュアルプログラミングにより、HaLake Kitにプログラムを書き込む開発環境の事です。
比較的、プログラム初心者の方からPCを使わず、Androidタブレットで開発を始める事ができます。
[プログラミングソフトRobip](https://robip.halake.com)

#早速はじめましょう！
##【1】[Google Play](https://play.google.com/store/apps/details?id=com.nyampass.robip)から、アプリをダウンロードしてください。
![lobip-01.png](https://qiita-image-store.s3.amazonaws.com/0/46262/6c5fe8fc-604b-32f3-a2e3-5d697cc733a8.png)

##【2】アプリを立ち上げると、ログイン画面が表示されますので、新規登録か、Facebookでログインかを選んでください。
![lobip-02.png](https://qiita-image-store.s3.amazonaws.com/0/46262/15c49de7-2bc4-7fc3-e55b-4cfb6a770fa7.png)

##【3】ログインをすると、「entry point」と記載されたキャンバスが表示されます。
![lobip-03.png](https://qiita-image-store.s3.amazonaws.com/0/46262/263b3fdf-0318-1514-691d-eed426ed9c4b.png)

##【4】まず、HaLake KitにWi-Fiの設定を書き込みます。アプリの右端のボタンをクリックして、設定を選びます。
![lobip-04.png](https://qiita-image-store.s3.amazonaws.com/0/46262/f1a5d838-8672-7832-7517-5bdb32c88e7d.png)

##【5】設定画面にて、RobipIDと、使用するWi-Fiを入力します。※Wi-Fiは複数設定する事が可能です。
![lobip-05.png](https://qiita-image-store.s3.amazonaws.com/0/46262/ccee9ae0-428c-a3e8-f68c-3a38ac57d022.png)

##【6】設定画面を閉じ、今度は「Wi-Fi設定を転送」をクリックします。
![lobip-06.png](https://qiita-image-store.s3.amazonaws.com/0/46262/f12ea571-539a-895d-623a-3812515ce26b.png)

##【7】「Wi-Fi設定を転送」をクリックすると上記の様なダイアログが表示されます。そのままの状態でタブレットのWi-Fi設定を開きます。※必ずアプリそのままにしてください。
![lobip-07.png](https://qiita-image-store.s3.amazonaws.com/0/46262/138672d8-4405-3ac2-a244-4166369e9f46.png)

##【8】HaLake Kitの電源を入れ、3秒以内にHaLake Kitのボタンを3回クリックします。
![lobip-08.png](https://qiita-image-store.s3.amazonaws.com/0/46262/9663ed12-bce6-8590-802d-2cd37c1a528f.png)

##【9】タブレットのWi-Fi設定にHaLake KitのID（HaLake ID）が表示されるので選びます。
![lobip-09.png](https://qiita-image-store.s3.amazonaws.com/0/46262/61abf147-e70b-e1b9-2531-edb1e1d62d0e.png)

##【10】Wi-Fiの設定をRobip IDに設定した状態でアプリに戻り、「OK」をクリックします。
![lobip-07.png](https://qiita-image-store.s3.amazonaws.com/0/46262/138672d8-4405-3ac2-a244-4166369e9f46.png)

##【11】しばらく待つと「更新しました！」と表示されれば、HaLake KitにWi-Fiの設定が書き込まれた証拠です。
![lobip-11.png](https://qiita-image-store.s3.amazonaws.com/0/46262/c6e990cb-5a4c-21e7-6c5b-9b53e69dbd6e.png)

##【12】タブレットのWi-Fi設定からHaLake IDを外しても大丈夫です。※HaLake KitにWi-Fiの設定が書き込まれますので、HaLake Kitに通電すれば設定したWi-Fiに接続します。
![lobip-12.png](https://qiita-image-store.s3.amazonaws.com/0/46262/d07bb57f-89d1-3495-8ec0-aaee489b7d82.png)

##【13】アプリでプログラムを作ります。※写真の様にブロックを組み合わせるとLEDを光らせるプログラムになります。
![lobip-13.png](https://qiita-image-store.s3.amazonaws.com/0/46262/62f89191-ab43-00dc-ad1b-028f07d1f76d.png)

##【14】右上の「ビルド」ボタンをクリックするとビルドログ画面が表示され「ビルドを終了しましたHaLake Kitの電源を入れなおして30秒程お待ち下さい。」と表示されます。
![lobip-14.png](https://qiita-image-store.s3.amazonaws.com/0/46262/0cdbac5f-001b-9bd1-e5fd-df8700c89672.png)

##【15】HaLake Kitの16番ピンと、GNDにLEDを取り付け、電源を入れます。15秒程待つとプログラムが更新されLEDが点灯します。
![lobip-15.png](https://qiita-image-store.s3.amazonaws.com/0/46262/3083c724-a739-5fbe-7bde-68871312184b.png)
Draper(Decorator)の中でpartialを使うパターンが結構よかった話

## 概要

RailsのHelperはグローバルな名前空間を汚染するのでなるべくDraper(もしくはActiveDecorator)を使ってDecoratorパターンを使おうって話はあると思うんですが、
ここで、ちょっとしたHTMLのモジュールを表示するメソッドをDraperの中で書こうと思うと結構だるいわけですよ。

## content_tag の闇

```rb
module ItemDecorator
  def facebook_btn
    h.content_tag(:div, class:'btn fb-btn') do
      # ごちゃごちゃいろいろ書く羽目になる
    end
  end
end
```

## partial を render しちゃうと楽

で、普段はslimとかで書いてて、slimのコードをcontent_tagとか使ったコードに移植してたらミスも起きやすいし、甚だ非効率だと思ったので、こういうパターンを採用してみたら、思った以上に良かったので喧伝。

```rb
module ItemDecorator
  def facebook_btn
    h.render '/partials/items/facebook_btn', {item: self}
  end
end
```

```/partials/items/_facebook_btn.html.slim
.btn.fb-btn
  /　いつものslim記法で書けるぞ！
```

これだけで随分利便性あがるなーと思ったのでした。

## 「これなら単にpartialをrenderすればよくないか？」への反論

これだったら、単にrenderするコードをviewの中に埋めれば一緒じゃないか、と思われるかも知れないので先に反論しつつメリットがあるのだと主張しておきます。

まず、単にrenderするコードにすると、引数に指定すべきものが多岐に渡る場合、どの引数が必要か分かりにくいという問題があり、Decoratorのメソッドを挟むことでそれが解決されます。ようは以下の例。

```rb
module ItemDecorator
  def buy_btn(price, disabled=false)
    h.render '/partials/items/buy_btn', {item: self, price: price, disabled: disabled}
  end
end
```

通常のメソッドを挟んでいることで、IDEによる補完の恩恵も受けやすいです。

また、テストコードが書きやすいのもメリットです。 単に partialだけにすると、少しテストが書きにくいです（本質的には先に指摘したメソッドが切り出されているとイイネってのと同じことなのかもしれない）
SSRSのグラフが一切描画されない（真っ白になる）のはサービスの再起動で直る（白目）

#SSRSでハマリかけた罠について紹介します

今まで普通に描画できていたグラフ（データバー）がある日突然、実行した途端真っ白になった。
（デザインビューでは何も問題なく表示されている）

例えば
![image](https://qiita-image-store.s3.amazonaws.com/0/123420/82dc4fad-2e6d-a24a-9abb-9a91ee572ebe.png)
のようにデザインビューでは表示されているのに、実行すると
![image](https://qiita-image-store.s3.amazonaws.com/0/123420/41da7c6d-46f5-b1c3-eb7c-a1906004674d.png)
となる。

ちなみに、ただただ真っ白になっているだけではなく、マウスオーバー時に出るToolTipすら表示されないのでグラフオブジェクト自体全く作られていない模様。

- 元々表示できていたrdlと差分チェックしてもグラフ部分の定義は変わっていない
- グラフに渡している値をテキストボックスで出すと表示される
- 実行すると真っ白なのに印刷レイアウトで表示すると描画される
　　　　　　　　　　　　　　　　　　　　　　　　　　↑ここでふと気づく。これバグってね？


いや、まさかと思いサービスからSQL Server Reporting Servicesを再起動してみる・・・**直った！！**

つまり~~Microsoft爆発しろ~~どうしようもなくなったら再起動しようというお話です。
check for broken link

You can check for broken link using this function:

```php
function check_url($url) {

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch , CURLOPT_RETURNTRANSFER, 1);
    $data = curl_exec($ch);
    $headers = curl_getinfo($ch);
    curl_close($ch);

    return $headers['http_code'];
}
```
You need to have CURL installed for this to work. Now you can check for broken links using:

```php
$check_url_status = check_url($url);
if ($check_url_status == '200')
   echo "Link Works";
else
   echo "Broken Link";
```
gem install 時に途中経過を表示させたい時は -V オプションをつける

gem install でエラーメッセージも出ずにタイムアウトしてインストール失敗することが、稀にあります。
そんな時は、途中経過を表示するverboseオプション -V をつけると、どこで止まっているのか見れて便利です。（-v ではありません）
(→・[Rubygems Command Reference](http://guides.rubygems.org/command-reference/#gem-install)）

通常のgemのインストール例

```
$ gem install ev3dev
Fetching: ev3dev-0.0.2.gem (100%)
Successfully installed ev3dev-0.0.2
Parsing documentation for ev3dev-0.0.2
Installing ri documentation for ev3dev-0.0.2
Done installing documentation for ev3dev after 0 seconds
1 gem installed
```

-V オプションをつけたgemのインストール例

```
$ gem install ev3dev -V
GET https://api.rubygems.org/latest_specs.4.8.gz
302 Moved Temporarily
GET https://rubygems.global.ssl.fastly.net/latest_specs.4.8.gz
304 Not Modified
HEAD https://api.rubygems.org/api/v1/dependencies
200 OK
GET https://api.rubygems.org/api/v1/dependencies?gems=ev3dev
200 OK
/Users/xxx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/ev3dev-0.0.2/lib/ev3dev.rb
/Users/xxx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/ev3dev-0.0.2/lib/ev3dev/device.rb
/Users/xxx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/ev3dev-0.0.2/lib/ev3dev/motor.rb
/Users/xxx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/ev3dev-0.0.2/lib/ev3dev/sensor.rb
Successfully installed ev3dev-0.0.2
Parsing documentation for ev3dev-0.0.2
Parsing sources...
100% [ 4/ 4]  lib/ev3dev/sensor.rb                                              
Done installing documentation for ev3dev after 0 seconds
1 gem installed
```

200 OK で固まってタイムアウトすることがありました。
cloud9環境でBackdrop CMSサイト制作① -導入- 

Backdrop CMSを手っ取り早く体験するために、cloud9を利用しようという試みです。
※勉強しながらの執筆のため、多々至らない点があるかと思いますのでご了承ください。

Backdrop CMSはDrupal からフォークしたCMSのようですね。みなさん知ってました？私は全く知らなかったです。。

1. cloud9でBackdrop CMS用のworkspaceを作成
-----
まず、cloud9のページにアクセスし、自身のアカウントでログインする。次に「Create a new workspace」をクリックします。

<img src=https://qiita-image-store.s3.amazonaws.com/0/91976/73aac71e-56e7-057d-f515-a063051e74c9.png width=400>

作成画面では、下記の例のように好みのWorkspace名を記載します。「Public」を選択するとインターネット上に公開されてしまいますので、公開せずに使用したい場合は「Private」を選択します。（ただし、「Private」は無料使用の場合は1アカウントにつき1つまでしか作成できません）また、Backdrop CMSはCloud9では公式サポートされていないため、自分で環境を構築します。なので、templateでは「Blank」を選択しています。
全ての入力が完了したら、「Create workspace」ボタンをクリックします。

<img src=https://qiita-image-store.s3.amazonaws.com/0/91976/403d33a9-2117-061e-4fe6-6beb43f8ff61.png width=400>

2. Mysqlの設定
-----
Backdrop CMSではMysqlを使用するので、下記のコマンドをターミナルから入力します。

Mysqlを起動し、バージョンが表示されることを確認します。

```bash:cloud9
mysql-ctl start
mysql -u <youruser> -D mysql -e "SELECT version()"
```

次に、Backdrop CMS用の「ユーザ」「パスワード」「DB」を作成します。
ここではそれぞれ「bdcmsuser」「bdcmspassword」「bdcms」として作成しています。
※あくまで例ですので、パスワードについてはより複雑なものを設定することをお勧めします

```bash:cloud9
mysql -u <youruser>
GRANT ALL PRIVILEGES ON *.* TO bdcmsuser@localhost IDENTIFIED BY 'bdcmspassword' WITH GRANT OPTION;
\q
mysql -u bdcmsuser -p
create database bdcms character set utf8;
show databases;
\q
```

show databasesの結果に「bdcms」が表示されていれば成功です。

3. Backdrop CMSのダウンロード
-----
下記コマンドでBackdrop CMSをダウンロードし、適切に配置していきます。

```bash:cloud9
wget https://github.com/backdrop/backdrop/releases/download/1.4.2/backdrop.zip
unzip backdrop.zip
```

4. 接続ファイルの設定
-----
「3. Backdrop CMSのダウンロード」が終わると「backdrop」ディレクトリが作成されているので、「/home/ubuntu/workspace/backdrop/setting.php」を開いて、DBの接続情報を下記のように修正しましょう。

```php:setting.php
$database = 'mysql://bdcmsuser:bdcmspassword@localhost/bdcms';
$database_prefix = '';
```

上記のコードは
'mysql://\<DBのユーザ名>:\<DBのパスワード>@localhost/\<DB名>';
となっています。

<img src=https://qiita-image-store.s3.amazonaws.com/0/91976/54d62c62-0876-e3ac-dd1a-a9f635566782.png width=400>

4. Backdrop CMSのインストール
-----
「Run」>「Run with」>「Apache httpd(PHP, HTML)」でapacheを起動します。

<img src=https://qiita-image-store.s3.amazonaws.com/0/91976/ef5101a5-8421-ec11-c28e-97411a48747e.png width=400>

起動が完了したら、下記URLにアクセスしてください。
https://bdcms-project-<your-username>.c9users.io/backdrop/

対話式のインストーラーが起動するので、「SAVE AND CONTINUE」ボタンをクリックする。（日本語はないです。というか英語しかないです。。）

<img src=https://qiita-image-store.s3.amazonaws.com/0/91976/c30ad833-a919-8eb2-e680-a87fcef15118.png width=400>

サイト名等を入力するページが表示されるので、適宜自由に入力してください。入力後「SAVE AND CONTINUE」ボタンをクリックします。

<img src=https://qiita-image-store.s3.amazonaws.com/0/91976/c597534e-a6fc-51f8-2c4f-3798f360bba9.png width=400>

<img src=https://qiita-image-store.s3.amazonaws.com/0/91976/b0d89d92-5147-17d0-8c28-1ab17268ede5.png width=400>

これで終了です。他のCMSとなんら変わりないですね！

<img src=https://qiita-image-store.s3.amazonaws.com/0/91976/5e9473e3-8d5b-6c66-85e2-b0a309b7a7f9.png width=400>

にしても情報がまるでないですね。
Drupalにかなり似ている気がするので、Drupalユーザの方であれば問題ない感じなんですかね？
RainLoop 参考サイト

# RainLoop を構築するにあたり参考にしたサイト
[KENP DEVELOP](http://www.kenpdev.com/2015/08/13/rainloop-webmail-%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/)
[教えて君](http://www.oshiete-kun.net/archives/2015/08/rainloop2.html)
[server-world](http://www.server-world.info/query?os=CentOS_7&p=httpd&f=14)
[自宅サーバの整理箱](http://log.windows78.net/2014/06/1020/)
[ITわかりたい](http://ufuso.jp/wp/?p=16077)

[RAINLOOP](http://www.rainloop.net/downloads/)
これから構築を進めていきたいです。。
VBScriptのディクショナリの参照の罠

VBScriptには辞書型のオブジェクト `Scripting.Dictionary` があります。
が、このオブジェクトにはちょっとした罠が潜んでいます。
それは「存在しないキーに対して値を取得しようとするとキーを作成してしまう」というものです。

https://msdn.microsoft.com/ja-jp/library/cc428120.aspx
>項目を変更するときに引数 key で指定したキーが見つからない場合、newitem で指定した項目と関連付けられた、引数 key で指定した新しいキーが作成されます。また、既存の項目を取得するときに引数 key で指定したキーが見つからない場合は、空の項目と関連付けられた、引数 key で指定した新しいキーが作成されます。


以下、実際に試したコードです。

```vbnet
Option Explicit

Dim objDict, sKey
Set objDict = CreateObject("Scripting.Dictionary")

' "hoge" キーを追加
objDict.Add "hoge", "hogehoge"

' この時点では "hoge" キーのみ表示される
For Each sKey In objDict.Keys
	WScript.Echo skey & " => " & objDict(sKey)
Next

' 存在しないキーにアクセスすると Empty が返る
If IsEmpty(objDict("fuga")) Then
	WScript.Echo "objDict(""fuga"") is Empty" ' こちらが表示される
Else
	WScript.Echo "objDict(""fuga"") is not Empty"
End If

' "hoge", "fuga" の両方が表示される
For Each sKey In objDict.Keys
	WScript.Echo skey & " => " & objDict(sKey)
Next
```

対策としては `objDict.Exists("fuga")` でキーを問い合わせることです。
アクセスログ集計環境の選定

# 概要

とあるWebサービスのアクセスログの集計をどうするか、という話です。

# やりたいこと

一日毎に、アクセスログを対象に集計を行いたい。

# 必須条件

* 漏れなく、ダブりなくログが集計できること
* 安心、安全にログが集計できる環境であること
* なるべく楽をすること
* ログサイズが大きくなっても問題なく対応できること

# 現在の状況整理

* 集計対象になり得るログ
    * リクエストURLが取得できるログなら何でもOKなので、ELB、Apacheログあたりか。
* 一日のログサイズ
    * Apacheログ：約3GB。ELBも同じくらい。

![IMG_0119.JPG](https://qiita-image-store.s3.amazonaws.com/0/79577/fc6fb47e-a178-3c0b-297d-1b3667f62333.jpeg)


# 調査

## Saasのログサービスを見てみる

ポイントは、

* 値段 (お金は無限ではない...) 
* API (ログを検索または集計するAPIがないと話にならない)

### LogEntries

https://logentries.com/

値段はお手頃だし、様々なログのインポート方法に対応しているが、
ログを検索するAPIのクエリが乏しい。
集計対象のログは、前日のログなのだが、パラメータで指定するtimestampはログのtimestampではなく、ログをインポートした時刻なので、ログのインポートに時差がある場合は、前日のログを検索で絞りこむことが出来ない。
不便そうなので見送る。

### PaperTrail

https://papertrailapp.com/

実際にFreeプランを利用してみた。
Freeプランは100MB/monthで、２日間のログ検索期間がつく。
ログをインポートする方法はとても簡単だし、指定したログがあったらアラートを飛ばしてくれるし、
実業務ではなく、個人でサービスを作って運用しているレベルならめちゃくちゃ使える。
ただ、今回のログサイズからすると、料金が高すぎる。
250GB/monthで3日間のログ検索期間を設けるとすると、$585もする！

### Loggly

https://www.loggly.com/

こちらもFreeプランに登録して動かしてみたが、
動きが・・・遅い・・・・・一個一個のアクセスに・・・・時間・・かかりすぎ・・・・・・
値段はまあまあだが、なんだか信用できなくなってしまった。
今回は見送る。

### NewRelic

https://newrelic.com/

ログの解析・集計というよりも、アプリケーションモニタリングなので、今回は見送る。

### SumoLogic

https://www.sumologic.com/

肝心のsearchAPIなのだが、Enterpriseプランのみ利用可能。→Enterpriseプランはいくらかな？→「contact sales」
ハードルが高いので今回は見送る。

## 仕方ない、他の方法を考えよう

### EC2でログを集計するスクリプトを動かす

実は、アクセスログを（日本時間での）一日分にマージしたファイルを、S3に置くというスクリプトをdailyで回している。
生成されたファイルをS3から取得→集計→DBにインポートするスクリプトを、上記のスクリプトが置いてあるEC2でdailyでクーロン実行する方法が考えられる。
では、そこで生まれる懸念点を洗い出そう。

* EC2が落ちないかどうか不安
    * →EC2の監視
* クーロンがちゃんと実行されるか不安
    * →クーロンの監視
* ログを一日分にマージするスクリプトにエラーが起きないか不安
    * →スクリプトのエラー監視
* ログ集計を行うスクリプトにエラーが起きないか不安
    * →スクリプトのエラー監視

「安心安全」という言葉がつくと、コードの実装だけではなく監視がまとわりついてくる。
なおかつ監視しているだけではダメで、リトライを行わせたりすることを考えると、自分たちで実装する部分が多くなってしまう。
なるべく監視が少なくすむ方法を、もう少し考える。

### lambda経由でELBログをElasticSearchにインポートする

* lambdaの処理が5分で終わるか不安
    * ElasticSearchのbulkAPIを利用すれば、ログのインポートは早くなる。1ファイル1MB ~ 2MBの場合なら10 ~ 15秒程で処理が終わるらしい。要件証。
* S3からElasticsearchにログをインポートするlambda関数にエラーが起きないか不安
    * →lambdaのエラー監視
* Elasticsearchの容量オーバーでログがインポートされなくなってしまう不安
    * cloudwatchのアラート監視

１つめは、検証結果次第では不安はなくなる。
２つめは、lambdaのログを見れるcloudwatchが大変見づらいので、エラー監視でエラー内容を素早くチェックできるかが肝。
３つめは、ElasticSearchのFree Strage Space(うろ覚え)を、あるしきい値でアラート設定すればOK。また、SNSとlambdaを利用して、自動でElasticSearchのストレージをアップすることができれば、アラートに気づかないという不安を解消できる。

さっきよりもぐっと、監視の数を減らすことができた。
lambdaでELBログをElasticSearchにインポートする事例は、ネット上で沢山転がっているし実現性があるだろう。

### fluentdを利用してEC2のApacheログをElasticSearchにインポートする

* fluentdが落ちないか不安
    * →fluentdの監視
* Elasticsearchの容量オーバーでログがインポートされなくなってしまう不安
    * →cloudwatchのアラート監視

１つめは、mackerelの監視を付ければ簡単にslack等にアラートをながせる。実際に落ちた時は、すぐに立ち上げるという方法しか今のところ取れないが・・・。
２つめは、上と同じなので割愛する。

# 決定

もう一度、要件を復習する。

* 漏れなく、ダブりなくログが集計できること
* 安心、安全にログが集計できる環境であること
* なるべく楽をすること
* ログサイズが大きくなっても問題なく対応できること

Saas系のログサービスを利用したログ集計の構築については、今回は要件に合わなかったので全て見送った。
以下の３つが候補に残ったわけだが、

* EC2でログを集計するスクリプトを動かす
* lambda経由でELBログをElasticSearchにインポートする
* fluentdを利用してEC2のApacheログをElasticSearchにインポートする

最低限の要件は満たせている中で、一番「楽」ができそうなのが「fluentdを利用してEC2のApacheログをElasticSearchにインポートする」だと考える。

選定理由は、fluentdの安定感と、監視をmackerelにお任せできて、なおかつ設定が楽そうだという点だ。
部分テンプレート locales オプション

また、localsというオプションを用いると部分テンプレート内でその変数を使えるようになります。

[例]  render partial: "sample", locals: { tweet: "hello!" }
これで部分テンプレート内においてhello! という文字列の代入されたtweetという変数が使えるようになります。

では、renderメソッドを利用して_tweet.html.erbを呼び出しましょう。



tweets/index.html.erb
`<div class="contents row">
  <% @tweets.each do |tweet| %>
    <%= render partial: "tweet", locals: { tweet: tweet } %>
  <% end %>
  <%= paginate(@tweets) %>
</div>`

ここでのrenderメソッドのlocalsオプションに注目してみます。{ tweet: tweet } の右側の tweet はeachメソッド内の変数としてのtweetでtweetのインスタンスを示しています。一方、左側の tweet は部分テンプレート内での変数の名前を表しています。

 <%= render partial: "tweet", locals: { tweet: tweet } %>
例えば、

 <%= render partial: "tweet", locals: { partial_tweet: tweet } %>
と名前を変更すると、tweetというインスタンスを部分テンプレートの中ではpartial_tweetとして使えるということです。ここでは、partial_tweetの部分の名前も tweetになっています。
NSLayoutConstraint.active は viewDidLoad の中で変更しても反映されない

### 現象

掲題の通り、viewDidLoad の中で NSLayoutConstraint.active を変更しても view には反映されない。

### 対処法

とはいえ view の初期化時に条件に応じて変更したい場合もあるので、

```
dispatch_async(dispatch_get_main_queue()) { [weak self] in
    self?.hogeConstraint.active = false
}
```

のように次のRunLoopに委譲して、ライフサイクルの罠から逃がしてやる。(より良い解決法などあればコメントお願いします)
ユーザーページで回答済みの質問を表示する場合、多対多のアソシエーションを利用する

**方法１**
`#ユーザーが答えた回答を取得する(user_idを1とする)
answers = Answer.where(user_id: 1)

#answersのquestion_idカラムの値で配列にする
#pluckメソッドで任意のカラムを配列として取得することが出来る
question_ids = answers.pluck(:question_id)

#ユーザーが答えた質問を重複なく取得する
Question.find(question_ids)`

**方法２　多対多のアソシエーションのオプションthroughを利用する**
Answerを介したUserとQuestionの関係を多対多の関係と呼び、has_manyにthroughオプションを指定することで、1つテーブルを経由してインスタンスを取得することができます。

《多対多のアソシエーション》
多対多の関係を表現するには、photos_tagsテーブルのような*中間テーブル*が必要です。

中間テーブルには、「どの写真がどのタグと関連づいているか」という情報が全て記載されていることになります。

・has_many throughオプション
`# app/models/photo.rb
class Photo < ActiveRecord::Base
  has_many :photos_tags
  has_many :tags, through: :photos_tags
end`

`# app/models/tag.rb
class Tag < ActiveRecord::Base
  has_many :photos_tags
  has_many :photos, through: :photos_tags
end`

`# app/models/photos_tag.rb
class PhotosTag < ActiveRecord::Base
  belongs_to :photo
  belongs_to :tag
en`

上記のようなアソシエーションを定義することで、自動的に以下のようなメソッドが使えるようになります。

`#通常レコードの作成
tag1 = Tag.create(name: "東京")
tag2 = Tag.create(name: "おしゃれ")
photo1 = Photo.create(image: "cool_cafe.jpg", location: "桜ヶ丘")`

`# 多対多関係を定義したレコードの作成
tag1.photos.create(image: "cute_shop.jpg", location: "宇田川町")`

`# リレーションの追加
tag1.photos << photo1
photo1.tags << tag2`

`# リレーションを利用したレコードの取得
photo1.tags
# => #<Tag id:1, name:"東京">,#<Tag id:2, name:"おしゃれ">`
対話形式でhttpアクセスできるhttp-promptを試す

HTTPieを拡張して、対話形式でhttpアクセスできるhttp-promptというのを試してみました。

# github

https://github.com/eliangcs/http-prompt

# インストール

pipを使います。

```bash
$ pip install http-prompt
```

# 実行してみる

とりあえず、適当なURLで試します。

```bash
$ http-prompt http://qiita.com
Version: 0.2.0
http://qiita.com> 
```

こんな感じで繋げました。

# elixirタグのURLに移動してみる

URLの移動はcdで行うみたいです。

```bash
http://qiita.com> cd tags/elixir
http://qiita.com/tags/elixir>
```

移動できました！

# データを取得する

get/post/headなんかはできるみたいなので、一旦レスポンスが短いheadを

```bash
http://qiita.com/tags/elixir> head
HTTP/1.1 200 OK
Cache-Control: max-age=0, private, must-revalidate
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Fri, 20 May 2016 09:40:59 GMT
ETag: W/"be3f80696e432bac41b243aae48c7bc2"
Server: nginx
Set-Cookie: _qiita_login_session=L0xvRVMrazJkVXdia05obE5hYkxFZ3NZN3kvL2tZNVV4d0I5K1dOWG5seWl4TUNIYU5HYkNsQUFrVVRKQ2hGMm9KbXhMTHZyR08ycDN0OTlKbTFnejZxSzRJT3ErcnFOVjAwUWZaUlc5QjZHd2tHc05PNDU2TW03UzlNOW1CNkt1bGN2R2E0bzBQZzlBZ3JBSnBNK2JLYzhUN3o3MVhPQWFQOXFlUFBhVmVnaDZ1THBxUnBXbEpSK2h0eHFEeVZxLS12cXQ4UU9sV3lmKzI3OUxxemt3N3BBPT0%3D--85b79975eafdf0131bcc0a097269892b297bd80a; domain=.qiita.com; path=/; expires=Sat, 20 May 2017 09:40:59 -0000; HttpOnly
Vary: Origin
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Request-Id: 5a666832-ac20-40d7-aca0-e033c5bf7e82
X-Runtime: 0.402365
X-XSS-Protection: 1; mode=block
```

---

こんな感じで面白そうではありますが、文字コードとかを解析してマルチバイトが文字化けせずに表示されるようになったら対話の意味ありそうだな〜って感じです。

あとHTTPieを使っているので、httpieコマンドは基本的になんでも使えるみたいです。
[java] byte配列をコロン区切りの16進数に変換する

```java
  public static String bytesToCommaSeparatedHex(byte[] bytes) {
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < bytes.length; i++) {
      buf.append(String.format("%02X:", bytes[i]));
    }
    return buf.toString();
  }
```
Chinachu環境で待機時間はシャットダウンさせる

#はじめに
Chinachu環境で待機時間はシャットダウンさせる方法です。Ubuntu 14.04の一般ユーザー（この場合tvユーザー）でテストしています。

#謝辞
これを作るにあたって[録画サーバー向けスクリプトと設定 · GitHub](https://gist.github.com/jtwp470/ca92c6a7b3d1c819acdc)を大いに参考にさせていただきました。おもな変更点は次の通りです。

- 次の録画時間から起動にかかる時間を減ずる処理をchinachuNextからautoshutdownに移した。
- autoshutdown
    - 次の録画時間まで6分あればシャットダウン（35分→6分）。
    - 次の録画時間の3分前に起動（5分→3分）。
    - 録画中、Sambaファイルロック中、SSH接続中のほかに、SMPlayer起動中もシャットダウンしなくした。
        - SSH接続判定において、デスクトップ環境でログオンしていてもシャットダウンするようにした（ptsで絞り込み）。
    - 環境をbashに決め打ちした。
    - ネストをなくした。
    - ログ出力機能を追加した。
    - chinachuNextを同じディレクトリから読むようにした。
    - 次回起動時間の設定にrtcwakeを使用した。
- chinachuNext
    - IPアドレスを決め打ちしなくてもすむように、localhostを参照するようにした。

#準備
- Chinachuの設定でWUIの認証をなくす。
- sudoのパスワードを不要にする。
- http://localhost:10772/api/reserves.json にアクセスできることを確認する。

#シャットダウン・起動テスト
これを実行して3分後に起動することを確認します。

```
NOW=$(date +%s) &&
WAKEUPTIME=$(($NOW + 180)) &&
echo "NOW:        $NOW $(date --date @$NOW --iso-8601=seconds)" &&
echo "WAKEUPTIME: $WAKEUPTIME $(date --date @$WAKEUPTIME --iso-8601=seconds)" &&
sudo rtcwake -m off -t $WAKEUPTIME
```

#ディレクトリ構成
- home
    - tv
        - cron
            - autoshutdown #本体
            - chinachuNext #次の録画時間を返す（要Python3）
            - crontab #cronの設定ファイル

#autoshutdown
- 次の録画時間までが6分（360秒）より長ければシャットダウン。
- 録画時間の3分前（180秒）に起動。
- chinachuNextはスクリプトと同じディレクトリに配置。
- LOG=trueでスクリプトと同じディレクトリにログを出力。
- デスクトップ環境を前提に、SMPlayerを起動しているときはシャットダウンしない。

```
#!/bin/bash
LOG=true # LOG=true LOG=false

REALPATH=$(cd $(dirname $0) && pwd)

# -lt <     -le <=     -eq =     -ne !=
[ 1 -lt $(ps aux | grep 'recpt1' | wc -l) ] && exit
[ 0 -lt $(sudo smbstatus -L | grep -E ' (EXCLUSIVE\+BATCH|EXCLUSIVE|BATCH|LEVEL_II) ' | wc -l) ] && exit
[ 1 -lt $(ps aux | grep 'smplayer' | wc -l) ] && exit
[ 1 -lt $(ps aux | grep '/usr/bin/mpv' | wc -l) ] && exit
[ 0 -lt $(who | grep ' pts/' | wc -l) ] && exit

NOW=$(date +%s)
NEXTTIME=$(python3 "$REALPATH/chinachuNext")
WAKEUPTIME=$(($NEXTTIME - 180))
INTERVAL=$(($NEXTTIME - $NOW))

[ $INTERVAL -lt 360 ] && exit

$LOG && echo "$(date --iso-8601=seconds) shutdown WAKEUPTIME: $(date --date @$WAKEUPTIME --iso-8601=seconds)" >> $REALPATH/autoshutdown.log
sudo rtcwake -m off -t $WAKEUPTIME
```
2016年9月10日、いろいろ修正しました。旧バージョンだとシャットダウンしなかったかも…。

#chinachuNext
```
#!/usr/bin/env python3

from urllib.request import urlopen
import json
import io
import time

class Reserves:
    def __init__(self, url):
        response = urlopen(url)
        self.o = json.load(io.TextIOWrapper(response, response.getheader('content-type').split('charset=')[1]))
    
    def getNextTime(self):
        now = time.time()
        for e in [ int(ent['start'] / 1000) for ent in self.o if ent['start'] / 1000 > now ]:
            return e

if __name__ == '__main__':
    url = 'http://localhost:10772/api/reserves.json'
    print(Reserves(url).getNextTime())
```

#crontab
10分に一回、autoshutdownを実行します。

```
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow command
*/10 *	* * *	~/cron/autoshutdown
```

#crontabを反映
```
crontab ~/cron/crontab
```

#テスト実行
```
chmod 700 ~/cron/chinachuNext && chmod 700 ~/cron/autoshutdown && ~/cron/autoshutdown
```
font-smoothingで文字の野暮ったさとサヨナラして、font-smoothingの謎とコンニチハした

# 元はと言えば
CSSでアニメーションを付けたページを作成している際に、SafariとChromeでアニメーション作動時に何故か文字が一瞬「ピョッ」っと太さが変わってチラつく、ということがありました。

解決策を探っているうちに
[Safari,Chromeで文字が太くなる現象の解消](http://qiita.com/artprojectteam/items/7bb1f042d163ebd109a1)
[font-smoothingでOSXでのフォントのレンダリング方法を調整する](http://qiita.com/htomine/items/3086f30ca09adea2f8e0)
こちらの記事に辿り着き、実際に適用してみると見事に問題が解決しました（本当にありがとうございますm(_ _)m）。
ということで一件落着ー。めでたしめでたしー。

##嬉しい副作用

しかし、それはもとより何となくページ全体に漂っていた野暮ったさが無くなったのです。同じフォントを表示しているはずなのにワンウェイト落としたような見た目になり、今流行りの細めのフォントを使っているような感じになりました。

ということで、見た目もビシッと決まってデザイン面においても幸せになれるので、設定の仕方とどうなるかをここでも布教させていただきたいと思います。

# 設定

まず、以下のようなHTMLを用意します。

```html:
  <p>これはアンチエイリアスの方式がデフォルトのテキストです。</p>
  <p class="antialiased">これはアンチエイリアスの方式を指定したテキストです。</p>
```
そしてCSSを

```css:
.antialiased {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
```
このように設定してやると、
![001.png](https://qiita-image-store.s3.amazonaws.com/0/118358/ca7d7847-4190-48cf-e432-039790363449.png)
上の画像のようになります。

指定をかけた下の一文は、ご覧のように細めでキリッとして知的な印象になります。ちなみにベンダープレフィックスによって違う値が設定されていますが、結果は一緒（のはず）です。ここではフォントの色は`#333333`、サイズは`16px`を指定しています。

# 何が起こってるの？
![002.png](https://qiita-image-store.s3.amazonaws.com/0/118358/e9b2e149-eadb-0e64-e464-3042d684fbcb.png)

拡大するとこのようになります。
デフォルトの方は横方向のサブピクセルが青/オレンジ系の色になっているのに対して、font-smoothingをかけた方はグレーになっています。`-moz-…`の値の名のとおり「グレースケール」になっているわけですね。

そしてよく見ていただきたいのが「ア」の上の棒。デフォルトでは中心部が指定した色に近いのに対し、font-smoothingの指定をかけた方は色が薄くなっています。つまりこれは、

これは…

**ん？**

これって

- **実際に**細めにレンダリングをしてる
- 細めに**見えるような**レンダリングをしてる

のどっちなんだろ…？

# どっちや。

気になった以上は白黒ハッキリつけてやりたい。~~`grayscale`だけにwwww~~

検証のためにフォントサイズを`256px`に上げてスクショを撮り、画像編集ソフトで文字の太さを確認します。
16pxでアレだけの差があったということは、もし「実際に細めにレンダリングしてる」ならフォントサイズが上がればその差も大きくなることでしょう。

---
![003.png](https://qiita-image-store.s3.amazonaws.com/0/118358/76faa418-d12c-b400-b6b7-47498cffb168.png)
font-smoothing指定：無
サブピクセル：含む
→18px

![004.png](https://qiita-image-store.s3.amazonaws.com/0/118358/9bfc6f73-34bb-763c-de1e-78c42cc726d3.png)
font-smoothing指定：無
サブピクセル：含まず
→16px

---

![005.png](https://qiita-image-store.s3.amazonaws.com/0/118358/2585809a-a8be-11d0-1a92-7550e11f6a04.png)
font-smoothing指定：有
サブピクセル：含む
→18px

![006.png](https://qiita-image-store.s3.amazonaws.com/0/118358/f9244311-dc30-be61-9c4c-06bbbf3aebbf.png)
font-smoothing指定：有
サブピクセル：含まず
→16px

---
お。

ということはこれは「サブピクセルの色が薄めなだけ」、つまり

**細く見えるようなレンダリングをしてる**

…というのが僕の結論です。
（もっと詳しい方・答えを御存知の方がいらっしゃいましたら、是非ともお手柔らかにお願いします。）

さて、話が逸れましたが、

# メリット
文字が細く見えるので、長文でもパッと見たときの圧迫感が少なくなります。（実際に小説の投稿サイトなんかで使われてました。）
また最近よく見かけるウェイトが軽いフォントのように見せることも出来るので、モダンな印象にもなります。

そして冒頭でもあったように、一部ブラウザでのCSSのアニメーション動作時の文字のチラつきと無縁になります。

# 注意点
フォントサイズが小さ過ぎると文字の色がかなり薄くなったり、明朝体やセリフ付きのフォントの細い部分（ヘアラインストロークやアーム等）が潰れて、読みづらくなる可能性があります。
設定する際はフォントサイズや、文字と背景色のバランスを見ながら作成・調整すると良いでしょう。

## 残念なお知らせ
そもそもの話になってしまうのですが、このfont-smoothingは残念ながら**OS Xで動作するもの**なので、全ての環境でこうなる訳ではありません。ですが入れておいて損は（あまり）無い（はずな）ので、試してみてはいかがでしょうか。
Python(Pandas/XlsxWriter)を使ってExcelファイルを操作してみる②



今後はExcelファイルを読み込む編。

ついでにCSVファイルを読み込むバージョンも。

[ファイルの出力についてはこちら](http://qiita.com/katzhide/items/462bac9a8c046e1cd6fe)

## 参照
* [pandas#read_excel](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_excel.html)
* [pandas#read_csv](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html#pandas.read_csv)


## Excelファイルを読み込む

```python
# import lib
import pandas as pd

# read xlsx file
xlsFile = "hoge.xlsx"
sheetName = "hoge1"
xls_data = pd.read_excel(xlsFile, sheetname=sheetName)
print(xls_data)

```

## CSVを読み込む

```python
# import lib
import pandas as pd

# read csv file
csvFile = "fuga.csv"
csv_data = pd.read_csv(csvFile, encoding='utf-8')
print(csv_data)

```

## おまけ

### 指定した位置のデータを読み込む

列指定
```py
xls_data = pd.read_excel(xlsFile, sheetname="hoge1", parse_cols="A:H")
```

行指定

```py
xls_data = pd.read_excel(xlsFile, sheetname="hoge1", skiprows=0, skip_footer=5)
```

行列指定したい場合は両方指定すればいい。`A1:H5`みたいに指定できればいいけど、それはできなさげ？