OmniAICreator/Qiita-1.07M huggingface dataset:
Jenkinsfileメモ

Jenkinsジョブを管理するのが辛くなって今更ながらJenkisfile(Jenkins Pipeline)に手を出してみた。

# Jenkinsfileとは
* JenkinsのPipelineという仕組みを使ってジョブをコード化するためのファイル
* groovyで記載する。
* `Declarative Pipeline`と`Scripted Pipeline`という２つの種類がある
    * `Declarative Pipeline`はジョブ設定(カスタムワークスペースの場所とか)＋ジョブの内容が書ける
    * `Scripted Pipeline`はスクリプトチックに書ける

`Declarative Pipeline`の中で`Scripted Pipeline`の書き方もできるので、基本的には`Declarative Pipeline`で書いたほうが良い。

# Jenkinsfileサンプル
```groovy
#!groovy
pipeline {
    // 実行ノードの設定。ここでdockerとか指定できる。
    agent any
    // ジョブ設定。実行タイミングとかも設定できる。
    options {
        retry(3)
    }
    // ジョブの内容
    stages {
        stage('checkout') {
            steps {
                checkout scm
            }
        }
        stage('build') {
            steps {
                // ビルド処理
                echo 'hello'
            }
        }
    }
    // 終了処理
    post {
       // 必ず実行
       always {
           deleteDir()
       }
       // ジョブ成功時のみ
       success {
           slackSend color: "good", message: "${env.JOB_NAME} - #${env.BUILD_NUMBER} ${currentBuild.durationString} (<${env.BUILD_URL}|Open>)"
       }
       // ジョブ失敗時のみ
       failure {
           slackSend color: "danger", message: "${env.JOB_NAME} - #${env.BUILD_NUMBER} ${currentBuild.durationString} (<${env.BUILD_URL}|Open>)"
       }
       // 前回のジョブと結果が違う場合(成功 -> 失敗)とかの処理も設定できる
   }
}
// ここに関数とか定義して使うもよし
```

# Jenkinsfileの管理
個人的には以下のような管理をしている

|管理方法|対象|
|:--|:--|
|ソースのリポジトリ内で一緒に管理|リソースがリポジトリ内で完結しているジョブ|
|ジョブ専用のリポジトリを作って管理|複数の成果物を使用するジョブ|


# 入れた方が良いプラグイン

|プラグイン|概要|
|:--|:--|
|Blue Ocean|見た目をかっこよくしてくれるやつ。これ入れたら必要なのほとんど入る|
|File Operations|ファイル操作系の便利関数を提供してる|



# 使ってみた感想
* Jenkinsサーバーのお引越しやソースコード管理システムのお引越しが発生したときにめちゃ楽。
* プラグインの恩恵がでかい。`BitBucket Team/Project`ジョブを作るだけでプロジェクト配下全部のリポジトリのジョブ勝手に作ってくれるので、手動で作るジョブの数が激減。(`GitHub Organization`ジョブも多分おんなじ感じだと思う。)
* Jenkinsfileデバッグ用ジョブ作らないと無駄コミットが発生しまくる
* ビルド環境もdocker使ってコード化したほうが良い（ジョブよりもビルド環境のほうが暗黙知が多い）


# 参考
* [Jenkinsfileの書き方](https://qiita.com/lufia/items/18cdb01f86a6d5040c60)
* [【Jenkins】Declarative Pipeline入門](https://qiita.com/toricor_/items/babc28db2738ed6cbac2)
* [Jenkins Pipeline の１１個のベスト・プラクティス](https://qiita.com/AHA_oretama/items/16d61d0af566ee7bf77c)
* [JenkinsFile個人的チートシート](https://qiita.com/yyYank/items/e591750c67f3a0bef221)
JSONへのシリアライズ方法の備忘録

DataContractSelializerクラスを利用します。


まずDataContractAttributeを付与した
クラスを定義します。

```csharp:Person.cs
[DataContract]  
internal class Person  
{  
    [DataMember]  
    internal string Name;  

    [DataMember]  
    internal int Id;  
}
```
JSONをstreamへとシリアライズします。

```csharp:Selialize.cs
var p = new Person()
{
    Name = "John",
    Id   = 10
}; 

var stream1 = new MemoryStream();  
var ser = new DataContractJsonSerializer(typeof(Person));

ser.WriteObject(stream1, p);
```

参考
---
[Microsoft Docs | 方法 : JSON データをシリアル化および逆シリアル化する](https://docs.microsoft.com/ja-jp/dotnet/framework/wcf/feature-details/how-to-serialize-and-deserialize-json-data)
CloudFront を利用し HTTP/HTTPS をサーバレスでリダイレクトする

CloudFront を利用し HTTP/HTTPS をサーバレスでリダイレクトする


## 何をしたいか

サイトを移転するときなど、既存の URL へのアクセスを新しい URL へリダイレクトしたいときがある。
S3 でのリダイレクトがお手軽だが、HTTPS のリダイレクトができないのが弱点である。
かといって、SSL 接続を終端させるためだけに ELB + EC2 の構成を用意するのも手間。

そこでこの、

* HTTP だけでなく、HTTPS でのリダイレクトも行いたい
* サーバレスで行いたい

という要求を満たすために、CloudFront + S3 の構成でリダイレクトを行う。

## 前提

* リダイレクト元に HTTP および HTTPS どちらのアクセスが来ても良いようにする
* **パスはカットしてリダイレクトしたい**
    * example.com/ の下にどのようなパスがきても、リダイレクト先のトップページに飛ばす

# 手順

## S3 バケットの作成、設定

### バケットの作成

リダイレクト設定を行うバケットを作成する。
直接表には出ないバケットであるため、名前は何でも良い。

### Static website hosting の設定

プロパティ => Static website hosting を開き、以下の設定をする。
ここで設定したリダイレクトのレスポンスが CloudFront を通じて返される。
今回は、www.google.com にリダイレクトしている。

* インデックスドキュメント
	* index.html
		* 指定がないとエラーになるため。ファイルは無くて良い
* エラードキュメント
	* （空白）
* リダイレクトルール
    * \<ReplaceKeyWith/\> によって、どのようなパスでもカットされてリダイレクトされる

   ```
<RoutingRules>
    <RoutingRule>
        <Redirect>
           <HostName>www.google.com</HostName>
           <ReplaceKeyWith/>
        </Redirect>
    </RoutingRule>
</RoutingRules> 
```

※ 「リクエストをリダイレクトする」を利用しても良いが、その場合はパスがカットされない

## ACM 証明書の発行

リダイレクト元の FQDN の SSL 証明書を発行する。
ドキュメント（[証明書のリクエスト](https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/gs-acm-request.html)）に沿って発行すれば問題ないが、リージョンは「**バージニア北部**」を選択して発行する。
（「東京」などで発行すると、CloudFront の証明書選択画面に証明書が現れない）

## CloudFront の設定

CloudFront のディストリビューションを作成する。
基本的にデフォルトで良いが、以下の設定を行う。

* Origin Domain Name
	* 上で作成した S3 のエンドポイント（http:// で始まるアドレス）を指定する（**プルダウンで出てくるバケット名ではない**）
		* CloudFront => S3 に http アクセスし、返ってきたリダイレクトレスポンスをクライアントに返すため
		* エンドポイントは Static website hosting の設定画面で確認できる
* Viewer Protocol Policy
	* Redirect HTTP to HTTPS
		* HTTP できたリクエストも、HTTPS に直した上でリダイレクトする
		* HTTP は HTTP のままリダイレクトしたい場合は、HTTP and HTTPS にする
* Alternate Domain Names(CNAMEs)
	* リダイレクト元のドメイン名を入れる
* SSL Certificate
	* Custom SSL Certificate
		* 「**バージニア北部**」で発行していない場合はプルダウンで選択できないので注意

Create Distribution を押したら、Deploy されるまで待つ。
Deploy されたら、DNS レコードを書き替える前に、"Domein Name" 欄にある CloudFront のエンドポイントを利用し、テストすると良い。

* 参考: リダイレクト元が example.com の場合

   ```
curl --head -v -H "Host: example.com" https://d2********.cloudfront.net
# 301 が返ってくれば OK
```

## DNS レコードの書換え

Route53 を利用している場合は、リダイレクト元のドメイン名の Alias レコードに、作成した CloudFront のディストリビューションを指定する。
それ以外の DNS サービスを利用している場合は、CNAME レコードに CloudFront ディストリビューションのエンドポイントを指定する。
2018年8月第5週　今週気になった記事まとめ

# 今週気になった記事まとめ
##■下手くそダンス映像をキレッキレに補正してくれるAIが登場
https://www.gizmodo.jp/amp/2018/08/everybody-dance-now-ai.html
ターゲット映像側であらかじめダンスめいた動きをさせてAIに登録するとAIの描写が楽になる仕組みがよく分からない。
ソース映像からポージングのボーンを取ってきてターゲット映像に反映する仕組みだと思うのだけど、ターゲット映像側で動きがあった方が良い理由が理解できないな。

##■「Amazon Alexa」と「Cortana」の連携機能を試して分かったこと
http://www.itmedia.co.jp/pcuser/articles/1808/27/news101.html
連携することで掛け算的なものを狙っているのかと思ったら、それぞれの不足分を補う足して１的な狙いらしい。
それぞれの足りないところを補うために音声アシスタント同士が連携する必要はあるのだろうか・・・？
結局音声アシスタントの先にある何かが目的なのだから、わざわざ音声アシスタントを挟んで連携を図る必要がよく分からないな。

##■正体不明の楽器「Venova」は、どのようにして生まれたのか
http://www.itmedia.co.jp/business/articles/1808/27/news025.html
YAMAHA自身がカジュアル管楽器をコンセプトに販売したことが凄く大きいことな気がする。
こういう自社ブランドとイメージなどの部分でミスマッチなものを作るときって別会社を立ち上げたり、ベンチャーに技術提供してとかってイメージだったので。

##■「8割がソシャゲの相談」　ゲームAI注目されるワケ、「がんばれ森川君2号」開発者が語る
http://www.itmedia.co.jp/news/articles/1808/27/news060.html
共通のフレームワークが～って話が最後の方に出てきたけど、なんというかゲーム会社が技術を追うことって凄い無駄やなぁと。

##■なんかかわいい。目と眉毛で感情を表現するロボット｢SEER｣
https://www.gizmodo.jp/amp/2018/08/seer-emotional-expression-robot.html
素材感だけで言えば全然無機物でそっけないもののはずなのに、ここまで表情が出てくるってホント不思議。
アニメーションのように表情が出てる。

##■“無料タクシー”の次は……機密文書処理0円　衝撃の「新ビジネス」続々
http://www.itmedia.co.jp/news/articles/1808/29/news049.html
個人的にあんまり広告というものの効果性を分かっていないので、何故広告が絡んだものにいつも価値が高く付くのかが不思議ではある。
もちろん多数の目に触れる機会を増やすことのメリットはなんとなくイメージできるのだが、実際の購買に繋がるイメージがあまり湧かないので・・・。
統計的に広告見た何割が購買に～とかあるのだろうか・・・。

##■「Windows」タスクスケジューラに脆弱性--現時点で解消策なし
https://japan.zdnet.com/article/35124784/
内部犯はあれとして、外部から見るとほぼほぼ影響の無い脆弱性だとしても、ゼロデイ脆弱性が出ること自体が大きな問題にはなってしまうのか。
当たり前といえば当たり前だけど、しっくりこないような気もする。
Java未経験者がKotlinを勉強するためにやったこと


# はじめに

普段はPythonばかりを書いている大学生です。
現在は興味半分で申し込んだインターンになぜか受かってしまい、研修としてメッセージングアプリを作っています。


このインターンでは推奨言語がサーバーサイド、クライアントサイド共にKotlinとなっていました。
一切Javaを触ったことのない自分がKotlinで実装できるのか、、、と結構不安でしたが、調べながらやってみると意外と**簡単に**覚えることができました。

ネットの記事は、Javaとの対比を目的としたKotlinの記事が多いように思います。私のようにJavaからの移行でない人にとっては、なかなか取っ付きづらいのも事実です。

そこで今回は、Java未経験者がKotlinを勉強するためにやったことを順番に紹介していきたいと思います。

# 言語の理解
## Kotlinスタートブック -新しいAndroidプログラミング

![Kotlinスタートブック -新しいAndroidプログラミン](https://qiita-image-store.s3.amazonaws.com/0/191796/02b28090-c602-9e50-8f85-6f0c1316b383.jpeg)

https://www.amazon.co.jp/Kotlinスタートブック-新しいAndroidプログラミング-長澤-太郎/dp/4865940391/


### 概要
- 最初にKotlinの文法を覚えるために買った本
- レイアウトが綺麗で、とっつきやすいデザイン

Googleで「Kotlin」と検索してみると分かると思いますが、基本的な文法から体系的にまとまっているサイトはなかなか見つかりません。普段はほとんど書籍で勉強することはないのですが、今回ばかりは買ってみました。

内容は三部構成になっていて、最初の2部がKotlinの文法、最後の第三部がAndroidでの実装について書かれています。分量もだいたいこの比率です。

### 文法
簡単な条件分岐や関数から、クラスや継承といったプログラミングをする上で必要な**基本的文法は網羅**されています。
他のプログラミング言語を少しでもかじったことのある人ならすぐに理解できると思いますし、プログラミング未経験者の方でも(多分)理解できるように書かれているように感じます。

### Android
こちらは**Androidの実装をある程度知っている前提で書かれています。**
私はAndroid実装に関しても完全な初心者だったので、少々理解するのに苦労しました。
しかし今読み返してみると、詰まっていたのはKotlinというより、xmlファイルの記述であったり、アダプターの概念などでした。
Kotlin特有のテクニックを多数使って書かれているので、Javaからの移行を検討しているクライアントエンジニアにとっては、「なるほど。」と思わせてくれる部分も多いかと思います。


## Kotlin Webアプリケーション 新しいサーバサイドプログラミング
![Kotlin Webアプリケーション 新しいサーバサイドプログラミング](https://qiita-image-store.s3.amazonaws.com/0/191796/7d1fceea-2995-19f9-aa90-1a7042793873.jpeg)

https://www.amazon.co.jp/Kotlinスタートブック-新しいAndroidプログラミング-長澤-太郎/dp/4865940391/

### 概要
- 先程と同じ方が書かれたKotlin入門本
- 半分は**サーバーサイドAPIの実装**について書かれている

JavaではWebフレームワークとして有名(らしい)SparkとSpring Bootを使った実装のサンプルが紹介されています。しかしながら、Kotlin特有の文法を使ったテクニック等も書かれており、「確かに便利だ」と思うものもありました。

Androidの実装をしない方はこちらの本の方が良いかもしれません。


# 基礎を学んだ後
大まかな基礎を学んだら、後はわからないところを個別に調べていくことになります。
ここでは、自分が詰まった部分にスポットを当てている記事を紹介したいと思います。

#### [Kotlin スコープ関数 用途まとめ](https://qiita.com/ngsw_taro/items/d29e3080d9fc8a38691e)

- Kotlinでは標準で多くの**スコープ関数**が用意されています。
- よく使うスコープ関数が表にわかりやすくまとまっていて、すんなり理解することができました。
- それぞれのスコープ関数に関する定義や例も載っているので、リファレンスを見る感じでよく見ています。

#### [Kotlin文法 - 関数とラムダ](https://qiita.com/k5n/items/964d765767a65cc3de5b)
- Kotlinで**高階関数**の例が書かれています。
- 自前でコールバックっぽい処理を書きたいときに詰まって調べました。
- 高階関数の定義を初めて見た時、「なにこれ？」と思ったのですが、じっくり読むことで理解できました。

#### [入門Kotlin coroutines](https://qiita.com/k-kagurazaka@github/items/8595ca60a5c8d31bbe37)
- Kotlinで**非同期処理**をやりたいなって思って見つけた記事です。
- 正直最初は読んでも全く理解できませんでしたが、**n回読んだら理解できました。**
- 後述するCoroutinesを使った実用例を先にみて、詳しく調べたいと思ったら見てみると良いと思います。

#### [KotlinのCoroutinesでRetrofitをより便利に！](https://dev.classmethod.jp/smartphone/kotlin-retrofit-coroutines/)
- Retrofit + Coroutinesを使った非同期APIクライアントの実装例です。
- Androidでの非同期処理はRxJavaを使うのが主流みたいですが、これからKotlinへの移行が進めば、Coroutinesを使った実装も増えるんじゃないかという読みで勉強してみました。
- **非同期処理がコールバックを使わず同期的に書けるのにググッっときました。**


### [Reference - Kotlin Programming Launguage](https://kotlinlang.org/docs/reference/)
- Kotlinの公式リファレンスです。
- なんだかんだいって**†最強†**
- 英強の方はこれだけですべて学べると思います（自分には無理)

# まとめ
いかがでしたでしょうか?
KotlinというとJavaから覚えないとダメなのかなと思いがちですが、案外すんなりと覚えることができます。書き方もモダンな言語を感じさせる部分もありますし。

「とりあえず本を買って、わからないところがあればネットで調べる」、これが最短でKotlinを覚える方法かもしれません。

これを気にKotlinを勉強してみてはいかがでしょうか?　　
　　

　　
~~「この処理Pythonならすぐなのになぁ」と時々思ってしまうのは秘密。~~
CentOS7.5に最新バージョンのDockerをインストールする

#はじめに
[公式ドキュメント](https://docs.docker.com/install/linux/docker-ce/centos/)を参考し、CentOSに最新バージョンのDockerをインストールしました。
メモとしてインストール手順を残しておきます。

#環境
- CentOS：7.5.18.04
- Docker：18.06.1-ce
- ネットワーク：プロキシーなし 

#手順
## 古いバージョンのものをアンインストールします
```bash 
sudo yum remove docker  docker-client  docker-client-latest  docker-common  docker-latest  docker-latest-logrotate  docker-logrotate  docker-selinux  docker-engine-selinux  docker-engine
```

## 必要なパッケージをインストールします
```bash
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
```

## リポジトリを追加します
```bash
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
```

## Docker CEをインストールします
```bash
sudo yum install docker-ce -y 
```

## 自動起動を有効化します
```bash
sudo systemctl enable docker
```

## Dockerを起動します
```bash
sudo systemctl start docker
```

## インストールしたDockerをバージョン確認します
```bash
[user@localhost ~]$ docker -v
Docker version 18.06.1-ce, build e68fc7a
```

## hello-worldを実行します
```bash
[user@localhost ~]$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
9db2ca6ccae0: Pull complete
Digest: sha256:4b8ff392a12ed9ea17784bd3c9a8b1fa3299cac44aca35a85c90c5e3c7afacdc
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/
```

##sudoなしでDockerを実行するため、ユーザーをDockerグループに追加します
**セキュリティが弱くなります** 

```bash
sudo usermod -aG docker $USER
```
実行後、再ログインすると、sudoなしでdockerコマンドを実行できるになります。

#参考資料
- https://docs.docker.com/install/linux/docker-ce/centos/ 
- https://docs.docker.com/install/linux/linux-postinstall/
tomcatエラー

#tomcatででたエラーメモ

エラー内容

```
情報: Using a shared selector for servlet write/read [金 8 31 22:33:37 JST 2018]
情報: Initialization processed in 614 ms [金 8 31 22:33:37 JST 2018]
情報: サービス [Catalina] を起動します [金 8 31 22:33:37 JST 2018]
情報: Starting Servlet Engine: Apache Tomcat/8.5.32 [金 8 31 22:33:37 JST 2018]
重大: A child container failed during start [金 8 31 22:33:37 JST 2018]
重大: A child container failed during start [金 8 31 22:33:37 JST 2018]
重大: The required Server component failed to start so Tomcat is unable to start. [金 8 31 22:33:37 JST 2018]
情報: Pausing ProtocolHandler ["http-nio-8080"] [金 8 31 22:33:37 JST 2018]
情報: Pausing ProtocolHandler ["ajp-nio-8009"] [金 8 31 22:33:37 JST 2018]
情報: サービス [Catalina] を停止します [金 8 31 22:33:37 JST 2018]
情報: Destroying ProtocolHandler ["http-nio-8080"] [金 8 31 22:33:37 JST 2018]
情報: Destroying ProtocolHandler ["ajp-nio-8009"] [金 8 31 22:33:37 JST 2018]
```

# 今回はこの方法で解決

特定のディレクトリとは、eclipseの[問題]のウィンドウに書いてあるパスを参照して確認し、以下をターミナルから実行
`cd /Users/ユーザー/.m2/repository/org/`
`rm -rf 特定のディレクトリ`


削除後にpom.xmlを右クリックして、mavenを更新する

無事tomcatが実行される


##　このエラーは大体以下のようなエラーらしい

サーブレットの設定がおかしい(servlet.xml)の`<Context docBase="test" path="/test" reloadable="false" source="org.eclipse.jst.jee.server:test"/></Host>`を存在するパスに変更する
Segueの選択肢の意味合い

## はじめに（メモ）
　Swift初めて1週間程度のペーペーです。今回、navigationControllerからViewControllerへSegueで接続しようとした際にSegueの選択肢の意味合いが気になり調べた結果を自分用のメモがわりに記載するだけです。

## Segueについて
　現在表示されているSegueについて以下のインデントされているものが表示されています。
Manual　Segue
　Show
　Show Detail
　Present Modally
　Present As Popover
　Custom
Relationship Segue
　root view controller
Non - Adaptive Manual Segue
　Push(deprecated)
　Modal(deprecated)


## Manual　Segueについて
　Action Segueは画面遷移を表現するSegueです。これらのSegueは現在のデバイスのSize Classや、コンテナビューコントローラの種類に応じて、異なる挙動をします。
###Show
　UINavigationControllerの画面遷移で画面間に関連性(親画面から子画面へ遷移させるなど、階層的な画面構成)があるときの「次」「戻る」などに使い、現在のビューを押し出すようにビューが横から現れます。
###Show detail
　UISplitViewControllerのケースで、MasterViewとDetailViewの画面遷移を表示し、2分割されているビューの詳細ビューを置き換えます。
###Present modally
　現在のviewの上に覆いかぶさるように新しいviewを表示します。
###Present As Popover
　iPad用の種類で、現在の画面の上にポップアップviewを表示します。
###Custom
　Segueに独自の画面遷移を実装する際に使用します。
　
##Relationship Segue
###root view controller
　NavigationControllerからViewControllerに接続する際に使用する。navigationControllerから接続からPush等を用いれるのは、UINavigationControllerによって管理されたViewControllerのみ利用可能らしい？？？？？

##Non - Adaptive Manual Segue
　複数のSceneに関連があることを示すSegueです。UINavigationBarやUITabBarControllerで用いられます。そのSceneがどういったコンテキスト（ナビゲーションなのか、タブなのか）で画面に表示されるのかを示す意味を持ちます。
　###Push(deprecated)
　deprecatedは非推奨みたいなので割愛します。昔はよく使われていたみたいです？？？？
　###Modal(deprecated)
　deprecatedは非推奨みたいなので割愛します。昔はよく使われていたみたいです？？？？

##最後に
　間違っているかもしれないので訂正のコメントお待ちしております。
ArchlinuxにPowerShellをインストール

### 概要
パイプで文字列しか流せないのはそろそろ時代遅れなのでは？
LinuxにもPowerShellをインストールしようず。

### 普通にインストールする場合


AURからインストール用のスクリプトをダウンロード

```bash
$ git clone https://aur.archlinux.org/powershell-bin.git
```

`powershell-bin`ディレクトリができるので、移動。

```bash
$ cd powershell-bin
```

パッケージをビルドしてインストール

```bash
$ makepkg -si
```

起動してみる

```bash
$ pwsh
```

### Dockerを利用する場合
イメージをダウンロード

```bash
sudo docker pull mcr.microsoft.com/powershell 
```

コンテナを立ち上げる

```bash
sudo docker run -it mcr.microsoft.com/powershell
```
Gitで管理しているファイルのディレクトリを1個深くしたい


調べれば出るけど。
既存のディレクトリ・ファイル群について、さらに上位のディレクトリを作り管理したい。

例えば以下のようなファイル構成。

```
+- README.md
`- manage.py
```

これを、こんなふうにしたい。
1個ディレクトリを作って全部移動させるという感じ。

```
- app
  +- README.md
  `- manage.py
```


過去のコミットを含めて全部移動させる場合のコマンド

```
git filter-branch --tree-filter 'FILES=`ls --almost-all | grep -v "^\\.git$"`; mkdir app; mv $FILES app;' HEAD
```

過去のコミットに興味がなければ、普通に`git mv`でも良いと思います。
matplotlib.basemapのbluemarble()のエラーの対処法。

下記のページを参考に、Twitterのデータを解析し緯度経度をmatplotlib.basemapに描くときに
発生したエラーとその対処法について示します。

Twitterのデータ解析で参考にしたのが以下のページです。

[スタバTwitterデータ位置情報のビジュアライゼーションと分析](https://qiita.com/kenmatsu4/items/114f3cff815aa5037535)

これを参考に衛星画像にTwitterデータより取得した緯度経度をプロットしようとしたところ、
以下のエラーが発生しました。

```
 File "/Users/******/anaconda3/lib/python3.6/site-packages/mpl_toolkits/basemap/__init__.py", line 3982, in bluemarble
    return self.warpimage(image='bluemarble',scale=scale,**kwargs)
 File "/Users/kawakita/anaconda3/lib/python3.6/site-packages/mpl_toolkits/basemap/__init__.py", line 4117, in warpimage
    np.concatenate((self._bm_lons,self._bm_lons+360),1)
numpy.core._internal.AxisError: axis 1 is out of bounds for array of dimension 1
```

どうも、bulemarbleで設定した次元が異なるらしい。
ということで、__init__,pyの4117行目のコードをいかに修正します。

修正前
```
    np.concatenate((self._bm_lons,self._bm_lons+360),1)
```
修正後
```
    np.concatenate((self._bm_lons,self._bm_lons+360))
```

これによってエラーは回避され、衛星画像がベースマップとして使用できるようになりました。
同じエラーで困った方の参考になれば幸いです。
ORB-SLAM2 with Realsense D435

#Realsense D435でVisual SLAMがしたい
Realsense D435は２万円くらいでグローバルシャッターで屋外でも使えるKinectの後継としては有力候補な子。ということは、みんなこいつでVisual SLAMしたいよね。僕もしたいです。というわけで動かすことはできたのでメモ。
#ORB-SLAM2を選んだ理由
もちろん有名なVisual SLAM実装であるのもそうだけど、このYoutubeビデオがあったから行けそうな気がした。
https://www.youtube.com/watch?v=yl6MgnYNDE8
#ORB-SLAM2コンパイル上の注意
このコメントみたいにCMakeListいじらないとだめ。ちなみに僕はLXD上のUbuntu 16.04 kineticでコンパイル。(ROSはTCP/IPでデータ送れるからね。ホストは18.04 melodic)
https://github.com/raulmur/ORB_SLAM2/issues/494#issuecomment-356221762
#yamlファイルの用意
yamlを作るにはrealsenseのノード(``roslaunch realsense2_camera rs_rgbd.launch``)を一回立てて、ファクトリー設定の校正情報を取得する(``rostopic echo /camera/color/camera_info ``)どれがyamlのパラメータのどれに対応してるかはここを見る。
http://docs.ros.org/api/sensor_msgs/html/msg/CameraInfo.html
歪み周りが0.0入ってるんだがこれ校正されてなくないか？
#launch
yamlファイルの位置と名前は自由。あとはgit cloneした位置にも依存。
``rosrun ORB_SLAM2 RGBD  ~/ORB_SLAM2/Vocabulary/ORBvoc.txt ~/ORB_SLAM2/Examples/RGB-D/D435.yaml /camera/rgb/image_raw:=/camera/color/image_raw /camera/depth_registered/image_raw:=/camera/aligned_depth_to_color/image_raw``
やってることはORB SLAM2がSubscribeしているトピックに中身的に合いそうなトピックをリネームして突っ込んでいる。これが対応しそうと考えた理由は見つけた中では唯一公式にD435に対応していたrtabmapのチュートリアル。
http://wiki.ros.org/rtabmap_ros/Tutorials/HandHeldMapping
#おわりに
ちなみにこれだと全然性能は出せていない。なぜかというとまずimage_rawがどうもグレイスケールで読まれているのと、たぶん/camera/depth_registered/image_rawという名前的に、openniが想定されているので、今突っ込んでるやつだと255までしか値が出てない気がするのでuint16じゃない。最悪ココらへんはラッパー挟むべきか。ちなみにYoutubeのもグレイになってる。画像出るとこの下のRGB値を見ると３つ一緒になってるし多分正しいのでは。
2-18/08/31追記:ソースを見ると内部でグレイスケールにしていたのでそれで良いようだ。uint16じゃないのも、ROSのメッセージの仕様でbyte単位で区切っているための模様。つまり、普通に動く。校正はもう少ししてもいいかもしれないが。
カーテンみたいなテクスチャレスな場所だときつかった。気が向いたら情報流出的に問題なさそうなところでテストして動画あげたいところ。
うまいこと動かせるように治ったら、次はStereo DSOやりたいけどこれはなんかROSの対応悪いし行けるかよくわからない。最悪、SDKを直叩きすればいいんだろうが。
Google Apps ScriptのObject、Array及びStringのメンバ一覧

[公式ドキュメント](https://developers.google.com/apps-script/guides/services/#basic_javascript_features)によると Google Apps Script のベースは JavaScript1.8 相当ということなのですが、「ブラウザにはあるあのメソッドってApps Scriptで使えたっけ？」とよく悩むのでメモ。

# Object

## Object - staticメンバ
- create
- defineProperties
- defineProperty
- freeze
- getOwnPropertyDescriptor
- getOwnPropertyNames
- getPrototypeOf
- isExtensible
- isFrozen
- isSealed
- keys
- preventExtensions
- prototype
- seal

## Object - インスタンスメンバ
- \_\_defineGetter\_\_
- \_\_defineSetter\_\_
- \_\_lookupGetter\_\_
- \_\_lookupSetter\_\_
- constructor
- hasOwnProperty
- isPrototypeOf
- propertyIsEnumerable
- toLocaleString
- toSource
- toString
- valueOf


# Array

## Array - staticメンバ
- concat
- every
- filter
- forEach
- indexOf
- isArray
- join
- lastIndexOf
- map
- pop
- prototype
- push
- reduce
- reduceRight
- reverse
- shift
- slice
- some
- sort
- splice
- unshift

## Array - インスタンスメンバ
- concat
- constructor
- every
- filter
- forEach
- indexOf
- join
- lastIndexOf
- length
- map
- pop
- push
- reduce
- reduceRight
- reverse
- shift
- slice
- some
- sort
- splice
- toLocaleString
- toSource
- toString
- unshift

# String

## String - staticメンバ
- charAt
- charCodeAt
- concat
- equalsIgnoreCase
- fromCharCode
- indexOf
- lastIndexOf
- localeCompare
- match
- prototype
- replace
- search
- slice
- split
- substr
- substring
- toLocaleLowerCase
- toLowerCase
- toUpperCase

## String - インスタンスメンバ
- anchor
- big
- blink
- bold
- charAt
- charCodeAt
- concat
- constructor
- equals
- equalsIgnoreCase
- fixed
- fontcolor
- fontsize
- indexOf
- italics
- lastIndexOf
- length
- link
- localeCompare
- match
- replace
- search
- slice
- small
- split
- strike
- sub
- substr
- substring
- sup
- toLocaleLowerCase
- toLocaleUpperCase
- toLowerCase
- toSource
- toString
- toUpperCase
- trim
- valueOf

# メンバ一覧の取得に使ったスクリプト
```js
function reportBasicTypeMembers() {
  var objects = [
    {foo: 'bar'}, // Oject
    ['1'], // Array
    new String(''),
  ];
  var report = {};
  for (var i = 0; i < objects.length; ++i) {
    var instance = objects[i];
    var ctor = instance.constructor;
    var proto = Object.getPrototypeOf(instance);
    var reportEntry = {
      constructor: ctor.name,
      staticMembers: Object.getOwnPropertyNames(ctor)
        .filter(function(name) {
          return -1 == ['arguments', 'arity', 'name', 'length'].indexOf(name);
        })
        .sort(),
      instanceMembers: Object.getOwnPropertyNames(proto).sort(),
    };
    report[reportEntry.constructor] = reportEntry;
  }
  var json = JSON.stringify(report, null, 2);
  // Logger.log だと途中で切れる
  SpreadsheetApp.getActiveSpreadsheet()
    .getActiveCell()
    .setValue(json);
}
```
Node-RED+Dashboardを使い、WebブラウザからPCカメラをキャプチャして画像解析する

# Node-RED+Dashboardを使い、WebブラウザからPCカメラをキャプチャして画像解析する
## はじめに
2018年9月現在、AIブームです。特に画像解析にAIを使うケースが増えてきました。
ビジュアルプログラミング環境であるNode-REDを使うと画像解析API（OpenCVやIBM CloudのVisual Recognitionなど）を呼び出すアプリが簡単に作れます。node-red-dashboardを使えばWebベースで画像解析アプリを作ることも可能です。

以下の画面は、Web画面にて自分のPCについているカメラを使って画像をキャプチャし、OpenCVで顔判定して顔の部分に丸を付ける、という例です。
WebブラウザでURLを開くと、HTML5の機能によりPCカメラへのアクセスを要求してきます。これを承認すると、動画欄にカメラ画像が表示されます。画像の上部にあるCaptureボタンを押すと、すぐ下のCanvasに画像をキャプチャし、Node-REDサーバにCanvas内容を送信。サーバ側は、OpenCV顔分類器で画像分析し、結果をHTMLインライン画像としてWebブラウザに表示してくれます。

![gamen1.png](https://qiita-image-store.s3.amazonaws.com/0/155377/73aa2297-90bb-ad7e-fe66-4a4330f8ac1f.png)
※自分の顔を晒すのは嫌なので、適当な顔写真を使いました・・・

本文は、このやり方をご紹介します。

## 条件
いくつか条件があります。
- Webブラウザ側ではHTML5 Videoタグを使いますが、Chrome、Firefoxなど、タグをサポートしているWebブラウザが必要です
- Videoタグでカメラにアクセスするためにはhttps接続が必須のため、サーバ（Node-RED）側はhttpsで稼働させる設定が必要です（IBM Cloudはデフォルトでhttps動作、Raspberry Pi等でローカル環境でNode-REDを動かす場合は”オレオレ認証”等の対応が必要です）
- もちろん、クライアント側にはカメラ（最近のPCは標準でついていると思いますがUSB接続カメラでも可能。なお、Androidスマホ＋Chromeでも動く）が必要です

## では、始めましょう

Node-REDのインストールおよびhttps設定は終わっているものとします。本文では、IBM Cloud上のNode-RED、および、Raspberry Pi上のhttps設定済みNode-REDで試しました。クライアントは両方とも同じPC（Windows10＋Chrome＋PCのビルトインカメラ）を使いました。

### 1. Node-REDの追加設定

Node-REDは、node-red-dashboardを使用することでWebブラウザ上にダッシュボードを簡単に作れます。このノードには、templatesノードという自由にUIの中身を書けるノード（Angular 2のコンポーネントとして記述する）があり、これを使ってVideoキャプチャや、結果画像のインライン表示を行っていきます。
また、Webブラウザとサーバ間でBase64エンコードした画像データをやり取りするため、Base64エンコード／デコードノードも併せてインストールします。

- node-red-dashboard
- node-red-contrib-base64
 
画像解析APIとして、Raspberry PiではOpenCV環境を、IBM Cloud環境では、Watson Visual Recognitionサービスを使用しました。

- node-red-contrib-opencv　※先だってOpenCVそのものをapt-getで入れておくこと（Raspberry Pi）
- Watson Visual Recognitionノード（IBM Cloud上のNode-REDボイラープレートなら標準で入っている）

※Node-REDに追加ノードをインストールする方法は割愛します。
※IBM CloudでWatson Visual Recognitionサービスを設定する方法は割愛します。

### 2. Node-REDでフローを作成する
**Raspberry Pi上でOpenCVによる顔認識する例（冒頭の写真）です。**
![node_rei.png](https://qiita-image-store.s3.amazonaws.com/0/155377/e206e590-ee34-c73d-ec93-b942bc3302ba.png)
※上記フローのコードは以下。
https://github.com/arrowmeiwaracing/test/blob/master/quiita_nodeflow1
※カメラから画像をキャプチャしサーバに投げるTemplatesコードは以下。
https://github.com/arrowmeiwaracing/test/blob/master/templates_1
※判定した画像データをWebページ（ダッシュボード）上にHTMLインライン画像で表示するTemplatesコードは以下。
https://github.com/arrowmeiwaracing/test/blob/master/templates_2



**IBM Cloud上で年齢推定している例です。**
![gamen2.png](https://qiita-image-store.s3.amazonaws.com/0/155377/3f54d8fa-f008-e715-65e0-70ad43779219.png)
・・・モナリザはアラサーなんですね・・・

※フローのイメージ
　APIキーなどが入っている都合上、コードは公開しません。
![ibm-node.png](https://qiita-image-store.s3.amazonaws.com/0/155377/7cfd7c3c-677e-ca3d-31f7-14f396086d00.png)


## 終わりに

Node-REDのフローを見ると、画像を受け取った後の画像解析ノードだけが異なっていることがわかります。今回紹介した画像解析API以外にも、以下のようなものもあり、
- QRcodeを読むノード
- Google CLOUD VISION API使う例
- IBMのRecognitionでリア充判定している人
色々探してみると面白い発見があるかもしれません。
Pythonでtkinterを使用するときにハマった件

python3でidle3を使うと、次のようにTcl/Tkのバージョンが不安定(非推奨)とメッセージが出る。

```
WARNING: The version of Tcl/Tk (8.5.9) in use may be unstable.
```

調べてみると、idle3が突然、落ちたりすることもあるらしい。
pythonのTcl/Tk使用時に呼ばれるpythonのライブラリと、そのライブラリが依存するTcl/Tkのライブラリを調べてみる

```
$ python3 -c "import _tkinter; print(_tkinter.__file__)"
/Users/tsuji/anaconda/lib/python3.6/lib-dynload/_tkinter.cpython-36m-darwin.so
$ otool -L $(python3 -c "import _tkinter; print(_tkinter.__file__)")
/Users/tsuji/anaconda/lib/python3.6/lib-dynload/_tkinter.cpython-36m-darwin.so:
/System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl (compatibility version 8.5.0, current version 8.5.9)
/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk (compatibility version 8.5.0, current version 8.5.9)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
$ otool -L /Users/tsuji/anaconda/lib/python3.6/lib-dynload/_tkinter.cpython-36m-darwin.so
/Users/tsuji/anaconda/lib/python3.6/lib-dynload/_tkinter.cpython-36m-darwin.so:
/System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl (compatibility version 8.5.0, current version 8.5.9)
/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk (compatibility version 8.5.0, current version 8.5.9)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
*python -c は""内のPythonコードを実行します
*otool -L は使用しているフレームワークを出力します
```
どうも、/System/Library/Frameworks　を参照しているらしい。
Tcl/Tkのサードパーティ版の最新ActiveTcl8.6.6をインストールすると、
/Library/Frameworks/　以下の　Tcl.framework/ と Tk.framework/ が更新された。
/System/Library/Frameworks以下は更新されていない。
/System/Library/Frameworks以下はAppleが提供するFrameworkのみ設置が可能らしい。
なので、bashでデフォルトで参照するフレームワークのライブラリを、
/System/Library/Frameworks　から　/Library/Frameworks/ に変えてみる。
.bash_profileに次を追加


```
export DYLD_FRAMEWORK_PATH="/Library/Frameworks"
```
idle3を使うと、まだTcl/Tkのバージョンが不安定(非推奨)とメッセージが出る。

/Library/Frameworks/　以下の　Tcl.framework/ と Tk.framework/ を8.6.6から8.5.18に変えて、再インストール。

```
Python 3.6.1 |Anaconda custom (x86_64)| (default, May 11 2017, 13:04:09)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "copyright", "credits" or "license()" for more information.
```
やっと、警告が消えた。
どうも、python3.6.1はTcl/Tk８．６には対応していないらしい。

参考サイト:
[Re: Getting IDLE to use correct Tcl/Tk on MacOSX 10.6?](http://code.activestate.com/lists/python-list/708162/?_ga=1.254001032.1251123037.1486910846)
[Cocoaの日々](http://cocoadays.blogspot.com/2010/11/macios-framework.html)
Spring 例外ハンドリング

# はじめに
Spring初心者です。
1.5ヶ月ほどで、Webアプリケーションを作りました。

例外処理について調べたので、まとめます。

# HandlerExceptionResolver
これを使って例外処理をする。

以下の順番で処理されていく
① `@ExceptionHandler`を付与したメソッド
② `@ResponseStatus`を付与したメソッド
③ Springで定義されている例外を処理するHandlerExceptionResolver
④ HandlerExceptionResolverを実装したクラス


個人制作の範疇ならば、①と②を使えば十分だった。

実際の使用例
① `@ExceptionHandler`

~~~Controller.java
@ExceptionHandler(Exception.class)
public String Handler(){catchしたExceptionの処理内容}
~~~

　　
② `@ResponseStatus` (クラスに@つけても大丈夫かも)

~~~Controller.java
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public String Status(){例外処理}
~~~

# 例外を投げる
アプリケーション制作にあたり、以下のような役割にわけた。

- `@Controller`
- `@Service`
- `@Repository`

理想としては、`@Service`でエラーを投げたかったが、できなかった。
おそらく`@Controller`クラスで、各Serviceクラスを`@Autowired`してたから、
Controller側で処理するしかなかったと思っている。

もしかしたらServiceで処理できたのかもしれないな。。。

# まとめ
慣れたら意外と、例外処理はできた。

`@Controller`のスーパークラスにExceptionControllerなどを作って、
そこに各Exceptionの処理をまとめて記述した。
Controller単位でハンドリングしたい場合は、
都度Overrideすれば、余分な記述はなくなるかと。

ソースは[**GitHub**](https://github.com/connectcrew-ishii/DanceSpring)に載っています。
matplotlib.basemapのエラーの対処法。

Pythonでmatplotlib.basemapを使って地図を描こうと試したとき、
エラー（AttributeError: 'AxesSubplot' object has no attribute 'get_axis_bgcolor'）がでて困りました。
その対処法がわかったの共有します。

matplotlibをつかって地図を描きたいかたは、このページをご参考にしてください。

[matplotlib.basemapで簡単にマップを描画する](https://qiita.com/msrks/items/ed18a2653bc177a24cca)


このページを参考にして、matplotlib.basemapのモジュールをインストールします。
そして、このページにあるコードを実行すると、以下のエラーがでてきます。

```
  File "/Users/anaconda3/lib/python3.6/site-packages/mpl_toolkits/basemap/__init__.py", line 1767, in fillcontinents
    axisbgc = ax.get_axis_bgcolor()
AttributeError: 'AxesSubplot' object has no attribute 'get_axis_bgcolor'
```

'__init__.py'のなかの1767行目のaxixbgc = ax.get_axis_bgcolor()でエラーがでているらしい。
ax.get_axis_bgcolorは使えない、ということです。

このコマンド部分を、以下に修正します。

axixbgc = ax.get_fc()

```__init__.py
       # get axis background color. 
        axisbgc = ax.get_fc()　#修正部分
        npoly = 0
        polys = []
```

これによって、matplotlib.basemapにて地図が描けるようになりました。
同じ問題が発生した方に参考になれば幸いです。
PowerShellで大量のファイルのリストを作ったり、加工してプログラムで使ったり

特定のファイルフォルダ内のリストを取得してなんらかの処理を行いたい というときはよくあると思います。
今までだと、`dir`コマンドで取得したデータをテキストエディタにコピーしてなんとかかんとか・・・ とかしなければならなかったのですが、PowerShellだとコマンドだけである程度のところまでいけます。

# とりあえず基本：ファイル名のみの取得
`ls *.png`などを使って、その名前部分のみを取得します。

```powershell
  $s = ls *.exe
  $s.Name
```
こう書いてもいけます

```powershell
  (ls *.exe).Name
```

# ファイルリストの特定の文字列などを取り除く
例えば"○○-△△.png"などといったファイルが大量に並んでいるフォルダで、○○のみの一覧を作りたいとき

```powershell
  $s = ls *.png
  $n = $s.Name. -replace '-\w+.png$' | Get-Unique
```

`-replace`句の引数には正規表現が使えます。マッチした部分を削除したうえで、重複のない名前のリストを作ります。

## さらに取得したデータを、そのままプログラムで使いたいとき

ほんとは各種プログラム言語のファイル処理関数などを使うべきところでしょうが、ちょっとしたコードだとそれを使うのも面倒です。そんなときも、PowerShellなら簡単

```powershell
  $s = ls *.png
  $n = $s.Name. -replace '-\w+.png$' | Get-Unique
  $n -split "\n" -join "," | CLIP
```

これで、ファイル名の一覧を,区切りで結合した文字列が、クリップボードに貼り付きます。あとはソースコードに貼り付けるだけ。

この辺のコマンドは基本中の基本ですが、意外と応用が利きそうですし覚えておくと良さそうです。
CloudFront + S3 で静的サイトを運用する際の注意点

# 概要

CloudFront と S3 で静的サイトを構築する場合、以下の 2 種類の構成があります。

1. CloudFront のオリジンに、 S3 バケットそのものを指定する構成。
2. CloudFront のオリジンに、 S3 バケットの Static website hosting のエンドポイントを指定する構成。

できることはだいたい同じですが、微妙に差異があるので、比較します。

# まとめ

|差異|構成 1|構成 2|
|---|---|---|
|S3 Static Website Hosting の設定|不要|必要|
|サブディレクトリのインデックスファイル※1|利用不可|利用可|
|S3 バケットの安全性|高|低|
|アクセス制限|CloudFront 側のみで完結|S3 側でも設定する必要あり|

※1 https://[CloudFront]/foo および https://[CloudFront]/foo/ という URL に対して、 foo/index.html などインデックスファイルを出力する機能。

# 構成 1. CloudFront のオリジンに、 S3 バケットそのものを指定する構成。

参考: [[CloudFront + S3]特定バケットに特定ディストリビューションのみからアクセスできるよう設定する ｜ Developers.IO](https://dev.classmethod.jp/cloud/aws/cloudfront-s3-origin-access-identity/)

## 主要点

- S3 バケットはパブリックアクセス可能に**しない。**
- S3 バケットの Static Website Hosting は有効に**しない**。
    - 有効にしても実害はないと思いますが、 CloudFront が S3 バケットに直接アクセスするこの構成では、意味はありません。(多分)
- CloudFront は Origin Access Identity を使って S3 バケットにアクセスする。

## メリット

- S3 バケットへ直接アクセスされることを防げる。
    - → S3 バケットに大量アクセスがきて、課金額が膨れ上がってしまうケースを防げる。
- S3 バケットの直接アクセスを考えなくていいため、 CloudFront の機能だけである程度のアクセス制限を実現できる。
    - AWS WAF や Lambda@Edge によるプログラマブルな制御など。

## デメリット

- サブディレクトリのインデックスファイルが**効かない**。
    - S3 バケットに foo/index.html というファイルがあり、 https://[CloudFront]/foo および https://[CloudFront]/foo/ という URL でアクセスしようとしても、エラーになってしまう。
    - インデックスファイルは、ルートディレクトリでのみ効く。
    - Lambda@Edge を使えば、この機能をある程度エミュレートすることが可能。 
        - 参考: [できた！S3 オリジンへの直接アクセス制限と、インデックスドキュメント機能を共存させる方法 ｜ Developers.IO](https://dev.classmethod.jp/cloud/aws/directory-indexes-in-s3-origin-backed-cloudfront/)
        - ただし (オリジンへの) 全アクセスに対して Lambda が起動するので、パフォーマンス&コストには注意が必要。
- S3 バケットを us-east-1 以外のリージョンで作成した場合、そのバケットを作成してから 1-2 時間？経たないと、正常に動作しない。
    - [Cloudfront,S3で307リダイレクトに苦しめられた - パパエンジニアのアウトプット帳](http://masaru-tech.hateblo.jp/entry/2018/03/27/111327)
    - その他 [【CloudFront S3 リダイレクトされる】で検索](https://www.google.co.jp/search?q=CloudFront+S3+リダイレクトされる)

# 構成 2. CloudFront のオリジンに、 S3 バケットの Static website hosting のエンドポイントを指定する構成。

参考: [Amazon S3 + CloudFront で始める静的サイトホスティング | kuune.org](https://kuune.org/text/2016/05/12/static-website-hosting-using-aws-s3-and-cloudfront/)

## 主要点

- S3 バケットはパブリックアクセス可能に**する**。
- S3 バケットの Static Website Hosting を有効に**する**。

## メリット

- サブディレクトリでもインデックスファイルが**効く**。
- S3 バケットを us-east-1 以外のリージョンで作成しても、すぐ利用できる。
    - 構成 1 のデメリットの逆。

## デメリット

- S3 バケットの名前が漏れると、 **S3 バケットへ直接アクセスされてしまう**。
    - [Amazon S3 + CloudFront で始める静的サイトホスティング | kuune.org](https://kuune.org/text/2016/05/12/static-website-hosting-using-aws-s3-and-cloudfront/) にある通り、バケットのポリシーで User Agent による制限を行うことは可能だが……。
    - [S3の静的ウェブサイトをカスタムオリジンとしてCloudFront運用する場合のS3側接続制限について - Qiita](https://qiita.com/takeswim/items/fccdf68c4f8f522e6a99) では、S3 バケットのバケットポリシーを定期的に自動更新し、 CloudFront の IP アドレスからのみアクセスできるようにする構成が解説されている。
- S3 バケットに直接アクセスされてしまうため、 CloudFront でアクセス制限を行っていても、それだけでは不十分になってしまう。

# 後書き

- サブディレクトリの URL には必ず末尾に index.html まで付ける、というルール化が可能であれば、何の問題もなく構成 1 が良いです。
- そうでない場合、構成 2 にするのが設定的には楽ですが、セキュリティに対して留意が必要です。
    - 手間とリターンのバランス次第で。
OpenCV の VideoCapture で生フレームを取得する方法

## 背景

Linux 環境で Motion JPEG 出力のカメラを繋いで `cv2.VideoCapture` すると、JPEG がデコードされて出力が得られるのですが、生の JPEG のままの画像を取得する方法が知りたくて、調べました。

## 生フレームを取得する方法

RGB への変換オプションを無効にすると、生の画像が取得できます。

``` python
>>> import cv2
>>> cap = cv2.VideoCapture(0)
>>> cap.get(cv2.CAP_PROP_CONVERT_RGB)
1.0
>>> cap.set(cv2.CAP_PROP_CONVERT_RGB, False)
>>> cap.get(cv2.CAP_PROP_CONVERT_RGB)
0.0
>>> cap.read()
```

## 処理の裏側

`opencv/modules/videoio/src/cap_v4l.cpp` を見ると、

``` C++
static IplImage* icvRetrieveFrameCAM_V4L( CvCaptureCAM_V4L* capture, int) {
    // 前略
    if(!capture->convert_rgb) {
        capture->frame.imageData = (char*)capture->buffers[capture->bufferIndex].start;
        return &capture->frame;
    }
    // 後略: フォーマットに応じたデコード処理
```

RGB への変換処理が無効な場合、デコードせずに生の値を返してくれるようです。

## 参考

- [How to get raw data using OpenCV APIs](http://answers.opencv.org/question/96945/how-to-get-raw-data-using-opencv-apis/)
Pythonによる単純なUDP送信GUIプログラム

##概要
[UDPパケットを送信するプログラム](https://qiita.com/Oside/items/b7b2666474e71b0fa222)をGUI化したい
GUIの構築にはTkinterを使う

##環境
* OS : Windows10 Pro
* IDE : PyCharm CE
* Python3.6

##GUI
下の画像みたいな感じにする
Sendだけはボタンで他はテキストボックス
テキストボックスの実装には一行だけ入力できるtk.Entryを使う
![gui.png](https://qiita-image-store.s3.amazonaws.com/0/283013/e6ac1094-5e43-5772-1ce1-03a6f91e3c04.png)

* IP : 対象のIPアドレス
* Port : 対象のポート
* Delay : パケットを送る間隔
* Data : パケットの中身
* Num : 送るパケットの総数

##ソース
```udp_send_gui.py
# -*- coding:utf-8 -*-

import time
import socket
import tkinter as tk


def udp_send():
    msg = DataBox.get()
    # 送るメッセージ

    client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    delay_time = DelayBox.get()

    for i in range(0, int(NumBox.get())):
        client.sendto(msg.encode(), (IpBox.get(), int(PortBox.get())))
        time.sleep(float(delay_time))
# UDP送信関数


root = tk.Tk()  # ウィンドウ作成
root.title("UDP Packet Generator")  # ウィンドウタイトル
root.geometry("640x480")    # ウィンドウサイズ


Ip = tk.Label(root, text="IP:")
Port = tk.Label(root, text="Port:")
Delay = tk.Label(root, text="Delay:")
Data = tk.Label(root, text="Data:")
Num = tk.Label(root, text="Num:")

IpBox = tk.Entry(font=("Consolas", "30"))
PortBox = tk.Entry(font=("Consolas", "30"))
DelayBox = tk.Entry(font=("Consolas", "30"))
DataBox = tk.Entry(font=("Consolas", "30"))
NumBox = tk.Entry(font=("Consolas", "30"))

IpBox.insert(tk.END, "192.168.")
PortBox.insert(tk.END, "9998")
DelayBox.insert(tk.END, "0.1")
NumBox.insert(tk.END, "1")
# 部品の作成


Ip.place(height=60, y=30)
Port.place(height=60, y=150)
Delay.place(height=60, y=270)
Data.place(height=60, y=390)
Num.place(height=60, x=440, y=390)

IpBox.place(height=60, width=360, x=60, y=30)
PortBox.place(height=60, width=360, x=60, y=150)
DelayBox.place(height=60, width=360, x=60, y=270)
DataBox.place(height=60, width=360, x=60, y=390)
NumBox.place(height=60, width=120, x=500, y=390)
# 部品の配置


Send = tk.Button(root, text="Send!")
Send["command"] = udp_send
Send.place(height=300, width=185, x=440, y=30)
# 送信ボタン

root.mainloop()

```

##結果
![UDP_Packet_Generator.PNG](https://qiita-image-store.s3.amazonaws.com/0/283013/8c6aea19-95c1-17c3-6d16-4e17cf63374a.png)

##まとめ
簡単にGUIが作れるTkinterつよい
【解決】Slackにbotからthreadを投げるとなぜか2回目以降ズレる。。。

# 起こったこと
botでslackのthreadに返信を送るようにしていたら、
ある日を境になぜか二個目以降のメッセージが外に出されていた。
（下図では元のメッセージに6件threadが入るはずだった）
<img width="680" alt="スクリーンショット 2018-08-31 19.30.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/198985/1bb6f648-efb2-3af0-fa7a-38bd72ec8587.png">

# threadに送る仕組み
slackの場合threadを送りたいメッセージの
`ts: "1535709632.000100"`
の値を送るメッセージの`thread_ts`にセットするだけ
`"thread_ts": "1535709632.000100"`

# 調査結果
以下のURLにget requestをして帰ってきたトークの情報から何が起こっていたかを調査
`https://slack.com/api/channels.history?token=xoxb-*************-******************&channel=CHANNEL_ID`

その結果なぜか2回目以降のメッセージだけ`thread_ts`が1ずれていた
`"thread_ts": "1535709632.000100"`
=> 
`"thread_ts": "1535709633.000100"`

しかも2回目以降ではなく随時二個目が送られるとずれるようで、
唯一元メッセージにthread返信できていたのは最後のリプライのみだったもよう。。。
バグなのかわからないが何か解決策が知りたい。。。
Djangoで取得件数の多いSQLの結果をcsvとしてエクスポートさせる

SQLの実行結果をCSVとしてエクスポートさせることは多々あるんですが、
その件数結果が多すぎてタイムアウトが発生したとか、メモリを使いすぎてwebサーバが爆発:boom:した……ということも稀にあったりします。
ので、少しずつ取得しつつ結果をcsvとして出力する方法を備忘録も兼ねて。

# 準備するもの！

```py
class Echo(object):
    def write(self, value):
        return value

def yield_query(query):
    filter_id = 0

    while True:
        rows = list(query.filter(id__gt=filter_id).order_by('id')[:1000])

        if len(rows) == 0:
            break

        for row in rows:
            yield row

        filter_id = rows[-1].id

def stream_csv_response(rows):
    writer = csv.writer(Echo())

    response = StreamingHttpResponse(
        (writer.writerow(row) for row in rows),
        content_type="text/csv"
    )

    response['Content-Disposition'] = 'attachment; filename="big.csv"'

    return response
```

- yield_queryは、渡されたqueryを少しずつ実行していく関数です。
- stream_csv_responseは、yield_queryの実行結果を引数rowsで受け取り、Djangoのresponseを返してあげる関数です。

# 呼び方！

```py
# 適当なModelを用意
test_query = Test.objects

# yieldを返すobjectを取得
yield_rows = yield_query(test_query) 

# レスポンスの返却
return stream_csv_response(yield_rows)    
```

ね、簡単でしょ？
datepickerについて 


## 結局、どのdatepickerが一番使い勝手がよいのか
https://qiita.com/knt45/items/6d74f6785cd4547ae53b

## flatpickr.js参考サイト
https://metrograph.jp/js-flatpickr/
https://tr.you84815.space/flatpickr/examples.html

##公式document
https://flatpickr.js.org/options/

## date picker
https://qiita.com/Yuta_Fujiwara/items/66af40dcc5ce206933eb


## エラー

### datepicker.jsの注意点


#### 1.呼び出す順番

```erb
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'legacy.js' %>
<%= javascript_include_tag 'picker.js' %>
<%= javascript_include_tag 'picker.date.js' %>
<%= javascript_include_tag 'picker.time.js' %>
```

#### 2.assets.rb のplicompileを指定

```rb
Rails.application.config.assets.precompile += %w(footer classic.css classic.date.css classic.time.css legacy.js picker.js picker.date.js picker.time.js)
```

#### 3.application.jsで`//= require_tree .`の削除

```js
//= require_tree . <-削除
```

## 日本語化など
https://qiita.com/Yuta_Fujiwara/items/e80fb931af623bd8e73e#%E6%97%A5%E6%9C%AC%E8%AA%9E%E5%AF%BE%E5%BF%9Cdatepicker
Re:dashで、FirebaseAnalyticsのBigQueryからコホートを表示する方法


FirebaseAnalytics使っていますか？無料でここまでやってくれるのはかなりありがたいですね。
私は特にRetensionページをよく見るのですが、ここではフィルターはできず、新規ユーザーに関するコホートしか見れません。
新規ユーザーだけでなく、ある時点で特定の状態だった人の継続率をみたいケースがあったので、手始めに新規ユーザーに関するコホートをRe:dashで再現することにしました。

## 1. クエリを作る
コホートを表示するには以下の4つの数字が必要です。（[参考文献](https://qiita.com/yokotty_j/items/b28452f117f0777e551e))

1. date（獲得日）
2. past_days（経過日数）
3. user_count (date, past_daysごとのユーザー数）
4. total_count（獲得日の人数（母数））

実際のクエリはこちらです。期間は昨日から28日間を取得しています

```
WITH first_counts AS
  (SELECT DATE(TIMESTAMP_MICROS(user_first_touch_timestamp), 'Asia/Tokyo') AS first_open_date,
          count(DISTINCT user_pseudo_id) AS total_count
   FROM `ninarubaby.analytics_164116869.events_*`
   WHERE _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY))
     AND device.operating_system = "IOS"
   GROUP BY first_open_date),
     cohorts AS
  (SELECT DATE(TIMESTAMP_MICROS(user_first_touch_timestamp), 'Asia/Tokyo') AS date,
          DATE_DIFF(DATE(TIMESTAMP_MICROS(event_timestamp), 'Asia/Tokyo'), DATE(TIMESTAMP_MICROS(user_first_touch_timestamp), 'Asia/Tokyo'),DAY) AS past_days,
          count(DISTINCT user_pseudo_id) AS user_count
   FROM `ninarubaby.analytics_164116869.events_*`
   WHERE _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 28 DAY)) AND FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY))
     AND device.operating_system = "IOS"
     AND DATE(TIMESTAMP_MICROS(user_first_touch_timestamp), 'Asia/Tokyo') >= DATE_SUB(CURRENT_DATE(), INTERVAL 28 DAY)
   GROUP BY past_days, date )
SELECT date, past_days,
             user_count,
             total_count
FROM first_counts
INNER JOIN cohorts ON first_counts.first_open_date = cohorts.date
WHERE past_days > 0
```

date, past_days, user_countは一気にとってしまって、別でとったtotal_countをinner joinしています。
firebase analyticsの設定によりますが、弊社では日本時間で設定していたのでtimestamp型からdate型に変換する際にtimezone（Asia/Tokyo）を指定しています。
`past_days > 0` を表示しないと一部表示がおかしくなったので一応つけていますが、手元で確認して問題なければ削除しても良いと思います。

## 2. コホートを表示する

それでは、実際に可視化して見ましょう

1. Re:dash上で `New Visualization` をクリック
2. 以下のように設定
 - Visualization Type: Cohort
 - Date: date
 - Strage: past_days
 - Bucket Popuration Size: total_count
 - Stage Value: user_count
3. Saveをクリック

![Re:dashでコホートを設定する](https://qiita-image-store.s3.amazonaws.com/0/68146/076701dd-aa59-af59-efed-6a6e2250f8d9.png "visualization.png")

すると、下記のような画面が作成できます（実際のデータは見せられないのでイメージ図ですw）
![コホートイメージ.png](https://qiita-image-store.s3.amazonaws.com/0/68146/ca39503b-5a39-45c8-79ae-4eb13efe5b12.png "コホートイメージ.png")

## 最後に
BigQueryにexportしてくれてれば、あとでなんとでもなるというのは楽ですね。
また、BigQueryなので、データが大きくても耐えられる時間内で帰ってきてくれるのも嬉しいところです。
初期のアプリであればBigQueryにexportしてもタダみたいな値段で使えるのでとりあえずexportしておくことをオススメします。
では、よいデータライフを
マイグレーションの確認

MySQL ログイン

```ruby:qiita.rb
$ mysql -u root
```



データベースの選択・・・データベース名を入力

```ruby:qiita.rb
mysql> use message-board_development
```

テーブル一覧確認（messagesテーブルが作成されているか確認）

```ruby:qiita.rb
mysql> show tables;
```


テーブル設計の確認・・・デーブル名を入力

```ruby:qiita.rb
mysql> describe messages;
```
Swiper4.3.5ってiosのバージョンによっては動かないらしい

#開発環境
使用言語:javascript
パッケージ管理ツール:npm
フレームワーク:Vue.js

#Swiper実装
npmでSwiperをインストールします。

```npm install swiper```
Swiper4.3.5をインストール

これでSwiperが使えるようになりました。
あとはSwiperのドキュメントを見ながら必要な記述を追加して終わりです。
下記サイトのドキュメントを見ながらせっせと追加していきました。
http://idangero.us/swiper/get-started/

ローカル環境でSwiperの動作確認ができていたのですが...

iosのバージョンにより、webページが写っていないことが判明しました。

なんてこったい...


#問題の切り分け
現状確認
・Swiperを実装することにより、一部のiosバージョンで画面が映らない現象が発生
・iosのバージョンは9.3.3と10.2系で発生
予想される原因
・Swiperの記述が間違えている
・Swiperを追加した時の記述が足りていない
・Swiperのバージョンがiosのバージョンをフォローしていない
結果
原因をそれぞれ確認していくと、どうやら最新バージョンのSwiperが一部のiosのバージョンをフォローしていないことが分かりました。

#問題解決
Swiperのバージョンをダウングレードすることにより、iosのバージョンをフォローすることができました。
```npm install Swiper@2.7.6```
Swiperのバージョンを指定して、再びインストールします。

iosのバージョンに関わらず画面に映るようになりました。
スワイプもしていました。改修が完了したかのように見えたのですが、
ボタンでSwiperが効かなくなっていました。

#問題の切り分け
現状確認
・画面に映るようにはなりましたが、ボタンを押してもスワイプがしない問題が発生
・Swiper2.7.6で使用可能なパラメータを確認
https://github.com/nolimits4web/swiper/blob/v2.7.6/src/idangerous.swiper.js#L112-L203

原因
・使用できないパラメータを使ってしまっている為、動作していないことが判明

```ruby
navigation: {
 nextEl: '.swiper-button-next',
 prevEl: '.swiper-button-prev',
},
```

解決準備
・swiperのドキュメントを確認し、必要な処理を探す
https://github.com/nolimits4web/Swiper/blob/Swiper2/API.md

```vuejs

mySwiper.swipeNext(runCallbacks)
mySwiper.swipePrev(runCallbacks)
```

それっぽいのを発見したので実装してみました。

#解決手順

1, mySwiperを登録

```vuejs
data(){
 return{
   mySwiper: null
 };
}
```

2, methodsにボタンを指定しているdivタグで発動する関数を定義

```vuejs
methods: {
 movePrev(){
   this.mySwiper.swipePrev();
 },
 moveNext(){
   this.mySwiper.swipeNext();
 }
},
```

3, mySwiperにnew Swiperを代入

```vuejs
this.mySwiper = new Swiper('.swiper-container,{
  loop: true,
  centeredSlides: true,
  speed: 2000,
  autoplay: 2000,
 });
```

4, ボタンのdivタグに@clickを追加

```vuejs
<div class="swiper-prev" @click="slidePrev()"></div>
<div class="swiper-next" @click="slideNext()"></div>
```

上記を追加すると、解決しました。
Eclipseでコメントの前の方だけ文字化けする

# はじめに
JavaのプログラミングでSTS（Eclipse派生IDE）を使っているのですが、今日、突然、文字化けするようになりました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/221845/b51eec69-104b-55f1-4806-568a2da8b0fc.png)

こんな感じにコメントの先頭の方だけ文字化けします！
他のエディタで開くと文字化けしていなく、STSで開いたときだけの現象です。

ちなみに環境は以下の通りです。
**STS 3.9.5**


# 原因はフォント

文字コードの設定等を見直しましたが、特に問題はなさそうで、これは迷宮入りか？と諦めかけていたところ、先輩が「それフォントの設定かも」と助言をくださり、フォントを見直したところ、解決しました！



# 解決方法

まず、STSのツールバーから**ウィンドウ**→**設定**を開きます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/221845/64ac0404-af83-7eaf-ebb0-c1a915f46f84.png)

左側の**一般**→**外観**→**色とフォント**をクリックします。
中央のリストにある**Java**を開き、中にある**Java エディター・テキスト・フォント**を選択し、**編集**をクリックします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/221845/755750b9-fd6e-d61f-4dab-e50374d3adb6.png)

こんなダイアログが表示されます。私の場合、フォントは**Consolas 標準 10**になっていました。先輩によるとこれはデフォルトのようです。

これを別のフォントに変更してみると、文字化けしなくなりました！

なぜConsolasだと文字化けするのか謎のままですが、症状が改善してよかったです。
【BigQuery】Firebase AnalyticsのDAU, WAU, MAUを取得するクエリ(新スキーマ)

## 概要

https://www.en.advertisercommunity.com/t5/Data-Studio/How-is-Firebase-Analytics-Monthly-30-day-Active-User-count/td-p/1638935#

内容は上記リンクを参考にしている。

こちらのリンクがBigQueryの旧スキーマでのクエリだったため
新しいスキーマへ調整した版を作成した。

## 結論

これです。

```
SELECT
date,
SUM(CASE WHEN period = 1 THEN users END) as days_01,
SUM(CASE WHEN period = 7 THEN users END) as days_07,
SUM(CASE WHEN period = 30 THEN users END) as days_30
FROM (
SELECT
dates.date as date,
periods.period as period,
COUNT(DISTINCT user_pseudo_id) as users
FROM `firebase_project_table.app_events_*`
CROSS JOIN (SELECT event_date as date FROM `firebase_project_table.app_events_*` WHERE event_name = 'user_engagement' GROUP BY date) as dates
CROSS JOIN (SELECT period FROM (SELECT 1 as period) UNION ALL
(SELECT 7 as period) UNION ALL (SELECT 30 as period)) as periods
WHERE dates.date >= event_date
AND SAFE_CAST(FLOOR(DATE_DIFF(PARSE_DATE("%Y%m%d",dates.date), PARSE_DATE("%Y%m%d",event_date), DAY)/periods.period) AS INT64) = 0
GROUP BY 1,2
)

GROUP BY date
ORDER By date
```

## 変更点


① ユニークユーザーの取得

```
COUNT(DISTINCT user_dim.app_info.app_instance_id) as users 
↓
COUNT(DISTINCT user_pseudo_id) as users 
```

② エンゲージメントイベントの指定方法

```
CROSS JOIN (SELECT e.date FROM `firebase_project_table.app_events_*`, UNNEST(event_dim) as e WHERE e.name = 'user_engagement' GROUP BY date) as dates
↓
CROSS JOIN (SELECT event_date as date FROM `firebase_project_table.app_events_*` WHERE event_name = 'user_engagement' GROUP BY date) as dates
```

③ 細かい所
日付の指定

```
○○.date 
↓
event_date
```

## おわりに

間違いがあれば、コメントいただけますと幸いです。
Laravel Dusk で縦長画面のキャプチャを撮りたい

Laravel Dusk で画面キャプチャが簡単に取れるのですが、
ディスプレイに収まらない場合、全体画像が取れないことがわかり、対処方法を考えてみました。

## 対処方法 - 概要

通常の画像と
一番下にスクロールした画像を撮影することで、
画面全体が確認できるようにしました。

> 2枚で収まらないケースが出てきたら、再検討します。

## 実行環境

Laravel5.5
MacOS High Sierra 10.13.2
PHP 7.1
Docker 18.06.0

## 対処方法 - 詳細


DuskTestCase.php に以下を追記

```
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\WebDriverDimension;

abstract class DuskTestCase extends BaseTestCase
{
　　　　　　　 // ------ 一番下に追記 ---------

    /**
     * Caputure Image for Long page.
     *
     * @return \Facebook\WebDriver\Remote\RemoteWebDriver
     */
    protected function captureImage($browser)
    {
        $body = $browser->driver->findElement(WebDriverBy::tagName('body'));
        if (!empty($body)) {
            $currentSize = $body->getSize();
            $size = new WebDriverDimension($currentSize->getWidth(), $currentSize->getHeight());
            $browser->driver->manage()->window()->setSize($size);
        }
        $browser->screenshot(date("Ymd")."_".$this->getName()."_001");
        
        $browser->script('window.scrollTo(0, 500);');
        $browser->screenshot(date("Ymd")."_".$this->getName().'_002');
    }
```

テストクラスの中で、画面キャプチャを撮りたい箇所に以下を記載する

```
parent::captureImage($browser);
```

これで、以下２枚の画像がキャプチャされます。

現在日付 + ファンクション名 ＋ 001.jpg　
現在日付 + ファンクション名 ＋ 002.jpg