OmniAICreator/Qiita-1.07M huggingface dataset:
STARTTLS ゲートウェイとしての StreamRelay.NET.exe

### STARTTLS ゲートウェイとしての StreamRelay.NET.exe

![StreamRelay017.png](http://rocketeer.dip.jp/sanaki/free/StreamRelay017.png)

### STARTTLS ゲートウェイとしての StreamRelay.NET.exe (StartTLS サーバ)

`StreamRelay.NET.exe -LocalPort 25 -RemotePort 192.0.2.3 -RemotePort 25 -LocalProxy "starttls://?command=STARTTLS^&SuccessMessage=200 Go ahead"`

とすると、サーバ側の STARTTLS 機能の代理をする事ができる。

### STARTTLS ゲートウェイとしての StreamRelay.NET.exe (StartTLS クライアント)

`StreamRelay.NET.exe -LocalPort 90 -RemotePort 192.0.2.2 -RemotePort 25 -RemoteProxy starttls://?command=STARTTLS^&SuccessMessage=200`

とすると、STARTTLSクライアントとなり、開始コマンドをまちつつ、TLS 開始時にはSSLクライアントになれる。
こうすれば、nc.exe(netcat)で、(StreamRelay.NET.exe経由で)StartTLSサーバに接続して、デバグできるよ。

てか「-LocalPort 90」を「-LocalPort 0」にすれば、StreamRelay.NET.exe がキーボード/コンソールの送受信を担当できるので、netcat 必要ないけどね。

### オプション

SSLProxy と同じオプションに加えて、開始コマンドを示す「command」と成功時の応答メッセージ、または成功時の応答メッセージの一部を示す「SuccessMessage」

### 方向を逆転させる

![StreamRelay019.png](http://rocketeer.dip.jp/sanaki/free/StreamRelay019.png)

<dl>
 <dt>Server と Client
  <dd>既定では、TCPのハンドシェイクの方向と、SSLのハンドシェイクの方向は同じだが、SSLプロキシの設定と同じように、反対にすることができる
 <dt>StartTLSServer と StartTLSClient
  <dd>既定では、TCPのハンドシェイクの方向と、StartTLS のハンドシェイクの方向は同じだが、SSLプロキシの設定と同じように、反対にすることができる
</dl>

つまり、TCP(通信) の方向と、SSL の方向、StartTLS の方向(StartTLSサーバとクライアントの位置関係)は、設定によって、自由にできます

---
### 本家の該当箇所
[本家の該当箇所](http://rocketeer.dip.jp/sanaki/free/free119.htm#STARTTLDDetail)

---
### STARTTLSクライアントにもなる

「StartTLSClientNoDelay」オプションを使う事で、接続後にStreamRelay.NET.exe自身が STARTTLSクライアントとなって、SSL接続を開始させられる。

`StreamRelay.NET.exe -LocalPort 90 -RemotePort 192.0.2.2 -RemotePort 25 -RemoteProxy "starttls://?command=STARTTLS&SuccessMessage=200 2.0.0&StartTLSClientNoDelay"`

という感じ。

「SuccessMessage」を「200」ではなくて「200 2.0.0」とより具体的に書いているのは、SMTPサーバのHELLOメッセージと混同する事を避けるためです。
(そして、半角スペースがあるので、ハット(^)を取ってダブルクォート(")で囲んだ)

つまり「200」だけだと、

1.接続
2.STARTTLS開始のコマンド「STARTTLS」を送信
3.接続先/相手(SMTPServer)の Helloメッセージ(200 OKとか)が返る
4.ここで、成功と判断してSSLハンドシェイク開始
5.2.の「STARTTLSいいよ」メッセージが SSLハンドシェイク中に返る
6.SSLハンドシェイクエラー

となってしまうので、「200 2.0.0」とすることで

1.接続
2.STARTTLS開始のコマンド「STARTTLS」を送信
3.接続先/相手(SMTPServer)の Helloメッセージ(200 OKとか)が返る
4.ここではまだ、成功と判断しない
5.2.の「STARTTLSいいよ」メッセージ(200 2.0.0)が返る
6.SSLハンドシェイク開始

となって、接続直後に StartTLS 接続を成功させることができる

---
### SMTP認証と兼ねる

StreamRelay.NET.exe は SMTP 認証も兼ねる事ができるよ。

[SMTP認証を代替するStreamRelay.NET.exe](https://qiita.com/tomoki0sanaki/items/57a0cdd2c448770f73d4)

---
### 目次へ戻る

[目次というか最初の一歩](http://qiita.com/tomoki0sanaki/items/85f20cbe18378e33cd6f)
api.aiとa3rtのtalkAPIでfacebookメッセンジャーを作る

# 概要
* 「あなたのお名前は？」や「生年月日は？」などの固定メッセージを返したい部分は[api.ai](https://docs.api.ai/)を利用して、その他の自由会話は[a3rtのtalkAPI](https://a3rt.recruit-tech.co.jp/product/talkAPI/)に任せる。
* api.aiのwebhookを利用して、特定の会話の時は外部APIを利用して天気/ニュースを返す。   
※今回は面倒なので空実装。箱だけ用意しておく。
* webhookの実装はjavaで行う。

# api.ai
## agent
* agentはbot本体。。と私は思っている。。
* 名前、言語、タイムゾーンの設定くらいで難しいことはない。
* 今回はエージェント名を`kunipon`にした。笑

## intent
* intentはユーザーが「何を知りたがっているのか？」や「どんな感情か」などを、ユーザーがどんなことを言ってきそうかを登録することで分類しておく箱。
* ユーザーの会話に対してのレスポンスを複数登録できて、ランダムで返してくれる
* 今回は以下を登録

| インテント名    | 登録会話例                         | レスポンス |
|:--------------|:----------------------------------|:------------------|
| acquaintance  | 「お名前は」「あなたは誰」            | kuniponです |
| age           | 「何歳」「あなたの年齢は」            | 9歳です |
| teach_me      | 「教えてください」「明日の東京の天気は」 | ※ここは後述 |

## entity
* インテントに登録した文章の本質を特定するために使用する。
 * 例えば今回は天気/ニュースを本質的に知りたがっているかを判別したいので、"teach_me"intentの中でも「明日の天気を教えてください」や「今日のニュースを教えて」などを特定するためにentityを登録する。
* 1つのentityに複数の項目と、項目に対する類義語を登録できる。   
※用途によっては類義でなくても構わない。   
* 今回以下のように登録した。

| エンティティ名 | リファレンス名  | シノニム例                   |
|:-------------|:-------------|:----------------------------|
| teach_me     | weather      | 「天気」「晴れ」「暑い」        |
| teach_me     | news         | 「ニュース」「出来事」「トピック」|

## intent2
* ユーザーの会話がteach_meインテントに属することを判別した後に、ユーザーが何に対してteach_meな状態なのかを判別しなくてはならない。そのために、インテントにはエンティティを紐づけることができる。
* 会話の中に紐づけたエンティティが存在しない場合、デフォルトのレスポンスとは別のレスポンスを返すことができる。
* 今回は、例えばユーザーが「教えてください」という文章の場合に「天気かニュースならお調べできますが、どちらになさいますか」というレスポンスを返すように設定
* 以下のようにAction項目ないのテーブルのteach_meエンティティにrequiedチェックがついていて、promptsにレスポンスを登録する
![apiai-intent-teachme.png](https://qiita-image-store.s3.amazonaws.com/0/135808/30379e67-3a47-0c35-8fe2-b29e85b92d77.png)

## 一旦試してみる
* エンティティとして登録した「天気」という単語が入っているのでparameterのteach_meがweatherになっているのがわかると思います。

![apiai-try1.png](https://qiita-image-store.s3.amazonaws.com/0/135808/421442a7-847d-227a-3a97-db208a7bdc03.png)

## default fallback
* 登録してあるインテントに合致しない会話が来た時にコイツが反応する。
* actionは自分で決められるが、defaultはinput.unknownか

## webhook
* 特定のインテントの時にapi経由でデータを取得して、取得データをレスポンスとして返したい時に使用する
* まずfulfillmentページでwebhookをenableにして、URLをセットする。
* URLはlocalhostなどは登録できず、publicなURLをセットしろと怒られるが、この時点で焦ってherokuやなんやを使う必要はない。ってかherokuあげたらデバッグできないし。。開発時であればngrokを使うようにgoogleも言っている。   
[Local fulfillment testing with ngrok](https://developers.google.com/actions/tools/ngrok)
* ngrokは`brew cask install ngrok`でインストールして、`ngrok http 8080`的なことすると`Forwarding                    https://abcd1234.ngrok.io -> localhost:8080`的な感じでpublicなURLできる。
* そのあとに対象のインテントページに行って、1番下の方にあるFulfillmentをクリックすると表示される「Use webhook」をチェック
 * teach_meインテント(apiで情報を持ってくるようにするため)とdefault fallback(api.aiでunknownの時にa3rtのtalkAPIに流すため)でチェック

# facebook messenger
* api.aiとの統合に関しては、[こちら](https://api.ai/docs/integrations/facebook)にドキュメントあります。
* こんな感じで会話できます。
![demo.png](https://qiita-image-store.s3.amazonaws.com/0/135808/25975228-825c-a82c-d8cb-dab4a625f01b.png)


# 最後に
* [github](https://github.com/api-ai/apiai-java-client)のsampleが参考になります。
* 実際のソースです。どなたかの参考になれば。。
gitでrevertされたブランチをrebaseして学んだ事

`git rebase`に関して、色々なサイトの説明を読んでいて勘違いしていた事があった。

今までは
**git rebase → そのブランチで行った変更を、rebase対象のブランチの変更の後に実施するような形のマージを行う**
だと思っていた。

ブランチ管理のルール上origin/masterへのmerge前にrebaseが必須だったものを、今回rebaseせずにmergeしてしまった事により
revertしてやり直す事になった。

自分のローカル作業ブランチには修正したものが変わらずあったので、何の躊躇もなく

`git rebase origin/master`

を実行したところ、修正が全部消えてしまった。

**「あれれれー」**

自分の想定では、rebaseすることで
**現在のorigin/masterの変更が適用された後、作業ブランチで作業した変更が適用**
こうなると思っていたが、どうやら少し違うようだ。

自分の作業ブランチで行われたすべての変更を、対象ブランチの差分取得後に適用すると思っていたのだがこれは大きな勘違いだった。
比較対象との最新の共通の祖先まで戻り、そこからの差分を適用するということらしい。

どうやらこういうことらしい

https://liginc.co.jp/web/tool/79390
```
1. 現在のブランチ（D,E,Jコミット）でおこなわれた変更を一時的に保存
2. 移行先のブランチ（master）にリセットする（git reset --hard master）
3. 1.で一時的に保存したコミットを順番に適用していく（親が違うので、コミットIDも変わる）
```

この1.の部分が、ブランチを切った時点の話だと思い込んでいた。
だがいったんmergeしてしまうと、今度はそこが起点になるようだ。

今回の場合は過去にコミットした修正対象のコミットをcherry-pickすることで解決した。
【Java】一時ファイルを作成する

#目的
- 任意のディレクトリにファイルを作成したい。
- 複数作りたいので、ファイル名は被って欲しくない。
- 作成したファイルは一時的に利用して、破棄したい。

#微妙なやり方
ファイル名を一意にするために、現在のミリ秒を利用した例。
勿論、確実にかぶらないとは言い切れない。。。

```java:
// 現在のミリ秒を取得
long millTime = System.currentTimeMillis();
String fileName = "tmp_" + millTime + ".txt";
File file = new File(fileName);
```
#素敵なやり方
FilesクラスのcreateTempFileメソッドを利用する。(Java7以降)

```java:
Files.createTempFile(Paths.get("任意のディレクトリ"), "prefix", "suffix");
```

以下は、一時ファイルを作成し、書き込んだのち、削除する例。

```java:
File file = null;
try {
  Path tmpPath = Files.createTempFile(Paths.get("/tmp"), "prefix", ".suffix");
  file = tmpPath.toFile();
  
  // ファイルに書き込み
  FileWriter fw = new FileWriter(file, true);
  BufferedWriter bw = new BufferedWriter(fw);
  PrintWriter pw = new PrintWriter(bw);
  pw.write("こんにゃく");
  pw.flush();
  pw.close();
} catch (IOException e) {
  e.printStackTrace();
} finally {
　// ファイルを削除
  if (file != null && file.exists()) {
    file.delete();
  }
}
```

Java6までの場合は、FileクラスのcreateTempFileメソッドを使えばできる。
参考
https://docs.oracle.com/javase/jp/8/docs/api/java/io/File.html#createTempFile-java.lang.String-java.lang.String-java.io.File-
TeraTermでLinuxONEにログインする方法

## はじめに
IBM LinuxONEというサーバーを構築し、TeraTermでそのサーバーにログインする方法を紹介します。
IBM LinuxONEは、半年間無料で使えるサーバーですので、よろしければお試しください。


## サーバーの構築、ログイン
### LinuxONEの登録
下記URLからIBM LinuxONEの登録をします。
https://developer.ibm.com/linuxone/

登録方法は、下記URLを参考にしてください。
http://dotnsf.blog.jp/archives/2017-01-04.html  

### LinuxONEで仮想サーバーを作成
1. 「Virtual Services」の「Manage Instances」をクリックして、仮想サーバーを作成します。
![linuxone1.png](https://qiita-image-store.s3.amazonaws.com/0/185050/c28c4c05-8080-86d4-dfb8-5cb0e06da8a8.png)  
　　
2. 「create」ボタンから、仮想サーバーを作成します。 
![linuxon2.png](https://qiita-image-store.s3.amazonaws.com/0/185050/a973b6d7-15f3-7a5d-0a3f-62465b0dc709.png)
　　
3. Step1のInstanceに関する情報を設定しますので、下記を入力してください。  
    「Instance name」:任意の名前  
    「Instance Description」:「RHEL」    
![instance1.png](https://qiita-image-store.s3.amazonaws.com/0/185050/c6d2cc69-0ca9-5619-f9a2-d56d76188531.png)  
　　
4. Step2の「Select an Image」に任意のディストリビューション／バージョンを選択します。  
![instance2.png](https://qiita-image-store.s3.amazonaws.com/0/185050/3487c485-2b99-a42f-2d4b-45e805f50387.png)  
　　
5. Step3の「Select a Flavor」で任意のサーバースペックを選択します。  
![instance3.png](https://qiita-image-store.s3.amazonaws.com/0/185050/8d0ce584-0ac1-c6bb-392d-cf7a4e55bf51.png)  
　　
6. Step4の「Select a SSH Key Pair」で「create」ボタンをクリックします。

![linuxone3.png](https://qiita-image-store.s3.amazonaws.com/0/185050/cb97cf3a-03e7-a3ce-8c70-e1df786bf926.png)  
　　
7. createボタンをクリックすると鍵の作成画面になりますので、「OK」をクリックします。
鍵の作成ができると、鍵を選択できるようになるので、鍵を選択し、「create」ボタンをクリックします。  
![linuxone6_1.png](https://qiita-image-store.s3.amazonaws.com/0/185050/4f00e67b-9120-1770-4edd-7ec494ce0b34.png)  
　　　　
8. サーバーが「Active」になるまで待ちます。
「Active」になったら、「IP Adress」をメモしておきます。
![linuxone8_1.png](https://qiita-image-store.s3.amazonaws.com/0/185050/76bde2e9-6fd9-9426-2e92-2ca66d5b8119.png)

### TeraTermでLinuxONEにログイン
1. Tera Termを開きます。  
「ホスト」に先ほどメモしたIPアドレスを入力し、「SSH2」を選択し、「OK」をクリックします。  
![teraterm1.png](https://qiita-image-store.s3.amazonaws.com/0/185050/663d5b03-54b8-1bf3-e286-66f7e3da4dff.png)  
　　
2. サーバーにログインします。  
「ユーザー名」に任意の名前を入力し、「秘密鍵」にLinuxONEのサーバーを構築した際に作成した秘密鍵を指定します。  
![teraterm2.png](https://qiita-image-store.s3.amazonaws.com/0/185050/aa4c527f-c0c1-2936-d60f-5fabe0b5ee8e.png)  
　　
3. サーバーにログインできましたら、下記の画面が表示されます。
![teraterm4.png](https://qiita-image-store.s3.amazonaws.com/0/185050/d8442af6-2a4d-be65-6305-2c453c44bac3.png)
json を読み込んで ObjectMapper のクラスのテストを書く

[ObjectMapper](https://github.com/Hearst-DD/ObjectMapper) は Swift の Json Parser の1つです。
Mappable を継承して Entity Object を作る事ができます。

```swift
import ObjectMapper

class User: Mappable {
    var id: Int = 0
    var familyName: String = ""
    var givenName: String = ""

    required init?(map: Map) { }

    func mapping(map: Map) {
        id <- map["id"]
        familyName <- map["family_name"]
        givenName <- map["given_name"]
    }
}

extension User {
    public var fullName: String {
        return familyName + " " + givenName
    }
}
```

このクラスのテストを書くときに、 User のデータを JSON ファイルから読み込んでテストができるようにしていきます。

## JSON ファイルの準備

User.json というファイル名で JSON を作成します。

```json
{
    "id": 1,
    "family_name": "苗字",
    "given_name": "名前"
}
```

## JSON の読み込み方法

まず User.json のファイルを読み込みます。

```swift
let url = Bundle(for: type(of: self)).url(forResource: "User", withExtension: "json")!
let json = try? String(contentsOf: url)
```

そして、その json を Mapper で読み込む事ができます。

```swift
let mapper = Mapper<User>()
user = mapper.map(JSONString: json!)
```

## 実際のテストファイル

ここでは Quick + Nimble でテストを書いています。 

用意した User を使い、テストを書いていきます。
イニシャライズは終わっているので、 User の挙動をテストするだけですね。

```swift
import Foundation
import Quick
import Nimble
import ObjectMapper

class UserSpec: QuickSpec {
    override func spec() {
        var user: User!
        let mapper = Mapper<User>()

        beforeEach {
            let url = Bundle(for: type(of: self)).url(forResource: "User", withExtension: "json")!
            let json = try? String(contentsOf: url)
            user = mapper.map(JSONString: json!)
        }

        describe("mapping") {
            it("JSON のパラメータがマッピング出来ていること") {
                expect(user.id).to(equal(1))
                expect(user.familyName).to(equal("苗字"))
                expect(user.givenName).to(equal("名前"))
            }
        }

        describe("fullName") {
            it("全角スペース区切りのフルネームを取得すること") {
                expect(user.fullName).to(equal("苗字　名前"))
            }
        }
    }
}
```

## おわり

ObjectMapper を利用した Entity のテストが書けるようになりました。
ネストの深い Object でも JSON を用意すればいいので、テストが簡単にかけます :muscle: 

Swift4 では Codable が出てくるので ObjectMapper が不要になりますね、 Swift4 が待ち遠しいです :relaxed:
Anaconda環境に引っ越す

#Anacondaでやっちまう

opencv3がAnacondaじゃないと上手く使えなかったりしたので、カッとなって全部Anacondaに依存しようと決意しました。当然、このままでは全くSeleniumも一からやり直しです。

```
$ conda create -yn py3.5 python=3.5
$ source activate py3.5
```

AnacondaProjectsディレクトリで作業することにしたので、

```
$ cd AnacondaProjects
```

仮想環境にある状態でpipを使ってインストールしていきます。本来conda〜　でやるほうがいいらしいですが、現状問題も起きてないし楽だしいいかな、なんて。

```
$ pip install selenium
$ pip install lxml
$ pip install beautifulsoup4
```

Chromedriverはサイトから落としてきたやつをそのまま移動しました。

<img width="201" alt="スクリーンショット 2017-06-29 15.30.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/71585/d6fbdf6b-2b26-c68f-e875-fd21c8e16662.png">

#動くかチェック

```test.py
import os, re
import lxml.html
import time
import bs4
from selenium import webdriver

browser = webdriver.Chrome('./chromedriver')
url = 'http://orteil.dashnet.org/cookieclicker/'
browser.get(url)
time.sleep(5)

for _ in range(100):
    try:
        push = browser.find_element_by_id('bigCookie')
        push.click()
    except:
        print('error')
```

バッチリ動きました。やったぜ！
Unicode文字列のサロゲートペア文字の文字コードを取得する

Scalaで絵文字などのサロゲートペアを含むUnicode文字列を変換し、サロゲートペア文字の文字コードを取得する方法。
地味にはまった。 単純にtoHexStringして連結すればOK

```scala
  def convert(str: String): String = {
    val sb = new StringBuilder
    for (i <- 0 until str.length)
      yield sb.append("\\u%s".format(str(i).toHexString))
    sb.toString
  }
```

なお、
http://qiita.com/sifue/items/039846cf8415efdc5c92
に記載の通り、Java的に書く方法も存在するが、
`Character.codePointAt(str, 0)` の値が4桁x2のサロゲートペア文字列ではなく、5桁の値が取得されてしまった。
Scalaであれば、`str(i).toInt.toHexString`でやりたいことは出来るので、難しく考えなくても良いかもしれない。
dockerコンテナ内のファイルをsshfs経由でローカルエディタで開く



この記事は
===

* リモートマシンのVirtualBox上のLinuxにdockerを入れて開発作業をしています
* docker内のファイルをローカルのエディタで編集するための設定のメモです

接続の構成
===

* Mac => VSCode => sshfs => ssh => dockerホストのLinux => ローカルファイル => dockerファイル

dockerコンテナのファイルのありかを見つける
===

* dockerコンテナ内のファイルは実はホスト側から丸見えの場所に置いてあります
* dockerのホストのLinuxにつないでまずどこにそれがあるかを探します

```:Ubuntuホスト
# コンテナ名testのコンテナIDを特定しておきます
$ docker inspect test | grep '"Id"'
        "Id": "28dd68cd116f243829d01c1494b00125f5e62832c62f240ae8be647ae59fdf08",

# コンテナIDからマウントIDを特定します
$ cat /var/lib/docker/image/overlay2/layerdb/mounts/cd0d6013b8972e2fcde25854509e916398d2aeb01888a32c7ea41b04b2495d45/mount-id
5c73e7776f5b5b6c6e292b12fa8546479b5ee7708f2132b4a232afa2aa2623b9

# マウントIDからコンテナのディレクトリを特定します
# ↓ここがtestコンテナのディレクトリ！
$ cd /var/lib/docker/overlay2/5c73e7776f5b5b6c6e292b12fa8546479b5ee7708f2132b4a232afa2aa2623b9/merged/
```

Mac:sshfsでマウント
===

sshfsとは
---

* dockerホストのマシンはsshでアクセスできます
* Mac上でsshfsでマウントすることで、sambaだとかを入れなくてもローカルファイルのようにつなぐことができます

fuseのインストール
---

```:Mac
brew install osxfuse
sudo /bin/cp -RfX /usr/local/opt/osxfuse/Library/Filesystems/osxfusefs.fs /Library/Filesystems
sudo chmod +s /Library/Filesystems/osxfusefs.fs/Support/load_osxfusefs
```

sshfsのインストール
---

```:Mac
brew install sshfs
```

マウント
---

```:Mac
mkdir /path/to/mountdir
sshfs root@172.16.xx.xx:/var/lib/docker/overlay2/5c73e7776f5b5b6c6e292b12fa8546479b5ee7708f2132b4a232afa2aa2623b9/merged/ /path/to/mountdir
```

エディタからアクセス
===

* 普通にエディタから/path/to/mountdirを開くことができます

終わりに
===

* これでdockerで環境作りまくってもお気に入りのエディタで開発ができますね！

おまけ
===

パスを探すスニペット貼っときます。パラメータにコンテナIDを渡してください。

```ruby:find_mount_dir.rb
require 'json'

inspect_json = `docker inspect #{ARGV[0]}`
image_id = JSON.parse(inspect_json)[0]['Id']
#puts image_id

mount_id = `cat /var/lib/docker/image/overlay2/layerdb/mounts/#{image_id}/mount-id`
#puts mount_id

path = "/var/lib/docker/overlay2/#{mount_id}/merged/"
puts path
```
URLRewiteツールとしての StreamRelay.NET.exe

---
### URLRewiteツールとしての StreamRelay.NET.exe

-r オプションで、リクエスト側通信パケットの最初のLfまでの一番最初の「/」をにょろにょろに書き換える。

`-r /webApp/../`
とすると、通信データのリクエスト側の「/」が「/webApp/../」に置き換わる。

正確には、通信データのリクエスト側パケットの最初のLfまでに「/」があれば、その最初の「/」が「/webApp/../」に置き換わる

---

例えば、192.0.2.1:80 はリバース・プロキシで、「/webApp/」以下を 192.0.2.2:80 の「/webApp/」以下に転送している。(しかも、バスの正規化をしていない)
という前提であれば、
`StreamRelay.NET.exe -LocalPort 80 -RemotePort 80 -RemoteHost 192.0.2.1 -r /webApp/../`
として、このStreamRelay.NET.exe に nikto.pl を実施すれば、リバース・プロキシの背後の Webサーバを適切に診断することができるかもしれない。

---
### 目次へ戻る

[目次というか最初の一歩](http://qiita.com/tomoki0sanaki/items/85f20cbe18378e33cd6f)
Swift3でスクロール画面で固定されたビューを実現するには

# 参照

[スクロール画面で固定されたビューを実現するには](http://xyk.hatenablog.com/entry/2014/09/30/140419)


![01.gif](https://qiita-image-store.s3.amazonaws.com/0/135794/6179964f-d50e-ad1e-f096-c0066639ed37.gif)


# 実装

contentOffsetを使えばスクロール画面で固定されたビューを実現することができます。

```swift


func scrollViewDidScroll(_ scrollView: UIScrollView) {

        // スクロール中の処理
        print("didScroll")

        固定させたいビュー.frame = CGRect(x:0+scrollView.contentOffset.x, y:0, width:0, height:0)
        

    }


```
express-restify-mongoose のアクセス制御


## リクエストの認可

ログインの有無による認可は options.preMiddleware で行う。

```javascript
preMiddleware: function (req, res, next) {
  if (req.isLoggedIn()) {
    next()
  } else {
    res.status(403).end()
    // Or `next(new Error('hoge hoge'))`
  }
}
```

## フィールド単位のアクセス制御

ログインの有無やロールに応じて、一部のフィールドをレスポンスから除外することもできる。

```javacsript
// Server
restify.serve(router, mongoose.model('Hoge', new mongoose.schema({
  name: String,
  zip: String,
  city: String
})), {
  access: function (req) {
    return req.isLoggedIn() ? 'protected' : 'public';
  },
  protected: ['zip', 'city']
});

// Client（未ログイン時）
$http.get('/api/v1/Hoge').then(res => {
  console.log(res.data)
})
# -> [{ name: 'fuga' }, { name: 'pico' }...]
# zip/city は protected なのでレスポンスに含まれない
```

全てのフィールドを protected や private に指定し除外しても、空のオブジェクトが返却される。

```javascript
// Server
restify.serve(router, mongoose.model('Fuga', new mongoose.schema({
  nyaa: String,
  nyannya: String
})), {
  access: function (req) {
    return req.isLoggedIn() ? 'protected' : 'public';
  },
  protected: ['nyaa', 'nyannya', '_id', '__v']
});

// Client（未ログイン時）
$http.get('/api/v1/Fuga').then(res => {
  console.log(res.data)
})
# -> [{}, {}, {}, {}...]
```
Dropboxの認証コード

古いiOSのブラウザではloginボタンが有効にならずにログインできないので、他の環境でログインと許可して、認証コードでOAuth2を使ってみました。

https://www.dropbox.com/1/oauth2/authorize

をredirect_uri無し,response_type=codeで叩くと以下のページに遷移してコードが取得できます。

![スクリーンショット（2017-06-29 14.22.02）.png](https://qiita-image-store.s3.amazonaws.com/0/104066/6515570f-687d-5e4a-b153-23f6effa3456.png)


このコードを以下のAPIに放り込むとAccess Tokenが取得できます。

https://api.dropbox.com/1/oauth2/token

いろいろ試したら以下のようなエラーがあるようです。

```json
{"error": "Call requires one of the following methods: POST, OPTIONS. Got GET."}
```

これはプログラムのミスでGETでアクセスしてしまったのでPOSTに直しました。

```json
{"error_description": "code has expired (within the last hour)", "error": "invalid_grant"}
```

アクセスコードを払い出してから1時間以内でないと無効になるようです。

一度使ってしまった認証コードは使えないようです。

```json
{"error_description": "code has already been used", "error": "invalid_grant"}
```

コードが空だとこんなエラーです。

```json
{"error_description": "\"code\": must not be empty", "error": "invalid_request"}
```

```json
{"access_token": "xxx", "token_type": "bearer", "uid": "yyy", "account_id": "zzz"}
```

正しくアクセスできると上記のように返ってきます。
Visual Studio 2017 > DataSet Visualizerの開き方

```txt:動作環境
Windows 8.1 Pro (64bit)
Microsoft Visual Studio 2017 Community
```

DataSet型の変数を用意した後、その中身を表示している例がある。
DataSet Visualizerというものらしい。

開き方は以下で見つけた。
https://msdn.microsoft.com/ja-jp/library/d480bk47.aspx

上記の記載通りではないが、DefaultViewManagerの虫メガネをクリックするとDataSet Visualizerが開いた。

![2017-06-29_14h19_41.png](https://qiita-image-store.s3.amazonaws.com/0/32870/50f2ee7f-a3f1-a64d-0df0-d61c8ce41a1d.png)

![2017-06-29_14h27_30.png](https://qiita-image-store.s3.amazonaws.com/0/32870/8bec8674-8480-e392-e462-d4a2928e334f.png)
Swift3の文字列操作

Swift3の文字列操作の自分用メモです。paiza.ioで動作確認済みです。ご自由に利用ください。

# 置換
abc2017 という文字列の中から、abc という文字列を、def という文字列に置換してから出力したい場合、こう書きます。

```
import Foundation
var str = "abc2017"
str = str.replacingOccurrences(of:"abc", with:"def")
print(str)
// def2017 が出力される
```
1行目：これを書かないと、2行目で使っている`replacingOccurrences`が使えません。

2行目：abc2017 という文字列を用意して、str という名前を付けました。

3行目：`str = str.replacingOccurrences(of:"abc", with:"def")`と書くことで、文字列変数strの、abc という文字列を、def に置換した結果を、str に再代入できます。
of:""の""の間に置換する前の文字列、with:""の""の間に置換した後の文字列を指定します。
結果として、文字列変数strの中身は、"def2017"になっています。

4行目：文字列変数strを出力します。def2017 が出力されます。

### おまけ
2,3,4行目をまとめて書くこともできます。

```
import Foundation
print("abc2017".replacingOccurrences(of:"abc", with:"def"))
```

# 削除
abc2017 という文字列の中から、abc という文字列を削除してから出力したい場合、こう書きます。

```
import Foundation
var str = "abc2017"
str = str.replacingOccurrences(of:"abc", with:"")
print(str)
// 2017 が出力される
```
置換する場合とほぼ同じです。with:""の""の中に空の文字列を指定しています。こうすることで、abc という文字列は、空の文字列に置き換えられます。つまり、abc という文字列を削除できます。

### おまけ
短く書けます（説明が雑）

```
import Foundation
print("abc2017".replacingOccurrences(of:"abc", with:""))
```

# 文字列の長さを取得
文字列の長さを知りたいときはこう書きます。

```
var str = "abc2017"
var length = str.characters.count
print(length)
// 7 が出力される
```
1行目：abc2017 という文字列を用意して、strという名前を付けました。

2行目：`var length = str.characters.count`と書くと、文字列変数strが何文字あるかを、Int型で変数lengthに代入できます。

3行目：変数lengthの値を出力します。

### おまけ
1行で書けます

```
print("abc2017".characters.count)
```
[C#]配列二つを受け取って特定の要素のみが一致するものを返すLINQ

# どゆこと
**※ほぼ自分用の覚書になります**
言葉にしづらいのでこんなタイトルになりました
正確には以下のとおりです
- とあるクラス`User`があり、`User`は名前とIDを持っている
- DBから全ユーザー一覧を取得して`List<User>`を作成する
- とある箇所で一部のユーザーIDのみを列挙したリスト`List<int>`を取得する
- IDリスト`List<int>`に列挙されたIDを持つ`User`を`List<User>`で取得したい

言葉にするとすごいわかりづらいなぁ…

## こういうこと

```csharp:LINQ.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

class Program
{
    static void Main(string[] args)
    {
        List<int> IDList = new List<int> { 1, 3, 5, 7 };

        //今回はDB用意するのは面倒なので適当にユーザーデータを作成する
        List<User> UserList = new List<User>
                        { new User { ID = 0, Name = "ID0" },
                          new User { ID = 1, Name = "ID1" },
                          new User { ID = 2, Name = "ID2" },
                          new User { ID = 3, Name = "ID3" },
                          new User { ID = 4, Name = "ID4" },
                          new User { ID = 5, Name = "ID5" },
                          new User { ID = 6, Name = "ID6" },
                          new User { ID = 7, Name = "ID7" } };

        //IDListにあるIDを持つUser一覧を取得する
        foreach (var item in UserList.Where(x => IDList.Contains(x.ID)))
        {
            Console.WriteLine(item.Name);
            //result -> ID1, ID3, ID5, ID7
        }

        Console.ReadKey();
    }
}

class User
{
    public int ID { get; set; }
    public string Name { get; set; }
}
```

なんでこんな単純なLINQが思いつかなかったのか…
普段`Where(x => x.ID == ほにゃらら)`という書き方ばかりしていたので
`Where(x => [boolが返る式なら何でもOK])`という基本ルールをすっかりと忘れていました

**@kiichi54321提案 : List<int>ではなくHashSet<int>を使うことでパフォーマンス向上させることが出来ます**

```csharp
HashSet<int> IDList = new HashSet<int> { 1, 3, 5, 7 };
```

**@yuba さんに別解を提示していただきました、コチラもかなり有用です**

```csharp
UserList.Join(IDList, u => u.ID, id => id, (u, id) => u)
```
Rubyだけでできる、静的なマスタデータをテーブルなしで持つ方法

# テーマ
## 静的なマスタデータをテーブルやGemを使わずRubyで作ってみる
とりあえずGemを使えばいい？ 本当に必要そうなGemのみ使うようにして**Rubyでできることは自前でやってみようよ。**
マスタデータをサクッと持ちたい場合、テーブル作ったり、[Gem active_hash](https://github.com/zilkey/active_hash)を使わなくてもできるよ。


# サンプルを作ってみる
[東京都の市区町村データを使ったサンプルアプリ](https://github.com/kaorina/jpaddress-rails)のデータを使いながら実践していきます。

[物件検索サービス](http://suumo.jp/chintai/tokyo/city/)などでよく使われている東京都のエリア（都心部、23区東部、23区西部等）のデータをサンプルにしてみる。
（全てのデータを作るのは大変だったので、都心部、23区東部のみ作成してます。）

`app/models`下にclassファイルを作成し、**ActiveRecordでおなじみのメソッドはもちろん使えないので、自分で定義する。**
今回は`all`, `find`系を定義

```ruby:app/models/tokyo_area.rb
class  TokyoArea
  class << self
  def all
    [
      {id: 1, name: '都心部', cities:[{id: 13101, name: "千代田区"}, {id: 13102, name: "中央区"}, {id: 13103, name: "港区"}, {id: 13104, name: "新宿区"}, {id: 13105, name: "文京区"}, {id: 13113, name: "渋谷区"}]},
      {id: 2, name: '23区東部', cities:[{id: 13106, name: "台東区"}, {id: 13107, name: "墨田区"}, {id: 13108, name: "江東区"}, {id: 13118, name: "荒川区"}, {id: 13121, name: "足立区"}, {id: 13122, name: "葛飾区"}, {id: 13123, name: "江戸川区"}]}
    ]
  end

  def find(id)
    self.all.find{ |item| item[:id] == id.to_i }
  end

  def find_by_name(name)
    self.all.find{ |item| item[:name] == name }
  end

  def find_by_id(id)
    self.find(id)
  end
  end
end
```

rails consoleで試してみる

```ruby:
pry(main)> TokyoArea.all
=> [{:id=>1, :name=>"都心部", :cities=>[{:id=>13101, :name=>"千代田区"}, {:id=>13102, :name=>"中央区"}, {:id=>13103, :name=>"港区"}, {:id=>13104, :name=>"新宿区"}, {:id=>13105, :name=>"文京区"}, {:id=>13113, :name=>"渋谷区"}]},
 {:id=>2, :name=>"23区東部", :cities=>[{:id=>13106, :name=>"台東区"}, {:id=>13107, :name=>"墨田区"}, {:id=>13108, :name=>"江東区"}, {:id=>13118, :name=>"荒川区"}, {:id=>13121, :name=>"足立区"}, {:id=>13122, :name=>"葛飾区"}, {:id=>13123, :name=>"江戸川区"}]}]

pry(main)> TokyoArea.find(1)
=> {:id=>1, :name=>"都心部", :cities=>[{:id=>13101, :name=>"千代田区"}, {:id=>13102, :name=>"中央区"}, {:id=>13103, :name=>"港区"}, {:id=>13104, :name=>"新宿区"}, {:id=>13105, :name=>"文京区"}, {:id=>13113, :name=>"渋谷区"}]}

pry(main)> TokyoArea.find(1)[:cities]
=> [{:id=>13101, :name=>"千代田区"}, {:id=>13102, :name=>"中央区"}, {:id=>13103, :name=>"港区"}, {:id=>13104, :name=>"新宿区"}, {:id=>13105, :name=>"文京区"}, {:id=>13113, :name=>"渋谷区"}]

pry(main)> TokyoArea.find(1)[:cities].map { |item| item[:id] }
=> [13101, 13102, 13103, 13104, 13105, 13113]
```
おー、あたかもデータベースから取得しているかのようにかけました！
もちろん、定義した通り、**取得した結果は配列とハッシュで返ってくる**ところが違いますね。

# まとめ
今までRailsだけでなく、Rubyが使えるとRails側でなんとなくいい感じにやってくれてあまり考えなかった実装の裏側がクリアになり構造を理解できるようになる気がします！
今まではGemを深く考えることなく使っていたのですが、Gemの先々のサポート体制など自分ではコントロールできない問題もあるので、その際の選択肢としても**自分でできることは自作する**という観点も持っておこうと思います╭( ・ㅂ・)و
色んなディレクトリに対応したデバイス振り分けリダイレクト

```js
// スマホの判定
const isMobile = (() => {
  // 省略（適当に作る）
})();

/**
 * @param {Object} [opts]
 * @param {string} [opts.root]
 * @param {string} [opts.spDir]
 */
const deviceRedirect = (opts = {}) => {
  const { root, spDir } = Object.assign({ root: '/', spDir: 'sp/' }, opts);
  const { pathname } = location;

  if(pathname.match(new RegExp(`^${ root }${ spDir }`))) {
    if(isMobile) return;
  } else {
    if(!isMobile) return;
  }

  const _before   = isMobile ? `^${ root }` : `^${ root }${ spDir }`;
  const _after    = isMobile ? (root + spDir) : root;
  const _pathname = pathname.replace(new RegExp(_before), _after);

  const { protocol, host, search, hash } = location;
  location.href = `${ protocol }//${ host }${ _pathname }${ search }${ hash }`;
};
```

## 使い方
```js
// 例1
// PC    -> '/'
// スマホ -> '/sp/' 
deviceRedirect();

// 例2
// PC    -> '/sample/'
// スマホ -> '/sample/mobile/' 
deviceRedirect({ root: '/sample/', spDir: 'mobile/' });
```
Emacs。もはや何でもありのエディタ。でも素晴らしい。

Emacsって本当になんでもできるんだなぁ...と驚かされる日々です。
ネットの情報を漁っては追加追加、たまに削除。あれ？動きおかしい！
ということを繰り返しながらも自分のエディタが自分色に染まっていくのを高揚しながら使っています。

今日、なんでもありやん！と認識したEmacsの素敵なパッケージを幾つか書き残す
**想定読者**
自分。
Emacs歴１ヶ月前後。
では早速...

## Google翻訳
常日頃キーボードから手を話したくないと思いながらも日本人なのでこの変数名どうしよう？クラス名どうする？
悩み、そしてブラウザから翻訳サイトへアクセスする日々。
これを何とかする方法ないだろうか？
Emacsならもしかしたら辞書機能とかあるかも？
そう思って検索したら出てきました...
そう「Google翻訳」ですよ。APIになってEmacsのパッケージに取り込まれたのか...？
しかも英語から日本語、日本語から英語、単語単位、文章単位での翻訳に対応しているという...
至れり尽くせり。神かよ...
Githubで書き方を調べるついでにネットでどんな設定しているのか調べてみたらカーソル乗ってる単語をショートカットキーで翻訳してくれる設定だったり、日本語と英語を動的に切り替えて翻訳してくれたりと...
これは**ますますEmacs**が好きになる。（声に出して読みたい日本語感がある）
やばい...

## popwin
Google翻訳は機能そのものが神ってるから気にしていなかったけどEmacsには`popwin`というパッケージが存在するそうで（Google翻訳調べてたら一緒に出てきた）もともと何もなければEmacsの画面を分割して表示してくれるんだけどpopwin使うともっと手軽に翻訳機能を召喚することができる。（控えめに出てすぐに消せるってことさ。）
これは単体では使わないけど全体としてはすごいことだと思うの。

## shell-pop
それでpopwin関連のおもしろ機能もついでに検索してたら出てきたのがshell-pop。こいつもやばい。
EmacsはエディタのくせにEmacsからシェルを操作することができるんです。
しかも多重起動もできる上にシェルにも選択肢がある。
そこは非常に気に入っていたんだけど使うにはEmacs内にタブを出したりと結構ガッツリ使う感じに...
そして今日、それらを解決決する方法に出会ってしまった。それがshell-pop
popwinと同じ感じで指定した場所に指定したサイズでミニウィンドウを召喚、そして**好きなシェル（これ重要）**を利用してコマンドを実行できる。
テストとかのためにターミナル内に大量のタブを出したりしなくてもさくっと終わらせることができる。
Emacsを導入したらぜひとも使ってほしいパッケージたちですよ！
---
あとがき
やはりEmacsはすごい。
設定ファイルがカオスになってるといえばそうだけどそれすら愛せるようになってきた。
（）のカオスは戦闘力の証。
僕lisp書けないけどEmacs lispなら書いてみようかなってちょっと思うもんな。。。
Emacsは美しい...
ローマ数字とアラビア数字の互換（自己流）

先日、表記関連のqiita投稿を拝見しました。
http://qiita.com/Saayaman/items/b8390cf4b5050694ae9f

ローマ数字からアラビアへの変換に興味深々で、自分流でやってみました！

## ローマ数字とアラビア数字の互換
###アラビア数字からローマ数字へ (mode = 1)
例：943 = CMXLIII

Input = 943

|roman|arabic|value|
|:-:|:-:|:-:|
|M|1000|0|
|CM|900|1|
|D|500|0|
|CD|400|0|
|C|100|0|
|XC|90|0|
|L|50|0|
|XL|40|1|
|X|10|0|
|IX|9|0|
|V|5|0|
|IV|4|0|
|I|1|3|

答えは roman * valueです。ここで、Output = CMXLIII

###ローマ数字からアラビア数字へ　（mode = 2）
mode1より少し複雑なので、2stepを分けて変換します。

step1

例：IX = 9

Input = IX

|roman|arabic|sign|
|:-:|:-:|:-:|
|I|1|-1|
|X|10|1|

次の数字より値が小さい場合、signを-1にする。(sign)
arabic * signalの合計を計算する。
Output = 1*(-1)+10*1 = 9

step2
step1で得られたOutputをもう一度ローマ数字に変換する。
変換されたローマ数字はInputと一致すれば、Outputは答えとなる。

ここで、
変換されたローマ数字 = IX = Input
なので、
Output = 9

例（×）: Input = VX
step1で Output = 5 得られるが、step2で、 もう一度ローマ変換の答え「V」と一致しないので、VXはローマ数字として存在しない。

## 演習

```
>>> Rom_Arab(Input = 'DCXXI', mode = 2)
>>> 621

>>> Rom_Arab(Input = 939, mode = 1)
>>> 'CMXXXIX'

>>> Rom_Arab(Input = 'IIXV', mode = 2)
>>> 'error'

>>> Rom_Arab(Input = arab, mode = 1)
>>> 'error'
```

## コード
```Rom_Arab.py
def Rom_Arab(Input,mode):
    
    import numpy as np
    
    romanValues = np.array(['M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I'])
    arabicValues = np.array([1000,900,500,400,100,90,50,40,10,9,5,4,1],dtype = int)

    def RomantoArabic(roman):

        result_arabic = 0
        
        if isinstance(roman,str) == True:         
            n = len(roman)
            value = np.array([0] * n)
            sign = np.array([1] * n)
            for i in range(0,n):
                if sum(romanValues == roman[i]) == 1:
                    value[i] = arabicValues[romanValues == roman[i]]
                else:
                    result_arabic = 'error'
                    break
                if i > 0 and value[i-1] < value[i]:
                    sign[i-1] = -1
            if result_arabic != 'error':
                result_arabic = int(value.dot(sign))
                
        else:
            result_arabic = 'error'

        return result_arabic
    
    def ArabictoRoman(arabic):

        result_roman = ''
        
        if isinstance(arabic,int) == True and arabic >0:        
            for i in range(0,len(arabicValues)):
                k = arabic // arabicValues[i]
                if k > 0:
                    arabic = arabic - arabicValues[i] * k
                    result_roman = result_roman + str(romanValues[i]) * k
        else:
            result_roman = 'error'

        return str(result_roman)
    
    if mode == 1:
        result = ArabictoRoman(Input)
    if mode == 2:
        Output = RomantoArabic(Input)
        if ArabictoRoman(Output) == Input:
            result = Output
        else:
            result = 'error'
        
    return result
```
stringをこねくり回すネタ集 swift 3.0

これだけ読んでおけば、stringがいじり放題って感じのネタ集作りました〜。
stackoverflow いちいち調べるの面倒なので、自分用メモとして。

## 1. substring()

```
var str = "Hello, playground"
```

### substring(to: )
*startIndex()は最初から読んでoffset個目の数字、endIndex()は最後から読む*
*Stringの中の文字をIndexで指定して引っ張りだす*

```
let index1 = str.index(str.startIndex, offsetBy: 5)
str.substring(to: index)  // Hello

let index2 = str.index(str.endIndex, offsetBy: -12)
print(str.substring(to: index3))  // playground
```
### substring(from: )
*指定した分以外を取って来る*
*オフセット後の文字全部取って来る。*

```
let index3 = str.index(str.startIndex, offsetBy: 7)
str.substring(from: index)  // playground
```


### substring(with: )
*後ろと前をそれぞれ指定する, つまりレンジを指定する*

```
let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let range = start..<end
print(str.substring(with: range))  // play
```

## 2. range()

```
var str = "Hello, playground"
```

Stringの中に特定のStringが存在するか確認する!

```
if str.range(of:"Hello") != nil{
    print("exists!")　//Exists
}
```
大文字と小文字を無視して、範囲指定をする!

```
if str.lowercased().range(of:"hello") != nil {
    print("exists, again!")
}
```

## 3. replacingOccurrences(of: (これを) , with: (これに交換), options: , range: )

```
　let aString = "This is my string"
```
Stringの中を探して別なStringと交換する!

```
　let newString = aString.replacingOccurrences(of: " ", with: "+", options: .literal, range: nil)
  print(newString) //This+is+my+string
```

## 4. components(seperatedBy: )

### スペースで切断
セパレーター(ナイフ的な？)でぶった切ったStringをArrayにする。

```
　let aString = "This is my string"
```

```
 let toArray = aString.components(separatedBy: " ")
 print(toArray) // ["This", "is", "my", "string"]
```

### CharacterSetで切断
自分で、もしくは用意された文字の配列でStringをArrayに分けることができる。

```
let word = "flower"
let wordTwo = "flour"
```
```
 let separators = CharacterSet(charactersIn: wordTwo)
 let match = word.components(separatedBy: separators)
// 結果：　["", "", "", "we", ""]

//"flower"の中に、"flour"の[f, l, o, r]が含まれていたので、それ以外をプリント             
```



## 5. Array(string.characters)
↑上記と同じく、StringをArrayにするものだけど、Character(文字)ごとにArrayにする方法

```
let string = "Hello 🐶🐮 🇩🇪"
```

```
 let characters = Array(string.characters)
 print(characters) // ["H", "e", "l", "l", "o", " ", "🐶", "🐮", " ", "🇩🇪"]
```

## 6. [String].join()

String Arrayをつなぎ合わせてくれる！ ※join()はstringしか使えないので、charの配列はつなげられない

```
let str = ["This", "is", "my", "string"]
let backToString = toArray.joined(separator: "+") // This+is+my+string
```
## 7. String()で文字配列を繋げる

char arrayをつなげたい場合は、単純にString()にキャストしてしまえばOK.
```
let characters = ["H", "e", "l", "l", "o"]
print(String(characters)) // Hello
```

### ひとまずここまで！どんどん足していく予定です。
開発フロー

開発フロー
#基本設計
・新製品の開発申請
↓
・設計審査
↓
・調査実験
↓
・設計審査
↓
#管理
試作
↓
新製品試作結果報告書
↓
顧客の使用評価（座談会とか？）
↓
新商品申請書
↓
設計審査
↓
仕様書
↓
品質設計
↓
工程設計
↓
量産（調査・試験）
↓
出荷
↓
使用
↓
クレーム
↓
不適合情報
・解析
・評価
→品質設計

関連
---

**関連サイト**

- [x] [要求定義と要件定義](http://qiita.com/sunstripe/items/61df719fb1f6178b2605)
---

## 投稿情報
投稿日 2017年06月29日
更新日 2020年12月02日
8297 views

## 関連記事

【About】(http://qiita.com/sunstripe) - サンストライプ

---

## 制作チーム：サンストライプ

[![sunstripe_logo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80600/322f2d60-f19d-af9e-2b6f-7290ca546848.png)](http://sunstripe.main.jp/)
http://sunstripe.main.jp/

(月１WEBコンテンツをリリースして便利な世の中を作っていくぞ！！ボランティアプログラマー/デザイナー/イラストレーター/その他クリエイター声優募集中！!)

### 地域情報 THEメディア
THE メディア 地域活性化をテーマに様々なリリース情報も含め、記事をお届けしてます！！
https://the.themedia.jp/

### ゼロからはじめる演劇ワークショップ
多様化の時代に向けて他者理解を鍛える

https://workshop.themedia.jp/

### プログラミングワークショップ・ウェブ塾の開講！！！
様々なテーマでプログラミングに囚われずに取り組んでいきます。
詳しくはこちら　↓　↓　↓　↓　↓　↓　↓　↓
[プログラミングサロン 月１だけのプログラミング学習塾](https://workshop.themedia.jp/posts/7057553?fbclid=IwAR32CfRQ7RvDOhvuogoSwqxDLMOU7Jvuzljlnx-TMc27qBPX1BnWsfLcBR8
)

### 協力応援 / 支援者の集い
## チーム：サンストライプ
#### プログラミングラボ
https://twitter.com/sunstripe2011

一緒にポートフォリオを作りませんか？現場の体験やそれぞれの立場から年齢関係なく作品を作りたい方々と一緒にチームを作って、作品を作っています。現場に行きたい人には、職場紹介や職場の体験や悩み相談なども受けております。
様々な職種からプログラミングの知識を得たい、デザインの知識を得たい、データーベースの知識を得たいという人が集まっております。
週１のミーティングにそれぞれの近況と作業報告して、たまにリモート飲み会などをしております！！

興味がある方は、DMに話しかけてみてください。

## トラストヒューマン
http://trusthuman.co.jp/
私たちは何よりも信頼､人と考えてます｡

｢コンサルティング｣と｢クリエイティブ｣の両角度から｢人材戦略パートナー｣としてトータル的にサポートします！！

キャリア教育事業
広域学習支援プラットフォーム『のびのび日和』
https://slc-lab.amebaownd.com/

#スポンサー募集
なぜ7セグは斜体なのか

7セグのUIを作ろうと思ったら気になったので調べてみる。

# wikiを見た。
> *全てではないが、ほとんどのものが斜体（イタリック）となるように配置されており、読みやすくなっている。*
- [7セグメントディスプレイ](https://ja.wikipedia.org/wiki/7%E3%82%BB%E3%82%B0%E3%83%A1%E3%83%B3%E3%83%88%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4)

一瞬で帰結した。
斜体にして読みやすくしているのかー。

...。

# **…斜体って、読みやすいの？**

そもそも斜体、イタリック体、オブリーク体とは？？？
> *イタリック＝手書き文字をもとに設計されたスタイルであり、結果的に右側に傾いている。ただ斜めになっている文字のことはイタリックとは言わない。
オブリーク＝文字を無理やり斜めにしているもの。つまり斜体。日本語で斜めになっているものはイタリックではなく、どちらかというとオブリーク。*
- [非デザイナーがイタリックとオブリークの違いについて調べた](https://cottala-becco.com/italic_and_oblique/)

傾いているのは手書きから来ているのかー。
文字の装飾としてイタリック体があってそれを簡易的に表現したのがオブリーク体、といった感じかな。

次に「斜体　読みやすい」でググってみた。けど、
やっぱり**「斜体＝読みやすい」**ではないよなー。
当たり前だけど読みやすさなんてフォントによっても場面によっても違うし。

# **じゃあ、何故7セグは斜体なのか**

ちゃんとググったらずばりなページがあった。
> *数字に斜体が掛かっている理由は目の錯覚を補正する為でした。*
- [デジタル表示　〜７セグ編〜 - 株式会社アヴァント｜AVANT DESIGN CO.,LTD.](http://www.avant-dc.co.jp/blog/watch_episode/2594)

ほーーー本来は**傾いているように見えるのを補性するための傾き(!?)**だったのか！

それで文字としては傾いてる書体(イタリック体)も存在しているから、
補正としての傾きから装飾としての傾きになっていった、ってとこかな。

スッキリ。


# 余談
7つのセグメントすべて両端がくさび？になってる六角形で構成されてると思ってたけど、よーく見てみると違った。
![IMG_3547.JPG](https://qiita-image-store.s3.amazonaws.com/0/21376/2e91c56e-6900-67ba-b76e-09cf38adae31.jpeg)
使っているチープカシオ。
傾き具合はほどほど。すべて直線で構成されているわけではなくて、カーブもある。底辺の左端が微妙に上向きにカーブしているのがわかりやすい。

[蛍光表示管](https://www.google.co.jp/search?q=%E8%9B%8D%E5%85%89%E8%A1%A8%E7%A4%BA%E7%AE%A1&source=lnms&tbm=isch&sa=X&ved=0ahUKEwiupt_TgeLUAhUE7mMKHZwoBTMQ_AUICigB&biw=1549&bih=926#imgrc=TQvAvxus-E9vVM:)でググったらしてみてみると書体のセリフっぽくなってる7セグもある。
おもしろいなー。
iTunesConnectのレーティングの設定と年齢設定の結果の関係

### AppStoreの年齢レーティングについて

* AppStoreの年齢レーティングは、ユーザーに対して、4+,9+,12+,17+で表示されます。
* どの項目がどの年齢レーティングに対応しているかわからなかったので表にまとめました。
* アプリ内に表示される広告もふくめて、年齢レーテイングの設定はDeveloperの責任です。しっかり正しく答えて申請するようにしましょう。

### 補足
* 「無制限のWebアクセス」は UIWebView, WKWebView, SFSafariViewController などを使っていて、インターネット上のWebページを表示できて、リンクも適当に辿れるようだと「はい」にチェックをつける必要があります。その場合年齢レーティング17+になります。
* x はAppStoreで販売できない設定です。
* レーテイング結果は国によって若干ことなる場合があるのですが、日本では基本的に下記のようになります。

|項目    |	なし	　 |軽度	               |  頻繁 |
|:--:|:-----------------:|:------------------:|:------------------:|
|アニメまたはファンタジーバイオレンス|	4+|	9+|	12+|
|リアルな暴力的表現|4+|	12+|	17+ |
|長時間の過激なまたは加虐的でリアルな暴力|	4+|	x|	x|
|冒とく的または下品なユーモア|	4+|	9+|	12+|
|成人向けまたは成人向けを暗示するテーマ|	4+|	9+|	17+|
|ホラー／恐怖に関するテーマ|	4+|	9+|	12+|
|医療／治療情報|	4+	|12+	|17+
|アルコール、タバコ、ドラッグの使用または言及|	4+|	12+|	17+|
|疑似ギャンブル	|4+	|12+|	12+|
|性的内容およびヌード|4+	|12+	|17+|
|過激な性的表現およびヌード	|4+	|x|	x|

|項目	|いいえ	|はい	
|:--:|:--:|:--:|
|無制限のWebアクセス	|4+|	17+|
|ギャンブルおよびコンテスト	|4+|	17+|
【翻訳】scikit-learn 0.18 User Guide 4.4. 教師なし次元削減

http://scikit-learn.org/0.18/modules/unsupervised_reduction.html を google翻訳した
[scikit-learn 0.18 ユーザーガイド 4. データセット変換](http://qiita.com/nazoking@github/items/267f2371757516f8c168#4-%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BB%E3%83%83%E3%83%88%E5%A4%89%E6%8F%9B) より

----
# 4.4. 教師なし次元削減

特徴量の次元数が多い場合は、教師ありステップの前に教師なしステップでそれを減らすと便利です。 [教師なし学習方法](http://qiita.com/nazoking@github/items/267f2371757516f8c168#2-%E6%95%99%E5%B8%AB%E3%81%AA%E3%81%97%E5%AD%A6%E7%BF%92) の多くは、次元を減らすために使用できる `transform` メソッドを実装しています。以下では、頻繁に使用されるこのパターンの2つの具体的な例について説明します。

 * パイプライン処理
   * 管理されていないデータの削減と管理された見積もりは、1つのステップで連鎖させることができます。 [パイプライン：連鎖見積り](http://qiita.com/nazoking@github/items/fdfd207b3127d6d026e0) を参照してください。

## 4.4.1. PCA：主成分分析

[decomposition.PCA](http://scikit-learn.org/0.18/modules/generated/sklearn.decomposition.PCA.html#sklearn.decomposition.PCA) は、元の特徴量の分散をよく捕捉する特徴量の組み合わせを探します。 [コンポーネントの信号の分解（行列分解問題）](http://scikit-learn.org/0.18/modules/decomposition.html#decompositions) を参照してください。

  * 例
    * [固有顔とSVMを使用した認識の例](http://scikit-learn.org/0.18/auto_examples/applications/face_recognition.html#sphx-glr-auto-examples-applications-face-recognition-py)

## 4.4.2. ランダム投影

モジュール：random_projection は、ランダム投影によるデータ削減のためのいくつかのツールを提供します。ドキュメントの関連セクション： [ランダム投影](http://qiita.com/nazoking@github/items/16f65bbcfda517a74df2) を参照してください。

  * 例
    * [Johnson-Lindenstraussはランダム射影の埋め込みにバインドされています](http://scikit-learn.org/0.18/auto_examples/plot_johnson_lindenstrauss_bound.html#sphx-glr-auto-examples-plot-johnson-lindenstrauss-bound-py)

## 4.4.3. 特徴集積

[cluster.FeatureAgglomeration](http://scikit-learn.org/0.18/modules/generated/sklearn.cluster.FeatureAgglomeration.html#sklearn.cluster.FeatureAgglomeration) は、 [階層的クラスタリング](http://scikit-learn.org/0.18/modules/clustering.html#hierarchical-clustering) を適用して、同様に動作する特徴量をグループ化します。

  * 例
    * [特徴集積対一変量選択](http://scikit-learn.org/0.18/auto_examples/cluster/plot_feature_agglomeration_vs_univariate_selection.html#sphx-glr-auto-examples-cluster-plot-feature-agglomeration-vs-univariate-selection-py)
    * [特徴集積](http://scikit-learn.org/0.18/auto_examples/cluster/plot_digits_agglomeration.html#sphx-glr-auto-examples-cluster-plot-digits-agglomeration-py)

**特徴量スケーリング**

特徴量のスケーリングまたは統計プロパティが非常に異なる場合、 [cluster.FeatureAgglomeration](http://scikit-learn.org/0.18/modules/generated/sklearn.cluster.FeatureAgglomeration.html#sklearn.cluster.FeatureAgglomeration) は関連特徴量間のリンクを取得できない場合があることに注意してください。これらの環境では、 [preprocessing.StandardScaler](http://scikit-learn.org/0.18/modules/generated/sklearn.preprocessing.StandardScaler.html#sklearn.preprocessing.StandardScaler) を使用することができます。

----

[scikit-learn 0.18 ユーザーガイド 4. データセット変換](http://qiita.com/nazoking@github/items/267f2371757516f8c168#4-%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BB%E3%83%83%E3%83%88%E5%A4%89%E6%8F%9B) より
©2010 - 2016、scikit-learn developers（BSDライセンス）。
【MySQL】あのカラムを持つテーブルってどれだっけ？

あのカラムを持ってるテーブルってどれだっけ？ってなった時に
（設計ドキュメント探すのがめんどうな時とか...）
一発でテーブルを検索してくれるSELECT句。

```mysql:特定のカラムを持つテーブルを検索する
select table_name, column_name from information_schema.columns where column_name ='検索するカラム名';
```


- ``table_name`` = テーブル名
- ``column_name`` = カラム名
- ``information_schema.columns`` = データベース内にある全てのカラム

※``information_schema``は、MySQLが保持するほかのすべてのデータベースに関する情報を格納する場所。
実行できる操作はテーブル内容の読み取りだけで、テーブルに対する INSERT、UPDATE、DELETE 操作は実行できません。
ニューラルネットワークの構成要素と実際に組んでいく上での注意点のまとめ

この記事は、自身のブログ、[Data Science Struggle](http://marubon-ds.blogspot.jp)を翻訳したものになる。  

#概略
色々な試みの中でニューラルネットワークを組むことが増えてきたので、組んでいく上での勘所をまとめておく。
ニューラルネットワークは自由度が高く、調整可能箇所の多いアルゴリズムなので、より良いモデルを作成するための調整には気にする手順がある。 
それも含めてまとめておく。 

#ニューラルネットワークの構成要素
構成要素を、***必須要素***と***オプション要素***に分けて整理する。今回整理しておく構成要素は、実際にニューラルネットワークを組むときに意識しなければいけないものに限る。 
ニューラルネットワークそのものの全体像については[別記事](http://qiita.com/shu_marubo/items/0f6c8625d42da528e190)に緩くまとめたのでそちらを参照で。 

##必須要素

* レイヤー
* ノード
* 活性化関数

###レイヤー、ノード

![20170629_1.png](https://qiita-image-store.s3.amazonaws.com/0/122985/b497c096-8fbf-5e6e-4c00-3eb6453fa62f.png)


上記図のL_1、L_2、L_3がそれぞれレイヤーになる。レイヤーを構成している円がノードになる。 
ニューラルネットワークを作成する際に、その全体の規模はレイヤーとレイヤーあたりのノードの数で決めることがでいる。 
この図ではL_1、L_2、L_3はそれぞれ入力層、隠れ層、出力層となる。基本的に、入力層はデータの形、出力層は出力の形、つまりモデルの目的に左右されることになるため、モデル作成者が調整することになるのはこの隠れ層の部分になる。 
レイヤーの数、レイヤーあたりのノード数を増やすことでモデルはよりデータに対する追跡能力を上げることになるが、更新する重みの数が増えるため学習には時間がかかるようになる。 
モデルの精度のスケールの最も大きい部分を担うので、モデルを作成するときにはここを大雑把に決めることからスタートする。 

###活性化関数

![20170629_2.png](https://qiita-image-store.s3.amazonaws.com/0/122985/1bf91dc7-e149-fe4a-2590-7faff1d6e48e.png)

活性化関数はノードが受け付けたインプット（データもしくは前のレイヤーの出力）と重みの線形結合された値に対して使用する関数だ。 
この関数は上記の図からわかるようにノードごとに設けられる。実際にニューラルネットワークを作成するときにはレイヤー単位で設定することになる。 
出力層と隠れ層では基本的に使用する活性化関数が異なる。出力層の活性化関数はモデルに求められる出力の形に左右される。 
隠れ層の活性化関数はいくつも種類があり、その選択によってモデルの精度も異なる。  
一部を挙げてみる。 

* Linear
* ReLU
* sigmoid
* Leaky ReLU
* Parametric ReLU
* maxout

##オプション要素
オプション要素は基本的には過学習の防止のために設けられる。ニューラルネットワークはレイヤーとノードの数を増やすことで非常に高いデータへの追跡能力を持つことになるため、汎化作用は大切だ。 

* ドロップアウト
* 正則化

###ドロップアウト
データを読み込んでモデルの訓練を行うときに、一定割合の数のノードを不活性化させて学習をしていく。一定割合のノードを不活性化させてパラメーターを更新させていくことで過学習を防ぐ。 
どのレイヤーにドロップアウトを設置し、どれだけの割合のノードを不活性化させるかを選択する。 
ドロップアウトさせるレイヤーの割合が高すぎると、学習がうまく進まないことがあるため、全てのレイヤーに高めの割合で仕込めば良いというものではない。 

###正則化
損失関数に対して正則化項を加えることでパラメーターの値が大きくなりすぎてしまうことを防ぐ。これもいくつか種類がある。 

* L1正則化
* L2正則化

どの正則化の手法を選択し、その係数（ハイパーパラメーター）の値をどうするかなどの選択をする。 
正則化を強めすぎるとこれもまた学習が進まなくなるため、一概に全てのレイヤーのノードに強めの正則化を仕込めば良いというものでもない。 

##実際に組んでいく時の手順
ニューラルネットワークを組むときに気にしなければいけないのは以下の二点。 

* データを追いかけるのに十分な規模を持つこと
* 過学習が起きてないこと

まず、ニューラルネットワークがデータに対応し、目的を達するのに十分な精度を持っている必要がある。さらに、訓練データに対するaccuracyが十分であっても、未知のデータに対する精度が低ければモデルは用を果たさない。汎化能力を十分に持たせる必要がある。 

上記の二つを満たすためにはだいたい以下の順で進める。（思いっきり主観） 

1. なるべく少なめのレイヤー数、ノード数のモデルを作成する
2. レイヤー数やノード数を増やしていき、lossを下げ、accuracyを上げていく
3. lossを下げていった段階で過学習が起きたようなら、ドロップアウトや正則化を設置して過学習を解消する

要するに、必須要素の部分でスケールを掴みつつ、オプション要素で生じた問題を調整していくということになる。

##kerasでの例
例えばkerasでは以下のように、レイヤー、レイヤーあたりのノード数、活性化関数、ドロップアウトを設置できる。 

```python
model.add(Dense(8, input_dim=4, W_regularizer = l1_l2(.01)))
model.add(Activation('relu'))
model.add(Dropout(0.2))
```
【MySQL】ORDER BYで条件を指定、任意の順番に並び替える！

##ORDER BYで条件を指定する方法

###背景
とある処理でマスター情報がない場合、
ユニークキーのカラム「``id``」には10桁の整数（マスターのidとかぶらない数値）を登録していた。
一覧の表示順が「``id``」の降順だったため、
マスター情報がないデータを一覧の最後に表示したいが、最初に表示されてしまう...
そんなとき、以下のコードで解決したのでメモ。

```mysql:メモ
select * from テーブル名 order by id < 1000000000 desc, id >= 1000000000 desc, id desc;
```

###単純な昇順降順

```mysql:単純な昇順降順
SELECT * FROM テーブル名 ORDER BY id;
SELECT * FROM テーブル名 ORDER BY id desc;
```
idの昇順(asc)、降順(desc)に並び替わる。
デフォルトは昇順(asc)です。
明示的に示す場合は、ascをフィールド名の後ろに付け足します。
最終行を``ORDER BY id asc;``にしても結果は同じ。

###条件を指定

```mysql:条件を指定
SELECT * FROM テーブル名 ORDER BY id = 1234 DESC;
```
``id``が``1234``のものが一番最初になる。

```mysql:条件を指定
SELECT * FROM テーブル名 ORDER BY id <= 5 DESC;
```
``id``が``5``以下のものが一番上に並ぶ。


###まとめ
ORDER BY句には、条件（関数や評価式）が指定できる！以上！
[小技] dotfilesの変更差分を自動でコミットする

複数のマシン上で同じシェル環境を整えるためにGitでdotfilesを管理している方は多いと思いますが、変更するたびにコミット&プッシュを手動で行うのは面倒だと思ったので改善したメモ。
# スクリプトの準備
```zsh:auto-commit.zsh
#!/usr/bin/env zsh

git add -A .
local timestamp="$(date '+%Y/%m/%d %H:%M:%S')"
git commit -m "Automatically updated on ${timestamp}" && git push origin master
```
```zsh
chmod +x auto-commit.zsh
```
几帳面な人はコミット前にスモークテストを挟んでもいいかもしれない。
# 定期アップデートの設定
cronを使って定期アップデートを設定する。

```zsh
crontab -e
```
下記は毎日15時にdotfilesの変更差分があればリモートに反映する例である。

```
0 15 * * * cd ~/dotfiles && ./auto-commit.zsh
```
Phoenixで新たにPageを追加した時のエラー


初心者として、ちょっとハマったので覚え書き。
Phoenixで新たにPageを追加した時のエラー

## 環境
Mac : 10.12.2
Elixir: 1.4.4
Phoenix: 1.2.4



```
function PhoenixSample.PageView.render/2 is undefined (module PhoenixSample.PageView is not available)
```


サーバを再起動しても解決しない。
結論から言うと、クリーンして再起動したら直った。

```
$ mix clean
$ mix phoenix.server
```


以上。
Unityで最新のLive2Dを使ってみる（Cubism SDK 3.0)

1.新しいUnityプロジェクトを作る（Unity5.6以上）
2.ダウンロードしてきたCubism SDK 3.0をUnityにインポートする
3.ダウンロードしてきたサンプルモデルをエディターで開く
4.moc3ファイルを書き出す
![スクリーンショット 2017-06-29 11.53.27.png](https://qiita-image-store.s3.amazonaws.com/0/59336/845fd5af-be28-e049-7fed-fccc343729e4.png)

![スクリーンショット 2017-06-29 11.51.53.png](https://qiita-image-store.s3.amazonaws.com/0/59336/62a7febd-2610-cd03-f64d-1a04053c1629.png)

![スクリーンショット 2017-06-29 11.50.41.png](https://qiita-image-store.s3.amazonaws.com/0/59336/d2067cc4-8229-0abd-97e3-0cc4511cd726.png)

5.モーションファイルを書き出す
![スクリーンショット 2017-06-29 11.53.44.png](https://qiita-image-store.s3.amazonaws.com/0/59336/6399ab54-13cd-1e27-0396-49a751b260fd.png)

![スクリーンショット 2017-06-29 11.51.59.png](https://qiita-image-store.s3.amazonaws.com/0/59336/19ba85be-ae83-5d68-a686-4b097e19e367.png)

![スクリーンショット 2017-06-29 11.51.16.png](https://qiita-image-store.s3.amazonaws.com/0/59336/364ead56-80b7-d66f-1cf5-ef7e33db19e2.png)

ここからが重要
6.書き出したファイルをUnityにインポートする
moc3、テクスチャフォルダ、model3.json、motion3.jsonの順番でインポートする
（UnityのEditor拡張であるところのAssetImpoterという機能によりインポートしたときに処理が行われるため）
するとプレハブとアセットが生成される
ここでエラーが起きると生成されないためインポートする順番を変えたりして何度か試す

![スクリーンショット 2017-06-29 12.20.19.png](https://qiita-image-store.s3.amazonaws.com/0/59336/0e247e49-ec67-2ce6-09a1-f811165d0b0e.png)

７．生成されたプレハブをシーンに置く

8.以上

![スクリーンショット 2017-06-29 12.07.19.png](https://qiita-image-store.s3.amazonaws.com/0/59336/e61a8422-4bcb-5834-3644-1fcd663cf7b5.png)

9.あとはAnimatorをプレハブにアタッチして先ほど生成されたanimデータを入れればアニメーションします
詳しくはサンプルを見てね
AnacondaでOpenCV3をインストールする

#OpenCV3はPython3.6には対応していない？

ということで、これで躓いてた。
結論として、Anacondaで3.5環境を作りインストールする。

毎度怒られるからやけになった。

```shell-session
$ conda create -yn newproject python=3.5.2
$ source activate newproject
```

仮想環境がアクティブになったら、以下のコマンドでインストール。

```shell-session
$ conda install -c https://conda.anaconda.org/menpo opencv3
$ conda list
```

```
# packages in environment at /anaconda/envs/opencvtest:
#
hdf5                      1.8.17                        1  
mkl                       2017.0.3                      0  
numpy                     1.13.0                   py35_0  
opencv3                   3.1.0                    py35_0    menpo
openssl                   1.0.2l                        0  
pip                       9.0.1                    py35_1  
python                    3.5.2                         0  
readline                  6.2                           2  
setuptools                27.2.0                   py35_0  
sqlite                    3.13.0                        0  
tbb                       4.3_20141023                  0    menpo
tk                        8.5.18                        0  
wheel                     0.29.0                   py35_0  
xz                        5.2.2                         1  
zlib                      1.2.8                         3  
```

やったぜ！
コマンドプロンプトでECHONET LiteパケットをWirsharkで確認（メモ）

#概要
コマンドプロンプトからWiresharkを用いてECHONET Liteのパケットを確認する。

#実行コマンド
## tshark
同一LAM内のパケットの流れを確認したい場合は以下を実行
※　tshark.exeが存在するディレクトリーで実行する

```
> tshark
```

##ECHONET Liteパケットのみを表示
同一LAN内でやりとりされるECHONET Liteパケットのみを表示する。
ECHONET LiteはUDPのポート3610で通信するので引数でフィルターの条件を与える

```
> tshark -f "port 3610"
```

###表示個数を指定する
以下は3つの通信を表示

```
tshark  -f "port 3610" -c 3
```