OmniAICreator/Qiita-1.07M huggingface dataset:
【TECH::CAMP（テックキャンプ）体験談】地方でもメンターの指導で2ヶ月でサイト開発ができた話

※こちらの記事は、プロスタ編集部がプログラミングの学習法を公開することで、皆様のお役に立ちたい意図で投稿しております。

参考サイト：[【TECH::CAMP（テックキャンプ）体験談】地方でもメンターの指導で2ヶ月でサイト開発ができた話](http://programming-study.com/case/techcamp-story/)


地方にいる私でも、プログラミングを学ぶことができました。

目次
1 [プログラミングを始めようと思ったきっかけと、TECH::CAMPを選んだ理由](##プログラミングを始めようと思ったきっかけと、TECH::CAMPを選んだ理由)
2 [私が選んだのはWebアプリケーションコース](##私が選んだのはWebアプリケーションコース)
3 [初心者が効率的にプログラミングを勉強するコツ](##初心者が効率的にプログラミングを勉強するコツ)

##プログラミングを始めようと思ったきっかけと、TECH::CAMPを選んだ理由

　私は元々ウェブ業界で働いていて、仕事がきっかけでHTMLやCSS、プログラミングに興味を持ちました。アイデアを形にできることが魅力だったのと、2020年にはプログラミング教育の必修が検討されている今、大きな強みになっていくと考えたからです。
　TECH::CAMPの一番の特徴は、ウェブ上に用意される自主学習形式のカリキュラムです。学生や社会人でも、私生活と両立しながらマイペースに進めることができます。

　また、メンターと呼ばれるスタッフがいて、分からないことは、AM11:00～PM11:00の間、直ぐに質問できます。独学と違って、すぐに疑問を解決できるからこそ1か月で基礎を学ぶことができます。
　質問の仕方も様々で、各教室で直接聞ける「キャンプスタイル」とスカイプや専用のチャットを利用した「オンラインスタイル」があります。その他、カリキュラムの進め方や卒業後の相談など、幅広くサポートをしてくれるのも心強い点です。

##私が選んだのはWebアプリケーションコース

　私は、今後もウェブ業界に関わりたかったので「Webアプリケーションコース」を2ヶ月日程で受けました。プログラムを含める一般的なウェブページを制作するコースです。コース選択については、事前にチャットで相談もできるので、色々と聞いてみましょう。

　学習し始めた当初、ターミナルなどのプログラミングツールの操作すらできず、基本的な文法や単語を覚えるだけで、毎日いっぱいいっぱいでした。「本当にプログラミングをできるようになるんだろうか・・・？」と不安でしたが、2週間ほど経つと学習した文法の意味も分かりはじめ、3週間目で何度か同じ課題を繰り返し復習することで、理解度が上がり自信もついてきました。振り返ってみると、1ヶ月で基礎カリキュラムを終了させたことが力になったと思います。集中して基礎を固めていくことで、記憶に残りやすくなるからです。
　2ヶ月目は、オリジナルアプリケーション制作として、Twitterを活用した簡単なサイトの開発を始めました。
　結果的には、基礎やエラー時の対応、応用した機能を開発したい時の調べ方が身についたので、ある程度自力でプログミングできるようになりました。

##初心者が効率的にプログラミングを勉強するコツ

　TECH::CAMPのカリキュラムを進める上でも大切なことですが、まずは挫けずに学習を進めることです。初めから全てを理解できる人はいません。最初は大まかに、次にわからなかった所、最後に完璧に、というように繰り返し理解していくことが重要です。

数学の公式を覚え、問題を解きながら理解していく感覚に似ています。数学と違って、プログラミングは動作を確認しながら進めるので、楽しみながら学習できると思います。実際に、何かアイデアを出してオリジナル制作をしてみると、なお良いです。プログラミングは、とにかくトライ&エラーを経験して、手を動かすことが大切です。


他にも体験談を読みたい方へ
➡[【TECH::CAMP体験談】もしもプロアスリートがプログラミングを学んだら](http://programming-study.com/case/techcamp-athlete/)
➡[【TECH::CAMP体験談】非ITの私が一ヶ月毎日8時間プログラミングを学んでみた](http://programming-study.com/case/techcamp-notit/)
[boto3]SESを使ってメールを送信する


boto3を使えば、PythonからSES経由でメール送信ができます。

```python
        client = boto3.client('ses')
        response = client.send_email(
            Source='YOUR@EMAIL.ADDRESS',
            Destination={
                'ToAddresses': [
                    'TO_ADDRESS@example.com',
                ],
                'CcAddresses': [
                    'CC_ADDRESS@example.com',
                ],
                'BccAddresses': [
                    'BCC_ADDRESS@example.com',
                ]
            },
            Message={
                'Subject': {
                    'Data': 'SES Mail by Python',
                    'Charset': 'UTF-8'
                },
                'Body': {
                    'Text': {
                        'Data': 'This is text mail',
                        'Charset': 'UTF-8'
                    },
                    'Html': {
                        'Data': '<h1>This is Html Mail</h1>',
                        'Charset': 'UTF-8'
                    }
                }
            },
            ReplyToAddresses=[
                'YOUR@EMAIL.ADDRESS',
            ]
        )
```

## 実行する
実行すると、以下のようにメールが送信されます。

![スクリーンショット 2017-01-12 15.08.10.png](https://qiita-image-store.s3.amazonaws.com/0/23936/7240f7be-dffe-cf66-0747-b40d2b5458bd.png "スクリーンショット 2017-01-12 15.08.10.png")

## Tips

### HTMLメールとテキストメール
`Message['Body']['Text']`は`Message['Body']['Html']`がある場合かつHTMLメールが見れるクライアントでは表示されない様子です。

### アドレスについて
`Source`に入れるアドレスは、自身のSESアカウントで認証済のものを使ってください。

### 権限について
実行するために必要な権限は`ses:SendEmail`です。
以下のようなロールを作って、LambdaなりIAMユーザーに割り当てておきましょう。

```
{
  "Version": "2012-10-17",
  "Statement": [{
      "Action": [
        "ses:SendEmail"
      ],
      "Resource": [
        "arn:aws:ses:*"
      ],
      "Effect": "Allow"
  }]
}
```

### その他
バウンスの処理などもできる様子なので、興味がある方は以下をご覧ください。
http://boto3.readthedocs.io/en/latest/reference/services/ses.html#SES.Client.send_email
リストのInfopathフォームを発行すると表のいくつかのセルの背景色が白くなってしまう場合の対処法

SharePoint2013 のリストのフォームを Infopath とした場合に、
Infopathのデザインモードでは全てのセルに色を付けても、SharePointに発行してフォームを確認すると白くなってしまう症状が発生する場合がある。

この場合、先にセルの背景色を塗り、そのあとに罫線を引くとうまくいく。逆にすると背景色が濡れない。

↓こちらのエントリでも同様の指摘。
http://sharepoint.stackexchange.com/questions/108324/why-some-cells-in-infopath-2013-doest-change-of-color


発行されたフォームのHTMLを確認するとTDタグのスタイルで背景色などが記述されてないことがわかる。
chromeアプリのTextのハイライトを直す

# chromeアプリのTextのハイライトを直す
環境

- Google Chrome	55.0.2883.87 (Official Build) m （64 ビット）
- Text 0.5.68

Chrome Storeのurlは[これ](https://chrome.google.com/webstore/detail/text/mmfbcljfglbokpmkimbfghdkjmjhdgbg?utm_source=chrome-app-launcher-info-dialog)

TextでC言語などのソースコードを開くと部分的にしかハイライトされないのでTextのソースを編集して直す.

## Textのソースコードの場所
[chrome アプリ  保存場所 (ここに自分のOSの名前を入れる)] [検索]

## all.js
ミニマライズされているので該当箇所は適当にサーチして見つけてください.
diffとっても1行だし意味ないし.
`var u=this.editor_.newSession(a)`を`var u=this.editor_.newSession(a,c)`に変える.
`EditorCodeMirror.prototype.newSession=function(a){return new CodeMirror.Doc(a||"")};`を

```js
EditorCodeMirror.prototype.newSession=function(a,c){
    var filename = c==undefined?[""]:c.name.split(/\.(?=[^.]+$)/),
        mime = (filename[filename.length - 1] == "c"?"text/x-csrc":"text/plain");
    return new CodeMirror.Doc(a||"", mime)
};
```

に変える.

`EditorCodeMirror.EXTENSION_TO_MODE`の`c:"clike"`を`c:"text/x-csrc"`にする.

多分これで上手くハイライトされるはず.
他の言語も同様に`newSession`でmimeタイプを適切に設定して,`EditorCodeMirror.EXTENSION_TO_MODE`のmimeタイプも適切に設計すればうまくいくはず.
スクレイピング！その前に

# まえがき

新サービスの企画を練る時、世にあるサービス同士のマッシュアップを考えるのは誰しも通る道です。お手軽に新しいコンテンツが作れるようにみえるんでしょうねぇ。あのサービスのここの部分に注目すれば、もっと良いサービスができるのに！という考えは魅力的です。
ましてや、それを実現するために技術はそれほど敷居も高くないとくれば。。。

某QAサイトの質問を見ても、多くの質問者が、スクレイピングによるコンテンツ収集を行い、新しサービスを立ち上げようとしています。

**が、ちょっと待って！**
そのスクレイピングを基底とした企画、ホントに上手く回るんでしょうか？

ということで、実体験と私宛に頂いたアドバイスを元に、スクレイピングを基底とした企画の注意点をまとめてみました。
識者の皆様からの追加アドバイスも待ってます！

# 企画
## スクレイピング先とコンタクトを取る
できれば、スクレイピング先とは企画段階でコンタクトをとっておくべきです。
後にトラブルになったときや、緊急対応が必要となる時にお互いに連携が取れていると対処できる幅が広がります。
また、公開されていないAPIやRSS等、自前でスクレイピングするより効率的にコンテンツを提供してもらえる可能性もあります。

## そもそもスクレイピング先に迷惑をかけないか？
スクレイピング先に迷惑をかけるようなサービスは当然先はありません。
スクレイピング先がなくなってしまっては、そもそもサービスが成り立たないので。
実は私が運営していたサイトの一つが、機械アクセスが元で、サービス提供ができなくなりました。。。
サービスによってはしょぼいインフラで回ってるサービスもあります。
ここはすごく慎重に、真摯に検討しましょう。

## 同じターゲットを取り合っていないか？

コンテンツ引用で、同じターゲットを取り合いになるようなサービスであれば、その先にはコンテンツの先細りしかありません。
スクレイピング先のターゲットを取り合うようなサービスはサービスとして無意味です。企画段階で注意しましょう。

## コンテンツを引用の範囲以上で使用する事になっていないか？

盗用になっていないか？
加工後に付加価値がつけられるか？
昨今このあたりの評価は厳しくなっています。自己の勝手解釈でコンテンツの二次利用を肯定するのは後のトラブルのもとです。
必要であれば、信頼できる専門家の意見を確認しましょう。

## スクレイピング先のサイトポリシーに違反する内容になっていないか？
当然ですが、スクレイピング先の利用の制限に抵触していれば、サービスは継続できません。
2次利用が禁止されていないか？機械アクセスを禁止していないか？等まず確認しましょう。

## スクレイピングはコストが掛かることを想定して企画しているか？
やってみればわかりますが、スクレイピングのコードは継続的にメンテナンスが必要なモノです。
スクレイピング先のレイアウト等の変更により、数ヶ月で改修が必要になることも少なくありません。
その変化の監視や、それに伴う改修はサービス提供にあたってのコストとして、計算していますか？
結構もれている検討事項だと思います。

# 設計
## アクセスは適切か？

企画でも書きましたが、スクレイピングの基本は、スクレイピング先に迷惑をかけないことです。
通常のユーザアクセスと同程度のアクセスとなっているか？
アクセスの頻度やアクセスの間隔をスクレイピング先の想定するものから外れないように設計することが重要です。
この時、アクセス頻度や間隔をコントロールできる設計を心がけるべきです。

## アクセスで不具合を起こさせてしまったときの連絡方法を確立できているか？

注意深くしていても、想定外の迷惑をかけることがあります。
設計段階から、不具合で先方に迷惑をかけてしまった場合の連絡方法を検討しましょう。
実装は、UserAgentを使用するのが一般的です。

## 取得情報のばらつきに対してのどのように対処するか？
一般的にスクレイピングで入手できる情報にはばらつきがあります。
フォーマットであったり、そもそもその項目が取れなかったときだったり、そういった場合の想定を設計に組み込む必要があります。

# 構築/テスト

## 実装としてアクセスは必要最小限となっているか？

極力スクレイピング先に負荷をかけない実装とする必要があります。
たとえば、キャッシュを作るとか。同じデータへのアクセスを一定期間はさせない工夫をしましょう。

## 構築/テスト段階ではローカルでテストできるように準備しているか？

構築/テスト段階で、スクレイピング先へアクセスを行うことは極力避けます。
データの加工処理を行う部分は、ダミーデータを使用して、きちんとローカルでテストしましょう。

## 使用するライブラリの仕様を把握しているか？

アクセスに使用するライブラリの仕様はきちんと把握する必要があります。
他サイトへ影響する部分なので、通常のライブラリを使用する時以上に、きちんと仕様を確認し把握しましょう。

## おかしなアクセスや内部でのループ処理が入っていないか？
ループでアクセス先を落としてしまうとか、最悪です。
アクセス処理には極力ループを使用しないように実装し、無理ならそのループに上限を設けて無限ループとならないよう管理します。

## 取得情報のばらつきに対して適切な回避処理や補完処理を行えているか？
おもに例外処理になると思いますが、決して短時間に再アクセスを行い、更新を確認するような実装にしないで下さい。
アクセス頻度は変えず、入手した情報を適切に補完したり、更新自体を回避する仕組みで実装しなければなりません。

# 運用
## エラー等の監視が必要十分に出来ているか？
非常に重要です。
エラーの発生は自サイトのみならず、スクレイピング先へ問題を派生させている可能性があります。
24H365Dで検出、対応できる体制をとっておく必要があります。

## スクレイピング先のレイアウト変更の監視
必要なデータが入手できなくなる可能性が高いです。イベント対応等で臨時変更されるケースもあるので、十分に注意しましょう。

# さいごに
スクレイピングを使用したサービスはスクレイピング先と共栄できることが理想です。
できれば企画段階から相談し、サービスの住み分けを提案、両者で利用者の拡大をはかるサービスとして立ち上げましょう。
SVGでフリーハンドお絵描き

svgでお絵描きサンプルを作ってみました。
線を滑らかにしたかったので色々と思考錯誤してみました。

## やりたいこと
- svg上でドラッグしたらpathを追加したい
- pathをベジェにして滑らかにしたい
- 頂点を間引いて滑らかにしたい

### svg上でドラッグしたらpathを追加したい
これは、単純にマウスイベントとフラグ管理でドラッグしている時にsvg要素にpath要素を追加していきました。


### pathをベジェにして滑らかにしたい
これがけっこう大変でした。

通過点のみで曲線を描くのはcatmull曲線があるのですが、まだpath要素には実装されていないようでした。
[ここ](http://defghi1977.html.xdomain.jp/tech/svgMemo/svgMemo_03.htm)によると下記のようです。
> R,r1  Catmull-Romスプライン曲線を引く
> SVG2での新機能．詳細仕様は策定中であり，動作する環境はまだない．

したがって、ベジェ曲線を使うことになるのですが、通過点の他に制御点が必要です。
イラレでよく見かけるアンカーポイントのことです。

[svgでベジェ曲線サンプル](http://codepen.io/osublake/pen/ggYxvp)

[通過点から制御点を求める関数を上げている](http://stackoverflow.com/questions/22442060/catmull-rom-spline-to-bezier-spline-converter)人がいたので、これを拝借しました。

ソースコードのみ抜粋

```javascript:catmullRom2bezier
function catmullRom2bezier(pts){
	var cubics = [];
	for ( var i = 0, iLen = pts.length; i < iLen ; i++ ){
	    var p = [
	        pts[i - 1],
	        pts[i],
	        pts[i + 1],
	        pts[i + 2]
	    ];
	    if( i === 0 ){
	        p[0] = {
	            x: pts[ 0 ].x,
	            y: pts[ 0 ].y
	        }
	    }
	    if( i === iLen - 2 ){
	        p[3] = {
	            x: pts[iLen - 2].x,
	            y: pts[iLen - 2].y
	        };
	    }
	    if ( i === iLen - 1 ) {
	        p[2] = {
	            x: pts[iLen - 1].x, 
	            y: pts[iLen - 1].y
	        };
	        p[3] = {
	            x: pts[iLen - 1].x, 
	            y: pts[iLen - 1].y
	        };
	    }
      const val = 6;
	    cubics.push([
	        (-p[0].x + val * p[1].x + p[2].x) / val,
	        (-p[0].y + val * p[1].y + p[2].y) / val,
	        (p[1].x + val * p[2].x - p[3].x) / val,
	        (p[1].y + val * p[2].y - p[3].y) / val,
	        p[2].x,
	        p[2].y
	    ]);
	}
	return cubics;
}
```

引数に通過点の座標配列を入れれば、制御点を含んだベジェ曲線用の座標配列を返してくれます。

他にも、[npmで公開している人](https://www.npmjs.com/package/@yr/catmull-rom-spline)もいました。
実際に使う時はこれをインストールしても良いさそうです。

### 頂点を間引いて滑らかにしたい
最初、単純に距離が近すぎる点を間引いていたのですが、あまりうまく機能しませんでした。
そこでポリゴンの線を単純化してくれる[Simplify.js](http://mourner.github.io/simplify-js/)を使うことにしました。
(CDNで公開されているものが見つからなかったので、成果物ではコードをコピペして使っています。)

## 成果物
http://codepen.io/kwst/pen/vgGgqN
上が滑らかにした線、下がフリーハンドで描いた線
![スクリーンショット 2017-01-12 14.40.30.png](https://qiita-image-store.s3.amazonaws.com/0/29966/1f02bd9c-5af1-dd27-993a-71137b21562e.png)
割りとなめらかになったかなと思います。
単純なお絵描きですが、線をなめらかにするだけでも結構骨が折れました。

Githubに公開してみました。
[SVGCatmullRomSpline](https://github.com/SatoshiKawabata/SVGCatmullRomSpline)
TravisCIでutf8mb4

.travis.yml

```yaml
before_script:
  - |
    echo -e "[mysqld]
    character_set_server=utf8mb4
    collation_server=utf8mb4_unicode_ci
    innodb_large_prefix=ON
    innodb_file_format=Barracuda
    innodb_file_format_max=Barracuda" | sudo tee /etc/mysql/conf.d/travis.cnf
  - sudo /etc/init.d/mysql restart
```

`/etc/mysql/conf.d/`以下は[MySQL 5.6](http://qiita.com/takeyuweb/items/bcc132defc17db84abbb)のパス。標準の5.5で同じかは試してない。たぶんいける？
ロックにかかってるのは誰？どのSQL？

# やりたかったいこと
DBはOracle。
異常系のテストがやりたくて、外部でレコードロックしかけてから対象コードを動かしたい。
もちろんUnitテストなフレームワークを使って。

# 詰まったこと
想定外のところでロックされているらしく、どっかでロック解除待ちになってテスト実行が途中で止まってる。

# 調査してみる
とりあえずどこで止まってるのか確認。
ロック解除待ちっぽいのはわかったのでほんとにそうか？を念のため確認する。
テストコードも途中で止まったままなので、とりあえずkillできるようにSIDとSERIAL#は欲しい。
引っかかってるSQLが何かわからないので、そいつもあるといい。

```sql
select SQL_ID, SID, SERIAL#, USERNAME, STATUS, SERVER, SCHEMANAME, PROGRAM FROM v$session WHERE SID IN (SELECT SID FROM V$LOCK);
```

詰まってるやつがいることがわかる。。。
やっぱりいた。
ではどのSQLがつまってるの？
先ほどのSQLで「SQL_ID」を抽出しているのでそれを使う。

```sql
select SQL_TEXT from v$sqlarea where SQL_ID = '[先に抽出していたSQL_ID]';
```

これでどのSQLがロック解除待ちにひっかかってるのか判明！

# 対処して終わり
ロック解除待ちのままになっているSQLがわかればどのオブジェクトがロックされっぱなしなのかがわかるので、そのロックを取得している処理を探して改修したら終わり。
DockerでJupyterをさくっと立ち上げる（対象言語:Anaconda/Ruby）

# この記事の目的
ローカルでJupyterをさくっと立てて分析をしたり、簡単なスクリプトを書きたい時にはDockerを使うと便利です。その方法をまとめました。

Jupyter上で扱う言語はAnacondaとRubyを対象としています。

# 前提
Dockerがインストールされていること。

# Anacondaを使う場合
Jupyterが公式で提供しているDockerイメージを利用します。
[jupyter/docker-stacks - Github](https://github.com/jupyter/docker-stacks)

色々なバージョンがあるのですが、今回は分析用のライブラリが一式入っているdatascience-notebookを使います。

ローカルなので認証Offの状態で立ち上げます。（サーバ上で起動する場合は認証掛けたほうがいいと思います）
また、分析対象のデータがあるディレクトリで docker run すればそのままデータが使えるように、Jupyterのworkをカレントディレクトリにマウントしておきます。こうすることで、notebook自体はローカル上に残ります。

```bash
docker pull jupyter/datascience-notebook
docker run -d -p 8888:8888 -v "$(pwd):/home/jovyan/work" jupyter/datascience-notebook start-notebook.sh --NotebookApp.token=''
```

ブラウザからlocalhost:8888にアクセスするとJupyterからAnacondaが使える状態になっています。

### Reference
[Jupyter の Docker イメージを使ってみる - Qiita](http://qiita.com/kshigeru/items/2cd504e927869163b4c8)

# Rubyを使う場合
公式では無いのですが、[こちらの記事](http://qiita.com/izumin5210/items/5531f58f31d788bb8b9b)で紹介されているイメージを利用します。

Rubyの場合はGemを自分で追加したいので、 docker run するディレクトリにGemfileとDockerfileを置いた状態で起動します。

```text:Gemfile
source 'https://rubygems.org'

gem 'hoge' # 好きなGemを入れる
gem 'fuga'
```

```text:Dockerfile
FROM izumin5210/iruby-notebook

ADD Gemfile .
RUN bundle install
```

Rubyの文字コードだけ指定して起動します。また。Anacondaの場合と同様に、分析対象のデータがあるディレクトリで docker run すればそのままデータが使えるように、Jupyterのworkをカレントディレクトリにマウントします。

```bash
docker build -t=iruby-notebook .
docker run -p 8888:8888 -e RUBYOPT=-EUTF-8 -v "$(pwd):/notebooks" iruby-notebook
```

ブラウザからlocalhost:8888にアクセスするとJupyterからRubyが使える状態になっています。

### Reference
[Railsエンジニアに役立つJupyter NotebookとiRuby - クックパッド開発者ブログ](http://techlife.cookpad.com/entry/201510-jupyter-and-rails)
[Pythonista以外が環境を汚さずにJupyter Notebookに触れる方法 あるいは，Rubyist以外が環境を汚さずにJupyter NotebookでRubyに触れる方法 - Qiita](http://qiita.com/izumin5210/items/5531f58f31d788bb8b9b)

以上です。
備忘録：Pepperで外部モジュールを利用するときの方法

Pepperで外部モジュールを利用するときの方法は、いくつかQiitaの投稿にも掲載され参考にさせていただきました。内容を私なりに整理してみました。
私もPythonに詳しい訳ではなく、Choregrapheを使うようになってやり始めた初心者です。

##背景
Pepperの機能確認をしていく中で、「Pepperが写真を撮り、撮った写真を送りたい」とういう要望での調査を実施していると、Qiitaに下記の記事を見つけました。

[『pepperが撮影した写真をS3にuploadしてslackでUP』](http://qiita.com/skylarking/items/3b2120c431645feb1a0d)

早速、自分で実装してみることにしました。

####そこで、問題！！
記事には、
>使ったもの
   -  boto
   -  slack_client
   -  websocket
アプリのルートに「lib」ディレクトリを作成して、上記ファイルをインポートした。

と記述されていました。
最初は、サンプルのコードばかりに気をとられ実装してもエラーで動きません。
それもそのはず、S3を使うためのbotoやslackのPythonライブラリが読み込まれていないことに気づきました。

通常、Pythonでは、`pip install` という便利なコマンドでインストールできるようですが、Pepperでは使えないらしい。

###解決方法！！
それが、
>アプリのルートに「lib」ディレクトリを作成して、上記ファイルをインポートした。


##実装方法
それでは具体的に私の行った手順を記載します。

###手順
1.  それぞれのライブラリを入手する
2.  Choregrapheのプロジェクトフォルダ内にlibディレクトリを作成する
3.  作成したlibディレクトリの中に 1. で入手したライブラリをコピーする
4.  Choregrapheでプロジェクトを開くと追加されたライブラリの読込確認があるのですべて読み込む


この手順を行うことで先に記述したエラーも解消され、記事『pepperが撮影した写真をS3にuploadしてslackでUP』の内容が実装できました。


###（補足）
>手順１：ライブラリの入手方法
一旦、自分のパソコン内のPythonに　`pip install` コマンドでライブラリのインストールをしました。
そして、Pythonディレクトリ内の "site-packages" というディレクトリにインストールされたライブラリフォルダをコピーしました。（\boto , \slackclient , \websocket）



##まとめ
実際に動作確認ができたあと、改めてPythonコードの確認をしてみました。
そこで気づいたことを補足します。

タイトルの「Pepperで外部モジュールを利用するときの方法」として最後まとめると、上記に記載した手順１～４とさらに実装されたPythonコードにも記述すべき内容があります。それらを手順５に補足します。

>手順５：Python Scriptボックスの中で、作成したlibディレクトリを参照できるようにする


```python:

    def onLoad(self):
        #put initialization code here
        self.framemanager = ALProxy("ALFrameManager")


    def onInput_onStart(self):
        #self.onStopped() #activate the output of the box
        import sys, os
        self.folderName = os.path.join(
                    self.framemanager.getBehaviorPath(self.behaviorId), "../lib")
        if self.folderName not in sys.path:
            sys.path.append(self.folderName)


```
Google Chrome 拡張機能の開発 - 6 - クリップボード履歴を一応それらしく使えるようにする

<font color="#0000ff"><b>やりたいこと：コンテキストメニューからコピーした情報の、履歴ページでのエントリーの削除と再コピー</b></font>
<font color="#ff0000"><b>やれたこと：一応、削除と再コピーができるようにはなった</b></font>
【[ソースコード](https://github.com/rrryutaro/RChromeExtension)】【[R Chrome Extension - Chrome ウェブストア](https://chrome.google.com/webstore/detail/r-chrome-extension/nmabekdmfpblgbgplficnahfkekbggil)】(一応公開してます)

# 前回のおさらい
前回、右クリックから選択したコピー内容を履歴ページ（とりあえずオプションページを利用）して、表示の確認までは行えるようにしました。
（記事を公開したのがv0.0.5.0で、そこからちょっとした不具合や、見栄えの変更をして、v0.0.5.3の時点までをGitHubに公開しました）

# 前回のちょっとした不具合
履歴の1つ目に`undefined`が表示されていましたが、データがない場合の初期化で次のようにしていたからですね。この程度のミスをやらかしているレベルです。

```js
//誤
if (saveData==null)
  saveData = [{}];
//正
if (saveData==null)
  saveData = [];
```

# 今回の実装内容
コピーと削除のアイコンを用意し、コピーをクリックしたら、その項目の内容をクリップボードへコピー、削除をクリックしたらその項目を削除して、画面を再表示する。

まず、基本のタグ文字列をこんな感じで定義しておきます。

```js
const tag1 = "<tr><td>{0}</td><td>{1}</td></tr>"
const tag2 = '<input type="image" id="btnCopy" src="copy_16.png" alt="コピー" value="{0}"><input type="image" id="btnRemove" src="trash_16.png" alt="削除" value="{1}">'
```
続いて、各要素の作成で、置き換えします。

```js
items.CopyData.reverse().forEach(x=>{
  const tbl = $("#copyTable");
  switch (x.Type){
    case "TITLE":
      tbl.append(fs(tag1, [fs(tag2, [fs("[{0}]({1})", [x.Data.Url, x.Data.Title]), index--]), fs("<a href={0}>{1}</a>", [x.Data.Url, x.Data.Title])]));
      break;
  	case "IMG":
  	  tbl.append(fs(tag1, [fs(tag2, [x.Data, index--]), x.Data]));
  	  break;
  	default:
  	  tbl.append(fs(tag1, [fs(tag2, [escapeHtml(x.Data), index--]), fs("<pre>{0}</pre>", [escapeHtml(x.Data)])]));
  	  break;
  }
});
```

表示は新しいものを上にするために、`reverse`させました。
`fs`は以前に作成した`formatString`のことです。ちょっと関数名が長いので、このスクリプト内でのエイリアスとして、`const fs = (fmt, ary)=>{ return formatString(fmt, ary); }`のようにしています。あまり好ましいやり方ではないですが、今はやりたいことを実現させるために試行錯誤している段階なので、よしとしておきます。

最初の`tag1`の置き換えで`{0}`を`tag2`で置き換え、その中でさらに、`tag2`の`{0}`と`{1}`を種別に応じて必要な値で置き換えるようにしています。
`tag1`の`{1}`の置き換えで画面上に表示する内容としています。
なお、エスケープについては、参考記事のコードを丸ごと拝借させてもらっています。

これで、大分使い物になる拡張機能になってきました。

あとは、インテリジェントなコピーが行えるように、せっせとタグなどに応じた表示や、再コピーを行えるようにガシガシ組んでいくことになるかと思います。

# 今後について
大分やりたいことができたのと、そのための方法がわかった次第です。
これまではその過程を垂れ流しでしたので、どこかのタイミングで整理して、人が参考にできるような記事にしたいと思います。
また、この拡張機能についても、さらなる機能拡張として、クリップボードヘの貼り付けを監視して、他のコピーも履歴に載せたり、キャプチャ関連の機能を充実させれば、本気で使えるものになるんじゃないかと思います。

# 動かしてみた感じ
![image](https://qiita-image-store.s3.amazonaws.com/0/156225/72ba7cda-e978-8601-ee6c-13db63dbe4ec.png)
あるぇ～ 画像のところのコピーアイコンのところがうまくエスケープできていないや。テヘ。

以上

|前回|一覧|次回|
|:--|:--:|--:|
|[コピーした履歴をわかるようにする](http://qiita.com/rrryutaro/items/530d5a50dec8436ebb5c)|[シリーズ一覧](http://qiita.com/rrryutaro/items/015b67568ddd947ec2b5)|[これまでの内容を整理](http://qiita.com/rrryutaro/items/93769ebcb35962821098)|
Windowsアプリのマルチスレッド処理

#ボタンを押すと、フォームが固まった#
昨日、ボタンに連続作業をさせるコードを入れて、ボタンを押すとその作業が終わるまでフォーム内の他の操作ができなくなってしまった。

ボタンにはwhile(true){}ループが入れてある。

これが原因であることは直感でわかったが、どうすればいいのかわからなかった。いろいろネットを調べたらサブスレッドからやればいいと書いてあった。それしか書いてないので、あとは自分でやり方を見つけるしかない。

#サブスレッド、BeginInvoke、デリゲートで#
まずフォームが固まるのは理由として、
>
UI フリーズが発生する原因は、メッセージループ上（UI スレッド上）で長時間処理を行ってしまうことである。イベントハンドラなどに長時間処理を記述すると、OS からの再描画要求が実行されなくなり、UI がフリーズする。

とマイクロソフトのページに書いてある。さらに、
>
UI がフリーズしないアプリを作るためには、時間のかかる処理（具体的には 0.1sec 以上かかる処理）を別スレッドに切り離して実行しなければならない。

同じスレッド内ではなく、別のスレッドを作成してそこから指令を出すとフォームが更新され、操作が可能になるという。これをフォームのマルチスレッド処理というらしい。Windowsアプリ開発では当たり前の作業らしいのだが、他のサイトではあまり詳しくは掲載されていなかった。

しかし、

別スレッドから当該スレッドを操作してはいけないと書いてある。どうすればいいのか？
>
メイン以外のスレッドから UI コントロールを操作してはならない。このような場合には、BeginInvoke() 命令を使って、UI スレッド上で画面描画更新処理を動作させる。

とある。
BeginInvokeを使えばサブで作ったスレッドから指示を出せることになる。以下にまとめる。
(コード内にあるデリゲートとは使節団、使節といった意味になる。使節(delegate)がBeginInvokeに下のメッセージを運ぶといった意味かなと思う）

```C++:フォームマルチスレッド処理
//MyFormというクラスを使う前提で記述してあります。

using namespace Threading;//名前空間を追加する（サブスレッド作成用）

private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {//ボタンクリック
buttun1->Enable = false;//ボタン１を無効化する。

Thread ^subThread = gcnew Thread(gcnew ThreadStart(this,&MyForm::subthread)) ;//サブスレッド作成
subThread->IsBackground = true;//サブスレッドをバックグラウンド化する
subThread->Start();//サブスレッドを立ち上げる。

}


private: System::Void subThread() {//上記で作成したサブスレッドを記述する。

        while(true) {//処理の長い作業やループを記述する。    

        BeginIvoke(gcnew delegate_of_shori_1(this,&MyForm::Shori_1));//ループ内でインボークを入れる。

        }

BeginInvoke(gcnew delegate_of_shori_2(this,&MyForm::shori_2)); //ボタンを有効にするデリゲート。

}	

private: delegate System::Void delegate_of_shori_1();//ループ内処理のデリゲート。shori_1
private: System::Void Shori_1() {//引数がある場合、()に記述する。上記デリゲートと引数をそろえる。
//ループ内で処理する内容。高速でループしているので重い処理は厳禁。軽い作業のみ記述する。
}

private: delegate System::Void delegate_of_shori_2();//ループ終了後のデリゲート。shori_2
private: System::Void shori_2{
//ループ後の処理を記述。
button1-> Enable = true;//ボタン１を有効化する。
}

```
eslint-plugin-react@6.9.0にアップグレードしたら`react/require-default-props`で怒られた

PropTypesでまたハマったので備忘録を残す。

## とりあえずeslint-plugin-react周りをアップデート

eslint-plugin-react周りが、eslint-plugin-jsx-a11yに対応してくれたみたいなので、
こんな感じでアップデートしたら、またeslintが騒ぎ出した。

```diff:package.json
diff --git a/package.json b/package.json
@@ -43,12 +43,12 @@
     "babel-preset-stage-3": "6.17.0",
     "babel-runtime": "^6.20.0",
     "css-loader": "^0.26.1",
-    "eslint": "^3.12.2",
-    "eslint-config-airbnb": "^13.0.0",
+    "eslint": "^3.13.1",
+    "eslint-config-airbnb": "^14.0.0",
     "eslint-loader": "^1.6.1",
     "eslint-plugin-import": "^2.2.0",
-    "eslint-plugin-jsx-a11y": "^2.2.3",
-    "eslint-plugin-react": "^6.8.0",
+    "eslint-plugin-jsx-a11y": "^3.0.2",
+    "eslint-plugin-react": "^6.9.0",
```

## 考察
下記を見るに、`{props.children}`で渡してるところのpropTypeが悪いようだ。
最初は、型名が変わったのかなと思ったけど、Requiredなら明記しろってことみたい。

#### 該当するコード
```js:Template.jsx
import Helmet from 'react-helmet';

const Template = props => (
  <div>
    <Helmet defaultTitle="jey3dayo.net" />
    {props.children}
  </div>
);

Template.propTypes = {
  children: React.PropTypes.shape({}),
};

export default Template;
```

#### 警告内容
```
app/containers/Template.jsx
  14:3  error  propType "children" is not required, but has no corresponding defaultProp declaration  react/require-default-props
```

## 対応
上記で述べた通り、`isRequired`追記したら黙った。
今後は、propTypes書くときは、Requiredなものか明示的に記載しなければならないようだ。

```diff:Template.jsx
diff --git a/containers/Template.jsx b/containers/Template.jsx
index 750be92..6dde794 100644
--- a/containers/Template.jsx
+++ b/containers/Template.jsx
@@ -9,8 +9,7 @@ const Template = props => (
 );

 Template.propTypes = {
-  children: React.PropTypes.shape,
+  children: React.PropTypes.shape.isRequired,
 };

 export default Template;
```
Cygwin環境作成、その２：「/cygdrive/c」ではなく「/c」でアクセスできるようにする


# fstabを使う方法
と言っても大げさなことではないです。
1．/etc/fstabへの追記

```bash
echo "none / cygdrive binary,posix=0,user 0 0" >> /etc/fstab
```

2．fstabの反映および確認

```bash
$ mount -a
$ mount -p
Prefix              Type         Flags
/                   user         binmode
$ ls /c
'$RECYCLE.BIN'/            'Program Files'/               Windows/       pagefile.sys
 Config.Msi/               'Program Files (x86)'/         Windows.old/   shortcut/
'Documents and Settings'@   ProgramData/                  apps/          swapfile.sys
 HashiCorp/                 Recovery/                     dev/           work/
```

参考：
http://d.hatena.ne.jp/snaka72/20100605/1275733012
http://takuya-1st.hatenablog.jp/entry/20101201/1291187213

# シンボリックリンクを使う方法
すでに/cygdrive/cであれこれリンクやらスクリプトやら組んでいる方向け。至極単純です。

```bash
$ cd /
$ ln -s /cygdrive/c c
$ ls -l
$ ls -la
合計 2.6M
drwxrwx---+  1 lranran Domain Users    0 1月   5 12:36 ./
drwxrwx---+  1 lranran Domain Users    0 1月   5 12:36 ../
drwxr-x---+  1 lranran Domain Users    0 1月   5 14:32 bin/
lrwxrwxrwx   1 lranran Domain Users   11 8月  16 19:59 c -> /cygdrive/c/
dr-xr-xr-x   1 lranran Domain Users    0 1月  12 13:57 cygdrive/
```
Pythonで先月を取得する


`201612`のように、日付はともかく先月の値をとりたかったので書いたコード。

```python
# ライブラリのインポート
import datetime

# 今日を取得
today = datetime.datetime.today()
print today.strftime("%Y-%m-%d")

# 当月1日の値を出す
thismonth = datetime.datetime(today.year, today.month, 1)
print thismonth.strftime("%Y-%m-%d")

# 前月末日の値を出す
lastmonth = thismonth + datetime.timedelta(days=-1)
print lastmonth

# フォーマットを指定して、年月だけ拾う
print lastmonth.strftime("%Y%m")
```

ちょっと手間なやり方ですが、AWS Lambdaで使えるデフォルトのライブラリだけでやりたかったので。
[Unityで学ぶC#] 1 変数の使用

変数は，数学で出てくるx,yのようなものです．

ここでは，概念の説明は避け，使い方のみの説明になります．



# 演習1 変数
 
```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Example1 : MonoBehaviour {

	// Use this for initialization
	void Start () {
		// 変数を宣言する
		int hp; // 1つ目の変数を宣言する．
		int damage; // 2つ目の変数を宣言する．

		// hpへ10を割りあてる
		hp = 10; // hpに10を代入

		Debug.Log ("現在のHP" + hp);

		damage = 3;
		Debug.Log ("ダメージ" + damage);

		hp -= damage; // hp から damageを引き算する
		Debug.Log ("現在のHP" + hp);
	}
}
```

![スクリーンショット 2017-01-12 13.36.07.png](https://qiita-image-store.s3.amazonaws.com/0/113504/9a6a70e3-0657-c8a3-5304-a1fc04b270e1.png "スクリーンショット 2017-01-12 13.36.07.png")

# 今回のスクリプトについて

## 変数の宣言の仕方
```csharp
型 変数名;
```

int は変数が整数であることを示します．

## = の意味
```csharp
hp = 10;
```
=は，「右のものを左につっこむ」と考えていただいて大丈夫です．

数学の「右と左が同じ」という考えとは全く異なりますね．


## -= の意味
左から右を引き算します．


## Debug.Logの()の中で足し算
```csharp
Debug.log("現在のHP" + hp);
```
ここでは()ないで
"現在のHP"とhpを+で繋げています．
+ を使うことで，文字列と変数をひとまとめにできます．



# 参考資料 (もっと詳しく知りたい方)
http://ufcpp.net/study/csharp/st_variable.html
AWS Lambdaと深層学習を組み合わせて、予測APIを作ってみて感じた事


深層学習..と言っても隠れ層は４層くらいの浅いものなのですが、これを利用して予測するAPIを作ってみて感じ事を書き連ねます。


環境
---

* ローカル(Mac)
	* python2.7
* リモート（もちろんLambdaの事)
	* Amazon Linux
	* python2.7
		* （3.x対応はいつ来るのか）



詰まった事
---

今回、この環境を作る上で頭を抱えた事を大きく分けると以下の２つになります。

1. Lambda用に自分のコードを圧縮するには？
2. Macで圧縮したzipをそのままあげても、Lambdaで動かなかった。
3. 作成したzipのサイズはLambdaの許容量を超えていた。

Lambda用に自分のコードを圧縮するには？の話
---

簡単なLambdaのコードだったら、ルートディレクトリに
`lambda_function.py`なんてファイルを作って置いておけば、すぐLambdaにアップロードして試せると思います。
しかし、自分のディレクトリ構成は以下のような構成でした。

```
./src
├── data
│   ├── __init__.py
│   └── data.py
├── __init__.py
├── lambda
│   ├── __init__.py
│   └── lambda_function.py
├── ml
│   ├── hoge_dir
│   ├── __init__.py
│   └── fuga_fir
└── utils
    ├── __init__.py
    └── utils.py
```

LambdaのHandlerの指定も以下のように指定しなければならないほど、実行したいコードが深くにあります。

```
src/lambda/lambda_function.lambda_handler
```

Lambdaで動かすにはimportするサードパーティのライブラリをプロジェクトのルートディレクトリに配置しなければいけません。

#### この配置を手動でやるとかめんどくさすぎるだろ...

が、どうやらクラスメソッドさんの記事を読んでいるとlambda-uploaderとかいう神ツールを使った記事を見つけて自分のコードをLambda用にzip圧縮するということはすんなり解決しました。

クラスメソッドさんの記事は以下
参照：http://dev.classmethod.jp/cloud/deploy-aws-lambda-python-with-lambda-uploader/



Macで圧縮したzipをそのままあげても、Lambdaで動かなかった話
---

なぜこんな事が起きたかというと、"当初"はpythonのライブラリとして以下を利用してコードを書いていました。


* numpy
* scipy
* scikit-learn

実際に、LambdaにzipをアップロードしテストRunしてみると以下のメッセージが...


```
/var/task/numpy/core/multiarray.so: invalid ELF header
```

これはMacとAmazonLinuxという環境の違いがあったため発生した問題です。

この件は公式に書いてある通り、Lambdaと同じ環境でzip化しなければなりません。（少し面倒ですが）
つまり、EC2を立ち上げてそこに同じような環境を作って、先ほどのlambda-uploaderを使うということになります。

参照：https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/current-supported-versions.html


作成したzipのサイズはLambdaの許容量を超えていた話
---

当初は以下のライブラリをつかっていました。

* numpy
	* numpyに関しては行列演算のため
* scipy
	* scikit-learnのため（うろ覚え）
* scikit-learn
	* データの標準化を行いたかったため
* pandas
	* csvデータの扱い


つまりpython上では以下の処理をさせていました。

1. Lambdaに入力されたデータを`scikit-learn`で標準化
2. S3に置いてある重み、バイアスのcsvデータを`boto3`と`pandas`を使って行列に変換
3. 手順1, 2のデータを使って予測

これをいざ、Lambdaでrunさせてみると以下の警告が...

```
Unzipped size must be smaller than 262144000 bytes
```

AWS Lambdaのデプロイメントの制限に引っかかっていたわけですね。
参照：https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/limits.html

#### これは非常に厄介

結論からどういう対応を行ったかというと、

* lambda-uploaderで圧縮される対象を絞った。（ignore設定を行った)
* `scipy`,`scikit-learn`を使わない実装にした。
	* ここを利用しているのはデータの標準化のみです。つまり、`numpy`だけでも同じ処理を実装することができます。

ただ、これはどの案件にも言える話ではないので、たまたま運が良かっただけですね...

感想
---

デプロイメントの制限は緩和して欲しいですね。（こういうケースはECSを使って欲しいのかもしれませんが...)
Go 言語で要素数を指定した組み合わせを列挙する

# はじめに

* [前回](http://qiita.com/nirasan/items/54fa87378e55b7f64964) は全要素での組み合わせの列挙をしてみたが、今回は要素数を指定した組み合わせの列挙を行う。

# 全要素の組み合わせから指定の要素数の組み合わせを抽出する

* 前回作成した全要素の組み合わせの列挙を行い、結果から指定の要素数の組み合わせを抽出する。
* 明らかに無駄が多いがとりあえず一番ナイーブな実装から。

```go:github.com/nirasan/algo/blob/master/combination.go#L3
func Combination1(nums []int, n int) [][]int {
	ps := Powerset2(nums)
	result := make([][]int, CombinationCount(len(nums), n))
	index := 0
	for _, s := range ps {
		if len(s) == n {
			result[index] = s
			index++
		}
	}
	return result
}

// 中略

func CombinationCount(n, m int) int {
	return Fact(n) / (Fact(n-m) * Fact(m))
}

func Fact(n int) int {
	if n == 0 {
		return 1
	} else {
		return n * Fact(n-1)
	}
}
```

# ビット操作で組み合わせのパターンを列挙する

* http://blog.livedoor.jp/dankogai/archives/51857323.html にある解法の移植
* 2 進数表現で選ぶ選ばないを表現し列挙するのは前回も使った方法
* `Combination2NextIndex` によって 2 進数で特定の数だけ 1 が立っている数を順次生成することができるのでこれを利用して列挙する

```go:github.com/nirasan/algo/blob/master/combination.go#L16
func Combination2(nums []int, n int) [][]int {
	size := len(nums)
	result := make([][]int, CombinationCount(len(nums), n))
	bi := (1 << uint(n)) - 1
	max := 1 << uint(size)
	index := 0
	for bi < max {
		bi = Combination2NextIndex(bi)
		flags := bi
		s := []int{}
		for _, n := range nums {
			if flags%2 != 0 {
				s = append(s, n)
			}
			flags /= 2
		}
		result[index] = s
		index++
	}
	return result
}

// 中略

func Combination2NextIndex(n int) int {
	// (1) 2 進数で 1 になっている一番下の桁を取得
	smallest := n & -n
	// (2) 1 になっている一番下の桁に 1 を足す
	ripple := n + smallest
	// (3) 新たに 1 になっている一番下の桁を取得
	newSmallest := ripple & -ripple
	// (3) / (1) で (2) の操作により増えた 0 の数（失われた 1 の数）が算出され
	// - 1 することで補填するべき 1 のビット列を取得する
	ones := ((newSmallest / smallest) >> 1) - 1
	// ripple に ones を補填して新しいインデックスとする
	return ripple | ones
}
```

# 比較

* やはり dankogai 氏のマジカルな実装が実行速度とメモリ効率ともに素晴らしい。

```
BenchmarkCombination_5to3/Combination1-4                  500000              3334 ns/op            1736 B/op         33 allocs/op
BenchmarkCombination_5to3/Combination2-4                  500000              2964 ns/op             768 B/op         30 allocs/op
BenchmarkCombination_10to3/Combination1-4                  20000            104392 ns/op           72624 B/op       1025 allocs/op
BenchmarkCombination_10to3/Combination2-4                  30000             45778 ns/op            9760 B/op        360 allocs/op
PASS
ok      github.com/nirasan/algo 8.124s
```

# 参考 URL

* [明日使えないすごいビット演算](http://www.slideshare.net/KMC_JP/slide-www)

# ソースコード

* https://github.com/nirasan/algo/blob/master/combination.go
* https://github.com/nirasan/algo/blob/master/combination_test.go
gitで日本語のファイルを扱うときに数字コードが表示される

### git status で日本語のファイル名を表示できなかった

```
git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        "memo/\343\201\246\343\201\231\343\201\250.txt"
```

### 対応策
gitの設定を変えてやればいい

`git config --local core.quotepath false`

↓設定反映後

```
git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        memo/てすと.txt
```

### その他
ちなみに.gitconfigに記載する場合は下記の[core]のブロックを追加してやればいい

``` .gitconfig
[alias]
	st = status
	ci = commit
	co = checkout
	bra = branch
[user]
	name = KTakata
	email = hogehoge@test.com
[gui]
	encoding = utf-8
[core]
	quotepath = false　

```
Jupyter NotebookをMacで動かしてみる

## What's this?

Wantedlyさんの [Jupyterで触れながら学ぶ機械学習速習会＠Wantedly](https://wantedly.connpass.com/event/47621/) という勉強会に参加するにあたりJupyterの環境をつくってみました。

ちなみにMacはOS X El Capitan（10.11.6）です。

## STEP1: Pythonインストール

brewなりで適当にPythonの2系をインストールしておいてください。

## STEP2: scikit-learnインストール

機械学習ライブラリ？であるscikit-learnをインストールします。
事前にいくつかパッケージをインストール。

```
$ pip install numpy
```

```
$ pip install scipy
```

```
$ pip install scikit-learn
```

## STEP3: Jupyterインストール

最後にJupyterをインストールします。

```
$ pip install jupyter
```

```
$ mkdir machine-learning
$ cd machine-learning/
```

適当にディレクトリをつくって、そこで、

```
$ jupyter notebook
```

Jupyter Notebookを起動すると、

![image](https://qiita-image-store.s3.amazonaws.com/0/48990/5f8eb466-587f-5ec7-3232-b02f95e6f25a.png)

上記のような画面が起動します。

おしまい。
特に問題なく出来ました。（たぶん）

## まとめ

まだ勉強会前なのでJupyterが何者なのかあんまり分かってないが、ひとまず環境は出来ました。

## 参考サイト

* Mac OS X 10.9.4にpython2.7開発環境+scikit-learn実行環境構築
  * http://entropiajp.hatenablog.com/entry/2014/08/21/212552
* Installing scikit-learn
  * http://scikit-learn.org/stable/install.html
* Project Jupyter | Install
  * http://jupyter.org/install.html
markdown-mode でコードをシンタックスハイライトする

`mmm-mode` を使用する。
`web-mode` が登場してもう `mmm-mode` のお世話になることはないだろうと思っていた。
けれど `markdown-mode` の登場で再度お世話になることになった。

`mmm-mode` で定義を追加するには一般的には `(mmm-add-classes)` `でmmm-class`を作っておいて `markdown-mode` を `(mmm-add-mode-ext-class)` する。
そうすれば `markdown-mode` で `mmm-mode` をして parse させればシンタックスハイライトされる。

しかしMarkdownで書きたいコードの種類は無数にあるし、パターンが決まっているので楽に定義したい。
ということで下記を設定した。

https://github.com/magnars/dash.el は必須

必要に応じて2行目にメジャーモードの名前を追加する。

```el
(with-eval-after-load "mmm-mode"
  (-each '("sh" "plantuml" "dos" "css" "js2" "web" "emacs-lisp") ;; 引数にメジャーモードの関数 -mode を抜いた文字列のリストを渡す
    '(lambda (mode-name)
       (let ((md-class (intern (concat "markdown-" mode-name))))
         (mmm-add-classes
          (list (list md-class
                      :submode (intern (concat mode-name "-mode"))
                      :face 'mmm-declaration-submode-face
                      :front (concat "^```" mode-name "[\n
]+")
                      :back "^```$")))
         (mmm-add-mode-ext-class 'markdown-mode nil md-class)))))

```

markdown-mode で下記のように記述すると、コードブロック内のみ該当のメジャーモードで記述できる。

![2017-01-12_12h57_16.png](https://qiita-image-store.s3.amazonaws.com/0/10012/caad6e8e-0a53-4fdd-da7e-e30cddae1ad3.png)
Google Drive の画像を HTML WebSiteで表示する

 
GoogleDrive上にある画像

https://drive.google.com/open?id=0B5XyfEvaaEXjTFdnR3J6NUd5SnM

このURLの `open` を `uc` に変換する 

https://drive.google.com/uc?id=0B5XyfEvaaEXjTFdnR3J6NUd5SnM

このURLなら img タグの src にぶち込んでもうまいこと動作する。

Qiita でも以下のような形で使えるので便利

````
![chatbox logo](https://drive.google.com/uc?id=0B5XyfEvaaEXjTFdnR3J6NUd5SnM)
````

![chatbox logo](https://drive.google.com/uc?id=0B5XyfEvaaEXjTFdnR3J6NUd5SnM)
jupyter で、IPアドレスから、国、都市名を割り出す

jupyter でちょっと便利なツールをつくっています。
今回は、IPアドレスから、国、都市名を割り出すスクリプトです。


# geoip の設定

jupyter で使うことを念頭においています。
https://github.com/maxmind/geoip-api-python  にしたがってインストール

ＩＰアドレスと地域を結びつけるデータベースをダウンロードする必要あり

```
# データは、http://dev.maxmind.com/geoip/geoip2/geolite2/ にあります。無料のものです。（精度が高いのは有償です。）
# どの形式でどこにダウンロードするかですが、とりあえず、下記のようにします。
# mkdir /usr/local/share/GeoIP/
# cd /usr/local/share/GeoIP/
# wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz
# gunzip GeoLite2-Country.mmdb.gz
# wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz
# gunzip GeoLite2-City.mmdb.gz
```
# ここからがスクリプトのサンプル
```
import geoip2.database
# データベースの読み込み
reader = geoip2.database.Reader('/usr/local/share/GeoIP/GeoLite2-City.mmdb')
ip_addr = '202.232.86.11'
record = reader.city(ip_addr)
print(record.country.names['ja'])
print(record.city.names['ja'])
print(record.country.names['en'])
print(record.city.names['en'])
```

結果はこれです。
```
日本
東京
Japan
Tokyo
```
RailsのStringクラスにemail?メソッドを追加する

## 作ったもの
```ruby
'hello'.email? #=> false
'hello@world.com'.email? #=> true
```

## コード

### Ruby 2.4
```ruby:config/initializers/validations.rb
class String
  def email?
    self.match? /\A[^@\s]+@[^@\s]+\z/
  end
end
```

### Ruby 2.3 以前
```ruby:config/initializers/validations.rb
class String
  def email?
    self.match /\A[^@\s]+@[^@\s]+\z/
  end
end
```

## 補足

正規表現にはDevise 4.2.0にて`Devise::email_regexp`として定義されている`/\A[^@\s]+@[^@\s]+\z/`を使っています。(`.`等を見ないので結構緩めです)

Deviseインストール済みなら上記のコードの該当部を`self.match? Devise::email_regexp`と置き換えても同じ事が出来ます。（当然ですが…汗）

Ruby 2.4 以降にはマッチしたかどうかを true or falseで返す高速な `match?` メソッドが追加されたので、そちらを使っています。
Android(というかLinux)でアプリに割り当てられるホームディレクトリのパスを取得

※備忘録です
実行すべきコマンドは`sh -c "cd; pwd"`なので、

```Java
new ProcessBuilder(new String[]{"sh", "-c", "cd; pwd"}).start()/*以下略*/;
```
使い道は[Parallel Space](https://play.google.com/store/apps/details?id=com.lbe.parallel.intl)上か直接起動しているかを判別する、など
両方で異なる値となるのでそれを比べれば良い。 参考までに、[Nexus 5X上での値](https://plus.google.com/+nao20010128naoX/posts/joqSKEWoCwJ)。
Riot.jsベースのお手軽開発環境「Yosegi」を公開しました

※ 2017/07/21追記
Riot v3とWebpack v3に対応しました。
その他package.jsonも更新済みです。

## はじめに

Riot.jsがんばれ。
そんな思いから生まれたRiot.jsベースのお手軽開発環境「 Yosegi 」を公開しました。 
https://github.com/hisayatanaka/yosegi

導入は基本 npm install 一発で完了。
ES6/Sass対応でWebpackによる自動コンパイル＆バンドル（minify）、ブラウザリロードまで面倒を見てくれるパッケージです。あくまでも基本フレームとなりますので、お好みで自由にカスタマイズしながらご利用ください。

Google Compute Engineでの導入手順もまとめましたので、慣れた方なら10分程度で環境が構築できると思います。コンポーネント指向なフレームワークは敷居が高そう…そんな方でも手軽に導入し、魅力を体感いただける、そんなパッケージを目指しました。

Riot.jsがんばれ！

## 特徴

* 手軽にRiot.jsベースのWeb components的開発環境をセットアップ
* ES6対応 (Babelにより自動的にES5へトランスパイル)
* Sass対応 (Riotタグ内で利用可)
* ブラウザの自動リロード (Browsersyncによる更新監視)
* Webpackによるコンパイルとバンドルの自動実行 (minifyも)

## 動作環境

* nodejs
* Sass
* Compass

## インストール

リポジトリを任意の場所にクローン。

```
https://github.com/hisayatanaka/yosegi.git
```

ディレクトリに移動して以下のコマンドを実行。 

```
$ npm install
```

以上。

## 使い方

はじめにcompass watch(compile)の実行とhttpサーバの起動が必要です。

```
$ compass watch (or compass compile)
$ npm start
```

Browsersyncのhttpサーバが起動します。
デフォルト設定のままであれば下記URLでアクセス可能です。

```
http://localhost:3000
```

1. モートサーバを利用している場合はlocalhostを適宜置き換えます
2. 3000番ポートの開放が必要です（UIモード利用時は3001番も）

ローカルサーバ上であればブラウザが自動起動します。
もしリモートサーバ上であれば「Couldn't open browser」エラーが表示されます。この場合でも手動でアクセスを行えば、正常に自動リロード機能は動作します。

## 専用のhttpサーバを利用する場合 (Nginxなど)

Browsersyncには「proxy」オプションがあります。  

#### bs-config.js

```js:bs-config.js
"proxy": {
  target: "127.0.0.1:80",
  ws: true
},
```
_参考： [Browsersync options](https://www.browsersync.io/docs/options#option-proxy)._

プロキシ経由でnginxに接続し、異なるポート番号（例：8080）で別のソケットサーバに接続することもできます。これはgolangを併用する開発に有用です。

## Google Compute Engineでのセットアップ例

1. CentOSでインスタンスを起動
2. GCEのネットワークルールで3000-3001番ポートを開放
3. ブラウザ上からSSHプロンプトを開く（一覧の`SSH`をクリック）
4. 以下の`yum install`コマンドを順に実行
5. 上記手順に従いYosegiをインストール
6. compass compileを実行しhttpサーバを起動
7. `http://[External IP]:3000`にアクセス

```
$ sudo yum install git
$ sudo yum install epel-release
$ sudo yum install nodejs npm --enablerepo=epel
$ sudo yum install ruby
$ sudo yum install ruby-devel
$ sudo yum install rubygems
$ sudo yum install gcc
$ sudo gem update --system
$ sudo gem install sass
$ sudo gem install compass
```

## スナップショット

![Snapshot](https://github.com/hisayatanaka/yosegi/wiki/img/yosegi_screen.png "Snapshot")

## 基本構造

* 基本 `src` の中身を元に各種コンパイル等がなされ `dist` に出力されます
* `img` `js` `css` は静的ディレクトリです（自由に変更/削除可能）
* `.babelrc` はBabelの設定ファイル
* `bs-config.js` はBrowsersyncの設定ファイル
* `config.rb` はSassの設定ファイル
* `webpack.config.js` はWebpackの設定ファイル
* `package.json` はnpmの設定ファイル

## 参考リンク

[Riot.js](http://riotjs.com/v2/ja/ "Riot.js")
[Browsersync](https://www.browsersync.io/ "Browsersync")
[Webpack](https://webpack.github.io/ "Webpack")
[Babel](https://babeljs.io/ "Babel")
[Sass](http://sass-lang.com/ "Sass")
[Compass](http://compass-style.org/ "Compass")

## ライセンス

MITライセンスに準拠します。
詳細は`LICENSE`ファイルをご確認ください。
パワポに波線をかきたいよ

#資料をパワポでつくる苦行
上司に言われて書きたくもない資料を書くわけだけど
書くからにはそれなりに仕上げたい。

#強調表示にイタリックとかいやだから
下線でもいいけど波線のほうがかっこいいかなぁ
そもそも波線もかっこわるいとかいわないで

#波線を引く方法
「パワポ　波線」で出てきたのは
グリッドに合わせてオートシェイプの曲線で波線を書く荒業…
いったいだれがやりたがるんだろ？
そもそもこの方法だと何となくいびつ…

#そうだ！
サイン波だったら見た目きれいじゃない？
→Excelでグラフつくって貼り付けたろ！
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/122215/d61da9b5-7ef2-aff7-d922-676e75fea2f8.png)

###できた
グラフのいらないところを削除して完成。
パワポに貼ったときにグラフオブジェクトになるのは愛嬌で…
Angular2のファイルをSpring Bootのプロジェクトファイルと統合する

参考にしたのはこちらの[stack overflow](http://stackoverflow.com/questions/41407237/spring-boot-angular-2-structure)
です


## 前提〜それぞれのプロジェクト作成する

Angular2: Angular Cli
Spring: Spring Initializer

でそれぞれ作成して、そのあとにフォルダを統合したい、というのが今回の記事の話題です。


## 統合の理由

そのままそれぞれ別のサーバで動作させる、とか[AngularでProxyの設定をする](http://tc.hatenablog.com/entry/2017/01/02/185917)という運用もあるかと思うのですが、Web UIもWeb APIも自社で作成するので、一つのWebサーバにする、一つのサーバプロセス（Tomcat）を監視する、それをAWSのElastic Beanstalkにデプロイしたら便利かな、と考えたのが始めです。

他に便利な運用があれば、統合しなくてもよいのかもしれないです。


## フォルダ構成

Spring Initializerやmavenで、Web Applicationプロジェクトの雛形を生成して、そのフォルダにangular2のフォルダを移動させます。

|階層1 |階層2 |階層3|階層4|説明|
|:-----|:----|:----|:---|:---|
|main|   ||||
|    |src||||
|    |   |java|||
|    |   |angular2||★angular2のプロジェクトルートフォルダを置きます。この中にangular2プロジェクトの.gitignoreファイルも含んでいます。（後述）|
|    |   |resources|||
|    |   |        |static|★ここをangular2のコンパイルのoutput先に指定します|

## 手順

この構成を作成するときの手順です。

1. それぞれのプロジェクトフォルダを作成する
2. Angular2のコンパイル先フォルダを修正する
3. 元のプロジェクトに対して、Gitに登録しないファイルが増えるので、.gitignoreを作成・追記・修正する
4. デプロイする際は、Angular2のソースを修正→ng buildコマンドを実行、それからSpringBootをwarファイルにする

## Angular2のコンパイル先フォルダの修正

```src/main/angular2/angular-cli.json
  "apps": [
    {
      "root": "src",
      "// outDir": "dist",
      "outDir": "../resources/static",
      "assets": [
```

上記jsonファイルの"outDir"がコンパイル先フォルダなので、これをSpringBootのWeb Applicationのドキュメントルートフォルダである、resources/staticに指定します。

angular-cli.jsonは、angular cliで雛形を生成すると、angular2のプロジェクトルートフォルダにあります。

注意点としては、ng buildでコンパイルしたときに、staticフォルダごと一回消して再生成するので、staticフォルダの中には何も入れてはいけないことです。


## .gitignoreの追加・修正
angular2のプロジェクトルートフォルダに.gitignoreがあれば、それをそのまま他のソースと一緒にコピーして持ってきます。
そして、.gitignoreファイルをSpringBootプロジェクトのリポジトリに追加すれば、.gitignoreが有効に働きます。無視すべきフォルダについては、下記に.gitignoreの内容を引用します。

```src/main/angular2/.gitignore

# See http://help.github.com/ignore-files/ for more about ignoring files.

# compiled output
/dist
/tmp

# dependencies
/node_modules

# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/

# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

# misc
/.sass-cache
/connect.lock
/coverage/*
/libpeerconnection.log
npm-debug.log
testem.log
/typings

# e2e
/e2e/*.js
/e2e/*.map

#System Files
.DS_Store
Thumbs.db
```


Angular2プロジェクトのコンパイルソース出力先のresources/staticも、リポジトリの管理から外します。

```src/main/resources/.gitignore
# See http://help.github.com/ignore-files/ for more about ignoring files.

# compiled output
/static
/tmp

# dependencies

#System Files
.DS_Store
Thumbs.db
```

これで設定は完了です。ng build後にwarファイルを作成、デプロイして動作確認をしてください。
PowerShellで生成したパスワードを暗号化して保存する

前回書いた[PowerShellでパスワード生成](http://qiita.com/Takeru/items/da17c8ae9122bca6f2d4)には続きがあります。

問題は生成したパスワードを忘れちゃうこと。なので、生成したパスワードを生成日時とともにログに残しましょう。とはいえ、プレーンテキストで残してしまうとパスワードの意味がありません。

## SecureStringを介して暗号化する
WindowsにはSecureStringというものがあります。（よく理解していませんが…）

プレーンテキストを暗号化するためには一旦プレーンテキストをSecureStringに変換後、暗号化された文字列に変換します。これをログに残すことにしましょう。

例えば"password"という文字列を暗号化してみます。

```
(*'-') >> $secure = ConvertTo-SecureString "password" -AsPlainText -Force
(*'-') >> $secure
System.Security.SecureString
```

このようにマスクされて内容がわからなくなります。これをさらに暗号化された文字列に変換します。

```
(*'-') >> $encrypt = ConvertFrom-SecureString -SecureString $secure
(*'-') >> $encrypt
01000000d08c9ddf0115d1118c7a00c04fc297eb01000000f01bb26b297c5c49be1c148addfcc00f0000000002000000000003660000c0000000100000006e1b3680bc87a3956426cc8bf3c8f03c0000000004800000a000000010000000b932a8b7cc446dd1a5d7c28d88f106bb18000000c8ad080bc460351ab8a64fa1ec53b466a636fd3012b0b35e140000005f384b07721a9675ec72b8724574ab235792e5e8
```

暗号化された文字列が取得できました。

## パスワードを生成日時とともにログに残す
前回の[PowerShellでパスワード生成](http://qiita.com/Takeru/items/da17c8ae9122bca6f2d4)コードにちょいと付け足し。

```
$passwd=""
foreach ($n in 1..$(Get-Random -min 8 -max 16)) {
  $passwd=$passwd+$(Get-Random -input 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z)
}
$passwd
$encrypt=ConvertFrom-SecureString -SecureString (ConvertTo-SecureString $passwd -AsPlainText -Force)
(Get-Date -uformat "%Y/%m/%d %H:%M:%S")+" "+$encrypt >> ~/passwd.log
```

`Get-Date`は`-uformat`オプションを使うとunixの`date`コマンドと同様の書式で出力フォーマットを指定できるようになります。これと暗号化された文字列を１行にまとめて、ホームディレクトリ内のログファイルに追記してゆきます。

## パスワードを復号する
当初の目的は *パスワードを忘れないようにすること* でした。自動生成できてらくちんでも、６ヶ月前に生成したパスワードが暗号化されていてなんだかわからないでは片手落ちです。

復号もまた`ConvertTo-SecureString`を使用します。先ほど`$encrypt`に保存された暗号化された文字列を元の"password"に戻してみます。

```
(*'-') >> $decrypt = ConvertTo-SecureString -String $encrypt
(*'-') >> $decrypt
System.Security.SecureString
```

```
(*'-') >> $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($decrypt)
(*'-') >> $BSTR
42806504
```

```
(*'-') >> $plaintext = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($BSTR)
(*'-') >> $plaintext
password
```

戻った！(๑•̀ㅂ•́)و✧

[復号用スクリプトをGithubにあげてみました。](https://github.com/Takeru-chan/mkpass)
Cannot convert 'lambda expression' to non-delegate type 'UniRx.IObserver<hogehoge>'というエラー

#概要
UniRxをプロジェクトを使っている際に
イベントを受け取る側で
Cannot convert 'lambda expression' to non-delegate type 'UniRx.IObserver<hogehoge>'というエラー
とでていた


# 原因
using UniRx;をイベント受け取る側に記載するのを忘れていた

# 解決方法
using UniRx;をイベント受け取る側に追加

# 補足
MonoDevelopでエラーが出る行で右クリックしても、
いつもの自動using追加はできないのではまった。
Nginxで躓いたところ及びメモ

さくらVPSにNginxをいれたらいろんな問題が起ったり、メモしたいことがあったのでメモ。

# ホームディレクトリにシンボリックリンクをはると「403 Forbidden」
アクセスするディレクトリにホームディレクトリからシンボリックリンクをはったものを適応させると「403 Forbidden」が出た。
default.confにも問題ないし、シンボリックリンクやホームディレクトリにおいてあるソースディレクトリにchownしてもchmodしてもだめ。

## 解決法
/home/userディレクトリ自体のパーミッションを変えるとOK。

```
chmod 755 /home/user
```

# phpMyAdminにログインできない
phpmyadminで以下のエラー

```
Cannot start session without errors, please check errors given in your PHP and/or webserver log file and configure your PHP installation properly.
```

## 解決法
大抵、php.iniの「session.save_path」で指定しているのディレクトリのパーミッションの問題。

```
sudo chown nginx:nginx /var/lib/php/session
```

# nginxでwordpressのパーマリンクをデフォルト以外に対応する
WPとかでパーマリンクデフォルトのやつ使ってない時は以下のように対応
[nginxでwordpressのパーマリンクをデフォルト以外に対応する](http://qiita.com/egnr-in-6matroom/items/a08f4851bf16d0131e60)

# そもそもVPSにNginx入れるとき
[さくらVPSにnginx/PHP/MySQLをインストールする手順](http://qiita.com/honmaaax/items/193826d23cccc900f5c5)

# よく使うNginxにまつわるコマンド
*  設定ファイルをいじる `sudo vi /etc/nginx/conf/***.conf`
* 起動 `sudo service nginx start`
* 再起動 `sudo service nginx restart`
* コンフィグテスト `sudo /etc/init.d/nginx configtest`
DB上で nil と nil は別のものとして扱われるのでRailsで対策として partial indexを使う方法

`instant` か `start_date`, `end_date` の二つのどちらかにだけ値が入るモデルがあって、こんな index を作ってたんですが、

```.rb
add_index :foos, [:name, :instant, :start_date, :end_date], unique: true
```

これでは`nil`がDB上ではそれぞれ異なる値として処理されるために unique 制限が全く働いてくれませんでした。

### 対策

`where`を使って`partial index`を作り対策しましょう。

    add_index :foos, [:name, :start_date, :end_date], unique: true, where: 'instant IS NULL'
    add_index :foos, [:name, :instant], unique: true, where: 'start_date IS NULL and end_date IS NULL'

### 参考

http://rny.io/rails/postgresql/2013/08/20/postgresql-indexing-in-rails.html
Azure functions へのdeploy方法とnpm packageのinstall方法


Azure functions上でnode.jsを動かせますが、開発していくうえで必要な

 * deploy方法
 * npm packageのinstall方法

を整理しておきます。

# deploy方法
functionsへのdeploy方法は、画像の`ソースの選択`の一覧にあるだけの方法が用意されており、今回はローカルのgitリポジトリを解説します。


## ローカルgit 
設定方法は、[ポータル](https://portal.azure.com)の対象のfunctionsを選んだ画面から、(0)Function Appの設定 -> (1)App Serviceの設定に移動 -> (2)デプロイオプション -> (3)ソースの選択 -> (4)ローカルGitリポジトリ -> OK
となります。
![azure_functions_local_git_repogitory.png](https://qiita-image-store.s3.amazonaws.com/0/1533/aee61ced-55dc-82eb-74f1-a3381854b119.png "azure_functions_local_git_repogitory.png")


###認証アカウント作成
認証用アカウントが未作成なら、認証用アカウント作成します。
![functions_auth_setting.png](https://qiita-image-store.s3.amazonaws.com/0/1533/3df5e076-6814-55d8-23b1-f6aa565befa5.png "functions_auth_setting.png")


###プロパティからpush先を確認
上記、ローカルgitとの連携ができていれば、プロパティからgit urlが確認できます。
![Azure_functions_git_url.png](https://qiita-image-store.s3.amazonaws.com/0/1533/ed6b837c-1bb7-06b2-3b4b-7605b5649c43.png "Azure_functions_git_url.png")


これがpush先のURLになります。

###ローカルのgit環境構築
ローカルの作業用ディレクトリ内で

```
git init
git remote add origin 確認したurl
```
remote addは必須ではないですが、しておくと楽です。

###ソースの同期
functions作成時、だいたいの雛形でデフォルトで作られる、`index.js` と`function.json`という２ファイルありますが、最初はリポジトリ管理内には存在しません。なので、一旦index.jsは、コピペするなりしてローカルに用意しましょう。

```
vi index.js
```
※function.jsonは、直接触るよりもポータルから変更する場合が多いので、最初はリポジトリで管理しなくていいかと思います。

###package.json追加

あとは、適当な修正を加えた後commit & push すれば、デプロイされます。
が、その前にnpm packageインストール用にpackage.jsonを追加しておきましょう。

```
npm init
```

###deploy
あとは、commit & push です。

```
git add .
git commit -m 'comit comment'
git push
```

これでデプロイされます。
処理フローとしては、git push -> azure上のリポジトリ反映 -> functions上にソース展開 -> npm install

というのが流れになります。

※注意、OSに依存するようなpackageはfunctions上でinstallできない場合があります。ただ、これは後々改善されるかもしれません。

## FTP
git連携でも構わないのですが、もっと、修正→動作確認のサイクルを早く回したい場合、FTPによるデプロイがおすすめです。


### プロパティからFTP接続情報参照
以下を参考に、FTP接続したらあとは修正ファイルをアップするだけで、デプロイ完了です。
![Azure_functions_ftp_property.png](https://qiita-image-store.s3.amazonaws.com/0/1533/ffef4f05-9053-39d1-6003-a60d1d2cb953.png "Azure_functions_ftp_property.png")

※上記、認証アカウント作成済み前提


このとき *アップロード後すぐ反映*されることがポイントで、gitによるdeployのときのように、自動でいろんな処理が走らない分、すぐに動作確認できます。

昔ながらの、レンタルサーバにFTPでファイルをアップするデプロイ方法と同じ感覚ですね。

ただその代わりnpm installが実行されないため、packageの追加・修正等の反映は、手動で実施する必要があります。

### npm installを手動で実行する方法
functionsに付随するkuduというサービスに、コンソール画面が用意されています。

####kudu console
ポータルのfunctionsを選んだら、Function Appの設定 -> Kuduに移動
![Azure_functions_to_kudu.png](https://qiita-image-store.s3.amazonaws.com/0/1533/83db56cc-3d73-3c52-c187-23a02eff6edb.png "Azure_functions_to_kudu.png")

そうすると別タブでKuduのコンソール画面に移動します。
![Azure_kudu_console.png](https://qiita-image-store.s3.amazonaws.com/0/1533/e42e1440-3e67-c223-9133-f47ab32822c9.png "Azure_kudu_console.png")


ここでは、簡単なlinuxコマンド（cd,ls等）が使えます。画面上側のディレクトリファイルをクリックしながらでもいいのですが、該当の関数（今回はfunc1）まで移動します。
作った関数たちは`/site/wwwroot/`内にいるので、

```
cd site/wwwroot/func1
```

ここまで移動したら、package.jsonがあることを確認し、

```
npm install
```
を実行します。少し時間はかかりますが、packageをinstallしてくれます。
※うまく反映されない場合、node_modulesディレクトリを削除してnpm install し直せば反映される場合があります。

# まとめ
 * deploy方法としてローカルgitとFTPを紹介
 * ローカルgitはpushしたらソースのデプロイ、npm installまでしてくれる
 * FTPは、ソースアップしたらすぐ反映される。npm installが必要な時、kudu konsoleから手動で叩く