OmniAICreator/Qiita-1.07M huggingface dataset:
とっても便利なAWS CLI使用のススメ

# AWS CLIのメリットとデメリット：管理コンソール、CloudFormationとの比較

AWS CLI (コマンドラインインターフェース)は、AWSのリソースを管理するための強力なツールです。AWS CLIを使用することで、ユーザーはコマンドラインから直接AWSサービスを操作できます。

## 1. AWS CLIのメリット
### 1.1 スクリプトによる自動化
AWS CLIの最大のメリットは、スクリプトを使って操作を自動化できることです。繰り返しのタスクや複雑なデプロイメントをシェルスクリプトやPythonなどで自動化することで、作業時間の短縮やエラーの減少を実現できます。

### 1.2 複数アカウントや複数プロファイルの管理が容易
AWS CLIでは、複数のAWSアカウントやプロファイルを簡単に切り替えることができます。これにより、異なる環境（例えば開発、ステージング、本番）での操作を一元的に管理できるようになります。

### 1.3 CLIでしかできない詳細な操作が可能
CLIには、管理コンソールでは対応していない詳細な操作やオプションが存在します。例えば、特定のフィルタリングやバルクオペレーション（大量のリソースを一度に操作）を簡単に実行できる点は、CLIならではの強みです。

## 2. AWS CLIのデメリット
### 2.1 学習コストが高い
CLIはコマンドラインベースの操作が前提となるため、コマンドの構文やオプションを確認する必要があります。これにより、初心者にとっては敷居が高いと感じるかもしれません。（確認すれば良いので覚える必要はありません）

### 2.2 リアルタイムの視覚的なフィードバックがない
管理コンソールは視覚的なインターフェースを提供するため、リソースの状態をリアルタイムで確認しやすいですが、CLIは基本的にテキストベースの出力となるため、視覚的なフィードバックに乏しいです。

### 2.3 誤操作のリスク
CLIではコマンド一つで重大な変更を加えることが可能です。誤ったコマンドを実行すると、大量のリソースを削除するなど、取り返しのつかない事態を招くことがあります。そのため、慎重な操作が求められます。

## 3. AWS管理コンソールとの比較
### 3.1 メリット
- **使いやすさ**: GUI（グラフィカルユーザインターフェース）で操作できるため、視覚的にわかりやすく、初学者でも直感的に操作できます。
- **リアルタイムなフィードバック**: 画面上でリソースの状態をリアルタイムで確認できるため、操作の結果がすぐにわかります。

### 3.2 デメリット
- **自動化が難しい**: 繰り返し作業や複雑な操作を自動化することが難しく、手動での操作が多くなります。
- **効率性の低下**: 複数のリソースを一括で操作する場合、CLIと比較して効率が落ちることがあります。

## 4. AWS CloudFormationとの比較
### 4.1 メリット
- **インフラストラクチャのコード化**: CloudFormationはインフラストラクチャをコードとして管理でき、リソースの作成や更新をテンプレート化して自動的に行うことができます。
- **一貫性の確保**: テンプレートを使用することで、同じ構成の環境を再現することが容易になります。

### 4.2 デメリット
- **学習コストが高い**: テンプレートの構文を理解する必要があり、特に大規模なインフラストラクチャを管理する場合、初学者には難易度が高いと感じるかもしれません。
- **リアルタイムのインタラクションが難しい**: CLIや管理コンソールと比べて、リアルタイムでの細かい操作がしにくいです。

## 5. 結論
AWS CLIは、自動化や複数環境の管理が容易で、詳細な操作が可能な強力なツールですが、学習コストが高く、視覚的なフィードバックが乏しいというデメリットがあります。一方、管理コンソールは直感的で使いやすい反面、自動化や大量のリソース操作には向いていません。CloudFormationはインフラをコードとして管理でき、一貫性を保つことができる一方、学習コストが高く、リアルタイムでの操作が難しい点が挙げられます。

初心者はまず管理コンソールでAWSの基礎を学び、その後CLIやCloudFormationに移行していくのが一般的なステップです。それぞれのツールの特徴を理解し、適切に使い分けることで、AWSをより効率的に活用できるようになります。

## AWS CLIと他のツールとの比較
|ツール|メリット|デメリット|
|---|---|---|
|AWS CLI|- 高速で効率的な操作<br>- 自動化が容易<br>- 詳細な制御が可能|- 初めてのユーザーにはコマンドラインが難しいことがある|
|AWS管理コンソール|- 直感的で視覚的な操作が可能<br>- 設定が簡単<br>|- 大規模な作業では効率が悪い<br>- 自動化が難しい|
|AWS CloudFormation|- インフラの自動化が容易<br>- インフラの一貫性を確保<br>|- テンプレートの学習が必要<br>- リアルタイムの操作が難しい|
ブレース展開を使ってcpやmvを短く書く

既に有名なものかもしれませんが、Bashのブレース展開の応用方法を知ったので備忘録として残します。

ブレース展開とは、中括弧でくくったカンマ区切りの文字列を展開する機能です：
```bash
$ echo a{1,2}
a1 a2
$ echo a{,2}
a a2
```
for文を書く時に活躍するものですね。これを使うと、例えば`cp file file.bk`は
```bash
$ cp file{,.bk}
```
のように書けます。次の例では`file.htm`の拡張子を`html`に変更します。
```bash
$ mv file.htm{,l}
```
あまり使う機会は無いかもしれませんが、目にした時に驚かないようにしておきたいです。
【Vue.js】.prevent .stopが効いてないと思ったら勘違いだった

Vue.jsを勉強中、イベント修飾子について、テストしていたら、詰まったのでメモします。
かなり初歩的なことですが、気づけず時間をかけてしまったので....（ᓀ‸ᓂ）ﾊﾞﾆ....




## 1.間違っていたコード
```vue:App.vue
<h1> {{ price }}</h1>
<div>
  <button @click.stop.prevent="increment()">増やす</button>
</div>

```
increment()でpriceの数が加算される仕組みにしています。
clickイベントに.stopをつけて起動しないようにしているのですが、なぜか起動してしまいました。

## 2.修正したコード
```vue:App.vue
<h1> {{ price }}</h1>
<div @click="increment()">
  <button @click.stop.prevent="">増やす</button>
</div>
</div>

```
これで動かなくなりました！！

## 3.なぜこのようなことが起きたのか？
個人的に引っかかったので図にしてまとめてみました。
慣れている人はともかく、一度勘違いしてしまうとはまっちゃいそうですね...笑

![unnamed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348307/ad3ce259-c7ee-b99d-bc9d-6fabafaf7a6e.png)

子のbuttonに書かれているclickが無事起動したら、親のclickが起動する仕組みになっているようです。

【実行順序】
子要素のイベント
　 ↓
親要素のイベント(子が起動しなければ起動しない。)

①のclickには、stopの例外処理のようなもと認識していて、基本機能はストップさせたいけど、ストップさせた後、この処理だけはやってほしいといったときに使うようです...!
【ORACLE MASTER Platinum DBA 2019 実技試験】(8) 練習問題4 フラッシュバック・データベースの構成

# 目指せ！ORACLE MASTER Platinum DBA 2019合格
#### - ORACLE Certified Master DBA 2019 -

:::note info
まずは最初の記事をチェック！
[試験概要](https://qiita.com/nisshii0/items/57822fb5cf72f3636cbe)
:::


オラクルマスター Platinum DBA 2019（Oracle Certified Master）を目指す方に、合格者の観点からアドバイスを送ります。
当然守秘義務がありますので、主に試験概要ページから参照可能な情報の読み解き方のアドバイスになります。
何回かに分けていきたいと思います。


# 全体目次
第1回：[試験概要](https://qiita.com/nisshii0/items/57822fb5cf72f3636cbe
)
第2回：[学習方法（インストラクターのアドバイスを読み解く）](https://qiita.com/nisshii0/items/fbd6782f43c16c1873df)
第3回：[実機演習環境を整える](https://qiita.com/nisshii0/items/c0e912b8b00a0b590198)
第4回：[試験範囲の予想（Platinum試験とGold試験）](https://qiita.com/nisshii0/items/32fbb5167ff3eb3f3f51)
第5回：[練習問題1 PDBの作成](https://qiita.com/nisshii0/items/4d07ba173d4c41fa9957)
第6回：[練習問題2 表領域の管理  ](https://qiita.com/nisshii0/items/0838c6f3fe7f8e21a065)
第7回：[練習問題3 リカバリカタログの管理](https://qiita.com/nisshii0/items/1641de47c0b4aab45363)
第8回：[練習問題4 フラッシュバック・データベースの構成](https://qiita.com/nisshii0/items/b6b9ad7e86b414482381)
★本記事です
～　ネタがあれば続けていきたい　～

## 本記事の前提
オラクル社公式サイトで公開されているPlatinum試験のチェックリストと、
GoldおよびPlatinumなどの公開された学習コンテンツ、ドキュメント等からの予想問題になります。
実試験の内容とは一切関係ありません。

## 試験勉強するときの考え方
Platinum DBA 2019 実技試験は、その名のとおり「実技」です。
試験勉強には、実機での演習がかかせません。
試験対策問題集はリリースされていないため、自分で練習問題を考えていく必要があります。

それではチェックリストの「フラッシュバック・データベースの構成」に関するマニュアルをみてみましょう。

><B>参考ドキュメント</B>
>[Oracle Database 19c バックアップおよびリカバリ・ユーザーズ・ガイド（7 フラッシュバック・データベースおよびリストア・ポイントの使用）](https://docs.oracle.com/cd/F19136_01/bradv/using-flasback-database-restore-points.html#GUID-909BBEEF-389B-443B-8CD7-F3C027AAFFF3)

ここではチェックリストの「フラッシュバック・データベースの構成」を見ていきたいと思います。
数あるフラッシュバック機能の中で、フラッシュバック・データベースとは何か？
他のフラッシュバック機能との違いは？

まずフラッシュバック・データベースとはどのような機能でしょうか？
バックアップ関連のマニュアルに記載があることから分かるように
データのリカバリに使えそうです。では、通常のリカバリ操作との違いは？
まずは機能についておさえておいてください。

以下はマニュアルの記述を問題文形式にした練習問題です。

## 練習問題
こちらも前記事と同じく、1問あたり3分以内を目指してください。
早いものは1分とかからないはずです。

#### 練習問題1.
・データベースをアーカイブログモードにしてください。

#### 練習問題3.
・高速リカバリ領域を有効にしてください。
　サイズは「10G」とします。

#### 練習問題3.
・保証付きリストアポイントおよびCDB上でリストアポイントを作成するための
　初期化パラメータを設定してください（または設定されていることを確認してください）

#### 練習問題4.
・CDBを使用します。
　通常のリストアポイント「before_upgrade」を作成してください。
　保証付きのリストアポイント「before_upgrade2」を作成してください。

 
#### 練習問題5.
・PDBに対してを使用します。
　通常のリストアポイント「before_patching」を作成してください。
　保証付きのリストアポイント「before_patching2」を作成してください。

 
#### 練習問題6.
・リストアポイントを表示してください（リストアポイント名を確認してください）。

#### 練習問題7.
・フラッシュバック可能期間を2日にしてください。

#### 練習問題8.
・データベース全体でフラッシュバックデータベース機能を有効にしてください。

#### 練習問題8.
・フラッシュバックデータベース機能を使用して、リストアポイント「before_upgrade」まで戻してください。



## 考え方のまとめ
フラッシュバック関連機能は多数あります。
そのなかで、フラッシュバック・データベースの特長を確認してください。
また、他の単元にくらべ「フラッシュバックデータベース」機能をONにするのは簡単です。
ただし、使用するにはいくつかの前提条件があるため、どういう前提条件が整えられていれば、この機能が使えるか、きちんとおさえておきましょう。
AWSの無料枠まとめてみた

## AWSの無料枠の種類
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3871776/d448861d-0876-9d50-2599-f5bc27fae473.png)

### ◇ 12か月間無料枠
 AWSアカウントを作成した日から1年間、特定のサービスを無料で利用できる枠。

### ◇ 無期限無料枠
特定のサービスを期間制限なく無料で利用できる枠。
ただし、利用回数や容量に制限があるため、注意が必要。

### ◇ 無料トライアル
一定期間または一定回数だけ無料で利用できる枠。


## 12ヶ月無料枠の代表的なサービス

- Amazon EC2: 750時間/月のt2.microまたはt3.microインスタンスが利用可能。
- Amazon S3: 5GBの標準ストレージが無料で利用できる。
- Amazon RDS: 750時間/月まで無料で利用可能。
- Amazon EBS: 30GBまでのEBS汎用ストレージが無料で利用可能。
- Amazon Elastic Load Balancing (ELB): 750時間/月のロードバランサー利用と15GBのClassic Load Balancerデータ処理が無料。
- Amazon API Gateway: 100万件/月のAPIリクエストが無料で利用可能。



## 無期限無料枠の代表的なサービス
- AWS Lambda: 100万回/月までのリクエストが無料。
- Amazon DynamoDB: 25GBまでのストレージが無料で利用可能。
- Amazon CloudFront: 1TBのデータ転送と1000万件のHTTP/HTTPSリクエストが無料。
- Amazon SNS: 100万件のリクエストと1,000件のメール配信が毎月無料で利用可能。
- Amazon SQS: 100万件/月のリクエストが無料。
- AWS CodeCommit: 月あたり5アクティブユーザー、50GBのストレージサイズが無料。
- Amazon Cognito: 50,000MAU（毎月のアクティブユーザー）が無料で利用可能。
- AWS Glue: 月あたり100万件のAWS Glue データカタログへのオブジェクトの保存が無料で利用可能。


## 無料トライアルの代表的なサービス
- Amazon QuickSight: 30日間の無料トライアルが提供されており、10GBのSPICE容量で最大4人のユーザーが利用可能。
- Amazon SageMaker: 機械学習プラットフォームとして2か月間の無料トライアルが提供されている。
- Amazon WorkSpaces: 40時間までの仮想デスクトップサービスが無料で利用可能。
- Amazon Redshift: 2か月間の無料トライアルで750時間/月のdc2.largeノードが利用可能。



## 注意点
- 無料枠を超えると通常料金が発生するため、使用状況を常に確認することが重要。
- クレジットカード情報の登録が必要だが、制限内であれば料金は発生しない。
- 無料の条件や無料のサービスは、変わる可能性がある。

https://aws.amazon.com/jp/free/
初心者必見：ベイズ理論でデータ分析が劇的に変わる理由とは？

# はじめに
ベイズ的思考は、現代のデータサイエンスにおいて極めて重要な役割を果たしています。

ベイズの定理を中心にしたこの考え方は、データに基づいて信念を更新し、より精度の高い意思決定を行うための強力なツールです。

特にAIや統計分析の分野では、この手法が不可欠となっています。

本記事では、ベイズ理論の基本概念から、その実践的な応用までを解説し、データサイエンスにおけるベイズ的思考の具体的な利点を探ります。

# ベイズ理論の基礎
### ベイズの定理とは？
ベイズの定理は、初期の仮説に新しい証拠を取り入れることで、その仮説の確からしさを更新する方法です。この定理は以下の式で表されます。
![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/556af381-692d-fdf8-5732-f1b4e265a97f.png)
 
ここで重要なのは、事前確率（P(A)）と事後確率（P(A|B)）の概念です。

事前確率は、新しい証拠が得られる前に仮説がどれほど真実であると考えられるかを示し、事後確率はその証拠を踏まえて更新された仮説の確からしさを示します。

### ベイズ的思考の意義
ベイズ的思考は、特に不確実な状況での意思決定において非常に有用です。

ベイズ推論により、データが追加されるたびにモデルを柔軟に更新し続けることができ、その結果、より信頼性の高い予測が可能になります。

この方法は、医療の臨床試験や経済予測、マーケティング分析など、多くの実世界の応用において大きな価値を提供しています。

# ベイズ理論の応用
### 1. ベイズ推論
ベイズ推論は、既知のデータと新しいデータを組み合わせて、より確実な結論を導く手法です。

例えば、臨床試験で新薬の効果を評価する際、ベイズ推論を用いることで、過去のデータと現在の試験結果を統合し、治療の有効性に対する確信度を高めることができます。

このプロセスは、従来の統計手法とは異なり、より柔軟で適応的なモデルを構築することが可能です。

### 2. 予測モデリングと不確実性の定量化
ベイズモデリングは、予測モデリングにおいても強力なツールです。

従来の手法が単一の予測値を提供するのに対し、ベイズアプローチは予測結果の信頼区間を提供し、その予測がどれだけ信頼できるかを定量化します。

これにより、例えば株価の予測において、投資家はリスクをより適切に評価し、より賢明な投資判断を下すことが可能となります。

また、ベイズモデリングはデータの不確実性を扱うため、従来の決定論的なモデルよりも現実的なシナリオを想定できます。

これにより、極端なシナリオに対してもロバストな予測が可能となり、実務的な意思決定において大きな利点を提供します。

### 3. ベイズニューラルネットワーク
ベイズニューラルネットワーク (BNN) は、ニューラルネットワークにおける不確実性の管理を可能にします。

BNNを使用すると、モデルの出力に対して確率的な解釈が可能となり、予測の信頼性を数値化することができます。

これにより、たとえば詐欺検出のようなタスクにおいて、従来の手法よりも高い精度で異常検出が可能となります。

BNNは、金融、医療、製造業など、さまざまな分野で重要な役割を果たしています。

## ベイズ的思考をサポートするツール
ベイズ的思考を実践に取り入れるためのツールも充実しています。

以下に、いくつかの代表的なツールとその特徴を紹介します。

- **PyMC**: PyMCはPythonでベイズモデリングを行うための強力なライブラリです。最新バージョンではJAXとの統合が進んでおり、計算速度とスケーラビリティが大幅に向上しています。これにより、大規模なデータセットや複雑なモデルを扱う際にも、高速かつ効率的なベイズ推論が可能です

- **Stan**: StanはC++で実装された確率的プログラミング言語で、複雑な統計モデルを効率的に推論することができます。特に、RやPythonとのインターフェースが用意されており、学術研究や産業界で広く利用されています。Stanの特徴は、その高速性と精度の高さにあり、多くの実務において信頼されるツールとなっています

- **TensorFlow Probability**: TensorFlow Probability (TFP) は、TensorFlowと統合されたライブラリで、確率的推論と統計的分析をサポートします。TFPを使用すると、ディープラーニングとベイズ推論をシームレスに組み合わせることができ、AIモデルの信頼性を高めることができます。特に、異常検知やリスク管理といったシナリオにおいて、TFPは優れたツールです

これらのツールを活用することで、ベイズ的思考を日常のデータ分析に取り入れることが容易になります。

これにより、より洗練された分析結果を得ることができ、データドリブンな意思決定の質を向上させることが可能です。

## ベイズ線形回帰の実例

ここでは、ベイズ線形回帰を実行するためのサンプルコードを紹介します。

このコードを使用することで、実際にベイズ的思考を体験することができます。

```python
import pymc as pm
import numpy as np
import matplotlib.pyplot as plt

# サンプルデータの生成
np.random.seed(123)
X = np.random.rand(100)
true_intercept = 0.5
true_slope = 3.0
noise = np.random.normal(0, 0.3, size=100)
y = true_intercept + true_slope * X + noise

# モデルの定義
with pm.Model() as linear_model:
    alpha = pm.Normal('alpha', mu=0, sigma=10)
    beta = pm.Normal('beta', mu=0, sigma=10)
    sigma = pm.Exponential('sigma', 1.0)
    
    mu = alpha + beta * X
    y_obs = pm.Normal('y_obs', mu=mu, sigma=sigma, observed=y)
    
    # サンプリング
    trace = pm.sample(3000, return_inferencedata=True)

# 結果のプロット
pm.plot_trace(trace)
plt.show()

# 結果の要約
print(pm.summary(trace))
```

# まとめ
ベイズ的思考は、データサイエンスの領域で革命的な変革をもたらしています。

事前の信念と新たな証拠を統合することで、データに基づくより正確で信頼性の高い意思決定を行うことが可能です。

また、ベイズ的思考をサポートするツールを活用することで、日常の分析業務においてその威力を発揮させることができます。

これからのデータサイエンスにおいて、ベイズ理論はますます重要な役割を果たすことでしょう。
UE5 TPS作成１

# UE5にMixamoからキャラをインポートする
今回はTPSを作るうえで必要なキャラクターをMixamoというサービスからもらってきて、UE5で配置する。

作成環境
blender 2.9
UE5 5.2

完成図
UE5内で、Idle状態のキャラを配置する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858651/b9b7f8bb-1823-5ee9-ebd2-c73af27e4b9f.png)


## 1.Mixamoからキャラをアニメーション付きで出力

### 1　Mixamoにログインする
https://www.mixamo.com/#/?page=1&query=idle&type=Motion%2CMotionPack

### 2 Characterを選びアニメーションをつける
キャラを選ぶ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858651/4184d527-b440-1f00-b5e5-771b1370a420.png)

1. animationsを開く
2. idleを選択する
3. Downloadを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858651/d51d6549-806b-73f3-1b2b-c16c503fa68e.png)


そのままの設定でダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858651/11b416ef-2ffd-95c0-2188-f6ebb78fa4d7.png)

## 2.Blender2.9でUEでアニメーションが動作出来るようにする
### 1.コンバーターダウンロード
下のサイトからコンバーターダウンロード
https://github.com/enziop/mixamo_converter

### 2.Blenderに追加

1. 「編集/プリファレンス/アドオン」からタブを開く
1.  インストールから先ほどのファイルをzip形式で選択
1.  チェックボックスにチェックを入れ有効化する

![スクリーンショット 2024-09-06 225730.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858651/12f007a2-6034-9d19-9aa0-715b1c65b8db.png)

### 3.プラグインで変換
1.プラグインを開く（右側に隠れている）
2.詳細オプションを開き、UseZを無効化する
3.Input Pathに先ほどMixamoからダウンロードfbxファイルが入っているPathを選択
4.出力パスには出力されるfbxファイルを格納する場所を指定
5.Batch Convertで変換

![スクリーンショット 2024-09-06 230524.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858651/325b9055-500a-85bb-79f1-be63c117da5b.png)

## 3.UE5にインポート
1.キャラクターを追加したいプロジェクト起動
2.UE5に変換後のfbxファイルをドラック＆ドロップ
3.import Animationにチェックをつける
4.Animation LengthをAnimation Timeにする
5.Import Allでアニメーション付きのキャラをインポート

![スクリーンショット 2024-09-07 075641.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858651/9dff7588-6227-0c14-64d2-8138e27628f8.png)

上記だけだとMaterialが剝がれた状態になってしまうため、Materialも別でインポート
1.UE5に変換前のfbxファイルをドラック＆ドロップ
2.Skeltal Meshのチェックを外しImportAllを実行
3.Materialがインポートされるため、名前の通りに、キャラにアタッチする
![スクリーンショット 2024-09-07 081558.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858651/35e5a486-d328-57a2-a5c0-d05406901207.png)

以上で下のようにAnimation可能なCharacterが追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858651/b9b7f8bb-1823-5ee9-ebd2-c73af27e4b9f.png)

読んで下さり、ありがとうございました！
薬剤師がエンジニアになるためにまずやったこと

はじめまして。
和（かず）と申します。

２０２４年1月から薬局ベンチャーへ就職して
開発エンジニアをしながら薬剤師として働いています。

今回は私がエンジニアになるために最初に行ったことを紹介したいと思います。

# まず何をすればいいのか
現役エンジニアの方々が口を揃えていうのは
『まずは何か作ってみるといい』

とは言われても何をすればいいのかわからない。
何かを作る前に私がまず行なったことは2つあります

***
### 開発環境を構築する

私はDockerを利用した開発環境の整え方について勉強しました。
Dockerとは「コンテナ型の仮想環境を作成、共有、実行するためのプラットフォーム」です。

なんのことやらとわからない方
Dockerについて知りたい方は他の方の記事ですが[こちら](https://qiita.com/S4nTo/items/977d28b0eac316915702)をご確認ください

導入と学習のメリットとしては
ローカル環境を汚さずに、従来の仮想環境に比べて軽量に起動が可能となります。

学び方は本を買うでもWebサイトから学ぶでもなんでもいいと思います。
私は下記本を用いて学習しました。
【[仕組みと使い方がわかる Docker&Kubernetesのきほんのきほん](https://www.amazon.co.jp/%E4%BB%95%E7%B5%84%E3%81%BF%E3%81%A8%E4%BD%BF%E3%81%84%E6%96%B9%E3%81%8C%E3%82%8F%E3%81%8B%E3%82%8B-Docker-Kubernetes%E3%81%AE%E3%81%8D%E3%81%BB%E3%82%93%E3%81%AE%E3%81%8D%E3%81%BB%E3%82%93-%E5%B0%8F%E7%AC%A0%E5%8E%9F%E7%A8%AE%E9%AB%98/dp/4839972745)】
【[Dockerをインストール](https://matsuand.github.io/docs.docker.jp.onthefly/get-docker/)】

***
### [Ruby on Rails Tutorial](https://railstutorial.jp/)で学習を行う

Rubyは日本で作られた言語であり、Railsといった
全てをインテグレーションされたフレームワークが備わっており
応用力が高いことから、幅広い職種のエンジニアから高い人気を得ています。

コミュニティも多くあり
独学で学習するのに適している言語と私自身考えています。

Ruby on Rails Tutorialでは
一からWebアプリを作成する手順を学習できます。

最初にこれをやることに関しては賛否分かれるかもしれませんが、知識が全くない私にとっては非常に効率よく学ぶことができました。

Railsについてもっと詳しく知りたい方はRailsの生みの親である[DHH氏が語るRailsの強みについての動画](https://youtu.be/wzBCGHmv-jY)を拝見していただくといいかもしれません。

# 何かしら作ってみる

環境構築とある程度の知識を学んだら何かしら作ってみるのが良いかもしれません。

とはいっても何を作れば良いのやらと思うかもしれません。

私は自社のRubyで構築されたプロダクトのPullRequestsを見て同様のものを作成してみなさいと指示をもらってサーバー構築からコードリードとコードを書くといったすべての開発工程を学習できました。（正直これは難易度高いかも）

なので、まずは多くのエンジニアが行っているように、LINEのおうむ返しbotを作成するのが良いかもしれません。

ググればすぐにやり方は出てくるのでそれ通りに作成していきながら、コードを理解していくと良いかもしれません。

# 終わりに

私は上記の２つをまず行うように言われましたが、人によってはまず最初に何か作るほうが良いという方もいらっしゃるかもしれません。

ここで伝えたいことは始め方に正解はないので、始め方ではなく学んでいく姿勢とコードをしっかりと理解することの方がよっぽど重要だということです。

こんなことを記載しながらも私自身まだまだ初学者に毛が生えたくらいなので、皆さんでともに学習していきましょう。
【laravel】soleとかいうじゃじゃ馬

いつの間にか追加されていた `sole()`  
この間 `sole()` メソッドでひと悶着あったので、使い方を調べておく。

https://readouble.com/laravel/11.x/ja/collections.html#method-sole

## `sole()`

> soleメソッドは、指定した真偽テストをパスしたアイテムが正確に１つだけの場合、コレクション内の最初の要素を返します。

だそうで。
要するに、Eloquentで検索をかけたとき、要素が1つだけのときは `first()` の挙動、
それ以外の時は例外を吐く面白い関数。

※ ちなみに Eloquent と Collection で使用可能

```php
> collect([1, 2, 3])->sole()
   Illuminate\Support\MultipleItemsFoundException  3 items were found.
   
> collect([1])->sole()
= 1

> collect([])->sole()
   Illuminate\Support\ItemNotFoundException  
```

面倒な点がこやつ、例外を吐いてくるんですよ！
それを知らなかったので、偶然複製されたデータに無限に引っ掛かっていた...

どの用途で使うのが良いのだろうか...

正直、`count()` `first()` でハンドリングしたほうが綺麗に書けるのではないか？

これを使わなければ！という場面が思いつかない...
ネットで調べても、soleの紹介のみで使い方の議論が無いのだが！
まぁ確実に1つしかないことを保証できるので、不用意な処理は防げそう...  






## ソース

ここで終わっても面白くないので、実装を見に行く。  
実装、二つで違うんだ...  

### Eloquent 

[https://github.com/laravel/framework/blob/11.x/src/Illuminate/Database/Eloquent/Builder.php#L673
](https://github.com/laravel/framework/blob/11.x/src/Illuminate/Database/Eloquent/Builder.php#L673
)

これは内部で `BuidsQueries.php` の trait を呼んでる。  
本体がこいつ

[https://github.com/laravel/framework/blob/11.x/src/Illuminate/Database/Concerns/BuildsQueries.php#L355](https://github.com/laravel/framework/blob/11.x/src/Illuminate/Database/Concerns/BuildsQueries.php#L355)

```php
    public function sole($columns = ['*'])
    {
        $result = $this->take(2)->get($columns);

        $count = $result->count();

        if ($count === 0) {
            throw new RecordsNotFoundException;
        }

        if ($count > 1) {
            throw new MultipleRecordsFoundException($count);
        }

        return $result->first();
    }
```

ははーん、いつものマクロみたいな実装なのね。  



### Collection

[
https://github.com/laravel/framework/blob/11.x/src/Illuminate/Collections/Collection.php#L1373
](
https://github.com/laravel/framework/blob/11.x/src/Illuminate/Collections/Collection.php#L1373
)

```php
    public function sole($key = null, $operator = null, $value = null)
    {
        $filter = func_num_args() > 1
            ? $this->operatorForWhere(...func_get_args())
            : $key;

        $items = $this->unless($filter == null)->filter($filter);

        $count = $items->count();

        if ($count === 0) {
            throw new ItemNotFoundException;
        }

        if ($count > 1) {
            throw new MultipleItemsFoundException($count);
        }

        return $items->first();
    }
```

あーフィルターって、unless + filter で実現してるんだ。
こちらもマクロ的いつもの実装。



### まとめ

Laravel はソースコードまで全部読めるので、気になったら読みに行くと良い。
めっちゃ勉強になる、というかコアの思想を理解しないときちゃない実装になりがち。

Laravel API 読もう！
Linuxで、AWC-Cliのコマンド補完を設定する

AWSコンプリータがインストールされていることを確認します。
```
which aws_completer
/usr/local/bin/aws_completer
```
　
.bash_profile、.profile、または .bash_loginに以下を追加します。
```
complete -C '/usr/local/bin/aws_completer' aws
```
※　「complete」はbashでコマンドラインの「補完」を行う方法を指定するコマンドです。

 　
 以下のコマンドを実行し、.bash_profile、.profile、または .bash_loginの設定を反映します。
 ```
 source .bashrc
 ```

 以上です。
【vite×Jest】テスト実行時にTypeError:* is not a functionというエラー

# はじめに
jestのエラーでハマりましたので解決法を共有します。

# 問題
タイトルの通り、「TypeError: setIsLoadingOverlay is not a function」というエラーが出てテストが通らない。

### 問題のコード
```tsx:Settings.test.tsx(中略)
describe("登録テスト", () => {
  test("[正常系]登録処理が正常に動作すること", async () => {
    // 実行
    render(<Settings />);

    // 入力
    const token = "test-api-key";
    const apiInput = screen.getByTestId("qiita-api-input");
    await userEvent.type(apiInput, token);
    // 登録
    const registButton = screen.getByTestId("regist-button");
    fireEvent.click(registButton);

    // 検証
    await waitFor(async () => {
      expect(DB.registQiitaAPIKey).toHaveBeenCalledTimes(1);
      expect(DB.registQiitaAPIKey).not.toHaveBeenCalledWith(token);
    });
    expect(apiInput).toHaveValue("");
  });
```

### テスト対象コード(+の箇所でエラー)
```diff_tsx:Settings.tsx(中略)
  // 登録
  const registQiitaAPIKey: SubmitHandler<{ token: string }> = useCallback(
    async ({ token }) => {
+      setIsLoadingOverlay(true);
      setIsRegistering(true);
      await DB.registQiitaAPIKey(Util.encrypt(token));
      displayMessage({ title: "登録が正常に完了しました。", status: "success" });
      setIsRegistering(false);
      setIsLoadingOverlay(false);
      reset({ token: "" });
    },
    [setIsLoadingOverlay, displayMessage, reset]
  );
```

# 解決方法
setIsLoadingOverlayはContextで定義した関数であるため、テスト時にrender関数でProviderをラップしないと読み込まない。
### 解決時のコード
```diff_tsx:Settings.test.tsx(中略)
describe("登録テスト", () => {
  test("[正常系]登録処理が正常に動作すること", async () => {
    // 実行
+    render(<Settings />, { wrapper: LoadingProvider });
    // 入力
    const token = "test-api-key";
    const apiInput = screen.getByTestId("qiita-api-input");
    await userEvent.type(apiInput, token);
    // 登録
    const registButton = screen.getByTestId("regist-button");
    fireEvent.click(registButton);

    // 検証
    await waitFor(async () => {
      expect(DB.registQiitaAPIKey).toHaveBeenCalledTimes(1);
      expect(DB.registQiitaAPIKey).not.toHaveBeenCalledWith(token);
    });
    expect(apiInput).toHaveValue("");
  });
```
render関数の第二引数にはテストしたいコンポーネントをラップするためのコンポーネントを指定できるようです。

# おわりに
テストコードをもっとサクサク実装できるようになりたいです。。

# 参考

https://testing-library.com/docs/react-testing-library/api/#render

## JISOUのメンバー募集中🔥
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
気になる方はぜひHPからライン登録お願いします！👇

https://projisou.jp/
Arduino UNO 3で温度センサー、Grove-Temperature_Sensorで遊ぶ


参考

https://wiki.seeedstudio.com/Grove-Temperature_Sensor/


結果

![o_coq374.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a9a5db20-815f-e505-e984-16ce4459c06c.jpeg)


![o_coq372.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f0232d9d-81dd-b757-3107-a3ac95c56667.jpeg)

![o_coq373.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/aaed6b64-4e94-f5c6-354f-4b965881cd32.jpeg)

![o_coq375.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a731fb07-0160-3359-98a3-ce4ad5d3c894.jpeg)


プログラム(サンプルそのまま)


```c++

/*
/* Grove - Temperature Sensor demo v1.0
*  This sensor detects the environment temperature,
*  Connect the signal of this sensor to A0, use the
*  Serial monitor to get the result.
*  By: https://www.seeedstudio.com
*/
#include <math.h>
int a;
float temperature;
int B=3975;                  //B value of the thermistor
float resistance;

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    a=analogRead(0);
    resistance=(float)(1023-a)*10000/a; //get the resistance of the sensor;
    temperature=1/(log(resistance/10000)/B+1/298.15)-273.15;//convert to temperature via datasheet&nbsp;;
    delay(1000);
    Serial.print("Current temperature is ");
    Serial.println(temperature);
}



```
UIイベントハンドリング

モバイルアプリやWebアプリを開発する際に避けて通れないのが「イベント」の概念です。イベントとは、ユーザーがアプリ上で行う操作（タップ、スワイプ、クリックなど）やシステムの通知（ページの読み込み完了、データ受信など）を指します。アプリはこれらのイベントを検出し、それに応じた処理を行うことで、インタラクティブな動的体験を提供します。

ここでは、UI操作のイベントにフォーカスして、UIイベントハンドリングの基本知識について整理したいと思います。

### Gesture Recognizer

アプリでUIイベントを処理するためには、まずイベントが発生したことを認識しなければなりません。これを自前で行うために必要なのが「Gesture Recognizer」(ジェスチャーリコグナイザ）です。ユーザーのタップやスワイプなどの操作を検出し、適切な処理を行うためには、事前にリコグナイザを設定しておく必要があります。これを怠ると、イベントが発生してもアプリは何も反応しないままとなってしまいます。したがって、イベントが発生する前にGesture Recognizerをセットしておく必要があります。

### GestureDetectorの例

Flutterでは、例えば、`GestureDetector`というウィジェットを使うことで、タップやスワイプ、ドラッグといった操作を簡単に認識し、それに応じた処理を記述することができます。

```dart
GestureDetector(
  onTap: () {
    print('タップされました');
  },
  child: Container(
    color: Colors.blue,
    width: 200,
    height: 200,
  ),
)
```

上記のコードでは、青いボックスがタップされたときにコンソールに「タップされました」と表示されます。

### イベント伝播とFlutterの階層構造

Flutterにおけるイベントハンドリングのもう一つの重要な概念が「イベントの伝播（バブリング）」です。イベントが発生すると、そのイベントはウィジェットツリー（widget tree）に沿って親ウィジェットへと伝わります。これを「バブリング（bubbling）」と呼び、特定のウィジェットで処理されなかったイベントが、さらに上位の親ウィジェットに伝わり、最終的にはルートウィジェットまで伝播する可能性があります。

この伝播を活用することで、例えば親ウィジェット全体で同じイベントを一括して処理したり、特定のウィジェットでのみイベントを消費させて、それ以上伝播させないようにすることが可能です。バブリングの制御には、適切にイベント処理の優先順位を設計することが求められます。

### イベント消費の考え方とFlutterの実装

イベント消費とは、あるウィジェットでイベントを処理した際、そのイベントがそれ以上他の要素に伝播しないようにすることです。これにより、不要な重複処理を避けたり、予期せぬ挙動を防ぐことができます。

例えば、ドラッグ中にタップイベントを無視したい場合、タップイベントがドラッグの開始時点で消費されていなければ、タップとドラッグが競合する可能性があります。こうした状況では、事前にジェスチャーリコグナイザをセットアップし、どのイベントがどのタイミングで消費されるべきかを設計することで、アプリの動作をスムーズに保つことができます。

### `preventDefault` に相当するFlutterのアプローチ

Web開発においては、`preventDefault`を使うことで、デフォルトのイベント動作を無効にし、カスタムの処理を実装することが一般的です。Flutterでも、似たようなアプローチを取り、デフォルトの動作を抑制しながら独自の処理を組み込むことが可能です。

たとえば、ユーザーがテキストフィールドに入力したときに、デフォルトの動作を無効化して、別のアクションをトリガーしたい場合があります。FlutterのTextFieldは、デフォルトでテキストの入力や編集を提供しますが、特定のキー入力に応じたカスタム処理を行いたい場合、デフォルトの動作を無効化し、そのタイミングで別のアクションを実行することが可能です。これを実現するためには、RawKeyboardListenerを使い、テキストフィールドへの入力に対してキーイベントをキャプチャしてカスタムアクションを実装します。

### ドラッグ開始後にGesture Recognizerを仕掛けてもハンドリングできない理由

イベント処理の中でも、特にドラッグ操作に関して「なぜドラッグ開始後にGesture Recognizerを設定してもイベントがハンドリングされないのか」について説明します。これには、イベントのライフサイクルが深く関係しています。

イベントが発生すると、システムはそのイベントのライフサイクルを管理します。例えば、ユーザーが画面をドラッグすると、最初に「タッチダウン」イベントが発生し、その後「ドラッグの移動（move）」イベントが続きます。この一連のイベントは、最初のタッチダウン時点でどの要素がイベントを処理するかが決定されます。つまり、タッチダウン後にGesture Recognizerを追加しても、既に進行中のイベントには反応できないのです。

この動作の背景には、イベントの「キャプチャリング（capturing）」という概念があります。タッチダウン時にキャプチャされたイベントは、その時点でどのリスナーがそのイベントを受け取るかを決定しており、進行中のイベントに対しては、新たに追加されたGesture Recognizerが割り込むことはできません。

前述のとおり、イベント発生前に仕掛けておく必要があるのです。
Qiitaにかつてあった笑える釣り記事


https://web.archive.org/web/20190510201805/https://qiita.com/alice1992/items/630662ef7238e60a811e

後日に書かれるこの記事のためのフリ

https://web.archive.org/web/20190523211118/https://qiita.com/alice1992/items/33b5b9ae9473c1903b90

ユーザーのアイコンは多分拾い物
【論文メモ #7】労働力の流動性って重要なのか

# はじめに
労働市場の流動性と経済パフォーマンスの関係に関する論文を読んだメモです。

具体的にはこちらの論文です。
Davis, Steven J., and John Haltiwanger. Labor market fluidity and economic performance. No. w20479. National Bureau of Economic Research, 2014.

読みたいなと思った背景としては、「転職」って流行っているけれど企業の目線に立つとポジティブなのかネガティヴなのか、どっちの要素もあるよな〜と疑問を持ったためです。

# メモ
## 要旨
- アメリカの労働市場における「流動性の低下」が、生産性、賃金、雇用に悪影響を与えている
- 具体的には、1990年以降、転職や職場の再配置といった労働市場の動きが大きく減少し、特に若年層や低学歴層でその傾向が強いことが報告されています。この流動性の低下には、高齢化や政策の影響が関わっており、特に小売業などでは顕著です
- 労働市場の流動性が低下すると、労働者がより適した職場に移動しにくくなり、その結果、全体の生産性が下がります。また、職の移動が少なくなると、賃金の伸びも鈍化し、失業率が上がりやすくなるため、雇用状況が悪化します。これは、特に若年層や低学歴層にとって深刻な影響を与えています
- 結論として、リーマンショック以前から、アメリカ経済は高い雇用率を維持するのが難しくなっており、労働市場の流動性を回復しなければ、持続的な高い雇用率の達成は難しいということです。
(ABC368)C - Triple Attack と pop vs pointerの速度の話

## はじめに
ABC368のC問題です。
またしてもTLE（実行時間制限超過）が発生させて
ハマった話です。

https://atcoder.jp/contests/abc368/tasks/abc368_c

## 自分の回答（1回目）

```py:ABC368_C_1.py
N = int(input())
E = list(map(int,input().split()))
T = 0
while E:
  while E[0] > 0:
    if E[0] >= 5:
      T += 3
      E[0] -= 5
    else:
      T += 1
      if T % 3 == 0:
        E[0] -= 3
      else:
        E[0] -= 1
  E.pop(0)

print(T)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296985/6e934426-b779-30df-ac78-e6b05cbe3845.png)

これは想定内です。
入力値が
$1≤N≤2×10^5$
$1≤H≤10^9$
ですから。計算量は $O(10^{14})$ であろう。

## 改善その１
すこし考えます。
$T$を3つセットで考えると、$(1,1,3)$、$(1,3,1)$、$(3,1,1)$のいずれの並びも$H$の体力を$5$減らせられるので、$H$が$5$以上の場合は、まとめて考えることができる。

```py:ABC368_C_2.py
N = int(input())
E = list(map(int,input().split()))
T = 0
while E:
  while E[0] > 0:
    if E[0] >= 5:
      T += E[0] // 5 * 3
      E[0] = E[0] % 5
    else:
      T += 1
      if T % 3 == 0:
        E[0] -= 3
      else:
        E[0] -= 1
  E.pop(0)

print(T)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296985/af5be150-1c92-936c-35fc-d336f285f079.png)

これはショックでした。
最大で計算量を$1/5$にしたと思ったのに。

ここでしばらく思考停止。

## 改善その２
ここでふと`pop`か？
配列の削除って処理遅いのかもと思い、`pop`をやめてみる。

```py:ABC368_C_3.py
N = int(input())
E = list(map(int,input().split()))
T = 0
for i in range(len(E)):
  while E[i] > 0:
    if E[i] >= 5:
      T += E[i] // 5 * 3
      E[i] = E[i] % 5
    else:
      T += 1
      if T % 3 == 0:
        E[i] -= 3
      else:
        E[i] -= 1

print(T)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296985/f166ef58-8a48-e363-fc2e-2b75f0ffb3f2.png)

無事通過です。

## 追加検証（popとポインタ移動の速度比較）
生成AIと一緒に検証してみる。
```py:popとpointerの速度検証
import timeit
import random

def test_pop_vs_pointer(list_size):
    test_list = [random.randint(1, 100) for _ in range(list_size)]
    
    # pop(0)の速度を測定
    pop_time = timeit.timeit(
        lambda: test_list.pop(0) if test_list else None,
        number=list_size
    )
    
    # ポインタを動かす速度を測定
    pointer_time = timeit.timeit(
        lambda: [test_list[i] for i in range(min(list_size, len(test_list)))],
        number=1
    )
    
    return pop_time, pointer_time

# テストするリストのサイズ
list_sizes = [10, 100, 1000, 10000, 100000]

print("リストサイズ | pop(0)の時間 | ポインタ移動時間 | 差")
print("-" * 55)

for size in list_sizes:
    pop_time, pointer_time = test_pop_vs_pointer(size)
    time_difference = pop_time - pointer_time
    print(f"{size:11d} | {pop_time:10.6f} | {pointer_time:10.6f} | {time_difference:10.6f}")
```
結果

リストサイズ | pop(0)の時間 | ポインタ移動時間 | 差
------------:|-------------|-----------------|-
|         10 |   0.000006 |   0.000005 |   0.000001
|        100 |   0.000025 |   0.000004 |   0.000021
|       1000 |   0.000313 |   0.000006 |   0.000307
|      10000 |   0.009507 |   0.000006 |   0.009501
|     100000 |   0.949552 |   0.000010 |   0.949542

一目瞭然ですね。

## おわりに
計算の部分に注目しすぎてハマってしまったという話でした。

Pythonの知識が１つ増えました！
M5AtomS3で黒電話のダイヤルを検知させてみた 

# はじめに

友人の作った[ダイヤルを回せ！](https://protopedia.net/prototype/5490)に感化されたのと、SPAJAMで使えたらいいよねということで黒電話を購入。
メルカリでクーポン使って1,000円以下というかなりお安くGET！
で、ダイヤルを検知できないと何もできないよね、ということでやってみた。

友人の以下の記事を参考にしてます。

https://qiita.com/macha1972/items/d1e84a9de348fdfd3427

なお、回路とかよくわからないことと、M5 Atom S3というか各ポートもよく理解していない(がさすがにグランドはわかる)のでおかしなところがあるかもしれないので、優しく指摘してくださいｗ


# 考え方

以下の考え方で実装しているつもり
実装はUIFlow2のブロックエディタで行った。
コードで書けばよかったかなと後からちょっと後悔

![dial.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/dd934568-30e0-a52f-c522-6eb13f02e5f7.png)


今回使っている黒電話は600-A1で、[こちら](https://note.com/ipower/n/n77b39623a8bc#dc3155db-7e30-42ca-abab-be77a7b4d027)の記事によると、1秒間に10パルス信号を発生させるらしい。

# コード

考え方の図はブロックエディタで処理を構成してから考えをまとめるために作成
その後、コードに反映。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/505dab5f-c5a6-61f2-3f50-6179fbf6ba3a.png)


ちなみに以下を試してみて、アナログ入力&デジタル入出力でできたので、それを採用

|パターン|結果|
|--|--|
|アナログ入力のみ|値が取れない|
|デジタル入力出力のみ|受話器は取れるダイヤルのパルスを拾いきれない。ゆっくりダイヤルを回すと取れるので拾えてなさそう|
|アナログ入力&デジタル入出力|デジタル化された値がアナログで取れてるようでうまくいった|

# M5AtomS3と黒電話の接続

以下のようにG1とグランドに接続

![P_20240907_021249.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/6637c73d-8680-c43f-7ca8-ef49e8920f61.jpeg)

ちなみに、電話から赤と白の線がでいるが、赤とG1、白とグランド、赤とグランド、白とG1のどちらでもいいみたい。

# ポイント

アナログ+デジタルにする際、初期化をアナログ→デジタルで行う。
逆にすると、値の取れ方がおかしくなった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/bf5dd0ec-c999-6d79-a024-cb6380359266.png)
（これ、あってる？）

# 今後
まず、UIFlowで作った処理を考え方に沿ってもう少しスリムにしたい。
もう、アナログだけ、デジタルだけの処理は消そうかな・・・
AndroidとBluetoothで接続して、値だけ転送する。
ダイヤルの入力判定等はAndroid側で行うようにしたい。
あと、アナログ入力有効使っているときに、受話器から音が聞こえるので、音出せたら面白いよねーって考えているけど、どうすべきかわからない

# 追記
気になったので画面に簡易的なグラフを出して確認。
デジタル入力出力の時にゆっくり回すとダイヤルを認識した理由が気になったので。
とはいえ状況証拠だけなので何ともですが。

通常のダイヤルの場合、出力される値が最大値の半分未満っぽい
ゆっくり回すと周波数が大きくなる

認識できなかったことと、上記を踏まえると、M5AtomS3側か黒電話側の問題かわからないが、波形の立ち上がりが遅い、または弱い為、認識できないのではないかと思われる。

別の黒電話で試したいところ。

# この記事の続き

https://qiita.com/krohigewagma/items/71367bb98934be59a37f
Ubuntu/Debian のフレッツ光網内でアクセス可能なミラーをつくってみた (東日本)

フレッツ光では最近では一般的に IPoE のネイティブ接続が使われるようになってきました。この場合，インターネットにいくには `HGW→フレッツ光 (NGN) 網内→VNE→インターネット`　というように通ってアクセスすることになりますが，フレッツ光網内に Ubuntu/Debian の APT ミラーを建ててしまえばいいのでは? と思ったのが今回の始まりです。そうすると， `HGW→フレッツ光 (NGN) 網内→ミラー` となり，だいぶ道程を短縮できます。 IPoE は PPPoE ほど混んでいないのが一般的ですが，それでも経由しないで済むなら少し効率的かもしれません。

そこで， APT ミラーを建ててみました。このサーバは東日本のフレッツ光からはインターネットを経由しないでアクセス可能です。

https://deb.i.e-ntt.jp/

もしアクセスできない場合，その環境は IPv6 につながっていません。IPv6 経由でないとこのサービスには利点がありませんが，それでも利用したい場合は以下の代替アドレスを利用してください。

https://deb.menhera.org/

## 使い方
ミラーサーバのドメインを `deb.i.e-ntt.jp` で置き換えます。 `ubuntu-ports` や `debian`， `debian-ports`， `debian-security` などに対応しています。 HTTP/HTTPS どちらでも利用可能です。

```:/etc/apt/sources.list
deb http://deb.i.e-ntt.jp/ubuntu noble main restricted universe multiverse
deb http://deb.i.e-ntt.jp/ubuntu noble-updates main restricted universe multiverse
deb http://deb.i.e-ntt.jp/ubuntu noble-backports main restricted universe multiverse
deb http://deb.i.e-ntt.jp/ubuntu noble-security main restricted universe multiverse
```

`apt update` が正常に動作することを確認してください。

## インストーラISOイメージ

* Ubuntu: https://deb.i.e-ntt.jp/ubuntu-releases/
* Debian: https://deb.i.e-ntt.jp/debian-cd/

## おまけ
このサービスは，東日本のフレッツ光を直に利用しているので，フレッツ光さえあればインターネットを契約していなくても利用可能です。フレッツ光しかない環境でこのサーバから ISO イメージをダウンロードして，インストールしてアップデートやパッケージのインストールまで完結できるようになってしまいました。これがおまけの利点です。

## 感想
ミラーの細かい作り方などは別な記事で良く説明されているものがたくさんあるのでここでは省略しますが，NTT西日本エリアにもあるといいなと思いました。
【Pythonの環境変えた話(25分でできたー)】Anacondaからpyenv + venv + pip

# Anaconda -> pyenv + venv + pip
Pythonの環境変えた話書くので参考になるところがあればうれしいです。（自分はWindowsなのでMac使ってる人には参考にならないかもしれない🙇）

## 動機
「大学の授業でPython使うからAnaconda入れといてね～」となって以降、そのまま約２年anacondaでPythonを使っていました。

ライブラリをインストールする際も「pip install 'ライブラリ名'」のpipをcondaに変えるだけなので当初は不便に感じなかったのですが、たまにcondaではインストールができないものがあったり、その際に入れる方法を調べて下の例のようなコマンドに変更しなければいけなかったりでイライラさせられることが多かったため乗り換えを決意しました。
例：
```shell
# yfinanceを入れるのに必要なコマンド
conda install conda-forge::yfinance
```

(Anacondaでもpipは使えるっちゃ使えるのだが、依存関係の問題でクラッシュする恐れがあるらしい。怖い…)

---

## 手順
1. [Anacondaの削除](#anacondaの削除)
2. [pyenvとpythonのインストール](#pyenvとpythonのインストール)
3. [VScodeの設定](#vscodeの設定)
4. [仮想環境の作成と利用](#仮想環境の作成と利用)
5. [まとめ](#まとめ)

---

## Anacondaの削除
- 「コントロールパネル」から「プログラム」→「プログラムと機能」へ移動
- リストからAnacondaを選択し、アンインストールをクリック
- 余計なフォルダの削除
  - 以下のフォルダを確認し、存在する場合は手動で削除する
    - C:\Users\あなたのユーザー名\Anaconda3
    - C:\Users\あなたのユーザー名\.conda
    - C:\Users\あなたのユーザー名\.anaconda
    - C:\Users\あなたのユーザー名\.jupyter
    - C:\ProgramData\Anaconda3
- Pathの設定（私の場合必要なかったです）
    - 「システムのプロパティ」→「環境変数」に移動し、PATH変数からCondaやAnacondaに関連するものがあれば削除

---

## pyenvとpythonのインストール
以下の動画を参考に「pyenv」と「python」をインストール
https://www.youtube.com/watch?v=r4SkIhQThe0&t=232s

### 注意事項
pyenvをインストールした際、一度Windows PowerShellの画面を閉じて再度開かないとpyenvコマンドが反応しない場合あり

---

## VScodeの設定
VScodeを開いてインタープリタを選択するだけ。
（自分の場合既存の拡張機能をそのまま利用できました）
仮想環境を使わないのであればこの状態で問題なく利用できると思います。

---

## 仮想環境の作成と利用
プロジェクトごとに仮想環境を作るというのは個人的に好みではなかったので、「仮想環境の集まり」のようなものを作って適宜利用できるようにしました。
### 作成手順
- どこかしらにvenvsというディレクトリを作る
（私はホームディレクトリの下に作りました）
- venvsに移動
```shell
cd ~/venvs
```
- 仮想環境を作成
```shell
# 仮想環境に使いたいpythonのバージョン（3.11.1）を指定
pyenv global 3.11.1
# 仮想環境作成
python -m venv '仮想環境の名前'
```
- 欲しいライブラリをインストール
```shell
# pipでインストール（今回はnumpy）
pip install numpy
```
### 作成した仮想環境をVScodeで有効化
- 設定を開く（「Ctrl + ,」を押す）
- 検索バーに「venv」と入力
- 「Python: Venv Path」に仮想環境が保存されているディレクトリ(~/venvs/)を追加
- インタープリタを選択する際に仮想環境のリストも表示されるようになるので選択したら使えるようになります
---

## まとめ
いかがでしたでしょうか。
この作業工程はほとんどChatGPTが考えてくれました。最近は調べたうえで回答を生成してくれるので便利ですね。初めての記事で読みずらいところもあったと思いますがここまで読んでくださり、誠にありがとうございました。
【Nuxt3】definePropsの分割代入の変数をリアクティブにしたい！

閲覧頂き、ありがとうございます🙇

この記事は `definePropsの分割代入` における、
`リアクティブ状態の保持` のための備忘録です！

# 前提

| name | version |
| - | - |
| Nuxt.js | v3.13.x |
| Vue.js | v3.5.x |

# ざっくり3行まとめ💨

* `propsDestructure: true` にすることで可能
* Vue.js v3.5では、`デフォルトで有効化される`
* Nuxt.js v3.13 上で動かした場合、内部的に Vue.js v3.5 でも`デフォルトで無効`の模様

# 経緯🧐

以下のように親からPropsを渡し、子で分割代入した際にリアクティブが失われる

```Parent.vue
<script setup lang="ts">
const count = ref(0)
const countUp = () => {
  count.value++
}
</script>
<template>
  <div>
    <Child :count="count" />
    <button @click="countUp">カウントアップ</button>
  </div>
</template>
```

```Child.vue
<script setup lang="ts">
const { count } = defineProps<{
  count: number
}>()
</script>
<template>
  <p>{{ count }}</p>
</template>
```

↓↓↓↓↓ 結果 ↓↓↓↓↓

**ボタンを押しても、カウントアップされない状態となる🙅**

# 解決方法📝

`nuxt.config.ts` に `propsDestructure` を設定をする

```nuxt.config.ts
export default defineNuxtConfig({
  vue: {
    propsDestructure: true,
  },
})
```

↓↓↓↓↓ 結果 ↓↓↓↓↓

**ボタンを押して、カウントアップがリアルタイムに反映される🙆**

# 最後に🍵

この設定があることに今日気付いたので備忘録として記事にしました！
設定することでPropsを扱う際に冗長的にならず可読性向上につながるのかなと思います。

また`2024年9月`に [Announcing Vue 3.5](https://blog.vuejs.org/posts/vue-3-5) によると、
こちらの設定が`デフォルトで有効化される`模様でした🙌

> Reactive Props Destructure has been stabilized in 3.5. With the feature now enabled by default, variables destructured from a defineProps call in \<script setup> are now reactive. 
>> Reactive Props Destructureは3.5で安定しました。この機能はデフォルトで有効になり、\<script setup>のdefineProps呼び出しからデストラクトされた変数はリアクティブになりました。

ただNuxt.js上だとやはりまだ設定が必要なようなので、
**今後のアップデートに期待しましょう🙏**

またこちらのアナウンスでは、
**メモリ使用量の大幅改善**や、
`defineProps`での初期値を代入する方法で従来`withDefaults`を使っていましたが、
そちらを使わず、**分割代入内で渡すことが可能**になるようでした！

> ```
> 【Before】
> const props = withDefaults(
>   defineProps<{
>     count?: number
>     msg?: string
>   }>(),
>   {
>     count: 0,
>     msg: 'hello'
>   }
> )
> 
> ↓↓↓↓↓
>
> 【After】
> const { count = 0, msg = 'hello' } = defineProps<{
>   count?: number
>   message?: string
> }>()

まだまだ Vue.js / Nuxt.js の進化が止まらないので今後の情報も楽しみです☺️

# 参考
* [Vue.js - Announcing Vue 3.5](https://blog.vuejs.org/posts/vue-3-5)
* [Nuxt.js - Configuration(Enabling Experimental Vue Features)](https://nuxt.com/docs/getting-started/configuration#enabling-experimental-vue-features)
非同期でSystem.cmdを使ってping砲

# 検証目的
- Task.asyncの検証です
- System.cmdの処理を分散したい
- 待ち時間を減らしたい
- すべて実行するまで待ちたい


# ソース
Task.asyncの有り無しで時間比較します

```elixir
defmodule ConcurrentExperiment do
  @moduledoc """
  Documentation for `ConcurrentExperiment`.
  """

  @doc """
  Hello world.

  ## Examples

      iex> ConcurrentExperiment.hello()
      :ok

  """
  def hello do
    run_ping = :timer.tc(fn -> run_ping() end)
    run_ping_async = :timer.tc(fn -> run_ping_async() end)

    run_ping |> IO.inspect()
    run_ping_async |> IO.inspect()

    {run_ping_time, _} = run_ping
    {run_ping_async_time, _} = run_ping_async

    run_ping_time / run_ping_async_time |> IO.inspect()

    :ok
  end

  def run_ping_async() do
    task =
    1..10
    |> Enum.map(& ping_async("192.168.0.#{&1}"))

    task
    |> Enum.map(& Task.await(&1))
    |> results_output()
  end

  def run_ping() do
    1..10
    |> Enum.map(& ping("192.168.0.#{&1}"))
    |> results_output()
  end

  def transform_output({results, _}) do
    results
    |> String.split(" ")
    |> Enum.at(1)
  end

  def results_output(results) do
    results
    |> Enum.filter(fn {_ , ok} -> ok == 0 end)
    |> Enum.map(& transform_output(&1))
  end

  def ping_async(ip) do
    Task.async(fn ->
      System.cmd("ping",  ~w"-w 1 #{ip}")
    end)
  end

  def ping(ip) do
      System.cmd("ping",  ~w"-w 1 #{ip}")
  end

end
```
# 結果
```
{10056036,
 ["192.168.0.1", "192.168.0.4", "192.168.0.6", "192.168.0.9", "192.168.0.10"]}
{1008590,
 ["192.168.0.1", "192.168.0.4", "192.168.0.6", "192.168.0.9", "192.168.0.10"]}
9.970390346919958
```

約　9.97倍の速度差がでました
これは、ping時に存在しないホストがあると待機するためです
非同期にすることで高速化できます

# ソース(github)
https://github.com/ymn-t-yamanashi/concurrent_experiment
Linuxのディレクトリ構造

# Linuxの攻撃者目線からのディレクトリ構造

攻撃者がシステムに侵入した場合、最初に行うことは、システムの情報を収集して状況を把握することです。攻撃者が確認する重要なディレクトリには、システム構成やセキュリティ情報、ユーザーアカウントなどが含まれている場所が多く含まれます。以下は、攻撃者が通常確認する典型的なディレクトリとその理由です。

## 1. /etc ディレクトリ
理由: システム全体の設定ファイルが格納されており、攻撃者はシステムの構成や設定情報、パスワードファイルを確認します。

よく確認するファイル:
- /etc/passwd: ユーザーアカウント情報を確認するため。これはパスワードが格納されていた古い名残ですが、現在はユーザーアカウント情報が格納されています。パスワード自体は暗号化されており、/etc/shadowに保存されています
- /etc/shadow: 暗号化されたパスワードが格納されています。root権限があれば、ここにアクセスしてパスワードクラッキングを試みることがあります
- /etc/hosts: システムがどのホストと通信しているか、あるいはホストの名前解決設定を確認します
- /etc/ssh/sshd_config: SSHの設定を確認し、リモートログインの設定やポート、認証方法を調べ、SSH経由で持続的なアクセスを確保できるか確認します

## 2. /home ディレクトリ
理由: 各ユーザーのホームディレクトリに個人データや設定ファイル、SSHキー、パスワードファイルなどが保存されているため、攻撃者はここにアクセスしてユーザーデータを盗む、もしくは後続の攻撃手法を探ります。
よく確認するファイル:
- ~/.ssh/: SSHキーが保存されているため、他のシステムへのアクセスが可能かどうかを調べます。id_rsa などの秘密鍵があれば、別のシステムにログインできる可能性があります
- ~/.bash_history: ユーザーが過去に実行したコマンドの履歴を確認します。これにより、ユーザーの行動やアクセスしたリソースを追跡できます
- ~/.profile, ~/.bashrc: ログイン時に実行される設定ファイルです。攻撃者はここに悪意のあるコマンドを追加して、バックドアを仕掛けたり、シェルの動作を改変したりすることがあります
## 3. /var ディレクトリ
理由: ログファイルやシステムの動作に関するデータが保存されているため、攻撃者はログを確認・削除して証拠隠滅を図ります。

よく確認するファイル:
- /var/log: システムのログファイルが保存されており、ここを確認して自身の侵入に関するログが残っていないか、あるいは侵入の痕跡を消すことを試みます。具体的には以下のファイルが重要です：
- /var/log/auth.log（もしくは/var/log/secure）: ログイン認証に関する情報が記録されます。SSH経由の侵入や、root権限の取得を試みた形跡がないか確認できます
- /var/log/syslog: システム全般の動作ログが記録されます。システムの異常動作やアクセスに関する情報がここに記録されている可能性があります


## 4. /tmp ディレクトリ
理由: 一時ファイルを保存する場所として、/tmpはしばしば攻撃者が自分のスクリプトやツールを隠して実行するために使用します。また、他のユーザーとの共有領域としても使われるため、ここで一時的なファイルを操作することが可能です。

使い方:
攻撃者はここにマルウェアやバックドア用のスクリプトを一時的に保存して実行します。/tmpはほとんどのシステムで書き込み可能なディレクトリであり、システム再起動後には自動でクリーンアップされるため、一時的な攻撃やデータ隠蔽に便利です。

## 5. /proc ディレクトリ
理由: システム上で実行中のプロセスに関する情報が格納されています。攻撃者は、システムのプロセスやネットワーク接続情報を調べて、どのようなサービスが動いているか確認します。

よく確認するコマンド:
- cat /proc/cpuinfo: システムのCPU情報を確認して、システムのスペックや性能を把握します
- cat /proc/meminfo: メモリの使用状況を確認して、システムのメモリ状態を把握します
- cat /proc/net/tcp: TCP接続に関する情報を確認して、ネットワーク接続状況や、リモートからの通信を確認します


## 6. /usr ディレクトリ
理由: ユーザーがインストールしたアプリケーションやツールがここに格納されています。攻撃者は、システムにインストールされたソフトウェアを確認し、脆弱性を持つアプリケーションが存在しないか調べます。

使い方:

- /usr/bin: 一般ユーザーが使用できる実行ファイルが格納されています。攻撃者はシステムにインストールされているソフトウェアを確認し、それに関連する脆弱性を利用するかを検討します
- /usr/local: 手動でインストールされたソフトウェアやツールが含まれるため、特にカスタムソフトウェアの存在を確認して、脆弱なものがないかを探ります


## 7. /boot ディレクトリ
理由: システムのカーネルやブートローダーに関するファイルが保存されています。ブートローダーやカーネルを改ざんして、システムの起動プロセスに干渉し、攻撃者が持続的なアクセスを得ることを試みることがあります。

# 攻撃者の行動パターン
1 初期情報収集
- システム情報を収集して、システムのディストリビューション、カーネルバージョン、インストールされているソフトウェアを確認し、脆弱性を探します。uname -a, cat /etc/os-release, ps aux などが使用されます

2 ユーザーアカウント情報の確認:
- /etc/passwd や /etc/shadow を確認して、ユーザーアカウント情報を取得し、特権ユーザーや弱いパスワードがないかを調べます

3 ログイン方法の探索:
- SSHの設定や他のリモートアクセス手段を調べて、持続的なアクセス手段（バックドアやSSHキーの追加など）を確保しようとします

4 証拠の隠滅:

- ログファイルを確認して、自身の活動が記録されていないかをチェックし、証拠隠滅を図ります。具体的には/var/log内のログを改ざん、削除することがあります

# まとめ
攻撃者は、システムへの侵入後に主に以下のディレクトリを確認します。

/etc: システム設定やユーザーアカウント、SSH設定などを確認。
/home: ユーザーの個人データやSSHキー、コマンド履歴などを取得。
/var/log: ログファイルを確認して、侵入の痕跡を隠蔽。
/tmp: 一時的なファイルやスクリプトの格納、実行場所として使用。
/proc: システムのプロセスやネットワーク接続情報を確認。

これらのディレクトリには、システムに関する重要な情報が保存されており、攻撃者はこれを利用してシステムへの持続的なアクセスを試みたり、さらなる攻撃を展開します。
【初心者向け AWS基礎】AWSサービスの料金計算(pricing calculator)

## 使いたいAWSサービスが、月にどれくらい費用がかかるのか

AWSサービスを使うとき、どれくらいの費用がかかるのか、調べるときに使うのが、AWS pricing calculator。

https://calculator.aws/#/

## 使い方

例えば、、
東京リージョンに、EC2にUbuntuサーバを立てる場合の料金を調べるとする。


①オレンジ色の『見積もりの作成』を押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3871776/b8e6b0e6-40d7-b8b7-405a-c825d1c2be7a.png)

②リージョン(東京)とサービス(EC2)を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3871776/d15da3df-1d85-b0a3-6997-4a35aad5da81.png)

③OSやインスタンスファミリー・メモリ等を入力することで、画面下の料金が自動で計算される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3871776/70e650ed-bd05-efd3-9555-3f77c10eef50.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3871776/dd51d538-e432-61b2-8df2-766b2a4c38a1.png)
その言葉は本当に必要ですか？

## 概要
qiita記事も含めた様々な記事を見ていると、よく見かけるけど **この言葉は実はいらないのではないか？** という言葉の存在をいくつか感じる。今日はその中から3つだけ挙げて語ります。私はこれらの言葉を使うことはありません。

### モダン
>〇〇はモダンな～フレームワークです。

記事の書き出し部分とかでよく見かけますね。
qiita記事をなんとなく探し回っていたら、2014年あたりのモダン記事をいっぱいみつけました。モダン、現代的。この記事は2024年に書いています。10年前にモダンだったものを覚えているでしょうか。それは今もモダンでしょうか。
Wikipediaを見てみると「昭和モダン」なんて言葉があります。昭和初期のことなのでそろそろ100年近く前のことです。**100年前はそれがモダンでした。** 
10年以上前の記事でも簡単に見つかる時代です。技術系記事なら特に、10年前のモダンは今もモダンなのか判断に苦しむ。**私が知りたいのはもっと具体的なこと** です。[^モダン文]

### いまさら聞けない
> 聞けないのなら諦めるしかないだろうか

こちらは記事のタイトルでよく使われる言葉ですが、間違いなく **聞けないことを聞かせてくる記事です。** タイトルがウソになるので使うべきではありません。 [^実際]

### ポエム

**詩人にあやまれ**

駄文は駄文。詩じゃありません。詩を愛する者には胸が痛む。[^詩]

## まとめ
この3つの言葉がなくなっても記事を書くのに困ることはないはずです。

[^モダン文]: 大抵の記事はちゃんと具体的な話も書いてあるので、ちょっと揚げ足取りかもしれません。あと海外の記事でもmodernって言葉は使われてますし、訳しただけのケースもありそうです。
[^実際]: いまさら「周りの人には聞けない」的な意味かも知れませんが、聞くは一時の恥、聞かぬは一生の恥なので、「いまさら聞けない記事」を過信することはできません。
[^詩]: 正直に言って侮蔑的に聞こえる。詩ってイメージ悪いのかなぁと落ち込む。
89. Partition List

## solution
before linked listとafter linked listを用意しておいて、x未満のやつはbeforeに連ねていって、x以上のやつはafterに連ねていく。
時間計算量はO(N)
空間計算量はO(1) 使っているのはポインタのための変数だけ。

```
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */

class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        ListNode* before_head = new ListNode(0);
        ListNode* before = before_head;
        ListNode* after_head = new ListNode(0);
        ListNode* after = after_head;

        while(head != nullptr){
            if(head->val < x){
                before->next = head;
                before = before->next;
            } else{
                after->next = head;
                after = after->next;
            }
            head = head->next;
        }
        after->next = nullptr;
        before->next = after_head->next;
        return before_head->next;
    }
};
```

## 最初にやろうとした方針
```
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        ListNode nil = ListNode();
        nil.next = head;
        ListNode* prev = &nil;
        ListNode* prevLeft = &nil;
        ListNode* next = &nil;

        while (head != nullptr){
            next = head->next;
            if (head->val < x){
                prev->next = head->next;
                head->next = prevLeft->next;
                prevLeft->next = head;
                prevLeft = head;
            } else{
                prev = head;
            }
            head = next;
        }
        return nil.next;
    }
};
```

これだと[1,1]でx=2とかの時に失敗する。
【Git】git diffで変更したファイルのみ取得する方法

以下のように実行すると変更したされたファイルのみのリストを取得できます。  

```zsh
git diff --name-only --diff-filter=M
```

逆に変更されたファイルを除外したい場合には`M`を小文字にします。  

```zsh
git diff --name-only --diff-filter=m
```

他のフィルタは以下のとおりです。

| 文字  | 意味                                                               |
| :---: | :----------------------------------------------------------------- |
|   A   | 追加                                                               |
|   C   | コピー                                                             |
|   D   | 削除                                                               |
|   M   | 変更                                                               |
|   R   | 名称変更                                                           |
|   T   | タイプ（通常ファイル、シンボリックリンク、サブモジュールなど）変更 |
|   U   | マージ解除                                                         |
|   X   | 不明                                                               |
|   B   | ペアリング解除                                                     |
【備忘録】Splideのスライダー内の要素に親要素の大きさを適用する

# はじめに
`Splide`のスライダー内の要素に親要素の大きさを適用する備忘録です。
`react-splide`を`Next.js(App Router)`で使用しています。
また、`tailwind css`も使用しています。

# 何が問題だったのか
`h-full`は親要素の大きさをそのまま引き継ぐという仕様上、ライブラリがDOMに吐き出す要素に自分で`CSS`を当てられない場合、その要素の子・孫要素は大元の親要素の大きさを引き継げないという問題が存在しました。

具体的には、`Splide`自体は以下のようなDOMを吐きますが、この内 `splide__track`クラスを持つ`div`要素に`h-full`を当てられないことで大きさを引き継げませんでした。
```html
<section class="splide" aria-label="基本構造の例">
  <div class="splide__track">
    <ul class="splide__list">
      <li class="splide__slide">Slide 01</li>
      <li class="splide__slide">Slide 02</li>
      <li class="splide__slide">Slide 03</li>
    </ul>
  </div>
</section>
```

# コード例
**1.**`Splide`の`hasTrackProps`に`false`を渡す。
**2.**`SplideTrack`コンポーネントを`Splide`コンポーネントの子要素に持たせる。
```tsx
import Image from "next/image";
import { Splide, SplideSlide, SplideTrack } from "react-splide-ts";

export function ImageSliderArea() {
  return (
    <div className="flex-1">
      <Splide className="h-full" hasTrack={false}>
        <SplideTrack className="h-full">
          <SplideSlide>
              <div className="relative h-full">
                <Image
                 src={ImageSrc}
                 alt="EnvHubのスクリーンショット"
                 fill
                 className="object-contain border border-gray-300"
                />
              </div>
          </SplideSlide>
        </SplideTrack>
      </Splide>
    </div>
  );
}
```
# さいごに
`hasTrack props`によってスライダーの矢印等を移動させることも出来るようです。
以下ライブラリのリンクです。

https://ja.splidejs.com/integration/react-splide/
Tanuki-8Bは『雪国』の冒頭をどうトークナイズするのか

日本語LLaMAモデル「[Tanuki-8B](https://huggingface.co/weblab-GENIAC/Tanuki-8B-dpo-v1.0)」が[リリースされた](https://zenn.dev/matsuolab/articles/377f7ae8b1169e)ので、とりあえずトークナイザを試してみた。

```
>>> from transformers import AutoTokenizer
>>> tkz=AutoTokenizer.from_pretrained("weblab-GENIAC/Tanuki-8B-dpo-v1.0")
>>> print(tkz.convert_ids_to_tokens(tkz("国境の長いトンネルを抜けると雪国であった。","夜の底が白くなった。")["input_ids"]))
['▁', '国境', 'の', '長', 'い', 'トンネル', 'を', '抜け', 'ると', '雪国', 'であった', '。', '▁', '夜の', '底', 'が', '白', 'くなった', '。']
```

やはり「ると」や「くなった」でブッタ切られてしまう。このあたり、日本語トークナイザとしては、もう一息だったりする。さて、どうしたものかな。