OmniAICreator/Qiita-1.07M huggingface dataset:
【新機能】3分でわかるdbtのモデルガバナンス【dbt-core v1.5】

# はじめに
この記事では[dbt-core v1.5](https://docs.getdbt.com/guides/migration/versions/upgrading-to-v1.5)で追加された「[モデルガバナンス(Model governance)](https://docs.getdbt.com/docs/collaborate/govern/about-model-governance)」について概要をさっくり説明します。


# モデルガバナンスについて

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/78e50ede-0b09-3d38-9233-93b86f8c1354.png">


4月に公開されたdbt-core 1.5では「[モデルガバナンス(Model governance)](https://docs.getdbt.com/docs/collaborate/govern/about-model-governance)」という機能が追加されました。
モデルガバナンスは3つの機能によって成り立っています。

- [Model access](https://docs.getdbt.com/docs/collaborate/govern/model-access)
- [Model contracts](https://docs.getdbt.com/docs/collaborate/govern/model-contracts)
- [Model versions](https://docs.getdbt.com/docs/collaborate/govern/model-versions)

## Model access
モデルのアクセス制御を行う機能です。モデルの可視性について「public」または「private」のようにマークして、だれがそのモデルを参照できるのかを制御します。
アクセス制御といっても、「だれがテーブル、データにアクセスできるか？」というデータのセキュリティ的な意味ではなく、「だれがモデル定義を参照、拡張できるか？」 という拡張性の観点でのアクセス制御を行います。
（オブジェクト指向プログラミングのアクセス修飾子のようなもの）

[Model access](https://docs.getdbt.com/docs/collaborate/govern/model-access)



<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/47788c18-dd53-f249-537a-45ad03222fed.png">

## Model contracts
モデルのカラムごとにデータ型(int, bool, stringなど)、制約(not nullなど）を定義できる機能です。
この機能があることで、モデルを下流のクエリで再利用するときに発生する型やデータの違いによる問題を抑えることができます。
(Webアプリケーションで例えると、API定義のようなもの)


- [Model contracts](https://docs.getdbt.com/docs/collaborate/govern/model-contracts)


## Model versions
モデルのバージョン管理を行う機能です。
この機能があることで、下流のクエリへの影響を制御することができます。
モデルに破壊的変更をするときに、モデルを新しいバージョンとしてリリースして、下流のモデルに対応の猶予を残したりすることができます。
(Web　APIのバージョンや、パッケージのバージョンと同じようなイメージ）


- [Model versions](https://docs.getdbt.com/docs/collaborate/govern/model-versions)

# モデルガバナンスの何が便利？
dbtモデルを下流のdbtモデルで利用したり、BIツールやスプレッドシートから再利用しているときに、発生する困りごとを解消してくれます。


##  「モデルがありすぎてどのモデルを選んだらいいかわからない！」

=> 「Model access」によって参照できるモデルが限定されます。


##  「依存しているモデルのデータ型や制約がわからない！」
    
 => 「Model contracts」によって明確になります。   

##  「モデルの破壊的な変更変更によって下流のdbtモデル/BIダッシュボードが壊れた！」
  => 「Model versions」によって変更が管理され、スムーズなアップデート作業ができます。

# まとめ

dbt モデルガバナンスでは、「モデルのアクセス制御」、「モデルのコントラクトの定義」、「モデルのバージョン管理」が実現されています。
モデルガバナンスはdbtモデルをチーム間で共有する際に秩序をもたらすための機能です。

以上、参考になりましたら幸いです。


# 参考記事

https://www.getdbt.com/blog/dbt-core-v1.5/

https://docs.getdbt.com/guides/migration/versions/upgrading-to-v1.5

https://github.com/dbt-labs/dbt-core/discussions/6725
RubyでAtCoder ABC252(A, B, C)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC252のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。

# A - ASCII code
https://atcoder.jp/contests/abc252/tasks/abc252_a
```ruby:a-252.rb
puts gets.to_i.chr
```

# B - Takahashi's Failure
https://atcoder.jp/contests/abc252/tasks/abc252_b
```diff_ruby:b-252.rb
gets.split
a = gets.split.map(&:to_i)
b = gets.split.map(&:to_i)

+ taste_max = a.max
- array = a.select.with_index.map{ |taste, index| index + 1 if taste == a.max}
+ array = a.filter_map.with_index(1){ |taste, index| index if taste == taste_max }
puts b.any?{ |dislike| array.include?(dislike) } ? "Yes" : "No"
```
## 解説
最初に「おいしさ」が最大となる食品のインデックスをarray配列にもたせます。そして、bの「嫌いな食品」がarrayに含まれていればYesを、含まれていなければNoを出力します。

# C - Slot Strategy
https://atcoder.jp/contests/abc252/tasks/abc252_c
```ruby:c-252.rb
array = Array.new(gets.to_i){ gets.chomp }

puts [*"0".."9"].map{ |c| array.map{ |str| str.index(c) }.tally.map{ |key, value| key + 10 * (value - 1)}.max}.min
```
## 解説
最初に、0～9の文字それぞれに対して、リールのどこにあるかを取得します。そして、リールに表示されている文字を揃えるために必要な時間（ボタンを押すときの経過時間の最大値）を求めます。求める答えは、それらの最小値となります。

# おわりに
「今回は結構良い感じに書けたんじゃないか？」と１人で喜んでいます。

改善点があればお願いします！

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166
HTML・CSS書くときに使うやつまとめ

## cssの適用方法
### 1. htmlのheadタグにcssへのリンクを書く
```
<link rel="stylesheet" href="static/css/shoma.css">
```

### 2. html内でclassを指定
```
<div class="empty-line">
</div>
```

### 3. css内でclassを指定
```
.empty-line {
padding: 10px;
margin: 10px;
}
```

## 余白
### css
```
.empty-line {
padding: 10px;
margin: 10px;
}
```
## card型

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738475/23d43c15-64fa-d4f3-d925-6efe0ed240f5.png)

### イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738475/da2296f5-27dc-6f82-1f8a-471b9b44f15b.png)

### HTML
```
<div class="eventcard_group">

<div class="eventcard1">
<div class="card border-secondary mb-3" style="max-width: 20rem;">
  <div class="card-header">本科4年・〇〇</div>
  <div class="card-body">
    <h4 class="card-title">是非楽しんで！</h4>
    <p class="card-text">講座を企画した時はインフラが全く分からない状態から始めました。検証を含め沢山苦労しましたが[>
  </div>
</div>
</div>


<div class="eventcard2">
<div class="card border-secondary mb-3" style="max-width: 20rem;">
  <div class="card-header">本科4年・〇〇</div>
  <div class="card-body">
    <h4 class="card-title">是非楽しんで！</h4>
    <p class="card-text">講座を企画した時はインフラが全く分からない状態から始めました。検証を含め沢山苦労しましたが[>
  </div>
</div>
</div>


<div class="eventcard3">
<div class="card border-secondary mb-3" style="max-width: 20rem;">
  <div class="card-header">本科4年・〇〇</div>
  <div class="card-body">
    <h4 class="card-title">是非楽しんで！</h4>
    <p class="card-text">講座を企画した時はインフラが全く分からない状態から始めました。検証を含め沢山苦労しましたが[>
  </div>
</div>
</div>


<div class="eventcard4">
<div class="card border-secondary mb-3" style="max-width: 20rem;">
  <div class="card-header">本科4年・〇〇</div>
  <div class="card-body">
    <h4 class="card-title">是非楽しんで！</h4>
    <p class="card-text">講座を企画した時はインフラが全く分からない状態から始めました。検証を含め沢山苦労しましたが[>
  </div>
</div>
</div>



</div>
```

### CSS
```
.eventcard_group {
display: flex
}

.eventcard1 {
margin: 10px
}

.eventcard2 {
margin: 10px
}

.eventcard3 {
margin: 10px
}

.eventcard4 {
margin: 10px
}
```
Laravel10 マルチ認証 未ログイン時の遷移先の指定

## 対応したときのソース

``` app\Http\Middleware\Authenticate.php
<?php

namespace App\Http\Middleware;

use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Http\Request;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Support\Facades\Auth;

class Authenticate extends Middleware
{    
    protected function unauthenticated($request, array $guards)
    {
        throw new AuthenticationException(
            'Unauthenticated.', $guards, $this->redirectToByGuards($request, $guards)
            );
    }

    /**
     * Get the path the user should be redirected to when they are not authenticated.
     */
    protected function redirectToByGuards($request, $guards) {
        if (!$request->expectsJson()) {
            foreach ($guards as $guard) {
                if ($guard === 'admin') {
                    // guardごとに設定
                    return route('admin.login');
                } else {
                    // 初期設定と同じ
                    return route('login');
                }
            }
        }
    }
}

```


## 参考サイト
https://teratail.com/questions/275008
100問パック完走まであと少し

Python100問パックが残り12問になった。
残るはまとめの12問らしい。

今日で完走しようと思ったらメンテナンス時間になってしまった。
5月中に完走したかったのでちょっと悔しいが、明日でとりあえず一周完走まで行こうと思う。

Google　ColabでやったファイルをGitHubにも保存できるっぽいのでそれをやって今日は終了。

でも5月中に一周走り切ろうと思ってたから本当に悔しいなあ😥
Dockerで簡単なPHPのPlaygroundを作る

# はじめに

ローカルにPHPの実行環境を作るにはXAMPPやMAMP、LAMPといったソフトウェアがまず候補にあがると思います。
しかし、どうせなら、今後のことも考えてDockerを使いたいという思いもあると思います。

ここではDocker + Apache + PHP + MySQL + phpMyAdminで簡単な環境構築の手順を示します。
わからない部分は適宜検索したりChatGPTに聞いたりしてください。

# やり方

[アプリの準備](#アプリの準備)、[ファイルの準備](#ファイルの準備)は最初に1回だけ行います。
[Dockerコンテナの起動](#dockerコンテナの起動)はログインする度に行います。

## アプリの準備

以下のアプリをインストールしてください。

- VSCode
- Docker

:::note warn
Windowsの場合はWSLを有効にする必要があります。
:::

## ファイルの準備

### リポジトリをクローンする

https://github.com/HotariTobu/PHP-starter-kit

### .env.exampleをコピーして.envとして保存する

## Dockerコンテナの起動

以下のコマンドを実行してください。

```sh
docker-compose up
```

以上でPlaygroundの準備は完了です。
コンテナを停止するには`Ctrl + C`を押します。

# 使い方

## PHPプログラムの実行

[localhost:8000](http://localhost:8000/)にアクセスします。

## データベースののぞき見

[localhost:4000](http://localhost:4000/)にアクセスします。

# 解説

# おわりに

説明は今後追記していく所存です。
内部設計書の作成と意味

# はじめに
<!-- 発端や概要を記載 -->
業務で新規に開発するシステムや既存のシステムの仕組みがどうなっているかというのは仕様書を読むことや実際に動かしてみないとわからない点が多いと思います。開発には欠かせない内部設計書、外部設計書等を作成することで機能についての理解度が上がります。今回は内部設計に注目して内部設計についての備忘録として残したいと思います。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [内部設計とは](#chapter1)
1. [内部設計の成果物](#Chapter2)
1. [全体のクラス図](#Chapter3)


<!-- 各チャプター -->
<a id="#chapter1"></a>
# 内部設計とは
システム開発において、はじめに要件定義を行い外部設計を行った後、内部設計を作成します。内部設計の目的は、外部設計をもとにシステムの全体像を具現化を行うことです。
データの処理方法や管理方法等を設計します。また内部設計はシステム内部の詳細内容を設計することから詳細設計とも呼ばれています。

<a id="#Chapter2"></a>
# 内部設計の成果物
* クラス図
システムを構成するクラスの関係を可視化できるように図に示したもの。システム全体像の把握や他の成果物作成にも使用されるため詳細設計で作成する中でも重要度が高い。

* モジュール構造図
それぞれのモジュールの持つ機能やシステムの構成についてまとめて可視化したもの。

* アクティビティ図
システムの処理やユーザーの実行の流れと条件分岐を可視化したもの。

* シーケンス図
プログラムの概要や処理の流れを時間軸で図に示したもの。

# クラス図の書き方
<!-- クラス図1 -->
![クラス図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071732/9b730e20-5c0b-8b69-62e7-945f9b2b8215.png)

1つのクラスを表現するルールとして
-クラス区画：　上段「社員」
-属性区画（フィールド）：　中断「社員番号」
-操作区画：　下段「start()」
の順に記載します。各区画の間を線で区分けします。

## 関連(association)
線や矢印で表します。
社員とプロジェクトのクラス図が線で繋がっているので、何かしらの関連を表します。
<!-- kanren -->
![kanren.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071732/4873ae9c-adbc-8088-675c-402cd96e6cef.png)

社員クラスとプロジェクトクラスをつなぐ線の上に”0..1”,”1”という表記が添えられています。
これは多重度を表現しています。
上記の図では「社員」から見た「プロジェクト」は1つ。「プロジェクト」から「社員」は0人以上であるという表現となります。

## 多重度
| 表記 | 意味 | 
| :--- | :--- |
|n| 値の通り、必ずn |
|“0..n” または “*”| 0以上 |
|“1..*”|1以上|
“m..n”|mからnまで|

## 集約(aggregation)
白塗りのひし形と実線で表します。
クラス間で「全体」と「部分」の関係にある時に「集約」として表現します。
例：会社がなくなったとしても社員は別の会社で社員になることができる。
<!-- syuuyaku -->
![syuyaku.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071732/aaebf194-03c9-2246-cf60-772948c7d03e.png)


## コンポジション(composition)
黒塗りのひし形と実線で表します。集約の一種で、より一層結びつきが強いときに使います。インスタンスの生成や削除を担っている場合に使用されます。
例：社員が入社したと同時に社員証が発行され、退職時に破棄される。
<!-- comp -->
![comp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071732/4018d123-2732-7b36-de4b-2a58703231af.png)


## 依存(dependency)
破線矢印で表します。
依存元が変更されたら、依存先は変更しなければいけないことを明記する必要があるときに「依存」を使用する。以下の図では、ホイールが変わったときに、タイヤも依存（その規格に合わせて変更する必要がある」を表現している。
<!-- depend -->
![depend.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071732/7d0fc0b8-c87b-e589-51ae-f12b366a720f.png)

<a id="#Chapter3"></a>
# 全体のクラス図
クラス図をつなげると以下のようになります。
この図はサンプルとして[drawio](https://www.drawio.com/)を使いました。
![class_all.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071732/e4d2c0e0-03cd-47ec-0da3-2e68f1c84f84.png)

## 最後に
設計書は作って終わりではなく今後、同じチーム（プロジェクト）に入った人に理解してもらうことや成果物として重要なので作成後の定期的なメンテナンスも可能な範囲で行っていかなければならないと思いました。
AIモデル構築入門：ニューラルネットワークの実装

# はじめに
AI技術が急速に発展する中、AIモデル構築スキルは大変価値のあるものとなりました。今回はPython初学者向けに、ニューラルネットワークを使用したAIモデルの構築手順を詳細に解説します。この記事を通じて、無料のデータセットを使って、実際にAIモデルを構築してみましょう。
**※実装環境：Jupyter notebook**

# 1. 問題の定義
今回扱うのは、手書き数字の認識です。この問題は、ニューラルネットワークを学ぶためのクラシックな問題であり、教師あり学習の一種である分類問題として扱います。

# 2. データの収集
Pythonのライブラリであるsklearn.datasetsから、手書き数字のデータセットを読み込みます。
```python
from sklearn import datasets
digits = datasets.load_digits()

```
このデータセットには、0から9までの手書き数字の8x8ピクセルのグレースケール画像が1797枚含まれています。

# 3. データの前処理
今回のデータセットは整理されているため、前処理としてはデータの正規化だけ行います。それぞれの画像を表す8x8のピクセル値を0〜1の範囲にスケーリングします。
```python
# データを0-1の範囲に正規化
X = digits.images / 16
y = digits.target

```
# 4. モデルの選択
ここでは、ニューラルネットワークを選択します。Pythonの深層学習ライブラリであるKerasを使います。Kerasは、Pythonでニューラルネットワークを簡単に構築することができるライブラリです。

# 5. モデルの訓練
まず、モデルの構造を定義します。64個の入力ノード（8x8ピクセル）、10個の出力ノード（0〜9の10クラス）を持つニューラルネットワークを構築します。
```python
from keras.models import Sequential
from keras.layers import Dense

model = Sequential([
    Dense(64, activation='relu', input_dim=64),
    Dense(10, activation='softmax'),
])

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

model.fit(X, y, epochs=10)

```

# 6. モデルの評価
モデルの評価には、訓練データとは別のテストデータセットを使用します。ここでは訓練データを訓練データとテストデータに分割して、モデルの評価を行います。
```python
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Train the model
model.fit(X_train, y_train, epochs=10)

# Evaluate the model
test_loss, test_accuracy = model.evaluate(X_test, y_test)
print(f"Test accuracy: {test_accuracy}")

```

# 7. モデルのチューニング
初めてモデルを訓練した後、そのパフォーマンスを改善するために、モデルのハイパーパラメータを調整します。ここでは、学習率やエポック数などを調整します。
```python
from keras.optimizers import Adam

# Lower learning rate
optimizer = Adam(learning_rate=0.001)

model.compile(optimizer=optimizer, loss='sparse_categorical_crossentropy', metrics=['accuracy'])

model.fit(X_train, y_train, epochs=20)

test_loss, test_accuracy = model.evaluate(X_test, y_test)
print(f"Test accuracy: {test_accuracy}")

```
# 8. モデルのデプロイ
モデルが十分な性能を示したら、それをプロダクション環境にデプロイします。ここでは、Kerasモデルを保存し、その後、ロードして予測を行います。
```python
# Save the model
model.save('digit_classifier.h5')

# Load the model
from keras.models import load_model
loaded_model = load_model('digit_classifier.h5')

# Use the model for prediction
prediction = loaded_model.predict(X_test[0:1])

```

# 9. モデルのモニタリングとメンテナンス
デプロイしたモデルは、定期的にモニタリングとメンテナンスを行う必要があります。例えば、定期的に新たなデータでモデルを再訓練したり、モデルの性能が低下した場合はモデルを更新するなどの活動が必要です。

# まとめ
この記事では、ニューラルネットワークを使用したAIモデルの構築手順を解説しました。Pythonの機械学習ライブラリを使用し、MNISTデータセットを用いて、手書き数字の分類モデルの訓練から評価、チューニング、そしてデプロイまでを行いました。

AIのモデルを構築するためには、Pythonの基本的な知識とニューラルネットワークについての理解が必要です。この記事で説明した内容を理解し、自分自身で試すことで、AIモデルの構築に必要なスキルを鍛えることができます。また、更にスキルを深めるためには、[こちらのリンク](https://qiita.com/yutut/items/143cfd496a8eef299699)から学べるAIの各種技術や学び方について調べることをお勧めします。

次のステップとして、自分自身のプロジェクトでAIモデルを構築してみてください。自分だけのユニークなデータセットを集め、それを用いてAIモデルを訓練し、評価してみてください。AIモデルの設計と実装は非常にクリエイティブなプロセスであり、無限の可能性があります。
M5 DMX Base + UIFlow でムービングライトを制御してみたメモ

M5 Stack 用の DMXインターフェースである M5 DMX Base が発売されたので早速DMX制御のムービングライトを動かしてみました。

https://www.switch-science.com/products/8961

https://twitter.com/yskmjp/status/1663891353439473664

### テスト環境
- M5 Stack Core
- M5 DMX Base
- UIFlow 1.0 ( https://flow.m5stack.com/ )
- ムービングライト ( U`King ZQ02040 )

### UIFlow
PAN　→　赤色に点灯　→　TILT　→　緑色に点灯　を繰り返すフローです。
- DMX関連のフローは「モジュール」→「DMX」にあります。
- DMX init のポートはM5 Stackの種類によって変わります。( https://github.com/m5stack/M5Module-DMX512 )
- 各CHANNLの機能は照明機器によって変わるので適宜変更してください。今回使った機器は以下です。
    - CH 1: Pan
    - CH 3: Tilt
    - CH 6: Dimmer
    - CH 8: Red
    - CH 9: Green

![スクリーンショット 2023-05-31 22.18.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149785/549c2cca-8940-2293-1ade-c452cc246ac6.png)

### 終わりに
基本的な動作は確認できたので、今後は外部サービスやセンサーと連携して照明を動かすことができるようになりました。まずは最近作っているChatGPT演劇システムという仕組みに連携して観たいと思います。

https://protopedia.net/prototype/3782
vSphere 8.0の互換性に関する変更点

今回は、今更ながらですが、最新バージョンのvSphere 8.0について、従来のバージョンとの互換性の変更点を紹介します。
vSphere 8.0では、仮想マシンの互換性、ゲストOSの互換性、デバイスの互換性、ソフトウェアなどいくつかの重要な変更があります。それでは、詳細を見ていきます。
※主にvSphere 8.0の[リリースノート](https://docs.vmware.com/jp/VMware-vSphere/8.0/rn/vmware-vsphere-80-release-notes/index.html)から抜粋した情報を基に紹介していきます。

### ESXiのデバイス互換性
ESXi 8.0と互換性のあるデバイスを確認するには、[VMware Compatibility Guide](https://www.vmware.com/resources/compatibility/search.php)を参照してください。
vSphere 8.0では、プロセッサ、ストレージデバイス、およびI/Oデバイスの互換性に関する情報が提供されています。これにより、既存環境に使用しているデバイスがvSphere 8.0と互換性があるかどうかを事前に確認することができます。
検索カテゴリから確認対象のカテゴリ、フィルタを設定して検索をします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2385304/6fd3a4f4-43ad-8c53-7ec1-26a4978e3c93.png)

### ESXiとvCenter Serverのバージョンの互換性
vCenter Server 8.0はESXi 6.7以降と互換性がありますが、ESXi 6.5とは互換性がありません。
したがって、vCenter Server 8.0でESXi 6.5を管理したい場合は、先にESXiをアップグレードする必要があります。
参考：Product Interoperability Matrixes
https://onl.sc/yK5zifw
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2385304/51666868-beff-8cc7-d5f7-d3e9783f63d2.png)

### ESXiの仮想マシンの互換性
vSphere 8.0は、ESX 3.x以降（ハードウェアバージョン4）と互換性のある仮想マシンをサポートしており、古めのバージョンまで広く対応しています。
なお、ESX 2.x以降（ハードウェアバージョン3）と互換性のある仮想マシンはサポート対象外となっています。

### ESXiのゲストOSの互換性
vSphere 8.0では、[VMware Compatibility Guide](https://www.vmware.com/resources/compatibility/search.php?deviceCategory=software&testConfig=16)を参照して、互換性のあるゲストOSを確認することができます。
今回のリリースでは、いくつかのゲストOSが非推奨またはサポート終了となります。例えば、Windows Vista、Windows 2003/R2、Windows XP、Oracle Linux 5.x、CentOS 5.x、SUSE Linux Enterprise Server 10 SP4などが含まれています。
これらのゲストOSはサポートされませんので、利用している場合は新規作成や、新しいゲストOSへのデータ移行等が必要となるのでご注意ください。

### NSX for vSphere (NSX-V)との互換性
vSphere 8.0では、NSX for vSphere（NSX-V）との互換性はありません。
NSX-Vを導入している環境からvSphere 8.0へのアップグレードはサポートされていません。そのため、NSX-Vを継続して利用したい場合は、新たにNSX-T（NSX）を準備する必要があります。なお、vSphere 8.0でサポートされるのはNSX（NSX-T）のバージョン4.1.0.0または4.0.1.1です。

### アップグレードパス
互換性のお話ではありませんが、アップグレードパスについても記載しておきます。
vSphere 8.0へのアップグレードを検討する際にはアップグレードパスを確認します。アップグレードパスは現在利用中のvSphereのバージョンに依存します。vCenter Server 8.0はESXi 6.5を管理できません。
vSphere 6.5の環境は、一度6.7もしくは7.0にアップグレードしてからvSphere 8.0にアップグレードする必要があります。
※ESXi 6.5 U1以前の場合は、ESXi 6.7へのアップグレードが必須で、7.0へのアップグレードはサポートされていません。

一方、vSphere 6.7と7.0は直接vSphere 8.0にアップグレードできます。
参考：[Product Interoperability Matrixes](https://interopmatrix.vmware.com/Upgrade?productId=1)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2385304/8e6128a7-f781-ef6c-6517-4623dbf3c56c.png)

今回はvSphere 8.0の互換性に関する変更点の概要について紹介しました。アップグレードを検討する際には、リリースノートやVMwareの公式ドキュメントを参照し、システムの互換性を確認するようおすすめします。
次回は互換性以外のアップグレードに関する注意点など投稿したいと思っています。
join関数を使い数値の格納されたリストの要素を全て繋げて一つの整数として出力する

#### 数字の扱いが難しい
そんな時は文字列にしてしまおう
意外とその方が扱いやすかったりする

この時に使うのはjoin関数だ
join関数は複数の文字列を連結することができる
使い方は

文字列　=　連結する物.join(連結したい文字列のリスト)

例えば
```Python
list = ["おい","何だ","これは"]
result = " ! ".join(list)
print(result)
# 出力
# おい ! 何だ ! これは
```
となる

それでは本題
下記のようなリストを一つの整数にしたい
```Python
num_list = [4,5,6,2,1,7,8,3,5,0,2,6,3]
```
map関数を使い、リストを文字列にし、join関数を使ってその文字列をつなげる
そしてそれをint型に戻すことで一つの整数になる

```Python
str_list = map(str,num_list)
num = int("".join(str_list))
print(num)
# 出力
# 4562178350263
```
おまけにもう少し簡単に書いてみた

```python
num = int("".join(map(str,num_list)))
```
これからはいかに見やすいか、シンプルかも意識したい

覚えておくと便利な関数である



色々な人の記事を見てもっと見やすい出力の表示をしたい
【SwiftUI】いい感じのグラデーションを作成する

# はじめに
Appleの標準アプリのアイコンってシンプルなのにかっこいいですよね
かっこいい要因は背景にあるんではないかと思ってるんです。

|AppStore|Mail|Message|
|-|-|-|
|![IMG_3007.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/60843407-841f-66be-7844-a82268859e5f.jpeg)|![IMG_3005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/34cdb8ee-3c17-b7ff-938c-d0be9cc35274.jpeg)|![IMG_3006.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/b468497d-0922-e51f-3974-42cdb5eed799.jpeg)|

絶妙なグラデーションがかかってるんです
これをSwiftUIで再現する方法があったので記事にしておきます

# 実装
```diff_swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        RoundedRectangle(cornerRadius: 60)
+           .foregroundStyle(Color.blue.gradient.opacity(0.9))
            .frame(width: 300, height: 300)
    }
}
```

こんな簡単に微妙なグラデーションができました

![simulator_screenshot_D941DF0E-9105-43E7-A278-302F0DD85F44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/6358c3e9-c935-a9e8-fc29-e442fdf2f414.png)

# おわり
ちゃんとグラデーションを作りたい時は`LinearGradient`を使いましょう！
クライアント（HTML）からサーバー（Node.js+Express+Multer）へファイルをアップロードする方法

クライアント（HTML）からサーバ（Node.js+Express+Multer）へファイルをアップロードするコードを紹介いたします。
他のネット記事にも様々な情報が記載されておりましたが、どれも一発で完璧に動作するコードがなかったので、これを機に完全版としてQiitaに公開しておこうかと思います。
参考にさせて頂いたネット記事を書かれた様々な方々にこの場を借りて感謝致します。

# クライアントサイド（HTMLコード）
```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>ファイルのアップロード</title>
</head>
<body>
    <form id="form1" method="POST" enctype="multipart/form-data" action="http://localhost:3000/single">
        <fieldset class="form-group">
            <label for="file1">アップロードファイル (1)</label>
            <input type="file" id="file1" name="file1" class="form-control" />
        </fieldset>
        <fieldset class="form-group">
            <input type="submit" id="submitButton" name="submitButton" class="btn btn-primary" value=" 送信 " />
        </fieldset>
    </form>
</body>
</html>
```
# サーバーサイド（Node.js+Express+Multerを使ったJavaScriptコード）
事前に必要なモジュールはnpmコマンドでインストールしておいてください。
アップロード先はindex.jsのあるフォルダ（ディレクトリ）下のtmpフォルダ（ディレクトリ）です。
あらかじめ、tmpフォルダ（ディレクトリ）自体は作成しておいてください。
```index.js
const multer = require('multer');
const express = require('express');
const app = express();

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
      cb(null, 'tmp/')
    },
    filename: function (req, file, cb) {
      cb(null, file.originalname)
    }
  })
  
const upload = multer({ storage: storage })

app.post('/single', upload.single('file1'), (req, res) => {
    console.log("{message:'アップロード成功'}");
});

app.listen(3000);
```
サーバの起動の仕方は以下のコマンドで。
```
node index.js
```
# HTML画面
クライアントサイドのindex.htmlをブラウザで表示させ、ファイルを選択して送信ボタンを押せば、サーバ側のtmpフォルダ（ディレクトリ）下にファイルがアップロードされます。
![アップロード画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600620/f0187217-ec36-9d50-517e-89f654491b5c.png)

# あとがき
結構、ネット検索して様々な記事を調べましたが、なかなか動作せず、苦労致しました。コードは応用が利くように最小限に留めました。この記事を見て、皆様のお役に立てれば幸いです。
fastapi-jwt-authを使用して Swagger UI に Authorize オプションを表示する方法

FastAPIでJWTトークンによるBearer認証を、fastapi-jwt-authライブラリを使用して実装する際、Swagger UI に Authorize オプションを表示する方法についての議事録です。

手順は、HTTPBearerスキームをDependsを使って依存関係として注入します。
これにより、Swagger UIに認証ヘッダーを入力するフィールドが表示されます。

公式ドキュメントのコードをベースに、追加変更した部分にDiffを表現しています。
公式ドキュメント：https://indominusbyte.github.io/fastapi-jwt-auth/usage/basic/
```diff_python:main.py
from fastapi import Depends, HTTPException, status
+ from fastapi.security import HTTPBearer
from fastapi_jwt_auth import AuthJWT
from fastapi import FastAPI

app = FastAPI()

+ bearer_scheme = HTTPBearer()

class User(BaseModel):
    username: str
    password: str

class Settings(BaseModel):
    authjwt_secret_key: str = "secret"

@AuthJWT.load_config
def get_config():
    return Settings()

@app.post("/login")
def login(user: User, Authorize: AuthJWT = Depends()):
    if user.username =='test' and user.password =='test':
        access_token = Authorize.create_access_token(subject=user.username)
        return {"access_token": access_token}
    else:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid username or password"
        )

+ @app.get("/protected", dependencies=[Depends(bearer_scheme)])
def protected(Authorize: AuthJWT = Depends()):
    Authorize.jwt_required()
    current_user = Authorize.get_jwt_subject()
    return {"user": current_user}
```

Swagger UIを開くとAuthorizeボタンが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3338230/303e61c4-e838-fda7-85aa-893b8e222013.png)

エンドポイント`('/login')`を使ってアクセストークンを取得します。
これはPOSTリクエストで、ユーザ名とパスワードをリクエストボディに含めます。
入力したらExecuteをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3338230/0961753e-63a8-171e-9004-24ba78459532.png)

トークンがレスポンスされたのが確認できます。
取得したアクセストークンをコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3338230/a4b371c0-1ca3-7ab3-9442-bfaf7aad3342.png)

Authorizeボタンをクリックし、コピーしたアクセストークンを入力し、AuthorizeとCloseをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3338230/e6da2cdd-40f7-b5c5-b8e3-5e12449164db.png)


これで保護されたエンドポイント（下記例では `'/user'`）にリクエストを送信するときにアクセストークンが認証ヘッダーに含まれます。
リクエストを送信してレスポンスを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3338230/6b8a9a3d-dd27-8e29-54ce-2a346e32e96e.png)
E2E自動テスト(Web)のロケーター指定 応用編1

## はじめに
前回の記事「[E2E自動テストを実装するためのロケーターの基礎](https://qiita.com/tyngw/items/7c2404cddb4b93e44837)」では、WebのE2E自動テストを実装するためのロケーターの指定の仕方についてご紹介しました。
今回は応用編(応用編というほどの内容ではありませんが)として、実際のプロダクトによくあるUIの操作方法をまとめてみました。
1回目のお題は「DatePicker」です。

## テスト対象システム(SUT)
テスト自動化の学習用のサイト [HOTEL PLANISPHERE](https://hotel.testplanisphere.dev/ja/) を用います。

## DatePickerの操作
日付を選択するときに出てくるカレンダーコントロールです。
テスト自動化においては、カレンダーから当日の日付を選びたい、翌日の日付を選びたいという場面があると思います。

SUTを操作して `宿泊予約` > 任意のプランの`このプランで予約` > `宿泊日`をクリックしてみましょう。

今回のSUTはホテルの予約サイトなので、初期状態で翌日の日付が選択されています。
また、過去の日付で予約をすることはできないので、日付を固定し**5日固定にする**といったことは難しいです。

宿泊日として**テスト実施日の翌日を選ぶ**という手順があったとき、どのように実装すれば良いでしょうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549722/9385f4bd-de08-4a31-0cc6-00ec17884731.png)

使用しているツールや言語で日付を取得することができるのであれば、
`a[data-date={日}]`(CSSセレクター)などで選択ができます。

もう一つのやり方として、UIの見た目が変化している場合、何らかのデザインを適用しているはずなので、
その違いに着目してUI要素を選択する方法があります。

現在選択されている14日と15日の要素をDeveloper Toolsで見比べてみましょう。
```html:14日の要素
<td class="  ui-datepicker-current-day" data-handler="selectDay" data-event="click" data-month="5" data-year="2023">
    <a class="ui-state-default ui-state-active" href="#" aria-current="true" data-date="14">14</a>
</td>
```
14日の要素には、td要素のclass属性に`ui-datepicker-current-day`、
a要素のclass属性に`ui-state-active`が付与されていることがわかります。
```html:15日の要素
<td class=" " data-handler="selectDay" data-event="click" data-month="5" data-year="2023">
    <a class="ui-state-default" href="#" aria-current="false" data-date="15">15</a>
</td>
```

これを用いてDatePickerを開いた時の初期状態、つまり翌日の日付を選択することができます。
`td.ui-datepicker-current-day`(CSSセレクター)

今回のSUTでは確認できませんが、もし当日の日付を選択したい場合は、
よくあるDatePickerだと当日の日付のみ異なるデザインになっていたりするので、
当日の要素とそれ以外の要素を比較してみて、`today`というキーワードがあったら、
そのキーワードを利用して要素を特定できないか検討してみましょう。

## バックナンバー
- [E2E自動テストを実装するためのロケーターの基礎](https://qiita.com/tyngw/items/7c2404cddb4b93e44837)
iPaaS　PaaS　IaaS　ってなんだよわからんよ―ーー

iPaaS　PaaS　IaaSとか、何が何だかさっぱりわからん。
皆さん、ほんとに全くわからないですよね。マジほんとに理解できん。
ということで、ある程度整理しました。

まずはクラウドサービスで言われているサービスの形式について
・SaaS（ソフトウェア・アズ・ア・サービス）
・PaaS（プラットフォーム・アズ・ア・サービス）
・IaaS（インフラストラクチャ・アズ・ア・サービス）
・FaaS（ファンクション・アズ・ア・サービス）
・DaaS（デスクトップ・アズ・ア・サービス）

■SaaS（ソフトウェア・アズ・ア・サービス）
ローカルで言うところのアプリケーション（Office等）プログラムをクラウド上（インターネット上）にて実行できるようにしてくれているものです。ライセンス体系として、期間×ライセンス人数が多くみられます。ライセンスの買取も応じてくれるところもあります。ブラウザを介して行うものが多いのですが、まれにライセンス情報をやり取りしてサービスとして行うものが見られます。
　　
SaaSサービスの代表
・Microsoft Office 365などのオフィスソフト
・GmailなどのWebメール
・Dropboxなどのオンラインストレージ
・サイボウズなどのグループウェア
・SalesForce

■PaaS（プラットフォーム・アズ・ア・サービス）
・開発環境を貸し出すサービス
・開発に必要な言語や管理システム、OSなどのプラットフォームを利用できる
「PaaS」では、複雑で面倒な開発環境を整備する手間がなくなるというメリットがあり、システム開発に注力したいという場合に適しています。一方で、開発言語やデータベースはベンダーが提供しているものに限られるというデメリットもあります。

例：　
Amazon　AWS
Microsoft　Azure
Google　Google Cloud Platform　等のサービス

■IaaS （インフラストラクチャ・アズ・ア・サービス）
　
「IaaS」では、ネットワークやサーバーといったインフラの運用を安価でベンダーに任せられるというメリットがあります。デメリットは、インフラ設計やサーバー管理・運用のスキルといった専門知識を持った技術者が必要となる点です。
 
つまり、どこまでサービスを求めるかにより、受けられるものが変わってくるものです。
実物の世界で言うと、
 
ハードウェア、OS、ミドルウェアを選定し用意する。アプリケーションを準備・インストールして、サーバーに設置し、ネットワークにハードウェア、サービスを組み込む。といった作業となるのですが、これらの作業がここからここまででいいよ、となるサービスとなります。

他にもこんなサービスがあります。
 
■BaaS（Backend as a service）
スマートフォンやタブレットなど、モバイルシステムのバックエンド機能をアプリケーションサーバーが代行するクラウドサービス
 
■DaaS（Desktop as a service）
アイコンやフォルダ、ウィンドウなどの環境をクラウドから呼び出し、クライアントのデスクトップ環境を提供するクラウドサービス
 
■IDaaS（Identity as a service）
ネットワークセキュリティの向上と、認証情報を管理する手間を省くため、クラウド上でID管理を行うクラウドサービス
 
■XaaS（X as a service）
コンピュータ処理に必要となるすべてのサービスを、ネットワークを介したサービスの形で提供する概念。EaaS（Everything as a service）と呼ばれることもある。

一息ついたところで、PaaSについては分かったけど、iPaaSってなんだよ。またわかんなくなったってば。
 iPaaS というのは、PaaSと似ていますが、全然違うサービスです…

■iPaaS (Integration Platform as a Service）
「オンプレミスとクラウドベースのプロセス、サービス、アプリケーション、およびデータの任意の組み合わせを、個別または複数の組織に接続する統合フローの開発、実行、およびガバナンスを可能にするクラウドサービスのスイート」
iPaaSとは、複数のクラウド環境上に分散している業務システムを統合するためのクラウドサービス。
 
SaaSサービスについては、部門ごとに収集されたデータが部内者にしか閲覧できない状態（データサイロ）になっています。そうしたデータサイロはさまざまな問題の原因となります。業務を進めるうえで従業員が何度もデータを入力し直し、都度アプリケーションを切り替える必要があったり、仕事の効果的な遂行に必要なデータがそろわないといった問題です。
 
つまり、個々のサービスに個々の部門のデータはあるけど結局全体としてデータが揃わない状態となるということですね。経理部門が使っているデータと営業部門が使っている共通のデータや連携を行わないといけないデータがあってもそれができないとのことかな。
※個々のサービスとしては問題ないけど全体として問題ありな状態
 
iPaaSは、SaaSのサービス同士を組み合わせて、データの連携をスムーズにするサービスですね。
[AWS Q&A 365][SNS]AWSのよくある問題の毎日5選 #72

# 1. アマゾンの商標とトレードドレスの使用に関するポリシーは何ですか？
答え：アマゾンの商標とトレードドレスは、アマゾンの製品やサービスに関連しないもの、顧客の混乱を招く可能性のある方法、またはアマゾンを中傷または信用を損なう方法で使用することはできません。

# 2. Amazon Simple Notification Serviceのセキュリティ機能と能力は何ですか？
答え：この文書はAmazon SNSのセキュリティ機能と能力について具体的な情報を提供していません。しかし、サービスがメッセージのセキュリティと耐久性を提供することを述べています。

# 3. Amazon SNSはどのようにしてメッセージのセキュリティを確保しますか？
答え：この文書はAmazon SNSがどのようにメッセージのセキュリティを確保するかについて具体的な情報を提供していません。

# 4. Amazon SNSにおけるメッセージデータ保護とは何ですか？
答え：メッセージデータ保護は、Amazon SNSの機能であり、ユーザーがメッセージを暗号化し、認証された受信者のみがアクセスできるようにするものです。

# 5. ユーザーはどのようにしてAmazon SNSでアクセス制御のためのタグを設定できますか？
答え：ユーザーは、アクセス制御のためのタグ付けを使用して、Amazon SNSでアクセス制御のためのタグを設定できます。これにより、トピックとサブスクリプションに基づいて権限を設定することができます。
[AWS Q&A 365][SNS]Daily Five Common Questions #72

# 1. What is Amazon's policy on the use of its trademarks and trade dress? 
Answer: Amazon's trademarks and trade dress may not be used in connection with any product or service that is not Amazon's, in any manner that is likely to cause confusion among customers, or in any manner that disparages or discredits Amazon. 

# 2. What are the security features and capabilities of Amazon Simple Notification Service? 
Answer: The document does not provide specific information about the security features and capabilities of Amazon SNS. However, it does mention that the service provides message security and message durability. 

# 3. How does Amazon SNS ensure message security? 
Answer: The document does not provide specific information about how Amazon SNS ensures message security. 

# 4. What is message data protection in Amazon SNS? 
Answer: Message data protection is a feature in Amazon SNS that allows users to encrypt messages and ensure that only authorized recipients can access them. 5. How can users configure tags in Amazon SNS for access control? Answer: Users can configure tags in Amazon SNS for access control by using tagging for access control. This allows them to set permissions on topics and subscriptions based on tags.
Vertex AI Matching EngineのINDEXの消し方

# 1.はじめに
* Vertex AI Matching Engine（のindex）をうっかりデプロイしたままにして課金でパニックになった。
* Indexを消さないと課金されていく。

# 2.経緯
* 最近の大規模言語モデルの影響で、ベクトルの検索を高速にしたいなと思ったところ、Vertex AIの[Matching Engine](https://cloud.google.com/vertex-ai/docs/matching-engine/overview?hl=ja)を発見。レスポンスがすごく速い（らしい）。
* さっそく[チュートリアル](https://github.com/GoogleCloudPlatform/vertex-ai-samples/blob/main/notebooks/community/matching_engine/matching_engine_for_indexing.ipynb)を見ながら複数indexを作成し、indexをデプロイした。


# 3. 翌日
* 課金でアラートが出ていたので、見に行くと、１日で18,000円も課金されている。翌日はさらに悪化して22,000円ほど。これはまずいと思う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385220/bebc4386-9e84-46fc-8165-3ef8629ced60.png)



# 4. 対応
* Google Bardに聞いてみたところ、indexの横にあるチェックボックスをチェックして、deleteボタンを押せばOK!とのことだが、Matching Engineのページに行っても、チェックボックスも削除ボタンもない！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385220/3467c508-b8b3-d923-a66a-4b213b57604a.png)



* ネット上をさまよい、[この説明](https://cloud.google.com/vertex-ai/docs/matching-engine/using-matching-engine?hl=ja#create-index)中のdeleteとundeploy関係のコマンドを実行。順番が大事で、
①まずindexに対応するINDEX ENDPOINTからINDEXをundepoy
②INDEX ENDPOINTを消す。
③INDEXを消す。


※indexの数字とdeployed-index-idの文字列は適当です。
```python
①
#例：
gcloud ai index-endpoints undeploy-index 4030255473566416896 --deployed-index-id=vectest_brute_force_deployed --project={Project-ID} --region=us-central1


②
#例：
gcloud ai index-endpoints delete 4030255473566416896 --project={Project-ID} --region=us-central1


③
#例：
gcloud ai indexes delete 8238869325344145408 --project={Project-ID} --region=us-central1


```

無事に消えてくれる。


# 5.さいごに
* このままだと月60万課金される・・・と思ったときはくらくらしました。
* Matching EngineはOSSの[scann](https://github.com/google-research/google-research/tree/master/scann)と同じアルゴリズムとのことなので、こちらをまずはいじることに。
* チュートリアル通り作るんじゃなくて[もっと安く作って動かすプラン](https://cloud.google.com/vertex-ai/pricing?hl=en#matchingengine)があるみたいですね。
SyntaxTree gemの紹介と実践例

## 前提

[世は大パーサー時代](https://yui-knk.hatenablog.com/entry/2023/05/23/191049)ということで、[SyntaxTree](https://github.com/ruby-syntax-tree/syntax_tree)を触ってみて、実際にRSpecファイルからドキュメンテーション部分を抜き出すことに成功したのでちょっと書きます。

## SyntaxTreeについて

RubyのASTをいい感じに触れるgemです。機能的にはRipperという標準ライブラリと近いのですが、各ノードが情報を豊富に持っているために色々と便利になっています。

## SyntaxTree実践：RSpecから情報を抜き出す

コードを読んだほうが早いと思うのでコードをどうぞ。

https://gist.github.com/okuramasafumi/471b6f7ac05e161d10baa414fc95f828

上のコードではRSpecのファイルから`describe`などに与えられた文字列を解析し、RSpecが`--format documentation`のときに出力する文字列と似た文字列を出力しています。

特に57行目の`visit_command`メソッドが重要で、ここでメソッド名に応じて処理を変更しています。`super`を呼ばないと下のノードが処理されなくなってしまうのですが、`super`の後ろで後片付けができる（感覚的には対応する`end`に来たときの処理を書ける）のが便利です。

お読みいただけるとわかるのですが、中核となる`RSpecVisitor`クラスは`SyntaxTree::Visitor`を継承することでわずか40行ほどに収まっており、全体でも100行以下で目的を達成できています。

## まとめ

ということで短いですがSyntaxTreeの紹介と実践例でした。パーサーというと大がかりに聞こえがちですが、このような小規模なコードでも便利さを実感できます。SyntaxTreeは使用感がとても良いですし、機能も豊富ですので手軽にやりたいことを実現できるかもしれません。
`packer hcl2_upgrade` を実行し生成された `.pkr.hcl` ファイルに `"template: hcl2_upgrade:3: unexpected \"\\\\\" in operand"` が出力された


## はじめに

Packer の v1.7.0 から Packer template の記述方法として JSON ではなく HCL2 を利用することが推奨されています。
JSON で記述された Packer template を HCL2 形式に変換する `hcl2_upgrade` コマンドを実行し生成された `.pkr.hcl` ファイルに、 `"template: hcl2_upgrade:3: unexpected \"\\\\\" in operand"` が出力されたときの対処法を記載します。

## 対処方法

https://github.com/hashicorp/packer/issues/10728#issuecomment-793199077

今回はエスケープに利用している `\"` (escaped quote) が原因でうまく JSON をパース出来ていませんでした。
`\"` (escaped quote) を "`" (backtick) に変更することでこの問題を回避することが出来ます。

### Before

下記のように定義された JSON ファイルに対して `packer hcl2_upgrade` を実行すると...

```json:sample_packer_template.json
{
  "builders": [{
    "type": "amazon-ebs",
    ...
    "ami_name": "ami_name-{{isotime \"2006-01-02-15-04-MST\"| clean_resource_name}}"
  }],
}
```

下記のような `.pkr.hcl` ファイルが生成されます。

```hcl:sample_packer_template.json.pkr.hcl
# could not parse template for following block: "template: hcl2_upgrade:3: unexpected \"\\\\\" in operand"

source "amazon-ebs" "autogenerated_1" {
  ami_name      = "ami_name-{{isotime \"2006-01-02-15-04-MST\"| clean_resource_name}}"
```

### After

記述を変更し `packer hcl2_upgrade` を実行すると...

```json:sample_packer_template.json
{
  "builders": [{
    "type": "amazon-ebs",
    ...
    "ami_name": "ami_name-{{isotime `2006-01-02-15-04-MST`| clean_resource_name}}"
  }],
}
```

`"template: hcl2_upgrade:3: unexpected \"\\\\\" in operand"` が `.pkr.hcl` ファイル内に出力されずに意図した形式 (`legacy_isotime`) を利用した `.pkr.hcl` ファイルが出力されます。

```hcl:sample_packer_template.json.pkr.hcl
source "amazon-ebs" "autogenerated_1" {
  ami_name      = "ami_name-{{ clean_resource_name `${legacy_isotime("2006-01-02-15-04-MST")}` }}"
```

## References

https://github.com/hashicorp/packer/issues/10728

https://developer.hashicorp.com/packer/docs/v1.7.x/commands/hcl2_upgrade

https://developer.hashicorp.com/packer/tutorials/configuration-language/hcl2-upgrade

https://developer.hashicorp.com/packer/docs/templates/hcl_templates/functions/datetime/legacy_isotime

https://developer.hashicorp.com/packer/docs/templates/legacy_json_templates/engine

https://www.packer.io/
（備忘録）ABCIのバッチスクリプトでの conda not found の解決方法

## 方法

`conda init bash`は済ませておく．

```bash:batch.sh
#!/bin/bash
source ~/.bashrc
```

`.bashrc`が自動で読み込まれていないっぽい．

## 参考
https://qiita.com/aya_se/items/9e3e333b26e989e2c97b#conda%E3%81%A7%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%81%99%E3%82%8B
クリップボードの内容をそのままGmail送信するRubyスクリプト

## サンプルソース

```clip2mail.rb
require 'mail'

# 以下にgmailのアプリパスワードを設定 https://accounts.google.com/IssuedAuthSubTokens?hide_authsub=1
mail_passwd = ENV['GMAIL_PASS']
mail_from   = ENV['GMAIL_ADDR'] # fromのアカウントとアプリパスワードを作ったアカウントは揃える必要がある
mail_to     = ENV['GMAIL_ADDR']

# クリップボードからテキストを取得（Macならpbpaste）
clip = `powershell.exe -command "[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding('utf-8');Get-Clipboard"`

lines = clip.split(/\n|\r\n/)
mail_subject = lines.shift # クリップボードの一行目がタイトル
mail_body    = lines.join("\n")  # 二行目以降が本文

if mail_body.nil?
  puts '本文が空です。クリップボードにテキストがありません'
  exit
end

Mail.defaults do
  delivery_method :smtp, {
    address: 'smtp.gmail.com',
    port: 587,
    domain: 'example.com',
    user_name: mail_from,
    password: mail_passwd,
    authentication: :login,
    enable_starttls_auto: true
  }
end

m = Mail.new do
  from     mail_from
  to       mail_to
  subject  mail_subject
  body     mail_body
end
m.charset = 'UTF-8'
m.content_transfer_encoding = '8bit'
m.deliver
```

## 解説

- gmail送信は[アプリパスワード](https://accounts.google.com/IssuedAuthSubTokens?hide_authsub=1)を発行して使う
- クリップボードから値を取得するにはPowerShell経由で取得する
    - `powershell.exe -command "[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding('utf-8');Get-Clipboard"` とめちゃ長い
    - Macならpbpaste一発でいい
- メール送信にはmailというgemを使う
- gmailのアプリパスワードを使った送信はSMTP AUTHで認証するSMTPサーバーとして接続する
- メールアドレスとパスワードは`.bashrc`みたいなところで環境変数としてexport しておく

## 用途・シナリオ

- エディタで新規ファイル上でメモをがーっと書いてる
- 保存するほどのことではないが捨てるのも忍びないメモもある（議事録というほどではない記録）
- だいたい一行目に大事なことが書かれてる
- これをファイル保存することなくgmailで自分自身に送信しておきたい
- エディタで全選択＆コピー → `ruby clip2mail.rb` で自分自身にメールできちゃう
- gmailならタイトルに重みを付けて高速に検索してくれるので後で見返す時に便利
- 世のメモツールはうっかり前回の議事メモを更新しちゃうのがイヤなところだったのです
[Git] 動作を試す 実行例41：--bareでローカルリポジトリからリモートリポジトリを作成

Gitの動作を理解するために、Gitのコマンドを実際に試して、結果を見てみました。

1つの記事内で一連のGitコマンドが完結しているので、これら一連のコマンドを順に実行させて結果を見ることで、一連のGitの動作を実際に体感でき、一通り独習することが可能です。

※前回記事のリポジトリ状態からの続きになっています。
| [前回記事へ](https://qiita.com/dl_from_scratch/items/b9b46150f08e7ad2f7e2) | [目次へ：Git関連記事のまとめページ](https://qiita.com/dl_from_scratch/items/597bc28a4787a7901d21) | [次回記事へ](https://qiita.com/dl_from_scratch/items/0e49693247b27a6ed97e) |
|:-:|:-:|:-:|

# 実行例

```
cd /test-space

※通常の作業用リポジトリをクローンして、そのまま新たにベアリポジトリを作成する(共有専用のリポジトリ)
git clone --bare D:/test-space/local-repo2 remote-repo2.git
↓
結果: 
Cloning into bare repository 'remote-repo2.git'...
done.

dir /b
↓
結果: 
local-repo1
local-repo2
remote-repo1.git
remote-repo2.git

cd /test-space/remote-repo2.git
git log --oneline --graph --all
↓
結果: 
* e009b2d (branch-R1) message R2
| * c69a305 (HEAD -> master) message R1
| * 94996a0 message4
|/
* 20bbab7 message3
* 00cad71 message2
* 4ace194 message1

cd /test-space/local-repo2
git remote -v
↓
結果: 
origin  D:/test-space/remote-repo1.git (fetch)
origin  D:/test-space/remote-repo1.git (push)

(※クローン元のリポジトリでは接続の追加はされない)

-----

※remote-repo2.gitを削除
cd /test-space
rd /s /q "/test-space/remote-repo2.git"
```

# 環境

Windows 10、PortableGit-2.40.0-64-bitを使用、全てローカルPC上で実施、GitHub等は不使用。
【Paiza問題集】算術・代入演算メニュー/代入演算

# Paiza問題集

## 算術・代入演算メニュー/代入演算

### Step01 代入演算1
```Python:Step01
"""
代入演算1
https://paiza.jp/works/mondai/arithmetic_substitution_op/arithmetic_substitution_op__substitution_step1

問題
変数Nを0で初期化する
Nに3,286を足した値をNへ代入する
Nに4,736 をかけた値をNへ代入する
Nを12,312で割った余りをNへ代入する
Nを出力する
"""

N = 0
N = N + 3286
N = N * 4736
N = N % 12312
print(N)
```

### Step02 代入演算2
```Python:Step02
"""
代入演算2
https://paiza.jp/works/mondai/arithmetic_substitution_op/arithmetic_substitution_op__substitution_step2

問題
整数A,B,Cが与えられる
変数Nを0で初期化する
NにAを足した値をNへ代入する
NにBをかけた値をNへ代入する
NをCで割ったあまりをNへ代入する
Nを出力する
"""

A, B, C = map(int, (input().split()))

N = 0
N = N + A
N = N * B
N = N % C
print(N)
```

### Step03 代入演算3
```Python:Step03
"""
代入演算3
https://paiza.jp/works/mondai/arithmetic_substitution_op/arithmetic_substitution_op__substitution_step3

問題
変数Nを10000で初期化する
Nを361で割った商をNへ代入する
Nを28で割った余りをNを代入する
Nを出力する
"""

N = 10000
N = N // 361
N = N % 28
print(N)
```

### Final問題 代入演算4
```Python:Final問題
"""
代入演算4
https://paiza.jp/works/mondai/arithmetic_substitution_op/arithmetic_substitution_op__substitution_step4

問題
整数A,Bが与えられる
変数Nを10000で初期化する
NをAで割った商をNへ代入する
NをBで割った余りをNへ代入する
Nを出力する
"""

A, B = map(int, input().split())

N = 10000
N = N // A
N = N % B
print(N)
```
psql: error: connection to server at "localhost" (127.0.0.1), port 5432 failed

# 概要
- 下記エラーを解消したい
`psql: error: connection to server at "localhost" (127.0.0.1), port 5432 failed: Connection refused
	Is the server running on that host and accepting TCP/IP connections?`

# 環境
- Ubuntu 18.04.6 LTS
- Postgresqlのパスワードは設定済み
- create databaseも実行済み

# ファイル修正
postgresql.confを探す
```
find / -name postgresql.conf 2> /dev/null
```

以下に変更
```
# - Connection Settings -

# listen_addresses = '*'          # what IP address(es) to listen on;
                                        # comma-separated list of addresses;
                                        # defaults to 'localhost'; use '*' for all
                                        # (change requires restart)
port = 5432                             # (change requires restart)
```
リスタートする
```
sudo service postgresql restart
```

こちらのファイルも変更する
```
/etc/postgresql/14/main/pg_hba.conf
```
開くとこのようになっているので、
```
# IPv4 local connections:
host    all             all             127.0.0.1/32         scram-sha-256
```
以下のように変更
```
# IPv4 local connections:
host    all             all             0.0.0.0/0            scram-sha-256
```
リスタートする
```
sudo service postgresql restart
```
再度接続

```
psql -h localhost -U postgres -W test
```

```
psql (14.8 (Ubuntu 14.8-1.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

test=#
```

できた！
【その８】メンテナンスについて

<br>[【その１】RPA初心者と歩むPower Automate活用日記【ポイ活】](https://qiita.com/tantanshio/items/2b741584f65d8ce967f8)


# ◆メンテナンスについて

作成した処理をダブルクリックで必要な項目を選択、修正することで可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/2bc73d60-24cd-ac4b-be79-34e0f8eb683d.png)

# ◆ロボットファイルが重い

無駄な処理が多くなっていませんか？

実行内容を見直して不要な処理を省くことで
処理スピード向上、ロボットファイルの軽量化を図ることが出来ます

また、処理で使用している画像キャプチャもロボットファイル側に保存されています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/3eb84c12-d473-ad4f-d187-d198c49be85f.png)

使用していない画像がある場合は削除しましょう



# ◆エラーの場合、ロボットを止めずに動かしたい

処理設定の「エラー発生時」から設定が行えます

フロー実行を続行する　で本来エラーの場合、ロボット停止するところをそのまま動かすことができます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/7879c4cd-45a1-e3b8-f21e-3556fcadf05a.png)
devise導入し、ログインのパスの記述

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/0d29646d-487a-cc08-e2bb-6adb0203cb6e.png)
１：deviseを導入し、ログインボタンをクリックしたら、ログイン画面へ遷移するための設定。
<%= form_with  model: @user, url:  user_session_path,  class: 'registration-main', local: true do |f| %>
と記述する。
rails routesコマンドを実行し、pathの確認をすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/98d53780-fc28-c0c8-a4de-77aaee7e9aa9.png)
今回、フォームからのログイン情報を送信して、sessions#createを実行し、保存したいため、Prefix：user_sessionをpathとして、sessions/new.html.erbのurlにuser_session_pathを記載することでログイン情報を保存できる。
AIモデル構築入門：ランダムフォレストの実装

# はじめに
　この記事では、AIモデルの構築フローを実際のPythonコードと共に詳しく解説します。今回の目標は、ランダムフォレストを使用して予測モデルを作成し、それを評価・チューニングすることです。始めてAIモデルを作成する方でも、この記事に従って進めれば、自分でも同様のAIモデルを実装できます。
# 1. 問題定義とデータセットの導入
　今回の問題は、アイリス（Iris）のデータセットを使用し、アイリスの種類を予測する分類問題とします。アイリスのデータセットは機械学習の入門によく使われ、花弁の長さ、花弁の幅、がくの長さ、がくの幅といった4つの特徴量からアイリスの3種類（setosa, versicolor, virginica）を分類します。
```python
# 必要なライブラリのインポート
from sklearn.datasets import load_iris

# アイリスのデータセットをロード
iris = load_iris()

# 特徴量とターゲット変数を定義
X = iris.data
y = iris.target

```
# 2. データの前処理
データの前処理は今回省略します。アイリスのデータセットは事前に整理されているため、欠損値の処理や異常値の処理は不要です。

# 3. モデルの選択
この問題にはランダムフォレストを使用します。ランダムフォレストは複数の決定木を生成し、それらの決定木の多数決により予測を行うアルゴリズムです。

# 4. モデルの訓練
データを訓練データとテストデータに分割し、ランダムフォレストのモデルを訓練します。
```python
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier

# データの分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# モデルのインスタンス化
clf = RandomForestClassifier()

# モデルの訓練
clf.fit(X_train, y_train)

```
# 5. モデルの評価
訓練したモデルをテストデータで評価します。分類問題の評価指標としては精度（Accuracy）が一般的に用いられます。
```python
from sklearn.metrics import accuracy_score

# テストデータを使った予測
y_pred = clf.predict(X_test)

# モデルの精度を計算
accuracy = accuracy_score(y_test, y_pred)
print("モデルの精度: ", accuracy)

```
# 6. モデルのチューニング
モデルの精度を向上させるために、ハイパーパラメータの調整（チューニング）を行います。ここではGrid Searchを使用します。
```python
from sklearn.model_selection import GridSearchCV

# チューニングするパラメータ
param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [None, 5, 10],
    'min_samples_split': [2, 3, 4],
}

grid_search = GridSearchCV(estimator=clf, param_grid=param_grid, cv=5, return_train_score=True)

grid_search.fit(X_train, y_train)

# ベストパラメータでモデルを再訓練
best_clf = grid_search.best_estimator_
best_clf.fit(X_train, y_train)

# ベストパラメータを使用して評価
y_pred = best_clf.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print("チューニング後のモデルの精度: ", accuracy)

```
# 7. モデルのデプロイ
モデルの性能が満足のいくレベルに達したら、そのモデルをデプロイします。デプロイとは、モデルをプロダクション環境に導入し、新たな入力データに対する予測を提供できる状態にすることです。具体的なデプロイの方法は多岐にわたりますが、Pythonではpickleモジュールを用いてモデルを保存し、再利用する方法が一般的です。
```python
import pickle

# モデルの保存
with open('model.pkl', 'wb') as f:
    pickle.dump(best_clf, f)

```
このようにして保存したモデルは、新たな予測を行う際にロードして利用することができます。
```python
# モデルのロード
with open('model.pkl', 'rb') as f:
    loaded_model = pickle.load(f)

# ロードしたモデルで予測
new_prediction = loaded_model.predict(new_data)

```
# まとめ
以上がランダムフォレストを用いたAIモデルの構築フローに従い、ランダムフォレストの実装を行いました。問題定義、データ収集、データ前処理、モデル選択、モデル訓練、モデル評価、モデルのチューニング、そしてモデルのデプロイという一連の流れをPythonを使用して実施しました。

初学者がこの記事を元に同様の流れでAIモデルを実装できるよう、具体的なPythonコードを交えて説明しました。また、重要なポイントは太字で強調し、理解を深めるための[リンク](https://qiita.com/yutut/items/143cfd496a8eef299699)も提供しました。

これを通じて、AIモデルを構築するための基本的なスキルとその学び方について理解を深めて頂けたでしょう。初学者の皆さんがこの記事を参考に、自身の手でAIモデルを作成し、実際にデプロイする経験を得ることを期待しています。
【その７】やりたいことを一通り入れて実行したらロボットが止まる

<br>[【その１】RPA初心者と歩むPower Automate活用日記【ポイ活】](https://qiita.com/tantanshio/items/2b741584f65d8ce967f8)


# ◆やりたいことを一通り入れて実行したらロボットが止まる

ロボットを実行したところ、3つ目のクリック処理でエラー停止してしまった
なぜだろう


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/8aa929a3-9712-4c64-a4c9-b031bec57783.png)


原因が何か
それぞれ何をクリックさせているか画像を確認する



すると、
2つ目のクリック処理が行われておらず、
3つ目のクリック処理に進んでいたため、エラーになっていた

どうやら、1つ目のクリック⇒2つ目のクリック
この画面切り替えに時間がかかり、2つ目のクリックがうまくいっていない模様


そのため、処理と処理の間に待ち時間を設け、画面切り替えに対応していく


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/1d4a49b1-5ea6-dbc6-680c-49d0456b29f3.png)





再実行で確認



エラー無く処理完了！




# ◆次回　【その８】メンテナンスについて
AIモデル構築入門：決定木の実装

# はじめに
　AIの世界へようこそ！この記事では、AIモデルを構築する一連のフローを追いながら、具体的な決定木モデルの実装を行います。Python初学者の方でも安心して取り組めるよう、すべてのコードには詳細な説明を加えています。また、AIのモデル構築に必要なスキルとその学び方についてのページへ誘導するリンクも用意しています。手を動かしながら学べるよう、実際に無料のデータセットを使用します。AIモデル構築の流れを学び、自分自身でも実装できるようになりましょう！
**※実装環境：Jupyter notebook**

# 1. 問題定義
　今回のタスクは、アイリスデータセットの特徴量（がくの長さ、がくの幅、花びらの長さ、花びらの幅）を用いて、アイリスの品種を予測する分類問題とします。

# 2. データの準備
　Pythonの機械学習ライブラリであるscikit-learnからアイリスデータセットを読み込みます。
```python
from sklearn.datasets import load_iris
iris = load_iris()

```
# 3. データ前処理
　データの前処理は今回は不要です。アイリスデータセットは前処理済みのため、すぐにモデルの訓練に進むことができます。

# 4. モデル選択
　今回は決定木モデルを使用します。以下のようにインポートします。
```python
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier()

```
# 5. モデル訓練
　データを訓練データとテストデータに分割し、モデルを訓練します。
```python
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=42)
model.fit(X_train, y_train)

```
# 6. モデル評価
　訓練したモデルを用いて、テストデータの予測を行い、モデルの性能を評価します。この結果は可視化します。
```python
from sklearn.metrics import accuracy_score
y_pred = model.predict(X_test)
print('Accuracy:',accuracy_score(y_test, y_pred))
```
# 7. モデルのチューニング
決定木の深さなど、モデルのハイパーパラメータを調整し、モデルの性能を改善します。ハイパーパラメータの調整にはグリッドサーチを用います。
```python
from sklearn.model_selection import GridSearchCV
parameters = {'max_depth':range(1,10)}
clf = GridSearchCV(DecisionTreeClassifier(), parameters, n_jobs=4)
clf.fit(X_train, y_train)
tree_model = clf.best_estimator_
print ('Accuracy:', accuracy_score(y_test, tree_model.predict(X_test)))
```
# 8. モデルのデプロイ
モデルのデプロイ方法は様々ですが、ここではPythonのpickleライブラリを使ってモデルを保存し、後で再利用する方法を示します。
```python
import pickle
pickle.dump(tree_model, open("decision_tree_model.pkl", "wb"))
```

# 9. モデルのモニタリングとメンテナンス
モデルの性能が低下した場合、新たなデータでモデルを再訓練する必要があります。定期的にモデルの性能をチェックし、必要に応じてモデルを更新しましょう。

# まとめ
以上、決定木を用いたAIモデルの構築を通じて、AIモデルの基本的な構築フローを学びました。Pythonのコードを書きながら学んだことで、理論だけでなく実践的なスキルも身につけられたことでしょう。さらに深く学びたい方は、[こちら](https://qiita.com/yutut/items/143cfd496a8eef299699)のリンクを参照してください。自身で問題を設定し、データを収集してAIモデルを作成することで、更なる理解を深められます。
【その６】サブフローを活用する

<br>[【その１】RPA初心者と歩むPower Automate活用日記【ポイ活】](https://qiita.com/tantanshio/items/2b741584f65d8ce967f8)


# ◆サブフローを活用する

処理が増えて、縦長になり見づらくなってきた

そこで、処理を見やすくするため、サブフローを利用する

作り方は
操作画面上部にあるサブフローから「新しいサブフロー」をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/f076e989-f152-976c-7448-abb06738e6a3.png)

名前を設定して保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/30914d2e-332f-38f9-4afd-3c04877c6c1b.png)




本ロボットでは
アプリが時々停止してしまうため、再起動をかける処理を
サブフローに用意しています（現在は1処理のみですが、増える可能性もあるため別分け）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/52bf91b0-5ba6-0451-852e-98d8a97bd1d0.png)

メイン処理からサブフローへ処理を流すには
「サブフローの実行」を入れてあげる必要があります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/4750b720-be17-e61a-0499-4dad4bf7913e.png)



ちなみに
サブフローからメインフローに戻す場合は特別処理を入れる必要はなく
サブフローに入っている処理を全て行うとメインフローに戻ります


# ◆次回　【その７】やりたいことを一通り入れて実行したらロボットが止まる
【ChatGPT無】step by stepは人間の仕事？


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

　プロンプトに「**step by step**」と指示すれば、まぁまぁの返答を得られるケースはあるようですね。
　日本語で「一歩一歩」なのかな。
　ChatGPTで、段階を踏んで、答えを導き出させる呪文。
　でも、本当にそうなのでしょうか？
　否定するわけではないですよ。


　ChatGPTは「一発で答えを得る」というよりも「やり取りをして、目標に近づく」という方が向いているように、私には感じられます。

　ですから、流れがわかっているのであれば、それを人間が、step by stepで指示していけば、より良い返答が得られるケースが多いと思われます。
　人力step by stepですねw

　また、流れがわかっていなくとも、やり取りすることで、明確化していく方法もとれます。

　ただし、ChatGPTは、人間で言うところの「短期記憶」が小さく（特に無料版は）、途中で目的を忘れてしまう・見失ってしまう場合もあります。
　そうなったら、一度、まとめさせてみるというのもありだと思います。

「**今までの指示をまとめてください。**」
　と指示すればまとめてくれます。
　まとまったことを編集して、
　　新たな指示として与えると、
　　　いいかも、です。

　またコードを吐き出してくる場合も
　　あります。
　　　しかも無条件にPythonでw

　指示する際に
「**コードはいりません。**」
とお断りしておきましょう。


※「短期記憶」
　　人間で言えば、
　　　すぐに忘れる程度の記憶。
　　人の名前とか、
　　　名刺をもらい忘れると
　　　　思い出すのが厄介ですね。

※「長期記憶」
　　反復練習したことや
　　　連想して覚える記憶。
　　自転車がよく例にあげられますね。
　　乗れるようになったら、一生物。