OmniAICreator/Qiita-1.07M huggingface dataset:
Xamarin.FormsのCollectionViewのバグ

Xamarinのシェルテンプレートから開発を開始し、最初にあるListViewをCollectionViewに変えたら全くリストが表示されなくなった。

# 環境
* Xamarin.Forms 4.1.0.581479


# 問題の事象

CollectionViewが表示されるべき場所に何も表示されず、コンソールに以下のようなエラーが出ている。

````
Foundation.MonoTouchException: Objective-C exception thrown.  Name: NSInternalInconsistencyException Reason: Invalid update: invalid number of items in section 0.  The number of items contained in an existing section after the update (1) must be equal to the number of items contained in that section before the update (1), plus or minus the number of items inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out).
Native stack trace:
	0   CoreFoundation                      0x00000001155686fb __exceptionPreprocess + 331
	1   libobjc.A.dylib                     0x00000001160eaac5 objc_exception_throw + 48
	2   CoreFoundation                      0x0000000115568482 +[NSException raise:format:arguments:] + 98
・・・
````


# 問題が起きる実装

Viewはシェルテンプレートで作られるItemPage.xamlを改修
ListViewからCollectionViewへ

````xml
    <CollectionView 
        x:Name="ItemsListView" 
        ItemsSource="{Binding Items}"
        VerticalOptions="FillAndExpand"
        HorizontalOptions="FillAndExpand"
        >
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid Padding="10">
　　　　　　　　　　・・・
````

ViewModel側はシェルテンプレートで作られるItemsViewModelそのまま。
ItemSourceのデータは以下で作られている。

````csharp
            Items.Clear();
            var items = await DataStore.GetItemsAsync(true);
            foreach (var item in items)
            {
                Items.Add(item);
            }
　　　　　　・・・
````

# 原因

CollectionView.ItemSourceにバインドされているコレクションがResetされた時の動きがバグってる。
（ObservableCollectionをClearした時の動きがバグってる。）

https://github.com/xamarin/Xamarin.Forms/issues/5793


# 対応

とりあえず`Items.Clear()`をコメントアウトしたら回避はできる。
Clearできないけど・・・

IssueはCloseされてるのでそのうちリリースされるでしょう。
git commit数 marge除いて 洗い出し

テキトーにelmのtutorialでやってみる

```shell:your-terminal
$ pwd
# -> ~/workspace/elm-architecture-tutorial

$ git shortlog -s -n
# ->    127  Evan Czaplicki
#        8  Isaac Shapira
#        2  kaznak
#        2  Johannes Emerich
#        1  Franklin Chen
#        1  Grace Lee
#        1  Hitesh Jasani
#        1  Janis Voigtländer
#        1  Jason Merrill
#        1  Javier Santiago Lozano
#        1  Jon Wood
#        1  Jonathan Persson
#        1  Logan Dean
#        1  Marcelo Lazaroni
#        1  Michael Anderson
#        1  PBRT
#        1  Talon
#        1  Thomas Weiser
#        1  Théo Zimmermann
#        1  Ville Peurala
#        1  hossameldeenfci
#        1  ACJDG
#        1  rgscherf
#        1  Charles Watson
#        1  Chris Bolin
#        1  Cifer-Y
```
XamarinでMethod not found: void .ResourceLoadingQuery.set_Instance(object)と言われる

# 環境
* Xamarin.Forms　4.1.0.581479


# 事象

Xamarin.Formsを更新して、実行するとApp.InitializeComponentで以下のエラーが発生。

````
Method not found: void .ResourceLoadingQuery.set_Instance(object)
````


# 原因

Native側のXamarin.Formsを更新していないのが原因。
iOS側のパッケージを更新して、リビルドすると解決した。

関連：https://github.com/xamarin/Xamarin.Forms/issues/6787
【Java】複数のList（Collection）を結合する

# 前提条件
List::addAllでも結合そのものはできますが、今回は以下の条件を満たす結合を行います。

- リストはいくつ入ってもよい
- 元のリストには影響がない
- `new`をしない

# やり方
`Stream API`の`flatMap`を使えばできます。
配列に置き換える場合`.flatMap(Arrays::stream)`でできます。

```java
List l1, l2, l3; // 初期化済みのリストを想定

List merged = Stream.of(l1, l2, l3).flatMap(Collection::stream).collect(Collectors.toList());
```
PHPのdatetime文字列の比較にstrtotime()を噛ませるとどれくらい遅くなるか確認してみた

# 前提として

phpでdatetimeの文字列を扱う上では色々な課題や注意点があります
参考：[【PHP入門】日付を取得・比較する方法と注意点まとめ](https://www.sejuku.net/blog/21496#i-2)

ここでは純粋に実行速度の確認だけを実施して、良し悪しについては触れません。

# やってみた

PHP7.2です。

## 全貌

[Github - compare-processing-speed-casted-datetime](https://github.com/aromanokarisu/compare-processing-speed-casted-datetime)

プロジェクト名は英語ガバなので許してください
以下にコード記述しているので、みなくて大丈夫です

## 文字列そのままの比較をするコード

10万回比較を10セット実施し、実行時間を得る

```php
<?php
    $datetime_today  = date('Y-m-d H:i:s');
    $datetime_future = '2020-07-24 00:00:00';

    echo '文字列そのままの比較' . PHP_EOL;
    for ($count=0; $count<10; $count++) {
        $time_start = microtime(true);

        // 10万回の判定する
        for ($i=0; $i < 100000; $i++) {
            if ($datetime_today > $datetime_future) {
                // do nothing
            }
        }

        $time = microtime(true) - $time_start;
        echo $time . ' 秒' . PHP_EOL;
    }
```

## 文字列をstrtotime変換してからの比較をするコード

同じく10万回比較を10セット実施し、実行時間を得る

```php
<?php
    $datetime_today  = date('Y-m-d H:i:s');
    $datetime_future = '2020-07-24 00:00:00';

    echo '文字列そのままの比較' . PHP_EOL;
    for ($count=0; $count<10; $count++) {
        $time_start = microtime(true);

        // 10万回の判定する
        for ($i=0; $i < 100000; $i++) {
            if (strtotime($datetime_today) > strtotime($datetime_future)) {
                // do nothing
            }
        }

        $time = microtime(true) - $time_start;
        echo $time . ' 秒' . PHP_EOL;
    }
```

## 実行結果

```
文字列そのままの比較
0.0070090293884277 秒
0.0046958923339844 秒
0.0039851665496826 秒
0.004115104675293 秒
0.004082202911377 秒
0.0045111179351807 秒
0.0044329166412354 秒
0.0046958923339844 秒
0.0042669773101807 秒
0.0043740272521973 秒

文字列をstrtotime変換してからの比較
0.23847007751465 秒
0.23226594924927 秒
0.23400783538818 秒
0.23232102394104 秒
0.23448014259338 秒
0.23279094696045 秒
0.23338794708252 秒
0.23172903060913 秒
0.23631811141968 秒
0.23155283927917 秒
```

# 結論

strtotime()使わない方が50倍くらい早い！！
結構顕著な数字が出る。
yarn 基本的な使い方

rubyでいうgemのようなnode.jsのスクリプト管理ツール

```shell:
$ yarn init
# -> 対話式にpackage.json作成
```

```shell:
$ yarn add module_name
# -> ローカルインストール
```


```shell:
$ yarn list
# -> add済みのモジュール一覧
```

またhomebrewのようにshellで使えるcliをグローバルインストールすることにも使える

```shell:
$ yarn add -g xxxx # cliとして入れたいモジュール名
$ yarn add -g http-server # 例
```
rails rack config.ru useの書き方について

`use`は`Rack::Builder`で用意されたDSLの記法
よって、以下の2つは同じ

```ruby:config.ru
use MiddlewareA
use MiddlewareB
run App.new
```

```ruby:config.ru
Rack::Handler::CGI.run MiddlewareA.new( MiddlewareB.new( App.new ) )
```
SQLクエリについて

##初めてのSQLコマンド
[Working with Amazon Redshift（日本語版）](https://www.qwiklabs.com/focuses/332?parent=catalog)
今まで、SQLコマンドを書いてこなかったのですが、LABでSQLクエリの書き方を学んだので、覚書程度に残しておきます。
DBの詳細はQwiklabで確認してください。
ちなみに、RedshiftのQuery editorからクエリを送りました。

色々なコマンドを使いながら任意のデータを検索できるようにチャレンジしました。
コマンドを書く上で一番重要なポイントはSELECT文の評価順序だと感じました。
[SELECT文の評価順序の話](https://qiita.com/suzukito/items/edcd00e680186f2930a8)

1.FROM
2.ON
3.JOIN
4.WHERE
5.GROUP BY
6.HAVING
7.SELECT
8.DISTINCT
9.ORDER BY
10.TOP（LIMIT）

#SELECT文をSELECT
Groupごとの、上位3つのレコードの取得をしたいと思いましたが、FROM句は最初に処理をされるため、Groupごとの取得条件げ付けられないため、このように、SELECT文をSELECTすることになりました。
別の手段としてはAS句を利用してSELECT文で新しいテーブルを作り、2つのクエリに分けてレコードの取得をすることも可能です。

各年の、キャリアごとの、都市間の移動距離の合計の　上位３つのキャリアを取得する、SELECT文です。

```xxx.sh
SELECT
    *
FROM
    (
        SELECT
            year,
            sum_mile,
            row_number() over(partition by year order by sum_mile desc) AS num
        FROM
            (
                SELECT
                    carrier,
                    year,
                    SUM(miles) AS sum_mile
                FROM
                    flights
                GROUP BY
                    carrier,
                    year
                ORDER BY
                    year,
                    sum_mile DESC
            )
    ) rank
WHERE
    rank.num BETWEEN 1 AND 3
;
ORDER BY
    year
```
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347413/7359b6ee-71db-c667-b910-45a13c912620.png)
SELECT文を評価順序に沿ってみていきます。
FROM内のFROMでflightテーブルを利用することを宣言します。
GROUP BYでcarrier,yearでグループを作成します。
SELECTのSUM(miles)でGROUPごとの都市間移動距離を取得します。
そしてyear(ASC),sum_mileでソートされます。
SELECT文のrow_number関数によって、yearごとのsum_mileの大きい順にランク付けがされ、出力されます。
その出力をWHERE句で上位３位に条件付けを行う
ORDER句でyearを昇順にソートし、表示する

#色々なコマンドを組み合わせて使ってみる

頭文字が'A'または、頭文字がBCの3文字のフライトの出発空港名で、かつ都市間の移動距離が500mil以上の、各年、キャリア、フライトの出発空港ごとの出発する便数合計が、1000以上のレコードを取得する


```xxx.sh
select
    year,
    MAX(departuresyear) as departuresyear
from
    (
        SELECT
            year,
            carrier,
            origin,
            sum(departures) AS departuresyear
        FROM
            flights
        WHERE
            (
                origin LIKE 'A%'
            OR  origin LIKE 'BC_'
            )
        AND miles >= 500
        GROUP BY
            year,
            carrier,
            origin
        HAVING sum(departures) > 10000
        ORDER BY
            1 ASC,
            departuresyear DESC
    )
GROUP BY
    year
ORDER BY
    year ASC
;
```
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347413/ccc4cbad-73d3-979b-63de-6e02974ef5c4.png)


FROMでflightテーブルを利用することを宣言し、
WHERE句で頭文字が'A'または、頭文字がBCの3文字のフライトの出発空港名で、かつ都市間の移動距離が500mil以上レコードに限定する
GROUP句で、year,carria,originのグルループを作成する
HAVINGでグループに対する条件指定を行い、合計出発便数が1000以上のレコードに限定する
SELECT文でテーブルを作成し、ORDER句でyearの昇順、年間合計出発便数の降順にソートして、出力する
yearでグループ化を行い、各年の最大年間出国便数を取得し、SELECT文で出力テーブルを作成し、
ORDER句でyearの降順でソートして、出力する

#まとめ
まだ、実際にSQLコマンドと利用したことはありませんが、なるべく使いまわせるテンプレートになるようにコマンドを利用しました。
なにか、改善案等あれば、ご教示ください。
mysql 過去180日のデータ取得

## 日付を計算する場合

```sql:
SELECT * FROM summary_tags
WHERE created_at BETWEEN (CURDATE() - INTERVAL 180 DAY) AND (CURDATE() + INTERVAL 1 DAY)
AND tag_id = 1473
```

interval xx dayは日付を表す
whereの条件はandで繋いでいく

## 日付を直接指定する場合

```sql:
SELECT * FROM summary_tags
WHERE created_at >= '2018-12-03 03:00:07'
AND tag_id = 1473
```

テーブル名、カラム名はただの事例
以上。
レンタルサーバーFTPでもデプロイスクリプトを用意してデプロイを楽する

# 背景

本番環境レンタルサーバーでFTPで手動アップは面倒くさい。もっと楽したい。
なんとか一部だけでも自動化できないかと思って試した。

## 環境

- 本番環境レンタルサーバー
- ローカル環境macOS Mojave(Laravel-Mix4を使っている)

## 主に使うもの

- ftp-deploy([公式ドキュメント](https://www.npmjs.com/package/ftp-deploy))

## package.jsonの設定

```js
{
	"private": true,
	"scripts": {
		"dev": "npm run development",
		"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
		"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
		"watch-poll": "npm run watch -- --watch-poll",
		"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
		"prod": "npm run production",
		"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
		"test": "jest",
		"predeploy": "npm install && npm run prod",
		"deploy": "node ftp-deploy"
	},

... 略
```

こんな感じでscriptを用意する

ルートディレクトリに`ftp-deploy.js`を用意する

## ftp-deploy.jsの設定

ルートディレクトリに`.env`はおいてある前提。
`FTP_USER` `FTP_PASSWORD` `FTP_HOST`を定義しておく

```js
var FtpDeploy = require("ftp-deploy");
var ftpDeploy = new FtpDeploy();
require('dotenv').config({path: __dirname + '/.env'})

var config = {
	user: process.env.FTP_USER,
	password: process.env.FTP_PASSWORD,
	host: process.env.FTP_HOST,
	localRoot: "/",
	remoteRoot: "/html",
	include: ["*.js"],
	deleteRemote: false,
	forcePasv: false
};

ftpDeploy.deploy(config)
    .then(res => console.log('finished:', res))
    .catch(err => console.log(err))
```

あとは

```
npm run deploy
```
を実行すれば、OK

念の為
`inquirer-confirm`とか用意しておくと良いかも。

## 参考

[ftp-deploy](https://www.npmjs.com/package/ftp-deploy)
jQueryプラグインのDatatablesにボタンやイベントを追加しようとしたらドツボにはまった件について

初投稿なのでアドバイスや指摘等あれば遠慮なくお願いします。

###0.前置き
jQueryにはDataTablesという便利なテーブルプラグインがあり、それを使っていたのだが、問題にぶち当たり、いくらググっても解決しないので、自力で解決した。
もしかしたら誰も書いてないかもしれないので、メモついでに書いておく。
（C\#にDataTableというものがあるらしいが、別物なので注意）

###1.環境、目的
環境：jQuery 3.4.1, DataTables 1.10.18
目的：DataTablesを使った上で、表の中にボタンを置きたかった。

###2.もくろみ
例えば売上テーブル（売上ID、売上日、顧客名）と売上明細テーブル（売上ID、商品ID、売上数量）があったとして、表には売上テーブルの情報を出力し、各行のボタンをクリックするとその明細が出る、みたいなことをやりたかった。
さらにセレクトボックスを置き、その選択内容で条件づけ（例えば売上日が１週間以内／１ヶ月以内／半年以内）し、ajaxを使ってページリロードなしで表を更新する、という風にしたかった。

###3.問題
DataTablesのapiには表をクリアするメソッドや行を追加するメソッドがあるので、それを使ってデータ抽出のたびにクリア→1行ずつ追加、とすればできるだろうと考えた。
しかし実際に使ってみると、追加する行のデータは配列で渡す必要があり、その中にボタンオブジェクトを入れて渡しても、正しく出力されない。
ならばと行を追加したあと自分でjQueryでhtmlをいじくってボタンを追加してみると、今度は一部の行にしかボタンが表示されない。
これはイベントも同様で、ボタンではなくテキストを置き、セルをクリックしたらページ遷移、というふうにイベントを設定しうとしたが、これも一部のセルにしか適用されなかった。以下、うまくいかなかった例：

```html:失敗例
<script>
$(function(){
	$('#sales_table').DataTable();			//#sales_tableにDataTablesを適用
	$('tbody td').click(function(){			//tbodyの中のtdタグ全てにクリックイベントを設定。クリックすると行と列の番号をダイアログで出す
		alert("行：" + ($(this).parent().index() +1) + ", 列：" + ($(this).index() + 1) + "");
	});
})
</script>
</head>
<body>
<table id="sales_table">
	<thead>
		<tr><td>あ</td><td>い</td></tr>
	</thead>
	<tbody>
		<c:forEach var="v" items="${sales}" varStatus="st">		//salesは売上データのコレクション
			<tr><td>${st.count }</td><td>${v }</td></tr>
		</c:forEach>
	</tbody>
</table>
</body>
```

###4.原因の分析
DataTablesを適用したテーブルのhtmlをいじるとき、どうやら初期表示される範囲に視野が限定されることがわかった。
DataTablesにはページング機能があり、デフォルトで10行ずつ表示するようになっている。この場合、データが10行を超えていると、最初の10行にしかボタンやイベントがつかないことになる。
色々試してみると、DataTablesでは内的に存在しているテーブルと、見えているテーブルの2つがあるらしいことがわかってきた。
内的なテーブルのうち、例えば10行ずつの表示ならば、最初の10行だけを切り取り、ブラウザに表示する。
apiを使わずにこちらの手が届くのは、見えているその10行のテーブルだけであり、それ以外の領域にアクセスしようとすると、DataTablesのapiを使わなければいけない。

DataTablesのapiには.draw()というメソッドがあり、apiで追加した行などはこれを実行しないと出力されない。
.draw()する前に、上記のようにイベントを設定したりしてみると、やはり追加された行には操作が適用されなかった。
これもどうやら、追加は内部的なテーブルに対してのみ行われ、.draw()を実行するとそれが表面にも反映され、こちらの手が届くようになる、という動作のように思える。

###5.解決策
公式を見ても解決方法が見つからなかったので、力押しで解決することにした。
この問題はDataTablesが適用されている限りつきまとうので、ajaxで表を更新するたび、表を消して作り直す、という方針。
tableタグをdivで囲い、データを抽出するたびにその子要素のtableタグを消し、新しくtableタグを作ってデータを入れ直す。最後にDataTablesを適用。
これなら自分のやりたいことが実現できた。
以下の成功例では、ajaxによる更新を行っていないが、ajaxの.done()の中のコールバックで上記のことをやればよい。

```html:成功例
<script>
$(function(){
	$('tbody td').click(function(){			//先にクリックイベントを付ける。今回はめんどくさいのでajaxによる更新はなし
		alert("行：" + ($(this).parent().index() +1) + ", 列：" + ($(this).index() + 1) + "");
	});
	$('#sales_table').DataTable();
})
</script>
</head>
<body>
<table id="sales_table">
	<thead>
		<tr><td>あ</td><td>い</td></tr>
	</thead>
	<tbody>
		<c:forEach var="v" items="${sales}" varStatus="st">
			<tr><td>${st.count }</td><td>${v }</td></tr>
		</c:forEach>
	</tbody>
</table>
</body>
```

apiを使ってスマートにやろうと思うとこういうドツボにはまる、ということをすでに2,3回経験している。
野蛮人みたいに、自分のできることでゴリ押しするという選択肢を、もっと上位に持ってきたほうがいいのかもしれない。

###6.まとめ
もっとスマートな方法があったら教えてください。
DBViewer Plugin for Eclipseのインストール方法

#概要
eclipse2019にDBViewerのインストールを行いたい！です。
私の認識ではバージョンOxgenまでeclipseのマーケットプレイスにDBViewerが存在していました。
しかし、2019verで検索をかけても表示されず困っておりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411353/f6b10657-2369-bf49-dc1e-aae5cd3df94a.png)




インストールしたいのに、、、
同じように躓いている方が多いと思いますので投稿します。


内容は下記リンクにある通りです。
https://symfoware.blog.fc2.com/blog-entry-808.html


##解決方法

eclipseエディタ上部「ヘルプ」-「新規ソフトウェアのインストール」をクリック
以下の画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411353/3ef79c4b-d2a5-dc8e-a7bb-32641b7daee2.png)
右上部、「追加」をクリック。



リポジトリの追加に
名前に「DBViewer UpdateSite」
ロケーションに「http://www.ne.jp/asahi/zigen/home/plugin/dbviewer/」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411353/bdabfb43-bc16-9a32-05a1-9b96cc172f3e.png)


あとは流れのままにインストールを完了させてください！！！


##終わりに

インストールの確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411353/7f8c3d82-5371-5e29-6f0a-1a74846482e0.png)

よしよし、やっと次に進めます

ご一読ありがとうございました。
GCE Ingressでhttps通信

# Ingressでhttps通信

## TL;DR
ドメインごとのgoogle managed 証明書を取得,Ingressに定義するところまで、
その過程ではまったポイントも少々記述しています

## Service, Deployment
ここはいろんな例があるので参考程度に

```deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: queen-gateway
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hogehoge
      tier: api
  template:
    metadata:
      labels:
        app: hogehoge
        tier: api
  spec:
    replicas: 1
    template:
      spec:
        containers:
          - name: api
            image: {docker_image}
            ports:
              - containerPort: 8080

```

```service.yaml
apiVersion: v1
kind: "Service"
metadata:
  name: "hogehoge-service"
  namespace: "default"
spec:
  type: "NodePort"　// NodePort or ClusterIP
  ports:
  - name: "http-port"
    protocol: "TCP"
    port: 8080
    targetPort: 8080
  selector:
    app: "hogehoge"
    tier: "api"

```

## Ingress

ingressを立ち上げるたびにIPが変わってはload balancingできないのでglobalIPを取得します
gcloudのcontextが対象のclusterであることを確認して

```shell
gcloud compute addresses create https-ip --global
```

google managed ssl certificateを取得します

```shell
gcloud beta compute ssl-certificates create https-cert \
    --domains ${YOUR_DOMAIN}
```

```ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hogehoge-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: https-ip # 取得したglobalIP
　　ingress.gcp.kubernetes.io/pre-shared-cert: https-cert # 取得した証明書
    kubernetes.io/ingress.allow-http: "false" # httpからのアクセス禁止
spec:
  backend:
    serviceName: hogehoge-service # serviceのmetadateのname
    servicePort: 8080 # serviceで指定したport
```

証明書,Ingress共に適用されるまでに少々時間がかかるので繋がらなくてやり直すのは少し間を置いた方が良いです

```shell
~  curl https://hogehoge.com/status
{"status":200}% 
```

## はまったポイント
### health check
コンテナのGET"/"が200を返すようにしておかないと、Ingressのトラフィックが正常にリクエストの処理ができないと判断し、
トラフィックが流されなくなります。
もしroot以外でhealth checkを行いたい場合は

```deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gateway
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hogehoge
      tier: api
  template:
    metadata:
      labels:
        app: hogehoge
        tier: api
  spec:
    replicas: 1
    template:
      spec:
        containers:
          - name: api
            image: {docker_image}
            readinessProbe:
            httpGet:
              path: /status #200を返すパス
              port: 80
            initialDelaySeconds: 5
            timeoutSeconds: 10
            ports:
              - containerPort: 8080
```
のようにすると良いでしょう
ちなみにk8sのhealth checkには２種類あります
https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/
今回はunhealthyなコンテナにはトラフィックを流さないreadinessProbeを使用しています


### サブドメインごとの証明書
調べてみたのですが、上記の証明書ではワイルドカードでの証明書取得ができないようです
よってドメインごとのIngress、証明書を定義して対応しています
もし良いやり方があれば教えていただけると助かります

## 参考資料
[公式 docs](https://kubernetes.io/docs/concepts/services-networking/ingress/)
[GKE でマネージド証明書を用いた https 通信を設定する](https://qiita.com/watiko/items/71d78a4d31eee02cb47d)
tesseractで文字認識

##環境
```.
Miniconda
python 3.7
windows
```

##tesseractの導入
バージョン4.0系からニューラルネットワークを採用し精度が向上しています。

ancondaにtesseractを入れる場合は、コマンドに以下を入力すればokです。
もし、anacondaを使っていて、できない場合は[こちら](https://anaconda.org/conda-forge/tesseract)を参考にしてください。

```
conda install -c conda-forge tesseract
```
anacondaを使ってない場合は、tesseractをインストールして、パスを通す。

ちゃんと使えるかは以下をコマンドに入力してください。
バージョンが返ってこればokです。

```.command
tesseract -v
>>tesseract 4.1.0
```

##言語追加
以下をコマンドに入力して、jpnがでなければ[こちら]からjpn.traineddataをダウンロードしてください。
jpn.traineddataを
```C:\Users\***\Miniconda3\envs\my_env\Library\bin\tessdata
```に置いてください。



```.commnad
tesseract --list-langs
```

```.
List of available languages (3):
eng
jpn
osd
```

↑のようになっていればokです。

日本語以外も追加可能です。

##PyOCRの導入

```terminal.
pip install pyocr
```

##実行してみる

```.py
from PIL import Image
import sys
import pyocr
import pyocr.builders

tools = pyocr.get_available_tools()
if len(tools) == 0:
    print("No OCR tool found")
    sys.exit(1)

tool = tools[0]

#言語、オプションの指定をする
txt = tool.image_to_string( 
    Image.open('IMG_5.png'),
    lang='jpn',
    builder=pyocr.builders.TextBuilder()
)
print(txt)
```

<img width="494" alt="2019-11-09 (1).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169545/4a272aa5-be03-0e7d-2879-656d13262f06.png">

```.
乃 木 坂 ④⑥・ 齋 藤 飛 鳥 の ①st 写 真 集 『 潮 騒 』 ( 幻 冬 舎 )
が 、 最 新 の ⑪/①① 付 オ リ コ ン 週 間 BOOK ラ ン キ ン グ ジ ャ
ン ル 別 ` 写 真 集 」 で ③④ 位 に ラ ン ク イ ン 。②0①⑦ 年 ① 月 の 発
売 か ら ② 年 ①0 ヶ 月 を 経 た 現 在 ち ラ ン キ ン グ 圏 内 を 推 移 。 好
調 な 乃 木 坂 ④⑥ メ ン バ ー の ソ ロ 写 真 集 の な か で も 数 少 な い
超 ロ ン グ ヒ ッ ト と な り 、 累 計 売 上 部 数 は ⑲.③ 万 部 を 超
え 、②0 万 部 目 前 ま で 迫 っ て い る 。

【 写 真 】 そ の 他 の 写 真 を 見 る

⑪/①① 付 の 同 ラ ン キ ン グ 内 を 見 る と 、 乃 木 坂 ④⑥ メ ン バ
ー の ソ ロ 写 真 集 の な か で 発 売 日 が ち っ と も 早 い の が 齋 膳
飛 鳥 の 『 潮 騒 』 と な り 、 次 い で ⑳①⑦ 年 ② 月 発 売 の 白 石 麻
衣 の 『 パ ス ポ ー ト 』 ( 講 談 社 ) 。 『 パ ス ポ ー ト 』 は 、 ジ
ヤ ン ル 別 ` 写 真 集 」 歴 代 ② 位 、 ソ ロ 写 真 集 と し て は 歴 代 ①
位 と な り 、 現 在 累 計 売 上 は ③③.⑥ 万 部 を 超 え て い る 。
```

数字の認識はいまいちですけど、他は高い確率で認識できていると思います。


##参考
[Python3系でtesseractを使ってOCRをやってみる](http://teru0rc4.hatenablog.com/entry/2017/08/09/230046)
[【PyOCR】画像から日本語の文字データを抽出する](https://qiita.com/mczkzk/items/393abc70836b9bde2f60)

間違いがありましたら、編集リクエストをお願いします。
duコマンド 容量の大きなファイル洗い出し

```shell:
$ du -d2 | sort | grep "\dG"
```

-d = 表示する階層の深さを指定する
sort = 数字の大きい順にソート
grep "\dG" = Giga Byte単位のファイルのみを表示(\dは任意の数字を表す正規表現

階層は1~2ぐらいに設定するのがオススメ。
Rails link_toメソッドについて

#link_toメソッドとは
引数を指定することで、リンクを生成してくれるメソッド
Railsではビューファイルで使用する。

ビューファイルのRubyタグ内で宣言することで
HTMLのaタグの様に使用することができる。

以下メソッド構造

~~~erb
<%= link_to 'リンクの文言', 'パス', class: 'クラス名', method: :HTTPリクエスト %>
~~~

methodを定義することで、リンクを踏んだ際のルーティング
を指定することができる。

以下使用例

~~~erb
<%= link_to '一覧へ', '/tweets', class: 'class' method: :get %>
~~~

上記の様に記述することで、HTMLのaタグと同じ扱いになる。
以下記述例

~~~html
<a class="class" href="/tweets">一覧へ</a>
~~~
Page Rankの近似推定

#前書き
本稿ではpage rankというアルゴリズムの大まかな概念と，行列演算を用いた近似推定について述べています．
また，最後にアルゴリズムをpythonで実装(20行程度)しています．

#Page rankとは
web pageにおけるrank付けを行うアルゴリズム
page rankによって定まるrankが高いほど検索時に上位になる
http://ja.wikipedia.org/wiki/ページランク

- リンクされている（他ページによってそのページヘのリンクがはられている) 場合，pagerankは加算される．
- 多くリンクされているページ（pagerankが高いページ）からのリンクのほうがpagerankはより加算される．
- 複数のページヘのリンクがある場合，すべてのページに対し同等のpagerankが加算される．

大体こんな感じ

#求め方
ここでは実際のweb pageのpagerankを求めるのではなく，用意したpage群(有向グラフ)におけるpagerankを求めます．

有向グラフの例
-存在するページ数：6
page1 → page3, page5
page2 → page3
page3 → page5, page6
page4 → page1
page5 → page2, page4, page6
page6 → page1

###隣接行列
まずグラフから隣接行列を考えます．
行に対し上からpage1, page2 ...　と考えたときの隣接行列は

```math
\begin{pmatrix}
0 & 0 & 1 & 0 & 1 & 0 \\
0 & 0 & 1 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 1 & 1 \\
1 & 0 & 0 & 0 & 0 & 0 \\
0 & 1 & 0 & 1 & 0 & 1 \\
1 & 0 & 0 & 0 & 0 & 0 \\
\end{pmatrix}
```
行が現在のpage, 列がつながっているpageを示しています．
どこへのリンク（すなわち隣接しているか）がわかるようになっています
例えば5行目なら page5はpage2,4,6へのリンクがあると読み取ることができます．

###遷移確率行列
次にこれを遷移確率行列にします．
まず一度転置します(ホントは最初から転置したものを考えるとか効率いい考えがあります）

```math
\begin{pmatrix}
0 & 0 & 0 & 1 & 0 & 1 \\
0 & 0 & 0 & 0 & 1 & 0 \\
1 & 1 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 1 & 0 \\
1 & 0 & 1 & 0 & 0 & 0 \\
0 & 0 & 1 & 0 & 1 & 0 \\
\end{pmatrix}
```

転置したものを列ごとに見て，列ごとの総和が1になるようにします．

```math
\begin{pmatrix}
0 & 0 & 0 & 1 & 0 & 1 \\
0 & 0 & 0 & 0 & 1/3 & 0 \\
1/2 & 1 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 1/3 & 0 \\
1/2 & 0 & 1/2 & 0 & 0 & 0 \\
0 & 0 & 1/2 & 0 & 1/3 & 0 \\
\end{pmatrix}
```
まず転置したので，列は現在のpage, 行はつながっているpageを示しています．
あるページにn個のpageへのリンクがある場合，すべてのpageに同等のpagerankを与える　
→　それぞれのpageへ移動する確率が 1/n
と考え，列ごとの総和が1になるようにしています．

要するにpage1にいるときpage3に遷移する確率は1/2, page5に遷移する確率は1/2
と考えています．

###ランダムウォーク
後は遷移確立行列に従って，n回後の存在確率を計算します．
このnが大きければ大きくなるほど答えが収束していくため，近似的にpageのrankを求めることができます．

まず初期ベクトルを与えます

```math
\begin{pmatrix}
0 \\ 
1 \\
0 \\
0 \\
0 \\
0\\
\end{pmatrix}
```

これはどこに1があってもいいです
要するに最初にどのpageにいるかということです．

後は先ほどの遷移確立行列とこの初期ベクトルの内積をとれば，現在の存在確率の行列(なんて呼ぶのかしらない）が出ます．
さらにそこに遷移確率行列をかけていくことできます．

```math
\begin{pmatrix}
0 \\ 
1 \\
0 \\
0 \\
0 \\
0\\
\end{pmatrix}
\begin{pmatrix}
0 & 0 & 0 & 1 & 0 & 1 \\
0 & 0 & 0 & 0 & 1/3 & 0 \\
1/2 & 1 & 0 & 0 & 0 & 0 \\
0 & 0 & 0 & 0 & 1/3 & 0 \\
1/2 & 0 & 1/2 & 0 & 0 & 0 \\
0 & 0 & 1/2 & 0 & 1/3 & 0 \\
\end{pmatrix}
```

#ソースコード
最後にpython(多分2.7)での実装例を書いておきます．

```pagerank.py
import numpy as np
import time

x = np.array([
[0, 0, 1, 0, 1, 0],                                                                              
[0, 0, 1, 0, 0, 0], 
[0, 0, 0, 0, 1, 1], 
[1, 0, 0, 0, 0, 0], 
[0, 1, 0, 1, 0, 1], 
[1, 0, 0, 0, 0, 0]],
dtype=float)
pagenum = 1 
pagerank = 30
rank = np.array([[0],[1],[0],[0],[0],[0]])

x_m = x.T/x.T.sum(axis=0)

for i in range(100000):
    rank = np.dot(x_m, rank)

print(x)
print(np.round(rank * pagerank/rank[pagenum - 1],2))
```

xの変数定義では隣接行列を書きます．
また，この手法ではpage間のrank比率が出るのみなので，実際には基準となるrankが分かっている必要があります．
よって
pagenumに基準となるpageの番号
pagerankにpagenumのrankを書いて
後は動かせば終わりです．

10万回内積をとっていますが自分の環境では計算時間は400ms程度でした．
rails クエリを使って集計しcsvをexport

formatをcsvにする（ブラウザからcsvを要求する）には
linkのurlの拡張子をcsvにする必要あり

## フォーム

```slim:form.slim
.form
  = form_tag 'output_csv.csv', method: :post do
    .form-group
      .mt10
        = datetime_select :csv, :start_at
      .mt10
        = datetime_select :csv, :finish_at
      .mt20.center
        = submit_tag "Output CSV", class: 'btn btn-primary'
```

## コントローラ

```ruby:chat_csvs_controller.rb
def output_csv
  start_at = datetime_params(params,'start_at')
  finish_at = datetime_params(params,'finish_at')
  csv_name = "chatbot#{start_at.strftime("%m/%d/%y")}to#{finish_at.strftime("%m/%d/%y")}.csv"
  @chats = Chat.count_desc(start_at,finish_at)
  respond_to do |format|
    format.csv do
      send_data render_to_string, filename: csv_name, type: :csv
    end
  end
end
```

## モデル

```ruby:chat.rb
class Chat < ActiveRecord::Base
  scope :count_desc, -> start_at, finish_at {
    Chat.select(:message,:created_at).where(created_at: start_at..finish_at).order('count_message desc').group(:message).count(:message)
  }
end
```

## ビュー

```ruby:output_csv.csv.ruby
require 'csv'
CSV.generate do |csv|
  column_names = %w(message count)
  csv << column_names
  @chats.each do |chat|
    csv_column_values = [
      chat[0],
      chat[1]
    ]
    csv << csv_column_values
  end
end
```
LeetCode / Count and Say

（[ブログ記事](https://mhiro216.hatenablog.com/entry/2019/07/20/151659)からの転載）

[https://leetcode.com/problems/count-and-say/]

The count-and-say sequence is the sequence of integers with the first five terms as following:

1.     1
2.     11
3.     21
4.     1211
5.     111221

1 is read off as "one 1" or 11.
11 is read off as "two 1s" or 21.
21 is read off as "one 2, then one 1" or 1211.

Given an integer n where 1 ≤ n ≤ 30, generate the nth term of the count-and-say sequence.

Note: Each term of the sequence of integers will be represented as a string. 

Example 1:
Input: 1
Output: "1"

Example 2:
Input: 4
Output: "1211"

Bad評価が多い問題、、、確かに問題の意味が分かりにくいですね。日本語で補足すると以下のようになります。

1.     1 -> 初期値は1
2.     11 -> 前のステップの値が、1つの1から成るので、11
3.     21 -> 前のステップの値が、2つの1から成るので、21
4.     1211 -> 前のステップの値が、1つの2、1つの1から成るので、1211
5.     111221 -> 前のステップの値が、1つの1、1つの2、2つの1から成るので、111221

#### 解答・解説

##### 解法1
この問題は、地道にループを回す解法しかないのではないかと思います。以下の通り。

```python
class Solution:
    def countAndSay(self, n: int) -> str:
        s = '1'
        # n-1回のループを回し、各ステップの出力を次のステップの入力とする
        for _ in range(n-1):
            # letがカウントする文字、cntがカウント数、tmpが(カウント数+カウントする文字)の文字列を一時的に格納する変数
            let, cnt, tmp = s[0], 0, ''
            # 文字列sの文字数分のループを回す
            for l in s:
                # 同じ文字が続いている場合はcntに+1するのみ
                if let == l:
                    cnt += 1
                # 異なる文字が来た場合はここまでの(カウント数+カウントする文字)をtmpに格納してlet,cntは初期化する
                else:
                    tmp += str(cnt)+let
                    let = l
                    cnt = 1
            tmp += str(cnt)+let
            s = tmp
        return s
```

##### 解法2
Pythonであれば、組み込み関数が充実しているので他にも様々な解法があります。
例えば、itertoolsというiterableなデータ（リストなど）を任意のキーでグルーピングし、キーとキーに属する要素のイテレータを返す関数を使う方法。
itertoolsの挙動の例は、以下の通り。

```python
s = '1211'
for d,i in itertools.groupby(s):
    print(d, list(i))
# ---> 1 ['1']
# ---> 2 ['2']
# ---> 1 ['1', '1']
```

これを使うと、以下のように書けます。

```python
class Solution:
    def countAndSay(self, n):
        s = '1'
        for _ in range(n - 1):
            s = ''.join(str(len(list(group))) + digit for digit, group in itertools.groupby(s))
        return s
    return s
```
elm パイプとmaybe繋ぐ使い方

```elm:hoge.elm
timeZone
    |> TimeZones.fromName
    |> Maybe.withDefault (TimeZones.asia_tokyo ())
```

2行目でmaybeを返す関数を`timeZone`に適用
返り値が`Nothing`であれば3行目でデフォルト値`TimeZones.asia_tokyo ()`が返る
`Just xx`ならばxxが返る

パターンマッチよりスッキリかける印象
SwiftのViewをグラデーション(gradation)(優良記事まとめ)

# 概要
SwiftでViewをグラデーションするのは２通り
####`IBDesignable`でカスタムクラス作って**Storyboardで設定いじいじ**
**※透明度まで考慮してgradationを考える際の注意点**
ex. `透明→黒`というgradationを作成する場合
`Top Color`: `Clear`
`Bottom Color`: `Black`
→gradationがおかしくなる(透明度だけでなく**rgbも差異が生じていてgradationしてしまう**)
`Top Color`: `Black`かつ`Opacity 0%`
`Bottom Color`: `Black`
→これならrgbが一致した状態で透明度のみgradationしてくれる

#### シンプルにカスタムクラス作って**コード側でパラメータいじいじ**

# IBDesignableでカスタムクラス
**・[Swift IBDesignable入門 - Qiita](https://qiita.com/ShoichiKuraoka/items/228b9e3fc4f886f94f16)**
**・[@IBDesignableをハックしてコードでの設定をRunせず確認する - Qiita](https://qiita.com/yutat93/items/4a0e053245fe92b3936a)**
→上記2つは基本からきちんと理解できます
**・[IBDesignableがウザい - Qiita](https://qiita.com/alt_yamamoto/items/834be6e978fbc31ec364)**
→デメリットがサクッとまとまってます

# シンプルにカスタムクラス
2つとも似たような感じ。

**・[Swiftで背景にグラデーションを設定する - Qiita](https://qiita.com/Gutenberg0x/items/ac737fb3305da3389bf9)**
→簡単なコードと使い方が載ってます(↓はコメント省いたやつ)

```simpleCustomClassView.swift
let topColor = UIColor(red:0.07, green:0.13, blue:0.26, alpha:1)
let bottomColor = UIColor(red:0.54, green:0.74, blue:0.74, alpha:1)
let gradientColors: [CGColor] = [topColor.CGColor, bottomColor.CGColor]
let gradientLayer: CAGradientLayer = CAGradientLayer()
gradientLayer.colors = gradientColors
gradientLayer.frame = self.view.bounds
self.view.layer.insertSublayer(gradientLayer, atIndex: 0)
```
**・[ios - Programmatically create a UIView with color gradient - Stack Overflow](https://stackoverflow.com/questions/23074539/programmatically-create-a-uiview-with-color-gradient)**
↓一番参考になりそうなやつ？(Swift3.0らしいし)

```swift
var gradientView = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 35))
 let gradientLayer:CAGradientLayer = CAGradientLayer()
 gradientLayer.frame.size = self.gradientView.frame.size
 gradientLayer.colors = 
 [UIColor.white.cgColor,UIColor.red.withAlphaComponent(1).cgColor] 
 gradientView.layer.addSublayer(gradientLayer)
 gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
 gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
```

# 制約(AutoLayoutとか入ってるとき)
上記のように`subLayer`を用いたやり方だと対象Viewが`AutoLayout`で配置されていて幅や高さが決定していない状態だとgradationがおかしくなったりするらしい

```swift
override public class var layerClass: Swift.AnyClass {
    get {
        return CAGradientLayer.self
    }
}
```
`View`の`layer`ごと`CALayer`→`CAGradientLayer`にすると`AutoLayout`にも対応してくれるみたいです

# 他参考記事
**・[swiftでグラデーションがかかったViewを作成する[CAGradientLayer][swift3.0] - MILLEN BOX](https://anthrgrnwrld.hatenablog.com/entry/2016/09/23/201221)**
→少しややこしめVer.
**・[Swift UIViewの背景をグラデーションさせる方法　-iPhoneアプリ開発-](https://techno-monkey.com/swift-uiview-gradation-iphoneapp/)**
**・[[Swift]グラデーション設定できるViewとかなんとか｜杏z 学習帳（旧）](https://anz-note.tumblr.com/post/165116877836/swift%E3%82%B0%E3%83%A9%E3%83%87%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E8%A8%AD%E5%AE%9A%E3%81%A7%E3%81%8D%E3%82%8Bview%E3%81%A8%E3%81%8B%E3%81%AA%E3%82%93%E3%81%A8%E3%81%8B)**
Pythonのlistをslideしながらwindow幅で切り出す

タイトルが雑でごめんなさい。

以下のようにPythonのリストをslide幅でずらしながらwindow幅で切り出す方法です。
<img width="563" alt="リストをwindow幅でslideずつずらす.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392425/216fb807-4d4f-0210-0dd4-24fef81cb74d.png">
機械学習などでよく使う割に忘れやすいのでメモしておきます。


## 実装
~~~python
>>> s = 3 #slide
>>> w = 5 #window

>>> array = list(range(10))
>>> [array[i:i+w] for i in range(0,len(array)-w+s,s)]
[[0, 1, 2, 3, 4], [3, 4, 5, 6, 7], [6, 7, 8, 9]]

>>> array = list(range(11))
>>> [array[i:i+w] for i in range(0,len(array)-w+s,s)]
[[0, 1, 2, 3, 4], [3, 4, 5, 6, 7], [6, 7, 8, 9, 10]]

>>> array = list(range(12))
>>> [array[i:i+w] for i in range(0,len(array)-w+s,s)]
[[0, 1, 2, 3, 4], [3, 4, 5, 6, 7], [6, 7, 8, 9, 10], [9, 10, 11]]
~~~

## more_itertools.windowedでも可能
([LouiS0616](https://qiita.com/LouiS0616)さんにコメントで教えていただきました。 ありがとうございます。)  
pipでのインストールが必要。

~~~bash
pip install more_itertools
~~~

以下のように第二引数がwindow幅、stepがslide幅に対応している。

~~~python
>>> import more_itertools
>>> array = list(range(12))
>>> list(more_itertools.windowed(array,5,step = 3))
[(0, 1, 2, 3, 4), (3, 4, 5, 6, 7), (6, 7, 8, 9, 10), (9, 10, 11, None, None)]
~~~

こんな便利な関数があったとは驚き。


以上。
【Rails】RailsでjQueryを使う方法とJavaScriptの実行順序はめちゃ大事だという話

この記事では、Rails.5.2でのjQueryの導入方法とJavaScriptの実行順序に関して、自分なりに色々調べてわかったことを備忘録として記事にしました。


# Rails5.2でjQueryを使う方法
@ngronさんのこちらの記事をかなり参考にさせていただきました。
[RailsでjQueryを使えるようにする方法](https://qiita.com/ngron/items/95846bd630a723e00038)
##Gemの追加
Railsプロジェクトフォルダ直下のGemfileに以下の記述を追加します。

```Gemfile
gem 'jquery-rails'
```

記述したら`bundle install`実行でプロジェクトにjQueryのgemがインストールされます。
インストールが成功していれば、Gemfile.lockに`jquery-rails`の記述があるかと思います。

##application.jsに追記
/app/assets/javascripts/application.jsにjQueryを読み込むためのコードを追記します。

```application.js
//= require jquery
//= require jquery_ujs
```

で、ここが重要なんですが、**上記のコードは`//= require_tree .`より上に追記してください。**
理由は後述します。

##サーバを再起動
`rails s`でサーバをしていた場合は再起動してください。

#導入完了
以上でjQueryの導入は完了しました。`/app/assets/javascripts`フォルダ内にjsファイルを作るか、viewにスクリプトを直書きすれば動作確認ができるかと思います。
Turbolinksが導入されている場合、JavaScriptが正常に動かない場合があります。その場合は@hiroyayamamoさんの[こちらの記事](https://qiita.com/hiroyayamamo/items/b258acbaa089d9482c8a)をご覧ください。

#JavaScriptの実行順序に関して
先ほどapplication.jsで

```application.js
//= require jquery
//= require jquery_ujs
```

は`//= require_tree .`より上に追記してくださいと説明しました。
下に追記した場合、以下のエラーが出ることがあります。

```
Uncaught ReferenceError: $ is not defined
```

これは「$なんて定義されてねーよ」というエラーなんですが、**「いや、jQuery読み込んでるし！」**と半日ぐらいハマっていました。
@okknさんの[こちらの記事](https://qiita.com/okkn/items/18c3f617c6fc34cdb6a2)によるとscriptタグの読み込みには順番があるらしく、jQueryのコードがjQueryの読み込みより早いと「$なんて定義されてねーよ」とエラーが出るようです。

`//= require_tree .`は指定されたパス(ここでは「.」なのでapplication.jsが配置されているディレクトリ)配下のjsファイルを出力に含めるものです。当然`/app/assets/javascripts`フォルダ内のjsファイルも出力に含まれます。

なので

```application.js
//= require_tree .
//= require jquery
//= require jquery_ujs
```

こんな風に書いちゃうと、jQueryを読み込む前に自分がせっせと作ったjsファイルが読み込まれ、先ほどのエラーが出てしまうようです。

これは別のファイルにjQueryのコードを書いた時に起きるので、viewにjQueryを直書きした場合にはエラーは起こりません。(レイアウトのjavascript_include_tagメソッドより上に書いたら起きますが)

#まとめ
C#だと実行する行よりも後に、クラスなりメソッドを書いても問題ないのでそのノリでいったらハマってしまいました。
自分で書いたjsファイルを読み込む時は、スクリプトが読み込まれる順序に気をつけましょう。
[css] どれだけスクロールしても常に画面いっぱいに表示

モーダルの背景とかによく使う

```css:hoge.css
.target-class {
  position: fixed;
  height: 100vh;
  width: 100vw;
  z-index: 350;
  top: 0;
  left: 0;
}
```

position: fixed = 画面上の任意の位置に固定
vh(view height)  = 画面の縦幅、100vhで縦幅いっぱい
vw(view width) = 画面の横幅、100vwで横幅いっぱい
z-index = 重なりの優先順位、前面に出したいなら相対的に大きな値にする
top: 0 = 画面上にくっつける
left : 0 = 画面左にくっつける
プログラミング初心者の備忘録ーCSS編

# はじめに
[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているMaomao Maoです。

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

今回は、progate初級CSS編での学びをまとめようと思います。

## CSSについて
CSSは、__色、大きさ、配置__などを指定し、デザインする言語です。
CSSは、HTMLとは別のファイルに記述します。

<p>・色を変える（color）</p>
色を変えたい場合、カラーコードを指定しなければなりません。
（主要の色であれば、色名で指定できる場合もあります。）
__文尾には、コロン__
__文末にはセミコロン__
覚えておきましょう。

```css
HTML
<h1>テキスト</h1>

CSS
h1{
 color: red;
}
```

<p>・文字の大きさを変える（font-size）</p>

```css
HTML
<h1>テキスト</h1>

CSS
h1{
 font-size:10px;
}
```

<p>・文字の種類を変える（font-family）</p>

```css
HTML
<h1>テキスト</h1>

CSS
h1{
 font-family:serif;
}
```

<p>・背景を変える（background-color）</p>

```css
HTML
<h1>テキスト</h1>

CSS
h1{
 background-color:red;
}
```

<p>・横幅、高さを変える（width,height）</p>

```css
HTML
<h1>テキスト</h1>

CSS
h1{
 width:50px;
 height:60px;
}
```
登壇スライドの作成に便利なTwemojiキーボードを作った

# tl;dr
- Apple絵文字のライセンス周りがアレなので登壇スライドにTwemojiを使っていたが、けっこう面倒だった。
- Macの絵文字キーボードみたいなのをElectronで適当に作った。
- https://github.com/tinoji/twemoji-image-picker


# 絵文字ライセンス問題
みなさん、絵文字(emoji)使ってますか〜〜？絵文字はウォシュレットに次ぐ日本の大発明ですよね:wink:

最近はイベントや勉強会に登壇させてもらう機会が増えてきたんですが、スライドに絵文字を使うと、簡単にポップな雰囲気を醸し出せるのでめっちゃ重宝しています。これまでは何も気にせずMacの絵文字キーボードを使ってApple Color EmojiをKeynoteにぺちぺち貼ってました。これね:point_down:
<img width="366" alt="Screen Shot 2019-07-20 at 14.25.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130232/7b174dd0-a219-3ac4-1f62-b9f86ea11960.png">

しかし去年、こちらの記事↓を見てからは、登壇で使ったり公開する資料には必ず[Twemoji](https://github.com/twitter/twemoji)を使っています。
[「絵文字」の利用で気をつけた方が良いこと、安全な使い方について](https://note.mu/ajalaca/n/ne6a18feb4ca5)

一言でまとめると「多くの絵文字には著作権や使用ルールがあり、実はそんなに気軽に使えるものではない」みたいな話です。一方、Twemojiは[CC-BY 4.0]( https://creativecommons.org/licenses/by/4.0/)なので、[適切なクレジット表示](https://wiki.creativecommons.org/wiki/License_Versions#Detailed_attribution_comparison_chart)を行えば再配布・改変などが可能です。最高。


# TwemojiをKeynote/Powerpointで使うのが面倒
ただ、Twemojiをデスクトップで画像やフォントとしてサクッと使えるサービスやアプリが見つけられなくて、基本的に[Emojipedia](https://emojipedia.org/)からポチポチ検索してコピペしてました:innocent:
(ガーッと草稿を作る際にはAppleの絵文字を使っておいて、公開する前にTwemojiの画像に置き換えるという作業・・・。置き換え漏れがそこそこ発生して良くない。)

https://github.com/eosrei/twemoji-color-font
これとかめっちゃいいかもと思ったんですが、使えませんでした(おそらくブラウザで見たときのみに対応？)。


# 作った
で、さすがにそれが嫌になったので、Electronで適当に作りました。なぜかTwemojiで変換できないものがあってサロゲートペアな絵文字の対応を諦めたり、ElectronのバグのせいでWindowsのクリップボードで透過PNGが使えなかったり、と色々アレですが、自分のユースケースは完全に満たせたのでオッケー:v:ただ、Windows版がたびたび動かないので誰か直してください:pray:

https://github.com/tinoji/twemoji-image-picker

見た目はこんな感じ。完全にパクリです。
<img width="414" alt="Screen Shot 2019-07-20 at 14.37.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130232/3a50bf7d-a703-95ba-0a0b-79d8f4a7d732.png">

# デモ
![61218291-ab038b00-a74c-11e9-853d-b3064ef81d22.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130232/5a3704ec-2ea5-6b64-846d-77299c081e24.gif)
cssの開発効率を爆アゲ♂するsimple-debug.cssプラグイン

## こういうものがあります
before
<img width="1143" alt="Screen Shot 2019-07-20 at 14.55.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170241/bda9fbea-2780-3090-9ff1-a54d0ee0def2.png">

after
<img width="1165" alt="Screen Shot 2019-07-20 at 13.57.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170241/d66097a0-be9f-257e-95dc-93bce06cf7c2.png">

そう、これが街談巷説道聴塗説、もとい巷で有名なsimple-debug.cssプラグインです

marginとかpaddingとかいちいちdeveloper-toolsを開いてカーソルを乗せて確認するの面倒ですよね

simple-debug.cssを導入するとそんな悩みも一網打尽、霧散霧消、五里霧中です

## 使い方

chromeのextentionストアからinstallできます
https://chrome.google.com/webstore/detail/simple-debugcss/jlkgkebpphmaiemciejnmgccejccnpha

追加すると右上にアイコンが表示されます

こいつを実行したいページでクリックするだけです

戻したいときにはもう一度クリックしてください

<img width="425" alt="Screen Shot 2019-07-20 at 14.31.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170241/d4e88643-e150-4930-239e-996084f12ebb.png">

## 活用方法

simple-debug.cssを適用した状態でdeveloper-toolsを開き、cssを調整すると開発がとっても楽になります

<img width="1440" alt="Screen Shot 2019-07-20 at 14.26.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170241/5ef5af6d-bddf-eff7-3699-9b9d321ac7e8.png">


他にもcss-debug系のプラグインはあるので探してみてくださいね、僕はこれがsimpleかつオシャンティで気に入っています

## 参考

https://scrimba.com/p/pV5eHk/c4EMaUR
vi vim コマンド

.bashrcのファイルを編集する機会があったので､

(↓がしたくて
https://qiita.com/lemtosh469/items/334ff76366e054a3a3aa)

vimコマンドの使い方で教えてもらった内容メモ
vimは慣れるまで少し時間がかかるとのこと｡

####はじめに
ターミナルで
`$vi`でvimに入れる｡
または
`$vi ファイル名`でファイルを指定して入れる｡

★実践 ｢.bashrcのファイルを編集したい｣★
`$vi ~/.` この状態でタブkey2回押すと､リストが表示される｡
そこから補完していくのを推奨｡
タイポ減らせる｡

####コマンドモード
便利キー
`i` 入力モードへ(カーソルがある場所で)
`o`1行下に改行して入力モードへ
`a`1文字ずらして入力モードへ

####入力モード
入力できる状態のこと
`--INSERT--`を表示されている時､入力モードです｡

コピペで編集｡

`esc`でコマンドモードへ戻る

####コマンドモード終了したい
`:q`保存せず終了
`:w`上書き保存のみ
`:wq`上書き保存して終了


おわり｡
React+AppsyncのSubscriptionを実装する（その1）

<h1>はじめに</h1>
AppsyncのSubscriptionを使って、チャットアプリを作ろうと色々と調査しましたが中々見つからず。色々と参考に、Appsyncのサブスクリブションを実装してみましたのでその備忘録です。

AppSyncとGraphQLはすごく便利で、慣れれば短時間でデータベース＋APIを簡単に実装することができます。長くなりそうなので2回に分けてお届けします。

その1.APIの設定、GraphQLのテスト
その2.Reactプロジェクトの立ち上げと実装

<h1>今回の流れ</h1>
1.Appsyncの設定
↓
2.Schema,Resolverの定義
（Resolverの設定は、AppSyncが自動でしてくれるので飛ばします。)
↓
3.DateBaseの作成
↓
4.GraphQLのテスト

<h1>AppSync設定</h1>
AWSコンソールにまずログインして、Appsyncを立ち上げます。



CreateAPIをクリック。


<h1>GraphQLの定義</h1>
メニューバーの```Schema```をクリックします。

```appsync:GraphQL
type Post{
 id:ID!
 title:String
 content:String
}
type Query{
 getPosts:[Post]
}
schema{
 query:Query
} 
```
まずはPostの型を定義します。```ID```,```String```はGraphQLに用意されている型です。```!```は必須という意味がありますので必須項目にはつけるようにしましょう。今回はidを必須にしてあります。
次に```Type Post```に対するQueryを登録します。Queryという名前のルート型に、今回は、getPostsとしてPostをオブジェクトごと配列にして渡しています。
最後にQueryをSchemaに登録して完了です。

<h1>データベースの設定</h1>
Schemaページ内にある```Create Resources```をクリックします。
「Define or select a type」は「Use existing type」を、
「Select a type」は「Post」を選択します。
TableNameが「PostTable」に変わったのを確認し、『Automatically generate GraphQL』をONにして、一番下の「Create」をクリック。
そうするとAppsyncがQueryとResolverを自動で設定し、DynamoDBにデータベースを作成してくれます。
※DynamoDBの「PostTest」の項目をチェックするとidしか登録されていませんが操作すると、自動で項目が追加されるようになっていますので、安心して次のGraphQLのテストへと進んでください。

<h1>GraphQLのテスト</h1>
<h2>CreatePostのテスト</h2>

```Appsync:createPost
mutation{
 createPost(input:{
  title:"MutationTest"
　content:"Queriesから投稿"
 }){
　　id
　　title
　　content
　}
}
```
<h2>updatePostのテスト</h2>
```Appsync:updatePost
mutation{
 updatePost(input:{
　id:""(先ほどのcreatePostのidを入力）
  title:"MutationTest１"
　content:"Queriesから投稿"
 }){
　　id
　　title
　　content
　}
}
```
<h2>getPostsのテスト</h2>
事前にcreatePostで何件か追加してください。

```Appsync:getPosts
query{
getPosts{
 id
 title
 content
 }
}
```

<h2>listPostsのテスト</h2>
```Appsync:listPosts
query{
 listPosts{
  items{
   id
   title
   content
  }
 }
}
```

<h1>詰まったところ</h1>
<h3>リゾルバ設定＆GraphQLテスト</h3>
2018/07/19からほとんど自動でGraphQLスキーマの作成と、リゾルバが設定されるようになっています。自動で設定してくれるのはすごく便利です。最初、他のサイトを参考にさせていただいていたのですが、createPostからinput　CreatePostに値を渡さないといけなかったのでなかなかうまくテストできず泣きました。テストが上手くいかないときはSchemaページ内にあるResolverをいじる必要があります。Resolverについては次の機会に。

参考
https://aws.amazon.com/jp/about-aws/whats-new/2018/07/aws-appsync-releases-enhanced-capabilities-nocode-graphql/
enrich my libraryパターンでZonedDateTimeをリッチにする


# はじめに
scalaのimplicit classを使ったenrich my libraryパターンでZonedDateTimeを便利に使おうという話です。

## 環境

scala 2.10 以上(implicit classが使えるのが2.10から)

## 時刻情報を扱うのがめんどくさい

めんどくさくないですか？

java8からjava.timeパッケージが入って色々楽になったものの、まだめんどくさいです。

私が関わっているサービスでは、年月日でパーティションを切っているDBテーブルがあり、ZoneDateTimeからyyyyMMdd形式の数値(20190101とか20191231とか)を取り出したい場面が頻繁にあります。

そういうとき、以下のような処理が必要になります。

``` scala
val now = ZonedDateTime.now() //とりあえず現在時刻
val formatter = DateTimeFormatter.ofPattern("yyyyMMdd")
val yyyyMMdd = now.format(formatter).toInt
```

DateTimeFormatterのインスタンスはスレッドセーフなので、どこかに定数として定義しておけばいいので、実質的には

> now.format(formatter).toInt

の1行にできるんですが。。。。

> now.yyyyMMdd.toInt

というふうにZonedDateTimeにメソッドが生えててほしくないですか？

**生えててほしくないですか！！！？！？！？**

それができるんです。

そう、Scalaならね。


## implicit classでZonedDateTimeを便利に拡張しよう

implicit classというのは、既存クラスを拡張できる仕組みです。

詳しくは[ドワンゴ新卒研修資料](https://dwango.github.io/scala_text/implicit.html#implicit-conversion%EF%BC%88%E6%9A%97%E9%BB%99%E3%81%AE%E5%9E%8B%E5%A4%89%E6%8F%9B%EF%BC%89%E3%81%A8implicit-parameter%EF%BC%88%E6%9A%97%E9%BB%99%E3%81%AE%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%EF%BC%89)のimplicitについての解説を参照するか、ググるかしてください。

以下のようなクラスを作ります

``` scala
implicit class RichZonedDateTime(val self: ZonedDateTime) extends AnyVal {
    private val yyyyMMddFormatter = DateTimeFormatter.ofPattern("yyyyMMdd")
    def yyyyMMdd: Int = {
        self.format(yyyyMMddFormatter).toInt
    }
}
```

クラス名はなんでもいいのですが、拡張元のクラスの接頭辞にRichとつけるのが単純でいいかと思います。(ググって出てくるのは大体それ)

selfの型には拡張したいクラスを指定します。

上記のクラスがスコープ内にある状態だと、以下のようにZonedDateTimeのインスタンスから(ソースコード上は)直接yyyyMMddメソッドを叩けるようになります

``` scala
val now = ZonedDateTime.now()
now.yyyyMMdd
```

yyyyMMddメソッドを叩いたタイミングで暗黙的にRichZonedDateTimeに変換されるという認識です。(あってるよね？)


今回のケースはシンプルですが、取り出しに複雑な処理が必要になるものをimplicit classのメソッドとして定義すると、便利に使えると思います。(月の最終日を取得するとか)


## 感想

デザインパターンの使い所あるあるパターン集みたいな本が欲しいです。

最近アンクルおじさんのClean Architecture本読んでるんですが(まだ半分)Interface(または各言語のそれに準ずる機能)の使い所の理解が深まりました。

JavaだとInterfaceの利用は避けては通れない感じがあるんですが、大学で最初に触ったときは、「なんで間にこんな何層も挟まるんだ？」と思いましたからね。
Go言語で日本語フォーマットをpdf出力

自分が過去に書いたテックブログの中で記載している内容なのですが、当時はシステム全体の話だったので、今回はpdf出力の部分にフォーカスして記事にしてみました。

過去のテックブログは以下から飛べます。

[Go言語でケアラベル発行の自動化](https://techblog.zozo.com/entry/2019/01/24/100305)

当時まだGo書き始めたばかりで、変な記述もあるかと思いますがご了承ください...

# gopdfについて

同じようにGo言語でpdf出力ができるライブラリとして、[gofpdf](https://github.com/jung-kurt/gofpdf)があります。
しかし、日本語出力することが難しいため、[gopdf](https://github.com/signintech/gopdf)を使っています。

## 基本的な使い方

### pdfページ作成

A4サイズで出力したい場合

```Go
pdf := gopdf.GoPdf{}
pdf.Start(gopdf.Config{ PageSize: gopdf.PageSizeA4 })
pdf.AddPage()
```

サイズを自分で定義したい場合

```Go
pdf := gopdf.GoPdf{}

// rect作成
rect := gopdf.Rect{}
rect.W = "pdfの幅"
rect.H = "pdfの長さ"

// サイズを代入
config := gopdf.Config{}
config.PageSize = rect

pdf.Start(config)
```

自分でサイズを定義する場合は、gopdf内で定義されているA4のサイズから逆算したり、フォントサイズと比較しながら定義したりしていました。

自分が作ったシステムの中では、pdfを動的に出力する必要があったため、エクセルから抽出した文字配列の数を数え、1行分の高さでかけることをしていました。力業というかアナログというか....

### フォントをインプット

フォントファイルは、商用利用可能な[Google Fonts](https://fonts.google.com/)のフォントを使いました。

```Go
// フォントのファイルを読み込む
fontPath := string("フォントファイルのパス")
// フォントを設定
pdf.AddTTFFont("フォントの名前", fontPath)
// フォントサイズを設定（例：１０）
pdf.SetFont("フォントの名前", 10)
```

最近otfファイルの対応もし始めたみたいですが、自分が使いたかったotfファイルのフォントを読み込んだところエラーになりました。
フォントの種類にもよるかもしれないです。

### 文字出力
**SetX**と**SetY**を出力する前に必ずおこなってください

```Go
// 座標を設定
pdf.SetX("pdfのX座標")
pdf.SetY("pdfのY座標")
// 出力
pdf.Cell(nil, "任意のテキスト")
```

### 画像出力

```Go
// 画像の場所
inputPath = "画像のパス"

// 出力
size := gopdf.Rect{
    H:"画像の高さ",
    W:"画像の幅",
}
pdf.Image(inputPath, "pdfのX座標", "pdfのY座標", &size)
```

### 改行

改行といってもただ座標を下にずらしているだけです

```Go
// 改行
pdf.SetX("前回ののX座標" + "下にずらしたい分のサイズ")
```

## 苦労した点

実際にデザインとして完璧に出力しようとすると、以下の様な所で躓きました。

- 長い説明書きだと文書的に変なところで改行されてしまうことがある
- 事前にどんな文章が入るか分からないため、改行した文の始めに空白が入ってしまい端がそろわないケースが出てくる
- 上記に対応しようとすると右端が揃わないケースが出てくる
- 洋フォントでは各文字、記号のサイズが違い、右端を揃えるのが困難（揃っているように見えてちょっとずれていることも...）

機械的にデザインを出力するってことは難しいですね...

# 最後に

基本的な記述は以上で説明した内容でできると思います。
次回はエクセルの読込み部分を解説していきたいと思います。
Micro:bitのボタンのOn/Offスイッチ動作

Microbitでロボットなどを操作する際に、ボタンの数が足りなくなることがあります。

例えば、Aボタンを押してモーターをスタート、Bボタンを押してモータをストップ。この場合2つのボタンが必要になります。
Aボタンを押してスタート、もう一度Aボタンを押すとストップというような、スイッチ機能があると使用するボタンの数も減らすことができます。

#### スイッチ機能のサンプルプログラム
Aを押すと0が表示され、Bを押すと1が表示されます。
ABボタンを押すと、前に表示されている値と違う値が表示されます。1→0、0→1のように。
![OnOffSwitchDemo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165987/b73ca12d-d6a4-ab3e-8a2f-efc4fa9e633a.png)

#### コード解説
ボタンAが押されたとき、ボタンBが押されたときは従来の方法です。
ボタンABが押されたときのブロック内がOn/Offスイッチ機能を持っています。
まず、変数を作成します。変数名は何でもよいのですが今回はStatusとしておきます。
最初だけブロックにStatusを最初0にします。
ボタンABブロックでは、論理を配置します。Statusの値に何が入っているかで条件分岐を行います。
Statusに0が入っていれば、Statusを1に変更します。Statusに1が入っていれば、Statusを0にします。

これで操作に使うボタンの数を減らすことができます。
郵便番号を検索するjipcodeを拡張して住所から郵便番号を逆引きする gem を作った

住所を与えると郵便番号のデータを返すgemを作った。[jipcode-address_locator] / [GitHub](https://github.com/oieioi/jipcode-address_locator)

こんな形で使う:

```ruby
require 'jipcode'
require 'jipcode/address_locator'

Jipcode.locate_by_address('東京都千代田区千代田1-1', prefecture_code: true, distance: true)
# [
#   {:zipcode=>"1008111", :prefecture=>"東京都", :city=>"千代田区", :town=>"千代田１−１", :prefecture_code=>13, :distance=>1.0},
#   {:zipcode=>"1000001", :prefecture=>"東京都", :city=>"千代田区", :town=>"千代田", :prefecture_code=>13, :distance=>0.9538461538461538},
#   {:zipcode=>"1000000", :prefecture=>"東京都", :city=>"千代田区", :town=>nil, :prefecture_code=>13, :distance=>0.9076923076923077}
# ]
```

郵便番号から郵便地域を取得する [jipcode] という非常に頻繁にメンテナンスされている素晴らしいgemがあり、このgemを拡張する形で実装した。参考記事: [郵便番号から住所を取得できるgemを作りました - Qiita](https://qiita.com/RinKeiHotman/items/213c1af7f0c190fcbbdf)

逆引きの挙動は住所→郵便番号の取得を行うWeb API、[Zipcoda](https://zipcoda.net/)に近くなるように調整した。検索語句と郵便地域のどちらかがどちらかを含んでいるデータを全て洗い出し、その後[Jaro Winkler距離](https://en.wikipedia.org/wiki/Jaro%E2%80%93Winkler_distance)を計算し、近いもの順にソートして返す。

毎回該当する都道府県のデータを全部チェックするので遅い。また[jipcode]のデータを都道府県別にインデックスしたファイルを作成するので、初回はより時間がかかる。~~ハイフンや数字は全角で渡さないとヒットしない。~~ (ちょっとだけ正規化するようにした。v0.1.0)

変な挙動してたら issue/プルリクください :bow:


[jipcode]:https://rubygems.org/gems/jipcode
[jipcode-address_locator]:https://rubygems.org/gems/jipcode-address_locator
RxSwiftのメモ

## ViewModelからUISearchBarへ値をセット

これでセットすると、UISearchBarからの変更通知がこない？

```swift
import RxCocoa

class ViewModel {
    let textOutput: PublishRelay<String?> = PublishRelay<String?>()
}
```

```swift
import UIKit
import RxSwift
import RxCocoa

class ViewController : UIViewController {

    private let vm: ViewModel = ViewModel()

    private let disposeBag: DisposeBag = DisposeBag()

    @IBOutlet private weak var searchBar: UISearchBar! {
        didSet {
            self.vm.textOutput
                .bind(to: self.searchBar.rx.text)
                .disposed(by: self.disposeBag)
        }
    }

}
```

## メソッドの実行を検知する

継承してオーバーライドしなくとも下記のようにしてメソッドの実行を検知できる

```swift
let view = UIView()
view.rx.methodInvoked(#selector(UIView.layoutSubviews))
    .subscribe(onNext: { _ in
        // 処理
     })
```