OmniAICreator/Qiita-1.07M huggingface dataset:
初めまして。よろしくお願いします。

初めまして。toytoy24と申します。

自己紹介します。よろしくお願いします。

・ドローンをプログラミングで自在に飛ばせるようになりたいです。
　pythonでプログラミングができるようなので、pythonの勉強中です。
　paizaにてPythonの勉強をしています。
　PythonのコードをQiitaでアウトプットすることで、頭の整理をします。
　ドローンエンジニアの方々とつながりたいです。
 
・趣味で、DRONE STAR PARTYを持っています。
　飛ばして遊んでいます。操縦して思ったこととか、
 　操縦記録をQiitaに投稿します。
　
・私はITインフラエンジニアとして15年間勤務しました。
　LinuxおよびWindowsサーバ,NW機器(Cisco)などを取り扱ってました。
 　また、ベンダ資格や情報処理技術者試験に数多く合格しました。
  　例）CCNP,LPIC,基本情報,応用情報,NW,SB,SC,PM,SM,SA等
HamlでRailsのビューを書いてみた

# はじめに

こんにちは！
社会人一年目の石川です。
記事をご覧いただきありがとうございます。

本記事では、Hamlの書き方についてまとめます。

# 目次
1. [Hamlとは？](#hamlとは)
1. [基本的なHamlの書き方](#基本的なhamlの書き方)
1. [Hamlのメリットと注意点](#hamlのメリットと注意点)
4. [Hamlの便利な機能](#hamlの便利な機能)
4. [最後に](#最後に)


# Hamlとは？
Haml (HTML Abstraction Markup Language) は、HTMLを簡潔に書けるテンプレートエンジンで、Ruby on Railsでよく使用されます。

HTMLのタグや閉じタグを手動で書くのは手間が掛かり、ミスが起きやすいです。
読みやすく、保守しやすいテンプレートを書くためのHamlが使われています。

:::note info
### ERB 
RubyコードをHTMLに埋め込むためのテンプレートエンジンです。Railsのビューで最もよく使われるテンプレートシステムの1つで、RubyコードをHTML内に直接記述できます。
:::


# 基本的なHamlの書き方
ERBとHamlのコード例を以下のようにに並べました。
###### ERBの場合
```erb
<div class="container">
  <h1>Welcome to Qiita!</h1>
  <p>Hamlの使い方を学びましょう。</p>
</div>
```

###### Hamlの場合
```haml
.container
  %h1 Welcome to Qiita!
  %p Hamlの使い方を学びましょう。
```
hamlはタグ名の前に`%`を使い、クラス名は`.`、IDは`#`で表現します。
`div`タグは省略可能です。また、インデントで構造を表現していて、閉じタグが必要ありません。


```haml
%ul
  %li リストアイテム1
  %li リストアイテム2
```
# Hamlのメリットと注意点

#### Hamlのメリット
可読性が高い：タグが少なく、インデントだけでHTML構造がわかる。
生産性向上：シンプルな構文で、HTMLを書く時間を短縮できる。

#### Hamlの注意点
インデントミスに注意：インデントが正しくないとエラーになりやすい。


# Hamlの便利な機能
Hamlにはシンプルな文法以外にも便利な機能があるので、それを紹介します。

##### 変数の挿入
RubyコードをHamlで使う場合は`=`を使います。

```haml
%h1= @title
%p= @description
```

##### 条件付きレンダリング
条件によって表示内容を変えたい場合、Rubyの制御構文もそのまま使えます。

```haml
- if user_signed_in?
  %p Welcome back, #{current_user.name}!
- else
  %p Please log in.
```
  
# 最後に
最後まで読んでいただきありがとうございました。
この記事を読んでHamlの書き方について理解が深まれば幸いです。
JavaScript ⇆ jQueryの書き換え　要素の取得編

# はじめに
検索したら腐るほど記事が出てくると思いますが、jQueryをJavaScript(以下js)へ書き換える案件に新人と入る為、簡単にまとめ。


内容は基本的にMDNと

https://developer.mozilla.org/ja/

JavaScript本格入門

https://www.kinokuniya.co.jp/f/dsg-01-9784297132880

の二つを参考に作成していますが、記事書いている本人もjsが得意な訳ではないので間違いがあるかもしれませんが、その際はご指摘いただけますと幸いです。

# DOMとは
Document Object Modelの略
ブラウザに表示されているHTML等をオブジェクトとノードとして表現することで、jsで操作することが出来るようにするAPI。


# 要素の取得
HTMLの要素を取得するには主に以下のような方法がある

* document.getElementBy~("hoge")
* document.querySelector("#hoge")
* document.querySelectorAll(".fuga")
* $(".fuga")

上3つがjsで要素を取得する際に利用される記法
最後の一つがjQueryの記法

例 次のhtmlからpタグを取得する
``` html
<body>
    <div>
        <p class="fuga" id="hoge1">id_hoge1</p>
        <p class="fuga" id="hoge2">id_hoge2</p>
    </div>
</body>
```

```JavaScript
// 指定した値に一致するidを持つ要素だけを取得  
const p_hoge_gemb1 = document.getElementById('hoge1');  // 取得したい要素のidを入力
const p_hoge_qs1   = document.querySlector('#hoge1');  // セレクターの指定はCSSと同じ
const p_hoge_jq1   = $("#hoge1")                       //　〃

// 指定した値に一致するclassを持つ要素を取得  
const p_fuga_gemb1 = document.getElementsByClassName('fuga'); // 取得したい要素のclassを入力
const p_fuga_qs1   = document.querySlectorAll('.fuga');     // セレクターの指定はCSSと同じ
const p_fuga_jq1   = $(".fuga")                             //　〃

// classを指定するのは同じだが挙動が違う
const p_fuga_qs2   = document.querySlector('.fuga');    // 指定したclassを持つ最初の要素だけ取
```

document.getElementBy~は取得したい要素によって~の部分が以下のように変わる
|指定したい対象|記述 |
|:-:|:-:|
|idを指定する場合|Id|
|タグを直接指定する場合|TagName|
|classを指定する場合|ClassName|

# それぞれの使い道

今回のようにquerySelectotとgetElementBy~であれば前者の方が使い勝手良さそうではあるものの、それぞれ特徴がある。

まず一番わかりやすい特徴として、取得される要素の形式(返り値)が違う

|記述|取得される要素の形式|
|:-:|:-:|
|getElementById or querySelector|element|
|getElementsBy~|HTMLCollection|
|querySelectorAll|NodeList|

それぞれ簡単に説明すると
### element
指定したセレクターに一致したHTML要素。
指定した要素が存在しない場合はnullが返る。

### HTMLCollection
指定したセレクターに一致した要素が集合した、【配列風】なオブジェクト。
HTMLCollectionは【生きた要素】で、元になった要素へ変更があった場合、自動で変更が入る。
配列として利用するにはArray.fromなどを使用する必要がある。

### NodeList
ノード(node)の集合。
配列ではないが、forEachメソッドで反復処理を実行することは可能。
querySelectorで取得した場合は静的な要素になるが、Node.ChildNodesなどで取得すると生きた要素になる

* node
  * DOMの基本的な構成要素 jsでHTMLをプログラムで操作する基本単位
  * elementはnodeの一種で基本的に要素(タグ)を表す


# jQuery・JavaScriptそれぞれの書き換えに関するイメージ

扱う要素の数やその後の処理によって変わりますが、個人的にはjQueryからJavaScriptに書き換えるとき、苦にせず入りやすいのはquerySelectorな気がする。


``` mermaid
flowchart TB
gei[getElementById]
gec[getElementsByClassName]
qe[querySelector]
qea[querySelectorAll]
jq[jQuery]

jq <---> qe & qea
qe <--> gei
qea <--> gec

```
読書管理アプリを作ってみた

# Synapsoul: 読書管理アプリ

こんにちは、読書愛好家の皆さん！
ここ数年読書が全然できてないのですが、最近読書欲が再発し始めてきたこともあり、思い切って読書管理アプリを作ってみました。着手から2週間で一気に作ったこともありクオリティはまだまだで、これからもっとブラッシュアップしていく予定ですが、一旦チェックポイントということでメモついでに記事にします。

## アプリ概要

https://www.synapsoul.com/

読書管理アプリというと、有名どころで読書メーターというサービスがあります。自分も使っていました。とてもいいサービスです。
https://bookmeter.com/

本アプリは読書メーターと機能がかぶる部分はありますが、読後体験をより深められるといいな、という思いで作りました。具体的には書籍に対する読書メモの作成、スレッドの作成ができるようにしました。読んだあとに他の人の考えと交流することでより幅広い理解ができるような場所があると面白いだろうなーと。

### 主な機能

1. **書籍管理**: 
   - 好きな本をお気に入り、読んだ本、読んでる本、気になる本、積んでる本などのステータスで管理
   - 書籍情報は楽天ブックスAPIを利用

- 書籍検索画面
![](https://storage.googleapis.com/zenn-user-upload/f13c803284ab-20240909.png)
- マイブック一覧画面
![](https://storage.googleapis.com/zenn-user-upload/d05cdbdfb07c-20240909.png)
- 書籍詳細画面
![](https://storage.googleapis.com/zenn-user-upload/cf6a844cc8ac-20240909.png)

3. **読書メモ機能**:
   - 各書籍に対して読書メモを複数作成できる
   - 公開・非公開の設定があり、公開したものは他のユーザーも見ることができる
   - ファイル添付機能があり、画像やダイアグラム図などで整理した内容を保管できる

- 読書メモ一覧
![](https://storage.googleapis.com/zenn-user-upload/1532a89ffbd7-20240909.png)
- 読書メモ内容確認
![](https://storage.googleapis.com/zenn-user-upload/716b211d999c-20240909.png)
- 公開メモ
![](https://storage.googleapis.com/zenn-user-upload/5a88990d41a8-20240909.png)

4. **スレッド作成機能**:
   - 各書籍に対してスレッドを複数作成できる
   - 他のユーザーとチャットでき、書籍に対してディスカッションできる

- スレッド一覧画面
![](https://storage.googleapis.com/zenn-user-upload/3ca54eb6eebb-20240909.png)
- スレッド詳細画面
![](https://storage.googleapis.com/zenn-user-upload/7481f073d657-20240909.png)

5. **インポート機能**:
   - 読書メーターからのデータインポート機能あり
   - 読んだ本、読んでる本、積読本、読みたい本に登録済みの本を、本アプリに登録可能
   - ユーザーIDは読書メーターのマイページのURL `https://bookmeter.com/users/{user_id}`のuser_idにあたる部分の数字
![](https://storage.googleapis.com/zenn-user-upload/056d0e1de763-20240909.png)

6. **フィードバック機能**:
   - アプリに対するコメント投稿機能、コメントに対するGood/Bad評価あり
   - より良いアプリにしていくために

![](https://storage.googleapis.com/zenn-user-upload/80ee27512b55-20240909.png)

6. **表示名変更機能**:
   - プライバシー保護のために表示名変更機能あり（Googleアカウントの名前は使わない）

![](https://storage.googleapis.com/zenn-user-upload/7b18990bc280-20240909.png)

## 技術スタック

- **フロントエンド**: 
  - Next.js 14（App Router）
  - React 18
  - TypeScript
  - Tailwind CSS

- **バックエンド**:
  - tRPC
  - Prisma ORM
  - PostgreSQL

- **認証**:
  - NextAuth.js (現在はGoogleアカウントでのログインのみ対応)

- **デプロイ**:
  - Vercel

- **その他**:
  - shadcn/ui
  - Lucide Icons
  - Zod for validation
  - Zustand
  - vercel/blob
  - vercel/kv

## 開発所感

### Vercelでのデプロイが楽
初めてvercelでデプロイしました。Githubと連携すればブランチpushするだけで自動でpreview環境、production環境が作られたりとかなり楽。ただサーバーの管理はこちらでできないので自由度の制限はある。

### vercel/blob, vercel/kv
ストレージにvercel/blob, redisにverce/kvを使用。
各環境との統合が楽でenv値も勝手に設定してくれる。

### T3stack
tRPC, Prismaで型安全かつ低コストに開発できた。
Next.jsのServerAction使えばもっと楽になるかも？

### Claude 3.5 Sonnet
フル活用。基本的にやりたいことを指示してコードの大部分を作らせて細かいところは自分で修正。
2週間でここまで作れたのは100%こいつのおかげ。基本的に動くコードを出してくれる。
Projects機能を使って↓を参考にアプリ全体のコードを読ませてた。
https://zenn.dev/olemi/articles/7b7992c055c64a
アプリ全体を把握したうえで回答してくれるので、想定と違った回答は殆どなかった。


## まとめ

もっといっぱい本を読むと、欲しい機能が出てくるかもしれない。
他の人の読書メモはめちゃくちゃ見たい。
Instantiateを変数に代入するってどういうこと？

こんな感じで、

        GameObject goal = Instantiate(goalPrefab, goalPosition, Quaternion.identity);

Instantiate関数を変数に代入するって
どういうこと？
インスタンス化はちゃんとされてるの？

とふと疑問におもったのでメモ
## 結論
変数に代入しようが、インスタンス化はされる。
生成されたオブジェクトへの参照を保存するために
変数に代入している。
## 質疑応答
__Q. なんのために生成したオブジェクトの参照を保存するの？__

__A. オブジェクトにさらに操作・調整を加えたいときに使うため。__

たとえば、
生成したオブジェクトの高さを生成時に調整したい、
と思ったらこのようなコードが必要になる。

        // ゴールポールの高さを設定
        goal.transform.localScale = new Vector2(goal.transform.localScale.x, goalHeight);

ここでは生成したオブジェクトを格納した変数に対して
プロパティを作用させている。

変数に代入しないとこの操作は行えない。

==
コメント歓迎です。
ご指摘をいただけるとうれしいです！
[番外編 #SPECIAL] 「Qiita Award」の振り返り

<!--
 <font color="c00000"></font> 赤
-->
## はじめに
皆様お疲れ様です。
今回の **「番外編」** では<font color="c00000"> **「特別編」** </font>ということで先日Qiita Awardの授賞式がありましたのでそれについて紹介いたします。

まず初めに今回の[**Qiita Award**](https://blog.qiita.com/qiitaengineerfesta-2024-presents/)では<font color="c00000">**「ハーフマラソン賞」**</font>を達成することができました！
![S__8937481.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/06c1081f-bbc6-6042-594d-079617da3be0.jpeg)

Qiita Engineer Festa 2024に19記事投稿したユーザーの皆さまにQiita猫？のボールが贈呈されるとのことです！私も先日届いたので後で紹介します:upside_down:

## 素直な感想
**正直まだまだいけたでしょ、38記事やろうと思えば書けたでしょという悔いがあります。**

私はイベント内で合計**27記事**を作成しました。（小学生時代サッカーやってたときの背番号と一緒でした:soccer:）

ハーフマラソンは19記事以上の作成、完走は**38**記事以上、私の結果は大体真ん中あたりですね...目標は38記事以上でしたが途中から色々あって記事作成の<font color="c00000">**モチベーション**</font>が下がってしまいました。

このことからまだまだ目標に対する<font color="c00000">**熱量が不足している**</font>と感じました。

次回のイベントでは完走賞もらえるように目標を明確にしてモチベーションが継続できる<font color="c00000">**「管理」**</font>というのも徹底しなければなりませんね。そのためには期間内で１日どのくらいの**記事**を作るか、**ボリューム**、**内容**をどうするかを、自分のモチベが維持できる状態にするというのを改めて考えてみます。

これは**資格学習**、**勉強**、**業務等**に置き換えて考えてみるのも良いかなと思っています。（人それぞれ考え方は変わるので色々な人のお知恵を頂きたいですね:rolling_eyes:）

今回のAwardでは色々な賞がありました。
受賞者の方に敬意を表しておめでとうございます:bouquet:
## おわりに

さて、今回**ハーフマラソン賞**で頂いたプレゼントを紹介します。（iPhone 14 ポートレート　スタジオ照明で撮影してみました）
![S__8929285_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/9ea9d108-753d-30c3-1f8a-b65624ce8cc4.jpeg)
100均に売っているゴムボールより少し小さいサイズかなと思います。（何とも可愛らしいですな）そして私は今現在このボールを飾るベストなポジションを考え中です:thinking:
![S__8929287_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/8fddf4f2-f7e4-5d23-b578-7e025dc365ed.jpeg)
![S__8929288_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/41fcf9df-c822-ad8c-a5d7-6bde8bac6637.jpeg)
![S__8929282_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/eff6c25d-c44f-8591-2f0c-07999b184214.jpeg)
![S__8929284_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/08523d31-b08f-57d6-f567-d5a89c4f993e.jpeg)
このQiitaボールは今後の記事作成で出てくるかも？ちょっと楽しみですな

今回は[番外編]の中でも特別編ということで[**Qiita Award**](https://blog.qiita.com/qiitaengineerfesta-2024-presents/)の振り返りを紹介しました。
最後まで読んで頂きありがとうございました！
>>過去の番外編はこちら
[#1 ばねのような動きを再現](https://qiita.com/aoiku/items/19cf51605f80c60d4004)
[#2 関節を動かしてみた](https://qiita.com/aoiku/items/c500c4cb65499d11027a)
HRBrainの年間1,100回リリースを実現する開発体制の秘訣

# はじめに
HRTechのリーディングカンパニーとして、人事領域に特化したプロダクトを多数展開しているHRBrain。
HRBrainは、年間1,100回ものリリースを実現していると聞き、その開発体制の秘密に迫るHRBrainのCTO、鈴木悠大さんへ質問している記事を見つけました。

https://techfeed.io/entries/66d6aa1c36fcf93778d35d95

# 要点
+ **ブランチデプロイ環境の導入**
プルリクエストごとに自動でブランチ専用の環境を構築し、検証やレビューが容易に行える仕組み
+ **Monorepo化の実施**
全プロダクトのコードを単一リポジトリで管理することで、リリースフローや改善の効率化を実現
+ **フィーチャーフラグの活用**
機能のON/OFFを柔軟に制御し、ユーザーに影響を与えずに迅速なリリースとテストを可能にする
+ **完全リモート開発環境の採用**
Google Cloud Workstationsを使用し、ローカル環境の設定不要で素早く開発に取り掛かれる体制を構築
+ **GitHub Actionsによるリリース自動化**
各サービスごとに個別にリリースできるフローを自動化し、リリースの効率化を実現。
+ **トランクベース開発の推進**
早期に各ブランチをmainにマージすることで、コンフリクトを最小化し、開発スピードを維持
+ **効率的なローカル開発環境**
Docker Composeを超える[tilt](https://times.hrbrain.co.jp/entry/2021/12/01/tilt)を導入し、複数の依存プロダクトを一括で立ち上げることで開発を効率化

# 1. 高いリリース頻度を支える開発体制の概要
HRBrainは、そのプロダクトの数の多さにもかかわらず、驚くべきスピードでリリースを続けています。開発チームの指揮を執る鈴木悠大さんは、複数のプロダクトを担当しながらも、効率的なリリースを可能にするための様々な工夫を取り入れているそうです。

「開発生産性を高めるために、我々はリリースのワークフローに多くの改善を加えました。特に、ブランチデプロイ環境の導入が大きな成果を上げました」と鈴木さんは語ります。

# 2. ブランチデプロイ環境による迅速なリリース
HRBrainのリリースフローにおける最大の特徴の一つが、ブランチデプロイ環境です。これは、プルリクエストが作成されるたびに、そのブランチ専用の環境が自動的に立ち上がり、URLが発行される仕組みです。

https://times.hrbrain.co.jp/entry/cloudrun-branch-deploy

「以前は、デプロイ先の環境が限られていて、チームメンバー同士で取り合うような状況でした。しかし、ブランチごとに検証できる専用環境が自動で立ち上がるようになったことで、プルリクエストのレビューやQAの依頼もURLを渡すだけで済み、作業効率が大幅に改善されました」と鈴木さんは説明します。

この仕組みにより、ローカル環境でコードをpullして確認する手間がなくなり、クラウド上ですべて完結することで、開発スピードが飛躍的に向上しました。

https://times.hrbrain.co.jp/entry/kubernetes-branch-deploy

# 3. Monorepo化による管理と生産性の向上
さらに、HRBrainは[Monorepo](https://zenn.dev/burizae/articles/c811cae767965a)化を実施することで、開発の生産性を大幅に向上させました。Monorepoとは、複数のサービスやプロダクトのコードを単一のリポジトリで管理する手法です。

「以前は、サービスごとに30個以上のリポジトリがあり、それぞれに対して同じプルリクエストを出す必要がありました。これでは小さな改善でも億劫になってしまい、どんどん後回しになってしまうことが多かったんです。しかし、Monorepoに移行することで、そのような作業の負担が減り、積極的に改善を行えるようになりました」と鈴木さんは振り返ります。

Monorepo化によって、リポジトリの管理がシンプルになり、リリースフローの改善やバグ修正がより効率的に行えるようになりました。

https://times.hrbrain.co.jp/entry/monorepo

# 4. フィーチャーフラグによる柔軟なリリース管理
HRBrainがリリースのスピードを維持できるもう一つの要因は、[フィーチャーフラグ](https://future-architect.github.io/articles/20230621a/#:~:text=%E3%83%95%E3%82%A3%E3%83%BC%E3%83%81%E3%83%A3%E3%83%BC%E3%83%95%E3%83%A9%E3%82%B0%E3%81%A8%E3%81%AF%E3%82%B3%E3%83%BC%E3%83%89,%E3%81%84%E3%81%8F%E3%81%A8%E5%AE%89%E5%BF%83%E3%81%A7%E3%81%99%E3%81%AD%E3%80%82)の活用です。フィーチャーフラグを使うことで、機能のON/OFFを制御し、ユーザーに影響を与えることなく、開発を進めることができます。

「フィーチャーフラグを導入することで、mainブランチへのマージスピードが格段に上がりました。新機能をリリースしても、ユーザーにはその機能を公開せずにテストや改善を進められるので、開発サイクルを短縮することができました」と鈴木さんは説明します。

この仕組みにより、機能のリリース後も、特定の顧客に対してのみ機能を有効にするなど、細やかなリリース管理が可能となっています。

https://developers.cyberagent.co.jp/blog/archives/35021/

# 5. 完全リモート環境の導入とクラウドの活用
HRBrainは、完全リモート開発環境を採用している点も、彼らの高い生産性に寄与しています。従来のローカル環境での開発から、Google Cloudの[Cloud Workstations](https://cloud.google.com/workstations?hl=ja)を使ったリモート開発環境へと移行しました。

「リモート環境に移行することで、開発の負担が減り、特に新人エンジニアがすぐに開発を開始できる点が大きな利点です。ローカル環境の設定を一から行う手間がなくなり、開発チーム全体のスピードが格段に上がりました」と鈴木さんは語ります。

# 6. まとめ：HRBrainから学べる開発生産性向上の秘訣
HRBrainの開発体制から学べるポイントは多くあります。ブランチデプロイ環境やMonorepo、フィーチャーフラグ、完全リモート環境の導入は、どれも他の企業でも参考になる要素です。特に、クラウド環境の活用と自動化の徹底は、これからの開発のスタンダードとなるでしょう。

HRBrainは、技術的な工夫と組織的な改善の両面から、生産性を高め、年間1,100回ものリリースを実現しています。このような開発体制を取り入れることで、他の企業も同様に効率的な開発を実現できるはずです。
【PostgreSQL】WHERE句に指定する文字列と数値の書き分け

## はじめに
本記事ではSQL学習で躓いたポイントを記録します。

## 概要
PostgreSQLを書く際、WHERE句で「""」を使ったら弾かれたので備忘録として仕様を記録します。

## 詳細
文字列指定の場合
```SQL:test
SELECT *
FROM books 
WHERE name = '宇宙の歴史';
```

数値指定の場合
```SQL:test2
SELECT *
FROM books 
WHERE number = 12;
```

なお、ダブルコーテーションを使うとWEHRE句で認識されません。

## 参考

https://www.javadrive.jp/postgresql/basic/index1.html

以上です。
2024/9/9主にITとかセキュリティの記事

アメリカ国内で販売停止になったKasperskyのユーザー約100万人をPango Groupが救済(9/7)
https://gigazine.net/news/20240907-pango-group-buys-kaspersky-customers/

Android端末をターゲットに「OCRソフトウェアで仮想通貨の認証情報を盗むマルウェア」が280種類以上も見つかる(9/7)
https://gigazine.net/news/20240907-android-spyagent-steals-crypto-credentials-ocr/

サイバー攻撃へ備えを パッケージで対策提案(9/7)
https://ab.jcci.or.jp/article/102200/

SEO（検索エンジン最適化）から「AIO（AI最適化）」へーーAIモデルの信頼性を揺るがす新たな手法(9/6)
https://ledge.ai/articles/aio_manipulates_ai_chatbot_impressions

玄海町のふるさと納税サイト不正アクセス事件に学ぶ、セキュリティ対策の重要性
https://cybersecurity-park.com/2885/

サイバー攻撃に迅速な対応を　ゲーム活用し産学官合同で訓練【宇部】(9/7)
https://ubenippo.co.jp/2024/09/07/4113716/

メガバンクの名を語り8万円騙し取る…スミッシング詐欺のURLを思わずクリックする人の「心の隙」(9/7)
https://diamond.jp/articles/-/349913

“焦りと恐怖心”で正常な判断をさせない データを人質に金銭を巻き上げる  相次いだ「サポート詐欺」「ランサムウェア」 の具体的事例と対策を解説(9/6)
https://newsdig.tbs.co.jp/articles/-/1393378?display=1

【オンラインコミュニティ】「データサイエンティストのキャリア相談所」を運営中！(9/6)
https://digital-transformation-blog.com/datascientist-community/

米国 NSA "No Such Agency"による"No Such Podcast" が2024.09.05から始まりました（毎週 6回シリーズ）(9/7)
http://maruyama-mitsuhiko.cocolog-nifty.com/security/2024/09/post-3046ef.html

米国他 ロシア軍のサイバー工作員が米国およびグローバルな重要インフラを標的にしているので注意してください...(9/7)
http://maruyama-mitsuhiko.cocolog-nifty.com/security/2024/09/post-38d5eb.html

TryHackMe Writeup：Basic Pentesting(9/6)
https://qiita.com/kgtakm/items/b0d73c5f82c706d130cc

中国のサイバースパイ活動(9/7)
https://vpoint.jp/opnion/viewpoint/230338.html

侵攻前サイバー攻撃関与か ロシアの軍人など6人起訴 米司法省(9/7)
https://www3.nhk.or.jp/news/html/20240907/k10014575481000.html

外務省 第3回北朝鮮サイバー脅威に関する日米韓外交当局間作業部会の開催(9/7)
http://maruyama-mitsuhiko.cocolog-nifty.com/security/2024/09/post-fe3a17.html
ChromeDriver(EdgeDriver)のVer.128からデフォルトポート9515がランダムに変更されました。

# はじめに
TinySeleniumVBA (ExcelでWebスクレイピングするツール) を使用しているユーザーから環境を変更したら動作しなくなったとの[コメント](https://qiita.com/uezo/items/66e20b064ffd5f239b9a#comment-27a5abb81f4a2ca39a50)がありました。

https://qiita.com/yaju/items/9d1f189a5d2118a3f4d3

他にも AutoIt (Windows用プログラムのGUI自動操作機能)でも問題が発生しているようです。

https://www.autoitscript.com/forum/topic/212201-chromedriver-issues-august-2024

【2024/12/28追記】
他にも、Laravel の旧バージョンでも問題が発生しているようです。 

https://qiita.com/akagane99/items/a1da4b45228f52868f66

# 原因
2024/08/22のChromeDriver(EdgeDriver)のVer.128からデフォルトポート9515がランダムに変更されたことによるものです。
TinySeleniumVBA では固定ポート指定をしていないため、デフォルトポート9515を前提として動作するようになっていたため、ポート不一致でエラーになっていました。

>Fix TCP port race in ChromeDriver
>
>Before this commit ChromeDriver used the default port number 9515 if the
server port was not provided explicitly via the command line. If user
needed to create several ChromeDriver instances the port number had to
be provided explicitly. This created a problem: user had to find a free
port, pass it to ChromeDriver and hope that the port won't be stolen by
another process in between.
This commit enables ChromeDriver to search for the available server port
if it was not specified explicitly or if the port argument was specified
as 0 (zero). This solves the problem of TCP port race.
https://chromium.googlesource.com/chromium/src/+/6f33d75f071e322c4a3e49b0a4ac2022e5b6cada

ChromeDriverのTCPポートレースを修正
今回のコミット以前は、ChromeDriverはサーバーポートがコマンドラインで明示的に提供されない場合、デフォルトのポート番号9515を使用していました。
複数のChromeDriverインスタンスを作成する必要がある場合、ポート番号を明示的に指定する必要がありました。
このため、ユーザーは空いているポートを探してChromeDriverに渡し、その間に他のプロセスにポートが盗まれないことを祈らなければならないという問題があった。
このコミットにより、明示的に指定されていない場合、またはポート引数に0（ゼロ）が指定されている場合に、ChromeDriverが利用可能なサーバーポートを検索できるようになった。
これにより、TCPポート競合の問題が解決される。

# 暫定対応
ポート番号を明示的に指定するよう「" --port=9515"」を追加

```vb:WebDriver.cls
' Launch Edge Driver
Public Sub Edge(ByVal driverPath As String, Optional ByVal driverUrl As String = "http://localhost:9515")
    start driverPath & " --port=9515", driverUrl, "MicrosoftEdge"
End Sub

' Launch Chrome Driver
Public Sub Chrome(ByVal driverPath As String, Optional ByVal driverUrl As String = "http://localhost:9515")
    start driverPath & " --port=9515", driverUrl, "chrome"
End Sub
```

# 最後に
タイトルに記載すれば検索に引っ掛かりやすくなると思うので書いてみました。
Bedrockにロールをやらせるなら詳細プロンプトをいじるべし

先日、AWSのAmazon Bedrockにロールを演じさせようとしたのですが、プロンプトエンジニアリングで詰まったので共有する。
# Amazon Bedrockについて
Amazon BedrockはAWSのサービスで、GUIでボタンをポチポチするだけで、RAGを使った対話エージェントを爆速で構築できるサービスである。API Gatewayなども不要で、作成したAgentとエイリアスのIDだけで、クライアント側から呼び出せるため、超簡単。
しかし、こういったお手軽サービスあるあるなのが、内部ロジックが分からないため、ちょっと深い調整をしようとすると沼る。

# エージェント向けの指示という罠
Amazon Bedrockでエージェントを作成すると、「エージェント向けの指示」といういかにもなUIがある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3879374/6eeb6daa-59d6-e8af-4585-cdc0dc9b0ae0.png)
しかし、これにロールを演じるような指示を与えても全然反映されない。
なぜここをいじっても反映されないかは、Amazon Bedrockのエージェントは単に、ユーザの入力から知識拡張を行って、プロンプトに突っ込んでいるだけではなく、ステップバイステップで多段階の推論を行っているためである。
これは右側のUIでテストを行ったときに表示される、スタックとレースを見るとよくわかる。詳細な推論過程は以下で詳しく解説している。
https://dev.classmethod.jp/articles/introduction-2024-agents-for-amazon-bedrock/
エージェント向けの指示がどの推論ステップで作用するかはスタックとレースには載っていないためわからないが、後述の「KBの回答生成」より効果がないことは確かである。

# 詳細プロンプトをいじる
ではどこをいじるべきかというと、下の方にある詳細プロンプトをいじる必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3879374/9945f005-95a9-dce8-a998-cf7623dd135b.png)
編集をクリックすると、4つのプロンプトとパラメータ調整が開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3879374/e163a9c3-458b-dbda-b6f5-9e0dedd654be.png)
「KBの回答生成」が検索を行った後、ユーザの指示と検索結果から生成を行う際の指示になるので、ここを編集すると、ちゃんとエージェントに指示を与えることができた。

# あとがき
前処理やオーケストレーションをいじることで、ナレッジベースからの検索も調整できるようなので、より回答の精度を上げるなら調整する必要がある。機会があればそちらも触ってみたい。
余談ではあるが、ナレッジベースをdisableにしたところ、全然反映されていなかった「エージェント向けの指示」が普通のプロンプトと同じように作用した。知識拡張を行う前に与えられるプロンプトなのかもしれない。
one secを使ってiPhoneのアプリを制限する

# 目的
iPhoneのアプリ(主にX)を厳しく制限したいなと思い，one secというアプリを見つけたので設定方法をメモしていく．

# one secとは
公式サイトはでは以下のような紹介担っています．
> 長期的な、ソーシャルメディアの妨害から自由になる
ソーシャルメディアアプリの起動時にone secはあなたに深呼吸を吐かせます。これはシンプルかつ効果的で、摩擦が邪魔なアプリの魅力を削ぎます。

つまり無駄なSNSの利用の防止を目的としたアプリです．
このone secの効果は，ハイデルベルク大学とマックス・プランク研究所の研究でSNSの利用が57%減ったとの結果が出ていほどのようです．

https://one-sec.app/max-planck-study/

https://one-sec.app/localized-files/ja_ALL/

# one secを入れてみる
iPhoneの場合はApple Storeから one secと検索して，インストールします．
注意点として，無料の場合は1つのアプリしか設定できません．試しに使ってみて，自分の利用に合わないと思ったらやめて良いと思います．

はじめの画面で追加をクリックします．
すると利用方法が書かれています!

<img width="400" alt="onesec.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469304/6d7d0caf-4e3b-d109-0c63-029fa0222d4c.jpeg">

このアプリはiPhoneのショートカットで設定して初めて効果を発揮します．なのでショートカットアプリで設定をしていきます．

# ショートカットアプリの設定
ショートカットを開いたらオートメーションをクリックします．クリックしたら下の方にあるアプリをクリックします．


<img width="400" alt="short1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469304/8c6b76eb-d9b4-c1ba-1825-127331495de3.jpeg">

アプリをクリックしたら，以下のようなどのアプリを設定するのかを求められます．
制限したいアプリを選びましょう．今回はXにします．
<img width="400" alt="short2.png"  src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469304/82a83cc2-a4b0-dcb0-e13e-bfac2314c249.jpeg>

またアプリは開いている状態で直ぐに実行するよう設定して次へをクリックします．

次へを押したら新規の空のオートメーションをクリックします．
アクションを追加を求められるのでクリックします．
そしたらまた色々なアクションの設定が出ますが，検索バーに「one」と入力すると，one secの設定が諸々でます．その中の`アプリ起動時に「one sec」を作動させる`を選びます．
<img width="400" alt="short3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469304/7ac02ccd-d80a-c9ca-3ec5-a46192812237.jpeg">

そしたら`アプリ（選択必須⚠）`という選択したでるので，制限したいアプリを選択します．
<img width="400" alt="short4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469304/a41e007f-8fb2-f133-3994-07880fd54e47.jpeg">

これで設定はOKです．試しに設定したアプリを開いてみましょう．
．
<img width="400" alt="short5.png"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469304/80668c73-af8c-2959-e003-f6c7ee4f0504.jpeg">
アプリを開いた瞬間に割り込みが入って，`深呼吸をしてみましょう`というページがiPhoneの振動付きで開き，すぐに使えなくなります．．10秒立つとその後にアプリを開くかを選択することはできます

この割り込み設定はデフォルトが10秒ですが，最大60秒まで設定できます．(まじで60秒は長いです...)
<img width="400" alt="short6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469304/06aaf688-1e45-90ba-3773-bfa2b4c943e9.jpeg">
# ちょっと設定を凝ってみる
このようにone secでアプリの制限をすることはできますが，Xは情報収集に使っている側面があるので，常時制限しておくのは辛いです．
なので特定の時間だけ制限するようにショートカット側の設定を変更してみます．
私は以下のように設定をしています．
<img width="400" alt="short7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469304/1c56cd60-c0cb-5a13-d8b6-b880fd0fda42.jpeg">

1. 現在の日付で`^..`に一致
2. 1から数字を取得
3. もし1で取得した数字が22 ~ 23 or 0 ~ 5のときにone secを起動

↑のようなショートカットの仕組みを作ることで，22時から5時以外ではone secを起動しないようにしています．これで常時アプリが開けなくてしんどい！みたいなことはなく，決められた時間でスマホを使用することができます．

# まとめ
当初入れたときは慣れない部分もありましたが，入れてしまうとスマホの利用はかなり減った気がします．まだ使い始めた段階ですが，個人的にはかなり満足しています．
ぜひ一度入れてみても良いと思います．
【Python】辞書データの値取得方法 keyアクセスと get()メソッドの違いについて

# はじめに
Pythonの辞書型データから値を取得するときに、`hoge[param]`とgetメソッドを使った`hoge.get(param)`があります。どちらも辞書型データの`value`を取得でき一見すると違いがなさそうに思えます。本記事ではこれらの違いについて記載します。

# ゴール
`hoge[param]` と `hoge.get(param)` の違いについて把握する

# 結論
- hoge[param]：存在しないkeyにアクセスするとエラーになります
- hoge.get(param)：デフォルト値を指定でき、対象のkeyがない場合にはデフォルト値が返却される

# 環境
Python 3.12.4

# 基本的な使い方
それぞれ次のように辞書から値を取得します。

```python
# 辞書の作成
fruit_prices = {"りんご": 100, "バナナ": 80, "オレンジ": 120}

# hoge[param]の使い方
print(fruit_prices["りんご"])  # 出力: 100

# hoge.get(param)の使い方
print(fruit_prices.get("バナナ"))  # 出力: 80
```

# 主な違い



##  1. 存在しないキーへのアクセス
hoge[param]は、キーが存在しない場合にエラー（KeyError）を発生させます。

<details><summary>KeyError 実行例</summary>

```python
# 辞書の作成
fruit_prices = {"りんご": 100, "バナナ": 80, "オレンジ": 120}

# デフォルト値を指定
print(fruit_prices["メロン"])  # KeyError: 'メロン'
```

</details>

hoge.get(param)は、キーが存在しない場合でもエラーを発生させず、Noneを返します。

<details><summary>None 実行例</summary>

```python
# 辞書の作成
fruit_prices = {"りんご": 100, "バナナ": 80, "オレンジ": 120}

# デフォルト値を指定
print(fruit_prices.get('メロン'))  # None
```

</details>

```python:実行例
# hoge[param]の場合
try:
    print(fruit_prices["メロン"])
except KeyError:
    print("メロンは辞書にありません")  # この行が実行されます

# hoge.get(param)の場合
print(fruit_prices.get("メロン"))  # 出力: None
```

## 2. デフォルト値の指定

getメソッドでは、キーが存在しない場合のデフォルト値を指定できます。
hoge[param]ではこのような指定はできません。
次の例ではgetメソッドを使用し、デフォルト値 `500` を設定しています。

```python
# 辞書の作成
fruit_prices = {"りんご": 100, "バナナ": 80, "オレンジ": 120}

# デフォルト値を指定
print(fruit_prices.get("メロン", 500))  # 出力: 500
```

# 結論
- hoge[param]：存在しないkeyにアクセスするとエラーになります。
- hoge.get(param)：デフォルト値を指定できて、対象のkeyがない場合にはデフォルト値が返却されます


# 終わりに
本記事では辞書型のデータからの値を取得するhoge[param]とhoge.get(param)の違いについて記載しました。
迷った時にはデフォルト値を設定できるgetメソッドで書いておけば予期せぬエラーを防ぐ事ができそうです。
Anaconda uninstallさせたらエラーが起きたので解決した

# 問題
入れていたAnacondaをアンインストールしたらpipxのpathがanacondaになっているため、autowareの`./setup-dev-env.sh`が通らなくなっていた問題


```terminal: エラーコード
All pipx binary directories have been added to PATH. If you are sure you
want to proceed, try again with the '--force' flag.
Otherwise pipx is ready to go!
./setup-dev-env.sh: /home/kazumaikeda/.local/bin/pipx: /home/<username>/anaconda3/bin/python3: bad interpreter: No such file or directory
```
pipxがanacondaのパスを参照しているのでないよと言われている

# 解決方法
pipxをアンインストールしてあげよう
```
pip uninstall pipx
```
autowareの`./setup-dev-env.sh`でまた戻るのでアンインストールしても問題ないので行ってよし
ネットワーク構成

# VPCを作成する
>AmazonVPCと呼ばれる領域を作ると、そこに自由なネットワークを作れます
...
それをいくつかのネットワークにさらに分割して利用します。

# サブネットを作成する
>分割したネットワークのことをサブネットと言います。
### パブリックサブネット
>インターネットからアクセスすることを目的としたサブネットです。
### プライベートサブネット
>インターネットから隔離したサブネットです。

>インターネットから接続できないサブネット
>...
>サーバーを隠すことができ、セキュリティを高められます。

# インターネットゲートウェイ
>あるサブネットをインターネットに接続するには、「インターネットゲートウェイ」を用います。
これは自分のネットワークにインターネットを引き込むというイメージの作業になります。

インターネットゲートウェイをVPCにつけてインターネット接続する
### デフォルトゲートウェイ
>「転送先が何も設定されていないときの、デフォルトの転送先」を示します

任意のipアドレスへの送信先になる

# ルーティング
>ネットワークにデータを流すためには、「ルーティング情報」と呼ばれる設定が必要です。
この設定は、「ルーティングテーブル」や「ルートテーブル」と呼ばれます。

> ルートテーブルをパブリックサブネットに適用します


ルートテーブルを作りたいVPCに設定する。

# インスタンスを作成
>起動された各サーバーの個体は「インスタンス」と呼ばれます。

任意のサブネットに合わせてインスタンスのipアドレスを設定する。

# セキュリティグループ
>パケットフィルタリングは流れるパケットを見て、通貨の可否を決める仕組みです。

>「インバウンド」と「アウトバウンド」の２つがあります。前者は「外から、このインスタンスに接続する向き」、後者は「このインスタンスから外側に出て行く向き」です。

# 出典
https://bookplus.nikkei.com/atcl/catalog/20/277900/

# 感想
これからネットワークを理解します
(Obsidianテンプレート)デイリーノート

この記事は以下の記事で紹介したデイリーノートのテンプレートの一例です。
[Obsidianを利用して知的労働を効果的に進める方法 ##obsidian - Qiita](https://qiita.com/haravity/items/b86c9b85b33154a2305f)

:::note info
コード部分は、コードの始まりのコードブロック記号の横にdataviewをつけて、「```dataview」となるように追記してください、dataviewプラグインが入っていればクエリされるようになります。
(ここから下がテンプレート)
:::

# [[<% tp.date.now("YYYY-MM-DD", -1, tp.file.title, "YYYY-MM-DD") %>|◀]] <% tp.date.now("YYYY年MM月DD日 ddd曜日") %> [[<% tp.date.now("YYYY-MM-DD", 1, tp.file.title, "YYYY-MM-DD") %>|▶]]
(ここに前日や翌日のデイリーノートに飛ばすリンクを表示させます。)

# タスクログ
(本日作成または編集した、ファイル名が「TL：」から始まるファイルをクエリします。)
```dataview
TASK 
WHERE ((file.mday = this.file.day) OR (file.cday = this.file.day))
  AND contains(file.name, "TL：")
GROUP BY file.link
SORT rows.file.ctime DESC
```

# その他のノート
## 作成
(本日作成した、ファイル名が「TL：」以外から始まるファイルをクエリします。)
```dataview
LIST
WHERE file.cday = this.file.day
  AND !contains(file.name, "TL：")
SORT file.mtime ASC
```

## 変更
(本日編集した、ファイル名が「TL：」以外から始まるファイルをクエリします。)
```dataview
LIST
WHERE file.mday = this.file.day AND file.cday != this.file.day
  AND !contains(file.name, "TL：")
SORT file.mtime ASC
```

# メモ
(ここにQuickAddによるメモを追加していきます。)
(Obsidianテンプレート)プロジェクトインデックス

この記事は以下の記事で紹介したタスクログのテンプレートの一例です。
[Obsidianを利用して知的労働を効果的に進める方法 ##obsidian - Qiita](https://qiita.com/haravity/items/b86c9b85b33154a2305f)

:::note info
コード部分は、コードの始まりのコードブロック記号の横にdataviewをつけて、「```dataview」となるように追記してください、dataviewプラグインが入っていればクエリされるようになります。
:::

(ここから下がテンプレート)


# 以下の作業を終えたらこの見出しは消す
ファイルのプロパティに、以下の2つのプロパティと値を追加。
- project_tag
    - (#から始まるプロジェクトを表すタグ名)
- prefix
    - (プロジェクトを表す絵文字、これがタイトルの頭に来るように運用)

# 目的
(プロジェクトキックオフ時やアサイン時に記述)

# 成果物（ゴール）
(プロジェクトキックオフ時やアサイン時に記述)

# 予定
(随時更新する)

# 重要なメモ
(随時更新する)

# 資料
(随時更新する)

# アイデア
(ファイルの頭文字が💡から始まり、プロジェクトのタグが含まれているファイルをクエリ)
```dataview
LIST
WHERE contains(file.name, "💡") 
AND contains(file.tags, this.file.frontmatter.project_tag) 
SORT file.cday DESC
```
# MTG
(MTGとプロジェクトのタグが含まれているファイルをクエリ)
```dataview
LIST
WHERE contains(file.tags, "#MTG") 
AND contains(file.tags, this.file.frontmatter.project_tag) 
SORT file.cday DESC
```
# すべてのファイル
(MTG以外のプロジェクトのタグが含まれているファイルをクエリ)
```dataview
LIST
WHERE contains(file.name, this.file.frontmatter.prefix)
  AND !contains(file.name, "MTG：")
SORT file.cday DESC
```

# その他メモ
AWS認定試験まとめ

## 基礎レベル (Foundational)

- **AWS認定クラウドプラクティショナー (Cloud Practitioner)**
概要：AWSクラウドの基本的な知識を問う試験。
費用: 100 USD (15,000円)。
試験時間: 90分。
問題数: 65問。

## アソシエイトレベル (Associate)

### AWS認定ソリューションアーキテクト アソシエイト (Solutions Architect Associate)
概要：AWSクラウドで適切なシステム設計を行う能力を問う試験。
費用: 150 USD (20,000円)。
試験時間: 130分。
問題数: 65問。


### AWS認定デベロッパー アソシエイト (Developer Associate)
概要：AWSを使用したアプリケーション開発の知識を問う試験。
費用: 150 USD (20,000円)。
試験時間: 130分。
問題数: 65問。

### AWS認定SysOpsアドミニストレーター アソシエイト (SysOps Administrator Associate)
概要：AWS上でのワークロード管理・運用・保守の知識を問う試験。
費用: 150 USD (20,000円)。
試験時間: 130分。
問題数: 65問。

### AWS認定データエンジニア アソシエイト (Data Engineer Associate)
概要：データエンジニアリングに関するスキルと知識を問う試験。
費用: 150 USD (20,000円)。
試験時間: 130分。
問題数: 65問。

### AWS Certified Data Engineer - Associate (DEA-C01)
概要：データエンジニアリングに特化した試験。
費用: 150 USD (20,000円)。
試験時間: 130分。
問題数: 65問。

## プロフェッショナルレベル (Professional)

### AWS認定ソリューションアーキテクト プロフェッショナル (Solutions Architect Professional)
概要：複雑なシステム設計を行う高度な技術と経験を問う試験。
費用: 300 USD (40,000円)。
試験時間: 180分。
問題数: 75問。

### AWS認定DevOpsエンジニア プロフェッショナル (DevOps Engineer Professional)
概要：高度に自動化されたインフラストラクチャの構築と運用の知識を問う試験。
費用: 300 USD (40,000円)。
試験時間: 180分。
問題数: 75問。

## スペシャリティレベル (Specialty)

### Advanced Networking Specialty
概要：複雑なネットワーク業務に関する専門知識を問う試験。
費用: 300 USD (40,000円)。
試験時間: 170分。
問題数: 65問。

### Machine Learning Specialty
概要：機械学習ソリューションの設計・実装・デプロイに関する知識を問う試験。
費用: 300 USD (40,000円)。
試験時間: 170分。
問題数: 65問。

### Security Specialty
概要：AWSにおけるセキュリティの運用とリスク管理に関する知識を問う試験。
費用: 300 USD (40,000円)。
試験時間: 170分。
問題数: 65問。

## 最新のベータ版試験 (2024年)

### AWS Certified AI Practitioner (AIF-C01)
概要：AIと機械学習の基礎力を証明する試験。
費用: 75 USD(10,000円)。
試験時間: 120分。
問題数: 85問。

### AWS Certified Machine Learning Engineer - Associate (MLA-C01)
概要：本番環境に ML を実装して運用可能にする技術的能力を実証する試験。
費用: 75 USD(10,000円)。
試験時間: 170分。
問題数: 85問。
Maria DB 備忘録

## MariaDB 接続方法
```
local@raspberrypi:~ $ sudo mysql -u <user_name> -p
```
## Databaseの確認 + 使用
```sql
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| Database_name      |
+--------------------+
```
## Databaseの使用
```sql
MariaDB [(none)]> USE <Database_name>;
```

## 登録済みテーブルの確認
```sql
MariaDB [db]> SHOW TABLES;
+----------------------+
| Tables_in_db         |
+----------------------+
| users                |
+----------------------+
1 row in set (0.001 sec)
```

## テーブルの追加
```sql
MariaDB [db]> CREATE TABLE users (
    -> id INT AUTO_INCREMENT PRIMARY KEY,
    -> name VARCHAR(100) NOT NULL,
    -> email VARCHAR(100) NOT NULL UNIQUE
    -> );
Query OK, 0 rows affected (0.040 sec)
```

## テーブルの削除
```sql
Mariadb [db]> DROP TABLE <Table_name>;
Query OK, 0 rows affected (0.024sec)
```

## INSERT
```sql
MariaDB [db]> INSERT INTO users (name, email)
    -> VALUES('John Doe', 'john.doe@example.com');
Query OK, 1 row affected (0.007 sec)
```

## READ 1
```sql
MariaDB [db]> SELECT * FROM users;
+----+----------+----------------------+
| id | name     | email                |
+----+----------+----------------------+
|  1 | John Doe | john.doe@example.com |
|  2 | Kate     | kate@example.com     |
+----+----------+----------------------+
2 rows in set (0.001 sec)
```
## READ 2 条件付き
```sql
MariaDB [db]> SELECT * FROM users WHERE name = 'John Doe';
+----+----------+----------------------+
| id | name     | email                |
+----+----------+----------------------+
|  1 | John Doe | john.doe@example.com |
+----+----------+----------------------+
1 row in set (0.001 sec)
```

## UPDATE
```sql
MariaDB [db]> UPDATE users
    -> SET email = 'kate_02@example.com'
    -> WHERE name = 'Kate';
Query OK, 1 row affected (0.010 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [db]> SELECT * FROM users;
+----+----------+----------------------+
| id | name     | email                |
+----+----------+----------------------+
|  1 | John Doe | john.doe@example.com |
|  2 | Kate     | kate_02@example.com  |
+----+----------+----------------------+
2 rows in set (0.001 sec)
```

## DELETE
```sql
MariaDB [db]> DELETE FROM users
    -> WHERE name = 'Kate';
Query OK, 1 row affected (0.007 sec)

MariaDB [db]> SELECT * FROM users;
+----+----------+----------------------+
| id | name     | email                |
+----+----------+----------------------+
|  1 | John Doe | john.doe@example.com |
+----+----------+----------------------+
1 row in set (0.001 sec)

MariaDB [mydatabase]>
```

## テーブル構造の確認
```sql
MariaDB [db]> DESCRIBE users;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(100) | NO   |     | NULL    |                |
| email | varchar(100) | NO   | UNI | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
3 rows in set (0.003 sec)
```
(Obsidianテンプレート)ミーティングログ

この記事は以下の記事で紹介したミーティングログのテンプレートの一例です。
[Obsidianを利用して知的労働を効果的に進める方法 ##obsidian - Qiita](https://qiita.com/haravity/items/b86c9b85b33154a2305f)

下記のテンプレートをプロジェクトごと、定例会議ごとに用意すると良いでしょう。

:::note info
コード部分は、コードの始まりのコードブロック記号の横にdataviewjsをつけて、「```dataviewjs」となるように追記してください、dataviewプラグインが入っていればクエリされるようになります。
(ここから下がテンプレート)
:::

# 前回の振り返り
(dataviewjsを使って、直近の日付の定例MTGの結論をクエリします、定例でない場合はこの段落ごと削除します。)
```dataviewjs
/* MTGごとに、prefixと、suffixを指定 */
//MTG用のprefixとsuffixを指定
const prefix = "🧪MTG："
const suffix = "定例"
/* 入力ここまで */

//現在のページから日付を取得
const currentFileName = dv.current().file.name;
const currentDateMatch = currentFileName.match(/(\d{8})/)
const nowPageDate = currentDateMatch && currentDateMatch.length > 1 ? parseInt(currentDateMatch[1], 10) : null;
if (nowPageDate === null) {
  dv.paragraph("現在のページの日付を識別できません。")
}

// prefixで始まるページと現在のページの日付の差を取得
const diffDateArr = dv.pages()
    .where(page => page.file.name.startsWith(prefix))
    .where(page => page.file.name.endsWith(suffix))
    .map(page => {
      // ページ名から日付部分を抽出し整数に変換
      const pageDateMatch = page.file.name.match(/(\d{8})/);
      if (!pageDateMatch) return null; // 日付が適切な形式でない場合はスキップ
      const pageDate = parseInt(pageDateMatch[1], 10);
      const diffDate = nowPageDate - pageDate;
      return diffDate
    })
    .filter(diffDate => diffDate !== null && diffDate > 0);

// 配列の最小値を取得
const min_val = Math.min(...diffDateArr); // => 1

// 現在の日付から引いて直近の日付を取得
const lastDate = nowPageDate -　min_val

// 直近の日付のファイル名のprefixを取得
const lastDateFilePrefix = `${prefix}${lastDate}`

// 直近の日付のファイル名を取得
const lastDateFilename = dv.pages()
    .where(page => page.file.name.startsWith(lastDateFilePrefix))
    .file.name[0]

dv.paragraph(`![[${lastDateFilename}#結論]]\n`);
dv.paragraph(`[[${lastDateFilename}]]`);
```
# 目的
(会議の最初に必ず書きましょう)

- 

# 結論
(会議の最後に必ず書きましょう)

- 

# 宿題
(ファイル内の「★」を含む行を抽出してここに一覧表示します。不要の場合はコードを削除します。)
```dataviewjs
// ファイルがロードされていることを確認
const activeFile = this.app.workspace.getActiveFile();
if (activeFile) {
    const fileContent = await this.app.vault.read(activeFile);

    // ファイルの内容を行ごとに分割
    const lines = fileContent.split('\n');

    // "★" を含む行を抽出（ただしコードブロック内は除外）
    const codeBlockRegex = /^```/;
    let inCodeBlock = false;
    const starLines = lines.filter(line => {
        // コードブロックの開始または終了を検出
        if (codeBlockRegex.test(line)) {
            inCodeBlock = !inCodeBlock;
            return false; // コードブロックの開始/終了行は含めない
        }
        // コードブロック内の場合は除外
        if (inCodeBlock) return false;
        // "★"を含む行であり、かつコードブロック内でない行を返す
        return line.includes("★");
    }).map(line => {
        // "★"より後ろの文字列を取得
        const starIndex = line.indexOf("★");
        return line.substring(starIndex);
    });

    // 抽出した文字列を表示
    starLines.forEach(content => {
        dv.paragraph(content);
    });
} else {
    dv.paragraph("No active file.");
}
```
# 参加者


# 資料
- 

# 要点
- 

# 内容

# タグ
(タグをつけておくと、プロジェクトインデックスからクエリがしやすくなる)
#project1 #定例 #MTG

(一番下にタイトルとなるものを用意している、これを切り取ってファイル名にコピーする)
🧪MTG：<% tp.date.now("YYYYMMDD", tp.file.title)%> 定例
(Obsidianテンプレート)タスクログ

この記事は以下の記事で紹介したタスクログのテンプレートの一例です。
[Obsidianを利用して知的労働を効果的に進める方法 ##obsidian - Qiita](https://qiita.com/haravity/items/b86c9b85b33154a2305f)

(ここから下がテンプレート)

# 目的
- 
# ゴール

# 結論


# 資料
(タスクで使う資料へのリンクを記述する)


# やったこと
## 小タスクA
(タスク実施前に小タスクに分けて見出しレベル##でプロセスを記載)
## 小タスクB

# その他

# タグ

🧪⚙️📘
(プロジェクトのprefixを並べておき、タイトルの頭文字にコピーして使用する)
タイタニックで76%を超えたアルゴリズム

<a href="https://qiita.com/murasaki1994/items/710237fb05fe661640a0">前回</a>、<a href="https://qiita.com/murasaki1994/items/ed8b77f5d953f46e2ae9">前々回</a>と初心に帰りタイタニックをやっていたわけですが(転職活動長引きすぎてスキルが理由なのか不安になっていたわけですが)どうもサンプルの提出物の精度を超えませんでした。
最初にやったのは欠損値を大真面目に考えたこと

https://qiita.com/murasaki1994/items/ed8b77f5d953f46e2ae9

そして次には名前の敬称を特徴量としたわけですが、

https://qiita.com/murasaki1994/items/710237fb05fe661640a0

どれも良くて75%でした。(検証用データは90%近くなのに)

そこで今度は使用する学習アルゴリズムを決定木系ではなくSVMを使ってみました。
初期値なのでRBFカーネル(ガウスカーネル)である程度ソフトマージンなのかな？

# コード
## 変数選択用
元々変数選択をしようとしたのでそれ用のコードを書きました。
```Python3
x2 = x
x_te2 = x_test
```
続いてSVMは決定木系のアルゴリズムではないので前処理として標準化が必要ですので、行います。
```Python3
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(x2)
x2 = ss.transform(x2)
models = []
for i in range(200):
    x_train, x_val, y_train, y_val = tts(x2, y, random_state=i, test_size=0.2, stratify=y)
    model1 = RFC()
    model1.fit(x_train, y_train)
    models.append([model1, model1.score(x_val, y_val), model1.score(x_train, y_train)])
    model2 = LGBMC()
    model2.fit(x_train, y_train)
    models.append([model2, model2.score(x_val, y_val), model2.score(x_train, y_train)])
    model3 = SVC()
    model3.fit(x_train, y_train)
    models.append([model3, model3.score(x_val, y_val), model3.score(x_train, y_train)])
models = sorted(models, key=lambda x:x[1], reverse=True)
```
これでモデルが作られました。見てみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/dda7edba-047a-3f61-f93e-9b6ec639c004.png)

SVMが最も精度が高くなりました(LightGBMよりも)。
ではこれで予測をしてみましょう。
```Python3
from scipy.stats import mode
x_te2 = ss.transform(x_te2)
y_pred1 = models[0][0].predict(x_te2)
y_pred2 = models[1][0].predict(x_te2)
y_pred3 = models[2][0].predict(x_te2)
y_pred = []
for i in range(len(y_pred1)):
    y_pred.append(mode([y_pred1[i], y_pred2[i], y_pred3[i]])[0])

pred = pd.DataFrame(y_pred1)
pred.columns = ["Survived"]
pred.index = x_test.index
pred.sort_index().to_csv("submit_allval11.csv")
```
これで提出した結果がこちらになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/28a082a1-fd4d-bb1f-90d4-08b6543b447c.png)
ようやくこれでサンプルの提出物の精度を超えました。
しかし何が原因だったんだろう。
【Next.js】conformの導入方法

## インストール

以下のコマンドを実行して必要なライブラリをインストールします。

```terminal
yarn add @conform-to/react @conform-to/zod
```

## Zodのスキーマを作成する

バリデーションのため、Zodのスキーマを作成します。

```ts:schema.ts
import { z } from "zod";

export const loginSchema = z.object({
  email: z.string().email(),
  password: z.string(),
});

```

## サーバーアクションを作成

```ts:action.ts
"use server";

import { redirect } from "next/navigation";
import { parseWithZod } from "@conform-to/zod";
import { loginSchema } from "@/app/schema";

export async function login(prevState: unknown, formData: FormData) {
  const submission = parseWithZod(formData, {
    schema: loginSchema,
  });

  if (submission.status !== "success") {
    return submission.reply();
  }

  redirect("/dashboard");
}
```

## フォームの作成

```tsx:form.tsx
"use client";

import { useForm } from "@conform-to/react";
import { parseWithZod } from "@conform-to/zod";
import { useFormState } from "react-dom";
import { login } from "@/app/actions";
import { loginSchema } from "@/app/schema";

export function LoginForm() {
  const [lastResult, action] = useFormState(login, undefined);
  const [form, fields] = useForm({
    lastResult,
    onValidate({ formData }) {
      return parseWithZod(formData, { schema: loginSchema });
    },
    shouldValidate: "onBlur",
  });

  return (
    <form id={form.id} onSubmit={form.onSubmit} action={action} noValidate>
      <div>
        <label htmlFor={fields.email.id}>>Email</label>
        <input type="email" name={fields.email.name} />
        <div>{fields.email.errors}</div>
      </div>
      <div>
        <label htmlFor={fields.password.id}>Password</label>
        <input type="password" name={fields.password.name} />
        <div>{fields.password.errors}</div>
      </div>
      <label>
        <div>
          <span>Remember me</span>
          <input type="checkbox" name={fields.remember.name} />
        </div>
      </label>
      <Button>Login</Button>
    </form>
  );
}
```
ローカルリポジトリをダイエット！不要なGitブランチを瞬時に整理するワンライナーコマンド

# はじめに
今回は、不要になったローカルブランチを自動的に削除するコマンドを紹介したいと思います。

不要になったローカルブランチというのは、リモートではすでにマージされ削除されたブランチと対応するローカルブランチを指します。

開発をしているとどんどん不要なブランチが溜まっていき、PCの容量を圧迫することにもつながりかねません。

それに、`git branch`を打って山のようにブランチが表示されるのは精神衛生上よろしくありません。(個人の感想です)

そこで、今回紹介するコマンドを打つことで身も心もPCすらも軽くして開発に臨みましょう。

## コマンド
```zsh
$ git fetch -p && git branch -vv | awk '/: gone]/{print $1}' | xargs -p git branch -d
```

これをgitが有効なディレクトリで実行することで、不要なブランチが削除されます。

一応ですが、実行前に確認のメッセージが表示されるようにしてあります。
`y`を入力し`Enter`を押すことで実行されます。

消してはいけないブランチがプロジェクトにある方は目を通してから実行するようにしてください。
確認なんていらないよって方は、`xargs -p`の部分の`-p`を削除してください。
faster whisperをdocker composeにまとめたのでサクッと文字起こしをしてみよう！

# TL;DR
文字起こしができる[faster-whisper](https://github.com/SYSTRAN/faster-whisper)を`docker compose`で実行できるようにしました。([repository](https://github.com/thrillingdream/whisper-sample))
NVIDIA周りの環境構築をあまりしないでサクッと文字起こしができます。
また、GPUがなくても実行可能です。

「文字起こしの自動化」を試してみたいと思っていた方は、この機会に初めてみてはいかがでしょうか？

# 動作サンプル
音声ファイルを入れて（動画ファイルでも可）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881186/adbeacbe-8570-79f8-b437-370fb0eb6ada.png)

docker composeで立ち上げると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881186/60b29d25-76e4-0dd6-f004-af2c8ce69599.png)

文字起こしができます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881186/d2bb21c2-d5fa-47e3-c910-239dd3298e79.png)

めっちゃ楽！

# リポジトリ
https://github.com/thrillingdream/whisper-sample

# 動作環境
- Docker
### GPUで推論する場合
- NVIDIA Container Toolkit
- NVIDIA Container Toolkitに対応したGPU

### 動作確認済み
- WSL2(ubuntu)

### 未確認
- その他Windows, Linux環境(NVIDIA Container Toolkit)があれば動くはず


## 事前準備

NVIDIA Container Toolkitを入れるだけ。

WSL2の場合は以下の記事で詳細に説明されています。
https://qiita.com/insilicomab/items/681f0b0e1c9ecfe10207

# 使い方

1. `./media`にメディアファイルを入れる
    - 対応拡張子は `mp3 , mp4 , mpeg , mpga , m4a , wav , webm`です
2. ファイル名を指定する

```python:main.py
AUDIO_FILE_NAME = "./media/voice01_A.mp3"
```
3. ルートディレクトリで`docker compose up --build`を実行
4. Consoleと`./output`に文字起こしが吐き出されます

これだけです。

# 技術解説

## ライブラリ管理
poetryを使ってライブラリを管理しています。

```pyproject.toml
[tool.poetry.dependencies]
python = "3.12.3"
yt-dlp = "^2024.4.9"
faster-whisper = "^1.0.2"
nvidia-cublas-cu11 = "^11.11.3.6"
nvidia-cudnn-cu11 = "^9.1.1.17"
```

また、Dockerfileでpoetryで管理しているライブラリをexportしてinstallしています。
```Dockerfile:Dockerfile
# Poetryを使ってrequirements.txtを生成
COPY pyproject.toml poetry.lock /app/
RUN poetry export -f requirements.txt --output requirements.txt

# 依存関係をインストール
RUN pip install -r requirements.txt
```

以下のライブラリはpoetryだとコケるのでDockerfileで直接インストールしています。
```Dockerfile:Dockerfile
# CUDA関連パッケージのインストール。Poetryだとコケるので直接インストールする。
RUN pip install nvidia-pyindex
RUN pip install nvidia-cublas
```

## 非GPU向け環境への対応
```python:main.py
def is_cuda_available():
    try:
        # nvidia-smi コマンドを実行
        subprocess.run(["nvidia-smi"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True)
        return True
    except (subprocess.CalledProcessError, FileNotFoundError):
        return False

def get_device_and_compute_type():
    if is_cuda_available():
        return "cuda", "float16"
    else:
        return "cpu", "int8"
```

`nvidia-smi`を実行できれば、GPUかつ`float16`を使った推論。
そうでなければ`int8`で推論します。

## その他
ライブラリのディレクトリへの参照が解決できないことがあるので以下のおまじないを入れています。
```Dockerfile:Dockerfile
# LD_LIBRARY_PATHの設定（おまじない）
ENV LD_LIBRARY_PATH `python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))'
```


参考：[faster-whisperのissue](https://github.com/SYSTRAN/faster-whisper/issues/153)

# 最後に
Zoomの文字起こしはキャプションが無駄に出て有効にできなかったり、iPhoneで音声を録画したり、文字起こしが必要な機会は多いのではないでしょうか？

faster-whisperの文字起こしはなかなかの精度でかなり助けられています。

みなさま、良い文字起こしライフを～～！
LeetCodeのSQL50を解いてみた

## はじめに
競技プログラミングはAtCoderしか知りませんでしたが、LeetCodeというサービスを最近知りました。
こちらは時間に縛られることなく、ひたすら問題を解くことができるのでのんびり楽しめます。

https://leetcode.com/

## SQLもあるよ
業務で使わないPython、使わないVue、使わないFirebaseでいろいろやってますが、LeetCodeにはSQLがあります。

普段業務で使っているSQLでも遊べます！
50問厳選してくれているので、解いてみました。

https://leetcode.com/studyplan/top-sql-50/

## 記憶に残った問題

https://leetcode.com/problems/count-salary-categories/description/?envType=study-plan-v2&envId=top-sql-50

```sql:回答例
select
    b.category
    ,COUNT(a.account_id) accounts_count
from Accounts a
right join (
    values('Low Salary'),('High Salary'),('Average Salary')) as b(category) 
    on case
        when a.income < 20000 then 'Low Salary'
        when a.income > 50000 then  'High Salary'
        else 'Average Salary'
       end = b.category
group by b.category
```

この問題は、回答例にある`values (col) as tmp_tab(col)`のように、
データから派生テーブルを作る使い方を完全に忘れてしまい、最初は結構長いものを書いてしまった。

https://learn.microsoft.com/ja-jp/sql/t-sql/queries/table-value-constructor-transact-sql?view=sql-server-ver16#c-specifying-multiple-values-as-a-derived-table-in-a-from-clause

## おわりに
全編英語なのですが、そこまで難しくないです。
普段SQLを使っている人はぜひ解いてみてください。

肌感の難易度は、データ分析業務でバリバリウィンドウ関数書いているよって人なら楽勝だと思います。
システム開発でテーブル結合してビュー作ったり、夜間処理などでIF連携を作っている人なら、解きごたえあると思います。
intersectionObserverについて調べています。

お疲れ様です。

再びポートフォリオの編集を行っているのですが、タイトルにある
intersectionObserverを使い、監視したい範囲を設定し、交差（特定の要素が監視の範囲に入った状態のこと）した時に、指定したアニメーションが再生されるようにしているのですが、再生できずに泣いています:innocent:

```diff_javascript
/監視対象が現れたらすること
const History = (entries) => {
  const move = {
    color: ['transparent', '#fff'],
    backgroundPosition: ['100% 0', '0 0'],
  };

  const choice = {
    duration: 1000,
    easing: 'ease',
  };
  entries.forEach(entry => {
    if(entry.isIntersecting){
      entry.target.animate(move, 3000);
    }
  });
};


// 監視設定
const history = new IntersectionObserver(History);

history.observe(document.querySelector('#history'));
```

始めはUncaught Type error　が出ていたので調べると、 entries　は配列扱いになるため、 entaries[0] と入力する必要があり、それでなんとかエラー解消できましたが、アニメは動きませんでした…:sob:

ですがエラーとか日々なんぼでも出会ってるので、へこまずコツコツやっていきたいと思います！

初心者程度の知識しか持ち合わせていませんので、さっそくchatGPT先生にコードを貼り付け、質問したところ、このコードで動かなかったら、 **intersectionObserver のオプション指定をしていきましょう** とのことでしたので、現在 **intersectionObserver.root** や **rootMargin** なるものについて、MDNのページで勉強中です。

交差について細かく指定できるプロパティなのでしょう。
とにかく記事を読んで、chatGPT先生が言っていることを理解できるようになるのを目指します:sweat_drops:
Blender の Geometory Nodes で複素関数 sin(z) を描く

こんにちは｜こんばんは。カエルのアイコンで活動しております @kyamaz :frog: です。

## はじめに
本稿は、数学的な対象を Blender の Geometory Nodes を使って扱うエントリです。複素関数 $ \sin{z} $ を描いてみましょう。


## Blender Geometry Nodes で描く
まず最初に、Scene Collection に Plane Mesh を追加します。[3D Viewport - Object Mode] にて「Add->Mesh->Plane」で追加し、[Outline - ViewLayer] にて名前を「complex_function」に変更しておきます。このオブジェントを選択した状態で [Geometory Node Editor - Modifier] の「+NEW」でモディファイアを追加し、この名前を [Properties] にて「complex_function」としておきます。

### Grid を準備する
複素平面をXY軸にマッピングするためのGridを準備します。いくつかの定数を次のように定めて利用します。

- SizeX：PlaneのX軸のサイズ
- SizeY：PlaneのY軸のサイズ
- VertecesXY：PlaneをGridにする分割数
- Scale：倍率（１未満で指定するとZoomIn、１以上でZoomOut）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136950/95b89293-24e6-2122-aee5-791650a9234f.png)


次の「Named Attribute」にそれぞれの定数の値を保存します。

- `gridsize_x` :: Float <- SizeX
- `gridsize_y` :: Float <- SizeY
- `scale` :: Float <- Scale
- `uv_map` :: Vector <- Gridより（本稿では利用しない）

### パラメーターを初期化する
GridのなかのPointごとに処理されますが、そのPointに対応する複素数を上記の定数を使って求め、「Named Attribute」の `z` :: Vector にその値を保持します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136950/63837fa3-c0f9-24f1-9151-5615607e0e4e.png)

その前に、汎用的な定数 `pi` と `e` を「Named Attribute」に保持しておきます。（ただし、本稿では `pi` ， `e` とも利用しません。汎用的な用例として記載してあります。）

### sin(z) を計算する

$ z = x + iy \\quad (x,y \in \mathbb{R}, z \in \mathbb{C}) $として、

$ \sin(z) = \sin(x) \cosh(y) + i \cos(x) \sinh(y) $ となります。

実部 $\Re(\sin(z)) = \sin(x) \cosh(y)$を z軸に割り当てると次のように設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136950/73c4b58f-1035-9f77-9097-d619057096ca.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136950/016c7308-709a-f009-1f3b-b06008ad6a5b.png)


虚部 $\Im(\sin(z)) = \cos(x) \sinh(y)$を z軸に割り当てると次のように設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136950/dc5e6255-9075-83ce-4521-a2d398a75ab9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136950/4a1b5005-b4cb-93fc-cec6-66b6131f3c4d.png)


以上で、Geometory Nodes で設定する全体像となります。

## おわりに
複素関数をイメージしやすく 3D で表すのには、Blender は良いツールに感じます。

<details><summary>本稿の環境</summary>

本稿のために使用した環境は以下となります。

* macOS: Sonoma 14.5 (chip: Apple M1)
* Blender: 4.2.0
* PYTHON INTERACTIVE CONSOLE 3.11.7 [Clang 15.0.0]

</details>

ご一読いただきまして有り難うございます。
（●）（●） Happy Hacking!
/""　＿＿""＼