OmniAICreator/Qiita-1.07M huggingface dataset:
psi4でHOMO LUMO GAP計算

　仕事で化合物のHOMO LUMO GAPを計算したくなったんですが、計算ツールが手元になかったので、pythonで行おうと思いました。
　量子化学計算を行えるツールとして、psi4(非経験的分子軌道法のツール)、mopac(半経験的分子軌道法)のパッケージを選びました。
 今回はpsi4についてメモを残します。

１ psi4をインストールしました。
```conda
conda install -c psi4 psi4
```

２ 分子情報を入力しました。
```geometry.py
import psi4

#分子構造(ベンゼン)の入力
#psi4.geometry()は引数としてcartesian座標形式、またはz座標形式を受け付けます。
#ここでは前者を選択しました。
#ベンゼンはCとHをそれぞれ6つずつ持っています。
#それぞれの原子の3次元位置情報(x,y,z)が記されています。(1行目の0、1はそれぞれチャージと多重度(一重項とか三重項とか))
#cartesian座標はavogadro(無料の分子描画ソフトウェア)にベンゼンの構造式を入れ、「extensions」から「PSI4」を選択し、そこからコピペしてきました。

molecule = psi4.geometry("""
0 1
   C        0.16410       -1.37260       -0.00020
   C       -1.10660       -0.82840        0.00010
   C       -1.27070        0.54420        0.00000
   C       -0.16410        1.37260        0.00000
   C        1.10660        0.82840        0.00060
   C        1.27070       -0.54420       -0.00070
   H        0.29230       -2.44490        0.00440
   H       -1.97120       -1.47560        0.00000
   H       -2.26350        0.96930       -0.00050
   H       -0.29230        2.44490       -0.00080
   H        1.97120        1.47560       -0.00010
   H        2.26350       -0.96930        0.00020
""")
```

３ 構造最適化計算します。((特に構造が複雑な場合に)conformerをいくつか作ってそちらも計算し、最もエネルギーが低い結果を採用すべし。)
```optimize.py
#計算のメソッドにB6LYPを、基底関数に6-31G(d)を選択しました。
#psi4.optimize()を使いました。
energy, wfn = psi4.optimize("B6LYP/6-31G(d)", molecule, return_wfn = True)

#普通のPCで普通に実行すると恐らく数時間かかります(ベンゼンなら数分？)
#ハイスペックのPCで以下のメモリとスレッドの設定をした方がいいと思います。
#例 (会社のPC使いました。こんなに必要かは知りません笑)
psi4.set_memory(1000GB)
psi4.set_num_threads(80)
```

４ wfnからHOMO LUMOの情報を取り出します。
```homolumogap.py
#HOMO軌道とLUMO軌道のエネルギー値(単位はhartree)を取り出し、27.2114をかけてeVの単位に変換しました。
HOMO = wfn.epsilon_a_subset('AO', 'ALL').np[wfn.nalpha()-1]*27.2114
LUMO = wfn.epsilon_a_subset('AO', 'ALL').np[wfn.nalpha()]*27.2114

#gapの計算です。
HLG = LUMO - HOMO

#表示
print(HOMO, LUMO, HLG)
```


安定化した構造情報を保存して、avogadro等で描画させることもできます。

以上
Next.js + NginxサーバーをDockerで構築した話

## はじめに
数ヶ月前にNext.jsの本番環境をDockerで構築したのですが、Nginxはホストマシンで立ててしまっていたため、Nginxの設定を都度サーバー上で書かないといけないという問題がありました。

https://qiita.com/piny940/items/e30f219f98bb3b87af18

そこで今回はNext.jsのサーバーに加えてNginxサーバーもDockerで構築することにしました。

**ディレクトリ構成**
```
- root
  - nginx # new!
    - Dockerfile
    - nginx.conf
  - node_modules
  - public
  - src
  ...
  - docker-compose.yml
  - Dockerfile
  - package.json
  - yarn.lock
```

## Nginx関連の設定
```nginx/nginx.conf
server {
  listen 80;
  server_name www.example.com;

  location / {
    proxy_pass http://app:4400; # appはNextサーバーの名前
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }
}
```

## Dockerの設定
```nginx/Dockerfile.
FROM nginx:alpine

RUN rm -f /etc/nginx/conf.d/*

ADD nginx.conf /etc/nginx/conf.d/portfolio.conf

CMD /usr/sbin/nginx -g 'daemon off;'
```
```docker-compose.yml
version: '3'

services:
  app:
    container_name: next-app
    image: next-app
    build:
      context: .
      dockerfile: Dockerfile
    restart: always

  nginx:
    container_name: next-app-nginx
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
      - {好きなポート番号}:80
    depends_on:
      - app

```

## おわりに
これで晴れてホストマシンにnginxの設定を記述しなくても済むようになりました。次回はRailsサーバーで使っているNginxサーバーをDockerに移行していきたいと思います。
[CDI] 図解：よく使うCDI変換部品 - ①アグリゲータ

# はじめに

[インフォマティカ](https://www.informatica.com/jp/)が提供する、 [CDI](https://www.informatica.com/jp/products/cloud-integration/cloud-data-integration.html)(Cloud Data Integration)では、トランスフォーメーション(Tx)と呼ばれる変換部品を使って、ノーコードでデータの変換・連携を行うことができます。

この記事では、[「アグリゲータ」](https://docs.informatica.com/ja_jp/integration-cloud/data-integration/current-version/_transformations_cloud-data-integration_current-version_ditamap/GUID-D0209C88-C4DC-465A-B250-80F5AE95AA83.html)と呼ばれる、集計を実施するためのトランスフォーメーションを解説します。

# 変換部品の概要
アグリゲータ
 - データのグループに関して、平均値や合計値などの集計計算を実行します

# 図解イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/1fa4c40f-00d2-221f-9821-68fa7371ee6d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110338/73b20783-a7dc-3ccf-a897-be995677ea02.png)


# 変換部品の詳細
アグリゲータトランスフォーメーションを設定して、データのグループに対して平均値や合計値などの集計計算を実行します。アグリゲータトランスフォーメーションを使用して、重複行を削除できます。

アグリゲータトランスフォーメーションは、データのグループに対して計算を実行するように設定できることを除いて、式トランスフォーメーションと同様に動作します。式トランスフォーメーションは、行ごとに結果を返します。

例えば、アグリゲータトランスフォーメーションを使用して、組織の各部門の従業員の平均給与を計算できます。アグリゲータトランスフォーメーションで、部門番号のグループを作成し、各グループの従業員の平均給与を計算する式を設定します。

# 参考文献
[トランスフォーメーション マニュアル - アグリゲータトランスフォーメーション](https://docs.informatica.com/ja_jp/integration-cloud/data-integration/current-version/_transformations_cloud-data-integration_current-version_ditamap/GUID-D0209C88-C4DC-465A-B250-80F5AE95AA83.html)

[トランスフォーメーション マニュアル](
https://docs.informatica.com/ja_jp/integration-cloud/data-integration/current-version/_transformations_cloud-data-integration_current-version_ditamap/GUID-1F3375E8-0571-40E7-888F-C7DFD4F331C0.html)
開発終了したAtomのパッケージ インストール方法

Atom版の[language-hsp3](https://github.com/honobonosun/language-hsp3)を試してみたいと思ったのですが、インストールに手間取ったので手順を書いておきます。おそらくすべてのパッケージ（拡張機能）で通用するはずです。

Atomは開発終了に伴い、パッケージのサーバーも閉鎖されて設定画面からはインストールできないようになってしまっています。そのため、手動でインストールする必要があるようです。

なお、Atom本体は以下からダウンロード可能。

https://github.com/atom/atom/releases

### パッケージの手動インストール方法

Windows想定。

1. パッケージのソースコードをGitHubなどからダウンロード
1. zip形式だと思うのですべて展開
1. フォルダ名を、`package.json`ファイル内の`name`の値にリネームする[^step-3]
1. フォルダ直下で`npm install`を実行する[^step-4]
1. `%USERPROFILE%\.atom\packages`下にフォルダを移動

参考：

https://sologaku.com/soft-service/package-not-found-within-github-atom/

### 余談

なお、[Pulsar](https://pulsar-edit.dev/) という名前で有志がAtomを引き継いでいるそうです。
パッケージも継承しており普通に設定からインストールできるので、メインで使いたい場合はこちらが良さそう。

[^step-3]: これをしないとパッケージの設定ボタンが表示されず、パッケージの設定が開けません。ここで詰まったのですが、Pulsarでインストールしてみて気づきました。
[^step-4]: node.jsをインストールしておく必要があります。依存関係がないパッケージの場合は不要です。
【Xcode】Xcodeの文字が大きくなったので戻したい

# はじめに
Xcodeに限らず、ブラウザでも変なコマンドを入力してしまって意図せず文字が大きくなったりしてしまうことがありますよね
文字を大きくするコマンドと文字を小さくするコマンドを知っていればすぐに元の大きさに戻すことができます。

# 環境
**OS**: macOS
**キーボード**: JIS配列

# コマンド
### 文字を大きくする
`command` + `;`

### 文字を小さくする
`command` + `-`

### 文字を標準サイズに戻す
`command` + `0`

# おわり
「文字を標準サイズに戻す」があるのは便利ですね
元のサイズがわからなくなるということを防げます
ナウいMacにとってもナウいPostgreSQLをインストールする

# はじめに

M2でSonomaなMacにPostgreSQL 16.1（公開されてから何日後？）をインストールしてみます。PostgreSQLが依存するソフトはHomebrewでインストールするものの、PostgreSQL自身だけはソースからインストールするという逸般の誤家庭向けの方法です。あと、（無駄な努力な気がしますが）既存の環境にはできるだけ影響を与えないようにしています。

## 一般のご家庭向けには
こんな記事を読んでないで https://www.postgresql.org/download/macosx/ から好みの方法を選択してバイナリーをダウンロードすれば良いと思います。もしかしたらバージョンが少し古いかもしれませんが、そのバージョンの違いが深刻な問題を引き起こすことはないでしょうから。

# 手順
## ソースを入手
https://www.postgresql.org/ftp/source/v16.1/ からダウンロードします。最後がbz2のものとgzのものがありますが、お好きな方で。単なる圧縮形式の違いです。（bz2の方がサイズが小さいということは圧縮効率が良いということですね。でも今の時代この程度のサイズの差を気にする人はいないような、、、）
~~~
shasum -a 256 ~/Downloads/postgresql-16.1.tar.bz2 
~~~
とかやって https://ftp.postgresql.org/pub/source/v16.1/postgresql-16.1.tar.bz2.sha256 と比較してもいいかもしれません。改竄のチェックですね。（何も考えていないので、~/Downloadsにダウンロードされています。）

## 展開
展開します。
~~~
tar jxvf ~/Downloads/postgresql-16.1.tar.bz2
~~~
gzだとオプションの指定が少し変わりますね。

これをやるとカレントディレクトリに展開されますが、postgresql-16.1という名前のディレクトリの下に展開されますので、カレントディレクトリがいい加減でもそれほど悲惨な事態にはならないでしょう。

## 依存ライブラリのインストール
Homebrewでicu4cをインストールしておきます。Homebrewの説明はここではしません。（それ以外も必要かもしれませんが、私の手元の環境では既に入っているものでしたので、、、gettext関連かな）

## configure
下の[configure --enable-nls](#configure---enable-nls)とどちらか一方だけでいいです。エラーメッセージとかが英語のままでいいよ、という方はこちらで。
~~~
PKG_CONFIG_PATH="/opt/homebrew/opt/icu4c/lib/pkgconfig:$PKG_CONFIG_PATH" 
./configure
~~~
こちらは私にとっての本命ではないので、実はconfigureが正常に終了することを確認しただけで、makeが動作するかどうかは確認していません。もしかしたら[configure --enable-nls](#configure---enable-nls)と同じように
~~~
CPPFLAGS="-I/opt/homebrew/include" LDFLAGS="-L/opt/homebrew/lib" 
~~~
も指定しないといけないのかもしれません。

## configure --enable-nls
日本人ならもちろんエラーメッセージも日本語だろ、という方はこちらで。そうでない方は上の[configure](#configure)で。
~~~
PKG_CONFIG_PATH="/opt/homebrew/opt/icu4c/lib/pkgconfig:$PKG_CONFIG_PATH" 
CPPFLAGS="-I/opt/homebrew/include" LDFLAGS="-L/opt/homebrew/lib" ./configure --enable-nls
~~~
configureはPKG_CONFIG_PATH="/opt/homebrew/opt/icu4c/lib/pkgconfig:$PKG_CONFIG_PATH"を指定するだけで正常に終わったのですが、makeでうまくいきませんでした。そのためCPPFLAGSとLDFLAGSを追加で指定しています。

## make
~~~
make -j 12
~~~
jの次の値はお好きな値で。何も値を指定しない、という方法もあるようです。並列実行数なのでCPUと同じ程度の値を指定するといい感じと聞いたような記憶があります。適切に大きな値を指定すれば、「うおお、M2 Mac速い！！！」（※個人の感想です）と一人悦に入ることができるという副作用が期待できます。

## 動作確認
~~~
sudo make install
make check
~~~
気分的にはcheckしてからinstallしたいところですが、先にインストールをしておかないとcheckが動かないので。
~~~
（省略）
# All 215 tests passed.
~~~
と表示されれば動作しています。

## とにかく動かす
この時点では何も設定していないのですから、データベースとしてまともな動作はするはずもないのですが、とにかく動かしてみましょう。
~~~
$ /usr/local/pgsql/bin/psql 
psql: エラー: ソケット"/tmp/.s.PGSQL.5432"のサーバーへの接続に失敗しました: No such file or directory
	サーバーはローカルで稼働していてそのソケットで接続を受け付けていますか?
~~~
はい、エラーメッセージが日本語で表示されました。めでたし、めでたし。

# おことわりなど
恒例のお断りですが、この文章の内容は、筆者が所属している会社・団体とは一切関わりがありません。いわゆる「自主的な研究の成果の発表」というものです。

また、「逸般の誤家庭」ならそもそもHomebrewなんて使わずにすべてソースから構築だろ、という見解もあるかと思いますが、私はそこまで漢（おとこ）ではありません。
複雑なDeepLinkをJetpackComposeで実装するPart1

# はじめに
今回から、数パートに分けて複雑なDeepLinkが来たときやDeepLinkの内容によってホーム画面で出しわけないといけない時の実装を紹介していきます
### 本文
まずは、リンクの受け取り口であるActivityの実装です
```kotlin:MainActivity
// メンバ変数として持っておきます
private var deepLink = Uri.EMPTY

// アプリがバックグラウンドにあるかどうかで呼び出し元が変わるのでonCreateとonNewIntentの両方でチェックする処理を呼び出します
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        checkLink(intent)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        checkLink(intent)
        isBackground = true
    }

// intentを引数で受け取ることでどちらからきても正確なリンクを取得できます
private fun checkLink(intent: Intent?) {
        Firebase.dynamicLinks
            .getDynamicLink(intent)
            .addOnSuccessListener(this) { pendingDynamicLinkData: PendingDynamicLinkData? ->
                pendingDynamicLinkData?.let {
                // FDLはこちらから受け取ります
                    deepLink = it.link
                    setView()
                } ?: kotlin.run {
                // カスタムURLスキーマなどはこちらに流れてきます
                    deepLink = intent?.data
                    setView()
                }
            }
            .addOnFailureListener(this) { e -> Log.w("TAG", "getDynamicLink:onFailure", e) }
    }

    private fun setView() {
        setContent {
            AppTheme {
                if(hasAccount) {
                    AuthView()
                } else {
                // MainViewに対してリンクを渡して終わったら初期化します
                    MainView(deepLink = deepLink)
                    deepLik = Uri.EMPTY
                }
            }
        }
    }
```
### 最後に
今回は、DeepLinkの受け取り部分を紹介してみました
次の記事は下記になります
https://qiita.com/ryuji_sato/items/aa126cb20706583e88b3
どなたかのお役に立てれば幸いです
マイグレーションファイル** NO FILE **を削除する方法

## マイグレーションファイル** NO FILE **を削除する方法

マイグレーションファイルをロールバックせずに誤ってモデルを消してしまうと、`*** NO FILE ***` のエラーが発生します。このエラーを解消する手順は以下の通りです。

1. **マイグレーションファイルに名前をつける**
   - コマンドを使い、消したいマイグレーションファイルに仮の名前をつけます。
     ```shell
     touch db/migrate/20231110114913_hoge.rb
     ```

2. **マイグレーションファイルの内容変更**
   - マイグレーションファイルを開き、以下のような記述を行います：
     ```ruby
     class Hoge < ActiveRecord::Migration[7.0]
       def hoge
         # 設定を記述
       end
     end
     ```

3. **マイグレーションステータスの変更**
   - 以下のコマンドを使って消したいファイルのステータスを `down` に変更します。
     ```shell
     rails db:rollback
     ```

4. **マイグレーションファイルの削除**
   - 以下のコマンドを使って、削除するマイグレーションファイルを削除します。
     ```shell
     rm -rf db/migrate/20231110114913_hoge.rb
     ```

これらの手順により、NO FILEのマイグレーションファイルを削除して、エラーが解消できます。
擬似言語プログラム

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/b2d5d85e-e3ba-2e6a-a488-8ba595360590.png)
プログラム５は、whileを利用したプログラム例です。

「プログラム５」
i ← １
while （i が　１０　以下）を表示する
　i を表示する
　i ←　i + 1
endwhile

　はじめに、変数iを１にセットしてから、whileループを実行します。繰り返す様子は次のようになります。全判定型ルー方ですから、先に継続条件を判定する点に注意する必要があります。

 ・i = 1で継続条件が成立するので、「iを表示する」によって、１を表示する。その後、iを１増やしてi=2とし、whileの行へ戻る。

 ・i=2で継続条件が成立するので、「i得お表示する」によって、２を表示する。その後、iを１増やしてi=3とし、whileの行へ戻る。

 ‥
 ・i=10で継続条件が成立するので、「iを表示する」によって、１０を表示する。その後iを１増やして、i=11とし、whileの行へ戻る。
 ・i=11で継続条件が不成立となる。endwhileの次の行へ移る。
 ・プログラム終了
 最終的に、画面上には、１〜１０の数値が表示されます。

 １：do~while命令
 　whileに似た記法に、do~whileがあります。下記のdo~whileの記述記法で記述します。doがループ開始位置を示していて、whileがループ終了位置です。ループ継続条件がループの最後に書いてあることが特徴です。このようなループを、後判定型ループといいます。「まず、処理１を実行して、その後、条件を判定して、再度繰り返すのかを決める」という動作が特徴です。

  　処理１　→ 条件式判定（成立）　→ 処理１　→ 条件式判定（成立）)→ 
   ..処理１　→ 条件式判定（不成立）　→ 終了（whileの次の行へ移る）

   と処理が進みます。この場合は、最初から条件式が不成立であっても、「処理１」は、一度は実行されることになります。

   「do~whileの記述記法」
   do
   　処理１
   while（ループ継続条件）
CentOS stream 9 + nginx SSL証明書が読み込めないエラー

新しくCentOS stream9で nginxにSSLの設定をしようとしたところ、正しくconfファイルを設定しても下記エラーになったさいすこしハマったのでメモ。

```conf:/etc/nginx/conf.d/default.conf

    ssl_certificate /etc/nginx/ssl/certs/your_domain.crt;
    ssl_certificate_key /etc/nginx/ssl/private/your_domain.key;

```

keyやcrt等証明書ファイルの`chown`や`chmod`で証明書ファイルの権限を調整しても駄目。
また、作り直して、ペアチェック等もしても問題なし、それでも駄目。

原因はselinuxで、下記実行したら解決しましたw
```shell
restorecon -v -R /etc/nginx
```
MacBookをWindowsみたいするために導入していること

社会人になって初めてMacBookを購入して5年ほど使っていますが、
いまだに職場でMacBookを使う職場に巡り会えていません。
1日の大半は仕事でWindowsPCを触るし、家でMacBookを使う時に「これができねえ」みたいなことが多々ありました。
色々調べるとWindowsPCみたいに使うアプリがあるのを知って導入しているので、紹介いたします。

# Magnet マグネット
https://apps.apple.com/jp/app/magnet-%E3%83%9E%E3%82%B0%E3%83%8D%E3%83%83%E3%83%88/id441258766?mt=12

有料で990円でインストール出来ます。
機能としてはWindowsでいうところ「Windows＋矢印キー」のようなもので画面の整理ができます。
自分でキーの割り当てができます。

# Clipy（クリッピー）
https://clipy.softonic.jp/mac

無料で使えます。
機能としては「Windows+v」でクリップボードの履歴から貼り付けをすることができます。

### 以上！これくらいしかなかった!

読んだ人でこれが便利だよってやつがあれば教えていただけますと幸いです。
あと、次に買うPCはWindowsにしようと思います。 AirdropくらいしかMacBookの機能を活かせてないような気がするので…
未経験エンジニアがJavaSilverを取得した話

# はじめに

はじめまして、Lincraftの酒井です。
アドベントカレンダー8日目の記事を担当します。
今回、会社でアドベントカレンダーに参加することになり、こうして１つ記事を書かせていただくことになりました。
僕自身、会社に入社して１年半ほど経ちましたが、まだまだ実力不足でわからないことだらけです。
他の社員のように技術に関してかっこよく書きたいのですが書けません。
そこで今回は先日自身のスキルアップのために取得した”JavaSilver”の合格体験記のようなものを書けたらと思います。
暖かい目で見ていただけましたら幸いです。


# JavaSilverとは

[Oracle公式](https://www.oracle.com/jp/education/certification/1z0-815-jpn-48261-ja.html)より抜粋

試験名：Java SE 11 Programmer I
受験料（税込）：37,730 円 
出題形式：選択問題
試験時間：180 分
出題数：80 問
合格ライン：63 %

Javaアプリケーション開発に必要とされる基本的なプログラミング知識を有し、上級者の指導のもとで開発作業を行うことができる開発初心者向け資格となっています。


# 資格対策ついて

## 学習教材

### 1. [黒本](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5Java-SE-11-Silver%E5%95%8F%E9%A1%8C%E9%9B%86-1Z0-815/dp/4295007625)
メインで使用しました。この教材を3周ほどして、基礎から応用までがっつり固めました。試験ではこの教材の問題が8割くらい出るイメージでした。

　<img width=200 alt="黒本" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3615491/e802b1a0-a670-9618-e724-f48f2fafb545.png">

### 2. [白本（アプリ）](https://apps.apple.com/jp/app/java-silver-se11%E5%95%8F%E9%A1%8C%E9%9B%86/id1504199281)
サブで使用しました。主に電車などの移動時間を活用し、黒本に載っていない問題を解くことで理解を深めるようにしました。

　<img width=200 alt="白本" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3615491/9e3a35c0-a794-e7df-a13d-22c5fd5598d2.png">

## 学習期間

学習期間：3ヶ月
学習時間：平日30分、休日2時間

Javaの基礎構文がわかる程度の状況からのスタートだったため、平均的な学習時間よりは少し長くなっているかもしれません。平日はやる気が出ずサボってしまうこともあったので、それがなければもっと早く取得できたかもしれません。

## 学習方法

### 1. 黒本をひたすら解く
学習教材にも書きましたが、試験までに教材を3周ほど解きました。1周目は出題傾向とレベル感の把握、2周目は自身の得意・不得意の把握、3周目は弱点の克服と完成度を高めるようにしました。最終的に9割くらいの点数が取れる状態を目指し、学習に励みました。

### 2. わからない問題は聞く
解説を読んでも理解できない問題に遭遇した際には、会社の先輩や同僚に質問するようにしていました。質問をすることで自身の頭の中が整理されることもありましたし、先輩や同僚からの噛み砕いた解説を聞くことでより理解を深めることができました。質問することを恥ずかしく感じる人もいるかもしれませんが、恥を捨てて聞くことで得られる恩恵は大きいように感じます。

### 3. 実際に動かしてみる
解答の出力結果に納得いかないことや出力までの過程がわからない際には、問題で与えられたコードを動かすようにしていました。実際手を動かして作業することで、解説を読んだだけの問題よりも記憶に定着しやすかったように感じます。


# 試験を終えて

## 良かった点

### 1. 自信がついた
資格を取得という成功体験を得られたことで、以前よりも自信がついたように感じます。未経験エンジニアということもあり、技術に関してコンプレックスがありましたが、Javaという自身の強みができたことで、少しだけ誇れる自分になれたような気がしています。

### 2. 気づきが多くなった
Javaの勉強をしたことで日々の業務の中での気づきが多くなりました。今までは気に留めていなかった事柄にも取っ掛かりが生まれ、業務の中での学びの機会が増えたことで、仕事の面白みが増したように感じます。また、今までは入ることができなかった技術に関する会話にも少しずつ入れるようになり、日々成長を実感することができています。

## 改善点

### 1. 朝勉強に変える
学習期間にも書きましたが、平日の仕事終わりは疲れて勉強をサボってしまうことがあったため、勉強する時間を変える必要があると感じました。具体的には、朝の元気な時間に勉強することで、毎日サボらずコンスタントに勉強できたらと思います。

### 2. アウトプットの機会を増やす
今回の資格勉強では解説を読んだり解説を聞くといったインプットばかりでアウトプットの機会があまり設けられてなかったように感じました。今後は、自身の学びを他の社員に還元したり、SNSなどで発信したりすることで、アウトプットの機会を増やし、更なる学びの機会の創出ができたらと思います。


# さいごに

僕自身、この資格に挑戦したことはすごく自身にとってプラスになったと感じています。
今後は現在学習中の基本情報技術者やJavaSilverのステップアップとしてJavaGoldの取得と更なる自身のスキルアップに努めたいです。
そしていつか技術に関するかっこいい記事を書けたらと思っています。
アドベントカレンダーはまだまだ続きますので、他の記事も読んでいただけましたら幸いです。
最後まで読んでいただきありがとうございました。

--------------------------------------------------------------------

#### 一緒に働く仲間を募集中です！

リンクラフト株式会社では、組織拡大に伴い積極的な採用活動を行っています。
少しでも興味がある方はぜひご連絡ください。

▽会社ホームページ
https://lincraft.co.jp/
▽Instagram
https://www.instagram.com/lincraft.inc/
▽ご応募はこちらより
https://lincraft.co.jp/recruit

※カジュアル面談も受付中です。ご希望の方はHPのお問い合わせフォームよりご連絡ください。
エンジニアとPSEの関係

# エンジニア(IT、AI）には直接関係ないですが

:::note info
インフォメーション
会社のリファレンスにしようかと思ったけど、あんまり取り上げない！
:::

# PSE と電気用品安全法

**この辺で重要なのはモノウリの人たち**

:::note warn
警告
我々エンジニアは 販売上のペナルティは受けませんが、変なもの手に入れたら、業者にそっと伝えて挙げましょう！
:::

## メインはこちら

https://www.meti.go.jp/policy/consumer/seian/denan/index.htm


https://www.meti.go.jp/policy/consumer/seian/denan/file/06_guide/seller_guide.pdf

https://www.meti.go.jp/policy/consumer/seian/denan/pse_guide.html


# 業者は罰を！ エンジニアは事故を！

- PSE は一応テストをして安全性を検証するのですが、我々にとっては必須ではないです。
- ただ、日本で使うにはこれはほしいです。アダプタの◇PSE,バッテリの○PSE

## 販売・輸入業者
:::note info
インフォメーション

・ 電気用品安全法に違反した場合の罰則はあります。 例えば電気用品安全法に違反して、PSEマークが表示されていない電気用品を販売したり、販売の目的で陳列したりすると、会社などの法人の場合は１億円以下の罰金、個人でも1年以下の懲役又は１００万円以下の罰金（懲役と罰金が両方科される場合あり）という罰則があります。
:::

## このマークないと注意ですよ。
- エンジニアとしては細かくいう必要なかもしれないけど
- 知っておくといいはず、名前はともかくこのマーク

![hishi_pse.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2155177/8ebc589f-5092-3fef-bb88-b088f317aa7c.gif)


![maru_pse.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2155177/934fa2bd-7178-c1da-5697-7fed52af48a4.gif)

**これらのマークには輸入業者の会社名が記載されます**
- それがなくて、変なマークだけなら使わないように。危ない。

## 使用者としてのエンジニア

:::note info
インフォメーション

- 私たちは日本の基準（法令・規則）に満たない電気用品を使用すると、思うような結果が得られない
- 最悪機器が故障するんじゃないか・・・

:::

# エンジニアだからちょっと作ってみる

https://github.com/mi-kaneyon/PSE_checker

# 業者から購入するときは以前紹介した技適同様注意です

https://qiita.com/Manyan3/items/0ef44f061b5ea8af9cc3
【Linuc102対策】オープンソースのライセンス

# オープンソースライセンスとは
オープンソースを推進しているOSIでは以下の10項目をオープンソースの定義としている。

1. ソフトウェアを自由に販売したり、無償で配布できる
2. ソースコードが入手できる
3. ソフトウェアに手を加えたり、派生ソフトウェアを作ることができる
4. 作者のソースコードの完全性を維持（※完全性：データを最新かつ正しい状態で維持すること）
5. 個人やグループを差別しない
6. 利用分野を差別しない
7. 再配布する時に追加的なライセンスを必要としない
8. ライセンスは特定の製品に依存しない
9. そのソフトウェアとともに頒布される他のソフトウェアに制限を設けない
10. 技術的に中立

# オープンソースライセンスの種類
## コピーレフト型ライセンス
コピーレフトとは著作者が著作物に対する権利（著作権）を保有したまま著作物の配布条件として、利用者に著作物を複写・改変・再配布する自由を与える考え方のこと。

コピーレフト型ライセンスは、①ライセンシの派生物にも同じライセンスを適用し、②他のソフトウェアと組み合わせた場合も組み合わせ先のソフトウェアと同じライセンスを適用する。

コピーレフト型ライセンスの例は以下。
・GPL(GNU General Public License)
当該プログラムを利用するプログラムも、ソースコードの対象となる。ソフトウェアをインターネットで公開する際はソースコードも公開する必要があるが、組織内や個人だけで利用する場合はその限りではない。
GPLv2とGPLv3のバージョンがあり、特許に関する姿勢が大きな違い。


## 準コピーレフト型ライセンス
準コピーレフト型ライセンスは、①ライセンシの派生物にも同じライセンスを適用し、②他のソフトウェアと組み合わせた場合も組み合わせ先のソフトウェアと同じライセンスを適用しなくてもOK。
準コピーレフト型ライセンスの例は以下。

・MPL(Mozilla Public License)
ソースコードの公開は必要だが、当該プログラムを利用するソフトウェアのソースコード公開は要求されない。GPLv2と互換性がある。

## 非コピーレフト型ライセンス
準コピーレフト型ライセンスは、①ライセンシの派生物にも同じライセンスを適用しなくてOK、②他のソフトウェアと組み合わせた場合も組み合わせ先のソフトウェアと同じライセンスを適用しなくてもOK。
非コピーレフト型ライセンスの例は以下。

・MIT License
ソースコードの公開は不要であり、ソフトウェアを改変した場合、MIT以外のライセンスで頒布が可能。

・Apache License
Apacheソフトウェア財団によって作られる。ソースコードの公開は不要。
Apache License2.0とGPLv3には互換性がある。

# おわりに
ライセンスの違いや特徴を正しく理解しよう。
ソフトウェアを利用する時にもライセンスを意識して利用したい。

# 参考
https://yamory.io/blog/about-gpl-license/
https://www.sbbit.jp/article/cont1/34811
API GatewayをIAM認可で呼び出し（REST API: POST, GET）（SigV4リクエスト, boto3）

# 本記事の概要

API GatewayのIAM認可の呼び出しをGETリクエストで行う記事はたくさんあるが、POSTリクエストで行う記事が見つからず苦労したので備忘

# コード

```Python: main.py
import json

import boto3

import botocore.auth
import botocore.awsrequest
from botocore.endpoint import create_request_object
from botocore.httpsession import URLLib3Session

session = boto3.Session(profile_name='CLI_profile_name')

def sign_request(endpoint, method, data, service, region):
    credentials = session.get_credentials()
    auth = botocore.auth.SigV4Auth(credentials, service, region)
    request = create_request_object({
        'method': method,
        'url': endpoint,
        'body': data if method == 'POST' else '',
        'headers': {
            'Content-Type': 'application/x-www-form-urlencoded' if method == 'POST' else 'application/json'
        },
        'params': {},
        'context': {}
    })

    #prepared_request = botocore.awsrequest.AWSPreparedRequest(request)
    auth.add_auth(request)
    return request

def call_iam_protected_api(host, path, body, method='POST', region=None):
    req = sign_request(
        f'https://{host}{path}'
        ,method
        ,json.dumps(body).encode('utf-8')
        ,'execute-api'
        ,session.region_name if region is None else region
    )
    responseBody, statusCode = send_request(req)
    return responseBody

def send_request(prepared_request):
    session = URLLib3Session()
    response = session.send(prepared_request.prepare())
    return response.text, response.status_code
```

# サンプルコード

```Python: main.py
r = call_iam_protected_api('******.execute-api.ap-northeast-1.amazonaws.com', '/path', '{"message": "hello"}', method='POST', region='ap-northeast-1')
print(r)
```

```Python: main.py
r = call_iam_protected_api('******.execute-api.ap-northeast-1.amazonaws.com', '/path', '', method='GET', region='ap-northeast-1')
print(r)
```

# API Gateway側の設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653543/9ff62713-bee2-2179-4716-e6d042e909b6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653543/29f79bc4-bd6a-4c8e-49af-845b0542b8cb.png)

# おまけ（Organization内からのアクセスを許可）

```json: リソースポリシー
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "execute-api:Invoke",
      "Resource": "arn:aws:execute-api:ap-northeast-1:accountId***:api_id***/*",
      "Condition": {
        "StringEquals": {
          "aws:PrincipalOrgID": "o-********"
        }
      }
    }
  ]
}
```
AtCoder初心者 DailyTrainingメモ 2023/11/10

# ABC260 B-問題
https://atcoder.jp/contests/adt_easy_20231109_2/tasks/abc260_b

![260B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547298/5861fdd4-320c-4844-cdf7-1852b1570829.png)

**ポイント**
・リストの最大値とインデックスを取得する
・合格者の得点を「-1」にする

自分のスキルでは、高難度の問題なので色々な方の回答を参考にしました。

````Python:260B.py
N,X,Y,Z = map(int,input().split())
Sugaku = list(map(int, input().split()))
Eigo = list(map(int, input().split()))

# 合格者リスト
ans = []

for i in range(X):
    # Sugaku リストの最大値のインデックスを取得する
    Smax_IDX = Sugaku.index(max(Sugaku))

    # 合格者リストに格納する
    ans.append(Smax_IDX)

    # 合格者リストに格納したので、選考から外すために得点を -1 にする
    Sugaku[Smax_IDX] = -1
    Eigo[Smax_IDX] = -1

for i in range(Y):
    # Eigo リストの最大値のインデックスを取得する
    Emax_IDX = Eigo.index(max(Eigo))

    # 合格者リストに格納する
    ans.append(Emax_IDX)

    # 合格者リストに格納したので、選考から外すために得点を -1 にする
    Sugaku[Emax_IDX] = -1
    Eigo[Emax_IDX] = -1

Both = []
for i in range(N):
    Both.append(Sugaku[i] + Eigo[i])

for i in range(Z):
    # 数学+英語の得点を合わせたリストの最大値のインデックスを取得する
    Both_IDX = Both.index(max(Both))

    # 合格者リストに格納する
    ans.append(Both_IDX)

    # 合格者リストに格納したので、選考から外すために得点を -1 にする
    Both[Both_IDX] = -1

# 条件通り小さい値順にソートする
ans.sort()

for i in ans:
    # インデックスの値なのでプラス１する
    print(i + 1) 
````

# ABC261 C-問題
https://atcoder.jp/contests/abc261/tasks/abc261_c

![261C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547298/cb188bba-f15f-44be-d86b-d887d7fd38b6.png)

**ポイント**
* 連想配列で入力されてくる文字をカウントする。
使い方をマスターすれば、色んな場面で使えると思いました。
※C++ では、map を使っていた。

````Python:261C.py
from collections import defaultdict

N = int(input()) 

# 連想配列でカウントする
cnt = defaultdict(int)

for i in range(N):
    S = str(input())

    # その文字が初めて出現した場合
    if cnt[S] == 0:
        print(S)

    # 複数回出現した場合
    else:
        print(S + '(' + str(cnt[S]) + ')')
    
    # 忘れずにプラス1
    cnt[S] += 1
````
RDS Performance Insights が CloudWatchDashboard へエクスポート可能に

# 背景
「RDS Performance Insights」はデータベースのパフォーマンスを監視し、チューニングするための強力な機能です。

非常に強力なツールでありながらAWSコンソールの専用画面にアクセスしないとパフォーマンスの状況が確認できないという大きな課題を持っていました。

# 新機能
今回、この「RDS Performance Insights」が、メトリクスダッシュボードをAmazon CloudWatchにエクスポートする新機能を発表しました。これにより、パフォーマンスメトリクスをより容易に視覚化し、CloudWatch内で他のメトリクスと統合することが可能になりました。

https://aws.amazon.com/jp/about-aws/whats-new/2023/11/amazon-rds-performance-insights-dashboards-cloudwatch/

# エクスポート手順
## 事前確認
Performance Insights が有効化されている必要がありますので以下を参考に設定してください。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_PerfInsights.Enabling.html

## エクスポート
RDS Performance Insights へアクセスしたら [メトリクス] タブから [CloudWatch にエクスポート] を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22939/e1a3f797-15f5-c163-250d-ad02e02b5264.png)

次に「新しいダッシュボードとしてエクスポート」を選択して [確認する] を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22939/d7e56038-8f1b-a970-6e31-bd587e1e9210.png)

元の画面に戻り、エクスポートされたメッセージが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22939/70f1cda5-23d6-c457-7f0a-f9145051b39f.png)

※「既存のダッシュボードに追加」はその名の通り、既存のダッシュボードを選択すればその末尾にグラフが追加されます。

# ダッシュボード
エクスポートメッセージから [CloudWatch で表示] を押して確認してみましょう。
今までは確認できなかったグラフがダッシュボードで確認できるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22939/ee6dd806-949c-2316-f25b-c449d0915674.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22939/00595f08-4ea1-3025-7876-64aa6e48ef2d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22939/734c7116-644a-7740-7aea-67349794e8fd.png)

# 監視可能なメトリクス
2023/11/10 現在で確認できるメトリクス一覧は以下の通りです。

- CPU 使用率
- 空きメモリ
- メモリ不足によるキル
- IO レイテンシー
- IO オペレーション
- IO スループット
- IO ディスクキューの深さ
- ネットワークスループット
- 接続の使用率
- セッション
- ログイン
- InnoDB の履歴リストの長さ
- クエリ
- クエリレイテンシー
- クエリスループット
- DML
- アクティブなトランザクションとロック
- クエリキャッシュヒット率
- バッファプールのヒット率
- IO キャッシュとディスク読み取り
- 行ロック時間
- デッドロック

# 何が嬉しいの？
## 監視
今までは確認することしかできなかった情報が CloudWatchMetrics で取得できることで監視が可能になりました。
新しく取得できる Metrics にアラートを設定することでオブザーバビリティが向上しました。

## 報告
RDS Perfomance Insights で確認した結果をスクリーンショットで共有することがしばしばありました。
ダッシュボード化できるということはそうです、「ダッシュボードの共有」が可能ということです。
サインインすることなく「皆さんここを見てください」が簡単に実現できるようになりました。

## アクセス
何となく RDS Performance Insights の画面は深いところにあるイメージがありましたが、ダッシュボードで確認できることでアクセスが容易になりました。（なったと思う！）

# まとめ
非常に便利になりましたが、皆さんの中でもほんの少し不満を感じている人がいるかもしれません。
そうです、「ディメンション」です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22939/25d09602-db26-d863-adf7-b319e7baa3d5.png)

こんなに素晴らしい情報を提供してくれているのに、「ディメンション」は奥深くの RDS Performance Insights までアクセスしないと見ることができません。

ですが、ここはまた次回のアップデートを楽しみに待ちたいと思います。

# 一言
皆さん AI で騒いでいる中で地味な記事書いてるなぁと感じつつの執筆でした。
でもこの新機能が具体的にどんなものなのかをすぐに知りたい方もいるだろうということで宜しければ参考にして頂ければと思います。

:::note info
華金のこの時間に何してんだろう(*´ω｀*)
:::
「画面見えていますでしょうか？」←ちょっと変じゃない？

## はじめに
&emsp;
皆さんは業務などで頻繁にオンライン会議をしますか？

&emsp;
今回は私が日常の業務で気になった点について少し調べたので、興味のある人はぜひ最後まで読んでみてください！

&emsp;

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958142/75165cde-fe51-9e68-553f-11fa898bc05e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958142/55378219-e28b-42a6-58ee-820988c06539.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958142/100374a8-fc66-1a17-1361-c98de1bc27ff.png)

&emsp;

ZoomやTeamsの会議やレビューでPCの画面を共有されたときに、

**「画面見えていますでしょうか？」**

と言われたらどう感じますか？

&emsp;

もしかすると、多くの人は違和感を感じないかもしれません。ですが気になって調べたところ、この敬語表現は誤りでした。

&emsp;

この敬語表現のどこが誤りなのか少し調べてみました！

ちなみに同じ職場にいる先輩3人に聞いてみたら、「まったく気にしていなかった」と口をそろえて言っていました。。
&emsp;
## 「～ますでしょうか」は二重敬語
「～ますでしょうか」には、「ます」と「です」の2つの丁寧語が入っていて、これが二重敬語になっているそうです。
&emsp;
単純ですがついつい使ってしまいますね。この二重敬語の解決方法があります！

&emsp;

### 解決方法 その1
#### →<font color="red">「ます」か「です」のどちらかを削除する</front>
二重敬語にしないための簡単な方法は、「です」か「ます」のどちらかを削除することです。
例えば、「です」を削除すると「画面見えていますか」になります。
&emsp;
### 解決方法 その2
#### →<font color="red">別の表現をする</front>
「画面見えていますでしょうか？」を言い直すために、敬語の使い方を考えるよりも、言い回しを変えた方が丁寧に聞こえるのではないかと個人的に感じました。
&emsp;

**「画面見えていますでしょうか？」**
から↓
**「画面共有していますが、見えないなどありましたらお知らせください」**

&emsp;
このように表現すると、会議参加者も「見えてるよ～」などの返答も待たなくて済みます。
あと、少し会議に慣れている感も出て良いかなと思ってます:smile:

&emsp;
## 会議の流れあるある(解決方法 その1)
### 返答を待つパターン
:dog:「〇〇さん、画面共有お願いします」

:cat:「画面共有します」
:cat:「私の画面見えていまか？」

:mouse:「・・・」
:rabbit:「・・・」

:cat:「・・・(気まずい、、)」

:frog:「うん、見えてるよー」

:cat:「ありがとうございます。では今回は～～～、」
&emsp;

画面共有が上手くいっているか確認をすると、相手の返答を待つ必要があって無言の時間が生まれてしまいますよね。私が気にしすぎなことなのかもしれませんが、このパターンだとほぼ確実にこのようになります。

## 会議の流れあるある(解決方法 その2)
### 返答を待たなくても進められるパターン
:dog:「〇〇さん、画面共有お願いします」

:cat:「画面共有します」
:cat:「画面共有していますが、見えないなどありましたらお知らせください」

:cat:「前回は～～～のため✕△でしたが、、」

:mouse:「(ふむふむ)」
:rabbit:「(なるほど)」
&emsp;

後者の解決方法だと、返答の待ち時間や相手に応えてもらう手間も省くことができます！
ただし、このやり方が絶対的に正しいということではないので、ミーティングに参加しているメンバーや雰囲気を見て使い分ける方が良いかもしれません。

## まとめ
ZoomやTeamsの会議やレビューでPCの画面を共有されたときに、「画面見えていますでしょうか？」は実は二重敬語だった。
&emsp;

**二重敬語とは**
・一つの語について、同じ種類の敬語を二重に使ったものを「二重敬語」と言う。
&emsp;

**解決方法 その1 「ます」か「です」のどちらかを削除する**
「です」を削除して「画面見えていますか」にするなど。

**解決方法 その2 別の表現をする**
「画面見えていますでしょうか？」
↓
「画面共有していますが、見えないなどありましたらお知らせください」
&emsp;

ミーティングに参加しているメンバーや雰囲気を見て使い分ける方が良いかもしれませんね:smile:

---
### 引用
#### 二重敬語とは？

一つの語について，同じ種類の敬語を二重に使ったものを「二重敬語」と言います。例えば，「お読みになられる」は，「読む」を「お読みになる」と尊敬語にした上で，更に尊敬語の「……れる」を加えたもので，二重敬語です。

「二重敬語」は，一般に適切ではないとされています。ただし，語によっては，習慣として定着しているものもあります。

#### 【習慣として定着している二重敬語の例】
・（尊敬語）お召し上がりになる，お見えになる
・（謙譲語I）お伺いする，お伺いいたす，お伺い申し上げる
&emsp;

https://www.bunka.go.jp/seisaku/kokugo_nihongo/kokugo_shisaku/keigo/chapter4/detail.html#:~:text=%E4%B8%80%E3%81%A4%E3%81%AE%E8%AA%9E%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%EF%BC%8C%E5%90%8C%E3%81%98,%E3%81%AA%E3%81%84%E3%81%A8%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82
dockerアプデしてからwsl2でたまにdockerコマンドが消滅する

# 症状

私の手元のバージョン：4.25.0 (126437)

dockerをアップデートしてから、wsl2でdockerコマンドを使おうとした際に `docker is not running` というメッセージが出てくる場合がある。しかし、wslを立ち上げた直後などは問題なくdockerコマンドを利用可能であり、常に使えないわけではない。

# 原因

dockerの新しい機能であるresouce saver modeが起動しているとき、wsl2からdockerが操作できなくなる様子。

↓これ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2281726/4364abf2-4685-fd5f-feb2-d43b6b5bd564.png)

デフォルトだと5分でresource saver modeに入るようで、その結果dockerコマンドが使えたり使えなかったりするっぽい。
なお、PowerShellなどからであればセーブモードでも問題なくコマンドは使えるみたいです。

# 対処

docker desktopの設定 -> Resouces -> Advancedにある、Enable Resource Saverのチェックを外しましょう。
[Mac] CapsLockで日本語/英語の切り替えがうまくいかない時

症状
--
システム設定でcontrolキーをCapsLockに入れ替えることで、controlキーを押下すると日本語/英語の切り替えができるところまではうまくいったが、反応がイマイチ悪い。時折、大文字に化けてしまう時がありかなりストレスだった。

原因（多分）
--
システム設定>キーボード>入力ソースの[編集]ボタンにて、以下の設定が原因っぽい？
- ［すべての入力ソース］の、[CapsLockキーで最後にしようしたラテン語系入力ソースと切り替える]がオン

補足説明に「長押しするとすべて大文字で入力できるようになります。」とあったので、大文字に化けてしまう現象の説明もつく。

解決策
--
システム設定>キーボード>入力ソースの[編集]ボタンにて、以下の設定をする

1. ［すべての入力ソース］の、[CapsLockキーで最後にしようしたラテン語系入力ソースと切り替える]をオフに

２.[日本語 - ローマ時入力]にて、以下の設定を行う
 - [入力モード：]にて、[英字]にチェックマークをつける
 - [Caps Lockの動作：] にて、[オンの時「英字」を入力」を選択する
時系列問題用のラージモデル：TimeGPT-1

TimeGPT-1は先月公開された初めての時系列問題用のラージモデルです。
その時は論文だけ出しましたが、最近になってモデル自体もリリースされました。
中国のあるサイトで、実際にこのモデルを使って精度を検証した記事を読みましたので、共有したいと思います。
（私は時系列問題にはあまりやったこと少なく、最新モデルとかについてはあまり詳しくないですが、）
 
まずTimeGPT-1の中身について、細かいところはよくわからないですが、全体的にはLLMと同じく、時系列データをembeedingして、モデルが学習するという流れです。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/e5359e8b-6e9b-b2ef-8f06-4940d023768c.png)

学習に使用されたデータは、様々な分野の時系列データです。約1000億件を使用しました。
 
ラージモデルのために、ほとんどのタスクは基本zero-shotでできます。
または少しfinetuingすれば複雑なタスクにも対応できるようになりますので、結構使いやすいかもしれません。
以下のスクリーンショットは開発者が論文で公開したモデルの精度です。月単位、週単位の場合は一番高くて、日単位や時間単位でも2,3位くらい高いですね。
![11-9-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/3b59184d-763c-1d5b-aa9f-130e7bfc245d.png)

あとは処理速度も注目されました。TimeGPTは平均0.6ms/件の速度で処理を行い、通常の統計モデルやlgbmなどのモデルよりは数十倍速いです。（lgbmは57ms/件）

 
それでこの記事では、その精度が本当に高いのかを実際に試し、スペックを確認しました。
この方は自分のブログのPV数データを使って予測を行いました。
評価指標はmae（平均絶対誤差）とmse（平均二乗誤差）を使用し、確かに他のN-BEATS, N-HiTSとPatchTSTとかのモデルよりも精度が高かったですね。
![11-9-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/dbb7251f-dedd-f4d1-5c40-8eb74e77e840.png)

 
最近Kaggleにも時系列データの異常検出コンペがあります。TimeGPTは区間予測が可能なので、異常検出にも適用できると思います（99%を超えたら異常値と判断するとか）。TimeGPTを使ってやってみたいと思います。
 
精度確認に使われたコードは以下となります。
興味ある方試してみてください。

https://github.com/marcopeix/time-series-analysis/blob/master/TimeGPT.ipynb

論文:

https://arxiv.org/abs/2310.03589
習慣が重要だと思ったときに僕の思うこと

こんにちは！普段は研修採用開発してたりするマツです。

最近会社のデスクに小さいガジュマルをお迎えしたところ、「リンクラ・ふとし」とかいう名前を勝手につけられて狼狽してます。ふとしという名前に愛着が湧き始めてる自分にはもっと狼狽してます。


さて！掲題の件についてちょっとお話しします。


# 習慣

### みなさんは習慣ありますか？
習慣とは、日々の暮らしの中で、繰り返され、しきたりになったものですね。
歯を磨いたり、寝るときはパジャマに着替えたり。
立派な習慣ですね。

習慣一つ一つは小さな出来事です。
でも、それらが積み重なって僕たちの人となりを形作る大きな要素になっています。

小さいけれど毎日繰り返される習慣が僕たちに及ぼす力は、とてつもなく大きいと言われていますね。

だから、習慣が大事。それも良い習慣が大事なんですね。

### そんなこと皆知ってますよね。
だから、良い習慣を見つけて取り入れようとしますよね。

朝早く起きて、ジョギングして、朝ごはんはフルーツとヨーグルト、仕事ではPDCAを回して、自分の機嫌は自分で見て、定時には帰る。お家に帰ったら自炊して、勉強して、ヨガやって、リラックスして早く寝る。

素晴らしいです。

でも問題があります。どうやって習慣にすればいいのでしょうか？
身につけたい習慣を、どうすれば身に着けられるのでしょうか？

習慣が重要だと思うとき、習慣の身につけ方（技能）が大切だなと思うわけです。

# 習慣の身につけ方
習慣を身に着けやすいポイントを何点かご紹介します！

### ポイント１：なりたい自分を見つけ、理想の自分になったかのように振る舞おう！

まず習慣にするには、繰り返し行える行動じゃないと駄目ですよね。
どんな行動が繰り返しやすいのでしょうか？

それは、自分らしい行動です。
逆に、自分らしくない行動は、なかなか繰り返し行えないらしいです。

だから、喫煙している方で、禁煙したいんだ、と思ってる人はなかなか禁煙しにくいそうです。
喫煙している方ならば、「自分は嫌煙家です」ってアイデンティティを自己認識することで禁煙行動に結びつきやすくなるそうです。

### ポイント２：結果じゃない、過程を見るんだ！
なぜ習慣を身に着けたいのか？というと、結果を得たいからだと思います。

運動習慣を作ってシェイプアップしたい。
勉強習慣を作ってより貢献できるようになりたい。
などなど。

わかります。

しかし、習慣を身につけるためには結果を重視するとつまづきます。

日々の行動自体は、小さなステップです。
今日の小さなステップだけを見た場合、その変化は小さくシェイプアップにも貢献にも繋がっていないように見えます。
そうすると、どうなるでしょう。
モチベーションが枯渇してしまうんですね。

将来良くなるから！という思いだけで続けられる人も中にはいるでしょう。
しかし、万人ができることではないでしょう。

習慣を身につけるのに、行動の結果を見てはいけません。
行動そのものを見てください。

運動すること、勉強すること、そのものを達成目標としてください。
モチベーションの枯渇という事態を避け、行動の継続が容易になり、習慣化へつながります。

### ポイント３：いつどこでなにをやるかは明確に！
いつ、どこでなにをやるか決めておくと、決まってないときに比べて倍近く実行されやすいそうです。

習慣化したい行動は、いつどこでなにをやるかを決めておきましょう。

その際、ただ決めておくだけでは行動に繋がらない可能性が捨てきれません。
明確に決めておくことが大切です。

△　お昼休みになったら運動する。
◯　お昼休みになって昼食を食べ終わったら腕立て伏せ運動する。

いつどこでなにをするか決めたら、カレンダーに書き込んじゃってください！

# ３つのポイントで習慣化を加速させてください
いかがでしたでしょうか。

他にもポイントがありますが、効果的で、すぐにでも実行できるものを挙げてみました。

皆さんの習慣づくりに寄与できたならば幸いです。

# 一緒に働く仲間を募集中です！

リンクラフト株式会社では、組織拡大に伴い積極的な採用活動を行っています。
少しでも興味がある方はぜひご連絡ください。

▽会社ホームページ
https://lincraft.co.jp/
▽Instagram
https://www.instagram.com/lincraft.inc/
▽ご応募はこちらより
https://lincraft.co.jp/recruit

※カジュアル面談も受付中です。ご希望の方はHPのお問い合わせフォームよりご連絡ください。
vmstatのデータをVBAで取り込もう②

## 第2弾
### vmstatの結果をvbaでの取り込み

①まずはvmstatの結果をcsv化
※一度csvデータにしたほうが楽。

cat vmstat.txt | column -t | sed -r 's/\s+/,/g' > newvmstat.txt

できたvmstatデータ
```
2023年,11月,10日,金曜日,13:13:01,JST,procs,-----------memory----------,---swap--,-----io----,-system--,------cpu-----,
2023年,11月,10日,金曜日,13:13:01,JST,r,b,swpd,free,buff,cache,si,so,bi,bo,in,cs,us,sy,id,wa,st
2023年,11月,10日,金曜日,13:13:01,JST,0,0,0,3187260,3772,366100,0,0,92,13,80,108,0,0,99,0,0
2023年,11月,10日,金曜日,13:13:02,JST,0,0,0,3186488,3772,366132,0,0,0,0,337,358,0,1,99,0,0
2023年,11月,10日,金曜日,13:13:03,JST,0,0,0,3186616,3772,366132,0,0,0,0,139,189,0,0,100,0,0
2023年,11月,10日,金曜日,13:13:04,JST,0,0,0,3186636,3772,366132,0,0,0,0,204,239,1,0,100,0,0
2023年,11月,10日,金曜日,13:13:05,JST,0,0,0,3186616,3772,366132,0,0,0,0,181,219,0,0,100,0,0
2023年,11月,10日,金曜日,13:13:06,JST,0,0,0,3186672,3772,366132,0,0,0,0,216,269,0,1,100,0,0
2023年,11月,10日,金曜日,13:13:07,JST,0,0,0,3186672,3772,366132,0,0,0,0,180,221,0,0,100,0,0

```

## csvファイルの内容をエクエルに取り込む

```

Sub test()

Open "C:\Users\kenke\OneDrive\デスクトップ\vba\newvmstat.txt" For Input As #1

'Dim usrcpu As Integer

'Dim syscpu As Integer


i = 0
k = 1


  Do Until EOF(1)
    Line Input #1, buf
    
   
   strsplit = Split(buf, ",") 'カンマ区切りで配列へ
   zzz = strsplit(6)
    
   If zzz = "procs" Then
   
     GoTo qqq
     
   
   
   ElseIf zzz = "r" Then
   
     GoTo qqq
   
   Else
   
   usrcpu = strsplit(18)
   syscpu = strsplit(19)
   
   timedate0 = strsplit(0)
   timedate1 = strsplit(1)
   timedate2 = strsplit(2)
   timedate4 = strsplit(4)
   
   timedate = timedate0 + timedate1 + timedate2 + timedate4
   
   
   
   
   End If
   
     
    'シートに数字を入れる
    
   Cells(k, "A") = timedate
   Cells(k, "B") = usrcpu
   Cells(k, "C") = syscpu
   
   k = k + 1
   
qqq:
   

    
  Loop

Close #1



End Sub



```

### 

## 最後に
第3弾はグラフまで追加します。

## 参考
https://orebibou.com/ja/home/201710/20171025_001/
Garmin Watch の月経追跡機能の使用方法

単に歩数やトレーニングを追跡するだけでなく、最近市場に出回っている最高のフィットネストラッカーのほとんどには、睡眠の質からストレスの度合い、月経周期のどの位置にあるかまで、自分の健康状態についてより多くの情報に基づいた決定を下すのに役立つ機能が満載されています 。

市場で最高の Garmin ウォッチがどのように月経周期を追跡しているのかを詳しく知るために、Garmin のシニア プロダクト マネージャーで、月経周期と妊娠の追跡の開発を主導した Jill Kaiser 氏に話を聞きました。

「月経のある人はそれぞれ異なります」とカイザー氏は説明した。「私たちは、ユーザーがBody Battery 機能、睡眠中、パフォーマンス内で見るのと同じように、自分たちの傾向を理解し、確認できるようにしたいと考えています。周期を通じて体がどのように変化するかは非常に重要なので、私たちはその力をユーザーに与えています。」

Garmin の月経追跡機能は、周期のどの位置にいるかを示すだけでなく、周期に応じてトレーニング方法についてのヒントやヒントを提供します。月経周期には、月経、卵胞期、排卵、黄体期の 4 つの主要な段階があります。ホルモンは周期の各段階で変化し、運動はホルモンバランスに影響を与えるため、周期に合わせて運動習慣を変えることが役立つと考える女性もいます。 

たとえば、プロゲステロンとエストロゲンは月経中に最低レベルになります。エネルギーやモチベーションが低下していると感じ、スタミナや持久力を必要とするペースの速い有酸素運動を行うのが難しく感じるかもしれません。 

卵胞期にはエストロゲンレベルが上昇し、より多くのエネルギーが得られるため、高強度の運動を行うのに最適な時期になります。 

排卵中もエネルギー レベルは高い状態が続く可能性がありますが、膨満感を感じる場合があります。 

黄体期には、厚くなった子宮内膜を維持するために、体はプロゲステロンを放出します。プロゲステロンの増加により、疲労感が増す可能性があります。黄体期にも体温が上昇し、運動に影響を与える可能性があります。たとえば、ある研究では、体温の上昇がランニングのパフォーマンスに影響を与える可能性があることがわかりました。もちろん、これはランニングを避けるべきだという意味ではなく、セッションで速いペースに達することがより困難になる可能性があるというだけです。 

Garmin Connect での月経追跡機能の仕組みと、それをウォッチに追加する方法について詳しくは、以下をお読みください。 

Garmin Watch の月経追跡機能の使用方法

Garmin の月経追跡機能はどのように機能しますか 

皮膚温度の測定値を調べる他のトラッカーとは異なり、Garmin の月経追跡機能はユーザー情報に基づいています。「ユーザーは、自分の周期情報を設定します。これは、最終月経の開始日と周期の一般的な長さです。その後、身体症状、気分、おりものなどのログ機能がすべて提供されます」とカイザー氏は述べました。また、レポート ビューで経時的な平均サイクルも確認します。これには、1 サイクル、6 サイクル、および 12 サイクル ビューが表示されます。私たちは 6 つのサイクルを取得し、それらを平均して予測を出します。」  

現時点では、多くの Garmin ウォッチには温度センサーが内蔵されていますが、皮膚温度の測定には使用されていません。環境の影響を受ける可能性がありますが、皮膚温は中核体温の指標となる可能性があり、体温の上昇は排卵を示します。これは将来の時計に登場する可能性があり、Oura リングやApple Watch Series 8などのデバイスが排卵を予測する方法です。 

Garmin Watch の月経追跡機能の使用方法

Garmin Watch にサイクルトラッキングを追加する方法 

始める準備はできていますか? ここでは、Garmin Connect で周期追跡を設定する方法と、互換性のある Garmin ウォッチに Women's Health ウィジェットを追加する方法を説明します。 

月経追跡を設定するには、携帯電話またはコンピュータでGarmin Connectにサインインします。
メインメニューを開き、「健康統計」を選択します
ドロップダウンから月経周期を選択します
その後、ウォッチは、最終生理の初日など、セットアップを完了するための詳細を尋ねます。
ここから、Garmin Connect アプリの「症状の追加」および「メモの追加」セクションで追跡を開始し、追加データを追加できます。
Garmin Watch の月経追跡機能の使用方法

周期のどの位置にいるかを確認するたびに携帯電話に手を伸ばす必要がない場合は、時計に周期追跡機能を追加できますが、少し面倒です。これを行うには、Women's Health アプリをダウンロードする必要があります。その方法は次のとおりです。 

Garmin Connect アプリから Garmin Watch 設定をクリックします。
「アクティビティとアプリ」オプションを選択します
「Open Connect IQ Store」をクリックし、「Women's Health Tracking」を選択します。
ダウンロードすると、ウォッチのアプリのリストに Women's Health が表示され、メニューに含まれる周期情報を手首から確認できるようになります。
ロー対ウェイドの訴訟を覆す最高裁判所の判決を受けて、米国の女性たちは生理管理アプリの安全性を懸念している。Garmin のプライバシー ポリシーの詳細と、個人データを安全に保つためのサイバー セキュリティの専門家からのアドバイスについては、こちらをご覧ください。 

携帯電話から生理を追跡しないことを選択した場合は、アプリを使用せずに生理を追跡する方法を次に示します。 

私たちのガイドの詳細:
https://officetips.wiki/ja/%E3%83%95%E3%82%A3%E3%83%83%E3%83%88%E3%83%8D%E3%82%B9/garmin-watch-%E3%81%AE%E6%9C%88%E7%B5%8C%E8%BF%BD%E8%B7%A1%E6%A9%9F%E8%83%BD%E3%81%AE%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95/11101146
Djangoの学習⑧（スタイルシートや画像の追加）

Webアプリケーションは一般的に完全なWebページをレンダリングするために、
画像、JavaScript、CSSなど必要なファイルを提供する必要があります。
Djangoでは、これらのファイルを "静的 (static) ファイル" と呼びます。

## CSSの追加

最初に、 polls ディレクトリの中に、 static ディレクトリを作成します。
Django はそこから静的ファイルを探します。
Django が polls/templates/ からテンプレートを探す方法と同様です。

作成した static ディレクトリ内に polls という名前のディレクトリを作り、
その中に style.css というファイルを作成します。


```css:polls/static/polls/style.css
li a {
    color: green;
}
```

次に、polls/templates/polls/index.html の上部に以下を追記します

```html:polls/templates/polls/index.html
{% load static %}

<link rel="stylesheet" href="{% static 'polls/style.css' %}">
```


サーバーを起動します (すでに起動済みの場合は再起動します)。


```
$ python manage.py runserver
```

http://localhost:8000/polls/ をリロードすると、
質問のリンクが緑色になり、
スタイルシートが適切に読み込まれたことが確認できます。

## 画像の追加

画像を追加する場合は、polls/static/polls/ ディレクトリの中に 
images サブディレクトリを 作ります。
ディレクトリの中に背景と使用したい画像ファイルを追加します。


```css:polls/static/polls/style.css
body {
    background: white url("images/background.jpg") no-repeat;
}
```

再起動して、画像が表示がされれば成功です。
【豆知識】「フールプルーフ」であまり知られていないこと

## 結論

逆から読んでも「フールプルーフ」

これで「フールプルーフ」というワードを忘れちゃう人は回文だということを覚えていれば「フール」だけから導き出されるようになったね。よかったよかった。
jQuery(document).on("click","selector", function(e){});をpure javascriptで書き換える

実際の要素ができる前でも処理が書けて便利だからと多用されていた
```javascript
// jQuery
jQuery(document).on("click","selector", function(e){
    // 要素は$(this);
    var $el = $(this);
    // 処理
});
```
はpure javascriptだと
```javascript
// javascript
document.addEventListener('click', function(e){
    let el;
    if(el = e.target.closest('selector')){
        // 要素は e.target.closest('selector')で取ると確実
        el;
        // 処理
    }
});
```
と書き換えられる。
面倒なのは2点、
1. e.currentTargetは常にdocument
1. selectorの子孫要素もMatchさせないといけないから要素を取るならclosestを使うと確実
Vue3 + KeyCloakで "Navigation to external protocol blocked by sandbox, ..." エラー

# はじめに
以下記事の作業をしていた際に掲題のエラーが出て解決に時間がかかったので備忘です
※以下記事を書き終わってから本記事を書くために再現しようと思ったらなぜか再現できなかったので、覚えている範囲で書きます

https://qiita.com/UMA9626/items/f15f061684a77815a441

# 事象
ブラウザのコンソールで以下エラーが発生する
`Navigation to external protocol blocked by sandbox, because it doesn't contain any of: 'allow-top-navigation-to-custom-protocols', 'allow-top-navigation-by-user-activation', 'allow-top-navigation', or 'allow-popups'`

# 調査
調べたところ、iframeで`sandbox`が指定されている場合に外部プロトコルへ移動しようとした際にエラーとなるようです。

https://chromestatus.com/feature/5680742077038592

https://chromeenterprise.google/policies/#SandboxExternalProtocolBlocked

ただ、なぜか記事投稿後の今は発生しない...
iframe自体は`keycloak-js`の`keycloak.js`内で追加されており、開発者ツールで見てもsandboxが指定されたiframeが追加されているのでなぜ発生しないのかが分かっていません。
(分かる人いたら教えて頂けるとありがたいです)
```javascript:keycloak.js
        ...
	    function check3pCookiesSupported() {
	        var promise = createPromise();

	        if (loginIframe.enable || kc.silentCheckSsoRedirectUri) {
	            var iframe = document.createElement('iframe');
	            iframe.setAttribute('src', kc.endpoints.thirdPartyCookiesIframe());
	            iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin'); // ここで設定して
	            iframe.setAttribute('title', 'keycloak-3p-check-iframe' );
	            iframe.style.display = 'none';
	            document.body.appendChild(iframe); // ここで追加している
                ...
```

# 暫定対応
もし仮に同じ状況になった人のために書いておくと、上記にも書いてありますがiframeを追加する前の条件分岐が以下となっています。
```javascript
if (loginIframe.enable || kc.silentCheckSsoRedirectUri)
```
なので、上記どちらもfalseになるようにすれば良いです。

これらはコードを追っていくと明示的にfalseにできそうな箇所がありました。
```javascript:keycloak.js
        ...
	    kc.init = function (initOptions) {
          console.log('hogehhoge')
          if (kc.didInitialize) {
	            throw new Error("A 'Keycloak' instance can only be initialized once.");
	        }

	        kc.didInitialize = true;

	        ...中略

	        if (initOptions) {
	            ...中略

	            if (typeof initOptions.checkLoginIframe !== 'undefined') {
	                loginIframe.enable = initOptions.checkLoginIframe; // ここと
	            }

	            ...中略

             	if (initOptions.silentCheckSsoRedirectUri) {
	                kc.silentCheckSsoRedirectUri = initOptions.silentCheckSsoRedirectUri; // ここ
	            }

                ...
```
というわけで、`keycloak.init()`の引数のオブジェクトに`checkLoginIframe: false`を追加し、`silentCheckSsoRedirectUri`は指定しなければ良さそうです。

エラーが発生していた当時は上記対応でエラーが出なくなりました。
ただ、今は`checkLoginIframe: false`を追加しなくてもエラーが出ないため、あくまで暫定対応でしかないと思います。

# おわりに
なんとも気持ち悪い状態ですが、原因が分からずに直っている状態です。
エラーが出た当時は記事に記載しているソースとは結構違っており、おそらく何か悪い実装をしていた結果発生した事象なのかなと思います。
もし何か分かれば or 指摘があれば記事追記します。
React Developer Toolsで Strictモードで2回ログ出るのを消す設定

## 概要
React Developer Toolsを使っていて、StrictModeが有効になっていると`console.log()`などでデバッグした際に、2個同じ値が出てしまうのが鬱陶しかったので、無効にしてみたら快適でしたって記事ですｗ

早速ささっと画像で順序説明。

1. React Developer Toolsのタブで、歯車マークを押す 
![スクリーンショット 2023-11-10 18.36.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1040483/be80c868-1739-77a7-d4bd-93fd7b0e1dba.png)

2. Hide logs during second render in Strict Modeにチェックを入れる
![スクリーンショット 2023-11-10 18.37.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1040483/03c92d91-55b3-e502-7d9a-a76f55f73760.png)

終わり。
Macで謎のアプリケーションで恐ろしいくらい容量を食っていた原因を突き止めた。

おそらく原因は、iCloudでアップロードかダウンロードで何らかの原因で途中で中断してしまい、ダウンロード時？のキャッシュが残ったままになっていた。

以下の中身を消しましょう。[自己責任！]
```
/Users/ユーザーネーム/Library/Application\ Support/CloudDocs
```
削除時にパスワードなどは求められないので、削除すると超危険とかそういうわけではないと思います。

ちなみにフォルダーごと削除しても、数分すると、勝手に再度作成されていました。

これを削除したことで200GBほど容量を削減できた。

以上。
『配列をN個ずつに分割したい』みたいな時には Object.groupBy がとてもよい

`Object.groupBy`がとてもよい。

たとえば『配列をN個ずつに分割したい』みたいな時には、`reduce()`で書いたり、最近だと`flatMap()`で書いたりするが、わりと泥臭いというか可読性の悪いコードになりがちだった。
でも、まさかの時の`Object.groupBy`。

```js
    Object.values(Object.groupBy(
        ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j",],
        (...[, i]) => Math.floor(i / 3)
    ));

// [
//     ["a", "b", "c"],
//     ["d", "e", "f"],
//     ["g", "h", "i"],
//     ["j"]
// ]
```

剰余にすれば、行列入れ替えバージョンも。

```js
    Object.values(Object.groupBy(
        ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j",],
        (...[, i]) => i % 3
    ));
    
// [
//     ["a", "d", "g", "j"],
//     ["b", "e", "h"],
//     ["c", "f", "i"]
// ]
```

ちょっと可読性がいまいちだけど、Python の `zip`関数もどきとか。

```js
    const zip = (...args) => {
        const minLength = Math.min(...args.map(x => x.length));
        return Object.values(Object.groupBy(
            args.flatMap(x => x.slice(0, minLength)),
            (...[, i]) => i % minLength
        ))
    }

    zip(["a", "b", "c"], ["A", "B", "C", "D"], [0, 1, 2])

// [
//     ["a", "A", 0],
//     ["b", "B", 1],
//     ["c", "C", 2]
// ]
```
brewとanyenvでJavaの環境構築［M1 Mac］

<h1>準備</h1>

下準備として、Homebrewとanyenvのインストールを行います。Homebrewのインストールは以下の記事を参照してください。

https://qiita.com/Hr_0531/items/d34b509748db77a7e63e

続いてanyenvのインストールを行います。`brew install anyenv`を実行してください。

```zsh
% brew install anyenv
==> Pouring anyenv--1.1.5.arm64_ventura.bottle.tar.gz
🍺  /opt/homebrew/Cellar/anyenv/1.1.5: 23 files, 31KB
```

続いて、`anyenv init`を実行します。

```zsh
% anyenv init
# Load anyenv automatically by adding
# the following to ~/.zshrc:

eval "$(anyenv init -)"
```

上記のような出力が確認できたら、以下のコマンドを順番に実行してください。

```zsh
% echo 'eval "$(anyenv init -)"' >> ~/.zshrc
% source ~/.zshrc
```

これでインストールは完了ですが、以下のような画面が出ることがあります。

```zsh
ANYENV_DEFINITION_ROOT(/Users/home/.config/anyenv/anyenv-install) doesn't exist. You can initialize it by:
> anyenv install --init
```

この場合、指示通り`anyenv install --init`を実行してください。

<h1>Javaのインストール</h1>

<h3>1.Javaのインストール</h3>

Jenvには`install`コマンドがありません。あらかじめ外部からJavaの本体をインストールしておく必要があります。公式サイトからダウンロードする方法もありますが、ここではbrew経由でインストールする方法を紹介します。

```zsh
% brew serch java
==> Formulae
google-java-format         java11                     jslint4java
java                       javacc                     libreadline-java
java-service-wrapper       javarepl                   pdftk-java

% brew install java11  # 好きなものを入れる
```
インストールが終わると次のように出力されます。

```zsh
==> Caveats
For the system Java wrappers to find this JDK, symlink it with
  sudo ln -sfn /opt/homebrew/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdk

openjdk@11 is keg-only, which means it was not symlinked into /opt/homebrew,
because this is an alternate version of another formula.

If you need to have openjdk@11 first in your PATH, run:
  echo 'export PATH="/opt/homebrew/opt/openjdk@11/bin:$PATH"' >> ~/.zshrc

For compilers to find openjdk@11 you may need to set:
  export CPPFLAGS="-I/opt/homebrew/opt/openjdk@11/include"
==> Summary
🍺  /opt/homebrew/Cellar/openjdk@11/11.0.21: 667 files, 296.2MB
```

出力結果をみると、（よくわからないが）openjdk@11はkeg-onlyなのでシンボリックの作成が必要らしい。次にパスを通すコマンド。Shellの環境変数'CPPFLAGS'を設定するコマンドが書かれています。
順番に実行していきましょう。

```zsh
% sudo ln -sfn /opt/homebrew/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-11.jdk
% echo 'export PATH="/opt/homebrew/opt/openjdk@11/bin:$PATH"' >> ~/.zshrc
% export CPPFLAGS="-I/opt/homebrew/opt/openjdk@11/include"
% source ~/.zshrc
```

<h3>2.jenvのインストールと設定</h3>

jenvをインストールするために以下のコマンドを順番に実行します。

```zsh
% anyenv install jenv
% exec $SHELL -l
```

jenvでJavaを管理するために、Shellの設定ファイル（.zshrc）にjenvの初期化コマンドを追加します。

```zsh
% echo 'export PATH="$HOME/.jenv/bin:$PATH"' >> ~/.zshrc
% echo 'eval "$(jenv init -)"' >> ~/.zshrc
% source ~/.zshrc
```

次に、以下のコマンドでjenvにopenjdk@11を追加します。

```
% jenv add /opt/Homebrew/opt/openjdk@11
```

jenvがopenjdk@11を認識しているか確認します。以下のように出力されれば正常にインストールできています。

```zsh
% jenv versions
* system (set by /Users/home/.anyenv/envs/jenv/version)
  11
  11.0
  11.0.21
  openjdk64-11.0.21
  ```