OmniAICreator/Qiita-1.07M huggingface dataset:
TauriにVueフレームワークのNuxt3を導入するまで（ついでにTailwindcssとRome）_ビルド編

## はじめに

前回の続き↓

https://qiita.com/GreenTea25/items/3a6311977d0e4d4d046d


前回の記事に記載し忘れた、環境・ツール等バージョンは以下の通り。(2023/5/14時点)
os：Windows 11
Rust：1.69.0
Node.js：18.15.0
yarn：1.22.19
tauri-cli：1.3.0

## ビルド実行
`yarn tauri build`でビルドを実行する。

``` bash
$ yarn tauri build

---省略---

   Compiling webview2-com v0.19.1
    Finished release [optimized] target(s) in 3m 24s
        Info Target: x64
     Running candle for "main.wxs"
     Running light to produce

--省略---

Done in 248.60s.

```

ビルドが成功したら「src-tauri\target\release」ディレクトリに生成された「tauri-nuxt3-tailwind-rome-template.exe」ファイルを実行


![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3387154/640f37ca-61c2-7f30-1012-1bbfd938dec3.png)


「tauri.localhost により、接続が拒否されました。」と出てしまう。


一旦`yarn tauri build --debug`でデバッグモードで起動してみると「Asset \`index.html` not found; fallback to index.html.html」の出力が。
index.htmlが見つからないとのことなので「"distDir": "../dist"」が指し示すディレクトリを確認したところindex.htmlは存在しない。

<br>

ではnuxtのビルド設定が良くないのか？と思いしばらく調べていたところ解決策が見つかった。

https://blog.mktia.com/diffrences-between-build-and-generate-in-nuxt/

<br>

上記の記事によると「nuxt.config.ts」で「ssr:false」に設定したため`nuxt build`ではなく`nuxt generate`を使うべきとの話。


なのでtauriのビルド前に実行されるコマンドを`yarn build`から`yarn generate`に変更。

```diff: tauri.config.json
{
  "build": {
    "beforeDevCommand": "yarn dev",
-   "beforeBuildCommand": "yarn build",
+   "beforeBuildCommand": "yarn generate", //buildからgenerateに変更
    "devPath": "http://localhost:3000",
    "distDir": "../dist",
    "withGlobalTauri": true
  },

---省略---
```

<br>

もう一度ビルドを実行し起動してみる。

![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3387154/7e780501-a6ad-b989-a656-8ac2a8e20981.png)


出来た！


## 終わりに

今回のテンプレート↓
[tauri-nuxt3-tailwind-rome-template](https://github.com/MHMami25/tauri-nuxt3-tailwind-rome-template)
今更ながら、ゼロからのAWS学習

# はじめに
　2006年にAmazon Web Serviceがサービス提供され、稼げる[IT資格](https://www.korekara-freelance.com/paying-certifications/1816/)として２位になっています。私の職場でも必要な知識となってきており、いよいよ学習しなくてはいけないという雰囲気になってきました。
　なお、１位はGoogleCloud認定資格になっていますが、普及率が低い中でどうしてもGoogleCloudPlattform（GCP）でなければ要件を満たせないような技術者での争いと想定でき、日本で働くうえでは、一旦そこまで手を伸ばさなくても良いという雰囲気があります。

# 目標
　以下のAWS認定資格を目指します。情報処理技術者試験に比べて価格が高いのと定期的な更新が必要となるため、デメリットと呼べるような部分もありますが、前段のランキングにもありましたように既に稼げる能力として多くの企業から評価されています。まずは、現職を含めアーキテクチャの理解が必要であるため以下の図の**ボールド**で表示した資格から取得したいと考えています。
![資格構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423321/927efdc8-2954-824a-7205-334372af4915.png)
　とりあえずは、令和５年で**１）ソリューションアーキテクトアソシエイト**、**２）ソリューションアーキテクトプロフェッショナル**の２つを取得する予定です。

# 参考サイト
|No|サイト|概要|追加日付|
|----|----|----|----|
|1|[AWSトレーニングと認定](https://www.aws.training/)|Amazonが無料、有料で準備するトレーニングサイトで非常によくできていてわかりやすいです。Amazonは、Googleとかと比べるとこの辺りが流石だなと思わせてくれます。|2023/01/08|
|2|[AWSドキュメント](https://aws.amazon.com/jp/documentation/)|Amazonの公式ドキュメント（英語版）|2023/1/14|
|3|[AWSクラウドサービス活用資料集](https://aws.amazon.com/jp/aws-jp-introduction/)|AWS Summit等の動画アーカイブがたくさん保存されている。AWSのポートフォリオを理解できる。|2023/1/15|
|4|[AWS スキルビルダー](https://aws.amazon.com/jp/training/course-descriptions/)|無料の学習コンテンツ、ハンズオン等をアカウント単位で進捗含めて管理ができます。|2023/1/15|
|5|[ICTスキル総合習得プログラム](https://www.soumu.go.jp/ict_skill/)|総務省が提供するデータ収集から活用までの一連の技術が記載されている|2023/1/15|
|6|[AWS スキルビルダー](https://aws.amazon.com/jp/training/course-descriptions/)|無料の学習コンテンツ、ハンズオン等をアカウント単位で進捗含めて管理ができます。|2023/1/15|
|7|[OpenStack](https://docs.openstack.org/arch-design/design.html)|OpenStackは、オープンソースのクラウドソフトウエアを指し、IaaSでのサービス提供も行っている|2023/1/15|
|8|[ホワイトペーパー](https://aws.amazon.com/jp/whitepapers/)|AWS上で環境構築するためのベストプラクティス集|2023/1/28|
|9|[ハンズオン](https://aws.amazon.com/jp/events/aws-event-resource/hands-on/)|ハンズオンチュートリアル|2023/1/28|

# 参考書
|No|参考書|概要|追加日付|
|----|----|----|----|
|1|Amazon Web Services 基礎からのネットワーク＆サーバー構築|AWSの無料範囲でサービスを構築するための手順が書かれています。ハンズオンの資料としてはわかりやすいです。ただ、現在はyoutube等にも同様の内容が無料で公開されています。|2023/1/15|
|2|AWS認定ソリューションアーキテクト[アソシエイト]|AWS認定ソリューションアーキテクトアソシエイトのための参考書です。ある程度の知識があれば恐らくサービス内容さえ覚えれば合格できるような内容です。|2023/1/15|
|3|AWSの基本・仕組み・重要用語が全部わかる教科書|AWSのマネージドサービスについて平易な言葉で記載されており非常にわかりやすい。|2023/1/15|
SpringDataJPAお試し

# JPA
Java標準のORM（Object-Relational Mapping）。
# Spring Data JPA
データストアに対するアクセスを抽象化したライブラリであるSpring Dataのサブプロジェクトであり、JPAを更に便利にした機能をもち、コードの書きやすさ、管理がしやすくなる。

# メリット
* SQLを記載しないで、DBとオブジェクトを連携できる。【JPA】
* DBを扱う上で重要となる排他制御についてサポートされている【JPA】
* JPAの機能を使用したデータベースアクセスのソースコードの書きやすさや管理のしやすさを実現【Spring Data JPA】

# 使用してみた
Hibernate（JPAの実装の１つ、SpringでJPAを利用する場合、HibernateがJPAのデフォルト実装として選択される。）を活用し、データアクセスを実装する。

* java Object
~~~ java
@Entity(name="m_item")
public class Item{

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long ItemId;
  private String itemName;
  private String itemCategory;
}
~~~
@Entity :Entityクラスを示し、name属性に実際に対応するテーブル名を指定する。

@Id:キー値(ID)となる項目に指定する。

@GeneratedValue:ID生成方針を定義する。GeneratedType.IDENTITYは、キー値生成をDBの機能で行う。(MYSQLではauto_incrementに対応する)

* インターフェース

インターフェースを定義するだけで、あらかじめ用意されたデータ操作を行うことができる。

~~~ java
@Respsitory
public interface ItemRepository extends CrudRepository<Item, Long>{

}
~~~

@Repository:DBアクセスを行うことを示す。

@CrudRepository:エンティティクラスと、IDを指定することで、CRUD機能を実装する。

Interfaceクラスだけを定義。実装クラスは不要。

* Serviceクラス

~~~ java
@Service
public class ItemService{
  @Autowired
  private ItemRepository itemRepositoty;
  
  public list<Item> getAllItems(){
    List<item> allItems = new ArrayList<>();
    itemRepository.findAll().forEach(allItems::add);
    
    return allItems;
  }
}
~~~

@Serviceクラスで@Repository付与のインターフェースクラスを@Autowiredをつけてそのまま利用する。

CrudRepositotyで使用できるメソッドを利用。

> * save : 指定したエンティティを登録する。
> * findById(id) :　キー値を指定すると、指定されたエンティティを検索する。
> * findAll : 対応するテーブルの全件を検索する。
> * deleteById(id) : 指定されたキー値のデータを削除する。
【Android】アニメーションを同時に行う【kotlin】

# AnimatorSet()
AnimatorSet()を使いことでいくつかのアニメーションを同時に、または順番に動かすことができます。



# 同時に動かす
同時に動かす方法は2種類あります。

```
val textView = findViewById<TextView>(R.id.text_view)
val animator = AnimatorSet()

val rotationAnimator = ObjectAnimator.ofFloat(textView, "rotation", 0f, 180f)
val translationYAnimator = ObjectAnimator.ofFloat(textView, "y", 300f, -1000f)

```
まずは　それぞれ使いやすいように変数化し
通常のアニメーションをするように
```
animator.play(rotationAnimator)
animator.start()
```
とすると　textViewが１８０度回転するアニメーションを行うことができます。
そこに　__.with()__　を.play()の後に追加し、引数に同時に動かしたいアニメーションを追加することで同時に動かすことができます。
```
animator.play(rotationAnimator).with(translationYAnimator)
animator.start()
```

２つ目の方法は　__.playTogether()__　を使い方法です。
第一引数と第二引数に同時に動かしたいアニメーションをそれぞれ追加するだけです。
```
animator.playTogether(
        rotationAnimator, translationYAnimator
        )
animator.start()
```

これで縦に回転しながら縦に移動するアニメーションをViewに加えることができました。
Power Apps で最初に表示される画面を動的に切り替える


# はじめに

例えば、以下のような申請をするアプリにて、承認依頼が承認者に飛んで来て、リンクをクリックすると、アプリのトップ画面ではなく、該当の申請の詳細が表示されると楽と思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/1ffa37d1-8742-4c3e-c550-761fbd34b636.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/11adf6a9-466a-427c-d370-d7a5f58f9062.png)

色々紹介されているとは思うのですが、先日聞かれたので改めてブログに書こうと思います。

# Power Apps 側

まず、App の`[Onstart]`に以下の処理を追加します。

```
If(
    !IsBlank(Param("review")),
    Set(
        gblReviewID,
        Value(Param("review"))
    );
    
);


``` 

ここで言う param は、URL のパラメーターを意味します。
実は、Power Apps では、以下のような感じで、アプリの URL の最後にパラメーターを付与し、アプリ側では、param 関数でその値を受け取ることが出来ます。

```
https://apps.powerapps.com/play/e/*****?tenantId=*****&パラメーター名=値
```

つまり、上記 App の`[Onstart]`で review というパラメーターが存在する場合は、変数に格納しています。

:::note warn
`[Onstart]`が見当たらない場合は、以下の設定を確認し、オンにします。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/64b50571-a2c3-46c9-7421-7d411c0c211a.png)

今回の方法で上手く画面が遷移しない場合や、`[Onstart]`で実行する処理の後に実行したい処理があるものの、そちらの処理が先に実行されてしまうことで動作がおかしくなる場合は、以下の設定をオフ (既定オン) にしてみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/ff06e6ad-57e6-a9f3-8acd-b7746852ae9c.png)


:::

更に、App の`[StartScreen]`に以下の処理を追加します。もし、review というパラメーターが存在する場合は別の画面を表示するようにしています。

```
If(
    IsBlank(Param("review")),
    ScreenTop,
    ScreenViewDetail
)
```

そして、最後に、別画面の方のフォームコントロールの `[Items]`プロパティに以下を追加します。表示したいアイテムの ID、つまり、承認したいアイテムの ID の行を表示する感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/16fd861c-bb38-4ea9-ceb9-0ddf00523fa2.png)

```
LookUp(
    休暇申請リスト,
    ID = gblReviewID
)
```

# Power Automate 側

Power Automate 側は以下のような感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/399ace14-72ec-d493-449c-9c5718416fa4.png)

アプリの URL の最後に以下のような感じで、review=承認対象の Item の ID を入れます。承認者は、この URL からアプリを起動することで、上記 Power Apps の設定より、承認対象のアイテムを直接開くことが可能になります。

```
review=@{outputs('項目の更新')?['body/ID']}
```

# まとめ

URL パラメーターを利用することで、Power Apps で最初に表示される画面を動的に切り替える方法を紹介しました。例に書いたような承認ワークフローなど、知っておくと便利なので参考になれば幸いです。
MQTTを使ってみる

# MQTTを試す方法
1. MQTTブローカーをInstallする。[Mosquitto](https://mosquitto.org/download/)からexeをInstall
1. ブローカーの開始。"c:\Program Files\mosquitto\mosquitto.exe" -v
1. PublishとSubscribeのコードを実行する
以上。



# コード
Publish用のコード
```python:pub.py

import paho.mqtt.client as mqtt     # MQTTのライブラリをインポート
from time import sleep              # 3秒間のウェイトのために使う

# ブローカーに接続できたときの処理
def on_connect(client, userdata, flag, rc):
  print("Connected with result code " + str(rc))

# ブローカーが切断したときの処理
def on_disconnect(client, userdata, rc):
  if rc != 0:
     print("Unexpected disconnection.")

# publishが完了したときの処理
def on_publish(client, userdata, mid):
  print("publish: {0}".format(mid))

# メイン関数   この関数は末尾のif文から呼び出される
def main():
  client = mqtt.Client()                 # クラスのインスタンス(実体)の作成
  client.on_connect = on_connect         # 接続時のコールバック関数を登録
  client.on_disconnect = on_disconnect   # 切断時のコールバックを登録
  client.on_publish = on_publish         # メッセージ送信時のコールバック

  client.connect("localhost", 1883, 60)  # 接続先は自分自身
 
  # 通信処理スタート
  client.loop_start()    # subはloop_forever()だが，pubはloop_start()で起動だけさせる

  # 永久に繰り返す
  num = 0
  while True:
    client.publish("drone/001","Hello, Drone" + str(num))    # トピック名とメッセージを決めて送信
    sleep(3)   # 3秒待つ
    num+=1

if __name__ == '__main__':          
  main()  
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680528/9ebccca3-174a-381e-e520-8d4e4723e227.png)


Subsclibe用のコード
```python:sub.py

import paho.mqtt.client as mqtt     # MQTTのライブラリをインポート
 
# ブローカーに接続できたときの処理
def on_connect(client, userdata, flag, rc):
  print("Connected with result code " + str(rc))  # 接続できた旨表示
  client.subscribe("drone/001")  # subするトピックを設定 

# ブローカーが切断したときの処理
def on_disconnect(client, userdata, rc):
  if  rc != 0:
    print("Unexpected disconnection.")

# メッセージが届いたときの処理
def on_message(client, userdata, msg):
  # msg.topicにトピック名が，msg.payloadに届いたデータ本体が入っている
  print("Received message '" + str(msg.payload) + "' on topic '" + msg.topic + "' with QoS " + str(msg.qos))

# MQTTの接続設定
client = mqtt.Client()                 # クラスのインスタンス(実体)の作成
client.on_connect = on_connect         # 接続時のコールバック関数を登録
client.on_disconnect = on_disconnect   # 切断時のコールバックを登録
client.on_message = on_message         # メッセージ到着時のコールバック
 
client.connect("localhost", 1883, 60)  # 接続先は自分自身
 
client.loop_forever()                  # 永久ループして待ち続ける
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680528/37b6d4e6-3437-97e9-cd7d-63df29f094f4.png)

ブローカー上
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680528/53da2a77-d4fc-5c98-3e5e-4fbd4354817b.png)


# 参考
[参考①](https://happy-nap.hatenablog.com/entry/2022/07/08/173750)
[参考②](https://qiita.com/emqx_japan/items/b63c918fe137a6db4b37)
Batchでディレクトリ名を付加してリネームする

# 目的
ディレクトリ「hogehoge」配下にあるファイル
・001.log
・002.log
・003.log
上記を
・<font color="red">hogehoge_</font>001.log
・<font color="red">hogehoge_</font>002.log
・<font color="red">hogehoge_</font>003.log
こうする

# どんな時に使うか？
ログファイルを格納する際
*LogDirectory*
　┗YYYYMM┳DD.log　　--01.log
　　　　　　┗DD.log　　--02.log
➔こんな構成で、検証目的でコピー。後から参照しようとしたら「何月何日」のファイルなのかがわからなくなったりする。
~~コピーした後即リネームしておけばいい話ではあるが~~
➔プロジェクトの仕様変更で「やっぱりログは１つのディレクトリに管理してリネームもしてくれ、過去の奴もな」と要望が出されたりする
~~仕事上本当に遭遇して、地獄を見た事がある~~

```batch:Rename.bat
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

REM カレントディレクトリフルパス
SET DIRECTORY_PATH=%~dp0
REM Batchファイル名(ファイル名+拡張子)
SET SELF_FILE=%~nx0

REM ディレクトリの名前だけ取る
FOR %%i IN ("%DIRECTORY_PATH:~0,-1%") DO SET THIS_DIRECTORY=%%~ni

REM ファイル巡回
FOR %%F IN ( * ) DO (
    REM 自身を除いたファイルに対してリネーム実行
	IF NOT %%F==%SELF_FILE% (
		SET OLD_NAME=%%F
		SET NEW_NAME=%THIS_DIRECTORY%_%%F
		RENAME !OLD_NAME! !NEW_NAME!
	)
)

ENDLOCAL
```
 

# 参考にした記事(マジで助かりました)
https://qiita.com/kaorikatakura/items/69d50a920caf7ada3004

https://417.run/pg/get_this_dir_bat/

https://correct-log.com/bat_get_cd/

https://qiita.com/n-nabe/items/b54bab5e03f9ce04ede6
Stable Animation SDKで簡単なアニメーションを作ってみた

# はじめに
2023年5月12日の[記事](https://gigazine.net/news/20230512-stability-ai-stable-animation-sdk/)でStable Animation SDKがリリースされたことを知り面白そうだと思い、早速アニメーションを作成してみることにしました。

# 簡単なアニメーションの作成
[こちらの記事](https://note.com/ri___note/n/n5a7bb1614a6a)を参考にgoogle cobabとDreamStudioに登録し、Stable Animation UIにアクセスしました。今回はAnimation promptsに↓を入力し（Animation prompts以外の設定はデフォルトのまま）、その後Renderボタンを押下するとアニメーションの自動生成が始まりました。

```
    0: "An oil painting of a cat by Leonardo da Vinci, highly-detailed, dramatic lighting",
    24: "An oil painting of a dog by Leonardo da Vinci, highly-detailed, dramatic lighting",
```

![promts.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3382528/4bc0c160-034e-7f59-cdba-5fb29c290c5b.png)

# 実際に作成したアニメーション
猫の油絵から犬の油絵に変化するアニメーションです！
![cat-animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3382528/8d0d4f8d-c49d-e198-ba7e-2fbe0b8f111c.gif)

# おわりに
今回はAnimation promptsのみを記載して、その他の設定は何もいじらずに自動生成しているので、他の設定を理解して弄った際にどのようにアニメーションが生成されるのか非常に気になるなと感じました。
また、プロントエンジニアリングについてあまりイメージできていない状態だったので、[こちらの記事](https://dreamstudio.ai/prompt-guide)で勉強しました。
もっとプロントエンジニアリングについて理解できると作成できるアニメーションの幅も広がってきそうです。
さらに、自動生成しては微修正して再度自動生成する等をしているとDreamStudioのクレジットが必要になってくるので、頻繁に自動生成するのはなかなか難しいのかなと個人的に感じました(^^;

# 参考記事

https://gigazine.net/news/20230512-stability-ai-stable-animation-sdk

https://note.com/ri___note/n/n5a7bb1614a6a

https://dreamstudio.ai/prompt-guide
【Vue3 / Vite】Markdownファイルをコンポーネントにインポート/表示する方法 vite-plugin-vue-markdown

Vue3 + Viteで、コンポーネントからMarkdownファイルをインポートして表示する手順を紹介します。

まず、MarkdownをHTMLに変換するモジュールとして[marked](https://www.npmjs.com/package/marked)をインストールします。
~~~bash
npm install marked
~~~
インストールが完了したら、以下のようなコンポーネントを作成します。
~~~vue
<script setup>
import { computed, ref } from 'vue'
import { marked } from "marked"

const markdown = ref("# Hello World!");

const parsedMarkdown = computed(() => {
  return marked(markdown.value);
});
</script>

<template>
  <div v-html="parsedMarkdown"/>
</template>
~~~
Markdownをそのまま文字列として変数として定義して、それをモジュール`marked`でパースしたものを画面に表示するといった感じです。
では、同じディレクトリに以下のようなMarkdownファイルを作成して、それを読み込み、表示する形に変更しましょう。
~~~markdown:some-markdown.md
# Hello World!
~~~
~~~vue
<script setup>
import { computed, ref } from 'vue'
import { marked } from "marked"
import someMarkdown from "./some-markdown.md";

const parsedMarkdown = computed(() => {
  return marked(someMarkdown);
});
</script>

<template>
  <div v-html="parsedMarkdown"/>
</template>
~~~
上記の実装では、以下のようなエラーが発生して画面が表示されなくなります。
~~~
Uncaught SyntaxError: Invalid or unexpected token
~~~
まずは、コンポーネントにMarkdownを取り込むのに使用するモジュール[`vite-plugin-vue-markdown`](https://github.com/mdit-vue/vite-plugin-vue-markdown)をインストールします。`vite-plugin-vue-markdown`は、Markdownファイルをロードして、そのままコンポーネントとして使用することができるモジュールです、
~~~bash
npm i vite-plugin-vue-markdown -D
~~~
ルートディレクトリにある`vite.config.js`を以下のように編集します。
~~~diff_javascript:vite.config.js
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import Markdown from "vite-plugin-vue-markdown";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue({
      include: [/\.vue$/, /\.md$/],
    }),
    Markdown()
  ],
});
~~~
これでViteの設定は完了です。コンポーネントを以下のように編集しましょう。
~~~vue
<script setup>
import SomeMarkdown from "./some-markdown.md";
</script>

<template>
  <SomeMarkdown/>
</template>
~~~
画面を再度確認してみると、問題なく外部のMarkdownファイルが読み込まれ、HTMLとして表示されていると思います！
[こちらの記事](https://qiita.com/whopper1962/items/ddc2613c07bf3bbe5f8c)でVue2でコンポーネントにMarkdownファイルを取り込む方法を紹介していますが、Vue3ではVue2では必要だったMarkdownをHTMLに変換する処理が必要ないので、記述量も少なくより分かりやすい見た目になっています。
Google Sitesを使いHP作成する

スクレイピングした店舗情報を、Googleマップにインポートし、HP上に公開しました。
初めてのHP作成で、Google Sitesを使用しました。備忘録です。
スクレイピングの備忘録は、過去に記事を投稿していますが、スクレイプに使ったコードは [GitHub](https://github.com/yukimatsuno/personalProject/tree/main)にもおいています。
作成したHPはこちら：[コスパ101](https://www.cospa101.com/)

## Google Sitesとは
無料のウェブサイト作成ツール。直感的なインターフェースとGoogle製品との連携が特徴で、誰でも簡単にノンコードでウェブサイトを作成できる。

## 作り方

[Google Sites](https://sites.google.com/)から作成する。テンプレートも利用可。
ページは非常に簡単に、直感的に作ることが可能。ここでは詳細は割愛する。

## HPを公開する
##### ドメイン購入
[お名前.com](https://onamae.com/)や、海外サイトだと[namecheap](https://www.namecheap.com/)などで購入できる。

##### HP公開
HPの内容が出来たらHPを公開する。Google Sites右上歯車の「設定」をクリック > 「カスタムドメイン」タブの「スタートセットアップ」をクリック 
![startSetup.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190318/2d006e93-cc9b-32b1-9ccc-5d035fca8abb.jpeg)

既にドメインを購入済みなので「サードパーティのドメインを使用する」をクリック。（「ドメインを購入」を選択すると、Google Domainに進みドメインを購入することが出来る。） 
![setUpDomain.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190318/cb3b1b20-4943-2e7d-42e8-4e895b00c183.jpeg)

次のページで購入しておいたドメインを入力 >「所有権を認証」をクリック。
![domainThirdParty.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190318/a443bad0-f6af-2057-d73c-1cb49348807a.jpeg)

(1)「TXT（推奨）」を選ぶ
(2)ドメインを購入したサイト(ドメインレジストラ)にログイン
(3)ドメインを購入したサイトにて、DNS設定ページよりレコードを追加する
(4)Google Sitesに戻り、「認証」をクリック
![Untitled.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190318/12288a15-c5a8-3ff9-ff2b-75115bbca653.jpeg)

下記画像は(3)が済んだ、ドメインを購入したサイトのページ
![DNS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190318/b4092266-f95b-1040-e0b1-3d7787e90892.jpeg)

Google Sitesの指示に従い、
(1)ドメインを購入したサイトにてCNAMEの行き先に「ghs.googlehosted.com.」を入力、保存
(2)Google Sitesに戻りDoneをクリック
![cname.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190318/4ae0847a-b2e7-5c7f-d29f-d0d27030eac8.jpeg)

ドメインが接続されました。
次にGoogle Sites右上の「公開」をクリック
![setting.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190318/7c581f19-c2fb-cb67-9896-ebc16d71f191.jpeg)

使いたいURLを入力し、「公開」をクリック
![publish.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190318/a4703026-b132-90bd-d27d-8d1e8aad25ac.jpeg)

HPが公開されました。
ブラウザに上記で入力したURL https://www.cospa101.com を入れ、Enterキーを押すと、HPが表示されました。
![Untitled 2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3190318/ef7f7db6-b1e4-3e97-b6db-dde68922b9e3.jpeg)

:::note info
ネイキッドドメイン（「www.」なし）の設定
1. Google Sitesでは、リダイレクトを設定する方法しかない。redirect.pizzaなどのサイトを利用すると良い。


## 最後に
初めてHPを作成したが、ノンコードで簡単に作ることが出来た。ただ、ノンコードとはいえ、ドメインの取得、DNS設定など要所要所で学ぶことがあった。普段の学習では触れることのない分野や新しい情報が入ってくるので、このHP作成は引き続き取り組んでいきたい。今後は、サイトの訪問者分析にも手を広げられたら良いと思う。

## 追記
[Googleアナリティクス](https://support.google.com/sites/answer/97459?hl=ja)というものを使えば、作成したHPを分析出来る。
【Vue2】Markdownファイルをコンポーネントにインポート/表示する方法

Vue2で、コンポーネントからマークダウンファイルをインポートして表示する手順を紹介します。

まず、マークダウンをHTMLに変換するモジュールとして[marked](https://www.npmjs.com/package/marked)をインストールします。
~~~bash
npm install marked
~~~
インストールが完了したら、以下のようなコンポーネントを作成します。
~~~vue
<template>
  <div v-html="parsedMarkdown"></div>
</template>

<script>
import { marked } from "marked";

export default {
  data() {
    return {
      markdown: "# Hello World!",
    };
  },
  computed: {
    parsedMarkdown() {
      return marked(this.markdown);
    },
  },
};
</script>
~~~
マークダウンをそのまま文字列として`data`に置き、それをモジュール`marked`でパースしたものを画面に表示するといった感じです。
では、同じディレクトリに以下のようなマークダウンファイルを作成して、それを読み込む形に変更しましょう。
~~~markdown:some-markdown.md
# Hello World!
~~~
~~~vue
<template>
  <div v-html="parsedMarkdown"></div>
</template>

<script>
import { marked } from "marked";
import someMarkdown from "./some-markdown.md"

export default {
  data() {
    return {
      markdown: "# Hello World!",
    };
  },
  created () {
    this.markdown = someMarkdown;
  },
  computed: {
    parsedMarkdown() {
      return marked(this.markdown);
    },
  },
};
</script>
~~~
おそらく、以下のようなコンパイルエラーが発生します。これはWebpackがマークダウンをモジュールとして読み込む設定がされていないことによるエラーです。
~~~
Module parse failed: Unexpected character '#'
~~~
まずは、インポートに使用するモジュール[`raw-loader`](https://www.npmjs.com/package/raw-loader)をインストールします。`raw-loader`は、Webpackがファイルを文字列としてインポートすることができるようにするモジュールです。
~~~bash
npm install raw-loader
~~~
Vueのルートディレクトリにある`vue.config.js`を以下のように編集します。
`configureWebpack`は、Webpackに関する設定を行うオプションで、その中で、拡張子が`.md`のものに関してはモジュール`raw-loader`を使用してデータをロードするように設定します。
~~~diff_javascript
const { defineConfig } = require("@vue/cli-service");
module.exports = defineConfig({
  transpileDependencies: true,
  configureWebpack: {
    module: {
      rules: [
        {
          test: /\.md$/i,
          loader: "raw-loader",
        },
      ],
    },
  },
});
~~~
`vue.config.js`は開発サーバー起動時に読み込まれるので、サーバーを再起動して設定を読み込ませてください。
問題なく外部のマークダウンファイルが読み込まれ、HTMLが表示されていれば完成です！
Pythonを使ったAIモデルの構築に必要なスキルと手法

　AI技術は今日の社会でますます重要な役割を果たしています。Pythonはその中心で、AIモデルを構築する際に必須となるスキルの多くにおいて主要な役割を果たします。この記事では、Pythonを使ってAIモデルを構築するために必要なスキルとそのスキルを身につけるための手法や技術について解説します。自分自身が独学でPythonを学び、業務で活用できるようになるまでの経歴について詳しく語った記事もありますので、ぜひ[こちら](https://qiita.com/yutut/items/c55e7a9fcb514f624172)もご覧ください。

# 1. Pythonプログラミング
　AIモデルの構築にはPythonが主要な言語として使用されます。NumPy、Pandas、Matplotlibなどのライブラリの理解が不可欠です。これらのライブラリはデータ分析やデータ前処理に使われ、Pythonの強力なツールセットの一部を形成します。

# 2. 基本的な統計知識
　AIや機械学習のモデルは、その根底に統計を持っています。確率、回帰、最尤推定などの基本的な統計学の理解は、これらのモデルがどのように動作し、なぜそのように動作するのかを理解するのに重要です。

# 3. 機械学習
　Scikit-learnなどの機械学習ライブラリを使い、[線形回帰](https://qiita.com/yutut/items/36bd64f8123350259572)、[ロジスティック回帰](https://qiita.com/yutut/items/654f34023a57aec344d6)、[サポートベクターマシン](https://qiita.com/yutut/items/1a14e9aa83f5bff14e0e)、[決定木](https://qiita.com/yutut/items/42454108cc5325966f84)、[ランダムフォレスト](https://qiita.com/yutut/items/37a6cac9070861a120e1)などの基本的な機械学習アルゴリズムに精通することが必要です。

# 4. ディープラーニング
　TensorFlow、Keras、またはPyTorchなどのフレームワークを使い、[ニューラルネットワーク](https://qiita.com/yutut/items/805976280bfed8761aa5)、畳み込みニューラルネットワーク（CNN）、リカレントニューラルネットワーク（RNN）などのディープラーニングアーキテクチャを理解し、適用できるようにすることが求められます。

# 5. 自然言語処理（NLP）
　BERT、[GPT](https://qiita.com/yutut/items/e9e013875ceb2893d7d6)、RoBERTaなどの最新のなどの理解が重要です。これらのモデルを扱うためには、Hugging FaceのTransformersライブラリが便利です。

# 6. コンピュータビジョン
　画像認識、物体検出、セマンティックセグメンテーションなどのタスクを理解し、OpenCV、PIL、Skimageなどのライブラリを使って実装できるようにすることが必要です。

# 7. データエンジニアリング
　大規模なデータセットを取り扱う能力は、AIモデル構築において重要です。SQL、Apache Spark、Hadoop、Pandasなどのデータベースとデータ処理ツールを使えるようになる必要があります。

# 8. ソフトウェアエンジニアリングとシステムデザイン
　[バージョン管理（Git）](https://qiita.com/yutut/items/2842046f78459ecea760)、テスト駆動開発、コンテナ技術（Docker、Kubernetes）、クラウドコンピューティングプラットフォーム（AWS、GCP、Azure）などの基本原則を理解し、適用する能力は必要です。

# 9. 機械学習ライフサイクル管理
　機械学習プロジェクトのライフサイクルを管理するためのツール（MLflowやKubeflowなど）を使えるようにすることが重要です。

# 10. 倫理と法律
　AI技術が引き起こす可能性のある社会的、倫理的な問題や、データプライバシー、著作権などに関する法律について理解することも必要です。

# 　まとめ
　AIモデルを構築するために必要なスキルは多岐にわたります。これらを独学で学び、Pythonを業務で活用するまでには時間と努力が必要ですが、その成果は非常に価値があります。また、これらのスキルを持つことで、自分のキャリアに新たな可能性をもたらすことができます。これらのスキルを取得するための詳細な経緯と経験については、[こちらの記事](https://qiita.com/yutut/items/c55e7a9fcb514f624172)でも詳しく説明しています。今日からPythonのを始めて、あなたのAIの未来を創造しまし






# 最後に
　私の経歴については **[こちらのページ](https://qiita.com/yutut/items/c55e7a9fcb514f624172)** で詳しく説明しています。Python初学者が独学で勉強をする際に参考になると思います。自身のスキルアップに役立てていただければ幸いです。そして、これらのスキルを駆使して、あなた自身がAIを活用したビジネスを展開する日を楽しみにしています。

あなたの**AI活用の旅**が成功することを祈っています。今後ともよろしくお願いいたします。
【GCP】GWにGCP資格1日で2つ受けてみた(GCP CDL, PCA)

前回、GCP ACEを取得した際の記事で
``` 次回はCDLかPCAを受験したいと思う。```
と書きましたが、どうせなら同時に受けてしまえということで1日で2試験受けてみました。

https://qiita.com/kei1-dev/items/24187af04e5c4f6ff712

## 前提
- 7年目エンジニア
- アプリケーション開発メイン
- AWS全冠
- GCPは業務経験なし
    - ACE資格を先月取得

## 試験結果
- 受験日: 2023/05/07
- 試験結果: CDL, PCA どちらも合格

## 試験感想
- 難易度はCDLはAWS　CLFとほぼ同等くらい、PCAはAWS　SAPより簡単だと個人的に思いました。
- ACEと同じく、コンテナやKubernatesの知識は前提として必要。
- CDLはほぼ勉強しませんでしたが、大丈夫でした。
- 特にPCAはクラウド上のベストプラクティスに関する問題が主なので、AWSで各種資格を取得している人にとってはAWSのサービスと対応ができていれば解ける問題も多いと感じた。（もしかしたらACEより簡単に感じるかも）
- 試験では相変わらず日本語で受けたが、翻訳がいまいち。
    - OPPORTUNISTICが日和見と訳されていて最初？？？となった。
    - 次回受ける試験は英語で受けてみようかと思っています。
The element ul has an implicit role of list. Defining this explicitly is redundant and should be avoided

`ul`要素に`role="list"`を明示した際に出た警告。
`role="list"`を削除することで消える。

🔽 以下、参考にした英文ページを翻訳したもの
https://www.scottohara.me/blog/2019/01/12/lists-and-safari.html

> 2023年1月 - Safariが入れ子のコンテキストに基づいてリストのセマンティクスを公開する方法について、追加のアップデートがありました。例えば、リストが<nav>要素の子孫である場合、リストスタイルが削除されても、Safari/VoiceOverはこれをリストとしてユーザーに公開します。
>
>Safari/VoiceOverの動作は、バグによるものではなく、視覚的なスタイルが削除されたリストを開発者が多用することに対する反応であることを念頭に置いてください。もはやリストには見えないが、実際にリストとして公開する必要があるかどうかは、ご自身の判断でお願いします。
csvファイルにするための方法 その①

vmstatで出力した結果をawkコマンドでcsvにする。


```
awk -v OFS=, '{ print $13,$14,$16 }' aaa.txt

```




https://linux.just4fun.biz/?%E9%80%86%E5%BC%95%E3%81%8D%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88/awk%E3%81%AE%E5%87%BA%E5%8A%9B%E3%82%92%E3%82%AB%E3%83%B3%E3%83%9E%E5%8C%BA%E5%88%87%E3%82%8A%E3%81%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95
WEPの危険性を実感するために、Macでaircrack-ngを使ってWi-Fiをクラックする

:::note alert
この記事では、あくまでWEPの危険性を周知するために、許可されたWi-Fiルーターに対して攻撃を行います。他人のWi-Fiに対して許可なく攻撃を行うことは違法です。
:::

# はじめに

Wi-Fiの暗号化方式としてWEPを使用することが危険なのは周知の事実だとは思いますが、試したことがなかったので、今回WEPの危険性を実感するために自分で用意したWi-Fiルーターに対して攻撃をすることにしました。

# 環境構築

## Wi-Fiルーターの用意
被攻撃ルーターとして使ってない古いWi-Fiルーターを使いました。暗号化方式をWEP64に変更し、Keyを`hello`に設定しました。

## `aircrack-ng`のインストール
Linuxを使う場合は下記の記事などが参考になると思います。

https://whitemarkn.com/learning-ethical-hacker/aircrack-ng/

僕も最初はWSL上のKali-linuxでやろうとしたのですが、WSLからホストマシンのWi-Fiアダプタにアクセスできないとのことでしたので、Macを使ってやることにしました。

https://github.com/microsoft/WSL/issues/7400

https://unix.stackexchange.com/questions/579466/kali-linuxwsl-not-recognizing-wireless-adapter

Windowsでも良かったのですが、MacだとHomebrewを使って簡単に`aircrack-ng`をインストールできそうだったので、Macを使うことにしました。下記のようにして、インストールできます。

```zsh
brew install aircrack-ng
```

https://formulae.brew.sh/formula/aircrack-ng

## `airport`コマンドのパス設定
Linuxの場合は`airmon-ng`を使うようですが、Macで使うことができないようなので、代わりに`airport`コマンドを使うことにしました。

https://stackoverflow.com/questions/45314589/airmon-ng-not-working-in-terminal-command-not-found

`airport`コマンドはデフォルトでmacに入ってはいるもののパスが通っていないので、実行時にフルパスを指定する必要があるとのことでした。毎回フルパスを入力するのはめんどくさいので、環境変数PATHにパスを追加し、`airport`コマンドを使えるようにしました。もちろん、パスを永続化させたいなら、`~/zshrc`などに追記してください。

```zsh
export PATH="/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources:$PATH"
exec $SHELL -l
```

https://discussions.apple.com/thread/8522195

# 攻撃

## 攻撃対象のチャンネルを特定する
以下を実行すると、近くを飛んでいるWi-Fiの一覧を取得できるので、攻撃対象のSSIDから、被攻撃ルーターのチャンネルを特定してください。

```zsh
% sudo airport -s
Password:
                            SSID BSSID             RSSI CHANNEL HT CC SECURITY (auth/unicast/group)
```

## チャンネル上の通信をキャプチャする

次にチャンネル上の通信をキャプチャします。環境によっては`en0`ではなく、`en1`かもしれません。macOSがVenturaの場合、「システム設定」 > 「一般」 > 「情報」 > 「システムレポート」 > 「ネットワーク」 > 「Wi-Fi」 > 「インターフェイス」に書いてあります。

```zsh
sudo airport en0 sniff <チャンネル番号>
```
## 被攻撃ルーター上で通信を流す

通信をキャプチャするにしても肝心の通信がされていなければキャプチャできませんから、被攻撃ルーターのWi-Fiになんかの機器を接続して通信を行います。大量のパケットをキャプチャすることでWEPをクラックすることができるので、僕はiPadを繋げて、２時間ほどYoutubeを流しっぱなしにして放置しました。

## Keyを割り出す

ある程度通信をしたら「Ctrl + C」でキャプチャを中止すると、キャプチャされたデータが保存されたファイル（`.cap`拡張子）が作成されるのでそのパスを使って以下のように実行すると、Keyとして設定した`hello`を割り出すことができました。

```zsh
% aircrack-ng /tmp/airportSniffzg5v7C.cap
                     KEY FOUND! [ *** ] (ASCII: hello )
```

# さいごに
簡単にWEPを使ったWi-FiのKeyを得ることができました。WEPではなく、WPA3とかを使うようにしましょう！
【メモ】prettierの設定


## やりたいこと
VSCode上でctrl + sでの保存時に、インデントなどの整形をさせたい

## 実行したコマンド
```sh
npm i --save-dev eslint                

npx eslint --init     

npm install --save-dev prettier eslint-config-prettier
```

## 生成した・されたファイル
```.prettierrc
{
  "semi": false,
  "singleQuote": false,
  "tabWidth": 2
}
```

```json:.vscode/settings.json
{
  "editor.defaultFormatter": "esbenp.prettier-vscode", // フォーマッターをPrettierにする
  "editor.formatOnSave": true // ファイル保存時にフォーマットを実行
}

```

```json:package.json
"devDependencies": {
    "eslint": "^8.40.0",
    "eslint-config-prettier": "^8.8.0",
    "prettier": "^2.8.8"
  }
```

## 参考記事
https://zenn.dev/big_tanukiudon/articles/c1ab3dba7ba111
docker-composeでRuby＋MySQLの環境構築する際に「Unknown MySQL server host 'db' (-3)」でハマった話

## はじめに
docker-composeの概要を学ぶべく学習上、Ruby＋MySQLで環境構築を進めていく中で
ハマってしまった箇所があるのでその備忘録として記事に残します。

## 環境

* Docker 23.0.5
* ruby 2.7.8
* MySQL 8.0
* rails 6.1.7
* Windows 11

## 手順
以下のコマンドでDBを作成したところ、、、
```
$ docker-compose run web rails db:create
```

こんなプロンプトが返ってきました。
```
Unknown MySQL server host 'db' (-3)
Couldn't create 'app_development' database. Please check your configuration.
rake aborted!
ActiveRecord::ConnectionNotEstablished: Unknown MySQL server host 'db' (-3)
```
MySQLサーバーに接続できずDBコンテナが動作しない、、、
まずは、ログを確認
```
$ docker-compose logs db
```
ログの中の一番始めのエラーで以下のエラー文が吐かれたいました。
```
[ERROR] [MY-012960] [InnoDB] Cannot create redo log files because data files are corrupt or the database was not shut down cleanly after creating the data files.
```
Dataファイルが破損しているみたいなエラーが発生していました。

## 解決方法
実はパスワードの設定を間違ったまま `db:create` を実施してエラーが出た際に破損したDataファイルが残ったままでその上で再度実施した際に上記のエラーが発生した模様です。

docker-compose.ymlにデータ永続化のために、ボリュームマウントしていたため、
docker compose downでコンテナを削除した後もデータディレクトリの中身が保持されていました。
```yml:docker-compose.yml
version: '3'
services:
  db:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - ./src/db/mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - ./src:/app
    ports:
      - "3000:3000"
    depends_on:
      - db
```

なので、一旦Dataファイルが含まれているDataディレクトリを初期化する必要があります。
ボリュームごとコンテナを削除します。
```
$ docker-compose down -v
```

mysql_dataディレクトリ配下のファイルも削除しておきます。
<img width="280" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641311/e355e76b-50ef-a059-c117-9997a665e5fd.png" />

`docker system prune -a` で不要なコンテナやイメージを削除し、再度ビルドします。
```
$  docker system prune -a
:
$ docker-compose build
```
ビルドが終わったら、DB作成。
```
$ docker-compose run web rails db:create
```
今度こそDBの作成に成功しました！
```
Created database 'app_development'
Created database 'app_test'
```
コンテナも起動できている様子！
```
$ docker-compose ps
NAME                IMAGE               COMMAND                  SERVICE             CREATED              STATUS              PORTS
rails_docker-db-1   mysql:8.0           "docker-entrypoint.s…"   db                  About a minute ago   Up About a minute   3306/tcp, 33060/tcp
```

## 参考
https://qiita.com/amagurix/items/4a3eba263aab5f0936d5

https://qiita.com/gobtktk/items/ea76422acc614830583b
CSS チートシート

## background-color: - 背景色を変える
```
body {
  background-color: red;
}
```
背景色を変更できる。
使用できる色名→[MDNドキュメント](https://developer.mozilla.org/ja/docs/Web/CSS/color_value#color_keywords)

参考：
https://magazine.techacademy.jp/magazine/21236
Power Automate でメール本文に画像を埋め込む


# はじめに

ある程度フォーマットが決まったメールを送る業務を Power Automate で自動化するようなシナリオがあります。

アプローチ方法としては、例えば、SharePoint リストに予めメールのテンプレートを用意しておき、一定の周期で自動でフローを動かしてメールを送る、または、Power Apps でそのリストを読み込み、何かしらの選択をして、ボタンを押したらそのテンプレートのメールが送られるみたいなものがあります。

その際、メールの本文に画像を埋め込みたいという要件をいただくことがあるため、今回、そちらのアプローチについて説明いたします。

# SharePoint ドキュメントライブラリの準備

今回、画像ファイルはドキュメントライブラリに保存しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/3cd8814c-429a-66e5-c72a-e9665c9f1c2a.png)

※出来れば、SharePoint リストの画像列で実現したいですが (画像列の値がリンクになれば実現できるはず)、一旦は、Power Automate からリンクの扱いが容易なドキュメントライブラリでの実現方法を紹介します


# Power Automate の処理

Power Automate は非常にシンプルで、以下のようなイメージです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/7f6e2ad2-a9d1-495e-d585-3337bf2b5086.png)

ドキュメントライブラリからファイルのプロパティを取得し、img タグを使ってアイテムへのリンクをソースにします。

```
<img src="@{items('Apply_to_each')?['{Link}']}"> 
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/1f65d819-ae1a-66e0-11f7-6c09bb7fd400.png)

無事に画像付きメールが届きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/90664f10-546a-db3e-2fe1-35d6f166a5a6.png)

:::note warn
SharePoint 上に画像ファイルがあるため、受信者はこちらのファイルにアクセスできる必要があります。そのため、SharePoint のアクセス権を、受信者を想定して適切に設定する必要があります。基本的には、社内受信者限定のアプローチと考えます。
:::

# まとめ

Power Automate でメール本文に画像を埋め込む方法について紹介しました。メール本文に画像を埋め込みたいというニーズは結構あると思うので、参考にしていただければ幸いです。
VBAでグラフ作成　初心者


``` VBA


Sub test()

Max = Cells(1, 1).End(xlDown).Row


With ActiveSheet.Shapes.AddChart.Chart
    .ChartType = xlLine
    .SetSourceData Range("A1:D" & Max & "")
    .HasTitle = True       'グラフタイトルの追加
    .ChartTitle.Text = "TEST"
End With

Worksheets("Sheet2").Activate
Worksheets("Sheet2").Range("A1").Activate

End Sub


```

以下の参考に
これから徐々にレベルアップ

https://www.sejuku.net/blog/69474
【MD5って何？】なんでもう使われていないのかまとめてみた！

「MD5はもう使われていないです」という記載は今までに何度か目にしたことはあったのですが、いかんせんエンジニアになってから暗号周りの勉強は後回しにしていたので、**なぜ**もう使われないのか、というところまではわかっていませんでした。

最近暗号技術についての勉強をし始めたので、MD5がなぜ今は使われないのか、というのを備忘録的に今回の記事ではまとめてみようと思います。

# MD5とは？

Ronald Rivestという方が1991年に作ったハッシュ関数の一つで、任意の長さの入力値に対して128ビットのハッシュ値を出力します。

そのため例えば、`qwerty`という文字列が与えられた場合には`d8578edf8458ce06fbc5bb76a58c5ca4`という返り値が返ってきます。

なお、MD5は同氏がすでに作っていたMD4の改良版という位置付けとなっています。

# ハッシュ関数の3つの安全性について

本格的にMD5が使われなくなった理由を書く前に、広く使われるハッシュ関数に対して求められる3つの安全性について説明します。

ハッシュ関数の3つの安全性はそれぞれ下記のように呼ばれています。
- 一方向性
- 衝突困難性
- 第二現像計算困難性

上記はハッシュ関数の安全性の基準を示しており、どれか1つでも欠けると安全なハッシュ関数ではないと見做されてしまいます。
下記がそれぞれの説明です。

## 一方向性（One Wayness) 

一言で言うと、ハッシュ値から元の値を計算することが困難であることを表します。
これはシンプルですね。

## 衝突困難性(Collision Resistance)

ハッシュ関数を通す前のインプットと返されたアウトプットでは使える文字数に差があるので（アウトプットの方が少ない）、全く別のメッセージをハッシュ関数に渡しても同じアウトプットが返ってくる可能性があります。（このことをハッシュ値の衝突と呼ぶ）

つまり、`hash(message1) = hash(message2)`となる場合があるということです。

衝突困難性というのは、このように衝突するようなメッセージの組み合わせを計算で割り出すことが困難であることを指します。

## 第二原像計算困難性（Second Preimage Resistance）

一言で言うと、ハッシュ関数に通す前の生のメッセージとそのメッセージのハッシュ値を手がかりに、同じハッシュ値を得られる別のメッセージを計算することが困難であることを指します。

余談ですが`同じハッシュ値になる別のメッセージ`の存在が出てくるので衝突困難性になんとなく似ているなと思ったらそのようでした。
暗号技術のすべてという本では、_第二原像計算困難生は「弱い意味での衝突困難性」、衝突困難性は「強い意味での第二原像計算困難生」_ とも紹介されていました。

# MD5が使われなくなった理由

ハッシュ関数に求められる3つの安全性について説明したところで今回の記事の本題に入りますが、
MD5が使われなくなった理由を一言で言うと、**衝突困難性が破られてしまったから**です。

2011年にIETFが公表したRFC6151によると、
2.6GHzほどの性能の当時のインテル製のプロセッサを使い10秒ほどで衝突するペアを見つけ出すことが可能だということが判明しました。

また、128ビットの出力値というのがハッシュ値としては短すぎたようで、ブルートフォース攻撃によって最大でも2、3日かければ解読できてしまうというのもあったようです。

なお、現在広く使われているSHA256においては文字通り256ビットの出力値が返ってくるようですが、こちらであれば元のメッセージが十分に長ければ1年以上やさらに長い時間をかけても解読することはできないようです。

これらの要因からMD5は安全なハッシュ関数とは見做されなくなり、SHA1やSHA2ファミリーがハッシュ関数として広く使われ始めるようになりました。


# まとめ

ということで今回の記事では暗号技術の勉強のノート程度にMD5が使われなくなった理由と暗号技術についての知識をちょびっとまとめてみました。
やっぱり読むだけで知った気になるのとこういった形でアウトプットするのでは身に付き方が全然違いますね。

あとDictionary Attackというのも今回の記事を書く中で初めて言葉として知りました。平文のパスワードが流出しているかを調べられるのは知っていたのですが、ハッシュ値で流出済みかを調べることもできるのですね。（考えてみれば当たり前な気もしますが）

「Passwordは長い方がいい」というのは技術者でなくても知っていることですが、こうやってなんでそうなのか、というのを調べるのはたのしいですね :thumbsup: 

また今回の勉強を通して下記の点も気になったので、次回以降の記事でまとめてみたいと思います。
- MD5が使われなくなってからSHA1が現れてすぐにいなくなった経緯
- SHA2ファミリーが現在の主流となっている理由



# 参考
- [暗号技術のすべて / 翔泳社](https://www.shoeisha.co.jp/book/detail/9784798148816)
- [What is MD5 (Message Digest Algorithm)?](https://www.techtarget.com/searchsecurity/definition/MD5)
- [3 Reasons why MD5 is not Secure](https://infosecscout.com/why-md5-is-not-safe/)
いまからでも遅くない！メッセージキュー超入門 ～REST APIでメッセージやりとりしてみた！～

# はじめに
MQ30周年おめでとうございます！
ということで（？）MQ入門の入り口になるようなコンテンツを目指して。。。
簡単にデモ環境つくって、メッセージキューイングを体験してみます。

# MQとは
メッセージキューイングアプリケーションです。
いわゆるシステム間連携で使用するもので、オンブレとクラウドとの間のデータ連携や
システムとシステムとのつなぐ仲立ちをするものになります。
いまや世の中にある様々なシステムの裏側で活躍する縁の下の力持ちです。

# やりたいこと
そんなメッセージキューイングを体感するためローカルにコンテナ環境を作り。
以下システム構成でメッセージのやりとりをしてみました。今回はcURLコマンドを使用して
REST APIで「Hello MQ!!」というメッセージを送受信してみます。

※以下図における「アプリ」はcURLコマンドを指します。
![MQシステム構成.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664175/b161932f-a0a5-306d-fb98-c2241d2b9049.jpeg)

# 私の環境
* Windows11 Pro
* Docker for Business

# 事前準備
* Docker（またはpodman）

# 構築
## 永続ボリュームを作って、MQコンテナ起動
```
C:\Users\hogehoge>docker volume create qm1v
C:\Users\hogehoge>docker run -d --name mymq -v qm1v:/mnt/mqm -e LICENSE=accept -e MQ_QMGR_NAME=QM1 -p 9443:9443  icr.io/ibm-messaging/mq:9.3.2.0-r2
```

## コンテナIDを確認して、動作確認
```
# CONTAINER IDを確認
C:\Users\hogehoge>docker ps
CONTAINER ID   IMAGE                                COMMAND   CREATED      STATUS         PORTS                NAMES
eaed19cf19a4   icr.io/ibm-messaging/mq:9.3.2.0-r2   ""        2 days ago   Up 3 seconds   1414/tcp, 9443/tcp   mymq
```
※上記コマンドから「eaed19cf19a4」とわかる

```
# コンテナIDを指定して実行
C:\Users\hogehoge>docker exec -it eaed19cf19a4 dspmq
QMNAME(QM1)                                               STATUS(Running)
```

## REST APIのエンドポイントを確認
```
# PC側で実行
C:\Users\hogehoge>docker exec -it eaed19cf19a4 /bin/bash
# コンテナ内で実行
$ dspmqweb status
MQWB1124I: Server 'mqweb' is running.
URLS:
  https://eaed19cf19a4:9443/ibmmq/console/
  https://eaed19cf19a4:9443/ibmmq/rest/
```
※上記で「https://eaed19cf19a4:9443」となっているが
コンテナで実行しているため「https://localhost:9443」となる。

# ブラウザでMQ Web Consoleの動作確認
https://localhost:9443/ibmmq/console/
（admin/passw0rdでログイン）
※警告が出るが無視してログイン

# RESTAPI実行のために事前認証（トークン認証）
```
# app/passw0rdでログイン。ローカルPC側のCookieに認証情報を保存する
C:\Users\hogehoge>curl -k https://localhost:9443/ibmmq/rest/v2/login -X POST -H "Content-Type: application/json; charset=UTF-8" -d "{\"username\":\"app\",\"password\":\"passw0rd\"}" -c c:\users\hogehoge\cookiejar.txt
```

# メッセージ送受信
```
# 送信
C:\Users\hogehoge>curl -k https://localhost:9443/ibmmq/rest/v2/messaging/qmgr/QM1/queue/DEV.QUEUE.1/message -X POST -b c:\users\hogehoge\cookiejar.txt -H "ibm-mq-rest-csrf-token: value" -H "Content-Type: text/plain;charset=utf-8" --data "Hello MQ!!"

# 受信
C:\Users\hogehoge>curl -k https://localhost:9443/ibmmq/rest/v2/messaging/qmgr/QM1/queue/DEV.QUEUE.1/message -b c:\users\hogehoge\cookiejar.txt -H "ibm-mq-rest-csrf-token: value" -H "Content-Type: text/plain;charset=utf-8"
Hello MQ!!
```
コンソールに「Hello MQ!!」となればOK。メッセージ受信できています。

# 最後に
ということで、ここまでMQコンテナを使って、メッセージキューを体験してみましたがいかがでしたか？
今回はコマンドでメッセージの送受信をしたので、ものすごくシンプルであっさりした見た目になりましたが・・・
でもメッセージキューはシステムにおける重要なファクターであることを忘れないであげてください。。。
次回はローカルコンテナではなく、クラウド上で同じことをやってみたいと思います。お楽しみに。

# 参考資料
## MQコンテナ使用方法
https://github.com/ibm-messaging/mq-container/blob/master/docs/usage.md
## 認証
https://www.ibm.com/docs/ja/ibm-mq/9.2?topic=security-using-token-based-authentication-rest-api
## MQ REST APIドキュメント
https://www.ibm.com/docs/ja/ibm-mq/9.2?topic=resources-messagingqmgrqmgrnamequeuequeuenamemessage
Git初心者がGithub入門してみた

# はじめに
Qiita初投稿となります。

駆け出しエンジニアがGithubに関して学んだことを記事としてまとめてみました。
初心者向けの簡単な説明となりますが、お付き合い頂ければ幸いです。
# GitとGithub
### Gitとは
Git（ギット）とは、分散型バージョン管理システムのことです。

バージョン管理ツールには集中型と分散型の2種類があり、集中型ではファイルの保管場所が一箇所のみの提供となるため、複数人数で1つのファイルを同時に修正したときにメンバーの変更がほかのメンバーに上書きされてしまう可能性があります。

一方でGitのような分散型は利用者一人一人に専用の保管場所を提供するため、他のメンバーに上書きされる心配なく個人の保管場所で作業することができます。
個人の作業としてファイルの修正が一段落したら、チーム全員で共有する保管場所に反映させていきます。

### Githubとは
GithubはGitの仕組みを利用してソースプログラムなどを保存・共有できるようにしたプログラマー向けのWebサービスです。
Microsoft傘下のGitHub社が運営するソースコードホスティングサービスであり、Gitをベースとしたソースコードホスティングサイトはいくつも存在しますがその中でも世界最大級です。

Githubの魅力としては、自分のソースコードを公開して助言を求めたり、自身が開発したシステムを公開して利用してもらいやすい点です。
単にソースコードをホスティングするだけでなく、開発者同士のコミュニティーの場としても広く利用されています。

# Github全体像
全体像としては以下の図の通りとなります。
![Git図解 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834935/f8b9da2b-95fb-8635-31a8-26dbf70793b3.jpeg)

##### ①リポジトリ
直訳すると「貯蔵庫」であり、「Gitにより管理されるファイルやバージョン情報を格納する領域」のことです。

Gitにおけるリポジトリには以下の2種類があります。

・リモートリポジトリ：サーバ上にある複数人で共有管理するリポジトリ
・ローカルリポジトリ：ローカル上にある個人で編集作業をするリポジトリ

##### ②ステージングエリア
ワークディレクトリとローカルリポジトリとの差分を記録する一時的な保存領域です。
ステージングエリアにインデックスのリストとして保存することで、リポジトリに保存したいファイルだけを選択することができます。

##### ③ワークディレクトリ
ローカルで実際に使うGitに管理されているディレクトリ。
基本的にはワークツリー上で変更を加え、リポジトリを更新していく流れになります。

##### ④ブランチ
直訳すると「枝、分岐」という意味で、バージョンごとにリポジトリを管理する機能のことです。
分岐したブランチは他のブランチに影響を与えないので複数人が別々のブランチ上で同時に作業でき、不具合などが発生しても問題の切り分けが容易になります。

設定を変更しない限りは、Gitリポジトリを作成した際のデフォルトのブランチ名は「main」となります。

# よく使うコマンド
|コマンド名　　|用途|
| ---- | ---- |
|git init|リポジトリを新規作成|
|git clone|リモートリポジトリからソースコードをローカルに複製|
|git pull|リモートリポジトリの変更点をローカルに取得|
|git push|ローカルリポジトリの変更点をリモートリポジトリにアップロード|
|git add|コミット対象のファイルをステージングエリアに登録|
|git commit|ローカルリポジトリに追加したファイルをコミット|
|git reset|ステージング/コミットを取り消し|
|git revert|特定のコミットを取り消し|
|git log|コミットの履歴を表示|
|git status|作業ツリー内の差分ファイルを表示|
|git diff|ファイル内の差分箇所を表示|
|git mv|ファイルを移動/ファイル名を変更|
|git branch|ブランチを作成|
|git checkout|処理対象ブランチの切り替え|
|git merge|別のブランチから変更点をマージ|
|git rebase|派生元ブランチに変更をマージ|
|git fetch|originのコミット状態を取得|

# 作業フロー【一例】
まずは、自分自身の作業場所を最新化します。
```git
$ git pull
```
自分の作業をするためのブランチを作成し、そのブランチに移動。
```git
$ git checkout -b ブランチ名
```
ソースコードの修正後、変更を確認。
```git
$ git status
```
変更されたファイルが赤字で表示されるので、指定してステージングエリアに追加。
（複数指定する場合、間は半角スペース）
```git
$ git add 修正したファイル1 修正したファイル2 ...
```
ステージングエリアに追加したファイルをローカルリポジトリにコミット。
```git
$ git commit -m "コミットメッセージ"
```
Githubのリモートブランチにアップロード
```git
$ git push origin ブランチ名
```
pushし終わったらプルリクエストを作成してレビューをもらいます。
レビュー後の修正が完了し、レビュアーの承認が降りたらマージする（してもらう）という流れになります。

## 終わりに
Githubの説明は以上となります。
お付き合いいただきありがとうございました。
【Linux】コマンドのMemo書き

プログラミングに関する勉強を始めたばかりで学習途中ですが、学んだことを記録として残していこうと思い投稿しています。間違っている部分がありましたらコメントなどをください。

# Linuxコマンド
| コマンド | 説明|
|:------------:|:------------:|
| ls |カレントディレクトリ内のファイルやディレクトリを表示するコマンド |
| cd |ディレクトリを変更するコマンド |
| mkdir |ディレクトリを作成するコマンド |
|rm|ファイルを削除するコマンド|
|cp|ファイルをコピーするコマンド|
|mv|ファイルを移動するコマンド|
|cat|ファイルの内容を表示するコマンド|
|grep|ファイル内の文字列を検索するコマンド|
|find|指定した条件に合致するファイルを検索するコマンド|
|tar|ファイルやディレクトリをアーカイブするコマンド|
【個人的勉強編】M5stack拡張モジュール~心電図電極パットの貼る位置について~

個人的勉強部屋へようこそ。新しいデバイスとかをキャッチアップするときに、何かにまとめておかないと即忘れるので、得た知識をまとめた。
今回は、M5stackの拡張モジュールで`ECG Module13.2(AD8232)`という
心電図信号を受け取ることができる拡張モジュールの初期知識キャッチアップをしていく。


https://docs.m5stack.com/ja/module/ecg


![スクリーンショット 2023-05-14 16.36.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/272851bd-9b5f-3168-bb74-dc9e29def541.png)



## ECG Module13.2(AD8232)でできること
**心臓の電気信号から心拍数を計算することが可能。**

AD8232の中には、心電図モジュール、接続ケーブル、電極パットが含まれてる。

### 電極パットの貼り方について
ケーブルには、「LA」「RA」「LL」というアルファベット二文字が書かれたケーブルがある。これは、それぞれ「Right Arm」「Left Arm」「Right Leg」を表していて、指定した体の位置に貼らないといけないらしい。



![スクリーンショット 2023-05-14 16.44.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/d1b0337d-e058-b10d-6479-89e6f15152d0.png)
![スクリーンショット 2023-05-14 16.48.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/4ceea8a9-86fd-60a6-528e-b19e478cbe0e.png)

出典元
> https://www.analog.com/jp/education/landing-pages/003/iot_lectureship/content_08.html



### sample program
心拍数と心電図波形を含む生データ

```C++
#include <M5Core2.h>
#include <AD8232.h>

#define LO_NEG_PIN 33
#define OUTPUT_PIN 32
#define LO_POS_PIN 27
#define BUTTON_A_PIN 39

AD8232 ecg;

void setup() {
  M5.begin();
  Serial.begin(115200);

  pinMode(LO_NEG_PIN, OUTPUT);
  pinMode(OUTPUT_PIN, INPUT);
  pinMode(LO_POS_PIN, OUTPUT);
  digitalWrite(LO_NEG_PIN, LOW);
  digitalWrite(LO_POS_PIN, HIGH);

  ecg.begin(OUTPUT_PIN, LO_POS_PIN, LO_NEG_PIN);
  ecg.setGain(ECG_GAIN_40X);
  ecg.setRate(ECG_RATE_500HZ);
  ecg.start();
}

void loop() {
  if (M5.BtnA.wasPressed()) {
    ecg.start();
  }
  if (M5.BtnA.wasReleased()) {
    ecg.stop();
  }

  if (ecg.available()) {
    int ecgValue = ecg.read();
    Serial.println(ecgValue);
  }
}

```
次世代ストレージZNS SSD

## はじめに
Zoned NameSpace SSD (ZNS SSD) とは近年注目を集めているストレージデバイスのことです。
一般的なSSDよりもアクセス速度に優れリアルタイム性が求められる組込みシステムでの適応が期待されています。この記事ではZNS SSDの特徴と利点を解説しようと思います。

## ストレージ
まずはストレージとは何かというところからいきましょう。
ストレージとは直訳すると”貯蔵”という意味、つまりコンピュータの世界ではプログラムを実行する命令やデータを保管しておく記憶装置のことを指します。
日常的にわかりやすい例でいうと、みなさんが保管しているファイルはストレージに保管されていて、アクセス時はファイルシステムを介してストレージデバイスにアクセスしているわけです。

## SSD
先ほど説明したストレージデバイスの一種としてSolid State Drive(SSD)があります。
従来はストレージデバイスとしてはHDDが一般的で多くのコンピュータに使用されていましたが、HDDはデータアクセス命令時にプラッタ内に保管されているデータ位置まで磁気ヘッドを移動することでデータのアクセスをします。つまり、HDDは機械的アクセスが必須なわけでその分アクセスレイテンシが高くなるわけです。
そこで、SSDは記憶素子としてはNAND型フラッシメモリを使用しています。つまりSSDは電気的なアクセスのみで機械的なアクセスが一切必要ないためHDDに比べて圧倒的に高速ということです。

## 従来のSSD
ZNS SSDの利点を説明する前に従来のSSDの問題点を説明していきます。
SSDができた当初は既存のSoftware Stackとの互換性を維持することで市場を獲得しました。つまり、アプリケーションがSSDにアクセスをしようとすると
 APP ⇨ File System ⇨ Block layer ⇨ Device Driver ⇨ SSD
というように、論理アドレスから物理アドレスへの変換を経てアクセスされます。つまり、書き込みファイルは以下の図のようにバラバラな位置に書き込まれます。
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3389213/bef0cebf-c89c-930e-026c-b2be43d8bd5d.png"width = "60%">
SSDは上書きができないという特徴がありファイルの上書き時は対象ファイルを削除してから書き込みをする必要があります。SSDの削除はブロック単位で行われるため以下の図からわかるようにファイルCを削除しようとすると、ファイルCと同一ブロックにある他のファイルを空きブロックに退避させる必要があります。この処理をガーベジコレクションと言います。
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3389213/ffaf7ffc-31b2-1d7d-4183-d61761ed117f.png"width="60%">
つまり、本来の書き込み量より多くの書き込みが発生してします。これが、結果的に書き込みレイテンシにつながっているわけですね。

## ZNS SSD
さて、本題のZNS SSDの説明に入りましょう。
ZNS SSDの最大の特徴はストレージ上のデータ配置をホストが直接管理できるという点です。
つまり、以下のようなデータ配置になりガーベジコレクションなどの書き込みレイテンシを低減できるわけです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3389213/d65c303a-d9c4-d979-df28-b5294cd30a59.png"width="60%">

## まとめ
本記事では次世代ストレージZNS SSDの特徴と利点を説明しました。ZNSに欠点がないように思えますが、アプリケーション開発者がストレージ内のデータ配置を考えながら実装することは難易度が高いと言えるでしょう。そこで、最近のLinuxではZNSに対応したファイルシステムなどが存在します。次の記事でLinuxのZNSへのアプローチを紹介しようと思います。

## 参考
- Zoned Storage : https://zonedstorage.io/
- https://snia.org/sites/default/files/SDC/2020/074-Holmberg-ZenFS-Zones-and-RocksDB.pdf
VSCode Neovimのinit.luaの個人的設定

* init.luaはC:\Users\ユーザ\AppData\Local\nvimに格納する

```lua
if vim.g.vscode then
	vim.keymap.set("n", "<C-a>", ":normal! ggVG<CR>", { noremap = true, silent = true }) -- ctrl+aで全選択
	-- vim.keymap.set('v', '<C-c>', '"*y', { noremap = true, silent = true })            -- vscodeだと機能しない
	
	local opt = vim.opt
	opt.clipboard = 'unnamedplus' -- yankでクリップボードに
else
	-- original
end
```
【Linux・vim】日本語を扱えるようにする

# はじめに
この記事では、初めてDockerでLinux環境を構築して、日本語が正しく入力できなくて困っている方のための記事となります。
簡単に設定できますので、サクッと終わらせちゃいましょう！
では、以下の3つのステップを順に実行していきましょう！( ^ω^ )




# 1. 日本語ロケールのインストール
   以下のコマンドを実行して、日本語ロケールをインストールしてください。

```
apt-get update
apt-get install -y language-pack-ja
```


# 2. 環境変数を永続化する
   環境変数を永続化し、コンテナの再起動後も設定が維持されるようにします。以下のコマンドを実行して、`/etc/bash.bashrc` に環境変数を追加します。

   ```bash
   echo 'export LANG=ja_JP.UTF-8' >> /etc/bash.bashrc
   echo 'export LC_CTYPE=ja_JP.UTF-8' >> /etc/bash.bashrc
   ```

   これにより、コンテナ内で新しいbashセッションを開始するたびに、環境変数が自動的に設定されます。ただし、現在のセッションには影響しないため、以下の手順で環境変数を設定するか、コンテナを再起動してください。





# 3. 環境変数を設定する
   まず、コンテナ内で以下のコマンドを実行し、環境変数を設定してください。

```bash
export LANG=ja_JP.UTF-8
export LC_CTYPE=ja_JP.UTF-8
```

これで、現在のセッションに対して環境変数が設定されます。

以下のコマンドで、ロケールの設定を確認してみましょう

```
locale
```

`LANG`や`LC_CTYPE`が`ja_JP.UTF-8`に設定されていればOKです！

以上で、現在のコンテナに対して日本語を設定することができました。
ただし、Dockerのベストプラクティスとしては、コンテナ内での変更は短期的なものとし、永続的な変更はDockerイメージまたはDockerfileに反映させることが推奨されているようです。





# 最後に
ここまで読んでいただきありがとうございました！！
ぜひイイね！をよろしくお願いします (*ᴗˬᴗ)⁾⁾
それではまた！(^_^)ﾉｼ