OmniAICreator/Qiita-1.07M huggingface dataset:
Gitでコミットの内訳(加減行数)を指定された月毎に可視化する

## 20170307追記

- `git shortlog --after=YYYY-mm-dd --before=YYYY-mm-dd` でなぜかプロジェクトのコミット内容がうまくいかなかった
- 解決策としては当月であれば、当日までにするとよいと思う。
- 自宅の個人端末でLaravelのプロジェクトを見た限りでは特に問題なかった
- 謎は深まるばかり・・

## やりたいこと

- 今のプロジェクトはgithubを使っていないのでコミット状況がわかりにくい
- とりあえず
    - 期間指定できて
    - コミッタ毎に
    - コミット数と差分行数がわかればいい
- 出来そうなので、作ればいい！

## やったこと

- Gitコマンドで期間指定する方法があるか調べる
    - `--before`オプションと`--after`オプションがあるよ！

```
$ $ git log --after='2016-11-01' --before='2017-12-01'
```

- 差分抽出をどうすれば見れるか
- 思いつかなかったのでggrksして
    - [Gitの貢献度？を計るワンライナーたち](http://qiita.com/digdagdag/items/e577611a032abc148664)あたりを参考に

## 出来そうなので作る

```bash
#!/usr/local/bin/bash

set -ue

if [ $# -ne 1 ] ; then
    echo "USAGE: $0 201702"
    exit
fi

if [[ ! "${1}" =~ ^[0-9]{6}$ ]] ; then
    echo "USAGE: $0 201702"
    exit
fi

started_at="$(echo "${1}" | sed 's/\([0-9][0-9][0-9][0-9]\)\(.*\)/\1-\2-01/')"
ended_at="$(date +'%Y-%m-01' -d "${started_at} +1 month")"
echo -e "\e[36m${started_at}-${ended_at}間のコミット状況\e[m"

git shortlog -s --after="${started_at}" --before="${ended_at}" | sort -nr | while read line ; do
    echo -e "$(echo "${line}" | sed 's/\([0-9]*\)/\\e[33m\1\\e[mcommits/')"
    author="$(echo ${line} | sed 's/  */ /g' | cut -d' ' -f2- | tr '\t' '.')"
    result="$(git log --numstat --pretty="%H" --author="${author}" --after="${started_at}" --before="${ended_at}" | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("%d %d\
", plus, minus)}')"
    echo -e "\e[32m+$(echo ${result} | cut -d' ' -f1)\e[m \e[31m-$(echo ${result} | cut -d' ' -f2)\e[m
"
done
```

## 出力結果

- サンプルにはLaravelのプロジェクト(branch: 5.2)を利用させていただきました

![スクリーンショット 2017-02-25 18.47.45.png](https://qiita-image-store.s3.amazonaws.com/0/39699/075176e2-b34f-7b48-b472-a69b475bbe83.png)

## Macで使用する場合

- dateコマンドがGNU標準ではないので下記に注意してください
    - coreutilsをインストールして、gdateを使う
    - vオプションを利用する
- 自分はcoreutilsを利用しています

## あとがき的な

- 正直、コミット数とか行数なんて見ても大した意味ない
    - ステップ数文化みたいなもん
- 前回書いた[PHPで循環的複雑度をコミッタ毎に可視化する](http://qiita.com/s-age/items/c41d8cb57124e60422a8)と組み合わせることで
    - 誰が
    - どれくらいの量を
    - こみっとしているか
- に加えて、
    - どの程度のメソッドが生やされ
    - それらの複雑度が本人の平均値にどう影響するか？
- といった分析が可能になると思います
- 循環的複雑度を計測するスクリプトよりも先にこちらを書いていましたが、正直これ単体だとあまり意味がないので順番が前後しましたね
Macのファイル名に使われるNFDなUTF-8（通称UTF-8-MAC）を通常のUTF-8に変換

Mac だとファイル名に濁音や半濁音が2文字扱いになる ~~ので、いろいろと困ることがあります[^1]。な~~ のでフツーの UTF-8 に戻したい ~~ですね~~。
というメモです。
#やりかた
くわしいことはさておき、2行で済ませます。
#NKF ライブラリでやる
```ruby
require 'nkf'
filename_utf_8 = NKF.nkf('--ic=UTF-8-MAC -w', filename_utf_8_mac)
```
#`String#encode` でやる（2017/2/27追記）
Ruby 1.9以降だとあんまり NKF でやるのはどうかな、と思いますし、コメントでもご指摘頂きましたので、（NKF ライブラリを使わずに） [`String#encode`](https://docs.ruby-lang.org/ja/latest/method/String/i/encode.html) でやってみましょう。

```ruby
filename_utf_8 = filename_utf_8_mac.encode(Encoding::UTF_8, Encoding::UTF8_MAC)
```
気付いたのは [`Encoding::UTF_8`](https://docs.ruby-lang.org/ja/latest/method/Encoding/c/CP65001.html) って書くところ。`Encoding::UTF8` じゃダメなんです。でも [`Encoding::UTF_8_MAC`](https://docs.ruby-lang.org/ja/latest/method/Encoding/c/UTF8_MAC.html) は `Encoding::UTF8_MAC` でもいいんです。なんでよぉ。

#参考
>###オプション文字列

>```
>-j -s -e -w -w16 出力するエンコーディングを指定する
  -w UTF-8 を出力する(BOMなし)

>--ic=input_codeset 入力のエンコーディングを指定します。
                   以下のエンコーディングが利用可能です。
                   ここでの名前の指定には大文字小文字は無視されます。
  UTF-8-MAC これは入力側にしか指定できません
```
>[module NKF (Ruby 2.3.0)](https://docs.ruby-lang.org/ja/2.3.0/class/NKF.html)

[^1]: コメント頂いたように、「`Dir.glob` とかで取れるパス名は `UTF8`」であり、特に困らなかったので削除。 Ruby メンテナたちに改めて感謝。
SwipeRefreshLayoutの垂直スワイプとViewPagerの水平スワイプがバッティングするのを防ぐ

## 概要
SwipeRefreshLayoutの中にViewPagerを含むようなレイアウトにすると、そのままではSwipeRefreshLayoutの垂直スワイプとViewPagerの水平スワイプがバッティングしてい、操作性が悪くなってしまいます。

```xml 
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/refresh"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</android.support.v4.widget.SwipeRefreshLayout>
```

## 解決策
`ViewPager.OnPageChangeListener`でViewPagerがスクロール中のときはSwipeRefreshLayoutを無効にすることでうまくいきます

以下、サンプルコードになります。

```java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
        viewPager.setAdapter(/* 適当なadapterを設定 */);

        final SwipeRefreshLayout swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.refresh);
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {
                // スクロールの状態がIDLE以外（スクロール中）のときは、SwipeRefreshLayoutは無効にする
                swipeRefreshLayout.setEnabled(state == ViewPager.SCROLL_STATE_IDLE);
            }
        });
    }
```

## 参考

http://stackoverflow.com/questions/25978462/swiperefreshlayout-viewpager-limit-horizontal-scroll-only
年寄りが後進に伝えられるもの

# 前回のエントリのコメントについて

前回「年をとって考えるのをやめる人」についてのエントリを書いたところ、そのコメントで後進に技術を伝えるという仕事の重要性について記載頂いた。

これについて、少し思うところをポエムチックに書いてみようと思う。

ちなみに、mewの開発者として有名な山本和彦氏が、「教育は歳をとってからでもできるから、若いうちは大学ではなくて研究開発の現場にいるために民間に転職した」というのは、どこで聞いたか忘れたが有名な話であると思う。


# 学ぶ側の人のこと

学ぶ側にも学ぶ技術というのがある。言い換えれば「勉強の仕方」で、これを知らない人はどうやら多い。ただ、勉強の仕方は、教わることで伸びるタイプとか、自力で勉強するタイプとか色々なので、単一ではなく、個人個人で自分に適した学びの技法を持っているかどうかに左右される部分も大きいように思う。

本稿では、学ぶ側の人のことは、少しわきに置いておこうと思う。

年寄りが教える側にたち、技術を次の世代に残していくことについて考えたい。

# 教えられる技術とは

あるやりかたが、感覚的なものでなく技術として昇華した場合、それは伝授できる。

基本的には。

少し脱線するがスポーツや音楽の技は、「あの人は技術点が高い」的な評価軸があるわりに、他人に伝授することが難しい。これは、その技術の言語化が難しく、身体に染み付くことでようやく会得できるものだからである。これを身体知と呼ぶ。
言語化の部分は、数値化、データ化とも置き換えられる。
言語化、数値化、データ化、デジタル化、こういうった出力が可能なものは、保存もしやすいし、再生もしやすいし、教えやすいし学びやすい。
身体知のデジタル化というのは、それはそれで研究しているひとたちがいるようだが、本論からは外れるので、別の話ということにする。

本稿では、技術は伝授可能なもの、というところをスタートにしたい。

UNIXというのはある意味恐ろしいもので、40年前の技術がいまだに現役で利用できる。
ここでいう技術というのは、たとえばシェルでの操作、コマンドの組み合わせ、シェルスクリプト、awkスクリプトなどのことだ。40年前にperlはなかったが、しかしperl4の頃のノウハウは今でも役に立たないということはない。

そういう観点での「UNIX的UNIXの使い方」というのは、今でも通用するし、むしろ若者は老人並の使いこなしをしてもらいたい。

カーネルのソースコードは、Version6, SystemIII, SystemV, 4.*BSD, Linuxと変化はしているものの、たとえばBSD系列のOSのディレクトリ構成は4.2BSDでおおよそ固まっていたりするなど、コードリーディングのノウハウというのは今でも通用する。
デバイスドライバの構造も、機能は増えたし(昔は当然のようにdetachやカーネルスレッドなどはなかったし、マルチプロセッサも考慮されていなかった)、抽象化も進んだ(昔は当たり前のようにI/OポートやMMIOを直接叩いていたりした)が、基本的な構造は変わっていない。

しかしハイパーバイザはなかったし、コンテナ型仮想化もなかったし（chrootはあったが）、go言語もなかったし、Scalaもなかったし、Rustもなかったし、Javaすらなかった。

しかしLISPはあった。すごいぞ、LISP。

各論を言い出すと切りがないのだが、ただこれらのノウハウは、若い層でもできるやつはできる。できないやつはできない。
不思議なもので、優秀な若者は、お前何年生まれだよと聞きたくなるくらい、昔からの技術も普通に使いこなし、その上で新しいことを知っている。歴史を学ぶことにも貪欲だが、最近あまりよい歴史書が出ていないので、この点は少し可哀想かもしれない。

結局、老人が若者に教えられる内容というのは、テクニックの集合ではなく、その根底にある考え方とかコンセプトといったものが一番重要なのではないかと考える。

# 伝えるべき「考え方」とは

自分の持つ技術を、他者に伝えられる「考え方」に消化して、連成して、昇華する力というのは、どのおっさんも持っているわけではない。結局、学問を作ることと同じだからだ。
学問を学んでいない人間が、学問を作ることは、なかなかに難しい。

果たして、考えるのをやめてしまったおじさんに、これができるのだろうか。

あるいは、考えるをやめてしまったおじさんというのは、手を動かすパワーもなくなったのに、少ない力で伝授できる「学問」という抽象度で自分の知見を語ることもできず、何もできなくなってしまったおじさんなのではないだろうか。

その一方で、ペアプログラミングとまでいかなくても、横について細かく指導しながら開発なりオペなりする人材としてのおっさんというポジションはありうるのかもしれない。
ただそれも常につきっきりはできないので、最初尻を叩くと後は自力で走れる系の若者の尻を叩くというポジションだ。

いやまてよ、本当に手取り足取りが必要なレベルの若者と、新しいことを勉強したり考えたりしないおっさんとのペアで、二人で一人という計算はできるか？

……なんか、そういう発想はどうなのかと思ってしまうなあ。

問題なのは、おっさんだからと言って、誰もがみんな伝達可能な「知見」を持っているとは限らないということで、そのレベルだからこそ楽しくなくなって考えることをやめてしまうのかもしれないとも言える、ということだ。

さて、だんだん収束に向けての方向付けがあやしくなってきたぞ。

思うのだが、無理に「偉い仕事」をさせようとするから無理があるのであり、トップエンジニアになれなかった人は、それはそれでトップでない仕事をしてもらえばよいのではないか。
それこそ、トラディショナルな構成の社内ネットワークインフラの整備などは人によっては適任だろう。ここでSDNとか言い出すと死ぬが。
サポート技術員という仕事はありうる。

あるいは、そういう人こそマネジメントをやってもらうべきなのではないだろうか。
もしかしたら瓢々と管理業務をこなしてくれるかもしれない。
もちろん、前提として、トップエンジニアのほうがマネージャより偉いという認識に、全員が改める必要はある。

この場合に完全能力給を謳っている組織はどう能力を評価すればよいかという問題はあるが、これもまた別の話ということで。

だから、別におっさんが無理して教育頑張ろうとかしなくてもいいと思うよ、個人的には。
Vimコマンド : 便利一覧

# 概要
2016年10月からエンジニアとして働き始めましたが、最初Vimを使った時に、正直「なんだこれ1? めっちゃ使いづらい(笑)!!」と感じました。

しかし、Vim最高とみんな叫んでいるので、「本当か???」と内心疑いながら、使い続けました。

そして、5ヶ月経った今、自分もようやくVimmerと名乗れる入り口に立った気がするので、ここで便利だと思ったコマンドを共有します。

# 便利度★★★
## 移動
### ページ内移動
- gg: ページの先頭に移動。
- G: ページの最後に移動。

### 行移動
- 行番号 `G`:入力した行にカーソルが移動。

### 文字移動
- `f` + 1文字: カーソルがある行の中で、入力した文字に該当する場所に前方移動。
  - `;` : fコマンドの移動を繰り返す。
  - `,` : 検索を後方に戻る。
- `F` + 1文字: カーソルがある行の中で、入力した文字に該当する場所に後方移動。
  - `;` : Fコマンドの移動を繰り返す。
  - `,` : 検索を前方に戻る。

### 単語移動
- w,W: 次の単語の先頭に前進。
- b,B: 現在の単語もしくは前の単語の先頭に後退。
- e,E: 単語のendまで前進。

※ 大文字: ドット(.)やコロン(:)のような記号もひと続きの単語とみなして移動

## 繰り返し
- `.` : 直前のコマンドを繰り返す。

## 削除
### 行削除
- dd: カーソルがある行を削除。
- :行番号 `d` : 特定の行を削除。
  - ex.10行目を削除する。

![スクリーンショット 2017-02-25 17.08.12.png](https://qiita-image-store.s3.amazonaws.com/0/142810/996f6b2d-4f38-2705-9be5-7438eb52974b.png "スクリーンショット 2017-02-25 17.08.12.png")

### 単語削除
- diw: カーソル上の単語を削除。
- di": ダブルクォーテーションの内部を削除。
- dit: HTMLタグの内部を削除。
- ciw: カーソル上の単語を削除して、インサートモード。
- ci": ダブルクォーテーションの内部を削除して、インサートモード。
- cit: HTMLタグの内部を削除して、インサートモード。

### 文字削除
- x: 1文字削除。
- D: カーソル位置から行末まで削除。
- C: カーソル位置から行末まで削除して, インサートモード。

## コピー
### 行コピー
- yy: カーソルがある1行をコピー。
- :行番号y : 特定の行をコピー。
  - ex.10行目をコピーする。

![スクリーンショット 2017-02-25 16.51.06.png](https://qiita-image-store.s3.amazonaws.com/0/142810/618b4358-7ba6-bc73-251f-a94cd197ab0c.png "スクリーンショット 2017-02-25 16.51.06.png")

### 単語コピー
- yiw: カーソル上の単語をコピー。
- yi": ダブルクォーテーションの内部をコピー。
- yit: HTMLタグの内部をコピー。

## 挿入
### 行挿入
- o: 現在の行の下に改行し、インサートモード。

### カーソル挿入
- a: カーソルの右側にインサートモード。
- I: 行頭に移動し、インサートモード。
- A: 行末に移動し、インサートモード。

## インデント
- >>: インデントを追加。
- <<: インデントを削除。

※ 複数の行を選択した状態で行なった場合、選択した行が操作されます。

## undo
- u: コマンドを戻す。

## redo
- Ctrl + r: undoを取り消す。

## 検索
- / + 文字: ページ内の文字を検索。
  - n: 前方の同じ文字を検索。
  - N: 後方に同じ文字を検索。

## 置換
- `:%s/検索する文字/置換する文字/g` : ファイル上の全ての"検索する文字"を"置換する文字"に置換。

## 選択
- V:カーソルがある行を選択。
  - y:選択した行をコピー。
  - d:選択した行を削除。

# 便利度★★
## 移動
### カーソル
- L: ウインドウ内の一番下の行に移動。
- ^: 行のテキスト部分の先頭に移動。

### 画面スクロール
- zz: 現在のカーソル位置を中央となるように画面がスクロール。
- zt: 現在のカーソル位置が一番上となるように画面がスクロール。
- Ctrl + u： 半画面分戻る。
- Ctrl + d： 半画面分進む。
- Ctrl + b： 1画面分戻る。
- Ctrl + f： 1画面分進む。

## 単語移動
- ge,gE: 前の単語の末尾に後退。

※ 大文字: ドット(.)やコロン(:)のような記号もひと続きの単語とみなして移動。

## 行編集
- cc: 1行を削除して、インサートモードに入る。

## 選択
- viw: カーソル上の単語を選択。
- vi": ダブルクォーテーションの内部を選択。
- vit: HTMLタグの内部を選択。

## レコーディング機能
- qa：レコーディングを開始。
- q：レコーディングを終了。

※ 参考:http://qiita.com/taketin/items/aa6cc363f84f6090f1c0

## 矩形選択
- `Cntl + v`:矩形選択モード。
  - d: 矩形選択した範囲を削除。
- `Cntl + v + $`:矩形選択し、長さが異なる行を全選択。
- `Cntl + v$A`:長さの異なる複数行の行末に同じ文字列を追加する。

※　参考：http://nanasi.jp/articles/howto/editing/blockwise-operation.html

# おすすめ書籍
- [実践Vim 思考のスピードで編集しよう!](https://www.amazon.co.jp/%E5%AE%9F%E8%B7%B5Vim-%E6%80%9D%E8%80%83%E3%81%AE%E3%82%B9%E3%83%94%E3%83%BC%E3%83%89%E3%81%A7%E7%B7%A8%E9%9B%86%E3%81%97%E3%82%88%E3%81%86-Drew-Neil/dp/4048916599)

# まとめ
- 私が普段使っているコマンドの中で、特に頻度が高いコマンドをピックアップしました。少しでも役に立てたら感謝です。

# 参考サイト
- http://motw.mods.jp/Vim/command.html
- http://qiita.com/jnchito/items/57ffda5712636a9a1e62
- http://myenigma.hatenablog.com/entry/2015/12/19/081933
Windows7 SP1 on VMware ESXi 5.5 にて、起動後放置しているとリモートデスクトップ接続できなくなる現象

1. 事の発端は、リモート保守用PCとして VMware ESXi 5.5 hypervisor 上に Windows 7 SP1 仮想マシンを構築していた際にリモートデスクトップ接続できなくなったことでした。
2. 仮想マシンがハングアップした？と思い、VMware のコンソール経由で接続すると正常動作していることを確認。
3. コンソール接続を行った後は、何事もなくリモートデスクトップ接続ができるように。
4. その後数時間放置して再度リモートデスクトップ接続を行おうとすると失敗。
5. 以後、2-4を再度実施して、どうもしばらく放置すると接続できなくなると判明。
6. 仮想マシン上でもWindows7のパワーマネジメント関連設定は有効であると考え、Windows7インストール直後の設定で有効であった、コントロールパネル内の「ディスプレイの電源を切る」「コンピューターをスリープ状態にする」設定を無効に。
7. その後は放置してもリモートデスクトップ接続できなくなる現象はなくなりました。

**常時稼働させておくWindows仮想マシンにおいては、パワーマネジメント設定に気をつけましょう・・・。**
warning: Insecure world writable dir /usr/local/bin in PATH の対処

Vagrantを使い始めて、エラーや警告で詰まることがあるので整理しました。

## 対応
下記の警告がいつも出る。操作に支障は無いが修正をしたい。

```Tarminal
$ rails -v
/home/vagrant/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.5/lib/rails/app_rails_loader.rb:39: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040777
Rails 4.2.5
```
このエラーの意味は、`/usr/local/bin`に Write権限があるのは、安全じゃないよって意味でした。
なので、このファイルの権限を変更する。

```Tarminal
$ sudo chmod go-w /usr/local/bin
```

これで、警告は無くなりました。
chmodコマンドについて詳しくは <b>[ここ](http://qiita.com/masashi-t-h/items/5f4c4fa768642aad9e06)</b> を見てください。

## 参考リンク
http://yatta47.hateblo.jp/entry/2015/02/15/152713
http://www.damp.tottori-u.ac.jp/~ooshida/unix/chmod.html
http://qiita.com/masashi-t-h/items/5f4c4fa768642aad9e06
メモ: lhtml使ってみた

## 参考

* [LHTML - Zip圧縮するだけ。Web技術で作るローカルアプリケーション MOONGIFT](http://www.moongift.jp/2017/02/lhtml-zip%E5%9C%A7%E7%B8%AE%E3%81%99%E3%82%8B%E3%81%A0%E3%81%91%E3%80%82web%E6%8A%80%E8%A1%93%E3%81%A7%E4%BD%9C%E3%82%8B%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1/)

ubuntuで使ってみた。

* https://github.com/iffy/lhtml/releases から .debをインストール。

サンプルは以下を使ってみると良い。

* https://github.com/iffy/lhtml/blob/master/demos/demo.lhtml
* https://github.com/iffy/lhtml/blob/master/samples/test1.lhtml

```bash:
lhtml test1.lhtml
```

![lhtml1.png](https://qiita-image-store.s3.amazonaws.com/0/25728/3e5e1e65-19be-ca99-f929-974746e8cbfa.png)

## 注意点

* 引数にlhtmlを指定しても開かれなかった。(2017/02/25)
    * File -> Open で開くと無事表示された。
* form入力内容の保存は `Ctrl-S` でできた。
    * 逆に`Save`ボタンはubuntuでは保存されていなかった。
RustでCall Operator Overloadしようとして躓いた。

# 背景
プログラミングする際にCall OperatorをしょっちゅうOverloadして使うんですがC++とかPythonと違ってOverloadの仕方がちょっと特殊？な上に全然関連ドキュメントが出てこないので備忘録がてらにメモしておきます。

# C++/PythonでのOperator Overload
自分がある程度書いていてOperator Overloadができる言語がC++/Pythonあたりしかなかったのでその2言語での例になりますがやり方はいずれも以下の通りです。

## C++
```cpp
#include <iostream>
#include <string>

class Foo {
public:
  void operator()(std::string arg) {std::cout << "Hello, " << arg << "!" << std::endl;}
};
```

## Python
```py
class Foo:
  def __init__(self):
    pass

  def __call__(self, arg):
    print "Hello {}!".format(arg)
```

いずれもクラス定義の中で関連する関数をOverloadすればおしまいですね。

# RustでのOperator Overload
普通の演算子のOverloadでさえちょっと面倒なのにCall Operatorでは更に一手間必要です。というのもRustにはオブジェクトという概念が存在しないのでCall OperatorをもったTraitを実装してやることでOperator Overloadを実現するんですがそのためのTraitが三種類 (`FnOnce`, `FnMut`, `Fn`) 存在します。そして`FnMut`の実装には`FnOnce`の実装が必要で、`Fn`の実装には`FnMut`の実装が必要というなんとも面倒な仕様になっています。

```rust
use std::ops::{FnOnce, FnMut, Fn};

struct Foo {}

impl FnOnce for Foo {
  type Output = (); // 返り値は無し
  extern "rust-call" fn call_once(self, (arg,): (String,)) -> Self::Output {
    println!("Hello {}!", arg);
  }
}

impl FnMut for Foo {
  extern "rust-call" fn call_mut(&mut self, (arg,): (String,)) -> Self::Output {
    println!("Hello {}!", arg);
  }
}

impl Fn for Foo {
  extern "rust-call" fn call(&self, (arg,): (String,)) -> Self::Output {
    println!("Hello {}!", arg);
  }
}
```

`self`が呼び出し時にconsumeされてもいいのであれば`FnOnce`だけ実装してあげればいいんですがそうでなく単純にImmutableなReferenceを貸したいだけの時は`FnMut`と`Fn`を実装してやる必要があります。なんでこうなったのかはわかりませんがそういうものみたいです。めんどくさい。
Railsの開発用データを用意する際に、FactoryGirlが便利だったりする

## 内容

Ruby on Railsで開発をするときに、開発用のデータ (シードデータ)があると便利で、これがないとあるとでは開発速度が違うと思います
FactoryGirlはテスト用データを作る際によく利用されるかと思いますが、これを開発用データを構築する際に使うと便利なので紹介します
**※ 慣れた開発者は既知だと思うので、この記事をすっ飛ばしてください**

## 開発環境

- Ruby: `2.4.0`
- Rails: `5.0.1`
- FactoryGirl: `4.8.0`
- FactoryGirlRails: `4.8.0`

## Model

今回は**books**というテーブルがあったとします

```app/models/book.rb
# == Schema Information
#
# Table name: books
#
#  id              :integer          not null, primary key
#  title           :string(255)      not null
#  created_at      :datetime
#  updated_at      :datetime
#

class Book < ApplicationRecord
end
```

※ 上の様にスキーマをmodelに書いてくれる`annotate`というgemが便利です

## FactoryGirl

FactoryGirlは以下に設定します。

```spec/factories/books.rb
# == Schema Information
#
# Table name: books
#
#  id              :integer          not null, primary key
#  title           :string(255)      not null
#  created_at      :datetime
#  updated_at      :datetime
#

FactoryGirl.define do
  factory :book do
    sequence(:title) { |n| "Book Title#{n}" }
  end
end

```

`annotate`を入れておくと、ここにもスキーマの情報を書いてくれるので便利です
筆者はRspecを使っています

## Seed

本題、シードデータを用意します

```db/seeds.rb
require 'factory_girl'
include FactoryGirl::Syntax::Methods

FactoryGirl.definition_file_paths = [ Rails.root.join('spec', 'factories') ]
FactoryGirl.reload

table_names = %w(
  books
)
table_names.each do |table_name|
  path = Rails.root.join("db/seeds", Rails.env, table_name + ".rb")
  if File.exist?(path)
    puts "Creating #{table_name}..."
    require path
  end
end

```

ここでは、FactoryGirlを`require`して、ファイルの場所は`spec/factories`にあることを設定しています
さらに、シードデータを入れる際に実装するファイルを`tables`にいれ、読み込みます

```db/seeds/development/books.rb
5.times{ create(:book) }
```

ここを言いたかったのですが、この`create(:book)`がFactoryGirlが提供しているメソッドです

```
bin/rails db:seed
```
これでFactoryGirlを利用してシードデータを投入することができした

### 何がいいのか

`db/seeds/development/books.rb`は以下の様に書くこともできます

```db/seeds/development/books.rb
5.times{ |n|
  Book.create({
    title: "Book Title#{n}"
  })
}
```

ならこれでいいじゃんという話になるのですが、開発を進めていくと、この`books`のテーブルをいじりたいという要望が高確率で出てきます
その際に、カラムを変更したり、null制約を変更したりすると、それに応じてシードデータやテストにも変更を加える必要が生じます
大規模かつ重要なテーブルでは変更漏れなど、ケアレスミスは避けたいところです
そのため、シードデータ、テストデータを用意するための記述は限りなく少ない方がいいはずです
これは筆者の主観ですが、一個変えたら全部変わる様な設計がいいなと思います
Vue.js で行が動的に増減する表を実装してみた

## 背景

今まで行が動的に増減する表を実装するのに、jQuery と文字列操作を駆使して DOM をゴリゴリ書き換えていたのですが、なかなかにつらい。

描画の部分を Vue.js に任せてしまうことで、実装者はデータの操作にだけ意識を向ければ良くなるということで使ってみた。

## つくったもの

単純な例として次のようなものを作りました。

* Name という属性だけを持つ要素が複数あって、表に1行1要素で出力する
* 表の末尾にテキストボックスと追加ボタンがあり、追加ボタンをクリックするとテキストボックスの内容を Name とした要素を追加する
* 各行にはその要素を削除するボタンがある

## ソースコード

```html
<html>
<head>
    <!-- jQuery -->
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <!-- Bootstrap -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    <!-- Vue.js -->
    <script src="https://npmcdn.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app" class="container">
    <table class="table table-striped">
        <thead>
            <tr>
                <th>Name</th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            <!-- 各要素を表示 -->
            <tr v-for="(elem, index) in elements">
                <td>{{ elem.name }}</td>
                <!-- クリックして要素を削除 -->
                <td><span v-on:click="remove(index)" class="glyphicon glyphicon-remove"></span></td>
            </tr>
            <!-- 新しい要素を追加するための行 -->
            <tr>
                <td>
                    <input id="new-name" type="text">
                </td>
                <!-- クリックして要素を追加 -->
                <td>
                    <span v-on:click="append" class="glyphicon glyphicon-plus"></span>
                </td>
            </tr>
        </tbody>
    </table>
</div>

<script type="text/javascript">
var vm = new Vue({
    el: '#app',
    data: {
        elements: []
    },
    methods: {
        // 要素を追加
        append: function() {
            this.elements.push({
                name: $('#new-name').val(),
            });
            // テキストボックスの中身を空に
            $('#new-name').val('');
        },
        // 要素を削除
        remove: function(index) {
            this.elements.splice(index, 1);
        }
    }
});
</script>
</body>
</html>
```

~~本当は Enter キーを押せば追加できるようにしたかったけどうまく行かなかったので、またこんど。~~


## 追記（2017-02-25）

Enter キーを押したときに追加できるようにするためには input 要素に `v-on:keyup.enter` を追加すればいいみたいです。

```
<input id="new-name" v-on:keyup.enter="append" type="text">
```
GITHUBでpermission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.のときの対処方法

# permission denied (publickey)の対処方法
permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.

- 対処方法

```
$ ssh-keygen -t rsa
$ eval `ssh-agent`
$ ssh-add ~/.ssh/id_rsa.pub
```

からの
[SSH KEY](https://github.com/settings/keys)でSSH KEYの作成

TITLEはなんでも良い
keyのところに、id_rsa.pubの内容を貼り付けて登録

# プロキシサーバー経由だと、クローン出来ない

- 対処方法

```
git config --global http.proxy http://192.129.292.222:8080
git config --global https.proxy http://192.129.292.222:8080
```

任意のIPアドレスとポートを設定して上げればクローンできるようになる。
プロキシの情報は、インタネットオプションにあるはず。
ド素人neovimの使い手になってみる。1.NeoVimインストールからdein導入設定まで

#最終ゴール

- Neovimのインストール
- プラグインの設定
- githubに設定ファイルをおいて、いつでも自分の設定にできる
- linuxでも、自分設定で使えるようにする

#この記事

- Neovimのインストール
- deinの導入設定

#前提
- windows10(home) 64ビット
- git windowsをインストール済み
- python をインストール済み

# Neovimのインストール

- Neovimの本体を[64bit](https://ci.appveyor.com/api/projects/equalsraf/neovim/artifacts/build/Neovim.zip?branch=tb-mingw&job=Configuration%3A%20MINGW_64)または[32bit](https://ci.appveyor.com/api/projects/equalsraf/neovim/artifacts/build/Neovim.zip?branch=tb-mingw&job=Configuration%3A%20MINGW_32)のダウンロード
- ディレクトリ作成（C:\Program Files\nvim\bin）し、そこに置く
- パスを通す
 
```
setx /M path "%path%;C:\Program Files\nvim\bin"
```

- 環境変数の作成
 
```
setx XDG_CONFIG_HOME %AppData% -m
setx XDG_DATA_HOME %AppData% -m
setx XDG_CACHE_HOME %Temp% -m
setx XDG_RUNTIME_DIR %Temp% -m
```

# deinの設定

- init.vim の作成

```
#%XDG_CONFIG_HOME%\nvim\init.vim

"""
" Dein TOML
" プラグインが実際にインストールされるディレクトリ
let s:dein_dir = expand('~\vimfiles\.cache\dein')
" dein.vim 本体
let s:dein_repo_dir = s:dein_dir . '\repos\github.com\Shougo\dein.vim'
" dein.vim がなければ github から落としてくる
if &runtimepath !~# '/dein.vim'
    if !isdirectory(s:dein_repo_dir)
        execute '!git clone https://github.com/Shougo/dein.vim' s:dein_repo_dir
    endif
    "execute 'set runtimepath^=' . fnamemodify(s:dein_repo_dir, ':p')
    execute 'set runtimepath^=' . s:dein_repo_dir
endif
" 設定開始
if dein#load_state(s:dein_dir)
  call dein#begin(s:dein_dir)
  " プラグインリストを収めた TOML ファイル
  " 予め TOML ファイル（後述）を用意しておく
  let g:rc_dir    = expand('~/vimfiles/rc') 
  let s:toml      = g:rc_dir . '/dein.toml'
  let s:lazy_toml = g:rc_dir . '/dein_lazy.toml'
  " TOML を読み込み、キャッシュしておく
  call dein#load_toml(s:toml,      {'lazy': 0})
  call dein#load_toml(s:lazy_toml, {'lazy': 1})
  " 設定終了
  call dein#end()
  call dein#save_state()
endif
" もし、未インストールものものがあったらインストール
if dein#check_install()
  call dein#install()
endif
```

- シンボリックリンクの作成

```
mklink /D  %USERPROFILE%\vimfiles\ %XDG_CONFIG_HOME%\nvim
mklink %USERPROFILE%\_vimrc %USERPROFILE%\vimfiles\init.vim 
```

- 随分はまったGitHubが使えなくなる現象がおきた。
・コマンドプロンプトからGITを使えないとだめなこと。
・鍵を作成して登録しないと行けない。->記事にした。

- dein.tomlの作成

```
[[plugins]]
repo = 'Shougo/dein.vim'

[[plugins]]
repo = 'scrooloose/nerdtree'
```

これで、nvim-qt.exeを動かせば動くはず。
次は、GitHub用に、ファイルを整理する。

# 追記 2017/3/1 ginit.vimを読み込まない現象の対処方法

- どうやら、nvim_gui_shim.vimが無いため、読み込まなかった。<br>
   [ここ](https://github.com/equalsraf/neovim-gui-shim/blob/master/plugin/nvim_gui_shim.vim)より取得してC:\Program Files\nvim\share\nvim\runtime\pluginに置けば行けるはず。
wpa_passphraseでハマったこと

# wpa_passphrase
man wpa_passphrase だと、

```shell-session
wpa_passphrase [ ssid ] [ passphrase ]
```
としか書いてないけど、
ssid=AAAA
passphrase=BBBB
のときで、BBBBが!から始まる場合は、

```shell-session
wpa_passphrase AAAA 'BBBB'
````
とpassphraseをシングルクォーテーションで囲まないと

```shell-session
bash: BBBB: event not found
````
というエラーになる。
Webアプリケーションエンジニアがディープラーニングに挑戦する際にやったこと(Coursera Week4)

# Coursera Week4
## はじめに
CourseraのWeek4を実施しましたので、私のメモを公開します。
Courseraってなんだ？という方は[Week1](http://qiita.com/KirariGlock/items/d41bdcc6f5ec5ad255fb)から御覧ください。
Week4ではニューラルネットワークについて学習を進めていきます。
非常にわかりやすく丁寧な解説なので、ニューラルネットワークのことが理解しやすいと思います。

## ニューラルネットワーク(Neural Networks:Representation)
### 非線型仮説(Non-linear hypotheses)
なぜニューラルネットワークが必要なのか。
ニューラルネットワークを使用せずに線形回帰やロジステック回帰で予測すると、入力の多いデータの場合、計算コストが高くなり、オーバフィットしやすくなる。
実際に車の画像を判定する場合、コンピュータはピクセル単位の数値で判定するため、入力が非常に多くなる。
（例）50x50pixelの小さい画像の場合、ピクセル数は2500 pixel。RGBは7500になる。

### モデル表現(Model representation)
ニューロンとはたくさんの入力を受け取り、何らかの計算をして結果を脳内の他のニューロンに送る計算ユニットであるといえる。
アクティベート関数とはニューラルネットワークの用語で、シグモイド関数のことである。
また、$\theta$のことをウェイトと呼ぶ。

ニューラルネットワークの最初のレイアを入力レイアと呼ぶ。
最後のレイヤを出力レイヤと呼ぶ。
その間のレイアを隠れたレイアと呼ぶ。
２つ目のレイアの1番目のニューロン$a_1^{(2)}$と表す。
$S_{j+1} = S_j + 1$

ニューラルネットワークの計算
$z^{(2)} = \theta^{(1)}a^{(1)}$
$a^{(2)} = g(z^{(2)})$
Add $a_0^{(2)} = 1$
$z^{(3)} = \theta^{(2)}a^{(2)}$
$h_\theta(x) = a^{3} = g(z^{(3)})$

### 例と直感的な説明 (Examples and intuitions)
ニューラルネットワークで$x_1 AND x_2$を計算する。
$g(-30 + 20x_1 + 20x_2)$

| $x_1$ | $x_2$ | $h\theta(x)$ |
|:-:|:-:|:-:|
| 0 | 0 | $g(-30)\approx0$ |
| 0 | 1 | $g(-10)\approx0$ |
| 1 | 0 | $g(-10)\approx0$ |
| 1 | 1 | $g(10)\approx 1$ |

ニューラルネットワークで$x_1 OR x_2$を計算する。
$g(-10 + 20x_1 + 20x_2)$

| $x_1$ | $x_2$ | $h\theta(x)$ |
|:-:|:-:|:-:|
| 0 | 0 | $g(-10)\approx0$ |
| 0 | 1 | $g(10)\approx 1$ |
| 1 | 0 | $g(10)\approx 1$ |
| 1 | 1 | $g(30)\approx 1$ |

ニューラルネットワークでのNOTの計算
$g(10 - 20x_1)$

| $x_1$ | $h\theta(x)$ |
|:-:|:-:|
| 0 | $g(10)\approx 1$ |
| 1 | $g(-10)\approx0$ |

ニューラルネットワークで$(NOT x_1) AND (NOT x_2)$を計算する。
$g(10 - 20x_1 - 20x_2)$

| $x_1$ | $x_2$ | $h\theta(x)$ |
|:-:|:-:|:-:|
| 0 | 0 | $g(10)\approx 1$ |
| 0 | 1 | $g(-10)\approx0$ |
| 1 | 0 | $g(-10)\approx0$ |
| 1 | 1 | $g(-30)\approx0$ |

ニューラルネットワークで$x_1$ XOR $x_2$を実現するには以下のようにニューラルネットワークを組み合わせる。

ニューラルネットワークの２層目のニューロン$a_1^{(2)}$に$x_1 AND x_2$のネットワークを使用。
ニューラルネットワークの２層目のニューロン$a_2^{(2)}$に$(NOT x_1) AND (NOT x_2)$のネットワークを使用。
ニューラルネットワークの3層目のニューロン$a_1^{(3)}$に$x_1 OR x_2$のネットワークを使用。

| $x_1$ | $x_2$ | $a_1^{(2)}$ | $a_2^{(2)}$ | $h_\theta(x)$ |
|:-:|:-:|:-:|:-:|:-:|
| 0 | 0 | 0 | 1 | 1 |
| 0 | 1 | 0 | 0 | 0 |
| 1 | 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 0 | 1 |

### マルチクラス分類器 (Multi-class classification)
ニューラルネットワークを用いて、画像を人、車、バイク、トラックのように分類する場合、1 vs ALL法と同じものになる。
上記の場合、$h_\theta(x)$は４つの要素を持つベクトルになる。
1つ目の要素が1なら人、2つ目の要素が1なら車…など。
Ruby｜caseでいろいろやってみた


`Proc`にある`===`演算子をうまいこと使ってあげると面白いことが出来たので投稿します。

## きっかけ
if/elsifで出来てたんだけどcaseで書き直せるのかな？と思ったので

```ruby
[*1..10].each do |value|
  if value.even?
    p "#{value} is even."
  elsif value.odd?
    p "#{value} is odd."
  end
end
```

## Procでやってみた

```ruby
def even_or_odd(value)
  case value
  # &:even? とは出来ませんでした。。
  when :even?.to_proc
    "#{value} is even."
  when :odd?.to_proc
    "#{value} is odd."
  end
end

[*1..10].each do |value|
  p even_or_odd(value)
end
```

## なぜ出来るのか

Rubyでは`when`に手続きを渡すために`===`を利用しています。
[リファレンス](https://docs.ruby-lang.org/ja/latest/class/Proc.html)をよく読んでみると、`when`で手続きを渡せるように作ってるよ！とあり
先に書いたようなプログラムでも期待した動きになっています。

Rubiniusでも確かにそうなってますね！

```ruby
# https://github.com/rubinius/rubinius/blob/master/core/proc.rb#L107
alias_method :===, :call
```
[GAS]GoogleAppsScriptで報告資料の定期自動複製

お客さんに報告する資料を定期的に作ったりするの大変ですよね。
毎週「先週の資料をコピーして、日付フォルダ作って、リネームして移動」みたいな運用をしている週報の作成を自動化した + 毎回リンクをお知らせする手間がのこるので、作成したファイルへのリンクをslackに通知してもらうようにした時のメモです。

# コード
```
function makeFolder() {
  Logger.log("週報作っちゃうぞ！");
  var success = false;
  // 「週報」フォルダ
  var rootFolder = DriveApp.getFolderById("your drive");
  // 「週報」配下のフォルダ
  var folders = rootFolder.getFolders();
  
  while (folders.hasNext()) {
    var folder = folders.next();
    var folderDateNum = Number(folder.getName());
    var todayNum = Number(Utilities. formatDate(new Date(), "Asia/Tokyo", "yyyyMMdd"));   
    // 今日の分か未来分まで作成済み
    if ((todayNum-folderDateNum) <= 0) {
        Logger.log("作成済みです");
      break;
    } 
    
    // ここに来るってことは、まだ今週分は作成していないはず。
    var todayFolder = rootFolder.createFolder(todayNum);
    // 先週のフォルダ内にあるファイル全部取得
    var files = folder.getFiles();
    // ファイルを取得
    while (files.hasNext()) {
      var file = files.next();
      // 週報以外をスキップ
      if (file.getName() == "進捗報告_" + folderDateNum) {
        break;
      }
    }
    
    // 今週分作成
    var todayFile = file.makeCopy("進捗報告_" + todayNum);
    todayFolder.addFile(todayFile);
    success = true;
    // 消さないとコピーが残っちゃうので削除
    folder.removeFile(todayFile);
    break;
  }
  // slackに通知
  postMessage(success, todayFile.getUrl());
  Logger.log("作成終了");
}

// Slackに通知
function postMessage(success, url) {
  var token = "your token"; // slackトークン
  var channel = "shuhou"; //投稿先チャンネル名
  var username = "週報bot"; //BOTの名前
  var text =  "週報の作成に失敗しちゃいました。ごめんなさい。今日は自分でコピーしてね！";
 
  if (success) {
    text = "週報ができたよ。" + url;
  }
  
  UrlFetchApp.fetch("https://slack.com/api/chat.postMessage?token=" + token + "&channel=%23" + channel + "&username=" + username + "&text=" + text);
}
```

# 感想
- 初めてGAS触りましたが、javascriptライクで直感的に操作できて、やりやすかった。
- 通知メッセージとかはもうちょっと考えたほうがよさそうですが、とりあえずこれで運用できてるので、いまはこのままにしてます。
- `@here`通知ってこれでできるのでしょうか？

# 参考
先人の知恵に感謝:pray:
[Google Apps Scriptを使って定期実行するcronを作る](http://www.sakana.tech/entry/make-cron-use-googleappsscript#i-3)
[GoogleAppsScript Reference](https://developers.google.com/apps-script/reference/calendar/)
[Google Apps Scriptを用いてライブラリを使わずにSlackにGoogleサイトの変更通知を投稿する](http://qiita.com/KanaSakaguchi/items/f0b1bb1cf73f0ec5ec71)
【GAS】onEdit(e)を使ってスプレッドシートの行の変動による式崩れを防ぐ

　このタイトルを見て「あるある」って思った人はスプレッドシーターの仲間と認定します（笑）。

　小遣い帳とか、在庫の受払帳みたいなものを想定していて、たとえばこんな簡単な出納帳を例に検討します。

![スクリーンショット 2017-02-25 14.42.01.png](https://qiita-image-store.s3.amazonaws.com/0/139134/c94943b4-124a-e0c5-8ba8-c16ca88d0b39.png)

　この状態で行を挿入したり削除したり、最大行を追加したりするとどうなるか、見ていきましょう。

#行挿入

![スクリーンショット 2017-02-25 14.12.48.png](https://qiita-image-store.s3.amazonaws.com/0/139134/208715dd-8e5e-f5d8-bd8d-f43d75dcee6e.png)

　セルE8は1個上のセルE7ではなく、挿入前の2つ上のセルE6を参照したままとなり、以降の残高の値がE7をすっ飛ばしたままとなってしまい、以降の残高の値が不正確となります。

#行削除

![スクリーンショット 2017-02-25 14.16.58.png](https://qiita-image-store.s3.amazonaws.com/0/139134/b4bd4bb8-e487-875c-d369-44563d45a2cc.png)

　E7が#REF!となり、以降もその影響を受けて全部#REF!となってしまいます。参照したいセルがなくなり、数式が=#REF!+・・・となってしまったためです。

#最大行追加

![スクリーンショット 2017-02-25 14.24.12.png](https://qiita-image-store.s3.amazonaws.com/0/139134/ebf6f7ae-4ac7-d22b-1c28-ce284214c9b1.png)

　試しに3行追加しましたが、当然のことながら式は自動的には入ってくれません。

#onEdit(e)で残高セルを監視し、計算式の空白や#REF!が出たら対応する

　そして、現時点の私見ですが「列ごと一気に数式を入れ直す」のが少々乱暴ですが最も手っ取り早い解決策かと思います。forで回したりしてピンポイントにセルを修正でもいいんですが行数が多くなってくるとパフォーマンスが微妙かと。また、複数の異なる離れた行の削除にも対応するためというのもあります。まだいっぺんに直すほうがマシかと思います。

```コード.gs
var sh = SpreadsheetApp.getActiveSheet();

function onEdit(e) {
  // 変更行
  var row = e.range.getRow();
  // 変更列
  var col = e.range.getColumn();
  // 変更行数
  var num = e.range.getValues().length-1;
  // 最終行
  var lr = sh.getLastRow();
  // 最大行
  var mr = sh.getMaxRows();
  // 行挿入or削除
  if (row > 2) {
    // 行挿入or最終行追加
    if (!sh.getRange(row,5).getFormula()) {
      sh.getRange(3,5,mr-2,1).setFormula('=R[-1]C+RC[-2]-RC[-1]');
      // 最大行追加なら罫線
      sh.getRange(lr+1,1,num+1,5).setBorder(true,true,true,true,true,true);
    // 行削除
    } else if (sh.getRange(row,5).getValue() === "#REF!") {
      sh.getRange(3,5,mr-2,1).setFormula('=R[-1]C+RC[-2]-RC[-1]');
    }
  }
}

```

#余談
というか、自力で式を修正したほうが早くないか？ってなるんですけどね。
2章　パーセプトロンの実装　ゼロから作るDeeplearningのいいとこだけ切り取る

# パーセプトロンとは？

パーセプトロンとは、複数の信号を入力として受取、一つの信号を出力します。
パーセプトロンの信号は1or0の二値の値です。今回は0を流さない、1を流すに対応させて記述します。

# ゲートの種類

## AND
|x1|x2|y|
|---|---|---|
|0|0|0|
|1|0|0|
|0|1|0|
|1|1|1|

## NAND
|x1|x2|y|
|---|---|---|
|0|0|1|
|1|0|1|
|0|1|1|
|1|1|0|

## OR 
|x1|x2|y|
|---|---|---|
|0|0|0|
|1|0|1|
|0|1|1|
|1|1|1|

# パーセプトロンの実装

## 簡単な実装

- AND関数を定義

```
def AND(x1, x2)
    w1, w2, theta = 0.5, 0.5, 0.7
    temp = x1*w1+x2*w2
    if tmp <= theta:
        return 0
    elif tmp > theta:
        return 1
```

パラメータのw1, w2, thetaは関数内で初期化し、重み付きの入力の総和が閾値を超えると1を返し、それ以外は0を返します。それでゃ、図2-2のとおり出力されるか確認しましょう。

```
AND(0, 0) # 0
AND(1, 0) # 0
AND(0, 1) # 0
AND(1, 1) # 1
```

期待した挙動が得られました。

同様にNANDもORも実装することができます。

## 重みとバイアスの導入

```
y = 0(b+w1x1+w2x2 <= 0)
    1(b+w1x1+w2x2 >  0)
```
```
>>>import numpy as np
>>>x = np.array([0,1])
>>>w = np.array([0.5, 0.5])
>>>b = -0.7
>>>w*x
>>>array([0. , 0.5])
>>>np.sum(w*x)
0.5
>>>np.sum(w*x) + b
-0.19999999996
```

## 重みとバイアスによる実装

```
def AND(x1, x2):
   x = np.array([x1, x2])
   w = np.array([0.5, 0.5])
   b = -0.7
   tmp = np.sum(w*x) + b
   if tmp <= 0:
       return 0
   else:
       return 1

def NAND(x1, x2):
   x = np.array([x1, x2])
   w = np.array([-0.5, -0.5])
   b = 0.7
   tmp = np.sum(w*x) + b
   if tmp <= 0
      return 0
   else:
      return 1

def OR(x1, x2):
   x = np.array([x1, x2])
   w = np.array([0.5, 0.5])
   b = -0.2
   tmp = np.sum(w*x) + b
   if tmp <= 0
       return 0
   else:
       return 1
```

# XORゲート

XORゲートは排他的論理和とも呼ばれる論理回路です。

## OR 
|x1|x2|y|
|---|---|---|
|0|0|0|
|1|0|1|
|0|1|1|
|1|1|0|

この結果を式で表すことが難しい。

# 多層パーセプトロン

パーセプトロンではXORゲートを表現できませんでした。しかし、それは層を重ねることによって可能になる。

## 既存ゲートの組み合わせ

NANDとORの組み合わせの値とANDによってXORゲートは表現することが可能。

## XOR 
|x1|x2|s1|s2|y|
|---|---|---|
|0|0|1|0|0|
|1|0|1|1|1|
|0|1|1|1|1|
|1|1|0|1|0|

## XORの実装
```
def XOR(x1, x2):
    s1 = NAND(x1, x2)
    s2 = OR(x1, x2)
    y = AND(s1, s2)

XOR(0, 0) # 0
XOR(1, 0) # 1
XOR(0, 1) # 1
XOR(1, 1) # 0
```

XORは2層のパーセプトロンです。
複数重ねたパーセプトロンを多層パーセプトロンと言うことがあります。
層を重ねるとより柔軟な表現を行うことが可能。

## まとめ

- パーセプトロンは入出力を備えたアルゴリズム。ある入力を与えたら、決まった値が出力される。
- パーセプトロンでは、[重み]と[バイアス]をパラメーターとして設定する。
- パーセプトロンを用いれば、ANDやORゲートなどの論理回路を表現できる。
- XORゲートは単相のパーセプトロンでは表現できない。
- 2層のパーセプトロンを用いれば、XORゲートを表現することができる。
- 単相のパーセプトロンは線形領域だけしか表現できないのに対して、多層のパーセプトロンは非線形領域を表現することができる。
- 多層のパーセプトロンはコンピューターを表現できる。
Serverless Frameworkのハマりポイント色々

先日自分が所属しているサンノゼのスタートアップでバックエンドにServerless Framework(AWS上でNode.js)を使ったサービスをリリースしたので、ハマりポイントをまとめておこうと思います。
AWSのサービス自体のハマりポイントだったりしますが気にせず行きます。

# コールドスタートが遅い
[この辺](https://forums.aws.amazon.com/thread.jspa?threadID=226136)にある通りですが、LambdaFunctionは初回呼び出し時やしばらく呼ばれなかった後に呼ばれたときはresponse timeが数秒になったりします。さらにVPC内で動かす場合は10秒以上になることもあります。なので、(ユーザ数いっぱいのアプリで常にアクセスある場合等を除いて)keepalive的なスクリプトが必要になります。間隔は不明ですが、今の所5分起きくらいに呼んでて特に問題になったことはないです。

ちなみに遅い理由はLambdaFunctionは[コンテナ上で動く](http://docs.aws.amazon.com/lambda/latest/dg/lambda-introduction.html)のでコールドスタート時はコンテナのセットアップに時間が掛かるかららしいです。VPCで特に遅いのは[コンテナにENIを割り当てる](http://docs.aws.amazon.com/lambda/latest/dg/vpc.html)必要があるからみたいです。

# VPC内だとデフォルトでは外に出れない

VPC内で起動するとデフォルトでは外に出れなくなります。外部のAPIを呼ぶ場合等は[VPC内にNATGatewayを作って](http://docs.aws.amazon.com/lambda/latest/dg/vpc.html#vpc-internet)Route Tablesを設定する必要があります。

# Adminが必要

[ここ](https://serverless.com/framework/docs/providers/aws/guide/credentials/)に書いてますが、まだどの権限が必要かが整理されてないので、AdministratorAccessで使ってね、とのことです。必要に応じてAWS自体のアカウントを分けてねみたいなことも書かれてますが、自分の会社はスタートアッププランのフリークレジットで使ってるので分けることができませんでした。

# Authorizerで認証エラー
Authorizerを立てて独自の認証を使うことができますが、再デプロイのたびになぜか認証エラーになるという現象に遭遇しました。これは[ドキュメントの例](https://serverless.com/framework/docs/providers/aws/events/apigateway/)の通りにTTLを0にしたら解決しました。[公式ドキュメント](http://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html)によるとポリシーがキャッシュされるからだそうです。

ちなみに認証・認可には[Auth0](https://auth0.com/)を使ってますが、ソーシャル系の認証やAD認証等が使えたり便利機能色々あったりでかなりオススメです(これまたそれなりにハマりポイントあるけど...)。Cognitoは調査開始当初では機能が足りなくて断念しました。Auth0の方が今後AWS以外の選択肢も持てるし良いんじゃないかと思います。

# 色んなリソース上限に達する

まずServerlessFrameworkは内部的にCloudFormationを使ってますが、CloudFormation自体のリソース上限が200なので、デプロイの際に200を超えるリソースがあるとエラーになります。ちなみに例えばhttpのエンドポイントを作ると、APIGateway、LambdaFunction、CloudWatchが作られて1エンドポイントあたり3リソース必要になります(色々まとめることはできる)。

[この辺](https://github.com/serverless/serverless/issues/2387)で色んなWorkaroundが議論されてますが、基本的にはserverless.yml自体を分けるのが良いみたいです。ただそれをするとAPIGatewayのrootが変わってしまうので、クライアント側もURLによって投げ先を変えるみたいなことが必要になります。さらにそれぞれのデプロイがアトミックに行われないので、アトミックに変更したいものは一つのserverless.ymlにまとめないといけません。

あとはデフォルトだと1ファンクションごとに1CloudWatchのログが作られたり、ステージごとにS3にBucketを作ったりするので、この辺もサービスやステージがたくさんあったりするとあっさりBucket上限やCloudWatchの上限にあたります。

今の所ここが一番の制約かなと思います...

# ローカル開発が鬼門

前述の通り、Administratorアクセスが必要だったり、色々上限があったりするので、それぞれの開発者が自分専用のステージにデプロイするみたいな使い方は厳しいです。

で、[serverless-webpack](https://github.com/elastic-coders/serverless-webpack)やら[serverless-offline](https://github.com/dherault/serverless-offline)みたいなプラグインを使ってローカルで動かすようにするんですが、まだまだ新しいものなので色々とバグを踏みます。例えば、queryが空のときローカルだと空のオブジェクトが入ってくるけどデプロイするとnullになってて落ちたりとかありました。

しかもこの手の不具合や前述のリソース上限とかはローカル開発だと遭遇しないけど、いざデプロイしようとすると当たったりするので、リリース直前に大慌てすることになりましたｗ

# でも良いところもいっぱい

いろいろハマったけど良いところもいっぱいあって、デプロイはホント楽だしスケールもする(はずだ)し、開発も活発で機能追加も頻繁だし、AWS以外の選択肢も持てるし、しばらくは乗り換え等は考えずに使っていこうかなと思ってます。
(ApexでGoで書きたい気持ちもあるけど...)

以上、簡単ですが他に使ってる方々の助けになれば幸いです。
また気付いたら(てゆーか、大分書き忘れもあると思うので)追記等したいと思います。

あ、採用もしてますので興味のある方がいたらツイッターとかで連絡ください。
日本からのリモートでも現地でも大丈夫です。
フロントはReact + reduxです。
二次元配列の初期化をmapで [Ruby]

Rubyで競プロやってて二次元配列ミスったので共有する

#間違えたパターン
####3x3の2次元配列を作る
```
a = Array.new(3, Array.new(3, 0) )
```

これではアウト
第一要素の配列の状態を変更すると

```×
a = Array.new(3, Array.new(3, 0) )

#変更前
p a
#第一要素の配列の変更 0 => 5
a[0][0] = 5
p a
```

```results.
#変更前
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]

#変更後
[[5, 0, 0], [5, 0, 0], [5, 0, 0]]
```
第一要素の配列のみに変更を行ったつもりが、他の配列にも影響を与えている。

####なぜ？
**最初の初期化で全て同じ配列オブジェクトを参照してしまっているため**

object_idを確認すると

```confirmation.
a = Array.new(3, Array.new(3, 0) )
p a.map(&:object_id)
```

```result.
[70285890080600, 70285890080600, 70285890080600]
```
配列はすべて同じオブジェクトを参照してしまっている


#mapメソッドを使って解決
個人的にmap好きなのでmap使います

```map.
a = Array.new(3).map{Array.new(3,0)}

p a
a[0][0] = 5
p a
```

```results.
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
[[5, 0, 0], [0, 0, 0], [0, 0, 0]]
```

mapを使うことで別々のオブジェクトとして定義したので、ほかの要素に影響を与えない

object_idを確認すると

```confirmation.
a = Array.new(3).map{Array.new(3,0)}

p a.map(&:object_id)
```

```result.
[70224619687520, 70224619687500, 70224619687480]
```

map洒落てるよね、好きです
Bitnami Redmine に DMSF プラグインを導入する

## 対象
Bitnami Redmine を利用していて、文書管理プラグイン(DMSF)を導入したいと思っている人、またはDMSFの導入に詰まった人。

## 環境
OS : Windows 10
Bitnami Redmine 3.3.1 導入済
(インストールディレクトリ: C:\Bitnami\redmine_3_3_1)

## 概要
Bitnami Redmine に 文書管理プラグイン DMSF Plugin 1.5.8を導入する。
私が詰まった部分を考慮して、詰まらないように手順を構成した文書。

## 1. 準備

あらかじめ以下の設定を行っておく。実施済の場合は2.へ。

* 環境変数に `C:\Bitnami\redmine_3_3_1\ruby\bin` を追加
* `.bundle\config` の BUNDLE_FROZEN: 1 の行を削除
* SSL証明書の配置
    * 参照：[Rails の Bundle Install で SSL 認証が失敗する件](http://neos21.hatenablog.com/entry/2016/10/27/003138)  
        * `cacert.pem` は、以下の２箇所に保存すること  
        `C:\Bitnami\redmine_3_3_1\ruby\lib\ruby\gems\2.1.0\gems\bundler-1.9.6\lib\bundler\ssl_certs`
        `C:\Bitnami\redmine_3_3_1\ruby\lib\ruby\2.1.0\rubygems\ssl_certs`

## 2. DMSF Plugin をダウンロード

pluginsフォルダにダウンロード。

```bat
cd "C:\Bitnami\redmine_3_3_1\apps\redmine\htdocs\plugins"
git clone --depth=1 -b v1.5.8 https://github.com/danmunn/redmine_dmsf.git
```

* gitコマンドを使用せず、zipファイルとしてダウンロードした場合、解凍後のフォルダ名を "redmine_dmsf" に修正する。でないとフォルダ名の "-" やら "." やらが原因で Thin_redmine, Thin_redmine2 が起動しなくなる。

## 3. Gemfile修正

`redmine_dmsf` フォルダの`Gemfile`を修正。
xapianはwindowsでそのままインストールできないので、コメントアウト。

```rb:Gemfile
(前略)

group :xapian do
#  gem 'xapian-full-alaveteli', :require => false この行をコメントアウト
end
```

## 4. bundle install

bundle install を実行。エラーが出た場合は、1.の準備がきちんと行われているか確認。

```bat:cmd
cd "C:\Bitnami\redmine_3_3_1\apps\redmine\htdocs"
bundle install
```

* proxy接続の場合、環境変数 `http_proxy`、`https_proxy` 等を設定した後、`bundle install`。
    * 参考1: [Windows環境でのbundle install](http://blog.nextcode.jp/2013/12/windowsbundle-install.html)
    * 参考2: [Ruby Gemsをwindows & proxy環境下で使う](http://d.hatena.ne.jp/allez_wk/20100929/1285767671)

結果
![bundle_install.png](https://qiita-image-store.s3.amazonaws.com/0/167477/553333fa-fb1a-0b93-1734-f8dda4de45cb.png)

## 5. マイグレーション

MySQLが起動していることを確認した上で、以下のコマンドを実行。

```bat:cmd
bundle exec rake redmine:plugins:migrate RAILS_ENV=production
```

結果
![rake.png](https://qiita-image-store.s3.amazonaws.com/0/167477/3b849119-d3e3-8d1d-055c-3f64ceaf2f50.png)

## 6. redmine再起動

![saikidou.png](https://qiita-image-store.s3.amazonaws.com/0/167477/924a13d4-62f0-043d-0ed1-e5f2e36483d4.png)

## 7. 設定

プロジェクトの[設定]->[モジュール]より、"文書管理" にチェックし、"文書" にチェックがあれば外す。

DMSF画面
![dmsf.png](https://qiita-image-store.s3.amazonaws.com/0/167477/b0b636d6-55d9-d273-61a5-1911a5ab5116.png)

xapian使わないならここまでで完了です。

## App. xapian

[Xapian を Windows上のBitnami 環境でインストール](http://goro.kuni.to/wp/install/540/)

上のリンクを参考にして頑張ればできそうなんだけども、当面実施予定なし。
SSH root login 禁止設定

#SSH root login 禁止設定
VPSを借りたついでに備忘録程度にSSH root login禁止設定について書いておく。

環境:CentOS 7

##新しいユーザを作る
```
# useradd [username]
# passwd [username]
```

一旦ログアウトする。

##新しいユーザから設定
```
$ su -
# vim /etc/ssh/sshd_config
```

```
PermitRootLogin no
```
に変更する。
[iOS][Storyboard]超簡単！ポップアップビューの実装方法

StoryBoardでポップアップビューを実装する方法をメモ。

#1. StoryboardでViewを作成
<img width="819" alt="スクリーンショット 2017-02-23 13.18.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/22680/89ccf908-0949-36e2-2cd3-eeb3730203fd.png">

ポップアップビューの背景色は黒にして２０%透過させる。
<img width="227" alt="スクリーンショット 2017-02-23 13.16.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/22680/430223f8-a530-b9e4-7d99-15c621f78097.png">

#2. ポップアップビューのViewControllerを実装

```swift
import UIKit

class PopupViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    // 閉じるボタンがタップされた時
    @IBAction func onTapCancel(_ sender: UIButton) {
        self.dismiss(animated: false, completion: nil)
    }

    // ポップアップの外側をタップした時にポップアップを閉じる
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        var tapLocation: CGPoint = CGPoint()
        // タッチイベントを取得する
        let touch = touches.first
        // タップした座標を取得する
        tapLocation = touch!.location(in: self.view)
        
        let popUpView: UIView = self.view.viewWithTag(100)! as UIView
        
        if !popUpView.frame.contains(tapLocation) {
            self.dismiss(animated: false, completion: nil)
        }
    }

}
```

#3. 「ポップアップを表示」ボタンをタップした時の表示処理を実装

```swift
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    // ポップアップを表示がタップされた時
    @IBAction func onTapShowPopup(_ sender: UIButton) {
        let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        
        let popupView: PopupViewController = storyBoard.instantiateViewController(withIdentifier: "popupView") as! PopupViewController
        popupView.modalPresentationStyle = .overFullScreen
        popupView.modalTransitionStyle = .crossDissolve
        
        self.present(popupView, animated: false, completion: nil)
    }
}
```

##完成
<img width="375" alt="Screen Shot 2017-02-25 at 14.26.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/22680/a0064c94-4638-b06e-ad40-b54c6524078b.png">
<img width="375" alt="Screen Shot 2017-02-25 at 14.26.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/22680/9c89294d-e402-2275-498e-1f573fb318e8.png">
Zeppelin0.7.0をproxy環境下で使う時の設定

# 概要
[Apache Zeppelin](https://zeppelin.apache.org/)をproxy環境下にインストールした時のメモです。
使用したパッケージはzeppelin-0.7.0-bin-all.tgzになります。

# NPMダウンロードのproxy設定
Zeppelinの起動時にnpmとnodeをダウンロードしようとしてタイムアウトしてました。
ZEPPELIN_JAVA_OPTSに、httpとhttpsのproxyを指定すれば回避できます。

```zeppelin-env.sh
export ZEPPELIN_JAVA_OPTS="-Dhttp.proxyHost=xxxx -Dhttp.proxyPort=xxxx -Dhttps.proxyHost=xxxx -Dhttps.proxyPort=xxxx"
```

# Artifactダウンロードのproxy設定
interpreterのArtifactにMySQLクライアントなどを指定しても、デフォルトで登録されているリポジトリはproxy設定がされていないので使えません。
リポジトリを新規登録する際はproxyの設定が可能なので、デフォルトは無視してリポジトリを新規登録すればそちらからダウンロード出来るようになります。
設定方法は[こちら](https://zeppelin.apache.org/docs/0.7.0/manual/dependencymanagement.html)に書いてあります。


以上です。
vim 設定メモ


- HOMEディレクトリを探す
```comand
echo $HOME
/home/elice
```
- HOMEディレクトリに移動する
```command
cd /home/elice
```

- 設定ファイル（.vimrc）の作成
```command
vim .vimrc
```

- 設定ファイルに記述する
```vim:/.vimrc
# 文字コードの指定(UTF-8)
set encoding=utf8
#コマンドの代わりにスペースを挿入
set expandtab
#改行時に自動的にインデントを行う
set autoindent
#カーソル行を強調表示する
set cursorline
#ステータスバーを常に表示する
set laststatus=2
#行番号を表示する
set number
#インデントの文字数を指定する
set shiftwidth=4
#対応する括弧を強調表示する
set showmatch
#タブの幅を指定する
set tabstop
#編集中のファイル名を表示する
set title
```
jQueryで動的に追加した要素はクリックイベントが発火しない？いやそんなことはないぞ

# 知ってるよって？
知ってる人には当たり前、でも知らない人はかなり躓くんだよ！

# 事象
こんなボタンを作るじゃろ

```html
<div class="btn-area">
    <button type="button" class="add-btn">ボタン1</button>
</div>
```

<img width="128" alt="スクリーンショット 2017-02-22 17.46.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/147005/9393ff12-954e-8ff6-77e8-6fc8ee159b15.png">

こんなスクリプトを設定するじゃろ
（自分のボタンナンバー+1のボタンを作成）

```js
$(".add-btn").on("click", function () {
    var num = Number($(this).text().replace("ボタン", ""));
    var html = '<button type="button" class="add-btn">ボタン' + (num + 1) + '</button>';
    $(".btn-area").append(html);
});
```

「ボタン1」をクリックするたび「ボタン2」が増えるね:wink:
<img width="255" alt="スクリーンショット 2017-02-22 17.46.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/147005/724edf03-972c-2953-96f0-f7bfa7ed9afb.png">

**だがしかし！**

「ボタン2」をクリックしても何も起きない！指定してるclass一緒なのにー:scream:
増えろ増えろ増えろ（カチッカチッ）
<img width="175" alt="スクリーンショット 2017-02-22 17.47.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/147005/9714fb9a-52fd-bca2-3732-80714abec9ae.png">

こいつ...動かないぞ。

動くわけないんだ、イベントを設定してないからね！

# 対策
HTMLをスクリプトで追加した後にその要素に対してイベントを設定すればいいんだけど、
こんな感じにクリックイベントを書くと追加した要素にもイベントが適用される。

```js
// $(".add-btn").on("click", function () {
$(document).on("click", ".add-btn", function () {
    var num = Number($(this).text().replace("ボタン", ""));
    var html = '<button type="button" class="add-btn">ボタン' + (num + 1) + '</button>';
    $(".btn-area").append(html);
});
```

ほれほれほれほれ:raised_hands:
<img width="442" alt="スクリーンショット 2017-02-22 17.47.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/147005/cebf9459-2367-3d08-5883-15438888f843.png">
NHK番組表apiのrubyクライアントでV2 APIを叩く


ふと思い立って、岩合光昭の世界ネコ歩きの放送予定をカレンダーを作ってみた。

調べてみると、[NHK 番組表 API](http://api-portal.nhk.or.jp/ja)が公開されていて、さらにそれに対応した[ruby クライアント](http://mitukiii.hatenablog.com/entry/2014/02/07/015233)も公開されていた。
めっちゃ助かりますね。

で、早速APIキーを取得して本日から１週間先の番組表を取得・・・ってやると、３日先からBad Requestになってしまう。
原因はnhk_programがV1のAPIを利用していることでした。

V1とV2の番組表APIはendpointが違うだけで仕様自体は変わってないようなのでnhk_programが使うendpointを変更して対応。

無事に１週間先まで取れました。

```ruby:nhkclient.rb
client = NHKProgram.new(
				api_key: hogehogehoge
				endpoint: 'http://api.nhk.or.jp/v2/pg')
```
1章 Python入門 ゼロから作るDeeplearningのいいとこだけ切り取る

# Python

pythonは、大学や専門学校、コンピューターサイエンスの授業では使われている。
Google, MS, FBなでのIT企業でも使われている。
機械学習つかうならPythonって言う流れ。

# Pythonのバージョン
2系と3系がある。今回は3系ですべて書いていきます。

# 外部ライブラリ
- Numpy
- Matplotlib

# Pythonのインタプリタ

## 算術計算

```
>>> 1 - 2
-1
>>> 4 * 5
20
>>> 7 / 5
1.4
>>> 3 ** 2
9
```

## データ型

```
>>> type(10)
int
>>> type(2.718)
float
>>> type('hello')
str
```

## 変数

```
>>> x = 10
>>> print(x)
10
>>> x = 100
>>> y = 3.14
>>> x * y
314.0
```

## リスト
```
>>> a = [1,2,3,4,5]
>>> len(a)
5
>>> a[0]
1
>>> a[0:2]
[1,2]
>>> a[1:]
[2,3,4,5]
>>> a[:-1]
[1,2,3,4]
```
## ディクショナリ
```
>>> me = {'height': 100 }
>>> me['height']
100
```
## ブーリアン
```
>>> hungry = True
>>> sleepy = False
```
## if文

```
>>> hungry = True
>>> if hungry:
...  print('I'm hungry')
...
```

## for文

```
>>> for i in [1,2,3]:
```

# 関数

```
>>> def hello():
```

### クラス

```
class name
    def __init__(self, xxx, xxx) # constructor
        ...

    def method1 # method1
        ...
    def method2 # method2
        ...
```
for expample
```
class Man
    def __init__(self, name)
        self.name = name
        print('init')

    def hello(self):
       print('hello' + self.name)

    def goodbye(self)
       print('goodby' + self.name)
```

# Numpy

## import

```
>>> import numpy as np
```

numpyをnpとして読み込むことができます。

## 配列の生成

```
>>> x = np.array([1.0,2.0,3.0])
>>> print(x)
[1.2.3.]
>>> type(x)
numpy.ndarray
```

## 計算
```
>>> x = np.array([1.0, 2.0, 3.0])
>>> y = np.array([2.0, 4.0, 6.0])
>>> x + y
array([3., 6., 9.])
>>> x- y
array([-1., -2., -3.])
>>> x * y
array([2., 8., 18.])
>>> x / y
array([0.5, 0.5, 0.5])
```

```
>>> x = np.array([1.0, 2.0, 3.0])
>>> x/2.0
array([0.5, 1., 1.5])
```
x,yの要素数が同じじゃないといけない

### N次元配列

```
>>> A = np.array([[1,2], [2,3]])
>>> print(A)
[
 [1,2]
 [3,4]
]
>>> A.shape
(2,2)
>>> A.dtype
dtype('int64')

>>> B = np.array([3,0], [0,6])
>>> A+B
array([4,2], [3,10])
>>> A*B
array([3,0], [0,24])
>>> print(A)
[[1 2] [3 4]]
>>> A * 10
[[10 20][30 40]]
```

### ブロードキャスト

>>> A = np.array([1,2][3,4])
>>> B = np.array([10, 20])
>>> A*B
array([10, 40][30, 80])

### 要素へのアクセス
```
>>> X = np.array([51,55], [14,19], [0,4])
>>> print(X)
>>> X[0][1]
55
```
```
for row in X:
    print(row)

[51 55]
[14 19]
[0 4]
```
1次元配列への変換
```
X = X.flattern()
[51 55 14 19 0 4]
>>> X[np.array([0, 2, 4])]
array([51, 14, 0])
>>> X > 15
array([T, T, F, T, F, F])
>>> X[X>15]
array([51,55,19])
```

### Matplotlib

### 単純なグラフの描画

```
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 6, 0.1)
y = np.sin(x)

plt.plot(x, y)
plt.show() ## グラフ描画

```

### pyplot機能

- グラフを複数表示可能
- 画像も表示可能