OmniAICreator/Qiita-1.07M huggingface dataset:
uvとGitHub ActionsでpythonパッケージとドキュメントのCI/CD


# はじめに
uvとGitHub Actionsでpythonパッケージの自動更新するテンプレートリポジトリを公開しました。

リポジトリ：https://github.com/jiroshimaya/version-update-workflow-sample

主に以下のようなことができます。

- git tagの自動インクリメント
- 自動テスト、lint、フォーマット
- sphinxによるドキュメントのビルドとGitHub Pages上での公開
- PyPI、TestPyPIでのパッケージ公開

本記事では、このリポジトリを作成した背景と簡単な使い方を紹介します。

# 背景

Pythonパッケージの開発中に以下の定常作業をなるべく簡単にしたいと思いました。

- PyPIの更新
- ドキュメントの更新

この解決策としてGitHub Actionsを使うことが考えられます。
一方、プライベートの開発では高速なpythonパッケージ管理ツールであるuvをよく使用しています。

この課題を持ち始めた時点では、uvとGitHub Actionsを組み合わせたプラクティスが世の中にあまりない気がしました。
そこで、[バージョン管理を自動化](https://qiita.com/shimajiroxyz/items/f1d92a6ccb0d2bbe33b5)したり、[ドキュメント更新を自動化](https://qiita.com/shimajiroxyz/private/ee751c62a9e1f75d612a)する方法を検討してきました。

今回、これらの知見を活かして、再利用しやすい形でまとめなおしたテンプレートリポジトリを作成したので、改めて背景や使い方をまとめました。

# 使い方
- 本リポジトリをテンプレートとした新規リポジトリを作成してください。
  - 参考: https://qiita.com/ryo2132/items/08f0561804c798012146
- 作成したリポジトリページのSettingページのSettingsから以下を設定してください。
  - GitHub ActionsによるリポジトリのReadとWriteの許可
  - GitHub Pagesの作成元をGitHub Actionsに変更
  - PyPIやTestPyPIのトークンをシークレットに登録
- ローカルにクローン
- uvが未インストールの場合はインストール
  - `curl -LsSf https://astral.sh/uv/install.sh | sh`
- `uv run task init`を実行して初期化
  
その他、詳細および最新の使い方はリポジトリのREADMEを参照してください。

# おわりに
実際に使いながら引き続き改良していこうと思います。
DatabricksでClaude Sonnet 3.7が利用できるようになりました！

こちらのニュースリリースが昨夜ありました。

https://www.databricks.com/company/newsroom/press-releases/databricks-and-anthropic-sign-landmark-deal-bring-claude-models

ブログはこちら。

https://www.databricks.com/blog/anthropic-claude-37-sonnet-now-natively-available-databricks

ということでこちらのアップデートです。

https://docs.databricks.com/aws/ja/release-notes/product/2025/march#claude-sonnet-37-now-supported-on-mosaic-ai-model-serving

> **Mosaic AIモデルサービングでClaude Sonnet 3.7がサポートされました**
> AnthropicのClaude Sonnet 3.7がMosaic AIモデルサービングでサポートされました。以下からClaude Sonnet 3.7 を利用できます:
> - [基盤モデルAPIトークン課金](https://docs.databricks.com/aws/ja/machine-learning/model-serving/foundation-model-overview)
> - 汎用[AI関数](https://docs.databricks.com/aws/ja/large-language-models/ai-functions): `ai_query`
> - [関数呼び出し](https://docs.databricks.com/aws/ja/machine-learning/model-serving/function-calling)

:::note info
**注意**
リージョンによってはロールアウトされるタイミングに差があります。執筆時点ではAWS東京リージョンはまだでしたが、USリージョンでは使えました。

**2025/3/28追記**
Azure、AWSともに東京リージョンでロールアウトされていました！
![Screenshot 2025-03-28 at 8.22.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b6bed443-d27c-4cd9-a107-3c861e0beb44.png)
![Screenshot 2025-03-28 at 9.16.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/0994edb5-fadc-47cb-9821-b8c35867d0c2.png)

:::

モデルサービングページに燦然と輝く**Claude Sonnet 3.7**が！

![Screenshot 2025-03-27 at 9.51.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/2d1b61df-51c4-4a65-b327-97119329014e.png)

AI Playgroundでも使えます。

![Screenshot 2025-03-27 at 9.52.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a8ce238c-7b7b-418f-a854-93ee09495d0c.png)

`ai_query`でも使えます。

```sql
SELECT ai_query("databricks-claude-3-7-sonnet", "マルチエージェントとは")
```
![Screenshot 2025-03-27 at 10.09.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/8a37a914-f2d4-4b77-80c9-d809151bf030.png)


### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
2010年から浦島太郎だった私が、IT業界の激変を振り返ってみた話

# 2010年〜2018年のIT業界の技術変革まとめ

こんにちは。エンジニア歴25年のアラフィフ主婦です。  
2010年から2018年の間、子育てに専念していたため、IT業界の技術進化についていけなかったブランクがあります。  
本記事では、自分自身の学び直しも兼ねて、その期間にIT業界で起こった主な技術トピックをまとめました。

## 🌩 クラウドの本格普及期

- **AWSが業界のデファクトスタンダードに**
  - EC2 / S3 / RDS / IAM などの主要サービスが浸透
  - **2014年：AWS Lambda（サーバーレス）の登場**
- **Infrastructure as Code（IaC）**
  - CloudFormation、Terraform の登場
- **他クラウドも台頭**
  - Google Cloud Platform（GCP）
  - Microsoft Azure

## 🐳 コンテナとDevOpsの時代へ

- **Docker（2013年）**
  - 開発・本番環境の差異解消、CI/CDが現実に
- **Kubernetes（2014年）**
  - コンテナのオーケストレーションツールとして標準化
- **CI/CD文化の加速**
  - Jenkins / Travis CI / CircleCI などの普及

## 🧠 AI・機械学習の爆発的進化

- **Deep Learningのブレイクスルー（2012年頃〜）**
  - AlexNetによる画像認識精度の向上
- **Pythonの台頭**
  - AI/機械学習分野での主要言語に
- **主なフレームワーク**
  - TensorFlow（2015年公開）
  - Keras、PyTorch、scikit-learn など

## 📱 スマホアプリの成熟期

- iOS / Android アプリが標準的に
- **React Native（2015年）登場**
  - JavaScriptでクロスプラットフォーム開発が可能に
- **モバイルファーストな設計思想の定着**

## 🌐 Web開発の進化

- **JavaScriptフレームワーク戦国時代**
  - AngularJS → React（2013）→ Vue.js（2014）
- **SPA（Single Page Application）の普及**
- **Node.js の台頭**
  - フロントエンドとバックエンドの垣根が縮小
- **Web API設計（REST, GraphQL）** の洗練

## 🧪 モダン開発文化の形成

- **GitHubがエンジニア文化の中心に**
- **CI/CDパイプラインの普及**
- **アジャイル開発・スクラム・DevOpsの浸透**
- **SaaSツールの活用が当たり前に**
  - Slack, Trello, GitLab, Firebase など

## 📝 まとめ

2010年〜2018年の間に、IT業界は以下のような大変革を遂げました：

- クラウドネイティブ化（AWSを中心に）
- コンテナ＆サーバーレスの登場
- AI・機械学習の大衆化とPythonの台頭
- スマートフォンアプリとクロス開発の進化
- Web開発のモダン化（SPA / API / Node.js）
- DevOpsとアジャイルによる開発文化の刷新

これらの変化をふまえて、私は現在、**「Python × AI × AWS」** を軸に学び直しを進めようと考えています。

同じようにブランクがある方、キャリアに不安を感じる方にも、何か参考になれば幸いです。
【Next.js+Firebase】Firebase Confingの読み込みに苦労していませんか

## firebase config
firebaseでwebアプリを作成する際、設定値として以下のスニペットでSDKを初期化すると思います。

```ts
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries

// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
  apiKey: "...",
  authDomain: "...",
  projectId: "...",
  storageBucket: "...",
  messagingSenderId: "...",
  appId: "...",
  measurementId: "..."
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
```

ただ、これかなり面倒です。
クライアントに露出するキーなのでセキュリティ上の懸念は少ないですが、環境ごとに異なる値なので直書きすることは行儀がよくないです。
そのため、環境変数を使用して渡すことになりますが、以下のような設定方法はあまりスマートに見えません。

```
NEXT_PUBLIC_FIREBASE_APIKEY=...
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=...
NEXT_PUBLIC_FIREBASE_PROJECT_ID=...
NEXT_PUBLIC_FIREBASE_STRAGE_BUCKET=...
NEXT_PUBLIC_FIREBASE_MASSAGING_SENDER_ID=...
NEXT_PUBLIC_FIREBASE_APP_ID=...
```

これを回避するために、JSONとして渡す方法があり、この方法を使用している方も多いのではないでしょうか。
```
NEXT_PUBLIC_FIREBASE_WEBAPP_CONFIG='{"apiKey":"...","appId":"...","authDomain":"...","databaseURL":"","messagingSenderId":"...","projectId":"...","storageBucket":"..."}'
```
これなら楽そうです。
環境変数として管理する値は一つになりました。

しかし、Firebase App Hostingを使用する場合はまた別の方法があります。

## App Hostingのビルド変数を使用する

Firebase App Hostingでは内部的にcloud buildを使用しています。
その際のログを見てみると、FIREBASE_WEBAPP_CONFIGがビルド時のみ有効になっています。
つまり、これを読み込むことができれば、デプロイ環境でのシークレット管理をゼロにできます。

```
2025/03/27 00:00:00 Final build schema:
runConfig:
  cpu: 1
  memoryMiB: 512
  concurrency: 80
  maxInstances: 1
  minInstances: 0
  vpcAccess: null
env:
- variable: FIREBASE_CONFIG
  value: '{"databaseURL":"","projectId":"...","storageBucket":"..."}'
  availability:
  - BUILD
  - RUNTIME
- variable: FIREBASE_WEBAPP_CONFIG
  value: '{"apiKey":"...","appId":"...","authDomain":"...","databaseURL":"","messagingSenderId":"...","projectId":"...","storageBucket":"..."}'
  availability:
  - BUILD
metadata:
  adapterPackageName: '@apphosting/adapter-nextjs'
  adapterVersion: 14.0.12
  framework: nextjs
  frameworkVersion: 15.2.3
```

この機能については公式でもほとんど言及されていません。

https://firebase.blog/posts/2025/03/apphosting-march-update

## NEXT_PUBLICでない環境変数をクライアントサイドで利用する

`next.config.ts`を変更する。

```ts:next.config.ts
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  /* config options here */
  env: {
    FIREBASE_WEBAPP_CONFIG: process.env.FIREBASE_WEBAPP_CONFIG,
  },
};

export default nextConfig;

```

呼び出し例（クライアントコード）
ローカル開発をしないと割り切っている場合は`initializeApp`を引数なしで呼び出せます
```ts
import { initializeApp } from "firebase/app";
const firebaseConfig = JSON.parse(process.env.FIREBASE_WEBAPP_CONFIG || "");
export const app = initializeApp(firebaseConfig);
```

## まとめ
- Firebaseの設定値を .env に NEXT_PUBLIC_ 付きで並べるのは管理が大変
- JSON形式で1つの環境変数にまとめるとスッキリする
- Firebase App Hosting を使う場合は FIREBASE_WEBAPP_CONFIG をそのまま使うのがベスト
- next.config.ts に FIREBASE_WEBAPP_CONFIG をセットすれば、クライアント側でも利用可能
自動返信メール (postfix)

## postfixの設定

* /etc/postfix/aliasesに以下追記

```
noreply:       "|/usr/bin/php /etc/postfix/noreply.php"
```

* 設定の反映

```
newaliases
```

## 処理

* /etc/postfix/noreply.php

```go
<?php
// メールの受信データを取得
$emailData = file_get_contents("php://stdin");

// 送信者のメールアドレスを抽出
preg_match('/^From: .*<(.*)>/m', $emailData, $matches);
$sender = $matches[1] ?? '';

// 自動返信メールの内容を設定
$subject = "自動返信";
$message = "このメールは自動返信です。";

$subject = "=?ISO-2022-JP?B?" . base64_encode(mb_convert_encoding($subject, "ISO-2022-JP")) . "?=";
$message = mb_convert_encoding($message, "ISO-2022-JP");

// 返信ヘッダー
$headers = "From: noreply@example.com\r\n";
$headers.= "Content-Type: text/plain; charset=ISO-2022-JP\r\n";
$headers.= "Content-Transfer-Encoding: 7bit\r\n";

// 返信メールを送信
if (!empty($sender)) {
    mail($sender, $subject, $message, $headers);
}
```


## 送信テスト

* noreply@example.com

宛にメールを送信して自動返信メールがくることを確認。


## ログの確認 (リアルタイム)

```
journalctl -f 
```
CORSに関するエラー

# エラー内容 
Access to XMLHttpRequest at 'http://localhost:8080/todos/create'
from origin 'http://{IP}' has been blocked by CORS policy

# 翻訳
🗣️「おい、フロントは http://{ElasticIP} から来てるのに、バックエンド（API）は http://localhost:8080 にあるじゃん？
でもCORS（クロスオリジン）対策されてねーからブロックするわ！」

## 捕捉

* オリジン
    * **スキーム＋ホスト＋ポート番号で定義**
        * http://example.com/app1/index.html
        * http://example.com/app2/index.html
* 上記の場合は、ファイルパスのみ異なるので同一オリジン
* 参照: https://developer.mozilla.org/ja/docs/Glossary/Origin

# バックエンドにCORS設定を追加

* @Configuration クラスに許可してよいオリジンを追記する

### コード例（※開発環境）
```java
@Configuration
public class WebConfig {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**") // 全エンドポイントに適用
                        .allowedOrigins("http://HOSTNAME") // 許可するオリジン
                        .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // OPTIONSも含む
                        .allowedHeaders("*")
                        .allowCredentials(true);
            }
        };
    }
}
```
【Azure】ADオブジェクト同期 ~意外と知らないフィルター処理について~

みなさん、こんにちは！

Entra Connect 同期についてお伝えできればと思います。

## Entra Connect 同期
ADで作成されたオブジェクト（ユーザー、連絡先、グループ、コンピューター）は、Entra IDに同期する際、ドメインやOU、属性に基づいて、Entra Connect側でフィルター処理を行う事が可能です。
ちなみに、、、属性でのフィルター処理はオブジェクトの種類毎に持つ属性に対してフィルター処理をかけることが可能

### 注意
規定の設定だと、ほぼすべてのオブジェクトが同期対象になるため、例えば個社システムの管理用にのみ利用している、サービスアカウント等の個人用以外のアカウントまで同期されてしまう事になる。
これが、一概に問題とも言えませんがEUの要望に応じて変更することが可能なため、Entra IDへの同期構成を考える際には使える機能。

### フィルター処理
このフィルター処理に関しては、Entra Connectサーバーを作成時でも運用中でも有効にする事が可能です。
ただし、フィルター処理をEntra IDに同期された後に構成した場合は、フィルター処理の内容によってはEntra ID側に同期されているオブジェクトの削除が起こります。
つまり、運用中に変更を加えることは意図されていない動作を招くことがあるという注意が必要。
ですが、意図的にその動作を想定している場合フィルター処理による削除動作で500ユーザー以上削除される場合には、削除保護機能の解放/無効が必要になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/05fbcbab-2ef7-4e9b-b304-cb55fada1371.png)
MLflow Community Meetup 3/26のまとめ

今朝聴いてました。登壇されていたお二人とは同僚です。

https://lu.ma/mlflow326?tk=WcOPFs

録画も公開されていました

<iframe width="560" height="315" src="https://www.youtube.com/embed/Qdw2r-12muM?si=mqw45W3T_kDRRduF" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

前半はプロンプトレジストリ。

![Screenshot 2025-03-27 at 8.23.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/99dd251c-1666-4902-a88f-31bd0b29644a.png)
![Screenshot 2025-03-27 at 8.23.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/843d3284-0153-4a9e-a6a2-05d5057ad676.png)

[MCPサーバー](https://github.com/B-Step62/mcp-server-mlflow)もあるとのこと。
![Screenshot 2025-03-27 at 8.25.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/dcf078f5-64d5-48fc-a7ef-4b0968f59b56.png)

そして、MLflow 3.0。モチベーションから。

MLflow 2.xの情報アーキテクチャは従来のMLでは問題なかったが、モデルのチェックポイントが多数作成されるディープラーニングや、トレーニングではなく評価を伴う生成AIユースケースではランにトレース、フィードバック、メトリクスを紐づけるのが困難だった。

![Screenshot 2025-03-27 at 8.32.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/3dec0fc4-8442-4943-8dcd-72d26465dce6.png)

そこで、MLflow 3.0では情報アーキテクチャに**モデル**が追加される。**Logged Modelエンティティ**がエクスペリメントに追加。モデルIDを持ち、メトリクス、トレース、評価はモデルに紐づけられるように。

![Screenshot 2025-03-27 at 8.32.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d0cf9982-5f3a-4f93-999c-0c34b2d4798a.png)

エクスペリメントページにModel UIが追加される。

![Screenshot 2025-03-27 at 8.37.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/08cfc453-a2f3-4efb-b377-afdd4a5f1fb7.png)

モデルはランのアーティファクトとしては保存されなくなる。`log_model`の`artifact_path`はdeprecatedに。新たな`name`パラメータを使う。

![Screenshot 2025-03-27 at 8.39.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/24d11a45-1658-4cd3-9a8a-a19e775fab63.png)

MLflow 3.0ではディープラーニング、生成AIワークフローを強化するためにモデル中心の情報アーキテクチャを導入。3.0.0.rc0は3月末あるいは4月頭にリリース。3.0.0は5月中旬リリース。

![Screenshot 2025-03-27 at 8.41.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/4cb43d61-fa20-441d-a62c-c28530981218.png)


スターターサンプルはこちら。

https://github.com/mlflow/mlflow/tree/mlflow-3/examples/demos/mlflow-3
外部キー制約なしでも hasMany / belongsTo は使える？仕組みと注意点を解説

# はじめに

LaravelのEloquent ORMでは、`hasMany` や `belongsTo` を使ってテーブル同士の親子関係（リレーション）を定義できます。

その際によく「外部キー制約が必要なのでは？」と思われがちですが、実は **Eloquentは外部キー制約がなくてもリレーションが機能します。**

今回はその仕組みと注意点を、自分の備忘録としてまとめます。

---

# ①外部キー制約なしでもリレーションは使える！

Eloquentの `hasMany()` や `belongsTo()` は、**あくまで** **「モデル同士の紐付けルール（クエリの構築ルール）」** を定義しているだけです。

そのため、**実際にデータベースに外部キー制約（FOREIGN KEY）がなくても機能します。**

---

# ②具体例：User と Post のリレーション

### posts テーブル（外部キー制約なし）

```php
Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->unsignedBigInteger('user_id'); // 外部キー制約は付けない
    $table->timestamps();
});
```

**モデル側の定義**
```php
// User.php
public function posts()
{
    return $this->hasMany(Post::class);
}

// Post.php
public function user()
{
    return $this->belongsTo(User::class);
}
```
このように定義しておけば、外部キー制約がなくても、$user->postsや$post->userは,
**正しく機能します。**

# ③なぜ動くのか？
Eloquentはリレーション定義をもとに、内部でSQLクエリを組み立てています。

例えば:
```php
$post->user
```
は、実際には以下のようなクエリが実行されます：
```sql
select * form users where id = $post->user_id limit 1;
```

つまり、**「user_idというカラムがある」ことが重要であって、DBに外部キー制約があるかどうかは関係ない**ということです。

# ④外部キー制約がなくてもよいのか？
結論から言うと、開発や学習環境ではOK！ですが、
**本番環境では注意が必要です！**

**制約なしのメリット:**
- 柔軟に開発できる
- 移行や変更が簡単(特にプロトタイプ段階)

**制約なしのデメリット**
- 調合性が保証されない(存在しないpost_idをpostsに設定できてしまう)
- 誤削除・参照エラーのリスク(ユーザー削除後にpostsが「孤立」することも)

# ⑤外部キー制約はつけるべき？
本番環境では以下のように、**外部キー制約をつけることが推奨されます:**

```php
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
```
- データの整合性を保つ
- Laravelのリレーションに加えて、DBレベルでも保証される

# ⑥まとめ
![IMG_7732.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2246240/d1c7fbc5-00b3-482d-bfd4-0ee1f5935544.jpeg)

Laravelでは、**リレーション＝モデルの関係定義、外部キー制約＝DBの安全ネット** という意識で使い分けると理解しやすくなります！
【Rails 初学者】Mac(M1) にHomebrewでRedisをインストールして起動するまでの手順メモ

こんにちは。
エンジニア転職を目指して勉強中を始めたばかりです。 
この記事では、M1チップ搭載のMacBook AirにRedisをインストールし、起動するまでの流れをまとめます。

自分用のメモとして、残しておきます。

---

## 環境

- macOS (M1チップ搭載 MacBook Air)
- Homebrew（パッケージ管理ツール）

---

## Redis をインストールする

まずはHomebrewでRedisをインストール。

```bash
brew install redis
```

実行時に表示された内容（一部）
```
==> Auto-updating Homebrew...
==> Downloading https://ghcr.io/v2/homebrew/core/redis/manifests/7.2.7
==> Pouring redis--7.2.7.arm64_sonoma.bottle.tar.gz
...
🍺  /opt/homebrew/Cellar/redis/7.2.7: 15 files, 2.4MB
```

## Redis を起動する方法
Homebrew公式の方法で常駐起動させるには以下のコマンドを使用
```
brew services start redis
```

## sudo redis-server で起動してみる
以下のコマンドでもRedisを起動できる。
```
sudo redis-server
```
```
95684:C 27 Mar 2025 04:06:02.273 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
...
95684:M 27 Mar 2025 04:06:02.274 * Ready to accept connections tcp
```
Redis のASCIIアートが出て、Ready to accept connections tcp と表示されたら起動成功


## Redis クライアントから接続確認
別のターミナルを開いて以下を入力
```
redis-cli
```
Redis のプロンプトが表示されたら接続成功
```
127.0.0.1:6379>
```
接続確認として以下を入力
```
ping
```
結果
```
PONG
```
Redisが正しく起動していることが確認できた。

------
間違えていたら、すいません。
引き続き、学習を続けていきます。
フローを使って複数のレコードをメールの本文としてHTMLのテーブルで表示する




+ [対象レコードを抽出してアラート通知を出したい](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000MYhiQ)
+ [How to Send Email With a Record Table in Flow](https://salesforcetime.com/2023/11/02/how-to-send-email-with-a-record-table-in-flow/)

検証したいだけなので、今回は自動起動フローを使っています


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/cc87cf00-0330-4993-a4b6-90feb6f7d11d.png)

嵌まったポイントはテキストテンプレートです。
最終的なテンプレートemailBoyだけはリッチテキストとして、部品になるテンプレートは全てプレーンテキストで作成します。リッチテキストだとHTMLのコードが表示されてしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a42e9ea1-b003-4a8f-8ccc-a6ebf52501b4.png)

テキストテンプレートはループの中の変数を指定できるので、テキスト型の変数に１行ずつ追加していくことはtd句を生成できます。ここもポイントです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/7cff01fd-d90a-48b1-8c01-0b15dcf8bc16.png)



結果：今回はプレイグランドを使って実装してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/5e9e3da6-5484-4664-85a3-ae4de4b35f02.png)
Fargate入門：具体像がつかみにくかったFargateを、クラスタやタスク定義を“給食”にたとえてみた話

## はじめに

AWS ECSは、コンテナアプリケーションの運用に便利なサービスですが、初めて触れると構成要素が多くて混乱しがちです。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

今回は、ECSの主要な要素を「食べ物」にたとえて、視覚的に理解しやすくまとめました。特に初心者の方にとって、楽しく学べる入り口になることを目指します。

## 書こうと思ったきっかけ

勉強会でECSについて話したとき、「クラスターとかタスク定義って抽象的で覚えにくい」という声がありました。

***そこで、身近なたとえを使って説明したところ、とても好評だったため、備忘録としても残すことにしました。***

## ECS構成を食べ物にたとえる

| 構成要素 | 意味 | たとえ | 補足説明 |
|----------|------|--------|----------|
| クラスター | リソースをまとめる単位 | お弁当箱 | タスク（中身）やサービス（お世話係）をまとめて運ぶ箱。環境やリソースの大枠を決める存在。 |
| サービス | タスクを維持管理 | 給食のおばちゃん | 常に一定数のタスク（おかず）を提供し続けるための仕組み。タスクが消えると補充もしてくれる。 |
| タスク定義 | コンテナの設計書 | コーチからの作戦指示 | どんなコンテナを動かすか、その仕様や設定をまとめた設計図。レシピのようなもの。 |
| タスク | 実動プロセス | お弁当の中身 | タスク定義（レシピ）に従って具体的に作られたお弁当の内容。実際に動いているアプリの単位。 |
| コンテナ | 実行単位 | 肉まん・あんまん | タスクの中にある、実際に動くひとつひとつのアプリケーション。味（処理内容）は違っても、形（構成）は似ている。 |

このようなたとえを使うことで、ECSの構成要素がより身近に感じられるようになります。

**ECS学習の第一歩として、ぜひ役立ててみてください。**

## まとめ

ECSは一見複雑ですが、身近なたとえを通じて理解すると、全体像がぐっとつかみやすくなります。

:::note warn
**特に、構成要素がそれぞれ何を担っているかを感覚的に掴めるのは大きな助けになります。**
:::

お弁当のイメージを思い出しながら、実際の設定や構築にトライしてみてください！
個人的備忘録：Flask×フロントエンドでCORSエラーが出たときの対処法について調べてみた

## はじめに

Webアプリケーションの開発中、フロントエンドとバックエンドが異なるポートやドメインで動いていると、通信がうまくいかずに "CORSエラー" に悩まされることがあります。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

今回は、PythonのFlaskでCORSに対応するための方法を、備忘録としてまとめます。

## CORS（クロスオリジンリソースシェアリング）とは？

CORSとは、ブラウザが異なるオリジン（ドメイン・ポート・スキーム）からのリクエストを制限する仕組みです。

たとえば：

- フロントエンドが `http://localhost:3000` で動いていて
- バックエンド（Python）が `http://localhost:5000` にある場合

ブラウザは「別のオリジンからデータを取得しようとしている」と判断し、CORSエラーを出すことがあります。

## Python（Flask）の場合のCORS対策

### Flask + flask-cors を使う

最も簡単な方法は、`flask-cors` ライブラリを使う方法です。

#### インストール
```bash
pip install flask-cors
```

#### 使い方（例）
```python
from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)  # すべてのオリジンを許可

@app.route("/hello")
def hello():
    return {"message": "Hello from backend!"}
```

### オリジンを限定したい場合
```python
CORS(app, origins=["http://localhost:3000"])  # 特定のオリジンだけ許可
```

## よくあるCORSエラー

```
Access to fetch at 'http://localhost:5000/hello' from origin 'http://localhost:3000' has been blocked by CORS policy
```

これはFlask側でCORS設定がされていないために発生します。

## 他のフレームワークの場合（自分調べ）

- Django：`django-cors-headers` ライブラリを使用
- FastAPI：`from fastapi.middleware.cors import CORSMiddleware` を使います

https://qiita.com/shun198/items/9ebf19d8fd2c412396dd

https://fastapi.tiangolo.com/ja/tutorial/cors/

## 補足：CORSは「サーバー側」で制御する

CORSの制限や許可は「サーバーが返すレスポンスヘッダー」で決まるので、クライアント側（JavaScriptなど）で無理に対処するのはNGです。

## まとめ
CORSは、最初は難しく感じても、仕組みを理解すれば柔軟なAPI連携の土台になります。

:::note warn
**今回のようにFlaskや他のフレームワークで正しく設定することで、エラーも回避できます。**
:::

学習を通して「なぜ制限されるのか」「どう解決できるのか」を考える姿勢が大切だと感じました！
【簡単AWS】【AWS CloudFormation】CloudFormationのサービスロールとは？

### 📌 まずはCloudFormationを理解しましょう
AWS CloudFormationは、AWSリソースを**自動的に作成・管理**できるサービスです。YAMLまたはJSONのテンプレートを使用して、EC2・RDS・S3などのAWSリソースを**一括でデプロイ**することが可能です。

---

### 🔍 CloudFormationのサービスロールとは？
CloudFormationは、AWSリソースを作成・更新するためにAWSの権限が必要です。しかし、CloudFormation自体にはデフォルトで権限がないため、**IAMロール**を使用して必要な権限を付与する仕組みが「CloudFormationのサービスロール」です。

- **サービスロールを指定しない場合**：CloudFormationは**実行ユーザーのIAM権限**を使用します。
- **サービスロールを指定した場合**：CloudFormationは**指定したIAMロールの権限**でリソースを操作します。

---

### 📌 なぜサービスロールが必要なのか？
#### ✅ **1. セキュリティの向上**
- CloudFormationがアクセスできるAWSリソースを**厳密に制御**できます。
- **不要な権限の付与を防止**し、誤った操作を抑制できます。

#### ✅ **2. 権限の少ないユーザーでもCloudFormationを実行可能**
- 例えば、開発者がEC2を作成する権限を持っていなくても、
  CloudFormationにEC2作成権限のある**サービスロールを付与**すればデプロイが可能になります。

#### ✅ **3. 組織・チームのセキュリティポリシーに適合**
- 企業やチームでは、**すべてのユーザーが直接AWSリソースを操作することを禁止**し、
  CloudFormationを通じてリソースを管理するケースがあります。

---

### 🛠️ CloudFormationでサービスロールを設定する方法

#### ✅ **方法1：AWSマネジメントコンソールで設定**（推奨）
1. **IAMロールを作成**（CloudFormationに必要な権限を付与）
   - AWS IAMコンソールで新しいロールを作成します。
   - 信頼されたエンティティとして**CloudFormation**を選択します。
   - 適切なポリシー（例：EC2やS3の作成権限）を付与します。
   - 作成後、**ロールのARN（例：`arn:aws:iam::123456789012:role/MyCloudFormationRole`）**をメモします。

2. **CloudFormationのスタック作成時にロールを指定**
   - CloudFormationの「スタック作成」画面で**「IAMロールを指定」**を選択します。
   - **作成したIAMロールのARNを入力**します。
   - 以降、CloudFormationはそのロールの権限でAWSリソースを操作します。

---

#### ✅ **方法2：AWS CLIで設定**
CLIを使用してCloudFormationのサービスロールを指定することも可能です。

```sh
aws cloudformation create-stack \
    --stack-name MyStack \
    --template-body file://my-template.yaml \
    --role-arn arn:aws:iam::123456789012:role/MyCloudFormationRole
```

このコマンドを実行すると、CloudFormationは`MyCloudFormationRole`の権限でスタックを作成します。

---

### 📌 まとめ
✅ **CloudFormationはAWSリソースを自動管理するサービスです。**
✅ **サービスロールを使用することで、CloudFormationの権限を明確に管理できます。**
✅ **組織やチーム単位でのセキュリティ管理が容易になります。**
✅ **IAMロールを作成し、CloudFormationの実行時に指定することで簡単に設定可能です。**

CloudFormationを活用する際は、セキュリティと利便性を両立するためにサービスロールの利用を検討しましょう！🚀
スライドに挿入するような論理構造や手順を示すグラフィクスをHTML+CSSで表現

プレゼンのスライドに挿入するような、論理構造や手順を示すグラフィクスをHTML+CSSで表現してみました。

## ストレートな展開の例

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="emYLZoM" data-pen-title="logic straight" data-user="yamahige" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yamahige/pen/emYLZoM">
  logic straight</a> by Taku Yamaguchi (<a href="https://codepen.io/yamahige">@yamahige</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

## 循環する展開の例

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="dPyqMEB" data-pen-title="logic cycle" data-user="yamahige" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yamahige/pen/dPyqMEB">
  logic cycle</a> by Taku Yamaguchi (<a href="https://codepen.io/yamahige">@yamahige</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

## 循環する展開でコンパクトな例

循環する展開で、上下のアイテムが左右のアイテムにオーバーラップする、左右方向にコンパクト例

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="ogNJRvx" data-pen-title="logic cycle compact" data-user="yamahige" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yamahige/pen/ogNJRvx">
  logic cycle compact</a> by Taku Yamaguchi (<a href="https://codepen.io/yamahige">@yamahige</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

## Webページに埋め込んだ例

これらサンプルをWebページに埋め込んだ例はこちら:

[サンプルを表示する](https://yamahige.github.io/20250326_visual_structure/slide.html)

## スライドに埋め込んだ例をVivliostyleで見る

[Vivliostyle](https://vivliostyle.org/)で作ったスライドなら、各スライドのヘッダーにスライドのタイトルを表示したり、「スライド番号 / 総スライド数」といった表示ができます。

[Vivliostyleでサンプルを表示する](https://vivliostyle.org/viewer/#src=https://yamahige.github.io/20250326_visual_structure/slide.html)

VivliostyleではMarkdown ([VFM, Vivliostyle Flavored Markdown](https://gihyo.jp/article/2024/03/vivliostyle-02))をソースにできます。

そこで「ストレートな展開の例」のソースは次の通りです:

```md
<figure class="--logic-flex-inline">

1. 夜をこめて
1. 鳥の空音は はかるとも
1. よに逢阪の 関はゆるさじ

</figure>
```

「循環する展開の例」のソースは次の通りです:

```md
<figure class="--logic-cycle-4">

- 吾輩はAである
- なぜA?
- 吾輩はBである
- なぜB?

</figure>
```

せっかくMarkdownなのでソースをシンプルにしておきたいとすると、`style`などの属性を使わずにCSSだけで頑張るのが工夫のしどころでしょうか。

<hr>

色違い、矢印のバラエティ、配置のバラエティなどから選んでスライドに使えると楽しそうです。そういったスニペット集があるといいかも。

HTMLでスライドを作ってプレゼンするのは昔からやられてます。そこで、こういった図の中身もHTML+CSSでやってみました。
ComfyUIのワークフローデザインの躓（つまず）き所

#### ComfyUIのワークフローデザインの躓（つまず）き所
ComfyUIは画像生成AIだけでなく、様々なAIを導入し、使いこなすための素晴らしいUIツールです。しかし、AIモジュールやプラグインの進化やバージョンアップが激しすぎて、すんなり導入できずに困っている方も多いのではないでしょうか。
この記事では、civitai.comにある以下のワークフローで実習していきます。
このワークフローは、Live Portraitで一枚の顔画像の表情を制御し、最初の画像と表情を変えた画像をモーフィングする動画を生成するものです。

https://civitai.com/models/867780/ab-morph-cogvideo-face-animation-rig-for-advanced-liveportrait

![名称未設定 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430586/f9e57c5b-201f-4182-8d53-94496ee32767.png)


まず、このワークフローをダウンロードし、abMorphCogvideoFace_v09.zipを解凍して、起動しているComfyUIの画面にドロップします。
図のように赤枠で囲まれたノードがある場合は、不足しているノードがあります。

![missing 2 スクリーンショット 2025-03-26 215401.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430586/f460254c-6aa9-4bfd-9b22-862cf8ac51df.png)

ComfyUIのManagerメニューから、
```
Manager -> Install Missing Custom Node
```

![misssing スクリーンショット 2025-03-26 215526.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430586/95665fd6-4d65-42ce-abdf-c1b1ec014749.png)

足りないノードをインストールするか、インストールされているがバージョンが違う場合はバージョンを変更するなどして対処します。

#### ノードがインストールできない

上の方法でノードがインストールできない場合、ComfyUIのリストに登録されていないということですので、手動でインストールする必要があります。その場合は、ノード名を検索エンジンで検索し、そのプラグインのGitHubサイトを探しましょう。
検索エンジンで見つからない場合は、ChatGPT-4のdeep researchなどで探すと見つかる場合があります。ComfyUIフォルダ下のcustom_nodesフォルダに移動し、以下のコマンドで導入できます。
``` 
git clone <そのプラグインのgitのアドレス>
````

#### ノードをインストールしても、モードが赤枠に囲まれている

 ノードをインストールしたり、バージョンアップしても、ノードが赤枠で囲まれている場合、ComfyUIのJSスクリプトの中のノードのバージョンが古い可能性があります。
この場合、ComfyUI画面の何もないところをダブルクリックし、そのノードと同じノードを新たに追加し、そのノードに接続をし直してみましょう。このとき、そのノードと繋がっている他のノードも古い場合がありますので、他のノードも追加し直して、繋ぎ直してみてください。

 #### ノードを入れ替えても動作しない。

 この場合は、そのノードが古すぎるか、バージョンアップがもう行われていない可能性があります。自力で対応する必要があるでしょう。
別のワークフローで動作しているノードの接続を参考にして、ノードと接続を置き換えます。

 ![スクリーンショット 2025-03-27 073753.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430586/7adfe44b-fe79-4247-ad57-e657350b8eed.png)

この場合、CogVideoFunX Samplerを　Cogvideo Samplerと、Cogvideo ImageEncode FunInPという二つのノードに分解して使っています。


#### モデルの導入に失敗

　このワークフローで、CogVideoXのモデルのダウンロードのところで、失敗（いつまでもダウンロードできないなど）があります。この場合は、CogVideoX-Fun-V1.5-5b-InPで検索やDeep　Researchし、ダウンロードします。これ（diffusion_pytorch_model.safetensors）を、ComfyUI\models\CogVideo\CogVideoX-Fun-V1.5-5b-InP\transformer
 フォルダに置きます。このフォルダは、上の失敗したときに作成されています。

![スクリーンショット 2025-03-27 074552.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430586/3ea30edc-96c1-4698-825b-ce997b6d11d9.png)


もともと手動でダウントードすべきモデルは、civitai.comかhugging faceからダウンロードするか、Manager ⇒ Model Managerからインストールします。
手動でダウンロードしたモデルは、modelフォルダ下の然るべきフォルダにセーブします。
Git怖くないシリーズその2(全5回)：マージとの向き合い方

## おさらい

- Gitはマージが頻繁に起こる
- 自動マージが優秀
- コンフリクト（衝突）は手動で解消する必要がある

----
## マージが正しいのか？

- 自動マージも、コンフリクト時も、結果が正しいかどうかを**確認する必要がある**
- 正直、特効薬はないと感じる

----
## 考え方

- 競合を起きにくくする
  機能単位でモジュールを分割、担当は機能単位にアサイン
  CVS/SVNでもやっていること！
- 「正しさを確認する方法」を確立

----
## 正しさを確認する方法

- **テストコード**：これが理想
  Gitはテストコード文化と共に浸透したように思う
- 実際の動作を見る機会・時間を増やす
  メインブランチの状態を常にどこかにデプロイして触れるようにしておき、デグレなどに気づけるようにしておく
  CI/CDは価値が高い
- 開発者に動作確認を依頼する：正直、現実的でないかな・・・
- (番外)コードをシンプルに保つ


----
## (寄り道)マージ作業者にとっての利点

- 良い副作用：マージ作業者は様々なコードを目にすることになる
- マージ作業を通してソースコードへの理解が深まる


----
## マージをしやすくする配慮

- スカッシュ操作：連続する複数のコミットを１つにまとめる
  差分が見やすくなるため、マージ作業がしやすくなる
  大きなマージはコミットも多くなる傾向があるため、スカッシュされていないとほんっとーに地獄です。
- 差分を確認しやすいコーディングルール
  １行に詰め込みすぎない

```csharp
public void Do(string userName, int level, string authName)
{
    ...
}
```

```csharp
public void Do(
    string userName,
    int level,
    string authName
)
{
    ...
}
```

----
## 最後に
- テストコードは銀の弾丸に近い
  重要なロジックだけでもテストコードを書いておくと心理的安全性が飛躍的に高まる
- 動作を見る機会を増やすのも有効
- 各開発者もマージしやすさに貢献できる
- マージ作業は絶好の成長機会
Vue3 背景画像の設定方法

<template>
  <div :style="{ backgroundImage: `url(${bgImage})` }" class="bg-container">
    背景画像を設定
  </div>
</template>

<script setup>
import { ref } from 'vue';

const bgImage = ref('/path/to/image.jpg'); // 画像のパス
</script>

<style>
.bg-container {
  width: 300px;
  height: 200px;
  background-size: cover;
  background-position: center;
}
</style>
windows11で、sketchup6 その5

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
CADに、近づけたいので、copilotに聞いてみた。

# 回答

CAD（コンピューター支援設計）では、立体的なモデルを作成する際に、さまざまな**プリミティブ（基本形状）**や**ブール演算**を使用します。
以下は、それぞれの要素についての簡単な説明です：

---

### **プリミティブ**
これらはCADで使用される基本的な形状で、より複雑なモデルの構築に利用されます。
- **Cube（立方体）**: 長方形の箱型の形状。多くのモデルの基礎として使用されます。
- **Sphere（球）**: 完全な球体で、丸い形状を作る際に使用します。
- **Cylinder（円柱）**: 丸い底面を持つ柱の形状で、よく円筒部品やドラム形状に適用されます。

---

### **集合演算（ブール演算）**
複数の形状を組み合わせたり、削除したりするための操作です。これにより、シンプルな形状から複雑なモデルを作成します：
1. **Union（合併）**: 2つ以上の形状を結合し、1つのオブジェクトにします。
2. **Subtract（減算）**: 1つの形状から他の形状を引き算して切り抜きを行います。例：球体に穴を開ける。
3. **Intersect（交差）**: 2つの形状の重なった部分だけを残し、他を削除します。

---

### **Inverse（反転）**
形状や方向を逆にする操作です。例えば、法線（面の向き）を反転したり、空間の負の部分を定義する際に使います。

これらの操作を活用すると、シンプルな部品から複雑なデザインまで、さまざまなものをCADで表現することができます

CADの三面図は、製図や設計において非常に重要な役割を果たします。三面図とは、対象物を三つの異なる方向から見た図面を指し、通常は以下の三つの視点で構成されます：

1. **正面図**（Front View）  
   - 対象物を真正面から見た図面で、主要な形状や寸法が表されます。
   - 対象物の「高さ」と「幅」の情報が含まれています。

2. **平面図**（Top View）  
   - 対象物を真上から見た図面で、配置や形状を確認できます。
   - 「幅」と「奥行き」の情報が含まれています。

3. **側面図**（Side View）  
   - 対象物を横から見た図面で、深さや詳細な構造がわかります。
   - 「高さ」と「奥行き」の情報が含まれています。

これらの図面は、設計者や製造業者が対象物の全体的な構造や寸法を正確に理解し、形状や空間関係を明確にするために使われます。三面図の正確さは、プロジェクト全体の成功に直結します。

以上。
Microsot Fromsリマインド機能/一時保存機能について備忘録 (2025年3月時点)

仕様の紹介です。

## 1. リマインド機能

「リマインド機能は公式的に用意されているのは以下3パターン存在

以下参考:

https://support.microsoft.com/ja-jp/office/%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%81%AE%E6%8B%9B%E5%BE%85%E3%82%92%E9%80%81%E4%BF%A1%E3%81%97-%E9%80%9A%E7%9F%A5%E3%82%92%E7%AE%A1%E7%90%86%E3%81%99%E3%82%8B-ca969c59-e27a-475d-9f24-4da924158949


#### 1\.回答者にフォーム送信した翌日にリマインダーの送信 

[リマインダーの送信]を選択

※リマインドメールの頻度の設定は未実装
  例えばForms送信3日後にリマインドを流すなどはできない。
  基本的には送信後、未回答者に翌日連絡

#### 2\.状況確認メールの送信

フォームまたはクイズの「応答] タブを使用して、[リマインドする]を選択

#### 3\.スマートリマインダーの機能

「以下の目的で使用する場合に使えるCopilotの機能 
※初期状態ではグレーアウトされているので有効化が必要

https://support.microsoft.com/ja-jp/topic/%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%81%A7%E3%81%AE-copilot-%E3%81%AE%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88-%E3%83%AA%E3%83%9E%E3%82%A4%E3%83%B3%E3%83%80%E3%83%BC-d41f412f-f64a-4bee-b745-eebf58b7e036

##### 目的
- 未回答者に通知する
- フォームのインサイトを確認するように促す: 回答数が多い場合、結果の確認をリマインド
- 参加者の行動に基づいてパーソナライズされたメッセージを送信する:参加者にフォームへの記入を促す
- フォーム作成者にフォローアップ アクションを提案する

##### <手順>
1\.フォームまたはテストを作成
2\.次のオプションを選択して、フォーム設定を構成します。

:::note info
すべてのユーザーが返信可能
回答を受け付ける
各回答の通知をメールで受け取る
スマート通知メールを取得して、応答の状態を追跡するを有効化
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571614/deb4e56f-4b8a-480f-8a74-c569823b396d.png)

3\.応答の収集機能を使用して応答者を招待。

4\.スマート リマインダーの機能: 
- 他のユーザーがメールの招待を受け取ってもフォームを送信しない場合、
フォームの所有者は約 16 時間後に応答の状態のメールを受け取る。

- メール内の [リマインダーの送信] ボタンを選択して、
応答者以外のユーザーにリマインダーを送信し、フォームに記入するよう促す。


#### (4) Power Automateで未回答者あてにリマインドを送ることを設定することにより、 定期的にリマインダーできる。(おまけ)

役立つかもしれない記事

https://powervbadesktop.com/powerautomate1/

https://blog.jbs.co.jp/entry/2023/03/16/124533

## 2.一時保存機能

#### 1)一時保存機能はMicrosoft Formsでは実装なし

※ちなみにGoogleのFormsでは実装あり。

#### 2)もし一時保存機能を実装したい場合は？？

Forms Pro(Dynamics 365 Customer Voice) であれば、回答途中での保存が可能


##### 参考資料
Title: 進行中の調査を保存する [調査作成者エクスペリエンス]

https://learn.microsoft.com/ja-jp/dynamics365/customer-voice/save-survey-progress#survey-author-experience


:::note warn
ただし有料
:::
HeliScriptとC#の違いをざっくりとまとめてみた

## 概要
HeliScript初学者向けに、C＃との主な違いをコンパクトにまとめました。
効果的な学習方法としては、[公式ドキュメント](https://vrhikky.github.io/VketCloudSDK_Documents/latest/hs/hs_overview.html)を読みながら実際にコードを試してみることをお勧めします。
この違いを頭に入れておくと、つまずきが少なくなると思います。

:::note warn 
2025/3現在のHeliScript仕様にもとづいた記事となります。
:::

## Heliscriptでは出来ない
- パラメーター付きコンストラクタ
- enum
- static
- インスタンス変数をフィールドで初期化
    - ただし、constを付与した定数の[基本の組み込み型](https://vrhikky.github.io/VketCloudSDK_Documents/latest/hs/hs_var.html#_2)は可能
- 型の名前と同じ変数名
- オーバーロード（同名異引数のメソッド）
- 非同期処理
    - ただし、Updateを利用した簡易的な処理は可能
- readonly修飾子
- interface 
- [基本の組み込み型](https://vrhikky.github.io/VketCloudSDK_Documents/latest/hs/hs_var.html#_2)以外の引数を持つメソッドのdelegate

## C#では出来ない
- [グローバル関数、グローバル変数の使用](https://vrhikky.github.io/VketCloudSDK_Documents/latest/hs/hs_statement_def.html)
    - HeliScript ではこれらを使用できます
 
## 実行環境の違い 
HeliScriptファイルはブラウザ上で直接実行されます。
- C#スクリプト: Unityでapkとしてビルドされる際に、中間言語にコンパイルされます
- HeliScriptスクリプト: ビルド時にコンパイル工程がなく、webブラウザでコードがそのまま実行されます

:::note info
**[VKCコンポーネント](https://vrhikky.github.io/VketCloudSDK_Documents/latest/VKCComponents/VKCItemActivity.html)のビルドの流れ**
HeliScriptファイルと異なり、一旦JSONファイルに反映されます
1. ユーザーがUnity EditorのInspector上でコンポーネントを設定
2. ビルド時にその設定がJSONファイルに反映されます
3. ブラウザでそのJSONを解釈・実行することで、ワールド内にアイテムが表現されます
:::
windows11で、sketchup6 その3

# 概要
windows11に、sketchup6を入れてみた。
rubyやってみた。

# 練習問題
UI testを書け。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1f943334-1ca9-4068-8503-51ff26406455.png)

# サンプルコード

```

require 'sketchup.rb'

def beepTest
	status = UI.beep
	if (status)
		UI.messagebox status
	else
		UI.messagebox status
	end
end
def inputBoxTest
	prompts = ["Width", "Height", "Depth"]
	values = [6, 5, 4]
	results = inputbox prompts, values, "Test"
end
def getMenuTest
	draw_menu = UI.menu("Draw")
	if (draw_menu)
		UI.messagebox "Success"
	else
		UI.messagebox "Failure"
	end
	begin
		invalid_menu = UI.menu("InvalidMenu")
	rescue
		UI.messagebox $!.message
	end
end
def messageBoxTest
	keypress = UI.messagebox "Testing with Just a String"
	UI.messagebox keypress
	UI.messagebox "Testing with a String and Type", MB_MULTILINE
	UI.messagebox "Testing with a String, Type, and Title", MB_MULTILINE, "Test"
	keypress = UI.messagebox "Testing MB_OKCANCEL", MB_OKCANCEL
	UI.messagebox keypress
	keypress = UI.messagebox "Testing MB_YESNOCANCEL", MB_YESNOCANCEL
	UI.messagebox keypress
	UI.messagebox "Testing MB_YESNO", MB_YESNO
	keypress = UI.messagebox "Testing MB_RETRYCANCEL", MB_RETRYCANCEL
	UI.messagebox keypress
	keypress = UI.messagebox "Testing MB_ABORTRETRYIGNORE", MB_ABORTRETRYIGNORE
	UI.messagebox keypress
end
def openURLTest
	status = UI.openURL("http://www.sketchup.com")
	if (status)
		UI.messagebox status
	else
		UI.messagebox "Failure"
	end
end
def openPanelTest
	begin
		status = UI.openpanel "Select image file", "", "*.jpg"
	rescue
		UI.messagebox $!.message
	end
end
def savePanelTest
	status = UI.savepanel
	if (status)
		UI.messagebox status
	else
		UI.messagebox "Failure"
	end
end
def playSoundTest
	begin
		pSound = UI.play_sound "mediadiscussion.wav"
	rescue
		UI.messagebox $!.message
	end
end
def startTimerTest
	id = UI.start_timer(10) {UI.beep}
	if (id)
		UI.messagebox id
	else
		UI.messagebox "Failure"
	end
end
def stopTimerTest
	id = UI.start_timer(10) {UI.beep}
	if (id)
		UI.messagebox id
	else
		UI.messagebox "Failure"
	end
	UI.stop_timer id
	UI.messagebox "Stopped"
end
def toolbarUITest
	toolbar = UI::Toolbar.new "Test"
	toolbar = UI.toolbar "Test"
	if (toolbar)
		UI.messagebox toolbar
	else
		UI.messagebox "Failure"
	end
end

def uitest
	puts "beepTest"
	puts "inputBoxTest"
	puts "getMenuTest"
	puts "messageBoxTest"
	puts "openURLTest"
	puts "openPanelTest"
	puts "savePanelTest"
	puts "playSoundTest"
	puts "startTimerTest"
	puts "stopTimerTest"
	puts "toolbarUITest"
end






```

以上。
【試験対策】サイバー犯罪のビジネス化とは？手口と対策を徹底解説！

✅ はじめに
近年、サイバー犯罪は個人のハッカーが単独で行うものではなく、組織的・ビジネス化 してきています。
いわゆる 「アンダーグラウンドサービス」（Cybercrime-as-a-Service: CaaS）が発展し、
✅ 誰でも簡単に攻撃ツールを購入可能
✅ 専門知識がなくてもサイバー攻撃を実行できる
といった状況が生まれています。

✅ 攻撃者は金銭目的でサイバー攻撃を「サービス化」して提供
✅ 被害は企業・個人を問わず拡大
✅ 応用情報技術者試験（午後）での出題が予想されるテーマ

本記事では、
✅ サイバー犯罪のビジネス化の実態
✅ 具体的なアンダーグラウンドサービスの手口
✅ 犯罪のビジネス化がもたらす影響
✅ 企業や個人が取るべき対策
✅ 試験の出題ポイント
を解説します！

⸻
📌 犯罪のビジネス化（アンダーグラウンドサービス）とは？
🔹 概要
サイバー犯罪の世界では、攻撃ツールや手口が「商品化」され、オンラインで売買される ようになっています。
これにより、技術力のない犯罪者でも高度な攻撃を実行できる ようになりました。

主なサイバー犯罪ビジネスの形態には以下のものがあります
| サービス名 | 内容 |
|:-:|:-:|
| Ransomware-as-a-Service（RaaS）  | ランサムウェア攻撃を提供し、感染後の身代金収益を分配するサービス  |
| Phishing-as-a-Service（PhaaS）  | フィッシングサイトや偽メールのテンプレートを販売するサービス  |
| DDoS-for-Hire（DDoS-as-a-Service）  | 企業や個人のサーバーをダウンさせるDDoS攻撃を代行するサービス  |
| Exploit Kits  | Webサイトの脆弱性を悪用するためのツールセット  |
| Credential Stuffing Services  | 流出したID・パスワードを使ってアカウントを乗っ取るための攻撃サービス  |
| Stolen Data Marketplaces | クレジットカード情報や個人情報を売買する闇市場  |


📌 具体的な攻撃事例
✅ 1. Ransomware-as-a-Service（RaaS）
	•	内容:
「誰でも簡単にランサムウェア攻撃を実行できるサービス」 が提供されている。
	•	手口:
	•	攻撃者は ダークウェブ上の「RaaSプロバイダー」 からランサムウェアを購入
	•	企業や個人にメールや脆弱なリモートデスクトップ経由で感染させる
	•	身代金が支払われると、サービス提供者が一定の割合を受け取る
	•	結果:
非技術者でも高度なランサムウェア攻撃が可能となり、被害が増加。

✅ 2. DDoS-for-Hire（DDoS-as-a-Service）
	•	内容:
「数千円〜数万円でDDoS攻撃を代行」 するサービスが存在する。
	•	手口:
	•	犯罪者がサービスを利用し、競合企業や特定のサイトを攻撃
	•	数時間の攻撃でサーバーをダウンさせ、業務を妨害
	•	結果:
企業は大きな損害を受け、復旧対応に追われる。

✅ 3. Stolen Data Marketplaces
	•	内容:
ダークウェブ上では、盗まれた個人情報・企業情報が売買 されている。
	•	手口:
	•	ハッカーが企業のデータベースを攻撃し、個人情報を窃取
	•	クレジットカード情報、ログイン情報を闇市場で販売
	•	結果:
企業の信用失墜、顧客の被害拡大、フィッシング詐欺の増加につながる。

⸻
📌 被害を防ぐための対策
サイバー犯罪のビジネス化に対抗するには、技術的対策＋監視体制の強化が必須 です。

🔹 1. ランサムウェア対策

✅ データのバックアップを定期的に取得
✅ ゼロトラストセキュリティを導入（信頼しない前提で対策）
✅ EDR（Endpoint Detection and Response）を導入し、感染を即座に検知

🔹 2. DDoS攻撃対策

✅ DDoS対策サービス（CDN・WAF・クラウド型防御）を活用
✅ サーバーのトラフィック監視を強化し、異常検知システムを導入

🔹 3. フィッシング・個人情報漏えい対策

✅ 従業員のセキュリティ教育を徹底し、フィッシング詐欺の手口を学ばせる
✅ 多要素認証（MFA）を導入し、パスワードの流出リスクを軽減
✅ ダークウェブ監視サービスを活用し、漏えいした情報の早期発見を目指す

⸻
📌 試験での出題ポイント
✅ 記述問題の対策

試験では、「サイバー犯罪のビジネス化がもたらすリスクと対策」について問われる可能性があります。

Q1. Ransomware-as-a-Service（RaaS）の特徴と、それに対する企業の対策を述べよ。

解答例:
特徴: RaaSは、ランサムウェア攻撃を「サービス」として提供する仕組みであり、技術的な知識がない攻撃者でも利用可能。
対策: 重要データの定期バックアップを実施し、ゼロトラストセキュリティを導入する。また、EDRを活用して感染の早期検知・対処を行う。

Q2. 犯罪のビジネス化（アンダーグラウンドサービス）がもたらすリスクと、その対策を述べよ。

解答例:
リスク: サイバー攻撃の敷居が下がり、犯罪者が増加することで、企業や個人の被害が拡大する。
対策: 企業はサイバー攻撃の監視体制を強化し、ダークウェブ監視サービスを活用する。また、従業員のセキュリティ意識向上のための教育を行う。

⸻
✅ まとめ
	•	サイバー犯罪のビジネス化により、攻撃の敷居が下がり、被害が拡大している。
	•	ランサムウェア、DDoS攻撃、個人情報売買がサービス化し、誰でも実行可能な時代に。
	•	試験では「攻撃手法」「リスク」「対策」をセットで理解し、記述問題に対応できるようにする！
RS485通信をM5Stackで簡単に実装する方法

# M5Stack用絶縁型RS485ユニット

今回使用したM5Stack用絶縁型RS485ユニットはこちらです。
M5Stackを使って、RS-485通信を実装したくて使いました。

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

# UIFlow2.0での実装例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/6e6c56b6-3569-43b1-89a8-e68b44a467be.png)

基本的な流れは以下になります。
1. iso485の初期化
1. iso485経由でコマンドを送信
1. レスポンスがあったかどうかを確認
1. レスポンスがあったら、受信データを読み取って表示

# 補足

M5Stack社の公式サイトでは、UIFlow1.0のサンプルが以下のように示されています。
通常のUARTでも使うことが出来そうですが、「Units」からユニットとしてブロックを追加することもできます。
通常のUARTの場合は、選択できる baudrateが決まっているので、それ以外で使用したい場合は、「Units」から追加すると良いと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/408f80a8-05f9-422e-9668-1bc316fe54e8.png)

https://docs.m5stack.com/en/unit/iso485



# 参考リンク
M5Stack用絶縁型RS485ユニットは、実際に使っている情報が少なかったので、以下のサイトなどを参考にさせてもらいました。ありがとうございます！

https://qiita.com/oguna/items/c9109d5574b019a5e326
家計簿アプリを作る＃２３

![スクリーンショット 2025-03-27 065733.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/02d2f9a5-342b-44c6-b187-252598941a99.png)
AppLayout.tsxのサイドバーを別ファイルに切り出して、型定義していく。

![スクリーンショット 2025-03-27 065842.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/a2ebc2fc-cb96-48ff-951d-4301f2efb345.png)
srcのcomponentsのcommonの中に、SideBar.tsxを作ります。

![スクリーンショット 2025-03-27 065955.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/dd0b4533-8116-4495-830b-f75fb7d0f4ce.png)
ひな形を作成して、

![スクリーンショット 2025-03-27 070048.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/3533df72-8a5b-4f9b-b25a-dd479dd0a01f.png)
return文の中に、サイドバーで切り取った部分を貼り付けます。
メモで書かれてあるサイドバーの部分は削除しておきます。
2つのパスの指定方法

# 環境

VSCode
バージョン: 1.98.2
コミット: ddc367ed5c8936efe395cffeec279b04ffd7db78
日付: 2025-03-12T13:32:45.399Z
Electron: 34.2.0
ElectronBuildId: 11161602
Chromium: 132.0.6834.196
Node.js: 20.18.2
V8: 13.2.152.36-electron.0
OS: Darwin arm64 24.3.0

Python 3.10.16

# Pythonでローカルファイルのパスを取得する
①特定のフォルダ直下のすべてのファイルパスを取得する

```python:
img_names = Path(DATA_DIR + "train/").glob("*.png")
```

①特定のファイルパスを取得する
```python:
# ベタ書でももちろんok
img_name = f'{DATA_DIR}train/{image_id}.png'
```
Geminiでラーメンを描いてもらった。

# 概要

Geminiでラーメンを描いてもらいました。

# 実装

リクエストと画像は以下の通りです。

```
美味しい味噌ラーメンを描いてみてください。
```

![美味しい味噌ラーメン_20250327.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/a8930d53-7032-4596-903f-e4e1ebd124a7.png)

うまく描けています。美味しそうです。

```
醤油ラーメンを描いてみてください。
```

![醤油ラーメン_20250327.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/42fa9c19-8195-4dc9-9389-a667af2f5eeb.png)

こちらもうまく描けています。

```
塩ラーメンを描いてみてください。
```

![塩ラーメン_20250327.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/35fc2ff3-5752-44f5-be8e-07f8e815ecb6.png)

うまく描けています。

```
家系ラーメンを描いてみてください。 
```

![家系ラーメン_20250327.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/132986d2-9951-4696-9536-c4631ee26ba6.png)

失敗しました。「家系」では分からなかったようです。

```
とんこつラーメンを描いてみてください。
```

![とんこつラーメン_20250327.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/a065a242-bc56-45de-90d1-ee9217e856f0.png)

うまく描けています。おいしそうです。

# まとめ

何かの役に立てばと。
OpenAIのIMGGENで出来る事

OpenAIのIGMGENに関して、機能がかなり多くて1度につかみにくいため、実際のツイート等をGROKに分析してもらって、やれる事やそれらの評判なども含めてまとめてもらいました。ご参考までに。

ちなみに下記はOpenAIのIMGGENの下記の文章を読ませて、それをIMGGENに図に起こしてもらったものです。なんか２枚あるけど、その間でスタイル変わってますねｗ

![ChatGPT Image 2025年3月27日 05_05_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2974126/9066fa7c-3bea-47a2-b831-4a16c2af7842.png)

![ChatGPT Image 2025年3月27日 05_11_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2974126/2c117689-599e-4e25-b58f-507c12d44a43.png)


---

OpenAIが2025年3月25日にGPT-4o上で画像生成・加工機能「IMGGEN」（正式名称は「GPT-4o Image Generation」）を発表したことで、さまざまなクリエイティブな可能性が広がっています。この新機能がどのようなことを可能にするのか、実際のX上の投稿や関連情報を基に、できるだけ具体的に分析し、以下に挙げます。

# 1. 高品質な画像生成

リアルな写真レベルの生成: GPT-4oはフォトリアリスティックな画像を生成可能。たとえば、風景や人物、物体などを現実的な質感で描けるため、写真撮影の代替として使える可能性があります（X投稿より「リアル写真レベル」との声）。

複雑なプロンプトへの対応: 詳細な指示（例: 「夕暮れの海辺に立つ犬」など）に基づいて正確な画像を生成でき、ユーザーの意図を細かく反映します。

# 2. テキストを含む画像の生成

自然なテキスト埋め込み: 画像内に看板やメニュー、インフォグラフィックなどのテキストを自然に配置可能。以前のモデルでは文字が歪むことが多かったが、GPT-4oでは読みやすい形で生成できます（「画像にテキスト入れたり」とのX投稿）。

多言語対応の可能性: 日本語の扱いがまだ苦手との指摘もあるが（X投稿より）、将来的には多言語テキストの正確な生成も期待されます。

# 3. 漫画やイラストの作成

漫画の自動生成: 複数パネルの漫画をキャラクターデザインや会話内容を含めて生成可能。クリエイターがストーリーを入力すれば、視覚的なストーリーテリングが簡単に実現します（「漫画の生成」とのX投稿）。

スタイルの切り替え: 写真からイラスト、または特定の画風（例: アニメ風、写実風）に変換でき、柔軟なクリエイティブ表現が可能です（「写真とイラストの切り替え」）。

# 4. 画像の編集・加工

視点やアングルの変更: 生成した画像の視点を自由に調整可能（例: 上から見た風景を横に変更）。これにより、デザインやプレゼンのニーズに合わせた調整が容易に（「アングルの変更」）。

服やオブジェクトの着せ替え: 人物画像に異なる服を着せたり、背景を変更したりする編集機能が利用でき、ファッションや広告用途で活躍（「洋服の着せ替え」）。

透明背景の生成: ステッカーやロゴデザインに適した透明背景の画像が作成可能で、商業利用に便利。

# 5. コンテキストを理解した連続生成

会話ベースの改良: チャット形式で「もっと明るくして」「キャラを追加して」といった指示を出し、前の画像を基に改良を重ねられる。コンテキストを保持するため、一貫性のある結果が得られます。

複数オブジェクトの正確な配置: 最大20個のオブジェクトを指定しても正確に配置可能で、複雑なシーン（例: 「カフェに10人の客と植物」）も描ける。

# 6. ビジネスや教育での活用

マーケティング素材の作成: 広告用のビジュアルやロゴ、メニューを迅速に生成でき、デザインコストを削減。X上でも「ビジネス活用も可能」との声が上がっています。

教育用ビジュアル: 科学的な図解（例: ニュートンのプリズム実験）や歴史的事件の再現画像を生成し、視覚的な学習支援が可能。

プレゼン資料の強化: カスタム画像を即座に作れるため、スライドや資料の視覚的訴求力が向上。

# 7. クリエイティブなアイデアの実現

ユニークなビジュアルの生成: 「三角形の車輪の自転車」など、従来の画像生成AIが苦手だった奇抜なアイデアも実現可能。
既存画像の変形: アップロードした写真を基に、アニメ風に変換したり、背景を透明にしたりするなど、カスタマイズの幅が広い（「既存のAIサービスと組み合わせたら何でも作れてしまう」とのX投稿）。

# 8. アクセシビリティと利便性

無料ユーザも利用可能: Plus/Proユーザーだけでなく、無料ユーザーにも段階的に展開され、制限付きながら広く試せる（Xでの言及あり）。

API経由での統合: 開発者がこの機能を自社アプリに組み込めるようになり、外部サービスとの連携でさらに用途が拡大する予定。

# 9. 倫理的・法的配慮を反映した利用

権利を考慮した生成: 「自分が権利を持つキャラクターや作品なら自由に描ける」（X投稿）とあり、著作権侵害を避けるための配慮が強化されている。これにより、個人クリエイターが安心して利用可能。

C2PAメタデータの埋め込み: 生成画像にAI作成を示すメタデータが付与され、透明性が確保される。

# 10. その他の可能性

動画生成への応用: GPT-4oの画像生成はOpenAIの動画生成ツール「Sora」にも統合され、静止画から動画への展開が期待される。

リアルタイムコラボレーション: 複数ユーザーで画像を改良するような共同作業が、会話ベースで可能になる可能性も。

# 分析に基づく補足

X上の反応からは、ユーザーが特に「柔軟性」と「実用性」に驚いていることが伺えます。例えば、漫画生成やビジネス用途への言及が多く、クリエイターや企業にとって即戦力となるツールとしての期待が高いです。一方で、「日本語が苦手かも」という指摘もあり、現時点では英語プロンプトでの利用が最適と考えられます。また、「ルールが緩和された」との声から、従来より自由度が増したことがクリエイティブな実験を後押ししているようです。
この機能は、単なるアート生成を超えて、実用的なデザイン、教育、エンターテインメントの分野で革新的な活用が期待されます。ユーザーのフィードバックやAPIの展開次第で、さらに多くの可能性が開かれるでしょう。
Playwright でブラウザテストを自動化

## 前提

前提として、 node.js をインストールしておきます。

バージョンは最新の LTS を推奨。

## 環境

* Windows11
* WSL2

```
$ node -v
v22.14.0
$ npm -v
10.9.2
```

## プロジェクトの新規作成

プロジェクト用のディレクトリを作成、 package.json を作成。

```
$ cd projects/
$ mkdir my-playwright-project
$ cd my-playwright-project
$ npm init -y
Wrote to ./package.json:

{
  "name": "my-playwright-project",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": ""
}

$ npm install @playwright/test

added 3 packages, and audited 4 packages in 2s

found 0 vulnerabilities
$ npx playwright install-deps
... (略
$ npx playwright install
... (略
```

## 簡単なテスト実行

```
$ cat examle.spec.js
const { test, expect } = require('@playwright/test');

test('basic test', async ({ page }) => {
  // 指定されたURLに移動
  await page.goto('https://playwright.dev/');

  // ページタイトルを取得して検証
  const title = await page.title();
  await expect(page).toHaveTitle(/Playwright/);
});
```

実行結果

```
$ npx playwright test

Running 1 test using 1 worker

  ✓  1 examle.spec.js:3:1 › basic test (832ms)

  1 passed (1.8s)
```

## スクリーンショット取得

画面遷移において、スクリーンショットを取得することができます。

```
$ cat screenshot.spec.js
const { test, expect } = require('@playwright/test');

test('basic test', async ({ page }) => {
  // 指定されたURLに移動
  await page.goto('https://playwright.dev/');

  // ページタイトルを取得して検証
  const title = await page.title();
  await expect(page).toHaveTitle(/Playwright/);

  // スクリーンショットを取得して保存
  await page.screenshot({
          path: 'screenshot.png',
          fullPage: true
  });
});
```

実行結果

```
$ npx playwright test ./screenshot.spec.js

Running 1 test using 1 worker

  ✓  1 screenshot.spec.js:3:1 › basic test (898ms)

  1 passed (1.8s)
```

## ページのアクセス速度を計測する

```
$ cat time.spec.js
const { test, expect } = require('@playwright/test');

test('ページの表示速度が5秒以下であることを確認する', async ({ page }) => {
  const startTime = Date.now();

  // 指定されたURLに移動
  await page.goto('https://playwright.dev');

  const loadTime = Date.now() - startTime;
  console.log(`ページの読み込み時間: ${loadTime}ms`);

  // ページの読み込み時間が5000ms（5秒）未満であることを期待
  expect(loadTime).toBeLessThan(5000);
});
```

実行結果

625ms はテストケースぜんたいにかかった時間、405ms はページの読み込みにかかった時間です。

```
$ npx playwright test ./time.spec.js

Running 1 test using 1 worker

  ✓  1 … › ページの表示速度が5秒以下であることを確認する (625ms)ページの読み込み時間: 405ms

  1 passed (2.2s)
```