OmniAICreator/Qiita-1.07M huggingface dataset:
iOSアプリでCrashlyticsにカスタムログを送信する方法

# なぜやるか
GoogleAnalyticsのイベントで送ってもいいのですが、バグトラッカーを一つにまとめておいた方が
何かと便利なためCrashlyticsに統一するようにしたメモです。


# 実装

```swift:swift
import Crashlytics

// ここのuserInfoは無視される
let error = NSError(domain: "bundleIDとかユニークなモノにした方がいいみたい", code: "Intでエラーの種類によって分けるといいみたい", userInfo: nil)
// 細かい情報が欲しい場合はwithAdditionalUserInfoに入れる。
// 要らない場合はCrashlytics.sharedInstance().recordError(error)でよい
let userInfo = ["hogehoge": "hugahuga"]
Crashlytics.sharedInstance().recordError(error, withAdditionalUserInfo: userInfo)
```

```objc:Objective-C
#import <Crashlytics/Crashlytics.h>


NSError *error = [NSError errorWithDomain:@"bundleIDとかユニークなモノにした方がいいみたい" code:1 userInfo:nil];
NSDictionary *userInfo = @{@"hogehoge": @"hugahuga", @"test": @"hogeghoge"};
[CrashlyticsKit recordError:error withAdditionalUserInfo:userInfo];
```


公式Documentはこちら
https://docs.fabric.io/ios/crashlytics/logged-errors.html

# ログ一覧画面
以下の様な形で```NON_FATALS```として出てきます
<img width="1059" alt="スクリーンショット 2016-06-23 13.05.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/30928/541a463f-efb1-3631-9863-17184b298d40.png">
# ログ詳細画面
詳細画面に入るとこんな感じ。View all sessionsを押すと```withAdditionalUserInfo```で送った情報も確認出来ます
<img width="1016" alt="スクリーンショット 2016-06-23 13.05.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/30928/1b18ec47-16d9-c2a5-f01a-f18c46b39f73.png">
# ログセッション画面
userInfo配列はなんでもいいみたいで、全て表示されてました。
<img width="994" alt="スクリーンショット 2016-06-23 13.05.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/30928/a7edf4c4-27b5-3b77-69e0-ee95155c449d.png">


# こちらも合わせてどうぞ
[1行追記するだけでCrashlyticsで会員情報からクラッシュログを探せるたった1つの方法](http://qiita.com/yo1106/items/75f63038f7af745e38d7)


ちなみにAndroidはカスタムログじゃなくて、追加情報を送るみたい
[[Android] Crashlyticsでクラッシュレポートに情報を追加する](http://qiita.com/hymmr/items/87807a8d79e3db49d00b)
JSONを自力でパースする

.NETでJSONをパースするためにはライブラリを入れなくてはいけない。
なので、自分でパース処理を書いてみました。
350行程度で実現。

要するに辞書の辞書が返ってくればいい、というシンプルなものです。

#ソース
https://github.com/0xfffffff7/JSONLight/blob/master/JSONLight.cs

#使い方

    JSONLight json = new JSONLight(jsontext);
    Dictionary<string, object> dict = json.Parse();
    
    // JSONに戻す.
    string jsonSerialize = json.Serialize();

#返却される値
辞書の辞書です。以下入れ子。

    Dictionary< "", Dictionary<string,object> >
【イベントレポート】API Meetup Tokyo #14開催で感じた事

API Meetup運営チームとして[API Meetup Tokyo #14(2016/06/17)](http://eventdots.jp/event/589663)を主催しました。

公開可能な資料などはイベントレポートページに掲載していますので、ご参照下さい。

イベントレポート
http://eventdots.jp/event/589663

企業内スタートアップに見る、企業連携で生み出すリーンスタートアップの裏側
http://www.slideshare.net/apijp/ss-63231968

minikura API がもたらした“予想外”な価値・課題
http://www.slideshare.net/minikura/minikura-api

東京開催も第１４回目となる今回。ベンチャーキャピタル及びビジネスクリエーション事業のWiL、リーンスタートアップによるサービス開発を企業内で実践する伊藤忠インタラクティブ、長い歴史を持う倉庫事業にITを導入し、アセットのAPI化事業に挑戦する寺田倉庫という視点の違った三名の方に、オープンイノベーションとAPIをテーマにお話＆ディスカッション頂きました。

日本でもここ最近、オープンイノベーションという名前が[急速に流行](https://www.google.co.jp/trends/explore#q=オープンイノベーション&geo=JP&cmpt=q&tz=Etc%2FGMT-9)していますよね。

各ステークホルダーのオープンイノベーションに対するモチベーションとは何なのでしょうか。


**大企業**
・研究開発の効率化・スピード化
・イントレプレナー（企業内起業家）の育成
・新しいテクノロジーへのアクセス

**ベンチャー**
・優秀な人材の確保
・グローバル規模のベンチャー構築
・世界標準のスピードでの製品・サービス開発

という指摘がありました。特に、日本の場合は優秀な人材が大企業の中に眠っている事が多いという。

スタートアップはとてつもないスピードの中で事業創造活動を行っており、ビジネスプロデューサーは自らPL責任を持ち、事業の成功に向けて自らのビジネスのネタの実現性を見極め、事業拡大を実行する。
また、大企業におけるイノベーション推進組織はゴールに対して、自社の強み弱みを鑑みて達成に向け適切な手段を選択することであるという。ビジネスプロデューサーにおいて、特に「この全体を見て把握しバランスを調整しながらPL責任を持つ、この振り子を常に振幅しながら、ビジネスの作り出していくという、とても体力の必要なワークロードであるということを再認識しました。

特に、何かに特化して役割分担、細分化しやすい企業内風土において、ビジネスプロデュースをイノベーション領域で実践する大切さはとても重要になるのかもしれません。

伊藤忠インタラクティブではリーンスタートアップを実践する事で様々なWebサービス開発を進めており、これまでの受託開発事業から舵を切って挑戦している印象があった。さらに、寺田倉庫のセッションでは、予想外の発見という部分は印象的であった。事業、現場、会社、人などによって事情は様々でAPI化、企業連携におけるベストプラクティスはなく、いかに色々なトライを自由かつ柔軟に進められる環境を構築するかがとても重要であると感じられました。

つまり、ビジネス創造するという事がスピーディーに流れていく中で、試行錯誤、失敗体験などのリーンスタートアップによりビジネス創出において、API化されたサービスの組み合わせによりオープンイノベーションを実行というのは、とても理にかなっていると確認が出来ました。

テクノロジーとビジネスの交差点にAPIは成り得るのだと思います。

![スライド11.jpg](https://qiita-image-store.s3.amazonaws.com/0/62616/eab67129-b96b-7979-09ad-0dec948a715a.jpeg)
利用中のGoogle Chromeで使われているV8のバージョンを手軽に調べる方法


[chrome://version](chrome://version) のバージョン情報の
`JavaScript` のセクションに記載されている。

ちなみに、手元の環境のChrome/Chrome Canaryはそれぞれ以下のバージョンが使われていた。

### Google Chrome

```
Google Chrome	51.0.2704.103 (Official Build) （64 ビット）
JavaScript	V8 5.1.281.65
```

### Google Chrome Canary

```
Google Chrome	53.0.2774.3 (Official Build) canary （64 ビット）
JavaScript	V8 5.3.267
```
Docker for MacでCannot connect to the Docker daemon. Is the docker daemon running on this host?

既にdocker-machineなどを使っているMacにDocker for Macをインストールして、`docker ps`を実行したとき、「Cannot connect to the Docker daemon. Is the docker daemon running on this host?」というエラーが出たら、環境変数`DOCKER_HOST`を削除するとエラーが起きなくなります。

```bash
# 環境変数にDOCKER_HOSTがあるか確認
env | grep DOCKER_HOST
```

おそらく、docker-machineを使っている場合、ご自身でbashrcなどに`DOCKER_HOST`を定義している場合があると思います。bashrcなどを書き換えて、DOCKER_HOSTを取り除くと、エラーが起きなくなります。
sudo bundle execを実行可能にする

## 概要
Chef実行時など、bundleコマンドをsudoで実行したい場合の方法。

bundleコマンド(rbenv)は、ユーザー環境別にインストールされる。
そのため、sudoで実行すると、rootの環境変数を読みに行き、
`sudo: bundle: command not found`となる。
そこで、rbenv-sudoという方法で実行するために下記をインストールする。

## rbenv-sudoのインストール
[Github: rbenv-sudo](https://github.com/dcarley/rbenv-sudo)

```
$ git clone https://github.com/dcarley/rbenv-sudo.git ~/.rbenv/plugins/rbenv-sudo
```

これで、下記のコマンドでsudoでbundleコマンドの実行が可能になる。

```
$ rbenv sudo bundle exec [command]
```

visudoを編集する方法もあるけど、こっちのほうが楽。

以上。

[参考]
http://qiita.com/snaka/items/1fbc655a3fc931dd2fff
https://blog.dakatsuka.jp/2015/02/19/rbenv-sudo.html
Androidの4系端末でwebview内の文字が寄る話

## webviewで表示したHTMLの文字が左端に寄るバグ

開発中にテスターさんから、「WebViewの文字が左に寄るんですが・・・」と言われる。
みると確かに画像やレイアウトの配置に問題はないのに、文字だけがきっかり途中から改行されて左に寄っている。（写真は持ってこれないので想像してください。）
発生していたのはAndroid4.2の端末。
他の機種でためしたところ、Nexus5などOSが新しいものでは起こらない。
webviewでOSバージョンによる差が出るとなると、webviewのベースの違いだなと思うはず。

## 4.3まではwebkitベース、4.4以上はchromiumベース

http://k-tai.watch.impress.co.jp/docs/column/keyword/685512.html
こちらにも書かれている通り、webviewのベースがOSのバージョンによって違うことがわかる。
つまりバグが発生しているのはwebkitベースのもの。

## 標準ブラウザとchromeで検証

昔のAndroid端末には入っている標準ブラウザ（地球儀アイコン）はwebkitベース、最近だとこれはなくなってChromeが入ってるはず。
それぞれのブラウザで表示したら、標準ブラウザは左に寄る、Chromeなら正常に表示されるのでは？
と思いそれぞれ見たところビンゴ。
他にもサイトなどみたところ、標準ブラウザのデフォルト設定であるページの自動調整が問題と発覚。
http://cityjumperweb.com/2014/03/06/android-browzers/

こちらに記載のとおりに自動調整を外すとChromeと同じように表示された。

## これをwebviewに設定する

標準ブラウザ内でも設定できているし、なんとかwebviewの設定でもできるはず、と思いdeveloperを調べる。
いろんなサイトやstackoverflow見るのもいいけど、ロシアの天才も言ってるしやっぱソースは正しいところを見るべきだよね。
http://qiita.com/jacksuzuki/items/b2fa6b44962e73a53d08

webviewの設定なので、javascript有効にするとかと同じだなーと予想してそのあたりを探す。
レイアウトや文字サイズ関連だよなあと思って見つけたのが次のメソッド。
https://developer.android.com/reference/android/webkit/WebSettings.html#setLayoutAlgorithm(android.webkit.WebSettings.LayoutAlgorithm)

簡単には、「基本的なwebviewのレイアウトを設定している」感じらしい。
実際にWebSettings.LayoutAlgorithmってどんなのかさらに下ってみると、デフォルトに設定してある「NARROW_COLUMNS」という値はすでに非推奨かつKitKat（4.4）より前のものでしか使えないとある。
あやしい！！
https://developer.android.com/reference/android/webkit/WebSettings.LayoutAlgorithm.html

上記のページにもあるように、いろんな機種に対応するには「NORMAL」設定がいいよ、とのことなので実際にNORMALを設定したところ、見事解消された。

```java

WebView webview = new WebView(this);
		webview.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
```

がんばって解消したものの、サイト側で治しましょうとなってこのコードは使われなくなってしまった（´・ω・｀）
頑張ろう。
Linuxサーバに一時的な負荷をかけたい、という話

# この記事は？
- 開発をしていると、「サーバに負荷がかかっている状態においてどのような挙動を示すか？」という確認をしたいことが稀にある。
- 細かいことはいいから手間をかけず、さくっと負荷をかけたい。
- そこでPerlですよ！

# 前提条件
この記事においてはターゲットをLinuxサーバとしています。
Windowsにおける負荷はcygwin等を用意してもらうか、別の方法を検討してください。

# 負荷のかけ方
## CPU
Perlで無限ループを複数発生させます。
4Coreの環境ですべてのCPU使用率を100%にしたい、という場合はこんな感じ。

```bash
 $ for i in {1..4}
 > do
 > perl -e 'while(1){}' &
 > done
```

もちろん、1行でもOK。

```bash
$ for i in {1..4}; do perl -e 'while(1){}' & done
```

停止させるときはPIDを確認した上でkillコマンドで。
topやpsでgrepしてもいいけど、次のがワンラインでかっこいい。

```bash
$ kill -9 `ps -ef|perl -lane '/perl -e while\(1\)\{\}/ and print $F[1]'`
```

## メモリ
とにかく配列処理をやらせてメモリを使い潰そう、というコンセプト。

```bash
$ perl -e '$c[$_]="a"x$_ for 1..10000'
```

もっとメモリを使わせたい、ということであれば10000よりも大きい値にしてあげてください。


* * *
以上
SeleniumGrid環境を作ってみるテスト（という名の備忘録）


dockerを使うと環境自体は簡単にできる訳です。

## Hubの起動
```
$ docker run -d -P --name selenium-hub selenium/hub
```

## Nodeの起動
ChromeとFirefoxをそれぞれ2ノード立ち上げます。

```
$ docker run -d -P --link selenium-hub:hub selenium/node-chrome-debug
$ docker run -d -P --link selenium-hub:hub selenium/node-chrome-debug
$ docker run -d -P --link selenium-hub:hub selenium/node-firefox-debug
$ docker run -d -P --link selenium-hub:hub selenium/node-firefox-debug
```

## Hubの稼働確認
Kitematicで見てみるとこんな感じになってるはず。

![スクリーンショット 2016-06-23 11.46.19.png](https://qiita-image-store.s3.amazonaws.com/0/105644/4f00e444-2c6f-2fe9-cfce-0ea4bec872cb.png "スクリーンショット 2016-06-23 11.46.19.png")

HomeタブのIP&PORTに記載されているURLにアクセスしてみると

![スクリーンショット 2016-06-23 11.50.59.png](https://qiita-image-store.s3.amazonaws.com/0/105644/d7dfbcfb-c308-8a62-4f34-2b21eba7374a.png "スクリーンショット 2016-06-23 11.50.59.png")

となるので、consoleというリンクをクリック

![スクリーンショット 2016-06-23 11.52.59.png](https://qiita-image-store.s3.amazonaws.com/0/105644/75c87fe8-59e5-4e6e-ebcf-fc7113f5c662.png "スクリーンショット 2016-06-23 11.52.59.png")

ちゃんと計4つのノードが接続されております。
## Nodeの稼働確認
各ノードの状況を確認するには、Kitematicを開いて、確認したいノードを選択し、HomeタブのIP&PORTを見てみます。

![スクリーンショット 2016-06-23 11.58.05.png](https://qiita-image-store.s3.amazonaws.com/0/105644/247685c1-cbf5-39c3-72b8-157deb841729.png "スクリーンショット 2016-06-23 11.58.05.png")

Finderを立ち上げて、Command(⌘)+Kを押します。

![スクリーンショット 2016-06-23 12.00.57.png](https://qiita-image-store.s3.amazonaws.com/0/105644/cc3c5054-eda5-d95c-c3ce-ee25f75ed414.png "スクリーンショット 2016-06-23 12.00.57.png")


サーバアドレスのとこに、URLを転記して、接続ボタンを押します。

![スクリーンショット 2016-06-23 12.02.35.png](https://qiita-image-store.s3.amazonaws.com/0/105644/0d49a4f6-ba71-c8fc-ae1b-b034ef3036f6.png "スクリーンショット 2016-06-23 12.02.35.png")

パスワードを要求されますので、「secret」と入れて、接続ボタンを押します。



![スクリーンショット 2016-06-23 12.06.12.png](https://qiita-image-store.s3.amazonaws.com/0/105644/ade3f166-7ffa-8af5-5151-28552979d268.png "スクリーンショット 2016-06-23 12.06.12.png")

これで、ノードが見れますので、テストスクリプトを流すと、この画面上にブラウザが開かれて動き出すことでしょう。
rollup.jsでレガシィjQueryコードを今すぐes6化しよう

長年フロントエンド開発をしましたが、昔 jQuery, Backbone, Handlebars などで開発したプロジェクトを今の時代に管理することは難しいことでした。es6とnpmで改善しようと思っていろいろ探してみて、[rollup.js](http://rollupjs.org/)と[buble](https://buble.surge.sh/)を発見しました。

rollup.jsはまさにjavascriptの未来であるimportを今の段階でサポートするライブラリで、bubleはbabelのようなライブラリです。webpackやbabelなどの複雑でいろんな機能を持ってるライブラリもありますが、rollup.jsとbubleだけで十分使えました。そして、その変換結果の綺麗さは見事です。

rollup.jsの設定の為にgithubにboilerplateをアップしました。設定には５分もかかりませんし、コードを書く必要も一切ありません。ただ設置するだけです。

# 2018.07.12
rollupの設定を最新にアップデートしました。IE11だけのサポートにして、postcss(css grid)を導入しました。scriptもie11用とそれ以外を分離しました。

設定に問題が2つありました。
babel7がrollup-plugin-babelと合わなくて、babel6に設定しました。これは後で修正します。
VS Codeのprettierが.babelrcを勝手に壊すバグがあり、[リンク](https://github.com/prettier/prettier/issues/4636)の情報で修正しました。

```
git clone https://github.com/fri13th/rollup-jquery-boilerplate your-project
cd your-project
yarn
```

startコマンドでsrc/のjavascriptとcssファイルがdist/に変換されます。browsersyncで変換された結果がする確認でします。

```
yarn start
```

buildでminifiedされたファイルが生成されます。

```
yarn build
```

 
これで環境設定は完了です。



実際の変換はこのような感じです。

```js:src/js/main.js
import $ from 'jquery';
import {view} from 'template';
import {cube} from 'utils';

let array = [1, 2, 3];

console.log(cube(3));
$(() => console.log(view('World', array)));
```

```js:src/js/template.js
export function view(who, array) {
  return `
Hello, ${who}!
${array.map(no => `${no}`).join('')}
`;
}
```

```js:src/js/utils.js
export function square ( x ) {
  return x * x;
}

// This function gets included
export function cube ( x ) {
  return x * x * x;
}
```

buildコマンドで無駄のない綺麗なコードに変換されます。

```js:dist/js/main.iife.js
(function () {
  'use strict';

  function view(who, array) {
    return '\nHello, ' + who + '!\n' + array.map(function (no) {
      return '' + no;
    }).join('') + '\n';
  }

  // This function gets included
  function cube(x) {
    return x * x * x;
  }

  var array = [1, 2, 3];

  console.log(cube(3));
  $(function () {
    return console.log(view('World', array));
  });

}());
//# sourceMappingURL=main.iife.js.map
```


```js:dist/js/main.es.js
function view(who, array) {
  return `
Hello, ${who}!
${array.map(no => `${no}`).join('')}
`;
}

// This function gets included
function cube ( x ) {
  return x * x * x;
}

let array = [1, 2, 3];

console.log(cube(3));
$(() => console.log(view('World', array)));
//# sourceMappingURL=main.es.js.map
```

es5を直接書くより何倍も効率よく作業が出来ます。機能がファイル単位で分散されて見やすくて管理しやすいし、templateもサポートするのでHandlebarsなどの必要性も低くなります。es6の標準コードなので、将来的に仕様変更の可能性もありません。

変換作業もまず既存のes5コードをそのままsrc/main.jsにコピーして、それからちょっとずつリファクタリングすればいいし、結果コードがIE8などでもそのまま使えるので、今すぐes6開発が可能になります。

今回作業して感じたのはJavascriptの未来は思ったより近いとこまで来てるってことです。今すぐes6開発に挑戦しましょう！
CentOS7にpostgresql9.6をセットアップ

#参考
[CentOSにPostgreSQL9.5をインストールおよびテスト](http://qiita.com/SOJO/items/a1d97887d24c3e44596f)

#Vagrantの場合

```lang:ポートフォワード
config.vm.network "forwarded_port", guest: 5432, host: 50432, id:"postgres"
```
```lang:スクリプト
config.vm.provision "shell", inline: <<-SHELL

sudo yum -y install yum-plugin-priorities

#日本語化
 sudo yum -y install ImageMagick ImageMagick-devel ipa-pgothic-fonts ibus-kkc vlgothic-*
 sudo localectl set-locale LANG=ja_JP.UTF-8
 sudo source /etc/locale.conf 
 sudo timedatectl set-timezone Asia/Tokyo

#gitのインストール
yum -y install git

#firewalldでHTTPを許可
firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --reload

#postgresql
wget https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-7-x86_64/pgdg-centos96-9.6-1.noarch.rpm
sudo rpm -ivh pgdg-centos96-9.6-1.noarch.rpm

sudo yum update
sudo yum -y install postgresql96*

sudo /usr/pgsql-9.6/bin/postgresql96-setup initdb

sudo systemctl start postgresql-9.6
sudo systemctl enable postgresql-9.6

sudo cp /vagrants/p* /var/lib/pgsql/9.6/data/

sudo systemctl restart postgresql-9.6

sudo firewall-cmd --permanent --zone=public --add-service=postgresql
sudo systemctl restart firewalld.service

SHELL
```

#最新のリポジトリをインストール
```lang:
https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-7-x86_64/pgdg-centos96-9.6-1.noarch.rpm

sudo rpm -ivh pgdg-centos96-9.6-1.noarch.rpm
```

```lang:念のためのupdate
sudo yum update
```

#postgresqlをインストール

`sudo yum -y install postgresql96*`

初期化
`/usr/pgsql-9.6/bin/postgresql96-setup initdb`

起動
`systemctl start postgresql-9.6`

サービスに登録
`systemctl enable postgresql-9.6`


* * *
#設定ファイルを編集

`vi /var/lib/pgsql/9.6/data/postgresql.conf`

```lang:postgresql.conf
59行目
# listen_addresses = 'localhost' 
↓
listen_addresses = '*' 

419行目
log_line_prefix = '< %m >'
↓
log_line_prefix = '<%t %u %d>'
```

`vi /var/lib/pgsql/9.6/data/pg_hba.conf`

```lang:postgresql.conf
# "local" is for Unix domain socket connections only
local   all         all                               trust
# IPv4 local connections:
host    all         all         127.0.0.1/32          trust
# IPv6 local connections:
host    all         all         ::1/128               trust
```

##変更後の再起動
`systemctl restart postgresql-9.6`




***
#スーパユーザのパスワード変更
```lang:
su - postgres
psql
postgres=# \password postgres
新しいパスワード: 
もう一度入力してください：
postgres=# \q

```

`firewall-cmd --permanent --zone=public --add-service=postgresql`

`systemctl restart firewalld.service`

***
#sqlファイルの実行
psql -f ./sql_file.sql -U user_name -D db_name (-h ホスト名)

#コマンド

```lang:テーブル一覧取得
select relname as TABLE_NAME from pg_stat_user_tables；
```

```lang:テーブル削除
DROP TABLE tablename;
```
git diff すると末尾に ^M が表示される

Windows環境の方が良く出くわすと思われます。

## 現象
`git diff`で変更のあった行の末尾に `^M`がついていて見づらい/邪魔/恥ずかしい。
![before.png](https://qiita-image-store.s3.amazonaws.com/0/111100/d01957ec-cece-7f8e-1e7b-a6c2c0706838.png)

## 対処法
行末のキャリッジリターンを許容してあげる。

```bash
git config --global core.whitespace cr-at-eol
```

設定ファイルいじる派のあなたは

```text:.gitconfig
[core]
  whitespace = cr-at-eol
```

## 結果
![after.png](https://qiita-image-store.s3.amazonaws.com/0/111100/c62dae1a-1efa-36da-22e4-c440cc4b7e27.png)
【Jupyter notebook】Jupyter notebook 稼働マシン以外からnotebookを参照する

# 1. はじめに
jupyter notebookにメモとったものを
他のマシンからも見たくなるじゃないですか。

というより、デモするのに楽な構成を取りたくて
調べてみました。

※2016.6.23追記 : パスワード設定部分を追記しました。
 
# 2. 実行環境

|items|version|note|
|---|---|---|
|CentOS|7.2|jupyter notebook稼働マシン|
|python|2.7.5|たぶんOS default|

# 3. 手順

1. jupyterのインストール
    
    ```
    pip install jupyter
    ```
  
1. jupyter起動用設定ファイルの生成
    
    ```
    jupyter notebook --generate-config
    ```
    
1. jupyter_notebook_config.pyの修正

    ```text:編集箇所
    # vi ~/.jupyter/jupyter_notebook_config.py
    
    (中略)
    c.NotebookApp.ip = '*'
    c.NotebookApp.port = 9999
    c.NotebookApp.notebook_dir = '/home/orefolder'
    c.NotebookApp.password = 'xxxxx'
    ```

    なんでviなんだよ！という方、別のエディタでも問題ないです。

    (追記)
    コメントのご指摘の通り、パスワードの箇所を編集箇所に加えました。
    やりかたは**[こちら](http://qiita.com/y__sama/items/5fb14f2dc7d294fa9980)**を参考にされるとよいと思います。
    ちなみに、config fileの書き方は以下が参考になります。
    **[・Config file and command line option](http://jupyter-notebook.readthedocs.io/en/latest/config.html)**

1. 起動

    ```
    jupyter notebook &
    ```

# 4. 解説
上記2.実行後、jupyter_notebook_config.pyが~/.jupyter/配下に生成されます。  
コメントアウトされている個々のデフォルト設定値のうち、3.にある３つの項目を変更します。  

    + c.NotebookApp.ip           // defaultはlocalhostのみ
    + c.NotebookApp.port         // defaultは8888 
    + c.NotebookApp.notebook_dir // 作業ディレクトリ
    + c.NotebookApp.password     // アクセス時の認証パスワード

他の端末のブラウザから http://[jupyter稼働マシンのIP]:9999　へアクセスして
画面表示されれば成功です。

# 5. あとがき
本記事が参考にしたのは以下です。
[・Jupyter Notebook(IPython)サーバの起動方法](http://www.task-notes.com/entry/20160204/1454513778)

jupyter自体の構築は以下の記事を参考にされるとよいと思います。
[・Ansible run on Jupyter notebook : CentOS6で`実行可能な手順書`の環境を構築する（ playbookやVagrantfileあり）](http://qiita.com/tbuchi888/items/4f4ed9192e2027759795)

jupyter用のconfigファイルの他はあまり探求していません。
あと、App.ipを*に設定するアクセス制御上の弊害もあまり探求していません。

jupyter notebook自体は、他でも語られているように 
手順書orientedな世界との親和性が高く、
特に半自動化(構築・運用上の作業手順の一部分だけやむなく手動が残るケース)に
効果を発揮しそうなオペレーションツールではなかろうか、と考えています。
Firebase StorageにCORSの設定をする

Google IO 2016でFirebaseの機能が大幅に強化されることが発表され、Amazon S3のようなクラウドストレージのFirebase Storageが導入されました。これによりFirebaseアプリケーションでより簡単にファイルのアップロード・ダウンロードを実装できるようになりました。
以前からFirebaseには静的Webサイトをホスティングする機能があり、これを使ってFirebaseデータベースと連携するWebアプリを簡単に作成できたのですが、**Firebase Storageの導入によって画像や動画、音声ファイルなど巨大なデータをアップロードしたりするアプリも作れるようになった**のです。素晴らしい。

ところが、Firebaseのホスティング機能でホストされるWebページとFirebase Storageでホストされるファイルはドメインが異なります。そしてFirebase StorageはCORS設定が有効になっていません。つまり、Firebaseホスティング機能でホストされるWebページ上でFirebase Storageから取得した画像をCanvasに描画したりJavaScriptで読み書きしたりすることができません。なのでCORSを有効にしたいのですが、管理コンソール上でもそれらしい設定は見当たりませんでした。

実のところFirebase Storageは以前から存在しているクラウドストレージサービスであるGoogle Cloud Storageそのものであり、Google Cloud SDKを使ってGoogle Cloud StorageのCORS設定を行えます。

1. Google Cloud SDKをインストールする
2. Google Cloud SDKの初期設定をする
3. CORS設定を記述したJSONファイルを作成する
4. CORS設定ファイルをデプロイする

順番に見ていきます。

## Google Cloud SDKをインストールする

[公式サイト](https://cloud.google.com/sdk/)からインストーラーをダウンロードして実行します。設定はデフォルトのままNext、Next…でも大丈夫です。

## Google Cloud SDKの初期設定をする

インストーラー終了時に自動で初期設定が始まります。インストール時に初期設定を行わなかった場合は、ターミナルで下記コマンドを実行します。

```
gcloud init
```

## CORS設定を記述したJSONファイルを作成する

任意のディレクトリに、以下のようなファイルを作成します。ファイル名は何でも良いです。ここでは説明のために`cors.json`とします。

```json:cors.json
[{
  "origin": ["https://xxxx.firebaseapp.com", "http://localhost:3000"],
  "responseHeader": ["*"],
  "method": ["GET"],
  "maxAgeSeconds": 86400
}]
```

※`http://localhost:3000`を入れているのは私が開発時に必要だったからです。個々の開発環境に応じて、必要に応じて書き換えてください。
※`https://xxxx.firebaseapp.com`の部分は実際のFirebase HostingのURLに書き換えてください。URLはFirebase Hostingの管理コンソールで確認できます。

## CORS設定ファイルをデプロイする

先ほど作成した`cors.json`のディレクトリでターミナルを開き、下記コマンドを実行します。
`gs://xxxx.appspot.com`の部分は実際のFirebase StorageのURLに書き換えてください。URLはFirebase Storageの管理コンソールで確認できます。

```
gsutil cors set cors.json gs://xxxx.appspot.com 
```

設定が正しく行えたかどうかは下記コマンドで確認できます。

```
gsutil cors get gs://xxxx.appspot.com 
```
これで、Firebase Storageにアップロードしたファイルを
pythonでcsvファイルに書き込みするところで、ちょっと間違えた結果納期に間に合わなかった話


## 環境
MAC 
python 2.7系

## やりたいこと

ローカルに存在するcsvファイルに、新しい行を書き込んであげたかった。
なぜかこれが上手くいかなかったので、まとめてみる。

## コード

```
import csv

c = csv.writer(open(path, 'w'))
lst = ['a','b','c','d']
lst.append('\n')
c.writerow(lst)

```

これで日本語ソースのサイトを見てみると上手く動くらしい。自分が試すと上手くいく時といかない時があったが、ほとんどの場合でアウト！

## 解決策

```
import csv

c = csv.writer(open(path, 'a'))
lst = ['a','b','c','d']
lst.append('\n')
c.writerow(lst)

```

open() のところのmode を``` 'w' -> 'a' ```に直してあげた。
既存のファイルに書き込みたかっただけだから'a'で問題ないらしい。


## 日本語ソースを探せなかったググり力不足

[ここのサイト](http://d.hatena.ne.jp/kakurasan/20090309/p1)に詳しい記述があった。

>読み込み処理は一切行わずに書き込み処理のみを行うと、(そのままでは)ファイルの先頭からデータを上書きしていくが、書き込んだ長さが元のデータより短いと、書き込んだデータが終わったところより後ろは元のデータが残る。

なるほどぉ〜


## 結果
納期、間に合いませんでした。なんで間に合わなかったかというと、実行時間が長いから、スクリプト動かしたまま寝ちゃったんですね

朝起きたらcsvファイルが１行しか存在しなくて、絶叫してもう一回寝ました。
WordPressでカテゴリーや固定ページなどでBasic認証

#functions.phpにBasic認証を掛けるための関数を記述

```
//ここから
function basic_auth($auth_list,$realm="Restricted Area",$failed_text="認証できませんでした。"){ 
    if (isset($_SERVER['PHP_AUTH_USER']) and isset($auth_list[$_SERVER['PHP_AUTH_USER']])){
        if ($auth_list[$_SERVER['PHP_AUTH_USER']] == $_SERVER['PHP_AUTH_PW']){
            return $_SERVER['PHP_AUTH_USER'];
        }
    }
 
    header('WWW-Authenticate: Basic realm="'.$realm.'"');
    header('HTTP/1.0 401 Unauthorized');
    header('Content-type: text/html; charset='.mb_internal_encoding());
 
    die($failed_text);
}
//.ここまで
```


#header.phpの一番上で関数呼び出し

```
<?php
//Basic認証
if(!is_home()): 
if(is_tax('タクソノミーのスラッグ','タームのID、名前')): //Basic認証を掛けたいタクソノミー
if(is_category('カテゴリID')): //Basic認証を掛けたいカテゴリID
if(is_page('固定ページID')): //Basic認証を掛けたい固定ページID
if(get_post_type()=== '投稿タイプ名'): //Basic認証を掛けたい投稿タイプ名
//ID・パスワード配列
$userArray = array(
"basic" => "basic",
"test" => "test"
);
basic_auth($userArray); 
endif;
endif;
//.Basic認証
```
tensorflow 勉強会 #4


RNN Camp 7月予定

## Googleの機械学習プロダクトのアップデート

SyntaxNetくらいしかアップデートなかった
ニューラルネットを組み合わせることでいい感じにパーシング
アカデミックなモノと比べて劇的に素晴らしいモノではない

OSSで公開されてるのですぐ使えるよ

### 既存のGCPのMLサービス 製品動向

- GA
	- Vision API
	- Translate API
- Alpha
	- Speech API
	- Machine Learning

もうちょいしたらSyntaxNetに関わるサービス出る

### TPU

CPUでもGPUでもない新しいプロセッサ
このためにハードウェアエンジニアを大量採用してチップを作った

8bitってミスリーディングだよ
8bitはCPUじゃないよ

0から作った
Tensorflowで使う階数演算に特化
8bitの中で演算
これによってパラメータのサイズが4分の1とかになる
Shared Memoryに収まるように苦労してるけど、TPU使うと4分の1になるので楽になる。

最大の性能は電力消費。
Tensorflow使ってる人への恩恵は今のところ提示してない
AlphaGoとかには使ってる
提供されるようになると、コストメリットがある

来週

## Tensorflowで趣味の画像収集サーバーを作る 6月号

有山さん

機械学習初心者

好みの眼鏡っ娘画像を自動で収集したい
眼鏡っ娘という表記揺れ重要。
×メガネっ娘
○めがねっ娘

この話だけで20分いけるｗ

2クラス分類
眼鏡っ娘かそうでないか。

GPUが使えない→ミスだった（GPUをTensorflowが認識してなかった）
きちんとドライバインストールしましょう

http://www.kabuku.co.jp/developers/errors-with-tensorflow-on-gpu

同人誌を作ろう

Tensorflowはじめました→作った

執筆上の課題

CIFAR-10に還る
10クラス分類
ただで公開されてる。

チュートリアルがチュートリアルじゃなかったんで1から作った
cuda-convnet

色んなモノを加えると認識がちょっとずつ上がっていく
元の論文の数式はよく分からん

データフロープログラミング初めてだった

重みの可視化

認識精度は向上しなかったけど試したこと
バッチサイズ1でやってたので計算時間増加してしまった
なぜ増やさなかったのか？
処理を最初からやり直さないといけなかったり

→バッチサイズを64にしたら大幅に短縮した

バッチサイズ1の時は20％しか使われてなかったけど、64にしたらフルフル使うようになった

## 唐揚げロボ

唐揚げをつかむロボットの宣伝ｗ
アールティ ロボットの会社

Pepperのプロトタイプ開発とか

人工知能こんな感じで分かれる

- 身体知
- 形式知
	- 大体弱いAI

機械学習はどちらにも使える

ニューラルネットは食品と深い関係がある
30年くらい前
- 神経が実際に見たい！
- 巨大軸索を持つのは何か？
- イカ
- イカを飼った
- アンモニアを抜けばイカを飼えるようになった
- 世の中のいけすで飼ってるイカはこれのおかげ！！

食品を扱うロボットは今は調理の所まで。
弁当に詰めたりとかはおばちゃんがやってる。
柔らかいモノをつかむとか難しい。

油でツルツル滑るから唐揚げ扱うのは難しかったｗ

NEKONOTE

以下を基準に産業ロボットが作られている

- コンパクトに作る
- 人にぶつかっても痛くない

重力補償でほどよい力加減

データ用の唐揚げを毎週土曜日揚げ続けた

ROS使えるようになると仕事が来るよ

不正解データとして何を用意した？
人間にとって不正解のを入れ続けた

唐揚げを「つかむ」必要があったのか？
仕事でつかむロボットの開発をしているため。
食品ロボットの中では最後のフロンティア。
弁当に詰めるところをロボット化したいという需要がめっちゃある。

## TensorFlowで逆強化学習

ブレインパッド 太田さん

良いとは？

様々な「良い」

### 逆強化学習

エキスパートの行動を元に良さを考える。

カウンセリングはゴールがあるけど指標化するのが難しい

何かわからんけど、すごい人はこういう感じでやってるからいいんだろう、みたいな学習方法
良さから学習する強化学習の逆。

## TensorFlowでDQN

DQNの理論的な話

ビデオゲームを学習する

Deep Learningが出る以前からQ Learningと言うのがあった
ディープラーニングが出てそれ組み合わせたらすげーうまいこといった

実装しようとすると一番難しいのは、データをかき集めるところ
データ収集と学習をパラレルでやっていくのがいい。

July Tech Festa 2016で倒立振子の問題話すよ

## TensorFlowとGymを使ってDoubleDQN

ダブルドキュン
何がダブるか？

同じ構造のニューラルネットワークが二つ
1つは今どうなるかを予測するネットワーク
2つめは取るべき行動の評価するネットワーク
同じ構造である必要がある。

それぞれが近くなるようにする。
Retrofit2へ移行した時の参考

- [Migrate from Retrofit to Retrofit2 （Retrofit から Retrofit2 に移行する）](http://y-anz-m.blogspot.jp/2016/03/migrate-from-retrofit-to-retrofit2.html)
- [Retrofit 2 and Rx Java call adapter error handling](http://bytes.babbel.com/en/articles/2016-03-16-retrofit2-rxjava-error-handling.html)
Windows版Photoshop CC(2015.5)でCSSがコピーできない問題


![](https://blogs.adobe.com/creativestation/files/2016/06/PS2015_5-1280x720.png)
#Photosohp CC 2015.5アップデート
最近Photshopのアップデートある、2015.5が公開されました。

アップデートの内容については、[「使える」「喜ぶ」機能搭載。Photoshop CC バージョン2015.5 提供開始](https://blogs.adobe.com/creativestation/photo-pscc2015_5-update)を見ていただけるとわかります。

#CSSがコピーできない
レイヤースタイルやフォントサイズなどの情報をCSSに変換してコピーしてくれる機能がついていて、マークアップの時に重宝しています。

<img width="186" alt="" src="https://qiita-image-store.s3.amazonaws.com/0/62429/199594b8-1ce5-1940-6c3c-0e085082d347.png">
（英語版を使用しているので英語になってます）

しかし、この機能を2015.5にアップデートした瞬間に使えなくなってしまいました。 Javascriptが見つからないといわれるのです。

#解決方法

*2016/09/01追記*
*解決方法をコメントにて教えていただいたので記載しておきます！*

この解決方法についてサポートに問い合わせたところ、バグのようで1個前のバージョンを使用することをお勧めされました。
ちなみにMacでは発生していないようです。

この問題は開発チームに報告中であり、できるだけ早く修正するとの返事もいただきました。

[以前のバージョンのアプリケーションをインストールする](https://helpx.adobe.com/jp/creative-cloud/help/download-install-app.html#topic-3)

##2016/09/01
@noellabo さんのコメントより引用。

>本件について、原因と解決方法がわかりました。スクリプトのBOM付け忘れです。
C:\Program Files\Adobe\Adobe Photoshop CC 2015.5\Required\CopyCSSToClipboard.jsx
[「CSSをコピー」機能が使用できなくなりました -- Photoshopコミュニティフォーラム (Japan)](https://forums.adobe.com/thread/2175548)
dialogタグでモーダル表示をしたときの背景色を変更する

モーダルを実現する方法は色々ありますがdialogタグを使うと簡単です。（ただしchromeに限る）
ただ、デフォルトだと背景（オーバーレイ）の透明度が高すぎてイマイチ。
なので、CSSで背景色変えるのにはどうしたらいいのかなと。

```
dialog::backdrop {
  background: rgba(0, 0, 0, 0.5);
}
```

`::backdrop`という疑似CSSセレクタが使えました。
【HTML5】contenteditable属性

#contenteditableとは？
contenteditable属性は、HTMLのコンテンツをブラウザ上で編集することができるようになります。
IE5.5で追加された機能です。
HTML5でもサポートされることになり、Chrome 11, Firefox 3.0, Opera 10.6, Safari 3.2でもサポートされました。
#値は？
|値       |説明                           |
|:--------|:-----------------------------|
|inherit  |親の要素の属性を継承します。既定値  |
|true     |編集モードをオフにします          |
|false    |編集モードをオフにします          |

#使用例
###HTMLの場合
```html:index.html
<div contenteditable=true>
    この文章はブラウザで編集できます
</div>
```
###JSの場合
```js:test.js
document.getElementById('id').contentEditable = true;
```

#参考サイト一覧
[HTMLリファレンス](http://www.tohoho-web.com/html/attr/contenteditable.htm)
[ブラウザをテキストエディタっぽく使うサンプルを作ってみたら意外に単純にできますた](http://blog.56doc.net/Entry/508/)
[contentEditableをJavaScriptで変更する際に気をつける事](http://blog.justoneplanet.info/2010/08/21/contenteditableをjavascriptで変更する際に気をつける事/)
[[HTML5API] contentEditable 属性を使用したリッチテキストエディタの実現](https://blogs.msdn.microsoft.com/osamum/2014/02/13/html5api-contenteditable/)
[Internet Explorer 5.5 を使った 編集可能な Web ページの作成方法](https://msdn.microsoft.com/ja-jp/library/dd163916.aspx)
Pyenvを使用してPythonをインストールするときにインストールするライブラリ一覧

完全に個人的なメモですが…。
## 使用環境
Ubuntu16.04 LTS

## インストールしなきゃいけなかったライブラリ
今回インストールしたのはPython3.5.1です。Pyenvの使い方は[このへん](http://qiita.com/Kodaira_/items/feadfef9add468e3a85b)がわかりやすいです。
インストールしなきゃいけない、というかしなくても大丈夫なものもあるっぽいですがしないと警告が出てなんだか気持ち悪いので。

* libbz2-dev
* libssl-dev
* libreadline-dev
* libsqlite3-dev

## インストール方法
もはや解説不要な感じしかしませんが `sudo apt-get install <ライブラリ名>`でイケます。

完全に余談ですが、最近は`apt-get`ではなく`apt`でいけるみたいですね。（いつからかは知らない）

後輩に`apt-get remove`とかremoveなのにgetっておかしいって言われて確かにと思いました。
xdomain.jp : php+mysql対応無料レンタルサーバ(広告無し)

* [無料レンタルサーバーのまとめ 2016年度版](http://hostingstock.net/article/notes/free-web-hosting/)

## 公式ページ

* [Xdomain](https://www.xdomain.ne.jp/)

> [(※)3ヶ月間、ファイルマネージャのご利用、もしくはFTPでの接続が行われない場合は、広告が表示されます。](https://www.xdomain.ne.jp/server/)

## 会員登録の流れ

* メールアドレス登録
* メールに確認URL
* id,pass,名前,性別,住所,電話番号を入力
* 登録完了
* [管理パネル](https://www.xdomain.ne.jp/login/member.php)でログイン

## ログイン

* FTPアカウントのパスワード設定
* mysqlアカウント作成
    * phpmyadminの利用も可能になる。
* phpバージョン設定
    * 7.0.3 に切り替え
* php.ini
    * mbstring.internal_encoding = utf-8
    * mbstring.http_output = utf-8

## URL

| type | url |
|:--|:--|
| HTML | http://サーバーID.html.xdomain.jp
| PHP・MySQL | http://サーバーID.php.xdomain.jp
| WordPress | http://サーバーID.wp.xdomain.jp
Zybo > Chronicles blog 51 > AMPの使用 > 7. OCMによるCore同士の通信 > 割込みの使用 > SW_INT_ID定義 / GICのConnect

MicroZed Chronicles リスト http://adiuvoengineering.com/?page_id=285
@ Adam Taylor blog
https://forums.xilinx.com/t5/Xcell-Daily-Blog/Adam-Taylor-s-MicroZed-Chronicles-Part-51-Interrupts-and-AMP/ba-p/525489

Core0, Core1間でのOCM経由でのデータ受渡しに関してInterruptを使う。

> Each ARM Cortex-A9 processor core in the Zynq SoC has 16 software-generated interrupts. 

…
> For this example, we will use Core 0 to generate an interrupt that informs Core 1 that there has been an updated LED pattern received.

16のうちの１つを使用するため以下を定義し、Core0, Core1のソフトで共用する。

```
#define SW_INT_ID                   0
```

> The next thing we need to do within Core 1—the core receiving the interrupt—is to connect the software-generated interrupt to the GIC (generic interrupt controller) and then enable the interrupt.

> Connecting the interrupt is achieved by using the function XScuGIC_Connect. 


```c
Status = XScuGic_Connect(GicInstancePtr, SW_INT_ID,
         (Xil_ExceptionHandler)sgi_handler, (void *)GicInstancePtr);
if (Status != XST_SUCCESS) {
    print("error setting SGI");
    return XST_FAILURE;
}
XScuGic_Enable(GicInstancePtr, SW_INT_ID);
```
Zybo > Chronicles blog 50 > AMPの使用 > 7. OCMによるCore同士の通信 > 実装 > データ転送 > 1:Xil_IO使用 / 2:ポインタ使用

MicroZed Chronicles リスト http://adiuvoengineering.com/?page_id=285
@ Adam Taylor blog
https://forums.xilinx.com/t5/Xcell-Daily-Blog/Adam-Taylor-s-MicroZed-Chronicles-Part-50-AMP-and-the-Zynq-SoC-s/ba-p/521889

OCM経由でのCore0, Core1間の通信の実装例

> The demo for this will use CPU0 to communicate over the UART link to a laptop. We’ll send <font color=red>an 8-bit ASCII value</font> from the laptop to the Zynq Soc’s UART. Once received, this 8-bit value will be transferred into the selected OCM memory address, which is shared between the two processors. Each time its private timer expires, CPU1 will read this memory address and set its GPIO output pins accordingly. 

使用するメモリアドレスを選択する。そのためにOCMのキャッシュを切る

```
Xil_SetTlbAttributes(0xFFFF0000,0x14de2);
```

指定のメモリアドレスへのデータ転送方法は２つある。

> The first method uses the generic Xilinx I/O functions to read from and write to the selected memory address.

```
Xil_Out8(0xFFFF0000,0x55);
 
read_char = Xil_In8(0xFFFF0000);
``` 

> The second method is for both programs to access the memory location using pointers. 

```
#define LED_OP (*(volatileunsignedint *)(0xFFFF0000))
```
Zybo > Chronicles blog 49 > AMPの使用 > 7. OCMによるCore同士の通信 > error protection to the OCM > OCM Control Parity control register / OCM shared interrupt (number 35) / an AXI read error (SLVERR)

MicroZed Chronicles リスト http://adiuvoengineering.com/?page_id=285
@ Adam Taylor blog
https://forums.xilinx.com/t5/Xcell-Daily-Blog/Adam-Taylor-s-MicroZed-Chronicles-Part-49-Using-the-Zynq-SoC-s/ba-p/518579

OCMに対するerror protection

> We can also add <font color=red>error protection to the OCM</font> using the <font color=blue>OCM Control Parity control register</font> if we are using it for a particularly critical application. You can set odd or even parity individually on each of the 16 bytes that make up the 128-bit word stored at each OCM address. Through this register we can also configure how the Zynq SoC handles parity errors (<font color=red>by issuing the OCM shared interrupt (number 35)</font> or <font color=red>by sending an AXI read error (SLVERR)</font> when a read error is detected, for example).


Table 7-3: PS and PL Shared Peripheral Interrupt (SPI)の一部

| Source | Interrupt Name | IRQ ID# | Status Bits | Required Type |
|:-:|:-:|:-:|:-:|:-:|
|   | CPU 1, 0 |  33:32 | spi_status_0[1:0] | Rising edge  |
| APU  | L2 Cache  |  34 | spi_status_0[2]  |  High level |
|   | OCM  | 35  | spi_status_0[3]  | High level  |
Stateless な React Component の記法をまとめてみた

## はじめに
React Component には様々な書き方があるので、自分の理解のため整理してみました。


```js
var CommentBox = ...

ReactDOM.render(
  <CommentBox hello="Hello, world" name="CommentBox" />,
  document.getElementById('content')
)
```

以下、CommentBox に hello と name という props を渡す stateless なコンポーネントを前提とします。


## 基本型

チュートリアルに出てくる書き方で、誰しもが真っ先に覚える書き方かと思います。
https://facebook.github.io/react/docs/tutorial.html

```js
var CommentBox = React.createClass({
  render: function() {
    return (
      <div className="commentBox">
        {this.props.hello}! I am a {this.props.name}.
      </div>
    );
  }
});
```



## ES6 Class

ES6のclassを利用する方法です。
https://facebook.github.io/react/docs/reusable-components.html

```js
class CommentBox extends React.Component {
  constructor(props) {
    super(props)
  }
  render() {
    return (
      <div className="commentBox">
        {this.props.hello}! I am a {this.props.name}.
      </div>
    );
  }
}
```

propsをそのまま渡すだけなら、constructorを定義しなくとも構いません。

```js
class CommentBox extends React.Component {
  render() {
    return (
      <div className="commentBox">
        {this.props.hello}! I am a {this.props.name}.
      </div>
    );
  }
}
```

## Stateless Functions

実は、プレーンなJavascript関数でもOKです。

```js
function CommentBox(props) {
  return(
    <div className="commentBox">
      {props.hello}! I am a {props.name}.
    </div>
  )
}
```

ES6のarrow syntaxを使うと、以下のように書けます。

```js
const CommentBox = (props) => {
  return(
    <div className="commentBox">
      {props.hello}! I am a {props.name}.
    </div>
  )
}
```

propsを展開してもよいです。

```js
const CommentBox = ({hello, name}) => {
  return(
    <div className="commentBox">
      {hello}! I am a {name}.
    </div>
  )
}
```

[arrow function](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/arrow_functions) で 右辺に expression を書けることを利用すると、さらに短く書けます。

```js
const CommentBox = ({hello, name}) => (
  <div className="commentBox">
    {hello}! I am a {name}.
  </div>
)
```


## で、どの書き方がいいの？

https://facebook.github.io/react/docs/reusable-components.html 

末尾に

> In an ideal world, most of your components would be stateless functions because in the future we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations. This is the recommended pattern, when possible.

と書かれています。 
この指針に素直に従い、可能なら Statless Functions で書くのがよさそうです。



## 最終形

propTypesまで含めるとこんな形になるかと。

```js
import React from 'react'

const App = ({hello, name}) => (
  <div className="commentBox">
    {hello}! I am a {name}.
  </div>
)

App.propTypes = {
  hello: React.PropTypes.string.isRequired,
  name: React.PropTypes.string.isRequired
}
```
技術英語 > So [about 3 months in] and [with less than 2 months to go] before the promised date panic began to set in

http://thecodist.com/article/the-best-code-i-ever-wrote-part-1-of-2

> So <font color=red>about 3 months in and with less than 2 months to go</font> before the promised date panic began to set in

プロジェクトが3ヶ月経過して、2ヶ月残りという場合、inとto goを使って上記のような言い方ができるようだ。

to goの方はVoyagerで「残りxx」という言い方で出ていた。inの方は初めて意識した。


https://www.reddit.com/r/Guildwars2/comments/43ctx2/three_months_in_and_im_still_find_things_to_be/
> Three months in and I'm still find things to be impressed with ...
簡易メモ帳 (db不要)

session_id固定ネタを見て感動したので。

![memo.png](https://qiita-image-store.s3.amazonaws.com/0/25728/07d38342-81f3-b86f-bd5f-f27f67e0267f.png)

```php:memo.php
<?php
session_id("memo-".md5($_SERVER["QUERY_STRING"]));
session_start();
if (!empty($_POST["memo"])) {
        $_SESSION["memo"] = $_POST["memo"];
}
?><meta charset="utf-8">
<form method="post">
        <textarea name="memo" style="height:80%; width:90%;"><?php echo $_SESSION["memo"]; ?></textarea>
        <input type="submit" value="save" style="width:80%; margin: 1em;" />
</form>
```

## データは以下に保存

* /var/lib/php/session/ (`php -i | grep session`)
    * sess_memo-
    * sess_memo-0c09c125348bcbb25da8438711c68234
* OS再起動しても残る。

## メモを増やしたい場合

QUERY_STRINGを変更すれば良い。

* memo.php
* memo.php?page=1
* memo.php?page=2
* memo.php?page=3
* memo.php?page=4
* memo.php?page=5

## セッションについてもっと詳しくなるには

* [Cookieとセッションをちゃんと理解する - Qiita](http://qiita.com/hththt/items/07136ad74127999df271)

## gz圧縮保存

* セッションのサイズは数KBしかないので圧縮するとよいかな。

```php:memo.php
<?php
session_id("memo-".md5($_SERVER["QUERY_STRING"]));
session_start();
$memo = null;
if (!empty($_POST["memo"])) {
        $_SESSION["memo"] = gzcompress($_POST["memo"]);
}
if (!empty($_SESSION["memo"])) {
    $memo = gzuncompress($_SESSION["memo"]);
}
?><meta charset="utf-8">
<form method="post">
        <textarea name="memo" style="height:80%; width:90%;"><?php echo $memo; ?></textarea>
        <input type="submit" value="save" style="width:80%; margin: 1em;" />
</form>
```

## ファイルに保存する場合

```php:memo.php
<?php
$file_name = "memo-".md5($_SERVER["QUERY_STRING"]);
if (!empty($_POST["memo"])) {
        file_put_contents($file_name, gzcompress($_POST["memo"]));
}
$memo = gzuncompress(file_get_contents($file_name));
?><meta charset="utf-8">
<form method="post">
        <textarea name="memo" style="height:80%; width:90%;"><?php echo $memo; ?></textarea>
        <input type="submit" value="save" style="width:80%; margin: 1em;" />
</form>
```
OSXにFortran Compilerのf2c，f77をインストールする

## はじめに

Mac OS XでFortranを使う場合，大体は[gfortran](https://gcc.gnu.org/wiki/GFortran)をインストールすれば事足ります．gfortranのインストールは[MacPorts](https://www.macports.org/)が使えるため，非常に簡単です．しかし今回f2cが必要になり，少しインストールに戸惑ったので備忘録．

### 環境

- OSX 10.10.3

## インストール手順

調べていたところ，まさに[Fortran Compiler Installation Instructions for OS X](http://www.webmo.net/support/fortran_osx.html)というドンピシャな記事があり，しかもインストールのためのシェルスクリプトも記載してあったので，これを試しました．

```csh

#! /bin/csh
setenv INSTALL /usr/local
curl "http://netlib.sandia.gov/cgi-bin/netlib/netlibfiles.tar?filename=netlib/f2c" -o "f2c.tar"
tar -xvf f2c.tar
gunzip -rf f2c/*
cd f2c
mkdir libf2c
mv libf2c.zip libf2c
cd libf2c
unzip libf2c.zip
cp makefile.u Makefile
make
cp f2c.h $INSTALL/include
cp libf2c.a $INSTALL/lib
cd ../src
cp makefile.u Makefile
make
cp f2c $INSTALL/bin
cd ..
mkdir -p $INSTALL/share/man/man1
cp f2c.1t $INSTALL/share/man/man1
cp fc $INSTALL/bin/f77
chmod +x $INSTALL/bin/f77
cd ..
rm -rf f2c
echo "==================SUMMARY=================="
echo $0 " has built and installed:"
find $INSTALL -name '*f2c*' -mmin -5
find $INSTALL -name '*f77*' -mmin -5
```
(上記サイトからの引用)

ですが，このスクリプトを実行すると

```shell-session

/bin/sh: ./xsum: Permission denied
make: *** [xsum.out] Error 126
```

と，パーミッションで怒られてしまいます．そこで

```
chmod +x f2c/src/xsum 
```

で実行権限を付与し，もう一度実行したところ，今度は，

```
/bin/sh: ./xsum: cannot execute binary file
make: *** [xsum.out] Error 126
```

と怒られ，八方塞がりになってしまいました．

いろいろいじってみてもうまくいかなかったので，一度xsumバイナリファイルを削除し，

```
cc -O xsum.c -o xsum 
```

でコンパイルしなおしてあげた結果，無事f2c, f77のインストールが終了しました．

なので最終的に，上記インストールスクリプトに

```csh

cd ../src
cp makefile.u Makefile
rm xsum                #追加
cc -O xsum.c -o xsum   #追加
chmod +x xsum          #追加
make
cp f2c $INSTALL/bin
```
この三行を追加してあげれば動くはずです．
Ajaxでファイルデータをphpファイルに送る

以下の記事を参照して出来た
http://chaika.hatenablog.com/entry/2014/04/12/001012

```javascript:manage.php
$('#upload').click(function(){

	//フォームのデータを変数formに格納
	var form = $('#listing_image_form').get()[0];

	//FormData オブジェクトを作成
	var formData = new FormData( form );

	$.ajax({//送るデータ
		url:'listing_manage_save.php',
		method:'post',
		dataType:'json',
		//dataにFormDataを指定
		data:formData,
		// Ajaxがdataを整形しない指定
		processData:false,
		// contentTypeもfalseに指定
		contentType:false
	}).done(function(data){//成功した時の処理

		console.log( 'SUCCESS', data );
		
		//data内の改行コードを消す
		var img_file_path = data.replace(/\r?\n/g,"");

		
		//レイアウトを整えるためのp要素を作成
		var pn = $('<p></p>').attr({
    		style: "float:left; margin:10px 10px;"
		});

		//追加するimg要素を作成
    	var img_src = $('<img>').attr({
    		src: img_file_path,
    		style: "width:200px; height:150px;"
		});

    	//p要素の中にimg要素を入れる->これが実際に挿入される要素になる
		var imgInP = pn.html(img_src);

		//作成した要素を画像を囲う親要素の最後に追加する
    	$('div.photoImage').append(imgInP);
		//失敗した時の処理
	}).fail(function( jqXHR, textStatus, errorThrown ){

		console.log( 'ERROR', jqXHR, textStatus, errorThrown );
	});

	return false;
});
```


以下が受け取るphpファイル
**ajaxでjson形式を指定したため、
返す値もjson形式でなければならない**
```php:upload.php
date_default_timezone_set('Asia/Tokyo');
	if($_FILES["upfile"]["tmp_name"] && $_FILES["upfile"]["size"] > 0){


		//$_FILESの各要素を変数に代入する.getimagesizeは画像情報を取得する
		list($w,$h,$type,$attr) = getimagesize($_FILES["upfile"]["tmp_name"]);

		//画像のタイプに応じて拡張子をつける
		switch ($type) {
			case IMAGETYPE_JPEG:
				$extention = '.jpg';
				break;
			case IMAGETYPE_PNG:
				$extention = '.png';
				break;
			case IMAGETYPE_GIF:
				$extention = '.gif';
				break;
		}

		//拡張子がついた場合、画像のファイル名をつけ、画像を移動させるためのファイルパスを指定する
		if($extention){
			$file_name = date("YmdHis").$extention;
			$img_file_path = "image/listing_photos/$file_name";
	
			
		//画像ファイルを指定フォルダに移動させる
			move_uploaded_file($_FILES["upfile"]["tmp_name"],"$img_file_path");
		}else{
		
		//拡張子がつかなかった場合、エラーメッセージを出す
			header('Content-Type: application/json; charset=utf-8');
			echo json_encode("指定したファイルは画像ファイルではありません");
			exit;
		}


		//サーバーに保存した画像ファイルのパスをDBにも保存する(後で表示出来るように)
		$sql = "insert into listing_image_info (list_id,img_file_path) values(?,?)";//preareの時はbindを使う！！
		$stmt = $dbh->prepare($sql);
		$stmt->execute(array($list_id,$img_file_path));

		$sql = "select * from listing_image_info where list_id = ?;";
		$stmt = $dbh->prepare($sql);
		$stmt->execute(array($list_id));
		$result_img = $stmt->fetchAll(PDO::FETCH_ASSOC);

		//ajaxでjason形式を指定したら返す値もjsonにする！！
		header('Content-Type: application/json; charset=utf-8');
		echo json_encode($img_file_path);


	}

```
[baserCMS]バージョン番号を比較して動作を分ける


プラグイン作ってるときに、baserCMSコアのバージョンによっては利用できない処理となってしまったときに、どうしたものか考えてみた。
その結果、version_compare() 見つけて、これ使えば良さそうっぽいとやってみた。


## 想定している対象者
- baserCMSでウェブサイトを制作をしている方
- PHPer


## 発生状況
1. baserCMS3.0.10 では動くけど、3.0.9 では動かない処理を作ったとき
2. バージョン番号での比較できる処理を探して旅に出たとき


## サンプル

```
<?php if (version_compare($siteConfig['version'], '3.0.10') >= 0): ?>
	3.0.10以上だからOK
<?php else: ?>
	3.0.9以下だからNG
<?php endif ?>
```

```
if(version_compare($siteConfig['version'], '3.0.10', '>=')) {
   echo '3.0.10以上だからOK';
} else {
   echo '3.0.9以下だからNG';
}
```

## version_compare() について

ふたつのバージョン番号文字列を比較できる関数。

```
version_compare(string $version1, string $version2[, string $operator])
```

version_compare() の返り値は、最初のバージョンが2番目のバージョンより
小さい場合に -1
同じ場合に 0
2番目のバージョンのほうが小さい場合に 1
となる。

## 特殊なケースで比較

状況としてはあんましないけど、以下みたいに特殊な場合でもOKでした。

```
if (version_compare('3.0.6-hash', '4.0.0', '>=')) {
	echo '以上';
} else {
	echo '以下';
}

if (version_compare('4.1.0-dev', '4.0.1', '>=')) {
	echo '以上';
} else {
	echo '以下';
}
```


### 参考記事

- [PHP: version_compare - Manual](http://php.net/manual/ja/function.version-compare.php)
c++ rvalue、lvalueとかmove, forwardとか(編集中)

```cpp:1.cpp
int x = 1;
```
left value と right value。左のxはlvalue, 右の1はravlueとなる。rvalueはmove可能で、lvalueは一般的にできない。lvalueは参照可能でrvalueはできない。
Ti.Network.createHTTPClientがnullを返す

久しぶりにハマッたので書きます。

開発中に、iOSでコールバック関数の中でHTTP通信を実行すると妙な挙動になる箇所を見つけました。

```js
createSomeObject({
  success: function(e){
    var xhr = Ti.Network.createHTTPClient();
    xhr.open(method, url);
  }
});
```

こんな感じの、ごく普通の処理です。ところが実行すると

```
[ERROR] Script Error: {
[ERROR]     column = 30;
[ERROR]     line = 26;
[ERROR]     message = "null is not an object (evaluating 'xhr.open')";
```

といった具合に、createHTTPClientがnullを返すのでエラーになってしまいます。Runtime Errorなのでアプリも停止してしまいます。ユニットテストだと見つけられないかもしれないので恐ろしいですね。

これ、どうやらコールバックを呼び出すネイティブのコードの中でスレッド処理の問題があると起きるみたいです。HTTP通信は基本的にUIスレッドとは別で実行されるのですが、もしJavaScriptからTi.Network.createHTTPClientを使ったHTTP通信を多数実行するようなアプリなら、

```js
createSomeObject({
  success: function(e){
    setTimeout(function(){
      var xhr = Ti.Network.createHTTPClient();
      xhr.open(method, url);
    }, 0);
  }
});
```

という具合にsetTimeoutで囲ってしまうと回避できたりします。
フルスクリーンスライダー実装方法（slider-pro-master）

#フルスクリーンスライダーを簡単に実装しよう！

[ここのサイトからインストールできます](http://bqworks.com/slider-pro/)
サイトなんていいから早くコードをくれと言う方は↓からダウンロードしてね。
[ソースダウンロード](https://github.com/bqworks/slider-pro/archive/master.zip)

※前提として、jquery-1.11.0.min.jsは入れておきましょう。
まあ入ってなくても、ソースダウンロードすればその中に入ってるからそれを使おう！

##使用するファイル

```
slider-pro.min.css
jquery.sliderPro.min.js
```

この２ファイルだけ。
使用するディレクトリにファイルを移動しましょう！


表示させたいHTMLはこんな感じ！コピペでOK

```html
<div id="slider-pro" class="slider-pro">
    <div class="sp-slides">
        <div class="sp-slide"><img class="sp-image" alt="" src=""></div>
        <div class="sp-slide"><img class="sp-image" alt="" src=""></div>
        <div class="sp-slide"><img class="sp-image" alt="" src=""></div>
    </div>
</div>
```

**src**に画像のパスを追加して、**alt**に説明を入れよう！



##slider-pro-masterをキックしよう！

動かすには

```
sliderPro-start.js
```

ファイルを作成し、

```js
$(function(){
    $( '#slider-pro' ).sliderPro({
        width: '100%',
        height: 500,
        responsive: true,
        imageScaleMode: 'cover',
            // 'cover'、'contain'、'exact'、'none'
        slideDistance:0,
        arrows: true,
        autoHeight:false,
        buttons: false,
        fadeFullScreen:true,
        waitForLayers: true,
        autoplay: true
    });
});
```

を書き込もう！

オプションはたくさんあるので参考にして自分なりにカスタマイズしてみてね！
[SliderPro Options](http://on-ze.com/archives/2717)


###画面で確認して、動いてたら完了！


##終わり
【プロトコル指向】キーボードを簡単に閉じることができるProtocol


iOSアプリを開発していてキーボードが邪魔になることってよくありますよね。

そんな時は`UITapGestureRecognizer`を付け、画面をタップすると`view.endEditing(true)`を呼んでキーボードを閉じるという処理を書くと思います。

ただ、キーボードを使用する画面ごとにその処理を記述するのは気持ち悪いですよね。
そこで、Protocolを適合させ、メソッドを一つ呼ぶだけで上記の処理を組み込むことができるようにしてみました。

## KeyboardCloseable

```swift:KeyboardCloseable.swift
import UIKit

private var keyboardKey: Void?
private var gestureKey: Void?

public protocol KeyboardCloseable: class {
}

extension KeyboardCloseable where Self: UIViewController {
    public func addKeyboardCloseGesture() {
        let keyboardAction = KeyboardAction(view: view) { [weak self] in
            self?.view.endEditing(true)
        }

        let gestureForKeyboard = UITapGestureRecognizer(target: keyboardAction, action: #selector(keyboardAction.action))
        gestureForKeyboard.delegate = keyboardAction
        view.addGestureRecognizer(gestureForKeyboard)

        // KeyboardActionがGCで回収されないようにする
        objc_setAssociatedObject(self, &keyboardKey, keyboardAction, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        objc_setAssociatedObject(self, &gestureKey, gestureForKeyboard, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
    }

    public func removeKeyboardCloseGesture() {
        if let gesture = objc_getAssociatedObject(self, &gestureKey) as? UITapGestureRecognizer {
            view.removeGestureRecognizer(gesture)
        }
        objc_removeAssociatedObjects(self)
    }
}

private final class KeyboardAction: NSObject, UIGestureRecognizerDelegate {
    private let _action: () -> ()
    private weak var view: UIView?

    init(view: UIView, action: () -> ()) {
        self.view = view
        _action = action
    }

    @objc private func action() {
        _action()
    }

    @objc private func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
        // キーボード表示中だけGestureを有効に
        return view?.findFirstResponder() != nil
    }
}

private extension UIView {
    private func findFirstResponder() -> UIView? {
        guard !isFirstResponder() else { return self }

        for view in subviews {
            guard !view.isFirstResponder() else { return view }

            if let responder = view.findFirstResponder() {
                return responder
            }
        }
        return nil
    }
}
```

## 使い方

```swift
// KeyboardCloseableに適合
class ViewController: UIViewController, KeyboardCloseable {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // これを呼ぶだけ
        addKeyboardCloseGesture()
    }
}
```


プロトコル指向で、見た目が非常に美しくなります:smile: