OmniAICreator/Qiita-1.07M huggingface dataset:
localhost:3000にアクセスするとhttpsに強制されるのが辛い

# はじめに
この記事は過去にハマったことを忘れて、また最近ハマったのでいい加減覚えるための自分用のメモです。
# 結論
以下の2点が原因
- Railsの`config/enviroments`の環境に対応したファイルで`config.force_ssl = true`が設定されている
- サーバー側がSSLによるアクセスを強制する場合、Chromeがそれをキャッシュし、次にhttpでアクセスしてもhttpsに強制する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1045272/6e7e18ac-1ba0-348e-1e9f-3c092d81e627.png)

# 直し方
1. `config.force_ssl = true`の記述をコメントアウトもしくは削除
2. Chromeのメニューから「設定」を開き、「プライバシーとセキュリティ」セクションの「閲覧データを削除」に進んで、「キャッシュされた画像とファイル」を選択し、「データの削除」をクリック

# 私がハマったケース
railsの7.2で簡単に開発環境を作ろうと思いとりあえず動くことを確認するため、productionの環境でDockerを起動しました。localhost:3000にブラウザでアクセスしてみるとブラウザに「このサイトは安全に接続できません」とメッセージが表示されました。
Railsのログを見てみると以下が出力されていました。
```
Puma::HttpParserError: Invalid HTTP format, parsing fails. Are you trying to open an SSL connection to a non-SSL Puma?
```
これは以前遭遇したことがあり、productionの環境ファイルを以下のように設定してやれば解決のはずです。
```ruby:config/enviroments/production.rb
  # この記述をコメントアウト
  # config.force_ssl = true
```
これによりRailsを再起動して再びブラウザから`http://localhost:3000`でアクセスしてみたのですが結果が変わらずでRailsのログも何も変わらずでした。
ここでブラウザを疑うことができてればハマらずに済んだのですが、Railsにこのsslを強制する機能があったため、「Railsを調査する」というハマりルートに突入しました。
# 学び
ブラウザがキャッシュするのはページの画像など表示されているものだけだと思っていたのですが、httpsでしか受け付けてないかどうかも覚えているみたいです。この機能に気がついた時はめちゃめちゃ腹立たしい気持ちになりましたが、開発者以外の利用を考えると理にかなっているように思いました。
Java Silver 試験中に気を付けたいこと

# はじめに

先日Java Silver (SE11)を取得したので、その時のノウハウを少し共有したいと思います。(合格体験記的なものではないです)

# 試験中に何を気を付けるか

Java Silverは結構というかかなり引っ掛けの問題が多いので、ボーっと解いていると簡単に点を落としてしまうと思います。そこで本記事では非常に簡単にではありますが、試験本番中に頭に片隅に入れておくことで3%くらい点数を伸ばせるかもしれないノウハウを紹介します。
(試験自体の学習が済んでいることを前提としているので、試験前日とかに確認するTips的なものとして捉えていただけると幸いです)


### 1. finalは初期化しないとエラー

finalの付いた変数は、初期化をしないとコンパイルエラーとなります。
特に気を付けたいのは、複数定義されているコンストラクタの中でfinalの変数が初期化されている問題です。一方のコンストラクタでは初期化されているのにもう一方では初期化されていない場合などがあるので、目を光らせておく必要があります。

例) 引数なしのコンストラクタではfinalの変数aが初期化されない
```Java
public class ClassA {
    private final int a;
    public ClassA(int a) {
        this.a = a;
    }
    public ClassA() {}
}
```


### 2. Immutableなクラス

StringなどのImmutableなクラスのメソッドが記述されている場合、返り値を変数に代入しているかをよく確認することが重要です。基本的な要素ですが、本番中に緊張すると見落とす可能性も高まるので気を付ける必要があります。


### 3. 抽象メソッドが実装されているか

インターフェースや抽象クラスにおいて定義される抽象メソッドは継承先のどこかで実装される必要があります。継承・実装を2個以上挟む場合などに見落としやすくなりがちなので、この場合は特に気を付けた方がいいでしょう。


### 4. クラスのアクセス修飾子

問題をこなしているうちに、メソッドや変数のアクセス修飾子については、よく確認する癖が自然と付くと思います。一方でクラスのアクセス修飾子については、メソッドや変数ほど気を付けて見ないことが多いかもしれません(少なくとも自分はそうでした)。
クラスのアクセス修飾子が解答の分かれ目になる問題が出題される可能性もあるため、確認する意識を持つと良いと思います。


例) ClassAのアクセス修飾子がデフォルトなのでClassBからアクセスができない

```Java
package example.p1;

class ClassA {}
```

```Java
package example.p2;
import example.ClassA;

public class ClassB {
    public static void main(String[] args) {
        ClassA a = new ClassA();
    }
}
```
### 5. 「進研ゼミでやったやつだ」で反射的に解答しないようにする

受験者の方は試験対策として模擬問題を解くことがあると思いますが、特に黒本の問題は質が良いため、本番でもかなり似たような問題を見かけることになるかと思います。その時に気を付けたいのが、反射的に「進研ゼミでやったやつだ」が発生して黒本での解答と同じような選択肢を選んでしまうことです。もちろんそれが結果的に正解となれば良いのですが、問題文によく目を通さずに解答してしまうのが一番怖いです。実際それで引っかかりかけた問題がありました。
したがって、よく知った(気がする)問題が出題されても油断しないことが大切だと感じます。



# 終わりに

最後まで読んでいただきありがとうございました。
今回はつまらないミスを減らすためのちょっとした考えを紹介させていただきました。本記事が皆様の助けとなれば幸いです。
Vertex AI Agent Builder目次

# Vertex AI Agent Builder 全体像

```mermaid
flowchart TD

    subgraph S1[Vertex AI Agent Builder]
        A[Vertex AI Agent Builder] --> B[Vertex AI Agents]
        A --> C[Vertex AI Search]
        
        B --> D[LLM app]

        C --> E[Search apps]
        C --> F[Recommendation apps]

        E --> G[Generic search]
        E --> H[Media search]
        E --> I[Healthcare search]

        F --> J[Media recommendations]
        F --> K["Generic recommendations (Preview)"]
    end

    subgraph S2[Vertex AI Search for retail]
        L["Vertex AI Search for retail"] --> M[Recommendation]
        L --> N[Search]
    end
```


1. [Vertex AI Agent Buidler](https://cloud.google.com/generative-ai-app-builder/docs/introduction)
    1. Vertex AI Agents <- LLM app
    1. Vertex AI Search
        1. Search apps
            1. Generic search
            1. Media search
            1. Healthcare search
        1. Recommendation apps
            1. media recommendations
            1. generic recommendations (Preview)
1. [Vertex AI Search for retail](https://cloud.google.com/retail/docs/features)
    1. Recommendations
    1. Search

:::note warn
Vertex AI Agent Builder > Vertex AI Search > Recommendation という構造が、知らない人にはわかりずらい。Agent、Search、Recommendationと幅広い用語が出てきて複雑になる。「Agentの下のSearchのRecommendation…」
:::

:::note warn
さらにもう一つ状況をややこしくしているのが[Vertex AI Search for retail](https://cloud.google.com/retail/docs/features)

Vertex AI Search for retailはVertex AI Agent Builder以下でもないが、Vertex AI Searchという言葉を共通で使っているのでややこしくなる。

Media searchとMedia recommendationのようにVertex AI Search以下でretail searchとretail recommendationにすればもっとわかりやすかったはず
:::

# まとめ記事一覧

## Vertex AI Agent Builder

### Vertex AI Agents

TBD

### Vertex AI Search

#### Search apps

https://qiita.com/nakamasato/items/295a2a3a4d5ed2aab2d5

#### Recommendation apps

https://qiita.com/nakamasato/items/26a60eca99b5323d440c

## Vertex AI Search for retail

https://qiita.com/nakamasato/items/012ea7159d3e3fc8e30e

## Vertex AI (その他)

https://qiita.com/nakamasato/items/ddf778aef32f3a8421c3
[TouchDesigner]動画ファイルをループ再生させない

![TouchDesigner](https://img.shields.io/badge/TouchDesigner-2023.11880-36476a?style=flat-square)

### サンプルファイル
https://github.com/arkwknsk/touchdesigner/tree/master/tips/movie-no-loop

### 動画ファイルをループ再生しない方法
`Movie File In TOP`のパラメーター→Trimタブの中の <img alt="1" width="15" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55390/e1bf660c-e249-c2a5-4714-f508440b8b48.png"> Extend Rightを`Hold`にします。

<img width="429" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55390/db29c1db-2ddc-4830-8bb2-f7cfd31a64eb.jpeg">

`Cycle`のままだとループ再生になります。`Black`にすると、再生終了後、黒みになります。
最小限のタスク分担管理をMicrosoft Plannerでやる使い方

# 概要

ちょっとした短期の作業を複数人でやる。標準のプロジェクト管理ツールを使うほどじゃないが、タスクの見える化と分担はしたい。それくらいのニーズをMicrosoft 365のPlannerで満たすための最低限の使い方を紹介します。Plannerを本格的に使う場合にできる事はもっと多いと思いますが、そういう解説は他に任せて、ここでは「取り急ぎ使いたいが、使い物になるか？」くらいの観点に絞ります。

# 最初に結論まとめ

手間の掛かる手順無しで、「タスクをカードにしてカンバンボードみたいなものに配置し、各担当へ共有したりメール通知する」程度の使い方ができました。

注意点として、プランを作ると自動でチーム（MS365グループ）が作られてしまいます。ルール上で申請が必要などの理由からそういう手間を避けたい場合は、既存のグループにプランを追加するという作り方がお勧めです。

# 説明

ちょっとしたごく短期のプロジェクトを複数人でやるので、タスクの分担をわかりやすく管理したい。もちろんredmineのような正式なプロジェクト管理ツールはあるが、そこに新規プロジェクトを作るような面倒なものでは無く、今すぐパッと使いたい。こんな要求はよく有ると思いますし、解決できるツールもいくつもあると思います。

しかし、そこにこんな条件が付く会社も多いと思います。「新規のSaaSを使うのは原則NG。Microsoft 365の契約で使える範囲なら良い」。そうなってしまう理由も分かりますが、ちょっと厄介ですね。そういうツールはあるでしょうか？

MS365にも、Microsoft PlannerというWebアプリがあります。大雑把に言うと、カンバンボードのような物を作れます。タスク1つを1枚のカードにして、画面上の領域に貼り付ける。カードはドラッグ＆ドロップで並べ替えたり移動したりできる。カードには担当者と期日を書ける。タスクが終わったらカードをパッと捨てられる。そういうものです。これなら要望に合いそうです。手軽に使えるかどうか、最低限の使い方を見ていきましょう。

## 最低限の使い方

まず、Microsoft 365のアプリ一覧から、Plannerを探し出してください。たくさんありますが、がんばって！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/79769f4c-7c29-0bd4-69ad-a8afff6de86b.png)

Plannerを開いたら、「プラン」を作ります。プランに対して1つのカンバンボードのようなものが割り当てられ、プランの単位でユーザーにアクセス権限を与えることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/096b27d1-866c-70cc-1a08-d72a42ad230e.png)

UIからは想像が付きませんが・・・そのまま作ると、新規のMS365グループが作成され、そこにプランが割り当てられます。MS365を使うような組織のルールだと、グループ作成にもルールが有る場合が多いと思うので、既存のグループに追加した方が手軽だと思います。その場合、「既存のMicrosoft 365グループの追加」を選びます。

プランを作成したら、上部の「メンバー」メニューから、一緒に作業をするメンバーを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/d03a5e8a-273e-d56d-1bd2-9701f9d8c26c.png)

この時点で、追加したメンバーへメール通知が行きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/f89a4451-3985-2439-4a7f-ecbb787423da.png)

準備ができたので、タスクを一覧して割り振っていきます。縦方向のエリアに対して、カードのような形でタスクを作って貼り付けていくというUIになっています。

タスクの名前を書くだけで作成完了です。担当と期日を設定することもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/c8ebe6e8-28bb-dcfd-508b-39b4f97ee42e.png)

担当を追加した場合、これもユーザーにメール通知されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/489c51d2-9529-6b91-d22d-54633c80a143.png)

作成時点ではタイトルだけですが、開いてメモやコメントを追加することもできます。（画像の例ではMarkdownで書いていますが、Markdownの認識はできません）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/18cc6ea6-5955-90be-f72a-9eadd3df975c.png)

メモやコメントの変更については通知メールは行かないようです。

以上です。かなり手軽に使えそうですね。

ちなみに、別の形式で表示することもできます。まず、スケジュール表示です。期日を入れたものがカレンダー上に表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/6c2ff9fa-1a23-e43a-adfa-4b8aa2bf1621.png)

グリッド表示もできます。同じ形でExcelファイルへのエクスポートもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616143/fa4765a5-b3ff-1ff2-c71c-16f3f55dc9ae.png)

まあここまでできれば、冒頭に書いたような用途では十分だと思います。

# まとめ

ちょっとした短期の作業を複数人でやる場合に使うようなお手軽なタスク管理ツールを、Microsoft 365で使えないか？という要望は、Plannerで満たせました。Microsoft 365はどちらかというと多機能で使い始めが大変なものが多いですが、Plannerは使い始めるのにはさほど苦労しないようです。ライセンスを持っている人は、上手く生かして便利にしていきましょう！
Calendly とSalesforceの統合

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめA～M](https://qiita.com/Keiji_otsubo/items/f3ddedee6793bf1576f8)

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


+ [Calendly のフローに INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY エラーが発生し、Salesforce がユーザー メール アドレスの下に重複したプロファイルを作成し、適切な権限なしで新しいイベント レコードを誤った {!OwnerId} に添付しています (基本的にはゴースト プロファイル)。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A8CQs)

:::note
純粋にこの記事を読んで、Calendly と Salesforce の統合を設定しようとしたときに同じエラーに遭遇した他の人のために言っておくと (私と同じように)、問題はゴースト ユーザーとはまったく関係がなく、むしろ Jessica と私に共通する要素は私たちが 2 人とも SF 管理者であるという点であり、それが手がかりだということがわかりました.....

管理者として、私の組織には、私のメール アドレスを共有する SF 統合ユーザー数名とテスト ユーザーがいます。これが問題でした。実行される Calendly の CreateEventTemplate フローに、ユーザーのメール アドレスを検索して Calendly でイベントを企画した人物と一致する「イベント発行者の取得」アクションがあります。最初のユーザーのみを取得し、そのユーザーをイベント レコードの OwnerId として割り当てます。そのため、エラーが発生し、フローが失敗しました。

フローを複製して編集し、ユーザーを検索する際にメール アドレスだけでなく別の識別フィールドも一致するようにしました (私たちの場合、Calendly ユーザー名を一致させました。これは SF のユーザーのフル ネームと常に一致していましたが、SF ユーザー名は私たちの組織のメール アドレスと完全に一致するため、一意になります)。こうすることで、一致した最初のユーザーが正しいユーザーとなり、フローは問題なくイベントを作成しました。

注意: Calendly がインストールする他のフローの中には、ユーザーの一致をチェックするものがあります。そのため、どこでそれが起こったとしても、それらのフローも更新する必要があります。
:::
カーネル密度関数でタイタニックの必要な変数を見つける

ヒストグラム以外で分かりやすく特徴量の分布を表してくれるものとしてカーネル密度関数というものがあるのですが、これを今回使って有効的な特徴量を探してみようと思います。
# カーネル密度関数
```Python3
for col in df_train.columns:
    try:
        sns.kdeplot(df_train[df_train["Survived"]==0][col], label="Survived = 0")
        sns.kdeplot(df_train[df_train["Survived"]==1][col], label="Survived = 1")
        plt.legend()
        plt.show()
    except:
        _ = 0
```
ここで見つけた分布が異なる特徴量がこれでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/e1c427d3-102a-2700-cceb-0d3685dbe73f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/a6d044b0-94c9-f6c9-dbfc-dcf23a44bec7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/4ec1e2d0-8c5b-b1f9-23c6-0ef6ac07bb58.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/1ad50580-a17c-d210-626b-95fbb76a96fb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/4d5cb5f7-c722-cb33-6c30-0cc6fde8633e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/e57d0ad7-e12b-6895-d1d8-4dbe85005b95.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/50a3cc9d-a24c-301b-8e30-5aa91479554c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/e4a903d8-31fc-8346-bb71-764970ad73d5.png)
と、ここから変数選択してなんやかんや77.272%となりました。
予測手法はhold-outを200回訓練データと検証用データを変えて学習させ上位3位のモデルを使って多数決で予測するという手法です。
【デザインパターン】Adapterパターンについての備忘録

# 概要

アダプターパターンは、互換性のないインターフェースを持つクラス同士を接続するためのデザインパターンである。**異なるインターフェースを持つオブジェクト**を使いたい場合、**アダプタークラスを介して既存のクラスを新しいインターフェースに適合させる**。

# 利用目的

アダプターパターンは、**既存のクラスを再利用しつつ、そのクラスのインターフェースを変更したい**場合に使用される。例えば、新しいインターフェースに合わせて**既存のクラスを使いたいが、元のクラスを直接変更したくない場合**に有効である。特に、異なるライブラリや API を統合する際に便利である。

# 注意点

アダプターパターンは、既存のクラスに依存しているため、**クラスの内部構造や動作に変化があった場合、アダプターも修正が必要になることがある**。また、複雑なアダプターを作ると、設計が不必要に複雑になる場合があるため、**単純な解決策で済むならばアダプターパターンを使用するべきではない**。

# 実装

```java:Target
// クライアントが使用するインターフェース
public interface Target {
    void request();
}
```

```java:Adaptee
// 既存のクラス。異なるインターフェースを持つ
public class Adaptee {
    public void specificRequest() {
        System.out.println("AdapteeのspecificRequestが呼び出された");
    }
}
```

```java:Adapter
// アダプタークラス。TargetインターフェースにAdapteeを適合させる
// 【注意】新インターフェースを implements する！
public class Adapter implements Target {
    //【 既存のクラス Adaptee を所有する！】
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        // 【新インターフェースのメソッド内で既存クラスのメソッドを呼び出す！】
        adaptee.specificRequest();
    }
}
```

```java:App
// Mainクラス
public class App {
    public static void main(String[] args) {
        Adaptee adaptee = new Adaptee();
        Target adapter = new Adapter(adaptee);

        // クライアントはTargetインターフェースを通してアダプティのメソッドを使う
        adapter.request();
    }
}
```

# クラス図
![adapter_class_diagram.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3845328/a4f231f5-46c2-c30c-4046-ecf46d29590c.jpeg)
2024/9/30主にITとかセキュリティの記事

Windowsの「ブルースクリーン問題」　Microsoftが頑なに脆弱性を認めない理由(9/27)
https://kn.itmedia.co.jp/kn/articles/2409/27/news048.html

柴山コンサルタントグループの事例に学ぶ建設業界のサイバーセキュリティ対策
https://cybersecurity-park.com/3047/

最新 AI 駆動フロントエンド開発ツールを使って Web アプリ、ネイティブモバイルアプリを開発してみよう(9/28)
https://www.docswell.com/s/shosuz/5EXEX8-2024-09-28-161232

Androidに偽ウォレットアプリ、5カ月で1万回ダウンロード(9/28)
https://news.mynavi.jp/techplus/article/20240928-3033106/

【第3報】当社におけるサイバー攻撃によるシステムの停止事案発生のお知らせ(9/28)
https://www.kantsu.com/news/6615/

財務省財務局が、株式会社DMM Bitcoinに対する行政処分を、金融庁が、暗号資産の流出リスクへの対応等に関する注意喚起及び自主点検要請について発表していますね...(2024.09.26)(9/28)
http://maruyama-mitsuhiko.cocolog-nifty.com/security/2024/09/post-ff4245.html

1100万台以上のAndroidに影響。トロイの木馬「Necro」が見つかった正規アプリとは(9/28)
https://www.lifehacker.jp/article/2409necro-trojan-malware-has-infected-11-million-android-devices/

全国労働金庫協会（ろうきん）を騙るフィッシング詐欺、実は判別できます！(9/28)
https://ascii.jp/elem/000/004/224/4224561/?rss

流出した個人情報買った名簿業者を告発　NTT西事件で政府保護委、岡山県警が受理(9/28)
https://news.yahoo.co.jp/articles/624e17bf393a6743b186235313c1eb73da0ede27?source=rss

当社Facebookアカウントのセキュリティ侵害について SmartNews(9/28)
https://about.smartnews.com/ja/2024/09/28

「パスワードを紙に書く管理方法は意外と安全」「パスワードの定期的な変更は危険」「記号や数字の混在を義務付けるのはNG」など知っておくべきパスワード知識(9/27)
https://news.livedoor.com/article/detail/27261874/

「独自の決済プラットフォーム創設を」（BRICS）目指すのは脱ドル依存(9/27)
https://www.jetro.go.jp/biz/areareports/2024/399b396ce7895687.html

子どもに「チャット機能」のある「オンラインゲーム」をやらせるのは危険ですか？ 「課金機能」もあると聞いてなおさら警戒しています…。(9/28)
https://financial-field.com/living/entry-327080

今年だけで76人の韓国人が拉致監禁されたカンボジア、フィッシング詐欺の拠点になっていた(9/28)
https://www.chosunonline.com/site/data/html_dir/2024/09/26/2024092680140.html

“トランプ前大統領の陣営をハッキング”イラン革命防衛隊の3人起訴　米司法省(9/28)
https://news.ntv.co.jp/category/international/02a5c1fdaa6d44b3be53bd4b075871e3

米選挙ハッキングで起訴　イラン革命防衛隊、制裁も(9/28)
https://nordot.app/1212488916222280148

安保テーマに日韓協力など議論　立命館大と韓国外大共催(9/28)
https://mainichi.jp/articles/20240925/k00/00m/030/320000c
【デザインパターン】Decoratorパターンについての備忘録

# 概要

デコレーターパターンは、既存のオブジェクトに新しい機能を追加するためのデザインパターンである。基本的な考え方は、**元のオブジェクトをラップし、動的に機能を拡張する**点にある。これにより、**サブクラス化せずに機能を追加でき**、柔軟で保守性の高い設計が可能となる。

# 利用目的

デコレーターパターンは、クラスの機能を動的に拡張する際に使用される。特に、複数の異なる拡張が必要な場合や、継承による設計が複雑になりすぎる場合に有効である。例えば、IO 処理において、バッファリングや圧縮、暗号化などの機能を重ねて適用する際に役立つ。

# 注意点

デコレーターパターンを過度に使用すると、オブジェクトが多層化してコードが複雑になり、可読性が低下する可能性がある。また、デコレータの連鎖が深くなると、デバッグやメンテナンスが難しくなる場合があるため、適切な設計が求められる。

# 実装

```java:Component
// 機能追加したいコンポーネントのインターフェース
public interface Component {
    void operation();
}
```

```java:ConcreteComponent
// 機能追加したいコンポーネントの実装
public class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("基本機能");
    }
}
```

```java:Decorator
// デコレータの抽象クラス
// 【注意！】機能追加したいコンポーネントのインターフェースをimplementsしている！
public abstract class Decorator implements Component {
    // 【注意！】機能追加したいコンポーネントを所有する！
    protected Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        component.operation();
    }
}
```

```java:ConcreteDecoratorA
// 追加機能Aを持つ具体的なデコレータ
public class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    // 【注意！】ここで機能追加！
    @Override
    public void operation() {
        super.operation();
        System.out.println("追加機能A");
    }
}
```

```java:ConcreteDecoratorB
// 追加機能Bを持つ具体的なデコレータ
public class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    // 【注意！】ここで機能追加！
    @Override
    public void operation() {
        super.operation();
        System.out.println("追加機能B");
    }
}
```

```java:App
// Mainクラス
public class App {
    public static void main(String[] args) {
        Component component = new ConcreteComponent();
        Component decoratedComponentA = new ConcreteDecoratorA(component);
        // 【注意】ConcreteDecoratorAもComponentをimplementsしているので、ConcreteDecoratorBに渡せる！
        Component decoratedComponentB = new ConcreteDecoratorB(decoratedComponentA);

        // 基本機能 + 追加機能A + 追加機能B を実行
        decoratedComponentB.operation();
    }
}
```

# クラス図
![decorator_class_diagram.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3845328/006032d3-9b45-6521-3157-fb1be46b5283.jpeg)
【デザインパターン】Observerパターンの学習備忘録

# 概要

Observer パターンは、あるオブジェクト（Subject）の状態が変化した際に、その変化を複数の依存するオブジェクト（Observer）に通知し、オブザーバーがその変化に対応する動作を実行できるようにするデザインパターンである。このパターンは、オブジェクト間の依存を減らし、柔軟な通知システムを実現するのに適している。

# 利用目的

- 状態が変わったときに、関連する他のオブジェクトに自動的に通知を行う必要がある場合。
- 監視対象（Subject）と監視者（Observer）間の結合度を低く保ちながら、柔軟な拡張を可能にする。
- イベントドリブンなシステムや、リアルタイムで更新が必要な UI コンポーネントなどに使用される。

# 注意点

- Observer の数が多い場合、通知処理が重くなる可能性がある。
- 通知する内容が多岐にわたる場合、通知内容を効率的に設計する必要がある。
- 循環参照や無限ループを避けるために、適切な管理が必要である。

# 実装

以下に、Observer パターンを Java で実装した例を示す。この実装では、状態を監視する`Subject`と、それに応じて通知を受ける`Observer`を実装する。

```java:Observer.java
// Observer.java - オブザーバーインターフェース（観察者）

public interface Observer {
    void update(String message);
}
```

```java:Subject.java
// Subject.java - サブジェクトインターフェース（被観察者、通知者）

public interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}
```

```java:ConcreteSubject.java
// ConcreteSubject.java - サブジェクトの具体的実装
import java.util.ArrayList;
import java.util.List;

public class ConcreteSubject implements Subject {
    private List<Observer> observers;
    private String message;

    public ConcreteSubject() {
        this.observers = new ArrayList<>();
    }

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }

    public void setMessage(String message) {
        this.message = message;
        notifyObservers();
    }

}
```

```java:ConcreteObserver.java
// ConcreteObserver.java - オブザーバーの具体的実装
public class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + " received message: " + message);
    }

}
```

```java:App.java
// App.java - 実行例
public class App {
    public static void main(String[] args) {
        // サブジェクトを作成
        ConcreteSubject subject = new ConcreteSubject();

        // オブザーバーを作成
        Observer observer1 = new ConcreteObserver("Observer 1");
        Observer observer2 = new ConcreteObserver("Observer 2");

        // オブザーバーをサブジェクトに登録
        subject.registerObserver(observer1);
        subject.registerObserver(observer2);

        // サブジェクトにメッセージを設定し、オブザーバーに通知
        subject.setMessage("Hello Observers!");

        // Observer 1を削除し、再度通知
        subject.removeObserver(observer1);
        subject.setMessage("Observer 1 has been removed");
    }

}
```

# クラス図
![observer_class_diagram.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3845328/359a759c-dd7f-b386-72cd-88d3411e74dd.jpeg)
量子アニーリング認定(エントリー)コースを受講し、認定を受けてみた

# 概要
日本量子コンピューティング協会主催の量子エンジニア(エントリー)講座を受講し、認定試験を受験してみたところ、無事:cherry_blossom:合格:cherry_blossom:したので記憶が薄れないうちに色々まとめておこうと思います。

:warning: 現在の量子アニーリングのエントリー講座は筆者が受講した時と**形式(全５回→全3回、教材、試験問題公開→教材は一部公開、試験問題は非公開)や講師が変わっている**様です。あくまで参考情報として御覧下さい。

# そもそも量子アニーリング認定(エントリー)とは？
詳細は以下の公式ページを参照いただければと思いますが、講座の内容としては量子アニーリングによる組み合わせ最適化の基礎やOSSのシミュレーターTytan SDKを用いた組み合わせ最適化問題の解き方の基礎などを学べます。昨今しばしば話題に上ることが多くなった量子コンピュータですが、大別すると量子アニーリング方式と量子ゲート方式が存在しますが、この講座では量子アニーリング方式の方が学べます。５回の講座を受講後、認定試験問題に解答し、合格すると量子アニーリング認定(エントリー)に認定されます。筆者はこれまで何度も量子コンピュータを勉強しようと思いながら、その度に専門書の難解さに辟易として挫折していました。しかし、以下の啓蒙書を読んで改めて面白さを実感し、改めて少しずつ勉強しよう思い立ち、その最初のステップとして当認定を受けてみました。

https://bookmeter.com/books/21610004

* 参考: 公式ページ

https://www.jqca.org/course.php

* 参考: Tytan SDK @ GitHub

https://github.com/tytansdk/tytan

* 参考: 講座情報 @ Connpass

https://jqca2023.connpass.com/event/322479/

https://jqca2023.connpass.com/event/323300/

https://jqca2023.connpass.com/event/323784/

https://jqca2023.connpass.com/event/324497/

https://jqca2023.connpass.com/event/325160/

## 受講料・受験料
筆者が受講した時期(2024年6月〜7月)は講座の受講自体は無料、認定試験も受験だけであれば無料でした。但し、正式な認定証を発行して貰う場合は、手数料として9,800円(これが実質受験料)必要となります。認定講座は非常に分かりやすく面白かったのと、折角認定に合格したので、筆者は手数料を支払い認定証を発行して貰うことにしました。但し、今後は受講料、受験料共に有料化？される様です。

## 教材
講座の各回の教材はGitHub上で公開されています。Google Colaboratoryで作成されており、解説＋実行コードがセットになっています。

https://github.com/tytansdk/tytan_tutorial#%E7%AC%AC3%E4%B8%96%E4%BB%A3%E5%9F%BA%E7%A4%8E%E3%82%B3%E3%83%BC%E3%82%B9%E3%81%A8%E8%AA%8D%E5%AE%9A%E8%A9%A6%E9%A8%93%E5%95%8F%E9%A1%8C

## 認定試験問題
筆者が受講した頃の認定試験問題はGitHubで公開されていました。講座を受講していなくても認定試験に合格すれば認定される方式でした。試験問題の形式としては選択問題が1問、コード実装問題が2問の計3問の試験でした。

:warning: この試験問題での受験は受付を締め切られている様です。

https://github.com/tytansdk/tytan_tutorial#%E9%87%8F%E5%AD%90%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%82%A2%E3%83%8B%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0%E5%BC%8F%E8%AA%8D%E5%AE%9A%E8%A9%A6%E9%A8%93%E5%95%8F%E9%A1%8C

# 試験受験後
試験問題解答後採点担当者の方にメールで回答したNotebookファイルをメールで送信します。(Google ColabのNotebookをIPython Notebook形式でダウンロードする方法は以下の参考ページを参照して下さい。)送信後、数日で採点結果が送られて来ます。筆者の場合、コード実装問題は全問正解、選択問題で凡ミスをしてしまい、再提出になりましたが、無事再提出後合格になりました。参考までに以下の様な採点結果とフィードバックがメールで送られてきました。どうやら全問正解で合格の認定試験だった様です。

採点結果のコメント

>▼問題A：要修正
順に◯◯✕◯◯です！
ひっかけ問題のようで申し訳ありません…！
>
>▼問題B-1：正解☆
適切な解が出ております！
チェック用の関数も用意していただいて素晴らしいです！
>
>▼問題B-2：正解☆
コストの言い換えも含め、適切に設定されています！
特に重みの見積もりが素晴らしいです！

修正後合格の連絡が来たときのコメント

>修正をありがとうございます。
問題Aも正解となりましたので、合格おめでとうございます！！

* 参考

https://research.google.com/colaboratory/faq.html?hl=ja#:~:text=%E3%82%88%E3%81%84%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F-,link,-%E4%BD%9C%E6%88%90%E3%81%97%E3%81%9F%20Colab

# まとめ
量子アニーリング認定(エントリー)の認定に合格したので記事を投稿してみました。実際は6月下旬〜7月中旬に講座を受講していましたが、認定問題の解答になかなか着手出来ず、お盆休みを利用して解答し、解答結果を送ったため、ひょっとするとこの形式の問題における最後の認定者だった可能性が有ります。。。 :scream: (筆者が合格後解答した試験問題の提出受付が終了していたため)実は量子アニーリング(アドバンス)にも合格しているので、後日改めてまとめ記事を投稿したいと思います。

# 関連記事

https://qiita.com/y-vectorfield/items/697fdd269ed9c18415c3

https://qiita.com/y-vectorfield/items/25b2ac76dbf3a0f6e923

https://qiita.com/y-vectorfield/items/bf50b135cd07b238e28a

https://qiita.com/y-vectorfield/items/7314fc4623c86356f16b

https://qiita.com/y-vectorfield/items/be4183cc458932b8ff56
【git initとは？｜初心者向け】Gitでプロジェクトのバージョン管理を行ってみよう！

## この記事でわかること
git initの基本的な使い方

## 主な想定読者
- Git初心者の方
- プロジェクトのバージョン管理をGitで行う予定の方

## git initとは
- git init は、Gitを使い始めるための最初のコマンド
- このコマンドを実行により、ディレクトリがGitによってバージョン管理されるように

## 主に使うタイミング
- 新規プロジェクトのために、新規ディレクトリを作成した時
- 既存プロジェクト用に存在する既存ディレクトリを、Gitでバージョン管理したくなった時

## 基本的な使い方
### 1. Gitで管理したいディレクトリへ移動
- コマンドライン（ターミナルやコマンドプロンプト）を使って、バージョン管理をGitで行いたいディレクトリへ移動

``` :ターミナル
cd path/to/your/project
```
※ `path/to/your/project` の部分には、管理したいプロジェクトのディレクトリのパスをご入力ください。

### 2. git initコマンドを実行
- 下記コマンドの実行により、ディレクトリ内に「.git」という、Gitによるバージョン管理の情報が保存される隠しフォルダを生成
``` :ターミナル
git init
```

### 3. 初回のステージング＆コミット
- `git init` 実行後は、該当フォルダのファイルをバージョン管理に追加し、最初のコミットを実行すればOK
- 具体的には、下記の「ステージング」および「コミット」を行うことで、Gitの管理下にファイルを追加可能
- ステージング
    - 下記コマンドにより、バージョン管理に含めたいファイルを「ステージングエリア」へ追加
    - <ファイル名> の部分には追加したいファイルの名前を入力（全てのファイルを追加したい場合は、 `git add .` と入力、特にこだわりがなければ、`git add .`と入力すればOK）

``` :ターミナル
git add <ファイル名>
```
- コミット
   - 下記コマンドにより、ステージングに追加したファイルを「コミット」することで、ファイルの変更履歴を保存
   - `-m` の後には、どのような変更を行ったのか、その内容の説明を入力することが可能であり、この説明は変更履歴（コミット履歴）を確認する際に便利

``` :ターミナル
git commit -m "初回コミット"
```
- `git add` & `git commit`のまとめ
要するに、下記2つのコマンドの実行により、プロジェクト内の全てのファイルがステージングされた後、「初回コミット」として保存されることで、プロジェクトがGitの管理下に

``` :ターミナル
git add .
git commit -m "初回コミット"
```

## コマンド実行時のポイント
- 複数回の実行は不要
`git init` コマンドは、何度も同じディレクトリで実行する必要なく、1度実行すれば、そのディレクトリはGitによるバージョン管理下に入るのでOK
- 誤ったディレクトリで実行しないこと
誤ったディレクトリで`git init` コマンドを実行してしまうと、不要なディレクトリまでGit管理の対象になってしまったり、逆にGitで管理したいと考えていたディレクトリがGit管理の対象外となってしまったりするため、コマンド実行前に、適切なディレクトリであることを念のため確認すると◎

## おわりに
最後までお読み頂き、ありがとうございました！
この記事が少しでもお役に立てば幸いです。
AWSの利用料が発生したらメール通知する方法（簡易版）

## TL;DR
AWS Budgetsのテンプレートを使用して、簡単に費用発生（$0.01以上）したらメール通知が来る設定をします。

**対象者**

- AWSの無料枠で利用している人
- AWSを使わない期間に費用が発生してないか心配な人

## 予算作成

１.マネジメントコンソールの上部に検索バーから「budgets」と入力＆押下

![「budgets」の検索結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3403411/9cd591c0-da23-81bd-cd2a-ce9cbddc581a.png)

２.右上の「予算を作成」を押下
![Pasted Graphic 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3403411/993d2e60-ffc2-cd27-04a0-febc5316c378.png)

３.今回は予算の設定で「テンプレートを使用（シンプル）」を選択
![Pasted Graphic 5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3403411/de727ee0-f585-fee7-b9ae-938dc57ff0c1.png)

:::note
個別に設定した予算を作りたい場合は、「カスタマイズ」を利用してください。
:::

４.テンプレートから「ゼロ支出予算」を選択
![テンプレート・新規.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3403411/56a01e39-e334-a95d-c835-330463d40139.png)

５.任意の予算名を入力、通知先のメールアドレスを入力
（カンマ区切りで複数メールアドレス登録可能）
![Pasted Graphic 17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3403411/a0a9b8e7-6458-7287-674e-db008c3b32a3.png)
最後に、ページの右下にある「予算を作成」を押下すると、以下のように入力した予算名で作成される。
![Pasted Graphic 10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3403411/61dda74c-8165-b6d9-7dfa-6a7f0c62b6e5.png)

これで予算の作成は完了です！（2,3分あれば十分作成できると思います）

しっかり、アラートの閾値が「$0.01」で出来てますね。
![Pasted Graphic 19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3403411/d0eb911f-7eb7-5ec5-eb1b-1eaa425d99a6.png)

## おまけ
閾値を超えたら、三角アラート表示が出てきます
![Pasted Graphic 22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3403411/ff55637e-c806-07fc-9128-33b91567603e.png)

実際のメール通知は「AWS Budgets: 予算名 has exceeded your alert threshold」こんな感じの件名でawsから以下のようなメールが届きます。
![aws.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3403411/50d1c05a-6632-9502-548b-7a9648aef586.png)
※↑は予算を作成した時点で既にコストが発生していたので、かなり閾値オーバーしております（汗

ご参考になれば幸いです。

## 参考資料
[AWS Budgets によるコストの管理](https://docs.aws.amazon.com/ja_jp/cost-management/latest/userguide/budgets-managing-costs.html)
RustでOpenSSL関連の依存関係に困ったらrustls-tlsを使うことを検討すると良いかも

## 概要

`reqwest`など、OpenSSLに依存しているcrateを使用する際、OpenSSL起因でビルドが失敗するなら、`rustls-tls`を使うことで回避できるかもしれない。

```toml
# Cargo.toml
reqwest = { version = "0.12.7", default-features = false, features = [
    "rustls-tls",
] }
```


## 課題

RustでWeb開発をしていると、HTTPクライアントである`reqwest`クレートをしばしば使用する。
しかし、`reqwest`はOpenSSL(クレート名だと`openssl-sys`など)に依存しており、ローカル開発環境や、採用したい`Docker`イメージによっては、下記のようなエラーにより、ビルドやバイナリの実行に失敗してしまう。

```
error: failed to run custom build command for `openssl-sys v0.9.103`
```

```
error while loading shared libraries: libssl.so.3: cannot open shared obj
ect file: No such file or directory
```

## 解決策

`Cargo.toml`に下記の通り記載する。

```toml
# Cargo.toml
reqwest = { version = "0.12.7", default-features = false, features = [
    "rustls-tls",
] }
```

ポイントは2つ。

1. `default-features = false`: `reqwest`はデフォルトで`native-tls`(こいつは`openssl-sys`に依存)に依存しているようなので、明示的に`default-features`を無効にする。
1. `features`で`rustls-tls`を指定: `features`に指定するだけで、`native-tls`の代わりに`rustls-tls`に依存してくれる。`rustls-tls`は純粋なRust実装なので、共有ライブラリなどは不要。


## 経緯

解決策の方向性は2種類思いつく。

1. OpenSSLの依存関係を用意する
1. OpenSSLへの依存をやめる

本記事は主に**2.OpenSSLへの依存をやめる**方法について記述した。
1のアプローチも至って真っ当だが、筆者は苦しんだ果、2に行き着いた。

### 1の苦しみ
- 必要なライブラリがどれなのかわからない
  - `apt-get install libssl-dev`はまだしも、``
- 必要なライブラリを入れるためのツールがわからない
- 必要なライブラリを入れても、環境によってはOpenSSLのインストールに失敗する
- OpenSSLのインストールに成功しても、Dockerのマルチステージングビルドで、ビルドしたRustのバイナリ以外にどのバイナリが必要なのかわからない
  - `ldd`(Macなら`otool`)で共有ライブラリは調べられるけど、不足していることもある

### 2の応用

`Cargo.lock`を`grep`して、`openssl`に依存している`crate`があれば、`rustls-tls`に変更できないか、クレートの`features`を調べてみる。など。

筆者は実際に、`google-cloud-starge`というクレートを使っているときに、本エラーに遭遇した。
結局、`google-cloud-storage`が`reqwest`に依存していたので、`google-cloud-storage`の`features`を調べて、本記事の解決策と同様にして対応し解決した。

## 参考

https://qiita.com/nacika_ins/items/465e89a7b3fbeb373605

https://qiita.com/tomoikey/items/ec1817741a0ac9ffa32d

https://stackoverflow.com/questions/75820353/failed-to-run-custom-build-command-for-openssl-sys-v0-9-80
Hybrid Backup sync での 「You do not have permission to access this file. 」エラーの解決

エラー原因を調べたときに、ほとんど情報が無かったのでここにまとめておく。

## エラーの発生
QNAPのNASにて、Hybrid Backup sync（以下 HBS）を用いて Amazon S3 に作成したバケットにバックアップをしようとしたところ、下記エラーが出てバックアップできなかった。

```
警告	ハイブリッドバックアップ同期 [日時] [Hybrid Backup Sync]
 Backup job "[ジョブ名]": Failed to upload file/folder from "[バックアップしたいファイル]".
 You do not have permission to access this file. Check access permissions.
```

日本語では、
```
警告	[日時など]	Hybrid Backup Sync	Job Status	[Hybrid Backup Sync]
バックアップジョブ「[ジョブ名]」：「[バックアップしたいファイル]」からのファイル/フォルダーの
アップロードに失敗しました。このファイルにアクセスする権限がありません。
アクセス権限を確認してください。
```

## 現状
### NAS側
* 当該ファイルにはNASの **File Station でアクセスできる。** 
* 別のクラウドストレージには正常にバックアップできる。

### Amazon S3側
* バケット内のオブジェクトの暗号化には SSE-KMSを使用
* S3 にアクセスするための IAMユーザーを作成しており、そのIAMユーザーの **マネジメントコンソール経由では、作成したバケットにファイルをアップロードできる。**
* バケットには、**PCから WinSCP で、アクセスキーを用いてアクセスできる。**

## 解決方法
### HBS の「サーバー側の暗号化を使用する」を無効にする。

## 原因と詳細
原因は、S3 のバケットに設定した「バケットポリシー」
エラー発生時には、「SSE-KMSでの暗号化の強制」を実現するようなバケットポリシーを設定していた。
HBS の **「サーバー側の暗号化を使用する」を有効にすると、SSE-S3 での暗号化が明示的に指定される** ようで、バケットのデフォルト暗号化の設定を SSE-S3 以外に設定していても、SSE-S3 で暗号化されてしまった。

そのため、バケットポリシーで「SSE-KMSでの暗号化の強制」を設定していると、SSE-S3を用いて暗号化しようとする HBS を拒否してしまい、データをアップロードすることができなくなってしまっていた。
HBSの詳細ログにも、403エラーが発生したようなことが書かれていた。

よって、「サーバー側の暗号化を使用する」を無効にすると、明示的に暗号化の方式が指定されなくなり、バケットのデフォルト暗号化の設定に従って暗号化されるようになる。

**※ソースコードを見たわけではないので、あくまで参考までに。**

## さいごに
思い込みを排除して原因を切り分けたり、詳細ログをしっかり分析するようにしたい。
Azure Portalで起こった謎現象

Azure Portalを別タブで2枚同時に開いて作業をしていたら、予期せぬ設定が反映されることがありました。

# 起こった事象
Azure WAFで「防止モード」に切り替えましたが、いつの間にか「検出モード」に戻っていました。

原因を調査していったところ、Azure Portalを2枚開いて作業していたことが原因でした。

# 事象の再現

Azure PortalでWAF設定の概要画面を開きます。現在は「検出モード」です。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/a000d88f-1a09-c79b-2810-e8b5c019a1d5.png)

別タブでAzure Portalを開きます。除外設定を追加する設定画面を開きます。ここではまだ保存ボタンを押しません。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/19390588-de74-cc01-a469-fa6fc0a72896.png)

概要ページを開いているタブに戻り、「防止モード」に切り替えます。防止モードに切り替わったことを確認しました。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/db30478a-1ca9-3c6b-b380-bb883bf79e3c.png)

除外設定を開いているタブに戻り、設定を保存します。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/3d0e73c9-c807-9b71-4bac-dcc7a890a120.png)

再び概要ページのタブへ戻り、ページをリロードするとなんと「検出モード」に戻っています。
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/62fa240c-6d1a-6bab-eb4a-4c41f690d49b.png)

# 原因推測
おそらく以下のような内部動作をしていると推測されます。
* 除外設定のページにはポリシーモードの設定値は表示されていないが、設定画面を開いたタイミングでポリシーモードの値も一緒に取得されている
* 除外設定を保存すると取得したポリシーモードも一緒に保存されてしまう。結果、裏でポリシーモードを切り替えていたとしても、除外設定の画面の開いた時点の値で上書きされてしまう

PowerShellでGetやSetしたことがあればイメージつくかと思います。

# 結論
Azure Portalの別窓作業はやめましょう。

設定値を参照する、といったようなReadOnlyな作業であれば問題ありませんが、別々のタブで設定作業を並行で進めるとこのような予期せぬトラブルが起こる可能性はゼロではないので、避けた方が無難でしょう。

同じ理由で同一リソースを複数人で同時設定するのも危険ですね。
spring framework。webclient。postのリクエストの返却のbodyがjson形式ではなくてhtmlだった場合の入力チェックは可能？

Spring FrameworkのWebClientを使用してPOSTリクエストを送信し、返却されるレスポンスがJSON形式ではなくHTML形式だった場合、それを検出して処理することは可能です。WebClientを使用してレスポンスボディの内容をチェックし、適切な処理を行う方法を以下に説明します。

#### レスポンスボディの形式を確認する方法
HTTPヘッダーをチェックする: 通常、サーバーはレスポンスのContent-Typeヘッダーを指定します。application/jsonであればJSON形式、text/htmlであればHTML形式が期待されます。これを利用してレスポンス形式をチェックできます。

ボディの内容をチェックする: レスポンスボディ自体を読み込んで、JSONかHTMLかを判別することも可能です。

#### サンプルコード
以下のコードでは、WebClientを使ってPOSTリクエストを送信し、レスポンスのContent-Typeヘッダーをチェックした後、JSON形式かHTML形式かを判定しています。

```java
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.http.MediaType;
import reactor.core.publisher.Mono;

public class WebClientExample {

    public static void main(String[] args) {
        WebClient webClient = WebClient.create();

        webClient.post()
            .uri("https://example.com/api")
            .header("Content-Type", "application/json")
            .bodyValue("{\"key\":\"value\"}")
            .retrieve()
            .toEntity(String.class)
            .flatMap(response -> {
                MediaType contentType = response.getHeaders().getContentType();

                if (MediaType.APPLICATION_JSON.equals(contentType)) {
                    // JSONの場合の処理
                    System.out.println("Response is JSON: " + response.getBody());
                } else if (MediaType.TEXT_HTML.equals(contentType)) {
                    // HTMLの場合の処理
                    System.out.println("Response is HTML: " + response.getBody());
                } else {
                    // その他の形式の場合の処理
                    System.out.println("Unknown response type: " + response.getBody());
                }

                return Mono.empty();
            })
            .block();  // ブロッキングで結果を取得
    }
}
```

#### 説明
retrieve()を使ってリクエストを送信し、toEntity(String.class)でレスポンスボディを文字列として取得しています。
response.getHeaders().getContentType()でContent-Typeヘッダーを確認し、application/jsonかtext/htmlかを判別しています。
それに基づいて、適切な処理を行うことができます。
#### 注意点
サーバーが正しいContent-Typeを返さない場合があるため、ボディの内容を文字列として取得し、JSONの構造（例：{}で始まるかどうか）を確認することも可能です。
block()を使うと非同期処理を同期的に待つことができますが、非同期処理を維持したい場合はリアクティブストリームを活用できます。
これで、返却されるボディがJSONかHTMLかを検出して適切に処理することが可能です。
Anime: A Deep Dive into Japanese Animation

What is Anime?
Anime refers to a style of animation originating from Japan, characterized by vibrant art, unique storylines, and diverse characters. It has gained international popularity and spans a variety of genres such as action, romance, fantasy, and sci-fi. Anime appeals to all age groups and offers content ranging from light-hearted series to complex narratives.

How to Watch Anime
Step 1: Visit popular anime streaming platforms such as Crunchyroll, Funimation, or Netflix.
Step 2: Use the search feature to find your favorite anime or explore various categories like "Shonen," "Shojo," or "Isekai."
Step 3: Select an episode, adjust the video quality, and enjoy your show with subtitles or dubbed audio options.
How to Download Anime
Step 1: On legal streaming platforms, look for a download button next to the episode.
Step 2: Choose your preferred video quality and start the download.
Step 3: Watch the anime offline at your convenience.
Is Anime Safe for All Audiences?
Anime covers a broad range of genres, some suitable for children and others intended for mature audiences. Always check the rating or read about the show to determine if it's appropriate for the intended viewer.

Key Features of Anime:
Diverse Genres: Anime includes genres such as action, slice of life, mecha, fantasy, and more.
Unique Art Styles: Anime art is known for its detailed backgrounds, expressive characters, and iconic facial expressions.
Storytelling: Anime often delves into deep emotional and philosophical themes, offering complex narratives.
FAQs:
Q: What’s the difference between anime and cartoons?
A: Anime refers to Japanese animation and often explores deeper, more complex storylines, while cartoons typically focus on humor and are Western in origin.
Q: Where can I watch anime legally?
A: You can watch anime on legal streaming platforms like Crunchyroll, Funimation, and Netflix.
Q: Can I download anime to watch offline?
A: Yes, many platforms allow you to download episodes and watch them without an internet connection.
PythonでPCA実装

# この記事の目的
主成分分析（PCA）をPythonで実装してPCAがなにをやっているかを理解します。PCAの説明は他にも多数の解説記事があるので実装と関係ない部分の説明には踏み込みません。

# 主成分分析の理論
主成分分析では、データベクトル$\bf{x}$の分散が最大になる方向への線形変換を求める。
```math
\bf{x}_i=\it{(x_{i1},...,x_{id})}^T\  \rm{(i=1,...,N)}
```

$N$個のデータからなるデータ行列を$\mathbf{X}=(\bf{x}_1,...,\bf{x}_N)^T$から平均ベクトル$\bf{\overline{x}}=\it{(\overline{x}_1,...,\overline{x}_d)}$を引いたデータ行列を$\bf{\overline{X}}$とする。
```math
\bf{\overline{X}}=(x_1-\overline{x},...,x_N-\overline{x})^T \tag{1}
```

このデータ行列$\bf{\overline{X}}$の共分散行列$Var(\bf{\overline{X}})$の固有値$\lambda$が変換先成分の分散に対応し、固有ベクトル$\bf{a}_j$が変換ベクトルに対応する。
```math
Var(\bf{\overline{X}})\bf{a}_j = \lambda\bf{a}_j \tag{2}
```

理論はこれだけなので、以下Pythonで実装する。

# 実装
### 共分散行列計算
```Python
  # 共分散行列計算
  ## N :データ数
  ## d :Xの特徴量次元数
  ## X.shape = (N, d)
  ## Sigma :共分散行列
  ## Sigma.shape = (d, d)
  N = X.shape[0]
  X_ = X - X.mean(axis=0).reshape(1,-1)
  Sigma = 1/N * X_.T @ X_
```

### 固有値、固有ベクトル計算
```Python
lambdas, eigenvectors = np.linalg.eig(Sigma)
```

### 固有値の大きい順にソートする
```Python
idx = lambdas.argsort()[::-1]
lambdas, eigenvectors = lambdas[idx], eigenvectors[idx]
```

### 変換する
```Python
transformed = X_ @ eigenvectors
```

これだけ

## 関数全体
```Python
def pca(X, n_components=2):
  """
  Args)
    X (np.array):
      データ行列
  Returns)
    transformed
  """
  # 共分散行列計算
  N = X.shape[0]
  X_ = X - X.mean(axis=0).reshape(1,-1)
  Sigma = 1/N * X_.T @ X_

  # 共分散行列の固有値、固有ベクトル計算
  ## lambdas[i]の固有ベクトルはeigenvectors[:,i]に対応する
  lambdas, eigenvectors = np.linalg.eig(Sigma)

  # 固有値が大きい順でソート＝射影先の分散が大きい順でソート
  idx = lambdas.argsort()[::-1]
  lambdas, eigenvectors = lambdas[idx], eigenvectors[idx]

  # 変換
  transformed = X_ @ eigenvectors

  return transformed[:,:n_components
```

# 実行例
2000次元の遺伝子発現量を特徴量としてもつ細胞のデータ(細胞数3102)を2次元に圧縮してプロットすると下図のようになった。何日目にサンプルされたかで色を分けて表示すると、最初の3日間と20日以降で異なるクラスタを形成していることが確認できる。
![pca_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111915/e2ceb824-2e38-2bf4-3a31-c9dd859baad2.png)
SSHについて

## ■はじめに
普段からSSHを使用することがあるのですが、大変恥ずかしながらSSHというものをよく分かっていない状態でいままで使用しておりました。
これを機に、基礎的な内容となりますがSSHについてまとめてみました。

## ■SSHとは？
SSHは、Secure Shellの略称であり、あるコンピュータから他のコンピュータへと通信するためのプロトコルになります。SSHで通信する情報は暗号化されており、安全性が確保されていることが特徴です。

もともとは、Telnetなどの通信技術が使用されていたのですが、これらは通信内容が暗号化されていない状態（平文）となっておりました。容易に想像できると思われますが、このままだとパスワード等の重要な情報が盗聴されたりするという危険性があり、この問題点を解決するために作られたのがSSHとなります。

## ■認証方式について
SSHではいくつかの認証方式があるのですが、ここでは代表的な2例を紹介させていただきます。
### パスワード認証
こちらはユーザー名とパスワードを使用して認証する方式となります。
サーバー側に上記を登録するだけなのですが、パスワード自体が簡単に設定されてしまったり、パスワードの使い回しによる盗聴の危険性などがあり、セキュリティ的に脆弱性が懸念されるため、使用することはなるべく避けたほうがよいと考えられます。

### 公開鍵認証
こちらは、公開鍵と秘密鍵を使用して認証する方式となります。
大まかな流れは以下のとおりです。
~~1. クライアント側で公開鍵と秘密鍵を作成する（公開鍵と秘密鍵は2つで1つのユニークなものとなります）~~
~~1. 公開鍵を何らかの方法でサーバー側に渡して登録しておきます~~
~~1. クライアントはログインしたいという通信をサーバーに送ります~~
~~1. サーバーは認証するために、事前にクライアントから受け取った公開鍵を用いて暗号化したデータをクライアントに送信します~~
~~1. クライアントは、秘密鍵を用いて受け取った暗号データを復号し、サーバーに返送します~~
~~1. サーバーは複合されたデータが正しい内容であれば認証に成功したと判断します~~

(2024/09/30 @angel_p_57さんにご指摘いただき、修正しました）
こちらの[記事](https://qiita.com/angel_p_57/items/2e3f3f8661de32a0d432)を参考にさせていただきました
1. クライアント側で公開鍵と秘密鍵を作成する（公開鍵と秘密鍵は2つで1つのユニークなものとなります）
1. 公開鍵を何らかの方法でサーバー側に渡して登録しておきます（このときに公開鍵とセッションIDが共有される）
1. 認証時は、クライアントは秘密鍵を用いて署名を作成し、サーバーに送信します
1. サーバーでは、公開鍵の照合と署名の検証を行い、両方が問題なければ認証に成功したと判断します

## ■公開鍵と秘密鍵の作成
簡単にはなりますが、クライアント側での公開鍵と秘密鍵の作成手順についても紹介させていただきます。
### まずはディレクトリの作成
公開鍵と秘密鍵を保管しておくディレクトリを作成しましょう
```
$ mkdir ~/.ssh
$ cd ~/.ssh
```

### SSHキーの作成
以下のコマンドでSSHキーを作成してください。（オプションをつけることも可能です）
```
$ ssh-keygen
```
    
作成に成功すると、以下のように公開鍵と秘密鍵が確認できると思います。
```
$ ls
id_rsa  id_rsa.pub
```
- `id_rsa`: 秘密鍵
- `is_rsa.pub`: 公開鍵（pubはpublicの略）

### サーバー側に公開鍵を登録
サーバー側の`~/.ssh`配下にクライアント側で作成した公開鍵の中身を登録してください
※秘密鍵は流出しないようにクライアント側で大切に保管してください


## ■さいごに
いかがでしたか？
いつもなんとなく使用していたので、この機会に学習できたのはよかったです。
どなたかのお役に立てれば嬉しいです！
【SQL】よく使うSQL文

# 【SQL】よく使うSQL文(SELECT系)

よく使うSELECT系のSQL文を忘備録としてメモとして記載する。

* 基本の検索

```sql
SELECT 列名, ・・・
FROM 表名
WHERE 条件
;
```

* あいまいな検索

```sql
SELECT 列名, ・・・
FROM 表名
WHERE 列名
LIKE 'パターン'
;
```

* 並び替え

```sql
SELECT 列名, ・・・
FROM 表名
WHERE 条件
ORDER BY 列名
;
```

* 集計・グループ化

```sql
SELECT 列名, ・・・
FROM 表名
WHERE 条件
GROUP BY グループ化する列名
HAVING グループ行への条件
;
```

* 表の結合

```sql
SELECT 列名, ・・・
FROM 表名
LEFT JOIN テーブル名
ON 結合するテーブル・カラム条件
WHERE 条件
```
Docker環境構築に伴うnode_modulesの対応策

## 発生した問題

アプリの動作には問題ないが、エディタなどでエラーが起きるためホスト側に`node_modules`を読み込ませる(作成する)必要があるため、作成しようとしたら下記の問題に遭遇した。

- DockerでNext.jsの環境を構築する際に、`npm install`をすると作成される`node_modules`が空ディレクトリでホスト側に作成される

- (上記と同じため省略)`node_modules`がホスト側に作成されない

- バインドマウントや名前付きボリュームマウントだと、ホスト側(またはコンテナ側)で`node_modules`が上書きされてしまい正常に動作しない

## 問題の解決方法

- コンテナ起動時に`npm install`を実行

すなわち、Dockerfileの`CMD`やdocker-compose.ymlの`command`で`npm install`をすることで解決した。

ですがこの解決方法では、再現性やビルド時間を考慮してイメージビルド時、つまりイメージ内で依存関係のインストールを完了したいという要件では、上記の対応策は意味をなさないでしょう。

ですので私は、ローカル開発環境ではコンテナ起動時に、本番環境ではイメージビルド時に`npm install`するように対応しました。
PowerApps 動的なコンテンツを作る際に必須な、タイマーについて

PowerAppsで動的なコンテンツを作ろうと思ったら、タイマーが必須です。ほぼすべてのコントロールが、ユーザーの動作（OnSelectプロパティなど）による変化のみに留まるため、ユーザーの操作なしにコンテンツを動かすためには、タイマーコントロールによる制御が必要だからです。

たとえば、配置したオブジェクトを左から右に動かしたいと思っても、タイマーコントロールがなければ、ボタンを押した際にXの値を増加させるなどの方法により、ユーザーの操作に依存することなります。

そこでタイマーコントロールを使用し、OnTimerEndプロパティなどに処理を記入して、繰り返し実行することで、自動的に動いているように見せることができます。

たとえば、時計の表示についてもそうで、タイマーのTextプロパティに以下のように書いたとします。
```
Text(Now(),"hh:mm:ss")
```
一見問題なく見えますが、これをプレビュー表示すると表示した時間のままピクリとも動きません。
Textプロパティに書いただけでは現在の時間を更新してくれないからです。
この場合は、Textプロパティには以下のように変数を設定します。
```
Text(_Nowtime,"hh:mm:ss")
```
そして、タイマーのOnTimerEndプロパティもしくはOnTimerStartプロパティに
```
UpdateContext({_Nowtime:Now()})
```
と記入することで、タイマーが終わる(始まる)毎に、現在の時刻を取得してくれます。
タイマーの長さ(Duration)は、1000ミリ秒(1秒)にしておけば、毎秒更新してくれるので、時計としては十分機能を果たしてくれると思います。

また、初めに例としてあげた、オブジェクトを左から右に動かそうと思ったら
そのオブジェクトのXプロパティに変数を設定し
```
初期位置 + _move
```

タイマーのOnTimerEndプロパティもしくはOnTimerStartプロパティに
```
UpdateContext({_move: _move + 5});
```
と書くことで、オブジェクトの位置が右へと動いていきます。

応用次第で色んなことができるので、好きなコントロールの一つです。
useEffect のクリーンアップ関数はひとつ前の実行に作用する

# はじめに

JISOU の課題を進める上で useEffect の使い方がパッとしませんでした。しかも useEffect はいろんな媒体で議論が繰り広げるくらいややこしい概念だと感じました。この記事では公式ドキュメントを引用して理解を進めます。

# 当時わからなかったこと

ぼんやり眺めてるとドキュメントにこう書いてありました。

> 競合状態を修正するには、クリーンアップ関数を追加して古いレスポンスを無視する必要があります。

URL: https://ja.react.dev/learn/you-might-not-need-an-effect#initializing-the-application

いやいや、クリーンアップあるだけで古いレスポンスをどうやって消すんだと（もっとちゃんと書いてあると思いますが）

検証のための次のようなスクリプトを書いてみました。`title` が変わるたびに関数を実行します。

```react
useEffect(() => {
  let ignore = false

  async function startFetching() {
    var now = new Date();
    console.log(`triggerd at ${now}`);
    
    await sleep(5000)

    if (ignore) {
      console.log(`Ignored triggerd at ${now}`);
    } else {
      console.log(title)
    }
  }

  startFetching()

  return () => {
    ignore = true
  }
}, [title])
```

# 検証してわかったこと

`title` を入力すると関数を実行してクリーンアップ関数を戻り値としています。このクリーンアップ関数は新たに `title` に入力すると実行してくれます。

1. `title` に `b` と入力
    1. 関数を実行（ア）
        1. クリーンアップ関数を返す
1. `title` に `r` と**すぐさま**入力
    1. 前回の実行で返したクリーンアップを実行（ア）
`ignore` が false から true になる
`b` を入力して `r` を 5 秒以内に入力済であれば `ignore` が true になるため `title` を **（ア）で表示しない**
    1. 関数を実行（イ）
        1. クリーンアップ関数を返す
1. `title` に何も入力しない
    1. 5 秒後に `title` を **（イ）で表示する**
表示内容は `br` となる

:notebook: コンポーネントマウントで useEffect で指定した関数を実行するため、クリーンアップ関数は `b` を入力したときに実行するが簡単化のため省略しています。

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

気になる方はぜひHPからお願いします👇

https://projisou.jp
Rye環境でNuitkaを使う

めっちゃ単純だった…
これに数日ハマってしまった…

# Rye
Pythonの今一番ホットなパッケージ管理ツール。
Rust製のため高速

https://rye.astral.sh/

# Nuitka
Pythonの今一番ホットなビルドツール。
Pythonから.exeを作れる。従来のpyinstallerなどと違い、C言語ベースでビルドするので、スクリプトで実行するよりも動作が高速になる。

https://nuitka.net/

# 問題点
Ryeをインストール後に、その環境にNuitkaをインストールしたが、Nuitkaがうまく動かなかった。
おそらくRye経由だとNuitkaが「スクリプト」としてインストールされない？

```Powershell
PS C:\Users\xxx\dev> rye add Nuitka
PS C:\Users\xxx\dev> rye run nuitka --version
error: 指定されたファイルが見つかりません。 (os error 2)
```

呼び出しを以下のように、　`python -m ` 経由に切り替えると動作した
```PowerShell
PS C:\Users\xxx\dev> rye run python -m nuitka --version
2.4.8
Commercial: None
Python: 3.12.5 (main, Aug 14 2024, 04:23:18) [MSC v.1929 64 bit (AMD64)]
Flavor: Unknown
Executable: C:\Users\hattori\Desktop\dev\2409_JRWest_Camera\.venv\Scripts\python.exe
OS: Windows
Arch: x86_64
WindowsRelease: 11
Version C compiler: C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.41.34120\bin\Hostx64\x64\cl.exe (cl 14.3).
```
Tailwind CSSを使ってレスポンシブ対応してみる

## レスポンシブデザインとは？
**レスポンシブデザイン**とは、画面サイズが異なるデバイス（スマホ、タブレット、PCなど）でも、見やすくデザインを調整する手法です。
画面サイズによって文字の大きさやレイアウトが変わるようにすることで、ユーザーに最適な見た目を提供できます。

## Tailwind CSSのブレークポイント
TailwindCSSではデフォルトで「ブレークポイント」という基準が予め用意されています。
- `sm`（Small）：640px以上
- `md`（Medium）：768px以上
- `lg`（Large）：1024px以上
- `xl`（Extra Large）：1280px以上
- `2xl`（それ以上）：1536px以上
このようなブレークポイントを使って、デバイスの画面サイズに合わせたスタイルを簡単に指定できます。

::: note
tailwind.config.jsからデフォルトのブレークポイントの数値を変更することも出来るし、独自のブレークポイント追加することもできます
:::

## 使い方
**【テキスト編】**
適用したいクラスの前にブレークポイントをつけるだけでok

```
<div class="text-base md:text-lg lg:text-xl">
　これはレスポンシブテキストです
</div>
```
- `text-base` : 通常時は文字サイズを`base`に設定
- `md:text-lg` : 画面幅が`768px`以上（md)の場合、文字サイズを`lg`に変更
- `lg:text-xl` : 画面幅が`1024px`以上（lg）の場合、文字サイズを`xl`に変更

**【色編】**
```
<button class="bg-blue-500 text-white rounded sm:bg-green-500 md:bg-yellow-500 lg:bg-red-500">
　レスポンシブボタン
</button>
```
- `bg-blue-500` : 通常時はボタンの色を`青色`
- `sm:bg-green-500` :画面幅が`640px`以上（sm）ならボタンの色を`緑`に変更
- `md:bg-yellow-500` : 画面幅が`768px`以上（md）ならボタンの色を`黄色`に変更
- `lg:bg-red-500` : 画面幅が`1024px`以上（lg）ならボタンの色を`赤色`に変更

**【レイアウト編】**
`grid`クラスを使って簡単にレスポンシブなグリットレイアウトを作成する
```
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2">
　<div>アイテム1</div>
　<div>アイテム2</div>
　<div>アイテム3</div>
　<div>アイテム4</div>
</div>
```
- 通常時：1カラム
- `sm` : 2カラム
- `md` : 3カラム
- `lg` : 4カラム

【表示&非表示編】
特定の画面サイズでアイテムを表示 or 非表示で切り替える事もできます。

```
<div class="block sm:hidden">
　これは小さな画面で表示され、640px以上の画面では非表示になります
</div>
<div class="hidden sm:block">
　これは640px以上の画面で表示され、小さな画面では非表示になります
</div>
```

## おわりに
基本的な使い方を紹介しましたが、レスポンシブデザインは奥が深く、まだまだ色んな実装パターンがあるようです。
公式ドキュメントの情報が豊富なので是非読んで見てください。
[公式ドキュメント](https://tailwindcss.com/docs/responsive-design)
【Excel】自作マクロをリボンに追加してちょっぴり業務効率化

自作のマクロを作って、ショートカットに追加していたのですが、記憶力に難があり覚えられないので他の方法を探していたところ、アドインを作成しリボンに追加する方法があると知ったので共有です。
同じように、自分用に設定したはずなのに久しぶりに使いたいマクロのショートカットを思い出せないよ。という方がいましたら、是非参考にしてみてください。

自作のアドインを作成して、使いたいマクロ（プロシージャ）リボンに配置しておくという方法です。

# 準備（マクロ作成）
Excelを開き、VBEを立ちあげ、リボンに設定したい機能をまず実装します。
今回は、設計書関係でよく使う
全シートの拡大率を100%＆A1選択。先頭シートを開いた状態で保存するマクロをサンプルとしてリボンに登録します。
（前の現場では[「RelaxTools」](https://software.opensquare.net/relaxtools/)を利用させていただいてましたが使えない現場なので車輪の再発名です。。。）

標準モジュールに以下を追加。
privateとかpublicとか自分用なのでなーーーんにも考慮してないです。
```VBA
Sub SelectA1AndSetZoom()
  Dim ws As Worksheet

  For Each ws In ThisWorkbook.Worksheets
    ws.Activate
    ActiveWindow.Zoom = 100
    ws.Range("A1").Select
  Next ws

  ThisWorkbook.Worksheets(1).Activate
  ThisWorkbook.Save
End Sub
```

# アドインを登録
上で作成したモジュールを含んだExcelファイルを「Excelアドイン(.xlam)」として保存。このとき、保存するパスは意識しなく大丈夫です。
パス指定したとしても「C:\Users\[ユーザ名]\AppData\Roaming\Microsoft\AddIns\」に保存されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779836/81512609-a262-6e47-5838-8a465e108dca.png)

Excel上で
ファイル＞オプション＞アドイン
と遷移して適宜先ほど作成したアドインを選択して「OK」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779836/639c0c70-41c7-1813-7290-d740666828aa.png)


# リボンに登録

次に
ファイル＞オプション＞リボンのユーザ設定
と遷移。
リボンのユーザ設定にて新しいタブを作成。
自由に名前を決めてください。
コマンドの選択で「マクロ」を選択。
先ほど作成したマクロ（プロシージャ名）が表示されているので、作成したタブに追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779836/cb9a98f6-9612-d78e-452b-f86fbb939268.png)

すると画像のように追加されるので、あとは良い具合に増やしていってください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779836/9fe2a463-aa48-6a96-6fd5-84f81edac650.png)

これで、マクロ有効ブック以外でも自分用のマクロがショートカットを使わずに利用できるようになります。

以上！