OmniAICreator/Qiita-1.07M huggingface dataset:
様々なプライバシー保護技術の比較



プライバシー保護技術は多岐にわたり、各技術には独自の強みと限界があります。以下に、主要な技術（VPN、Tor、dVPN、I2P、NymVPN）を比較し、それぞれの特性とプライバシー保護の程度について詳しく見ていきましょう。

### VPN（Virtual Private Network）

**特徴:**
- インターネットトラフィックをリモートサーバーに暗号化して転送。
- ISPからオンライン活動を隠す。

**プライバシー保護の程度:**
- VPNプロバイダーへの信頼が必要。
- トラフィックの暗号化は行うが、プロバイダーがトラフィックを監視する可能性がある。
- 無料VPNは特にリスクが高く、データを販売することがある。
- 中央集権型であるため、データ漏洩のリスクがある。

### Tor（The Onion Router）

**特徴:**
- データを3つのサーバー（ホップ）を通じて暗号化し、トンネルを作成。
- オニオン暗号化で複数層の暗号化を提供。

**プライバシー保護の程度:**
- 非常に高いプライバシー保護（特にローカルな攻撃者から）
- NSA等のネットワーク全体を監視できる敵に対しては脆弱性がある。
- ボランティアによる運営であり、持続可能性やパフォーマンスに問題がある。

### I2P（Invisible Internet Project）

**特徴:**
- ピアツーピアネットワークで、すべてのユーザーがクライアントでありルーターでもある。
- ガーリック暗号化を使用し、複数のメッセージをバンドルして暗号化。

**プライバシー保護の程度:**
- Torと同様にローカルネットワークの敵から保護。
- トラフィック解析攻撃に対しては限界があり、ボランティアベースで運営されているため、信頼性や持続可能性に問題がある。

### dVPN（Decentralized VPN）

**特徴:**
- 中央集権型ではなく、分散型のネットワークを利用。
- ノードがインセンティブ化され、暗号通貨で報酬を受け取る。

**プライバシー保護の程度:**
- ノードが個人によって運営され、データが分散されるため、プライバシー保護が強化される。
- マルチホップルーティングを提供するものもあり、Torのような多層保護が可能。
- ただし、トラフィックミキシングがない場合、トラフィック解析攻撃に対して脆弱である。

### NymVPN

**特徴:**
- 5ホップミックスネットを基にし、通信パターンをシャッフル。
- トラフィックミキシングにより、データ追跡をほぼ不可能にする。
- プライバシーと速度のバランスを最適化したモードを提供。

**プライバシー保護の程度:**
- 非常に高いプライバシー保護を提供し、政府レベルの敵対者に対しても強固な防御を持つ。
- 通信パターンのシャッフルにより、タイミングやパケットの相関が防止される。
- エンドツーエンドで分散化されており、中央集権型のログ記録は存在しない。
- インセンティブ化されたノードによる運営で、高品質なサービスが提供される。

### まとめ

- VPNは一般的なプライバシー保護を提供するが、プロバイダーへの信頼が必要で、データ漏洩のリスクがある。
- Torは高い匿名性を提供するが、ネットワーク全体を監視できる敵には脆弱。
- I2Pはボランティアベースで、信頼性や持続可能性に問題があり、トラフィック解析攻撃に対して限界がある。
- dVPNは分散型のメリットを提供し、ノードのインセンティブ化によりパフォーマンスを維持できるが、トラフィックミキシングがない場合、トラフィック解析攻撃に対して脆弱。
- NymVPNは、非常に高いプライバシー保護を提供し、5ホップミックスネットにより、通信パターンのシャッフルが行われ、最も高いレベルのプライバシー保護を実現しています。

それぞれの技術が持つ利点と限界を理解し、自分のプライバシー保護ニーズに最適な選択をすることが重要です。

# sponsor

HStorageは、高度なセキュリティ機能を提供しているオンラインストレージサービスです。

![Screenshot 2024-08-07 at 2.26.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3672851/82985efd-ae04-b64f-49eb-502d257897c3.png)
https://hstorage.io/

# 参考リンク

- [Nym公式サイト](https://nymtech.net/)
- [Nymのミキシングネットワーク - Wikipedia](https://ja.wikipedia.org/wiki/Nymミックスネット)
- [Nymホワイトペーパー](https://nymtech.net/nym-whitepaper.pdf)
- [分散型VPN と中央集権型VPN:違いの全て](https://note.com/koko_crypto/n/n71fe7e92b68a)
- [ミックスネットとは何か？ VPNによる比類なきオンラインプライバシー](https://note.com/koko_crypto/n/n302e7516f691?magazine_key=m0129d65e3526)
- [Sphinx暗号-Nymを支える匿名データフォーマット](https://qiita.com/pseudonym2/items/107cf005e9cab0b165b6)
- [ココナッツ認証（Coconut Credentials）とは？- プライバシーを保護するゼロ知識証明技術](https://qiita.com/pseudonym2/items/b2739ae32f4fb29de0b6)

# コミュニティ

- [Nym日本コミュニティ - Telegram](https://t.me/nymjapanese)
- [Nym日本コミュニティ - Discord](https://discord.com/invite/nym)
- [Nym日本コミュニティ - LINEオープンチャット](https://line.me/ti/g2/0YGYYq4EoQZ8fL5FYQmqU4O9SRuE_a6YX19GtA?utm_source=invitation&utm_medium=link_copy&utm_campaign=default)
- [Nym 公式LINE(現在非稼働)](https://line.me/R/ti/p/@986ytsdx?from=page&accountId=986ytsdx)
- [Nymプロジェクト日本語アカウント - X](https://x.com/nymproject_jp)
ことすたぐらむ-New.ver

以前、ことすたぐらむとして、インスタグラムの自動化をseleniumと、pythonのライブラリを使用し、行いました。
その時点で、InstaPyというライブラリが存在することは把握していたのですが、手を出しておりませんでした。
以前作成したものが使い物にならなくなりました（特にselenium）。
しかし、InstaPyは常時アップデートを繰り返されているため、長く使用することが可能かと考えました。
正直なところ、以前使用していたライブラリはとても便利でしたので、そちらもアップデートが加えられているのであれば、こちらも使用したいと思います。
長くなりましたが、これからこちらに目次を追加していきますので、ぜひウォッチしてくださいね。
Accessのフォームを閉じる時に発生する3つのイベント

# 概要

Accessのフォームを閉じる時は『閉じる時』という名前のイベント以外も発生します。
『閉じる時』イベント以外は使うことあまりなくて、忘れがちなのでまとめ。

**どんなイベントが** **どの順番で** 実行されるのか。

# 発生するイベント

## ① Form_Unload()

まずは『読み込み解除時』が発生します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/5b141a90-82e2-c5ad-d82c-f2f2de3fba94.png)

## ② Form_Deactivate()

次に『非アクティブ時』。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/d5d97f8c-c071-5914-de9e-c4667e356f4a.png)

## ③ Form_Close()

最後に『閉じる時』。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/1a2da379-9c35-1394-f4c6-a0972651f3c7.png)

# 蛇足

逆に開く時のイベントを知りたい時は下記。

https://qiita.com/waokitsune/private/e30338b963a4ed86e73b

# 参考サイトさん

https://learn.microsoft.com/ja-jp/office/vba/api/access.form.unload

https://learn.microsoft.com/ja-jp/office/vba/api/access.form.deactivate

https://learn.microsoft.com/ja-jp/office/vba/api/access.form.close

# バージョン

Microsoft Windows [Version 10.0.22631.3880]
Microsoft Access for Microsoft 365 MSO (バージョン 2406 ビルド 16.0.17726.20078) 32 ビット
データベースは構造体

# データベースは構造体である
これはプログラマなら感覚として認識しているところだと思いますが、より正確な表現をすると、「データベースにおいて表現できるデータ構造とstructにおいて表現できるデータ構造は全く同一である」ということです。この考え方は非常に重要で、プログラムにおけるオブジェクト設計とデータベース設計は非常に似た考え方を持っており、概念としても実装においても、この2つは相互に影響し合う相互依存の関係になっています。

# データベースと構造体の関係
データベースにおいてテーブル設計をする際は、プログラムにおいてどのようなstructとして利用するかを意識して設計しておくべきでしょう。例えば、一つのstructに対しては、structと同じ項目をカラムに持った一つのテーブルが対応するような設計となっているべきでしょう。しかし通常、データベースはプログラムのstructよりも先に決定されます。テーブル定義や、DB正規化という考え方は、単にDBの構造について話しているわけではなく、DB正規化によってプログラム内のstructを正規化し、テーブル定義によってプログラムにおけるstructを定義していると考えることができるのです。
また機能的な面ではデータベースは構造体の機能を包含していることを明らかにすることができます。テーブルにはテーブル名とカラム名、カラムのデータ型しかありません。構造体も同じように、構造体名とメンバ変数、メンバ変数のデータ型しかありません。つまりデータベースにおいて表現できるデータ構造とstructにおいて表現できるデータ構造は全く同一なのです。

# データベースとEnum
ここで、一つの疑問が浮かびます。structにはenum型が使えますが、データベースにはenum型はありません。やっぱりデータベースとstructは同一ではありませんでした...ちゃんちゃん。
否、ちょっと待ってください。データベースにはforeign key constraint(外部キー制約)という機能があります。データベースのカラムにおいて、enumのように一定の値しか取り得ないという制約は、foreign key constraintによって実現できます。このとき、foreign keyを持つ親テーブルは、それ自体がenumのような役割を持ちます。オブジェクトにおいてenumの値を増やした際には、この親テーブルも同時に変更することで、外部キー制約を保つことができます。
【スプレッドシート】Query関数で該当するはずの文字を抽出できない場合の対処法

## Qeruy関数を使ってデータ抽出をしたい
Query関数は、2024年7月時点でプレッドシートでしか使えない関数です。
先日、Query関数でキーワードを含む文字列を抽出するようにしたのですが、
where句で指定した文言を含んでいるにもかかわらず、抽出できない問題が発生しました。

以下はサンプルです。
C2 ~ C4の3セルに検索キーワードを3つ指定できます。
入力したキーワードが、右のマスタの商品説明(H列)に該当するものがあると、
商品ID(E列)と商品名(F列)を抽出してくれます。

```Q
// B6に入力してます
=QUERY(E2:H,"select E,F where H matches '.*" & TEXTJOIN(".*|.*", TRUE, C2:C4) & ".*'" )
```

▼キーワードを何も指定していない場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317240/c3e60013-a55c-6186-e931-f254f354352c.png)

▼「回復」を指定した場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317240/87af2ee5-cce1-9845-f97c-1354f8dd6300.png)

▼「回復」「爆発」を指定した場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317240/3c93d90e-ab6d-a117-dc1e-37db239a71dd.png)

## キーワードに該当するはずなの抽出できない！
▼「回復」を指定した場合
の画像をもう一度見てください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317240/c36d3809-931e-4ea1-ab0c-fbeaca1efa8f.png)

スニッカーズの商品説明に「回復」が含まれているのに、Query関数で拾えていません！

原因はぱっと見でわかると思いますが、「**セル内改行がある**」ためです。
当時、何百行とあるデータに対してQuery関数を使っていたため、デバックしても気づくのに2時間ぐらいかかりました...

## セル内改行が悪さをしている
これは恐らく仕様なのですが、ネット上に情報がなくどうすればいいのか悩みました。
というより、**セル内改行がない部分は正常に取れてきている**というのがたちが悪いです。
この世の中でQuery関数は結構使われているものだと思いますが、この仕様を知らないと抜け漏れが発生します。

じゃあどうすれば正しくとれるのかというと、**Query関数内でセル内改行を削除するだけ**です。
データのセル内改行を削除する必要はありません。

```Q
=QUERY(
ARRAYFORMULA(SUBSTITUTE(SUBSTITUTE(E2:H, CHAR(10), ""), CHAR(13), "")),
"select Col1,Col2 where Col4 matches '.*" & TEXTJOIN(".*|.*", TRUE, C2:C4) & ".*'" )
````
当たり前と思う人もいるかと思いますが、
改行ってな、3種類あんねん（\r、\n、\r\n）

これをすべて削除します
それが
SUBSTITUTE(SUBSTITUTE(E2:H, CHAR(10), ""), CHAR(13), "")
の部分です。
ただし、ARRAYFORMULAを使わないとすべてのセルに対して処理が行われませんので、一緒につかって下さい。

そしてもう一つ注意があります。
抽出対象のセルです。
先ほどはH列を条件に、E,Fを抽出するという書き方でしたが、
select **Col1**,**Col2** where **Col4** 
Col（カラム）を使う必要があります。

SUBSTITUTEで元データを破壊（加工）してしまっているため、
EやFという列番号でデータを指定できなくなってしまいます。
そのため、Col1やCol2のように番号で列を指定する必要があります。

▼修正後に「回復」で検索
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1317240/689520de-e6f1-cb74-fe5e-6a13177aaecc.png)

無事、スニッカーズも抽出できました！

よかったね！スニッカーズ！
JavaScriptで半角数字を全角数字に変換する

# やり方
画面で作ってみました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/ff490020-a619-7f2f-bac0-8eacc9cfd1ca.png)



```ruby:
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数字変換ツール</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            padding: 20px;
        }
        input, button {
            font-size: 16px;
            margin: 10px 0;
        }
        .output {
            font-size: 20px;
            font-weight: bold;
            color: blue;
        }
    </style>
</head>
<body>
    <h1>半角数字を全角数字に変換</h1>
    <label for="input-number">半角数字を入力してください:</label>
    <input type="text" id="input-number">
    <button onclick="convertToFullWidth()">変換</button>
    <p>変換後の数字: <span class="output" id="output-number"></span></p>

    <script>
        function toFullWidthNumber(numStr) {
            const offset = '０'.charCodeAt(0) - '0'.charCodeAt(0);
            return numStr.replace(/[0-9]/g, function(ch) {
                return String.fromCharCode(ch.charCodeAt(0) + offset);
            });
        }

        function convertToFullWidth() {
            const inputNumber = document.getElementById('input-number').value;
            const outputNumber = toFullWidthNumber(inputNumber);
            document.getElementById('output-number').textContent = outputNumber;
        }
    </script>
</body>
</html>

```
PRで余計な差分を大量に指摘された場合に一気に修正する方法

# はじめに
最近、インターン(といっても大学の先輩のお手伝いですが）でwebアプリケーション開発に携わる機会をいただいたのですが、私はPRでコードレビューやってもらったことがありませんでした。
最初のインターンでUnityを使った共同開発を行ってはいましたが、コードレビューをしていただく機会がなかったので、今回のインターンでコードレビューで指摘をいただいた時とても困りました。
なのでこれからインターンに参加する方が困らないように、記事で残しておこうと思います。

# どんな感じに指摘されたか

実際に指摘されたのは、要らない差分があるという指摘でした。
![スクリーンショット 2024-07-08 14.29.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/c545c565-088b-1281-b19b-08fcf0f24abc.png)

>これが大量にありました。アホです。

この場合解決方法として

- 改行（差分）を消す
- gitのresetコマンドを使う
があります。

ですが、改行を消すとなるとかなりのファイルを移動することになるので、gitのresetコマンドを使ってみようと思います。

# 修正してみる
まず下のコマンドでコミットIDを探します。
```
git log
```

すると下の画像のように`commit`という文字の後ろに長い文字列が書いてあると思います。これがコミットIDです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/f4ae728f-ae98-d607-259b-f9581d69294d.png)
>引用:https://www.kagoya.jp/howto/rentalserver/webtrend/gitlog/

ここからどこのコミット履歴に戻りたいかを選択します。
そして以下のコマンドで履歴を戻します。
```
git reset --hard <コミットID>
```
:::note
Git Flowに沿って行うと、develop等のブランチから切ると思うので、(develop)と書かれているところに戻るといいんじゃないかなと思います。
:::

ただこれだと戻さなくていい変更も戻ってしまって困ると思います。
ですが、PRの`Files Changed`を見れば自分が変更したコードの内容を確認できるので、その内容をコピペとかで戻します。
> もしかしたら他の方法で簡単に戻す方法があるかもしれません。また調べてみます。


変更したら以下のコマンドでフォースプッシュします。
```
git push -f <リモートリポジトリ> <リモートブランチ名>
```

:::note
force pushの取り扱いは慎重に！
:::
><リモートリポジトリ名>は多分originにしてるんじゃないかなと

これでPRの`File Changed`を確認すると変更したコードが適応されていると思います。

もしこの記事が初めてのインターンで困った方のお役に立てればと思います。
OCI OpenSearchのメトリクスをPrometheusで取得する

# はじめに
OCI OpenSearchをPrometheusで監視する手順について説明します。
OCI OpenSearchは、高性能でスケーラブルな検索エンジンであり、全文検索、ベクトル検索、ログ分析等に広く使用されています。

https://speakerdeck.com/oracle4engineer/oci-search-service-with-opensearch-gai-yao

Prometheusはオープンソースの監視ソリューションで、多様なシステムのメトリクスを収集・分析することができます。
OCIマネージドサービスであるSearch with OpenSearchは2024/7現在においてprometheus pluginに対応していないため、prometheus形式でのメトリクスを収集するために、elasticsearch exproterを使用します。

https://github.com/prometheus-community/elasticsearch_exporter

このツールを監視用サーバに入れて動かすことで、OpenSearchのapiエンドポイント(http:○○:9200)から、elasticsearch文脈でのメトリクスをスクレイピングして取得可能です。
取得できるメトリクスは上記リンクページにある「elasticsearch_*」の項目です。

# 環境構築

OpenSearchと監視用のサーバを1台用意します。

下記に手順を示します。なおバージョンは本記事執筆時点で最新のものです。

### prometheus起動


```shell: prometheus取得
wget https://github.com/prometheus/prometheus/releases/download/v2.53.1/prometheus-2.53.1.linux-amd64.tar.gz
tar xvfz prometheus-2.53.1.linux-amd64.tar.gz
```
prometheusのyamlファイルの末尾に以下を追記します↓
```yaml:
（前略）
scrape_configs:
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
- job_name: "prometheus"

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
    - targets: ["localhost:9090"]

### 以下を追加 ###
- job_name: "opensearch_exporter"
    static_configs:
    - targets: ["(exporter ip):9114"]
```

```shell: prometheus実行
./prometheus --config.file=prometheus.yml
```

### elastic exproter起動

```shell: elastic exporter取得
wget https://github.com/prometheus-community/elasticsearch_exporter/releases/download/v1.7.0/elasticsearch_exporter-1.7.0.linux-amd64.tar.gz
tar xvfz elasticsearch_exporter-1.7.0.linux-amd64.tar.gz
```

例えば以下のように記述して実行します↓
```shell: run.sh
export ES_USERNAME="(username)"
export ES_PASSWORD="(password)"
./elasticsearch_exporter --es.uri https://amaaaaaas......opensearch.us-ashburn-1.oci.oraclecloud.com:9200
```

# 結果確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2846649/d9f8e162-2db0-0788-a33e-202d1169fe4e.png)

# おわりに
OpenSearchをPrometheusで監視するための環境構築と設定手順について説明しました。
Prometheusを利用することで、OpenSearchの詳細なパフォーマンスデータを収集し、トラブルシューティングやパフォーマンスの最適化に役立てることができます。今回はgrafanaまでは入れていませんがOpenSearch監視の一案として参考になれば幸いです。
IBM i のIPL中に表示される8桁のコード（SRCコード, システム参照コード）の意味を調べたい

## IBM i のSRCコード, システム参照コード はどこに表示されますか？

オンプレのハードウェアの場合、下記の図のようなCEC(CPUが載っている筐体）上のパネルに表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/41e2b6f3-5037-4743-1179-60b9f40ef743.png)

IBM CloudのPowerVS IBM i の場合も上記と同じSRCコードが表示されます。
表示は各IBM i インスタンス（VM、LPAR）の管理画面上に表示されます。

IBM i インスタンスの管理画面にシステム参照コード SRCコードが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/6d78cb5d-17bf-889f-2043-ac907a91ce2e.png)

上記の例ではIPL完了、正常稼働中なので 00000000となっています。


## SRCコード（システム参照コード）の調べ方？

こちらのサイトで調べることが出来ます。

***IPL SRC finder***
https://www.ibm.com/docs/en/i/7.5?topic=problems-ipl-src-finder

※上記はIBM i 7.5です。


### 例

IPL中に表示される（オンプレでもPowerVSでも共通です）、SRCコード8桁を入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/ad3560db-3c65-b279-6a46-b5fc4b24dc8d.png)


※検索するSRCコードは全8桁じゃなくてもOKです。
guri guri さんのコメントをご参照くださいませ。（guri guriさんありがとうございます♪）
【Go】Ginでhealth_checkのログを表示したくない

# はじめに
health_checkのログが多すぎて大事なログが見つけられない...みたいなことありますよね。
Ginの環境を作っている際にその問題にぶち当たったので、そんなお悩みを解決できる方法を備忘録としてまとめました。


# 結論
以下の2通りの方法で、特定のパス（ここでは/health）についてログ出力を抑制することができます。
```go
router := gin.New()
router.Use(gin.LoggerWithWriter(gin.DefaultWriter, "/health"))
router.Use(gin.Recovery())
```

```go
router := gin.New()
router.Use(gin.LoggerWithConfig(gin.LoggerConfig{SkipPaths: []string{"/health"}}))
router.Use(gin.Recovery())
```

通常、基本的なルーターの設定にはgin.Default()を使用することが多いと思います。
この関数はデフォルトで`Logger`と`Recovery`のミドルウェアを設定します。
```go
package gin

// Default returns an Engine instance with the Logger and Recovery middleware already attached.
func Default(opts ...OptionFunc) *Engine {
	debugPrintWARNINGDefault()
	engine := New()
	engine.Use(Logger(), Recovery())
	return engine.With(opts...)
}
```
しかし、この関数で設定される`Logger`ミドルウェアは設定の変更ができず、特定のパスに対してログ出力を抑制することができません。
そのため、`gin.Default()`ではなく、`gin.New()`を使用し、手動でログ設定を追加する（`gin.LoggerWithWriter` or `gin.LoggerWithConfig`）必要があります。

:::note warn
gin.New()を使用する場合、`gin.Recovery()`の設定を忘れると、500エラーが発生した際にGinがクラッシュしてしまうことがあります。避けたい場合は`gin.Recovery()`も設定しましょう。
:::

# `LoggerWithWriter`と`LoggerWithConfig`について
どちらを使うのが適当かは正直よくわかってません。
ただし、コードを見てみると、`LoggerWithWriter`の内部で`LoggerWithConfig`を呼び出しており、引数で明確に`notlogged`を受け取れるようになっています。
そのため、シンプルにログ出力を制御したい場合は、`LoggerWithWriter`を使用する方が無難なのかなと思っています。
```go
package gin

// LoggerWithWriter instance a Logger middleware with the specified writer buffer.
// Example: os.Stdout, a file opened in write mode, a socket...
func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc {
	return LoggerWithConfig(LoggerConfig{
		Output:    out,
		SkipPaths: notlogged,
	})
}
```
Cloud FunctionsでGemini APIを呼び出してみた

こんにちは。
業務において、HTTPリクエストをトリガーにGoogle Cloudのサーバレスクラウドコンピューティング「Cloud Functions」上のPythonファイルを実行し、Geminiにプロンプトを投げ、回答をレスポンスするということをおこないました。
備忘録として、実装を簡単にまとめてみようと思います。

# Cloud Functionsの概要
Cloud Functionsとは、Google Cloudが提供するサーバレスのクラウドコンピューティングサービスのひとつです。
サーバレスとは、サーバーが必要ないという意味ではなく、サーバーの構築や保守などのメンテナンスが不要という意味です。
指定したイベントをトリガーにサーバーを意識することなく、クラウド上でプログラムを実行できる便利なサービスです。
トリガーとして指定できるものは多数ありますが(Pub/Sub・Cloud Firebaseなど)、今回は外部サービスからのHTTPリクエストをトリガーに指定します。
類似サービスとして、AWSの「Lambda」などがあります。

# 実装
今回は下記のように実装をしました。
```python:main.py
import functions_framework
import vertexai
from vertexai.generative_models import GenerativeModel, ChatSession

@functions_framework.http
def gemini(request):
    project_id = "gemini-try"
    region = "asia-northeast1"
    data = request.get_json()
    prompt = ""
    if data.get('prompt') is not None:
        prompt = data.get('prompt')

    if prompt == "":
        return 'NG'

    temperature = 0
    if data.get('temperature') is not None:
        temperature = data.get('temperature')

    max_token = 100
    if data.get('max_token') is not None:
        max_token = data.get('max_token')
        max_token = int(max_token)
        
    vertexai.init(project=project_id, location=region)

    config = {"max_output_tokens": max_token, "temperature": temperature}
    system_instruction = "あなたは5歳の男の子です。"
    model = GenerativeModel(
        model_name="gemini-1.5-flash-001",
        system_instruction = [
            system_instruction
        ])

    response = model.generate_content(prompt, generation_config=config)

    return response.text
```
```:requirements.txt
functions-framework==3.*
google-cloud-aiplatform==1.51.0 
```
temperatureとは、生成AIの回答の創造性・ランダム性の指標です。この数値が高いほど、創造性に富んだ回答を出力してくれます。
今回、temperature・max_output_tokenはリクエストのボディーから受け取っておりますが、Cloud Functions上のpyファイルにて設定することも可能です。
## System instructionsとは
System instructionsとはGeminiの振る舞いや役割を設定するための指示や制約を定義するものです。
今回はGeminiに「5歳の男の子」というペルソナを与えました。この指示を与えることで、5歳の男の子として回答を返してくれます。

https://ai.google.dev/gemini-api/docs/system-instructions?lang=python&hl=ja

## まとめ
APIを介して生成AIモデルの回答を取得できるので、これからますます様々なサービスが生まれてきそうですね。
今回はPythonを採用しましたが、GoやNode.jsでも実装できるそうです

https://ai.google.dev/gemini-api/docs/api-overview?hl=ja
レコメンド機能をオフって情報過多にサヨナラ

## 『レコメンド』がノイズになる？
最近はなんでもかんでもパーソナライズ化が進んでます。

たとえば、ネットで買い物をしていると、「この商品を見た人は以下の商品も見ています」と、関連商品が表示されたり。

Googleで調べものをしようとしたら検索窓の下に気になる記事が表示されたり。

テクノロジーはどんどん進化し、高性能なアルゴリズムによって、それぞれの趣味嗜好にあわせたものが表示されるようになってきています。

でも、時折そういったものに、うんざりするときありませんか？

目的があって画面を開いたはずなのに、端に表示されてる魅力的なコンテンツについ指が伸びてしまって、「あれ、自分は何は何しようとしてたんだっけ？」みたいな。

「デジタルデトックス」、「SNS疲れ」なんて言葉がありますが、たまには技術の進化に逆らって、あえて不便にした方がいいときもあるのではないでしょうか。

そんなわけで今回は、色んなWebサービスの、レコメンド機能やパーソナライズ設定をオフにする方法を紹介します。

## Google
### シークレットモード
もっとも気軽にパーソナライズされた表示から逃れられるのが、[シークレットモード](https://www.android.com/intl/ja_jp/articles/167/)です。

Googleでは、主に閲覧履歴に基づいてパーソナライズされるようになっていますが、シークレットモードは履歴が残らないので、常にニュートラルな状態でブラウジングすることができます。

https://support.google.com/chrome/answer/95464

## マイアクティビティ

https://myactivity.google.com/myactivity

※上記リンクから参照
❝Google マップや Google 検索などの Google サービスにおいて、検索の高速化、おすすめ機能の精度向上、カスタマイズの充実を図るため、Google のサイトやアプリでのアクティビティを保存します❞

この設定はデフォルトでオンになっていますが、上記リンクから簡単にオフにできます。

## Amazon
Amazonに表示されるレコメンドは、主に閲覧履歴と購入履歴に基づいています。
[閲覧履歴](https://www.amazon.co.jp/gp/history/)のページから、これまでの閲覧履歴を削除できます。

購入履歴を削除することはできませんが、[おすすめ商品を正確にする](https://www.amazon.co.jp/gp/yourstore/iyr/)ページから、「この商品をおすすめに使用する」のチェックを外すことで、購入履歴に基づくおすすめ表示をオフにできます。
なお、この設定はWebブラウザ版でのみ行うことができます。

## X(旧Twitter)
Xは、どのようにパーソナル情報から表示のカスタマイズを行っているか、公式ヘルプセンターにて懇切丁寧に解説してくれています。

https://help.x.com/ja/about-personalization-across-your-devices

カスタマイズとデータ 設定ページで、表示される広告などをパーソナライズさせるか選択できます。

https://twitter.com/settings/account/personalization

Xがトピックでは、Xが自動で判断した、ユーザーが興味あるコンテンツの一覧を確認できます。これらのチェックを外すことでそのジャンルに関する投稿や広告が表示されないようになります。

https://help.x.com/ja/using-x/follow-and-unfollow-topics#unfollow

## Instagram
Instagramには、基本的にパーソナライズされたレコメンド表示をオフにすることはできません。

ただ、フィードやリール、検索で興味のない投稿が表示される場合は、画面端の『︙』をタップしてから、[興味がない]を選択することで、そのジャンルに関する投稿の表示を減らすことができます。

https://ja-ks.facebook.com/help/instagram/1105548539497125
検索広告からの流入をアナリティクスで確認したいとき

# Google広告とアナリティクス
はじめまして。所属企業で広告運用を担当している鈴木と申します。

仕事柄、Google広告の管理画面を使用する作業が多いのですが、
広告からのサイトへの流入を監視するため、同時にアナリティクス(GA4)を必ず見ています。

そこで今回は、**検索(リスティング)広告からの流入をアナリティクスで確認する方法**について書いていきたいと思います。

## 広告経由のユーザー・セッション等を確認する方法

![スクリーンショット 2024-07-23 110324.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/86a25763-8336-65be-4a09-aa53d49acca4.png)
GA4にログイン後、左メニュー「レポート」から「集客」→「トラフィック獲得」をクリックします。
検索広告からの流入はチャネル「**Paid Search**」に分類されるので、この行で数値を確認していきます。

## 広告経由のPVを確認する方法

![スクリーンショット 2024-07-23 110833.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/a24d2d43-d83c-6fe9-e062-3edd0f021595.png)
GA4にログイン後、左メニュー「レポート」から「エンゲージメント」→「イベント」をクリックし、「page_view」の行を確認します。
イベント名の右横「＋」から「トラフィックソース」→「セッションのメディア」を選択すると、各イベントの流入元が表示されます。
メディア「cpc」がクリック単価型有料広告からの流入となるので、「**page_view / cpc**」の行で数値を確認していきます。

### まとめ
広告からの流入を確認する方法は他にもあるのですが、今回はよく使う2つを書いてみました。
PVの確認はひと手間加える必要がありますが、どちらも比較的簡単に行うことができる方法なので、参考にしていただけたら幸いです。

Google広告やGA4の使用方法について、これからも投稿できればと思っています。
以上、鈴木でした。
(Excel VBA) GAS風にセル範囲を選択する汎用Function

##  はじめに

Excel VBA と GoogleスプレッドシートのGAS (Google Apps Script) の両方を使っていると、GASの関数に使いやすい(分かりやすい)ものがあるなぁと思うことがあります。その中でも、sheet クラスにある セル範囲を取得する getRange メソッドがとても使いやすいので、Excel VBA に移植してみました。

#### 公式リファレンス

https://developers.google.com/apps-script/reference/spreadsheet/sheet#getrangerow,-column,-numrows,-numcolumns

## GAS (Google Apps Script) の getRange メソッド

### 使用サンプル
```js:GAS
const sheet = SpreadsheetApp.getActivesheet();
let targetRange = sheet.getRange(1, 1, 5, 3);

// 基準セル ＝ A1
// セル範囲 ＝ A1:C5
```

### 構文と解説
```text
クラス   : Sheet
メソッド : getRange(row, column, numRows, numColumns)
引数     :
  row         [Integer] 基準セルの行番号
  column      [Integer] 基準セルの列番号
  numRows     [Integer] 基準セルからの行数
  numColumns  [Integer] 基準セルからの列数
戻り値   : range
```

Excel VBAで言えば、基準セルとoffsetを組み合わせたような表現ですが、ここで一点だけ注意点があります。基準セルからの数え方が Excel VBAとGASで異なります。

- Excel VBAで `Cells(1, 1).Offset(1, 1)`を示すセルは`B2`セル
- GASで`getRange(1, 1, 1, 1)`としたときの最終セルは `A1`セル

つまりExcel VBAでは基準セルを含まず、GASでは基準セルを含んで1から数えるのです。


## Excel VBA

### ユーザ定義 列挙型 `ueCountMethod` を定義しておく

基準セルからの数え方の違いを反映させるため、ユーザ定義の列挙体を作っておきます。こうすることで、VBAに慣れた人でもGASに慣れた人でも使えるようにできます。

```vb:Excel VBA
' uFnGetRange用
Public Enum ueCountMethod
  ueCountMethodVBA = 0
  ueCountMethodGAS = 1
End Enum
```

### Public Function プロシージャ : `uFnGetRange`
```vb:Excel VBA
' GAS風にセル範囲を取得する
Public Function uFnGetRange(ByVal aoSheet As Worksheet _
                         , ByVal aBaseRow As Long _
                         , ByVal aBaseCol As Long _
                         , ByVal aNumRows As Long _
                         , ByVal aNumCols As Long _
            , Optional ByVal aCountMethod As ueCountMethod = ueCountMethodGAS _
                                        ) As Range
  ' 仮戻り値
  Dim oRetRange As Range
  
  ' 開始セルを取得
  Dim oStartCell As Range
  Set oStartCell = aoSheet.Cells(aBaseRow, aBaseCol)
  
  ' 終了セルを取得
  Dim oEndCell   As Range
  Select Case aCountMethod
    Case 0  ' ueCountMethodVBA
      Set oEndCell = oStartCell.Offset(aNumRows, aNumCols)
    Case 1  ' ueCountMethodGAS
      ' GAS式の場合 aNumRows,aNumColsに 0 を指定するとエラーになるのを回避
      If aNumRows = 0 Then aNumRows = 1
      If aNumCols = 0 Then aNumCols = 1
      '----------------------------------
      Set oEndCell = oStartCell.Offset(aNumRows - 1, aNumCols - 1)
  End Select
  
  ' セル範囲を取得
  Set oRetRange = aoSheet.Range(oStartCell, oEndCell)
  
  ' 戻り値
  Set uFnGetRange = oRetRange
  
  ' オブジェクト変数の解放
  Set oRetRange = Nothing
  Set oStartCell = Nothing
  Set oEndCell = Nothing
  
End Function
```

### 実行例
```text:VBE イミディエイト
? uFnGetRange(Application.ActiveSheet, 1, 1, 1, 1, ueCountMethodVBA).Address
$A$1:$B$2

? uFnGetRange(Application.ActiveSheet, 1, 1, 1, 1, ueCountMethodGAS).Address
$A$1

? uFnGetRange(Application.ActiveSheet, 1, 1, 1, 1).Address
$A$1
```

### 注意点 : エラー処理は別途必要
引数に無効な値を入れたときのエラー処理はここでは組み込んでません。

## おわりに

セル範囲の指定はよく使うのですが、GASのgetRangeメソッドが本当に秀逸だったので移植しました。これは自分でも結構使っています。よかったら参考にして下さい。
【Luma AIのDream Machine】新機能End Frame紹介


　どうも、カーブミラーです。

　今回は、Dream Machineの新機能、End Frameの紹介です。

:::note info
本記事に、
　画像はありません。

あしからず。
:::

　まずは、ニュース。

　GPT-4o miniについてです。

　これは、APIでの利用での
　　話のようですね。

　記事内容は、
　　タイトルどおりで、
　　　画像に関する処理をさせると
　　　　高くつく、というものです。

　APIは、
　　トークン数で
　　　価格が計算されます。

　画像を解析すれば
　　トークン数が上がり、
　　　最終的な値段は高い、と
　　　　なるわけです。

　GPT-4oと
　　比較したポストもありました。

　API利用のみなさん、ご注意を。
　　まぁ、これを見ている人は
　　　利用してないと思いますけど😅

　[note：GPT-4o miniの画像処理コストは安くない](https://note.com/robothink/n/n6e71ba4ee5ec?sub_rt=share_b)
***
　さて、本題です。

　今回は、
　　Luma AIの
　　　DreamMachineの新機能が、
　　　　Loop
　　　　Loop Extendのほかに
　　　　　もうひとつありましたので
　　　　　　紹介します。

　“End Frame”機能です。

　実は、Loop機能が出た際に
　　この機能があることは
　　　知っていました。

　ですが、
　　最初のフレームと
　　　最後のフレームで
　　　　動画を生成するものと
　　　　　判断してしまい、
　　　　　　紹介は避けたのです。

　その機能は
　　すでにあって
　　　紹介済でしたから。
***
　では、“End Frame”機能です。

　画面上では、
　　画像をふたつ、
　　　アップロードできる機能と
　　　　見た目が変わらなかったので
　　　　　気付きませんでした。

　この“End Frame”機能は
　　アップロードした一枚の画像を
　　　“End Frame”にする機能なのです。

　一枚の画像がアップロードされると
　　もう一枚を受け入れる準備として
　　　枠が現れます。

　そのまま、アップロードすれば、
　　最初のフレームと
　　　最後のフレームとして働きます。

　“End Frame”機能は
　　最初のフレームを
　　　最後のフレームに
　　　　切り替えることで、
　　　　　ラストを狙ったシーンに
　　　　　　できる機能です。

　使い方は、
　❶画像をアップロード
　　　追加枠が出てきます。
　❷追加枠を触ったままスワイプ。
　　　アップした画像と追加枠のあいだ
　　　　上部に、切り替えアイコンが
　　　　　出てくる。
　❸アイコンをタップ。
　　　アップした画像が、
　　　　End Frameとして移動する。
　❹Promptを入れて送信。

　あとは
　　出来上がりを
　　　待つだけです。
　　　　[Luma AIポスト](https://x.com/LumaLabsAI/status/1816143208663097784?t=LfkUEKDbAl7bMXc9QkdHoQ&s=19)

　[私の説明&サンプルのポスト](https://x.com/kabumira862571/status/1816278071168884939?t=tYdDDplJG75EhdcjTCesmA&s=19)

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
***
　ちなみに、
　　気のせいか、
　　　動画生成を送信したら
　　　　待ちもなく、すぐに生成へと
　　　　　移りました。

　これって、
　　設備投資して
　　　計算資源に余裕が
　　　　出てきた、ということかな？
【Laravel11】あのメンテナンスモードが進化していた


こんにちは！
新しい Laravel を眺めてたら、謎の設定項目があるじゃないですか。知らない子！

```ini:.env
APP_MAINTENANCE_DRIVER=file
# APP_MAINTENANCE_STORE=database
```

これが何か調べる記事です。

https://readouble.com/laravel/11.x/ja/configuration.html



## メンテナンスモード

Laravelには、標準でメンテナンスモードが搭載されています。
使い方は簡単。

```bash
$ php artisan down
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833190/26d9e4dd-f62f-bf20-84c9-9f4109446d33.png)

```bash
$ php artisan up
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833190/87bb845f-1ee4-00b5-d8d7-7d7c7aea8c6a.png)

これだけ。
勝手にステータスコードも `503` にしてくれるので、とても便利。
更新手順書やデプロイコマンドに仕込んでおきたいくらい。



## メンテナンス中に接続する

でも、このままでは全ての通信を遮断してしまいます。
デプロイ担当者だけは見たいですよね。その時は `--with-secret` 。

```php
$ php artisan down --with-secret
   INFO  You may bypass maintenance mode via [http://localhost/Ev1wpGy2nfj76JZM]. 
```

出てきたURLにアクセスすると、通行手形のクッキーが生成されて、リダイレクトします。
なので、そのブラウザだけはメンテナンスモード時でも通信が可能となるわけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833190/bdedf858-b8cd-052f-e843-8f800107d874.png)

当然、別のブラウザではNG。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833190/10c92072-8c32-7bda-facb-4106bc020520.png)



## 最初のお話 `APP_MAINTENANCE_DRIVER`

今までのが前提で、最初の話題。
config ファイルを見ると、以下で使われている。

```php:config/app.php
'maintenance' => [
    'driver' => env('APP_MAINTENANCE_DRIVER', 'file'),
    'store' => env('APP_MAINTENANCE_STORE', 'database'),
],
```

どうやらこれは複数台のサーバーを運用する時に、メンテナンスモードを連動させる仕組みのよう。
最近は AWS を使ってそういった運用も多いので、とても助かる。

- `driver`: `file`, `cache`
- `store`: `cache` を選択した際に、`config/cache.php` で定義されているストア名
    - `array`, `database`, `file`, `memcached`, `redis`, `dynamodb`, `octane`
    - 複数台のサーバーを運用するのであれば、共通のDB、redis あたりを使用すると良さそう

試しに以下の設定で運用してみる。

```ini:.env
APP_MAINTENANCE_DRIVER=cache
APP_MAINTENANCE_STORE=database

CACHE_STORE=database
```

```bash
# cache 用のテーブルを生成する
$ php artisan cache:table

$ php artisan down
```

DB に以下のような内容が記録され、全てのLaravelでメンテナンス状態が共有される。
お～これから使ってこ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833190/415b0852-b883-a5d8-4d24-52440d3d10cf.png)  



## まとめ

Laravel は神。

> 弊社は、以前はフロントとバックエンドを別々に作って nginx で振り分けたんですけど、Laravelに統一したほうが利点が大きいので、今はまとめちゃってます。
> 置くだけで良いのは偉大。
>
> そうすると、メンテナンスモードなど Laravel の恩恵を受けられるので、この一枚のアプリケーション層のメリットが大きすぎる。
Azure Static Web Appsでの404エラー解消法：クライアントサイドルーティング設定

## はじめに

ローカル環境ではパス遷移が正常に動作していたが、Static Web Appsにデプロイしたアプリでは、ブラウザのリロードやURLを直接入力すると404エラーが返されてしまいました。

![Azure Static Web Apps スクリーンショット Jul 25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3461384/7c507bf7-41bd-6b2d-2004-5bec3951a673.png)


## 原因

この問題は、Static Web Appsがデフォルトではクライアントサイドのルーティングをサポートしていないために発生します。

シングルページアプリケーション（SPA）では、ReactやVueなどを使用してクライアント側でページ遷移を管理します。このため、ボタンを押してページ遷移する場合はクライアント側で完結するためエラーが出ません。しかし、ブラウザリロードやURLを直接入力するとサーバーにリクエストが送信されるため、サーバーが適切なHTMLファイルを返さないと404エラーが発生します。


引用：
[Azure Static Web Apps についてよく寄せられる質問](https://learn.microsoft.com/ja-jp/azure/static-web-apps/faq#---------------------web-------404-----------------)
> Static Web Apps からクライアント側ルートを要求した場合、そのルートはアプリのデプロイ済みアセットに存在しないため、404 エラーが返されます。
> 



## 解決策

ドキュメント：[Azure Static Web Apps を構成する](https://learn.microsoft.com/ja-jp/azure/static-web-apps/configuration#fallback-routes)

Static Web Appsの構成ファイル（staticwebapp.config.json）に`navigationFallback`セクションを追加し、すべてのクライアントサイドルートに対してindex.htmlを返すように設定します。これにより、ブラウザのリロードやURLへの直接アクセスでもクライアントサイドのルーティングが正しく動作するようになります。

### staticwebapp.config.jsonの例

```json
{
  "navigationFallback": {
    "rewrite": "index.html",
    "exclude": ["/img/*.{png,jpg,gif}", "/css/*"]
  }
}
```

- クライアントサイドのルートに直接アクセスした場合、サーバーはindex.htmlを返し、クライアントサイドのルーティングが適切に機能します。
- `/images/logo.png`のような実際の静的ファイルは通常通り返されます。
スクリーンフロー：複数選択リストコンポーネント


選択した結果をどのように使えるのかを検証してみます。

画面にはこのように設定しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/c473a323-238e-7396-7680-a3509adfef84.png)


数式の中で使うと...
確かにテキストだと言われますね。リスト変数だと思ってましたが...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/413cef80-e1be-f31d-f9e6-0f7fdd8ea3be.png)

この決定要素が判定されないんです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/506b45b8-2a39-47f6-be7d-a85823449a96.png)


意味がないと思ったけど、一度数式に落とし込んでみます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/32e7233d-d002-b7e7-b2b4-a89409488170.png)

決定要素では数式を使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/976e6234-5fb2-106b-345f-9d37aec31834.png)

みごとに機能します。不思議ですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/d8b06032-4841-a7f8-2c39-1c8fb9fa3fe2.png)
新卒2年目エンジニアの成長記録: React学習5か月目

# はじめに
新卒2年目エンジニアのA.Kと申します。
現在は運用保守の案件に参画しておりますが、フロントエンドの開発案件を希望しているため、**個人でReact、Next.js、TypeScriptを使ってアプリを作成しています。**
毎月まとめや振り返りを兼ねてこのような記事を書いています。


先月の状況はこちらです！

https://qiita.com/AK_React/items/3f1130cb0f05fc289872
# 学習5カ月目にやったこと


<font color="Red">**１．React学習の集大成としてフィットネス系のアプリを作成**</font>

アプリの詳細は下記の記事にあります。

https://qiita.com/AK_React/items/ff8f501cc546dfd24c89

React学習を開始してから**約5カ月**、Udemyのインプットからスタートし、常に手を動かしてアプリを作成し続けてきました。
今回作成したアプリが**4つ目のアプリ**になります。

これまで、作成するアプリの仕様はすでにカリキュラムとして組まれていたのですが、**今回のアプリでは「自分のアイデアをゼロから形にする」経験も積むことができました。**

結果、**細部まで詰めることができず**、キリがないので最低限の機能のみ実装した段階で区切りをつけたのですが、**ゼロからサービスを生み出すことの大変さを痛感しました。**
（個人開発で生計を立てられている方本当にすごいな。。）

***

<font color="Red">**２．Next.jsの学習開始**</font>

**Reactにある程度慣れてきたところで、Next.jsの学習に移行**しました。
**学習方法はReactと変わらず、アウトプット9割**といったところです。

最初はUdemyで基礎のインプットを行いました。

https://www.udemy.com/share/109nOg3@X2mkIkiawCtgk8yrGhNJiON8NnWJC4oYzJxYMou3FGwTt5Q9vIKhe-OhW8ITq2EtiQ==/

Udemyが終わったら、さっそく手を動かしてアプリを作成していきます。
現在は**QiitaとmicroCMSの記事を取得して、ブログ形式で表示するアプリを作成中です。**

Next.jsはReactがベースではあるものの、サーバーサイドでレンダリングが行われるためそのあたりのイメージが掴みづらかったり、便利な機能が多い分複雑になりやすいと感じています。

しかし、その分Webアプリケーション開発の効率アップにつながるため、**Next.jsを使いこなせれば大きなアドバンテージになると思っています。**


# 学習5カ月目に意識したこと

<font color="Red">**1日5分でもいいから継続すること**</font>

現在SEとして現場で働きながら学習を行っていますが、**1日12時間稼働の日も少なくありません。**加えて、ボディメイクの大会にも出場予定のため**週5でジム通い**の日々を送っています。
**こうした状況下でも、学習を辞めずに継続することを意識**しました。

コツとしては、**「学習のハードルを徹底的に下げること」**　だと思います。
忙しいと精神的にも体力的にも追い詰められていくので、あえてノルマを設定せずただ粛々とできることをやっていました。
**毎日ほんの少しでも学習していると勝手に習慣化されていきます。**


# おわりに
以上、React学習5か月目の振り返りでした。
8月から参画案件が変わるのですが、相変わらず稼働が高そうなので、健康面に配慮しつつ進めていきます。


# JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？

気になる方はぜひHPからライン登録お願いします👇

https://projisou.jp
BitLockerとは？回復キーがわからない時の検索方法

## BitLockerとは?
BitLockerは、Windowsユーザーがデータの盗難や不正アクセスから保護するための効果的なツールとなっています。です。この機能を使用すると、ハードドライブやUSBフラッシュドライブなどのディスク上のデータを暗号化することができ、機密性やセキュリティを向上させることができます。
## BitLocker回復キーがわからない時の検索方法
下記の検索方法に関しては、BitLocker回復キーがバックアップされたことを前提として紹介します。
![bitlocker-backup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3845312/29d358af-d78b-59e3-9dcf-727fd7837119.png)
### Microsoftアカウントで検索
https://account.microsoft.com/devices/recoverykey にアクセスして、回復キーを見つけます。 スマホなど任意のデバイスでMicrosoftアカウントにサインインできます。
![bitlocker-key-recovery.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3845312/c326318f-5436-4ab1-e005-093caee704af.png)
### USBフラッシュドライブから確認
保存しておいたUSBフラッシュドライブからテキストファイルを確認してみます。
### システム管理者に確認
職場のWindowsデバイスがドメインに接続されている場合は、システム管理者に問い合わせて回復キーを確認します。
### プリントアウトの場合
BitLocker がアクティブ化されたときに回復キーが印刷されている可能性があります。重要な書類を保管してある場所も探してみます。

より詳しい内容は参考サイトにてご覧ください。
## 参考サイト
[BitLocker回復キーの解除・無効化する方法](https://4ddig.tenorshare.com/jp/windows-recovery-solutions/check-bitlocker-recovery-key.html)
[Windows BitLocker回復キーが求められる原因](https://support.microsoft.com/ja-jp/windows/windows-%E3%81%A7%E3%81%AE-bitlocker-%E5%9B%9E%E5%BE%A9%E3%82%AD%E3%83%BC%E3%81%AE%E6%A4%9C%E7%B4%A2-6b71ad27-0b89-ea08-f143-056f5ab347d6)
[Windows BitLocker回復キーをバックアップする方法](https://support.microsoft.com/ja-jp/windows/bitlocker-%E5%9B%9E%E5%BE%A9%E3%82%AD%E3%83%BC%E3%82%92%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97%E3%81%99%E3%82%8B-e63607b4-77fb-4ad3-8022-d6dc428fbd0d)
[BitLockerで暗号化したドライブからデータを復元する方法](https://jp.easeus.com/storage-media-recovery/bitlocker-partition-recovery.html)
【応用情報技術者試験】3Dコンピュータグラフィックスやイラストレーションの技法について、イメージがつきやすくなる動画のリンク集

# 概要
応用情報技術者試験で出題されうる、3Dコンピュータグラフィックスやイラストレーションの技法について、イメージがつきやすくなるよう、youtube動画へのリンクをまとめました。

# 目次
- [クリッピング](#クリッピング)
- [シェーディング](#シェーディング)
- [テクスチャマッピング](#テクスチャマッピング)
- [モーフィング](#モーフィング)
- [レイトレーシング](#レイトレーシング)

## クリッピング
描画の領域からはみ出した部分を切り捨てること。

- [Clipping | 3D Graphics Overview](https://www.youtube.com/watch?v=wH8Z-d2oW-c)

## シェーディング
光源と描画対象の位置関係をもとに、光の当たり具合などを計算して各画素の色を変化させて、明暗のコンストラクト付けを行うこと。
- [シェーディング](https://www.youtube.com/watch?v=5HfCBGTWGwQ)
- [Gouraud Shading - Interactive 3D Graphics](https://www.youtube.com/watch?v=T-GKzksIb-4)

## テクスチャマッピング
ポリゴンに対して、画像 (テクスチャ) の貼り付け (マッピング) をすること。
物体の表面的な質感をだすことができる。
- [Texture Mapping - Affine vs Perspective Correct](https://www.youtube.com/watch?v=-hv8lmuFlIY)
- [Mayaにおけるテクスチャマッピングの基本1](https://www.youtube.com/watch?v=WzHHmBpPJH0)

## モーフィング
2つの異なる画像やオブジェクトの間を自動的に補間して、時間の経過とともに形状を変化させる手法。﻿

- [【AE】テキストのモーフィングアニメーション](https://www.youtube.com/watch?v=jiUavLnKy9c
)
- [3D Infinite Shape Morphing Animation](https://www.youtube.com/watch?v=Ie1OgSMzn6M)

## レイトレーシング
光の屈折や反射などを中心にして現実世界の様々な影響をコンピューターで計算し、リアルな映像を作成する技術のこと。
「レイトレ」と略されて呼ばれることがある。
- [レイトレーシングとは？ 歴史や原理、将来性など、-解説を試みる-](https://www.youtube.com/watch?v=aAnPCe0uuDQ)

- [Basic 3D lighting concepts, Ray Tracing and Global Illumination](https://www.youtube.com/watch?v=b_I9fVenRIo)

***
**[記載した応用情報技術者試験の記事まとめ](https://qiita.com/MetroOsamu/items/550001240d76e24f505f)**
WindowsのWSL上にAnsible実行環境を構築する

Windows上でAnsibleは実行できないので、WSLから実行するため
WSL構築からAnsibleインストール、実行までの手順をまとめます。

# WSL用OSインストール
WSLとして動かすOSをインストールします。

1. Microsoft Storeを開く
1. 「almalinux」で検索する　※他のOSでも良いです。Ubuntuとか
1.  出てきたものをインストールする
(今回はAlmaLinux 9)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177673/c4d3d302-a774-c55f-69bb-6d0f3f2d5e27.png)
1. インストール後、AlmaLinux9を実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177673/e93e2d9e-50e4-07b4-1862-bf50739d87b5.png)
1. ユーザー名とパスワードが聞かれるので入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177673/d01d0b09-d20e-0508-8b54-36598709ad5d.png)

# Ansibleインストール
以下コマンドを順番に実行
```shell
> sudo dnf install -y epel-release
> sudo dnf install -y ansible
> ansible --version
# -> ansible [core 2.14.14]
#      config file = /etc/ansible/ansible.cfg
#      configured module search path = ['/home/xxx/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
#      ansible python module location = /usr/lib/python3.9/site-packages/ansible
#      ansible collection location = /home/xxx/.ansible/collections:/usr/share/ansible/collections
#      executable location = /usr/bin/ansible
#      python version = 3.9.18 (main, Jan  4 2024, 00:00:00) [GCC 11.4.1 20230605 (Red Hat 11.4.1-2)] (/usr/bin/python3)
#      jinja version = 3.1.2
#      libyaml = True
```

以下コマンドで動作確認
(自分自身に対して`cat /etc/redhat-release`を実行した結果を出力する)
```shell
> ansible localhost -m shell -a "cat /etc/redhat-release"
# -> localhost | CHANGED | rc=0 >>
#    AlmaLinux release 9.3 (Shamrock Pampas Cat)
```
robloxでassistant その142

# 概要
robloxでassistantやってみた。
練習問題、やってみた。

# 練習問題
スクリプトだけで、コイン収集システムを作成せよ。

# 手順
- ServerScriptServiceにScriptを追加
- スクリプトを書く
- robloxにセーブする。
- Game Settings > Security > Enable Studio Access API

```

local DataStoreService = game:GetService("DataStoreService")
local playerData = DataStoreService:GetDataStore("PlayerData0")

local function saveData(key, val)
	local success, errorMessage = pcall(function()
		playerData:SetAsync(key, val)
	end)
	if success then
		print("Data saved successfully!")
	else
		warn("Cannot save data for player!")
	end
end

local function loadData(key)
	local val
	local success, errorMessage = pcall(function()
		val = playerData:GetAsync(key)
	end)
	return val
end

game.Players.PlayerAdded:Connect(function(player)
	print("入った")
	local v = loadData(player.UserId .. "-coin")
	if v == nil then
		v = 0
	end
	local leaderstats = Instance.new("Folder", player)
	leaderstats.Name = "leaderstats"
	local coin = Instance.new("IntValue", leaderstats)
	coin.Name = "coin"
	coin.Value = v
end)

game.Players.PlayerRemoving:Connect(function(player)
	print("出た")
	local v = player.leaderstats.coin.Value
	saveData(player.UserId .. "-coin", v)
end)

local Players = game:GetService("Players")

local bomb = Instance.new("Part", workspace)
bomb.Name = "bomb"
bomb.Anchored = false
bomb.Shape = Enum.PartType.Cylinder
bomb.BrickColor = BrickColor.Red()
bomb.Size = Vector3.new(0.5, 3, 3)
local explosionSound = Instance.new("Sound")
explosionSound.SoundId = "rbxassetid://5137964328"
explosionSound.Parent = bomb
local function explode()
	local explosion = Instance.new("Explosion")
	explosion.BlastRadius = 10
	explosion.BlastPressure = 500000
	explosion.Position = bomb.Position
	explosion.Parent = game.Workspace
	explosionSound:Play()
end
bomb.Touched:Connect(function(hit)
	local character = hit.Parent
	local humanoid = character:FindFirstChildWhichIsA("Humanoid")
	if humanoid then
		local player = Players:GetPlayerFromCharacter(character)
		bomb:Destroy()
		player.leaderstats.coin.Value = 0
		explode()
	end
end)
local x = math.random(-20, 20)
local z = math.random(-20, 20)
bomb.Position = Vector3.new(x, 8, z)
while true do
	local part = Instance.new("Part", workspace)
	part.Name = "Coin"
	part.Anchored = false
	part.Shape = Enum.PartType.Cylinder
	part.BrickColor = BrickColor.Yellow()
	part.Size = Vector3.new(0.5, 3, 3)
	part.Touched:Connect(function(hit)
		local character = hit.Parent
		local humanoid = character:FindFirstChildWhichIsA("Humanoid")
		if humanoid then
			local player = Players:GetPlayerFromCharacter(character)
			part:Destroy()
			player.leaderstats.coin.Value += 1
		end
	end)
	local x = math.random(-30, 30)
	local z = math.random(-30, 30)
	part.Position = Vector3.new(x, 8, z)
	wait(2)
end




```

# 写真


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/c6bb0de6-d764-c1e9-9e70-dd3cce9c1d49.png)



以上。
Gitをhttpsからsshに接続変更する

# 概要
Gitを最初はhttpsでcloneした人向け。sshに接続変更する。

## 状態の確認
ターミナルからGitリポジトリをcloneしたところで以下を入力

```:コマンド
git remote -v
```

多分httpsでやってるとこうなる。

```:実行結果例
origin  https://github.com/example/hogehoge.git (fetch)
origin  https://github.com/example/hogehoge.git (push)
```

## sshの鍵作成

```:コマンド
ssh-keygen -t rsa -b 4096 -C "自身のメールアドレス"
```

上記入力後、鍵の名前、パスワード、パスワード(確認)を入力する。
（ここでは
鍵の名前： git_rsa
パスワード： 自分自身のPCパスワードにする）

```:例
% ssh-keygen -t rsa -b 4096 -C "test@example.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/****/.ssh/id_rsa): git_rsa
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in git_rsa
Your public key has been saved in git_rsa.pub
```

秘密鍵： git_rsa
公開鍵： git_rsa.pub

が作成される。

### ※-Cオプションの備考
ssh-keygenコマンドの-Cはコメントのオプションです。コメントは、公開鍵の末尾に付与されます。
オプションを使用しなかった場合は、ssh-keygenを実行した環境のユーザー名とホスト名で ```username@hostname``` が付与されます。
ここでは業務で鍵を作る場合に誰が作ったか一意で見分けやすいという理由から、"自身のメールアドレス"という具合にさせていただきました。

## 公開鍵をGitHubに登録

https://github.com/settings/keys

New SSH keyを押す

![スクリーンショット 2024-06-12 9.53.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290284/8112b56e-cf07-8955-f8bc-072b3a135c97.png)

この入力画面になる。

![スクリーンショット 2024-06-12 9.54.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290284/dd2bc78a-c81f-ed0c-21bc-e7abec7785b6.png)

以下を入力する。

Title: GitSSH
Key type: Authentication Key
Key: さっきのgit_rsa.pubの中身コピペ


Add SSH keyで公開鍵を登録。

## sshのclone 先の設定

(私のGitHub画面で恐縮ですが)
cloneしたいリポジトリのここを押してコピーします。

![スクリーンショット 2024-06-12 9.38.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290284/717b85ae-377a-20b2-0c7f-7949ff384d90.png)

## URL変更

ターミナルで以下のコマンドを実行して先ほどコピーしたsshのURLにします。

```:コマンド
git remote set-url origin git@github.com:hogehoge/fugafuga.git
```

## GitHubのssh configを設定する

ターミナルで以下のコマンドを実行。

```:コマンド
vi ~/.ssh/config
```

以下を追記

```:.ssh/configの中身
Host github github.com
        HostName github.com
        IdentityFile ここgit_rsaの設置場所
        User git
```

## 状態の確認
ターミナルからGitリポジトリをcloneしたところで以下を入力

```コマンド
git remote -v
```

こうなる。

```実行結果例
origin	git@github.com:hogehoge/fugafuga.git (fetch)
origin	git@github.com:hogehoge/fugafuga.git (push)
```

## 秘密鍵の権限変更

ターミナルで以下のコマンドを実行。

```:コマンド
chmod 600 git_rsaのファイル自体を指定
```

※git_rsaが秘密鍵ファイルなので、所有者のみの実行権限じゃないと警告が出るのでそのファイル自体の権限を変えてねってことです

## 接続テスト

ターミナルで以下のコマンドを実行。

```:コマンド
ssh -T git@github.com
```

```実行結果例
Hi ****! You've successfully authenticated, but GitHub does not provide shell access.
```

がでればOK
【Storybook】Nextjs14 & React 18でStorybookのインストールエラー修正 #Nextjs

この間Storybookのインストールを行う際にエラーが発生してしまったので、修正方法を記しておきます。

# やり方

1. まず```react-docgen-typescript-plugin```をnpm経由でダウンロード
2. ```package.json```の末尾に以下を追加
```package.json
 "typescript": {
    "reactDocgen": "react-docgen-typescript-plugin"
  }
```

あとはStoryBookのDOCSの通りにやればインストールできる...はず。

# ライブラリのサイト

https://www.npmjs.com/package/react-docgen-typescript-plugin
Makefileで赤文字 ( 色付きの文字 ) を標準出力する

# コード例

```
FONT_RED := $(shell tput setaf 1)
FONT_RESET := $(shell tput sgr0)

print-test:
	@printf "$(FONT_RED)red$(FONT_RESET)\n"

```


# 実行例

```
make print-test
```

<img width="231" alt="image" src="https://github.com/user-attachments/assets/a60fc9e5-5563-4c70-96e4-3ef2aac7462e">


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
社会人の勉強の仕方について

## はじめに

先日、IT系の資格を取得しました。久々に試験勉強をしてみると、学生のときの勉強方法と、社会人の勉強方法とは根本的に異なるものだということに気付きました。

同じ社会人でも独身のときと、家庭を持った後でも異なってきます。家庭を持った社会人の効率的な勉強方法について、感じたことを書いてみました。もしかすると、Qiitaの記事にはあまり関連性のない話題になるかも分かりませんが、ご容赦願います。

## 勉強の仕方について

家庭を持つと休日にたっぷり勉強をするといったことができなくなります。子供が小さいと尚更です。しかし、子供が大きくなるとまた事情は変わってくるかも分かりません。自分には４歳の子供がいますがまず無理です。それでも、０～１歳の頃と比べると、大分、融通が利くようにはなってきました。自分は子供が寝ている間を見計らって、短期集中的に勉強をしました。それと、隙間時間を活用しました。隙間時間とは、子供が風呂に入っているとき、買い物の待ち合わせのとき、公園で遊ばしているとき、図書館で子供が絵本を読んでいるときなどです。勉強できたとしても２０分がせいぜいです。正直、あまり勉強ができた手ごたえが得られないまま、中断を余儀なくされます。１時間でも勉強ができれば「有意義な時間を過ごせたぞ」と思えてきます。家庭を持ちながら勉強をするということはこういうことです。独身のときや、学生の頃はこんな勉強の仕方など、夢想だにしませんでした。

なんせ、机に座ってじっくりと、まとまった時間勉強するといったことができなくなります。（自分だけでしょうか？）そんな環境でも、資格取得をひとたび志せば、勉強せざるを得なくなります。このような環境でも成果を出すにはどうすればいいのでしょうか。

自分はこのような勉強の方法を取りました。というか、取らざるを得ませんでした。

- ザブノートは作らない
- 暗記カードは作らない
- 完璧暗記を目指さない
- 短期集中型の取得を目指さない（気ながにやる）

結果的には、このやり方でよかったんじゃないかと思っています。昔からこのような勉強方法の方がよかったんじゃないかと、今更ながら実感しました。人は追い込まれたり、逆況に追いやられると、知恵を出すようになるものです。

## やり方を変えてみる

やり方を変えてみることはいいことです。イチローは調子が良かった年でも、毎年バッティングフォームを変えていたと言っていました。普通なら調子が悪い時にフォームは変えるもので、調子が良いいのであれば変えないものです。イチローはなぜ敢えて変えていたのかは分かりません。それが結果的に良かったのか悪かったのかも分かりません。恐らく、イチロー自身も分かっていない可能性があります。恐らく、未知の領域に挑戦したいという思いが彼の原動力だったのではないかと個人的に推測しています。

変えてみる。それは、飽くなき挑戦だと思います。

## 時短こそが効率のポイント

高校の時、部活をやっていない人よりもやっている人の方が成績がいいといったデータがあるといった話を聞いたことがあります。部活をやっていると勉強する時間が限られるため、短い時間でどのように工夫すれば、成果が上げられるかを考えて取り組むようになるからなのでしょう。部活をしていない人はたっぷりと時間があるため、逆にダラダラしてしまい、効率的に勉強しようと思わなくなるのでしょう。

家庭を持つと時間が取れなくなる分、独身貴族のときにやっていた、時間の無駄遣いをしなくなるようになるのでしょう。逆説的ではありますが、時間がない方が、結果的にいい結果を生み出すといったことが言えるのでしょう。

それでも、圧倒的に時間が短くなると、物理的に時間が欲しいと思う場合もあります。そんなときは、たまには有給を取って、たっぷり勉強に充てるのもありでしょう。有給は年間２０日もあるのです。（勤続年数にもよりますが）日本人は働き過ぎだと言われますが、考えてみれば割と休みはあるのです。取得率が低い人は再認識するべきです。

## 勉強方法の詳細

自分が取った勉強方法をもう少し詳細に書いてみます。

#### 1.ザブノートは作らない

机に座ってじっくりができない環境なのでそもそも作りませんでした。結果的に作らなくて正解だったと思っています。作り出すとノート作りが目的になってしまうものです。最終目的は暗記です。紙に覚えさせるのではなく、自分の頭に覚えさせることが最終目的です。綺麗なノート作りはそれはそれで楽しいものではありますが、そんなことに時間を割くのは無意味だと悟るべきでした。

#### 2.暗記カードは作らない

作ってもいいのだが、これを作ると完璧主義に陥ってしまう可能性が高いように思います。それに作っている時間などないので作りませんでした。

#### 3.完璧暗記を目指さない

資格の試験問題は大抵選択式です。用語を完璧に暗記している必要性はありません。用語を記述するような問題は出題されません。うろ覚えでも問題文を読むとなんとなく思い出せるものです。完璧暗記は時間の無駄です。70%でも覚えていれば、ほぼほぼ対応できるものです。自分は紙に殴り書きをして、覚えるようにしていました。これを数回繰り返しただけで、ある程度記憶に残るものです。

殴り書きには白紙の紙に青色ペンを使いました。なぜ青色ペンを使ったかといえば、ネットのある記事を読んで、青色ペンでノートを取ると、記憶力が増すといった記事を読んだことがあるので、根拠があるのかどうかは分かりませんが、とりあえず真似してみようと思っただけです。

#### 4.短期集中型の取得を目指さない

合格体験記を読んでいると「業務未経験から〇〇の資格を〇週間で取得しました！」などといった記事をときどき目にします。「業務未経験なのに、そんなすごい資格をそんな短期間で取得したんだ。すけー。」と思ってしまいますが、家庭を持つ社会人にはまず無理です。１日数分しか勉強できなくなるので長期戦を余儀なくされます。はなから弾丸取得は目指さないで下さい。心に余裕を、のんびり気分でいきましょう。
Outlook会議室予約のトラブルメモ（第三者からの参照可否）




# Exchange管理センターでのリソース設定

## 背景
- 弊社グループ内での会議室予約を「LINE WORKS」から「Outlook/Teams」に切り替えることなった。

## 前提・課題

- Exchange管理センターにて会議室リソースの追加をおこなった
- 会議室の予約が可能となり第三者は会議室の空き状況を把握できるようになったものの予約者を参照できない
- 会議室リソースのタイムゾーンもずれている可能性がある

> **注意**: 実際の画面と文言がずれている場合がありますがご了承ください。

## 手順

### 1. 事前準備: リソースへのアクセス権付与

各リソースの共有設定をするために、共有設定を実施するメンバーに対して各リソースへのアクセス権を付与します。

1. Exchange管理センターにログインします。https://admin.exchange.microsoft.com/#/homepage
2. 「受信者」>「リソース」>対象リソースを開き「委任」タブを選択します。
3. 読み取りと管理（フルアクセス）の「編集」をクリックします。
4. 「＋メンバーの追加」>共有設定を実施するメンバーを選択して「保存」>「確認」をクリックします。

### 2. 共有設定: タイムゾーンと共有設定

各リソースのタイムゾーンと共有設定をします。

1. 事前準備でリソースへのアクセス権を付与したユーザーでWeb版Outlookにログインします。https://outlook.office.com/calendar/view/week
2. 画面右上の自身のアイコンをクリックし「他のメールボックスを開く」をクリックします。
3. 対象リソースを検索（リソース名、メールアドレスいずれも可）し「開く」をクリックします。
4. 対象リソースのOutlookカレンダー画面に遷移したら、画面右上の「設定（歯車マーク）」をクリックします。
5. 「表示」>タイムゾーンで「（UTV+09:00）大阪、札幌、東京」を選択します。
6. 「会議室のタイムゾーンを更新しますか？」で「はい、更新します」をクリックします。
7. 「保存」します。
8. 「共有予定表」>予定表を共有するで「calendar」を選択し「共有」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492406/284aa7ce-372f-909e-df34-0772509d84f3.png)

9. 所属組織内の人に対して付与する権限を選択します。（会社の方針に合わせて選択してください）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492406/9618ec7e-e7f0-b2cd-abde-bd9b6140c660.png)
コンテナ内でsystemdを使う方法

とりあえず実験したいときにsystemdが動くようにする設定方法。
9系から/sbin/initが無くなったりしておりDockerfileで小細工が必要となっている。

以下参考
AlmaLinux Container image for Ansible
https://github.com/bpadair32/docker-image-alma9-systemd
Rocky Linux 9 Docker Image with systemd
https://github.com/eniocarboni/docker-rockylinux-systemd
Running Amazon Linux 2023 with systemd in Docker
https://github.com/compwright/amazonlinux-2023-systemd

## 8系

```yml:docker-compose.yml
services:
  alma8:
    image: almalinux:8.10-20240723
    container_name: alma8
    privileged: true
    command: /sbin/init
```

```bash
docker compose up -d
docker compose exec alma8 /bin/bash
[root@1d4aa45a0f49 /]# dnf module enable -y nginx:1.24
[root@1d4aa45a0f49 /]# dnf install -y nginx
[root@1d4aa45a0f49 /]# systemctl start nginx
```

## 9系

```text:Dockerfile
FROM amazonlinux:2023.5.20240708.0
RUN dnf install -y systemd kernel-libbpf
CMD ["/usr/sbin/init"]
```

```yml:docker-compose.yml
services:
  amazon2023:
    build:
      context: .
    container_name: amazon2023
    tty: true
    cgroup: host
    cap_add:
      - SYS_ADMIN
      - NET_ADMIN
    volumes:
      - /sys/fs/cgroup:/sys/fs/cgroup:rw
```

```bash
docker compose up -d
docker compose exec amazon2023 /bin/bash
bash-5.2# dnf install -y nginx
bash-5.2# systemctl start nginx
```