OmniAICreator/Qiita-1.07M huggingface dataset:
CodeDeploy

#CodeDeploy コンピューティングプラットフォームの概要
* EC2/オンプレミス
* AWS Lambda
* Amazon ECS

##CodeDeploy デプロイタイプの概要
* インプレイスデプロイ
    * デプロイグループの各インスタンス上のアプリケーションが停止され、最新のアプリケーションリビジョンがインストールされて、新バージョンのアプリケーションが開始され検証されます。ロードバランサーを使用すれば、各インスタンスがデプロイ中に登録解除され、デプロイ完了後にサービスに復元されるようにすることができます。インプレイスデプロイは、EC2/オンプレミス compute platform を使用するデプロイでのみ使用できます。
* Blue/Green デプロイ
    * EC2/オンプレミス compute platform の Blue/Green
        * デプロイグループのインスタンス (元の環境) がインスタンスの別のセット (置き換え先環境) に置き換えられます。
    * AWS Lambda compute platform の Blue/Green
        * トラフィックは、現在のサーバーレス環境から、更新された Lambda 関数のバージョンの環境に移行されます。検証テストを実行する Lambda 関数を指定し、トラフィックの移行が発生する方法を選択できます。AWS Lambda compute platform のデプロイはすべて、Blue/Green デプロイです。
    * Amazon ECS compute platform の Blue/Green
        * トラフィックは、Amazon ECS サービス内のアプリケーション元のバージョンのタスクセットから、同じサービスの置き換えタスクセットに移行されます。デプロイメント設定を使用して、トラフィックの移行を線形または Canary に設定できます。指定されたロードバランサーリスナーのプロトコルとポートは、本稼働トラフィックを再ルーティングするために使用されます。デプロイ中、テストリスナーは、検証テストの実行中に設定された置換タスクセットにトラフィックを配信するために使用することができます。
            * 線形
                * トラフィックを毎回、同じ増分、同じ間隔 (分) で移行します。事前定義された複数の線形オプションから選択し、増分ごとに移行するトラフィックの割合 (%) と増分間の間隔 (分) を指定できます。
            * Canary
                * トラフィックを 2 回の増分で移行します。事前定義された複数の Canary オプションから選択し、最初の増分および間隔でトラフィックを更新済みタスクセットに移行する割合 (%) を分単位で指定できます。次に 2 回目の増分で残りのトラフィックを移行します。
OpenSeadragonでフルスクリーン時に強制的にControlを消す方法

OpenSeadragonでフルスクリーン時にControlを消す方法が見つからなかったのでソースを調べてやってみた。

似たような質問があったが構成が変わったのが動作せず
https://github.com/openseadragon/openseadragon/issues/1304

```ts
import { Viewer } from 'openseadragon'
export class CustomOpenSeadragon {
    public viewer: any
    public constructor() {
        //適当
        const init: any = {
            id: 'hogediv',
            tileSources : getHogeTileUrl
            }
        }
        this.viewer = new Viewer(init)
        this.viewer.addHandler('full-screen', (e) => {
            this.viewer.controls[0].autoFade = !e.fullScreen
            this.viewer.controls[0].container.style.opacity = String(Number(!e.fullScreen))
        })
    }
}
```

Controlが表示されている状態でフルスクリーンボタンを押すと、Viewerのfull-screenイベントが発火され、フルスクリーン状態を示すBooleanであるeventSource.fullScreenを読み取り、自動フェードアウトフラグとコンテナのopacityに代入させるというもの。

!をつけて代入することでイベント発生ごとにtoggleできる
【GCP】関連記事まとめ

# 各サービス紹介
https://clonos.jp/knowledge/detail04/


# 構築例
https://clonos.jp/knowledge/detail03/
https://clonos.jp/knowledge/detail02/

# GCPのインフラ
https://clonos.jp/knowledge/detail11/

# 他社クラウドとの比較
https://clonos.jp/knowledge/detail12/

# セキュリティ規格
https://clonos.jp/knowledge/detail13/

# 価格
https://clonos.jp/knowledge/detail17/
ローカライズファイルをAndroidとiOSで共通管理する

## はじめに
AndroidとiOSでサービスを展開している場合、同じ文言を使っている。
プラットフォームごとに管理することで文言の誤字が発生しやすく、コストも上がる。
ローカライズファイルを効率よく管理する方法を考えました

## 前提条件
- AndroidとiOSで共通のリソースを扱う
- 差分を追いやすいこと

## githubを使って管理
- オリジナルデータとなる文言とkeyはjsonにして管理
- githubを使うことで差分を追いやすくなる
- CIを使うことで自動化できる

## ローカライズファイルを更新するツール
- JSONからローカライズファイルを生成するのを簡単にするためにツールを作成した
- [t-osawa-009/JSONToString](https://github.com/t-osawa-009/JSONToString)

### 使い方
1.オリジナルデータとなるJSONファイルを追加

```json
[
    {
      "key": "hoge",
      "key_android": "hoge",
      "key_ios": "hoge",
      "value_android": "hoge",
      "value_ios": "hoge"
    },
]
```

2.ローカライズファイルの生成を設定する`.JSONToString.yml`ファイルを追加

```yml
outputs:
  - key: key
    value_key: value_ios
    output: Strings/Localizable.strings
    format: strings
    sort: asc
  - key: key
    value_key: value_android
    output: Strings/strings.xml
    format: xml
```

3.コマンドを実行

```sh
$ JSONToString --json_path Strings.json
```
4.生成したファイルを各プロジェクトに追加する

```
"hoge" = "hoge";
```

```xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hoge">hoge</string>
</resources>
```

## まとめ
- githubで管理することで1元管理が可能になった
- 運用を考えて、ツールを自作するのは有効である

## 参考リンク
- [Pairs Global iOSでのクールな多言語管理](https://medium.com/eureka-engineering/pairs-global-ios%E3%81%A7%E3%81%AE%E3%82%AF%E3%83%BC%E3%83%AB%E3%81%AA%E5%A4%9A%E8%A8%80%E8%AA%9E%E7%AE%A1%E7%90%86-b91010b063cb)
TypeScriptのジェネリック型制約とデフォルト型

```typescript
type SomeType<T extends object = any> = {
  value: T;
};
```

使おうと思って調べていたライブラリの`d.ts`ファイルを見ていたらこんな感じの型があった。読み方がわからなかったので調べた。

## extends

まずは`<T extends object>`。ジェネリックで`extends`を使うことによって、`T`がとれる型の範囲を決めます。下記の例では、`T`が`object`で`extends`されているので、`T`は`object`型、または`object`のサブクラス型を取ることができます。

```typescript
type SomeType<T extends object> = {
  value: T;
};

const hoge1: SomeType<object> = {
  value: { value: "object" },
};
// => ok

const hoge2: SomeType<string[]> = {
  value: [],
};
// => ok

const hoge3: SomeType<string> = {
  value: "record",
};
// => Type 'string' does not satisfy the constraint 'object'.

```

`array`は`object`のサブクラスなので利用できますが、`string`はサブクラスでないので使えません。

ちなみに型のヒエラルキーはこのようになっています。

![prts_0301.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34733/eff5d28d-17b2-cbaa-12c5-2e964cc48f44.png)

*[3. All About Types - Programming TypeScript Book](https://www.oreilly.com/library/view/programming-typescript/9781492037644/ch03.html)*

## デフォルト型

次にジェネリックのデフォルト型について見てみます。

```typescript
type SomeType<T = object> = {
  value: T;
};

const hoge1: SomeType = {
  value: { value: "object" },
};
// => ok

const hoge2: SomeType<object> = {
  value: { value: "object" },
};
// => ok

const hoge3: SomeType<string> = {
  value: "string",
};
// => ok
```

ジェネリックのデフォルト型を設定しておくと、`hoge1`のように型利用時にジェネリック型を明示的に指定しなくても推論してくれます。デフォルト型は`object`になっていますが、`extends`で制約されているわけではないので、`string`型も指定できます。

# extends とデフォルト型
最後に冒頭に書いた型について。`extends`で型を制約しつつ、デフォルト型を設定する場合、変数設定時等でジェネリック型を明示的に指定した際に制約が課され、指定しない場合はデフォルト型が適応されます。


```typescript
type SomeType<T extends object = any> = {
  value: T;
};

const hoge1: SomeType = {
  value: "string",
};
// => ok

const hoge2: SomeType<string> = {
  value: "string",
};
// => Type 'string' does not satisfy the constraint 'object'.

const hoge3: SomeType<string[]> = {
  value: [],
};
// => ok

```

`hoge1`はジェネリック型を明示的にしていないため、`T`が`any`型になりますが、`hoge2`は明示的に`string`を指定しているため、`extends object`の制約でエラーになります。
ビデオチャット中に左シフトキーを押している間だけミュート解除し会話できるアプリをつくった

Google MeetやZOOMでビデオチャットをしているとき、マイクに雑音が入らないよう自分の発言中以外は基本的にミュートしているのですが、
ミュート解除を切り忘れたり、別画面を開いているとすぐにミュート解除できなかったりで、面倒だったのでキーボードの特定のキーを押している間だけミュートを解除してくれるアプリ「[**Cough Switch**](https://github.com/narikei/cough-switch)」を作成しました。

トランシーバーやレコーディングスタジオのトークバック機能のようなイメージです。

![output2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7132/1b083795-2d17-8c44-7aba-b3ffbdbb9788.gif)


## AppleScriptでマイクの音量を操作する
Macの場合、 `システム環境設定 > サウンド > 入力` でマイク設定を操作することができます。
この入力音量を0にするとミュートされます。

<img width="780" alt="スクリーンショット 2020-05-28 11.51.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7132/36fa3b22-6bad-3bad-95c7-e3214f426148.png">

```applescript:applescript
tell application "System Events" to set volume input volume 100
```

このスクリプトをjsから実行するにはこんな感じ

```javascript:javascript
const applescript = require('applescript');
applescript.execString('tell application "System Events" to set volume input volume 100', function);
```


## `iohook`ですべてのキーボードイベントを取得する
さくっと作りたいのでまたElectronで簡単にアプリ化していきます。

Webのいつも通りにキーボード操作を取得しようと、
`document.addEventListener("keydown", function)`
としてしまうと、Windowがアクティブになっていないとキーボードイベントを取得できません。


`electron.globalShortcut`では`keyup`イベントを取得できないので却下。


他に探してみたところ[iohook](https://github.com/wilix-team/iohook)ってやつで取得できるみたいです。
（特定のバージョンのNodeとElectronしかサポートしていないらしくちょっとはまった）

```javascript:javascript
const iohook = require('iohook');

const KEYCODE = 42; // left shift key

iohook.on('keydown', (msg) => {
  if (msg.keycode === KEYCODE) {
    talk();
  }
});

iohook.on('keyup', (msg) => {
  if (msg.keycode === KEYCODE) {
    mute();
  }
});
```

どのキーに割り当てるか悩みましたが２つあるので、左シフトキーにしました。


## Electronの最前面の触れない透明なWindowを作成
ミュート解除中のアイコンを表示させるために、最前面に触れないWindowを作成します。
さらに邪魔にならないよう背景を透明にします。

```javascript:javascript
const appWindow = new BrowserWindow({
  transparent: true,
  frame: false,
  resizable: false,
  alwaysOnTop: true,
});

appWindow.setIgnoreMouseEvents(true);

appWindow.loadURL(`file://${__dirname}/index.html`);
```

これで最前面にHTMLが表示されます。
あとはキーボードイベントに応じて、Windowへ状態を送り、CSSでアイコンを表示させます。

```javascript:javascript
appWindow.webContents.send('talk');
```


## おわり

あとは前にやった [MacBook Proの充電器の情報をメニューバーに表示するElectronアプリをつくった](https://qiita.com/narikei/items/aaee2c7e7e1a5ae61015) と同様にアプリケーション化して完成です。


![icon_512x512.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7132/af579437-df68-2d50-7889-6844eac6ccb6.png)

[ソースコードはこちら（https://github.com/narikei/cough-switch）](https://github.com/narikei/cough-switch)



## おわりのおわり
デフォルトだとスピーカーの設定しかできないけど、
こういうときこそタッチバーの出番なのではないかな？
バックグラウンドのアプリでタッチバーを使えないのどうにかしてほしい。
Androidアプリが非SDKインターフェースを使用していないか調べる方法

# その1

分かりやすい方法としては、対象のOSをエミュレーターで起動しアプリのすべての操作を実施して以下のようなログが表示されていないか確認する方法がある。
この方法であれば発生箇所がある程度予測できるし、非SDKを使用してはならないなどの要件にも対応しやすい。

```
Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)
```

# その2
[veridex](https://android.googlesource.com/platform/prebuilts/runtime/+archive/master/appcompat.tar.gz) を使用した方法もあります。
veridexをダウンロードし、以下のコマンドを実行するとgraylistな関数などの利用場所や利用数を教えてくれます。

```
./appcompat.sh --dex-file=/path-from-root/your-app.apk
```

参考
https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces#test-for-non-sdk
iOS,Androidのheightとwidthの値

何回も値を確認することあがあるので自分用にメモする。  

* iPhone11proMax
 * height:896  
 * width:414

* iPhone11pro
  * height:812
  * width:375

* iPhone8
  * height:667
  * width:375

* iPhoneSe
  * height:568
 *  width:320

* GooglePixcel 3XL
  * height:748.8571428571429
  * width:411.42857142857144

自分の場合、ReactNativeで開発をしているので下記サイトを参考に端末のサイズ取得を行ってます.  
https://qiita.com/mogamin3/items/1aad5fd2d03fb54e0dbf  

Dimensionsって便利ですねー
```
const { width, height } = Dimensions.get('window');
console.log("height:"+height);
console.log("width:"+width);
```
Thinned Grid の補間 (rev2)

前回 https://qiita.com/e_toyoda/items/3e7e2c75140f39274b02 の続き。

入力が thinned grid という不規則な場所で与えられていて、しかも全球8分割されて順番無保証で入電するのですが、結果はメルカトル投影面上の全球一枚の正方格子でほしいので、どうにかして拾い集めて補間（あるいはもっと高尚な何か）する必要があります。

# 補間アルゴリズム

素朴に考えたらこんなんなるんでしょう。これで収集と補間が一発でできます。

```
入力電文群.選択(高度、予報時間、要素).each {|電文|
  電文.各格子点 {|格子点, 値|
    出力格子系.各近隣(格子点) {|出力点|
      係数 = 重み関数(距離(格子点, 出力点))
      積算配列[格子点] += 係数 * 値
      重み配列[格子点] += 係数
    }
  }
}
結果 = 積算配列 / 重み配列  #要素毎除算
```

# 整数型で積算できるか (のちに断念)

さてまず考えるのが、メモリをけちりたいので積算配列を16bit整数型にできないでしょうか。ぼちぼち大きな入力電文群に対してワンパスで処理しようと思うと、欲しい結果すべてに対して積算配列・重み配列ペアをもっていなければなりませんから、メモリが心配になります。

もとの情報はせいぜい12ビット程度の深さで整数、結果も整数型と決めています。まずもっていちばん危険そうなのは、重みの合算がゼロまたは非常に小さくなってしまう場合。まあ、それがないように近隣の範囲と重み関数をチューニングするのでしょう。 ... **のちに断念**

# 重み関数形

まあ素朴には最適内挿法とかの関数をつかうのでしょう。

> *Wa* (*d*) = exp[-(*d* / *D*)^2]

重み関数で用いる距離は、球面上の距離にするのが美しいですが、おかしな近似にするくらいなら、メルカトル投影面上の距離のほうが美しいかもしれない、という気がします。

ところがです。この関数は遠くで速く落ちすぎるのです。

スケールとしてたとえば赤道付近のデータ間隔を使う *D* = 138 km としましょう。出力点とぴったり合っている格子点がある場合の重み *Wa*(0)=1 に対して 138 km 離れた格子点の重みは *Wa*(*D*) = 1/e = 0.368 となります。ちょっと周囲に振り回されすぎな気もしますが、ちょっと緯度が上がればまあいい感じでしょう。しかし端のほうでは実に厳しい。ウェブメルカトル図法の北端は 85.051129° ですから縮尺はだいたい 11.5 倍。*Wa*(11.5 *D*) = 3.67e-58 ですから、積算変数を整数にする前節の夢が破れるどころか単精度実数ですら表現できません。まあ、最近接格子点は 6 *D* くらいの距離にあるのだろうから、単精度におさまるだろうけれど。

だからといって関数形をいじるのも悪手で、たとえば exp[-(*d* / *D*)] とすると、熱帯で 2 *D* くらい離れた格子点にふりまわされすぎます（出力が「なまる」）。

まあやっぱり縮尺を意識せざるを得ない。なんか牛刀すぎるんだが。

TBD（もうちょい考える）
hamlでクラス名やid名に変数を使う

アプリ開発中にクラス名にインデックスをつけたいときがあり、書き方が分からずつまづいたので、同じような方がおられましたら参考にしてください。

### 基本
まず、基本的なクラス名id名の書き方は「.」「#」始まりで書き始めます。

```
#クラス名
.item_name
%p.item_name

#ID名
#item_name
%p#item_name
```

###変数を使った書き方
そして今回わたしがつまづいたのはeach文の中で変数名を使った書き方です。
下記の書き方で適用されました！

```
-@items.each_with_index do |item, i|
  %div{class: "#{item.name}"}
    %p{class: "item_name_#{i}"}
```

クラス名を{}で囲うと、適用されます！
each文ではない場合でも同じ書き方で適用されます

```
%div{class: @item.name}
```
【仮想MFA】「Google authenticator」VS「authy」VS「IIJ Smart Key」

@tmknom さんの [BOOTH:クラウド破産を回避するAWS実践ガイド](https://booth.pm/ja/items/1994587)
を購入して色々AWSの基本設定をしていたのですが**MFA**の選定で色々考察したのでメモ程度で書き留めておきます。


## MFAとは
(Multi-factor Authentication)の略のことで日本語に訳すと「多要素認証」になります。要するにSMS認証や指紋認証とかの認証方式を複数組み合わせた総称です。また、二種類の組み合わせで構成されたモノを「二要素認証」とも呼ばれます。基本的には「通常のパスワード」+「SMS認証・メール認証」の構成が一般的だと思われます。しかし、クラウドサーバー(AWS/GCP)やゲームクライアント(steam)などの「ハッキングされたら壮大な被害を受ける」「ハッキングの対象になりやすいサービス」では「通常のパスワード」+「スマホ認証」(知的認証+所有物認証)の構成で多要素認証を実現される傾向にあるみたいです。

## 仮想MFA(スマホ認証)
スマホがあればすぐに導入できコスト面も低いのでよく採用されやすいですが「ハードウェアMFAデバイス(ワンタイムパス)」「U2Fセキュリティキー」の方が常に公的なネットワークに接続されているスマホを使った仮想MFAよりセキュリティ性が高くリスクとコストを比較したとき大規模なサービスほど恩恵が受けやすいと私は考えますが個人開発/小規模なサービスだとコストが見合わない場面の方が多いと思うので大規模サービスでなければ仮想MFAの方が賢明な選択だと思います。なので仮想MFAの導入は個人開発/小規模サービス時の想定で選定していきます。

## 比較

[引用:MFAを「Google Authenticator」 から 「Authy」 に乗り換えました](https://qiita.com/garakutayama/items/33f78c932e817bcb8b22)

|        |Authy|Google Authenticator|IIJ Smart Key|
|:-----------------:|:------------------:|:------------------:|:------------------:|
| シェア|〇|◎|△|
| 検索性|〇|△|〇|
| 複数端末管理/バックアップ|〇|△|△
| PC利用|                〇|         ×|×|
| アプリロック|             〇|       ×|〇|
| 日本語|           ×|      〇|〇|


「Google Authenticator」は最近ローカルなバックアップ機能が追加されたみたいですが未だにクラウドバックアップ機能が実装されないのでおそらくセキュリティ面から考えると今後も実装されないでしょう。しかしその環境だとデバイスの紛失時に対応できません。仮にあらかじめ各種サービスのバックアップコード等を発行してあっても正直手間で復旧作業中は「本当に復旧できるのか？復旧出来なければどうしよう」と思うのは容易に想定でき精神的にも良くありません。なので**デバイス喪失のリスク**と**クラウドによるバックアップのリスク**を考慮したとき前者のリスクの方が大きいです。前述の通りコストがかかってもセキュリティ性を向上させたい状態であれば仮想MFAは向いてないです。これらを踏まえて各種仮想MFAを比較したとき利便性やクラウドバックアップ機能がある「Authy」に軍配が上がります。
【個人開発・忘備録】JenkinsでGitHubの変更検知→自動テスト・結果表示・メール通知

#概要

+ 開発しているmacにJenkinsインストール
+ GitHubを定期的にチェック
+ 変更があればテストを含むビルドを実施
+ テスト失敗時はメール通知
+ テスト結果をJenkinsの画面で確認
 

#環境

+ macOS Catalina 10.15.4
+ Jenkins 2.238
+ JDK 1.8.0_231（build.gradle内のJDKバージョンと合わせる）
+ gradle6.4.1

#ビルド対象
SpringBootで作成したWebアプリ（gradleプロジェクト）。
JUnit4とSeleniedによるテストコードを含む。

#Jenkins初期設定
Jenkisは```brew services start jenkins```で動かしておく。
##メール設定
通知を行う送信元となるメールアドレスの設定をする。
Jenkinsの管理→システムの設定の「Jenkinsの位置」、「Email通知」を設定。Jenkinsからメール操作できるようGmailのセキュリティの設定も済ませておく（[参考]
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250449/db2e1b70-4888-e7ef-11ef-67c796e2cc56.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250449/c8d4fce9-aca4-85f7-5a7a-9751168cd73d.png)


##JDK・Git・gradleのパス設定
Jenkinsの管理→Global Tool Configurationと進み、JDK・Git・gradleの各種パスを通す。
Gitとgradleのパスはこれで良いのか不明。。。
まだわかっていないところがあるがとりあえずは動いた。。。
【メモ】
eclipseでのアプリ作成時はJDK11を使うよう設定したが、なぜかJenkinsでのbuild時にはJDK1.8でビルドしようとし、エラーが起きた。とりあえずはbuild.gradle内のJDKのバージョンを8に設定しなおし対処した。

#ジョブの設定
##ジョブ新規作成
新規ジョブ作成→ジョブの名前入力→フリースタイル・プロジェクトのビルドを選択
![スクリーンショット 2020-05-27 22.27.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250449/57bba6e6-474a-c7c0-85f4-1b58606a56c2.png)

##ジョブの各種設定

+ **ソースコード管理**にGitHubのリポジトリのURLを記載
+ **ビルド・トリガ**は「SCMをポーリング」にし、cronを記載。ここでは5分に一回GitHubを見に行き、変更があればビルドする設定とした。
+ **ビルド**はシェルの実行とし、シェルスクリプト```./gradlew build```を記載。
+ **ビルド後の処理**は「JUnitテスト結果の集計」「E-mail通知」を設定。
![ソースコード管理.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250449/509882a5-311b-a772-8d0f-d1753b234ed4.png)
![ビルドトリガ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250449/9481e38a-41f6-8aae-b357-0405491ec5e9.png)
![ビルド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250449/18ae5098-a5c4-5c60-cdb3-63966ae6a2fb.png)
![ビルド後の処理.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250449/1c6074bb-98c6-f6b2-7013-1c2ca666f332.png)
※JUnitの結果（XMLファイル）の出力先が自分の環境では上記のパスとなっていた。デフォルト？ 

#結果
GitHubに変更があると、ビルドが始まる（変更がなくとも手動でもできる）。今回は全て個人のPC環境であるためアプリを立ち上げておかないと失敗する。
画像はジョブを停止しているのでSのマークがグレーになっているが、ビルドが成功すると青になる。赤は失敗。
![スクリーンショット 2020-05-27 22.09.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250449/dfd5f1e6-4399-e798-41ac-56ce985da15d.png)
![テスト結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250449/b9af953d-6a00-b52b-703e-c71d648fb0e9.png)

#参考
[Jenkins実践入門](www.amazon.co.jp/dp/B07JGWKRZQ)
Mojave環境で最新のXcodeを使う

#最初に
この記事に書かれている方法を実施する場合は、
自己責任で行って下さい。

同意して頂ける場合のみ以下へお進み下さい。

※基本的に未来の自分へのメモです…



#記事執筆時の環境
macOS Mojave 10.14.6
Xcode 11.5
Retroactive 1.7

#Retroactiveとは
Retroactiveを簡単に説明すると、
macOSのバージョンによってサポート外となってしまったアプリケーションを、
使用出来る様にするツールです。

自分の場合は、
最新のXcodeにしないと支障をきたすのですが、
支給されているMacBook Proが古く、
Catalinaにするのはちょっと危険なので、
Retroactiveの力を借りています。

※SwiftUIのコーディングは出来ますが、
  Preview(Canvas)は使用出来ません。

#Retroactiveの入手方法
githubから最新版を[ダウンロード](https://github.com/cormiertyshawn895/Retroactive/releases)して下さい。

#Retroactiveの使用方法
最新のXcodeを入手した状態でRetroactiveを起動し、
起動した画面のXcodeの下にあるUNLOCKボタンをクリックします。

パスワードの入力を求められたらパスワードを入力して下さい。

Xcodeが起動出来たら成功です。

#2020年8月6日追記
Xcodeを11.5から11.6にUpdateする為にRetroactive1.8でUNLOCKしたがXcodeが起動しなかった。
原因はたぶんRetroactiveでUNLOCKをする前に間違ってXcodeを立ち上げてしまい、
macOSのバージョン不一致エラーを発生させてしまったからだと思われる。
アプリケーションからXocdeを削除し、
再インストール後UNLOCKしたら起動した。
【Swift】選択上限のある複数選択可能なTableViewの実装＋スクロールしてもチェックマークがズレないようにする

選択上限をつけた複数選択可能なTableViewの実装が調べても出てこなかったので、簡単に作ってみました。

##### 今回実現したいTableView

1. 複数選択可能
2. 選択状態がスクロールによって他のCellにズレない
3. 選択できる数に上限をつける


[サンプルプログラム](https://github.com/asa08/multiple-select-table)

## 1. 複数選択を可能にする
```MultipleTableView.swift
// tableViewのisMultipleTouchEnabledをtrueにする
isMultipleTouchEnabled = true
```
これだけで複数選択が可能になる。

## 2. 選択状態がスクロールによって他のCellにズレない
`Model`に選択状態を持って、その値を元に`Cell`を`init`する。
（R.swift使っております）

```MultipleTableView.swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(
                         withIdentifier: R.reuseIdentifier.multipleTableViewCell.identifier, 
                         for: indexPath) as! MultipleTableViewCell
    cell.selectionStyle = .none
    cell.kind = kinds[indexPath.row]
    return cell
}
```

```MultipleTableViewCell.swift
var kind: KindModel? {
    didSet {
       accessoryType = kind?.isSelected ?? false ? .checkmark : .none
       initLabel()
    }
}
```

選択状態の`set`は次の **選択できる数に上限をつける** と合わせて紹介します。

## 3. 選択できる数に上限をつける
選択状態に上限をつけるのは、`TableView`に選択数のカウンタをつけるのが1番楽かなと思います。
もっとかっこいい方法はないかと考えたのですが、特に思いつきませんでした。。

```MultipleTableView.swift
var selectedIndex: [Int] = []

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if let row = selectedIndex.filter({ $0 == indexPath.row }).first {
        guard let removeIndex = selectedIndex.firstIndex(of: row) else { return }
        selectedIndex.remove(at: removeIndex)
        kinds[indexPath.row].isSelected.toggle()
        return
    }
    // 今回は上限を3にしました
    if selectedIndex.count > 2 { return }
    kinds[indexPath.row].isSelected.toggle()
    selectedIndex.append(indexPath.row)
}
```
これで上限の管理は完了です！

`didDeselectRowAt` 使いたかったけど、なぜか呼ばれなかった。
SOFにも同じような投稿がありましたが、解決ならずだったので諦めました。。
ChromiumではないMS Edgeで要素ドラッグしようとするとタッチジェスチャーが動作してしまう件の回避

#概要
- 最新のChromium版のMicrosoft Edgeではない、古いEdge
- タッチディスプレイで、タッチ操作

という条件で、HTML内の要素ドラッグをしようとすると、全体のタッチジェスチャー（？）が効いてドラッグできません。
![Microsoft-Edge-2020-05-28-11-08-20_Trim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24420/cee77968-1ed7-c3a5-da18-3e469f1a2f08.gif)

上記キャプチャのURLはこちら。
https://gijgo.com/draggable

#解決法
CSSで、ドラッグしたい要素に ```touch-action: none;``` を指定するだけ！

ひとまず、DeveloperToolで追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24420/de2db7a5-13bb-d9c2-1060-a667376532ee.png)

うまくいった！
![Microsoft-Edge-2020-05-28-11-14-18_Trim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24420/1ca59329-004d-d893-a956-038309058332.gif)


#参考
https://stackoverflow.com/questions/47495465/how-to-disable-swipe-to-go-back-in-microsoft-edge-with-javascript-or-jquery
sql で percentile を算出してランク付けする

# Overview

テーブル形式の大量のデータに対して、なんらかの値が

| 閾値 | ランク |
| --- | --- |
| 上位80% | A |
| 60% - 80% | B |
| 40% - 60% | C |
| 20% - 40% | D |
| 下位20% | E |

みたいにランク付けしたいときとかあるじゃないですか。

それを SQL でやります。

```bash
$ sqlite3 -version
3.31.1 2020-01-27 19:55:54 3bfa9cc97da10598521b342961df8f5f68c7388fa117345eeb516eaa837bb4d6
```

# 適当なデータを投入

```bash
$ { echo idx,value; seq 10000 | while read x; do echo $x,$RANDOM; done } | \
   sqlite3 -csv -header a.db ".import /dev/stdin hoge"
```

## 確認

```bash
$ sqlite3 a.db ".schema"
CREATE TABLE hoge(
  "idx" TEXT,
  "value" TEXT
);

$ sqlite3 a.db "SELECT count(*) FROM hoge"
10000

$ sqlite3 -header a.db "SELECT * FROM hoge LIMIT 10"
idx|value
1|16165
2|9345
3|7693
4|1073
5|12271
6|7869
7|3264
8|11153
9|16929
10|14493
```

# パーセンタイルでランク付けして別テーブルに格納

`TEXT` で入っちゃってるのを `INT` にキャストしてあるので、そこだけ注意。

```sql:a.sql
CREATE TABLE rank AS
WITH q1 AS (
SELECT
  *
  , PERCENT_RANK() OVER(ORDER BY CAST(value AS INT)) as percentile
FROM hoge
)

SELECT
  *
  , CASE
    WHEN percentile >= 0.8 THEN "A"
    WHEN percentile >= 0.6 THEN "B"
    WHEN percentile >= 0.4 THEN "C"
    WHEN percentile >= 0.2 THEN "D"
    ELSE "E"
    END AS rank
FROM q1;
```

## 確認

```sql:b.sql
SELECT
  COUNT(*)
  , MAX(percentile)
  , MAX(value)
  , rank
FROM rank
GROUP BY rank
```

```bash
$ sqlite3 -header a.db <b.sql
COUNT(*)|MAX(percentile)|MAX(value)|rank
2000|1.0|32767|A
2000|0.7999799979998|26157|B
2000|0.5999599959996|19568|C
2000|0.3999399939994|9999|D
2000|0.1999199919992|999|E
```


っていう話。
閾値を変えたり、足切りとかにも使えますね。
PHP 配列に格納された連想配列に要素を追加する

# 目的

- 配列に格納された連想配列に値を追加する際に若干詰まったので方法をまとめる

# 前提情報

- 下記のリンク先で後述するコードの振る舞いを確かめる。
    - [https://paiza.io/ja/projects/new](https://paiza.io/ja/projects/new)

# 具体例

- 連想配列が格納された配列`$tests`を定義し、`$tests`の末尾に連想配列を追加する処理を下記に記載する。

    ```php
    <?php

    //連想配列が格納された配列の定義
    $tests = [
        [
            'str_1' => 'aaa',
            'str_2' => 'bbb',
            'str_3' => 'ccc',
        ]
    ];

    //追加する連想配列を記載する
    $tests[] =
        [
            'str_1' => 'ddd',
            'str_2' => 'eee',
            'str_3' => 'fff',
        ];

    //配列内容の出力
    foreach ($tests as $test) {
        echo $test['str_1'] ."\n";
        echo $test['str_2'] ."\n";
        echo $test['str_3'] ."\n";
        echo '===================';
    };
    ?>
    ```
jest の spy を使ったテストでテスト順番に依存して落ちたり落ちなかったりする問題の解決

spy で toBeCalled() を使ったテストで、テストの順番に依存してうまく動いたり動かなかったりする現象があって、ハマりそうだったので記録しておきます。
テスト対象は TypeScript の関数ですが、型がある以外は JavaScript に読み替えても同じだと思います。

テスト対象の関数が以下のようにあるとします。

```typescript

export const targetFunction = (flag: boolean) => {
  if (flag) {
    console.error('出力です')
  }
}
```


### 失敗するパターンのテスト
```typescript

import { targetFunction } from '~/plugins/axios'

const spyConsoleError = jest.spyOn(console, 'error')
spyConsoleError.mockImplementation(() => {
})

describe('spy resetの動作テスト', () => {
  test('console error が呼ばれる', async () => {
    await targetFunction(true)

    expect(console.error).toBeCalled()
  })

  test('console error が呼ばれないはず', async () => {
    await targetFunction(false)

    expect(console.error).not.toBeCalled()
  })
})

```
これを実行してみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144064/3a5577ca-97c2-d61d-e61c-ba795b6c0b96.png)

対象のテストの中では console.error は呼ばれていないはずなのですが、すでに前のテストで呼ばれているため、1回呼ばれたことになってしまっています。

### うまくいくように書き換えたパターン

```typescript


import { targetFunction } from '~/plugins/axios'

const spyConsoleError = jest.spyOn(console, 'error')
spyConsoleError.mockImplementation(() => {
})

// ------  これを書き足します --------
beforeEach(() => {
  spyConsoleError.mockReset()
})
// ------  ここまで  ---------

describe('spy resetの動作テスト', () => {
 // 同じテスト
})

```

それぞれのテストの前に beforeEach で初期化処理をしてあげると依存関係の問題が起こりません。
knex.js + postgresql migration メモ

knex.js を postgresql で利用する際の migration について、こうやるといいんじゃないかな的な話題をまとめていきます。(随時更新予定)

# bigint な primary key

64bit にしたい場合。

```javascript
exports.up = function(knex) {
    return knex.schema
        .createTable('xxxx', function (table) {
            table.specificType('id', knex.raw('BIGSERIAL PRIMARY KEY'));
        });
};
```

# enum の up / down 

up / down の行き来によって enum 型定義だけ残るので強制的に消しに行ってます。

```javascript
const dropTypeStmt = 'drop type if exists xxx_type';

exports.up = function(knex) {
    return knex.schema
        .raw(dropTypeStmt)
        .createTable('xxx', function (table) {
            table.enu('state', ['a', 'b'], { useNative: true, enumName: 'xxx_type' });
        });
};

exports.down = function(knex) {
    return knex.schema
        .raw(dropTypeStmt);
};
```
Javascript　コーディング問題（手助け求めます）

#　Javascript のコーディング質問
Javascriptにて

**あなたは現在価格mドルの土地の購入するために、年利i(0 < i < 100)%の金融商品にpドル投資しました。何年後に土地の購入ができるでしょうか？howLongToReachFundGoalという関数を再帰によって作成してください。なお、毎年得られた利益は同商品に再投資するとし、土地の価格は経過する年数が偶数(0を含む)の時は2%、奇数の時は3%上昇します。また、人の寿命は80歳未満と仮定し、80年以上かかる時は80としてください。**

という内容の元プログラムを組んでいます。

問題に直面しているのですが、一定数の入力だと正解の出力より１多い数値を出してしまうのですが、改善方法がわからず行き詰まってしまっています。

（例）
入力：5421,10421,5
正解の出力：27
自分の出力：２８

どなたか分かる方手助けお願いします。

```
function howLongToReachFundGoalHelper(capitalMoney, goalMoney, interest, x){
    function capitalAfterInterest(capitalMoney, interest, x){
        if(x == 0){
            return capitalMoney;
        } else {
            return capitalMoney * (1 + (interest / 100));
        }
    }
    function goalMoneyAfterInflation(goalMoney, x){
        if((x % 2 == 0) || (x == 0)){
            return goalMoney * 1.02;
        } else {
            return goalMoney * 1.03;
        }
    }
    if(x >= 80){
        return 80;
    } else if(capitalMoney >= goalMoney){
        return x;
    } else {
        return howLongToReachFundGoalHelper(capitalAfterInterest(capitalMoney, interest, x + 1), goalMoneyAfterInflation(goalMoney, x + 1), interest, x + 1);
    }
}

function howLongToReachFundGoal(capitalMoney,goalMoney,interest){
    //ここから書きましょう
    return howLongToReachFundGoalHelper(capitalMoney, goalMoney, interest, 0);
}
```
AWS Update 5/28

#Data Lifecycle Manager が cron 式に基づくスケジューリングと、週単位、月単位、および年単位のスケジュールを含む追加のバックアップ間隔をサポート
> Data Lifecycle Manager (DLM) ポリシーのスケジューリング入力として cron 式を提供できるようになりました。cron 式を使用すると、ポリシーでカスタムスケジュールを柔軟に指定できます。 

さらに、今回のリリースにより、DLM のバックアップ間隔が拡張され、すでに利用可能な時間単位および日単位のスケジュールに加えて、週単位、月単位、および年単位のスケジュールがサポートされるようになりました。これにより、バックアップ間隔を 1 時間から 1 年の間のいずれかにすることができます。 

ポリシーを使用して EBS ボリュームスナップショットの作成および保持を自動化する DLM は、2018 年 7 月にローンチされました。それ以降、当社は、DLM の使いやすさを向上させ、より頻繁なバックアップサポートやスナップショットのクロスリージョンコピーなどの機能で災害復旧のユースケースをサポートしてきました。本日、柔軟性を高めるべく、DLM を拡張して、追加のバックアップ間隔と cron 式に基づくスケジューリングのサポートを開始します。 

#AWS Systems Manager Explorer が AWS Compute Optimizer のレコメンデーションのマルチアカウント、マルチリージョンの概要の提供を開始
> 本日より、AWS Systems Manager Explorer は、ワークロードのコストとパフォーマンスを改善するのに役立つ AWS Compute Optimizer のレコメンデーションの概要の提供を開始します。Systems Manager Explorer は、運用のダッシュボードであり、パッチのコンプライアンスやインスタンスの詳細などの運用データのビューを提供し、運用上の問題を調査および修正する必要がある場所を確認するのに役立ちます。Compute Optimizer は、Amazon Elastic Compute Cloud (Amazon EC2) インスタンスのレコメンデーションを提供するため、最大の影響をもたらす最適化の機会をすばやく特定できます。Systems Manager Explorer の 1 つの集約ビューで、すべての運用データと Compute Optimizer のレコメンデーションを確認できるようになりました。

この新機能により、Systems Manager Explorer を使用して、複数のアカウントまたは組織全体にわたる Compute Optimizer のレコメンデーションを表示できます。さらに、Compute Optimizer の概要でレコメンデーションを選択して、現在のインスタンスタイプ、推奨されるインスタンスタイプ、両者の料金の差など、EC2 インスタンスの詳細のリストを表示できます。次に、このデータをフィルタリングし、結果をコンマ区切り値 (.csv) ファイルにエクスポートして、Amazon Simple Notification Service (Amazon SNS) 通知を発行できます。Systems Manager Automation を使用してインスタンスのサイズを変更し、推奨される EC2 インスタンスタイプに変更することもできます。

#Amazon Connect が問い合わせフローエディタ内の複数のブロックの選択のサポートを開始
> 複数のブロックを同時に選択して、それらを問い合わせフロー内のグループとして再配置できるようになりました。これにより、時間と労力を節約できます。以前は、一連のブロックを移動するには、各ブロックを個別にドラッグアンドドロップする必要がありました。この機能では、一度に 1 つのブロックをドラッグするという、イライラし、エラーが発生しやすく、時間がかかる繰り返しのタスクを、数秒で終わる 1 回の作業に置き換えるものです。
Rails テーブルにcommentを追加するマイグレーションファイル

## マイグレーションファイル
```ruby
class AddCommmentsToStaffEmail < ActiveRecord::Migration[6.0]
  def change
    change_column_comment(:staff_emails, :employee_id, '業者ID') 
  end
end
```
### change_column_comment
change_column_commentにテーブル名、カラム名、コメント内容　を記載する

```
change_column_comment(:table_name, :column_name, 'contents') 
```



## 環境

- activerecord (6.0)


## 実行手順

マイグレーションファイル作成

**コマンド**

```cmd.
$bundel exec rails g migration AddCommentsToTable
```

マイグレーションの実行

**コマンド**

```cmd.
$bundel exec rake db:migrate
```

## 備考

- 参考リンク

http://hotoolong.hatenablog.com/entry/2018/06/20/083106
user/bin とは




https://linuc.org/study/knowledge/544/


- /usr/local/binを普段は使う?

- シングルユーザモードは何かを調べる


## シングルユーザモードとは

```
UNIX系OSの動作モードの一つで、
管理者ユーザ（スーパーユーザ、rootユーザ）のみがログインしてOSを操作できるモードのこと
```
の事らしい。


http://e-words.jp/w/%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%A2%E3%83%BC%E3%83%89.html


いまいちわからないからもうちょっと調べる
正体不明のファイルのフォーマットを推測する方法

## zip

```shell
file hoge.hoge
hoge.hoge Zip archive data, at least v2.0 to extract
```

## tar.gz

```shell
file hoge.hoge
hoge.hoge gzip compressed data, last modified: Thu May 28 00:12:04 2020, from Unix, original size modulo 2^32 35602944
```

## text(ASCII)

```shell
file hoge.hoge
hoge.hoge ASCII text
```

## text(UTF-8)

```shell
file hoge.hoge
hoge.hoge UTF-8 Unicode text
```


## mp4

```shell
file hoge.hoge
hoge.hoge ISO Media, MP4 v2 [ISO 14496-14]
```
SceneDelegateのシングルトンオブジェクトを取得する

UIApplicationが接続されたSceneを保持しています。
外部ディスプレイへの接続などを行わない一般的なiOSアプリの場合は基本的にconnectedScenesは1つとなると思います。
以下のようなコードでオブジェクトを取得できます。

```swift
UIApplication.shared.connectedScenes.first?.delegate as! SceneDelegate
```

また、以下のようなユーティリティを定義しておくと使用が楽です。

```swift
extension SceneDelegate {
    static var shared: SceneDelegate {
        UIApplication.shared.connectedScenes.first?.delegate as! SceneDelegate
    }
}
```

上記関数は以下のように使用ができ、簡単にUIViewControllerをSwiftUIから表示することができます。

```swift
let controller = UIViewController()
SceneDelegate.shared.window?.rootViewController.present(controller, animated: true)
```
Bootstrap4のnavbarカスタマイズ方法

レスポンシブで使いやすいnavbarですがカスタマイズの方法忘れやすいのでメモ

# Bootstrap4の基本形navbar

項目はいろいろありますが最低限なら下記でいけるでしょう

- タブレットサイズでメニュー展開
- メニューを右寄せ
- タイトルを文字
- 色をlight

```html
<nav class="navbar navbar-expand-md navbar-light bg-light">
  <a class="navbar-brand" href="#">タイトル</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar-content" aria-controls="navbar-content" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse justify-content-end" id="navbarSupportedContent">
    <ul class="navbar-nav">
      <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">link1</a>
      </li>
      <li class="nav-item">
        <a class="nav-link disabled" href="#">link2</a>
      </li>
    </ul>
  </div>
</nav>
```

よく使うカスタマイズを見てみましょう

# navタグをみてみる(1行目)

```html
<nav class="navbar navbar-expand-md navbar-light bg-light">
```

メニューを展開するポイントを設定する

- navbar-expand-○○
  - sm:モバイル md:タブレット lg:デスクトップ など

ナビゲーションの色変更

- navbar-○○
  - primary, light など
  
ナビゲーションの背景色変更

- bg-○○
  - primary, light など

# タイトルに画像を使用

aタグ内にimgタグをいれる

```html
<a class="navbar-brand" href="#"><img src="" alt=""></a>
```

# バーガーアイコンの枠を消す

```css
.navbar-toggler{
  border: none;
}
.navbar-toggler:active{
  outline: none;
}
button:focus{
  outline: none;
}
```

# バーガーアイコンの色と先の太さを変える

```css
.navbar-light .navbar-toggler-icon {
  background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}
```

CSSで変更

- stroke-width='2' の数値を変えて太さ変更
- stroke='rgba(0, 0, 0, 0.5)' のrgbaの値変更で色変

変更できますが個人的にはFontawesomeに入れ替えてしまったほうが好みですね  
すこしややこしいですし

# バーガーアイコンを変更

```html
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar-content" aria-controls="navbar-content" aria-expanded="false" aria-label="Toggle navigation">
  <i class="fab fa-apple"></i>
</button>
```

font-sizeなどで変更できるのでオススメです

# メニューとタイトルの位置を逆にする

```html
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar-content" aria-controls="navbar-content" aria-expanded="false" aria-label="Toggle navigation">
  <span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="#">タイトル</a>
```
buttonタグとaタグの場所を入れ替えるだけです


# メニューの並びを変更する

```html
    <div class="collapse navbar-collapse justify-content-start" id="navbar-content">
```

- 左寄せ : justify-content-start
- 中央寄せ : justify-content-center
- 右寄せ : justify-content-end

# navbarをスクロールしても上部に貼り付ける

```html
<nav class="navbar navbar-expand-md navbar-light bg-light fixed-top">
```
fixed-topを追加する

# まとめ
navbarのカスタマイズでどれだけつまずいたことか！
レスポンシブ対応は難しいから勉強しはじめの頃にnavbarの存在知って「すごい！」と思ったものの、カスタマイズがよくわからずたくさんの時間をほうりだしました(笑)
助けになればとおもいます
LaravelでVue.jsのscaffoldを生成した時の違和感

Laravelで`php artisan ui vue`をするとVue.jsのscaffold（「スカフォールド」とか「スキャフォールド」とか言って、ひな形を意味するらしい）を生成できるのだが...

```js
Vue.component(
    'example-component',
    require('./components/ExampleComponent.vue').default
);
```
これは違和感を感じないか？？

ExampleComponent.vue側で`module.exports`して、

```js
Vue.component(
    'example-component',
    require('./components/ExampleComponent.vue')
);
```
とするか、

```js
import ExampleComponent from './components/ExampleComponent';
Vue.component('example-component', ExampleComponent);
```
としたくない？
[Laravel公式](https://laravel.com/docs/7.x/frontend#writing-vue-components)にも堂々と`.default`って書いてるし、敢えてなのか？
SpacemacsでClojureファイルを開いた時の (wrong-type-argument stringp package-desc)を直す


# Clojureファイルを開く度にエラー
`Spacemacs on Emacs26.3 on Ubuntu18.04LTS on WSL2 on Windows10`で `.clj`ファイルを開いた時、毎回このエラーが起こる。

```
File mode specification error: (wrong-type-argument stringp package-desc)
```

どこに実害があったかわからなかったが、 `File mode specification error`は大体どこかの機能に支障をきたしているので直したい。





# パッケージの再コンパイルで解決
clj-refactorに関するドンピシャissueがあった。なるほどrefactor…

cf. [Wrong type argument: stringp, package-desc](https://github.com/clojure-emacs/clj-refactor.el/issues/369)

そして解決方法もいくつか提示されていた。注目したのはこれ (Emacs26なので)

> Rebuilding all packages after upgrading from 25->26 helped to solve a similar error with a different package, thanks all and especially @kaushalmodi !
I did:
M-: (byte-recompile-directory package-user-dir nil 'force)
see: stackoverflow.com/a/24735377/531439

cf. https://github.com/clojure-emacs/clj-refactor.el/issues/369#issuecomment-388326195

Spacemacsの本体はEmacsなので、当然実行できる。

`M-:`は、WSL2なら `Alt + :`。
その場で式を入力して実行できるみたい。

> M-: (eval-expression)は、ミニバッファーを使って式を読み取り、それを評価します(式を評価する前に、カレントバッファーは、式をタイプするためのミニバッファーではなく、M-:をタイプしたときカレントだったバッファーに切り替わります)。

cf. https://ayatakesi.github.io/emacs/24.5/Lisp-Eval.html

書かれていた通り `(byte-recompile-directory package-user-dir nil 'force)`を評価すると、再コンパイルが始まる。あとは待っていれば終わるので、Spacemacsを再起動する。

`.clj`ファイルを開いてもエラーが出なくなった :tada:
GatsbyにTableOfContents（目次）をつける

<head>

<link rel="canonical" href="https://tech-blog.yoshikiohashi.dev/posts/start-gatsby-blog-tableofcontent" />

</head>

# はじめに

> 本記事は https://tech-blog.yoshikiohashi.dev/posts/start-gatsby-blog-tableofcontent のクロスポスト記事になります。

この記事は[Gatsby](https://www.gatsbyjs.org/)というヘッドレスCMS技術で構成されています。今回は「エンジニア初心者でもできる」を前提に以下の構成で記事を作成していこうと思います。

* [Gatsby始めるまで](https://tech-blog.yoshikiohashi.dev/posts/start-gatsby-blog/)
* [GatsbyにShare機能、OGPタグをつける](https://tech-blog.yoshikiohashi.dev/posts/start-gatsby-blog-share/)
* [タグ機能、カテゴリ機能をつける（基礎編）](https://tech-blog.yoshikiohashi.dev/posts/start-gatsby-blog-add-tags)
* [タグ機能、カテゴリ機能をつける（応用編）](https://tech-blog.yoshikiohashi.dev/posts/start-gatsby-blog-add-tags-application)
* [GatsbyにTableOfContents（目次）をつける](https://tech-blog.yoshikiohashi.dev/posts/start-gatsby-blog-tableofcontent)
* [DarkModeをつける](https://tech-blog.yoshikiohashi.dev/posts/start-gatsby-blog-darkmode)

# 内容

前回はタグ一覧と記事一覧のコンポーネントを同時に出すGrapuQLクエリーの応用まで行いました。

今回はブログで欠かせないTableOfContents（目次）の実装方法のご紹介です。全く難しくないのでササッと行きましょう！

![](https://ucarecdn.com/94b024f1-760a-471c-875c-0ba1f4a2ed71/)

## クエリー

超簡単です。記事を取得しているクエリーに**tableOfContents**を付け足すだけです。エディタで結果を確認してみましょう。

```graphql
  query PostBySlug($slug: String!) {
    markdownRemark(fields: { slug: { eq: $slug } }) {
      id
      html
      fields {
        slug
        tagSlugs
      }
      frontmatter {
        date
        description
        tags
        title
        socialImage
      }
      tableOfContents
    }
  }
```

![](https://ucarecdn.com/d9fbac98-d126-4772-a731-dfb1b217cc57/)

このようにHTML形式のデータを取得することができました。あとは表示するだけです。

## コンポーネント作成

TOCを表示するコンポーネントつくりです。

ちなみになぜコンポーネントにするのか？理由は単純で

- 使い回しがしやすい
- CSSの設定を限定的にできる
- パーツを好きなところに配置しやすくなる

からです。パーツ１つ１つの依存度を下げていきましょう。

下のように**dangerouslySetInnerHTML={{ __html: tableOfContents }}**に先程取得したHTMLデータを流し込みましょう。（CSSの設定はお好みで設定してください）

```js
const Toc = ({ tableOfContents, gridArea }: Props) => (
  <div className={styles.toc} dangerouslySetInnerHTML={{ __html: tableOfContents }} />
);

export default Toc;
```

# まとめ

いかがだったでしょうか？

他にも[gatsby-remark-toc](https://github.com/DSchau/gatsby-remark-toc)などのライブラリがあるみたいですが、私個人としてはこちらの方がシンプルで簡潔だと考えています。それでは次回の記事で。
HTML5ビデオをcontent-encoding: gzip してはいけない

HTML5 にはvideo タグがあり、いくつかの形式のビデオをブラウザで再生させることができる。

私のデプロイパイプラインでは、静的なファイルはzopfli という高圧縮を実現できるgzip エンコーダを通して、圧縮結果が圧縮前よりも小さければ、事前に圧縮したファイルをストレージ(AWS S3)に配置する構成になっていた。

mp4 (H.264) 形式とWebM (VP9)のビデオを上記デプロイ方法で配置したところ、iOS 13.5 Safari およびWindows 10 Chrome 83.0.4103.61 にて再生が行えない状況が発生した。特に、Windows 10のChrome 83.0.4103.61においては、「コンソール」に以下表示が出力されていることを確認した。

```
net::ERR_CONTENT_DECODING_FAILED
```

一方、Firefox 77.0 では問題なく再生できていた。

結果として、上記ビデオを `content-encoding: gzip` で送らなければ、全環境で再生できることが検証された。私のようにビデオファイルを事前にgzip する場合は少ないと思うが、ちょっとハマるので注意が必要。
カラープリンタでA4に縮小＆モノクロ印刷　

# A4より大きいPDFファイルをA4に縮小してモノクロ印刷したい
やりたいことは単純だったんですが、上手くいかず苦労したのでやり方載せておきます。
結論としてはChromeではなくColorSyncユーティリティを利用すればいいです。

# 利用環境
OS: High Sierra 10.13.6
プリンタアプリケーション: printer proxy 13.6.1 (CANON MG5100 Series)
PDF取扱アプリケーション: ColorSyncユーティリティ 4.13.0

# 手順
1. PDFをColorSyncユーティリティで開く
2. `フィルタ`を`Black&White`に設定、適用
3. プリント->`ColorSyncユーティリティ`で`用紙サイズに合わせる`が設定されていることを確認
4. `用紙処理`で`用紙サイズに合わせる`にチェックが入っているのを確認  

これだけです。

ちなみに失敗(モノクロにはなるがA4縮小されず分割印刷になる)の手順は
1. ChromeでPDF開いて`印刷`
2. ChromeでPDF開いていたのでChromeの機能で`倍率`を`用紙に合わせる`を選択
   ->これだけだとモノクロにできないので`システムダイアログを利用して印刷`に進む
3. システムダイアログで`用紙設定`で`用紙に合わせる`を選択(A4)、プリンタ機能で`モノクロ印刷`をオン 
でした。
【Golang】interface型

#【Golang】interface型
Golangの基礎学習〜Webアプリケーション作成までの学習を終えたので、復習を兼ねてまとめていく。 基礎〜応用まで。

```
package main 
//インターフェース
//指定したメソッドを保持して欲しい時にインターフェースを使う
//異なるstructで共通のメソッドを持たせたい。

/*interface用途

1、異なる構造体で共通のメソッドをまとめられる。

2、どんな型も入るが、関数内で計算などを処理する場合は型アサーションする必要がある。

3、カスタムエラー、Stringerを設定できる。
*/



//interface1の使い方
import (
	"fmt"
)

//interface　型みたいな感じ
//同じメソッドを持つstructをまとめる
type Human interface {
	//共通のメソッドを持つ
    Say() string
}

type Man struct {
    Name string
}

type Woman struct {
    Name string
}

type Dog struct {
    Name string
}


//名前を書き換える場合 アドレスで渡す必要がある
func (m *Man) Say() string {
	m.Name = "Mr." + m.Name
	fmt.Println(m.Name)
	return m.Name
}

//名前を書き換える場合 アドレスで渡す必要がある
func (w *Woman) Say() string {
	w.Name = "Mrs." + w.Name
	fmt.Println(w.Name)
	return w.Name
}

//interfaceがHumanの関数
//Sayを持つ型なので、実行できる
func Speak(h Human){
	h.Say()
}


func main() {
	//structを作成 Human
	//指定したメソッドを保持して欲しい時にインターフェースを使う
	//say()メソッドを持つ
	//変数名 intarface = struct
	//var mike Human = Person{"Mike"}
	//mike.Say()でもできる。ので正直メリットがわからない筆者。
	var mike Human = &Man{"Mike"}
	var nancy Human = &Woman{"Nancy"}
	Speak(mike)
	Speak(nancy)

	//Dogはintarfaceを持たない
    //Say()を持たないとエラーになる
	var dog Dog = Dog{"dog"}
	//Speak(dog)
}
```
リモートワークをふりかえってみた

## 0. はじめに

私がリモートワークを始めて、約1か月半が経ちました。(もう終わりましたが)
リモートワークをプロジェクトメンバーや社内メンバーでふりかえった結果をまとめてみました。

## 1. メリット
#### 1-1. 通勤がなくなる:sunny:
**ほとんどの人が真っ先にあげるのがこれでした！**
自分たちはほぼ車通勤で、往復1時間以上かかる人が多いので、この差はでかいですね。
さらには、「ガソリン代が浮く」「環境にも優しい」「交通事故のリスクが減る」といったメリットもついてきます。

#### 1-2. 好きな環境で仕事ができる:sunny:
「好きなアーティストの曲を聴きたい」「BGMだけ聞きたい」「無音がいい」など、音楽の好みは様々ですが、それを自分に合わせることができます。
机とか椅子とか、部屋自体を自分好みに合わせられるのもいいですね。

#### 1-3. マスクが減らない:sunny:
これは最初気づきませんでしたｗ
家に引きこもってると、そもそもマスクを使わないんで減らないんですよね。(家でマスクしている人もいると思いますが)
マスクが非常に貴重だったので助かりました。

#### 1-4. 自分の時間が増える:sunny:
「1-1. 通勤がなくなる」の延長みたいな感じですが、趣味の時間、家族の時間、自己学習の時間が増えました。
私は空いた時間のうち、約40分をランニングにあてることで、かなりの減量に成功しました:innocent:

#### 1-5. 弁当を作らなくていい:sunny:
らしいです。

## 2. デメリット
#### 2-1. 質問などの文面を考えるのに時間がかかる:umbrella2:
コミュニケーションがSlack等に偏るので、文面を考えるのが大変という意見もありました。
やはり面と向かって会話するのが最強のコミュニケーションですね。

##### ＜やってみたこと:runner:＞
文章書くのに迷うんだったら即通話！というスタイルをチームでとりました。

- 「xxxの件で相談があるのですが通話よろしいでしょうか？」

みたいな感じです。
結果、**無駄(？)な時間がかなり減りました！！**
このような環境は、少しでも早めに作っておくべきだと思います。

#### 2-2. ネットワークが繋がらなくなった時に何もできなくなる:umbrella2:
先日、突然朝Slackが繋がりにくくなって、いつも通りの時間にSlack会議ができなくなりました。
その時は急遽Google Meetにて会議を行いましたが、ちょっとバタつきました。。。

##### ＜やってみたこと:runner:＞
ネットワークトラブルに備え、あらかじめ対策(どうするか)を決めておくようにしました。
私たちのチームでは、

- **Slack**　(だめなら)⇒　**メール**　(だめなら)⇒　**電話**

という手段で連絡をするようにしました。
それ以来まだトラブルは起きていませんが、事前に備えることが大事ですね。心理的安全性も確保されます。

#### 2-3. 業務時間外にPCを開いてしまう:umbrella2:
メール返事きてるかなーとか、レビュー結果どうなったかなーとか気になって、ついつい夜10時とかに仕事PCを開いてしまうことがありました。

##### ＜やってみたこと:runner:＞
業務終了後、PCを棚に片づけるようにしましたｗ
また出すのが面倒なので、それ以来は一切開かなくなりました。
仕事PCが家にあるのはメリットデメリットあるかと思いますが、メリハリをつけるのが大事ですね。

#### 2-4. 作業環境を作るのにお金がかかる:umbrella2:
椅子とかモニターとか買った人は多いかと思います。
まぁこれは仕方ないですね。

##### ＜やってみたこと:runner:＞
リモートワークが終わっても使えるような品を選びました。
結局は自己投資！！！

#### 2-5. 時間間隔が狂う:umbrella2:
真面目な人程こうなるようです。昼休みになったにも関わらずずっと仕事続けていたり・・・
~~ちなみに私は一切なりませんでした:rolling_eyes:~~

##### ＜やってみたこと:runner:＞
特になし。

#### 2-6. 電気代がかかる:umbrella2:
これも仕方ない！ｗ
夏とか冬とかにリモートワークだと、さらに電気代が・・・。
そう考えると季節的にまだマシでしたね。

##### ＜やってみたこと:runner:＞
特になし。

## 4. おわりに
リモートワークをして自分の時間はかなり増えると思います。
この時間を、

- ゴロゴロするのか
- ぼーっとネットサーフィンするのか
- 自己の成長に使うのか
- 家族との時間に使うのか

満足できる時間となるかは**完全に自分次第**かと思います。
でもこの時間の使い方の積み重なって、人生の満足度に繋がっていくのかと思いました。

また、生産性の低下は特になかったかなと思います。
**リモートワークを1日やってみたあと、すぐにプロジェクトメンバーで意見を出し合って対策を立てた**ことが大きかったかなと思います。
やはり、↓が効果大だったかと・・・メンバー全員が感じたことです。
[2-1. 質問などの文面を考えるのに時間がかかる:umbrella2: ＜やってみたこと:runner:＞](https://qiita.com/i-tanaka730/items/3fe10092d0712cc1d398#%E3%82%84%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F%E3%81%93%E3%81%A8runner)



もう少しリモートワークに関しての意見をお聞きして、随時更新していきたいと思います:blush:
golang bulitinのprintとruntime

# golangでCPU数やgoroutine数を知るためのruntimeを流してみた。ついでに、builtinのprintを使ってみた

go routineを呼んで、その数が変わることを確かめた。

```test_runtime.go
package main                                                                    

import (
    "runtime"
    "time"
)

func RuntimeSurvey() {
    print("NumCPU:", runtime.NumCPU(), "\n")
    print("NumGoroutine:", runtime.NumGoroutine(), "\n")
    print("Version:", runtime.Version(), "\n")
    print("OS:", runtime.GOOS, "\n")
}

func main() {
    go func() {
        time.Sleep(time.Second * 1)
    }() 
    print("Before sleep")
    RuntimeSurvey()

    time.Sleep(time.Second * 1)
    print("After sleep")
    RuntimeSurvey()
}

```


結果はこういうふうになります。goroutineの数が、２になって、そのあと１になってます。
処理が終わって待機中みたいになったら、数に含まれなくなるのかな。

```
$ go run test_runtime
Before sleepNumCPU:8
NumGoroutine:2
Version:go1.14.2
OS:darwin
After sleepNumCPU:8
NumGoroutine:1
Version:go1.14.2
OS:darwin
```

#### goroutine(ゴルーチン)の終了条件は

関数の処理が終わる。
returnで抜ける。
runtime.Goexit() を実行する

#### おまけ appleのこのOSって、darwinっていうんだ！

*wikiより
Darwin（ダーウィン）はアップルが開発するUnix系のPOSIX準拠オペレーティングシステム (OS) である。 技術的にはNEXTSTEPからOPENSTEPに続く流れを汲み、Mach 3.0+BSDをベースとし、一部の機能は他のBSD系OSからも取り入れている。
CCC: coding crash course (4) 円周率3.141562.... に出現する数字をヒストグラムにする

# 3.141562.... に出現する数字の頻度分布

円周率(PI)の小数点以下に出てくる数字のヒストグラムを作ります。

効率重視ではなく、初心者向けのやり方で試してみましょう。

まず、PIの小数点以下を　http://www.eveandersson.com/pi/digits/pi-digits?n_decimals_to_display=500&breakpoint=500 で取得します。

```python

char_pi = "14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912"
```

例えば、「0」の出現回数を調べるには：

```python

count_0 = 0
for i in range(500):
    s = char_pi[i]
    if (s == "0"):
        count_0 = count_0 +1

print( count_0 )

```

同様にすれば、各数字が何回現れるのかを調べることができます。
最後に、グラフにして可視化します。


```python

list_digits = [0,1,2,3,4,5,6,7,8,9,]

list_count = [0,0,0,0,0,0,0,0,0,0,]

for d in range(10):
    for i in range(500):
        s = char_pi[i]
        if (s == str(d)):
            list_count[d] = list_count[d] +1
    print(d, list_count[d])


from matplotlib import pyplot

pyplot.plot(list_digits, list_count, 'o')

pyplot.plot(list_digits, list_count, '-')

pyplot.ylim([0, max(list_count)+5])
pyplot.xlabel('Number')
pyplot.ylabel('Count')
pyplot.xticks([0,1,2,3,4,5,6,7,8,9,])

pyplot.show()

```

![Figure_pi_digits_500.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610740/af5648c7-d9a4-d35e-3f54-557e5475f270.png)
Puppeteerを2系から3系にアップデートしたらError: Failed to launch the browser process!


Puppeteerメモです。

Heroku上で利用していたPuppetterのバージョンを2系->3系にアップデートしたらエラー発生。

## Puppetterのバージョンを2系->3系にするとChromiumのバージョン違いで動かないっぽい

### Heroku上のログ

```
Error: Failed to launch the browser process!
2020-05-27T21:22:10.217234+00:00 app[web.1]: /app/node_modules/puppeteer/.local-chromium/linux-756035/chrome-linux/chrome: error while loading shared libraries: libgbm.so.1: cannot open shared object file: No such file or directory
```

### Heroku上でインストールされているChromiumを更新する

> https://github.com/puppeteer/puppeteer/releases

Puppetterのv3.1.0ではChromium 83.0.4103.0 (r756035)を利用していると、Big changesと書かれていて、内部で利用するChromiumのバージョンが違う模様です。

最初にインストールしたときはPuppetterのv2系だったので、その時に対応していたバージョンのChromiumがHeroku側に残ったままになってるんだと思います。

### bildpackを再ビルド

```
$ heroku buildpacks:add jontewks/puppeteer
```

その後デプロイしなおす(`git push heroku master`)と再度ビルドされてHeroku上のChromiumも更新されてこれで問題なく利用できるようになりました。

## その他メモ

その他触っててでたエラーをメモ的に残しておきます。

### TimeoutError: Navigation timeout of 30000 ms exceeded

タイムアウト。
デフォルトだと30秒待ってくれるみたいだけど、それ以上かかる場合もありそう。

`page.goto()`のオプションで`{waitUntil: 'networkidle'}`を指定するっぽいけど更にエラーが

```
Error: ERROR: "networkidle" option is no longer supported. Use "networkidle2" instead
```

なるほど

```
page.goto(url, {waitUntil: 'networkidle2'})
```

でうまくいった。

### Error: Evaluation failed: TypeError: Cannot set property 'value' of null


こんな雰囲気でiPhoneでのページ閲覧エミュレートをしてましたが、

```
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone X'];

省略

await page.emulate(iPhone);
```

これもv2->3にあげたら`Error: Evaluation failed: TypeError: Cannot set property 'value' of null`とエラーが発生し、うまく動作しなくなってしまいました。

これパッと調べても原因や解決策がわからなかったので、iPhoneでのエミュレートを泣く泣く断念。

今回やりたかったのはデスクトップエミュレートでもなんとかなったのでよかったけど、必要になったらまた調べないと...
ESP32-DevKitC-32DのdigitalRead()

この記事は、2020-05-28に書きました。
***
#概略
ESP32-DevKitC-32DでのdigitalRead()の話です。
ボタンを押すと、LEDが点灯します

#環境・部品
PC：Windows 10 Professional
開発環境：Arduino IDE 1.8.12
本体：ESP32-DevKitC-32D
タクトスイッチ
LED
抵抗：10KΩ（プルダウン用）、220Ω（LED用）

#回路図
<img width="320" alt="ESP32-DevKitC-32Dの5番ピンにタクトスイッチを繋ぐ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635194/62f02792-ec9f-6797-7fa4-98ceab5be8d1.png">

<img width="320" alt="ESP32-DevKitC-32Dの5番ピンにタクトスイッチを繋ぐ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635194/568bd397-e4ef-4594-bd70-7c8ae233b187.png">


#コード

```cpp:digitalRead.ino
const int pinLed = 2;
const int pinButton = 5;

void setup() {
    pinMode(pinLed, OUTPUT);
    pinMode(pinButton, INPUT);
}

void loop() {
    digitalWrite(pinLed, digitalRead(pinButton));
}
```

#解説
基本的に、Arduino用のコードがそのまま使えます。
ピン番号の指定は、GPIOピンの番号で指定します。
<img width="320" alt="ESP32のピン配置" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635194/2ead5151-40f1-a10c-3b4c-edc112392ab5.png">
画像は、[ESP32のGitHub](https://github.com/espressif/arduino-esp32)から転載。©Espressif Systems

使えるピンは、GPIOの1、2、4、5、7、8、12、13、14、15、16、17、18、19、21、22、23、25、26、27、32、33、34、35、36、37です。1番ピンは、使わない方が無難です。

#参考
[ESP32のGitHub](https://github.com/espressif/arduino-esp32)（英語）
回路図の[ブレッドボードとESP32-DevKitC-32Dのパーツ](https://twitter.com/ht_deko/status/888760472417083392)は、DEKOさん（@ht_deko
）が作成したものです。感謝！