OmniAICreator/Qiita-1.07M huggingface dataset:
Nginxをソースコードからインストール

## ユーザーとグループを作成する

```
$ sudo groupadd -g 500 nginx
$ sudo useradd -g nginx -u 500 -s /sbin/nologin -d /var/www nginx
```
※USER及びGROUPのIDは環境に併せて下さい


## ソースコードを取得し、展開する

Nginxデベロッパーサイトから使用したいバージョンのソースコードを取得し、展開します。

```
$ wget http://nginx.org/download/nginx-1.7.11.tar.gz
$ tar zxvf nginx-1.7.11.tar.gz
$ cd nginx-1.7.11
```

## ソースコードをビルドする

実際にコンパイルし、インストールを実行します。

```
$ ./configure --prefix=/usr/local/stow/nginx-1.7.11 --user=nginx --group=nginx --with-http_ssl_module
$ make
$ sudo make install
```

## 起動ファイルを用意

デベロッパーサイトの下記ページより、インストール先サーバーのOSに合わせて起動ファイルをダウンロードして設置します。
[http://wiki.nginx.org/InitScripts](http://wiki.nginx.org/InitScripts)


また、必要箇所をインストール環境に合わせて修正を行います。

```
vim /etc/init.d/nginx
--------------------------
< nginx="/usr/sbin/nginx"
> nginx="/usr/local/sbin/nginx"
---
< NGINX_CONF_FILE="/etc/nginx/nginx.conf"
> NGINX_CONF_FILE="/usr/local/config/nginx.conf"
--------------------------
```

## サービスの起動

実際にWEBサーバを起動して挙動を確認しましょう。

```
$ /etc/init.d/nginx start
```

## 各種プログラムを動かす方法

- [PHPを使う方法](http://qiita.com/HayneRyo/items/7eb4578138677067cd6d)
- [Railsを使う方法](http://qiita.com/) (執筆中)
【touch】Linux コマンド

#touch [option] file
指定したファイルの最終更新日時やアクセス日時を変更する。
指定したファイルが存在しない場合は空のファイルを作成する。

##option
`-a`
アクセス日時を変更する。

`-c`
指定したファイルが空の場合でもファイルを作成しない。

`-m`
最終更新日時のみを変更する。

`-r`
指定したファイルと同じ日時にする。

`-t [[CC]YY]MMDDhhmm[.ss]`
現在時刻の代わりに指定した時刻に変更する。
Gitで管理しているExcelファイルの差分を見る

## 動機
ExcelファイルをGitで管理しているときに、差分を見られると嬉しい。Git for Windows (msysgit)は、WordファイルやPDFファイルは差分を見られるように設定済で配布されているが、Excelファイルについては未対応。

## できたこと

 * git diffでExcelファイルに加えた変更を確認してからgit commitできる
 * もちろん過去の履歴の差分も見られる
 * 行頭にシート名が含まれていて複数シートにも対応している

CUIでのExcelファイルの差分表示例
![cui.png](https://qiita-image-store.s3.amazonaws.com/0/60598/244a990b-e1be-0a69-f9ba-2b8d41450cd2.png)

GUI ([Git Extensions](https://code.google.com/p/gitextensions/))でのExcelファイルの差分表示例
![gui.png](https://qiita-image-store.s3.amazonaws.com/0/60598/04cbd3d9-af87-dac0-6fb6-faa6fe4ae341.png)

超便利！！！

## 使ったもの

 * [Git for Windows (msysgit)](https://msysgit.github.io/
) version 1.8.4.msysgit.0
 * [Go](https://golang.org/) 1.4.2
 * [git-xlsx-textconv](https://github.com/tokuhirom/git-xlsx-textconv) ab71fc84ecd7ae97b19305ba05159dda867ca7c3

## 手順

### Go環境の構築
まずはGo言語の環境を構築します。といっても、.msi形式のインストーラををダウンロードしてきてインストールするだけです。.msiファイルのダウンロードは https://golang.org/dl/ から。

インストール後は、環境変数`GOPATH`にフォルダを指定します。ちなみにですが、環境変数の管理には[Rapid Environment Editor](http://www.rapidee.com/)がお勧めです。`GOPATH`はどこでもよいです。自分しか使わないPCなので、`C:\gocode`フォルダをつくり、システム全体の環境変数として指定しちゃいました。

![gopath.png](https://qiita-image-store.s3.amazonaws.com/0/60598/2e1df908-3044-bd63-2228-a92b446d05d6.png)

コマンドプロンプトでgoコマンドが通ることと、GOPATHが設定されていることを確認します。

```shell-session
> go version
go version go1.4.2 windows/amd64

> go env GOPATH
C:\gocode
```

### git-xlsx-textconvの取得とビルド
コマンドプロンプトで以下のとおり実行します。

```shell-session
> go get github.com/tokuhirom/git-xlsx-textconv
```

`%GOPATH%\bin\git-xlsx-textconv.exe`が実行できることを確認します。

```shell-session
> %GOPATH%\bin\git-xlsx-textconv.exe
2015/04/07 22:24:53 Usage: git-xlsx-textconv file.xslx
```

### Gitの設定
Gitで設定しなくてはいけないのは、いつもの`git config`と`gitattributes`の2つ。リポジトリごとの設定でもいいのですが、これまた自分しか使わないPCなので、msysgitのグローバルな設定に施してしまいます。msysgitのグローバル設定は`C:\Program Files (x86)\Git\etc`配下においてあります。

`C:\Program Files (x86)\Git\etc\gitconfig` をAdministrator権限のテキストエディタで開き、以下を追記します。ここでは、`%GOPATH%`ではなく`$GOPATH`を使うのが正解の模様。

```
[diff "xlsx"]
	binary = true
	textconv = $GOPATH/bin/git-xlsx-textconv
```

`C:\Program Files (x86)\Git\etc\gitattributes` を同じくAdministrator権限のテキストエディタで開き、以下を追記します。

```
*.xlsx	diff=xlsx
*.XLSX	diff=xlsx
```

以上で終わりです。簡単で便利です。

## TODO
簡単とはいえ手順が必要なのはいけてないので、[msysgit](https://github.com/msysgit)の本家に貢献できないか考える。

ちなみに、msysgitのデフォルトのgitattributesには以下が指定されていて、これらのファイルの差分は特に設定なしに差分が取れる。

```
*.doc	diff=astextplain
*.DOC	diff=astextplain
*.docx	diff=astextplain
*.DOCX	diff=astextplain
*.dot	diff=astextplain
*.DOT	diff=astextplain
*.pdf	diff=astextplain
*.PDF	diff=astextplain
*.rtf	diff=astextplain
*.RTF	diff=astextplain
```
OpenCVSharpのFindContoursAsArray()は破壊的である

OpenCVの輪郭検出関数findContours()は破壊的である。

> void findContours(const Mat& image, vector<vector<Point> >& contours, vector<Vec4i>& hierarchy, int mode, int method, Point offset=Point())
> void findContours(const Mat& image, vector<vector<Point> >& contours, int mode, int method, Point offset=Point())
> 2値画像中の輪郭を検出します．
> （略）
> 注意： 元の image は，この関数によって書き換えられます．
http://opencv.jp/opencv-2svn/cpp/imgproc_structural_analysis_and_shape_descriptors.html#cv-findcontours

これはまぁ気をつければなんとか。

一方、これをwrapしたOpenCVSharpの関数はこういうシグネチャになっているが、これも破壊的なのである。
```csharp
public Point[][] FindContoursAsArray(ContourRetrieval mode, ContourChain method, Point? offset = null)
```

元のものが壊されたくなければ、こうすればよい。
```csharp
mat.Clone().FindContoursAsArray(ContourRetrieval.External, ContourChain.ApproxSimple)
```

気をつけるべし。
iTerm2 Trigger Regular Expression

iTerm2のRegular Expressionを使って
tailや
mysqlコンソールに色を付ける

* SQLキーワードに色を付ける
Regular Expression:
\s+(?i:select|update|insert|where|from|group by|order by|and|as|in)\s+
Action: Highlight Text
Parameters: Green Foreground

* 日付に色を付ける
Regular Expression:
([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})
Action: Highlight Text
Parameters: Purple Foreground


##### 正規表現のテストには
Menu-Edit-Find-Find...で検索ボックスが出たら、
ゴーグルをクリックして、RegularExpressionにチェックボックスを入れてから、
検索ボックスに正規表現を書く。これをそのままもっていけばいい
はじめてのstylus①


私はこれまで、CSSの延長線ということで、
SCSSで主にスタイルシートのマークアップをしていました。

しかし、ひょうんなこと（coffee scriptとかrubyの影響）からSASS記法をつかいはじめました。

あれ？？？
SASSよりstylusの方がスタイリッシュじゃないか？
あんまり使っている人いないし？モテるんじゃないか？みたいなこと思い始め、stylusに手を出し始めました。


##導入(mac)
※ node&npmはインストールされているものとします

① ターミナルからstylusをグローバルインストール

`$ npm install -g stylus`

② インストールされているかチェック
`$ stylus -V`
ｖは大文字です。

##Usage

まずディレクトリ構造ですが、
`css/`
`stylus/style.styl`
とあるとします。

① コンパイル
`$ stylus`
or
`$ stylus stylus/`
ただ、こうするとstylus/の中にstyle.cssがコンパイルされます。

② アウトプットディレクトリを指定してコンパイル
`$ stylus stylus/ -o css/`
こうするとcss/の中にstyle.cssがコンパイルされます。

③watch
`$ stylus -w stylus/ -o css/`
・・・これだけで十分ですね。

正直、コマンドの使い方が書いてあるサイトがありませんでした。（公式になかった・・・）なので、
`$ stylus --help`
コマンドはこいつで逐一調べながらやっていくのがベターです。

また、gulpやgruntでもプラグインがあるので、使用している方はそちらに組み込んだ方が楽だと思います。

私はgulpを使ってますが近々試してみようと思っております。



##ライブラリ（sassでいうBourbonみたいなの）

Kouto-swissというそうです。こいつ一択？のようですが、resetだったりprefixだったりcompassには及ばずとも色々できそうです。

詳しくは公式見てください。
私も勉強中です。

http://kouto-swiss.io/

##参考サイト
http://totora0155.hatenablog.jp/entry/how-to-use-stylus

http://pgpg-sou.hatenablog.com/entry/2014/04/02/193159
MACのscutilコマンド使ってVPN接続する

いろいろな人がコマンドラインからのVPN接続のやり方は書いていたんですけど、自分の大学のVPNに繋ぐのにほんのちょっと苦労したので一応書き記しておこうかなと...

[MacでコマンドラインからVPN接続]("http://qiita.com/moritam@github/items/25aa9ab2153da2154ea4")

scutilというコマンドを使うところまでは良かったのですが、それだけだと鍵が必要なところには入れませんでした。

ということで

```
$ scutil --nc help
```

とすると

```
 start <service> [--user user] [--password password] [--secret secret]
                Start a given service. Can take optional arguments for user, password, and secret

stop <service>
                Stop a given service

```
とあるので

```
$scutil --nc start [VPNサービス名] --user [ユーザー名] --password [パスワード] --secret [共有シークレット]
```
で接続することができました。
ちなみに接続状況を知るには

```
$scutil --nc list
```
でVPNの接続状況が確認できます。
【Arduino】割り込みって何？　〜CPUの動作のちょっとした解説〜

皆さんこんばんは！
今日は割り込みについて、皆さんにシェアしたいと思います。

理解しやすいようにサンプルを下に用意してありますので、それも合わせてご覧ください！

# 割り込みって何？
そもそも、割り込みって何かご存じでしょうか？
普段皆さんが使われているPCでもごく普通に割り込みが使われています！
ほら、目の前、手元にあるそれですよ！！！
キーボード、マウス、ディスプレイ、全部CPUの割り込み機能によって実現されているんです。

割り込みとは、簡単に言うと、あらかじめ登録された命令を外部の要因（例えばボタンが押されたなど）で
最優先で実行するCPUの機能の事を言います。
最近のCPUやOSでは最優先というのはちょっと語弊がありますが（割り込みにも優先レベルがあるCPUが今は
ほとんどですので）、だいたいそう思っていただければ。

32bitのOSの頃や少し前のIntelのCPUでは、例えば、C言語の標準関数である、malloc()なども、
int80という割り込みを使って、カーネルモードに移行して、カーネル内部にある、メモリ取得機能を
実行して戻ってくるなんてことをやってました。
なので、割り込みって実は身近な存在なんです！！！

さてArduinoでは、リファレンスに公開されている機能だけを使うのであれば、
pin2,pin3が割り込み外部要因pinとして使えます。
http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=3045
コレがリファレンスです。

例えば、pin2に光センサーを取り付けて、暗くなったら、pin2がHIGH,LOWどちらかに変わるように
しておけば、暗くなった時に何か処理をさせることが出来ます。

実は、Arduinoは、Atmega328などのAVR CPUを使っており、このCPUは他のピンも
外部要因ピンとして動作させることが出来ます！
詳しくは、データシートをご覧ください。（ご要望があれば書きます）
http://www.avr.jp/
ここから詳しいCPUの解説が書いてあるデータシートをDLすることが出来ます。

一つだけ用語説明を！
上で出てきた、あらかじめ登録された命令をある特別なメモリ領域に記憶させておくのですが、
このメモリ領域の事を割り込みベクタといいます。
名前はvector＝ベクタ＝ベクトルから来ており割り込みが発生したらどこの処理をして良いのか
を指し示す方向という意味から名付けられたんだと思います。

## 割り込みって何がいいの？
Arduinoの場合、loop()がずっとぐるぐる回っていますので、なんで割り込みが良いのかわかり
にくいと思います。
loopの処理が軽ければ特に問題はあまり出てこないのですが、例えば、delay等が入っており、
1ループあたり30秒もかかるプログラムだった時に、外部要因に出来るだけ早く応答するシステム
を作る必要があるとき、普通に作ると、最大30秒もの遅延が発生します。
しかし、割り込みを使えば、loopの処理が実行中でも、優先的に割り込み処理をCPUは実行しますので、
遅延をかなり押さえることが出来ます。
loopなどで状態を見に行くことをポーリングといいます。
一方割り込みはCPUの機能なので、ポーリングという時間さえ省くことが出来るのです。
これは、遅延が許されないシステムを作るときには必須の知識です。


さて、一般的なpin2,pin3で実現しても良かったのですが、どうせなら、難しい方（データシートを
見ないとわからないと言う意味）の割り込みで実現したサンプルがあります。

コレです！！！
https://github.com/developerwaiwai/Arduino-Various/tree/master/auto_switch_optical_sensor_interrupt

これは私が書いたサンプルです。
pin4に光センサをつないで暗くなったら、pin5に刺さっているサーボを動かして、電気をつけるサンプルです。


コレを応用して作ったものが、自作IoTですwww
Arduino,Raspberry Pi,Windows Azureを使用した上から下までのフルシステムですw
興味のある方は是非、ソースを覗いて行ってください。
https://github.com/developerwaiwai/MyHomeSwitch

## 最後に
割り込みの概念がわかれば、OSのドライバを書くこともとても簡単になります！
一度トライしてみてはいかがでしょうか。
FactoryGirl でバリデーションもコールバックも無効にしたい

諸事情により FactoryGirl でバリデーションもコールバックも無効にしたいことがあったので。

# バリデーションしない

ActiveRecord の `#save` に `validate: false` を渡すとバリデーションしない。なので、FactoryGirl で `create` する時に `save!` ではなく `save(validate: false)` を呼び出すようにすれば OK。

FactoryGirl でインスタンスを保存する方法を上書きしたい場合は `to_create` を定義すれば良い。詳しくは[こちら](https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#custom-methods-to-persist-objects)。

```ruby
FactoryGirl.define do
  # ここに書いたら全 factory の to_create が上書きされる。
  # to_create { |instance| instance.save(validate: false) }
  factory :person do
    to_create { |instance| instance.save(validate: false) }
  end
end
```

# コールバックを走らせない

ActiveSupport::Callbacks::ClassMethods の `skip_callback` を使って、`before(:create)` でコールバックをスキップするようにする。それだけだと、factory でインスタンスを作成した後もスキップされっぱなしになるので `after(:create)` で `set_callback` する。

`set/skip_callback` の第一引数には `:validate` や `:save` など、対象のコールバックが呼び出されるイベントを指定。第二引数ではイベントの `:before`、`:after`、`:around` のいずれで呼び出されるのかを指定。`if` や `prepend` といったオプションも用意されている。

```ruby
FactoryGirl.define do
  factory :person do
    before(:create) { Person.skip_callback(:save, :before, :do_something) }
    after(:create) { Person.set_callback(:save, :before, :do_something) }
  end
end
```

参考：http://api.rubyonrails.org/classes/ActiveSupport/Callbacks/ClassMethods.html

# まとめると

こうなる。

```ruby
FactoryGirl.define do
  factory :person do
    to_create { |instance| instance.save(validate: false) }
    before(:create) { Person.skip_callback(:save, :before, :do_something) }
    after(:create) { Person.set_callback(:save, :before, :do_something) }
  end
end
```
macで英字配列のキーボードを買ったときにしたこと

とある退っ引きならない理由で英字配列のキーボードに乗り換えなくてはならなくなった。
最初は日本語を入力する事にさえ不自由していたが、いくつかの設定をして快適になったので、備忘録として残します。

## コマンドキーを英数/カナ変換に
[Karabiner](https://pqrs.org/osx/karabiner/index.html.ja)をインストールして、
スペースの左にあるコマンドキーを英数キー、右にあるコマンドキーをかなキーとして動くようにした。
やり方は、`Karabiner`を実行し、「Change Key」タブの「左右のコマンドキーを英数／かなとしても使う」の内「コマンドキーの動作を優先モード v2」にチェックを入れるだけ。

![スクリーンショット 2015-04-07 23.07.50.png](https://qiita-image-store.s3.amazonaws.com/0/8398/305a7232-9d1a-7ac0-1794-5451ee41d2c2.png)

これでJIS配列と同じように、スペースキーの左右を叩くことで入力モードを切り替えられるようになった。
このKarabinerかなりの優れもので、コマンドキーの同時押しの機能はきちんと生かしてくれている。
最初はコマンドキーが死ぬのか別に割り当てられるのではないかと不安だったけど、そんなことはなくストレスなく両方の機能が使えています。

## caps lockをcontrolに

次にしたことは、`caps lock`キーと`ctrl`キーの入れ替え。
ctrlキーが下段の`fn`キーと`option`キーの間にあり、さすがに押しにくかったので、jis配列と同じ位置である、`a`キーの横に持ってきた。
この入れ替えは、「設定」の「キーボード」で出来る。
「キーボード」の設定で「修飾キー」ボタンをクリックすると、以下のようなウィンドウが表示されるので、`Caps Lock キー`を`Control`に、`Control`キーを`Caps Lock`に変更した。

![スクリーンショット 2015-04-07 23.21.21.png](https://qiita-image-store.s3.amazonaws.com/0/8398/da5a3833-75c5-4668-f352-a26dfb9075a3.png)

以上、この２つを実施しました。

これでJISを使い続けていた自分でもほぼ不自由なく使えています。

以下、蛇足ですが、
英字配列に変えみて、バッククォートとシングルクォートがshift無しで打てたり、コロンが指の移動無しで打てるのが結構便利で気に入っています。
スクロールしない固定サイズのListViewを作成する

## はじめに

AndroidのListViewは、表示領域に収まらないリストをスクロールさせて表示するためにWidgetなので、本来タイトルのような使い方は好ましくないです。
ただどうしても使いたい場面が時々出てくるので、メソッドにまとめました。

## 実装したコード

```java
public static void makeFixedListView(ListView listView, int offset) {
    int totalHeight = offset;
    ListAdapter adapter = listView.getAdapter();
    int headerCount = listView.getHeaderViewsCount();
    int footerCount = listView.getFooterViewsCount();
    int itemCount = adapter.getCount();

    for (int i = 0; i < itemCount; i++) {
      View listItem = adapter.getView(i, null, listView);
      if (i < headerCount || i >= (itemCount - footerCount)) {
        listItem.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT,
            AbsListView.LayoutParams.WRAP_CONTENT));
      } else if (listItem instanceof ViewGroup) {
        listItem.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT));
      }
      listItem.measure(0, 0);
      totalHeight += listItem.getMeasuredHeight();
    }

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight + (listView.getDividerHeight() * (adapter.getCount() - 1));
    listView.setLayoutParams(params);
  }
```

## 補足-1

`makeFixedListView(ListView listView, int offset)` のoffsetは親のViewGroupにPaddingなどが設定されていた場合を想定しています。その場合、最終的に必要となるListViewの高さに影響しますので。

## 補足-2

詳細は割愛しますが、ListViewにHeaderやFooterがセットされていると他の`listItem`と同じように処理するとクラッシュします。原因はListViewが表示されるときに、HeaderとFooterは`(AbsListView.LayoutParams)getLayoutParams()`されるタイミングがあるためです。（詳細はListViewのコードを読むと分かります。）
そのためFooterとHeaderのときは、`AbsListView.LayoutParams`を使うようにしています。

## 補足-3

このメソッドは`setAdapter()`した後で使用する。
Could not find XXXX in any of the sources エラーの修正方法

# 環境
* ruby 2.1.3
* rbenv 0.4.0
* bundler 1.8.3

# 概要
以下のようなエラーが出た時に私個人で修正を行った再の備忘録です。
さまざまなケースがあると思いますが、私が発生したケースについて記載致します。

```bush
Could not find rake-10.4.2 in any of the sources
Run bundle install to install missing gems.
```

## エラー時の状況
* bundle exec rake db:migrate を実行すると発生。
* railsサーバー起動時はにはエラーが発生せず、正常に起動する。

# 修正経緯
## ruby 確認

```bash
$ ruby -v
$ ruby 2.1.3p242 (2014-09-19 revision 47630) [x86_64-darwin14.0]
$ which ruby
$ /Users/xxxx/.rbenv/shims/ruby
```
こちらは問題なかった。

## bundle 確認

```bash
$ which bundle
$ /usr/bin/bundle
$ bundle show rake
$ /Users/xxxx/.gem/ruby/2.0.0/gems/rake-10.4.2
```

こちららおかしい。。。両方とも./rbenv配下を見て欲しいが見ていない。。。
これが原因かと思い修正

## .bundle/config の削除
作成した覚えがないのだが .bundle/configというファイルがあり、中で以下が指定されていたため削除

### .bundle/config
```bash
  1 ---
  2 BUNDLE_PATH: /Users/xxxx/.gem
  3 BUNDLE_DISABLE_SHARED_GEMS: '1'
```

```bash
$ rm -rf .bundle/
### 一応 .gemも削除
$ rm -rf ~/.gem/
```
.bundle/configを削除

## もう一度 bundle系を確認

```bash
$ which bundle
$ /usr/bin/bundle
$ bundle show rake
$ /Library/Ruby/Gems/2.0.0/gems/rake-10.4.2
```

あれ。。。今度はシステムの方を見に行ってしまった。。。。

## bundlerを再インストール

```bash
### rbenv exec を指定してinstall
$ rbenv exec gem install bundler
$ rbenv rehash

### 確認
$ which bundle
$ /Users/xxxx/.rbenv/shims/bundle
$ bundle show rake
$ /Users/xxxx/.rbenv/versions/2.1.3/lib/ruby/gems/2.1.0/gems/rake-10.4.2
```
.rbenv配下を指すようになった。

## bundle install実施

```bash
$ bundle install
```

これでめでたく上記エラーが出なくなりました。

# 結論
以下のコマンドでbundlerを再インストールするとエラーが改善するかもです。

```bash
$ rbenv exec gem install bundler
$ rbenv rehash
```
chart.js で折れ線グラフを作成

## <i class="fa fa-pie-chart" style="font-size:1em;"></i> 概要
chart.js で折れ線グラフを作成します。

## <i class="fa fa-flask" style="font-size:1em;"></i> サンプル

~~~html
<!doctype html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Line Chart Test</title>
  <script src="Chart.min.js"></script>
  <script language="JavaScript"><!--
  function displayLineChart() {
    var data = {
        labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
        datasets: [
            {
                label: "Prime and Fibonacci",
                fillColor: "rgba(220,220,220,0.2)",
                strokeColor: "rgba(220,220,220,1)",
                pointColor: "rgba(220,220,220,1)",
                pointStrokeColor: "#fff",
                pointHighlightFill: "#fff",
                pointHighlightStroke: "rgba(220,220,220,1)",
                data: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
            },
            {
                label: "My Second dataset",
                fillColor: "rgba(151,187,205,0.2)",
                strokeColor: "rgba(151,187,205,1)",
                pointColor: "rgba(151,187,205,1)",
                pointStrokeColor: "#fff",
                pointHighlightFill: "#fff",
                pointHighlightStroke: "rgba(151,187,205,1)",
                data: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
            }
        ]
    };
    var ctx = document.getElementById("lineChart").getContext("2d");
    var options = { };
    var lineChart = new Chart(ctx).Line(data, options);
  }
  --></script>
</head>
<body onload="displayLineChart();">
  <div class="box">
    <canvas id="lineChart" height="450" width="800"></canvas>
  </div>
</body>
</html>
~~~

![line_chart.png](https://qiita-image-store.s3.amazonaws.com/0/43480/f0593209-324a-83a7-482e-6931c275c116.png)

## <i class="fa fa-github" style="font-size:1em;"></i> Gist
[Chart.js 折れ線グラフサンプル Gist](https://gist.github.com/tbpgr/304782f57b6f0a0fb8e7)

## <i class="fa fa-check-circle" style="font-size:1em;"></i> デモ
[Chart.js 折れ線グラフサンプル デモ](http://bl.ocks.org/tbpgr/304782f57b6f0a0fb8e7)

## :books: 外部資料
* <i class="fa fa-external-link" style="font-size:1em;"></i> [chart.js docs](http://www.chartjs.org/docs/#line-chart)
git pre-commitにghooksいいんじゃね？


#概要
コードを書いているとコミット前に自動でしてほしいことだったり、その他にもpush前にやっておきたいことがある。

そんな時gitにはいろんなイベントに対してhookしてくれる機能がある。
[Git のカスタマイズ - Git フック](http://git-scm.com/book/ja/v1/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%83%95%E3%83%83%E3%82%AF)


多人数チームで開発をしていると、コーディング規約をつくりそれ通りにやってくれるとレビューしやすいし細かいところ指摘しなくていいよなみたいなことがある。

そんな時はgitのcommitをhookに自動的にformatしてくれるようなtaskを実行すればいい。

しかしgitのhookは.gitの中のhooksが実行されるため、全体で同じようなhookをするためには```.git/hooks```をgitで管理する方法を取ったりしている。
でもsymlinkとか面倒だったりする。


#ghooks
[https://github.com/gtramontina/ghooks](https://github.com/gtramontina/ghooks)

ghooksは.hooksで書かれるスクリプトをpackage.jsonに書き、それを```.git/hooks```に上書きしgitのコマンドをトリガーにhookしてくれる


package.jsonに定義されるのはかなりいいなと感じた。
正直まだ検証しきれてないからいいんじゃね？程度の提案
cocos2d-jsのタッチイベントハンドラで苦労した結果

サンプルの js-moonwarriors を元にというかそのままな感じで onTouchesMoved を onTouchesBegan へ置き換えただけの処理をしていたところ Android では動くが iOS では動かないという現象に遭遇。
サンプルでは touchId を操作していることが理由だったわけでほぼ自爆した感じなのだが、せっかくなので挙動確認結果のメモを残す。

[公式サイトの記述](http://cocos2d-x.org/docs/manual/framework/html5/v3/eventManager/en "")を読みながら次のように書き方を整理して対応。
id の操作は必要に応じていずれ行うことにする。

```javascript
var GameMainLayer = cc.Layer.extend({
	ctor: function(){
		this._super();
	},
	init: function () {
		if (cc.sys.capabilities.hasOwnProperty('touches')) {
			cc.eventManager.addListener({
				event: cc.EventListener.TOUCH_ALL_AT_ONCE,
				swallowTouches: true,
				onTouchesBegan: this.onTouchesBegan,
				onTouchesMoved: null,
				onTouchesEnded: null
			}, this)
		}
	},
	onTouchesBegan: function(touches, event) {
		// to do here
		return true;
	}
});
```

サンプルの記述がちょっと唐突な感じなのと（Began の function がないと id 操作の意味がわからない）、ネットに散在する情報が古めだったりで把握に手間取ったが cocos2d-js v3.5 の時点では次のように考えておけばよさそう。

* マルチタッチを拾うのであればイベントのタイプを cc.EventListener.TOUCH_ALL_AT_ONCE にしてコールバック群は「onTouches?????」を使用。（複数形）
* シングルでよいのであればイベントのタイプを cc.EventListener.TOUCH_ONE_BY_ONE にしてコールバック群は「onTouch????」を使用。（単数形）

このコールバック時のメソッド名とイベントタイプの関係に最初気づいていなかったため勝手に苦労してしまった。
[apex:コード]MAP の中の日付でソートをする

Sort　は　List　にはあるけど、MAPでするとこんな感じになる。

```java:mapsort.java
	map<String,Date>  ADMapInfo = new  map<String,Date>();
	
	ADMapInfo.put('A10001', Date.newInstance(2014, 10, 01));
	ADMapInfo.put('A10002', Date.newInstance(2014, 01, 19));
	ADMapInfo.put('A10003', Date.newInstance(2014, 09, 23));
	ADMapInfo.put('A10004', Date.newInstance(2013, 12, 07));

	//IDを保存
	map<String,String> aMap = new Map<String,String>();
	//IDのリスト
	List<String> aList = new List<String>();
	//データのリスト
	List<Date> values = new List<Date>();

	//IDのリスト作成
	aList.addAll(ADMapInfo.keySet());

	//IDのリスト回しながら、データのリスト作成する
	//また、データ取出し用のデータを作る。
	for(String str:aList)
	{
		values.add(ADMapInfo.get(str));
		aMap.put(str+ADMapInfo.get(str).format(),str);
	}
	values.sort();
	for(Date s: values)
	{
		for(String str:aList)
		{
			if(aMap.get(str+s.format()) <> null){
				system.debug(str+ '>>' + s.format());
			}
		}
	}
```
【jQuery】かなり簡単なスムーススクロールの実装



プラグイン使うのがあまり得意でないため、いつもこれを使います。
もっと簡単なやり方があれば教えて下さい・・・。

```js:script.js

$(function () {

  $('a[href^=#]').click(function() {
  
    var myHref, myPos, duration;
    myHref = $(this).attr('href');
    myPos = $(myHref).offset().top;
    
    duration = 500;
    
    $('html, body').animate({
      scrollTop: myPos
        }, duration);
        return false;
    });
    
  });
    
```
Scalaで素数判定プログラムを書いてみた

# Scalaで素数判定
scalaで入力された数字が素数か判定するプログラムを書いてみました。
素数なら"prime number"が、素数でないなら"not prime number"が出力されます。
Scala勉強中なので改善点があれば教えてください。

```PrimeNumber.scala
object PrimeNumber {
  def main(args: Array[String]) = {
    println("Enter number")
    val num: Int = scala.io.StdIn.readInt
    primeNumberChecker(num) match {
      case 0 => println("prime number")
      case 1 => println("not prime number")
      case _ => println("error")
    }
    def primeNumberChecker(x: Int): Int = {
      var check: Int = 0
      if(x > 1) {
        for(i <- 1 to x) {
          if( (i != 1) && (i != x) && (x % i == 0) ) { check = 1 }
        }
      } else { check = 1 }
      check
    }
  }
}
```
【CakePHP】トランザクション

コントローラーからdelete/inseretをトランザクションで行っている。validationでエラーの場合も、ロールバックしている。

```php
$dataSource = $this->Member->getDataSource();

try{
  //BEGINの発行
  $dataSource->begin();

  if (!$this->Member->deleteAll($delte_condition)) {
    throw new Exception('delete失敗のメッセージ');
  }

  if (!$this->Member->save($data)) {
    throw new Exception('insert失敗のメッセージ');
  }
  
  //COMMITの発行
  $dataSource->commit();
} catch(Exception $e) {
  //ROLLBACKの発行
  $dataSource->rollback();

  //ログにエラー内容を出力
  $this->log($e->getMessage());
  $this->log($e->getTraceAsString());
}
```

begin()、commit()、rollback()を行うためのデータソースの取得は、更新対象のモデルでなくても良い。
KaminariをSlimで使用した際のメモ

# 概要

ページング処理の実装をサポートしてくれる Gem です。
Slim での使用例をメモしています。

# 導入

```ruby:Gemfile
gem 'kaminari'
```

```shell-session
bundle install
```

```ruby:users_controller.rb
def index
  @users = User.page(7).per(50)
end
```

```slim:index.html.slim
= paginate @users
```

# 同一ページで複数のページネーション

`param_name` を指定して、個別にページ数を扱うようにします。

```ruby:users_controller.rb
def index
  @a_users = User.where(status: 'a').page(params[:a_page])
  @b_users = User.where(status: 'b').page(params[:b_page])
end
```

```slim:index.html.slim
= paginate @a_users, param_name: 'a_page'
= paginate @b_users, param_name: 'b_page'
```

# Ajax で更新

`remote: true` を指定すると Ajax が可能です。
Ajax のリクエストに対して、リストを再描画するような js を返却します。

```ruby:users_controller.rb
def index
  @users = User.page(param[:page])
  respond_to do |format|
    format.html
    format.js
  end
end
```

```slim:index.html.slim
#users
  = render partial: 'users', locals: {users: @users}
```

```slim:index.js.slim
| $('#users').html('#{j render partial: 'users', locals: {users : @users}}');
```

```slim:_users.html.slim
- users.each do |user|
  / do something ...

= paginate users, remote: true
```

# 外部 API 連携

`paginate_array` を利用し、配列に対してページネーションを行います。

```ruby:controller.rb
def index
  page = params[:page] || '1'

  limit = 10
  offset = (page.to_i - 1) * limit

  # limit, offset を受け取り、リストと最大件数を返すような API にリクエスト
  @items, pagination = request_external_api(limit, offset)
  total = pagination['total']

  @items = Kaminari.paginate_array(@items, total_count: total).page(page).per(limit)
end
```

```slim:index.html.slim
= paginate @items
```

# Bootstrap 用の View に調整

Bootstrap のテーマを指定して、 View を生成します。

```shell-session
rails g kaminari:views bootstrap3 -e slim
```

以下のファイルが生成されます。
大枠の調整に関しては `_paginator.html.slim` を触る形になりそうです。

```
app/views/
└── kaminari
    ├── _first_page.html.slim
    ├── _gap.html.slim
    ├── _last_page.html.slim
    ├── _next_page.html.slim
    ├── _page.html.slim
    ├── _paginator.html.slim
    └── _prev_page.html.slim
```

# 設定調整

設定ファイルを生成します。

```shell-session
rails g kaminari:config
```

以下のファイルが生成されます。
それぞれデフォルト値がコメントされていますので、適宜調整していきます。

```ruby:config/initializers/kaminari_config.rb
Kaminari.configure do |config|
  # config.default_per_page = 25
  # config.max_per_page = nil
  # config.window = 4
  # config.outer_window = 0
  # config.left = 0
  # config.right = 0
  # config.page_method_name = :page
  # config.param_name = :page
end
```

`paginate` で個別に指定することも可能です。

```slim:index.html.slim
= paginate @users, window: 2
```

# 参考

* [GitHub/kaminari](https://github.com/amatsuda/kaminari)
* [GitHubWiki/kaminari](https://github.com/amatsuda/kaminari/wiki)
* [kaminari徹底入門](http://qiita.com/nysalor/items/77b9d6bc5baa41ea01f3)
* [Kaminariにて複数のpaginationを同じ画面に混在させる方法](http://qiita.com/yuutetu/items/b83d7c634914b1e99e89)
* [kaminariを使ってajax通信でページ送りを実装しました](http://yutaszk23.hatenadiary.jp/entry/2014/03/08/211430)
* [Railsでkaminariを使わずにシンプルなページング処理を自作する](http://qiita.com/knt45/items/8ed3e9f77509ecc6a69d)
* [Railsでkaminariを使ってページネーションを実現する](http://ruby-rails.hatenadiary.com/entry/20141113/1415874683)
NSURLSessionConfigurationについてメモ

# NSURLSessionConfigurationについて整理する
`NSURLSessionConfiguration`、意外と情報が少ないので整理しておく。

## インスタンスの生成
以下のメソッドで、`NSURLSessionConfiguration`のインスタンスを生成することができます。

* + defaultSessionConfiguration
* + ephemeralSessionConfiguration
* + backgroundSessionConfigurationWithIdentifier:

### defaultSessionConfiguration
`NSURLConnection`と同じように通信するように設定されたインスタンスを生成します。
キーチェーンに保存された証明書や、ストレージに永続化されたキャッシュ、`NSURLConnection`や`NSURLDownload`と同じcookieのストレージを使います。

### ephemeralSessionConfiguration
証明書やキャッシュ、cookieをメモリ上に保存するデータ転送のためのインスタンスを生成します。
`NSURLSession`が破棄されたタイミングで全てのデータが消去されます。

また、メモリ使用量の制約を受けるため、使用時にはどの程度の転送量が発生するか、考慮する必要があります。

### backgroundSessionConfigurationWithIdentifier:
HTTP/HTTPS通信で、ダウンロード・アップロード処理をバックグラウンドで行えるインスタンスを生成します。
アプリケーションとは別なプロセスで通信するため、アプリケーションがバックグラウンドにいる場合や、アプリケーションが終了している場合でも通信を継続します。
（ユーザーがアプリを強制終了した場合は通信を終了します）

このクラスメソッドで指定するidentifierは、指定したIDの`NSURLSession`のインスタンスを再生成するときに必要になります。
ダウンロード完了時にアプリケーションが終了しているとき、再起動されたアプリケーションを進行中のバックグラウンド転送のタスクに紐付け直します。
その際にidentifierが必要になります。

## 実装時に考慮したほうが良さそうなプロパティ
### allowsCelluarAccess
3G・4G回線を使ったアクセスを許可するか、指定するプロパティです。
デフォルト値は`YES`です。

### timeoutIntervalForRequest
データの転送が始まるまで、何秒待機するか指定するプロパティです。
デフォルト値は60秒です。

### timeoutIntervalForResource
全てのデータを転送するまで、何秒待機するか指定するプロパティです。
デフォルト値は604800秒（7日間）です。

### discretionary
バックグラウンド転送の際、バッテリー残量や通信状況に応じて通信処理の優先度を下げても良いか、指定するメソッドです。
大容量のファイル転送などの場合、YESを設定することが推奨されています。
UIKit DynamicsでViewを落下させる！(息抜き)

ええい！ってなったときに、
UIViewを全部落下させてみるのもいいかもしれません。
iOS7から使えるようになったUIKit Dynamicsを使えば結構簡単です。

そこで、ちょっと息抜きにSORDynamicAnimator(後述)なるクラスを作ってみました。
使い方はカンタン。
そっと2行書くだけ・・・。


``` swift:ViewController.swift
class ViewController: UIViewController {
    
    //アニメーション中は保持する必要があります
    var animator : SORDynamicAnimator?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // アニメータ初期化
        self.animator = SORDynamicAnimator(referenceView: self.view)
        self.animator?.start()
    }
}
```



``` swift:SORDynamicAnimator.swift
class SORDynamicAnimator: NSObject {

    let referenceView : UIView

    private var items : [AnyObject] = []
    
    private var animator : UIDynamicAnimator? //これをアニメーション中保持しておく必要あり！

    init(referenceView : UIView) {
        self.referenceView = referenceView
    }
    
    func start() {
        if self.animator == nil {
            let view : UIView = self.referenceView
            var items : [AnyObject] = []

            //レイアウトを強制的に更新
            view.layoutIfNeeded()
            
            //全てのsubViewを抽出
            self.allSubviews(view)
            
            //全てのsubViewからUILayoutSupportを省く
            for item in self.items {
                if item is UILayoutSupport {
                    continue
                }
                if item is UIDynamicItem {
                    items.append(item)
                }
            }
            
            //アニメータ作成
            let animator = UIDynamicAnimator(referenceView: view)
            
            //重力設定
            let gravityBeahvior = UIGravityBehavior(items: items)
            animator.addBehavior(gravityBeahvior)
            
            //衝突設定
            let collisionBehavior = UICollisionBehavior(items: items)
            collisionBehavior.translatesReferenceBoundsIntoBoundary = true
            animator.addBehavior(collisionBehavior)
            
            self.animator = animator
        }
    }
    
    private func allSubviews(view : UIView) -> () {
        for subview in view.subviews {
            if subview is UIView {
                self.items.append(subview)
                self.allSubviews(subview as! UIView)
            }
        }
    }
}
```



適当にラベルやらを並べてみる

![iOS Simulator Screen Shot 2015.04.07 19.24.24.png](https://qiita-image-store.s3.amazonaws.com/0/74739/67b5121c-0b76-0ef6-23c7-388efcdaf1f0.png)

表示と同時に、崩れ落ちていく、、、

![iOS Simulator Screen Shot 2015.04.07 19.24.08.png](https://qiita-image-store.s3.amazonaws.com/0/74739/485bcf5a-6ecb-25bb-42ab-7edbe8d2c85e.png)


なお、TableViewやらNavigationControllerやら使ってるとクラッシュしちゃいます・・。
valgrindでC/C++のメモリリークを発見する

c言語やc++のプログラムのメモリリークをチェックするのに、valgrindが便利です。

## install

`sudo apt-get install valgrind`
や
`brew install valgrind`
で入ります。

参考: [Yosemiteでvalgrindを入れる - Qiita](http://qiita.com/tjun/items/372744484db91e23fe3f)

## 使ってみる

例えば次のような、メモリリークやダブルフリーをしてるコードがあるとします。

```c
#include <stdlib.h>

int main() {
  char* test1 = (char*)malloc(sizeof(char) * 4);
  char* test2 = (char*)malloc(sizeof(char) * 4);

  free(test2);
  free(test2);
}
```

上の例では、test1が解放されておらず, test2が2回フリーされてる。

ビルドします。

    gcc sample.c -g


valgrindを使って実行します。

    valgrind --leak-check=full ./a.out

すると、以下のように出力されます。

```
==23525== Invalid free() / delete / delete[] / realloc()
==23525==    at 0x1000089DF: free (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==23525==    by 0x100000F4F: main (sample.c:8)
==23525==  Address 0x10081f510 is 0 bytes inside a block of size 4 free'd
==23525==    at 0x1000089DF: free (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==23525==    by 0x100000F46: main (sample.c:7)
==23525==
==23525==
==23525== HEAP SUMMARY:
==23525==     in use at exit: 34,997 bytes in 426 blocks
==23525==   total heap usage: 507 allocs, 82 frees, 41,129 bytes allocated
==23525==
==23525== 4 bytes in 1 blocks are definitely lost in loss record 1 of 81
==23525==    at 0x10000859B: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==23525==    by 0x100000F26: main (sample.c:4)
==23525==
==23525== LEAK SUMMARY:
==23525==    definitely lost: 4 bytes in 1 blocks
==23525==    indirectly lost: 0 bytes in 0 blocks
==23525==      possibly lost: 0 bytes in 0 blocks
==23525==    still reachable: 0 bytes in 0 blocks
==23525==         suppressed: 34,993 bytes in 425 blocks
==23525==
==23525== For counts of detected and suppressed errors, rerun with: -v
==23525== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 17 from 17)
```

上記のうち、

    ==23525== Invalid free() / delete / delete[] / realloc()
    ==23525==    at 0x1000089DF: free (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
    ==23525==    by 0x100000F4F: main (sample.c:8)
    ==23525==  Address 0x10081f510 is 0 bytes inside a block of size 4 free'd
    ==23525==    at 0x1000089DF: free (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
    ==23525==    by 0x100000F46: main (sample.c:7)

の部分は、7行目でfreeしたのに8行目でもfreeしてしまっていることを示しています。

そして、

    ==23525== 4 bytes in 1 blocks are definitely lost in loss record 1 of 81
    ==23525==    at 0x10000859B: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
    ==23525==    by 0x100000F26: main (sample.c:4)

では4行目のmallocで確保した領域が解放されていないことを示しています。


という感じでお手軽にチェックできるので、とりあえずvalgrindかけてみるのはおすすめです。
【jQuery】stopメソッドを理解する


#stopメソッド

私はstopメソッドを`$(hoge).stop().animate({`のような、
引数を指定しない方法でしか使っていませんでした。

しかし、`true/false`の引数の使い分けで四種類の動作が使い分けることができるようだったので、
ビボっておこうと思います。

## 引数によって変わる処理の仕方


```js:stop.js

/* １．現在のアニメーションが最後まで完了していなくても、その状態から次のアニメーションに移行する*/
stop(false, false).animate
stop().animate

/*２．現在のアニメーションが完了しないまま、次のアニメーションは破棄されて実行されないので、
最初のアニメーションの途中状態で止まる*/
stop(true, false).animate

/*３．現在のアニメーションは最終的なゴールにジャンプし、そこから次のアニメーションが開始される*/
stop(false, true).animate

/*４．現在のアニメーションは最終的なゴールにジャンプするが、次のアニメーションは破棄されて実行されない*/
stop(true,true).animate
```


fadeやslideでもそうですが、ホバーアニメーションの途中でマウスアウトしたりすると、
opacityや高さが戻りきっていない状態の時があるのは`stop()`→`stop(true, true)`にすればいいようです。

##補足
<dl>
<dt><strong>第一引数</strong></dt>
<dd>現在のアニメーションをゴールまでジャンプさせるか否か</dd>
<dt><strong>第二引数</strong></dt>
<dd>待機状態のアニメーションを破棄するか否か</dd>
</dl>
[Qiita] Qiita向けの記事投稿・編集アプリを作りました

最近Qiitaへ投稿する記事をモバイル端末で書くことが多くなりました。
そこでQiitaに記事を投稿できるアプリが無くて欲しいなと思ったので、Qiitaへ記事を投稿することのできるアプリ**『どこでもQiita』**を作ってみました。
Webサービスと連携したアプリを作ってみたいとも前から思っていたので、勉強の教材としてこれ以上のものはないですね。
・・・ちなみにこの記事、今回作った『どこでもQiita』から投稿しています。

[どこでもQiita - 記事編集・投稿アプリ for Qiita (iOS版)](https://itunes.apple.com/jp/app/dokodemoqiita-ji-shi-bian/id978369969?mt=8)

![fix0.jpg](https://qiita-image-store.s3.amazonaws.com/0/38888/de7a6bfc-dddb-eb32-593a-3881e7a5348d.jpeg)　![fix1.jpg](https://qiita-image-store.s3.amazonaws.com/0/38888/f87b5414-7c0c-c57f-04b5-c50e2b204b72.jpeg)　![fix2.jpg](https://qiita-image-store.s3.amazonaws.com/0/38888/df9d0e8e-65c6-fc69-3b7b-2c8d608ee919.jpeg)

![fix3.jpg](https://qiita-image-store.s3.amazonaws.com/0/38888/943edb38-3b1e-0cf8-003a-5ae4dd7a239b.jpeg)　![fix4.jpg](https://qiita-image-store.s3.amazonaws.com/0/38888/410de26e-beb2-fee1-868e-e9be79ee8888.jpeg)

※ Android版も提供予定ですが、動作確認が取れていないため、確認が取れ次第公開する予定です。

# 『どこでもQiita』を使ってできること

* OAuth認証によるQiitaへのログイン（GitHubやTwitterアカウントによるログインも可能）
* 記事の新規投稿
* 記事の下書き保存
* 投稿した記事の修正・削除
* 下書きの修正・削除・Qiitaへの新規投稿
* 記事・下書きのプレビュー（Qiitaとの互換性はなし）

記事を投稿することに重点をおいているため、自分以外の他の人が投稿した記事は見ることができません。
他の人の記事をみたい場合には、すでにたくさんの素晴らしいアプリがありますのでそちらをご利用ください。

# 開発方針

Qiitaに記事を投稿するために最低限必要な機能のみ考え、とりあえず完成・リリースさせることを最優先としました。
**機能をたくさん追加することで完成しないよりも、最低限の機能でも完成させた方が良い**と考えました。
そのため開発方針は以下のような感じで、まずはリリースさせることに集中しています。

* クロスプラットフォームに対応する
* Qiitaへの記事投稿に**機能を限定し、余分な機能はつけない**
* フラットなデザインを採用する
* ライブラリを積極的に使い、**車輪の再発明はしない**
* ある程度完成したら使用感を確かめて、問題箇所を修正する
* 便利そうな機能を思いついても、**最初のリリースでは開発せずに次のバージョンに持ち越す**

# 開発ツール、利用したライブラリ

アプリの開発のために利用したツールとライブラリを簡単に紹介します。

### PhoneGap (Cordova)
iOS/Androidのどちらにも対応したアプリを作りたかったので、開発ツールも**複数の端末・プラットフォームに簡単に対応できるもの**を選びました。
Xamarineという選択肢もありますが**有料**であったので、無料のPhoneGapを選んでいます。

### Onsen UI
iOS7風の**フラットなデザインを持つアプリを作成**することができます。
このライブラリがなかったら、今のようなフラットテザインに比べて激しく劣っているものとなっていたでしょう。

## marked
下書きのプレビュー画面で、**markdown記法で書かれた文章をHTMLに変換する**ために使用しています。
変換処理のために時間がかかると思っていましたが、このライブラリは**非常に高速に動作します**。

## highlight.js
markedによって変換されたHTMLに対して、**ソースコード箇所を色付けする**ために使用しています。

# ソースコード

『どこでもQiita』の全ソースコード（パスワードなどの秘密情報は除く）はGitHubに公開しています。

[nutti/Doko-Demo-Qiita](https://github.com/nutti/Doko-Demo-Qiita)

ライブラリを何度も変えたのと、リリースに向けてほぼ突貫工事のような開発を行っていたので、ソースコードの見易さは度外視しています。

# 開発を終えて

PhoneGapでの開発が初めてであることと、ゲームではないアプリの開発が初めてであることから、開発規模に対してリリースまで二ヶ月弱とそれなりに時間がかかってしまいました。
しかし開発を通してPhoneGapの使い方を知ることができましたし、Web関連の技術に触れられたことも非常によかったです。
このアプリを開発する前までは、**POST送信とかGET送信さえ知らなかった**わけですから、かなりいい勉強になりました！
また、Onsen UIという素晴らしいCSSライブラリにも出会えました。

**開発の初期段階で完成のレベルを低めに設定し、終わりが見えやすいようにすることは、開発を途中で投げ出さないために重要なこと**であると改めて実感しました。
開発中に思いついた改善案を全て実装していたら、途中で投げ出して無事にリリースまで辿りつけなかったと思います。

ひとまず開発はこれで終わりですが、ソフトウェアに限らず**ものを作るということは非常に楽しいこと**です。
また何か良いネタが思いついたら作りたいですね！

# 今後のアプリの更新

『どこでもQiita』のテスト中、既にいくつか追加・修正しておきたい機能が出てきました。
次回以降リリースする時に可能な限り反映していきたいと思います。
追加・修正したい機能は今のところこんな感じです。

* 既存のタグを検索して入力
* TwitterやGistへの投稿確認は、投稿ボタンを押した時の確認画面で表示
* エディタでmarkdown記法の構文を入力するボタンの設置
* エディタの全画面表示
* エディタからの画像を貼り付ける機能


# アプリのサポートについて

最後に、このような素人丸出しのアプリを使っていただいている方、ありがとうございます！
改善して欲しいことやアプリの不具合等がありましたら、報告いただければ幸いです。
可能な限り対応したいと思います。
あ、念のためですが本アプリは公式のものではないため、**間違ってもQiitaのサポートへ問い合わせたりしたらダメ**ですよ。
Hive on EMRで手っ取り早くTezを使う


## サマリ

社内でTezのデモを見たんだけど、非常に使い始めが簡単で、しかもクエリ高速化の効果がかなり高いので使い方をまとめておく。手順的にはビルド済みのTezをEMRのBootstrap actionでS3から配布する感じ。

Hiveの実行エンジンをMapReduceからTezに変えるだけで25%から、場合によっては50%以上も性能が上がるので、費用対効果としてはかなり高い施策だと思う。

## クラスタ起動

```bash
aws emr create-cluster \
--name tez_installed_cluster \
--ami-version 3.5.0 \
--applications Name=Hive \
--instance-groups InstanceGroupType=MASTER,InstanceCount=1,InstanceType=c3.xlarge InstanceGroupType=CORE,InstanceCount=4,InstanceType=c3.xlarge \
--ec2-attributes SubnetId=YOUR_SUBNET_ID,KeyName=YOUR_KEY_PAIR \
--log-uri s3://PATH/TO/LOG/ \
--enable-debugging \
--bootstrap-actions Name=tez,Path=s3://support.elasticmapreduce/bootstrap-actions/ami/3.2.x/install-tez.beta \
--steps Name=setup-tez,Jar=s3://elasticmapreduce/libs/script-runner/script-runner.jar,Args=s3://support.elasticmapreduce/bootstrap-actions/ami/3.2.x/setup-tez.beta
```

ポイントはbootstrap actionで起動される`install-tez.beta`とsetup-tezと命名したstepで実行される`setup-tez.beta`。`install-tez.beta`でビルド済みのTezをダウンロードしてきて、`setup-tez.beta`でHDFSに配置したりいろいろしてる感じ。

まあこの2行については何も変える必要はないのでコピペして動かせばOK。

## Tezを使う

Tezを使うのはすごく簡単

```
$ hive
```

```
hive> set hive.execution.engine=tez; 
```

これでOK。あとはHiveでいつもどおりクエリするだけ。

## MapReduceとくらべてみる

AmplabのビッグデータベンチマークのRankingsテーブルを使って比べてみることにする。

```
hive> CREATE EXTERNAL TABLE Rankings (
  pageURL STRING,
  pageRank STRING,
  avgDuration STRING
)
ROW FORMAT DELIMITED
  FIELDS TERMINATED BY ','
STORED AS SEQUENCEFILE
LOCATION 's3://big-data-benchmark/pavlo/sequence/1node/rankings/';

hive> select count(1) from rankings;
Status: Finished successfully
OK
17999999
```

ということでこの1800万行のテーブルへのクエリをMapReduceとTezで比べてみる。

### MapReduce
```
hive> set hive.execution.engine=mr; 
hive> select pagerank, count(1) from rankings group by pagerank;
Time taken: 97.975 seconds, Fetched: 3213 row(s)
```

### Tez
```
hive> set hive.execution.engine=tez; 
hive> select pagerank, count(1) from rankings group by pagerank;
Time taken: 72.925 seconds, Fetched: 3213 row(s)
```

所要時間 MR 97.975秒 vs Tez 72.925秒ということで、 **劇的に** とまではいかないが25%くらいの高速化はされている。もちろん、クエリの性質にも依存してると思うのでいろいろなパターンを検証してみないとより精緻な数値は出ない。

が、エンジンを変えるだけでこれだけ性能があたるというのはだいぶお得感がある。

## お約束

このポストは個人のメモであり、私の所属する組織を代表するものではありません。
クロスプラットフォーム開発の辛み

# クロスプラットフォーム開発経験
クロスプラットフォームというと主語がでかいですが、Titanium Mobileを指します。

Titanium Mobile開発経験約二年です。
出したアプリiOS6本/Android3本。
(Androidはストアから削除した/された)

* iOS: [Kensuke Hoshikawa のソフトウェアを iTunes でダウンロード](https://itunes.apple.com/jp/artist/kensuke-hoshikawa/id733552122)

最近はTitanium辞めてSwift書いてます。

# Titanium Mobileの辛み

1. クロスプラットフォームは幻想
    * iOSで開発完了→Android対応が容易ではない
    * 自分の場合、iOSにかけた時間の1.5倍くらいは必要だった
    * Android対応あきらめたアプリもある
    * ソースコードの中でiOSとAndroidの切り分けが頻発
2. バグがあった場合、Titaniumのバグかネイティブのバグかわからない
3. パフォーマンスがでない、カクカクする
4. ドキュメントに書いてあるのに動かない
5. ドキュメントに書いてないのに動く
5. 黒魔術的なコードを書かないと回避できなかったりする
6. Titaniumが対応しないと使えないapiがある、選択肢が狭くなってしまう
    * moduleがあればそれを使う、無ければ自分で作るしかない
    * 自分で作る->結局ネイティブの知識が必要
7. バイナリサイズがでかい
8. JS、いくらでもクソコードで動いてしまう
    * これは俺が悪い

# Titanium Mobileの良かったとこ

1. 記述量少なかった
    * swiftだと記述増えた、TitaniumはJSONでいい感じに書けた
2. JSで書ける
3. 学習コスト低め
3. ロジックはiOS/Androidで動く
    * UI作るのがツラい

# クロスプラットフォーム開発に必要なこと

1. 工数は半分で済むと思うな
2. アプリがヒットしたらネイティブで書き直す気持ち
    * 絶対にネイティブで開発したくなる
3. 地雷を踏み抜く勇気
4. 折れない心
5. ネイティブの知識
    * 無くても何とかなる

# 最後に

クロスプラットフォームの辛みを書きましたが、クロスプラットフォームをディスっているわけではないです。ただ、銀の弾丸ではないということを伝えたかっただけです。

また、個人の技量や経験に大きく左右されます。この内容に共感できる人もいればそうでないひともいるでしょう。

私はTitanium、好きでした。でもつらい。
ChatWorkでTo:が自分の時だけ未読数を表示させる

# js
```
setInterval(function () {
  // ページタイトルセット
  document.title = 'Silent ChatWork';

  // 左カラムの未読数を表示しない。(自分宛ては表示する)
  $('li ._unreadBadge.unread').css('display', 'none');

  // 左カラム、上の未読件数の合計も表示しない。(自分宛ては表示する)
  $('#_chatUnreadStatus').css('display', 'none');
}, 10000); // 10秒毎。
```

これをjs consoleで実行するとタイトルの通り。
既存プロジェクトでkakurenbo-putiを使うときのtips


この頃、論理削除に関する論争があったと思いますが、Railsではacts_as_paranoid, paranoia, kakurenboなど様々な論理削除用gemが登場しており、私もこれらのgemを利用していました。しかし、ActiveRecordのメソッドをオーバーライドするこれらのgemは、Railsのバージョンアップで壊れる可能性があり、メンテナンスされなくなってしまうとこれらのgemの影響でRailsのアップグレードができないということになりかねないため、paranoidを使うのをやめて、kakurenbo-putiを使うように修正中です。

kakurenbo-putiは、ActiveRecordのメソッドを上書きすることなく、機能追加という形で論理削除用のメソッドを入れるという方式のため、安全です。
しかし、既にparanoiaを使っているプロジェクトを修正していく際に、結構ハマりがちです。というかまだ私のプロジェクトでは修正しきれていません。

そこで、どういう対応をしたか忘れないために、メモを書いておこうと思います。

## Deviseを使っている場合

paranoiaを使っている場合はdefault_scopeが論理削除ユーザーを排除するように上書きされていたので特に意識することがなかったのですが、kakurenbo-putiの場合は、勝手にdefault_scopeを変更することはないので、自分で設定する必要があります。

Deviseのwikiに書かれていますが、認証部分のメソッドをオーバーライドして、ログイン可能対象ユーザーを絞っておく必要があります。`self.without_soft_destroyed`を使っておきます。

```rb:app/models/user.rb
class User < ActiveRecord::Base

  devise :database_authenticatable,
         :registerable,
         :timeoutable,
         :recoverable,
         :rememberable,
         :trackable,
         :confirmable


  soft_deletable column: :deleted_at

  # Deviseの認証に関わる箇所
  def self.find_for_database_authentication(warden_conditions)
    conditions = warden_conditions.dup
    self.without_soft_destroyed.where(conditions.to_h).first
  end

end
```

## Ancestryを使っている場合

ユーザーに、親ユーザーと子ユーザーを持たせていたので、Ancestryを使っています。
親ユーザーを論理削除したら、子ユーザーも全部論理削除してほしかったのですが、kakurenbo-putiで設定できる親子関係の削除設定は、ほかのテーブル同士の場合なので、Ancestryを使った同一テーブルのものは考慮されていません（当たり前だけど）。

### 子が削除されたら取得しないように

また、子ユーザーを論理削除した後でも、`user.children`を行ったら削除済みの子ユーザーが含まれた結果になります。しかし、childrenを上書きするのも面倒そうな気がしたので、短いメソッドを定義しました。`user.live_children`で論理削除を除いた子ユーザーを取得します。

```app/models/user.rb
class User < ActiveRecord::Base

  def live_children
    self.children.without_soft_destroyed
  end

end
```


### 親が削除されたら子も削除

そして、親ユーザーが削除されたら、子ユーザーを削除するという処理を書いておく必要があります。kakurenbo-putiのコードを読むと、`define_model_callbacks :soft_destroy`というのがあるので、これを使いましょう。

```app/models/user.rb
class User < ActiveRecord::Base

  soft_deletable column: :deleted_at
  has_ancestry

  set_callback :soft_destroy, :after, :soft_destroy_with_children

  def soft_destroy_with_children
    if self.root? && self.soft_destroyed?
      self.live_children.each do |child|
        child.soft_destroy
      end
    end
  end

end
```


また、Tipsがあったら追加していこうと思います。
Wordpressの画像を保護する

先日はWordpressを使った会員サイトを作成した際に、
ユーザーの個人情報を持ったファイルや画像を純正機能で
アップロードさせる機会がありました。アップロードしたものは
wp-content/uploadsディレクトリーに入りますので、URLさえ知っていれば
誰でもアクセスできてしまうのは残念なところです。

ユーザーによってアクセスされちゃ困るファイルを制御したい！
ということで、今回は簡単なプラグイン（WP File Protector）を作成しました。
プラグインというよりも、シンプルなphpのクラスですね。

仕組みはシンプルで、uploadsディレクトリ直下に.htaccessファイルを設置し、
ローカルホストからしかアクセスを受けられないようにします。
すべてのメディアURLを書き換えて、プラグインコードをバイパスするようにします。
プラグインの中にwpfp/display_fileというフィルターを用意して、すべての
メディアへのアクセス権限を決定させます。

上記フィルターのデフォルト結果はtrueであるので、functions.phpで
何も記載しなければ、特に制限なくすべてのユーザーがアクセスが可能です。

30分ほどで書いたものなので、バグ等がございましたらごめんなさい…

コードはこちら
https://github.com/web-picker/wp-file-protector

シンプルですが、使ってみて下さい。
Client Behaviorを作成する

http://jsfcorner.blogspot.jp/2013/02/client-behavior-functionality-with-jsf.html
を参考にBehaviorを実装してみたがbehavior-classが見つからないエラーが発生してしまう。

```text:エラー
javax.faces.FacesException: Could not find any registered behavior-class for behaviorId : confirmation
	at org.apache.myfaces.application.ApplicationImpl.createBehavior(ApplicationImpl.java:1182)
	at javax.faces.application.ApplicationWrapper.createBehavior(ApplicationWrapper.java:113)
	at org.apache.myfaces.view.facelets.tag.jsf.BehaviorTagHandlerDelegate.createBehavior(BehaviorTagHandlerDelegate.java:102)
	at org.apache.myfaces.view.facelets.tag.jsf.BehaviorTagHandlerDelegate.applyAttachedObject(BehaviorTagHandlerDelegate.java:137)
	at org.apache.myfaces.view.facelets.tag.jsf.BehaviorTagHandlerDelegate.apply(BehaviorTagHandlerDelegate.java:71)
```

以下は上記サイトを参考に実装した内容。

```java:ConfirmBehavior.java
@FacesBehavior(value = "confirmation")
public class ConfirmBehavior extends ClientBehaviorBase {
    @Override
    public String getScript(ClientBehaviorContext behaviorContext) {
        return "return confirm('Are you sure ?');";
    }
}
```

```xml:taglib.xml
<namespace>http://www.rubus.be/jsf/tutorial</namespace>
<tag>
    <tag-name>confirmation</tag-name>
    <behavior>
        <behavior-id>confirmation</behavior-id>
    </behavior>
</tag>
```

```html:confirm.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:r="http://www.rubus.be/jsf/tutorial"
...
<h:commandButton value="with confirmation" actionListener="#{bean.performAction}">
    <r:confirmation/>
</h:commandButton>
...
</html>
```

ConfirmBehavior.javaがbehaiviorとして読み込まれていないのが原因のようだったので、faces-config.xmlに追加してみたらうまくいった。

```xml:faces-config.xml
<behavior>
	<behavior-id>confirmation</behavior-id>
	<behavior-class>xxx.ConfirmBehavior</behavior-class>
</behavior>
```
Windows8.1環境での開発環境セットアップ

Windows8.1のセットアップをしたので、メモ。
私の環境のセットアップのメモなので参考になるかはわかりません。

# セットアップ目次
+ Atom
+ Git for Windows
+ ConEmu（Cmder）
+ Vim
+ Rapid Environment

# Atom
主にWindowsでのMarkdown環境として、Atomをダウンロードします。
いつの間にか、Windowsにも対応したりとかいろいろアップデートしてますね。

## インストーラ
[こちら](https://atom.io/)からダウンロード

## Plugin
[ここ](http://www.geeks-dev.com/atom-%E3%81%8C%E3%83%A4%E3%83%90%E3%82%A4%EF%BC%81sublimetext%E3%82%92%E4%BD%99%E8%A3%95%E3%81%A7%E5%87%8C%E9%A7%95%E3%81%97%E3%81%A6%E3%81%97%E3%81%BE%E3%81%A3%E3%81%A6%E3%81%84%E3%81%9F%E4%BB%B6/)などを参考に、いくつか入れました。

- minimap
- localization
- file-icons
- highlight-column
- highlight-line
- japanese-wrap
- linter
- vim-mode

# Git for Windows
## インストーラのダウンロード
[こちら](https://msysgit.github.io/)からインストーラをダウンロード

## インストール
[こちら](http://increment-log.com/git-install/)を参考にインストール。

### ポイント

+ Componentはそのまま
+ PATHの設定は真ん中
+ Line endingの設定も真ん中（環境次第）

## 日本語文字化け対応
[こちら](http://qiita.com/kumazo@github/items/2169e1ee7be278f82b94)を参考に変更する。

### ポイント

- トウフ化についてはComEmuを使う場合は対処不要
- lsの日本語メッセージ対応は必要（ただし後述のdotfiles作って設定してる場合は不要）

# ConEmu
ターミナルはConEmuを使ってます。

## ConEmuのメリット

- タブ機能がWindows環境としては超便利
  - タブごとに別のシェルを立ち上げられる（cmd、PowerShell、GitBash...etc）
- 画面分割できる
- フォントも自由に変更できる
- 見た目きれい
- 透過もできる
- インストールしたら導入終了
- 細かいカスタマイズがしやすい

## ConEmuのデメリット

- シェルごとの設定をする場所がない
- キーバインドがひどい

## インストール
上記のデメリットを消すために、便利な設定がされているCmderというパッケージをインストールします。
Cmderについては[こちら](http://qiita.com/tanakh/items/a1b4705fb58ef3c89800)の記事を参考にしてください。

# Vim
## Kaoriya版をダウンロード
[こちら](http://www.kaoriya.net/software/vim/)からダウンロード。

## dotfilesをclone
[こちら](https://github.com/moonoverwalker/dotfiles)のようにGithubにdotfilesをアップロードしてあるのでそれをクローンして使う。
dotfilesをgithubで管理する方法については[こちら](http://qiita.com/himinato/items/7f5461814e8ed8916870)とかを参考にするとよろしいかと。

dotfilesの中に.vimrcなども入れてあります。

## NeoBundleの導入
[こちら](http://qiita.com/poad1010/items/0434466cec41193b1136)を参考にNeoBundleを導入。

```
mkdir -p ~/.vim/bundle
git clone https://github.com/Shougo/neobundle.vim ~/.vim/bundle/neobundle.vim
```

でクローンしてきて、kaoriya版vimのディレクトリ内からvimprocをコピー。
Vimを立ち上げるとdotfilesに記入済みのbundleが自動的にインストールが開始される。

# Rapid Environment Editor
Windowsの環境変数の設定エディターが貧弱すぎるんですが、これ入れるとスーパー便利なので入れます。

## インストール
[こちら](http://www.rapidee.com/en/about)からダウンロードを選択してダウンロード。

終わり。

# まとめ
Windowsでも開発環境を整えると、割とまともな環境になるのでちゃんとセットアップしましょう。

# 4/7　追記
## Ctrl2Cap
普段はMac使いなので、Ctrlキーの位置をどうにかしたいと思いCtrl2Capをインストールしました。

### インストール方法
[こちら](http://pc-karuma.net/windows8-key-ctrl-cap/)を参考にインストールしてください。

# （4/15追記）メモ追記
http://tanakh.jp/posts/2013-05-23-windows-setup.html
【サービス終了】10項目まで無料。初心者向けサーバ死活監視サービス「AlertMe」を使ってみた

#注意
2016-08-31でサービスが終了します。
現在、新規登録は受け付けておりません。移転しましょう。

#あらまし
自社WebサーバをVPSからwordpressホスティングに変更したので、以前まで使っていたモニタリングツールのmuninなどが使えんようになった。
そも、今回の目的がサーバ管理をLinuxのスキルが無い人に移譲するためのものなので、簡単に使えるような死活監視サービスがあれば、と探していた。

で、白羽の矢が立ったのは、GMOのAlertMe。
http://www.securestar.jp/alertme/

#特長（フリープラン）
- 監視可能な数は10個まで。 → 有料は20個まで。
- ping, 各種サービス（http,ftp,smtp,pop,dns）などの死活監視ができる。

##pros（よい点）
- 「おすすめ監視設定」が非常に良い。ping監視、URLレスポンス監視、SSL証明書期限チェックで運用するならコレだけ弄ればOK。後から詳細設定の編集も可能。おすすめ設定(ping)だと、「指定への接続が、１０分間隔の確認で２回応答が無ければ警告メールを送信する」になる。
- URL監視（レスポンスタイム）が良い。ロードが5秒以上掛かったらアラート、などという設定が可能。
- DNS正引き逆引きチェック、SSL証明書期限チェックも無料の範囲で可能。試してないけど。
- 監視間隔が5分-1時間まで。十分。
- 通知メールアドレスを複数登録でき、別に割り振ることが可能。有料プランじゃないと通知メール文面やタイトルを編集することができない為、メールアドレスでエラー箇所を別ける運用が良いかも。
- ここ２年の監視統計を出力できる。円グラフで出してくれるのは良い。

##cons（悪い点）
- コントロールパネルのサーバが重い。ホントなんとかして欲しい。
- 登録が微妙に手間。管理者アカウントと、実際に運用する利用者アカウントの２つが必要になる。
- 監視統計をcsvなどで吐き出せない。多分プロプランでも無理。これは割と痛い人も多い気がする。
- ftp,pop3,smtpなどの監視はプロプランじゃないと監視port番号を変更できないので実質使えない。imapの監視もプロプランから。まあこの辺は仕方なし。
- サーバが重い。

#設定画面のSS
大体サービス概要が分かるだろうか。
![Screen Shot 2015-04-07 at 14.12.22.png](https://qiita-image-store.s3.amazonaws.com/0/23318/4d59f98d-96a6-bd50-2e5b-b8c0478eff34.png)


#総評
それほど機能を必要としない・管理中のサーバ数とサービス数が少ないのであれば良いかと思う。

運用担当が常駐しない客先への導入や、ネットショップと自社Webサイトだけの監視、などであれば、非常に使いやすいサービス。
（特にネットショップなどであれば、SSL証明書監視は有りがたいのでは）
サーバ複数台構成のWebアプリなどの死活監視には向かない。そも、ビジネスの規模がその程度であれば、zabbix, hinemos, nagios辺りを組むべき。

……というわけで、**画面読込に20秒掛かるような管理画面**にも耐えれるのであればオススメ。
（こんだけ宣伝したんだからGMOなんかくれーとか思ったけど色々と諦めたオチ）
ScalaのString Interpolation内で$を出力する

# $をString Interpolation内でうまく出力したい
例

```scala
val money = 7777
println(s"you have $$money")
```
出力

```
you have $money
```
$moneyがそのまま出力されてしまっている。
## 解決策
\$を2つ書くことで\$として出力される。

```scala
val money = 7777
println(s"you have $$$money")
```
出力

```
you have $7777
```

きちんと出力できた。