OmniAICreator/Qiita-1.07M huggingface dataset:
VPCフローログ とは

## 勉強前イメージ

フローログ。。。流れるログ
ログデータ取得する的な話？

## 調査

### VPCフローログ とは

VPCのネットワークインターフェイスとの間で行き来するトラフィックに関する情報をキャプチャできるようにする機能で
CloudWatch Logs か s3に発行できます。

### VPCフローログの特徴

- VPC/サブネット/ENI のいずれかに作成
	- ENIに対して作成する場合は以下のサービスで作成したENIにもフローログを作成できる
		- ELB
		- RDS
		- ElastiCache
		- Redshift
		- WorkSpaces
		- NATゲートウェイ
		- トランジットゲートウェイ
- フローログの取得はネットワークのスループットやレイテンシーには影響しません

### VPCフローログのユースケース

- セキュリティ診断

セキュリティ要件通りに動作しているかの確認・診断などで使用することが出来ます

- 通信トラブルの調査

トラフィックのモニタリングが出来るので通信到達の切り分けが出来ます


### 設定方法

- フローログへ移動

![1VPC Management Console - Google Chrome 2021-03-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/28bf8df8-64f6-d0d5-c11c-6065a6d6d1e2.png)



- フローログの作成

![2VPC Management Console - Google Chrome 2021-03-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/4a675931-f0e8-6037-6aa8-f05bf2f17f21.png)


- フローログの設定

名前・フィルタ・最大集約間隔・送信先・S3バケットARN(s3の場合)・ログレコード形式 を選択します。
データはcloudwatchかs3、どちらか選択できます。

![3VPC Management Console - Google Chrome 2021-03-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/a2752869-0711-fe48-e9a6-0fbd13b30ccf.png)

- 作成できました

![2021-03-02お使いの VPC _ VPC Management Console - Google Chrome.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/b77cbdb8-1c82-5e20-198b-7ac6170bf450.png)

## 勉強後イメージ

logを取る機構もいろいろあるのね。。
あとcloudwatchで見れるのもすごい・・・

## 参考

- [VPC フローログ](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/flow-logs.html)
- [VPC フローログの取得方法とログ見方](https://oji-cloud.net/2020/08/04/post-5242/)
【Nuxt.js × golang】ゴミ出しの通知をしてくれるラインbotを作った

## 経緯

起きてすぐにゴミ出しに行かないと間に合わないので寝起きでもすぐに判断できるように通知botを作成しました。

## 概要

管理画面で各曜日の設定することでbotからメッセージが送信されるアプリです。

### 処理のイメージ

管理画面では、ログインしたユーザーIDと画面上で設定した内容をfirestoreに保存します。
APIでは、毎朝6時にfirestoreからデータを取得して対象のユーザーに設定されている内容のメッセージを送信します。


![](https://i.imgur.com/n6AZUeE.png)

### 管理画面のリンク

https://grn-line.herokuapp.com/

ログインしなくてもサンプル用画面でモーダルの操作などは行えます。

## 使用技術

言語はTypescriptとgolangで書いています。
詳細は以下の通りです。

### 管理画面

- Nuxt.js
- Typescript
- liff
    - Line Login SDK
- firestore

### API

- golang
- echo
- firestore

### その他

- Docker
- heroku
- cron job
    - APIを毎朝6時に叩く用

## 画面説明

### ログイン後の画面

- 通知を停止するかどうかと各曜日の通知内容を編集できます
- 曜日ごとに設定した内容が表示されます
- 複数選択した場合は` ・ `区切りで表示されます

<img width="300" alt="S__79880194.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530479/2ae5d902-7373-d111-7911-fba16dcfaf78.jpeg">

### 通知内容編集モーダル

- 通知する内容をチェックして更新するとその曜日の朝に通知されるようになります

<img width="300" alt="S__79880196.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530479/3c5287b5-9d99-52d5-8df3-99b8e8d32627.jpeg">


## 詰まった点

### デプロイ失敗

- portを固定してデプロイしようとしていた
    - portを環境変数にすることで解決
- Dockerfileに`ENTRYPOINT yarn run start`と記載していた
    - dockerで立ち上げるのは問題なかったがデプロイできなかった
    - `CMD ["yarn", "run", "start"]`に修正して解決

### `window is not defined`が出る

pluginsで次のようにファイルを作成した

```
import liff from '@line/liff'

if (!liff.id) {
  const liffId: string = process.env.liffId as string
  // liffの初期化
  liff.init({ liffId })
}

export default liff
```

ページ内で呼び出そうとしたら`window is not defined`が出た
importで呼び出すのではなく次のように書き換えてみたところ解決した

```
let liff: any = null
if (process.browser) {
  liff = require('@/plugins/liff')
}
```

### storeの呼び出し方法

`this.$store`でエラーが出る
次のような書き方で解決した

```
(this as any).$store.getters['users/getGarbageList']
```

できれば`this.$store`に直したい

## おわりに

今回初めてTypescriptで個人開発してみたが、storeの定義や呼び出しがjavascriptと結構違い大変でした。
その分引数や変数に型がついてると全体的にコードが読みやすくなる気がしました。
最後に今回書いたコードを載せておきます。


管理画面: https://github.com/d-yamagishi522/garbage-removal-notification-ui
API: https://github.com/d-yamagishi522/garbage-removal-notification-api
MySQL カバリングインデックス

## カバリングインデックス

データが欲しい時に、より小さなコストでやろうと思ったら、
行全体を取得するよりも、インデックスのみで処理するようが良いに決まっている。

そこで、クエリを処理するのに必要なデータを全て含んでいるようなインデックスをカバリングインデックスと呼ぶ。
これは非常に有効な手段で、特にInnnoDBにおいては、セカンダリインデックスは、主キーの値をそのままリーフノードに格納するため、クエリをカバーするセカンダリインデックスによって、主キーでもう１つのインデックスルックアップを回避することができる。

カバリングインデックスが実行された時、EXPLAIN句のEXTRA列にUsing Indexが表示される。

それでは、これから、複合インデックスを用いてカバリングインデックスを活用することを考える。
Userのageとnameがの一覧が必要であれば、(age, name)の複合インデックスをUserテーブルにはる・
そして、

```sql
SELECT
  age,
  name
FROM
  users
```

これは、Using Indexとなる。

注意したいのが、MySQLにおけるクエリオプティマイザは、クエリを実行する前にインデックスを選択するため、
インデックスがWHERE条件をカバーしてもSELECTをカバーしないとカバリングインデックスと判断されないことだ。
そのため、下記のようなクエリは、チューニングを台無しにする。


```sql
SELECT
  *
FROM
  users
WHERE
  age >= 20
  AND name LIKE "riita%"
```

これはUsing Whereとなる。

SELECT * により、全ての列をカバーしているインデックスのみがカバリングインデックスであり、そのようなインデックスは存在しないため。

この場合は、カバリングインデックスとして、(id, age, name)を採用して、
(※ InnnoDBでは、セカンダリインデックスがリーフノードに主キー値を格納するため、事実上では、インデックス(id, name)は上記のクエリをカバーし、実際上記のクエリに対して、インデックスを使用する)


```sql
SELECT
  *
FROM
  users AS list
INNER JOIN (
  SELECT
    id
  FROM
    users
  WHERE
    age >= 20
    AND name LIKE "riita%") AS ind
ON
  ind.id = list.id
```

とすることで、カバリングインデックスとして、探索をすることができる。
ただし、WHERE句のヒット率が高すぎる場合、行を取得するコストを削減するよりも、
相関サブクエリを起動するコストがかかってしまいあまりパフォーマンスが改善されないような場合もある。

## ソートのためのインデックススキャン
ORDER BY句をインデックスがカバーしていれば、そのインデックスを用いて並び替えを行うため、
クイックソートアルゴリズム$O(nlogn)$を使用する必要がなくなる。
クイックソートアルゴリズムを使用するとオプティマイザーが判断した時、Explain句のExtra列にUsing filesortと記述されることを確認すると良い。

ORDER BYがインデックスで順序付けをすることができるのは下記の場合である。

- まず、WHERE句とORDER BY句がどちらもインデックスにカバーされている必要がある。
- そして、インデックスの順序がORDER BY句と同じかつ、全ての列が同じ方向でソートされている場合
- 左端プレフィックスの原則を満たしている
    - WHERE句によって定数を確保していれば問題ない

以下のような時には、順序付けにインデックスが使用されないので注意
- `ORDER BY id DESC, age ASC`としているが、インデックスがASCで並んでいる
- WHEREまたはORDER BYをインデックスがカバーできていない
- カバーしていても左端プレフィックスの原則に準拠していない
- 最右端以外のインデックスが範囲指定をしてしまう(範囲指定すると残りのインデックスを使用できない)

## 冗長インデックス、重複インデックス
やめましょう


## 参考

実践ハイパフォーマンスMySQL 第3版
Baron Schwartz、Peter Zaitsev、Vadim Tkachenko　著、菊池 研自　監訳、株式会社クイープ　訳
2013年11月 発行
https://www.oreilly.co.jp/books/9784873116389/
Lambda Authorizerでカスタムエラーメッセージを出力する


Lambda Authorizerでカスタムのエラーメッセージを出力したい時。

Lambda Proxy統合の場合ステータスコードが変更できないのでDenyポリシーを返す403限定ではありますが、context変数にエラーメッセージ等を格納し、ゲートウェイレスポンスのレスポンステンプレートを編集することで可能です。

context変数はこちらのドキュメントにそって定義します。
[Amazon API Gateway Lambda オーソライザーからの出力 \- Amazon API Gateway](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html)

レスポンステンプレートはCloudFormation的にはこんな感じで定義します。
この例でいうと、`context.message`と`context.code`をLambdaの方で定義します。

```yaml
  GatewayResponse:
    Type: "AWS::ApiGateway::GatewayResponse"
    Properties:
      ResponseTemplates:
        application/json: >
          {"message":"$context.authorizer.message", "code":"$context.authorizer.code"}
      ResponseType: DEFAULT_4XX
      RestApiId: !Ref ResourceApi
```
メモリリーク検出ライブラリ「LeakCanary」のセットアップ&使い方

## はじめに

Androidアプリ開発で使えるメモリリーク検出ライブラリを教えてもらったので、導入することにしました。

## 「LeakCanary」とは？

Android向けのメモリリーク検出ライブラリです。

## 環境

- OS：macOS Big Sur 11.1
- Android Studio：4.1.2
- Kotlin：1.4.20
- Gradle：6.8
- Gradle plugin：4.1.2
- LeakCanary：2.6

## セットアップ

### LeakCanaryのインストール

appフォルダ配下の「build.gradle」に依存関係を追加します。

```diff_groovy:/app/build.gradle
android {
     defaultConfig {
+         // For LeakCanary in instrumentation tests
+         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+         testInstrumentationRunnerArgument "listener", "leakcanary.FailTestOnLeakRunListener"
    }
}

dependencies {
+     // LeakCanary
+     def leakcanary_version = '2.6'
+     debugImplementation "com.squareup.leakcanary:leakcanary-android:$leakcanary_version"
+     androidTestImplementation "com.squareup.leakcanary:leakcanary-android-instrumentation:$leakcanary_version"
}
```

インストルメンテッドテストでLeakCanaryを実行しない場合は `debugImplementation` の追加のみでOKです。

これだけでLeakCanaryのセットアップは完了です。

## 使い方

### メモリリーク検出の開始

Android Studioから開発しているアプリを実行するだけで、メモリリークの検出が始まります。

Logcatに以下の文字列が出力されていたら、無事に実行されています。

```
D LeakCanary: LeakCanary is running and ready to detect leaks
```

### メモリリーク検出の確認

LeakCanaryは別アプリになっているので起動します。
![Screenshot_1614686735.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/ad1f06bd-071d-941e-47de-b9d92a76b195.png)

[Leaks]タブでメモリリークの検出を確認できます。
![Screenshot_1614686711.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/6e993560-1fb6-c322-cb83-9cdab2d81dd1.png)

私が開発しているアプリではメモリリークが検出されませんでした。

## おわりに

かんたんにAndroidアプリのメモリリークを検出できました！
どのようなアプリの開発でも有用だと思います。

## 参考リンク

- [LeakCanary](https://square.github.io/leakcanary/)
- [Getting Started - LeakCanary](https://square.github.io/leakcanary/getting_started/)
- [Upgrading to LeakCanary 2 - LeakCanary](https://square.github.io/leakcanary/upgrading-to-leakcanary-2.0/)
- [square/leakcanary: A memory leak detection library for Android.](https://github.com/square/leakcanary)
- [Setup LeakCanary · Issue #90 · uhooi/UhooiPicBook-Android](https://github.com/uhooi/UhooiPicBook-Android/issues/90)
- [Add LeakCanary dependencies #90 by omooooori · Pull Request #91 · uhooi/UhooiPicBook-Android](https://github.com/uhooi/UhooiPicBook-Android/pull/91)
vue.jsで作ったサイトをgithubに保存してnetlifyで公開する方法


vue.jsのquasar cliを使って作ったサイトをネットリファイで公開することにしました。
ネットリファイはファイルをドラッグアンドドロップするだけでサイトとURL作成されて公開ができるのですが、
毎回手動デプロイだと、デプロイするごとに新しいURLが作成されたり、してサイトは更新が非常に手間です。
なので、ギットハブと連携させることで、git pushをするだけでサイトの内容だけ自動更新されて、
更新が非常に楽になります。


１，githubのサイト上で新しくrepositoryを作成する


作業中のフォルダで（今回はorigin-investment-requestというフォルダ）でターミナルを開き、



２，ターミナルでギットハブにアップロードする

```
smac@smac origin-investment-request % git init
Initialized empty Git repository in /Users/smac/Desktop/origin-investment-request/.git/

smac@smac origin-investment-request % git add .
smac@smac origin-investment-request % git commit -m "first commit"

〜いろんなファイルがコミットされる〜

smac@smac origin-investment-request % git remote add origin ”リポジトリのアドレスをコピペ”
smac@smac origin-investment-request % git push -u origin master

```


３，netlifyで公開する
new site from gitをクリックして
ギットハブの自分のレポジトリまでアクセスする

問題はここからで、
ギットハブにはdistフォルダがアップロードされていない。でも公開するのはdistフォルダという、状況になる

なので、ネットリファイのデプロイ設定で、
①ビルドコマンドを指定して
②公開ファイルをdistではなく、その中身の、dist/spaと指定しないと、表示されない
![スクリーンショット 2021-03-02 21.19.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/898667/f8abe6c6-efeb-f84c-ea64-e62e8b161ffa.png)



![スクリーンショット 2021-03-02 20.53.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/898667/103add17-1492-ee51-55a7-e54b33801f90.png)


これで無事公開されて見れるようになりました。

サイトを更新したら、git pushすれば、ネットリファイで自動ビルドされて、自動更新されるという流れですね
Nuxt.jsでscss導入しようとしたらエラッた


## 開発環境
macOS:  10.15.7
node: 14.15.3
npm: 6.14.9

## 再現方法 （2021.03.02時点）

`npx create-nuxt-app projectName-xxxx`

上記で諸々をインストール後に、下記でscssに必要なパッケージをインストール

`npm install --save-dev node-sass sass-loader @nuxtjs/style-resources`

そしてvueファイルの

```
<style>
  ...
</style>
```
を、↓に書き換える

```
<style lang="scss">
  ...
</style>
```

そして、`npm run dev`を実行すると下記エラー


```
 ERROR  Failed to compile with 1 errors                                                                                                                                                                                                                                                               friendly-errors 20:33:55


 ERROR  in ./pages/index.vue?vue&type=style&index=0&lang=scss&                                                                                                                                                                                                                                        friendly-errors 20:33:55

Module build failed (from ./node_modules/sass-loader/dist/cjs.js):                                                                                                                                                                                                                                    friendly-errors 20:33:55
TypeError: this.getOptions is not a function
    at Object.loader (/Users/xxxx/node_modules/sass-loader/dist/index.js:25:24)
```

## 原因
Nodeと下記パッケージのバージョンがうまく噛み合っていないよう。
この段階でインストールされているパッケージのバージョンは↓

package.json

```
    "node-sass": "^5.0.0",
    "sass-loader": "^11.0.1",
```

## 解決方法
`node-sass`と`sass-loader`のバージョンを下げたらエラー解消した

## 解決方法の詳細

#### 1. まずは`node-sass`のバージョンを下げてみる

`npm uninstall --save-dev node-sass`でアンインストールして、
`npm install --save-dev node-sass@4.14`でバージョン指定して再インストール

##### `npm run dev` 実行 → エラー解消せず（先述のエラー発生）

#### 2. `sass-loader`のバージョンも下げてみる
`npm uninstall --save-dev sass-loader`でアンインストールして、
`npm install --save-dev sass-loader@10.1.0`でバージョン指定して再インストール

##### `npm run dev` 実行 → エラー解消！！

## 所感
エラー解消してよかった〜

## 補足
今回のエラーに関しては、ググった感じでは他に起因するケースもあるようです。
本記事は原因の一つとしてご参考までにmm
環境構築　1　VSCode

##VSCodeをインストール
プログラミング開発に特化したものになっていて、エンジニアには非常に人気が高いエディタの一種です。

https://code.visualstudio.com/
ダウンロード

ダウンロードが終わったら、ダウンロードファイルからアプリケーションフォルダにドラッグ&ドロップします。

##拡張機能の導入
VSCode内の画面左側の、アイコンメニュー内にある四角のアイコンをクリック。
拡張機能インストール後、再起動すると反映されます。
####便利な拡張機能
・Japanese Language Pack for Visual Studio Code
　日本語表記にします。

・HTML Snippets
　HTMLタグ、CSSタグの入力を補完してくれます。

・Ruby
　Rubyの構文をチェックし、間違った箇所を指摘してくれます。

・zenkaku
　全角スペースを知らせてくれます。

・Code Spell Checker
　コードのスペルをチェックしてくれます。

##VSCodeのカスタマイズ
####・半角スペースの設定

1. VSCodeのサイドバーより、「管理（下部の歯車マーク）」→ 「設定」の順に選択
2. Editor: Tab Sizeを２に設定
3. Editor: Render Whitespaceで「all」を選択

####・オートセーブ設定
1. VSCodeのサイドバーより、「管理（下部の歯車マーク）」→ 「設定」の順に選択（直前の作業に続けて行う方は、この操作の必要はありません）
2. オートセーブの設定で「onFocusChange」を選択
Athenaでnullなデータを読む

### やりたいこと
JSONL（※）ファイルをGlue Crawlerで認識しAthenaで読む際、nullなデータがあった場合どうなるかを知りたい。

※[JSON Lines](https://jsonlines.org/)。改行コードをデリミタとして1行1レコードに分割したJSONのこと。AthenaはJSONLしか扱えないので注意。

### データを作る

nameをstring、ageをintと想定してサンプルデータを作る。

```json:json-test.json
{ "id": 001, "name": "Kamado", "age": 16 }
{ "id": 002, "name": "Kibutsuji", "age": null }
{ "id": 003, "name": null, "age": 19 }
{ "id": 004, "name": "Gyutaro", "age": 0 }
{ "id": 005, "name": "", "age": null }
{ "id": 006, "name": "Uzui" }
{ "id": 007, "age": 32 }
```

```bash
% aws s3 cp ./json-test.json s3://<バケット名>/jsontest/
```

### スキーマを読み取る

jsondbというデータベースを作り、上記S3パスを走査対象としたGlue Crawlerを作成し、実行する。
（※詳細は省略）

読み取られたスキーマはこちら。
int、stringとintとして読み取られていることが分かる。テーブルはS3パス名を反映してjsontestとなっている。

![スクリーンショット 2021-03-02 午後6.28.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/5c3c5f48-a403-5cd7-766f-d379a28178b8.png)

### Athenaで検索

まずは全件。
![スクリーンショット 2021-03-02 午後8.36.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/90a9e359-bc59-be85-df24-cd58604944df.png)

null、空文字（""）、項目なしは、ぱっと見いずれも同じ扱いに見える。

name（string）がnullのものをクエリーしてみる。![スクリーンショット 2021-03-02 午後8.37.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/7b48ed14-114a-e23c-a63d-d4f4dc78e63f.png)

id=3（null）とid=7（値なし）が検索され、id=4（空文字）は除外された。
両者は同じ扱いな一方で、空文字は別扱いされていることが分かる。

intについても確認。
![スクリーンショット 2021-03-02 午後8.38.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/d899639b-bb6c-a371-9cf7-de0b0ca39556.png)

id=2（null）、id=5（null）、id=6（値なし）が検索された。id=4（0）が除外されるのはまあ当たり前。
ここでも、nullと値なしが同じ扱いなのが確認できた。

### 結論

- GlueでもAthenaでも、JSONLに含まれたnullを扱える。
- nullと値なしは同等の扱いのため、出力元コードやAthenaの処理量を少しでも減らしたい場合は、nullで埋めずに値なしでJSONL出力するのもあり。
[rails] 多対多の中間テーブル [to_table, class_name, through, source]




　　　　　　gift　　　　　　　　　　　　　　　
User　ーーーーーーーー＞　Profile　　　　　　　　　ギフトを贈る

[![Image from Gyazo](https://i.gyazo.com/8a77616e9c882a3aad12898f4574d6a7.png)](https://gyazo.com/8a77616e9c882a3aad12898f4574d6a7)

```20210301082221_create_gifts_.rb
class CreateGifts < ActiveRecord::Migration[6.0]
  def change
    create_table :gifts do |t|
      t.integer    :price,    null: false
      t.references :giver,    foreign_key: { to_table: :users }
      t.references :receiver, foreign_key: { to_table: :profiles }
      t.timestamps
    end
  end
end
```


```gift.rb
class Gift < ApplicationRecord
  belongs_to :giver, class_name: 'User', foreign_key: :giver_id
  belongs_to :receiver, class_name: 'Profile', foreign_key: :receiver_id
end
```


```user.rb
class User < ApplicationRecord
  has_many :gifts, class_name: 'Gift', foreign_key: 'giver_id'
  has_many :receivers, through: :gifts, source: :receiver
end
```


```profile.rb
class Profile < ApplicationRecord
  has_many :gifts, class_name: 'Gift', foreign_key: 'receiver_id'
  has_many :givers, through: :gifts, source: :giver
end
```

---

foreign_key: { to_table: :users }　　usersテーブルから参照してね

class_name: 'User'　　　　　　　 Userクラスから参照してね

through: :gifts　　　　　　　　　　giftsテーブルを通してね

source: :giver　　　　　　　　　　giverモデルが参照元だよ

---
foregin_key = 入口
source = 出口

という記事を見させていただいて、非常にわかりやすかったです。
記事は<a href="https://qiita.com/mitsumitsu1128/items/e41e2ff37f143db81897#relationships%E3%83%A2%E3%83%87%E3%83%AB%E3%81%A8user%E3%83%A2%E3%83%87%E3%83%AB%E3%81%AB%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E6%9B%B8%E3%81%8F">こちら</a>
略語(頭字語、固有名詞)のSwiftyな命名規則

[Swift標準APIのURL構造体](https://developer.apple.com/documentation/foundation/url)の名前に疑問符が付いたので調べてみた。
Swift公式の命名規則として[API Design Guidelines](https://swift.org/documentation/api-design-guidelines/)があるが、ここでは略語に関して「標準的な略語以外は省略しないで書いてね」ぐらいしか書かれていない。よって、一般的な規則である「型とプロトコルの名前はUpperCamelCase、それ以外はlowerCamelCaseで書いてね」に沿って`Url`になるはずだが、なぜか`URL`になっているのだ。調べてみた結果帰納的に以下の規則で結論付けたのでまとめる。

## 標準的な略語の命名規則
- 単語の最初の文字の種類に揃える
- ただし、IPv4とIPv6のvは必ず小文字

## 例
[URL](https://developer.apple.com/documentation/foundation/url)
[CommandLineAPIHost](https://developer.apple.com/documentation/webkitjs/commandlineapihost?language=data)
[url](https://developer.apple.com/documentation/foundation/urlrequest/2011416-url)
[absoluteURL](https://developer.apple.com/documentation/foundation/url/1780323-absoluteurl)
[IPv6Address](https://developer.apple.com/documentation/network/ipv6address)
[ipv6Settings](https://developer.apple.com/documentation/networkextension/nepackettunnelnetworksettings/1406138-ipv6settings)

## 証拠
- [URL](https://developer.apple.com/documentation/foundation/url)の型名とか初期化子とかメンバーとか
- [XMLDTD](https://developer.apple.com/documentation/foundation/xmldtd)の型名とかプロパティーとか
- [UTTypeのSystem Declared Types](https://developer.apple.com/documentation/uniformtypeidentifiers/uttype/system_declared_types)
- [WebKit JS](https://developer.apple.com/documentation/webkitjs?language=data)のパッケージ名とかクラス名とか
- [Identifiable.ID](https://developer.apple.com/documentation/swift/identifiable/3285390-id)

## 例外
- [Url](https://developer.apple.com/documentation/devicemanagement/url)
- [threeDContent](https://developer.apple.com/documentation/uniformtypeidentifiers/uttype/3551580-threedcontent)
- [cPlusPlusHeader](https://developer.apple.com/documentation/uniformtypeidentifiers/uttype/3551473-cplusplusheader)
- [CXXSetting](https://developer.apple.com/documentation/swift_packages/cxxsetting)

下三つに関しては表記可能な文字で代替するようだ。C++の表記揺れも見られるので統一して欲しい。

## 所感
IPv6が全てを狂わせた。おそらく"IP"で一つの単語として原則に従わせ、"v6"は可読性重視で固定にしているのだと思う。
先頭に来ないiOSやmacOSはどうなるんだろう？上記の規則だとIOS、MACOSだが。。。
(AWS Lambda) ffmpeg exited with code 126 at ChildProcess.

## 原因
AWSのLambdaで`ffmpeg-static`を利用してffmpegを利用しよとしたら表題のエラーが発生した。 
恐らく理由としては`ffmpeg-static`のバイナリをLambda上で実行できないためと思われる。

## 対処法
Lambda layersを使用して予め実行環境に用意しておくのがおすすめ。(バイナリをアップロードするやり方もあるがこちらの方がスマート)


```bash
// 最新版
wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz

// 以下のディレクトリ構成でzipさせてアップロードさせる
ffmpeg/
|__bin
   |__ffmpeg (バイナリ)
```
α-βフィルタ(g-hフィルタ)まとめ

# α-βフィルタ(g-hフィルタ)
α-βフィルタ(g-hフィルタ)は観測値をモデルに基づいた予測値で修正することでノイズを除去するフィルタです。
α-βフィルタ(g-hフィルタ)は以下2つのステップから構成されます。

1. 事前予測ステップ
    事前予測ステップでは現時刻の事後予測のデータから次の時刻での状態を推測します。推測にはモデルが使われます。

2. 事後予測ステップ
   事後予測ステップでは算出された事前予測を観測された状態を用いて修正します。事後予測の出力がフィルタ後のデータとして使用されます。     また、算出された事後予測は次の事前予測で使われます。

α-βフィルタでは、この1と2のステップをひたすら繰り返します。

# モデル
モデルの表現には状態空間表現を用います。時刻$k$の状態量を$x_k$、観測値を$z_k$とするとモデルは一般的に以下のように表すことができます。

```math
x_{k+1} = A x_k + Bu_k \\
z_k = C x_k
```

ここに状態$x_k$は、

```math
x_k=
\begin{pmatrix}
x \\
\dot{x}
\end{pmatrix}
```

です。物理量としては位置と速度からなるベクトルとなります。

# 事前予測値
事後予測値とモデルを用いて1周期未来の状態を推測します。
事前予測値は以下の通りモデルに事後予測値を代入することで得られます。

```math
\hat{x}_{k+1, k} = A \hat{x}_{k,k}+Bu_k \\
```

# 事後予測値
事前予測値を観測データで修正します。

```math
\hat{x}_{k+1, k+1}=\hat{x}_{k+1, k}+K(z_{k+1}-C\hat{x}_{k+1,k})
```

ここにKは以下の$\alpha$と$\beta$という2つの定数からなる定数ベクトルです。

```math
K=\begin{pmatrix}
\alpha \\
\beta
\end{pmatrix}
```

$\alpha$と$\beta$の値が大きいほどセンサの出力がフィルタの出力に反映されます。その反面、大きくなるほどノイズも出力されるようになります。$\alpha$と$\beta$はちょうどいい値にチューニングする必要があります。

# 事後予測値初期値
事後予測値初期値 は適当でも計測するにつれて収束していくので適当に選んでも問題ありません。
適当に0ベクトルをいれておけば問題なさそうですが、センサデータを使用するまえに収束するまで待つ時間が必要になってきます。「そんなの待てない」というせっかちさんは事後予測値初期値を時刻0でのセンサデータで初期化しましょう。

```math
\hat{x}_{0, 0} = C^{-1} z_0
```

# 参考文献

- [Boost Library : Basic Linear Algebra Library](https://www.boost.org/doc/libs/1_65_0/libs/numeric/ublas/doc/index.html)
- [Fix Your Measurements With Alpha-Beta Estimator- Python](https://towardsdatascience.com/fix-your-measurements-with-alpha-beta-estimator-python-6cddfb3ac24)
Android開発メモ① Activity ドキュメントの自分用まとめ

#Android開発メモ① Activity ドキュメントの自分用まとめ

要は[アクティビティの概要](https://developer.android.com/guide/components/activities/intro-activities?hl=ja)のまとめ

## [アプリアーキテクチャガイド](https://developer.android.com/jetpack/guide?hl=ja)
またの機会に

## コンセプト
* main() メソッドで起動するアプリをプログラミングする際の枠組みとは異なり、Android システムでは、ライフサイクルのそれぞれの段階に対応するコールバック メソッドを呼び出すことにより、Activity インスタンス内のコードが開始されます。
* 一つのアプリが別のアプリを呼び出しやすくする、モバイル特有の画面遷移を実現
* アクティビティにより、アプリがUIを描画するウィンドウが用意される。  
  - 通常ウィンドウが画面全体だが、小さくなったり、重なったりする
* アクティビティ関係は緩やかな結びつきで依存関係はほとんどない
* アクティビティを利用するにはマニフェストに登録する必要がある

## マニフェストの設定

```xml
    <manifest ... >
      <application ... >
          <activity android:name=".ExampleActivity" />
          ...
      </application ... >
      ...
    </manifest >
    
```
## インテントフィルタ
* 明示的なリクエスト
  * 「Gmail アプリでのメール送信アクティビティの開始」
* 暗黙的なリクエスト
  * 「この作業を行えるアクティビティでのメール送信画面の開始」

```xml
    <activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="text/plain" />
        </intent-filter>
    </activity>
```

## パーミッション
マニフェスト内で```<uses-permission>```することでアクティビティの呼び出し権限を制御できる

## ライフサイクル
おなじみのonCreate()など
ライフサイクルの項でまとめる
ex modeからカーソル操作してみる (Vim/Vimscript)

#概要
Vimscriptに親しむため、ex modeからカーソルを移動してみる。

やってみたかっただけ。カーソル操作の理解が深まる気がした。
#内容
##環境
macOS Catalina
VIM - Vi IMproved 8.1 macOS version Normal version without GUI.

今回は基本的に、vim起動、`:`で実行し確認する。
##準備
```:tmp.txt
a,a,a,a,a
b,b,b,b,b
c,c,c,c,c
```
上記ファイルを開き、真ん中のbにカーソルを置く。
##実行
```Vimscript:
:call cursor(line('.'), col('.')+1)
```
一個右にずれた。

##蛇足
`cursor`：指定(行,列)にカーソルを移動する。
`line`：`'.'`を受けると、カーソルの行目を返す。
`col`：`'.'`を受けると、カーソルの列目を返す。

#参考にさせていただいた頁・本
- https://stackoverflow.com/questions/9953082/how-to-jump-directly-to-a-column-number-in-vim
- https://vim-jp.org/vimdoc-ja/usr_41.html#cursor-functions

#感想
できて良かった。
#今後
スクリプトを読む助けにしたい。
Vimscriptでautocommandを試してみる (Vim/Vimscript)

#概要
Vimscriptに親しむため、少しautocommandを使ってみる。
#内容
##環境
macOS Catalina
VIM - Vi IMproved 8.1 macOS version Normal version without GUI.

今回は、基本的にvim起動後、:を入力し、順次実行する。
##内容
```Vimscript:vim
:autocmd BufNewFile * :echo "Hello, new file!"
:e tmp.txt
```
```:output
"tmp.txt" [New File]
Hello, new file!
```
新ファイル`tmp.txt`を開くのが、`BufNewFile`に該当し、`:echo`以下が実行される。

```:explanation
:autocmd BufNewFile * :write
         ^          ^ ^
         |          | |
         |          | The command to run.
         |          |
         |          A "pattern" to filter the event.
         |
         The "event" to watch for.
```
https://learnvimscriptthehardway.stevelosh.com/chapters/12.html の図を使わせていただいた。
##蛇足

|Reading||
|:--|:--|
|BufNewFile|starting to edit a file that doesn't exist
|BufReadPre|starting to edit a new buffer, before reading the file
|BufRead|starting to edit a new buffer, after reading the file
|BufReadPost|starting to edit a new buffer, after reading the file
|BufReadCmd|before starting to edit a new buffer
|||
|FileReadPre|before reading a file with a ":read" command
|FileReadPost|after reading a file with a ":read" command
|FileReadCmd|before reading a file with a ":read" command
|||
|FilterReadPre|before reading a file from a filter command
|FilterReadPost|after reading a file from a filter command
|||
|StdinReadPre|before reading from stdin into the buffer
|StdinReadPost|After reading from the stdin into the buffer

autocommand-eventsにはReadingの他に、Writing、Buffers、などの分類あり。


実装時には、重複・削除される可能性を考えて、`augroup`を併せて活用する。

#参考にさせていただいた本・頁
- https://learnvimscriptthehardway.stevelosh.com/chapters/12.html
- https://vimhelp.org/autocmd.txt.html#autocmd-events

#感想
何となく.vimrcに書いていたことが分かって良かった。
#今後
活用できる時があったら使っていきたい。
Vimscriptで関数を試してみる (Vim/Vimscript)

#概要
Vimscriptに親しむため、少し関数で遊んでみる。
#内容
##環境
macOS Catalina
VIM - Vi IMproved 8.1 macOS version Normal version without GUI.

今回は基本的に、外部ファイル記述保存し、vim起動後、`:call`で実行する。

## Hello, world
基本的に、ユーザ定義関数は、大文字から始めるか、`s:`を付けないといけない。

```Vimscript:hello.vim
function Hello()
  echo "Hello, world"
endfunction
```
```Vimscript
:so hello.vim
:call Hello()
```
```:output
Hello, world
```
今回は、`:`から`call`しているので、`s:`は使いにくい。
## 引数を扱う
```Vimscript:hello.vim
function Hello(...)
  echo a:0
  echo a:1
  echo a:2
  for s in a:000
    echon ' ' . s
  endfor
endfunction
```
```Vimscript
:so hello.vim
:call Hello("Hello,", "world")
```
```:output
2
Hello,
world Hello, world
```
`a:0`：引数の個数
`a:自然数`：n番目の引数
`a:000`：引数のリスト

(`echo`：多分改行コードとともに；`echon`：改行コードを加えたりはしない)
## コマンドから呼び出せるようにする
毎回`call ~ ()`を入力するのは大変なので、コマンドで呼び出せるようにする。

```Vimscript:hello.vim
function Hello()
  echo "Hello, world"
endfunction

command SayHello call Hello()
```
```Vimscript
:so hello.vim
:SayHello
```
```:output
Hello, world
```
##蛇足
コマンドで呼び出す場合、`s:`も使える。

```Vimscript:hello.vim
function s:hello()
  echo "Hello, world"
endfunction

command SayHello call <SID>hello()
```
```Vimscript
:so hello.vim
:SayHello
```
```:output
Hello, world
```
トラブルを避けるため、呼び出し時は`s:`の代わりに`<SID>`を使うと良いとのこと。

#参考にさせていただいた本・頁
- https://devhints.io/vimscript

#感想
楽しい。
#今後
少しずつできることを増やしていきたい。
Vimscriptでautoload関数を試してみる (Vim/Vimscript)

#概要
Vimscriptに親しむため、autoload関数を使用してみる。

起動の速さだけでなく、名前空間の利点もあるのでは？と期待して。
#内容
##環境
macOS Catalina
VIM - Vi IMproved 8.1 macOS version Normal version without GUI.

今回は基本的に、外部ファイル記述保存し、vim起動後、コマンドを実行する。

##準備
```Vimscript:~/.vim/autoload/hello.vim
function hello#Hello()
  echo "Hello, world"
endfunction
```
```Vimscript:vim
:call hello#Hello()
```
```:output
Hello, world
```
関数名は`(ディレクトリ#)ファイル名#ほにゃらら`で書く。

##便利にするために
コマンドを定義すると楽。(`nnoremap`を使えばさらに楽ではあるが)

```Vimscript:~/.vimrc
command SayHello call hello#Hello()
```
```Vimscript:vim
:SayHello
```
```:output
Hello, world
```

#参考にさせていただいた頁・本
- https://sites.google.com/site/hymd3a/vim/vim-autoload

#感想
関数名に#が入ってびびったが、
関数名にファイル名を含めなくてはいけないあたり、Vimらしくて好感。
#今後
機会があれば活用していきたい。
Vimscriptでコマンドから関数に引数を渡す (Vim/Vimscript)

#概要
Vimscriptに親しむため、コマンドから関数に引数を渡してみる。
#内容
##環境
macOS Catalina
VIM - Vi IMproved 8.1 macOS version Normal version without GUI.

今回は基本的に、外部ファイル記述保存し、vim起動後、コマンドを実行する。
##準備
```Vimscript:hello.vim
function Hello(...)
  echo a:1 . ", " . a:2
endfunction

command -nargs=* Say call Hello(<f-args>)
```
`-nargs=*`：0以上の引数をとる
`<f-args>`：コマンド引数はこれでユーザ定義関数に渡す。

##実行
```Vimscript:
:so hello.vim
:Say Hello world
```
```:output
Hello, world
```
引数は、文字列として渡されるので、`"Hello"`のようにしなくて良い。

#参考にさせていただいた本・頁
- https://devhints.io/vimscript
- https://stackoverflow.com/questions/3213657/vim-how-to-pass-arguments-to-functions-from-user-commands


#感想
.vimrcの記載がわかって良かった。
`command`に`-nargs`がくっついていると今更気づいた。
#今後
適宜活用したい。
VimscriptでHello world的な (Vim/Vimscript)

#概要
Vimscriptに親しむため、少しechoで遊んでみる。
#内容
##環境
macOS Catalina
VIM - Vi IMproved 8.1 macOS version Normal version without GUI.

今回は、基本的にvim起動後、`:`を入力し、順次実行する。
##hello
```Vimscript
:echo "Hello, " . "world"
```
```:output
Hello, world
```
できた。
##hello(変数も使って)
```Vimscript
:let name = "world"
:echo "Hello, " . name
```
```:output
Hello, world
```
##hello(editorらしく)
tmp.txt(1行)に名前を記入しておく。それを開いておく。

```:tmp.txt
world
```
```Vimscript
:echo "Hello, " . getline('.')
```
```:output
Hello, world
```
`.`：文字列の結合
`getline('.')`：カーソルがある位置の行内容を得る
cf: `getline(3)`：3行目の行内容を得る

##hello(将来も見つめて)
scopeも意識してみる。

```Vimscript
:let w:name = "world"
:echo "Hello, " . w:name
```
```:output
Hello, world
```
|prefix|explanation|
|:--|:--|
|g: |global|
|s: |local (to script)|
|l: |local (to function)|
|||
|w: |window|
|b: |buffer|
|t: |tab|
|v: |var|
|||
|@ |register|
|$ |env|
##hello(外部ファイルから)
hello.vimを記述保存し、`:so[urce] hello.vim`で実行する。

```Vimscript:hello.vim
echo "Hello, " . "world"
```
```Vimscript
:so hello.vim
```
```:output
Hello, world
```
できた。
#参考にさせていただいた本・頁
- https://devhints.io/vimscript

#感想
できた。
#今後
少しずつできることを増やしていきたい。
TD-Gammon でお試し

強化学習の教科書など読むと、かなり最初の方に Temporal Difference という手法が紹介されている。その手法はバックギャモンに応用され、強ーいプログラムができたと。その名は [TD-Gammon](https://researcher.watson.ibm.com/researcher/view_page.php?id=7021)。私がいくら古くても、このプログラムは使ったことがありません。確か最初に使ったのは JellyFish だったかな。

[TD-Gammon を PyTorch で実装](https://github.com/dellalibera/td-gammon)した素敵な方を見つけたので、少し動かしてみました。そのままでは動かなかったのと、dockerで使えるように[forkしました](https://github.com/mkisono/td-gammon-1/tree/docker)。

このレポジトリはいろいろ勉強になったのですが、学習させた bot を gnubg と自動で対戦させる仕組みもあり感動しました。今のところ、bot 同士の対戦で200,000回学習させました。初心者レベルにはなってますね。100,000回学習時点で gnubg と100回対戦。次に200,000回学習時点で 同じく gnubg と100回対戦。合計 200マッチをXGで解析してみました。

![スクリーンショット 2021-03-02 191513.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42252/f31bb3e8-a27c-c812-6e79-41f89c8be04a.png)
グラフを見ると明らかに右肩上がり！　ちゃんと学習して強くなってるようですね。頼もしいやつだ。しかも、ニューラルネットワークはまっさらな状態から始めているので、なんらの前提知識も入れていないのです。隠れ層のユニットは、[gnubgより多い 256](https://qiita.com/mkisono/items/aa1d551db5233808d886) にしています。

キューブについては何も学習してないので進歩はありません。gnubgからキューブが飛んできたら全部テイク。自分からは決してダブルしませんw

これだけでどこまで強くなるか、しばらく学習を続けてみようと思います。その間に私はお勉強して理屈を学ばないとね。
Python文字列関連の覚え書き

## この記事について
Pythonで文字列を扱って何かする際の色々を覚え書き的に順次追記していきます。

## 正規表現を使ったパターンマッチ
### 正規表現チートシート
https://qiita.com/tossh/items/635aea9a529b9deb3038

### パターンマッチとマッチ部分の抽出
以下のようなファイルから、学習曲線を描くための情報を抽出したいとする。

```:ファイル
(省略)
2021-01-18 13:48:13     3784964 parameters in model
2021-01-18 13:54:34     # =====> Epoch: 1 Average gen loss = 1.02231, KLD = 0.924802, total loss = 1.022387; Finished in 0:06:20.245799
2021-01-18 14:01:29     # =====> Epoch: 2 Average gen loss = 1.01518, KLD = 1.224245, total loss = 1.015275; Finished in 0:06:22.065888
2021-01-18 14:08:19     # =====> Epoch: 3 Average gen loss = 1.01342, KLD = 1.943195, total loss = 1.013566; Finished in 0:06:20.048240
(省略)
```

re モジュールの match 関数を使う。
`m = re.match(<パターン文字列>, <検索対象文字列>)`

パターン文字列の中の特定の部分(数字とか)を後から取り出したいときは、パターン文字列の中の当該部分を`()`でくくっておく。

```python:コード
log = []

for line in open(log_file):
    # マッチ結果が返ってくるので変数で受け取る
    m = re.match(r'.+Epoch:\s*(\d*)\s*Average gen loss =\s*(\d*\.\d*), KLD =\s*(\d*\.\d*),\s*total loss =\s*(\d*\.\d*).*', line)
    # マッチしていない場合は None が入っているんでスルー
    if m is not None:
        # m.group(0)は文字列全体、m.group(N) (N>0)はパターン文字列の中で()でくくった部分が入っている
        log.append(dict(
            epoch=int(m.group(1)),
            average_gen_loss=float(m.group(2)),
            kld=float(m.group(3)),
            total_loss=float(m.group(4))
        ))

df_log = pd.DataFrame(log)
# pip install tabulate しておけばmarkdown形式で表出力できます
print(df_log.to_markdown())
```

**出力**

|    |   epoch |   average_gen_loss |      kld |   total_loss |
|---:|--------:|-------------------:|---------:|-------------:|
|  0 |       1 |            1.02231 | 0.924802 |      1.02239 |
|  1 |       2 |            1.01518 | 1.22425  |      1.01527 |
|  2 |       3 |            1.01342 | 1.9432   |      1.01357 |
|  3 |       4 |            1.01169 | 2.33714  |      1.01187 |
ksnctf Jewel Writeup

本物のAndroidマルウェアの解析訓練にもなる良問なので， ksnctf Jewel の writeup を残そうと思う。

https://ksnctf.sweetduet.info/problem/15

ノーヒントで Jewel.apk が与えられるので JADX でデコンパイルする

AndroidManifest.xmlからエントリーポイントをさがす

```java
    <activity android:label="@string/app_name" android:name=".JewelActivity">
```
JewelActivityから動きそう

JewelActivity の OnCreate() を見るとすぐに AES とわかる

```java
    Cipher instance2 = Cipher.getInstance("AES/CBC/PKCS5Padding");
```

AES鍵は？

```java
        String deviceId = ((TelephonyManager) getSystemService("phone")).getDeviceId();
        try {
            MessageDigest instance = MessageDigest.getInstance("SHA-256");
            instance.update(deviceId.getBytes("ASCII"));
            String bigInteger = new BigInteger(instance.digest()).toString(16);
            if (!deviceId.substring(0, 8).equals("99999991")) {
                new AlertDialog.Builder(this).setMessage("Your device is not supported").setCancelable(false).setPositiveButton("OK", new C0001b(this)).show();
            } else if (!bigInteger.equals("356280a58d3c437a45268a0b226d8cccad7b5dd28f5d1b37abf1873cc426a8a5")) {
                new AlertDialog.Builder(this).setMessage("You are not a valid user").setCancelable(false).setPositiveButton("OK", new C0000a(this)).show();
            } else {
                InputStream openRawResource = getResources().openRawResource(R.raw.jewel_c);
                byte[] bArr = new byte[openRawResource.available()];
                openRawResource.read(bArr);
                SecretKeySpec secretKeySpec = new SecretKeySpec(("!" + deviceId).getBytes("ASCII"), "AES");
```

getDeviceId()でIMEIを取得している
!+IMEIがAES鍵だ！

ただし，動作に条件があり，
IMEIの先頭8文字 = 99999991
IMEIのSHA-256ハッシュ = 356280a58d3c437a45268a0b226d8cccad7b5dd28f5d1b37abf1873cc426a8a5
IMEIは15文字なので
999999910000000～999999919999999まで総当たりでハッシュ計算してターゲットのIMEIを計算する


IVは？

```java
    IvParameterSpec ivParameterSpec = new IvParameterSpec("kLwC29iMc4nRMuE5".getBytes());
```

ペイロードは？

```java
    InputStream openRawResource = getResources().openRawResource(R.raw.jewel_c);
```

問題データ Jewel.apk の拡張子を zip にして ペイロードを取り出す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/921ac023-30c6-df29-163a-41dc173a62fb.png)

あとは，CyberChefで料理するだけ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/dfbc4619-5215-9605-8edc-19e3cc391f97.png)

※なお，もしこれが本物の Android マルウェアならば，ここからが本番。
IT用語英語

IT用語英語

個人的なメモなのであてにしないで下さい。
追加していきます。

A
B
C
D

E
editing（えでぃしぃんく）
→編集

everywhere（えぶりうぇあ）
→ どこにでも

F
G
H
I
J
K
L
M
N

O
other（あざー）
→ その他

P
platforms（ぷらっとふぉーむ）
→ プラットフォーム、台、演壇、演台、舞台

Q

R
redefined（りーどふぁいんど）
→ 再定義

S
stable（すてーぶる）
→ 安定

T
U
V
W
X
Y
Z
flysystem-aws-s3-v3は~1.0を使いましょう

#概要
LaravelからAWS S3に画像をアップロードをしようとしたら起きた事象です。

> Class 'League\Flysystem\AwsS3v3\AwsS3Adapter' not found


#原因

Laravelの[Readable](https://readouble.com/laravel/8.x/ja/filesystem.html)を見たら、

> Composerパッケージ
S3やSFTPドライバーを使用するときは、事前にComposerパッケージマネージャーを介して適切なパッケージをインストールする必要があります。
Amazon S3: league/flysystem-aws-s3-v3 ~1.0

と書かれておりました。


何も考えずにインストールしたら、
> composer require league/flysystem-aws-s3-v3

2.0が入ってしまっていたので、ダウングレードします。

> composer require league/flysystem-aws-s3-v3 ~1.0


無事直せました。
findを使ってデータを一か所に集めたい　＋自動削除も

#ユースケース
radikoで録音した音源、クラウドにアップロードしたいが手動のコピーや削除が面倒なので自動化したい
#環境
debian_version:9.4
#最新〇〇日のデータをコピー

ラジオフォルダに保存されているデータ(サブディレクトリを含む)をクラウドにコピーします

```
例）
ラジオ---
       |---オードリーのオールナイトニッポン---20210302オードリーのオールナイトニッポン.mp3
       |---有吉弘行のsundaynightdreamer---20210202有吉弘行のsundaynightdreamer.mp3
       |---霜降り明星のオールナイトニッポンゼロ---20200103霜降り明星のオールナイトニッポンゼロ.mp3
```
```
find /録音ディレクトリ -mtime -最新〇〇日 -iname *.mp3 -exec cp -n --target-directory /コピーしたいクラウドストレージ {} \;
```
結果
最新〇〇日データのみクラウドのストレージにコピーされました。

```
BOX---20210302オードリーのオールナイトニッポン.mp3,20210202有吉弘行のsundaynightdreamer.mp3,
```

#〇〇日以降経過したデータの削除
こちらはfindとrmを組み合わせて、〇〇日以降経過したデータを削除します。

```
find /クラウドストレージ -iname *.mp3  -type f -mtime +〇〇日＋１ -exec rm -rf {} \;
```
あとはcrontabに登録し、毎日実行させてば自動化されます。

楽しいデータ管理ライフを！
EslintとPrettierをReactプロジェクトで使用(備忘録)

<h2>目的</h2>
[公式](https://prettier.io/docs/en/integrating-with-linters.html#notes)では基本的には非推奨となっているみたいなので、
"eslint-plugin-prettier"を使わずに、Reactで作成したプロジェクトをVSCodeで保存時に
 フォーマットの自動整形と構文チェックをする。


***前提***

* node.jsとyarnはインストール済み
* `npx create-react-app`でプロジェクト作成  
(この時、eslint 系パッケージはreact-scriptsに含まれている。yarn.lockで確認。)
* Typescriptはここでは使用せず  

* VS Code extensionsにて　eslintとprettierを導入済み  
(VSCode 拡張用の prettier は、node_modules に prettier がインストールされていれば、そちらを実行するようになっている。ここではCLIでコマンドで実行させずに、エディタ上で自動整理を実行させるために、インストールしておく。)  
https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint  
https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode

<h2>手順</h2>
1, `npx create-react-app sample` 
2, `cd sample`
3, ` yarn add -D eslint prettier eslint-config-prettier ` 
4, `yarn run eslint --init`   　:eslintrc.jsonファイル作成  (質問に答えていきます)
5,　各ファイルを編集 　(prettierrc.jsonは作らず、デフォルトのままになってます。)
   



```eslintrc.json
{
  "env": {
    "browser": true,
    "es2021": true,
    "jest": true 
  },
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:prettier/recommended",
    "prettier" //eslintのフォーマットの機能を上書きして機能の競合をなくす
  ],
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 12,
    "sourceType": "module"
  },
  "plugins": ["react","prettier"],
  "rules": {
    "react/react-in-jsx-scope": "off",
    "prettier/prettier": "error"
  }
}

```
```settings.json
{  *省略

　//liner
  "editor.codeActionsOnSave": { "source.fixAll.eslint": true },
  "eslint.alwaysShowStatus": true,
  "eslint.lintTask.enable": true,

  //formatter
  "editor.formatOnSave": true,
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "editor.formatOnPaste": true,
  "prettier.packageManager": "yarn",
  "javascript.format.enable": false,

  "files.autoSave": "onFocusChange",
}
```


<h2>参照</h2>
* https://medium.com/how-to-react/config-eslint-and-prettier-in-visual-studio-code-for-react-js-development-97bb2236b31a
* https://ai-can-fly.hateblo.jp/entry/prettier-usage  
* https://knote.dev/post/2020-08-29/duprecated-eslint-plugin-prettier/
Qiitaで文字の色変えたい

##結論```<font color="RedとかOrangeとかGreen">ここに色を変えたい文字</font>```

まあ、一応やってみよう。

```
<font color="Green">こんにちは！！</font>
```
この上の文章をコピーしてQiitaとかに貼り付けると。。

<font color="Green">こんにちは！！</font>

上のような感じになります。

"Green"の部分に色の指定をしますが、その際最初は大文字になります。

大暴れ編

```
###<font color="Red">私の</font><font color="Orange">名前は</font><font color="LightGreen">レ</font><font color="Green">イ</font><font color="SkyBlue">ン</font><font color="Blue">ボ</font><font color="Navy">ー</font><font color="PurPle">マン</font>
```
###<font color="Red">私の</font><font color="Orange">名前は</font><font color="LightGreen">レ</font><font color="Green">イ</font><font color="SkyBlue">ン</font><font color="Blue">ボ</font><font color="Navy">ー</font><font color="PurPle">マン</font>

いろんな色を使って遊んでみようと思います。

##参考資料
https://qiita.com/twipg/items/d8043cd4681a2780c160
[Amazon linux 2] /tmp配下の自動削除

# /tmp配下ファイル削除の仕組み
* /tmp配下ファイルの削除タイミングは、systemdのtimerで指定されています。
* systemd-tmpfiles-clean.timerの中身を確認することで、そのタイミングを知ることができます。(**デフォルト: 起動後 15 分経過時点と、それ以降に一日置きにタイマーが発火**)

```
$ sudo systemctl cat systemd-tmpfiles-clean.timer
　...
　[Timer]
　OnBootSec=15min
　OnUnitActiveSec=1d
```


* タイマーが発火後は、以下のコマンドが実行されます。

```
$ sudo systemctl cat systemd-tmpfiles-clean.service
...
ExecStart=/usr/bin/systemd-tmpfiles --clean
```

* --clean オプションを指定していると、 systemd-tmpfiles.d の設定ファイルで Age パラメータでした期間を経過したファイルが削除されます。

* 削除対象のファイルは、/usr/lib/tmpfiles.d/tmp.confで指定されています。
/usr/lib/tmpfiles.d/tmp.confのファイルの中を確認すると、**デフォルトで/tmpは10日、/var/tmpは30日**で配下のファイルが削除される設定が書かれています。

```

$ cat /usr/lib/tmpfiles.d/tmp.conf
...
# Clear tmp directories separately, to make them easier to override
v /tmp 1777 root root 10d
...
```

## 次回及び前回のタイマー発火時刻の確認方法
* Amazon linux2だと、systemd list-timersコマンドで確認できます。

```
sh-4.2$ sudo systemctl list-timers
```
line-bot-sdkをインストールしたらsocketsがないって言われた

#環境・前提
筆者は素人です。
この記事は記録が目的です。
ただ、流れくらいは参考になって欲しい。

windows10homeにdocker-composeでLEMP環境を作り、Laravelのプロジェクトを作成。
LaravelでLINE Botを作りたいのでline-bot-sdkを入れたかった。

#やったこと
dockerのコンテナで
```$ composer require linecorp/line-bot-sdk 4.2.*```
を実行。

#エラーの内容
```
Problem 1
    - Installation request for linecorp/line-bot-sdk 4.2.* -> satisfiable by linecorp/line-bot-sdk[4.2.0].
    - linecorp/line-bot-sdk 4.2.0 requires ext-sockets * -> the requested PHP extension sockets is missing from your system.
```
要はext-socketsというやつがないからエラーになるっぽい。

#解決策を調べた
ググったら2つのやり方が出てきた。

1つはphp.iniファイルにある
```;extension=sockets```
のコメントアウトを外す、というもの。
でも自分のphp.iniにはそもそも```;extension=sockets```自体がなかった。

2つ目はDockerfileの

```
RUN
  docker-php-ext-install
```
に```sockets```を加えるというもの。

で、```php -m```コマンドを実行してインストールされているモジュールを確認したところ、
socketのモジュールがなかったので2つ目のやり方でいけると予想。

#解決方法
2つ目のやり方で```Dockerfile```に変更を加え、コンテナから出て
```$docker-compose down```
```$docker-compose up -d --build```
を実行。
これで```Dockerfile```の再読み込みを行う。

#結果
無事いけました！
VBScript で WordファイルをまとめてHTMLに変換する

# 機能

指定したフォルダにあるWordファイルを全てHTMLに変換し、別のフォルダに保存します。
Wordで開いてHTMLとして保存、という処理を繰り返します。

# 実行環境

Windows 10

# コード

```visualbasic

Option Explicit
Dim objFso 
Set objFso = CreateObject("Scripting.FileSystemObject")
' Wsh Shell
Dim objWshShell
Set objWshShell = WScript.CreateObject("WScript.Shell")
' Word App
Dim objWdApp
Set objWdApp = WScript.CreateObject("Word.Application")

Dim objWdDoc
Dim strPath
Dim outPath
strPath = "D:\doc\"
outPath = "D:\htm\"

Dim obj
For Each obj In objFso.getfolder(strPath).Files
	Set objWdDoc = objWdApp.Documents.Open(strPath & "\" & obj.Name)
	' https://www.relief.jp/docs/word-vba-enum-wdsaveformat.html
	' 8 wdFormatHTML 標準 HTML 形式
	' WScript.Echo "SAVE AS " & outPath & objFso.getbasename(obj.Path) & ".htm"
	objWdDoc.SaveAs2 outPath & objFso.getbasename(obj.Path) & ".htm" , 8
	objWdDoc.Close
	Set objWdDoc = Nothing
Next
	objWdApp.Quit
Set objFso = Nothing
WScript.Echo "Finished"

```
Javaでtiff,tifファイルをpngに変換する方法

[記事はこちらに移動しました。](https://tro555-engineer.com/2022/02/05/java%e3%81%a7tiff%e3%80%81tif%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e3%82%92png%e3%81%ab%e5%a4%89%e6%8f%9b%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95%ef%bc%88java8%e6%9c%aa%e6%ba%80%e3%81%af%e5%8b%95%e3%81%8b/?preview_id=208&preview_nonce=cf53c6c884&preview=true&_thumbnail_id=217/)
Xamarin.Androidで動的に追加したコントロールの文字や背景の色を変える

最近、[目標達成スケジュール](https://play.google.com/store/apps/details?id=com.companyname.testapp1)というアプリを作りました。
これを作るにあたり、調べてもなかなか情報が見つからないことがあったので、同じようなところで困っている人のために共有しようと思います。

間違った知識、非効率的な方法を紹介しているかもしれませんが、一時お付き合いください。
***


#環境
windows10
VisualStudio2019
Xamarin.Android

#コントロールを追加する
まずはコントロールを追加しましょう。
コントロールを追加する方法は、XMLファイルで定義したコントロールをCSファイルで利用する方法とあまり変わりません。

まずレイアウトを作成し、そのレイアウトの中にコントロールを追加します。


            var ll = new LinearLayout(this)
            {
                Orientation = Orientation.Vertical,//縦並びにする
                LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent)
            };

            var title = new TextView(this)
            {
                Text = "タイトル",
                LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent)
            };

            ll.AddView(title);//これでレイアウト内にtitleテキストが表示される



これをSetContentViewの引数に指定するだけです。

LayoutParamsは縦横の大きさを指定します。MatchParentとWrapContent以外にも値を直接指定することができます。自分は常に画面サイズの何分の1を維持したいときなどに使っています。



#コントロールの色を変える

こっちがこの記事のメインです。プログラムからコントロールを追加する方法はググれば簡単に見つかるのですが、探し方が悪かったのか語る必要もないほど常識的なことなのか、色を指定する方法がなかなか見つかりませんでした。同じところで迷っている人がもしいれば、参考にしてください。


            var title = new TextView(this)
            {
                Text = "タイトル",
                LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent)
            };

            title.SetTextColor(Android.Graphics.Color.Argb(200, 200, 0, 0));//テキストの色
            title.SetBackgroundColor(Android.Graphics.Color.Argb(200, 0, 200, 0));//背景の色

            ll.AddView(title);


これだけでOKです。
TLSの設定を網羅的に確認したい

(2021-03-02現在の記事です)

## TL;DR (この記事はなに?)

建てているサーバに対する脆弱性診断で弱い設定を指摘された。
修正したあと、`openssl s_client -ciphers` でひとつひとつ調べることもできるけど、ざくっと網羅的に確認したいなぁ。

と思って調べてみたら、sslscanというコマンドがあったので、試してみた。

やってみたら、CBCがWeakなのか? という疑問が浮かんだので、それも追いかけてみた。

## Install (Google Cloud Shell)

https://ozuma.hatenablog.jp/entry/20150320/1426841511 を参考に、rbsec製の静的リンク版を使う。

```shell-session
$ git clone https://github.com/rbsec/sslscan/ 
$ cd sslscan
$ make static
```
あっさりできた。

## 実行
引数なしで実行するとヘルプが表示

```shell-session
$ sslscan

Command:
  sslscan [Options] [host:port | host]
```

単純にスキャンするだけならこれだけ!!

```shell-session
$ sslscan  10.XX.XX.XX
```

結果は長いので割愛しますが、
```
Accepted  TLSv1.2  256 bits  ECDHE-ECDSA-AES256-SHA384     Curve 25519 DHE 253
```

## あれ? なんか違う。

https://www.ssllabs.com/ssltest/analyze.html だと WEAK って出るんだけど。

(`ECDHE-ECDSA-AES256-SHA384` = `TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384` です)

```
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (0xc024)   ECDH x25519 (eq. 3072 bits RSA)   FS   WEAK
```

### どういうこと?

https://security.stackexchange.com/questions/210072/why-does-ssl-labs-now-consider-cbc-suites-weak

> CBCは理論的には問題ありませんが、不適切な実装によって接続がパディングオラクル攻撃を受けるリスクが常にあります。TLSでのCBC実装は何度も脆弱であることが示され、実装が修正されるたびに、パディングオラクル攻撃を実行可能にするさらに別のバグが発生しているようです。ラッキーサーティーンは2013年に公開され、サイドチャネルに基づくこの攻撃の亜種が次々と出現しています。SSL Labsは、歴史を観察し、そこから学んでいます。 (Google翻訳による)

なるほど。弱くはないけど狙われているからリスク、ということね。

## 日本政府はどう言っている?

https://www.cryptrec.go.jp/list.html

CBCは推奨暗号リストに掲載されている。
プロジェクトの要件は……。「CRYPTREC準拠」。ってことはCBCを使っていてもOKか。

念のため除外しておこうかなぁ……。
SwiftUIでリスト表示する際に画像が黒く塗り潰される

SwiftUIでリストを作成した際に画像が黒く塗りつぶされてしまったので対応方法の覚書です。

以下の様な画像と名称のみのセルを持ったシンプルなリストを定義します。

```swift

struct ContentView: View {
    var body: some View {
        VStack {
            List {
                ForEach(0..<2, id: \.self) { index in
                    Button(action: {
                        print("タップ")
                    }) {
                        SpotCell()
                    }
                }
            }
        }
    }
}

struct SpotCell: View {
    var body: some View {
        HStack(alignment: .top) {
            Spacer().frame(width: 20)
            VStack(alignment: .leading) {
                HStack(alignment: .top) {
                    VStack {
                        Spacer().frame(height: 16)
                        Image(uiImage: UIImage(named: "otaru")!)
                            .resizable()
                            .scaledToFill()
                            .frame(width: 60, height: 60)
                            .clipped()
                            .cornerRadius(4.0)
                        Spacer().frame(height: 16)
                    }
                    VStack(alignment: .leading) {
                        Spacer().frame(height: 16)
                        Text("小樽運河").font(.subheadline)
                        Spacer()
                    }
                }
            }
            Spacer()
        }
    }
}
```

こちらiOS14以上で実行すると問題なく画像が表示されますが、iOS13の実機で実行すると以下の様に画像が黒く塗り潰されてしまいました。
![IMG_1830.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428301/6894ab1f-1cca-f3ef-3ada-0adab5a17a33.png)

iOS13以下だとImageを定義する際に.renderingMode(.original)を付けなればならない様です。
以下の様にresizableの後ろにつけることによって画像が正常に表示されました。
※リストの外に画像を配置した場合は.renderingModeを付けなくても正常に表示されるのですが、リストの中に画像を配置すると上のように黒く塗り潰されてしまう様です。

```swift

Image(uiImage: UIImage(named: "otaru")!)
                            .resizable()
                            .renderingMode(.original)
                            .scaledToFill()
                            .frame(width: 60, height: 60)
                            .clipped()
                            .cornerRadius(4.0)
```

![IMG_1831.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428301/a25c992a-1092-9bc1-2491-68047f18ec94.png)
Wi-Fi経由でadb接続したときのエラーへの対処

# 経緯
WiFi経由でスマホ(HUAWEI P20 Lite)とパソコン(Windows)をadb接続しようとしたものの、なかなかうまくいかなかったので、僕が直面したエラーとその解決方法について書いていきます。
以下、開発者向けオプションは有効化してあるものとして話を進めていきます。

# 基本的な手順

1. スマホとパソコンを同じWi-Fiネットワークに接続
2. USBケーブルでスマホをパソコンを接続
3. ```adb tcpip 5555```をコマンドプロンプトで実行
4. USBを切り離す
5. スマホのIPアドレスを調べ、```adb connect [IPアドレス]```を実行。
6. ```adb devices```でadb接続できていることを確認

>[Android Debug Bridge（adb）](https://developer.android.com/studio/command-line/adb)

# うまくいかなかったこと
まずは手順通りに進めていったところ、手順の5で```adb connect [IPアドレス]```を実行したときに、

```
対象のコンピューターによって拒否されたため、接続できませんでした。(10061)
```
となり、接続できませんでした。
そこで、手順4でUSBを切り離さずに、USBで接続したまま```adb connect [IPアドレス]```を実行したところ、その時点では

```
connect to [IPアドレス]:5555
```
と接続できたものの、その後USBを切り離してから```adb devices```で確認したところ、

```
List of devices attached
[IPアドレス]:5555        offline
```
と表示され、うまく接続できませんでした。

同様のエラーについて検索したところ色々な情報が見つかったのですが、僕の場合はどれもうまくいきませんでした。

>[adb device offline with ADB wireless - Stack Overflow](https://stackoverflow.com/questions/17626691/adb-device-offline-with-adb-wireless)
[adb devicesでofflineと表示される | 悠久無窮的生活](http://blog.yukyumukyu.com/201308/09/adb-devices%E3%81%A7offline%E3%81%A8%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%82%8B/)
[android — Android StudioワイヤレスADBエラー（10061）](https://www.it-swarm.jp.net/ja/android/android-studio%E3%83%AF%E3%82%A4%E3%83%A4%E3%83%AC%E3%82%B9adb%E3%82%A8%E3%83%A9%E3%83%BC%EF%BC%8810061%EF%BC%89/824466087/)
[AndroidアプリをWiFi経由でデバッグ - Qiita](https://qiita.com/fukasawah/items/3f5b24819fac24c6686a)

# 解決方法
スマホの設定の
```設定 > システム > 開発者向けオプション > 充電専用モードでADBデバッグを許可する```
をONにして手順通りに実行したところ、無事にWi-Fi経由でadb接続することができました。