OmniAICreator/Qiita-1.07M huggingface dataset:
【IFTTT】Google カレンダー×LINE Notifyで、うっかり忘れを無くしたい

# メモしてたし昨日まで覚えてた

**なんなら今朝まで覚えてた、けど忘れちゃった…。**
そんなふうに予定をすっぽかしてしまったこと、みなさんにもあるのではないでしょうか。

これの防止策として、
- **スマホでアラームを設定しておく**
- **付箋をテーブルに貼っておく**
- **手の甲に油性ペンで書いておく**

なんて方法もあるかと思いますが、もう少し良い方法は無いものでしょうか。
今回はこれを解決できるサービスを考えてみたいと思います！

# どんなのつくろう

直前にリマインドしてくれるのは良策だと思うのですが、上で書いた「スマホでアラームを設定しておく」だと、「カレンダー／ToDoで予定を登録」⇒「スマホでアラームを設定しておく」の**二度手間になってしまいます。**

また、Googleカレンダーなど、それ自体にリマインド機能がついているものがありますが、**アプリケーションを起動しておかないと動作しないものが殆どです。**

**上記2点の課題（面倒）を解消したサービスつくりたい！**

:::note info
**【目標】予定をリマインドしてくれ、うっかり忘れを防ぐサービスをつくる**
　■ Google カレンダーで予定を登録する。
　■ 予定の時間の○○分前に、LINEにリマインドを送信する。
 
 ⇒普及率の高い「Google」と「LINE」を使うため、多くの利用者が新規アカウントを追加する必要無く、使い始めることができる。
 ⇒アプリを起動しておかなくてもメッセージ受信できる「LINE」の特性を利用する。
:::

# 技術・環境
『IFTTT』にて以下のサービスを組合せ、アプレット（機能）化する。
・Connect Google Calendar to LINE：Any event starts
・LINE integrations：Send message

# うっかり防止リマインダー！

紹介動画をご覧ください。

https://twitter.com/xe_ay51938/status/1731603299466654175

## 詳しくはこちら

![画像_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3563752/04bbc365-984b-4661-0c27-1a2ba34b4005.png)

上で書いた、
「予定を登録」⇒「アラームを設定しておく」の二度手間が無く、
アプリケーションを起動しておかなくても動作する、という点を満たしました！

# ひと手間のカットが「ちりつも」で大きな時間を生む

ひと手間かけて「スマホでアラームを設定しておく」でも、うっかり忘れを軽減することはできます。ただ、**この「ひと手間」を一日何回も、毎日やるとなると、それなりの気力と時間を要するものです。これらを他の有意義な行為に充てた方が有意義ですよね。**

画期的な発明で無くても、そんなちょっとした改善ができるものはないか、日々アンテナを張っていたいと思います。

今回の制作物はしばらく試運用して、効果を測ってみたいと思います！
【rails】 ActiveRecord exists? present? empty? blank? の使い分けどころ


## はじめに
初学者の頃から分かったような気がするけど、適切に使いこなせてなかった
`ActiveRecord`の `exists?`, `present?`, `empty?`, `blank?` の
使い分けについて最近やっと腑に落ちたのでメモリます。

## exists

データが1件でもあるかどうかチェックするには`Model.exists?`を使う。
どういうことかというと
```ruby
 Pokemon.exists?
  Pokemon Exists? (98.6ms)  SELECT 1 AS one FROM `pokemon` LIMIT 1
=> true             
```

ポイントになるのが`SELECT 1 AS` というところ。
データが1行以上「あるかどうか」だけが問題となります。
ということで、データの値を取ってくる必要がないため、
カラムの情報が一切ないことがわかります。

**ちなみにこれと反対の意味を持つのが`empty?`である**


## blank?

``` ruby
Pokemon.where(type: 'FIRE').blank?
  Pokemon Load (481.6ms)  SELECT `pokemon`.* FROM `pokemon` WHERE `pokemon`.`type` = 'FIRE'
=> true  
```
ポイントは` SELECT pokemon.* ` の部分で、**条件にマッチするデータを全て、カラム情報込み** で取得していることがわかる。



**ちなみにこれと反対の意味を持つのが`present?`である**


## では、 どんな時に使い分けると嬉しいか

ある特定の条件を満たすデータがデータベースに存在するかどうかを確認する場合に、`exists?` が適しています。（存在しないことを確認したいなら `empty?`）

これはデータの有無だけが気になる場合で、具体的なデータの値を使用しないときです。

```ruby
if pokemon.exists?(type: 'Fire')
  puts "炎タイプのポケモンが登録されていません。"
else
  puts "炎タイプのポケモンは登録されています。"
end
```

一方で、`present? / blank?` は特定の条件を満たすデータがデータベースに存在するかだけでなく、**それらのデータの値も利用する場合** に使いたい。

```ruby
fire_pokemon = Pokemon.where(type: 'FIRE')

return if fire_pokemon.blank? # この時点で必要なデータも取得できている

puts "Fire タイプのポケモンが存在します。"
# blank?で取得したデータを利用するので、発行されるSQLは１件のみ
puts "それらのポケモン: #{fire_pokemon.pluck(:name).join(', ')}"
```

仮に、データの値も利用する場合に `empty?` を使ってしまうと、後でデータを使用する時に、改めてデータを引いてしまうので、DBサーバーにアクセスする回数が2回になってしまう。
```ruby
fire_pokemon = Pokemon.where(type: 'FIRE')

return if fire_pokemon.empty? #  データが存在するどうかを確認するためにDBにアクセス

# 利用するデータを引くためにDBに再アクセスする必要がある
puts "それらのポケモン: #{fire_pokemon.pluck(:name).join(', ')}" 
```

一概にデータの確認の際には`empty?`と決めに行くのではなく、
処理全体の内容によって`empty? / blank?, exists? / present?` を
使い分けるようにしたい。

## 最後に
ここまで見てくださりありがとうございます。m(_ _)m
この手の記事は山ほどありますが、自身の勉強視点でまとめてみた感じです。

誰かの役に立てば嬉しいです。
【Docker x MySQL】エラー「Can't connect to local MySQL server...」の原因と解決方法

# 概要
Djangoアプリケーションをdocker環境で構築後、コンテナの中に入ってマイグレートやスクリプト実行を行うと以下エラーが発生しました。本記事ではこちらの解決方法を記載します。

```
django.db.utils.OperationalError: (2002, "Can't connect to local MySQL server through socket '/run/mysqld/mysqld.sock' (2)")
```

## 設定ファイルの前提
`docker-compose.yml`と`settings.py`は以下の通りです。

`docker-compose.yml`は以下。

```docker-compose.yml
version: '3'
services:
  mysite:
    build:
      context: ../
      dockerfile: ./docker/Dockerfile
    volumes:
      - '../web:/mysite'
    ports:
      - "8080:8000"
    container_name: mysite_django
    tty: true
    working_dir: '/mysite'

  mysql:
    image: mysql:latest
    container_name: mysite_mysql
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_USER: docker
      MYSQL_PASSWORD: docker
      MYSQL_DATABASE: mysite_db
    ports:
      - "3306:3306"
    volumes:
      - mysite-data-volume:/var/lib/mysql

volumes:
    mysite-data-volume:
```

`settings.py`の`DATABASES`は以下。

```py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mysite_db',
        'USER': 'docker',
        'PASSWORD': 'docker',
        'HOST': 'localhost',
        'PORT': '3306',
        'OPTIONS': {
            'init_command':
                'SET character_set_connection=utf8,collation_connection=utf8_unicode_ci'
        }
    },
}
```

ちなみに、`'127.0.0.1'`に変更してみて実行すると、

```py
        'HOST': '127.0.0.1',
```

同様に`Can't connect to...`エラーになります。

```
django.db.utils.OperationalError: (2002, "Can't connect to MySQL server on '127.0.0.1' (115)")
```

## 原因
原因は、Djangoアプリケーションが探しに行くDBサーバの設定が不適切だったためです。
というより、MySQLサーバーをコンテナで起動させているときのお作法が抜けてしまっていました。

`'HOST': 'localhost'`（または`'127.0.0.1'`）を使用すると、Djangoアプリケーションは自身のコンテナ内でMySQLサーバーを探そうとしますが、実際には`docker-compose.yaml`で定義している通り、MySQLサーバーは別のコンテナ内（`mysql`）で動作しています。そのため、接続エラーが発生したのです。

## 解決方法

`mysql`というサービス名を`docker-compose.yml`で定義していますので、このサービス名をDjangoアプリケーションがMySQLサーバーを見つける際のホスト名として指定することで、正しくMySQLに接続できるようになります。具体的には以下の通り。

```py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mysite_db',
        'USER': 'docker',
        'PASSWORD': 'docker',
        'HOST': 'mysql',  # Dockerコンテナ内でのMySQLサービス名を指定
        'PORT': '3306',
        'OPTIONS': {
            'init_command':
                'SET character_set_connection=utf8,collation_connection=utf8_unicode_ci'
        }
    },
}
```

これにより、Djangoアプリケーションは`mysql`というサービス名で定義されたコンテナ内のMySQLサーバーを正しく参照し、接続できるようになります。
Workato：カスタムコネクター開発にChatGPTを活用してみる

# はじめに
今回は、WorkatoでChatGPTを使う話ではなく、Workatoのカスタムコネクター開発にChatGPTを活用してみる話になります。

ChatGPTはWorkatoのカスタムコネクター（Connector SDK）を理解しており、カスタムコネクター開発に活用することができます。もちろん完璧とはいえませんが（結果に誤りが含まれることもありますが）、開発に役立つ結果を得ることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/ae5bfc67-4f7c-f2b8-123e-67bceb61ac34.png)

# 例

ChatGPTに対して、カスタムコネクター開発について質問してみました

## WorkatoのConnector SDKでRuntime User Connectionsに対応したカスタムコネクタを作成するには
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/691b3876-5d0a-12d6-fee2-1831898c1ea6.png)

WorkatoのドキュメントにはConnector SDKで作成したカスタムコネクタでRuntime User Connectionsを利用する方法が書かれていない（あるいは書かれていても分かりやすく書かれていない）ので、どのようにすれば実装すれば良いのか困っていたのですが、ChatGPTに聞いたら一瞬で解決しました。

## OAuth2に対応したkintoneカスタムコネクタを作成するには
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/9a40b5ef-ed53-e82b-df51-cabd3f4775a9.png)

`kintone.com` と出力されている箇所は `cybozu.com` へ修正は必要ですが、リフレッシュトークンに対応したコードが出力されました。リフレッシュトークンに対応したコードをどのように実装すればよいか、トライアンドエラーをしながら数時間ほど悩んでいました（そして何度か試してみて）ので、一瞬で答えが出てきて解決するのは感動ものです。

# おわりに

Workatoでは、Workato Copilotという生成AIを利用してレシピやカスタムコネクター開発を支援する機能を今後リリース予定ですが（以下参照）、ChatGPTを活用することでWorkato Copilotにを待たずして生成AIを活用したカスタムコネクター開発に取り組むことが可能です。

https://note.ricksoft.jp/n/n07ac53b5259e?gs=bd112e9e62b2

「私もカスタムコネクター開発にChatGPT活用してみようかな」と思った方は、是非お試しくださいませ。
自動運転AIチャレンジ2023インテグレーション大会の振り返り

[自動運転AIチャレンジ2023インテグレーション大会](https://www.jsae.or.jp/jaaic/2023_contest.php
)に参加しました。私は今大会初めて参加させていただき、前回までの経験者から色々教えてもらいながら一緒に取り組みました。

---

## モチベーション
- 自動運転のセンシング以外の判断、制御を含むシステムに興味があった。
- Autowareに興味があったけど、業務ではなかなか触る時間がなかった。
- 前回大会で会社同僚が楽しそうに取り組んでおられた。

**→ 今大会に向けてPCを準備して参戦！**

---

## 取り組み方
週1でDiscordで会話してました。
会話するメリットとして、
- 差分や気づきを共有できる。
- 心が折れない。
- 話すことで理解が深まる。

これは環境構築のバグを乗り越えた瞬間。
一つずつ怪しい点を潰していきました。
最終的に、ディスプレイ設定を変更でリソース不足を回避できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599506/f09540ca-eedd-cd59-69bb-c29873aa6050.png)

---

### 予選提出まで(~8/31)
- 7/M   チーム結成！
- 7/22  環境構築バトル
- 8/10  お盆休暇でやる気を出し始める！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599506/f4bd74f1-db83-e611-503e-8439d77fb65b.png)
- 8/19  実家からリモート勢が復活
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599506/ecf054fd-7e1d-732e-7be4-1fc7e6beee9e.png)

- 8/29  自作プランナーが提出環境で動作せず焦る。運営の方にデバッグ対応していただく(ありがとうございます！)。
提出前の様子

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599506/0188ac3a-5897-92af-7432-079cb1de8699.png)
         
- 9/1  朝提出して出勤！お疲れさまでした！

---

### 決勝まで(~11/12)

前回参加者の他のメンバーに環境構築をお任せしてしまい、私はこれまでセンサ開発の経験やLiDARを扱った経験があったため、特に煙対策の部分を楽しませてもらいました。

煙対策については別記事に記載しました。

https://qiita.com/kiwsdiv/items/cf92182450b2cde7b921

決勝当日は残念ながら海外出張が入ってしまい、現地参加はできませんでしたが、メンバーが現地から中継してくださったおかげで、海外からも当日の熱い様子が伝わってきました。

---

## 感想

これまでセンサ開発の経験はありましたが、自動運転のシステム側に触れることがなかったので、初手の環境構築や自動運転システムのドキュメントを読んでパラメータチューニングするところから楽しかったです。
また、チームで開発しながら、環境構築やテスト環境の大切さを学びました。（さらに効率化するには、どうすればいいのでしょうか…）

当初のモチベーションだったAutowareを通じた自動運転のシステムの理解は道半ばなので、次回は自分で経路生成するなどアルゴリズムに手を入れてみたいです。
【IFTTT】Google Tasks×LINE Notifyで、『かんたん令和の回覧板』

# 報連相はどこでも大切

過去に記事にもしていますが、私のライフワークは『推し活』であり、
当記事のテーマはこれに関連します。

界隈ではよくある話なのですが、
**推しのアーティストの誕生日に、街頭にお祝い動画広告を出したことがあります。**

いつの期間中、どこに、いくらかけて、どんな広告を出すか。
そのために、いつまでに、誰が、何をするべきか。さながらプロジェクトです。

:::note info
**【やったこと】**
①仲の良い推し仲間とプロジェクトチームを組んで推進
②代理店と担当者と連絡を取る
③広告動画を制作
④賛同者から資金を集める（≒クラウドファンディング）
:::

特に④の際の「進捗の共有」「連絡」が大変でした。
**賛同者の年齢層がさまざまで、ITサービスへの理解度やなじみ度合いなどがバラバラだったためです。**

当初は共有カレンダーサービスなどを利用し、
賛同者にプロジェクト進捗状況の共有・ToDo依頼などしようと考えていましたが、
「メールで送って」「X（旧：Twitter）で連絡して」「Googleアカウント？何？わからない」など言われ、効率的な運営ができませんでした。

**人間、わからない・めんどくさそうなものを使うことには、抵抗がありますよね。**
でも、次の機会があった際は、絶対に改善したい…！

# どんなのつくろう

あるWebサービスのアカウントの普及率の調査結果によると、
**『LINE』の利用率が最も高く、10～60代まで8～9割が利用しているとのことです。**
【参照】当記事最後の『参考』

サービスは数あれど、手軽さから、これほど普及していると推測します。これを受け、情報を管理・発信する側も、受信する側もうれしいサービスをつくりたいと考えます！

:::note info
**【目標】『かんたん令和の回覧板』をつくる**
　■ 【発信側】プロジェクトチーム内でToDoタスクを共有管理
　■ 【受信側】LINEで情報を受信
:::

# 技術・環境
『IFTTT』にて以下のサービスを組合せ、アプレット（機能）化する。
・Google Tasks integrations：New Task added
・LINE integrations：Send message

プロジェクトチーム内でのGoogleカレンダー・Google Tasksの共有については、公式案内があるため省略。
【参照】当記事最後の『参考』

# 『かんたん令和の回覧板』
紹介動画をご覧ください。

https://twitter.com/xe_ay51938/status/1731599867057934365

## 詳しくはこちら

![構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3563752/f801f9b0-d18e-7635-e899-759348d2037a.png)

双方に、以下のメリットがあります。

:::note info
**【発信側チーム】**
　■ ToDoタスク状況、発信状況が共有できる。
　■ タスクの登録と同時に受信者に発信でき二度手間とならず、発信漏れもない。
:::
:::note info
**【各受信者】**
　■ LINEさえインストールしていれば情報が受信できる。
　■ Xのタイムラインのように情報が流れてしまわない。
:::

# おいてけぼりにしないモノづくり

似たようなことをもっと精度高く行えるサービスは他にもたくさんあると思いますが、
**新しいアカウントの登録をすることもなく、使用方法を覚えることなく、既存のもので課題解決できるサービス、いわゆる紙の回覧板のように、多くの人が抵抗なく感覚的に理解でき使えるようなモノを目指しました。**
LINEの利用者は多いため、今回のToDoタスク連携のパーツを入れ替えれば、いろいろと応用できそうです。


**IT関連の仕事をしている私ですら「すごいんだろうけど、めんどくくさそう」のハードルを感じるサービスは多いと感じます。**
仕事にしている私は頑張らないといけませんが、全員がそれを強要される必要は無い／強制はできないということを念頭においたモノづくりをするマインドが必要そうですね。

ちなみに、今回の制作物を推し仲間に連携したところ、大変喜んでくれました。うれしい！
学校や町内会の連絡網としても、そのまま使えそうですね！

# 参考
https://webtan.impress.co.jp/n/2022/10/04/43409

https://www.moba-ken.jp/project/service/20230417.html

https://support.google.com/calendar/answer/37082?hl=ja
panel で作成したインタラクティブなグラフを html に組み込む

# 目的
panel で作成したインタラクティブなグラフを html に組み込む

# きっかけ
先日、[「国勢調査で実践する初心者のためのPythonデータ分析ハンズオンセミナー」](https://github.com/mazarimono/python-data-seminar/tree/main/hands-on-seminar)を受講しました。セミナーの資料やnotebookは、GitHubに公開されていますが、興味がありましたら、ぜひ、書籍もご参照ください。
jupyter notebook を html に export し、そのまま資料化しようとしたところ、インタラクティブなグラフがエラーとなってしまい、いろいろ調べましたが根本解決ができなかったため、htmlに組み込むことで、それに対処しました。その方法を記事にしたいと思いました。

# エラー概要、手順
セミナーのjupyter notebookを実行する。（データダウンロードやpath変更等は必要だが、ここでは省略）
例えばChapter6_データの視覚化.ipynbを実行すると、大阪府の市区町村別人口密度の棒グラフが表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570565/559b84cb-d8b8-db53-1a94-44f5d43640a6.png)

インタラクティブなグラフなので、上部ウィジット（プルダウンメニュー、上図では'ratio_area'人口密度）を変更することで、面積や人口、年齢別人口比率など切り替えることができる。
これを、VSCodeから、export⇒htmlでHTML化するが、出力されたHTMLをブラウザで開くと、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570565/00b758b3-918f-d85f-0ea1-b2b27a28a58e.png)
```html
BokehModel(combine_events=True, render_bundle={'docs_json': {'…
```

のようなエラーが表示され、インタラクティブなグラフは表示できない。
前述の通り、いろいろ調べたが、根本解決ができなかった。

# 対処方法

①インタラクティブなグラフを個別でhtml化する。
変更前は、jupyter notebook で表示するだけだったものを、
```python
# 変更前
# ⑤ウィジェットとグラフが並んで配置されるよう、レイアウトを作成
pn.Column(
    col_sel,
    interactive_chart
)
```
一旦panel変数に格納し、output.htmlにsaveした後、表示する。
ここで、embed=Trueを指定しないと、インタラクティブにならない（デフォルト設定のグラフしか表示できず、設定を変更できない）ので、embed=Trueを指定し、インタラクティブなグラフとして出力する。
```python
# 変更後
# ⑤ウィジェットとグラフが並んで配置されるよう、レイアウトを作成
panel = pn.Column(
    col_sel,
    interactive_chart
)
panel.save('output.html',embed=True)
panel
```

②出力されたoutput.htmlをブラウザで開くと、インタラクティブなグラフが表示されることが確認できるので、これをhtml本体に組み込む。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570565/fd30202f-c030-5b65-3647-a24858b5148f.png)

③jupyter notebookをexportしたhtml（本体）をテキストエディタで開くと、
```
<pre>BokehModel(combine_events=True, render_bundle={&#39;docs_json&#39;: {&#39;56c948e6-7248-4b0e-a5b8-7b7b55262126&#39;: {&#39;version…</pre>
```
が確認できるので、その１行を以下に書き換える。
```
<iframe src="output.html" width="1000" height="700"></iframe>
```
output.htmlは、インタラクティブなグラフを個別に出力したファイル名。
width/heightは、そのグラフを表示するサイズ。見やすいように適切なサイズに調整する。

# 結果
jupyter notebookをexportしたhtmlをブラウザで開くと、インタラクティブなグラフも表示できるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570565/f5f35c72-61e3-1b67-193e-3df3e629249e.png)
Microsoft 認定試験の勉強で知った Windows の機能

NTTデータ先端技術株式会社の原田です。

Microsoft 認定試験の勉強で改めて知ることのできた Windows の機能がありましたので、自分自身の備忘録も兼ねて記事にしておきます。
認定試験は主に AZ-800 (Windows Server ハイブリッド コア インフラストラクチャの管理) と AZ-801 (Windows Server Hybrid Advanced Services の構成) の範囲です。

## Hyper-V のリソースメータリング

https://learn.microsoft.com/ja-jp/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/hh831661(v=ws.11)

https://learn.microsoft.com/en-us/virtualization/community/team-blog/2012/20120820-how-to-use-resource-metering-with-powershell

Windows Server 2012 以降の機能です。
Hyper-V ホストからゲスト仮想マシンのリソース情報 (CPU / Memory / Disk /Network) を取得することができます。
PowerShell になっているのでタスクスケジューラ等と組み合わせて使いやすいのと、取りにくいディスクやネットワークの I/O を取れるので使い道あるなと思いました。

## 信頼性モニター

https://learn.microsoft.com/ja-jp/training/modules/monitor-windows-server-performance/4-review-reliability-with-reliability-monitor

こちらに至っては Windows Server 2008 からありましたが全く知りませんでした。(MCP の受験見たたことはあったかもしれません)
2008 ではパフォーマンスモニターの一部でしたが 2012 以降ではコントロールパネルに組み込まれています。
内容見るとイベントログをサマリしてレポート化するツールで、うまく使えるとトラブルシューティングで良くあるイベントビューアーの管理イベントをサルベージするオペレーションが削減できるかもしれません。

## ユーザーアクセスログ(UAL)

https://learn.microsoft.com/ja-jp/windows-server/administration/user-access-logging/get-started-with-user-access-logging

Windows Server 2012 以降の機能です。
グループポリシーによるログオン監査の代わりになるかと思ったのですが、<INS>UAL で記録できるアクセスの最大数は 1 日に 65,535 個 </INS>と言う制約があり監査用途にはちょっと厳しそうです。
あとメモリとディスクを消費するので明示的に無効化 (既定は有効) の方が良さそうに思います。

## セットアップおよびブート イベントの収集

https://learn.microsoft.com/ja-jp/windows-server/administration/get-started-with-setup-and-boot-event-collection

Windows Server 2016 以降の機能です。
セットアップおよびブートイベントを特定のコンピューターに転送して管理することができるようになるものです。
特にブートに関するトラブルはログを抜き出すのが大変なのでいざと言う時の備えになりますね。

## Just Enough Administration (JEA) 

https://learn.microsoft.com/ja-jp/powershell/scripting/learn/remoting/jea/overview?view=powershell-7.4

PowerShell 5.0 以降の機能で、プレインストールされているのが Windows Server 2016 以降となります。
Powershell リモート実行の際の特権を管理する機能で、管理者特権を要求される処理に対して管理者特権要求をクリアしながら最小特権での実行を可能とします。
とかなり重要な機能だと思いますが周りではあまり使われていない印象です、仕組み的にはシンプルですが定義ファイル作成 (New-PSRoleCapabilityFile) のプラクティスが乏しく使いづらい感じは少しあります。

## PowerShell ダイレクト

https://learn.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/user-guide/p

Windows Server 2016 以降の機能です。
Hyper-V ホストからゲスト仮想マシンに PowerShell を実行することができる機能です。
普段使いにはならないと思いますが、トラブルなどで仮想マシンに接続できない場合の対処手段として覚えておいて良いかと思いました。

## シールドされた VM

https://learn.microsoft.com/ja-jp/windows-server/security/guarded-fabric-shielded-vm/guarded-fabric-and-shielded-vms

Windows Server 2016 以降の機能です。
すべての仕組みを理解するのはかなり複雑ですが、仮想マシンそのものを BitLocker で暗号化することにより特定の (承認された) ホストでのみ起動可能とするテクノロジーと理解しています。
キーの管理が付随するので運用には気を使いそうです。

## おわりに
とこんなところでしょうか、結構使い出のありそうな機能で知らなったものも多かったので勉強当時ちょっとショックを受けました。
あと同じ過程で Windows Admin Center がリリースされていますがそこも取り込めてないですね、まだなんだかんだでリモートサーバー管理ツール (RSAT) 使うことが多いので。
システムとともに人間もバージョンアップしていかないと。
新機能 InsightsでIncidentの傾向分析！

PagerDutyのIncident傾向把握、分析・改善はされていますか？

Incidentの分析として、下記3つの指標を確認されることが多いです。

<strong>1. Incident件数</strong>
<strong>2. MTTA (Mean Time to Acknowledge)　‐　Incident認識(Acknowledge)までの時間</strong>
<strong>3. MTTR (Mean Time to Resolve)　‐　Incident解決(Resolved)までの時間</strong>

この3つはそれぞれ以下のポイントが確認できる重要な指標です。

<strong>1.Incident件数</strong>
- インシデントが多い場合...システム/インフラに重大な問題がある、モニタリングの設定ミス、または調整が必要
- インシデントが少ない場合...正しい状態！! ...もしくは、モニタリングが十分出では無い？！

<strong>2.MTTA</strong>
- チームがインシデントに対して、オーナーシップを持ち対応できているか？
- 作業を開始するまでにかかる時間は適切か？

<strong>3.MTTR </strong>
- チームがインシデントに対応できているのか？
- 動員や問題解決の速さは適切か？
- ダウンタイムを最小化し、顧客と収益への影響を最小限に抑える事ができているか？


これらの指標は、AnalyticsのInsightsで確認することができます！

現在のPagerDuty利用状況を可視化し、
インシデントの解決時間を短縮やデータドリブンの意思決定を強化するために、
今すぐInsightsを使って確認してみましょう！！！


【アクセス方法】
Analytics　> Insightsからアクセスします


【Insights画面】

![9709bd8-incident_activity_report.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618387/550c1430-52bf-00af-6f32-414993bf7296.png)

【Insightsに関する記事】
詳しくはこちらの記事をご覧ください
https://support.pagerduty.com/lang-ja/docs/insights


https://www.pagerduty.co.jp/
DynamoDB おさらい

# はじめに

* 業務で利用するかもしれないためおさらい
* 備忘のためキーワードなどのみ
* 2023/12 時点

# DynamoDB

## 概要

[ドキュメント](https://docs.aws.amazon.com/ja_jp/dynamodb/)

* フルマネージドNoSQLデータベース
* ReadCapacityUnit(4KB) / WriteCapacityUnit(1KB) を持つ
* KMS暗号化をサポート
* オンデマンドバックアップを作成可能で、それを用いたポイントインタイムリカバリを使用可能
* 項目にTTL(有効期限)を設定することで、項目を自動削除可能
* 結果整合性のある読み込みをデフォルトとし、強力な整合性のある読み込みをサポート
* マルチアクティブ/マルチリージョンレプリケーション向けのグローバルテーブルをサポート

## サブサービス

* DynamoDB Streams
  * テーブルのデータ変更イベントをキャプチャするオプション
  * 項目のイメージをキャプチャしてストリームに書き込む
* DAX
  * マイクロ秒応答に対応

## 直近アップデート

* [OpenSearch Service との zero-ETL 統合](https://aws.amazon.com/jp/blogs/aws/amazon-dynamodb-zero-etl-integration-with-amazon-opensearch-service-is-now-generally-available/)
* [Redshift との zero-ETL 統合](https://dev.classmethod.jp/articles/zero-etl-integrations-amazon-redshift-reinvent/)
* [ベクトルサーチ](https://dev.classmethod.jp/articles/vector-search-capabilites-amazon-documentdb-amazon-dynamodb-ga/)
* [期間での増分エクスポート](https://dev.classmethod.jp/articles/update-amazon-dynamodb-incremental-exports/)
* [トランザクション毎に最大100リクエスト実行可能](https://dev.classmethod.jp/articles/update-amazon-dynamodb-can-now-fulfill-up-to-100-requests-per-transaction/)

## 機能詳細

### プライマリキー

* パーティションキー
  * 設定必須、項目が保存されるパーティションの決定にかかわる
* ソートキー
  * 設定任意
* キー以外の属性でソートやクエリはできない

### セカンダリインデックス

* 別の属性をキーに指定した射影を作成し、それに対してソートやクエリを実行する
* [グローバルセカンダリインデックス](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GSI.html)
* [ローカルセカンダリインデックス](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/LSI.html)

### セキュリティ

* VPC Endpoint

### モニタリング

* [メトリクスとディメンション](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/metrics-dimensions.html)

### シャード分割

* [大規模な Amazon DynamoDB テーブルに適切なシャード数の選択](https://aws.amazon.com/jp/blogs/news/choosing-the-right-number-of-shards-for-your-large-scale-amazon-dynamodb-table/)

### DynamoDB Transactions

* ACIDサポート

### AutoScaling

* [DynamoDB Auto Scaling によるスループットキャパシティの自動管理](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/AutoScaling.html)

### レートリミット戦略?

* [Global Admission Control](https://qiita.com/yoshii0110/items/bd71b4479ee71aa6bf53#global-admission-control)
* [プレエンプティブ・スプリット](https://dev.classmethod.jp/articles/reinvent2023-report-dat330/)
* レプリカモード

### Global Tables

* [操作](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GlobalTables.html)

### クォータ

[ドキュメント](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/ServiceQuotas.html)

* 最大5つのローカルセカンダリインデックス
* テーブルごとに20個のグローバルセカンダリインデックス
* パーティションキーと値の長さ 1-2048バイト
* ソートキーと値の長さ 1-1024バイト
* テーブルとセカンダリインデックス名 3-255文字
* 属性名 1文字以上 64KB以下

データ型

* 文字列 最大400KB
* 数値 最大38桁
* バイナリ 最大400KB

属性

* 深さ最大32までの入れ子
Chrome拡張で現在のタブのタイトルを取得する

# はじめに
Chrome拡張HelloWorldの[にわのわ](https://twitter.com/niwa_nowa)です。
前日、前々日とRSSフィードとRSSリーダを作りました。
このRSSフィードにお好みの記事を追加するためのChrome拡張を作りたいと思います。

# 作ったもの
今回作ったものはこちらで公開しています。

https://github.com/niwanowa/niwanowa-rss-post-extension

# ソース
```background.js
/* コンテキストメニューを作成 */
const parent = chrome.contextMenus.create({
    id: "share",
    title: "ページを共有",
    contexts: ["all"],
});

chrome.contextMenus.create({
    parentId: parent,
    id: "title",
    title: "ページタイトルとURLを送信",
    contexts: ["all"],
});


/* コンテキストメニューがクリックされた時の処理 */
chrome.contextMenus.onClicked.addListener((info, tab) => {
    switch (info.menuItemId) {
        case "title":
            chrome.scripting.executeScript({
                target: { tabId: tab.id },
                function: title,
            });
            break;
    }
});
function title() {
    // タイトルとURLを取得
    const url = "https://hogehoge.com";
    const link = location.href;
    const title = document.title;

    // POSTリクエストを送信
    fetch(url, {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
        },
        body: JSON.stringify({ link, title }),
    })
    .then(response => response.json())
    .then(data => console.log("POST successful:", data))
    .catch(error => console.error("Error:", error));
}

```
# Feature
> const url = "https://hogehoge.com";
とURLをベタ書きしているのですがこれはオプションで設定できるようにする予定です。
（ソースにoption.htmlを書き散らしている。）

# おわりに
初めてChrome拡張でものを作りました。
jsではあるんですが拡張特有のものが多く、全くわからんとなっています。
全くわからん。

# 参考

https://qiita.com/FrogApp/items/cd64894721a0e4723047
【javascript】【jquery】console.logで要素をキレイに見る方法

# 結果
```javascript

$.fn.log = function() {
    this.removeAttr('style');
    console.log.apply(console, this);
    return this;
};
// コンソールに出力

target_li.log();
```


```javascript

$(() => target_li.removeAttr('style').each(console.log));
```
ブックマークレットの作り方　～お決まりのサイトを開く～

## ブックマークレットとは
ブックマークレットは、WEBブラウザ上でURL化されたJavascriptを動かす機能です。
名の通り、URL化されたJavascriptをブックマークに登録して使われることが多いです。
ブラウザの種類を問わずに動かせるため、他者への共有時に配慮することも少なく、とても扱いやすいです。

## 作り方
試しに、普段業務で使用するWEBサイトをボタン一つで表示するブックマークレットを作成します。

### 1. Javascriptを書く
お決まりのサイトを別タブで開くコードを記載します。
```javascript
window.open("https://slack.com/intl/ja-jp");
window.open("https://www.atlassian.com/ja/software/jira");
```

### 2. JavascriptをURLエンコードする
URLエンコードを実行する前に、お決まりの文言をJavascript内に追記します。
前方に「(function(){」、後方に「})()」を追記します。
具体的には以下の通り。
```javascript
(function(){
window.open("https://slack.com/intl/ja-jp");
window.open("https://www.atlassian.com/ja/software/jira");
})()
```
上記を以下のサイトで、URLエンコード(UTF-8)を実行します。
[ASCIIコード変換器(https://web-apps.nbookmark.com/ascii-converter/)](https://web-apps.nbookmark.com/ascii-converter/)

結果、以下のように出力されます。
```
(function()%7B%0Awindow.open(%22https%3A%2F%2Fslack.com%2Fintl%2Fja-jp%22)%3B%0Awindow.open(%22https%3A%2F%2Fwww.atlassian.com%2Fja%2Fsoftware%2Fjira%22)%3B%0A%7D)()
```

最後に、出力された文字列の前方に「javascript:」を追記して、URL化が完了します。
```
javascript:(function()%7B%0Awindow.open(%22https%3A%2F%2Fslack.com%2Fintl%2Fja-jp%22)%3B%0Awindow.open(%22https%3A%2F%2Fwww.atlassian.com%2Fja%2Fsoftware%2Fjira%22)%3B%0A%7D)()
```

### 3. ブックマークに登録する
適当なサイトをブックマークした後、「ブックマークを編集」ダイアログを表示します。
「名前」にはブックマークレットの名前を、
「URL」には先程作成したURLを入力し、保存します。
![ブックマーク.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911155/be60dd27-2db3-2c9b-2c82-ab2bae6420f9.png)

## 終わりに
Javascriptならばブラウザの機能で実行できるため、業務効率化に用いるツールとして導入しやすいと思います。
ぜひお試しあれ。
LangChainのConversationEntityMemoryを検証してみた

## はじめに
LangChainの会話履歴を保存するMemory機能の1つであるConversationEntityMemoryを検証してみました。LangChainのConversationEntityMemoryの挙動を確認したい方におすすめです。

## 開発環境
- Windows 11
- Python 3.11.5
- dotenv
- LangChain
- Azure OpenAI

## 実装
### 必要なパッケージのインストール
以下のコマンドで必要なパッケージをインストールします。

```
pip install langchain
pip install openai
pip install python-dotenv
```

### 環境変数の設定と依存関係の読み込み
.envファイルを作成し、Azure Open AIの環境変数の設定をします。
ご自身の環境に合わせて設定してください。

```.env
# APIキー
OPENAI_API_KEY = "XXXXX"

# エンドポイント
AZURE_OPENAI_ENDPOINT = "XXXXX"

# 使用するOpenAI APIのバージョン
OPENAI_API_VERSION = "XXXXX"
```
　　
必要なライブラリをインポートします。
```test.py
# 環境変数を.envファイルから読み込む
from dotenv import load_dotenv
load_dotenv()

from langchain.chat_models import AzureChatOpenAI
from langchain.chains import ConversationChain # 会話専用のChain
from langchain.memory import ConversationEntityMemory
from langchain.memory.prompt import ENTITY_MEMORY_CONVERSATION_TEMPLATE # ConversationEntityMemory専用のテンプレート
```

### 使用するモデルの準備
Azure Chat OpenAIを定義します。

```test.py
llm = AzureChatOpenAI(
    temperature=0,
    azure_deployment="gpt-35-turbo-16k",
)
```

### ConversationEntityMemoryの定義

以下のようにConversationEntityMemoryを定義します。
ConversationEntityMemoryは**会話に含まれているエンティティ情報を保持**します。
エンティティとは、話者や固有名詞など、会話中の特定の事物に関する情報のことです。
```test.py
memory = ConversationEntityMemory(llm=llm)
```

### chainを作成し、実行

最後にchainを作成し、実行します。最初の質問ではトムとサムという人物がIT企業でエンジニアで働いていることを伝え、次の質問でそれを確かめる質問を投げます。

```test.py
conversation = ConversationChain(
    llm=llm,
    verbose=True,
    prompt=ENTITY_MEMORY_CONVERSATION_TEMPLATE,
    memory=memory
)

result = conversation.predict(input="トムとサムはIT企業でエンジニアとして働いています。")
print(result)
result = conversation.predict(input="トムとサムの職業について教えてください。")
print(result)
```

　　
これまでのPythonコードを上から順に記述し終わったら、Pythonファイルを実行します。
実行結果は以下のようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124507/55706f0d-58df-cce7-11db-dddcb36f1dac.png)

「Context」に固有名詞の情報が抽出されています。
その情報から2問目は回答していることが確認できます。


## おわりに
LangChainの会話履歴を保存するMemory機能の1つであるConversationEntityMemoryを検証してみました。固有名詞の情報を保持して回答したい場合には有効です。ぜひ、試してみてください。

最後までお読みいただき、ありがとうございました！ 記事に関する質問等ございましたら、コメントもしくは以下のDMにてよろしくお願いします。

https://twitter.com/t___tatsuki

## 参考文献
https://python.langchain.com/docs/modules/memory/types/entity_summary_memory
nginxの再インストール

調べてもあんまり的確な答えが出てこなかったので、備忘録的な感じで記事にしました。

# 動作環境
Webarena IndigoのVPSを使用
OSはUbuntu 20.04 (x86_64)

# nginxを停止+削除
```bash
sudo systemctl stop nginx #停止
sudo rm -f -R /usr/local/nginx && rm -f /usr/local/sbin/nginx #削除
cd nginx-1.24.0 #ソースが置かれてるディレクトリへ移動
sudo make clean #clean
```
:::note info
ビルドし直す程度ならこれで十分なはずですが、設定やら何やら全部消し飛ばしたい場合は
```bash
sudo rm -rf /etc/nginx /etc/default/nginx /usr/sbin/nginx* /usr/local/nginx /var/run/nginx.pid /var/log/nginx
```
を実行してください。
:::

# ビルド
```bash
sudo ./configure #オプションとかはお好みで
sudo make && sudo make install #makeしましょ
sudo systemctl start nginx #開始
```

# 確認
```bash
ubuntu@myindigo:~$ sudo systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2023-12-04 17:20:41 JST; 2min 5s ago
       Docs: man:nginx(8)
    Process: 101393 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
    Process: 101405 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
   Main PID: 101406 (nginx)
      Tasks: 3 (limit: 9491)
     Memory: 3.6M
     CGroup: /system.slice/nginx.service
             tq101406 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
             tq101407 nginx: worker process
             mq101408 nginx: worker process

12月 04 17:20:41 myindigo systemd[1]: Starting A high performance web server and a reverse proxy server...
12月 04 17:20:41 myindigo systemd[1]: Started A high performance web server and a reverse proxy server.
```

簡単ですね。
どのインストーラーをダウンロードすればいいの？インストーラーの選び方

# はじめに
みなさんは何かソフトをPCにインストールしたことはありますか？
インストールする際にいろんなバージョンの中から選ぶことがよくあるでしょう。サイトによってはインストールボタンを押すと自動で自分の環境にあったものを入れることができますが、そうもいかないこともあります。
今回はどれを選んでいけばいいかをVSCodeのインストールのページを例に説明していきます。

# 想定読者とゴール
いつもインストーラーを雰囲気で選んでいる人が、ちゃんと自分の環境にあったものを選べるようになる。

# 対象のOS
windows, Linux
MacOSの端末を持っていないため、MacOSに関する説明はしません。

# ページを見る
まずページを見てみましょう。VSCodeの[ダウンロードページ](https://code.visualstudio.com/download)を開くとこんな感じになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560756/9c4e1dee-5fce-761d-410b-1214c4f85815.png)
大きなダウンロードボタンを押せば自動で判別してダウンロードできますが、今回はCPUアーキテクチャとOSを自分で選択できることが目的なので、それは使わないことにしましょう。

# x64とかArm64って何？
これはCPUアーキテクチャを指しています。OSやCPUごとに実行できるファイルが決まっています。CPUは様々な種類があり、CPUごとに理解できる機械語が異なります。CPUごとに機械語があるといろいろ大変なので、CPUのグループごとに機械語は決まっています。このグループごとをCPUのアーキテクチャといい、64ビット, arm64などの種類があります。

話は少々それますが、macbookにwindowsOSを入れることができなくなったのもMacBookのCPUのアーキテクチャが変わったことによります。

# で、どれを選べばいいの？

まずは自分のPCのOSとCPUのアーキテクチャを調べましょう。win11の場合は設定 > システム>システムの種類で確認することができます。Linuxの場合は`uname -m`コマンドで確認できます。

## windows
windowsの場合、いくつか種類がありますね。
### User Install
今ログインしているユーザー環境にだけ入れたいときに使います。公式が推奨しています。

### System Install
全てのユーザー環境に入れたいときに使います。

### .zip
インターネット経由で入れるのが不可能、会社で共有フォルダに置いておきたい場合などに使います。

### CLI
power shellなどのターミナル経由で入れたいときに使います。

## Linux
LinuxにはUbuntu、Read Hatなど様々なディストリビューションがあります。また、rpm, bedなどパッケージ管理ソフトがあります。それぞれの環境に合わせて選択してください。

# 最後に
今回はVSCodeを例に入れ方を紹介しました。ほかのソフトのインストーラーのダウンロードのやり方も変わらないと思います。よかったら参考にしてください。
PythonでExcelマクロを実行

## はじめに
業務自動化において，「既存マクロの実行」をPythonで実装したときの備忘録．

## 動作環境
- Python 3.12.0
- pywin32 306

pywin32はpipを使用してインストールできます．
```
pip install pywin32
```

## 準備
1. Excelマクロが有効なxlsmファイルを準備する．
2. モジュール名と実行するマクロ名を記憶する．
3. Pythonスクリプトを書く．

今回使用するマクロとサンプルコードは以下になります．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617469/63c8d1ab-28a0-d6ac-b6c4-40e464da0308.png)

マクロの実行コマンドでは，上図の標準モジュール名とsubプロシージャ名を必要とします．

### ソースコード
```sample.py
import win32com.client

excelFile = r"C:\qiita\macro.py"
try:
    # Excelアプリケーションを起動
    xlp = win32com.client.Dispatch('Excel.Application')
    # Excelアプリケーション表示
    xlp.Visible = True
    # 警告ダイアログを非表示
    xlp.DisplayAlerts = False
    # マクロファイルを開く
    wb = xlp.Workbooks.Open(excelFile)    
    # マクロ実行
    xlp.Application.Run('sample.hogehoge')
    # ファイルを保存して閉じる
    wb.Close(SaveChanges = True)

finally:
    # 警告ダイアログを表示
    xlp.DisplayAlerts = True
    # Excelアプリケーション終了
    xlp.Quit()
```
<INS>pywin32はインストールするときと使用するときで名前が異なります．</INS>

ソースコードのL14 ```xlp.Application.Run('sample.hogehoge')```のカッコ内で実行するマクロを指定します．指定方法は <b>(モジュール名.subプロシージャ名)</b> です．

```Quit()```でExcelを終了すると，もともと開いていたExcelファイルも閉じるので注意しましょう．
全要素の出力 (paizaランク D 相当)

https://paiza.jp/works/mondai/array_primer/array_primer__2dmatrix_output_step2

今日はこれ
久しぶりにやったからか、理解があやふやなまま
試行錯誤してこれで正解した。
だがコードを見直すと変だ。。


```py
li = [[6,5,4,3,2,1],[3,1,8,8,1,3]]
for i in range(len(li)):
    for j in range(len(li[0])+1):
        if j < len(li[0])-1:
            print(li[i][j],end=" ")
        elif j == len(li[0])-1:
            print(li[i][j])

```

なるほど。。。要素数の合計を＋１したままループしてしまってました。
あと、elifじゃなくてもelseでもよさそう。

```py
li = [[6,5,4,3,2,1],[3,1,8,8,1,3]]
for i in range(len(li)):
    for j in range(len(li[0])):
        if j < len(li[0])-1:
            print(li[i][j],end=" ")
        elif j == len(li[0])-1:
            print(li[i][j])

```
秒でわかるオススメするエディタ👑BEST3👑

# #1 はじめに
メリークリスマス！！←ちょっと早くない？？
いかがお過ごしでしょうか！！
僕はめちゃくちゃ元気ですよーー！！←風邪引いてます
:santa:｛今日はみんなにささやかなプレゼントを贈るよ！！）
今回は僕がオススメするエディタのベスト3について
ランキング形式でまとめてみました。

# #2 オススメのエディタ
### 👑1位👑　Sublime Text
https://www.sublimetext.com/

僕がオススメするエディタ1位はSublime Textです！！
軽くてUIが見やすい上にどの言語でもコードが書きやすいのでオススメです。
### 2位 VScode
https://code.visualstudio.com/

僕がオススメするエディタ2位はVScodeです！！
他のエディタと比べてダントツに高機能で誰が使っても使いやすいのでオススメです。
しかし、機能が多すぎるあまりに初心者には使いづらいかな...と思います。
### 3位 Geany
https://www.geany.org/

僕がオススメするエディタ3位はGeanyです！！
他のエディタと比べてダントツに軽いのでオススメです。
しかし、UIがちょっと見づらいかな...と思います。
# #3 さいごに
今回はオススメするエディタのベスト3についてランキング形式でまとめてみました。
この記事が皆さんの助けになれば幸いです。
SwayFXを試す

## SwayFXとは
タイル型ウィンドウマネージャ及びWaylandコンポジタのSwayのフォーク
https://github.com/WillPower3309/swayfx

下記のようなことができるようになる
- ぼかし
- 角、ボーダー、タイトルバーの丸みにアンチエイリアスをかける
- 影
- フォーカスされていないウィンドウを暗くする


## 環境
いわゆる[中二病エンジニア](https://zenn.dev/yutakatay/articles/chuunibyou-engineer)

## 導入
```
yay -S swayfx
```

## コンフィグ
```
# 例
blur enable
blur_passes 3
blur_radius 2
corner_radius 10

shadows enable
shadow_blur_radius 25

default_dim_inactive 0.2
dim_inactive_colors.unfocused #000000FF
dim_inactive_colors.urgent #900000FF
```
また、/usr/share/swayディレクトリを指定している場合は
```
/usr/share/swayfx/
```
に変更する。
```diff
# スクリーンショット
- bindsym Mod4+Shift+X exec /usr/share/sway/scripts/grimshot --notify save window $HOME/Downloads/screenshot_$(date "+%y%m%d%H%M%S").png
+ bindsym Mod4+Shift+X exec /usr/share/swayfx/scripts/grimshot --notify save window $HOME/Downloads/screenshot_$(date "+%y%m%d%H%M%S").png
```

## プレビュー
![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512427/9118012d-292b-e8ff-8bd5-24aa98258ff6.gif)
VScodeの便利なショートカットまとめ（Mac）

個人的に業務でよく使用するVScodeのショートカットをまとめて見たいと思います。
ちなみにMacのみとなりますので、あしからず…

## 全般

| 内容 | キー |
|:-:|:-:|
| これまで開いたプロジェクトを選択 | control + r  |
| ターミナルを開く |  cmd + j |
| サイドバーの開閉 | cmd + b  |
| ターミナルを開く | cmd + j  |

## エディタ関連

| 内容 | キー |
|:-:|:-:|
| カーソルを行頭、行末まで移動  |  cmd + ← , cmd + → |
| カーソルが行の途中でも改行 | ｃｍｄ + enter  |
| カーソルの行の上に改行 | ｃｍｄ + shift + enter  |
| 行の上下移動 |  option + 上下矢印 |
| 行の複製 |  option + shift + 上下矢印 |
| 行の削除 | cmd + shift + k  |
| 複数行を選択（マルチカーソル） | cmd + option + 上下矢印  |
| 同じ単語を複数選択 | cmd + d  |
| ウィンドウ内のファイルを探す | cmd + p  |
| タブを閉じる | cmd + w  |
| ウィンドウを閉じる | cmd + shift + w  |

他にもたくさんあるのですが、とりあえずこのあたりまで…
VScodeは便利ですよね。
特にマルチカーソルなんかは、すごく重宝します。
BigQueryでKARTE SignalsのGoogle広告用のハッシュ値を生成する

以下のドキュメントにかかれている、ハッシュ値をBigQueryで求めてみます。

https://support.karte.io/faq/1MZmzZXZNsgZ4Vd22tjT5T#1-2

@の手前のドットは削除する必要がある一方で、@の後ろのドットは維持する必要がある点に注意しながら、文字列置換を行います。

```sql
to_hex(sha256(lower(replace(replace(split(email, '@')[0], ' ', ''), '.', '')) || '@' || lower(replace(split(email, '@')[1], ' ', ''))))
```

サンプルとして提供されている ` John.Smith@gmail.com` に対して処理した結果、ハッシュ値のサンプル通りの値が得られることが分かります。

![スクリーンショット 2023-12-04 17.01.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/00dc6984-54b2-17a4-de56-4447ed362786.png)
Azureサポートチケットの問い合わせ方法によってログやAPIが変わる話

## はじめに
AzureのMicrosoftサポートでリクエストを作成すると、アクティビティログが出力されるのはご存知でしょうか？
今回は、その問合せ方法によってログの出力や、やり取りの履歴を取得する際のAPIが変わることについてご紹介します。

## サポートへの問合せ方法
### 1. メール
個人的には、こちらを良く使います。
（内容についてはほとんど黒塗りです。。すみません。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3242301/625e05ed-9d9e-bf7f-581d-8c6e59249e6b.png)


### 2 . Portal上の[ヘルプとサポート]
こちらはPortalの[ヘルプとサポート] > [すべてのサポート リクエスト] > [タイトル]からやり取りする方法です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3242301/b055cbed-829e-6d81-56af-e11e769a29f6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3242301/9ef650b5-05ef-1f4b-e9bb-928f388a9469.png)

## 何が違うのか
### アクティビティログに出力される内容が違う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3242301/a7b65300-dbd1-90a8-c514-2c8f166632df.png)
メールの場合は **「Write Support Ticket」** 、Portalの場合は **「Write Support Ticket Communication」** が表示されます。

こちらは単に表示が違うというわけではなく、リソースタイプがメールの場合は**Support Ticket**、Portalの場合は**Communications**としてログが出力されているということのようです。

実際にログを見てみると、リソースタイプは以下のようになります。

```text: メールの場合
/SUBSCRIPTIONS/{サブスクリプションID}/PROVIDERS/MICROSOFT.SUPPORT/SUPPORTTICKETS/{チケットName(ID)}
```

```text: Portalの場合
/subscriptions/{サブスクリプションID}/providers/microsoft.support/supporttickets/{チケットName(ID)}/communications/{コミュニケーションName(ID)}
```

**補足**
「Support Ticket」はチケット単位、「Communications」はチケットに紐づくやり取り単位のイメージです。

## 活用シーンを考えてみる
媒体の特性から使い分けるのはもちろんですが、ナレッジ活用の観点からすると、チケット単位で見るか、やり取り一つ一つに焦点を当てるかというところで違いがあるかと思います。

例えば、Javaではチケットとコミュニケーションを取得する場合では、次のように異なるインターフェースを実装し、getあるいはgetByIdで取得する必要があります。

```Java:SupportTickets
public interface SupportTickets{
    public abstract SupportTicketDetails get(String supportTicketName)
}
```
```Java:Communications
public interface Communications{
    public abstract CommunicationDetails get(String supportTicketName, String communicationName)
}
```
上述の通り、メールで連絡を取っている場合は、「communicationName」がログ上に表示されていないため、やり取り一つ一つを管理したい場合はPortal上で連絡を取るのが良いかもしれません。

※なお、「communicationName」がない場合も以下のメソッドを利用して、やり取りの一覧を取得することができます。
```Java:SupportTickets
public interface SupportTickets{
    ppublic abstract PagedIterable list()
}
```

## まとめ
今回は、MSサポートの問合せ方法について、メールとPortalを利用した場合の違いについて紹介しました。


## 参考記事
https://learn.microsoft.com/en-us/java/api/com.azure.resourcemanager.support.models.supporttickets?view=azure-java-preview

https://learn.microsoft.com/en-us/java/api/com.azure.resourcemanager.support.models.communications?view=azure-java-preview
【UEFN】Verseのデザインパターンを考える - メソッドチェーン -

Verseのデザインパターンを考えるシリーズです。
今回はメソッドチェーンによるコードの簡略化のアプローチについてです。

## 関数型言語とメソッドチェーン
Verseの世界では関数も式でありその結果を関数にわたすことも可能です。
以下のコードは１から１０を足し算するコードの例です。

※こんなコードを書くメリットは正直ないですが再帰呼び出しを絡めるとよく使う考え方になるので一旦こういう書き方もできる程度で理解を勧めてください

```typescript
Add(a: int, b: int): int = a + b

Sample(): void = 
  AddOneFromTen := Add(Add(Add(Add(Add(Add(Add(Add(Add(1, 2), 3), 4), 5), 6), 7), 8), 9), 10)
  Print("{AddOneFromTen}") // ← 55が出力される
```

嫌なコードですよね。
実際こんな計算することはないですが可読性も悪いですし、保守性も悪いです。

この処理をリファクタリングするとしたらこういう形が一般的です

```typescript
AddAfromB(a: int, b: int): int = 
  if(a > b):
    return 0
  return a + AddAfromB(a + 1, b)

Sample(): void = 
  AddOneFromTen := AddAfromB(1, 10)
  Print("{AddOneFromTen}") // ← 55が出力される
```

この処理は再帰呼び出しを利用したアプローチでaがb以上になるまでAddAfromBは関数内で呼び出されます。
そのためfor文を書かずともループしているような処理が実行でき、aがb以上になった時点で0を返し再帰呼び出しは止まります。

再帰呼び出しは関数型言語で抑えたい設計手法ではありますが、可読性が良いかと呼ばれると微妙なところです。
（慣れている人やプログラマは問題ないと思いますがVerseの思想上誰でも書けること、は大事なファクタとして書いていきます）

ではこの処理をメソッドチェーンを使った実装に修正してみましょう

```typescript
(Input: int).Add(value: int): int = Input + value

Sample(): void =
  AddOneFromTen := 1.Add(2).Add(3)
                    .Add(4).Add(5)
                    .Add(6).Add(7)
                    .Add(8).Add(9)
                    .Add(10)
  Print("{AddOneFromTen}") // ← 55が出力される
```

いかがですか？
先程のコードより若干直感的に感じるのではないでしょうか。
再帰呼び出しの処理のようにaからbまでを加算する、といった要件は満たせないですが加算する数字が決まっている場合はこちらのほうが使いやすいかもしれません。

正直再帰呼び出しでもメソッドチェーンでもfor文ループでもわかりやすい方法であればどちらでも良いかなとは思ってます（メモリパフォーマンスなどは度外視）がこのあとの記事で紹介していきたいと考えているデザインパターンで多用する内容になっているので覚えていただけると幸いです。

## おまけ
こんなこともできます

```typescript
(Input: int).Print(): int = 
  Print("{Input}")
  Input
(Input: int).Add(value: int): int = Input + value
(Input: int).Subtract(value: int): int = Input - value
(Input: int).Multiply(value: int): int = Input * value
(Input: int).Divide(value: int): int = 
  if(Result := Input / value):
    return Floor(Result)
  return 0

Sample(): void =
  Result := 10.Multiply(10).Subtract(20).Devide(2).Add(10)
```

Resultの値は何でしょうか？
メソッドチェーンは前から答えが評価されていくので答えは `50` なのですが、これを計算式にすると以下の数式です。

```
(((10 * 10) - 20) / 2) + 10
(10 * 10 - 20) / 2 + 10 // 計算優先度でカッコを省略した形
```

単純に計算式を書くとVerseでもカッコの処理が必要なため読み解くのにより数学的な考え方が必要になります。
メソッドチェーンの場合前から順番に処理の流れを追っていくだけで済むのでコードレビューや保守性も高くなるとおもいます。

## まとめ
今回紹介したアプローチはVerseにおける設計手法の一つのアプローチで必ずしも答えではないのでご注意ください。
使う場面によっては再帰呼出しやループを用いたほうがいいシーンももちろんあります。
ROS 2環境でRealSense D435を使ってRTAB-MAPを動かす

# はじめに


RealSense D435を使って　RTAB-MAPのROS 2パッケージを動かしてみた。

RTABMAP自体の説明について以下の記事や参考にある記事などを参照


https://qiita.com/k65c1/items/7a4df58b50a587fad3e2

https://github.com/introlab/rtabmap_ros







# 環境

|   |       |
|------------|--------------|
| ROS  | ROS 2 Humble       |
| OS         | Ubuntu 22.04.2 LTS |
| RealSense  | D435         |



# 事前準備

## RealSense をROS 2で使えるようにする

これらの記事を参考にしてRealSenseをROS2 Humble 環境で使えるようにしておく。

https://qiita.com/porizou1/items/9d44053dbce648f1470d

https://qiita.com/srs/items/9677f4128215c9021571


## rtabmap_ros のインストール

```bash
sudo apt install ros-humble-rtabmap-ros
```

## TurtleBot3のサンプルを動かす

動作確認のためTurtleBot シミュレータのサンプルを動かす。
TurtleBot シミュレーションとteleop-keyboardを起動。

```bash
export TURTLEBOT3_MODEL=waffle
ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py
```


```bash
export TURTLEBOT3_MODEL=waffle
ros2 run turtlebot3_teleop teleop_keyboard
```

rtabmapを起動。
これは入力が/scan のみの例、teleop_keyboardでTurtleBotを動かすとrtabmap vizの3D Mapにマップと軌跡が表示される。

```bash
ros2 launch rtabmap_demos turtlebot3_scan.launch.py
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399606/618a0c20-21bb-de6c-f140-2872b3a1de83.png)


# RealSenseで実行


realsense2_cameraの実行。align_depth.enable=trueにする。

```bash
ros2 launch realsense2_camera rs_launch.py align_depth.enable:=true
```

rtabmapの実行。　approx_sync:=trueにしないとエラーが出た。

```bash
ros2 launch rtabmap_launch rtabmap.launch.py frame_id:=camera_link args:="-d" rgb_topic:=/camera/color/image_raw depth_topic:=/camera/aligned_depth_to_color/image_raw camera_info_topic:=/camera/color/camera_info approx_sync:=true
```

ToDo : 実行時のrtabmap vizの画像を貼る


- rqt_graph

![rosgraph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399606/222a8d98-8c8c-f42f-65f4-3cca1b02dd7a.png)


# おわりに

最新のROS 2 Humble環境でRealSenseを使って エラーなくRTAB-MAPを動かすことができた。
以前はソースからビルドが必要だったがバイナリインストールできるようになっていたので動かすまで簡単にできた。

IMUがないと回転に弱いので次はIMU付いたRealSenseを使って試したい。


# IMUを使用して実行する手順

D455で動かしたが、多分D435iでも同じ

```
ros2 launch realsense2_camera rs_launch.py enable_gyro:=true enable_accel:=true unite_imu_method:=1 enable_sync:=true depth_module.profile:="640,480,30" rgb_camera.profile:="640,480,30"
```

exemplesにあるlaunchファイルをそのまま使用

```
 ros2 launch rtabmap_examples realsense_d435i_color.launch.py 
```


![rosgraph_imu_rtabmap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399606/4474f55c-7ae0-ebc6-63c7-22d553d795ec.png)


RealSenseの内蔵IMUについてはこちらの記事に書きました。

https://qiita.com/porizou1/items/6ecc89d218502ad6fe68

# 参考

https://qiita.com/k65c1/items/0d9039c021ecbb26b04e


https://zenn.dev/karaage0703/articles/8e3e84c0fe45ba


https://qiita.com/k65c1/items/7a4df58b50a587fad3e2


http://wiki.ros.org/rtabmap_ros

https://qiita.com/porizou1/items/ad730b7f6ac87d9a0304
【超初学者向け】VScode拡張機能まとめ

### 主にRailsでコーディングするときに便利な拡張機能まとめ
- Auto Close Tag
    - 閉じタグ勝手に書いてくれる
- Code Spell Checker
    - 変数名とかが英単語として正しいスペルかチェックしてくれる
- endwise
    - endを勝手に書いてくれる
- Highlight Matching Tag
    - ペアになってる開始タグと閉じタグを見やすくカラーリングしてくれる
- HTML End Tag Labels
    - 閉じタグに開始タグの名称を表示してくれる
- indent-rainbow
    - インデントレインボー
- Rails DB Schema
    - schemaからdb関連の予測変換
- Rainbow End
    - rubyファイルの開始と終了をカラーリング
- Beautify
    - erbファイルのフォーマットとかできる
- RuboCop
    - rubyファイルのフォーマット
- SQLite Viewer
    - SQLファイルの中身を直接vscodeから見れる最高
- Trailing Spaces
    - 邪魔な余白あれば赤くしてくれる
    - ctrl + shift + p 押して「Trailing Spaces: Delete」というのを選べば自動で削除
### 拡張機能ではないが、自分が使ってるツール紹介
- [Warp](https://qiita.com/miruon/items/2c7c2b3da40722f91fbc)
    - ターミナル
    - mac限定かもmac買え
    - ターミナルで予測変換が使える
    - マウスによるカーソル移動が可能
- [Cursor](https://zenn.dev/gamuprog/articles/53e7adee04b337)
    - AIを使った最強Editor
    - 正直vscodeもう使わん
    - vscodeベースになっているのでvscodeからの引き継ぎが楽
    - 単純にvscodeにAIが乗って使いやすくなった
    - 拡張機能等もそのまま引き継げる
秒でわかるM5stackの開発環境

# #1 はじめに
メリークリスマス！！←早くない？？
いかがお過ごしでしょうか！！
僕はめちゃくちゃ元気ですよーー！！←風邪引いてます
:santa:｛今日はみんなにささやかなプレゼントを贈るよ！！）
今回はM5stackの開発環境についてまとめてみました。
# #2 M5stackとは
M5stackとはディスプレイ付きの小型マイコンボードです。
ディスプレイにボタンやスピーカー、Groveポートなどが内蔵されているので
とても便利で使いやすいです。
M5stackの本体が6000円～10000円とRaspberryPiと比べると少しお手頃です。
Groveポートが内蔵されているので、
電子回路の知識なくセンサーやサーボモーターなどを接続できて拡張性が高いです。
# #3 M5stackの開発環境
### Arduino IDE
https://www.arduino.cc/en/software

マイコンボードでお馴染みのArduino IDEです。
C言語がベースとなっています。
### PlatformIO
https://platformio.org/

こちらはマイコンボードの開発ができるVScodeのプラグインです。
特別な環境を構築する必要がなく、いつものVScodeにこのプラグインを導入するだけで、
マイコンボードの開発を簡単に行うことができます。
### UIFlow
https://m5stack.com/uiflow
こちらはScratchのようにビジュアルプログラミングで
M5stackを開発することができるソフトです。
こちらは一度、M5Burnerでファームウェアを書き込む必要があります。
（M5GOの場合は不要）
# #4 さいごに
今回はM5stackの開発環境についてまとめてみました。
この記事が皆さんの助けになれば幸いです。
Ansible で Python スクリプトを実行する

### はじめに

Ansible でターゲットのシステムに対して Python コマンドでスクリプトを実行する時、複数のバージョンの Python がインストールされていて、意図した通りに処理が実行されない場合があります。今回は Ansible が参照する Python とその Python でスクリプトを実行する方法を紹介します。

### Ansible が利用する Python のパスを取得する

Ansible が取得する Python のパスを 取得します。

```yaml:リモートホストに対して実行する場合
- name: Gather facts from remote host
  ansible.builtin.setup:
  register: results

- name: Execute selenium on remote host
  ansible.builtin.command:
    cmd: "{{ results.ansible_facts.ansible_python.executable }} script.py"
```

```yaml:ローカルに対して実行する場合
- name: Gather facts
  ansible.builtin.setup:
  register: results
  delegate_to: localhost

- name: Execute selenium
  ansible.builtin.command:
    cmd: "{{ results.ansible_facts.ansible_python.executable }} script.py"
  delegate_to: localhost
```

この方法で利用する Python を限定することができます。

### 実践例 Ansible から Selenium を実行する

Ansible から Selenium を実行するサンプルです。動作確認は Ubuntu 22.04 lts で行っています。事前に Ubuntu に Docker をインストールし pip で ansible ・docker・selenium をインストールしておきます。

```yaml:selenium.yml
---
- name: Create
  hosts: localhost
  connection: local

  tasks:
    - name: Setup Selenium container
      community.docker.docker_container:
        name: selenium
        image: selenium/standalone-firefox:latest
        ports:
          - '4444:4444'
        state: started

    - name: Gather facts
      ansible.builtin.setup:
      register: results

    - name: Execute selenium
      ansible.builtin.command:
        cmd: "{{ results.ansible_facts.ansible_python.executable }} selenium.py"
      args:
        chdir: files
      changed_when: false
```

```python:selenium.py
import os
from selenium import webdriver
from selenium.webdriver.firefox.options import Options

# Setting up headless Firefox options
options = Options()

driver = webdriver.Remote(
    command_executor='http://localhost:4444/wd/hub',
    options=options
)

driver.get(target_url)

w = driver.execute_script("return document.body.scrollWidth;")
h = driver.execute_script("return document.body.scrollHeight;")
driver.set_window_rect(width=w, height=h)

filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "./screenshot.png")

driver.save_screenshot(filename)

driver.quit()
```

Selenium は Remote Container から実行されます。対象のサーバーの定期的なスクリーンショットが必要な場面、Ansible playbook 実行時の UIテストが必要な場面などで役に立つでしょう。

### 参考サイト

* [ansible-playbooks-mamono210/wordpress_install | GitHub](https://github.com/ansible-playbooks-mamono210/wordpress_install) これらの処理を実際に導入しているAnsible playbook のコードサンプル
認証基盤（SAML）について

# SSO、SAMLに関する説明

## Overview 
皆さんは、色んなのサイトを利用すると、以下のことを経験したことがあると思う。
本！人！確！認！
では、本人認証とは？
地球ではそれぞれの人が存在、個人の性質があると思う。
しかし、何を基準にして個人だと判断できるだろうか？
外面的な部分で判断できますが、住所、Eメール、電話番号、名前など多様に存在するだろう。
これらを個人情報あるいは個人データと呼ぶ。
そのような情報を用いて特定の者が本人であることを証明するのが本人認証であるということである。

## SSO（Single Sign On)
### SSOとは
:::note info
一度のユーザ認証処理によって、独立した複数のソフトウェアシステム上のリソースが利用可能になる機能または環境である。シングルサインオンによって、ユーザはシステムごとにユーザIDとパスワードの組を入力する必要がなくなる。
:::
代表的に以下のものがある
* Google Accounts
* Facebook Login
* Twitter

SSOを構築することは色んな方でできるが、代表的なモデル式は二つがある。

1\. Delegation Model
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958484/4fc4781e-742b-3ae0-dddf-08a0bc1eb426.png)

対象アプリケーションの認証方式を変更することが困難な場合によく使用
対象アプリケーションの認証方式を全く変更せず、ユーザの対象アプリケーション認証情報をエージェントが管理してユーザの代わりにログオンする方式

2\. Propagation Model
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958484/8b9c0172-fe89-1e86-f157-c54ede8177e4.png)

統合認証を遂行するところで認証を受け、対象アプリケーションで伝達するトークン(Token)を発給を受ける。
対象アプリケーションに使用者が接近する時トークンを自動的に転送し、対象アプリケーションが使用者を確認できるようにする方式

3\. Delegation & Propagation Model(混在）
ウェブ環境だとしても、Propagation方式が全て適用されるわけではない。 
特にウェブアプリケーションの変更が全く不可能で、ユーザー統合が難しい場合、Delegation方式を使用することになる。 
また、対象アプリケーションが多く、アプリケーションの特性が多様な場合、各アプリケーションにDelegation方式とPropagation方式を混用してシステム全体のSSOを構成する


そうしたらSSOシステムはどうやって具現できるか？
代表的に使っているは、以下の三つが存在する。
* SAML
* OAuth
* OIDC

今回ではSAMLに関して説明をする。
### SAMLとは
:::note info
Security Assertion Markup Language は、特にアイデンティティプロバイダーとサービスプロバイダーの間で認証および認可データを交換するための公開標準である。SAML は、セキュリティアサーション のための XML ベースのマークアップ言語である。
:::
代表的にSAMLに関して対応できるサービスは以下のものがある
* Okta
* OneLogin
* ADFS

SAMLでは、3つの役割があって、重点的に理解すればよい。
* User:クライアント
* Service Povider サービス プロバイダー
* Identity Provider 認証情報提供者

SAML認証フローは上のそれぞれを役割を利用して使用されます。
#### SAML認証フロー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958484/38263f08-51de-e6bf-86b6-8f2eb90c5a4d.png)

1\. サービス要請
* ユーザがサービスにアクセス、SPは当該ユーザが認証の有無をチェックする。

2\. SSOサービス遷移
* 認証されていないユーザーの場合は、認証要求を作成してクライアントに転送する。
* SPでSAMLRequestを生成してユーザーに転送する。
* SPはIDPと直接接続されず、クライアントのブラウザからIDPへSAMLRequestをredirectする。

3\. SSOサービス要請（リクエスト）
* IDPはSAMLRequestをパーシングし、ユーザー認証を進行する。
* 認証方式はパスワードPKIなど多様に使用する。

4\. SAML応答
* 認証が成功するとSAMLResponseを生成、 ユーザーのブラウザに転送する。
* SAMLResponseにはSAMLAssertionが格納される。(XML形式)
* IDPはウェブブラウゼSession Cokkieを設定、その情報はブラウザにキャッシュ

5\. (POST)SAML応答転送
* ユーザはSPのACS(Assertion Consumer Service)のURL内にSAMLResponseをPOST形式で送信する。

6\. サービス応答
* ACSはSAMLResponseを検証し、有効であればユーザーが要請したサービスでユーザーをForwardingする。
* ログインが成功する。

### SAMLに関する長所と短所
#### 長所
* アプリケーションとサービスにより簡単にログインすることはもちろん、ユーザーの生産性向上にも効果的
* 様々なログインを繰り返すとパスワードを簡単に忘れることができ、さらにはパスワードを紙に書いておいて資格証明の盗難リスクが増加、一つのユーザー名とパスワードだけ知っていればいい
* 資格情報が直接送信されるため、フィッシングやアイデンティティ奪取の可能性が最小限
* 開発コスト（専用認証方式と主に関連がある）を最小限に抑えるのにも効果的
* 各ユーザーを単一ディレクトリで管理するため、ユーザー管理が容易

#### 短所
* SAMLRequest,SAMLResponseはXML形式であるためブラウザでのみ動作が可能である
* モバイルやNative Applicationには使用を推奨しない。

# 終わりに
ここまでSSOとSAMLは何なのかを説明をしました。
今後は、実査に構築して、実装する方法と開発過程を記載したいと思う。
（Ruby on Railsでログインする時にOneLoginでログインする作業を行う予定。）