OmniAICreator/Qiita-1.07M huggingface dataset:
【SwiftUI】テキストを円形に配置する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648522/846f3805-b2cd-c6d4-377e-f7234dec3ff2.png)
```swift
struct CircleLabelView: View {
    var text = "Latitude 35.08587 E • Longitude 21.43673 W • Elevation 64M • Incline 12 •".uppercased()
    var textWidth: Double = 4.9
    var diameter: Double = 300
    
    var body: some View {
        ZStack {
            ForEach(Array(text.enumerated()), id: \.offset) { index, letter in
                VStack {
                    Text(String(letter))
                    Spacer()
                }
                .rotationEffect(.degrees(textWidth * Double(index)))
            }
        }
        .frame(width: diameter, height: diameter)
        .font(.system(size: 13, design: .monospaced)).bold()
    }
}
```
typescript-eslintのawait-thenableルールについて

## はじめに
この記事では[typescript-eslint](https://typescript-eslint.io/)のルールのうち`await-thenable`について解説します。
typescript-eslintの他のルールについても別記事で解説し、最終的にReact開発を行うにあたって最適なルール設定を構築することを目的としています。

## ルールについて
[`await-thenable`](https://typescript-eslint.io/rules/await-thenable)は`await`の利用をthenableなオブジェクト以外に出来ないようにするルールで、`"plugin:@typescript-eslint/recommended-requiring-type-checking"`で設定されるルールの一つです。
thenableなオブジェクトとはPromiseのように`then`メソッドを持つオブジェクトのことを指します。
```ts:thenableなオブジェクトのイメージ
type Thenable<T> = {
  then: (onfulfilled: (arg: T) => unknown) => unknown;
}
```
そしてこのルールは以下のようなケースで違反になります。
```ts
const hoge = () => 'hello';
await hoge();
```
解決するためには、`hoge`自体をthenableなオブジェクトにするか、`await`を外します。
```ts:thenableなオブジェクトにする
const hoge = async () => 'hello';
await hoge();
```

```ts:awaitを外す
const hoge = () => 'hello';
hoge();
```

## ルールの採用について
不必要な`await`を配置することで想定外な動作を起こすことはありませんが、必要な場合でなければ`await`を使えないようにすることでミスを減らせたり可読性を向上させられるのでこのルールは採用した方が良いと考えています。

```ts:このルールが有効であることでこのようなミスを防げる
const hoge = async () => 'hello';
// hogeの呼び出しを忘れている
await hoge;
```
typescript-eslintのarray-typeルールについて

## はじめに
この記事では[typescript-eslint](https://typescript-eslint.io/)のルールのうち`array-type`について解説します。
typescript-eslintの他のルールについても別記事で解説し、最終的にReact開発を行うにあたって最適なルール設定を構築することを目的としています。

## ルールについて
[`array-type`](https://typescript-eslint.io/rules/array-type)は配列の型宣言の方法を統一するためのルールです。`"plugin:@typescript-eslint/strict"`に設定すると有効になるルールの一つです。そして自動修正可能なルールです。
型宣言の方法は`T`という型を要素として持つ配列型を表現するために`T[]`のようにする方法と`Array<T>`のようにする2種類があります。
このルールではこの2つのどちらかに統一するか、条件によってこの2つの記法を使い分けるという3つのルールが存在します。さらにそれらを通常の配列に対してと読み取り専用の配列に対してでそれぞれ定義可能です。
`T[]`で統一する場合は`'array'`、`Array<T>`の場合は`'generic'`、金剛の場合は`'array-simple'`をオプションに指定します。
オプションの形式の型は以下のようになっています。
```ts
type Options = {
  default?: 'array' | 'generic' | 'array-simple',
  readonly?: 'array' | 'generic' | 'array-simple',
}
```
`default`と`readonly`のどちらも`array`を指定した場合は以下のように統一します。
```ts:array
type Hoge = string[];
type Foo = readonly string[];
type Bar = (string | number)[];
type Fuga = readonly (string | number)[];
```
`default`と`readonly`のどちらも`generic`を指定した場合は以下のように統一します。
```ts
type Hoge = Array<string>;
type Foo = ReadonlyArray<string>;
type Bar = Array<string | number>;
type Fuga = ReadonlyArray<string | number>;
```
`default`と`readonly`のどちらも`array-simple`を指定した場合は以下のように統一します。
```ts
type Hoge = string[];
type Foo = readonly string[];
type Bar = Array<string | number>;
type Fuga = ReadonlyArray<string | number>;
```
簡単に書ける時は`T[]`のように、複雑な組み合わせの時は`Array<T>`のように出し分けます。

## ルールの採用について
配列の型定義方法を統一することで可読性が上がるので積極的に採用したいです。例え既存のプロジェクトに加えるとしても自動修正が可能なので低いハードルで簡単に採用できます。
そして設定するオプションは、`default`と`readonly`で同じ値に設定したいです。読み取り専用という理由で異なるルールを設けると統一性に欠けることが理由です。
`array-simple`は条件によって記法を変える必要があるので、記法のずれが目立つのと条件を開発者が把握する必要がある点から採用を避けたいです。
`array`と`generic`ですが、記述量の多さやデフォルトの記法でもあるので`array`を採用するのが良いと考えています。

結果としてできた設定するルールは以下のようになります。
```json
"@typescript-eslint/array-type": [
  "error",
  {
    "default": "array",
    "readonly": "array"
  }
]
```
typescript-eslintのadjacent-overload-signaturesルールについて

## はじめに
この記事では[typescript-eslint](https://typescript-eslint.io/)のルールのうち`adjacent-overload-signatures`について解説します。
typescript-eslintの他のルールについても別記事で解説し、最終的にReact開発を行うにあたって最適なルール設定を構築することを目的としています。

## ルールについて
[`adjacent-overload-signatures`](https://typescript-eslint.io/rules/adjacent-overload-signatures)はオーバーロード関数を利用する際にまめて定義するためのルールです。`"plugin:@typescript-eslint/recommended"`ではデフォルトで有効となります。
オーバーロード関数とは以下のような関数を指します。
```ts
function returnArg(arg: string): string;
function returnArg(arg: number): number;

function returnArg(arg: string | number): string | number {
  return arg;
}
```
`returnArg`は文字列か数値の値を受け取って、それをそのまま返す関数です。関数を実装した部分だけでは、返り値の型は引数の型に関わらず`string | number`を返す関数です。そこで関数シグネチャと呼ばれる型宣言を予め行うことでこの関数は文字列を引数に渡したときは`string`を返す関数、数値が引数に渡したときは`number`を返す関数として扱われます。
実装部分でその関数における緩い型を定義し、より厳密な型をシグネチャとして別で定義して型の安全性を高めるようなイメージの機能です。

`adjacent-overload-signatures`はそんなオーバーロード関数をバラバラに定義したときに違反となるルールです。
先ほどの例だとシグネチャと実装の間に関係のないコードが挟まっているときや
```ts
function returnArg(arg: string): string;
function returnArg(arg: number): number;

const hoge = 'hoge';

function returnArg(arg: string | number): string | number {
  return arg;
}
```
シグネチャの間に余計なコードが挟まっているときに違反となります。
```ts
function returnArg(arg: string): string;
const hoge = 'hoge';
function returnArg(arg: number): number;

function returnArg(arg: string | number): string | number {
  return arg;
}
```

## ルールの採用について
このルールは可読性を上げれるだけではなく、TypeScriptの[実行エラー](https://typescript.tv/errors/#TS2391)を防ぐことにもなります。このルールを課すことで特定のコードが実行できなくなることはないことに加えて、可読性の向上・バグの回避につながるルールのため採用すべきルールと考えています。
WEB+DB PRESS休刊すんの！！？ うそん！？なんで！？

この記事はsubstack等の他の媒体でも投稿しています。

tacast放送局新聞


WEB+DB PRESS休刊すんの！！？ うそん！？なんで！？
マジらしいっすわ

🌮TACOSU🌮@TACAST放送局
2023/05/01

という訳で、WEB＋DB　PRESSが休刊されるみたい

衝撃のあまり初のsubstack投稿がこれになった。

だんだん紙の情報媒体が減っていってるね。

ほんとにこれで良かったのか



[WEB+DB PRESSとは？]

2000年から出ている「プログラミング技術情報誌」である。

同社の「Software Design」とごっちゃになってる人も多いかと思われるが、

どちらかと言えば「Webアプリケーション向け」というのがWEB+DB PRESSになる。

「Software Design」は
「OS,Web,プログラミング,技術者のスキルアップのための総合誌」という通り、
Webだけでなく幅広い層（いろんな意味でね）への情報誌だ。

ちなみにWEB+DB PRESS Plussというシリーズがあり、

こちらはWEB+DB PRESSの編集者がWEB+DB PRESSの各コーナーなどを再編集して、
一つのテーマに沿って一つの本にまとめたものだ。

雑誌の形態だったり、一冊の本になっていたりといろんなパターンがある。

エンジニアになりたいと思っていた時は、
いつの日か読んだこれらが、

自分の武器となってくれることを想像して
このシリーズをワクワクしながら読んでいた。

結局今は全く違う職に就いたが、
それでも「面白い技術は無いか」と楽しく読み物として読んでいる。

[で、それがなんだって？]

休刊します

はい、公式のページはこれ

技術評論社さんのwebページ
『WEB+DB PRESS』 休刊のお知らせ
https://gihyo.jp/magazine/wdpress/suspended


とりあえず気になった部分をWebページから引用して一緒に読んでいきたいと思う。

・『WEB+DB PRESSは，2023年8月発売のVol.136をもって隔月刊誌としては休刊させていただきます。』

はい、一文目から

えぐい。そんなのっけからそんなのいらない。

もうちょいこう…ないの？挨拶とかさ。「本日はお日柄もよく…」みたいなやつ。

「おはよう。今日も今日とてGWの真っただ中にPCとにらめっこしてる物好きども」ぐらいの煽りがあってもよいのよ？

そもそも5/1にこんなの出されても、
GW中にも関わらず休日返上してTwitterに張り付いてる物好きしか反応しないんだからさ。

あと、136号って結構続いてるのね。全くそこらへん気にしたこと無かった。

ずっと続くもんだと思っていたし。
そりゃね、業界自体がまだまだ元気だし

なにより、「常にアンテナを張って勉強して自分のスキルを磨け」みたいな業界だもの

一つの何が今業界で起こってるのかという指針見たいなものなんだから
なくなるなんて思ってもいないよ。

ある意味トレンドを発信する媒体が無くなってしまうと、

指針が無くなってしまうのではないかという懸念があるぐらいだ。

・『物価上昇による製作費の高騰など諸般の事情により，今回の決定に至った次第です。』

はい、二文め

個人的には

「前々からSoftware Designと統合したかったんだけど、
都合がつかなくって良いタイミングを見計らっていた」

というのを想像していたんだけれども、なんかもっと酷い感じを見受けられる。

制作費の高騰って…

確かに技術評論社の雑誌って結構いい紙使ってるイメージがあるけども！！

まぁ、恐らくそこではないだろう。

なんだったら、このご時世、電子版での購入の方が多いだろうし。

（というか、そこが問題なのなら紙の質を落としてもらっても全然僕は構わない。

そら、日経系の雑誌とか見てみろ。笑っちまうぐらいぺらっぺらだぞ。

中身じゃないぞ。物理的な話だ。

その分カラーページは日経系の雑誌の方が多い印象がある。

まぁ、ペラペラな紙にしたところでどれだけ変わるのかという話だが）

せめても電子媒体だけでも配信してくれればと思っていたが、それすらもできないということは相当なことだ。

ということは、

おそらく記事の作成、編集にかかるコストの問題という風に捉えることもできる。

創刊された2000年代とくらべ、

zennやqiitaなどの
「エンジニアであろうとなかろうと気軽にアクセスできる情報共有の場」
が出来たということもあり、

「どこかの記事と内容がダブった」とか、「これ、○○ですでにやってる…」とかのチェックの手間も爆発的に増えてるんだろう。

そもそもWEB系技術というポイントを絞った雑誌だ。

この20年間業界がものすごい速さで進んできたとは言え、
続けば続くほど書くことに真新しさが無くなっていくのも当然。

何度も同じことを毎年こすり続ける雑誌もあるが、

アウトプットを推奨している業界として
「あれ？これ書かれてあるの去年と全く同じじゃね？」
というのは是が非でも避けたいところではないか。

そういう意味では「役割を終えた」という風にみなされたのかもしれない。

・『必要な場合には「特別号」の編集・刊行なども検討してまいります。』

最後から一行上から取ってきた。

上でも言っているが、WEB+DB PRESS Plussというシリーズがある。

雑に言うと「まとめ号」みたいなものだ。

恐らくそれが「特別号」という感じで出るかもね？ということだろうと思っている。

というかついこの間にWEB+DB PRESS pluss 「WEB+DB PRESS 総集編［Vol.1～120］」というのが出たばっかりなんだが

これ、残りの［Vol.121～136］はどうするんだ？無しのまま行くのか？

正直それがめちゃくちゃ気になる。

[まとめ]

やめんでください。お願いします。
自分のウェブサイトリリース


自分のウェブサイトリリース完了しました。
ようこそ、いらっしゃいませ。

http://self-introduce.mojoru.com/jp.html

![self-introduce-mojoru-jp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1273212/39da80a6-666e-ac94-84d5-271b551ea6eb.png)

![self-introduce-mojoru-en.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1273212/ea5e53cf-b17d-0f5b-ed94-c8f99834d0bc.png)
ChatGPTにチャット内容の著作権について説明を求めたら

# はじめに
先日、新しい Bingで「作成」の「執筆分野」に「Bingのチャットと著作権」というワードでトーン「プロフェッショナル」長さ「中」で下書き生成したら興味深い長文が生成されましたので、今回は、ChatGPTに「ChatGPTのチャット内容の著作権についてなるべく正確に説明してください。」と聞いてみました。

## この記事内容の作業環境
Windows11
Microsoft Edge 112.0.1722.64
ChatGPT3.5

## この記事内容の保証
※この記事にはAIが自動生成した見解的な情報が含まれます。AIが自動生成して書かれた内容の妥当性は保証されません。

# 実行結果

ChatGPT
>ChatGPTのチャット内容については、OpenAIが保有する著作権があります。このチャット内容を無断で複製、改変、再配布することは違法であり、OpenAIの著作権を侵害することになります。
>
>ただし、ChatGPTのチャット内容は、ユーザーとの対話に応じて生成されたものであり、一部のチャット内容は一般的な知識や情報に基づいて生成されたものであるため、一部の場合には著作権保護の対象となりません。
>
>そのため、ChatGPTのチャット内容を使用する場合には、OpenAIの利用規約に従い、正当な方法で利用する必要があります。具体的には、OpenAI APIを介してChatGPTを使用することが必要であり、OpenAIのライセンス契約に従って使用する必要があります。


あなたがネット上のコンテンツを利用する際に第三者の著作権を侵害する恐れはありませんか？

ChatGPT
>ChatGPTは、OpenAIが所有するコンピューター上のソフトウェアであり、ネット上のコンテンツを利用することはありません。ただし、ChatGPTを使用するユーザーが、ネット上のコンテンツに関する質問や意見を述べる場合があります。この場合、ChatGPTはその内容について、知識や情報を提供するだけであり、実際にそのコンテンツを利用することはありません。
>
>ただし、ChatGPTは、自然言語処理技術を利用して文章を生成するため、ユーザーが与えた入力に基づいて、著作権保護の対象となる文章を生成する可能性があります。そのため、OpenAIはChatGPTの利用に関する利用規約を設け、ユーザーに対して、著作権保護の対象となるコンテンツを生成しないように指導しています。また、OpenAIは、著作権侵害に関するクレームがあった場合には、速やかに対応することを明示しています。



このチャット内容を引用して、
（ここで間違えてエンター送っちゃいました。）

ChatGPT
>このチャット内容を引用する場合は、以下のように引用符で囲み、ChatGPTとOpenAIについての情報を明示する必要があります。
>
>例：
>ChatGPTは、「OpenAIが所有するコンピューター上のソフトウェアであり、ネット上のコンテンツを利用することはありません」と述べています。
>
>引用符で囲んだ部分は、ChatGPTが提供する回答の一部であることを示し、OpenAIがChatGPTの所有者であることを明示しています。また、引用元の情報が不明確な場合は、利用目的に応じて出典を明示する必要があります。


了解しました。ありがとうございます。

ChatGPT
>どういたしまして。他に何か質問があれば、いつでもお気軽にお聞きください。

ご回答されているChatGPTのバージョンを教えてください。

ChatGPT
>私が使用しているChatGPTのバージョンは、GPT-3.5というバージョンに基づいています。GPT-3.5は、GPT-3とGPT-4の中間に位置する、OpenAIが開発した最新の自然言語処理技術です。このバージョンでは、GPT-3よりも精度が向上しており、より自然な対話を実現することができます。ただし、私の知識の更新は定期的に行われており、最新の情報に基づいて回答を提供しています。

# 考察
検索エンジンと統合された「Bingのチャットと著作権」では、まず第三者著作権の侵害の可能性について言及してきたのに対して、ChatGPT本体は、まず自身が生成したコンテンツに対するOpenAIの著作権を主張してきたのは想定外でした。

Bingのチャットとは違って、オンデマンドには、あるいはアクティブにはネット情報を探索しないことから、「ネット上のコンテンツを利用することはありません。」と断言しているのかもしれません。



# おわりに
ChatGPT4は有料なんですね。Upgrade to Plusを開いて、すぐ閉じちゃいました。

# 参考リンク
https://qiita.com/mylifewithviolin/items/953d7a36fca07df1e260
【論文読み】動画解析による公共空間の行動検出

## はじめに
こんにちは。論文を読んだ結果の紹介記事です。  
今回紹介するのは、「動画解析による公共空間の行動検出」という論文です。  

- タイトル： 【論文読み】動画解析による公共空間の行動検出 
- 出典： 岡野 将大, et al.; 人工知能学会 2022    
- URL： https://www.jstage.jst.go.jp/article/pjsai/JSAI2022/0/JSAI2022_1O4GS703/_pdf/-char/ja  


## 概要
深層学習により「滞在しやすさ」の指標の一つである「ベンチ利用行動」を定量的に評価する技術を開発。  
１地点のみを対象とした。ベンチ利用／未利用の２分類。


## 特徴
- 活性化関数をReLUからGELUに変更   
- 損失関数をHuber lossに変更。損失が大きい場合にMAE、損失が小さい場合にMSEと同様の機能となる。  
- ROC-AUC精度評価

## 想定される適用例
- 動画による人や物の有無の検知全般  


## 参考
- [動画解析による公共空間の行動検出](https://www.jstage.jst.go.jp/article/pjsai/JSAI2022/0/JSAI2022_1O4GS703/_pdf/-char/ja)
Pythonデコレータの違い：staticmethodとclassmethod

# はじめに

Pythonのデコレータは、関数やメソッドの振る舞いを修飾したり拡張したりするために使用されます。
staticmethodとclassmethodデコレータの違いについてまとめます。

# クラスメソッド（classmethod）
・クラスそのものに対して操作を行うメソッド。
・第一引数としてクラスオブジェクト（通常はcls）を受け取る。
・クラスの状態（クラス変数）にアクセス・操作が可能。

```python
class MyClass:
    @classmethod
    def my_class_method(cls, arg1, arg2):
        # クラスメソッドの実装
```

# 静的メソッド（staticmethod）
・クラスやインスタンスに依存しないメソッド。
・クラスオブジェクトやインスタンスオブジェクトを受け取らない。
・クラスやインスタンスの状態にアクセス・変更ができない。

```python
class MyClass:
    @staticmethod
    def my_static_method(arg1, arg2):
        # 静的メソッドの実装
```

# 違いのまとめ
**引数**：
classmethodは、第一引数としてクラスオブジェクトを受け取ります。
staticmethodは、クラスオブジェクトやインスタンスオブジェクトを受け取りません。

**使用目的**：
classmethodは、クラスの状態（クラス変数）にアクセス・操作するために使用されます。
staticmethodは、クラスやインスタンスの状態に依存しない操作を行うために使用されます。

```python
class ExampleClass:
    class_var = 0

    @classmethod
    def class_method(cls):
        return cls.class_var

    @staticmethod
    def static_method(a, b):
        return a + b

# クラスメソッドの呼び出し
result1 = ExampleClass.class_method()
print(result1)  # 0を出力

# 静的メソッドの呼び出し
result2 = ExampleClass.static_method(1, 2)
print(result2)  # 3を出力
```
(備忘メモ) ~/.ssh/known_hosts のエントリを手動で探す

## これはなに?

sshのknown_hostsファイルを見たらハッシュ化されていて、どういうハッシュ化なのか気になったので調べた結果をメモする。

## 本題

### known_hostsのハッシュ化?

known_hostsファイルが流出したときに備えてホスト名やアドレスを隠すための機能とのこと。[^1]
known_hostsへのアクセスが可能な状況が想定されているので、実際の状況は様々かもしれませんが、最悪の場合、当該ユーザーのユーザーディレクトリには侵入できると想定すると、例えばプライベートネットワーク内のサーバーのアドレスが分かると攻撃者にとっては(攻撃を拡大するために)有用な情報になってしまう、ということを想定しているのかと思いました。

### ハッシュ化アルゴリズムについて

[こちらの記事][yoichi-nakayama]にアルゴリズムの詳細がかかれています。

```text
|1|uu_salt|uu_result
```

という形式で書かれており、 `uu_salt` はソルト、 `uu_result` がハッシュ値(結果)と書かれていますが、デコードしているコードとPythonの[ドキュメント][python-doc-hmac-new] によるとソルトと呼ばれている `uu_salt` は `key` と呼ばれることもあるようです。(後で `openssl` で指定するときに `key` として指定することの正当化)
ところで、実際にソルトと元のホスト名/アドレスからPythonでハッシュ値を得るコードがありますが、個人的にPythonはあまり使わないのでopensslなどのコマンドでできるようにしたいです。

[yoichi-nakayama]: https://zenn.dev/yoichi/articles/host-in-ssh-known-hosts
[python-doc-hmac-new]: https://docs.python.org/3/library/hmac.html#hmac.new

### コマンドでハッシュ値を再生成する

当然ですがハッシュ値から元のホスト名/アドレスを生成することはできないので、目的のエントリを探すには探したいホスト名/アドレスからハッシュ値を再生成して比較するしかありません。

HMAC-SHA1は `openssl` で計算できるようだったので[こちらのページ][engineers-notebook]を参考に計算してみた。

[engineers-notebook]: https://eng-notebook.com/blog-entry-107/

まず `ssh-keyscan` コマンドで `known_hosts` ファイルのエントリを生成してみる:

```terminal
$ ssh-keyscan -H -t ed25519 github.com
# github.com:22 SSH-2.0-babeld-8f627ebe
|1|A7mBfgQFBh/axJPBkhN1czQ4QXo=|ULxHU20iBKTPncOF6w/R9h59d/g= ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
```

ここで得られたソルトを `base64` でデコードして指定し、ハッシュ値を求める平文はファイルで指定するようなのでコマンド置換で `github.com` という文字列を与えるとこのようになる:

```terminal
$ openssl dgst -hmac "$(printf 'A7mBfgQFBh/axJPBkhN1czQ4QXo=' | base64 -d)" -sha1 <(printf 'github.com')
HMAC-SHA1(/dev/fd/63)= 50bc47536d2204a4cf9dc385eb0fd1f61e7d77f8
```

得られたハッシュ値は16進数表記なので、 `ssh-keyscan` のハッシュ値をBase64をデコードすると

```terminal
$ printf 'ULxHU20iBKTPncOF6w/R9h59d/g=' | base64 -d | od -t x1 -w24
0000000 50 bc 47 53 6d 22 04 a4 cf 9d c3 85 eb 0f d1 f6 1e 7d 77 f8
0000024
```

となって `openssl` で得られたハッシュ値が `ssh-keyscan` の結果と同じであることを確かめられた。

### 有用な情報

実際に `known_hosts` から目的のエントリを検索したり、エントリの追加/削除がしたい場合は[こちらのブログ][hnakamur]にある通り、 `ssh-keyscan`(追加)/`ssh-keygen`(検索/削除)を使うとよい[^2]。

[hnakamur]: https://hnakamur.github.io/blog/2021/07/23/find_add_delete_entry_in_hashed_ssh_known_hosts/

[^1]: [公式ドキュメント][official-doc-known-hosts]より
[^2]: [ブログ][hnakamur]だけ見ると戻り値で判別するだけのようにも読めるが、実際にやってみると見つかった行が標準出力に出力される。またヘルプをみたら `-l` オプションがあり、与えると見つかった場所(行数)も出力される。 `-lv` まで指定すると[^3]キーのASCIIアート表示も出力される。(鍵が意図したものか確認するには便利かも)
[^3]: さらにちなみに `-l` でも `-v` でも見つかった行の表示しかされず、 `-lv` にするとキーのASCIIアートが表示されるのだが、この挙動は `ssh-keygen` のほかのオプションとは挙動が一貫していないと思う。

[official-doc-known-hosts]: https://manpages.org/sshd/8
CKA試験、Volume EmptyDir(命令語のみ)

# Volume
## EmptyDir


https://kubernetes.io/docs/concepts/cluster-administration/logging/


次の条件に合わせて、`nginx`webサーバが生成したログファイルをもらい、STDOUTで出力する`busybox`コンテナーを運営しなさい

- pod名: weblog1
- Web Container
  - image: nginx:1.17
  - Volume mount: /var/log/nginx
  - readwrite権限
- Log Container
  - image: busybox
  - Command: /bin/sh, -c, "tail -n+1 -f /data/access.log"
  - Volume mount: /data
  - readonly
 - emptyDirを利用した、データ共有
 

```sh
kubectl run weblog --image=nginx:1.17 --dry-run=client -o yaml > weblog1.yaml
```

```修正前weblog1.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: weblog1
  name: weblog1
spec:
  containers:
  - image: nginx:1.17
    name: weblog1
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
```



```修正後weblog1.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: weblog1
  name: weblog1
spec:
  containers:
  - image: nginx:1.17
    name: weblog1
    volumeMounts:
    - mountPath: /var/log/nginx # path を記載する
      name: cache-volume # volumesと合わせる

  - image: busybox
    name: busybox2
    args: [/bin/sh, -c, 'tail -n+1 -F /data/access.log'] 
    volumeMounts:
    - mountPath: /data # path を記載する
      name: cache-volume # volumesと合わせる
      readOnly: true # readOnly: true

  volumes:
  - name: cache-volume
    emptyDir: {}

```

```sh
kubectl apply -f weblog1.yaml
```
第1 ~ 第３正規化までのまとめ

# テーブルとは？

* 共通点を持つレコードの集合体

# 正規化とは？

データの冗長性を排除し、一貫性と効率性を保持するためのデータ形式

# 第一正規形

**1つのセルには1つの値の原則を満たせば第一正規形**

1つのセルに複数の値を入れることがRDBで認められない理由は、
複数セルを許すことで**主キーが各列の値を一意に決定できないため**です



（↓第一正規形）

![名称未設定ファイル.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/12ada6d7-0d14-2abe-852c-229316440458.jpeg)


### 問題点1
* 主キーを決めることが出来ない
    * 一意のレコードが特定出来ない
    * レコードを特定するには、`ユーザーid、名前、子` 全ての情報が必要
    * 主キーはその列の一部のため、吉田さんの子は`NULL`なので一意にはならないので×

### 問題点2
* ユーザーと、扶養者の2つのエンティティを含んでいる
    * テーブルの意味やレコードの単位が理解できない

## 修正後

![正規化.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/19fe1fb7-afaf-757a-86de-ce24242e3e29.png)


`ユーザー`と、`子ども`で分けました

関数従属性を満たすことが出来ました。
関数従属性とは、**どんな関数でも`X`が決まれば、`Y`が決まる性質**

`社員ID` → `社員`
`社員ID` → `子1`
`社員ID` → `子2`
`社員ID` → `子3`

# 第二正規形

第二正規形とは、
**部分関数従属を解消して、完全関数従属のみのテーブルを作ること**

部分関数従属とは、主キーの一部の列に対して従属関係があること
完全関数従属とは、主キーを構成する全ての列に対して従属関係があること

![名称未設定ファイル.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/74aa08ad-57d6-b245-f417-1e96f6f19a0c.png)

こちらのテーブルは第二正規形ではありません。
理由は、**完全関数従属では無い**からです。

こちらのテーブルでは主キーは、`食べ物種別コード`と`食べ物id`の二つがあります
`食べ物種別コード`は、`食べ物種別`に従属しています
主キーの一部の列に対して従属関係があるので、部分関数従属になります

## 第二正規化すると

![名称未設定ファイル.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/be9fe7b6-a986-616a-c2db-1c17ef0862eb.jpeg)

## 第二正規化にする意味

第二正規化する前のテーブルに対して、食べ物は無いですが`食べ物種別`として、`中華`を追加しようとしたとします。



しない場合のデメリットとしては、
* 主キーである食べ物idをNULLにできないので、何かしらのダミー値を登録する必要があります

![名称未設定ファイル.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/7752f486-ede3-aa13-481c-470eb279bc82.jpeg)

* また、想定外のデータを登録してしまう可能性があります
    * `{4, 中華}`と登録するつもりが、ある特定のレコードだけ`{4, China}`と登録してしまうかもしれません
    * アプリケーション側でチェックはできるものの、DBに直接挿入されれば対処出来ません

![名称未設定ファイル.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/9eb956be-e926-8982-ec99-4cc20d8c0009.jpeg)

# 第三正規形

![スクリーンショット 2023-05-01 21.39.59.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/baba8671-6d99-6a34-0291-22a6a4d25925.jpeg)

`生産地コード`と、`生産地`にフォーカスを当てます。

仮に、生産地に`愛知`が増えたとして登録しようとしたとき。
新しく生産地ができただけで実際に生産された食べ物が存在しない場合、主キーである`食べ物コード`と`食べ物id`は空になるため登録できません

![スクリーンショット 2023-05-01 21.52.20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/92641f17-79e1-a95b-9f97-3e6f1c9ba122.jpeg)

また、テーブル内には**関数従属性が存在します**（`生産地コード` → `生産地`)

仮に、生産地が食べ物に対して1:1の場合、

`食べ物種別コード、食べ物id` → `生産地コード`となり、

全体としては、

`食べ物種別コード、食べ物id` → `生産地コード` → `生産地`
の2段階の関数従属が存在します

このような従属性を**推移的関数従属性**と言い、正規化されていないことになります

## 第三正規化を行う

![正規化.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536974/e06834f0-10c4-e09c-5d7e-a6b555b45392.png)
【GAS】特定の列を更新したら日時を追記する

特定の列を（今回はA列）更新したら（何か文字を入力したり内容を変更したら）日時をG列に追記するGAS

```javascript
function insertDate() {

  var ss = SpreadsheetApp.getActiveSpreadsheet(); //現在アクティブなシートを選択 
  var sheet = ss.getSheetByName("シート名"); //対象のシート名を選択("シート名"にシート名記入)
  var currentRow = sheet.getActiveCell().getRow(); //アクティブなセルの行番号を取得
  var currentCol = sheet.getActiveCell().getColumn(); //アクティブなセルの列番号を取得


  //A列が更新されたらG列に日時を出力する
  //2行目以降(currentRow > 2)かつA列(currentCol === 1）を更新した場合
  //B列ならcurrentCol === 2にする
  if(currentRow > 2 && currentCol === 1) { 

    var updateCell = sheet.getRange(currentRow, 7); //更新した列のG列に値を入れるためセルを指定
    var date=new Date()  //日時を取得
    var date2 = Utilities.formatDate(date,'Asia/Tokyo','yyyy/MM/dd HH:mm:ss'); // 日時フォーマット
    updateCell.setValue(date2);  //updatecell（G列）に日時を追記する
  }
    
}
```

参考にしたサイト
https://qiita.com/daichi_ca/items/23c4d8e662dcbb5571a7
SwiftでHelloWorldプログラムを実装してみた

# 概要
SwiftでHelloWorldプログラムを実装してみました。以下のページを参考にしました。
https://press.share-wis.com/try-swift
https://zenn.dev/treastrain/scraps/74efdd196edd83
今回はDockerでやってみました。

# DockerでSwift環境をセットアップ
```
$ docker pull swiftdocker/swift
Using default tag: latest
latest: Pulling from swiftdocker/swift
50aff78429b1: Pull complete 
f6d82e297bce: Pull complete 
275abb2c8a6f: Pull complete 
9f15a39356d6: Pull complete 
fc0342a94c89: Pull complete 
2b53dcb0eee7: Pull complete 
267fcb0a26f6: Pull complete 
Digest: sha256:0b2ad4a26977a27bedd2cbbae1c8821b3816a7be8b1fb4ad783816be058f8e95
Status: Downloaded newer image for swiftdocker/swift:latest
docker.io/swiftdocker/swift:latest
```

# Swift環境にアクセス
```
$ docker run -it --privileged --name swift2 swiftdocker/swift /bin/bash
root@f026c48d20bb:/# 
```

# Swiftプログラムを実装
Hello, World!と表示するプログラムを実装してみました。
```
root@f026c48d20bb:/# echo 'print("Hello, World!")' > hello2.swift
```

# Swiftプログラムを実行（コンパイルなし）
以下の通りコマンドを実行しました。
```
root@f026c48d20bb:/# swift hello2.swift 
Hello, World!
```

# Swiftプログラムを実行（コンパイルあり）
以下の通りコマンドを実行しました。
```
root@f026c48d20bb:/# swiftc hello2.swift 
root@f026c48d20bb:/# ./hello2 
Hello, World!
```

何かの役に立てばと。
ベルトランの投票問題とカタラン数

### ベルトランの投票問題
ベルトランの投票問題はなかなか面白い問題で、[Bertrand's ballot theorem (Wikipedia)【英文】](https://en.wikipedia.org/wiki/Bertrand%27s_ballot_theorem)に説明がありますが残念ながら日本語訳がないので、簡単ですが紹介します。

【問題】選挙において、候補者$M$は$m$票を、候補者$N$は$n$票を得票した。ただし、$m \gt n$である. 開票していく過程において$M$の得票数が$N$の得票数を常に 上回る確率は$\Large \frac{m-n}{m+n}$となる。

### 数学的帰納法で証明
驚くほど簡単な式になりますが、以下ののように数学的帰納法で証明することが出来ます。

```math 
\begin{align*}
&m \gt 0 かつ n=0のときは常に上回るので \\
&P_{m,n} = \frac{m-0}{m+0} = 1で正しい \\
&m = n \gt 0のときは成り立たないので \\
&P_{m,n} = \frac{0}{m+m} = 0で正しい \\
&P_{m,n-1} とP_{m-1,n}が成り立つとき P_{m,n}は \\ 
&P_{m,n-1} が起こった後、Nが出た場合と、\\
&P_{m-1,n} が起こった後、Mが出た場合なので\\
\end{align*}
```
```math
\begin{align*}
P_{m,n} &= P_{m,n-1}\frac{n}{m+n}+P_{m-1,n} \frac{m}{m+n}  \\
&= \frac{m-(n-1)}{m+(n-1)}\frac{n}{m+n}+\frac{(m-1)-n}{(m-1)+n}\frac{m}{m+n}\\
&= \frac{m-n}{m+n} \\
\end{align*}
```

### カタラン数との関係

同じ問題を確率ではなくて**場合の数**$C_{m,n}$で考えてみます。その場合も以下の同様の式が成り立ちます。

```math 
\begin{align*}
&c_{m,0} = 1  & (m \gt 0) \\
&c_{m,n} = 0  & (m \le n) \\
&c_{m,n} = c_{m,n-1}+c_{m-1,n}  & (m \gt n)\\
\end{align*}
```
この結果を表にすると以下のようになります。
|  m\n |  0 |  1 |  2 |  3 |   4 |   5 |   6 | 7 |  8 |
|----:|----:|----:|----:|----:|----:|-----:|----:|----:|-----:|
|   1 |  1 |  |          
|   2 |  1 |  1 |     
|   3 |  1 |  2 |  2 |       
|   4 |  1 |  3 |  5 |   5 |  
|   5 |  1 |  4 |  9 |  14 |   14|   
|   6 |  1 |  5 | 14 |  28 |   42 |  42 |    
|   7 |  1 |  6 | 20 |  48 |   90 | 132 |  132|     
|   8 |  1 |  7 | 27 |  75 |  165 | 297 |  429 |  429|    
|   9 |  1 |  8 | 35 | 110 |  275 | 550 |  902 | 1430 | 1430|

この対角線の数列$c_{n+1,n}$は $1,1,2,5,14,42,132,429,1430$ですが、これは[カタラン数(Catalan number) Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%AB%E3%82%BF%E3%83%A9%E3%83%B3%E6%95%B0)のように見えます。カタラン数の一般項は以下の式で表されますので、これと一致するか確認していきます。

```math 
\frac{1}{n+1}\times\binom{2n}{n}
```

### カタラン数の一般項と一致するか

$c_{n+1,n}$の値をベルトランの投票問題の確率から場合の数を逆算します。


```math 
\begin{align*}
&一般に、確率 = \frac{場合の数}{すべての数} なので\\
&場合の数 = 確率 \times すべての数 \\ \\

&したがって \\
& c_{n+1,n} = \frac{1}{2n+1} \times 同じものを含む順列(n+1,n)\\
&           = \frac{1}{2n+1}  \times \binom{2n+1}{n} \\

& = \frac{1}{2n+1}  \times\frac{(2n+1)!}{(n+1)!n!}  \\
& = \frac{1}{n+1}\times \frac{(2n)!}{n!n!}  \\
& = \frac{1}{n+1}\times\binom{2n}{n}
\end{align*}
```

となりベルトランの投票問題の場合の数$c_{n+1,n}$はカタラン数の一般項と一致することが確認できました。
React: 実行する際の仕組みや用語

## はじめに
記事作成者はJavaScript、React勉強中の👶です。
理解を深めるために日々の学びを記事にしています。
初心者の記事なので言い回しや記載に誤りがあるかも知れませんが、暖かく見守っていただけると幸いです。
<font color="gray">(よろしければ間違いをコメントいただけると学び、励みになります！)</font>

## 学んだこと
・JavaScript、Reactを実行する際の仕組みや用語

## DOMとは？
Document Object Model。
画面表示するまでのHTML/CSS/JSを解釈し、木構造(DOM)で表現する。
=> レンダリングコスト: 高△
=> コードの可読性: 低△

## 仮想DOMとは？
JavaScriptのオブジェクトで仮想的に作られたDOM。
いきなりDOMを操作しない。
仮想DOM(変更前) と 仮想DOM(変更後) で差分を確認してから、実際のDOMに同期する(差分検出処理 reconciliation)。
=> レンダリングコスト: 低○
=> コードの可読性: 高○

## npm/yarn
npm/yarnは、JavaScriptのパッケージマネージャー
=>パッケージのインストール、アンインストール、アップデートなど。
- 読み込み時に依存関係を勝手に解決してくれる
- import先が明示的に分かれる
- NPM (レジストリ)に公開されているパッケージをコマンド一つで利用可能
- チーム内共有も簡単に

NPM: パッケージのレジストリ。オンライン上に世界中のNode.jsのパッケージが集約されている。
package.json: 設計書的な役割(プロジェクト(パッケージ)の詳細が書いている)
package-lock.json / yarn.lock: パッケージのバージョンをロックするファイル
node_modules: 各モジュールの実態(サイズが膨大のためGitHubにはあげない)

## モジュールバンドラー
- 開発時に分割していたjs(css/image)ファイルを本番用に1つにまとめてくれる。
	→ 転送(HTTTPリクエスト)の最適化ができる
- 制作環境の機能が揃う
webpackなど。

## トランスパイラ
新しいJavaScriptの記法(開発向け)を古い記法(本番向け)に変換してくれる。
BABELなど。

## SPA (Single Page Application)
Webプリケーションの形式。1つのWebページによって、1つのアプリを構築する。最初にHTMLやCSS、JavaScriptを受け取った後は必要なデータだけをサーバに要求し差分を表示する(FechやXMLHttpRequestなどのJavaScript APIを介して更新する)
ページの更新速度が早い利点をもつ反面、最初のローディング時間が長くなってしまう特徴がある(=> SSR、SSG で軽減が見込める)

開発に利用されるフレームワーク: React、Angular、Vue.js など

## 参考
- [Qiita |【React】仮想DOMって何！？コンポーネントのレンダリングと描画について理解しよう！
](https://qiita.com/seira/items/6767e222890c9890ecb9)
- [Zennn | pmとyarnについて解説](https://zenn.dev/hinoshin/articles/aadfdd7ba958a9)
- [SPAの基本と3大JavaScriptフレームワーク（React、Angular、Vue.js）の最新動向 ～2023年版～](https://devlog.grapecity.co.jp/spa-javascript-framework-in-2020/)
[AWS Q&A 365][SES]AWSのよくある問題の毎日5選 #45

# 1. Amazon Simple Email ServiceのVirtual Deliverability Managerとは何ですか？
回答：Virtual Deliverability Managerは、Amazon Simple Email Serviceのツールで、ユーザーが電子メールの配信状況をモニターし、改善するための推奨事項を提供します。メールキャンペーンを最適化する方法に関するメトリクスやアドバイスを表示するダッシュボードを提供します。

# 2. Virtual Deliverability Managerを始めるにはどうすればよいですか？
回答：Virtual Deliverability Managerを始めるには、ユーザーはAmazon SESコンソールまたはAWS CLIを介してアクセスできます。設定を構成し、ダッシュボードにアクセスして電子メールの配信状況を監視できます。

# 3. Virtual Deliverability Managerはどのような機能を提供していますか？
回答：Virtual Deliverability Managerは、バウンス率、クレーム率、評判などのメトリクスを表示するダッシュボードを提供します。配信状況を改善するための推奨事項を提供し、電子メールリストやサブスクリプションを管理するリスト管理ツールを提供します。

# 4. Virtual Deliverability Managerはどのように動作しますか？
回答：Virtual Deliverability Managerは、電子メールの送信パターンを分析し、配信状況を改善するためのフィードバックを提供することによって動作します。機械学習アルゴリズムを使用して問題を特定し、ベストプラクティスに基づいて推奨事項を提供します。

# 5. 自分自身のIPアドレスでVirtual Deliverability Managerを使用できますか？
回答：はい、Virtual Deliverability Managerは、Amazon SES専用IPアドレスとユーザー所有のIPアドレスの両方で使用できます。IPプールの管理や評判の監視などの機能を提供して、ユーザーが電子メールの配信状況を最適化するのに役立ちます。
[AWS Q&A 365][SES]Daily Five Common Questions #45

# 1. What is Virtual Deliverability Manager in Amazon Simple Email Service? 
Answer: Virtual Deliverability Manager is a tool in Amazon Simple Email Service that helps users monitor their email deliverability and provides recommendations to improve it. It offers a dashboard that displays metrics and advice on how to optimize email campaigns. 

# 2. How do I get started with Virtual Deliverability Manager? 
Answer: To get started with Virtual Deliverability Manager, users can access it through the Amazon SES console or AWS CLI. They can then configure settings and access the dashboard to monitor their email deliverability. 

# 3. What features does Virtual Deliverability Manager offer? 
Answer: Virtual Deliverability Manager offers a dashboard that displays metrics such as bounce rate, complaint rate, and reputation. It also provides recommendations on how to improve deliverability and offers a list management tool to manage email lists and subscriptions. 

# 4. How does Virtual Deliverability Manager work? 
Answer: Virtual Deliverability Manager works by analyzing email sending patterns and providing feedback on how to improve deliverability. It uses machine learning algorithms to identify issues and offers recommendations based on best practices. 

# 5. Can I use Virtual Deliverability Manager with my own IP addresses? 
Answer: Yes, Virtual Deliverability Manager can be used with both Amazon SES dedicated IP addresses and user-owned IP addresses. It offers features such as IP pool management and reputation monitoring to help users optimize their email deliverability.
テキストだけでアバターを生成できるプラットフォーム「Creative Reality Studio」を試してみた

お疲れ様です。

テキストを打ち込むことで、アバターやアニメーション作成を行えるプラットフォーム「Creative Reality Studio」を試した事例を紹介します。

（だいぶ前からあったやつなのですが、、なかなか忙しくて試すことができず2月に試した際のログとなります。）

https://studio.d-id.com/


サイトはこちら。

日本語版の自己紹介

https://www.youtube.com/watch?v=76VQeZAjX6k


英語版の自己紹介

https://www.youtube.com/watch?v=ZXfi03ZulIg



まあ、違和感ですし、この写真も実はまるっきり私というわけではないので、
（SnowのAIアバターで作成した写真）

諸々違和感ですね。。

ただ、もはや、顔出ししなくても説明動画みたいなものはこれで作る形でもいいかもしれないと思ったりしました。

活用どころはありそうだなと思ってますー。

以前、Unity開発とかでBlender使ってモデル作ったりしてましたが、結構時間かかるし、なるべくクイックに作ることを考えるとこういうツールは利用できそうだなと。

改めて、

AIは

作る時代から

使う時代へ

そしてAIが使えない人の生産性は落ちていくので、こういったデジタル・リテラシーが低い人はどんどん淘汰されていく時代に突入していきますね。

今日はこの辺で。
【Symfony】localでHTTPSのサーバーを立ち上げる

## はじめに
[symfony casts](https://symfonycasts.com/)を勉強していると、
```
symfony serve
```
を実行するとHTTPSのローカルサーバーが立ち上がる。
と説明がありましたが、自分の環境ではHTTPが立ち上がったので、その解決方法

### 解決方法
```:terminal
// このコマンドを実行する
symfony server:ca:install
```
それから`symfony serve`実行するとhttpsになります。

なぜローカルサーバーでHTTPSを立ち上げる必要があるかについてドキュメントにはこう書かれていました。

>Enabling TLS
Browsing the secure version of your applications locally is important to detect problems with mixed content early, and to run libraries that only run in HTTPS. Traditionally this has been painful and complicated to set up, but the Symfony server automates everything.
-和訳-
ローカルでアプリケーションの安全なバージョンを閲覧することは、混在コンテンツの問題を早期に検出し、HTTPSでのみ実行できるライブラリを実行するために重要です。従来、これを設定することは面倒で複雑でしたが、Symfonyサーバーはすべてを自動化します。

### まとめ
symfony castsとてもいいコンテンツですが、PHP Storm使ってるからVSCode信者としては少し残念です。
HTMLとJavaScriptでChatGPT APIを使いたい人が参考にする記事はこちら

## :rotating_light:注意:rotating_light:(2023年5月2日追記)
この記事のやり方で**公開Webアプリ**を作ってしまうと、**本来秘匿すべきAPIキーが公開されてしまいます！**
あくまで**手元の環境で使用する公開しないWebアプリ**を作るときのみ参考にしてください:point_up:

OpenAI platformの記載
> Do not share your API key with others, or expose it in the browser or other client-side code. 
>
>APIキーを他者に共有したり、**ブラウザやクライアントサイドコードで公開しないでください。**

今のところHTMLを利用して安全にChatGPT APIを使う方法は見つかっていないのですが、もし良い方法をご存じの方がいらっしゃればぜひ教えてください:pray:


## よくぞこの記事まで辿り着きました
あなたは**HTML**と**JavaScript**を使って**ChatGPT API**にリクエストを投げたいのにうまくいかず、途方に暮れていらっしゃるのですね。
:angel:**もう大丈夫**:angel:
この記事を参考にすれば、あなたのやりたいことがすぐに実現できます！

## あなたがChatGPT APIにリクエストを投げることができない理由
きっとこのような記事を参考にされていないでしょうか。
[ChatGPT API（gpt-3.5-turbo）を Node.js から使ってみる（公式リファレンスで参照した情報も記載）](https://qiita.com/youtoy/items/b3e2e462029bf40f8a1a)

**それが原因です！！！**

HTMLを利用しているあなたは、JavaScriptを**フロントエンド**（ブラウザ側）で動かそうとしています。一方、Node.jsはJavaScriptを**バックエンド**（サーバ側）で動かすための実行環境です。

したがって、**HTMLを使う場合とNode.jsを使う場合とでは、ChatGPT APIの呼び出し方が異なるのです！！！**

## HTMLを使うChatGPT APIの呼び出し方はこれ！！！
ユーザーが入力した言葉をChatGPTが受け取り、回答をブラウザに表示するだけの簡単なWebアプリです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958610/c589b251-c834-b271-520a-a16eb91f497b.png)
以下のコードをお好みの形に変更してご利用ください！
<details><summary>HTMLコード</summary>

```HTML:sample.html
<html>
<head>
  <meta charset="UTF-8" />
  <title>sample</title>
</head>

<body>
<textarea id="request_text" cols="100" rows="10">
</textarea>
<br />
<input type="button" onClick="reply()" value="話しかける" />
<br /><br />
<textarea id="response_text" cols="100" rows="10" disabled>
</textarea>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://unpkg.com/axios@1.1.2/dist/axios.min.js"></script>
<script src="sample.js"></script>
</body>
</html>
```
</details>

<details><summary>JavaScriptコード</summary>

```JavaScript:sample.js
const API_KEY = 'ご自身で取得したAPIキーを記載する';
const URL = "https://api.openai.com/v1/chat/completions";

function reply() {
    var text = document.getElementById("request_text").value;
    async function getResponse() {
        try {
            const response = await axios.post(
                URL,
                {
                    "model": "gpt-3.5-turbo",
                    "messages": [
                        { "role": "user", "content": text }
                    ]
                },
                {
                    headers: {
                        "Content-Type": "application/json",
                        Authorization: `Bearer ${API_KEY}`,
                    },
                }
            );
            var chatgpt_response = response.data.choices[0].message.content;
            $("#response_text").val(chatgpt_response);
        } catch (error) {
            console.log(error);
        }
    }
    getResponse();
}
```
</details>

※ChatGPT APIの料金体系が気になる方はこちらの記事をご参照あれ！
[【ChatGPT API × ラズパイ × LINEbot】ChatGPT君、きょう何着て行く？](https://qiita.com/iwakatakagundan/items/8292cc1bb215cecea304)

## さあ、あなたが書いたコードに組み込んでみましょう！
動くようになりましたか？

**動くようになった！**
**参考になった！**
という方は**いいね**・**ストック**・**コメント**や、**あなたのQiita記事にリンク**をつけてください:wink:

この世のHTMLとJavaScriptでChatGPT APIを使いたいすべての人が救われますように:angel:
画像生成AIの魅力: 新しい世界を創造する驚くべき技術【Stable Diffusion】

お疲れ様です。

Hiroです。

![00003-1907768106.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194974/5dae3eeb-7193-ba30-f06e-010ac94c02ae.png)

![00001-3887328114.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194974/377bc30b-ec1b-3b33-0a1c-b2b057ecb9a4.png)

![00000-2084901629.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194974/1a633171-68a1-537b-60b9-41cd8475e134.png)


↑の画像はすべて私が作ったものです。

これで私もプロンプトエンジニアです！！（豪語ｗ）



ほんとすごいですよね。。こんな世界が来るとは。。

まずはStable Diffusionを試してみました。

せっかくなので、やり方をお知らせします。

↓　やり方

まず、下記URLからGoogle Colaboratoryにアクセスし、アップロードのタブを選択します。
https://colab.research.google.com/?hl=ja



次に下記GitHubから「JapaneseDollLikeness_LoRA.ipynb」をダウンロードします。
https://github.com/nolanaatama/sd-1click-colab


Code → Download ZIPと選択し、PCに保存後解凍してください。

解凍したフォルダの中にある「JapaneseDollLikeness_LoRA.ipynb」を、Google Colaboratoryのアップロードの中にドラッグアンドドロップします。

下記のような画面が開くので、まずは「Setup the web ui」の欄にある実行ボタンをクリックします。

処理が終わるまで（URLが2つ現れるまで）待った後、もう一度「Setup the web ui」の欄にある実行ボタンをクリックして処理を停止させます。

その後実行ボタンを右クリックして、「出力を消去」を選択します。

最後に、「Load the LoRA & launch the web ui」の欄にある実行ボタンをクリック。

処理が終わるまで待ち、表示されるpublic URLをクリック。

これでStable Diffusionが起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194974/702e7881-9a6d-9361-d12c-bdb81891b237.png)


「Stable Diffusion」起動後、Show extra networkのボタンを押し、LoRAのタブでJapaneseDollLikenessを選択して、実行します。

そうすると、画像が出てきます。


いや、これやばいですね。

ChatGPTと組み合わせたりしたらもっと面白くなりそう。

今日は以上です。



↑　の説明は、下記のサイトを参考にしています。

https://ishikawatsukasa.com/


https://yuuyuublog.org/

また、あくまで2023/04/29時点の情報で作成しています。

今後諸々改定などで利用できないこともありますので、お試しになりたい方は、他のサイトをご参考にされてください。

※こちらのサイトは試してみた、例のみでして、作成できることを保証するものではございません。あらかじめご了承ください。

また、利用については今後慎重に取り扱わねばという気もしますので、今後は注意が必要そうです。
WSL2に固定のIPを追加する

WSL2のIPアドレスは再起動すると変わってしまうため、疑似的に固定IPを使用する方法を備忘録として残しておく。

## IP追加手順（手動）
以下の手順をPowerShellで実行する。（PowerShellは管理者として実行すること。）
まず、InterfaceIndexの確認。
```powershell
Get-NetAdapter -IncludeHidden
```

結果から以下の行を見つける。ifIndexが必要。
```powershell
Name                      InterfaceDescription                    ifIndex Status       MacAddress             LinkSpeed
----                      --------------------                    ------- ------       ----------             ---------
vEthernet (WSL)           Hyper-V Virtual Ethernet Adapter             20 Up           xx-xx-xx-xx-xx-xx        10 Gbps
```

以下のコマンドでIPアドレスを追加する。IPアドレスは任意でOK。InterfaceIndexは上で確認したものを設定する。
```powershell
New-NetIPAddress -IPAddress 172.29.3.50 -PrefixLength 24 -InterfaceIndex 20
```
```powershell
IPAddress         : 172.29.3.50
InterfaceIndex    : 20
InterfaceAlias    : vEthernet (WSL)
AddressFamily     : IPv4
Type              : Unicast
PrefixLength      : 24
PrefixOrigin      : Manual
SuffixOrigin      : Manual
AddressState      : Tentative
ValidLifetime     :
PreferredLifetime :
SkipAsSource      : False
PolicyStore       : ActiveStore

IPAddress         : 172.29.3.50
InterfaceIndex    : 20
InterfaceAlias    : vEthernet (WSL)
AddressFamily     : IPv4
Type              : Unicast
PrefixLength      : 24
PrefixOrigin      : Manual
SuffixOrigin      : Manual
AddressState      : Invalid
ValidLifetime     :
PreferredLifetime :
SkipAsSource      : False
PolicyStore       : PersistentStore
```

ipconfigで確認。IPv4 アドレスが追加されている。
```powershell
ipconfig
```
```powershell
Windows IP 構成

イーサネット アダプター vEthernet (WSL):

   接続固有の DNS サフィックス . . . . .:
   リンクローカル IPv6 アドレス. . . . .: fe80::97d2:449d:4467:e66c%20
   IPv4 アドレス . . . . . . . . . . . .: 172.29.3.50
   サブネット マスク . . . . . . . . . .: 255.255.255.0
   IPv4 アドレス . . . . . . . . . . . .: 172.29.48.1
   サブネット マスク . . . . . . . . . .: 255.255.240.0
   デフォルト ゲートウェイ . . . . . . .:
```

## IP追加手順（自動）
上記手順を以下のようなps1ファイルとして保存し、タスクスケジューラなどでPC起動時に自動実行するように設定する。
こうすることで"172.29.3.50"を固定IPのように使用することが可能となる。
（タスクスケジューラへの設定は「タスクスケジューラ ps1」などでググれば出てくる。）
```powershell:AddIPAddress.ps1
New-NetIPAddress -InterfaceIndex 20 -IPAddress 172.29.3.50 -PrefixLength 24
```

## 削除手順
ちなみに、再起動しなくとも以下のコマンドで追加したIPを削除できる。
```powershell
Get-NetIPAddress -IPAddress 172.29.3.50 | Remove-NetIPAddress
```
【PyTorchコツ】テンソルのデバイスが異なるエラーが出るときは、計算相手と同じデバイスに送る


# TL;DR
PyTorchでForward/Backward処理を記述するとき、テンソルを新しく生成する場合は、計算相手と同じデバイスを設定するとよいです。

# 課題
PyTorchでForward/Backward処理を書いてるとき。

テンソル同士の演算で...
```python:例
v2 =  torch.tensor(v2).clone().detach()
torch.bitwise_not(torch.bitwise_xor(v1, v2))
```

以下のようなエラーに遭遇することがあります。

```bash:エラー
RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu!
```

## 原因
演算対象の２つのテンソル`v1`, `v2`が異なるデバイス（CPUとGPU）に存在するのが原因です。

## 対応

PyTorchでのdeviceの扱いは、初期化時に実行対象のデバイスを指定するのがよく見かける対応です。
```python:実行対象デバイスを指定
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
a = torch.tensor([1., 2.]).to(device)
```

しかし、Forward/Backward処理はモデル定義のコードなので、記述時点ではどのデバイスで実行するのか分かりません。

そこで、Forward/Backward中に作成するテンソルは、`.to(v1.device)`を付けて計算相手と同じデバイスに送るようにすると良いです。

```python:修正した例
v2 =  torch.tensor(v2).clone().detach().to(v1.device)
torch.bitwise_not(torch.bitwise_xor(v1, v2))
```

これで、モデル定義にデバイスを明示せずに２つのテンソルを同じデバイス上で計算することができるようになりました。
yieldってやつがよくわからないので調べてみた

`yield`ってやつがよくわからないので動かしてみた

### 基本形
```ruby
def my_method
  p 'my_method called'
  res = 0
  yield res # <- ブロック変数に格納される
  p 'my_method done'
end

my_method do |res_from_yield|
  p 'in block'
  p res_from_yield # <- yieldに渡された値が入る
end

# 出力
# "my_method called"
# "in block"
# 0
# "my_method done"
```
実行順
1. `my_method`を呼ぶ
2. `my_method`内、通常通り上から順番に実行される
3. `yield` がいたらblock内の処理を実行する
    `yield 値`とするとblockに値を渡す
4. blockの処理が終わったら`my_method`に帰ってくる 

### 複数の引数を渡す
```ruby
def my_method
  p 'my_method called'
  res  = "res"
  res2 = "res2"
  yield res, res2
  p 'my_method done'
end

my_method do |res, res2|
  p 'in block'
  p res, res2
end

# "my_method called"
# "in block"
# "res"
# "res2"
# "my_method done"
```

### キーワード引数みたいのはハッシュにして渡すのがよさそう
```ruby
def my_method
  yield({ message: "Hello, World!", count: 3 })
end

my_method do |options|
  puts "The message is: #{options[:message]}"
  puts "The count is: #{options[:count]}"
end

# The message is: Hello, World!
# The count is: 3
```

### スコープは普通の関数と同じ
[goのクロージャ](https://go-tour-jp.appspot.com/moretypes/25)のような挙動ではないので、以下のコードは`0, 1, 2...`となるわけじゃない
```ruby
def my_method
  res = res || 0
  yield res
  res += 1
end

3.times do
  my_method do |res_from_yield|
    p res_from_yield
  end
end

# 出力
# 0
# 0
# 0
```

当たり前だがインスタンス変数に置き換えてやればやりたいことはできる
```ruby
def my_method
  @res = @res || 0 # <- インスタンス変数に置き換える
  yield @res
  @res += 1
end

3.times do
  my_method do |res_from_yield|
    p res_from_yield
  end
end

# 出力
# 0
# 1
# 2
```

### 用途を考えてみた
異なる種類のデータを同じ関数で柔軟に処理できる
やっぱり普通の関数でもよいきがしますね
```ruby
def my_method(data)
  if data.is_a? Array
    data.each do |item|
      yield item
    end
  elsif data.is_a? Hash
    data.each do |key, value|
      yield key, value
    end
  else
    yield data
  end
end

# 配列を処理するブロックを渡す
my_method([1, 2, 3]) do |item|
  puts "item: #{item}"
end

# ハッシュを処理するブロックを渡す
my_method({ name: "Alice", age: 30 }) do |key, value|
  puts "#{key}: #{value}"
end

# 単一の値を処理するブロックを渡す
my_method("Hello, World!") do |data|
  puts data
end

```

### 感想
賢くないので`yield`は直感的に理解できなくて嫌いです
良い使い道があれば是非コメントしてください
HTTP/3ってなんだ？

## "HTTP"って何？
> HTTPはプロトコルの一つです。プロトコルとは、通信ルールのことです。ブラウザやWebサーバはHTTPという通信ルールにのっとりやりとりを行います。通信ルールにより、開発者が異なる多くのソフトウェアどうしがきちんと通信できます。

HTTPとは、インターネットにおける通信ルールのことです！

具体的には、通信するデータに含まれる
```
* h2h3 [:method: GET]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: example.com]
* h2h3 [user-agent: curl/7.87.0]
```
こういうメッセージの意味だったり、そもそもどういった形でデータを扱うのか、ということが定義されています！

データの形については、HTTP/1.1ではテキスト形式ですが、HTTP/2とHTTP/3ではバイナリ形式（0と1の組み合わせ）だそうです。

## HTTPの歴史
2022年6月からは、HTTP/3がインターネットの標準仕様となっています！
例えば、chrome検証ツールのネットワークタブを開いてみると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2483874/a825d895-5d0e-1f48-c9b9-8286490381cb.png)
Protcolのカラムに`h3`と表示されます。これは、HTTP/3の通信ルールを使っているということです！

### HTTP/1.1の課題
> 2010年ごろより、Webがより発達し、各ページの見た目や振る舞いがよりリッチになっていきました。それに伴いWebページの表示に必要なファイル数は多くなり、ブラウザとサーバでやりとりされる通信の数も増えました。そういった中で、HTTP/1.1が抱える問題に直面します。

HTTP/1.1では連続して1,2,3,4とリクエストを送った際、レスポンスも1,2,3,4と順番に返す必要がありました。そのため、あるレスポンスの生成に時間がかかると、**後続のレスポンスの待ち状態**が発生してしまうという問題がありました。これを、Head-of-Line-Blocking問題といいます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2483874/60ecf2ed-3aca-6ea6-3cb2-4615125df973.png)

### HTTP/2
HTTP/2では、リクエストとレスポンスの一対のペアを、他のペアに依存しないように並列的にやり取りすることができます！

実際にはリクエスト(レスポンス)を並列に送ることはできないのですが、各リクエスト（レスポンス）を細切れにし、フレームという単位で識別することによって、あたかも並列的に通信しているかのようになります。これで、**リクエストの順番通りにレスポンスを返さなくてもよくなりました！**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2483874/435b4fdc-f95a-6212-3e5c-e80baa302eb5.png)
ここで、図に出てくるTCPコネクションとは、HTTPよりも下位（より物理に近い？）プロトコル(=通信ルール)です。HTTPはアプリケーション層と呼ばれるソフトウェアに関するプロトコルですが、TCP(Transmission Control Protocol)はトランスポート層と呼ばれる、データの転送制御に関するプロトコルです！

### HTTP/2の課題
HTTP/2は、**下位のプロトコルであるTCP**に課題がありました！
> TCPでは、送信者がパケットを送信した順番どおりに、受信者はパケットを処理する必要があります。そのため、パケットロスが発生した場合は、送りなおしてもらう必要があります。パケットの順番の入れ替わりが発生した場合は、もとの順番に戻す必要があります。パケットロスやパケットの順番の入れ替わりが解消されるまでは、処理は待ちとなります。

パケットとは、通信しやすくするためにデータを細切れにしたものです。（細切れが多くてややこしいですね、、）

すなわち、データが正しく順番通りに送られてこなければ、結局後続のレスポンスが待ち状態に入ってしまう、Head-of-Line-Blocking問題がありました。

ちなみに、パケットロスってどのくらい起こるのか調べてみたところ、、
> 通信事業者のIP通信サービスが満たすべき国際標準規格 （Y.1541） では，上限が 0.1% と規定されている

結構日常的に起こっていそうですね！

### HTTP/3
さて、TCPのHead-of-Line-Blocking問題を解決するために、HTTP/3ではトランスポート層に新しく開発されたQUICというプロトコルを使います！
**QUICは、パケットロスやパケットの順番の入れ替わりが起きても、受信者が受け取った順番にデータを処理**できます。これにより、リクエストとレスポンスのペアは、他の通信が上手くいかなくても待ち状態になることなく、Webページを早く表示することができます!


あくまで、QUICはトランスポート層の新たなプロトコルです。HTTP/3はQUICを活かすように設計されたアプリケーション層のプロトコルで、他のレスポンスに依存しない処理優先度のルールなど、届いたパケットから処理できるような工夫がされています！

## まとめ
HTTP/2ではHTTPメッセージを並列的にやりとりできるようになり、HTTP/3ではQUICという新たなプロトコルを活かすように届いたパケットからリクエストを処理できるようになりました。2022年6月からはHTTP/3が標準化され、従来よりも高速な通信が可能になりました！



## 参考文献
https://gihyo.jp/admin/serial/01/http3/0001
画像もこちらから引用させていただきました。
Open Liberty の公式サイトを使いこなそう

## はじめに
Open Libertyは、現行世代のJavaフレームワークでモノリシックからマイクロサービスまで幅広いアプリケーション・アーキテクチャに対応しています。
Open Liberty の[公式サイト](https://openliberty.io/)は、英語表記で公開されています。
ブラウザの翻訳機能で多くをカバーできるとはいえ、英語であることで参照に二の足を踏む開発者もいるのではないでしょうか。

そこで「公式サイトに記載されていること」の全体像を整理したうえで、サイトの参照・活用に慣れていければと思います。
## 目次の構成
23年4月時点のメニュー構成は次のようになっています。
![Liberty01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536604/c05ee47f-9c26-1099-1379-8ded262e5a2a.png)

## Get Started
### Create a starter application
**指定のプロジェクト構成を生成してダウンロードできます**

構築したいアプリケーションの前提条件や名称を指定することで、最小のプロジェクトを作成してダウンロードすることができます。
HelloWorldレベルの処理であれば、Javaがインストールされていれば多少編集することですぐに実行が可能となっています。
Windowsでは、
- JDKのインストール
- コマンドプロンプトで展開フォルダにcd
- mvnw liberty:dev

で、localhost:9080
にアクセスが可能になります。
EEベースで実行する場合、初回はライブラリのダウンロードが走るため10分くらいは時間がかかるかと思います。

まずは起動するところを見届けたい！という方はこちらから始めるとよいかと思います。

Spring InitializrやQuarkusのStartCodingのように、必要な機能に合わせてDependencyを編集する機能はないようです。
### Download package
**Liberty本体をダウンロードできます**

開発プロジェクトで開発リソースを管理しておきたい場合や開発環境のネットワーク事情などで予め取得しておく場合などに必要かと思います。
ダウンロードサイズは、23.0.0.3でJakartaEE10パッケージは114MB、MicroProfile6は52MBとなっています。

## Guides
**コードの書き方に困ったときはこちら**

開発するために必要な知識を、サンプルコードを中心にカテゴリ別にリストしています。
解決したい内容に応じてコンパクトに実装手順がまとまっているため、長大なマニュアルを読むよりクイックな問題解決が期待できます。
把握するのに必要な目安時間が記載してあり、ほとんどが30分以内となっており、集中が途切れない範囲で読み切れるボリュームになっています。
個人的には表記の時間は少々タイト（もうちょっと時間が必要）と思っていますが...

網掛けされた部分は、下スクロールで読み進めると必要な個所でサンプルコードが表示されます。

### RUN ON CLOUD
**ローカルに環境がなくてもコードを試すことができます**

サンプルコードを、リモートのコンテナ環境で記載どおりに動かして確認することができるようになっています。
IBM Developer Skills Network の登録を行うと次のようなサンドボックス環境にアクセスすることができます。
![Liberty02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536604/7150a3f5-d65d-c200-c618-0217393045c6.png)
左に記載されている解説はブラウザ翻訳（Chrome）では日本語変換できませんでした。
ただ内容はGuidesに記載されたものと同内容のようなので、こちらで日本語変換すれば読み進めることは可能です。

## Docs
**深く理解したい人はこちら、APIドキュメントもあります**

こちらはフレームワークの活用方法を主体に記載されたドキュメントです。

左ペインの最上段に、対象バージョンを指定するプルダウンがあるため、こちらが適切に選択されていることを確認しましょう。

フレームワークの構造や考え方を中心に記載されています。サンプルコードの類はあまりありません。

利用する立場によって、主に参照する章は次のあたりかと思います。
| 立場 | 章 |
|:-:|:-:|
|  一般開発者 |  BASICS、DEVELOPMENT |
|  アーキテクト | BASICS、DEVELOPMENT、SECURITY、OPERATIONS  |
|  オペレーション担当 |  DEPLOYMENT |

開発者がお供にするべきAPIリファレンスは、左ペインメニューの最下段にあるREFERENCEに含まれています。日本語変換するとかえって読みづらくなるため英語表記のまま利用するほうがいいかもしれません。

## Support
**コミュニティサポートはStack Overflowを見てみよう**

有償サポートのご案内と、4つのコミュニティサポートが記載されています。
日本で馴染みが深いのはTwitterですが、インタラクティブに問題解決するのはStackOverflowが使いやすいでしょう。

## Blog
**リリースノートの色彩が濃い目**

管理者からのリリース状況などの通知が主体です。Posts in other languagesから日本語を選択いただくと、日本からの投稿をピックアップできます。

## まとめ
* 動くソースが簡単に取得できる
* 気になるところをピンポイントで確認する

と、すぐに動かせるということに拘ったサイト構成になっていると思います。
個人的には、ガイドの説明が縦長すぎて全体をつかみづらいので、右側のコード部を見やすくレイアウトできないかなとは思いますが...

うまく使いこなしていきたいと思います。
Azure Logic Apps の Twitter コネクターを BYOA に変更したときにハマったとこ

# 結論
Azure Logic Apps で Twitter API を叩いて 403 エラーになったら、**Twitter Developer Portal で App を作り直してみよう。**

# 背景
Twitter の Developer アカウント作成のハードルが下がったようなので、Azure Logic Apps で使っているコネクターの認証を `Use default shared application` から `Bring your own application(BYOA)` に変えてみようと思いました。時を同じくして、Microsoft 様は `Use default shared application` のサポートを終了したようです。
Twitter の Developer アカウント作成などは先達に任せるとして（とっても簡単でした。最終的に一番ためになった記事を末尾にリンクします。）、僕が BYOA に移行したときにハマったとこと解決方法を書きます。

### 参考

https://learn.microsoft.com/en-us/connectors/twitter/

※2023/05/01現在はまだ記載されていますが、Logic Apps では `Use default shared application` が選択できなくなっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/8b425f6f-d1a7-57a3-6ab4-588c6defe47a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/18d298ad-6158-c058-c02f-b97bae313923.png)

# 症状
BYOA のコネクター設定はうまくできたように見えるのですが、アクションを実行すると 403 エラーになってしまいました。メッセージを読むと、以前のプラン？の話をしているようです。（現在は Free/Basic/Enterprise）

```json
{
  "status": 403,
  "message": "You currently have Essential access which includes access to Twitter API v2 endpoints only. If you need access to this endpoint, you’ll need to apply for Elevated access via the Developer Portal. You can learn more here: https://developer.twitter.com/en/docs/twitter-api/getting-started/about-twitter-api#v2-access-leve\r\nclientRequestId: ＜略＞\r\nserviceRequestId: ＜略＞",
  "error": {
    "message": "You currently have Essential access which includes access to Twitter API v2 endpoints only. If you need access to this endpoint, you’ll need to apply for Elevated access via the Developer Portal. You can learn more here: https://developer.twitter.com/en/docs/twitter-api/getting-started/about-twitter-api#v2-access-leve"
  },
  "source": "twitter-je.azconn-je-001.p.azurewebsites.net"
}
```

# 解決方法

Twitter Developper Portal で App を作り直したところうまくいきました。アカウント作成時に作られる App だとうまくいかないようです。まったく同じ設定でも作り直したところうまく動作しました。

### 参考

https://blog.ciaops.com/2023/04/27/connect-power-automate-to-twitter-using-a-bring-your-own-app-approach/

神です。この通りやれば全部解決。
【Docker】MySQLをコンテナで起動するまで

## やりたいこと
Docker上でMySQLのサーバーを立ち上げ、ターミナル上で動作確認をしたい。

## Dockerfileを用意する
適当に新規ディレクトリを作成し、Dockerfileを新規作成します。

```dockerfile:Dockerfile
# 最新バージョンのMySQLイメージを指定
FROM mysql:latest 

# ルートユーザーのパスワードを"rootpass"として環境変数を定義
ENV MYSQL_ROOT_PASSWORD=rootpass
```

## コンテナを起動する
### コンテナイメージを作成
Dockerコンテナを起動するためには、DockerfileからDockerイメージをビルドする必要があります。

```terminal
docker build -t mysql-test .
```


### コンテナを起動
```terminal
docker run mysql-test -d
```

## 動作確認をする
```terminal
docker ps
```
このコマンドで起動中のコンテナを一覧表示させます。
```terminal
CONTAINER ID   IMAGE        COMMAND                  CREATED          STATUS          PORTS                 NAMES
ffb34b43b73b   mysql-test   "docker-entrypoint.s…"   22 seconds ago   Up 21 seconds   3306/tcp, 33060/tcp   youthful_noyce
```

```terminal
docker exec -it ffb34b43b73b /bin/bash
```

```terminal
bash-4.4# 
```

```terminal
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.33 MySQL Community Server - GPL

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
```

```terminal
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)
```