OmniAICreator/Qiita-1.07M huggingface dataset:
富岳のspack0.19版python3.10でtransformersをムリヤリ動かすには

[昨日の日記](https://qiita.com/KoichiYasuoka/items/521087a76186b4432145)の続きだが、富岳のspack0.19版python3.10で[tokenizers](https://huggingface.co/docs/tokenizers)が動かない理由は、rustの[スレッド周り](https://github.com/rust-lang/rust/blob/1.75.0/library/std/src/sys/unix/thread.rs#L102)にある。`fcc`(富岳の`gcc`もどき)はスレッドをサポートしているので、そこはrustコンパイラをうまく繋いでやればいいのだが、私(安岡孝一)の力不足でうまく繋げない。ならば`TOKENIZERS_PARALLELISM=false`で、tokenizersにスレッドを使わせないようにすれば、何とか[transformers](https://huggingface.co/docs/transformers)が動くんじゃないだろうか。[12月27日の記事](https://qiita.com/KoichiYasuoka/items/73c1f0bc69101dd03386)のプログラムを、富岳のspack0.19に移し替えてみよう。

```
#! /bin/bash
#PJM -L rscgrp=small
#PJM -L elapse=1:00:00
#PJM -L node=1
#PJM -j
#PJM -S

. /vol0004/apps/oss/spack/share/spack/setup-env.sh
spack load py-torch@1.13.0/glqavnh
G=`id | sed 's/^.*gid=[0-9]*(\([^)]*\)).*$/\1/'`
set `ls -d /vol*/$G /vol*/data/$G` $HOME
export PYTHONUSERBASE=$1/PyTorch-1.13.0
export PATH=$PYTHONUSERBASE/bin:$PATH
export HF_HOME=$PYTHONUSERBASE
export TMPDIR=$PYTHONUSERBASE/tmp
mkdir -p $TMPDIR
pip3 install -U transformers --user

P=$TMPDIR/fillmask.$PJM_JOBID.$$.py
cat << 'EOF' > $P
from transformers import pipeline
fmp=pipeline("fill-mask","KoichiYasuoka/deberta-large-japanese-aozora")
print(fmp("夜の底が[MASK]なった。"))
EOF
env TOKENIZERS_PARALLELISM=false python3 $P
```

富岳のログインノードから`pjsub`してみたところ、ジョブ待ち・インストール・ダウンロード等も含め、20分ほどで以下の結果が得られた。

> [{'score': 0.10754115134477615, 'token': 2113, 'token_str': '白く', 'sequence': '夜の底が白くなった。'}, {'score': 0.041453491896390915, 'token': 298, 'token_str': '重', 'sequence': '夜の底が重なった。'}, {'score': 0.03892168030142784, 'token': 3504, 'token_str': '黒く', 'sequence': '夜の底が黒くなった。'}, {'score': 0.0380183570086956, 'token': 114, 'token_str': 'どう', 'sequence': '夜の底がどうなった。'}, {'score': 0.03193163871765137, 'token': 3520, 'token_str': 'わるく', 'sequence': '夜の底がわるくなった。'}]

rustのスレッド周りを避ければ、一応transformersが動くようだ。tokenizersが遅くなるのさえガマンすれば、これで富岳のPyTorch-1.13.0が使えるかな。
【プラクティス紹介】1分でさらっと分かる「焼肉レトロスペクティブ」

## プラクティス名
焼肉レトロスペクティブ

## プラクティスの目的・狙い
* ふりかえりを楽しく行う
* 出来事や反省点を面白く伝える

## どんな時に使うか
* いつもと一味違う遊び心のあるふりかえりをしたい時

## 実施手順
1. 焼肉の楽しそうな画像を、ホワイトボードに大きくどーんと貼り出す
1. ふりかえる期間の出来事を、**焼肉に喩えながら**付箋に書き出す
1. 付箋の内容を紹介する

ルールはたったこれだけ。果たしてその効果は？
* 楽しい、盛り上がる（焼肉に喩えることで反省もネガティブにならずに済む）
* 他の人が書いた付箋に「これって何を表現したの？」と自然と興味が湧く
* 最終的に出来上がったボードに機密情報が含まれないので、どこにでも貼れる

| 付箋の記入例 | その意味 |
|:-:|:--|
| 肉を注文しすぎた  | → タスクを取りすぎた  |
| 肉を焼きすぎた  | → 過剰な作り込みを行ってしまった  |
| タレが旨かった  | → アレンジした箇所が好評だった  |

※このプラクティスの考案者はSatoshi HaradaさんとTeamYAKINIKUの皆様で、A-CSM研修をきっかけに誕生した手法とのことです。

## アレンジ例
* 全員で「いただきます！」で始めて「ごちそうさまでした！」で締める
* ふりかえりのふりかえりを「二次会」と呼ぶ

## アンチパターン
* 「焼肉に喩える」のに悩みすぎて付箋の書き出しがすすまない
（→焼肉力が問われるため、詳しくない人がいる場合は発想しやすいように用語が載っているメニュー表などを渡しておくといいかもしれません）

## 参考情報

僕の要約版の文量ですとこのプラクティスの楽しさがイマイチ伝わらないと思いますので、興味がある方は是非、原典である下記の記事をご参照下さい。

https://agile.hatenadiary.com/entry/2023/10/09/110843

Qiitaでも体験談があがっておりましたので、併せてご紹介しておきます。

https://qiita.com/Sicut_study/items/597a061401600bb07468

## こぼれ話（私的コメント）
本稿は考案者の一人であるHarada様の許可を得て、記事にしております。
[RSGT2024にもご登壇](https://speakerdeck.com/psj59129/shao-rou-retorosupekuteibubao-dan-you-bixin-wojie-fang-sitetimunoxue-xi-wofei-yue-saseyou)され、この手法の狙いや効果を説明されていました。決してノリと勢いだけで出来たワケではなく、その裏には明確な意図と理屈がありました。
メタファーを使ったふりかえりプラクティスで「セイルボート」というものがあります。チームをボートに喩えると、追い風にあたるものは何だろう？岩礁にあたるものは？と考えることで脳のイマジネーションを引き出す手法ですが、この応用版とも言えます。焼肉と聞くと思わずテンションが上がってしまう日本人の習性を利用した秀逸なメタファーだと思います。こういった日本オリジナルのプラクティスがどんどん世に広まっていくといいなと思います♪

懸念点があるとしたらこの手法をよく知らないエライ人から「ちゃんとやれ」と言われそうなことでしょうか。その点もHaradaさんが発表の中で「そもそもちゃんとしたふりかえりとは？」で補足されていましたが、何も真面目な顔で反省点を挙げていくだけが効果的なアプローチではないハズです。

それでは皆様、よい焼肉を！

---
【2024/6/24追記】
先日行われたスクフェス大阪2024・虎ノ門トラックにて、焼肉レトロの続編（？）ともいえる発表がありました！　登壇者はHarada様のご同僚であるshimitaka様。こちらもかなり面白いのでオススメです！　会場も大いに沸いておりました♪

[焼肉役員会議爆誕！老舗製造業で30人の役員相手に「アジャイルとは美味しい焼肉を食べること」とプレゼンした話](https://www.docswell.com/s/shimitaka/58G412-2024-06-22-155023)

---
　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)
Swiftでラジオボタンのような挙動のボタン実装方法！(XIB・StoryBoard)

### 0.完成した例
![gamen_test1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3660939/b0d817c0-8933-2b28-23a8-d3e31dc7713a.gif)


### 1.新たなカスタムクラスを作る
##### -1.Swift Fileを選択
![スクリーンショット 2024-01-13 11.24.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3660939/190c38e1-deed-dc94-21e2-40fad04f8c82.png)
##### -2.ファイル名は今回「RadioBtn.swift」とします。
![スクリーンショット 2024-01-13 11.23.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3660939/c1d40d3b-a154-de87-0f84-62f57f93c92f.png)


### 2.RadioBtn.swiftに下記コードを記述
```swift
import UIKit

@IBDesignable
class RadioBtn: UIButton {
    @IBInspectable var group: String?

    // ラジオボタンの初期化
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupRadioButton()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupRadioButton()
    }

    private func setupRadioButton() {
        self.setImage(UIImage(named: "RadioButton-Unselected"), for: .normal)
        self.setImage(UIImage(named: "RadioButton-Selected"), for: .selected)
        self.addTarget(self, action: #selector(radioButtonTapped), for: .touchUpInside)

    }

    @objc private func radioButtonTapped() {
        isSelected = true // タップされたラジオボタンを選択状態にする

        // 同じグループ内の他のラジオボタンを選択解除にする
        if let group = group {
            for view in superview?.subviews ?? [] {
                if let radioButton = view as? RadioBtn, radioButton.group == group && radioButton != self {
                    radioButton.isSelected = false
                }
            }
        }
    }

}


```
### 3.StoryBoard上でUIボタンを複数配置し、作ったクラスを継承させる。
##### -1.ボタンを複数配置する。
![スクリーンショット 2024-01-13 11.29.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3660939/f4803cef-83be-550e-a8bb-7edaf8d28bfa.png)

##### -2.グルーピングしたいラジオボタンを全選択する
![スクリーンショット 2024-01-13 11.33.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3660939/599816c7-27e6-75b9-62be-01b96c0c06bb.png)
※storyboardの画面左側のツリーから選択するとやりやすいです。

##### -3.その状態でXcode右側の[Identity Inspection]で先程作ったクラスを継承させる。
![スクリーンショット 2024-01-13 11.35.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3660939/172919e0-eccb-1452-6624-76a1df1f1993.png)

##### -4.[Attributes Inspector]タブに新たなプロパティが付与されている。
![スクリーンショット 2024-01-14 0.48.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3660939/a17db9a0-b87d-104a-5c09-824d2382dcf3.png)


:::note warn
【Groupプロパティ】
グルーピングしたいラジオボタンに任意のグループ名をつけてください
:::



※補足
```swift
@IBInspectable var プロパティ
```
→StoryBoard上で直接プロパティを変更できるようになる。

```swift
@IBDesignable MyClass {}
```
→StoryBoardのプロパティ上で変更した内容が、リアルタイムでStoryBoardに反映される。
InDesignドキュメントのカラープロファイルを表示するjsx

PhotoshopやIllustratorと違って、InDesignは「単にドキュメントのカラープロファイルを確認する」だけの安全な手段が無いようです（あったら教えて）

:::note info 
Illustratorはドキュメント情報から、Photoshopは情報パネルほかから確認できます。
:::

:::note
安全、というのは、操作ミスが起きない確認方法、という意味です。プロファイルの指定やプロファイル変換ダイアログからの確認は、うっかりOKボタンを押す可能性が少しでもあるので勧められません。
:::

以下のコードを〜.jsxと名前をつけて、InDesignのスクリプトフォルダに保存します。

:::note 
フォルダはInDesignスクリプトパネルから開いてください。ユーザフォルダを右クリック。
![SS_CleanShot_20240113-122950.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35477/17f60cca-1bae-e2b8-1ad7-d78e17251f22.png)

:::
```javascript
function getProfileStatus(docProfile, defProfile) {
    if (!docProfile) {
        return "⚠️タグなし\n作業用（" + defProfile + "）を一時的に使用";
    } else if (docProfile === defProfile) {
        return "🙂作業用と同じ（" + docProfile + "）";
    } else {
        return docProfile + "\n⚠️作業用（" + defProfile + "）と異なります";
    }
}

function getPolicyDescription(docPolicy) {
    var policies = {
        "COLOR_POLICY_OFF": "✅オフ（作業用を使用）",
        "COMBINATION_OF_PRESERVE_AND_SAFE_CMYK": "✅CMYK値保持（画像プロファイル破棄）",
        "CONVERT_TO_WORKING_SPACE": "⚠️作業用に全変換",
        "PRESERVE_EMBEDDED_PROFILES": "➡️埋め込みを保持"
    };
    return policies[docPolicy] || docPolicy;
}

function getDocumentAndApplicationColorSettings() {
    var myDoc = app.activeDocument;
    var myCol = app.colorSettings;

    return {
        defCMYK: myCol.workingSpaceCMYK,
        docCMYK: myDoc.cmykProfile,
        defRGB: myCol.workingSpaceRGB,
        docRGB: myDoc.rgbProfile,
        docCMYKPolicy: getPolicyDescription(myDoc.cmykPolicy.toString()),
        docRGBPolicy: getPolicyDescription(myDoc.rgbPolicy.toString())
    };
}

function displayColorProfilesAndPolicies() {
    var colorSettings = getDocumentAndApplicationColorSettings();

    var cmykStatus = getProfileStatus(colorSettings.docCMYK, colorSettings.defCMYK);
    var rgbStatus = getProfileStatus(colorSettings.docRGB, colorSettings.defRGB);

    alert("ドキュメントのカラー設定\n■■■■■ CMYK ■■■■■\n" + cmykStatus + "\n\n■■■■■ RGB ■■■■■\n" + rgbStatus + "\n\n\n■ ドキュメントのポリシー ■\n■■CMYK■■\n" + colorSettings.docCMYKPolicy + "\n\n■■RGB■■\n" + colorSettings.docRGBPolicy);
}

displayColorProfilesAndPolicies();

```

実行するとこうなります。

![246979699324.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35477/97b103a5-1fd5-a811-522f-ea8bf81281e0.png)

:::note
※InDesignドキュメントにカラーマネジメントポリシーが埋め込まれます。
開く際に作業用との差や、ポリシーに沿って（アラートオンなら）処理方法を聞かれます。

破棄・オフ：作業用を使用
カラー値を保持（プロファイル破棄）：数値が変わってはいけないCMYK用のポリシー
作業用に変換：これやると、CMYKドキュメントのオブジェクトの数値も変わるので危険
埋め込みを保持：プロファイルが埋まっているなら保持
:::


:::note
ドキュメントにカラープロファイルが埋め込まれていない「タグなし」の場合、編集＞カラー設定で指定した作業用プロファイルが仮に使用されます。ドキュメントとプロファイルが紐付けされていないため、作業用プロファイルを変えるとドキュメントの表示もそれに合わせて変わります。
プロファイルが埋め込まれている＝ドキュメントとプロファイルが紐付けられている状態では、作業用プロファイルは関係ありません。
※一部の数値計算の表示に使われるだけです。
:::

:::note alert
コードはプロパティの取得方法をChatGPTに教えて書かせたものです。
:::
あっという間に！MAKEで名刺をGoogledrive＆Googlespreadsheetに残す！

# LINEを使って誰でもできる⁉ 

こんにちは！デジタルとは真逆を生きてきた私が、名刺＆商談記録を残す方法としてノーコードでLINEbotとMAKEを活用して作成しました！

今までは名刺を撮影し、商談相手の情報をエクセルへ打ち込むなんていう作業を行っていましたが、一日に何名もの方と商談したりデスクに座れなかったりと忙しい時は忘れてしまう…
もっと「楽」に「早く」できないかなぁ・・・と思い作成しました！
<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://twitter.com/hashtag/withmake?src=hash&amp;ref_src=twsrc%5Etfw">#withmake</a> <br>LINEで画像と文字を保存&amp;記録ができる！ <a href="https://t.co/4CoQmxUERE">pic.twitter.com/4CoQmxUERE</a></p>&mdash; ｍ0526579 (@m0526579) <a href="https://twitter.com/m0526579/status/1746008041743622148?ref_src=twsrc%5Etfw">January 13, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 使用ツール
・Make
・Google SpreadSheet
・Google Drive
・LINE Developers　　

### こんな感じ



LINEはこんな感じ（スクショ）↓
![IMG_6840.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656665/ce476d98-0141-605e-177a-e9aca74416e6.jpeg)

#### MAKEのシナリオはこちら↓
![25スクリーンショット (16).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656665/9c1289e0-3c79-a59c-380e-4b737a2858ef.png)


##### ポイント：GoogleSpreadsheetとGoogledriveへ保存され、完了するとLINEから返信がきます。その中でLINEの機能も少し活用！（LINEカメラで撮影して文字化させる）


#### 【手順】
：使用API
Google drive
Google Spreadsheet

保存後にLINEbotから完了報告の返信がくるようにGoogle driveとGoogle sheetのどちらもLINEbotと連携しています。
こちらのqiita記事を参考にさせていただきました。

![22スクリーンショット (16).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656665/73341207-0cae-e6e0-7ad6-7e8a8dfc1981.png)







#### Google Spreadsheetモジュール(Add a Row) と　LINEモジュール（Send a Push Message）を作成し繋げます。
![25スクリーンショット (18).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656665/7311d518-0ecc-c7bd-523d-6fed2597b063.png)

#### Google driveモジュール（Download a Message Attachment）とLINEモジュール（Send a Push Message）を繋げます。
![24スクリーンショット (17).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656665/b6a580bc-83d2-221c-8573-27145f2aea7a.png)
##### Google Spreadsheetにこんな感じで記録されます！
![スクリーンショット (19).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656665/92b8d62f-aa6d-2239-e1d2-7bbafcdade70.png)
##### Google driveはこんな感じで保存されます！
![スクリーンショット (20).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656665/43cdf92e-44ee-f881-7798-4e031fb8365b.png)



##### LINEカメラで文字化
LINEカメラを開く
![IMG_6840.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656665/d7b2f2fe-6dc3-d0ce-1ce5-a88b0392890c.jpeg)
文字認証をタップ
![IMG_6843.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656665/1f0e40c3-d508-b762-f26b-520f9df3121e.jpeg)
文字認証したものを撮影しシェアをタップ
![IMG_6846.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656665/40c115ad-ac9a-3206-a2bc-12f8d65d2569.jpeg)

## 最後に
実際に活用してみて、数秒で画像の保存と記録を残せるのは感激しました！MAKEを知らずに生きてきたことを反省してます(笑)
また、デジタルと真逆を生きてきた私がここまでできるとは…ビックリです。

##### （作成に伴う反省点）
・作成中に右往左往して無駄な時間を過ごしてしまった。相談できる環境や同じように取り組む仲間がいたので、早めに相談等の対応を取るべきでした。

 ##### （実際に使用した上での反省点）
・画像を文字化認識する際に一発で行えればいいが、LINEカメラからの文字認識を活用しているため、若干の手間が発生している。
実際にはGoogle cloud vision のモジュール活用を検討する必要があるかもしれない。
%{X-Forwarded-For}i にはIPアドレスが1つだけ入ると思っていた話

プロキシを経由したアクセスでは、Apacheのログで `%h` にはプロキシサーバのIPアドレスが入る。
代理サーバの代理アクセスなので、常に同じIPアドレスが記録され、エンドユーザのIPアドレスが分からない。
そこで登場するのが、Apacheのアクセスログで言う `%{X-Forwarded-For}i` です。
これにより、プロキシサーバ経由でアクセスしてくる元のアクセスIPが分かります。

それを元に、 .htaccess などに

- 修正前

```
    RewriteCond %{REQUEST_URI} (^/admin)
    
    RewriteCond %{HTTP:X-Forwarded-For} !^11\.33\.44\.22$
    RewriteCond %{HTTP:X-Forwarded-For} !^11\.33\.44\.23$
    RewriteCond %{HTTP:X-Forwarded-For} !^11\.33\.44\.24$

    RewriteRule ^(.*)$ ? [F,L]
```

的な記述をすると、上記に記述したIPアドレス群以外からの `/admin` 配下へのアクセスに対して `403 Forbidden` を返すことができます。

#### 問題発生

ところが、「11.55.66.21 も対象に追加しておいて」と言われて同様の記述を追加したところ、 `11.55.66.21` からのアクセスに `403 Forbidden` が返ります。「？？？」 良く分かりません。

.htaccess に記述していたので、httpdの再起動等は不要なはずですが、とりあえず可能性の一つとして httpd の reload や restart を試してみました。状況は変わりません。


ssl.conf のアクセスログのフォーマットを、 common に `%{X-Forwarded-For}i` を追加したものに変更します。

```
CustomLog /var/log/httpd/ssl_access_log \
 "%h %l %u %t \"%r\" %>s %b \"%{X-Forwarded-For}i\"
```

すると、 ログの `%{X-Forwarded-For}i` にあたる部分に想定と違った値が入っていました。

#### 原因判明

```
n.n.n.n - - [12/Jan/2024:15:39:25 +0900]
 "GET /x.png HTTP/1.1" 200 1049 "19.59.169.17, 11.55.66.21"
```

**「11.55.66.21」でなく「19.59.169.17, 11.55.66.21」が入っていました。** （※ IP値は適当です）

「11.55.66.21」IPの持ち主でないので詳しくは分かりませんが、恐らく多段プロキシ的（多段串とか言われます）なもので、複数のIPが記述されているようです。

## これで謎は解けた

上述のRewriteCondで指定していた `!^11\.33\.44\.22$` は正規表現でIPアドレスの完全一致をしていたので正しく適用されなかったようです。

完全一致にしないという意図で`「^」「$」`を外し、 `!11\.33\.44\.22` としてしまうと、「111.33.44.22」「11.33.44.229」などが一致してしまうので、 
`!(^|[^0-9]11\.33\.44\.22($|[^0-9])`
などにする必要がありますね。

- 修正後

```
    RewriteCond %{REQUEST_URI} (^/admin)
    
    RewriteCond %{HTTP:X-Forwarded-For} !(^|[^0-9])11\.33\.44\.22($|[^0-9])
    RewriteCond %{HTTP:X-Forwarded-For} !(^|[^0-9])11\.33\.44\.23($|[^0-9])
    RewriteCond %{HTTP:X-Forwarded-For} !(^|[^0-9])11\.33\.44\.24($|[^0-9])
    RewriteCond %{HTTP:X-Forwarded-For} !(^|[^0-9])11\.55\.66\.24($|[^0-9])

    RewriteRule ^(.*)$ ? [F,L]
```

既存のIPアドレスが多段串経由に変化することはなさそうですが、
最初から正規表現を使っているものについては、
ことさら遅くなることはないような気がするので、全部同じ形にしまって良いのかな、と考えています。
サクっとchaliceでlambdaをデプロイするまで

# はじめに
サブシステムの開発などでスピード感をもって **lambda** をリリースしたい時がよくあります。
割と「あれ、どうやって環境構築したっけ？」ってなることが多いので、まとめることにしました。

**sam**でもいいですし、何を使ってデプロイするかはその組織や案件によって様々考えられると思いますが、私の場合は **chalice** でデプロイすることが多いので、今回は **chalice**　でデプロイするまでの流れを記述します。

# 技術
- python 3.12.1
- chalice 1.30.0

# 前提
AWSアカウントを所有していること

# 環境構築
1\. direnvインストール
goコンパイラが入っている場合
```bash
~/ $ git clone https://github.com/direnv/direnv
~/ $ cd direnv
direnv $ sudo make install
```

macの場合
```zsh
~/ $ brew install direnv
~/ $ brew install openssl readline sqlite3 xz zlib    # 依存関係のライブラリ
```

2\. direnvのバージョン確認
```bash
direnv version
```

これで、`バージョン`が表示されればOK

## 開発用環境変数設定
1\. .envrcファイル作成

```zsh
~/ $ cd hoge    #適当なファイルを作ったり git clone したり
hoge $ echo 'dotenv .env' > .envrc
```

2\. direnv適用
```bash
direnv allow
```

## 仮想環境作成
1\. 仮想環境を作成する
```zsh
hoge $ python -m venv .venv
```

※ 人によっては `python3 -m venv .venv` だったりするかも

2\. 仮想環境をアクティベート
```zsh
hoge $ source .venv/bin/activate
```

3\. pipアップデート
```zsh
# (venv)
hoge $ python -m pip install pip~=23.3.2
hoge $ python -m pip install --upgrade pip # 最新をインストールする場合
```
4\. pip-toolsインストール
```zsh
# (venv)
hoge $ pip install pip-tools
```

## requirements.txtのコンパイル
1\. requirements.txtの作成
```vim
certifi==2023.11.17
    # via requests
charset-normalizer==3.3.2
    # via requests
idna==3.6
    # via requests
requests==2.31.0
    # via -r requirements.in
urllib3==2.1.0
    # via requests
aws-lambda-powertools==2.31.0
```

2\. dev-requirements.inの作成
用途に合わせてdev-requirements.inを作成する
```vim
# dev-requirements.in

# Lambdaランタイムにあわせる
botocore==1.34.18
boto3==1.34.18
# https://pypi.org/project/botocore-stubs/#history
botocore-stubs==1.34.18
# https://pypi.org/project/boto3-stubs/
boto3-stubs[lambda]==1.34.18

# Lambdaレイヤーにあわせる
# https://pypi.org/project/aws-lambda-powertools/#history
aws-lambda-powertools[parser]==2.31.0

# https://pypi.org/project/chalice/#history
chalice~=1.30.0

# https://pypi.org/project/black/#history
black~=23.12.1

# https://pypi.org/project/flake8/#history
flake8~=7.0.0

# https://pypi.org/project/pipdeptree/#history
pipdeptree~=2.13.2

# https://pypi.org/project/pytest/
pytest~=7.4.4

# https://pypi.org/project/coverage/#history
coverage~=7.4.0

# https://pypi.org/project/locust/#history
locust~=2.20.1

# https://pypi.org/project/Faker/#history
Faker~=22.2.0
```

3\. dev-requirements.inをコンパイルしてdev-requirements.txtを作成する
```
hoge $ pip-compile dev-requirements.in
```

4\. dev-requirements.txtをインストールする
```zsh
hoge $ pip install -r dev-requirements.txt
```

5.\ chaliceプロジェクト作成
```zsh
chalice new-project project-name
```
project-nameというプロジェクトディレクトリが作成される。

## ローカルテスト
```zsh
# (venv)
hoge $ chalice local --stage dev
```

`Serving on http://127.0.0.1:8000`が出力されればOK

## デプロイ
環境を指定しない場合
```zsh
# (venv)
hoge $ chalice deploy
```

環境を指定する場合
```zsh
# (venv)
hoge $ chalice deploy --stage dev
hoge $ chalice deploy --stage stg
hoge $ chalice deploy --stage prd
```

# 最後に
個人的には一番手っ取り早くデプロイできると思っています。
特に `.chalice/config.json`　にサブネットやSG、IAMなども指定することができて、
DEV、STG、PRDなどもオブジェクト単位で分けて記述できるので便利です。
PowerShellでCSVの内容が重複していないか調べる

ファイル名が異なるが中身が完全に重複しているかもしれないファイル群があり、重複の有無をチェックすることなったので……
※レコード毎の比較であり並び順は考慮しない

workフォルダ内イメージ
```powershell
work\
    ├test.csv
    ├test2.csv
    ├test3.csv
    …
```
作業フォルダ設定
```powershell
#比較するCSVらがあるフォルダ
$work_path = "C:\Users\work"

Set-Location -Path $work_path

#作業フォルダ内で拡張子が.csvのみのファイルをフィルターして取得
$compare_files = Get-ChildItem -File -Filter *.csv
```

Compare-Objectでファイルの中身を比較できるみたいなので[^1] ループ処理で比較する

```powershell
$same_file = @() #csvの中身が重複しているファイル名を格納する
$end_check = @() #$refで比較済のファイルが$defでも比較されると作業量が2倍になるので、比較済のファイル名を格納する

$compare_files | % {
    
    $ref = $null
    $ref = $_
    $ref_size = $ref.Length


    $compare_files | % {
        $def = $_
        $def_size = $def.Length
        if(($def.Name -notin $end_check) -and ($ref_size -eq $def_size)){ #$refで比較済のファイルが$defである場合とサイズが異なる場合は比較をスキップ
                 #比較した結果($result)がnullであれば重複しているので$same_fileにファイル名を格納する
            $result = Compare-Object (Get-Content (join-path $work_path $ref.Name)) (Get-Content (join-path $work_path $def.Name))

            if(($null -eq $result) -and ($ref.Name -ne $def.Name)){$same_file += ($ref.Name + "_" + $def.Name) 
            }
        }
     }

        $end_check += $ref.Name
}

#重複しているファイル名らをテキストに出力
Set-Content -PassThru (Join-Path $work_path "same_file.txt") -Value $same_file
```

### 問題点
+ 各ファイルが数百行程度ならCompare-Objectはすぐ終わるが、数万行などになると遅い
+ レコードの並び順が一致しているか否かは判定してくれないので順序も比較したい場合は別に考慮する必要がある
+ そもそも重複するような管理をしなければいい
[^1]:https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/compare-object?view=powershell-7.4
新規でディスクをマウントする Ubuntu 20.04

VMware ESXi上やベアメタルのUbuntu環境、新規でハードディスクを追加することが多いです。
毎度調べてめちゃくちゃなマウントをしていたので、完結編として記載します

## 環境
* Ubuntu 20.04 (筆者はESXi上の仮想マシン)
* 今回はHDD/SSDを増設する前提で説明

## やること
* HDD/SDDを増設
* パーティション作成
* ファイルシステムの構築
* マウント処理

## やり方
### HDD/SSDを物理/仮想的に増設
### OSの入っているディスクを確認
```
df /home -h
```
自分の環境だと/dev/sdaが使用中のメインディスクになり、容量がぎりぎりなことが分かる

### 追加したディスクを確認
```
sudo parted -l
```
自分の環境だと/dev/sdbが追加されていることが分かる

### パーティション作成
ログが長いため入力するもののみ記載
```
$ sudo parted /dev/sdb
(parted) mklabel gpt           #ラベル作成
(parted) mkpart                #パーティション作成
Partition name? []?            #適当にEnter
File system type? [ext2]? xfs  #xfsと入力
Start? 0%                      #ディスクの最初0%と入力
End? 100%                      #ディスクの最後100%と入力
(parted) print                 #設定確認
(parted) quit　　　　　　　　　 #設定完了
```
これで作成できたはずなのでもう一度パーティション確認
```
sudo parted -l
```
今回だとsdb分がきちんと表示されていればOK

### ファイルシステムの構築
/dev/sdb1のところはもちろん環境に合わせて
```
sudo mkfs.ext4 /dev/sdb1
```

### マウント処理
```
sudo mkdir /mnt/data
sudo mount /dev/sdb1 /mnt/data
```
再起動してみるとこんな感じ(35GB追加の例)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532124/db512105-f7e7-38f8-345b-0ba3d0bbb0fb.png)



## おまけ 実行例
```
user@user:~/Desktop$ df /home -h
Filesystem Size Used Avail use% Mounted on
/dev/sda5  491G 440G   27G  95% /
```
```
user@user:~/Desktop$ sudo parted -l
Model: VMware Virtual Disk (scsi)
Disk /dev/ada: 537GB
sector Size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number  Start  End   Size  Type    File system  Flags
1       1049kB 538MB 537MB primary fat32        boot
2       539MB  537GB 536GB extended
3       539MB  537GB 536GB logical ext4

Error:  /dev/sdb: unrecognised disk label
Model: VMware Virtual Disk (scsi)
Disk /dev/adb: 500GB
sector Size (logical/physical): 512B/512B
Partition Table: unknown
Disk Flags:
```
ポートフォリオを作ってみた(2)

# ドメイン作成
以下の流れで説明をしていきます。前回は(1)環境説明をしたので、今回は(2)ドメイン作成を説明いたします。
(1)環境説明
(2)ドメイン作成
(3)サーバー構築
(4)デザイン検討
(5)コーディング
(6)公開


今回使うものは、[ネットオウル](https://www.netowl.jp/)になります。

ドメイン作成は全体の中で唯一お金がかかる部分になっています。なぜ、ネットオウルを選んだかですが、今回一番にこだわった部分は、以下の3つです。
(1)コストを極力抑えること
(2)できるだけ早くに構築できること
(3)拡張性を備えていること

(1)と(2)は分かりやすいですが、(3)については人それぞれであり、考え方が異なる部分ですよね。
私の場合は、新たにサイトを増やしたくなったとき対応しやすいこと、規模が大きくなったやサービスを変えたくなったときにサーバー移行しやすいことを「拡張性が高い」状態であると定義付けました。

今回、Public Cloud(AWS, Azure, GCP)を選択した場合、サーバー費用がかかってしまうので、無料で公開できるものを探しました。その結果、Cloud Flareを選びました。しかし、そうなるとドメインをCloud Flareで登録した場合、Cloud Flareから移行したくなった場合、ドメイン移行費用が発生する恐れがあります。そこで、ネットオウルでドメイン管理を行い、DNSはCloud Flareにしようと考えました。DNS移行であれば簡単にできます。

ドメインは様々なものがありますが、今回は.comからドメインを作ることにしました。新規取得・更新ともに安価だからです。.xyzなど、新規取得は安価だけれども更新は高いドメインもあるため、要注意です。

ネットオウルでのドメイン登録は非常に簡単で、
- (1)まずは会員登録を行います。
- (2)ログイン後、メンバー管理ツールにてスタードメイン管理 -> 新規取得にうつります。
- (3)使いたいドメインを入力して、ドメイン名チェックをクリックします。
- (4)下にチェック結果が表示されるので、取得したいドメイン名の「取得する」をクリックします。
- (5)レジストラからJPRSが選択されていることを確認して、契約年数・お支払い方法を選択。利用規約に同意をして、確認画面へをクリックします。
- (6)確認画面で決済が終われば、もうドメインが利用できるようになっています。

このように、ドメインを作るのは非常に簡単であり、コストも年額1,000円～3,000円程度で済みます。

プログラムの勉強をする上でドメインは必要ではないかもしれないですが、しかし、取得しておくとDNSやWebサーバーの勉強にも役立つのでおすすめです。
Amazon

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


[Amazon AppFlow](https://qiita.com/Keiji_otsubo/items/03bed8ce52e8d1544cf1)

+ [TODOの画面でAmazonconnectの音声が再生ができない:ほかのユーザーであれば、0：00/1：16と表示されるところが、そのユーザーは、0：00/0：00と表示されるようです。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Vhl6H)

:::note
Amazon connectを別でログインしていたようで、

サービスコンソール上でログインをすると解消したようです。
:::

+ [event relays : イベントリレー](https://qiita.com/Keiji_otsubo/items/3ff2e633e156f182071a)
【ChatGPT有＋DALL-E3】作品。シャボン玉に文字投影。プロンプト共有。


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

　今回は、作品発表です。ある記事からインスパイアされて、作成しました。プロンプト共有します。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
あしからず。
:::

　シャボン玉に
　　文字を投影というのは、
　　　下記の記事を読んで、
　　　　それを再現したくなり、
　　　　　やってみました。
[「はかなく美しい……」　シャボン膜を“凍結”させたスクリーン　北陸先端大の研究者らが開発](https://www.itmedia.co.jp/news/spv/2401/12/news046.html)

　こちらが今回の作品です。
![DALL·E 2024-01-12 12.26.42 - Beneath a frozen soap bubble, a projection device is set to project inwards, casting words onto the interior of the frozen bubble. In this scene, the .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/e0ad77d1-5537-ece1-e42e-1082845a51fc.png)

　ふつう、
　　シャボン玉は透明です。
　　　膜が光を反射して
　　　　見えるだけです。

　そんなものに
　　文字を投影できるのか？

　答えは、簡単です。
　　シャボン玉を凍結して、
　　　表面を凍らせれば、
　　　　投影可能になります。

　凍結したシャボン玉は
　　以前に描いていましたので、
　　　その応用になります。

　それで試行錯誤して、
　　ようやくプロンプトとして
　　　出せるようになりました。

　下記が
　　そのプロンプトです。
　　　“I LOVE YOU”の部分を
　　　　書き換えてみてください。

　残念ながら、
　　日本語はダメです。

English Prompt:
"Beneath a frozen soap bubble, a projection device is set to project inwards, casting words onto the interior of the frozen bubble. In this scene, the words 'I LOVE YOU' are projected onto the frozen soap bubble. The bubble, in its frozen state, allows the projection from within to create an enchanting visual effect on its icy-like surface."

Japanese Translation:
"凍結したシャボン玉の下に、内側に向けて投影装置が設置されており、凍結したシャボン玉の内側に言葉を投影しています。このシーンでは、「I LOVE YOU」という言葉が凍結したシャボン玉に投影されています。シャボン玉は凍結状態で、内部からの投影により、氷のような表面に魅力的な視覚効果を生み出しています。"

　どうでしょうか。

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

　今回は、ここまで。
AWS Application Discovery Serviceとは？の備忘録

## サービス説明
オンプレミスの環境やデータセンター内で実行されているアプリケーションやインフラストラクチャのマッピングおよび可視化を支援するサービスです。

### 何のために使う？
クラウドへの移行やアプリケーションの最適化、またはオンプレミス環境の動作状況の把握に向けて、収集した情報を基に計画を策定するのに役立ちます。

### 可視化するためにどんな情報を集めるのか？

#### サーバーおよび仮想マシン情報:
ホスト名やIPアドレス
オペレーティングシステムの種類とバージョン
インストールされているアプリケーションやサービス

#### ネットワークデバイス情報:
ルーターやスイッチの情報
ネットワークトポロジーおよび接続情報

#### ストレージデバイス情報:
ハードディスクやストレージアレイの情報
ファイルシステムの種類や容量

#### 仮想化プラットフォーム情報:
仮想化ホストやハイパーバイザーの情報
仮想マシンの構成情報

#### アプリケーション依存関係情報:

アプリケーションコンポーネント間の依存関係
データベースやサービスとの接続情報

#### パフォーマンスデータ:

CPU利用率、メモリ使用量、ネットワークトラフィックなどのパフォーマンスデータ

#### セキュリティ関連情報:
セキュリティグループやファイアウォールの設定
インストールされているセキュリティソフトウェア
sendgrid ムームードメイン さくらサーバー

現在、さくらサーバー、ムームードメインで利用している。
しかし、sendgridを利用し、gmailから送信させたい。

その場合の方法

# sengrid で利用したいドメインを追加し、情報を取得

![b1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/ebd2b279-e60d-cd2d-ca13-55e20591b9b5.png)

上記の HOSTは、すべてドメインを削除する必要があるので注意
例:

```
HOST
em7947.your.com	

VALUE
u123.wl123.sendgrid.net
```

だった場合

```
HOST
em7947

VALUE
u123.wl123.sendgrid.net
```

にする。


# ムームーDNSを使う

https://komish.com/archives/6054

最終的な設定はこんな感じ。

![b2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/90e6dae8-62ea-5390-6545-aa641b86c5c7.png)


_dmarc は
返信先のメールアドレスを設定しておいた方が良いので、
```
v=DMARC1; p=none; fo=1; rua=mailto:info@yourdomain.com
```

にしておく。

特に、
５．ムームードメインのネームサーバ(ムームーＤＮＳ)を使用するをチェック

を忘れないようにする。

こんな感じですね
【React】react-uuidの代わりにuuidを使おう

## はじめに

`react-uuid` の代替モジュールとして使える `uuid` について調べました。

## react-uuidは非推奨

Reactの教材にあった `$ npm install react-uuid` を実行したところ、以下のようなWarningが出ました。

```bash
$ npm install react-uuid
npm WARN deprecated react-uuid@2.0.0: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

added 1 package, and audited 273 packages in 2s

97 packages are looking for funding
  run `npm fund` for details
```

調べてみますと、`react-uuid`はすでに廃止されているようでした。

https://www.npmjs.com/package/react-uuid

## uuidの使用

代わりに `uuid` の使用が推奨されているようですので、こちらを使用します。

https://www.npmjs.com/package/uuid

```bash
$ npm install uuid
```

### 使用例

```
import { v4 as uuid } from "uuid";
```

```react
const newItem = {
    id: uuid(),
    text: "newText",
};
```

## 終わりに

WarningであってErrorではないので、もしかしたら`react-uuid`も使用できるかもしれないですが、`uuid`を使うに越したことはないと思います。
paiza.ioでelixir その278

# 概要
paiza.ioでelixirやってみた。
mnesiaやってみた。

# サンプルコード

```


:mnesia.start()
:mnesia.create_table(:a, [attributes: [:key, :value]])
:mnesia.transaction(fn() -> 
    :mnesia.write({:a, :a, 1}) 
end)
:mnesia.transaction(fn() -> 
    :mnesia.write({:a, :b, 2}) 
end)
:mnesia.transaction(fn() -> 
    :mnesia.write({:a, :c, 3}) 
end)
:ets.i(:a)
:mnesia.dump_to_textfile('test_data')
|>IO.inspect

:mnesia.stop

:mnesia.create_schema([node()])
:mnesia.start
:mnesia.load_textfile('test_data')
:ets.i(:a)
:mnesia.system_info


```

# 実行結果

```
<1   > {a,a,1}
<2   > {a,b,2}
<3   > {a,c,3}
EOT  (q)uit (p)Digits (k)ill /Regexp -->:ok

22:40:31.762 [info]  Application mnesia exited: :stopped
New table a
<1   > {a,a,1}
<2   > {a,b,2}
<3   > {a,c,3}
EOT  (q)uit (p)Digits (k)ill /Regexp -->===> System info in version "4.16.2", debug level = none <===
opt_disc. Directory "/workspace/Mnesia.nonode@nohost" is used.
use fallback at restart = false
running db nodes   = [nonode@nohost]
stopped db nodes   = [] 
master node tables = []
remote             = []
ram_copies         = [a]
disc_copies        = [schema]
disc_only_copies   = []
[{nonode@nohost,disc_copies}] = [schema]
[{nonode@nohost,ram_copies}] = [a]
4 transactions committed, 0 aborted, 0 restarted, 2 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []



```

# 成果物

https://paiza.io/projects/6nMKpEEx2_eJjHAmnTdMAg


以上。
【M2Mac】ストレージの「管理」ボタンが見当たらない

めちゃしょうもないけど30分くらい詰まったのでメモ

### 環境
- MacBookPro M2 Max
- macOS Sonoma 14.1.1

### 経緯
- flutterで開発していたとある日、iOSシミュレータを立ち上げようとしたら「unable to boot the simulator」のメッセージが出て立ち上がらなくなった。
- ググって出てきた参考ページ https://zenn.dev/blendthink/articles/111dfa86265a34 によると
- 「🍎」→「このMacについて」→「ストレージ」→「管理…」→「デベロッパ」・・・ と進んでいくらしいが、「管理…」ボタンが見当たらない。
![スクリーンショット 2024-01-13 10.52.29のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639188/361d8c13-21fd-55df-cad4-15a46bda95cb.png)


### 解決策
- ストレージの画面のデベロッパの「！」マークを押したら出てきた（赤矢印の箇所）
![スクリーンショット 2024-01-13 10.52.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639188/22224c6a-4ea6-03c2-ed7e-da16a40e4b36.png)

- 「Xcodeキャッシュ」と「プロジェクト・ビルド・データとインデックス」を削除して、再度シミュレータを起動
![スクリーンショット 2024-01-13 10.54.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639188/ed82e2a3-f041-6a5b-63d8-86cde471ae7c.png)

- 立ち上がった！
![スクリーンショット 2024-01-13 11.03.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639188/f287f1f4-0da7-02e9-1fae-629f0753da1b.png)


めでたしめでたし
【PyTorch】torch.solveをtorch.linalg.solveに置き換える

数年前に作ったリポジトリの `torch==1.7.0` を `torch==1.13.0` に置き換えていて気付いた `torch.solve` の仕様変更に関するメモ。

Pytorchでは、線型方程式 $\mathbf{A} \mathbf{X} = \mathbf{B}$ を解く（行列$\mathbf{A}$ と 行列orベクトル$\mathbf{B}$ から解 $\mathbf{X}$ を求める）ソルバーが提供されている。

`torch<=1.7` では `torch.solve` が利用可能で、`torch>=1.8` からは `torch.linalg.solve` が新しく利用できる。

ただし、

:::note warn
**`torch.solve` と `torch.linalg.solve` では引数と返り値が異なる**
:::

ことに注意する。

```py: torch==1.7.0
X, LU = torch.solve(B, A)
```

https://pytorch.org/docs/1.7.0/generated/torch.solve.html?highlight=solve#torch.solve

```py: torch==1.8.0
X = torch.linalg.solve(A, B)
LU = torch.lu(A)    # LU分解したい場合
```

https://pytorch.org/docs/1.8.0/linalg.html?highlight=solve#torch.linalg.solve

そしてさらに

:::note warn
`torch==1.9` から `torch.solve` の利用が非推奨
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882064/71e3225a-a416-a614-4dd2-051b32c88c47.png)

https://pytorch.org/docs/1.9.0/generated/torch.solve.html?highlight=solve#torch.solve

になり、

:::note alert
`torch>=1.12` では `torch.linalg.solve` に一本化されて `torch.solve` は使えない
:::

ことに注意。
ubuntu 22.04 desktop向けWi-Fi設定

# はじめに

余っていたPCにubuntu 22.04 desktopをインストールしたところ、ちょっとハマりポイントがあったのでメモ

## リブート後にWi-Fiが自動接続できない

症状としては、ログインすればWi-Fi接続ができるけど、rebootして放置状態だと自動接続されない。
この時、”Authentication Required System policy prevents modification of network settings for all users” というメッセージが出ている。

色々と調べたところ、```/etc/NetworkManager/system-connections/<SSID>.nmconnection```
に以下の設定（autoconnectとpermissions）を追加すれば回避できることがわかった

```
[connection]
autoconnect=true
permissions=
...
```

## 画面オフで切断されてしまう

症状としては、パワーマネージメントが入った時に切断されてしまう感じ。
以下のようにすれば回避できることがわかった。

```
$ cat /etc/network/if-up.d/wifi-power-management-off
#!/bin/sh

iwconfig wlp2s0 power off
$
```

## APから切断されてしまう

しばらく運用していたところ、APから切断されてしまい、再接続できなくなる事象が発生。
同じSSIDだが、BSSIDの違うAPに接続しようと試みて、PREV_AUTH_NOT_VALIDになっている。
電波状況でもしかしたら最初とは違うBSSIDに接続しようとすることがあるのかも。
色々調査してみたが良い方法が見つからず、別のAPに接続することで一旦回避することに。
３匹のインフラエンジニア

![GDPl6SxawAEsMzc.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565276/c7d8ebca-d837-8945-cf3f-bff795482c9b.jpeg)
![GDPl6S0a4AAw17Q.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565276/cb6a1261-772a-b1ad-9caf-3d701c35d6d0.jpeg)
![GDPl4jybAAA_dJg.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565276/0a6408fe-0b71-900c-3efa-c85231527a45.jpeg)
![GDPl5B9bUAAtV2a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565276/91adc71c-8d74-dace-cf0d-e7864bba2533.jpeg)
terraform planの実行時間を短くするTIPS

どーも、ogimanです。
最近、terraformを触る機会が多いです。
terraformを使い始めて思うこと・・・それは、terraform planの実行時間が長〜い！？


えっ！？一つのリソース変えただけなのに、まだ終わってないの？
えっ！？全然仕事が進まないのですけどー
えっ！？待ち時間に他のことやってしまいマルチタスクになって生産性落ちるんですけどー

terraformのディレクトリの構成が悪いのだとは思いますが、これにより開発の効率が非常に悪くなってます。

ということで、この問題を解決する方法をメモっときます。

# 目的
terraformの開発効率を上げる

# 誰向け
- terrraformを普段使っている方
- terraformの実行時間を短くしたい方

# 現状
terraformのリソースやtfファイルを修正と実装を繰り返しながら開発している。その度にterraform planやterraform applyを実行するが、1回の実行時間が1分以上掛かる

# 問題
1つ、2つのリソース変更を適用するだけなのにterraform全体に対してterraform planやterraform applyを実行している

# 対策
- 1つもしくは複数のリソース単位でterraform plan、terraform applyを実行する
- 1つのtfファイル単位でterraform plan、terraform applyを実行する


# 注意
- コマンド例に記載している *リソースタイプ* にはterraformの各providerのリソースタイプを指定します。[こちら](https://registry.terraform.io/browse/providers)から参照ください。
- コマンド例に記載している *リソース名* には任意のリソース名を指定してください。
- 後述しているコマンド例は `terraform plan` を実行していますが、`terraform apply` を実行する場合は`terraform plan` を`terraform apply` に置き換えてください。


# 実際のコマンド

**1つもしくは複数のリソース単位でterraform plan、terraform applyを実行する方法**


```bash
#　コマンド構文
## terraform plan -target={リソースタイプ.リソース名}
# 実行例
terraform plan -target={aws_iam_role.ogiman_ec2}
```

**複数のリソースを指定してterraform plan、terraform applyを実行する方法**

```bash
#　コマンド構文
## terraform plan \
##   -target=リソースタイプ.リソース名 \
##   -target=リソースタイプ.リソース名
# 実行例
terraform plan \
  -target=aws_iam_role.ogiman_ec2 \
  -target=aws_iam_role.ogiman_alb
```

もしくは

```bash
#　コマンド構文
## terraform plan -target={リソースタイプ(1).リソース名(1),リソースタイプ(2).リソース名(2)}
# 実行例
terraform plan -target={aws_iam_role.ogiman_ec2,aws_iam_role.ogiman_alb}
```

**1つのtfファイル単位でterraform plan、terraform applyを実行する方法**

```bash
# tfファイル名を変数へ設定
## tf="tfファイル名" 
tf="elb.tf"

# 以下のコマンドを実行して適用
terraform plan $(cat $tf | grep -E '^resource ' | tr -d '"' | awk '{printf("-target=%s.%s ",$2,$3);}')
```

以上です。
他にも効率的に開発刷る方法があればドシドシ情報お待ちしております。

ではではー


## 参考
- https://gist.github.com/mAster-rAdio/0749d320a3dffefad4df5629224cd808
Azure Functions の Timer Trigger を Curl で手動実行してみた

Azure Functions でタイマートリガーを使用しているとします。何らかの理由で、スケジュール済みの時間以外に手動実行したいケースがあったりします。そこで、タイマートリガーを Curl で手動実行してみました。

## 検証用 Azure Functions を用意

```bash:bash
prefix=mnrfunc
region=japaneast

az group create \
  --name ${prefix}-rg \
  --location $region

az storage account create \
  --name ${prefix}stor \
  --resource-group ${prefix}-rg \
  --sku Standard_LRS

az monitor log-analytics workspace create \
  --workspace-name ${prefix}-log \
  --resource-group ${prefix}-rg

az monitor app-insights component create \
  --app ${prefix}-ai \
  --location $region \
  --resource-group ${prefix}-rg \
  --workspace ${prefix}-log

az functionapp create \
  --name ${prefix} \
  --resource-group ${prefix}-rg \
  --consumption-plan-location $region \
  --runtime dotnet \
  --functions-version 4 \
  --storage-account ${prefix}stor \
  --app-insights ${prefix}-ai \
  --https-only \
  --os-type Linux
```

## ローカルでタイマートリガーの Functions を作成

```bash:bash
func init $prefix --dotnet

cd $prefix

func new --name sample --template "Timer trigger"

func start

func azure functionapp publish $prefix
```

こちらが、作成されたコードです。

```csharp:sample.cs
using System;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;

namespace mnrfunc
{
    public class sample
    {
        [FunctionName("sample")]
        public void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
        {
            log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
        }
    }
}
```


## Curl で Azure Functions を手動実行

下記の `input` に設定する値は何でも良いみたいです。

```bash:bash
masterkey=$(az functionapp keys list \
  --name ${prefix} \
  --resource-group ${prefix}-rg \
  --query masterKey \
  --output tsv)

curl -i https://$prefix.azurewebsites.net/admin/functions/sample \
  -H "x-functions-key: $masterkey" \
  -H "Content-Type: application/json" \
  -d '{ "input": "test" }'

HTTP/2 202 
date: Sat, 13 Jan 2024 00:36:40 GMT
server: Kestrel
content-length: 0
request-context: appId=cid-v1:2b3e2847-daf1-4dc6-8ddd-507e8cff0cd3
```

## 実行結果

下記赤枠がタイマートリガーの実行ログです。

![functions-timer-http-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/263e8a3b-1739-3928-9cc4-58cd3126eabe.png)

下記赤枠が Curl で手動実行した日時です。

![functions-timer-http-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/92d5783a-a187-2716-c6f0-de27623a460e.png)

## 参考

https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-manually-run-non-http?tabs=azure-cli
遅刻・早退厳禁です！！

### 自己紹介

　私は、スーパーマーケットで働いています。通称、「わか」です。主な常務内容は、食肉の加工、数値管理、勤怠管理、部下の育成など多岐にわたります。勤務時間は7：00～15：00、7：00～16：00、7：00～17：00の3パターンがあります。その日の忙しさに応じて働き方を変えています。

　 同じ部署の仲間は5人で働いています。牛肉、豚肉、鶏肉、加工肉（ハム・ベーコンなど）を加工して詰めています。自分たちの作った商品が目の前で売れていく楽しさや、やりがいを感じられる職場になります。

  5人とも勤務時間、勤務日が異なるため把握しておく必要があります。現在は紙の公休表を渡していますが、それが機能しているのかわかりません。掲示板には貼ってはいるものの見ていない人もちらほらいます。　　


### こんな時どうする？

　最近、メンバー内（自分含む）の意図しない早退・残業が月に2.3回発生しています。
+ ケース1
    + Aさん　勤務終了時間より早く帰宅→早退
+ ケース2
    + Bさん　勤務終了時刻より遅く帰宅→残業

　両ケースともに、その日の自身の勤務時間を把握していなかったことが考えられます。理由を尋ねたところ、「公休表はカバンの中に入れっぱなしだった」とのことです。
　これでは、私が公休表を時間をかけて作る意味がありません。そこで、次のようなことを考えました。

### これで解決なるか！
　LINEで今日の日付けを打ち込むと「休日」または「出退勤時間」が帰ってくるような仕組みを作りました。毎日操作するスマートフォンであれば、忘れる機会が少ないのではと考えました。

 使用したツール
 ①Make
 ②LINE
 ③GoogleSpreadSheet

 実際に稼働してみると以下の通りになります。
 
 ①日付を入力→勤務時間の表示。来月以降の日付を入力→間違ってる旨を表示

 <blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">こんなのができました!<br>1/31日までの公休です（実際とは異なります）2/1以降は未作成なので、このような返信パターンにしました。<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://t.co/rtSBRVa4g5">pic.twitter.com/rtSBRVa4g5</a></p>&mdash; 若林幹太 (@young45_knt) <a href="https://twitter.com/young45_knt/status/1745446469988147498?ref_src=twsrc%5Etfw">January 11, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Makeの全体像はこれです。
![スクリーンショット (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655358/46e839f4-dc0b-9b14-5faf-7745c9bf3925.png)

①LINEを作成
![スクリーンショット (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655358/07476aa0-e5b6-ed0a-6262-b3676ee89721.png)
②GoogleSheetsを作成
![スクリーンショット (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655358/9080ad12-bb94-9a79-e8b8-c3f14f56efe7.png)
③GoogleSpreadSheetの内容
![スクリーンショット (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655358/edf42254-87b9-4b72-c189-50894f1f3a57.png)
④ルーターを使って正しい返信内容の場合のLINE
![スクリーンショット (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655358/54843d32-8f7d-7734-f1fe-3447165477c5.png)
⑤正しい内容がなかった時の返信用のLINE
![スクリーンショット (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655358/df35cfa4-4316-bec7-e41c-d3b9b4bb59ff.png)

### まとめ
　今回、初めて開発してみて、四苦八苦しましたが、なんとか形になりました。今後は、GoogleSpreadsheetではなく、画像から認識できるようなものを作りたいと考えています。
  今後の展開は、現在は、自部門だけのツールであるが、職場全体で共有していきたいと考えています。
 
### 参考資料
・LINE Developer Community
ゲームにオーバーレイを追加してHUDを表示させる方法



## A.  ゲームがボーダーレスウィンドウやウィンドウで表示されている場合
ボーダーレスウィンドウモードやウィンドウモードの場合、オーバーレイを作成するのは比較的簡単です。以下の方法が一般的です。

### STEP1. 透過ウィンドウの作成
ゲームの上に表示される別のウィンドウ（オーバーレイウィンドウ）を作成し、このウィンドウを透過させます。多くのプログラミング言語やフレームワークで、ウィンドウの透明度を制御できる機能が提供されています。
### STEP2. 常に最前面に表示
オーバーレイウィンドウをゲームウィンドウの上に常に表示するように設定します。これには、ウィンドウを「常に最前面に表示」する設定が必要です.
### STEP3. イベントのパススルー
オーバーレイウィンドウがゲームの操作を妨げないように、マウスクリックやキーボードイベントをゲームにパススルーするように設定する必要があります.

具体的な方法, C++とPythonでの実装方法はTODO

この方法の場合、スクリーン全体を画面共有、録画、配信した場合にHUDは配信に表示されるが, ゲームのウィンドウのみを配信した場合, 表示されない.

## B. ゲームが完全なフルスクリーンの場合
完全なフルスクリーンモードの場合、オーバーレイを作成するのはより複雑です。以下の手法が考えられる. これらの方法はボーダーレスウィンドウのゲームにも当然適応できる.

## B-1. グラフィックAPIをフックする

グラフィックスAPIのフックDirectXやOpenGLなどのグラフィックスAPIをフック（hook）し、ゲームのレンダリングプロセスに直接オーバーレイを描画します。この方法は高度な技術が必要であり、ゲームのレンダリングエンジンに依存します。


この方法の場合、スクリーン全体を画面共有、録画、配信した場合にHUDは配信に表示されるし, ゲームのみを配信した場合でもHUDは表示されてしまいます。

## B-2. 外部ツールの使用 

一部の外部ツールやソフトウェア（例：OBS Studio、Discordオーバーレイなど）は、フルスクリーンモードのゲームにオーバーレイを表示する機能を提供しています。これらのツールは専用の技術を使用してオーバーレイを実現しています。

## B-3 HDMI Combinerの利用

ハードウェアを用いた方法。パソコンが2台必要。

この方法の場合、スクリーン全体を画面共有、録画、配信した場合にHUDは配信に表示されないかつ ゲームのみを配信した場合でもHUDは表示されません。
Rails SQLでデータ整形（ROUMD, SUM）

## はじめに

Railsでデータを取得する際に、SQLでROUND内でSUMをして、平均や率として取得する際に一癖あったので備忘録として残しておきます。

## やりたいこと

レコードからデータを取得するときに率として取得したい。

`一部 / 全体 * 100`のようなイメージ

普通にレコードを取得してから計算することもできるが、アプリの仕様上やクエリ上、viewへの表示、CSVダウンロードなどにも使用するため取得時にデータを整形しておくことが良いと判断しております。

## コードサンプル

```rb
select(
    "ROUND((SUM(一部) / NULLIF(SUM(全体), 0.0)) * 100)
    as 算出したい率,
    ..."
)
```

ポイントとして`NULLIF()`を用いることで分母が`0.0`の場合でもエラーにならないようにしている。
筆者はこの`0.0`の箇所を`0`にしていたがために、期待する結果にならず多くの時間を費やした。
お家サーバー その9

# 概要
お家サーバーやってみる。
ハッカソンなので、一年間、電源切っていたのを、動かして見た。

# 調査1
ディスプレイとキーボード、マウス、LANを繋ぐ。
- ラズパイのモデルは？

```
$ cat /proc/device-tree/model
```
3bです。

- raspbianは？

```
$ cat /etc/os-release
```
Stretchです。

- ipアドレスは？

```
$ ifconfig
```
192.168.1.2です。

- グローバルipは？

ルーター覗く。

# 調査2

- DDNSは、動いてる？
ルーターのグローバルIPが、変わって、たどり着けない。
DDNS　NOWの設定を更新する。

# 調査３

- httpsは、動いてる？

期限切れしてる。
半日、待つ

# 調査４

- wordpressは、動いてる？

OK

# 後始末

- ルーターにLANケーブルで繋いで、運用開始。

以上。
【2024年1月版】Autoware x AWSIM の環境構築 (Ubuntuインストール後から)

本記事では、Autoware を AWSIM と一緒に利用するための環境構築手法をご説明します。
なお、対象とするOSは以下に示すOSで、クリーンインストールされた状態を想定しております。


# 事前準備
- openssh server のインストール
```
sudo apt -y update
sudo apt -y install openssh-server
```
- ROS 2 Humble のインストール
参考: https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html

```
locale  # check for UTF-8

sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8

locale  # verify settings

sudo apt install software-properties-common
sudo add-apt-repository universe

sudo apt update && sudo apt install curl -y
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

sudo apt update

sudo apt upgrade

sudo apt install ros-humble-desktop
```

- Git と vimのインストール
```
sudo apt-get -y update
sudo apt-get -y install git vim
```

- Git の設定
```
cd ~/.ssh
ssh-keygen -t ed25519
```

下記にアクセスし、公開鍵をGitHubに保存する。
https://github.com/settings/keys

# Autoware の環境構築
- git clone
参考: https://autowarefoundation.github.io/autoware-documentation/main/installation/autoware/source-installation/
Autowareの環境を作りたいディレクトリに移動してください。
```
git clone https://github.com/autowarefoundation/autoware.git
cd autoware
```

- cuda のバージョン変更
```
vim amd64.env
```
amd64.env の「cuda_version=12.3」を「cuda_version=12.2」に変更して保存してください。

```
./setup-dev-env.sh
```
適宜、ターミナルからの要求に応じて入力する。

# Autoware のインストール
下記サイトを参考にAutowareをインストールする。

参考: https://autowarefoundation.github.io/autoware-documentation/main/installation/autoware/source-installation/

# AWSIM のインストール
以下のサイトを参考にインストール
https://tier4.github.io/AWSIM/GettingStarted/QuickStartDemo/
シロートがSquidを動かしてみた（その１：初歩の初歩＋ブラックリスト）

# いまさらながらSquidを動作させてみた
Squidのその１。プロキシサーバーであるSquidを最小設定で動作させる。さらに＋αとして、ブラックリストの設定を実施、初歩の初歩レベルのメモ。

## 最小設定はポート設定のみであった
いつぞや購入したネットワークカード（[Gigabit LANカード](https://www.amazon.co.jp/gp/product/B086HRPXZG/ref=ppx_yo_dt_b_asin_title_o07_s01?ie=UTF8&th=1)）を自作PCに装着し、Ubuntu 22.04.3 LTS上にSquidをインストール（”sudo apt install squid”）。”/etc/squid/squid.conf”に設定ファイルがあり、数多くの設定がある。とりあえず、全部削除して起動してみたが動作せず。SquidのListenポートだけを指定すると動作した。
```shell:/etc/squid/squid.conf
http_port 8080
```
## ブラックリスト
＋αとして、ブラックリストの設定を実施。（と言うかこの動作確認をしたかったのである。）

### 環境
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/60f672ab-465c-9088-708b-38875c798c7b.png)
左のクライアントからSquidをとおしてWebアクセスを行う。なお、DNS設定が適切であるもとで、Webアクセスのみであれば、Squidを動作させるUbuntuにて、IPフォワーディングは不要である（”net.ipv4.ip_forward=0”でもOK）。

### 設定
記事「[16.4. Squid でのドメインブラックリストの設定](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/networking_guide/configuring-a-domain-blacklist-in-squid)」をそのまま利用。
```shell:/etc/squid/squid.conf
http_port 8080
acl domain_blacklist dstdomain "/etc/squid/domain_blacklist.txt"
http_access deny all domain_blacklist
```
アクセス制限するブラックリストファイルを”/etc/squid/domain_blacklist.txt”に設定する。
```shell:/etc/squid/domain_blacklist.txt
.zm
www.yahoo.com
```
次のドメインのアクセス制限の実施。
- ワイルドカード的（ピリオド”.”）に”zm”ドメイン
- www.yahoo.com

### 結果
クライアントのブラウザでプロキシ設定を行いアクセスしたときの状況である。
![Proxy設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/cc325a09-b4e7-4d4f-24db-25881a82eaea.png)

#### ブラックリストに未登録サイト
正常表示なので省略。

#### www.yahoo.com
![Error1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/679a5bc8-f2de-3efc-d33c-7a171cfc6641.png)

#### .zm
![Error2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/e7f3b1b4-ddcc-7b40-268f-a7d7c05c97b4.png)

フルドメイン（www.yahoo.com）を指定したときと、部分的のドメイン（.zm）を指定したときとで、表示内容（レスポンス）が異なるのはよくわからず（未調査）。

#### Squidのアクセスログ
```shell:/var/log/squid/access.log

1703894044.868      1 172.16.1.11 TCP_DENIED/403 4179 GET http://www.yahoo.com/ - HIER_NONE/- text/html

1703894167.205      0 172.16.1.11 TCP_DENIED/403 3983 CONNECT zamportal.gov.zm:443 - HIER_NONE/- text/html

```

## おわりに
クライアントにてプロキシサーバー設定することなく、Squidが動作するLinuxにて、ポート80や443をSquidポートに転送することもできる。この場合、透過型プロキシなる設定をする必要があるらしい。理解できたら、その２として、トライしてみたい。
iPadOSで外部カメラを使用する

# AVFoundationで外部カメラを扱える
![DALL·E 2024-01-13 08.05.17 - A cute anime-style girl connecting a USB webcam to an iPad. The girl has large, expressive anime eyes and a playful, animated expression. She is smili.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/841f846b-3d6a-6d1b-7797-071972a5b569.png)

AVCaptureDevice.DeviceTypeの.externalを使ってAVCaptureDeviceを設定するだけ。

```swift
var defaultVideoDevice: AVCaptureDevice?
if let externalCamera = AVCaptureDevice.default(.external, for: .video, position: .unspecified) {
    defaultVideoDevice = externalCamera
} else if let dualCameraDevice = AVCaptureDevice.default(.builtInDualCamera, for: .video, position: .back) {
    defaultVideoDevice = dualCameraDevice
} else if let backCameraDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) {
    defaultVideoDevice = backCameraDevice
}
if captureSession.canAddInput(videoDeviceInput) {
    captureSession.addInput(videoDeviceInput)
}
```

これでwebcamなど外部カメラが使える。

🐣
****
フリーランスエンジニアです。
AIについて色々記事を書いていますのでよかったらプロフィールを見てみてください。

もし以下のようなご要望をお持ちでしたらお気軽にご相談ください。
AIサービスを開発したい、ビジネスにAIを組み込んで効率化したい、AIを使ったスマホアプリを開発したい、
ARを使ったアプリケーションを作りたい、スマホアプリを作りたいけどどこに相談したらいいかわからない…

いずれも中間コストを省いたリーズナブルな価格でお請けできます。

お仕事のご相談はこちらまで
rockyshikoku@gmail.com

機械学習やAR技術を使ったアプリケーションを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
Experience Cloudのライセンスまとめ

# Experience Cloudとは

そもそもExperience Cloudってなに？と思われた方もいるかもしれません。
以前は、コミュニティサイトと呼ばれていたSalesforceの外部サイトです。
外部サイトを代理店やサポートセンター向けに、クイックに構築することができます。
今でも、コミュニティと呼ばれることもあるかと思います。

Salesforceのヘルプサイトでは下記のように紹介されています。

Salesforce Experience Cloud サイトを使用すると、顧客、パートナー、従業員など、ビジネスプロセスにとって重要な人々と情報を共有したり、コラボレーションしたりするためのブランド設定されたデジタルエクスペリエンスを作成できます。
ポータル、ヘルプフォーラム、サポートコミュニティなどさまざまな呼び方がありますが、Experience Cloud サイトは、仕事をしていく上で重要な人々とつながることができる、すばらしい場所です。

https://help.salesforce.com/s/articleView?id=sf.networks_overview.htm&type=5

今回は、Experience Cloudの外部ユーザーのライセンスについて、まとめたいと思います。

# ライセンスの種類

Experience Cloudの外部ユーザーのライセンスとして、Customer Community、Customer Community Plus、Partner Community、External Apps、External Identity、Channel Account が用意されています。

## ライセンス一覧

試験にもよく出題される主要な3つのライセンスを、表にしてみました。

|      | CUSTOMER COMMUNITY | CUSTOMER COMMUNITY PLUS |PARTNER COMMUNITY |
|:-----------|:------------:|:------------:|:------------:|
| 使用用途       |B2C         | B2B         |B2B      |
| 取引先       |参照、編集         | 参照、作成、編集         |参照、作成、編集      |
| 取引先責任者       |参照、作成、編集         | 参照、作成、編集         |参照、作成、編集      |
| ToDo       |参照、作成、編集、削除         | 参照、作成、編集、削除         |参照、作成、編集、削除      |
| 行動とカレンダー       |参照         | 参照、作成、編集、削除         |参照、作成、編集、削除      |
| Chatter       |◯        | ◯         |◯      |
| ケース       |参照、作成、編集         | 参照、作成、編集         |参照、作成、編集  |
| ナレッジ       |◯         | ◯         |◯      |
| アイデア       |参照、作成         |参照、作成         |参照、作成      |
| 共有セット       |◯         | ◯         |◯      |
| ロールと標準共有     |–      | ◯       |◯      |
| レポート         |–          | 作成および管理           |作成および管理      |
| ダッシュボード       | –       | 参照のみ       |◯      |
| キャンペーン    | –     | -      |◯      |
| リード    | –     | -      |◯      |
| 商談    | –     | -      |参照、作成、編集      |
| 見積    | –     | -      |参照、作成、編集      |
| 代理管理者       |-        | -         |◯      |
| カスタムオブジェクト    | 10個     | 10個      |10個 *1 or 100個 *2     |

*1 PRM SKU で購入した場合: ライセンスあたり 10 個のカスタムオブジェクト
*2 External Apps SKU で購入した場合: ライセンスあたり 100 個のカスタムオブジェクト

### その他のライセンスと使用用途

EXTERNAL APPS
使用用途：B2C

CHANNEL ACCOUNT
使用用途：B2B

# まとめ

いかがでしたでしょうか。
ライセンスは複雑で自分も定着するまで苦労しました。
試験にもよく出題されると思うので、Experience Cloudの外部ユーザーのライセンス導入としてどなたかのお役にたてば幸いです！