OmniAICreator/Qiita-1.07M huggingface dataset:
Windows10をInsiderPreviewにする

# Windows10のInsiderPreviewを使いたいので、方法をメモ
VirtualBoxにインストールしたWindows10をInsiderPreviewにしてみたいと思います。
前回の記事 https://qiita.com/hinataysi29734/items/d4e48ca673bad2f5ea03

まずは、設定を開き、更新とセキュリティのWindows Insider Program を開きます。
「開始する」をクリックします。
![01](https://qiita-image-store.s3.amazonaws.com/0/369431/ca0dec88-6b1b-0659-b6c6-9ae8a634ed89.png)
「登録」をクリックしました。
![02](https://qiita-image-store.s3.amazonaws.com/0/369431/9361879c-5f19-98d8-b998-27a6317900c7.png)
「Sign Up」をクリックしました。
![03](https://qiita-image-store.s3.amazonaws.com/0/369431/c7f53ece-b289-12e0-3337-3aef959d1cd1.png)
チェックを入れて「Submit」をクリックします。
![04](https://qiita-image-store.s3.amazonaws.com/0/369431/e711f399-9b35-136a-82b1-fd8c84b9a407.png)
「Close」をクリックします。
![05](https://qiita-image-store.s3.amazonaws.com/0/369431/774009df-5746-f300-2611-6b63b5827a2a.png)
「アカウントをリンクする」をクリックします。
![06](https://qiita-image-store.s3.amazonaws.com/0/369431/fff34437-57f4-c2d5-4a63-fdbd662e60e0.png)
登録したアカウントが選択されていますで、そのまま「続行」をクリックします。
![07](https://qiita-image-store.s3.amazonaws.com/0/369431/aaafa19c-9c7f-0040-22eb-c4a1d852c343.png)
そのまま確認ボタンをクリックしました。
![08](https://qiita-image-store.s3.amazonaws.com/0/369431/ce229484-ca99-8987-1e1f-6ffb2e45c158.png)
![09](https://qiita-image-store.s3.amazonaws.com/0/369431/dae22098-df2f-0cdf-81db-035cf97fd804.png)
「確認」をクリックします。
![10](https://qiita-image-store.s3.amazonaws.com/0/369431/8cd40ced-dfcc-a097-c2b4-88e5eeebb168.png)
「今すぐ再起動」をクリックしました。
![11](https://qiita-image-store.s3.amazonaws.com/0/369431/c45f836f-a590-edf7-c2c5-476c807fa3f0.png)
再起動したら、設定の更新とセキュリティのWindows Update を開いて、アップデートを実行します。このあと何回か再起動されます。念のため電源に接続するようにしてください。
![12](https://qiita-image-store.s3.amazonaws.com/0/369431/7d067d21-dad5-c03c-62d9-81a88219c377.png)
![13](https://qiita-image-store.s3.amazonaws.com/0/369431/b8730ca2-fcdd-09bb-ee62-2321112ae638.png)
![14](https://qiita-image-store.s3.amazonaws.com/0/369431/f6ee7b63-839d-6b19-f80c-5e652ae301bb.png)
ログイン画面で、背景にぼかしがかかるようになりました。
![Windows10.jpg](https://qiita-image-store.s3.amazonaws.com/0/369431/7eca2c2f-f80f-624f-ac07-96ae6cfa82e5.jpeg)
スタートメニューの左側のボタンにカーソルを当てるとサブメニューが出るようになっていました。
![15](https://qiita-image-store.s3.amazonaws.com/0/369431/36e4ed01-0d46-1b4a-c26f-839dfd5e8769.png)

# 不満な点について
デフォルトの壁紙が変わってしまいました。元の画像ファイルが上書きされているようです。
![16](https://qiita-image-store.s3.amazonaws.com/0/369431/09d356d3-9976-d210-d8c1-b7a3e016c79a.png)
![17](https://qiita-image-store.s3.amazonaws.com/0/369431/91481db5-7076-971b-f110-2e678e7cc3dd.png)

すごく気に入っていたので消えてしまうのは残念です。

Windows 10の新しい壁紙はこうやって作られた - GIGAZINE
https://gigazine.net/news/20150626-windows-10-desktop-image/
これの没写真にもっと良い画像あったかも?

改善できる点はフィードバックFubで積極的に意見表明しましょう!
実際に改善されるかはわかりませんが、すべて読んでいるらしいです。
フィードバックFubに同じような意見がありましたので、よかったら賛成票を投じてください。
![18](https://qiita-image-store.s3.amazonaws.com/0/369431/2cc97bd9-104b-faf0-4ba6-bf6c48fcb84d.png)
![19](https://qiita-image-store.s3.amazonaws.com/0/369431/d2ab7bb3-1dfa-c4f6-7b75-f6a9296c9b2a.png)

こちらからもアクセスできます。
https://aka.ms/AA4ezmy
https://aka.ms/AA4fssq
https://aka.ms/AA4ezn0
pyplot.jlでmatplotlib標準の任意のカラーマップを使う方法

get_cmap()を使う．

```julia
c=get_cmap("tab10") #tab10のところは好きなカラーマップの名前
plot(rand(10),color=c(0))
```

カラーマップは例えばこんなの
https://matplotlib.org/mpl_examples/color/colormaps_reference_04.png
俺でもわかる脱SSO AzureAD + PingFederate連携の解除

俺です。
SSOしないと死ぬ教信者ではありますが、
ちょっとした実験のためにAzureADとのFederateionを解除したいときがあるようなないような本当は無いほうが良いんですが男にはやらねばならぬときがある。
ということでAzureAD Connectで設定したAzureAD Federated Modeを解除する方法(Managed Modeに変更)する記録を残します。


# Powershellの起動とコマンドレットの実行

- Connect-MolServiceを実行してAzureADの認証を通します。
(<your_domain>.onmicrosoft.comアカウント情報で認証が必要です)
- AzureAD Root DomainのAuthentication modeをManagedに変更します。

```
PS C:\Windows\system32>  Connect-MsolService
PS C:\Windows\system32> Set-MsolDomainAuthentication -DomainName mussle.orenokaisha.co.jp -Authentication Managed
Set-MsolDomainAuthentication : Unable to change the authentication type of this domain because it is a subdomain. To
change the authentication type of this subdomain, use the Get-MsolDomain cmdlet to find the root domain and  then
change the root domain authentication type.
At line:1 char:1
+ Set-MsolDomainAuthentication -DomainName mussle.orenokaisha.co.jp -Authenti ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [Set-MsolDomainAuthentication], MicrosoftOnlineException
    + FullyQualifiedErrorId : Microsoft.Online.Administration.Automation.DomainNotRootException,Microsoft.Online.Admin
   istration.Automation.SetDomainAuthentication
PS C:\Windows\system32> Set-MsolDomainAuthentication -DomainName orenokaisha.co.jp -Authentication Managed
PS C:\Windows\system32> Get-msoldomain

Name                         Status   Authentication
----                         ------   --------------
orenokaisha.co.jp                Verified Managed
orenokaisha.onmicrosoft.com      Verified Managed
mussle.orenokaisha.co.jp           Verified Managed
orenokaisha.mail.onmicrosoft.com Verified Managed
```

脱フェデレーションライフを！
おわり
NSObject-Rxの実装を読み解く(二番煎じ)

# NSObject-Rxの実装を紐解きます。

RxSwiftを利用していれば、おそらく利用したことのあるライブラリ、`RxSwiftCommunity/NSObject-Rx`。

一応解説しておくと、`NSObject`のサブクラスであれば、`DisposeBag`を宣言する必要なく利用することができるという便利な代物です。

RxSwiftで開発をしているととても良く使うライブラリの一つではないでしょうか。

今回、ひょんなことからこのライブラリがどのようにして`disposeBag`を実装しているのかを確認してみたくなって、びっくりしたので、まとめておきます。

# Swiftの機能のみを利用した実装ではない。

今回話している`RxSwiftCommunity/NSObject-RX`は、Swiftの機能のみを利用した実装にはなっていません。

`NSObject-Rx`の実体ファイルは下記ファイルなのですが、結構無茶苦茶やってますね。

https://github.com/RxSwiftCommunity/NSObject-Rx/blob/master/NSObject%2BRx.swift

大まかな流れは、

1. `Reactive` Protocolのデフォルト拡張を`Base: AnyClass`に指定(すべてのクラスでデフォルト拡張される)
2. Objective-Cの`メンバ変数追加`ができる`Associated Object`というびっくり黒魔術を利用して`DisposeBag`を宣言
(SwiftでObjective-Cの黒魔術ってどうなった？: https://qiita.com/fmtonakai/items/e9036dec4af2609b5715)

3. 初回アクセス時には生成、セット時には`setter`内部でセットされたdisposeBagをAssociated Object経由でプロパティかのように保持
4. disposeBagの生成、アクセス処理は`objc_sync_enter`、`objc_sync_exit`で強制同期。

結構すごい実装になってました。

ちなみになんですが、`Associated Object`はピュアSwiftだと動作しないようなので、Ubuntuとかで開発する場合は、うまくいかない感じだと思われます。

# 読み解いてみて

`Objective-C`由来の黒魔術がこんなところで生かされていたのが結構驚きでした。
p5.jsの開発環境をwebpack4を使って整える

p5.jsの開発環境の選択肢としては、[OpenProcessing](https://openprocessing.org)などのweb上のエディタを使うか、自前で用意するかどちらかになると思います。自前で用意する場合、[`p5-manager`](https://www.npmjs.com/package/p5-manager)という便利なライブラリがあり、基本的にはこのp5-managerを使って開発環境を整えれば、自分のエディタ上で開発できる上に、`watch`機能もあるのでソースを編集したらすぐにホットリロードされてかなり便利です。

## Webサイトに組み込んでいきたい
このp5-managerの環境でもwebサイトを作れると思いますが、cssやes6でクラスを使って開発していくには物足りません。そこで、webpackとes6で開発できる環境を整えるために良さそうなのが[こちらのGitHub](https://github.com/julsgud/p5-es6-webpack-seed)にありました。クローンして使ってみたところ、問題なく使えたので、しばらくこれを使って開発していて、いざGitHubにアップしてみたら、GitHub上で以下の警告を受けました。

<img width="1001" alt="スクリーンショット 2019-03-05 11.02.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/117549/791ec031-2a41-a193-82c3-784b432fd118.png">

セキュリティの致命的な脆弱性が見つかったという警告ですが、どこが問題だったかというと、webpackのバージョンが古すぎるのが原因だそうです。

<img width="722" alt="スクリーンショット 2019-03-05 11.03.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/117549/7a4694b0-2f38-d8c0-1ccf-65929c79c959.png">

## webpack4に対応した環境を試してみる
webpackについては概念程度の知識しかなかったので、これを機に勉強がてら最新バージョンのwebpack4に対応した環境を試してみました。構築の際に参考にしたサイトは[本家のドキュメント](https://webpack.js.org/concepts)です。そのほか、webpackについては様々な方の記事を参考にしました。

脆弱性のあったのリポジトリの`webpack.config.js`の構成を見ながら何が必要かを洗い出していくと、構成的には以下のような構成で、オプションにある項目をwebpackのドキュメントから参照してconfigファイルを作りました。

| オプション |自分なりの解釈|
| :-- |:----|
|entry|変換対象のjsファイル|
|output|変換したデータの出力先。webpackコマンドで出力される。|
|module|jsモジュール以外の処理やそのほかの依存依存関係を含む処理。ここではstyle-loaderなどのモジュールを使ってscssの処理をすぐに適用するように設定|
|devServer|開発用の設定。ポート番号と、watchするディレクトリの指定。|
|plugins|js以外のファイルの変換などを行う設定<br>assetsのデータのコピーとhtmlの書き出し。htmlはbundle.jsが読み込まれた状態で出力される。|

## エラーに悩まされる
webpackのサイトの設定通りにconfigに書いていっても、エラーに遭遇してなかなか開発環境が整えられませんでした。とくに、`plugins`の設定で

```
Tapable.plugin is deprecated. Use new API on `.hooks` instead
```
こういうエラーが出たり

```
compilation.mainTemplate.applyPluginsWaterfall is not a function
    at /var/www/myproject/node_modules/html-webpack-plugin/lib/compiler.js:81:
```
こういうエラーが出たりで、なぜ本家と同じ設定なのにできないのだ。。。と意気消沈してましたが、`html-webpack-plugin`と`copy-webpack-plugin`のバージョンを最新にしたらあっさり解消されました。脆弱性があったリポジトリのnpmパッケージそのまま使っていたのがアダになりました。。。

## なんとか完成
まだまだ理解に苦しむところもありますが、なんとかwebpack4で開発できる環境が整えられました。これでp5.jsを使ってアニメーションを作っていけます。
  
[GitHub](https://github.com/mitsuyacider/p5-starter)に置いておくので良ければどうぞ。
p5.jsだけでなく、そのままCanvasのアニメーションを扱うコードも入っていますので、p5.jsと`canvas`の`context`を使ったアニメーションも同じcanvas上で両立して使えます。


![output2.gif](https://qiita-image-store.s3.amazonaws.com/0/117549/827a32b0-3cf8-845b-3829-d4a0099dd884.gif)
DKIM の 公開鍵を Terraform で Route53 の TXTレコードに登録する

## DKIM で使うキーペア作成
```
# opendkim-genkey -D /etc/opendkim/keys -b 2048 -d ドメイン名
```
↓
/etc/opendkim/keys ディレクトリに秘密鍵と公開鍵が作られる
セレクタ指定なしの場合（＝default）
　秘密鍵・・・default.private
　公開鍵・・・default.txt

この公開鍵 default.txt の内容を DNS に登録する

```
default._domainkey	IN	TXT	( "v=DKIM1; k=rsa; "
	  "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0IzkotJLTz7HxddvSO7PSfOsJgDolIH0Vc9i+QXiMi9liPw9CETbbg46tHKx1U2o9g4zXnNmNSDihr0VV/Xjf/urL5ScQSup40SzkeDsrSycT9afNPEtD9nPG5/JvPchGIt54Creu+EQQ0BOEEUwC0mXnBhq6NCM5yYgr+3rGSX/K1IaCzwQwUyjfKVfQuNQqidt/A0SkHXWk8"
	  "1RjmB2SBFgRluusAwaEIj39EWnIK5qKfFK6f8mJGqkhyAsq/b2G/7HE7xRjECd9TA0ibgPzHFxR4TcmMu7yvxLYsDvmixVEXpjv3qesPehZvW7gmnLkw+Q7h48z1hCBJ66bFMO0wIDAQAB" )  ; ----- DKIM key default for ドメイン名
```

## Route53 の制限

default.txt で TXT レコードが３行（３分割）になっているのは、文字数の長いTXTレコード値を登録できないDNSがあるので、わざわざ分けてくれている。

Amazon Route53 も TXT レコード値の上限は 255 なので、
https://forums.aws.amazon.com/message.jspa?messageID=343304

３行を次のように１行に繋げる
１行目："v=DKIM1; k=rsa; "
２行目："p=MIIBIjANBgkq〜A0SkHXWk8"
３行目："1RjmB2SBFgRluu〜O0wIDAQAB"
↓
"v=DKIM1; k=rsa;\" \"p=MIIBIjANBgkq〜A0SkHXWk8\" \"1RjmB2SBFgRluus〜O0wIDAQAB"


## terraform テンプレート例

```
resource "aws_route53_record" "domainkey-TXT" {
  zone_id = "************"
  name    = "default._domainkey"
  type    = "TXT"
  ttl     = "600"
  records = [ "v=DKIM1; k=rsa;\" \"p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0IzkotJLTz7HxddvSO7PSfOsJgDolIH0Vc9i+QXiMi9liPw9CETbbg46tHKx1U2o9g4zXnNmNSDihr0VV/Xjf/urL5ScQSup40SzkeDsrSycT9afNPEtD9nPG5/JvPchGIt54Creu+EQQ0BOEEUwC0mXnBhq6NCM5yYgr+3rGSX/K1IaCzwQwUyjfKVfQuNQqidt/A0SkHXWk8\" \"1RjmB2SBFgRluusAwaEIj39EWnIK5qKfFK6f8mJGqkhyAsq/b2G/7HE7xRjECd9TA0ibgPzHFxR4TcmMu7yvxLYsDvmixVEXpjv3qesPehZvW7gmnLkw+Q7h48z1hCBJ66bFMO0wIDAQAB" ]
}
```
IDCFクラウドのゾーン別・仮想マシン作成時間の比較

# 概要
ゾーンによって仮想マシンを作成する時間に差異があるように感じるが、実際のところいったいどうなの？ということで、東日本リージョン１から２ゾーン、東日本リージョン２から２ゾーン を選んで仮想マシン作成にかかる時間を計測してみます。
# 条件
#### 計測対象
  - 東日本リージョン１: newton, radian
  - 東日本リージョン２: candela, kelvin

#### 作成する仮想マシン
  - スペック：standard.M8
  - ディスクサイズ：8GB（デフォルト）
  
#### 計測方法
計測対象のゾーンに対し、１時間毎に１分おきに１台ずつ５台を作成し、２４時間計測する
terraformで仮想マシンを作成し、time コマンドで 実行時間を計測する

# 結果

#### ゾーン別平均作成時間
ゾーンごとの作成時間の平均値を示します。

|    | newton | radian | candela | kelvin|
|:--:|:------:|:------:|:-------:|:-----:|
|Ave.| 01:14  | 01:12  | 00:34   | 00:21 |

東日本リージョン１の newton, radian はあまり差異がありませんでした。
東日本リージョン２は、kelvin が candela に比べて早い結果となりました。

#### 時間ごとの分布
実行時間帯ごとの平均作成時間を示します。

<img width="572" alt="IDCFゾーン別VM作成時間平均.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/105824/d70f9a0b-66d1-0839-cf90-f138a3a9deba.png">

newton は 2:00～7:00 の夜間・早朝の時間帯に若干時間がかかっているように見えますが、各ゾーンに共通した実行時間帯による有意な差異は認められませんでした。
#### 最大／最小作成時間
ゾーンごとの最大の作成時間と最小の作成時間です。
<img width="592" alt="IDCFゾーン別VM作成時間最大最小.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/105824/8b49f939-52bc-c7d1-084d-cae5d1705411.png">
作成にかかる時間には、25秒～45秒くらいの幅がありそうです。

#### 作成時間の分布
ゾーンごとに、仮想マシン作成にかかった時間の分布を示します。

<img width="597" alt="newton.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/105824/88187cc9-e20c-4e6c-730e-dc66bf6e8daa.png">
<img width="600" alt="radian.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/105824/2db19ccc-6c5e-b3b6-544f-8e4cf67d4480.png">
<img width="600" alt="candela.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/105824/b654e6e6-afea-2a4d-72bd-7e584e59d348.png">
<img width="600" alt="kelvin.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/105824/f6bebb0b-bc5a-f418-ceb9-d525774be5f9.png">

どのゾーンも、仮装マシン作成にかかる時間には幅があるものの、早く作成が終わるケースの方が多いようです。

##総評

東日本リージョン1はnewton, radian とも 1分～2分、東日本リージョン2は candela で30秒～1分程度の作成時間という結果でしたので、東日本リージョン2は東日本リージョン1の半分程度の速度で仮装マシンの作成が完了すると言えそうです。
また、kelvin は candela よりもさらに早い結果となりました。kelvin は 2019/03/04 現在最新のゾーンのため、単純に「新しいから早い」と考えることもできますが、 公式サイトで「サーバーとストレージ機器を刷新し、仮想マシンの処理性能が約10%向上」とうたわれているので、ハードウェア的な違いによって差が生じているのかもしれません。

※ 一番成績の良かった kelvin ですが、2019/03/04 現在、新規作成停止状態だそうで・・・残念:sob:
せっかく性能のよいゾーンのようですので、はやく活用できるようになるといいですね♪
Amazon Linux 2にClamAVをインストールする

`clamd.scan`はかなりメモリを食うのでt2.microでは動かなかった。t2.mediumでは動いた。topで見たところ、VIRTが800 MiB、RESが600 MiBほど使っていた。

## パッケージをインストール

```
sudo amazon-linux-extras install -y epel
sudo yum install -y clamav clamav-update clamd
```

## freshclamの設定ファイルを編集

`/etc/freshclam.conf`を必要に応じて編集する。
当方では何も編集せずとも`sudo freshclam`は動いた。

## freshclamを実行してみる（ウィルス定義の更新）

```
sudo freshclam
```

## cronの設定の確認

`/etc/cron.d/clamav-update`というファイルが既に存在し、中で`/usr/bin/freshclam --quiet`を実行しているので、ウィルス定義の更新は毎日自動で実行される。

## clamdの設定ファイルを編集

編集しないと起動しなかった。

```/etc/clamd.d/scan.conf
--- scan.conf.orig	2019-01-05 02:44:58.000000000 +0900
+++ scan.conf	2019-03-05 12:00:08.489123891 +0900
@@ -5,13 +5,13 @@


 # Comment or remove the line below.
-Example
+#Example

 # Uncomment this option to enable logging.
 # LogFile must be writable for the user running daemon.
 # A full path is required.
 # Default: disabled
-#LogFile /var/log/clamd.scan
+LogFile /var/log/clamd.scan

 # By default the log file is locked for writing - the lock protects against
 # running clamd multiple times (if want to run another clamd, please
@@ -90,7 +90,7 @@

 # Path to a local socket file the daemon will listen on.
 # Default: disabled (must be specified by a user)
-#LocalSocket /var/run/clamd.scan/clamd.sock
+LocalSocket /var/run/clamd.scan/clamd.sock

 # Sets the group ownership on the unix socket.
 # Default: disabled (the primary group of the user running clamd)
@@ -98,7 +98,7 @@

 # Sets the permissions on the unix socket to the specified mode.
 # Default: disabled (socket is world accessible)
-#LocalSocketMode 660
+LocalSocketMode 660

 # Remove stale socket after unclean shutdown.
 # Default: yes
@@ -174,8 +174,8 @@
 # Don't scan files and directories matching regex
 # This directive can be used multiple times
 # Default: scan all
-#ExcludePath ^/proc/
-#ExcludePath ^/sys/
+ExcludePath ^/proc/
+ExcludePath ^/sys/

 # Maximum depth directories are scanned at.
 # Default: 15
@@ -204,7 +204,7 @@

 # Run as another user (clamd must be started by root for this option to work)
 # Default: don't drop privileges
-User clamscan
+#User clamscan

 # Stop daemon when libclamav reports out of memory condition.
 #ExitOnOOM yes
```

## clamdの起動

```
sudo systemctl start clamd@scan
sudo systemctl enable clamd@scan
```

ログは`journalctl -u clamd@scan`で見る。
設定ファイルで設定してあれば`/var/log/clamd.scan`にも出る。

あとは普通に`systemctl status clamd@scan` `systemctl stop clamd@scan`ができる。

# 参考

- [Linuxアンチウイルスソフト ClamAV - Qiita](https://qiita.com/bezeklik/items/4696e15c889ffff6bc41)
    - CentOSだが記事が新しく、内容的に近かった。

下記はいずれもAmazon Linux 1だったり、yumのパッケージ内容が変わっていたり？だったりして、そのままでは動かなかった。

- [Clam AntiVirus を AWS EC2 にインストールする - Qiita](https://qiita.com/yamadar/items/c916152462272b397100)
- [ClamAV on Amazon Linux - ぬぞうWiki]( https://tanuzou.com/nuzou/wiki/index.php?ClamAV%20on%20Amazon%20Linux)
Google+API終了！devise✕omniauth-google-oauth2でGoogle+APIを利用せずにrailsのgoogleログインできるようにする

# 背景

自分が開発していたrailsアプリケーションで`omniauth-google-oauth2`のgemでgoogleログインを実装していたのですが
他の記事を参考に、Google+APIを有効にしてgoogle側の認証の設定をしていました。
参考：[爆速ッ!! gem omniauth-google-oauth2 で認証させる](https://qiita.com/bino98/items/596b5cffeca7c104bd90)
　　　[[Rails] Facebook/Twitter/Googleでのユーザー登録をDevise & Omniauthを使って爆速で実装する](https://qiita.com/kazuooooo/items/47e7d426cbb33355590e)
　　　など。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/148486/a2418504-e66b-3969-dd6c-98e8bab97fff.png)


# Google+APIの終了
ところが、[Google+APIが終了](https://developers.google.com/+/api-shutdown)ということでこれはまずいんじゃないか？
と思い調べてみたものの、なかなか解決策がみつからず。
Google+APIを無効化したら `Invalid Credential`　と認証が無効であると怒られてしまう...


# 解決方法

どうしたものかと、`omniauth-google-oauth2`のgemのバージョンを上げてみたところ、

```ruby:
gem update 'omniauth-google-oauth2'
bundle install 'omniauth-google-oauth2'
```

無事Google+APIを無効にしてもログインできるようになりました。

定期的なgemの更新は大事ですね。
【Jenkins】【天気】Jenkins のlogin時にページ読み込みが遅い方々へ 【Health Metrics】

# Jenkinsのページ読み込みが遅い

- 仕事で多くのJOBを作成しているのですが、結果としてJOB数がえぐい
- 半年前ぐらいからlogin時にページ読み込みが極端に遅くなった

# 原因はお天気かも

いろいろありますが、JOB数が多くなってから遅くなった場合はお天気のせいかもしれません。

### お天気とは
- Health Metricsのことです
    - JOBの成功率を天気で表現してくれます
- 便利なのですが、JOBの成功率計算のためにアクセスページ以下のJOBを***再帰的***にみます

# 解決方法

- 天気の再帰設定を無効化します

### 実行環境

- jenkins2.0
    - CloudBees Folders Plugin
- JOBはgroovyファイルでDSLで管理しています

### GUIでやる

- JOBが作成されているFolderのconfigureを開く
- Health Metricsの欄を開き、Worst Child Health Metricのオプションにかかれている`Recursive` のチェックを外す。
- 設定を保存するとページ開くのが早くなっている

### groovy DSLで設定する

- DSL Pluginで使用できる、専用の設定値がありません。
- なのでjob のconfig.xmlを直接設定するオプションを使用します
- folder pluginの configureオプションを使うと、xmlを直接いじった設定ができます
- 参考にしたページ
    - https://jenkinsci.github.io/job-dsl-plugin/#method/javaposse.jobdsl.dsl.DslFactory.folder
    - https://jenkinsci.github.io/job-dsl-plugin/#method/javaposse.jobdsl.dsl.Folder.configure
    - GUIで設定したJenkinsFolderのURLのxmlを見る 
        - `{FolderURL}/config.xml`

- 結果、こんな感じになります

```groovy
folder("${jobPathString}"){
            description('disable_recursive_health_Metrics_directory')
            configure { folder ->
                folder / 'healthMetrics' / 'com.cloudbees.hudson.plugins.folder.health.WorstChildHealthMetric' {
                    'nonRecursive'(true)
                }
            }
        }
```

# まとめ

- 最近Jenkinsのページ読み込みが遅い、、という方は一度お試しあれ

# 参考URL

* https://github.com/jenkinsci/job-dsl-plugin/blob/master/job-dsl-core/src/main/resources/javaposse/jobdsl/dsl/Folder-template.xml
* https://jenkinsci.github.io/job-dsl-plugin/#method/javaposse.jobdsl.dsl.jobs.IvyJob.configure
brew install python で checking size of size_t... configure: error: in `/private/tmp/python-20190305-41841-p17rug/Python-3.7.2':

# なぜ

MacBookPro の引っ越しをしたら brew の環境が盛大にぶっ壊れた

# vim

```
$ brew install vim
==> Installing dependencies for vim: python and ruby
==> Installing vim dependency: python
Warning: Building python from source:
  The bottle needs the Apple Command Line Tools to be installed.
  You can install them, if desired, with:
    xcode-select --install

==> Downloading https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tgz
Already downloaded: /Users/ishii/Library/Caches/Homebrew/downloads/c0a14628b5078ca696f1e18227df67d9c5fbe04462c041d9252709c120ea3e1a--Python-3.7.2.tgz
==> ./configure --prefix=/usr/local/Cellar/python/3.7.2_2 --enable-ipv6 --datarootdir=/usr/local/Cellar/python/3.7.2_2/share --datadir=/usr/local/Cellar/python/3.7.2_2/share --enable-framework=/usr/local/Cellar/python/3.7.2_2/Frameworks -
Last 15 lines from /Users/ishii/Library/Logs/Homebrew/python/01.configure:
checking for size_t... yes
checking for uid_t in sys/types.h... yes
checking for ssize_t... yes
checking for __uint128_t... yes
checking size of int... 0
checking size of long... 0
checking size of long long... 0
checking size of void *... 0
checking size of short... 0
checking size of float... 0
checking size of double... 0
checking size of fpos_t... 0
checking size of size_t... configure: error: in `/private/tmp/python-20190305-37442-u0c38a/Python-3.7.2':
```

どうやら pythonでエラー

# python

```
$ brew install python
Warning: Building python from source:
  The bottle needs the Apple Command Line Tools to be installed.
  You can install them, if desired, with:
    xcode-select --install

==> Downloading https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tgz
Already downloaded: /Users/ishii/Library/Caches/Homebrew/downloads/c0a14628b5078ca696f1e18227df67d9c5fbe04462c041d9252709c120ea3e1a--Python-3.7.2.tgz
==> ./configure --prefix=/usr/local/Cellar/python/3.7.2_2 --enable-ipv6 --datarootdir=/usr/local/Cellar/python/3.7.2_2/share --datadir=/usr/local/Cellar/python/3.7.2_2/share --enable-framework=/usr/local/Cellar/python/3.7.2_2/Frameworks -
Last 15 lines from /Users/ishii/Library/Logs/Homebrew/python/01.configure:
checking for size_t... yes
checking for uid_t in sys/types.h... yes
checking for ssize_t... yes
checking for __uint128_t... yes
checking size of int... 0
checking size of long... 0
checking size of long long... 0
checking size of void *... 0
checking size of short... 0
checking size of float... 0
checking size of double... 0
checking size of fpos_t... 0
checking size of size_t... configure: error: in `/private/tmp/python-20190305-41841-p17rug/Python-3.7.2':
configure: error: cannot compute sizeof (size_t)
```

Oops

# 解決

```
xcode-select --install
```

xcode のコマンドラインツールを入れたら治りましたとさ
[検証]Puppeteerの接続　〜対象ページでの違い〜

#はじめに
編集中で解説がまだ記載できておりませんが、先にコードだけ共有しておきます。

#今回のコード
```javascript:接続時間の検証コード
const puppeteer = require('puppeteer');

(async() => {
    const url = [
        'https://www.google.com/',
        'https://www.yahoo.co.jp/',
        'https://qiita.com/',
        'https://github.com/',
        'https://www.rakuten.co.jp/',
    ];

    const browser = await puppeteer.launch();
    const page = await browser.newPage();

    for (let i = 0; i < 5; i++){
        console.log(url[i] + 'に接続中')
        console.time('接続までの時間');
        await page.goto(url[i]); // ページへ
        console.timeEnd('接続までの時間');
    }
    

// puppeteerを終了
await browser.close();
})();
```
```terminal:実行結果（１回目）
https://www.google.com/に接続中
接続までの時間: 1190.734ms

https://www.yahoo.co.jp/に接続中
接続までの時間: 1360.209ms

https://qiita.com/に接続中
接続までの時間: 4163.477ms

https://github.com/に接続中
接続までの時間: 2957.095ms

https://www.rakuten.co.jp/に接続中
接続までの時間: 20221.243ms
```
```terminal:実行結果（２回目）
// https://www.google.com/に接続中
// 接続までの時間: 1194.058ms

// https://www.yahoo.co.jp/に接続中
// 接続までの時間: 2463.839ms

// https://qiita.com/に接続中
// 接続までの時間: 1958.890ms

// https://github.com/に接続中
// 接続までの時間: 2816.664ms

// https://www.rakuten.co.jp/に接続中
// 接続までの時間: 20071.951ms
```
```terminal:実行結果（３回目）
// https://www.google.com/に接続中
// 接続までの時間: 1171.473ms

// https://www.yahoo.co.jp/に接続中
// 接続までの時間: 1387.476ms

// https://qiita.com/に接続中
// 接続までの時間: 2444.999ms

// https://github.com/に接続中
// 接続までの時間: 2725.922ms

// https://www.rakuten.co.jp/に接続中
// 接続までの時間: 19709.615ms
```

#考察
楽天が圧倒的に遅い。
平均値で見ると、おそらくgoogleの接続時間の10倍ほどかかっている。

ヘッドレスブラウザとはいえ、情報量の重いページは接続が遅いと思われる。
（編集中）
prettier でコミット前にフォーマットする

`prettier` `lint-staged` `husky` を使って`git commit` に合わせて`JavaScript`のコードを整形します。

## 必要なパッケージをインストールする

```
npm install --save-dev prettier lint-staged husky
```

## commitに連動させる
`husky`と`lint-staged`の設定をpackage.jsonにします。

```package.json
{
  "devDependencies": {
    "husky": "^1.3.1",
    "lint-staged": "^8.1.5",
    "prettier": "^1.16.4"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.{js,jsx}": [
      "prettier --write",
      "git add"
    ]
  }
}
```

`git`のバージョンが古いとhooksをうまくつけれないことがあります。
参考: [husky バージョン3 で git hooks が動かない](https://qiita.com/hikonaz/items/bd4ab14e7ce9996f36f5)

## prettierの整形ルールを作る
`prettier`の整形ルールを`.prettierrc.js`に追加します。

```.prettierrc.js
module.exports = {
  printWidth    : 120,
  tabWidth      : 2,
  useTabs       : false,
  semi          : true,
  singleQuote   : true,
  trailingComma : 'es5',
  bracketSpacing: true,
  arrowParens   : 'avoid',
};
```

オプションの一覧: [prettier.io/docs/en/options.html](https://prettier.io/docs/en/options.html)

おわり。
SikuliXをmacにインストール

# 環境
macOS Mojave 10.14.1
SikuliX 1.1.3

# インストール
https://launchpad.net/sikuli
ここのURLを踏んで、右側の`Latest version is 1.1.3`をクリック（現在は1.1.3）

![スクリーンショット 2019-03-05 11.28.23.png](https://qiita-image-store.s3.amazonaws.com/0/285122/cae95466-c390-02ba-edea-99e9a0880d2b.png)

# Set up
ダウンロードしたファイルをダブルクリックして開いてください。
「はい」を押していき、以下の画像のところまで行ったら「Pack1」にチェックを入れ、PythonかRubyを選んでください。

<img width="980" alt="スクリーンショット 2019-03-05 11.31.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/285122/a30022f4-06b5-0ed1-2665-ac9aaefeef1d.png">

その後は全部「はい」でインストールできます。

Setupが完了したら以下のような構造になっていると思います。
<img width="234" alt="folder.png" src="https://qiita-image-store.s3.amazonaws.com/0/285122/03b2f1e3-728c-9174-e948-d7f84441dd72.png">

# 起動
SikuliX.appをダブルクリックして起動してください。
起動したら以下のようになっていると思います。(少し設定をしたので、このような画面になっています。)
「マウスの動作」でどういう処理をして欲しいかを選び、スクショを撮ればスクショしたディレクトリなどを探しにいき選んだ動作をしてくれます。

<img width="1077" alt="screen.png" src="https://qiita-image-store.s3.amazonaws.com/0/285122/4037e9ed-caf5-e94c-9e93-81e9f1068276.png">

# その他
スクショして動作を選べば動いてくれますが、自分でPythonやRubyで組むこともできるので、かなり自由度が高い自動化ツールだなと思いました。
Mac, Windows, Linuxに対応しているので、誰でも使える点もいいなと思いました。
Windowsにてファイル一覧をコマンドで取得する

#フォルダ内のファイルをリストアップしたい


フォルダ内のファイルをリストアップしたい
(したいというより、してくれ！という機会が多いと思いますが。。。)

```ruby:qiita.rb
dir *.* /s /b (対象のディレクトリのフルパス) C:\hoge\hogehoge\hogegenoge > (出力先フルパス)C:\hoge\test.csv
```

# 中身

冒頭のアスタリスクは拡張子などの指定
sで再帰的にフォルダ内を見てくれます。
bでファイルまで見てくれます。

終わり！


# 参考

[Windowsのdirコマンドでファイル名の一覧を取得する](https://www.atmarkit.co.jp/ait/articles/0412/04/news014.html)
[【Windows】フォルダ内のファイル名一覧を簡単に作成する方法](https://blog.honjala.net/entry/2016/04/05/011705)

ありがとうございますっ！
Rubyのブロックがあまり理解できてないので自分なりにまとめてみる

Rubyのブロックが毎回よくわからなくなります。強いエンジニアになりたひ。。。

あと、範囲オブジェクトもよくわかってないような気がします。雑魚です。

でも、Rubyにおいてブロックという概念はめっちゃ大事らしいので逃げることはできなさそうです。

仕方ないので勉強します。

勉強がてらここにアウトプットしてみます。

よかったらいいねしてください。喜びます。

## ブロックは範囲オブジェクトや配列に対して使える

具体例をみながら理解していきましょう。

例
`(1..5).each { |i| puts 2*i }`

出力結果
`2
4
6
8
10`

波カッコの部分がブロックです。
出力結果をみながらだと理解しやすいですね。

`(1..5).each { |i| puts 2*i }`
を無理やり和訳すると、
「(1..5)という範囲オブジェクトに対して、eachメソッドを実行する。eachメソッドの引数は `|i| puts 2*i`」
という感じでしょうか。

「1から5までのそれぞれの要素に対して、2倍した結果を出力する」
というとより自然言語っぽくていいですかね。


ちなみにこのコード
`(1..5).each { |i| puts 2*i }`
はこのように書くこともできます。

`(1..5).each do |i|
　　puts 2*i
end`

他の言語やってた人だったらこっちの方がわかりやすいかもですね。
しかし、今回のようにRubyのコードが一行の場合は前者の書き方が一般的なので早く慣れる必要がありそうです。
複数行のときは後者の書き方でオッケーです。

`(1..5).each { |i| puts 2*i }`
は和訳すると、
「(1..5)という範囲オブジェクトに対して、eachメソッドを実行する。eachメソッドの引数は `|i| puts 2*i`」
と言えると言いましたが、より汎用的な言い方をすると、

**「範囲オブジェクトで指定された要素に対して、波カッコで書かれたRubyのコードを実行する」**

とも言えますね。

## ブロックを一言でいうと？？？

ブロックを一言でいうと、
**「引数としてRubyのコードを渡せる機能」**
と言えます。

今までは引数には数字や文字列、trueやfalseなどを渡していましたが、ブロックでは引数にRubyコードを渡すことができます。

---
とりあえずはこれくらいの理解でいいですかね。
あとはコードみたり書いたりして慣れていこうと思います。

mapもよくわかってないので、次はmapの記事を書こうかな。
LaravelのEloquentでカラムの変更情報を取得

カラムが変更されたか判断する必要があり、動作を確認したメモ。

```php
>>> $group = App\Group::all()->last();
=> App\Group {#49052
     id: 10,
     name: "Aグループ",
     mailaddress: "hoge@example.com",
     prefectures_id: 13,
     city: "千代田区",
     address: "大手町一丁目",
     telephone: "03XXXXXXXX",
     created_at: "2019-01-09 12:09:56",
     updated_at: "2019-01-09 12:09:56",
   }
```

値を変更してみる

```php
>>> $group->name = "hoge";
=> "hoge"
>>> $group->telephone = "03YYYYYYYY"
=> "03YYYYYYYY"
```

`isDrity`メソッドで確認。変更されてるので`true`ですね。

```php
>>> $group->isDirty();
=> true
```

カラム絞っても確認できます。

```php
>>> $group->isDirty("name");
=> true
>>> $group->isDirty("city");
=> false
>>> $group->isDirty(["name", "city"]);
=> true
```

変更された内容は`getDirty`メソッドで確認。
変更されたnameとtelephoneの内容が確認できる。

```php
>>> $group->getDirty();
=> [
     "name" => "hoge",
     "telephone" => "03YYYYYYYY",
   ]
```

変更前の値が知りたい場合には`getOriginal`メソッド

```php
>>> $group->getOriginal();
=> [
     "id" => 10,
     "name" => "Aグループ",
     "mailaddress" => "hoge@example.com",
     "prefectures_id" => 13,
     "city" => "千代田区",
     "address" => "大手町一丁目",
     "telephone" => "03XXXXXXXX",
     "created_at" => "2019-01-09 12:09:56",
     "updated_at" => "2019-01-09 12:09:56",
   ]
>>> $group->getOriginal("name");
=> "Aグループ"
```

`save`してみる。
`isDirty`はfalseを返すようになり、`getOriginal`で確認しても更新後の値に書き換わっている。

```php
>>> $group->save();
=> true
>>> $group->isDirty();
=> false
>>> $group->getOriginal("name");
=> "hoge"
```
MySQLチートシート


## mysqldumpで特定のdbをgzipでバックアップ&リストア
**バックアップ**

```bash
mysqldump -u ${user} -p --single-transaction ${db_name} --ignore-table=mysql.event | gzip > ${db_name}.dmp.gz.`date +%Y%m%d`
```
**リストア**

```bash
zcat ${db_name}.dmp.gz.`date +%Y%m%d` | mysql -u ${user} -p ${db_name}
```

## 全テーブルの大雑把なレコード数を一覧表示する
各テーブルのレコード数を確認したい時に使用する。例えばレプリケーションやリストアの確認の時など。

ただし、information_schemaはわりと大雑把なので、完全に一致しないこともあるので注意。
その場合は `select count` する。
公式ドキュメントにも以下のように記載がある。
> For InnoDB tables, the row count is only a rough estimate used in SQL
> optimization. (This is also true if the InnoDB table is partitioned.)

**全DBの全テーブル**

```sql
mysql> select table_name, table_rows from information_schema.TABLES;
```

**特定のDBの全テーブル**

```sql
mysql> select table_name, table_rows from information_schema.TABLES where table_schema = '${db_name}';
```
OpenJDK 11 以降で JavaMail が使えない場合の対処法

# 概要

OracleJDK 8 から OpenJDK 11 に変更したところ、JavaMail で以下の例外が発生するようになりメール送信が一切できなくなりました。

```plaintext
java.lang.NoClassDefFoundError: javax/activation/DataSource
　　　(略)
Caused by: java.lang.ClassNotFoundException: javax.activation.DataSource
```

本記事では OpenJDK 11 以降で JavaMail を使うための方法についてご紹介します。

# 例外発生の原因

JavaMail では内部で `java.activation` パッケージを使用していますが、OpenJDK 11 以降では [JEP 320: Remove the Java EE and CORBA Modules](http://openjdk.java.net/jeps/320) によって以下のパッケージが削除されています。

* java.xml.ws
* java.xml.bind
* java.activation
* java.xml.ws.annotation
* java.corba
* java.transaction

`java.activation` パッケージが削除されたことにより JavaMail で参照するクラスが見つからなくなり概要で示した例外が発生しています。

# 対処法

`java.activation` パッケージとして [JavaBeans Activation Framework](https://mvnrepository.com/artifact/com.sun.activation/javax.activation) を使用することで JavaMail が使えるようになります。

```xml:Maven
<!-- https://mvnrepository.com/artifact/com.sun.activation/javax.activation -->
<dependency>
    <groupId>com.sun.activation</groupId>
    <artifactId>javax.activation</artifactId>
    <version>1.2.0</version>
</dependency>
```

```gradle:Gradle
// https://mvnrepository.com/artifact/com.sun.activation/javax.activation
compile group: 'com.sun.activation', name: 'javax.activation', version: '1.2.0'
```
記事作成のためのMarkdown記法のまとめ

#Markdown記法とは
Markdown（マークダウン）記法は文章を記述するための記法（マークアップ言語）の一つです。

メールを記述する時のように書きやすくて読みやすいプレーンテキストをある程度見栄えのする
HTML文書へ変換できるフォーマットとしてジョン・グルーバーによって開発されました。

Markdown記法を使用する大きな利点は
**「簡単にコントラストのある記事を制作できること」**にあります。

#Markdown記法の書き方
以下からMarkdown記法の主な書き方に関して説明していきます。

##1. 見出し
先頭に#をつけることで見出し文字を表現できます。 
(#の数が少ないほど見出しは大きく表示されます)

###-- 記入例

>\#見出し1
>\##見出し2
>\###見出し3

###-- 表示例

#見出し1
##見出し2
###見出し3

##2. リスト
先頭に -(ハイフン), *(アスタリスク), 「+(プラス)」&半角スペースをつけることでul型(マーク型)リストを表現できます。

###-- 記入例

>\- 項目1
>　- 項目1_1
>　- 項目1_2
>\* 項目2
>\+ 項目3

###-- 表示例

- 項目1
 - 項目1_1
 - 項目1_2    
* 項目2
+ 項目3

##3. 強調
文字を*(アスタリスク)または_(アンダーバー)で囲めば文字の強調を表現できます。 

###-- 記入例

>\*イタリック強調*
>\_イタリック強調_

>\**太字強調**
>\__太字強調__

###-- 表示例

*イタリック強調*
_イタリック強調_

**太字強調**
__太字強調__

##4. 引用
先頭に>(大なり記号)をつけることで以下の文字が引用表現になります。
複数行で引用表現をしたい場合、すべての行に>(大なり記号)をつけなければなりません。

###-- 記入例

>\> こちらの文章はすべて引用表現で表示されているものです。
>\> 改行後も>(大なり記号)を先頭につけてください。

###-- 表示例

> こちらの文章はすべて引用表現で表示されているものです。
> 改行後も>(大なり記号)を先頭につけてください。

##5. リンクの挿入、画像埋め込み
\[リンクテキスト](URL)の記述でリンクの挿入が可能になります。
また、!\[代替テキスト](画像URL)の記述で画像の埋め込みが可能になります。

###-- 記入例

>\[coliss](https://coliss.com/)
>!\[zebra.jpg](https://qiita-image-store.s3.amazonaws.com/0/371684/1287a0e9-8bab-7855-7a39-3220c3cf3a47.jpeg)

###-- 表示例

[coliss](https://coliss.com/)
![zebra.jpg](https://qiita-image-store.s3.amazonaws.com/0/371684/9006bbfe-9cea-d912-bcc0-694b334aa570.jpeg)


##6. コードの埋め込み
コードを```(バッククォート3つ)で囲めば、
コードの埋め込みが可能になります。

###-- 記入例

>\`\`\`
>\<div>
> 　\<h1>Hello World!\</h1>
>\<div>
>\`\`\`

###-- 表示例

```
<div>
　<h1>Hello World!</h1>
<div>
```

#参照
[Markdown 記法 チートシート](https://tech.recruit-mp.co.jp/docs/markdown/)
[かんたんMarkdownの記法](https://tatesuke.github.io/KanTanMarkdown/syntax.html)
[Markdown–Wikipedia](https://ja.wikipedia.org/wiki/Markdown)
ds9 command line options

```bash:ds9-2det.sh
im1=$1
im2=$2

ds9='/Applications/SAOImageDS9.app/Contents/MacOS/ds9'

# fimgbin $im $imR ${rebin}                                                                                                       

zoom=1
lm1=0.01
lm2=10
opt1="-zoom to ${zoom} "
geo="-geometry 1718x1122+55+2"
scale="-scale log"
#limit="-scale limits $lm1 $lm2"                                                                                                  
# reg="-regions load $reg_file"                                                                                                   
#cmap="-cmap b"                                                                                                                   
cmap="-cmap gray -cmap invert yes"
ps=test1.ps

ds9X="ds9$$"

echo $ds9

opt_i="$cmap $scale $limit"
                                                                      
$ds9 -title $ds9X $opt1 $geo $im1 ${opt_i} $im2 ${opt_i}    
```
WindowsからUbuntuに切り替えて便利だったこと、不便だったこと

今回は、Windows10からUbuntu18.04に切り替えて「便利だったこと」、「不便だったこと」を書きました。
切り替えたというか、デュアルブートでPCのOSにUbuntuを追加し、開発にはUbuntuを使うようにしました。

PC：Panasonic  Let's note
機種によって設定方法が違うらしいです。

# 不便だったこと
### 明るさ変更
明るさ変更できなかったので、こちらの記事を参考にしました。
http://tkyma.hatenablog.jp/entry/2015/10/24/012902
（2016/07/25 追記2）の部分

あと、充電器を挿したら勝手に明るさが1番暗くなってしまいます。

### かな変更とキーボードレイアウトの設定
かな変換も不便だったので、自分で設定変更。
**Mozc**をインストールし、
- 「変換」キーで日本語かな(Mozc)
- 「無変換」キーで日本語英数字(Mozc)

に変更できるようにしました。
あとは、
「設定 ⇒ 地域と言語」
で英語を追加しました。
「Start + Space」で切り替えられます。

![Qiitaかな設定.png](https://qiita-image-store.s3.amazonaws.com/0/298112/a3e639ac-8fcc-0e9f-82d1-905a6a3e7e04.png)

キーボードのレイアウト変更も必要です。
おそらく、USキーボードのレイアウトになっているのか、「@」などが変な位置にいっている。
「Shift + ...」で打つ文字が1個ずつ右にずれてた。
[キーボードレイアウト変更](https://qiita.com/jimaz/items/af134896483ae9d32a7d)
こちらで解消されましたが、一度シャットダウンすると元に戻ってしまう問題が発生。
[キーボードレイアウトの設定が初期化されてしまう問題](https://ja.stackoverflow.com/questions/43015/ubuntu%E3%82%92%E8%B5%B7%E5%8B%95%E3%81%99%E3%82%8B%E3%81%9F%E3%81%B3%E3%81%AB%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E3%83%AC%E3%82%A4%E3%82%A2%E3%82%A6%E3%83%88%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%81%8C%E3%83%AA%E3%82%BB%E3%83%83%E3%83%88%E3%81%95%E3%82%8C%E3%82%8B)
こちらで解決できました。

### ホイールパッド
Windowsでは、上下にスクロールするために、ホイールパッドを回転させていました。
しかし、Ubuntuでは反応しません。
**2本指スライド**でスクロールします。

### 音量
```zsh
alsamixer
```
で変更できましたが、イヤホンからは音出るけど、スピーカーからは音が出ない。

### 日付と時刻の設定
Windowsを起動した時、たまに時間が9時間ずれる(ロンドンの時間になる)。

### Microsoft Office などの便利なアプリが使えない
WordみたいなのとかペイントとかがUbuntuに用意されているが、
個人的には、WindowsのOfficeのほうが使いやすい。
代用で、スクショは「Shutter」というアプリを、ペイントは「Pinta」を使っています。

# 便利だったこと
### 作業スペースが複数ある
**Ctrl + shift + Alt**：新しい作業スペースに今のページを移動させる
**Ctrl + shift**：作業スペースを移動させる

### Windowsのファイルにもアクセスできる
OSが違っていても、アクセスできる。
Windows 👉 Ubuntu は、ファイル参照できない。

### いろんなアプリを使える
Windowsでは使えなかった、Dockerなどを使える。
プログラマーには必須な機能が楽に実装できて素晴らしい。
VS Codeからqfixhowmを起動する

# QfixHowmを使いたい
- [VIMとVSCodeを行ったり来たり移動する](https://qiita.com/hogedeath/items/6231755248a94f8eb9eb)
  を書いてから早半年、やっぱりVSCodeからQfixHowmを使いたい
    - よくよく考えると、QfixHowmルールで新規メモが作りたい
    - 調べるとVS CodeでShell実行できる
    - qfixhowmのソースを見ると、call qfixmemo#EditNew()を呼べばよさげ

## ツール
- [VS Code](https://code.visualstudio.com/)
- [vim](https://www.kaoriya.net/software/vim/)
- [qfixhowm](https://sites.google.com/site/fudist/Home/qfixhowm) 

## 検証
- vim起動Optionでqfixhowmを叩く

```bash
vim -c "call qfixmemo#EditNew()"
```

## VIM側
- いけそうなので、前回記事を使いまわし「保存->閉じる->VSCODEオープン」をするVimScript準備
    - (qfixhowmで開いたあと、保存することでVIMを閉じたいだけです。)

```vimscript

"open vscode"{{{
if has('win32')
  nnoremap <silent> <leader>v :<c-u>call <SID>OpenVSCode()<CR>
  function! s:OpenVSCode()
    " target file
    let l:targetfile  = expand("%:p")
    let l:lastfolderid = strridx(targetfile,"/")
    let l:targetfolder = l:targetfile[0:l:lastfolderid]
    " command line
    "let l:cmd = '!code ' . l:targetfolder
    let l:cmd = '!code ' . l:targetfile
    silent execute 'write'
    silent execute 'quit'
    silent execute l:cmd
  endfunction
  command! -nargs=0 OpenVS call s:OpenVSCode()
endif
"}}}

```
## VS Code側
- [参考:Visual Studio Codeでキーボードショートカットに外部コマンドを割り当てる](https://qiita.com/sakano/items/685b6a15dd600ccd34bd)
- Ctrl+Shift+p -> Task:Configure Task ->tasks.json -> Other
- VIM起動optionは複数記載可能なので、それを利用してScript側のOpenVSまでを呼び出す
 
```json
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "qfixNewMemo",
            "type": "shell",
            "command": "vim",
            "args": ["-c call qfixmemo#EditNew()","-c w","-c OpenVS"]
        }
    ]
}
```

### VS Codeショートカット
- 作成したTaskをショートカット登録

```
// Place your key bindings in this file to override the defaults
[
  {
    "key": "Ctrl+n",
    "command": "workbench.action.tasks.runTask",
    "args": "qfixNewMemo",
  }
]
```

#### Ctrl+Nを実行すると、QfixHowmで新しいメモを作成して、VSCodeで開きなおします。
動的→静的リダイレクトさせようとしてクエリストリング（クエリパラメータ）の取り扱いではまった。


NetCommons2 で作成された動的サイトをアーカイブのためにwgetで静的サイトに変換したあとに元の動的URLから静的ファイルへのリダイレクトを設定中にクエリストリングのとりあかいではまってしまいました。

最初にかいてたのは下記の様な感じ。

```.hatccess
RewriteEngine on
RewriteBase /
RewriteRule ^(|index.php)\?(.+)$ index.php@$2.html [R=301,L]
```

index.php?page_id=100 とかにアクセスがあったら index.php@page_id=100.html にリダイレクトされることを想定してたんですが、全然リダイレクトされません。

で、ぐぐってみたらRewriteRuleの転送元にクエリストリングは含まれないんですね。

かわりにRewriteCondを使ってくれと言うことのようです。



```.htaccess
RewriteEngine on
RewriteBase /
RewriteCond %{QUERY_STRING} ^(.+)$
RewriteRule ^(|index.php)$ index.php@%1.html [R=301,L]
```

これで目的のファイルにリダイレクトされるようにはなったんですが、もうひとつ問題が。
リダイレクト先にクエリストリングがくっついたまま index.php@page_id=100.html?page_id=100 というURLに…

リダイレクト先にクエリストリングをつけたくない場合は末尾に "?" を追加するといいようなので最終的には下記の様になりました。

```.htaccess
RewriteEngine on
RewriteBase /
RewriteCond %{QUERY_STRING} ^(.+)$
RewriteRule ^(|index.php)$ index.php@%1.html? [R=301,L]
```
vim入力モードでCtrlキーを使ったショートカット（コマンドライン編集）


参考用に。

Vim で使える Ctrl を使うキーバインドまとめ - 反省はしても後悔はしない
http://cohama.hateblo.jp/entry/20121023/1351003586

インサートモードで、`delete` （カーソルの右の文字を削除する）の役割をするコマンドが見つからない。。。
軽量JREでUnsupportedCharsetExceptionが発生した時の対処法

# 概要

[配布用の軽量JREの作り方](https://qiita.com/Targityen/items/8a136eb4792f669a1122)の記事でも紹介していますが、Java 9 以降では必要最低限のモジュールで構成された軽量JREを作ることができます。

JDKに付属の `jdeps` コマンドで軽量JREに含めるべき依存モジュールを知ることはできますが、作成した軽量JREでアプリを実行してみると以下の例外に遭遇することがあります。

```java
UnsupportedCharsetException: EUC-JP
```

これはサポート外の文字コードを指定した場合に発生する例外となります。軽量JREではない通常のJDKでは発生していない例外ですが、`jdeps` コマンドで示された必要最低限のモジュールは含んでいるはずですが例外が発生してしまっています。
つまり、`jdeps` コマンドだけでは軽量JREに含めるべきモジュールが不十分ということになります。

本記事では軽量JREを使う際に上記の例外を回避する方法についてご紹介します。

# なぜ例外が発生するのか

`EUC-JP` などの拡張文字コードは `java.base` モジュールに含まれていないためです。

ちなみに、JDK9 の `jdk.charsets` モジュールの [Javadoc](https://docs.oracle.com/javase/jp/9/docs/api/jdk.charsets-summary.html) には以下のような記載があります。

> java.base (主に2バイト文字とIBM文字セット)にないcharsetsを提供します。

つまり、日本語の文字コードセットは `jdk.charsets` モジュールを追加で指定する必要があるということです。
Java のソースコード内で以下のように `Charset.forName` メソッドなどを使用して文字コードを指定していると、`jdeps` コマンドでは `jdk.charsets` モジュールは表示されないため、軽量JREを作る際は注意が必要となります。

```java
Charset.forName("EUC-JP")
```

# 対処法

`jlink` コマンドで軽量JREを作る際に `jdk.charsets` モジュールを含めることで拡張文字コードが扱えるようになります。

```bash
jlink --compress=2 --module-path ../jmods --add-modules java.base,jdk.charsets --output jre
```
Windows Subsystem for Linux の Ubuntu 18.04 LTS で俗に言う「今さら聞けない・・・」を調べやすくしてみる

Windows Subsystem for Linux (WSL) をちょこっとした調べ物用途で使うようにしてみましょうというお話。man を Windows 10 上でこっそり開いて難を切り抜けましょう:relaxed:

Windows 10 Version 1809 で確認。WSL をインストールして立ち上げるまでについては、いっぱい記事が出てるようなので割愛です。親切な記事がいっぱいありますね。
<img width="498" alt="スクリーンショット 2019-03-05 10.46.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/371960/dc5855b4-a179-104d-78f8-55c91cb64492.png">


### 1. Ubuntu Japanese Team のレポジトリを追加して、日本語関連のモジュールを落としやすくする
→[Ubuntuの日本語環境](https://www.ubuntulinux.jp/japanese)

```
wget -q https://www.ubuntulinux.jp/ubuntu-ja-archive-keyring.gpg -O- | sudo apt-key add -
wget -q https://www.ubuntulinux.jp/ubuntu-jp-ppa-keyring.gpg -O- | sudo apt-key add -
sudo wget https://www.ubuntulinux.jp/sources.list.d/bionic.list -O /etc/apt/sources.list.d/ubuntu-ja.list
sudo apt update
```

### 2. 日本語のパッケージを入れる

```
sudo apt-get install language-pack-ja-base language-pack-ja
```

### 3. ロケールを変更する

```
sudo update-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
source /etc/default/locale
```

### 4. man の日本語ページを入れる

```
sudo apt-get install manpages-ja manpages-ja-dev
```

### 5. 結果がどうなったか確認してみる
a: nano を立ち上げてみる (終了は [Ctrl] + [x])

```
nano
```
下部のメニューが日本語になってますね:clap_tone1:
<img width="979" alt="スクリーンショット 2019-03-05 10.28.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/371960/a18c855b-25e9-274d-4215-2a81ec78c445.png">

b: man を開く

```
man cp
```
「今さら聞けない・・・」がこれでちょっとは解消されるかも。
<img width="991" alt="スクリーンショット 2019-03-05 10.40.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/371960/aa895bc6-286b-5e6c-4ccb-55356713e59b.png">
動画のストリーミング技術について初歩的なことをまとめた

## モチベーション

仕事で動画技術を扱うことになったので学習のために情報をまとめます。

## ストリーミング

動画のファイルサイズは一般的に大きく、全てダウンロードしてから再生するのではユーザーの待ち時間が増えてしまいます。
またライブ配信を実現するためにも録画が完了していない状態で動画の再生ができなければなりません。
これを解決するために、ダウンロードと再生を並行する「ストリーミング」という方式があります。
と、一口にいってもどのようにダウンロードして再生していくかルール（プロトコル）が必要です。
その代表的なプロトコルがHLSとMPEG-DASHになります。

## HLSとMPEG-DASH

どちらもHTTP通信を軸としたストリーミング技術ですが、開発している企業が異なります。

- HLS
    - HTTP Live Streaming
    - 開発: Apple
    - 仕様: IETF
        - https://datatracker.ietf.org/doc/rfc8216/
- MPEG-DASH
    - MPEG-Dynamic Adaptive Streaming over HTTP
    - 開発: DASH-IF(DASH-Industry Forum)
        - https://dashif.org/
        - 参加企業(順不同): Microsoft, Netflix, Google, Ericsson, Samsung, Adobe
    - 仕様: ISO
        - https://mpeg.chiariglione.org/standards/mpeg-dash


## HLSとMPEG-DASHの対応状況

いくらかのブラウザはこれらのプロトコルに対応しています。

### HLS

https://caniuse.com/#feat=http-live-streaming
2019/03/05時点では主要なところで、Edge, Safari, iOS-Safari, Android Browserが対応しているようです。
当たり前ですがApple主導なので、きっちり対応されています。

### MPEG-DASH

https://caniuse.com/#search=mpeg-dash
2019/03/05時点ではEdgeのみ対応という状況でした。

## HLS vs MPEG-DASH

実際のプロトコルの内容はまた別の機会に調べるとして、どちらがどういった点で優れたり異なっているのか気になります。
調べてみて大きな違いを感じたのは、CodecとDRMの差でした。

### Codec

動画ファイルはサイズを小さくするために圧縮技術が使われています。
圧縮アルゴリズムのことをコーデックといいます。
動画の場合、映像と音声の２つからなるため映像についてはVideo Codec, 音声についてはAudio Codecとわけて考えます。

この２つでHLSとMPEG-DASHを比較すると以下のようになります。（2019/03/05時点での情報です）

|   |Video Codec|Audio Codec|
|---|----|----|
|HLS|H.264, H.265|AAC, MP3|
|MPEG-DASH|縛りなし|縛りなし|

HLSもMPEG-DASHもストリーミングに関するプロトコルなので、別途ビデオプレイヤー自体が各Codecに対応している必要があります。
それでもHLSにCodecの制限があるというのは、何か事情がありそうです。（ここは別の機会に調べてみることにします）

### DRM

Digital Rights Managementの略でDRMで、デジタル著作権管理技術のことを指します。
HLSとMPEG-DASHの違いを調べるとDRMのことが話題に上がっていましたが、最近ではその差も少なくなっているように感じました。
（プロトコルの問題なのか、プレイヤーの実装の問題なのか、そのあたりの深いところにはたどり着けませんでした）
一応メインで使われる組み合わせとしては、間違ってないと思われるので表にまとめます。

|   |DRM|
|---|----|
|HLS|Fairplay|
|MPEG-DASH|Widevine, PlayReady|

## まとめ

HLSとMPEG-DASHというストリーミング技術に触れてみましたが、まだまだ浅い部分しか調べられてません。
次はHLSとMPGE-DASHの違いを実際やりとりするデータを軸に調べてみたいと思います。
Ruby と Python は似ているというけれど、設計思想レベルで見るとめちゃめちゃ違う

RubyもPythonもスクリプト言語ですし、確かに似ている部分はあります。

しかし、"設計思想"レベルで見てみると大きく違っています。

その違いがとてもおもしろいので紹介したいと思います。

## Rubyは自由を好み、Pythonは統一を好む

簡単に言ってしまえば、Rubyは自由を好み、Pythonは統一を好みます。

Pythonはインデントによるdefなどの範囲指定が特徴的ですが、Rubyにはそのような制約はありません。

というのも、
**Rubyは「書きたいように書く」というような自由な設計思想**があるからです。

それに対し、
**Pythonは「誰が書いても同じようなコードになる」というような、統一感を好む設計思想**になっています。

---

このような設計思想を知っていれば各言語の細々とした違いも理解しやすくなります。

他の言語も調べてみると面白いかもしれないですね。
【Alexaスキル】ダイアログモデルのスロットの検証をLambdaでやる

## はじめに
アレクサスキル開発中に受け取ったスロットの検証をしたい場面があり調べました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/206219/1447cda8-224e-6fe0-7792-312f224816a2.png)

このインテントでは{option}スロットが必須の項目となっています。
ユーザーは【水】と【コップ】を頼むか、【水】だけ頼むかの選択肢があります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/206219/7a001708-4b51-bc48-2b5b-37c5ce8b44d8.png)
{option}なしでインテントが呼び出された場合、アレクサは【コップ】も注文するか聞き返します。

スロットのバリエーションは以下です。
※ここに【コップ】も入っちゃてるのがイケてません。いい方法があればコメントください。。。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/206219/9d5f1a39-69eb-7e4b-3e9a-2246bf1a2130.png)

## alexa developer consoleで検証ルールを設定したが。。。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/206219/9f6243f5-500e-f069-0123-a8bed41633af.png)

テストしてみると、、、
![図1.png](https://qiita-image-store.s3.amazonaws.com/0/206219/c5cd3654-bad8-1302-85ea-f4cdf3f673af.png)

２回想定外の回答をするとスキルが強制終了してしまいました。
今回のスキルではユーザーの正しい回答があるまで何度も聞き返してほしかったので困ります。

## Lambdaで検証してユーザーに応答を促す
やっと本題です。
Alexa側の検証を外してしまい、Lambda側で検証を行います。

```javascript
const OrderIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'OrderIntent';
  },
  handle(handlerInput) {
    const { slots } = handlerInput.requestEnvelope.request.intent;

    if (slots.option.resolutions["resolutionsPerAuthority"][0]["status"]["code"] != 'ER_SUCCESS_MATCH') {
      return handlerInput.responseBuilder
        .speak('答えは「はい」か「いいえ」でお願いします。キャンセルする場合は「キャンセル」と言ってください。')
        .addElicitSlotDirective('option')
        .getResponse();
    }
    const option = slots.option.resolutions["resolutionsPerAuthority"][0]["values"][0]["value"]["id"];
    // 本来の処理は省略
    return handlerInput.responseBuilder
      .speak('ご注文を承りました。')
      .withShouldEndSession(true)
      .getResponse();
  }
};
```

まず`slots.option.resolutions["resolutionsPerAuthority"][0]["status"]["code"] != 'ER_SUCCESS_MATCH'`でスロットに入った単語が想定しているバリエーションの同義語かどうか判定します。
ユーザーに再度発話を促すには`.addElicitSlotDirective('option')`を呼び出します。
`option`はスロット名です。

また、同義語でIDを設定している場合は`slots.option.resolutions["resolutionsPerAuthority"][0]["values"][0]["value"]["id"]`で一意のIDを取得できるのでいろいろな言い回しが想定される場合は便利です。

これで何度でもユーザーに発話を促すことができました！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/206219/a3b3f7c4-b7b8-4690-9a60-ed8e3a3034f5.png)


## おわりに
もっときれいな形がありそうですがとりあえずは実現したいことができました。
これからもっとガンガン触っていこうと思います。
Pandasでデータを操る。重複した行のみを残したい編

# Introduction

ここに以下のような実験データ(test.tsv)があります。

![スクリーンショット 2019-03-05 9.36.17.png](https://qiita-image-store.s3.amazonaws.com/0/335400/ea8fe5b3-c6a5-2eda-8ccd-204c0c019100.png)

このデータをよく見てみると、POS列に同じ値が入っている箇所がいくつかあることがわかりました。今後はこれに注目してデータ処理を行いたいと思ったため、POS列で重複した箇所だけを抽出するスクリプトがほしい、というのが今回のお題です。この例ではPOSの値が865545, 874671, 874826が重複しているので、その部分さえぬき出せればよいということになります。

# .duplicated()

ズバリ、今回の願いを叶えるスクリプトは以下のようになります。

```python:test.py

'''
    test.py
'''
import pandas as pd


# read data
data = pd.read_csv('test.tsv', delimiter='\t', index_col=0)

# delete non-overlapping row
data2 = data[data.duplicated(subset='POS', keep=False)]

# write to excel
data2.to_excel('test.xlsx')
```

そして結果は以下のようになります。

![スクリーンショット 2019-03-05 9.51.06.png](https://qiita-image-store.s3.amazonaws.com/0/335400/8f5e562d-aca0-64d2-10d3-4d3ee9d16d3a.png)

## subset 引数

.duplicated()の引数subsetに重複を判定したい列名を指定しています。試しに以下のコマンドを実行してみましょう。

```python
print(data.duplicated(subset='POS', keep=False))
```

結果は以下のようになります。

```
#CHROM
chr1    False
chr1    False
chr1     True
chr1     True
chr1    False
chr1    False
chr1    False
chr1     True
chr1     True
chr1    False
chr1    False
chr1    False
chr1    False
chr1     True
chr1     True
dtype: bool
```

POS列で重複している行全てがTrue, それ以外がFalseとなっていることがわかります。もし、POS列だけでなくREF列の重複も判定したい場合は

```python
data2 = data[data.duplicated(subset=['POS', 'REF'], keep=False)]
```

のようにsubsetに列名のリストを渡してあげます。

## keep引数

では.duplicated()のもう一つの引数であるkeepはどのように使うのでしょうか。
今度は試しに

```python
print(data.duplicated(subset='POS', keep='first'))
```

としてみます。すると結果は

```
#CHROM
chr1    False
chr1    False
chr1    False
chr1     True
chr1    False
chr1    False
chr1    False
chr1    False
chr1     True
chr1    False
chr1    False
chr1    False
chr1    False
chr1    False
chr1     True
dtype: bool
```

となります。keep='first'とすると、重複した行の中でも最初に見つけた行がFalseとなります。keep='last'とすれば、逆に重複した行の中でも最後に見つけた行がFalseとなり、

```python
#CHROM
chr1    False
chr1    False
chr1     True
chr1    False
chr1    False
chr1    False
chr1    False
chr1     True
chr1    False
chr1    False
chr1    False
chr1    False
chr1    False
chr1     True
chr1    False
dtype: bool
```

となります。今回の場合、keep=Falseを指定することで、重複した行全てをTrueとして残しています。
AWS FARGATE タスクの終了時に終了直前付近のログがcloudwatchに送られない

# 詳細
ECSのコンテナ内で処理の重いs3 syncコマンドを発行
Cloudwatchログを確認したところ、終了メッセージ付近のログが欠ける現象が発生

# 原因
### AWS側の障害(FARGATEの挙動)
AWS FARGATE タスクの終了時に終了直前付近のログがcloudwatchに送られない
※2019/03/05現在

# 対策
タスク内の処理終了前に 10 秒から 15 秒ほど sleep 処理を入れる
・・・らしい(AWS回答)ですけど、これは課金額があがるのでは・・・