OmniAICreator/Qiita-1.07M huggingface dataset:
LeetCode: Average of Levels in Binary Tree

# Introduction

Treeの問題。各レベルにおける平均値を求めよ、というお題です。
https://leetcode.com/problems/average-of-levels-in-binary-tree/description/


# Problem statement

```
Given a non-empty binary tree, return the average value of the nodes on each level in the form of an array.
Example 1:
Input:
    3
   / \
  9  20
    /  \
   15   7
Output: [3, 14.5, 11]
Explanation:
The average value of nodes on level 0 is 3,  on level 1 is 14.5, and on level 2 is 11. Hence return [3, 14.5, 11].
Note:
The range of node's value is in the range of 32-bit signed integer.
```

# My solution

Easyレベルだったので単純かなと思ったのですが、長々としたSolutionになりました。

方針：
1. Mapにて各レベルにおけるノードの値の合計値とその数を記録
sumByLevel：ノードの値の合計値
countByLevel：ノードの個数
2. TreeNodeに加えてレベルの情報もQueueに組みこむ

引っかかったポイント：
1. sumByLevelにてvalueにIntegerを使うと、テストケースが通らないケースあり
そのため、 Map<Integer, Long> sumByLevel と定義
2. integer -> double の変換を考慮しておらず、コンパイルエラーが発生

Time Complexity = O(N): すべてのTreeを走査する必要があるため
Space Complexity = O(h): マップを使い、各レベルの情報を記憶しているため

```Java
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<Double> averageOfLevels(TreeNode root) {
        List<Double> list = new ArrayList<>();
        if (root == null) {
            return list;
        }
        Map<Integer, Integer> countByLevel = new HashMap<>();
        Map<Integer, Long> sumByLevel = new HashMap<>();
        Queue<TreeNode> queue = new ArrayDeque<>();
        Queue<Integer> height = new ArrayDeque<>();
        queue.add(root);
        height.add(1);
        while (!queue.isEmpty()) {
            TreeNode cur = queue.poll();
            int curHeight = height.poll();
            if (countByLevel.containsKey(curHeight)) {
                countByLevel.put(curHeight, countByLevel.get(curHeight) + 1);
            } else {
                countByLevel.put(curHeight, 1);
            }
            if (sumByLevel.containsKey(curHeight)) {
                sumByLevel.put(curHeight, (long) sumByLevel.get(curHeight) + cur.val);
            } else {
                sumByLevel.put(curHeight, (long) cur.val);
            }
            if (cur.left != null) {
                queue.add(cur.left);
                height.add(curHeight + 1);
            }
            if (cur.right != null) {
                queue.add(cur.right);
                height.add(curHeight + 1);                
            }            
        }
        for (Integer key: sumByLevel.keySet()) {
            list.add((double) sumByLevel.get(key) / countByLevel.get(key));
        }
        return list;
    }
}
```

# Optimal solution

この問題の解説によると、より良い回答があるそうです。
https://leetcode.com/articles/average-of-levels/
ただ、上記回答もTimeComplexity = O(N)、Space Complexity = O(h) のため、私の回答と変わらないので良いかな？と思ってみたり。
LeetCode: Merge Two Binary Trees

# Introduction
ツリーの問題です。バイナリツリーをマージする、比較的簡単な問題です。

# Problem statement

```
Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not.

You need to merge them into a new binary tree. The merge rule is that if two nodes overlap, then sum node values up as the new value of the merged node. Otherwise, the NOT null node will be used as the node of new tree.

Example 1:

Input: 
	Tree 1                     Tree 2                  
          1                         2                             
         / \                       / \                            
        3   2                     1   3                        
       /                           \   \                      
      5                             4   7                  
Output: 
Merged tree:
	     3
	    / \
	   4   5
	  / \   \ 
	 5   4   7
 

Note: The merging process must start from the root nodes of both trees.
```

# My solution
1. t1ノード, t2ノードともに存在していたら t1.val += t2.val を実行します。t1とt2ともにNULL,t1のみnull, t2のみnullの3ケースに対しても対応します。
2. 左側・右側のノードでも1と同一のことを実行します。


```Java
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
        if (t1 == null && t2 == null) {
            return null;
        }
        if (t1 == null) {
            return t2;
        }
        if (t2 == null) {
            return t1;
        }
        t1.val += t2.val;
        t1.right = mergeTrees(t1.right, t2.right);
        t1.left = mergeTrees(t1.left, t2.left);
        return t1;
    }
}
```
1~3回のAIブームまとめ

現在は3回目のAIブームと言われています。
それぞれのAIブームはどのようなもので、なぜブームが終わったのか、忘れたらすぐに見ることができるようにまとめました。

#1回目：探索・推論の時代
#####時期
1956年~1960年代

#####概要
ゴール(目的)までに至る考えうる様々なルートで場合分けを行い目的の条件に合致するか探索をしていく。

#####ブームの終わり
探索・推論は明確にルールが決められたToy problem(おもちゃの問題)は解くことができるが、複雑な現実の問題を解くことは困難だった。

#2回目：知識の時代
#####時期
1980年代

#####概要
現実の問題に適応できるような様々な分野の知識をその分野の専門家からAIに覚えさせようとした。

#####ブームの終わり
各分野の専門家から知識を得る必要があり膨大なコストがかかった。また、人間は自分が習得している知識を言葉で説明することが困難だった(e.g.人間はどのように歩いているのか＝どの部分の筋肉にどれくらいの力をかけてどの部分の角度をどれくらいにして・・・)

そしてもし仮にすべての知識をAIに学習させることができても、それらの膨大な知識を正常に管理できる仕組みの実現が困難だった。

#3回目：機械学習・表現学習の時代
#####時期
2013年~

#####概要
すべての問題は「分ける」ということに帰着する(e.g.この写真には犬が写っている→Yes or No)。
コンピューターが分けるには式を与える必要がある。式で用いる変数を「特徴量」と呼ぶ。
これまで特徴量は人間の手で選択されてきたが、深層学習(ディープラーニング)という手法によってデータをもとにコンピュータが自ら特徴量を探し出すようになった。

#出典
1. 人工知能はどのようにして「名人」を超えたのか？ - 山本一成
2. Harvard Business Review 人工知能 - DIAMONDハーバード・ビジネス・レビュー編集部

追加した方がいい項目や追加・修正がありましたら編集リクエスト等いただけるとありがたいです。
【随時更新】ECに関わる開発者が最低限知っておくとよい用語集

# 概要

初めて Hamee に入った時、開発以前にECの用語がわからず、苦労した覚えがあるため、用語集を作ってみた。
何か参考になれば幸い。これあった方が良いなどあったら教えてください。


# 用語

|用語|意味|
|:---:|:---:|
|EC(E-Commerce)|電子商取引 (＝electronic commerce)のことで、ECとは、電子商取引を行うこと|
|受注|注文を受けた状態のこと|
|在庫|商品のある数のこと。これ自体は他の業界にも存在するが、ECではこの在庫にも種類がある。|
|予約在庫||
|実在庫|予約在庫と引き当て済みの在庫を抜いた今店舗が自由に動かせる在庫のこと。フリー在庫などと呼ばれることもある。|
|引き当て済み在庫||
|引き当て|商品は受注(ユーザから注文を受ける)から実際に存在する商品があって発送できるかどうかチェックする必要がある。そのため、注文を受けて実際の在庫を出荷できるようにキープする。そのキープのこと。|
|モール|ショッピングモールのことを指す。楽天とか、Amazonとか、ポンパレモールとか・・・|
|NPS（ネットプロモータースコア）|顧客ロイヤルティを図る指標。要するに満足度の指標の一つ。ECに限らず、最近は用いられることが多い指標|
|ロングテール|様々なジャンルで使われる言葉だが、ネットショップの場合、商品登録点数を増やして検索で引っかかる機会、販売機会を出来るだけ増やす、という戦略で使用される|
|EC化率|総流通額に占めるネット販売額の比率のこと|
|LTV　（ライフタイムバリュー）|1人の顧客が長期的に生み出す利益のこと。初めて購入してもらうための集客コストは高くが、その後、リピーター化できれば、集客コストを徐々に回収できるため、重要とされる|
|NP後払い|ネットプロテクションズ（NP）が提供する後払い決済システム。購入した商品が到着後、NPから届く請求書で、14日以内にコンビニ、銀行、郵便局で商品代金を支払う。購入者の不安が大きく取り除けるため、転換率が上がることが期待できる|
|転換率　（CVR／コンバージョンレート）|ECサイトの場合、店舗を訪問してくれたお客様（アクセス人数）のうち、購入して頂いたお客様の人数の割合。商品ジャンルによって目安は違うが、1％以下だと、店舗のデザインや説明文の不足など、何か問題があると考える必要がある|
|クロスセル|ある商品を購入したり購入しようとしている顧客に対して、別の商品を勧めるマーケティング手法。同時購入することで割引になるような商品や、本体に付属する備品など、同時購入を促進して客単価を上げる効果がある|
|セット率|お客様一人当たりの売上数量、まとめ買いのこと。客単価の増加を図るうえで重要な指標。セット率＝総売上数量÷購入者数で計算される|
Amazon Linux 2でmysql-serverがインストールできないときの対処方法

# 背景

AWSの勉強中、DBサーバ用のEC2インスタンスを用意しました。
1年間無料で使い放題とのことだったので、OSはAmazon Linux2です。
その際に、mysqlがインストールできず、苦戦しました。
そのときの解決方法です。

# 動作環境
OS：Amazon Linux 2

# 事象

下記のように、「パッケージ mysql-serverは利用できません。」というメッセージが出力されてしまいました。

```
$ sudo yum -y install mysql-server
読み込んだプラグイン:extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                               | 2.4 kB     00:00     
amzn2extra-docker                                        | 1.3 kB     00:00     
(1/4): amzn2-core/2/x86_64/updateinfo                      |  47 kB   00:00     
(2/4): amzn2extra-docker/2/x86_64/primary_db               |  29 kB   00:00     
(3/4): amzn2-core/2/x86_64/primary_db                      |  22 MB   00:00     
(4/4): amzn2-core/2/x86_64/group_gz                        | 2.4 kB   00:00     
パッケージ mysql-server は利用できません。
エラー: 何もしません
```

# 解決方法

どうやら、デフォルトで入ってるmariaDBと競合する場合があるということで、下記のコマンドを実行。

```
$ sudo yum remove mariadb-libs
$ sudo yum localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
$ sudo yum -y install mysql-community-server
```

バージョン確認のコマンドを実行して、正常に出力されればOKです。

```
$ mysqld --version
```



# 参考文献
[第10回　yum, rpmインストールにおけるMySQL 5.6とMySQL 5.7の違い](http://gihyo.jp/dev/serial/01/mysql-road-construction-news/0010)
[CentOS7 mysqlがインストールできない](http://americandog1993.hatenablog.jp/entry/2017/07/22/013708)
php-master-changes 2018-09-30

今日はコンパイラの改善、非スタティックメソッドの $this 潰しの警告化、sodium_memzero() のリフレクションでの引数修正、変数の使い回し化、ext/spl のテスト修正があった！
あと始めてから 2 ヶ月たった

# 2018-09-30
## nikic: Generalize compile_typename
- https://github.com/php/php-src/commit/c4cb3250cab9d793cd9efd1d00212a98e8aad4c3
- ASTノードと arginfo をとって関数引数の型名を解決する処理 compile_typename() を一般化し、引数の arginfo へ型を詰めるのではなく、返り値で型名を返す処理に修正
    - 元々関数引数でのタイプヒント専用だった処理が他でも利用可能になったような形？
- nullable の処理もこの関数内へ移動

## nikic: Deprecate unbinding of $this of non-static methods
- https://github.com/php/php-src/commit/fc18f44213d59190a3e524e5c2f1a33f73be2cda
- 非 static メソッドの $this を [ReflectionMethod::getClosure()](http://php.net/manual/ja/reflectionmethod.getclosure.php) と [Closure::bindTo()](http://php.net/manual/ja/closure.bindto.php) などの組み合わせで潰す際、deprecation notice が出るよう修正
- 非 static メソッドを `::` で静的に呼び出すのは [7.0 で非推奨化された](https://wiki.php.net/rfc/reclassify_e_strict#calling_non-static_methods_statically)が、$this を外すのは実質的にこれと等価なため

## asgrim: Fix reflection arguments for sodium_memzero function
- https://github.com/php/php-src/commit/950c338f8012f8ca4a2928cc833fb7efa05a905e
- [7.2~]
- ext/sodium の [sodium_memzero()](http://php.net/manual/ja/function.sodium-memzero.php) が文字列の参照のみをとる関数だったのが、Reflection では長さとあわせて 2 引数が必須だったように見えていた問題の修正
- 元々 [PHP マニュアルの方も間違ってた](https://github.com/php/php-src/pull/3565)みたい

## carusogabriel: Use already set variable
- https://github.com/php/php-src/commit/257bec33f82668bce0e2615bfea67bf71339d7f1
- ext/standard で直前で変数に入れてるデータを無視してるような箇所があったので、使い回すよう微修正

## KalleZ: Fix some tests and improve coverage for Windows in SPL
- https://github.com/php/php-src/commit/8595dc8fa93237565217e7d8d42e7e79dcd427e7
- ext/spl のテストを修正、Windows でのカバレッジを向上
ApsaraDB for Memcacheのアップグレード/ダウングレードを試してみる

# はじめに
今回はAlibabaCloudのキャッシュサービス、Memcacheを
アップグレードをして見ます。

# インスタンス一覧から管理を選びます
![8fd1b25a.png](https://qiita-image-store.s3.amazonaws.com/0/241104/318fc48a-daf6-0fa8-02a7-b6330e5a1f4a.png)

# 設定を変更するを選びます
![a89b9431.png](https://qiita-image-store.s3.amazonaws.com/0/241104/3f1a29cd-3907-f2c7-c3ea-0217a4cddebd.png)

# その前に、実験でtelnetで接続しておきます。

```shell
[root@poc3 ~]# telnet m-e9bfbc2700f87e54.memcache.japan.rds.aliyuncs.com 11211
Trying 10.0.3.111...
Connected to m-e9bfbc2700f87e54.memcache.japan.rds.aliyuncs.com.
Escape character is '^]'.
version
VERSION 1.4.33
get hoge1
VALUE hoge1 0 4
hoge
END
```

# アップグレードを有効化します
**2G HA構成**に変更してみます。

![9e6894d4.png](https://qiita-image-store.s3.amazonaws.com/0/241104/573052a5-6546-fadc-4e07-ecc799f3d5f4.png)

![d25b3bb8.png](https://qiita-image-store.s3.amazonaws.com/0/241104/26de17f7-f74a-1804-e7d7-f9cb9893eb6f.png)

[ApsaraDB for Memcache 料金｜アリババクラウド](https://jp.alibabacloud.com/product/apsaradb-for-memcache#pricing)
にあるスペック変更されになりました。

# まとめ
## 変更中
変更中は、多少瞬断はされるようです。
なお、ダウングレードの際にも試して見ました。

```shell
get hoge1
VALUE hoge1 0 4
hoge
END
Connection closed by foreign host.
[root@poc3 ~]# telnet m-e9bfbc2700f87e54.memcache.japan.rds.aliyuncs.com 11211
Trying 10.0.3.111...
Connected to m-e9bfbc2700f87e54.memcache.japan.rds.aliyuncs.com.
Escape character is '^]'.
```

## 所要時間
### アップグレード
アップグレードは、あまり時間がかからず5分ぐらいでした。
しかしデータ量があると、変わると考えられます。

### ダウングレード
ダウングレードは、かなり時間かり10分以上を要しました。
2Gのところに1Gにしましたが印象的に長いと感じました。
こちらもデータ量があると、もっと変わると考えられます。
[プログラミングの課題] HTMLとCSS #1 Flexで横並び

# はじめに
HTMLとCSSでどのようにして、横並びにするのでしょうか。
今まではFloatが主流でしたが、回り込み問題などいろいろややこしかったですが、
Flexbox Layoutというものが出てきて、Floatを使用することなく簡単に横並びが出来るようになりました。


# Container と Item

<img width="1186" alt="Screenshot 2018-09-30 11.25.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/114543/caf40ad1-c434-f1bd-d2fd-6d1d75ac7593.png">
`参照: https://css-tricks.com/snippets/css/a-guide-to-flexbox/`

Flexを使用するとき、containerとitemsがあります。図とその名の通りの関係ですが、今回の例ではクラス名でそれぞれ `.container` と `.item` と名付けます。

それぞれに指定のプロパティを使うことでflexを使いこなせるようになります。

# 課題

<img width="890" alt="Screenshot 2018-09-30 11.42.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/114543/25b23ce6-f519-19d8-ef7b-2692f59e1182.png">

上記のような画像をHTMLとCSSを使用して作成してみましょう。

回答: https://jsfiddle.net/NaggiGoishi/6urw2qsb/

```
=====使用した色========
header: #008B8B
footer: #B8860B
container: #9932CC
item: #8B0000
=====================

=====WidthとHeight===
header height: 50px
footer height: 50px
item width: 200px
item height: 200px
====================
```
初心者がRailsガイドを1から100まで読んでみる　Railsをはじめよう編その13　データの削除

####5.13.記事を削除する
CRUDの最後の機能を実装しましょう。
Create→済
Read→済
Update→済
Delete→イマココ

<img width="491" alt="スクリーンショット 2018-09-16 23.04.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/f6cc9320-2622-def1-5d15-937568311d57.png">

おあつらえ向きなアクションがありますね。
そう、destroyアクションです。

それじゃあいつもの
①コントローラにアクションを追加
②ビューを作成
しましょう。

```article_controller.rb
class ArticlesController < ApplicationController

	def index
		@articles = Article.all
	end

	def show
		@article = Article.find(params[:id])
	end

	def new
  		@article = Article.new
	end
 
	def create
  		@article = Article.new(article_params)
	 
  		if @article.save
    		redirect_to @article
  		else
    		render 'new'
  		end
	end

	def edit
  		@article = Article.find(params[:id])
	end

	def update
  		@article = Article.find(params[:id])
 
  		if @article.update(article_params)
    		redirect_to @article
  		else
    		render 'edit'
  		end
	end

    def destroy
        @article = Article.find(params[:id])
        @article.destroy
  
        redirect_to articles_path
    end
  
	private
  		def article_params
    		params.require(:article).permit(:title, :text)
  		end
end
```

destroyアクションを追加しました。

```rb
    def destroy
        @article = Article.find(params[:id])
        @article.destroy
  
        redirect_to articles_path
    end
```

削除したい記事をfindしてdestroyしてますね。
そのあとarticles_pathにリダイレクトしている。
ルーティングから確認するとarticles_pathはindexアクションへのパスだ。
消した後一覧に戻る動きだね。

ビューだけど、削除ページなんて特にいらないので、一覧に削除するリンクを貼ればOK

```erb:index.html.erb

<h1>Listing Articles</h1>
<%= link_to 'New article', new_article_path %>
<table>
  <tr>
    <th>Title</th>
    <th>Text</th>
    <th colspan="3"></th>
  </tr>
 
<% @articles.each do |article| %>
  <tr>
    <td><%= article.title %></td>
    <td><%= article.text %></td>
    <td><%= link_to 'Show', article_path(article) %></td>
    <td><%= link_to 'Edit', edit_article_path(article) %></td>
    <td><%= link_to 'Destroy', article_path(article),
                    method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>
</table>
```

```erb
    <td><%= link_to 'Destroy', article_path(article),
                    method: :delete, data: { confirm: 'Are you sure?' } %></td>
```
他のリンクとちょっと違うけど、こう書くことで確認ダイアログが出てその後削除してくれる。

<img width="973" alt="スクリーンショット 2018-10-01 2.49.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/e5d873ee-adce-d287-d159-ec93b8f56ed3.png">

僕の黒歴史を全部消してやったぞ！
<img width="309" alt="スクリーンショット 2018-10-01 2.50.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/283826/c2b422f0-6980-fd06-eb67-21cf9342da3a.png">
Containing AppとApp Extensionを同時にデバッグする

# はじめに
Containing Appをデバッグ実行した時に
同時にApp Extensionのデバッグもする方法を纏めます。

# サンプルの構成
サンプルアプリは、以下の構成とします。

|Category|Target name|Description|
|:---:|:---:|:---:|
|Containing App|iOSTodayExtension|拡張元のアプリ<BR>(開発するアプリ)|
|App Extension|TodayEx|Today Extension|

# 何も考慮せずデバッグ実行する(失敗ケース)

```TodayViewController.swift:
extension TodayViewController: NCWidgetProviding {

    func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) {
        label.text = TodayViewData.fetchMessage()
        completionHandler(NCUpdateResult.newData)
    }

    func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
        switch activeDisplayMode {
        case .compact:
            preferredContentSize = maxSize
        case .expanded:
            preferredContentSize = CGSize(width: 0, height: expandedContentHeight)
        }

        // iOSTodayExtension(Containing App)実行時は、以下のデバッグログはコンソールに表示されない
        print("NCWidgetDisplayMode: \(activeDisplayMode)")
        print("preferredContentSize: \(preferredContentSize)")
    }
}
```

TodayEx側のコードに上記の通り、print文を書いてみたところ、

「TodayEx」を実行してwidgetの表示を増やしたり減らしたりしたところ、コンソールにログを出力できました。
また、上記TodayViewController内にブレイクポイントを設定したところ、ちゃんと停止しました。
![](https://farm2.staticflickr.com/1904/30075497137_a97ccdb110_z.jpg)

```
NCWidgetDisplayMode: NCWidgetDisplayMode
preferredContentSize: (0.0, 200.0)
NCWidgetDisplayMode: NCWidgetDisplayMode
preferredContentSize: (398.0, 105.0)
```

しかし、「iOSTodayExtension」を実行して同様にwidgetの表示を増やしたり減らしたりしたところ、
**コンソールにログが出力されませんでした。**
また、**ブレイクポイントを設定しても停止しませんでした。**

![](https://farm2.staticflickr.com/1960/31138886278_01c67685f0_z.jpg)

# プロセスにアタッチする
Containing AppとApp Extensionは、別のプロセスで動作するため
「iOSTodayExtension」実行時は、「TodayEx」の方はprint文の内容をコンソールに出力したり
ブレイクポイントで停止したりしていないようでした。


「iOSTodayExtension」実行後、

Debug > Attach to Process by PID or Name...
もしくは
Debug > Attach to Process
で、アタッチします。(以下のイメージは、「Attach to Process by PID or Name...」を選択した場合)

![](https://farm2.staticflickr.com/1938/43200365370_3904707ab7_z.jpg)

![](https://farm2.staticflickr.com/1929/44100915945_2da176133c_z.jpg)


ブレイクポイントで停止するようになりました！

![](https://farm2.staticflickr.com/1973/44293128804_47de795de1_z.jpg)

しかし、print文の内容は出力できておらず、これだけでは
毎回lldbのコマンドで値を出力させなければなりません。

![](https://farm2.staticflickr.com/1973/30076182217_fbd74d0c99_z.jpg)

# ブレイクポイントを編集してログを出力する
print文は機能しませんでしたが、ブレイクポイントは機能するようになったので
ブレイクポイントにログを設定することでコンソールにログを出力することができます。

![](https://farm2.staticflickr.com/1915/44101152155_90a83a8b79_z.jpg)
![](https://farm2.staticflickr.com/1935/44101152405_84fd3443ef_z.jpg)

一番下の「Automatically continue after evaluating actions」にチェックを付けることで、
ログを出力後処理を停止しないようになります。

# まとめ
Containing Appをデバッグ実行中にApp Extension側のデバッグをするには...

1. Debug > Attach to Process by PID or Name...(もしくはDebug > Attach to Process)からApp Extensionのプロセスにアタッチする
2. ブレイクポイントを編集して、ログを出力する
【Node.js】たった1行のプログラムでWebサーバを構築!?

# Node.jsとは？
- JavaScript(以下JS)でサーバ・バックエンド実装が行えるJS実行環境
- JSをWebブラウザの中でなく単独で実行できる
- JSベースだからフロントエンド経験者からの参入障壁が低い

# 1行でWebサーバを構築
Node.js自体の詳細やインストール方法等は他記事を検索いただくとして、
ここでは「1行でWebサーバを構築」するプログラム例をご紹介します！

Node.jsインストール後にJSファイルを一つ作成し（仮に”server.js”とする）、
以下のコードを入力します。

```Javascript:server.js
require('http').createServer(function(request,response){response.end("TEST");}).listen(3000);
```

これが「1行Webサーバ」になります。

上記ファイルの配置ディレクトリで以下のコマンドを実行します。

```
node server.js
```

Webブラウザを開き下記のアドレスにアクセスすれば”TEST”という文字列が表示されるはずです。
http://localhost:3000/

テキストを表示するだけの簡単なプログラムですが、「ブラウザからアクセスするとテキストを送り返す」というサーバ機能を非常に短いプログラムで実現しており画期的です！
以下はJSコードの仕組みを噛み砕いていきます👇

# 「1行Webサーバ」の仕組み
コードを1行で書きましたが短くするための書き方なので、
解説用に分解して書き換えると以下のようになります。

```Javascript:server.js
const http = require('http');	// …①
var server = http.createServer(
	function(request,response){
		response.end("TEST");
	}
);	// …②
server.listen(3000);	// …③
```

##### ①インターネットアクセスをするhttpオブジェクトを読み込む：
Node.jsのAPIモジュールとしてhttpオブジェクトというものがあります。
名前の通りでHTTPプロトコルを取り扱えるようになります。
requireメソッドはNode.jsのAPIモジュールを呼び出すことができます。
まとめると、httpオブジェクトを呼び出して定数httpに設定をしていることになります。

##### ②httpからサーバオブジェクトを作る：
httpオブジェクトにあるcreateServerメソッドを利用しています。
このメソッドは関数を引数に取り（後述）、Node.jsのサーバとなるhttp.Serverオブジェクトを作成します。
createServerメソッド中の関数ですが、引数を二つ渡しています。
引数requestはクライアントからサーバへ送られる情報を管理するオブジェクトで、
引数responseはサーバからクライアントへ送られる情報を管理するオブジェクトです。
サーバプログラムではこの二つの情報の行き来を考慮することが必須となります。
そして、responseオブジェクトのendメソッドでクライアントへの返信を終了します。引数にテキストを用意するとその内容を出力して終了します。
まとめると、誰かがブラウザでアクセスしてきたら必ず”TEST”という文字列を返すサーバを作ったことになります。

##### ③サーバオブジェクトを待ち受け状態にする：
待ち受けとはサーバにクライアントがアクセスしてくるのを待ち続けている状態を指します。
http.Serverオブジェクトのlistenメソッドは引数で指定した数値を待ち受けポート番号として設定します。これによりhttp://localhost:3000/ というアドレスに②の処理を反映できます。
まとめると、ここでWebページのアドレスを決定することになります。

# まとめ
Node.jsによるWebサーバ構築の流れは：
①インターネットアクセスをするhttpオブジェクトを読み込む
②httpからサーバオブジェクトを作る
③サーバオブジェクトを待ち受け状態にする

これらの処理をコンパクトなコードで表現できちゃうんです。
そう、Node.jsならね！
Node.js + Express + PostgreSQLによる英単語検索APIの開発 ～01. データ用意編～ 

# はじめに
Node.js + Express + PostgreSQLで英単語検索APIを開発しています。
この記事では「01. データ用意編」と称して、API開発に必要なデータ（英和辞書）の用意の仕方について記載しています。

パブリックドメインの英和辞書に対して、TreeTaggerのPython wrapperを使用して品詞のタグ付けを行いました。

# やったこと
## 必要なデータ(英和辞書）とは？
最低でも下記の3つは必要であろうと考えました。
 - 英単語
 - 日本語訳
 - 品詞情報

## データの取得
英単語と日本語訳については、下記のパブリックドメインの英和辞書を使用させて頂きました。
https://kujirahand.com/web-tools/EJDictFreeDL.php


## 品詞情報の付与
今回使用させて頂いた﻿上記パブリックドメインの英和辞書データ (ejdic-hand)には品詞情報がありませんでした。
英単語APIの作成にあたり、やはり品詞情報は必要でしょう。
そこで、英語（+様々な言語）に対して品詞タグ付けをすることができるTreeTaggerを使用し、品詞のタグ付けを行いました。

### TreeTaggerとは？
TreeTaggerは品詞タグ付け器です。英語をはじめ、多くの自然言語に対応しています。
Python、Ruby、Javaなどの、様々なの言語に対してwrapperが提供されています。
今回はPythonのwrapperを使用してタグ付けを行いました。
[TreeTagger公式ドキュメント](http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/)

### TreeTaggerのインストール
開発環境はUbuntu16.04です。
[公式ドキュメント](http://www.cis.uni-muenchen.de/~schmid/tools/TreeTagger/)通りに進めて、問題なくインストールすることができました。

### 品詞タグ付けのソースコード
```Python
#!/usr/bin/env python
#! -*- coding:utf-8 -*-

""" 英単語の品詞情報を取得する。
"""

import re
import treetaggerwrapper as ttw

def main():
    # TAGDIRを指定する必要がある。
    tagger = ttw.TreeTagger(TAGLANG='en',TAGDIR='/usr/local/src/treetagger')
    lines = read_file()
    result = []
    dict_def = load_def()
    for line in lines:
        try:
            english, japanese = line.split('\t')
            japanese = japanese.rstrip('\n')
            # 複数語は取り込み対象外とする。
            if re.match('.+[\s　].+', english):
                continue
            tags = tagger.TagText(english)
            tags2 = ttw.make_tags(tags)
            word_type = tags2[0][1]
            result.append(english + '\t' + japanese + '\t' + dict_def[word_type])
        except:
            continue
    write_file(result)

def read_file():
    """
    パブリックドメインの英語辞書データ
    https://kujirahand.com/web-tools/EJDictFreeDL.php
    """
    with open('./ejdic-hand-utf8.tsv') as f:
        return f.readlines()

def write_file(ary):
    with open('./ejdic-hand-utf8-with-word-type.tsv', 'w') as f:
        return f.write('\n'.join(ary))

def load_def():
    """
    TreeTaggerの付与する品詞タグを、実際の品詞表記に変換するための定義ファイル
    http://computer-technology.hateblo.jp/entry/20150824/p1
    """
    result = {}
    with open('./def_word_type.tsv') as f:
        for line in f.readlines():
            list_line = line.split('\t')
            result[list_line[0]] = list_line[3].rstrip('\n')
    return result

if __name__ == '__main__':
    main()
```
[リポジトリへのリンク](https://bitbucket.org/kmisogi/english_word_api/src/master/create_db/get_word_type.py)

### 結果
下記の通り、各英単語について品詞を割り当てることができました。
ejdic-hand-utf8-with-word-type.tsv より一部抜粋

``` tsv
afflict  (肉体的に,精神的に)(…で)…'を'『苦しめる』,悩ます(distress)《+『名』+『with』+『名』 (a person's do『ing』)》   動詞
affliction       (心身の)苦悩,難儀 / 苦悩(悩み)を引き起こすもの 名詞
affluence        (物質的な)裕福 / (思考・言葉などの)豊かさ      名詞
affluent         (物質的に)裕福な / (思考・言葉などが)豊富な,たくさんの;(…が)豊富な《+『in』+『名』》 / (川の)支流      形容詞
```
次回以降、こちらのデータを使用して英単語検索APIを開発していきます。
GPU/TPU で Mandelbrot (Google Colaboratory 編)　

#TensorFlow？
Google Colaboratory で TPU が使えるということで盛り上がっているようなので、訳の分からぬまま使ってみることにしてみました。Qiita 等各種記事を見る限り、TensorFlow というライブラリから呼び出すようになっているようです。

TensorFlow というものを調べてみると、どうも配列演算のサブルーチン集のようで、Fortran でいえば、’70年代や’80年代のアレイプロセッサ時代に逆戻りしたような趣きです。ただリダクション演算が拡張されていて、指定の任意の Rank 間でリダクション演算ができるようになっています。これは、Fortran で不満に思う所なので中々気が利くなと思いました。Tensor の名前の由来と思われます。

けしからんことに、各種言語用の API が用意されているのに、最もふさわしいと思われる Fortran 用がありません。**死刑！**ここでは、Python で利用してみます。

計算時間を比較すると、計算の性質かあるいは使い方を間違っているのか、GPU の方が TPU よりかなり速い感じでした。Mandelbrot 図形もなにか荒いので、計算間違ってるかもしれません。Python も初心者なので許してね。

###Google 謹製例題 　
[Hello, TPU in Colab](https://colab.research.google.com/notebooks/tpu.ipynb#scrollTo=PUINPtMG_w9i)

###TensorFlow マニュアル
[TensorFlow](https://www.tensorflow.org/api_docs/python/tf)

##プログラム
###GPU 

```python
import tensorflow as tf
tf.test.gpu_device_name()
```
```python
import numpy as np

N = 1024
Niter = 255
zero = tf.zeros([N, N])
one  = tf.fill([N, N], 1.0)
n = zero
x = np.linspace(-2.0, 1.0, N)
y = np.linspace(-1.5, 1.5, N)
xx = x[None, :]
yy = y[:, None]
c = tf.complex(xx, yy)
z = tf.multiply(c, 0.0)
for i in range(Niter):
    z = tf.add(tf.square(z), c)
    n = tf.add(n, tf.where(tf.abs(z) > 2.0, one, zero))
```
```python
sess = tf.Session()
```
```python
result = sess.run(n)
```
```python
%matplotlib inline
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (20.0, 20.0)
plt.imshow(result)
```
###実行例 GPU
![TFGPU.png](https://qiita-image-store.s3.amazonaws.com/0/44522/92c42ba9-76b8-f3b6-d4a2-89f573a5c523.png)

###TPU

```python
import tensorflow as tf
import os

tpu_address = 'grpc://' + os.environ['COLAB_TPU_ADDR']
print ('TPU address is', tpu_address)

with tf.Session(tpu_address) as session:
  devices = session.list_devices()
  
print ('TPU devices:')
devices
```

```python
import numpy as np

N = 1024
Niter = 255
zero = tf.zeros([N, N])
one  = tf.fill([N, N], 1.0)
n = zero
x = np.linspace(-2.0, 1.0, N)
y = np.linspace(-1.5, 1.5, N)
xx = x[None, :]
yy = y[:, None]
c = tf.complex(xx, yy)
z = tf.multiply(c, 0.0)
for i in range(Niter):
    z = tf.add(tf.square(z), c)
    n = tf.add(n, tf.where(tf.abs(z) > 2.0, one, zero))
```

```python
session = tf.Session(tpu_address)
try:
  print('Initializing...')
  session.run(tf.contrib.tpu.initialize_system())
  print('Running ops')
  result = session.run(n)
finally:
  # For now, TPU sessions must be shutdown separately from
  # closing the session.
  session.run(tf.contrib.tpu.shutdown_system())
  session.close()
```

```python
%matplotlib inline
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (20.0, 20.0)
plt.imshow(result)
```
###実行例 TPU
![TFTPU.png](https://qiita-image-store.s3.amazonaws.com/0/44522/bcd4178f-d4d4-aa35-cbd2-2c6b0f8d9f9f.png)

##参考
Python での初期座標の作り方は、以下のページを参考にしました。
http://www.turbare.net/transl/scipy-lecture-notes/advanced/advanced_numpy/index.html

```python
x = np.linspace(-2.0, 1.0, N)
y = np.linspace(-1.5, 1.5, N)
xx = x[None, :]
yy = y[:, None]
```
株価をscikit-learnで機械学習してみる　分類編

（注）ここでは最終結果だけでなくエラーの試行錯誤も含めて書いていきます。
　　　また、あくまで参考のため、全件で訓練し、同じデータで学習結果を確認します。

#目的
過去４日分を参考に日経平均を予測します。

#株価データの読み込み
松井証券のcsvから終値を読み込みます。

```
#coding: UTF-8
import pandas as pd
stock_data = pd.read_csv('stockchart_20180909.csv')
owarine = stock_data[['終値']]
```

(メモ)最初「終値」の表記ではダメでした。なぜか再度実行するとOK。理由は・・・なぜでしょう。


```
successive_data = []
answers = []
for i in range(4, count_s):
    successive_data.append([owarine[i-4], owarine[i-3], owarine[i-2], owarine[i-1]])
    answers.append(owarine[i])
```

successive_data：過去４日分の終値
answers：当日の終値

```
clf = svm.LinearSVC()
n = len(successive_data)
m = len(answers)
clf.fit(successive_data, answers)
```

##デバック
機械学習させるとエラーとなりました。
![dimension_err.jpg](https://qiita-image-store.s3.amazonaws.com/0/248083/80c9b26a-a545-e07a-c636-c8f3cca86c9a.jpeg)

「dim 3」は３次元配列になっているというエラーのようです。

よくよく見るとowarineが変です。
![owarine_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/248083/4a277393-4f34-862e-a8f3-35cd2a4a03eb.jpeg)

「[～],[～]」となっているため、1つの値の配列の1000個配列の1つのリスト扱いの模様です。pythonでは１つの値の配列ってできるんですね。

```
owarine = stock_data[['終値']]
↓
owarine = stock_data['終値']
```

ここの問題でした。pandasの複数列用サンプルそのまま使ったのが問題だったようです。

再度実施したところ別のエラーが発生です。
![ValueErr_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/248083/8792c1ce-8fc2-0f77-4d2e-eb0778e6e6b4.jpeg)

ググってみるとy値は整数でないといけないらしい。
よってanswersは整数にします。

```
answers.append(owarine[i])
↓
answers.append(round(owarine[i]))
```
![success_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/248083/34e336da-f5e9-c412-6555-bf1a47cd799e.jpeg)

fitが通ったので同じデータで結果を出力します。

```
predicted = clf.predict(successive_data)
```


![success_2.jpg](https://qiita-image-store.s3.amazonaws.com/0/248083/26193485-6daa-1615-4b77-08294c998d65.jpeg)

一応学習して数字が出ました。
でも同じ数字が大量に・・・これはSVMで学習したがためのようです。
SVMあくまで分類のため、教師ありの場合のどの値に近いか
出力したためのものです。
※SVMの説明は[こちら](https://qiita.com/hikaru_/items/3d64af35769235471d9c)が簡単で分かりやすそうです。

よってここでは教師データを日経平均ではなく前日との差とします。
ただ前日と比べて上がった/下がったは結構多くの人がやっていますのでちょっと趣向を変え
（日経平均_当日　－　日経平均_前日）÷ 100　を四捨五入した値を使います。
（例）前日から+180円なら+2、-310円なら-3、+30円なら0等。
大きさの幅があった方がリアルっぽくなるのかなと思います。
先ほど直したanswersを再度修正します。

```
answers.append(round(owarine[i]))
↓
x1 = (owarine[i] - owarine[i-1]) / 100
x2 =round(x1)
answers.append(x2)
```

##学習結果
このまま学習すると
![predict_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/248083/7b52f2aa-63b9-0b0f-4ea6-ff6add7dcc61.jpeg)


何やら2と-1ばかりで怪しげですが学習ができました。
※何度か試すと結果は変わりました。

##まとめ
結果を表示します。

```
from sklearn.metrics import accuracy_score
accuracy_score(answers, predicted)
```
![result.jpg](https://qiita-image-store.s3.amazonaws.com/0/248083/41b4b3f1-ef12-dfcf-b479-dad31a0eaef2.jpeg)

あまりよくはないようです。

###ソース
https://github.com/soshi8/finance1/blob/master/SVM_1.py
Python+Flask+MySQL on WindowsではじめるWebアプリ開発 #Step3

# はじめに

- 初心者が簡単なWebアプリを開発していきます。
- 手順をStep-by-Step方式で記載していきます。
  - [前回(Step2)](https://qiita.com/sireline/items/b29a90a350a1171fabc2)では、テンプレートを使ってみました。

# 開発環境

- Windows10 Home
- Python3.7.0 (pip 18.0)
 - Flask 1.0.2
 - Jinja2 2.10

# 前回の復習として

- 仮想環境**(step3)**を作成
- 仮想環境の有効化
- pipのアップグレード
- flaskのインストール
- アプリの作成
- テンプレートの作成

## Hello Flask

```py:hello.py
from flask import Flask
from flask import render_template

app = Flask(__name__)

@app.route('/')
def main():
    props = {'title': 'Step-by-Step Flask', 'msg': 'Hello World.'}
    html = render_template('hello.html', props=props)
    return html

if __name__ == '__main__':
    app.run(debug=True)
```

```html:templates\hello.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>{{props.title}}</title>
    </head>
    <body>
        <div id="contents">
            <p>{{props.msg}}</p>
        </div>
    </body>
</html>
```

# Step3 - ルーティングを利用する

## アプリを修正する
- **url_for, redirect**をインポートする
- main関数を修正
- hello関数の作成
- not_found関数の作成

```py:index.py
from flask import Flask
from flask import redirect
from flask import url_for
from flask import render_template

app = Flask(__name__)

@app.route('/')
def main():
    props = {'title': 'Step-by-Step Flask - index', 'msg': 'Welcome to Index Page.'}
    html = render_template('index.html', props=props)
    return html

@app.route('/hello')
def hello():
    props = {'title': 'Step-by-Step Flask - hello', 'msg': 'Hello World.'}
    html = render_template('hello.html', props=props)
    return html

@app.errorhandler(404)
def not_found(error):
    return redirect(url_for('main'))

if __name__ == '__main__':
    app.run(debug=True)
```

## テンプレートファイルを追加・修正する
```html:templates\index.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>{{props.title}}</title>
    </head>
    <body>
        <div id="contents">
            <p>{{props.msg}}</p>
        </div>
        <hr>
        <ul>
            <li><a href="/hello">Hello World</a></li>
        </ul>
    </body>
</html>
```

```html:templates\hello.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>{{props.title}}</title>
    </head>
    <body>
        <div id="contents">
            <p>{{props.msg}}</p>
        </div>
        <hr>
        <ul>
            <li><a href="/">Home</a></li>
        </ul>
    </body>
</html>
```

## 実行
- 環境変数の設定 SET FLASK_APP=**index.py**
- サーバ起動

### ルート(/)へアクセス

- http://127.0.0.1:5000/

![flask-fig3.png](https://qiita-image-store.s3.amazonaws.com/0/89366/fb3bb3ab-22f3-b53c-795a-a4bba18af401.png)

### /helloへアクセス

 - http://127.0.0.1:5000/hello

![flask-fig4.png](https://qiita-image-store.s3.amazonaws.com/0/89366/1b8b5105-f291-ab72-b7f2-578e75b25abd.png)

### /hogeへアクセス

- http://127.0.0.1:5000/hoge

存在しないページへのアクセスはルートへリダイレクトする。

# 今回のまとめ
- ルーティングを使うとページ遷移を制御出来ます。

# [Step4](https://qiita.com/sireline/items/8980110d945313cf7fab)で実施すること
- MySQLへ接続してみます。

# 参考リンク
- [Jinja2 Documents](http://jinja.pocoo.org/docs/2.10/)
Docker入門  Nginxを動かしてみる

DockerでNginxを動かしていこうと思います。

## Nginxのリポジトリをチェック
Docker HubのNginxのリポジトリを見に行く
https://hub.docker.com/r/library/nginx/

いろいろと使い方が記載されているので、それを参考にする
<img width="970" alt="スクリーンショット 2018-10-01 0.37.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/253092/ab9b028e-4f7b-7fce-49e3-95fdd6e291b2.png">

## Nginxの実行
Exposing external portに記載されているコマンドでNginxの初期画面を表示させてみる

```
$docker run --name hogehoge -d -p 8080:80 nginx
```
--name:　任意のイメージ名を指定する
-d:　デタッチモード　コンテナ実行時にバックグラウンドで起動する事ができる
（deamonのような常駐のプログラムでつかう)
-p　ホストのポート番号：コンテナのポート番号：　Webで叩くポート番号は実はコンテナのポート番号と紐付いてますよ。という宣言。

###実行結果
いえーい。表示された！
<img width="1440" alt="スクリーンショット 2018-10-01 0.56.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/253092/9bedc9dd-e095-5b61-3b15-fa27b6573db0.png">


###Q.-dしてないと何がかわるの？
フォアグラウンドで動作するために、それ以外の処理を実行することができない。
プロセスを終了させると、コンテナも停止してしまう。

下記のようにログが流れてくる

```
$docker run --name hogehoge  -p 8080:80 nginx
172.17.0.1 - - [30/Sep/2018:15:13:51 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36" "-"
```

###実行結果
実行画面も変化なし！！
<img width="1440" alt="スクリーンショット 2018-10-01 0.56.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/253092/9bedc9dd-e095-5b61-3b15-fa27b6573db0.png">



##Nginxで自分で作成したHTMLを表示させる

###表示させたいHTMLファイルを作成
`ｈｔｍｌ`というディレクトリを作ってその中にファイルを作成します。


```html

<!DOCTYPE html>

<html>
<body>

<h1>hugahuga</h1>
<p>husahusa</p>

</body>
</html>
```

作成したファイルのパスを確認します。

```
/Users/ユーザー名/workspace/dockerPractice/html
```

それでは、Nginxで上記ファイルを表示させるコマンドを実行していきましょう

###バインドマウントを使用してNginxを起動する

```
docker run --name hugahugahuga -v /Users/masa/workspace/dockerPractice/html:/usr/share/nginx/html:ro -d -p 8080:80  nginx
```

先程の起動と異なる部分は`-v'の部分

`-v ホストのディレクトリ：コンテナ側のマウントポイント：オプション`

今回はReadOnlyを示す`ro`オプションを指定している。

###実行結果
ちゃんとファイルがよみこまれているのがわかります。
<img width="1440" alt="スクリーンショット 2018-10-01 1.17.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/253092/00e72e02-df50-e064-27f2-3d61562ff8f4.png">


###バインドマウントのメリットは？
Nginxのコンテナ外にNginxで公開するコンテンツを配置することができるため
* 手元で簡単に更新をためすことができる
* Gitで管理することができる

これでサービス全体のディレクトリごとつなげてるんだろうな。


##参考
ゼロからはじめる Dockerによるアプリケーション実行環境構築
セッション4 chapter22~23
https://www.udemy.com/docker-k/
git を使って変更のあるファイルのみに対して xx する

# 変化があったものだけに何かしたい

git は CI を始めとして、いろいろ展開できるので、表示オプションがとても充実してます。

現実的にこれらを覚えるのは早々に諦めて、必要になったら調べるようにしているのだけど、新しい要望のために調べてると、こんなに簡単に書く方法があったのか (または書けるようになったのか) ということがあり関心します。

xx する部分はいろいろだと思うので、今回は例として php の Syntax check を行います。
静的解析が普及してきたので Syntax check なんて必要ないですけどね。

# 要はこれだけ

php の Syntax check 自体は `php -l file_path` で出来ます。

```sh
$ git diff master --name-only --diff-filter=ACMR *.php | xargs -IPATH php -l PATH
```

# 書きたいこと

どんな方法だって結果要件を満たせれば、正直どうでもいいのですが、こんな記事を書くには **へー** と思うことがあったわけで。

宇宙でもボールペン使えたら、ポケットにしまえて便利じゃん？ 鉛筆にキャップすりゃいいんだけど。

## git diff master --diff-filter=ACMR

`--diff-filter=ACMR` なんてあったんだ！ 言っといてや、できるんやったら…

昔はこんなんやってたわ。情弱やから。

```sh
$ git diff master --name-status | grep '^[MACR]' | awk '{print $2}'
```

ちなみに status の記号は下記。 `D` のファイルは存在しないわけだから除外したいんだよね。

| Symbol | 意味 | Note |
|:--:|:--|:--|
| M | 更新のあったファイル | Modified |
| A | 追加されたファイル | Added |
| C | コピーされたファイル | Copied |
| R | リネームしたファイル | Renamed |
| D | 削除されたファイル | Deleted |

`MACRD` は　*真っ黒だ*　で覚えられます。

## git diff master *.php

まぁ、最初からできたんだろうけど、その発想がなかったわ。愚か者やから。

```sh
$ git diff master --name-only | grep '\.php$'
```

こんなんやってたよね。
目的と手段が入れ替わってる感じあるよね。普通が一番だよ。

## 本題

ここ、絶対どうにかなるだろ。

`xargs -IPATH php -l PATH`

## 最後に

おっさん、コマンド組み合わせすぎ。
経験に学びすぎ。発想が固定化されてる。
awk とか若いものは使わないよ。カラムの編集オプションとか大体あるんだよ今どきは。

お疲れ様でした。
【Mac】汎用的に使える移動コマンド【これだけでも覚えるべき】

ChromeなどのWebブラウザ、テキストエディタ、ターミナル…などなど様々なアプリで使える汎用的な移動コマンドを紹介します。
とりあえず覚えて損は無いです！

※ 全てのアプリで必ずこの動きになるというわけではないです。ただ比較的共通するコマンドだと思います。

## 先頭・後尾
|  | コマンド |
|:-:|:-:|
| 先頭に移動 | cmd + ↑  |
| 後尾に移動 | cmd + ↓  |

### Chromeでの例
![web.gif](https://qiita-image-store.s3.amazonaws.com/0/126861/10b09583-1c3c-0600-9ff1-2970bf73cb07.gif)

## 行頭・行末
|  | コマンド |
|:-:|:-:|
| 行頭に移動 | ctrl + a |
| 行末に移動 | ctrl + e |

### テキストエディットでの例
行末→行頭→後尾→先頭
![texteditor.gif](https://qiita-image-store.s3.amazonaws.com/0/126861/9c3993ed-1778-4712-52c1-95afe08154ea.gif)
UniRxのFromCoroutineValueは同一フレームで実行される

# 起こった問題
UniRxのFromCoroutineValueはコルーチンから戻り値を受け取ってRxのストリームに流せるので便利なのですが、同一フレームで実行されるという罠がありました。FromCoroutineValueを使わずにFromCoroutineを使うことで解決できました。
# 普通のコルーチン
```csharp
public class CoroutineTest : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(MyCoroutine());
    }

    IEnumerator<int> MyCoroutine()
    {
        for(int i = 0; i < 10; i++)
        {
            Debug.Log(Time.frameCount); // コルーチン内で何フレーム目か表示
            int someValue = 10;
            yield return someValue;
        }
    }
}
```
[Unityではyield return以降は次フレームで実行される](https://docs.unity3d.com/ja/current/Manual/Coroutines.html)(Unityのyield returnの仕様と言うよりStartCoroutineの仕様？)ので適当なGameObjectに貼り付けて実行すると以下のような結果になります。
![aaa.png](https://qiita-image-store.s3.amazonaws.com/0/222469/65c77ac0-a3e6-53d1-5367-573bb50093f7.png)

# FromCoroutineValue
コルーチン内でなにか処理を行ってその結果```someValue```を返したいといったシチュエーションは結構あると思うのですが、通常のコルーチンでは厄介です。そんなとき便利なのがUniRxのFromCoroutineValueなのですがこれには同一フレームで実行されるという罠があります。

```csharp
void Start()
{
    Observable.FromCoroutineValue<int>(MyCoroutine)
        .Subscribe(v => {});
}
```
これを実行すると以下のようなログが出ます。
![bbb.png](https://qiita-image-store.s3.amazonaws.com/0/222469/2ad938ff-9837-b96d-29de-edefd5d8e6a9.png)
yield returnで次フレームに移っておらず同一フレームで実行されてしまっています。ですので無限ストリームが作りたいからといって以下のようなコードを書くと永遠に次フレームに移れないのでUnity Editorがフリーズします（悲しい世界）

```csharp
public class CoroutineTest : MonoBehaviour
{
    void Start()
    {
        Observable.FromCoroutineValue<int>(MyEndlessCoroutine)
            .Subscribe(v =>
            {
                Debug.Log(v);
            });
    }

    IEnumerator<int> MyEndlessCoroutine()
    {
        while (true)
        {
            yield return Random.Range(0, 10);
        }
    }
}
```

# じゃあどうするか
FromCoroutineを使ってIObserver経由で渡します。どういうわけか、FromCoroutineではyield returnで次フレームに移る仕様のようです。先程の無限ストリームは以下のように実現できます。

```csharp
public class CoroutineTest : MonoBehaviour
{
    void Start()
    {
        Observable.FromCoroutine<int>(observer => MyEndlessCoroutine(observer))
            .Subscribe(v => 
            {
                Debug.Log(v);
            });
    }

    IEnumerator MyEndlessCoroutine(IObserver<int> observer)
    {
        while(true)
        {
            yield return null;
            observer.OnNext(Random.Range(0, 10));
        }
    }
}
```
Gazebo on ubuntu 18

# Gazebo
- I just prepare new linux machine of ubuntu-1804 in Japanese customized one. 
- I installed Gazebo version 9.0 on this machine.
- I just followed [this tutorial](http://gazebosim.org/tutorials?tut=install_ubuntu) on Gazebo site. It was really simple. Install and run is just one line!

```
$ curl -sSL http://get.gazebosim.org | sh
$ gazebo
```
It really worked.
![image.png](https://qiita-image-store.s3.amazonaws.com/0/294040/4096d1ec-bc2e-8e4c-1ca7-00bc79bd1653.png)
なぜrebase後に強制プッシュをする必要があるのか

# rebase後の強制プッシュ

以下のようにfeatureブランチをmainブランチにrebaseして最新のmainを取り込むことはよくあると思います。

```
$ git pull --rebase origin main
```

で、それをリモートにpushしようとすると、**fast-forwardできないからpushできないよ!**と怒られます。

```
$ git push origin feature1
To github.com:hitochan777/test.git
 ! [rejected]        feature1 -> feature1 (non-fast-forward)
error: failed to push some refs to 'git@github.com:hitochan777/test.git'
(以下略)
```

これを解決するためには強制プッシュをするとうまくいきます。

```
git push origin feature1 -f
```

# なぜ強制プッシュする必要があるのか
ポイントは**pushはリモートブランチがfast-forwardできることを想定している**ということです。
どういうことか、具体的に例を考えてみましょう。

`origin/feature1`がC3を、`feature1`がC5を指している状態を考えます。

```
C1--C2--C3          <- origin/feature1 (C5までfast-forwardできる)
         \        
          C4--C5    <- feature1
```

この場合、`origin/feature1`はC5までポインターを進められる(fast-forward)ので、
強制プッシュをしなくてもプッシュは成功します。

ではfeature1ブランチをorigin/mainブランチにrebaseしている場合はどうでしょうか。

```
C1--C2--C3--C6--C7  <- origin/main
         \        
          C4--C5    <- feature1, origin/feature1
```

rebase後は次のようになります。`origin/main`にrebaseをすると`feature1`と`origin/main`の共通の祖先から`origin/mai`が指すコミットまでの**コミットのコピー**が作られます。下図ではC4', C5'としています。

```
C1--C2--C3-------C6--C7--C4'--C5'   <- feature1
         \  
          C4--C5                    <- origin/feature1
```

この場合`origin/feature1`のポインターを前に進めて(fast-forwardして)feature1と
同じコミットを指すようにすることはできないので、エラーが出てしまいます。

# おまけ

`feature1`を複数人で共有している場合を考えます。
他のメンバーによって`origin/feature1`がアップデートされたとしましょう。(C8の追加)
ここで、このことに気づかず`feature1`を強制プッシュしてしまうと、リモートブランチは上書きされ、C8は消えてしまいます。

```
C1--C2--C3-------C6--C7--C4'--C5'   <- feature1
         \  
          C4--C5--C8                <- origin/feature1
```

こういったことが起きないように `--force-with-lease`というオプションがあります。
vee-validateで入力検証を実行

## 概要
入力検証の定義をJavaScript側にまとめられないか調べた内容をメモしておく。

## 実装方法
下記のやり方でうまくいったので、添付しておく。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Validation</title>
</head>
<body>

  <div id="app">
    <h1>Vee-Validateのテスト</h1>

    <div>
      <label>タイトル</label>
      <div :class="{'is-error': errors.has('title') }">
        <input 
          type="text"
          name="title"
          v-model="title"
          v-validate="'required|max:20'"
          data-vv-as="タイトル">
      </div>
      <!-- エラーの個別表示(タイトル) -->
      <p v-show="errors.has('title')">{{ errors.first('title') }}</p>
    </div>

    <button type="button" @click="submit">作成する</button>
    <!-- エラーの個別表示(お知らせ) -->
    <div v-show="errors.has('notification')">{{ errors.first('notification') }}</div>

    <!-- 全てのエラーをまとめて一箇所に表示する場合 -->
    <div v-show="errors.any()">
      <p v-for="error in errors.collect()">{{ error }}</p>
    </div>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.13"></script>
  <script src="https://cdn.jsdelivr.net/npm/vee-validate@2.1.0-beta.9/dist/vee-validate.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vee-validate@2.1.0-beta.9/dist/locale/ja.js"></script>
  <script>
    Vue.use(VeeValidate);

    new Vue({
      el: '#app',
      // データ
      data: {
        title: null
      },
      created() {
        // メッセージを日本語に設定する
        this.$validator.localize('ja');
      },
      methods: {
        submit: function () {
          // お知らせメッセージを初期化
          this.$validator.errors.remove('notification');

          // バリデートの判定
          this.$validator.validateAll().then((result) => {

            if (result === false) {
              // 入力エラー
              this.$validator.errors.add({field: 'notification', msg: '入力エラーがあります...'});
              return false;
            }

            // 何かしらの処理...
            const is_success = (Math.random() > 0.3);
            if (!is_success) {
              // お知らせメッセージをセットする
              this.$validator.errors.add({field: 'notification', msg: '処理に失敗しました...'});
              return false;
            }

            //エラーがなかった時の処理を下に記述
            alert('Submit OK.')
          });
        }
      }
    });
  </script>
</body>
</html>
```
## 実行結果
作成ボタンを押すと、エラーメッセージが３つ表示されました。
![test.png](https://qiita-image-store.s3.amazonaws.com/0/142279/4d7bf5ef-becf-a4b5-e654-a1d00f39e1b8.png)

## まとめ
v-validate属性で各htmlタグに定義することもできるが、敢えてJavaScript側で定義できないかやってみた。
独自ルールなどを定義することもあると思うので、JS側にまとめて定義しておいた方がメンテが楽かな...

## 参考サイト
- [VeeValidate - Custom Rules](https://baianat.github.io/vee-validate/guide/custom-rules.html#creating-a-custom-rule)
- [validateAll() not running on validations attached in child component](https://github.com/baianat/vee-validate/issues/974)
- [VeeValidateで複数のフィールドにバリデーションをかけるやり方](https://qiita.com/_Keitaro_/items/c06210d69f8c8382dfab)
- [Vee-validate : how to attach several validation rules after object constructed](https://stackoverflow.com/questions/50050515/vee-validate-how-to-attach-several-validation-rules-after-object-constructed)
- [VeeValidate を使って、vue.jsで簡単にバリデートしてみた](https://qiita.com/youdie/items/417ed2df1bcb6a60001c)
REST APIについて

# RESTとは
REpresentational State Transferの略で、分散型システムにおける複数のソフトウェアを連携させるのに適した設計原則の集合、考え方のこと

## RESTの原則
主に以下の4つの原則から成る

- アドレス可能性(Addressability)
    - 提供する情報がURIを通して表現できること。全ての情報はURIで表現される一意なアドレスを持っている
- ステートレス性(Stateless)
    - HTTPをベースにしたステートレスなクライアント/サーバプロトコルである
    - セッション等の状態管理はせず、やり取りされる情報はそれ自体で完結して解釈できる
- 接続性(Connectability)
    - 情報の内部に、別の情報や(その情報の別の)状態へのリンクを含めることができる
- 統一インターフェース(Uniform Interface)
    - 情報の操作(取得、作成、更新、削除)は全てHTTPメソッド(GET、POST、PUT、DELETE)を利用する

# REST API
- RESTの原則に則って構築されたWebシステムのHTTPでの呼び出しインターフェース
    - HTTPメソッド, パラメータ, URI, レスポンス形式等の項目に該当する

## REST APIのメリット
- URIに規律が生まれ、APIを利用する開発者が把握しやすく実装しやすい
- ブラウザへURIを入力するだけでリソースの参照ができる
- ステートレスであり、サーバ・クライアント間で何も共有しないため、負荷に応じたスケーラビリティを向上することができる
- HTTP標準のメソッドを使うことで、シンプルかつ一貫性のあるリクエストが円滑に行うことができる

## リソース設計
1. 何をリソースとするか決める。APIの利用者がどのようなリソースを必要としているか、そのリソースをどのように利用するかといったユースケースを考えながらリソースを抽出する
2. 抽出したリソースに対して、どのようなCRUD操作が必要かを検討する
3. リソース間の従属関係(親子関係)を明確にする
4. リソースの各項目のデータ型の定を行う
5. リソース定義を明文化する

## HTTPメソッド
クライアントが行いたい処理をサーバに伝えるという役割を担い、その種類は以下の9つ

- GET
    - リソースの取得
- POST 
    - 子リソースの作成, リソースへのデータ追加, その他処理
- PUT
    - リソースの更新, リソースの削除
- DELETE
    - リソースの削除
- HEAD
    - リソースのヘッダ (メタデータの取得)
- OPTIONS
    - リソースがサポートしているメソッドの取得
- TRACE
    - プロキシ動作の確認
- CONNECT
    - プロキシ動作のトンネル接続への変更
- PATCH
    - リソースの部分的な変更

## CRUD
以下をCRUDとし、これらは基本的にCreate, Read, Update, Deleteにより満たすことができる

- Create（作成）
    - メソッド : POST/PUT
- Read（読み込み）
    - メソッド : GET
- Update（更新）
    - メソッド : PUT
- Delete（削除）
    - メソッド : DELETE

### PUT？ POST？
PUTもPOSTもCreate（リソースの作成）に当たるが、冪等性から使い分けることができる

- PUT: リソースの作成、リソースの置換
    - リソース名を指定して作成または更新をかけるメソッド
- POST: リソースの作成
    - Idempotent（冪等）な操作で、何度やっても同じ結果になるような処理

## 設計指針ポイント
- PUT
    - 更新成功の場合 → 204 No Content
        - クライアントにとって思い通りの結果になったということなので、中身は重要ではなく204で十分
- DELETE
    - 成功時 → 204 No Content
        - リソースがないので204が最適
- 失敗した時
    - 4xxは通知することでクライアントまたはユーザが反応できる可能性があるときに利用する
 
# 便利ツール
APIのテストでは、「REST Client （Chrome Extension）」が便利

# 参考
- [RESTful APIとは何なのか](https://qiita.com/NagaokaKenichi/items/0647c30ef596cedf4bf2)
- [MDN HTTPリクエストメソッド](https://developer.mozilla.org/ja/docs/Web/HTTP/Methods)
- [ステートフル ステートレス](http://blog.sojiro.me/blog/2014/09/13/stateful-and-stateless/)
- [RESTful APIのリソース設計](https://qiita.com/NagaokaKenichi/items/ef23ca15ba0e9e5ee022)
- [RESTful API設計におけるHTTPステータスコードの指針](https://qiita.com/uenosy/items/ba9dbc70781bddc4a491)
- [HTTPメソッド(CRUD)についてまとめた](https://qiita.com/Ryutaro/items/a9e8d18467fe3e04068e)
- [PUTかPOSTかPATCH か？](https://qiita.com/suin/items/d17bdfc8dba086d36115)
Python+Flask+MySQL on WindowsではじめるWebアプリ開発 #Step2

# はじめに

- 初心者が簡単なWebアプリを開発していきます。
- 手順をStep-by-Step方式で記載していきます。
  - [前回(Step1)](https://qiita.com/sireline/items/288cd0eb193962f774d5)では、環境構築からHelloWorldまで実施しました。

# 開発環境

- Windows10 Home
- Python3.7.0 (pip 18.0)
 - Flask 1.0.2
 - Jinja2 2.10

# 前回の復習として

- 仮想環境**(step2)**を作成
- 仮想環境の有効化
- pipのアップグレード
- flaskのインストール
- アプリの作成

## Hello Flask

```py:hello.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def main():
    return 'Hello World.'

if __name__ == '__main__':
    app.run(debug=True)
```

# Step2 - テンプレートを利用する

## テンプレート用のフォルダを作成する
```txt
(step2) C:\pystudy\lesson-flask>mkdir step2\templates
```

## アプリを修正する
- **render_template**をインポートする
- main関数を修正
 - テンプレートへデータ受け渡し
 - テンプレートファイルの指定

```py:hello.py
from flask import Flask
from flask import render_template

app = Flask(__name__)

@app.route('/')
def main():
    props = {'title': 'Step-by-Step Flask', 'msg': 'Hello World.'}
    html = render_template('hello.html', props=props)
    return html

if __name__ == '__main__':
    app.run(debug=True)
```

## テンプレートファイルを作成する

```html:templates\hello.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>{{props.title}}</title>
    </head>
    <body>
        <div id="contents">
            <p>{{props.msg}}</p>
        </div>
    </body>
</html>
```

## 実行
- 環境変数の設定
- サーバ起動

![flask-fig2.png](https://qiita-image-store.s3.amazonaws.com/0/89366/a13a77d3-6f61-8d1c-914d-227874ce681d.png)

# 今回のまとめ
- テンプレートを利用するとヘッダーやフッターなどを使いまわせたりして便利です。
- コンテンツを動的に作成出来るようになります。

# [Step3](https://qiita.com/sireline/items/13451d8457d0b7d53e96)で実施すること
- ルーティングを使ってみます。