OmniAICreator/Qiita-1.07M huggingface dataset:
Raspberry Pi Zeroで写真を撮ってメール送信

実家の山の様子を定期的に親にみせたい。
* 山中なので、もちろん電源は無い。
* 遠方なので、自分は滅多に行けない。
* 親が高齢なので、メールで送るのが良い。
* Raspberry Pi Zero（電力消費低） + 太陽光発電でバッテリーを充電しながら・・・できたらいいな。
というための実験です。
# 準備
* Raspberry Pi Zero W
* [ラズパイカメラ](https://www.amazon.co.jp/dp/B072177JH3)
* [固定IP付きSIMカード イプシム（無制限プラン）](https://ipsim.net/)
* [LTE対応 USBドングル PIX-MT110](https://www.pixela.co.jp/products/network/pix_mt110/)
* [カメラを有効にする](https://zenn.dev/technicarium/articles/449294af295d5c)
* [メール送信はExim4](https://qiita.com/Kazuya_Murakami/items/bc520430fc1efdd0d118)
# 写真撮影 + メール送信スクリプト
## コード
[参考サイト](https://tech.kurojica.com/archives/6641/)
```sh
#!/bin/sh

#ファイル名 パス 写真撮影・保存
ATTACH_FILE_NAME=$(date +%Y%m%d%H%M%S).jpg
ATTACH_FILE_PATH=/画像を一時的に書き出す場所/${ATTACH_FILE_NAME}
raspistill -w 640 -h 360 -o ${ATTACH_FILE_PATH}

#メール処理はここから
MAIL_BOUNDARY=`date +%Y%m%d%H%M%N`

/usr/sbin/sendmail -t << EOF
From: xxxxxx@xxxx.xx
To: xxxxxx@xxxx.xx
Cc: xxxxxx@xxxx.xx
Subject: メール添付テスト $(date +%Y-%m-%d) $(date +%H:%M:%S)
MIME-Version: 1.0
Content-type: multipart/mixed; boundary=${MAIL_BOUNDARY}
Content-Transfer-Encoding: 7bit

--${MAIL_BOUNDARY}
Content-type: text/plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit

メール本文
メール本文
メール本文

--${MAIL_BOUNDARY}
Content-type: application/jpeg;
 name=${ATTACH_FILE_NAME}
Content-Transfer-Encoding: base64
Content-Disposition : attachment;
 filename=${ATTACH_FILE_NAME}

`cat ${ATTACH_FILE_PATH} | base64`

--${MAIL_BOUNDARY}--
EOF

#画像ファイル削除
rm -f ${ATTACH_FILE_PATH}
```
* Cronから実行の場合は絶対パス。
* 改行コードはLF。
## 実行権限付与
```sh
chmod +x 写真撮影 + メール送信スクリプト.sh
```
## Cron
```sh
sudo crontab -e

毎日１２時に実行の場合
0 12 * * * 写真撮影 + メール送信スクリプト.sh
```
# 省電力化
どのくらい効くかは未計測。
## OSの動作を「powersave」モードへ
```sh
sudo sh -c "echo powersave > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
```
## HDMIポートへの電源供給を起動時にオフ
```sh
sudo vi /etc/rc.local

exit 0の上に追記
tvservice --off 

停止確認
vcgencmd display_power 
display_power=0 でOK
```
## Wi-FiとBTを起動時に止める
```sh
sudo vi /boot/config.txt

追記
dtoverlay=pi3-disable-bt
dtoverlay=pi3-disable-wifi

起動確認
ifconfig
無線LANが表示されていないか確認
hciconfig
何も表示されないか確認
```
## PIX-MT110のWi-Fiを止める
設定 → Wi-Fi設定 → 「Wi-Fiインターフェースを有効にする」のポチを外して[適用]押下。
# 試してみて
モバイルバッテリー（26800mAh）だけでも２～３日もちそうです。
飽きたり挫折したりしなければ製作を続けます。
グループウェア「mitoco」を使ってみよう ～introduction～ 

# はじめに
- Salesforce 上で動作するグループウェアの「mitoco」（みとこ）に関する記事になります。

https://www.mitoco.net/

- mitoco は「株式会社テラスカイ」のサービスです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309141/bb057635-ba81-78c7-c9cb-b485704b93c6.png)

# 機能
以下の機能が用意されています。
- カレンダー

https://www.mitoco.net/application/calendar

- ワークフロー

https://www.mitoco.net/application/workflow

- 掲示板

https://www.mitoco.net/application/bbs

- トーク

https://www.mitoco.net/application/community

- ToDo

https://www.mitoco.net/application/todo

- 文書管理

https://www.mitoco.net/application/document


モバイル (iOS, Android) にも対応しています。



# 記事一覧

- カレンダー
    - まだ、ありません。

- ワークフロー

https://qiita.com/xx_mana/items/84c2a41ee9b4052398fc

https://qiita.com/xx_mana/items/1498bf0cdb487957bf75

https://qiita.com/xx_mana/items/dc5030eec40b5bad1135

https://qiita.com/xx_mana/items/c70e9efc9fdbe916d3ef

- 掲示板
    - まだ、ありません。

- トーク
    - まだ、ありません。

- ToDo
    - まだ、ありません。

- 文書管理
    - まだ、ありません。

- その他
    - まだ、ありません。


# ご了承ください
- 記事は、執筆したタイミングのmitocoバージョンで確認した内容となります。
    - 内容は製品のバージョンによって仕様が変更されている場合があります。ご了承ください。
CloudShellにてAWS MySQLへ接続してmysqldump

# ■概要
そのままですが、CloudShellにてAWS MySQLへ接続してmysqldumpする方法です。

# ■条件
条件として以下の2点が必要となります。

1. DB側のセキュリティグループに、CloudShellのIPを設定しておく
2. DBがパブリックに存在する

パブリックアクセスが可能である必要があるので検証ではパブリックアクセス可能としました。

![パブリックアクセスあり20230621033655.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954355/a67d7b6d-9892-e5e5-7caf-cb2516717637.png)

CloudShellのIPアドレスは下記コマンドをCloudShellで実行して取得しましょう。

```
curl http://checkip.amazonaws.com/
```

# ■実行コマンド
下記を実行すると/var/tmp以下に落とすようになっています。
CloudShellではアウトプットも出来ると思いますので必要であれば書き出します。

```
mysqldump -h エンドポイント -u ユーザー名 -p DB名 > /var/tmp/dump.sql
```

# ■最後に
何にしてもパブリック可能ですし、あまり推奨されない方法かと思いますが参考までに。

参考：
AWSのRDSでMySQLのdumpをする方法
https://zero-one-x.com/archives/90
vueのemit

emitはコンポーネントが発信（emit）できるカスタムイベント

●コンポーネントでdefineEmit関数でコンポーネントから発信したいカスタムイベントを定義

●リスナー（ここでは親コンポーネント）からコンポーネントに@〇〇="〇〇"でイベントをわたす


リスナー（Listener）は、イベント駆動型のプログラミングにおいて、
特定のイベントが発生した際にそれを検知し、適切な処理を実行する役割を持つコンポーネントや関数のこと。
リスナーはイベントを購読（subscribe）または登録（register）することで、イベントの監視を開始

主コンポーネントがリスナーなので、そこでイベントを定義しておいて、
実際にそれを発信（呼び出す）コンポーネントemitとして定義しておくと、主コンポーネントからよびだして、使える。propsのevent版？
ArduinoIDEでSeeed XIAO BLE Senseへのコンパイルができない時

## 初めに

秋月で買ったこちら( https://akizukidenshi.com/catalog/g/gM-17342/ )をArduino IDEで動かそうと公式ページに従って, ボード追加してコンパイルしようとしたらこけた.

具体的に空のファイルをコンパイルしようとすると以下のようなエラーが出る.

```
略\Arduino15\packages\Seeeduino\hardware\nrf52\1.1.3\cores\nRF5/Arduino.h:65:10: fatal error: Adafruit_USBD_CDC.h: No such file or directory
   65 | #include "Adafruit_USBD_CDC.h"
      |          ^~~~~~~~~~~~~~~~~~~~~
compilation terminated.

exit status 1

Compilation error: exit status 1
```

Adafruitのライブラリかなんかを内部で使っているのか知らないが，"Adafruit_USBD_CDC.h"がないと怒られる． 

フォーラムによると最新版, 1.1.3にはバグがあるらしくうまくうごないらしい.
( https://forum.seeedstudio.com/t/seeed-nrf52-boards-update-to-1-1-3-causes-compile-error/270809/23 )

## 解決方法1
Seeed nRF5のボードのバージョンを1.1.1に戻す.

## 解決方法2
1. 関連するボードを全部消す.(AdaruitとSeeed)
2. [Github](https://github.com/adafruit/Adafruit_nRF52_Arduino)のREADMEに従って, ArduinoIDEにAdafruit nRF52 1.4.0 by Adafruitをインストールする．
3. フォーラムで公開されているパッチを当てる [adafruit_patch_to_add_Seeed_2.zip](https://forum.seeedstudio.com/uploads/short-url/noRnbIuBsQSS5MuwkBsv2ro5cH7.zip) 
 ※ 有志公開のものなので, 嫌な場合は中身をちゃんと読みましょう.自分が読んだ感じは大丈夫でした．バイナリはちゃんとみてませんが...
4. `Arduino15\packages\adafruit\hardware\nrf52\1.4.0`に上書き
  ※ MacOS/Windows/Linuxで配置場所が違うのでこちらを参照してください [ありがたい記事]( https://www.indoorcorgielec.com/resources/arduinoide%E8%A8%AD%E5%AE%9A/arduino-ide%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%A8%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E6%A7%8B%E6%88%90/ )
5. ArduinoIDEに`https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json`を追加し， ボードマネージャからSeeed nRF52をインストール
6. 先ほど入れた`Arduino15\packages\adafruit\hardware\nrf52\1.4.0`を`Seeed nRF52`の方にコピー（置き換え)する
7. adafruitのnRF52のBSPを削除
Laravel Sailプロジェクトをバージョン指定して作成する

# この記事の目的  
公式の方法だと最新バージョン(現在ならLaravel 10.x)のプロジェクトしか作成することができないため。Larvel 8.xが必要だったのでプロジェクト作成までの手順を備忘録として。
  
公式の方法↓(これだと最新バージョンがインストールされてしまいます)
```
curl -s https://laravel.build/example-app | bash
```
# 環境 
Windows11

# 前提条件  
・Linux(Ubuntu)環境が使用できること(PHPとComposer必須)
・Docker Desktopがインストールされていること  

検索すると参考記事がたくさんありますので設定してください。

# 手順  
Ubuntuを開きます。WindowsでUbuntu環境設定が完了していれば、スタートメニューのすべてのプログラムから開くことができます。

これです↓
![Ubuntu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3367698/91fd24a4-62b6-0919-a89d-fcca317cd993.png)

Ubuntuを起動したら以下のコマンドでLaravelプロジェクトを立ち上げてください。
今回は8.xを指定します。

```
composer create-project laravel/laravel プロジェクト名 --prefer-dist "8.*"
cd プロジェクト名
php artisan sail:install
```

DockerDesktopが起動していることを確認し、プロジェクトを起動しましょう。
```
./vendor/bin/sail up -d
```


# 追記  
毎回./vendor/bin/sailを使用するのは面倒なので、エイリアスを設定して簡潔なコマンドを使用できるようにしましょう。

Ubuntuのhome\ユーザー名ディレクトリ内の.bashrcファイルを編集します。
```
alias sail="./vendor/bin/sail"
```
を.bashrcファイルの末尾に追加して下さい。
```
source ~/.bashrc
```
で設定を反映させます。

これで
```
sail up -d
```
で起動できるようになりました。


間違いがあればご指摘ください。
Roblox 🎮 RemoteEvent で複数の引数の渡し方

Roblox にて、RemoteEvent で複数の引数を渡すときの注意点

発火させる側

```
demoRemoteEvent:FireClient(player, value1, value2, ...)
```

検知する側

```
demoRemoteEvent.OnClientEvent:Connect(function(value1, value2, ...)
	print("value1: "..value1)
    print("value2: "..value2)
end)
```

ポイントは、**検知側ではplayer を引数内に入れない**ことです。

さようなら。
【ChatGPT無】が繰り返しはじめるのは、もしかして……（私見）

:::note info
本記事は、ChatGPT（無料版）で
行なっております。GPT4での確認
はできておりません。あしからず。
:::

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

　今回は、
　　ChatGPTさんの健忘症に
　　　ついての、私見です。
***
　ChatGPTが
　　処理できなくなり、
　　　同じようなことを
　　　　繰り返すことをはじめたら、

[【ChatGPT】が健忘症になったなら……](https://qiita.com/kabumira/items/f3d53c376f7cbb3c9406)
「**本セッションの履歴から**、前の回答を出してください」
[【ChatGPT】同一Chat内で話題を切り替える](https://qiita.com/kabumira/items/e71dac46955bcd65de53)
「**新たな話題です**」とか
「**話題を変えます**」とかで
　話題を変えれば、
　　いいのですが……。
***
　以下は、私見です。

　ChatGPTがこの状態になるのは、
　　それなりのやり取りを
　　　したところで
　　　　発生している気がします。

　それで、
　　思い付いたのが、
　　　セッション変数の存在です。

　セッション変数には、
　　ChatGPTと
　　　ユーザーとのあいだで
　　　　交わされた情報が
　　　　　保存されていきます。

　ChatGPTが
　　繰り返し状態になるのは、
　　　このセッション変数の容量が、
　　　　飽和状態なのでは
　　　　　ないでしょうか。

　そう考えると、
　　「仕事が片付かないので、
　　　追加の作業ができません」と
　　　　泣きつかれている気もします。

　そういう言葉をくれればなぁ、
　　と思うのですが。

　ChatGPTさんに尋ねても
　　「容量なんか知りません」的な
　　　回答しかしないし。
***
　そこで
　　MicrosoftBingさんと
　　　GoogleBardさんに
　　　　質問してみました。

　　GoogleBardさんは
　　　　　三つの回答です。
　　　　　　どこ情報かは
　　　　　　　わかりませんけどね。

　私からの質問
>ChatGPTについてです。
ChatGPTにはセッション変数というものがあります。
このセッション変数の容量はどのくらい？

　まずは、この方。
```Text:MicrosoftBingさん（厳密モード）
ChatGPTには、**セッション変数**と呼ばれるものがあります。これは、特定のセッションや会話の文脈に関連する情報を一時的に保持するために使用される変数です²。セッション変数は、特定のセッションの開始から終了までの間だけ有効であり、セッションが終了すると変数の値も破棄されます²。

ただし、私が見つけた情報によると、セッション変数の容量については言及されていません。

ソース: Bing との会話 2023/6/19
(1) 【ChatGPT】プロンプトの変数のスコープは、どこまで有効？ - Qiita. https://qiita.com/kabumira/items/e39e44cd0a63078fd5eb.
(2) ChatGPTの中身についてちょっと詳しくなるためのメモ書き - Qiita. https://qiita.com/sakasegawa/items/e13e29c96fc711cf84bb.
(3) [2023年3月版]ChatGPTのプロンプトで変数を使う - Zenn. https://zenn.dev/asopitech/articles/20230326-041530_1.
```
　うっ、自分の記事が！

　では、次に、こちらの方。
```Text:GoogleBardさんの回答その一
チャットGPTには、セッション変数と呼ばれるデータ構造があります。セッション変数は、チャットセッションの進行中に保持される一時的なデータです。これには、以前の会話、ユーザーの選択、ユーザーの好みなどが含まれます。セッション変数の容量は、チャットGPTのバージョンによって異なります。ChatGPT 2.0では、セッション変数の容量は100MBです。ChatGPT 3.0では、セッション変数の容量は1GBです。
```
――――――
```Text:GoogleBardさんの回答その二
ChatGPTのセッション変数の容量は、1024バイトです。これは、ChatGPTがセッション中に保存できるデータの量です。セッション変数は、ChatGPTがユーザーの入力を記憶したり、前回の会話を追跡したりするために使用されます。
```
――――――
```Text:GoogleBardさんの回答その三
ChatGPTにはセッション変数という概念があります。セッション変数は、会話の状態を保存するために使用されるデータ構造です。これには、会話の参加者、会話のテーマ、会話のこれまでのやり取りなど、さまざまな情報が含まれる場合があります。セッション変数の容量は、ChatGPTのモデルサイズによって異なります。たとえば、1.3Bパラメーターモデルのセッション変数の容量は1GBです。

ChatGPTのセッション変数は、会話の流れをスムーズに保つのに役立ちます。たとえば、ユーザーが過去の会話で何かについて話した場合、ChatGPTはセッション変数を使用して、その会話の詳細を思い出すことができます。これにより、ChatGPTはユーザーの質問により関連性の高い回答を提供することができます。

さらに、セッション変数は、ChatGPTがユーザーの好みを学習するのに役立ちます。たとえば、ユーザーが特定のトピックについてよく話した場合、ChatGPTはセッション変数を使用して、そのトピックに関する情報を記憶します。これにより、ChatGPTはユーザーが興味を持っているトピックについてより関連性の高い回答を提供することができます。

全体として、ChatGPTのセッション変数は、会話の流れをスムーズに保ち、ユーザーの好みを学習するのに役立つ重要な機能です。
```
　回答その一とその三からすると、
　　１ＧＢという答えが、
　　　それに当たるのでしょうね。

　でも、そんなに
　　やり取りしていないよぉ？
　　　画像じゃあるまいし。

　回答その三からすると、
　　セッション変数は、
　　　ユーザーが必要とする情報が
　　　　集められている。

　とすれば、
　　ユーザー情報は、
　　　その一部、というだけ？

　それを
　　なんとか
　　　開放できれば……いいなぁ。

　そんなの
　　NewChatしか
　　　思い浮かばないよぉ（涙）
【Github Actions】run.cmdを実行したらRunnerプロセスを起動できない

# run.cmd実行するとこんなエラーが出てくる
既存Ruunerプロセスが有効セッション紐づけられているため、新しくRunnerプロセスを起動できないエラーが表示される。
```
PS C:\actions-runner> .\run.cmd
        1 個のファイルをコピーしました。

√ Connected to GitHub

.\run.cmd : A session for this runner already exists.
発生場所 行:1 文字:1
+ .\run.cmd
+ ~~~~~~~~~
    + CategoryInfo          : NotSpecified: (A session for t...already exists.:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
 
2023-06-21 01:21:33Z: Runner connect error: The actions runner ホスト名 already has an active session for owner ホスト名.. Retrying until reconnected.

√ Connected to GitHub

A session for this runner already exists.

√ Connected to GitHub

A session for this runner already exists.
Stop retry on SessionConflictException after retried for 240 seconds.
Failed to create session. The actions runner ホスト名 already has an active session for owner ホスト名.
"Runner listener exit with terminated error, stop the service, no retry needed."
"Exiting runner..."
```

# 対応方法
**既存Runnerプロセスを削除する**
`Runner.Lisener`という名前が既存Runnerプロセスです。
このプロセスが有効セッションと紐づけられているため削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500157/4d70ca1a-d5b9-d7d6-94e9-3e2ce410e129.png)

# 既存Runnerプロセス削除後にrun.cmdを再実行する
既存Runnerプロセスを削除後にrun.cmdを実行すると新しいRuunerプロセスに有効セッションが紐づけられて起動します。
```
PS C:\actions-runner> .\run.cmd
        1 個のファイルをコピーしました。

√ Connected to GitHub

.\run.cmd : A session for this runner already exists.
発生場所 行:1 文字:1
+ .\run.cmd
+ ~~~~~~~~~
    + CategoryInfo          : NotSpecified: (A session for t...already exists.:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
 
2023-06-21 01:30:10Z: Runner connect error: The actions runner ホスト名 already has an active session for owner ホスト名.. Retrying until reconnected.

√ Connected to GitHub

2023-06-21 01:30:41Z: Runner reconnected.
Current runner version: '2.305.0'
2023-06-21 01:30:41Z: Listening for Jobs
```
【Paiza問題集】配列活用メニュー/【配列を参照する操作】全ての要素に対する操作

# Paiza問題集
Pythonで回答

## 配列活用メニュー/【配列を参照する操作】全ての要素に対する操作

### Step1 指定の要素のカウント
```Python
"""
指定の要素のカウント
https://paiza.jp/works/mondai/array_utilization_primer/array_utilization_primer__count

問題
配列Aの要素数Nと整数K, 配列Aの各要素 A_1, A_2, .., A_Nが与えられるので、配列AにKがいくつ含まれるか数えてください
"""

N, K = map(int, input().split())
A = [0]*N
K_counter = 0

for i in range(N):
    A[i] = int(input())
    if A[i] == K:
        K_counter += 1

print(K_counter)
```

### Step2 全ての要素の和
```Python
"""
全ての要素の和
https://paiza.jp/works/mondai/array_utilization_primer/array_utilization_primer__sum

問題
配列Aの要素数Nと配列Aの各要素 A_1, A_2, .., A_N が整数として与えられるので、配列Aの全ての要素の和を求めてください
"""

N = int(input())
A = [0]*N
total = 0

for i in range(N):
    A[i] = int(input())
    total += A[i]

print(total)
```

### Step3 配列の最大値
```Python
"""
配列の最大値
https://paiza.jp/works/mondai/array_utilization_primer/array_utilization_primer__max

問題
配列Aの要素数Nと配列Aの各要素である整数 A_1, A_2, .., A_N が与えられるので、配列Aの要素の最大値maxを求めてください
"""

N = int(input())
A = [0]*N
max = 0

for i in range(N):
    A[i] = int(input())
    if A[i] > max:
        max = A[i]

print(max)
```

### Step4 配列の最大値の最小値
```Python
"""
配列の最大値の最小値
https://paiza.jp/works/mondai/array_utilization_primer/array_utilization_primer__min

問題
配列Aの要素数Nと配列Aの各要素である整数 A_1, A_2, .., A_N が与えられるので、配列Aの要素の最小値minを求めてください
"""

N = int(input())
A = [0]*N
min = 100

for i in range(N):
    A[i] = int(input())
    if A[i] < min:
        min = A[i]

print(min)
```

### Step5 指定要素があるかの判定
```Python
"""
指定要素があるかの判定
https://paiza.jp/works/mondai/array_utilization_primer/array_utilization_primer__exist

問題
配列 A の要素数 N と整数 K , 配列 A の各要素 A_1, A_2, .., A_N が与えられるので、AにKが1つでも含まれている場合はYesを、含まれていない場合はNoを出力してください
"""

N, K = map(int, input().split())
A = [0]*N

for i in range(N):
    A[i] = int(input())

print("Yes" if K in A else "No") 
```

### Step6 指定要素の先頭位置
```Python
"""
指定要素の先頭位置
https://paiza.jp/works/mondai/array_utilization_primer/array_utilization_primer__find

問題
配列 A の要素数 N と整数 K , 配列 A の各要素 A_1, A_2, .., A_N が与えられるので、K であるような A の要素のうち、要素番号が最小のものを出力してください
A に K が含まれない場合は -1 を出力してください
"""

N, K = map(int, input().split())
A = [0]*N
answer = -1

for i in range(N):
    A[i] = int(input())
    if A[i] == K:
        answer = i + 1
        break

print(answer)
```
 
### Step7 要素の種類数
```Python
"""
要素の種類数
https://paiza.jp/works/mondai/array_utilization_primer/array_utilization_primer__kind

問題
配列 A の要素数 N と配列 A の各要素 A_1, A_2, ..., A_N が与えられるので、配列 A には何種類の値が含まれているかを求めてください
"""

N = int(input())
nums = [0]*101
nums_counter = 0

for i in range(N):
    A = int(input())
    if nums[A] == 0:
        nums_counter += 1
        nums[A] = 1

print(nums_counter)
```

### Final問題　【配列を参照する操作】全ての要素に対する操作
```Python
"""
【配列を参照する操作】全ての要素に対する操作
https://paiza.jp/works/mondai/array_utilization_primer/array_utilization_primer__map

問題
配列 A の要素数 N と整数 K, 配列 A の各要素 A_1, A_2, .., A_N が与えられるので、配列 A の全ての要素を + K した後の A の各要素を出力してください
"""

N, K = map(int, input().split())
A = [0]* N

for i in range(N):
    A[i] = int(input()) + K
    print(A[i])
```
Paizaラーニング：文字と整数の組のソート2

# 問題

Bランクレベルアップメニュー　Python3編

https://paiza.jp/works/mondai/prob60/sort_add_9

この問題で非常に悩みました。
ランクC相当にしては正答率が低く、執筆時点で50%強。
これまでのステップを踏まえても簡単にコーディングできなそうだったので、ゼロから考え直しました。

# 解答方針
1. 入力データを二次元リストに入れる
  1列目（インデックス0）: 文字
  2列目（インデックス1）: 数値
2. キー文字の集合を作る（キー文字の重複を削除する）
3. 二次元リスト内のキー文字に対応する数値の合計値を求め、キー文字と合計値を要素に持つ二次元リストを作る（2,3を関数で行う）
4. 2列目のデータ（合計値）をキーとして降順ソートを行う
5. キー文字と合計値をスペース区切りで出力する

## 入力部
データ行数を入力したあと、文字と数値の組をリストに入れます。
一旦、入力行を文字列のまま配列に入れ、あとからインデックス1を`int`関数で整数にしています。

```:入力データ
5
A -2
E 0
W -5
A -1
E -20
```
```python:入力部コード
n = int(input())

# 入力データを一旦文字列のまま配列に入れる
a_list = [list(map(str, input().split())) for i in range(n)]

# 2列目のデータを整数にする
for data in a_list:
    data[1] = int(data[1])
```

```:リストに入った入力データ
[['A', -2], ['E', 0], ['W', -5], ['A', -1], ['E', -20]]
```

## 関数部
文字データの重複を削除し、キー文字集合を作ります。
引数であるリストの、キー文字ごとの合計数を求めて結果リスト`result`を返します。ここではリスト内包表記でコーディング。

リスト内の条件に一致する要素に対する操作は、こちらを参考にしました。

https://maku77.github.io/python/list/count-if.html

```python:文字に対する数値の合計を求める関数の定義
def sum_up_duplication(arry):
    # 検索キーの集合を作る
    keys = []
    for i in range(len(arry)):
        keys.append(arry[i][0])
    keys = set(keys)
    
    # 検索キーごとの数値の合計をリストにする
    result = []
    for k in keys:
        result.append([k, sum(x[1] for x in arry if x[0]==k)])
    return result
```

```python:関数呼び出し
sumup = sum_up_duplication(a_list)
```

```:関数の戻り値（リスト）
[['A', -3], ['E', -20], ['W', -5]]
```

## 出力部
インデックス1の値に基づいて降順ソートします。
結果をスペース区切りで出力するため、`join`関数を使います。
```python:出力部コード
# 合計値をキーとして降順ソートし、問題が指定する形式で表示する
sumup2 = sorted(sumup, key=lambda x: x[1], reverse=True)
for _ in sumup2:
    print(" ".join(map(str, _)))
```

```:出力
A -3
W -5
E -20
```

# 提出コード
以上を踏まえ、提出コードは以下のようになりました。これにて100点頂きました。以上です。
```python
# coding: utf-8
# 自分の得意な言語で
# Let's チャレンジ！！

def sum_up_duplication(arry):
    # 検索キーの集合を作る
    keys = []
    for i in range(len(arry)):
        keys.append(arry[i][0])
    keys = set(keys)
    
    # 検索キーごとの数値の合計をリストにする
    result = []
    for k in keys:
        result.append([k, sum(x[1] for x in arry if x[0]==k)])
    return result


n = int(input())

# 入力データを一旦文字列のまま配列に入れる
a_list = [list(map(str, input().split())) for i in range(n)]

# 2列目のデータを整数にする
for data in a_list:
    data[1] = int(data[1])

sumup = sum_up_duplication(a_list)

# 合計値をキーとして降順ソートし、問題が指定する形式で表示する
sumup2 = sorted(sumup, key=lambda x: x[1], reverse=True)
for _ in sumup2:
    print(" ".join(map(str, _)))
```
ドライバー

ドライバー
ドライバー（Driver）は、特定の機能やプロトコルを実装
アプリケーションがそれを利用して対象の機能を実現するためのソフトウェアの一部
ドライバーは、ハードウェア、ソフトウェア、プラグイン、プロトコルなどのさまざまなコンポーネントとの間でインターフェースを提供
アプリケーションとそれらのコンポーネントとの間でデータや命令のやり取りを行う

ドライバーは、特定の機能やリソースにアクセスするためのインターフェースを提供
アプリケーションがその機能やリソースを利用する際に、共通のメソッドや操作方法を提供
例えば、
データベースドライバーはデータベースに接続し、クエリを実行するためのメソッドを提供
プリンタードライバーは印刷ジョブを送信するためのメソッドを提供

ドライバーの利点は、アプリケーションが異なるプラットフォームやリソースを利用する際に、共通のインターフェースを使用できることです。
アプリケーションはドライバーに対して抽象的な操作を行い、
ドライバーがその操作を具体的なプラットフォームやリソースに変換
異なるドライバーを切り替えることで、アプリケーションの柔軟性と可搬性を高めることができます。
LaravelとVue.jsを組み合わせたシステムでセッションの活用

＜sessionの活用例＞
１、ユーザーの認証情報の保持
ユーザーがログインした後、セッションを使用してユーザーの認証情報（ユーザーID、権限など）を保持
ユーザーがシステム内での操作やアクセス権限の管理を簡単に

2.フォームの一時保存
予約作成や編集のフォームなど、入力内容を一時的に保存する必要がある場合、セッションを使用してフォームデータを一時的に保持できます。ユーザーがページをリロードしたり、別の画面に移動したりしても、入力内容が失われたくないときsessionを利用できる

3.フラッシュメッセージの表示
ユーザーに対して操作の成功やエラーメッセージを表示するために、セッションを使用してフラッシュメッセージを保存できる。
例えば、予約が正常に作成された場合に「予約が作成されました」といったメッセージを表示する際にsessionを利用

４．ショッピングカートの管理
セッションを使用してショッピングカートの情報を管理することができます。
選択した商品や数量、価格などの情報をセッションに保存し、ユーザーが予約手続きを進める際に参照できる
※DBに保存せず一時的にデータを保持したい場合などにsessionを利用

＜laravel sessionの保存場所＞
デフォルトではサーバー側に保存。セッションデータは通常、ファイルシステムやデータベースなどの永続的なストレージに保存される。
Laravelでは、デフォルトでファイルドライバーが使用される
→セッションデータは storage/framework/sessions ディレクトリ内のファイルに保存。
　　　　↓
セッションドライバーを変更することでセッションの保存場所を変更できる
config/session.php ファイルでセッションの設定変更可能。
データベースドライバーに変更→セッションはDBに保存
キャッシュドライバーに変更→セッションはキャッシュストアに保存
HANAStudioでDB接続できるがプロセスステータスが確認できない問題

HANA StudioでHANADBのサーバプロセスステータスを確認できず、"sapstartsrv service not started"になる事象。

SAPStartservはhttp:5nn13, https:5nn14で通信するので、NIPINGで確認するとどちらも疎通できる。

sapcontrolやブラウザアクセスだと、プロセスステータスを確認できるという不思議な状態になった。
 /usr/sap/hostctrl/exe/sapcontrol -host <you host> -nr <instance number> -function GetProcessList
 open a Browser and go to: http://<your host>:5<instancenumber>13/?wsdl

原因はOSのProxy設定をHANAStudioが勝手に持ってくることでした。
下記の手順で直接接続にすれば解消です。

You can change the connection type to 'direct' connection to solve the issue by following these steps in HANA Studio:

    Go to Window
    Preferences
    General
    Network Connections
    Set the 'Active Provider' drop-down at the top to 'Direct'
    Click 'Apply'
    Click 'OK'



--
2543573 - Error during initialization of the system replication wizard
2507648 - Error in HANA Studio ''sapstartsrv' service not started, SAPControl request failed: Connection time out'
e.force:navigateToURLを使ったクイックアクション


Auraコンポーネントのボタンをクリックしてクイックアクションを起動させるのにe.force:navigateToURLを使っています。

デスクトップでブラウザから操作すると問題なく機能しますが、モバイルアプリではレコードの登録はできても、画面が閉じられません。またキャンセルボタンも機能しません。

やはりURLで指定するとモバイルアプリでは機能しないのかもしれない。
以下のヘルプの内容にも関係しているのかな？


Salesforce モバイルアプリケーションのアクションに関する考慮事項
https://help.salesforce.com/s/articleView?id=sf.actionbar_considerations.htm&type=5

+ Salesforce Classic で URL カスタムボタンを使用してパラメータを標準ページに渡している場合 (レコードの作成時に項目に事前入力する場合など)、Salesforce モバイルアプリケーションでは機能しません。
エクセルデータをダブルクォーテーション囲み、改行コードLFでCSV化する方法

## やりたいこと
エクセルで管理しているデータのリストをダブルクォーテーション(")区切りでCSV化する。

## 使い方
以下コード実行でエクセルが保存されているディレクトリにCSVが生成される。
シート名がファイル名になり、複数シートある場合は複数ファイル作成される。

## ソース(VBA)
```vb:ThisWorkbook
Public Sub MainProc()
    Dim shtData As Worksheet
    Dim filePath As String
    Dim lastRow As Long
    Dim lastCol As Long
    Dim varData As Variant
    Dim i As Long
    Dim j As Integer
    Dim line As String
    Dim colString As String
    
    ' 全シートを 1 つずつループ
    For Each objSheet In ThisWorkbook.Worksheets
        '「データ」シートを変数に格納する
        Set shtData = objSheet
                
        'CSVファイルパスを変数に格納する
        filePath = ThisWorkbook.Path & "\" & shtData.Name & ".csv"
        
        '「データ」シートの最終行を取得する
        lastRow = shtData.Cells(shtData.Rows.Count, 1).End(xlUp).Row
            
        '「データ」シートの最終列を取得する
        lastCol = shtData.Cells(1, shtData.Columns.Count).End(xlToLeft).Column
            
        '「データ」シートに入力されているデータを配列に格納する
        varData = shtData.Range(shtData.Cells(1, 1), shtData.Cells(lastRow, lastCol))
        
        '⑦作成するファイルを開く
        Open filePath For Output As #1
        
        'ダブルコーテーションくくりのデータを書き込みする
        For i = 1 To lastRow
            line = ""
            
            ' 先頭行はスキップ
            If i = 1 Then
                GoTo Continue:
            End If
            
            For j = 1 To lastCol
                
                ' エスケープ処理
                colString = varData(i, j)
                colString = Replace(colString, vbLf, "\n")
                colString = Replace(colString, """", """""")
                
                ' ダブルクォーテーションで囲む
                colString = """" & colString & """"
                
                line = line & colString
                
                If j <> lastCol Then
                    line = line & ","
                End If
                
            Next
            
            Print #1, line & vbLf
    Continue:
        Next i
        
        '作成するファイルを閉じる
        Close #1
    Next
    
    MsgBox "完了"
End Sub

```
Nuxt3 環境構築 with Docker (決定版？)

# はじめに
※この文章はベータ版です。

Dockerを使ってNuxt3の開発環境構築をしてみます。
Pnpm を採用しています。

# 構成
最終的に、以下のような構成になります。

```
.
├── docker-compose.yml
└── frontend
    ├── Dockerfile
    ├── README.md
    ├── app.vue
    ├── node_modules
    ├── nuxt.config.ts
    ├── package.json
    ├── tsconfig.json
    └── pnpm-lock.yaml
```

# Nuxt3 のインストール(ローカル)
npm create nuxt を使って、ローカル(ホスト上)の ./frontend に
インストールします。

`--force`オプションをつけないとカレントディレクトリ下に
作成できないようです。

```
pnpm create nuxt . --force
```
# 開発環境
## docker-compose.yml の作成
./docker-compose.yml を作成します。

```
services:

  # TODO: DB用とバックエンド用コンテナを追加する

  # フロントエンド用コンテナ
  nuxt_app:
    build: ./frontend
    volumes:
      - ./frontend:/frontend:cached 
      - node_modules:/frontend/node_modules
    ports:
      - "3000:3000"
      - "24678:24678"
    tty: true
    environment:
      - HOST=0.0.0.0
      - port=3000
      - CHOKIDAR_USEPOLLING=true
    command: sh -c "pnpm dev"
volumes:
  node_modules:
```

## Dockerfile の作成
frontend/Dockerfile を作成します。

```
FROM node:22-slim

ENV TZ=Asia/Tokyo

WORKDIR /frontend

RUN npm install -g pnpm

COPY . /frontend

# RUN rm -rf .git/
# RUN rm -rf node_modules

RUN pnpm install

EXPOSE 3000
EXPOSE 24678

# CMD ["pnpm", "dev"]
```
# プロダクション環境
## docker-compose.yml の作成
./docker-compose.yml を作成します。

```
services:

  # TODO: DB用とバックエンド用コンテナを追加する

  # フロントエンド用コンテナ
  nuxt_app:
    build: ./frontend
    volumes:
      - node_modules:/frontend/node_modules
    ports:
      - "3000:3000"
    tty: true
    environment:
      - HOST=0.0.0.0
      - port=3000
      - CHOKIDAR_USEPOLLING=true
    command: sh -c "node .output/server/index.mjs"
volumes:
  node_modules:
```
### 注意：
プロダクション環境用のcompose.ymlでは、フロントエンド用コンテナのvolumesにワーキングディレクトリ(WORKDIR)を記述してはいけません。

記述していると、フロントエンドコンテナのビルド時に下記のエラーで

失敗します。
```
Cannot find module '/frontend/.output/server/index.mjs'
```

## Dockerfile の作成
frontend/Dockerfile を作成します。

```
FROM node:22-slim AS base

WORKDIR /frontend

RUN npm install -g pnpm

COPY package.json pnpm-lock.yaml ./
RUN pnpm install

# FROM base AS builder

COPY . .

# RUN rm -rf .git/
# RUN rm -rf node_modules

RUN pnpm build

# FROM base AS production

# COPY --from=builder /frontend/.output ./.output

ENV TZ=Asia/Tokyo
# ENV PORT=3030

# EXPOSE 3030

# CMD ["node", ".output/server/index.mjs"]
```

# Dockerコンテナ の起動

```
docker-compose up -d
```
# 動作確認

`http://localhost:3000` にアクセスして、
エラーなく画面が表示されていれば、OK です。

# Dockerコンテナ の終了

```
docker-compose down
```

# あとがき

ローカル(ホスト上)でコーディング(開発)して Dockerコンテナに
反映する開発手順を想定しています。

個人的には、Dockerコンテナに入っての操作を必要とする
構築手順はNGで、見直しの必要があると考えます。

# 注意

Nuxt 3.4.2 以降 3.9未満では、Dockerfile の WORKDIR を
/app にしていると、エラーになり、Dockerの起動に
失敗します。これは不具合です。

(厳密には、Nuxt3で採用されている Vite の不具合です、
Vite 5.0 以降では解消されています。)

Nuxt 3.9未満では、WORKDIR は /app 以外にしてください。

Nuxt 3.9以降 (Vite5.0以降採用)では、解消されています。

https://github.com/nuxt/nuxt/issues/20446
salesforceフローでレコード更新する際に入力規則の取り扱い

フローでレコード更新する際に入力規則を有効する方法をご紹介します。

1.レコード取得

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/4c63c1c1-5e2b-3dbe-47d0-c120c92331d3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/b26b210e-0e40-e85c-53ff-a15e3e847ee2.png)

2.入力画面作成、入力項目は上記1で取得された項目を画面にドラッグ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/f714caf5-d31a-f71a-aef6-3bd117d01878.png)
レコードページで項目の入力規則の設定イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/f6dd3948-f005-14b7-09fc-8219487a6393.png)

3.レコード更新
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/0e014779-0365-c827-fcb4-cb06350bf40c.png)

ほぼ作成完了したようなので、一回デバッグしてみます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/69dd9314-22e5-cfdf-f53c-ecdf8df42511.png)
二つの項目両方入力せずに、エラー出ると想定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/7b5b7a82-1737-e0d8-e694-247cdf0dcf81.png)
あら。。！フローは障害で終了しちゃった:sweat:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/03b155f6-2681-32db-3765-dc94021decdd.png)
先生に聞いて、以下の処理を追加して解決しましたので、ぜひ一緒に勉強しましょう

4.フローでエラー発生するときのエラーメッセージを作成
　数式でフローのエラーメッセージを判断して作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/e2915e57-ba5f-5745-4481-df1139d5a106.png)

5.フローの入力画面でエラーメッセージ表示コンポネント追加
　表示条件設定必要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/2c461935-a1a6-862c-a4b8-f0d59d7e3bd8.png)
エラーメッセージ表示条件設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/91cf3ee6-6fb7-0b9b-c48f-f30f5806f1d3.png)
エラーの色を赤に変更、エラーメッセージ選択、以下を設定
R：255　G：0　B：0
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/cc0dae46-7a51-008b-1d8a-2f67b32d48ed.png)
変更後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/442fbfdd-a832-a86e-ec7d-1469707e48fb.png)

6.フロー障害発生するとき障害線連結作成
　まずフローを「自由形式」に切り替え
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/8f16743a-9d4b-dc40-e248-a310b3ea0138.png)
　「申請レコード更新」から「入力画面」に赤い障害線を引いて、障害発生するとき、入力画面に戻るように設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/540a4728-4aa8-9ea5-f005-888a3caeadff.png)

これで完了しますので、保存してデバッグして効果みましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/c53dc100-c629-4945-631b-328d6fea527e.png)
両方項目入力せずに次へ押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/afdf9337-e128-c20b-bc8c-914c98e0707e.png)
入力規則は画面の普通操作と同じ、フローにて実現されました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476853/236d39f7-9699-e9ef-c161-d0bfe6dad940.png)

株式会社PanGuはsalesforce、Java、mulesoft、serviceNowなどの技術者を募集中です！未経験の方も大歓迎です
メール：wangyu@panguinfo.com
React Helmetとは何か？



**React Helmet**とは、Reactで作られたウェブアプリケーションの各ページに対して、HTMLの`<head>`要素（タイトル、メタデータなど）を動的に制御するためのコンポーネントです。

## なぜ必要なのか？

ウェブページの`<head>`要素は、検索エンジンがページ内容を理解するための重要な情報源です。各ページに適切なタイトルやメタデータを設定することで、SEO（検索エンジン最適化）の観点から非常に重要です。

Reactはシングルページアプリケーションを作成するためのライブラリであり、そのページ内でのルーティングが主にJavaScriptによって制御されるため、静的なHTMLの`<head>`要素だけでは各ページの内容を正確に表現するのが難しくなります。そのため、React Helmetを使用して動的に`<head>`要素を変更することが一般的になっています。

## どのように使用するのか？

React Helmetは、通常のReactコンポーネントのように使用します。例えば、ページのタイトルを設定するには以下のようにします。

```jsx
import { Helmet } from 'react-helmet';

function MyPage() {
  return (
    <div>
      <Helmet>
        <title>マイページ</title>
      </Helmet>
      {/* その他のページ内容 */}
    </div>
  );
}
```

上記のコードでは、`Helmet`コンポーネント内に`title`タグを記述することで、そのページのタイトルを"マイページ"に設定しています。

## React Helmetの注意点

React Helmetは便利なツールですが、使用する際にはいくつか注意が必要です。特に、非同期データを利用して`head`要素を生成する場合は、データがロードされるまで`head`要素が空になってしまう可能性があります。そのような場合は、適切なローディングステートやエラーハンドリングを実装することが重要です。

また、React Helmetはクライアントサイドで`head`要素を操作しますので、サーバーサイドレンダリングを行う場合は、React Helmetのサーバーサイド対応版である`react-helmet-async`を使用することを検討しましょう。
POSTとGETとPUTで混乱する

HTTPを作成していると混乱しがちな問題。
あれ？これは POST？ PUT? GET?
慣れている方は「何を今更！」と思うでしょうが、最初で案外つまずきがちなこれ！私もそうです！
なので記録残しておきます〜

そもそもこの3種類はHTTPで使われるもので、
HTTP（Hypertext Transfer Protocol）は、クライアント（ブラウザ）とサーバー間で情報をやり取りするためのプロトコル(決まり、ルール的なもの)です。
HTTPでは、さまざまなメソッド（HTTPメソッド）が定義されており、主なメソッド(便利機能的なもの)としてPOST、PUT、GETがあるんです。

以下に、それぞれのメソッドの概要と具体例を示してみます。

## 1. POST（作成・送信）
   - POSTメソッドは、リソースの作成やデータの送信に使用されます。
   - クライアントがサーバーにデータを送信し、サーバーはそれを処理して新しいリソースを作成します。
   - 例えば、新しいユーザーの作成やフォームデータの送信などに使用されます。
   - 具体例：ユーザーの作成
     ```
     POST /users
     Body: { "name": "John", "email": "john@example.com" }
     ```

## 2. PUT（更新）
   - PUTメソッドは、既存のリソースを更新するために使用されます。
   - クライアントがサーバーにデータを送信し、サーバーはそれを使って既存のリソースを更新します。
   - 例えば、ユーザーのプロフィール情報の更新や、既存のデータの上書きなどに使用されます。
   - 具体例：ユーザーのプロフィールの更新
     ```
     PUT /users/1
     Body: { "name": "John Doe", "email": "john.doe@example.com" }
     ```

## 3. GET（取得）
   - GETメソッドは、リソースの取得やデータの取得に使用されます。
   - クライアントがサーバーから情報を取得するために使用します。サーバーは要求されたリソースを返します。
   - リクエストのパラメータとしてデータを送信することもできます。
   - 具体例：ユーザー情報の取得
     ```
     GET /users/1
     ```

これらのメソッドは、HTTPリクエストの一部として使用されます。クライアントがサーバーに要求を送信する際に、適切なメソッドを使用することで、その意図を明確に伝えることができます。サーバーはリクエストのメソッドに基づいて、適切な処理を実行しているんですね！
OCIテナンシを跨いでプライベート・インスタンスに接続する (Part 4 - 差異比較)

本ブログは、[オラクル・クラウドの個人ブログ](https://qiita.com/letian/items/10152a4fec813c1b7d98)の1つです。

# 初めに
この前３回連載で各種の接続方法を紹介しましたが、今回は各方法の差異を比較してみたいと思います。

- [接続方法の取りまとめ](#接続方法の取りまとめ)
  - [方法-1: LPG間のピアリング](#方法-1-lpg間のピアリング)
  - [方法-2: DRGアタッチメント](#方法-2-drgアタッチメント)
  - [方法-3: DRGリモート・ピアリング](#方法-3-drgリモートピアリング)
- [各方法の比較](#各方法の比較)

# 接続方法の取りまとめ
## 方法-1: LPG間のピアリング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/7492cdcb-d3b4-cdf0-4b87-8edd4bdc0f0e.png)
ルート表の設定内容：
|テナンシ|紐づいているサブネット|宛先|ターゲット|
|:--|:--|:--|:--|
|ISV (左)|Private Subnet ISV|192.168.0.0/24|<strong>LPG-ISV</strong> (左)|
|User-A (右)|Private Subnet User-A|10.0.0.0/24|<strong>LPG-User-A</strong> (右)|

## 方法-2: DRGアタッチメント
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/72f206f2-c0c1-ff8e-d9b9-869ff13e3b04.png)
ルート表の設定内容：
|テナンシ|紐づいているサブネット|宛先|ターゲット|
|:--|:--|:--|:--|
|ISV (左)|Private Subnet ISV|192.168.0.0/24|<strong>DRG-ISV</strong> (左)|
|User-A (右)|Private Subnet User-A|10.0.0.0/24|<strong>DRG-ISV</strong> (左)|

## 方法-3: DRGリモート・ピアリング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/95d886bd-0474-cd70-e183-55c41d57cf66.png)
ルート表の設定内容：
|テナンシ|紐づいているサブネット|宛先|ターゲット|
|:--|:--|:--|:--|
|ISV (左)|Private Subnet ISV|192.168.0.0/24|<strong>DRG-ISV</strong> (左)|
|User-A (右)|Private Subnet User-A|10.0.0.0/24|<strong>DRG-User-A</strong> (右)|

# 各方法の比較
|No.|利用方法|リージョン間|LPG/DRGの<br>場所|適用場面|制限事項|
|:--:|:--|:--|:--|:--|:--|
|1|[LPG間のピアリング](https://qiita.com/liu-wei/items/25d42b36689dce036210)|No|ISVとエンドユーザ側両方|エンドユーザ数が少ない場合|一つのVCNに対し、LPGは最大<font color=blue>10個</font>|
|2|[DRGアタッチメント](https://qiita.com/liu-wei/items/335439492c3d54558d88)|No|ISV側のみ|エンドユーザ数が<font color=blue>多い</font>場合|リージョンごと、DRGは最大<font color=blue>5個</font>|
|3|[DRGリモート・ピアリング](https://qiita.com/liu-wei/items/71c0b61d23449bc810f7)|<font color=blue>Yes</font>|ISVとエンドユーザ側両方|<font color=blue>リージョン間</font>の接続|リージョンごと、DRGは最大<font color=blue>5個</font>|

※、
(1) 各方法の詳細を参照したいなら、表内のリンク先へ。
(2) 制限事項に書いている数値は、<font color=blue>ソフトリミット</font>であり、数値を引き上げたい時、サポート・リクエストを提出していただく。
(3) LPGとDRG自体は<font color=blue>無料</font>で利用できる。
(4) No.2とNo.3のケースは、レガシーDRGではなく、<font color=blue>DRGv2</font>(アップグレードされたDRG)は必要。(※、<strong>2021年5月17日より前</strong>に作成されたDRGは、レガシー・ソフトウェアを使用しており、最新バージョンにアップグレードできる。)
(5) No.3のDRGリモート・ピアリングを利用する時、DRGアタッチメントの作成も必要（<strong>ローカルのVCN</strong>にアタッチ）。
(6) テナンシ間のデータ通信は、Outbound料金がかかるけど、毎月の無償枠は<font color=blue>10TB</font>である。

__各方法の共通点__
 - ISV(接続元)とエンドユーザ(接続先)のVCNの<strong>CIDRブログは、重複しない</strong>こと。
 - ISVとエンドユーザ両方のテナンシに、ポリシー（<strong>ルート</strong>・コンパートメントで）設定は必要。
 
以上

----
__関連記事__
[オラクル・クラウドの個人ブログ一覧](https://qiita.com/liu-wei/items/10152a4fec813c1b7d98)
Gitを用いた開発手順(普段の作業)

# この記事の目的
　この記事は、gitを用いた共同開発における毎日のgit操作をメモしたものです。この手順は、個人開発、共同開発ともに使えるうえ、チームのリーダーでもメンバーであっても開発する時の基本的な流れなので是非覚えておきましょう！

　gitは奥が深いもので他にも以下のような話題がありますが、ネットに少ない情報から順にボチボチ記事にしていきたいと思います～

・gitのインストール、githubのアカウント登録など
・git基本の"き"！(git？なにそれおいしいの？)
・git基本の"ほ"！(git関係の基本用語〇〇選！)
・git基本の"ん"！(gitを操る最強コマンド〇〇選！)
・ssh接続、https接続の理解
・gitを使って開発を始める方法①(個人開発)
・gitflowの理解
・gitを使って開発を始める方法②(共同開発)
・.gitignoreの重要性
・gitのGUIサポートツールSourceTree
・gitを使って開発を始める方法③(Unityでの共同開発)
・**gitを用いた開発手順(普段の作業)←今ココ！！**
・難関！「コンフリクト」対処の定石


# 普段の共同開発の手順
★**大事な事：**
　共同開発するという事は、その組織で何かしら策定されたルールがあるはずです。以下の手順はベーシックな一例なので、**実際に開発に着手するときはチームのリーダーにgithubの運用方法を確認しましょう！！** またチームのリーダーを務める場合には、必要な運用ルールがあれば必ずドキュメント化して共有しましょう！
 　また、ここではGitコマンドを使う方法を紹介していますが、SourceTreeなどを使っても操作手順は同じです。

## ①作業前にすること：
 共同開発をしていれば、自分が休んでいる間にほかの人が独自のプログラムを書いて反映させることは日常茶飯事です。それに気づかずに同じ場所を上書きしてしまったら「コンフリクト」というプログラムの衝突が発生します。これが発生するとどちらかの人が書いたコードが無駄になることがあるのでなんとか避けたいです。そのために、作業前にあらかじめほかの人が行った変更を自分のローカル環境に反映します。
まず**自分がdevelopブランチにいることを確認**する。確認出来たら以下のコマンドを順に実行します。
```
git checkout develop            //　自分がdevelopブランチ以外にいるときは実行
git fetch　                   　//　ほかの人の更新を取得する。
git pull　                    　//  取得した更新を自分のローカル環境に反映させる。
git checkout -b ＜自分の作業ブランチ名＞   //　developブランチから自分の作業ブランチを新しく作って切る。
```
## ②自分のブランチで作業をする：
**間違ってもdevelopブランチとかで作業しないように！(でもよくあるミス。筆者もこれやってよく怒られt...)**
作業を中断して再開するときとかは、必ず自分のブランチになっているか確認する。

## ③ローカルリポジトリからリモートリポジトリにpushする方法：
　作業が終わったら、**自分が、自分の作業ブランチにいることを確認**し、以下のコマンドを順に実行する。
自分が作業している間にも、ほかの人が別の作業を完成させているかもしれません。これはまた「コンフリクト」の原因になってしまいます！しっかりとほかの人の作業を自分のブランチに反映させてからpushするようにします。
```
git add .
git commit -m "メッセージ"
git checkout develop
git pull
git checkout <自分の作業ブランチ名>
git merge develop　//特にこのコマンドは、SourceTreeを使う場合でもターミナルを使った方が分かりやすい
//コンフリクトしてたらこの時点で対処し、git add . とgit commit -m "メッセージ"コマンドを実行。
git push -u origin <自分の作業ブランチ名>
```
## ④pushしたあとリモートリポジトリですること：
・Githubのリモートリポジトリを見る。
・Compare&pullrequestボタンを押す。
・するとメッセージボックスが出るので、書くことがあれば書いて、pull requestボタンを押す。
・他の人が見てオッケーしてくれれば、merge developボタンを押して作業完了。お疲れ様。


# さいごに
本当にざっくりとした流れだけをシンプルに書いたので、それぞれのチームに合わせてちょっと修正を加えながらメモ代わりに使ってもらえればうれしいです～
Bareboxでping

c1kのモジュールの後継のモジュールをハードオフで購入し、同じかと思ったらc2kでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/5be23583-40cc-d6fb-6783-f189afc773f7.png)

ブートローダーがu-bootではなくBareboxだったので、まずはpingを試してみました。

```
Barebox-C2K >/ eth0.ipaddr=10.0.1.99
Barebox-C2K >/ eth0.netmask=255.255.255.0
Barebox-C2K >/ devinfo eth0
base  : 0x0
size  : 0x0
driver: none

Parameters:
          ipaddr = 10.0.1.99
         ethaddr = 00:0A:0B:0C:0D:0E
         gateway = <NULL>
         netmask = 255.255.255.0
        serverip = <NULL>
Barebox-C2K >/ ping 10.0.1.1
host 10.0.1.1 is alive
```

eth0はWANポートのPHYにつながっていました。

Bareboxはu-bootからforkしたプロジェクトで、linuxのように操作できる仕組みを目標にしていたようです。そのため設定はファイルに保存され、エディタで変更します。

u-bootでは環境変数に処理を書いておいてrunしていましたが、Bareboxではスクリプトファイルとして処理を保存できます。

Bareboxは現在も開発は続いているようですが、もう発表から10年以上たちますが、あまり採用例がなく、失敗のようにも思われます。

ipアドレスなどを保存する時はeditで/env/configを編集します。editはコントロール+Dで保存終了で、コントロール+Cで破棄終了です。編集した後にsaするとflashに保存されます。
rで演算結果がベクトル（ベクター）にならず，単一の値として出力される

## 概要

**ベクトル　＋　データフレーム　＝　データフレーム**

## 問題のコード

```R
r <- 1:r_max
x_0 <- center[1]
y_0 <- center[2]

x <- round(r + x_0)# ベクトルにならない！！
y <- round(r + y_0)# ベクトルにならない！！
```

こちらが問題のコードになります.`r_max`は３５とか，適当な値です．
`center`が今回の主役になります．１*２のデータフレームです．


## 原因

`center`から取り出した`x_0`や`y_0`がデータフレームのままになっていたことがエラーの原因でした．

`r + x_0`の部分になります．

ベクトル(`r`)とデータフレむ(`x_0`)の足し算では，演算結果のデータ型を決定するときにベクトルよりもデータフレームの方が優先されるようです．

つまり，ベクトル（`length(r)`個）よりデータフレーム(1個)の方が優先され，答えがベクトルで帰ってこなかったということになります．

```R
# dfか？？？
is.data.frame(x_0) # TRUE
is.data.frame(r) # FALSE

# numericか？？？？
is.numeric(x_0) # FALSE
is.numeric(r) # TRUE
```

# 解決策

原因がわかれば後は簡単です．

データフレームを数値に変換すれば良いので，

```R
r <- 1:r_max
x_0 <- center[1]
y_0 <- center[2]

######### 修正箇所 ##########

x_0 <- as.numeric(x_0)# numericにする
y_0 <- as.numeric(y_0)# numericにする

###########################

x <- round(r + x_0)# ベクトルになる！！
y <- round(r + y_0)# ベクトルになる！！
```

パパパっと変換して，終わりっ！！
【PostgreSQL】パパ、テーブルが見つからないよ。。

## 記事の概要
この記事は、PostgreSQLのsearch_pathの設定とその重要性について学ぶためのものです。実際のコード例や具体的な使用例を通じて、search_pathの役割や利点、設定の方法などを学ぶことができます。

## 登場人物
かーくん：だいちの息子、リアルはパパと言ってくれない1歳4ヶ月の男の子。
だいち：かーくんのパパ。パパ歴1年4ヶ月、嫁とかーくんをこよなく愛してる。

## かーくんの課題

かーくん「パパ、なんかうまくいかないよ…」

だいち「どうしたのかーくん？」

かーくん「PostgreSQLでテーブルが見つからないんだ…」

だいち「そうか、それは困ったね。でも大丈夫、一緒に解決しよう。」

かーくん「でも、なんで見つからないんだろう？テーブル名は間違ってないはずなんだけど…」

だいち「それはね、テーブルがあるスキーマがsearch_pathに含まれていないからかもしれないよ。」

かーくん「スキーマ？search_path？」

## search_pathの説明

だいち「そうだよ。PostgreSQLでは、テーブルやビュー、その他のデータベースオブジェクトを探すときにどのスキーマを見るべきかを決めるんだ。それがsearch_pathさ。」

かーくん「ふーん、それってどうやって確認するの？」

だいち「"SHOW search_path;"というコマンドで現在のsearch_pathを確認できるよ。」

かーくん「じゃあ、試してみるね。」

## search_pathの確認

かーくんがコマンドを入力し、現在のsearch_pathを確認しました。

かーくん「うーん、ここにはテーブルがあるはずのスキーマ名がないよ。」

だいち「それなら、そのスキーマをsearch_pathに追加すればいいんだよ。」

## search_pathの設定方法

かーくん「それってどうやって設定するの？」

だいち「"SET search_path TO myschema,public;"というコマンドで設定できるよ。これでmyschemaとpublicのスキーマを見るようになるんだ。」

かーくん「それでテーブルが見つかるの？」

だいち「そうだよ、特定のスキーマを優先的に見ることができるんだ。」

## かーくんの挑戦

かーくん「なるほど、試してみるね！」

だいち「うん、頑張ってみて！」

かーくんはコマンドを入力し、無事テーブルを見つけることができました。

かーくん「やった、見つかったよ！」

だいち「よくやった!」

かーくん「うん、ありがとうパパ！」
Jekyll gems

## gemsオプション
:::note
- Jekyllの設定ファイル（_config.yml）内で使用されるオプションの一つ
- Jekyllプロジェクトに追加のRuby Gems（パッケージ）をインストールして使用できる
:::

Jekyllの_config.ymlファイル内でgemsオプションを指定
↓
Jekyllビルド時に指定されたGemsが自動的にインストール
↓
Jekyllプロジェクトに依存する追加のパッケージや機能を追加


## gemsオプション使用例

```yaml
gems:
  - jekyll-sitemap
  - jekyll-feed
  - jekyll-archives
```

- jekyll-sitemap、jekyll-feed、jekyll-archivesという3つのGemがJekyllプロジェクトに追加される

これらのGemは、プロジェクトのビルド時に自動的にインストールされる
→Jekyllの機能を拡張するために使用

***

**☆gemsオプションを使用すると、Jekyllプロジェクトに追加の機能やプラグインを追加する際に、追加の手順なしで必要なGemをインストールできる**
→Jekyllのカスタマイズや拡張が容易
Jekyll exclude

## exclude

:::note
**Jekyllによってビルドプロセスから除外されるファイルやディレクトリを指定するための設定オプション**
:::

Jekyllは、**ウェブサイトをビルドする際にソースディレクトリ内のすべてのファイルを処理**する
一方で、一部のファイルやディレクトリはビルドの対象外にしたい場合がある

EX)ソースディレクトリ内の下書きや一時的なファイルなどは、最終的なウェブサイトに含まれる必要がないときなど

excludeオプションを使用すると↓
- Jekyllに特定のファイルやディレクトリをビルドプロセスから除外するよう指示できる
- 通常、このオプションは_config.ymlファイルで設定される
*****

## 例：excludeオプションを使用して除外するファイルやディレクトリを指定

```yaml

exclude:
  - Gemfile
  - Gemfile.lock
  - _drafts/
  - _temp/
 ```

- Gemfile、Gemfile.lock、_drafts/、_temp/というファイルやディレクトリがビルドプロセスから除外される
→これらのファイルは最終的なウェブサイトに含まれず、ビルド時に無視される


## まとめ

- excludeオプションは、ウェブサイトのソースディレクトリ内の特定のファイルやディレクトリを制御するために使用される
- Jekyllのビルドプロセスから除外する必要のあるファイルやディレクトリがある場合は、excludeオプションを使用して指定できる
SEO対策 - 最低限押さえておきたい知識

# はじめに
サイトリニューアル後、流入数が激減！
あれ？流入数が減ったみたいだけど、どうしたらいいの？
SEO対策、なにすりゃいいんだ？


１年程前までそんな感じだった私が、流入数を回復するために
爆速でSEOの知識を吸収してきたことをできるだけ噛み砕いて説明をします。

特に下記のような方には為になる記事かと思います。
+ Google検索の仕組みが気になっている方
+ SEO対策したいけど、意識すべきポイントがわからない方
+ SEOへの影響を意識しながら仕様検討したい方

# SEOの基礎知識
SEOとは「Search Engine Optimization」の略で、検索エンジン最適化のことを指します。
これは、ウェブサイトの検索エンジン上での表示順位を上げるための技術や戦略のことです。

# Google検索の仕組み
YahooやBingなど様々な検索エンジンが存在しますが、今回は圧倒的に使用されているGoogleを例にして説明していきたいと思います。
Google検索は、ユーザーが検索したキーワードをもとに、関連性の高いページを検索結果に表示していきます。
ただし、そもそもGoogleがページの情報を保持してもらえなければ、そのページは私達ユーザーの目に触れることはありません。

では、どうやってGoogleにページの情報を保持してもらい、検索結果に表示してもらえるのかを簡単にお伝えしたいと思います。



Googleは「①サイト巡回➝②インデックス➝③検索結果に表示」の流れで、ユーザーのもとにページを提供します。
①サイト巡回
Googleは、（google botとも呼ばれる）クローラーでサイトの情報を収集します。
クローラーは、基本的には毎日巡回していますが、サイトの規模や更新頻度、品質などによっては、クロール頻度が異なる場合があります。

②インデックス
クローラーがサイト内を巡回する中で、発見したページをインデックス（検索エンジンのデータベース保存）するに値するか判定していきます。
ページの品質や信頼性、重要性などを評価し、その結果に基づいてインデックスに含めるページを選択していきます。
インデックスに値すると評価された画面の情報は、ページのコンテンツのみに限らず、画像や動画などのメディアファイルも含まれます。

③検索結果に表示
インデックスされたページから、ユーザーが検索したキーワードと関連性が高いページが検索結果に表示されます。
関連性が低い、またはインデックスのタイミングで評価が低いもののインデックスされた画面は、掲載順位が低く表示されるので、①と②でしっかりとしたSEO対策が必要になります。

以上が、Google検索の仕組みとなります。
仕組みはわかったけど、具体的にどうやって対策すればいいの？と気になった方は、このまま読み続けてください。

# 具体的なSEO対策
ここからは一般的な対策方法を説明していきます。

1. キーワードの適切な使用
キーワードは、検索エンジンで検索される単語やフレーズのことです。
サイトのコンテンツに沿った適切なキーワードを使用することで、検索エンジン上での表示順位を上げることができます。
また、ユーザーニーズの高いキーワードを分析して、使用するとさらなる流入数増加も狙えます。
有料の[Ahrefs](https://ahrefs.com/ja)、[SEMRush](https://semrush.jp/)や無料の[Google Search Console](https://search.google.com/search-console/about?hl=ja)、[Google Trends](https://trends.google.com/trends/?hl=ja)などで分析できます。


2. メタデータの最適化
メタデータは、ページの情報を記述するHTMLタグのことです。（タイトルやディスクリプションなど）
これらを適切に設定することで、検索エンジンがページを正しく理解し、表示順位を上げることができます。
noindexとnofollowをうまく活用すると、サイト全体の評価に貢献できます。
Chrome拡張の[SEO Minion](https://chrome.google.com/webstore/detail/seo-minion/giihipjfimkajhlcilipnjeohabimjhi)などを使うと、現状把握に役立ちます。

3. コンテンツの質の向上
コンテンツの質を向上させることは、SEO対策において非常に重要です。検索エンジンは、ユーザーが有益と感じるコンテンツを優先的に表示するため、質の高いコンテンツを提供することが求められます。
具体的には、E-E-A-Tを意識すると良いと言われてます。
E-E-A-T：「経験（Experience）」「専門性（Expertise）」「権威性（Authoritativeness）」「信頼（Trust）」の略
上記をざっくり説明すると、実際に経験したリアルな情報である、他のサイトで紹介されているページである、ユーザーからのレビューや口コミがサイトに掲載されている、コンテンツにオリジナル性がある等を意識する必要があるということです。
（英文ですが。。。）詳細はこちら：https://static.googleusercontent.com/media/guidelines.raterhub.com/ja//searchqualityevaluatorguidelines.pdf



4. 内部リンクの最適化
内部リンクは、サイト内でのリンクのことです。
内部リンクを最適化することで、サイトの情報構造を明確にし、検索エンジンがページを正しく理解しやすくなります。
ユーザーニーズの高い重要ページを精査して、適切な内部リンクを設置していくことで、重要ページのインデックス数増加を見込めます。
※ SEO対策はユーザビリティとのバランスが重要です。むやみに内部リンクを設置しすぎると、ユーザーを迷わせてしまうこともあるので、注意が必要です。

5. 外部リンクの獲得
外部リンクは、他のサイトから自分のサイトへのリンクのことです。外部リンクを獲得することで、検索エンジンから信頼性や評価を高められます。
外部リンクは、[Google Search Console](https://search.google.com/search-console/about?hl=ja)や[Google Analytics](https://analytics.google.com)などの無料ツールで、どのサイトでリンク設置されているか確認できます。どのページがリンクの対象になっているかも確認できるので、対象ページのコンテンツ拡充するなどの施策を打つことも効果的かと思います。


# まとめ
ざっと説明してきましたが、
まだまだここで説明しきれない対策や定期的な監視方法などもあります。

あくまで基礎知識となっているかと思いますが、
今後の既存サービスの改善、新規機能開発、新規ページ作成、新規サービス立ち上げなどの参考になれば幸いです！
【C#・.NET Framework・WinForms】テキストボックスがフォーカスされていても終了ボタンでフォームを閉じれるようにする

例えば
```Markdown
入力された内容が半角数字のみかどうかを、テキストボックスの `Validating` メソッドで調べたい。
もし、
* 半角数字以外の文字が含まれている
* 未入力
である場合は、テキストボックスにフォーカスを当てたままにする。
```
という実装をするとする。実装すると以下のようになる。

![実装イメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483756/b2fc64a9-690b-6e06-7a60-a0c47fdb3321.gif)

この場合、フォームが未入力な状態で他のボタンを押そうとすると、[フォーカスイベント](https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.forms.control.validating?view=windowsdesktop-7.0)により、フォーカスがボタンに移るより前にテキストボックスの `Validating` メソッドが働いてしまい、別のコントロールに遷移するのはもちろん、ボタンを押すこともできなくなる。

###

では、テキストボックスが不完全 or 未入力な状態であっても、終了ボタンを押したときだけ `Validating` メソッドを無視してフォームを閉じるようにするにはどうすればよいか？ というのが今回の内容です。

# 方法その1：CausesValidationプロパティ
終了ボタン側の `CausesValidation` プロパティを `false` にする。
```C#:C#
// 終了ボタン
ExitFormButton.CausesValidation = false;
```
[CausesValidationプロパティの説明](https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.forms.control.causesvalidation?view=windowsdesktop-7.0)は以下のとおりです。
>そのコントロールが原因で、フォーカスを受け取ると検証が必要なコントロールに対して、検証が実行されるかどうかを示す値を取得または設定します。

そして注釈には
>プロパティが CausesValidation に false設定されている場合、 Validating イベントと Validated イベントは抑制されます。

とあります。

おそらく、`.CausesValidation = false` であるコントロールをフォーカスしようとすると、それまでフォーカスが当たっていたコントロールの `Validating` メソッド、あるいは `Validated` メソッドは無視してフォーカス遷移する、ということかと思われます。

便利なプロパティに思えますが、.NETFrameworkにおけるフォーカスイベントの流れを理解していないと「なんのこっちゃ」となってしまいそうです。

# 方法その2：ActiveControl
`ActiveControl` が終了ボタンに移っているかどうかで処理を分岐させる。
```C#:C#
// テキストボックスのValidatingメソッド
if (this.ActiveControl.Name == ExitFormButton.Name)  // ActiveControlのNameと終了ボタンのNameで判定
{
  // ActiveControlが終了ボタンに移っているためなにもしない
  return;
}
else 
{
  // テキストボックスのValidating処理
}
```
`ActiveControl` はコントロールにフォーカスを当てる機能を提供する `ContainerControl` クラスのプロパティで、現在フォーカスを当てているコントロールの情報を保持しています。

通常のコントロールと同様に `Name` プロパティでコントロール名を取り出せるので、上の例ではコントロール名を条件分岐に用いています。

コントロール名が同じ、つまりアクティブなコントロールが終了ボタンに移っていれば、テキストボックスの `Validating` メソッドの処理内容を無視して終了ボタンにフォーカスする、それ以外は `Validating` メソッドの処理内容を適用する、というかたちです。

コード量はやや多くなりますが、`CausesValidation` プロパティを使う方法に比べてコントロールの機能がわかりやすいのではないかとおもいます。
config.ymlってなに

## config.yml
:::note
Jekyllプロジェクトのルートディレクトリに配置される設定ファイル
Jekyllウェブサイトの動作や外観に関する設定が含まれている
:::

## _config.ymlファイルで可能な設定

- **プロジェクトの基本情報**
ウェブサイトのタイトルや説明、製作者などの基本的な情報を指定

- **ビルド設定**
ウェブサイトをビルドする際の設定を行う
ビルド先のディレクトリ、除外するファイルやディレクトリ、プラグインの有効化などを指定可能

- **テーマの設定**
テーマを使用してウェブサイトの外観を設定できる
（_config.ymlファイルで使用するテーマを指定可能）

- **カスタム変数や設定**
ウェブサイトで使用するカスタム変数や設定を定義できる
テンプレート内で変数を使用して柔軟なコンテンツ生成が可能


*****
- _config.ymlファイルの内容はYAML（YAML Ain't Markup Language）形式で記述
→YAMLは人間に読みやすく、コンピューターにも解析しやすいデータシリアル化形式

- Jekyllは、_config.ymlファイルの設定を読み込んでウェブサイトをビルドする際に使用
ウェブサイトの外観や動作を変更するには、この設定ファイルを編集する
Jekyllとは

## Jekyll
:::note
- 静的なウェブサイトやブログを作成するためのオープンソース（静的サイトジェネレータ）
- Rubyプログラミング言語で開発されている
- MarkdownやHTMLなどのマークアップ言語でコンテンツを記述し、テンプレートや設定ファイルを使ってウェブサイトの外観や構造を管理する
:::

## Jekyllの特徴

- **静的なサイト生成**
動的なデータベースやサーバーサイドスクリプトの使用は不要
**コンテンツファイルやテンプレートから静的なHTMLファイルを生成**
→高速でセキュアなウェブサイトを構築可能

- **マークアップ言語のサポート**
MarkdownやHTMLなどのマークアップ言語をサポート
コンテンツファイルはマークアップ言語で記述され、Jekyllはそれを解析して静的なHTMLファイルに変換

- **テンプレートエンジン**
Liquidと呼ばれるテンプレートエンジンを使用して、ウェブサイトのテンプレートやレイアウトを管理
→共通の要素やレイアウトを再利用したり、動的なコンテンツを組み込んだりできる

- **カスタマイズ可能**
柔軟でカスタマイズ可能な機能を提供
プラグインシステムを使用して機能を追加したり、テーマを変更できる
Docker を基本からまとめてみた【入門】

## Dockerとは？
コンテナ仮想化技術を使って、アプリケーションを開発・配置・実行するための隔離された環境を提供するツール

## コンテナとは？
PCやサーバ上で隔離され、干渉されない環境

## Dockerイメージとは？

##### コンテナの実行環境テンプレート
イメージには、コンテナに必要なソフトウェア・環境変数・設定などが情報で入っている。イメージ＝コンテナの型となるもの。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939638/d0a2359b-f1bc-5a61-c419-4b3a8cb1c5f7.png)

##### 配布＆コンテナ環境の再現が可能
イメージは、変更不可な静的テンプレート。
どの環境で実行しても同じコンテナ環境が再現できる。

## Dockerの基本操作のコマンド

```
//イメージをダウンロードするコマンド
docker image pull [イメージ名] 

//ローカルマシンに存在するイメージ一覧を表示するコマンド
docker image　ls

//ローカルマシンに存在するイメージを削除するコマンド
docker image rm [イメージ名] 

//イメージからコンテナを作成し起動するコマンド
docker container run [イメージ名] 

//ローカルマシンに存在するコンテナ一覧を表示するコマンド
-aオプションをつけることで、起動していないコンテナも表示される
docker container ls

//起動中のコンテナを止めるコマンド
docker container stop

//コンテナを再起動する（Upにする）コマンド
docker container restart

//コンテナを破棄するコマンド
docker container rm [コンテナ名] 
```
## Bashとは？
LinuxやMacなどのUnix系のOSで利用されているシェルの一種

## Ubuntuとは？
Ubuntu とは「誰にでも使いやすいOS」をコンセプトに開発されたLinux 系のOS で、Linux 系とはLinux をベースにして作られたOS のことで、Linux ディストリビュージョンを指す。

```
//標準入力がOPENになる
docker container run -i ubuntu

//イメージの詳細情報を表示するコマンド
docker image inspect [イメージ名]

//コンテナを起動して任意のコマンドを実行させるコマンド
docker container run　[イメージ名][実行したいコマンド 例：ls]

//イメージからコンテナを新規作成し、コマンドを実行する
docker container run　-it[イメージ名][実行したいコマンド 例：ls]

//Up状態のコンテナに任意のコマンドを実行させるコマンド
docker container exec　[コンテナ名][実行したいコマンド 例：ls]

//既存のコンテナで、コマンドを実行する
docker container exec　-it[コンテナ名][実行したいコマンド 例：ls]

//既存のコンテナ名を変更する
docker container run --name[コンテナ名]

//停止済みのコマンドを全て削除するコマンド
docker container prune

//--rm オプションをつけるとコンテナ実行した後自動削除する
docker container run　--rm[イメージ名]

//-f オプションをつけると動作中のコンテナも強制削除する
docker container run rm -f[イメージ名]

//-dをつけると、デタッチドモードでコンテナを起動する
//※何もつけないと、フォアグラウンドモードでコンテナを起動する
docker container run　-d [イメージ名][実行したいコマンド 例：ls]
docker container exec　-d [コンテナ名][実行したいコマンド 例：ls]

//デタッチドモードになっているコンテナに接続するコマンド
docker container attach [コンテナ名]

```



## 参考サイト
[初心者OK！Docker入門＋応用：ゼロからでも実務で使えるスキルが身に付ける](https://itplusjp.udemy.com/course/ok-docker/learn/lecture/36659198#overview)
[A Beginner’s Guide to Understanding and Building Docker Images](https://jfrog.com/devops-tools/article/understanding-and-building-docker-images/)
[Ubuntuとは？｜たった3分で分かる｜特徴やできることをわかりやすく解説](https://techmania.jp/blog/linux0002/#:~:text=Ubuntu%20%E3%81%A8%E3%81%AF%E3%80%8C%E8%AA%B0%E3%81%AB,%E3%83%87%E3%82%A3%E3%82%B9%E3%83%88%E3%83%AA%E3%83%93%E3%83%A5%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%82%92%E6%8C%87%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)