OmniAICreator/Qiita-1.07M huggingface dataset:
Laravelで違う文字（濁点/半濁点/平仮名/片仮名）が同じ文字として使われてしまう問題の対処法

## はじめに
Laravelで日本語の比較処理をしようとしたところ、違う文字列であるにも関わらず同じものとして扱われてしまうことがありました。
その時の対処法を忘れないように記事にしたいと思います。

## 動作確認環境
- PHP 8.0
- Laravel 8.0
- MySQL 8.0

※下位環境でも動作する場合がございます

## テーブル構造
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1490767/d74a503e-6891-a7fd-f186-37cc45134653.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1490767/fac676c1-f138-e5e3-226c-394b767305f6.png)

## 問題点
```php
$nana = Sample::where('name', 'バッグ')->get();
```

この処理。一見だと違う文字列であるため、一致する値は取得できないように思えますが、実はID：1の情報が返ってきてしまいます。

## 解決法1
```php
$nana = Sample::where('name', 'LIKE BINARY', 'バッグ')->get();
```

あいまい一致を回避するためにはLaravelでは'LIKE BINARY'を付けることで完全一致に切り替えることができます。


## 解決法2
ただ、解決法1ではSelect文の時は回避できるのですが、該当カラムにユニークキーが貼られていた場合、Insertは依然として通りません。
該当カラムにユニークキーを使っている場合は、該当カラムの参照順序（文字コード）を変えてしまいましょう。
MySQLのバージョンにもよりますが8.0.2以降であれば、utf8mb4_ja_0900_as_cs_ksを使っておけば無難です。
※MySQL8系が使えない場合はutf8mb4_binが無難です（適時読み替えて下さい）

```php
/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    // マイグレーションの書き方
    Schema::create('samples', function (Blueprint $table) {
        $table->id();
        $table->string('name')->unique()->collation('utf8mb4_ja_0900_as_cs_ks');
        $table->timestamps();
    });
}
```

## 解決法3
文字コードで混乱しなくないという場合は、Laravelのconfig/database.phpの設定を書き換えてしまうのが簡単です。
MySQL 8.0.2以降を使用する場合は下記の設定しておけば問題ないかと思います。
マイグレーションした際の初期値がutf8mb4_ja_0900_as_cs_ksになります（個別設定は不要）。
※なお、MySQL8系が使えない場合はutf8mb4_binが無難です（適時読み替えて下さい）

```php
'mysql' => [
    ...
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_ja_0900_as_cs_ks',
    ...
],
```


## 参考記事

https://qiita.com/haruraruru/items/b138ee9bcc0af35ce42f

http://program.sagasite.info/wiki/index.php?MySQL%E3%81%AEutf8_general_ci%E3%81%A8utf8_unicode_ci%E3%81%AE%E9%81%95%E3%81%84

https://zudoh.com/mysql/should-use-collation-utf8mb4_bin-as-default

https://qiita.com/kazu56/items/6af85ffcf8d3954455ad

https://mysqlserverteam.com/mysql-8-0-kana-sensitive-collation-for-japanese-ja_jp/
FirestoreでMapオブジェクト内のフィールドに対してWhere検索する


# はじめに

以下のような、Mapオブジェクトを持つコレクションに対してWhere句で条件指定してデータ取得するメモ。
自分用備忘録を兼ねる。（むしろそっちの目的が大きい）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392942/00d5166f-1cb5-37e8-d880-e3831723e0e7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392942/3cfaa8ce-db5b-6b34-5090-8d69e834ce96.png)

# 検索方法

`where('[フィールド名].[Mapオブジェクト内のフィールド名]' , '==' , 'hogehoge')`のように指定する。
上の例だと`where('data.name','==','hogehoge')`とする。
以下Node.jsのサンプル

```javascript
const admin = require('firebase-admin');
admin.initializeApp();
const db = admin.firestore();
const hogehoge = db.collection('Hogehoge');

async function getHogehoge() {
    try {
        const querySnapShot = await hogehoge.where('data.name' , '==' , 'hogehoge').get(); // ここで条件指定する
        var datas = [];

        querySnapShot.forEach(async (d)=>{
            datas.push(await d.data());
        });

        return datas;

    } catch(err) {
        throw err;
    }
}
module.exports = {
    getHogehoge: getHogehoge,
};
```

演算子`==`の部分は公式ドキュメントに載っている他の演算子も利用可能。
https://firebase.google.com/docs/firestore/query-data/queries?hl=ja#query_operators
上記のドキュメントにはMapオブジェクトに対するWhereの指定が明記されてないように見えたので一応自分用にメモとして興した。

# FieldPathを使う方法

`where('data.name')`のように、whereメソッド内のフィールド名部分にドットを書いて直接記述しても動作するのだが、`FiledPath`を使うやり方もある。

```javascript
const { firestore } = require('firebase-admin');

...

const querySnapShot = await hogehoge.where(new firestore.FieldPath('data' , 'name') , '==' , 'hogehoge');
```

`new firestore.FieldPath('data' , 'name') `が`where('data.name')`と同じ働きをする。
公式ドキュメントはこちら↓
https://firebase.google.com/docs/reference/js/firebase.firestore.FieldPath?hl=ja
Vue.js クリックしたボタンの色を変化させる。

##環境
jsfiddle
vue@2.6.14

##クリックしたボタンの色を変化させる!
###完成したコード
ボタンをクリックするとボタンの色が変化します。

クリック前
![スクリーンショット 2021-06-21 22.42.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025549/7cc2d4e1-fa4d-718d-ecbb-4fae3cc0260b.png)

クリック後
![スクリーンショット 2021-06-21 22.41.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025549/665039da-ec7b-50da-7cdd-d62f64788ed8.png)

###詳細
####css

```
.buttoncolor {
	background-color: green;
}
```
変更後のボタンの色を指定しています。
####html

```
<div id='app'>
	<button v-bind:class="{ buttoncolor: buttonState }" v-on:click="changeState">
		 色を変えるためのボタン
	</button>
	{{buttonState}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
```

①v-bind:classでは```v-bind:class="{class名: バインド先(真偽値を持つ)}"```とすることで、真偽値を持つbuttonState変数とbuttoncolorクラスを対応させている。
つまりbuttonStateがtrueの時、buttoncolorクラスが適用されるが、falseの際には適用されなくなることでボタンの色が変化する。

②v-on:clickは、クリックした際に作成したchangeStateメソッドが実行され、buttonStateの真偽値が変更される。
真偽値が変更されることで①が実行される。(changeStateメソッドの詳細は、sctiptの詳細で説明します。)

####script

```
var app = new Vue ({
	el:'#app',
	data:{
		buttonState: false	
	},
	methods:{
	 changeState: function(){
		 this.buttonState = !this.buttonState
	 }
	}
})
```
①data内に、真偽値を持つbuttonState変数を指定している。
②methodsでは、呼び出された際に、真偽値を変更するchangeStateメソッドを作成している。

###動作
①ボタンがクリックされる
②v-on:clickで指定された、changeStateメソッドが実行される。
③②でbuttonStateの真偽が変更される。
④③で真偽値が変更されたこと、v-bindでバインドされたクラスがtrueの時にだけ適用される。

##まとめ
簡単なコードですが、いざ実装するとなると慣れるまでは時間がかかってしまいました。
私と同じ初心者さんの参考になればと嬉しいです!
JavaScriptの === について

最近、仕事でよくJavaScriptを使用するようになったのですが、その中で「===」という演算子が出てきたのが気になったので調べてみました。
相変わらず自分用メモです。

「===」は、「===厳密等価演算子」と言って、「型を変換することなく厳密に等しいかどうか」をチェックする演算子です。
Javaなどでよく使われる「==等価演算子」は、たとえば数値型の「1」と文字列型の「1」なら、自動的に文字列型の「1」を数値型に変換し、変換後の値が等価であればTrueを返してくれます。
しかし、「===厳密等価演算子」は型を変換せずに「等価であるか」を判定するため、上記のような例の場合はFalseを返します。
「===厳密等価演算子」でTrueの結果を得たい場合は、型、値の両方が一致していなければならないのです。

また、「===」の否定は「!==」となります。記述するときに迷ったので書き残しておく。
当然ながら、先程とは逆で数値型の「1」と文字列型の「1」の場合はTrueを返し、数値型の「1」同士ならFalseを返します。
VS Codeにおけるインデント

# VS Codeにおけるインデント

# 概要
開発における、インデントの調整、改行コードの変更方法についてまとめる

# 目次
1. インデントの調整について
2. 改行コードの変更方法について

# 1.インデントの調整について
開発において、プロジェクトにもよるが、基本的にインデントのサイズは、  
半角スペースで4つ分である。
VS Codeでその変更方法を下記にまとめる

1. 右下にある「スペース：XX」をクリック  
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1282434/37992930-2037-33f5-274b-30917a08e9ef.png)

2. 「スペースによるインデント」をクリックし、「4」を選択  
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1282434/b0039d84-e84e-8a77-feb4-f72636541797.png)
 ![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1282434/17d72865-9df0-5a71-7e1a-5b4db35013ca.png)

→これにより、タブを押下すると半角スペース4つ分で、インデントが調整される

※補足  
図1の「インデントをスペースに変換」をクリックするとそのファイルで、  
生成されているインデント全てに、手順2で設定したサイズに自動で変換される。

# 2.改行コードの変更方法について
改行コードの変更方法を下記にまとめる。

1. 右下の「LF」or「CRLF」をクリック
2. 「LF」or「CRLF」を選択し、上書き保存する  
![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1282434/2c19226e-5480-7a34-96ce-68d3aa5d439f.png)
[swift] Snippetを作成する方法

# はじめに
- この記事は自分のメモとして書いてあります。

# snippetを使うことで便利になること
- コードを打つ手間が省ける
- スペルを忘れても補完でなんとかなる
- ドキュメントコメントや特殊タグを書く時に便利

ドキュメントコメント参考文献　：　https://qiita.com/y-some/items/8bc06567eee18dfeafbb

#Snippet作成
## snippetとして登録したいコードを選択
- 今回は // MARK: - <#comment#> を選択しています。

```swift
// MARK: - <#comment#> 
```
![snipet.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1379778/ab9b38e6-9fba-139a-b444-e155c485c67b.jpeg)

## Create Code Snippetを選択
- コードを選択して、右クリックで　Create Code Snippet を選択します。![snipet.002.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1379778/506b9198-3e78-b8db-66cd-fd05e897d526.jpeg)

## 登録画面から登録
- 登録画面が表示されます
- 登録画面のTittleとCompletionを入力して登録します。

Tittleは補完で表示される内容を登録します。
Completionは何を打ったら補完されるのかを登録します。

- 今回はTittleに// MARK:をCompletionに markを登録しました。

![snipet.003.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1379778/c5fb5211-2980-7088-bed3-c91c8d10ac4a.jpeg)
![snipet.004.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1379778/b2c4e79b-c95d-c9f6-4c2d-4b8cf79f7a84.jpeg)

## 完成
- 以上で完成です。
- markと入力されるだけで補完されます。
ConsolasとMeiryoKeConsoleをくっつけて使いたい


Consolasは~~MS製とは思えないほど~~使いやすいフォントだが、いかんせん欧文フォントなので日本語は等幅になってくれない。そこで、等幅のメイリオであるMeiryoKe_Consoleを組み合わせていい感じにしよう、というやつ。

情報はたくさんあるんだけど、結構ハマったので。

# ざっくり手順
- MeiryoKeを導入する
- fontlinkを設定する
- OSを再起動する

基本的にはこれだけ。fontlinkはざっくり言うと、欧文フォントを設定したときに、日本語文字を表示するフォントを指定できる機能。デフォルトではたしかMS UI Gothicとかになる。

## MeiryoKeの導入

[ここ](https://meir000.github.io/MeiryoKe/)にアクセスしてzipをDLし、中に入ってる生成ツールを実行してフォントを指定する。それから**全てのユーザーにインストール**する。

※MeiryoKeは厳密にはライセンス違反なので、導入は自己責任で。MeiryoKeではなく、他のフォントを使用してもよい。

## fontlinkの設定
レジストリエディタ(Win+R→regedit)を開き、` HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink`と階層を潜る。右クリック→新規→複数行文字列値 と選択し、名前を`Consolas`、値を`meiryoKe_650r1.ttc,MeiryoKe_Console,128,112`と入力する。
最初の部分はフォントのファイル名なので、もしバージョンが違う場合はそれに合わせる。
一番右の112はフォントの大きさで、**この数字が小さいほどフォントが縦に大きくなる**ので、好みで指定する。

## OSの再起動
レジストリを反映させるため。普通の再起動で良い。サイズをいろいろ試す場合はちょっと面倒。

成功すれば、メモ帳なんかでも等幅になってくれる。便利。というかマイクロソフトさん、MSゴシックじゃない日本語等幅フォント用意してくれませんかねえ……BIZ UD ゴシックで我慢しろということなのだろうか。

# ちなみに
この記事を書いたのは、powershellの日本語の字間がスッカスカになるのをマシにするためだったのだが、そもそもpowershellではconsolasが使えなかった。(chcp 65001を叩けば使えるが、これはこれで別の問題がわんさか発生するらしい……）。素直にMyricaとか入れるか、git bashなんかを使ったほうがいいかもしれない。
[Rust]多重起動処理

同じプログラムがいくつも起動するのを防ぐ処理を作ったりする関数。

cargo.tomlに以下を追加。

```toml:cargo.toml
[dependencies]
sysinfo = "*"
```

スクリプト本体

```rust
use sysinfo::{System, SystemExt, ProcessExt};
use std::env::current_exe;
/// trueの場合は、他に同じ実行ファイルが起動していることを示しています。
/// ※　ただし、デバッガを介した実行の場合、let countが0になることがあるため、注意が必要です。
/// cargo.toml
/// [dependencies]
/// sysinfo = "*"
/// if is_multiple_activation() {
///     // 多重起動しているので終了。
///     std::process::exit(1);
/// }
fn is_multiple_activation() -> bool {
    let my_path = current_exe().unwrap().display().to_string();
    let mut count = 0;
    for (_, process) in System::new_all().get_processes() {
        if my_path == process.exe().display().to_string() {
            if count > 1 { return true; };
            count += 1;
        }
    }
    return count > 1;
}
```

自身のファイルパスを`current_exe().unwrap().display().to_string()`で取得し、プロセス一覧から同じものがあるかどうかを調べて同じものがあれば`let mut count`をインクリメントし、自身以外にも起動している状態（`let mut count`が1以上）の状態であれば`true`を返す。

#### 注意点

このスクリプトはデバッガーを介して使用した場合、自身をカウントせず、`let mut count`が0となる場合がある。

## 使用例

```rust:main.rs
// タイマー用
use std::thread;
use std::time::Duration;

fn main() {
    if is_multiple_activation() {
        println!("multi activation!");
        thread::sleep(Duration::from_secs(3));
        std::process::exit(1);
    }
    // 5秒後に終了するプログラム
    thread::sleep(Duration::from_secs(5));
}
```
aws-events-targetsから紐付けたECSタスクにはパブリックIPが割り当てられない　を解決できた

これ↓を嘆いていたら次の日には通りすがりの方が解決してくださった

---

cf. https://github.com/aws/aws-cdk/issues/9233

※ お金があればそもそも `NATゲートウェイ使おう` `PrivateLink使おう`で解決すると思います

[FargateServiceProps](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ecs.FargateServiceProps.html)にはある `assignPublicIp?`に相当するプロパティが [EcsTaskProps](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-events-targets.EcsTaskProps.html)にはない。

じゃあデフォルト値＝enableでパブリックIPを自動割り当てするのかというと、なんとデフォルト値はdisabledなので割り当てられない。

パブリックIPがないのでECSタスクはECRからimageをpullすることもできず堕ちる :innocent: 



[SubnetProps](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ec2.SubnetProps.html)の `mapPublicIpOnLaunch?`に一縷の望みを託して独自にパブリックサブネットを作って配下に置いてみたがダメだった。無駄無駄ァ！


~~たぶんダメだろうけど[ScheduledFargateTaskProps](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ecs-patterns.ScheduledFargateTaskProps.html)という搦手があるいはと思うこともあったが試す気力はなかった~~

---


## どう解決したのか

- [EcsTaskProps.SubnetSelection](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ec2.SubnetSelection.html).SubnetType = `PUBLIC`を指定した
  - デフォルト値が `PRIVATE`になっているらしい :innocent: 
  - https://github.com/aws/aws-cdk/blob/c647e389bd279b34e91110c9418885fe904739c3/packages/%40aws-cdk/aws-events-targets/lib/ecs-task.ts#L166
  - サブネットのほうのパブリックIP割り当て設定を引き継いでくれても良いのではと今でも思っている
- ECSタスク設定では、VPCサブネットのことを深く考えないことにした
  - 当時は `subnets`で細かく指定しようとしていた
  - `subnetType`と競合した :innocent: のでやむなく `subnets`は諦めた
  - つまり `SubnetType = PUBLIC`だけの指定になった≒パブリックであることしか指定しないのでVPC内のパブリックサブネットが複数あったときどうなるのかわからないがそもそもVPCとサブネットの関係とはそんなものなのかもしれないので考えるのをやめた


```typescript:こんな感じの指定をする
    const nanikaNoTask = new eventstargets.EcsTask({
      cluster: nanikaNoCluster,
      taskDefinition: nanikaNoTaskDefinition,
      taskCount: 1,
      securityGroup: nanikaNoSecurityGroup,
      subnetSelection: {
        subnetType: ec2.SubnetType.PUBLIC, // <- これ
        availabilityZones: [nanika.no.availabilityZones.a],
        // subnets: [nanikaNoPublicSubnet1], <- これがsubnetTypeと同時指定できない
      },
      platformVersion: ecs.FargatePlatformVersion.VERSION1_4,
    });
```
ランタイム(exe)でVRM(MToon)をHDRP(Lit)表示

#概要
ランタイム(exe)でVRM(MToon)をHDRP(Lit)表示します。

#環境
Unity 2020.3.11f1
UniVRM 0.66.0

#実装
```cs
using System.IO;
using System.Collections.Generic;
using UnityEngine;
using VRM;

public class MToonToLit : MonoBehaviour
{
    [SerializeField] string FilePath;
    [SerializeField] Material Opaque;
    [SerializeField] Material Transparent;

    void Start()
    {
        // VRM読み込み
        var bytes = File.ReadAllBytes(FilePath);
        var context = new VRMImporterContext();
        context.ParseGlb(bytes);
        context.Load();
        context.ShowMeshes();

        // MToonをLitに置き換え
        var renderers = context.Root.GetComponentsInChildren<Renderer>();
        for (int i = 0; i < renderers.Length; i++)
        {
            var materials = new List<Material>(renderers[i].materials);
            for (int j = 0; j < renderers[i].materials.Length; j++)
            {
                if (renderers[i].materials[j].GetFloat("_BlendMode") != 2)
                {
                    materials[j] = new Material(Opaque);
                }
                else
                {
                    materials[j] = new Material(Transparent);
                }
                // 通常と透過を使い分けて色とテクスチャを反映
                materials[j].color = renderers[i].materials[j].color;
                materials[j].mainTexture = renderers[i].materials[j].mainTexture;
            }
            renderers[i].materials = materials.ToArray();
        }
    }
}

```
#補足
HDRPで作成したプロジェクトのシーンのどこかへ前述のスクリプトを張り付けて、FilePathに読み込みたいVRMファイルのパス、Opaqueに新規作成したHDRP/Litのマテリアルを設定、Transparentには新規作成したHDRP/LitのマテリアルのSurface TypeをTransparentにしてから設定すれば動くと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286581/a277ddad-1c49-f7ea-8b3d-eddc8656cc2b.png)
既知問題として、このままだとUnlitが来た時に失敗して真っ黒になるので、_BlendModeの判定辺りをちゃんとやる必要があります。どうやれば良いかは調べれてません。
#参考
左がHDRP、右がMToonです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286581/4152f00f-1409-14f7-7897-6f2d5a49249a.png)
モデル：リンツちゃん改変
https://booth.pm/ja/items/1255264
サンプルアプリ
https://120byte.booth.pm/items/3062310
1人目が2人目をフォローする、2人目が3人目をフォローする... の様なズレと組み合わせを生成するアルゴリズム[Ruby]（zip, rotate）

1人目のユーザーが2人目のユーザーをフォローする。
2人目のユーザーが3人目のユーザーをフォローする。...など、
少しずれた関係性を生み出す際に利用可能なアルゴリズムを考えついたのでここで共有します。
2つのメソッドを組み合わせる事で、生成することが可能です。

## 結論

```ruby
users = User.all
users.zip(users.rotate) do |following_user, followerd_user|
	following_user.follow(followerd_user)
end

省略形
User.all.zip(User.all.rotate) { _1.follow(_2) }
```

恐らくこれで動作すると思います！`follow`というtwitterなどで用いられる関係性を生み出す独自メソッドです。省略形はruby2.7以降で動作すると思います！

### rotate メソッド

https://docs.ruby-lang.org/ja/3.0.0/method/Array/i/rotate.html

```ruby
a = [1, 2, 3, 4]
a.rotate         # => [2, 3, 4, 1]
a                # => [1, 2, 3, 4]
a.rotate(2)      # => [3, 4, 1, 2]
a.rotate(-1)     # => [4, 1, 2, 3]
```

こちらはメソッド名から想像が着くように、引数に渡した数字分だけ配列の要素をズラすメソッドになります。

### zip メソッド

https://docs.ruby-lang.org/ja/3.0.0/method/Array/i/zip.html

```ruby
p [1, 2, 3].zip(["A", "B", "C"], ["a", "b", "c"])
# => [[1, A, a], [2, "B", "b"], [3, "C", "c"]]

p [1,2].zip([:a,:b,:c], [:A,:B,:C,:D])
# => [[1, :a, :A], [2, :b, :B]]
```

こちらのメソッドは痒いところに手が届くようなメソッドです。
self配列に対して、引数の配列の同じインデックスに対応する要素を抽出し、それらを組み合わせて新たな配列を生成するメソッドです。
個人的にはメソッド名が好きです。

## まとめ

上記2つのメソッドを活用することで、

1. ズラした配列を生成し、
2. 元の配列とズラした配列を組み合わせた配列を生成する
3. 新たな配列に対して、2つの要素を引数に取る繰り返し処理

といった流れで、対応していきます。以下動作反応。

```ruby
users = User.all
=>   TRANSACTION (0.4ms)  BEGIN
  User Load (15.5ms)  SELECT `users`.* FROM `users`
[#<User id: 1, name: "Test_User1", created_at: "2021-06-20 04:34:55.577201000 +0900", updated_at: "2021-06-20 04:34:56.195767000 +0900">,
 #<User id: 2, name: "Test_User2", created_at: "2021-06-20 04:34:56.513694000 +0900", updated_at: "2021-06-20 04:34:56.607071000 +0900">,
 #<User id: 3, name: "Test_User3", created_at: "2021-06-20 04:34:57.040755000 +0900", updated_at: "2021-06-20 04:34:57.147144000 +0900">,
 #<User id: 4, name: "Test_User4", created_at: "2021-06-20 04:34:57.636523000 +0900", updated_at: "2021-06-20 04:34:57.876562000 +0900"]

users.zip(users.rotate) do |following_user, followerd_user|
	following_user.follow(followerd_user)
end
TRANSACTION (0.4ms)  SAVEPOINT active_record_1
  User Load (0.7ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  Relationship Create (2.4ms)  INSERT INTO `relationships` (`follower_id`, `followed_id`, `created_at`, `updated_at`) VALUES (1, 2, '2021-06-21 13:29:30.279783', '2021-06-21 13:29:30.279783')
	:
```

## 余談

これらのメソッドは、Qiitaを通してあるユーザー様にご教授いただきました。
自分の記事に色々とコメントしてくださり、いつも助けられております。
アウトプットする事で視野が広がるいい経験でしたっ
[Unity]Animatorを任意のフレームレートで動作させる

E3で公開された「SABLE」の世界観素敵ですね・・・。

https://twitter.com/ShedworksGreg/status/1391803209686126598

このゲームの魅力を支えているたくさんのテクニックの内のほんの一つですが、**モーションのフレームレートをあえて落としてトゥーンシェーディングのグラをよりアニメ調に見せる方法** を以前Qiitaの記事にしました。

https://twitter.com/flankids/status/1328770524231602177

この記事では`PlayableAPI`を使った実装を紹介していて、普通に`AnimatorController`を使って動かすモデルにはそのまま適用できず扱いづらいものだったので、`AnimatorController`をそのまま使ってフレームレートを落とす機能を作ったので、話題に便乗して紹介します！

# こんな感じになります

https://twitter.com/flankids/status/1406965877979848708

※シェーダーは[ユニティちゃんシェーダー](https://unity-chan.com/download/releaseNote.php?id=UTS2_0)を当ててます

# スクリプト

`Animator`コンポーネントを持つオブジェクトに付与する`AnimatorFPSController.cs`を作っています。

![スクリーンショット 2021-06-21 22.32.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184294/bc3eca23-e6cb-2067-d8c8-21c703ee455c.png)

```AnimatorFPSController.cs
using UnityEngine;

[RequireComponent(typeof(Animator))]
public class AnimatorFPSController : MonoBehaviour
{
    [SerializeField, Range(1, 30)]
    int _fps = 30;

    Animator _animator;

    /// <summary>しきい値時間</summary>
    float _thresholdTime;

    /// <summary>スキップされた更新時間</summary>
    float _skippedTime;

    private void Awake()
    {
        _animator = GetComponent<Animator>();
        _animator.enabled = false;
        InitializeThresholdTime();
    }

    /// <summary>
    /// しきい値時間の初期化
    /// </summary>
    void InitializeThresholdTime()
    {
        _thresholdTime = 1f / _fps;
    }

    private void Update()
    {
        _skippedTime += Time.deltaTime;

        if (_thresholdTime > _skippedTime)
        {
            return;
        }

        // アニメーションの時間を計算する
        _animator.Update(_skippedTime);
        _skippedTime = 0f;
    }

    /// <summary>
    /// Inspectorの値変更時の処理
    /// </summary>
    private void OnValidate()
    {
        InitializeThresholdTime();
    }
}
```

動作フレームレートを指定する変数`_fps`に応じて計算される更新頻度（秒）変数`_thresholdTime`の間だけ、`Animator`の更新を止めています。
更新頻度の時間に到達したら、更新を止めていた時間を込みで`Animator`の`Update`を進めて、モーションによって作られるポーズに更新する仕組みです。

# 雰囲気作り・絵作り以外の用途

高負荷になりがちな`Animator`の更新頻度を抑えて**負荷削減**する用途にも使えます。
市場のゲームだと、

* マリオオデッセイのニュードンクシティの街の人々
* モンハンワールドの一部の敵
* ドラクエモンスターズ2 3DS版のフィールドの敵シンボル

などのモデルがカメラからの距離に応じてアニメーションのフレームレートを落とすような仕組みが施されていることが確認できました。
LODの一環としてこの仕組みを入れるのも良いかもしれません。

`Animator`以外にも、大量のオブジェクトやインスタンスの更新処理で負荷が高い場合、この手法で負荷を減らすこともできそうです。

# 負荷削減として扱う場合

更新頻度を減らすオブジェクトが大量にある場合、**更新処理に到達するタイミングをズラす**必要があります。
ズラさなかった場合、**全てのオブジェクトの更新が同一フレームで走る**ため、一定間隔でスパイクしてしまいます。

```AnimatorFPSController.cs
void InitializeThresholdTime()
{
    _thresholdTime = 1f / _fps;
    // 更新タイミングがバラつくように初期値に乱数を与える
    _skippedTime = Random.Range(0f, _thresholdTime);
}
```

このように`_skippedTime`に`_thresholdTime`を最大値とする乱数を与えることで、更新タイミングを散らすことができます。
ビッグカメラで買ったGit-hub を使う（初めてのgithub完全ガイド1）

#Git とは何じゃ？　ビッグカメラで買えるんか？
すでにプログラミングを業務にされている諸先輩方は、今更なトピックかも知れませんが、プログラミングはじめました　という入門者にとっては、GitやGit hubっていうのは、何やら世界のプログラマーが使う、怪しい秘密のプラットフォームで、色々なトラップが埋め込まれたハッカーの溜まり場的なイメージがあると思うのじゃ。 
Gitっていうのは、ざっくり言うとプログラムの”バージョンコントロール”で、ドラクエで言う”セーブ”。教会で行うアレじゃ。 
プログラムっていうのは、ほんの一文字で全てが崩壊する危機をはらんでおり、えらいことが起こった時に、その前に戻れるようにする機能のこと。
Git hubはそのデータをセーブしたり、管理したりするクラウドの場所。また、そのデータをチームで共有して、一緒に作業していく場。 
別記事ではnodeのプロジェクトを解説していこうと思うので、その中でどう使うのかを解説してみるぞ。 
###どうやって使うんじゃ？ 
まずはGitの機能を自分のコンピューターで使うために、ダウンロードしないと始まりません。 
**ビッグカメラでは買えません。** 
ここからダウンロード↓ 
https://git-scm.com/ 
OSにインストールできたら、コマンドラインから以下のコマンドを打ってみましょう。バージョンが表示されたらインストールが出来てます。

```
myProject$ git --version
git version 2.25.1
```
次にする事は、Gitでトラックしたいプロジェクトのメインフォルダを初期化する。そのフォルダ内のファイルがGitの監視下に入る。 
今回はmyProjectディレクトリを制作。

```
myProject/$ git init
Initialized empty Git repository in /home/ubuntu/myProject/spicy_mandarin/.git/
```

この時自動生成された隠れディレクトリ.gitリポジトリに、変更履歴などのデータが蓄積されていくが、git側が勝手に処理してくれるので、特に気にしなくて大丈夫。 
リポジトリっていうのはフォルダみたいなもので、更新履歴やファイルもひっくるめて、Gitに関する全てが保存されてる場所。 
これで準備はオーケー。 これでGitでファイルをトラックしたり、Git hubやサーバーにコマンド一つでプッシュ出来るようになったでござる。 
Gitで使う主なコマンドは以下。 

- **git status** // ファイルの状態をみる
- **git add ファイル名**　// コミットするファイルに加える。また、新しく作ったファイルをGit監視下に加える時に使う。
- **git commit** //　コミット（変更をセーブ）する。
- **git push** //　コミットしたファイルと情報をGit hubなどのサードパーティーにアップ

流れとしては、statusで状態を確認して、addしてcommitしてpush！ 
何故addっていう作業を挟むかと言うと、commitはひとまとまりのファイルを一気にセーブするから、その束に加える必要がある。
で、Gitに一々変更をトラックさせる必要のないファイルや、Git hubなどにあげるとセキュリティ上問題のあるpornhub的なエッチなファイルやディレクトリは、**.gitignore**というファイルを作って、そこに記述しておくと、 Gitの監視対象からは外される。 

```git：.gitignore
node_modules/
myEroFiles/
```

コードを変更したり、新しいファイルを作ったり、ここらで一旦セーブって所で、add commit。 
ローカルのgitリポジトリに変更が記録されていく。 
で、次の作業はそれをgit hubにアプ。 

バイトの時間が来たので、今回はここまでじゃ！ 
[次回](https://qiita.com/monsoonTropicalBird/items/d026a4bc4796127ab155)はSSHキーを作って、ローカルリポジトリをgit hubにアップするぞい。
[Ruby]スキルチェックDの足し算問題/配列のデータ型を変更

https://paiza.jp/works/mondai/skillcheck_sample/addition

足し算 (paizaランク D 相当)の問題を解いてみました。（プログラミング初心者です。）
ちなみに練習問題なので、コードの公開はokのようです。

順を追って答えを導きたいと思います。
もっと綺麗な答えがあるように思いますが、今ある知識で回答を導きたいと思います。


<h3>①値を配列に格納<h3>

まず横１行で与えらえる値２つ（今回１と１とします）を受け取り、配列に入れてしまいます。

```
line=gets.split(" ")
```

<h3>②失敗!普通に足してみた　<h3>

これで、p numberで出力すると、["1", "1"]と配列に格納されます。
配列を取り出して足せばいいかなと思ったのですが、
配列の中身が文字列stringになっているため、
↓こうしてしまうと、、１１と出力されます。

```
puts line[0]+line[1]
```

<h3>配列のデータ型を変えるには？？<h3>

わからなかったので調べました。
以下のコードを追加すれば整数型になります。

```
line.map!(&:to_i)
```
他にもいくつかやり方はあるようで、今回以下の記事を参考にしました。

https://qiita.com/kota-es/items/eec73aa4c2576ab63715

<h2>解答コード<h2>
一応正解できました。

```
line=gets.split(" ").map!(&:to_i)
puts line[0]+line[1]
```


頑張れ、自分。
[Linux]基本的なコマンドライン編集機能まとめ

#環境
ホストOS　macOS Catalina 10.15.7
仮想OS CentOS 7
使用シェル bash

## カーソル操作
```
Ctrl + b
Ctrl + f
```
bがカーソルの後退
fがカーソルの前進

```
Ctrl + a
Ctrl + e
```
aが行頭へカーソルを移動
eが行末へカーソルを移動

```
Esc + b
Esc + f
```
※　Escは押しっぱなしではなく押した後に付随するキーを押す
bは後方に単語1つ分移動
fは前方に単語1つ分移動

##文字削除
```
Backspace　又は Ctrl + h
Delete 又は　Ctrl + d
Ctrl + w
```
hはカーソル位置の後方に1つ削除
dはカーソル位置の1文字を削除
wは後方にスペース区切りで1単語分削除

##カット＆ヤンク（ペースト）
```
Ctrl + k
Ctrl + u
Ctrl + y
```
kはカーソル位置から行末までを削除する（カット）
uはカーソル位置から行頭までを削除する（カット）
yは最後に削除した内容を挿入する（ヤンク[ペースト]）

##コマンド強制終了
```
Ctrl + c
```
プロンプトに戻らない場合に活用、進行中の動作を終了させる

## 補間機能
```
特定の文字 + Tab
例
ec + Tab
echo
```
当てはまるコマンドを補間してくれる
複数同じ文字のコマンドがある場合はTabを2回押す事でコマンド一覧が表示されるためそこから探す

## コマンド履歴
```
Ctrl + p 又は↑キー
Ctrl + n　　又は↓キー
Ctrl + r
```
pは一つ前のコマンド履歴に移動
nは次のコマンド履歴に移動する

rは履歴を遡ってインクリメンタル検索を行う

```
(reverse-i-serch)`':
```
Ctrl + rを入力すると上記の様なプロンプトになる
1文字ずつ履歴から一致するコマンドを表示する
さらに以下のコマンド入力できる

```
Ctrl + r
Enterキー
Escキー
Ctrl + g
```
rは1つ前の検索結果へ移動
Enterは現在表示されたコマンドを実行
Escは現在表示されたコマンドのままプロンプトへ移動
gは検索結果を破棄し、プロンプトに戻る

以上！
BIP32

## 拡張鍵
秘密鍵/公開鍵と、Chain Code が対になったもの

## 鍵ツリー
拡張鍵を連結してツリー構造を作る。後述のマスター鍵がルートになる。

## 鍵インデックス
子鍵にはゼロベースのインデックスが振られる

## 鍵インデックスの種類
| 種類 | 鍵インデックスの範囲 |
| --- | --- |
|Normal|$0$ ~ $2^{31}-1$|
|Hardened|$2^{31}$ ~ $2^{32}-1$|

- 公開鍵から Hardened インデックスを持つ子公開鍵はつくれない。
- Hardened インデックスを持つ秘密鍵以降の子秘密鍵は、同じパスを持つ公開鍵と対応しない。

## パス
木のルートから、子ノードのインデックスを並べていったもの。秘密鍵のルートが m で、公開鍵のルートが M。Hardened Index は H を後につける。例えば、M/0/1H/3 等。

## マスター鍵
1. 128 ビットから 512 ビットの長さのシードバイト列 S を作る
2. `I = HMAC-SHA512(Key = "Bitcoin seed", Data = S)` を計算する
3. I の前半 32 バイトが マスター鍵、後半 32 バイトが chain code
3. マスター鍵が 1 から n-1 の範囲になければやり直し。n は Generatorの位数。

## 子キー
### 導出方法
#### 親秘密鍵 -> 子秘密鍵
##### Normal Index
1. `I = HMAC-SHA512(Key = 親のChain Code, Data = 親秘密鍵から作った公開鍵 || インデックス)`
2. I の前半 32 バイトが 子秘密鍵、後半 32 バイトが 子 Chain Code

##### Hardened Index
1. `I = HMAC-SHA512(Key = 親のChain Code, Data = 0x00 || 親秘密鍵 || インデックス)`
2. I の前半 32バイトが 子秘密鍵、後半 32 バイトが 子 Chain Code

#### 親公開鍵 -> 子公開鍵
##### Normal Index
1. `I = HMAC-SHA512(Key = 親のChain Code, Data = 親公開鍵 || インデックス)`
2. I の前半 32 バイトを秘密鍵として公開鍵を作り、親公開鍵に足したものが子公開鍵、後半 32 バイトが 子 Chain Code

##### Hardened Index
不可

#### 親秘密鍵 -> 子公開鍵
#### Normal/Hardened
1. 親秘密鍵から公開鍵を計算したものが子公開鍵、親 Chain Code が、子 Chain Code

#### 親公開鍵 -> 子秘密鍵
不可

## 同じパスの Normal 秘密鍵と、Normal 公開鍵が対応する理由
どちらも同じ親 Chain Codeと、同じ親公開鍵と、同じインデックスの HMAC を計算したものを、子秘密鍵（部分）の増分として扱っているため。

親 Chain Code が同じになるのは、ルートの Chain Code が秘密鍵と公開鍵で同じで、子 Chain Code が、秘密鍵と公開鍵で同じ HMAC の同じ部分からつくられるため。

## 参考ページ
https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
Rustで書くUDPサーバー

## UDP Listen

`UdpSocket`を使ってlocalhostとbindする。

```rust
use std::net::UdpSocket;

fn main() -> std::io::Result<()> {
  let socket = UdpSocket::bind("127.0.0.1:34254")?;
}
```

受信できるBufferの容量を指定。
今回は2048byte。

```rust
fn main() -> std::io::Result<()> {
  let socket = UdpSocket::bind("127.0.0.1:34254")?;
  let mut buf = [0; 2048];
}
```

待ち受けしているポートが受信した場合の処理を書く。
また、一回の受信後はまた待ち受け状態にするために、処理をループさせる。

```rust
loop {
  match socket.recv_from(&mut buf) {
    Ok((buf_size, src_addr)) => {
      //
    },
    Err(e) => {
      println!("couldn't recieve request: {:?}", e);
    }
  }
}
```

受信した情報をconsole上にstdoutさせる。
今回出力させるのは、Bufferサイズ、送信元アドレス、メッセージ内容。

```rust
loop {
  match socket.recv_from(&mut buf) {
    Ok((buf_size, src_addr)) => {
      thread::spawn(move || {
        let buf = &mut buf[..buf_size];
        let req_msg = str::from_utf8(&buf).unwrap();
        println!("{:}", "=".repeat(80));
        println!("buffer size: {:?}", buf_size);
        println!("src address: {:?}", src_addr);
        println!("request message: {:?}", req_msg);
      });
    },
    Err(e) => {
      println!("couldn't recieve request: {:?}", e);
    }
  }
}
```

## 全体のコード

全体のコードが以下になる。

```rust
use std::net::UdpSocket;
use std::thread;
use std::str;

fn main() -> std::io::Result<()> {
    let socket = UdpSocket::bind("127.0.0.1:34254")?;
    let mut buf = [0; 2048];

    loop {
      match socket.recv_from(&mut buf) {
        Ok((buf_size, src_addr)) => {
          thread::spawn(move || {
            let buf = &mut buf[..buf_size];
            let req_msg = str::from_utf8(&buf).unwrap();
            println!("{:}", "=".repeat(80));
            println!("buffer size: {:?}", buf_size);
            println!("src address: {:?}", src_addr);
            println!("request message: {:?}", req_msg);
          });
        },
        Err(e) => {
          println!("couldn't recieve request: {:?}", e);
        }
      }
    }
}

```

## 実行

実際に動かして待ち受け状態にした後、`nc`コマンドでメッセージを送信してみる。
結果が以下。

```bash
## Send
$ nc -u 127.0.0.1 34254
固め
濃いめ
多め


## Listen
$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/debug/rust-udp-server`
================================================================================
buffer size: 7
src address: 127.0.0.1:51038
request message: "固め\n"
================================================================================
buffer size: 10
src address: 127.0.0.1:51038
request message: "濃いめ\n"
================================================================================
buffer size: 7
src address: 127.0.0.1:51038
request message: "多め\n"
```

送信された文字列が、それぞれBufferサイズと送信元アドレスと一緒に表示されている。
ESP32-CAMのようなカメラデバイスを作成する

#はじめに

[ESP32-CAM](https://www.amazon.co.jp/Aideepen-ESP32-CAM-5V%E3%83%87%E3%83%A5%E3%82%A2%E3%83%AB%E3%82%B3%E3%82%A232%E3%83%93%E3%83%83%E3%83%88CPU-Bluetooth%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB-TF%E3%82%AB%E3%83%BC%E3%83%89%E3%82%AB%E3%83%A1%E3%83%A9%E9%96%8B%E7%99%BA%E3%83%9C%E3%83%BC%E3%83%89/dp/B07PKQ8B5M)という製品は、ESP32ベースでOV2640カメラが付いた、IoTプロトタイピングに最適なデバイスである。
1000円程度で、

* 4MBのESP32-WROOM-32
* 大きなサイズのJPEGを取り扱うために必要な4MB PSRAM
* TFカードスロット
* OV2640 カメラモジュール
* シリアル書き込みは別途USBシリアル変換で行う

上記を搭載した破格のIoTデバイスである。
ただ、惜しいことに搭載されているESP32モジュールに技適がついていないため、
そのままで使いやすい状態ではない。

[技適対応のWireless-Tag WT-ESP32-CAMを買ってみた](https://lang-ship.com/blog/work/wireless-tag-wt-esp32-cam/)
[ESP32-CAMを技適対応にしてみた](https://firtel.blogspot.com/2019/06/esp32-cam-telec.html)
等、様々に工夫をして技適の問題をクリアする試みが見つかる。

[ESPカメラモジュール [ESP32-CAM-K]](https://www.aitendo.com/product/19515)のようにキット形式のものも出てきている。

今回、セキュアなWEBカメラを作成したく、セキュアエレメントを搭載したOV2640対応のデバイスを作成してみた。

#セキュアなWEBカメラモジュールの作成

[ESP32のセキュアなプロトタイピング環境を作成した(ドキュメント編)](https://qiita.com/kmitsu76/items/76323b7d695833b251e5)ですでに作成しているプロトタイピング環境向けに、OV2640とセキュアエレメントが載ったデバイスを設計する。

まず、[OV2640のデータシート](https://akizukidenshi.com/download/ds/omnivision/ov2640.pdf)を確認してみると、電源が3V、2.8V、1.2Vの3種類が必要なようだ。
併せて[ESP32-CAMの回路図](https://raw.githubusercontent.com/SeeedDocument/forum_doc/master/reg/ESP32_CAM_V1.6.pdf)を確認すると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/8802756a-2e80-5bf7-c4e0-0d3261a6aaad.png)

XC6206　レギュレーターで2.8V、1.2Vを生成している。
3Vの入力はそのままESP32と共通の3.3Vをかけているようだ。

この設計を生かして、TIの[TLV713](https://www.tij.co.jp/product/jp/TLV713)　LDOを使って同様に2.8V、1.2Vを生成する回路を組む。

セキュアエレメントは、プロトタイピング環境向けのATECC608Aを搭載、今後の実験用に同じI2CバスにNXP SE050,Optiga Trust Mを搭載できるようにした。

ESP32はESP32-WROVER-E(8MB)を選択し、PSRAM対応で技適対応のモジュールを搭載する。

カメラは[Sipeed OV2640 魚眼レンズカメラモジュール](https://www.switch-science.com/catalog/5710/)を別途購入した。

基盤を以下のように設計し、いつものElecrowへ依頼。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/e899848f-a633-a9c1-7de3-4b907bfb2e63.png)


実装した写真
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/14db534c-9bbd-0879-3264-a918dfb448db.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/fac1f78a-e37f-b02e-6948-c3945403acab.png)

PSRAM搭載のため、JPEGで大きな画像を撮影できる。
Reactで画面を作成し、2つのカメラの映像を並べて表示してみた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/a49f69a8-2e4b-b428-bbdc-1e7599c70504.png)

<iframe width="560" height="315" src="https://www.youtube.com/embed/V85D79XiV2E" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
PathGeometryを文字列から復元する方法


```
M51.806640625,40.0390625C47.8678359985352,40.0390625 44.8323554992676,41.3981132507324 42.7001953125,44.1162109375 40.5680313110352,46.8343124389648 39.501953125,50.68359375 39.501953125,55.6640625 39.501953125,65.5924491882324 43.017578125,70.556640625 50.048828125,70.556640625 53.1412734985352,70.556640625 56.1848945617676,69.384765625 
...
```

PathGeometryを使っていると上記のような文字列に遭遇することがあるかと思います。

上記の形式の文字列はPathGeometryオブジェクトに変換することが可能です。
やり方は次の通りです。

```csharp
using System.Windows.Media;
var str = "M51.806640625,40.0390625C47.8678359985352,40.0390625 44.8323554992676,41.3981132507324 42.7001953125,44.1162109375...";
var geometry = Geometry.Parse(str);
var pathGeometry = PathGeometry.CreateFromGeometry(geometry);
```
Automate.Parse JSON で Invalid type. Expected {type} but got Null.となった時の対処法

# 概要
Parse JSONを利用した際に、以前であれば以下で簡単に出来ていたんですが、Automateの仕様変更？によって問題が出るようになったので対処法をメモ

- Generate From Sample にSampleのoutputs を設定してやると、Schemaが生成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/150bc4aa-7edb-8858-2b88-f5040f29e4ee.png)

# エラーメッセージ
```json:errorMessage
[
  {
    "message": "Invalid type. Expected String but got Null.",
    "lineNumber": 0,
    "linePosition": 0,
    "path": "Name",
    "schemaId": "#/properties/Name",
    "errorType": "type",
    "childErrors": []
  }
]
```

# 昔の対処法
-  "required": から対象を外す。

# 対処法
1. エラーメッセージの "path" をメモ
1. JSONの定義にいき、型修正
    1. "null" を追加　<br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/81034a13-e381-2c4d-2080-9a826635670a.png)
    1. {} にしてもOK　<br> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/dd12070c-8600-cbe2-ca12-ba1d2b68f3f9.png)
Mac上でskaffoldのCPU使用率が高くなる問題の緩和方法

# （追記）

skaffold のCPU使用率が高くなるのに困って記事を書いたのですが、改めてソース等を調べてみたところskaffoldにバグがあると分かりました･･･ということでPRを作成して送ってみたところ無事にmergeされました。

https://github.com/GoogleContainerTools/skaffold/pull/6114

skaffold 1.28.0 以降には修正が含まれているので、同じ問題で困っている方は更新してみると解消されるかもしれません。

この記事は不要になったのですが、オプションの説明も間違っているわけではないので記事自体は残しておきます。

# 対象としている問題
Mac上で [skaffold](https://github.com/GoogleContainerTools/skaffold) を `dev` モードで起動すると CPU 使用率が非常に高く（CPU使用率100%に）なる場合があります。

skaffold の issue を調べてみたところ [High CPU usage on Mac OS X](https://github.com/GoogleContainerTools/skaffold/issues/531) という関係しそうな issue がありました。このissueによると、ファイルが多数ある場合に変更検知の処理で重くなっているようです。またissueはcloseされているものの、重くなること自体は解消されていないようです。

ということで変更検知の対象となるファイル数を減らせれば良い･･･のですが、そうもいかない状況で少しでもCPU使用率を減らす方法を記載しています。ちなみにいずれの方法もデメリットがあるためCPU使用率とのトレードオフとなります。

# 対象イメージの制限

`--watch-image` オプションに artifact 名を記載すると、変更検知の対象となるイメージ(artifact)を限定できます。

```console
skaffold dev --watch-image=artifact1
```

複数のイメージが含まれる場合は、このオプションで対象を絞ることでCPU使用率をある程度抑えることができます。ただ当然ながら指定しなかったイメージは変更検知の対象外となるので利便性が低下します。

# 変更検知方法の変更

変更検知方法は `--trigger` オプションで指定することができ、デフォルトでは `notify` という方法が選択されています。それ以外に `polling` と `manual` があり、これらを利用することでCPU使用率を低減することができます。

## polling

`polling` を指定すると変更検知を定期実行で行うようになります。実行間隔は `--watch-poll-interval` で指定可能で、デフォルトでは`1000`ミリ秒となります。

```
skaffold dev --trigger=polling --watch-poll-interval=3000
```

CPU使用率は実行間隔を大きくするほど改善されるのですが、変更検知までの時間も長くなるので利便性が低下します。ちなみに私が試した環境ではデフォルトの`1000`ミリ秒ではまったく改善せず `3000`ミリ秒でやっとCPU使用率が半分くらいになる感じです。

## manual

`manual` を指定すると文字通り自動での変更検知を行わなくなります。変更を検知させたい時はコンソールで Enter を入力して手動実行します。

```
skaffold dev --trigger=manual
```

CPU使用率は劇的に低下するのですが、手動で更新する必要があるため利便性も劇的に低下します。
Unity実行時のマウスによるカメラ操作例

#概要
Unity実行時のマウスによるカメラ操作例を記載します。

#実装
##オブジェクト構造
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286581/b1821061-04d9-0956-f52b-5c6f8441ec63.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286581/4d31ced1-88a4-f8be-922a-ad7cdd7ae691.png)
##スクリプト
```cs
using UnityEngine;

public class CtrlView : MonoBehaviour
{
    [SerializeField] Transform TargetCam;
    [SerializeField] Transform ViewPoint;

    [SerializeField] float Angle_Speed = 0.5f;
    [SerializeField] float PosXY_Speed = 0.005f;
    [SerializeField] float PosZ_Speed = 5;

    Vector3 MousePos;

    void Update()
    {
        // マウスの移動量を取得
        var diff = MousePos - Input.mousePosition;
        MousePos = Input.mousePosition;

        if (Input.GetMouseButton(0))
        {
            // 左クリック（回転）
            var tmp = diff;
            diff.x = +tmp.y;
            diff.y = -tmp.x;
            ViewPoint.eulerAngles += diff * Angle_Speed;
        }
        else if (Input.GetMouseButton(1))
        {
            // 右クリック（移動）
            var tmp = diff;
            diff.x = -tmp.x;
            diff.y = +tmp.y;
            ViewPoint.position += diff * PosXY_Speed;
        }

        // スクロール（拡縮というか前後）
        var scroll = Input.GetAxis("Mouse ScrollWheel");
        var pos = TargetCam.localPosition;
        pos.z += scroll * PosZ_Speed;
        TargetCam.localPosition = pos;
    }
}
```
#補足
スクリプトは同クラス名でファイルを作成してそのままコピペしたら、どこかテキトウなオブジェクトにアタッチして、TargetCamに操作したいカメラ、ViewPointに視点とするカメラの親オブジェクトを設定すればそのまま使えます。
対象を中心にカメラどうやって回せばいいの？と思って良く分からない計算しようと思ったりしたこともありましたが、カメラをオブジェクトの子にしてオブジェクトを回せば良いのでは？という方法になります。
利用シーンは多そうな気がするんですが基本的過ぎる？せいか、あまりド直球な例は見かけないため、自分用としてのメモもかねて記事にしました。
【PHP】PHP課題14-8 ジャンケンゲーム  難易度（高）


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/94cd6c7f-2233-f347-177d-1d1e92680e5f.png)

```
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/04b768fa-3780-2eff-bc8e-08422eca0f65.png)

```
```

１・画面のレイアウトは画像の通り
２・ユーザーはグー・チョキ・パーのいずれかをラジオボタンで入力する
３・submitされたら、ユーザーの手を表示する
４・submitされたら、コンピュータの手をグー・チョキ・パーからランダムに選択し、表示する
５・submitされたら、じゃんけんの勝敗を判定し、出力する
６・利用するクラスは public/object_sample/classes 内に作成し、適宜読み込む。
７・JankenGameクラスとHandクラスを作成する。
JankenGameクラスはコンピュータの手をランダムに決める。
JankenGameクラスはユーザーの手とコンピュータの手を比べて勝敗を判定できる。
JankenGameクラスは勝敗に応じて結果のテキストを返す。

/laravel_bbs/public/object_sample/**rock_paper_scissors.php**

```PHP
  <?php
  require_once 'classes/Hand.php';

  require_once 'classes/JankenGame.php';

  $hand   = new Hand();
  $cpu    = new Hand();
  $result = '';

  if($_SERVER['REQUEST_METHOD'] === 'POST'){ 
      $hand->set($_POST['hand']);
      $cpu->random();
      $jankenGame = new jankenGame($hand,$cpu);
      $result     = $jankenGame->get_result();
  }
  ?>  

<!DOCTYPE html>
<html lang="ja">
<head>
    <title>じゃんけん</title>
</head>
<body>

  <h1>じゃんけん勝負</h1>
  <p>あなたの手：       <?php print $hand->get(); ?> </p>
  <p>コンピューターの手：  <?php print $cpu->get(); ?> </p>
  <p>結果：            <?php print $result; ?> </p>

  <form method="post">
      <label> グー <input type="radio" name="hand" value="グー" required ></label>
      <label>チョキ <input type="radio" name="hand" value="チョキ" required ></label>
      <label>パー <input type="radio" name="hand"  value="パー" required ></label>
      <input style="display:block;" type="submit"  value="勝負">
  </form>
  
  <p><a href="rock_paper_scissors.php">初画面</a></p>

</body>
</html>


```

/laravel_bbs/public/object_sample/classes/**Hand.php**

```php

<?php

class Hand {
    
    const HANDS = ['グー', 'チョキ', 'パー'];

    private  $hand;

    public function __construct(){
        
        $this->hand = '';
    }
    
    public function random(){
        
        $this->hand = Hand::HANDS[array_rand(Hand::HANDS)];
        
    }
    
    public function set($hand){
        $this->hand = $hand;
    }
    
    public function get(){
        return $this->hand;
    }
    
}
```

/laravel_bbs/public/object_sample/classes/**JankenGame.php**

```PHP
<?php

class JankenGame {
    private  $hand;
    private  $cpu;
    
    public function __construct($hand, $cpu){
        
        $this->hand = $hand;
        $this->cpu  = $cpu;
    }
    
    public function get_result(){
        $playerHand = $this->hand->get();
        $pcHand = $this->cpu->get();
     
        if ($playerHand == $pcHand) {
            $result ='あいこ';
        } elseif ($playerHand == 'グー' && $pcHand == 'チョキ') {
            $result = '勝ち';
        } elseif ($playerHand == 'チョキ' && $pcHand == 'パー') {
            $result = '勝ち';
        } elseif ($playerHand == 'パー' && $pcHand == 'グー') {
            $result = '勝ち';
        } else {
            $result = '負け';
        }
        return $result;
    }

}
```
Python + Selenium 4で Edge のヘッドレス (Headless) 起動の設定

# 概要
PythonでWeb操作の自動化をする際に、ヘッドレス設定をそのまま使えるところがなく困ったのでメモしておく

# 環境
- Selenium 4.0.0.a7
    - beta4 まで出てたのね・・[nuget beta4](https://www.nuget.org/packages/Selenium.WebDriver/4.0.0-alpha04)
- python 3.9.5

# コード例
```python:automateWeb.py
# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.options import Options

options = Options()
options.use_chromium = True
options.headless = True

service_args = ['--verbose']

browser = webdriver.Edge(
  executable_path='msedgedriver.exe',
  options=options,
  # service_args = service_args,
  # service_log_path=service_log_path,
  # verbose=True
  )

browser.implicitly_wait(10) 
browser.get('{target url}')
   # 省略
```

# 参考
[Selenium 4 With Python: All You Need To Know](https://www.lambdatest.com/blog/selenium-with-python/#:~:text=The%20Alpha%20release%207%20%28Selenium-4.0.0.a7%29%20for%20Selenium%204,including%20the%20provision%20of%20CDP%20%28Chrome%20Debug%20Protocol%29.)
[テスト オートメーションに WebDriver (Chromium) を使用する](https://docs.microsoft.com/ja-jp/microsoft-edge/webdriver-chromium/?tabs=python#choose-specific-browser-binaries-chromium-only)
[Chromium-固有 のオプションを使用する](https://docs.microsoft.com/ja-jp/microsoft-edge/webdriver-chromium/?tabs=python#use-chromium-specific-options)
ユーザーエージェントを判別するAgentをLaravelにインストールする

![68747470733a2f2f6a656e737365676572732e636f6d2f7374617469632f6d656469612f6167656e742e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47882/bc9f18d2-f2fb-528f-e6e2-e163b667cc57.png)

「Agent」のロゴ。ダンディですね。

# UserAgentを識別するライブラリ「Agent」
https://github.com/jenssegers/agent

PHPでユーザーのOSやブラウザの種類を判別したいときには「Agent」が便利です。

## 使い方

```php
<?php
use Jenssegers\Agent\Agent;

$agent = new Agent();

// デバイスのチェック
$agent->isAndroidOS();

// ブラウザのチェック
$agent->isIE();
$agent->isSafari();

```

# Laravelへのインストール

composerでインストールします。

```terminal
composer require jenssegers/agent
```

Laravelから呼び出せるように設定を`config/app.php`に足します。

```php:config/app.php
Jenssegers\Agent\AgentServiceProvider::class,
```

```php:config/app.php
'Agent' => Jenssegers\Agent\Facades\Agent::class,
```

# LaravelのBladeに便利に渡す

ServiceProviderを追加し、Bladeテンプレートに常に`$agent`が渡されるようにします。
これでいつでもBlade内から`$agent`を参照することによってUserAgentを取得できます。

```php:app/Providers/AgentServiceProvider.php
<?php

namespace App\Providers;

use View;
use Jenssegers\Agent\Agent;
use Illuminate\Support\ServiceProvider;

class AgentServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $agent = new Agent();

        View::share('agent', $agent);
    }

    public function register()
    {
        //
    }
}
```

```php:config/app.php
<?php
    ... 略 ...

        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        
        ... 略 ...

        App\Providers\AgentServiceProvider::class,
    ],
```

これで以下のようにBladeテンプレートから呼び出せます。

```php:index.blade.php
    @if($agent->isIE())
        {{ 'Internet Explorerを使っています。' }}
    @endif
```
DEPRECATION WARNING: Devise::Models::Authenticatable::BLACKLIST_FOR_SERIALIZATION is deprecated! Use Devise::Models::Authenticatable::UNSAFE_ATTRIBUTES_FOR_SERIALIZATION instead.  が出た時。

railsでAPIを開発していて、devise_token_authをインストールしたのちにコマンドを打つと、タイトルのような警告が出現。
ターミナルが見づらくなるので、今後のために対処法をメモっておく。

# 警告発生までの流れ
①Gemfileに devise, devise_token_auth を追加
②``bundle install``
③``rails g devise:install``
④``bundle exec rails g devise_token_auth:install User auth``
⑤``bundle exec rake db:migrate``　←ここで警告が表示されるようになる。

# 原因
どうやら2021年5月にあったdeviseのアップデートによって、バージョンが'4.7.3'→'4.8.0'にアップデートされたらしく、デフォルトのdevise_token_authをインストールすると警告が出現するらしい(？)

#解決策
Gemfileのdeviseのバージョンを'4.7.3'に指定して⑤以降の操作をやりなおすとできた。①〜④をやり直す必要はなさそうだ。

1 Gemfileを修正

```ruby:Gemfile
# This is for authentication based on token
gem 'devise', '4.7.3'                           
gem 'devise_token_auth'         
```



2 ``bundle install``



#参照
https://github.com/lynndylanhurley/devise_token_auth/issues/1483
Chanpon  Securityの皆様に聞いた、初めての学習への取り組み方

私がセキュリティーの勉強をどうすればいいか分からなくなっていた際に、皆様に有難いお言葉を頂いたのでその要約です。<br>

沢山の良い意見を頂いて、これはコミュニティーに限らず、勉強を始める時にも知っていただきたい方法だな、と思い記事にしました。

# Chanpon Securityとは？

まずChanpon Securityとは？というところですが、技術に関して、色々な意見を交わしたり、情報交換することによって一人で勉強するハードルを乗り越えて成長していこうというコミュニティーです。
特定の分野やカテゴリ、方針などに拘らないな感じで自由にやれたらいいなーという思いからちゃんぽんという名称らしいです。

https://twitter.com/number3to4/status/1406099808385785862?s=20

https://twitter.com/mimura1133/status/1406243441793650689?s=20

「私は初心者だから怖いなあ･･･」と思っていましたが、快く大丈夫と言ってくださいました。
セキュリティーの技術交換をしたい方はぜひ･･･！


# テーマ「初めての学習でどう取り掛かればいいのか」

私が「セキュリティーの勉強始めるぞー！」となった時に、知らない単語、知らない説明が多すぎて、診断の方法を身につけることに高いハードルを感じており、どうしたらこの高い壁を乗り越えることが出来るのかアドバイスを頂きたいという投稿をしました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1110799/3d3a16d6-34da-ce99-c86a-0931808fb5cf.png" width=80%>

# 1. インプット

最初はインプットから。
本を読んだり、ハンズオンに参加することで、インプットしていくという方法。
最初は全てを理解するのではなくて、ある程度ざっくりと理解して次の段階(実践)に進むようにする。
(ハンズオンは次の項目の手を動かした実践にも含まれると思いますが、どちらかといえばインプット方面かなと思ったのでこちらに入れてます)


実際にもらった意見のまとめ

- とにかく真似る
- ハンズオンに参加してみる
- ざっくり一通り触れる
- CTFとかで勘を養う

# 2. 手を動かした実践

インプットをした後は、自分でやってみることによって知識として落とし込むという感じ。

ポイントとしては、考える事と範囲を決める事。
考える事については、「こうすればこうなるかな」とか「どうしたらこうなるだろう」など思考しながらやることによって、間違って覚えていた知識を修正したり、頭に入りやすくなるから大事。また何回も手を動かして実践することで自分流を身につけることが出来、今後も応用することが出来るようになる。

範囲を決めるのは、ある程度理解できた範囲に限定して集中的に理解を深めることによって、気が付いたら周辺知識も身につけていてそこそこ分かっているようになるから。(全てを理解しようとするととても出来ないと思ってしまうからというのもありそう)


実際に頂いた意見のまとめ

- 攻撃手法の目星をつけながら攻撃の実践を行う
- 「わかりそうなことだけを徹底的にわかるようにする」という学び方をする
- 2,3機能くらいにスコープ絞ってやってみる
- ある程度オレオレ手法を作る

# 3. アウトプットをする

ある程度理解した段階で人に発表する。「締め切り」「知らないことを理解する」「自分の言葉に置き換えて説明できるようにする」の3コンボによって、身に付くようになる。

実際に頂いた意見のまとめ

- 勉強会で「ほんわかしか知らないテーマ」なのにスピーカー登録して、いっちょ前に喋るってことを繰り返す

# その他ツール、思考整理方法など

- どこで躓いているかをしっかりと把握する
- サンプルレポートを見て、まとめ方を学習する
- マインドマップを作って思考を整理する

マインドマップのオススメ↓

https://www.freeplane.org/wiki/index.php/Home

演習資料↓

https://speakerdeck.com/owaspkansai/owasp-kansai-20180427handson

# 最後に

質問に答えて頂いた皆様ありがとうございましたー！
まとめる為にかなり文章を削減してしまったので、伝わらなかったらごめんなさい_(._.)_
ほかにもアドバイスがあったら教えてください！
Windows環境のdockerで外部ネットワークに接続できない

WindowsをDockerのホストとゲストとして利用しており、ゲスト内から`npm ci`がエラーになる問題でハマりました。
エラーは以下のようなメッセージ。

```
getaddrinfo EAI_AGAIN registry.npmjs.org:443
```

どうやら名前解決で失敗しているもよう。

Dockerの設定を開き、Docker Engineメニューのconfigurationに以下を追加してDockerを再起動して解決しました。
GoogleのDNSサーバーを追加しているようです。

```
"dns": ["8.8.8.8"]
```

参考
https://github.com/StefanScherer/dockerfiles-windows/issues/270#issuecomment-382229052
Lua 入門メモ

# Lua 入門メモ

関数を作るのは勝手だが、
この言語にはプロトタイプ宣言はないらしいし、
もちろん下には飛ばない


## Hello World
``` test.lua
print "Hello"
print("World")
```

## コメントアウト(--)
``` test.lua
pint "Hello"
--print("World")
```

## コマンドライン引数(arg)
``` test.lua
print(arg[0])
```
実行結果

```
$ lua test.lua hoge
test.lua
```

## 配列要素数 - 1 (#)
``` test.lua
print(#arg)
```
実行結果

```
$ lua test.lua hoge fuga
2
```

## 数字→文字 (tostring)
```test.lua
print("argnum : " .. tostring(#arg + 1))
```
## 文字連結 (..)
上記

## 外部コマンド実行 (os.execute)
``` test.lua
os.execute("cat" .. arg[1] .. " |grep hoge")
```


#???
``` hoge.lua
hoge = "42"
hoge = hoge + 1
pint(hoge)
--43
```
Qiita Organization を使い始めるとき

## はじめに

個人的にずっとやってみたかったけど、一歩を踏み出せずにいた Qiita

せっかく始めるならば、ということで Organization を作り、会社として参加するよう提案しました

（私は役員でも管理部門でも管理職でもないです）

どのように提案し、稟議し、アカウントを作り、 Organization を作ったのか、経緯を残しておきたいと思います

## 契機

前年度（2020年度）の1年間、社内勉強会で講師役を何度か勤めました

　AI、AWS、Python、Dockerなどなど、私が扱ってきた諸々について

1年間やって、講師をすることのメリットを実感しました

- 資料として自身の知識を整理できる
- 人に教えるために、更に深い知識が身に付く
- ハンズオンのための環境作りでもスキルが磨ける
- トーク力、度胸が付く

しかし、以下のような限界も感じました

- 社外へのアピールにならない
- ちょっとしたトピックなどで気軽に開催できない
- 受講者も、講師も限られた人だけになる
- 社内向けなので、ほとんど叩かれない = 緊張感が足りない

講師をするためには結構な準備が必要で、それを残業時間でやるわけですが、これではもったいない

そこで、今年度は兼ねてより興味のあった Qiita を使ってみようと考えました

- 社外にアピールできる
- いつでも気軽に投稿できる
- 誰でも見れるし、誰でも書ける
- 全世界に公開されるので十分な緊張感がある

そして、 Qiita 　について調べたところ、 Organization の機能を見つけ、これは会社としてやるしかない、と思い上長に提案しました

- Organization を使うことで、企業として技術を外部にアピールできる
- 記事を書くために整理・調査することで技術者全体のレベルアップを図れる

## ルール作り

会社として利用するにあたって、それなりにルール作りが必要になるため、以下のようなルールを提案しました

これらにより、社内の管理部門が個人アカウント、記事の内容を把握することができ、不正な投稿を防ぎます

### Organization へのアカウント追加ルール

- 個人のアカウントは自由に作成可能

- Organization に参加する際、まず社内ワークフローにて申請・承認を得る

- 承認後、管理部門が Organization に招待する

### 記事の投稿ルール

- 各個人が記事を書いたときは、まず **限定共有投稿** する

- 社内ワークフローにて記事の内容について申請・承認を得る

- ワークフロー内で必要に応じて有識者のレビューを受ける

- 承認後、各個人が **全体に共有** する

## Organization 作成

無事、上記ルールによって社内稟議が承認されました

意気揚々と Organization を作るよう管理部門に依頼したのですが、、、

なんと、ある程度 Qiita での実績がないと作れない仕様でした！

記事を一つも投稿していない時点では作れません

と、いうわけで、以前から準備していた AI　や Tellus などのキャッチーな記事を3本投稿してみることに

翌日には無事、投稿した私の個人アカウントで Organization を作成することができました

Organization の作成時に管理部門のアカウントを招待しています

## 今後

今後は私自身どんどん記事を書いていこうと思いますが、それ以上に社内の有志に記事を書いてもらうつもりです

技術者が活発に研鑽する場として、 Qiita を活かしていきたいと思います