OmniAICreator/Qiita-1.07M huggingface dataset:
【Flutter】初心者必見！入力フォームってどうやって作るの？

こんにちは！
今回はflutterでの入力フォームの作り方について紹介いたします！
最後まで記事を読んでいただけたら嬉しいです！

## 1,入力フォームって何？
入力フォームは、ウェブサイトやアプリケーションでユーザーからテキストやデータを収集するための対話型な要素です。ユーザーがテキストを入力し、データを提供し、そのデータをアプリケーション内で処理するために使用されます。入力フォームは、ユーザーから情報を受け取るための主要な方法の一つで、ウェブページ、モバイルアプリ、デスクトップアプリなどで利用されています。

#### テキストフィールド: 
ユーザーがテキストを入力できるフィールド。例えば、名前、メールアドレス、検索クエリ、コメントなど。

#### パスワードフィールド:
ユーザーがパスワードなどの機密情報を隠して入力できるフィールド。

#### 選択フィールド:
ユーザーがオプションから選択できるセレクトボックス、ラジオボタン、チェックボックス、ドロップダウンリストなど。

#### ボタン: 
フォームの送信やアクションのトリガーを提供するボタン。通常、フォームの送信を行うボタンが含まれます。

#### バリデーション:
入力データが有効であるかを確認するためのバリデーションルール。バリデーションエラーメッセージは、不正確なデータを修正するのに役立ちます。

#### 送信: 
ユーザーがフォームに入力したデータをアプリケーションやサーバーに送信するプロセス。


## 2,入力フォームの作り方

#### TextFieldウィジェットの追加:
テキスト入力フォームを作成するには、TextFieldウィジェットを使用します。
```php
TextField(
  decoration: InputDecoration(
    labelText: '名前', // ラベル
  ),
)
```

#### フォームの送信ボタンの追加:
フォームデータを送信するためのボタンを追加します。例えば、ElevatedButtonウィジェットを使用して、送信ボタンを作成できます。
```php
ElevatedButton(
  onPressed: () {
    // フォームが送信されたときの処理を記述
  },
  child: Text('送信'),
)
```

#### バリデーションの追加:
フォームデータが有効であることを確認するために、バリデーションを追加することが一般的です。例えば、TextEditingControllerを使用してフォームデータを取得し、バリデーションを行います。
```php
final nameController = TextEditingController();
// バリデーションルールを追加
if (nameController.text.isEmpty) {
  // エラーメッセージを表示するか、エラー処理を行う
}
```

## 3,使用例
```php
TextField(
            decoration: InputDecoration(
              labelText: "日本語入力",
              border: OutlineInputBorder(
                borderRadius: BorderRadius.circular(10.0), // 枠線の角の丸みを設定
              ),
            ),
          ),
        ElevatedButton(
          onPressed: () {
            // フォームが送信されたときの処理を記述
          },
          child: Text('送信'),
        )
```
![入力フォーム.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524127/b79a6f0c-36dc-0553-e7b4-188ecef59c37.gif)

## 4,最後に
今回の紹介は以上になります！
最後まで見ていただきありがとうございました！
では、また次の記事で〜！
axiosのrequest/response Object keyのケース変換を行うライブラリを公開した話

## はじめに

[axios](https://www.npmjs.com/package/axios)を利用してAPIを呼び出しているアプリケーションは無数にあると思う。しかし、キーのケース違いで実装にわずらわしさを感じる場面も少なくない。

具体的には、REST APIでは*snake_case*だが、JavaScript/TypeScriptでは*camelCase*というのはよくあるだろう。

今回はそのケース違いによる煩わしさ（ケース変換の手間）をなくしてくれるライブラリを公開したので、そのライブラリの紹介をしたいと思う。

## [simple-axios-case-converter](https://www.npmjs.com/package/simple-axios-case-converter)

https://www.npmjs.com/package/simple-axios-case-converter

というライブラリを利用することで、ケース変換の手間から解放される。

利用方法は簡単で、以下のようにaxiosをこのライブラリの関数に渡すだけ。

```ts
import axios from 'axios';
import axiosCaseConverter from 'simple-axios-case-converter';

axiosCaseConverter(axios);
```

これで、あとはいつも通りに`axios.get()`や`axios.post()`などを使ってAPIを呼び出せばいい。実装時はすべてcamelCaseで実装できる。

```ts
// you need not convert request `params` to snake_case
axios.get('https://example.com/api/v1/todos', { params: { onlyComplete: true } });

// you need not convert request `data` to snake_case
axios.post('https://example.com/api/v1/address', {
	countryCode: 'JP',
	postalCode: '123-4567',
	prefecture: 'Tokyo',
	city: 'Shibuya'
});

// you need not convert request `data` to snake_case
axios.patch('https://example.com/api/v1/address/123', { postalCode: '123-4567' });

// you need not convert request `data` to snake_case
axios.delete('https://example.com/api/v1/address/123', { data: { addressId: 123 } });
```

このライブラリはaxiosのinterceptorを利用しているので、もしケース変換をしないようにしたい場合には、以下のように`eject`を利用すればいい。

```ts
const { requestInterceptorId, responseInterceptorId } = axiosCaseConverter(axios);
axios.interceptors.request.eject(requestInterceptorId);
axios.interceptors.response.eject(responseInterceptorId);
```

## まとめとして

似たようなライブラリに[axios-case-converter](https://www.npmjs.com/package/axios-case-converter)があるが、そのライブラリをよりシンプルにしたものとして今回、[simple-axios-case-converter](https://www.npmjs.com/package/simple-axios-case-converter)を公開してみた。

※詳細の違いについては[What is different from axios-case-converter](https://www.npmjs.com/package/simple-axios-case-converter?activeTab=readme#what-is-different-from-axios-case-converter)を参照ください。
Oracle19c@Windowsで統合監査を有効化する手順

# 現状の確認

``` sql
SELECT VALUE FROM V$OPTION WHERE PARAMETER = 'Unified Auditing';
```

FALSEとなっている場合は統合監査が無効です。

# 統合監査の有効化

## ファイルのリネーム

``` cmd
cd c:\Oracle\product\19.3.0\dbhome_1\bin
dir orauni*
```

> 2021/04/22  05:16             8,704 orauniaud19.dll.dbl

```
move orauniaud19.dll.dbl orauniaud19.dll
dir orauni*
```

> 2021/04/22  05:16             8,704 orauniaud19.dll

## Oracleサービス再起動

``` cmd
net stop OracleServiceCDB
net start OracleServiceCDB
```

## 結果の確認

``` sql
SELECT VALUE FROM V$OPTION WHERE PARAMETER = 'Unified Auditing';
```

TRUEになっていれば有効化されています。

# ログオン監査の有効化

統合監査を有効化した時点では、ログオン失敗の監査のみが有効になっています。

``` sql
CREATE AUDIT POLICY LOGIN_BY_ALL_USERS ACTIONS LOGON;
AUDIT POLICY LOGIN_BY_ALL_USERS;
```

上の例では、全てのユーザによるログインを監査します。

ユーザを特定することも可能です。

``` sql
CREATE AUDIT POLICY LOGIN_BY_SPECIFIC_USERS ACTIONS LOGON;
AUDIT POLICY LOGIN_BY_SPECIFIC_USERS BY USER01;
```

上の例では、DBA20548ユーザによるログインを監査します。
複数ユーザを列挙することもできます。

``` sql
AUDIT POLICY LOGIN_BY_SPECIFIC_USERS BY USER01, USER02;
```

逆に特定のユーザを除外することもできます。

``` sql
CREATE AUDIT POLICY LOGIN_BY_EXCEPTED_USERS ACTIONS LOGON;
AUDIT POLICY LOGIN_BY_EXCEPTED_USERS EXCEPT USER01, USER02;
```

## 応用

特定のOSユーザ、マシンからのログインのみを監査することが可能です。

- 特定のホスト名

```
CREATE AUDIT POLICY LOGIN_BY_SPECIFIC_HOSTS ACTIONS LOGON
WHEN 'SYS_CONTEXT(''USERENV'',''HOST'') IN (''Machine01'',''Machine02'')'
EVALUATE PER SESSION;
AUDIT POLICY LOGIN_BY_SPECIFIC_HOSTS;
```

NOT IN も可能です。

```
CREATE AUDIT POLICY LOGIN_BY_SPECIFIC_HOSTS ACTIONS LOGON
WHEN 'SYS_CONTEXT(''USERENV'',''HOST'') NOT IN (''Machine01'',''Machine02'')'
EVALUATE PER SESSION;
AUDIT POLICY LOGIN_BY_SPECIFIC_HOSTS;
```
react ダイアログ

```react
const items = [
  { key: '1', name: 'アイテム1', value: '100' },
  { key: '2', name: 'アイテム2', value: '200' },
  // 他の行データを追加
];



import React from 'react';
import { Dialog, DialogType, DialogFooter, PrimaryButton } from '@fluentui/react';
import { DetailsList, DetailsListLayoutMode, SelectionMode, IColumn } from '@fluentui/react/lib/DetailsList';

const MyTableDialog = ({ showDialog, onClose, items }) => {
  const columns: IColumn[] = [
    { key: 'name', name: '名前', fieldName: 'name', minWidth: 100, maxWidth: 200, isResizable: true },
    { key: 'value', name: '値', fieldName: 'value', minWidth: 100, maxWidth: 200, isResizable: true },
  ];

  return (
    <Dialog
      hidden={!showDialog}
      onDismiss={onClose}
      dialogContentProps={{
        type: DialogType.normal,
        title: '表のタイトル',
      }}
      modalProps={{
        isBlocking: false,
        styles: { main: { maxWidth: 600 } },
      }
    >
      <div>
        <DetailsList
          items={items}
          columns={columns}
          selectionMode={SelectionMode.none}
          layoutMode={DetailsListLayoutMode.fixedColumns}
        />
      </div>
      <DialogFooter>
        <PrimaryButton onClick={onClose} text="閉じる" />
      </DialogFooter>
    </Dialog>
  );
};

export default MyTableDialog;












import React, { useState } from 'react';
import MyTableDialog from './MyTableDialog';

const ParentComponent = () => {
  const [isDialogVisible, setIsDialogVisible] = useState(false);

  const openDialog = () => {
    setIsDialogVisible(true);
  }

  const closeDialog = () => {
    setIsDialogVisible(false);
  }

  const items = [
    { key: '1', name: 'アイテム1', value: '100' },
    { key: '2', name: 'アイテム2', value: '200' },
    // 他の行データを追加
  ];

  return (
    <div>
      <a href="#" onClick={openDialog}>ダイアログを開く</a>
      <MyTableDialog showDialog={isDialogVisible} onClose={closeDialog} items={items} />
    </div>
  );
};

export default ParentComponent;



```
【Salesforce】0から始めて認定アソシエイト試験に合格しました



# 1.はじめに

2023年10月に、Salesforce認定アソシエイトに受験して合格しました。
今回は、受験までの学習方法や受験当日の様子などについて振り返りたいと思います。

長くなったので、勉強方法だけ知りたい！という方は「[5. 勉強方法と期間](#5勉強方法と期間)」までジャンプしてください。


# 2.試験について

- 2023年2月に登場した資格
- Salesforce エコシステムの初心者で、Salesforce Customer 360 Platform を理解して使用することに関心がある方が対象
:::note info
エコシステム：生態系の用語。ある領域（地域や空間など）の生き物や植物がお互いに依存しながら生態を維持する関係のようすを表します。
:::
- Salesforceの実務経験が0〜6ヶ月の人が対象→実務経験がなくてもOK
- 受講料：10,000円／70分の試験（2回まで0円で再受験可能）
- オンライン・オフラインともに受験可能


# 3.受験前の状況

- 「Salesforce = 営業支援ツール」という認識
- 実務経験0、アカウントの登録からスタート


# 4.受験の目的

Salesforceの理解を深めること


# 5.勉強方法と期間

## ①勉強方法

職場の方に聞いたりネットで情報収集し、ハンズオンで学ぶ→過去問を解く流れで進めました。
本番の形式に慣れておくためにも、過去問を解くことをおすすめします。

### (1)Trailhead

Trailheadは、Salesforceが無料で提供しているオンラインサービスです。
認定アソシエイト資格用のカリキュラムがあるので、上から順番に進めていきました。

https://trailhead.salesforce.com/ja/users/strailhead/trailmixes/prepare-for-your-salesforce-certified-associate-credential

ハンズオン・クイズ形式となっており、各単元の最後にチャレンジ問題がついています。
「実務で知っていると便利そう」と考えながら進めていきました。

チャレンジ問題でうまく行かないときは、以下で大体クリアできました。
- 言語を英語に設定する
- Playgroundを作り直す（作り直すとうまくいくことがある）
- 「Salesforce + 単元名」などで調べる（他の人がヘルプで質問していることがある）

### (2)過去問

以下のnoteを購入し、試験当日まで周回しました。

- Salesforceベーシックプランに加入し、「Salesforce認定アソシエイト対策問題集①②」を解く
- 「解説：Salesforce認定アソシエイトPACK」で解説を読む

https://note.com/salesforce777/membership

https://note.com/salesforce777/m/m62f6cc86ad96

## ②期間

125時間(約1.5ヶ月)


# 6.申込

テストセンターで受けようと思っておりましたが、最寄りのテストセンターは対象外となっていたのでオンライン受験にしました。
当日申し込みもできたりと、受けられる日程が多く驚きました。

https://tandc.salesforce.com/webassessor-apply

スケジュールの変更やキャンセルは試験開始時刻の 24 時間前まで可能で、それ以降の場合は費用が発生します。


# 7.受験当日

オンラインでの受験の場合、トラブルが起きることがあります。**「受験に関する記事を読んでおいた方が良い」** とアドバイスを頂いていたので、認定アソシエイトや他のSalesforceの認定資格を受験した方の記事を読んでいました。

以下、当日の様子を記載します。

## ①パソコンのOS

Macのパソコンで受験しようと思っていたのですが、手持ちのパソコンはOSが対象外でした。
**「OSが対象外で不合格判定となった」** という記事を見て、慌ててWindowsのパソコンを用意してWindows11で受験しました。

## ②セキュリティソフト

セキュリティソフトを切り忘れていました。その結果、

- カメラの許可の承諾ができない（試験用のソフトが1つのタブしか操作できないような仕様になっていた）
- 顔認証ができない
- 画面は「exit exam」のボタンしか押せない

…という状況になりました。**「ここで受験終了？！」** と焦ったのですが、ダメ元で「exit exam」をクリックしてカメラを許可することで、再度受験ができました。

試験時間にはカウントされていなかったので良かったです。

## ③顔認証

「何もない状態の部屋」で受験するため、仕事後に浴室で受験したのですが、日が落ちるスピードが早く、事前の顔認証と受験時で照明が全然違う状態になっていました。（別人扱いされなくて良かったです...:sweat_smile:）

## ④メガネ

事前に見ていた受験の動画では「メガネを確認するので指示があったら外してください」とのことでしたが、何もありませんでした。（カメラはずっとオンの状態でした）

## ⑤お風呂が苦しい

お風呂の浴槽にパソコンを持ち込んで受験をしたことと、「試験を最後まで受けられないかも」と焦った結果、終盤は窮屈さで苦しみながら進めておりました。。

受験中は席を外すことができないので、広い浴槽もしくは部屋で受験することをおすすめします:clap:


# 8.結果

焦る場面もありましたが、無事合格することができて安心しました:tada:
試験結果はすぐに確認することができ、その後メールで認定証が届きました。


# 9.参考

https://www.salesforce.com/jp/blog/salesforce-associate-certification/

https://quip.com/qBRXAsRSoVho

https://makefri.jp/marketing/13156/

https://www.cct-inc.co.jp/news/technology/salesforce-trailhead/

https://note.com/shift_tech/n/na447c8d8dbf2#12aa5ac6-b9c4-41c0-9bd9-23f2b50dbf05

https://kojinjigyou.org/9007/


# 10.おわりに

0から始めて、無事に合格することができて本当に良かったです。
ゆくゆくは他の資格にも挑戦していきたいなと思いました。

記事の感想や意見、ご指摘等あれば伝えていただけるとありがたいです。
読んでいただき、ありがとうございました。
【Javascript】テキストボックスでEnterキーを押したら任意の処理を発火させる

# はじめに
テキストボックスでEnterキーを押したときに任意の処理を発火させるにはどうすればいいのか調べたときの備忘録です。

# やりかた
- ~~`addEventListener`で`keypress`イベントを登録する。~~
- `addEventListener`で`keydown`イベントを登録する。
- ~~`Event`オブジェクトから`keyCode === 13`で条件分岐をする。~~
- `Event`オブジェクトから`key === 'Enter'`で条件分岐をする。
:::note warn
注意
`keypress`イベント及び`keyCode`プロパティは現在非推奨となっています。
`keydown`イベント及び`key`や`code`など他のプロパティに変更することをお勧めします。
(@jsdtue55 さんよりコメントにてご教授いただきました。ありがとうございます。)
:::


## サンプル
テキストボックスでEnterキーを押したときにコンソールに文字を表示します。

```html:sample.html
<html lang="ja">
	<head>
		<title>さんぷる</title>
	</head>
	<body>
		<h1>さんぷる</h1>
        <!-- ↓のテキストボックスでEnterキーを押したらイベントが発火 -->
		<input type="text" id="textbox">
	</body>
	<script src="sample.js"></script>
</html>
```

```Javascript:sample.js
document.addEventListener('DOMContentLoaded',pageLoad)

/* ページをロードした時にテキストボックスにリスナを登録 */
function pageLoad(){
	var textbox = document.getElementById('textbox');
	textbox.addEventListener('keydown', enterKeyPress);
}

/* テキストボックスでEnterキーが押されたらコンソールに文字を表示 */
function enterKeyPress(event){
	if(event.key === 'Enter'){
		console.log('Press your Enter key.')
	}
}
```

おしまい。
B2C CommerceでJavaScriptが反応しない原因の対応

# 事象
添付画像のように、商品ソートボタンを押しても、商品の並び替えが反映されない。
商品の並び替え自体は、以下のJavaScriptで制御している。

`cartridges/bbiq_ec_app_storefront_base/cartridge/client/default/js/search/search.js`

![スクリーンショット 2023-10-23 9.15.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/535f15eb-fa4e-68e9-a939-aaf2c1ae4a74.png)

# 原因１（コンパイルエラー）
ブラウザのデベロッパーツールで確認すると、JavaScriptファイルのコンパイルエラーが発生していた。
そのため、コンパイルエラーを解決して、カートリッジをアップロードしたが解決せず。

# 原因２（サイトのキャッシュが有効になっていた）
Business Manager上でのサイトのキャッシュが有効になっていた。
キャッシュが有効になっている場合、ソートがキャッシュによって制御される場合がある。
そのため、キャッシュを無効化した状態でテストすることが良い。

設定は以下。
管理 >  サイト >  サイトの管理 > (対象のサイト) > キャッシュタブ

静的コンテンツの TTL (有効期限):0 に設定
サイトの静的コンテンツキャッシュとページ全体キャッシュ：　無効化にするをクリック
サイトのページ全体キャッシュ：　無効化にするをクリック

![スクリーンショット 2023-10-23 8.12.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/a23541e0-9a97-a4fe-5bbb-bf5cc267390e.png)

# 再コンパイル
ローカルで再度コンパイルし、カートリッジをアップロード。
ストアフロントで動作確認。
正常に動作していることを確認。
algebraic effectとはなんなのか



### Algebraic Effects とは?
Algebraic Effects は、計算の途中で特定の効果を「要求」し、その効果が外部で「提供」される仕組みを指します。これにより、関数や計算の内部ロジックを、外部の効果や副作用から疎結合に保つことができます。

### なぜ Algebraic Effects なのか?
1. 疎結合
関数内部のロジックと外部の世界（例: IO、データベース、API呼び出し）との結合を疎にすることで、テストや再利用が容易になります。

2. 明確な副作用の取り扱い
Algebraic Effects を使用すると、副作用の発生点とその処理方法を明確に分けることができ、コードの理解やメンテナンスがしやすくなります。

3. 実際のコード例
```python
def main_function():
    try:
        value = yield "Request Value"
        print(value)
    except ProvideEffect as e:
        if e.effect == "Request Value":
            e.resume("Value from outside")
```
上記のコードでは、main_function 内で "Request Value" という効果を要求しています。この要求は、外部で捕捉され、適切な値が提供されることを期待しています。追記予定。

### 他のアプローチとの比較
1. モナド
モナドは、副作用を型システム内で取り扱うための関数型プログラミングのアプローチです。Algebraic Effects はこのモナドと似ていますが、もう少し柔軟性があり、中間の計算を外部で補完することが可能です。

2. コルーチン
コルーチンもまた、非同期や副作用を扱うための手段として知られています。Algebraic Effects はこのコルーチンの考え方を一般化したものとも言えるでしょう。

### 次は
- モナド
- コルーチン
- ...
Sphinxのテーマ"Read the Docs"のカスタマイズ

# 目的

* `sphinx_rtd_theme`の横幅を広げる（など）
* property属性が１行に詰め込まれてレイアウトされるのを防ぐ

# 仕掛け

```css:docs/source/_static/css/custom_sphinx_rtd_theme.css
/*
 * 「Sphinx の sphinx_rtd_theme をカスタマイズする」
 * https://kuttsun.blogspot.com/2016/11/sphinx-sphinxrtdtheme.html
 */

.wy-nav-content {
    max-width: 1600px;
}

h1,h2,h3,h4,h5,h6 {
    border-bottom: 1px solid #ccc;
}

.wy-table-responsive table td, .wy-table-responsive table th {
    white-space: normal;
}

colgroup {
    display: none;
}
```

```css:docs/source/_static/css/fix-layout-pyproperty.css
/*
 * py:property's stacking on a single line on larger screen widths.
 * https://github.com/readthedocs/sphinx_rtd_theme/issues/1301
 *
 * > Problem
 * > Multiple properties I defined in the docs are all stacking on a single line.
 * > （ドキュメントで定義した複数のプロパティがすべて1行に重なっている）
 *
 * https://github.com/readthedocs/sphinx_rtd_theme/issues/1301#issuecomment-1219961515
 * https://gist.github.com/nocarryr/846301fd5c9083e2243346d19e55b5a3#file-override-css
 */

dl.py.property {
    display: block !important;
}
```

* `sphinx-apidoc -F`コマンドで生成される`conf.py`に以下を設定

```py:docs/source/conf.py
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

html_theme = 'sphinx_rtd_theme'
html_static_path = ['_static']
html_css_files = ['css/custom_sphinx_rtd_theme.css', 'css/fix-layout-pyproperty.css']
```

# 参考URL

* [Sphinx の sphinx_rtd_theme をカスタマイズする](https://kuttsun.blogspot.com/2016/11/sphinx-sphinxrtdtheme.html)
* [py:property's stacking on a single line on larger screen widths.](https://github.com/readthedocs/sphinx_rtd_theme/issues/1301)
Program Management Module　(PMM)　

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめN～Z](https://qiita.com/Keiji_otsubo/items/92f92bb9f668ca9688be)


+ [トレイルヘッド](https://qiita.com/Keiji_otsubo/items/c496614734e0d959686d)
+ [プログラム管理モジュール (PMM)](https://qiita.com/Keiji_otsubo/items/a6a83fd96091234aaec5#2-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E7%AE%A1%E7%90%86%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB-pmm)


# Whoops, looks like there was a problem. Please try again

+ [Administer Program Management Module (PMM)>Build an Email Flow for Program Management Module (PMM)>Build the Flow](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Ou276)

:::note
I ended up deleting everything and starting over from the beginning! 
:::

+ [Winter '24　での障害？PMM Component Error when creating Service Schedules](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007MY5As)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/eeacd0c6-6edc-8b8d-80fc-8b8b8dbab08b.png)

:::note
UPDATE: Above mentioned workaround is no longer applicable due to some recent updates. As of now, we do not have a workaround until the issue is resolved.
:::

# その他

+ [PMM Service Delivery creation process failing intermittently - 'Unable to lock row'](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007PhZnX)

:::note alert
The error is: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY: pmdm.ServiceDeliveryTrigger: execution of AfterInsert caused by: System.DmlException: Update failed. First exception on row 0 with id a1m5f000000X5D5AAK; first error: UNABLE_TO_LOCK_ROW, unable to obtain exclusive access to this record or 1 records: a1m5f000000X5D5AAK: [] (System Code).
:::

+ [ここの連絡先に表示されるフィールドを変更したいと考えています。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ZB991SAD)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/57950bdb-a435-dfa7-a3ae-caa5bbb9dff2.png)

:::note
Those columns are taken from the SessionParticipantView fieldset on the Program Engagement object. 

Any changes should affect both the Contact Selection screen of the Bulk Service Deliveries (by Group) component and the Add Service Participants screen of the Service Schedule component

これらの列は、Program Engagement オブジェクトの SessionParticipantView フィールドセットから取得されます。 

変更は、一括サービス配信 (グループ別) コンポーネントの連絡先選択画面とサービス スケジュール コンポーネントのサービス参加者の追加画面の両方に影響します。
:::


# 未解決

+ [How to add + component to a dashboard in PMM](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007cmHzQSAU)
読まないでいいです　どうせバズらないし笑

　　　　　･プログラミングメモ

→段落をつけながら箇条書きでOK!!

→ほとんどコピペでもOK!!

→何でも気軽にメモする

→綺麗にすることにこだわりすぎない

→タイトルにキーワードを入れておく

①知らないことを学ぶ為に

　　

②errorに詰まった時の為に

　　・やりたいことをまず書く、そしてやったことを書く

　　・次にerror内容について書く→errorメッセージを全文メモしておく

　　・原因を書く

　　・解決策を書く

　　　　　　　　　　　　　⇓

　　先ずは上記の項目ごとに見出しだけ書く（つまり、骨格だけ）

　　解決した際に使った記事などを参考に残しておく!!（URL，リンクをはる）

　　間違えたところも解決策に乗せておく
アトミックデザインについて雑に調べてまとめたやつ


<a id="overview"></a>
## アトミックデザインとは
アトミックデザインは、Brad Frostによって提唱されました。彼の考え方は、自然界の原子から生命体への進化をヒントに、UIもまた小さな部品から構築すべきだというものです。

<a id="levels"></a>
## 5つのレベルについて

### Atoms (原子)
これはUIの最も基本的な部分です。例としては、ボタンやテキスト、アイコンなどが考えられます。それ自体ではあまり役に立たないことも多いですが、他の原子と組み合わせることで役立ちます。

### Molecules (分子)
2つ以上のAtomsを組み合わせて作られるUIの部品です。例えば、テキストフィールドとそのラベル、ボタンなどからなる検索フォームがこれに該当します。

### Organisms (有機体)
MoleculesやAtomsを組み合わせて、より複雑なUI部品を構築します。例としては、ヘッダーやフッター、サイドバーなどが考えられます。

### Templates (テンプレート)
実際のコンテンツを持たない、ページのレイアウトや骨組みを示す部分です。ここでページの全体的な流れや構造を確認できます。

### Pages (ページ)
Templatesに実際のコンテンツやデータです。実際のページの見た目や動作を確認することができます。

<a id="pros-cons"></a>
## メリットとデメリット

### メリット
- **一貫性**: 同じコンポーネントを再利用することで、UIの一貫性を保つことが容易になります。
- **効率性**: 一度作成したコンポーネントは、他の場面でも再利用することができます。
- **保守性**: 小さな部品ごとに修正や更新ができるため、変更が容易です。

### デメリット
- **設計の難しさ**: 最初からしっかりとした設計が必要となります。
- **過剰な抽象化**: あまりに細かく分けると、かえって複雑性が増すことも。

<a id="implementation"></a>
## 実際の実装例

アトミックデザインはReactやVueなどのフロントエンドフレームワークでの実装に適しています。コンポーネントベースの設計とアトミックデザインは非常に相性が良いです。

```python
# Atomの例: Buttonコンポーネント
def Button(text):
    return f"<button>{text}</button>"

# Moleculeの例: Formコンポーネント
def Form(label_text, button_text):
    return f"<label>{label_text}</label><input type='text'><button>{button_text}</button>"
```

<a id="when-to-use"></a>

### アトミックデザインを採用するべき時
大規模なプロジェクトや、再利用の必要が多いプロジェクトでは、アトミックデザインの採用を検討する価値があります。また、チーム開発の際にも一貫性を保つために役立ちます。

<a id="conclusion"></a>

### まとめ
ある程度学習すればそこまで難しい概念ではなさそう
挙動はどこで制御すれば良いのだろうか、より詳しく調べていきたい。
MegatronLMを解説

# はじめに
LLMはモデルがサイズがデカすぎるため、複数のGPUにモデルを分割配置して学習を行います。MegatronLMはモデルを分割する手法の一つであり、Transoformerを分割することに特化しています。今回はそんなMegatronLMを説明したいと思います。

https://arxiv.org/abs/1909.08053

# モデルの分割
皆さんもご存知の通りLLMのモデルは非常にサイズがでかいです。例えばllama2-70bのモデルは140GBです。GPUのメモリサイズは多くても100GBほどですので、1つのGPUには乗り切らないです。学習際にはモデル以外にactivationなどをメモリに保持しないといけないので、1つのGPUで学習することは当然できないです。それを可能にしてくれるのがモデル分割手法たちです。

モデル分割手法はレイヤー間でモデルを分割する手法とレイヤー内でモデルを分割する手法があります。レイヤー間の分割は非常に単純でTransformer blockの切れ目でモデルを分割するといった感じです。レイヤー内のモデルの分割はTransoformer block内のAttentionやFFNを分割する手法です。MegatronLMはそんなレイヤー内のモデル分割手法であり、AttentionのFFNを分割します。

# MegatronLM
MegatronLMではTransformer blockのAttentionとFFNを分割しますが、分割方法はそれぞれ少し異なっています。

### Attentionの分割
Attentionの分割は正確にとMulti-Head Attentionを分割します。簡単にいうとhead数が8でGPU数が２だとするとhead1~4をGPU1が実行し、head5~8をGPU2が実行して、最後にお互いに結果を送りあうという感じです。これを順に説明してきます。

まず、Muti-Head Attentionは次の式でかけます。$n$はhead数で、$I$は入力、$W_i^Q,W_i^K,V_i^V$はそれぞれ、$QKV$を計算する重みを列方向に$i$個に分割した時の$i$番目です。
```math
\begin{align}
MutiHeadAttention(Q,K,V) & = Concat(h_1,h_2,...h_n)W^O\\
h_i & = Attention(Q_i,K_i,V_i)\\
Attention(Q,K,V) & = Softmax(QK^T)V\\
Q_i & = IW_{i}^Q\\
K_i & = IW_{i}^K\\
V_i & = IW_{i}^V\\
\end{align}
```
この計算を複数のGPUで実行します。でもそんなには難しくないです。$n$が2でGPU数も2の時を考えると下のように書けるはずです。$W_i^O$は$W^O$を行方向に分割した$i$番目のことで、よりわかりやすくするためにConcatの部分を式変形しています。
```math
\begin{align}
MutiHeadAttention(Q,K,V) & = Concat(h_1,h_2)W^O\\
& = 
\begin{bmatrix}
h_1 & h_2
\end{bmatrix}
\begin{bmatrix}
W_1^O \\
W_2^O
\end{bmatrix}
\\
& = h1W_1^O + h2W_2^O
\end{align}
```
これの$h1W_1^O$をGPU1で行って、$h2W_2^O$をGPU２で行います。その後、お互いに自分が計算した結果を相手に送ってあげて、相手から受けとた結果を自分が計算した結果に足してあげれば、無事に計算ができることがわかると思います。

###　FFNの分割
FFNの分割はAttentionの分割を理解していれば非常に簡単です。まず、FFNは次のように書けると思います。
```math
\begin{align}
FFN(I) = GeLU(IW)
\end{align}
```
これのWを分割してあげます。分割する方法は列方向で2分割した場合は下記のように$W_1,W_2$と分割できます。

```math
\begin{align}
FFN(I) = GeLU(I
\begin{bmatrix}
W_1\\
W_2
\end{bmatrix}
)
\end{align}
```
これをさらに変形してあげると次のようになるはずです。
```math
\begin{align}
FFN(I) &= GeLU(I
\begin{bmatrix}
W_1\\
W_2
\end{bmatrix}
)
\\
& = GeLU(Concat(IW_1, IW_2)) \\
& = Concat(GeLU(IW_1), GeLU(IW_2))
\end{align}
```
Concatは行列を列方向にくっつけるだけですので、GeLUの中にあった、Concatを外に出してあげて大丈夫です。これの$GeLU(IW_1)$をGPU1で計算し、$GeLU(IW_2)$をGPU2で計算し、お互いに送り合ってConcatしてあげれば、無事に計算できるはずです。

これで、無事にAttentionもFFNも分割して行えることがわかりました。最後まで読んでいただきありがとうございます。
【Android】WebViewでプロキシ(proxy)の設定をする方法

Androidアプリ開発において、WebViewで開くページにプロキシを適用させる必要があったので、その方法についてメモしておきます。

# `ProxyController` を使えばOK
[Webkit](https://developer.android.com/jetpack/androidx/releases/webkit) にある [`ProxyController`](https://developer.android.com/reference/androidx/webkit/ProxyController) を使えばOKでした。

# 使ってみる
`ProxyController` を使ってみます。

## `Webkit` の依存を追加

```kotlin
dependencies {
    implementation "androidx.webkit:webkit:1.8.0"
}
```

## サンプル実装

```kotlin
// プロキシを設定
if (WebViewFeature.isFeatureSupported(PROXY_OVERRIDE)) {
    val proxyConfig = ProxyConfig.Builder()
        .addProxyRule("proxy.example.com") // プロキシ
        .addBypassRule("exclude.example.com") // プロキシから除外する設定
        .build()
    val executor = Executor {}
    val listener = Runnable {}
    ProxyController.getInstance().setProxyOverride(proxyConfig, executor, listener)
}

// プロキシを解除
if (WebViewFeature.isFeatureSupported(PROXY_OVERRIDE)) {
    val executor = Executor {}
    val listener = Runnable {}
    ProxyController.getInstance().clearProxyOverride(executor, listener)
}
```

### 要点メモ
- `ProxyController.getInstance()` の呼び出しには `WebViewFeature.isFeatureSupported(PROXY_OVERRIDE)` が必要
- `ProxyConfig` でプロキシの設定を指定
    - `addProxyRule` でプロキシのURLを指定
        - ポートも指定する場合は `addProxyRule("proxy.example.com:1111")` みたいに指定
    - `addBypassRule` でプロキシから除外したいURLを指定
        - `setReverseBypassEnabled` を `true` にすることで、`addBypassRule` で指定したURLのみプロキシを使うようにもできる
- `executor: Executor` `listener: Runnable` はそれぞれ下記の通り
    - `executor: Executor` → リスナーの実行を管理するオブジェクト
    - `listener: Runnable` → プロキシ設定の変更が適用されたときに呼び出されるリスナー
    - プロキシの設定は即座に反映されるわけではないので、それのタイミングをハンドリングしたい場合に使う。（細かい調整をしない限りは空でもよさそう :thinking: ）
- プロキシの設定はアプリ内のWebView全体に影響するので、プロキシ設定が不要になったら解除する
数式を説明する解答例


+ [数式が正しいと思えるが機能していないとき](https://qiita.com/Keiji_otsubo/items/c339e3f7d44b8f84a264)
+ [Validation Rule Help](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007MbGgw)

:::note
Make sure "Stages Support" and "Closed" are the right API names for the values. Formulas do not take labels.

If that still doesn't work, generate a debug log in setup under your name, recreate the issue and open the logs to find the validation rule API name. You will see the field values at runtime and should be able to see what the discrepancy is between your rule and the actual values

「Stages Support」と「Closed」が値の正しい API 名であることを確認してください。数式にはラベルは付けられません。

それでも問題が解決しない場合は、セットアップで自分の名前でデバッグ ログを生成し、問題を再作成してログを開いて検証ルール API 名を見つけます。実行時にフィールド値が表示され、ルールと実際の値の間にどのような不一致があるかを確認できるはずです。
:::

# 添付ファイルは数式では使えない

+ [Validation rule on file upload under Notes & Attachment](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007X9Hh6)

:::note
Looks like this is still an idea:

https://ideas.salesforce.com/s/idea/a0B8W00000GdjhTUAR/validation-rules-on-attachments

I think it's possible using Apex triggers.

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A9BK7SAN
:::

# ラベルを使っている？

+ [残念ながら、現在の検証ルールでは、価格表名に会社名が含まれているものの、会社名が複数の単語（つまりスペースを含む）である場合にエラー メッセージが表示されます。つまり、価格表会社「CompanyOne」の価格表名「CompanyOne V2024.2」は検証ルールに合格します。価格表会社「Another Company」の価格表名「Another Company V2024.2」は、検証ルールに合格すると予想していましたが、合格しませんでした。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007clgyd)

:::note
If you're using TEXT, I assume Price_Book_Company__c is a picklist field. Can you check the API name of the value as that is what the rule looks at, not the label

TEXT を使用している場合、Price_Book_Company__c は選択リスト フィールドであると想定します。ルールが参照するのはラベルではなく値の API 名なので、それを確認してください。
:::
Engagement Studio



+ [Waiting days in Engagement Studio](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007O2IlZ)

:::note
The maximum wait time for actions and triggers is 365 days.

https://destined.com.au/seven-pardot-engagement-studio-ideas-subscription-based-businesses/
:::

+ [Pardot Engagement Studio スケジュール設定済みメールステップの FAQ](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000HF1A4)

:::note
Pardot Engagement Studio Scheduled Email Step FAQ
https://help.salesforce.com/s/articleView?id=000319723&type=1
:::

+ [Engagement Studio テスト機能:テスト中に送信リストに実際にテスト メールが送信されるかどうか](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JglwMSAR)

:::note
実際に電子メールを送信するわけではありません。プログラムがどのように機能するかを順を追って説明しますが、アクティブ化するまで機能しません。 

メールは送信されません。エンゲージメント プログラムをどのように通過するかをシミュレートするだけです。
:::

+ [Pardot の自動化ルールと Engagement Studio アクション (アカウントエンゲージメント)](https://www.salesforceben.com/the-drip/automation-rules-vs-engagement-studio-actions-pardot-account-engagement/)

+ [Engagement studioで回帰させたい](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007KYyMDSA1)

:::note
①Engagement Studioの受信者リストはダイナミックリスト

→ターゲットのプロスペクトにタグを付与

②Engagement Studioの開始で「プロスペクトに複数回プログラムにエントリすることを許可」にチェック

→再エントリの対象になるまでの日数を指定できます。

③D配信→評価したら付与されたタグを削除

④再度、ターゲットのプロスペクトにタグを付与
:::

+ [開始ステップをどのように設定し、特に受信者リストを定義すればよいでしょうか?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A8fCOSAZ)
Next.jsの開発過程で出たエラーの解消法

勉強し始めのエラーは解消に時間がかかるものです。
私が出会ったエラーとその解消について紹介しておきます。

:::note info
【この記事をオススメしたい人】
・これからNext.jsを勉強しようとしている人
・Next.jsを勉強中で日が浅い人
:::

ひとつでもお役に立てることがあれば幸いです！

## Unhandled Runtime Error

Error: Hydration failed because the initial UI does not match what was rendered on the server.
Warning: Expected server HTML to contain a matching `<p> in <p>.`

上記のエラーが出ました。
`<p>`の中にHTMLが入っていることを怒っているようでした。
原因は、受け取ったchildrenをpタグで囲ってしまったことでした。

```diff_javascript
// コンポーネントの呼び出し側（一部を抜粋）
<Heading
  level={1}
  text="h1タグで囲まれたテキストがここに入ります。"
>
  <p>subtitleを入力する場合</p>
</Heading>

// コンポーネントの定義側（一部を抜粋）
<hgroup className="mb-6">
  <HeadingTag className={classes}>{text}</HeadingTag>
  <p>{children}</p> 
</hgroup>

// エラーの原因はコンポーネント側のchildrenの箇所
- <p>{children}</p>
+ {children}
```

## 〜は型 'JSX.IntrinsicElements' に存在しません
コンポーネントは大文字から始めないとエラーになります。

JSXのファイル内には通常のHTMLのように`<div>`とタグを書くことができます。
なので小文字から始めてしまうとエラーとなるため独自で定義したコンポーネントであることを明示的に示すためにお作法として「コンポーネントは大文字から始める」が基本となります！
2023/10/23主にITとかセキュリティの記事

NTT西子会社の900万件情報流出、うち400万件は山田養蜂場。過度なコストカットがモンスター派遣社員の暗躍を生んだ？さらにPマークも取り消される危機(10/20)
https://www.mag2.com/p/money/1370614

ＮＴＴ西系の情報流出　指摘後社内調査３カ月も「漏洩ない」　委託元の指摘見逃し検証へ(10/21)
https://news.yahoo.co.jp/articles/db0f3f73e20e85a5e1b3c29be0977e8f0b4094cd?source=rss

NTT西社長、情報流出「私にも責任」(10/21)
https://www.nikkei.com/article/DGKKZO75471550Q3A021C2TB0000/

Amazon.co.jpで3Dセキュア認証開始か(10/21)
https://www.zaikei.co.jp/article/20231021/742672.html

ランサム集団の中枢メンバー逮捕、日米欧共同捜査で(10/21)
https://www.nikkei.com/article/DGXZQOUE207900Q3A021C2000000/

ランサムウエア「開発者」をフランス当局が逮捕　日本警察も情報提供(10/21)
https://news.yahoo.co.jp/articles/44ea2a1a303cf7b47ca5b630db7b02fb9b8ec4b8

【速報】サイバー攻撃集団「ラグナロッカー」開発者とみられる男をフランスで逮捕　“サイバー特別捜査隊”も協力(10/21)
https://nordot.app/1088131470891009015

ハッカー集団「ラグナロッカー」中核メンバー、チェコ在住の男を国際捜査で逮捕…カプコンも被害(10/21)
https://www.yomiuri.co.jp/national/20231021-OYT1T50171/

ICC国際刑事裁判所「9月のサイバー攻撃はスパイ活動が目的」と発表　オランダ当局が犯罪捜査(10/21)
https://nordot.app/1088142750246683399

「NauNau」230万人以上 位置情報など外部から閲覧可能な状態に(10/21)
https://www3.nhk.or.jp/news/html/20231021/k10014232891000.html

“政府認定クラウドサービス”登録で開示される情報・されない情報　リスト入りを目指すときの注意点(10/21)
https://news.yahoo.co.jp/articles/5c8687a5b5e0162a0121dbc0ad0a706b17edaaa0

Androidマルウェア、イタリアの偽の全国公共警報サイトで配布(10/21)
https://news.mynavi.jp/techplus/article/20231021-2795867/

AWS運用に忙殺されないための基礎知識！
前知識ゼロから学ぶAWS WAFの特性と課題解決(10/20)
https://b-library.impress.co.jp//ud/product/code/WD-2023-0099

家電芸人が教える“iPhoneでやってはいけないこと”　少しでもバッテリーを長持ちさせるために…(10/21)
https://nordot.app/1088185282909848490

セキュニティとは？現状と今後・重要性まで解説(10/20)
https://cybersecurity-jp.com/column/90257

カシオ計算機株式会社のシステムへの不正アクセスによる県立高校への影響について(10/20)
https://www.pref.saitama.lg.jp/f2220/news/page/news2023102101.html

伊奈学園、松山など8校…埼玉県立高生約2千人の個人情報、流出の恐れ　教育アプリのDBに不正アクセスで(10/21)
https://www.saitama-np.co.jp/articles/51136/postDetail

カシオ計算機の教育アプリ個人情報漏洩問題　城之内中等教育学校で漏洩か【徳島】(10/20)
https://news.yahoo.co.jp/articles/0f1302af9777db210a6aa11922cb615aef750a99

大分市、生成AIの業務活用手引を作成　全職員に配布「発展的な使い方を」(10/21)
https://news.yahoo.co.jp/articles/75fcf1ddb6f5f636efdba905f98b8ab3e5883fe4

サイバー犯罪未然防止で連携強化へ　栃木県警が県医師会と覚書締結(10/21)
https://news.yahoo.co.jp/articles/736459b18bb39051ef9d0dfd17380bf494b85562?source=rss

文政権時代の統計操作疑惑…大統領記録館を家宅捜索(10/21)
https://news.yahoo.co.jp/articles/540b228b9b34a99d548b80b57e2bf9f316952a6f

【深層レポート】様々な思惑が交錯…イスラエル×ハマス ″終わらない戦争″が招く「地獄以上の恐怖」(10/21)
https://news.yahoo.co.jp/articles/5e31d16af0d8d8610fe78c28076d08cb24459be5
vscode WSLでファイルを変更できないときの対処法

Ubuntuなどとvscodeをつなげたはいいものの、ファイルの編集をするとPermission denidedといわれるときの対処法をメモとして残しておく。

### 環境
- windows11
- ubuntu : 20.04.6 LTS
- vscode (wsl)

今回は、`directory1`内のファイルを編集できないとする。

### 事象
vscodeで`directory1`内のファイルを編集し保存しようとしたところ以下のようなエラーがでて保存ができない。

```
Failed to save 'ファイル名': Unable to write file 'vscode-remote:ファイルパス' (NoPermissions (FileSystemError): Error: EACCES: permission denied, open 'ファイルパス')
```

権限関連の問題のようなので調査する。

### 調査
- directory1が編集できないため権限を確認する。

```
$ ll

total 20
drwxr-xr-x  2 root root 4096 Oct 23 10:00 directory1
drwxr-xr-x  2 root root 4096 Oct 23 10:01 directory2
-rw-r--r--  1 root root   23 Oct 23 09:59 file1.txt
-rw-r--r--  1 root root   42 Oct 23 10:00 file2.txt
```

所有者がrootになっているため変更をする(変更しても問題ないかは確認)


- 所有者の変更
```
// ファイルの所有者を変更する
$ sudo chown 新しい所有者:新しい所属グループ ディレクトリのパス

// ディレクトリ内すべての所有者を変更する(Option: -R)
$ sudo chown -R 新しい所有者:新しい所属グループ ディレクトリのパス


// 実行
$ sudo chown -R yamaken:yamaken directory1
```

- 所有者が変更されているか確認する

```
$ ll

total 20
drwxr-xr-x  2 yamaken yamaken 4096 Oct 23 10:00 directory1
drwxr-xr-x  2 root root 4096 Oct 23 10:01 directory2
-rw-r--r--  1 root root   23 Oct 23 09:59 file1.txt
-rw-r--r--  1 root root   42 Oct 23 10:00 file2.txt
```

この状態でvscodeで編集したところ保存することができました。
今回は所有者が問題でした。
# PyInstallerの使い方(Windows)


1. PowerShell起動
2. ```pip install pyinstaller```
3. exe化したいPythonファイルのあるフォルダへ移動
4. ```pipenv --python 3.11``` ..仮想環境の作成
5. ```pipenv shell``` ..仮想環境の有効化(見た目、変化なし)
6. ```pipenv install [ライブラリ]``` ..必要なライブラリのインストール
7. ```pyinstaller exe化したいPythonファイル名 --onefile --noconsole``` ..exe化
8. ```exit``` ..仮想環境から抜ける
9. ```pipenv --rm``` ..仮想環境を削除
Kaggle初めてのLLMコンペに参加しました

Kaggleは最近LLMのコンペを開催しました。初めてのLLMコンペなので、Kaggleで有名なデータサイエンティストの方はほとんど参加してきました。（2600チーム）
タイトルは「Kaggle-LLM Science Exam」です。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/4be89eaa-00d5-f7a3-eba1-b8e71e3ccaa0.png)

今回のコンペの目的は科学の多肢選択問題を回答するLLMをトレーニングすることです。
問題はChatGPT3.5とWikipediaの科学スレ(stem)から生成されて，それでtrainデータは200件くらい用意して，testデータは4000件くらいがあります。
公平性を保つために、今回はGPUの性能が制限されて、16GBメモリ+9時間以内で処理を完了する条件があります。
また、モデルの実行はローカル環境で行われるため、ChatGPTなどのapiを使うこともダメです。（ただし、学習データの生成には利用されています）
皆さんやり方自体は様々で、あと初めてのLLMコンペなので、従来のBert系モデル(Bert,Deberta,Distilbert)使ってる方もいるし、LLM（7B,13B,70B)使ってる方もいます。
finetuningに関しても、LoRAやP-tuningまたは全パラメータチューニングまでやっっている方もいました。あとはRAGも基本みんな使ってます。
GPU性能の制限などもあるため、Bertなどの小規模モデルでチューニングしてもLLMと大きな差はないですが、
パラメータ数が少ないために（一番多いDeberta v3でも1.5Bしかない）、やはりちょっと使いにくいなと感じていました。

多くの参加者のsolutionを見て、精度のランキングは大体以下のような感じだと思います。
1.LLM finetuningのアンサンブル+RAG
2.70B finetuning+RAG 
3.Deberta finetuning+RAG 
4.70B zeroshot＋RAG
5.他のLLM
6.他のbert
7.Faiss

*私はLLMのfinetuning、DebertaのfinetuningとRAG全部やりました。

ステップごとのやり方＋tipsについて以下にまとめています。
1.データセットの作成：
①基本的な方法や半教師あり学習でGPT4使って生成します。
tips:科学問題なので、科目別にデータセットを用意すれば精度が上がります。
②API使ってWikipediaから関連する領域のデータをクローリングします。（私は約20GBのデータを取りました。）


2.promptのチューニング
prompt文の書き方は人それぞれなので、試して自分のモデルで最適なpromptを探すことが大事です。
tips:回答の順序を変更してモデルに投げること（強化学習）が大事です。また、よく間違っている問題をまとめてboostモデルを構築することも効果的です。

3.モデルの選び方(7B,13B,70B)：
70Bの方が基本性能が上ですが、必ず70Bが高いというわけでもないです。（top1の方は70Bモデルさえ使ってないですね）
tips:16GBメモリーで70Bのモデルをトレーニングする方法についてはコンペの途中で、あるフランスの方が公開しました。
一言で簡単に言うと、モデルをいくつに分割してメモリーに入れることでトレーニングします。この方法が公開されてから、多くの参加者が70Bモデルのトレーニングを始めました。
やり方自体は非常に複雑なので、詳細は次回共有したいと思います。

4.パラメーターチューニング(learning rate、batch size、epochなど）
みんな精度の差が小さすぎるので、パラメーターのチューニングが結構大変だったです。
tips:色々試してlossを見ながら経験を積むことしかないですね。

5.RAG
RAGするとほぼ必ず精度上がるためにみんな使ってます。
ちなみに、RAGとfinetuiningがどんな状況に使うのかについては下図に非常にわかりやすくまとめてます。
モデルが外部データを必要とする場合はRAG、モデルに特定な行動を求める場合はfinetuining。
今回は質問に対しての回答（QA）を求める＋外部データセットも参照するために、両方要ります。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/28b31bc7-7c3f-f354-c9a6-f79359894632.png)



ちなみに、今回一番上の日本チームはPreferred Networksだったです。（4位と5位）
しかも完全に異なる手法でfinetuningしました。
4位はDeberta+データの並び替え調整
5位はMistral 7B+Llama 70B +Qlora
どちらでも非常にすばらしいやり方です。

私は銅メダル取りました。今回のコンペで特に惜しかったのは、Debertaに色々finetuningして、trainデータではずっとLLＭより精度が高かったです。
ですが、testデータの量はtrainデータよりかなり多いために、Debertaの汎用性には自信なくて、どちらを提出するのか悩んで、チームメートともかなり議論しましたが、最後はDebertaを提出しました。
やはり、testデータにはランキングが結構落ちてしまいました。もしLLMを提出すればもとの順位に残す可能性もあるかもしれません。
このメダルのおかげでランクがKaggle Expertに上がりました。次はMasterになるように頑張りたいと思います。

https://www.kaggle.com/competitions/kaggle-llm-science-exam/overview
プランニングポーカー Thunderdome をdocker-composeで構築

# 環境作成（Windowsの場合）

インストールしていない場合

1. WSLのインストール

1. Docker Desktop for Windowsのインストール

# Thunderdome planning-poker の設定

イントラネット上でThunderdomeサーバーを起動します。

1. WSL（Linux用Windowsサブシステム）を開く

1. GitHubリポジトリのクローン

    ```bash
    git clone https://github.com/StevenWeathers/thunderdome-planning-poker.git
    cd thunderdome-planning-poker
    ```

1. config.ymlの作成

    ```bash
    http:
      domain: thunderdome.dev
    db:
      host: localhost
      port: 5432
      user: thor
      pass: odinson
      name: thunderdome
    ```
    ※http domainは無くてもよさそう

1. ポート開放
    ファイアウォールの8080ポートを開放しておきます。

1. Docker Compose の実行

    ```bash
    docker-compose up -d
    ```

1. ブラウザでアクセス

    ブラウザで `http://(ホスト名もしくはIPアドレス):8080/` を開くと起動するはずです。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184382/d17f3b50-faa2-b9e1-ad9e-9ecc59c54b48.png)
よし、「並べよう」！


# 目次
- [前回の振り返り](#前回の振り返り)
- [本編に行く前に](#本編に行く前に)
- [テスト対象を並べる](#テスト対象を並べる)
- [課題](#課題)
- [おわりに](#おわりに)

# 前回の振り返り
前回の投稿「[テストすべき対象は、「モノの集め方」によって決まる 〜TM技術を使ってモデルベースドテストの可能性を考える(第1回)〜](https://qiita.com/YukTak/items/8e7c3c9a030b875e9cdc)」にて、テスト対象の集め方、もとい「**モノの集め方**」について、T字書式にてまとめる方法を投稿しました。

今回はその集めたものを、「**並べる**」ことについて書いていきます。

参照元は前回と同様、[事業分析・データ設計のためのモデル作成技術入門](https://gihyo.jp/book/2022/978-4-297-12946-0)から学んだことから書いていきます。

[<img width = 200 src = http://image.gihyo.co.jp/assets/images/cover/2022/9784297129460.jpg>](https://gihyo.jp/book/2022/978-4-297-12946-0)

# 本編に行く前に

前回の「[テストすべき対象は、「モノの集め方」によって決まる 〜TM技術を使ってモデルベースドテストの可能性を考える(第1回)〜](https://qiita.com/YukTak/items/8e7c3c9a030b875e9cdc)」で、一つ書き忘れたことがありますので、それを書きます！
※書き忘れて、すみません🙇　　

### 「モノを集める」の追加工程
T字書式で集めた後に、さらに以下の作業を実行します。

:::note info
追加する作業
- 「**1つの個体指定子について、1つのT字書式を作ってその他の項目(attribute)を"分ける"**」
:::

左側に記載した個体指定子から、更に**1つの個体指定子ごとに1つのT字書式を作って、その他項目(attribute)を、対応する個体指定子ごとに分ける**作業を実行します。こうすることで、モノを並べるときに「それがどういうモノなのか」を分かりやすくすることにより、並べやすくなると思います。

また、「**現実的事態を写像する構造物**」において、作成するモデルは、品質が保たれるとも考えます。

:::note info
- 論理的に構築することによる、**完全性**または**信頼性**
- カスタマイズしやすいことによる、**拡張性**
- 修正や追加しやすいことによる、**保守性**
- モデルを継続して使用できることによる、**可用性**
- テスト対象・観点などを導出しやすくなることによる、**使用性**
- AのテストプロジェクトとBのテストプロジェクトで、名前が変わっても種別が同じテストプロジェクトで、作成したモデルの一部または全てを再利用することができることによる、**互換性**
- 別の環境・領域に変わっても容易に移行することができることによる、**移植性**
:::

ここまで記載して、お気づきかと思いますがこのTM技術によるモデルは所謂「**品質特性である「非機能要件が満たされる」※**」ことに繋がると考えます。
※「拡張性」を除いた品質特性

それらを、これからの投稿で示して行く予定です。

# テスト対象を並べる
本筋に戻りまして、ここから集めたモノの「並べ方」について述べたいと思います。

まずは、T字書式で分けたモノを以下のカテゴリーに分類します。

- **Event**：その他の項目(attribute)に**日付**が入っているもの
- **Resource**：**Event以外**のもの

**Event**は、日付が入っているモノを指します。例えば、以下のような日付が入っているものです。
- 保存した日
- 作成した日
- 更新した日　など

**Resource**は、Event以外のモノで**日付が入っていないもの**になります。

これらの2つのカテゴリに、Eventには「**E**」、そしてResourceには「**R**」というラベルをつけて分類します。


分類し終わったら、**Event**を**時系列に従って左から順に並べて**いきます。
例えば、ファイルを生成するシステムの場合、以下のEvent持っていると仮定します。

<dl>
    <dt>ファイル生成のシステム(EventのT字書式で作成したモノと想定)</dt>
        <dd>⚫︎新規作成</dd>
        <dd>⚫︎保存</dd>
        <dd>⚫︎更新</dd>
</dl>

これらを「新規作成→保存→更新」の順に、各Eventの集まりを左から右に並べていきます。

Eventが並べられたら、**Resourceの集まり**を**Eventが配置している周り(上下)に配置**していきます。

これだけです。


### 並べてみて判明すること
この「並べる」工程により、テストするシステム・プロダクトが「変化に強いシステム・またはプロダクトかどうか判断できる」とのことです。
Resourceの数　> Eventの数(Resourceの数が、Eventの数より多い)になっていれば、変化に強いものになっているとのことです。


ここから、テストするシステム・プロダクトに対して「**そのシステム・プロダクトの仕様に対して、不足・欠損していることから起因する不具合の要否**」が分かると考えます。
つまり、**仕様の不具合がある程度そこで判明できる**です。

# 課題
「**時系列にEventを並べる**」について、ここは開発側と一緒に確認しながら並べていく必要があると思いました。

具体的な機能処理を並べる訳なので、関連する領域ごとのシステムやプロダクトの処理の流れが分かっている場合、ある程度並べた後で開発チームに見てもらうといったことが有益でしょう。

逆に、処理の流れが分からなかったときは、開発側のエンジニア・プログラマーの方と一緒に、共通の理解を得ながら作業していくことが必要です。

# おわりに
今回は、「モノを並べる」について書いていきました。

今週は、内容を凝縮して書いていきましたが、文章の適切なバランスをとるのって難しいですね😓

次は、「**関係するモノを線で引く**」について複数回に分けて投稿しようかと思います。


今回も、貴重なお時間を割いて本記事を読んでいただき、ありがとうございます。

では、また！
フェルミ推定の指南書

# 導入
こんにちは、るっちです。
今回はフェルミ推定の考え方に関して、簡単に備忘録を残そうと思います。

参考:[現役東大生が書いた 地頭を鍛えるフェルミ推定ノート――「6パターン・5ステップ」でどんな難問もスラスラ解ける!](https://www.amazon.co.jp/s?k=%E5%9C%B0%E9%A0%AD%E3%82%92%E9%8D%9B%E3%81%88%E3%82%8B%E3%83%95%E3%82%A7%E3%83%AB%E3%83%9F%E6%8E%A8%E5%AE%9A%E3%83%8E%E3%83%BC%E3%83%88&adgrpid=131256218322&hvadid=667908073387&hvdev=c&hvqmt=e&hvtargid=kwd-332606508126&hydadcr=4077_13351780&jp-ad-ap=0&tag=yahhyd-22&ref=pd_sl_74hyy9sqfh_e)

# フェルミ推定
　フェルミ推定とは、「日本にコンビニはいくつあるか？」や「ぬいぐるみの市場規模」、「ラーメン店の売り上げ」のような見当のつかない数量を、知っている知識だけをもとに合理的な仮説とロジックを駆使して短時間で概算する方法です。
封筒の裏でちょこちょこっと計算するところから、Back of Envelope(封筒の裏)などと呼ばれています。

# フェルミ推定の基本体系
　フェルミ推定の骨組みとなる「基本体系」は以下の図になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2880103/735cc05c-290a-637a-cb60-2fe908841cb4.png)

- <b>ストック問題</b>：何個あるの～？系の問題
「所有アプローチ」の「個人ベース」であれば、1人当たりの数値から日本の人口規模へ拡張します。
「存在アプローチ」の「面積ベース」であれば、何km^2に1つ存在するのか仮説を立て、日本の面積へ拡張します。

- <b>フロー問題</b>：市場規模や年間売り上げ系の問題
「どれくらいの人数が求めるのか」という買う側の視点から推定するのが「マクロ推定」です。
「1店舗でどれくらい売るのか」という売る側の視点から推定するのが「ミクロ推定」です。

# フェルミ推定の5ステップ
　フェルミ推定は、基本的に以下の5ステップで進めていきます。
1. <b>前提確認</b>：どの範囲で数えるのか、売上でも1日なのか1年なのか、1店舗だけなのか全店舗なのかなどを最初に決めます。
2. <b>アプローチ設定</b>：何ベースで考えるのか設定し、基本的な式を立てます。
「人口×1人当たりの所持数」のような式です。
3. <b>モデル化</b>：アプローチ設定で立てた式を深堀します。人口は人口でも、年齢によって割合が異なります。また時間帯によって客足も変化します。このようにセグメント化し分解します。（結局は、より相手を納得させれるような論理的な仮説を立てれれば良い）
4. <b>計算実行</b>：モデル化で深堀した値を元の式の当てはめ実際に計算します。
5. <b>現実性検証</b>：計算した値の妥当性を検証します。1店舗の1日の売り上げが数百億円のようなおかしな数字になってしまった場合、仮説を修正します。

# 覚えておくと良いかも？フェルミ推定の基礎数値
- 日本の人口：1.2億人
- 日本の面積：38万km^2（便宜上40万km^2とする場合もある）
- 日本の平地と山地：「1 : 3」=「10万km^2 : 30万km^2」
- 年齢：「0-20 : 20-40 : 40-60 : 60-80」=「2 : 3 : 3 : 2」=「2400万人 : 3600万人 : 3600万人 : 2400万人」
- 東京都の面積と人口：3200km^2、1500万人
- 大阪府の面積と人口：2000km^2、900万人


以上、フェルミ推定の備忘録でした。
【Next.js】コンポーネントをサーバー限定にする

`server-only`をimportすることでコンポーネントがクライアントコンポーネントにインポートされた際にエラーが発生するようになります。

`server-only`をインストールします。

```terminal
npm i server-only
```

`server-only`をインポートします。

```
import "server-only"
```

また、以下のように`import "client-only"`を記述することでコンポーネントがサーバーサイドで実行された際にエラーが発生するようにできます。

```
import "client-only"
```
Oracle提供のJava17をインストール

この前 [SDKMANを使ったやり方を書きました](https://qiita.com/nacho4d/items/a9f0e1a0ec5e22e6f16d)。 みんな SDKMANを使っていないかもしれないので　今回は最も一般的なやり方を書いてみる。（多分非プログラマーもこんなやり方をするのでは？）

## OracleサイトからJDK17を取得

これは[ダウンロードページへの直接リンク](https://www.oracle.com/jp/java/technologies/downloads/#java17)だが、グーグルで「Oracle java17 downloads」を検索するとOracleのダウンロードページがトップヒットとして出ると思う。

ページから 自分の環境に合うインストーラーをダウンロードし、実行する。zipファイルもあるが、インストーラーをお勧め。なぜならば適切な場所に配置してくれるからである。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83390/84681b77-0bd2-0aaa-efc0-f69070601ba6.png" width="350">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83390/8cee40e9-c515-d6c7-2ba7-547737b4cc50.png" width="350">

## インストールの確認

上記のインストーラーがMacOSが昔から期待する「`/Library/Java/JavaVirtualMachines` ディレクトリーにJavaを配置する。その存在チェックを確認する。

Finder > New finder window > Cmd + Shift + G押下 > `/Library/Java/JavaVirtualMachines` を入力する

標準的な場所なので　他のjava sdkもある可能性もある。今回jdk-17.sdkがあるので　OK!

![Screenshot 2023-10-22 at 19.53.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83390/0a1e499c-9404-1bf8-ae99-b536afa49153.png)


## JAVA_HOMEを確認

### 


<details>
  <summary>JAVA_HOMEって何でしたっけ？というあなたへ　ここクリックし、展開してください 😀</summary>
  <div>

JAVA_HOMEという環境変数を正しく設定することで　色々なプログラム・アプリがデフォルトのJavaを知ることができて　他のプログラムに必要。

Android Studioを使う場合は GUIを使って選択できるので　JAVA_HOMEをセットしていなくてokだが　他のアプリは大抵Javaを特別に選択するUIを用意してくれない。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83390/42187dd8-9a31-5ee2-1efb-c3adb67b3bb2.png" width="300">)

例えば ターミナル`java --version` を実行すると JAVA_HOMEを定義していないと　`/Library/Java/JavaVirtualMachines` の中で最もバージョン高いものが得られる。JAVA_HOMEを定義していなくても `/usr/libexec/java_home` がなんとかしてくれている。

```zsh
% /usr/libexec/java_home
/Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home
```


```zsh
% echo $JAVA_HOME

%
% java --version
java 21.0.1 2023-10-17 LTS
Java(TM) SE Runtime Environment (build 21.0.1+12-LTS-29)
Java HotSpot(TM) 64-Bit Server VM (build 21.0.1+12-LTS-29, mixed mode, sharing)
```
今回は17を使いたいので JAVA_HOMEを定義することで java --versionの結果を変えることができる！
  </div>
</details>

JAVA_HOMEが正しく設定される場所で定義する。`~/.zshenv`で以下を追加

```zsh
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home
```

もしく　java_homeコマンドを使って17を取得しJAVA_HOMEを設定することもOK

```zsh
export JAVA_HOME=$(/usr/libexec/java_home -v 17)
```

## Java全体の確認

適当なターミナルを開いて、以下の二つのコマンドを打って、Java 17が表示される筈

```zsh
% echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home 
% 
% java --version
java 17.0.8 2023-07-18 LTS
Java(TM) SE Runtime Environment (build 17.0.8+9-LTS-211)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.8+9-LTS-211, mixed mode, sharing)
```

以上、これでJava使えるはず！


See you later! 🐊
Android Emulatorからlocalhostにアクセスする

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458231/0c3be5cb-ff12-3506-b7df-40351bcd20af.png" width=25% />

Android Emulatorでlocalhostにアクセスする機会はよくあると思います。
URLにhttp:\//localhost/を指定しただけだとエラーが出てしまいます。
そのようなときは以下の2点を確認する必要があります。
1. http:\//10.0.2.2/を指定する
1. network_security_config.xmlを設定する

## http:\//10.0.2.2/を指定する
Android Emulatorではlocalhost（127.0.0.1）はhttp:\//10.0.2.2/として割り当てられています。[^1]

> 開発マシンのアドレス 127.0.0.1 は、エミュレータのループバック インターフェースに対応します。開発マシンのループバック インターフェースで実行されているサービスにアクセスするには、代わりに特殊アドレス 10.0.2.2 を使用します。

そのため、localhostを指定したい場合は、http:\//10.0.2.2/に置き換える必要があります。

## network_security_config.xmlを設定する
デフォルトでは、httpの接続は許可されていないので設定で許可する必要があります。[^2]
res/xml/network_security_config.xmlに以下のように設定します。
ドメインのみを指定します。
```xml
    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <domain-config cleartextTrafficPermitted="true">
            <domain includeSubdomains="true">10.0.2.2</domain>
        </domain-config>
    </network-security-config>
```

上記の設定をAndroidManifest.xmlに指定します。
```xml
    <?xml version="1.0" encoding="utf-8"?>
    <manifest ... >
        <application android:networkSecurityConfig="@xml/network_security_config"
                        ... >
            ...
        </application>
    </manifest>
```

これでlocalhostにアクセスできるようになりました。

[^1]: https://developer.android.com/studio/run/emulator-networking?hl=ja#networkaddresses
[^2]: https://developer.android.com/training/articles/security-config?hl=ja
Phoenixで静的ページレンダリングする方法

# Phoenixで静的ページレンダリングする方法

Controllerからテンプレートまで、全て手動で作成する方法

- [Phoenixで静的ページレンダリング](#phoenixで静的ページレンダリング)
  - [routerへの追記](#routerへの追記)
  - [アクションの定義](#アクションの定義)
  - [render関数](#render関数)
  - [テンプレートと関数コンポーネント](#テンプレートと関数コンポーネント)
    - [関数コンポーネントの定義](#関数コンポーネントの定義)
  - [結論](#結論)

## routerへの追記

<font color="black">`router.ex`</font>ファイルに以下の形式で記述を行う。

形式: <font color="red">`get "/URLを記述", 省略Controller, :アクション`</font>

例として、<font color="chocolate">`get "/sample", SampleContoller, :home`</font>と記述する。

この場合記述したURLでリクエストが送信されると、<font color="black">`sample_controller.ex`</font>内の<font color="bule">home</font>というアクションが実行される。


## アクションの定義

アクションは以下のように定義することができる。

```elixir
def アクション(conn, params) do
  ... 
  render(conn, template_or_component)
end
```

アクションの引数は以下のようなものである。

* <font color="red">conn</font> - リクエスト情報が含まれている。<font color="gray">(ここでは割愛)</font>
* params - URLによって渡された**パラメータ**がMapで格納される。

例えば`/greet/:name/`というルートを設定しており、`/greet/taro`/というURLにリクエストが送信されると、<font color="chocolate">`%{ "name" => "taro"}`</font>という形式でパラメタが格納される。

アクション内では必ずrender関数を実行する必要がある。

## render関数

render関数の以下のように呼び出す。

形式: <font colo="chocolate">`render(conn, template_or_component, options)`</font>

この引数の内<font color="red">`template_or_component`</font>が指すものは<font color="red">テンプレート</font>、<font color="red">関数コンポーネント</font>である。

当然ながら、それを指定するためには予め定義している必要がある。

なお、テンプレート、関数コンポーネントは**アプリレイアウト**(<font color="gray">もしくは**ルートレイアウト**</font>)の`@inner_content`内にレンダリングされる。

レイアウトについては、[Phoenixにおけるページレンダリング順についてのメモ](https://qiita.com/B_tanuki/items/891a5258787faa59bb1d "Phoenixにおけるページレンダリング順についてのメモ")を参照

## テンプレートと関数コンポーネント

テンプレートと関数コンポーネントを作成するために、
それらを定義するHTMLモジュールとディレクトリを作成する必要がある。

まず、<font color="black">`.*_html.ex`</font>と<font color="darkturquoise">`/.*_html`</font>を作成する。

<font color="black">`.*_html.ex`</font>は次のように記述する。

```elixir
defmodule 省略 do
  use ..., :html

  embed_templates "省略_html/*"

```

<font color="blue">`embed_templates`</font>は、
<font color="red">テンプレートの構成を設定するため</font>に記述している。

`embed_templates`で指定したディレクトリ内に、
heexファイルを配置することでテンプレートとして使用できるようになる。

例として<font color="black">`sample_controller.ex`</font>と<font color="black">`sample_html.ex`</font>を作成した場合、<font color="darkturquoise">`/sample_html`</font>を作成する。

<font color="black">`sample_html.ex`</font>内に<font color="chocolate">`embed_templates "sample_html/*"`</font>と記述する。

### 関数コンポーネントの定義

関数コンポーネントは以下の例のように記述する。

```elixir
def sample(assigns) do
  ~H"""
    // ここにHTMLを記述する。
    <p>function component.</p>
  """
end
```

テンプレート(<font color="gray">または`~H`シジル</font>)に
次のように記述して使用する。

形式: <font color="chocolate">`<.関数コンポーネント名(引数) />`</font>
例: <font color="chocolate">`<.sample() />`</font>

なお、このモジュール内でrender関数を上書きし、
<font color="orange">`~H`シジル</font>で表示内容を記述することもできる。


## 結論

以下の手順を行いテンプレートを表示させる。

1. `router.ex`に`get`でURLを記述。
1. `/controllers`に<font color="red">`.*_contoller.ex`</font>という名前のコントローラーファイルを生成。
2. アクションの処理を定義する。
3. <font color="red">`.*_html.ex`</font>と<font color="red">`/.*_html`</font>を作成する。
4. `/.*_html`にheexを配置。
5. `.*_html.ex`に<font color="red">`embed_templates`</font>でディレクトリを指定する。