OmniAICreator/Qiita-1.07M huggingface dataset:
オリジナルアプリ作成断念

プログラミングスクールで作っていたオリジナルアプリですが、やむなく作成を断念することになりました。

# 経緯
スクレイピングの処理（野球の成績を取得にかかる）において、打者と投手の成績を同時に取得することが出来ず、
データベースに保存する作業も別々になってしまい、コードの記述が困難なため。
## 気持ちの面では
一からコードを書かなければいけないため、労力が必要以上にかかり、それにプラスしてスキルの追及が必要で頭が追い付かなかったため。

# 問題点
コードを書く段階で講師の人からダメ出しが多く、考えさせられることが多いのと正確なコードを教えてくれるわけでもありませんでした。
それがずっと続き、結局あまり進まなかったことが大きな要因です。
## 要件定義から失敗
オリジナルアプリは特に決まったものはなく何でもよかったんですが、その中でプロ野球の該当チームの選手の成績をスクレイピングでとってくるという初心者には難しいものを選んでしまったのも原因と言えます。

# これからどうするか
正直なところ、続きをやる予定はありません。第二弾もあるので、そちらに移っていくでしょう。

# 最終コード
https://github.com/kazunarigit/baystarsapp/tree/sub2
メインにも上げていません。

以上です。
Storybookの導入と絶対参照の有効化

# 対象
既存のReact/NextプロジェクトにStorybookを追加したい方。
Typescriptの絶対参照の有効化の方法もあります。

# Storybookとは
[公式ホームページ](https://storybook.js.org/)が参考になります。
簡単に言えば、
**コンポーネント単位で**UIや挙動をチェックできる
というもの。

# 導入
npx を使うのが最も簡単な方法
```terminal
npx sb init
```
それぞれの環境に合わせてインストールしてくれる


### 追加されるもの
```
├─.storybook
│      main.js
│      preview.js
│      
├─src
│  └─stories
│      Button.tsx
│      Button.stories.tsx
│      Button.css
│      ...
```

#### src/stories/
初めに追加されるこれらのファイルはExampleなので不必要なら消してよい
#### /.storybook/main.js
設定ファイル

- **絶対パス指定を有効にする方法**
デフォルトでは `import ~ from "~/..."` ではエラーが発生します
以下を追記してください
```diff_javascript
+ const path = require('path')
+ const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin')


mudule.export = {
  ...
+   webpackFinal(config) {
+   config.resolve.modules = [
+      ...(config.resolve.modules || []),
+      path.resolve(__dirname, '../src')
+    ]

+    config.resolve.plugins = [
+      ...(config.resolve.plugins || []),
+      new TsconfigPathsPlugin()
+    ]
+    return config;
+  },
 ...
}
```
# Storybookサーバーの起動

```terminal
yarn storybook
```
デフォルトポートは6006

# 基本的なコード
Storybookの機能Actions(onClickやonChangeなど)やControls(PropsをGUI上で変更できる)を有効にするためにはStorybook特有の書き方が必要となる。
詳しくはDocを参照してください


### 最も簡単な例
フォルダ構成
```
src
├─components
│   └─ atoms
│       └─ Button
│            index.tsx
│            style.tsx
├─stories
│   ├─ Button.stories.tsx

```
Storiesを記述するファイル

```typescript: Button.stories.tsx
import React from "react";
import { ComponentStory, ComponentMeta } from "@storybook/react";

import { Button } from "~/components/atoms/Button";

// 必須
export default {
  title: "Atoms/Button",
  component: Button,
} as ComponentMeta<typeof Button>;


// 任意
const Template: ComponentStory<typeof Button> = (args) => (
  <Button {...args} />
);

export const Primary = Template.bind({});
Primary.args = {
    // Add props
};

export const Noraml = Template.bind({});
Normal.args = {
    // Add props
};
```
Git ユーザ設定（各プロジェクトで指定したい！）

# プロジェクトごとに、 ユーザ名 と メアド を 設定したい

個人プロジェクトと業務プロジェクトで設定を同じにしたくないときがあるんじゃないかと思い
今、書いておこうと思いました。

~~書くほどのことでもないのかもしれないような気がするけど（読みにくい日本語）~~

```terminal:terminal
$ ls -al
$ # 出力結果に .git があるかを確認する
$ # .git がなければ git init しましょう
```

```terminal:terminal
$ git config -l
$ # 設定されているか出力結果を見て確認できる
$ # user.name=
$ # user.email=
$ # user について出力されなかったら下記で新しく追記する感じ、出力されたら下記で上書きする感じ
```

```terminal:terminal
$ git config --local user.name "kmyan"
$ git config --local user.email "xxx@yyy.zzz"
```

```terminal:terminal
$ git config -l
$ # git config --local -l # と書いても出力されるンゴ
出力内容…（一部省略）

user.name=kmyan
user.email=xxx@yyy.zzz
```

意図（設定）したユーザ名とメールアドレスは出力されましたか？

:::note info
儂の端末では、意図したものが出力されました。
:::
【 Azure App Service 】Git/デプロイメント情報を更新する方法

Azure App Service でアプリケーションのデプロイ方法を **ローカルGit** に設定した場合、デプロイ用の Git へソースコードをプッシュする際に、**Git/デプロイメントユーザー資格情報** が求められます。

Git/デプロイメントユーザー情報は、Azure Portal のAzure App Service リソースから確認することができます。(他に最適な確認方法があれば、コメントいただけると嬉しいです。)

※ Git/デプロイメントユーザーは特定のリソースではなく、ユーザー自身に紐づいた資格情報です。Azure App Service リソース固有の資格情報ではないので注意してください。

## ユーザー資格情報確認手順

App Service リソースのナビゲーションメニューから
**デプロイメント > デプロイセンター** を選択すると、
デプロイ方法の選択画面が表示されます。

デプロイ方法に **ローカルGit** が指定されていることを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/cd828f44-abce-46d0-f131-d47c3dcadf5d.png)

ページ上部の **ローカルGit または FTPS の資格情報** タブを選択します。
ユーザースコープの欄に　**ユーザー名** が表示されていることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180432/5d2f20e9-91f7-5fd2-e7ee-1377d54f50ee.png)

ただし、既に設定済みのパスワード情報は表示ボタンを押しても表示ない仕様になっています。

## ユーザー資格情報変更手順

Azure Portal 上で確認したところ、ユーザー資格情報の変更ページが見当たらず、公式ドキュメントを読んでいると、Azure CLI コマンドで **ユーザー資格情報の設定** ができるコマンドを見つけました。試しに Azure CLI で実行してみたところ、無事ユーザー資格情報の更新ができました。

``<username>``, ``<password>`` は設定したい値に置き換えて実行します。
 
```
az webapp deployment user set --user-name <username> --password <password>
```

## Azure App Service に ローカルGit でデプロイする方法

まず最初に、``azure`` という名前のリモートリポジトリを追加します。

``
git remote add azure <ローカル Git URL>
``

リモートリポジトリの追加ができたら、デプロイしたいソースコードを
リモートリポジトリの ``master`` ブランチに明示的にプッシュします。

```
git push azure ローカルブランチ名:master
```

コマンドが正常動作していると、さきほど設定した
ユーザー資格情報の入力ポップアップが表示されます。
資格情報の認証が通ると、ローカルGit 経由のデプロイが実行されます。

# 参考サイト
[ユーザー スコープの資格情報を構成する](https://docs.microsoft.com/ja-jp/azure/app-service/deploy-configure-credentials?tabs=cli#userscope)
PowerShell7のDockerコンテナサポート

PowerShell7になってガラッとこれまでのPowerShellとは違っていて、別の名前の方が良かったのではないかと思うくらい。

PowerShell7の新機能がこちら。

https://docs.microsoft.com/ja-jp/powershell/scripting/whats-new/migrating-from-windows-powershell-51-to-powershell-7?view=powershell-7.2

- Windows PowerShell とのサイド バイ サイドのインストールおよび実行
- 既存の Windows PowerShell モジュールとの強化された互換性
- 三項演算子や ForEach-Object -Parallel などの新しい言語機能
- パフォーマンスの向上
- SSH ベースのリモート処理
- クロス プラットフォームの相互運用性
- Docker コンテナーのサポート

えちょっとまって、Docker コンテナーのサポート？Windows上のPowerShellから直接Docker使えるってこと？それめちゃくちゃ便利じゃん。

ところが、そのページを探してもDockerの一言も他にはない。そして`Docker`で検索してヒットするPowerShell7のドキュメントがこちら。

https://docs.microsoft.com/ja-jp/powershell/scripting/install/powershell-in-docker?view=powershell-7.2

コンテナの中でPowerShellが使えますよという話でした。
node.jsのインストールに苦戦した。

vuejsの学習で環境構築をするために、
node.jsをインストールしようとした時のエラーをまとめます。

環境構築に必要な作業は、
①node.jsをインストール。
  (node.jsをインストールするのに、HomebrewとNodebrewをインストールしないといけない)
②VueCLIをインストール。

①のnode.jsのインストールに苦戦したのでまとめます。

### 発生している問題・エラー
①今回はnode.jsのバーージョン14.6
　をインストールしたいので下記コマンド実行。
```
$ nodebrew install-binary v14.16.0
```
次に、インストールされたバージョンを確認
```
 nodebrew ls
```
使用するバージョンを指定
```
nodebrew use v14.16.0
```
結果
```
v14.16.0

current: v14.16.0
```
ここまでは問題なし。
再度に
```
node　-v
```
で最終確認しようとしたが、
```
zsh: command not found: node
```
インストールしたはずなのに、
node.jsを確認できない、、、

・mac再起動。
・node.jsをアンインストール、もう一度インストールしたが
　解決せず、、、

・結論、nodebrewのセットアップをしていないことが原因。

nodebrewのセットアップ
```
$ nodebrew setup
Fetching nodebrew...
Installed nodebrew in $HOME/.nodebrew

========================================
Export a path to nodebrew:

export PATH=$HOME/.nodebrew/current/bin:$PATH
========================================
```
PATHを通す
```
$ echo '# nodebrew' >> ~/.bash_profile
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile
$ source .bash_profile
```
再度node.jsインストール
```
$ nodebrew install-binary v14.16.0
```
Node.jsを有効にする。
```
$ nodebrew use stable
```
再度にバージョン確認
```
$ node -v

v14.16.0
```

無事解決できました！
C# クリップボードの画像を、即プリンタ出力する。ユーザ名・コンピュータ名・日時も付与。


:::note info
C# クリップボードの画像を、即プリンタ出力する。
ユーザ名・コンピュータ名・日時も付与。
:::


```c#:clip2print.cs
//c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /target:exe clip2print.cs
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Printing;

class clip2print
{
	static void Main()
	{
		System.Threading.Thread t = new System.Threading.Thread(GetClipboardText);
		t.SetApartmentState(System.Threading.ApartmentState.STA);
		t.Start();
		t.Join();
	}

	private static void pd_PrintPage(object sender,
		System.Drawing.Printing.PrintPageEventArgs e)
	{
		Image img = System.Windows.Forms.Clipboard.GetImage();
		Console.WriteLine("img 高さ:{0} 幅:{1}", img.Height, img.Width);
		Rectangle r = e.MarginBounds;
		double rr = (double)r.Height / (double)r.Width;
		double ir = (double)img.Height / ((double)img.Width+1);
		Console.WriteLine("rr:{0} ir:{1}", rr, ir);
		if(rr < ir){
			if(r.Height > img.Height){
				r.Width = img.Width;
				r.Height = img.Height;
				Console.WriteLine("1");
			}else{
				double rt = (double)r.Height/(double)img.Height;
				r.Width = (int)(rt*(double)img.Width);
				r.Height = (int)(rt*(double)img.Height);
				Console.WriteLine("2");
			}
		}else{
			if(r.Width > img.Width){
				r.Width = img.Width;
				r.Height = img.Height;
				Console.WriteLine("3");
			}else{
				double rt = (double)r.Width/(double)img.Width;
				r.Width = (int)(rt*(double)img.Width);
				r.Height = (int)(rt*(double)img.Height);
				Console.WriteLine("4");
			}
		}
		Console.WriteLine("X:{0} Y:{1}", e.MarginBounds.X, e.MarginBounds.Y);
		Console.WriteLine("高さ:{0} 幅:{1}", e.MarginBounds.Height, e.MarginBounds.Width);
		Console.WriteLine("上:{0} 左:{1}", e.MarginBounds.Top, e.MarginBounds.Left);
		Console.WriteLine("rw:{0} rh:{1}", r.Width, r.Height);
		e.Graphics.DrawImage(img,r);
		
		Font fnt = new Font("MS UI Gothic", 16);
		DateTime dt = DateTime.Now;
		e.Graphics.DrawString(Environment.UserName + " " + Environment.MachineName + " " + dt, fnt, Brushes.Blue, 0, 0);
		e.HasMorePages = false;
		img.Dispose();
	}

	static void GetClipboardText()
	{
		try{
			if (System.Windows.Forms.Clipboard.GetImage() != null)
			{
				Image img = System.Windows.Forms.Clipboard.GetImage();
				Bitmap sub1 = new Bitmap(img);
				System.Drawing.Printing.PrintDocument pd =
					new System.Drawing.Printing.PrintDocument();
				pd.PrintPage +=
					new System.Drawing.Printing.PrintPageEventHandler(pd_PrintPage);
				pd.Print();
			}else{
				Console.WriteLine("クリップボードに画像がない");
			}
		}
		catch(Exception ex){
			MessageBox.Show("エラー\n"+ex);
		}
	}
}
```
G検定を受けてみた

# はじめに
この記事は、G検定を受験すためにどのような勉強をしたか、
試験をうけてみてどうだったか
などの備忘録です。

# 前提
- 独学でpythonを勉強(progate,pyq)
- 短期スクールで機械学習の勉強

# 使用したテキスト、サイト
- [深層学習教科書 ディープラーニング G検定(ジェネラリスト)公式テキスト 第2版](https://www.amazon.co.jp/%E6%B7%B1%E5%B1%A4%E5%AD%A6%E7%BF%92%E6%95%99%E7%A7%91%E6%9B%B8-%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0-G%E6%A4%9C%E5%AE%9A-%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%A9%E3%83%AA%E3%82%B9%E3%83%88-%E5%85%AC%E5%BC%8F%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88/dp/4798165948)

- [DIVE INTO EXAM](https://diver.diveintocode.jp/dive_into_exam/lp)

# 結果
- 合格
- 試験結果、点数の詳細は確認できない
- 試験結果のメール内で総受験者数、合格者数、シラバス分野別得点率　が記述してある


# 勉強期間・時間
- 1ヶ月 + 1週間
- 平日1～2時間、土日3時間



# 勉強方法
- 公式テキストをとにかく読みこむ
-  [DIVE INTO EXAM](https://diver.diveintocode.jp/dive_into_exam/lp) の模擬試験をうける

勉強順序としては、
1. テキスト全体を確認程度に読む(1週間半)
1. テキスト内容は7章あり、各章を読み込み、章末の練習問題を解く(2週間)
1. 難しい章を重点的に勉強し、模擬試験を受ける(1週間半)

といった流れでした。


# 1. テキスト全体を確認程度に読む
全体の流れの把握。
前提知識と比較して、どの項目を重要視するかしないかなどを確認しました。
パラパラと読んだ実感としては、1～3章は読みやすく、4章から難しくなり、5～6章で理解、覚えることが多く、7章でまた読みやすくなる印象です。



# 2. 各章の読み込み
ここからは一章一章読み込んで、章末の練習問題を解き、間違っていた点を読み直しました。
2週間かけたので、1章を1～3日で進めるイメージです。
特に5～6章はディープラーニングの概要、手法で覚える内容が多く、何度か読み直しました。
色んなディープラーニングの手法があり、さらに細分化した説明があるので、うまく整理しながら覚えていきましたが初見では覚えられなかったですね。


# 3. 苦手な章を重点的に勉強。模擬試験を受ける(1週間)
各章の練習問題で弱い点がわかったので、その点を再度復習。
特に5～6章の結果がよろしくなかったので、念入りにこの2つの章は復習しました。

復習が終わり、模擬試験に近いテキストでも買おうかと思っていたのですが、検索してみると模擬試験が受けられるサイトを発見。月額980円で書籍より安いし、1週間以内であれば無料なので [DIVE INTO EXAM](https://diver.diveintocode.jp/dive_into_exam/lp)というサイトで模擬試験を受講しました。

模擬試験の正解率は50％くらいで、少し焦る…覚えていることをいざ問題にされると解答につながらない…
受けてよかったとしみじみ思いました。
何が間違っていたのかを把握し、問題文の傾向を確認してテキスト、模擬試験を再度見直しました。
試験間際まで模擬試験を見直し、いざ受験。




# 試験を受けてみて
選択問題がほとんどなので、そんなに苦労はしませんでしたが、
問題文がまわりくどかったり、ディープラーニングの手法が絡んでくると、回答に迷わされることが多かったです。

インプットすること、模擬試験で試験問題に慣れることの対策が無事合格という結果につながって良かったです。



以下試験情報↓
実施概要	試験時間：120分
知識問題（多肢選択式・220問程度）
オンライン実施（自宅受験）


# 反省点
欲を言えば、5～6章のディープラーニングの概要、手法のインプットにもう少し時間を取りたかったです。
詰め込みに時間をかけたので、知識というよりは試験のために覚えている感じがあり、身になった実感が少なかったからです。
より高得点を狙うのであれは、テキストの問題集をたくさんやったほうが良かったのかもしれません。
ググると何冊かでてきます。



# 終わりに

なんとか合格できて良かったとほっとしています。
この試験は機械学習の知識を万遍なく網羅しています。
機械学習を勉強したい、機械学習の知識の証明をしたい、そういった方に勧めやすい資格だと思います。
最後までお読みいただきありがとうございました。
【Laravel】Controllerメソッドの戻り値が意図した値で返却されない

# 環境

- Macbook Air 2020
- Laravel 9.27.0
- PHP 8.0.23
- sail  v1.15.4
- Composer 2.4.1

# １．状況

LaravelにてAPIを構築しておりGETメソッドでエンドポイント `/reservation/status/{gym_id}/{machine_id}` にアクセスすると、 `ResrvationController.php` 内の `getReservationStatus` メソッドで対象のレコードの数を取得したい。


```php:api.php
Route::prefix('reservation')->group(function () {
    Route::get('/{reservation_id}/{gym_id}/{machine_id}', [ReservationController::class, 'nextReservationExists']);
    Route::get('/status/{gym_id}/{machine_id}', [ReservationController::class, 'getReservationStatus']);
});
```

```php:ReservationController.php
public function getReservationStatus($gym_id, $machine_id)
{
    $count = Reservation::where([
        ["gym_id", "=", $gym_id],
        ["machine_id", "=", $machine_id],
        ["start_at", "=", null],
        ["is_canceled", "=", 0],
    ])->count();
    return $count;
}
```

# ２．エラー内容

エラーは特に出ていなかったが、数字が返却されず `json` が常に返却される。

```json
{
	"id": 1,
	"gym_id": 2,
	"machine_id": 8,
	"user_id": 3,
	"is_canceled": 0,
	"start_at": null,
	"end_at": null,
	"created_at": "2022-09-07T05:13:27.000000Z",
	"updated_at": "2022-09-07T07:36:44.000000Z"
}
```

# ３．調査

### ルーティングの設定を確認

`sail artisan route:list` コマンドで確認するも、ルーティングは設定されている模様。
![スクリーンショット 2022-09-08 16.24.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2638572/73328720-e3a9-93fb-01dc-ba89eb3c30da.png)
### キャッシュクリア、オートロード

`sail composer dump-autoload` `sail artisan route:clear` `sail artisan config:clear`
 を実行したが変化なし。

### `/status` を `/test` に変更

特に変化なし。 `json` が返却される

### 実行されたメソッド名取得して返却してみる

`ResrvationController.php` のGETメソッド内に `return __FUNCTION__` を記述し意図した関数が実行されているか確認。
↓↓↓
原因判明

# ４．原因

- `getReservationStatus` メソッドを呼び出しているつもりが、エンドポイント `/reservation/{reservation_id}/{gym_id}/{machine_id}` の `nextReservationExists` メソッドが呼び出されていた
- エンドポイント①`/reservation/status/{gym_id}/{machine_id}` とエンドポイント②　`/reservation/{reservation_id}/{gym_id}/{machine_id}` の階層が同じで、 ①にアクセスした場合でも`status` が `{reservation_id}` のところに入ってしまい②にアクセスしている状態になっていた

# ５．解決策

- ルーティングファイルの`/reservation/status/{gym_id}/{machine_id}` と`/reservation/{reservation_id}/{gym_id}/{machine_id}` の記述を逆にした
    
    【変更前】
    
    ```php:api.php
    Route::prefix('reservation')->group(function () {
        Route::get('/{reservation_id}/{gym_id}/{machine_id}', [ReservationController::class, 'nextReservationExists']);
        Route::get('/status/{gym_id}/{machine_id}', [ReservationController::class, 'getReservationStatus']);
    });
    ```
    
    【変更後】
    
    ```php:api.php
    Route::prefix('reservation')->group(function () {
        Route::get('/status/{gym_id}/{machine_id}', [ReservationController::class, 'getReservationStatus']);
        Route::get('/{reservation_id}/{gym_id}/{machine_id}', [ReservationController::class, 'nextReservationExists']);
    });
    ```
    
- 数字が返却された
![スクリーンショット 2022-09-09 12.14.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2638572/658499c7-ca2d-8717-5fc3-34f0f2a07dfc.png)
Salesforce認定アドミニストレーター試験の公式練習問題を解説してみた-その018

こんにちは。本橋孝昭です。

Salesforce認定アドミニストレーター試験の公式練習問題があるのはご存じでしょうか。
Trailheadにフラッシュカードとして何度も解ける練習問題がございます。

今回はTrailhead
アドミニストレーター認定の準備: 構成、設定とオブジェクト
オブジェクトマネージャと Lightning アプリケーションビルダーの確認
　にある練習問題6問目をご紹介します。
https://trailhead.salesforce.com/ja/content/learn/modules/administrator-certification-prep-setup-and-objects/practice-user-setup

なお、こちらの内容はYouTubeでも公開しております




<iframe width="560" height="315" src="https://www.youtube.com/embed/p9upfJBmssI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


オブジェクトマネージャと Lightning アプリケーションビルダーの確認
練習問題6問目はこちらです

![1006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/3749283e-8700-2e26-8ff5-29c8120db85b.png)


いかがでしたでしょうか

正解がCです

今回の場合、取引先のページから関連リストに取引先責任者に表示させない　という設定をします


あくまでもページから表示させないなのでページレイアウトの設定が正解でした


Aについて
今回はページの表示なのでレコードの閲覧の設定は間違いです

Bについてもレコードの閲覧の設定なので間違いです

Dについて
これはCの逆ですね
取引先責任者の関連リストに取引先はございません


よって間違いです



今日の内容はここまでです。
皆さん楽しく元気にSalesforceを学びましょう！
Swiftで配列をmapで扱う。


mapは**配列の要素すべてに、何らかの処理を施して返す**もの。

https://developer.apple.com/documentation/swift/sequence/map(_:)

例えば,　指定された季節に応じて、その時の花の写真を出し分けたいという状況を考えてみる。
画像ファイルの名前は「花の名前＋季節」
夏のひまわりだったら、「sumflowerSummer」みたいなイメージ。

```swift
let flowersImage = ["rose", "cherryBlossoms", "sunflower"]

print (springFlowers)
/// ["rose", "cherryBlossoms", "sunflower"]

let springFlowers = flowersImage.map { $0 + "Spring" }

print (springFlowers)
/// ["roseSpring", "cherryBlossomsSpring", "sunflowerSpring"]
````
ここで、$0は引数の省略。
【パブリッシャー】ページデザイナーを使ってみる

今回は、以下のような定型レポートをパブリッシャーで作成してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/5c32f26f-cbfb-5c63-cbbb-323ad7e41ce7.png)
このようなレポートは、[Sharperlight](https://sharperlight.jp/)パブリッシャーのページデザイナー機能を利用して作成します。
[Sharperlight](https://sharperlight.jp/)アプリケーションメニューから**パブリッシャー**を起動します。
今回は、既に作成しているものを使用していきます。
一覧から対象となるレポートをダブルクリックし編集ダイアログを開きます。
➊`ページ`タブに移動して、➋`新規`アイコンをクリックしページの作成を開始します。
➌最初のエントリーが作成されます。➍`編集`ボタンでページの編集を開始します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/c99480b6-08a7-6488-f093-5f1a6c3dcc1d.png)
このようなダイアログが起動するので、`OK`ボタンで先に進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/ba2a75c2-983d-3acf-0ea8-04368166628b.png)
すると、Sharperlightに組み込まれているページデザイナーコンポーネントが起動します。
中央のレイアウト領域に、テーブルやテキストフィールドなどの部品を配置していきます。その部品にSharperlightで作成したクエリをデータソースとして、リンクさせていきます。
左側の領域には、各種部品の一覧が表示されています。右側の領域には、レポートの各部位の詳細および使用可能なSharperlightクエリの一覧が表示されています。
右側の領域の**Data Sources** -> **Sharperlight**の下に3つのクエリが見えます。
`Q001`は、このレポートのメインクエリを指し、ここでは`Q002`と`q_HF`がそれぞれサブクエリを指します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/3cd859f5-c3f8-cc53-d724-9b671a74b6fc.png)
レポートで使用するサブクエリーは、`ページ`タブの下部で定義できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/6b701eb6-914c-e878-2b26-a76c04b2a7c1.png)
では、実際のフィールド属性をみてみましょう。
請求書送付先のテキストフィールドを見てみましょう。右側の領域にこのテキストフィールドの名称`TextBox15`、その下部に各種属性が表示されています。`Value`属性に注目してください。ここでは、クエリ`q_HF`の**OINV_Address.Value**を参照していることが分かりますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/166b049c-1122-3331-30c1-4fd558457edd.png)
このようにして部品を配置し、その部品にクエリで得た値をリンクさせていきます。テーブルなどは、クエリ結果に応じでページを跨いで上手に表示されるようになっています。
こういった特殊なフォーマットが必要な場合は、このページデザイナーを使ってみてくださいね。

では、失礼します。
VSCode ショートカット

# VSCodeショートカット
|内容|キーボード|
|-|-|
|範囲選択|Shift+カーソル|
|カーソル移動(端に移動)|Cmd+カーソル|
|カーソル移動(単語移動)|Opt+左右|
|もとに戻す|Cmd+Z|
|やり直し|Cmd＋Shift+Z|
|複数範囲選択|Cmd+D|
|検索|Cmd+F|
|横断検索|Cmd+Shift+F|
|定義元を参照|F12|
|ピークで定義元を参照|Opt+F12|
|リファレンスを表示|Shift+F12|
|クイックフィックス|Cmd+.|
|ファイル検索|Cmd+P|
|タブを閉じる|Cmd+W|
|行の入れ替え|Opt+上下|
|ファイル移動|Cmd+Opt+左右|
|トグルラインコメント|Cmd+/|
|コマンドパレットを表示|Cmd+Shift+P　もしくはF1|
|新しいウィンドウ|Cmd+Shift+N|
|フォルダを閉じる|Cmd+K → F|
|新しいタブ|Cmd+N|
|別名で保存|Cmd+Shift+S|
|直前で閉じたタブを復元|Cmd+Shift+T|
|VS Codeの設定を開く|Cmd+,|
|シンボル名を変更|F2|
|シンボル名を横断検索|Cmd+T|
|ファイル内のシンボルへ変更|Cmd+Shift+O|
|問題タブをトグル|Cmd+Shift+M|
|カッコのはじまり・終わりに移動|Cmd+Shift+\|
|全ての検索一致を同時選択|Cmd+F2|
|トグルブロックコメント（複数行コメント）|Opt+Shift+A|
|ファイル内の文字列置換|Cmd+Opt+F|
|編集閲覧履歴|Ctrl+Tab|
|直前の編集ファイルを開く|Ctrl+_|
|ファイルを開く|Cmd+O|
|ズームイン|Cmd+Shift+-|
|ズームアウト|Cmd+-|
|コードのフォーマット|Opt+Shift+F|
|||
|行削除|Cmd+Shift+K|
|マルチカーソル|Opt+Ctrl+上下|
|インデント|Cmd+] もしくはTab|
|アウトデント|Cmd+[|
|下に1行インサート|Cmd+Enter|
|上に1行インサート|Cmd+Shift+Enter|
|上下に1行コピー|Opt+Shift+上下|
|指定行へ移動|Ctrl+G|
|サイトバーのトグル|Cmd+B|
|次の問題箇所へ移動|F8|
|前の問題箇所へ移動|Shift+F8|
|||
|現在の行を選択|Cmd+L|
|開いているタブ以外を閉じる|Cmd+Opt+T|
|カーソル操作の元に戻す|Cmd+U|
|全てのタブを保存|Cmd+Opt+S|
# 検索時の条件をコマンドで操作する方法
|内容|キーボード|
|-|-|
|小文字・大文字の切り替え|Cmd+Opt+C|
|ワード検索|Cmd+Opt+W|
|正規表現|Cmd+Opt+R|
# その他
|内容|キーボード|
|-|-|
|開いているファイルのパスをコピー|Cmd+K → P|
|開いているファイルをFinderで表示|Cmd+K → R|
|開いているファイルと新しいウィンドウで表示|Cmd+K → O|
# 引用
>YouTube
[しまぶーのIT大学](https://www.youtube.com/watch?v=cNyvefTJOcM)
MySQLのバージョン確認

# やり方（SQL）

```sql:
SELECT version();
```

# 参考サイトさん

https://qiita.com/rokumura7/items/b270acb9550efddd5fe5

https://stackoverflow.com/questions/40331746/what-does-log-stand-for-in-mysql-version

TODO:バージョン末尾に-logが付く場合についてまとめる
TODO:sql以外の方法についてもまとめる
WordPress+LightningにGoogleAnalyticsを導入

# 前提
## やること
- WordPress(Lightning)にGoogleAnalyticsを導入のみ
WordPressにアクセスして、GoogleAnalytics上で、アクセス数がカウントされるのを確認。

## やらないこと
- WordPressの導入・使い方説明
- GoogleAnalyticsの導入・使い方説明

そもそも自分がよくわかってない

## 環境
| ツール | 補足 |
|:-:|:-:|
| WordPress  | v 6.0.2 |
| Lightning  | WordPressテーマ  |
| VK All in One Expansion Unit  | WordPressプラグイン  |

# 実践
:::note info
1. [GoogleAnalyticsにプロパティを追加](#googleanalyticsにプロパティを追加)
1. [WordPressに測定IDを設定](#wordpressに測定idを設定)
1. [動作確認](#動作確認)
:::

## GoogleAnalyticsにプロパティを追加
まずは対象のサイトに設定するために、`プロパティ`というものを作成します。
GoogleAnalyticsにログインして、`管理 > プロパティを追加`。
![スクリーンショット 2022-09-09 10.29.15.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2585352/eec6bb08-6723-3a21-60db-2b0bc6fbd2ac.jpeg)
***
プロパティ名を入力します。
GoogleAnalytics上で管理する上での名称です。
複数サイトを管理している方は、何のサイトであることが自分でわかるような名称を入力します。
![スクリーンショット 2022-09-09 10.37.08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2585352/ccfaa2b0-7b06-590b-944b-31bba0240da7.jpeg)
***
以下を入力して、`作成`
- 業種
- ビジネスの規模
- 利用目的
![スクリーンショット 2022-09-09 10.37.44.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2585352/75a38a0a-9151-a168-013c-e37c608c0b29.jpeg)
***
プラットフォームを選択。
今回はwordpressのブログなので`ウェブ`を選択。
![スクリーンショット 2022-09-09 10.38.08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2585352/029a2639-eb54-0674-e072-3b0f1b760738.jpeg)
***
以下を入力
　- サイトのURL
　- ストリーム名（何のサイトか自分がわかれば何でも良さそう。ただし、後から変更はできないみたい）
![スクリーンショット 2022-09-09 10.42.19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2585352/466698f0-f528-1be9-564b-b13fff7e67b1.jpeg)
***
作成完了。
後ほど、作成した`測定 ID`を使用します。
![スクリーンショット 2022-09-09 10.43.13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2585352/ae89bf01-cefd-55d9-43ac-25fcba7359d5.jpeg)

## WordPressに測定IDを設定
GoogleAnalyticsで作成した`測定ID`をWordPress側に設定してきます。

`ExUnit > メイン設定`で、設定画面を開く。
`Google Analytics設定`で、以下を入力。
- 測定ID（先ほど作成したIDをコピペ）
- ログインしているユーザーの追跡を無効化（自分のアクセス数を除外）
![スクリーンショット 2022-09-09 10.56.56.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2585352/f8aa7e2f-c87b-031a-5a92-fbe3462d1a1e.jpeg)
***
念のため、GoogleAnalyticsが有効化になっているか確認。
`ExUnit > 有効化設定`で、設定画面を開く。
`GoogleAnalyticsがチェックされている`こと。
![スクリーンショット 2022-09-09 11.22.21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2585352/a6d5009c-dbde-36ac-8848-640be64e7814.jpeg)

## 動作確認
WordPressにログインしていない状態で、対象のサイトにアクセス。
（ブラウザのシークレットモードでも良いかも）

GoogleAnalyticsを開いて、`レポート > リアルタイム`を選択。
アクセス数が反映されていることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2585352/34320baf-a26d-bc2b-2c5a-55fb4a3ef531.png)
discord.py v2.0の自動変換を使ってみる

久しぶりにdiscord　botを作ってみたら面白い機能が追加されていたのでメモ書き。

discord.pyのVer2.0から追加された新機能の一部
- `app_commands.choices`
- `app_commands.autocomplete`

この2つはコマンドの引数を設定する際に特定の文字列の中からユーザーに入力して欲しい時に候補を表示することができて便利なのでよく使っています。

今回は候補にしたい配列がほとんどカタカナで構成されているという前提で、
ひらがな→カタカナ変換をして配列の中から部分一位した文字列を返すコードを載せています。


```python
import discord  
from discord import app_commands  
from discord.ext import commands

intents = discord.Intents.default()  
intents.members = True  
bot = commands.Bot(command_prefix = '.',intents=intents, help_command=None)  
tree = bot.tree


special_list = [
'ウルトラショット', 'ウルトラハンコ', 'エナジースタンド', 'カニタンク', 
'キューインキ', 'グレートバリア', 'サメライド', 'ショクワンダー', 'ジェットパック', 
'トリプルトルネード', 'ナイスダマ', 'ホップソナー', 'マルチミサイル', 'メガホンレーザー5.1ch'
]

# ひらがな→カタカナ変換  
def hiraToKata(target):  
    return ''.join([chr(n + 96) if (12352 < n and n < 12439) or n == 12445 or n == 12446 else chr(n) for n in  
                    [ord(c) for c in target]])
                    
# 検索コマンド  
async def sp_autocomplete(  
    interaction: discord.Interaction,  
    current: str,  
) -> list[app_commands.Choice[str]]:  
    target_str = hiraToKata(current)  
    return [  
        app_commands.Choice(name=buki_name, value=buki_name)  
        for buki_name in special_list if target_str in buki_name  
    ]  
  
@tree.command(  
    name="find",  
    description="候補を表示します"  
)  
"""
選択肢が少ない時はchoicesの方が入力の必要がなく楽です
"""
# @app_commands.choices(  
#     category=[  
#         app_commands.Choice(name="サブウェポン",value="サブ"),  
#         app_commands.Choice(name="スペシャル",value="スペシャル"),  
#         app_commands.Choice(name="ブキカテゴリー",value="カテゴリー")  
#     ]  
# )  
@app_commands.autocomplete(name=sp_autocomplete)  
async def find(ctx, name: str):  
    await ctx.response.send_message(name)
    
  
bot.run(DISCORD_TOKEN)
```

いつの間にか起動時にインテントなるものが必要になっていて ちょっとつまづいた。

日本語だとカタカナ以外はコードで変換処置いれなくても部分一致で候補出しやすいかもしれないですね〜
漢字はユーザー側で変換までしてもらったほうが実装が楽そう...

## 参考
- ひらがなからカタカナ変換

https://oboe2uran.hatenablog.com/entry/2020/12/19/003000
Flutterで開発したWindowsデスクトップアプリのスクリーンリーダー対応状況の現在地

Flutterはバージョン2.10から正式にWindowsデスクトップアプリに対応しました。
とはいえ、まだまだ発展途上。
最新3.3で作成したWindowsデスクトップアプリを例にスクリーンリーダーでの動作状況をまとめます。

------


## ウィジェット間の移動
タブキーを使って可能。
ただしリストなどの一部のウィジェットにはフォーカスが当たりません。

## onPress に対応したウィジェットについて
エンターやスペースを押しても反応していません

## テキストフィールドについて
タブキーでフォーカスができ、入力ができています。
しかしカーソルキーで入力した文字の確認やバックスペースやデリートを押したときに削除した文字が読み上げられません。

## 最後に
ご自身で作成されたWindowsデスクトップアプリでスクリーンリーダーの動作を確認されたい方は
__ctrl + Windows + エンター__
でナレーターを呼び出すことで確認できます。
ナレーターは上記と同じ操作で終了することができます。
MailHogでテスト用SMTPサーバを構築する

# 概要
alpine + golangでWebアプリを実装した際に、メール送信機能の動作確認のため簡単なSMTPサーバが必要になり、[MailHog](https://github.com/mailhog/MailHog)を導入したので手順を書いておく。あくまでもWebアプリのメール送信機能が動作していることを確認するのが目的なので、外部へのメール配信は想定しない。

# インストール
```
# go install github.com/mailhog/MailHog@latest
```

# SMTPサーバ起動
```
# MailHog -smtp-bind-addr 127.0.0.1:25 -storage maildir -maildir-path /var/tmp/mail
```
これで`127.0.0.1:25`でSMTPサーバが起動する。送信されたメールは`/var/tmp/mail`以下に保存される。
少し複雑なレポート


質問者さんが何でできないと言っているかが最後まで理解できませんでしたが、私も色々試してみたので忘れないように記録しておきます。
ずっと英語の質問場所で回答してきましたがたまに日本語の方に戻ると　質問の意図やテクニカルなエラーの内容を理解できなくなっていることが多いです。　英語の質問の場合は英語が理解できてないので、まぁ仕方ないですが、そんな環境にずっといると脳が破壊されるのかもしれません。

最近は質問者さんが困っていることしか理解できないことが多いです。何に困っているか正直がわからん。　というのも私の場合だったらすんなりできていたりします。別に何んにも変わったことはせずに... 何だろうなぁ。

[レポート：日付型項目の個数集計方法](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000JdI8ESAV)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/5b597102-2ad7-5cb5-e8fd-16d01964900d.png)

真ん中は Opportunity.Stage_Date__c だけを指定した場合です。 ユニークなので１です。


もし、一番右のように表示したければ、以下のように設定します。

GRAND_SUMMARYで割っているので総合計に対する割合になっています。違うのかな？

```
RowCount / PARENTGROUPVAL(RowCount, GRAND_SUMMARY)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/98577976-77a7-4d0d-4617-72b7cb85bd53.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/252a2a10-ee77-7407-4548-6b887c8639ab.png)


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

Stage単位に日付ごとの割合を表示ですか？

これだと、まだ総合計に対する割合のままですなぁ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9f599953-f475-e476-2090-9470ce6e20a9.png)

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

こうやるとステージ単位での割合が出る。

```
RowCount / PARENTGROUPVAL(RowCount ,STAGE_NAME )
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a576267d-0445-fdaa-f5b6-ac288487ee01.png)

ここが大事だな。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/dc79244c-ad3f-4e9e-71cc-ad825e984427.png)


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

Row Group をステージに変えると当然こうなる。
ということは、Record CountはこのRow Group で指定したフィールドの件数ですよねぇ当たり前だけど。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9246425e-30c0-c688-4695-0f09040adbcc.png)

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

いつもよく分からんまま使う　PARENTGROUPVAL関数。説明を読んでも理解できん。

PARENTGROUPVAL
この関数は親グルーピングに対する相対的な値の計算に使用します

この関数は、指定した親グルーピングの値を返します。「親」グルーピングとは、数式が含まれるレベルよりも上にあるレベルです。この関数は、カスタム集計項目およびレポートのグルーピングレベルでのみ使用可能で、集計レベルでは使用できません。

行でグループ化されたレポート (サマリー) および結合レポートの場合: PARENTGROUPVAL(summary_field, grouping_level)

grouping_level単位でsummary_fieldを集計するってこと？
ということはSTAGE_NAME単位にRowCountを合計するということかな？

```
RowCount / PARENTGROUPVAL(RowCount ,STAGE_NAME )
```

これだと、総合計に対するRowCountの合計？

```
RowCount / PARENTGROUPVAL(RowCount, GRAND_SUMMARY)
```

これと同じかな？
と思ったけど　保存できんなぁ。
Warning
Incorrect parameter type for operator '/'. Expected Number, received Object

```
RowCount / GRAND_SUMMARY
```

[PARENTGROUPVAL および PREVGROUPVAL](https://help.salesforce.com/s/articleView?id=sf.reports_summary_functions_about.htm&type=5)


# 分からん

+ [Formula field on report to calculate difference in total donations between financial years](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000KRnDm)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/31219b79-8614-3433-6584-9413d974f021.png)


```
https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000KRnDm#:~:text=BLANKVALUE(Donation_Amount%3ASUM%2C0)%2D%0ABLANKVALUE(PREVGROUPVAL(Donation_Amount%3ASUM%2CFYGrouping)%2C0)
```
【Power Platform】 SharePointと連携したPower Automateでの自動メール送信

## はじめに

Power Platformを使う方が増えている中、業務で発生する繰り返し作業を自動化したいというニーズも増加しているように思います。
そんな中、多いのが定型のメール送信を自動で送りたいというご要望です。
そこで、SharePointと連携したPower Automateを使った日時指定での自動メール送信機能について以下にご紹介します。
※豆知識も紹介しますので、ご参考にしていただければと思います。

## 概要

メール送信の概要としては、下記になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2830694/f6d73bb5-3e4c-f632-e50c-f7521b37c972.png)




## 具体例
全体像としては下記のようになります。
※詳細は、追ってご説明いたします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2830694/b65f7a9e-0fef-6283-2527-6ba7145352b8.png)

## １．トリガーを選択
トリガーには、様々なものがありますが、本日は、日時指定の自動メール送信のため、スケジューリングされたトリガーを設定します。
※こちらを手動トリガーにするとPower Appsのボタンを押下した際にメールを送信することができます。
<details><summary>もっと見る</summary>
・間隔
Power Automateの処理を実行する間隔を記載します。
※頻度に記載されている単位の間隔をどれくらいで設定するか？

・頻度
Power Automateの処理を実行する頻度を記載します。
・タイムゾーン
トリガーとして、実行される日時を指定しますが、その日時が何基準の時間なのかを設定します。
・開始時刻
自動でPower Automateの処理を実行するのは、この開始時刻以降ですというのを設定します。
※自動でメール送信をしてよい日は、この日付以降ですということが可能です。
・設定時刻(時間)
何時にPower Automateの処理を実行するかを記載します。
・設定時刻(分)
何分にPower Automateの処理を実行するかを記載します。
</details>


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2830694/132bf528-1d15-791c-786a-b14d2a846490.png)


## ２．メール送信情報取得
メールを送信する宛先を取得します。
※リストには、複数の送信先がある想定なため、「複数の項目の取得」を使い、宛先を取得します。

<details><summary>もっと見る</summary>
・サイトのアドレス

SharePointが格納されたサイトのアドレスになります。

・リスト名
SharePointのリストの名前になります。

・フィルタークエリ
SharePointのリストの抽出条件を設定できます。
※メールを送信する対象に日時を設定したい時は、下記のように設定します。
例のように現在日時以降をメール送信対象とする場合は、要注意です。
現在日時=utcNow()は、UTCの時間となりますので、トリガーの設定の際に指定したタイムゾーンとは異なる日付になる可能性があります。
そのため、下記のプログラムのように9時間時刻に足してあげる必要があります。

`
mailDate ge '@{formatDateTime(addHours(utcNow(), 9, 'yyyy/MM/dd HH:mm:ss'),'yyyy-MM-dd')}
`

</details>



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2830694/cc84d70e-af62-ab4f-300e-e22fffecf1a2.png)




## ３．メール送信
メールを送信します。
※メールにURLを添付したいことがありますが、その際は、URLを変数にいれることをお勧めします。
　URLを変数に入れずにメール本文に入れた場合、Power Automateを開くたびに文字が変換されて、本来想定していたURLとは違うものが送られてしまう可能性があります。


<details><summary>もっと見る</summary>
■変数の設定

・値
URLをメールに記載したい場合は、変数の設定の値にURLを記載してください。

■メール通知を送信する(V3)
・宛先
「複数の項目の取得」で取得したメールアドレスを入れます。
メールアドレスが固定の場合は、直接入力も可能です。

・件名
メール送信時の件名になります。

・本文
メールを送信した際の本文になります。
※メールを送信する機能は、いくつかありますが、下記の２点がよくつかわれるかと思います。
下記２点の使い分けとしては、
メールの送信(V2)：差出人を設定したい場合に使用するとよいでしょう。
※ただし、独自のSMTPサーバが必要になります。
メール通知を送信する(V3)：V2の条件に合致しない場合は使用するとよいでしょう。
※ただし、差出人は、設定できず、Power Automateが定めた差出人からメールが届くようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2830694/09e31399-3936-8447-fd52-850edbb22e23.png)


</details>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2830694/38f5f47f-3e89-c4e4-585c-d0015744406e.png)


## まとめ
Power Automateでは大きく３つの部品を使うだけでメール送信が可能です。
複雑なプログラムもないので、初心者の方も使いやすく、また、作成後にすぐに実証できるので、使用感を即時に体感いただけるかと思います。
今後も、Power AppsやPower Automateの記事を上げていきますので、繰り返し業務で多忙になっている方のご負担が少しでも軽減されればと思います。
熱指数(Heat Index) の計算のみを移植してみた 

熱指数(Heat Index) ... 熱指数は温度と相対湿度を用い、気温が実際にどのくらい暑く感じられるかを決める体感温度です

DHT11を使うときに、複数のクラスがあります。

DHT dht(DHTPIN, DHTTYPE);

DHT_Unified dht(DHTPIN, DHTTYPE);

DHT_Unifiedを使いたいが熱指数(Heat Index)の計算が無いそこで,DHTのcomputeHeatIndexを移植してみました。

湿度と温度（摂氏）のみです。

```c

float computeHeatIndex(float temperature, float percentHumidity) {
  float hi; // heat-index
  temperature = ((temperature * 9 / 5) + 32);

  hi = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) +
              (percentHumidity * 0.094));

  if (hi > 79) {
    hi = -42.379 + 2.04901523 * temperature + 10.14333127 * percentHumidity +
         -0.22475541 * temperature * percentHumidity +
         -0.00683783 * pow(temperature, 2) +
         -0.05481717 * pow(percentHumidity, 2) +
         0.00122874 * pow(temperature, 2) * percentHumidity +
         0.00085282 * temperature * pow(percentHumidity, 2) +
         -0.00000199 * pow(temperature, 2) * pow(percentHumidity, 2);

    if ((percentHumidity < 13) && (temperature >= 80.0) &&
        (temperature <= 112.0))
      hi -= ((13.0 - percentHumidity) * 0.25) *
            sqrt((17.0 - abs(temperature - 95.0)) * 0.05882);

    else if ((percentHumidity > 85.0) && (temperature >= 80.0) &&
             (temperature <= 87.0))
      hi += ((percentHumidity - 85.0) * 0.1) * ((87.0 - temperature) * 0.2);
  }
  return (hi- 32) * 5/9 ;
}
```
functools.lru_cacheに有効期限があると便利だよね。

個人的な備忘録メモです。

プロジェクト内で、DBで取得したデータってメモリないにキャッシュしておきたいなと思うことありませんか？
でも、DBの記録されているデータって常時変わる可能性があるし、いちいちサービスを止めれない。
じゃ、redisか、いやlru_cacheをうまく活用できないかと上司との擦った揉んだ（私は聞いていた）の上、
以下のページでどうやらできるらしい。

https://www.rhoboro.com/2021/06/01/lru_cache-with-ttl.html

https://stackoverflow.com/questions/31771286/python-in-memory-cache-with-time-to-live

一番参考になったのは、ほぼろさんの記事ですね。ほぼろさんの記事ではstackoverflowの内容を保管してくれていてすごく勉強になりました。

それらを踏まえて完成したのは以下のコード


```python
import functools
from datetime import datetime, timedelta
from threading import Lock

def timed_lru_cache(seconds=300, maxsize=128, typed=False):
    """
    時間制約付きlru_cache
    デフォルト300秒後、再キャッシュする。
    """

    def wrapper_cache(func):
        func = functools.lru_cache(maxsize=maxsize, typed=typed)(func)
        func.ttl = timedelta(seconds=seconds)
        func.expiration = datetime.utcnow() + func.ttl

        @functools.wraps(func)
        def wrapped_func(*args, **kwargs):
            with Lock():
                if datetime.utcnow() >= func.expiration:
                    func.cache_clear()
                    func.expiration = datetime.utcnow() + func.ttl
                return func(*args, **kwargs)

        wrapped_func.clear_cache = func.cache_clear
        wrapped_func.cache_info = func.cache_info
        return wrapped_func

    return wrapper_cache

#以下使用例
@timed_lru_cache(secconds=10)
def hoge():
    print('hoge')
    return True

>>>_hoge = hoge()
>>>hoge
>>>_hoge = hoge()
>>>_hoge = hoge()
>>>_hoge = hoge()
>>>_hoge = hoge()
>>>hoge

```

こんな感じで使えるようです。
2年経ってるのにまだまだ未熟者だなと痛感しました。
既存のSSO設定で拡張ドメインを有効化したきの問題

+ [Enhanced domains enabled, but the experience cloud SSO endpoint did not change](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000MgjCI)


拡張ドメインでは、*.force.com で終わる Experience Cloud サイト URL は *.my.site.com に変更され、*.force.com URL に依存するすべての SSO エンドポイントを更新する必要があります。

https://www.example.comなどのカスタム ドメインで Experience Cloud サイトを提供しているようです。つまり、ユーザー (および SSO エンドポイント) は *. force.com のURL。その場合、対応する認証を更新する必要はありません。

カスタム ドメイン経由で Experience Cloud サイトを提供しない場合、 ExperienceCloudSiteSubdomainを使用するすべての SSO エンドポイント。force.com のホスト名を更新する必要があります。

# Azureに関連する話題

ID プロバイダーにAzureを使っている時に「/」が指定できない？ので機能しないようなことを質問しているみたい。

[Salesforce Sandbox SSO 設定 (エンドポイント) のログイン URL が正しくないようです (/ がありません)](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000JdRflSAF)

私の理解が正しければ、参照している SSO 構成は SAML SSO IdP 構成です。もしそうなら、Salesforce がエンドポイントを更新できない理由は、エンドポイントが実際に ID プロバイダー (IdP) から来ているためです。この場合は Azure だと思います。あなた (または Azure) が外部 Azure IdP 構成内のログイン URL を更新すると、Salesforce のその画面でフィールドが更新されていることがわかると思います。 

注: [私のドメイン] の変更がプロビジョニングされた時点で は、新しい URL はまだ使用されていません。デプロイのためにステージングされているだけです。URL は近くにあり、すぐに使用できますが、まだ誰も使用できません。新しい URL は、変更を展開した後にのみ有効になります。したがって、拡張ドメインを展開した後に SSO が機能しなくなったのは、新しい URL (「サンドボックス」という単語が含まれる) が有効になったときです。

と拡張ドメインではおなじみのお姉さんが回答したけど、私には質問との関連が分からん。
やっぱり質問者さんも同じだったみたいで、再質問

Azure のログイン URL は既に更新されています。/が付いています。これは、まだ / がない Salesforce の SSO 設定 (エンドポイント) のログイン URL を更新しません。

ドキュメントの指示に従いましたが、.com 部分の前に / がないため、Salesforce SSO 設定にあるログイン URL が正しくないようです。これについて確認していただけますか。URL が Salesforce で正しくなく、Azure で入力した内容で更新されていません。

結局サポートに戻されたようですね。もともとはサポート部隊に質問したけど解決しなかったので質問として投稿したようです。
なんでもコミュニティーで質問しろと回答するのはいかがなものだろうか？


# 参考資料

+ [SSOと拡張ドメイン 2023/03/07 の話題](https://qiita.com/Keiji_otsubo/items/71376a53d44f54e9757c)
+ [注意: Sandbox 組織の拡張ドメイン適用タイミングの変更](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000J7eWH)
+ [My Domain change and SSO](https://salesforce.stackexchange.com/questions/375450/my-domain-change-and-sso)
+ [Does anyone faced issue with Single Sign On after Deploy New enhanced domain?](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000IS3ku)
+ [拡張ドメインでの SSO ログインの問題](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000HDchwSAD)

1. 私のドメイン URL では、サンドボックス インスタンス名が yourdomain--instanceNameから変更されます。my.salesforce.comを  yourdomain--instanceNameに。サンドボックス.my.salesforce.com. 
2. SSO アプリケーションは、URL への適切な有効な応答で更新する必要があります。
3. Salesforce 側では、Salesforce シングル サインオン設定のエンティティ ID を調整する必要がある場合があります。

サンドボックスの場合、拡張された [私のドメイン] のホスト名は、拡張されていないものとは異なり、「サンドボックス」サブドメインが含まれています。本番組織では、拡張された [私のドメイン] と拡張されていない [私のドメイン] の間にそのような違いはありません。
VercelからImage Optimization Source Imagesの使いすぎ警告が来た時の対応

# 本記事の目的
- NextをVercelにデプロイしているサービスが対象。
- サービスをリリースして数日後に下記の警告がメールで送られてきたので、それへの対処を紹介します。

> Hi there,
>
>We're getting in touch to let you know that your Personal Account, 名前, has consumed over 100% of the resources allocated to it during the current 30 day usage period, as per the Fair Use Policy.
>
>You can find your usage summary for the last 30 days below:
>
>Bandwidth: 247.38 MB / 100.00 GB (0.25%)
Serverless Function Execution: 0.50 GB-Hours / 100.00 GB-Hours (0.5%)
Build Execution: 0.60 Hours / 100.00 Hours (0.6%)
Image Optimization Source Images: 1,213 Source Images / 1,000 Source Images (121.3%)
Edge Middleware Invocations: 0.00 million / 1.00 million (0%)
Visit the dashboard for more details about your Personal Account's usage.
>
>Please take immediate action to avoid your account being blocked. Should your resource usage not decrease, your Personal Account will be blocked.
>
>Alternatively, you can create a Pro Team to use for your Projects. By using a Pro Team, you will have access to a greater level of resources more suitable for your use case.


# 先に結論
毎度違う画像を表示するような`next/image`に対して、`unoptimized`をつけることを検討する。

つまりこういうこと↓
```image.tsx
<Image
  src={imageUrl}
  width={90}
  height={90}
  layout="intrinsic"
  alt="cover image"
  objectFit="contain"
  unoptimized //コレを追加！！！！
/>
```

# 解説
## 警告の意味
この警告は
> Source Imagesの最適化枚数の制限を超えてるからなんとかせえよ。
なんとかしない場合はアプリ停止するからな

というもの。
Vercelでは色々なリソースの使用量に制限がかかっており、その一つにソース画像の最適化の制限がある。
無料プランで1000枚/月、proプランで3000枚/月。


## ソース画像の最適化の制限とは
この「ソース画像（Source Images）」が何かというと、`next/image`のsrcに与えている画像のこと。
[`next/image`はsrcに与えられた画像をソースとして、最適化された画像を表示してくれる。](https://vercel.com/docs/concepts/image-optimization#source-images)

↓を例に考えると、下のようなコードを書いた場合、ソース画像の最適化は2枚とカウントされる。
```image.tsx
<Image src="/hello.png" width="700" height="745" />
<Image src="/world.png" width="700" height="745" />
```

しかし↓の場合は1枚としてカウントされる。
srcに与えられた画像が同じなら、何回使ってもソース画像の最適化のは1枚とカウントされる。
```image.tsx
<Image src="/hello.png" width="700" height="745" />
<Image src="/hello.png" width="1400" height="1490" />
```
つまり基本的に`next/image`に別の画像を表示するたびにソース画像の最適化カウントが1増えると考えればよい。
これが無料プランの場合は1000枚/月に抑えないとならない。

## 注意すべきこと
ここで注意するべきが、**毎回違う画像を表示するような使い方のときに、毎回ソース画像の最適化をおこなっているとあっという間に1000枚を超える**ということ。

自分の場合は、「曲を検索してそのジャケット画像を表示する」みたいな使い方をしているところでこれをやらかした。
曲を検索するたびに7曲くらいのジャケット画像を表示していたため、色々な検索ワードでなんども検索すると、どんどんソース画像の最適化カウントが増していたよう。

このように毎回違う画像を表示する使い方の場合、ソース画像の最適化を行う必要はない。
なので
```image.tsx
<Image src={img} unoptimized />
```
のように、`unoptimized`を与えてあげることでソース画像の最適化を行わない（＝カウントが増えない）ようにしてソース画像の最適化カウントを節約する必要がある。



## 後書き
なお、今回の出来事から無料プランでも1000枚を超えてもいきなりサービス停止ではなく、多少の猶予をくれるということがわかった。
ちなみに自分は対処が遅かったので僕のアプリは無事停止されました。

停止されたサービスはこちら↓（多分9月末くらいには制限解除されて復活してると思います）
[【個人開発】推し曲を動的に生成したOGP付きで共有できるサービス「推し曲.com」を作りました](https://qiita.com/0ba/items/baf8415e0f1593f81cd1)

Twitterもやってるので、よければフォローお願いします。
→https://twitter.com/ObataGenta
Salesforce でユーザーの確認コードをスキップする


[Skip verification code for a user in salesforce](https://salesforcethinkers.home.blog/2019/06/25/skip-verification-code-for-a-user-in-salesforce/)

Salesforce でユーザーの検証コードを回避することは可能です。ユーザーが別のブラウザーまたは 別のデバイスでログインを試みるたびに、ユーザー は検証コードの入力を求められます。

この動作は、セキュリティ上の目的でブラウザーの Cookieを自動的に削除するか、ネットワーク アクセスで信頼できるログイン IP 範囲を指定しない組織内のユーザーによく見られます。

Trusted IP Rangesを指定することで、確認コードを取り除くことができ ます。Salesforce で信頼できる IP 範囲を設定 すると、ユーザーはログイン IP 制限を克服できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/7c5d1a4a-eebd-f373-1c88-8780e0264d22.png)


# ログインIP制限：

許可する IP アドレスの範囲をユーザーのプロファイルで指定して、他の IPアドレスからのログインを拒否し、指定した IP アドレスからのログインを許可することができます。

ユーザーがアクセスを拒否されると、ユーザー名またはパスワードが正しくない場合と同じエラー メッセージが表示されます。

**ログインIP制限を設定する**

1. 設定 >>クイック検索ボックスにプロファイルを入力>> プロファイル >>プロファイルを選択します。
2. [ ログイン IP 範囲]関連リストで [新規] をクリックします。
3. 有効な IP アドレスを「IP Start Address」に入力し、より大きな番号の IP アドレスを「IP End Address」フィールドに入力します。
4. オプションで、範囲の説明を入力します。
5. [保存] をクリックします。

# 信頼できる IP 範囲

信頼できる IP 範囲を設定すると、ユーザーは身元を確認せずに Salesforce に直接ログインできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a459195e-9bc1-5333-1ffb-86f7e717f697.png)


信頼できる IP 範囲は、携帯電話に送信されるコードなど、身元を確認するためのログイン チャレンジを受け取らずにユーザーがログインできるIP アドレスのリストを定義します。

組織のデータを不正アクセスから保護するのに役立ちます。ユーザーがログイン チャレンジを受けずにログインできるIP アドレスのリストを指定できます。

ユーザーが信頼できる IP 範囲外からログインしようとすると、アクティベーション コードが送信されます。コードを入力すると、 Salsforceにアクセスできます。

**信頼できる IP 範囲を設定する**

1. セットアップ >> 管理セットアップ >> セキュリティ コントロール >> ネットワーク アクセス。
2.  [新規] をクリックします。
    [開始 IP アドレス]フィールドと [終了 IP アドレス] フィールドに有効な IP アドレスを入力します 。単一の IP アドレスからのログインを許可する場合は、両方のフィールドに同じアドレスを入力します。
3. [保存] をクリックします。
格子暗号ベースの準同型暗号・秘密計算の理解に必要な数学の知識をまとめてみる

タイトルにあるとおりで，いくつかの準同型暗号の論文に対して，必要な数学の知識をまとめます．

個人的には，数学科学部２年生レベルの知識（特に「代数学」・「確率・統計」・「計算量理論」の３つ）さえ揃っていれば，大体の暗号理論の論文は読めると思いますが，
実際のところどうなんっていうのが気になったので，今まで読んできた論文などの振り返りも兼ねて，必要だと思われる数学の知識をまとめてみようと思います．

レベル分けとしては，次の３つで分けます:
- 必須
- 知っているとよい（より良く議論を理解できる）
- 知らなくてもよい（背景的な部分）

知っているとよい，は，論文中で導入・言及があるものの，土台を知っていた方がよりスッキリ理解できる部分です．
知らなくてもよい，は，直接議論には関係しないけど，背景にはこういう分野があることを表します．

# それぞれの分類
## [イデアル格子暗号入門](https://www2.iisec.ac.jp/proc/vol0006/arita14.pdf)

必須
- 高校数学（複素平面・mod）

知っているとよい
- 群論（巡回群）
- 環論（イデアル）
- 確率・統計（正規分布）

＊巡回群，は直接出てきませんが，知っていると円分整数の見通しがかなり良くなるかと

知らなくてもよい
- 初等整数論・有限体（オイラー関数）
- Galois理論・円分体（円分多項式・円分整数）

## [Generalized Compact Knapsacks are Collision Resistant](https://cseweb.ucsd.edu/~vlyubash/papers/generalknapsackfull.pdf)
必須
- 高校数学（mod）

知っているとよい
- 線型代数（$L_p, L_{\infty}$ ノルム・線型独立・基底）
- 微積（$\varepsilon$-$N$, $\varepsilon$-$\delta$）
- 環論（イデアル・剰余環・多項式環・既約多項式）
- 計算量理論（確率的多項式時間アルゴリズム）
- 確率・統計（正規分布・一様分布・条件付確率）

＊（$L_p, L_{\infty}$ ノルム）は通常，関数解析の文脈で登場することが多いですが，さすがに一部分すぎるので，線型代数の範囲としました

知らなくてもよい
- 位相空間（距離空間）
- 加群

＊normとか距離の定義は知っていてもよいかもです

## [Programmable Bootstrapping Enables Efficient Homomorphic Inference of Deep Neural Networks](https://eprint.iacr.org/2021/091.pdf)
必須
- 高校数学（mod）

知っているとよい
- 線型代数（Tensor積・$L_{\infty}$ ノルム・基底）
- 環論（剰余環・多項式環・既約多項式）
- Galois理論・円分体（円分多項式）
- 加群（Torus）
- 確率・統計（正規分布）

＊基底については，「２成分の暗号文同士を掛けると，３成分になって・・・」みたいな部分を見通しよく理解するためです

知らなくてもよい
- 多様体（Torus）

＊イデアル格子暗号入門と異なり，「2べきの$N$について，$2N$次の円分多項式の次数は$N$」をクリティカルに使う部分があるので，今回は知っているとよいに入れました

## BFV, CKKS, TFHE: Which One is the Best for a Secure Neural Network Evaluation in the Cloud?
必須
- 高校数学（mod）
- 環論（剰余環・多項式環・既約多項式）
- 確率・統計（正規分布）

＊~~説明があまりに簡素すぎるので~~色々と必須枠に入れました

知っているとよい
- 加群（Torus）

知らなくてもよい
- 多様体（Torus）

## [Leveled Multikey FHE with constant-size ciphertexts from RLWE](https://eprint.iacr.org/2022/447.pdf)
必須
- 高校数学（mod）

知っているとよい
- 線型代数（$L_{\infty}$ ノルム・基底）
- 環論（剰余環・多項式環・既約多項式）
- 確率・統計（正規分布）

知らなくてもよい
たぶんない？？？

# まとめ
こうしてみると，意外と必要な知識が被っていることが分かります．
確率・統計は案外，正規分布だけでもどうにかなるもんなんですね．あと，$L_{\infty}$ ノルムも割と使う感じっぽいですね．

振り返ってみると，

**実装メインなので，理論はそこそこの理解でいい**
→高校数学と「代数（群論・環論）」はしっかりやって，あとはポイントごとに「正規分布」・「多項式時間アルゴリズム」・「円分多項式」などを理解（飛ばしてもいい）
＊代数の数学書を何冊も読む必要はおそらくなくて，[代数学から学ぶ暗号理論](https://www.nippyo.co.jp/shop/book/5846.html)や[暗号から学ぶ代数学](https://gihyo.jp/book/2021/978-4-297-12516-5)あたりで必要な箇所のみを勉強するのも１つの手

**安全性の議論などをするため，理論をしっかり理解したい**
→数学科学部２年生ぐらいまでの範囲（微積・Jordan標準形・位相など人による部分もある）
＊学部３年生までの範囲を理解していたら，なおよいのはそれはそうなんですが，学部３年の範囲は広いので，いきなりやろうとすると大変かと

になりそうです．

ですが，どちらにも共通で一番大事なのは，行間を埋めて誤植を察する能力ですね・・・．
AWSのコンテナサービス

# AWSのコンテナサービスとは
**コンテナ**とは、プログラムの実行環境を隔離する仕組み。
Virtual BoxやVMwareなどの仮想マシンは、OS全部を仮想環境に含む。
しかし、コンテナでは、アプリケーションプロセスのみをコンテナ内に隔離し、それに必要なライブラリとデータのみを含む。そのため、とても軽量で、管理も容易。コンテナの形式としてはDockerが有名。AWSではDocker形式のコンテナをサポートする。
一般にコンテナサービスには、コンテナを配置・管理するための「レジストリサービス」と、コンテナ化されたアプリケーションの実行やコンテンナ同士の調整を行う「オーケストレーションサービス」が必要。
AWSのレジストリサービスには**Amazon Elastic Container Registry(ECR)** がある。
オーケストレーションサービスには、AWSの各サービスから成る**Amazon Elastic Container Service(ECS)** と最近脚光を浴びているKubernetes(クーベネティス)があると互換性がある**Amazon Elastic Kubernetes Service**がある。
# コンテナサービスの用語
|項目|内容|
|-|-|
|コンテナ|プログラム一式をまとめて隔離して実行するシステムのこと|
|Dockerイメージ|コンテナを構成するプログラムや設定などの一式をさす|
|Docker Hub|Dockerイメージを登録できるサービス。AWSでは、私的なDocker HubとしてECRを使用する。|
|Amazon EC2 Container Registory(ECR)|Dockerイメージを登録できるサービス|
|Amazon ECS|Dockerイメージから、EC2やAWS Fargate上にコンテナを作って実行するサービス|
|Kubernetes|コンテナを総合管理する仕組み。|
|Amazon Elastic Container Service for Kubernetes(EKS)|KubernetesをAWSに載せたサービス|
|AWS Fargate|コンテナを実行するEC2を自動管理するための仕組み|
# AWS Fargateの仕組み
AWS Fargateは、必要に応じてEC2インスタンスを起動し、その中にコンテナを割り当てて実行する仕組み。
# コンテナサービスの料金
EC2起動タイプの場合は、EC2料金のみで、追加料金がない。
Fargateタイプの場合は、割り当てCPUごとの実行単価 × 稼働時間 × コンテナ数 + メモリ単価 × 稼働時間 × コンテナ数 + データ転送料金。
# 余談
## AWSの注目されるサービス
* Amazon SageMakerとAWS Deep Learning AMI
AWSで機械学習を使用するにはAmazon SageMakerを使う方法とAWS Deep Learning AMIを使う方法がある。
Amazon SageMakerは機械学習モデルを簡単かつ迅速に構築・トレーニング、ホスト環境にデプロイするための、完全マネージドサービス。機械学習法に各種アルゴリズムや学習フレームワークを組み込んだJupyter Notebookのインスタンスを用いてモデルの構築とトレーニングを行う。
一方で、AWS Deep Learning AMIは、深層学習用のフレームワークとインターフェースを有するAmazon EC2インスタンス。SageMakerより環境や手法の選択幅が広く、カスタマイズ可能で、機械学習の詳細な研究に向く。
* AWS IoT Core
AWS IoT　CoreはIoTデバイスとAWS、またはIoTデバイス間のインターネット接続・通信を行うためのマネージド型クラウドサービス。数十億個のIoTデバイスと数兆件のメッセージを取り扱える。
HTTTPなどの標準通信プロトコルをサポートしており、TLS暗号化と認証により通信の安全を守りる。AWS SDKおよびAWS IoT Device SDKを用いて、IoTデバイスから送信されたデータの処理、IoTデバイスを操作するアプリケーションの開発と実行ができる。
* Amazon Lumberyard
Amazon Lumberyardはゲームエンジン。付属のゲームエディタでゲームを作成する。
入手のしようも無料で、運用のためにAWSを利用するときに料金がかかるだけで、ゲーム収益からの支払い義務もない。
ライブゲームやマルチプレイヤーゲームの運営、動的コンテンツの利用にはクラウドコンピューティング・ネットワークリソースやストレージを使用する事になるため、そのときにAWSクラウドと統合されたLumberyardの特徴が活かされる。
ライブストリーミング配信のプラットフォームのTwitchとも連携でき、動画付きのチュートリアルやドキュメント、フォーラムなどのでゲーム開発を取得できる。
Lightning Email TemplatesでCustomMetadata or Labelsが使えない

元の質問 : [Is it possible to access CustomMetadata or Labels from Lightning Email Templates?](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000JdRwN)

私の回答は対応してないのでできないです。

[Custom lable/settings/metadata in email templates](https://salesforce.stackexchange.com/questions/377445/custom-lable-settings-metadata-in-email-templates)

In a Plain Text or HTML template, you need a formula, but in a Visualforce template, you can use the global variables directly to access labels, settings, metadata, etc.

プレーン テキストまたは HTML テンプレートでは数式が必要ですが、Visualforce テンプレートではグローバル変数を直接使用してラベル、設定、メタデータなどにアクセスできます。

上記の回答も一緒につけたけど、納得しなかったようですねぇ。私に言われても... SFさんが対応しないんだからどうしようもない。

こんなものを再投稿されてもなぁ。HTMLテンプレートではできないよって回答したんだけど...

```
<html style="overflow-y: hidden;"><head>	<title></title></head><body> Hello {{{Case.Name}}}<br/>			   <a href="{{!$CustomMetadata.Test__mdt.Record.Data__c}}{{{Case.Id}}}" target="_blank"> Link to another page </a></body></html>
```

ここでもできないようなことが言われています。

[Lightning メールテンプレートでカスタム表示ラベルを使用することはできますか?](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000A7cWKSAZ)

回避策はカスタムフィールドの中でCustomMetadata or Labelsを使って、そのフィールドをメールテンプレートで呼び出すみたいです。

[Using Custom Metadata Type in Email Template](https://salesforce.stackexchange.com/questions/261302/using-custom-metadata-type-in-email-template)

You can use custom metadata types in SObject Formula fields so the following works fine (example):

**On Contact SObject**
New formula field (text) Foo__c with value

```
$CustomMetadata.MyCustomMetadataType__mdt.SomeDeveloperNameOfRow.SomeFieldName__c
```

**In email template:**

```
Hello {!Foo__c}
```