OmniAICreator/Qiita-1.07M huggingface dataset:
Web制作におけるVSCodeのおすすめ拡張機能

# 初めに
環境設定......なにそれおいしいの？
そんな自分が出会ったやらなければいけない事orz、やった方が良い事について、備忘録として記載していきます。
（文章力が無いので読みづらい場合はすいません...）

本稿では、HTML,CSSを用いる場合のVSCodeのおすすめ拡張機能（ついでに設定とか）を記載します。

# 拡張機能一覧
#### [1. Live Server（Webページ確認）](#1-live-server)
#### [2. Live Preview（Webページ確認）](#2-live-preview)
#### [3. Auto Rename Tag（HTMLのタグを同時に変更）](#3-auto-rename-tag)

## 拡張機能説明
#### [1. Live Server](#拡張機能一覧)
Live Serverとは、作成した（又は作成途中の）Webページを簡単に確認する方法です。
Live Serverをインストールすると、VSCode右下に、Go Liveと書かれた下のボタンが出現します。
![Live_Server.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545522/8c015e27-6d57-ecb3-7f67-a284937a6c14.png)
このボタンを押すことで、自動的にブラウザへWebページを表示してくれます。

HTMLファイルを右クリックしてパスをコピーしてブラウザに貼り付ければ確認できますが、
正しく表示されなかったり、F5キーなどでページを更新しなければいけなかったりすることがあるので、
ローカルファイルを簡単に開けるLive Serverがお勧めです。

**※　HTMLファイルを開いた状態で押してください。cssなどを開いた状態で押しても違う画面になります。**

#### [2. Live Preview](#拡張機能一覧)
Live Previewは、Live Serverよりさらに簡単にWebページを確認できる方法です。
Webページの内容をVSCode上で確認できるので、モニターが1つしかない方などには特におすすめです。
また、リアルタイムで書き換えた内容を更新してくれます。

ここまで言うと、Live Serverの立つ瀬がない感じがありますが、実際は使い分けを行うことが重要です。
Live Previewはあくまでも変更点の簡易な確認手段だと思ってください。
出来たWebページを実際にLive Serverなどで確認すると思っていた動作と異なる場合があります。
（自分はまだ実感してない。。。）

#### [3. Auto Rename Tag](#拡張機能一覧)
Auto Rename Tagは、HTMLのタグの種類を同時に変更してくれます。

例えば、下記例ではタグが*h1*なりますが、*h2*に変更したい！となった場合にこの拡張機能を入れていると、
*Hello World*の前後どちらの*h1*を*h2*に変えた場合、変えてない方の*h1*も同時に変更してくれます。
```
<h1>Hello World</h1>
```

# 最後に
以上でお勧め拡張機能の紹介を終わります。
今後もこれいい！っていう拡張機能があれば随時追加してまいります！

また、VSCodeのオススメ拡張機能・設定もまとめておりますので、興味があればそちらもどうぞ
誰かのために

 
<br><br><br><br><br>
#### プログラミングは美しくなければならない。 
<br><br><br><br><br>
　実際、美しく書けるかどうかではない。美しく書こうという心構えが大切だ。コーディングの話ではない。いやコーディングの話なのか？　
<br><br><br>

計画の段階で「こういう風に書き始めよう、ああいうステートメントを書くだろうな、ちょっとだるいな。あのライブラリ使うな、久しぶりだし覚えてないなぁ。あとこういうAPIが必要だな。勉強しないと。。。。」

<br><br><br>


　こんな脳内ふわふわ計画段階で、8割決まっていると私は思う。問題点、課題が正確に把握できているならば、それを実行すればいいだけだからだ。
　やることが分かっている。明確な着地点が見えている。これ以上ないことだ。

<br><br><br>


　生きるということはあいまいだ。20世紀の哲学者、アルベール・カミュは著書｢シーシュポスの神話｣でこう書き出している。 

<br><br><br><br><br>

>「真に重大な哲学上の問題は一つしかない。自殺ということだ」

<br><br><br><br><br>

 生きるということにそもそも意味がないならば、今すぐ死ぬのが正解だ。つまりカミュは、下記のifが、初期化処理内(人が生まれた時)にあるだろう、という。

<br><br><br>
```C#
While(true)
{
    if (「生きる意味」 == true)
    {
        人生();
    }
    else
    {
    break;
    }
}
```
<br><br><br>
　友と談笑するのも、仕事に汗水流すのも、すべての前提、根本にある if (「生きる意味」 == True) が真であってこそ。そもそもfalseなら、人生()メソッドはいらない。今すぐ生きるというWhile(true)からbreakするのが論理的じゃあないか。

<br><br><br>

でも、残念ながら生の意味は誰にも分らない。　bool 「生きる意味」　は、　Public Static　ではないローカルな変数だ。その真偽に私たちはアクセスできない。
<br><br><br><br><br>
>―――何故こんな事になったのだろう。分らぬ。全く何事も我々には判らぬ。理由も分らずに押付けられたものを大人しく受取って、理由も分らずに生きて行くのが、我々生きもののさだめだ。―――

<br><br><br>

とは中島敦「山月記」の一節だが、とっても濃厚な一文で、ハッ、とさせられる。
<br><br><br>
　私は100%独学でへっぽこプログラミングをしている。田舎の小さな町工場で、Excel関数を一つも知らない事務員さんや、21世紀だというのに紙の帳簿に入出庫を記帳している経理や、毎回紙のカレンダーに予定を書いてる職長や、客先との急ぎではないやり取りを毎回電話でしている同僚のため、「少しでも仕事を楽にしてあげられたらいいな」という心でプログラムを書いている。全部は無理だ。私はヤハウェじゃない。少しづつ。ひとつづつ。
<br><br><br>

　しかしSEなわけではなく、普通に工場の作業員である。金属プレス加工業を営む会社にお世話になっており、鉄を曲げたり、穴を空けたりする合間に、VBAやVSをポチポチしている。

<br><br><br>

　片手間の、独学で、大した技量でないのは自分でわかっている。先人の書いた記事とにらめっこして、本を読んで、やっとこさぐちゃぐちゃのコードが、どうにか動く。

<br><br><br>

　いろんなやり方がある。一つの目的に、選択肢が3つ4つgoogleで検索上位にヒットする。どんな言語で書くかも選ぶ余地があったりする。
<br><br><br>


　自由だから、どれかしらの方法を選ぶしかない。なるべく簡単な方法を。どれが一番簡単か考える。英語のサイトだとちょっと気後れする。だからQiitaで、日本のみなさんが書いてくれたものを参考にすることが多い。

<br><br><br>


>―――人間は自由の刑に処せられている――― 　　

<br><br>
ジャン･ポール･サルトルの言葉だそうだ。なんと簡潔で美しい言葉だろうか。私たちの生活や努力が、この一言にバネのように撓んでしまわれているように私は思う。

<br><br><br>

　今までQiitaの記事に、たくさん助けられた。だから自分も、少しづつここに書いていけたらと思った。もちろん、自分自身の備忘録、復習のためが一番だけど、もしも誰かの助けになれたらこんなに嬉しいことはない。こんな気持ちを引数にして、誰かに値を渡せたら。


<br><br><br><br><br><br>

　私が初めてちゃんとコーディングしたのはExcelVBAだった。同じ事業所の事務員さんが、毎日製品の入出庫をExcelに記帳していた。
 会社全体の帳簿であり、どこに何個ものがあるのかは考慮外だったが、だれかのわがままで事業所ごとの在庫も記帳し始めた。会社としては頼んでいない。彼女が勝手に始めた仕事。

<br><br><br>

　客先との取引の流れを、細かく都度メールにまとめて配信していた。会社としては頼んでいない。誰かが、自分が楽をしたくて彼女に頼んだのだろう。彼女が勝手に始めた仕事。だからだれも手伝わなかったし、彼女だけいつも忙しそうだった。

<br><br><br>

みんなのためにと、彼女は思ってくれていたのだと思う。会社のカギは私が持っていたので、残業したい、とよく相談してくれた。

<br><br><br>

　だんだん彼女は元気がなくなってしまった。手伝いますよ、と声をかけても、私が好きでやってることだから、といつも断られた。会社としても、そんな仕事しなくていいよ、と何度も伝えていた。彼女は頑なだった。

<br><br><br><br><br><br><br>

　なにかできることは。そう思って、VBAを勉強し始めた。




<br><br><br><br><br><br><br><br><br>





　出来上がった時、もう遅かった。　彼女はうつ病の診断書を持ってきた。そのまま退職してしまった。




<br><br><br><br><br><br><br><br><br><br><br><br><br>







　だから、きれいなコードじゃなくていい。
<br><br><br>
　無駄があっても、動きが遅くても、ユーザビリティが低くても、ベストプラクティスじゃなくても、オブジェクト指向の理解が間違ってても、UIがダサくっても。


<br><br><br><br><br><br><br>





　誰かの助けになるかもしれないから。

<br><br><br><br><br><br><br>

　誰かを守る武器になるかもしれないから。

<br><br><br><br><br><br><br><br><br><br><br><br><br><br>




　プログラミングは美しくなければならない。




<br><br><br><br><br><br><br><br><br><br><br><br><br><br>
【AWS】CDKでECSサービスディスカバリを設定する方法

# 前提

### CDKとは？
JavaやTypescriptなどのプログラミング言語を使用してAWSのリソースをコードとして定義し、AWS上にデプロイするためのフレームワーク。コードでAWSリソースを管理する感じのもの。個人的には、概念的にはAnsibleに似てると感じた。
### ECSとは？
DockerのコンテナをAWS上で動かすサービス

### サービスディスカバリとは？
ECS間通信に使うサービス。サービスディスカバリを使えば、コンテナにFQDNがついてIPアドレスではなく名前（FQDN）でアクセスできる。実際はFQDNとIPアドレスの対応がRoute53に自動で登録される。
マネジメントコンソールからだと、
- ECS > クラスター > サービスの作成 > ネットワーク構成 > サービスの検出

から設定する。
一般的な他の方法としては、ECSでコンテナをたてるとIPアドレスを付加して他のリソースからアクセスするなどの方法がある。

# 困ったこと
CDKでコードを書こうとして、ecs,サービスディスカバリのドキュメントを読んでいくが、ECSとサービスディスカバリのクラスには両者を関連させるメソッドが存在しない。

### 参考
- [class ServiceDiscovery · AWS CDK](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-appmesh.ServiceDiscovery.html)
- [@aws-cdk/aws-ecs module · AWS CDK](https://docs.aws.amazon.com/cdk/api/v1/docs/aws-ecs-readme.html)

# 困る前にできていたこと
- マネジメントコンソールからボタンを押していってサービスの検出をすることはできていた。
- [class ServiceDiscovery · AWS CDK](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-appmesh.ServiceDiscovery.html) を参考に、CDKで以下の名前解決はできていた。Exampleのコードに書いてある通りに実現できた。
    - [FQDN-コンテナのIPアドレス]のレコード追加
    - [FQDN-Application load balancer]のレコード追加

# 解決するために必要だったこと
- サービスディスカバリとはどういうものなのか今一度知ること

# 結論
(CDKでECSサービスディスカバリを設定するコード)
以下のようにすればよかった。
```java

// まずサービスディスカバリを作る
// 以下の記事あたりを参考
// https://docs.aws.amazon.com/cdk/api/v1/java/software/amazon/awscdk/services/ecs/FargateService.html
Cluster cluster;
TaskDefinition taskDefinition;
Vpc vpc;
FargateService fargateService = FargateService.Builder.create(this, "Service").cluster(cluster).taskDefinition(taskDefinition).build();


// サービスディスカバリの機能を使ってレコードをroute53に登録
// ここのコードは以下に記載してあるものとだいたい同じ
// https://docs.aws.amazon.com/cdk/api/v1/java/index.html?software/amazon/awscdk/services/servicediscovery/package-summary.html
PrivateDnsNamespace namespace = PrivateDnsNamespace.Builder.create(this, "namespace")
        .name("domainName")
        .vpc(vpc)
        .build();
Service service = namespace.createService("service-discovery-service", DnsServiceProps.builder()
        .dnsRecordType(DnsRecordType.A)
        .dnsTtl(Duration.seconds(30))
        .loadBalancer(false)
        .name("subDomainName")
        .build());

// ECSからcloudMapsサービス経由でサービスディスカバリを用いる。　　ここが難しかったポイント
// 以下の記事の中のAssociateCloudMapServiceOptionsメソッドを用いる
// 　https://docs.aws.amazon.com/cdk/api/v1/java/index.html?software/amazon/awscdk/services/ecs/package-summary.html
fargateService.associateCloudMapService(AssociateCloudMapServiceOptions.builder()
        .service(service)
        .build());


```

#### ポイント
- サービスディスカバリの後ろ側ではCloudMapが動いていると知ること
- ECS-CloudMap-Route53　のように間にCloudMapを仲介してECSとRoute53を関連させること

# 感想
英語の記事含め、直接「CDKでECSサービスディスカバリを設定する」記事が見つけられなかったので難しかった。
そのため、正直、上記のassociateCloudMapServiceのコードを書いて実行するまで本当に「CDKでECSサービスディスカバリを設定する」ことが可能なのか半信半疑だった。
同じ悩みをもった方々の参考になれば嬉しいです。

# 謝辞
上記の解決を手助けしてくださった方々、感謝しております。
ありがとうございます。
CountdownCalendar 2022を企画する Wireshark(14)

Countdown Calendar 2021では、手が回らない企画がいくつかあった。

その反省に立って、大事なCountdown Calendarは半年前から企画することにする。

自分が企画するのではなく、投稿するだけのものも、準備を始めたものがある。

# FreeBSD Countdown Calendar 
FreeBSD Advent Calendar 2022記事を書き始める。
https://qiita.com/kaizen_nagoya/items/b169da9fdf0cb0a16253

FreeBSD Countdown Calendarは、記事をfacebookに記載してくださったり、
記事を読む企画をしてくださったりする。すごい。

FreeBSD Countdown Calendar 2021

https://qiita.com/advent-calendar/2021/freebsd

BSDnagoyaのMLに長く参加していたメールアドレスは、退職とともに消えてしまい、
ちょっと疎遠になっていたところ。

Ethernet のプログラム組んだら、BSDで対向試験をするのは続けている。

そんなこともあって、FreeBSDの Advent Calendar 2021に投稿した。

ネットワーク ReferenceとしてのBSD
https://qiita.com/kaizen_nagoya/items/14fba711d42fd8b5db4c

今度は、ちゃんとWiresharkで測定するとこまでやって連携したい。

# Wireshark Countdown Calendar
Wireshark Countdown Calendar 2021
https://qiita.com/advent-calendar/2021/Wireshark 

投稿数２１。これを満席にする。

Wireshark Countdown Calendar 2021 を満席にする3つの方法
https://qiita.com/kaizen_nagoya/items/295bf68a9724d0ba3c9a

カレンダーにURLを、20220611まで間違ったのを張っていた。ごめんなさい。今、差し替えました。

FreeBSDでEthernetのプログラムを動かしたり、対向試験したものをWiresharkで測定して
Wireshark Countdown Calendarに投稿すればいいかも。

自分が投稿するのと、みなさんに投稿していただくのと、２つのCalendarにしてもいいかも。

記事を書き始めながら、企画を相談するのもいいかも。

の派生記事を書き始めるのもいいかも。

# 参考資料
Wiresharkのインストール手順（Windows編）
https://qiita.com/yasushi-jp/items/7cacbe6089c760ad4202

WireSharkで学ぶネットワークの基礎
https://qiita.com/na-777/items/d656f720709de2ca4ec4

WireSharkの仕組み
https://qiita.com/Kate941-su/items/df7276b746602a49f0da

wiresharkで保存したデータをpysharkで扱う
https://qiita.com/etherpoc/items/aa5d567ed19d7bd22076

m1macにWiresharkをインストール
https://qiita.com/Qubieeee/items/b72f09eb28f768ff52f2

Nutanix から通信フロー情報を取得してみる
https://qiita.com/2-3/items/117b1530666e400b11ad

## 自己参照
Ethernet Countdown Calendar 2022を企画する
https://qiita.com/kaizen_nagoya/items/1a747cb74ba05b9ef023

Wi-Fi(IEEE 802.11) Advent Calendar 2022を企画する
https://qiita.com/kaizen_nagoya/items/7e14d70cafe4e87525a5

CountdownCalendarに過去記事を投稿
https://qiita.com/kaizen_nagoya/items/9a37fed670a774c3c7e8

# 自己参照
Error一覧 error(0)
https://qiita.com/kaizen_nagoya/items/48b6cbc8d68eae2c42b8

プログラマが知っていると良い「公序良俗」
https://qiita.com/kaizen_nagoya/items/9fe7c0dfac2fbd77a945

Ethernet 記事一覧　Ethernet(0)
https://qiita.com/kaizen_nagoya/items/88d35e99f74aefc98794

Wireshark 一覧 wireshark(0)、Ethernet(48) 
https://qiita.com/kaizen_nagoya/items/fbed841f61875c4731d0

線網（Wi-Fi）空中線(antenna)(0) 記事一覧(118/300目標)
https://qiita.com/kaizen_nagoya/items/5e5464ac2b24bd4cd001

通信記事１００
https://qiita.com/kaizen_nagoya/items/1d67de5e1cd207b05ef7

一覧の一覧( The directory of directories of mine.) Qiita(100)
https://qiita.com/kaizen_nagoya/items/7eb0e006543886138f39

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently.
### 文書履歴(document history)
ver. 0.01 初稿 　 20220621
ver. 0.02 ありがとう追記 20230530
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
JS 公開鍵 暗号化 => PHP 秘密鍵 複合

メモ。
[ここ](https://qiita.com/buntafujikawa/items/51de0847232a117b272a)を参考にしたけど、自分の環境だとcrypto モジュールがうまく設定できなかったので、JSEncrypt を使う。

```shell
# JSEncryptを入れる
$ yarn add jsencrypt
```

```JavaScript:JavaScript
import JSEncrypt from 'jsencrypt';
import axios from 'axios ';

// 公開鍵取得
const publicKey = await(async()=>{
  const res = await axios.get('/crypt/publickey');
  return res.data || "";
})();

// 暗号化
var encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);
var encrypted = encrypt.encrypt("hogehoge@example.com");

// サーバ側で複合
const res = await axios.post('/crypt/decode', {encrypted});
console.log("res.data", res.data);
```

```PHP:Laravel
class CryptController extends Controller
{
    public function __construct()
    {
    }

    public function publickey()
    {
        return file_get_contents(resource_path('rsa_2048_pub.pem'));
    }

    public function decode(Request $request)
    {
        $privatekey = file_get_contents(resource_path('rsa_2048_priv.pem'));
        $encrypted = base64_decode($request->encrypted);

        $decrypted = null;
        if (!openssl_private_decrypt($encrypted, $decrypted, $privatekey)){
            abort(422);
        };

        return $decrypted;
    }
}
```
Dockerで構築したLaravelアプリでStorageをホスト上の外付けHDDに紐付けした話

**ローカルでのみ開発するのにどうしてもファイルストレージを外付けHDDにしたかった。**


クラウドストレージサービスを使っても良かったのですが、　不要なHDDがあったのでそちらに画像などを保存したかった。
※月額料金が掛かるのが嫌だっただけ（笑）



**環境**
・OS ：MacOｓ　BigSur(M1 mac)
・Laravel（Docker）


XAMPでLaravel構築していればそのまま紐付けられたと思いますが、すでにDockerで構築してあったので、
なんとかMacに外付けしているHDDで出来ないかと思い試行錯誤しました。
あまり同じ事している人いませんよね。。


結果、、簡単でした。

コンテナイメージをビルドする時に,
docker-compose.ymlファイルにVolumeｓに紐付けるだけでした。
そりゃそうですね（笑）

**docker-compose.yml**
```
services:
  app:
    build:
      context: .
      dockerfile: ./docker/php/Dockerfile
    volumes:
      - ./src/:/var/www/html
      - /Volumes/ADATA HV620:/var/www/html/storage/app/public/HDD ////挿入
    environment:
      - DB_CONNECTION=mysql
      - DB_HOST=db
      - DB_PORT=3306
      - DB_DATABASE=${DB_NAME}
      - DB_USERNAME=${DB_USER}
      - DB_PASSWORD=${DB_PASSWORD}
```

buildし直したらapp/storage/publicに紐づきました！
Bカーブの可変抵抗の入力値を使って擬似的にAカーブのようなデータを取り出す 

## 可変抵抗の種類について
可変抵抗には抵抗値の変化の特性によって、Aカーブ、Bカーブ、Cカーブといった主に3種類のものが存在するようです。
一般的にはAカーブ、Bカーブのものがよく使われるようですが、用途毎に準備しておくのも無駄ですし、Amazon等で安く購入できる物はBカーブのものが多い印象です。

都合によりAカーブのような特性をもたせたかったのですが手元にBカーブの可変抵抗しか持ち合わせていなかったので、計算式を用いて擬似的にAカーブ、それも任意のカーブ具合に調整できないか考えてみました。

## 計算式
#### 前提
RaspberryPi等で、12bitのA-Dコンバータ経由で可変抵抗の値を取得する場合を想定しています。
私の場合はRaspberryPi4Bと[MCP3208-CI/P](https://akizukidenshi.com/catalog/g/gI-00238/ "秋月電気通商")を使用しました。

#### Bカーブの可変抵抗をそのまま使用する場合の計算式

$y＝a\ x$
ここで、$x$は12bitなので0～4095まで変化します。この変化量はBカーブなので、回転角度増加とリニアに連動します。
もし、求める値$y$の範囲を0～100としたい場合は、
$y=x/4095\times100$
とします。
#### yの値をAカーブ的に変化させる場合の計算式
$y=a\ x^n$
このように、$n$乗を追加するだけです。
ただ、これだけでは$n$の値によって求める$y$の範囲が大きく変動してしまいますので、求める値$y$の範囲を0～100としたい場合は
$y= x^n / 4095^n \times 100$
とします。

#### nの値について
上記の式において、$n$の値を変更することによりカーブの具合を調整することができます。
具体的には$n$の値が1に近づくほどBカーブ（直線的）に近くなり、大きくなればなるほどカーブがきつくなります。
下の図のように$n$を2,2.5,3と大きくするにつれてカーブがきつくなるのがわかると思います。
![n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696364/5bf5d34c-a743-ac12-53b6-da31f5d8a6c5.jpeg)

通常のAカーブの可変抵抗を使用する場合と比べ、このカーブの具合を任意で調整できるところが利点かと思います。
## Pythonでの記述例
```python
EXPO = 2.5     #ここの値を修正
SRANGE = 4095  #可変抵抗からの入力最大値
RRANGE = 100   #計算により求める値の最大値

  iv0 = Decimal(str(ここに可変抵抗からの入力値 ** EXPO / SRANGE ** EXPO * RRANGE ))
  i0  = str(iv0.quantize(Decimal('0.1'), rounding=ROUND_HALF_UP)) #四捨五入する桁を指定

```
※私が使用したケースでは最後に文字列として出力したかったため、最終行で文字列に変換しています。
cscの作法 その182

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
湯婆婆を実装せよ。

# サンプルコード

```
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Globalization;

class form1: Form {
	TextBox bo1;
	TextBox bo2;
	public form1() {
		this.Text = "ybb";
		this.ClientSize = new Size(400, 250);
		Button btn1 = new Button();
		btn1.Location = new Point(250, 200);
		btn1.Text = "承諾";
		btn1.Click += btn1_Click;
		Controls.AddRange(new Control[] {
			btn1
		});
		bo1 = new TextBox();
		bo1.Location = new Point(50, 30);
		bo1.Width = 300;
		bo1.Height = 100;
		bo1.Multiline = true;
		bo1.Text += "契約書\r\n";
		bo1.Text += "甲は油屋当主として、乙を油屋に雇用することを契約し、\r\n";
		bo1.Text += "労働に伴う対価の支払いを右の通り、約定する。\r\n";
		bo1.Text += "なお、一日の労働の対価は金百円とする。\r\n";
		bo1.Text += "甲　油屋当主　湯婆婆\r\n";
		bo1.Text += "\r\n";
		bo1.Text += "乙\r\n";
		Controls.AddRange(new Control[] {
			bo1
		});
		bo2 = new TextBox();
		bo2.Location = new Point(150, 130);
		bo2.Width = 100;
		bo2.Height = 30;
		bo2.Text = "吉田恵子";
		Controls.AddRange(new Control[] {
			bo2
		});
	}
	void btn1_Click(object sender, System.EventArgs e) {
		string str = "契約書だよ。そこに名前を書きな。";
		string name = bo2.Text;
		str += String.Format("フン。{0}というのかい。贅沢な名だねぇ。", name);
		Random random = new Random();
		StringInfo nameInfo = new StringInfo(name);
		int newNameIndex = random.Next(nameInfo.LengthInTextElements);
		string newName = nameInfo.SubstringByTextElements(newNameIndex, 1);
		str += String.Format("今からお前の名前は{0}だ。いいかい、{0}だよ。分かったら返事をするんだ、{0}!!", newName);
		MessageBox.Show(str);
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}





```


以上。
Blender 3.2 or later での blendshapes のメモ



## 用語

https://docs.blender.org/manual/en/latest/animation/shape_keys/introduction.html

Blender では Shape keys となっています.

## 作る

![Screenshot from 2022-06-11 18-38-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/70652790-766d-6740-86f2-a11ef56a93f4.png)

`Object mode`(`4` キー)で, 逆三角形のアイコンから Shape keys を追加.

もういっこ追加し, `Edit mode`(`1` キー)で, 頂点を動かしてみる.

![Screenshot from 2022-06-11 18-40-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/1cbcb946-9731-aafb-8b2c-812b0fe427c1.png)

`Object mode` に戻って, weight (Value)を変えると変化します!

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ありがとう Blender blendshapes(Shape Keys)🤟 <a href="https://t.co/ShrQlUe80A">pic.twitter.com/ShrQlUe80A</a></p>&mdash; Syoyo Fujita 🌸 レイトラ ® 🐯 4 周年 🎉 (@syoyo) <a href="https://twitter.com/syoyo/status/1535568905812725760?ref_src=twsrc%5Etfw">June 11, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

Voila!

## in-between blendshape

Maya でいう in-between blendshape は Blender では対応していません.

https://stackoverflow.com/questions/40344004/is-it-possible-to-create-a-shapekey-in-blender-which-has-in-between-targets-lik


Drivers (Maya でいう driven key)で作ることになるでしょう

https://qiita.com/SaitoTsutomu/items/cbcbd43272698c07ebf0
https://3dcg-school.pro/blender-driver/
Laravel 国籍を登録してそれ用のページを作る

Laravel.6においてレシピアプリを開発中です。

国別のユーザーごとのレシピを表示する機能を実装し、苦戦したので自分用にメモします。

前提として、usersにnational_idというカラムを持ちユーザー登録時にプルダウンで国籍が登録されるようにしています。

### ルーティングを定義
```web.php
Route::get('/recipes/{country_key}','RecipeController@country')->name('recipes.country');
```

### Viewにプルダウンを表示
```recipes/index.php
<form class="form-group" method="GET">
        @csrf
    <select type="text" class="form-control" name="national_id"  onChange="location.href=value;">
    @foreach(config('country') as $key => $value )
        <option value="{{ route('recipes.country',['country_key' => $key]) }}">{{ $value }}</option>
    @endforeach
    </select>
    </form>
```

ここでうまいことリンクに飛ばなくて苦戦。。。
aタグは使えてもforeachでうまく回せなさそうだったのでJSのonChangeを使って、optionのvalueをforeachで回してそれをonChangeでとってくるイメージ！

### 国の登録
```config/country.php
<?php 
return array(
  '0' => '未選択',
  '1' => 'アイスランド', 
  '2' => 'アイルランド', 
  '3' => 'アフガニスタン', 
  '4' => 'アメリカ合衆国',
  '5' => 'アラブ首長国連邦', 
  '6' => 'アルゼンチン', 
  '7' => 'イギリス', 
  '8' => 'イスラエル',
  '9' => 'イタリア', 
  '10' => 'イラク', 
  '11' => 'イラン', 
  '12' => 'インド',
,,,以下略（108か国登録）

```
### コントローラーで実装

```RecipeController.php
 public function country(Request $request,$key)
    {   $key = $request->route('country_key');
        $users= User::where('users.national_id','=',$key)->get();
        $user = \Auth::user();
        return view('recipes.country',[
            'title' => '各国のレシピ', 
            'key' => $key,
            'users' => $users,
            'user' => $user,
        ]);
    }
```

$keyを飛んできたrouteからとってきて、userのnational_idと国のidが一致するユーザーを表示する。
そのユーザーのレシピやらレシピの詳細をbladeで表示させる予定。
この辺はとりあえず作ったので今後いじっていく。



### 感想

最初Seederでやろうと頑張ったが、断念。
configの便利さに感動しました。


初心者なのでまだまだ改善点はありそうですが、ひとまず実装できました。


意見、感想、改善点等あればよろしくお願いいたします。
npm run compile:scssでエラー

# 背景
SalesforceのCommerce CloudにStripeを導入する過程（下記①）で、
下記コマンドを打つというものがあったが、ここでエラーにはまった。

```
npm run compile:scss
```


# やったこと
- 当初はNode推奨版のv16.15.1をインストールしていた
- その後v8.11.1にダウングレードして試したもののうまくいかない
- 下記②の記事を参考にし、Nodeのバージョンをv12.16.0にアップグレード
- その上で下記③の記事を参考に、以下の「node_modulesを消す、npmのキャッシュクリア、node_modulesを入れ直す」というnpmのエラーでは鉄板(？)らしい対処法を試した
```
rm -rf node_modules && rm package-lock.json && npm cache clear --force && npm cache clean --force && npm i
```
- その後以下コマンドを再度試したら、うまくいった
```
npm run compile:scss
```

# 参考記事
- ① https://stripe.com/docs/plugins/salesforce-commerce-cloud/implementation-guide
- ② https://developer.commercecloud.com/s/question/0D53k00006e8b6sCAA/npm-run-compilescss-throwing-error
- ③ https://qiita.com/kuroro_ru/items/d50212a1919308cc1480
MacにNode.jsをpkgでインストールしたらbrew doctorで警告が出たので再インストール

# はじめに

MacでNode.jsを使いたくて、[公式ホームページ](https://nodejs.org/ja/)からpkgをダウンロード、インストールしました。その後、`brew doctor`を実行したら、node関連のファイルの影響で警告が出ていたので、homebrewから再インストールしようとやってみました。

# Node.jsのアンインストール

必要に応じて`sudo`で実行してください。

まず始めに、npmのアンインストール。

```bash
sudo npm uninstall --location=global npm
rm -rf .npm
npm -v
```

最後に、「zsh: command not found: npm」と出力されたら成功。

次に、Node.jsのbomファイルから削除対象のファイルを取得して削除。それ以外の関連するファイルも削除。

```bash
lsbom -f -l -s -pf /var/db/receipts/org.nodejs.node.pkg.bom | while read i; do sudo rm /usr/local/${i}; done
rm -rf /usr/local/lib/node
rm -rf /usr/local/lib/node_modules
rm -rf /var/db/receipts/org.nodejs.*
node -v
```

また最後に、「zsh: command not found: npm」と出力されたら成功だったのだけど、私の場合はバージョンが出てしまったので、以下のコマンドで対象のファイルを確認し、削除。

```bash
which node
rm /usr/local/bin/node
```

`yarn`もインストールしていたことを忘れていたので、それも対象のファイルを確認して削除。本当なら、`npm`をアンインストールする前に`npm uninstall --location=global yarn`で消すべきだったと思います。

```bash
which yarn
ls /usr/local/bin/yarn
rm /usr/local/bin/yarn
yarn -v
```

最後に、「zsh: command not found: npm」と出力されたら成功。

再度`brew doctor`を実行したら、`yarn`で入れた覚えのあるファイルが警告で表示されたので、それぞれ`rm`で削除。もう一回`brew doctor`を実行したら警告がなくなりました。

# Node.jsのインストール

色々調べてみたら、[nodebrewやめてVoltaにのりかえてみた](https://o-kun.com/archives/3057/changed-from-nodebrew-to-volta/)というブログを目にして、良さそうだったのでVoltaからインストールしてみました。

```bash
$ brew install volta
$ volta -v
1.0.8
```

さっそくnodeをインストール。

```bash
$ volta install node
success: installed and set node@16.15.1 (with npm@8.11.0) as default
$ node -v
zsh: command not found: node
```

nodeコマンドが使えない！？パスの設定かなと思い、[公式サイト](https://docs.volta.sh/guide/getting-started)を見てみると、やはりパスを追加しなければいけない模様。なので、ホームディレクトリにある.zshrcファイルに以下の記述を追加、ターミナルを再起動したらうまくいきました。

```bash:.zshrc
export VOLTA_HOME="$HOME/.volta"
export PATH="$VOLTA_HOME/bin:$PATH"
```

```bash
$ node -v
v16.15.1
```

これでNode.jsのインストールは完了。`npm`も一緒に入っていました。`yarn`も使いたいので、続けてインストールしてみました。

```bash
$ volta install yarn
success: installed and set yarn@1.22.19 as default
$ yarn -v
1.22.19
```

何も問題なくできました。

プロジェクトごとに`node`や`yarn`のバージョンも指定できるそうなので、ここから先は調べてやってみてください。

```bash
$ volta pin node@16.13.1
success: pinned node@16.13.1 (with npm@8.1.2) in package.json

$ volta pin yarn@1.22.1
success: pinned yarn@1.22.1 in package.json
```

# 参考

<https://www.yurikago-blog.com/posts/27>

<https://docs.volta.sh/guide/getting-started>
MOGAMI 3103 スピーカーケーブルの終端処理 (ONKODO CT-204G 使用)

スピーカーケーブル MOGAMI `3103` の終端処理をメモします。ここではYラグによる終端処理を示します。
なお、Yラグとして ONKODO `CT-204G` を使用した例になっています。

# MOGAMI 3103 終端処理

## MOGAMI 3103 を入手

最初に MOGAMI 3103 を入手します。
メートル単位の切り売りをしているオンラインショップなどを利用することができます。
※私は `CABLECRAFT 音光堂` というオンラインショップから入手しました。


## ニッパおよびケーブルストリッパーの準備

ケーブル終端処理にはニッパおよびケーブルストリッパーなどの器具が必要になります。
私は FUJIYA `770-150` および FUJIYA `FA106` を使用しました。


## Yラグの取り付け

Yラグの準備をします。
小さい六角レンチを準備します。そして ONKODO CT-204G を開封します。

![MOGAMI3103h.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/ee41c76f-5f34-76de-6f2e-c60a8be216cb.jpeg)

## 黒色の外皮を除去

黒色の外皮を剥きます。
緩衝材の白い線は切断します。

内側の赤と黒の銅線ケーブルについて、ケーブルストリッパーなどで銅線の皮を剥きます。

![MOGAMI3103i.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/0dd1c755-e85d-bcd3-da6b-80c7e58ce7b2.jpeg)

Yラグを差し込み、ネジを回して取り付けます。
※この例では、銅線はそのままねじ止め。
※お好みで銅線の終端は軽くハンダ処理などおこないます。 (私はここの処理でハンダなしのほうが好みですが、抜け防止を目的とするためにはハンダ処理が必要とも考えます)


![MOGAMI3103j.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/746c2e40-2a4d-61e9-45bd-743851ec8f0f.jpeg)

今回の例では、反対側はバナナプラグとしました。
バナナプラグには ONKODO BP-146G を使用しています。

![MOGAMI3103a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/435648f7-128a-58c0-2c8e-db6a7c8f5db3.jpeg)

全体像としては以下のようになります。

![MOGAMI3103b.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/2fe36bfc-2e78-a61d-9fcd-7756329a6441.jpeg)

これでケーブルの終端加工は終了です。

# 感想

- ケーブルが重いと感じました。
- 試聴して確認した結果、私は MOGAMI 3103 よりも MOGAMI 3082 のほうが好みの音質でした。(個人の感想です)
- ONKODO `CT-204G` を購入したところ、思っていたのより大きな Yラグだったため、手持ちケーブルの中で最も太い MOGAMI 3103 が余っていたのを有効活用したのをきっかけに記事を記述しました。

# 関連する記事

- [MOGAMI 3082 スピーカーケーブルの終端処理（プッシュ式）](https://qiita.com/igapyon/items/258758cef152dca46873)
- [CANARE 4S8 スピーカーケーブル終端処理 (OYAIDE BP-146G 使用)](https://qiita.com/igapyon/items/272d0e9342aebc980eb5)
- [MOGAMI 3103 スピーカーケーブルの終端処理 (OYAIDE CT-204G 使用)](https://qiita.com/igapyon/items/6ab0ce00a4fd2594c1f2)
- [MOGAMI 3103 スピーカー内部ケーブルの終端処理 (OYAIDE FTL-G、CI-G100 使用)](https://qiita.com/igapyon/items/e202ec2e89485c05ef78)
- [MOGAMI 3104 スピーカーケーブルの終端処理 (ONKODO BP-208BG 使用)](https://qiita.com/igapyon/items/355bdaf5e73ae600cd66)
ECS FargateとElasticBeastalk（Ruby Platform）の比較

昨年、[本番稼働を意識したECS Fargateを用いたFastAPIの環境構築（ALB、SSM、BlueGreenデプロイ）](https://qiita.com/yuyasat/items/04a083a57f5691f1ed3c)という記事を投稿しました。その後、仕事にて実運用でECS Fargateを利用し始め、ある程度感覚がわかってきましたので、以前利用していたElasticBeanstalk（Ruby Platform）との比較を簡単に紹介したいと思います。
仕事では、ECS Fargateは2022年2月末に本番運用を開始しています。また、ElasticBeanstalkに関しては、2017年より仕事で使っています（既にある環境の運用から始まり、新規構築も何度か行いました）。その経験を踏まえて感じたことですので、使用している機能が限定的だったり、詳しい方から見れば容易に改善できる面もあるかと思います。ご教授いただけましたら幸いです。


## 1. デプロイのしやすさ
| | ElasticBeanstalk | ECS Fargate |
|---|---|---|
|良い点|`eb deploy`コマンドを叩けばデプロイできる簡単。|イメージのビルドは事前に済ませているのでデプロイが早い。|
|気になる点|デプロイに時間がかかる。特に.platform(AL2)や.ebextensions(AL)などで処理をたくさんしている場合や、assets:precompileをデプロイ時に行うようにした場合に顕著。|Dockerイメージのビルド、タスク定義の追加、サービスの更新などを行う必要があり煩雑。いろいろな方法が提示されているが、CodePipelineなどで自動化していけばよい。|

## 2. アプリケーションログ
| | ElasticBeanstalk | ECS Fargate |
|---|---|---|
|良い点||CloudWatchとの連携がしやすい。|
|気になる点|どこかのファイルに吐かれたログをkinesis firehoseなどの仕組みを利用してs3などに退避させる必要があり構築が面倒。||

## 3. コスト
- 運用上はそこまで違いはない気がする。

| | ElasticBeanstalk | ECS Fargate |
|---|---|---|
|良い点|||
|気になる点||プライベートサブネットにおくとイメージのpullでNAT費が増大になる。PrivateLink（エンドポイントサービス）を正しく設定する必要がある。|

## 4. メンテナンス性
| | ElasticBeanstalk | ECS Fargate |
|---|---|---|
|良い点|プラットフォームのマイナーバージョンは（設定にもよるが）自動で上げてくれる。|Dockerのイメージは自分たちで管理するので、OSやopensslなどのアップデートなどは自分たちでやらなければいけない。|
|気になる点|プラットフォームバージョンを上げる（AL2移行、RubyやPythonのバージョンアップ）といったときにはサービスを別で作らなければいけない。組織にもよるが弊社の場合はTerraformで管理しておりインフラチームが作業してくれおり、AL2のバージョンアップなどは同じ時期にくるのでインフラチームの負担が一時的に増大する。|RubyやOSDockerのイメージを更新するだけでよい。弊社の場合はDockerfileはアプリエンジニアが修正するのでインフラチームに頼る必要がなくなり気軽に上げやすい。|

## 5. 構築のしやすさ
| | ElasticBeanstalk | ECS Fargate |
|---|---|---|
|良い点|nginxなども含まれているので簡単にできる。|Dockerに慣れていれば容易い。|
|気になる点|カスタマイズしていこうと思うとElasticBeanstalkのプラットフォームの独特の挙動に悩まされることがある。|良くも悪くもDockerに慣れ親しんでいるかどうかで変わる。Fargate特有の設定もある。|

他にもあると思いますが、思いついたタイミングで随時更新していければと思います。
見えるけど見えないもの。それは「メンバ関数の第一引数」さ


# 結論
C++のメンバ関数の第一引数は、そのインスタンスのアドレスです。  
static関数はメンバ変数を使用する必要がないため、例外です。

以下は解説と茶番です。

# C++のメンバ関数をスレッド実行したかった
std::thread、_beginthread、CreateThreadと色々あるが、今日は気分でCreateThreadをチョイス。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595099/c774955b-a865-1b25-36af-d3c9d7d3799a.png)

書いてみたら何やらエラーが。エラー内容は以下
```
型 "DWORD (__stdcall hoge::*)(LPVOID pParam)" の引数は型 "LPTHREAD_START_ROUTINE" のパラメータと互換性がありません
```
「なるほど、スレッド化したい関数と型が違うとな。ちゃんと定義を確認しに行こう」
```cpp:minwinbase.h
typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)(
    LPVOID lpThreadParameter
    );
typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE;
```

|戻り値|呼び出し規約|引数
|---|---|---|
|DWORD  |WINAPI |LPVOID一つ |

「合っとるやんけ。何で使えないんや。」
# メンバ変数の第一引数はインスタンスのアドレスなのです
論より証拠ということで、実際のソースコードと生成されたアセンブラを見てみましょう。
```:元のソースコード
int main()
{
	hoge instance;

	instance.hugaThread(NULL);

	return 0;
}
```
```:生成されたアセンブラ
	hoge instance;
00007FF7B6CA19AD  lea         rcx,[instance]  
00007FF7B6CA19B1  call        hoge::hoge (07FF7B6CA100Fh)  
00007FF7B6CA19B6  nop  

	instance.hugaThread(NULL);
00007FF7B6CA19B7  xor         edx,edx  
00007FF7B6CA19B9  lea         rcx,[instance]  
00007FF7B6CA19BD  call        hoge::hugaThread (07FF7B6CA137Fh)
```
Windows10 VisualStudio2022 x64でビルドしたものです。  
このアセンブラから、以下の処理が確認できます。
* `instance`の宣言をしたところで、コンストラクタを呼び出している
* edx(rdx)レジスタを0クリア、つまりNULLを格納している
* `instance`のアドレスをrcxレジスタに格納している  

MSのx64環境では一般的に第一引数から順にrcx、rdx、r8、r9に格納されます。詳細はこちらを御覧ください。  
[x64 での呼び出し規則](https://docs.microsoft.com/ja-jp/cpp/build/x64-calling-convention)  

よって、スレッド化しようとしたメンバ変数の方は本当は以下のようになっているのです。

```
DWORD WINAPI hoge::hugaThread(hoge* myself, PVOID pParam);
```
内部的にこうしてくれているおかげで、メンバ関数内で、インスタンスのメンバ変数にアクセスできているわけですね。  
C言語では構造体を作って各関数に渡してステータスを変更/参照するといったことになりますが、内部的にはそれをやっているのと大して変わりはないわけです。  

これの仕組みが理解できれば、冒頭で書いた通り、staticのメンバ関数であればCreateThreadに渡す事ができる理屈を察する事ができると思います。

# C++のメンバ関数をスレッド実行する
本記事ではメインの話題ではありませんが、こういった所で躓く人もいらっしゃると思うので、他の方の記事のリンクを貼り付けておきます。

https://kakashibata.hatenablog.jp/entry/2019/09/29/210359
https://qiita.com/tsuru3/items/c3e706ed77912f809cd2
https://stackoverflow.com/questions/1372967/how-do-you-use-createthread-for-functions-which-are-class-members

## おわり
以上、お読みいただきありがとうございました。
全然遊戯王ネタ入れるところなかった。
DB未経験ながらORACLE MASTER Silver DBA 2019を取得しました

ORACLE MASTER Silver DBA 2019を取得してきました。(得点率90%ほど)
この試験、情報が少なく困っていたので、これから受験する方の参考になればと思い、記録を残したいと思います。

# 受験理由・感想
今後の仕事でOracleデータベースを扱うので、会社に「取っておいで」と言われたのが理由です。
毎日の業務時間の半分は勉強させて頂いたと思います。

データベースに触れたことがない身として、Oracleはいろいろなシステムがあって理解が大変でした。
どう動いているのか体系的に掴めたので、受けて良かったなと思います。

# 勉強時間・方法
150時間ほど(推測)。
配分はこんな感じ(以下)。
|項目|(時間)|
|---|---|
|黒本|100|
|ping-t(DBA)|35|
|ping-t(SQL)|5|
|その他|10|

## 黒本
![オラクルマスター教科書 Silver DBA Oracle Database Administration I](https://m.media-amazon.com/images/P/B0919PVHTD.01._SCLZZZZZZZ_SX500_.jpg "オラクルマスター教科書 Silver DBA Oracle Database Administration I")
[オラクルマスター教科書 Silver DBA Oracle Database Administration I](https://www.amazon.co.jp/dp/4798166359 "オラクルマスター教科書 Silver DBA Oracle Database Administration I")
これ完璧にすれば受かると思います。

ただ、Oracleが初めてだととっつきにくいものが多かったので、「[絵で見てわかるOracleの仕組み](https://www.amazon.co.jp/dp/4798157694 "絵で見てわかるOracleの仕組み 新装版")」を一通り読んでから始めました。
私は昔の版を読みましたが、新装版があるようですね。概要をつかむ目的であれば、どちらでも大丈夫そう。

あとは、 **黒本読む→各章の練習問題解く** の繰り返しで、8割9割解けるように。
並行してping-tのBronze DBAをやると、知識が定着しやすかったです。

模試は1回分しかないので、最後に取っておきました。
ちなみに私の場合、模試の得点率は70%くらい(本試験近かったので結構焦った)。
試験自体の合格ラインが60%とゆるめなので、模試で危なげでも苦手分野補強すれば合格できると思います。

## ping-t
ping-tの12c Bronze DBAの問題を、9割がた覚えるまで解いてました。
Silver DBA 2019は半分近くSQLの問題なので、同じくping-tの12c Bronze SQLも解くと良いらしいです。
私は~~面倒で~~時間無くて少ししかやりませんでしたが、おかげでSQL文の苦手分野がわかるようになったので、わけわからん項目がある人は、そこだけでもやっておくのがおすすめです。

**追記**
**ping-tにSilver SQLが追加されたようです。**
**Silver DBAと試験範囲もろ被りの問題で、しかも完全無料なので、とりあえずやってみてはいかがでしょうか！**

## その他
ちょうど、Oracle主催の「SilverDBA 傾向と対策セミナー」(無料)があったので、業務時間内ですが参加させてもらいました。
各分野のポイント解説や、沢山の練習問題が配布され、受験直前の復習に有り難すぎました。

全体の復習にちょうど良い内容だったので、タイミングが合えば参加することをお勧めします。
(私が情報を見つけたのは、ping-tのトップページにある「最新ニュース(その他)」の欄でした。
公式だと、[新着ニュース | Oracle University](https://www.oracle.com/jp/education/news-172121-ja.html "新着ニュース | Oracle University")で確認できるみたいです)

あと、このセミナーで教えていただいた「[資格試験準備セミナー](https://learn.oracle.com/ols/course/oracle-master-silver-dba-2019-certification-exam-prep-seminar-oracle-master-silver-dba-jp/84763/76958/91254 "資格試験準備セミナー")」がめちゃくちゃ役に立ちました。
※期間限定無料だったようで、普段は有料
点数20%くらいはこのセミナーで盛れたので、無料公開分までか、オール無料のときは一通りやっておくと良いと思います。

# おわりに
Silver DBA 2019は情報が少なく、簡単な資格でもないので、合格を目指すのは大変だと思います。
ただ、終わってみると、しっかりやってきた実感があって自信に繋がりますし、よくわからなかったOracleとも仲良くなれそうです。
これから受験する方の合格を心から祈っています！
ML_Agentでうまくいかなかったことまとめ

# まえがき

この記事は下記サイトを参考にUnityで強化学習を行った際に吐かれたエラーをまとめたもので個人的な覚え書きです。
参考サイト

https://note.com/npaka/n/ndd679aa343ea

環境
windows11
Unity20203.30f
ml-agents-release_19

# 目次

[1.起こった問題その1：mlagents-learnが実行できない](#起こった問題その1-mlagents-learnが実行できない)
[2.起こった問題その2：yamlが読まれない](#起こった問題その2-yamlが読まれない)
[3.起こった問題その3：Unityの実行を押しても動作しない](#起こった問題その3-unityの実行を押しても動作しない)

# 起こった問題その1 mlagents-learnが実行できない

[参考サイト](https://note.com/npaka/n/ndd679aa343ea)の手順7-(2)で

```言語:コマンド
mlagents-learn ./config/RollerBall.yaml --run-id=RollerBall-ppo-1
```
を実行したところ
「`mlagents-learn : 用語 'mlagents-learn' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。`」
というエラーが吐かれました。
つまりmlagents-learnなんてコマンドないよって話ですね。

## 解決策

[参考サイト](https://note.com/npaka/n/ndd679aa343ea)の通りにwindows storeのpythonを使用していましたが[Unity ML-Agents実践ゲームプログラミング](https://www.amazon.co.jp/dp/B08JBFXFQ9/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)ではAnacondaを使用していたのでAnacondaでやったところうまく作動しました。

>注意点
windows storeのpythonはpowershellでコマンドを実行しますが、anacondaのcondaコマンドはAnaconda Powershell Prompt (anaconda3)でないと作動しないので注意してください。(１敗)

# 起こった問題その2 yamlが読まれない

アナコンダで仮想環境を作り下記のコマンドを実行してみました。
```言語:コマンド
mlagents-learn ./config/RollerBall.yaml --run-id=RollerBall-ppo-1
```
すると「`mlagents.trainers.exception.TrainerConfigError: There was an error decoding Config file from ./config/RollerBall.yaml. Make sure your file is save using UTF-8`」と吐かれました。
簡単に訳すと「RollerBall.yaml読めないんだけどちゃんとUTF-8で書いてる？」ってことです。もちろんUTF-8で書いてますし、コードは[参考サイト](https://note.com/npaka/n/ndd679aa343ea)をコピペしたものなのでどっか書き間違えがあって読めないとかではないです。ですが読めないといわれてます。なんでや

エラー文で検索をかけてみると同じ悩みを抱えている方がいました。

https://teratail.com/questions/328742

この方はML-Agentsのバージョンを上げると解決したようですが、2022/6/11の時点で最新のrelease_19を使っているので同じ方法は取れませんでした。

## 解決策

config\ppoファイル内にはサンプルのシーン用の強化学習設定ファイルが転がっています。
>path
ml-agents-release_19\config\ppo

こちらのファイルにある3DBall.yamlを指定してmlagents-learnコマンドを実行したところうまく動作しました。こちらの設定ファイルはちゃんと読んでくれるようです。（当たり前ですが）
なので3DBall.yamlをコピーしRollerBall2.yamlと名前を変え、中身の数値を[参考サイト](https://note.com/npaka/n/ndd679aa343ea)のRollerBall.yamlに置き換えを行いました。するとうまく動作し、Unityのロゴが出てきました。

# 起こった問題その3 Unityの実行を押しても動作しない

うまくmlagents-learnが作動し、Unityのロゴが出てきたためUnityの実行ボタンを押したところ
「`mlagents.trainers.exception.TrainerConfigError: The behavior name Roll_Ball has not been specified in the trainer configuration. Please add an entry in the configuration file for Roll_Ball, or set default_settings.`」と吐かれました。
つまりRoll_Ballなんてないぞってことですね。Roll_Ballってどっから出てきた？

# 解決策

エラー文で検索をかけたところ同じ同じ悩みを抱えている方がいました。

https://teratail.com/questions/375312

この方の自己解決によると、yamlの2行目をBrainの名前と一致させたらできるようになるとのことです。つまりUnityでRollerAgentにコンポーネントしたBehavior Parametersの名前がyamlと一致してないのが原因のようでした。自身のプロジェクトをのぞいてみるとBehavior　NameがRoll_Ballになってました。

### あとがき
以上が自分が吐かれたエラーのまとめです。誰かの助けとなれば幸いです。
catに色をつけたい

これでよし
```sh
$ brew install bat
$ alias cat='bat -pP' # .zshrcなどに書いておく
```
https://github.com/sharkdp/bat

batは便利だけど手が勝手にcatを入力するからaliasにした

`-pP`のオプションを付けると、行番号の表示やページングがオフになる
これをしてないとcatの結果をパイプで渡した時などに想定外の挙動をするから
Oracleの識別子のサイズ・使える文字制限のメモ

# データベース オブジェクトの識別子の上限サイズ
|データベースオブジェクトの識別子|12.2以後|12.2未満|
|-|-|-|
|データベース名|8バイト|8バイト|
|ディスク・グループ<br/>プラガブル・データベース(PDB)<br/>ロールバック・セグメント<br/>表領域および表領域セット|30バイト|30バイト|
|識別子にピリオドで区切られた複数の部分が含まれる場合、各属性の長さ|128バイト|30バイト|
|データベース・リンクの名前|128バイト|128バイト|
|その他|128バイト|30バイト|

# 非引用識別子と引用識別子の使える文字の制限
|識別子の種類|データベースオブジェクト|文字制限|開始文字制限|使える単語の制限|禁止文字|
|-|-|-|-|-|-|
|非引用識別子|データベース・リンク以外|英数字<br/>下線(_)<br/>ドル($)<br/>シャープ(#)|アルファベット|Oracle SQLの予約語は使用不可|二重引用符<br/>null文字(\0)|
|非引用識別子|データベース・リンク|英数字<br/>下線(_)<br/>ドル($)<br/>シャープ(#)<br/>**ピリオド(.)<br/>アットマーク(@)**|アルファベット|Oracle SQLの予約語は使用不可|二重引用符<br/>null文字(\0)|
|引用識別子|-|-|全て|大文字のROWIDは列名に使用不可|二重引用符<br/>null文字(\0)|

## 補足
引用識別子はダブルクォートで囲う名前。
非引用識別子はそれ以外の名前。

# 参考
[SQL言語リファレンス-データベース・オブジェクト名および修飾子-Oracle Help Center](https://docs.oracle.com/cd/F39414_01/sqlrf/Database-Object-Names-and-Qualifiers.html#GUID-3C59E44A-5140-4BCA-B9E1-3039C8050C49)
「ネットワーク超入門　手を動かしながら学ぶIPネットワーク」環境構築メモ

## はじめに
「ネットワーク超入門　手を動かしながら学ぶIPネットワーク」を購入してみたものの、
環境構築ちょっと引っかかったので、同じく初心者のためにメモ。
まだ読了していないので、なにかあったら書き足すかも。

本：ネットワーク超入門　手を動かしながら学ぶIPネットワーク（技術評論社）

## 環境
MacOS Monterey v12.3.1

## ソフトのダウンロード
本書での推奨ソフトは以下の２つ。
* GNS3
* Cisco Packet Tracer
どちらもソフトウェアのダウンロードには登録が必要（どちらも登録無料）

## GNS3
IOSイメージファイルなるものが必要だが、IOSイメージファイルは自身で用意する必要がある。
IOSイメージファイルの取得法は作者のブログに記載があるが、別途**有線で**ルーターとの接続が必要。
今回、有線でルーターと接続できる準備がなかったために割愛。

## Cisco Packet Tracer
以下著者のブログにダウンロード法が書かれている
https://www.n-study.com/cisco-packet-tracer/install-guide/

ただし、少しサイトが変わっていたので、インストール方法までのメモ。
1. Cisco Networking Academyの"Getting Started with Cisco Packet Tracer"のページ
https://skillsforall.com/course/getting-started-cisco-packet-tracer
ここで、ログインを行う（Googleアカウント可）

2. 上記コースのGet Startedからコース登録。（受講無料）
（日本語はないので英語で）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322185/c21799a3-f38d-bc7c-c8b8-f90f78cdfe5c.png)

3. Module1：Download and Use Cisco Packet Tracerへすすむ
（Safariは非対象ブラウザなので注意。Vivaldiで動いたので、Chromeは大丈夫そうかな？）

4. スクロールダウンすると、ダウンロードリンクが現れるので、クリックしてダウンロード。

5. インストーラに従ってインストールをすすめる。

6. Cisco Packet Tracerをアプリケーション一覧より起動。
初めての起動時、Ciscoのアカウントに関しての選択画面が表示されるので、
"Cisco Skills For All"を選択。画面遷移ののち、アプリが使用可能になる。
WIP : AndroidでMotionLayoutを使う時の注意点()


結論
1. setTransitionListener()に設定するTransitionListenerの`onTransitionCompleted()`が発動されないこともある
他の
`onTransitionStarted()`
`onTransitionChange()`
`onTransitionTrigger()`
でも同じく発動されない可能性があると思っておくと安心。

2. MotionLayoutの配下の要素に`.animate()`でViewPropertyAnimatorを適用してそのアニメーションが終わると
MotionLayoutのTransitionが中断される。
回避策としてViewPropertyAnimatorに`.setListener()`で元々実行中だったTransitionを改めて実行させる処理を
`onAnimationEnd()`に入れたリスナーを設定してあげると最後までTransitionが行われる。
【UiPath】2文字以上の空白を含む文字列から、空白以外の文字列に分割したい

<h2>2文字以上の空白を含む文字列</h2>

UiPathでの文字列操作は専用のアクティビティを使うケースもあれば、VBのコードを使うこともある。私が特定の文字列を分割しようとしたがうまくいかなかった。例えば以下のような例

```
"名前    身長 体重   備考   "
```

これを各文字列ごとに分割したい
```
"名前" "身長" "体重" "備考"
```
<h2>よくあるアプローチ</h2>

```vb:trim
str.trim
```


str.trimを使うと前後の空白は除くことができるが中間の空白は省くことができない。

```
"名前    身長 体重   備考"
```

```vb:split
str.split(" ")
```
str.split(" ")を使うと途中の空白も分割されてしまう。

```
"名前" " " " " "身長" "体重" " " "備考"
```

<h2>実装例</h2>
いろいろ調べたがよい方法が見つからなかったのでロジックを組んだ

![contain.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707463/3f2c09ca-b50c-c5a1-f6a2-9804f1314140.png)


まずは空白が2文字つづくケースが存在するか判定する
```
str.Contains("  ")
```


空白が2文字を続く文字列を空白1文字に変換する

```
str.Replace("  ", " ")
```

```
"名前 身長 体重 備考 "
```

これをこれを行えば連続する空白を1文字の空白に変えることができた。
終わってみれば簡単だったが、2時間くらい調べてしまった。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707463/30a7f183-b97d-f58b-47ff-ff81658b564c.png)


この後によく使うSplitを入れ込むことで文字列を分割できる。

```vb :
item.Split(CChar(" "))
```

```
"名前" "身長" "体重" "備考"
```
もし、コードで一発で出来るような方法があれば是非おしえてください。
【Python】print文で、変数を使って文字列を作ったり、文字列に変数を埋め込んだりする方法をいつも調べちゃうのでまとめてみた

# 0. はじめに
動機はタイトルの通り。
システムのログなどで「変数を文章の中に入れて出力したい」みたいな場面は皆様も日常茶飯事かと思います。
が、いくつかの言語をやっているとそれぞれ微妙に文法が違うので、「あれっpythonだとどれでできるんだっけ…？」「javascriptだとこうじゃないんだっけ…？」みたいに僕はいつも混乱しています。
ということで、直近でよく使っているPythonからメモ代わりにまとめてみます。
まだ知らない方法、他言語でのまとめもあれば、今後追加するかも知れません。

# 1. `+`で頑張って連結（連結演算子）
言わずと知れた基本文法。
`文字列 + 文字列`のように書くと、文字列を連結できる。
ただし、javascriptとかでは`文字列 + 数字`としても数字を自動で文字列化してくれるのでエラーにならないけど、pythonではエラーになるので必ず数字は`str()`で文字列化することに注意。
```python:python
str1 = "数字："
value1 = 1

print(str1 + str(value1))
# 出力 >> "数字：1"
```

短所としては、これだと`+`がいっぱい出てきて無駄に長くなったり、数字を`str()`し忘れたりしてちょっと大変。

# 2. フォーマット済み文字列リテラル
これにはいくつかの書き方がある。

## `f" "`を使う方法（f文字列）
個人的にはこれが一番好き。
`f" "`の中で、変数を埋め込みたい箇所は`{変数}`として直接書き込む方法。
```python:python
value1 = 1
value2 = 2
str = f"数字1つ目：{value1}、数字2つ目:{value2}"
print(str)
# 出力 >> 数字1つ目：1、数字2つ目:2

# 出力だけならもちろんこれもOK
print(f"数字1つ目：{value1}、数字2つ目:{value2}")
# 出力 >> 数字1つ目：1、数字2つ目:2
```
変数を埋めたいところに直接書き込む形なので直感的に分かりやすいのと、数字も`str()`をしなくて済むので簡便。
ただし、これも埋め込みが多いと全体が少しごちゃっとなる可能性はあるので、この辺は好みですかね。

ちなみにjavascriptでは、
```javascript:javascript
let value = 1;
console.log(`数字1つ目：${value}`);
// 出力 >> 数字1つ目：1
```
のように、シングルクォーテーションやダブルクォーテーションではなくバックティック（キーボードだと`shift + @`）で囲み、変数を埋め込みたい部分はドルマーク付きで`${変数}`とします。
現在は業務でよくpythonとjavascriptを使っているので、このあたりでいつも混乱していました笑

## `.format()`を使う方法（formatメソッド）
変数を埋め込みたい部分を`{}`としておき、その後に`.format()`として順番に変数を書き込んでいく方法。
```python:python
value1 = 1
value2 = 2
str = "数字1つ目：{}、数字2つ目:{}".format(value1, value2)
print(str)
# 出力 >> 数字1つ目：1、数字2つ目:2
```
ただし、ちょっとした短所としては、
1. `format()`の中は順番通りにしないと思い通りの出力ができないので、やや間違えやすい。
2. もし複数個所に同じ文字列を埋め込みたい（あんまりない気もするが）場合でも、全て順番通りに列挙する必要がある。

あたりが挙げられそう。
そこで、以下のように`{仮の変数名}`で書いておき、`format()`の中でバインドさせた方が、確実性や可読性が高いかも知れない。
```python:python
value1 = 1
value2 = 2
str = "数字1つ目：{first}、数字2つ目:{second}".format(first=value1, second=value2)
print(str)
# 出力 >> "数字1つ目：1、数字2つ目:2
```
これなら、同じ文字列を複数個所に埋め込みたい（あんまりない気もするが）場合も、`format()`の中身が比較的すっきりする。

# 3. `%`を使う方法（書式指定子、書式化演算子）
書き方的には`.format()`と似ている。
変数を埋め込みたい部分を、その変数の変換型に合わせて`%s`や`%d`など（書式指定子`%`）として仮置きしておき、その後に書式化演算子`%`で順番に変数を列挙する方法。
ちょっと言葉では分かりづらいので例。
```python
str1 = "数字1つ目"
value1 = 1
str = "%s：%d" % (str1 , value1)
# 出力 >> 数字1つ目：1
```
ここでは、`str1`を文字列`%s`、`value1`を符号付き10進整数`%d`として埋め込んでいる。
こうした変換型については、下記Qiita記事や公式ドキュメントを参照されたい。
[Pythonの%演算子による文字列フォーマット](https://qiita.com/takahiro_itazuri/items/e585b46d096036bc837f)
が、現在ではこれまでに挙げてきた他の方法があり、本方法はあまり推奨されていないとのこと。

# まとめ
いくつかの方法を知っておくことで、その時々で分かりやすいコードが書けそうだし、他の言語と混乱することもあるけど逆に他言語を勉強するときの役にも立ちそう。

[参考文献・記事]
* [Pythonの%演算子による文字列フォーマット](https://qiita.com/takahiro_itazuri/items/e585b46d096036bc837f)
PHP SESSION セッションハイジャック対策　ハッシュ化

# 初めに
自身の備忘録として記述いたします。
一つの方法として見ていただければと思います.
重要な情報を扱う際は、更なる対策が必要になると思いますので、ご注意ください。

# セッションハイジャックとは？
攻撃者がログイン中の利用者のセッションIDを不正に取得し、セッションを乗っ取る攻撃手法。
この攻撃手法では利用者のIDやパスワードを知ることなく、アカウントの乗っ取りが可能となってしまう。
## 対策1 パスワードのハッシュ化
### １：パスワードをハッシュ化する
``password_hash()``を使うことで、簡単にハッシュ化ができます。
```
$hash_password = password_hash("パスワード", PASSWORD_DEFAULT);
```
### 2:ハッシュ化されたパスワードと、入力されたパスワードの比較
```password_verify```を利用することで、
「ハッシュ化されたパスワード」と「ハッシュ化されていないパスワード」が**同一のものか**を判断し、``true``か``false``で返してくれます。
```
//左側の引数が「ハッシュ化前」、右側が「ハッシュ化後」
password_verify($password, $hash_password); 
```

## 対策2 セッションIDを遷移時に変更
ページが遷移する度に、セッションIDを変更します。
``session_regenerate_id``を利用する事で、セッションIDの変更が可能です。

``chk_ssid　``にはセッションIDが格納されている前提です。

```
function sschk(){
  //セッションIDの確認
  if(!isset($_SESSION["chk_ssid"]) || $_SESSION["chk_ssid"]!=session_id()){
      exit("Login Error");
  }else{
    //画面遷移するたびに、idを変える
      session_regenerate_id(true); //ここでセッションidを変更
      $_SESSION["chk_ssid"] = session_id();　//変更後のセッションIDを代入
  }
}
```

# 終わりに
もし認識違い等あれが、ご教授いただけると幸いです。

Twitter
https://mobile.twitter.com/tatsuki_kt
Typescriptでnpm startしても上手くいかない

- Typescriptの学習時にnpm startでサーバーを起動させ、動作確認した時に起きたので自身の備忘目的で残してみる。
- npm startでサーバーを起動させる。
- `ERROR in ./src/hooks/use_state_with_storage.ts 3:40
Module parse failed: Unexpected token (3:40)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders`
というエラーが出てきた。
- 最初は./src/hooks/use_state_with_storage.tsでタイポがあるかと思い見直したが特にない。
- もう一度エラーを見返し`You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.`というところが気になる。
- 翻訳すると、**このファイル形式を扱うには適切なローダーが必要かもしれません。現在、このファイルを処理するローダーは設定されていません**という意味になる。
- ならばと **webpack.config.js** のファイルを見返すとここの`test: /\.tsx$/,`の設定が少し足りていなかったことが発覚した。
![スクリーンショット 2022-06-11 17.10.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641460/b40b0fce-4836-294a-ba8d-033cd574c1bd.png)

- `test: /\.tsx$/,`を`test: /\.tsx?$/,`としたら解決した。

備忘として残してみた。
MA, AR, ARMA, ARIMAの関係についての備忘（時系列データ）

# MAモデルとは
- MAモデル＝Movement Averageモデル（移動平均モデル）
- $y_t = ε_t + θ_1ε_{t-1}$で表される
- 一時点前は、$y_{t-1} = ε_{t-1} + θ_1ε_{t-2}$となり、$ε_{t-1}$の部分（誤差）で自己相関を持つ
　⇒ 過去の誤差に影響されるモデル
- 直前の$q$個の値の誤差に影響を受けるモデルを$M(q)$と記載
    - $MA(1)$
        - $y_t = μ + ε_t + θ_1ε_{t-1}$
        - $y_{t-1} = μ + ε_{t-1} + θ_1ε_{t-2}$
    - $MA(2)$
        - $y_t = μ + ε_t + θ_1ε_{t-1} + θ_2ε_{t-2}$
        - $y_{t-1} = μ + ε_{t-1} + θ_1ε_{t-2} + θ_2ε_{t-3}$
    - $MA(q)$モデルでは、$y_t$と$y_{t-1}$との間に$q$個の共通部分を持つ = ***$q$期前までは自己相関を持ち、$q+1$期以降とは自己相関を持たない***
# ARモデルとは
- ARモデル＝Autoregressiveモデル（自己回帰モデル）
- $y_t = c + φ_1y_{t-1} + ε_t$
    - $y_t$が$y_{t-1}$で表現される = 自己相関がある
- 直前の$p$個の値から次の値を予測するモデルを$AR(p)$と記載
# ARMAモデルとは
- MAモデルとARモデルは互いに競合しないため、これらを組み合わせ、次のように表す
    - $AR(p)$と$MA(q)$を表したARMAモデル：$ARMA(p,q)$
# ARIMAモデルとは
- ARIMAモデル = Autoregressive Integrated Moving Averageモデル（自己回帰和分移動平均モデル）
- 原系列を階差数列へ変換し、ARMAモデルへ適応したもの
- ARMAモデルは定常過程（時間によって確率分布（平均や分散）が変化しない確率過程のデータ）にしか適応できないが、ARIMAモデルは非定常過程にも適応可能
- $d$時点前との差分をとった場合の$ARMA(p,q)$モデルから構築されたARIMAモデルは、$ARIMA(p,d,q)$と表される
    - $p$: 自己相関度
    - $d$: 誘導
    - $q$: 移動平均
BottomNavigationViewの戻る処理について

Android JetpackのNavigationコンポーネントを利用。
（確認したバージョンは、 2.4.2）

`NavigationBarView.setupWithNavController` を利用した場合の、タブ遷移後の戻るボタンの処理について確認した。

`android:menuCategory="secondary"` の有無によって、動作が違う。

![Screenshot_20220611_165007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8708/2ac80358-eb92-3b84-34b3-ebfe5b615a7d.png)

例： Home -> Dashboard -> Notifications -> Dashboard と操作したあとに、back keyを押したとき。

## パターンA: menuCategory="secondary" を指定した場合

```xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/home"
        android:icon="@drawable/ic_home_black_24dp"
        android:menuCategory="secondary"
        android:title="@string/title_home" />

    <item
        android:id="@+id/dashboard"
        android:icon="@drawable/ic_dashboard_black_24dp"
        android:menuCategory="secondary"
        android:title="@string/title_dashboard" />

    <item
        android:id="@+id/notifications"
        android:icon="@drawable/ic_notifications_black_24dp"
        android:menuCategory="secondary"
        android:title="@string/title_notifications" />
</menu>
```

Dashboard から、
-> Notifications -> Dashboard -> Home
のように、順番に戻っていく。
（stackがすべて積まれている状態）

## パターンB: 未指定

上記のそれぞれの `item` から、 `android:menuCategory="secondary"` を削除した場合。

Dashboard から、
-> Home
のように、起動直後の初期タブに戻るのみ。
（stackを破棄しながら遷移しているイメージ）
Next.jsのImage Optimizasionsのあれこれ

### __公式のドキュメントからImage Componentが何を出来るのか調べたメモ。__

# Next.js includes many image optimizations
- __Next.jsのImage Componentは画像を表示させるための最適化をおこなっている__
  - 最適化: いろいろな工夫くらいの認識

- Image Componentは`<img/>`を拡張しており、パフォーマンス(ここでは画像の読み込みなど.)の改善を


# Image Componentが行う最適化
- __Improved Performance__: 各デバイスに対応した画像サイズの提供
- __Visual Stability__: 可視的な安定性(ここまだわかってないから詳しく調べる)
- __Faster Page Loads__: viewportに入った時だけ画像が読み込まれ、それまではblur-upプレイスホルダーが表示される
- __Asset Flexibility:__: オンデマンドで画像をリサイズすることが可能

[オンデマンド](https://it-trend.jp/words/ondemand)


### 1. ローカルの画像(Local image)
ローカルの画像を利用する際はimport文を使用して、拡張子`.jpg`,`.png`,`.webp`を利用する。
import文(画像ファイルをインポートする)を利用することで、Next.jsは画像の`width`、`height`を自動的に決めてくれる。

```typescript
import hogePic from '../public/hoge.png'
```

:::note alert
__注意__
- Dynamic await import() と require() はサポートしていない
:::

### 2. リモートの画像(Remote images)
:::note alert
__注意__
- ビルド時にリモートのファイルにアクセスすることがない
  - そのため、width, height とoptionalでblurDataURLの指定が必要
:::

### 3.ドメイン(Domains)

:::note warn
これよくわからなかった
https://nextjs.org/docs/basic-features/image-optimization#domains
:::

### 4.ローダー(Loaders)

`myLoader`で複数のURLを作成して、生成したURLは`srcset`の自動生成に利用される

> ```typescript: 公式のコードを引用
>import Image from 'next/image'
>
>const myLoader = ({ src, width, quality }) => {
> // qualityはdefaultで75
>  return `https://hoge.com/${src}?w=${width}&q=${quality || 75}`
>}
>
>const MyImage = (props) => {
>  return (
>    <Image
>      loader={myLoader}
>      src="myhoge.png"
>      alt=""
>      width={500}
>      height={500}
>    />
>  )
>}
>```

### CDNや画像用のサーバーから画像を取得する場合→ [Build in Loader](https://nextjs.org/docs/api-reference/next/image#built-in-loaders)を利用する(自前でmyloaderのように書かないようにするため)

#### [srcsetについて(Qiita記事)](https://qiita.com/dowanna6/items/b9e132b4c56e67491027)
> srcset : 画像URLを複数保持しておいて、デバイスの幅に応じて最適化された画像を表示させる
>[「ピクセル数足りてるかな」と考えるプロセス](https://qiita.com/dowanna6/items/b9e132b4c56e67491027#%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%AF%E8%87%AA%E5%88%86%E3%81%AE%E7%94%BB%E9%9D%A2%E5%B9%85%E3%81%A8%E7%94%BB%E5%83%8F%E5%B9%85%E3%82%92%E6%AF%94%E8%BC%83%E3%81%99%E3%82%8B)


### 5.優先順位(Priority)
priorityをtrueにすることでdefaultのlazy loadを無効にすることができる。
LCP(Largest Contentful Paint)を向上させることができる
> When true, the image will be considered high priority and preload. Lazy loading is automatically disabled for images using priority.
[参考](https://nextjs.org/docs/api-reference/next/image#priority)


## 参考
https://nextjs.org/docs/basic-features/image-optimization

https://networkteam.com/journal/2021/lazy-and-eager-images-with-nextjs
PHP SESSION（セッション)基礎

# 初めに
PHPでセッションを利用する為の基礎的な部分をまとめています。
# SESSION（セッション）とは？
セッションとは、**サーバー側にデータ(変数)を保存する仕組み**のこと。
セッションを利用する事で、ページ遷移の際に、**データ(変数)を送受信しなくても、他ページで利用可能**になる!(めちゃ便利。。。。)

分かりやすい利用シーンだと、ECサイトのカート機能等に使われています!
# ◎SESSION（セッション）の使い方
思ったより簡単に使えます!
## １：セッション管理の開始
``session_start()``でセッション管理を開始します。
ユーザーごとに「セッションID」が割り当てられ、「クッキー」からその値にアクセスできるようになります。
```
<?php
    session_start();
```
## ２：SESSION変数に値を代入
◇書式:
```
$_SESSION["変数名"]="代入する値";
```
◇例:
``session_id()``を使う事で、個々に割り当てられた、セッションIDの取得が可能。
```
$_SESSION["name"]="テストユーザー";
$_SESSION["age"]=24;

//セッションIDの取得
$sid = session_id();
```
## ３：SESSION変数の取得　取り出し
```
echo $_SESSION["name"];
?>
//出力結果　：　　　テストユーザー
```

## ４：セッション管理終了
セッションファイルは、通常ブラウザを閉じると削除され、セッションは破棄されます。
破棄を動的に行いたい場合の手順です。

### ①：セッションの初期化
$_SESSION に空の配列を代入することで、セッションを破棄できます
```
$_SESSION = array();
```
### ②：クッキーの破棄
Cookieに保存してある"SessionIDの保存期間を過去にして破棄する。
```
//session_name()は、セッションID名を返す関数
if (isset($_COOKIE[session_name()])) {
    setcookie(session_name(), '', time()-42000, '/');
}
```
### ③：サーバー上のセッションIDの破棄
```
session_destroy();
```

# 終わりに
 
Twitterでも情報発信しておりますので、ぜひフォローお願い致します!
https://mobile.twitter.com/tatsuki_kt