OmniAICreator/Qiita-1.07M huggingface dataset:
8週間でAWS SAA資格を合格する方法

こんにちは！今日はAWS Solutions Architect Associate試験の勉強法と合格までの8週間の経験を共有させていただきたいと思います。さあ、始めましょう！


# AWS Solutions Architect Associate試験とは？

|　　　　　　　　  　　　　　　　　   　　　　　　　　　　　　　　　　　　　　　　　　　|
|:-:|
|![Qiita](https://d1.awsstatic.com/training-and-certification/certification-badges/AWS-Certified-Solutions-Architect-Associate_badge.3419559c682629072f1eb968d59dea0741772c0f.png "Qiita")|


AWS Certified Solutions Architect Associate試験は、Amazon Web Services（AWS）が提供する権威ある資格です。この資格は、AWSプラットフォーム上でスケーラブルで高可用性かつ障害耐性のあるシステムを設計および展開するために必要な技術的な専門知識を検証します。

試験では、Solutions Architectにとって重要な4つの主要なトピックをカバーしています：

1.	**耐障害性のあるアーキテクチャの設計**
2.	**パフォーマンスアーキテクチャの設計**
3.	**セキュアアーキテクチャの設計**
4.	**コスト最適化アーキテクチャの設計**

## 戦略
効果的に試験の準備をするために、この包括的な勉強戦略になります。

:::note warn
注意
私はエンジニアなので、ITの知識はだいたい理解しています。したがって、以下のスケジュールは私にとっては大丈夫だと思いますが、他の方にとっては異なるかもしれません。
:::

### フェーズ1（3週間)
- AWSコアサービスに焦点を当てる このフェーズでは、基本的なAWSコアサービスの理解に時間を費やします。VPC、IAM、EC2、S3、Lambda、SQSなどの主要なサービスをマスターすることが重要です。これらのサービスは試験で頻繁に出題され、それらをしっかり理解していることが肝心です。

### フェーズ2（3週間）
- 模擬試験を受験し、パフォーマンスを分析する このフェーズでは、Udemyなどのプラットフォームで提供されている模擬試験を利用します。問題と解答を注意深く見直し、キーとなる概念を理解し覚えるためにノートを取ったり、図を作成したりしましょう。不正解の理由に注意を払い、理解を深めるためにフェーズ1の素材を復習します。

### フェーズ3（2週間）
- 高度なサービスに深く入る この最終フェーズでは、Solutions Architect Associate試験に関連する高度なAWSサービスに深く入ります。これらのサービスを研究し、知識を拡充して十分に準備されていることを確認します。さらに、フェーズ2の素材を復習して理解を強化します。


## 勉強材料としては
- Udemy AWS Certified Solutions Architect - Associateコース：このUdemyの包括的なコースでは、試験に必要なすべてのトピックをカバーし、詳細な説明と実践的な例が提供されています。
- 練習試験 | AWS認定ソリューションアーキテクト：これらの模擬試験もUdemyで利用可能で、知識を評価し、改善の余地を見つけるのに役立ちます。試験のような条件下での練習を通じて、自信を得てテストの受験能力を向上させましょう。
- AWSドキュメンテーション：公式のAWSドキュメンテーションは、AWSサービスとそれらの設定に関する詳細な情報を取得するための貴重なリソースです。理解を深め、疑問があれば解消するために使用してください。



# まとめ
試験はAWSで直ちに仕事ができることを確認するものではなく、多くのトレーニングと仕事中の失敗から学ぶプロセスが必要です。これによりスキルを向上させることができます。
以上です！！！
Vonage ハンズオン Vol.2 開催決定！

![Whimson Electroniq (4) (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1851076/edbdbeec-eef7-aa38-b1b9-738fa12e372b.png)
Vonage AI Studioを実際に触ってみよう！
# Vonage ハンズオン Vol.2
Vonageを実際に使いながら、機能や設定、実装方法を体感していただくオフラインのイベントになります。昨年12月に開催し大変ご好評を頂きました『Vonage ハンズオン』の第2回目を開催いたします！前回残念ながらご参加いただけなかった方をはじめ、さらに多くの方々にご来場いただければと存じます。今回は、OpenAIの連携まで解説させていただく予定です。
## こんな方におすすめ

- IT/WEBエンジニアとして活動している方
- Vonage以外も含め、CPaaSに興味のある方
- すでに別のCPaaSをご利用中で、Vonageへのマイグレーションを検討中の方
- エバンジェリストに直接相談したい方

Vonageが初めての方でも、最初にプロダクトの紹介がありますので安心してご参加いただけます！

## 開催概要

- 開催日：2024年2月28日（水）
- 時間：ハンズオン 18:30〜20:00（開場18:00）/ 懇親会 20:15〜21:30
- 主催：Vonage Open User Group
- 協賛：Vonage Japan合同会社
- 場所：ハンズオン [WeWork 渋谷スクランブルスクエア](https://wework.co.jp/location/tokyo/shibuya-aoyama-area/shibuya-scramble-square)
/ 懇親会 [AWkitchen figlia 渋谷スクランブルスクエア](https://aw-kitchen.com/1643/)
- 定員：20名（先着順）
- 参加費：無料

## タイムテーブル

| 時間 | 内容 |
| ---| ---|
| 18:00 - 18:30 | 開場・受付 |
| 18:30 - 18:35 | 挨拶・諸注意 |
| 18:35 - 20:00 | 「Vonage概要・ハンズオン」株式会社KDDIウェブコミュニケーションズ エバンジェリスト: 高橋克己<br />Vonage AI Studioを使って、コールフローの作成を行います。IVRの設定や、AI機能を使った音声ボット、外部サービスとの連携など、より実践的な内容を体感していただきます。|
| 20:15 - 21:30 | 懇親会|

## 参加方法

Vonageページよりお申し込みください。<br />[お申込みはこちら](https://vonage-24266656.hubspotpagebuilder.com/vonage-hands-on-vol-2)

*イベントの詳細をご確認の上、お申し込みください。
[Vonage Open User Groupのページ](https://vonage-24266656.hubspotpagebuilder.com/vonage-hands-on-vol-2)

## 事前準備

イベント当日は、ハンズオン実施のために**Chromeブラウザが利用できるPCと通話が可能な電話**を忘れずにご持参ください。なお、電源とWiFiは会場にございます。
また、以下の準備もお願い致します。

Vonageアカウント
---------------
事前にVonageのアカウント（トライアルで可）を作成しておいてください。
アカウントは、以下のページから行えます。
https://ui.idp.vonage.com/ui/auth/registration
すでにアカウントをお持ちの方は、そちらをご利用いただいても構いません。

OpenAIアカウント
---------------
ハンズオンの後半では、OpenAI APIを用いたフローの作成がありますので、OpenAIのシークレットキーをご用意いただけるようにお願い致します。
https://openai.com/


皆様のご参加お待ちしています！
作成者項目の作られる順番


+ [新しいレコードを作成するときに [作成者] フィールドはいつ更新されますか?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007XIJ6D)


これは「検証の実行後にCreated Byが更新されると信じられる」という点で正しいです。問題はSalesforceの実行順序だ。カスタム検証ルールの最初のラウンドは、レコードがデータベースに保存される前にトリガーされます。この時点では、Created By 値はまだ設定されていないため、検証することはできません。

Salesforce の実行順序のこの概要は非常に役立ちます。
https://www.saasguru.co/salesforce-order-of-execution/

 

これは Salesforce の公式ヘルプ記事です。上記の文書では、何らかの理由でステップ 17 が省略されています。
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_triggers_order_of_execution.htm

 

ステップ 5 ではカスタム検証ルールがトリガーされ、ステップ 7 では作成者値が設定されます。
主要ECモールのサイトスピードの移り変わり

[CrUX](https://developer.chrome.com/docs/crux?hl=ja) (Chrome User Experience)を元にWebサイトのスピードを比較を簡単に行う無料サービスを提供しています。

サイトスピード簡単比較
https://sitespeed-hikaku.com/

これを使い、主要ECモールのスピードを比較した例を紹介します。

# 国内主要ECモールTOP5

国内のECモール売り上げTOP5は次のサイトだそうです。

- Amazon https://www.amazon.co.jp/
- 楽天 https://www.rakuten.co.jp/
- Yahoo!ショッピング https://shopping.yahoo.co.jp/
- au PAY マーケット https://wowma.jp/
- ZOZOTOWN https://zozo.jp/

https://www.w2solution.co.jp/useful_info_ec/1110/

みなさんはどこ派でしょうか？ 私はAmazonです。

# スピードランキング ※ 弊社調べ

2023年12月時点で、スマホでは楽天、PCではYahoo!ショッピングが一番速いという結果になりました。

![ranking (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/7713c412-afc4-338c-fc53-0dc80feea1c0.png)

![ranking (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/184dfa61-157b-11eb-fbe3-9e398db4b78a.png)

レポートはこちら
https://sitespeed-hikaku.com/reports/sample

このランキングは、`LCP`、`FID`、`INP`、`CLS`、`TTFB`、`FCP`、`OnLoad`の7指標について、Googleの基準において`良い`とされる体験の割合の単純な平均値で出しています。

:::note info
複数の指標で見てどれだけ多く高速な体験を提供できているか、という観点ですが、あくまで弊社独自の便宜的な基準なのでご参考まで。
:::

各指標の内訳については、「評価比較」など別のタブをご覧ください。

# ランキング推移

CrUXには2017年ごろからのデータが蓄積されているので、指標がどのように変化してきたかも知ることができます。

ランキング推移
https://sitespeed-hikaku.com/reports/sample/billboard

スマホのランキング推移を見ると、2020年には、楽天は5サイト中4位でした。

![billboard (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/b56cfd44-5faf-0271-4299-7ac8ed8583f7.png)

それが2021年に楽天が2位に躍進。

![billboard (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/0e82c9c4-959f-aeab-80ad-de09cc7bae58.png)

代表値(P75)を見ても2021年5月〜7月にかけて読み込み時間(OnLoad)を3秒も短縮し、半減した過程が見られます。何があったのか大変興味深いです。

P75 推移
https://sitespeed-hikaku.com/reports/sample/monthly-p75

![CleanShot 2024-01-31 at 09.51.05@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/355e5850-ccb2-5464-06e5-017c89c1a2de.png)

2023年12月にはついにAmazonも抜いて一番速いスマホECモール(あくまで弊社の独自基準ですが)になりました。

![billboard (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/34ce6f5f-7e6b-0fc8-d0ea-e1e80c02bcc8.png)

念のため楽天の関係者ではありませんが、あれだけの超大規模サイトでありながら不断のスピード改善を続けている様子に頭が下がります。

# みなさんのインサイトも教えてください

このように過去にも遡って、サイト間のスピードについて考察できる「サイトスピード簡単比較」ぜひ使ってみてください！

Googleサインインして、URLを入力するだけで簡単にレポートを作成できます。

サイトスピード簡単比較
https://sitespeed-hikaku.com/
DockerでTimeZoneの設定でハマった話 Asp.Net

WebAPIをAsp.Netで開発しAzure Container Appsにデプロイし、環境変数でTZ=Asia/Tokyoと設定したが反映されずハマりました。

## 結論
Dockerfileを作成するため
```
docker init
```
を使いました。

ここで出力されるDockerfileはマルチステージになっており便利だと思います。
しかし利用するイメージは

```
mcr.microsoft.com/dotnet/sdk:8.0-alpine
```

を利用する設定となっています。

この状態で環境変数の設定
TZ=Asia/Tokyo
を行っても反映されず困っていました。

そこで

```diff_docker
- FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build
+ FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0 AS build

- FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine AS final
+ FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final

```

したところ正しくTZが反映されるようになりました。
typescript の型を正規表現っぽく書く ( 型に型を埋め込む / Union型でOR表現する )

# コード例

以下のように、型指定の中に型を埋め込めるようだ

```ts
type SomeType1 = `${number}px`

```

文字列を OR でつないで正規表現チックにすることも出来る

```ts
type SomeType2 = `IT IS ${'YES' | 'NO'}`
```

正規表現そのものを書けるわけではないようだが、これを組み合わせると正規表現チックに書けそうだ

##  090で始まる電話番号とか

```ts
type PhoneNumber = `090${'-' | ''}${number}${'-' | ''}${number}`
```

## 全体をユニオン型でつないで OR 表現するとか

```ts
type RGB = `rgb(${number}, ${number}, ${number})`;
type RGBA = `rgba(${number}, ${number}, ${number}, ${number})`;
type HEX = `#${string}`;

type Color = RGB | RGBA | HEX;
```

https://stackoverflow.com/questions/42584228/how-can-i-define-a-type-for-a-css-color-in-typescript

# 動作確認例


```ts
type AnswerType = `IT IS ${'YES' | 'NO'}`

const answer1: AnswerType = 'IT IS YES' // これはOK
const answer2: AnswerType = 'IT IS WOW' // これは型エラー
```



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
自動運転AIチャレンジ〜オンライン環境に提出〜

本記事は前回記事までに作成したLQRのアルゴリズムを使った経路追従プログラムについて、自動運転AIチャレンジのオンライン環境に提出してみた結果をまとめております。

# 前回までのまとめ
[前回記事](https://qiita.com/Massy0127/items/7fe38f084bd87d2199fa)で経路追従にLQRを適用させて完走させたという記事を記載しました。
今回記事ではでオンライン環境に提出し、結果を確認してみたいと思います。

# オンライン環境提出について
[こちら](https://github.com/AutomotiveAIChallenge/aichallenge2023-racing/blob/main/documentation/docfx_project/online/index.md)記載の通り実施。

# 実行結果
何回か提出し、完走することを確認しました。
実行結果はjsonファイル、mp4ファイル等でダウンロードできるのでダウンロードしてみます。
rawLapTimeが走行時間、lapTimeがペナルティを加味した時間のようです。
distanceScoreが走行距離、100.0になると完走です。
結果は約469.6秒かかって完走、ペナルティを結構食らっているようです。
```result.json
{
  "rawLapTime": 469.553925,
  "distanceScore": 100.0,
  "lapTime": 599.553955,
  "isLapCompleted": true,
  "isTimeout": false,
  "trackLimitsViolation": [
    10,
    12,
    2,
    0,
    0
  ],
  "collisionViolation": [
    0,
    0,
    0,
    0
  ]
}  
```

ダウンロードした走行結果は以下の通りとなります。

https://youtu.be/wA8LlTAeazk

現在(1/31)提出チームは20チーム以上あり、120秒台の攻防が行われているようです。
皆さんすごいですね。

# 終わりに
自動運転AIチャレンジ、非常に勉強になりました。
次回以降参戦する機会があれば独自アルゴリズムで上位を狙いたいと思います。
あと、Autoware-universeに独自アルゴリズムを追加して新宿（シミュレーション）とか走らせてみたいと思います。
確率ロボティクスとかVitとかにも興味があるいので。
期限まで残り少ないですが、皆さん悔いなく。
データウェアハウス、データマート、データレイク、ＢＩ

# 目的
- データの収集から分析までの機能と、対応するAWSサービスを整理する。

# データベース
 - DataBase：データの基地
 - 各システム、アプリ単位で処理したデータを格納
 - システムが参照、更新するためのデータの集まり。人間向けの整理、構造化が目的ではない。
 - AWSサービス：EBS,RDS,EFS,S3ほか

# データレイク
 - Data Lake：データの湖
 - ローデータ（分析用の加工をしていないデータ）や、非構造のデータ（画像、動画）を収集したデータベース。
 - 将来的に有用になりうるデータをとりあえずまとめて格納しておく目的
 - AWSサービス：AWS Lake Formation(+ S3)

# ETLツール
 - Extract（データの抽出） Transform（データの加工） Load（データの出力）
 - データを分析できるように加工するツール。
 - AWSサービス：AWS Glue

# データウェアハウス
 - Data Warehouse:データの倉庫
 - ETLツールによって加工されたデータ群を蓄積するデータベース。
 - AWSサービス：RedShift

# データマート
 - Data Mart：データの小売店
 - データウェアハウスのデータを分析用により細かい単位に分割したデータベース

# BIツール
 - Business Interigence：ビジネス知見
 - データウェアハウスのデータを、分析し可視化するツール
 - AWSサービス：Quicksight


# 構成のイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684955/581672b5-5365-3350-f572-3c085188559d.png)
Android開発の始め方

## 記事を書くきっかけ
最近仕事で新言語を触れることが多く、swift、golang、kotlinとやってきて今はAndroid開発をしています。これらの言語は社内ナレッジがない状態から開発を始めました。これまでの開発から次新言語で始めるとき、または0からプロジェクトをやるときに、こう始めるな〜というのが自分の中にでき始めたので、書こうと思いました。

## 公式ドキュメントを読む、軽く触る
公式ドキュメントを読むことで新言語(今回で言えばKotlin)の概要が把握できます。例えばAndroid開発では、Jetpack Composeを知りました。
それから軽くチュートリアルをして慣れます。
公式：https://developer.android.com/?hl=ja
Jetpack Compose：https://developer.android.com/jetpack/compose?hl=ja

## アーキテクチャ・ディレクトリ構造を決める
色々調べまくってアーキテクチャを決めます。
特にAndroidは公式のドキュメントや参考ようのレポジトリを多く用意してくださっているのでそれを参考にしました。
この時の調べ方はこんな感じで、信頼度順に並べています。
1. 公式に書いていないか
1. Googleが出しているやつがないか
1. githubでスターの多いOSSがないか
1. ブラウザで参考にできる記事はないか

Android開発では1でhttps://github.com/android/architecture-samples を見つけて、これをメインで参考にしています。また、3でhttps://github.com/android/nowinandroid?tab=readme-ov-file を見つけました。（Android公式が手厚すぎる）

## コード規約を決める
Android開発では公式が出してくれているのでそれを参考にしています。
1. 公式に書いていないか（ Android：https://developer.android.com/kotlin/style-guide?hl=ja ）
1. Googleが出しているやつがないか（ Google styleguide：https://google.github.io/styleguide/ ）
1. ブラウザで参考にできる記事はないか

## ごりごりコードを書く
新言語で調べてばっかになったり、チュートリアルばっかやってプロジェクトが進まないとかよくあると思いますが、取り合えず勉強がてらに開発してコードを書くのが一番早いと思います。

## 終わりに
今まではすでにアーキテクチャが出来上がっていてすでにあるものを参考にすれば何も考えなくて良かったですが、こうやって新言語にたくさん触れて考える機会を得れてよかった〜と感じました。
Androidは公式のドキュメントがものすごく豊富で、Swiftとは大違いでした。
最近ではSwaggerやopenapiジェネレーターを使用していて、色々と新しいことを学ぶ機会が多いので、新しく知ったことを記事に書いていこうと思います。
Integrate Salesforce and an External Database with MuleSoft Anypoint Platform

[MuleSoft Composerまとめに戻る](https://qiita.com/Keiji_otsubo/items/ef2fdd213551168c360b)


-------------
+ [Integrate Salesforce and an External Database with MuleSoft Anypoint Platform](https://trailhead.salesforce.com/content/learn/projects/integrate-salesforce-and-an-external-database-with-mulesoft-anypoint-platform)

# Deploy Your Integration in Anypoint Platform

### We can't find the credentials in the properties of the running application deployed to CloudHub 2.0. 

+ [Unable to complete Deploy Your Integration in Anypoint Platform](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007JCk7U)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/fb3bdb75-f65b-c404-fe93-7c063a4a7e9f.png)

:::note
Be sure to put the actual text in the first column without quotes: "org1.username", then put the username in column 2. Same with all the rest (org1.password)....

DO NOT put your username in column 1, etc. Also, make sure the ip address range is set to 0.0.0.0 to 255.255.255.255 in each org. (org1 and org2)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/4c9d2e45-13ae-76c9-8c79-64e231a93894.png)

:::

### 未解決

+ [We can't find the credentials in the properties of the running application deployed to CloudHub 2.0. ](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007JCk7U)
+ [Step not yet complete in your MuleSoft Anypoint Account We can't find the credentials in the properties of the running application deployed to CloudHub 2.0.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007XIPsdSAH)
続・Unity でスクリーンセーバーを作る方法を模索してみた

あらすじ
========

去年のアドベントカレンダーにて [Unity でスクリーンセーバーを作る方法を模索してみた](/tkooler_lufar/items/c5bdf1b2793ba0b390d9)ところ、Windows と Android で大まかな手順が見えてきました。

動かしてみると粗が目立つコードでしたが、あの後さらに整えたので、記録に残します。

更新情報
========

Windows
-------

Windows 版を作る際は [ExternalPrograms\\Windows\\UnityScreenSaverLauncher\\UnityScreenSaverLauncher\\Program.cs](https://github.com/TkoolerLufar/UnityScreenSaver/blob/main/ExternalPrograms%2FWindows%2FUnityScreenSaverLauncher%2FUnityScreenSaverLauncher%2FProgram.cs) のレジストリ操作の行を適宜書き換える必要がありました。

まず、この[レジストリキーをVC#プロジェクトの会社名と製品名から引用するよう変更](https://github.com/TkoolerLufar/UnityScreenSaver/commit/1ffaf901306492c3e483d4b953814fe6470f7516)しまして、 [Unity でのビルド成功時に Unity プロジェクトの設定をVC#プロジェクトへ自動反映する](https://github.com/TkoolerLufar/UnityScreenSaver/commit/3a2eb424bcf65720829a8d053c11a680c9e14db9)スクリプトを書きました。

これでもう中のプログラムをいじる必要はありません!

しかし、いざ Windows 版をビルドして実際にスクリーンセーバーに設定してみたところ、なんと**起動時にエラーが発生**して実行できませんでした(不覚)
どうやら.exeの置いてあるフォルダーを基準にアセットファイルやら何やらを読むようなのですが、
本実行では手動実行時と異なり **RUNDLL32.EXE** がエントリーポイントになるため何も読めない事態に。

Unity 標準の.exeを置き換えるやり方では攻略できないので、 [Unity 標準の.exeを子プロセスとして起動するよう変更](https://github.com/TkoolerLufar/UnityScreenSaver/commit/be1ebdfc17c94d5856154594b5a472dd0ed1e146)しました。
インストール時の設定画面で即刻OKボタンを押しちゃうとウィンドウハンドルが無効になってクラッシュしちゃいますが、本実行できないよりはマシってことで。

Android
-------

Android 版のスクリーンセーバーを閉じるときにエラーログが出てたのは、どうやら **Unity のバグ**だった模様。
Unity を 2022.3.14f1 から 2022.3.18f1 
に更新したら直りました。
(具体的には 2022.3.16f1 で直ったらしい&rarr; [リリースノート](https://unity.com/releases/editor/whats-new/2022.3.16))

> Android: Fixed PersistentUnitySurface potentially crashing on destroy if given context is not an Activity.

あと UnityPlayerDreamService のライフサイクルの実装を UnityPlayerActivity や BounceDreamService と見比べたら[問題が見つかったので、修正した](https://github.com/TkoolerLufar/UnityScreenSaver/commit/cd9b88ae4a5145ae62d9991a5d38a10d03f81448)ところキレイに起動終了するようになりました。やったね!

ところでシェーダーアート作るって言ってたのはどうなったのか
----

**できました!**

&rarr; [リポ](https://github.com/TkoolerLufar/ShaderArtScreenSaver)

Qiitaのアバターに使ってた画像をベースにシェーダーを書いて Unity で動かしてみました。
RPGツクールVXでレンダリングしたときは500px四方で10秒くらいかかってたのに、GPUが本気を出せばフルHDさえも一瞬なのですね。やはりネイティブは強い。

せっかくなので動きをつけて、ついでにバッテリー状態に応じて色を変えるようにしてみました。

リリースビルドをリポに上げたのでよければ持ってってください。

&rarr; https://github.com/TkoolerLufar/ShaderArtScreenSaver/releases/tag/v0.1.0

感想
====

アドベントカレンダーで詰めの甘かったところをしっかり追究できて、だいぶ満足しました。
シェーダーアートのコード書くとき Android 版で変な最適化が走ったり妙な困難があり、普段サーバーサイドでコード書くときは思いもよらない不具合が出て原因調査が大変だったのはいい経験です。
クライアントサイドって難しいですね。
[Mac]ショートカットを使ってプログラミングやPC操作を効率的に

# はじめに
普段よく使っているショートカットを布教するためだけの記事です。
コピー/ペースト、切り取りなどPC使ってる人なら知ってるよ！くらいのやつは記載しません。
※使ってるPCがmacなのでWindowsの方はご注意ください。

# ショートカット一覧
### Emacsショートカット
普段矢印キーを使ってるのであれば覚えておいて損はない。
ホームポジションから指がほとんどずれないのでまじでおすすめ。

###### カーソルがある行の先頭位置に移動する(WindowsだとHOMEキー)
**control + A**  

###### カーソルがある行の最後位置に移動する(WindowsだとEndキー)
**control + E**

###### 一文字進む(→キー)
**control + F**

###### 一文字戻る(←キー)
**control + B**

###### 上行に行く(↑キー)
**control + P**

###### 下行に行く(↓キー)
**control + N**

### 普段使いできるショートカット

※アプリケーションによっては別のショートカットが設定されている可能性があるため正常に動作しない場合があります。

###### 選択中のアプリケーションを切り替える
**command + tab**

###### タブを切り替える
**control + tab**
※逆方向に切り替える場合は command + shift + tab 

###### 同アプリのウィンドウを切り替える(同じアプリを複数ウィンドウで立ち上げている場合のみ)
**command + `(バッククウォート)**

###### 選択した範囲のスクリーンショットを撮る
**command + shift + 4**

###### 選択中ウィンドウをフルスクリーンにする
**control + comamnd + F**
※フルスクリーンからウィンドウ表示に戻す時も同ショートかっと

# 最後に
マウス操作が嫌いってわけじゃないけどわざわざこの操作するためだけにマウスとか使うの馬鹿馬鹿しいなぁって思ったら調べるようにしてます。
この記事を読んでショートカットを使ってみようと思ってくださったら幸いです。

おすすめのショートカットがあれば教えてください。
awsの(デフォルト)profile切り替え

# はじめに
awsのアカウントが複数ある場合、アカウント切り替えで調べたの際の備忘録です。

# awsのprofile一覧を表示
```
aws configure list-profiles
```

# awsの現在セットされているprofileを表示
```
aws configure list
```
![l_6814799_103_05932accf528f6278b035c049c712d50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/1d642a9c-1e23-4fdf-da92-074bf4695949.png)

# profileの切り替え
```
export AWS_PROFILE=hogehoge
```

# さいごに
アカウントの切り替えについて調べたところ色々ありましたが、個人的にはこのやり方が一番シンプルでわかりやすかったです。
とても短いですが、以上です。
半角カタカナが含まれているか判定する

入力されたデータの中に半角カタカナが含まれているかチェックするコードを書きましたので復習を兼ねてサンプルへまとめたいと思います。
詳しい正規化表現については下記のサイトを参考にしました。

#### 参考サイト
-「JavaScript 正規表現まとめ」
https://qiita.com/iLLviA/items/b6bf680cd2408edd050f
-「全角・半角カタカナのバリデーションルール設定方法（正規表現）」
https://qiita.com/nasuB7373/items/17adc4b808a8bd39624d

# サンプル関数
```Typescript:sample.ts
const containsHalfSizeKana = (text: string): boolean => {
  // 文字列として入力されているかチェック
  if (typeof text != 'string') {
     return false
  }
  // 半角カタカナが含まれているかチェック
  const halfSizeKana_regex = new RegExp(/[ｦ-ﾟ]/) 
  if (text.match(halfSizeKana_regex)) { 
    return true
  }
  return false
}

//実行結果
containsHalfSizeKana() //false
containsHalfSizeKana(null) //false
containsHalfSizeKana(undefined) //false
containsHalfSizeKana("あいうえお") //false
containsHalfSizeKana("アイウエオ") //false
containsHalfSizeKana("012345") //false
containsHalfSizeKana("aiueo") //false
containsHalfSizeKana("ｱｲｳｴｵ") //true
containsHalfSizeKana("アイウエｵ") //true
containsHalfSizeKana("ﾌｧ") //true
```

まとめ
今回は文字列に半角カタカナが含まれているかチェックしました。
開発時に正規化表現でこんな機能があったと思いだすことができるレベルになれればと思います。
Kali Linux 2023.4 Release (Cloud ARM64, Vagrant Hyper-V & Raspberry Pi 5)

# はじめに
2023年12月5日、[Kali Linux 2023.4 Release (Cloud ARM64, Vagrant Hyper-V & Raspberry Pi 5)](https://www.kali.org/blog/kali-linux-2023-4-release/)の通りにKaliの新しいリリースが公開されています。

今回のリリースでは、多数の新しいプラットフォームの提供や新しいツールが追加されました。詳細については、上記公式のブログ記事をご参照ください。

本記事では、今回新しく追加されたツールの一部について記載しています。

## アップデート方法
公式ドキュメントの[Updating Kali](https://www.kali.org/docs/general-use/updating-kali/)を踏まえて、Kaliのアップデート方法を以下に記載します。

前提として、`/etc/apt/sources.list`が適切に設定されていることを確認した上で以下のコマンドを実行します。

`$ sudo apt update`
`$ sudo apt full-upgrade -y`

上記コマンド実行後、OS再起動を行います。
OS再起動後、`/etc/os-release`ファイルを参照してディストリビューションのバージョンが更新されたことを確認します。

```console
VERSION_ID="2023.4"
VERSION="2023.4"
VERSION_CODENAME=kali-rolling
```

## PassDetective
PassDetectiveは、BashやZ Shellなどのコマンド履歴をスキャンして、誤って書き込まれたパスワード、API キー、およびシークレットを検出します。

https://github.com/aydinnyunus/PassDetective

以下に実行例を記載します。

- パッケージのインストール
`$ sudo apt install passdetective`

検証としてAWSの公式ドキュメントで使用されているアクセスキーの環境変数をexportします。

`$ export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE`

Bashを使用しているため、以下のコマンドを実行します。

`$ PassDetective extract -b -s`

```console
===============================================================
Scan is started.
===============================================================
AWS API Key
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
Amazon AWS Access Key ID
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
===============================================================
Scan is finished.
===============================================================
```

exportした環境変数が検出できました。

`PassDetective extract -h`を実行することで、コマンドのオプションが確認できます。

```console
The "extract" command allows you to automatically extract passwords from shell history.
By analyzing the history of shell commands, this tool can identify and extract passwords that were used during
previous commands and display them for further inspection or use.

Usage:
  PassDetective extract [flags]

Flags:
  -a, --all       Check passwords on all shells
  -b, --bash      Check passwords on BASH
  -h, --help      help for extract
  -s, --secrets   Check secrets on shell history
  -z, --zsh       Check passwords on ZSH
```

## Portspoof
Portspoofは、OSのセキュリティを強化することを目的に開発されています。

使い方として、特定のポートがCLOSEDまたはFILTERED状態にあることを攻撃者に通知する代わりに、PortspoofはポートごとにSYN+ACKを返します。

従って、攻撃者に対して偽のバナーを生成したり、スキャナーを騙すために使用されます。

https://github.com/drk1wi/portspoof

以下に実行例を記載します。

- パッケージのインストール
`$ sudo apt install portspoof`

以下の様なコマンドを実行することで、ポートをエミュレートします。

`portspoof -i <Ip address> -p <Port Number>`

# おわりに
今回のアップデートではOSINTに関するパッケージもいくつか追加されているため、OSINTに対する重要度が上がっている気がします。

仮想マシンでもKali Linuxを動かすことはできますが、不自由なくパフォーマンスを発揮するためには自作PCなどで動かすのもお勧めです。

以前書いた以下の記事では、自作PCにKali Linuxを導入及び構築する方法について記載しています。

- [自作PCの組み立て方　ベアメタルで構築するKali Linux【PC組み立て編】](https://qiita.com/Brutus/items/4d6da6a989f2a64ec9a2)
- [自作PCの組み立て方　ベアメタルで構築するKali Linux【構築編】](https://qiita.com/Brutus/items/a35654b7644fb358b9cd)
Rubyのイミュータブルとミュータブルオブジェクトが理解したかった

## まず
Rubyにおいてオブジェクトが　**イミュータブル（不変）**　か　**ミュータブル（可変）**　かという区分は、プログラムの設計とパフォーマンスに重大な影響を与えます、と言われているが正直なところどのように影響しているのかわからなかったのでまとめました

## イミュータブルオブジェクトの特徴と利点
イミュータブルオブジェクトは、一度作成されるとその状態が変更されないオブジェクトらしい。
Rubyでは、数値やシンボル、凍結された文字列などがイミュータブルに該当
ここで数値がイミュータブルなのは違和感というかよくわからなかったので深掘りしてみよう

## 数値のイミュータブル性
Rubyにおける数値はイミュータブル！
これは、数値に対する操作が元の数値を変更することなく、常に新しい数値オブジェクトを生成する

### 具体例
```ruby
a = 10
b = a + 5
# aは10のまま、bは15になる
```
この場合、a の値は変更されず、a + 5 の計算により新しい数値 15 が作成され b に代入される。
これだとわかりにくいというかよくわからなかったのでもう少しやってみる
```Ruby
a = 100
b = 100
c = 100

# a, b, cのオブジェクトIDを確認
id_a = a.object_id
id_b = b.object_id
id_c = c.object_id

puts id_a, id_b, id_c
```
こうした時にputsで表示されるidsは同じになる

## イミュータブルのメリット
~~安全性と予測可能性: 数値が不変であるため、値が意図せず変更されることがなく、バグの原因を減らすことができる。~~
↑については自分で検証する方法がわからなかった、参考書的な知識だとこうらしい
- メモリ効率: 同じ値を持つ数値はメモリ上で共有され、新しいメモリ領域を確保する必要がなくなる。
- ガベージコレクションの効率化: オブジェクトが不変であれば、ガベージコレクタの負担が軽減され、パフォーマンスが向上します。（ガベージコレクション（メモリの不要なデータを回収し、再利用可能にするプロセス））

### シンボルのイミュータブル性
シンボルもイミュータブル。一度作成されたシンボルは変更されず、同じシンボルはプログラム全体で共有される
```Ruby
symbol = :symbol
symbol_another = :symbol
symbol == symbol_another # => true
```

## ミュータブルオブジェクトの特徴と取り扱い
一方、ミュータブルオブジェクトは、作成後にその状態を変更できるオブジェクト
Rubyでは配列、ハッシュ、非凍結の文字列などがミュータブル

### ミュータブルオブジェクトの例
配列やハッシュはミュータブルであり、要素の追加や変更が可能

具体例
```ruby
array = [1, 2, 3]
array << 4
# arrayは[1, 2, 3, 4]になる
```
この例では、配列 array に新しい要素を追加できる→ミュータブルだね！

### ミュータブルオブジェクトの取り扱い
ミュータブルオブジェクトの柔軟性は便利、でも変更による副作用やデータの競合に注意する必要があり！

### イミュータブルとミュータブルの選択
プログラムの安全性、効率性、予測可能性を考慮して、イミュータブルとミュータブルのどちらを使用するかを選択するのが大事かなと

## その他重要そうな要素をまとめました
### 文字列の凍結
Ruby 2.3以降では、マジックコメント # frozen_string_literal: true を使用してファイル内のすべての文字列リテラルを自動的に凍結（イミュータブル化）することが可能
```ruby
# frozen_string_literal: true

str1 = "Hello"
str2 = "Hello"

puts str1.object_id == str2.object_id  # => true
```
このようにした時、同じオブジェクトIDになるのは凍結された文字数リテラルを使っているから

### オブジェクトの凍結
freeze メソッドを使用して、ミュータブルオブジェクトをイミュータブルにすることができます。これにより、オブジェクトの不変性を保証することが可能
```ruby
obj = [1, 2, 3]
obj.freeze
obj << 4  # => can't modify frozen Array
```
配列`obj`が凍結されているため、新しい要素を追加しようとするとエラーが発生する

### オブジェクトの複製
dup または clone メソッドを使ってオブジェクトの複製を作成することで、元のオブジェクトを変更から保護する
``` ruby
original_array = [1, 2, 3]
duplicate_array = original_array.dup

duplicate_array << 4
puts original_array.inspect  # => [1, 2, 3]
puts duplicate_array.inspect # => [1, 2, 3, 4]
```
dupを使用して配列の複製を作成し、複製された配列に変更を加えても元の配列は変更されない
dupとcloneの主な違いは、cloneは凍結状態や特異メソッドも複製する点
https://www.rubyguides.com/2018/11/dup-vs-clone/
https://www.rubysos.com/std-lib/whats-the-difference-between-rubys-dup-and-clone-methods/
https://koenwoortman.com/ruby-clone-object/
go-awslambda

```text
--- FAIL: TestSlogtest (0.03s)
    \zapslog\logger.go:130: 	message
    \zapslog\logger.go:130: 	INFO	message	{"k": "v"}
    \zapslog\logger.go:130: 	msg	{"a": "b", "c": "d"}
    \zapslog\logger.go:130: INFO	msg	{"k": "v"}
    \zapslog\logger.go:130: 	msg	{"a": "b", "k": "v"}
    \zapslog\logger.go:130: 	msg	{"a": "b", "G": {"c": "d"}, "e": "f"}
    \zapslog\logger.go:130: 	msg	{"a": "b", "e": "f"}
    \zapslog\logger.go:130: 	msg	{"a": "b", "c": "d", "e": "f"}
    \zapslog\logger.go:130: 	a Handler should inline the Attrs of a group with an empty key	{"a": "b"}
    \zapslog\logger.go:130: 	a Handler should handle multiple WithGroup and WithAttr calls	{"a": "b", "G": {"c": "d", "e": "f"}}
    \zapslog\logger.go:130: 	msg	{"a": "b", "G": {"c": "d"}}
    \zapslog\logger.go:130: 	msg	{"k": "replaced"}
    \zapslog\logger.go:130: 	msg	{"G": {"a": "v1", "b": "v2"}}
    \zapslog\logger.go:130: 	msg	{"k": "replaced"}
    \zapslog\logger.go:130: 	msg	{"G": {"a": "v1", "b": "v2"}}
```

```
{"G": {"a": "b"}}
{"a": "b", "G": {"c": "d", "H": {"e": "f"}}}
```

```aaa.go
// WithAttrs returns a new Handler whose attributes consist of
// both the receiver's attributes and the arguments.
func (h *Handler) WithAttrs(attrs []slog.Attr) slog.Handler {
	var cloned Handler

	if h.holdGroup != "" {
		handler := h.withFields(zap.Namespace(h.holdGroup))
		cloned = *handler
	} else {
		cloned = *h
	}
	cloned.holdGroup = ""

	fields := make([]zapcore.Field, 0, len(attrs))
	for _, attr := range attrs {
		fields = append(fields, convertAttrToField(attr))
	}
	return (&cloned).withFields(fields...)
}

// WithGroup returns a new Handler with the given group appended to
// the receiver's existing groups.
func (h *Handler) WithGroup(group string) slog.Handler {
	var cloned Handler

	if h.holdGroup != "" {
		handler := h.withFields(zap.Namespace(h.holdGroup))
		cloned = *handler
	} else {
		cloned = *h
	}
	cloned.holdGroup = group
	return &cloned
}
```
[2024/02/07] Zoom Video SDKのウェビナーを開催します

Zoom Video SDK - Zoomのコア・テクノロジーでビデオ通信を実現

新しいユーザーにサービスを提供し、収益の機会を増やしたいとお考えの場合、Zoom Video SDKは、独自のブランディングとユーザーインターフェイスを使用しながら、構築に必要なツールを提供します。遠隔医療から教育、採用から不動産取引まで、ZoomのVideo SDKがどのように貴社のイノベーションを可能にするか、ぜひ本ウェビナーに参加いただき、ご確認ください。

昨年12月にTwilio社がTwilio Programabble Videoを提供を2024年12月に終了することを発表、推奨移行先としてZoom Video SDKを選定されたことを併せて発表しました。

https://www.zoom.com/ja/blog/welcome-twilio-video-developers-3-reasons-why-zoom-s-video-sdk-is-a-win-for-you/

この度、本件について非常に多くの日本の皆さまからお問い合わせいただいたことを踏まえて、Twilio Japanからソリューションアーキテクトの中村様をゲストにお招きして、ウェビナーを開催する運びとなりました。

皆さまのご参加を心よりお待ち申し上げております。

開催日時: 2024年2月7日 16:00-17:00

講演者
Twilio Japan 合同会社 ソリューションアーキテクト 中村 光晴
ZVC JAPAN 株式会社(Zoom) ISV事業開発部長 佐野 健

▼お申し込みはこちら
https://success.zoom.us/webinar/register/6917066535124/WN_iM-yf-xmSd2njaEnjm54VQ

当日はTwilio社がProgramabble Videoの移行先としてZoom Video SDKを選んだ理由に加えて、文字起こしや翻訳機能など、Zoom Video SDKの最新機能もご案内する予定です。

少しでもご興味がありましたら、ぜひご登録の上、当日のご参加をお待ちしております。
20億ドル相当のユニコーンを育てる - CEOからのもうひとつの手紙

<font color="Grey">*[Raising a unicorn worth $2 billion - another letter from our CEO](https://aiven.io/blog/raising-a-unicorn)の翻訳です。*</font>

2021年10月19日

#20億ドル相当のユニコーンを育てる - CEOからのもうひとつの手紙

AivenはシリーズCを1億6,000万ドルまで拡大し、ユニコーンの地位を獲得しました。Aivenにとって、そしてオープンソースデータテクノロジーの未来にとって、このことが何を意味するのかをご覧ください。

[前回のブログ記事](https://aiven.io/blog/building-aiven-from-zero-to-usd800m-a-letter-from-our-ceo)で、私はシリーズCの資金調達ラウンドを発表し、Aivenの未来について書きました。わずか7ヶ月前のことですが、あれから多くのことが起こりました。


収益率はおよそ2倍になりました。従業員数は140人から230人以上に増え、シンガポールとニュージーランドにもチームを拡大しました。また、オープンソース・プログラム・オフィスを立ち上げ、企業としていくつかのオープンソース・プロジェクトに上流から貢献しています。


これらすべてが[最新ニュース](https://aiven.io/press/aiven-achieves-usd2b-unicorn-valuation-with-its-series-c-extension)に結実しています：Aivenは6,000万ドルの追加資金を調達し、シリーズCラウンドの総額を1億6,000万ドルに拡大しました。また、会社の評価額も新たに決定しました：Aivenの企業価値は20億ドルに達し、北欧発の最新ユニコーンとなりました。


わずか6年でゼロからここまで来たことを考えると、身が引き締まる思いです。そして、これを可能にしてくれたAivenの従業員や創業者仲間、顧客やパートナーには、これ以上ないほど感謝しています。ありがとうございました！



> ![](/build/_assets/shape-quote-WGSAHX4E.svg)
> > "わずか6年でゼロからここまでの道のりを歩んできたことを考えると、身が引き締まる思いだ。"
>

>


私たちの使命は常に明確です。私たちは開発者の生活を向上させ、メンテナンスや管理の負担なしにオープンソースデータテクノロジーの利点を活用できるようにしたいと考えています。


私たちが成長するにつれて、より多くの開発者がこのようなことができるように支援してきました。現在では、Aivenが世界中でマネージド・クラウド・データ・インフラストラクチャを提供するリーダー的存在になりつつあります。



> ![](/build/_assets/shape-quote-WGSAHX4E.svg)
> 私たちは開発者の生活を向上させ、保守や管理の負担なしにオープンソース技術のメリットを活用できるようにしたいと考えています。
>
>
>


お客様との会話の中で、Aivenが運用コストの削減、ビジネスの俊敏性の向上、開発者の日々の生産性の向上など、その他の目標達成に役立っていることを耳にする機会も増えました。


こうしたことを定量化するために、私たちは最近[IDCによる調査](https://aiven.io/blog/aiven-cloud-data-services-bring-340-three-year-roi)のスポンサーとなり、一部のお客様にインタビューを行い、Aivenサービスのビジネス価値について調査しました。その結果は興味深いものでした。全体として、私たちはオープンソース・テクノロジーが企業にもたらすメリットを表面化させたに過ぎないと考えています。そして、私たちの成長を支援してくれるビジョンを共有する投資家がいることを嬉しく思っています：World Innovation Lab、IVP、Atomico、Earlybird、First Fellows、Lifeline Ventures、Salesforce Venturesです。



> ![](/build/_assets/shape-quote-WGSAHX4E.svg)
> オープンソース技術が企業にもたらす恩恵は、まだ表面しか見ていないと思います。
>
>
>


つまり、簡単でアクセスしやすいオープンソースを支持し続けることが、今後のAivenに期待できることなのだ。しかし、これは実際にはどのように見えるのでしょうか？


私たちが今取り組んでいることをいくつかご紹介しましょう：


* [Aivenのスタートアップ・プログラムであるCluster](https://landing.aiven.io/signup-cluster-notification/)を、数週間後に世界で最もクールなスタートアップ・イベントであるSlushで発表します。
* すでに世界50カ国以上で顧客にサービスを提供しており、次はパリとシンガポールにオフィスを開設し、これらの地域の顧客とより密接に連携する予定です。
* 私たちは、Aivenプラットフォーム上でより洗練されたストリーミングのユースケースを直接可能にするApache Flinkのような新しいオープンソース技術で製品ポートフォリオを広げています。
* さまざまなオープンソースコミュニティに貢献するため、より多くの時間とリソースを割くオープンソースプログラムオフィスを成長させます。


私は前回のブログで、この先のオープンな道がどこまで続くのか楽しみだと述べました。今日、私たちはすでにかなり先まで進んでいますが、まだ先は長いです。それが私たちの好きなところだ。


## まとめ


Aivenのサービスをまだご利用でない方は<https://console.aiven.io/signup>から無料トライアルにお申し込みください！


また、[changelog](https://aiven.io/changelog)や[blog](https://aiven.io/blog)のRSSフィード、または[LinkedIn](https://www.linkedin.com/company/aiven/)や[Twitter](https://twitter.com/aiven_io)のアカウントをフォローし、製品や機能関連の最新情報をご確認ください。
MojoのインストールとPythonとの速度比較

## はじめに
Mojo🔥は、Pythonの上位互換という話で、とても速いということでニュースになっていました。ニュースからしばらく経過して、簡単に触れるようになってきたので、実際に体験してみたいということで触ってみた備忘録となります。

## インストール

- 環境：Windows WSL2 - Ubuntu 22.04.2 LTS

参照させていただいたいくつかのページをみるとおり、とても簡単。
公式で Windows WSL2でのやり方もでています。

https://www.modular.com/max/mojo

![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/61035f41-82b2-8dff-5c0d-9055d6da45b0.png)

![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/88e24caf-e541-c998-8c23-0e049a8a100d.png)

Modular CLIのインストール

~~~ bash:Ubuntu
curl https://get.modular.com | sh - && \
modular auth mut_166cde5cb99f4247a1e2fae9f0228a9e
~~~

![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/fc54cca0-d8b9-70bc-41f5-00abcfbe6a04.png)

インストール
~~~ bash:Ubuntu
modular install mojo
~~~

以下のようなエラーになるので、指示どおり python3.10-venvをインストール

![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/dcd9a509-97f7-e6e5-5466-a849c138b0a8.png)

再チャレンジで完了。指示どおり、パス設定。

![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/ea322668-bac7-fa24-4f24-93250f25b7ff.png)

mojoをたたくと、Welocom to Mojoがでてきました。

![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/ba049d07-3840-b012-4ff6-e291bb0bef80.png)

## Hello World

printとそのまま書くのではなく、fn main(): を記載するのが特徴

~~~ hello wrold.mojo
fn main():
    print("Hello mojo World!")
~~~

## 比較プログラム
PythonとMojoで素数を求めるプログラムで比較してみたいと思います。

- python 3.10.12
- mojo 0.7.0

速度の比較というと「素数」を求める、みたいな感じに数学素人はなってしまいます。ということで、1～3,000,000の間の数字で素数を求め、それにかかった時間を見てみたいと思います。

こういうケースに、ChatGPTやCopilotはめちゃくちゃ便利です。一瞬でサンプルプログラムを作成くれ、ちょっとだけ修正。素数の数もカウントします。

~~~ primes.py
import time

def is_prime(n):
    if n < 2:
        return False
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            return False
    return True

# スタート
print("start")

start_time = time.time()

num_primes = 0

for i in range(1, 3000000):
    if is_prime(i):
        num_primes += 1

end_time = time.time()

proc_time = end_time - start_time

print("素数の数: ", num_primes)
print("かかった秒数: ", proc_time)
~~~

Mojoに関しては最近の言語のため、ChatGPTへの指示は、うまくやらないとでてない＆でてきたサンプルでは、ちょこちょこ間違いがありました。（"pythonに似たmojoという言語で～"、という感じで指示とすると、まぁまぁのものが返ってきました）

~~~ primes.mojo
from time import now

fn is_prime(n: Int) -> Bool:
    if n < 2:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

fn main():
    print("start")

    let start_time = now()

    var num_primes = 0

    for i in range(1, 3000000):
        if is_prime(i):
            num_primes += 1

    let end_time = now()
    
    let proc_time = end_time - start_time

    let seconds = proc_time / 1000 / 1000 / 1000

    print("素数の数: ", num_primes)
    print("かかった秒数: ", seconds)
~~~

## 比較結果
私の環境下では以下のようになり、とても速いということを体感できました。

~~~
#py
start
素数の数:  216816
かかった秒数:  10.494363069534302

#mojo
start
素数の数:  216816
かかった秒数:  0.526632353
~~~

## 参照URL

https://qiita.com/gomi1994/items/ea87468d4f4ba7bbf462

https://qiita.com/masahibi/items/6da96c0ff4c8c15f1652
ドコモ光で、ひかり電話のみ解約する

かなり混乱したので、記録を共有する。
結論、IPoE接続なら、ホームゲートウェイが、ただのONUになるので、IPv6対応ルーターを準備すればよい。
ドコモに聞くと技術がない人が電話に出て、しかも、オペレーター端末の顧客情報にppp接続か、IPoE接続かの情報を持っておらず、話がややこしくなる。

一番最初に電話するところは、プロバイダ。

なお、対応ルーターについては、プロバイダのホームページに動作確認済みのwifiルーターが掲載されているので、その中から選択すべし。


# その１（NTT）
ひかり電話を解約するため、0120-116116に電話した。
ひかり電話の番号で契約の有無を調べてもらうと、
　　・でんわ契約　１
　　・アクセス　コラボ事業者　１
があった。
いつ解約したいか聞かれたので、「可能な限り早く」と答えた。
調査後、NTTから電話するとのことで、いったん電話は切れた。
１時間くらいしてNTTから電話があり、
　　・工事無し（たぶん、私の家に誰も来ないという意味）
　　・機器の返却無し
　　・○月○日に設定して、電話が使えなくなります。
　　・ホームゲートウェイが使えなくなるので、ルータを用意してください。
　　・ルータを買うか、ドコモからレンタルしてください。
とのことだった。
インターネットが使えなくなる可能性があるので、
　　・申込なし
　　・相談のみ
とした。

# その２（ドコモ光）
ドコモ光の 151 7-1-5 に電話した。

私：NTTにホームゲートウェイが使えなくなると言われたが、機器の無料レンタルはしてくれるのか？
オペ：まずは、固定電話を先に廃止手続きをしてもらって、工事（局内）が終わったら、また、ここに電話してもらったら、設定担当につなげる。

私：インターネットにつながらない状況が長くなると困る。１日で必ず設定できるのか？
オペ：現時点で案内できることが無いか、設定担当に回します

# その３（ドコモ光・設定担当）

明確になったこと
・NTTのホームゲートウェイの情報は遠隔でNTTに消される（その日に局内工事も実施される）
・NTTのホームゲートウェイは、ONUとして使い続ける
・自分のルータに プロバイダの　IDとパスワード等を設定する必要がある（本当？）
・151は年中無休　9:00～20:00（設定担当も同じ）
・バッファローのルーター設定のサポートは有償（ドコモネットトータルサポート）

まずやること
プロバイダのID、パスワードを書いた紙が行方不明、探さないと

# ここで疑問を整理
IPoEなので、ルータにプロバイダのIDとパスワードを設定する必要は無いのでは？
自宅のバッファローのWiFiルーター（APモードで使用中）は古い、IPv6接続できるのか？

https://support.biglobe.ne.jp/settei/setuzoku/docomoh/index.html

https://support.biglobe.ne.jp/ipv6/

https://support.biglobe.ne.jp/ipv6/compatibility.html

https://support.biglobe.ne.jp/settei/setuzoku/ipv6/

# その４（再度・ドコモ光）
ドコモ光の 151 7-1-5 に電話した。

ここで明確になったのは、
・ホームゲートウェイはNTTに消去された後、ONUとして使う
・ドコモから小さいONUを新たにレンタルされない
・IPv6接続のことはドコモではわからないので、プロバイダのビッグローブに確認するように

# その５（ビッグローブ）
固定電話から無料の　0120-86-0962 に電話した。
もしかしたら固定電話最後の発信かも？
土曜日というのもあって、なかなかつながらない。
20分待ち。

まず、今ある機械で接続できるように v4 の設定うんぬんの話が出たが、ビッグローブのホームページで動作確認ができているwifiルータに買い替えると説明

結論
①　BIGLOBEのホームページにあるドコモ光で動作確認済みのwifiルーターを購入
②　商品到着後、NTTに電話して、ひかり電話の契約を切る
③　機器を接続して、wifiルータの設定をv6で接続するように変更（ここはルータを買ったとこ、例えば、バッファローに聞け）
※設定は超簡単と思うが、ビッグローブの人に簡単ですよね？と聞いたが、明確に簡単と言ってくれなかった。

# ここまでの感想
ドコモ光で技術的なことを聞くなら、プロバイダに聞くのが一番。
NTT、NTTドコモは、名前や規模で、注文取って、ピンハネして、協力会社に丸投げという基本体質は昔も今も変わらない。
.(ピリオド)で終わるフォルダの削除方法

- zipを展開する際に.で終わるフォルダ名にした。
- 削除しようとすると"この項目は見つかりませんでした"と表示され、削除できない。
- コマンドプロンプトで以下を入力
- ```rd /s "\\?\C:絶対パス"```
- 例)```rd /s "\\?\C:\Users\myname\Documents\spring-tool-suite-4-4.21.0."```
プリザンターのインストールで「CodeDefinerの実行」でエラーになった時の対応策

# はじめに
[プリザンター](https://pleasanter.org/)を久々にローカル環境で動かそうと思った時に躓いたのでメモ。

## 環境
OS：windows 11 pro

## 現象
公式ドキュメントの[プリザンターをWindowsにインストールする](https://pleasanter.org/manual/getting-started-pleasanter-windows)の手順で**CodeDefinerの実行**を行うと「フルテキスト検索がインストールされていないか、フルテキスト　コンポーネントを読み込めませんでした。」というエラーが出る。

```batchfile
 cd C:\web\pleasanter\Implem.CodeDefiner
 dotnet Implem.CodeDefiner.dll _rds
```

### 実際のメッセージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/be104adb-1152-8170-628f-7a9be73db01a.png)

## 原因
その昔、SQL Server ExpressEditionをインストールした時に、基本を選択したのでインストールされていなかった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119455/18cf02cf-93b1-5649-2cd7-d2b75a07d6cb.png)

## 対応
公式ドキュメントの[SQL Server 2019 Expressのインストール及び設定](https://pleasanter.org/manual/install-sql-server2019-express)の手順にある通り「検索のためのフルテキスト抽出とセマンティック抽出」を選択し（または再インストール）を行うとエラー無く進むことができた。

## 忘備録
sp_fulltext_databaseで有効になるか試してみたが、正常終了となるものの、インストールされていないので有効にはならなかった。

```sql
EXEC sp_fulltext_database 'enable'
```
Asus ROG ZephyrusG14 のキーボードが光らない問題

# 症状

Armoury Crateの`設定`にある`アップデートセンター`を使用してアップデートを行ったら電源接続時・バッテリー駆動時・BIOS画面など全ての状態でキーボードが光らなくなった。

# サービスバージョン

型番: GA401QM

OS: Windows 10 --> 11にアップデート済み

```
Item                       Version     
----                       -------     
Armoury Crate UWP App      5.7.9.0     
ROG Live Service           2.3.6.0     
Aura Service (Lighting Service)  3.07.33     
Armoury Crate service      5.7.9       
Aura Wallpaper Service     インストールされていません
Aura SDK                   3.04.39     
ASUS Aac_GmAcc HAL         1.0.0.0     
ASUS Aac_NBDT HAL          2.5.35.0    
ASUS Ambient HAL           2.0.0.0     
ASUS Keyboard HAL          1.01.48     
ASUS MB Peripheral Products  1.0.35      
ASUS Mouse HAL             1.1.0.45    
AacAudioHal                1.3.26.0    
AacDisplay                 1.2.12      
```

# 解決方法

1. Armoury Crateを開きます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283091/0a89823d-110a-82f6-b71f-f26e554fe23c.png)

2. 左側サイドバーから`デバイス`の`システム`を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283091/14c8afb4-504e-e16e-9e1d-f153e1f969e7.png)

3. `ライティング`の`設定`を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283091/fc6b21d2-5bd1-fb25-6e3d-830a3b955ceb.png)

4. `電源時接続時`の`キーボード`をオンの場合、`オフ`にしてから`オン`にする

※オフの場合はオンする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283091/1732fe1f-b2ff-4158-c488-44ab3f9d6a42.png)

完了

# 参考ページ

https://www.reddit.com/r/ZephyrusG14/comments/wr12k0/keyboard_backlight_not_working_on_2021_zephyrus/
Pacemaker2系でノードをstandbyに落とすやり方

Pacemaker2系を使っててノードをStandbyに落とす時のコマンドメモ。
`crm node standby` でもなく、 `pcs cluster standby` でもなかった我が家のHAクラスタ環境。

コマンドを探すのに苦労したのでメモしておく。


### HAクラスタからノードを外す

* 例： `rpi2b-ds-3` をStandbyにする
    ```sh
    crm_standby -N rpi2b-ds-3 -v on
    ```


### HAクラスタにノードを戻す

* 例： `rpi2b-ds-3` をOnLineにする
    ```sh
    crm_standby -N rpi2b-ds-3 -v off
    ```



standby属性をon/offすることで、クラスタから切り離す感じ。
【PostGIS】マルチポリゴンをシングルポリゴンに変換

地理データを扱うシステムを開発する際に、 PostGIS のマルチポリゴンのデータをシングルポリゴン(単一ポリゴン)に変更する機会があったので、その方法を記しておきます。

# シングルポリゴンとマルチポリゴンのテーブル

以下のようなシングルポリゴンのテーブルがあるとします。

```sql
CREATE TABLE areas (
    area_id integer NOT NULL,
    wkb_geometry public.geometry(Polygon,4326)
);
```

上記のテーブルに、以下のマルチポリゴンのテーブルのデータをシングルポリゴンに変換して入れようと思います。

```sql
CREATE TABLE areas_multi (
    area_id integer NOT NULL,
    wkb_geometry public.geometry(MultiPolygon,6668)
);
```

# 変換 SQL

前提として area_id は 2つのテーブル間で重ならないとします。
以下の SQL で areas_multi.wkb_geometry のマルチポリゴンをシングルポリゴンに変換して、 areas.wkb_geometry に挿入します。

```sql
BEGIN;

INSERT INTO areas (area_id, wkb_geometry)
SELECT area_id, (ST_Dump(ST_Transform(wkb_geometry, 4326))).geom FROM areas_multi;

COMMIT;
```

まず、空間参照系が異なりますので、 SRID:6668 の参照系から SRID:4326 の参照系へ ST_Transform を用いて変換します。
次に ST_Dump でマルチポリゴンをシングルポリゴンに変換しています。

ST_Dump はマルチポリゴンを変換した場合、 geometry_dump(geom, path) の形式の複数のレコードに変換されます。
今回は geom だけを挿入しましたが、各ポリゴンをユニークに扱いたい場合は、 path を含めた複合キーを作るなど、工夫が必要です。

# 参考

http://cse.naro.affrc.go.jp/yellow/pgisman/2.2.0/ST_Transform.html

http://cse.naro.affrc.go.jp/yellow/pgisman/2.2.0/ST_Dump.html
Bitgetで全銘柄集めるまで注文し続けるショッピングジャンキーbot

# 趣旨
取引所に上場している全USDTペア銘柄を購入したいけど、一つ一つ注文するの面倒くさいという時に大活躍するショッピング中毒botを作ってみたので公開します。

以下の記事で公開した関数を利用しますので、まずはこっちの記事を先に見て参考にしてください。
`market_order.py`と`market_order.py`と`config.py`はそのまま使用します。

https://qiita.com/danieltanaka/items/fc229ccddcd573d861cd

:::note alert
以下のコードを実行する場合は全て自己責任でお願い致します。
本記事は教育目的での共有であり、投資を勧誘するものではありません。
:::

# 環境設定
前回と同じディレクトリに移動します。
```
cd jikannomuda
```
前回の続きなので特筆すべきポイントはないですね。

# メインのコード
まずはコードを起動した結果がどうなるか説明します。

JSONファイルが作成され、一つずつUSDTのペアになっているコインを6USDT分ずつだけ購入していきます。
購入がなされて30秒経過した時点でデータが保管されます。

例えば"TRXUSDT"を例にとると"5"は取引所でセットされているminTradeUSDTの数値で、"160.61222700"　は購入がなされた枚数になります。

```json: 結果のサンプル
{
    "TRXUSDT": [
        "5",
        "160.61222700"　
    ],
    "LINKUSDT": [
        "5",
        "1.18881000"
    ],
```
注意しておくべき点は途中でbotを中断してもう一度初めからやりなおすと、途中の銘柄から続行されるのではなくまた初めから6USDT分ずつ購入していく仕様になってます。

また1銘柄毎に30秒待機するよう`market_order.py`で設定してあるのでゆっくり買い物が進んでいきます。コードを試しに実行しても一気に全銘柄を買ってしまうなんてことはありません。

```python zengai.py
from data_functions import fetch_symbol_data, save_data_to_json
from datetime import datetime
from market_order import place_market_order

def main():
    try:
        current_data = fetch_symbol_data()
    except Exception as e:
        print(f"Failed to fetch data: {e}")
        return

    if not current_data:
        print("No data fetched. Exiting.")
        return
        
    current_date = datetime.now().date()
    order_data = {}

    for symbol_info in current_data:
        symbol = symbol_info.get("symbol").replace("/", "")
        # Ensure minTradeUSDT is a number before adding 1
        min_trade_usdt = float(symbol_info.get("minTradeUSDT", 0)) + 1

        usdt_symbol_length = 4
        formatted_symbol = symbol[:-usdt_symbol_length] + '/' + symbol[-usdt_symbol_length:]
        order_result = place_market_order(formatted_symbol, "buy", min_trade_usdt)

        if order_result:
            order_data[symbol] = {
                'min_trade_usdt': min_trade_usdt,
                'order_result': order_result
            }

    order_data['last_update_date'] = current_date.strftime('%Y-%m-%d')
    save_data_to_json(order_data)

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

# 提案
仮想通貨のヒートマップが真っ赤っかの時に色々物色して買うのが面倒くさかったりするんだったら、起動してみてもいいかも知れませんね！

https://coin360.com/
（解決しました）huponexit exit時にプロセスを終了。

### 消えなかったプロセスが消えるようになった
@dameyodamedame さんのアドバイスによりプロセスが消えない事象が解決しました
https://qiita.com/Natukasi/questions/afc603787855f1608132#answer-5f2ac3f9ab191db5ebd1

```
[linuxstudy@xxxx ~]$ bash -l       //コレ重要
[linuxstudy@xxxx ~]$ shopt -s huponexit
[linuxstudy@xxxx ~]$ shopt | grep hup
huponexit      	on                  //onになっている
[linuxstudy@xxxx ~]$ sleep 1200&
[1] 3592
[linuxstudy@xxxx ~]$ ps -ef | grep sleep
linuxst+   3331      1  0 19:47 pts/0    00:00:00 sleep 10000
root       3567    896  0 19:50 ?        00:00:00 sleep 60
linuxst+   3592   3474  0 19:50 pts/0    00:00:00 sleep 1200    //このプロセス
linuxst+   3611   3474  0 19:50 pts/0    00:00:00 grep --color=auto sleep
[linuxstudy@xxxx ~]$ exit
ログアウト
[linuxstudy@xxxx ~]$ ps -ef | grep sleep
linuxst+   3331      1  0 19:47 pts/0    00:00:00 sleep 10000
root       3567    896  0 19:50 ?        00:00:00 sleep 60    //3592プロセスがない。消えた。
root       3627   2241  7 19:51 ?        00:00:00 sleep 3s
linuxst+   3629   3083  0 19:51 pts/0    00:00:00 grep --color=auto sleep
[linuxstudy@xxxx ~]$ 
```


# 以下は、失敗していたときの記録
huponexitをonにした状態でログアウトするとバックグラウンドプロセスが
消滅するという話、ONにしてもプロセスが消滅しない。
# huponexit:off
```
[linuxstudy@xxxx ~]$ shopt | grep hup
huponexit      	off
[linuxstudy@xxxx ~]$ ./sample.sh
^Z
[1]+  停止                  ./sample.sh
[linuxstudy@xxxx ~]$ bg %1
[1]+ ./sample.sh &
[linuxstudy@xxxx ~]$ ps -el | grep -e sample -e PID
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1000  26728  25952  0  80   0 - 28321 do_wai pts/0    00:00:00 sample.sh
[linuxstudy@xxxx ~]$ exit
```
別ターミナルを立ち上げてプロセスを確認。
プロセス（PID:26728)は残ったまま
```
[linuxstudy@xxxx ~]$ ps -el | grep -e sample -e PID
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1000  26728      1  0  80   0 - 28321 do_wai ?        00:00:00 sample.sh
[linuxstudy@xxxx ~]$ 
```
# huponexit:on
```
[linuxstudy@xxxx ~]$ shopt | grep hup
huponexit      	on
[linuxstudy@xxxx ~]$ ./sample.sh
^Z
[1]+  停止                  ./sample.sh
[linuxstudy@xxxx ~]$ bg %1
[1]+ ./sample.sh &
[linuxstudy@xxxx ~]$ ps -el | grep -e sample -e PID
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1000  27138  26832  0  80   0 - 28321 do_wai pts/1    00:00:00 sample.sh
[linuxstudy@xxxx ~]$ exit
```
別ターミナルを立ち上げてプロセスを確認。
プロセス（PID:27138)は残ったまま
```
[linuxstudy@xxxx ~]$ ps -el | grep -e sample -e PID
F S   UID    PID   PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1000  27138      1  0  80   0 - 28321 do_wai ?        00:00:00 sample.sh
```
vimの基本操作をまとめてみた

## Vimとは
Vimとはマウスを使わない、キーボードで操作するエディターです。今回はVimの基本的なコマンドをまとめてみました。
## モード
Vimはキーボードで全て行うのでテキストの入力、カーソルの移動は同じままではできないのでモードという機能で変更して操作します。
| モード | 内容 | コマンド |
|:-:|:-:|:-:|
|  ノーマルモード | カーソルの移動。テキストのコピー、カット、ペースト  |  esc |
|  インサートモード |  テキストの入力、編集 |  a/A/i/l/ci/w |
|ヴィジュアルモード   | テキストの選択  |  v |
## カーソル移動
| コマンド | 実行内容 |
|:-:|:-:|
| j |  下に移動 |
|  k |  上に移動 |
|   l|   左に移動|
|   h|  右に移動 |
|  gg  |ページの一番上に行く|
|   G   |ページの一番下にいく　|
## ファイルの保存
| コマンド | 実行内容 |
|:-:|:-:|
| :w ファイル名  |  名前をつけて保存 |
| :w  |  上書き保存 |
| :q   |  編集終了 |
| :q!  |   保存しないで編集終了|
|  :wq |  保存して終了 |
## 削除
| コマンド | 実行内容 |
|:-:|:-:|
|  x | カーソルの文字を削除  |
|  dd |カーソルがある行を削除   |
|  dw | カーソルの位置から次の単語まで削除  |
|  de | カーソルの位置から単語の末尾まで削除  |
## 検索
| コマンド| 実行内容 |
|:-:|:-:|
|   /文字列| 前の文字列を検索  |
| ?文字列  | 後ろの文字列を検索  |
## 入力、編集
| コマンド | 実行内容 |
|:-:|:-:|
| i  |  カーソルの所からインサートモードに入る |
|  a |カーソルの所から1文字進んでインサートモードに入る    |
|   A| カーソルのある行の最後に飛んでインサートモードに入る   |
|  l |  カーソルのある行の最初に飛んでインサートモードに入る |
| p  | ペースト  |
PHP stdClassって結局なんなのさ

## 概要

stdClassについて調べたので簡単にまとめる。

## stdClassって？

- PHPが最初っから定義してくれている組み込みのクラス
- メソッドもプロパティも定義されていない完全に空のクラス
- `new stdClass();`とすることでインスタンス化できる。
- インスタンス化後にプロパティを定義、値を格納する事ができる。
- 一時的な値の保持や、テスト時のモックのレスポンスなどに使われる。

https://qiita.com/miriwo/items/e7d7cbd55f4003661b62

## 参考文献

https://www.php.net/manual/ja/class.stdclass.php
Next.jsとTailwind CSSでダイアログボックスを秒で実装する

## この記事で分かること
- Next.jsとTailwind CSSでのダイアログボックス（モーダル）の実装方法

## 全ソースコードはこちら

- https://github.com/takayukiblue/nextjs-tailwind-modal-sample

## 実行結果

![no_modal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386528/17a38dd0-f4ad-e1d3-e9de-a078e504b1e1.png)

![modal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386528/5b7dbe95-571d-ab23-6993-c1698cb16343.png)


## 機能概要
- Open Modalをクリックするとダイアログが開く
- ダイアログはOKをクリックするかダイアログの外をクリックすると閉じる
- メッセージは固定

## 実装コード

### ダイアログボックスコンポーネント

- src/app/components/Modal.tsx

```React
import React from 'react';

export type ModalProps = {
  open: boolean;
  onCancel: () => void;
  onOk: () => void;
};

const Modal = (props: ModalProps) => {
  return props.open ? (
    <>
      <div className="bg-white  top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-80 h-48 p-5 flex flex-col items-start absolute z-20">
        <h1 className="text-xl font-bold mb-5">Title</h1>
        <p className="text-lg mb-5">Dialog Message.</p>
        <div className="flex mt-auto w-full">
          <button
            className="bg-slate-900 hover:bg-slate-700 text-white px-8 py-2 mx-auto"
            onClick={() => props.onOk()}
          >
            OK
          </button>
        </div>
      </div>
      <div
        className="fixed bg-black bg-opacity-50 w-full h-full z-10"
        onClick={() => props.onCancel()}
      ></div>
    </>
  ) : (
    <></>
  );
};

export default Modal;
```

### 呼び出し側

- src/app/page.tsx

```React
'use client';

import MessageDialog from './components/Modal';
import { useState } from 'react';

export default function Home() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <>
      <MessageDialog
        open={isOpen}
        onCancel={() => setIsOpen(false)}
        onOk={() => setIsOpen(false)}
      />

      <div className="flex flex-col min-h-screen items-center justify-center">
        <button
          className="bg-slate-900 hover:bg-slate-700 text-white text-lg w-60 h-14 py-2 px-4"
          onClick={() => setIsOpen(true)}
        >
          Open Modal
        </button>
      </div>
    </>
  );
}
```

## フォルダ構成（抜粋）

```
src
  └─ app
      ├─ components
      │   └─ Modal.tsx
      └─ page.tsx
```

## ポイント
- ダイアログは`absolute`を指定することで、元の画面の上に重なるように表示する
- `absolute`の次に`fixed`の`div`を指定することで、背景を半透明を実現し、クリック判定を持たせる
- ダイアログに`z-20`、ダイアログの周囲に`z-10`のZインデックスを指定し、ダイアログが全面に来るようにする
- 呼び出し元は`useState()`で`isOpen`フラグを設定する
- useStateを使用するためClient Side Rendering（`'use client';`）を指定する必要がある
- `props`でメッセージ等を渡すようにすれば、ダイアログの表示を可変にできる
- ダイアログの`<div>`に`className="shadow-2xl"`や`"rounded"`などを指定するともう少しカッコよくなる