OmniAICreator/Qiita-1.07M huggingface dataset:
Gitの「フェッチ」について

# Gitの「フェッチ」について詳しく解説

Gitを使っていると、「フェッチ (fetch)」という操作に出会うことがあります。しかし、フェッチとは具体的に何をするものなのか、どのように使うべきかを理解していない方も多いのではないでしょうか。本記事では、フェッチの意味とその使い方について詳しく解説します。

## フェッチとは？

**フェッチ (fetch)** とは、Gitでリモートリポジトリの情報をローカルリポジトリに取得する操作のことです。フェッチを行うと、リモートリポジトリのブランチやコミットがローカルリポジトリに更新されますが、ローカルの作業ブランチには変更が反映されません。つまり、フェッチはリモートの最新情報をローカルに取得するだけで、ローカルの作業内容を変更することはありません。

### フェッチの主な用途

1. **リモートの変更を確認**:
    フェッチを行うことで、リモートリポジトリの最新のコミットやブランチ情報を確認できます。
    
2. **リモートブランチの追跡**:
    フェッチはリモートブランチをローカルに反映するため、他の開発者がリモートリポジトリにプッシュした変更を知ることができます。

## フェッチとプルの違い

- **フェッチ (fetch)**:
  リモートリポジトリの変更をローカルに取得するだけで、ローカルの作業ブランチには影響を与えません。
  ```sh
  git fetch origin
  ```

- **プル (pull)**:
  フェッチを行った後、自動的にマージもしくはリベースを行い、ローカルの作業ブランチにリモートの変更を反映させます。つまり、フェッチとマージの操作を組み合わせたものです。
  ```sh
  git pull origin main
  ```

## フェッチの手順

1. **フェッチの実行**
    ```sh
    git fetch origin
    ```
   ここで`origin`はリモートリポジトリのデフォルトの名前です。

2. **取得したリモートの情報を確認**
    ```sh
    git branch -r
    ```
   これにより、リモートのブランチ情報を確認できます。

## フェッチ後の操作

フェッチした後にリモートの変更をローカルに反映させるためには、マージやリベースを行います。

- **マージを行う**:
    ```sh
    git merge origin/main
    ```

- **リベースを行う**:
    ```sh
    git rebase origin/main
    ```

## まとめ

フェッチはリモートリポジトリの最新情報を取得するための重要な操作です。これにより、リモートの変更を確認し、必要に応じてローカルのブランチに反映させることができます。フェッチとプルの違いを理解し、適切に使い分けることで、より効率的にリポジトリを管理しましょう。
cscの作法 その500

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
msbuildで、wpfをコンパイルせよ。

# 環境
windows11

# 手順
- プログラムを書く。
```

using System.Windows;
using System;

class Program {
	[STAThread]
	static void Main() {
		Application app = new Application();
		Window w = new Window();
		w.Title = "Hello World";
		app.Run(w);
	}
}


```
- プロジェクトを書く。

```

<Project DefaultTargets='Build' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
	<PropertyGroup>
		<Configuration>Debug</Configuration>
		<Platform>AnyCPU</Platform>
		<RootNamespace>Test</RootNamespace>
		<AssemblyName>Test</AssemblyName>
		<OutputPath>.\bin\Debug\</OutputPath>
	</PropertyGroup>
	<ItemGroup>
		<Reference Include='System' />
		<Reference Include='WindowsBase' />
		<Reference Include='PresentationCore' />
		<Reference Include='PresentationFramework' />

		<Reference Include="System.Xaml">
			<RequiredTargetFramework>4.0</RequiredTargetFramework>
		</Reference>

	</ItemGroup>
	<ItemGroup>
		<Compile Include='program.cs' />
	</ItemGroup>
	<Import Project='$(MSBuildBinPath)\Microsoft.CSharp.targets' />
	<Import Project='$(MSBuildBinPath)\Microsoft.WinFX.targets' />
</Project>


```

- コンパイルする。

```
>set PATH=C:\Windows\Microsoft.NET\Framework\v4.0.30319;%PATH%


>MSBuild Test.csproj


```

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/f1e68f5c-4d57-f0e2-5cec-0ddbf41ccd14.png)


以上。
pry-byebugを使ってRuby on Railsでのデバッグ

Ruby on Railsでアプリケーションを作成するうえで、必ずエラーに遭遇します。そのためエラーを解決する能力というものが、開発を行う上で必須の能力となります。

今回はこのエラーが発生した際に、どうすればエラーを解決できるかという方法についてご紹介します。最初はエラー画面が怖いものですが、エラー対応を身に着けることで飛躍的に成長できるので頑張りましょう！

## 「pry-byebug」の使い方

「pry-byebug」とは？については、下記リンクにて説明があります。気になる方は、こちらをご覧ください。それでは早速ですが、使い方について説明します。

[>> 「pry-byebug」とは？](https://taishi-official.com/2021/05/21/729/#toc1)

### 「pry-byebug」のインストール
Gemfileのgroup :developmentの最後に、以下の追記をすることで使用できます。

```ruby:Gemfile
group :development do

...

gem 'pry-byebug'
end
```

保存して、以下を実行してください。
```ruby
bundle install
```

pry-byebugは、デバッグしたい箇所で<strong>「binding.pry」「<% binding.pry %>」</strong>を記述することで処理を止めることができます。<strong>rbファイルではbinding.pry、erbファイルでは<% binding.pry %></strong>というように使い分けをします。コントローラーのrbファイルで使用するパターンとビューのerbファイルで使用するパターンの2パターンについて、例として今回紹介します。

### コントローラーでデバッグ

仮に以下のようなコントローラーがあったとします。createアクション内のpost変数に、どのような値が入っているのかを確認したいとき、以下のようにbinding.pryを記述します。コントローラはrbファイルですので、binding.pryを追加を追加することになります。

```ruby:posts_controller.rb
class PostsController < ApplicationController

...

def create
post = Post.new(post_params)
binding.pry
post.save
redirect_to post_path(post.id)
end

...

end
```

注意点として、確認したい箇所の下に追記をしてください。追記した箇所で、アプリケーションの処理を止めて状態確認することができます。記述したら保存して、ターミナルでrailsサーバを立ち上げてアプリケーションで実際にを投稿してみてください。

```
[1] pry(#<PostsController>)> post
=> #<Post:~ id: nil, title: "タイトル", body: "ボディ", created_at: nil, updated_at: nil>
[2] pry(#<PostsController>)> post_params
=> <ActionController::Parameters {"title"=>"タイトル", "body"=>"ボディ"} permitted: true>
[3] pry(#<PostsController>)> Post
=> Blog(id: integer, title: string, body: text, created_at: datetime, updated_at: datetime)
[4] pry(#<PostsController>)>
```

binding.pryを追加したところで、処理が止まります。この状態で、**変数・メソッド・モデルの内容を確認**できます。ここで上記のpost・post_params・Postのように入力することで、各パラメータが出力されます。

```
[4] pry(#<PostsController>)> exit
```

確認し終えたら最後に**exitと入力すると、デバッグから抜けてプログラムは再開**されます。

### ビューでデバッグ
ビューはerbファイルなので、以下のように<% binding.pry %>にする必要があります。

```ruby:index.html.erb
:

<% @posts.each do |post| %>
<% binding.pry %>

:
```

indexのビューをブラウザで開いて、ターミナルを見るとデバッグモードになっています。@postsやpostと入力すると、それぞれの受け渡されている値を確認することができます。

またpry-byebugのデバッグ中には、以下のようなコマンドが使えます。これらをうまく役立てて、開発を進めてみましょう。

- ステップインで先へ進める　：　stepまたは s
- ステップオーバーで先へ進める　：　nextまたは n
- 現在のスコープを抜ける　：　finishまたは f
- デバッグを終了して処理を再開する　：　continueまたは c

## まとめ
pry-byebugを使って、デバッグする方法についてまとめてみました。開発を進めるにあたって、必ずエラーは発生してしまいます。しかし今回の内容をうまく使うことで、エラー解消のヒントを探ることができるようになるかと思います。

### おまけ
https://qiita.com/taishi_will_be/items/70a8ce8938944286b487

https://taishi-official.com/learning-programming/

<strong>＼Follow me／</strong>

- X（旧Twitter）：https://x.com/taishi_it_blog
- Instagram：https://www.instagram.com/taishi_will_be/
- YouTube：https://www.youtube.com/@Engineer_ILLBE
- TikTok：https://www.tiktok.com/@taishi_will_be
- note：https://note.com/taishi_wii_be/

<br>

最後にいいねお願いします:thumbsup:
【メモ】github+python+macの場合の使い方をまとめる

なかなか覚えられないので、githubの使い方をまとめます。

まず、最初にやることはgit cloneですね。
```
git clone -b [ブランチ名] [https://リポジトリのアドレス] . 
```
最後にピリオドを入れておくと、現在のディレクトリにそのままコピーしてくれる。

さて、このフォルダにpythonの環境を作りたいと思います。
https://qiita.com/yabish/items/93c4e043e4c8dbc60cad

```
pyenv install --list　# 使えるpythonのリストを出す
pyenv install 3.12.1 # python3.12.1をインストールする
pyenv versions # インストールされているpythonの一覧を見る
pyenv global 3.12.1 # デフォルトバージョンを指定する
python --version # バージョンが切り替わっていることを確認する
pip install --upgrade pip　# pipをアップグレードしておく
python3 -m venv .venv # macでは.venvとしておくのが慣習らしく、そこにvenvのフォルダを作る
touch .venv/.gitignore # .venvディレクトリ配下は.gitignoreを入れておく
. .venv/bin/activate # 仮想環境をアクティベートする
pip install --upgrade pip　# pipをアップグレードしておく
pip install ldap3 jinja2 ulid-py pyyaml boto3 # これは一例だが使うモジュールをどんどんinstallする。venv内にインストールされるので、mac全体の環境はキレイなままです。
```

gitの操作

https://qiita.com/shungo_m/items/4bbcbcbd3d7aea40b21e

```
git branch -a # remoteのbranchを確認
git branch # localのbranchを確認
> * main #main branchを確認できる
git switch -c dev_docker_yaml
git branch # localのbranchを再度確認
>   main
> * dev_docker_yaml　 #branchが切り替わっていますね
git add *.yml # 変更したファイルを追加
git diff --cached --name-only --diff-filter=ACMR　# 追加されたものの一覧を見たい
git commit -m "環境によりdocker-compose.ymlの処理を振り分けられるようにしたい"
git push -u origin dev_docker_yaml # リモートにブランチを作る
git push # リモートにpushする
```
Rspec(deviseあり)でユーザ登録する際、Missing・・とかいうエラーが出た時

# はじめに
みなさん、こんにちは **torihazi**です

今回はタイトルのことをやっていきます。

# 現状
現在、Rspecにおいてリクエストスペックのテストを行っています。

deviseを使って認証を行っており、ユーザ登録のテストをする際、次のエラーが出ました。

```
    ActionView::Template::Error:
       Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
 ```

実際に使っていたコードは下記です。
deviseを使用して登録処理を行っているので、登録後認証メールが行く仕様になっています。

```
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe 'Users', type: :request do
  describe 'POST #create' do
    context "when the parameters is valid" do

      it "request successfully" do
        user_params = FactoryBot.attributes_for(:user)
        post user_registration_path, params: {user: user_params}
        expect(response.status).to eq 302
      end

    end
  end
end

```

# 結論
congit/environments/test.rbに次の記述をします。
```
Rails.application.configure do
~~~
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
~~~
end
```
{ host: ***}のところは正直 hogehoge@mail.comとかでも機能します。

先ほどのエラーは送り元がわかんないから認証メール送れないよ、という内容でした。

開発環境(development.rb)や本番環境(production.rb)は

設定していたのに テスト環境だからということで忘れていました。

# 終わりに
以上！

まだエラーが出ているのでその解決に入ります！
【Android】ViewAnimatorの高さを子要素に合わせて可変にする方法

# はじめに
Android Viewの機能であるViewAnimatorを久しぶりに触ったのですが、Viewを切り替える際に高さが最も高さの大きい子要素に依存する挙動となっており、可変にする為の方法を少し調べる形となったので、今後の備忘録的に調整方法を残しておこうと思います。

# ViewAnimatorの高さを可変にする方法
可変にする方法は非常にシンプルで、以下をXMLに追加するだけで実現可能です。

```main.xml
<ViewAnimator
   android:id="@+id/animator"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:measureAllChildren="false" >
```

measureAllChildrenは、ViewAnimatorのプロパティで、すべての子Viewを測定するかどうかを指定する設定になります。
デフォルトではtrueが設定されているので、非表示の子Viewも含め、すべての子Viewの高さを測定し最も高さのあるViewのサイズで固定となります。
見えていないViewの高さが欲しい場合などはデフォルトの設定でも良いと思いますが、切り替わり後の高さに違いがある場合などはUI的にスペースが空いてしまうなどのトラブルもあるかもしれません。
その場合はfalseで設定してあげる形が良いかと思います。

ご説明は以上になります。

# さいごに
もう6月ですね、また年をひとつ重ねてしまうのか、、、
RedmineにScrum Pluginを設定してプロジェクトを管理する方法①

WindowsマシンのWSL上のUbuntuにBitnami RedmineのDockerイメージをpullし、Scrum Pluginをインストールする手順を説明します。

## 1. 初期設定
1. **作業ディレクトリの作成**:
   - Ubuntuターミナルで以下のコマンドを実行して、作業ディレクトリを作成し、そこに移動します。
     ```bash
     mkdir -p ~/redmine
     cd ~/redmine
     ```

## 2. Bitnami Redmine Dockerイメージのpull
1. **Bitnami Redmineイメージのpull**:
   - 以下のコマンドを実行して、Bitnami RedmineのDockerイメージをpullします。
     ```bash
     docker pull bitnami/redmine
     ```

## 3. docker-composeファイルのダウンロード
1. **docker-composeファイルのダウンロード**:
   - 以下のコマンドを実行して、Bitnami Redmineの`docker-compose.yml`ファイルをダウンロードします。
     ```bash
     curl -sSL https://raw.githubusercontent.com/bitnami/containers/main/bitnami/redmine/docker-compose.yml > docker-compose.yml
     ```

2. **Redmineコンテナの起動**:
   - 以下のコマンドを実行してRedmineコンテナを起動します。
     ```bash
     docker-compose up -d
     ```

## 4. Redmineの動作確認
1. **Redmineの動作確認**:
   - ブラウザを開き、`http://localhost:3000` にアクセスしてRedmineが動作していることを確認します。
   - 初期ユーザー名とパスワードは[Dokerイメージ提供元](https://hub.docker.com/r/bitnami/redmine/)をご確認ください。

## 5. Scrum Pluginのインストール
1. **Scrum Pluginのダウンロード**:
   - Ubuntuターミナルで以下のコマンドを実行して、Scrum Pluginをダウンロードします。
     ```bash
     wget https://redmine.ociotec.com/attachments/download/564/scrum-v0.23.0.tar.gz
     ```

2. **Scrum Pluginの展開**:
   - ダウンロードしたtar.gzファイルを展開します。
     ```bash
     tar -xzvf scrum-v0.23.0.tar.gz
     ```

3. **Scrum Pluginのコンテナへのコピー**:
   - 以下のコマンドを実行して、展開したScrum Pluginをコンテナ内の`/opt/bitnami/redmine/plugins`ディレクトリにコピーします。
     ```bash
     docker cp scrum redmine-redmine-1:/opt/bitnami/redmine/plugins
     ```

4. **プラグインのインストール**:
   - Redmineコンテナに接続し、プラグインの依存関係をインストールし、データベースをマイグレーションします。
     ```bash
     docker exec -it redmine-redmine-1 /bin/bash
     cd /opt/bitnami/redmine
     bundle install --without development test
     bundle exec rake redmine:plugins:migrate RAILS_ENV=production
     exit
     ```

5. **Redmineの再起動**:
   - Redmineコンテナを再起動します。
     ```bash
     docker-compose restart redmine
     ```

## 6. Scrum Pluginの設定
1. **Redmineにログイン**:
   - ブラウザで `http://localhost:3000` にアクセスし、管理者アカウントでログインします。

2. **Scrum Pluginの有効化**:
   - 「管理」タブをクリックし、「プラグイン」セクションでScrum Pluginが有効になっていることを確認します。

以上で、Bitnami RedmineのDockerイメージをWSL上のUbuntuにpullし、Scrum Pluginをインストールする手順が完了です。これでScrumを使ったプロジェクト管理が可能になります。
検索時間を圧倒的に短縮させるショートカットキー

# はじめに
プログラミングやWEB制作を始めてみようと手を付ける人が増え、まずはProgate、ドットインストールなどを始めてみる人が多いと思います。

しかし、私みたいに今まで前職でパソコンを定期的に使う機会が無いとまず基本的なところをすっ飛ばしてしまいがちです。パソコンの基本的な使い方、タイピング、便利なショートカットキーの使い方など。コーディングや分からないことを検索するうえでこれらの効率が悪いと学習時間のロスにも繋がります。

その第一弾としてまずはマウスポチッ！ばかりが習慣になっているパソコン初心者やプログラミング初心者のために書いていきたいなと感じました。

## なぜマウスポチッ！ではいけないの？
マウスポチッ！は時間が掛かるからです。ショートカットキーを主に使うか、マウスを主に使うかは、言い換えればで車でAT(オートマチック)を使うか、MT(マニュアル)を使うか、みたいな違いです。

ATは基本的にD(ドライブ)を入れて後は走るだけです。普通に走っている分にはあまりギアを変えたりすることはあまりないでしょう。せいぜい坂道、止まる、バックするときだけです。それに比べてMTは都度クラッチを踏み、ギアを1速から、2速、3速、坂道の時は坂道発進など、はっきり言ってめんどくさいですよね？

ですが車本来の性能を活かすにはMTの方が優れています。F1のレーサーでもATの車やATしか乗れないレーサーがいないように、より車の性能をフルで活かすには、MTを使いこなす方がプロとして賢明です。

それと同じように普段マウスを使うことはもちろん業務に支障をきたしませんし、悪いことではありません。しかしよりプロのエンジニアとして検索や実装の時間を短縮し、作業効率を上げるには極力脱マウス生活を練習し、実践していくのが良いと考えています。


## chromeのショートカットキーについて

そんな私もマウスに頼りきりなので、自戒の念をこめていろんなショートカットキーを覚えながら、脱マウス生活を目指していきたいなと考えています。その始めとして,chromeのショートカットキーを紹介していきたいと思います。
なぜならchromeは検索に使われているケースが最も多いからです。


## 目的

* Chromeのショートカットキーを覚え、検索に掛かる時間を短縮して欲しい
※今回はwindowsショートカットキーで書いていきます


## chromeショートカットキー一覧

重要度
星★★★

### 次のタブへ移動する
 **「Ctrl」+ 「PgDn」もしくは　「Ctrl」+ 「Tab」**

### 前のタブへ移動する
 **「Ctrl」+ 「PgUp」もしくは　「Ctrl」+ 「Shift」+「Tab」**

 個人的には「PgUp」と「PgDn」を組み合わせたタブの移動の方が楽です

 ### 指定した番号のタブへ移動
 **「Ctrl」+ 「番号」**

 開いているタブの何番目かを指定することでそのタブへ一瞬で移動することが出来ます
 タブを開きすぎた場合はこっちの方が便利ですね
 ちなみに番号9で指定した場合はどれだけタブを開いていても問答無用で一番右端のタブへ移動します

 ### 前のページに戻る
 **「Alt」+ 「←」**

 ### 新しいタブを開く
 **「Ctrl」+ 「T」**

 ### 新しいウィンドウを開く
 **「Ctrl」+ 「N」**

 ### 表示しているタブを閉じる
 **「Ctrl」+ 「W」**

### 直前に閉じたタブを開く
 **「Ctrl」+ 「Shift」+「T」**

### ページ内のワードを検索する
 **「Ctrl」+ 「F」**

 ***
重要度
星★★

### 検索窓にフォーカスする
 **「Ctrl」+ 「K」**
 
 調べ物をしたいときに一瞬で検索窓に移ることが出来ます

 ### 現在のページをブックマークする
 **「Ctrl」+ 「D」**

 ### ダウンロード履歴を開く
 **「Ctrl」+ 「J」**

 ### 過去の閲覧履歴を開く
 **「Ctrl」+ 「H」**

 ## おわりに
 初めは慣れないので1つ1つメモやブックマークしながらの動作なので効率が悪いですが、都度使い続けることを心掛け、習慣化していくことで検索などで爆速の効果が得られると思います。
 引き続き便利なショートカットなどを紹介していこうと思います。

 他にもこれが便利だ！というのがあれば是非教えてください！
魚拓がなくても消された記事を読む方法


## 読者対象

面白い記事だったのに消された記事を読みたい人

## 前提

* 消されてから日にちがそこまで経過していないこと
* 記事のURLを知っていること

## 動作確認したブラウザ

Chrome

## 方法

ブラウザのアドレスバーに以下を入力して検索してください。
URLは各自置き換えるように。

```
cache:読みたいURL
```

### 例

```
cache:https://qiita.com/
```

## 助言

これはキャッシュなのでいずれ消えると思われます。
検索後のURLで[魚拓](https://megalodon.jp/)をとってあげれば永遠の思い出となります。

## 参考

https://developers.google.com/search/docs/monitor-debug/search-operators/web-search-cache?hl=ja
AZ-204 合格まで (2024.05)

[AZ-900 と MS-900 合格まで (2023.01) - Qiita](https://qiita.com/e99h2121/items/4ee69f047e555990065d)
[AZ-104 合格まで (2023.06) #AZ-104 - Qiita](https://qiita.com/e99h2121/items/de97a5e78b083739b5a1)
[AI-900 合格まで (2023.11) #AI-900 - Qiita](https://qiita.com/e99h2121/items/f32fcf4648bdf33a5ebd)
[AZ-305 合格まで (2023.12) #AZ-305 - Qiita](https://qiita.com/e99h2121/items/18ed097e6ecb66aafb3f)
[DP-900 合格まで (2024.02) #DP-900 - Qiita](https://qiita.com/e99h2121/items/51bf98981bffa218a712)

2024.05.31 AZ-204 を受けて合格したメモです。

## 感想
- 用語の耳馴染みのせいなのか理解のせいなのか、、脳内の整理整頓に苦慮して時間がかかった。
- でも「Developer」資格、実用性高めで嬉しい。


## 覚える

https://qiita.com/e99h2121/items/25ae757eaa884b8e35c1

https://qiita.com/e99h2121/items/a91c6594c21f5f938530



## MS Learn

https://learn.microsoft.com/ja-jp/training/courses/az-204t00

https://learn.microsoft.com/ja-jp/credentials/certifications/azure-developer/?practice-assessment-type=certification



## 参考

https://www.examtopics.com/exams/microsoft/az-204/

https://www.udemy.com/course/az204-azure-practice/

https://www.udemy.com/course/az-204-developing-solutions-for-microsoft-azure-fp/

https://qiita.com/yoshi-maru/items/80932a38aa005944c333


## 次ステップ

AZ-400 を取りたい。

以上です～
2024/6/1主にITとかセキュリティの記事

Check Point機器のVPN機能に脆弱性、攻撃から判明 - アップデートを
https://www.security-next.com/157686

Windowsの「BitLocker」を悪用するランサムウェア - ドライブ名に連絡先
https://www.security-next.com/157699

職員が患者カルテをインスタ投稿、個人情報が残存 - 仙台市立病院
https://www.security-next.com/157654

タリーズの通販サイトにサイバー攻撃 - 情報流出など影響を調査
https://www.security-next.com/157744

利用する労務管理クラウドで関連ファイルが流出 - イオングループ会社
https://www.security-next.com/157326

通販サイトに不正アクセス、個人情報流出の可能性 - JF全漁連
https://www.security-next.com/157200

今月4件目の「Chromium」ゼロデイ脆弱性を悪用リストに追加 - 米当局
https://www.security-next.com/157696

調味料通販サイトに不正アクセス - 個人情報流出の可能性
https://www.security-next.com/157639

macOS向け「Citrix Workspace App」に権限昇格の脆弱性
https://www.security-next.com/157734

サンスターの公式Xアカウントが乗っ取り被害 - 原因や情報流出は調査中
https://www.security-next.com/157726

テキスト生成AI利活用におけるリスクへの対策ガイドブック（α版）(5/30)
https://www.digital.go.jp/resources/generalitve-ai-guidebook

2023年度「内部不正防止対策・体制整備等に関する中小企業等の状況調査」報告書(5/30)
https://www.ipa.go.jp/security/reports/economics/ts-kanri/20240530.html

IPAテクニカルウォッチ「米国におけるAIのセキュリティ脅威・リスクの認知調査レポート」(5/30)
https://www.ipa.go.jp/security/reports/technicalwatch/20240530.html

2024年4月 マルウェアレポート(5/30)
https://eset-info.canon-its.jp/malware_info/malware_topics/detail/malware2404.html
ThinkPad Compact KeyboardでFnキーを押さずにホットキーを使う方法

## はじめに
ThinkPad Compact USB Keyboard with TrackPoint (KU-1255) は，トラックポイントを搭載したコンパクトな外付けキーボードです．デフォルトでは，上部のキーはファンクションキー（F1〜F12）として動作し，左下のFnキーと同時に押下することでホットキー（音量調整や画面の明るさ調整など）として動作します．

通常，Fnキーを押しながらEscキーを押すことで，ホットキーとして動作するかファンクションキーとして動作するかを切り替えることができるはずですが，私の環境ではこの方法が機能しませんでした．そこで，コマンドを使って切り替える方法を見つけましたので，その方法を紹介します．

## 動作環境
- **OS**: Ubuntu 22.04 LTS
- **キーボード**: ThinkPad Compact USB Keyboard with TrackPoint (KU-1255)

## FnLkを切り替える
ホットキーとF1〜F12のキーの動作を切り替えるためには，FnLk（ファンクションロック）を切り替える必要があります．FnLkとは，Fnキーの動作モードを切り替える機能です．FnLkが有効な場合，上部のキーはホットキーとして動作し，無効な場合はファンクションキーとして動作します．

### 現在のFnLkの状態を確認する
現在のFnLkの状態を確認するには，ターミナルで以下のコマンドを実行します：
```bash
cat /sys/bus/hid/devices/*17EF\:604*/fn_lock
```
このコマンドは，現在のFnLkの状態を表示します．出力が`0`なら有効，`1`なら無効です．

### FnLkを無効にする方法
FnLkを有効にするには，以下のコマンドを使用します：
```bash
echo 0 | sudo tee /sys/bus/hid/devices/*17EF\:604*/fn_lock
```
これにより，上部のキーがホットキーとして動作するようになります．

### FnLkを有効にする方法
FnLkを無効にするには，以下のコマンドを使用します：
```bash
echo 1 | sudo tee /sys/bus/hid/devices/*17EF\:604*/fn_lock
```
これにより，上部のキーがファンクションキーとして動作するようになります．

### FnLkの状態をトグルする方法
FnLkの状態をトグル（切り替え）するには，以下のスクリプトを使用します：
```bash
{ grep -q 1 /sys/bus/hid/devices/*17EF\:604*/fn_lock && echo 0 | sudo tee /sys/bus/hid/devices/*17EF\:604*/fn_lock || echo 1 | sudo tee /sys/bus/hid/devices/*17EF\:604*/fn_lock; }
```
このスクリプトを実行すると，現在の状態に応じてFnLkが有効または無効に切り替わります．

## おわりに
以上のコマンドを使用することで，ThinkPad Compact KeyboardのFnキーとホットキーの動作を簡単に切り替えることができます．自分の使用スタイルに合わせて設定を変更してみてください．

## 参考文献
https://github.com/lentinj/tp-compact-keyboard
UEFI起動順序の変更 <VMware Fusion>

## 環境
Mac OS Sonoma 14.5
VMware Fusion 13.5.2
Guest OS Ubuntu 20

# 状況
- ゲストOSを起動しようとするが、ISOを読み込んで起動しない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815458/ac1e9601-51a5-4356-9657-bf2bf56f2a7c.png)

# 起動順序の変更

- Enter Setup →Enter
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815458/0f362936-c6ac-8a79-ebe9-b67a1e44f063.png)


- configure boot options
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815458/c88c4fa6-6506-daa3-5c2c-4f3777caf5fd.png)


- change boot order
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815458/c6ad9078-0577-a504-c017-70a4322abb2c.png)


- Change the order →Enter
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815458/9f0c644e-6647-5315-3cba-e57587e36edb.png)


- 起動順序を変更するため、CDROMの上にある起動ディスクにカーソルをあて「-」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815458/38d35f88-999f-a97d-4c53-1d46d730a02f.png)


- Enter
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815458/742fe4db-56f5-9c6f-ab24-cc444824c7d1.png)


- 変更済
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815458/1fbf530e-5f00-976a-3397-e2b8bd5adadf.png)


- commit changes and exit
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815458/0d66c6c9-a9e4-77a0-c06f-2af217c3f86e.png)


- Exit the Boot Maintenance Manager
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815458/aa15c764-f7d7-90da-0495-a12356e168c2.png)


- RestartしてもCDROMが一番上にならない。。うーん。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/815458/833609b9-9ef9-5aea-44b6-aa5ef07606a7.png)
【Raspberry Pi】Raspberry Pi OSでdockerをセットアップする

# やりたいこと

* Raspberry Pi OSでdocker環境を構築する。
* root権限なしでdockerコマンドを叩けるようにする。

# 環境
* デバイス:RASPBERRY PI 5
* OS      :RASPBERRY PI OS(64-bit)
* ↓そのほか
```
user@raspberrypi:~ $ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

user@raspberrypi:~ $ uname -a
Linux raspberrypi 6.6.20+rpt-rpi-2712 #1 SMP PREEMPT Debian 1:6.6.20-1+rpt1 (2024-03-07) aarch64 GNU/Linux
```

# セットアップ
公式ドキュメントをもとにセットアップしてみます。
※2024/6/01時点の情報をもとに記載しています。

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

### 1.Dockerをinstall

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

$ echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```
実行後、試しにhell worldを叩いてみる
```
user@raspberrypi:~ $ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
478afc919002: Pull complete 
Digest: sha256:266b191e926f65542fa8daaec01a192c4d292bff79426f47300a046e1bc576fd
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (arm64v8)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
```
rootユーザーでdockerコマンドが叩けるようになりました。


### 2.root権限なしでdockerを使用できるようにする
```
$ sudo usermod -aG docker $USER
```
実行後OSを再起動するとsudoなしでdockerコマンドが叩けるようになります。

```
user@raspberrypi:~ $ docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
hello-world   latest    ee301c921b8a   13 months ago   9.14kB
```
Microsoft IME の変換候補だけ欲しい

# 概要
Microsoft IME の変換候補を自作アプリで取得することができます。
キオスク端末や IME が小さくて使いずらい場面で有効です。

# 環境
* Windows 11 Home
* .NET Framework 4.5
* 以前のバージョンの Microsoft IME を使用設定
:::note info
.NET Framework 4.8 と .NET Standard 2.0 でも動作を確認
:::

# テストコード
下記の NuGet をプロジェクトにインポートします。

https://www.nuget.org/packages/TSF.SearchCandidateProvider

:::note warn
ほとんど使用実績がないライブラリのようなので、信頼性は不明です。
自己責任でお願いします。
:::

あとは、下のコードのように実装すれば変換結果を取得できます。
コンソールアプリで書いているので、ほかで使うときは GetCandidates() メソッドだけ使えばいいです。
``` C#
using System;
using System.Threading.Tasks;
using TSF;

namespace TSF_Test
{
    internal class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("変換候補を取得したい文字列を入力してください");
                var input = Console.ReadLine();

                var candidates = GetCandidates(input);

                Console.WriteLine();
                Console.WriteLine("変換候補：");

                foreach (var item in candidates.Result)
                {
                    Console.WriteLine($"{item}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.ReadLine();
        }

        /// <summary>
        /// 変換候補を取得します
        /// </summary>
        /// <param name="value"> 変換候補を取得したい文字列 </param>
        /// <returns> 変換候補一覧 </returns>
        private static async Task<string[]> GetCandidates(string value)
        {
            using (var provider = await SearchCandidateProvider.FromCurrentProfile())
            {
                // 以前のバージョンの Microsoft IME を使用しないと null が返る
                if (provider == null)
                {
                    throw new Exception("変換候補プロバイダが見つかりません");
                }

                var candidates = await provider.GetSearchCandidates(value);

                return candidates.Candidates;
            }
        }
    }
}
```

## 実行結果のスクリーンショット
![スクリーンショット 2024-06-01 013206.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619311/a77224ea-af7a-1fdc-e96e-8b9e2ef29b2d.png)

ちゃんと変換結果が取得できていますね。
そのまま返ってくるものや予測変換も混ざっているので、用途によってはフィルターをかけてもいいかもしれません。

# 小話
日本語変換についての分かりやすい情報がさっぱり無かったので書きました。
ここまで情報を探るのに Mozc などに寄り道して３日もかかってしまいました。
いつかこの情報が誰かの役に立つことを祈ります。

最後に、ライブラリ作成者の NyaRuRuさん に感謝を。
iビット目のビット値(1/0)を取得したい

ド忘れしがちなので、自分用のメモに残しておきます。

nのiビット目のビット値(1/0)を取得する方法は以下の通りです。

```rust
let bit = (n >> i) & 1;
```

あるいは以下のように書くことも可能です。

```rust
let bit = if n & (1 << i) == 0 { 0 } else { 1 };
```
【GCP】個人開発のアプリでGoogleMapApi使ってたら2日で3万円近くかかった話

## この記事は何？
タイトルの通り。
だから気をつけようね、っていう自戒を込めつつ、同じような思いをする人が少しでも減りますようにと祈りも込めて。
とりあえず、起こったことと対応したことを時系列に沿って記述していこうと思います。

<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/fa13e94a-9e80-1822-4228-32161eef7d3f.png">
<img width=500 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/403c837e-77b7-208f-6d3e-286ac94ee57f.png">


## 時系列に沿って

### 2022/02/08
東海オンエアのYoutube動画に映っている聖地をみんなで登録・共有できるアプリをリリースしました。

https://qiita.com/ninoko1995/items/d984c96ff2260374a985

こちらのアプリでは、以下のような機能を実装しています。

- マップ上にスポット表示
- スポット詳細ページでスポットの詳細を表示
- スポット一覧ページで一覧を見られる

### 2022/03/15
YoutubeAPIを用いて、Youtube動画一覧ページを追加

### 2022/03/17
デザインの大幅な修正を実施。
UIに重きを置いてスポット一覧ページに各スポットの画像を掲載するようにした。

### 2022/03/22
東海オンエアファンの方に見つけていただき、拡散される。

### 2022/03/23~24早朝
ユーザ数の増加に伴いPlaceAPIの呼び出し数爆増、利用料金爆増。
仕事終わりに対応し、深夜5時に修正リリースを審査に提出。

暫定対応として、GoogleMapApiの方でPlacesApiの利用を停止した。

## 原因
原因は大きく分けて二つある。
- その1: 地図上のスポットを表示する際、スポットの画像を毎回apiを叩いて取得して表示するようにしていた
- その2: ページングを適切に行なっておらず、全てのスポット情報を一度にレンダリングしていた

上記両方が揃った結果、毎画面描画のたびに全てのスポットに対してその画像を取得する処理が走ってしまっていた。

## 対応
### 1への対応
PlaceApiの取得回数を減らすために、スポットの画像はスポット作成時に取得して、保存しておくことにした。
画面描画時には、自分のサーバのapiを叩くだけで済むので、placeApiへのリクエストはスポット登録時だけですむ。

### 2への対応
1への対応をすれば十分ではあるが、スポット数が多くなるに従って描画処理が重くなってきたので、適切なページング処理を入れた。
具体的には、リスト表示の際には20件を取得しておくようにし、リスト下端に到達したら次の20件を取得する、とした。


## 教訓

想定リクエスト数や利用金額の概算などは大事です。
まぁ、適切な設計がなされていれば気にしなくてもいい部分ではあるかもしれませんが。
useCallback/useMemo/React.memoをどこで使うか、イメージで頭に叩き込む

## はじめに
できるだけ文章量を減らして見た目とイメージで。

## 全体のイメージ
下記使用パターンの1と2はできるだけやった方が良く、3は状況に応じて。

「必要に応じて」はなぜかというと、[こちらの記事](https://kentcdodds.com/blog/usememo-and-usecallback)にあるように
> MOST OF THE TIME YOU SHOULD NOT BOTHER OPTIMIZING UNNECESSARY RERENDERS.

必要のない再レンダリングは特に大きな影響を及さなければ過度に気にする必要がないためです。

## 1. useEffect内でpropsで渡ってくる関数を呼ぶ際
`useCallback`と`useMemo`を使い、useEffect内の関数が何度も呼ばれるのを防ぐ。

```jsx
const Parent = () => {
  // useCallbackを使わないとParentがレンダリングする度に
  // aが新しく作られ、ChildのuseEffect内のfooも毎回実行されてしまう
  const a = useCallback(() => {}, []); // 何かしらの関数
  // 関数にはcallback、配列とオブジェクトにはuseMemoを使う
  // （useMemoを使わないとレンダリング毎に参照が変わるため）
  const b = useMemo(() => [1, 2, 3], []); // 何かしらの配列
  return <Child a={a} b={b} />;
};

const ChildComponent = ({ a, b }) => {
  useEffect(() => {
    const options = { a, b };
    foo(options);
  }, [a, b]);
  return <div>Child</div>;
};

// 実はこれでは足りず、useCallback/useMemoを使っていても
// まだ再レンダリングが走る。React.memoで包む必要がある
const Child = memo(ChildComponent);
```

## 2. カスタムフックが関数や配列、オブジェクトを返す際
利用箇所ごとに必要に応じて`useCallback`や`useMemo`を追加することを避けるため、カスタムフックには組み込んでおく（組み込んでおくことによるオーバーヘッドは大きくないため）
```jsx
export const useSomeCustomHook = () => {
  const a = useCallback(() => {}, []); // 何かしらの関数
  const b = useMemo(() => [1, 2, 3], []); // 何かしらの配列
  return { a, b }
};
```

## 3. 重い処理の関数を実行する際
`useMemo`の出番。ただしこちらも必要な時だけ使うようにする（場合によってはメモリーを大きく消費することがあるため）

```jsx
const SomeComponent = ({ a, b }) => {
  const result = useMemo(() => someHeavyProcess(a, b), [a, b]);
  return <div>{result}</div>;
};
```

## さいごに
いつもこの辺り頭で整理している気がするのでまとめました。しばらくreactを使わない期間などあったりしてもすぐに理解が取り戻せるよう、できるだけ文章少なめにしています。
「月月火水木金金」の16ビット漢字フォントを作って遊ぶ。(土日もあるよ)




目的
日めくりカレンダー用のフォントを作る
今は、著作権とうでいろいろうるさいのでオリジナルで作る

●　データを作る

![o_coq152.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/404b478a-efe8-9d0c-2ba7-4ef7ad5be1de.jpeg)


●　変換

![o_coq153.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/cea0c792-ef56-66fb-6508-cb9a65671a86.jpeg)


月火水木金土日

```

// 'u月火水木金土日1', 16x112px
const unsigned char epd_bitmap_u_______1 [] PROGMEM = {
	0xf7, 0xff, 0xf0, 0x07, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf0, 0x07, 0xf7, 0xf7, 0xf7, 0xf7, 
	0xf7, 0xf7, 0xf0, 0x07, 0xf7, 0xf7, 0xef, 0xf7, 0xdf, 0xf7, 0xdf, 0xc7, 0xbf, 0xe7, 0xff, 0xff, 
	0xfe, 0xff, 0xfe, 0xff, 0xee, 0xf7, 0xee, 0xef, 0xee, 0xdf, 0xee, 0xbf, 0xee, 0xff, 0xfe, 0xff, 
	0xfe, 0xff, 0xfe, 0xff, 0xfd, 0x7f, 0xfb, 0xbf, 0xe7, 0xdf, 0xdf, 0xef, 0xbf, 0xe7, 0xff, 0xff, 
	0xff, 0xff, 0xfe, 0xff, 0xfe, 0xf7, 0xfe, 0xcf, 0xc0, 0xbf, 0xfc, 0x7f, 0xfc, 0x7f, 0xfa, 0x7f, 
	0xf6, 0xbf, 0xf6, 0xdf, 0xee, 0xdf, 0xee, 0xef, 0xda, 0xef, 0xfc, 0xf7, 0xfe, 0xff, 0xff, 0xff, 
	0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xc0, 0x07, 0xfc, 0x7f, 0xfc, 0x7f, 0xfa, 0xbf, 
	0xfa, 0xbf, 0xf6, 0xdf, 0xf6, 0xdf, 0xee, 0xef, 0xee, 0xef, 0xde, 0xf7, 0xfe, 0xff, 0xff, 0xff, 
	0xfe, 0x3f, 0xfd, 0xbf, 0xfb, 0xdf, 0xe7, 0xef, 0x9f, 0xf3, 0xf0, 0x1f, 0xfe, 0xff, 0xfe, 0xff, 
	0xfe, 0xff, 0xe0, 0x0f, 0xfe, 0xff, 0xfe, 0xef, 0xf6, 0xdf, 0xfa, 0xbf, 0xc0, 0x07, 0xff, 0xff, 
	0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xe0, 0x0f, 
	0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x80, 0x03, 0xff, 0xff, 
	0xff, 0xff, 0xc0, 0x07, 0xdf, 0xf7, 0xdf, 0xf7, 0xdf, 0xf7, 0xdf, 0xf7, 0xdf, 0xf7, 0xc0, 0x07, 
	0xdf, 0xf7, 0xdf, 0xf7, 0xdf, 0xf7, 0xdf, 0xf7, 0xdf, 0xf7, 0xdf, 0xf7, 0xc0, 0x07, 0xff, 0xff
};

// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 240)
const int epd_bitmap_allArray_LEN = 1;
const unsigned char* epd_bitmap_allArray[1] = {
	epd_bitmap_u_______1
};

```

●　データを編集する


```


0xf7ff, 0xf007, 0xf7f7, 0xf7f7, 0xf7f7, 0xf007, 0xf7f7, 0xf7f7, //月
0xf7f7, 0xf007, 0xf7f7, 0xeff7, 0xdff7, 0xdfc7, 0xbfe7, 0xffff, 
0xfeff, 0xfeff, 0xeef7, 0xeeef, 0xeedf, 0xeebf, 0xeeff, 0xfeff, //火
0xfeff, 0xfeff, 0xfd7f, 0xfbbf, 0xe7df, 0xdfef, 0xbfe7, 0xffff, 
0xffff, 0xfeff, 0xfef7, 0xfecf, 0xc0bf, 0xfc7f, 0xfc7f, 0xfa7f, //水
0xf6bf, 0xf6df, 0xeedf, 0xeeef, 0xdaef, 0xfcf7, 0xfeff, 0xffff, 
0xffff, 0xfeff, 0xfeff, 0xfeff, 0xc007, 0xfc7f, 0xfc7f, 0xfabf, //木
0xfabf, 0xf6df, 0xf6df, 0xeeef, 0xeeef, 0xdef7, 0xfeff, 0xffff, 
0xfe3f, 0xfdbf, 0xfbdf, 0xe7ef, 0x9ff3, 0xf01f, 0xfeff, 0xfeff, //金
0xfeff, 0xe00f, 0xfeff, 0xfeef, 0xf6df, 0xfabf, 0xc007, 0xffff, 
0xffff, 0xffff, 0xfeff, 0xfeff, 0xfeff, 0xfeff, 0xfeff, 0xe00f, //土
0xfeff, 0xfeff, 0xfeff, 0xfeff, 0xfeff, 0xfeff, 0x8003, 0xffff, 
0xffff, 0xc007, 0xdff7, 0xdff7, 0xdff7, 0xdff7, 0xdff7, 0xc007, //日
0xdff7, 0xdff7, 0xdff7, 0xdff7, 0xdff7, 0xdff7, 0xc007, 0xffff


```
【論文メモ】Extracting Low-/High- Frequency Knowledge from Graph Neural Networks and Injecting It into MLPs： An Effective GNN-to-MLP Distillation Framework

https://arxiv.org/abs/2305.10758

# この論文を読んだ理由
GNN-to-MLPの知識蒸留(KD)手法をサーベイしている際に見つけた論文．
GLNN(Graph-Less Neural Network)を発展させた手法であるから．

# 解いている課題
- タスク：ノード分類

- 既存のGNN-to-MLPでの知識蒸留で，蒸留される知識と蒸留されない知識を分析
  $\rightarrow$**低周波情報は蒸留されやすく，高周波情報は蒸留されにくいことを発見**
  
  以下，自分の理解
  **低周波情報：グラフ全体で変化する情報$\rightarrow$ GNNの出力（全体）という情報**
  **高周波情報：グラフの局所的な部分で変化する情報$\rightarrow$ 局所構造の情報（隣接ノード同士で特徴量がどれくらい変わるか**
  
  GLNNでは，MLPの出力をGNNの出力に似せていたので，これは低周波情報を使っていることになる．
  $\rightarrow$この論文では，高周波成分も蒸留させて精度を高める


# 提案手法のアプローチ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583007/1be42df8-0dba-ba8a-e4de-4770f6e4f1cb.png)

- GLNNで用いられていない高周波情報（隣接ノード間の相対的な情報）を使う

- 損失関数
  - **低周波情報のロス**，$z$はMLPの出力，$h$はMLPの出力，$\tau_1$は温度パラメータ
    $$
    L_{\text{LFD}} = \frac{1}{|\mathcal{E}|} \sum_{i \in \mathcal{V}} \sum_{j \in \mathcal{N}i, u_i} D_{\text{KL}}\left( \sigma \left( \frac{z_j^{(L)}}{\tau_1} \right), \sigma \left( \frac{h_i^{(L)}}{\tau_1} \right) \right)
    $$
    $\rightarrow$これはGLNNと同様に，GNNの出力に似せることを目的としている
    <br>
  - **高周波情報のロス**，$\tau_2$は温度パラメータ，$N_i$は隣接ノード集合
    ```math
    \mathcal{K}(s_i, s_j) = |s_i - s_j|
    ```
    ```math
    L_{\text{HFD}} = \frac{1}{|\mathcal{E}|} \sum_{i \in \mathcal{V}} \sum_{j \in \mathcal{N}i} D_{\text{KL}}\left( \sigma \left( \mathcal{K} (z_j^{(L)}, z_j^{(L)})/\tau_2 \right), \sigma \left( \mathcal{K} (h_i^{(L)}, h_j^{(L)})/\tau_2 \right) \right)
    ```
    $\rightarrow$**GNNにおける隣接ノードとの特徴量の差を似せる，局所構造を捉えるためのロス**
    <br>
  - **全体のロス関数**，$\lambda$はバランスパラメータ
    ```math
    L_{\text{total}} = \frac{\lambda}{|\mathcal{V}_L|} \sum_{i \in \mathcal{V}_L} \mathcal{H} (y_i, \sigma (h_i^{(L)})) + (1 - \lambda) \left( L_{\text{LFD}} + L_{\text{HFD}} \right)
    ```
    $\rightarrow$クロスエントロピーロスと知識蒸留のロスを組み合わせる
    <br>

## 実験結果
- ノード分類でGCNやGLNNより高い精度を発揮
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583007/503c4e9c-e89e-a6c4-ea02-92bd71d78f86.png)
  <br>
- 高周波成分のロスによって，ノード間の相対距離も保たれている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583007/d58a5810-ce4c-b035-6ffc-bf375ab1f237.png)
エンジニアコミュニティ参加で楽しみながら広がる世界


現在参加させて頂いているLinuC Open Networkで以下のことを学ばせて頂きました。

### オープンコミュニティに参加させて頂くことで学んだ5点

①大海を知る
　オープンコミュニティにはエンジニアの方を始め、レベルが高く自発的な方が参加されています。そこに参加させて頂くことによって自分もそのレベルに追いつこうとするため、自然に自分も成長させて頂くことができたと感じました。
 
②視野を広げる
　社会人になると、同じような立場の方と接することがほとんどだと感じます。例えば私であれば学生さんやフリーランスの方とお話する機会はほとんどないのですがコミュニティには様々な職業、立場の方が参加されているため働き方や技術への考え方などに対して自分の今いる立場とは違う視点を知ることができます。
 
③コミュニケーション力
　①②の理由により、自分とは異なる立場の方とお話や一緒に活動させて頂くためコミュニケーション力が上がります。また、自分からこれに参加しますと能動的に立候補する必要があるため主体性も身に着けることができていると感じています。
 
④技術力
　コミュニティで自分の知らなかった技術を見聞きするので勉強する、あるいは興味を持つきっかけになります。①と似ていますが自分よりということはもちろん、社会的な水準で見てもレベルの高い方がいらっしゃるため学ぶことにまだまだ終わりはないと感じられ、モチベーションが上がるため結果技術的な知見やできることを増やすことができました。
 
⑤発信力
　このQiitaやOSC、技書博などのイベントに一緒に参加させて頂くことにより一人で勉強して終わりではなく、知ったことをアウトプットする習慣がつきその手段についても知ることができました。
 投稿やイベント参加は個人でも可能ですが、モチベーション向上や切磋琢磨にはグループが良いと思います。何より楽しく活動できます。

 これからもコミュニティ活動に積極的に参加させて頂き、また自分でもエンジニアリングや業務の成長につながる勉強会やイベントに参加していきたいと感じています。
『戦略的思考トレーニング』読書メモ

# 概要
- [『戦略的思考トレーニング　目標実現力が飛躍的にアップする37問』](https://www.amazon.co.jp/gp/product/4569850774)の読書メモ。
- Kindle版で読了。文章に色付けできたり、注釈をすぐ読めて便利。
- 尊敬している方がお薦めしてたので読んでみた。

# 戦略的思考とは？
目標を実現し、納得のいく結果を得るためのシナリオを思考すること。

## 戦略的思考と問題解決思考の違い
`考え始めること`、`シナリオ`が異なる。
- **戦略的思考**
    - 目標から考え始める。
    - 目標実現までのシナリオを思考する。
- **問題解決的思考**
    - 問題から考え始める。
    - 問題解決までのシナリオを思考する。
## 戦略と作戦、戦術の違い
- **戦略**
    - 目標実現に向けたシナリオ。
- **作戦**
    - シナリオの中に位置付けられる各プロジェクト。
- **戦術**
    - 各プロジェクトを成功に導く戦い方。

## 戦略的思考のコツ
- **目標をムーンショットで設定する**
    - 主体的に考える余白が生まれる。
    - 工夫や知恵、他者の協力必要な状況に自らを追い込める。
    - ムーンショット：50%以上達成できたら素晴らしい目標。
- **目標実現に強い想いを抱く**
    - 目標を実現することに強いこだわりを持つ。
    - 情熱を抱くきっかけは、縁を感じるとき。
    - 情熱を持てない時は、縁を辿る。
        ```
        例）
        「野球が好きで、ずっと関わっていきたい。」
        「あの時、先輩に教えてもらったことを今でも覚えている。」
        「初めてHello World!とブラウザに表示された時、ワクワクした。」
        ```
- **アウトサイド・インで考える**
    - 目標や結果から逆算する。
    - まずは、相手（競合）のことを知る。
    - マクロ環境分析(PEST分析) → 業界環境分析(5フォース分析) → 市場環境分析(3C(4C・5C)分析)
- **努力に依存した戦略を立てない**
    - 「戦わずして、勝つ」を実現する。
    - いかに現場に楽をさせるかを考え抜く。
- **周囲を巻き込む**
    - 羊飼いのリーダーシップ。
    - 戦略を立案する段階から周囲を巻き込む。
    - 戦略に反対する、3つの抵抗が生じることを把握して対策する。
      ```
      1.能力的側面からの抵抗
      必要なスキルや能力、技術を有していない不安から生じる抵抗。
      
      2.政治的・経済的側面からの抵抗
      自分(自社)の地位や立場に不利益が生じることからリスクを有していることで生じる抵抗。
      
      3.慣習的側面からの抵抗
      例) 「うちらしくない」、「これまでにやったことがない」、「受け継いだ伝統に反している」、など。 
      ```
BME680をRaspberry Pi 4で使ってみる

# 概要

温湿度気圧計BME680をRaspberry Pi 4で使用します。 ラズパイにあるデバイスツリー機能を使用します。適切に設定すると、温湿度気圧の値をテキストファイルとして取り出すことができます。

## 環境

- Raspberry Pi 4 Model B Rev 1.5

## BME680の設定

電子部品自体は、秋月電子がモジュールとして使いやすいようにしてくれているキットを使用しています。

- [BME680使用 温湿度・気圧・ガスセンサモジュールキット: 計測器・センサ・ロガー 秋月電子通商-電子部品・ネット通販](https://akizukidenshi.com/catalog/g/g114469/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139537/61a145ce-0f00-55ca-fd80-6511f4302156.png)

商品詳細ページの「マニュアル」より引用（[ae-bme680.pdf](https://akizukidenshi.com/goodsaffix/ae-bme680.pdf)）

- J2（画像赤枠右）にはんだ付けしジャンプ（短絡）させるかどうかでI2C接続のアドレス設定を0x77か0x78に変えることができます。
- ラズパイ側にプルアップ抵抗がついているため、J1（画像赤枠左）をジャンプ（短絡）する必要はありません。
  - これに関しては若干自身がありません。。。最初勝手がわからずJ1をジャンプさせて接続していたのですが、特に通信エラーにはならず動作しました。

## 接続方法

下記にラズパイとBME680の接続例を示します。あらかじめこのように接続しておきます。

|ラズパイ（PIN）|BME680|
|---|---|
|GPIO1（3V3 power）（Pin1）|VIN|
|GPIO3（Pin5）|SCL|
|GPIO2（Pin3）|SDA|
|Ground（Pin9）|GND|

## ラズパイ側の設定

自動的にマッピングする機能を使用します。`/boot/overlays/README`に詳細説明があります。

### I2Cの有効化

「Raspberry Pi Software Configuration Tool」を起動して設定を変更します。

```bash
sudo raspi-config
```

- 3 Interface Options > I4 I2C
- 「Would you like the ARM I2C interface to be enabled?」と聞かれるので`<Yes>`を選択

### 設定

下記設定を`/boot/firmware/config.txt`に追記します（最終行で良い）。J2をジャンプさせなかった場合（=0x77）は下記のようにします。

```ini
dtoverlay=i2c-sensor,bme680,addr=0x77
```

J2をジャンプさせた場合（=0x78）は下記のようにします（デフォルト設定で問題なし）。

```ini
dtoverlay=i2c-sensor,bme680
```

上記設定を済ませ、ラズパイを再起動します。

```bash
sudo reboot
```

### BME680の値を取得

BME680から温湿度気圧を取得します。ディレクトリの場所が、I2Cのアドレスによって異なるので注意します。

```bash
# addr=0x77 の場合
cd /sys/bus/i2c/devices/1-0077/iio:device0

# addr=0x78 （デフォルト）の場合
# cd /sys/bus/i2c/devices/1-0078/iio:device0

cat in_humidityrelative_input
# 相対湿度[%]
# 出力例 51.497000000

cat in_pressure_input
# 気圧[hPa]
# 出力例 1015.370000000

cat in_resistance_input
# 出力例 150765
# 抵抗値らしい、よくわかってない。他データと組み合わせて空気の清浄度を測ることができる？

cat in_temp_inputgggee
# 気温 [ミリ℃]
# 出力例 27820
# 単位はミリ℃で格納されているようなので、1000で割る（27820 -> 27.820℃）
```

## 精度と校正

実際に数日測定してみて、精度を確認しました。
手元にSwitch-botの温湿度計があり、BME680の隣において数値を比較しました。微妙に数値が異なっていました。BME680のほうが、湿度は+5%、温度は+1℃程度高く表示されているようです。気圧は気象庁のデータと照らし合わせてみたところ、ざっくりあってそう。今度はグラフにして可視化してみる予定です。
【VSCode】エラーをわかりやすく表示する

Error Lensという拡張機能をインストールするとエラーがわかりやすく表示されるようになります。

![demo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/4dc09834-82da-eec1-690b-346d97b62516.png)

https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens
Emacsの初期設定：どんなモニタでもフレームを最大表示する設定

# 課題：ノートPC本体、外部モニタでEmacsを使う際にきちんと最大フレームにならない！

Emacsを立ち上げた時に、フレームが画面いっぱいに広がってくれると嬉しいです。しかし、ノートPCで作業することも、外部モニタ（職場・自宅など複数の外部モニタあり）につないで作業することもあり、一つの環境に設定をあわせても他の環境では最適でなかったりしました。

# 解決策
フレームが最大にならない場合でも、タイトルバーをダブルクリックすると、良い感じにフレームが広がってくれます。きっとなにか良い設定方法があるのでは？とChatGPTさんと対話を繰り返して、良い方法が見つかりました。

この設定により、Emacsを起動するたびに手動でウィンドウを最大化する手間を省くことができます。

#### 1. Emacsの設定ファイルにコードを追加

まず、Emacsの設定ファイル（通常は `~/.emacs` または `~/.emacs.d/init.el`）に以下のコードを追加します。

```emacs-lisp
;; フレームをフルスクリーンモードで起動してから最大化する
(defun maximize-frame ()
  "Maximize the current frame."
  (interactive)
  (set-frame-parameter nil 'fullscreen 'maximized))

(add-hook 'window-setup-hook 'maximize-frame)
```

#### 2. コードの詳細な説明

このコードは、Emacsが起動する際にフレーム（ウィンドウ）を自動的に最大化するためのものです。各部分の機能について詳しく説明します。

2-1. **関数の定義**
   ```emacs-lisp
   (defun maximize-frame ()
     "Maximize the current frame."
     (interactive)
     (set-frame-parameter nil 'fullscreen 'maximized))
   ```
   `maximize-frame` という関数を定義しています。この関数は、現在のフレームを最大化するためのものです。`set-frame-parameter` 関数を使用して、フレームのパラメータを変更し、`fullscreen` を `maximized` に設定しています。これにより、フレームが全画面表示になります。

   - `set-frame-parameter` の引数：
     - `FRAME`: パラメータを設定するフレームを指定します。`nil` を指定すると、現在のフレームが対象になります。
     - `PARAMETER`: 設定するパラメータの名前を指定します。この場合は `fullscreen` です。
     - `VALUE`: パラメータに設定する値を指定します。この場合は `maximized` です。

   - `nil` の意味：
     ここでの `nil` は、現在のフレームを指します。つまり、以下のコードは「現在のフレームの `fullscreen` パラメータを `maximized` に設定する」という意味になります。

     ```emacs-lisp
     (set-frame-parameter nil 'fullscreen 'maximized)
     ```

   - `fullscreen` パラメータと `maximized` 値：
     - `fullscreen` パラメータは、フレームの全画面表示モードを制御します。
     - `maximized` 値は、フレームを最大化することを意味します。これにより、フレームが画面全体を占めるようになりますが、ウィンドウマネージャの装飾（タイトルバーやウィンドウ枠）は残ります。

2-2. **フックの追加**
   ```emacs-lisp
   (add-hook 'window-setup-hook 'maximize-frame)
   ```
   `window-setup-hook` に `maximize-frame` 関数を追加しています。これにより、Emacsが起動してウィンドウが設定された後に `maximize-frame` 関数が実行され、フレームが最大化されます。

#### 3. コードの実行方法

Emacsを再起動するか、設定ファイルを再読み込みすることで、この設定が適用されます。設定ファイルの再読み込みは `M-x eval-buffer` コマンドを使用して行うことができます。

これで、Emacsを起動するたびにフレームが自動的にフルスクリーンモードで最大化されるようになります。手動で最大化する手間が省け、作業環境が整いやすくなりました！

### まとめ

Emacsのフレームを自動的に最大化する設定は、効率的な作業環境を整えるのに役立ちます。今回紹介したコードを設定ファイルに追加するだけで、Emacsを起動するたびにフレームがフルスクリーンモードで最大化されるようになります。ぜひ試してみてください。
[VirtualBox / Vagrant] VirtualBoxとVagrantとは

# まとめ
## VirtualBoxとは
> Oracle VM VirtualBox （オラクル ブイエム バーチャルボックス）とは、x86ならびにAMD64/Intel64にかかる仮想化ソフトウェアパッケージの一つ。
※ [Wikipedia](https://ja.wikipedia.org/wiki/VirtualBox)

つまり、ホストOS上で複数のゲストOSを仮想マシンとして実行するためのソフトウェア。VMの実行環境です。

## Vagrantとは
> 仮想機械の提供自体は、VirtualBoxをはじめとする仮想化ソフトウェアが行う。Vagrantは、これらソフトウェアが用意されているのを前提として、仮想機械の設定や立ち上げに特化している。
※ [Wikipedia](https://ja.wikipedia.org/wiki/Vagrant_(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2))

つまり、色々な種類の仮想マシンの定義、構築、管理を同一の設定ファイルとインターフェースで操作するためのソフトウェア。

# 目次
- [詳細](#詳細)
    - [VirtualBoxとは](##VirtualBoxとは)
    - [Vagrantとは](#Vagrantとは)
- [使用例](#使用例)
    - [VirtualBoxのみ使用](##VirtualBoxのみ使用)
    - [VirtualBox+Vagrantを使用](##VirtualBox+Vagrantを使用)

# 詳細
## VirtualBoxとは
**種類**: ハイパーバイザ（仮想マシンモニタ）
**提供元**: Oracle
**主な機能**: ホストOS上で複数のゲストOSを仮想マシンとして実行するためのソフトウェア。
**用途**: 個別の仮想マシンを作成、管理、実行すること。

#### 実現できること 
- **複数のOSを同時に実行**: 例えば、Windows上でLinuxや他のWindowsを実行。
- **テスト環境の構築**: 異なるOSでの動作確認や開発テストを実行。
- **スナップショット**: 仮想マシンの現在の状態を保存し、後でその状態に戻す。

#### 比較対象
- EC2 (AWS)
- GCE (GCP)
- Docker (***VMとコンテナは別物だがアプリケーションの実行環境という点では共通のため比較対象に含む***)


## Vagrantとは
**種類**: 仮想マシンのプロビジョニングと管理を行うツール。
**提供元**: HashiCorp
**主な機能**: 仮想マシンの定義、構築、管理を簡単に行えるようにする。特に開発環境のセットアップを自動化するために使われる。
**用途**: 仮想環境の構築を自動化し、開発環境の共有を容易にする。

#### 実現できること
- **仮想マシンの自動構築**: コマンド一つで仮想マシンを設定、起動、構築。
- **環境の再現性**: どの開発者も同じ開発環境を容易に構築できる。
- **プロビジョニング**: Shellスクリプト、Chef、Puppetなどを使って、仮想マシン上にソフトウェアをインストールし、設定を行う。

#### 比較対象
Vagrant単体で使うことはないため
- Vagrant + VirtualBox（VagrantがデフォルトでVirtualBoxに対応してる）
- Vagrant + EC2（vagrant-aws を利用）
- Vagrant + GCE（vagrant-google を利用）
- Vagrant + Docker

# 使用例
## VirtualBoxのみ使用
- 手動でUbuntu仮想マシンを作成し、OSをインストールし、必要なソフトウェアを手動でインストール。
- 各開発者が自分で設定を行うため、設定がバラバラになる可能性がある。

## VirtualBox+Vagrantを使用
- Vagrantfileを作成し、仮想マシンの設定（例えば、OSの種類、メモリサイズ、ネットワーク設定など）とプロビジョニングスクリプト（必要なソフトウェアのインストールや設定）を記述。
- 各開発者は`vagrant up`コマンドを実行するだけで、同じ設定の仮想マシンを立ち上げ、環境を統一。


# 参考リンク
- [VagrantとVirtualBoxは別物](https://sue445.hatenablog.com/entry/2021/02/07/205521)
pgAdmin4のダッシュボードで確認できること

### pgAdmin4とは

PostgreSQL用のGUI管理ツールです。

### ダッシュボードのグラフで確認できる5つの観点

ダッシュボードとは、pgAdmin4を起動した際最初に出てくる以下の画面です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533750/291c7ce9-ad78-5eef-c2fc-e7f1fa2f8a06.png)

①Database Sessions
データベースセッション

②Transactions per second
秒間トランザクション

③Tuples in
書き込み行数

④Tuples out
読み取り行数

⑤Block I/O
ブロックI/O

pgAdmin4ではこの5項目がグラフで確認できます。
vimium 初心者が使ってみた

## vimiumとは
vimふうにブラウザイングができるchromの拡張機能です。[コチラ](https://chromewebstore.google.com/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb?hl=ja)

## 背景
外付けキーボードを使い始めると、マウスがトラックパッドの代わりとなるが、マウスに手を伸ばすのが億劫になった。ショーカット勉強中ではあるが、どうしてキーボードから手を離す場面、それは調べごとをする際のブラウジングである。

## vimiumで改善されたこと
・ブラウジングの際にキーボードから手を離さなくて良くなった！

## vimium初心者がよく使うコマンド

|キー入力|動作|
|---|---|
|j|下スクロール|
|k|上スクロール|
|h|左スクロール|
|l|右スクロール|
|gg|ページ最上部へ移動|
|G|ページ最下部へ移動|
|t|新タブを開く|
|o|新しいタブで検索|
|J|タブを左へ移動|
|K|タブを右へ移動|
|H|戻る(back)|
|L|進む(forward)|
|x|タブを閉じる|
|X|消したタブをもとに戻す|
|ｒ|ページの再読込|
|/|ページ内検索|
|n|検索結果次へ|
|N|検索結果前へ|
|f|ページ内のクリック可能な要素<br>(リンクやinput要素)をラベリング<br>※ラベルを入力してフォーカス<br>(リンクなら開く)<br>※`F`で新規タブで開く|

## 所感
まだまだ初心者なので、t(タブ開く)→f(気になるサイトを開く)→j,k,/を使ってサイトの熟読のような用途で使っています。まだまだ使えてないことたくさんあるので、勉強していきます。こんなふうに使っている！という意見があれば、是非コメントよろしくお願いします! Let's Vim!!
vimがそもそもわからないという人がいらっしゃったら、下記コマンドで基礎学習できます。初めてやった際結構感動しました！
```
vimtutor
```

### 参考文献
https://qiita.com/ysuzuki19/items/c774796468a7ae25b28b
https://qiita.com/Takuya-MY/items/f29618a70bccdae0a926
[Lambda]Pythonライブラリをアップロードする

## まとめ

```bash
mkdir hoge
cd hode
pip3 install ライブラリ名 -t .
```

## 経緯

- Slackに記事のURLが投稿された時、その記事の要約をPerplexity APIを使用して投稿したい
    - AWS Lambdaに置くか
    - pythonのライブラリ必要やん！
    - ほな入れよか

```zsh
pip3 install requests /rss_summary

error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try brew install
    xyz, where xyz is the package you are trying to
    install.

    If you wish to install a Python library that isn't in Homebrew,
    use a virtual environment:

    python3 -m venv path/to/venv
    source path/to/venv/bin/activate
    python3 -m pip install xyz

    If you wish to install a Python application that isn't in Homebrew,
    it may be easiest to use 'pipx install xyz', which will manage a
    virtual environment for you. You can install pipx with

    brew install pipx

    You may restore the old behavior of pip by passing
    the '--break-system-packages' flag to pip, or by adding
    'break-system-packages = true' to your pip.conf file. The latter
    will permanently disable this error.

    If you disable this error, we STRONGLY recommend that you additionally
    pass the '--user' flag to pip, or set 'user = true' in your pip.conf
    file. Failure to do this can result in a broken Homebrew installation.

    Read more about this behavior here: <https://peps.python.org/pep-0668/>

note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
```

**ほげぇぇぇぇぇぇぇぇぇぇぇぇ！！！！！**

どうやらグローバルにインストールしようとして、それやめとき！って言われてるっぽい
ってことで、アップロードするディレクトリの中だけに入れまひょか

```zsh
pip3 install requests -t .

Collecting requests
  Using cached requests-2.32.3-py3-none-any.whl.metadata (4.6 kB)
Collecting charset-normalizer<4,>=2 (from requests)
  Using cached charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl.metadata (33 kB)
Collecting idna<4,>=2.5 (from requests)
  Using cached idna-3.7-py3-none-any.whl.metadata (9.9 kB)
Collecting urllib3<3,>=1.21.1 (from requests)
  Using cached urllib3-2.2.1-py3-none-any.whl.metadata (6.4 kB)
Collecting certifi>=2017.4.17 (from requests)
  Using cached certifi-2024.2.2-py3-none-any.whl.metadata (2.2 kB)
Using cached requests-2.32.3-py3-none-any.whl (64 kB)
Using cached certifi-2024.2.2-py3-none-any.whl (163 kB)
Using cached charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl (119 kB)
Using cached idna-3.7-py3-none-any.whl (66 kB)
Using cached urllib3-2.2.1-py3-none-any.whl (121 kB)
Installing collected packages: urllib3, idna, charset-normalizer, certifi, requests

Successfully installed certifi-2024.2.2 charset-normalizer-3.3.2 idna-3.7 requests-2.32.3 urllib3-2.2.1
```

:dancers: :dancer: :dancer_tone1: :dancer_tone2: :dancer_tone3: :dancer_tone4: :dancer_tone5: :dancers:
OpenSSLを使わずにp12→pem変換Pythonコード

# OpenSSLが使えない時でもcryptographyでp12→pem変換

自分用
必要になったので書きます。windows11環境です。

```terminal
pip install cryptography
````

```py
from cryptography.hazmat.primitives import serialization

def convert_p12_to_pem(p12_data, password):
    # p12データを読み込み、秘密鍵、証明書、追加の証明書を取得
    private_key, cert, additional_certs = serialization.load_pkcs12_data(p12_data, password)
    
    # 秘密鍵をPEM形式でエンコード
    pem_data = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption()
    ) + cert.public_bytes(serialization.Encoding.PEM)  # 証明書をPEM形式で追加
    
    # 追加の証明書があれば、それらもPEM形式で追加
    for additional_cert in additional_certs:
        pem_data += additional_cert.public_bytes(serialization.Encoding.PEM)
    
    return pem_data
````