OmniAICreator/Qiita-1.07M huggingface dataset:
アドウェア、デモンストレーション用ソフト「あおい」解説

[掲載ブログ](http://blog.livedoor.jp/a17646158162488/archives/1051724191.html "How to hack・初心者でもわかるハッキングのやり方")
#VBプロジェクト構造
- ApplicationEvents.vb
- Class.vb
- Module1.vb

プロジェクトファイルはもっとありますがコードを入力するのは基本このファイルです。
#プログラム解説
##壁紙更新
```VBScript
Dim path As String = System.IO.Path.GetFullPath("test.bmp")
Dim registry As Microsoft.Win32.RegistryKey
registry = Microsoft.Win32.Registry.CurrentUser.CreateSubKey("Control Panel\Desktop")
registry.SetValue("Wallpaper", path)
registry.Close()
```
一行目で相対パスから絶対パスを取得します。これは壁紙変更の際にレジストリキーを書き込むのですがそれには当然絶対パスが必要だからです。
二行目でレジストリキーを書き込むための変数を宣言しています。三行目で```Control Panel\Desktop```と書きこむ場所を、四行目で書き込む値を入れます。
これで壁紙を変更します。
##お気に入り操作
```VBScript
For Each tempFile As String In _
	System.IO.Directory.GetFiles("C:\Users\" & System.Environment.UserName & "\Favorites")
	System.IO.File.Delete(tempFile)
Next
Dim shortcutPath As String = System.Environment.GetFolderPath(Environment.SpecialFolder.Favorites) & "\test.url"
'ショートカットのリンク先 
Dim targetUrl As String = "http://blog.livedoor.jp/a17646158162488/"
'テキストファイルに書き込む 
Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("shift_jis")
Dim sw As New System.IO.StreamWriter(shortcutPath, False, enc)
sw.WriteLine("[InternetShortcut]")
sw.WriteLine("URL=" & targetUrl)
sw.Close()
```
お気に入りフォルダのパスは
C:\Users\ユーザー名\Favorites
となっているのでユーザー名を```System.Environment.UserName```で取得しました。二回目は
```System.Environment.GetFolderPath(Environment.SpecialFolder.Favorites)```
を使ってパスを取得しました。(途中で書き方が変わったのは日付をまたいで作成したからです。許してね)
一行目のfor文では```In System.IO.Directory.GetFiles```でフォルダー内のファイルの数だけ繰り返します。
三行目ではフォルダー内のファイルパスが```tempFile```に代入されるのでそれを削除していきます。
次に五行目ではお気に入りフォルダーにショートカットを作るのでお気に入りフォルダーのパスの末尾に```\test.url```を挿入してショートカットのパスを作ります。
七行目ではショートカット先のURLをセットします。
ショートカットは.urlファイルをテキストで編集出来るのでテキスト編集からショートカットを作成します。
九行目以降のフォーマットに従って書けばメモ帳からでもショートカットは作れます。
##子ファイルの検索と作成
これ、あおいにはあおい.exeの他にaoi.htaという子ファイルを作成します。
あおいが起動
↓
あおいが自分と同じ階層にあるフォルダーからaoi.htaを探す
↓
あれば起動、無ければ作成して起動

これ・・・**可愛くない？**
だって起動したら必死で友達(aoi.hta)を探して見つけたらすぐ起動するし見つからなかったら頑張って一から作るんだよ
こんな可愛いこの機能だけど不充分でとりあえず公開したのが「あおい」だから今回の数倍バージョンアップさせた「あかね」を今後公開します。そこで解説予定
##IEのホームページ設定の変更
```VBScript
WshShell = CreateObject("WScript.Shell")
WshShell.RegWrite("HKCU\Software\Microsoft\Internet Explorer\Main\Start Page","http://blog.livedoor.jp/a17646158162488/", "REG_SZ")
WshShell = Nothing
```
IEのホームページの設定はレジストリキーで```HKCU\Software\Microsoft\Internet Explorer\Main\Start Page```格納されています。そこに値であるURLをセットします。

注）*ここで例としているコードは文字数の都合上本来のコードと異なり変数を省いて直接引数で渡している場合があります*
Ansible で Systemd の設定を書き換えた際の reload ハンドラの書き方



とりあえず、手元の Ansible 2.0.0.2 の “service” モジュール（[service - Manage services. — Ansible Documentation](http://docs.ansible.com/ansible/service_module.html)）では、自動的には全く `systemctl daemon-reload` をしてくれないので、Systemd の設定を書き換えた後に、勝手には反映してくれない。

2015 年の暮れくらいでも右記のようなやりとりが。まだ、特に Ansible 側に機能は無い模様。 ∥ [make the system module call daemon-reload on systemctl control by oaken-source · Pull Request #2676 · ansible/ansible-modules-core](https://github.com/ansible/ansible-modules-core/pull/2676)

仕方がないので、下記のようなイディオムで対応します。SysV Init や Upstart では単純にハンドラで “service” に “restart” をさせますが、Systemd では二段構えのハンドラを使い、“daemon-reload“ をしてから “restart” をさせます。

~~~~yaml:handlers/main.yml
- name: Restart Docker (systemd)
  shell: systemctl daemon-reload
  notify: Restart Docker
- name: Restart Docker
  service: name=docker state=restarted
~~~~

なお、Ansible では残念ながら、複文というか、一つのハンドラで二つ以上のモジュールは列挙して実行できないみたいなんだな（えー…）。 ∥ [How do I write an Ansible handler with multiple tasks? - Stack Overflow](http://stackoverflow.com/questions/31618967/how-do-i-write-an-ansible-handler-with-multiple-tasks)

呼び方としては、以下のようになる。Docker サーバのストレージドライバとして、標準の aufs ではなく devicemapper を使わせる設定の、Upstart と Systemd 両対応。

~~~~yaml:tasks/main.yml
## For SysV Init and Upstart
- lineinfile:
    dest: "/etc/default/docker"
    regexp: '^DOCKER_OPTS='
    line: 'DOCKER_OPTS="--storage-driver=devicemapper"'
  notify: "Restart Docker"
## For Systemd
- file:
    dest: /etc/systemd/system/docker.service.d/
    state: directory
    mode: 0755
- copy:
    content: |
      [Service]
      ExecStart=
      ExecStart=/usr/bin/docker daemon -H fd:// --storage-driver=devicemapper
    dest: /etc/systemd/system/docker.service.d/default-file.conf
    mode: 0755
  notify: "Restart Docker (systemd)"
- meta: flush_handlers
- name: “devicemapper” is being used for storage driver
  shell: 'docker info 2>&1 | grep -q "Storage Driver: devicemapper"'
  changed_when: false
~~~~

では。
HTML,CSS勉強メモ #18 ～iframeのとこどうなってるのか？の件～

本日はこれで終わりました・・・

##**進度**##
<dl>
<dt>レスポンシブなウェブサイトを作ろう10,11</dt>
<dd>iframeのとこがどうなってるのか考えてみた。</dd>
</dl>

##**メモ**##
確信的な答えとは言えませんが、一応こんな感じでしょうか？

```css
.movie {
   position: relative;
   height: 0;              /* ％で指定しても親基準の高さなので`iframe`の高さと合わない */
   padding-top: 56.25%;    /* 親は関係ないのでここで正確な高さにしてあげれば結果iframeと合う */
}
iframe {
   position: absolute;     /* 他の要素に重ねられる */
   top: 0;                 /* .movieの頭と合わせる */
   left: 0;
   width: 100%;            /* 横幅をレスポンシブ対応 */
   height: 100%;           /* 高さをレスポンシブ対応 */
}
```

ということで納得しました。

`.movie`の`height: 0;`は敢えて書かなくても良い気もするのですが・・・明示的にってことでしょうか？
あと、デベロッパーツールで確認したところ`left: 0;`はなくても変わらなかったのですが・・・
どうなのでしょう？
まだ疑問は残りますが、あまりハマりすぎると先に進めなくなるので今回はこのくらいにしておきます。
APIドキュメントをSwaggerで簡単に用意する (Apache Camel)


# Swaggerとは

http://swagger.io/

json形式でAPIドキュメントを作成するというフォーマット。
UIも準備されている。

詳しくは検索してみて。


# Apache Camel + Swagger

Apache Camelを使うと自前でSwaggerのjsonを書く必要がない。


# サマリ

Camelで実装

サーバの初期設定 (spring用xmlで定義することも可能）

```java
restConfiguration().component("netty4-http").bindingMode(RestBindingMode.json)
        .dataFormatProperty("prettyPrint", "true") // jsonの整形
        .contextPath("/").port(18181) // httpサーバ (netty)の設定
        .apiContextPath("/api-doc") // swagger api doc の url
        .apiProperty("api.title", "Example API") // api title
        .apiProperty("api.version", "1.2.3") // api version
        .enableCORS(true) // rest用
        .apiProperty("cors", "true"); // api doc用
```

RESTの定義

```java
// user
rest("/user").description("ユーザーサービス")
        .consumes("application/json").produces("application/json")

        // HTTP GET
        .get("/{id}").description("IDからユーザー情報を取得")
        // パラメータの説明
        .param().name("id").type(path).description("取得するユーザーのID").dataType("integer").endParam()
        .to("direct:xxx")

        // HTTP POST
        .post("").description("ユーザーを新規追加")
        .param().name("body").type(body).description("").required(false).endParam()
        .to("direct:yyy")
;
```

このようになる

<img width="987" alt="スクリーンショット 2016-04-16 20.18.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/37624/a74d0857-2ef9-ad6b-5bb7-9c793d2de48a.png">


# 環境

<img width="400" alt="スクリーンショット 2016-04-16 21.48.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/37624/363d2af3-6e8c-ab3f-ae8d-70d71269cdc7.png">

* swagger ui
    * http://swagger.io/swagger-ui/
    * PCにダウンロードしたhtmlファイルをダブルクリック （特別なサーバは不要）
* APIサーバ
    * Camelで作ったもの
* swagger ui --> APIサーバ
    * swagger uiのjavascriptがajaxでアクセスする
    * camelのrest設定でcors（クロスドメイン）を許可するとブラウザがアクセスしてくれる
    * 矢印はswagger uiが直接apiサーバを呼び出しているように見えるが、単なるhtmlなのでswagger uiのjavascriptの指示によりブラウザがapiサーバにアクセスしているだけ

# 利用するライブラリ

```xml:pom.xml
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-swagger-java</artifactId>
    <version>${camel-version}</version>
</dependency>
```

# 全ソースコード

https://github.com/d7kuro/HelloCamelSwagger
vscode コマンドパレットが日本語化されたので対応策をメモ

解決策ページをメモっておく

https://blogs.msdn.microsoft.com/ayatokura/2016/04/15/%E3%80%90visual-studio-code%E3%80%91%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%8C%E6%97%A5%E6%9C%AC%E8%AA%9E%E5%8C%96%E3%81%95%E3%82%8C%E3%82%8B%E3%83%90%E3%82%B0%E3%81%8C%E4%BF%AE%E6%AD%A3%E3%81%95/
Linuxメモ - コマンドラインの編集

操作
Ctrl + b：１文字戻る
Ctrl + f ：１文字進む
Esc + b：単語１つ分戻る
Esc + f ：単語１つ分進む
Ctrl + a：行の先頭へ移動する
Ctrl + e：行の最後尾へ移動する

Ctrl + h：カーソル位置の後方に１文字削除する（BackSpaceキーと同じ動き）
Ctrl + d：カーソル位置の１文字を削除する（Deleteキーと同じ）
Ctrl + w：後方へスペース区切りで１単語分削除する
Ctrl + k：カーソル位置から行末までを削除（切り取り？）する
Ctrl + u：カーソル位置から行頭までを削除（切り取り？）する
Ctrl + y：最後に削除した内容を挿入する

Ctrl + s：画面表示をロックする
Ctrl + q：画面表示のロックを解除する
Ctrl + l ：画面を消去する（clearコマンドと同じ）

Ctrl + p：１つ前のコマンド履歴に移動する（↑キーと同じ）
Ctrl + n：次のコマンド履歴へ移動する（↓キーと同じ）
Ctrl + r ：履歴を遡ってインクリメンタル検索する（コマンド履歴の検索）
 Ctrl + r ：１つ前の検索結果へ移動する
 Enterキー ：現在の検索結果を実行する
 Escキー ：現在の検索結果を表示したまま、コマンドラインへ戻る
 Ctrl + g：検索結果を破棄し、プロンプトへ戻る
telnetでgmailへメールを送るコマンド(Bash)

telnetを使って、**gmailのメールアドレス**へメールを送ることが出来ます。（2016/04/15現在）
SMTPサーバーの仕様が変われば、使えなくなる可能性があります。

## Bash

```bash
(echo "EHLO example.com"; sleep 1
echo "MAIL FROM: <example@example.com>"; sleep 1
echo "RCPT TO: <example@gmail.com>"; sleep 1
echo "DATA"; sleep 1
echo "Subject: Subject"; sleep 1
echo "From: example@example.com"; sleep 1
echo "To: example@gmail.com"; sleep 1
echo ""
echo "Content"
echo ""
echo "."; sleep 1
echo ""
echo "quit") | telnet gmail-smtp-in.l.google.com 25
```

## 参考
[telnetでメール送信 - つれづれなるままに](http://d.hatena.ne.jp/KuroNeko666/20071113/1194931378 "telnetでメール送信 - つれづれなるままに")
CentOS6 に nginx を yum からインストール


CentOS6.7 にnginxの Mainline を yum でインストールした時のメモです。

# yum リポジトリの登録

yum でインストールするため、yumのリポジトリを登録します。

```bash
$ sudo rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
```

Mainlineをインストールしたいので、「/etc/yum.repos.d/nginx.repo 」を修正します。
stable の場合 nginx.repo は修正しなくて良いです。


```bash:/etc/yum.repos.d/nginx.repo
# nginx.repo

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/6/$basearch/
gpgcheck=0
enabled=1
```

baseurl に mainline を追加しました。

# インストール

リポジトリの登録が終わったのでインストールします。

```bash
$ sudo yum install nginx
```

これでインストールは完了です。
ひとまずデフォルト設定で起動します。
（設定ファイルは「/etc/nginx/nginx.conf」にあります。）

```bash
$ sudo service nginx start
```


# 参考

http://www.atmarkit.co.jp/ait/articles/1407/24/news003.html
chmodの124

仕事で755とか644とかを目にすることがあります。

755, 644, 755, 644, 755, 666, ...

慣れれば大したことではないとは思うのですが、<b>まったく覚えられません</b>。

心配ありません。これだけ覚えておけばokです。

xは1, wは2, rは4.

7は4+2+1なのでrwxということになります。

755の7は誰の権限か?

これも問題おおありです。

ugo, 勇午と覚えましょう!

uは所有者、gはグループ、oはその他。

なので、所有者の権限が7で、グループの権限が5で、その他の権限が5ということになります。

以上
既存のプロジェクトをBitBucketに上げるには？


## 躓いていること
bitbucket上にリポジトリを作り、それのクローンをクライアントに作り、そこにプロジェクトをコピーするという流れならばわかり易いのだが・・・

### 今までの手順
1. bitbucket上に新規リポジトリを作成
2. ローカルにクローン
3. ローカルのクローンフォルダに必要なソースをコピー
4. リモートとコピー

## 調べた手順

1. 既存のフォルダを保存先に指定して、リポジトリを作成
    2. cd [フォルダ]
    3. git init
2. SourceTreeでリポジトリを「開く」
3. bitbucket上に新規リポジトリを作成する
    * ![image](https://qiita-image-store.s3.amazonaws.com/0/42407/420871d2-e043-ebe6-438e-e7fa82815aea.png)
    *![image](https://qiita-image-store.s3.amazonaws.com/0/42407/20afc4e6-6536-caf0-c383-8339279390e4.png)
    ![image](https://qiita-image-store.s3.amazonaws.com/0/42407/40751a3c-dc71-a5f1-7980-7d22b5211df7.png)
4. 上で作ったBibtbucketのリポジトリをリモートリポジトリとして追加
    * ![image](https://qiita-image-store.s3.amazonaws.com/0/42407/a4a0c36e-c086-f0a7-d41d-ff80134683ff.png)
    * ![image](https://qiita-image-store.s3.amazonaws.com/0/42407/dc82e488-0102-487c-450d-ac0a5b2a8248.png)
冒頭文つきで、CocoaPods経由のOSSのライセンス表記を自動化する

# はじめに
CocoaPods経由でOSSを複数インストールしていくとライセンス表記の追記作業を自動化したくなります。

Setting.bundleの中のAcknowledgements(謝辞)項目への追記作業を自動化する方法は、こちらの記事に詳しいです。

ライセンス表記の自動作成
http://qiita.com/mox2/items/545f1d39e4829907ac42

CocoaPods経由のOSSのみのライセンスだけを列挙する場合は、この説明の通りにやると出来ました。(Pods経由が生成した.PlistをFileUtils.cp_rでSetting.bundle下の.plistと置き換える方法)

*(2016年10月17日追記: この点、CocoaPods1.0.0以降ではパスが少し変わっていて、No such file or directory @ rb_file_s_stat - Pods/Target Support Files/Pods/Pods-acknowledgements.plistのようなエラーが発生します。**解決方法については[CocoaPods1.1.0.rc.3でpod updateして遭遇したエラーと解決方法](http://qiita.com/hsylife/items/e3f6b6cb433ca6cfa71b)をご覧ください。**)*

ただ、このままですと、Podsを使わずに手作業で導入したOSSのライセンス表記や、その他の貢献者への感謝の言葉などを挿入したいときに困りました。

謝辞の冒頭のほうで、Special thanks to ** とか、手作業で入れたOSSのCopyright 2016- ** のような文を入れつつ、その下にPodsが生成したランセンス表記を入れたいです。

そこで調べてみると、公式の方法がありましたので、その工程についてメモを残したいと思います。

# Podfileで文字列を指定する

任意の文字列を挟む方法は、公式に用意されていました。
https://github.com/CocoaPods/CocoaPods/wiki/Acknowledgements

例えば、全体の冒頭に文字列“Special thanks to **”を挿入したい場合、Podfileの中で次のように指定します。

```Podfile
class ::Pod::Generator::Acknowledgements
  def header_text
    “Special thanks to **”
  end
end
```

次に、pod install(あるいはpod update)します。

これだけです。

これで、
1. Acknowledgements
2. Special thanks to **
3. (以下、Pods経由のOSSのランセンス表記が続く)
という構造の.Plistを自動生成できるようになります。

# ちょっとした不満
上のような並びになるのですが、どうも1と2の間に改行がかなり入ってしまい、間延びした形になってしまいます。この点は何か解決方法がないものか模索中です。

# “(ダブルクォーテーション)について
細かい点ですが、一度ひっかかったのでメモとして。

PodfileはRubyの文法で書くので、文字列の中に“(ダブルクォーテーション)などの特殊な文字が含まれる場合、そこを特殊文字で書き換える必要があります。
例えば、こういう、そのままコピペする文言の中でダブルクォーテーションが使われているときがあります。
>Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the **"Software"**), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

この場合は、" "　→　\” \”と置換すれば大丈夫です。

ですので、上の文章は以下のようになります。

```Podfile
　"(省略)  (the \"Software\"), to deal in (省略)"
```

# Bundle.settingのiOS9.3のバグ

もう一つ気になった点をメモします。
iOS9のバグのために、Settings.bundleとRoot.plistを更新してしまうと、独自の設定項目が何も表示されなくなります。

[こちらの記事](http://qiita.com/nkawa/items/fc5a5e002724cb0c489a)に詳しいのてですが、執筆時最新版のiOS9.3.1においても、同じ現象が起きます。

iOS9 で、アプリ独自の設定(Settings.bundle)ができない場合への対応
http://qiita.com/nkawa/items/fc5a5e002724cb0c489a

この場合、一度、設定アプリを終了させてから設定アプリを再度開くと直ります。iOS9のバグが早く直るとよいですね。
target/actionの代わりにclosureで処理を書けるマイクロライブラリを作りました

## その名もActionClosurable

https://github.com/takasek/ActionClosurable

## どう使うか

以下のクラスおよびサブクラスがextensionで拡張されており、クロージャで処理を書くことができるようになっています。

`UIControl`, `UIButton`, `UIGestureRecognizer`, `UIBarButtonItem` and `NSTimer`

こんなふうに書けます。

```swift
let barButtonItem = UIBarButtonItem(title: "title", style: .Plain, closure: { _ in
    print("barButtonItem title")
})

button.on(.TouchDown) {
    $0.backgroundColor = UIColor.redColor()
}
button.on(.TouchUpOutside) {
    $0.backgroundColor = UIColor.whiteColor()
}
button.onTap {
    $0.enabled = false
    print($0)
}

self.gr = UITapGestureRecognizer? = UITapGestureRecognizer()
view.addGestureRecognizer(gr!)
gr?.onGesture { [weak self] in
    $0.removeTarget(nil, action: nil)
    self?.gr = nil
}

var i = 5
self.timer = NSTimer.scheduledTimerWithTimeInterval(1, repeats: true) { [weak self] timer in
    print("timer", i)
    i -= 1
    if i <= 0 {
        timer.invalidate()
        self?.timer = nil
    }
}

```

なお、NSObjectを継承しているクラスであれば、好きなように拡張できます。めっちゃ簡単です。
どれだけ簡単かは、[実際のソース](https://github.com/takasek/ActionClosurable/blob/master/ActionClosurable/Extensions.swift)を読んでいただければ分かるかと。

```swift

extension ActionClosurable where Self: UIButton {
    public func onTap(closure: Self -> Void) {
        registerClosure(closure) {
            self.addTarget($0, action: $1, forControlEvents: .TouchUpInside)
        }
    }
}

extension ActionClosurable where Self: NSTimer {
    public static func timerWithTimeInterval(ti: NSTimeInterval, repeats yesOrNo: Bool, closure: Self -> Void) -> Self {
        return registerClosure(closure) {
            let timer = Self.init(timeInterval: ti, target: $0, selector: $1, userInfo: nil, repeats: yesOrNo)
            return timer
        }
    }
}
```

こんな感じ。ね、簡単でしょ？


## 使った技について

ActionClosurableはマイクロライブラリなので、短いソースです。[コアのロジック](https://github.com/takasek/ActionClosurable/blob/master/ActionClosurable/ActionClosurable.swift)は実質40行足らず。
長々と解説するものでもないんで、今回のこだわりポイントをざっくり箇条書きで挙げます。

- プロトコル指向
    - 常に型を `Self` で表現することで、指定したクロージャでは引数に対して柔軟に型推論が掛かります。たとえば、UIButtonを継承したHogeButtonを作ったら、クロージャの型も自動的に `HogeButton -> Void` になります。 
- `@noescape`
    - **いいえ逃**。
    - `registerClosure` の中身で `[weak self]` とか書かなくていいの、気持ちいいですね。
- `objc_setAssociatedObject`, `objc_getAssociatedObject`
    - プロトコルの中でストアドプロパティを保持できるようになる裏技。
    - actionを複数個設定しても動くように、ArrayやSetを噛ませて保持させようとしたら、どうも思ったタイミングでリリースされなくて結構ハマった。ここらへんの事情はそのうち単独の記事にしようかなと思います。


## ほかにもライブラリ作ってますので良かったら是非

[NotifwiftでNSNotification.userInfoをSwiftyに扱おう - Qiita](http://qiita.com/takasek/items/141adc4bbc58894551cd)
処理フローとデータの流れをつかむ

新人教育用のメモ。

# プログラム設計で大切なこと
おしごとでプログラミングをする場合、SEが書いた仕様書をもとにプログラムを組みます。
たいてい仕様書には実装方法ではなく実装させたい機能（表に見える結果）しか記述されていないので、プログラマ側がソースレベルのプログラム設計を行う必要があります。

プログラム設計を行うとき、個人的には以下の3点が重要だと思っています。
1. 処理フローのをパターン網羅する
2. 処理に使うデータの発生場所をつかむこと
2. データの変更箇所を把握すること

これについて少し語ります。
※GUIアプリ（Windowsアプリ）開発の話です。C#てきな言い回しをします。
※要は入力フォーム（テキストボックス）とかボタン等が配置された画面が出てくるプログラムです

## 1. 処理フローとパターンをつかむ
GUIアプリのフローは基本的には以下のようになっています。
（起動） → 初期処理 → 画面表示 → （イベント発生） → イベント処理 → メソッド(関数)を呼ぶ等... → 画面表示に戻るor終了

イベントとはユーザの操作にをきっかけに発生する処理です。
ボタンをクリックした時とか、入力フォームに文字を入力した時とかのことです。
あえて初期処理と書いていますがこれも起動時のイベント処理です。

つまりユーザの操作次第でプログラムの動きが変わります。これをイベントドリブンとか言います。
ということはイベント発生時の状態は何通りもありえるわけで、この辺を考慮して設計しないとバグが発生します。

例えば[単価]と[数量]の項目に入力があった時、自動で[金額]項目に単価×数量を計算するという仕様があるとしましょう。
この時に[単価]と[数量]の入力時に
「[単価]と[数量]に入力された値を数値に変換して、乗算した値を[金額]にセットする」
という機能を実装するだけじゃだめなんですね。

このままだと[単価]を入力したときに[数量]が入力されていなかった場合、どうしたらいいと思いますか？
[単価]と[数量]どちらかが入力されていない場合は金額は計算しないとか、
そもそも空欄の場合はエラーが出て入力させなおすとか、
空欄の場合は0にしてしまうとか、
そういった視点が必要になります。
仕様書に書いてない場合は、SEに相談する必要があります。

上の例のような簡単な内容だったら深く考えなくてもわかると思いますが、複雑な仕様になるとパターンが増えて、抜け漏れが発生しやすくなります。
なので、フローとパターンは意識しておいたほうがいいでしょう。
で、そのパターンを割り出すために、2. データの居場所、変更されるタイミングを把握するが必要になります。

## 2. データの居場所、変更されるタイミングを把握する
GUIなんでデータの居場所もいっぱいあるんです。
* コントロールの値（入力フォームとかテキストボックスに入力された値）
* メソッド（関数）の引数
* メソッド（関数）内で定義した一時変数
* メンバ変数（画面内のグローバル変数みたいなもの）
* DBに格納されている値
* （WEBだと隠し項目、セッション、クエリ文字列もあるね…）

データの居場所に応じて、発生・変更されるタイミングが異なります。
* コントロールの値：初期値、ユーザによる入力、イベント処理による変更
* メソッドの引数、一時変数：メソッドが呼び出された時、メソッド内の変更
* メンバ変数：初期値、イベント処理による変更
* DB：更新された時（ほかのプログラムから更新される可能性もあり）

という感じで、データによって変更されるタイミングがまちまちです。
つまり、イベント発生時のデータの状態は、様々なパターンがありうるのです。

1.の例でいうと、[単価][数量]のコントロールの値の組み合わせだけでも
[単価]、[数量]どちらも初期値
[単価]がユーザによって入力された値、[数量]が初期値
[単価]が初期値、[数量]がユーザによって入力された値
[単価]、[数量]どちらもユーザによって入力された値
の4パターンが存在することになります。
さらに[単価]や[数量]が数字以外の「a」などが入力された場合、マイナス値が入力された場合、などを考慮する必要がある場合、さらにパターンが増えたりします。
ここで金額を計算するロジックをメソッド化した場合、引数として入ってくる値のパターンを考慮する必要があります。
このパターンを減らすために、入力される値を制限するような仕組み（入力パターンを制限するためにドロップダウンリストにする、誤った値が入力された時にエラーを出す等）が採用されたりします。
この仕組み自体に欠陥があるとバグが発生するので、仕様によって生じるパターンを正確に把握できるようになりましょう。

# まとめ
プログラム設計を行うとき、以下の3点を意識しましょう！
1. 処理フローのをパターン網羅する
2. 処理に使うデータの発生場所をつかむこと
3. データの変更箇所を把握すること
Google Apps Script で Spreadsheet のセルのデータ操作についての備忘録

sheet オブジェクトを取得する方法はこちらをご参照ください。 http://qiita.com/negito6/items/c64a7a8589faaffcfdcf
本記事内のスクリプトで、 `sheet` という変数は全て上記の方法で取得した「Spreadsheet の一つの sheet」 を表しています。

# データ取得系
## セルの番地を指定してデータを取得

```js
  var range = sheet.getRange("A1"); // A1 のところがセルの番地
  var values = range.getValues();
  var value = values[0][0];
```

_range_.getValues は、値を二重配列で取得します。
それは、明らかに単一のセルを指定しているときも同じです。

## シートの全セルのデータを取得

```js
  var values = sheet.getDataRange().getValues();
```

* _sheet_.getDataRange は、値が入っている全てのセルを持つ Range オブジェクトを取得します

### 一番左列をキーにして、シートを連想配列にする

```js
  var values = sheet.getDataRange().getValues();
  var data = {};
  for (var i = 0, l = values.length; i < l; i++) {
    var key = values[i].shift();
    if (key.length > 0) {
      data[key] = values[i];
    }
  }
```

例：シートが下記の状態の場合（一行目と1列目は、データではなく見出し）

||A|B|C|D|
|---|---|---|---|---|
|1|甲|21|160|55|
|2|乙|31|170|65|
|3|丙|41|180|75|

data には下記の連想配列が入ります

```js
{
  "甲": [21, 160, 55],
  "乙": [31, 170, 65],
  "丙": [41, 180, 75]
}
```



# データ更新系
## シートを空白にする

```js
  sheet.clearContents();
```

たとえば他の function の組み合わせだと、下記のようにも書けます

```js
  sheet.getDataRange().setValue("");
```

* _sheet_.getDataRange は、値が入っている全てのセルを持つ Range オブジェクトを取得します
* _range_.setValue は、Range オブジェクトが指す全てのセルのデータに書き込みます

## 末尾に行を追加

```js
sheet.appendRow([1, 2, 3, 4]); // 行のデータを配列で表現して渡す
```
Windows Server 2012 R2にHyper-Vをインストール

# 概要
Windows Server 2012 R2にHyper-Vを導入する手順を記載する。
自分の備忘録です。

# Hyper-V の導入
1. 自動起動する「サーバーマネージャー」画面
「ローカルサーバー」を選択し、「管理」→「役割と機能の追加」を選択する。以降、「役割と機能の追加ウィザード」画面で作業する。
   

1. 開始する前に
以下の画面で、「規定でこのページを表示しない」チェックボックスにチェックを入れ「次へ」ボタンをクリックする。
![Hyperv01.png](https://qiita-image-store.s3.amazonaws.com/0/106250/21b0e409-482d-0990-4ecc-836e6e654e1b.png)
　
1. インストールの種類の選択
以下の画面で、「役割ベースまたは機能ベースのインストール」ラジオボタンを選択し、「次へ」ボタンをクリックする。
![Hyperv02.png](https://qiita-image-store.s3.amazonaws.com/0/106250/0a03ede3-7863-0648-1f8e-8df6aaa02e23.png)
　
1. サーバーの役割の選択
以下の画面で、「Hyper-V」チェックボックスを選択する。
![Hyperv03.png](https://qiita-image-store.s3.amazonaws.com/0/106250/8465af26-1cdb-9995-42c7-b52a3dd9a48e.png)　
　
1. 機能の追加ダイアログ
以下の画面で、Hyper-Vに関連する機能のインストールを求められるので、「機能の追加」ボタンをクリックする。
![Hyperv05.png](https://qiita-image-store.s3.amazonaws.com/0/106250/57f18ee3-be39-c360-a395-f7921c51cfcc.png)
　　
1. サーバーの役割の選択
以下の画面に戻るので、「次へ」ボタンをクリックする。
![Hyperv06.png](https://qiita-image-store.s3.amazonaws.com/0/106250/1cc7974e-5267-78e4-26a8-da4839cb52a3.png)
　
1. 機能の選択
以下の画面で、デフォルト設定のまま、「次へ」ボタンをクリックする。
![Hyperv07.png](https://qiita-image-store.s3.amazonaws.com/0/106250/16cf6dc1-6cc1-cf41-b99b-a5dc20c6bf0d.png)
　
1. Hyper-V
以下の画面で、「次へ」ボタンをクリックする。
![Hyperv08.png](https://qiita-image-store.s3.amazonaws.com/0/106250/0083c138-3588-752e-8b36-f0657ef10127.png)
　
1. 仮想スイッチの作成
以下の画面で、仮想スイッチを作成するネットワークアダプターを選択し、「次へ」ボタンをクリックする。
![Hyperv09.png](https://qiita-image-store.s3.amazonaws.com/0/106250/36c9049e-4bf2-7f25-197e-f21f067a8c10.png)
　
1. 仮想マシンの移行
以下の画面で、特に移行する必要なないのでデフォルトのまま、「次へ」ボタンをクリックする。
![Hyperv10.png](https://qiita-image-store.s3.amazonaws.com/0/106250/c2d5d13f-cbba-170d-fa5b-fab1dcc3a6df.png)
　
1. 既定の保存場所
以下の画面で、Hyper-V関連のファイルを保存するパスを指定し、「次へ」ボタンをクリックする。
![Hyperv11.png](https://qiita-image-store.s3.amazonaws.com/0/106250/4c4934eb-c170-ce0c-6789-5581cd5e5450.png)
　
1. インストールオプションの確認
以下の画面で、「インストール」ボタンをクリックする。
![Hyperv12.png](https://qiita-image-store.s3.amazonaws.com/0/106250/d325e17d-3234-4862-2669-583c5a12a36e.png)
　
1. インストールの実施
以下の画面で、インストールが進む。
![Hyperv13.png](https://qiita-image-store.s3.amazonaws.com/0/106250/e4744672-83c2-fe6c-624e-fb667557c62e.png)
　
1. インストールの完了
指示に従い、何度か再起動を実施するとHyper-Vの導入が完了する。　


以上
slackのremind機能で隔週通知

[slack の /remind 機能まとめ](http://qiita.com/takesato/items/335061d7945ebd5c23f7)や[公式のhelp](https://get.slack.help/hc/en-us/articles/208423427-Setting-reminders)の説明には無いですがちゃっかり隔週もできます
# 隔週指定
`every other 曜日` 
例 : 隔週土曜日12:55
 `/remind #random "隔週土曜日" at 12:55pm every other Saturday`


slackのremind指定は意外に融通利きますね。
ちなみに毎月第2水曜日（every month 2nd Wednesday）試したけどevery Wednesdayになっちゃいました（残念。。
Heroku初心者がHello, Herokuをしてみる

![heroku-logo-001 のコピー 2.png](https://qiita-image-store.s3.amazonaws.com/0/50208/1a6e73bf-0c92-4a6d-8d67-7d2aec11be65.png)


#はじめに
Heroku初心者がHerokuで「Hello, Heroku」を表示させたいと思います。

まあ、あまり知見のない僕でもできるらしいのでメモしておこう。

基本的な使い方を書いていくので、今から入門する方はぜひ見てほしいですね(\*'ω'\*)

# Herokuとは
Herokuとは、Webアプリケーションの開発から公開までを簡単にできるプラットフォームです。
プログラムが動作可能な環境を提供してあげますよ！ということですね。
ありがたや。

# Heroku登録
まずはHerokuに登録しなければなりませんね。

こちらへどうぞ → [Heroku登録画面](https://signup.heroku.com/)

![スクリーンショット 2016-04-16 19.53.54.png](https://qiita-image-store.s3.amazonaws.com/0/50208/73c4986b-44bf-1d97-dc83-2b6d34c8a987.png)

上から順にささっと入力していきます。

【Company name】は入れなくてもいけるみたいですね。
【Select a Language】は【PHP】にします。ぼくはPHPerなので。

そして、【Create Free Account】をクリック。

メールが飛んで来るので、メール内のリンクをクリックして、パスワード設定画面へ。

![スクリーンショット 2016-04-16 20.02.56.png](https://qiita-image-store.s3.amazonaws.com/0/50208/69f72d1c-6719-04f6-b905-71477e8e7493.png)

パスワードを入力して、【Set password and log in】をクリック。
この画面が表示されればOKです！

![スクリーンショット 2016-04-16 20.03.48.png](https://qiita-image-store.s3.amazonaws.com/0/50208/32881fa2-7429-4efa-8f31-7ad99bedf450.png)


# heroku toolbeltインストール
次にこちらをインストール。
[toolbeltインストール画面](https://toolbelt.heroku.com/)

このツールでHerokuをコマンドラインで操作できます。
各環境に合わせたものを選択してインストールしましょう。

![スクリーンショット 2016-04-16 20.39.18.png](https://qiita-image-store.s3.amazonaws.com/0/50208/467b890c-a4b2-6eeb-2a30-5e1c5c63b5fb.png)

# アカウント認証
toolbeltをインストールしたら、ターミナルでコマンドを入力しましょう。
先ほど登録したメールアドレスとパスワードを入力すれば下記のようになるかと思います。

```sh:
$ heroku login
Enter your Heroku credentials.
Email: adam@example.com
Password (typing will be hidden):
Authentication successful.
```

![スクリーンショット 2016-04-16 21.03.28.png](https://qiita-image-store.s3.amazonaws.com/0/50208/f5bbae60-68ef-b30e-8606-22101713d9b2.png)


# アプリ作成
作成するアプリを置くディレクトリを作成します。

```sh:
$ mkdir helloHeroku
$ cd helloHeroku
```
次に、【Hello, Heroku!!!】を出力してくれるファイルを作成し、内容を記述していきます。
また、PHPアプリケーションとして利用する場合は、`composer.json`が必要になるみたいです。
`composer.json`が含まれていないと、デプロイするときに`Warning`を吐き出します。
とりあえず今回は、composer.jsonは空でいきますね。

```sh:
$ touch index.php
$ touch composer.json
```

```php:index.php
<?php

echo "Hello, Heroku!!!";
```

# Gitリポジトリ初期化
Herokuでは、アプリケーションごとにGitを使ってリモートリポジトリへプッシュする必要があるので、リポジトリを作成し、追加、コミットします。
`$ git commit -m " "`のメッセージは何でも大丈夫です。

```sh:
$ git init
$ git add .
$ git commit -m "hello heroku commit"
```

# Herokuにアプリ作成
Herokuに新しいアプリケーションを作成します。
このとき、名前指定をしなければ自動的に名前がつけられます。名前はあとからでも変更可能なので、ここは指定無しでいきます。

```sh:
$ heroku create
Creating app... done, stack is cedar-14
https://xxxxxxxxxx.herokuapp.com/ | https://git.heroku.com/xxxxxxxxxx.git
```

# アプリをデプロイ
先ほど作成したアプリをデプロイします。

```sh:
$ git push heroku master
Counting objects: 4, done.

〜 略 〜

remote: Verifying deploy... done.
To https://git.heroku.com/xxxxxxxxxxxxxxx.git
 * [new branch]      master -> master
```

こんな感じになればOKです！

# アプリをブラウザで確認
このコマンドを叩くと、自動的にブラウザでアプリを表示してくれます。

```sh:
$ heroku open
```

問題なければ、【Hello, Heroku!!!】が表示されてると思います。

# 終わりに
とてつもく簡単でしたね。。。
すごっ！！！と思いました。

こんな簡単ならば、開発に没頭することができそうですね。

目標はクリアできたので、またなにかできればいいなーと思います！
Windows Update の設定

# 概要
Windows Server 2012 R2にWindows Updateを設定する手順を記載する。

# Windows Update の設定
1. 自動起動する「サーバーマネージャー」画面
「ローカルサーバー」を選択し、「プロパティ」の「Windows Update」をクリックする。以降、「Windows Update」画面で作業する。
   

1. Windows Updateの自動更新の有効化
以下の画面で、「自動更新を有効にする」ボタンをクリックする。
![Windowsupdate01.png](https://qiita-image-store.s3.amazonaws.com/0/106250/7f4fb7f2-02e8-4462-ccd0-16bc98b0ec0a.png)
　
1. Windows Upateの実施
以下の画面の流れで、Windows Updateを実施する。「役割ベースまたは機能ベースのインストール」ラジオボタンを選択し、「次へ」ボタンをクリックする。
![Windowsupdate02.png](https://qiita-image-store.s3.amazonaws.com/0/106250/80ea78b0-3980-cadd-8f86-e4177af4eb5b.png)
　
![Windowsupdate03.png](https://qiita-image-store.s3.amazonaws.com/0/106250/5966816d-d976-ab00-9d9a-25db252463f7.png)
　
以下の画面で、「今すぐ再起動する」ボタンをクリックする。
![Windowsupdate04.png](https://qiita-image-store.s3.amazonaws.com/0/106250/87dc0e53-bd3e-2723-8b8d-7a63f357bc90.png)
　
1. 備考
上記の作業を何度か繰り返して、OSを最新の状態にする。

以上
Xamarin.Android のビルドで java.lang.OutOfMemoryError が発生したとき

Adam J Wolf さんの [Xamarin.Forms in Anger](https://www.syntaxismyui.com/xamarin-forms-in-anger/) がサンプルとして秀逸だったので手元で動かしてみようとビルドしたところ、Android のプロジェクトで **java.lang.OutOfMemoryError** が発生。

<img width="362" alt="20160416-xamarin-error.png" src="https://qiita-image-store.s3.amazonaws.com/0/4407/efa6f52c-365d-f776-bf70-fb62f3466354.png">

この例外は Java VM がメモリ不足に陥ることによって発生する。サンプルのサイズやリンクするライブラリのサイズによって引き起こされている可能性あり。
例外の発生を回避してビルドを成功させるには、.csproj に下記を追加する。

```xml
<PropertyGroup> 
    <JavaMaximumHeapSize>1G</JavaMaximumHeapSize> 
</PropertyGroup>
```

2016/05/27 追記

プロジェクトの設定に編集欄がありました。
![20160507-java-max-heap-size.png](https://qiita-image-store.s3.amazonaws.com/0/4407/087a26b0-e188-1c98-8288-04040ec57481.png)
GPU搭載のノートPCにUbuntu入れたときのメモ

少し前に、GTX960M搭載の[Alienware 13-R2](http://www.dell.com/jp/p/alienware-13-r2/pd)を購入した。当初は予定になかったのだが、このPCをWindows10/Ubuntu14.04でデュアルブートし、CUDAを入れ、ChainerやTensorflowをGPUで学習を回せる環境を作ることにした。  
 
## Ubuntuのインストール
基本的にこちらで紹介されている手順でインストールして、デュアルブートさせる

[（UEFI環境 編）Microsoft Windows10 と Ubuntu 14.04 LTS とのデュアルブート環境の構築](https://www.abten.net/2015/05/444/)

少し一般の手順と異なる点があったので、補足を加えながら説明する

### windowsのパーティションを縮小させて、未割り当て領域を確保
Windows上でパーティションを縮小させる。 やってみたところ、Window上未使用が370GBほどあるのに、縮小できたのは70GB程度だった。ファイルがバラついているのだろう。[ここらへん](http://www.pc-memo.info/windows8-1/996/) をやるともっと縮小できるかも。もしくはWindowを起動しているからページングファイル等が発生しているため縮小できないとすれば、Ubuntuの方で縮小をかけてしまえばもっと縮小できるかも。

### USBメモリでUbuntuの起動ディスクを作る
Alienware 13インチには、CD/DVDドライブなんて付いていないので、USBからインストールする。USB起動ディスクの作り方は、こちらを参照
[UbuntuをUSBメモリからインストール](http://chee-s.net/ubuntu%E3%82%92usb%E3%83%A1%E3%83%A2%E3%83%AA%E3%81%8B%E3%82%89%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)  

### USBからブートしてUbuntuインストール
Alienwareの場合、起動時にF12を押して、直接ブートオプションを選択できるので、そこでUSBを選択して、Ubuntuを起動させる。  

今まで経験したPCでは、F2やDeleteキーを押してBIOSに入り、ブートの優先度をUSBを最高にして起動していた。だがAlienwareの場合、いくらUSBを指して起動しBIOSに行けども、ブートの選択肢にUSBは現れない。
セキュアブートが影響しているのかと考えて、セキュアブートをDisableにしてもUSBは現れない。

余談だが、Alienwareでセキュアブートを外すと、起動時の画面が少し怖くなる。

|セキュアブートあり|セキュアブート無し| 
|---|---|
|![2016-04-15 15.35.41.jpg](https://qiita-image-store.s3.amazonaws.com/0/50474/d7c435d4-9521-345c-8312-512a89039973.jpeg)|![2016-04-15 15.37.15.jpg](https://qiita-image-store.s3.amazonaws.com/0/50474/be0b509c-487e-9682-56f9-8e1ed5c57b53.jpeg)|

いろいろ試した結果、先に述べた通り、F12でブートオプションを選択すればよい。
あとはインストール指示に従うだけでOK.

## インストール後の不具合とその対応
ノートPCならではの問題がいくつか発生した。

### 内臓無線LANアダプターが機能しない
無線LANのネットワークアダプタ自体は認識されているようだが、使えない状態となった。

```
$ lspci
02:00.0 Network controller: Qualcomm Atheros QCA6174 802.11ac Wireless Network Adapter (rev 20)
```
この情報を手掛かりに、様々な解決策を試みたが、解決はしなかった。
http://askubuntu.com/questions/607707/ath10k-installation

結局、800円ほどのUSB小型無線子機を購入して、Wifi接続をしている。
こんなの
[無線LAN子機](http://www.amazon.co.jp/BUFFALO-11n%E5%AF%BE%E5%BF%9C-%E7%84%A1%E7%B7%9ALAN%E5%AD%90%E6%A9%9F-%E8%A6%AA%E6%A9%9F-%E5%AD%90%E6%A9%9F%E3%83%87%E3%83%A5%E3%82%A2%E3%83%AB%E3%83%A2%E3%83%BC%E3%83%89%E5%AF%BE%E5%BF%9C%E3%83%A2%E3%83%87%E3%83%AB-WLI-UC-GNM2/dp/B005DU4XSM/ref=zg_bs_2151998051_1)

### トラックパッドが動かない
まだ調査中。

参考
http://askubuntu.com/questions/453876/how-to-install-synaptiks-on-touchpad-on-ubuntu-14-04
http://askubuntu.com/questions/271476/my-touchpad-is-not-responding-on-an-acer-aspire-e1-471-6650?rq=1
Ubuntu, NVIDIAディスプレイドライバで困ったときに使うコマンド

GPU搭載のノートPCにCUDAを入れようとして、ディスプレイドライバの問題でハマりまくって、何度もUbuntu再インストールしなおしてるので、メモとしてまとめた。


## デバイス等の確認
```bash
$ lspci |grep -i nvidia
```
## ドライバ等確認

```bash
$ dpkg -l |grep nvidia
```
## X serverのログを見るとき

```bash
$ tail /var/log/Xorg.0.log
```

## X server の停止、開始
```bash
# 停止
$ sudo stop lightdm
# 開始
$ sudo start lightdm
```
簡単な見方
http://www.garunimo.com/program/linux/corumn-linux3.xhtml

## 起動時、GUI→CUIへ切り替え
CTRL + ALT + F1

## CUI→GUIへ切り替え
ALT + F7

## 全体のログを見る
```bash
$ tail /var/log/syslog
```
Minecraft サーバ /w Arch Linux

## 前提

## 手順

インストール．

```bash
yaourt -S jdk
yaourt -S minecraft-server
```

Systemd の起動設定．

```bash
systemctl start minecraftd
systemctl enable minecraftd
```

EULA に同意．

```bash
nano /srv/minecraft/eula.txt
```

ファイアウォールの設定．

```bash
ufw allow 25565/tcp
ufw reload
```
TeamSpeak 3 サーバ w/ Arch Linux

## 前提

## 手順

インストール．

```bash
yaourt -S teamspeak3-server
systemctl start teamspeak3-server
systemctl enable teamspeak3-server
```

ポートを開けます．

```bash
ufw allow 9987/udp
ufw allow 30033/tcp
ufw allow 10011/tcp
ufw reload
```

初回起動時はトークンを入力する必要があるので，確認します．

```bash
systemctl status teamspeak3-server
```
NSNotificationCenterはもう古い。

## はじめに
僕はもともと`NSNotificationCenter`があまり好きではありません。
僕の中では`GOTO文`に近い位置付けで、使う時に違和感を覚えて使ってました。
トリガーがどこでイベントで発生したのか、どこのオブジェクトに通知するのかがさっぱりわからないカオス的な感じが自分にはありませんでした。

しかし、`delegate`を駆使してできるとことは`delegate`で行い、もっと単純の場合は`block`構文を使うような実装を心がけても`NSNotificationCenter`は絶対に発生します。
（例えばプッシュ通知など）

なので、仕方なく使っていたのですが最近`RxSwift`を使ってから一つの解が生まれました。
・・・という話です。

## NSNotificationCenterの代わり
前置きが長いですが、解法は楽です。
例えば、以下のようなクラスを作成すれば解決です。

```swift
import RxSwift
class NotificationCenter {
    static let observable = PublishSubject<String>()
}
```

通知したい方のプログラムは以下のような感じになります。
この例では`String`をインターフェースにしてますが、どのクラスでも受け渡せます。

```swift
NotificationCenter.observable.on(.Next("Notification"))
```

購買する側は以下のような形になります。

```swift
class TestViewController {
    private let disposeBag = DisposeBag()
    func sub() {
        _ = NotificationCenter.observable.subscribeNext { (str) in
            print(str)
        }.addDisposableTo(disposeBag)
    }
}
```

`NSNotificationCenter`は購買と購買解除のタイミングがわかりにくく、購買解除をし忘れることもありますが、このようにすれば購買解除をする必要がありません。
（`disposeBag`が解放されるタイミングで購買解除される。）

また、`NSNotificationCenter`ではスペルミスなどが起こるとデータが正しく送信されませんし、インターフェースも`AnyObject`になってしまうのでコードの保守性が弱くなります。
`RxSwift`ならその点も安心です。
しかも、`PublishSubject`でなく`ReplaySubject`を使うなどの局面に合わせた戦略をとるのがとても楽にできます。

というコード技法の紹介です。
`RxSwift`を使ってる人には普通の事ですが・・・
バグの追いかけ方

Web系やモバイル系でプログラムを書いていると、自分自身が作ったのでないバグや問題に遭遇することも、決して珍しいことではありません（Androidアプリの機種依存の問題を除いたとしても、年に数回はあります）。

今回は、ちょうど少し前に遭遇した[PDO-MySQLのバグ](http://qiita.com/jkr_2255/items/9949c9a60dca94673c7f)を例に、バグに遭遇した時はどうすればいいのか、流れを示していきます。

# その0：とりあえず、再起動など
コードを書き換えた直後にトラブルが出ても、キャッシュが残っているなどで一時的にデータが整合しなくなっているだけ、ということもよくあります。ひとまず、サーバ系なら再起動、ビルドが必要なら完全リビルド、ブラウザの場合はブラウザキャッシュのクリアをして、それでも再現するか確認しましょう。

# その1：エラーメッセージでググる
[前にも書きましたが](http://qiita.com/jkr_2255/items/cadac23918c773f0032d#%E3%82%A8%E3%83%A9%E3%83%BC%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%81%AF%E6%83%85%E5%A0%B1%E3%81%AE%E5%AE%9D%E5%BA%AB)、エラーが起きた時に出るメッセージやエラーコードは重要な情報です。まずは、エラーメッセージでぐぐってみると、手がかりになる情報が手に入ることもあります。

今回の場合、ググってみると、このエラーはUnbuffered Queryにした場合に起こることがわかったので、そのクエリモードについても調べていたのですが、まったく切り替えは意図したものではなく、この段階では意味不明なままでした。

# その2：再現条件を追いかける
CodeIgniterを3.0.3から3.0.6に上げて今回の現象が起きたのですが、どこのバージョンアップで不具合になったのかを特定するため、CodeIgniter 3.0.4にしてみたところ…同じ状況となったので、ここのバージョンアップでなにかがあったことがほぼ確定しました。

このように再現性が取れるバグであれば追いかけやすいのですが、そうでない場合、たとえば

* 日付・時間が特定の値になると動かない
* 他のメモリに入っている値によって状況が変化する
* 同時実行に関係したバグ

などは、再現条件を確定させるだけで一苦労します。もっとも、「どのようにすればバグが起きるか」を確定できれば、バグ調査の山場は超えたと言ってもいいです。

# その3：差分を見る
自分でコードを書き換えてバグが出た場合、書き換えた部分で何かが起きています。今回はCodeIgniterの更新で起きたということなので、3.0.3と3.0.4の間で更新されたところに、原因があるということになります。

ソースコードの差分を取ったり、ChangeLogを見ていたところ、MySQLまわりで、「MySQL 5.7でSTRICTのデフォルトが変化するために、それを吸収する」コードが追加されていました。これが影響するとはにわかには考えられなかったのですが、実際に変わっているのがここぐらいだったので、ぐぐってみたところ、[PHP側のIssue](https://bugs.php.net/bug.php?id=71145)にたどり着きました。

# その4：対策を考える
バグの原因がわかれば、対策を行うことができます。それにも、いくつかの手段があります。

まず、フレームワークなどの場合、ソースを見れば問題点が明らかになっていることもあるので、「直して自分からPRを投げる」という選択肢があります。一方で、今回のPHPのように、容易にソースを追えない部分、さらにはブラウザごとに起きるバグのように実行環境の側に手を入れることができない場合は、「バグを回避するようにコードを書き換える」ということになります。状況によっては、「バグを起こす機能そのものを削る」ことで回避する、なんていう苦渋の決断が必要となることもあります。
Arch Linux でサーバ構築

## 前提

- お名前 VPS (メモリ 2G プラン)

## OS のインストール

http://qiita.com/macchaberrycream/items/1dfabe8b710dc638e3f9

## SSH サーバのインストール

```bash
pacman -S openssh
```

設定ファイルを開いてポート番号を 10022 などに変えておきましょう．

```bash
nano /etc/ssh/sshd_config
```

`systemctl` から起動設定．

```bash
systemctl enable sshd
systemctl start sshd
```

## ファイアウォールの設定

`iptables` を使うのは面倒なので，`ufw` をインストール．

```bash
pacman -S ufw
```

ファイアウォールを設定していきます．

```bash
ufw default deny
ufw limit 10022/tcp
ufw enable
```

Systemd から起動設定．

```bash
systemctl enable ufw
```
knockout.jsでズンドコキヨシ（ドコモ光対応版）

ここ一ヶ月ほどの間にたくさんのズンドコシステムが世に出てきましたが、お客様からの「ドコモ光に対応してほしい」というご要望に対応できるズンドコが見つからなかったので自分で作ってみました。

https://jsfiddle.net/tag1216/e7m9ugwk/

<img width="548" alt="knockout_jsでズンドコキヨシ_-_JSFiddle.png" src="https://qiita-image-store.s3.amazonaws.com/0/35192/e33e21c7-bbc3-bd87-f25b-75390903f713.png">

テキストフィールドの文言を変更すると、実行中でもキヨシ発動後でも変更が即反映されます。

```html:html
<div>
  <input type="text" data-bind="textInput: zun"/>
  <input type="text" data-bind="textInput: doko"/>
  <input type="text" data-bind="textInput: kiyoshi"/>
</div>
<div>
  interval(ms):<input type="text" data-bind="value: interval"/>
</div>
<div>
  <button data-bind="click: start">start</button>
</div>

<div data-bind="foreach: results">
  <span data-bind="text: $data"></span>
</div>

<div class="completed">
  <span data-bind="text: kiyoshi, visible: isCompleted"></span>
</div>
```

```js:JavaScript
var ZundokoViewModel = function() {
  this.zun = ko.observable("ズン");
  this.doko = ko.observable("ドコ");
  this.kiyoshi = ko.observable("キヨシ!");
  this.pattern = [this.zun, this.zun, this.zun, this.zun, this.doko];
  this.interval = ko.observable(500);
  this.results = ko.observableArray();

  this.start = function() {
    this.results.removeAll();
    this.next();
  };
  this.next = function() {
    this.results.push(Math.random() < 0.5 ? this.zun : this.doko);
    if (!this.isCompleted()) {
      setTimeout(this.next.bind(this), this.interval());
    }
  };
  this.isCompleted = ko.computed(function() {
    var len = this.results().length;
    if (len < this.pattern.length) return false;
    var tails = this.results().slice(len - this.pattern.length);
    for (i = 0; i < this.pattern.length; i++) {
      if (tails[i] != this.pattern[i]) return false;
    }
    return true;
  }, this);
};

var viewModel = new ZundokoViewModel();

ko.applyBindings(viewModel);
```

- knockout.jsのデータバインディングを使用しています。
- テキストフィールドのデータバインディングには'textInput'を使用することで入力を即反映するようにしています。（`value`だとEnterを押した時、フォーカスが外れた時にしか反映されません）  

    ```html:
    <input type="text" data-bind="textInput: zun"/>
    ```
- ランダムに選択したズンドコは`observableArray`(`results`プロパティ)に格納しています。
  この際、バインドされた値(`this.zun()`)ではなくobservableオブジェクト(`this.zun`)を直接格納することで、値の変更が即反映されるようになります。  

    ```js:
    this.results.push(Math.random() < 0.5 ? this.zun : this.doko);
    ```
BootcampにしたWindows8.1からWindows10にアップグレードしたとき外部モニタ（デュアルモニタ）が認識されなかったがなんとか認識された

## はじめに
数か月前Windows8.1からWindows10へアップデートしたとき、無残にも失敗。
MacBook自体のモニタおよび外部ディスプレイさえまともに表示されることがなくなり、何とか心眼によって（マウス操作なしでキーボードのみの作業で）セーフティーモードで立ち上げなおしてWindows8.1に戻した経験がある。

## 今一度再挑戦しなんとかデュアルモニタに成功した
### やっとこと
- マウスおよび外部ディスプレイなどの有線をすべてはずす。
- ブートキャンプではOS Xが優先的に立ち上がっるようになっているので、Windows10のアップデート中に何回も再起動されることを考慮して、Windows側が優先的に立ち上がるように変更。
- Windows10に無料でアップデートできます的なメッセージをクリックして、アップデート（これだけで数時間待つ）。

やはりアップデートが終わった段階で外部モニタを認識してくれない。

- Windows10でApple Software Updateを実行してApple関係を最新にする。2回行った。

やはり外部モニタを認識してくれない...

https://www.reddit.com/r/mac/comments/3f4znw/just_upgraded_to_windows_10_on_my_late_2013/
にある通り 

> Boot back into OSX and insert a USB thumb drive. Run Bootcamp Assistant. Continue past the Introduction screen. Under Select Tasks, uncheck the top and bottom options and make sure only "Download the latest Windows support software from Apple" is checked.
This will download and save the latest windows drivers for your Mac. After this is complete, boot back into Windows and insert the USB thumb drive and run the setup.exe file that is in the Bootcamp folder. This will reinstall all the latest Windows drivers from Apple.

を行ったがやはりだめ。（これでさらに数時間要する）

- 最近使っていなかったj5 create USB 3.0 HDMI DISPLAY ADAPTER JUA350 を差し込むと何かインストーラが起動して最新にアップデートしますか？（正確には忘れてしまった）みたいなのがでたのでこれはチャンスと思ってアップデート
http://www.j5create.com/our-products/external-video-adapters/jua350.html


ついに外部ディスプレイを認識してくれた！！

デスクトップで右クリックすると　グラフィックス・プロパティーとグラフィックス・オプションという項目が増えており、グラフィックス・プロパティーを選ぶとインテル　グラフィックス・コントロール・パネルが立ち上がった。おそらくインテルのグラフィックス関係がインストールされていなかったもしくはバージョンが上がっていなかったため外部ディスプレイが認識できなかったのではと考える。
ファイルを移動しつつカレントディレクトリもそこへ移動するシェル関数


ファイルをどこかに移動させた後、カレントディレクトリもそこに変更したい場合がよくあるので、シェル関数を作ってみました。bashとzshで動作します。あまりちゃんと検証してないのですが、普段使いで問題は発生していません。

```bash:.bashrcとか.zshrcとか
take() {
  eval local TO=\$$#
  mv $@ && cd "$TO"
}
```

なお本処理をシェルスクリプトに書いて実行しても、`cd`が別シェルで実行されてしまうので上手く動きません。必ずシェル関数にする必要があります。
WinSCPでファイルを取得する処理を自動化したい

WinSCPのGUIをつかって手動でファイルをダウンロードするのが、手間だと感じる時があれば、それは、WinSCPコマンドラインの出番です。


![WinSCP-Logo.png](https://qiita-image-store.s3.amazonaws.com/0/117147/e2cba1b0-e09f-5f2f-a1fc-5c79be29c81d.png)


**WinSCPにはWinSCP.comというコマンドラインのオプションがあります。**
コマンドラインを使えれば、batファイルを作成して、タスクスケジューラーで定期実行させることもできますし、イベントトリガーで実行させることもできます。


以下、サンプルコードです。
いろいろなやり方がありますが、一例として、
接続先サーバからファイルをgetする処理を記載しています。


```bat:bat
@REM
@echo off

cls
echo START
echo.
echo cd /zzz/xxx > SCPcom.scp
echo lcd "C:\xxx/zzz" >> SCPcom.scp
echo bin >> SCPcom.scp
echo get vvv >> SCPcom.scp
echo close >> SCPcom.scp
echo exit >> SCPcom.scp

"C:\Program Files\WinSCP\WinSCP.com" /ini="C:\Program Files\WinSCP\WinSCP.ini" [WinSCPName] /console /script=.\SCPcom.scp

echo.
echo ScriptEnd
echo.
exit

```

###処理の流れ

①ファイル（ここでは"SCPcom.scp"としています）に、実行したいコマンドを書き込みます。
②WinSCP.comを使用して、①で作ったファイルを読み込んで実行する。

流れは上記のように単純です。
変更箇所と注意点を見ていきましょう。

###変更箇所
- cd,lcd　の箇所は、リモート先、ローカルのディレクトリを指定しましょう。
- bin　はバイナリモードの指定です。必要に応じて変更しましょう。
- get　でファイルをゲットしてきます。対象ファイル名を書きましょう。
- close,exit　で接続を終了します。
- "C:\Program Files　ではじまる次の行で、いよいよWinSCP実行です。WinSCP.comのファイル、iniファイルのパスを指定します。
- [WinSCPName]　には、WinSCPのGUIで設定した、接続先の設定名を記載しましょう。
- script=　は、コマンドをリダイレクトで書き込んだファイルを指定します。


###注意点
- 基本的にはbatファイルとして実行しますので、書き方はそれに準じる形でOKです。
- コマンド用のファイルに書き込むので、リダイレクト（ > もしくは >> ）を使ってファイルへ書き込んでいきます。
 
他にも様々なコマンドラインがあります。
[詳細はこのページ](https://osdn.jp/projects/winscp/wiki/script_commands)などを参照してください。



###さいごに
WinSCPやFTPはファイル操作をするときに、非常に多く利用すると思いますが、
ある程度、固定的な内容であれば、自動化したほうが良いでしょう。

スクリプトを組む時間はかかりますが、その後は、ボタンひとつで、もしくは自動実行で作業できてしまうことでしょう！
ディスクの空き容量を LVM にくっつける

VM やクラウドをいじっているとき、インスタンスに割り当てるディスクを増やしたものの起動したイメージでドライブサイズが決まってしまい後ろが未使用のまま空いているという場面に良く出会います。
このような時の解決方法は環境によってさまざまなのですが、最近私がよくやっている手順が

 1. fdisk で新しいパーティションを作り後ろの空きをすべて割り当てる
 2. 作成した新しいパーティションを LVM にする
 3. 既存の LVM に新しいパーティションをくっつける

というものです。

あまりにもよくやる手順なのでシェルスクリプトにまとめてみました。

```shellscript:
#!/bin/bash

DEVICE=/dev/sda
ADDDEVICE=debian-vg
ADDDRIVE=/dev/debian-vg/root

SMAX=`fdisk -l ${DEVICE} | awk '$0 ~ /sectors$/ {print $7-1}'`
SMIN=`fdisk -l ${DEVICE} | awk '$0 ~ /^\/dev/ {if(m<$3) m=$3} END{print m+1}'`

echo 'free area '${SMIN}' - '${SMAX}
parted -s -a optimal ${DEVICE} -- mkpart P${PART} ${SMIN}s ${SMAX}s
PART=`parted -s ${DEVICE} print | awk '$1 ~ /^([0-9]+)/ {if(m<$3) m=$3;n=$1} END{print n}'`
parted -s ${DEVICE} set ${PART} lvm on

echo 'create device '${DEVICE}${PART}
pvcreate ${DEVICE}${PART}
vgextend ${ADDDEVICE} ${DEVICE}${PART}
lvextend -l +100%FREE ${ADDDRIVE}
resize2fs ${ADDDRIVE}
```

ADDDEVICE が追加先の LVM VG 名、ADDDRIVE が追加先のドライブデバイス名になります。
これらはあらかじめ編集して指定しておきます。
AWS API Gateway x Lambda で jsonp を返却する

## 普通に作ると jsonp にはできない

AWS API Gateway x Lambda x Python の API を作り、デフォルト設定のまま retuen で dict を返却すると自動的に json にパースされレスポンスが返る。
文字列を返すとクオートで囲まれてしまうので、 Lambda から直接 js を返却することができなかった。

例） `callback({"hoge":"foo"})` を return すると `"callback({\"hoge\":\"foo\"})"` のように文字列としてレスポンスされてしまう。

## やったこと

API Gateway レスポンスを加工する機能があったのでそれを利用した。
まずは `Amazon API Gateway > APIs > hogeAPI > Resources > /foo` から Method Execution を開く。

### Method Response の設定

1. Method Execution から Method Response を選択
2. HTTP Status `200` を選択
3. Response Models に `application/javascript` を追加  
![Method Response.PNG](https://qiita-image-store.s3.amazonaws.com/0/68136/4ed89f31-0662-b7df-bc29-2b64907dcd2a.png)

### Integration Response の設定

1. Method Execution から Integration Response を選択
2. Method response status `200` を選択
3. Body Mapping Templates を開く
4. Content-Type `application/json` を開く
5. 下記を入力する 
 
```js:BodyMappingTemplates
## format to jsonp
callback($input.json('$'))
```
![Integration Response.PNG](https://qiita-image-store.s3.amazonaws.com/0/68136/970251d3-7df8-3861-a994-1c8f35ac82cd.png)

## まとめ

これで `application/javascript` で jsonp を返却することができるようになる。
データフローとしては以下のようになっている。

1. Lambda から json を返却
2. Integration Response で body を整形
3. Method Response header を整形

BodyMappingTemplates をゴリゴリと作りこめば動的な callbak にも対応できそう。

### 参考

[Amazon API Gateway – JSON形式のレスポンスをHTML形式に加工して返してみる](http://dev.classmethod.jp/cloud/aws/api-gateway-2/)

## 補足

API Gateway はデフォルト CORS が無効になっているので別途設定が必要です。
アプリっぽい固定レイアウトをhtml+PureCSSで

#アプリっぽい固定レイアウトをPureCSSで

Webアプリを作る時欲しくなる、全体がウインドウサイズ内部に収まり、画面を複数のペインに分割し、その中でスクロールするようなレイアウトを、PureCSSで作るシンプルな方法です。javascriptは使いません。

ターゲットは、Chrome,Firefox,Safari,IE11,Edgeです。

このような画面を作ります。実働サンプルは [こちら](http://wakufactory.jp/html5/layout/flex3.html) 。

![flex3.png](https://qiita-image-store.s3.amazonaws.com/0/74838/50f00f75-6323-a079-9d2b-b92b6d349fe5.png)

まず、htmlは、素直にブロックを並べてこのように作ります。

baseが全体のベースでその中にhead,cont,footが縦に並び、contの中がleft,mid,rightと三つに分割されています。leftの中はさらに上下に2分割しています。

```html
<body>
<div class=base>
<section class=head>
<div class=mdiv>
<h1>header</h1>
</div>
</section>
<section class=cont>
<section class=left>
<article class="left_up rollbase">
list1
<div class="roll">
<div>
scrolling content <br/>
中略
scrolling content <br/>
</div>
</div>
</article>
<article class="left_down rollbase">
list2
<div class="roll">
<div>
scrolling content <br/>
中略
scrolling content <br/>
</div>
</div>
</article>
</section>
<section class="mid">
<div>
mid content (auto size)<br/>
scrolling
</div>
<div class=rollbase>
<div class=roll>
<div>
scrolling content <br/>
中略
scrolling content <br/>
</div>
</div>
</div>
</section>
<section class=right>
right content<br/>
(fix width)
</section>
</section>
<section class=foot>
<div class=mdiv>
footer
</div>
</section>
</div>
</body>
```

スタイルは以下のようになります。


```css
html,body {
	width:100% ;
	height:100% ;
	margin:0 ;
	overflow:hidden ;
}
div,section,article {
	box-sizing: border-box ;
}

div.base {
	width:100%;
	height:100% ;
	display:flex ;
	flex-direction:column ;
}
section.head {
	background-color: #eee ;
}
section.foot {
	background-color: #eee ;
}
section.cont {
	height:1rem ;
	flex-grow:1 ;
	display:flex ;
}
section.left {
	width:20% ;
	background-color:#fee ;
	display:flex ;
	flex-direction:column ;	
}
section.mid {
	display:flex ;
	flex-direction:column ;
	flex-grow:1 ;
	padding:0.5rem ;
	background-color:#fef ;
}
section.right {
	width:10em ;
	padding:0.5rem ;
	border:5px solid black ;
	background-color:#eef ;
}

article.left_up {
	height:10rem  ;
}
article.left_down {
	flex-grow:1 ;
}
article.left_up .roll {
	margin-top:1rem ;
}
article.left_down .roll {
	margin-top:1rem ;
}
section.mid .rollbase {
	flex-grow:1 ;
}
.rollbase {
	position:relative ;	
}
.roll {
	overflow:scroll ;
	-webkit-overflow-scrolling : touch  ;
	position:absolute ;
	top:10px ;
	left:5px ;
	right:5px ;
	bottom:5px ;
}
.roll div {
	background-color:#efe ;
}

div.mdiv {
	padding:0.5rem ;
	border:1px dotted black;
}
```

ポイントは、上下/左右の分割は、flexで行い、サイズを固定するブロックにはwidthかheightを指定、それ以外はflex-growを指定して自動的に伸縮するようにします。

また、スクロールするブロックが入る場合は、内部に合わせてflexのブロックが拡大してしまわないように、外側のブロックのサイズに合わせたブロックで囲みます。これがrollbaseとrollの部分です。

ブロックをさらに分割する場合は、親にdisplay:flexとfrex-directionを設定し、その中にブロックを配置していけば、どんどん入れ子にすることができます。
slim完全攻略

#slimについてまとめてみる
プロジェクトでerbを全てslimにする作業を通して、「slim最高！」と思った一方でslimについては体系的にまとめられていなかったため、今後挑戦する人のために書いておく。
ちなみに、公式ドキュメントは[こちら](https://github.com/slim-template/slim)

## 1. slimの特徴
slimはhtmlの煩わしい部分を全部省略して文字通りコードを"slim"にすることを可能にしてくれる・特徴は以下の通り
1. <>タグは省略
2. 閉じタグは省略
3. 入れ子構造はインデントで表現
htmlの表現に慣れている人から見ると何が何だか分からないが、逆にslimになれると正規のhtml表現がとても読みにくくなる。タグが邪魔w
## 2. slim変換の例
```lang:hoge.html.erb
 <% hoge %>                    #1
 <%= hoge %>                   #2
 <h1> hoge </h1>               #3
 <h1 class="hoge"> fuga </h1>  #4
 <div id="hoge"></div>         #5
 <div class="hoge"></div>      #6
 <%= render 'hoge' %>          #7
 <%= yield %>                  #8
```
これをslimに変換すると

```lang:hoge.html.slim
 - hoge                 #1
 = hoge                 #2
 h1 hoge                #3
 h1.hoge fuga           #4
 div#hoge               #5
 #hoge                  #5
 div.hoge               #6
 .hoge                  #6
 == render 'hoge'       #7
 == yield               #8
```
## 3. 実例を交えて解説する

```lang:hoge.html.erb
 <div class="container">
   <div class="header-left">
     <img class="logo" src="example.png">
   </div>
   <div class="header-right">
     <a href="#" class="login">ログイン</a>
   </div>
 </div>
 <div class="top-wrapper">
   <div class="container">
     <h1 class="<%= 'feature' if user.silm.present? %>">Slim完全攻略</h1>
     <p>slimはとても簡単<br>ぜひ挑戦してみましょう！</p>
     <% unless user_signed_in? %>
       <%= link_to "新規登録", "http://hoge.com", class: "btn signup" %>
       <p>ログイン</p>
       <a href="#" class="btn facebook"><span class="fa fa-facebook"></span>Facebook</a>
     <% else %>
       <%= link_to user_path do %>
         <%= current_user.name %>さんのマイページ 
       <% end %>
     <% end %>
   </div>
 </div>
 <div class="main-content">
   <%= render "main_content" %>
 </div>
```
これをslimに変換すると

```lang:hoge.html.slim
 div.container
   div.header-left
     img.logo src="example.png"
   div.header-right
     a href="#" class="login"
       |
         ログイン
 div.top-wrapper
   div.container
     h1 class="#{'feature' if usr.slim.present?}" Slim完全攻略
     p 
       'slimはとても簡単
       br
       'ぜひ挑戦してみましょう！
     - unless user_signed_in?
       = link_to "新規登録", "http://hoge.com", class: "btn signup"
       p ログイン
       a href="#" class="btn facebook"
         span.fa.fa-facebook
           'Facebook
     - else
       = link_to user_path do
         = current_user.name
         'さんのマイページ 
 div.main-content
   == render "main_content"
```

注意するべき点としては、
1. `div.container`としても`.container`としてもどちらもブロック要素を作るから変わりはない。しかし、それを明確に示すためにも`div`はつけておいたほうがわかりやすいと思う。
2. インライン要素は、`'`か`|`+インデントで表現する
3. 閉じタグは当然だが、`<% end %>`も省略する
4. `""内で<% %>を使いたい時は#{}を用いる`
## 4. 最後に
slimにしてからコードを書く時間がとてもはやくなりました。さらに良かったのは、インデントにものすごい意識するようになったこと。メリットだらけです、是非使ってみては！
comporser + pear

```
{
    "name": "doishun/framework",
    "description": "Solution Unit Framework",
    "type": "project",
    "homepage": "http://hoge.com",
    "license": [
       "GPL-2.0",
       "Commercial"
    ],
    "repositories": [
        {
            "type": "pear",
            "url": "http://pear.php.net/"
        }
    ],
    "require": {
          "php": ">=5.3.3"
        , "smarty/smarty": "2.6.25"
        , "pear-pear.php.net/PEAR" : "1.9.4"
        , "pear-pear.php.net/Pager" : "2.4.9"
	}
}
```