OmniAICreator/Qiita-1.07M huggingface dataset:
【Flutter】Firebase Authenticationを使ってログイン/ユーザー登録画面を作成する(その2)

# はじめに
【Flutter】Firebase Authenticationを使ってログイン/ユーザー登録画面を作成する(その1)の続きです。
前回はただ、TextFieldを実装しただけですが、これからFirebaseの連携を始めていきます。
引き続きVSCodeのMac版を利用していますので、AndroidStudio利用の方は適宜読み替えて行ってみてください。
　いつから変わったのかわからないのですが、久しぶりにFirebaseAuthを実装しようと今まで通りにやってみたところ、iOSは上手くったのですがなぜかAndroidでログアウトするとクラッシュするという現象がでてしまったので、いろいろ調べたらFlutterFireで自動化できるらしいので、これを機にやってみようと考えた次第です。

## 更新履歴
2024.1.18 新規投稿
2024.2.16 誤字修正

## FlutterプロジェクトとFirebaseプロジェクトの連携設定 
 1. Firebaseプロジェクトでプロダクトのカテゴリ>構築>Authenticationを選択します。
    ![firebaseAuth設定0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/3cd828da-1360-12fa-0c2f-b10da0de818c.png)
2.「始める」ボタンをクリックします。
    ![firebaseAuth設定1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/88bf0b21-f699-b70c-cb67-90fe6f478678.png)
3.　次の画面で「メール/パスワード」を選択します。
    ![firebaseAuth設定2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/49f1544a-7e44-b72a-f924-ef1335cedd53.png)
    4. 次の画面で「メール/パスワード」右横のスイッチを有効にします。
    ![firebaseAuth設定3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/2810e6eb-7c33-03f3-524f-e5009e88f5cf.png)
    5.　Firebase側のメール/パスワードのログイン設定は完了です。

### FlutterFire CLIをインストール(インストール済みの場合はスキップ)
   
 1. FlutterFire CLIがグローバルにインストールされているか確認する
    ```
    % flutterfire --version
    ```
2. インストールされていない場合はインストール
    ```
    % dart pub global activate flutterfire_cli
    ```
3. .zshrcファイルを開く
    ```
    % open ~/.zshrc
    ```
4. 以下をzshrcファイルに追加する
    ```
    export PATH="$PATH":"$HOME/.pub-cache/bin"
    ```
4. .zshrcを更新した時に、ターミナルを再起動しただけではシェルの設定は反映されません。
    必ず以下のコマンドを叩いて、シェルの設定を反映させましょう。
    ```
    % source ~/.zshrc
    ```
4. インストールできているかどうか確認します。
    ```
    % flutterfire --version
    ``` 
### FlutterとFirebaseの連携設定をする
1. 作成したプロジェクトのディレクトリ内に移動します
    ```
    % cd fb_auth_login_sample
    ```
1. FirebaseCLIでFirebaseにあらかじめログインしておきます
    ```
    % firebase login
    ```
1. firebase_coreのパッケージをインストールします
    ```
    % flutter pub add firebase_core
    ```
1. 同じくアプリのルートで以下のコマンドでfirebaseの環境設定します。
    ```
    % flutterfire configure
    ```
1. Firebaseで作成したプロジェクト一覧が表示されるので、上下キーで移動して、該当するプロジェクト名のところでリターン
1. 次にFlutterで作成するプラットフォームを必要に応じて選択し、リターン(そのまま選択しなくてもOK)。
![flutterfireconfigure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/0dc21d47-45ef-ded5-b762-af655fda1bc5.png)

7. Firebaseのプロジェクト画面で以下のようになっていれば成功です!![FirebaseProject.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/1a117b4f-4b0c-764e-2dbb-37043eccca68.png)

次はfirebase authenticationの実装です。
https://qiita.com/yoshikoba/items/9a58783b71f3c353d6fe

# 参考サイト
https://www.flutter-study.dev/firebase-app/authentication
Python threadingの使い方

Python threadingの使い方の備忘録です。

ビギナー向けの説明としてよく見かけるコード：
```py
t1 = threading.Thread(target=<関数名>)
t1.start()
```

このthreading.Threadはクラスにも適用できます。
以下はMyTestThreadクラスのthread1とthread2がメッセージを交互に出力するサンプルです。
```py
import threading
import time

class MyTestThread(threading.Thread):
    def __init__(self, threadMessage) :
        super().__init__()  # おまじない
        self.myMessage = threadMessage

    def run(self):
        while True:
            print(self.myMessage)
            time.sleep(1)
        
if __name__ == "__main__":
    testThread1 = MyTestThread('thread1')
    testThread2 = MyTestThread('thread2')

    testThread1.start()
    testThread2.start()
```

`super().__init__()`を呼び出さないと、start()時に例外が起きます。

組み込み業界で生きてきたこともあり、スレッドの優先度指定方法が気になり調べてみたところ、Pythonの世界では組み込み用タスクのようなスレッド優先度は無いという衝撃的な結果となりました。

まあ、RTOSで使う言語でもないし、優先度なんて気にしないのかな。

---
当初、super()を`super(MyTestThread, self).__init__()`と記述したところ、引数は不要と教えて頂きました。
親切にコメントくださった方、ありがとうございました。
ループメニュー1を解いていく4

https://paiza.jp/works/mondai/loop_problems/loop_problems__seq_reverse

### Python

```py
N = int(input())
A = list(map(int,input().split()))
# reversed関数を使うなら
print((*reversed(A)),sep="\n")
# for文を使うなら
for i in range(N-1,-1,-1):
    print(A[i])
```

### PHP
$Aはtrimしないと後ろに改行がくっついたままexplodeしてしまうので注意。

```PHP
<?php
    $N = trim(fgets(STDIN));
    $A = explode(" ",trim(fgets(STDIN)));
    for($i=$N-1; $i>=0; $i--){
        print($A[$i] . "\n");
    }
    //reverse関数を使うならこれでも。でもぶっちゃけ上の方が早い
    $A = array_reverse($A);
    for($i=0; $i<=$N; $i++){
         print($A[$i] . "\n");
    }
    
?>

```
https://paiza.jp/works/mondai/loop_problems/loop_problems__kuku_step1


### Python

```py
for i in range(1,10):
    if i < 9:
      print(i * 8, end=" ")
    else:
        print(i * 8)
```

### PHP

```PHP
<?php
    for($i=1; $i<=9; $i++){
        if($i < 9){
            print($i * 8 . " ");
        } else {
            print($i * 8 . "\n");
        }
    }
?>
```
【Vitest】Cannot read property 'details' of undefined と TypeError: env.window.matchMedia is not a function

## 背景
Vitest + Chakra UI + RTL + Next.jsでテストを実装したときに起きたエラーです。

## 解決策
```tsx:sample.test.tsx
import { ChakraProvider } from "@chakra-ui/react"

describe('Sample', () => {
  test('サンプルのテスト', () => {
    render(
        <ChakraProvider>
            <SampleComponent />
        </ChakraProvider>
    )
  });
});
```
ChakraProviderで囲むことでタイトルのエラーを解決することができます。しかしこれだけだと以下のエラーが出てしまします。
```
TypeError: env.window.matchMedia is not a function
```
このエラーはvitest.config.tsで定義したsetupFilesに以下を追加することで解決します。
```setup.ts
global.matchMedia = global.matchMedia || function () {
  return {
    matches: false,
    addListener: vi.fn(),
    removeListener: vi.fn(),
  };
};
```

Chakra UIのuseBreakpointではwindowオブジェクトが使用されています。しかし、Node環境ではwindowオブジェクトをデフォルトでは利用することができないため、エラーが起きたということでした。
MySQL で AUTO_INCREMENT をリセットする

# はじめに
開発中に MySQL でテーブルの値の追加・削除を繰り返していると AUTO_INCREMENT の値がどんどん増えていくので、たまにリセットしたくなります。
この記事では、そのようなときに MySQL で AUTO_INCREMENT をリセットする方法について記載します。

# 開発環境
開発環境は以下の通りです。

- Windows11
- MySQL 8.0.33

# 方法1：TRUNCATE を利用する
TRUNCATE を利用すると、テーブル内の全てのレコードを削除することができ、 AUTO_INCREMENT もリセットされます。

```powershell
TRUNCATE TABLE tbl_name;
```

ただ、TRUNCATE では、ロールバックができないため。利用時は注意が必要です。

:::note
DELETE でもテーブル内のレコードを削除できますが、AUTO_INCREMENT はリセットされません。
:::

# 方法2：DELETE と ALTER TABLE を利用する
上記の通り TRUNCATE では、ロールバックができません。また、DELETE だと AUTO_INCREMENT はリセットされません。
しかし、DELTE を実行した後、ALTER TABLE を利用すれば、 AUTO_INCREMENT をリセットすることができます。

```powershell
DELETE FROM tbl_name;
```

```powershell
ALTER TABLE tbl_name AUTO_INCREMENT = 1;
```

# まとめ
- 何も気にせずはやく削除したい：TRUNCATE を利用する
- ロールバックできるようにしておきたい：DELETE と ALTER TABLE を利用する

# 参考
- [13.1.9 ALTER TABLE ステートメント](https://dev.mysql.com/doc/refman/8.0/ja/alter-table.html)
- [13.1.37 TRUNCATE TABLE ステートメント](https://dev.mysql.com/doc/refman/8.0/ja/truncate-table.html)
- [13.2.2 DELETE ステートメント](https://dev.mysql.com/doc/refman/8.0/ja/delete.html)
Response code 403 (Forbidden) : DevOps Center




+ [what dan I do wit h error: Response code 403 (Forbidden)](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007UvNMy)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/813ac9c9-346d-1948-94dd-9a8e698ab50d.png)

:::note
It is just an authentication issue. Indeed I changed my password on this sandbox a few days ago. It appears that the OAuth credential is therefore wrong. 

Go to Setup > Named Credentials. 

+ Find the one related to your sandbox.
+ Delete the entry having your name.
+ Return to Devops Center and on the environment click on the link to the sandbox. You can now + connect and enter the new password. 
+ Now the promotion can start.


I don't say that it is the same issue for everyone, but it resolved my 403 issue. 


[Edit : note that I was still able to open the environment from Devops Center!] 
:::
 


+ [Response code 403 (Forbidden)](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007X6ZJV)
default unable to prepare context: path "/path/to/Dockerfile" not found というエラーへの対処

# はじめに
docker composeで環境構築を試みたところ，以下のようなエラーが発生した．

```bash: error
docker: default unable to prepare context: path "/path/to/Dockerfile" not found
```

ディレクトリ構成などは以下の通り．

```bash: tree
.
├── data
├── docker-compose.yml
└── src
    └── Dockerfile.src
```

```docker: docker-compose.yml
version: '3'

services:
  src:
    build: ./src/Dockerfile.src
    container_name: src
    tty: true
    volumes:
      - ./src:/home/workdir

  mongo:
    image: mongo:7.0.5-rc0-jammy
    ~~ 省略 ~~

networks:
  dbnet:
    name: my_dbnet
```

```dockerfile: Dockerfile.src
FROM ubuntu:22.04

WORKDIR /home/workdir

RUN something_to_do
```


# まずは検索
検索したところ，以下の記事を発見．

https://stackoverflow.com/questions/72138703/docker-compose-building-back-unable-to-prepare-context-unable-to-evaluate-symli

これに従って，`docker-compose.yml`を編集．

```docker: docker-compose.yml
version: '3'

services:
  src:
    build: 
      context: ./src
      dockerfile: ./Dockerfile.src
    container_name: src
    tty: true
    volumes:
      - ./src:/home/workdir

  mongo:
    image: mongo:7.0.5-rc0-jammy
    ~~ 省略 ~~

networks:
  dbnet:
    name: my_dbnet
```

これでエラーが解消．


# 最後に
何故，上記の操作でエラーが解消できたのかは不明です．
調べてみたのですが，元のように`build`をしている記事もあり，何が根本的な原因であるかが掴めませんでした．（予想：明示的に指定するか，そうでないかの違い？）
応用情報技術者試験　キーワード

1. ブルートフォース　　Brute-force 総当たり攻撃
1. SQLインジェクション　　SQL injection
1. NAS(Network Attached Storage)　　　TCP/IPのコンピュータネットワークに直接接続して使用するファイルサーバ
1. エスクロウ　　　Escrow　　第三者への預託の意味
1. ページフォールト Page fault 
1. Cross compiler クロスコンパイラ 
> A cross compiler is a compiler capable of creating executable code for a platform other than the one on which the compiler is running. For example, a compiler that runs on a PC but generates code that runs on Android smartphone is a cross compiler.

1. CSMA/CD(搬送波感知多重アクセス／衝突検出)    イーサネットが採用している通信手順で、主に媒体共有型ネットワークで発生する伝送路上での衝突を前提とした通信制御方式です。
1. OCSP(Online Certificate Status Protocol)は、リアルタイムでディジタル証明書の失効情報を検証し、有効性を確認するプロトコルです。
1. Delphi method デルファイ法は、技術革新や社会変動などに関する未来予測においてよく用いられ、多数の専門家が他の専門家の意見も相互に参照しながら意見交換をし、最終的に意見の収束をしていく手法です。
1. ヒュリスティックス [heuristics]  いつも正解するとは限らないが、おおむね正解するという直感的な思考方法で、たとえば、服装からその人の性格や職業を判断する。ある程度正解に近い解を見つけ出すための経験則や発見方法のことで、「発見法」とも呼ばれます。
1. DHCPリレーエージェント　DHCP Relay Agent　
> DHCPリレーエージェント機能により、DHCPサーバとDHCPクライアントが異なるサブネットに存在してもDHCPクライアントから受信したブロードキャストをユニキャストに変換して、DHCPサーバに転送します。現在では、ルータやL3スイッチのネットワーク機器でDHCPリレーエージェント機能を持たせるのが一般的。

1. 一意性制約 Unique Constraint
1. ストアドプロシージャ stored procedure
1. CRM(Customer Relationship Management)
1. SCM(Supply Chain Management)
1. トレーサビリティ　Produce traceability
1. トレンドチャート 【trend chart】
> プロジェクトの進捗を把握するために作成される図の一つで、費用と工程の消化度合いを表す折れ線グラフを予算と実績の両方について描画したもの。

1. メモリ・インターリーブ　memory interleave　：　複数のメモリ・バンク（memory banks）に対してほぼ同時にアクセスすることで、メモリ・サブシステムのデータ転送レートを高める
1. リトルエンディアン little endian
1. コンカレントエンジニアリング　concurrent engineering
1. ファジング(fuzzing)とは、検査対象のソフトウェア製品に「ファズ（英名：fuzz）」と呼ばれる問題を引き起こしそうなデータを大量に送り込み、その応答や挙動を監視することで(未知の)脆弱性を検出する検査手法です。
1. DNSラウンドロビン　Round-robin DNS
グラフが表示できない



+ [Won't let me add chart](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000PmLep)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/56a51e78-699a-44b8-9d92-2a64bb37ad93.png)

::: note
When creating a report you can display the report as a chart. Charts provide you and your users with a visual way to understand the data in your report. When creating a report however, users can find that the Add Chart icon is greyed out.

The reason why the Add Chart icon is greyed out is because a report must have at least one grouped field.


1. Click to open the report you would like to add a chart to
2. Click Edit on the right side of the screen
3. Click Outline on the left side of the screen
4. Under the Groups section, click within the lookup field titled Group Rows
5. Select a field that you would like to group your report by. Fields that are commonly grouped are the Owner fields.
6. Now that you have a grouped field, the Add Chart icon can be clicked and a chart added to your report
7. To edit the default chart that is added to your report after clicking Add Chart, click the gear icon on the top right corner of the chart and edit it as needed


https://help.salesforce.com/s/articleView?id=000389964&type=1 

:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/141c3982-2a66-ec69-ce9f-9a489fc6776e.png)

:::note
This is because you did not perform step 8.

1. Click Reports.
2. Click New Report.
3. Under Category, click All.
4. In Search Report Types, enter Discoveries and select Discoveries.
5. Then, click Start Report.
6. Click the Update Preview Automatically slider to switch it on.
7. In Add column, enter Link and then select Link to add it to the report. Similarly add the Notes column.
8. **In Add group, enter Type and then select Type to create a grouping.**
9. Click Save and save the report as follows:
+ Report Name: New Discoveries Report
+ Description: Summary of my career exploration discoveries.

 https://trailhead.salesforce.com/content/learn/projects/build-an-app-to-track-your-trailblazer-journey/create-a-report-a-report-chart-and-a-dashboard
:::


+ [In my New Discoveries report the Add Chart option is greyed out. In addition, the only type of widget that is available to me in the reports is a table. Can anyone assist?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007epkiv)

この画面の時のパターン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/e76c38a6-9671-bded-4ef5-ec4fecd8666e.png)


# レポートタイプにない

+ [For report creation, Discoveries is not seen in Report Type.](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000SWghl)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9fb302f7-1480-4202-b6d0-2c56751a5753.png)

:::note
Goto Setup --> Object Manager --> Discoveries  -->Details

Try enabling Allow Reports 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/93225210-3aec-4c7a-a00d-2b4f49a49c46.png)
:::
yolov5-obb インストール時のエラー「~ 'THC/THC.h': No such file or directory ~ 」の対処方法

yolov5-obbインストール時、`utils/nms_rotated`のセットアップを実施した際に以下のようなエラーが発生.

```
/usr/local/cuda/bin/nvcc -DWITH_CUDA -I/usr/local/lib/python3.10/dist-packages/torch/include -I/usr/local/lib/python3.10/dist-packages/torch/include/torch/csrc/api/include -I/usr/local/lib/python3.10/dist-packages/torch/include/TH -I/usr/local/lib/python3.10/dist-packages/torch/include/THC -I/usr/local/cuda/include -I/usr/include/python3.10 -c src/poly_nms_cuda.cu -o build/temp.linux-x86_64-cpython-310/src/poly_nms_cuda.o -D__CUDA_NO_HALF_OPERATORS__ -D__CUDA_NO_HALF_CONVERSIONS__ -D__CUDA_NO_BFLOAT16_CONVERSIONS__ -D__CUDA_NO_HALF2_OPERATORS__ --expt-relaxed-constexpr --compiler-options '-fPIC' -D__CUDA_NO_HALF_OPERATORS__ -D__CUDA_NO_HALF_CONVERSIONS__ -D__CUDA_NO_HALF2_OPERATORS__ -DTORCH_API_INCLUDE_EXTENSION_H -DPYBIND11_COMPILER_TYPE=\"_gcc\" -DPYBIND11_STDLIB=\"_libstdcpp\" -DPYBIND11_BUILD_ABI=\"_cxxabi1011\" -DTORCH_EXTENSION_NAME=nms_rotated_ext -D_GLIBCXX_USE_CXX11_ABI=0 -gencode=arch=compute_75,code=compute_75 -gencode=arch=compute_75,code=sm_75 -std=c++17
src/poly_nms_cuda.cu:4:10: fatal error: THC/THC.h: No such file or directory
    4 | #include <THC/THC.h>
      |          ^~~~~~~~~~~
compilation terminated.
error: command '/usr/local/cuda/bin/nvcc' failed with exit code 1
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/981f26a3-c7c5-8167-35e5-8fcb8e5fc8fb.png)

`nms_rotated`のコードが最新のcuda(今回試したのは,`cuda_12.2`)に対応していないらしい.
下記issueで最新バージョンのcudaに対応している`nms_rotated`をアップしてくれている方がいた.

https://github.com/hukaixuan19970627/yolov5_obb/issues/607#issuecomment-1763285095

エラー対策後の`nms_rotated`のリンクは[こちら](https://drive.google.com/file/d/1o4c0qxM8Jbdyy1TXlhs84Ae3czQCSYVp/view)

これを元の`yolov5/utils/nms_rotated`と入れ替えると上記エラーの対処ができる.
どうしても頭の中にJavaScriptが出てきてしまう中学生の話

どうもAtsu1209です。
私は中学生なのですが、ある授業の時どうしてもJavaScriptが頭の中に
出ててきてしまうので、それを記事にしました。

# 技術
中学校の技術の授業でフローチャートを勉強することになりました。
そこで、`条件分岐`のフローチャートが出てきました。

それを見た瞬間頭の中に１つの単語が出てきました。それは、
`if` JavaScriptのifがどうしても頭から離れなくなりました。
どうしてでしょうね。

# 以上
今回は短い記事ですが、共感できる方がいましたらぜひコメントとハート
よろしくお願いします。
では
EPPlus4.5.3.3 にてDrawings.xmlが自動でインデントされてしまう問題について

記事タイトルの内容で困ったのでメモと情報共有代わりに残します。
(更新の凍結したOSSを使う人間が私以外にいるかは不明ですが……)

# 問題
- EPPlus4.5.3.3(以下EPPlus)を使用した時、吹き出し、図形内にスペースを使うと自動で改行されてしまう。

# 対策
上記の問題はEPPlusのExcelDrawings.cs内のExcelDrawingsクラスのConstructor内の記述に、
```C#
_drawingsXml.PreserveWhitespace = false;
```
と記載されている事が原因でした。

これをtrueに変更すると自動で改行されなくなります。

# 詳細
PreserveWhitespaceは要素のコンテンツにある空白を保存するかどうかを示す値の取得設定をするプロパティです。[^1]

###### 読み込み時
true:空白は保存される。
false:重要な空白だけが保存される。

###### 保存時
true:ドキュメント内の空白は出力でも保存される。
false:出力に自動的にインデントを設定して保存する。

その為、ExcelDrawingsでPreserveWhitespaceがfalseだと、空白を消去され、xmlが整理(インデント、改行などが自動で設定)されてしまいます。

この変更をする事で何処かしらでエラーが起きるかもしれませんが、今のところは発生していません。
(気づいていないだけかも……)

[^1]:https://learn.microsoft.com/ja-jp/dotnet/api/system.xml.xmldocument.preservewhitespace?view=net-8.0
JavaScript documentオブジェクトの主なメソッド

# はじめに
JavaScriptでHTML要素を操作するのに使用するdocumentオブジェクトの，主なメソッドをアウトプットします．

# getElementById
指定したID属性を持つHTML要素を取得することができるメソッド．
#### 使用例 : input内のテキストを取得
```HTML:HTML
～～～

  <body>
    <input id="example" />
    <button onclick="onclickAlert()">表示</button>
    <script>
      const onclickAlert = () => {
        const inputText = document.getElementById("example").value;
        alert(inputText);
      };
    </script>
  </body> 
  
～～～
```

![input](https://lh3.googleusercontent.com/pw/ABLVV87IbQ9mkajBNXemFXF0aK0NyUNq_LJUyMnKBbDUD0qWTun0WvJ1Dr2QLHWFN6xPVR6nRm1qBJqK6UiKbd2aKp3EvCfyiurXkEjXvAIjO7takBo-SnrJHphIBizpXHcFjAso_mOLH6yC0AZrp5gM0et5=w274-h37-s-no-gm?authuser=0)

```javascript:「表示」ボタン実行結果
aaa //アラートに表示される
```
addEventListenerメソッドを使い，`document.getElementById("対象要素のid").addEventListener("click",クリック時の処理)`とすることで，要素をクリックしたときに実行する処理を設定できる．

# createElement
HTML要素を生成することができる．

#### 使用例1
```javascript
const li = document.createElement("li");
console.log(li);
```
```html:実行結果
<li></li>
```
生成した要素にクラスを設定するには，`className`プロパティを使用する．

#### 使用例2
```javascript:JavaScript
const li = document.createElement("li");
li.className = "list";
console.log(li);
```
```html:実行結果
<li class="list"></li>
```

# appendChild
JavaScriptで要素の階層構造を作るのに使用．対象要素に子要素を追加する．

#### 使用例
```javascript:JavaScript
const div = document.createElement("div");
const p = document.createElement("p");
p.className = "child";

div.appendChild(p);

console.log(div);
```
```HTML:実行結果
<div>
    <p class="child"></p>
</div>
```
【2024年】Qiitaの投稿始めます

## はじめに
こんにちは。現在バンクーバーで未経験からエンジニア就職を目指している@JamesCroissantです。今はReact×TypeScriptを利用したフロント周りの開発中心の勉強をメインで行なっています。

## 決意
2024年からReact, Next.js, TypeScirptの開発に関する記事を書いていきます。

## きっかけ
去年の夏頃から独学で学習を進めていて、フロント周りの技術の急速な変化により、古く使い物にならない情報が新しい情報と混在していて困っていました。（特に日本語）

## 目標
私と同じように最近勉強を始めた人（特に古い情報を知らない人）が学習を進めていくにあたり、迷いなく最新かつ正確な情報を得られるように記事をまとめていきたいと思います。
営利クラスター

<font color="Grey">*[Cluster for profit](https://aiven.io/blog/cluster-for-profit)の翻訳です。*</font>

2021年12月1日

# 営利クラスター

データ・インフラを正しくセットアップする必要がある新興企業向けのAivenのプログラム、Clusterに参加しませんか？

Aivenは最近、データインフラストラクチャを正しく構築する必要がある、あらゆるビジネス分野のフレッシュな新人のための[スタートアッププログラム](https://aiven.io/cluster)を[立ち上げました](https://aiven.io/blog/an-invitation-to-cluster)。


しかし、Aivenクラスターに参加し、そこから利益を得るにはどうすればいいのでしょうか？その方法は以下の通りだ！


## 1.Aivenクラスターに参加する


[クラスターのページ](https://aiven.io/cluster)にアクセスし、フォームに必要事項を記入して大きなカニ色のボタンをクリックする。これで申し込み手続きが開始される。


## 2.???


申請が承認されると、10万ドルのAiven・クレジットがもらえます。([Among other things](https://aiven.io/cluster)) そのクレジットを活用する方法をいくつかご紹介します：


* 2TBのストレージと半分のテラバイトのRAMを持つ強力なPostgreSQLインスタンス（business-512）を6ヶ月間実行する。
* より控えめなKafka Business-8パッケージの運用。
* 12ヶ月間、フルハウスのデータをセットアップする：
	+ データベースはPostgreSQL business-64。
	+ OpenSearch Business-32 検索用
	+ Redis business-64（アプリを快適に動作させるためのキャッシュ用
	+ メトリクスのためのM3ビジネス-16
	+ Grafanaによる監視


より多くのアイデアについては、私たちの[ケーススタディ](https://aiven.io/case-studies)を見て、他の人がどのようにAivenのサービスを使用しているかを見てみましょう。


## 3.利益


一度データインフラを構築すれば、あとは動くだけです。アップグレードもメンテナンスもお任せください。データ・パイプは常にクリアな状態に保たれ、御社はビジネスを継続することができます。


スタートアップがうまくいけば、つまりAivenを利用すれば、独自のデータインフラを構築するコストを省くことができます。つまり、管理、ハードウェア、接続のコストがかさみ、後で解体しなければならないようなものに投資する必要がないのです。


そして、どれほどの利益が見込めるのだろうか？[IDCによる最近のホワイトペーパー](https://aiven.io/blog/aiven-cloud-data-services-bring-340-three-year-roi)によると、当社の顧客は、5ヶ月の投資回収期間で3年間のROIを平均340%、3年間の運用コストを37%削減しました。
UbuntuデスクトップでDockerをインストール

[docker Docs]()にいろんな方法が書いてあって、わかりにくいんですよね。
あとDocsをちゃんと目次で読んでいかないといけないっぽくて、個人的にいつも検索で出てきづらい。
ということでメモです。リンクも含めて。

普通に[dockerデスクトップ](https://docs.docker.com/desktop/install/ubuntu/)がラクだとは思います。

ただ、今回は前回なにで入れたかも覚えてない状態で、Dockerデスクトップが入ってなかったので、
適当に消して適当に動かす感じの記事を見つけたので、その雰囲気を書いていきます。

読んだのは[これ](https://docs.docker.com/engine/install/ubuntu/)

![uninstall_previous_version.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/addb0ebc-9000-63bc-0b31-79c28a5b1fa4.png)

アンインストールコマンドとかか言ってるので、いい感じっぽいです。
軽く注意しながら、そのまま読み進めて、インストールのコマンドも打っていきます。

```shell:コマンド
$ sudo apt-get update
$ sudo apt-get install ca-certificates curl gnupg

$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg

$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update

$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```

```shell:コマンド
$ sudo docker run hello-world
```

![Hello_docker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/08475c4a-74d0-deda-0d67-ffc54fa3b575.png)

OK。ハローワールドが出たので、お掃除します。



[Dockerのお掃除](https://qiita.com/MasanoriIwakura/items/53cb7968e44f7a25e083)という記事を@MasanoriIwakuraさんが書いてくださっているので、そのまま実行します。

Dockerコンテナ全停止Dockerコンテナ全削除Dockerイメージ全削除。

```shell:コマンド
$ sudo docker container stop $(sudo docker container ls -aq)
$ sudo docker container rm $(sudo docker container ls -aq)
$ sudo docker image rm $(sudo docker images -q)
```


----

あとは、
[ubuntu版Dockerを毎回sudoなしで実行したい](https://qiita.com/katoyu_try1/items/1bdaaad9f64af86bbfb7)ので、実行します。

かるく確認
```shell:コマンド
$ getent group docker
```

whoamiで今ログイン中のユーザー名をDockerグループに追加する。

```shell:コマンド
$ sudo gpasswd -a $(whoami) docker
```

ログアウトするか再起動すると、以下のコマンドがsudoでなくても通る。

```shell:コマンド
$ docker images
```

----

#### 引用元

https://docs.docker.com/desktop/install/ubuntu/

https://docs.docker.com/engine/install/ubuntu/

https://qiita.com/MasanoriIwakura/items/53cb7968e44f7a25e083

https://qiita.com/katoyu_try1/items/1bdaaad9f64af86bbfb7
Bash と Caddy サーバで ActivityPub のインスタンス(8) reply.sh もフォロワーに送りつける

## reply.sh を改造する
Note と同じく、誰かへのリプライも自分のフォロワーへ配送しなければならない。(ここでは公開範囲を考えないことにする)
なので note.sh と同様に
- followers ファイルから各フォロワーの inbox エンドポイントを取得して配列にし
- reply する相手がフォロワーにいなかったら、その配列に加えるが
- フォロワーにいたらその配列には加えず
- その配列の各エンドポイントへ全部配送する

というようにする。以下がそのスクリプトである。

```bash:reply.sh
#!/bin/bash


read -p "@myself@my_instance: " MY
MY_arry=(${MY//@/ })
myself=${MY_arry[0]}
my_instance=${MY_arry[1]}
echo

read -p "@to@to_instance: " TO
TO_arry=(${TO//@/ })
to=${TO_arry[0]}
to_instance=${TO_arry[1]}
echo

read -p "which id do you wanna reply?: " id_of_reply_to
echo

if [ -n "$id_of_reply_to" ]; then
	id_of_reply_to=\"$id_of_reply_to\"
else id_of_reply_to="null"
fi

read -p "what do you wanna mention?: " content
echo


URL=$(curl https://$to_instance/.well-known/webfinger?resource=acct:$to@$to_instance | jq -r '.links[] | select (.rel == "self")'.href | tr -d "\"")
INBOX=$(curl -H "Accept: application/activity+json" $URL | jq .inbox | tr -d "\"")
REQUEST_TARGET=$(echo  "/"$(sed -E 's/^.*(https):\/\/([^/]+).([^/]+)/\3/g' <<< $INBOX))

unixtime=$(date "+%s")
date_now=$(date -uR  | head -c -6 | sed -e 's/$/GMT/')

sed -e "s/{id}/$unixtime/g" ./json_templates/reply.json > live
sed -i "s/{myself}/$myself/g" live
sed -i "s/{my_instance}/$my_instance/g" live
sed -i "s/{to}/$to/g" live
sed -i "s/{to_instance}/$to_instance/g" live
sed -i "s/{date_now}/$date_now/g" live
sed -i "s|{id_of_reply_to}|$id_of_reply_to|g" live
sed -i "s|{URL}|"$URL"|g" live
sed -i "s/{content}/$content/g" live


body=$(cat live | jq -c .)
digest_val=$(echo -n "$body" | sha256sum | xxd -r -p | base64)


### フォロワーの inbox 一覧を followers ファイルから取得
while read -r line; do
	followers_inbox_URL+=( $(echo $line) ) # 配列に
done < followers

## followers_inbox_URL 配列に reply する相手がいたら追加
if echo "${followers_inbox_URL[*]}" | grep -qw "$INBOX"; then
	:
else
	followers_inbox_URL+=($INBOX)
fi

# for で followers_inbox_URL 配列内の inbox へ、署名して配送
for INBOX in ${followers_inbox_URL[*]}; do

	to_instance=$(sed -E 's/^.*(http|https):\/\/([^/]+).*/\2/g' <<< $INBOX)
	REQUEST_TARGET=$(echo "/"$(sed -E 's/^.*(http|https):\/\/([^/]+).([^/]+)/\3/g' <<< $INBOX))

	signature_headers="(request-target): post ${REQUEST_TARGET}\ndate: ${date_now}\nhost: ${to_instance}\ndigest: SHA-256=${digest_val}"
	echo -e "$signature_headers" > 4_sig_headers # 後に見返すためにファイルに
	sig_val=$(echo -en $signature_headers | openssl dgst -binary -sign ./personal/private -sha256 | openssl enc -A -base64)
	signature="Signature: keyId=\"https://${my_instance}/users/${myself}#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) date host digest\",signature=\"$sig_val\""

	curl -H "Date: $date_now" -H "Digest: SHA-256=$digest_val" -H "$signature" $INBOX -d "$body"

done

echo $body | jq .object > ./statuses/$unixtime
echo $body > ./post/$unixtime

```
配列に変数 INBOX と同じ文字列があるかどうかを調べるのに grep -qw を使っているあたり以外は、元の reply.sh と note.sh をそれなりに混ぜただけである。
前回と同様に
```
bash ./script/reply.sh
```
と実行する。


## 参考記事
[ Bash 配列に値が含まれているかどうかを確認する方法 ](https://ja.linux-console.net/?p=13637)
Ubuntuデスクトップで最新版のNodeのインストール

WebではMacの記事が多いので、Ubuntu向けに書いてみています。

# 答えは [GitHubにある](https://github.com/nodesource/distributions/blob/master/README.md) ようです。

![install_instruction.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/bb6700ba-0593-fbb6-3591-97c05e67ab37.png)



ただ、いつも調べて出てくるの方法[^1]の方が便利なので、そちらを引用してメモしておきます。

基本的には apt でインストール自体はできるんですよね。

```shell
$ sudo apt install -y nodejs npm
```

ただ、バージョンが古いんです。(メモってないですが、今回は Node12 あたりが入りました。)
最新のNext.js（Next14）とかちゃんと動かないっぽいので最新安定版入れていきます。

node自体のバージョン管理パッケージ「n」をインストールする。
```shell
$ sudo npm install n -g
```

すぐにnode.js最新安定版（stable）のインストール、というかたぶん切り替え。

```shell
$ sudo n stable
```

aptでインストールしたnodejsバージョンのアンインストール（不要になったnodeの削除）

```
sudo apt purge -y nodejs npm
```

最終インストールされているnodeのバージョンの確認

```shell
$ node -v
# v20.11.0
```

今回は「v20.11.0」が表示されました。
[Nodeの公式サイト](https://nodejs.org/en)を確認しに行ってみると、数字が一致してます！

![node_stable_version_20240117.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285882/07910e8f-e265-3ea9-a7e7-89dd8ffc2756.png)



#### 以下引用元
[^1]: ざっと検索で出てきたものですが、
https://mebee.info/2022/07/29/post-75180/ や
https://www.softel.co.jp/blogs/tech/archives/6487 や
https://qiita.com/nouernet/items/d6ad4d5f4f08857644de など
nvimメモ(nvim-qt on Windows)

最近nvimを触り始めた。ちょっとずつ育てていこうかな。

## Vim-plug

https://github.com/junegunn/vim-plug

```powershell
iwr -useb https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim |`
    ni "$(@($env:XDG_DATA_HOME, $env:LOCALAPPDATA)[$null -eq $env:XDG_DATA_HOME])/nvim-data/site/autoload/plug.vim" -Force
```

WSL(Linux)用

```bash
sh -c 'curl -fLo "${XDG_DATA_HOME:-$HOME/.local/share}"/nvim/site/autoload/plug.vim --create-dirs \
       https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
```


## init.vim

いじるときは`:e $MYVIMRC`、読み込むときは`:source $MYVIMRC`

```vim
set number
set cursorline
set cursorcolumn
highlight CursorColumn ctermbg=blue
set expandtab
set tabstop=4

" use clipboard
set clipboard&
set clipboard^=unnamedplus

call plug#begin(expand('~/.vim/plugged'))
Plug 'arcticicestudio/nord-vim'
call plug#end()

colorscheme nord

" Use HackGen Console NF
let g:nertfont_installed='yes'
let &guifont="HackGen Console NF:h13"
let &guifontwide="HackGen Console NF:h13"
```

WSL用

```vim
set number
" set cursorline
" set cursorcolumn
" highlight CursorColumn ctermbg=blue
set expandtab
set tabstop=4

call plug#begin(expand('~/.vim/plugged'))
Plug 'arcticicestudio/nord-vim'
call plug#end()
colorscheme nord

" customize
set cursorline
hi CursorLine cterm=underline
"set nocursorcolumn
"highlight CursorColumn ctermbg=gray

hi Visual ctermfg=6 ctermbg=8
```


## 操作めも

- Window
    - `:vs` 縦割り, `:sp` 横割り , `:new` 横割り(新規)
    - `Ctrl-W,xxx` (`Ctrl-w,q` 閉じる)
- Buffer
    - `:b以下略`
        - `:bd[N]` N番目のbufferを閉じる
    - `:ls`, `:ls!`
    - `:enew` 新規バッファ開く
- 移動
    - `0` 行の先頭, `^` 行の先頭の文字, `$` 行の最後
    - `gg` bufferの先頭, `G` bufferの最後
    - `Ctrl-u` 画面半分上, `Ctrl-d` 画面半分下 (`eof`送出とバインド被り注意)
- コピペ
    - `Ctrl-v` visual矩形モード(Windowsのペーストとバインド被り注意)
p5.js のフィルター用シェーダー「createFilterShader()」で座標情報を使った着色のお試し 〜その2〜

## はじめに
以下の「p5.js の createFilterShader()」を扱った　2つの記事に引き続き、また 「createFilterShader() を扱います。

- [p5.js の createFilterShader() を使ったフィルター用シェーダーのお試し - Qiita](https://qiita.com/youtoy/items/1083d6319ddab6d525d3)
- [p5.js のフィルター用シェーダー「createFilterShader()」で座標情報を使った着色のお試し - Qiita](https://qiita.com/youtoy/items/b06e65d20aa2f468b8bb)

今回は、上記の 2つ目で少し試した「createFilterShader() での座標情報の利用」をさらに試してみます。

## 前回の内容
前回の記事では、以下のように座標情報をそのまま色情報にする、というのを試していました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/6a2d4a0f-5269-031e-f570-a1e17dd45e6b.png)

この時の処理は、main() で処理されていく個々のピクセルに対して、他のピクセルの値を参照するようなことは行わない形でした。

## 今回の内容
今回は、前は試していなかった「異なる位置のピクセルの情報を使った処理」を簡単に試してみます。

### プログラムを書いてみる
今回のお試し用に書いたプログラムは以下のとおりです。

```javascript
function setup() {
  let fragSrc = `precision highp float;

  varying vec2 vTexCoord;
  uniform sampler2D tex0;

  void main() {
    vec4 color = texture2D(tex0, vTexCoord);
    if(vTexCoord.x < 0.5) {
      vec4 color2 = texture2D(tex0, vec2(vTexCoord.x + 0.2, vTexCoord.y + 0.2));
      color.r = color2.b;
    }

    gl_FragColor = vec4(color.rgb, 1.0);
  }`;

  createCanvas(400, 400, WEBGL);
  background(0);

  noStroke();
  fill(100, 100, 200);
  rect(0, 0, 150, 150);

  let s = createFilterShader(fragSrc);
  filter(s);
}
```

キャンバスでの処理の流れは、「背景を黒にする ⇒ キャンバス上の特定の範囲に青系の色の矩形を描画する ⇒ シェーダーを使ったフィルターを適用」となっています。

この中で使っているシェーダーの処理で、「他のピクセルの情報を参照して処理をする」ということを試しています。

具体的には、主に main() の中の部分です。

その処理では、全体の中の特定の範囲でだけ別のピクセルを参照する処理を行います。
具体的には `if(vTexCoord.x < 0.5)` という条件で処理を分けている部分のことです。

vTexCoord.x は、x座標の左端から右端を 0 から 1 という範囲の値で取得できます。
0.5未満という条件を指定しているので、他のピクセルを参照した処理が行われるのは、描画領域の左半分のみです。

さらに、その左半分の範囲のピクセルに対する処理では、以下のような処理を適用しています。

```javascript
vec4 color2 = texture2D(tex0, vec2(vTexCoord.x + 0.2, vTexCoord.y + 0.2));
color.r = color2.b;
```

この処理では、ある処理対象のピクセルの色を決める際に、x方向と y方向のそれぞれに 幅と高さのそれぞれ 20％の距離離れた位置のピクセルの値を使っています。
具体的には、その離れた位置にあるピクセルの青色成分の値を、処理対象のピクセルの赤色成分の値に代入しています。

これにより、フィルター適用後のキャンバスでは、描画範囲の一部に赤色の成分をもった部分が出現することになります（上記の「キャンバス上の特定の範囲に青系の色の矩形を描画する」という処理で描画した内容が元になり、赤色の部分が出てきます）。

### 実行結果
上記のプログラムを実行した結果は、以下のとおりです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/b4215a18-fe17-ca35-3986-7f595f554d2f.png)

キャンバス内の左半分の領域の中に、赤い矩形が描画されています。

別の位置にあるピクセルの値を使う際に、以下のように x方向と y方向のそれぞれに 幅と高さのそれぞれ 20％の距離離れた位置のピクセルの値を使うということを行ったため、青系の色の矩形の領域と少しずれた位置に赤の矩形が出現しています。

```javascript
vec4 color2 = texture2D(tex0, vec2(vTexCoord.x + 0.2, vTexCoord.y + 0.2));
```

ちなみに、シェーダーを使ったフィルターを適用しなかった場合の描画（例えば `filter(s)` をコメントアウトした場合の実行結果）は、以下となります。
上で示していた描画結果の赤色の矩形の部分は、シェーダーによるフィルター処理で出現したものであるため、シェーダーを使ったフィルターを適用しない状態にすると、以下のように青系の色の矩形のみが描画されることになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/fdcbd1b2-40c7-fe75-2d35-769d38433a66.png)

青系の色の矩形が描画されるのは、シェーダーを用いたフィルターを適用する処理の前に書いていた、以下の部分によるものです。

```javascript
   fill(100, 100, 200);
  rect(0, 0, 150, 150);
```

今回は、あるピクセルの処理に対して、別の位置にある 1つのピクセルの値を用いた処理を行いましたが、別の位置にある複数のピクセルを用いた処理を行うと、いろいろ面白い見た目のものを作ることもできそうです。
KeychronのVIAでノブにマウスホイールを割り当てる

Keychron Q8 Pro を買ったのですが現在のVIAのバージョン（3.0.0）ではノブへのアクション割り当て時の候補にはライトに関する候補しか出てこないためQMKキーコードを直接入力する必要がありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29354/121b74b7-f888-37d7-c6dc-2a3323381e8f.png)

割り当てたQMKコードは

- Rotate Counterclockwise(反時計回り): `KC_MS_WH_DOWN` (下にスクロール)
- Rotate Clockwise(時計回り): `KC_MS_WH_UP`　(上にスクロール)

 です。

 ちなみにデフォルトに戻す場合、
 - ボリュームダウンは `KC_VOLD`
 - ボリュームアップは `KC_VOLU`
 - ミュートは `KC_MUTE`

です。
障害対応で大切だと感じていることのまとめ

私個人の障害対応の経験と
一昨日参加した[Incident Response Meetup vol.1](https://incident-response.connpass.com/event/304636/)での学びから
障害対応において大切だと感じていることをまとめる。

https://incident-response.connpass.com/event/304636/

# 障害とは
リリース後のシステムにおいてシステムの不具合やユーザーの操作ミスによってユーザー業務に影響が出ているもしくは出る恐れがあるもの。

# 障害対応の目的
システムを直すことではなく、ユーザー影響の回避・低減・早期回復をすること。

# 障害対応に対する心構え
- システムの信頼性の要である
- 障害への対応の仕方でユーザー影響が大きく変わる
- いつ発生するかわからないため特定の人が常に障害対応をするということは不可能である
- 素早く適切に行動するための備えが重要である

# 役割分担
障害対応では復旧対応、原因調査、ユーザーへの説明、社内調整などたくさんのことをやる必要がある。
またそれぞれの作業の難易度が高いことも多い。
一人の人間にできることは限られている。
そのため役割分担をする必要がある。
特に以下が重要であると考える。

- 作業者が一つの作業に集中できていること
並行で進めなければいけない作業がある場合は分担できるだけの人を集めるべき
- 専任のインシデントコマンダーが存在すること

### インシデントコマンダーの役割
- 障害対応に必要な人員を集め体制の構築と維持をする
- すべての情報を集め、判断をする
情報が自分に集約されるように行動をする必要がある
- インシデントコマンダーは直接作業を行ってはいけない


# 情報集約
情報はフロー型とストック型でまとめるのが良い。

情報集約はやり方によって一長一短がある。

障害対応では後から対応者が増えることがある。
障害対応は長期化することがあり、メンバーが入れ替わることがある。
その際に新しいメンバーが状況をすぐに把握できる必要がある。

また再発防止のための振り返りでは整理された情報が必要である。
ユーザーへの説明にも整理された情報が必要である。

そのため2種類の方法を組み合わせてまとめ、
対応メンバーは誰でもすぐにアクセスできるようにする。

### フロー型
タイムライン、経緯。
いつ何が起きたのかを時系列で記録する。

### ストック型
システムとタスクの最新状況を整理してまとめたもの。
障害対応メンバーが一目で最新状況を理解できるようにする。
- 現在のシステム影響の状況
- 実施している作業、目的、作業者、完了予定
- 現在の体制（だれが何の役割を担っているのか）

事前に所定のフォーマットを用意しておくことで作成時間が短縮できる。

# コミュニケーション
- WarRoomの準備
WarRoomとは障害対応中のメンバーが同期コミュニケーションを取れる場所。
方法はなんでも良いが使い慣れた方法が良い。
事前にWarRoom設置をどのように行うかを決めておくと迷子が発生しづらい。
- コミュニケーション時に意識した方が良いこと
情報は簡潔に伝える
事実と推測は分けて考える
インシデントコマンダーに情報を集約する

# 調査作業者としての心得
- 推測をしない（ログを見る）
- ユーザーの発言を鵜呑みにしない（ログを見る）
- ユーザーの発言を必要以上に疑わない（推測で捻じ曲げない）

# 振り返り
- 必ず振り返りを実施する
- できるだけ早く実施する
- 振り返りのフォーマットを決めておく

# 事前の備え
事前に備えておくことで障害対応時にすばやく落ち着いて行動ができる。
障害復旧までの時間は直接的な復旧活動以外の時間も含めたかかった時間の総和である。
そのため簡単なことでも取り決めておくことが重要。

- インシデントコマンダーを機械的に決定できるようにしておく
- 障害のレベルを決めておく
- 障害のレベルに応じた体制の構築手順を決めておく
機械的に実施できるようにしておき、人を集める心理的ハードルを下げておく
- 障害のレベルに応じた復旧プロセスを用意しておく
    - セキュリティインシデントの場合
データ保護を最優先に行動できるようにする
    - コア機能に障害が起きている場合
コア機能の復旧を最優先に行動できるようにする
- 情報集約のフォーマットを用意しておく
- WarRoomの設定方法を決めておく
- 障害解消とする条件を決めておく
【カスタムGPTs_基礎】簡単な会話で自分だけの映画推薦GPTを開発してみる！

## はじめに
トレンドの映画を推薦してくれるカスタムGPTの作成に挑戦しました。この記事では、基本的なカスタムGPTの開発方法をステップバイステップで解説します。最終的にはTMBDのAPIを導入して、より高度なGPTsを作成しましたが、その詳細については[別の記事](https://qiita.com/TajimaMiho/items/9816575cbda7e9196b26)で紹介しています。この記事では、基本的な部分に焦点を当て解説します。

## GPTsとは
カスタムGPTsとはChatGPTのノーコード機能で、ユーザーが特定のタスクや目的に合わせてチャットボットをカスタマイズできるものです。完全に自作することも、ChatGPTとの対話で簡単に作成することも可能です。

## 開発を始める
以下の手順で開発画面に移ります。
1. 画面左の`Explore GPTs`をクリック
2. 画面右上の`+ Create`をクリック
3. 開発画面に移ったら`Create`を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/dc8a6ec3-8af7-4fcb-e4ef-7e5a2092567e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/be802353-bfe9-f7d8-7b67-ac7d9d7b1421.png)

## chatを通して作りたいGPTを構築する
ここでは、chatGPTとの簡単な対話を通してGPTを具体化し、構築していきます。
私の場合はトレンドの映画をおすすめしてくれるGPTを作りたかったので、
`What would you like to make? (どのようなものを作りたいですか？)`
という最初の質問に対して
`I would like to make a friendly movie buff for a fascinating movie recommendation.(魅力的な映画を推薦するために、友好的な映画ファンを作りたい。)`
という回答をしました。英語での回答が効果的ですが、日本語でも可能です。
この調子で、GPTの名前、画像、特性などを話し合いながら構築していきます。

![スクリーンショット 2024-01-17 22.37.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/430208b1-5c81-b880-76ef-8f4938aac263.png)

`~ is all set up!`のように完成を意味する言葉が出てきたら完成です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/c464f87b-7a66-269f-e506-97c1ede4ce10.png)

## プロジェクトの内容を確認
タブを`Configure`に切り替えてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/badab691-2946-0f2d-2533-c43d15c434c2.png)

ここでは、先ほどの会話を通して構築されたGPTの内容が項目ごとに分けられて記載されています。以下に各項目の内容を示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/b05d8c46-8568-2bf1-1ff2-255334cbaf9b.png)

|番号|内容|
|---|---|
|①|GPTのアイコン画像|
|②|GPTの名前|
|③|GPTの概要|
|④|GPTの役割や機能などの詳細(ここでGPTの性質が決まります！)|
|⑤|ユーザーが打ち込む最初のプロンプトの例（英語で書かれていますが、日本人向けの場合、日本語の方が親切かもしれません。`例：最近のトレンドの映画を教えて。, 彼女と見るおすすめの映画はある？ ...`）|
|⑥|Web検索機能, 画像生成, コード生成の設定。（今回は何も使わないので全てのチェックを外しました。）|

各項目の内容を確認し、必要に応じて調整してください。
そのほかの`Knowledge`や`Actions`も面白い機能となっていますが、少し高度なため今回は飛ばします。

## Previewで動作を確認する
画面右側のPreviewで動作を確認し、必要に応じて先述の各項目を調整します。理想の動作になるまで繰り返し調整します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/d4b4bb5f-2453-299b-8e88-a7e6f22d1efd.png)

## 公開設定
最後に公開範囲などを設定し、`Conrifm`を押したら完成です🎉
![スクリーンショット 2024-01-18 0.18.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/0919cdf3-a9da-3678-4e74-91704c7b0c15.png)

## 最後に
これまで同じ目的で同じ命令を何度も打ち込んでいた作業が、カスタムGPTのおかげで効率化されました。これからもたくさんお世話になる予定です！
Azureで生成AIアプリ開発に入門したい人に朗報！ 鉄板の解説書が出ました✌️

:::note info
2023年10月からの景品表示法の改正に伴う注記：この記事は技術評論社様より献本をいただき、発売前の書籍レビューをするものです。
:::

来週1/24にMicrosoft社のAzureクラウドで生成AIアプリケーションを開発する人向けの入門書籍が発売されます。

幸運なことに、著者の一人である吉田真吾さんのご厚意で発売前献本の機会に預かりましたので、先行レビューということでみなさんに紹介させていただきます！


# Azure OpenAI ServiceではじめるChatGPT/LLMシステム構築入門

永田 祥平 (著), 伊藤 駿汰 (著), 宮田 大士 (著), 立脇 裕太 (著), 花ケ﨑 伸祐 (著), 蒲生 弘郷 (著), 吉田 真吾 (著) - 技術評論者より2024/1/24発売予定

https://amzn.asia/d/a0XKMeP

通称「ドーナツ本」です。おそらくOpenAIのロゴが某ドーナツ屋さんのフレンチ●ルーラーに酷似していることからこのカバー写真になったものと思われます（笑）

![スクリーン ショット 2024-01-17 に 23.45.04 午後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/d2e4a895-e184-7499-159c-10750b2d1d7d.png)


私は生成AIブームの初期からAzure OpenAI Serviceを使ってAIチャットアプリ開発を行っていたのと、最近はもともと得意だったAWSでもBedrockが登場したことにより同様の案件をこなせるようになってきたことから、両クラウドのLLM（大規模言語モデル）利用者目線でこの本を紹介します。

https://speakerdeck.com/minorun365/enpuraqi-ye-nishe-nei-ban-chatgptwoteamsbotutodeshi-zhuang-sitemitajian


# 最近のAIエンジニアにありがちな課題

2023年は「わが社も生成AIを活用していくのである！オイ君、担当に任命するから推進よろしくな👋」てな感じでLLM特命隊員デビューされた方も多いのではないでしょうか？

### AOAI入門あるある

- 生成AIをウチもやっていくぞ！ これを機にAzureクラウドに入門しよう。…あれ、意外と入門書籍少ない？
- 生成AIでよく使われるAzureサービスは新しかったりニッチだったりで入門解説書に載っていないものも多い
- 玄人は「MS Learn読めばいいじゃん！」って言うけど、公式トレーニングの類の文章って正直認知負荷が高くて辛い
- クラウドは分かるけど生成AIの基礎知識が足りない。アプリ開発スキルが弱い


# この本の凄いところ

お気付きの方もいるかも知れませんが、本書の著者人の多くがAzureの本家Microsoftの中でもOpenAI Serviceの国内コアメンバーたる方々で構成されています。

AOAIを少しかじったことのある方なら、QiitaやZennで日本のMS有志メンバーの方々が良質なアウトプットを発信されているのを見たことがあるのではないでしょうか？

https://qiita.com/tmiyata25

https://speakerdeck.com/hirosatogamo/chatgpt-azure-openai-da-quan

### 特筆すべき点

- Azure OpenAIの有用なアウトプットを多数発信されている超豪華な執筆陣
- 今月出るホヤホヤの新刊なので、色々あったけど現時点で最新の情報が整理されている
- 図解・スクショたっぷりでめちゃ読みやすい
- 実装だけでなく「評価・運用・ガバナンス」といった "その先" の課題対応も解説
- RAGの次に間違いなく流行る「エージェント」の実装もばっちり記載

やはり生成AI領域でトップラインを走っているAzureだからこそ、こういった完成度の高い書籍が素早く世に出て来れるのだなと思いました。


# 具体的に面白いポイント

私も早速読んだのですが、特にRAGとエージェントの章はとても興味深く読みふけってしまいました。もともとAzureやAWSでLLMアプリ開発をやってはいるものの、改めてサービスの動作構造を深く理解することができました。

AzureのAI Search（旧Cognitive Search）の仕組みや検索の種類についても分かりやすく解説されていて、「ハイブリッド検索って具体的に何してるの？」みたいなことが結構ちゃんと分かるようになりました。

### ここに注目

- RAGの概要やアーキテクチャ紹介はもちろん、実際のコーディング実装例を添えて解説してくれているので「AIに社内文書を食わせる」みたいなフワッとした理解ではなく解像度高くRAGを理解することができる
- Azureの各サービスで実際にどのぐらいの料金が発生するのか、分かりやすくまとめてくれているので個人検証する人も安心
- 社内で「OpenAI API共通基盤」を作ってガバナンスを保つというJTCエンプラあるある感のある実装方法の紹介も
- 新刊だけあって、コラムにHyDEやGPT-4 Turboが出てきたりと比較的新しいLLM技術もちゃっかり解説されている
- 付録でChatGPTの内部構造についての歴史を含めた解説がありとても興味深い


# まとめ

LLMアプリケーション開発のサービス提供でとりわけ先行しているAzureの解説書籍なので、AWSやGoogle Cloudなど他のクラウドを主に使っているエンジニアにとっても有用で、生成AI活用の普遍的なナレッジや「競合サービスの比較軸」を理解することができるのでAzureユーザーに限らず読んでおくべき本だと思います。

めちゃ充実していて良かったので、個人的にはこんな本のAWS版も出てくれたらめちゃ嬉しいな〜と思いました😆
スクレイピングでTwitterの画像を一括保存するpythonコード　2024/1/16

# はじめに
Twitterのいいね欄、メディア、ブックマークなどの画像を一括でダウンロードするPythonコードです。


スクレイピングなので使用は自己責任でお願いします。
# 概要
Twitterのいいねやメディア欄のURLを入力すると、そのページの画像が自動的にダウンロードされます。これは他人のいいね欄やメディア欄も含めてダウンロードが可能です。ブックマークは自分のものだけ対象です。
任意のダウンロード数を指定しないと、タイムラインの画像が無限にダウンロードされる可能性があります。

このツールを使用するには、ログイン用のTwitterアカウントが必要ですが、入力されたURLの画像をDLしに行くのでどのアカウントでも構いません。（アカウントのみの画像限定ではありません）

実行時に必要なもの:
ログイン用アカウントのユーザー名とパスワード

# 実行環境
・言語 Python 3.11.7

・ライブラリ 
　requests 2.31.0
　selenium 3.141.0
 
・実行ブラウザ chrome 120.0.6099.217 (Official Build) （64 ビット） (cohort: Stable) 

・webドライバ chrome driver 120.0.6099.109


# セットアップ
1.python 3.11.7をダウンロード

2.下記のpythonコードを自分のPCにダウンロード

https://github.com/TanakaG1217/TwitterDLder

3.使っているブラウザのバージョンにあったwebドライバをインストール
[参考]

https://www.google.com/search?q=chrome+webdriver+windows+64+120&rlz=1C1JCYX_jaJP1072JP1072&oq=chrome+&gs_lcrp=EgZjaHJvbWUqBggAEEUYOzIGCAAQRRg7MgYIARBFGDsyBggCEEUYOzIGCAMQRRg7MgYIBBBFGDwyBggFEEUYPDIGCAYQRRg8MgYIBxBFGDzSAQgyNzUyajBqN6gCALACAA&sourceid=chrome&ie=UTF-8

4.ライブラリインストール
  WindowsPoWerShell（なんでも）で
```WindowsPowerShell.
pip install requests
pip install selenium
```

5.DLしたpythonファイルがあるディレクトリ移動
```WindowsPowerShell.
cd C:\your_path_twitterDLer
```

# 使い方
1.実行
```WindowsPowerShell.
python3 twt_DL.py
```

2.ユーザー名、パスワード、DLしに行くURL、ダウンロードするファイル数を記入
```WindowsPowerShell.
ログインの為ユーザ名を入力してください　※誰にも公開されません.保存もされません.
 @も入れてね
 >@testname

パスワード
>testpass

DevTools listening on ws://127.0.0.1:58219/devtools/browser/fa8f39d8-fb9b-4706-aa9d-9c512458e60a

 画像をDLするURLを記入してください
 例：https://twitter.com/username/media , https://twitter.com/username/likes等　
>https://twitter.com/username/media

 ダウンロードする枚数を記入してください
 ※最新のものからDLするので期間指定などはできません。
 全ての場合は半角で ０ にしてください
>0
```
すると画像のURL取得が始まります。少し時間がかかるので気長にお待ちください。
（まだDL始まってないです）
```
>0
DL予定画像枚数： 3
DL予定画像枚数： 7
DL予定画像枚数： 9
DL予定画像枚数： 16
DL予定画像枚数： 20
DL予定画像枚数： 25
 .
 .
 .
```

画像のURL取得が終わったら、今度はDL開始です。
DLした画像を入れるフォルダのパスを入力してください。
※中身は空にしてください。パスの名前に　”　”　は含まないでください

正しく入力されたらDLが始まります。
```
 DL予定画像枚数： 1230
 画像の総枚数: 1230

 中身が空のディレクトリパスを入力してください:
 例：C:\Users\user\OneDrive\画像\新しいフォルダー
 注意!： " " をつけないで！空のフォルダにしてね！

>C:\Users\user\OneDrive\画像\sample
 画像を保存するディレクトリ： C:\Users\user\OneDrive\画像\sample

 画像をpngにしてDL...0 /1230

 画像をpngにしてDL...1 /1230

 画像をpngにしてDL...2 /1230
```

以上！

# さいごに
webスクレイピングなのでたまに画像を取りこぼしたりします。
また個人の責任でお願いします。
【React】複数の関連要素に一意のIDを設定する方法

以下のように`useId`を使用することで一意のIDを設定できます。

```js
import { useId } from 'react';

export default function Form() {
  const id = useId();
  return (
    <form>
      <label htmlFor={`${id}-firstName`}>First Name:</label>
      <input id={`${id}-firstName`} type="text" />
      <hr />
      <label htmlFor={`${id}-lastName`}>Last Name:</label>
      <input id={`${id}-lastName`} type="text" />
    </form>
  );
}
```
PostgreSQLでprisma migrateがError: P1010: User `username` was denied access on the databaseで失敗する


## 問題
Dockerコンテナ上にPostgreSQLを構築し、prismaでmigrateを実行しようとしたら以下のようなエラーになった。

```
$ prisma migrate dev
Error: P1010: User `username` was denied access on the database `hoge-db.public`
```

usernameという名前のユーザーはちゃんと存在していて、権限を確認したところ問題なさそうだった。
Prismaの接続設定も問題なさそうだった。

## 原因
色々探った結果、ローカルマシンに同ポートでPostgreSQLが起動していたのが原因だった。

```
$ ps aux | grep postgres
// 省略
hoge 6066   0.0  0.0 408843216   7568   ??  S    11:27PM   0:00.04 /opt/homebrew/opt/postgresql@15/bin/postgres -D /opt/homebrew/var/postgresql@15
hoge 8642   0.0  0.0 408626896   1360 s008  S+   11:33PM   0:00.00 grep postgres
````

## まとめ
ローカルマシンとDockerコンテナ間でポートが競合すると、予期しないエラーが発生するので気をつけましょう。
何も分からない人がPythonでSeleniumを動かしたときのメモ

# 著者のスペック
- 開発経験なし
- テストをしています

# 経緯
- 大量のテストデータをテスト環境に追加したい
- 開発メンバーに打診→「すまんが手動じゃないと無理」
- この量を！？手動！？狂っちゃうよ！？
- 調べる
- Seleniumを使えば無料で出来そう！自動化や！頑張るぞ〜☆（イマココ）

# 前提
- windows10
- chromeブラウザをseleniumで操作したい

# 事前準備
「Python Selenium」でググると出てくるものを全部入れる
- Python
- Selenium
- chrome driver

# さあ動かそう
1. PythonのIDLEを立ち上げる
1. サンプルコードを調べる
1. Googleを立ち上げる→閉じるだけなら簡単そう！
1. サンプルコードをコピペしてRUN
1. Python「ModuleNotFoundError: No module named ‘selenium’ 」
1. なぜNotFound…！？seleniumはPCに入ってるはずだが……！？
1. 調べました


# Seleniumのインストールが必要
**コマンドプロンプトから操作が必要** ということが分かりました。
pipコマンドを使ってseleniumをインストールする必要があるようです。

以下のサイトを参照しました
https://regardie.dev/post-3034 
https://www.seleniumqref.com/introduction/python/Python_Sele_Ins.html

## pipコマンドの実行〜失敗
1. コマンドプロンプトで `pip install selenium` を入力すれば良いと分かった
1. やってみる
1. コマンドプロンプト「認識されていません」
1. ！？
1. 調べました

## Pythonでpathの設定が必要
環境変数が設定できていないのでコマンドプロンプト氏に通じなかったようです。
**Pythonをインストールするときにチェックをつけるべき項目がある** と分かりました。
1. もう一度Pythonのインストーラーを起動
1. 「Add  Python to environment variables」にチェックをつけて再度インストール
1. いっぱい設定したので再起動しておく

以下のサイトを参照しました
https://gammasoft.jp/blog/python-change-environment-variables-after-installed/

## pipコマンドの再実行〜成功
1. pipコマンドがよく分からないので調べる
1. コマンドプロンプトでPythonのScriptディレクトリへ移動して `pip install selenium` のコマンドを叩く
1. できた！！！:raised_hands:

以下のサイトを参照しました
https://moticat.net/?p=77


# 終わりに
初心者がやりそうなミスを全部やった気がしています。
エラー内容をGoogleに突っ込めばそこに答えがあるということを改めて実感しました。
Terraform で Azure リソースの診断設定を投入する

タイトルの通り、Terraform にて Azure リソースの診断設定を投入する方法を調べていたので、備忘として残しておこうと思います。

# 前提

* 設定したいリソースは既にある (今回は Application Gateway を例にする)
* 診断設定の送信先のストレージアカウントおよび Log Analytics Workspace も既にある

# コード

以下、自分でも試してみたコードです。なお、`<>` で括られている箇所 (主に名称) については、それぞれ環境に合った文字列に書き換えてください。

```terraform
data "azurerm_client_config" "current" {}

data "azurerm_resource_group" "rg" {
  name = "<resource_group_name>"
}

data "azurerm_application_gateway" "AppGw01" {
  name = "<application_gateway_name>"
  resource_group_name = data.azurerm_resource_group.rg.name
}

data "azurerm_storage_account" "StorageAccount01" {
  name = "<storage_account_name>"
  resource_group_name = data.azurerm_resource_group.rg.name
}

data "azurerm_log_analytics_workspace" "LogAnalyticsWS01" {
  name = "<log_analytics_workspace_name>"
  resource_group_name = data.azurerm_resource_group.rg.name
}

resource "azurerm_monitor_diagnostic_setting" "DiagSetting01" {
  name               = "<diagnostic_setting_name>"
  target_resource_id = data.azurerm_application_gateway.AppGw01.id
  storage_account_id = data.azurerm_storage_account.StorageAccount01.id
  log_analytics_workspace_id = data.azurerm_log_analytics_workspace.LogAnalyticsWS01.id
  
  # 複数の診断設定を行う場合、一個ずつ記載する
  enabled_log {
    # カテゴリ名は、表示内容から半角スペースを削除して指定する
    category = "ApplicationGatewayAccessLog"
  }

  enabled_log {
    category = "ApplicationGatewayFirewallLog"
  }

  metric {
    category = "AllMetrics"
  }
}
```

なお、プロバイダの設定などの他に必要なコードについては、基礎的な資料を見てくださいませ🙇‍♂️

# 参考リファレンス

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/monitor_diagnostic_setting
JavaはまだChromeやEdgeで使えるのか？解決策としてのCheerpJの紹介

![rectangle_large_type_2_305e069cc554723270842d3aefc91891.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3486144/62d4afb4-b6be-2b7f-a43a-c2ccbe77df07.jpeg)

広く使われているプログラミング言語であるJavaは、何十年もの間、ソフトウェア開発業界の基本技術となってきた。Webブラウザを含むさまざまなプラットフォームで数多くのアプリケーションを動かしてきた。しかし、テクノロジーが進化し続けるにつれ、[Javaとモダンブラウザの互換性](https://leaningtech.com/cheerpj/)が議論されるようになりました。

このブログは、その疑問を解決することを目的としている： Javaは今でもChromeやEdgeで使えるのか？

__Javaアプレットとその衰退__

Javaアプレットは、かつてWebブラウザでインタラクティブなコンテンツを配信するための一般的な手段でした。アプレットによって、デベロッパーはJavaコードをHTMLページに埋め込むことができ、豊富な機能とクロスプラットフォーム互換性を提供することができました。しかし、時間の経過とともに、Javaアプレットの使用は、いくつかの理由により大幅に減少した。

主な懸念事項の1つはセキュリティだった。Javaアプレットはユーザーのシステム・リソースにアクセスできるため、潜在的な脆弱性につながる可能性があった。その結果、Chromeを含む主要なブラウザは、Javaアプレットのサポートを徐々に廃止していった。2015年9月、OracleはJavaブラウザ・プラグインを完全に非推奨にすると発表し、Javaアプレットの時代の終わりを示した。

__モダンブラウザにおけるJava： 課題__

Javaアプレットの衰退に伴い、疑問が生じた： JavaはChromeやEdgeのようなモダンブラウザでも動作するのでしょうか？CheerpJのような代替ソリューションの登場により、答えはイエスだ。

__CheerpJ：ブラウザでJavaを強化する__

Leaning Technologiesが開発したCheerpJは、Javaアプリケーションを最新のWebブラウザでスムーズに実行できるようにする画期的なテクノロジーです。JavaバイトコードをJavaScriptにコンパイルすることで、ブラウザでネイティブに実行できるようになります。このアプローチにより、Javaアプレットが不要になり、WebアプリケーションにJavaコードをシームレスに統合することができます。

__CheerpJの利点__

__互換性：__ JavaバイトコードをJavaScriptとWebAssemblyに変換することで、CheerpJはChromeやEdgeを含むすべての主要なWebブラウザとの互換性を保証します。これは、ユーザーが追加のプラグインをインストールしたり、非推奨の機能を有効にしたりすることなく、Javaアプリケーションがシームレスに機能し続けることを意味します。

__パフォーマンス：__ CheerpJのバイトコードからJavaScriptへのコンパイルプロセスは、ブラウザでのJavaアプリケーションのパフォーマンスを最適化します。生成されるJavaScriptコードは非常に効率的で、複雑なJavaアプリケーションであっても、高速な実行と応答性を可能にします。

__セキュリティ：__ 従来のJavaアプレットとは異なり、CheerpJは完全にブラウザのJavaScriptサンドボックス内で実行されます。このサンドボックス技術は、Javaコードを基礎となるシステムから隔離し、セキュリティを強化し、潜在的なセキュリティの脆弱性を防ぎます。

__レガシーアプリケーションのサポート：__ CheerpJは、これまでJavaアプレットに依存していたレガシーJavaアプリケーションにライフラインを提供します。コードベース全体を書き直す代わりに、これらのアプリケーションはCheerpJを活用してWebベース環境に移行し、Chromeのようなモダンブラウザでシームレスに機能し続けることができます。

__簡単な統合：__ CheerpJを既存のJavaアプリケーションに統合するのは簡単です。CheerpJが提供するツールにより、デベロッパーはJavaコードをJavaScriptにコンパイルし、Webプロジェクトにシームレスに統合することができます。この統合の容易さにより、Javaアプリケーションの近代化に必要な時間と労力が削減されます。

__結論__

Javaアプレットの利用が減少するにつれ、Javaと最新のWebブラウザとの互換性が懸念されてきた。しかし、CheerpJは革新的なソリューションとして登場し、JavaアプリケーションをChromeのようなブラウザでスムーズに実行できるようにしました。CheerpJのバイトコードからJavaScriptへのコンパイルを活用することで、デベロッパーは互換性、パフォーマンス、セキュリティを確保しながら、JavaコードをWebアプリケーションにシームレスに統合することができます。

Javaアプレットの時代は過ぎ去ったかもしれませんが、Javaは強力で多用途な言語であり続けています。CheerpJを使えば、Javaの潜在能力を最新のWeb開発で解き放つことができ、デベロッパーはWebアプリケーションに新しい命を吹き込むことができます。

https://leaningtech.com/legacy-modernisation-jp/

引用元：https://leaningtech.com/does-java-still-work-in-chrome-and-edge-introducing-cheerpj-as-the-solution/